diff --git a/.devcontainer/server/container-start-frontend.sh b/.devcontainer/server/container-start-frontend.sh index 9a0d617d41..e7f1dcc1d0 100755 --- a/.devcontainer/server/container-start-frontend.sh +++ b/.devcontainer/server/container-start-frontend.sh @@ -8,6 +8,8 @@ log "Preparing Immich Web Frontend" log "" run_cmd pnpm --filter @immich/sdk install run_cmd pnpm --filter @immich/sdk build +run_cmd pnpm --filter @immich/plugin-sdk install +run_cmd pnpm --filter @immich/plugin-sdk build run_cmd pnpm --filter immich-web install log "Starting Immich Web Frontend" diff --git a/.github/workflows/build-mobile.yml b/.github/workflows/build-mobile.yml index 637e812881..1f3b99ef38 100644 --- a/.github/workflows/build-mobile.yml +++ b/.github/workflows/build-mobile.yml @@ -230,8 +230,12 @@ jobs: - name: Generate platform APIs run: mise //mobile:codegen:pigeon + - name: Resolve iOS Swift Packages + working-directory: ./mobile + run: flutter build ios --config-only --no-codesign + - name: Setup Ruby - uses: ruby/setup-ruby@6aaa311d81eba98ae12eaffbcb63296ace0efcde # v1.307.0 + uses: ruby/setup-ruby@afeafc3d1ab54a631816aba4c914a0081c12ff2f # v1.310.0 with: ruby-version: '3.3' bundler-cache: true @@ -288,7 +292,6 @@ jobs: APP_STORE_CONNECT_API_KEY_ID: ${{ secrets.APP_STORE_CONNECT_API_KEY_ID }} APP_STORE_CONNECT_API_KEY_ISSUER_ID: ${{ secrets.APP_STORE_CONNECT_API_KEY_ISSUER_ID }} ENVIRONMENT: ${{ inputs.environment || 'development' }} - BUNDLE_ID_SUFFIX: ${{ inputs.environment == 'production' && '' || 'development' }} GITHUB_REF: ${{ github.ref }} FASTLANE_XCODEBUILD_SETTINGS_TIMEOUT: 120 FASTLANE_XCODEBUILD_SETTINGS_RETRIES: 6 diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index abfe2a77aa..cebd9b1747 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -57,7 +57,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@68bde559dea0fdcac2102bfdf6230c5f70eb485e # v4.35.4 + uses: github/codeql-action/init@9e0d7b8d25671d64c341c19c0152d693099fb5ba # v4.35.5 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -70,7 +70,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@68bde559dea0fdcac2102bfdf6230c5f70eb485e # v4.35.4 + uses: github/codeql-action/autobuild@9e0d7b8d25671d64c341c19c0152d693099fb5ba # v4.35.5 # ℹ️ Command-line programs to run using the OS shell. # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun @@ -83,6 +83,6 @@ jobs: # ./location_of_script_within_repo/buildscript.sh - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@68bde559dea0fdcac2102bfdf6230c5f70eb485e # v4.35.4 + uses: github/codeql-action/analyze@9e0d7b8d25671d64c341c19c0152d693099fb5ba # v4.35.5 with: category: '/language:${{matrix.language}}' diff --git a/.github/workflows/static_analysis.yml b/.github/workflows/static_analysis.yml index d347317793..6fdd7af18b 100644 --- a/.github/workflows/static_analysis.yml +++ b/.github/workflows/static_analysis.yml @@ -72,10 +72,6 @@ jobs: run: flutter pub get working-directory: ./mobile/packages/ui - - name: Install dependencies for UI Showcase - run: flutter pub get - working-directory: ./mobile/packages/ui/showcase - - name: Generate translation files run: mise //mobile:codegen:translation diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index d97e759e7c..98179825eb 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -30,25 +30,32 @@ jobs: filters: | i18n: - 'i18n/**' + - 'mise.toml' web: - 'web/**' - 'i18n/**' - 'packages/sdk/**' - 'pnpm-lock.yaml' + - 'mise.toml' server: - 'server/**' - 'pnpm-lock.yaml' + - 'mise.toml' cli: - 'packages/cli/**' - 'packages/sdk/**' - 'pnpm-lock.yaml' + - 'mise.toml' e2e: - 'e2e/**' - 'pnpm-lock.yaml' + - 'mise.toml' mobile: - 'mobile/**' + - 'mise.toml' machine-learning: - 'machine-learning/**' + - 'mise.toml' .github: - '.github/**' force-filters: | diff --git a/Makefile b/Makefile index 648aed5120..eb8bad09f3 100644 --- a/Makefile +++ b/Makefile @@ -1,46 +1,46 @@ dev: - @trap 'make dev-down' EXIT; COMPOSE_BAKE=true docker compose -f ./docker/docker-compose.dev.yml up --remove-orphans + @printf "This command has been removed. Please use:\n\n mise dev # or mise //:dev from another directory\n\n" >&2 && exit 1 dev-down: - docker compose -f ./docker/docker-compose.dev.yml down --remove-orphans + @printf "This command has been removed. Please use:\n\n mise dev-down # or mise //:dev-down from another directory\n\n" >&2 && exit 1 dev-update: - @trap 'make dev-down' EXIT; COMPOSE_BAKE=true docker compose -f ./docker/docker-compose.dev.yml up --build -V --remove-orphans + @printf "This command has been removed. Please use:\n\n mise dev-update # or mise //:dev-update from another directory\n\n" >&2 && exit 1 dev-scale: - @trap 'make dev-down' EXIT; COMPOSE_BAKE=true docker compose -f ./docker/docker-compose.dev.yml up --build -V --scale immich-server=3 --remove-orphans + @printf "This command has been removed. Please use:\n\n mise dev-scale # or mise //:dev-scale from another directory\n\n" >&2 && exit 1 dev-docs: npm --prefix docs run start .PHONY: e2e e2e: - @trap 'make e2e-down' EXIT; COMPOSE_BAKE=true docker compose -f ./e2e/docker-compose.yml up --remove-orphans + @printf "This command has been removed. Please use:\n\n mise e2e # or mise //:e2e from another directory\n\n" >&2 && exit 1 e2e-dev: - @trap 'make e2e-down' EXIT; COMPOSE_BAKE=true docker compose -f ./e2e/docker-compose.dev.yml up --remove-orphans + @printf "This command has been removed. Please use:\n\n mise e2e-dev # or mise //:e2e-dev from another directory\n\n" >&2 && exit 1 e2e-update: - @trap 'make e2e-down' EXIT; COMPOSE_BAKE=true docker compose -f ./e2e/docker-compose.yml up --build -V --remove-orphans + @printf "This command has been removed. Please use:\n\n mise e2e-update # or mise //:e2e-update from another directory\n\n" >&2 && exit 1 e2e-down: - docker compose -f ./e2e/docker-compose.yml down --remove-orphans + @printf "This command has been removed. Please use:\n\n mise e2e-down # or mise //:e2e-down from another directory\n\n" >&2 && exit 1 prod: - @trap 'make prod-down' EXIT; COMPOSE_BAKE=true docker compose -f ./docker/docker-compose.prod.yml up --build -V --remove-orphans + @printf "This command has been removed. Please use:\n\n mise prod # or mise //:prod from another directory\n\n" >&2 && exit 1 prod-down: - docker compose -f ./docker/docker-compose.prod.yml down --remove-orphans + @printf "This command has been removed. Please use:\n\n mise prod-down # or mise //:prod-down from another directory\n\n" >&2 && exit 1 prod-scale: - @trap 'make prod-down' EXIT; COMPOSE_BAKE=true docker compose -f ./docker/docker-compose.prod.yml up --build -V --scale immich-server=3 --scale immich-microservices=3 --remove-orphans + @printf "This command has been removed. Please use:\n\n mise prod-scale # or mise //:prod-scale from another directory\n\n" >&2 && exit 1 .PHONY: open-api open-api: - @printf "This command has been removed. Please use:\n\n mise open-api # or mise //:open-api from another directory\n\n"\n\n >&2 && exit 1 + @printf "This command has been removed. Please use:\n\n mise open-api # or mise //:open-api from another directory\n\n" >&2 && exit 1 sql: - @printf "This command has been removed. Please use:\n\n mise sql # or mise //:sql from another directory\n\n"\n\n >&2 && exit 1 + @printf "This command has been removed. Please use:\n\n mise sql # or mise //:sql from another directory\n\n" >&2 && exit 1 renovate: @@ -52,16 +52,7 @@ renovate: MODULES = e2e server web cli sdk docs .github test-e2e: - docker compose -f ./e2e/docker-compose.yml build - pnpm --filter immich-e2e run test - pnpm --filter immich-e2e run test:web + @printf "This command has been removed. Please use:\n\n mise //e2e:test # or mise //e2e:test-web for web tests, respectively\n\n" >&2 && exit 1 clean: - find . -name "node_modules" -type d -prune -exec rm -rf {} + - find . -name "dist" -type d -prune -exec rm -rf '{}' + - find . -name "build" -type d -prune -exec rm -rf '{}' + - find . -name ".svelte-kit" -type d -prune -exec rm -rf '{}' + - find . -name "coverage" -type d -prune -exec rm -rf '{}' + - find . -name ".pnpm-store" -type d -prune -exec rm -rf '{}' + - command -v docker >/dev/null 2>&1 && docker compose -f ./docker/docker-compose.dev.yml down -v --remove-orphans || true - command -v docker >/dev/null 2>&1 && docker compose -f ./e2e/docker-compose.yml down -v --remove-orphans || true + @printf "This command has been removed. Please use:\n\n mise clean # or mise //:clean from another directory\n\n" >&2 && exit 1 diff --git a/deployment/mise.lock b/deployment/mise.lock new file mode 100644 index 0000000000..fb7be27b99 --- /dev/null +++ b/deployment/mise.lock @@ -0,0 +1,65 @@ +# @generated - this file is auto-generated by `mise lock` https://mise.en.dev/dev-tools/mise-lock.html + +[[tools.opentofu]] +version = "1.11.6" +backend = "aqua:opentofu/opentofu" + +[tools.opentofu."platforms.linux-arm64"] +checksum = "sha256:d4f2ab15776925864b049bb329d69682851de6f5204f256e9fa86d07a0308850" +url = "https://github.com/opentofu/opentofu/releases/download/v1.11.6/tofu_1.11.6_linux_arm64.tar.gz" + +[tools.opentofu."platforms.linux-arm64-musl"] +checksum = "sha256:d4f2ab15776925864b049bb329d69682851de6f5204f256e9fa86d07a0308850" +url = "https://github.com/opentofu/opentofu/releases/download/v1.11.6/tofu_1.11.6_linux_arm64.tar.gz" + +[tools.opentofu."platforms.linux-x64"] +checksum = "sha256:02800fafa2753a9f50c38483e2fdf5bc353fd62895eb9e25eec9a5145df3a69e" +url = "https://github.com/opentofu/opentofu/releases/download/v1.11.6/tofu_1.11.6_linux_amd64.tar.gz" + +[tools.opentofu."platforms.linux-x64-musl"] +checksum = "sha256:02800fafa2753a9f50c38483e2fdf5bc353fd62895eb9e25eec9a5145df3a69e" +url = "https://github.com/opentofu/opentofu/releases/download/v1.11.6/tofu_1.11.6_linux_amd64.tar.gz" + +[tools.opentofu."platforms.macos-arm64"] +checksum = "sha256:62d7fa8539e13b444827aa0a3b90c5972da5c47e8f8882d9dcf2e430e78840c1" +url = "https://github.com/opentofu/opentofu/releases/download/v1.11.6/tofu_1.11.6_darwin_arm64.tar.gz" + +[tools.opentofu."platforms.macos-x64"] +checksum = "sha256:1408cdef1c380f914565e6b4bb70794c6b163f195fcb233357f3d6c5745906b6" +url = "https://github.com/opentofu/opentofu/releases/download/v1.11.6/tofu_1.11.6_darwin_amd64.tar.gz" + +[tools.opentofu."platforms.windows-x64"] +checksum = "sha256:27323f70c875b8251bfd7e61a4cffc3ebff4e56ed1e611b955016f0c7077367e" +url = "https://github.com/opentofu/opentofu/releases/download/v1.11.6/tofu_1.11.6_windows_amd64.tar.gz" + +[[tools.terragrunt]] +version = "1.0.3" +backend = "aqua:gruntwork-io/terragrunt" + +[tools.terragrunt."platforms.linux-arm64"] +checksum = "sha256:e5b60ab05b5214db694e6bc215d8124fb626e277cdb56b86f6147ae110d510fe" +url = "https://github.com/gruntwork-io/terragrunt/releases/download/v1.0.3/terragrunt_linux_arm64.tar.gz" + +[tools.terragrunt."platforms.linux-arm64-musl"] +checksum = "sha256:e5b60ab05b5214db694e6bc215d8124fb626e277cdb56b86f6147ae110d510fe" +url = "https://github.com/gruntwork-io/terragrunt/releases/download/v1.0.3/terragrunt_linux_arm64.tar.gz" + +[tools.terragrunt."platforms.linux-x64"] +checksum = "sha256:6d48049baf82e0bf9c804368dc85cbfeadc10955e33777e9e8de3e020b94b073" +url = "https://github.com/gruntwork-io/terragrunt/releases/download/v1.0.3/terragrunt_linux_amd64.tar.gz" + +[tools.terragrunt."platforms.linux-x64-musl"] +checksum = "sha256:6d48049baf82e0bf9c804368dc85cbfeadc10955e33777e9e8de3e020b94b073" +url = "https://github.com/gruntwork-io/terragrunt/releases/download/v1.0.3/terragrunt_linux_amd64.tar.gz" + +[tools.terragrunt."platforms.macos-arm64"] +checksum = "sha256:aacb5be2ca5475300cbce246dfbd8a45eb47510fbaa70fab8561c49ef5db03aa" +url = "https://github.com/gruntwork-io/terragrunt/releases/download/v1.0.3/terragrunt_darwin_arm64.tar.gz" + +[tools.terragrunt."platforms.macos-x64"] +checksum = "sha256:3133c2251e191aede8e3dd2a5b3aee2e91c5f08f88f117aee40eed9a24c8ef6b" +url = "https://github.com/gruntwork-io/terragrunt/releases/download/v1.0.3/terragrunt_darwin_amd64.tar.gz" + +[tools.terragrunt."platforms.windows-x64"] +checksum = "sha256:183b2745b4e04980a6bfa4450ff81956a12596ca22d70f7aaa793980f5b036db" +url = "https://github.com/gruntwork-io/terragrunt/releases/download/v1.0.3/terragrunt_windows_amd64.exe.tar.gz" diff --git a/docker/docker-compose.dev.yml b/docker/docker-compose.dev.yml index 350e82e767..adcb6b628f 100644 --- a/docker/docker-compose.dev.yml +++ b/docker/docker-compose.dev.yml @@ -21,7 +21,7 @@ services: volumes: - ..:/usr/src/app # - ../../ui:/usr/src/ui - - pnpm_cache:/buildcache/pnpm_cache + - build_cache:/buildcache - server_node_modules:/usr/src/app/server/node_modules - web_node_modules:/usr/src/app/web/node_modules - github_node_modules:/usr/src/app/.github/node_modules @@ -45,11 +45,11 @@ services: target: dev command: - | - pnpm install + mise install touch /tmp/init-complete exec tail -f /dev/null volumes: - - pnpm_store_server:/buildcache/pnpm-store + - build_cache:/buildcache restart: 'no' healthcheck: test: ['CMD', 'test', '-f', '/tmp/init-complete'] @@ -73,7 +73,6 @@ services: volumes: - ${UPLOAD_LOCATION}/photos:/data - /etc/localtime:/etc/localtime:ro - - pnpm_store_server:/buildcache/pnpm-store - ../packages/plugin-core:/build/plugins/immich-plugin-core env_file: - .env @@ -122,8 +121,6 @@ services: ports: - 3000:3000 - 24678:24678 - volumes: - - pnpm_store_web:/buildcache/pnpm-store restart: unless-stopped depends_on: immich-init: @@ -203,9 +200,7 @@ volumes: model_cache: prometheus_data: grafana_data: - pnpm_cache: - pnpm_store_server: - pnpm_store_web: + build_cache: server_node_modules: web_node_modules: github_node_modules: diff --git a/docs/docs/FAQ.mdx b/docs/docs/FAQ.mdx index 7b7a265ddf..1a17385132 100644 --- a/docs/docs/FAQ.mdx +++ b/docs/docs/FAQ.mdx @@ -26,6 +26,8 @@ For organizations seeking to resell Immich, we have established the following gu When in doubt or if you have an edge case scenario, we encourage you to contact us directly via email to discuss the use of our trademark. We can provide clear guidance on what is acceptable and what is not. You can reach out at: questions@immich.app +--- + ## User ### How can I reset the admin password? @@ -36,6 +38,10 @@ The admin password can be reset by running the [reset-admin-password](/administr You can see the list of all users by running [list-users](/administration/server-commands.md) Command on the Immich-server. +### How can I change my profile picture? + +View a single photo, press the three dots in the top-right to show context menu, and select "Set as profile picture". In the pop-up, use your mouse scroll wheel to zoom in the picture until it completely fills the circle. Click and drag the picture to align it to your liking. Press "Save" to save your changes. + --- ## Mobile App diff --git a/docs/docs/developer/database-migrations.md b/docs/docs/developer/database-migrations.md index a73e7e747c..05f5941f70 100644 --- a/docs/docs/developer/database-migrations.md +++ b/docs/docs/developer/database-migrations.md @@ -5,7 +5,7 @@ After making any changes in the `server/src/schema`, a database migration need t 1. Run the command ```bash -pnpm run migrations:generate +mise //server:migrations generate ``` 2. Check if the migration file makes sense. @@ -18,7 +18,7 @@ The server will automatically detect `*.ts` file changes and restart. Part of th If you need to undo the most recently applied migration—for example, when developing or testing on schema changes—run: ```bash -pnpm run migrations:revert +mise //server:migrations revert ``` This command rolls back the latest migration and brings the database schema back to its previous state. diff --git a/docs/docs/developer/devcontainers.md b/docs/docs/developer/devcontainers.md index 99f340c557..27004215d5 100644 --- a/docs/docs/developer/devcontainers.md +++ b/docs/docs/developer/devcontainers.md @@ -252,44 +252,33 @@ To connect the mobile app to your Dev Container: The Dev Container supports multiple ways to run tests: -#### Using Mise Commands (Recommended) - ```bash -# Run tests for specific components -mise run checklist # in `server/`, `web/`, `packages/cli` +# Server +mise //server:test # unit tests +mise //server:test-medium # medium / integration tests + +# Web +mise //web:test # unit tests + +# E2E +mise //e2e:test # API tests +mise //e2e:test-web # web UI tests (Playwright) + +# Run all checks for a component +mise //server:checklist +mise //web:checklist ``` -#### Using PNPM Directly - -```bash -# Server tests -cd /workspaces/immich/server -pnpm test # Run all tests -pnpm run test:medium # Medium tests (integration tests) -pnpm run test:watch # Watch mode -pnpm run test:cov # Coverage report - -# Web tests -cd /workspaces/immich/web -pnpm test # Run all tests -pnpm run test:watch # Watch mode - -# E2E tests -cd /workspaces/immich/e2e -pnpm run test # Run API tests -pnpm run test:web # Run web UI tests -``` - -### Additional Make Commands +### Additional Commands ```bash # API generation -make open-api # Generate OpenAPI specs -make open-api-typescript # Generate TypeScript SDK -make open-api-dart # Generate Dart SDK +mise //:open-api # Generate OpenAPI specs +mise //:open-api-typescript # Generate TypeScript SDK +mise //:open-api-dart # Generate Dart SDK # Database -mise sql # Sync database schema +mise //server:sql # Sync database schema ``` ### Debugging diff --git a/docs/docs/developer/pr-checklist.md b/docs/docs/developer/pr-checklist.md index c4ed44c77b..bab9924126 100644 --- a/docs/docs/developer/pr-checklist.md +++ b/docs/docs/developer/pr-checklist.md @@ -8,34 +8,42 @@ When contributing code through a pull request, please check the following: ## Web Checks -- [ ] `pnpm run lint` (linting via ESLint) -- [ ] `pnpm run format` (formatting via Prettier) -- [ ] `pnpm run check:svelte` (Type checking via SvelteKit) -- [ ] `pnpm run check:typescript` (check typescript) -- [ ] `pnpm test` (unit tests) +- [ ] `mise //web:lint` (linting via ESLint) +- [ ] `mise //web:format` (formatting via Prettier) +- [ ] `mise //web:check-svelte` (type checking via SvelteKit) +- [ ] `mise //web:check-typescript` (type checking via `tsc`) +- [ ] `mise //web:test` (unit tests) :::tip AIO -Run all web checks with `pnpm run check:all` +Run all web checks with `mise //web:checklist` +::: + +:::tip Auto Fix +Use `mise //web:lint-fix` and `mise //web:format-fix` to automatically correct some issues. ::: ## Documentation -- [ ] `pnpm run format` (formatting via Prettier) +- [ ] `mise //docs:format` (formatting via Prettier) - [ ] Update the `_redirects` file if you have renamed a page or removed it from the documentation. +:::tip Auto Fix +Use `mise //docs:format-fix` to automatically fix formatting. +::: + ## Server Checks -- [ ] `pnpm run lint` (linting via ESLint) -- [ ] `pnpm run format` (formatting via Prettier) -- [ ] `pnpm run check` (Type checking via `tsc`) -- [ ] `pnpm test` (unit tests) +- [ ] `mise //server:lint` (linting via ESLint) +- [ ] `mise //server:format` (formatting via Prettier) +- [ ] `mise //server:check` (type checking via `tsc`) +- [ ] `mise //server:test` (unit tests) :::tip AIO -Run all server checks with `pnpm run check:all` +Run all server checks with `mise //server:checklist` ::: :::tip Auto Fix -You can use `pnpm run __:fix` to potentially correct some issues automatically for `pnpm run format` and `lint`. +Use `mise //server:lint-fix` and `mise //server:format-fix` to automatically correct some issues. ::: ## Mobile Checklist @@ -53,6 +61,17 @@ Run all these commands at once with `mise //mobile:checklist` You can use `mise //mobile:lint-fix` to potentially correct some issues automatically for `mise //mobile:lint`. ::: +## Machine Learning Checklist + +- [ ] `mise //machine-learning:lint` (linting via ruff) +- [ ] `mise //machine-learning:format` (formatting via ruff) +- [ ] `mise //machine-learning:check` (type checking via mypy) +- [ ] `mise //machine-learning:test` (unit tests via pytest) + +:::tip AIO +Run all machine learning checks with `mise //machine-learning:checklist` +::: + ## 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](/api.md) for more details. diff --git a/docs/docs/developer/setup.md b/docs/docs/developer/setup.md index c5d782fb52..cac9f501d8 100644 --- a/docs/docs/developer/setup.md +++ b/docs/docs/developer/setup.md @@ -32,6 +32,10 @@ This environment includes the services below. Additional details are available i All the services are packaged to run as with single Docker Compose command. +:::tip mise +[mise](https://mise.jdx.dev) is used throughout the project to manage tool versions and run tasks. [Install mise](https://mise.jdx.dev/installing-mise.html), then from the repo root run `mise trust` and `mise install` to get all required tools. Tasks for each service can be run from the repo root using `mise //namespace:task` (e.g. `mise //server:lint`). To list all available tasks, run `mise tasks ls --all`. +::: + ### Server and web apps 1. Clone the project repo. @@ -56,22 +60,23 @@ You can access the web from `http://your-machine-ip:3000` or `http://localhost:3 #### Connect web to a remote backend -If you only want to do web development connected to an existing, remote backend, follow these steps: - -1. Build the Immich SDK - `pnpm --filter @immich/sdk install && pnpm --filter @immich/sdk build` -2. Enter the web directory - `cd web/` -3. Install web dependencies - `pnpm i` -4. Start the web development server +If you only want to do web development connected to an existing, remote backend, run from the repo root: ```bash -IMMICH_SERVER_URL=https://demo.immich.app/ pnpm run dev +IMMICH_SERVER_URL=https://demo.immich.app/ mise //web:start +``` + +This will install all dependencies (including the SDK) and start the dev server in one step. To connect to the hosted demo server specifically, use the shorthand: + +```bash +mise //web:start-demo ``` If you're using PowerShell on Windows you may need to set the env var separately like so: ```powershell $env:IMMICH_SERVER_URL = "https://demo.immich.app/" -pnpm run dev +mise //web:start ``` #### `@immich/ui` @@ -90,24 +95,38 @@ To see local changes to `@immich/ui` in Immich, do the following: #### Setup -1. [Install mise](https://mise.jdx.dev/installing-mise.html). -2. Change to the immich (root) directory and trust the mise config with `mise trust`. -3. Install tools with mise: `mise install`. -4. Change to the `mobile/` directory. -5. Run `flutter pub get` to install the dependencies. -6. Run `make translation` to generate the translation file. -7. Run `flutter run` to start the app. +1. Run `mise //mobile:install` to install Flutter dependencies. +2. Run `mise //mobile:translation` to generate the translation file. +3. Change to the `mobile/` directory and run `flutter run` to start the app. #### Translation -To add a new translation text, enter the key-value pair in the `i18n/en.json` in the root of the immich project. Then, from the `mobile/` directory, run +To add a new translation text, enter the key-value pair in the `i18n/en.json` in the root of the immich project. Then run: ```bash -make translation +mise //mobile:translation ``` The mobile app asks you what backend to connect to. You can utilize the demo backend (https://demo.immich.app/) if you don't need to change server code or upload photos. Alternatively, you can run the server yourself per the instructions above. +#### UI components and widget previews + +Shared design-system widgets (buttons, inputs, forms) live in the +[`immich_ui` package](https://github.com/immich-app/immich/tree/main/mobile/packages/ui/) +under `mobile/packages/ui/`. Components are defined in `lib/src/components/` +and have matching previews in `lib/src/previews/`. + +To inspect a component in isolation with a light/dark toggle and hot reload, +launch [Flutter's Widget Previewer](https://docs.flutter.dev/tools/widget-previewer): + +```bash +cd mobile/packages/ui +flutter widget-preview start +``` + +In VS Code or Android Studio with the Flutter plugin, the previewer +auto-starts when you open the **Flutter Widget Preview** tab in the sidebar. + ## IDE setup ### Lint / format extensions diff --git a/docs/docs/developer/testing.md b/docs/docs/developer/testing.md index d2f64b7824..7f8ed629e0 100644 --- a/docs/docs/developer/testing.md +++ b/docs/docs/developer/testing.md @@ -4,8 +4,8 @@ ### Unit tests -Unit are run by calling `pnpm run test` from the `server/` directory. -You need to run `pnpm install` (in `server/`) before _once_. +Unit tests are run with `mise //server:test`. +You need to run `mise //server:install` before _once_. ### End to end tests @@ -17,8 +17,7 @@ make e2e Before you can run the tests, you need to run the following commands _once_: -- `pnpm install` -- `pnpm --filter @immich/sdk --filter @immich/cli build` +- `mise //e2e:ci-setup` (installs e2e, SDK, and CLI dependencies) - `mise //:open-api` Once the test environment is running, the e2e tests can be run via: diff --git a/docs/docs/install/environment-variables.md b/docs/docs/install/environment-variables.md index ca22c5ad34..0932fa2855 100644 --- a/docs/docs/install/environment-variables.md +++ b/docs/docs/install/environment-variables.md @@ -154,33 +154,33 @@ Redis (Sentinel) URL example JSON before encoding: ## Machine Learning -| Variable | Description | Default | Containers | -| :---------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------- | :-----------------------------: | :--------------- | -| `MACHINE_LEARNING_MODEL_TTL` | Inactivity time (s) before a model is unloaded (disabled if \<= 0) | `300` | machine learning | -| `MACHINE_LEARNING_MODEL_TTL_POLL_S` | Interval (s) between checks for the model TTL (disabled if \<= 0) | `10` | machine learning | -| `MACHINE_LEARNING_CACHE_FOLDER` | Directory where models are downloaded | `/cache` | machine learning | -| `MACHINE_LEARNING_REQUEST_THREADS`\*1 | Thread count of the request thread pool (disabled if \<= 0) | number of CPU cores | machine learning | -| `MACHINE_LEARNING_MODEL_INTER_OP_THREADS` | Number of parallel model operations | `1` | machine learning | -| `MACHINE_LEARNING_MODEL_INTRA_OP_THREADS` | Number of threads for each model operation | `2` | machine learning | -| `MACHINE_LEARNING_WORKERS`\*2 | Number of worker processes to spawn | `1` | machine learning | -| `MACHINE_LEARNING_HTTP_KEEPALIVE_TIMEOUT_S`\*3 | HTTP Keep-alive time in seconds | `2` | machine learning | -| `MACHINE_LEARNING_WORKER_TIMEOUT` | Maximum time (s) of unresponsiveness before a worker is killed | `120` (`300` if using OpenVINO) | machine learning | -| `MACHINE_LEARNING_PRELOAD__CLIP__TEXTUAL` | Comma-separated list of (textual) CLIP model(s) to preload and cache | | machine learning | -| `MACHINE_LEARNING_PRELOAD__CLIP__VISUAL` | Comma-separated list of (visual) CLIP model(s) to preload and cache | | machine learning | -| `MACHINE_LEARNING_PRELOAD__FACIAL_RECOGNITION__RECOGNITION` | Comma-separated list of (recognition) facial recognition model(s) to preload and cache | | machine learning | -| `MACHINE_LEARNING_PRELOAD__FACIAL_RECOGNITION__DETECTION` | Comma-separated list of (detection) facial recognition model(s) to preload and cache | | machine learning | -| `MACHINE_LEARNING_PRELOAD__OCR__RECOGNITION` | Comma-separated list of (recognition) OCR model(s) to preload and cache | | machine learning | -| `MACHINE_LEARNING_PRELOAD__OCR__DETECTION` | Comma-separated list of (detection) OCR model(s) to preload and cache | | machine learning | -| `MACHINE_LEARNING_ANN` | Enable ARM-NN hardware acceleration if supported | `True` | machine learning | -| `MACHINE_LEARNING_ANN_FP16_TURBO` | Execute operations in FP16 precision: increasing speed, reducing precision (applies only to ARM-NN) | `False` | machine learning | -| `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_MAX_BATCH_SIZE__OCR` | Set the maximum number of boxes that will be processed at once by the OCR model | `6` | machine learning | -| `MACHINE_LEARNING_RKNN` | Enable RKNN hardware acceleration if supported | `True` | machine learning | -| `MACHINE_LEARNING_RKNN_THREADS` | How many threads of RKNN runtime should be spun up while inferencing. | `1` | machine learning | -| `MACHINE_LEARNING_MODEL_ARENA` | Pre-allocates CPU memory to avoid memory fragmentation | true | machine learning | -| `MACHINE_LEARNING_OPENVINO_PRECISION` | If set to FP16, uses half-precision floating-point operations for faster inference with reduced accuracy (one of [`FP16`, `FP32`], applies only to OpenVINO) | `FP32` | machine learning | +| Variable | Description | Default | Containers | +| :---------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------- | :--------------------------: | :--------------- | +| `MACHINE_LEARNING_MODEL_TTL` | Inactivity time (s) before a model is unloaded (disabled if \<= 0) | `300` | machine learning | +| `MACHINE_LEARNING_MODEL_TTL_POLL_S` | Interval (s) between checks for the model TTL (disabled if \<= 0) | `10` | machine learning | +| `MACHINE_LEARNING_CACHE_FOLDER` | Directory where models are downloaded | `/cache` | machine learning | +| `MACHINE_LEARNING_REQUEST_THREADS`\*1 | Thread count of the request thread pool (disabled if \<= 0) | number of CPU cores | machine learning | +| `MACHINE_LEARNING_MODEL_INTER_OP_THREADS` | Number of parallel model operations | `1` | machine learning | +| `MACHINE_LEARNING_MODEL_INTRA_OP_THREADS` | Number of threads for each model operation | `2` | machine learning | +| `MACHINE_LEARNING_WORKERS`\*2 | Number of worker processes to spawn | `1` | machine learning | +| `MACHINE_LEARNING_HTTP_KEEPALIVE_TIMEOUT_S`\*3 | HTTP Keep-alive time in seconds | `2` | machine learning | +| `MACHINE_LEARNING_WORKER_TIMEOUT` | Maximum time (s) of unresponsiveness before a worker is killed | `300` (`900` if using ROCm) | machine learning | +| `MACHINE_LEARNING_PRELOAD__CLIP__TEXTUAL` | Comma-separated list of (textual) CLIP model(s) to preload and cache | | machine learning | +| `MACHINE_LEARNING_PRELOAD__CLIP__VISUAL` | Comma-separated list of (visual) CLIP model(s) to preload and cache | | machine learning | +| `MACHINE_LEARNING_PRELOAD__FACIAL_RECOGNITION__RECOGNITION` | Comma-separated list of (recognition) facial recognition model(s) to preload and cache | | machine learning | +| `MACHINE_LEARNING_PRELOAD__FACIAL_RECOGNITION__DETECTION` | Comma-separated list of (detection) facial recognition model(s) to preload and cache | | machine learning | +| `MACHINE_LEARNING_PRELOAD__OCR__RECOGNITION` | Comma-separated list of (recognition) OCR model(s) to preload and cache | | machine learning | +| `MACHINE_LEARNING_PRELOAD__OCR__DETECTION` | Comma-separated list of (detection) OCR model(s) to preload and cache | | machine learning | +| `MACHINE_LEARNING_ANN` | Enable ARM-NN hardware acceleration if supported | `True` | machine learning | +| `MACHINE_LEARNING_ANN_FP16_TURBO` | Execute operations in FP16 precision: increasing speed, reducing precision (applies only to ARM-NN) | `False` | machine learning | +| `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_MAX_BATCH_SIZE__OCR` | Set the maximum number of boxes that will be processed at once by the OCR model | `6` | machine learning | +| `MACHINE_LEARNING_RKNN` | Enable RKNN hardware acceleration if supported | `True` | machine learning | +| `MACHINE_LEARNING_RKNN_THREADS` | How many threads of RKNN runtime should be spun up while inferencing. | `1` | machine learning | +| `MACHINE_LEARNING_MODEL_ARENA` | Pre-allocates CPU memory to avoid memory fragmentation | true | machine learning | +| `MACHINE_LEARNING_OPENVINO_PRECISION` | If set to FP16, uses half-precision floating-point operations for faster inference with reduced accuracy (one of [`FP16`, `FP32`], applies only to OpenVINO) | `FP32` | machine learning | \*1: It is recommended to begin with this parameter when changing the concurrency levels of the machine learning service and then tune the other ones. diff --git a/docs/docusaurus.config.js b/docs/docusaurus.config.js index 00a120b8b6..734317a302 100644 --- a/docs/docusaurus.config.js +++ b/docs/docusaurus.config.js @@ -10,7 +10,6 @@ const config = { url: 'https://docs.immich.app', baseUrl: '/', onBrokenLinks: 'throw', - onBrokenMarkdownLinks: 'warn', favicon: 'img/favicon.png', // GitHub pages deployment config. @@ -29,6 +28,9 @@ const config = { // Mermaid diagrams markdown: { mermaid: true, + hooks: { + onBrokenMarkdownLinks: 'warn', + }, }, themes: ['@docusaurus/theme-mermaid'], diff --git a/docs/mise.lock b/docs/mise.lock new file mode 100644 index 0000000000..dee476c431 --- /dev/null +++ b/docs/mise.lock @@ -0,0 +1,5 @@ +# @generated - this file is auto-generated by `mise lock` https://mise.en.dev/dev-tools/mise-lock.html + +[[tools.wrangler]] +version = "4.66.0" +backend = "npm:wrangler" diff --git a/docs/mise.toml b/docs/mise.toml index 32fcac5578..165f1f4a93 100644 --- a/docs/mise.toml +++ b/docs/mise.toml @@ -3,7 +3,7 @@ run = "pnpm install --filter documentation --frozen-lockfile" [tasks.start] env._.path = "./node_modules/.bin" -run = "docusaurus --port 3005" +run = "docusaurus start --port 3005" [tasks.build] env._.path = "./node_modules/.bin" @@ -28,4 +28,4 @@ run = "prettier --write ." run = "wrangler pages deploy build --project-name=${PROJECT_NAME} --branch=${BRANCH_NAME}" [tools] -wrangler = "4.66.0" +wrangler = "4.91.0" diff --git a/e2e/docker-compose.dev.yml b/e2e/docker-compose.dev.yml index b301ef8441..ac6973a0d6 100644 --- a/e2e/docker-compose.dev.yml +++ b/e2e/docker-compose.dev.yml @@ -83,9 +83,7 @@ volumes: model_cache: prometheus_data: grafana_data: - pnpm_cache: - pnpm_store_server: - pnpm_store_web: + build_cache: server_node_modules: web_node_modules: github_node_modules: diff --git a/e2e/mise.toml b/e2e/mise.toml index 99056f9ead..b149922564 100644 --- a/e2e/mise.toml +++ b/e2e/mise.toml @@ -1,11 +1,21 @@ [tasks.install] run = "pnpm install --filter immich-e2e --frozen-lockfile" +[tasks.build] +dir = "{{ config_root }}" +run = "docker compose build" + [tasks.test] +depends = ["//e2e:build", "//e2e:ci-setup"] env._.path = "./node_modules/.bin" run = "vitest --run" +[tasks.playwright-install] +env._.path = "./node_modules/.bin" +run = "playwright install" + [tasks."test-web"] +depends = ["//e2e:build", "//e2e:ci-setup", "//e2e:playwright-install"] env._.path = "./node_modules/.bin" run = "playwright test" @@ -30,7 +40,12 @@ run = "tsc --noEmit" [tasks.ci-setup] -depends = ["//:sdk:install", "//:sdk:build", "//cli:install", "//cli:build"] +depends = [ + "//:sdk:install", + "//:sdk:build", + "//packages/cli:install", + "//packages/cli:build", +] run = { task = ":install" } diff --git a/e2e/package.json b/e2e/package.json index aa6bee180f..383866c197 100644 --- a/e2e/package.json +++ b/e2e/package.json @@ -33,7 +33,7 @@ "@playwright/test": "^1.44.1", "@socket.io/component-emitter": "^3.1.2", "@types/luxon": "^3.4.2", - "@types/node": "^24.12.2", + "@types/node": "^24.12.4", "@types/pg": "^8.15.1", "@types/pngjs": "^6.0.4", "@types/supertest": "^7.0.0", diff --git a/e2e/src/ui/generators/timeline/rest-response.ts b/e2e/src/ui/generators/timeline/rest-response.ts index 52dfa4c493..553ce18005 100644 --- a/e2e/src/ui/generators/timeline/rest-response.ts +++ b/e2e/src/ui/generators/timeline/rest-response.ts @@ -55,8 +55,8 @@ export function toColumnarFormat(assets: MockTimelineAsset[]): TimeBucketAssetRe result.duration.push(asset.duration); result.projectionType.push(asset.projectionType); result.livePhotoVideoId.push(asset.livePhotoVideoId); - result.city.push(asset.city); - result.country.push(asset.country); + result.city?.push(asset.city); + result.country?.push(asset.country); result.visibility.push(asset.visibility); } diff --git a/e2e/src/ui/specs/timeline/timeline.e2e-spec.ts b/e2e/src/ui/specs/timeline/timeline.e2e-spec.ts index c2a3b8e724..6f986df84f 100644 --- a/e2e/src/ui/specs/timeline/timeline.e2e-spec.ts +++ b/e2e/src/ui/specs/timeline/timeline.e2e-spec.ts @@ -536,7 +536,7 @@ test.describe('Timeline', () => { force: false, ids: [assetToTrash.id], }); - await page.locator('#asset-selection-app-bar').getByLabel('Close').click(); + await page.locator('#control-bar').getByLabel('Close').click(); await page.getByText('Trash', { exact: true }).click(); await timelineUtils.waitForTimelineLoad(page); await thumbnailUtils.expectInViewport(page, assetToTrash.id); @@ -676,7 +676,7 @@ test.describe('Timeline', () => { ids: [assetToArchive.id], }); await thumbnailUtils.expectThumbnailIsArchive(page, assetToArchive.id); - await page.locator('#asset-selection-app-bar').getByLabel('Close').click(); + await page.locator('#control-bar').getByLabel('Close').click(); await page.getByRole('link').getByText('Archive').click(); await timelineUtils.waitForTimelineLoad(page); await thumbnailUtils.expectInViewport(page, assetToArchive.id); @@ -823,7 +823,7 @@ test.describe('Timeline', () => { }); // ensure thumbnail still exists and has favorite icon await thumbnailUtils.expectThumbnailIsFavorite(page, assetToFavorite.id); - await page.locator('#asset-selection-app-bar').getByLabel('Close').click(); + await page.locator('#control-bar').getByLabel('Close').click(); await page.getByRole('link').getByText('Favorites').click(); await timelineUtils.waitForTimelineLoad(page); await pageUtils.goToAsset(page, assetToFavorite.fileCreatedAt); diff --git a/i18n/en.json b/i18n/en.json index 1b849e4374..95bfc19610 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -698,6 +698,7 @@ "birthdate_saved": "Date of birth saved successfully", "birthdate_set_description": "Date of birth is used to calculate the age of this person at the time of a photo.", "blurred_background": "Blurred background", + "browse_templates": "Browse templates", "bugs_and_feature_requests": "Bugs & Feature Requests", "build": "Build", "build_image": "Build Image", @@ -839,6 +840,7 @@ "copy_error": "Copy error", "copy_file_path": "Copy file path", "copy_image": "Copy Image", + "copy_json": "Copy JSON", "copy_link": "Copy link", "copy_link_to_clipboard": "Copy link to clipboard", "copy_password": "Copy password", @@ -976,7 +978,10 @@ "downloading_asset_filename": "Downloading asset {filename}", "downloading_from_icloud": "Downloading from iCloud", "downloading_media": "Downloading media", + "drag_to_reorder": "Drag to reorder", "drop_files_to_upload": "Drop files anywhere to upload", + "duplicate": "Duplicate", + "duplicate_workflow": "Duplicate workflow", "duplicates": "Duplicates", "duplicates_description": "Resolve each group by indicating which, if any, are duplicates.", "duration": "Duration", @@ -2233,6 +2238,7 @@ "slideshow_repeat": "Repeat slideshow", "slideshow_repeat_description": "Loop back to beginning when slideshow ends", "slideshow_settings": "Slideshow settings", + "smart_album": "Smart album", "sort_albums_by": "Sort albums by...", "sort_created": "Date created", "sort_items": "Number of items", @@ -2259,6 +2265,7 @@ "step_delete_confirm": "Are you sure you want to delete this step?", "step_details": "Step details", "steps": "Steps", + "steps_count": "{count, plural, one {# step} other {# steps}}", "stop_casting": "Stop casting", "stop_motion_photo": "Stop Motion Photo", "stop_photo_sharing": "Stop sharing your photos?", @@ -2420,6 +2427,7 @@ "use_browser_locale_description": "Format dates, times, and numbers based on your browser locale", "use_current_connection": "Use current connection", "use_custom_date_range": "Use custom date range instead", + "use_template": "Use template", "user": "User", "user_has_been_deleted": "This user has been deleted.", "user_id": "User ID", @@ -2481,6 +2489,7 @@ "week": "Week", "welcome": "Welcome", "welcome_to_immich": "Welcome to Immich", + "when": "When", "width": "Width", "wifi_name": "Wi-Fi Name", "workflow": "Workflow", @@ -2493,6 +2502,7 @@ "workflow_name": "Workflow name", "workflow_navigation_prompt": "Are you sure you want to leave without saving your changes?", "workflow_summary": "Workflow summary", + "workflow_templates": "Workflow templates", "workflow_update_success": "Workflow updated successfully", "workflow_updated": "Workflow updated", "workflows": "Workflows", diff --git a/machine-learning/immich_ml/config.py b/machine-learning/immich_ml/config.py index c5ba0bdf0a..d1e44fd70a 100644 --- a/machine-learning/immich_ml/config.py +++ b/machine-learning/immich_ml/config.py @@ -6,7 +6,7 @@ from pathlib import Path from socket import socket from gunicorn.arbiter import Arbiter -from pydantic import BaseModel +from pydantic import BaseModel, Field from pydantic_settings import BaseSettings, SettingsConfigDict from rich.console import Console from rich.logging import RichHandler @@ -42,6 +42,10 @@ class MaxBatchSize(BaseModel): ocr: int | None = None +def default_worker_timeout() -> int: + return 900 if os.environ.get("DEVICE") == "rocm" else 300 + + class Settings(BaseSettings): model_config = SettingsConfigDict( env_prefix="MACHINE_LEARNING_", @@ -54,7 +58,7 @@ class Settings(BaseSettings): model_ttl: int = 300 model_ttl_poll_s: int = 10 workers: int = 1 - worker_timeout: int = 300 + worker_timeout: int = Field(default_factory=default_worker_timeout) http_keepalive_timeout_s: int = 2 test_full: bool = False request_threads: int = os.cpu_count() or 4 diff --git a/machine-learning/immich_ml/models/facial_recognition/recognition.py b/machine-learning/immich_ml/models/facial_recognition/recognition.py index ed1897c9f9..c144bd3eaa 100644 --- a/machine-learning/immich_ml/models/facial_recognition/recognition.py +++ b/machine-learning/immich_ml/models/facial_recognition/recognition.py @@ -89,4 +89,10 @@ class FaceRecognizer(InferenceModel): @property def _batch_size_default(self) -> int | None: providers = ort.get_available_providers() - return None if self.model_format == ModelFormat.ONNX and "OpenVINOExecutionProvider" not in providers else 1 + if ( + self.model_format == ModelFormat.ONNX + and "MIGraphXExecutionProvider" not in providers + and "OpenVINOExecutionProvider" not in providers + ): + return None + return 1 diff --git a/machine-learning/immich_ml/models/ocr/recognition.py b/machine-learning/immich_ml/models/ocr/recognition.py index 6408e4818f..94f40c9285 100644 --- a/machine-learning/immich_ml/models/ocr/recognition.py +++ b/machine-learning/immich_ml/models/ocr/recognition.py @@ -64,6 +64,7 @@ class TextRecognizer(InferenceModel): rec_batch_num=max_batch_size if max_batch_size else 6, rec_img_shape=(3, 48, 320), lang_type=self.language, + model_root_dir=self.cache_dir, ) ) return session diff --git a/machine-learning/immich_ml/sessions/ort.py b/machine-learning/immich_ml/sessions/ort.py index bebd235970..579cafc1cd 100644 --- a/machine-learning/immich_ml/sessions/ort.py +++ b/machine-learning/immich_ml/sessions/ort.py @@ -1,6 +1,7 @@ from __future__ import annotations from pathlib import Path +from threading import Lock from typing import Any import numpy as np @@ -12,6 +13,37 @@ from immich_ml.schemas import ModelPrecision, SessionNode from ..config import log, settings +MigraphxInputSignature = tuple[tuple[str, str, tuple[int, ...]], ...] + +_migraphx_registry_lock = Lock() +_migraphx_model_locks: dict[str, Lock] = {} +_migraphx_compiled_inputs: set[tuple[str, MigraphxInputSignature]] = set() + + +def _migraphx_get_model_lock(model_key: str) -> Lock: + with _migraphx_registry_lock: + lock = _migraphx_model_locks.get(model_key) + if lock is None: + lock = Lock() + _migraphx_model_locks[model_key] = lock + return lock + + +def _migraphx_has_compiled_input(key: tuple[str, MigraphxInputSignature]) -> bool: + with _migraphx_registry_lock: + return key in _migraphx_compiled_inputs + + +def _migraphx_mark_compiled_input(key: tuple[str, MigraphxInputSignature]) -> None: + with _migraphx_registry_lock: + _migraphx_compiled_inputs.add(key) + + +def _migraphx_input_signature( + input_feed: dict[str, NDArray[np.float32]] | dict[str, NDArray[np.int32]], +) -> MigraphxInputSignature: + return tuple((name, str(value.dtype), tuple(value.shape)) for name, value in sorted(input_feed.items())) + class OrtSession: session: ort.InferenceSession @@ -48,7 +80,21 @@ class OrtSession: input_feed: dict[str, NDArray[np.float32]] | dict[str, NDArray[np.int32]], run_options: Any = None, ) -> list[NDArray[np.float32]]: - outputs: list[NDArray[np.float32]] = self.session.run(output_names, input_feed, run_options) + if "MIGraphXExecutionProvider" in self.providers: + model_key = self.model_path.resolve().as_posix() + input_key = (model_key, _migraphx_input_signature(input_feed)) + if not _migraphx_has_compiled_input(input_key): + model_lock = _migraphx_get_model_lock(model_key) + with model_lock: + if not _migraphx_has_compiled_input(input_key): + outputs: list[NDArray[np.float32]] = self.session.run(output_names, input_feed, run_options) + _migraphx_mark_compiled_input(input_key) + return outputs + + outputs = self.session.run(output_names, input_feed, run_options) + return outputs + + outputs = self.session.run(output_names, input_feed, run_options) return outputs @property diff --git a/machine-learning/mise.lock b/machine-learning/mise.lock new file mode 100644 index 0000000000..b9788e603b --- /dev/null +++ b/machine-learning/mise.lock @@ -0,0 +1,72 @@ +# @generated - this file is auto-generated by `mise lock` https://mise.en.dev/dev-tools/mise-lock.html + +[[tools.python]] +version = "3.11.15" +backend = "core:python" + +[tools.python."platforms.linux-arm64"] +checksum = "sha256:243f794278eff6adba96ed3677ec6877175df84c25f140e17f09f9be82d0f12a" +url = "https://github.com/astral-sh/python-build-standalone/releases/download/20260510/cpython-3.11.15+20260510-aarch64-unknown-linux-gnu-install_only_stripped.tar.gz" +provenance = "github-attestations" + +[tools.python."platforms.linux-arm64-musl"] +checksum = "sha256:52b4c52094ff8b383a45c694acf4c5c0e883152be6d5229a35a8186ce907c6eb" +url = "https://github.com/astral-sh/python-build-standalone/releases/download/20260510/cpython-3.11.15+20260510-aarch64-unknown-linux-musl-install_only_stripped.tar.gz" +provenance = "github-attestations" + +[tools.python."platforms.linux-x64"] +checksum = "sha256:171dffd8c0f66e8a0725364a7428015b22fc18dd298b24f541392e17dd0e561f" +url = "https://github.com/astral-sh/python-build-standalone/releases/download/20260510/cpython-3.11.15+20260510-x86_64-unknown-linux-gnu-install_only_stripped.tar.gz" +provenance = "github-attestations" + +[tools.python."platforms.linux-x64-musl"] +checksum = "sha256:2ac90fef8917ebd14826a6d667593a06cf0ae5f745ba9b1147dc086dd35f5284" +url = "https://github.com/astral-sh/python-build-standalone/releases/download/20260510/cpython-3.11.15+20260510-x86_64-unknown-linux-musl-install_only_stripped.tar.gz" +provenance = "github-attestations" + +[tools.python."platforms.macos-arm64"] +checksum = "sha256:fdfc363b538662eb7441a14e06f72c4a992c56af7f401f5730ea5081f8f8ad6e" +url = "https://github.com/astral-sh/python-build-standalone/releases/download/20260510/cpython-3.11.15+20260510-aarch64-apple-darwin-install_only_stripped.tar.gz" +provenance = "github-attestations" + +[tools.python."platforms.macos-x64"] +checksum = "sha256:5f1eb247cbca2c0ad5ccbf6d299a4f54b31b5c63b492d74c3531dc4344a42f88" +url = "https://github.com/astral-sh/python-build-standalone/releases/download/20260510/cpython-3.11.15+20260510-x86_64-apple-darwin-install_only_stripped.tar.gz" +provenance = "github-attestations" + +[tools.python."platforms.windows-x64"] +checksum = "sha256:756d7f148498b8822f6aedf44a020613576f09983161f346ad36dcef6238cdc3" +url = "https://github.com/astral-sh/python-build-standalone/releases/download/20260510/cpython-3.11.15+20260510-x86_64-pc-windows-msvc-install_only_stripped.tar.gz" +provenance = "github-attestations" + +[[tools.uv]] +version = "0.8.15" +backend = "aqua:astral-sh/uv" + +[tools.uv."platforms.linux-arm64"] +checksum = "sha256:23ea21a05c62c4c307ce691f29bff2f15c94c4f07f2b83d9b356f0664bc8b3a2" +url = "https://github.com/astral-sh/uv/releases/download/0.8.15/uv-aarch64-unknown-linux-musl.tar.gz" + +[tools.uv."platforms.linux-arm64-musl"] +checksum = "sha256:23ea21a05c62c4c307ce691f29bff2f15c94c4f07f2b83d9b356f0664bc8b3a2" +url = "https://github.com/astral-sh/uv/releases/download/0.8.15/uv-aarch64-unknown-linux-musl.tar.gz" + +[tools.uv."platforms.linux-x64"] +checksum = "sha256:d0fec58f3124e05e0a1af0f6541abfce4333253cdaf23c7b6bb2e6128bf138ea" +url = "https://github.com/astral-sh/uv/releases/download/0.8.15/uv-x86_64-unknown-linux-musl.tar.gz" + +[tools.uv."platforms.linux-x64-musl"] +checksum = "sha256:d0fec58f3124e05e0a1af0f6541abfce4333253cdaf23c7b6bb2e6128bf138ea" +url = "https://github.com/astral-sh/uv/releases/download/0.8.15/uv-x86_64-unknown-linux-musl.tar.gz" + +[tools.uv."platforms.macos-arm64"] +checksum = "sha256:103367962c5cb00bf7370d84cbaa3fec5a9807be9cc833ea9d8eea400c119fa2" +url = "https://github.com/astral-sh/uv/releases/download/0.8.15/uv-aarch64-apple-darwin.tar.gz" + +[tools.uv."platforms.macos-x64"] +checksum = "sha256:2bbef70982e97dfc36454de173f35ec1a5e83ae11e3885df6a50db3fd76171cb" +url = "https://github.com/astral-sh/uv/releases/download/0.8.15/uv-x86_64-apple-darwin.tar.gz" + +[tools.uv."platforms.windows-x64"] +checksum = "sha256:459d95892a5cc5c21779532f4f41b9238594b79e312a5142da2148ecfa10e705" +url = "https://github.com/astral-sh/uv/releases/download/0.8.15/uv-x86_64-pc-windows-msvc.zip" diff --git a/machine-learning/pyproject.toml b/machine-learning/pyproject.toml index f706a1f125..4a74c6405e 100644 --- a/machine-learning/pyproject.toml +++ b/machine-learning/pyproject.toml @@ -10,7 +10,7 @@ dependencies = [ "fastapi>=0.95.2,<1.0", "gunicorn>=21.1.0", "huggingface-hub>=1.0,<2.0", - "insightface>=0.7.3,<1.0", + "insightface>=0.7.3,<2.0", "numpy>=2.4.0,<3.0", "opencv-python-headless>=4.7.0.72,<5.0", "orjson>=3.9.5", diff --git a/machine-learning/test_main.py b/machine-learning/test_main.py index cce334e40e..5145be0045 100644 --- a/machine-learning/test_main.py +++ b/machine-learning/test_main.py @@ -35,7 +35,37 @@ from immich_ml.sessions.ort import OrtSession from immich_ml.sessions.rknn import RknnSession, run_inference +class FakeLock: + def __init__(self) -> None: + self.enter = mock.Mock() + self.exit = mock.Mock() + + def __enter__(self) -> None: + self.enter() + + def __exit__(self, *args: object) -> None: + self.exit(*args) + + class TestBase: + def test_sets_default_worker_timeout(self, monkeypatch: MonkeyPatch) -> None: + monkeypatch.delenv("DEVICE", raising=False) + monkeypatch.delenv("MACHINE_LEARNING_WORKER_TIMEOUT", raising=False) + + assert Settings().worker_timeout == 300 + + def test_sets_rocm_default_worker_timeout(self, monkeypatch: MonkeyPatch) -> None: + monkeypatch.setenv("DEVICE", "rocm") + monkeypatch.delenv("MACHINE_LEARNING_WORKER_TIMEOUT", raising=False) + + assert Settings().worker_timeout == 900 + + def test_worker_timeout_env_override(self, monkeypatch: MonkeyPatch) -> None: + monkeypatch.setenv("DEVICE", "rocm") + monkeypatch.setenv("MACHINE_LEARNING_WORKER_TIMEOUT", "1200") + + assert Settings().worker_timeout == 1200 + def test_sets_default_cache_dir(self) -> None: encoder = OpenClipTextualEncoder("ViT-B-32__openai") @@ -413,6 +443,52 @@ class TestOrtSession: assert sess_options is session.sess_options + def test_serializes_rocm_first_run_for_new_input_signature(self, mocker: MockerFixture) -> None: + lock = FakeLock() + get_model_lock = mocker.patch("immich_ml.sessions.ort._migraphx_get_model_lock", return_value=lock) + mocker.patch("immich_ml.sessions.ort._migraphx_compiled_inputs", set()) + mocker.patch("immich_ml.sessions.ort.Path.mkdir") + session = OrtSession("/cache/ViT-B-32__openai/model.onnx", providers=["MIGraphXExecutionProvider"]) + input_feed = {"input": np.random.rand(1, 3, 224, 224).astype(np.float32)} + + session.run(None, input_feed) + session.run(None, input_feed) + + lock.enter.assert_called_once() + lock.exit.assert_called_once() + get_model_lock.assert_called_once() + session.session.run.assert_has_calls([mock.call(None, input_feed, None), mock.call(None, input_feed, None)]) + + def test_serializes_rocm_run_for_each_new_input_signature(self, mocker: MockerFixture) -> None: + lock = FakeLock() + mocker.patch("immich_ml.sessions.ort._migraphx_get_model_lock", return_value=lock) + mocker.patch("immich_ml.sessions.ort._migraphx_compiled_inputs", set()) + mocker.patch("immich_ml.sessions.ort.Path.mkdir") + session = OrtSession("/cache/ViT-B-32__openai/model.onnx", providers=["MIGraphXExecutionProvider"]) + input_feed = {"input": np.random.rand(1, 3, 224, 224).astype(np.float32)} + new_shape_input_feed = {"input": np.random.rand(2, 3, 224, 224).astype(np.float32)} + + session.run(None, input_feed) + session.run(None, new_shape_input_feed) + + assert lock.enter.call_count == 2 + assert lock.exit.call_count == 2 + session.session.run.assert_has_calls( + [mock.call(None, input_feed, None), mock.call(None, new_shape_input_feed, None)] + ) + + def test_does_not_serialize_non_rocm_run(self, mocker: MockerFixture) -> None: + lock = FakeLock() + get_model_lock = mocker.patch("immich_ml.sessions.ort._migraphx_get_model_lock", return_value=lock) + session = OrtSession("/cache/ViT-B-32__openai/model.onnx", providers=["CPUExecutionProvider"]) + input_feed = {"input": np.random.rand(1, 3, 224, 224).astype(np.float32)} + + session.run(None, input_feed) + + get_model_lock.assert_not_called() + lock.enter.assert_not_called() + session.session.run.assert_called_once_with(None, input_feed, None) + class TestAnnSession: def test_creates_ann_session(self, ann_session: mock.Mock, info: mock.Mock) -> None: @@ -883,6 +959,34 @@ class TestFaceRecognition: onnx.load.assert_not_called() onnx.save.assert_not_called() + def test_recognition_does_not_add_batch_axis_for_migraphx( + self, ort_session: mock.Mock, path: mock.Mock, mocker: MockerFixture + ) -> None: + onnx = mocker.patch("immich_ml.models.facial_recognition.recognition.onnx", autospec=True) + update_dims = mocker.patch( + "immich_ml.models.facial_recognition.recognition.update_inputs_outputs_dims", autospec=True + ) + mocker.patch("immich_ml.models.base.InferenceModel.download") + mocker.patch("immich_ml.models.facial_recognition.recognition.ArcFaceONNX") + mocker.patch( + "immich_ml.models.facial_recognition.recognition.ort.get_available_providers", + return_value=["MIGraphXExecutionProvider", "CPUExecutionProvider"], + ) + path.return_value.__truediv__.return_value.__truediv__.return_value.suffix = ".onnx" + + inputs = [SimpleNamespace(name="input.1", shape=(1, 3, 224, 224))] + outputs = [SimpleNamespace(name="output.1", shape=(1, 800))] + ort_session.return_value.get_inputs.return_value = inputs + ort_session.return_value.get_outputs.return_value = outputs + + face_recognizer = FaceRecognizer("buffalo_s", cache_dir=path) + face_recognizer.load() + + assert face_recognizer.batch_size == 1 + update_dims.assert_not_called() + onnx.load.assert_not_called() + onnx.save.assert_not_called() + def test_set_custom_max_batch_size(self, mocker: MockerFixture) -> None: mocker.patch.object(settings, "max_batch_size", MaxBatchSize(facial_recognition=2)) @@ -924,7 +1028,12 @@ class TestOcr: text_recognizer.load() rapid_recognizer.assert_called_once_with( - OcrOptions(session=ort_session.return_value, rec_batch_num=6, rec_img_shape=(3, 48, 320)) + OcrOptions( + session=ort_session.return_value, + rec_batch_num=6, + rec_img_shape=(3, 48, 320), + model_root_dir=text_recognizer.cache_dir, + ) ) def test_set_custom_max_batch_size(self, ort_session: mock.Mock, path: mock.Mock, mocker: MockerFixture) -> None: @@ -937,7 +1046,12 @@ class TestOcr: text_recognizer.load() rapid_recognizer.assert_called_once_with( - OcrOptions(session=ort_session.return_value, rec_batch_num=4, rec_img_shape=(3, 48, 320)) + OcrOptions( + session=ort_session.return_value, + rec_batch_num=4, + rec_img_shape=(3, 48, 320), + model_root_dir=text_recognizer.cache_dir, + ) ) def test_ignore_other_custom_max_batch_size( @@ -952,7 +1066,12 @@ class TestOcr: text_recognizer.load() rapid_recognizer.assert_called_once_with( - OcrOptions(session=ort_session.return_value, rec_batch_num=6, rec_img_shape=(3, 48, 320)) + OcrOptions( + session=ort_session.return_value, + rec_batch_num=6, + rec_img_shape=(3, 48, 320), + model_root_dir=text_recognizer.cache_dir, + ) ) diff --git a/machine-learning/uv.lock b/machine-learning/uv.lock index 5623c553df..145ee5f9e5 100644 --- a/machine-learning/uv.lock +++ b/machine-learning/uv.lock @@ -1004,7 +1004,7 @@ requires-dist = [ { name = "fastapi", specifier = ">=0.95.2,<1.0" }, { name = "gunicorn", specifier = ">=21.1.0" }, { name = "huggingface-hub", specifier = ">=1.0,<2.0" }, - { name = "insightface", specifier = ">=0.7.3,<1.0" }, + { name = "insightface", specifier = ">=0.7.3,<2.0" }, { name = "numpy", specifier = ">=2.4.0,<3.0" }, { name = "onnxruntime", marker = "extra == 'armnn'", specifier = ">=1.23.2,<2" }, { name = "onnxruntime", marker = "extra == 'cpu'", specifier = ">=1.23.2,<2" }, diff --git a/mise.lock b/mise.lock new file mode 100644 index 0000000000..7760585258 --- /dev/null +++ b/mise.lock @@ -0,0 +1,354 @@ +# @generated - this file is auto-generated by `mise lock` https://mise.en.dev/dev-tools/mise-lock.html + +[[tools."aqua:flutter/flutter"]] +version = "3.44.0" +backend = "aqua:flutter/flutter" + +[tools."aqua:flutter/flutter"."platforms.linux-arm64"] +url = "https://storage.googleapis.com/flutter_infra_release/releases/stable/linux/flutter_linux_3.44.0-stable.tar.xz" + +[tools."aqua:flutter/flutter"."platforms.linux-arm64-musl"] +url = "https://storage.googleapis.com/flutter_infra_release/releases/stable/linux/flutter_linux_3.44.0-stable.tar.xz" + +[tools."aqua:flutter/flutter"."platforms.linux-x64"] +url = "https://storage.googleapis.com/flutter_infra_release/releases/stable/linux/flutter_linux_3.44.0-stable.tar.xz" + +[tools."aqua:flutter/flutter"."platforms.linux-x64-musl"] +url = "https://storage.googleapis.com/flutter_infra_release/releases/stable/linux/flutter_linux_3.44.0-stable.tar.xz" + +[tools."aqua:flutter/flutter"."platforms.macos-arm64"] +checksum = "blake3:fb03aa5d9790205c948922ec3f0751c16e4575b09d6ae9dd4fbeb664a69f0e00" +url = "https://storage.googleapis.com/flutter_infra_release/releases/stable/macos/flutter_macos_arm64_3.44.0-stable.zip" + +[tools."aqua:flutter/flutter"."platforms.macos-x64"] +url = "https://storage.googleapis.com/flutter_infra_release/releases/stable/macos/flutter_macos_3.44.0-stable.zip" + +[tools."aqua:flutter/flutter"."platforms.windows-x64"] +url = "https://storage.googleapis.com/flutter_infra_release/releases/stable/windows/flutter_windows_3.44.0-stable.zip" + +[[tools.flutter]] +version = "3.41.9-stable" +backend = "asdf:flutter" + +[[tools."github:CQLabs/homebrew-dcm"]] +version = "1.37.0" +backend = "github:CQLabs/homebrew-dcm" + +[tools."github:CQLabs/homebrew-dcm"."platforms.linux-arm64"] +checksum = "sha256:253da2512b149913dfe345bf9a62a79acb2d730f66e71162ba4a92dfc4224b82" +url = "https://github.com/CQLabs/homebrew-dcm/releases/download/1.37.0/dcm-linux-arm-release.zip" +url_api = "https://api.github.com/repos/CQLabs/homebrew-dcm/releases/assets/404543838" + +[tools."github:CQLabs/homebrew-dcm"."platforms.linux-arm64-musl"] +checksum = "sha256:253da2512b149913dfe345bf9a62a79acb2d730f66e71162ba4a92dfc4224b82" +url = "https://github.com/CQLabs/homebrew-dcm/releases/download/1.37.0/dcm-linux-arm-release.zip" +url_api = "https://api.github.com/repos/CQLabs/homebrew-dcm/releases/assets/404543838" + +[tools."github:CQLabs/homebrew-dcm"."platforms.linux-x64"] +checksum = "sha256:477e086d4099c12f21e5ccd83b005d5fb945dd4cac4fd127fd9a08d7649af1cf" +url = "https://github.com/CQLabs/homebrew-dcm/releases/download/1.37.0/dcm-linux-x64-release.zip" +url_api = "https://api.github.com/repos/CQLabs/homebrew-dcm/releases/assets/404543797" + +[tools."github:CQLabs/homebrew-dcm"."platforms.linux-x64-musl"] +checksum = "sha256:477e086d4099c12f21e5ccd83b005d5fb945dd4cac4fd127fd9a08d7649af1cf" +url = "https://github.com/CQLabs/homebrew-dcm/releases/download/1.37.0/dcm-linux-x64-release.zip" +url_api = "https://api.github.com/repos/CQLabs/homebrew-dcm/releases/assets/404543797" + +[tools."github:CQLabs/homebrew-dcm"."platforms.macos-arm64"] +checksum = "sha256:30bede64367d09067093cc57af6ec9496d7717898138ded5cb98a16ac8dd9d93" +url = "https://github.com/CQLabs/homebrew-dcm/releases/download/1.37.0/dcm-macos-arm-release.zip" +url_api = "https://api.github.com/repos/CQLabs/homebrew-dcm/releases/assets/404543757" + +[tools."github:CQLabs/homebrew-dcm"."platforms.macos-x64"] +checksum = "sha256:e56cb99872be7445a4de1d37e5438ca70e3bcd83be7a2b9b385e3538881f8068" +url = "https://github.com/CQLabs/homebrew-dcm/releases/download/1.37.0/dcm-macos-x64-release.zip" +url_api = "https://api.github.com/repos/CQLabs/homebrew-dcm/releases/assets/404543727" + +[tools."github:CQLabs/homebrew-dcm"."platforms.windows-x64"] +checksum = "sha256:f133470daa3fb0427f039b424392af7e917d7e7db6b556aa2a968ab0e31587da" +url = "https://github.com/CQLabs/homebrew-dcm/releases/download/1.37.0/dcm-windows-release.zip" +url_api = "https://api.github.com/repos/CQLabs/homebrew-dcm/releases/assets/404543660" + +[[tools."github:extism/cli"]] +version = "1.6.3" +backend = "github:extism/cli" + +[tools."github:extism/cli"."platforms.linux-arm64"] +checksum = "sha256:d92f830c9be39637569feacb04e9750c28848df6d9a219db94152a9b4eb9452b" +url = "https://github.com/extism/cli/releases/download/v1.6.3/extism-v1.6.3-linux-arm64.tar.gz" +url_api = "https://api.github.com/repos/extism/cli/releases/assets/275694030" + +[tools."github:extism/cli"."platforms.linux-arm64-musl"] +checksum = "sha256:d92f830c9be39637569feacb04e9750c28848df6d9a219db94152a9b4eb9452b" +url = "https://github.com/extism/cli/releases/download/v1.6.3/extism-v1.6.3-linux-arm64.tar.gz" +url_api = "https://api.github.com/repos/extism/cli/releases/assets/275694030" + +[tools."github:extism/cli"."platforms.linux-x64"] +checksum = "sha256:34e7ae9bfded6e2c32dee83f70a4e50d34f9d3e80d1762b09625fe82e214d02d" +url = "https://github.com/extism/cli/releases/download/v1.6.3/extism-v1.6.3-linux-amd64.tar.gz" +url_api = "https://api.github.com/repos/extism/cli/releases/assets/275694025" + +[tools."github:extism/cli"."platforms.linux-x64-musl"] +checksum = "sha256:34e7ae9bfded6e2c32dee83f70a4e50d34f9d3e80d1762b09625fe82e214d02d" +url = "https://github.com/extism/cli/releases/download/v1.6.3/extism-v1.6.3-linux-amd64.tar.gz" +url_api = "https://api.github.com/repos/extism/cli/releases/assets/275694025" + +[tools."github:extism/cli"."platforms.macos-arm64"] +checksum = "sha256:b4ddbc575b5ac000115247f781723f9b9f284ed87b29c600539d72161b5b29fc" +url = "https://github.com/extism/cli/releases/download/v1.6.3/extism-v1.6.3-darwin-arm64.tar.gz" +url_api = "https://api.github.com/repos/extism/cli/releases/assets/275694029" + +[tools."github:extism/cli"."platforms.macos-x64"] +checksum = "sha256:9a2f71b6e6009685a622cc3084e52d2a1a8e23c98d29ffa72e666e9dc699855f" +url = "https://github.com/extism/cli/releases/download/v1.6.3/extism-v1.6.3-darwin-amd64.tar.gz" +url_api = "https://api.github.com/repos/extism/cli/releases/assets/275694026" + +[tools."github:extism/cli"."platforms.windows-x64"] +checksum = "sha256:47e4ed2782445b2b08a4d1ac127211588f8b4d1fc25fd6481d4cb65151b5213c" +url = "https://github.com/extism/cli/releases/download/v1.6.3/extism-v1.6.3-windows-amd64.zip" +url_api = "https://api.github.com/repos/extism/cli/releases/assets/275694035" + +[[tools."github:extism/js-pdk"]] +version = "1.6.0" +backend = "github:extism/js-pdk" + +[tools."github:extism/js-pdk"."platforms.linux-arm64"] +checksum = "sha256:15a186250e68d6bff4ec839fff275d45a90e383a69209dcc1239eb9e3aee6e1b" +url = "https://github.com/extism/js-pdk/releases/download/v1.6.0/extism-js-aarch64-linux-v1.6.0.gz" +url_api = "https://api.github.com/repos/extism/js-pdk/releases/assets/353223214" + +[tools."github:extism/js-pdk"."platforms.linux-arm64-musl"] +checksum = "sha256:15a186250e68d6bff4ec839fff275d45a90e383a69209dcc1239eb9e3aee6e1b" +url = "https://github.com/extism/js-pdk/releases/download/v1.6.0/extism-js-aarch64-linux-v1.6.0.gz" +url_api = "https://api.github.com/repos/extism/js-pdk/releases/assets/353223214" + +[tools."github:extism/js-pdk"."platforms.linux-x64"] +checksum = "sha256:4ded271ccf465031ccd0dc35e7a140e134d7f30721671cc4a8e1ff805d4aad68" +url = "https://github.com/extism/js-pdk/releases/download/v1.6.0/extism-js-x86_64-linux-v1.6.0.gz" +url_api = "https://api.github.com/repos/extism/js-pdk/releases/assets/353223119" + +[tools."github:extism/js-pdk"."platforms.linux-x64-musl"] +checksum = "sha256:4ded271ccf465031ccd0dc35e7a140e134d7f30721671cc4a8e1ff805d4aad68" +url = "https://github.com/extism/js-pdk/releases/download/v1.6.0/extism-js-x86_64-linux-v1.6.0.gz" +url_api = "https://api.github.com/repos/extism/js-pdk/releases/assets/353223119" + +[tools."github:extism/js-pdk"."platforms.macos-arm64"] +checksum = "sha256:548e25bda3971a07c32d78a249135cf8cb7b3eede101e878e06e53e01ac2e0ce" +url = "https://github.com/extism/js-pdk/releases/download/v1.6.0/extism-js-aarch64-macos-v1.6.0.gz" +url_api = "https://api.github.com/repos/extism/js-pdk/releases/assets/353223215" + +[tools."github:extism/js-pdk"."platforms.macos-x64"] +checksum = "sha256:d85a875c2a071f0c29fe572764c52c3a499f157ab7f9efac8939a4364390e29b" +url = "https://github.com/extism/js-pdk/releases/download/v1.6.0/extism-js-x86_64-macos-v1.6.0.gz" +url_api = "https://api.github.com/repos/extism/js-pdk/releases/assets/353223239" + +[tools."github:extism/js-pdk"."platforms.windows-x64"] +checksum = "sha256:97b7b746141e4777e1ca2b76febdeb16dc9d314ff6a4257df05a476b67228acc" +url = "https://github.com/extism/js-pdk/releases/download/v1.6.0/extism-js-x86_64-windows-v1.6.0.gz" +url_api = "https://api.github.com/repos/extism/js-pdk/releases/assets/353224133" + +[[tools."github:jellyfin/jellyfin-ffmpeg"]] +version = "7.1.3-6" +backend = "github:jellyfin/jellyfin-ffmpeg" + +[tools."github:jellyfin/jellyfin-ffmpeg"."platforms.linux-arm64"] +checksum = "sha256:bea03c670e8cc5bfe9edc0c5d624d4735421610cef5e808db93e7d8596952886" +url = "https://github.com/jellyfin/jellyfin-ffmpeg/releases/download/v7.1.3-6/jellyfin-ffmpeg_7.1.3-6_portable_linuxarm64-gpl.tar.xz" +url_api = "https://api.github.com/repos/jellyfin/jellyfin-ffmpeg/releases/assets/409048876" + +[tools."github:jellyfin/jellyfin-ffmpeg"."platforms.linux-arm64-musl"] +checksum = "sha256:bea03c670e8cc5bfe9edc0c5d624d4735421610cef5e808db93e7d8596952886" +url = "https://github.com/jellyfin/jellyfin-ffmpeg/releases/download/v7.1.3-6/jellyfin-ffmpeg_7.1.3-6_portable_linuxarm64-gpl.tar.xz" +url_api = "https://api.github.com/repos/jellyfin/jellyfin-ffmpeg/releases/assets/409048876" + +[tools."github:jellyfin/jellyfin-ffmpeg"."platforms.linux-x64"] +checksum = "sha256:39e99a7927468a6abec5f65d00f55010e8ff2ae3c2605294f179c94f6ae21af2" +url = "https://github.com/jellyfin/jellyfin-ffmpeg/releases/download/v7.1.3-6/jellyfin-ffmpeg_7.1.3-6_portable_linux64-gpl.tar.xz" +url_api = "https://api.github.com/repos/jellyfin/jellyfin-ffmpeg/releases/assets/409048879" + +[tools."github:jellyfin/jellyfin-ffmpeg"."platforms.linux-x64-musl"] +checksum = "sha256:39e99a7927468a6abec5f65d00f55010e8ff2ae3c2605294f179c94f6ae21af2" +url = "https://github.com/jellyfin/jellyfin-ffmpeg/releases/download/v7.1.3-6/jellyfin-ffmpeg_7.1.3-6_portable_linux64-gpl.tar.xz" +url_api = "https://api.github.com/repos/jellyfin/jellyfin-ffmpeg/releases/assets/409048879" + +[tools."github:jellyfin/jellyfin-ffmpeg"."platforms.macos-arm64"] +checksum = "sha256:e024d5e78d5414e75f0181036cd21373fafb9270c72894dfd7dbda2572439820" +url = "https://github.com/jellyfin/jellyfin-ffmpeg/releases/download/v7.1.3-6/jellyfin-ffmpeg_7.1.3-6_portable_macarm64-gpl.tar.xz" +url_api = "https://api.github.com/repos/jellyfin/jellyfin-ffmpeg/releases/assets/408995838" + +[tools."github:jellyfin/jellyfin-ffmpeg"."platforms.macos-x64"] +checksum = "sha256:066ede9774aaae97a18098aaeea8b7e0d286653eb8618f640476e99c59a536c2" +url = "https://github.com/jellyfin/jellyfin-ffmpeg/releases/download/v7.1.3-6/jellyfin-ffmpeg_7.1.3-6_portable_mac64-gpl.tar.xz" +url_api = "https://api.github.com/repos/jellyfin/jellyfin-ffmpeg/releases/assets/408995889" + +[tools."github:jellyfin/jellyfin-ffmpeg"."platforms.windows-x64"] +checksum = "sha256:7b7168149689610296f3a187c717056ce0786cc125a31caf28056737e9ba1cc1" +url = "https://github.com/jellyfin/jellyfin-ffmpeg/releases/download/v7.1.3-6/jellyfin-ffmpeg_7.1.3-6_portable_win64-clang-gpl.zip" +url_api = "https://api.github.com/repos/jellyfin/jellyfin-ffmpeg/releases/assets/409036094" + +[[tools."github:webassembly/binaryen"]] +version = "version_124" +backend = "github:webassembly/binaryen" + +[tools."github:webassembly/binaryen"."platforms.linux-arm64"] +checksum = "sha256:6291bd9a57d8e046f3bc099a4db386c147433a87f71c783a901c5b1792e38de3" +url = "https://github.com/WebAssembly/binaryen/releases/download/version_124/binaryen-version_124-aarch64-linux.tar.gz" +url_api = "https://api.github.com/repos/WebAssembly/binaryen/releases/assets/288927659" + +[tools."github:webassembly/binaryen"."platforms.linux-arm64-musl"] +checksum = "sha256:6291bd9a57d8e046f3bc099a4db386c147433a87f71c783a901c5b1792e38de3" +url = "https://github.com/WebAssembly/binaryen/releases/download/version_124/binaryen-version_124-aarch64-linux.tar.gz" +url_api = "https://api.github.com/repos/WebAssembly/binaryen/releases/assets/288927659" + +[tools."github:webassembly/binaryen"."platforms.linux-x64"] +checksum = "sha256:0290c3779fedf592b8da0ded3032ff55c41a2b7bfa2d6bf7b7bac6f0e6e28963" +url = "https://github.com/WebAssembly/binaryen/releases/download/version_124/binaryen-version_124-x86_64-linux.tar.gz" +url_api = "https://api.github.com/repos/WebAssembly/binaryen/releases/assets/288926769" + +[tools."github:webassembly/binaryen"."platforms.linux-x64-musl"] +checksum = "sha256:0290c3779fedf592b8da0ded3032ff55c41a2b7bfa2d6bf7b7bac6f0e6e28963" +url = "https://github.com/WebAssembly/binaryen/releases/download/version_124/binaryen-version_124-x86_64-linux.tar.gz" +url_api = "https://api.github.com/repos/WebAssembly/binaryen/releases/assets/288926769" + +[tools."github:webassembly/binaryen"."platforms.macos-arm64"] +checksum = "sha256:86a2c960ff62c6d2ea6009d1f89745c22c70100d394a095eab45eb941bdaa24c" +url = "https://github.com/WebAssembly/binaryen/releases/download/version_124/binaryen-version_124-arm64-macos.tar.gz" +url_api = "https://api.github.com/repos/WebAssembly/binaryen/releases/assets/288926134" + +[tools."github:webassembly/binaryen"."platforms.macos-x64"] +checksum = "sha256:b389bb0731758d86c3cb266d01d28a12725c23bd3cabc3df34faa162af0887e9" +url = "https://github.com/WebAssembly/binaryen/releases/download/version_124/binaryen-version_124-x86_64-macos.tar.gz" +url_api = "https://api.github.com/repos/WebAssembly/binaryen/releases/assets/288926135" + +[tools."github:webassembly/binaryen"."platforms.windows-x64"] +checksum = "sha256:b5e1d2a1ad3c03229ddc89823848f4a1c11f9c6402a51fa26f0aaa5f1d7a2203" +url = "https://github.com/WebAssembly/binaryen/releases/download/version_124/binaryen-version_124-x86_64-windows.tar.gz" +url_api = "https://api.github.com/repos/WebAssembly/binaryen/releases/assets/288925833" + +[[tools.java]] +version = "21.0.2" +backend = "core:java" + +[tools.java."platforms.linux-arm64"] +checksum = "sha256:08db1392a48d4eb5ea5315cf8f18b89dbaf36cda663ba882cf03c704c9257ec2" +url = "https://download.java.net/java/GA/jdk21.0.2/f2283984656d49d69e91c558476027ac/13/GPL/openjdk-21.0.2_linux-aarch64_bin.tar.gz" + +[tools.java."platforms.linux-x64"] +checksum = "sha256:a2def047a73941e01a73739f92755f86b895811afb1f91243db214cff5bdac3f" +url = "https://download.java.net/java/GA/jdk21.0.2/f2283984656d49d69e91c558476027ac/13/GPL/openjdk-21.0.2_linux-x64_bin.tar.gz" + +[tools.java."platforms.macos-arm64"] +checksum = "sha256:b3d588e16ec1e0ef9805d8a696591bd518a5cea62567da8f53b5ce32d11d22e4" +url = "https://download.java.net/java/GA/jdk21.0.2/f2283984656d49d69e91c558476027ac/13/GPL/openjdk-21.0.2_macos-aarch64_bin.tar.gz" + +[tools.java."platforms.macos-x64"] +checksum = "sha256:8fd09e15dc406387a0aba70bf5d99692874e999bf9cd9208b452b5d76ac922d3" +url = "https://download.java.net/java/GA/jdk21.0.2/f2283984656d49d69e91c558476027ac/13/GPL/openjdk-21.0.2_macos-x64_bin.tar.gz" + +[tools.java."platforms.windows-x64"] +checksum = "sha256:b6c17e747ae78cdd6de4d7532b3164b277daee97c007d3eaa2b39cca99882664" +url = "https://download.java.net/java/GA/jdk21.0.2/f2283984656d49d69e91c558476027ac/13/GPL/openjdk-21.0.2_windows-x64_bin.zip" + +[[tools.node]] +version = "24.15.0" +backend = "core:node" + +[tools.node."platforms.linux-arm64"] +checksum = "sha256:73afc234d558c24919875f51c2d1ea002a2ada4ea6f83601a383869fefa64eed" +url = "https://nodejs.org/dist/v24.15.0/node-v24.15.0-linux-arm64.tar.gz" + +[tools.node."platforms.linux-arm64-musl"] +checksum = "sha256:31e98aa960a067da91edffd5d93bc46657b5d2a8029612c359f5f2ac0060152a" +url = "https://unofficial-builds.nodejs.org/download/release/v24.15.0/node-v24.15.0-linux-arm64-musl.tar.gz" + +[tools.node."platforms.linux-x64"] +checksum = "sha256:44836872d9aec49f1e6b52a9a922872db9a2b02d235a616a5681b6a85fec8d89" +url = "https://nodejs.org/dist/v24.15.0/node-v24.15.0-linux-x64.tar.gz" + +[tools.node."platforms.linux-x64-musl"] +checksum = "sha256:f55af5bd489c5347b113ca6594cae00a54b30ba57ac5875324311bfc6f4762e3" +url = "https://unofficial-builds.nodejs.org/download/release/v24.15.0/node-v24.15.0-linux-x64-musl.tar.gz" + +[tools.node."platforms.macos-arm64"] +checksum = "sha256:372331b969779ab5d15b949884fc6eaf88d5afe87bde8ba881d6400b9100ffc4" +url = "https://nodejs.org/dist/v24.15.0/node-v24.15.0-darwin-arm64.tar.gz" + +[tools.node."platforms.macos-x64"] +checksum = "sha256:ffd5ee293467927f3ee731a553eb88fd1f48cf74eebc2d74a6babe4af228673b" +url = "https://nodejs.org/dist/v24.15.0/node-v24.15.0-darwin-x64.tar.gz" + +[tools.node."platforms.windows-x64"] +checksum = "sha256:cc5149eabd53779ce1e7bdc5401643622d0c7e6800ade18928a767e940bb0e62" +url = "https://nodejs.org/dist/v24.15.0/node-v24.15.0-win-x64.zip" + +[[tools."npm:oazapfts"]] +version = "7.5.0" +backend = "npm:oazapfts" + +[[tools.opentofu]] +version = "1.11.6" +backend = "aqua:opentofu/opentofu" + +[tools.opentofu."platforms.linux-arm64"] +checksum = "sha256:d4f2ab15776925864b049bb329d69682851de6f5204f256e9fa86d07a0308850" +url = "https://github.com/opentofu/opentofu/releases/download/v1.11.6/tofu_1.11.6_linux_arm64.tar.gz" + +[tools.opentofu."platforms.linux-arm64-musl"] +checksum = "sha256:d4f2ab15776925864b049bb329d69682851de6f5204f256e9fa86d07a0308850" +url = "https://github.com/opentofu/opentofu/releases/download/v1.11.6/tofu_1.11.6_linux_arm64.tar.gz" + +[tools.opentofu."platforms.linux-x64"] +checksum = "sha256:02800fafa2753a9f50c38483e2fdf5bc353fd62895eb9e25eec9a5145df3a69e" +url = "https://github.com/opentofu/opentofu/releases/download/v1.11.6/tofu_1.11.6_linux_amd64.tar.gz" + +[tools.opentofu."platforms.linux-x64-musl"] +checksum = "sha256:02800fafa2753a9f50c38483e2fdf5bc353fd62895eb9e25eec9a5145df3a69e" +url = "https://github.com/opentofu/opentofu/releases/download/v1.11.6/tofu_1.11.6_linux_amd64.tar.gz" + +[tools.opentofu."platforms.macos-arm64"] +checksum = "sha256:62d7fa8539e13b444827aa0a3b90c5972da5c47e8f8882d9dcf2e430e78840c1" +url = "https://github.com/opentofu/opentofu/releases/download/v1.11.6/tofu_1.11.6_darwin_arm64.tar.gz" + +[tools.opentofu."platforms.macos-x64"] +checksum = "sha256:1408cdef1c380f914565e6b4bb70794c6b163f195fcb233357f3d6c5745906b6" +url = "https://github.com/opentofu/opentofu/releases/download/v1.11.6/tofu_1.11.6_darwin_amd64.tar.gz" + +[tools.opentofu."platforms.windows-x64"] +checksum = "sha256:27323f70c875b8251bfd7e61a4cffc3ebff4e56ed1e611b955016f0c7077367e" +url = "https://github.com/opentofu/opentofu/releases/download/v1.11.6/tofu_1.11.6_windows_amd64.tar.gz" + +[[tools.pnpm]] +version = "10.33.4" +backend = "aqua:pnpm/pnpm" + +[[tools.terragrunt]] +version = "1.0.3" +backend = "aqua:gruntwork-io/terragrunt" + +[tools.terragrunt."platforms.linux-arm64"] +checksum = "sha256:e5b60ab05b5214db694e6bc215d8124fb626e277cdb56b86f6147ae110d510fe" +url = "https://github.com/gruntwork-io/terragrunt/releases/download/v1.0.3/terragrunt_linux_arm64.tar.gz" + +[tools.terragrunt."platforms.linux-arm64-musl"] +checksum = "sha256:e5b60ab05b5214db694e6bc215d8124fb626e277cdb56b86f6147ae110d510fe" +url = "https://github.com/gruntwork-io/terragrunt/releases/download/v1.0.3/terragrunt_linux_arm64.tar.gz" + +[tools.terragrunt."platforms.linux-x64"] +checksum = "sha256:6d48049baf82e0bf9c804368dc85cbfeadc10955e33777e9e8de3e020b94b073" +url = "https://github.com/gruntwork-io/terragrunt/releases/download/v1.0.3/terragrunt_linux_amd64.tar.gz" + +[tools.terragrunt."platforms.linux-x64-musl"] +checksum = "sha256:6d48049baf82e0bf9c804368dc85cbfeadc10955e33777e9e8de3e020b94b073" +url = "https://github.com/gruntwork-io/terragrunt/releases/download/v1.0.3/terragrunt_linux_amd64.tar.gz" + +[tools.terragrunt."platforms.macos-arm64"] +checksum = "sha256:aacb5be2ca5475300cbce246dfbd8a45eb47510fbaa70fab8561c49ef5db03aa" +url = "https://github.com/gruntwork-io/terragrunt/releases/download/v1.0.3/terragrunt_darwin_arm64.tar.gz" + +[tools.terragrunt."platforms.macos-x64"] +checksum = "sha256:3133c2251e191aede8e3dd2a5b3aee2e91c5f08f88f117aee40eed9a24c8ef6b" +url = "https://github.com/gruntwork-io/terragrunt/releases/download/v1.0.3/terragrunt_darwin_amd64.tar.gz" + +[tools.terragrunt."platforms.windows-x64"] +checksum = "sha256:183b2745b4e04980a6bfa4450ff81956a12596ca22d70f7aaa793980f5b036db" +url = "https://github.com/gruntwork-io/terragrunt/releases/download/v1.0.3/terragrunt_windows_amd64.exe.tar.gz" diff --git a/mise.toml b/mise.toml index 08e6b7fd78..8cff3993f7 100644 --- a/mise.toml +++ b/mise.toml @@ -16,8 +16,8 @@ config_roots = [ [tools] node = "24.15.0" -flutter = "3.41.9" -pnpm = "10.33.1" +"aqua:flutter/flutter" = "3.44.0" +pnpm = "10.33.4" terragrunt = "1.0.3" opentofu = "1.11.6" java = "21.0.2" @@ -50,11 +50,12 @@ macos-arm64 = { asset_pattern = "jellyfin-ffmpeg_*_portable_macarm64-gpl.tar.xz" [settings] experimental = true pin = true +lockfile = true [tasks.plugins] run = [ - "pnpm --filter @immich/plugin-sdk --filter @immich/plugin-core install --frozen-lockfile", - "pnpm --filter @immich/plugin-sdk --filter @immich/plugin-core build" + "pnpm --filter @immich/sdk --filter @immich/plugin-sdk --filter @immich/plugin-core install --frozen-lockfile", + "pnpm --filter @immich/sdk --filter @immich/plugin-sdk --filter @immich/plugin-core build", ] [tasks.open-api-typescript] @@ -72,18 +73,83 @@ run = "bash ./bin/generate-dart-sdk.sh" env = { SHARP_IGNORE_GLOBAL_LIBVIPS = true } run = [ { task = "//:plugins" }, - { task = "//server:build" }, { task = "//server:install" }, { task = "//server:build" }, { task = "//server:sync-open-api" }, - { task = ":open-api-typescript"}, - { task = ":open-api-dart"}, + { task = ":open-api-typescript" }, + { task = ":open-api-dart" }, ] [tasks.sql] dir = "server" run = "node ./dist/bin/sync-sql.js" +# TODO dev, prod, and e2e should be de-duplicated by using env but for some reason I ran into issues +[tasks.dev] +depends = "//:plugins" +dir = "docker" +interactive = true +env = { COMPOSE_BAKE = true } +run = "docker compose -f ./docker-compose.dev.yml up --remove-orphans" +depends_post = "//:dev-down" + +[tasks.dev-update] +run = { task = "//:dev", args = ["--build", "-V"] } + +[tasks.dev-scale] +run = { task = "//:dev", args = ["--build", "-V", "--scale immich-server=3"] } + +[tasks.dev-down] +dir = "docker" +run = "docker compose -f ./docker-compose.dev.yml down --remove-orphans" + +[tasks.prod] +depends = "//:plugins" +dir = "docker" +interactive = true +env = { COMPOSE_BAKE = true } +run = "docker compose -f ./docker-compose.prod.yml up --build --remove-orphans" +depends_post = "//:prod-down" + +[tasks.prod-scale] +run = { task = "//:prod", args = [ + "--build", + "-V", + "--scale immich-server=3", + "--scale immich-microservices", +] } + +[tasks.prod-down] +dir = "docker" +run = "docker compose -f ./docker-compose.prod.yml down --remove-orphans" + +[tasks.e2e] +depends = "//:plugins" +dir = "e2e" +interactive = true +env = { COMPOSE_BAKE = true } +run = "docker compose -f ./docker-compose.yml up --remove-orphans" +depends_post = "//:e2e-down" + +[tasks.e2e-dev] +depends = "//:plugins" +dir = "e2e" +interactive = true +env = { COMPOSE_BAKE = true } +run = "docker compose -f ./docker-compose.dev.yml up --remove-orphans" +depends_post = "//:e2e-dev-down" + +[tasks.e2e-update] +run = { task = "//:e2e", args = ["--build", '-V'] } + +[tasks.e2e-down] +dir = "e2e" +run = "docker compose -f ./docker-compose.yml down --remove-orphans" + +[tasks.e2e-dev-down] +dir = "e2e" +run = "docker compose -f ./docker-compose.dev.yml down --remove-orphans" + # SDK tasks [tasks."sdk:install"] dir = "packages/sdk" @@ -99,3 +165,14 @@ run = "pnpm format" [tasks."i18n:format-fix"] run = "pnpm format:fix" + +[tasks.clean] +run = [ + "find . -name 'node_modules' -type d -prune -exec rm -rf '{}' +", + "find . -name 'dist' -type d -prune -exec rm -rf '{}' +", + "find . -name 'build' -type d -prune -exec rm -rf '{}' +", + "find . -name '.svelte-kit' -type d -prune -exec rm -rf '{}' +", + "find . -name 'coverage' -type d -prune -exec rm -rf '{}' +", + "find . -name '.pnpm-store' -type d -prune -exec rm -rf '{}' +", + { task = "//:*-down" }, +] diff --git a/mobile/.vscode/settings.json b/mobile/.vscode/settings.json index 517086e98a..781acecc6d 100644 --- a/mobile/.vscode/settings.json +++ b/mobile/.vscode/settings.json @@ -1,5 +1,4 @@ { - "dart.flutterSdkPath": ".fvm/versions/3.41.9", "dart.lineLength": 120, "[dart]": { "editor.rulers": [ 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 2c80b8d2bd..b4cd705b05 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 @@ -17,6 +17,8 @@ import app.alextran.immich.images.LocalImageApi import app.alextran.immich.images.LocalImagesImpl import app.alextran.immich.images.RemoteImageApi import app.alextran.immich.images.RemoteImagesImpl +import app.alextran.immich.permission.PermissionApi +import app.alextran.immich.permission.PermissionApiImpl import app.alextran.immich.sync.NativeSyncApi import app.alextran.immich.sync.NativeSyncApiImpl26 import app.alextran.immich.sync.NativeSyncApiImpl30 @@ -44,7 +46,9 @@ class MainActivity : FlutterFragmentActivity() { } else { NativeSyncApiImpl30(ctx) } + val permissionApiImpl = PermissionApiImpl(ctx) NativeSyncApi.setUp(messenger, nativeSyncApiImpl) + PermissionApi.setUp(messenger, permissionApiImpl) LocalImageApi.setUp(messenger, LocalImagesImpl(ctx)) RemoteImageApi.setUp(messenger, RemoteImagesImpl(ctx)) @@ -53,6 +57,7 @@ class MainActivity : FlutterFragmentActivity() { flutterEngine.plugins.add(backgroundEngineLockImpl) flutterEngine.plugins.add(nativeSyncApiImpl) + flutterEngine.plugins.add(permissionApiImpl) } fun cancelPlugins(flutterEngine: FlutterEngine) { @@ -60,6 +65,8 @@ class MainActivity : FlutterFragmentActivity() { flutterEngine.plugins.get(NativeSyncApiImpl26::class.java) as ImmichPlugin? ?: flutterEngine.plugins.get(NativeSyncApiImpl30::class.java) as ImmichPlugin? nativeApi?.detachFromEngine() + val permissionApi = flutterEngine.plugins.get(PermissionApiImpl::class.java) as ImmichPlugin? + permissionApi?.detachFromEngine() } } } diff --git a/mobile/android/app/src/main/kotlin/app/alextran/immich/core/Network.g.kt b/mobile/android/app/src/main/kotlin/app/alextran/immich/core/Network.g.kt index 1687a7ba95..c380a0a6a5 100644 --- a/mobile/android/app/src/main/kotlin/app/alextran/immich/core/Network.g.kt +++ b/mobile/android/app/src/main/kotlin/app/alextran/immich/core/Network.g.kt @@ -315,6 +315,7 @@ interface NetworkApi { fun hasCertificate(): Boolean fun getClientPointer(): Long fun setRequestHeaders(headers: Map, serverUrls: List, token: String?) + fun getAppGroupId(): String companion object { /** The codec used by NetworkApi. */ @@ -430,6 +431,21 @@ interface NetworkApi { channel.setMessageHandler(null) } } + run { + val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.immich_mobile.NetworkApi.getAppGroupId$separatedMessageChannelSuffix", codec) + if (api != null) { + channel.setMessageHandler { _, reply -> + val wrapped: List = try { + listOf(api.getAppGroupId()) + } catch (exception: Throwable) { + NetworkPigeonUtils.wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } } } } diff --git a/mobile/android/app/src/main/kotlin/app/alextran/immich/core/NetworkApiPlugin.kt b/mobile/android/app/src/main/kotlin/app/alextran/immich/core/NetworkApiPlugin.kt index 85b7a6c730..4479ec7701 100644 --- a/mobile/android/app/src/main/kotlin/app/alextran/immich/core/NetworkApiPlugin.kt +++ b/mobile/android/app/src/main/kotlin/app/alextran/immich/core/NetworkApiPlugin.kt @@ -13,7 +13,7 @@ class NetworkApiPlugin : FlutterPlugin, ActivityAware { private var networkApi: NetworkApiImpl? = null override fun onAttachedToEngine(binding: FlutterPlugin.FlutterPluginBinding) { - networkApi = NetworkApiImpl() + networkApi = NetworkApiImpl(binding.applicationContext) NetworkApi.setUp(binding.binaryMessenger, networkApi) } @@ -39,9 +39,11 @@ class NetworkApiPlugin : FlutterPlugin, ActivityAware { } } -private class NetworkApiImpl : NetworkApi { +private class NetworkApiImpl(private val context: Context) : NetworkApi { var activity: Activity? = null + override fun getAppGroupId(): String = context.packageName + override fun addCertificate(clientData: ClientCertData, callback: (Result) -> Unit) { try { HttpClientManager.setKeyEntry(clientData.data, clientData.password.toCharArray()) diff --git a/mobile/android/app/src/main/kotlin/app/alextran/immich/permission/ManageMediaPermissionDelegate.kt b/mobile/android/app/src/main/kotlin/app/alextran/immich/permission/ManageMediaPermissionDelegate.kt new file mode 100644 index 0000000000..ddabfbabd8 --- /dev/null +++ b/mobile/android/app/src/main/kotlin/app/alextran/immich/permission/ManageMediaPermissionDelegate.kt @@ -0,0 +1,96 @@ +package app.alextran.immich.permission + +import android.content.Context +import android.content.Intent +import android.os.Build +import android.provider.MediaStore +import android.provider.Settings +import androidx.core.net.toUri +import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding +import io.flutter.plugin.common.PluginRegistry + +class ManageMediaPermissionDelegate( + context: Context, + private val requestCode: Int = 1003, +) : PluginRegistry.ActivityResultListener { + private val ctx = context.applicationContext + private var activityBinding: ActivityPluginBinding? = null + private var pendingResult: ((Result) -> Unit)? = null + + fun hasManageMediaPermission(): Boolean { + return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { + MediaStore.canManageMedia(ctx) + } else { + false + } + } + + fun requestManageMediaPermission(callback: (Result) -> Unit) { + if (hasManageMediaPermission()) { + callback(Result.success(true)) + return + } + + openManageMediaPermissionSettings(callback) + } + + fun manageMediaPermission(callback: (Result) -> Unit) { + openManageMediaPermissionSettings(callback) + } + + private fun openManageMediaPermissionSettings(callback: (Result) -> Unit) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) { + callback(Result.success(false)) + return + } + + val activity = activityBinding?.activity + if (activity == null) { + callback(Result.failure(FlutterError("NO_ACTIVITY", "Activity not available", null))) + return + } + + pendingResult = callback + val intent = Intent(Settings.ACTION_REQUEST_MANAGE_MEDIA).apply { + data = "package:${activity.packageName}".toUri() + } + try { + activity.startActivityForResult(intent, requestCode) + } catch (e: Exception) { + pendingResult = null + callback( + Result.failure( + FlutterError("ACTIVITY_LAUNCH_FAILED", "Failed to launch MANAGE_MEDIA settings", e.toString()) + ) + ) + } + } + + fun onAttachedToActivity(binding: ActivityPluginBinding) { + activityBinding = binding + binding.addActivityResultListener(this) + } + + fun onDetachedFromActivity() { + failPending("ACTIVITY_DETACHED", "Activity detached before MANAGE_MEDIA result") + activityBinding?.removeActivityResultListener(this) + activityBinding = null + } + + override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?): Boolean { + if (requestCode == this.requestCode) { + val callback = pendingResult + pendingResult = null + callback?.invoke(Result.success(hasManageMediaPermission())) + return true + } + + return false + } + + private fun failPending(code: String, message: String) { + val callback = pendingResult ?: return + pendingResult = null + callback(Result.failure(FlutterError(code, message, null))) + } +} diff --git a/mobile/android/app/src/main/kotlin/app/alextran/immich/permission/PermissionApi.g.kt b/mobile/android/app/src/main/kotlin/app/alextran/immich/permission/PermissionApi.g.kt new file mode 100644 index 0000000000..48a1a72037 --- /dev/null +++ b/mobile/android/app/src/main/kotlin/app/alextran/immich/permission/PermissionApi.g.kt @@ -0,0 +1,128 @@ +// Autogenerated from Pigeon (v26.3.4), do not edit directly. +// See also: https://pub.dev/packages/pigeon +@file:Suppress("UNCHECKED_CAST", "ArrayInDataClass") + +package app.alextran.immich.permission + +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 PermissionApiPigeonUtils { + + 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) + ) + } + } +} + +/** + * Error class for passing custom error details to Flutter via a thrown PlatformException. + * @property code The error code. + * @property message The error message. + * @property details The error details. Must be a datatype supported by the api codec. + */ +class FlutterError ( + val code: String, + override val message: String? = null, + val details: Any? = null +) : RuntimeException() +private open class PermissionApiPigeonCodec : 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 PermissionApi { + fun hasManageMediaPermission(): Boolean + fun requestManageMediaPermission(callback: (Result) -> Unit) + fun manageMediaPermission(callback: (Result) -> Unit) + + companion object { + /** The codec used by PermissionApi. */ + val codec: MessageCodec by lazy { + PermissionApiPigeonCodec() + } + /** Sets up an instance of `PermissionApi` to handle messages through the `binaryMessenger`. */ + @JvmOverloads + fun setUp(binaryMessenger: BinaryMessenger, api: PermissionApi?, messageChannelSuffix: String = "") { + val separatedMessageChannelSuffix = if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else "" + run { + val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.immich_mobile.PermissionApi.hasManageMediaPermission$separatedMessageChannelSuffix", codec) + if (api != null) { + channel.setMessageHandler { _, reply -> + val wrapped: List = try { + listOf(api.hasManageMediaPermission()) + } catch (exception: Throwable) { + PermissionApiPigeonUtils.wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.immich_mobile.PermissionApi.requestManageMediaPermission$separatedMessageChannelSuffix", codec) + if (api != null) { + channel.setMessageHandler { _, reply -> + api.requestManageMediaPermission{ result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(PermissionApiPigeonUtils.wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(PermissionApiPigeonUtils.wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.immich_mobile.PermissionApi.manageMediaPermission$separatedMessageChannelSuffix", codec) + if (api != null) { + channel.setMessageHandler { _, reply -> + api.manageMediaPermission{ result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(PermissionApiPigeonUtils.wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(PermissionApiPigeonUtils.wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + } + } +} diff --git a/mobile/android/app/src/main/kotlin/app/alextran/immich/permission/PermissionApiImpl.kt b/mobile/android/app/src/main/kotlin/app/alextran/immich/permission/PermissionApiImpl.kt new file mode 100644 index 0000000000..c3443bb06d --- /dev/null +++ b/mobile/android/app/src/main/kotlin/app/alextran/immich/permission/PermissionApiImpl.kt @@ -0,0 +1,37 @@ +package app.alextran.immich.permission + +import android.content.Context +import app.alextran.immich.core.ImmichPlugin +import io.flutter.embedding.engine.plugins.activity.ActivityAware +import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding + +class PermissionApiImpl(context: Context) : ImmichPlugin(), PermissionApi, ActivityAware { + private val manageMediaPermissionDelegate = ManageMediaPermissionDelegate(context) + + override fun hasManageMediaPermission(): Boolean = + manageMediaPermissionDelegate.hasManageMediaPermission() + + override fun requestManageMediaPermission(callback: (Result) -> Unit) { + manageMediaPermissionDelegate.requestManageMediaPermission { completeWhenActive(callback, it) } + } + + override fun manageMediaPermission(callback: (Result) -> Unit) { + manageMediaPermissionDelegate.manageMediaPermission { completeWhenActive(callback, it) } + } + + override fun onAttachedToActivity(binding: ActivityPluginBinding) { + manageMediaPermissionDelegate.onAttachedToActivity(binding) + } + + override fun onDetachedFromActivityForConfigChanges() { + manageMediaPermissionDelegate.onDetachedFromActivity() + } + + override fun onReattachedToActivityForConfigChanges(binding: ActivityPluginBinding) { + manageMediaPermissionDelegate.onAttachedToActivity(binding) + } + + override fun onDetachedFromActivity() { + manageMediaPermissionDelegate.onDetachedFromActivity() + } +} diff --git a/mobile/android/app/src/main/kotlin/app/alextran/immich/sync/MediaTrashDelegate.kt b/mobile/android/app/src/main/kotlin/app/alextran/immich/sync/MediaTrashDelegate.kt new file mode 100644 index 0000000000..fbf4d7e919 --- /dev/null +++ b/mobile/android/app/src/main/kotlin/app/alextran/immich/sync/MediaTrashDelegate.kt @@ -0,0 +1,133 @@ +package app.alextran.immich.sync + +import android.app.Activity +import android.content.ContentResolver +import android.content.ContentUris +import android.content.Context +import android.content.Intent +import android.net.Uri +import android.os.Build +import android.os.Bundle +import android.provider.MediaStore +import androidx.annotation.RequiresApi +import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding +import io.flutter.plugin.common.PluginRegistry + +class MediaTrashDelegate( + context: Context, + private val trashRequestCode: Int = 1002, +) : PluginRegistry.ActivityResultListener { + private val ctx = context.applicationContext + private var activityBinding: ActivityPluginBinding? = null + private var pendingResult: ((Result) -> Unit)? = null + + private fun hasManageMediaPermission(): Boolean { + return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { + MediaStore.canManageMedia(ctx) + } else { + false + } + } + + fun restoreFromTrashById(mediaId: String, type: Long, callback: (Result) -> Unit) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R || !hasManageMediaPermission()) { + callback(Result.failure(FlutterError("PERMISSION_DENIED", "Media permission required", null))) + return + } + + val id = mediaId.toLongOrNull() + if (id == null) { + callback(Result.failure(FlutterError("INVALID_ID", "The file id is not a valid number: $mediaId", null))) + return + } + + if (!isInTrash(id)) { + callback(Result.failure(FlutterError("TRASH_NOT_FOUND", "Item with id=$id not found in trash", null))) + return + } + + restoreUri(ContentUris.withAppendedId(contentUriForType(type.toInt()), id), callback) + } + + @RequiresApi(Build.VERSION_CODES.R) + private fun restoreUri( + contentUri: Uri, + callback: (Result) -> Unit, + ) { + val activity = activityBinding?.activity + if (activity == null) { + callback(Result.failure(FlutterError("NO_ACTIVITY", "Activity not available", null))) + return + } + + try { + val pendingIntent = MediaStore.createTrashRequest(ctx.contentResolver, listOf(contentUri), false) + pendingResult = callback + activity.startIntentSenderForResult( + pendingIntent.intentSender, + trashRequestCode, + null, + 0, + 0, + 0, + ) + } catch (e: Exception) { + pendingResult = null + callback( + Result.failure( + FlutterError("TRASH_ERROR", "Error creating or starting trash request", e.toString()) + ) + ) + } + } + + @RequiresApi(Build.VERSION_CODES.R) + private fun isInTrash(id: Long): Boolean { + val filesUri = MediaStore.Files.getContentUri(MediaStore.VOLUME_EXTERNAL) + val args = Bundle().apply { + putString(ContentResolver.QUERY_ARG_SQL_SELECTION, "${MediaStore.Files.FileColumns._ID}=?") + putStringArray(ContentResolver.QUERY_ARG_SQL_SELECTION_ARGS, arrayOf(id.toString())) + putInt(MediaStore.QUERY_ARG_MATCH_TRASHED, MediaStore.MATCH_ONLY) + putInt(ContentResolver.QUERY_ARG_LIMIT, 1) + } + return ctx.contentResolver.query(filesUri, arrayOf(MediaStore.Files.FileColumns._ID), args, null) + ?.use { it.moveToFirst() } == true + } + + private fun contentUriForType(type: Int): Uri = + when (type) { + // Same order as AssetType from Dart. + 1 -> MediaStore.Images.Media.EXTERNAL_CONTENT_URI + 2 -> MediaStore.Video.Media.EXTERNAL_CONTENT_URI + 3 -> MediaStore.Audio.Media.EXTERNAL_CONTENT_URI + else -> MediaStore.Files.getContentUri(MediaStore.VOLUME_EXTERNAL) + } + + fun onAttachedToActivity(binding: ActivityPluginBinding) { + activityBinding = binding + binding.addActivityResultListener(this) + } + + fun onDetachedFromActivity() { + failPending("ACTIVITY_DETACHED", "Activity detached before trash result") + activityBinding?.removeActivityResultListener(this) + activityBinding = null + } + + override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?): Boolean { + if (requestCode == trashRequestCode) { + val callback = pendingResult + pendingResult = null + callback?.invoke(Result.success(resultCode == Activity.RESULT_OK)) + return true + } + + return false + } + + private fun failPending(code: String, message: String) { + val callback = pendingResult ?: return + pendingResult = null + callback(Result.failure(FlutterError(code, message, null))) + } +} diff --git a/mobile/android/app/src/main/kotlin/app/alextran/immich/sync/Messages.g.kt b/mobile/android/app/src/main/kotlin/app/alextran/immich/sync/Messages.g.kt index b49664dea5..345302026d 100644 --- a/mobile/android/app/src/main/kotlin/app/alextran/immich/sync/Messages.g.kt +++ b/mobile/android/app/src/main/kotlin/app/alextran/immich/sync/Messages.g.kt @@ -553,6 +553,7 @@ interface NativeSyncApi { fun hashAssets(assetIds: List, allowNetworkAccess: Boolean, callback: (Result>) -> Unit) fun cancelHashing() fun getTrashedAssets(): Map> + fun restoreFromTrashById(mediaId: String, type: Long, callback: (Result) -> Unit) fun getCloudIdForAssetIds(assetIds: List): List companion object { @@ -747,6 +748,27 @@ interface NativeSyncApi { channel.setMessageHandler(null) } } + run { + val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.immich_mobile.NativeSyncApi.restoreFromTrashById$separatedMessageChannelSuffix", codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val mediaIdArg = args[0] as String + val typeArg = args[1] as Long + api.restoreFromTrashById(mediaIdArg, typeArg) { result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(MessagesPigeonUtils.wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(MessagesPigeonUtils.wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } run { val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.immich_mobile.NativeSyncApi.getCloudIdForAssetIds$separatedMessageChannelSuffix", codec, taskQueue) if (api != null) { diff --git a/mobile/android/app/src/main/kotlin/app/alextran/immich/sync/MessagesImplBase.kt b/mobile/android/app/src/main/kotlin/app/alextran/immich/sync/MessagesImplBase.kt index 777a565fe3..1f5ff2529e 100644 --- a/mobile/android/app/src/main/kotlin/app/alextran/immich/sync/MessagesImplBase.kt +++ b/mobile/android/app/src/main/kotlin/app/alextran/immich/sync/MessagesImplBase.kt @@ -17,6 +17,8 @@ import com.bumptech.glide.Glide import com.bumptech.glide.load.ImageHeaderParser import com.bumptech.glide.load.ImageHeaderParserUtils import com.bumptech.glide.load.resource.bitmap.DefaultImageHeaderParser +import io.flutter.embedding.engine.plugins.activity.ActivityAware +import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job @@ -39,10 +41,11 @@ sealed class AssetResult { private const val TAG = "NativeSyncApiImplBase" @SuppressLint("InlinedApi") -open class NativeSyncApiImplBase(context: Context) : ImmichPlugin() { +open class NativeSyncApiImplBase(context: Context) : ImmichPlugin(), ActivityAware { private val ctx: Context = context.applicationContext private var hashTask: Job? = null + private val mediaTrashDelegate = MediaTrashDelegate(ctx) companion object { private const val MAX_CONCURRENT_HASH_OPERATIONS = 16 @@ -448,6 +451,26 @@ open class NativeSyncApiImplBase(context: Context) : ImmichPlugin() { hashTask = null } + fun restoreFromTrashById(mediaId: String, type: Long, callback: (Result) -> Unit) { + mediaTrashDelegate.restoreFromTrashById(mediaId, type) { completeWhenActive(callback, it) } + } + + override fun onAttachedToActivity(binding: ActivityPluginBinding) { + mediaTrashDelegate.onAttachedToActivity(binding) + } + + override fun onDetachedFromActivityForConfigChanges() { + mediaTrashDelegate.onDetachedFromActivity() + } + + override fun onReattachedToActivityForConfigChanges(binding: ActivityPluginBinding) { + mediaTrashDelegate.onAttachedToActivity(binding) + } + + override fun onDetachedFromActivity() { + mediaTrashDelegate.onDetachedFromActivity() + } + // This method is only implemented on iOS; on Android, we do not have a concept of cloud IDs @Suppress("unused", "UNUSED_PARAMETER") fun getCloudIdForAssetIds(assetIds: List): List { diff --git a/mobile/android/gradle.properties b/mobile/android/gradle.properties index f63dcd33e1..99f62dc8c2 100644 --- a/mobile/android/gradle.properties +++ b/mobile/android/gradle.properties @@ -5,3 +5,7 @@ android.nonTransitiveRClass=false android.nonFinalResIds=false org.gradle.caching=true org.gradle.parallel=true +# This builtInKotlin flag was added automatically by Flutter migrator +android.builtInKotlin=false +# This newDsl flag was added automatically by Flutter migrator +android.newDsl=false diff --git a/mobile/drift_schemas/main/drift_schema_v27.json b/mobile/drift_schemas/main/drift_schema_v27.json new file mode 100644 index 0000000000..4df6ef8389 --- /dev/null +++ b/mobile/drift_schemas/main/drift_schema_v27.json @@ -0,0 +1,3368 @@ +{ + "_meta": { + "description": "This file contains a serialized version of schema entities for drift.", + "version": "1.3.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_ms", + "getter_name": "durationMs", + "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": [ + { + "foreign_key": { + "to": { + "table": "user_entity", + "column": "id" + }, + "initially_deferred": false, + "on_update": null, + "on_delete": "cascade" + } + } + ] + }, + { + "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": "uploaded_at", + "getter_name": "uploadedAt", + "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": [] + }, + { + "name": "is_edited", + "getter_name": "isEdited", + "moor_type": "bool", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "CHECK (\"is_edited\" IN (0, 1))", + "dialectAwareDefaultConstraints": { + "sqlite": "CHECK (\"is_edited\" 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": [ + "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": [ + { + "foreign_key": { + "to": { + "table": "user_entity", + "column": "id" + }, + "initially_deferred": false, + "on_update": null, + "on_delete": "cascade" + } + } + ] + }, + { + "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_ms", + "getter_name": "durationMs", + "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": [] + }, + { + "name": "i_cloud_id", + "getter_name": "iCloudId", + "moor_type": "string", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "adjustment_time", + "getter_name": "adjustmentTime", + "moor_type": "dateTime", + "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": "playback_style", + "getter_name": "playbackStyle", + "moor_type": "int", + "nullable": false, + "customConstraints": null, + "default_dart": "const CustomExpression('0')", + "default_client_dart": null, + "dsl_features": [], + "type_converter": { + "dart_expr": "const EnumIndexConverter(AssetPlaybackStyle.values)", + "dart_type_name": "AssetPlaybackStyle" + } + } + ], + "is_virtual": false, + "without_rowid": true, + "constraints": [], + "strict": true, + "explicit_pk": [ + "id" + ] + } + }, + { + "id": 4, + "references": [ + 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": "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": [ + { + "foreign_key": { + "to": { + "table": "remote_asset_entity", + "column": "id" + }, + "initially_deferred": false, + "on_update": null, + "on_delete": "setNull" + } + } + ] + }, + { + "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": [ + { + "foreign_key": { + "to": { + "table": "remote_album_entity", + "column": "id" + }, + "initially_deferred": false, + "on_update": null, + "on_delete": "setNull" + } + } + ] + }, + { + "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": [ + { + "foreign_key": { + "to": { + "table": "local_asset_entity", + "column": "id" + }, + "initially_deferred": false, + "on_update": null, + "on_delete": "cascade" + } + } + ] + }, + { + "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": [ + { + "foreign_key": { + "to": { + "table": "local_album_entity", + "column": "id" + }, + "initially_deferred": false, + "on_update": null, + "on_delete": "cascade" + } + } + ] + }, + { + "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": [ + 6 + ], + "type": "index", + "data": { + "on": 6, + "name": "idx_local_album_asset_album_asset", + "sql": "CREATE INDEX IF NOT EXISTS idx_local_album_asset_album_asset ON local_album_asset_entity (album_id, asset_id)", + "unique": false, + "columns": [] + } + }, + { + "id": 8, + "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": 9, + "references": [ + 3 + ], + "type": "index", + "data": { + "on": 3, + "name": "idx_local_asset_cloud_id", + "sql": "CREATE INDEX IF NOT EXISTS idx_local_asset_cloud_id ON local_asset_entity (i_cloud_id)", + "unique": false, + "columns": [] + } + }, + { + "id": 10, + "references": [ + 2 + ], + "type": "index", + "data": { + "on": 2, + "name": "idx_stack_primary_asset_id", + "sql": "CREATE INDEX IF NOT EXISTS idx_stack_primary_asset_id ON stack_entity (primary_asset_id)", + "unique": false, + "columns": [] + } + }, + { + "id": 11, + "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": 12, + "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": 13, + "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": 14, + "references": [ + 1 + ], + "type": "index", + "data": { + "on": 1, + "name": "idx_remote_asset_stack_id", + "sql": "CREATE INDEX IF NOT EXISTS idx_remote_asset_stack_id ON remote_asset_entity (stack_id)", + "unique": false, + "columns": [] + } + }, + { + "id": 15, + "references": [ + 1 + ], + "type": "index", + "data": { + "on": 1, + "name": "idx_remote_asset_owner_visibility_deleted_created", + "sql": "CREATE INDEX IF NOT EXISTS idx_remote_asset_owner_visibility_deleted_created\nON remote_asset_entity (owner_id, visibility, deleted_at, created_at DESC)\n", + "unique": false, + "columns": [] + } + }, + { + "id": 16, + "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": 17, + "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": [ + { + "foreign_key": { + "to": { + "table": "user_entity", + "column": "id" + }, + "initially_deferred": false, + "on_update": null, + "on_delete": "cascade" + } + } + ] + }, + { + "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": 18, + "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": [ + { + "foreign_key": { + "to": { + "table": "user_entity", + "column": "id" + }, + "initially_deferred": false, + "on_update": null, + "on_delete": "cascade" + } + } + ] + }, + { + "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": [ + { + "foreign_key": { + "to": { + "table": "user_entity", + "column": "id" + }, + "initially_deferred": false, + "on_update": null, + "on_delete": "cascade" + } + } + ] + }, + { + "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": 19, + "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": [ + { + "foreign_key": { + "to": { + "table": "remote_asset_entity", + "column": "id" + }, + "initially_deferred": false, + "on_update": null, + "on_delete": "cascade" + } + } + ] + }, + { + "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": 20, + "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": [ + { + "foreign_key": { + "to": { + "table": "remote_asset_entity", + "column": "id" + }, + "initially_deferred": false, + "on_update": null, + "on_delete": "cascade" + } + } + ] + }, + { + "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": [ + { + "foreign_key": { + "to": { + "table": "remote_album_entity", + "column": "id" + }, + "initially_deferred": false, + "on_update": null, + "on_delete": "cascade" + } + } + ] + } + ], + "is_virtual": false, + "without_rowid": true, + "constraints": [], + "strict": true, + "explicit_pk": [ + "asset_id", + "album_id" + ] + } + }, + { + "id": 21, + "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": [ + { + "foreign_key": { + "to": { + "table": "remote_album_entity", + "column": "id" + }, + "initially_deferred": false, + "on_update": null, + "on_delete": "cascade" + } + } + ] + }, + { + "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": [ + { + "foreign_key": { + "to": { + "table": "user_entity", + "column": "id" + }, + "initially_deferred": false, + "on_update": null, + "on_delete": "cascade" + } + } + ] + }, + { + "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": 22, + "references": [ + 1 + ], + "type": "table", + "data": { + "name": "remote_asset_cloud_id_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": [ + { + "foreign_key": { + "to": { + "table": "remote_asset_entity", + "column": "id" + }, + "initially_deferred": false, + "on_update": null, + "on_delete": "cascade" + } + } + ] + }, + { + "name": "cloud_id", + "getter_name": "cloudId", + "moor_type": "string", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "created_at", + "getter_name": "createdAt", + "moor_type": "dateTime", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "adjustment_time", + "getter_name": "adjustmentTime", + "moor_type": "dateTime", + "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": [] + } + ], + "is_virtual": false, + "without_rowid": true, + "constraints": [], + "strict": true, + "explicit_pk": [ + "asset_id" + ] + } + }, + { + "id": 23, + "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": [ + { + "foreign_key": { + "to": { + "table": "user_entity", + "column": "id" + }, + "initially_deferred": false, + "on_update": null, + "on_delete": "cascade" + } + } + ] + }, + { + "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": 24, + "references": [ + 1, + 23 + ], + "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": [ + { + "foreign_key": { + "to": { + "table": "remote_asset_entity", + "column": "id" + }, + "initially_deferred": false, + "on_update": null, + "on_delete": "cascade" + } + } + ] + }, + { + "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": [ + { + "foreign_key": { + "to": { + "table": "memory_entity", + "column": "id" + }, + "initially_deferred": false, + "on_update": null, + "on_delete": "cascade" + } + } + ] + } + ], + "is_virtual": false, + "without_rowid": true, + "constraints": [], + "strict": true, + "explicit_pk": [ + "asset_id", + "memory_id" + ] + } + }, + { + "id": 25, + "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": [ + { + "foreign_key": { + "to": { + "table": "user_entity", + "column": "id" + }, + "initially_deferred": false, + "on_update": null, + "on_delete": "cascade" + } + } + ] + }, + { + "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": 26, + "references": [ + 1, + 25 + ], + "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": [ + { + "foreign_key": { + "to": { + "table": "remote_asset_entity", + "column": "id" + }, + "initially_deferred": false, + "on_update": null, + "on_delete": "cascade" + } + } + ] + }, + { + "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": [ + { + "foreign_key": { + "to": { + "table": "person_entity", + "column": "id" + }, + "initially_deferred": false, + "on_update": null, + "on_delete": "setNull" + } + } + ] + }, + { + "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": [] + }, + { + "name": "is_visible", + "getter_name": "isVisible", + "moor_type": "bool", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "CHECK (\"is_visible\" IN (0, 1))", + "dialectAwareDefaultConstraints": { + "sqlite": "CHECK (\"is_visible\" IN (0, 1))" + }, + "default_dart": "const CustomExpression('1')", + "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": [] + } + ], + "is_virtual": false, + "without_rowid": true, + "constraints": [], + "strict": true, + "explicit_pk": [ + "id" + ] + } + }, + { + "id": 27, + "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": 28, + "references": [], + "type": "table", + "data": { + "name": "trashed_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_ms", + "getter_name": "durationMs", + "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": "album_id", + "getter_name": "albumId", + "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": [] + }, + { + "name": "source", + "getter_name": "source", + "moor_type": "int", + "nullable": false, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [], + "type_converter": { + "dart_expr": "const EnumIndexConverter(TrashOrigin.values)", + "dart_type_name": "TrashOrigin" + } + }, + { + "name": "playback_style", + "getter_name": "playbackStyle", + "moor_type": "int", + "nullable": false, + "customConstraints": null, + "default_dart": "const CustomExpression('0')", + "default_client_dart": null, + "dsl_features": [], + "type_converter": { + "dart_expr": "const EnumIndexConverter(AssetPlaybackStyle.values)", + "dart_type_name": "AssetPlaybackStyle" + } + } + ], + "is_virtual": false, + "without_rowid": true, + "constraints": [], + "strict": true, + "explicit_pk": [ + "id", + "album_id" + ] + } + }, + { + "id": 29, + "references": [ + 1 + ], + "type": "table", + "data": { + "name": "asset_edit_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": [ + { + "foreign_key": { + "to": { + "table": "remote_asset_entity", + "column": "id" + }, + "initially_deferred": false, + "on_update": null, + "on_delete": "cascade" + } + } + ] + }, + { + "name": "action", + "getter_name": "action", + "moor_type": "int", + "nullable": false, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [], + "type_converter": { + "dart_expr": "const EnumIndexConverter(AssetEditAction.values)", + "dart_type_name": "AssetEditAction" + } + }, + { + "name": "parameters", + "getter_name": "parameters", + "moor_type": "blob", + "nullable": false, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [], + "type_converter": { + "dart_expr": "editParameterConverter", + "dart_type_name": "Map" + } + }, + { + "name": "sequence", + "getter_name": "sequence", + "moor_type": "int", + "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": 30, + "references": [], + "type": "table", + "data": { + "name": "settings", + "was_declared_in_moor": false, + "columns": [ + { + "name": "key", + "getter_name": "key", + "moor_type": "string", + "nullable": false, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "value", + "getter_name": "value", + "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": [] + } + ], + "is_virtual": false, + "without_rowid": true, + "constraints": [], + "strict": true, + "explicit_pk": [ + "key" + ] + } + }, + { + "id": 31, + "references": [ + 18 + ], + "type": "index", + "data": { + "on": 18, + "name": "idx_partner_shared_with_id", + "sql": "CREATE INDEX IF NOT EXISTS idx_partner_shared_with_id ON partner_entity (shared_with_id)", + "unique": false, + "columns": [] + } + }, + { + "id": 32, + "references": [ + 19 + ], + "type": "index", + "data": { + "on": 19, + "name": "idx_lat_lng", + "sql": "CREATE INDEX IF NOT EXISTS idx_lat_lng ON remote_exif_entity (latitude, longitude)", + "unique": false, + "columns": [] + } + }, + { + "id": 33, + "references": [ + 19 + ], + "type": "index", + "data": { + "on": 19, + "name": "idx_remote_exif_city", + "sql": "CREATE INDEX IF NOT EXISTS idx_remote_exif_city\nON remote_exif_entity (city) WHERE city IS NOT NULL\n", + "unique": false, + "columns": [] + } + }, + { + "id": 34, + "references": [ + 20 + ], + "type": "index", + "data": { + "on": 20, + "name": "idx_remote_album_asset_album_asset", + "sql": "CREATE INDEX IF NOT EXISTS idx_remote_album_asset_album_asset ON remote_album_asset_entity (album_id, asset_id)", + "unique": false, + "columns": [] + } + }, + { + "id": 35, + "references": [ + 22 + ], + "type": "index", + "data": { + "on": 22, + "name": "idx_remote_asset_cloud_id", + "sql": "CREATE INDEX IF NOT EXISTS idx_remote_asset_cloud_id ON remote_asset_cloud_id_entity (cloud_id)", + "unique": false, + "columns": [] + } + }, + { + "id": 36, + "references": [ + 25 + ], + "type": "index", + "data": { + "on": 25, + "name": "idx_person_owner_id", + "sql": "CREATE INDEX IF NOT EXISTS idx_person_owner_id ON person_entity (owner_id)", + "unique": false, + "columns": [] + } + }, + { + "id": 37, + "references": [ + 26 + ], + "type": "index", + "data": { + "on": 26, + "name": "idx_asset_face_person_id", + "sql": "CREATE INDEX IF NOT EXISTS idx_asset_face_person_id ON asset_face_entity (person_id)", + "unique": false, + "columns": [] + } + }, + { + "id": 38, + "references": [ + 26 + ], + "type": "index", + "data": { + "on": 26, + "name": "idx_asset_face_asset_id", + "sql": "CREATE INDEX IF NOT EXISTS idx_asset_face_asset_id ON asset_face_entity (asset_id)", + "unique": false, + "columns": [] + } + }, + { + "id": 39, + "references": [ + 26 + ], + "type": "index", + "data": { + "on": 26, + "name": "idx_asset_face_visible_person", + "sql": "CREATE INDEX IF NOT EXISTS idx_asset_face_visible_person\nON asset_face_entity (person_id, asset_id)\nWHERE is_visible = 1 AND deleted_at IS NULL\n", + "unique": false, + "columns": [] + } + }, + { + "id": 40, + "references": [ + 28 + ], + "type": "index", + "data": { + "on": 28, + "name": "idx_trashed_local_asset_checksum", + "sql": "CREATE INDEX IF NOT EXISTS idx_trashed_local_asset_checksum ON trashed_local_asset_entity (checksum)", + "unique": false, + "columns": [] + } + }, + { + "id": 41, + "references": [ + 28 + ], + "type": "index", + "data": { + "on": 28, + "name": "idx_trashed_local_asset_album", + "sql": "CREATE INDEX IF NOT EXISTS idx_trashed_local_asset_album ON trashed_local_asset_entity (album_id)", + "unique": false, + "columns": [] + } + }, + { + "id": 42, + "references": [ + 29 + ], + "type": "index", + "data": { + "on": 29, + "name": "idx_asset_edit_asset_id", + "sql": "CREATE INDEX IF NOT EXISTS idx_asset_edit_asset_id ON asset_edit_entity (asset_id)", + "unique": false, + "columns": [] + } + } + ], + "fixed_sql": [ + { + "name": "user_entity", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE TABLE IF NOT EXISTS \"user_entity\" (\"id\" TEXT NOT NULL, \"name\" TEXT NOT NULL, \"email\" TEXT NOT NULL, \"has_profile_image\" INTEGER NOT NULL DEFAULT 0 CHECK (\"has_profile_image\" IN (0, 1)), \"profile_changed_at\" TEXT NOT NULL DEFAULT (CURRENT_TIMESTAMP), \"avatar_color\" INTEGER NOT NULL DEFAULT 0, PRIMARY KEY (\"id\")) WITHOUT ROWID, STRICT;" + } + ] + }, + { + "name": "remote_asset_entity", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE TABLE IF NOT EXISTS \"remote_asset_entity\" (\"name\" TEXT NOT NULL, \"type\" INTEGER NOT NULL, \"created_at\" TEXT NOT NULL DEFAULT (CURRENT_TIMESTAMP), \"updated_at\" TEXT NOT NULL DEFAULT (CURRENT_TIMESTAMP), \"width\" INTEGER NULL, \"height\" INTEGER NULL, \"duration_ms\" INTEGER NULL, \"id\" TEXT NOT NULL, \"checksum\" TEXT NOT NULL, \"is_favorite\" INTEGER NOT NULL DEFAULT 0 CHECK (\"is_favorite\" IN (0, 1)), \"owner_id\" TEXT NOT NULL REFERENCES user_entity (id) ON DELETE CASCADE, \"local_date_time\" TEXT NULL, \"thumb_hash\" TEXT NULL, \"deleted_at\" TEXT NULL, \"uploaded_at\" TEXT NULL, \"live_photo_video_id\" TEXT NULL, \"visibility\" INTEGER NOT NULL, \"stack_id\" TEXT NULL, \"library_id\" TEXT NULL, \"is_edited\" INTEGER NOT NULL DEFAULT 0 CHECK (\"is_edited\" IN (0, 1)), PRIMARY KEY (\"id\")) WITHOUT ROWID, STRICT;" + } + ] + }, + { + "name": "stack_entity", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE TABLE IF NOT EXISTS \"stack_entity\" (\"id\" TEXT NOT NULL, \"created_at\" TEXT NOT NULL DEFAULT (CURRENT_TIMESTAMP), \"updated_at\" TEXT NOT NULL DEFAULT (CURRENT_TIMESTAMP), \"owner_id\" TEXT NOT NULL REFERENCES user_entity (id) ON DELETE CASCADE, \"primary_asset_id\" TEXT NOT NULL, PRIMARY KEY (\"id\")) WITHOUT ROWID, STRICT;" + } + ] + }, + { + "name": "local_asset_entity", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE TABLE IF NOT EXISTS \"local_asset_entity\" (\"name\" TEXT NOT NULL, \"type\" INTEGER NOT NULL, \"created_at\" TEXT NOT NULL DEFAULT (CURRENT_TIMESTAMP), \"updated_at\" TEXT NOT NULL DEFAULT (CURRENT_TIMESTAMP), \"width\" INTEGER NULL, \"height\" INTEGER NULL, \"duration_ms\" INTEGER NULL, \"id\" TEXT NOT NULL, \"checksum\" TEXT NULL, \"is_favorite\" INTEGER NOT NULL DEFAULT 0 CHECK (\"is_favorite\" IN (0, 1)), \"orientation\" INTEGER NOT NULL DEFAULT 0, \"i_cloud_id\" TEXT NULL, \"adjustment_time\" TEXT NULL, \"latitude\" REAL NULL, \"longitude\" REAL NULL, \"playback_style\" INTEGER NOT NULL DEFAULT 0, PRIMARY KEY (\"id\")) WITHOUT ROWID, STRICT;" + } + ] + }, + { + "name": "remote_album_entity", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE TABLE IF NOT EXISTS \"remote_album_entity\" (\"id\" TEXT NOT NULL, \"name\" TEXT NOT NULL, \"description\" TEXT NOT NULL DEFAULT '', \"created_at\" TEXT NOT NULL DEFAULT (CURRENT_TIMESTAMP), \"updated_at\" TEXT NOT NULL DEFAULT (CURRENT_TIMESTAMP), \"thumbnail_asset_id\" TEXT NULL REFERENCES remote_asset_entity (id) ON DELETE SET NULL, \"is_activity_enabled\" INTEGER NOT NULL DEFAULT 1 CHECK (\"is_activity_enabled\" IN (0, 1)), \"order\" INTEGER NOT NULL, PRIMARY KEY (\"id\")) WITHOUT ROWID, STRICT;" + } + ] + }, + { + "name": "local_album_entity", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE TABLE IF NOT EXISTS \"local_album_entity\" (\"id\" TEXT NOT NULL, \"name\" TEXT NOT NULL, \"updated_at\" TEXT NOT NULL DEFAULT (CURRENT_TIMESTAMP), \"backup_selection\" INTEGER NOT NULL, \"is_ios_shared_album\" INTEGER NOT NULL DEFAULT 0 CHECK (\"is_ios_shared_album\" IN (0, 1)), \"linked_remote_album_id\" TEXT NULL REFERENCES remote_album_entity (id) ON DELETE SET NULL, \"marker\" INTEGER NULL CHECK (\"marker\" IN (0, 1)), PRIMARY KEY (\"id\")) WITHOUT ROWID, STRICT;" + } + ] + }, + { + "name": "local_album_asset_entity", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE TABLE IF NOT EXISTS \"local_album_asset_entity\" (\"asset_id\" TEXT NOT NULL REFERENCES local_asset_entity (id) ON DELETE CASCADE, \"album_id\" TEXT NOT NULL REFERENCES local_album_entity (id) ON DELETE CASCADE, \"marker\" INTEGER NULL CHECK (\"marker\" IN (0, 1)), PRIMARY KEY (\"asset_id\", \"album_id\")) WITHOUT ROWID, STRICT;" + } + ] + }, + { + "name": "idx_local_album_asset_album_asset", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE INDEX IF NOT EXISTS idx_local_album_asset_album_asset ON local_album_asset_entity (album_id, asset_id)" + } + ] + }, + { + "name": "idx_local_asset_checksum", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE INDEX IF NOT EXISTS idx_local_asset_checksum ON local_asset_entity (checksum)" + } + ] + }, + { + "name": "idx_local_asset_cloud_id", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE INDEX IF NOT EXISTS idx_local_asset_cloud_id ON local_asset_entity (i_cloud_id)" + } + ] + }, + { + "name": "idx_stack_primary_asset_id", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE INDEX IF NOT EXISTS idx_stack_primary_asset_id ON stack_entity (primary_asset_id)" + } + ] + }, + { + "name": "UQ_remote_assets_owner_checksum", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE UNIQUE INDEX IF NOT EXISTS UQ_remote_assets_owner_checksum ON remote_asset_entity (owner_id, checksum) WHERE(library_id IS NULL)" + } + ] + }, + { + "name": "UQ_remote_assets_owner_library_checksum", + "sql": [ + { + "dialect": "sqlite", + "sql": "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)" + } + ] + }, + { + "name": "idx_remote_asset_checksum", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE INDEX IF NOT EXISTS idx_remote_asset_checksum ON remote_asset_entity (checksum)" + } + ] + }, + { + "name": "idx_remote_asset_stack_id", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE INDEX IF NOT EXISTS idx_remote_asset_stack_id ON remote_asset_entity (stack_id)" + } + ] + }, + { + "name": "idx_remote_asset_owner_visibility_deleted_created", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE INDEX IF NOT EXISTS idx_remote_asset_owner_visibility_deleted_created ON remote_asset_entity (owner_id, visibility, deleted_at, created_at DESC)" + } + ] + }, + { + "name": "auth_user_entity", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE TABLE IF NOT EXISTS \"auth_user_entity\" (\"id\" TEXT NOT NULL, \"name\" TEXT NOT NULL, \"email\" TEXT NOT NULL, \"is_admin\" INTEGER NOT NULL DEFAULT 0 CHECK (\"is_admin\" IN (0, 1)), \"has_profile_image\" INTEGER NOT NULL DEFAULT 0 CHECK (\"has_profile_image\" IN (0, 1)), \"profile_changed_at\" TEXT NOT NULL DEFAULT (CURRENT_TIMESTAMP), \"avatar_color\" INTEGER NOT NULL, \"quota_size_in_bytes\" INTEGER NOT NULL DEFAULT 0, \"quota_usage_in_bytes\" INTEGER NOT NULL DEFAULT 0, \"pin_code\" TEXT NULL, PRIMARY KEY (\"id\")) WITHOUT ROWID, STRICT;" + } + ] + }, + { + "name": "user_metadata_entity", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE TABLE IF NOT EXISTS \"user_metadata_entity\" (\"user_id\" TEXT NOT NULL REFERENCES user_entity (id) ON DELETE CASCADE, \"key\" INTEGER NOT NULL, \"value\" BLOB NOT NULL, PRIMARY KEY (\"user_id\", \"key\")) WITHOUT ROWID, STRICT;" + } + ] + }, + { + "name": "partner_entity", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE TABLE IF NOT EXISTS \"partner_entity\" (\"shared_by_id\" TEXT NOT NULL REFERENCES user_entity (id) ON DELETE CASCADE, \"shared_with_id\" TEXT NOT NULL REFERENCES user_entity (id) ON DELETE CASCADE, \"in_timeline\" INTEGER NOT NULL DEFAULT 0 CHECK (\"in_timeline\" IN (0, 1)), PRIMARY KEY (\"shared_by_id\", \"shared_with_id\")) WITHOUT ROWID, STRICT;" + } + ] + }, + { + "name": "remote_exif_entity", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE TABLE IF NOT EXISTS \"remote_exif_entity\" (\"asset_id\" TEXT NOT NULL REFERENCES remote_asset_entity (id) ON DELETE CASCADE, \"city\" TEXT NULL, \"state\" TEXT NULL, \"country\" TEXT NULL, \"date_time_original\" TEXT NULL, \"description\" TEXT NULL, \"height\" INTEGER NULL, \"width\" INTEGER NULL, \"exposure_time\" TEXT NULL, \"f_number\" REAL NULL, \"file_size\" INTEGER NULL, \"focal_length\" REAL NULL, \"latitude\" REAL NULL, \"longitude\" REAL NULL, \"iso\" INTEGER NULL, \"make\" TEXT NULL, \"model\" TEXT NULL, \"lens\" TEXT NULL, \"orientation\" TEXT NULL, \"time_zone\" TEXT NULL, \"rating\" INTEGER NULL, \"projection_type\" TEXT NULL, PRIMARY KEY (\"asset_id\")) WITHOUT ROWID, STRICT;" + } + ] + }, + { + "name": "remote_album_asset_entity", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE TABLE IF NOT EXISTS \"remote_album_asset_entity\" (\"asset_id\" TEXT NOT NULL REFERENCES remote_asset_entity (id) ON DELETE CASCADE, \"album_id\" TEXT NOT NULL REFERENCES remote_album_entity (id) ON DELETE CASCADE, PRIMARY KEY (\"asset_id\", \"album_id\")) WITHOUT ROWID, STRICT;" + } + ] + }, + { + "name": "remote_album_user_entity", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE TABLE IF NOT EXISTS \"remote_album_user_entity\" (\"album_id\" TEXT NOT NULL REFERENCES remote_album_entity (id) ON DELETE CASCADE, \"user_id\" TEXT NOT NULL REFERENCES user_entity (id) ON DELETE CASCADE, \"role\" INTEGER NOT NULL, PRIMARY KEY (\"album_id\", \"user_id\")) WITHOUT ROWID, STRICT;" + } + ] + }, + { + "name": "remote_asset_cloud_id_entity", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE TABLE IF NOT EXISTS \"remote_asset_cloud_id_entity\" (\"asset_id\" TEXT NOT NULL REFERENCES remote_asset_entity (id) ON DELETE CASCADE, \"cloud_id\" TEXT NULL, \"created_at\" TEXT NULL, \"adjustment_time\" TEXT NULL, \"latitude\" REAL NULL, \"longitude\" REAL NULL, PRIMARY KEY (\"asset_id\")) WITHOUT ROWID, STRICT;" + } + ] + }, + { + "name": "memory_entity", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE TABLE IF NOT EXISTS \"memory_entity\" (\"id\" TEXT NOT NULL, \"created_at\" TEXT NOT NULL DEFAULT (CURRENT_TIMESTAMP), \"updated_at\" TEXT NOT NULL DEFAULT (CURRENT_TIMESTAMP), \"deleted_at\" TEXT NULL, \"owner_id\" TEXT NOT NULL REFERENCES user_entity (id) ON DELETE CASCADE, \"type\" INTEGER NOT NULL, \"data\" TEXT NOT NULL, \"is_saved\" INTEGER NOT NULL DEFAULT 0 CHECK (\"is_saved\" IN (0, 1)), \"memory_at\" TEXT NOT NULL, \"seen_at\" TEXT NULL, \"show_at\" TEXT NULL, \"hide_at\" TEXT NULL, PRIMARY KEY (\"id\")) WITHOUT ROWID, STRICT;" + } + ] + }, + { + "name": "memory_asset_entity", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE TABLE IF NOT EXISTS \"memory_asset_entity\" (\"asset_id\" TEXT NOT NULL REFERENCES remote_asset_entity (id) ON DELETE CASCADE, \"memory_id\" TEXT NOT NULL REFERENCES memory_entity (id) ON DELETE CASCADE, PRIMARY KEY (\"asset_id\", \"memory_id\")) WITHOUT ROWID, STRICT;" + } + ] + }, + { + "name": "person_entity", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE TABLE IF NOT EXISTS \"person_entity\" (\"id\" TEXT NOT NULL, \"created_at\" TEXT NOT NULL DEFAULT (CURRENT_TIMESTAMP), \"updated_at\" TEXT NOT NULL DEFAULT (CURRENT_TIMESTAMP), \"owner_id\" TEXT NOT NULL REFERENCES user_entity (id) ON DELETE CASCADE, \"name\" TEXT NOT NULL, \"face_asset_id\" TEXT NULL, \"is_favorite\" INTEGER NOT NULL CHECK (\"is_favorite\" IN (0, 1)), \"is_hidden\" INTEGER NOT NULL CHECK (\"is_hidden\" IN (0, 1)), \"color\" TEXT NULL, \"birth_date\" TEXT NULL, PRIMARY KEY (\"id\")) WITHOUT ROWID, STRICT;" + } + ] + }, + { + "name": "asset_face_entity", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE TABLE IF NOT EXISTS \"asset_face_entity\" (\"id\" TEXT NOT NULL, \"asset_id\" TEXT NOT NULL REFERENCES remote_asset_entity (id) ON DELETE CASCADE, \"person_id\" TEXT NULL REFERENCES person_entity (id) ON DELETE SET NULL, \"image_width\" INTEGER NOT NULL, \"image_height\" INTEGER NOT NULL, \"bounding_box_x1\" INTEGER NOT NULL, \"bounding_box_y1\" INTEGER NOT NULL, \"bounding_box_x2\" INTEGER NOT NULL, \"bounding_box_y2\" INTEGER NOT NULL, \"source_type\" TEXT NOT NULL, \"is_visible\" INTEGER NOT NULL DEFAULT 1 CHECK (\"is_visible\" IN (0, 1)), \"deleted_at\" TEXT NULL, PRIMARY KEY (\"id\")) WITHOUT ROWID, STRICT;" + } + ] + }, + { + "name": "store_entity", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE TABLE IF NOT EXISTS \"store_entity\" (\"id\" INTEGER NOT NULL, \"string_value\" TEXT NULL, \"int_value\" INTEGER NULL, PRIMARY KEY (\"id\")) WITHOUT ROWID, STRICT;" + } + ] + }, + { + "name": "trashed_local_asset_entity", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE TABLE IF NOT EXISTS \"trashed_local_asset_entity\" (\"name\" TEXT NOT NULL, \"type\" INTEGER NOT NULL, \"created_at\" TEXT NOT NULL DEFAULT (CURRENT_TIMESTAMP), \"updated_at\" TEXT NOT NULL DEFAULT (CURRENT_TIMESTAMP), \"width\" INTEGER NULL, \"height\" INTEGER NULL, \"duration_ms\" INTEGER NULL, \"id\" TEXT NOT NULL, \"album_id\" TEXT NOT NULL, \"checksum\" TEXT NULL, \"is_favorite\" INTEGER NOT NULL DEFAULT 0 CHECK (\"is_favorite\" IN (0, 1)), \"orientation\" INTEGER NOT NULL DEFAULT 0, \"source\" INTEGER NOT NULL, \"playback_style\" INTEGER NOT NULL DEFAULT 0, PRIMARY KEY (\"id\", \"album_id\")) WITHOUT ROWID, STRICT;" + } + ] + }, + { + "name": "asset_edit_entity", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE TABLE IF NOT EXISTS \"asset_edit_entity\" (\"id\" TEXT NOT NULL, \"asset_id\" TEXT NOT NULL REFERENCES remote_asset_entity (id) ON DELETE CASCADE, \"action\" INTEGER NOT NULL, \"parameters\" BLOB NOT NULL, \"sequence\" INTEGER NOT NULL, PRIMARY KEY (\"id\")) WITHOUT ROWID, STRICT;" + } + ] + }, + { + "name": "settings", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE TABLE IF NOT EXISTS \"settings\" (\"key\" TEXT NOT NULL, \"value\" TEXT NOT NULL, \"updated_at\" TEXT NOT NULL DEFAULT (CURRENT_TIMESTAMP), PRIMARY KEY (\"key\")) WITHOUT ROWID, STRICT;" + } + ] + }, + { + "name": "idx_partner_shared_with_id", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE INDEX IF NOT EXISTS idx_partner_shared_with_id ON partner_entity (shared_with_id)" + } + ] + }, + { + "name": "idx_lat_lng", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE INDEX IF NOT EXISTS idx_lat_lng ON remote_exif_entity (latitude, longitude)" + } + ] + }, + { + "name": "idx_remote_exif_city", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE INDEX IF NOT EXISTS idx_remote_exif_city ON remote_exif_entity (city) WHERE city IS NOT NULL" + } + ] + }, + { + "name": "idx_remote_album_asset_album_asset", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE INDEX IF NOT EXISTS idx_remote_album_asset_album_asset ON remote_album_asset_entity (album_id, asset_id)" + } + ] + }, + { + "name": "idx_remote_asset_cloud_id", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE INDEX IF NOT EXISTS idx_remote_asset_cloud_id ON remote_asset_cloud_id_entity (cloud_id)" + } + ] + }, + { + "name": "idx_person_owner_id", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE INDEX IF NOT EXISTS idx_person_owner_id ON person_entity (owner_id)" + } + ] + }, + { + "name": "idx_asset_face_person_id", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE INDEX IF NOT EXISTS idx_asset_face_person_id ON asset_face_entity (person_id)" + } + ] + }, + { + "name": "idx_asset_face_asset_id", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE INDEX IF NOT EXISTS idx_asset_face_asset_id ON asset_face_entity (asset_id)" + } + ] + }, + { + "name": "idx_asset_face_visible_person", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE INDEX IF NOT EXISTS idx_asset_face_visible_person ON asset_face_entity (person_id, asset_id) WHERE is_visible = 1 AND deleted_at IS NULL" + } + ] + }, + { + "name": "idx_trashed_local_asset_checksum", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE INDEX IF NOT EXISTS idx_trashed_local_asset_checksum ON trashed_local_asset_entity (checksum)" + } + ] + }, + { + "name": "idx_trashed_local_asset_album", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE INDEX IF NOT EXISTS idx_trashed_local_asset_album ON trashed_local_asset_entity (album_id)" + } + ] + }, + { + "name": "idx_asset_edit_asset_id", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE INDEX IF NOT EXISTS idx_asset_edit_asset_id ON asset_edit_entity (asset_id)" + } + ] + } + ] +} \ No newline at end of file diff --git a/mobile/ios/Podfile.lock b/mobile/ios/Podfile.lock index c566d37182..5d966e0033 100644 --- a/mobile/ios/Podfile.lock +++ b/mobile/ios/Podfile.lock @@ -1,58 +1,23 @@ PODS: - - background_downloader (0.0.1): - - Flutter - bonsoir_darwin (0.0.1): - Flutter - FlutterMacOS - - connectivity_plus (0.0.1): - - Flutter - cupertino_http (0.0.1): - Flutter - FlutterMacOS - - device_info_plus (0.0.1): - - Flutter - Flutter (1.0.0) - flutter_local_notifications (0.0.1): - Flutter - - flutter_native_splash (2.4.3): - - Flutter - flutter_secure_storage (6.0.0): - Flutter - - flutter_udid (0.0.1): - - Flutter - - KeychainAccess - - flutter_web_auth_2 (5.0.0): - - Flutter - fluttertoast (0.0.2): - Flutter - - geolocator_apple (1.2.0): - - Flutter - - FlutterMacOS - home_widget (0.0.1): - Flutter - - image_picker_ios (0.0.1): - - Flutter - - integration_test (0.0.1): - - Flutter - - KeychainAccess (4.2.2) - - local_auth_darwin (0.0.1): - - Flutter - - FlutterMacOS - - MapLibre (6.14.0) - - maplibre_gl (0.0.1): - - Flutter - - MapLibre (= 6.14.0) - native_video_player (1.0.0): - Flutter - - network_info_plus (0.0.1): - - Flutter - - package_info_plus (0.4.5): - - Flutter - permission_handler_apple (9.3.0): - Flutter - - photo_manager (3.9.0): - - Flutter - - FlutterMacOS - share_handler_ios (0.0.14): - Flutter - share_handler_ios/share_handler_ios_models (= 0.0.14) @@ -61,144 +26,56 @@ PODS: - Flutter - share_handler_ios_models - share_handler_ios_models (0.0.9) - - share_plus (0.0.1): - - Flutter - - shared_preferences_foundation (0.0.1): - - Flutter - - FlutterMacOS - - url_launcher_ios (0.0.1): - - Flutter - - wakelock_plus (0.0.1): - - Flutter DEPENDENCIES: - - background_downloader (from `.symlinks/plugins/background_downloader/ios`) - bonsoir_darwin (from `.symlinks/plugins/bonsoir_darwin/darwin`) - - connectivity_plus (from `.symlinks/plugins/connectivity_plus/ios`) - cupertino_http (from `.symlinks/plugins/cupertino_http/darwin`) - - device_info_plus (from `.symlinks/plugins/device_info_plus/ios`) - Flutter (from `Flutter`) - flutter_local_notifications (from `.symlinks/plugins/flutter_local_notifications/ios`) - - flutter_native_splash (from `.symlinks/plugins/flutter_native_splash/ios`) - flutter_secure_storage (from `.symlinks/plugins/flutter_secure_storage/ios`) - - flutter_udid (from `.symlinks/plugins/flutter_udid/ios`) - - flutter_web_auth_2 (from `.symlinks/plugins/flutter_web_auth_2/ios`) - fluttertoast (from `.symlinks/plugins/fluttertoast/ios`) - - geolocator_apple (from `.symlinks/plugins/geolocator_apple/darwin`) - home_widget (from `.symlinks/plugins/home_widget/ios`) - - image_picker_ios (from `.symlinks/plugins/image_picker_ios/ios`) - - integration_test (from `.symlinks/plugins/integration_test/ios`) - - local_auth_darwin (from `.symlinks/plugins/local_auth_darwin/darwin`) - - maplibre_gl (from `.symlinks/plugins/maplibre_gl/ios`) - native_video_player (from `.symlinks/plugins/native_video_player/ios`) - - network_info_plus (from `.symlinks/plugins/network_info_plus/ios`) - - package_info_plus (from `.symlinks/plugins/package_info_plus/ios`) - permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`) - - photo_manager (from `.symlinks/plugins/photo_manager/darwin`) - share_handler_ios (from `.symlinks/plugins/share_handler_ios/ios`) - share_handler_ios_models (from `.symlinks/plugins/share_handler_ios/ios/Models`) - - share_plus (from `.symlinks/plugins/share_plus/ios`) - - shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`) - - url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`) - - wakelock_plus (from `.symlinks/plugins/wakelock_plus/ios`) - -SPEC REPOS: - trunk: - - KeychainAccess - - MapLibre EXTERNAL SOURCES: - background_downloader: - :path: ".symlinks/plugins/background_downloader/ios" bonsoir_darwin: :path: ".symlinks/plugins/bonsoir_darwin/darwin" - connectivity_plus: - :path: ".symlinks/plugins/connectivity_plus/ios" cupertino_http: :path: ".symlinks/plugins/cupertino_http/darwin" - device_info_plus: - :path: ".symlinks/plugins/device_info_plus/ios" Flutter: :path: Flutter flutter_local_notifications: :path: ".symlinks/plugins/flutter_local_notifications/ios" - flutter_native_splash: - :path: ".symlinks/plugins/flutter_native_splash/ios" flutter_secure_storage: :path: ".symlinks/plugins/flutter_secure_storage/ios" - flutter_udid: - :path: ".symlinks/plugins/flutter_udid/ios" - flutter_web_auth_2: - :path: ".symlinks/plugins/flutter_web_auth_2/ios" fluttertoast: :path: ".symlinks/plugins/fluttertoast/ios" - geolocator_apple: - :path: ".symlinks/plugins/geolocator_apple/darwin" home_widget: :path: ".symlinks/plugins/home_widget/ios" - image_picker_ios: - :path: ".symlinks/plugins/image_picker_ios/ios" - integration_test: - :path: ".symlinks/plugins/integration_test/ios" - local_auth_darwin: - :path: ".symlinks/plugins/local_auth_darwin/darwin" - maplibre_gl: - :path: ".symlinks/plugins/maplibre_gl/ios" native_video_player: :path: ".symlinks/plugins/native_video_player/ios" - network_info_plus: - :path: ".symlinks/plugins/network_info_plus/ios" - package_info_plus: - :path: ".symlinks/plugins/package_info_plus/ios" permission_handler_apple: :path: ".symlinks/plugins/permission_handler_apple/ios" - photo_manager: - :path: ".symlinks/plugins/photo_manager/darwin" share_handler_ios: :path: ".symlinks/plugins/share_handler_ios/ios" share_handler_ios_models: :path: ".symlinks/plugins/share_handler_ios/ios/Models" - share_plus: - :path: ".symlinks/plugins/share_plus/ios" - shared_preferences_foundation: - :path: ".symlinks/plugins/shared_preferences_foundation/darwin" - url_launcher_ios: - :path: ".symlinks/plugins/url_launcher_ios/ios" - wakelock_plus: - :path: ".symlinks/plugins/wakelock_plus/ios" SPEC CHECKSUMS: - background_downloader: 50e91d979067b82081aba359d7d916b3ba5fadad bonsoir_darwin: 29c7ccf356646118844721f36e1de4b61f6cbd0e - connectivity_plus: cb623214f4e1f6ef8fe7403d580fdad517d2f7dd cupertino_http: 94ac07f5ff090b8effa6c5e2c47871d48ab7c86c - device_info_plus: 21fcca2080fbcd348be798aa36c3e5ed849eefbe Flutter: cabc95a1d2626b1b06e7179b784ebcf0c0cde467 flutter_local_notifications: ad39620c743ea4c15127860f4b5641649a988100 - flutter_native_splash: c32d145d68aeda5502d5f543ee38c192065986cf flutter_secure_storage: 1ed9476fba7e7a782b22888f956cce43e2c62f13 - flutter_udid: 92a5d31fe0526b7b6002a2318df702e12e7eb300 - flutter_web_auth_2: 646fc9df97a01c59e5eea99b237da2c6360f8439 fluttertoast: 2c67e14dce98bbdb200df9e1acf610d7a6264ea1 - geolocator_apple: ab36aa0e8b7d7a2d7639b3b4e48308394e8cef5e home_widget: f169fc41fd807b4d46ab6615dc44d62adbf9f64f - image_picker_ios: e0ece4aa2a75771a7de3fa735d26d90817041326 - integration_test: 4a889634ef21a45d28d50d622cf412dc6d9f586e - KeychainAccess: c0c4f7f38f6fc7bbe58f5702e25f7bd2f65abf51 - local_auth_darwin: c3ee6cce0a8d56be34c8ccb66ba31f7f180aaebb - MapLibre: 69e572367f4ef6287e18246cfafc39c80cdcabcd - maplibre_gl: 3c924e44725147b03dda33430ad216005b40555f native_video_player: b65c58951ede2f93d103a25366bdebca95081265 - network_info_plus: cf61925ab5205dce05a4f0895989afdb6aade5fc - package_info_plus: af8e2ca6888548050f16fa2f1938db7b5a5df499 permission_handler_apple: 4ed2196e43d0651e8ff7ca3483a069d469701f2d - photo_manager: 25fd77df14f4f0ba5ef99e2c61814dde77e2bceb share_handler_ios: e2244e990f826b2c8eaa291ac3831569438ba0fb share_handler_ios_models: fc638c9b4330dc7f082586c92aee9dfa0b87b871 - share_plus: 50da8cb520a8f0f65671c6c6a99b3617ed10a58a - shared_preferences_foundation: 7036424c3d8ec98dfe75ff1667cb0cd531ec82bb - url_launcher_ios: 7a95fa5b60cc718a708b8f2966718e93db0cef1b - wakelock_plus: e29112ab3ef0b318e58cfa5c32326458be66b556 PODFILE CHECKSUM: 938abbae4114b9c2140c550a2a0d8f7c674f5dfe diff --git a/mobile/ios/Runner.xcodeproj/project.pbxproj b/mobile/ios/Runner.xcodeproj/project.pbxproj index fbffa69ba5..42926ef45e 100644 --- a/mobile/ios/Runner.xcodeproj/project.pbxproj +++ b/mobile/ios/Runner.xcodeproj/project.pbxproj @@ -9,7 +9,7 @@ /* Begin PBXBuildFile section */ 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; - 3B6A31FED0FC846D6BD69BBC /* Pods_ShareExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 357FC57E54FD0F51795CF28A /* Pods_ShareExtension.framework */; }; + 467DA6EAF83F3481F8BD94AB /* Pods_ShareExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8AB817AA297EDEC88B23F3F6 /* Pods_ShareExtension.framework */; }; 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; @@ -19,8 +19,10 @@ B21E34AC2E5B09190031FDB9 /* BackgroundWorker.swift in Sources */ = {isa = PBXBuildFile; fileRef = B21E34AB2E5B09100031FDB9 /* BackgroundWorker.swift */; }; B25D377A2E72CA15008B6CA7 /* Connectivity.g.swift in Sources */ = {isa = PBXBuildFile; fileRef = B25D37782E72CA15008B6CA7 /* Connectivity.g.swift */; }; B25D377C2E72CA26008B6CA7 /* ConnectivityApiImpl.swift in Sources */ = {isa = PBXBuildFile; fileRef = B25D377B2E72CA20008B6CA7 /* ConnectivityApiImpl.swift */; }; + B2EE00022E72CA15008B6CA7 /* PermissionApi.g.swift in Sources */ = {isa = PBXBuildFile; fileRef = B2EE00012E72CA15008B6CA7 /* PermissionApi.g.swift */; }; + B2EE00042E72CA15008B6CA7 /* PermissionApiImpl.swift in Sources */ = {isa = PBXBuildFile; fileRef = B2EE00032E72CA15008B6CA7 /* PermissionApiImpl.swift */; }; B2BE315F2E5E5229006EEF88 /* BackgroundWorker.g.swift in Sources */ = {isa = PBXBuildFile; fileRef = B2BE315E2E5E5229006EEF88 /* BackgroundWorker.g.swift */; }; - D218389C4A4C4693F141F7D1 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 886774DBDDE6B35BF2B4F2CD /* Pods_Runner.framework */; }; + D3BED739C0BC29BB32E18EB2 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CC499FBCE6B29B2DAFED7130 /* Pods_Runner.framework */; }; F02538E92DFBCBDD008C3FA3 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; F0B57D3A2DF764BD00DC5BCC /* WidgetKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F0B57D392DF764BD00DC5BCC /* WidgetKit.framework */; }; F0B57D3C2DF764BD00DC5BCC /* SwiftUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F0B57D3B2DF764BD00DC5BCC /* SwiftUI.framework */; }; @@ -37,6 +39,7 @@ FEE084F82EC172460045228E /* SQLiteData in Frameworks */ = {isa = PBXBuildFile; productRef = FEE084F72EC172460045228E /* SQLiteData */; }; FEE084FB2EC1725A0045228E /* RawStructuredFieldValues in Frameworks */ = {isa = PBXBuildFile; productRef = FEE084FA2EC1725A0045228E /* RawStructuredFieldValues */; }; FEE084FD2EC1725A0045228E /* StructuredFieldValues in Frameworks */ = {isa = PBXBuildFile; productRef = FEE084FC2EC1725A0045228E /* StructuredFieldValues */; }; + 78A318202AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage in Frameworks */ = {isa = PBXBuildFile; productRef = 78A3181F2AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -82,16 +85,18 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 10B378D23F917891A0F23E33 /* Pods-ShareExtension.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ShareExtension.release.xcconfig"; path = "Target Support Files/Pods-ShareExtension/Pods-ShareExtension.release.xcconfig"; sourceTree = ""; }; 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; - 2E3441B73560D0F6FD25E04F /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; - 357FC57E54FD0F51795CF28A /* Pods_ShareExtension.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_ShareExtension.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; - 571EAA93D77181C7C98C2EA6 /* Pods-ShareExtension.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ShareExtension.release.xcconfig"; path = "Target Support Files/Pods-ShareExtension/Pods-ShareExtension.release.xcconfig"; sourceTree = ""; }; + 614A7F5DC5DB09E89E4FCBE8 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; + 681FBA560D5D2ADDE4F0B59E /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; + 6D160F04A389B9FFBC557803 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; - 886774DBDDE6B35BF2B4F2CD /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 8AB817AA297EDEC88B23F3F6 /* Pods_ShareExtension.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_ShareExtension.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 937632897A02DE9C249F20A6 /* Pods-ShareExtension.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ShareExtension.debug.xcconfig"; path = "Target Support Files/Pods-ShareExtension/Pods-ShareExtension.debug.xcconfig"; sourceTree = ""; }; 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; 97C146EE1CF9000F007C117D /* Immich-Debug.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Immich-Debug.app"; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -100,18 +105,18 @@ 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; A01DD6982F7F43B40049AB63 /* ImageRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageRequest.swift; sourceTree = ""; }; - B1FBA9EE014DE20271B0FE77 /* Pods-ShareExtension.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ShareExtension.profile.xcconfig"; path = "Target Support Files/Pods-ShareExtension/Pods-ShareExtension.profile.xcconfig"; sourceTree = ""; }; B21E34A92E5AFD210031FDB9 /* BackgroundWorkerApiImpl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BackgroundWorkerApiImpl.swift; sourceTree = ""; }; B21E34AB2E5B09100031FDB9 /* BackgroundWorker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BackgroundWorker.swift; sourceTree = ""; }; B25D37782E72CA15008B6CA7 /* Connectivity.g.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Connectivity.g.swift; sourceTree = ""; }; B25D377B2E72CA20008B6CA7 /* ConnectivityApiImpl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConnectivityApiImpl.swift; sourceTree = ""; }; + B2EE00012E72CA15008B6CA7 /* PermissionApi.g.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PermissionApi.g.swift; sourceTree = ""; }; + B2EE00032E72CA15008B6CA7 /* PermissionApiImpl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PermissionApiImpl.swift; sourceTree = ""; }; B2BE315E2E5E5229006EEF88 /* BackgroundWorker.g.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BackgroundWorker.g.swift; sourceTree = ""; }; - E0E99CDC17B3EB7FA8BA2332 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; + C4A6A71F33CE37B3C913115C /* Pods-ShareExtension.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ShareExtension.profile.xcconfig"; path = "Target Support Files/Pods-ShareExtension/Pods-ShareExtension.profile.xcconfig"; sourceTree = ""; }; + CC499FBCE6B29B2DAFED7130 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; F0B57D382DF764BD00DC5BCC /* WidgetExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = WidgetExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; }; F0B57D392DF764BD00DC5BCC /* WidgetKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WidgetKit.framework; path = System/Library/Frameworks/WidgetKit.framework; sourceTree = SDKROOT; }; F0B57D3B2DF764BD00DC5BCC /* SwiftUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SwiftUI.framework; path = System/Library/Frameworks/SwiftUI.framework; sourceTree = SDKROOT; }; - F7101BB0391A314774615E89 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; - F8A35EA3C3E01BD66AFDE0E5 /* Pods-ShareExtension.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ShareExtension.debug.xcconfig"; path = "Target Support Files/Pods-ShareExtension/Pods-ShareExtension.debug.xcconfig"; sourceTree = ""; }; FA9973382CF6DF4B000EF859 /* Runner.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Runner.entitlements; sourceTree = ""; }; FAC6F8902D287C890078CB2F /* ShareExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = ShareExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; }; FAC6F8B12D287F120078CB2F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; @@ -125,6 +130,7 @@ FE5499F72F1198DE006016CB /* RemoteImagesImpl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RemoteImagesImpl.swift; sourceTree = ""; }; FE5FE4AD2F30FBC000A71243 /* ImageProcessing.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageProcessing.swift; sourceTree = ""; }; FEAFA8722E4D42F4001E47FE /* Thumbhash.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Thumbhash.swift; sourceTree = ""; }; + 78E0A7A72DC9AD7400C4905E /* FlutterGeneratedPluginSwiftPackage */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = FlutterGeneratedPluginSwiftPackage; path = Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */ @@ -189,10 +195,11 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 78A318202AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage in Frameworks */, FEE084F82EC172460045228E /* SQLiteData in Frameworks */, FEE084FB2EC1725A0045228E /* RawStructuredFieldValues in Frameworks */, FEE084FD2EC1725A0045228E /* StructuredFieldValues in Frameworks */, - D218389C4A4C4693F141F7D1 /* Pods_Runner.framework in Frameworks */, + D3BED739C0BC29BB32E18EB2 /* Pods_Runner.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -209,7 +216,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 3B6A31FED0FC846D6BD69BBC /* Pods_ShareExtension.framework in Frameworks */, + 467DA6EAF83F3481F8BD94AB /* Pods_ShareExtension.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -219,12 +226,12 @@ 0FB772A5B9601143383626CA /* Pods */ = { isa = PBXGroup; children = ( - 2E3441B73560D0F6FD25E04F /* Pods-Runner.debug.xcconfig */, - E0E99CDC17B3EB7FA8BA2332 /* Pods-Runner.release.xcconfig */, - F7101BB0391A314774615E89 /* Pods-Runner.profile.xcconfig */, - F8A35EA3C3E01BD66AFDE0E5 /* Pods-ShareExtension.debug.xcconfig */, - 571EAA93D77181C7C98C2EA6 /* Pods-ShareExtension.release.xcconfig */, - B1FBA9EE014DE20271B0FE77 /* Pods-ShareExtension.profile.xcconfig */, + 614A7F5DC5DB09E89E4FCBE8 /* Pods-Runner.debug.xcconfig */, + 6D160F04A389B9FFBC557803 /* Pods-Runner.release.xcconfig */, + 681FBA560D5D2ADDE4F0B59E /* Pods-Runner.profile.xcconfig */, + 937632897A02DE9C249F20A6 /* Pods-ShareExtension.debug.xcconfig */, + 10B378D23F917891A0F23E33 /* Pods-ShareExtension.release.xcconfig */, + C4A6A71F33CE37B3C913115C /* Pods-ShareExtension.profile.xcconfig */, ); path = Pods; sourceTree = ""; @@ -232,10 +239,10 @@ 1754452DD81DA6620E279E51 /* Frameworks */ = { isa = PBXGroup; children = ( - 886774DBDDE6B35BF2B4F2CD /* Pods_Runner.framework */, - 357FC57E54FD0F51795CF28A /* Pods_ShareExtension.framework */, F0B57D392DF764BD00DC5BCC /* WidgetKit.framework */, F0B57D3B2DF764BD00DC5BCC /* SwiftUI.framework */, + CC499FBCE6B29B2DAFED7130 /* Pods_Runner.framework */, + 8AB817AA297EDEC88B23F3F6 /* Pods_ShareExtension.framework */, ); name = Frameworks; sourceTree = ""; @@ -243,6 +250,7 @@ 9740EEB11CF90186004384FC /* Flutter */ = { isa = PBXGroup; children = ( + 78E0A7A72DC9AD7400C4905E /* FlutterGeneratedPluginSwiftPackage */, 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, 9740EEB21CF90195004384FC /* Debug.xcconfig */, 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, @@ -283,6 +291,7 @@ B25D37792E72CA15008B6CA7 /* Connectivity */, B21E34A62E5AF9760031FDB9 /* Background */, B2CF7F8C2DDE4EBB00744BF6 /* Sync */, + B2EE00052E72CA15008B6CA7 /* Permission */, FA9973382CF6DF4B000EF859 /* Runner.entitlements */, FAC7416727DB9F5500C668D8 /* RunnerProfile.entitlements */, 97C146FA1CF9000F007C117D /* Main.storyboard */, @@ -317,6 +326,15 @@ path = Connectivity; sourceTree = ""; }; + B2EE00052E72CA15008B6CA7 /* Permission */ = { + isa = PBXGroup; + children = ( + B2EE00032E72CA15008B6CA7 /* PermissionApiImpl.swift */, + B2EE00012E72CA15008B6CA7 /* PermissionApi.g.swift */, + ); + path = Permission; + sourceTree = ""; + }; FAC6F8B62D287F120078CB2F /* ShareExtension */ = { isa = PBXGroup; children = ( @@ -346,10 +364,13 @@ /* Begin PBXNativeTarget section */ 97C146ED1CF9000F007C117D /* Runner */ = { + packageProductDependencies = ( + 78A3181F2AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage */, + ); isa = PBXNativeTarget; buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; buildPhases = ( - 4044AF030EF7D8721844FFBA /* [CP] Check Pods Manifest.lock */, + BAEA01ACA3F5C9CD3D732370 /* [CP] Check Pods Manifest.lock */, 9740EEB61CF901F6004384FC /* Run Script */, 97C146EA1CF9000F007C117D /* Sources */, 97C146EB1CF9000F007C117D /* Frameworks */, @@ -357,8 +378,8 @@ 9705A1C41CF9048500538489 /* Embed Frameworks */, FAC6F89A2D287C890078CB2F /* Embed Foundation Extensions */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, - D218A34AEE62BC1EF119F5B0 /* [CP] Embed Pods Frameworks */, - 6724EEB7D74949FA08581154 /* [CP] Copy Pods Resources */, + 513DA7292DED6106813332F4 /* [CP] Embed Pods Frameworks */, + 2FA39DEC809D6D7C4A01EFCB /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -372,6 +393,9 @@ FEE084F22EC172080045228E /* Schemas */, ); name = Runner; + packageProductDependencies = ( + 78A3181F2AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage */, + ); productName = Runner; productReference = 97C146EE1CF9000F007C117D /* Immich-Debug.app */; productType = "com.apple.product-type.application"; @@ -400,7 +424,7 @@ isa = PBXNativeTarget; buildConfigurationList = FAC6F8A02D287C890078CB2F /* Build configuration list for PBXNativeTarget "ShareExtension" */; buildPhases = ( - 3BEF3D71D97E337D921C0EB5 /* [CP] Check Pods Manifest.lock */, + 8EC9CF3E20AF32BF24D4F3E1 /* [CP] Check Pods Manifest.lock */, FAC6F88C2D287C890078CB2F /* Sources */, FAC6F88D2D287C890078CB2F /* Frameworks */, FAC6F88E2D287C890078CB2F /* Resources */, @@ -449,6 +473,7 @@ ); mainGroup = 97C146E51CF9000F007C117D; packageReferences = ( + 781AD8BC2B33823900A9FFBB /* XCLocalSwiftPackageReference "FlutterGeneratedPluginSwiftPackage" */, FEE084F62EC172460045228E /* XCRemoteSwiftPackageReference "sqlite-data" */, FEE084F92EC1725A0045228E /* XCRemoteSwiftPackageReference "swift-http-structured-headers" */, ); @@ -495,6 +520,23 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ + 2FA39DEC809D6D7C4A01EFCB /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Copy Pods Resources"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { isa = PBXShellScriptBuildPhase; alwaysOutOfDate = 1; @@ -511,7 +553,24 @@ shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; }; - 3BEF3D71D97E337D921C0EB5 /* [CP] Check Pods Manifest.lock */ = { + 513DA7292DED6106813332F4 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + 8EC9CF3E20AF32BF24D4F3E1 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -533,7 +592,22 @@ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - 4044AF030EF7D8721844FFBA /* [CP] Check Pods Manifest.lock */ = { + 9740EEB61CF901F6004384FC /* Run Script */ = { + isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Run Script"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build\n"; + }; + BAEA01ACA3F5C9CD3D732370 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -555,55 +629,6 @@ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - 6724EEB7D74949FA08581154 /* [CP] Copy Pods Resources */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist", - ); - name = "[CP] Copy Pods Resources"; - outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n"; - showEnvVarsInLog = 0; - }; - 9740EEB61CF901F6004384FC /* Run Script */ = { - isa = PBXShellScriptBuildPhase; - alwaysOutOfDate = 1; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "Run Script"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build\n"; - }; - D218A34AEE62BC1EF119F5B0 /* [CP] Embed Pods Frameworks */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", - ); - name = "[CP] Embed Pods Frameworks"; - outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; - showEnvVarsInLog = 0; - }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -619,6 +644,8 @@ FE5499F42F1197D8006016CB /* RemoteImages.g.swift in Sources */, FE5FE4AE2F30FBC000A71243 /* ImageProcessing.swift in Sources */, B25D377A2E72CA15008B6CA7 /* Connectivity.g.swift in Sources */, + B2EE00022E72CA15008B6CA7 /* PermissionApi.g.swift in Sources */, + B2EE00042E72CA15008B6CA7 /* PermissionApiImpl.swift in Sources */, FE5499F82F1198E2006016CB /* RemoteImagesImpl.swift in Sources */, FEAFA8732E4D42F4001E47FE /* Thumbhash.swift in Sources */, B25D377C2E72CA26008B6CA7 /* ConnectivityApiImpl.swift in Sources */, @@ -718,6 +745,7 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; + CUSTOM_GROUP_ID = group.app.immich.share.profile; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; @@ -750,7 +778,6 @@ CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 240; - CUSTOM_GROUP_ID = group.app.immich.share; DEVELOPMENT_TEAM = 2W7AC6T8T5; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; @@ -801,6 +828,7 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; + CUSTOM_GROUP_ID = group.app.immich.share.debug; DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; @@ -860,6 +888,7 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; + CUSTOM_GROUP_ID = group.app.immich.share; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; @@ -894,7 +923,6 @@ CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 240; - CUSTOM_GROUP_ID = group.app.immich.share; DEVELOPMENT_TEAM = 2W7AC6T8T5; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; @@ -924,7 +952,6 @@ CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 240; - CUSTOM_GROUP_ID = group.app.immich.share; DEVELOPMENT_TEAM = 2W7AC6T8T5; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; @@ -1068,7 +1095,7 @@ }; FAC6F89C2D287C890078CB2F /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = F8A35EA3C3E01BD66AFDE0E5 /* Pods-ShareExtension.debug.xcconfig */; + baseConfigurationReference = 937632897A02DE9C249F20A6 /* Pods-ShareExtension.debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; @@ -1080,7 +1107,6 @@ CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 240; - CUSTOM_GROUP_ID = group.app.immich.share; DEVELOPMENT_TEAM = 2W7AC6T8T5; ENABLE_USER_SCRIPT_SANDBOXING = YES; GCC_C_LANGUAGE_STANDARD = gnu17; @@ -1112,7 +1138,7 @@ }; FAC6F89D2D287C890078CB2F /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 571EAA93D77181C7C98C2EA6 /* Pods-ShareExtension.release.xcconfig */; + baseConfigurationReference = 10B378D23F917891A0F23E33 /* Pods-ShareExtension.release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; @@ -1124,7 +1150,6 @@ CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 240; - CUSTOM_GROUP_ID = group.app.immich.share; DEVELOPMENT_TEAM = 2W7AC6T8T5; ENABLE_USER_SCRIPT_SANDBOXING = YES; GCC_C_LANGUAGE_STANDARD = gnu17; @@ -1153,7 +1178,7 @@ }; FAC6F89E2D287C890078CB2F /* Profile */ = { isa = XCBuildConfiguration; - baseConfigurationReference = B1FBA9EE014DE20271B0FE77 /* Pods-ShareExtension.profile.xcconfig */; + baseConfigurationReference = C4A6A71F33CE37B3C913115C /* Pods-ShareExtension.profile.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; @@ -1165,7 +1190,6 @@ CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 240; - CUSTOM_GROUP_ID = group.app.immich.share; DEVELOPMENT_TEAM = 2W7AC6T8T5; ENABLE_USER_SCRIPT_SANDBOXING = YES; GCC_C_LANGUAGE_STANDARD = gnu17; @@ -1237,6 +1261,13 @@ }; /* End XCConfigurationList section */ +/* Begin XCLocalSwiftPackageReference section */ + 781AD8BC2B33823900A9FFBB /* XCLocalSwiftPackageReference "FlutterGeneratedPluginSwiftPackage" */ = { + isa = XCLocalSwiftPackageReference; + relativePath = Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage; + }; +/* End XCLocalSwiftPackageReference section */ + /* Begin XCRemoteSwiftPackageReference section */ FEE084F62EC172460045228E /* XCRemoteSwiftPackageReference "sqlite-data" */ = { isa = XCRemoteSwiftPackageReference; @@ -1257,6 +1288,10 @@ /* End XCRemoteSwiftPackageReference section */ /* Begin XCSwiftPackageProductDependency section */ + 78A3181F2AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage */ = { + isa = XCSwiftPackageProductDependency; + productName = FlutterGeneratedPluginSwiftPackage; + }; FEE084F72EC172460045228E /* SQLiteData */ = { isa = XCSwiftPackageProductDependency; package = FEE084F62EC172460045228E /* XCRemoteSwiftPackageReference "sqlite-data" */; @@ -1272,7 +1307,17 @@ package = FEE084F92EC1725A0045228E /* XCRemoteSwiftPackageReference "swift-http-structured-headers" */; productName = StructuredFieldValues; }; + 78A3181F2AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage */ = { + isa = XCSwiftPackageProductDependency; + productName = FlutterGeneratedPluginSwiftPackage; + }; /* End XCSwiftPackageProductDependency section */ +/* Begin XCLocalSwiftPackageReference section */ + 781AD8BC2B33823900A9FFBB /* XCLocalSwiftPackageReference "Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage" */ = { + isa = XCLocalSwiftPackageReference; + relativePath = Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage; + }; +/* End XCLocalSwiftPackageReference section */ }; rootObject = 97C146E61CF9000F007C117D /* Project object */; } diff --git a/mobile/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/mobile/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 187a67cb27..a9381e541a 100644 --- a/mobile/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/mobile/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -1,5 +1,4 @@ { - "originHash" : "9be33bfaa68721646604aefff3cabbdaf9a193da192aae024c265065671f6c49", "pins" : [ { "identity" : "combine-schedulers", @@ -19,6 +18,24 @@ "version" : "7.8.0" } }, + { + "identity" : "keychainaccess", + "kind" : "remoteSourceControl", + "location" : "https://github.com/kishikawakatsumi/KeychainAccess", + "state" : { + "revision" : "84e546727d66f1adc5439debad16270d0fdd04e7", + "version" : "4.2.2" + } + }, + { + "identity" : "maplibre-gl-native-distribution", + "kind" : "remoteSourceControl", + "location" : "https://github.com/maplibre/maplibre-gl-native-distribution.git", + "state" : { + "revision" : "60d9bb85c94ce6e7fc4406cd32529fd12bdb7809", + "version" : "6.14.0" + } + }, { "identity" : "sqlite-data", "kind" : "remoteSourceControl", @@ -146,5 +163,5 @@ } } ], - "version" : 3 + "version" : 2 } diff --git a/mobile/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/mobile/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index 2367c52b97..f8dd8b0b9f 100644 --- a/mobile/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/mobile/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -5,6 +5,24 @@ + + + + + + + + + + Bool func getClientPointer() throws -> Int64 func setRequestHeaders(headers: [String: String], serverUrls: [String], token: String?) throws + func getAppGroupId() throws -> String } /// Generated setup class from Pigeon to handle messages through the `binaryMessenger`. @@ -388,5 +389,18 @@ class NetworkApiSetup { } else { setRequestHeadersChannel.setMessageHandler(nil) } + let getAppGroupIdChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.immich_mobile.NetworkApi.getAppGroupId\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + getAppGroupIdChannel.setMessageHandler { _, reply in + do { + let result = try api.getAppGroupId() + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) + } + } + } else { + getAppGroupIdChannel.setMessageHandler(nil) + } } } diff --git a/mobile/ios/Runner/Core/NetworkApiImpl.swift b/mobile/ios/Runner/Core/NetworkApiImpl.swift index 82a913d837..288b8e9539 100644 --- a/mobile/ios/Runner/Core/NetworkApiImpl.swift +++ b/mobile/ios/Runner/Core/NetworkApiImpl.swift @@ -61,6 +61,10 @@ class NetworkApiImpl: NetworkApi { return Int64(Int(bitPattern: pointer)) } + func getAppGroupId() throws -> String { + return Bundle.main.object(forInfoDictionaryKey: "AppGroupId") as! String + } + func setRequestHeaders(headers: [String : String], serverUrls: [String], token: String?) throws { URLSessionManager.setServerUrls(serverUrls) diff --git a/mobile/ios/Runner/Core/URLSessionManager.swift b/mobile/ios/Runner/Core/URLSessionManager.swift index e9d65d3113..48963aa577 100644 --- a/mobile/ios/Runner/Core/URLSessionManager.swift +++ b/mobile/ios/Runner/Core/URLSessionManager.swift @@ -4,7 +4,7 @@ import native_video_player let CLIENT_CERT_LABEL = "app.alextran.immich.client_identity" let HEADERS_KEY = "immich.request_headers" let SERVER_URLS_KEY = "immich.server_urls" -let APP_GROUP = "group.app.immich.share" +let APP_GROUP = Bundle.main.object(forInfoDictionaryKey: "AppGroupId") as! String let COOKIE_EXPIRY_DAYS: TimeInterval = 400 enum AuthCookie: CaseIterable { diff --git a/mobile/ios/Runner/Permission/PermissionApi.g.swift b/mobile/ios/Runner/Permission/PermissionApi.g.swift new file mode 100644 index 0000000000..53ad9e5b11 --- /dev/null +++ b/mobile/ios/Runner/Permission/PermissionApi.g.swift @@ -0,0 +1,106 @@ +// Autogenerated from Pigeon (v26.3.4), do not edit directly. +// See also: https://pub.dev/packages/pigeon + +import Foundation + +#if os(iOS) + import Flutter +#elseif os(macOS) + import FlutterMacOS +#else + #error("Unsupported platform.") +#endif + +private func wrapResult(_ result: Any?) -> [Any?] { + return [result] +} + +private func wrapError(_ error: Any) -> [Any?] { + if let pigeonError = error as? PigeonError { + return [ + pigeonError.code, + pigeonError.message, + pigeonError.details, + ] + } + if let flutterError = error as? FlutterError { + return [ + flutterError.code, + flutterError.message, + flutterError.details, + ] + } + return [ + "\(error)", + "\(Swift.type(of: error))", + "Stacktrace: \(Thread.callStackSymbols)", + ] +} + +private func isNullish(_ value: Any?) -> Bool { + return value is NSNull || value == nil +} + +private func nilOrValue(_ value: Any?) -> T? { + if value is NSNull { return nil } + return value as! T? +} + +/// Generated protocol from Pigeon that represents a handler of messages from Flutter. +protocol PermissionApi { + func hasManageMediaPermission() throws -> Bool + func requestManageMediaPermission(completion: @escaping (Result) -> Void) + func manageMediaPermission(completion: @escaping (Result) -> Void) +} + +/// Generated setup class from Pigeon to handle messages through the `binaryMessenger`. +class PermissionApiSetup { + static var codec: FlutterStandardMessageCodec { FlutterStandardMessageCodec.sharedInstance() } + /// Sets up an instance of `PermissionApi` to handle messages through the `binaryMessenger`. + static func setUp(binaryMessenger: FlutterBinaryMessenger, api: PermissionApi?, messageChannelSuffix: String = "") { + let channelSuffix = messageChannelSuffix.count > 0 ? ".\(messageChannelSuffix)" : "" + let hasManageMediaPermissionChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.immich_mobile.PermissionApi.hasManageMediaPermission\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + hasManageMediaPermissionChannel.setMessageHandler { _, reply in + do { + let result = try api.hasManageMediaPermission() + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) + } + } + } else { + hasManageMediaPermissionChannel.setMessageHandler(nil) + } + let requestManageMediaPermissionChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.immich_mobile.PermissionApi.requestManageMediaPermission\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + requestManageMediaPermissionChannel.setMessageHandler { _, reply in + api.requestManageMediaPermission { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + requestManageMediaPermissionChannel.setMessageHandler(nil) + } + let manageMediaPermissionChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.immich_mobile.PermissionApi.manageMediaPermission\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + manageMediaPermissionChannel.setMessageHandler { _, reply in + api.manageMediaPermission { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + manageMediaPermissionChannel.setMessageHandler(nil) + } + } +} diff --git a/mobile/ios/Runner/Permission/PermissionApiImpl.swift b/mobile/ios/Runner/Permission/PermissionApiImpl.swift new file mode 100644 index 0000000000..e725b742fd --- /dev/null +++ b/mobile/ios/Runner/Permission/PermissionApiImpl.swift @@ -0,0 +1,15 @@ +import Foundation + +class PermissionApiImpl: PermissionApi { + func hasManageMediaPermission() throws -> Bool { + return false + } + + func requestManageMediaPermission(completion: @escaping (Result) -> Void) { + completion(.success(false)) + } + + func manageMediaPermission(completion: @escaping (Result) -> Void) { + completion(.success(false)) + } +} diff --git a/mobile/ios/Runner/Runner.entitlements b/mobile/ios/Runner/Runner.entitlements index e5862cb213..c8a6be9cbb 100644 --- a/mobile/ios/Runner/Runner.entitlements +++ b/mobile/ios/Runner/Runner.entitlements @@ -10,7 +10,7 @@ com.apple.security.application-groups - group.app.immich.share + $(CUSTOM_GROUP_ID) diff --git a/mobile/ios/Runner/RunnerProfile.entitlements b/mobile/ios/Runner/RunnerProfile.entitlements index 6a5c086baf..93a4aab552 100644 --- a/mobile/ios/Runner/RunnerProfile.entitlements +++ b/mobile/ios/Runner/RunnerProfile.entitlements @@ -12,7 +12,7 @@ com.apple.security.application-groups - group.app.immich.share + $(CUSTOM_GROUP_ID) diff --git a/mobile/ios/Runner/Sync/Messages.g.swift b/mobile/ios/Runner/Sync/Messages.g.swift index 2933fc89af..d18a153bb7 100644 --- a/mobile/ios/Runner/Sync/Messages.g.swift +++ b/mobile/ios/Runner/Sync/Messages.g.swift @@ -537,6 +537,7 @@ protocol NativeSyncApi { func hashAssets(assetIds: [String], allowNetworkAccess: Bool, completion: @escaping (Result<[HashResult], Error>) -> Void) func cancelHashing() throws func getTrashedAssets() throws -> [String: [PlatformAsset]] + func restoreFromTrashById(mediaId: String, type: Int64, completion: @escaping (Result) -> Void) func getCloudIdForAssetIds(assetIds: [String]) throws -> [CloudIdResult] } @@ -721,6 +722,24 @@ class NativeSyncApiSetup { } else { getTrashedAssetsChannel.setMessageHandler(nil) } + let restoreFromTrashByIdChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.immich_mobile.NativeSyncApi.restoreFromTrashById\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + restoreFromTrashByIdChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let mediaIdArg = args[0] as! String + let typeArg = args[1] as! Int64 + api.restoreFromTrashById(mediaId: mediaIdArg, type: typeArg) { result in + switch result { + case .success(let res): + reply(wrapResult(res)) + case .failure(let error): + reply(wrapError(error)) + } + } + } + } else { + restoreFromTrashByIdChannel.setMessageHandler(nil) + } let getCloudIdForAssetIdsChannel = taskQueue == nil ? FlutterBasicMessageChannel(name: "dev.flutter.pigeon.immich_mobile.NativeSyncApi.getCloudIdForAssetIds\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) : FlutterBasicMessageChannel(name: "dev.flutter.pigeon.immich_mobile.NativeSyncApi.getCloudIdForAssetIds\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec, taskQueue: taskQueue) diff --git a/mobile/ios/Runner/Sync/MessagesImpl.swift b/mobile/ios/Runner/Sync/MessagesImpl.swift index 40b71bd6c2..e6903defeb 100644 --- a/mobile/ios/Runner/Sync/MessagesImpl.swift +++ b/mobile/ios/Runner/Sync/MessagesImpl.swift @@ -382,6 +382,10 @@ class NativeSyncApiImpl: ImmichPlugin, NativeSyncApi, FlutterPlugin { func getTrashedAssets() throws -> [String: [PlatformAsset]] { throw PigeonError(code: "UNSUPPORTED_OS", message: "This feature not supported on iOS.", details: nil) } + + func restoreFromTrashById(mediaId: String, type: Int64, completion: @escaping (Result) -> Void) { + completion(.success(false)) + } private func getAssetsFromAlbum(in album: PHAssetCollection, options: PHFetchOptions) -> PHFetchResult { // Ensure to actually getting all assets for the Recents album diff --git a/mobile/ios/ShareExtension/ShareExtension.entitlements b/mobile/ios/ShareExtension/ShareExtension.entitlements index d16dcca065..1328658832 100644 --- a/mobile/ios/ShareExtension/ShareExtension.entitlements +++ b/mobile/ios/ShareExtension/ShareExtension.entitlements @@ -4,7 +4,7 @@ com.apple.security.application-groups - group.app.immich.share + $(CUSTOM_GROUP_ID) \ No newline at end of file diff --git a/mobile/ios/WidgetExtension/ImmichAPI.swift b/mobile/ios/WidgetExtension/ImmichAPI.swift index 6ae2d502f8..c5d7971aba 100644 --- a/mobile/ios/WidgetExtension/ImmichAPI.swift +++ b/mobile/ios/WidgetExtension/ImmichAPI.swift @@ -2,7 +2,7 @@ import Foundation import SwiftUI import WidgetKit -let IMMICH_SHARE_GROUP = "group.app.immich.share" +let IMMICH_SHARE_GROUP = Bundle.main.object(forInfoDictionaryKey: "AppGroupId") as! String enum WidgetError: Error, Codable { case noLogin diff --git a/mobile/ios/WidgetExtension/Info.plist b/mobile/ios/WidgetExtension/Info.plist index d4e598ee31..15b00baa20 100644 --- a/mobile/ios/WidgetExtension/Info.plist +++ b/mobile/ios/WidgetExtension/Info.plist @@ -2,6 +2,8 @@ + AppGroupId + $(CUSTOM_GROUP_ID) NSAppTransportSecurity NSAllowsArbitraryLoads diff --git a/mobile/ios/WidgetExtension/WidgetExtension.entitlements b/mobile/ios/WidgetExtension/WidgetExtension.entitlements index d16dcca065..1328658832 100644 --- a/mobile/ios/WidgetExtension/WidgetExtension.entitlements +++ b/mobile/ios/WidgetExtension/WidgetExtension.entitlements @@ -4,7 +4,7 @@ com.apple.security.application-groups - group.app.immich.share + $(CUSTOM_GROUP_ID) \ No newline at end of file diff --git a/mobile/ios/fastlane/Fastfile b/mobile/ios/fastlane/Fastfile index ff9fc4580f..f5f7f7887a 100644 --- a/mobile/ios/fastlane/Fastfile +++ b/mobile/ios/fastlane/Fastfile @@ -21,6 +21,7 @@ platform :ios do CODE_SIGN_IDENTITY = "Apple Distribution: FUTO Holdings, Inc. (#{TEAM_ID})" BASE_BUNDLE_ID = "app.alextran.immich" DEV_BUNDLE_ID = "tech.futo.immich.testflight" + DEV_GROUP_ID = "group.app.immich.share.testflight" # Helper method to get App Store Connect API key def get_api_key @@ -33,6 +34,13 @@ platform :ios do ) end + # Helper method to assemble xcargs with optional CUSTOM_GROUP_ID override + def build_xcargs(group_id: nil) + args = "-skipMacroValidation CODE_SIGN_IDENTITY='#{CODE_SIGN_IDENTITY}' CODE_SIGN_STYLE=Manual" + args += " CUSTOM_GROUP_ID='#{group_id}'" if group_id + args + end + # Helper method to get version from pubspec.yaml def get_version_from_pubspec require 'yaml' @@ -89,7 +97,8 @@ end version_number: nil, profile_name_main:, profile_name_share:, - profile_name_widget: + profile_name_widget:, + group_id: nil ) app_identifier = base_bundle_id @@ -97,7 +106,7 @@ end if version_number increment_version_number(version_number: version_number) end - + # Increment build number increment_build_number( build_number: latest_testflight_build_number( @@ -106,14 +115,14 @@ end ) + 1, xcodeproj: "./Runner.xcodeproj" ) - + # Build the app build_app( scheme: "Runner", workspace: "Runner.xcworkspace", configuration: configuration, export_method: "app-store", - xcargs: "-skipMacroValidation CODE_SIGN_IDENTITY='#{CODE_SIGN_IDENTITY}' CODE_SIGN_STYLE=Manual", + xcargs: build_xcargs(group_id: group_id), export_options: { provisioningProfiles: { "#{app_identifier}" => profile_name_main, @@ -165,7 +174,8 @@ end distribute_external: false, profile_name_main: main_profile_name, profile_name_share: share_profile_name, - profile_name_widget: widget_profile_name + profile_name_widget: widget_profile_name, + group_id: DEV_GROUP_ID ) end @@ -274,7 +284,7 @@ end configuration: "Release", export_method: "app-store", skip_package_ipa: true, - xcargs: "-skipMacroValidation CODE_SIGN_IDENTITY='#{CODE_SIGN_IDENTITY}' CODE_SIGN_STYLE=Manual", + xcargs: build_xcargs(group_id: DEV_GROUP_ID), export_options: { provisioningProfiles: { DEV_BUNDLE_ID => main_profile_name, diff --git a/mobile/lib/constants/constants.dart b/mobile/lib/constants/constants.dart index 1748a2a57d..b7fec86b55 100644 --- a/mobile/lib/constants/constants.dart +++ b/mobile/lib/constants/constants.dart @@ -23,6 +23,7 @@ const String kBackupLivePhotoGroup = 'backup_live_photo_group'; const String kDownloadGroupImage = 'group_image'; const String kDownloadGroupVideo = 'group_video'; const String kDownloadGroupLivePhoto = 'group_livephoto'; +const String kShareDownloadGroup = 'group_share'; // Timeline constants const int kTimelineNoneSegmentSize = 120; @@ -30,7 +31,6 @@ const int kTimelineAssetLoadBatchSize = 1024; const int kTimelineAssetLoadOppositeSize = 64; // Widget keys -const String appShareGroupId = "group.app.immich.share"; const String kWidgetAuthToken = "widget_auth_token"; const String kWidgetServerEndpoint = "widget_server_url"; const String kWidgetCustomHeaders = "widget_custom_headers"; diff --git a/mobile/lib/domain/models/config/app_config.dart b/mobile/lib/domain/models/config/app_config.dart index 1baa368df4..a955fb73a8 100644 --- a/mobile/lib/domain/models/config/app_config.dart +++ b/mobile/lib/domain/models/config/app_config.dart @@ -1,14 +1,25 @@ +import 'package:flutter/material.dart'; +import 'package:immich_mobile/constants/colors.dart'; +import 'package:immich_mobile/constants/enums.dart'; import 'package:immich_mobile/domain/models/config/album_config.dart'; import 'package:immich_mobile/domain/models/config/backup_config.dart'; import 'package:immich_mobile/domain/models/config/cleanup_config.dart'; import 'package:immich_mobile/domain/models/config/image_config.dart'; import 'package:immich_mobile/domain/models/config/map_config.dart'; +import 'package:immich_mobile/domain/models/config/network_config.dart'; import 'package:immich_mobile/domain/models/config/slideshow_config.dart'; import 'package:immich_mobile/domain/models/config/theme_config.dart'; import 'package:immich_mobile/domain/models/config/timeline_config.dart'; import 'package:immich_mobile/domain/models/config/viewer_config.dart'; +import 'package:immich_mobile/domain/models/log.model.dart'; +import 'package:immich_mobile/domain/models/settings_key.dart'; +import 'package:immich_mobile/domain/models/timeline.model.dart'; +import 'package:immich_mobile/providers/album/album_sort_by_options.provider.dart'; + +const defaultConfig = AppConfig(); class AppConfig { + final LogLevel logLevel; final ThemeConfig theme; final CleanupConfig cleanup; final MapConfig map; @@ -18,8 +29,10 @@ class AppConfig { final SlideshowConfig slideshow; final AlbumConfig album; final BackupConfig backup; + final NetworkConfig network; const AppConfig({ + this.logLevel = .info, this.theme = const .new(), this.cleanup = const .new(), this.map = const .new(), @@ -29,9 +42,11 @@ class AppConfig { this.slideshow = const .new(), this.album = const .new(), this.backup = const .new(), + this.network = const .new(), }); AppConfig copyWith({ + LogLevel? logLevel, ThemeConfig? theme, CleanupConfig? cleanup, MapConfig? map, @@ -41,7 +56,9 @@ class AppConfig { SlideshowConfig? slideshow, AlbumConfig? album, BackupConfig? backup, + NetworkConfig? network, }) => .new( + logLevel: logLevel ?? this.logLevel, theme: theme ?? this.theme, cleanup: cleanup ?? this.cleanup, map: map ?? this.map, @@ -51,12 +68,14 @@ class AppConfig { slideshow: slideshow ?? this.slideshow, album: album ?? this.album, backup: backup ?? this.backup, + network: network ?? this.network, ); @override bool operator ==(Object other) => identical(this, other) || (other is AppConfig && + other.logLevel == logLevel && other.theme == theme && other.cleanup == cleanup && other.map == map && @@ -65,12 +84,113 @@ class AppConfig { other.viewer == viewer && other.slideshow == slideshow && other.album == album && - other.backup == backup); + other.backup == backup && + other.network == network); @override - int get hashCode => Object.hash(theme, cleanup, map, timeline, image, viewer, slideshow, album, backup); + int get hashCode => + Object.hash(logLevel, theme, cleanup, map, timeline, image, viewer, slideshow, album, backup, network); @override String toString() => - 'AppConfig(theme: $theme, cleanup: $cleanup, map: $map, timeline: $timeline, image: $image, viewer: $viewer, slideshow: $slideshow, album: $album, backup: $backup)'; + 'AppConfig(logLevel: $logLevel, theme: $theme, cleanup: $cleanup, map: $map, timeline: $timeline, image: $image, viewer: $viewer, slideshow: $slideshow, album: $album, backup: $backup, network: $network)'; + + T read(SettingsKey key) => + (switch (key) { + .logLevel => logLevel, + .themePrimaryColor => theme.primaryColor, + .themeMode => theme.mode, + .themeDynamic => theme.dynamicTheme, + .themeColorfulInterface => theme.colorfulInterface, + .imagePreferRemote => image.preferRemote, + .imageLoadOriginal => image.loadOriginal, + .viewerLoopVideo => viewer.loopVideo, + .viewerLoadOriginalVideo => viewer.loadOriginalVideo, + .viewerAutoPlayVideo => viewer.autoPlayVideo, + .viewerTapToNavigate => viewer.tapToNavigate, + .networkAutoEndpointSwitching => network.autoEndpointSwitching, + .networkPreferredWifiName => network.preferredWifiName, + .networkLocalEndpoint => network.localEndpoint, + .networkExternalEndpointList => network.externalEndpointList, + .networkCustomHeaders => network.customHeaders, + .albumSortMode => album.sortMode, + .albumIsReverse => album.isReverse, + .albumIsGrid => album.isGrid, + .backupEnabled => backup.enabled, + .backupUseCellularForVideos => backup.useCellularForVideos, + .backupUseCellularForPhotos => backup.useCellularForPhotos, + .backupRequireCharging => backup.requireCharging, + .backupTriggerDelay => backup.triggerDelay, + .backupSyncAlbums => backup.syncAlbums, + .timelineTilesPerRow => timeline.tilesPerRow, + .timelineGroupAssetsBy => timeline.groupAssetsBy, + .timelineStorageIndicator => timeline.storageIndicator, + .mapShowFavoriteOnly => map.favoritesOnly, + .mapRelativeDate => map.relativeDays, + .mapIncludeArchived => map.includeArchived, + .mapThemeMode => map.themeMode, + .mapWithPartners => map.withPartners, + .cleanupKeepFavorites => cleanup.keepFavorites, + .cleanupKeepMediaType => cleanup.keepMediaType, + .cleanupKeepAlbumIds => cleanup.keepAlbumIds, + .cleanupCutoffDaysAgo => cleanup.cutoffDaysAgo, + .cleanupDefaultsInitialized => cleanup.defaultsInitialized, + .slideshowTransition => slideshow.transition, + .slideshowRepeat => slideshow.repeat, + .slideshowDuration => slideshow.duration, + .slideshowLook => slideshow.look, + .slideshowDirection => slideshow.direction, + }) + as T; + + factory AppConfig.fromEntries(Map, Object> overrides) => + overrides.entries.fold(const AppConfig(), (config, entry) => config.write(entry.key, entry.value)); + + AppConfig write(SettingsKey key, T value) { + return switch (key) { + .logLevel => copyWith(logLevel: value as LogLevel), + .themePrimaryColor => copyWith(theme: theme.copyWith(primaryColor: value as ImmichColorPreset)), + .themeMode => copyWith(theme: theme.copyWith(mode: value as ThemeMode)), + .themeDynamic => copyWith(theme: theme.copyWith(dynamicTheme: value as bool)), + .themeColorfulInterface => copyWith(theme: theme.copyWith(colorfulInterface: value as bool)), + .imagePreferRemote => copyWith(image: image.copyWith(preferRemote: value as bool)), + .imageLoadOriginal => copyWith(image: image.copyWith(loadOriginal: value as bool)), + .viewerLoopVideo => copyWith(viewer: viewer.copyWith(loopVideo: value as bool)), + .viewerLoadOriginalVideo => copyWith(viewer: viewer.copyWith(loadOriginalVideo: value as bool)), + .viewerAutoPlayVideo => copyWith(viewer: viewer.copyWith(autoPlayVideo: value as bool)), + .viewerTapToNavigate => copyWith(viewer: viewer.copyWith(tapToNavigate: value as bool)), + .networkAutoEndpointSwitching => copyWith(network: network.copyWith(autoEndpointSwitching: value as bool)), + .networkPreferredWifiName => copyWith(network: network.copyWith(preferredWifiName: (value as String))), + .networkLocalEndpoint => copyWith(network: network.copyWith(localEndpoint: (value as String))), + .networkExternalEndpointList => copyWith(network: network.copyWith(externalEndpointList: value as List)), + .networkCustomHeaders => copyWith(network: network.copyWith(customHeaders: value as Map)), + .albumSortMode => copyWith(album: album.copyWith(sortMode: value as AlbumSortMode)), + .albumIsReverse => copyWith(album: album.copyWith(isReverse: value as bool)), + .albumIsGrid => copyWith(album: album.copyWith(isGrid: value as bool)), + .backupEnabled => copyWith(backup: backup.copyWith(enabled: value as bool)), + .backupUseCellularForVideos => copyWith(backup: backup.copyWith(useCellularForVideos: value as bool)), + .backupUseCellularForPhotos => copyWith(backup: backup.copyWith(useCellularForPhotos: value as bool)), + .backupRequireCharging => copyWith(backup: backup.copyWith(requireCharging: value as bool)), + .backupTriggerDelay => copyWith(backup: backup.copyWith(triggerDelay: value as int)), + .backupSyncAlbums => copyWith(backup: backup.copyWith(syncAlbums: value as bool)), + .timelineTilesPerRow => copyWith(timeline: timeline.copyWith(tilesPerRow: value as int)), + .timelineGroupAssetsBy => copyWith(timeline: timeline.copyWith(groupAssetsBy: value as GroupAssetsBy)), + .timelineStorageIndicator => copyWith(timeline: timeline.copyWith(storageIndicator: value as bool)), + .mapShowFavoriteOnly => copyWith(map: map.copyWith(favoritesOnly: value as bool)), + .mapRelativeDate => copyWith(map: map.copyWith(relativeDays: value as int)), + .mapIncludeArchived => copyWith(map: map.copyWith(includeArchived: value as bool)), + .mapThemeMode => copyWith(map: map.copyWith(themeMode: value as ThemeMode)), + .mapWithPartners => copyWith(map: map.copyWith(withPartners: value as bool)), + .cleanupKeepFavorites => copyWith(cleanup: cleanup.copyWith(keepFavorites: value as bool)), + .cleanupKeepMediaType => copyWith(cleanup: cleanup.copyWith(keepMediaType: value as AssetKeepType)), + .cleanupKeepAlbumIds => copyWith(cleanup: cleanup.copyWith(keepAlbumIds: value as List)), + .cleanupCutoffDaysAgo => copyWith(cleanup: cleanup.copyWith(cutoffDaysAgo: value as int)), + .cleanupDefaultsInitialized => copyWith(cleanup: cleanup.copyWith(defaultsInitialized: value as bool)), + .slideshowTransition => copyWith(slideshow: slideshow.copyWith(transition: value as bool)), + .slideshowRepeat => copyWith(slideshow: slideshow.copyWith(repeat: value as bool)), + .slideshowDuration => copyWith(slideshow: slideshow.copyWith(duration: value as int)), + .slideshowLook => copyWith(slideshow: slideshow.copyWith(look: value as SlideshowLook)), + .slideshowDirection => copyWith(slideshow: slideshow.copyWith(direction: value as SlideshowDirection)), + }; + } } diff --git a/mobile/lib/domain/models/config/network_config.dart b/mobile/lib/domain/models/config/network_config.dart index 78f0482a1a..34666d60e1 100644 --- a/mobile/lib/domain/models/config/network_config.dart +++ b/mobile/lib/domain/models/config/network_config.dart @@ -2,15 +2,15 @@ import 'package:flutter/foundation.dart'; class NetworkConfig { final bool autoEndpointSwitching; - final String? preferredWifiName; - final String? localEndpoint; + final String preferredWifiName; + final String localEndpoint; final List externalEndpointList; final Map customHeaders; const NetworkConfig({ this.autoEndpointSwitching = false, - this.preferredWifiName, - this.localEndpoint, + this.preferredWifiName = '', + this.localEndpoint = '', this.externalEndpointList = const [], this.customHeaders = const {}, }); diff --git a/mobile/lib/domain/models/config/system_config.dart b/mobile/lib/domain/models/config/system_config.dart deleted file mode 100644 index 7d8fef6dd8..0000000000 --- a/mobile/lib/domain/models/config/system_config.dart +++ /dev/null @@ -1,22 +0,0 @@ -import 'package:immich_mobile/domain/models/config/network_config.dart'; -import 'package:immich_mobile/domain/models/log.model.dart'; - -class SystemConfig { - final LogLevel logLevel; - final NetworkConfig network; - - const SystemConfig({this.logLevel = .info, this.network = const .new()}); - - SystemConfig copyWith({LogLevel? logLevel, NetworkConfig? network}) => - SystemConfig(logLevel: logLevel ?? this.logLevel, network: network ?? this.network); - - @override - bool operator ==(Object other) => - identical(this, other) || (other is SystemConfig && other.logLevel == logLevel && other.network == network); - - @override - int get hashCode => Object.hash(logLevel, network); - - @override - String toString() => 'SystemConfig(logLevel: $logLevel, network: $network)'; -} diff --git a/mobile/lib/domain/models/metadata_key.dart b/mobile/lib/domain/models/metadata_key.dart deleted file mode 100644 index 541c538169..0000000000 --- a/mobile/lib/domain/models/metadata_key.dart +++ /dev/null @@ -1,273 +0,0 @@ -import 'dart:convert'; - -import 'package:collection/collection.dart'; -import 'package:flutter/material.dart'; -import 'package:immich_mobile/constants/colors.dart'; -import 'package:immich_mobile/constants/enums.dart'; -import 'package:immich_mobile/domain/models/config/app_config.dart'; -import 'package:immich_mobile/domain/models/config/system_config.dart'; -import 'package:immich_mobile/domain/models/log.model.dart'; -import 'package:immich_mobile/domain/models/timeline.model.dart'; -import 'package:immich_mobile/providers/album/album_sort_by_options.provider.dart'; - -enum MetadataDomain { - appConfig('config.app'), - systemConfig('config.system'); - - final String prefix; - const MetadataDomain(this.prefix); -} - -enum MetadataKey { - // Theme - themePrimaryColor(.appConfig, 'theme.primaryColor', .indigo, _EnumCodec(ImmichColorPreset.values)), - themeMode(.appConfig, 'theme.mode', .system, _EnumCodec(ThemeMode.values)), - themeDynamic(.appConfig, 'theme.dynamic', false), - themeColorfulInterface(.appConfig, 'theme.colorfulInterface', true), - - // Image - imagePreferRemote(.appConfig, 'image.preferRemote', false), - imageLoadOriginal(.appConfig, 'image.loadOriginal', false), - - // Viewer - viewerLoopVideo(.appConfig, 'viewer.loopVideo', true), - viewerLoadOriginalVideo(.appConfig, 'viewer.loadOriginalVideo', false), - viewerAutoPlayVideo(.appConfig, 'viewer.autoPlayVideo', true), - viewerTapToNavigate(.appConfig, 'viewer.tapToNavigate', false), - - // Network - networkAutoEndpointSwitching(.systemConfig, 'network.autoEndpointSwitching', false), - networkPreferredWifiName(.systemConfig, 'network.preferredWifiName', ''), - networkLocalEndpoint(.systemConfig, 'network.localEndpoint', ''), - networkExternalEndpointList>( - .systemConfig, - 'network.externalEndpointList', - [], - _ListCodec(_PrimitiveCodec.string), - ), - networkCustomHeaders>( - .systemConfig, - 'network.customHeaders', - {}, - _MapCodec(_PrimitiveCodec.string, _PrimitiveCodec.string), - ), - - // Album - albumSortMode( - .appConfig, - 'album.sortMode', - AlbumSortMode.mostRecent, - _EnumCodec(AlbumSortMode.values), - ), - albumIsReverse(.appConfig, 'album.isReverse', true), - albumIsGrid(.appConfig, 'album.isGrid', false), - - // Backup - backupEnabled(.appConfig, 'backup.enabled', false), - backupUseCellularForVideos(.appConfig, 'backup.useCellularForVideos', false), - backupUseCellularForPhotos(.appConfig, 'backup.useCellularForPhotos', false), - backupRequireCharging(.appConfig, 'backup.requireCharging', false), - backupTriggerDelay(.appConfig, 'backup.triggerDelay', 30), - backupSyncAlbums(.appConfig, 'backup.syncAlbums', false), - - // Timeline - timelineTilesPerRow(.appConfig, 'timeline.tilesPerRow', 4), - timelineGroupAssetsBy( - .appConfig, - 'timeline.groupAssetsBy', - GroupAssetsBy.day, - _EnumCodec(GroupAssetsBy.values), - ), - timelineStorageIndicator(.appConfig, 'timeline.storageIndicator', true), - - // Log - logLevel(.systemConfig, 'log.level', .info, _EnumCodec(LogLevel.values)), - - // Map - mapShowFavoriteOnly(.appConfig, 'map.showFavoriteOnly', false), - mapRelativeDate(.appConfig, 'map.relativeDate', 0), - mapIncludeArchived(.appConfig, 'map.includeArchived', false), - mapThemeMode(.appConfig, 'map.themeMode', .system, _EnumCodec(ThemeMode.values)), - mapWithPartners(.appConfig, 'map.withPartners', false), - - // Cleanup - cleanupKeepFavorites(.appConfig, 'cleanup.keepFavorites', true), - cleanupKeepMediaType( - .appConfig, - 'cleanup.keepMediaType', - AssetKeepType.none, - _EnumCodec(AssetKeepType.values), - ), - cleanupKeepAlbumIds>(.appConfig, 'cleanup.keepAlbumIds', [], _ListCodec(_PrimitiveCodec.string)), - cleanupCutoffDaysAgo(.appConfig, 'cleanup.cutoffDaysAgo', -1), - cleanupDefaultsInitialized(.appConfig, 'cleanup.defaultsInitialized', false), - - // Slideshow - slideshowTransition(.appConfig, 'slideshow.transition', true), - slideshowRepeat(.appConfig, 'slideshow.repeat', true), - slideshowDuration(.appConfig, 'slideshow.duration', 5), - slideshowLook(.appConfig, 'slideshow.look', SlideshowLook.contain, _EnumCodec(SlideshowLook.values)), - slideshowDirection( - .appConfig, - 'slideshow.direction', - SlideshowDirection.forward, - _EnumCodec(SlideshowDirection.values), - ); - - final MetadataDomain domain; - final String name; - final T defaultValue; - final _MetadataCodec? _codecOverride; - - const MetadataKey(this.domain, this.name, this.defaultValue, [this._codecOverride]); - - String get key => '${domain.prefix}.$name'; - - _MetadataCodec get _codec => _codecOverride ?? _MetadataCodec.forPrimitive(defaultValue); - - String encode(T value) => _codec.encode(value); - - T decode(String raw) => _codec.decode(raw) ?? defaultValue; - - static Map> asKeyMap() => {for (var value in MetadataKey.values) value.key: value}; -} - -sealed class _MetadataCodec { - const _MetadataCodec(); - - String encode(T value); - T? decode(String raw); - - static const Map> _primitives = { - int: _PrimitiveCodec.integer, - double: _PrimitiveCodec.real, - bool: _PrimitiveCodec.boolean, - String: _PrimitiveCodec.string, - DateTime: _DateTimeCodec(), - }; - - static _MetadataCodec forPrimitive(T sample) { - final codec = _primitives[sample.runtimeType]; - if (codec == null) { - throw StateError( - 'No primitive codec for ${sample.runtimeType}. Provide an explicit codec when defining the MetadataKey.', - ); - } - return codec as _MetadataCodec; - } -} - -final class _EnumCodec extends _MetadataCodec { - final List values; - - const _EnumCodec(this.values); - - @override - String encode(T value) => value.name; - - @override - T? decode(String raw) => values.firstWhereOrNull((v) => v.name == raw); -} - -final class _DateTimeCodec extends _MetadataCodec { - const _DateTimeCodec(); - - @override - String encode(DateTime value) => value.toIso8601String(); - - @override - DateTime? decode(String raw) => DateTime.tryParse(raw); -} - -final class _MapCodec extends _MetadataCodec> { - final _MetadataCodec _keyCodec; - final _MetadataCodec _valueCodec; - - const _MapCodec(this._keyCodec, this._valueCodec); - - @override - String encode(Map value) { - final entries = {}; - value.forEach((k, v) => entries[_keyCodec.encode(k)] = _valueCodec.encode(v)); - return jsonEncode(entries); - } - - @override - Map? decode(String raw) { - try { - final decoded = jsonDecode(raw); - if (decoded is! Map) { - return null; - } - final result = {}; - for (final entry in decoded.entries) { - final rawKey = entry.key; - final rawValue = entry.value; - if (rawKey is! String || rawValue is! String) { - return null; - } - final k = _keyCodec.decode(rawKey); - final v = _valueCodec.decode(rawValue); - if (k == null || v == null) { - return null; - } - result[k] = v; - } - return result; - } on FormatException { - return null; - } - } -} - -final class _ListCodec extends _MetadataCodec> { - final _MetadataCodec _elementCodec; - - const _ListCodec(this._elementCodec); - - @override - String encode(List value) => jsonEncode(value.map(_elementCodec.encode).toList()); - - @override - List? decode(String raw) { - try { - final decoded = jsonDecode(raw); - if (decoded is! List) { - return null; - } - final result = []; - for (final item in decoded) { - if (item is! String) { - return null; - } - final element = _elementCodec.decode(item); - if (element == null) { - return null; - } - result.add(element); - } - return result; - } on FormatException { - return null; - } - } -} - -final class _PrimitiveCodec extends _MetadataCodec { - final T? Function(String) _parse; - - const _PrimitiveCodec._(this._parse); - - @override - String encode(T value) => value.toString(); - - @override - T? decode(String raw) => _parse(raw); - - static const integer = _PrimitiveCodec._(int.tryParse); - static const real = _PrimitiveCodec._(double.tryParse); - static const boolean = _PrimitiveCodec._(bool.tryParse); - static const string = _PrimitiveCodec._(_identity); - - static String? _identity(String s) => s; -} diff --git a/mobile/lib/domain/models/settings_key.dart b/mobile/lib/domain/models/settings_key.dart new file mode 100644 index 0000000000..5277a37a60 --- /dev/null +++ b/mobile/lib/domain/models/settings_key.dart @@ -0,0 +1,217 @@ +import 'dart:convert'; + +import 'package:flutter/material.dart'; +import 'package:immich_mobile/constants/colors.dart'; +import 'package:immich_mobile/constants/enums.dart'; +import 'package:immich_mobile/domain/models/log.model.dart'; +import 'package:immich_mobile/domain/models/timeline.model.dart'; +import 'package:immich_mobile/providers/album/album_sort_by_options.provider.dart'; + +enum SettingsKey { + // Theme + themePrimaryColor(codec: _EnumCodec(ImmichColorPreset.values)), + themeMode(codec: _EnumCodec(ThemeMode.values)), + themeDynamic(), + themeColorfulInterface(), + + // Image + imagePreferRemote(), + imageLoadOriginal(), + + // Viewer + viewerLoopVideo(), + viewerLoadOriginalVideo(), + viewerAutoPlayVideo(), + viewerTapToNavigate(), + + // Network + networkAutoEndpointSwitching(), + networkPreferredWifiName(), + networkLocalEndpoint(), + networkExternalEndpointList>(codec: _ListCodec(_PrimitiveCodec.string)), + networkCustomHeaders>(codec: _MapCodec(_PrimitiveCodec.string, _PrimitiveCodec.string)), + + // Album + albumSortMode(codec: _EnumCodec(AlbumSortMode.values)), + albumIsReverse(), + albumIsGrid(), + + // Backup + backupEnabled(), + backupUseCellularForVideos(), + backupUseCellularForPhotos(), + backupRequireCharging(), + backupTriggerDelay(), + backupSyncAlbums(), + + // Timeline + timelineTilesPerRow(), + timelineGroupAssetsBy(codec: _EnumCodec(GroupAssetsBy.values)), + timelineStorageIndicator(), + + // Log + logLevel(codec: _EnumCodec(LogLevel.values)), + + // Map + mapShowFavoriteOnly(), + mapRelativeDate(), + mapIncludeArchived(), + mapThemeMode(codec: _EnumCodec(ThemeMode.values)), + mapWithPartners(), + + // Cleanup + cleanupKeepFavorites(), + cleanupKeepMediaType(codec: _EnumCodec(AssetKeepType.values)), + cleanupKeepAlbumIds>(codec: _ListCodec(_PrimitiveCodec.string)), + cleanupCutoffDaysAgo(), + cleanupDefaultsInitialized(), + + // Slideshow + slideshowTransition(), + slideshowRepeat(), + slideshowDuration(), + slideshowLook(codec: _EnumCodec(SlideshowLook.values)), + slideshowDirection(codec: _EnumCodec(SlideshowDirection.values)); + + final _SettingsCodec? _codecOverride; + + const SettingsKey({_SettingsCodec? codec}) : _codecOverride = codec; + + _SettingsCodec get _codec => _codecOverride ?? _SettingsCodec.forType(T); + + String encode(T value) => _codec.encode(value); + + T decode(String raw) => _codec.decode(raw); +} + +sealed class _SettingsCodec { + const _SettingsCodec(); + + String encode(T value); + T decode(String raw); + + static const Map> _primitives = { + int: _PrimitiveCodec.integer, + double: _PrimitiveCodec.real, + bool: _PrimitiveCodec.boolean, + String: _PrimitiveCodec.string, + DateTime: _DateTimeCodec(), + }; + + static _SettingsCodec forType(Type runtimeType) { + final codec = _primitives[runtimeType]; + if (codec == null) { + throw StateError('No primitive codec for $runtimeType. Provide an explicit codec when defining the SettingsKey.'); + } + return codec as _SettingsCodec; + } +} + +final class _EnumCodec extends _SettingsCodec { + final List values; + + const _EnumCodec(this.values); + + @override + String encode(T value) => value.name; + + @override + T decode(String raw) => values.firstWhere((v) => v.name == raw); +} + +final class _DateTimeCodec extends _SettingsCodec { + const _DateTimeCodec(); + + @override + String encode(DateTime value) => value.toIso8601String(); + + @override + DateTime decode(String raw) => DateTime.parse(raw); +} + +final class _MapCodec extends _SettingsCodec> { + final _SettingsCodec _keyCodec; + final _SettingsCodec _valueCodec; + + const _MapCodec(this._keyCodec, this._valueCodec); + + @override + String encode(Map value) { + final entries = {}; + value.forEach((k, v) => entries[_keyCodec.encode(k)] = _valueCodec.encode(v)); + return jsonEncode(entries); + } + + @override + Map decode(String raw) { + try { + final decoded = jsonDecode(raw); + if (decoded is! Map) { + return {}; + } + final result = {}; + for (final entry in decoded.entries) { + final rawKey = entry.key; + final rawValue = entry.value; + if (rawKey is! String || rawValue is! String) { + return {}; + } + final k = _keyCodec.decode(rawKey); + final v = _valueCodec.decode(rawValue); + result[k] = v; + } + return result; + } on FormatException { + return {}; + } + } +} + +final class _ListCodec extends _SettingsCodec> { + final _SettingsCodec _elementCodec; + + const _ListCodec(this._elementCodec); + + @override + String encode(List value) => jsonEncode(value.map(_elementCodec.encode).toList()); + + @override + List decode(String raw) { + try { + final decoded = jsonDecode(raw); + if (decoded is! List) { + return []; + } + final result = []; + for (final item in decoded) { + if (item is! String) { + return []; + } + final element = _elementCodec.decode(item); + result.add(element); + } + return result; + } on FormatException { + return []; + } + } +} + +final class _PrimitiveCodec extends _SettingsCodec { + final T Function(String) _parse; + + const _PrimitiveCodec._(this._parse); + + @override + String encode(T value) => value.toString(); + + @override + T decode(String raw) => _parse(raw); + + static const integer = _PrimitiveCodec._(int.parse); + static const real = _PrimitiveCodec._(double.parse); + static const boolean = _PrimitiveCodec._(bool.parse); + static const string = _PrimitiveCodec._(_identity); + + static String _identity(String s) => s; +} diff --git a/mobile/lib/domain/services/asset.service.dart b/mobile/lib/domain/services/asset.service.dart index 7fa8c13fd8..b055ad38b1 100644 --- a/mobile/lib/domain/services/asset.service.dart +++ b/mobile/lib/domain/services/asset.service.dart @@ -8,11 +8,7 @@ class AssetService { final RemoteAssetRepository _remoteAssetRepository; final DriftLocalAssetRepository _localAssetRepository; - const AssetService({ - required RemoteAssetRepository remoteAssetRepository, - required DriftLocalAssetRepository localAssetRepository, - }) : _remoteAssetRepository = remoteAssetRepository, - _localAssetRepository = localAssetRepository; + const AssetService({required this._remoteAssetRepository, required this._localAssetRepository}); Future getAsset(BaseAsset asset) { final id = asset is LocalAsset ? asset.id : (asset as RemoteAsset).id; diff --git a/mobile/lib/domain/services/background_worker.service.dart b/mobile/lib/domain/services/background_worker.service.dart index bcefadaf0e..d28f7ff14b 100644 --- a/mobile/lib/domain/services/background_worker.service.dart +++ b/mobile/lib/domain/services/background_worker.service.dart @@ -11,7 +11,7 @@ import 'package:immich_mobile/entities/store.entity.dart'; import 'package:immich_mobile/extensions/platform_extensions.dart'; import 'package:immich_mobile/infrastructure/repositories/db.repository.dart'; import 'package:immich_mobile/infrastructure/repositories/logger_db.repository.dart'; -import 'package:immich_mobile/infrastructure/repositories/metadata.repository.dart'; +import 'package:immich_mobile/infrastructure/repositories/settings.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/background_sync.provider.dart'; @@ -39,7 +39,7 @@ class BackgroundWorkerFgService { _foregroundHostApi.saveNotificationMessage(title, body); Future configure({int? minimumDelaySeconds, bool? requireCharging}) { - final backup = MetadataRepository.instance.appConfig.backup; + final backup = SettingsRepository.instance.appConfig.backup; return _foregroundHostApi.configure( BackgroundWorkerSettings( minimumDelaySeconds: minimumDelaySeconds ?? backup.triggerDelay, @@ -61,15 +61,13 @@ class BackgroundWorkerBgService extends BackgroundWorkerFlutterApi { bool _isCleanedUp = false; - BackgroundWorkerBgService({required Drift drift, required DriftLogger driftLogger}) - : _drift = drift, - _driftLogger = driftLogger, - _backgroundHostApi = BackgroundWorkerBgHostApi() { - _ref = ProviderContainer(overrides: [driftProvider.overrideWith(driftOverride(drift))]); + BackgroundWorkerBgService({required this._drift, required this._driftLogger}) + : _backgroundHostApi = BackgroundWorkerBgHostApi() { + _ref = ProviderContainer(overrides: [driftProvider.overrideWith(driftOverride(_drift))]); BackgroundWorkerFlutterApi.setUp(this); } - bool get _isBackupEnabled => MetadataRepository.instance.appConfig.backup.enabled; + bool get _isBackupEnabled => SettingsRepository.instance.appConfig.backup.enabled; Future init() async { try { diff --git a/mobile/lib/domain/services/hash.service.dart b/mobile/lib/domain/services/hash.service.dart index 6781507566..e2938a79ad 100644 --- a/mobile/lib/domain/services/hash.service.dart +++ b/mobile/lib/domain/services/hash.service.dart @@ -21,18 +21,13 @@ class HashService { final _log = Logger('HashService'); HashService({ - required DriftLocalAlbumRepository localAlbumRepository, - required DriftLocalAssetRepository localAssetRepository, - required DriftTrashedLocalAssetRepository trashedLocalAssetRepository, - required NativeSyncApi nativeSyncApi, - bool Function()? cancelChecker, + required this._localAlbumRepository, + required this._localAssetRepository, + required this._trashedLocalAssetRepository, + required this._nativeSyncApi, + this._cancelChecker, int? batchSize, - }) : _localAlbumRepository = localAlbumRepository, - _localAssetRepository = localAssetRepository, - _trashedLocalAssetRepository = trashedLocalAssetRepository, - _cancelChecker = cancelChecker, - _nativeSyncApi = nativeSyncApi, - _batchSize = batchSize ?? kBatchHashFileLimit; + }) : _batchSize = batchSize ?? kBatchHashFileLimit; bool get isCancelled => _cancelChecker?.call() ?? false; diff --git a/mobile/lib/domain/services/local_sync.service.dart b/mobile/lib/domain/services/local_sync.service.dart index 34300dee3d..77ded0ba4d 100644 --- a/mobile/lib/domain/services/local_sync.service.dart +++ b/mobile/lib/domain/services/local_sync.service.dart @@ -9,10 +9,10 @@ import 'package:immich_mobile/entities/store.entity.dart'; import 'package:immich_mobile/extensions/platform_extensions.dart'; import 'package:immich_mobile/infrastructure/repositories/local_album.repository.dart'; import 'package:immich_mobile/infrastructure/repositories/local_asset.repository.dart'; -import 'package:immich_mobile/infrastructure/repositories/storage.repository.dart'; import 'package:immich_mobile/infrastructure/repositories/trashed_local_asset.repository.dart'; import 'package:immich_mobile/platform/native_sync_api.g.dart'; -import 'package:immich_mobile/repositories/local_files_manager.repository.dart'; +import 'package:immich_mobile/repositories/asset_media.repository.dart'; +import 'package:immich_mobile/repositories/permission.repository.dart'; import 'package:immich_mobile/utils/datetime_helpers.dart'; import 'package:immich_mobile/utils/diff.dart'; import 'package:logging/logging.dart'; @@ -23,29 +23,24 @@ class LocalSyncService { final DriftLocalAssetRepository _localAssetRepository; final NativeSyncApi _nativeSyncApi; final DriftTrashedLocalAssetRepository _trashedLocalAssetRepository; - final LocalFilesManagerRepository _localFilesManager; - final StorageRepository _storageRepository; + final AssetMediaRepository _assetMediaRepository; + final IPermissionRepository _permissionRepository; final Logger _log = Logger("DeviceSyncService"); LocalSyncService({ - required DriftLocalAlbumRepository localAlbumRepository, - required DriftLocalAssetRepository localAssetRepository, - required DriftTrashedLocalAssetRepository trashedLocalAssetRepository, - required LocalFilesManagerRepository localFilesManager, - required StorageRepository storageRepository, - required NativeSyncApi nativeSyncApi, - }) : _localAlbumRepository = localAlbumRepository, - _localAssetRepository = localAssetRepository, - _trashedLocalAssetRepository = trashedLocalAssetRepository, - _localFilesManager = localFilesManager, - _storageRepository = storageRepository, - _nativeSyncApi = nativeSyncApi; + required this._localAlbumRepository, + required this._localAssetRepository, + required this._nativeSyncApi, + required this._trashedLocalAssetRepository, + required this._assetMediaRepository, + required this._permissionRepository, + }); Future sync({bool full = false}) async { final Stopwatch stopwatch = Stopwatch()..start(); try { if (CurrentPlatform.isAndroid && Store.get(StoreKey.manageLocalMediaAndroid, false)) { - final hasPermission = await _localFilesManager.hasManageMediaPermission(); + final hasPermission = await _permissionRepository.hasManageMediaPermission(); if (hasPermission) { await _syncTrashedAssets(); } else { @@ -373,7 +368,7 @@ class LocalSyncService { final assetsToRestore = await _trashedLocalAssetRepository.getToRestore(); if (assetsToRestore.isNotEmpty) { - final restoredIds = await _localFilesManager.restoreAssetsFromTrash(assetsToRestore); + final restoredIds = await _assetMediaRepository.restoreAssetsFromTrash(assetsToRestore); await _trashedLocalAssetRepository.applyRestoredAssets(restoredIds); } else { _log.info("syncTrashedAssets, No remote assets found for restoration"); @@ -381,15 +376,15 @@ class LocalSyncService { final localAssetsToTrash = await _trashedLocalAssetRepository.getToTrash(); if (localAssetsToTrash.isNotEmpty) { - final mediaUrls = await Future.wait( - localAssetsToTrash.values - .expand((e) => e) - .map((localAsset) => _storageRepository.getAssetEntityForAsset(localAsset).then((e) => e?.getMediaUrl())), - ); - _log.info("Moving to trash ${mediaUrls.join(", ")} assets"); - final result = await _localFilesManager.moveToTrash(mediaUrls.nonNulls.toList()); - if (result) { - await _trashedLocalAssetRepository.trashLocalAsset(localAssetsToTrash); + final localIds = localAssetsToTrash.values.expand((assets) => assets).map((asset) => asset.id).toList(); + _log.info("Moving to trash ${localIds.join(", ")} assets"); + final movedIds = await _assetMediaRepository.deleteAll(localIds); + if (movedIds.isNotEmpty) { + final movedAssetsByAlbum = localAssetsToTrash.map( + (albumId, assets) => MapEntry(albumId, assets.where((asset) => movedIds.contains(asset.id)).toList()), + )..removeWhere((_, assets) => assets.isEmpty); + + await _trashedLocalAssetRepository.trashLocalAsset(movedAssetsByAlbum); } } else { _log.info("syncTrashedAssets, No assets found in backup-enabled albums for move to trash"); diff --git a/mobile/lib/domain/services/log.service.dart b/mobile/lib/domain/services/log.service.dart index 1235d7ac76..216f030b12 100644 --- a/mobile/lib/domain/services/log.service.dart +++ b/mobile/lib/domain/services/log.service.dart @@ -2,9 +2,9 @@ import 'dart:async'; import 'package:immich_mobile/constants/constants.dart'; import 'package:immich_mobile/domain/models/log.model.dart'; -import 'package:immich_mobile/domain/models/metadata_key.dart'; +import 'package:immich_mobile/domain/models/settings_key.dart'; import 'package:immich_mobile/infrastructure/repositories/log.repository.dart'; -import 'package:immich_mobile/infrastructure/repositories/metadata.repository.dart'; +import 'package:immich_mobile/infrastructure/repositories/settings.repository.dart'; import 'package:immich_mobile/utils/debug_print.dart'; import 'package:logging/logging.dart'; @@ -12,10 +12,10 @@ import 'package:logging/logging.dart'; /// /// It listens to Dart's [Logger.root], buffers logs in memory (optionally), /// writes them to a persistent [LogRepository], and manages log levels via -/// [MetadataRepository]. +/// [SettingsRepository]. class LogService { final LogRepository _logRepository; - final MetadataRepository _metadataRepository; + final SettingsRepository _settingsRepository; final List _msgBuffer = []; @@ -38,12 +38,12 @@ class LogService { static Future init({ required LogRepository logRepository, - required MetadataRepository metadataRepository, + required SettingsRepository settingsRepository, bool shouldBuffer = true, }) async { _instance ??= await create( logRepository: logRepository, - metadataRepository: metadataRepository, + settingsRepository: settingsRepository, shouldBuffer: shouldBuffer, ); return _instance!; @@ -51,17 +51,17 @@ class LogService { static Future create({ required LogRepository logRepository, - required MetadataRepository metadataRepository, + required SettingsRepository settingsRepository, bool shouldBuffer = true, }) async { - final instance = LogService._(logRepository, metadataRepository, shouldBuffer); + final instance = LogService._(logRepository, settingsRepository, shouldBuffer); await logRepository.truncate(limit: kLogTruncateLimit); - final level = instance._metadataRepository.systemConfig.logLevel; + final level = instance._settingsRepository.appConfig.logLevel; Logger.root.level = Level.LEVELS.elementAtOrNull(level.index) ?? Level.INFO; return instance; } - LogService._(this._logRepository, this._metadataRepository, this._shouldBuffer) { + LogService._(this._logRepository, this._settingsRepository, this._shouldBuffer) { _logSubscription = Logger.root.onRecord.listen(_handleLogRecord); } @@ -91,7 +91,7 @@ class LogService { } Future setLogLevel(LogLevel level) async { - await _metadataRepository.write(MetadataKey.logLevel, level); + await _settingsRepository.write(SettingsKey.logLevel, level); Logger.root.level = level.toLevel(); } diff --git a/mobile/lib/domain/services/map.service.dart b/mobile/lib/domain/services/map.service.dart index 6c64e2817e..6c484d1a14 100644 --- a/mobile/lib/domain/services/map.service.dart +++ b/mobile/lib/domain/services/map.service.dart @@ -10,7 +10,7 @@ typedef MapQuery = ({MapMarkerSource markerSource}); class MapFactory { final DriftMapRepository _mapRepository; - const MapFactory({required DriftMapRepository mapRepository}) : _mapRepository = mapRepository; + const MapFactory({required this._mapRepository}); MapService remote(List ownerIds, TimelineMapOptions options) => MapService(_mapRepository.remote(ownerIds, options)); diff --git a/mobile/lib/domain/services/remote_album.service.dart b/mobile/lib/domain/services/remote_album.service.dart index e873a7631f..35a8f899a8 100644 --- a/mobile/lib/domain/services/remote_album.service.dart +++ b/mobile/lib/domain/services/remote_album.service.dart @@ -192,43 +192,30 @@ class RemoteAlbumService { required UserDto uploader, required AlbumAssetCandidates candidates, UploadCallbacks uploadCallbacks = const UploadCallbacks(), + Completer? cancelToken, }) async { int addedCount = 0; if (candidates.remoteAssetIds.isNotEmpty) { addedCount += await addAssets(albumId: albumId, assetIds: candidates.remoteAssetIds); } if (candidates.localAssetsToUpload.isNotEmpty) { - addedCount += await _uploadAndAddLocals(albumId, uploader, candidates.localAssetsToUpload, uploadCallbacks); + addedCount += await _uploadAndAddLocals( + albumId, + uploader, + candidates.localAssetsToUpload, + uploadCallbacks, + cancelToken, + ); } return addedCount; } - /// Creates an album, seeding it with already-remote asset IDs, then uploads - /// local-only assets and links each one as it finishes. - Future createAlbumWithAssets({ - required String title, - required UserDto owner, - String? description, - AlbumAssetCandidates candidates = const AlbumAssetCandidates(remoteAssetIds: [], localAssetsToUpload: []), - UploadCallbacks uploadCallbacks = const UploadCallbacks(), - }) async { - final album = await createAlbum( - title: title, - owner: owner, - description: description, - assetIds: candidates.remoteAssetIds, - ); - if (candidates.localAssetsToUpload.isNotEmpty) { - await _uploadAndAddLocals(album.id, owner, candidates.localAssetsToUpload, uploadCallbacks); - } - return album; - } - Future _uploadAndAddLocals( String albumId, UserDto uploader, List localAssets, UploadCallbacks userCallbacks, + Completer? cancelToken, ) async { int addedCount = 0; final pendingAdds = >[]; @@ -258,7 +245,7 @@ class RemoteAlbumService { return; } pendingAdds.add( - _linkUploadedAssetToAlbum(albumId, remoteId, uploader, source) + linkUploadedAssetToAlbum(albumId, remoteId, uploader, source) .then((added) { addedCount += added; }) @@ -269,7 +256,7 @@ class RemoteAlbumService { }, ); - await _uploadService.uploadManual(localAssets, callbacks: wrappedCallbacks); + await _uploadService.uploadManual(localAssets, callbacks: wrappedCallbacks, cancelToken: cancelToken); await Future.wait(pendingAdds); return addedCount; } @@ -288,7 +275,7 @@ class RemoteAlbumService { /// `remote_asset_entity` row from the local source so the FK-protected /// junction insert succeeds. Sync overwrites the placeholder later with /// the authoritative server data. - Future _linkUploadedAssetToAlbum(String albumId, String remoteId, UserDto uploader, LocalAsset source) async { + Future linkUploadedAssetToAlbum(String albumId, String remoteId, UserDto uploader, LocalAsset source) async { final result = await _albumApiRepository.addAssets(albumId, [remoteId]); if (result.added.isEmpty) { return 0; diff --git a/mobile/lib/domain/services/setting.service.dart b/mobile/lib/domain/services/setting.service.dart index 99e07a2872..1823e46cf9 100644 --- a/mobile/lib/domain/services/setting.service.dart +++ b/mobile/lib/domain/services/setting.service.dart @@ -9,7 +9,7 @@ final AppSetting = SettingsService(storeService: StoreService.I); class SettingsService { final StoreService _storeService; - const SettingsService({required StoreService storeService}) : _storeService = storeService; + const SettingsService({required this._storeService}); T get(Setting setting) => _storeService.get(setting.storeKey, setting.defaultValue); diff --git a/mobile/lib/domain/services/sync_stream.service.dart b/mobile/lib/domain/services/sync_stream.service.dart index 9c8bac4c92..200dca2418 100644 --- a/mobile/lib/domain/services/sync_stream.service.dart +++ b/mobile/lib/domain/services/sync_stream.service.dart @@ -9,12 +9,12 @@ import 'package:immich_mobile/domain/models/sync_event.model.dart'; import 'package:immich_mobile/entities/store.entity.dart'; import 'package:immich_mobile/extensions/platform_extensions.dart'; import 'package:immich_mobile/infrastructure/repositories/local_asset.repository.dart'; -import 'package:immich_mobile/infrastructure/repositories/storage.repository.dart'; import 'package:immich_mobile/infrastructure/repositories/sync_api.repository.dart'; import 'package:immich_mobile/infrastructure/repositories/sync_migration.repository.dart'; import 'package:immich_mobile/infrastructure/repositories/sync_stream.repository.dart'; import 'package:immich_mobile/infrastructure/repositories/trashed_local_asset.repository.dart'; -import 'package:immich_mobile/repositories/local_files_manager.repository.dart'; +import 'package:immich_mobile/repositories/asset_media.repository.dart'; +import 'package:immich_mobile/repositories/permission.repository.dart'; import 'package:immich_mobile/services/api.service.dart'; import 'package:immich_mobile/utils/semver.dart'; import 'package:logging/logging.dart'; @@ -34,31 +34,23 @@ class SyncStreamService { final SyncStreamRepository _syncStreamRepository; final DriftLocalAssetRepository _localAssetRepository; final DriftTrashedLocalAssetRepository _trashedLocalAssetRepository; - final LocalFilesManagerRepository _localFilesManager; - final StorageRepository _storageRepository; + final AssetMediaRepository _assetMediaRepository; + final IPermissionRepository _permissionRepository; final SyncMigrationRepository _syncMigrationRepository; final ApiService _api; final bool Function()? _cancelChecker; SyncStreamService({ - required SyncApiRepository syncApiRepository, - required SyncStreamRepository syncStreamRepository, - required DriftLocalAssetRepository localAssetRepository, - required DriftTrashedLocalAssetRepository trashedLocalAssetRepository, - required LocalFilesManagerRepository localFilesManager, - required StorageRepository storageRepository, - required SyncMigrationRepository syncMigrationRepository, - required ApiService api, - bool Function()? cancelChecker, - }) : _syncApiRepository = syncApiRepository, - _syncStreamRepository = syncStreamRepository, - _localAssetRepository = localAssetRepository, - _trashedLocalAssetRepository = trashedLocalAssetRepository, - _localFilesManager = localFilesManager, - _storageRepository = storageRepository, - _syncMigrationRepository = syncMigrationRepository, - _api = api, - _cancelChecker = cancelChecker; + required this._syncApiRepository, + required this._syncStreamRepository, + required this._localAssetRepository, + required this._trashedLocalAssetRepository, + required this._assetMediaRepository, + required this._permissionRepository, + required this._syncMigrationRepository, + required this._api, + this._cancelChecker, + }); bool get isCancelled => _cancelChecker?.call() ?? false; @@ -500,22 +492,22 @@ class SyncStreamService { } Future _trashLocalAssets(Map> localAssetsToTrash) async { - final mediaUrls = await Future.wait( - localAssetsToTrash.values - .expand((e) => e) - .map((localAsset) => _storageRepository.getAssetEntityForAsset(localAsset).then((e) => e?.getMediaUrl())), - ); - _logger.info("Moving to trash ${mediaUrls.join(", ")} assets"); - final result = await _localFilesManager.moveToTrash(mediaUrls.nonNulls.toList()); - if (result) { - await _trashedLocalAssetRepository.trashLocalAsset(localAssetsToTrash); + final localIds = localAssetsToTrash.values.expand((assets) => assets).map((asset) => asset.id).toList(); + _logger.info("Moving to trash ${localIds.join(", ")} assets"); + final movedIds = await _assetMediaRepository.deleteAll(localIds); + if (movedIds.isNotEmpty) { + final movedAssetsByAlbum = localAssetsToTrash.map( + (albumId, assets) => MapEntry(albumId, assets.where((asset) => movedIds.contains(asset.id)).toList()), + )..removeWhere((_, assets) => assets.isEmpty); + + await _trashedLocalAssetRepository.trashLocalAsset(movedAssetsByAlbum); } } Future _applyRemoteRestoreToLocal() async { final assetsToRestore = await _trashedLocalAssetRepository.getToRestore(); if (assetsToRestore.isNotEmpty) { - final restoredIds = await _localFilesManager.restoreAssetsFromTrash(assetsToRestore); + final restoredIds = await _assetMediaRepository.restoreAssetsFromTrash(assetsToRestore); await _trashedLocalAssetRepository.applyRestoredAssets(restoredIds); } else { _logger.info("No remote assets found for restoration"); @@ -523,7 +515,7 @@ class SyncStreamService { } Future _syncAssetTrashStatus(List remoteIds) async { - if (!(await _localFilesManager.hasManageMediaPermission())) { + if (!(await _permissionRepository.hasManageMediaPermission())) { _logger.warning("Syncing asset trash status cannot proceed because MANAGE_MEDIA permission is missing"); return; } @@ -533,7 +525,7 @@ class SyncStreamService { } Future _syncAssetDeletion(List remoteIds) async { - if (!(await _localFilesManager.hasManageMediaPermission())) { + if (!(await _permissionRepository.hasManageMediaPermission())) { _logger.warning("Syncing asset deletion cannot proceed because MANAGE_MEDIA permission is missing"); return; } diff --git a/mobile/lib/domain/services/timeline.service.dart b/mobile/lib/domain/services/timeline.service.dart index 5779ee1053..4cc58b0fe7 100644 --- a/mobile/lib/domain/services/timeline.service.dart +++ b/mobile/lib/domain/services/timeline.service.dart @@ -7,7 +7,7 @@ import 'package:immich_mobile/domain/models/asset/base_asset.model.dart'; import 'package:immich_mobile/domain/models/events.model.dart'; import 'package:immich_mobile/domain/models/timeline.model.dart'; import 'package:immich_mobile/domain/utils/event_stream.dart'; -import 'package:immich_mobile/infrastructure/repositories/metadata.repository.dart'; +import 'package:immich_mobile/infrastructure/repositories/settings.repository.dart'; import 'package:immich_mobile/infrastructure/repositories/timeline.repository.dart'; import 'package:immich_mobile/utils/async_mutex.dart'; @@ -39,16 +39,12 @@ enum TimelineOrigin { class TimelineFactory { final DriftTimelineRepository _timelineRepository; - final MetadataRepository _metadataRepository; + final SettingsRepository _settingsRepository; - const TimelineFactory({ - required DriftTimelineRepository timelineRepository, - required MetadataRepository metadataRepository, - }) : _timelineRepository = timelineRepository, - _metadataRepository = metadataRepository; + const TimelineFactory({required this._timelineRepository, required this._settingsRepository}); GroupAssetsBy get groupBy { - final group = _metadataRepository.appConfig.timeline.groupAssetsBy; + final group = _settingsRepository.appConfig.timeline.groupAssetsBy; // We do not support auto grouping in the new timeline yet, fallback to day grouping return group == GroupAssetsBy.auto ? GroupAssetsBy.day : group; } @@ -108,12 +104,7 @@ class TimelineService { TimelineService(TimelineQuery query) : this._(assetSource: query.assetSource, bucketSource: query.bucketSource, origin: query.origin); - TimelineService._({ - required TimelineAssetSource assetSource, - required TimelineBucketSource bucketSource, - required this.origin, - }) : _assetSource = assetSource, - _bucketSource = bucketSource { + TimelineService._({required this._assetSource, required this._bucketSource, required this.origin}) { _bucketSubscription = _bucketSource().listen((buckets) { _mutex.run(() async { final totalAssets = buckets.fold(0, (acc, bucket) => acc + bucket.assetCount); diff --git a/mobile/lib/domain/services/user.service.dart b/mobile/lib/domain/services/user.service.dart index e7b4b0f4e6..d5c1a6c4f7 100644 --- a/mobile/lib/domain/services/user.service.dart +++ b/mobile/lib/domain/services/user.service.dart @@ -12,9 +12,7 @@ class UserService { final UserApiRepository _userApiRepository; final StoreService _storeService; - UserService({required UserApiRepository userApiRepository, required StoreService storeService}) - : _userApiRepository = userApiRepository, - _storeService = storeService; + UserService({required this._userApiRepository, required this._storeService}); UserDto getMyUser() { return _storeService.get(StoreKey.currentUser); diff --git a/mobile/lib/infrastructure/entities/metadata.entity.dart b/mobile/lib/infrastructure/entities/settings.entity.dart similarity index 72% rename from mobile/lib/infrastructure/entities/metadata.entity.dart rename to mobile/lib/infrastructure/entities/settings.entity.dart index 2908245040..36e0bcc990 100644 --- a/mobile/lib/infrastructure/entities/metadata.entity.dart +++ b/mobile/lib/infrastructure/entities/settings.entity.dart @@ -1,8 +1,8 @@ import 'package:drift/drift.dart'; import 'package:immich_mobile/infrastructure/utils/drift_default.mixin.dart'; -class MetadataEntity extends Table with DriftDefaultsMixin { - const MetadataEntity(); +class SettingsEntity extends Table with DriftDefaultsMixin { + const SettingsEntity(); TextColumn get key => text()(); @@ -14,5 +14,5 @@ class MetadataEntity extends Table with DriftDefaultsMixin { Set get primaryKey => {key}; @override - String get tableName => "metadata"; + String get tableName => "settings"; } diff --git a/mobile/lib/infrastructure/entities/metadata.entity.drift.dart b/mobile/lib/infrastructure/entities/settings.entity.drift.dart similarity index 74% rename from mobile/lib/infrastructure/entities/metadata.entity.drift.dart rename to mobile/lib/infrastructure/entities/settings.entity.drift.dart index 80bf7bfc43..e2cac89a5e 100644 --- a/mobile/lib/infrastructure/entities/metadata.entity.drift.dart +++ b/mobile/lib/infrastructure/entities/settings.entity.drift.dart @@ -1,28 +1,28 @@ // dart format width=80 // ignore_for_file: type=lint import 'package:drift/drift.dart' as i0; -import 'package:immich_mobile/infrastructure/entities/metadata.entity.drift.dart' +import 'package:immich_mobile/infrastructure/entities/settings.entity.drift.dart' as i1; -import 'package:immich_mobile/infrastructure/entities/metadata.entity.dart' +import 'package:immich_mobile/infrastructure/entities/settings.entity.dart' as i2; import 'package:drift/src/runtime/query_builder/query_builder.dart' as i3; -typedef $$MetadataEntityTableCreateCompanionBuilder = - i1.MetadataEntityCompanion Function({ +typedef $$SettingsEntityTableCreateCompanionBuilder = + i1.SettingsEntityCompanion Function({ required String key, required String value, i0.Value updatedAt, }); -typedef $$MetadataEntityTableUpdateCompanionBuilder = - i1.MetadataEntityCompanion Function({ +typedef $$SettingsEntityTableUpdateCompanionBuilder = + i1.SettingsEntityCompanion Function({ i0.Value key, i0.Value value, i0.Value updatedAt, }); -class $$MetadataEntityTableFilterComposer - extends i0.Composer { - $$MetadataEntityTableFilterComposer({ +class $$SettingsEntityTableFilterComposer + extends i0.Composer { + $$SettingsEntityTableFilterComposer({ required super.$db, required super.$table, super.joinBuilder, @@ -45,9 +45,9 @@ class $$MetadataEntityTableFilterComposer ); } -class $$MetadataEntityTableOrderingComposer - extends i0.Composer { - $$MetadataEntityTableOrderingComposer({ +class $$SettingsEntityTableOrderingComposer + extends i0.Composer { + $$SettingsEntityTableOrderingComposer({ required super.$db, required super.$table, super.joinBuilder, @@ -70,9 +70,9 @@ class $$MetadataEntityTableOrderingComposer ); } -class $$MetadataEntityTableAnnotationComposer - extends i0.Composer { - $$MetadataEntityTableAnnotationComposer({ +class $$SettingsEntityTableAnnotationComposer + extends i0.Composer { + $$SettingsEntityTableAnnotationComposer({ required super.$db, required super.$table, super.joinBuilder, @@ -89,47 +89,47 @@ class $$MetadataEntityTableAnnotationComposer $composableBuilder(column: $table.updatedAt, builder: (column) => column); } -class $$MetadataEntityTableTableManager +class $$SettingsEntityTableTableManager extends i0.RootTableManager< i0.GeneratedDatabase, - i1.$MetadataEntityTable, - i1.MetadataEntityData, - i1.$$MetadataEntityTableFilterComposer, - i1.$$MetadataEntityTableOrderingComposer, - i1.$$MetadataEntityTableAnnotationComposer, - $$MetadataEntityTableCreateCompanionBuilder, - $$MetadataEntityTableUpdateCompanionBuilder, + i1.$SettingsEntityTable, + i1.SettingsEntityData, + i1.$$SettingsEntityTableFilterComposer, + i1.$$SettingsEntityTableOrderingComposer, + i1.$$SettingsEntityTableAnnotationComposer, + $$SettingsEntityTableCreateCompanionBuilder, + $$SettingsEntityTableUpdateCompanionBuilder, ( - i1.MetadataEntityData, + i1.SettingsEntityData, i0.BaseReferences< i0.GeneratedDatabase, - i1.$MetadataEntityTable, - i1.MetadataEntityData + i1.$SettingsEntityTable, + i1.SettingsEntityData >, ), - i1.MetadataEntityData, + i1.SettingsEntityData, i0.PrefetchHooks Function() > { - $$MetadataEntityTableTableManager( + $$SettingsEntityTableTableManager( i0.GeneratedDatabase db, - i1.$MetadataEntityTable table, + i1.$SettingsEntityTable table, ) : super( i0.TableManagerState( db: db, table: table, createFilteringComposer: () => - i1.$$MetadataEntityTableFilterComposer($db: db, $table: table), + i1.$$SettingsEntityTableFilterComposer($db: db, $table: table), createOrderingComposer: () => - i1.$$MetadataEntityTableOrderingComposer($db: db, $table: table), + i1.$$SettingsEntityTableOrderingComposer($db: db, $table: table), createComputedFieldComposer: () => i1 - .$$MetadataEntityTableAnnotationComposer($db: db, $table: table), + .$$SettingsEntityTableAnnotationComposer($db: db, $table: table), updateCompanionCallback: ({ i0.Value key = const i0.Value.absent(), i0.Value value = const i0.Value.absent(), i0.Value updatedAt = const i0.Value.absent(), - }) => i1.MetadataEntityCompanion( + }) => i1.SettingsEntityCompanion( key: key, value: value, updatedAt: updatedAt, @@ -139,7 +139,7 @@ class $$MetadataEntityTableTableManager required String key, required String value, i0.Value updatedAt = const i0.Value.absent(), - }) => i1.MetadataEntityCompanion.insert( + }) => i1.SettingsEntityCompanion.insert( key: key, value: value, updatedAt: updatedAt, @@ -152,34 +152,34 @@ class $$MetadataEntityTableTableManager ); } -typedef $$MetadataEntityTableProcessedTableManager = +typedef $$SettingsEntityTableProcessedTableManager = i0.ProcessedTableManager< i0.GeneratedDatabase, - i1.$MetadataEntityTable, - i1.MetadataEntityData, - i1.$$MetadataEntityTableFilterComposer, - i1.$$MetadataEntityTableOrderingComposer, - i1.$$MetadataEntityTableAnnotationComposer, - $$MetadataEntityTableCreateCompanionBuilder, - $$MetadataEntityTableUpdateCompanionBuilder, + i1.$SettingsEntityTable, + i1.SettingsEntityData, + i1.$$SettingsEntityTableFilterComposer, + i1.$$SettingsEntityTableOrderingComposer, + i1.$$SettingsEntityTableAnnotationComposer, + $$SettingsEntityTableCreateCompanionBuilder, + $$SettingsEntityTableUpdateCompanionBuilder, ( - i1.MetadataEntityData, + i1.SettingsEntityData, i0.BaseReferences< i0.GeneratedDatabase, - i1.$MetadataEntityTable, - i1.MetadataEntityData + i1.$SettingsEntityTable, + i1.SettingsEntityData >, ), - i1.MetadataEntityData, + i1.SettingsEntityData, i0.PrefetchHooks Function() >; -class $MetadataEntityTable extends i2.MetadataEntity - with i0.TableInfo<$MetadataEntityTable, i1.MetadataEntityData> { +class $SettingsEntityTable extends i2.SettingsEntity + with i0.TableInfo<$SettingsEntityTable, i1.SettingsEntityData> { @override final i0.GeneratedDatabase attachedDatabase; final String? _alias; - $MetadataEntityTable(this.attachedDatabase, [this._alias]); + $SettingsEntityTable(this.attachedDatabase, [this._alias]); static const i0.VerificationMeta _keyMeta = const i0.VerificationMeta('key'); @override late final i0.GeneratedColumn key = i0.GeneratedColumn( @@ -219,10 +219,10 @@ class $MetadataEntityTable extends i2.MetadataEntity String get aliasedName => _alias ?? actualTableName; @override String get actualTableName => $name; - static const String $name = 'metadata'; + static const String $name = 'settings'; @override i0.VerificationContext validateIntegrity( - i0.Insertable instance, { + i0.Insertable instance, { bool isInserting = false, }) { final context = i0.VerificationContext(); @@ -255,9 +255,9 @@ class $MetadataEntityTable extends i2.MetadataEntity @override Set get $primaryKey => {key}; @override - i1.MetadataEntityData map(Map data, {String? tablePrefix}) { + i1.SettingsEntityData map(Map data, {String? tablePrefix}) { final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; - return i1.MetadataEntityData( + return i1.SettingsEntityData( key: attachedDatabase.typeMapping.read( i0.DriftSqlType.string, data['${effectivePrefix}key'], @@ -274,8 +274,8 @@ class $MetadataEntityTable extends i2.MetadataEntity } @override - $MetadataEntityTable createAlias(String alias) { - return $MetadataEntityTable(attachedDatabase, alias); + $SettingsEntityTable createAlias(String alias) { + return $SettingsEntityTable(attachedDatabase, alias); } @override @@ -284,12 +284,12 @@ class $MetadataEntityTable extends i2.MetadataEntity bool get isStrict => true; } -class MetadataEntityData extends i0.DataClass - implements i0.Insertable { +class SettingsEntityData extends i0.DataClass + implements i0.Insertable { final String key; final String value; final DateTime updatedAt; - const MetadataEntityData({ + const SettingsEntityData({ required this.key, required this.value, required this.updatedAt, @@ -303,12 +303,12 @@ class MetadataEntityData extends i0.DataClass return map; } - factory MetadataEntityData.fromJson( + factory SettingsEntityData.fromJson( Map json, { i0.ValueSerializer? serializer, }) { serializer ??= i0.driftRuntimeOptions.defaultSerializer; - return MetadataEntityData( + return SettingsEntityData( key: serializer.fromJson(json['key']), value: serializer.fromJson(json['value']), updatedAt: serializer.fromJson(json['updatedAt']), @@ -324,17 +324,17 @@ class MetadataEntityData extends i0.DataClass }; } - i1.MetadataEntityData copyWith({ + i1.SettingsEntityData copyWith({ String? key, String? value, DateTime? updatedAt, - }) => i1.MetadataEntityData( + }) => i1.SettingsEntityData( key: key ?? this.key, value: value ?? this.value, updatedAt: updatedAt ?? this.updatedAt, ); - MetadataEntityData copyWithCompanion(i1.MetadataEntityCompanion data) { - return MetadataEntityData( + SettingsEntityData copyWithCompanion(i1.SettingsEntityCompanion data) { + return SettingsEntityData( key: data.key.present ? data.key.value : this.key, value: data.value.present ? data.value.value : this.value, updatedAt: data.updatedAt.present ? data.updatedAt.value : this.updatedAt, @@ -343,7 +343,7 @@ class MetadataEntityData extends i0.DataClass @override String toString() { - return (StringBuffer('MetadataEntityData(') + return (StringBuffer('SettingsEntityData(') ..write('key: $key, ') ..write('value: $value, ') ..write('updatedAt: $updatedAt') @@ -356,29 +356,29 @@ class MetadataEntityData extends i0.DataClass @override bool operator ==(Object other) => identical(this, other) || - (other is i1.MetadataEntityData && + (other is i1.SettingsEntityData && other.key == this.key && other.value == this.value && other.updatedAt == this.updatedAt); } -class MetadataEntityCompanion - extends i0.UpdateCompanion { +class SettingsEntityCompanion + extends i0.UpdateCompanion { final i0.Value key; final i0.Value value; final i0.Value updatedAt; - const MetadataEntityCompanion({ + const SettingsEntityCompanion({ this.key = const i0.Value.absent(), this.value = const i0.Value.absent(), this.updatedAt = const i0.Value.absent(), }); - MetadataEntityCompanion.insert({ + SettingsEntityCompanion.insert({ required String key, required String value, this.updatedAt = const i0.Value.absent(), }) : key = i0.Value(key), value = i0.Value(value); - static i0.Insertable custom({ + static i0.Insertable custom({ i0.Expression? key, i0.Expression? value, i0.Expression? updatedAt, @@ -390,12 +390,12 @@ class MetadataEntityCompanion }); } - i1.MetadataEntityCompanion copyWith({ + i1.SettingsEntityCompanion copyWith({ i0.Value? key, i0.Value? value, i0.Value? updatedAt, }) { - return i1.MetadataEntityCompanion( + return i1.SettingsEntityCompanion( key: key ?? this.key, value: value ?? this.value, updatedAt: updatedAt ?? this.updatedAt, @@ -419,7 +419,7 @@ class MetadataEntityCompanion @override String toString() { - return (StringBuffer('MetadataEntityCompanion(') + return (StringBuffer('SettingsEntityCompanion(') ..write('key: $key, ') ..write('value: $value, ') ..write('updatedAt: $updatedAt') diff --git a/mobile/lib/infrastructure/repositories/db.repository.dart b/mobile/lib/infrastructure/repositories/db.repository.dart index e81fe58ba9..6bb2e946f1 100644 --- a/mobile/lib/infrastructure/repositories/db.repository.dart +++ b/mobile/lib/infrastructure/repositories/db.repository.dart @@ -13,7 +13,7 @@ import 'package:immich_mobile/infrastructure/entities/local_asset.entity.dart'; import 'package:immich_mobile/infrastructure/entities/local_asset.entity.drift.dart'; import 'package:immich_mobile/infrastructure/entities/memory.entity.dart'; import 'package:immich_mobile/infrastructure/entities/memory_asset.entity.dart'; -import 'package:immich_mobile/infrastructure/entities/metadata.entity.dart'; +import 'package:immich_mobile/infrastructure/entities/settings.entity.dart'; import 'package:immich_mobile/infrastructure/entities/partner.entity.dart'; import 'package:immich_mobile/infrastructure/entities/person.entity.dart'; import 'package:immich_mobile/infrastructure/entities/remote_album.entity.dart'; @@ -55,7 +55,7 @@ import 'package:logging/logging.dart'; StoreEntity, TrashedLocalAssetEntity, AssetEditEntity, - MetadataEntity, + SettingsEntity, ], include: {'package:immich_mobile/infrastructure/entities/merged_asset.drift'}, ) @@ -98,7 +98,7 @@ class Drift extends $Drift { } @override - int get schemaVersion => 26; + int get schemaVersion => 27; @override MigrationStrategy get migration => MigrationStrategy( @@ -276,6 +276,9 @@ class Drift extends $Drift { from25To26: (m, v26) async { await m.addColumn(v26.remoteAssetEntity, v26.remoteAssetEntity.uploadedAt); }, + from26To27: (m, v27) async { + await customStatement('ALTER TABLE metadata RENAME TO settings'); + }, ), ); diff --git a/mobile/lib/infrastructure/repositories/db.repository.drift.dart b/mobile/lib/infrastructure/repositories/db.repository.drift.dart index c43a83f86a..692523219b 100644 --- a/mobile/lib/infrastructure/repositories/db.repository.drift.dart +++ b/mobile/lib/infrastructure/repositories/db.repository.drift.dart @@ -43,7 +43,7 @@ import 'package:immich_mobile/infrastructure/entities/trashed_local_asset.entity as i20; import 'package:immich_mobile/infrastructure/entities/asset_edit.entity.drift.dart' as i21; -import 'package:immich_mobile/infrastructure/entities/metadata.entity.drift.dart' +import 'package:immich_mobile/infrastructure/entities/settings.entity.drift.dart' as i22; import 'package:immich_mobile/infrastructure/entities/merged_asset.drift.dart' as i23; @@ -91,7 +91,7 @@ abstract class $Drift extends i0.GeneratedDatabase { .$TrashedLocalAssetEntityTable(this); late final i21.$AssetEditEntityTable assetEditEntity = i21 .$AssetEditEntityTable(this); - late final i22.$MetadataEntityTable metadataEntity = i22.$MetadataEntityTable( + late final i22.$SettingsEntityTable settingsEntity = i22.$SettingsEntityTable( this, ); i23.MergedAssetDrift get mergedAssetDrift => i24.ReadDatabaseContainer( @@ -132,7 +132,7 @@ abstract class $Drift extends i0.GeneratedDatabase { storeEntity, trashedLocalAssetEntity, assetEditEntity, - metadataEntity, + settingsEntity, i10.idxPartnerSharedWithId, i11.idxLatLng, i11.idxRemoteExifCity, @@ -395,6 +395,6 @@ class $DriftManager { ); i21.$$AssetEditEntityTableTableManager get assetEditEntity => i21.$$AssetEditEntityTableTableManager(_db, _db.assetEditEntity); - i22.$$MetadataEntityTableTableManager get metadataEntity => - i22.$$MetadataEntityTableTableManager(_db, _db.metadataEntity); + i22.$$SettingsEntityTableTableManager get settingsEntity => + i22.$$SettingsEntityTableTableManager(_db, _db.settingsEntity); } diff --git a/mobile/lib/infrastructure/repositories/db.repository.steps.dart b/mobile/lib/infrastructure/repositories/db.repository.steps.dart index 1fb88de1d0..a51174d980 100644 --- a/mobile/lib/infrastructure/repositories/db.repository.steps.dart +++ b/mobile/lib/infrastructure/repositories/db.repository.steps.dart @@ -13539,6 +13539,550 @@ i1.GeneratedColumn _column_212(String aliasedName) => type: i1.DriftSqlType.string, $customConstraints: 'NULL', ); + +final class Schema27 extends i0.VersionedSchema { + Schema27({required super.database}) : super(version: 27); + @override + late final List entities = [ + userEntity, + remoteAssetEntity, + stackEntity, + localAssetEntity, + remoteAlbumEntity, + localAlbumEntity, + localAlbumAssetEntity, + idxLocalAlbumAssetAlbumAsset, + idxLocalAssetChecksum, + idxLocalAssetCloudId, + idxStackPrimaryAssetId, + uQRemoteAssetsOwnerChecksum, + uQRemoteAssetsOwnerLibraryChecksum, + idxRemoteAssetChecksum, + idxRemoteAssetStackId, + idxRemoteAssetOwnerVisibilityDeletedCreated, + authUserEntity, + userMetadataEntity, + partnerEntity, + remoteExifEntity, + remoteAlbumAssetEntity, + remoteAlbumUserEntity, + remoteAssetCloudIdEntity, + memoryEntity, + memoryAssetEntity, + personEntity, + assetFaceEntity, + storeEntity, + trashedLocalAssetEntity, + assetEditEntity, + settings, + idxPartnerSharedWithId, + idxLatLng, + idxRemoteExifCity, + idxRemoteAlbumAssetAlbumAsset, + idxRemoteAssetCloudId, + idxPersonOwnerId, + idxAssetFacePersonId, + idxAssetFaceAssetId, + idxAssetFaceVisiblePerson, + idxTrashedLocalAssetChecksum, + idxTrashedLocalAssetAlbum, + idxAssetEditAssetId, + ]; + late final Shape33 userEntity = Shape33( + source: i0.VersionedTable( + entityName: 'user_entity', + withoutRowId: true, + isStrict: true, + tableConstraints: ['PRIMARY KEY(id)'], + columns: [ + _column_107, + _column_108, + _column_109, + _column_110, + _column_111, + _column_112, + ], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape50 remoteAssetEntity = Shape50( + source: i0.VersionedTable( + entityName: 'remote_asset_entity', + withoutRowId: true, + isStrict: true, + tableConstraints: ['PRIMARY KEY(id)'], + columns: [ + _column_108, + _column_113, + _column_114, + _column_115, + _column_116, + _column_117, + _column_118, + _column_107, + _column_119, + _column_120, + _column_121, + _column_122, + _column_123, + _column_124, + _column_212, + _column_125, + _column_126, + _column_127, + _column_128, + _column_129, + ], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape35 stackEntity = Shape35( + source: i0.VersionedTable( + entityName: 'stack_entity', + withoutRowId: true, + isStrict: true, + tableConstraints: ['PRIMARY KEY(id)'], + columns: [ + _column_107, + _column_114, + _column_115, + _column_121, + _column_130, + ], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape36 localAssetEntity = Shape36( + source: i0.VersionedTable( + entityName: 'local_asset_entity', + withoutRowId: true, + isStrict: true, + tableConstraints: ['PRIMARY KEY(id)'], + columns: [ + _column_108, + _column_113, + _column_114, + _column_115, + _column_116, + _column_117, + _column_118, + _column_107, + _column_131, + _column_120, + _column_132, + _column_133, + _column_134, + _column_135, + _column_136, + _column_137, + ], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape48 remoteAlbumEntity = Shape48( + source: i0.VersionedTable( + entityName: 'remote_album_entity', + withoutRowId: true, + isStrict: true, + tableConstraints: ['PRIMARY KEY(id)'], + columns: [ + _column_107, + _column_108, + _column_138, + _column_114, + _column_115, + _column_139, + _column_140, + _column_141, + ], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape38 localAlbumEntity = Shape38( + source: i0.VersionedTable( + entityName: 'local_album_entity', + withoutRowId: true, + isStrict: true, + tableConstraints: ['PRIMARY KEY(id)'], + columns: [ + _column_107, + _column_108, + _column_115, + _column_142, + _column_143, + _column_144, + _column_145, + ], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape39 localAlbumAssetEntity = Shape39( + source: i0.VersionedTable( + entityName: 'local_album_asset_entity', + withoutRowId: true, + isStrict: true, + tableConstraints: ['PRIMARY KEY(asset_id, album_id)'], + columns: [_column_146, _column_147, _column_145], + attachedDatabase: database, + ), + alias: null, + ); + final i1.Index idxLocalAlbumAssetAlbumAsset = i1.Index( + 'idx_local_album_asset_album_asset', + 'CREATE INDEX IF NOT EXISTS idx_local_album_asset_album_asset ON local_album_asset_entity (album_id, asset_id)', + ); + 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 idxLocalAssetCloudId = i1.Index( + 'idx_local_asset_cloud_id', + 'CREATE INDEX IF NOT EXISTS idx_local_asset_cloud_id ON local_asset_entity (i_cloud_id)', + ); + final i1.Index idxStackPrimaryAssetId = i1.Index( + 'idx_stack_primary_asset_id', + 'CREATE INDEX IF NOT EXISTS idx_stack_primary_asset_id ON stack_entity (primary_asset_id)', + ); + 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)', + ); + final i1.Index idxRemoteAssetStackId = i1.Index( + 'idx_remote_asset_stack_id', + 'CREATE INDEX IF NOT EXISTS idx_remote_asset_stack_id ON remote_asset_entity (stack_id)', + ); + final i1.Index idxRemoteAssetOwnerVisibilityDeletedCreated = i1.Index( + 'idx_remote_asset_owner_visibility_deleted_created', + 'CREATE INDEX IF NOT EXISTS idx_remote_asset_owner_visibility_deleted_created ON remote_asset_entity (owner_id, visibility, deleted_at, created_at DESC)', + ); + late final Shape40 authUserEntity = Shape40( + source: i0.VersionedTable( + entityName: 'auth_user_entity', + withoutRowId: true, + isStrict: true, + tableConstraints: ['PRIMARY KEY(id)'], + columns: [ + _column_107, + _column_108, + _column_109, + _column_148, + _column_110, + _column_111, + _column_149, + _column_150, + _column_151, + _column_152, + ], + 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_153, _column_154, _column_155], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape41 partnerEntity = Shape41( + source: i0.VersionedTable( + entityName: 'partner_entity', + withoutRowId: true, + isStrict: true, + tableConstraints: ['PRIMARY KEY(shared_by_id, shared_with_id)'], + columns: [_column_156, _column_157, _column_158], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape42 remoteExifEntity = Shape42( + source: i0.VersionedTable( + entityName: 'remote_exif_entity', + withoutRowId: true, + isStrict: true, + tableConstraints: ['PRIMARY KEY(asset_id)'], + columns: [ + _column_159, + _column_160, + _column_161, + _column_162, + _column_163, + _column_164, + _column_117, + _column_116, + _column_165, + _column_166, + _column_167, + _column_168, + _column_135, + _column_136, + _column_169, + _column_170, + _column_171, + _column_172, + _column_173, + _column_174, + _column_175, + _column_176, + ], + 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_159, _column_177], + 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_177, _column_153, _column_178], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape43 remoteAssetCloudIdEntity = Shape43( + source: i0.VersionedTable( + entityName: 'remote_asset_cloud_id_entity', + withoutRowId: true, + isStrict: true, + tableConstraints: ['PRIMARY KEY(asset_id)'], + columns: [ + _column_159, + _column_179, + _column_180, + _column_134, + _column_135, + _column_136, + ], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape44 memoryEntity = Shape44( + source: i0.VersionedTable( + entityName: 'memory_entity', + withoutRowId: true, + isStrict: true, + tableConstraints: ['PRIMARY KEY(id)'], + columns: [ + _column_107, + _column_114, + _column_115, + _column_124, + _column_121, + _column_113, + _column_181, + _column_182, + _column_183, + _column_184, + _column_185, + _column_186, + ], + 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_159, _column_187], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape45 personEntity = Shape45( + source: i0.VersionedTable( + entityName: 'person_entity', + withoutRowId: true, + isStrict: true, + tableConstraints: ['PRIMARY KEY(id)'], + columns: [ + _column_107, + _column_114, + _column_115, + _column_121, + _column_108, + _column_188, + _column_189, + _column_190, + _column_191, + _column_192, + ], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape46 assetFaceEntity = Shape46( + source: i0.VersionedTable( + entityName: 'asset_face_entity', + withoutRowId: true, + isStrict: true, + tableConstraints: ['PRIMARY KEY(id)'], + columns: [ + _column_107, + _column_159, + _column_193, + _column_194, + _column_195, + _column_196, + _column_197, + _column_198, + _column_199, + _column_200, + _column_201, + _column_124, + ], + 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_202, _column_203, _column_204], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape47 trashedLocalAssetEntity = Shape47( + source: i0.VersionedTable( + entityName: 'trashed_local_asset_entity', + withoutRowId: true, + isStrict: true, + tableConstraints: ['PRIMARY KEY(id, album_id)'], + columns: [ + _column_108, + _column_113, + _column_114, + _column_115, + _column_116, + _column_117, + _column_118, + _column_107, + _column_205, + _column_131, + _column_120, + _column_132, + _column_206, + _column_137, + ], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape32 assetEditEntity = Shape32( + source: i0.VersionedTable( + entityName: 'asset_edit_entity', + withoutRowId: true, + isStrict: true, + tableConstraints: ['PRIMARY KEY(id)'], + columns: [ + _column_107, + _column_159, + _column_207, + _column_208, + _column_209, + ], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape49 settings = Shape49( + source: i0.VersionedTable( + entityName: 'settings', + withoutRowId: true, + isStrict: true, + tableConstraints: ['PRIMARY KEY("key")'], + columns: [_column_210, _column_211, _column_115], + attachedDatabase: database, + ), + alias: null, + ); + final i1.Index idxPartnerSharedWithId = i1.Index( + 'idx_partner_shared_with_id', + 'CREATE INDEX IF NOT EXISTS idx_partner_shared_with_id ON partner_entity (shared_with_id)', + ); + final i1.Index idxLatLng = i1.Index( + 'idx_lat_lng', + 'CREATE INDEX IF NOT EXISTS idx_lat_lng ON remote_exif_entity (latitude, longitude)', + ); + final i1.Index idxRemoteExifCity = i1.Index( + 'idx_remote_exif_city', + 'CREATE INDEX IF NOT EXISTS idx_remote_exif_city ON remote_exif_entity (city) WHERE city IS NOT NULL', + ); + final i1.Index idxRemoteAlbumAssetAlbumAsset = i1.Index( + 'idx_remote_album_asset_album_asset', + 'CREATE INDEX IF NOT EXISTS idx_remote_album_asset_album_asset ON remote_album_asset_entity (album_id, asset_id)', + ); + final i1.Index idxRemoteAssetCloudId = i1.Index( + 'idx_remote_asset_cloud_id', + 'CREATE INDEX IF NOT EXISTS idx_remote_asset_cloud_id ON remote_asset_cloud_id_entity (cloud_id)', + ); + final i1.Index idxPersonOwnerId = i1.Index( + 'idx_person_owner_id', + 'CREATE INDEX IF NOT EXISTS idx_person_owner_id ON person_entity (owner_id)', + ); + final i1.Index idxAssetFacePersonId = i1.Index( + 'idx_asset_face_person_id', + 'CREATE INDEX IF NOT EXISTS idx_asset_face_person_id ON asset_face_entity (person_id)', + ); + final i1.Index idxAssetFaceAssetId = i1.Index( + 'idx_asset_face_asset_id', + 'CREATE INDEX IF NOT EXISTS idx_asset_face_asset_id ON asset_face_entity (asset_id)', + ); + final i1.Index idxAssetFaceVisiblePerson = i1.Index( + 'idx_asset_face_visible_person', + 'CREATE INDEX IF NOT EXISTS idx_asset_face_visible_person ON asset_face_entity (person_id, asset_id) WHERE is_visible = 1 AND deleted_at IS NULL', + ); + final i1.Index idxTrashedLocalAssetChecksum = i1.Index( + 'idx_trashed_local_asset_checksum', + 'CREATE INDEX IF NOT EXISTS idx_trashed_local_asset_checksum ON trashed_local_asset_entity (checksum)', + ); + final i1.Index idxTrashedLocalAssetAlbum = i1.Index( + 'idx_trashed_local_asset_album', + 'CREATE INDEX IF NOT EXISTS idx_trashed_local_asset_album ON trashed_local_asset_entity (album_id)', + ); + final i1.Index idxAssetEditAssetId = i1.Index( + 'idx_asset_edit_asset_id', + 'CREATE INDEX IF NOT EXISTS idx_asset_edit_asset_id ON asset_edit_entity (asset_id)', + ); +} + i0.MigrationStepWithVersion migrationSteps({ required Future Function(i1.Migrator m, Schema2 schema) from1To2, required Future Function(i1.Migrator m, Schema3 schema) from2To3, @@ -13565,6 +14109,7 @@ i0.MigrationStepWithVersion migrationSteps({ required Future Function(i1.Migrator m, Schema24 schema) from23To24, required Future Function(i1.Migrator m, Schema25 schema) from24To25, required Future Function(i1.Migrator m, Schema26 schema) from25To26, + required Future Function(i1.Migrator m, Schema27 schema) from26To27, }) { return (currentVersion, database) async { switch (currentVersion) { @@ -13693,6 +14238,11 @@ i0.MigrationStepWithVersion migrationSteps({ final migrator = i1.Migrator(database, schema); await from25To26(migrator, schema); return 26; + case 26: + final schema = Schema27(database: database); + final migrator = i1.Migrator(database, schema); + await from26To27(migrator, schema); + return 27; default: throw ArgumentError.value('Unknown migration from $currentVersion'); } @@ -13725,6 +14275,7 @@ i1.OnUpgrade stepByStep({ required Future Function(i1.Migrator m, Schema24 schema) from23To24, required Future Function(i1.Migrator m, Schema25 schema) from24To25, required Future Function(i1.Migrator m, Schema26 schema) from25To26, + required Future Function(i1.Migrator m, Schema27 schema) from26To27, }) => i0.VersionedSchema.stepByStepHelper( step: migrationSteps( from1To2: from1To2, @@ -13752,5 +14303,6 @@ i1.OnUpgrade stepByStep({ from23To24: from23To24, from24To25: from24To25, from25To26: from25To26, + from26To27: from26To27, ), ); diff --git a/mobile/lib/infrastructure/repositories/metadata.repository.dart b/mobile/lib/infrastructure/repositories/metadata.repository.dart deleted file mode 100644 index fa1d275026..0000000000 --- a/mobile/lib/infrastructure/repositories/metadata.repository.dart +++ /dev/null @@ -1,177 +0,0 @@ -import 'package:drift/drift.dart'; -import 'package:immich_mobile/domain/models/config/app_config.dart'; -import 'package:immich_mobile/domain/models/config/system_config.dart'; -import 'package:immich_mobile/domain/models/metadata_key.dart'; -import 'package:immich_mobile/extensions/string_extensions.dart'; -import 'package:immich_mobile/infrastructure/entities/metadata.entity.drift.dart'; -import 'package:immich_mobile/infrastructure/repositories/db.repository.dart'; - -class MetadataRepository extends DriftDatabaseRepository { - final Drift _db; - final Map _cache = {}; - - MetadataRepository._(this._db) : super(_db); - - static MetadataRepository? _instance; - - static MetadataRepository get instance { - final instance = _instance; - if (instance == null) { - throw StateError('MetadataRepository not initialized. Call ensureInitialized() first'); - } - return instance; - } - - AppConfig _appConfig = const .new(); - AppConfig get appConfig => _appConfig; - - SystemConfig _systemConfig = const .new(); - SystemConfig get systemConfig => _systemConfig; - - static Future ensureInitialized(Drift db) async { - if (_instance == null) { - final instance = MetadataRepository._(db); - await instance._hydrate(); - _instance = instance; - } - return _instance!; - } - - static Future refresh() async { - instance._cache.clear(); - instance._appConfig = const .new(); - instance._systemConfig = const .new(); - await instance._hydrate(); - } - - Future _hydrate() async => _hydrateCache(await _db.select(_db.metadataEntity).get()); - - T _read(MetadataKey key) => (_cache[key] as T?) ?? key.defaultValue; - - Future write(MetadataKey key, U value) async { - if (_read(key) == value) { - return; - } - - await _db - .into(_db.metadataEntity) - .insertOnConflictUpdate( - MetadataEntityCompanion.insert(key: key.key, value: key.encode(value), updatedAt: Value(DateTime.now())), - ); - _updateCache(key, value); - } - - Future delete(MetadataKey key) async { - await (_db.delete(_db.metadataEntity)..where((t) => t.key.equals(key.key))).go(); - _updateCache(key, key.defaultValue); - } - - Stream watchAppConfig() => _watchDomain(.appConfig).distinct(); - - Stream watchSystemConfig() => _watchDomain(.systemConfig).distinct(); - - Stream _watchDomain(MetadataDomain domain) { - final query = _db.select(_db.metadataEntity)..where((t) => t.key.like('${domain.prefix}.%')); - return query.watch().map((rows) { - _hydrateCache(rows); - return domain.config(this); - }); - } - - void _hydrateCache(List rows) { - final keyMap = MetadataKey.asKeyMap(); - for (final row in rows) { - final key = keyMap[row.key]; - if (key == null) { - continue; - } - _updateCache(key, key.decode(row.value)); - } - } - - void _updateCache(MetadataKey key, T value) { - if (_cache[key] == value) { - return; - } - _cache[key] = value; - key.domain.rebuild(this); - } -} - -extension on MetadataDomain { - T config(MetadataRepository repo) => switch (this) { - .appConfig => repo._appConfig as T, - .systemConfig => repo._systemConfig as T, - }; - - void rebuild(MetadataRepository repo) { - switch (this) { - case .appConfig: - repo._appConfig = .new( - theme: .new( - mode: repo._read(.themeMode), - primaryColor: repo._read(.themePrimaryColor), - dynamicTheme: repo._read(.themeDynamic), - colorfulInterface: repo._read(.themeColorfulInterface), - ), - cleanup: .new( - keepFavorites: repo._read(.cleanupKeepFavorites), - keepMediaType: repo._read(.cleanupKeepMediaType), - keepAlbumIds: repo._read(.cleanupKeepAlbumIds), - cutoffDaysAgo: repo._read(.cleanupCutoffDaysAgo), - defaultsInitialized: repo._read(.cleanupDefaultsInitialized), - ), - map: .new( - relativeDays: repo._read(.mapRelativeDate), - favoritesOnly: repo._read(.mapShowFavoriteOnly), - includeArchived: repo._read(.mapIncludeArchived), - themeMode: repo._read(.mapThemeMode), - withPartners: repo._read(.mapWithPartners), - ), - timeline: .new( - tilesPerRow: repo._read(.timelineTilesPerRow), - groupAssetsBy: repo._read(.timelineGroupAssetsBy), - storageIndicator: repo._read(.timelineStorageIndicator), - ), - image: .new(preferRemote: repo._read(.imagePreferRemote), loadOriginal: repo._read(.imageLoadOriginal)), - viewer: .new( - loopVideo: repo._read(.viewerLoopVideo), - loadOriginalVideo: repo._read(.viewerLoadOriginalVideo), - autoPlayVideo: repo._read(.viewerAutoPlayVideo), - tapToNavigate: repo._read(.viewerTapToNavigate), - ), - slideshow: .new( - transition: repo._read(.slideshowTransition), - repeat: repo._read(.slideshowRepeat), - duration: repo._read(.slideshowDuration), - look: repo._read(.slideshowLook), - direction: repo._read(.slideshowDirection), - ), - album: .new( - sortMode: repo._read(.albumSortMode), - isReverse: repo._read(.albumIsReverse), - isGrid: repo._read(.albumIsGrid), - ), - backup: .new( - enabled: repo._read(.backupEnabled), - useCellularForVideos: repo._read(.backupUseCellularForVideos), - useCellularForPhotos: repo._read(.backupUseCellularForPhotos), - requireCharging: repo._read(.backupRequireCharging), - triggerDelay: repo._read(.backupTriggerDelay), - syncAlbums: repo._read(.backupSyncAlbums), - ), - ); - case .systemConfig: - repo._systemConfig = .new( - logLevel: repo._read(.logLevel), - network: .new( - autoEndpointSwitching: repo._read(.networkAutoEndpointSwitching), - preferredWifiName: repo._read(.networkPreferredWifiName).nullIfEmpty, - localEndpoint: repo._read(.networkLocalEndpoint).nullIfEmpty, - externalEndpointList: repo._read(.networkExternalEndpointList), - customHeaders: repo._read(.networkCustomHeaders), - ), - ); - } - } -} diff --git a/mobile/lib/infrastructure/repositories/settings.repository.dart b/mobile/lib/infrastructure/repositories/settings.repository.dart new file mode 100644 index 0000000000..56066f543a --- /dev/null +++ b/mobile/lib/infrastructure/repositories/settings.repository.dart @@ -0,0 +1,84 @@ +import 'package:collection/collection.dart'; +import 'package:drift/drift.dart'; +import 'package:immich_mobile/domain/models/config/app_config.dart'; +import 'package:immich_mobile/domain/models/settings_key.dart'; +import 'package:immich_mobile/infrastructure/entities/settings.entity.drift.dart'; +import 'package:immich_mobile/infrastructure/repositories/db.repository.dart'; + +class SettingsRepository extends DriftDatabaseRepository { + final Drift _db; + + SettingsRepository._(this._db) : super(_db); + + static SettingsRepository? _instance; + + static SettingsRepository get instance { + final instance = _instance; + if (instance == null) { + throw StateError('SettingsRepository not initialized. Call ensureInitialized() first'); + } + return instance; + } + + AppConfig _appConfig = const .new(); + AppConfig get appConfig => _appConfig; + + static Future ensureInitialized(Drift db) async { + if (_instance == null) { + final instance = SettingsRepository._(db); + await instance.refresh(); + _instance = instance; + } + return _instance!; + } + + Future refresh() async => _applyOverrides(await _db.select(_db.settingsEntity).get()); + + Future clear(Iterable keys) async { + if (keys.isEmpty) { + return; + } + + final names = keys.map((key) => key.name).toList(); + await (_db.delete(_db.settingsEntity)..where((row) => row.key.isIn(names))).go(); + + for (final key in keys) { + _appConfig = _appConfig.write(key, defaultConfig.read(key)); + } + } + + Future write(SettingsKey key, U value) async { + if (value == _appConfig.read(key)) { + return; + } + + if (value == defaultConfig.read(key)) { + return clear([key]); + } + + await _db + .into(_db.settingsEntity) + .insertOnConflictUpdate( + SettingsEntityCompanion.insert(key: key.name, value: key.encode(value), updatedAt: Value(DateTime.now())), + ); + _appConfig = _appConfig.write(key, value); + } + + Stream watchConfig() => _db.select(_db.settingsEntity).watch().map((rows) { + _applyOverrides(rows); + return _appConfig; + }); + + void _applyOverrides(List rows) { + _appConfig = AppConfig.fromEntries( + rows.fold({}, (overrides, row) { + final metadataKey = SettingsKey.values.firstWhereOrNull((key) => key.name == row.key); + if (metadataKey == null) { + return overrides; + } + + return {...overrides, metadataKey: metadataKey.decode(row.value)}; + }), + ); + } +} diff --git a/mobile/lib/main.dart b/mobile/lib/main.dart index 19455be61c..cc5f131572 100644 --- a/mobile/lib/main.dart +++ b/mobile/lib/main.dart @@ -25,7 +25,7 @@ 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/infrastructure/db.provider.dart'; -import 'package:immich_mobile/providers/infrastructure/metadata.provider.dart'; +import 'package:immich_mobile/providers/infrastructure/settings.provider.dart'; import 'package:immich_mobile/providers/infrastructure/platform.provider.dart'; import 'package:immich_mobile/providers/locale_provider.dart'; import 'package:immich_mobile/providers/routes.provider.dart'; 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 de37437326..f999e7671f 100644 --- a/mobile/lib/pages/backup/drift_backup_album_selection.page.dart +++ b/mobile/lib/pages/backup/drift_backup_album_selection.page.dart @@ -8,11 +8,11 @@ import 'package:immich_mobile/domain/models/album/local_album.model.dart'; import 'package:immich_mobile/domain/services/sync_linked_album.service.dart'; import 'package:immich_mobile/extensions/build_context_extensions.dart'; import 'package:immich_mobile/extensions/translate_extensions.dart'; -import 'package:immich_mobile/infrastructure/repositories/metadata.repository.dart'; +import 'package:immich_mobile/infrastructure/repositories/settings.repository.dart'; import 'package:immich_mobile/providers/background_sync.provider.dart'; import 'package:immich_mobile/providers/backup/backup_album.provider.dart'; import 'package:immich_mobile/providers/backup/drift_backup.provider.dart'; -import 'package:immich_mobile/providers/infrastructure/metadata.provider.dart'; +import 'package:immich_mobile/providers/infrastructure/settings.provider.dart'; import 'package:immich_mobile/providers/infrastructure/platform.provider.dart'; import 'package:immich_mobile/providers/user.provider.dart'; import 'package:immich_mobile/widgets/backup/drift_album_info_list_tile.dart'; @@ -43,7 +43,7 @@ class _DriftBackupAlbumSelectionPageState extends ConsumerState p.totalCount)); @@ -55,7 +55,7 @@ class _DriftBackupAlbumSelectionPageState extends ConsumerState a.backupSelection == BackupSelection.selected) @@ -103,7 +103,7 @@ class _DriftBackupAlbumSelectionPageState extends ConsumerState p.totalCount)); final totalChanged = currentTotalAssetCount != _initialTotalAssetCount; diff --git a/mobile/lib/pages/backup/drift_backup_options.page.dart b/mobile/lib/pages/backup/drift_backup_options.page.dart index 4e8a185955..42643a0496 100644 --- a/mobile/lib/pages/backup/drift_backup_options.page.dart +++ b/mobile/lib/pages/backup/drift_backup_options.page.dart @@ -4,10 +4,10 @@ import 'package:auto_route/auto_route.dart'; import 'package:flutter/material.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/extensions/translate_extensions.dart'; -import 'package:immich_mobile/infrastructure/repositories/metadata.repository.dart'; +import 'package:immich_mobile/infrastructure/repositories/settings.repository.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/infrastructure/metadata.provider.dart'; +import 'package:immich_mobile/providers/infrastructure/settings.provider.dart'; import 'package:immich_mobile/providers/user.provider.dart'; import 'package:immich_mobile/widgets/settings/backup_settings/drift_backup_settings.dart'; import 'package:logging/logging.dart'; @@ -19,7 +19,7 @@ class DriftBackupOptionsPage extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { bool hasPopped = false; - final previousBackup = ref.read(metadataProvider).appConfig.backup; + final previousBackup = ref.read(appConfigProvider).backup; final previousCellularForVideos = previousBackup.useCellularForVideos; final previousCellularForPhotos = previousBackup.useCellularForPhotos; return PopScope( @@ -27,7 +27,7 @@ class DriftBackupOptionsPage extends ConsumerWidget { // There is an issue with Flutter where the pop event // can be triggered multiple times, so we guard it with _hasPopped - final currentBackup = ref.read(metadataProvider).appConfig.backup; + final currentBackup = ref.read(appConfigProvider).backup; final currentCellularForVideos = currentBackup.useCellularForVideos; final currentCellularForPhotos = currentBackup.useCellularForPhotos; @@ -45,7 +45,7 @@ class DriftBackupOptionsPage extends ConsumerWidget { } await ref.read(driftBackupProvider.notifier).getBackupStatus(currentUser.id); - final isBackupEnabled = MetadataRepository.instance.appConfig.backup.enabled; + final isBackupEnabled = SettingsRepository.instance.appConfig.backup.enabled; if (!isBackupEnabled) { return; } diff --git a/mobile/lib/pages/common/headers_settings.page.dart b/mobile/lib/pages/common/headers_settings.page.dart index e599286dcf..9a6b602b04 100644 --- a/mobile/lib/pages/common/headers_settings.page.dart +++ b/mobile/lib/pages/common/headers_settings.page.dart @@ -3,10 +3,9 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:immich_mobile/domain/models/metadata_key.dart'; import 'package:immich_mobile/generated/translations.g.dart'; import 'package:immich_mobile/providers/api.provider.dart'; -import 'package:immich_mobile/providers/infrastructure/metadata.provider.dart'; +import 'package:immich_mobile/providers/infrastructure/settings.provider.dart'; class SettingsHeader { String key = ""; @@ -22,7 +21,7 @@ class HeaderSettingsPage extends HookConsumerWidget { final headers = useState>([]); final setInitialHeaders = useState(false); - final storedHeaders = ref.read(metadataProvider).systemConfig.network.customHeaders; + final storedHeaders = ref.read(appConfigProvider).network.customHeaders; if (!setInitialHeaders.value) { storedHeaders.forEach((k, v) { final header = SettingsHeader(); @@ -94,7 +93,7 @@ class HeaderSettingsPage extends HookConsumerWidget { headersMap[key] = value; } - await ref.read(metadataProvider).write(MetadataKey.networkCustomHeaders, headersMap); + await ref.read(settingsProvider).write(.networkCustomHeaders, headersMap); await ref.read(apiServiceProvider).updateHeaders(); } } diff --git a/mobile/lib/pages/common/splash_screen.page.dart b/mobile/lib/pages/common/splash_screen.page.dart index 7b49d98307..aaa9fffc05 100644 --- a/mobile/lib/pages/common/splash_screen.page.dart +++ b/mobile/lib/pages/common/splash_screen.page.dart @@ -7,12 +7,12 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/constants/locales.dart'; -import 'package:immich_mobile/domain/models/metadata_key.dart'; +import 'package:immich_mobile/domain/models/config/app_config.dart'; import 'package:immich_mobile/domain/models/store.model.dart'; import 'package:immich_mobile/entities/store.entity.dart'; import 'package:immich_mobile/generated/codegen_loader.g.dart'; import 'package:immich_mobile/generated/translations.g.dart'; -import 'package:immich_mobile/infrastructure/repositories/metadata.repository.dart'; +import 'package:immich_mobile/infrastructure/repositories/settings.repository.dart'; import 'package:immich_mobile/providers/auth.provider.dart'; import 'package:immich_mobile/providers/background_sync.provider.dart'; import 'package:immich_mobile/providers/backup/drift_backup.provider.dart'; @@ -36,7 +36,7 @@ class BootstrapErrorWidget extends StatelessWidget { @override Widget build(BuildContext _) { - final immichTheme = MetadataKey.themePrimaryColor.defaultValue.themeOfPreset; + final immichTheme = defaultConfig.theme.primaryColor.themeOfPreset; return EasyLocalization( supportedLocales: locales.values.toList(), @@ -341,7 +341,7 @@ class SplashScreenPageState extends ConsumerState { await backgroundManager.hashAssets(); } - if (MetadataRepository.instance.appConfig.backup.syncAlbums) { + if (SettingsRepository.instance.appConfig.backup.syncAlbums) { await backgroundManager.syncLinkedAlbum(); } } catch (e) { @@ -370,7 +370,7 @@ class SplashScreenPageState extends ConsumerState { } Future _resumeBackup(DriftBackupNotifier notifier) async { - final isEnableBackup = MetadataRepository.instance.appConfig.backup.enabled; + final isEnableBackup = SettingsRepository.instance.appConfig.backup.enabled; if (isEnableBackup) { final currentUser = Store.tryGet(StoreKey.currentUser); diff --git a/mobile/lib/platform/native_sync_api.g.dart b/mobile/lib/platform/native_sync_api.g.dart index e7095663b0..ff6ca7bf9d 100644 --- a/mobile/lib/platform/native_sync_api.g.dart +++ b/mobile/lib/platform/native_sync_api.g.dart @@ -654,6 +654,25 @@ class NativeSyncApi { return (pigeonVar_replyValue! as Map).cast>(); } + Future restoreFromTrashById(String mediaId, int type) async { + final pigeonVar_channelName = + 'dev.flutter.pigeon.immich_mobile.NativeSyncApi.restoreFromTrashById$pigeonVar_messageChannelSuffix'; + final pigeonVar_channel = BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final Future pigeonVar_sendFuture = pigeonVar_channel.send([mediaId, type]); + final pigeonVar_replyList = await pigeonVar_sendFuture as List?; + + final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( + pigeonVar_replyList, + pigeonVar_channelName, + isNullValid: false, + ); + return pigeonVar_replyValue! as bool; + } + Future> getCloudIdForAssetIds(List assetIds) async { final pigeonVar_channelName = 'dev.flutter.pigeon.immich_mobile.NativeSyncApi.getCloudIdForAssetIds$pigeonVar_messageChannelSuffix'; diff --git a/mobile/lib/platform/network_api.g.dart b/mobile/lib/platform/network_api.g.dart index 7fab476694..6258060bfb 100644 --- a/mobile/lib/platform/network_api.g.dart +++ b/mobile/lib/platform/network_api.g.dart @@ -309,4 +309,23 @@ class NetworkApi { _extractReplyValueOrThrow(pigeonVar_replyList, pigeonVar_channelName, isNullValid: true); } + + Future getAppGroupId() async { + final pigeonVar_channelName = + 'dev.flutter.pigeon.immich_mobile.NetworkApi.getAppGroupId$pigeonVar_messageChannelSuffix'; + final pigeonVar_channel = BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final Future pigeonVar_sendFuture = pigeonVar_channel.send(null); + final pigeonVar_replyList = await pigeonVar_sendFuture as List?; + + final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( + pigeonVar_replyList, + pigeonVar_channelName, + isNullValid: false, + ); + return pigeonVar_replyValue! as String; + } } diff --git a/mobile/lib/platform/permission_api.g.dart b/mobile/lib/platform/permission_api.g.dart new file mode 100644 index 0000000000..d2646e482f --- /dev/null +++ b/mobile/lib/platform/permission_api.g.dart @@ -0,0 +1,119 @@ +// Autogenerated from Pigeon (v26.3.4), do not edit directly. +// See also: https://pub.dev/packages/pigeon +// ignore_for_file: unused_import, unused_shown_name +// ignore_for_file: type=lint + +import 'dart:async'; +import 'dart:typed_data' show Float64List, Int32List, Int64List; + +import 'package:flutter/services.dart'; +import 'package:meta/meta.dart' show immutable, protected, visibleForTesting; + +Object? _extractReplyValueOrThrow(List? replyList, String channelName, {required bool isNullValid}) { + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel: "$channelName".', + ); + } else if (replyList.length > 1) { + throw PlatformException(code: replyList[0]! as String, message: replyList[1] as String?, details: replyList[2]); + } else if (!isNullValid && (replyList.isNotEmpty && replyList[0] == null)) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } + return replyList.firstOrNull; +} + +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 PermissionApi { + /// Constructor for [PermissionApi]. 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. + PermissionApi({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 hasManageMediaPermission() async { + final pigeonVar_channelName = + 'dev.flutter.pigeon.immich_mobile.PermissionApi.hasManageMediaPermission$pigeonVar_messageChannelSuffix'; + final pigeonVar_channel = BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final Future pigeonVar_sendFuture = pigeonVar_channel.send(null); + final pigeonVar_replyList = await pigeonVar_sendFuture as List?; + + final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( + pigeonVar_replyList, + pigeonVar_channelName, + isNullValid: false, + ); + return pigeonVar_replyValue! as bool; + } + + Future requestManageMediaPermission() async { + final pigeonVar_channelName = + 'dev.flutter.pigeon.immich_mobile.PermissionApi.requestManageMediaPermission$pigeonVar_messageChannelSuffix'; + final pigeonVar_channel = BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final Future pigeonVar_sendFuture = pigeonVar_channel.send(null); + final pigeonVar_replyList = await pigeonVar_sendFuture as List?; + + final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( + pigeonVar_replyList, + pigeonVar_channelName, + isNullValid: false, + ); + return pigeonVar_replyValue! as bool; + } + + Future manageMediaPermission() async { + final pigeonVar_channelName = + 'dev.flutter.pigeon.immich_mobile.PermissionApi.manageMediaPermission$pigeonVar_messageChannelSuffix'; + final pigeonVar_channel = BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final Future pigeonVar_sendFuture = pigeonVar_channel.send(null); + final pigeonVar_replyList = await pigeonVar_sendFuture as List?; + + final Object? pigeonVar_replyValue = _extractReplyValueOrThrow( + pigeonVar_replyList, + pigeonVar_channelName, + isNullValid: false, + ); + return pigeonVar_replyValue! as bool; + } +} diff --git a/mobile/lib/presentation/pages/drift_slideshow.page.dart b/mobile/lib/presentation/pages/drift_slideshow.page.dart index 4c4ee48cf9..3a5f95554c 100644 --- a/mobile/lib/presentation/pages/drift_slideshow.page.dart +++ b/mobile/lib/presentation/pages/drift_slideshow.page.dart @@ -17,7 +17,7 @@ import 'package:immich_mobile/presentation/widgets/asset_viewer/video_viewer.wid import 'package:immich_mobile/presentation/widgets/images/image_provider.dart'; import 'package:immich_mobile/providers/asset_viewer/asset_viewer.provider.dart'; import 'package:immich_mobile/providers/asset_viewer/video_player_provider.dart'; -import 'package:immich_mobile/providers/infrastructure/metadata.provider.dart'; +import 'package:immich_mobile/providers/infrastructure/settings.provider.dart'; import 'package:immich_mobile/routing/router.dart'; import 'package:immich_mobile/widgets/common/immich_loading_indicator.dart'; import 'package:immich_mobile/widgets/photo_view/photo_view.dart'; diff --git a/mobile/lib/presentation/widgets/action_buttons/add_action_button.widget.dart b/mobile/lib/presentation/widgets/action_buttons/add_action_button.widget.dart index ecfe4a60fe..1ab3f2039d 100644 --- a/mobile/lib/presentation/widgets/action_buttons/add_action_button.widget.dart +++ b/mobile/lib/presentation/widgets/action_buttons/add_action_button.widget.dart @@ -6,6 +6,7 @@ import 'package:immich_mobile/presentation/widgets/action_buttons/base_action_bu import 'package:immich_mobile/presentation/widgets/action_buttons/unarchive_action_button.widget.dart'; import 'package:immich_mobile/providers/asset_viewer/asset_viewer.provider.dart'; import 'package:immich_mobile/presentation/widgets/album/album_selector.widget.dart'; +import 'package:immich_mobile/providers/infrastructure/action.provider.dart'; import 'package:immich_mobile/providers/infrastructure/album.provider.dart'; import 'package:immich_mobile/providers/routes.provider.dart'; import 'package:immich_mobile/widgets/common/immich_toast.dart'; @@ -142,13 +143,18 @@ class _AddActionButtonState extends ConsumerState { return; } - final addedCount = await ref.read(remoteAlbumProvider.notifier).addAssets(album.id, [latest.remoteId!]); + final result = await ref.read(actionProvider.notifier).addToAlbum(ActionSource.viewer, album); if (!context.mounted) { return; } - if (addedCount == 0) { + if (!result.success) { + ImmichToast.show(context: context, msg: 'scaffold_body_error_occurred'.tr(), toastType: ToastType.error); + return; + } + + if (result.count == 0) { ImmichToast.show( context: context, msg: 'add_to_album_bottom_sheet_already_exists'.tr(namedArgs: {'album': album.name}), @@ -159,7 +165,7 @@ class _AddActionButtonState extends ConsumerState { msg: 'add_to_album_bottom_sheet_added'.tr(namedArgs: {'album': album.name}), ); - // Invalidate using the asset's remote ID to refresh the "Appears in" list + // Refresh the "Appears in" list on the asset's info panel. ref.invalidate(albumsContainingAssetProvider(latest.remoteId!)); } diff --git a/mobile/lib/presentation/widgets/action_buttons/delete_local_action_button.widget.dart b/mobile/lib/presentation/widgets/action_buttons/delete_local_action_button.widget.dart index 2e15de49df..6911d09f89 100644 --- a/mobile/lib/presentation/widgets/action_buttons/delete_local_action_button.widget.dart +++ b/mobile/lib/presentation/widgets/action_buttons/delete_local_action_button.widget.dart @@ -9,6 +9,7 @@ import 'package:immich_mobile/presentation/widgets/action_buttons/base_action_bu import 'package:immich_mobile/providers/infrastructure/action.provider.dart'; import 'package:immich_mobile/providers/timeline/multiselect.provider.dart'; import 'package:immich_mobile/widgets/common/immich_toast.dart'; +import 'package:immich_mobile/providers/infrastructure/album.provider.dart'; /// This delete action has the following behavior: /// - Prompt to delete the asset locally @@ -39,6 +40,8 @@ class DeleteLocalActionButton extends ConsumerWidget { return; } + ref.invalidate(localAlbumProvider); + final successMessage = 'delete_local_action_prompt'.t(context: context, args: {'count': result.count.toString()}); if (context.mounted) { 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 6fbd6f7dfa..7bc5dacb16 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 @@ -14,7 +14,9 @@ import 'package:immich_mobile/providers/timeline/multiselect.provider.dart'; import 'package:immich_mobile/widgets/common/immich_toast.dart'; class _SharePreparingDialog extends StatelessWidget { - const _SharePreparingDialog(); + final ValueNotifier progress; + + const _SharePreparingDialog({required this.progress}); @override Widget build(BuildContext context) { @@ -22,8 +24,24 @@ class _SharePreparingDialog extends StatelessWidget { content: Column( mainAxisSize: MainAxisSize.min, children: [ - const CircularProgressIndicator(), - Container(margin: const EdgeInsets.only(top: 12), child: const Text('share_dialog_preparing').tr()), + Container(margin: const EdgeInsets.only(bottom: 12), child: const Text('share_dialog_preparing').tr()), + SizedBox( + width: 240, + child: ValueListenableBuilder( + valueListenable: progress, + builder: (context, value, _) { + final percent = value == null ? null : (value * 100).clamp(0, 100); + return Column( + mainAxisSize: MainAxisSize.min, + children: [ + LinearProgressIndicator(value: value, minHeight: 8.0), + if (percent != null) + Container(margin: const EdgeInsets.only(top: 8), child: Text('${percent.toStringAsFixed(0)}%')), + ], + ); + }, + ), + ), ], ), ); @@ -43,32 +61,39 @@ class ShareActionButton extends ConsumerWidget { } final cancelCompleter = Completer(); - const preparingDialog = _SharePreparingDialog(); + final progress = ValueNotifier(null); + final preparingDialog = _SharePreparingDialog(progress: progress); await showDialog( context: context, builder: (BuildContext buildContext) { - ref.read(actionProvider.notifier).shareAssets(source, context, cancelCompleter: cancelCompleter).then(( - ActionResult result, - ) { - if (cancelCompleter.isCompleted || !context.mounted) { - return; - } + ref + .read(actionProvider.notifier) + .shareAssets( + source, + context, + cancelCompleter: cancelCompleter, + onAssetDownloadProgress: (value) => progress.value = value, + ) + .then((ActionResult result) { + if (cancelCompleter.isCompleted || !context.mounted) { + return; + } - ref.read(multiSelectProvider.notifier).reset(); + ref.read(multiSelectProvider.notifier).reset(); - if (!result.success) { - ImmichToast.show( - context: context, - msg: 'scaffold_body_error_occurred'.t(context: context), - gravity: ToastGravity.BOTTOM, - toastType: ToastType.error, - ); - } + if (!result.success) { + ImmichToast.show( + context: context, + msg: 'scaffold_body_error_occurred'.t(context: context), + gravity: ToastGravity.BOTTOM, + toastType: ToastType.error, + ); + } - buildContext.pop(); - }); + buildContext.pop(); + }); - // show a loading spinner with a "Preparing" message + // Show download progress with a "Preparing" message return preparingDialog; }, barrierDismissible: false, @@ -77,6 +102,7 @@ class ShareActionButton extends ConsumerWidget { if (!cancelCompleter.isCompleted) { cancelCompleter.complete(); } + progress.dispose(); }); } diff --git a/mobile/lib/presentation/widgets/album/album_selector.widget.dart b/mobile/lib/presentation/widgets/album/album_selector.widget.dart index 6241623978..5a174bfc5e 100644 --- a/mobile/lib/presentation/widgets/album/album_selector.widget.dart +++ b/mobile/lib/presentation/widgets/album/album_selector.widget.dart @@ -7,7 +7,6 @@ import 'package:flutter/material.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; 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/extensions/build_context_extensions.dart'; import 'package:immich_mobile/extensions/theme_extensions.dart'; import 'package:immich_mobile/extensions/translate_extensions.dart'; @@ -15,12 +14,11 @@ import 'package:immich_mobile/models/albums/album_search.model.dart'; import 'package:immich_mobile/presentation/widgets/album/album_tile.dart'; import 'package:immich_mobile/presentation/widgets/album/new_album_name_modal.widget.dart'; import 'package:immich_mobile/presentation/widgets/images/thumbnail.widget.dart'; -import 'package:immich_mobile/domain/models/metadata_key.dart'; import 'package:immich_mobile/providers/album/album_sort_by_options.provider.dart'; import 'package:immich_mobile/providers/asset_viewer/asset_viewer.provider.dart'; import 'package:immich_mobile/providers/infrastructure/album.provider.dart'; import 'package:immich_mobile/providers/infrastructure/asset.provider.dart'; -import 'package:immich_mobile/providers/infrastructure/metadata.provider.dart'; +import 'package:immich_mobile/providers/infrastructure/settings.provider.dart'; import 'package:immich_mobile/providers/timeline/multiselect.provider.dart'; import 'package:immich_mobile/providers/user.provider.dart'; import 'package:immich_mobile/routing/router.dart'; @@ -58,7 +56,7 @@ class _AlbumSelectorState extends ConsumerState { super.initState(); WidgetsBinding.instance.addPostFrameCallback((_) { - final albumConfig = ref.read(metadataProvider).appConfig.album; + final albumConfig = ref.read(appConfigProvider).album; setState(() { sort = AlbumSort(mode: albumConfig.sortMode, isReverse: albumConfig.isReverse); @@ -94,7 +92,7 @@ class _AlbumSelectorState extends ConsumerState { setState(() { isGrid = !isGrid; }); - ref.read(metadataProvider).write(MetadataKey.albumIsGrid, isGrid); + ref.read(settingsProvider).write(.albumIsGrid, isGrid); } void changeFilter(QuickFilterMode mode) { @@ -110,9 +108,9 @@ class _AlbumSelectorState extends ConsumerState { this.sort = sort; }); - final metadata = ref.read(metadataProvider); - await metadata.write(MetadataKey.albumSortMode, sort.mode); - await metadata.write(MetadataKey.albumIsReverse, sort.isReverse); + final metadata = ref.read(settingsProvider); + await metadata.write(.albumSortMode, sort.mode); + await metadata.write(.albumIsReverse, sort.isReverse); await sortAlbums(); } @@ -747,12 +745,10 @@ class AddToAlbumHeader extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { Future onCreateAlbum() async { + final selectedAssets = ref.read(multiSelectProvider).selectedAssets; final newAlbum = await ref .read(remoteAlbumProvider.notifier) - .createAlbum( - title: "Untitled Album", - assetIds: ref.read(multiSelectProvider).selectedAssets.map((e) => (e as RemoteAsset).id).toList(), - ); + .createAlbumWithAssets(title: "Untitled Album", assets: selectedAssets); if (newAlbum == null) { ImmichToast.show(context: context, toastType: ToastType.error, msg: 'errors.failed_to_create_album'.tr()); diff --git a/mobile/lib/presentation/widgets/album/pending_uploads_banner.widget.dart b/mobile/lib/presentation/widgets/album/pending_uploads_banner.widget.dart index 397170ec54..2701316e75 100644 --- a/mobile/lib/presentation/widgets/album/pending_uploads_banner.widget.dart +++ b/mobile/lib/presentation/widgets/album/pending_uploads_banner.widget.dart @@ -5,6 +5,7 @@ import 'package:immich_mobile/extensions/build_context_extensions.dart'; import 'package:immich_mobile/extensions/translate_extensions.dart'; import 'package:immich_mobile/presentation/widgets/images/thumbnail.widget.dart'; import 'package:immich_mobile/providers/album/pending_album_uploads.provider.dart'; +import 'package:immich_mobile/providers/backup/asset_upload_progress.provider.dart'; /// Pinned banner sliver that surfaces in-flight album uploads directly under /// the album app bar. Renders nothing while the queue is empty. Tapping the @@ -165,6 +166,8 @@ class _PendingUploadsSheet extends ConsumerWidget { } final failedCount = pending.where((p) => p.failed).length; + final inFlightCount = pending.length - failedCount; + final canAbort = inFlightCount > 0 && ref.watch(manualUploadCancelTokenProvider) != null; return SafeArea( child: Padding( @@ -183,7 +186,21 @@ class _PendingUploadsSheet extends ConsumerWidget { style: context.textTheme.titleMedium, ), ), - if (failedCount > 0) + if (canAbort) + TextButton.icon( + onPressed: () { + final cancelToken = ref.read(manualUploadCancelTokenProvider); + if (cancelToken != null && !cancelToken.isCompleted) { + cancelToken.complete(); + } + ref.read(manualUploadCancelTokenProvider.notifier).state = null; + ref.read(pendingAlbumUploadsProvider(albumId).notifier).clear(); + }, + icon: const Icon(Icons.stop_circle_outlined, size: 18), + label: Text('cancel'.t(context: context)), + style: TextButton.styleFrom(foregroundColor: context.colorScheme.error), + ) + else if (failedCount > 0) TextButton.icon( onPressed: () => ref.read(pendingAlbumUploadsProvider(albumId).notifier).clearFailed(), icon: const Icon(Icons.clear_rounded, size: 18), diff --git a/mobile/lib/presentation/widgets/asset_viewer/asset_page.widget.dart b/mobile/lib/presentation/widgets/asset_viewer/asset_page.widget.dart index 0afc1b781c..84edc4df65 100644 --- a/mobile/lib/presentation/widgets/asset_viewer/asset_page.widget.dart +++ b/mobile/lib/presentation/widgets/asset_viewer/asset_page.widget.dart @@ -19,7 +19,7 @@ import 'package:immich_mobile/presentation/widgets/images/image_provider.dart'; import 'package:immich_mobile/presentation/widgets/images/thumbnail.widget.dart'; import 'package:immich_mobile/providers/asset_viewer/asset_viewer.provider.dart'; import 'package:immich_mobile/providers/asset_viewer/is_motion_video_playing.provider.dart'; -import 'package:immich_mobile/providers/infrastructure/metadata.provider.dart'; +import 'package:immich_mobile/providers/infrastructure/settings.provider.dart'; import 'package:immich_mobile/providers/infrastructure/timeline.provider.dart'; import 'package:immich_mobile/widgets/common/immich_loading_indicator.dart'; import 'package:immich_mobile/widgets/photo_view/photo_view.dart'; @@ -241,7 +241,7 @@ class _AssetPageState extends ConsumerState { return; } - final tapToNavigate = ref.read(metadataProvider).appConfig.viewer.tapToNavigate; + final tapToNavigate = ref.read(appConfigProvider).viewer.tapToNavigate; if (!tapToNavigate) { _viewer.toggleControls(); return; diff --git a/mobile/lib/presentation/widgets/asset_viewer/video_viewer.widget.dart b/mobile/lib/presentation/widgets/asset_viewer/video_viewer.widget.dart index 97ca8ace10..c1e6fe10e6 100644 --- a/mobile/lib/presentation/widgets/asset_viewer/video_viewer.widget.dart +++ b/mobile/lib/presentation/widgets/asset_viewer/video_viewer.widget.dart @@ -12,7 +12,7 @@ import 'package:immich_mobile/providers/asset_viewer/is_motion_video_playing.pro import 'package:immich_mobile/providers/asset_viewer/video_player_provider.dart'; import 'package:immich_mobile/providers/cast.provider.dart'; import 'package:immich_mobile/providers/infrastructure/asset.provider.dart'; -import 'package:immich_mobile/providers/infrastructure/metadata.provider.dart'; +import 'package:immich_mobile/providers/infrastructure/settings.provider.dart'; import 'package:immich_mobile/services/api.service.dart'; import 'package:logging/logging.dart'; import 'package:native_video_player/native_video_player.dart'; @@ -128,7 +128,7 @@ class _NativeVideoViewerState extends ConsumerState with Widg final remoteId = (videoAsset as RemoteAsset).id; final serverEndpoint = Store.get(StoreKey.serverEndpoint); - final isOriginalVideo = ref.read(metadataProvider).appConfig.viewer.loadOriginalVideo; + final isOriginalVideo = ref.read(appConfigProvider).viewer.loadOriginalVideo; final String postfixUrl = isOriginalVideo ? 'original' : 'video/playback'; final String videoUrl = videoAsset.livePhotoVideoId != null ? '$serverEndpoint/assets/${videoAsset.livePhotoVideoId}/$postfixUrl' @@ -161,7 +161,7 @@ class _NativeVideoViewerState extends ConsumerState with Widg return; } - final autoPlayVideo = ref.read(metadataProvider).appConfig.viewer.autoPlayVideo; + final autoPlayVideo = ref.read(appConfigProvider).viewer.autoPlayVideo; if (autoPlayVideo || widget.asset.isMotionPhoto) { await _notifier.play(); } @@ -212,7 +212,7 @@ class _NativeVideoViewerState extends ConsumerState with Widg } await _notifier.load(source); - final loopVideo = ref.read(metadataProvider).appConfig.viewer.loopVideo; + final loopVideo = ref.read(appConfigProvider).viewer.loopVideo; await _notifier.setLoop(!widget.asset.isMotionPhoto && loopVideo); await _notifier.setVolume(1); } diff --git a/mobile/lib/presentation/widgets/asset_viewer/viewer_kebab_menu.widget.dart b/mobile/lib/presentation/widgets/asset_viewer/viewer_kebab_menu.widget.dart index 5a79485daf..418d41e1f2 100644 --- a/mobile/lib/presentation/widgets/asset_viewer/viewer_kebab_menu.widget.dart +++ b/mobile/lib/presentation/widgets/asset_viewer/viewer_kebab_menu.widget.dart @@ -2,7 +2,6 @@ import 'package:flutter/material.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/constants/enums.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/build_context_extensions.dart'; import 'package:immich_mobile/providers/asset_viewer/asset_viewer.provider.dart'; import 'package:immich_mobile/providers/cast.provider.dart'; @@ -34,7 +33,7 @@ class ViewerKebabMenu extends ConsumerWidget { final isInLockedView = ref.watch(inLockedViewProvider); final currentAlbum = ref.watch(currentRemoteAlbumProvider); final isArchived = asset is RemoteAsset && asset.visibility == AssetVisibility.archive; - final advancedTroubleshooting = ref.watch(settingsProvider.notifier).get(Setting.advancedTroubleshooting); + final advancedTroubleshooting = ref.watch(settingsProvider.notifier).get(.advancedTroubleshooting); final actionContext = ActionButtonContext( asset: asset, 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 708d3a9879..3bf48783ea 100644 --- a/mobile/lib/presentation/widgets/backup/backup_toggle_button.widget.dart +++ b/mobile/lib/presentation/widgets/backup/backup_toggle_button.widget.dart @@ -1,10 +1,9 @@ import 'package:flutter/material.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:immich_mobile/domain/models/metadata_key.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/providers/infrastructure/metadata.provider.dart'; +import 'package:immich_mobile/providers/infrastructure/settings.provider.dart'; class BackupToggleButton extends ConsumerStatefulWidget { final VoidCallback onStart; @@ -31,7 +30,7 @@ class BackupToggleButtonState extends ConsumerState with Sin end: 1, ).animate(CurvedAnimation(parent: _animationController, curve: Curves.easeInOut)); - _isEnabled = ref.read(metadataProvider).appConfig.backup.enabled; + _isEnabled = ref.read(appConfigProvider).backup.enabled; } @override @@ -41,7 +40,7 @@ class BackupToggleButtonState extends ConsumerState with Sin } Future _onToggle(bool value) async { - await ref.read(metadataProvider).write(MetadataKey.backupEnabled, value); + await ref.read(settingsProvider).write(.backupEnabled, value); setState(() { _isEnabled = value; 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 0bafacfe54..c3a569407a 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 @@ -3,9 +3,7 @@ import 'package:flutter/material.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; 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/bulk_tag_assets_action_button.widget.dart'; @@ -25,7 +23,7 @@ import 'package:immich_mobile/presentation/widgets/action_buttons/unstack_action 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'; -import 'package:immich_mobile/providers/infrastructure/album.provider.dart'; +import 'package:immich_mobile/providers/infrastructure/action.provider.dart'; import 'package:immich_mobile/providers/infrastructure/setting.provider.dart'; import 'package:immich_mobile/providers/infrastructure/user_metadata.provider.dart'; import 'package:immich_mobile/providers/server_info.provider.dart'; @@ -63,37 +61,23 @@ class _GeneralBottomSheetState extends ConsumerState { userMetadataPreferencesProvider.select((value) => value.valueOrNull?.tagsEnabled ?? false), ); - Future addAssetsToAlbum(RemoteAlbum album) async { - final selectedAssets = multiselect.selectedAssets; - if (selectedAssets.isEmpty) { + Future addToAlbum(RemoteAlbum album) async { + final result = await ref.read(actionProvider.notifier).addToAlbum(ActionSource.timeline, album); + + if (!context.mounted) { return; } - final remoteAssets = selectedAssets.whereType(); - final addedCount = await ref - .read(remoteAlbumProvider.notifier) - .addAssets(album.id, remoteAssets.map((e) => e.id).toList()); - - if (selectedAssets.length != remoteAssets.length) { - ImmichToast.show( - context: context, - msg: 'add_to_album_bottom_sheet_some_local_assets'.t(context: context), - ); + if (!result.success) { + ImmichToast.show(context: context, msg: 'scaffold_body_error_occurred'.tr(), toastType: ToastType.error); + return; } - - if (addedCount != remoteAssets.length) { - ImmichToast.show( - context: context, - msg: 'add_to_album_bottom_sheet_already_exists'.tr(namedArgs: {"album": album.name}), - ); - } else { - ImmichToast.show( - context: context, - msg: 'add_to_album_bottom_sheet_added'.tr(namedArgs: {"album": album.name}), - ); - } - - ref.read(multiSelectProvider.notifier).reset(); + ImmichToast.show( + context: context, + msg: result.count == 0 + ? 'add_to_album_bottom_sheet_already_exists'.tr(namedArgs: {'album': album.name}) + : 'add_to_album_bottom_sheet_added'.tr(namedArgs: {'album': album.name}), + ); } Future onKeyboardExpand() { @@ -131,12 +115,10 @@ class _GeneralBottomSheetState extends ConsumerState { const DeleteLocalActionButton(source: ActionSource.timeline), if (multiselect.onlyLocal) const UploadActionButton(source: ActionSource.timeline), ], - slivers: multiselect.hasRemote - ? [ - const AddToAlbumHeader(), - AlbumSelector(onAlbumSelected: addAssetsToAlbum, onKeyboardExpanded: onKeyboardExpand), - ] - : [], + slivers: [ + const AddToAlbumHeader(), + AlbumSelector(onAlbumSelected: addToAlbum, onKeyboardExpanded: onKeyboardExpand), + ], ); } } diff --git a/mobile/lib/presentation/widgets/bottom_sheet/local_album_bottom_sheet.widget.dart b/mobile/lib/presentation/widgets/bottom_sheet/local_album_bottom_sheet.widget.dart index b1e87dfaea..ac8c77af03 100644 --- a/mobile/lib/presentation/widgets/bottom_sheet/local_album_bottom_sheet.widget.dart +++ b/mobile/lib/presentation/widgets/bottom_sheet/local_album_bottom_sheet.widget.dart @@ -1,25 +1,78 @@ +import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/constants/enums.dart'; +import 'package:immich_mobile/domain/models/album/album.model.dart'; import 'package:immich_mobile/presentation/widgets/action_buttons/delete_local_action_button.widget.dart'; import 'package:immich_mobile/presentation/widgets/action_buttons/share_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'; +import 'package:immich_mobile/providers/infrastructure/action.provider.dart'; +import 'package:immich_mobile/widgets/common/immich_toast.dart'; -class LocalAlbumBottomSheet extends ConsumerWidget { +class LocalAlbumBottomSheet extends ConsumerStatefulWidget { const LocalAlbumBottomSheet({super.key}); @override - Widget build(BuildContext context, WidgetRef ref) { - return const BaseBottomSheet( + ConsumerState createState() => _LocalAlbumBottomSheetState(); +} + +class _LocalAlbumBottomSheetState extends ConsumerState { + late final DraggableScrollableController sheetController; + + @override + void initState() { + super.initState(); + sheetController = DraggableScrollableController(); + } + + @override + void dispose() { + sheetController.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + Future addToAlbum(RemoteAlbum album) async { + final result = await ref.read(actionProvider.notifier).addToAlbum(ActionSource.timeline, album); + + if (!context.mounted) { + return; + } + + if (!result.success) { + ImmichToast.show(context: context, msg: 'scaffold_body_error_occurred'.tr(), toastType: ToastType.error); + return; + } + + ImmichToast.show( + context: context, + msg: result.count == 0 + ? 'add_to_album_bottom_sheet_already_exists'.tr(namedArgs: {'album': album.name}) + : 'add_to_album_bottom_sheet_added'.tr(namedArgs: {'album': album.name}), + ); + } + + Future onKeyboardExpand() { + return sheetController.animateTo(0.85, duration: const Duration(milliseconds: 200), curve: Curves.easeInOut); + } + + return BaseBottomSheet( + controller: sheetController, initialChildSize: 0.25, - maxChildSize: 0.4, + maxChildSize: 0.85, shouldCloseOnMinExtent: false, - actions: [ + actions: const [ ShareActionButton(source: ActionSource.timeline), DeleteLocalActionButton(source: ActionSource.timeline), UploadActionButton(source: ActionSource.timeline), ], + slivers: [ + const AddToAlbumHeader(), + AlbumSelector(onAlbumSelected: addToAlbum, onKeyboardExpanded: onKeyboardExpand), + ], ); } } 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 6848a07bb8..6b914ed077 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 @@ -2,7 +2,6 @@ import 'package:flutter/material.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; 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/extensions/translate_extensions.dart'; import 'package:immich_mobile/presentation/widgets/action_buttons/archive_action_button.widget.dart'; import 'package:immich_mobile/presentation/widgets/action_buttons/delete_local_action_button.widget.dart'; @@ -21,7 +20,7 @@ import 'package:immich_mobile/presentation/widgets/action_buttons/trash_action_b import 'package:immich_mobile/presentation/widgets/action_buttons/unstack_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'; -import 'package:immich_mobile/providers/infrastructure/album.provider.dart'; +import 'package:immich_mobile/providers/infrastructure/action.provider.dart'; import 'package:immich_mobile/providers/server_info.provider.dart'; import 'package:immich_mobile/providers/timeline/multiselect.provider.dart'; import 'package:immich_mobile/providers/user.provider.dart'; @@ -56,29 +55,28 @@ class _RemoteAlbumBottomSheetState extends ConsumerState final isTrashEnable = ref.watch(serverInfoProvider.select((state) => state.serverFeatures.trash)); final ownsAlbum = ref.watch(currentUserProvider)?.id == widget.album.ownerId; - Future addAssetsToAlbum(RemoteAlbum album) async { - final selectedAssets = multiselect.selectedAssets; - if (selectedAssets.isEmpty) { + Future addToAlbum(RemoteAlbum album) async { + final result = await ref.read(actionProvider.notifier).addToAlbum(ActionSource.timeline, album); + + if (!context.mounted) { return; } - final addedCount = await ref - .read(remoteAlbumProvider.notifier) - .addAssets(album.id, selectedAssets.map((e) => (e as RemoteAsset).id).toList()); - - if (addedCount != selectedAssets.length) { + if (!result.success) { ImmichToast.show( context: context, - msg: 'add_to_album_bottom_sheet_already_exists'.t(context: context, args: {"album": album.name}), - ); - } else { - ImmichToast.show( - context: context, - msg: 'add_to_album_bottom_sheet_added'.t(context: context, args: {"album": album.name}), + msg: 'scaffold_body_error_occurred'.t(context: context), + toastType: ToastType.error, ); + return; } - ref.read(multiSelectProvider.notifier).reset(); + ImmichToast.show( + context: context, + msg: result.count == 0 + ? 'add_to_album_bottom_sheet_already_exists'.t(context: context, args: {"album": album.name}) + : 'add_to_album_bottom_sheet_added'.t(context: context, args: {"album": album.name}), + ); } Future onKeyboardExpand() { @@ -118,10 +116,7 @@ class _RemoteAlbumBottomSheetState extends ConsumerState SetAlbumCoverActionButton(source: ActionSource.timeline, albumId: widget.album.id), ], slivers: ownsAlbum - ? [ - const AddToAlbumHeader(), - AlbumSelector(onAlbumSelected: addAssetsToAlbum, onKeyboardExpanded: onKeyboardExpand), - ] + ? [const AddToAlbumHeader(), AlbumSelector(onAlbumSelected: addToAlbum, onKeyboardExpanded: onKeyboardExpand)] : null, ); } diff --git a/mobile/lib/presentation/widgets/images/image_provider.dart b/mobile/lib/presentation/widgets/images/image_provider.dart index 9364fdd091..36d9678277 100644 --- a/mobile/lib/presentation/widgets/images/image_provider.dart +++ b/mobile/lib/presentation/widgets/images/image_provider.dart @@ -4,7 +4,7 @@ import 'package:async/async.dart'; import 'package:flutter/widgets.dart'; import 'package:immich_mobile/domain/models/asset/base_asset.model.dart'; import 'package:immich_mobile/infrastructure/loaders/image_request.dart'; -import 'package:immich_mobile/infrastructure/repositories/metadata.repository.dart'; +import 'package:immich_mobile/infrastructure/repositories/settings.repository.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/timeline/constants.dart'; @@ -189,5 +189,5 @@ ImageProvider? getThumbnailImageProvider(BaseAsset asset, {Size size = kThumbnai bool _shouldUseLocalAsset(BaseAsset asset) => asset.hasLocal && - (!asset.hasRemote || !MetadataRepository.instance.appConfig.image.preferRemote) && + (!asset.hasRemote || !SettingsRepository.instance.appConfig.image.preferRemote) && !asset.isEdited; diff --git a/mobile/lib/presentation/widgets/images/local_image_provider.dart b/mobile/lib/presentation/widgets/images/local_image_provider.dart index 6376e07405..eba4f0a1cd 100644 --- a/mobile/lib/presentation/widgets/images/local_image_provider.dart +++ b/mobile/lib/presentation/widgets/images/local_image_provider.dart @@ -2,7 +2,7 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/widgets.dart'; import 'package:immich_mobile/domain/models/asset/base_asset.model.dart'; import 'package:immich_mobile/infrastructure/loaders/image_request.dart'; -import 'package:immich_mobile/infrastructure/repositories/metadata.repository.dart'; +import 'package:immich_mobile/infrastructure/repositories/settings.repository.dart'; import 'package:immich_mobile/presentation/widgets/images/animated_image_stream_completer.dart'; import 'package:immich_mobile/presentation/widgets/images/image_provider.dart'; import 'package:immich_mobile/presentation/widgets/images/one_frame_multi_image_stream_completer.dart'; @@ -104,7 +104,7 @@ class LocalFullImageProvider extends CancellableImageProvider { } void switchFavoriteOnly(bool isFavoriteOnly) { - ref.read(metadataProvider).write(MetadataKey.mapShowFavoriteOnly, isFavoriteOnly); + ref.read(settingsProvider).write(.mapShowFavoriteOnly, isFavoriteOnly); state = state.copyWith(onlyFavorites: isFavoriteOnly); EventStream.shared.emit(const MapMarkerReloadEvent()); } void switchIncludeArchived(bool isIncludeArchived) { - ref.read(metadataProvider).write(MetadataKey.mapIncludeArchived, isIncludeArchived); + ref.read(settingsProvider).write(.mapIncludeArchived, isIncludeArchived); state = state.copyWith(includeArchived: isIncludeArchived); EventStream.shared.emit(const MapMarkerReloadEvent()); } void switchWithPartners(bool isWithPartners) { - ref.read(metadataProvider).write(MetadataKey.mapWithPartners, isWithPartners); + ref.read(settingsProvider).write(.mapWithPartners, isWithPartners); state = state.copyWith(withPartners: isWithPartners); EventStream.shared.emit(const MapMarkerReloadEvent()); } void setRelativeTime(int relativeDays) { - ref.read(metadataProvider).write(MetadataKey.mapRelativeDate, relativeDays); + ref.read(settingsProvider).write(.mapRelativeDate, relativeDays); state = state.copyWith(relativeDays: relativeDays); EventStream.shared.emit(const MapMarkerReloadEvent()); } diff --git a/mobile/lib/presentation/widgets/timeline/fixed/row.dart b/mobile/lib/presentation/widgets/timeline/fixed/row.dart index 126254e687..851cb5ebae 100644 --- a/mobile/lib/presentation/widgets/timeline/fixed/row.dart +++ b/mobile/lib/presentation/widgets/timeline/fixed/row.dart @@ -62,14 +62,11 @@ class RenderFixedRow extends RenderBox RenderBoxContainerDefaultsMixin { RenderFixedRow({ List? children, - required double height, - required List widths, - required double spacing, - required TextDirection textDirection, - }) : _height = height, - _widths = widths, - _spacing = spacing, - _textDirection = textDirection { + required this._height, + required this._widths, + required this._spacing, + required this._textDirection, + }) { addAll(children); } diff --git a/mobile/lib/presentation/widgets/timeline/scrubber.widget.dart b/mobile/lib/presentation/widgets/timeline/scrubber.widget.dart index c2905bcafa..5eda237ec4 100644 --- a/mobile/lib/presentation/widgets/timeline/scrubber.widget.dart +++ b/mobile/lib/presentation/widgets/timeline/scrubber.widget.dart @@ -578,9 +578,7 @@ class _SlideFadeTransition extends StatelessWidget { final Animation _animation; final Widget _child; - const _SlideFadeTransition({required Animation animation, required Widget child}) - : _animation = animation, - _child = child; + const _SlideFadeTransition({required this._animation, required this._child}); @override Widget build(BuildContext context) { diff --git a/mobile/lib/presentation/widgets/timeline/timeline.state.dart b/mobile/lib/presentation/widgets/timeline/timeline.state.dart index 7b88800f22..8dd87f9868 100644 --- a/mobile/lib/presentation/widgets/timeline/timeline.state.dart +++ b/mobile/lib/presentation/widgets/timeline/timeline.state.dart @@ -5,7 +5,7 @@ import 'package:immich_mobile/domain/models/timeline.model.dart'; import 'package:immich_mobile/presentation/widgets/timeline/constants.dart'; import 'package:immich_mobile/presentation/widgets/timeline/fixed/segment_builder.dart'; import 'package:immich_mobile/presentation/widgets/timeline/segment.model.dart'; -import 'package:immich_mobile/providers/infrastructure/metadata.provider.dart'; +import 'package:immich_mobile/providers/infrastructure/settings.provider.dart'; import 'package:immich_mobile/providers/infrastructure/timeline.provider.dart'; class TimelineArgs { diff --git a/mobile/lib/presentation/widgets/timeline/timeline.widget.dart b/mobile/lib/presentation/widgets/timeline/timeline.widget.dart index 2660b0da31..eb7a31ac8b 100644 --- a/mobile/lib/presentation/widgets/timeline/timeline.widget.dart +++ b/mobile/lib/presentation/widgets/timeline/timeline.widget.dart @@ -10,7 +10,6 @@ import 'package:flutter/rendering.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/events.model.dart'; -import 'package:immich_mobile/domain/models/metadata_key.dart'; import 'package:immich_mobile/domain/models/timeline.model.dart'; import 'package:immich_mobile/domain/utils/event_stream.dart'; import 'package:immich_mobile/extensions/asyncvalue_extensions.dart'; @@ -22,7 +21,7 @@ import 'package:immich_mobile/presentation/widgets/timeline/scrubber.widget.dart import 'package:immich_mobile/presentation/widgets/timeline/segment.model.dart'; import 'package:immich_mobile/presentation/widgets/timeline/timeline.state.dart'; import 'package:immich_mobile/presentation/widgets/timeline/timeline_drag_region.dart'; -import 'package:immich_mobile/providers/infrastructure/metadata.provider.dart'; +import 'package:immich_mobile/providers/infrastructure/settings.provider.dart'; import 'package:immich_mobile/providers/infrastructure/readonly_mode.provider.dart'; import 'package:immich_mobile/providers/infrastructure/timeline.provider.dart'; import 'package:immich_mobile/providers/timeline/multiselect.provider.dart'; @@ -397,7 +396,7 @@ class _SliverTimelineState extends ConsumerState<_SliverTimeline> { final grid = CustomScrollView( primary: true, physics: _scrollPhysics, - cacheExtent: maxHeight * 2, + scrollCacheExtent: .pixels(maxHeight * 2), slivers: [ if (isSelectionMode) const SelectionSliverAppBar() else if (widget.appBar != null) widget.appBar!, if (widget.topSliverWidget != null) widget.topSliverWidget!, @@ -459,7 +458,7 @@ class _SliverTimelineState extends ConsumerState<_SliverTimeline> { _restoreAssetIndex = targetAssetIndex; }); - ref.read(metadataProvider).write(MetadataKey.timelineTilesPerRow, _perRow); + ref.read(settingsProvider).write(.timelineTilesPerRow, _perRow); } }; }, @@ -503,7 +502,7 @@ class _SliverTimelineState extends ConsumerState<_SliverTimeline> { class _SliverSegmentedList extends SliverMultiBoxAdaptorWidget { final List _segments; - const _SliverSegmentedList({required List segments, required super.delegate}) : _segments = segments; + const _SliverSegmentedList({required this._segments, required super.delegate}); @override _RenderSliverTimelineBoxAdaptor createRenderObject(BuildContext context) => @@ -527,8 +526,7 @@ class _RenderSliverTimelineBoxAdaptor extends RenderSliverMultiBoxAdaptor { markNeedsLayout(); } - _RenderSliverTimelineBoxAdaptor({required super.childManager, required List segments}) - : _segments = segments; + _RenderSliverTimelineBoxAdaptor({required super.childManager, required this._segments}); int getMinChildIndexForScrollOffset(double offset) => _segments.findByOffset(offset)?.getMinChildIndexForScrollOffset(offset) ?? 0; diff --git a/mobile/lib/providers/album/pending_album_uploads.provider.dart b/mobile/lib/providers/album/pending_album_uploads.provider.dart index db857ba3c0..7b1188891b 100644 --- a/mobile/lib/providers/album/pending_album_uploads.provider.dart +++ b/mobile/lib/providers/album/pending_album_uploads.provider.dart @@ -67,6 +67,11 @@ class AlbumPendingUploadsNotifier extends AutoDisposeFamilyNotifier { await Future.delayed(const Duration(milliseconds: 500)); final backgroundManager = _ref.read(backgroundSyncProvider); - final isAlbumLinkedSyncEnable = _ref.read(metadataProvider).appConfig.backup.syncAlbums; + final isAlbumLinkedSyncEnable = _ref.read(appConfigProvider).backup.syncAlbums; try { bool syncSuccess = false; @@ -137,7 +137,7 @@ class AppLifeCycleNotifier extends StateNotifier { } Future _resumeBackup() async { - final isEnableBackup = _ref.read(metadataProvider).appConfig.backup.enabled; + final isEnableBackup = _ref.read(appConfigProvider).backup.enabled; if (isEnableBackup) { final currentUser = Store.tryGet(StoreKey.currentUser); diff --git a/mobile/lib/providers/auth.provider.dart b/mobile/lib/providers/auth.provider.dart index ae97909349..8a3f503553 100644 --- a/mobile/lib/providers/auth.provider.dart +++ b/mobile/lib/providers/auth.provider.dart @@ -3,7 +3,6 @@ import 'dart:convert'; import 'package:flutter_udid/flutter_udid.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/constants/constants.dart'; -import 'package:immich_mobile/domain/models/metadata_key.dart'; import 'package:immich_mobile/domain/models/store.model.dart'; import 'package:immich_mobile/domain/models/user.model.dart'; import 'package:immich_mobile/domain/services/user.service.dart'; @@ -11,7 +10,7 @@ import 'package:immich_mobile/entities/store.entity.dart'; import 'package:immich_mobile/models/auth/auth_state.model.dart'; import 'package:immich_mobile/models/auth/login_response.model.dart'; import 'package:immich_mobile/providers/api.provider.dart'; -import 'package:immich_mobile/providers/infrastructure/metadata.provider.dart'; +import 'package:immich_mobile/providers/infrastructure/settings.provider.dart'; import 'package:immich_mobile/providers/infrastructure/user.provider.dart'; import 'package:immich_mobile/services/api.service.dart'; import 'package:immich_mobile/services/auth.service.dart'; @@ -130,7 +129,7 @@ class AuthNotifier extends StateNotifier { await _apiService.updateHeaders(); final serverEndpoint = Store.get(StoreKey.serverEndpoint); - final headerMap = _ref.read(metadataProvider).systemConfig.network.customHeaders; + final headerMap = _ref.read(appConfigProvider).network.customHeaders; final customHeaders = headerMap.isEmpty ? null : jsonEncode(headerMap); await _widgetService.writeCredentials(serverEndpoint, accessToken, customHeaders); @@ -179,19 +178,19 @@ class AuthNotifier extends StateNotifier { } Future saveWifiName(String wifiName) async { - await _ref.read(metadataProvider).write(MetadataKey.networkPreferredWifiName, wifiName); + await _ref.read(settingsProvider).write(.networkPreferredWifiName, wifiName); } Future saveLocalEndpoint(String url) async { - await _ref.read(metadataProvider).write(MetadataKey.networkLocalEndpoint, url); + await _ref.read(settingsProvider).write(.networkLocalEndpoint, url); } String? getSavedWifiName() { - return _ref.read(metadataProvider).systemConfig.network.preferredWifiName; + return _ref.read(appConfigProvider).network.preferredWifiName; } String? getSavedLocalEndpoint() { - return _ref.read(metadataProvider).systemConfig.network.localEndpoint; + return _ref.read(appConfigProvider).network.localEndpoint; } /// Returns the current server endpoint (with /api) URL from the store diff --git a/mobile/lib/providers/cleanup.provider.dart b/mobile/lib/providers/cleanup.provider.dart index e4a3d10a15..378ceb010f 100644 --- a/mobile/lib/providers/cleanup.provider.dart +++ b/mobile/lib/providers/cleanup.provider.dart @@ -1,8 +1,8 @@ import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/constants/enums.dart'; import 'package:immich_mobile/domain/models/asset/base_asset.model.dart'; -import 'package:immich_mobile/infrastructure/repositories/metadata.repository.dart'; -import 'package:immich_mobile/providers/infrastructure/metadata.provider.dart'; +import 'package:immich_mobile/infrastructure/repositories/settings.repository.dart'; +import 'package:immich_mobile/providers/infrastructure/settings.provider.dart'; import 'package:immich_mobile/providers/user.provider.dart'; import 'package:immich_mobile/services/cleanup.service.dart'; @@ -54,21 +54,21 @@ final cleanupProvider = StateNotifierProvider((re return CleanupNotifier( ref.watch(cleanupServiceProvider), ref.watch(currentUserProvider)?.id, - ref.watch(metadataProvider), + ref.watch(settingsProvider), ); }); class CleanupNotifier extends StateNotifier { final CleanupService _cleanupService; final String? _userId; - final MetadataRepository _metadataRepository; + final SettingsRepository _settingsRepository; - CleanupNotifier(this._cleanupService, this._userId, this._metadataRepository) : super(const CleanupState()) { + CleanupNotifier(this._cleanupService, this._userId, this._settingsRepository) : super(const CleanupState()) { _loadPersistedSettings(); } void _loadPersistedSettings() { - final cleanup = _metadataRepository.appConfig.cleanup; + final cleanup = _settingsRepository.appConfig.cleanup; final keepFavorites = cleanup.keepFavorites; final keepMediaType = cleanup.keepMediaType; final keepAlbumIds = cleanup.keepAlbumIds.toSet(); @@ -87,18 +87,18 @@ class CleanupNotifier extends StateNotifier { state = state.copyWith(selectedDate: date, assetsToDelete: []); if (date != null) { final daysAgo = DateTime.now().difference(date).inDays; - _metadataRepository.write(.cleanupCutoffDaysAgo, daysAgo); + _settingsRepository.write(.cleanupCutoffDaysAgo, daysAgo); } } void setKeepMediaType(AssetKeepType keepMediaType) { state = state.copyWith(keepMediaType: keepMediaType, assetsToDelete: []); - _metadataRepository.write(.cleanupKeepMediaType, keepMediaType); + _settingsRepository.write(.cleanupKeepMediaType, keepMediaType); } void setKeepFavorites(bool keepFavorites) { state = state.copyWith(keepFavorites: keepFavorites, assetsToDelete: []); - _metadataRepository.write(.cleanupKeepFavorites, keepFavorites); + _settingsRepository.write(.cleanupKeepFavorites, keepFavorites); } void toggleKeepAlbum(String albumId) { @@ -118,7 +118,7 @@ class CleanupNotifier extends StateNotifier { } void _persistExcludedAlbumIds(Set albumIds) { - _metadataRepository.write(.cleanupKeepAlbumIds, albumIds.toList()); + _settingsRepository.write(.cleanupKeepAlbumIds, albumIds.toList()); } void cleanupStaleAlbumIds(Set existingAlbumIds) { @@ -131,7 +131,7 @@ class CleanupNotifier extends StateNotifier { } void applyDefaultAlbumSelections(List<(String id, String name)> albums) { - final isInitialized = _metadataRepository.appConfig.cleanup.defaultsInitialized; + final isInitialized = _settingsRepository.appConfig.cleanup.defaultsInitialized; if (isInitialized) { return; } @@ -144,7 +144,7 @@ class CleanupNotifier extends StateNotifier { _persistExcludedAlbumIds(keepAlbumIds); } - _metadataRepository.write(.cleanupDefaultsInitialized, true); + _settingsRepository.write(.cleanupDefaultsInitialized, true); } Future scanAssets() async { diff --git a/mobile/lib/providers/infrastructure/action.provider.dart b/mobile/lib/providers/infrastructure/action.provider.dart index d73f3f1963..aa734f56b8 100644 --- a/mobile/lib/providers/infrastructure/action.provider.dart +++ b/mobile/lib/providers/infrastructure/action.provider.dart @@ -5,15 +5,19 @@ import 'package:background_downloader/background_downloader.dart'; import 'package:flutter/material.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; 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/asset_edit.model.dart'; import 'package:immich_mobile/domain/services/asset.service.dart'; +import 'package:immich_mobile/domain/services/remote_album.service.dart'; import 'package:immich_mobile/models/download/livephotos_medatada.model.dart'; import 'package:immich_mobile/providers/asset_viewer/asset_viewer.provider.dart'; import 'package:immich_mobile/providers/backup/asset_upload_progress.provider.dart'; +import 'package:immich_mobile/providers/infrastructure/album.provider.dart'; import 'package:immich_mobile/providers/infrastructure/asset.provider.dart'; import 'package:immich_mobile/providers/infrastructure/asset_viewer/asset.provider.dart' show assetExifProvider; import 'package:immich_mobile/providers/infrastructure/tag.provider.dart'; +import 'package:immich_mobile/providers/server_info.provider.dart'; import 'package:immich_mobile/providers/timeline/multiselect.provider.dart'; import 'package:immich_mobile/providers/user.provider.dart'; import 'package:immich_mobile/providers/websocket.provider.dart'; @@ -21,6 +25,7 @@ import 'package:immich_mobile/routing/router.dart'; import 'package:immich_mobile/services/action.service.dart'; import 'package:immich_mobile/services/download.service.dart'; import 'package:immich_mobile/services/foreground_upload.service.dart'; +import 'package:immich_mobile/utils/semver.dart'; import 'package:immich_mobile/widgets/asset_grid/delete_dialog.dart'; import 'package:logging/logging.dart'; import 'package:openapi/api.dart'; @@ -371,6 +376,52 @@ class ActionNotifier extends Notifier { } } + Future addToAlbum(ActionSource source, RemoteAlbum album) async { + final selected = _getAssets(source).toList(growable: false); + if (selected.isEmpty) { + return const ActionResult(count: 0, success: true); + } + + final candidates = RemoteAlbumService.categorizeCandidates(selected); + final remoteIds = candidates.remoteAssetIds; + final localAssets = candidates.localAssetsToUpload; + final albumNotifier = ref.read(remoteAlbumProvider.notifier); + + int addedRemote = 0; + if (remoteIds.isNotEmpty) { + try { + addedRemote = await albumNotifier.addAssets(album.id, remoteIds); + } catch (error, stack) { + _logger.severe('Failed to add assets to album ${album.id}', error, stack); + return ActionResult(count: 0, success: false, error: error.toString()); + } + } + + // Keep the selection available for retry if the remote add fails. Once the + // album mutation succeeds, clear timeline selection so upload overlays can render. + if (source == ActionSource.timeline) { + ref.read(multiSelectProvider.notifier).reset(); + } + + if (localAssets.isEmpty) { + return ActionResult(count: addedRemote, success: true); + } + + final uploadResult = await upload( + source, + assets: localAssets, + onAssetUploaded: (asset, remoteId) async { + await albumNotifier.linkUploadedAssetToAlbum(album.id, asset, remoteId); + }, + ); + + return ActionResult( + count: addedRemote + uploadResult.count, + success: uploadResult.success, + error: uploadResult.error, + ); + } + Future removeFromAlbum(ActionSource source, String albumId) async { final ids = _getRemoteIdsForSource(source); try { @@ -463,11 +514,17 @@ class ActionNotifier extends Notifier { ActionSource source, BuildContext context, { Completer? cancelCompleter, + void Function(double progress)? onAssetDownloadProgress, }) async { final ids = _getAssets(source).toList(growable: false); try { - await _service.shareAssets(ids, context, cancelCompleter: cancelCompleter); + await _service.shareAssets( + ids, + context, + cancelCompleter: cancelCompleter, + onAssetDownloadProgress: onAssetDownloadProgress, + ); return ActionResult(count: ids.length, success: true); } catch (error, stack) { _logger.severe('Failed to share assets', error, stack); @@ -487,8 +544,16 @@ class ActionNotifier extends Notifier { } } - Future upload(ActionSource source, {List? assets}) async { + Future upload( + ActionSource source, { + List? assets, + FutureOr Function(LocalAsset asset, String remoteId)? onAssetUploaded, + }) async { final assetsToUpload = assets ?? _getAssets(source).whereType().toList(); + final assetById = {for (final a in assetsToUpload) a.id: a}; + final uploadedAssetIds = {}; + final failedAssetIds = {}; + final postUploadTasks = >[]; final progressNotifier = ref.read(assetUploadProgressProvider.notifier); final cancelToken = Completer(); @@ -510,16 +575,43 @@ class ActionNotifier extends Notifier { }, onSuccess: (localAssetId, remoteAssetId) { progressNotifier.remove(localAssetId); + uploadedAssetIds.add(localAssetId); + final asset = assetById[localAssetId]; + final callback = onAssetUploaded; + if (asset != null && callback != null) { + postUploadTasks.add( + Future.sync(() => callback(asset, remoteAssetId)).catchError((Object error, StackTrace stack) { + failedAssetIds.add(localAssetId); + progressNotifier.setError(localAssetId); + _logger.warning('Post-upload callback failed for $localAssetId', error, stack); + }), + ); + } }, onError: (localAssetId, errorMessage) { + failedAssetIds.add(localAssetId); progressNotifier.setError(localAssetId); }, ), ); - return ActionResult(count: assetsToUpload.length, success: true); + + await Future.wait(postUploadTasks); + final successCount = uploadedAssetIds.difference(failedAssetIds).length; + final isSuccess = successCount == assetsToUpload.length && failedAssetIds.isEmpty; + + return ActionResult( + count: successCount, + success: isSuccess, + error: isSuccess ? null : 'Failed to upload ${assetsToUpload.length - successCount} assets', + ); } catch (error, stack) { _logger.severe('Failed manually upload assets', error, stack); - return ActionResult(count: assetsToUpload.length, success: false, error: error.toString()); + + return ActionResult( + count: uploadedAssetIds.difference(failedAssetIds).length, + success: false, + error: error.toString(), + ); } finally { ref.read(manualUploadCancelTokenProvider.notifier).state = null; Future.delayed(const Duration(seconds: 2), () { @@ -536,14 +628,22 @@ class ActionNotifier extends Notifier { return ActionResult(count: ids.length, success: false, error: 'Expected single asset for applying edits'); } - final completer = ref.read(websocketProvider.notifier).waitForEvent("AssetEditReadyV1", (dynamic data) { - final eventAsset = SyncAssetV1.fromJson(data["asset"]); - return eventAsset?.id == ids.first; - }, const Duration(seconds: 10)); + Future editReady; + if (ref.read(serverInfoProvider).serverVersion >= const SemVer(major: 3, minor: 0, patch: 0)) { + editReady = ref.read(websocketProvider.notifier).waitForEvent("AssetEditReadyV2", (dynamic data) { + final eventAsset = SyncAssetV2.fromJson(data["asset"]); + return eventAsset?.id == ids.first; + }, const Duration(seconds: 10)); + } else { + editReady = ref.read(websocketProvider.notifier).waitForEvent("AssetEditReadyV1", (dynamic data) { + final eventAsset = SyncAssetV1.fromJson(data["asset"]); + return eventAsset?.id == ids.first; + }, const Duration(seconds: 10)); + } try { await _service.applyEdits(ids.first, edits); - await completer; + await editReady; return const ActionResult(count: 1, success: true); } catch (error, stack) { _logger.severe('Failed to apply edits to assets', error, stack); diff --git a/mobile/lib/providers/infrastructure/metadata.provider.dart b/mobile/lib/providers/infrastructure/metadata.provider.dart deleted file mode 100644 index 46ff1069f9..0000000000 --- a/mobile/lib/providers/infrastructure/metadata.provider.dart +++ /dev/null @@ -1,20 +0,0 @@ -import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:immich_mobile/domain/models/config/app_config.dart'; -import 'package:immich_mobile/domain/models/config/system_config.dart'; -import 'package:immich_mobile/infrastructure/repositories/metadata.repository.dart'; - -final metadataProvider = Provider.autoDispose((_) => MetadataRepository.instance); - -final appConfigProvider = Provider.autoDispose((ref) { - final repo = ref.watch(metadataProvider); - final subscription = repo.watchAppConfig().listen((event) => ref.state = event); - ref.onDispose(subscription.cancel); - return repo.appConfig; -}); - -final systemConfigProvider = Provider.autoDispose((ref) { - final repo = ref.watch(metadataProvider); - final subscription = repo.watchSystemConfig().listen((event) => ref.state = event); - ref.onDispose(subscription.cancel); - return repo.systemConfig; -}); diff --git a/mobile/lib/providers/infrastructure/platform.provider.dart b/mobile/lib/providers/infrastructure/platform.provider.dart index 01d0f61d1c..9f85235927 100644 --- a/mobile/lib/providers/infrastructure/platform.provider.dart +++ b/mobile/lib/providers/infrastructure/platform.provider.dart @@ -3,9 +3,10 @@ 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/local_image_api.g.dart'; +import 'package:immich_mobile/platform/native_sync_api.g.dart'; import 'package:immich_mobile/platform/network_api.g.dart'; +import 'package:immich_mobile/platform/permission_api.g.dart'; import 'package:immich_mobile/platform/remote_image_api.g.dart'; final backgroundWorkerFgServiceProvider = Provider((_) => BackgroundWorkerFgService(BackgroundWorkerFgHostApi())); @@ -16,6 +17,8 @@ final backgroundWorkerLockServiceProvider = Provider((_) => NativeSyncApi()); +final permissionApiProvider = Provider((_) => PermissionApi()); + final connectivityApiProvider = Provider((_) => ConnectivityApi()); final localImageApi = LocalImageApi(); diff --git a/mobile/lib/providers/infrastructure/remote_album.provider.dart b/mobile/lib/providers/infrastructure/remote_album.provider.dart index 73a796bd31..a4bbbae818 100644 --- a/mobile/lib/providers/infrastructure/remote_album.provider.dart +++ b/mobile/lib/providers/infrastructure/remote_album.provider.dart @@ -9,6 +9,7 @@ import 'package:immich_mobile/domain/services/remote_album.service.dart'; import 'package:immich_mobile/models/albums/album_search.model.dart'; import 'package:immich_mobile/providers/album/album_sort_by_options.provider.dart'; import 'package:immich_mobile/providers/album/pending_album_uploads.provider.dart'; +import 'package:immich_mobile/providers/backup/asset_upload_progress.provider.dart'; import 'package:immich_mobile/providers/infrastructure/album.provider.dart'; import 'package:immich_mobile/providers/user.provider.dart'; import 'package:immich_mobile/services/foreground_upload.service.dart'; @@ -207,6 +208,22 @@ class RemoteAlbumNotifier extends Notifier { return added; } + /// Links a freshly-uploaded local asset to an album using its new remote ID, + /// upserting a placeholder remote asset row so the local DB join survives + /// until the next sync catches up. + Future linkUploadedAssetToAlbum(String albumId, LocalAsset source, String remoteId) async { + final currentUser = ref.read(currentUserProvider); + if (currentUser == null) { + throw Exception('User not logged in'); + } + + final added = await _remoteAlbumService.linkUploadedAssetToAlbum(albumId, remoteId, currentUser, source); + if (added > 0) { + await _refreshAlbumInState(albumId); + } + return added; + } + /// Adds a heterogeneous asset selection to an album. Already-remote assets /// are linked immediately; local-only assets are queued in /// [pendingAlbumUploadsProvider] (so the album page can show them with @@ -221,11 +238,18 @@ class RemoteAlbumNotifier extends Notifier { final pendingNotifier = ref.read(pendingAlbumUploadsProvider(albumId).notifier); pendingNotifier.enqueue(candidates.localAssetsToUpload); + Completer? cancelToken; + if (candidates.localAssetsToUpload.isNotEmpty) { + cancelToken = Completer(); + ref.read(manualUploadCancelTokenProvider.notifier).state = cancelToken; + } + try { final added = await _remoteAlbumService.addAssetsToAlbum( albumId: albumId, uploader: currentUser, candidates: candidates, + cancelToken: cancelToken, uploadCallbacks: UploadCallbacks( onProgress: (localAssetId, _, bytes, totalBytes) { final progress = totalBytes > 0 ? bytes / totalBytes : 0.0; @@ -245,6 +269,15 @@ class RemoteAlbumNotifier extends Notifier { } _logger.severe('Failed to add assets to album $albumId', error, stack); rethrow; + } finally { + if (cancelToken != null) { + if (cancelToken.isCompleted) { + pendingNotifier.clear(); + } + if (ref.read(manualUploadCancelTokenProvider) == cancelToken) { + ref.read(manualUploadCancelTokenProvider.notifier).state = null; + } + } } } diff --git a/mobile/lib/providers/infrastructure/settings.provider.dart b/mobile/lib/providers/infrastructure/settings.provider.dart new file mode 100644 index 0000000000..d2b9dce1d6 --- /dev/null +++ b/mobile/lib/providers/infrastructure/settings.provider.dart @@ -0,0 +1,12 @@ +import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:immich_mobile/domain/models/config/app_config.dart'; +import 'package:immich_mobile/infrastructure/repositories/settings.repository.dart'; + +final settingsProvider = Provider.autoDispose((_) => SettingsRepository.instance); + +final appConfigProvider = Provider.autoDispose((ref) { + final repo = ref.watch(settingsProvider); + final subscription = repo.watchConfig().listen((event) => ref.state = event); + ref.onDispose(subscription.cancel); + return repo.appConfig; +}); diff --git a/mobile/lib/providers/infrastructure/sync.provider.dart b/mobile/lib/providers/infrastructure/sync.provider.dart index 5b9f29225e..75c8e09326 100644 --- a/mobile/lib/providers/infrastructure/sync.provider.dart +++ b/mobile/lib/providers/infrastructure/sync.provider.dart @@ -11,8 +11,8 @@ import 'package:immich_mobile/providers/infrastructure/asset.provider.dart'; import 'package:immich_mobile/providers/infrastructure/cancel.provider.dart'; import 'package:immich_mobile/providers/infrastructure/db.provider.dart'; import 'package:immich_mobile/providers/infrastructure/platform.provider.dart'; -import 'package:immich_mobile/providers/infrastructure/storage.provider.dart'; -import 'package:immich_mobile/repositories/local_files_manager.repository.dart'; +import 'package:immich_mobile/repositories/asset_media.repository.dart'; +import 'package:immich_mobile/repositories/permission.repository.dart'; final syncMigrationRepositoryProvider = Provider((ref) => SyncMigrationRepository(ref.watch(driftProvider))); @@ -22,8 +22,8 @@ final syncStreamServiceProvider = Provider( syncStreamRepository: ref.watch(syncStreamRepositoryProvider), localAssetRepository: ref.watch(localAssetRepository), trashedLocalAssetRepository: ref.watch(trashedLocalAssetRepository), - localFilesManager: ref.watch(localFilesManagerRepositoryProvider), - storageRepository: ref.watch(storageRepositoryProvider), + assetMediaRepository: ref.watch(assetMediaRepositoryProvider), + permissionRepository: ref.watch(permissionRepositoryProvider), syncMigrationRepository: ref.watch(syncMigrationRepositoryProvider), api: ref.watch(apiServiceProvider), cancelChecker: ref.watch(cancellationProvider), @@ -39,8 +39,8 @@ final localSyncServiceProvider = Provider( localAlbumRepository: ref.watch(localAlbumRepository), localAssetRepository: ref.watch(localAssetRepository), trashedLocalAssetRepository: ref.watch(trashedLocalAssetRepository), - localFilesManager: ref.watch(localFilesManagerRepositoryProvider), - storageRepository: ref.watch(storageRepositoryProvider), + assetMediaRepository: ref.watch(assetMediaRepositoryProvider), + permissionRepository: ref.watch(permissionRepositoryProvider), nativeSyncApi: ref.watch(nativeSyncApiProvider), ), ); diff --git a/mobile/lib/providers/infrastructure/timeline.provider.dart b/mobile/lib/providers/infrastructure/timeline.provider.dart index 9f2fdec519..b22c693033 100644 --- a/mobile/lib/providers/infrastructure/timeline.provider.dart +++ b/mobile/lib/providers/infrastructure/timeline.provider.dart @@ -3,7 +3,7 @@ import 'package:immich_mobile/domain/services/timeline.service.dart'; import 'package:immich_mobile/infrastructure/repositories/timeline.repository.dart'; import 'package:immich_mobile/presentation/widgets/timeline/timeline.state.dart'; import 'package:immich_mobile/providers/infrastructure/db.provider.dart'; -import 'package:immich_mobile/providers/infrastructure/metadata.provider.dart'; +import 'package:immich_mobile/providers/infrastructure/settings.provider.dart'; import 'package:immich_mobile/providers/user.provider.dart'; final timelineRepositoryProvider = Provider( @@ -29,7 +29,7 @@ final timelineServiceProvider = Provider( final timelineFactoryProvider = Provider( (ref) => TimelineFactory( timelineRepository: ref.watch(timelineRepositoryProvider), - metadataRepository: ref.watch(metadataProvider), + settingsRepository: ref.watch(settingsProvider), ), ); diff --git a/mobile/lib/providers/map/map_state.provider.dart b/mobile/lib/providers/map/map_state.provider.dart index b0a59f6a1e..b643264dca 100644 --- a/mobile/lib/providers/map/map_state.provider.dart +++ b/mobile/lib/providers/map/map_state.provider.dart @@ -1,8 +1,7 @@ import 'package:flutter/material.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:immich_mobile/domain/models/metadata_key.dart'; import 'package:immich_mobile/models/map/map_state.model.dart'; -import 'package:immich_mobile/providers/infrastructure/metadata.provider.dart'; +import 'package:immich_mobile/providers/infrastructure/settings.provider.dart'; import 'package:immich_mobile/providers/server_info.provider.dart'; final mapStateNotifierProvider = NotifierProvider(MapStateNotifier.new); @@ -27,12 +26,12 @@ class MapStateNotifier extends Notifier { } void switchTheme(ThemeMode mode) { - ref.read(metadataProvider).write(MetadataKey.mapThemeMode, mode); + ref.read(settingsProvider).write(.mapThemeMode, mode); state = state.copyWith(themeMode: mode); } void switchFavoriteOnly(bool isFavoriteOnly) { - ref.read(metadataProvider).write(MetadataKey.mapShowFavoriteOnly, isFavoriteOnly); + ref.read(settingsProvider).write(.mapShowFavoriteOnly, isFavoriteOnly); state = state.copyWith(showFavoriteOnly: isFavoriteOnly, shouldRefetchMarkers: true); } @@ -41,17 +40,17 @@ class MapStateNotifier extends Notifier { } void switchIncludeArchived(bool isIncludeArchived) { - ref.read(metadataProvider).write(MetadataKey.mapIncludeArchived, isIncludeArchived); + ref.read(settingsProvider).write(.mapIncludeArchived, isIncludeArchived); state = state.copyWith(includeArchived: isIncludeArchived, shouldRefetchMarkers: true); } void switchWithPartners(bool isWithPartners) { - ref.read(metadataProvider).write(MetadataKey.mapWithPartners, isWithPartners); + ref.read(settingsProvider).write(.mapWithPartners, isWithPartners); state = state.copyWith(withPartners: isWithPartners, shouldRefetchMarkers: true); } void setRelativeTime(int relativeTime) { - ref.read(metadataProvider).write(MetadataKey.mapRelativeDate, relativeTime); + ref.read(settingsProvider).write(.mapRelativeDate, relativeTime); state = state.copyWith(relativeTime: relativeTime, shouldRefetchMarkers: true); } } diff --git a/mobile/lib/providers/theme.provider.dart b/mobile/lib/providers/theme.provider.dart index 909b8137c1..962781586e 100644 --- a/mobile/lib/providers/theme.provider.dart +++ b/mobile/lib/providers/theme.provider.dart @@ -1,5 +1,5 @@ import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:immich_mobile/providers/infrastructure/metadata.provider.dart'; +import 'package:immich_mobile/providers/infrastructure/settings.provider.dart'; import 'package:immich_mobile/theme/color_scheme.dart'; import 'package:immich_mobile/theme/dynamic_theme.dart'; import 'package:immich_mobile/theme/theme_data.dart'; diff --git a/mobile/lib/providers/websocket.provider.dart b/mobile/lib/providers/websocket.provider.dart index a53f0aaaeb..8d9bd5bfe3 100644 --- a/mobile/lib/providers/websocket.provider.dart +++ b/mobile/lib/providers/websocket.provider.dart @@ -7,7 +7,7 @@ import 'package:immich_mobile/infrastructure/repositories/network.repository.dar import 'package:immich_mobile/models/server_info/server_version.model.dart'; import 'package:immich_mobile/providers/auth.provider.dart'; import 'package:immich_mobile/providers/background_sync.provider.dart'; -import 'package:immich_mobile/providers/infrastructure/metadata.provider.dart'; +import 'package:immich_mobile/providers/infrastructure/settings.provider.dart'; import 'package:immich_mobile/providers/server_info.provider.dart'; import 'package:immich_mobile/utils/debounce.dart'; import 'package:immich_mobile/utils/debug_print.dart'; @@ -193,7 +193,7 @@ class WebsocketNotifier extends StateNotifier { return; } - final isSyncAlbumEnabled = _ref.read(metadataProvider).appConfig.backup.syncAlbums; + final isSyncAlbumEnabled = _ref.read(appConfigProvider).backup.syncAlbums; try { unawaited( _ref.read(backgroundSyncProvider).syncWebsocketBatchV1(_batchedAssetUploadReady.toList()).then((_) { @@ -214,7 +214,7 @@ class WebsocketNotifier extends StateNotifier { return; } - final isSyncAlbumEnabled = _ref.read(metadataProvider).appConfig.backup.syncAlbums; + final isSyncAlbumEnabled = _ref.read(appConfigProvider).backup.syncAlbums; try { unawaited( _ref.read(backgroundSyncProvider).syncWebsocketBatchV2(_batchedAssetUploadReady.toList()).then((_) { diff --git a/mobile/lib/repositories/asset_media.repository.dart b/mobile/lib/repositories/asset_media.repository.dart index a2d8bfe162..e86a372768 100644 --- a/mobile/lib/repositories/asset_media.repository.dart +++ b/mobile/lib/repositories/asset_media.repository.dart @@ -1,26 +1,29 @@ import 'dart:async'; import 'dart:io'; +import 'package:background_downloader/background_downloader.dart'; import 'package:device_info_plus/device_info_plus.dart'; import 'package:flutter/widgets.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:immich_mobile/constants/constants.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/platform_extensions.dart'; -import 'package:immich_mobile/extensions/response_extensions.dart'; -import 'package:immich_mobile/repositories/asset_api.repository.dart'; +import 'package:immich_mobile/platform/native_sync_api.g.dart'; +import 'package:immich_mobile/providers/infrastructure/platform.provider.dart'; +import 'package:immich_mobile/services/api.service.dart'; +import 'package:immich_mobile/utils/image_url_builder.dart'; import 'package:logging/logging.dart'; -import 'package:path_provider/path_provider.dart'; import 'package:photo_manager/photo_manager.dart'; import 'package:share_plus/share_plus.dart'; -final assetMediaRepositoryProvider = Provider((ref) => AssetMediaRepository(ref.watch(assetApiRepositoryProvider))); +final assetMediaRepositoryProvider = Provider((ref) => AssetMediaRepository(ref.watch(nativeSyncApiProvider))); class AssetMediaRepository { - final AssetApiRepository _assetApiRepository; + final NativeSyncApi _nativeSyncApi; static final Logger _log = Logger("AssetMediaRepository"); - const AssetMediaRepository(this._assetApiRepository); + const AssetMediaRepository(this._nativeSyncApi); Future _androidSupportsTrash() async { if (Platform.isAndroid) { @@ -45,6 +48,27 @@ class AssetMediaRepository { return PhotoManager.editor.deleteWithIds(ids); } + Future _restoreFromTrashById(String mediaId, int type) async { + try { + return await _nativeSyncApi.restoreFromTrashById(mediaId, type); + } catch (e, s) { + _log.warning('Error restore file from trash by Id', e, s); + return false; + } + } + + Future> restoreAssetsFromTrash(Iterable assets) async { + final restoredIds = []; + for (final asset in assets) { + _log.info("Restoring from trash, localId: ${asset.id}, checksum: ${asset.checksum}"); + final result = await _restoreFromTrashById(asset.id, asset.type.index); + if (result) { + restoredIds.add(asset.id); + } + } + return restoredIds; + } + Future get(String id) async { final entity = await AssetEntity.fromId(id); return entity; @@ -81,10 +105,29 @@ class AssetMediaRepository { ); } - // TODO: make this more efficient - Future shareAssets(List assets, BuildContext context, {Completer? cancelCompleter}) async { + Future shareAssets( + List assets, + BuildContext context, { + Completer? cancelCompleter, + void Function(double progress)? onAssetDownloadProgress, + }) async { final downloadedXFiles = []; final tempFiles = []; + final totalAssets = assets.length; + var processedAssets = 0; + + void updateProgress([double currentAssetProgress = 0.0]) { + if (totalAssets <= 0) { + onAssetDownloadProgress?.call(1.0); + return; + } + + final normalizedAssetProgress = currentAssetProgress.clamp(0.0, 1.0); + final overallProgress = ((processedAssets + normalizedAssetProgress) / totalAssets).clamp(0.0, 1.0); + onAssetDownloadProgress?.call(overallProgress); + } + + updateProgress(); for (var asset in assets) { if (cancelCompleter != null && cancelCompleter.isCompleted) { @@ -101,6 +144,8 @@ class AssetMediaRepository { if (localId != null && !asset.isEdited) { File? f = await AssetEntity(id: localId, width: 1, height: 1, typeInt: 0).originFile; downloadedXFiles.add(XFile(f!.path)); + processedAssets++; + updateProgress(); if (CurrentPlatform.isIOS) { tempFiles.add(f); } @@ -108,22 +153,50 @@ class AssetMediaRepository { final remoteId = (asset is RemoteAsset) ? asset.id : asset.remoteId; if (remoteId == null) { _log.warning("Asset has no remote ID for sharing: $asset"); + processedAssets++; + updateProgress(); continue; } - final tempDir = await getTemporaryDirectory(); - final name = asset.name; - final tempFile = await File('${tempDir.path}/$name').create(); - final res = await _assetApiRepository.downloadAsset(remoteId, edited: true); + final taskId = 'share-$remoteId-${DateTime.now().microsecondsSinceEpoch}'; + final sanitizedFilename = asset.name.replaceAll(RegExp(r'[\\/]'), '_'); + final task = DownloadTask( + taskId: taskId, + url: getOriginalUrlForRemoteId(remoteId, edited: asset.isEdited), + headers: ApiService.getRequestHeaders(), + filename: sanitizedFilename, + baseDirectory: BaseDirectory.temporary, + group: kShareDownloadGroup, + updates: Updates.statusAndProgress, + ); + final statusUpdate = await FileDownloader().download( + task, + onProgress: (value) { + if (cancelCompleter != null && cancelCompleter.isCompleted) { + unawaited(FileDownloader().cancelTaskWithId(taskId)); + return; + } + updateProgress(value); + }, + ); - if (res.statusCode != 200) { - _log.severe("Download for $name failed", res.toLoggerString()); - continue; + if (cancelCompleter != null && cancelCompleter.isCompleted) { + await _cleanupTempFiles(tempFiles); + return 0; } - await tempFile.writeAsBytes(res.bodyBytes); - downloadedXFiles.add(XFile(tempFile.path)); - tempFiles.add(tempFile); + if (statusUpdate.status == TaskStatus.complete) { + final filePath = await task.filePath(); + final file = File(filePath); + tempFiles.add(file); + downloadedXFiles.add(XFile(filePath)); + processedAssets++; + updateProgress(); + continue; + } + _log.severe("Download for ${asset.name} failed with status ${statusUpdate.status}", statusUpdate.exception); + processedAssets++; + updateProgress(); } } diff --git a/mobile/lib/repositories/auth.repository.dart b/mobile/lib/repositories/auth.repository.dart index e71c752f44..dd9aed3a03 100644 --- a/mobile/lib/repositories/auth.repository.dart +++ b/mobile/lib/repositories/auth.repository.dart @@ -1,39 +1,39 @@ import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/infrastructure/repositories/db.repository.dart'; -import 'package:immich_mobile/infrastructure/repositories/metadata.repository.dart'; +import 'package:immich_mobile/infrastructure/repositories/settings.repository.dart'; import 'package:immich_mobile/infrastructure/repositories/sync_stream.repository.dart'; import 'package:immich_mobile/models/auth/auxilary_endpoint.model.dart'; import 'package:immich_mobile/providers/infrastructure/db.provider.dart'; -import 'package:immich_mobile/providers/infrastructure/metadata.provider.dart'; +import 'package:immich_mobile/providers/infrastructure/settings.provider.dart'; final authRepositoryProvider = Provider( - (ref) => AuthRepository(ref.watch(driftProvider), ref.watch(metadataProvider)), + (ref) => AuthRepository(ref.watch(driftProvider), ref.watch(settingsProvider)), ); class AuthRepository { final Drift _drift; - final MetadataRepository _metadata; + final SettingsRepository _settings; - const AuthRepository(this._drift, this._metadata); + const AuthRepository(this._drift, this._settings); Future clearLocalData() async { await SyncStreamRepository(_drift).reset(); } bool getEndpointSwitchingFeature() { - return _metadata.systemConfig.network.autoEndpointSwitching; + return _settings.appConfig.network.autoEndpointSwitching; } String? getPreferredWifiName() { - return _metadata.systemConfig.network.preferredWifiName; + return _settings.appConfig.network.preferredWifiName; } String? getLocalEndpoint() { - return _metadata.systemConfig.network.localEndpoint; + return _settings.appConfig.network.localEndpoint; } List getExternalEndpointList() { - return _metadata.systemConfig.network.externalEndpointList + return _settings.appConfig.network.externalEndpointList .map((url) => AuxilaryEndpoint(url: url, status: .valid)) .toList(); } diff --git a/mobile/lib/repositories/local_files_manager.repository.dart b/mobile/lib/repositories/local_files_manager.repository.dart deleted file mode 100644 index 6a6200b2e1..0000000000 --- a/mobile/lib/repositories/local_files_manager.repository.dart +++ /dev/null @@ -1,51 +0,0 @@ -import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:immich_mobile/domain/models/asset/base_asset.model.dart'; -import 'package:immich_mobile/services/local_files_manager.service.dart'; -import 'package:logging/logging.dart'; - -final localFilesManagerRepositoryProvider = Provider( - (ref) => LocalFilesManagerRepository(ref.watch(localFileManagerServiceProvider)), -); - -class LocalFilesManagerRepository { - LocalFilesManagerRepository(this._service); - - final Logger _logger = Logger('LocalFilesManagerRepo'); - final LocalFilesManagerService _service; - - Future moveToTrash(List mediaUrls) async { - return await _service.moveToTrash(mediaUrls); - } - - Future restoreFromTrash(String fileName, int type) async { - return await _service.restoreFromTrash(fileName, type); - } - - Future requestManageMediaPermission() async { - return await _service.requestManageMediaPermission(); - } - - Future hasManageMediaPermission() async { - return await _service.hasManageMediaPermission(); - } - - Future manageMediaPermission() async { - return await _service.manageMediaPermission(); - } - - Future> restoreAssetsFromTrash(Iterable assets) async { - final restoredIds = []; - for (final asset in assets) { - _logger.info("Restoring from trash, localId: ${asset.id}, remoteId: ${asset.checksum}"); - try { - final result = await _service.restoreFromTrashById(asset.id, asset.type.index); - if (result) { - restoredIds.add(asset.id); - } - } catch (e) { - _logger.warning("Restoring failure: $e"); - } - } - return restoredIds; - } -} diff --git a/mobile/lib/repositories/permission.repository.dart b/mobile/lib/repositories/permission.repository.dart index 74230a3652..e4b6d99f25 100644 --- a/mobile/lib/repositories/permission.repository.dart +++ b/mobile/lib/repositories/permission.repository.dart @@ -1,12 +1,16 @@ import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:immich_mobile/platform/permission_api.g.dart'; +import 'package:immich_mobile/providers/infrastructure/platform.provider.dart'; import 'package:permission_handler/permission_handler.dart'; -final permissionRepositoryProvider = Provider((_) { - return const PermissionRepository(); +final permissionRepositoryProvider = Provider((ref) { + return PermissionRepository(ref.watch(permissionApiProvider)); }); class PermissionRepository implements IPermissionRepository { - const PermissionRepository(); + final PermissionApi _permissionApi; + + const PermissionRepository(this._permissionApi); @override Future hasLocationWhenInUsePermission() { @@ -34,6 +38,21 @@ class PermissionRepository implements IPermissionRepository { Future openSettings() { return openAppSettings(); } + + @override + Future hasManageMediaPermission() { + return _permissionApi.hasManageMediaPermission(); + } + + @override + Future requestManageMediaPermission() { + return _permissionApi.requestManageMediaPermission(); + } + + @override + Future manageMediaPermission() { + return _permissionApi.manageMediaPermission(); + } } abstract interface class IPermissionRepository { @@ -42,4 +61,7 @@ abstract interface class IPermissionRepository { Future hasLocationAlwaysPermission(); Future requestLocationAlwaysPermission(); Future openSettings(); + Future hasManageMediaPermission(); + Future requestManageMediaPermission(); + Future manageMediaPermission(); } diff --git a/mobile/lib/repositories/widget.repository.dart b/mobile/lib/repositories/widget.repository.dart index f21d31e1ec..87209ac983 100644 --- a/mobile/lib/repositories/widget.repository.dart +++ b/mobile/lib/repositories/widget.repository.dart @@ -1,5 +1,6 @@ import 'package:home_widget/home_widget.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:immich_mobile/providers/infrastructure/platform.provider.dart'; final widgetRepositoryProvider = Provider((_) => const WidgetRepository()); @@ -14,7 +15,7 @@ class WidgetRepository { await HomeWidget.updateWidget(iOSName: iosName, qualifiedAndroidName: androidName); } - Future setAppGroupId(String appGroupId) async { - await HomeWidget.setAppGroupId(appGroupId); + Future setAppGroupId() async { + await HomeWidget.setAppGroupId(await networkApi.getAppGroupId()); } } diff --git a/mobile/lib/services/action.service.dart b/mobile/lib/services/action.service.dart index b9e601ca25..b22c6680a4 100644 --- a/mobile/lib/services/action.service.dart +++ b/mobile/lib/services/action.service.dart @@ -269,8 +269,18 @@ class ActionService { await _assetApiRepository.unStack(stackIds); } - Future shareAssets(List assets, BuildContext context, {Completer? cancelCompleter}) { - return _assetMediaRepository.shareAssets(assets, context, cancelCompleter: cancelCompleter); + Future shareAssets( + List assets, + BuildContext context, { + Completer? cancelCompleter, + void Function(double progress)? onAssetDownloadProgress, + }) { + return _assetMediaRepository.shareAssets( + assets, + context, + cancelCompleter: cancelCompleter, + onAssetDownloadProgress: onAssetDownloadProgress, + ); } Future> downloadAll(List assets) { diff --git a/mobile/lib/services/api.service.dart b/mobile/lib/services/api.service.dart index bc36c98768..a0828927ce 100644 --- a/mobile/lib/services/api.service.dart +++ b/mobile/lib/services/api.service.dart @@ -5,7 +5,7 @@ import 'dart:io'; import 'package:device_info_plus/device_info_plus.dart'; import 'package:immich_mobile/domain/models/store.model.dart'; import 'package:immich_mobile/entities/store.entity.dart'; -import 'package:immich_mobile/infrastructure/repositories/metadata.repository.dart'; +import 'package:immich_mobile/infrastructure/repositories/settings.repository.dart'; import 'package:immich_mobile/infrastructure/repositories/network.repository.dart'; import 'package:immich_mobile/utils/debug_print.dart'; import 'package:immich_mobile/utils/url_helper.dart'; @@ -13,7 +13,7 @@ import 'package:logging/logging.dart'; import 'package:openapi/api.dart'; class ApiService { - late ApiClient _apiClient; + final ApiClient _apiClient = ApiClient(basePath: ''); late UsersApi usersApi; late AuthenticationApi authenticationApi; @@ -54,7 +54,7 @@ class ApiService { } setEndpoint(String endpoint) { - _apiClient = ApiClient(basePath: endpoint); + _apiClient.basePath = endpoint; _apiClient.client = NetworkRepository.client; usersApi = UsersApi(_apiClient); authenticationApi = AuthenticationApi(_apiClient); @@ -177,9 +177,9 @@ class ApiService { if (serverEndpoint != null && serverEndpoint.isNotEmpty) { urls.add(serverEndpoint); } - final network = MetadataRepository.instance.systemConfig.network; + final network = SettingsRepository.instance.appConfig.network; final localEndpoint = network.localEndpoint; - if (localEndpoint != null) { + if (localEndpoint.isNotEmpty) { urls.add(localEndpoint); } for (final url in network.externalEndpointList) { @@ -191,7 +191,7 @@ class ApiService { } static Map getRequestHeaders() { - return MetadataRepository.instance.systemConfig.network.customHeaders; + return SettingsRepository.instance.appConfig.network.customHeaders; } ApiClient get apiClient => _apiClient; diff --git a/mobile/lib/services/auth.service.dart b/mobile/lib/services/auth.service.dart index 7d470ecd7a..0de22fd124 100644 --- a/mobile/lib/services/auth.service.dart +++ b/mobile/lib/services/auth.service.dart @@ -1,11 +1,11 @@ import 'dart:async'; import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:immich_mobile/domain/models/metadata_key.dart'; +import 'package:immich_mobile/domain/models/settings_key.dart'; import 'package:immich_mobile/domain/models/store.model.dart'; import 'package:immich_mobile/domain/utils/background_sync.dart'; import 'package:immich_mobile/entities/store.entity.dart'; -import 'package:immich_mobile/infrastructure/repositories/metadata.repository.dart'; +import 'package:immich_mobile/infrastructure/repositories/settings.repository.dart'; import 'package:immich_mobile/infrastructure/repositories/network.repository.dart'; import 'package:immich_mobile/models/auth/auxilary_endpoint.model.dart'; import 'package:immich_mobile/models/auth/login_response.model.dart'; @@ -100,7 +100,7 @@ class AuthService { _log.severe("Error clearing local data", error, stackTrace); }); - await MetadataRepository.instance.write(MetadataKey.backupEnabled, false); + await SettingsRepository.instance.write(SettingsKey.backupEnabled, false); } } @@ -110,7 +110,7 @@ class AuthService { /// - Authentication repository data /// - Current user information /// - Access token - /// - Asset ETag + /// - Server-specific endpoint configuration /// /// All deletions are executed in parallel using [Future.wait]. Future clearLocalData() async { @@ -120,6 +120,12 @@ class AuthService { _authRepository.clearLocalData(), Store.delete(StoreKey.currentUser), Store.delete(StoreKey.accessToken), + SettingsRepository.instance.clear(const [ + .networkAutoEndpointSwitching, + .networkPreferredWifiName, + .networkLocalEndpoint, + .networkExternalEndpointList, + ]), ]); } diff --git a/mobile/lib/services/background_upload.service.dart b/mobile/lib/services/background_upload.service.dart index 37577e3666..903fd02395 100644 --- a/mobile/lib/services/background_upload.service.dart +++ b/mobile/lib/services/background_upload.service.dart @@ -13,7 +13,7 @@ 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/metadata.repository.dart'; +import 'package:immich_mobile/infrastructure/repositories/settings.repository.dart'; import 'package:immich_mobile/infrastructure/repositories/storage.repository.dart'; import 'package:immich_mobile/providers/infrastructure/asset.provider.dart'; import 'package:immich_mobile/providers/infrastructure/storage.provider.dart'; @@ -359,7 +359,7 @@ class BackgroundUploadService { } bool _shouldRequireWiFi(LocalAsset asset) { - final backup = MetadataRepository.instance.appConfig.backup; + final backup = SettingsRepository.instance.appConfig.backup; if (asset.isVideo && backup.useCellularForVideos) { return false; } diff --git a/mobile/lib/services/foreground_upload.service.dart b/mobile/lib/services/foreground_upload.service.dart index 2fc1a92127..ef7f32d168 100644 --- a/mobile/lib/services/foreground_upload.service.dart +++ b/mobile/lib/services/foreground_upload.service.dart @@ -11,7 +11,7 @@ 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/infrastructure/repositories/backup.repository.dart'; -import 'package:immich_mobile/infrastructure/repositories/metadata.repository.dart'; +import 'package:immich_mobile/infrastructure/repositories/settings.repository.dart'; import 'package:immich_mobile/infrastructure/repositories/storage.repository.dart'; import 'package:immich_mobile/platform/connectivity_api.g.dart'; import 'package:immich_mobile/providers/infrastructure/platform.provider.dart'; @@ -451,7 +451,7 @@ class ForegroundUploadService { } bool _shouldRequireWiFi(LocalAsset asset) { - final backup = MetadataRepository.instance.appConfig.backup; + final backup = SettingsRepository.instance.appConfig.backup; if (asset.isVideo && backup.useCellularForVideos) { return false; } diff --git a/mobile/lib/services/local_files_manager.service.dart b/mobile/lib/services/local_files_manager.service.dart deleted file mode 100644 index 0cc00f3e4b..0000000000 --- a/mobile/lib/services/local_files_manager.service.dart +++ /dev/null @@ -1,66 +0,0 @@ -import 'package:flutter/services.dart'; -import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:logging/logging.dart'; - -final localFileManagerServiceProvider = Provider((ref) => const LocalFilesManagerService()); - -class LocalFilesManagerService { - const LocalFilesManagerService(); - - static final Logger _logger = Logger('LocalFilesManager'); - static const MethodChannel _channel = MethodChannel('file_trash'); - - Future moveToTrash(List mediaUrls) async { - try { - return await _channel.invokeMethod('moveToTrash', {'mediaUrls': mediaUrls}); - } catch (e, s) { - _logger.warning('Error moving file to trash', e, s); - return false; - } - } - - Future restoreFromTrash(String fileName, int type) async { - try { - return await _channel.invokeMethod('restoreFromTrash', {'fileName': fileName, 'type': type}); - } catch (e, s) { - _logger.warning('Error restore file from trash', e, s); - return false; - } - } - - Future restoreFromTrashById(String mediaId, int type) async { - try { - return await _channel.invokeMethod('restoreFromTrash', {'mediaId': mediaId, 'type': type}); - } catch (e, s) { - _logger.warning('Error restore file from trash by Id', e, s); - return false; - } - } - - Future requestManageMediaPermission() async { - try { - return await _channel.invokeMethod('requestManageMediaPermission'); - } catch (e, s) { - _logger.warning('Error requesting manage media permission', e, s); - return false; - } - } - - Future hasManageMediaPermission() async { - try { - return await _channel.invokeMethod('hasManageMediaPermission'); - } catch (e, s) { - _logger.warning('Error requesting manage media permission state', e, s); - return false; - } - } - - Future manageMediaPermission() async { - try { - return await _channel.invokeMethod('manageMediaPermission'); - } catch (e, s) { - _logger.warning('Error requesting manage media permission settings', e, s); - return false; - } - } -} diff --git a/mobile/lib/services/widget.service.dart b/mobile/lib/services/widget.service.dart index 23ec0aa770..91f65dd684 100644 --- a/mobile/lib/services/widget.service.dart +++ b/mobile/lib/services/widget.service.dart @@ -12,7 +12,7 @@ class WidgetService { const WidgetService(this._repository); Future writeCredentials(String serverURL, String sessionKey, String? customHeaders) async { - await _repository.setAppGroupId(appShareGroupId); + await _repository.setAppGroupId(); await _repository.saveData(kWidgetServerEndpoint, serverURL); await _repository.saveData(kWidgetAuthToken, sessionKey); @@ -25,7 +25,7 @@ class WidgetService { } Future clearCredentials() async { - await _repository.setAppGroupId(appShareGroupId); + await _repository.setAppGroupId(); await _repository.saveData(kWidgetServerEndpoint, ""); await _repository.saveData(kWidgetAuthToken, ""); await _repository.saveData(kWidgetCustomHeaders, ""); diff --git a/mobile/lib/utils/bootstrap.dart b/mobile/lib/utils/bootstrap.dart index 68ebfe9c9f..9bd652381a 100644 --- a/mobile/lib/utils/bootstrap.dart +++ b/mobile/lib/utils/bootstrap.dart @@ -6,7 +6,7 @@ import 'package:immich_mobile/extensions/translate_extensions.dart'; import 'package:immich_mobile/infrastructure/repositories/db.repository.dart'; import 'package:immich_mobile/infrastructure/repositories/log.repository.dart'; import 'package:immich_mobile/infrastructure/repositories/logger_db.repository.dart'; -import 'package:immich_mobile/infrastructure/repositories/metadata.repository.dart'; +import 'package:immich_mobile/infrastructure/repositories/settings.repository.dart'; import 'package:immich_mobile/infrastructure/repositories/network.repository.dart'; import 'package:immich_mobile/infrastructure/repositories/store.repository.dart'; import 'package:photo_manager/photo_manager.dart'; @@ -49,11 +49,11 @@ abstract final class Bootstrap { await StoreService.init(storeRepository: storeRepo, listenUpdates: listenStoreUpdates); - final metadataRepo = await MetadataRepository.ensureInitialized(drift); + final settingsRepo = await SettingsRepository.ensureInitialized(drift); await LogService.init( logRepository: LogRepository(logDb), - metadataRepository: metadataRepo, + settingsRepository: settingsRepo, shouldBuffer: shouldBufferLogs, ); diff --git a/mobile/lib/utils/migration.dart b/mobile/lib/utils/migration.dart index 41301fb227..3afa554e29 100644 --- a/mobile/lib/utils/migration.dart +++ b/mobile/lib/utils/migration.dart @@ -1,16 +1,18 @@ import 'dart:async'; import 'dart:convert'; +import 'package:collection/collection.dart'; import 'package:drift/drift.dart'; import 'package:flutter/material.dart'; import 'package:immich_mobile/constants/colors.dart'; import 'package:immich_mobile/constants/enums.dart'; +import 'package:immich_mobile/domain/models/config/app_config.dart'; import 'package:immich_mobile/domain/models/log.model.dart'; -import 'package:immich_mobile/domain/models/metadata_key.dart'; +import 'package:immich_mobile/domain/models/settings_key.dart'; import 'package:immich_mobile/domain/models/store.model.dart'; import 'package:immich_mobile/domain/models/timeline.model.dart'; import 'package:immich_mobile/entities/store.entity.dart'; -import 'package:immich_mobile/infrastructure/entities/metadata.entity.drift.dart'; +import 'package:immich_mobile/infrastructure/entities/settings.entity.drift.dart'; import 'package:immich_mobile/infrastructure/repositories/db.repository.dart'; import 'package:immich_mobile/infrastructure/repositories/network.repository.dart'; import 'package:immich_mobile/models/auth/auxilary_endpoint.model.dart'; @@ -72,80 +74,76 @@ Future _migrateTo25() async { Future _migrateTo26(Drift drift) async { final migrator = _StoreMigrator(drift); - await migrator.migrateEnumIndex(StoreKey.legacyLogLevel, MetadataKey.logLevel, LogLevel.values); + await migrator.migrateEnumIndex(StoreKey.legacyLogLevel, SettingsKey.logLevel, LogLevel.values); // Theme - await migrator.migrateEnumName(StoreKey.legacyThemeMode, MetadataKey.themeMode, ThemeMode.values); - await migrator.migrateEnumName(StoreKey.legacyPrimaryColor, MetadataKey.themePrimaryColor, ImmichColorPreset.values); - await migrator.migrateBool(StoreKey.legacyDynamicTheme, MetadataKey.themeDynamic); - await migrator.migrateBool(StoreKey.legacyColorfulInterface, MetadataKey.themeColorfulInterface); + await migrator.migrateEnumName(StoreKey.legacyThemeMode, SettingsKey.themeMode, ThemeMode.values); + await migrator.migrateEnumName(StoreKey.legacyPrimaryColor, SettingsKey.themePrimaryColor, ImmichColorPreset.values); + await migrator.migrateBool(StoreKey.legacyDynamicTheme, SettingsKey.themeDynamic); + await migrator.migrateBool(StoreKey.legacyColorfulInterface, SettingsKey.themeColorfulInterface); // Cleanup final cleanupKeepAlbumIds = await migrator.readLegacyStoreString(StoreKey.legacyCleanupKeepAlbumIds.id); if (cleanupKeepAlbumIds != null) { final ids = cleanupKeepAlbumIds.split(',').where((id) => id.isNotEmpty).toList(); - migrator.stage(StoreKey.legacyCleanupKeepAlbumIds, MetadataKey.cleanupKeepAlbumIds, ids); + migrator.stage(StoreKey.legacyCleanupKeepAlbumIds, SettingsKey.cleanupKeepAlbumIds, ids); } - await migrator.migrateBool(StoreKey.legacyCleanupKeepFavorites, MetadataKey.cleanupKeepFavorites); + await migrator.migrateBool(StoreKey.legacyCleanupKeepFavorites, SettingsKey.cleanupKeepFavorites); await migrator.migrateEnumIndex( StoreKey.legacyCleanupKeepMediaType, - MetadataKey.cleanupKeepMediaType, + SettingsKey.cleanupKeepMediaType, AssetKeepType.values, ); - await migrator.migrateInt(StoreKey.legacyCleanupCutoffDaysAgo, MetadataKey.cleanupCutoffDaysAgo); - await migrator.migrateBool(StoreKey.legacyCleanupDefaultsInitialized, MetadataKey.cleanupDefaultsInitialized); + await migrator.migrateInt(StoreKey.legacyCleanupCutoffDaysAgo, SettingsKey.cleanupCutoffDaysAgo); + await migrator.migrateBool(StoreKey.legacyCleanupDefaultsInitialized, SettingsKey.cleanupDefaultsInitialized); // Map - await migrator.migrateBool(StoreKey.legacyMapShowFavoriteOnly, MetadataKey.mapShowFavoriteOnly); - await migrator.migrateInt(StoreKey.legacyMapRelativeDate, MetadataKey.mapRelativeDate); - await migrator.migrateBool(StoreKey.legacyMapIncludeArchived, MetadataKey.mapIncludeArchived); - await migrator.migrateEnumIndex(StoreKey.legacyMapThemeMode, MetadataKey.mapThemeMode, ThemeMode.values); - await migrator.migrateBool(StoreKey.legacyMapwithPartners, MetadataKey.mapWithPartners); + await migrator.migrateBool(StoreKey.legacyMapShowFavoriteOnly, SettingsKey.mapShowFavoriteOnly); + await migrator.migrateInt(StoreKey.legacyMapRelativeDate, SettingsKey.mapRelativeDate); + await migrator.migrateBool(StoreKey.legacyMapIncludeArchived, SettingsKey.mapIncludeArchived); + await migrator.migrateEnumIndex(StoreKey.legacyMapThemeMode, SettingsKey.mapThemeMode, ThemeMode.values); + await migrator.migrateBool(StoreKey.legacyMapwithPartners, SettingsKey.mapWithPartners); // Timeline - await migrator.migrateInt(StoreKey.legacyTilesPerRow, MetadataKey.timelineTilesPerRow); + await migrator.migrateInt(StoreKey.legacyTilesPerRow, SettingsKey.timelineTilesPerRow); await migrator.migrateEnumIndex( StoreKey.legacyGroupAssetsBy, - MetadataKey.timelineGroupAssetsBy, + SettingsKey.timelineGroupAssetsBy, GroupAssetsBy.values, ); - await migrator.migrateBool(StoreKey.legacyStorageIndicator, MetadataKey.timelineStorageIndicator); + await migrator.migrateBool(StoreKey.legacyStorageIndicator, SettingsKey.timelineStorageIndicator); // Image - await migrator.migrateBool(StoreKey.legacyPreferRemoteImage, MetadataKey.imagePreferRemote); - await migrator.migrateBool(StoreKey.legacyLoadOriginal, MetadataKey.imageLoadOriginal); + await migrator.migrateBool(StoreKey.legacyPreferRemoteImage, SettingsKey.imagePreferRemote); + await migrator.migrateBool(StoreKey.legacyLoadOriginal, SettingsKey.imageLoadOriginal); // Viewer - await migrator.migrateBool(StoreKey.legacyLoopVideo, MetadataKey.viewerLoopVideo); - await migrator.migrateBool(StoreKey.legacyLoadOriginalVideo, MetadataKey.viewerLoadOriginalVideo); - await migrator.migrateBool(StoreKey.legacyAutoPlayVideo, MetadataKey.viewerAutoPlayVideo); - await migrator.migrateBool(StoreKey.legacyTapToNavigate, MetadataKey.viewerTapToNavigate); + await migrator.migrateBool(StoreKey.legacyLoopVideo, SettingsKey.viewerLoopVideo); + await migrator.migrateBool(StoreKey.legacyLoadOriginalVideo, SettingsKey.viewerLoadOriginalVideo); + await migrator.migrateBool(StoreKey.legacyAutoPlayVideo, SettingsKey.viewerAutoPlayVideo); + await migrator.migrateBool(StoreKey.legacyTapToNavigate, SettingsKey.viewerTapToNavigate); // Network - await migrator.migrateBool(StoreKey.legacyAutoEndpointSwitching, MetadataKey.networkAutoEndpointSwitching); - await migrator.migrateString(StoreKey.legacyPreferredWifiName, MetadataKey.networkPreferredWifiName); - await migrator.migrateString(StoreKey.legacyLocalEndpoint, MetadataKey.networkLocalEndpoint); + await migrator.migrateBool(StoreKey.legacyAutoEndpointSwitching, SettingsKey.networkAutoEndpointSwitching); + await migrator.migrateString(StoreKey.legacyPreferredWifiName, SettingsKey.networkPreferredWifiName); + await migrator.migrateString(StoreKey.legacyLocalEndpoint, SettingsKey.networkLocalEndpoint); await _migrateExternalEndpointList(migrator); await _migrateCustomHeaders(migrator); // Album await _migrateAlbumSortMode(migrator); - await migrator.migrateBool(StoreKey.legacySelectedAlbumSortReverse, MetadataKey.albumIsReverse); - await migrator.migrateBool(StoreKey.legacyAlbumGridView, MetadataKey.albumIsGrid); + await migrator.migrateBool(StoreKey.legacySelectedAlbumSortReverse, SettingsKey.albumIsReverse); + await migrator.migrateBool(StoreKey.legacyAlbumGridView, SettingsKey.albumIsGrid); // Backup - await migrator.migrateBool(StoreKey.legacyEnableBackup, MetadataKey.backupEnabled); - await migrator.migrateBool(StoreKey.legacyUseWifiForUploadVideos, MetadataKey.backupUseCellularForVideos); - await migrator.migrateBool(StoreKey.legacyUseWifiForUploadPhotos, MetadataKey.backupUseCellularForPhotos); - await migrator.migrateBool(StoreKey.legacyBackupRequireCharging, MetadataKey.backupRequireCharging); - await migrator.migrateInt(StoreKey.legacyBackupTriggerDelay, MetadataKey.backupTriggerDelay); - await migrator.migrateBool(StoreKey.legacySyncAlbums, MetadataKey.backupSyncAlbums); + await migrator.migrateBool(StoreKey.legacyEnableBackup, SettingsKey.backupEnabled); + await migrator.migrateBool(StoreKey.legacyUseWifiForUploadVideos, SettingsKey.backupUseCellularForVideos); + await migrator.migrateBool(StoreKey.legacyUseWifiForUploadPhotos, SettingsKey.backupUseCellularForPhotos); + await migrator.migrateBool(StoreKey.legacyBackupRequireCharging, SettingsKey.backupRequireCharging); + await migrator.migrateInt(StoreKey.legacyBackupTriggerDelay, SettingsKey.backupTriggerDelay); + await migrator.migrateBool(StoreKey.legacySyncAlbums, SettingsKey.backupSyncAlbums); await migrator.complete(); } Future _migrateAlbumSortMode(_StoreMigrator migrator) async { final raw = await migrator.readLegacyStoreInt(StoreKey.legacySelectedAlbumSortOrder.id); - if (raw == null) { + final mode = AlbumSortMode.values.firstWhereOrNull((e) => raw != null && e.storeIndex == raw); + if (mode == null) { return; } - final mode = AlbumSortMode.values.firstWhere( - (e) => e.storeIndex == raw, - orElse: () => MetadataKey.albumSortMode.defaultValue, - ); - - migrator.stage(StoreKey.legacySelectedAlbumSortOrder, MetadataKey.albumSortMode, mode); + migrator.stage(StoreKey.legacySelectedAlbumSortOrder, SettingsKey.albumSortMode, mode); } Future _migrateExternalEndpointList(_StoreMigrator migrator) async { @@ -169,7 +167,7 @@ Future _migrateExternalEndpointList(_StoreMigrator migrator) async { // ignore invalid entries } - migrator.stage(StoreKey.legacyExternalEndpointList, MetadataKey.networkExternalEndpointList, urls); + migrator.stage(StoreKey.legacyExternalEndpointList, SettingsKey.networkExternalEndpointList, urls); } Future _migrateCustomHeaders(_StoreMigrator migrator) async { @@ -192,30 +190,34 @@ Future _migrateCustomHeaders(_StoreMigrator migrator) async { // ignore invalid entries } - migrator.stage(StoreKey.legacyCustomHeaders, MetadataKey.networkCustomHeaders, headers); + migrator.stage(StoreKey.legacyCustomHeaders, SettingsKey.networkCustomHeaders, headers); } class _StoreMigrator { final Drift _db; - final Map, Object> _cache = {}; + final Map, Object> _cache = {}; final List _migratedStoreIds = []; _StoreMigrator(this._db); - Future migrateEnumIndex(StoreKey legacyKey, MetadataKey newKey, List values) async { + Future migrateEnumIndex(StoreKey legacyKey, SettingsKey newKey, List values) async { final index = await readLegacyStoreInt(legacyKey.id); if (index == null) { return; } - final enumValue = values.elementAtOrNull(index) ?? newKey.defaultValue; + final enumValue = values.elementAtOrNull(index); + if (enumValue == null) { + return; + } + _cache[newKey] = enumValue; _migratedStoreIds.add(legacyKey.id); } Future migrateEnumName( StoreKey legacyKey, - MetadataKey newKey, + SettingsKey newKey, List values, ) async { final name = await readLegacyStoreString(legacyKey.id); @@ -223,12 +225,16 @@ class _StoreMigrator { return; } - final enumValue = values.firstWhere((e) => e.name == name, orElse: () => newKey.defaultValue); + final enumValue = values.firstWhereOrNull((e) => e.name == name); + if (enumValue == null) { + return; + } + _cache[newKey] = enumValue; _migratedStoreIds.add(legacyKey.id); } - Future migrateBool(StoreKey legacyKey, MetadataKey newKey) async { + Future migrateBool(StoreKey legacyKey, SettingsKey newKey) async { final intValue = await readLegacyStoreInt(legacyKey.id); if (intValue == null) { return; @@ -239,7 +245,7 @@ class _StoreMigrator { _migratedStoreIds.add(legacyKey.id); } - Future migrateInt(StoreKey legacyKey, MetadataKey newKey) async { + Future migrateInt(StoreKey legacyKey, SettingsKey newKey) async { final intValue = await readLegacyStoreInt(legacyKey.id); if (intValue == null) { return; @@ -249,7 +255,7 @@ class _StoreMigrator { _migratedStoreIds.add(legacyKey.id); } - Future migrateString(StoreKey legacyKey, MetadataKey newKey) async { + Future migrateString(StoreKey legacyKey, SettingsKey newKey) async { final value = await readLegacyStoreString(legacyKey.id); if (value == null) { return; @@ -259,7 +265,7 @@ class _StoreMigrator { _migratedStoreIds.add(legacyKey.id); } - void stage(StoreKey legacyKey, MetadataKey newKey, T value) { + void stage(StoreKey legacyKey, SettingsKey newKey, T value) { _cache[newKey] = value; _migratedStoreIds.add(legacyKey.id); } @@ -267,9 +273,12 @@ class _StoreMigrator { Future complete() async { await _db.batch((batch) { for (final entry in _cache.entries) { + if (entry.value == defaultConfig.read(entry.key)) { + continue; + } batch.insert( - _db.metadataEntity, - MetadataEntityCompanion(key: Value(entry.key.key), value: Value(entry.key.encode(entry.value))), + _db.settingsEntity, + SettingsEntityCompanion(key: Value(entry.key.name), value: Value(entry.key.encode(entry.value))), mode: InsertMode.insertOrReplace, ); } diff --git a/mobile/lib/widgets/common/immich_sliver_app_bar.dart b/mobile/lib/widgets/common/immich_sliver_app_bar.dart index 32aa766dec..a81082753a 100644 --- a/mobile/lib/widgets/common/immich_sliver_app_bar.dart +++ b/mobile/lib/widgets/common/immich_sliver_app_bar.dart @@ -10,7 +10,7 @@ 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/metadata.provider.dart'; +import 'package:immich_mobile/providers/infrastructure/settings.provider.dart'; import 'package:immich_mobile/providers/infrastructure/readonly_mode.provider.dart'; import 'package:immich_mobile/providers/server_info.provider.dart'; import 'package:immich_mobile/providers/sync_status.provider.dart'; diff --git a/mobile/lib/widgets/forms/login/login_form.dart b/mobile/lib/widgets/forms/login/login_form.dart index 4967f28718..090c9bb2b8 100644 --- a/mobile/lib/widgets/forms/login/login_form.dart +++ b/mobile/lib/widgets/forms/login/login_form.dart @@ -15,14 +15,14 @@ import 'package:immich_mobile/domain/models/store.model.dart'; import 'package:immich_mobile/entities/store.entity.dart'; import 'package:immich_mobile/extensions/build_context_extensions.dart'; import 'package:immich_mobile/extensions/translate_extensions.dart'; -import 'package:immich_mobile/infrastructure/repositories/metadata.repository.dart'; +import 'package:immich_mobile/infrastructure/repositories/settings.repository.dart'; import 'package:immich_mobile/providers/auth.provider.dart'; import 'package:immich_mobile/providers/background_sync.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/repositories/local_files_manager.repository.dart'; +import 'package:immich_mobile/repositories/permission.repository.dart'; import 'package:immich_mobile/routing/router.dart'; import 'package:immich_mobile/utils/provider_utils.dart'; import 'package:immich_mobile/utils/url_helper.dart'; @@ -187,13 +187,13 @@ class LoginForm extends HookConsumerWidget { await backgroundManager.syncRemote(); await backgroundManager.hashAssets(); - if (MetadataRepository.instance.appConfig.backup.syncAlbums) { + if (SettingsRepository.instance.appConfig.backup.syncAlbums) { await backgroundManager.syncLinkedAlbum(); } } getManageMediaPermission() async { - final hasPermission = await ref.read(localFilesManagerRepositoryProvider).hasManageMediaPermission(); + final hasPermission = await ref.read(permissionRepositoryProvider).hasManageMediaPermission(); if (!hasPermission) { await showDialog( context: context, @@ -224,7 +224,7 @@ class LoginForm extends HookConsumerWidget { ), TextButton( onPressed: () { - ref.read(localFilesManagerRepositoryProvider).requestManageMediaPermission(); + unawaited(ref.read(permissionRepositoryProvider).requestManageMediaPermission()); Navigator.of(context).pop(); }, child: Text( diff --git a/mobile/lib/widgets/photo_view/src/core/photo_view_core.dart b/mobile/lib/widgets/photo_view/src/core/photo_view_core.dart index 2f775f57e2..265feb756e 100644 --- a/mobile/lib/widgets/photo_view/src/core/photo_view_core.dart +++ b/mobile/lib/widgets/photo_view/src/core/photo_view_core.dart @@ -139,8 +139,6 @@ class PhotoViewCoreState extends State PhotoViewHeroAttributes? get heroAttributes => widget.heroAttributes; - late ScaleBoundaries cachedScaleBoundaries = widget.scaleBoundaries; - void handleScaleAnimation() { scale = _scaleAnimation!.value; } @@ -303,7 +301,7 @@ class PhotoViewCoreState extends State controller.scaleAnimationBuilder(_animateControllerScale); controller.rotationAnimationBuilder(_animateControllerRotation); - cachedScaleBoundaries = widget.scaleBoundaries; + _updateScaleBoundaries(); _scaleAnimationController = AnimationController(vsync: this) ..addListener(handleScaleAnimation) @@ -334,14 +332,29 @@ class PhotoViewCoreState extends State widget.onTapDown?.call(context, details, controller.value); } - @override - Widget build(BuildContext context) { - // Check if we need a recalc on the scale - if (widget.scaleBoundaries != cachedScaleBoundaries) { - markNeedsScaleRecalc = true; - cachedScaleBoundaries = widget.scaleBoundaries; + void _updateScaleBoundaries() { + final prev = controller.scaleBoundaries; + if (prev == widget.scaleBoundaries) { + return; } + if (prev != null && controller.scale != null && prev.initialScale > 0) { + final ratio = widget.scaleBoundaries.initialScale / prev.initialScale; + controller.setScaleInvisibly(controller.scale! * ratio); + } else { + markNeedsScaleRecalc = true; + } + controller.scaleBoundaries = widget.scaleBoundaries; + } + + @override + void didUpdateWidget(PhotoViewCore oldWidget) { + super.didUpdateWidget(oldWidget); + _updateScaleBoundaries(); + } + + @override + Widget build(BuildContext context) { return StreamBuilder( stream: controller.outputStateStream, initialData: controller.prevValue, diff --git a/mobile/lib/widgets/photo_view/src/photo_view_wrappers.dart b/mobile/lib/widgets/photo_view/src/photo_view_wrappers.dart index d8d2ae7ee5..a9cfeb3a40 100644 --- a/mobile/lib/widgets/photo_view/src/photo_view_wrappers.dart +++ b/mobile/lib/widgets/photo_view/src/photo_view_wrappers.dart @@ -145,7 +145,6 @@ class _ImageWrapperState extends State { _lastStack = null; _didLoadSynchronously = synchronousCall; - widget.controller.scaleBoundaries = scaleBoundaries; } synchronousCall && !_didLoadSynchronously ? setupCB() : setState(setupCB); diff --git a/mobile/lib/widgets/settings/advanced_settings.dart b/mobile/lib/widgets/settings/advanced_settings.dart index 60557aaaca..542a7cc5e2 100644 --- a/mobile/lib/widgets/settings/advanced_settings.dart +++ b/mobile/lib/widgets/settings/advanced_settings.dart @@ -7,10 +7,10 @@ import 'package:flutter_hooks/flutter_hooks.dart' hide Store; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/domain/services/log.service.dart'; import 'package:immich_mobile/extensions/build_context_extensions.dart'; -import 'package:immich_mobile/providers/infrastructure/metadata.provider.dart'; +import 'package:immich_mobile/providers/infrastructure/settings.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/repositories/local_files_manager.repository.dart'; +import 'package:immich_mobile/repositories/permission.repository.dart'; import 'package:immich_mobile/services/app_settings.service.dart'; import 'package:immich_mobile/utils/bytes_units.dart'; import 'package:immich_mobile/utils/hooks/app_settings_update_hook.dart'; @@ -31,11 +31,11 @@ class AdvancedSettings extends HookConsumerWidget { final manageLocalMediaAndroid = useAppSettingsState(AppSettingsEnum.manageLocalMediaAndroid); final isManageMediaSupported = useState(false); final manageMediaAndroidPermission = useState(false); - final levelId = useState(ref.read(systemConfigProvider).logLevel.index); + final levelId = useState(ref.read(appConfigProvider).logLevel.index); final preferRemote = useState(ref.read(appConfigProvider).image.preferRemote); useValueChanged( preferRemote.value, - (_, __) => ref.read(metadataProvider).write(.imagePreferRemote, preferRemote.value), + (_, __) => ref.read(settingsProvider).write(.imagePreferRemote, preferRemote.value), ); final readonlyModeEnabled = useAppSettingsState(AppSettingsEnum.readonlyModeEnabled); @@ -57,9 +57,7 @@ class AdvancedSettings extends HookConsumerWidget { () async { isManageMediaSupported.value = await checkAndroidVersion(); if (isManageMediaSupported.value) { - manageMediaAndroidPermission.value = await ref - .read(localFilesManagerRepositoryProvider) - .hasManageMediaPermission(); + manageMediaAndroidPermission.value = await ref.read(permissionRepositoryProvider).hasManageMediaPermission(); } }(); return null; @@ -82,7 +80,7 @@ class AdvancedSettings extends HookConsumerWidget { subtitle: "advanced_settings_sync_remote_deletions_subtitle".tr(), onChanged: (value) async { if (value) { - final result = await ref.read(localFilesManagerRepositoryProvider).requestManageMediaPermission(); + final result = await ref.read(permissionRepositoryProvider).requestManageMediaPermission(); manageLocalMediaAndroid.value = result; manageMediaAndroidPermission.value = result; } @@ -96,7 +94,7 @@ class AdvancedSettings extends HookConsumerWidget { ? const Color.fromARGB(255, 243, 188, 106) : null, onActionTap: () async { - final result = await ref.read(localFilesManagerRepositoryProvider).manageMediaPermission(); + final result = await ref.read(permissionRepositoryProvider).manageMediaPermission(); manageMediaAndroidPermission.value = result; }, ), diff --git a/mobile/lib/widgets/settings/asset_list_settings/asset_list_group_settings.dart b/mobile/lib/widgets/settings/asset_list_settings/asset_list_group_settings.dart index b9f81da79e..59adb335bb 100644 --- a/mobile/lib/widgets/settings/asset_list_settings/asset_list_group_settings.dart +++ b/mobile/lib/widgets/settings/asset_list_settings/asset_list_group_settings.dart @@ -3,11 +3,10 @@ import 'dart:async'; import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:immich_mobile/domain/models/metadata_key.dart'; import 'package:immich_mobile/domain/models/timeline.model.dart'; import 'package:immich_mobile/extensions/translate_extensions.dart'; import 'package:immich_mobile/providers/app_settings.provider.dart'; -import 'package:immich_mobile/providers/infrastructure/metadata.provider.dart'; +import 'package:immich_mobile/providers/infrastructure/settings.provider.dart'; import 'package:immich_mobile/widgets/settings/setting_group_title.dart'; import 'package:immich_mobile/widgets/settings/settings_radio_list_tile.dart'; @@ -19,7 +18,7 @@ class GroupSettings extends HookConsumerWidget { final groupBy = useValueNotifier(ref.watch(appConfigProvider.select((s) => s.timeline.groupAssetsBy))); Future updateAppSettings(GroupAssetsBy groupBy) async { - await ref.read(metadataProvider).write(MetadataKey.timelineGroupAssetsBy, groupBy); + await ref.read(settingsProvider).write(.timelineGroupAssetsBy, groupBy); ref.invalidate(appSettingsServiceProvider); } diff --git a/mobile/lib/widgets/settings/asset_list_settings/asset_list_layout_settings.dart b/mobile/lib/widgets/settings/asset_list_settings/asset_list_layout_settings.dart index 20025286f4..f915df04f8 100644 --- a/mobile/lib/widgets/settings/asset_list_settings/asset_list_layout_settings.dart +++ b/mobile/lib/widgets/settings/asset_list_settings/asset_list_layout_settings.dart @@ -2,10 +2,9 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:immich_mobile/domain/models/metadata_key.dart'; import 'package:immich_mobile/extensions/translate_extensions.dart'; import 'package:immich_mobile/providers/app_settings.provider.dart'; -import 'package:immich_mobile/providers/infrastructure/metadata.provider.dart'; +import 'package:immich_mobile/providers/infrastructure/settings.provider.dart'; import 'package:immich_mobile/widgets/settings/setting_group_title.dart'; import 'package:immich_mobile/widgets/settings/settings_slider_list_tile.dart'; @@ -16,7 +15,7 @@ class LayoutSettings extends HookConsumerWidget { Widget build(BuildContext context, WidgetRef ref) { final tilesPerRow = useState(ref.read(appConfigProvider.select((s) => s.timeline.tilesPerRow))); useValueChanged(tilesPerRow.value, (_, __) { - ref.read(metadataProvider).write(MetadataKey.timelineTilesPerRow, tilesPerRow.value); + ref.read(settingsProvider).write(.timelineTilesPerRow, tilesPerRow.value); }); return Column( diff --git a/mobile/lib/widgets/settings/asset_list_settings/asset_list_settings.dart b/mobile/lib/widgets/settings/asset_list_settings/asset_list_settings.dart index 21d751c26f..3ac72d6612 100644 --- a/mobile/lib/widgets/settings/asset_list_settings/asset_list_settings.dart +++ b/mobile/lib/widgets/settings/asset_list_settings/asset_list_settings.dart @@ -2,10 +2,8 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:immich_mobile/domain/models/metadata_key.dart'; import 'package:immich_mobile/providers/app_settings.provider.dart'; -import 'package:immich_mobile/providers/infrastructure/metadata.provider.dart'; -import 'package:immich_mobile/providers/infrastructure/setting.provider.dart'; +import 'package:immich_mobile/providers/infrastructure/settings.provider.dart'; import 'package:immich_mobile/widgets/settings/asset_list_settings/asset_list_group_settings.dart'; import 'package:immich_mobile/widgets/settings/asset_list_settings/asset_list_layout_settings.dart'; import 'package:immich_mobile/widgets/settings/settings_sub_page_scaffold.dart'; @@ -23,7 +21,7 @@ class AssetListSettings extends HookConsumerWidget { valueNotifier: storageIndicator, title: 'theme_setting_asset_list_storage_indicator_title'.tr(), onChanged: (value) { - ref.read(metadataProvider).write(MetadataKey.timelineStorageIndicator, value); + ref.read(settingsProvider).write(.timelineStorageIndicator, value); ref.invalidate(appSettingsServiceProvider); ref.invalidate(settingsProvider); }, diff --git a/mobile/lib/widgets/settings/asset_viewer_settings/image_viewer_quality_setting.dart b/mobile/lib/widgets/settings/asset_viewer_settings/image_viewer_quality_setting.dart index 7858033401..f65af6af9d 100644 --- a/mobile/lib/widgets/settings/asset_viewer_settings/image_viewer_quality_setting.dart +++ b/mobile/lib/widgets/settings/asset_viewer_settings/image_viewer_quality_setting.dart @@ -3,7 +3,7 @@ import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/extensions/translate_extensions.dart'; import 'package:immich_mobile/providers/app_settings.provider.dart'; -import 'package:immich_mobile/providers/infrastructure/metadata.provider.dart'; +import 'package:immich_mobile/providers/infrastructure/settings.provider.dart'; import 'package:immich_mobile/widgets/settings/setting_group_title.dart'; import 'package:immich_mobile/widgets/settings/settings_switch_list_tile.dart'; @@ -14,7 +14,7 @@ class ImageViewerQualitySetting extends HookConsumerWidget { Widget build(BuildContext context, WidgetRef ref) { final isOriginal = useState(ref.read(appConfigProvider).image.loadOriginal); useValueChanged(isOriginal.value, (_, __) { - ref.read(metadataProvider).write(.imageLoadOriginal, isOriginal.value); + ref.read(settingsProvider).write(.imageLoadOriginal, isOriginal.value); }); return Column( diff --git a/mobile/lib/widgets/settings/asset_viewer_settings/image_viewer_tap_to_navigate_setting.dart b/mobile/lib/widgets/settings/asset_viewer_settings/image_viewer_tap_to_navigate_setting.dart index 5af64b0be9..730521e3c1 100644 --- a/mobile/lib/widgets/settings/asset_viewer_settings/image_viewer_tap_to_navigate_setting.dart +++ b/mobile/lib/widgets/settings/asset_viewer_settings/image_viewer_tap_to_navigate_setting.dart @@ -2,7 +2,7 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:immich_mobile/providers/infrastructure/metadata.provider.dart'; +import 'package:immich_mobile/providers/infrastructure/settings.provider.dart'; import 'package:immich_mobile/widgets/settings/settings_sub_title.dart'; import 'package:immich_mobile/widgets/settings/settings_switch_list_tile.dart'; @@ -13,7 +13,7 @@ class ImageViewerTapToNavigateSetting extends HookConsumerWidget { Widget build(BuildContext context, WidgetRef ref) { final tapToNavigate = useState(ref.read(appConfigProvider).viewer.tapToNavigate); useValueChanged(tapToNavigate.value, (_, __) { - ref.read(metadataProvider).write(.viewerTapToNavigate, tapToNavigate.value); + ref.read(settingsProvider).write(.viewerTapToNavigate, tapToNavigate.value); }); return Column( diff --git a/mobile/lib/widgets/settings/asset_viewer_settings/slideshow_settings.dart b/mobile/lib/widgets/settings/asset_viewer_settings/slideshow_settings.dart index 4e566e6065..5f93d429b0 100644 --- a/mobile/lib/widgets/settings/asset_viewer_settings/slideshow_settings.dart +++ b/mobile/lib/widgets/settings/asset_viewer_settings/slideshow_settings.dart @@ -3,7 +3,7 @@ import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/constants/enums.dart'; import 'package:immich_mobile/extensions/translate_extensions.dart'; -import 'package:immich_mobile/providers/infrastructure/metadata.provider.dart'; +import 'package:immich_mobile/providers/infrastructure/settings.provider.dart'; import 'package:immich_mobile/widgets/settings/setting_group_title.dart'; import 'package:immich_mobile/widgets/settings/settings_radio_list_tile.dart'; import 'package:immich_mobile/widgets/settings/settings_slider_list_tile.dart'; @@ -23,19 +23,19 @@ class SlideshowSettings extends HookConsumerWidget { final useDirection = useState(slideshow.direction); useValueChanged(useTransition.value, (_, __) { - ref.read(metadataProvider).write(.slideshowTransition, useTransition.value); + ref.read(settingsProvider).write(.slideshowTransition, useTransition.value); }); useValueChanged(useRepeat.value, (_, __) { - ref.read(metadataProvider).write(.slideshowRepeat, useRepeat.value); + ref.read(settingsProvider).write(.slideshowRepeat, useRepeat.value); }); useValueChanged(useDuration.value, (_, __) { - ref.read(metadataProvider).write(.slideshowDuration, useDuration.value); + ref.read(settingsProvider).write(.slideshowDuration, useDuration.value); }); useValueChanged(useLook.value, (_, __) { - ref.read(metadataProvider).write(.slideshowLook, useLook.value); + ref.read(settingsProvider).write(.slideshowLook, useLook.value); }); useValueChanged(useDirection.value, (_, __) { - ref.read(metadataProvider).write(.slideshowDirection, useDirection.value); + ref.read(settingsProvider).write(.slideshowDirection, useDirection.value); }); return Column( diff --git a/mobile/lib/widgets/settings/asset_viewer_settings/video_viewer_settings.dart b/mobile/lib/widgets/settings/asset_viewer_settings/video_viewer_settings.dart index 8d62544dd4..81929d95b9 100644 --- a/mobile/lib/widgets/settings/asset_viewer_settings/video_viewer_settings.dart +++ b/mobile/lib/widgets/settings/asset_viewer_settings/video_viewer_settings.dart @@ -2,7 +2,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/extensions/translate_extensions.dart'; -import 'package:immich_mobile/providers/infrastructure/metadata.provider.dart'; +import 'package:immich_mobile/providers/infrastructure/settings.provider.dart'; import 'package:immich_mobile/widgets/settings/setting_group_title.dart'; import 'package:immich_mobile/widgets/settings/settings_switch_list_tile.dart'; @@ -17,13 +17,13 @@ class VideoViewerSettings extends HookConsumerWidget { final useOriginalVideo = useState(viewer.loadOriginalVideo); useValueChanged(useAutoPlayVideo.value, (_, __) { - ref.read(metadataProvider).write(.viewerAutoPlayVideo, useAutoPlayVideo.value); + ref.read(settingsProvider).write(.viewerAutoPlayVideo, useAutoPlayVideo.value); }); useValueChanged(useLoopVideo.value, (_, __) { - ref.read(metadataProvider).write(.viewerLoopVideo, useLoopVideo.value); + ref.read(settingsProvider).write(.viewerLoopVideo, useLoopVideo.value); }); useValueChanged(useOriginalVideo.value, (_, __) { - ref.read(metadataProvider).write(.viewerLoadOriginalVideo, useOriginalVideo.value); + ref.read(settingsProvider).write(.viewerLoadOriginalVideo, useOriginalVideo.value); }); return Column( diff --git a/mobile/lib/widgets/settings/backup_settings/drift_backup_settings.dart b/mobile/lib/widgets/settings/backup_settings/drift_backup_settings.dart index 89d6f13f43..e5debb43fe 100644 --- a/mobile/lib/widgets/settings/backup_settings/drift_backup_settings.dart +++ b/mobile/lib/widgets/settings/backup_settings/drift_backup_settings.dart @@ -5,15 +5,15 @@ import 'package:flutter/material.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/domain/models/album/local_album.model.dart'; import 'package:immich_mobile/domain/models/config/app_config.dart'; -import 'package:immich_mobile/domain/models/metadata_key.dart'; +import 'package:immich_mobile/domain/models/settings_key.dart'; import 'package:immich_mobile/domain/services/sync_linked_album.service.dart'; import 'package:immich_mobile/extensions/build_context_extensions.dart'; import 'package:immich_mobile/extensions/platform_extensions.dart'; import 'package:immich_mobile/extensions/translate_extensions.dart'; import 'package:immich_mobile/providers/background_sync.provider.dart'; import 'package:immich_mobile/providers/backup/backup_album.provider.dart'; -import 'package:immich_mobile/providers/infrastructure/metadata.provider.dart'; import 'package:immich_mobile/providers/infrastructure/platform.provider.dart'; +import 'package:immich_mobile/providers/infrastructure/settings.provider.dart'; import 'package:immich_mobile/providers/user.provider.dart'; import 'package:immich_mobile/widgets/settings/setting_group_title.dart'; import 'package:immich_mobile/widgets/settings/setting_list_tile.dart'; @@ -112,7 +112,7 @@ class _AlbumSyncActionButtonState extends ConsumerState<_AlbumSyncActionButton> trailing: Switch( value: albumSyncEnable, onChanged: (bool newValue) async { - await ref.read(metadataProvider).write(MetadataKey.backupSyncAlbums, newValue); + await ref.read(settingsProvider).write(.backupSyncAlbums, newValue); if (newValue == true) { await _manageLinkedAlbums(); @@ -158,7 +158,7 @@ class _AlbumSyncActionButtonState extends ConsumerState<_AlbumSyncActionButton> } class _BackupSwitchTile extends ConsumerWidget { - final MetadataKey metadataKey; + final SettingsKey metadataKey; final bool Function(AppConfig) selector; final String titleKey; final String subtitleKey; @@ -183,7 +183,7 @@ class _BackupSwitchTile extends ConsumerWidget { trailing: Switch( value: value, onChanged: (bool newValue) async { - await ref.read(metadataProvider).write(metadataKey, newValue); + await ref.read(settingsProvider).write(metadataKey, newValue); onChanged?.call(newValue); }, ), @@ -198,7 +198,7 @@ class _UseCellularForVideosButton extends StatelessWidget { @override Widget build(BuildContext context) { return _BackupSwitchTile( - metadataKey: MetadataKey.backupUseCellularForVideos, + metadataKey: SettingsKey.backupUseCellularForVideos, selector: (c) => c.backup.useCellularForVideos, titleKey: "videos", subtitleKey: "network_requirement_videos_upload", @@ -212,7 +212,7 @@ class _UseCellularForPhotosButton extends StatelessWidget { @override Widget build(BuildContext context) { return _BackupSwitchTile( - metadataKey: MetadataKey.backupUseCellularForPhotos, + metadataKey: SettingsKey.backupUseCellularForPhotos, selector: (c) => c.backup.useCellularForPhotos, titleKey: "photos", subtitleKey: "network_requirement_photos_upload", @@ -227,7 +227,7 @@ class _BackupOnlyWhenChargingButton extends ConsumerWidget { Widget build(BuildContext context, WidgetRef ref) { final fgService = ref.read(backgroundWorkerFgServiceProvider); return _BackupSwitchTile( - metadataKey: MetadataKey.backupRequireCharging, + metadataKey: SettingsKey.backupRequireCharging, selector: (c) => c.backup.requireCharging, titleKey: "charging", subtitleKey: "charging_requirement_mobile_backup", @@ -282,11 +282,11 @@ class _BackupDelaySlider extends ConsumerWidget { value: currentValue.toDouble(), onChanged: (double v) async { final seconds = backupDelayToSeconds(v.toInt()); - await ref.read(metadataProvider).write(MetadataKey.backupTriggerDelay, seconds); + await ref.read(settingsProvider).write(SettingsKey.backupTriggerDelay, seconds); }, onChangeEnd: (double v) async { final seconds = backupDelayToSeconds(v.toInt()); - await ref.read(metadataProvider).write(MetadataKey.backupTriggerDelay, seconds); + await ref.read(settingsProvider).write(SettingsKey.backupTriggerDelay, seconds); }, max: 3.0, min: 0.0, diff --git a/mobile/lib/widgets/settings/language_settings.dart b/mobile/lib/widgets/settings/language_settings.dart index d0b3ac0021..2482801923 100644 --- a/mobile/lib/widgets/settings/language_settings.dart +++ b/mobile/lib/widgets/settings/language_settings.dart @@ -1,12 +1,13 @@ import 'dart:async'; + +import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:easy_localization/easy_localization.dart'; import 'package:immich_mobile/constants/locales.dart'; +import 'package:immich_mobile/extensions/build_context_extensions.dart'; import 'package:immich_mobile/extensions/translate_extensions.dart'; import 'package:immich_mobile/services/localization.service.dart'; -import 'package:immich_mobile/extensions/build_context_extensions.dart'; import 'package:immich_mobile/widgets/common/search_field.dart'; class LanguageSettings extends HookConsumerWidget { @@ -84,7 +85,7 @@ class LanguageSettings extends HookConsumerWidget { padding: const EdgeInsets.all(8), itemCount: filteredLocaleEntries.value.length, itemExtent: 64.0, - cacheExtent: 100, + scrollCacheExtent: const .pixels(100), itemBuilder: (context, index) { final countryName = filteredLocaleEntries.value[index].key; final localeValue = filteredLocaleEntries.value[index].value; diff --git a/mobile/lib/widgets/settings/networking_settings/external_network_preference.dart b/mobile/lib/widgets/settings/networking_settings/external_network_preference.dart index 7900747055..492a13de93 100644 --- a/mobile/lib/widgets/settings/networking_settings/external_network_preference.dart +++ b/mobile/lib/widgets/settings/networking_settings/external_network_preference.dart @@ -1,11 +1,11 @@ import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:immich_mobile/domain/models/metadata_key.dart'; +import 'package:immich_mobile/domain/models/settings_key.dart'; import 'package:immich_mobile/extensions/build_context_extensions.dart'; import 'package:immich_mobile/extensions/translate_extensions.dart'; import 'package:immich_mobile/models/auth/auxilary_endpoint.model.dart'; -import 'package:immich_mobile/providers/infrastructure/metadata.provider.dart'; +import 'package:immich_mobile/providers/infrastructure/settings.provider.dart'; import 'package:immich_mobile/widgets/settings/networking_settings/endpoint_input.dart'; class ExternalNetworkPreference extends HookConsumerWidget { @@ -26,7 +26,7 @@ class ExternalNetworkPreference extends HookConsumerWidget { .map((e) => e.url) .toList(); - ref.read(metadataProvider).write(MetadataKey.networkExternalEndpointList, urls); + ref.read(settingsProvider).write(SettingsKey.networkExternalEndpointList, urls); } updateValidationStatus(String url, int index, AuxCheckStatus status) { @@ -36,10 +36,6 @@ class ExternalNetworkPreference extends HookConsumerWidget { } handleReorder(int oldIndex, int newIndex) { - if (oldIndex < newIndex) { - newIndex -= 1; - } - final entry = entries.value.removeAt(oldIndex); entries.value.insert(newIndex, entry); entries.value = [...entries.value]; @@ -68,7 +64,7 @@ class ExternalNetworkPreference extends HookConsumerWidget { } useEffect(() { - final urls = ref.read(metadataProvider).systemConfig.network.externalEndpointList; + final urls = ref.read(appConfigProvider).network.externalEndpointList; if (urls.isEmpty) { return null; @@ -113,7 +109,7 @@ class ExternalNetworkPreference extends HookConsumerWidget { shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), itemCount: entries.value.length, - onReorder: handleReorder, + onReorderItem: handleReorder, itemBuilder: (context, index) { return EndpointInput( key: Key(index.toString()), diff --git a/mobile/lib/widgets/settings/networking_settings/networking_settings.dart b/mobile/lib/widgets/settings/networking_settings/networking_settings.dart index f232f41a5d..7e6e169de7 100644 --- a/mobile/lib/widgets/settings/networking_settings/networking_settings.dart +++ b/mobile/lib/widgets/settings/networking_settings/networking_settings.dart @@ -5,7 +5,7 @@ import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/extensions/build_context_extensions.dart'; import 'package:immich_mobile/extensions/translate_extensions.dart'; import 'package:immich_mobile/models/auth/auxilary_endpoint.model.dart'; -import 'package:immich_mobile/providers/infrastructure/metadata.provider.dart'; +import 'package:immich_mobile/providers/infrastructure/settings.provider.dart'; import 'package:immich_mobile/providers/network.provider.dart'; import 'package:immich_mobile/utils/url_helper.dart'; import 'package:immich_mobile/widgets/settings/networking_settings/external_network_preference.dart'; @@ -19,9 +19,9 @@ class NetworkingSettings extends HookConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { final currentEndpoint = getServerUrl(); - final featureEnabled = useState(ref.read(systemConfigProvider).network.autoEndpointSwitching); + final featureEnabled = useState(ref.read(appConfigProvider).network.autoEndpointSwitching); useValueChanged(featureEnabled.value, (_, __) { - ref.read(metadataProvider).write(.networkAutoEndpointSwitching, featureEnabled.value); + ref.read(settingsProvider).write(.networkAutoEndpointSwitching, featureEnabled.value); }); Future checkWifiReadPermission() async { diff --git a/mobile/lib/widgets/settings/preference_settings/primary_color_setting.dart b/mobile/lib/widgets/settings/preference_settings/primary_color_setting.dart index 330555ed54..48d0ca672b 100644 --- a/mobile/lib/widgets/settings/preference_settings/primary_color_setting.dart +++ b/mobile/lib/widgets/settings/preference_settings/primary_color_setting.dart @@ -4,7 +4,7 @@ import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/constants/colors.dart'; import 'package:immich_mobile/extensions/build_context_extensions.dart'; import 'package:immich_mobile/extensions/theme_extensions.dart'; -import 'package:immich_mobile/providers/infrastructure/metadata.provider.dart'; +import 'package:immich_mobile/providers/infrastructure/settings.provider.dart'; import 'package:immich_mobile/providers/theme.provider.dart'; import 'package:immich_mobile/theme/color_scheme.dart'; import 'package:immich_mobile/theme/dynamic_theme.dart'; @@ -26,16 +26,16 @@ class PrimaryColorSetting extends HookConsumerWidget { } onUseSystemColorChange(bool newValue) { - ref.read(metadataProvider).write(.themeDynamic, newValue); + ref.read(settingsProvider).write(.themeDynamic, newValue); popBottomSheet(); } onPrimaryColorChange(ImmichColorPreset colorPreset) { - ref.read(metadataProvider).write(.themePrimaryColor, colorPreset); + ref.read(settingsProvider).write(.themePrimaryColor, colorPreset); //turn off system color setting if (themeConfig.dynamicTheme) { - ref.read(metadataProvider).write(.themeDynamic, false); + ref.read(settingsProvider).write(.themeDynamic, false); } popBottomSheet(); } diff --git a/mobile/lib/widgets/settings/preference_settings/theme_setting.dart b/mobile/lib/widgets/settings/preference_settings/theme_setting.dart index d71842d786..ffeeceae02 100644 --- a/mobile/lib/widgets/settings/preference_settings/theme_setting.dart +++ b/mobile/lib/widgets/settings/preference_settings/theme_setting.dart @@ -3,7 +3,7 @@ import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/extensions/build_context_extensions.dart'; import 'package:immich_mobile/extensions/translate_extensions.dart'; -import 'package:immich_mobile/providers/infrastructure/metadata.provider.dart'; +import 'package:immich_mobile/providers/infrastructure/settings.provider.dart'; import 'package:immich_mobile/widgets/settings/preference_settings/primary_color_setting.dart'; import 'package:immich_mobile/widgets/settings/setting_group_title.dart'; import 'package:immich_mobile/widgets/settings/settings_switch_list_tile.dart'; @@ -22,7 +22,7 @@ class ThemeSetting extends HookConsumerWidget { void onThemeChange(bool isDark) { currentTheme.value = isDark ? ThemeMode.dark : ThemeMode.light; - ref.read(metadataProvider).write(.themeMode, currentTheme.value); + ref.read(settingsProvider).write(.themeMode, currentTheme.value); } void onSystemThemeChange(bool isSystem) { @@ -39,11 +39,11 @@ class ThemeSetting extends HookConsumerWidget { currentTheme.value = ThemeMode.dark; } } - ref.read(metadataProvider).write(.themeMode, currentTheme.value); + ref.read(settingsProvider).write(.themeMode, currentTheme.value); } void onSurfaceColorSettingChange(bool useColorfulInterface) { - ref.read(metadataProvider).write(.themeColorfulInterface, useColorfulInterface); + ref.read(settingsProvider).write(.themeColorfulInterface, useColorfulInterface); colorfulInterface.value = useColorfulInterface; } diff --git a/mobile/makefile b/mobile/makefile index 5a21287b85..645316efee 100644 --- a/mobile/makefile +++ b/mobile/makefile @@ -1,26 +1,26 @@ .PHONY: build watch create_app_icon create_splash build_release_android pigeon test analyze format migration translation build: - @printf "This command has been removed. Please use:\n\n mise codegen # or mise //:mobile:codegen:dart from another directory\n\n" >&2 && exit 1 + @printf "This command has been removed. Please use:\n\n mise codegen # or mise //mobile:codegen:dart from another directory\n\n" >&2 && exit 1 pigeon: - @printf "This command has been removed. Please use:\n\n mise pigeon # or mise //:mobile:codegen:pigeon from another directory\n\n" >&2 && exit 1 + @printf "This command has been removed. Please use:\n\n mise pigeon # or mise //mobile:codegen:pigeon from another directory\n\n" >&2 && exit 1 build_release_android: - @printf "This command has been removed. Please use:\n\n mise run build:android # or mise //:mobile:build:android from another directory\n\n" >&2 && exit 1 + @printf "This command has been removed. Please use:\n\n mise run build:android # or mise //mobile:build:android from another directory\n\n" >&2 && exit 1 migration: - @printf "This command has been removed. Please use:\n\n mise migration # or mise //:mobile:drift:migration from another directory\n\n" >&2 && exit 1 + @printf "This command has been removed. Please use:\n\n mise migration # or mise //mobile:drift:migration from another directory\n\n" >&2 && exit 1 translation: - @printf "This command has been removed. Please use:\n\n mise translation # or mise //:mobile:codegen:translation from another directory\n\n" >&2 && exit 1 + @printf "This command has been removed. Please use:\n\n mise translation # or mise //mobile:codegen:translation from another directory\n\n" >&2 && exit 1 analyze: - @printf "This command has been removed. Please use:\n\n mise analyze # or mise //:mobile:lint from another directory\n\n" >&2 && exit 1 + @printf "This command has been removed. Please use:\n\n mise analyze # or mise //mobile:lint from another directory\n\n" >&2 && exit 1 format: - @printf "This command has been removed. Please use:\n\n mise format # or mise //:mobile:format from another directory\n\n" >&2 && exit 1 + @printf "This command has been removed. Please use:\n\n mise format # or mise //mobile:format from another directory\n\n" >&2 && exit 1 test: - @printf "This command has been removed. Please use:\n\n mise test # or mise //:mobile:test from another directory\n\n" >&2 && exit 1 + @printf "This command has been removed. Please use:\n\n mise test # or mise //mobile:test from another directory\n\n" >&2 && exit 1 diff --git a/mobile/mise.toml b/mobile/mise.toml index c31a5b06ff..a0f25718ac 100644 --- a/mobile/mise.toml +++ b/mobile/mise.toml @@ -78,6 +78,15 @@ alias = "migration" description = "Generate database migrations" run = "dart run drift_dev make-migrations" +[tasks.install] +alias = "install" +description = "Install flutter dependencies" +run = "flutter pub get" + +[tasks.start] +alias = "start" +description = "Start flutter app" +run = "flutter run" # Internal tasks [tasks."i18n:loader"] diff --git a/mobile/openapi/lib/api/activities_api.dart b/mobile/openapi/lib/api/activities_api.dart index e0a393948c..490c418785 100644 --- a/mobile/openapi/lib/api/activities_api.dart +++ b/mobile/openapi/lib/api/activities_api.dart @@ -25,7 +25,7 @@ class ActivitiesApi { /// Parameters: /// /// * [ActivityCreateDto] activityCreateDto (required): - Future createActivityWithHttpInfo(ActivityCreateDto activityCreateDto,) async { + Future createActivityWithHttpInfo(ActivityCreateDto activityCreateDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/activities'; @@ -47,6 +47,7 @@ class ActivitiesApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -57,8 +58,8 @@ class ActivitiesApi { /// Parameters: /// /// * [ActivityCreateDto] activityCreateDto (required): - Future createActivity(ActivityCreateDto activityCreateDto,) async { - final response = await createActivityWithHttpInfo(activityCreateDto,); + Future createActivity(ActivityCreateDto activityCreateDto, { Future? abortTrigger, }) async { + final response = await createActivityWithHttpInfo(activityCreateDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -81,7 +82,7 @@ class ActivitiesApi { /// Parameters: /// /// * [String] id (required): - Future deleteActivityWithHttpInfo(String id,) async { + Future deleteActivityWithHttpInfo(String id, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/activities/{id}' .replaceAll('{id}', id); @@ -104,6 +105,7 @@ class ActivitiesApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -114,8 +116,8 @@ class ActivitiesApi { /// Parameters: /// /// * [String] id (required): - Future deleteActivity(String id,) async { - final response = await deleteActivityWithHttpInfo(id,); + Future deleteActivity(String id, { Future? abortTrigger, }) async { + final response = await deleteActivityWithHttpInfo(id, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -141,7 +143,7 @@ class ActivitiesApi { /// /// * [String] userId: /// Filter by user ID - Future getActivitiesWithHttpInfo(String albumId, { String? assetId, ReactionLevel? level, ReactionType? type, String? userId, }) async { + Future getActivitiesWithHttpInfo(String albumId, { String? assetId, ReactionLevel? level, ReactionType? type, String? userId, Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/activities'; @@ -177,6 +179,7 @@ class ActivitiesApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -198,8 +201,8 @@ class ActivitiesApi { /// /// * [String] userId: /// Filter by user ID - Future?> getActivities(String albumId, { String? assetId, ReactionLevel? level, ReactionType? type, String? userId, }) async { - final response = await getActivitiesWithHttpInfo(albumId, assetId: assetId, level: level, type: type, userId: userId, ); + Future?> getActivities(String albumId, { String? assetId, ReactionLevel? level, ReactionType? type, String? userId, Future? abortTrigger, }) async { + final response = await getActivitiesWithHttpInfo(albumId, assetId: assetId, level: level, type: type, userId: userId, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -229,7 +232,7 @@ class ActivitiesApi { /// /// * [String] assetId: /// Asset ID (if activity is for an asset) - Future getActivityStatisticsWithHttpInfo(String albumId, { String? assetId, }) async { + Future getActivityStatisticsWithHttpInfo(String albumId, { String? assetId, Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/activities/statistics'; @@ -256,6 +259,7 @@ class ActivitiesApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -270,8 +274,8 @@ class ActivitiesApi { /// /// * [String] assetId: /// Asset ID (if activity is for an asset) - Future getActivityStatistics(String albumId, { String? assetId, }) async { - final response = await getActivityStatisticsWithHttpInfo(albumId, assetId: assetId, ); + Future getActivityStatistics(String albumId, { String? assetId, Future? abortTrigger, }) async { + final response = await getActivityStatisticsWithHttpInfo(albumId, assetId: assetId, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } diff --git a/mobile/openapi/lib/api/albums_api.dart b/mobile/openapi/lib/api/albums_api.dart index e0fc383c1d..e6e7cdbf40 100644 --- a/mobile/openapi/lib/api/albums_api.dart +++ b/mobile/openapi/lib/api/albums_api.dart @@ -27,7 +27,7 @@ class AlbumsApi { /// * [String] id (required): /// /// * [BulkIdsDto] bulkIdsDto (required): - Future addAssetsToAlbumWithHttpInfo(String id, BulkIdsDto bulkIdsDto,) async { + Future addAssetsToAlbumWithHttpInfo(String id, BulkIdsDto bulkIdsDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/albums/{id}/assets' .replaceAll('{id}', id); @@ -50,6 +50,7 @@ class AlbumsApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -62,8 +63,8 @@ class AlbumsApi { /// * [String] id (required): /// /// * [BulkIdsDto] bulkIdsDto (required): - Future?> addAssetsToAlbum(String id, BulkIdsDto bulkIdsDto,) async { - final response = await addAssetsToAlbumWithHttpInfo(id, bulkIdsDto,); + Future?> addAssetsToAlbum(String id, BulkIdsDto bulkIdsDto, { Future? abortTrigger, }) async { + final response = await addAssetsToAlbumWithHttpInfo(id, bulkIdsDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -89,7 +90,7 @@ class AlbumsApi { /// Parameters: /// /// * [AlbumsAddAssetsDto] albumsAddAssetsDto (required): - Future addAssetsToAlbumsWithHttpInfo(AlbumsAddAssetsDto albumsAddAssetsDto,) async { + Future addAssetsToAlbumsWithHttpInfo(AlbumsAddAssetsDto albumsAddAssetsDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/albums/assets'; @@ -111,6 +112,7 @@ class AlbumsApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -121,8 +123,8 @@ class AlbumsApi { /// Parameters: /// /// * [AlbumsAddAssetsDto] albumsAddAssetsDto (required): - Future addAssetsToAlbums(AlbumsAddAssetsDto albumsAddAssetsDto,) async { - final response = await addAssetsToAlbumsWithHttpInfo(albumsAddAssetsDto,); + Future addAssetsToAlbums(AlbumsAddAssetsDto albumsAddAssetsDto, { Future? abortTrigger, }) async { + final response = await addAssetsToAlbumsWithHttpInfo(albumsAddAssetsDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -147,7 +149,7 @@ class AlbumsApi { /// * [String] id (required): /// /// * [AddUsersDto] addUsersDto (required): - Future addUsersToAlbumWithHttpInfo(String id, AddUsersDto addUsersDto,) async { + Future addUsersToAlbumWithHttpInfo(String id, AddUsersDto addUsersDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/albums/{id}/users' .replaceAll('{id}', id); @@ -170,6 +172,7 @@ class AlbumsApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -182,8 +185,8 @@ class AlbumsApi { /// * [String] id (required): /// /// * [AddUsersDto] addUsersDto (required): - Future addUsersToAlbum(String id, AddUsersDto addUsersDto,) async { - final response = await addUsersToAlbumWithHttpInfo(id, addUsersDto,); + Future addUsersToAlbum(String id, AddUsersDto addUsersDto, { Future? abortTrigger, }) async { + final response = await addUsersToAlbumWithHttpInfo(id, addUsersDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -206,7 +209,7 @@ class AlbumsApi { /// Parameters: /// /// * [CreateAlbumDto] createAlbumDto (required): - Future createAlbumWithHttpInfo(CreateAlbumDto createAlbumDto,) async { + Future createAlbumWithHttpInfo(CreateAlbumDto createAlbumDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/albums'; @@ -228,6 +231,7 @@ class AlbumsApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -238,8 +242,8 @@ class AlbumsApi { /// Parameters: /// /// * [CreateAlbumDto] createAlbumDto (required): - Future createAlbum(CreateAlbumDto createAlbumDto,) async { - final response = await createAlbumWithHttpInfo(createAlbumDto,); + Future createAlbum(CreateAlbumDto createAlbumDto, { Future? abortTrigger, }) async { + final response = await createAlbumWithHttpInfo(createAlbumDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -262,7 +266,7 @@ class AlbumsApi { /// Parameters: /// /// * [String] id (required): - Future deleteAlbumWithHttpInfo(String id,) async { + Future deleteAlbumWithHttpInfo(String id, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/albums/{id}' .replaceAll('{id}', id); @@ -285,6 +289,7 @@ class AlbumsApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -295,8 +300,8 @@ class AlbumsApi { /// Parameters: /// /// * [String] id (required): - Future deleteAlbum(String id,) async { - final response = await deleteAlbumWithHttpInfo(id,); + Future deleteAlbum(String id, { Future? abortTrigger, }) async { + final response = await deleteAlbumWithHttpInfo(id, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -315,7 +320,7 @@ class AlbumsApi { /// * [String] key: /// /// * [String] slug: - Future getAlbumInfoWithHttpInfo(String id, { String? key, String? slug, }) async { + Future getAlbumInfoWithHttpInfo(String id, { String? key, String? slug, Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/albums/{id}' .replaceAll('{id}', id); @@ -345,6 +350,7 @@ class AlbumsApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -359,8 +365,8 @@ class AlbumsApi { /// * [String] key: /// /// * [String] slug: - Future getAlbumInfo(String id, { String? key, String? slug, }) async { - final response = await getAlbumInfoWithHttpInfo(id, key: key, slug: slug, ); + Future getAlbumInfo(String id, { String? key, String? slug, Future? abortTrigger, }) async { + final response = await getAlbumInfoWithHttpInfo(id, key: key, slug: slug, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -387,7 +393,7 @@ class AlbumsApi { /// * [String] key: /// /// * [String] slug: - Future getAlbumMapMarkersWithHttpInfo(String id, { String? key, String? slug, }) async { + Future getAlbumMapMarkersWithHttpInfo(String id, { String? key, String? slug, Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/albums/{id}/map-markers' .replaceAll('{id}', id); @@ -417,6 +423,7 @@ class AlbumsApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -431,8 +438,8 @@ class AlbumsApi { /// * [String] key: /// /// * [String] slug: - Future?> getAlbumMapMarkers(String id, { String? key, String? slug, }) async { - final response = await getAlbumMapMarkersWithHttpInfo(id, key: key, slug: slug, ); + Future?> getAlbumMapMarkers(String id, { String? key, String? slug, Future? abortTrigger, }) async { + final response = await getAlbumMapMarkersWithHttpInfo(id, key: key, slug: slug, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -454,7 +461,7 @@ class AlbumsApi { /// Returns statistics about the albums available to the authenticated user. /// /// Note: This method returns the HTTP [Response]. - Future getAlbumStatisticsWithHttpInfo() async { + Future getAlbumStatisticsWithHttpInfo({ Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/albums/statistics'; @@ -476,14 +483,15 @@ class AlbumsApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } /// Retrieve album statistics /// /// Returns statistics about the albums available to the authenticated user. - Future getAlbumStatistics() async { - final response = await getAlbumStatisticsWithHttpInfo(); + Future getAlbumStatistics({ Future? abortTrigger, }) async { + final response = await getAlbumStatisticsWithHttpInfo(abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -508,12 +516,18 @@ class AlbumsApi { /// * [String] assetId: /// Filter albums containing this asset ID (ignores other parameters) /// + /// * [String] id: + /// Album ID + /// /// * [bool] isOwned: /// Filter by ownership: true = only owned, false = only shared-with-me, undefined = no filter /// /// * [bool] isShared: /// Filter by shared status: true = only shared, false = not shared, undefined = no filter - Future getAllAlbumsWithHttpInfo({ String? assetId, bool? isOwned, bool? isShared, }) async { + /// + /// * [String] name: + /// Album name (exact match) + Future getAllAlbumsWithHttpInfo({ String? assetId, String? id, bool? isOwned, bool? isShared, String? name, Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/albums'; @@ -527,12 +541,18 @@ class AlbumsApi { if (assetId != null) { queryParams.addAll(_queryParams('', 'assetId', assetId)); } + if (id != null) { + queryParams.addAll(_queryParams('', 'id', id)); + } if (isOwned != null) { queryParams.addAll(_queryParams('', 'isOwned', isOwned)); } if (isShared != null) { queryParams.addAll(_queryParams('', 'isShared', isShared)); } + if (name != null) { + queryParams.addAll(_queryParams('', 'name', name)); + } const contentTypes = []; @@ -545,6 +565,7 @@ class AlbumsApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -557,13 +578,19 @@ class AlbumsApi { /// * [String] assetId: /// Filter albums containing this asset ID (ignores other parameters) /// + /// * [String] id: + /// Album ID + /// /// * [bool] isOwned: /// Filter by ownership: true = only owned, false = only shared-with-me, undefined = no filter /// /// * [bool] isShared: /// Filter by shared status: true = only shared, false = not shared, undefined = no filter - Future?> getAllAlbums({ String? assetId, bool? isOwned, bool? isShared, }) async { - final response = await getAllAlbumsWithHttpInfo( assetId: assetId, isOwned: isOwned, isShared: isShared, ); + /// + /// * [String] name: + /// Album name (exact match) + Future?> getAllAlbums({ String? assetId, String? id, bool? isOwned, bool? isShared, String? name, Future? abortTrigger, }) async { + final response = await getAllAlbumsWithHttpInfo(assetId: assetId, id: id, isOwned: isOwned, isShared: isShared, name: name, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -591,7 +618,7 @@ class AlbumsApi { /// * [String] id (required): /// /// * [BulkIdsDto] bulkIdsDto (required): - Future removeAssetFromAlbumWithHttpInfo(String id, BulkIdsDto bulkIdsDto,) async { + Future removeAssetFromAlbumWithHttpInfo(String id, BulkIdsDto bulkIdsDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/albums/{id}/assets' .replaceAll('{id}', id); @@ -614,6 +641,7 @@ class AlbumsApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -626,8 +654,8 @@ class AlbumsApi { /// * [String] id (required): /// /// * [BulkIdsDto] bulkIdsDto (required): - Future?> removeAssetFromAlbum(String id, BulkIdsDto bulkIdsDto,) async { - final response = await removeAssetFromAlbumWithHttpInfo(id, bulkIdsDto,); + Future?> removeAssetFromAlbum(String id, BulkIdsDto bulkIdsDto, { Future? abortTrigger, }) async { + final response = await removeAssetFromAlbumWithHttpInfo(id, bulkIdsDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -655,7 +683,7 @@ class AlbumsApi { /// * [String] id (required): /// /// * [String] userId (required): - Future removeUserFromAlbumWithHttpInfo(String id, String userId,) async { + Future removeUserFromAlbumWithHttpInfo(String id, String userId, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/albums/{id}/user/{userId}' .replaceAll('{id}', id) @@ -679,6 +707,7 @@ class AlbumsApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -691,8 +720,8 @@ class AlbumsApi { /// * [String] id (required): /// /// * [String] userId (required): - Future removeUserFromAlbum(String id, String userId,) async { - final response = await removeUserFromAlbumWithHttpInfo(id, userId,); + Future removeUserFromAlbum(String id, String userId, { Future? abortTrigger, }) async { + final response = await removeUserFromAlbumWithHttpInfo(id, userId, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -709,7 +738,7 @@ class AlbumsApi { /// * [String] id (required): /// /// * [UpdateAlbumDto] updateAlbumDto (required): - Future updateAlbumInfoWithHttpInfo(String id, UpdateAlbumDto updateAlbumDto,) async { + Future updateAlbumInfoWithHttpInfo(String id, UpdateAlbumDto updateAlbumDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/albums/{id}' .replaceAll('{id}', id); @@ -732,6 +761,7 @@ class AlbumsApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -744,8 +774,8 @@ class AlbumsApi { /// * [String] id (required): /// /// * [UpdateAlbumDto] updateAlbumDto (required): - Future updateAlbumInfo(String id, UpdateAlbumDto updateAlbumDto,) async { - final response = await updateAlbumInfoWithHttpInfo(id, updateAlbumDto,); + Future updateAlbumInfo(String id, UpdateAlbumDto updateAlbumDto, { Future? abortTrigger, }) async { + final response = await updateAlbumInfoWithHttpInfo(id, updateAlbumDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -772,7 +802,7 @@ class AlbumsApi { /// * [String] userId (required): /// /// * [UpdateAlbumUserDto] updateAlbumUserDto (required): - Future updateAlbumUserWithHttpInfo(String id, String userId, UpdateAlbumUserDto updateAlbumUserDto,) async { + Future updateAlbumUserWithHttpInfo(String id, String userId, UpdateAlbumUserDto updateAlbumUserDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/albums/{id}/user/{userId}' .replaceAll('{id}', id) @@ -796,6 +826,7 @@ class AlbumsApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -810,8 +841,8 @@ class AlbumsApi { /// * [String] userId (required): /// /// * [UpdateAlbumUserDto] updateAlbumUserDto (required): - Future updateAlbumUser(String id, String userId, UpdateAlbumUserDto updateAlbumUserDto,) async { - final response = await updateAlbumUserWithHttpInfo(id, userId, updateAlbumUserDto,); + Future updateAlbumUser(String id, String userId, UpdateAlbumUserDto updateAlbumUserDto, { Future? abortTrigger, }) async { + final response = await updateAlbumUserWithHttpInfo(id, userId, updateAlbumUserDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } diff --git a/mobile/openapi/lib/api/api_keys_api.dart b/mobile/openapi/lib/api/api_keys_api.dart index 3ca85265c4..c26ddc263d 100644 --- a/mobile/openapi/lib/api/api_keys_api.dart +++ b/mobile/openapi/lib/api/api_keys_api.dart @@ -25,7 +25,7 @@ class APIKeysApi { /// Parameters: /// /// * [ApiKeyCreateDto] apiKeyCreateDto (required): - Future createApiKeyWithHttpInfo(ApiKeyCreateDto apiKeyCreateDto,) async { + Future createApiKeyWithHttpInfo(ApiKeyCreateDto apiKeyCreateDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/api-keys'; @@ -47,6 +47,7 @@ class APIKeysApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -57,8 +58,8 @@ class APIKeysApi { /// Parameters: /// /// * [ApiKeyCreateDto] apiKeyCreateDto (required): - Future createApiKey(ApiKeyCreateDto apiKeyCreateDto,) async { - final response = await createApiKeyWithHttpInfo(apiKeyCreateDto,); + Future createApiKey(ApiKeyCreateDto apiKeyCreateDto, { Future? abortTrigger, }) async { + final response = await createApiKeyWithHttpInfo(apiKeyCreateDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -81,7 +82,7 @@ class APIKeysApi { /// Parameters: /// /// * [String] id (required): - Future deleteApiKeyWithHttpInfo(String id,) async { + Future deleteApiKeyWithHttpInfo(String id, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/api-keys/{id}' .replaceAll('{id}', id); @@ -104,6 +105,7 @@ class APIKeysApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -114,8 +116,8 @@ class APIKeysApi { /// Parameters: /// /// * [String] id (required): - Future deleteApiKey(String id,) async { - final response = await deleteApiKeyWithHttpInfo(id,); + Future deleteApiKey(String id, { Future? abortTrigger, }) async { + final response = await deleteApiKeyWithHttpInfo(id, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -130,7 +132,7 @@ class APIKeysApi { /// Parameters: /// /// * [String] id (required): - Future getApiKeyWithHttpInfo(String id,) async { + Future getApiKeyWithHttpInfo(String id, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/api-keys/{id}' .replaceAll('{id}', id); @@ -153,6 +155,7 @@ class APIKeysApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -163,8 +166,8 @@ class APIKeysApi { /// Parameters: /// /// * [String] id (required): - Future getApiKey(String id,) async { - final response = await getApiKeyWithHttpInfo(id,); + Future getApiKey(String id, { Future? abortTrigger, }) async { + final response = await getApiKeyWithHttpInfo(id, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -183,7 +186,7 @@ class APIKeysApi { /// Retrieve all API keys of the current user. /// /// Note: This method returns the HTTP [Response]. - Future getApiKeysWithHttpInfo() async { + Future getApiKeysWithHttpInfo({ Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/api-keys'; @@ -205,14 +208,15 @@ class APIKeysApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } /// List all API keys /// /// Retrieve all API keys of the current user. - Future?> getApiKeys() async { - final response = await getApiKeysWithHttpInfo(); + Future?> getApiKeys({ Future? abortTrigger, }) async { + final response = await getApiKeysWithHttpInfo(abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -234,7 +238,7 @@ class APIKeysApi { /// Retrieve the API key that is used to access this endpoint. /// /// Note: This method returns the HTTP [Response]. - Future getMyApiKeyWithHttpInfo() async { + Future getMyApiKeyWithHttpInfo({ Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/api-keys/me'; @@ -256,14 +260,15 @@ class APIKeysApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } /// Retrieve the current API key /// /// Retrieve the API key that is used to access this endpoint. - Future getMyApiKey() async { - final response = await getMyApiKeyWithHttpInfo(); + Future getMyApiKey({ Future? abortTrigger, }) async { + final response = await getMyApiKeyWithHttpInfo(abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -288,7 +293,7 @@ class APIKeysApi { /// * [String] id (required): /// /// * [ApiKeyUpdateDto] apiKeyUpdateDto (required): - Future updateApiKeyWithHttpInfo(String id, ApiKeyUpdateDto apiKeyUpdateDto,) async { + Future updateApiKeyWithHttpInfo(String id, ApiKeyUpdateDto apiKeyUpdateDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/api-keys/{id}' .replaceAll('{id}', id); @@ -311,6 +316,7 @@ class APIKeysApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -323,8 +329,8 @@ class APIKeysApi { /// * [String] id (required): /// /// * [ApiKeyUpdateDto] apiKeyUpdateDto (required): - Future updateApiKey(String id, ApiKeyUpdateDto apiKeyUpdateDto,) async { - final response = await updateApiKeyWithHttpInfo(id, apiKeyUpdateDto,); + Future updateApiKey(String id, ApiKeyUpdateDto apiKeyUpdateDto, { Future? abortTrigger, }) async { + final response = await updateApiKeyWithHttpInfo(id, apiKeyUpdateDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } diff --git a/mobile/openapi/lib/api/assets_api.dart b/mobile/openapi/lib/api/assets_api.dart index 691c57cd3e..bb14238e02 100644 --- a/mobile/openapi/lib/api/assets_api.dart +++ b/mobile/openapi/lib/api/assets_api.dart @@ -25,7 +25,7 @@ class AssetsApi { /// Parameters: /// /// * [AssetBulkUploadCheckDto] assetBulkUploadCheckDto (required): - Future checkBulkUploadWithHttpInfo(AssetBulkUploadCheckDto assetBulkUploadCheckDto,) async { + Future checkBulkUploadWithHttpInfo(AssetBulkUploadCheckDto assetBulkUploadCheckDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/assets/bulk-upload-check'; @@ -47,6 +47,7 @@ class AssetsApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -57,8 +58,8 @@ class AssetsApi { /// Parameters: /// /// * [AssetBulkUploadCheckDto] assetBulkUploadCheckDto (required): - Future checkBulkUpload(AssetBulkUploadCheckDto assetBulkUploadCheckDto,) async { - final response = await checkBulkUploadWithHttpInfo(assetBulkUploadCheckDto,); + Future checkBulkUpload(AssetBulkUploadCheckDto assetBulkUploadCheckDto, { Future? abortTrigger, }) async { + final response = await checkBulkUploadWithHttpInfo(assetBulkUploadCheckDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -81,7 +82,7 @@ class AssetsApi { /// Parameters: /// /// * [AssetCopyDto] assetCopyDto (required): - Future copyAssetWithHttpInfo(AssetCopyDto assetCopyDto,) async { + Future copyAssetWithHttpInfo(AssetCopyDto assetCopyDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/assets/copy'; @@ -103,6 +104,7 @@ class AssetsApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -113,8 +115,8 @@ class AssetsApi { /// Parameters: /// /// * [AssetCopyDto] assetCopyDto (required): - Future copyAsset(AssetCopyDto assetCopyDto,) async { - final response = await copyAssetWithHttpInfo(assetCopyDto,); + Future copyAsset(AssetCopyDto assetCopyDto, { Future? abortTrigger, }) async { + final response = await copyAssetWithHttpInfo(assetCopyDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -133,7 +135,7 @@ class AssetsApi { /// /// * [String] key (required): /// Metadata key - Future deleteAssetMetadataWithHttpInfo(String id, String key,) async { + Future deleteAssetMetadataWithHttpInfo(String id, String key, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/assets/{id}/metadata/{key}' .replaceAll('{id}', id) @@ -157,6 +159,7 @@ class AssetsApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -171,8 +174,8 @@ class AssetsApi { /// /// * [String] key (required): /// Metadata key - Future deleteAssetMetadata(String id, String key,) async { - final response = await deleteAssetMetadataWithHttpInfo(id, key,); + Future deleteAssetMetadata(String id, String key, { Future? abortTrigger, }) async { + final response = await deleteAssetMetadataWithHttpInfo(id, key, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -187,7 +190,7 @@ class AssetsApi { /// Parameters: /// /// * [AssetBulkDeleteDto] assetBulkDeleteDto (required): - Future deleteAssetsWithHttpInfo(AssetBulkDeleteDto assetBulkDeleteDto,) async { + Future deleteAssetsWithHttpInfo(AssetBulkDeleteDto assetBulkDeleteDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/assets'; @@ -209,6 +212,7 @@ class AssetsApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -219,8 +223,8 @@ class AssetsApi { /// Parameters: /// /// * [AssetBulkDeleteDto] assetBulkDeleteDto (required): - Future deleteAssets(AssetBulkDeleteDto assetBulkDeleteDto,) async { - final response = await deleteAssetsWithHttpInfo(assetBulkDeleteDto,); + Future deleteAssets(AssetBulkDeleteDto assetBulkDeleteDto, { Future? abortTrigger, }) async { + final response = await deleteAssetsWithHttpInfo(assetBulkDeleteDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -235,7 +239,7 @@ class AssetsApi { /// Parameters: /// /// * [AssetMetadataBulkDeleteDto] assetMetadataBulkDeleteDto (required): - Future deleteBulkAssetMetadataWithHttpInfo(AssetMetadataBulkDeleteDto assetMetadataBulkDeleteDto,) async { + Future deleteBulkAssetMetadataWithHttpInfo(AssetMetadataBulkDeleteDto assetMetadataBulkDeleteDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/assets/metadata'; @@ -257,6 +261,7 @@ class AssetsApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -267,8 +272,8 @@ class AssetsApi { /// Parameters: /// /// * [AssetMetadataBulkDeleteDto] assetMetadataBulkDeleteDto (required): - Future deleteBulkAssetMetadata(AssetMetadataBulkDeleteDto assetMetadataBulkDeleteDto,) async { - final response = await deleteBulkAssetMetadataWithHttpInfo(assetMetadataBulkDeleteDto,); + Future deleteBulkAssetMetadata(AssetMetadataBulkDeleteDto assetMetadataBulkDeleteDto, { Future? abortTrigger, }) async { + final response = await deleteBulkAssetMetadataWithHttpInfo(assetMetadataBulkDeleteDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -290,7 +295,7 @@ class AssetsApi { /// * [String] key: /// /// * [String] slug: - Future downloadAssetWithHttpInfo(String id, { bool? edited, String? key, String? slug, }) async { + Future downloadAssetWithHttpInfo(String id, { bool? edited, String? key, String? slug, Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/assets/{id}/original' .replaceAll('{id}', id); @@ -323,6 +328,7 @@ class AssetsApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -340,8 +346,8 @@ class AssetsApi { /// * [String] key: /// /// * [String] slug: - Future downloadAsset(String id, { bool? edited, String? key, String? slug, }) async { - final response = await downloadAssetWithHttpInfo(id, edited: edited, key: key, slug: slug, ); + Future downloadAsset(String id, { bool? edited, String? key, String? slug, Future? abortTrigger, }) async { + final response = await downloadAssetWithHttpInfo(id, edited: edited, key: key, slug: slug, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -366,7 +372,7 @@ class AssetsApi { /// * [String] id (required): /// /// * [AssetEditsCreateDto] assetEditsCreateDto (required): - Future editAssetWithHttpInfo(String id, AssetEditsCreateDto assetEditsCreateDto,) async { + Future editAssetWithHttpInfo(String id, AssetEditsCreateDto assetEditsCreateDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/assets/{id}/edits' .replaceAll('{id}', id); @@ -389,6 +395,7 @@ class AssetsApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -401,8 +408,8 @@ class AssetsApi { /// * [String] id (required): /// /// * [AssetEditsCreateDto] assetEditsCreateDto (required): - Future editAsset(String id, AssetEditsCreateDto assetEditsCreateDto,) async { - final response = await editAssetWithHttpInfo(id, assetEditsCreateDto,); + Future editAsset(String id, AssetEditsCreateDto assetEditsCreateDto, { Future? abortTrigger, }) async { + final response = await editAssetWithHttpInfo(id, assetEditsCreateDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -425,7 +432,7 @@ class AssetsApi { /// Parameters: /// /// * [String] id (required): - Future getAssetEditsWithHttpInfo(String id,) async { + Future getAssetEditsWithHttpInfo(String id, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/assets/{id}/edits' .replaceAll('{id}', id); @@ -448,6 +455,7 @@ class AssetsApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -458,8 +466,8 @@ class AssetsApi { /// Parameters: /// /// * [String] id (required): - Future getAssetEdits(String id,) async { - final response = await getAssetEditsWithHttpInfo(id,); + Future getAssetEdits(String id, { Future? abortTrigger, }) async { + final response = await getAssetEditsWithHttpInfo(id, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -486,7 +494,7 @@ class AssetsApi { /// * [String] key: /// /// * [String] slug: - Future getAssetInfoWithHttpInfo(String id, { String? key, String? slug, }) async { + Future getAssetInfoWithHttpInfo(String id, { String? key, String? slug, Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/assets/{id}' .replaceAll('{id}', id); @@ -516,6 +524,7 @@ class AssetsApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -530,8 +539,8 @@ class AssetsApi { /// * [String] key: /// /// * [String] slug: - Future getAssetInfo(String id, { String? key, String? slug, }) async { - final response = await getAssetInfoWithHttpInfo(id, key: key, slug: slug, ); + Future getAssetInfo(String id, { String? key, String? slug, Future? abortTrigger, }) async { + final response = await getAssetInfoWithHttpInfo(id, key: key, slug: slug, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -554,7 +563,7 @@ class AssetsApi { /// Parameters: /// /// * [String] id (required): - Future getAssetMetadataWithHttpInfo(String id,) async { + Future getAssetMetadataWithHttpInfo(String id, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/assets/{id}/metadata' .replaceAll('{id}', id); @@ -577,6 +586,7 @@ class AssetsApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -587,8 +597,8 @@ class AssetsApi { /// Parameters: /// /// * [String] id (required): - Future?> getAssetMetadata(String id,) async { - final response = await getAssetMetadataWithHttpInfo(id,); + Future?> getAssetMetadata(String id, { Future? abortTrigger, }) async { + final response = await getAssetMetadataWithHttpInfo(id, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -618,7 +628,7 @@ class AssetsApi { /// /// * [String] key (required): /// Metadata key - Future getAssetMetadataByKeyWithHttpInfo(String id, String key,) async { + Future getAssetMetadataByKeyWithHttpInfo(String id, String key, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/assets/{id}/metadata/{key}' .replaceAll('{id}', id) @@ -642,6 +652,7 @@ class AssetsApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -656,8 +667,8 @@ class AssetsApi { /// /// * [String] key (required): /// Metadata key - Future getAssetMetadataByKey(String id, String key,) async { - final response = await getAssetMetadataByKeyWithHttpInfo(id, key,); + Future getAssetMetadataByKey(String id, String key, { Future? abortTrigger, }) async { + final response = await getAssetMetadataByKeyWithHttpInfo(id, key, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -680,7 +691,7 @@ class AssetsApi { /// Parameters: /// /// * [String] id (required): - Future getAssetOcrWithHttpInfo(String id,) async { + Future getAssetOcrWithHttpInfo(String id, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/assets/{id}/ocr' .replaceAll('{id}', id); @@ -703,6 +714,7 @@ class AssetsApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -713,8 +725,8 @@ class AssetsApi { /// Parameters: /// /// * [String] id (required): - Future?> getAssetOcr(String id,) async { - final response = await getAssetOcrWithHttpInfo(id,); + Future?> getAssetOcr(String id, { Future? abortTrigger, }) async { + final response = await getAssetOcrWithHttpInfo(id, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -746,7 +758,7 @@ class AssetsApi { /// Filter by trash status /// /// * [AssetVisibility] visibility: - Future getAssetStatisticsWithHttpInfo({ bool? isFavorite, bool? isTrashed, AssetVisibility? visibility, }) async { + Future getAssetStatisticsWithHttpInfo({ bool? isFavorite, bool? isTrashed, AssetVisibility? visibility, Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/assets/statistics'; @@ -778,6 +790,7 @@ class AssetsApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -794,8 +807,8 @@ class AssetsApi { /// Filter by trash status /// /// * [AssetVisibility] visibility: - Future getAssetStatistics({ bool? isFavorite, bool? isTrashed, AssetVisibility? visibility, }) async { - final response = await getAssetStatisticsWithHttpInfo( isFavorite: isFavorite, isTrashed: isTrashed, visibility: visibility, ); + Future getAssetStatistics({ bool? isFavorite, bool? isTrashed, AssetVisibility? visibility, Future? abortTrigger, }) async { + final response = await getAssetStatisticsWithHttpInfo(isFavorite: isFavorite, isTrashed: isTrashed, visibility: visibility, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -822,7 +835,7 @@ class AssetsApi { /// * [String] key: /// /// * [String] slug: - Future playAssetVideoWithHttpInfo(String id, { String? key, String? slug, }) async { + Future playAssetVideoWithHttpInfo(String id, { String? key, String? slug, Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/assets/{id}/video/playback' .replaceAll('{id}', id); @@ -852,6 +865,7 @@ class AssetsApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -866,8 +880,8 @@ class AssetsApi { /// * [String] key: /// /// * [String] slug: - Future playAssetVideo(String id, { String? key, String? slug, }) async { - final response = await playAssetVideoWithHttpInfo(id, key: key, slug: slug, ); + Future playAssetVideo(String id, { String? key, String? slug, Future? abortTrigger, }) async { + final response = await playAssetVideoWithHttpInfo(id, key: key, slug: slug, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -890,7 +904,7 @@ class AssetsApi { /// Parameters: /// /// * [String] id (required): - Future removeAssetEditsWithHttpInfo(String id,) async { + Future removeAssetEditsWithHttpInfo(String id, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/assets/{id}/edits' .replaceAll('{id}', id); @@ -913,6 +927,7 @@ class AssetsApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -923,8 +938,8 @@ class AssetsApi { /// Parameters: /// /// * [String] id (required): - Future removeAssetEdits(String id,) async { - final response = await removeAssetEditsWithHttpInfo(id,); + Future removeAssetEdits(String id, { Future? abortTrigger, }) async { + final response = await removeAssetEditsWithHttpInfo(id, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -939,7 +954,7 @@ class AssetsApi { /// Parameters: /// /// * [AssetJobsDto] assetJobsDto (required): - Future runAssetJobsWithHttpInfo(AssetJobsDto assetJobsDto,) async { + Future runAssetJobsWithHttpInfo(AssetJobsDto assetJobsDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/assets/jobs'; @@ -961,6 +976,7 @@ class AssetsApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -971,8 +987,8 @@ class AssetsApi { /// Parameters: /// /// * [AssetJobsDto] assetJobsDto (required): - Future runAssetJobs(AssetJobsDto assetJobsDto,) async { - final response = await runAssetJobsWithHttpInfo(assetJobsDto,); + Future runAssetJobs(AssetJobsDto assetJobsDto, { Future? abortTrigger, }) async { + final response = await runAssetJobsWithHttpInfo(assetJobsDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -989,7 +1005,7 @@ class AssetsApi { /// * [String] id (required): /// /// * [UpdateAssetDto] updateAssetDto (required): - Future updateAssetWithHttpInfo(String id, UpdateAssetDto updateAssetDto,) async { + Future updateAssetWithHttpInfo(String id, UpdateAssetDto updateAssetDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/assets/{id}' .replaceAll('{id}', id); @@ -1012,6 +1028,7 @@ class AssetsApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -1024,8 +1041,8 @@ class AssetsApi { /// * [String] id (required): /// /// * [UpdateAssetDto] updateAssetDto (required): - Future updateAsset(String id, UpdateAssetDto updateAssetDto,) async { - final response = await updateAssetWithHttpInfo(id, updateAssetDto,); + Future updateAsset(String id, UpdateAssetDto updateAssetDto, { Future? abortTrigger, }) async { + final response = await updateAssetWithHttpInfo(id, updateAssetDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -1050,7 +1067,7 @@ class AssetsApi { /// * [String] id (required): /// /// * [AssetMetadataUpsertDto] assetMetadataUpsertDto (required): - Future updateAssetMetadataWithHttpInfo(String id, AssetMetadataUpsertDto assetMetadataUpsertDto,) async { + Future updateAssetMetadataWithHttpInfo(String id, AssetMetadataUpsertDto assetMetadataUpsertDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/assets/{id}/metadata' .replaceAll('{id}', id); @@ -1073,6 +1090,7 @@ class AssetsApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -1085,8 +1103,8 @@ class AssetsApi { /// * [String] id (required): /// /// * [AssetMetadataUpsertDto] assetMetadataUpsertDto (required): - Future?> updateAssetMetadata(String id, AssetMetadataUpsertDto assetMetadataUpsertDto,) async { - final response = await updateAssetMetadataWithHttpInfo(id, assetMetadataUpsertDto,); + Future?> updateAssetMetadata(String id, AssetMetadataUpsertDto assetMetadataUpsertDto, { Future? abortTrigger, }) async { + final response = await updateAssetMetadataWithHttpInfo(id, assetMetadataUpsertDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -1112,7 +1130,7 @@ class AssetsApi { /// Parameters: /// /// * [AssetBulkUpdateDto] assetBulkUpdateDto (required): - Future updateAssetsWithHttpInfo(AssetBulkUpdateDto assetBulkUpdateDto,) async { + Future updateAssetsWithHttpInfo(AssetBulkUpdateDto assetBulkUpdateDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/assets'; @@ -1134,6 +1152,7 @@ class AssetsApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -1144,8 +1163,8 @@ class AssetsApi { /// Parameters: /// /// * [AssetBulkUpdateDto] assetBulkUpdateDto (required): - Future updateAssets(AssetBulkUpdateDto assetBulkUpdateDto,) async { - final response = await updateAssetsWithHttpInfo(assetBulkUpdateDto,); + Future updateAssets(AssetBulkUpdateDto assetBulkUpdateDto, { Future? abortTrigger, }) async { + final response = await updateAssetsWithHttpInfo(assetBulkUpdateDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -1160,7 +1179,7 @@ class AssetsApi { /// Parameters: /// /// * [AssetMetadataBulkUpsertDto] assetMetadataBulkUpsertDto (required): - Future updateBulkAssetMetadataWithHttpInfo(AssetMetadataBulkUpsertDto assetMetadataBulkUpsertDto,) async { + Future updateBulkAssetMetadataWithHttpInfo(AssetMetadataBulkUpsertDto assetMetadataBulkUpsertDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/assets/metadata'; @@ -1182,6 +1201,7 @@ class AssetsApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -1192,8 +1212,8 @@ class AssetsApi { /// Parameters: /// /// * [AssetMetadataBulkUpsertDto] assetMetadataBulkUpsertDto (required): - Future?> updateBulkAssetMetadata(AssetMetadataBulkUpsertDto assetMetadataBulkUpsertDto,) async { - final response = await updateBulkAssetMetadataWithHttpInfo(assetMetadataBulkUpsertDto,); + Future?> updateBulkAssetMetadata(AssetMetadataBulkUpsertDto assetMetadataBulkUpsertDto, { Future? abortTrigger, }) async { + final response = await updateBulkAssetMetadataWithHttpInfo(assetMetadataBulkUpsertDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -1253,7 +1273,7 @@ class AssetsApi { /// Sidecar file data /// /// * [AssetVisibility] visibility: - Future uploadAssetWithHttpInfo(MultipartFile assetData, DateTime fileCreatedAt, DateTime fileModifiedAt, { String? key, String? slug, String? xImmichChecksum, int? duration, String? filename, bool? isFavorite, String? livePhotoVideoId, List? metadata, MultipartFile? sidecarData, AssetVisibility? visibility, }) async { + Future uploadAssetWithHttpInfo(MultipartFile assetData, DateTime fileCreatedAt, DateTime fileModifiedAt, { String? key, String? slug, String? xImmichChecksum, int? duration, String? filename, bool? isFavorite, String? livePhotoVideoId, List? metadata, MultipartFile? sidecarData, AssetVisibility? visibility, Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/assets'; @@ -1333,6 +1353,7 @@ class AssetsApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -1377,8 +1398,8 @@ class AssetsApi { /// Sidecar file data /// /// * [AssetVisibility] visibility: - Future uploadAsset(MultipartFile assetData, DateTime fileCreatedAt, DateTime fileModifiedAt, { String? key, String? slug, String? xImmichChecksum, int? duration, String? filename, bool? isFavorite, String? livePhotoVideoId, List? metadata, MultipartFile? sidecarData, AssetVisibility? visibility, }) async { - final response = await uploadAssetWithHttpInfo(assetData, fileCreatedAt, fileModifiedAt, key: key, slug: slug, xImmichChecksum: xImmichChecksum, duration: duration, filename: filename, isFavorite: isFavorite, livePhotoVideoId: livePhotoVideoId, metadata: metadata, sidecarData: sidecarData, visibility: visibility, ); + Future uploadAsset(MultipartFile assetData, DateTime fileCreatedAt, DateTime fileModifiedAt, { String? key, String? slug, String? xImmichChecksum, int? duration, String? filename, bool? isFavorite, String? livePhotoVideoId, List? metadata, MultipartFile? sidecarData, AssetVisibility? visibility, Future? abortTrigger, }) async { + final response = await uploadAssetWithHttpInfo(assetData, fileCreatedAt, fileModifiedAt, key: key, slug: slug, xImmichChecksum: xImmichChecksum, duration: duration, filename: filename, isFavorite: isFavorite, livePhotoVideoId: livePhotoVideoId, metadata: metadata, sidecarData: sidecarData, visibility: visibility, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -1410,7 +1431,7 @@ class AssetsApi { /// * [AssetMediaSize] size: /// /// * [String] slug: - Future viewAssetWithHttpInfo(String id, { bool? edited, String? key, AssetMediaSize? size, String? slug, }) async { + Future viewAssetWithHttpInfo(String id, { bool? edited, String? key, AssetMediaSize? size, String? slug, Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/assets/{id}/thumbnail' .replaceAll('{id}', id); @@ -1446,6 +1467,7 @@ class AssetsApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -1465,8 +1487,8 @@ class AssetsApi { /// * [AssetMediaSize] size: /// /// * [String] slug: - Future viewAsset(String id, { bool? edited, String? key, AssetMediaSize? size, String? slug, }) async { - final response = await viewAssetWithHttpInfo(id, edited: edited, key: key, size: size, slug: slug, ); + Future viewAsset(String id, { bool? edited, String? key, AssetMediaSize? size, String? slug, Future? abortTrigger, }) async { + final response = await viewAssetWithHttpInfo(id, edited: edited, key: key, size: size, slug: slug, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } diff --git a/mobile/openapi/lib/api/authentication_admin_api.dart b/mobile/openapi/lib/api/authentication_admin_api.dart index 0a4b91ebc3..2c107891b3 100644 --- a/mobile/openapi/lib/api/authentication_admin_api.dart +++ b/mobile/openapi/lib/api/authentication_admin_api.dart @@ -21,7 +21,7 @@ class AuthenticationAdminApi { /// Unlinks all OAuth accounts associated with user accounts in the system. /// /// Note: This method returns the HTTP [Response]. - Future unlinkAllOAuthAccountsAdminWithHttpInfo() async { + Future unlinkAllOAuthAccountsAdminWithHttpInfo({ Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/admin/auth/unlink-all'; @@ -43,14 +43,15 @@ class AuthenticationAdminApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } /// Unlink all OAuth accounts /// /// Unlinks all OAuth accounts associated with user accounts in the system. - Future unlinkAllOAuthAccountsAdmin() async { - final response = await unlinkAllOAuthAccountsAdminWithHttpInfo(); + Future unlinkAllOAuthAccountsAdmin({ Future? abortTrigger, }) async { + final response = await unlinkAllOAuthAccountsAdminWithHttpInfo(abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } diff --git a/mobile/openapi/lib/api/authentication_api.dart b/mobile/openapi/lib/api/authentication_api.dart index e1219f2c03..8e088d040b 100644 --- a/mobile/openapi/lib/api/authentication_api.dart +++ b/mobile/openapi/lib/api/authentication_api.dart @@ -25,7 +25,7 @@ class AuthenticationApi { /// Parameters: /// /// * [ChangePasswordDto] changePasswordDto (required): - Future changePasswordWithHttpInfo(ChangePasswordDto changePasswordDto,) async { + Future changePasswordWithHttpInfo(ChangePasswordDto changePasswordDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/auth/change-password'; @@ -47,6 +47,7 @@ class AuthenticationApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -57,8 +58,8 @@ class AuthenticationApi { /// Parameters: /// /// * [ChangePasswordDto] changePasswordDto (required): - Future changePassword(ChangePasswordDto changePasswordDto,) async { - final response = await changePasswordWithHttpInfo(changePasswordDto,); + Future changePassword(ChangePasswordDto changePasswordDto, { Future? abortTrigger, }) async { + final response = await changePasswordWithHttpInfo(changePasswordDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -81,7 +82,7 @@ class AuthenticationApi { /// Parameters: /// /// * [PinCodeChangeDto] pinCodeChangeDto (required): - Future changePinCodeWithHttpInfo(PinCodeChangeDto pinCodeChangeDto,) async { + Future changePinCodeWithHttpInfo(PinCodeChangeDto pinCodeChangeDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/auth/pin-code'; @@ -103,6 +104,7 @@ class AuthenticationApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -113,8 +115,8 @@ class AuthenticationApi { /// Parameters: /// /// * [PinCodeChangeDto] pinCodeChangeDto (required): - Future changePinCode(PinCodeChangeDto pinCodeChangeDto,) async { - final response = await changePinCodeWithHttpInfo(pinCodeChangeDto,); + Future changePinCode(PinCodeChangeDto pinCodeChangeDto, { Future? abortTrigger, }) async { + final response = await changePinCodeWithHttpInfo(pinCodeChangeDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -129,7 +131,7 @@ class AuthenticationApi { /// Parameters: /// /// * [OAuthCallbackDto] oAuthCallbackDto (required): - Future finishOAuthWithHttpInfo(OAuthCallbackDto oAuthCallbackDto,) async { + Future finishOAuthWithHttpInfo(OAuthCallbackDto oAuthCallbackDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/oauth/callback'; @@ -151,6 +153,7 @@ class AuthenticationApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -161,8 +164,8 @@ class AuthenticationApi { /// Parameters: /// /// * [OAuthCallbackDto] oAuthCallbackDto (required): - Future finishOAuth(OAuthCallbackDto oAuthCallbackDto,) async { - final response = await finishOAuthWithHttpInfo(oAuthCallbackDto,); + Future finishOAuth(OAuthCallbackDto oAuthCallbackDto, { Future? abortTrigger, }) async { + final response = await finishOAuthWithHttpInfo(oAuthCallbackDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -181,7 +184,7 @@ class AuthenticationApi { /// Get information about the current session, including whether the user has a password, and if the session can access locked assets. /// /// Note: This method returns the HTTP [Response]. - Future getAuthStatusWithHttpInfo() async { + Future getAuthStatusWithHttpInfo({ Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/auth/status'; @@ -203,14 +206,15 @@ class AuthenticationApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } /// Retrieve auth status /// /// Get information about the current session, including whether the user has a password, and if the session can access locked assets. - Future getAuthStatus() async { - final response = await getAuthStatusWithHttpInfo(); + Future getAuthStatus({ Future? abortTrigger, }) async { + final response = await getAuthStatusWithHttpInfo(abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -233,7 +237,7 @@ class AuthenticationApi { /// Parameters: /// /// * [OAuthCallbackDto] oAuthCallbackDto (required): - Future linkOAuthAccountWithHttpInfo(OAuthCallbackDto oAuthCallbackDto,) async { + Future linkOAuthAccountWithHttpInfo(OAuthCallbackDto oAuthCallbackDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/oauth/link'; @@ -255,6 +259,7 @@ class AuthenticationApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -265,8 +270,8 @@ class AuthenticationApi { /// Parameters: /// /// * [OAuthCallbackDto] oAuthCallbackDto (required): - Future linkOAuthAccount(OAuthCallbackDto oAuthCallbackDto,) async { - final response = await linkOAuthAccountWithHttpInfo(oAuthCallbackDto,); + Future linkOAuthAccount(OAuthCallbackDto oAuthCallbackDto, { Future? abortTrigger, }) async { + final response = await linkOAuthAccountWithHttpInfo(oAuthCallbackDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -285,7 +290,7 @@ class AuthenticationApi { /// Remove elevated access to locked assets from the current session. /// /// Note: This method returns the HTTP [Response]. - Future lockAuthSessionWithHttpInfo() async { + Future lockAuthSessionWithHttpInfo({ Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/auth/session/lock'; @@ -307,14 +312,15 @@ class AuthenticationApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } /// Lock auth session /// /// Remove elevated access to locked assets from the current session. - Future lockAuthSession() async { - final response = await lockAuthSessionWithHttpInfo(); + Future lockAuthSession({ Future? abortTrigger, }) async { + final response = await lockAuthSessionWithHttpInfo(abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -329,7 +335,7 @@ class AuthenticationApi { /// Parameters: /// /// * [LoginCredentialDto] loginCredentialDto (required): - Future loginWithHttpInfo(LoginCredentialDto loginCredentialDto,) async { + Future loginWithHttpInfo(LoginCredentialDto loginCredentialDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/auth/login'; @@ -351,6 +357,7 @@ class AuthenticationApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -361,8 +368,8 @@ class AuthenticationApi { /// Parameters: /// /// * [LoginCredentialDto] loginCredentialDto (required): - Future login(LoginCredentialDto loginCredentialDto,) async { - final response = await loginWithHttpInfo(loginCredentialDto,); + Future login(LoginCredentialDto loginCredentialDto, { Future? abortTrigger, }) async { + final response = await loginWithHttpInfo(loginCredentialDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -381,7 +388,7 @@ class AuthenticationApi { /// Logout the current user and invalidate the session token. /// /// Note: This method returns the HTTP [Response]. - Future logoutWithHttpInfo() async { + Future logoutWithHttpInfo({ Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/auth/logout'; @@ -403,14 +410,15 @@ class AuthenticationApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } /// Logout /// /// Logout the current user and invalidate the session token. - Future logout() async { - final response = await logoutWithHttpInfo(); + Future logout({ Future? abortTrigger, }) async { + final response = await logoutWithHttpInfo(abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -434,7 +442,7 @@ class AuthenticationApi { /// /// * [String] logoutToken (required): /// OAuth logout token - Future logoutOAuthWithHttpInfo(String logoutToken,) async { + Future logoutOAuthWithHttpInfo(String logoutToken, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/oauth/backchannel-logout'; @@ -459,6 +467,7 @@ class AuthenticationApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -470,8 +479,8 @@ class AuthenticationApi { /// /// * [String] logoutToken (required): /// OAuth logout token - Future logoutOAuth(String logoutToken,) async { - final response = await logoutOAuthWithHttpInfo(logoutToken,); + Future logoutOAuth(String logoutToken, { Future? abortTrigger, }) async { + final response = await logoutOAuthWithHttpInfo(logoutToken, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -482,7 +491,7 @@ class AuthenticationApi { /// Requests to this URL are automatically forwarded to the mobile app, and is used in some cases for OAuth redirecting. /// /// Note: This method returns the HTTP [Response]. - Future redirectOAuthToMobileWithHttpInfo() async { + Future redirectOAuthToMobileWithHttpInfo({ Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/oauth/mobile-redirect'; @@ -504,14 +513,15 @@ class AuthenticationApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } /// Redirect OAuth to mobile /// /// Requests to this URL are automatically forwarded to the mobile app, and is used in some cases for OAuth redirecting. - Future redirectOAuthToMobile() async { - final response = await redirectOAuthToMobileWithHttpInfo(); + Future redirectOAuthToMobile({ Future? abortTrigger, }) async { + final response = await redirectOAuthToMobileWithHttpInfo(abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -526,7 +536,7 @@ class AuthenticationApi { /// Parameters: /// /// * [PinCodeResetDto] pinCodeResetDto (required): - Future resetPinCodeWithHttpInfo(PinCodeResetDto pinCodeResetDto,) async { + Future resetPinCodeWithHttpInfo(PinCodeResetDto pinCodeResetDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/auth/pin-code'; @@ -548,6 +558,7 @@ class AuthenticationApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -558,8 +569,8 @@ class AuthenticationApi { /// Parameters: /// /// * [PinCodeResetDto] pinCodeResetDto (required): - Future resetPinCode(PinCodeResetDto pinCodeResetDto,) async { - final response = await resetPinCodeWithHttpInfo(pinCodeResetDto,); + Future resetPinCode(PinCodeResetDto pinCodeResetDto, { Future? abortTrigger, }) async { + final response = await resetPinCodeWithHttpInfo(pinCodeResetDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -574,7 +585,7 @@ class AuthenticationApi { /// Parameters: /// /// * [PinCodeSetupDto] pinCodeSetupDto (required): - Future setupPinCodeWithHttpInfo(PinCodeSetupDto pinCodeSetupDto,) async { + Future setupPinCodeWithHttpInfo(PinCodeSetupDto pinCodeSetupDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/auth/pin-code'; @@ -596,6 +607,7 @@ class AuthenticationApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -606,8 +618,8 @@ class AuthenticationApi { /// Parameters: /// /// * [PinCodeSetupDto] pinCodeSetupDto (required): - Future setupPinCode(PinCodeSetupDto pinCodeSetupDto,) async { - final response = await setupPinCodeWithHttpInfo(pinCodeSetupDto,); + Future setupPinCode(PinCodeSetupDto pinCodeSetupDto, { Future? abortTrigger, }) async { + final response = await setupPinCodeWithHttpInfo(pinCodeSetupDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -622,7 +634,7 @@ class AuthenticationApi { /// Parameters: /// /// * [SignUpDto] signUpDto (required): - Future signUpAdminWithHttpInfo(SignUpDto signUpDto,) async { + Future signUpAdminWithHttpInfo(SignUpDto signUpDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/auth/admin-sign-up'; @@ -644,6 +656,7 @@ class AuthenticationApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -654,8 +667,8 @@ class AuthenticationApi { /// Parameters: /// /// * [SignUpDto] signUpDto (required): - Future signUpAdmin(SignUpDto signUpDto,) async { - final response = await signUpAdminWithHttpInfo(signUpDto,); + Future signUpAdmin(SignUpDto signUpDto, { Future? abortTrigger, }) async { + final response = await signUpAdminWithHttpInfo(signUpDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -678,7 +691,7 @@ class AuthenticationApi { /// Parameters: /// /// * [OAuthConfigDto] oAuthConfigDto (required): - Future startOAuthWithHttpInfo(OAuthConfigDto oAuthConfigDto,) async { + Future startOAuthWithHttpInfo(OAuthConfigDto oAuthConfigDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/oauth/authorize'; @@ -700,6 +713,7 @@ class AuthenticationApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -710,8 +724,8 @@ class AuthenticationApi { /// Parameters: /// /// * [OAuthConfigDto] oAuthConfigDto (required): - Future startOAuth(OAuthConfigDto oAuthConfigDto,) async { - final response = await startOAuthWithHttpInfo(oAuthConfigDto,); + Future startOAuth(OAuthConfigDto oAuthConfigDto, { Future? abortTrigger, }) async { + final response = await startOAuthWithHttpInfo(oAuthConfigDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -730,7 +744,7 @@ class AuthenticationApi { /// Unlink the OAuth account from the authenticated user. /// /// Note: This method returns the HTTP [Response]. - Future unlinkOAuthAccountWithHttpInfo() async { + Future unlinkOAuthAccountWithHttpInfo({ Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/oauth/unlink'; @@ -752,14 +766,15 @@ class AuthenticationApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } /// Unlink OAuth account /// /// Unlink the OAuth account from the authenticated user. - Future unlinkOAuthAccount() async { - final response = await unlinkOAuthAccountWithHttpInfo(); + Future unlinkOAuthAccount({ Future? abortTrigger, }) async { + final response = await unlinkOAuthAccountWithHttpInfo(abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -782,7 +797,7 @@ class AuthenticationApi { /// Parameters: /// /// * [SessionUnlockDto] sessionUnlockDto (required): - Future unlockAuthSessionWithHttpInfo(SessionUnlockDto sessionUnlockDto,) async { + Future unlockAuthSessionWithHttpInfo(SessionUnlockDto sessionUnlockDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/auth/session/unlock'; @@ -804,6 +819,7 @@ class AuthenticationApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -814,8 +830,8 @@ class AuthenticationApi { /// Parameters: /// /// * [SessionUnlockDto] sessionUnlockDto (required): - Future unlockAuthSession(SessionUnlockDto sessionUnlockDto,) async { - final response = await unlockAuthSessionWithHttpInfo(sessionUnlockDto,); + Future unlockAuthSession(SessionUnlockDto sessionUnlockDto, { Future? abortTrigger, }) async { + final response = await unlockAuthSessionWithHttpInfo(sessionUnlockDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -826,7 +842,7 @@ class AuthenticationApi { /// Validate the current authorization method is still valid. /// /// Note: This method returns the HTTP [Response]. - Future validateAccessTokenWithHttpInfo() async { + Future validateAccessTokenWithHttpInfo({ Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/auth/validateToken'; @@ -848,14 +864,15 @@ class AuthenticationApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } /// Validate access token /// /// Validate the current authorization method is still valid. - Future validateAccessToken() async { - final response = await validateAccessTokenWithHttpInfo(); + Future validateAccessToken({ Future? abortTrigger, }) async { + final response = await validateAccessTokenWithHttpInfo(abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } diff --git a/mobile/openapi/lib/api/database_backups_admin_api.dart b/mobile/openapi/lib/api/database_backups_admin_api.dart index 768185db1e..ba393833b5 100644 --- a/mobile/openapi/lib/api/database_backups_admin_api.dart +++ b/mobile/openapi/lib/api/database_backups_admin_api.dart @@ -25,7 +25,7 @@ class DatabaseBackupsAdminApi { /// Parameters: /// /// * [DatabaseBackupDeleteDto] databaseBackupDeleteDto (required): - Future deleteDatabaseBackupWithHttpInfo(DatabaseBackupDeleteDto databaseBackupDeleteDto,) async { + Future deleteDatabaseBackupWithHttpInfo(DatabaseBackupDeleteDto databaseBackupDeleteDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/admin/database-backups'; @@ -47,6 +47,7 @@ class DatabaseBackupsAdminApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -57,8 +58,8 @@ class DatabaseBackupsAdminApi { /// Parameters: /// /// * [DatabaseBackupDeleteDto] databaseBackupDeleteDto (required): - Future deleteDatabaseBackup(DatabaseBackupDeleteDto databaseBackupDeleteDto,) async { - final response = await deleteDatabaseBackupWithHttpInfo(databaseBackupDeleteDto,); + Future deleteDatabaseBackup(DatabaseBackupDeleteDto databaseBackupDeleteDto, { Future? abortTrigger, }) async { + final response = await deleteDatabaseBackupWithHttpInfo(databaseBackupDeleteDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -73,7 +74,7 @@ class DatabaseBackupsAdminApi { /// Parameters: /// /// * [String] filename (required): - Future downloadDatabaseBackupWithHttpInfo(String filename,) async { + Future downloadDatabaseBackupWithHttpInfo(String filename, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/admin/database-backups/{filename}' .replaceAll('{filename}', filename); @@ -96,6 +97,7 @@ class DatabaseBackupsAdminApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -106,8 +108,8 @@ class DatabaseBackupsAdminApi { /// Parameters: /// /// * [String] filename (required): - Future downloadDatabaseBackup(String filename,) async { - final response = await downloadDatabaseBackupWithHttpInfo(filename,); + Future downloadDatabaseBackup(String filename, { Future? abortTrigger, }) async { + final response = await downloadDatabaseBackupWithHttpInfo(filename, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -126,7 +128,7 @@ class DatabaseBackupsAdminApi { /// Get the list of the successful and failed backups /// /// Note: This method returns the HTTP [Response]. - Future listDatabaseBackupsWithHttpInfo() async { + Future listDatabaseBackupsWithHttpInfo({ Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/admin/database-backups'; @@ -148,14 +150,15 @@ class DatabaseBackupsAdminApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } /// List database backups /// /// Get the list of the successful and failed backups - Future listDatabaseBackups() async { - final response = await listDatabaseBackupsWithHttpInfo(); + Future listDatabaseBackups({ Future? abortTrigger, }) async { + final response = await listDatabaseBackupsWithHttpInfo(abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -174,7 +177,7 @@ class DatabaseBackupsAdminApi { /// Put Immich into maintenance mode to restore a backup (Immich must not be configured) /// /// Note: This method returns the HTTP [Response]. - Future startDatabaseRestoreFlowWithHttpInfo() async { + Future startDatabaseRestoreFlowWithHttpInfo({ Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/admin/database-backups/start-restore'; @@ -196,14 +199,15 @@ class DatabaseBackupsAdminApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } /// Start database backup restore flow /// /// Put Immich into maintenance mode to restore a backup (Immich must not be configured) - Future startDatabaseRestoreFlow() async { - final response = await startDatabaseRestoreFlowWithHttpInfo(); + Future startDatabaseRestoreFlow({ Future? abortTrigger, }) async { + final response = await startDatabaseRestoreFlowWithHttpInfo(abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -219,7 +223,7 @@ class DatabaseBackupsAdminApi { /// /// * [MultipartFile] file: /// Database backup file - Future uploadDatabaseBackupWithHttpInfo({ MultipartFile? file, }) async { + Future uploadDatabaseBackupWithHttpInfo({ MultipartFile? file, Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/admin/database-backups/upload'; @@ -251,6 +255,7 @@ class DatabaseBackupsAdminApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -262,8 +267,8 @@ class DatabaseBackupsAdminApi { /// /// * [MultipartFile] file: /// Database backup file - Future uploadDatabaseBackup({ MultipartFile? file, }) async { - final response = await uploadDatabaseBackupWithHttpInfo( file: file, ); + Future uploadDatabaseBackup({ MultipartFile? file, Future? abortTrigger, }) async { + final response = await uploadDatabaseBackupWithHttpInfo(file: file, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } diff --git a/mobile/openapi/lib/api/deprecated_api.dart b/mobile/openapi/lib/api/deprecated_api.dart index a437cd5837..a8e2deab44 100644 --- a/mobile/openapi/lib/api/deprecated_api.dart +++ b/mobile/openapi/lib/api/deprecated_api.dart @@ -25,7 +25,7 @@ class DeprecatedApi { /// Parameters: /// /// * [String] id (required): - Future createPartnerDeprecatedWithHttpInfo(String id,) async { + Future createPartnerDeprecatedWithHttpInfo(String id, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/partners/{id}' .replaceAll('{id}', id); @@ -48,6 +48,7 @@ class DeprecatedApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -58,8 +59,8 @@ class DeprecatedApi { /// Parameters: /// /// * [String] id (required): - Future createPartnerDeprecated(String id,) async { - final response = await createPartnerDeprecatedWithHttpInfo(id,); + Future createPartnerDeprecated(String id, { Future? abortTrigger, }) async { + final response = await createPartnerDeprecatedWithHttpInfo(id, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -78,7 +79,7 @@ class DeprecatedApi { /// Retrieve the counts of the current queue, as well as the current status. /// /// Note: This method returns the HTTP [Response]. - Future getQueuesLegacyWithHttpInfo() async { + Future getQueuesLegacyWithHttpInfo({ Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/jobs'; @@ -100,14 +101,15 @@ class DeprecatedApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } /// Retrieve queue counts and status /// /// Retrieve the counts of the current queue, as well as the current status. - Future getQueuesLegacy() async { - final response = await getQueuesLegacyWithHttpInfo(); + Future getQueuesLegacy({ Future? abortTrigger, }) async { + final response = await getQueuesLegacyWithHttpInfo(abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -132,7 +134,7 @@ class DeprecatedApi { /// * [QueueName] name (required): /// /// * [QueueCommandDto] queueCommandDto (required): - Future runQueueCommandLegacyWithHttpInfo(QueueName name, QueueCommandDto queueCommandDto,) async { + Future runQueueCommandLegacyWithHttpInfo(QueueName name, QueueCommandDto queueCommandDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/jobs/{name}' .replaceAll('{name}', name.toString()); @@ -155,6 +157,7 @@ class DeprecatedApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -167,8 +170,8 @@ class DeprecatedApi { /// * [QueueName] name (required): /// /// * [QueueCommandDto] queueCommandDto (required): - Future runQueueCommandLegacy(QueueName name, QueueCommandDto queueCommandDto,) async { - final response = await runQueueCommandLegacyWithHttpInfo(name, queueCommandDto,); + Future runQueueCommandLegacy(QueueName name, QueueCommandDto queueCommandDto, { Future? abortTrigger, }) async { + final response = await runQueueCommandLegacyWithHttpInfo(name, queueCommandDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } diff --git a/mobile/openapi/lib/api/download_api.dart b/mobile/openapi/lib/api/download_api.dart index 4d0c5c8165..ac26259277 100644 --- a/mobile/openapi/lib/api/download_api.dart +++ b/mobile/openapi/lib/api/download_api.dart @@ -29,7 +29,7 @@ class DownloadApi { /// * [String] key: /// /// * [String] slug: - Future downloadArchiveWithHttpInfo(DownloadArchiveDto downloadArchiveDto, { String? key, String? slug, }) async { + Future downloadArchiveWithHttpInfo(DownloadArchiveDto downloadArchiveDto, { String? key, String? slug, Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/download/archive'; @@ -58,6 +58,7 @@ class DownloadApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -72,8 +73,8 @@ class DownloadApi { /// * [String] key: /// /// * [String] slug: - Future downloadArchive(DownloadArchiveDto downloadArchiveDto, { String? key, String? slug, }) async { - final response = await downloadArchiveWithHttpInfo(downloadArchiveDto, key: key, slug: slug, ); + Future downloadArchive(DownloadArchiveDto downloadArchiveDto, { String? key, String? slug, Future? abortTrigger, }) async { + final response = await downloadArchiveWithHttpInfo(downloadArchiveDto, key: key, slug: slug, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -100,7 +101,7 @@ class DownloadApi { /// * [String] key: /// /// * [String] slug: - Future getDownloadInfoWithHttpInfo(DownloadInfoDto downloadInfoDto, { String? key, String? slug, }) async { + Future getDownloadInfoWithHttpInfo(DownloadInfoDto downloadInfoDto, { String? key, String? slug, Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/download/info'; @@ -129,6 +130,7 @@ class DownloadApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -143,8 +145,8 @@ class DownloadApi { /// * [String] key: /// /// * [String] slug: - Future getDownloadInfo(DownloadInfoDto downloadInfoDto, { String? key, String? slug, }) async { - final response = await getDownloadInfoWithHttpInfo(downloadInfoDto, key: key, slug: slug, ); + Future getDownloadInfo(DownloadInfoDto downloadInfoDto, { String? key, String? slug, Future? abortTrigger, }) async { + final response = await getDownloadInfoWithHttpInfo(downloadInfoDto, key: key, slug: slug, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } diff --git a/mobile/openapi/lib/api/duplicates_api.dart b/mobile/openapi/lib/api/duplicates_api.dart index 9bd01281b3..357947b889 100644 --- a/mobile/openapi/lib/api/duplicates_api.dart +++ b/mobile/openapi/lib/api/duplicates_api.dart @@ -25,7 +25,7 @@ class DuplicatesApi { /// Parameters: /// /// * [String] id (required): - Future deleteDuplicateWithHttpInfo(String id,) async { + Future deleteDuplicateWithHttpInfo(String id, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/duplicates/{id}' .replaceAll('{id}', id); @@ -48,6 +48,7 @@ class DuplicatesApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -58,8 +59,8 @@ class DuplicatesApi { /// Parameters: /// /// * [String] id (required): - Future deleteDuplicate(String id,) async { - final response = await deleteDuplicateWithHttpInfo(id,); + Future deleteDuplicate(String id, { Future? abortTrigger, }) async { + final response = await deleteDuplicateWithHttpInfo(id, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -74,7 +75,7 @@ class DuplicatesApi { /// Parameters: /// /// * [BulkIdsDto] bulkIdsDto (required): - Future deleteDuplicatesWithHttpInfo(BulkIdsDto bulkIdsDto,) async { + Future deleteDuplicatesWithHttpInfo(BulkIdsDto bulkIdsDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/duplicates'; @@ -96,6 +97,7 @@ class DuplicatesApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -106,8 +108,8 @@ class DuplicatesApi { /// Parameters: /// /// * [BulkIdsDto] bulkIdsDto (required): - Future deleteDuplicates(BulkIdsDto bulkIdsDto,) async { - final response = await deleteDuplicatesWithHttpInfo(bulkIdsDto,); + Future deleteDuplicates(BulkIdsDto bulkIdsDto, { Future? abortTrigger, }) async { + final response = await deleteDuplicatesWithHttpInfo(bulkIdsDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -118,7 +120,7 @@ class DuplicatesApi { /// Retrieve a list of duplicate assets available to the authenticated user. /// /// Note: This method returns the HTTP [Response]. - Future getAssetDuplicatesWithHttpInfo() async { + Future getAssetDuplicatesWithHttpInfo({ Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/duplicates'; @@ -140,14 +142,15 @@ class DuplicatesApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } /// Retrieve duplicates /// /// Retrieve a list of duplicate assets available to the authenticated user. - Future?> getAssetDuplicates() async { - final response = await getAssetDuplicatesWithHttpInfo(); + Future?> getAssetDuplicates({ Future? abortTrigger, }) async { + final response = await getAssetDuplicatesWithHttpInfo(abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -173,7 +176,7 @@ class DuplicatesApi { /// Parameters: /// /// * [DuplicateResolveDto] duplicateResolveDto (required): - Future resolveDuplicatesWithHttpInfo(DuplicateResolveDto duplicateResolveDto,) async { + Future resolveDuplicatesWithHttpInfo(DuplicateResolveDto duplicateResolveDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/duplicates/resolve'; @@ -195,6 +198,7 @@ class DuplicatesApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -205,8 +209,8 @@ class DuplicatesApi { /// Parameters: /// /// * [DuplicateResolveDto] duplicateResolveDto (required): - Future?> resolveDuplicates(DuplicateResolveDto duplicateResolveDto,) async { - final response = await resolveDuplicatesWithHttpInfo(duplicateResolveDto,); + Future?> resolveDuplicates(DuplicateResolveDto duplicateResolveDto, { Future? abortTrigger, }) async { + final response = await resolveDuplicatesWithHttpInfo(duplicateResolveDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } diff --git a/mobile/openapi/lib/api/faces_api.dart b/mobile/openapi/lib/api/faces_api.dart index 43d63b47b9..2a71bbbaca 100644 --- a/mobile/openapi/lib/api/faces_api.dart +++ b/mobile/openapi/lib/api/faces_api.dart @@ -25,7 +25,7 @@ class FacesApi { /// Parameters: /// /// * [AssetFaceCreateDto] assetFaceCreateDto (required): - Future createFaceWithHttpInfo(AssetFaceCreateDto assetFaceCreateDto,) async { + Future createFaceWithHttpInfo(AssetFaceCreateDto assetFaceCreateDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/faces'; @@ -47,6 +47,7 @@ class FacesApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -57,8 +58,8 @@ class FacesApi { /// Parameters: /// /// * [AssetFaceCreateDto] assetFaceCreateDto (required): - Future createFace(AssetFaceCreateDto assetFaceCreateDto,) async { - final response = await createFaceWithHttpInfo(assetFaceCreateDto,); + Future createFace(AssetFaceCreateDto assetFaceCreateDto, { Future? abortTrigger, }) async { + final response = await createFaceWithHttpInfo(assetFaceCreateDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -75,7 +76,7 @@ class FacesApi { /// * [String] id (required): /// /// * [AssetFaceDeleteDto] assetFaceDeleteDto (required): - Future deleteFaceWithHttpInfo(String id, AssetFaceDeleteDto assetFaceDeleteDto,) async { + Future deleteFaceWithHttpInfo(String id, AssetFaceDeleteDto assetFaceDeleteDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/faces/{id}' .replaceAll('{id}', id); @@ -98,6 +99,7 @@ class FacesApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -110,8 +112,8 @@ class FacesApi { /// * [String] id (required): /// /// * [AssetFaceDeleteDto] assetFaceDeleteDto (required): - Future deleteFace(String id, AssetFaceDeleteDto assetFaceDeleteDto,) async { - final response = await deleteFaceWithHttpInfo(id, assetFaceDeleteDto,); + Future deleteFace(String id, AssetFaceDeleteDto assetFaceDeleteDto, { Future? abortTrigger, }) async { + final response = await deleteFaceWithHttpInfo(id, assetFaceDeleteDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -127,7 +129,7 @@ class FacesApi { /// /// * [String] id (required): /// Face ID - Future getFacesWithHttpInfo(String id,) async { + Future getFacesWithHttpInfo(String id, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/faces'; @@ -151,6 +153,7 @@ class FacesApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -162,8 +165,8 @@ class FacesApi { /// /// * [String] id (required): /// Face ID - Future?> getFaces(String id,) async { - final response = await getFacesWithHttpInfo(id,); + Future?> getFaces(String id, { Future? abortTrigger, }) async { + final response = await getFacesWithHttpInfo(id, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -191,7 +194,7 @@ class FacesApi { /// * [String] id (required): /// /// * [FaceDto] faceDto (required): - Future reassignFacesByIdWithHttpInfo(String id, FaceDto faceDto,) async { + Future reassignFacesByIdWithHttpInfo(String id, FaceDto faceDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/faces/{id}' .replaceAll('{id}', id); @@ -214,6 +217,7 @@ class FacesApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -226,8 +230,8 @@ class FacesApi { /// * [String] id (required): /// /// * [FaceDto] faceDto (required): - Future reassignFacesById(String id, FaceDto faceDto,) async { - final response = await reassignFacesByIdWithHttpInfo(id, faceDto,); + Future reassignFacesById(String id, FaceDto faceDto, { Future? abortTrigger, }) async { + final response = await reassignFacesByIdWithHttpInfo(id, faceDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } diff --git a/mobile/openapi/lib/api/jobs_api.dart b/mobile/openapi/lib/api/jobs_api.dart index 9dda59a883..287432ad9a 100644 --- a/mobile/openapi/lib/api/jobs_api.dart +++ b/mobile/openapi/lib/api/jobs_api.dart @@ -25,7 +25,7 @@ class JobsApi { /// Parameters: /// /// * [JobCreateDto] jobCreateDto (required): - Future createJobWithHttpInfo(JobCreateDto jobCreateDto,) async { + Future createJobWithHttpInfo(JobCreateDto jobCreateDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/jobs'; @@ -47,6 +47,7 @@ class JobsApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -57,8 +58,8 @@ class JobsApi { /// Parameters: /// /// * [JobCreateDto] jobCreateDto (required): - Future createJob(JobCreateDto jobCreateDto,) async { - final response = await createJobWithHttpInfo(jobCreateDto,); + Future createJob(JobCreateDto jobCreateDto, { Future? abortTrigger, }) async { + final response = await createJobWithHttpInfo(jobCreateDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -69,7 +70,7 @@ class JobsApi { /// Retrieve the counts of the current queue, as well as the current status. /// /// Note: This method returns the HTTP [Response]. - Future getQueuesLegacyWithHttpInfo() async { + Future getQueuesLegacyWithHttpInfo({ Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/jobs'; @@ -91,14 +92,15 @@ class JobsApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } /// Retrieve queue counts and status /// /// Retrieve the counts of the current queue, as well as the current status. - Future getQueuesLegacy() async { - final response = await getQueuesLegacyWithHttpInfo(); + Future getQueuesLegacy({ Future? abortTrigger, }) async { + final response = await getQueuesLegacyWithHttpInfo(abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -123,7 +125,7 @@ class JobsApi { /// * [QueueName] name (required): /// /// * [QueueCommandDto] queueCommandDto (required): - Future runQueueCommandLegacyWithHttpInfo(QueueName name, QueueCommandDto queueCommandDto,) async { + Future runQueueCommandLegacyWithHttpInfo(QueueName name, QueueCommandDto queueCommandDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/jobs/{name}' .replaceAll('{name}', name.toString()); @@ -146,6 +148,7 @@ class JobsApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -158,8 +161,8 @@ class JobsApi { /// * [QueueName] name (required): /// /// * [QueueCommandDto] queueCommandDto (required): - Future runQueueCommandLegacy(QueueName name, QueueCommandDto queueCommandDto,) async { - final response = await runQueueCommandLegacyWithHttpInfo(name, queueCommandDto,); + Future runQueueCommandLegacy(QueueName name, QueueCommandDto queueCommandDto, { Future? abortTrigger, }) async { + final response = await runQueueCommandLegacyWithHttpInfo(name, queueCommandDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } diff --git a/mobile/openapi/lib/api/libraries_api.dart b/mobile/openapi/lib/api/libraries_api.dart index ca59f823fe..a3b3086994 100644 --- a/mobile/openapi/lib/api/libraries_api.dart +++ b/mobile/openapi/lib/api/libraries_api.dart @@ -25,7 +25,7 @@ class LibrariesApi { /// Parameters: /// /// * [CreateLibraryDto] createLibraryDto (required): - Future createLibraryWithHttpInfo(CreateLibraryDto createLibraryDto,) async { + Future createLibraryWithHttpInfo(CreateLibraryDto createLibraryDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/libraries'; @@ -47,6 +47,7 @@ class LibrariesApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -57,8 +58,8 @@ class LibrariesApi { /// Parameters: /// /// * [CreateLibraryDto] createLibraryDto (required): - Future createLibrary(CreateLibraryDto createLibraryDto,) async { - final response = await createLibraryWithHttpInfo(createLibraryDto,); + Future createLibrary(CreateLibraryDto createLibraryDto, { Future? abortTrigger, }) async { + final response = await createLibraryWithHttpInfo(createLibraryDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -81,7 +82,7 @@ class LibrariesApi { /// Parameters: /// /// * [String] id (required): - Future deleteLibraryWithHttpInfo(String id,) async { + Future deleteLibraryWithHttpInfo(String id, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/libraries/{id}' .replaceAll('{id}', id); @@ -104,6 +105,7 @@ class LibrariesApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -114,8 +116,8 @@ class LibrariesApi { /// Parameters: /// /// * [String] id (required): - Future deleteLibrary(String id,) async { - final response = await deleteLibraryWithHttpInfo(id,); + Future deleteLibrary(String id, { Future? abortTrigger, }) async { + final response = await deleteLibraryWithHttpInfo(id, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -126,7 +128,7 @@ class LibrariesApi { /// Retrieve a list of external libraries. /// /// Note: This method returns the HTTP [Response]. - Future getAllLibrariesWithHttpInfo() async { + Future getAllLibrariesWithHttpInfo({ Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/libraries'; @@ -148,14 +150,15 @@ class LibrariesApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } /// Retrieve libraries /// /// Retrieve a list of external libraries. - Future?> getAllLibraries() async { - final response = await getAllLibrariesWithHttpInfo(); + Future?> getAllLibraries({ Future? abortTrigger, }) async { + final response = await getAllLibrariesWithHttpInfo(abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -181,7 +184,7 @@ class LibrariesApi { /// Parameters: /// /// * [String] id (required): - Future getLibraryWithHttpInfo(String id,) async { + Future getLibraryWithHttpInfo(String id, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/libraries/{id}' .replaceAll('{id}', id); @@ -204,6 +207,7 @@ class LibrariesApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -214,8 +218,8 @@ class LibrariesApi { /// Parameters: /// /// * [String] id (required): - Future getLibrary(String id,) async { - final response = await getLibraryWithHttpInfo(id,); + Future getLibrary(String id, { Future? abortTrigger, }) async { + final response = await getLibraryWithHttpInfo(id, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -238,7 +242,7 @@ class LibrariesApi { /// Parameters: /// /// * [String] id (required): - Future getLibraryStatisticsWithHttpInfo(String id,) async { + Future getLibraryStatisticsWithHttpInfo(String id, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/libraries/{id}/statistics' .replaceAll('{id}', id); @@ -261,6 +265,7 @@ class LibrariesApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -271,8 +276,8 @@ class LibrariesApi { /// Parameters: /// /// * [String] id (required): - Future getLibraryStatistics(String id,) async { - final response = await getLibraryStatisticsWithHttpInfo(id,); + Future getLibraryStatistics(String id, { Future? abortTrigger, }) async { + final response = await getLibraryStatisticsWithHttpInfo(id, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -295,7 +300,7 @@ class LibrariesApi { /// Parameters: /// /// * [String] id (required): - Future scanLibraryWithHttpInfo(String id,) async { + Future scanLibraryWithHttpInfo(String id, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/libraries/{id}/scan' .replaceAll('{id}', id); @@ -318,6 +323,7 @@ class LibrariesApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -328,8 +334,8 @@ class LibrariesApi { /// Parameters: /// /// * [String] id (required): - Future scanLibrary(String id,) async { - final response = await scanLibraryWithHttpInfo(id,); + Future scanLibrary(String id, { Future? abortTrigger, }) async { + final response = await scanLibraryWithHttpInfo(id, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -346,7 +352,7 @@ class LibrariesApi { /// * [String] id (required): /// /// * [UpdateLibraryDto] updateLibraryDto (required): - Future updateLibraryWithHttpInfo(String id, UpdateLibraryDto updateLibraryDto,) async { + Future updateLibraryWithHttpInfo(String id, UpdateLibraryDto updateLibraryDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/libraries/{id}' .replaceAll('{id}', id); @@ -369,6 +375,7 @@ class LibrariesApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -381,8 +388,8 @@ class LibrariesApi { /// * [String] id (required): /// /// * [UpdateLibraryDto] updateLibraryDto (required): - Future updateLibrary(String id, UpdateLibraryDto updateLibraryDto,) async { - final response = await updateLibraryWithHttpInfo(id, updateLibraryDto,); + Future updateLibrary(String id, UpdateLibraryDto updateLibraryDto, { Future? abortTrigger, }) async { + final response = await updateLibraryWithHttpInfo(id, updateLibraryDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -407,7 +414,7 @@ class LibrariesApi { /// * [String] id (required): /// /// * [ValidateLibraryDto] validateLibraryDto (required): - Future validateWithHttpInfo(String id, ValidateLibraryDto validateLibraryDto,) async { + Future validateWithHttpInfo(String id, ValidateLibraryDto validateLibraryDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/libraries/{id}/validate' .replaceAll('{id}', id); @@ -430,6 +437,7 @@ class LibrariesApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -442,8 +450,8 @@ class LibrariesApi { /// * [String] id (required): /// /// * [ValidateLibraryDto] validateLibraryDto (required): - Future validate(String id, ValidateLibraryDto validateLibraryDto,) async { - final response = await validateWithHttpInfo(id, validateLibraryDto,); + Future validate(String id, ValidateLibraryDto validateLibraryDto, { Future? abortTrigger, }) async { + final response = await validateWithHttpInfo(id, validateLibraryDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } diff --git a/mobile/openapi/lib/api/maintenance_admin_api.dart b/mobile/openapi/lib/api/maintenance_admin_api.dart index 0f953f1634..8bab193ddf 100644 --- a/mobile/openapi/lib/api/maintenance_admin_api.dart +++ b/mobile/openapi/lib/api/maintenance_admin_api.dart @@ -21,7 +21,7 @@ class MaintenanceAdminApi { /// Collect integrity checks and other heuristics about local data. /// /// Note: This method returns the HTTP [Response]. - Future detectPriorInstallWithHttpInfo() async { + Future detectPriorInstallWithHttpInfo({ Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/admin/maintenance/detect-install'; @@ -43,14 +43,15 @@ class MaintenanceAdminApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } /// Detect existing install /// /// Collect integrity checks and other heuristics about local data. - Future detectPriorInstall() async { - final response = await detectPriorInstallWithHttpInfo(); + Future detectPriorInstall({ Future? abortTrigger, }) async { + final response = await detectPriorInstallWithHttpInfo(abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -69,7 +70,7 @@ class MaintenanceAdminApi { /// Fetch information about the currently running maintenance action. /// /// Note: This method returns the HTTP [Response]. - Future getMaintenanceStatusWithHttpInfo() async { + Future getMaintenanceStatusWithHttpInfo({ Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/admin/maintenance/status'; @@ -91,14 +92,15 @@ class MaintenanceAdminApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } /// Get maintenance mode status /// /// Fetch information about the currently running maintenance action. - Future getMaintenanceStatus() async { - final response = await getMaintenanceStatusWithHttpInfo(); + Future getMaintenanceStatus({ Future? abortTrigger, }) async { + final response = await getMaintenanceStatusWithHttpInfo(abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -121,7 +123,7 @@ class MaintenanceAdminApi { /// Parameters: /// /// * [MaintenanceLoginDto] maintenanceLoginDto (required): - Future maintenanceLoginWithHttpInfo(MaintenanceLoginDto maintenanceLoginDto,) async { + Future maintenanceLoginWithHttpInfo(MaintenanceLoginDto maintenanceLoginDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/admin/maintenance/login'; @@ -143,6 +145,7 @@ class MaintenanceAdminApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -153,8 +156,8 @@ class MaintenanceAdminApi { /// Parameters: /// /// * [MaintenanceLoginDto] maintenanceLoginDto (required): - Future maintenanceLogin(MaintenanceLoginDto maintenanceLoginDto,) async { - final response = await maintenanceLoginWithHttpInfo(maintenanceLoginDto,); + Future maintenanceLogin(MaintenanceLoginDto maintenanceLoginDto, { Future? abortTrigger, }) async { + final response = await maintenanceLoginWithHttpInfo(maintenanceLoginDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -177,7 +180,7 @@ class MaintenanceAdminApi { /// Parameters: /// /// * [SetMaintenanceModeDto] setMaintenanceModeDto (required): - Future setMaintenanceModeWithHttpInfo(SetMaintenanceModeDto setMaintenanceModeDto,) async { + Future setMaintenanceModeWithHttpInfo(SetMaintenanceModeDto setMaintenanceModeDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/admin/maintenance'; @@ -199,6 +202,7 @@ class MaintenanceAdminApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -209,8 +213,8 @@ class MaintenanceAdminApi { /// Parameters: /// /// * [SetMaintenanceModeDto] setMaintenanceModeDto (required): - Future setMaintenanceMode(SetMaintenanceModeDto setMaintenanceModeDto,) async { - final response = await setMaintenanceModeWithHttpInfo(setMaintenanceModeDto,); + Future setMaintenanceMode(SetMaintenanceModeDto setMaintenanceModeDto, { Future? abortTrigger, }) async { + final response = await setMaintenanceModeWithHttpInfo(setMaintenanceModeDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } diff --git a/mobile/openapi/lib/api/map_api.dart b/mobile/openapi/lib/api/map_api.dart index 4ce62bd96c..7e1618a875 100644 --- a/mobile/openapi/lib/api/map_api.dart +++ b/mobile/openapi/lib/api/map_api.dart @@ -41,7 +41,7 @@ class MapApi { /// /// * [bool] withSharedAlbums: /// Include shared album assets - Future getMapMarkersWithHttpInfo({ DateTime? fileCreatedAfter, DateTime? fileCreatedBefore, bool? isArchived, bool? isFavorite, bool? withPartners, bool? withSharedAlbums, }) async { + Future getMapMarkersWithHttpInfo({ DateTime? fileCreatedAfter, DateTime? fileCreatedBefore, bool? isArchived, bool? isFavorite, bool? withPartners, bool? withSharedAlbums, Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/map/markers'; @@ -82,6 +82,7 @@ class MapApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -108,8 +109,8 @@ class MapApi { /// /// * [bool] withSharedAlbums: /// Include shared album assets - Future?> getMapMarkers({ DateTime? fileCreatedAfter, DateTime? fileCreatedBefore, bool? isArchived, bool? isFavorite, bool? withPartners, bool? withSharedAlbums, }) async { - final response = await getMapMarkersWithHttpInfo( fileCreatedAfter: fileCreatedAfter, fileCreatedBefore: fileCreatedBefore, isArchived: isArchived, isFavorite: isFavorite, withPartners: withPartners, withSharedAlbums: withSharedAlbums, ); + Future?> getMapMarkers({ DateTime? fileCreatedAfter, DateTime? fileCreatedBefore, bool? isArchived, bool? isFavorite, bool? withPartners, bool? withSharedAlbums, Future? abortTrigger, }) async { + final response = await getMapMarkersWithHttpInfo(fileCreatedAfter: fileCreatedAfter, fileCreatedBefore: fileCreatedBefore, isArchived: isArchived, isFavorite: isFavorite, withPartners: withPartners, withSharedAlbums: withSharedAlbums, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -139,7 +140,7 @@ class MapApi { /// /// * [double] lon (required): /// Longitude (-180 to 180) - Future reverseGeocodeWithHttpInfo(double lat, double lon,) async { + Future reverseGeocodeWithHttpInfo(double lat, double lon, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/map/reverse-geocode'; @@ -164,6 +165,7 @@ class MapApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -178,8 +180,8 @@ class MapApi { /// /// * [double] lon (required): /// Longitude (-180 to 180) - Future?> reverseGeocode(double lat, double lon,) async { - final response = await reverseGeocodeWithHttpInfo(lat, lon,); + Future?> reverseGeocode(double lat, double lon, { Future? abortTrigger, }) async { + final response = await reverseGeocodeWithHttpInfo(lat, lon, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } diff --git a/mobile/openapi/lib/api/memories_api.dart b/mobile/openapi/lib/api/memories_api.dart index 0cd96ac442..f5c653765a 100644 --- a/mobile/openapi/lib/api/memories_api.dart +++ b/mobile/openapi/lib/api/memories_api.dart @@ -27,7 +27,7 @@ class MemoriesApi { /// * [String] id (required): /// /// * [BulkIdsDto] bulkIdsDto (required): - Future addMemoryAssetsWithHttpInfo(String id, BulkIdsDto bulkIdsDto,) async { + Future addMemoryAssetsWithHttpInfo(String id, BulkIdsDto bulkIdsDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/memories/{id}/assets' .replaceAll('{id}', id); @@ -50,6 +50,7 @@ class MemoriesApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -62,8 +63,8 @@ class MemoriesApi { /// * [String] id (required): /// /// * [BulkIdsDto] bulkIdsDto (required): - Future?> addMemoryAssets(String id, BulkIdsDto bulkIdsDto,) async { - final response = await addMemoryAssetsWithHttpInfo(id, bulkIdsDto,); + Future?> addMemoryAssets(String id, BulkIdsDto bulkIdsDto, { Future? abortTrigger, }) async { + final response = await addMemoryAssetsWithHttpInfo(id, bulkIdsDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -89,7 +90,7 @@ class MemoriesApi { /// Parameters: /// /// * [MemoryCreateDto] memoryCreateDto (required): - Future createMemoryWithHttpInfo(MemoryCreateDto memoryCreateDto,) async { + Future createMemoryWithHttpInfo(MemoryCreateDto memoryCreateDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/memories'; @@ -111,6 +112,7 @@ class MemoriesApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -121,8 +123,8 @@ class MemoriesApi { /// Parameters: /// /// * [MemoryCreateDto] memoryCreateDto (required): - Future createMemory(MemoryCreateDto memoryCreateDto,) async { - final response = await createMemoryWithHttpInfo(memoryCreateDto,); + Future createMemory(MemoryCreateDto memoryCreateDto, { Future? abortTrigger, }) async { + final response = await createMemoryWithHttpInfo(memoryCreateDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -145,7 +147,7 @@ class MemoriesApi { /// Parameters: /// /// * [String] id (required): - Future deleteMemoryWithHttpInfo(String id,) async { + Future deleteMemoryWithHttpInfo(String id, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/memories/{id}' .replaceAll('{id}', id); @@ -168,6 +170,7 @@ class MemoriesApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -178,8 +181,8 @@ class MemoriesApi { /// Parameters: /// /// * [String] id (required): - Future deleteMemory(String id,) async { - final response = await deleteMemoryWithHttpInfo(id,); + Future deleteMemory(String id, { Future? abortTrigger, }) async { + final response = await deleteMemoryWithHttpInfo(id, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -194,7 +197,7 @@ class MemoriesApi { /// Parameters: /// /// * [String] id (required): - Future getMemoryWithHttpInfo(String id,) async { + Future getMemoryWithHttpInfo(String id, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/memories/{id}' .replaceAll('{id}', id); @@ -217,6 +220,7 @@ class MemoriesApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -227,8 +231,8 @@ class MemoriesApi { /// Parameters: /// /// * [String] id (required): - Future getMemory(String id,) async { - final response = await getMemoryWithHttpInfo(id,); + Future getMemory(String id, { Future? abortTrigger, }) async { + final response = await getMemoryWithHttpInfo(id, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -265,7 +269,7 @@ class MemoriesApi { /// Number of memories to return /// /// * [MemoryType] type: - Future memoriesStatisticsWithHttpInfo({ DateTime? for_, bool? isSaved, bool? isTrashed, MemorySearchOrder? order, int? size, MemoryType? type, }) async { + Future memoriesStatisticsWithHttpInfo({ DateTime? for_, bool? isSaved, bool? isTrashed, MemorySearchOrder? order, int? size, MemoryType? type, Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/memories/statistics'; @@ -306,6 +310,7 @@ class MemoriesApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -330,8 +335,8 @@ class MemoriesApi { /// Number of memories to return /// /// * [MemoryType] type: - Future memoriesStatistics({ DateTime? for_, bool? isSaved, bool? isTrashed, MemorySearchOrder? order, int? size, MemoryType? type, }) async { - final response = await memoriesStatisticsWithHttpInfo( for_: for_, isSaved: isSaved, isTrashed: isTrashed, order: order, size: size, type: type, ); + Future memoriesStatistics({ DateTime? for_, bool? isSaved, bool? isTrashed, MemorySearchOrder? order, int? size, MemoryType? type, Future? abortTrigger, }) async { + final response = await memoriesStatisticsWithHttpInfo(for_: for_, isSaved: isSaved, isTrashed: isTrashed, order: order, size: size, type: type, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -356,7 +361,7 @@ class MemoriesApi { /// * [String] id (required): /// /// * [BulkIdsDto] bulkIdsDto (required): - Future removeMemoryAssetsWithHttpInfo(String id, BulkIdsDto bulkIdsDto,) async { + Future removeMemoryAssetsWithHttpInfo(String id, BulkIdsDto bulkIdsDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/memories/{id}/assets' .replaceAll('{id}', id); @@ -379,6 +384,7 @@ class MemoriesApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -391,8 +397,8 @@ class MemoriesApi { /// * [String] id (required): /// /// * [BulkIdsDto] bulkIdsDto (required): - Future?> removeMemoryAssets(String id, BulkIdsDto bulkIdsDto,) async { - final response = await removeMemoryAssetsWithHttpInfo(id, bulkIdsDto,); + Future?> removeMemoryAssets(String id, BulkIdsDto bulkIdsDto, { Future? abortTrigger, }) async { + final response = await removeMemoryAssetsWithHttpInfo(id, bulkIdsDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -432,7 +438,7 @@ class MemoriesApi { /// Number of memories to return /// /// * [MemoryType] type: - Future searchMemoriesWithHttpInfo({ DateTime? for_, bool? isSaved, bool? isTrashed, MemorySearchOrder? order, int? size, MemoryType? type, }) async { + Future searchMemoriesWithHttpInfo({ DateTime? for_, bool? isSaved, bool? isTrashed, MemorySearchOrder? order, int? size, MemoryType? type, Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/memories'; @@ -473,6 +479,7 @@ class MemoriesApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -497,8 +504,8 @@ class MemoriesApi { /// Number of memories to return /// /// * [MemoryType] type: - Future?> searchMemories({ DateTime? for_, bool? isSaved, bool? isTrashed, MemorySearchOrder? order, int? size, MemoryType? type, }) async { - final response = await searchMemoriesWithHttpInfo( for_: for_, isSaved: isSaved, isTrashed: isTrashed, order: order, size: size, type: type, ); + Future?> searchMemories({ DateTime? for_, bool? isSaved, bool? isTrashed, MemorySearchOrder? order, int? size, MemoryType? type, Future? abortTrigger, }) async { + final response = await searchMemoriesWithHttpInfo(for_: for_, isSaved: isSaved, isTrashed: isTrashed, order: order, size: size, type: type, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -526,7 +533,7 @@ class MemoriesApi { /// * [String] id (required): /// /// * [MemoryUpdateDto] memoryUpdateDto (required): - Future updateMemoryWithHttpInfo(String id, MemoryUpdateDto memoryUpdateDto,) async { + Future updateMemoryWithHttpInfo(String id, MemoryUpdateDto memoryUpdateDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/memories/{id}' .replaceAll('{id}', id); @@ -549,6 +556,7 @@ class MemoriesApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -561,8 +569,8 @@ class MemoriesApi { /// * [String] id (required): /// /// * [MemoryUpdateDto] memoryUpdateDto (required): - Future updateMemory(String id, MemoryUpdateDto memoryUpdateDto,) async { - final response = await updateMemoryWithHttpInfo(id, memoryUpdateDto,); + Future updateMemory(String id, MemoryUpdateDto memoryUpdateDto, { Future? abortTrigger, }) async { + final response = await updateMemoryWithHttpInfo(id, memoryUpdateDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } diff --git a/mobile/openapi/lib/api/notifications_admin_api.dart b/mobile/openapi/lib/api/notifications_admin_api.dart index 7821553d30..e9e18e791e 100644 --- a/mobile/openapi/lib/api/notifications_admin_api.dart +++ b/mobile/openapi/lib/api/notifications_admin_api.dart @@ -25,7 +25,7 @@ class NotificationsAdminApi { /// Parameters: /// /// * [NotificationCreateDto] notificationCreateDto (required): - Future createNotificationWithHttpInfo(NotificationCreateDto notificationCreateDto,) async { + Future createNotificationWithHttpInfo(NotificationCreateDto notificationCreateDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/admin/notifications'; @@ -47,6 +47,7 @@ class NotificationsAdminApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -57,8 +58,8 @@ class NotificationsAdminApi { /// Parameters: /// /// * [NotificationCreateDto] notificationCreateDto (required): - Future createNotification(NotificationCreateDto notificationCreateDto,) async { - final response = await createNotificationWithHttpInfo(notificationCreateDto,); + Future createNotification(NotificationCreateDto notificationCreateDto, { Future? abortTrigger, }) async { + final response = await createNotificationWithHttpInfo(notificationCreateDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -83,7 +84,7 @@ class NotificationsAdminApi { /// * [String] name (required): /// /// * [TemplateDto] templateDto (required): - Future getNotificationTemplateAdminWithHttpInfo(String name, TemplateDto templateDto,) async { + Future getNotificationTemplateAdminWithHttpInfo(String name, TemplateDto templateDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/admin/notifications/templates/{name}' .replaceAll('{name}', name); @@ -106,6 +107,7 @@ class NotificationsAdminApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -118,8 +120,8 @@ class NotificationsAdminApi { /// * [String] name (required): /// /// * [TemplateDto] templateDto (required): - Future getNotificationTemplateAdmin(String name, TemplateDto templateDto,) async { - final response = await getNotificationTemplateAdminWithHttpInfo(name, templateDto,); + Future getNotificationTemplateAdmin(String name, TemplateDto templateDto, { Future? abortTrigger, }) async { + final response = await getNotificationTemplateAdminWithHttpInfo(name, templateDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -142,7 +144,7 @@ class NotificationsAdminApi { /// Parameters: /// /// * [SystemConfigSmtpDto] systemConfigSmtpDto (required): - Future sendTestEmailAdminWithHttpInfo(SystemConfigSmtpDto systemConfigSmtpDto,) async { + Future sendTestEmailAdminWithHttpInfo(SystemConfigSmtpDto systemConfigSmtpDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/admin/notifications/test-email'; @@ -164,6 +166,7 @@ class NotificationsAdminApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -174,8 +177,8 @@ class NotificationsAdminApi { /// Parameters: /// /// * [SystemConfigSmtpDto] systemConfigSmtpDto (required): - Future sendTestEmailAdmin(SystemConfigSmtpDto systemConfigSmtpDto,) async { - final response = await sendTestEmailAdminWithHttpInfo(systemConfigSmtpDto,); + Future sendTestEmailAdmin(SystemConfigSmtpDto systemConfigSmtpDto, { Future? abortTrigger, }) async { + final response = await sendTestEmailAdminWithHttpInfo(systemConfigSmtpDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } diff --git a/mobile/openapi/lib/api/notifications_api.dart b/mobile/openapi/lib/api/notifications_api.dart index ab0be3e8f3..6b4f213bcd 100644 --- a/mobile/openapi/lib/api/notifications_api.dart +++ b/mobile/openapi/lib/api/notifications_api.dart @@ -25,7 +25,7 @@ class NotificationsApi { /// Parameters: /// /// * [String] id (required): - Future deleteNotificationWithHttpInfo(String id,) async { + Future deleteNotificationWithHttpInfo(String id, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/notifications/{id}' .replaceAll('{id}', id); @@ -48,6 +48,7 @@ class NotificationsApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -58,8 +59,8 @@ class NotificationsApi { /// Parameters: /// /// * [String] id (required): - Future deleteNotification(String id,) async { - final response = await deleteNotificationWithHttpInfo(id,); + Future deleteNotification(String id, { Future? abortTrigger, }) async { + final response = await deleteNotificationWithHttpInfo(id, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -74,7 +75,7 @@ class NotificationsApi { /// Parameters: /// /// * [NotificationDeleteAllDto] notificationDeleteAllDto (required): - Future deleteNotificationsWithHttpInfo(NotificationDeleteAllDto notificationDeleteAllDto,) async { + Future deleteNotificationsWithHttpInfo(NotificationDeleteAllDto notificationDeleteAllDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/notifications'; @@ -96,6 +97,7 @@ class NotificationsApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -106,8 +108,8 @@ class NotificationsApi { /// Parameters: /// /// * [NotificationDeleteAllDto] notificationDeleteAllDto (required): - Future deleteNotifications(NotificationDeleteAllDto notificationDeleteAllDto,) async { - final response = await deleteNotificationsWithHttpInfo(notificationDeleteAllDto,); + Future deleteNotifications(NotificationDeleteAllDto notificationDeleteAllDto, { Future? abortTrigger, }) async { + final response = await deleteNotificationsWithHttpInfo(notificationDeleteAllDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -122,7 +124,7 @@ class NotificationsApi { /// Parameters: /// /// * [String] id (required): - Future getNotificationWithHttpInfo(String id,) async { + Future getNotificationWithHttpInfo(String id, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/notifications/{id}' .replaceAll('{id}', id); @@ -145,6 +147,7 @@ class NotificationsApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -155,8 +158,8 @@ class NotificationsApi { /// Parameters: /// /// * [String] id (required): - Future getNotification(String id,) async { - final response = await getNotificationWithHttpInfo(id,); + Future getNotification(String id, { Future? abortTrigger, }) async { + final response = await getNotificationWithHttpInfo(id, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -187,7 +190,7 @@ class NotificationsApi { /// /// * [bool] unread: /// Filter by unread status - Future getNotificationsWithHttpInfo({ String? id, NotificationLevel? level, NotificationType? type, bool? unread, }) async { + Future getNotificationsWithHttpInfo({ String? id, NotificationLevel? level, NotificationType? type, bool? unread, Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/notifications'; @@ -222,6 +225,7 @@ class NotificationsApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -240,8 +244,8 @@ class NotificationsApi { /// /// * [bool] unread: /// Filter by unread status - Future?> getNotifications({ String? id, NotificationLevel? level, NotificationType? type, bool? unread, }) async { - final response = await getNotificationsWithHttpInfo( id: id, level: level, type: type, unread: unread, ); + Future?> getNotifications({ String? id, NotificationLevel? level, NotificationType? type, bool? unread, Future? abortTrigger, }) async { + final response = await getNotificationsWithHttpInfo(id: id, level: level, type: type, unread: unread, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -269,7 +273,7 @@ class NotificationsApi { /// * [String] id (required): /// /// * [NotificationUpdateDto] notificationUpdateDto (required): - Future updateNotificationWithHttpInfo(String id, NotificationUpdateDto notificationUpdateDto,) async { + Future updateNotificationWithHttpInfo(String id, NotificationUpdateDto notificationUpdateDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/notifications/{id}' .replaceAll('{id}', id); @@ -292,6 +296,7 @@ class NotificationsApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -304,8 +309,8 @@ class NotificationsApi { /// * [String] id (required): /// /// * [NotificationUpdateDto] notificationUpdateDto (required): - Future updateNotification(String id, NotificationUpdateDto notificationUpdateDto,) async { - final response = await updateNotificationWithHttpInfo(id, notificationUpdateDto,); + Future updateNotification(String id, NotificationUpdateDto notificationUpdateDto, { Future? abortTrigger, }) async { + final response = await updateNotificationWithHttpInfo(id, notificationUpdateDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -328,7 +333,7 @@ class NotificationsApi { /// Parameters: /// /// * [NotificationUpdateAllDto] notificationUpdateAllDto (required): - Future updateNotificationsWithHttpInfo(NotificationUpdateAllDto notificationUpdateAllDto,) async { + Future updateNotificationsWithHttpInfo(NotificationUpdateAllDto notificationUpdateAllDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/notifications'; @@ -350,6 +355,7 @@ class NotificationsApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -360,8 +366,8 @@ class NotificationsApi { /// Parameters: /// /// * [NotificationUpdateAllDto] notificationUpdateAllDto (required): - Future updateNotifications(NotificationUpdateAllDto notificationUpdateAllDto,) async { - final response = await updateNotificationsWithHttpInfo(notificationUpdateAllDto,); + Future updateNotifications(NotificationUpdateAllDto notificationUpdateAllDto, { Future? abortTrigger, }) async { + final response = await updateNotificationsWithHttpInfo(notificationUpdateAllDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } diff --git a/mobile/openapi/lib/api/partners_api.dart b/mobile/openapi/lib/api/partners_api.dart index 7d18f6d867..45bcdcd085 100644 --- a/mobile/openapi/lib/api/partners_api.dart +++ b/mobile/openapi/lib/api/partners_api.dart @@ -25,7 +25,7 @@ class PartnersApi { /// Parameters: /// /// * [PartnerCreateDto] partnerCreateDto (required): - Future createPartnerWithHttpInfo(PartnerCreateDto partnerCreateDto,) async { + Future createPartnerWithHttpInfo(PartnerCreateDto partnerCreateDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/partners'; @@ -47,6 +47,7 @@ class PartnersApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -57,8 +58,8 @@ class PartnersApi { /// Parameters: /// /// * [PartnerCreateDto] partnerCreateDto (required): - Future createPartner(PartnerCreateDto partnerCreateDto,) async { - final response = await createPartnerWithHttpInfo(partnerCreateDto,); + Future createPartner(PartnerCreateDto partnerCreateDto, { Future? abortTrigger, }) async { + final response = await createPartnerWithHttpInfo(partnerCreateDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -81,7 +82,7 @@ class PartnersApi { /// Parameters: /// /// * [String] id (required): - Future createPartnerDeprecatedWithHttpInfo(String id,) async { + Future createPartnerDeprecatedWithHttpInfo(String id, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/partners/{id}' .replaceAll('{id}', id); @@ -104,6 +105,7 @@ class PartnersApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -114,8 +116,8 @@ class PartnersApi { /// Parameters: /// /// * [String] id (required): - Future createPartnerDeprecated(String id,) async { - final response = await createPartnerDeprecatedWithHttpInfo(id,); + Future createPartnerDeprecated(String id, { Future? abortTrigger, }) async { + final response = await createPartnerDeprecatedWithHttpInfo(id, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -138,7 +140,7 @@ class PartnersApi { /// Parameters: /// /// * [PartnerDirection] direction (required): - Future getPartnersWithHttpInfo(PartnerDirection direction,) async { + Future getPartnersWithHttpInfo(PartnerDirection direction, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/partners'; @@ -162,6 +164,7 @@ class PartnersApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -172,8 +175,8 @@ class PartnersApi { /// Parameters: /// /// * [PartnerDirection] direction (required): - Future?> getPartners(PartnerDirection direction,) async { - final response = await getPartnersWithHttpInfo(direction,); + Future?> getPartners(PartnerDirection direction, { Future? abortTrigger, }) async { + final response = await getPartnersWithHttpInfo(direction, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -199,7 +202,7 @@ class PartnersApi { /// Parameters: /// /// * [String] id (required): - Future removePartnerWithHttpInfo(String id,) async { + Future removePartnerWithHttpInfo(String id, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/partners/{id}' .replaceAll('{id}', id); @@ -222,6 +225,7 @@ class PartnersApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -232,8 +236,8 @@ class PartnersApi { /// Parameters: /// /// * [String] id (required): - Future removePartner(String id,) async { - final response = await removePartnerWithHttpInfo(id,); + Future removePartner(String id, { Future? abortTrigger, }) async { + final response = await removePartnerWithHttpInfo(id, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -250,7 +254,7 @@ class PartnersApi { /// * [String] id (required): /// /// * [PartnerUpdateDto] partnerUpdateDto (required): - Future updatePartnerWithHttpInfo(String id, PartnerUpdateDto partnerUpdateDto,) async { + Future updatePartnerWithHttpInfo(String id, PartnerUpdateDto partnerUpdateDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/partners/{id}' .replaceAll('{id}', id); @@ -273,6 +277,7 @@ class PartnersApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -285,8 +290,8 @@ class PartnersApi { /// * [String] id (required): /// /// * [PartnerUpdateDto] partnerUpdateDto (required): - Future updatePartner(String id, PartnerUpdateDto partnerUpdateDto,) async { - final response = await updatePartnerWithHttpInfo(id, partnerUpdateDto,); + Future updatePartner(String id, PartnerUpdateDto partnerUpdateDto, { Future? abortTrigger, }) async { + final response = await updatePartnerWithHttpInfo(id, partnerUpdateDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } diff --git a/mobile/openapi/lib/api/people_api.dart b/mobile/openapi/lib/api/people_api.dart index 99821f31aa..c35491e110 100644 --- a/mobile/openapi/lib/api/people_api.dart +++ b/mobile/openapi/lib/api/people_api.dart @@ -25,7 +25,7 @@ class PeopleApi { /// Parameters: /// /// * [PersonCreateDto] personCreateDto (required): - Future createPersonWithHttpInfo(PersonCreateDto personCreateDto,) async { + Future createPersonWithHttpInfo(PersonCreateDto personCreateDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/people'; @@ -47,6 +47,7 @@ class PeopleApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -57,8 +58,8 @@ class PeopleApi { /// Parameters: /// /// * [PersonCreateDto] personCreateDto (required): - Future createPerson(PersonCreateDto personCreateDto,) async { - final response = await createPersonWithHttpInfo(personCreateDto,); + Future createPerson(PersonCreateDto personCreateDto, { Future? abortTrigger, }) async { + final response = await createPersonWithHttpInfo(personCreateDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -81,7 +82,7 @@ class PeopleApi { /// Parameters: /// /// * [BulkIdsDto] bulkIdsDto (required): - Future deletePeopleWithHttpInfo(BulkIdsDto bulkIdsDto,) async { + Future deletePeopleWithHttpInfo(BulkIdsDto bulkIdsDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/people'; @@ -103,6 +104,7 @@ class PeopleApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -113,8 +115,8 @@ class PeopleApi { /// Parameters: /// /// * [BulkIdsDto] bulkIdsDto (required): - Future deletePeople(BulkIdsDto bulkIdsDto,) async { - final response = await deletePeopleWithHttpInfo(bulkIdsDto,); + Future deletePeople(BulkIdsDto bulkIdsDto, { Future? abortTrigger, }) async { + final response = await deletePeopleWithHttpInfo(bulkIdsDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -129,7 +131,7 @@ class PeopleApi { /// Parameters: /// /// * [String] id (required): - Future deletePersonWithHttpInfo(String id,) async { + Future deletePersonWithHttpInfo(String id, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/people/{id}' .replaceAll('{id}', id); @@ -152,6 +154,7 @@ class PeopleApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -162,8 +165,8 @@ class PeopleApi { /// Parameters: /// /// * [String] id (required): - Future deletePerson(String id,) async { - final response = await deletePersonWithHttpInfo(id,); + Future deletePerson(String id, { Future? abortTrigger, }) async { + final response = await deletePersonWithHttpInfo(id, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -191,7 +194,7 @@ class PeopleApi { /// /// * [bool] withHidden: /// Include hidden people - Future getAllPeopleWithHttpInfo({ String? closestAssetId, String? closestPersonId, int? page, int? size, bool? withHidden, }) async { + Future getAllPeopleWithHttpInfo({ String? closestAssetId, String? closestPersonId, int? page, int? size, bool? withHidden, Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/people'; @@ -229,6 +232,7 @@ class PeopleApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -252,8 +256,8 @@ class PeopleApi { /// /// * [bool] withHidden: /// Include hidden people - Future getAllPeople({ String? closestAssetId, String? closestPersonId, int? page, int? size, bool? withHidden, }) async { - final response = await getAllPeopleWithHttpInfo( closestAssetId: closestAssetId, closestPersonId: closestPersonId, page: page, size: size, withHidden: withHidden, ); + Future getAllPeople({ String? closestAssetId, String? closestPersonId, int? page, int? size, bool? withHidden, Future? abortTrigger, }) async { + final response = await getAllPeopleWithHttpInfo(closestAssetId: closestAssetId, closestPersonId: closestPersonId, page: page, size: size, withHidden: withHidden, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -276,7 +280,7 @@ class PeopleApi { /// Parameters: /// /// * [String] id (required): - Future getPersonWithHttpInfo(String id,) async { + Future getPersonWithHttpInfo(String id, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/people/{id}' .replaceAll('{id}', id); @@ -299,6 +303,7 @@ class PeopleApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -309,8 +314,8 @@ class PeopleApi { /// Parameters: /// /// * [String] id (required): - Future getPerson(String id,) async { - final response = await getPersonWithHttpInfo(id,); + Future getPerson(String id, { Future? abortTrigger, }) async { + final response = await getPersonWithHttpInfo(id, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -333,7 +338,7 @@ class PeopleApi { /// Parameters: /// /// * [String] id (required): - Future getPersonStatisticsWithHttpInfo(String id,) async { + Future getPersonStatisticsWithHttpInfo(String id, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/people/{id}/statistics' .replaceAll('{id}', id); @@ -356,6 +361,7 @@ class PeopleApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -366,8 +372,8 @@ class PeopleApi { /// Parameters: /// /// * [String] id (required): - Future getPersonStatistics(String id,) async { - final response = await getPersonStatisticsWithHttpInfo(id,); + Future getPersonStatistics(String id, { Future? abortTrigger, }) async { + final response = await getPersonStatisticsWithHttpInfo(id, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -390,7 +396,7 @@ class PeopleApi { /// Parameters: /// /// * [String] id (required): - Future getPersonThumbnailWithHttpInfo(String id,) async { + Future getPersonThumbnailWithHttpInfo(String id, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/people/{id}/thumbnail' .replaceAll('{id}', id); @@ -413,6 +419,7 @@ class PeopleApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -423,8 +430,8 @@ class PeopleApi { /// Parameters: /// /// * [String] id (required): - Future getPersonThumbnail(String id,) async { - final response = await getPersonThumbnailWithHttpInfo(id,); + Future getPersonThumbnail(String id, { Future? abortTrigger, }) async { + final response = await getPersonThumbnailWithHttpInfo(id, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -449,7 +456,7 @@ class PeopleApi { /// * [String] id (required): /// /// * [MergePersonDto] mergePersonDto (required): - Future mergePersonWithHttpInfo(String id, MergePersonDto mergePersonDto,) async { + Future mergePersonWithHttpInfo(String id, MergePersonDto mergePersonDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/people/{id}/merge' .replaceAll('{id}', id); @@ -472,6 +479,7 @@ class PeopleApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -484,8 +492,8 @@ class PeopleApi { /// * [String] id (required): /// /// * [MergePersonDto] mergePersonDto (required): - Future?> mergePerson(String id, MergePersonDto mergePersonDto,) async { - final response = await mergePersonWithHttpInfo(id, mergePersonDto,); + Future?> mergePerson(String id, MergePersonDto mergePersonDto, { Future? abortTrigger, }) async { + final response = await mergePersonWithHttpInfo(id, mergePersonDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -513,7 +521,7 @@ class PeopleApi { /// * [String] id (required): /// /// * [AssetFaceUpdateDto] assetFaceUpdateDto (required): - Future reassignFacesWithHttpInfo(String id, AssetFaceUpdateDto assetFaceUpdateDto,) async { + Future reassignFacesWithHttpInfo(String id, AssetFaceUpdateDto assetFaceUpdateDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/people/{id}/reassign' .replaceAll('{id}', id); @@ -536,6 +544,7 @@ class PeopleApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -548,8 +557,8 @@ class PeopleApi { /// * [String] id (required): /// /// * [AssetFaceUpdateDto] assetFaceUpdateDto (required): - Future?> reassignFaces(String id, AssetFaceUpdateDto assetFaceUpdateDto,) async { - final response = await reassignFacesWithHttpInfo(id, assetFaceUpdateDto,); + Future?> reassignFaces(String id, AssetFaceUpdateDto assetFaceUpdateDto, { Future? abortTrigger, }) async { + final response = await reassignFacesWithHttpInfo(id, assetFaceUpdateDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -575,7 +584,7 @@ class PeopleApi { /// Parameters: /// /// * [PeopleUpdateDto] peopleUpdateDto (required): - Future updatePeopleWithHttpInfo(PeopleUpdateDto peopleUpdateDto,) async { + Future updatePeopleWithHttpInfo(PeopleUpdateDto peopleUpdateDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/people'; @@ -597,6 +606,7 @@ class PeopleApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -607,8 +617,8 @@ class PeopleApi { /// Parameters: /// /// * [PeopleUpdateDto] peopleUpdateDto (required): - Future?> updatePeople(PeopleUpdateDto peopleUpdateDto,) async { - final response = await updatePeopleWithHttpInfo(peopleUpdateDto,); + Future?> updatePeople(PeopleUpdateDto peopleUpdateDto, { Future? abortTrigger, }) async { + final response = await updatePeopleWithHttpInfo(peopleUpdateDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -636,7 +646,7 @@ class PeopleApi { /// * [String] id (required): /// /// * [PersonUpdateDto] personUpdateDto (required): - Future updatePersonWithHttpInfo(String id, PersonUpdateDto personUpdateDto,) async { + Future updatePersonWithHttpInfo(String id, PersonUpdateDto personUpdateDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/people/{id}' .replaceAll('{id}', id); @@ -659,6 +669,7 @@ class PeopleApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -671,8 +682,8 @@ class PeopleApi { /// * [String] id (required): /// /// * [PersonUpdateDto] personUpdateDto (required): - Future updatePerson(String id, PersonUpdateDto personUpdateDto,) async { - final response = await updatePersonWithHttpInfo(id, personUpdateDto,); + Future updatePerson(String id, PersonUpdateDto personUpdateDto, { Future? abortTrigger, }) async { + final response = await updatePersonWithHttpInfo(id, personUpdateDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } diff --git a/mobile/openapi/lib/api/plugins_api.dart b/mobile/openapi/lib/api/plugins_api.dart index d2a1d386d9..40892b8a67 100644 --- a/mobile/openapi/lib/api/plugins_api.dart +++ b/mobile/openapi/lib/api/plugins_api.dart @@ -25,7 +25,7 @@ class PluginsApi { /// Parameters: /// /// * [String] id (required): - Future getPluginWithHttpInfo(String id,) async { + Future getPluginWithHttpInfo(String id, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/plugins/{id}' .replaceAll('{id}', id); @@ -48,6 +48,7 @@ class PluginsApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -58,8 +59,8 @@ class PluginsApi { /// Parameters: /// /// * [String] id (required): - Future getPlugin(String id,) async { - final response = await getPluginWithHttpInfo(id,); + Future getPlugin(String id, { Future? abortTrigger, }) async { + final response = await getPluginWithHttpInfo(id, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -104,7 +105,7 @@ class PluginsApi { /// /// * [WorkflowType] type: /// Workflow types - Future searchPluginMethodsWithHttpInfo({ String? description, bool? enabled, String? id, String? name, String? pluginName, String? pluginVersion, String? title, WorkflowTrigger? trigger, WorkflowType? type, }) async { + Future searchPluginMethodsWithHttpInfo({ String? description, bool? enabled, String? id, String? name, String? pluginName, String? pluginVersion, String? title, WorkflowTrigger? trigger, WorkflowType? type, Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/plugins/methods'; @@ -154,6 +155,7 @@ class PluginsApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -186,8 +188,8 @@ class PluginsApi { /// /// * [WorkflowType] type: /// Workflow types - Future?> searchPluginMethods({ String? description, bool? enabled, String? id, String? name, String? pluginName, String? pluginVersion, String? title, WorkflowTrigger? trigger, WorkflowType? type, }) async { - final response = await searchPluginMethodsWithHttpInfo( description: description, enabled: enabled, id: id, name: name, pluginName: pluginName, pluginVersion: pluginVersion, title: title, trigger: trigger, type: type, ); + Future?> searchPluginMethods({ String? description, bool? enabled, String? id, String? name, String? pluginName, String? pluginVersion, String? title, WorkflowTrigger? trigger, WorkflowType? type, Future? abortTrigger, }) async { + final response = await searchPluginMethodsWithHttpInfo(description: description, enabled: enabled, id: id, name: name, pluginName: pluginName, pluginVersion: pluginVersion, title: title, trigger: trigger, type: type, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -204,6 +206,58 @@ class PluginsApi { return null; } + /// Retrieve workflow templates + /// + /// Retrieve workflow templates provided by installed plugins + /// + /// Note: This method returns the HTTP [Response]. + Future searchPluginTemplatesWithHttpInfo({ Future? abortTrigger, }) async { + // ignore: prefer_const_declarations + final apiPath = r'/plugins/templates'; + + // ignore: prefer_final_locals + Object? postBody; + + final queryParams = []; + final headerParams = {}; + final formParams = {}; + + const contentTypes = []; + + + return apiClient.invokeAPI( + apiPath, + 'GET', + queryParams, + postBody, + headerParams, + formParams, + contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, + ); + } + + /// Retrieve workflow templates + /// + /// Retrieve workflow templates provided by installed plugins + Future?> searchPluginTemplates({ Future? abortTrigger, }) async { + final response = await searchPluginTemplatesWithHttpInfo(abortTrigger: abortTrigger,); + if (response.statusCode >= HttpStatus.badRequest) { + throw ApiException(response.statusCode, await _decodeBodyBytes(response)); + } + // When a remote server returns no body with a status of 204, we shall not decode it. + // At the time of writing this, `dart:convert` will throw an "Unexpected end of input" + // FormatException when trying to decode an empty string. + if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) { + final responseBody = await _decodeBodyBytes(response); + return (await apiClient.deserializeAsync(responseBody, 'List') as List) + .cast() + .toList(growable: false); + + } + return null; + } + /// List all plugins /// /// Retrieve a list of plugins available to the authenticated user. @@ -225,7 +279,7 @@ class PluginsApi { /// * [String] title: /// /// * [String] version: - Future searchPluginsWithHttpInfo({ String? description, bool? enabled, String? id, String? name, String? title, String? version, }) async { + Future searchPluginsWithHttpInfo({ String? description, bool? enabled, String? id, String? name, String? title, String? version, Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/plugins'; @@ -266,6 +320,7 @@ class PluginsApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -288,8 +343,8 @@ class PluginsApi { /// * [String] title: /// /// * [String] version: - Future?> searchPlugins({ String? description, bool? enabled, String? id, String? name, String? title, String? version, }) async { - final response = await searchPluginsWithHttpInfo( description: description, enabled: enabled, id: id, name: name, title: title, version: version, ); + Future?> searchPlugins({ String? description, bool? enabled, String? id, String? name, String? title, String? version, Future? abortTrigger, }) async { + final response = await searchPluginsWithHttpInfo(description: description, enabled: enabled, id: id, name: name, title: title, version: version, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } diff --git a/mobile/openapi/lib/api/queues_api.dart b/mobile/openapi/lib/api/queues_api.dart index 1312cb5952..39386c23f9 100644 --- a/mobile/openapi/lib/api/queues_api.dart +++ b/mobile/openapi/lib/api/queues_api.dart @@ -27,7 +27,7 @@ class QueuesApi { /// * [QueueName] name (required): /// /// * [QueueDeleteDto] queueDeleteDto (required): - Future emptyQueueWithHttpInfo(QueueName name, QueueDeleteDto queueDeleteDto,) async { + Future emptyQueueWithHttpInfo(QueueName name, QueueDeleteDto queueDeleteDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/queues/{name}/jobs' .replaceAll('{name}', name.toString()); @@ -50,6 +50,7 @@ class QueuesApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -62,8 +63,8 @@ class QueuesApi { /// * [QueueName] name (required): /// /// * [QueueDeleteDto] queueDeleteDto (required): - Future emptyQueue(QueueName name, QueueDeleteDto queueDeleteDto,) async { - final response = await emptyQueueWithHttpInfo(name, queueDeleteDto,); + Future emptyQueue(QueueName name, QueueDeleteDto queueDeleteDto, { Future? abortTrigger, }) async { + final response = await emptyQueueWithHttpInfo(name, queueDeleteDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -78,7 +79,7 @@ class QueuesApi { /// Parameters: /// /// * [QueueName] name (required): - Future getQueueWithHttpInfo(QueueName name,) async { + Future getQueueWithHttpInfo(QueueName name, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/queues/{name}' .replaceAll('{name}', name.toString()); @@ -101,6 +102,7 @@ class QueuesApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -111,8 +113,8 @@ class QueuesApi { /// Parameters: /// /// * [QueueName] name (required): - Future getQueue(QueueName name,) async { - final response = await getQueueWithHttpInfo(name,); + Future getQueue(QueueName name, { Future? abortTrigger, }) async { + final response = await getQueueWithHttpInfo(name, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -138,7 +140,7 @@ class QueuesApi { /// /// * [List] status: /// Filter jobs by status - Future getQueueJobsWithHttpInfo(QueueName name, { List? status, }) async { + Future getQueueJobsWithHttpInfo(QueueName name, { List? status, Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/queues/{name}/jobs' .replaceAll('{name}', name.toString()); @@ -165,6 +167,7 @@ class QueuesApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -178,8 +181,8 @@ class QueuesApi { /// /// * [List] status: /// Filter jobs by status - Future?> getQueueJobs(QueueName name, { List? status, }) async { - final response = await getQueueJobsWithHttpInfo(name, status: status, ); + Future?> getQueueJobs(QueueName name, { List? status, Future? abortTrigger, }) async { + final response = await getQueueJobsWithHttpInfo(name, status: status, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -201,7 +204,7 @@ class QueuesApi { /// Retrieves a list of queues. /// /// Note: This method returns the HTTP [Response]. - Future getQueuesWithHttpInfo() async { + Future getQueuesWithHttpInfo({ Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/queues'; @@ -223,14 +226,15 @@ class QueuesApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } /// List all queues /// /// Retrieves a list of queues. - Future?> getQueues() async { - final response = await getQueuesWithHttpInfo(); + Future?> getQueues({ Future? abortTrigger, }) async { + final response = await getQueuesWithHttpInfo(abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -258,7 +262,7 @@ class QueuesApi { /// * [QueueName] name (required): /// /// * [QueueUpdateDto] queueUpdateDto (required): - Future updateQueueWithHttpInfo(QueueName name, QueueUpdateDto queueUpdateDto,) async { + Future updateQueueWithHttpInfo(QueueName name, QueueUpdateDto queueUpdateDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/queues/{name}' .replaceAll('{name}', name.toString()); @@ -281,6 +285,7 @@ class QueuesApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -293,8 +298,8 @@ class QueuesApi { /// * [QueueName] name (required): /// /// * [QueueUpdateDto] queueUpdateDto (required): - Future updateQueue(QueueName name, QueueUpdateDto queueUpdateDto,) async { - final response = await updateQueueWithHttpInfo(name, queueUpdateDto,); + Future updateQueue(QueueName name, QueueUpdateDto queueUpdateDto, { Future? abortTrigger, }) async { + final response = await updateQueueWithHttpInfo(name, queueUpdateDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } diff --git a/mobile/openapi/lib/api/search_api.dart b/mobile/openapi/lib/api/search_api.dart index 6f8a4df902..0118cabdba 100644 --- a/mobile/openapi/lib/api/search_api.dart +++ b/mobile/openapi/lib/api/search_api.dart @@ -21,7 +21,7 @@ class SearchApi { /// Retrieve a list of assets with each asset belonging to a different city. This endpoint is used on the places pages to show a single thumbnail for each city the user has assets in. /// /// Note: This method returns the HTTP [Response]. - Future getAssetsByCityWithHttpInfo() async { + Future getAssetsByCityWithHttpInfo({ Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/search/cities'; @@ -43,14 +43,15 @@ class SearchApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } /// Retrieve assets by city /// /// Retrieve a list of assets with each asset belonging to a different city. This endpoint is used on the places pages to show a single thumbnail for each city the user has assets in. - Future?> getAssetsByCity() async { - final response = await getAssetsByCityWithHttpInfo(); + Future?> getAssetsByCity({ Future? abortTrigger, }) async { + final response = await getAssetsByCityWithHttpInfo(abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -72,7 +73,7 @@ class SearchApi { /// Retrieve data for the explore section, such as popular people and places. /// /// Note: This method returns the HTTP [Response]. - Future getExploreDataWithHttpInfo() async { + Future getExploreDataWithHttpInfo({ Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/search/explore'; @@ -94,14 +95,15 @@ class SearchApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } /// Retrieve explore data /// /// Retrieve data for the explore section, such as popular people and places. - Future?> getExploreData() async { - final response = await getExploreDataWithHttpInfo(); + Future?> getExploreData({ Future? abortTrigger, }) async { + final response = await getExploreDataWithHttpInfo(abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -145,7 +147,7 @@ class SearchApi { /// /// * [String] state: /// Filter by state/province - Future getSearchSuggestionsWithHttpInfo(SearchSuggestionType type, { String? country, bool? includeNull, String? lensModel, String? make, String? model, String? state, }) async { + Future getSearchSuggestionsWithHttpInfo(SearchSuggestionType type, { String? country, bool? includeNull, String? lensModel, String? make, String? model, String? state, Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/search/suggestions'; @@ -187,6 +189,7 @@ class SearchApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -215,8 +218,8 @@ class SearchApi { /// /// * [String] state: /// Filter by state/province - Future?> getSearchSuggestions(SearchSuggestionType type, { String? country, bool? includeNull, String? lensModel, String? make, String? model, String? state, }) async { - final response = await getSearchSuggestionsWithHttpInfo(type, country: country, includeNull: includeNull, lensModel: lensModel, make: make, model: model, state: state, ); + Future?> getSearchSuggestions(SearchSuggestionType type, { String? country, bool? includeNull, String? lensModel, String? make, String? model, String? state, Future? abortTrigger, }) async { + final response = await getSearchSuggestionsWithHttpInfo(type, country: country, includeNull: includeNull, lensModel: lensModel, make: make, model: model, state: state, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -242,7 +245,7 @@ class SearchApi { /// Parameters: /// /// * [StatisticsSearchDto] statisticsSearchDto (required): - Future searchAssetStatisticsWithHttpInfo(StatisticsSearchDto statisticsSearchDto,) async { + Future searchAssetStatisticsWithHttpInfo(StatisticsSearchDto statisticsSearchDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/search/statistics'; @@ -264,6 +267,7 @@ class SearchApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -274,8 +278,8 @@ class SearchApi { /// Parameters: /// /// * [StatisticsSearchDto] statisticsSearchDto (required): - Future searchAssetStatistics(StatisticsSearchDto statisticsSearchDto,) async { - final response = await searchAssetStatisticsWithHttpInfo(statisticsSearchDto,); + Future searchAssetStatistics(StatisticsSearchDto statisticsSearchDto, { Future? abortTrigger, }) async { + final response = await searchAssetStatisticsWithHttpInfo(statisticsSearchDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -298,7 +302,7 @@ class SearchApi { /// Parameters: /// /// * [MetadataSearchDto] metadataSearchDto (required): - Future searchAssetsWithHttpInfo(MetadataSearchDto metadataSearchDto,) async { + Future searchAssetsWithHttpInfo(MetadataSearchDto metadataSearchDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/search/metadata'; @@ -320,6 +324,7 @@ class SearchApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -330,8 +335,8 @@ class SearchApi { /// Parameters: /// /// * [MetadataSearchDto] metadataSearchDto (required): - Future searchAssets(MetadataSearchDto metadataSearchDto,) async { - final response = await searchAssetsWithHttpInfo(metadataSearchDto,); + Future searchAssets(MetadataSearchDto metadataSearchDto, { Future? abortTrigger, }) async { + final response = await searchAssetsWithHttpInfo(metadataSearchDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -443,7 +448,7 @@ class SearchApi { /// /// * [bool] withExif: /// Include EXIF data in response - Future searchLargeAssetsWithHttpInfo({ List? albumIds, String? city, String? country, DateTime? createdAfter, DateTime? createdBefore, bool? isEncoded, bool? isFavorite, bool? isMotion, bool? isNotInAlbum, bool? isOffline, String? lensModel, String? libraryId, String? make, int? minFileSize, String? model, String? ocr, List? personIds, int? rating, int? size, String? state, List? tagIds, DateTime? takenAfter, DateTime? takenBefore, DateTime? trashedAfter, DateTime? trashedBefore, AssetTypeEnum? type, DateTime? updatedAfter, DateTime? updatedBefore, AssetVisibility? visibility, bool? withDeleted, bool? withExif, }) async { + Future searchLargeAssetsWithHttpInfo({ List? albumIds, String? city, String? country, DateTime? createdAfter, DateTime? createdBefore, bool? isEncoded, bool? isFavorite, bool? isMotion, bool? isNotInAlbum, bool? isOffline, String? lensModel, String? libraryId, String? make, int? minFileSize, String? model, String? ocr, List? personIds, int? rating, int? size, String? state, List? tagIds, DateTime? takenAfter, DateTime? takenBefore, DateTime? trashedAfter, DateTime? trashedBefore, AssetTypeEnum? type, DateTime? updatedAfter, DateTime? updatedBefore, AssetVisibility? visibility, bool? withDeleted, bool? withExif, Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/search/large-assets'; @@ -559,6 +564,7 @@ class SearchApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -658,8 +664,8 @@ class SearchApi { /// /// * [bool] withExif: /// Include EXIF data in response - Future?> searchLargeAssets({ List? albumIds, String? city, String? country, DateTime? createdAfter, DateTime? createdBefore, bool? isEncoded, bool? isFavorite, bool? isMotion, bool? isNotInAlbum, bool? isOffline, String? lensModel, String? libraryId, String? make, int? minFileSize, String? model, String? ocr, List? personIds, int? rating, int? size, String? state, List? tagIds, DateTime? takenAfter, DateTime? takenBefore, DateTime? trashedAfter, DateTime? trashedBefore, AssetTypeEnum? type, DateTime? updatedAfter, DateTime? updatedBefore, AssetVisibility? visibility, bool? withDeleted, bool? withExif, }) async { - final response = await searchLargeAssetsWithHttpInfo( albumIds: albumIds, city: city, country: country, createdAfter: createdAfter, createdBefore: createdBefore, isEncoded: isEncoded, isFavorite: isFavorite, isMotion: isMotion, isNotInAlbum: isNotInAlbum, isOffline: isOffline, lensModel: lensModel, libraryId: libraryId, make: make, minFileSize: minFileSize, model: model, ocr: ocr, personIds: personIds, rating: rating, size: size, state: state, tagIds: tagIds, takenAfter: takenAfter, takenBefore: takenBefore, trashedAfter: trashedAfter, trashedBefore: trashedBefore, type: type, updatedAfter: updatedAfter, updatedBefore: updatedBefore, visibility: visibility, withDeleted: withDeleted, withExif: withExif, ); + Future?> searchLargeAssets({ List? albumIds, String? city, String? country, DateTime? createdAfter, DateTime? createdBefore, bool? isEncoded, bool? isFavorite, bool? isMotion, bool? isNotInAlbum, bool? isOffline, String? lensModel, String? libraryId, String? make, int? minFileSize, String? model, String? ocr, List? personIds, int? rating, int? size, String? state, List? tagIds, DateTime? takenAfter, DateTime? takenBefore, DateTime? trashedAfter, DateTime? trashedBefore, AssetTypeEnum? type, DateTime? updatedAfter, DateTime? updatedBefore, AssetVisibility? visibility, bool? withDeleted, bool? withExif, Future? abortTrigger, }) async { + final response = await searchLargeAssetsWithHttpInfo(albumIds: albumIds, city: city, country: country, createdAfter: createdAfter, createdBefore: createdBefore, isEncoded: isEncoded, isFavorite: isFavorite, isMotion: isMotion, isNotInAlbum: isNotInAlbum, isOffline: isOffline, lensModel: lensModel, libraryId: libraryId, make: make, minFileSize: minFileSize, model: model, ocr: ocr, personIds: personIds, rating: rating, size: size, state: state, tagIds: tagIds, takenAfter: takenAfter, takenBefore: takenBefore, trashedAfter: trashedAfter, trashedBefore: trashedBefore, type: type, updatedAfter: updatedAfter, updatedBefore: updatedBefore, visibility: visibility, withDeleted: withDeleted, withExif: withExif, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -689,7 +695,7 @@ class SearchApi { /// /// * [bool] withHidden: /// Include hidden people - Future searchPersonWithHttpInfo(String name, { bool? withHidden, }) async { + Future searchPersonWithHttpInfo(String name, { bool? withHidden, Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/search/person'; @@ -716,6 +722,7 @@ class SearchApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -730,8 +737,8 @@ class SearchApi { /// /// * [bool] withHidden: /// Include hidden people - Future?> searchPerson(String name, { bool? withHidden, }) async { - final response = await searchPersonWithHttpInfo(name, withHidden: withHidden, ); + Future?> searchPerson(String name, { bool? withHidden, Future? abortTrigger, }) async { + final response = await searchPersonWithHttpInfo(name, withHidden: withHidden, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -758,7 +765,7 @@ class SearchApi { /// /// * [String] name (required): /// Place name to search for - Future searchPlacesWithHttpInfo(String name,) async { + Future searchPlacesWithHttpInfo(String name, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/search/places'; @@ -782,6 +789,7 @@ class SearchApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -793,8 +801,8 @@ class SearchApi { /// /// * [String] name (required): /// Place name to search for - Future?> searchPlaces(String name,) async { - final response = await searchPlacesWithHttpInfo(name,); + Future?> searchPlaces(String name, { Future? abortTrigger, }) async { + final response = await searchPlacesWithHttpInfo(name, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -820,7 +828,7 @@ class SearchApi { /// Parameters: /// /// * [RandomSearchDto] randomSearchDto (required): - Future searchRandomWithHttpInfo(RandomSearchDto randomSearchDto,) async { + Future searchRandomWithHttpInfo(RandomSearchDto randomSearchDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/search/random'; @@ -842,6 +850,7 @@ class SearchApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -852,8 +861,8 @@ class SearchApi { /// Parameters: /// /// * [RandomSearchDto] randomSearchDto (required): - Future?> searchRandom(RandomSearchDto randomSearchDto,) async { - final response = await searchRandomWithHttpInfo(randomSearchDto,); + Future?> searchRandom(RandomSearchDto randomSearchDto, { Future? abortTrigger, }) async { + final response = await searchRandomWithHttpInfo(randomSearchDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -879,7 +888,7 @@ class SearchApi { /// Parameters: /// /// * [SmartSearchDto] smartSearchDto (required): - Future searchSmartWithHttpInfo(SmartSearchDto smartSearchDto,) async { + Future searchSmartWithHttpInfo(SmartSearchDto smartSearchDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/search/smart'; @@ -901,6 +910,7 @@ class SearchApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -911,8 +921,8 @@ class SearchApi { /// Parameters: /// /// * [SmartSearchDto] smartSearchDto (required): - Future searchSmart(SmartSearchDto smartSearchDto,) async { - final response = await searchSmartWithHttpInfo(smartSearchDto,); + Future searchSmart(SmartSearchDto smartSearchDto, { Future? abortTrigger, }) async { + final response = await searchSmartWithHttpInfo(smartSearchDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } diff --git a/mobile/openapi/lib/api/server_api.dart b/mobile/openapi/lib/api/server_api.dart index dd38ade167..1a46a86188 100644 --- a/mobile/openapi/lib/api/server_api.dart +++ b/mobile/openapi/lib/api/server_api.dart @@ -21,7 +21,7 @@ class ServerApi { /// Delete the currently set server product key. /// /// Note: This method returns the HTTP [Response]. - Future deleteServerLicenseWithHttpInfo() async { + Future deleteServerLicenseWithHttpInfo({ Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/server/license'; @@ -43,14 +43,15 @@ class ServerApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } /// Delete server product key /// /// Delete the currently set server product key. - Future deleteServerLicense() async { - final response = await deleteServerLicenseWithHttpInfo(); + Future deleteServerLicense({ Future? abortTrigger, }) async { + final response = await deleteServerLicenseWithHttpInfo(abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -61,7 +62,7 @@ class ServerApi { /// Retrieve a list of information about the server. /// /// Note: This method returns the HTTP [Response]. - Future getAboutInfoWithHttpInfo() async { + Future getAboutInfoWithHttpInfo({ Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/server/about'; @@ -83,14 +84,15 @@ class ServerApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } /// Get server information /// /// Retrieve a list of information about the server. - Future getAboutInfo() async { - final response = await getAboutInfoWithHttpInfo(); + Future getAboutInfo({ Future? abortTrigger, }) async { + final response = await getAboutInfoWithHttpInfo(abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -109,7 +111,7 @@ class ServerApi { /// Retrieve links to the APKs for the current server version. /// /// Note: This method returns the HTTP [Response]. - Future getApkLinksWithHttpInfo() async { + Future getApkLinksWithHttpInfo({ Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/server/apk-links'; @@ -131,14 +133,15 @@ class ServerApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } /// Get APK links /// /// Retrieve links to the APKs for the current server version. - Future getApkLinks() async { - final response = await getApkLinksWithHttpInfo(); + Future getApkLinks({ Future? abortTrigger, }) async { + final response = await getApkLinksWithHttpInfo(abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -157,7 +160,7 @@ class ServerApi { /// Retrieve the current server configuration. /// /// Note: This method returns the HTTP [Response]. - Future getServerConfigWithHttpInfo() async { + Future getServerConfigWithHttpInfo({ Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/server/config'; @@ -179,14 +182,15 @@ class ServerApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } /// Get config /// /// Retrieve the current server configuration. - Future getServerConfig() async { - final response = await getServerConfigWithHttpInfo(); + Future getServerConfig({ Future? abortTrigger, }) async { + final response = await getServerConfigWithHttpInfo(abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -205,7 +209,7 @@ class ServerApi { /// Retrieve available features supported by this server. /// /// Note: This method returns the HTTP [Response]. - Future getServerFeaturesWithHttpInfo() async { + Future getServerFeaturesWithHttpInfo({ Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/server/features'; @@ -227,14 +231,15 @@ class ServerApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } /// Get features /// /// Retrieve available features supported by this server. - Future getServerFeatures() async { - final response = await getServerFeaturesWithHttpInfo(); + Future getServerFeatures({ Future? abortTrigger, }) async { + final response = await getServerFeaturesWithHttpInfo(abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -253,7 +258,7 @@ class ServerApi { /// Retrieve information about whether the server currently has a product key registered. /// /// Note: This method returns the HTTP [Response]. - Future getServerLicenseWithHttpInfo() async { + Future getServerLicenseWithHttpInfo({ Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/server/license'; @@ -275,14 +280,15 @@ class ServerApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } /// Get product key /// /// Retrieve information about whether the server currently has a product key registered. - Future getServerLicense() async { - final response = await getServerLicenseWithHttpInfo(); + Future getServerLicense({ Future? abortTrigger, }) async { + final response = await getServerLicenseWithHttpInfo(abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -301,7 +307,7 @@ class ServerApi { /// Retrieve statistics about the entire Immich instance such as asset counts. /// /// Note: This method returns the HTTP [Response]. - Future getServerStatisticsWithHttpInfo() async { + Future getServerStatisticsWithHttpInfo({ Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/server/statistics'; @@ -323,14 +329,15 @@ class ServerApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } /// Get statistics /// /// Retrieve statistics about the entire Immich instance such as asset counts. - Future getServerStatistics() async { - final response = await getServerStatisticsWithHttpInfo(); + Future getServerStatistics({ Future? abortTrigger, }) async { + final response = await getServerStatisticsWithHttpInfo(abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -349,7 +356,7 @@ class ServerApi { /// Retrieve the current server version in semantic versioning (semver) format. /// /// Note: This method returns the HTTP [Response]. - Future getServerVersionWithHttpInfo() async { + Future getServerVersionWithHttpInfo({ Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/server/version'; @@ -371,14 +378,15 @@ class ServerApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } /// Get server version /// /// Retrieve the current server version in semantic versioning (semver) format. - Future getServerVersion() async { - final response = await getServerVersionWithHttpInfo(); + Future getServerVersion({ Future? abortTrigger, }) async { + final response = await getServerVersionWithHttpInfo(abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -397,7 +405,7 @@ class ServerApi { /// Retrieve the current storage utilization information of the server. /// /// Note: This method returns the HTTP [Response]. - Future getStorageWithHttpInfo() async { + Future getStorageWithHttpInfo({ Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/server/storage'; @@ -419,14 +427,15 @@ class ServerApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } /// Get storage /// /// Retrieve the current storage utilization information of the server. - Future getStorage() async { - final response = await getStorageWithHttpInfo(); + Future getStorage({ Future? abortTrigger, }) async { + final response = await getStorageWithHttpInfo(abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -445,7 +454,7 @@ class ServerApi { /// Retrieve all media types supported by the server. /// /// Note: This method returns the HTTP [Response]. - Future getSupportedMediaTypesWithHttpInfo() async { + Future getSupportedMediaTypesWithHttpInfo({ Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/server/media-types'; @@ -467,14 +476,15 @@ class ServerApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } /// Get supported media types /// /// Retrieve all media types supported by the server. - Future getSupportedMediaTypes() async { - final response = await getSupportedMediaTypesWithHttpInfo(); + Future getSupportedMediaTypes({ Future? abortTrigger, }) async { + final response = await getSupportedMediaTypesWithHttpInfo(abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -493,7 +503,7 @@ class ServerApi { /// Retrieve information about the last time the version check ran. /// /// Note: This method returns the HTTP [Response]. - Future getVersionCheckWithHttpInfo() async { + Future getVersionCheckWithHttpInfo({ Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/server/version-check'; @@ -515,14 +525,15 @@ class ServerApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } /// Get version check status /// /// Retrieve information about the last time the version check ran. - Future getVersionCheck() async { - final response = await getVersionCheckWithHttpInfo(); + Future getVersionCheck({ Future? abortTrigger, }) async { + final response = await getVersionCheckWithHttpInfo(abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -541,7 +552,7 @@ class ServerApi { /// Retrieve a list of past versions the server has been on. /// /// Note: This method returns the HTTP [Response]. - Future getVersionHistoryWithHttpInfo() async { + Future getVersionHistoryWithHttpInfo({ Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/server/version-history'; @@ -563,14 +574,15 @@ class ServerApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } /// Get version history /// /// Retrieve a list of past versions the server has been on. - Future?> getVersionHistory() async { - final response = await getVersionHistoryWithHttpInfo(); + Future?> getVersionHistory({ Future? abortTrigger, }) async { + final response = await getVersionHistoryWithHttpInfo(abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -592,7 +604,7 @@ class ServerApi { /// Pong /// /// Note: This method returns the HTTP [Response]. - Future pingServerWithHttpInfo() async { + Future pingServerWithHttpInfo({ Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/server/ping'; @@ -614,14 +626,15 @@ class ServerApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } /// Ping /// /// Pong - Future pingServer() async { - final response = await pingServerWithHttpInfo(); + Future pingServer({ Future? abortTrigger, }) async { + final response = await pingServerWithHttpInfo(abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -644,7 +657,7 @@ class ServerApi { /// Parameters: /// /// * [LicenseKeyDto] licenseKeyDto (required): - Future setServerLicenseWithHttpInfo(LicenseKeyDto licenseKeyDto,) async { + Future setServerLicenseWithHttpInfo(LicenseKeyDto licenseKeyDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/server/license'; @@ -666,6 +679,7 @@ class ServerApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -676,8 +690,8 @@ class ServerApi { /// Parameters: /// /// * [LicenseKeyDto] licenseKeyDto (required): - Future setServerLicense(LicenseKeyDto licenseKeyDto,) async { - final response = await setServerLicenseWithHttpInfo(licenseKeyDto,); + Future setServerLicense(LicenseKeyDto licenseKeyDto, { Future? abortTrigger, }) async { + final response = await setServerLicenseWithHttpInfo(licenseKeyDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } diff --git a/mobile/openapi/lib/api/sessions_api.dart b/mobile/openapi/lib/api/sessions_api.dart index da508059bc..fdd6c09266 100644 --- a/mobile/openapi/lib/api/sessions_api.dart +++ b/mobile/openapi/lib/api/sessions_api.dart @@ -25,7 +25,7 @@ class SessionsApi { /// Parameters: /// /// * [SessionCreateDto] sessionCreateDto (required): - Future createSessionWithHttpInfo(SessionCreateDto sessionCreateDto,) async { + Future createSessionWithHttpInfo(SessionCreateDto sessionCreateDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/sessions'; @@ -47,6 +47,7 @@ class SessionsApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -57,8 +58,8 @@ class SessionsApi { /// Parameters: /// /// * [SessionCreateDto] sessionCreateDto (required): - Future createSession(SessionCreateDto sessionCreateDto,) async { - final response = await createSessionWithHttpInfo(sessionCreateDto,); + Future createSession(SessionCreateDto sessionCreateDto, { Future? abortTrigger, }) async { + final response = await createSessionWithHttpInfo(sessionCreateDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -77,7 +78,7 @@ class SessionsApi { /// Delete all sessions for the user. This will not delete the current session. /// /// Note: This method returns the HTTP [Response]. - Future deleteAllSessionsWithHttpInfo() async { + Future deleteAllSessionsWithHttpInfo({ Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/sessions'; @@ -99,14 +100,15 @@ class SessionsApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } /// Delete all sessions /// /// Delete all sessions for the user. This will not delete the current session. - Future deleteAllSessions() async { - final response = await deleteAllSessionsWithHttpInfo(); + Future deleteAllSessions({ Future? abortTrigger, }) async { + final response = await deleteAllSessionsWithHttpInfo(abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -121,7 +123,7 @@ class SessionsApi { /// Parameters: /// /// * [String] id (required): - Future deleteSessionWithHttpInfo(String id,) async { + Future deleteSessionWithHttpInfo(String id, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/sessions/{id}' .replaceAll('{id}', id); @@ -144,6 +146,7 @@ class SessionsApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -154,8 +157,8 @@ class SessionsApi { /// Parameters: /// /// * [String] id (required): - Future deleteSession(String id,) async { - final response = await deleteSessionWithHttpInfo(id,); + Future deleteSession(String id, { Future? abortTrigger, }) async { + final response = await deleteSessionWithHttpInfo(id, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -166,7 +169,7 @@ class SessionsApi { /// Retrieve a list of sessions for the user. /// /// Note: This method returns the HTTP [Response]. - Future getSessionsWithHttpInfo() async { + Future getSessionsWithHttpInfo({ Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/sessions'; @@ -188,14 +191,15 @@ class SessionsApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } /// Retrieve sessions /// /// Retrieve a list of sessions for the user. - Future?> getSessions() async { - final response = await getSessionsWithHttpInfo(); + Future?> getSessions({ Future? abortTrigger, }) async { + final response = await getSessionsWithHttpInfo(abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -221,7 +225,7 @@ class SessionsApi { /// Parameters: /// /// * [String] id (required): - Future lockSessionWithHttpInfo(String id,) async { + Future lockSessionWithHttpInfo(String id, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/sessions/{id}/lock' .replaceAll('{id}', id); @@ -244,6 +248,7 @@ class SessionsApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -254,8 +259,8 @@ class SessionsApi { /// Parameters: /// /// * [String] id (required): - Future lockSession(String id,) async { - final response = await lockSessionWithHttpInfo(id,); + Future lockSession(String id, { Future? abortTrigger, }) async { + final response = await lockSessionWithHttpInfo(id, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -272,7 +277,7 @@ class SessionsApi { /// * [String] id (required): /// /// * [SessionUpdateDto] sessionUpdateDto (required): - Future updateSessionWithHttpInfo(String id, SessionUpdateDto sessionUpdateDto,) async { + Future updateSessionWithHttpInfo(String id, SessionUpdateDto sessionUpdateDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/sessions/{id}' .replaceAll('{id}', id); @@ -295,6 +300,7 @@ class SessionsApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -307,8 +313,8 @@ class SessionsApi { /// * [String] id (required): /// /// * [SessionUpdateDto] sessionUpdateDto (required): - Future updateSession(String id, SessionUpdateDto sessionUpdateDto,) async { - final response = await updateSessionWithHttpInfo(id, sessionUpdateDto,); + Future updateSession(String id, SessionUpdateDto sessionUpdateDto, { Future? abortTrigger, }) async { + final response = await updateSessionWithHttpInfo(id, sessionUpdateDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } diff --git a/mobile/openapi/lib/api/shared_links_api.dart b/mobile/openapi/lib/api/shared_links_api.dart index 4750442287..5bd548d7d2 100644 --- a/mobile/openapi/lib/api/shared_links_api.dart +++ b/mobile/openapi/lib/api/shared_links_api.dart @@ -27,7 +27,7 @@ class SharedLinksApi { /// * [String] id (required): /// /// * [AssetIdsDto] assetIdsDto (required): - Future addSharedLinkAssetsWithHttpInfo(String id, AssetIdsDto assetIdsDto,) async { + Future addSharedLinkAssetsWithHttpInfo(String id, AssetIdsDto assetIdsDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/shared-links/{id}/assets' .replaceAll('{id}', id); @@ -50,6 +50,7 @@ class SharedLinksApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -62,8 +63,8 @@ class SharedLinksApi { /// * [String] id (required): /// /// * [AssetIdsDto] assetIdsDto (required): - Future?> addSharedLinkAssets(String id, AssetIdsDto assetIdsDto,) async { - final response = await addSharedLinkAssetsWithHttpInfo(id, assetIdsDto,); + Future?> addSharedLinkAssets(String id, AssetIdsDto assetIdsDto, { Future? abortTrigger, }) async { + final response = await addSharedLinkAssetsWithHttpInfo(id, assetIdsDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -89,7 +90,7 @@ class SharedLinksApi { /// Parameters: /// /// * [SharedLinkCreateDto] sharedLinkCreateDto (required): - Future createSharedLinkWithHttpInfo(SharedLinkCreateDto sharedLinkCreateDto,) async { + Future createSharedLinkWithHttpInfo(SharedLinkCreateDto sharedLinkCreateDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/shared-links'; @@ -111,6 +112,7 @@ class SharedLinksApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -121,8 +123,8 @@ class SharedLinksApi { /// Parameters: /// /// * [SharedLinkCreateDto] sharedLinkCreateDto (required): - Future createSharedLink(SharedLinkCreateDto sharedLinkCreateDto,) async { - final response = await createSharedLinkWithHttpInfo(sharedLinkCreateDto,); + Future createSharedLink(SharedLinkCreateDto sharedLinkCreateDto, { Future? abortTrigger, }) async { + final response = await createSharedLinkWithHttpInfo(sharedLinkCreateDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -149,7 +151,7 @@ class SharedLinksApi { /// /// * [String] id: /// Filter by shared link ID - Future getAllSharedLinksWithHttpInfo({ String? albumId, String? id, }) async { + Future getAllSharedLinksWithHttpInfo({ String? albumId, String? id, Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/shared-links'; @@ -178,6 +180,7 @@ class SharedLinksApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -192,8 +195,8 @@ class SharedLinksApi { /// /// * [String] id: /// Filter by shared link ID - Future?> getAllSharedLinks({ String? albumId, String? id, }) async { - final response = await getAllSharedLinksWithHttpInfo( albumId: albumId, id: id, ); + Future?> getAllSharedLinks({ String? albumId, String? id, Future? abortTrigger, }) async { + final response = await getAllSharedLinksWithHttpInfo(albumId: albumId, id: id, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -221,7 +224,7 @@ class SharedLinksApi { /// * [String] key: /// /// * [String] slug: - Future getMySharedLinkWithHttpInfo({ String? key, String? slug, }) async { + Future getMySharedLinkWithHttpInfo({ String? key, String? slug, Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/shared-links/me'; @@ -250,6 +253,7 @@ class SharedLinksApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -262,8 +266,8 @@ class SharedLinksApi { /// * [String] key: /// /// * [String] slug: - Future getMySharedLink({ String? key, String? slug, }) async { - final response = await getMySharedLinkWithHttpInfo( key: key, slug: slug, ); + Future getMySharedLink({ String? key, String? slug, Future? abortTrigger, }) async { + final response = await getMySharedLinkWithHttpInfo(key: key, slug: slug, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -286,7 +290,7 @@ class SharedLinksApi { /// Parameters: /// /// * [String] id (required): - Future getSharedLinkByIdWithHttpInfo(String id,) async { + Future getSharedLinkByIdWithHttpInfo(String id, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/shared-links/{id}' .replaceAll('{id}', id); @@ -309,6 +313,7 @@ class SharedLinksApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -319,8 +324,8 @@ class SharedLinksApi { /// Parameters: /// /// * [String] id (required): - Future getSharedLinkById(String id,) async { - final response = await getSharedLinkByIdWithHttpInfo(id,); + Future getSharedLinkById(String id, { Future? abortTrigger, }) async { + final response = await getSharedLinkByIdWithHttpInfo(id, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -343,7 +348,7 @@ class SharedLinksApi { /// Parameters: /// /// * [String] id (required): - Future removeSharedLinkWithHttpInfo(String id,) async { + Future removeSharedLinkWithHttpInfo(String id, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/shared-links/{id}' .replaceAll('{id}', id); @@ -366,6 +371,7 @@ class SharedLinksApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -376,8 +382,8 @@ class SharedLinksApi { /// Parameters: /// /// * [String] id (required): - Future removeSharedLink(String id,) async { - final response = await removeSharedLinkWithHttpInfo(id,); + Future removeSharedLink(String id, { Future? abortTrigger, }) async { + final response = await removeSharedLinkWithHttpInfo(id, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -394,7 +400,7 @@ class SharedLinksApi { /// * [String] id (required): /// /// * [AssetIdsDto] assetIdsDto (required): - Future removeSharedLinkAssetsWithHttpInfo(String id, AssetIdsDto assetIdsDto,) async { + Future removeSharedLinkAssetsWithHttpInfo(String id, AssetIdsDto assetIdsDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/shared-links/{id}/assets' .replaceAll('{id}', id); @@ -417,6 +423,7 @@ class SharedLinksApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -429,8 +436,8 @@ class SharedLinksApi { /// * [String] id (required): /// /// * [AssetIdsDto] assetIdsDto (required): - Future?> removeSharedLinkAssets(String id, AssetIdsDto assetIdsDto,) async { - final response = await removeSharedLinkAssetsWithHttpInfo(id, assetIdsDto,); + Future?> removeSharedLinkAssets(String id, AssetIdsDto assetIdsDto, { Future? abortTrigger, }) async { + final response = await removeSharedLinkAssetsWithHttpInfo(id, assetIdsDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -460,7 +467,7 @@ class SharedLinksApi { /// * [String] key: /// /// * [String] slug: - Future sharedLinkLoginWithHttpInfo(SharedLinkLoginDto sharedLinkLoginDto, { String? key, String? slug, }) async { + Future sharedLinkLoginWithHttpInfo(SharedLinkLoginDto sharedLinkLoginDto, { String? key, String? slug, Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/shared-links/login'; @@ -489,6 +496,7 @@ class SharedLinksApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -503,8 +511,8 @@ class SharedLinksApi { /// * [String] key: /// /// * [String] slug: - Future sharedLinkLogin(SharedLinkLoginDto sharedLinkLoginDto, { String? key, String? slug, }) async { - final response = await sharedLinkLoginWithHttpInfo(sharedLinkLoginDto, key: key, slug: slug, ); + Future sharedLinkLogin(SharedLinkLoginDto sharedLinkLoginDto, { String? key, String? slug, Future? abortTrigger, }) async { + final response = await sharedLinkLoginWithHttpInfo(sharedLinkLoginDto, key: key, slug: slug, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -529,7 +537,7 @@ class SharedLinksApi { /// * [String] id (required): /// /// * [SharedLinkEditDto] sharedLinkEditDto (required): - Future updateSharedLinkWithHttpInfo(String id, SharedLinkEditDto sharedLinkEditDto,) async { + Future updateSharedLinkWithHttpInfo(String id, SharedLinkEditDto sharedLinkEditDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/shared-links/{id}' .replaceAll('{id}', id); @@ -552,6 +560,7 @@ class SharedLinksApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -564,8 +573,8 @@ class SharedLinksApi { /// * [String] id (required): /// /// * [SharedLinkEditDto] sharedLinkEditDto (required): - Future updateSharedLink(String id, SharedLinkEditDto sharedLinkEditDto,) async { - final response = await updateSharedLinkWithHttpInfo(id, sharedLinkEditDto,); + Future updateSharedLink(String id, SharedLinkEditDto sharedLinkEditDto, { Future? abortTrigger, }) async { + final response = await updateSharedLinkWithHttpInfo(id, sharedLinkEditDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } diff --git a/mobile/openapi/lib/api/stacks_api.dart b/mobile/openapi/lib/api/stacks_api.dart index a691af2a7d..a99ebe0600 100644 --- a/mobile/openapi/lib/api/stacks_api.dart +++ b/mobile/openapi/lib/api/stacks_api.dart @@ -25,7 +25,7 @@ class StacksApi { /// Parameters: /// /// * [StackCreateDto] stackCreateDto (required): - Future createStackWithHttpInfo(StackCreateDto stackCreateDto,) async { + Future createStackWithHttpInfo(StackCreateDto stackCreateDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/stacks'; @@ -47,6 +47,7 @@ class StacksApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -57,8 +58,8 @@ class StacksApi { /// Parameters: /// /// * [StackCreateDto] stackCreateDto (required): - Future createStack(StackCreateDto stackCreateDto,) async { - final response = await createStackWithHttpInfo(stackCreateDto,); + Future createStack(StackCreateDto stackCreateDto, { Future? abortTrigger, }) async { + final response = await createStackWithHttpInfo(stackCreateDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -81,7 +82,7 @@ class StacksApi { /// Parameters: /// /// * [String] id (required): - Future deleteStackWithHttpInfo(String id,) async { + Future deleteStackWithHttpInfo(String id, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/stacks/{id}' .replaceAll('{id}', id); @@ -104,6 +105,7 @@ class StacksApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -114,8 +116,8 @@ class StacksApi { /// Parameters: /// /// * [String] id (required): - Future deleteStack(String id,) async { - final response = await deleteStackWithHttpInfo(id,); + Future deleteStack(String id, { Future? abortTrigger, }) async { + final response = await deleteStackWithHttpInfo(id, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -130,7 +132,7 @@ class StacksApi { /// Parameters: /// /// * [BulkIdsDto] bulkIdsDto (required): - Future deleteStacksWithHttpInfo(BulkIdsDto bulkIdsDto,) async { + Future deleteStacksWithHttpInfo(BulkIdsDto bulkIdsDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/stacks'; @@ -152,6 +154,7 @@ class StacksApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -162,8 +165,8 @@ class StacksApi { /// Parameters: /// /// * [BulkIdsDto] bulkIdsDto (required): - Future deleteStacks(BulkIdsDto bulkIdsDto,) async { - final response = await deleteStacksWithHttpInfo(bulkIdsDto,); + Future deleteStacks(BulkIdsDto bulkIdsDto, { Future? abortTrigger, }) async { + final response = await deleteStacksWithHttpInfo(bulkIdsDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -178,7 +181,7 @@ class StacksApi { /// Parameters: /// /// * [String] id (required): - Future getStackWithHttpInfo(String id,) async { + Future getStackWithHttpInfo(String id, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/stacks/{id}' .replaceAll('{id}', id); @@ -201,6 +204,7 @@ class StacksApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -211,8 +215,8 @@ class StacksApi { /// Parameters: /// /// * [String] id (required): - Future getStack(String id,) async { - final response = await getStackWithHttpInfo(id,); + Future getStack(String id, { Future? abortTrigger, }) async { + final response = await getStackWithHttpInfo(id, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -237,7 +241,7 @@ class StacksApi { /// * [String] assetId (required): /// /// * [String] id (required): - Future removeAssetFromStackWithHttpInfo(String assetId, String id,) async { + Future removeAssetFromStackWithHttpInfo(String assetId, String id, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/stacks/{id}/assets/{assetId}' .replaceAll('{assetId}', assetId) @@ -261,6 +265,7 @@ class StacksApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -273,8 +278,8 @@ class StacksApi { /// * [String] assetId (required): /// /// * [String] id (required): - Future removeAssetFromStack(String assetId, String id,) async { - final response = await removeAssetFromStackWithHttpInfo(assetId, id,); + Future removeAssetFromStack(String assetId, String id, { Future? abortTrigger, }) async { + final response = await removeAssetFromStackWithHttpInfo(assetId, id, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -290,7 +295,7 @@ class StacksApi { /// /// * [String] primaryAssetId: /// Filter by primary asset ID - Future searchStacksWithHttpInfo({ String? primaryAssetId, }) async { + Future searchStacksWithHttpInfo({ String? primaryAssetId, Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/stacks'; @@ -316,6 +321,7 @@ class StacksApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -327,8 +333,8 @@ class StacksApi { /// /// * [String] primaryAssetId: /// Filter by primary asset ID - Future?> searchStacks({ String? primaryAssetId, }) async { - final response = await searchStacksWithHttpInfo( primaryAssetId: primaryAssetId, ); + Future?> searchStacks({ String? primaryAssetId, Future? abortTrigger, }) async { + final response = await searchStacksWithHttpInfo(primaryAssetId: primaryAssetId, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -356,7 +362,7 @@ class StacksApi { /// * [String] id (required): /// /// * [StackUpdateDto] stackUpdateDto (required): - Future updateStackWithHttpInfo(String id, StackUpdateDto stackUpdateDto,) async { + Future updateStackWithHttpInfo(String id, StackUpdateDto stackUpdateDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/stacks/{id}' .replaceAll('{id}', id); @@ -379,6 +385,7 @@ class StacksApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -391,8 +398,8 @@ class StacksApi { /// * [String] id (required): /// /// * [StackUpdateDto] stackUpdateDto (required): - Future updateStack(String id, StackUpdateDto stackUpdateDto,) async { - final response = await updateStackWithHttpInfo(id, stackUpdateDto,); + Future updateStack(String id, StackUpdateDto stackUpdateDto, { Future? abortTrigger, }) async { + final response = await updateStackWithHttpInfo(id, stackUpdateDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } diff --git a/mobile/openapi/lib/api/sync_api.dart b/mobile/openapi/lib/api/sync_api.dart index e7bc822ace..c2a57c3395 100644 --- a/mobile/openapi/lib/api/sync_api.dart +++ b/mobile/openapi/lib/api/sync_api.dart @@ -25,7 +25,7 @@ class SyncApi { /// Parameters: /// /// * [SyncAckDeleteDto] syncAckDeleteDto (required): - Future deleteSyncAckWithHttpInfo(SyncAckDeleteDto syncAckDeleteDto,) async { + Future deleteSyncAckWithHttpInfo(SyncAckDeleteDto syncAckDeleteDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/sync/ack'; @@ -47,6 +47,7 @@ class SyncApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -57,8 +58,8 @@ class SyncApi { /// Parameters: /// /// * [SyncAckDeleteDto] syncAckDeleteDto (required): - Future deleteSyncAck(SyncAckDeleteDto syncAckDeleteDto,) async { - final response = await deleteSyncAckWithHttpInfo(syncAckDeleteDto,); + Future deleteSyncAck(SyncAckDeleteDto syncAckDeleteDto, { Future? abortTrigger, }) async { + final response = await deleteSyncAckWithHttpInfo(syncAckDeleteDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -69,7 +70,7 @@ class SyncApi { /// Retrieve the synchronization acknowledgments for the current session. /// /// Note: This method returns the HTTP [Response]. - Future getSyncAckWithHttpInfo() async { + Future getSyncAckWithHttpInfo({ Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/sync/ack'; @@ -91,14 +92,15 @@ class SyncApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } /// Retrieve acknowledgements /// /// Retrieve the synchronization acknowledgments for the current session. - Future?> getSyncAck() async { - final response = await getSyncAckWithHttpInfo(); + Future?> getSyncAck({ Future? abortTrigger, }) async { + final response = await getSyncAckWithHttpInfo(abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -124,7 +126,7 @@ class SyncApi { /// Parameters: /// /// * [SyncStreamDto] syncStreamDto (required): - Future getSyncStreamWithHttpInfo(SyncStreamDto syncStreamDto,) async { + Future getSyncStreamWithHttpInfo(SyncStreamDto syncStreamDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/sync/stream'; @@ -146,6 +148,7 @@ class SyncApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -156,8 +159,8 @@ class SyncApi { /// Parameters: /// /// * [SyncStreamDto] syncStreamDto (required): - Future getSyncStream(SyncStreamDto syncStreamDto,) async { - final response = await getSyncStreamWithHttpInfo(syncStreamDto,); + Future getSyncStream(SyncStreamDto syncStreamDto, { Future? abortTrigger, }) async { + final response = await getSyncStreamWithHttpInfo(syncStreamDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -172,7 +175,7 @@ class SyncApi { /// Parameters: /// /// * [SyncAckSetDto] syncAckSetDto (required): - Future sendSyncAckWithHttpInfo(SyncAckSetDto syncAckSetDto,) async { + Future sendSyncAckWithHttpInfo(SyncAckSetDto syncAckSetDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/sync/ack'; @@ -194,6 +197,7 @@ class SyncApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -204,8 +208,8 @@ class SyncApi { /// Parameters: /// /// * [SyncAckSetDto] syncAckSetDto (required): - Future sendSyncAck(SyncAckSetDto syncAckSetDto,) async { - final response = await sendSyncAckWithHttpInfo(syncAckSetDto,); + Future sendSyncAck(SyncAckSetDto syncAckSetDto, { Future? abortTrigger, }) async { + final response = await sendSyncAckWithHttpInfo(syncAckSetDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } diff --git a/mobile/openapi/lib/api/system_config_api.dart b/mobile/openapi/lib/api/system_config_api.dart index b04da71273..ba5b82263a 100644 --- a/mobile/openapi/lib/api/system_config_api.dart +++ b/mobile/openapi/lib/api/system_config_api.dart @@ -21,7 +21,7 @@ class SystemConfigApi { /// Retrieve the current system configuration. /// /// Note: This method returns the HTTP [Response]. - Future getConfigWithHttpInfo() async { + Future getConfigWithHttpInfo({ Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/system-config'; @@ -43,14 +43,15 @@ class SystemConfigApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } /// Get system configuration /// /// Retrieve the current system configuration. - Future getConfig() async { - final response = await getConfigWithHttpInfo(); + Future getConfig({ Future? abortTrigger, }) async { + final response = await getConfigWithHttpInfo(abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -69,7 +70,7 @@ class SystemConfigApi { /// Retrieve the default values for the system configuration. /// /// Note: This method returns the HTTP [Response]. - Future getConfigDefaultsWithHttpInfo() async { + Future getConfigDefaultsWithHttpInfo({ Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/system-config/defaults'; @@ -91,14 +92,15 @@ class SystemConfigApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } /// Get system configuration defaults /// /// Retrieve the default values for the system configuration. - Future getConfigDefaults() async { - final response = await getConfigDefaultsWithHttpInfo(); + Future getConfigDefaults({ Future? abortTrigger, }) async { + final response = await getConfigDefaultsWithHttpInfo(abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -117,7 +119,7 @@ class SystemConfigApi { /// Retrieve exemplary storage template options. /// /// Note: This method returns the HTTP [Response]. - Future getStorageTemplateOptionsWithHttpInfo() async { + Future getStorageTemplateOptionsWithHttpInfo({ Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/system-config/storage-template-options'; @@ -139,14 +141,15 @@ class SystemConfigApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } /// Get storage template options /// /// Retrieve exemplary storage template options. - Future getStorageTemplateOptions() async { - final response = await getStorageTemplateOptionsWithHttpInfo(); + Future getStorageTemplateOptions({ Future? abortTrigger, }) async { + final response = await getStorageTemplateOptionsWithHttpInfo(abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -169,7 +172,7 @@ class SystemConfigApi { /// Parameters: /// /// * [SystemConfigDto] systemConfigDto (required): - Future updateConfigWithHttpInfo(SystemConfigDto systemConfigDto,) async { + Future updateConfigWithHttpInfo(SystemConfigDto systemConfigDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/system-config'; @@ -191,6 +194,7 @@ class SystemConfigApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -201,8 +205,8 @@ class SystemConfigApi { /// Parameters: /// /// * [SystemConfigDto] systemConfigDto (required): - Future updateConfig(SystemConfigDto systemConfigDto,) async { - final response = await updateConfigWithHttpInfo(systemConfigDto,); + Future updateConfig(SystemConfigDto systemConfigDto, { Future? abortTrigger, }) async { + final response = await updateConfigWithHttpInfo(systemConfigDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } diff --git a/mobile/openapi/lib/api/system_metadata_api.dart b/mobile/openapi/lib/api/system_metadata_api.dart index 63fd7628ec..a1429b54b0 100644 --- a/mobile/openapi/lib/api/system_metadata_api.dart +++ b/mobile/openapi/lib/api/system_metadata_api.dart @@ -21,7 +21,7 @@ class SystemMetadataApi { /// Retrieve the current admin onboarding status. /// /// Note: This method returns the HTTP [Response]. - Future getAdminOnboardingWithHttpInfo() async { + Future getAdminOnboardingWithHttpInfo({ Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/system-metadata/admin-onboarding'; @@ -43,14 +43,15 @@ class SystemMetadataApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } /// Retrieve admin onboarding /// /// Retrieve the current admin onboarding status. - Future getAdminOnboarding() async { - final response = await getAdminOnboardingWithHttpInfo(); + Future getAdminOnboarding({ Future? abortTrigger, }) async { + final response = await getAdminOnboardingWithHttpInfo(abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -69,7 +70,7 @@ class SystemMetadataApi { /// Retrieve the current state of the reverse geocoding import. /// /// Note: This method returns the HTTP [Response]. - Future getReverseGeocodingStateWithHttpInfo() async { + Future getReverseGeocodingStateWithHttpInfo({ Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/system-metadata/reverse-geocoding-state'; @@ -91,14 +92,15 @@ class SystemMetadataApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } /// Retrieve reverse geocoding state /// /// Retrieve the current state of the reverse geocoding import. - Future getReverseGeocodingState() async { - final response = await getReverseGeocodingStateWithHttpInfo(); + Future getReverseGeocodingState({ Future? abortTrigger, }) async { + final response = await getReverseGeocodingStateWithHttpInfo(abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -117,7 +119,7 @@ class SystemMetadataApi { /// Retrieve the current state of the version check process. /// /// Note: This method returns the HTTP [Response]. - Future getVersionCheckStateWithHttpInfo() async { + Future getVersionCheckStateWithHttpInfo({ Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/system-metadata/version-check-state'; @@ -139,14 +141,15 @@ class SystemMetadataApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } /// Retrieve version check state /// /// Retrieve the current state of the version check process. - Future getVersionCheckState() async { - final response = await getVersionCheckStateWithHttpInfo(); + Future getVersionCheckState({ Future? abortTrigger, }) async { + final response = await getVersionCheckStateWithHttpInfo(abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -169,7 +172,7 @@ class SystemMetadataApi { /// Parameters: /// /// * [AdminOnboardingUpdateDto] adminOnboardingUpdateDto (required): - Future updateAdminOnboardingWithHttpInfo(AdminOnboardingUpdateDto adminOnboardingUpdateDto,) async { + Future updateAdminOnboardingWithHttpInfo(AdminOnboardingUpdateDto adminOnboardingUpdateDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/system-metadata/admin-onboarding'; @@ -191,6 +194,7 @@ class SystemMetadataApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -201,8 +205,8 @@ class SystemMetadataApi { /// Parameters: /// /// * [AdminOnboardingUpdateDto] adminOnboardingUpdateDto (required): - Future updateAdminOnboarding(AdminOnboardingUpdateDto adminOnboardingUpdateDto,) async { - final response = await updateAdminOnboardingWithHttpInfo(adminOnboardingUpdateDto,); + Future updateAdminOnboarding(AdminOnboardingUpdateDto adminOnboardingUpdateDto, { Future? abortTrigger, }) async { + final response = await updateAdminOnboardingWithHttpInfo(adminOnboardingUpdateDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } diff --git a/mobile/openapi/lib/api/tags_api.dart b/mobile/openapi/lib/api/tags_api.dart index a6840f9483..c3cf9f545c 100644 --- a/mobile/openapi/lib/api/tags_api.dart +++ b/mobile/openapi/lib/api/tags_api.dart @@ -25,7 +25,7 @@ class TagsApi { /// Parameters: /// /// * [TagBulkAssetsDto] tagBulkAssetsDto (required): - Future bulkTagAssetsWithHttpInfo(TagBulkAssetsDto tagBulkAssetsDto,) async { + Future bulkTagAssetsWithHttpInfo(TagBulkAssetsDto tagBulkAssetsDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/tags/assets'; @@ -47,6 +47,7 @@ class TagsApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -57,8 +58,8 @@ class TagsApi { /// Parameters: /// /// * [TagBulkAssetsDto] tagBulkAssetsDto (required): - Future bulkTagAssets(TagBulkAssetsDto tagBulkAssetsDto,) async { - final response = await bulkTagAssetsWithHttpInfo(tagBulkAssetsDto,); + Future bulkTagAssets(TagBulkAssetsDto tagBulkAssetsDto, { Future? abortTrigger, }) async { + final response = await bulkTagAssetsWithHttpInfo(tagBulkAssetsDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -81,7 +82,7 @@ class TagsApi { /// Parameters: /// /// * [TagCreateDto] tagCreateDto (required): - Future createTagWithHttpInfo(TagCreateDto tagCreateDto,) async { + Future createTagWithHttpInfo(TagCreateDto tagCreateDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/tags'; @@ -103,6 +104,7 @@ class TagsApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -113,8 +115,8 @@ class TagsApi { /// Parameters: /// /// * [TagCreateDto] tagCreateDto (required): - Future createTag(TagCreateDto tagCreateDto,) async { - final response = await createTagWithHttpInfo(tagCreateDto,); + Future createTag(TagCreateDto tagCreateDto, { Future? abortTrigger, }) async { + final response = await createTagWithHttpInfo(tagCreateDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -137,7 +139,7 @@ class TagsApi { /// Parameters: /// /// * [String] id (required): - Future deleteTagWithHttpInfo(String id,) async { + Future deleteTagWithHttpInfo(String id, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/tags/{id}' .replaceAll('{id}', id); @@ -160,6 +162,7 @@ class TagsApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -170,8 +173,8 @@ class TagsApi { /// Parameters: /// /// * [String] id (required): - Future deleteTag(String id,) async { - final response = await deleteTagWithHttpInfo(id,); + Future deleteTag(String id, { Future? abortTrigger, }) async { + final response = await deleteTagWithHttpInfo(id, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -182,7 +185,7 @@ class TagsApi { /// Retrieve a list of all tags. /// /// Note: This method returns the HTTP [Response]. - Future getAllTagsWithHttpInfo() async { + Future getAllTagsWithHttpInfo({ Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/tags'; @@ -204,14 +207,15 @@ class TagsApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } /// Retrieve tags /// /// Retrieve a list of all tags. - Future?> getAllTags() async { - final response = await getAllTagsWithHttpInfo(); + Future?> getAllTags({ Future? abortTrigger, }) async { + final response = await getAllTagsWithHttpInfo(abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -237,7 +241,7 @@ class TagsApi { /// Parameters: /// /// * [String] id (required): - Future getTagByIdWithHttpInfo(String id,) async { + Future getTagByIdWithHttpInfo(String id, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/tags/{id}' .replaceAll('{id}', id); @@ -260,6 +264,7 @@ class TagsApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -270,8 +275,8 @@ class TagsApi { /// Parameters: /// /// * [String] id (required): - Future getTagById(String id,) async { - final response = await getTagByIdWithHttpInfo(id,); + Future getTagById(String id, { Future? abortTrigger, }) async { + final response = await getTagByIdWithHttpInfo(id, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -296,7 +301,7 @@ class TagsApi { /// * [String] id (required): /// /// * [BulkIdsDto] bulkIdsDto (required): - Future tagAssetsWithHttpInfo(String id, BulkIdsDto bulkIdsDto,) async { + Future tagAssetsWithHttpInfo(String id, BulkIdsDto bulkIdsDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/tags/{id}/assets' .replaceAll('{id}', id); @@ -319,6 +324,7 @@ class TagsApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -331,8 +337,8 @@ class TagsApi { /// * [String] id (required): /// /// * [BulkIdsDto] bulkIdsDto (required): - Future?> tagAssets(String id, BulkIdsDto bulkIdsDto,) async { - final response = await tagAssetsWithHttpInfo(id, bulkIdsDto,); + Future?> tagAssets(String id, BulkIdsDto bulkIdsDto, { Future? abortTrigger, }) async { + final response = await tagAssetsWithHttpInfo(id, bulkIdsDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -360,7 +366,7 @@ class TagsApi { /// * [String] id (required): /// /// * [BulkIdsDto] bulkIdsDto (required): - Future untagAssetsWithHttpInfo(String id, BulkIdsDto bulkIdsDto,) async { + Future untagAssetsWithHttpInfo(String id, BulkIdsDto bulkIdsDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/tags/{id}/assets' .replaceAll('{id}', id); @@ -383,6 +389,7 @@ class TagsApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -395,8 +402,8 @@ class TagsApi { /// * [String] id (required): /// /// * [BulkIdsDto] bulkIdsDto (required): - Future?> untagAssets(String id, BulkIdsDto bulkIdsDto,) async { - final response = await untagAssetsWithHttpInfo(id, bulkIdsDto,); + Future?> untagAssets(String id, BulkIdsDto bulkIdsDto, { Future? abortTrigger, }) async { + final response = await untagAssetsWithHttpInfo(id, bulkIdsDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -424,7 +431,7 @@ class TagsApi { /// * [String] id (required): /// /// * [TagUpdateDto] tagUpdateDto (required): - Future updateTagWithHttpInfo(String id, TagUpdateDto tagUpdateDto,) async { + Future updateTagWithHttpInfo(String id, TagUpdateDto tagUpdateDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/tags/{id}' .replaceAll('{id}', id); @@ -447,6 +454,7 @@ class TagsApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -459,8 +467,8 @@ class TagsApi { /// * [String] id (required): /// /// * [TagUpdateDto] tagUpdateDto (required): - Future updateTag(String id, TagUpdateDto tagUpdateDto,) async { - final response = await updateTagWithHttpInfo(id, tagUpdateDto,); + Future updateTag(String id, TagUpdateDto tagUpdateDto, { Future? abortTrigger, }) async { + final response = await updateTagWithHttpInfo(id, tagUpdateDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -483,7 +491,7 @@ class TagsApi { /// Parameters: /// /// * [TagUpsertDto] tagUpsertDto (required): - Future upsertTagsWithHttpInfo(TagUpsertDto tagUpsertDto,) async { + Future upsertTagsWithHttpInfo(TagUpsertDto tagUpsertDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/tags'; @@ -505,6 +513,7 @@ class TagsApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -515,8 +524,8 @@ class TagsApi { /// Parameters: /// /// * [TagUpsertDto] tagUpsertDto (required): - Future?> upsertTags(TagUpsertDto tagUpsertDto,) async { - final response = await upsertTagsWithHttpInfo(tagUpsertDto,); + Future?> upsertTags(TagUpsertDto tagUpsertDto, { Future? abortTrigger, }) async { + final response = await upsertTagsWithHttpInfo(tagUpsertDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } diff --git a/mobile/openapi/lib/api/timeline_api.dart b/mobile/openapi/lib/api/timeline_api.dart index 6c72f62604..a85aee2d7a 100644 --- a/mobile/openapi/lib/api/timeline_api.dart +++ b/mobile/openapi/lib/api/timeline_api.dart @@ -69,7 +69,7 @@ class TimelineApi { /// /// * [bool] withStacked: /// Include stacked assets in the response. When true, only primary assets from stacks are returned. - Future getTimeBucketWithHttpInfo(String timeBucket, { String? albumId, String? bbox, bool? isFavorite, bool? isTrashed, String? key, AssetOrder? order, AssetOrderBy? orderBy, String? personId, String? slug, String? tagId, String? userId, AssetVisibility? visibility, bool? withCoordinates, bool? withPartners, bool? withStacked, }) async { + Future getTimeBucketWithHttpInfo(String timeBucket, { String? albumId, String? bbox, bool? isFavorite, bool? isTrashed, String? key, AssetOrder? order, AssetOrderBy? orderBy, String? personId, String? slug, String? tagId, String? userId, AssetVisibility? visibility, bool? withCoordinates, bool? withPartners, bool? withStacked, Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/timeline/bucket'; @@ -138,6 +138,7 @@ class TimelineApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -192,8 +193,8 @@ class TimelineApi { /// /// * [bool] withStacked: /// Include stacked assets in the response. When true, only primary assets from stacks are returned. - Future getTimeBucket(String timeBucket, { String? albumId, String? bbox, bool? isFavorite, bool? isTrashed, String? key, AssetOrder? order, AssetOrderBy? orderBy, String? personId, String? slug, String? tagId, String? userId, AssetVisibility? visibility, bool? withCoordinates, bool? withPartners, bool? withStacked, }) async { - final response = await getTimeBucketWithHttpInfo(timeBucket, albumId: albumId, bbox: bbox, isFavorite: isFavorite, isTrashed: isTrashed, key: key, order: order, orderBy: orderBy, personId: personId, slug: slug, tagId: tagId, userId: userId, visibility: visibility, withCoordinates: withCoordinates, withPartners: withPartners, withStacked: withStacked, ); + Future getTimeBucket(String timeBucket, { String? albumId, String? bbox, bool? isFavorite, bool? isTrashed, String? key, AssetOrder? order, AssetOrderBy? orderBy, String? personId, String? slug, String? tagId, String? userId, AssetVisibility? visibility, bool? withCoordinates, bool? withPartners, bool? withStacked, Future? abortTrigger, }) async { + final response = await getTimeBucketWithHttpInfo(timeBucket, albumId: albumId, bbox: bbox, isFavorite: isFavorite, isTrashed: isTrashed, key: key, order: order, orderBy: orderBy, personId: personId, slug: slug, tagId: tagId, userId: userId, visibility: visibility, withCoordinates: withCoordinates, withPartners: withPartners, withStacked: withStacked, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -257,7 +258,7 @@ class TimelineApi { /// /// * [bool] withStacked: /// Include stacked assets in the response. When true, only primary assets from stacks are returned. - Future getTimeBucketsWithHttpInfo({ String? albumId, String? bbox, bool? isFavorite, bool? isTrashed, String? key, AssetOrder? order, AssetOrderBy? orderBy, String? personId, String? slug, String? tagId, String? userId, AssetVisibility? visibility, bool? withCoordinates, bool? withPartners, bool? withStacked, }) async { + Future getTimeBucketsWithHttpInfo({ String? albumId, String? bbox, bool? isFavorite, bool? isTrashed, String? key, AssetOrder? order, AssetOrderBy? orderBy, String? personId, String? slug, String? tagId, String? userId, AssetVisibility? visibility, bool? withCoordinates, bool? withPartners, bool? withStacked, Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/timeline/buckets'; @@ -325,6 +326,7 @@ class TimelineApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -376,8 +378,8 @@ class TimelineApi { /// /// * [bool] withStacked: /// Include stacked assets in the response. When true, only primary assets from stacks are returned. - Future?> getTimeBuckets({ String? albumId, String? bbox, bool? isFavorite, bool? isTrashed, String? key, AssetOrder? order, AssetOrderBy? orderBy, String? personId, String? slug, String? tagId, String? userId, AssetVisibility? visibility, bool? withCoordinates, bool? withPartners, bool? withStacked, }) async { - final response = await getTimeBucketsWithHttpInfo( albumId: albumId, bbox: bbox, isFavorite: isFavorite, isTrashed: isTrashed, key: key, order: order, orderBy: orderBy, personId: personId, slug: slug, tagId: tagId, userId: userId, visibility: visibility, withCoordinates: withCoordinates, withPartners: withPartners, withStacked: withStacked, ); + Future?> getTimeBuckets({ String? albumId, String? bbox, bool? isFavorite, bool? isTrashed, String? key, AssetOrder? order, AssetOrderBy? orderBy, String? personId, String? slug, String? tagId, String? userId, AssetVisibility? visibility, bool? withCoordinates, bool? withPartners, bool? withStacked, Future? abortTrigger, }) async { + final response = await getTimeBucketsWithHttpInfo(albumId: albumId, bbox: bbox, isFavorite: isFavorite, isTrashed: isTrashed, key: key, order: order, orderBy: orderBy, personId: personId, slug: slug, tagId: tagId, userId: userId, visibility: visibility, withCoordinates: withCoordinates, withPartners: withPartners, withStacked: withStacked, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } diff --git a/mobile/openapi/lib/api/trash_api.dart b/mobile/openapi/lib/api/trash_api.dart index f1dcbb8896..7b593e5111 100644 --- a/mobile/openapi/lib/api/trash_api.dart +++ b/mobile/openapi/lib/api/trash_api.dart @@ -21,7 +21,7 @@ class TrashApi { /// Permanently delete all items in the trash. /// /// Note: This method returns the HTTP [Response]. - Future emptyTrashWithHttpInfo() async { + Future emptyTrashWithHttpInfo({ Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/trash/empty'; @@ -43,14 +43,15 @@ class TrashApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } /// Empty trash /// /// Permanently delete all items in the trash. - Future emptyTrash() async { - final response = await emptyTrashWithHttpInfo(); + Future emptyTrash({ Future? abortTrigger, }) async { + final response = await emptyTrashWithHttpInfo(abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -73,7 +74,7 @@ class TrashApi { /// Parameters: /// /// * [BulkIdsDto] bulkIdsDto (required): - Future restoreAssetsWithHttpInfo(BulkIdsDto bulkIdsDto,) async { + Future restoreAssetsWithHttpInfo(BulkIdsDto bulkIdsDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/trash/restore/assets'; @@ -95,6 +96,7 @@ class TrashApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -105,8 +107,8 @@ class TrashApi { /// Parameters: /// /// * [BulkIdsDto] bulkIdsDto (required): - Future restoreAssets(BulkIdsDto bulkIdsDto,) async { - final response = await restoreAssetsWithHttpInfo(bulkIdsDto,); + Future restoreAssets(BulkIdsDto bulkIdsDto, { Future? abortTrigger, }) async { + final response = await restoreAssetsWithHttpInfo(bulkIdsDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -125,7 +127,7 @@ class TrashApi { /// Restore all items in the trash. /// /// Note: This method returns the HTTP [Response]. - Future restoreTrashWithHttpInfo() async { + Future restoreTrashWithHttpInfo({ Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/trash/restore'; @@ -147,14 +149,15 @@ class TrashApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } /// Restore trash /// /// Restore all items in the trash. - Future restoreTrash() async { - final response = await restoreTrashWithHttpInfo(); + Future restoreTrash({ Future? abortTrigger, }) async { + final response = await restoreTrashWithHttpInfo(abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } diff --git a/mobile/openapi/lib/api/users_admin_api.dart b/mobile/openapi/lib/api/users_admin_api.dart index 5e165ffd5d..fd6b43d9ce 100644 --- a/mobile/openapi/lib/api/users_admin_api.dart +++ b/mobile/openapi/lib/api/users_admin_api.dart @@ -25,7 +25,7 @@ class UsersAdminApi { /// Parameters: /// /// * [UserAdminCreateDto] userAdminCreateDto (required): - Future createUserAdminWithHttpInfo(UserAdminCreateDto userAdminCreateDto,) async { + Future createUserAdminWithHttpInfo(UserAdminCreateDto userAdminCreateDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/admin/users'; @@ -47,6 +47,7 @@ class UsersAdminApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -57,8 +58,8 @@ class UsersAdminApi { /// Parameters: /// /// * [UserAdminCreateDto] userAdminCreateDto (required): - Future createUserAdmin(UserAdminCreateDto userAdminCreateDto,) async { - final response = await createUserAdminWithHttpInfo(userAdminCreateDto,); + Future createUserAdmin(UserAdminCreateDto userAdminCreateDto, { Future? abortTrigger, }) async { + final response = await createUserAdminWithHttpInfo(userAdminCreateDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -83,7 +84,7 @@ class UsersAdminApi { /// * [String] id (required): /// /// * [UserAdminDeleteDto] userAdminDeleteDto (required): - Future deleteUserAdminWithHttpInfo(String id, UserAdminDeleteDto userAdminDeleteDto,) async { + Future deleteUserAdminWithHttpInfo(String id, UserAdminDeleteDto userAdminDeleteDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/admin/users/{id}' .replaceAll('{id}', id); @@ -106,6 +107,7 @@ class UsersAdminApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -118,8 +120,8 @@ class UsersAdminApi { /// * [String] id (required): /// /// * [UserAdminDeleteDto] userAdminDeleteDto (required): - Future deleteUserAdmin(String id, UserAdminDeleteDto userAdminDeleteDto,) async { - final response = await deleteUserAdminWithHttpInfo(id, userAdminDeleteDto,); + Future deleteUserAdmin(String id, UserAdminDeleteDto userAdminDeleteDto, { Future? abortTrigger, }) async { + final response = await deleteUserAdminWithHttpInfo(id, userAdminDeleteDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -142,7 +144,7 @@ class UsersAdminApi { /// Parameters: /// /// * [String] id (required): - Future getUserAdminWithHttpInfo(String id,) async { + Future getUserAdminWithHttpInfo(String id, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/admin/users/{id}' .replaceAll('{id}', id); @@ -165,6 +167,7 @@ class UsersAdminApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -175,8 +178,8 @@ class UsersAdminApi { /// Parameters: /// /// * [String] id (required): - Future getUserAdmin(String id,) async { - final response = await getUserAdminWithHttpInfo(id,); + Future getUserAdmin(String id, { Future? abortTrigger, }) async { + final response = await getUserAdminWithHttpInfo(id, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -199,7 +202,7 @@ class UsersAdminApi { /// Parameters: /// /// * [String] id (required): - Future getUserPreferencesAdminWithHttpInfo(String id,) async { + Future getUserPreferencesAdminWithHttpInfo(String id, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/admin/users/{id}/preferences' .replaceAll('{id}', id); @@ -222,6 +225,7 @@ class UsersAdminApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -232,8 +236,8 @@ class UsersAdminApi { /// Parameters: /// /// * [String] id (required): - Future getUserPreferencesAdmin(String id,) async { - final response = await getUserPreferencesAdminWithHttpInfo(id,); + Future getUserPreferencesAdmin(String id, { Future? abortTrigger, }) async { + final response = await getUserPreferencesAdminWithHttpInfo(id, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -256,7 +260,7 @@ class UsersAdminApi { /// Parameters: /// /// * [String] id (required): - Future getUserSessionsAdminWithHttpInfo(String id,) async { + Future getUserSessionsAdminWithHttpInfo(String id, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/admin/users/{id}/sessions' .replaceAll('{id}', id); @@ -279,6 +283,7 @@ class UsersAdminApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -289,8 +294,8 @@ class UsersAdminApi { /// Parameters: /// /// * [String] id (required): - Future?> getUserSessionsAdmin(String id,) async { - final response = await getUserSessionsAdminWithHttpInfo(id,); + Future?> getUserSessionsAdmin(String id, { Future? abortTrigger, }) async { + final response = await getUserSessionsAdminWithHttpInfo(id, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -324,7 +329,7 @@ class UsersAdminApi { /// Filter by trash status /// /// * [AssetVisibility] visibility: - Future getUserStatisticsAdminWithHttpInfo(String id, { bool? isFavorite, bool? isTrashed, AssetVisibility? visibility, }) async { + Future getUserStatisticsAdminWithHttpInfo(String id, { bool? isFavorite, bool? isTrashed, AssetVisibility? visibility, Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/admin/users/{id}/statistics' .replaceAll('{id}', id); @@ -357,6 +362,7 @@ class UsersAdminApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -375,8 +381,8 @@ class UsersAdminApi { /// Filter by trash status /// /// * [AssetVisibility] visibility: - Future getUserStatisticsAdmin(String id, { bool? isFavorite, bool? isTrashed, AssetVisibility? visibility, }) async { - final response = await getUserStatisticsAdminWithHttpInfo(id, isFavorite: isFavorite, isTrashed: isTrashed, visibility: visibility, ); + Future getUserStatisticsAdmin(String id, { bool? isFavorite, bool? isTrashed, AssetVisibility? visibility, Future? abortTrigger, }) async { + final response = await getUserStatisticsAdminWithHttpInfo(id, isFavorite: isFavorite, isTrashed: isTrashed, visibility: visibility, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -399,7 +405,7 @@ class UsersAdminApi { /// Parameters: /// /// * [String] id (required): - Future restoreUserAdminWithHttpInfo(String id,) async { + Future restoreUserAdminWithHttpInfo(String id, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/admin/users/{id}/restore' .replaceAll('{id}', id); @@ -422,6 +428,7 @@ class UsersAdminApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -432,8 +439,8 @@ class UsersAdminApi { /// Parameters: /// /// * [String] id (required): - Future restoreUserAdmin(String id,) async { - final response = await restoreUserAdminWithHttpInfo(id,); + Future restoreUserAdmin(String id, { Future? abortTrigger, }) async { + final response = await restoreUserAdminWithHttpInfo(id, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -460,7 +467,7 @@ class UsersAdminApi { /// /// * [bool] withDeleted: /// Include deleted users - Future searchUsersAdminWithHttpInfo({ String? id, bool? withDeleted, }) async { + Future searchUsersAdminWithHttpInfo({ String? id, bool? withDeleted, Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/admin/users'; @@ -489,6 +496,7 @@ class UsersAdminApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -503,8 +511,8 @@ class UsersAdminApi { /// /// * [bool] withDeleted: /// Include deleted users - Future?> searchUsersAdmin({ String? id, bool? withDeleted, }) async { - final response = await searchUsersAdminWithHttpInfo( id: id, withDeleted: withDeleted, ); + Future?> searchUsersAdmin({ String? id, bool? withDeleted, Future? abortTrigger, }) async { + final response = await searchUsersAdminWithHttpInfo(id: id, withDeleted: withDeleted, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -532,7 +540,7 @@ class UsersAdminApi { /// * [String] id (required): /// /// * [UserAdminUpdateDto] userAdminUpdateDto (required): - Future updateUserAdminWithHttpInfo(String id, UserAdminUpdateDto userAdminUpdateDto,) async { + Future updateUserAdminWithHttpInfo(String id, UserAdminUpdateDto userAdminUpdateDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/admin/users/{id}' .replaceAll('{id}', id); @@ -555,6 +563,7 @@ class UsersAdminApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -567,8 +576,8 @@ class UsersAdminApi { /// * [String] id (required): /// /// * [UserAdminUpdateDto] userAdminUpdateDto (required): - Future updateUserAdmin(String id, UserAdminUpdateDto userAdminUpdateDto,) async { - final response = await updateUserAdminWithHttpInfo(id, userAdminUpdateDto,); + Future updateUserAdmin(String id, UserAdminUpdateDto userAdminUpdateDto, { Future? abortTrigger, }) async { + final response = await updateUserAdminWithHttpInfo(id, userAdminUpdateDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -593,7 +602,7 @@ class UsersAdminApi { /// * [String] id (required): /// /// * [UserPreferencesUpdateDto] userPreferencesUpdateDto (required): - Future updateUserPreferencesAdminWithHttpInfo(String id, UserPreferencesUpdateDto userPreferencesUpdateDto,) async { + Future updateUserPreferencesAdminWithHttpInfo(String id, UserPreferencesUpdateDto userPreferencesUpdateDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/admin/users/{id}/preferences' .replaceAll('{id}', id); @@ -616,6 +625,7 @@ class UsersAdminApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -628,8 +638,8 @@ class UsersAdminApi { /// * [String] id (required): /// /// * [UserPreferencesUpdateDto] userPreferencesUpdateDto (required): - Future updateUserPreferencesAdmin(String id, UserPreferencesUpdateDto userPreferencesUpdateDto,) async { - final response = await updateUserPreferencesAdminWithHttpInfo(id, userPreferencesUpdateDto,); + Future updateUserPreferencesAdmin(String id, UserPreferencesUpdateDto userPreferencesUpdateDto, { Future? abortTrigger, }) async { + final response = await updateUserPreferencesAdminWithHttpInfo(id, userPreferencesUpdateDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } diff --git a/mobile/openapi/lib/api/users_api.dart b/mobile/openapi/lib/api/users_api.dart index 401cf4e94b..a7fac3ea66 100644 --- a/mobile/openapi/lib/api/users_api.dart +++ b/mobile/openapi/lib/api/users_api.dart @@ -26,7 +26,7 @@ class UsersApi { /// /// * [MultipartFile] file (required): /// Profile image file - Future createProfileImageWithHttpInfo(MultipartFile file,) async { + Future createProfileImageWithHttpInfo(MultipartFile file, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/users/profile-image'; @@ -58,6 +58,7 @@ class UsersApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -69,8 +70,8 @@ class UsersApi { /// /// * [MultipartFile] file (required): /// Profile image file - Future createProfileImage(MultipartFile file,) async { - final response = await createProfileImageWithHttpInfo(file,); + Future createProfileImage(MultipartFile file, { Future? abortTrigger, }) async { + final response = await createProfileImageWithHttpInfo(file, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -89,7 +90,7 @@ class UsersApi { /// Delete the profile image of the current user. /// /// Note: This method returns the HTTP [Response]. - Future deleteProfileImageWithHttpInfo() async { + Future deleteProfileImageWithHttpInfo({ Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/users/profile-image'; @@ -111,14 +112,15 @@ class UsersApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } /// Delete user profile image /// /// Delete the profile image of the current user. - Future deleteProfileImage() async { - final response = await deleteProfileImageWithHttpInfo(); + Future deleteProfileImage({ Future? abortTrigger, }) async { + final response = await deleteProfileImageWithHttpInfo(abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -129,7 +131,7 @@ class UsersApi { /// Delete the registered product key for the current user. /// /// Note: This method returns the HTTP [Response]. - Future deleteUserLicenseWithHttpInfo() async { + Future deleteUserLicenseWithHttpInfo({ Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/users/me/license'; @@ -151,14 +153,15 @@ class UsersApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } /// Delete user product key /// /// Delete the registered product key for the current user. - Future deleteUserLicense() async { - final response = await deleteUserLicenseWithHttpInfo(); + Future deleteUserLicense({ Future? abortTrigger, }) async { + final response = await deleteUserLicenseWithHttpInfo(abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -169,7 +172,7 @@ class UsersApi { /// Delete the onboarding status of the current user. /// /// Note: This method returns the HTTP [Response]. - Future deleteUserOnboardingWithHttpInfo() async { + Future deleteUserOnboardingWithHttpInfo({ Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/users/me/onboarding'; @@ -191,14 +194,15 @@ class UsersApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } /// Delete user onboarding /// /// Delete the onboarding status of the current user. - Future deleteUserOnboarding() async { - final response = await deleteUserOnboardingWithHttpInfo(); + Future deleteUserOnboarding({ Future? abortTrigger, }) async { + final response = await deleteUserOnboardingWithHttpInfo(abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -209,7 +213,7 @@ class UsersApi { /// Retrieve the preferences for the current user. /// /// Note: This method returns the HTTP [Response]. - Future getMyPreferencesWithHttpInfo() async { + Future getMyPreferencesWithHttpInfo({ Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/users/me/preferences'; @@ -231,14 +235,15 @@ class UsersApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } /// Get my preferences /// /// Retrieve the preferences for the current user. - Future getMyPreferences() async { - final response = await getMyPreferencesWithHttpInfo(); + Future getMyPreferences({ Future? abortTrigger, }) async { + final response = await getMyPreferencesWithHttpInfo(abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -257,7 +262,7 @@ class UsersApi { /// Retrieve information about the user making the API request. /// /// Note: This method returns the HTTP [Response]. - Future getMyUserWithHttpInfo() async { + Future getMyUserWithHttpInfo({ Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/users/me'; @@ -279,14 +284,15 @@ class UsersApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } /// Get current user /// /// Retrieve information about the user making the API request. - Future getMyUser() async { - final response = await getMyUserWithHttpInfo(); + Future getMyUser({ Future? abortTrigger, }) async { + final response = await getMyUserWithHttpInfo(abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -309,7 +315,7 @@ class UsersApi { /// Parameters: /// /// * [String] id (required): - Future getProfileImageWithHttpInfo(String id,) async { + Future getProfileImageWithHttpInfo(String id, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/users/{id}/profile-image' .replaceAll('{id}', id); @@ -332,6 +338,7 @@ class UsersApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -342,8 +349,8 @@ class UsersApi { /// Parameters: /// /// * [String] id (required): - Future getProfileImage(String id,) async { - final response = await getProfileImageWithHttpInfo(id,); + Future getProfileImage(String id, { Future? abortTrigger, }) async { + final response = await getProfileImageWithHttpInfo(id, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -366,7 +373,7 @@ class UsersApi { /// Parameters: /// /// * [String] id (required): - Future getUserWithHttpInfo(String id,) async { + Future getUserWithHttpInfo(String id, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/users/{id}' .replaceAll('{id}', id); @@ -389,6 +396,7 @@ class UsersApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -399,8 +407,8 @@ class UsersApi { /// Parameters: /// /// * [String] id (required): - Future getUser(String id,) async { - final response = await getUserWithHttpInfo(id,); + Future getUser(String id, { Future? abortTrigger, }) async { + final response = await getUserWithHttpInfo(id, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -419,7 +427,7 @@ class UsersApi { /// Retrieve information about whether the current user has a registered product key. /// /// Note: This method returns the HTTP [Response]. - Future getUserLicenseWithHttpInfo() async { + Future getUserLicenseWithHttpInfo({ Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/users/me/license'; @@ -441,14 +449,15 @@ class UsersApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } /// Retrieve user product key /// /// Retrieve information about whether the current user has a registered product key. - Future getUserLicense() async { - final response = await getUserLicenseWithHttpInfo(); + Future getUserLicense({ Future? abortTrigger, }) async { + final response = await getUserLicenseWithHttpInfo(abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -467,7 +476,7 @@ class UsersApi { /// Retrieve the onboarding status of the current user. /// /// Note: This method returns the HTTP [Response]. - Future getUserOnboardingWithHttpInfo() async { + Future getUserOnboardingWithHttpInfo({ Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/users/me/onboarding'; @@ -489,14 +498,15 @@ class UsersApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } /// Retrieve user onboarding /// /// Retrieve the onboarding status of the current user. - Future getUserOnboarding() async { - final response = await getUserOnboardingWithHttpInfo(); + Future getUserOnboarding({ Future? abortTrigger, }) async { + final response = await getUserOnboardingWithHttpInfo(abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -515,7 +525,7 @@ class UsersApi { /// Retrieve a list of all users on the server. /// /// Note: This method returns the HTTP [Response]. - Future searchUsersWithHttpInfo() async { + Future searchUsersWithHttpInfo({ Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/users'; @@ -537,14 +547,15 @@ class UsersApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } /// Get all users /// /// Retrieve a list of all users on the server. - Future?> searchUsers() async { - final response = await searchUsersWithHttpInfo(); + Future?> searchUsers({ Future? abortTrigger, }) async { + final response = await searchUsersWithHttpInfo(abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -570,7 +581,7 @@ class UsersApi { /// Parameters: /// /// * [LicenseKeyDto] licenseKeyDto (required): - Future setUserLicenseWithHttpInfo(LicenseKeyDto licenseKeyDto,) async { + Future setUserLicenseWithHttpInfo(LicenseKeyDto licenseKeyDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/users/me/license'; @@ -592,6 +603,7 @@ class UsersApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -602,8 +614,8 @@ class UsersApi { /// Parameters: /// /// * [LicenseKeyDto] licenseKeyDto (required): - Future setUserLicense(LicenseKeyDto licenseKeyDto,) async { - final response = await setUserLicenseWithHttpInfo(licenseKeyDto,); + Future setUserLicense(LicenseKeyDto licenseKeyDto, { Future? abortTrigger, }) async { + final response = await setUserLicenseWithHttpInfo(licenseKeyDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -626,7 +638,7 @@ class UsersApi { /// Parameters: /// /// * [OnboardingDto] onboardingDto (required): - Future setUserOnboardingWithHttpInfo(OnboardingDto onboardingDto,) async { + Future setUserOnboardingWithHttpInfo(OnboardingDto onboardingDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/users/me/onboarding'; @@ -648,6 +660,7 @@ class UsersApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -658,8 +671,8 @@ class UsersApi { /// Parameters: /// /// * [OnboardingDto] onboardingDto (required): - Future setUserOnboarding(OnboardingDto onboardingDto,) async { - final response = await setUserOnboardingWithHttpInfo(onboardingDto,); + Future setUserOnboarding(OnboardingDto onboardingDto, { Future? abortTrigger, }) async { + final response = await setUserOnboardingWithHttpInfo(onboardingDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -682,7 +695,7 @@ class UsersApi { /// Parameters: /// /// * [UserPreferencesUpdateDto] userPreferencesUpdateDto (required): - Future updateMyPreferencesWithHttpInfo(UserPreferencesUpdateDto userPreferencesUpdateDto,) async { + Future updateMyPreferencesWithHttpInfo(UserPreferencesUpdateDto userPreferencesUpdateDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/users/me/preferences'; @@ -704,6 +717,7 @@ class UsersApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -714,8 +728,8 @@ class UsersApi { /// Parameters: /// /// * [UserPreferencesUpdateDto] userPreferencesUpdateDto (required): - Future updateMyPreferences(UserPreferencesUpdateDto userPreferencesUpdateDto,) async { - final response = await updateMyPreferencesWithHttpInfo(userPreferencesUpdateDto,); + Future updateMyPreferences(UserPreferencesUpdateDto userPreferencesUpdateDto, { Future? abortTrigger, }) async { + final response = await updateMyPreferencesWithHttpInfo(userPreferencesUpdateDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -738,7 +752,7 @@ class UsersApi { /// Parameters: /// /// * [UserUpdateMeDto] userUpdateMeDto (required): - Future updateMyUserWithHttpInfo(UserUpdateMeDto userUpdateMeDto,) async { + Future updateMyUserWithHttpInfo(UserUpdateMeDto userUpdateMeDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/users/me'; @@ -760,6 +774,7 @@ class UsersApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -770,8 +785,8 @@ class UsersApi { /// Parameters: /// /// * [UserUpdateMeDto] userUpdateMeDto (required): - Future updateMyUser(UserUpdateMeDto userUpdateMeDto,) async { - final response = await updateMyUserWithHttpInfo(userUpdateMeDto,); + Future updateMyUser(UserUpdateMeDto userUpdateMeDto, { Future? abortTrigger, }) async { + final response = await updateMyUserWithHttpInfo(userUpdateMeDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } diff --git a/mobile/openapi/lib/api/views_api.dart b/mobile/openapi/lib/api/views_api.dart index a45e89d58f..3ccbacb650 100644 --- a/mobile/openapi/lib/api/views_api.dart +++ b/mobile/openapi/lib/api/views_api.dart @@ -25,7 +25,7 @@ class ViewsApi { /// Parameters: /// /// * [String] path (required): - Future getAssetsByOriginalPathWithHttpInfo(String path,) async { + Future getAssetsByOriginalPathWithHttpInfo(String path, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/view/folder'; @@ -49,6 +49,7 @@ class ViewsApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -59,8 +60,8 @@ class ViewsApi { /// Parameters: /// /// * [String] path (required): - Future?> getAssetsByOriginalPath(String path,) async { - final response = await getAssetsByOriginalPathWithHttpInfo(path,); + Future?> getAssetsByOriginalPath(String path, { Future? abortTrigger, }) async { + final response = await getAssetsByOriginalPathWithHttpInfo(path, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -82,7 +83,7 @@ class ViewsApi { /// Retrieve a list of unique folder paths from asset original paths. /// /// Note: This method returns the HTTP [Response]. - Future getUniqueOriginalPathsWithHttpInfo() async { + Future getUniqueOriginalPathsWithHttpInfo({ Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/view/folder/unique-paths'; @@ -104,14 +105,15 @@ class ViewsApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } /// Retrieve unique paths /// /// Retrieve a list of unique folder paths from asset original paths. - Future?> getUniqueOriginalPaths() async { - final response = await getUniqueOriginalPathsWithHttpInfo(); + Future?> getUniqueOriginalPaths({ Future? abortTrigger, }) async { + final response = await getUniqueOriginalPathsWithHttpInfo(abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } diff --git a/mobile/openapi/lib/api/workflows_api.dart b/mobile/openapi/lib/api/workflows_api.dart index 12b33b7238..4b27acd624 100644 --- a/mobile/openapi/lib/api/workflows_api.dart +++ b/mobile/openapi/lib/api/workflows_api.dart @@ -25,7 +25,7 @@ class WorkflowsApi { /// Parameters: /// /// * [WorkflowCreateDto] workflowCreateDto (required): - Future createWorkflowWithHttpInfo(WorkflowCreateDto workflowCreateDto,) async { + Future createWorkflowWithHttpInfo(WorkflowCreateDto workflowCreateDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/workflows'; @@ -47,6 +47,7 @@ class WorkflowsApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -57,8 +58,8 @@ class WorkflowsApi { /// Parameters: /// /// * [WorkflowCreateDto] workflowCreateDto (required): - Future createWorkflow(WorkflowCreateDto workflowCreateDto,) async { - final response = await createWorkflowWithHttpInfo(workflowCreateDto,); + Future createWorkflow(WorkflowCreateDto workflowCreateDto, { Future? abortTrigger, }) async { + final response = await createWorkflowWithHttpInfo(workflowCreateDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -81,7 +82,7 @@ class WorkflowsApi { /// Parameters: /// /// * [String] id (required): - Future deleteWorkflowWithHttpInfo(String id,) async { + Future deleteWorkflowWithHttpInfo(String id, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/workflows/{id}' .replaceAll('{id}', id); @@ -104,6 +105,7 @@ class WorkflowsApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -114,8 +116,8 @@ class WorkflowsApi { /// Parameters: /// /// * [String] id (required): - Future deleteWorkflow(String id,) async { - final response = await deleteWorkflowWithHttpInfo(id,); + Future deleteWorkflow(String id, { Future? abortTrigger, }) async { + final response = await deleteWorkflowWithHttpInfo(id, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -130,7 +132,7 @@ class WorkflowsApi { /// Parameters: /// /// * [String] id (required): - Future getWorkflowWithHttpInfo(String id,) async { + Future getWorkflowWithHttpInfo(String id, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/workflows/{id}' .replaceAll('{id}', id); @@ -153,6 +155,7 @@ class WorkflowsApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -163,8 +166,8 @@ class WorkflowsApi { /// Parameters: /// /// * [String] id (required): - Future getWorkflow(String id,) async { - final response = await getWorkflowWithHttpInfo(id,); + Future getWorkflow(String id, { Future? abortTrigger, }) async { + final response = await getWorkflowWithHttpInfo(id, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -187,7 +190,7 @@ class WorkflowsApi { /// Parameters: /// /// * [String] id (required): - Future getWorkflowForShareWithHttpInfo(String id,) async { + Future getWorkflowForShareWithHttpInfo(String id, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/workflows/{id}/share' .replaceAll('{id}', id); @@ -210,6 +213,7 @@ class WorkflowsApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -220,8 +224,8 @@ class WorkflowsApi { /// Parameters: /// /// * [String] id (required): - Future getWorkflowForShare(String id,) async { - final response = await getWorkflowForShareWithHttpInfo(id,); + Future getWorkflowForShare(String id, { Future? abortTrigger, }) async { + final response = await getWorkflowForShareWithHttpInfo(id, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -240,7 +244,7 @@ class WorkflowsApi { /// Retrieve a list of all available workflow triggers. /// /// Note: This method returns the HTTP [Response]. - Future getWorkflowTriggersWithHttpInfo() async { + Future getWorkflowTriggersWithHttpInfo({ Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/workflows/triggers'; @@ -262,14 +266,15 @@ class WorkflowsApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } /// List all workflow triggers /// /// Retrieve a list of all available workflow triggers. - Future?> getWorkflowTriggers() async { - final response = await getWorkflowTriggersWithHttpInfo(); + Future?> getWorkflowTriggers({ Future? abortTrigger, }) async { + final response = await getWorkflowTriggersWithHttpInfo(abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -308,7 +313,7 @@ class WorkflowsApi { /// /// * [WorkflowTrigger] trigger: /// Workflow trigger type - Future searchWorkflowsWithHttpInfo({ String? description, bool? enabled, String? id, String? name, WorkflowTrigger? trigger, }) async { + Future searchWorkflowsWithHttpInfo({ String? description, bool? enabled, String? id, String? name, WorkflowTrigger? trigger, Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/workflows'; @@ -346,6 +351,7 @@ class WorkflowsApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -369,8 +375,8 @@ class WorkflowsApi { /// /// * [WorkflowTrigger] trigger: /// Workflow trigger type - Future?> searchWorkflows({ String? description, bool? enabled, String? id, String? name, WorkflowTrigger? trigger, }) async { - final response = await searchWorkflowsWithHttpInfo( description: description, enabled: enabled, id: id, name: name, trigger: trigger, ); + Future?> searchWorkflows({ String? description, bool? enabled, String? id, String? name, WorkflowTrigger? trigger, Future? abortTrigger, }) async { + final response = await searchWorkflowsWithHttpInfo(description: description, enabled: enabled, id: id, name: name, trigger: trigger, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } @@ -398,7 +404,7 @@ class WorkflowsApi { /// * [String] id (required): /// /// * [WorkflowUpdateDto] workflowUpdateDto (required): - Future updateWorkflowWithHttpInfo(String id, WorkflowUpdateDto workflowUpdateDto,) async { + Future updateWorkflowWithHttpInfo(String id, WorkflowUpdateDto workflowUpdateDto, { Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'/workflows/{id}' .replaceAll('{id}', id); @@ -421,6 +427,7 @@ class WorkflowsApi { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -433,8 +440,8 @@ class WorkflowsApi { /// * [String] id (required): /// /// * [WorkflowUpdateDto] workflowUpdateDto (required): - Future updateWorkflow(String id, WorkflowUpdateDto workflowUpdateDto,) async { - final response = await updateWorkflowWithHttpInfo(id, workflowUpdateDto,); + Future updateWorkflow(String id, WorkflowUpdateDto workflowUpdateDto, { Future? abortTrigger, }) async { + final response = await updateWorkflowWithHttpInfo(id, workflowUpdateDto, abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } diff --git a/mobile/openapi/lib/model/job_name.dart b/mobile/openapi/lib/model/job_name.dart index 444b080c12..511e1158e9 100644 --- a/mobile/openapi/lib/model/job_name.dart +++ b/mobile/openapi/lib/model/job_name.dart @@ -77,7 +77,7 @@ class JobName { static const versionCheck = JobName._(r'VersionCheck'); static const ocrQueueAll = JobName._(r'OcrQueueAll'); static const ocr = JobName._(r'Ocr'); - static const workflowAssetCreate = JobName._(r'WorkflowAssetCreate'); + static const workflowAssetTrigger = JobName._(r'WorkflowAssetTrigger'); /// List of all possible values in this [enum][JobName]. static const values = [ @@ -135,7 +135,7 @@ class JobName { versionCheck, ocrQueueAll, ocr, - workflowAssetCreate, + workflowAssetTrigger, ]; static JobName? fromJson(dynamic value) => JobNameTypeTransformer().decode(value); @@ -228,7 +228,7 @@ class JobNameTypeTransformer { case r'VersionCheck': return JobName.versionCheck; case r'OcrQueueAll': return JobName.ocrQueueAll; case r'Ocr': return JobName.ocr; - case r'WorkflowAssetCreate': return JobName.workflowAssetCreate; + case r'WorkflowAssetTrigger': return JobName.workflowAssetTrigger; default: if (!allowNull) { throw ArgumentError('Unknown enum value to decode: $data'); diff --git a/mobile/openapi/lib/model/plugin_template_response_dto.dart b/mobile/openapi/lib/model/plugin_template_response_dto.dart new file mode 100644 index 0000000000..9f54753f49 --- /dev/null +++ b/mobile/openapi/lib/model/plugin_template_response_dto.dart @@ -0,0 +1,146 @@ +// +// 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 PluginTemplateResponseDto { + /// Returns a new [PluginTemplateResponseDto] instance. + PluginTemplateResponseDto({ + required this.description, + required this.key, + this.steps = const [], + required this.title, + required this.trigger, + this.uiHints = const [], + }); + + /// Template description + String description; + + /// Template key (unique across all templates) + String key; + + /// Workflow steps + List steps; + + /// Template title + String title; + + WorkflowTrigger trigger; + + /// Ui hints, for example \"smart-album\" + List uiHints; + + @override + bool operator ==(Object other) => identical(this, other) || other is PluginTemplateResponseDto && + other.description == description && + other.key == key && + _deepEquality.equals(other.steps, steps) && + other.title == title && + other.trigger == trigger && + _deepEquality.equals(other.uiHints, uiHints); + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (description.hashCode) + + (key.hashCode) + + (steps.hashCode) + + (title.hashCode) + + (trigger.hashCode) + + (uiHints.hashCode); + + @override + String toString() => 'PluginTemplateResponseDto[description=$description, key=$key, steps=$steps, title=$title, trigger=$trigger, uiHints=$uiHints]'; + + Map toJson() { + final json = {}; + json[r'description'] = this.description; + json[r'key'] = this.key; + json[r'steps'] = this.steps; + json[r'title'] = this.title; + json[r'trigger'] = this.trigger; + json[r'uiHints'] = this.uiHints; + return json; + } + + /// Returns a new [PluginTemplateResponseDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static PluginTemplateResponseDto? fromJson(dynamic value) { + upgradeDto(value, "PluginTemplateResponseDto"); + if (value is Map) { + final json = value.cast(); + + return PluginTemplateResponseDto( + description: mapValueOfType(json, r'description')!, + key: mapValueOfType(json, r'key')!, + steps: PluginTemplateStepResponseDto.listFromJson(json[r'steps']), + title: mapValueOfType(json, r'title')!, + trigger: WorkflowTrigger.fromJson(json[r'trigger'])!, + uiHints: json[r'uiHints'] is Iterable + ? (json[r'uiHints'] as Iterable).cast().toList(growable: false) + : const [], + ); + } + 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 = PluginTemplateResponseDto.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 = PluginTemplateResponseDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of PluginTemplateResponseDto-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] = PluginTemplateResponseDto.listFromJson(entry.value, growable: growable,); + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'description', + 'key', + 'steps', + 'title', + 'trigger', + 'uiHints', + }; +} + diff --git a/mobile/openapi/lib/model/plugin_template_step_response_dto.dart b/mobile/openapi/lib/model/plugin_template_step_response_dto.dart new file mode 100644 index 0000000000..b58884d1cd --- /dev/null +++ b/mobile/openapi/lib/model/plugin_template_step_response_dto.dart @@ -0,0 +1,131 @@ +// +// 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 PluginTemplateStepResponseDto { + /// Returns a new [PluginTemplateStepResponseDto] instance. + PluginTemplateStepResponseDto({ + this.config = const {}, + this.enabled, + required this.method, + }); + + /// Step configuration + Map? config; + + /// Whether the step is enabled + /// + /// 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. + /// + bool? enabled; + + /// Step plugin method + String method; + + @override + bool operator ==(Object other) => identical(this, other) || other is PluginTemplateStepResponseDto && + _deepEquality.equals(other.config, config) && + other.enabled == enabled && + other.method == method; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (config == null ? 0 : config!.hashCode) + + (enabled == null ? 0 : enabled!.hashCode) + + (method.hashCode); + + @override + String toString() => 'PluginTemplateStepResponseDto[config=$config, enabled=$enabled, method=$method]'; + + Map toJson() { + final json = {}; + if (this.config != null) { + json[r'config'] = this.config; + } else { + // json[r'config'] = null; + } + if (this.enabled != null) { + json[r'enabled'] = this.enabled; + } else { + // json[r'enabled'] = null; + } + json[r'method'] = this.method; + return json; + } + + /// Returns a new [PluginTemplateStepResponseDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static PluginTemplateStepResponseDto? fromJson(dynamic value) { + upgradeDto(value, "PluginTemplateStepResponseDto"); + if (value is Map) { + final json = value.cast(); + + return PluginTemplateStepResponseDto( + config: mapCastOfType(json, r'config'), + enabled: mapValueOfType(json, r'enabled'), + method: mapValueOfType(json, r'method')!, + ); + } + 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 = PluginTemplateStepResponseDto.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 = PluginTemplateStepResponseDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of PluginTemplateStepResponseDto-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] = PluginTemplateStepResponseDto.listFromJson(entry.value, growable: growable,); + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'config', + 'method', + }; +} + diff --git a/mobile/openapi/lib/model/time_bucket_asset_response_dto.dart b/mobile/openapi/lib/model/time_bucket_asset_response_dto.dart index 45e793e9e3..32e08a9ea0 100644 --- a/mobile/openapi/lib/model/time_bucket_asset_response_dto.dart +++ b/mobile/openapi/lib/model/time_bucket_asset_response_dto.dart @@ -276,8 +276,6 @@ class TimeBucketAssetResponseDto { /// The list of required keys that must be present in a JSON. static const requiredKeys = { - 'city', - 'country', 'createdAt', 'duration', 'fileCreatedAt', diff --git a/mobile/openapi/lib/model/workflow_trigger.dart b/mobile/openapi/lib/model/workflow_trigger.dart index 47bf95e05e..b56d1b0dba 100644 --- a/mobile/openapi/lib/model/workflow_trigger.dart +++ b/mobile/openapi/lib/model/workflow_trigger.dart @@ -24,11 +24,13 @@ class WorkflowTrigger { String toJson() => value; static const assetCreate = WorkflowTrigger._(r'AssetCreate'); + static const assetMetadataExtraction = WorkflowTrigger._(r'AssetMetadataExtraction'); static const personRecognized = WorkflowTrigger._(r'PersonRecognized'); /// List of all possible values in this [enum][WorkflowTrigger]. static const values = [ assetCreate, + assetMetadataExtraction, personRecognized, ]; @@ -69,6 +71,7 @@ class WorkflowTriggerTypeTransformer { if (data != null) { switch (data) { case r'AssetCreate': return WorkflowTrigger.assetCreate; + case r'AssetMetadataExtraction': return WorkflowTrigger.assetMetadataExtraction; case r'PersonRecognized': return WorkflowTrigger.personRecognized; default: if (!allowNull) { diff --git a/mobile/packages/ui/lib/src/components/form.dart b/mobile/packages/ui/lib/src/components/form.dart index 4d0344ae6b..31e9d01980 100644 --- a/mobile/packages/ui/lib/src/components/form.dart +++ b/mobile/packages/ui/lib/src/components/form.dart @@ -10,9 +10,16 @@ class ImmichFormController extends ChangeNotifier { FutureOr Function()? onSubmit; final formKey = GlobalKey(); + bool _isDisposed = false; bool _isLoading = false; bool get isLoading => _isLoading; + @override + void dispose() { + _isDisposed = true; + super.dispose(); + } + Future submit() async { if (_isLoading) { return; @@ -27,7 +34,9 @@ class ImmichFormController extends ChangeNotifier { await onSubmit?.call(); } finally { _isLoading = false; - notifyListeners(); + if (!_isDisposed) { + notifyListeners(); + } } } } @@ -38,13 +47,7 @@ class ImmichForm extends StatefulWidget { final String? submitText; final IconData? submitIcon; - const ImmichForm({ - super.key, - this.onSubmit, - this.submitText, - this.submitIcon, - required this.builder, - }); + const ImmichForm({super.key, this.onSubmit, this.submitText, this.submitIcon, required this.builder}); @override State createState() => _ImmichFormState(); diff --git a/mobile/packages/ui/lib/src/previews.dart b/mobile/packages/ui/lib/src/previews.dart new file mode 100644 index 0000000000..076bc253c9 --- /dev/null +++ b/mobile/packages/ui/lib/src/previews.dart @@ -0,0 +1,60 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/widget_previews.dart'; +import 'package:immich_ui/src/theme.dart'; + +const ColorScheme _lightColorScheme = ColorScheme.light( + primary: Color(0xFF4250AF), + onPrimary: Colors.white, + primaryContainer: Color(0xFFD4D6F0), + onPrimaryContainer: Color(0xFF181E44), + secondary: Color(0xFF737373), + onSecondary: Colors.white, + error: Color(0xFFE53E3E), + onError: Colors.white, + surface: Color(0xFFFAFAFA), + onSurface: Color(0xFF1A1C1E), + surfaceContainerHighest: Color(0xFFE3E4E8), + outline: Color(0xFFD1D3D9), + outlineVariant: Color(0xFFD4D4D4), +); + +const ColorScheme _darkColorScheme = ColorScheme.dark( + primary: Color(0xFFACCBFA), + onPrimary: Color(0xFF0F1433), + primaryContainer: Color(0xFF616D94), + onPrimaryContainer: Color(0xFFD4D6F0), + secondary: Color(0xFFC4C6D0), + onSecondary: Color(0xFF2E3042), + error: Color(0xFFE88080), + onError: Color(0xFF0F1433), + surface: Color(0xFF0A0A0A), + onSurface: Color(0xFFE3E3E6), + surfaceContainerHighest: Color(0xFF262626), + outline: Color(0xFF8E9099), + outlineVariant: Color(0xFF43464F), +); + +PreviewThemeData immichPreviewTheme() => PreviewThemeData( + materialLight: ThemeData(colorScheme: _lightColorScheme, useMaterial3: true), + materialDark: ThemeData(colorScheme: _darkColorScheme, useMaterial3: true), + ); + +Widget immichPreviewWrapper(Widget child) { + return Builder( + builder: (context) => ImmichThemeProvider( + colorScheme: Theme.of(context).colorScheme, + child: Scaffold( + backgroundColor: Theme.of(context).colorScheme.surface, + body: Padding( + padding: const EdgeInsets.all(16), + child: Align(alignment: Alignment.topLeft, child: child), + ), + ), + ), + ); +} + +final class ImmichPreview extends Preview { + const ImmichPreview({super.name, super.group, super.size, super.textScaleFactor}) + : super(theme: immichPreviewTheme, wrapper: immichPreviewWrapper); +} diff --git a/mobile/packages/ui/lib/src/previews/close_button.dart b/mobile/packages/ui/lib/src/previews/close_button.dart new file mode 100644 index 0000000000..678d6bed18 --- /dev/null +++ b/mobile/packages/ui/lib/src/previews/close_button.dart @@ -0,0 +1,26 @@ +import 'package:flutter/material.dart'; +import 'package:immich_ui/src/components/close_button.dart'; +import 'package:immich_ui/src/previews.dart'; +import 'package:immich_ui/src/types.dart'; + +void _previewNoop() {} + +@ImmichPreview(group: 'CloseButton', name: 'Variants') +Widget previewCloseButtonVariants() => const Wrap( + spacing: 12, + runSpacing: 12, + children: [ + ImmichCloseButton(onPressed: _previewNoop), + ImmichCloseButton(onPressed: _previewNoop, variant: ImmichVariant.filled), + ], + ); + +@ImmichPreview(group: 'CloseButton', name: 'Colors') +Widget previewCloseButtonColors() => const Wrap( + spacing: 12, + runSpacing: 12, + children: [ + ImmichCloseButton(onPressed: _previewNoop), + ImmichCloseButton(onPressed: _previewNoop, color: ImmichColor.secondary), + ], + ); diff --git a/mobile/packages/ui/lib/src/previews/form.dart b/mobile/packages/ui/lib/src/previews/form.dart new file mode 100644 index 0000000000..9e488cfd68 --- /dev/null +++ b/mobile/packages/ui/lib/src/previews/form.dart @@ -0,0 +1,72 @@ +import 'package:flutter/material.dart'; +import 'package:immich_ui/src/components/form.dart'; +import 'package:immich_ui/src/components/password_input.dart'; +import 'package:immich_ui/src/components/text_input.dart'; +import 'package:immich_ui/src/constants.dart'; +import 'package:immich_ui/src/previews.dart'; + +@ImmichPreview(group: 'Form', name: 'Login Form') +Widget previewFormLogin() => const _PreviewLoginForm(); + +class _PreviewLoginForm extends StatefulWidget { + const _PreviewLoginForm(); + + @override + State<_PreviewLoginForm> createState() => _PreviewLoginFormState(); +} + +class _PreviewLoginFormState extends State<_PreviewLoginForm> { + final _emailController = TextEditingController(); + final _passwordController = TextEditingController(); + String _result = ''; + + @override + void dispose() { + _emailController.dispose(); + _passwordController.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + ImmichForm( + submitText: 'Login', + submitIcon: Icons.login, + onSubmit: () async { + await Future.delayed(const Duration(seconds: 1)); + if (!mounted) { + return; + } + setState(() { + _result = 'Form submitted!'; + }); + }, + builder: (context, form) => Column( + spacing: ImmichSpacing.sm, + children: [ + ImmichTextInput( + label: 'Email', + controller: _emailController, + keyboardType: TextInputType.emailAddress, + validator: (value) => value?.isEmpty ?? true ? 'Required' : null, + ), + ImmichPasswordInput( + label: 'Password', + controller: _passwordController, + validator: (value) => value?.isEmpty ?? true ? 'Required' : null, + onSubmit: (_) => form.submit(), + ), + ], + ), + ), + if (_result.isNotEmpty) ...[ + const SizedBox(height: 16), + Text(_result, style: const TextStyle(color: Colors.green)), + ], + ], + ); + } +} diff --git a/mobile/packages/ui/lib/src/previews/formatted_text.dart b/mobile/packages/ui/lib/src/previews/formatted_text.dart new file mode 100644 index 0000000000..9ef3b4b851 --- /dev/null +++ b/mobile/packages/ui/lib/src/previews/formatted_text.dart @@ -0,0 +1,50 @@ +import 'package:flutter/material.dart'; +import 'package:immich_ui/src/components/formatted_text.dart'; +import 'package:immich_ui/src/previews.dart'; + +@ImmichPreview(group: 'FormattedText', name: 'Bold') +Widget previewFormattedTextBold() => const ImmichFormattedText('This is bold text.'); + +@ImmichPreview(group: 'FormattedText', name: 'Links') +Widget previewFormattedTextLinks() => const _PreviewFormattedTextLinks(); + +@ImmichPreview(group: 'FormattedText', name: 'Mixed Content') +Widget previewFormattedTextMixed() => const _PreviewFormattedTextMixed(); + +class _PreviewFormattedTextLinks extends StatelessWidget { + const _PreviewFormattedTextLinks(); + + @override + Widget build(BuildContext context) { + return ImmichFormattedText( + 'Read the documentation or visit GitHub.', + spanBuilder: (tag) => FormattedSpan( + onTap: switch (tag) { + 'docs-link' => + () => ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('Docs link clicked!'))), + 'github-link' => + () => ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('GitHub link clicked!'))), + _ => null, + }, + ), + ); + } +} + +class _PreviewFormattedTextMixed extends StatelessWidget { + const _PreviewFormattedTextMixed(); + + @override + Widget build(BuildContext context) { + return ImmichFormattedText( + 'You can use bold text and links together.', + spanBuilder: (tag) => switch (tag) { + 'b' => const FormattedSpan(style: TextStyle(fontWeight: FontWeight.bold)), + _ => FormattedSpan( + onTap: () => + ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('Link clicked!'))), + ), + }, + ); + } +} diff --git a/mobile/packages/ui/lib/src/previews/icon_button.dart b/mobile/packages/ui/lib/src/previews/icon_button.dart new file mode 100644 index 0000000000..6a0196bc81 --- /dev/null +++ b/mobile/packages/ui/lib/src/previews/icon_button.dart @@ -0,0 +1,41 @@ +import 'package:flutter/material.dart'; +import 'package:immich_ui/src/components/icon_button.dart'; +import 'package:immich_ui/src/previews.dart'; +import 'package:immich_ui/src/types.dart'; + +void _previewNoop() {} + +@ImmichPreview(group: 'IconButton', name: 'Variants') +Widget previewIconButtonVariants() => const Wrap( + spacing: 12, + runSpacing: 12, + children: [ + ImmichIconButton(icon: Icons.add, onPressed: _previewNoop), + ImmichIconButton(icon: Icons.edit, onPressed: _previewNoop, variant: ImmichVariant.ghost), + ], + ); + +@ImmichPreview(group: 'IconButton', name: 'Colors') +Widget previewIconButtonColors() => const Wrap( + spacing: 12, + runSpacing: 12, + children: [ + ImmichIconButton(icon: Icons.favorite, onPressed: _previewNoop), + ImmichIconButton(icon: Icons.delete, onPressed: _previewNoop, color: ImmichColor.secondary), + ], + ); + +@ImmichPreview(group: 'IconButton', name: 'Disabled') +Widget previewIconButtonDisabled() => const Wrap( + spacing: 12, + runSpacing: 12, + children: [ + ImmichIconButton(icon: Icons.settings, onPressed: _previewNoop, disabled: true), + ImmichIconButton( + icon: Icons.settings, + onPressed: _previewNoop, + disabled: true, + variant: ImmichVariant.ghost, + ), + ], + ); diff --git a/mobile/packages/ui/lib/src/previews/password_input.dart b/mobile/packages/ui/lib/src/previews/password_input.dart new file mode 100644 index 0000000000..72bd9cbfc5 --- /dev/null +++ b/mobile/packages/ui/lib/src/previews/password_input.dart @@ -0,0 +1,18 @@ +import 'package:flutter/material.dart'; +import 'package:immich_ui/src/components/password_input.dart'; +import 'package:immich_ui/src/previews.dart'; + +@ImmichPreview(group: 'PasswordInput', name: 'With Validator') +Widget previewPasswordInput() => ImmichPasswordInput( + label: 'Password', + hintText: 'Enter your password', + validator: (value) { + if (value == null || value.isEmpty) { + return 'Password is required'; + } + if (value.length < 8) { + return 'Password must be at least 8 characters'; + } + return null; + }, + ); diff --git a/mobile/packages/ui/lib/src/previews/text_button.dart b/mobile/packages/ui/lib/src/previews/text_button.dart new file mode 100644 index 0000000000..46c689bbae --- /dev/null +++ b/mobile/packages/ui/lib/src/previews/text_button.dart @@ -0,0 +1,88 @@ +import 'package:flutter/material.dart'; +import 'package:immich_ui/src/components/text_button.dart'; +import 'package:immich_ui/src/previews.dart'; +import 'package:immich_ui/src/types.dart'; + +void _previewNoop() {} + +@ImmichPreview(group: 'TextButton', name: 'Variants') +Widget previewTextButtonVariants() => const Wrap( + spacing: 12, + runSpacing: 12, + children: [ + ImmichTextButton(onPressed: _previewNoop, labelText: 'Filled', expanded: false), + ImmichTextButton(onPressed: _previewNoop, labelText: 'Ghost', variant: ImmichVariant.ghost, expanded: false), + ], +); + +@ImmichPreview(group: 'TextButton', name: 'Colors') +Widget previewTextButtonColors() => const Wrap( + spacing: 12, + runSpacing: 12, + children: [ + ImmichTextButton(onPressed: _previewNoop, labelText: 'Primary', expanded: false), + ImmichTextButton(onPressed: _previewNoop, labelText: 'Secondary', color: ImmichColor.secondary, expanded: false), + ], +); + +@ImmichPreview(group: 'TextButton', name: 'With Icons') +Widget previewTextButtonWithIcons() => const Wrap( + spacing: 12, + runSpacing: 12, + children: [ + ImmichTextButton(onPressed: _previewNoop, labelText: 'With Icon', icon: Icons.add, expanded: false), + ImmichTextButton( + onPressed: _previewNoop, + labelText: 'Download', + icon: Icons.download, + variant: ImmichVariant.ghost, + expanded: false, + ), + ], +); + +@ImmichPreview(group: 'TextButton', name: 'Loading') +Widget previewTextButtonLoading() => const _PreviewLoadingDemo(); + +@ImmichPreview(group: 'TextButton', name: 'Disabled') +Widget previewTextButtonDisabled() => const Wrap( + spacing: 12, + runSpacing: 12, + children: [ + ImmichTextButton(onPressed: _previewNoop, labelText: 'Disabled', disabled: true, expanded: false), + ImmichTextButton( + onPressed: _previewNoop, + labelText: 'Disabled Ghost', + variant: ImmichVariant.ghost, + disabled: true, + expanded: false, + ), + ], +); + +class _PreviewLoadingDemo extends StatefulWidget { + const _PreviewLoadingDemo(); + + @override + State<_PreviewLoadingDemo> createState() => _PreviewLoadingDemoState(); +} + +class _PreviewLoadingDemoState extends State<_PreviewLoadingDemo> { + bool _isLoading = false; + + @override + Widget build(BuildContext context) { + return ImmichTextButton( + onPressed: () async { + setState(() => _isLoading = true); + await Future.delayed(const Duration(seconds: 2)); + if (mounted) { + setState(() => _isLoading = false); + } + }, + labelText: _isLoading ? 'Loading...' : 'Click Me', + loading: _isLoading, + expanded: false, + ); + } +} diff --git a/mobile/packages/ui/lib/src/previews/text_input.dart b/mobile/packages/ui/lib/src/previews/text_input.dart new file mode 100644 index 0000000000..fab58c8cc4 --- /dev/null +++ b/mobile/packages/ui/lib/src/previews/text_input.dart @@ -0,0 +1,71 @@ +import 'package:flutter/material.dart'; +import 'package:immich_ui/src/components/text_input.dart'; +import 'package:immich_ui/src/previews.dart'; + +@ImmichPreview(group: 'TextInput', name: 'Basic') +Widget previewTextInputBasic() => const _PreviewTextInputBasic(); + +@ImmichPreview(group: 'TextInput', name: 'With Validator') +Widget previewTextInputValidator() => const _PreviewTextInputValidator(); + +class _PreviewTextInputBasic extends StatefulWidget { + const _PreviewTextInputBasic(); + + @override + State<_PreviewTextInputBasic> createState() => _PreviewTextInputBasicState(); +} + +class _PreviewTextInputBasicState extends State<_PreviewTextInputBasic> { + final _controller = TextEditingController(); + + @override + void dispose() { + _controller.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return ImmichTextInput( + label: 'Email', + hintText: 'Enter your email', + controller: _controller, + keyboardType: TextInputType.emailAddress, + ); + } +} + +class _PreviewTextInputValidator extends StatefulWidget { + const _PreviewTextInputValidator(); + + @override + State<_PreviewTextInputValidator> createState() => _PreviewTextInputValidatorState(); +} + +class _PreviewTextInputValidatorState extends State<_PreviewTextInputValidator> { + final _controller = TextEditingController(); + + @override + void dispose() { + _controller.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return ImmichTextInput( + label: 'Username', + controller: _controller, + autovalidateMode: AutovalidateMode.onUserInteraction, + validator: (value) { + if (value == null || value.isEmpty) { + return 'Username is required'; + } + if (value.length < 3) { + return 'Username must be at least 3 characters'; + } + return null; + }, + ); + } +} diff --git a/mobile/packages/ui/lib/src/previews/url_input.dart b/mobile/packages/ui/lib/src/previews/url_input.dart new file mode 100644 index 0000000000..6819ac5796 --- /dev/null +++ b/mobile/packages/ui/lib/src/previews/url_input.dart @@ -0,0 +1,28 @@ +import 'package:flutter/material.dart'; +import 'package:immich_ui/src/components/url_input.dart'; +import 'package:immich_ui/src/previews.dart'; + +@ImmichPreview(group: 'URLInput', name: 'Basic') +Widget previewUrlInput() => const _PreviewUrlInput(); + +class _PreviewUrlInput extends StatefulWidget { + const _PreviewUrlInput(); + + @override + State<_PreviewUrlInput> createState() => _PreviewUrlInputState(); +} + +class _PreviewUrlInputState extends State<_PreviewUrlInput> { + final _controller = TextEditingController(); + + @override + void dispose() { + _controller.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return ImmichURLInput(label: 'Server URL', hintText: 'https://demo.immich.com', controller: _controller); + } +} diff --git a/mobile/packages/ui/pubspec.lock b/mobile/packages/ui/pubspec.lock index 4ac863d0f7..9d11b49253 100644 --- a/mobile/packages/ui/pubspec.lock +++ b/mobile/packages/ui/pubspec.lock @@ -5,10 +5,10 @@ packages: dependency: transitive description: name: async - sha256: "758e6d74e971c3e5aceb4110bfd6698efc7f501675bcfe0c775459a8140750eb" + sha256: e2eb0491ba5ddb6177742d2da23904574082139b07c1e33b8503b9f46f3e1a37 url: "https://pub.dev" source: hosted - version: "2.13.0" + version: "2.13.1" boolean_selector: dependency: transitive description: @@ -103,10 +103,10 @@ packages: dependency: transitive description: name: meta - sha256: "23f08335362185a5ea2ad3a4e597f1375e78bce8a040df5c600c8d3552ef2394" + sha256: "1741988757a65eb6b36abe716829688cf01910bbf91c34354ff7ec1c3de2b349" url: "https://pub.dev" source: hosted - version: "1.17.0" + version: "1.18.0" path: dependency: transitive description: @@ -124,10 +124,10 @@ packages: dependency: transitive description: name: source_span - sha256: "254ee5351d6cb365c859e20ee823c3bb479bf4a293c22d17a9f1bf144ce86f7c" + sha256: "56a02f1f4cd1a2d96303c0144c93bd6d909eea6bee6bf5a0e0b685edbd4c47ab" url: "https://pub.dev" source: hosted - version: "1.10.1" + version: "1.10.2" stack_trace: dependency: transitive description: @@ -164,10 +164,10 @@ packages: dependency: transitive description: name: test_api - sha256: "8161c84903fd860b26bfdefb7963b3f0b68fee7adea0f59ef805ecca346f0c7a" + sha256: "949a932224383300f01be9221c39180316445ecb8e7547f70a41a35bf421fb9e" url: "https://pub.dev" source: hosted - version: "0.7.10" + version: "0.7.11" vector_math: dependency: transitive description: @@ -180,10 +180,10 @@ packages: dependency: transitive description: name: vm_service - sha256: "45caa6c5917fa127b5dbcfbd1fa60b14e583afdc08bfc96dda38886ca252eb60" + sha256: "0016aef94fc66495ac78af5859181e3f3bf2026bd8eecc72b9565601e19ab360" url: "https://pub.dev" source: hosted - version: "15.0.2" + version: "15.2.0" sdks: - dart: ">=3.11.0 <4.0.0" + dart: ">=3.12.0 <4.0.0" flutter: ">=3.18.0-18.0.pre.54" diff --git a/mobile/packages/ui/pubspec.yaml b/mobile/packages/ui/pubspec.yaml index de50e0a429..1f44694ace 100644 --- a/mobile/packages/ui/pubspec.yaml +++ b/mobile/packages/ui/pubspec.yaml @@ -2,7 +2,7 @@ name: immich_ui publish_to: none environment: - sdk: '>=3.11.0 <4.0.0' + sdk: '>=3.12.0 <4.0.0' dependencies: flutter: diff --git a/mobile/packages/ui/showcase/.gitignore b/mobile/packages/ui/showcase/.gitignore deleted file mode 100644 index b285cd608b..0000000000 --- a/mobile/packages/ui/showcase/.gitignore +++ /dev/null @@ -1,11 +0,0 @@ -# Build artifacts -build/ - -# Test cache and generated files -.dart_tool/ -.packages -.flutter-plugins -.flutter-plugins-dependencies - -# IDE-specific files -.vscode/ \ No newline at end of file diff --git a/mobile/packages/ui/showcase/.metadata b/mobile/packages/ui/showcase/.metadata deleted file mode 100644 index b95fa4d74e..0000000000 --- a/mobile/packages/ui/showcase/.metadata +++ /dev/null @@ -1,30 +0,0 @@ -# This file tracks properties of this Flutter project. -# Used by Flutter tool to assess capabilities and perform upgrades etc. -# -# This file should be version controlled and should not be manually edited. - -version: - revision: "adc901062556672b4138e18a4dc62a4be8f4b3c2" - channel: "stable" - -project_type: app - -# Tracks metadata for the flutter migrate command -migration: - platforms: - - platform: root - create_revision: adc901062556672b4138e18a4dc62a4be8f4b3c2 - base_revision: adc901062556672b4138e18a4dc62a4be8f4b3c2 - - platform: web - create_revision: adc901062556672b4138e18a4dc62a4be8f4b3c2 - base_revision: adc901062556672b4138e18a4dc62a4be8f4b3c2 - - # User provided section - - # List of Local paths (relative to this file) that should be - # ignored by the migrate tool. - # - # Files that are not part of the templates will be ignored by default. - unmanaged_files: - - 'lib/main.dart' - - 'ios/Runner.xcodeproj/project.pbxproj' diff --git a/mobile/packages/ui/showcase/analysis_options.yaml b/mobile/packages/ui/showcase/analysis_options.yaml deleted file mode 100644 index f9b303465f..0000000000 --- a/mobile/packages/ui/showcase/analysis_options.yaml +++ /dev/null @@ -1 +0,0 @@ -include: package:flutter_lints/flutter.yaml diff --git a/mobile/packages/ui/showcase/assets/immich-text-dark.png b/mobile/packages/ui/showcase/assets/immich-text-dark.png deleted file mode 100644 index 215687af8f..0000000000 Binary files a/mobile/packages/ui/showcase/assets/immich-text-dark.png and /dev/null differ diff --git a/mobile/packages/ui/showcase/assets/immich-text-light.png b/mobile/packages/ui/showcase/assets/immich-text-light.png deleted file mode 100644 index 478158d39c..0000000000 Binary files a/mobile/packages/ui/showcase/assets/immich-text-light.png and /dev/null differ diff --git a/mobile/packages/ui/showcase/assets/immich_logo.png b/mobile/packages/ui/showcase/assets/immich_logo.png deleted file mode 100644 index 49fd3ae289..0000000000 Binary files a/mobile/packages/ui/showcase/assets/immich_logo.png and /dev/null differ diff --git a/mobile/packages/ui/showcase/assets/themes/github_dark.json b/mobile/packages/ui/showcase/assets/themes/github_dark.json deleted file mode 100644 index bd4801482e..0000000000 --- a/mobile/packages/ui/showcase/assets/themes/github_dark.json +++ /dev/null @@ -1,339 +0,0 @@ -{ - "name": "GitHub Dark", - "settings": [ - { - "settings": { - "foreground": "#e1e4e8", - "background": "#24292e" - } - }, - { - "scope": [ - "comment", - "punctuation.definition.comment", - "string.comment" - ], - "settings": { - "foreground": "#6a737d" - } - }, - { - "scope": [ - "constant", - "entity.name.constant", - "variable.other.constant", - "variable.other.enummember", - "variable.language" - ], - "settings": { - "foreground": "#79b8ff" - } - }, - { - "scope": [ - "entity", - "entity.name" - ], - "settings": { - "foreground": "#b392f0" - } - }, - { - "scope": "variable.parameter.function", - "settings": { - "foreground": "#e1e4e8" - } - }, - { - "scope": "entity.name.tag", - "settings": { - "foreground": "#85e89d" - } - }, - { - "scope": "keyword", - "settings": { - "foreground": "#f97583" - } - }, - { - "scope": [ - "storage", - "storage.type" - ], - "settings": { - "foreground": "#f97583" - } - }, - { - "scope": [ - "storage.modifier.package", - "storage.modifier.import", - "storage.type.java" - ], - "settings": { - "foreground": "#e1e4e8" - } - }, - { - "scope": [ - "string", - "punctuation.definition.string", - "string punctuation.section.embedded source" - ], - "settings": { - "foreground": "#9ecbff" - } - }, - { - "scope": "support", - "settings": { - "foreground": "#79b8ff" - } - }, - { - "scope": "meta.property-name", - "settings": { - "foreground": "#79b8ff" - } - }, - { - "scope": "variable", - "settings": { - "foreground": "#ffab70" - } - }, - { - "scope": "variable.other", - "settings": { - "foreground": "#e1e4e8" - } - }, - { - "scope": "invalid.broken", - "settings": { - "fontStyle": "italic", - "foreground": "#fdaeb7" - } - }, - { - "scope": "invalid.deprecated", - "settings": { - "fontStyle": "italic", - "foreground": "#fdaeb7" - } - }, - { - "scope": "invalid.illegal", - "settings": { - "fontStyle": "italic", - "foreground": "#fdaeb7" - } - }, - { - "scope": "invalid.unimplemented", - "settings": { - "fontStyle": "italic", - "foreground": "#fdaeb7" - } - }, - { - "scope": "message.error", - "settings": { - "foreground": "#fdaeb7" - } - }, - { - "scope": "string variable", - "settings": { - "foreground": "#79b8ff" - } - }, - { - "scope": [ - "source.regexp", - "string.regexp" - ], - "settings": { - "foreground": "#dbedff" - } - }, - { - "scope": [ - "string.regexp.character-class", - "string.regexp constant.character.escape", - "string.regexp source.ruby.embedded", - "string.regexp string.regexp.arbitrary-repitition" - ], - "settings": { - "foreground": "#dbedff" - } - }, - { - "scope": "string.regexp constant.character.escape", - "settings": { - "fontStyle": "bold", - "foreground": "#85e89d" - } - }, - { - "scope": "support.constant", - "settings": { - "foreground": "#79b8ff" - } - }, - { - "scope": "support.variable", - "settings": { - "foreground": "#79b8ff" - } - }, - { - "scope": "meta.module-reference", - "settings": { - "foreground": "#79b8ff" - } - }, - { - "scope": "punctuation.definition.list.begin.markdown", - "settings": { - "foreground": "#ffab70" - } - }, - { - "scope": [ - "markup.heading", - "markup.heading entity.name" - ], - "settings": { - "fontStyle": "bold", - "foreground": "#79b8ff" - } - }, - { - "scope": "markup.quote", - "settings": { - "foreground": "#85e89d" - } - }, - { - "scope": "markup.italic", - "settings": { - "fontStyle": "italic", - "foreground": "#e1e4e8" - } - }, - { - "scope": "markup.bold", - "settings": { - "fontStyle": "bold", - "foreground": "#e1e4e8" - } - }, - { - "scope": "markup.underline", - "settings": { - "fontStyle": "underline" - } - }, - { - "scope": "markup.inline.raw", - "settings": { - "foreground": "#79b8ff" - } - }, - { - "scope": [ - "markup.deleted", - "meta.diff.header.from-file", - "punctuation.definition.deleted" - ], - "settings": { - "foreground": "#fdaeb7" - } - }, - { - "scope": [ - "markup.inserted", - "meta.diff.header.to-file", - "punctuation.definition.inserted" - ], - "settings": { - "foreground": "#85e89d" - } - }, - { - "scope": [ - "markup.changed", - "punctuation.definition.changed" - ], - "settings": { - "foreground": "#ffab70" - } - }, - { - "scope": [ - "markup.ignored", - "markup.untracked" - ], - "settings": { - "foreground": "#2f363d" - } - }, - { - "scope": "meta.diff.range", - "settings": { - "fontStyle": "bold", - "foreground": "#b392f0" - } - }, - { - "scope": "meta.diff.header", - "settings": { - "foreground": "#79b8ff" - } - }, - { - "scope": "meta.separator", - "settings": { - "fontStyle": "bold", - "foreground": "#79b8ff" - } - }, - { - "scope": "meta.output", - "settings": { - "foreground": "#79b8ff" - } - }, - { - "scope": [ - "brackethighlighter.tag", - "brackethighlighter.curly", - "brackethighlighter.round", - "brackethighlighter.square", - "brackethighlighter.angle", - "brackethighlighter.quote" - ], - "settings": { - "foreground": "#d1d5da" - } - }, - { - "scope": "brackethighlighter.unmatched", - "settings": { - "foreground": "#fdaeb7" - } - }, - { - "scope": [ - "constant.other.reference.link", - "string.other.link" - ], - "settings": { - "fontStyle": "underline", - "foreground": "#dbedff" - } - } - ] -} diff --git a/mobile/packages/ui/showcase/lib/app_theme.dart b/mobile/packages/ui/showcase/lib/app_theme.dart deleted file mode 100644 index 995bf3c91e..0000000000 --- a/mobile/packages/ui/showcase/lib/app_theme.dart +++ /dev/null @@ -1,96 +0,0 @@ -import 'package:flutter/material.dart'; - -class AppTheme { - // Light theme colors - static const _primary500 = Color(0xFF4250AF); - static const _primary100 = Color(0xFFD4D6F0); - static const _primary900 = Color(0xFF181E44); - static const _danger500 = Color(0xFFE53E3E); - static const _light50 = Color(0xFFFAFAFA); - static const _light300 = Color(0xFFD4D4D4); - static const _light500 = Color(0xFF737373); - - // Dark theme colors - static const _darkPrimary500 = Color(0xFFACCBFA); - static const _darkPrimary300 = Color(0xFF616D94); - static const _darkDanger500 = Color(0xFFE88080); - static const _darkLight50 = Color(0xFF0A0A0A); - static const _darkLight100 = Color(0xFF171717); - static const _darkLight200 = Color(0xFF262626); - - static ThemeData get lightTheme { - return ThemeData( - colorScheme: const ColorScheme.light( - primary: _primary500, - onPrimary: Colors.white, - primaryContainer: _primary100, - onPrimaryContainer: _primary900, - secondary: _light500, - onSecondary: Colors.white, - error: _danger500, - onError: Colors.white, - surface: _light50, - onSurface: Color(0xFF1A1C1E), - surfaceContainerHighest: Color(0xFFE3E4E8), - outline: Color(0xFFD1D3D9), - outlineVariant: _light300, - ), - useMaterial3: true, - fontFamily: 'GoogleSans', - scaffoldBackgroundColor: _light50, - cardTheme: const CardThemeData( - elevation: 0, - color: Colors.white, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.all(Radius.circular(12)), - side: BorderSide(color: _light300, width: 1), - ), - ), - appBarTheme: const AppBarTheme( - centerTitle: false, - elevation: 0, - backgroundColor: Colors.white, - surfaceTintColor: Colors.transparent, - foregroundColor: Color(0xFF1A1C1E), - ), - ); - } - - static ThemeData get darkTheme { - return ThemeData( - colorScheme: const ColorScheme.dark( - primary: _darkPrimary500, - onPrimary: Color(0xFF0F1433), - primaryContainer: _darkPrimary300, - onPrimaryContainer: _primary100, - secondary: Color(0xFFC4C6D0), - onSecondary: Color(0xFF2E3042), - error: _darkDanger500, - onError: Color(0xFF0F1433), - surface: _darkLight50, - onSurface: Color(0xFFE3E3E6), - surfaceContainerHighest: _darkLight200, - outline: Color(0xFF8E9099), - outlineVariant: Color(0xFF43464F), - ), - useMaterial3: true, - fontFamily: 'GoogleSans', - scaffoldBackgroundColor: _darkLight50, - cardTheme: const CardThemeData( - elevation: 0, - color: _darkLight100, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.all(Radius.circular(12)), - side: BorderSide(color: _darkLight200, width: 1), - ), - ), - appBarTheme: const AppBarTheme( - centerTitle: false, - elevation: 0, - backgroundColor: _darkLight50, - surfaceTintColor: Colors.transparent, - foregroundColor: Color(0xFFE3E3E6), - ), - ); - } -} diff --git a/mobile/packages/ui/showcase/lib/constants.dart b/mobile/packages/ui/showcase/lib/constants.dart deleted file mode 100644 index cfca4cfda9..0000000000 --- a/mobile/packages/ui/showcase/lib/constants.dart +++ /dev/null @@ -1,16 +0,0 @@ -const String appTitle = '@immich/ui'; - -class LayoutConstants { - static const double sidebarWidth = 220.0; - - static const double gridSpacing = 16.0; - static const double gridAspectRatio = 2.5; - - static const double borderRadiusSmall = 6.0; - static const double borderRadiusMedium = 8.0; - static const double borderRadiusLarge = 12.0; - - static const double iconSizeSmall = 16.0; - static const double iconSizeMedium = 18.0; - static const double iconSizeLarge = 20.0; -} diff --git a/mobile/packages/ui/showcase/lib/main.dart b/mobile/packages/ui/showcase/lib/main.dart deleted file mode 100644 index 6cd2df4fe5..0000000000 --- a/mobile/packages/ui/showcase/lib/main.dart +++ /dev/null @@ -1,55 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:go_router/go_router.dart'; -import 'package:immich_ui/immich_ui.dart'; -import 'package:showcase/app_theme.dart'; -import 'package:showcase/constants.dart'; -import 'package:showcase/router.dart'; -import 'package:showcase/widgets/example_card.dart'; - -void main() async { - WidgetsFlutterBinding.ensureInitialized(); - await initializeCodeHighlighter(); - runApp(const ShowcaseApp()); -} - -class ShowcaseApp extends StatefulWidget { - const ShowcaseApp({super.key}); - - @override - State createState() => _ShowcaseAppState(); -} - -class _ShowcaseAppState extends State { - ThemeMode _themeMode = ThemeMode.light; - late final GoRouter _router; - - @override - void initState() { - super.initState(); - _router = AppRouter.createRouter(_toggleTheme); - } - - void _toggleTheme() { - setState(() { - _themeMode = _themeMode == ThemeMode.light - ? ThemeMode.dark - : ThemeMode.light; - }); - } - - @override - Widget build(BuildContext context) { - return MaterialApp.router( - title: appTitle, - themeMode: _themeMode, - routerConfig: _router, - theme: AppTheme.lightTheme, - darkTheme: AppTheme.darkTheme, - debugShowCheckedModeBanner: false, - builder: (context, child) => ImmichThemeProvider( - colorScheme: Theme.of(context).colorScheme, - child: child!, - ), - ); - } -} diff --git a/mobile/packages/ui/showcase/lib/pages/components/close_button_page.dart b/mobile/packages/ui/showcase/lib/pages/components/close_button_page.dart deleted file mode 100644 index 1bae98e0a4..0000000000 --- a/mobile/packages/ui/showcase/lib/pages/components/close_button_page.dart +++ /dev/null @@ -1,41 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:immich_ui/immich_ui.dart'; -import 'package:showcase/routes.dart'; -import 'package:showcase/widgets/component_examples.dart'; -import 'package:showcase/widgets/example_card.dart'; -import 'package:showcase/widgets/page_title.dart'; - -class CloseButtonPage extends StatelessWidget { - const CloseButtonPage({super.key}); - - @override - Widget build(BuildContext context) { - return PageTitle( - title: AppRoute.closeButton.name, - child: ComponentExamples( - title: 'ImmichCloseButton', - subtitle: 'Pre-configured close button for dialogs and sheets.', - examples: [ - ExampleCard( - title: 'Default & Custom', - preview: Wrap( - spacing: 12, - runSpacing: 12, - children: [ - ImmichCloseButton(onPressed: () {}), - ImmichCloseButton( - variant: ImmichVariant.filled, - onPressed: () {}, - ), - ImmichCloseButton( - color: ImmichColor.secondary, - onPressed: () {}, - ), - ], - ), - ), - ], - ), - ); - } -} diff --git a/mobile/packages/ui/showcase/lib/pages/components/examples/formatted_text_bold_text.dart b/mobile/packages/ui/showcase/lib/pages/components/examples/formatted_text_bold_text.dart deleted file mode 100644 index 7e36ac7537..0000000000 --- a/mobile/packages/ui/showcase/lib/pages/components/examples/formatted_text_bold_text.dart +++ /dev/null @@ -1,11 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:immich_ui/immich_ui.dart'; - -class FormattedTextBoldText extends StatelessWidget { - const FormattedTextBoldText({super.key}); - - @override - Widget build(BuildContext context) { - return ImmichFormattedText('This is bold text.'); - } -} diff --git a/mobile/packages/ui/showcase/lib/pages/components/examples/formatted_text_links.dart b/mobile/packages/ui/showcase/lib/pages/components/examples/formatted_text_links.dart deleted file mode 100644 index 3910a5117a..0000000000 --- a/mobile/packages/ui/showcase/lib/pages/components/examples/formatted_text_links.dart +++ /dev/null @@ -1,24 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:immich_ui/immich_ui.dart'; - -class FormattedTextLinks extends StatelessWidget { - const FormattedTextLinks({super.key}); - - @override - Widget build(BuildContext context) { - return ImmichFormattedText( - 'Read the documentation or visit GitHub.', - spanBuilder: (tag) => FormattedSpan( - onTap: switch (tag) { - 'docs-link' => () => ScaffoldMessenger.of( - context, - ).showSnackBar(const SnackBar(content: Text('Docs link clicked!'))), - 'github-link' => () => ScaffoldMessenger.of( - context, - ).showSnackBar(const SnackBar(content: Text('GitHub link clicked!'))), - _ => null, - }, - ), - ); - } -} diff --git a/mobile/packages/ui/showcase/lib/pages/components/examples/formatted_text_mixed_tags.dart b/mobile/packages/ui/showcase/lib/pages/components/examples/formatted_text_mixed_tags.dart deleted file mode 100644 index 3490b1c386..0000000000 --- a/mobile/packages/ui/showcase/lib/pages/components/examples/formatted_text_mixed_tags.dart +++ /dev/null @@ -1,23 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:immich_ui/immich_ui.dart'; - -class FormattedTextMixedContent extends StatelessWidget { - const FormattedTextMixedContent({super.key}); - - @override - Widget build(BuildContext context) { - return ImmichFormattedText( - 'You can use bold text and links together.', - spanBuilder: (tag) => switch (tag) { - 'b' => const FormattedSpan( - style: TextStyle(fontWeight: FontWeight.bold), - ), - _ => FormattedSpan( - onTap: () => ScaffoldMessenger.of( - context, - ).showSnackBar(const SnackBar(content: Text('Link clicked!'))), - ), - }, - ); - } -} diff --git a/mobile/packages/ui/showcase/lib/pages/components/form_page.dart b/mobile/packages/ui/showcase/lib/pages/components/form_page.dart deleted file mode 100644 index f4480026b3..0000000000 --- a/mobile/packages/ui/showcase/lib/pages/components/form_page.dart +++ /dev/null @@ -1,80 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:immich_ui/immich_ui.dart'; -import 'package:showcase/routes.dart'; -import 'package:showcase/widgets/component_examples.dart'; -import 'package:showcase/widgets/example_card.dart'; -import 'package:showcase/widgets/page_title.dart'; - -class FormPage extends StatefulWidget { - const FormPage({super.key}); - - @override - State createState() => _FormPageState(); -} - -class _FormPageState extends State { - final _emailController = TextEditingController(); - final _passwordController = TextEditingController(); - String _result = ''; - - @override - Widget build(BuildContext context) { - return PageTitle( - title: AppRoute.form.name, - child: ComponentExamples( - title: 'ImmichForm', - subtitle: - 'Form container with built-in validation and submit handling.', - examples: [ - ExampleCard( - title: 'Login Form', - preview: Column( - children: [ - ImmichForm( - submitText: 'Login', - submitIcon: Icons.login, - onSubmit: () async { - await Future.delayed(const Duration(seconds: 1)); - setState(() { - _result = 'Form submitted!'; - }); - }, - builder: (context, form) => Column( - spacing: 10, - children: [ - ImmichTextInput( - label: 'Email', - controller: _emailController, - keyboardType: TextInputType.emailAddress, - validator: (value) => - value?.isEmpty ?? true ? 'Required' : null, - ), - ImmichPasswordInput( - label: 'Password', - controller: _passwordController, - validator: (value) => - value?.isEmpty ?? true ? 'Required' : null, - onSubmit: (_) => form.submit(), - ), - ], - ), - ), - if (_result.isNotEmpty) ...[ - const SizedBox(height: 16), - Text(_result, style: const TextStyle(color: Colors.green)), - ], - ], - ), - ), - ], - ), - ); - } - - @override - void dispose() { - _emailController.dispose(); - _passwordController.dispose(); - super.dispose(); - } -} diff --git a/mobile/packages/ui/showcase/lib/pages/components/formatted_text_page.dart b/mobile/packages/ui/showcase/lib/pages/components/formatted_text_page.dart deleted file mode 100644 index b827e0340b..0000000000 --- a/mobile/packages/ui/showcase/lib/pages/components/formatted_text_page.dart +++ /dev/null @@ -1,40 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:showcase/pages/components/examples/formatted_text_bold_text.dart'; -import 'package:showcase/pages/components/examples/formatted_text_links.dart'; -import 'package:showcase/pages/components/examples/formatted_text_mixed_tags.dart'; -import 'package:showcase/routes.dart'; -import 'package:showcase/widgets/component_examples.dart'; -import 'package:showcase/widgets/example_card.dart'; -import 'package:showcase/widgets/page_title.dart'; - -class FormattedTextPage extends StatelessWidget { - const FormattedTextPage({super.key}); - - @override - Widget build(BuildContext context) { - return PageTitle( - title: AppRoute.formattedText.name, - child: ComponentExamples( - title: 'ImmichFormattedText', - subtitle: 'Render text with HTML formatting (bold, links).', - examples: [ - ExampleCard( - title: 'Bold Text', - preview: const FormattedTextBoldText(), - code: 'formatted_text_bold_text.dart', - ), - ExampleCard( - title: 'Links', - preview: const FormattedTextLinks(), - code: 'formatted_text_links.dart', - ), - ExampleCard( - title: 'Mixed Content', - preview: const FormattedTextMixedContent(), - code: 'formatted_text_mixed_tags.dart', - ), - ], - ), - ); - } -} diff --git a/mobile/packages/ui/showcase/lib/pages/components/icon_button_page.dart b/mobile/packages/ui/showcase/lib/pages/components/icon_button_page.dart deleted file mode 100644 index 4418b1de4f..0000000000 --- a/mobile/packages/ui/showcase/lib/pages/components/icon_button_page.dart +++ /dev/null @@ -1,52 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:immich_ui/immich_ui.dart'; -import 'package:showcase/routes.dart'; -import 'package:showcase/widgets/component_examples.dart'; -import 'package:showcase/widgets/example_card.dart'; -import 'package:showcase/widgets/page_title.dart'; - -class IconButtonPage extends StatelessWidget { - const IconButtonPage({super.key}); - - @override - Widget build(BuildContext context) { - return PageTitle( - title: AppRoute.iconButton.name, - child: ComponentExamples( - title: 'ImmichIconButton', - subtitle: 'Icon-only button with customizable styling.', - examples: [ - ExampleCard( - title: 'Variants & Colors', - preview: Wrap( - spacing: 12, - runSpacing: 12, - children: [ - ImmichIconButton( - icon: Icons.add, - onPressed: () {}, - variant: ImmichVariant.filled, - ), - ImmichIconButton( - icon: Icons.edit, - onPressed: () {}, - variant: ImmichVariant.ghost, - ), - ImmichIconButton( - icon: Icons.delete, - onPressed: () {}, - color: ImmichColor.secondary, - ), - ImmichIconButton( - icon: Icons.settings, - onPressed: () {}, - disabled: true, - ), - ], - ), - ), - ], - ), - ); - } -} diff --git a/mobile/packages/ui/showcase/lib/pages/components/password_input_page.dart b/mobile/packages/ui/showcase/lib/pages/components/password_input_page.dart deleted file mode 100644 index 772dd7882f..0000000000 --- a/mobile/packages/ui/showcase/lib/pages/components/password_input_page.dart +++ /dev/null @@ -1,39 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:immich_ui/immich_ui.dart'; -import 'package:showcase/routes.dart'; -import 'package:showcase/widgets/component_examples.dart'; -import 'package:showcase/widgets/example_card.dart'; -import 'package:showcase/widgets/page_title.dart'; - -class PasswordInputPage extends StatelessWidget { - const PasswordInputPage({super.key}); - - @override - Widget build(BuildContext context) { - return PageTitle( - title: AppRoute.passwordInput.name, - child: ComponentExamples( - title: 'ImmichPasswordInput', - subtitle: 'Password field with visibility toggle.', - examples: [ - ExampleCard( - title: 'Password Input', - preview: ImmichPasswordInput( - label: 'Password', - hintText: 'Enter your password', - validator: (value) { - if (value == null || value.isEmpty) { - return 'Password is required'; - } - if (value.length < 8) { - return 'Password must be at least 8 characters'; - } - return null; - }, - ), - ), - ], - ), - ); - } -} diff --git a/mobile/packages/ui/showcase/lib/pages/components/text_button_page.dart b/mobile/packages/ui/showcase/lib/pages/components/text_button_page.dart deleted file mode 100644 index 59e5b86294..0000000000 --- a/mobile/packages/ui/showcase/lib/pages/components/text_button_page.dart +++ /dev/null @@ -1,140 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:immich_ui/immich_ui.dart'; -import 'package:showcase/routes.dart'; -import 'package:showcase/widgets/component_examples.dart'; -import 'package:showcase/widgets/example_card.dart'; -import 'package:showcase/widgets/page_title.dart'; - -class TextButtonPage extends StatefulWidget { - const TextButtonPage({super.key}); - - @override - State createState() => _TextButtonPageState(); -} - -class _TextButtonPageState extends State { - bool _isLoading = false; - @override - Widget build(BuildContext context) { - return PageTitle( - title: AppRoute.textButton.name, - child: ComponentExamples( - title: 'ImmichTextButton', - subtitle: - 'A versatile button component with multiple variants and color options.', - examples: [ - ExampleCard( - title: 'Variants', - description: - 'Filled and ghost variants for different visual hierarchy', - preview: Wrap( - spacing: 12, - runSpacing: 12, - children: [ - ImmichTextButton( - onPressed: () {}, - labelText: 'Filled', - variant: ImmichVariant.filled, - expanded: false, - ), - ImmichTextButton( - onPressed: () {}, - labelText: 'Ghost', - variant: ImmichVariant.ghost, - expanded: false, - ), - ], - ), - ), - ExampleCard( - title: 'Colors', - description: 'Primary and secondary color options', - preview: Wrap( - spacing: 12, - runSpacing: 12, - children: [ - ImmichTextButton( - onPressed: () {}, - labelText: 'Primary', - color: ImmichColor.primary, - expanded: false, - ), - ImmichTextButton( - onPressed: () {}, - labelText: 'Secondary', - color: ImmichColor.secondary, - expanded: false, - ), - ], - ), - ), - ExampleCard( - title: 'With Icons', - description: 'Add leading icons', - preview: Wrap( - spacing: 12, - runSpacing: 12, - children: [ - ImmichTextButton( - onPressed: () {}, - labelText: 'With Icon', - icon: Icons.add, - expanded: false, - ), - ImmichTextButton( - onPressed: () {}, - labelText: 'Download', - icon: Icons.download, - variant: ImmichVariant.ghost, - expanded: false, - ), - ], - ), - ), - ExampleCard( - title: 'Loading State', - description: 'Shows loading indicator during async operations', - preview: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - ImmichTextButton( - onPressed: () async { - setState(() => _isLoading = true); - await Future.delayed(const Duration(seconds: 2)); - if (mounted) setState(() => _isLoading = false); - }, - labelText: _isLoading ? 'Loading...' : 'Click Me', - loading: _isLoading, - expanded: false, - ), - ], - ), - ), - ExampleCard( - title: 'Disabled State', - description: 'Buttons can be disabled', - preview: Wrap( - spacing: 12, - runSpacing: 12, - children: [ - ImmichTextButton( - onPressed: () {}, - labelText: 'Disabled', - disabled: true, - expanded: false, - ), - ImmichTextButton( - onPressed: () {}, - labelText: 'Disabled Ghost', - variant: ImmichVariant.ghost, - disabled: true, - expanded: false, - ), - ], - ), - ), - ], - ), - ); - } -} diff --git a/mobile/packages/ui/showcase/lib/pages/components/text_input_page.dart b/mobile/packages/ui/showcase/lib/pages/components/text_input_page.dart deleted file mode 100644 index 5a0bfec6cd..0000000000 --- a/mobile/packages/ui/showcase/lib/pages/components/text_input_page.dart +++ /dev/null @@ -1,65 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:immich_ui/immich_ui.dart'; -import 'package:showcase/routes.dart'; -import 'package:showcase/widgets/component_examples.dart'; -import 'package:showcase/widgets/example_card.dart'; -import 'package:showcase/widgets/page_title.dart'; - -class TextInputPage extends StatefulWidget { - const TextInputPage({super.key}); - - @override - State createState() => _TextInputPageState(); -} - -class _TextInputPageState extends State { - final _controller1 = TextEditingController(); - final _controller2 = TextEditingController(); - - @override - Widget build(BuildContext context) { - return PageTitle( - title: AppRoute.textInput.name, - child: ComponentExamples( - title: 'ImmichTextInput', - subtitle: 'Text field with validation support.', - examples: [ - ExampleCard( - title: 'Basic Usage', - preview: Column( - children: [ - ImmichTextInput( - label: 'Email', - hintText: 'Enter your email', - controller: _controller1, - keyboardType: TextInputType.emailAddress, - ), - const SizedBox(height: 16), - ImmichTextInput( - label: 'Username', - controller: _controller2, - validator: (value) { - if (value == null || value.isEmpty) { - return 'Username is required'; - } - if (value.length < 3) { - return 'Username must be at least 3 characters'; - } - return null; - }, - ), - ], - ), - ), - ], - ), - ); - } - - @override - void dispose() { - _controller1.dispose(); - _controller2.dispose(); - super.dispose(); - } -} diff --git a/mobile/packages/ui/showcase/lib/pages/design_system/constants_page.dart b/mobile/packages/ui/showcase/lib/pages/design_system/constants_page.dart deleted file mode 100644 index 17de02d80a..0000000000 --- a/mobile/packages/ui/showcase/lib/pages/design_system/constants_page.dart +++ /dev/null @@ -1,396 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:immich_ui/immich_ui.dart'; -import 'package:showcase/routes.dart'; -import 'package:showcase/widgets/component_examples.dart'; -import 'package:showcase/widgets/example_card.dart'; -import 'package:showcase/widgets/page_title.dart'; - -class ConstantsPage extends StatefulWidget { - const ConstantsPage({super.key}); - - @override - State createState() => _ConstantsPageState(); -} - -class _ConstantsPageState extends State { - @override - Widget build(BuildContext context) { - return PageTitle( - title: AppRoute.constants.name, - child: ComponentExamples( - title: 'Constants', - subtitle: 'Consistent spacing, sizing, and styling constants.', - expand: true, - examples: [ - const ExampleCard( - title: 'Spacing', - description: 'ImmichSpacing (4.0 → 48.0)', - preview: Column( - children: [ - _SpacingBox(label: 'xs', size: ImmichSpacing.xs), - _SpacingBox(label: 'sm', size: ImmichSpacing.sm), - _SpacingBox(label: 'md', size: ImmichSpacing.md), - _SpacingBox(label: 'lg', size: ImmichSpacing.lg), - _SpacingBox(label: 'xl', size: ImmichSpacing.xl), - _SpacingBox(label: 'xxl', size: ImmichSpacing.xxl), - _SpacingBox(label: 'xxxl', size: ImmichSpacing.xxxl), - ], - ), - ), - const ExampleCard( - title: 'Border Radius', - description: 'ImmichRadius (0.0 → 24.0)', - preview: Wrap( - spacing: 12, - runSpacing: 12, - children: [ - _RadiusBox(label: 'none', radius: ImmichRadius.none), - _RadiusBox(label: 'xs', radius: ImmichRadius.xs), - _RadiusBox(label: 'sm', radius: ImmichRadius.sm), - _RadiusBox(label: 'md', radius: ImmichRadius.md), - _RadiusBox(label: 'lg', radius: ImmichRadius.lg), - _RadiusBox(label: 'xl', radius: ImmichRadius.xl), - _RadiusBox(label: 'xxl', radius: ImmichRadius.xxl), - ], - ), - ), - const ExampleCard( - title: 'Icon Sizes', - description: 'ImmichIconSize (16.0 → 48.0)', - preview: Wrap( - spacing: 16, - runSpacing: 16, - alignment: WrapAlignment.start, - children: [ - _IconSizeBox(label: 'xs', size: ImmichIconSize.xs), - _IconSizeBox(label: 'sm', size: ImmichIconSize.sm), - _IconSizeBox(label: 'md', size: ImmichIconSize.md), - _IconSizeBox(label: 'lg', size: ImmichIconSize.lg), - _IconSizeBox(label: 'xl', size: ImmichIconSize.xl), - _IconSizeBox(label: 'xxl', size: ImmichIconSize.xxl), - ], - ), - ), - const ExampleCard( - title: 'Text Sizes', - description: 'ImmichTextSize (10.0 → 60.0)', - preview: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - 'Caption', - style: TextStyle(fontSize: ImmichTextSize.caption), - ), - Text('Label', style: TextStyle(fontSize: ImmichTextSize.label)), - Text('Body', style: TextStyle(fontSize: ImmichTextSize.body)), - Text('H6', style: TextStyle(fontSize: ImmichTextSize.h6)), - Text('H5', style: TextStyle(fontSize: ImmichTextSize.h5)), - Text('H4', style: TextStyle(fontSize: ImmichTextSize.h4)), - Text('H3', style: TextStyle(fontSize: ImmichTextSize.h3)), - Text('H2', style: TextStyle(fontSize: ImmichTextSize.h2)), - Text('H1', style: TextStyle(fontSize: ImmichTextSize.h1)), - ], - ), - ), - const ExampleCard( - title: 'Elevation', - description: 'ImmichElevation (0.0 → 16.0)', - preview: Wrap( - spacing: 12, - runSpacing: 12, - children: [ - _ElevationBox(label: 'none', elevation: ImmichElevation.none), - _ElevationBox(label: 'xs', elevation: ImmichElevation.xs), - _ElevationBox(label: 'sm', elevation: ImmichElevation.sm), - _ElevationBox(label: 'md', elevation: ImmichElevation.md), - _ElevationBox(label: 'lg', elevation: ImmichElevation.lg), - _ElevationBox(label: 'xl', elevation: ImmichElevation.xl), - _ElevationBox(label: 'xxl', elevation: ImmichElevation.xxl), - ], - ), - ), - const ExampleCard( - title: 'Border Width', - description: 'ImmichBorderWidth (0.5 → 4.0)', - preview: Column( - children: [ - _BorderBox( - label: 'hairline', - borderWidth: ImmichBorderWidth.hairline, - ), - _BorderBox(label: 'base', borderWidth: ImmichBorderWidth.base), - _BorderBox(label: 'md', borderWidth: ImmichBorderWidth.md), - _BorderBox(label: 'lg', borderWidth: ImmichBorderWidth.lg), - _BorderBox(label: 'xl', borderWidth: ImmichBorderWidth.xl), - ], - ), - ), - const ExampleCard( - title: 'Animation Durations', - description: 'ImmichDuration (100ms → 700ms)', - preview: Column( - crossAxisAlignment: CrossAxisAlignment.start, - spacing: 8, - children: [ - _AnimatedDurationBox( - label: 'Extra Fast', - duration: ImmichDuration.extraFast, - ), - _AnimatedDurationBox( - label: 'Fast', - duration: ImmichDuration.fast, - ), - _AnimatedDurationBox( - label: 'Normal', - duration: ImmichDuration.normal, - ), - _AnimatedDurationBox( - label: 'Slow', - duration: ImmichDuration.slow, - ), - _AnimatedDurationBox( - label: 'Extra Slow', - duration: ImmichDuration.extraSlow, - ), - ], - ), - ), - ], - ), - ); - } -} - -class _SpacingBox extends StatelessWidget { - final String label; - final double size; - - const _SpacingBox({required this.label, required this.size}); - - @override - Widget build(BuildContext context) { - return Padding( - padding: const EdgeInsets.symmetric(vertical: 4), - child: Row( - children: [ - SizedBox( - width: 60, - child: Text( - label, - style: const TextStyle(fontFamily: 'GoogleSansCode'), - ), - ), - Container( - width: size, - height: 24, - color: Theme.of(context).colorScheme.primary, - ), - const SizedBox(width: 8), - Text('${size.toStringAsFixed(1)}px'), - ], - ), - ); - } -} - -class _RadiusBox extends StatelessWidget { - final String label; - final double radius; - - const _RadiusBox({required this.label, required this.radius}); - - @override - Widget build(BuildContext context) { - return Column( - children: [ - Container( - width: 60, - height: 60, - decoration: BoxDecoration( - color: Theme.of(context).colorScheme.primary, - borderRadius: BorderRadius.circular(radius), - ), - ), - const SizedBox(height: 4), - Text(label, style: const TextStyle(fontSize: 12)), - ], - ); - } -} - -class _IconSizeBox extends StatelessWidget { - final String label; - final double size; - - const _IconSizeBox({required this.label, required this.size}); - - @override - Widget build(BuildContext context) { - return Column( - children: [ - Icon(Icons.palette_rounded, size: size), - const SizedBox(height: 4), - Text(label, style: const TextStyle(fontSize: 12)), - Text( - '${size.toStringAsFixed(0)}px', - style: const TextStyle(fontSize: 10, color: Colors.grey), - ), - ], - ); - } -} - -class _ElevationBox extends StatelessWidget { - final String label; - final double elevation; - - const _ElevationBox({required this.label, required this.elevation}); - - @override - Widget build(BuildContext context) { - return Column( - children: [ - Material( - elevation: elevation, - borderRadius: const BorderRadius.all(Radius.circular(8)), - child: Container( - width: 60, - height: 60, - alignment: Alignment.center, - child: Text(label, style: const TextStyle(fontSize: 12)), - ), - ), - const SizedBox(height: 4), - Text( - elevation.toStringAsFixed(1), - style: const TextStyle(fontSize: 10), - ), - ], - ); - } -} - -class _BorderBox extends StatelessWidget { - final String label; - final double borderWidth; - - const _BorderBox({required this.label, required this.borderWidth}); - - @override - Widget build(BuildContext context) { - return Padding( - padding: const EdgeInsets.symmetric(vertical: 4), - child: Row( - children: [ - SizedBox( - width: 80, - child: Text( - label, - style: const TextStyle(fontFamily: 'GoogleSansCode'), - ), - ), - Expanded( - child: Container( - height: 40, - decoration: BoxDecoration( - border: Border.all( - color: Theme.of(context).colorScheme.primary, - width: borderWidth, - ), - borderRadius: const BorderRadius.all(Radius.circular(4)), - ), - ), - ), - const SizedBox(width: 8), - Text('${borderWidth.toStringAsFixed(1)}px'), - ], - ), - ); - } -} - -class _AnimatedDurationBox extends StatefulWidget { - final String label; - final Duration duration; - - const _AnimatedDurationBox({required this.label, required this.duration}); - - @override - State<_AnimatedDurationBox> createState() => _AnimatedDurationBoxState(); -} - -class _AnimatedDurationBoxState extends State<_AnimatedDurationBox> { - bool _atEnd = false; - bool _isAnimating = false; - - void _playAnimation() async { - if (_isAnimating) return; - setState(() => _isAnimating = true); - setState(() => _atEnd = true); - await Future.delayed(widget.duration); - if (!mounted) return; - setState(() => _atEnd = false); - await Future.delayed(widget.duration); - if (!mounted) return; - setState(() => _isAnimating = false); - } - - @override - Widget build(BuildContext context) { - final colorScheme = Theme.of(context).colorScheme; - return Row( - children: [ - SizedBox( - width: 90, - child: Text( - widget.label, - style: const TextStyle(fontFamily: 'GoogleSansCode', fontSize: 12), - ), - ), - Expanded( - child: Container( - height: 32, - decoration: BoxDecoration( - color: colorScheme.surfaceContainerHighest.withValues(alpha: 0.5), - borderRadius: BorderRadius.circular(6), - ), - child: AnimatedAlign( - duration: widget.duration, - curve: Curves.easeInOut, - alignment: _atEnd ? Alignment.centerRight : Alignment.centerLeft, - child: Container( - width: 60, - height: 28, - margin: const EdgeInsets.symmetric(horizontal: 2), - decoration: BoxDecoration( - color: colorScheme.primary, - borderRadius: BorderRadius.circular(4), - ), - alignment: Alignment.center, - child: Text( - '${widget.duration.inMilliseconds}ms', - style: TextStyle( - fontSize: 11, - color: colorScheme.onPrimary, - fontWeight: FontWeight.w500, - ), - ), - ), - ), - ), - ), - const SizedBox(width: 8), - IconButton( - onPressed: _isAnimating ? null : _playAnimation, - icon: Icon( - Icons.play_arrow_rounded, - color: _isAnimating ? colorScheme.outline : colorScheme.primary, - ), - iconSize: 24, - padding: EdgeInsets.zero, - constraints: const BoxConstraints(minWidth: 32, minHeight: 32), - ), - ], - ); - } -} diff --git a/mobile/packages/ui/showcase/lib/pages/home_page.dart b/mobile/packages/ui/showcase/lib/pages/home_page.dart deleted file mode 100644 index de7af6c26b..0000000000 --- a/mobile/packages/ui/showcase/lib/pages/home_page.dart +++ /dev/null @@ -1,118 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:go_router/go_router.dart'; -import 'package:showcase/constants.dart'; -import 'package:showcase/routes.dart'; - -class HomePage extends StatelessWidget { - final VoidCallback onThemeToggle; - - const HomePage({super.key, required this.onThemeToggle}); - - @override - Widget build(BuildContext context) { - return Title( - title: appTitle, - color: Theme.of(context).colorScheme.primary, - child: ListView( - padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 32), - children: [ - Text( - appTitle, - style: Theme.of(context).textTheme.displaySmall?.copyWith( - fontWeight: FontWeight.bold, - color: Theme.of(context).colorScheme.onSurface, - ), - ), - const SizedBox(height: 12), - Text( - 'A collection of Flutter components that are shared across all Immich projects', - style: Theme.of(context).textTheme.titleMedium?.copyWith( - color: Theme.of(context).colorScheme.onSurfaceVariant, - fontWeight: FontWeight.w400, - height: 1.5, - ), - ), - const SizedBox(height: 48), - ...routesByCategory.entries.map((entry) { - if (entry.key == AppRouteCategory.root) { - return const SizedBox.shrink(); - } - - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - entry.key.displayName, - style: Theme.of(context).textTheme.headlineSmall?.copyWith( - fontWeight: FontWeight.w600, - color: Theme.of(context).colorScheme.onSurface, - ), - ), - const SizedBox(height: 16), - GridView.builder( - shrinkWrap: true, - physics: const NeverScrollableScrollPhysics(), - gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: 3, - crossAxisSpacing: LayoutConstants.gridSpacing, - mainAxisSpacing: LayoutConstants.gridSpacing, - childAspectRatio: LayoutConstants.gridAspectRatio, - ), - itemCount: entry.value.length, - itemBuilder: (context, index) { - return _ComponentCard(route: entry.value[index]); - }, - ), - const SizedBox(height: 48), - ], - ); - }), - ], - ), - ); - } -} - -class _ComponentCard extends StatelessWidget { - final AppRoute route; - - const _ComponentCard({required this.route}); - - @override - Widget build(BuildContext context) { - return InkWell( - onTap: () => context.go(route.path), - borderRadius: const BorderRadius.all(Radius.circular(LayoutConstants.borderRadiusLarge)), - child: Card( - child: Padding( - padding: const EdgeInsets.all(20), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.min, - children: [ - Icon(route.icon, size: 32, color: Theme.of(context).colorScheme.primary), - const SizedBox(height: 16), - Text( - route.name, - style: Theme.of(context).textTheme.titleMedium?.copyWith( - fontWeight: FontWeight.w600, - color: Theme.of(context).colorScheme.onSurface, - ), - ), - - const SizedBox(height: 8), - Text( - route.description, - style: Theme.of( - context, - ).textTheme.bodyMedium?.copyWith(color: Theme.of(context).colorScheme.onSurfaceVariant, height: 1.4), - maxLines: 2, - overflow: TextOverflow.ellipsis, - ), - ], - ), - ), - ), - ); - } -} diff --git a/mobile/packages/ui/showcase/lib/router.dart b/mobile/packages/ui/showcase/lib/router.dart deleted file mode 100644 index 34393da508..0000000000 --- a/mobile/packages/ui/showcase/lib/router.dart +++ /dev/null @@ -1,48 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:go_router/go_router.dart'; -import 'package:showcase/pages/components/close_button_page.dart'; -import 'package:showcase/pages/components/form_page.dart'; -import 'package:showcase/pages/components/formatted_text_page.dart'; -import 'package:showcase/pages/components/icon_button_page.dart'; -import 'package:showcase/pages/components/password_input_page.dart'; -import 'package:showcase/pages/components/text_button_page.dart'; -import 'package:showcase/pages/components/text_input_page.dart'; -import 'package:showcase/pages/design_system/constants_page.dart'; -import 'package:showcase/pages/home_page.dart'; -import 'package:showcase/routes.dart'; -import 'package:showcase/widgets/shell_layout.dart'; - -class AppRouter { - static GoRouter createRouter(VoidCallback onThemeToggle) { - return GoRouter( - initialLocation: AppRoute.home.path, - routes: [ - ShellRoute( - builder: (context, state, child) => - ShellLayout(onThemeToggle: onThemeToggle, child: child), - routes: AppRoute.values - .map( - (route) => GoRoute( - path: route.path, - pageBuilder: (context, state) => NoTransitionPage( - key: state.pageKey, - child: switch (route) { - AppRoute.home => HomePage(onThemeToggle: onThemeToggle), - AppRoute.textButton => const TextButtonPage(), - AppRoute.iconButton => const IconButtonPage(), - AppRoute.closeButton => const CloseButtonPage(), - AppRoute.textInput => const TextInputPage(), - AppRoute.passwordInput => const PasswordInputPage(), - AppRoute.form => const FormPage(), - AppRoute.formattedText => const FormattedTextPage(), - AppRoute.constants => const ConstantsPage(), - }, - ), - ), - ) - .toList(), - ), - ], - ); - } -} diff --git a/mobile/packages/ui/showcase/lib/routes.dart b/mobile/packages/ui/showcase/lib/routes.dart deleted file mode 100644 index 4feeeafdb6..0000000000 --- a/mobile/packages/ui/showcase/lib/routes.dart +++ /dev/null @@ -1,97 +0,0 @@ -import 'package:flutter/material.dart'; - -enum AppRouteCategory { - root(''), - forms('Forms'), - buttons('Buttons'), - designSystem('Design System'); - - final String displayName; - const AppRouteCategory(this.displayName); -} - -enum AppRoute { - home( - name: 'Home', - description: 'Home page', - path: '/', - category: AppRouteCategory.root, - icon: Icons.home_outlined, - ), - textButton( - name: 'Text Button', - description: 'Versatile button with filled and ghost variants', - path: '/text-button', - category: AppRouteCategory.buttons, - icon: Icons.smart_button_rounded, - ), - iconButton( - name: 'Icon Button', - description: 'Icon-only button with customizable styling', - path: '/icon-button', - category: AppRouteCategory.buttons, - icon: Icons.radio_button_unchecked_rounded, - ), - closeButton( - name: 'Close Button', - description: 'Pre-configured close button for dialogs', - path: '/close-button', - category: AppRouteCategory.buttons, - icon: Icons.close_rounded, - ), - textInput( - name: 'Text Input', - description: 'Text field with validation support', - path: '/text-input', - category: AppRouteCategory.forms, - icon: Icons.text_fields_outlined, - ), - passwordInput( - name: 'Password Input', - description: 'Password field with visibility toggle', - path: '/password-input', - category: AppRouteCategory.forms, - icon: Icons.password_outlined, - ), - form( - name: 'Form', - description: 'Form container with built-in validation', - path: '/form', - category: AppRouteCategory.forms, - icon: Icons.description_outlined, - ), - formattedText( - name: 'Formatted Text', - description: 'Render text with HTML formatting', - path: '/formatted-text', - category: AppRouteCategory.forms, - icon: Icons.code_rounded, - ), - constants( - name: 'Constants', - description: 'Spacing, colors, typography, and more', - path: '/constants', - category: AppRouteCategory.designSystem, - icon: Icons.palette_outlined, - ); - - final String name; - final String description; - final String path; - final AppRouteCategory category; - final IconData icon; - - const AppRoute({ - required this.name, - required this.description, - required this.path, - required this.category, - required this.icon, - }); -} - -final routesByCategory = AppRoute.values - .fold>>({}, (map, route) { - map.putIfAbsent(route.category, () => []).add(route); - return map; - }); diff --git a/mobile/packages/ui/showcase/lib/widgets/component_examples.dart b/mobile/packages/ui/showcase/lib/widgets/component_examples.dart deleted file mode 100644 index 21e6516079..0000000000 --- a/mobile/packages/ui/showcase/lib/widgets/component_examples.dart +++ /dev/null @@ -1,85 +0,0 @@ -import 'package:flutter/material.dart'; - -class ComponentExamples extends StatelessWidget { - final String title; - final String? subtitle; - final List examples; - final bool expand; - - const ComponentExamples({ - super.key, - required this.title, - this.subtitle, - required this.examples, - this.expand = false, - }); - - @override - Widget build(BuildContext context) { - return Padding( - padding: const EdgeInsets.fromLTRB(10, 24, 24, 24), - child: CustomScrollView( - slivers: [ - SliverToBoxAdapter( - child: _PageHeader(title: title, subtitle: subtitle), - ), - const SliverPadding(padding: EdgeInsets.only(top: 24)), - if (expand) - SliverList.builder( - itemCount: examples.length, - itemBuilder: (context, index) => examples[index], - ) - else - SliverLayoutBuilder( - builder: (context, constraints) { - return SliverList.builder( - itemCount: examples.length, - itemBuilder: (context, index) => Align( - alignment: Alignment.centerLeft, - child: ConstrainedBox( - constraints: BoxConstraints( - minWidth: constraints.crossAxisExtent * 0.6, - maxWidth: constraints.crossAxisExtent, - ), - child: IntrinsicWidth(child: examples[index]), - ), - ), - ); - }, - ), - ], - ), - ); - } -} - -class _PageHeader extends StatelessWidget { - final String title; - final String? subtitle; - - const _PageHeader({required this.title, this.subtitle}); - - @override - Widget build(BuildContext context) { - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - title, - style: Theme.of( - context, - ).textTheme.headlineLarge?.copyWith(fontWeight: FontWeight.bold), - ), - if (subtitle != null) ...[ - const SizedBox(height: 8), - Text( - subtitle!, - style: Theme.of(context).textTheme.bodyLarge?.copyWith( - color: Theme.of(context).colorScheme.onSurfaceVariant, - ), - ), - ], - ], - ); - } -} diff --git a/mobile/packages/ui/showcase/lib/widgets/example_card.dart b/mobile/packages/ui/showcase/lib/widgets/example_card.dart deleted file mode 100644 index fea561afb6..0000000000 --- a/mobile/packages/ui/showcase/lib/widgets/example_card.dart +++ /dev/null @@ -1,237 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; -import 'package:showcase/constants.dart'; -import 'package:syntax_highlight/syntax_highlight.dart'; - -late final Highlighter _codeHighlighter; - -Future initializeCodeHighlighter() async { - await Highlighter.initialize(['dart']); - final darkTheme = await HighlighterTheme.loadFromAssets([ - 'assets/themes/github_dark.json', - ], const TextStyle(color: Color(0xFFe1e4e8))); - - _codeHighlighter = Highlighter(language: 'dart', theme: darkTheme); -} - -class ExampleCard extends StatefulWidget { - final String title; - final String? description; - final Widget preview; - final String? code; - - const ExampleCard({ - super.key, - required this.title, - this.description, - required this.preview, - this.code, - }); - - @override - State createState() => _ExampleCardState(); -} - -class _ExampleCardState extends State { - bool _showPreview = true; - String? code; - - @override - void initState() { - super.initState(); - if (widget.code != null) { - rootBundle - .loadString('lib/pages/components/examples/${widget.code!}') - .then((value) { - setState(() { - code = value; - }); - }); - } - } - - @override - Widget build(BuildContext context) { - return Card( - elevation: 1, - margin: const EdgeInsets.only(bottom: 16), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsets.all(16.0), - child: Row( - children: [ - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - widget.title, - style: Theme.of(context).textTheme.titleMedium - ?.copyWith(fontWeight: FontWeight.bold), - ), - const SizedBox(height: 4), - if (widget.description != null) - Text( - widget.description!, - style: Theme.of(context).textTheme.bodyMedium - ?.copyWith( - color: Theme.of( - context, - ).colorScheme.onSurfaceVariant, - ), - ), - ], - ), - ), - if (code != null) ...[ - const SizedBox(width: 16), - Row( - children: [ - _ToggleButton( - icon: Icons.visibility_rounded, - label: 'Preview', - isSelected: _showPreview, - onTap: () => setState(() => _showPreview = true), - ), - const SizedBox(width: 8), - _ToggleButton( - icon: Icons.code_rounded, - label: 'Code', - isSelected: !_showPreview, - onTap: () => setState(() => _showPreview = false), - ), - ], - ), - ], - ], - ), - ), - const Divider(height: 1), - if (_showPreview) - Padding( - padding: const EdgeInsets.all(16.0), - child: SizedBox(width: double.infinity, child: widget.preview), - ) - else - Container( - width: double.infinity, - decoration: const BoxDecoration( - color: Color(0xFF24292e), - borderRadius: BorderRadius.only( - bottomLeft: Radius.circular( - LayoutConstants.borderRadiusMedium, - ), - bottomRight: Radius.circular( - LayoutConstants.borderRadiusMedium, - ), - ), - ), - child: _CodeCard(code: code!), - ), - ], - ), - ); - } -} - -class _ToggleButton extends StatelessWidget { - final IconData icon; - final String label; - final bool isSelected; - final VoidCallback onTap; - - const _ToggleButton({ - required this.icon, - required this.label, - required this.isSelected, - required this.onTap, - }); - - @override - Widget build(BuildContext context) { - return InkWell( - onTap: onTap, - borderRadius: const BorderRadius.all(Radius.circular(24)), - child: Container( - padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 10), - decoration: BoxDecoration( - color: isSelected - ? Theme.of(context).colorScheme.primary.withValues(alpha: 0.7) - : Theme.of(context).colorScheme.primary, - borderRadius: const BorderRadius.all(Radius.circular(24)), - ), - child: Row( - mainAxisSize: MainAxisSize.min, - children: [ - Icon( - icon, - size: 16, - color: Theme.of(context).colorScheme.onPrimary, - ), - const SizedBox(width: 6), - Text( - label, - style: Theme.of(context).textTheme.bodyMedium?.copyWith( - color: Theme.of(context).colorScheme.onPrimary, - fontWeight: isSelected ? FontWeight.w600 : FontWeight.w400, - ), - ), - ], - ), - ), - ); - } -} - -class _CodeCard extends StatelessWidget { - final String code; - - const _CodeCard({required this.code}); - - @override - Widget build(BuildContext context) { - final lines = code.split('\n'); - final lineNumberColor = Colors.white.withValues(alpha: 0.4); - - return SingleChildScrollView( - scrollDirection: Axis.horizontal, - child: Padding( - padding: const EdgeInsets.only(left: 12, top: 8, bottom: 8), - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Column( - crossAxisAlignment: CrossAxisAlignment.end, - children: List.generate( - lines.length, - (index) => SizedBox( - height: 20, - child: Text( - '${index + 1}', - style: TextStyle( - fontFamily: 'GoogleSansCode', - fontSize: 13, - color: lineNumberColor, - height: 1.5, - ), - ), - ), - ), - ), - const SizedBox(width: 16), - SelectableText.rich( - _codeHighlighter.highlight(code), - style: const TextStyle( - fontFamily: 'GoogleSansCode', - fontSize: 13, - height: 1.54, - ), - ), - ], - ), - ), - ); - } -} diff --git a/mobile/packages/ui/showcase/lib/widgets/page_title.dart b/mobile/packages/ui/showcase/lib/widgets/page_title.dart deleted file mode 100644 index eae3bf6ffb..0000000000 --- a/mobile/packages/ui/showcase/lib/widgets/page_title.dart +++ /dev/null @@ -1,17 +0,0 @@ -import 'package:flutter/material.dart'; - -class PageTitle extends StatelessWidget { - final String title; - final Widget child; - - const PageTitle({super.key, required this.title, required this.child}); - - @override - Widget build(BuildContext context) { - return Title( - title: '$title | @immich/ui', - color: Theme.of(context).colorScheme.primary, - child: child, - ); - } -} diff --git a/mobile/packages/ui/showcase/lib/widgets/shell_layout.dart b/mobile/packages/ui/showcase/lib/widgets/shell_layout.dart deleted file mode 100644 index 8bcb687e75..0000000000 --- a/mobile/packages/ui/showcase/lib/widgets/shell_layout.dart +++ /dev/null @@ -1,59 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:showcase/constants.dart'; -import 'package:showcase/widgets/sidebar_navigation.dart'; - -class ShellLayout extends StatelessWidget { - final Widget child; - final VoidCallback onThemeToggle; - - const ShellLayout({ - super.key, - required this.child, - required this.onThemeToggle, - }); - - @override - Widget build(BuildContext context) { - final isDark = Theme.of(context).brightness == Brightness.dark; - - return Scaffold( - appBar: AppBar( - title: Row( - mainAxisSize: MainAxisSize.min, - children: [ - Image.asset('assets/immich_logo.png', height: 32, width: 32), - const SizedBox(width: 8), - Image.asset( - isDark - ? 'assets/immich-text-dark.png' - : 'assets/immich-text-light.png', - height: 24, - filterQuality: FilterQuality.none, - isAntiAlias: true, - ), - ], - ), - actions: [ - IconButton( - icon: Icon( - isDark ? Icons.light_mode_outlined : Icons.dark_mode_outlined, - size: LayoutConstants.iconSizeLarge, - ), - onPressed: onThemeToggle, - tooltip: 'Toggle theme', - ), - ], - shape: Border( - bottom: BorderSide(color: Theme.of(context).dividerColor, width: 1), - ), - ), - body: Row( - children: [ - const SidebarNavigation(), - const VerticalDivider(), - Expanded(child: child), - ], - ), - ); - } -} diff --git a/mobile/packages/ui/showcase/lib/widgets/sidebar_navigation.dart b/mobile/packages/ui/showcase/lib/widgets/sidebar_navigation.dart deleted file mode 100644 index 10eba170e6..0000000000 --- a/mobile/packages/ui/showcase/lib/widgets/sidebar_navigation.dart +++ /dev/null @@ -1,117 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:go_router/go_router.dart'; -import 'package:showcase/constants.dart'; -import 'package:showcase/routes.dart'; - -class SidebarNavigation extends StatelessWidget { - const SidebarNavigation({super.key}); - - @override - Widget build(BuildContext context) { - return Container( - width: LayoutConstants.sidebarWidth, - decoration: BoxDecoration(color: Theme.of(context).colorScheme.surface), - child: ListView( - padding: const EdgeInsets.symmetric(vertical: 20, horizontal: 16), - children: [ - ...routesByCategory.entries.expand((entry) { - final category = entry.key; - final routes = entry.value; - return [ - if (category != AppRouteCategory.root) _CategoryHeader(category), - ...routes.map((route) => _NavItem(route)), - const SizedBox(height: 24), - ]; - }), - ], - ), - ); - } -} - -class _CategoryHeader extends StatelessWidget { - final AppRouteCategory category; - - const _CategoryHeader(this.category); - - @override - Widget build(BuildContext context) { - return Padding( - padding: const EdgeInsets.only(left: 12, top: 8, bottom: 8), - child: Text( - category.displayName, - style: Theme.of(context).textTheme.bodySmall?.copyWith( - color: Theme.of(context).colorScheme.onSurfaceVariant, - fontWeight: FontWeight.w600, - letterSpacing: 0.5, - ), - ), - ); - } -} - -class _NavItem extends StatelessWidget { - final AppRoute route; - - const _NavItem(this.route); - - @override - Widget build(BuildContext context) { - final currentRoute = GoRouterState.of(context).uri.toString(); - final isSelected = currentRoute == route.path; - final isDark = Theme.of(context).brightness == Brightness.dark; - - return Padding( - padding: const EdgeInsets.symmetric(vertical: 4), - child: Material( - color: Colors.transparent, - child: InkWell( - onTap: () { - context.go(route.path); - }, - borderRadius: BorderRadius.circular( - LayoutConstants.borderRadiusMedium, - ), - child: Container( - padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8), - decoration: BoxDecoration( - color: isSelected - ? (isDark - ? Colors.white.withValues(alpha: 0.1) - : Theme.of( - context, - ).colorScheme.primaryContainer.withValues(alpha: 0.5)) - : Colors.transparent, - borderRadius: BorderRadius.circular( - LayoutConstants.borderRadiusMedium, - ), - ), - child: Row( - children: [ - Icon( - route.icon, - size: 20, - color: isSelected - ? Theme.of(context).colorScheme.primary - : Theme.of(context).colorScheme.onSurfaceVariant, - ), - const SizedBox(width: 16), - Expanded( - child: Text( - route.name, - style: Theme.of(context).textTheme.bodyMedium?.copyWith( - color: isSelected - ? Theme.of(context).colorScheme.primary - : Theme.of(context).colorScheme.onSurface, - fontWeight: FontWeight.w500, - ), - ), - ), - ], - ), - ), - ), - ), - ); - } -} diff --git a/mobile/packages/ui/showcase/pubspec.lock b/mobile/packages/ui/showcase/pubspec.lock deleted file mode 100644 index c676b23c53..0000000000 --- a/mobile/packages/ui/showcase/pubspec.lock +++ /dev/null @@ -1,377 +0,0 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - async: - dependency: transitive - description: - name: async - sha256: "758e6d74e971c3e5aceb4110bfd6698efc7f501675bcfe0c775459a8140750eb" - url: "https://pub.dev" - source: hosted - version: "2.13.0" - boolean_selector: - dependency: transitive - description: - name: boolean_selector - sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea" - url: "https://pub.dev" - source: hosted - version: "2.1.2" - characters: - dependency: transitive - description: - name: characters - sha256: faf38497bda5ead2a8c7615f4f7939df04333478bf32e4173fcb06d428b5716b - url: "https://pub.dev" - source: hosted - version: "1.4.1" - clock: - dependency: transitive - description: - name: clock - sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b - url: "https://pub.dev" - source: hosted - version: "1.1.2" - collection: - dependency: transitive - description: - name: collection - sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76" - url: "https://pub.dev" - source: hosted - version: "1.19.1" - crypto: - dependency: transitive - description: - name: crypto - sha256: c8ea0233063ba03258fbcf2ca4d6dadfefe14f02fab57702265467a19f27fadf - url: "https://pub.dev" - source: hosted - version: "3.0.7" - device_info_plus: - dependency: transitive - description: - name: device_info_plus - sha256: "98f28b42168cc509abc92f88518882fd58061ea372d7999aecc424345c7bff6a" - url: "https://pub.dev" - source: hosted - version: "11.5.0" - device_info_plus_platform_interface: - dependency: transitive - description: - name: device_info_plus_platform_interface - sha256: e1ea89119e34903dca74b883d0dd78eb762814f97fb6c76f35e9ff74d261a18f - url: "https://pub.dev" - source: hosted - version: "7.0.3" - fake_async: - dependency: transitive - description: - name: fake_async - sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44" - url: "https://pub.dev" - source: hosted - version: "1.3.3" - ffi: - dependency: transitive - description: - name: ffi - sha256: d07d37192dbf97461359c1518788f203b0c9102cfd2c35a716b823741219542c - url: "https://pub.dev" - source: hosted - version: "2.1.5" - file: - dependency: transitive - description: - name: file - sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4 - url: "https://pub.dev" - source: hosted - version: "7.0.1" - fixnum: - dependency: transitive - description: - name: fixnum - sha256: b6dc7065e46c974bc7c5f143080a6764ec7a4be6da1285ececdc37be96de53be - url: "https://pub.dev" - source: hosted - version: "1.1.1" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_lints: - dependency: "direct dev" - description: - name: flutter_lints - sha256: "3105dc8492f6183fb076ccf1f351ac3d60564bff92e20bfc4af9cc1651f4e7e1" - url: "https://pub.dev" - source: hosted - version: "6.0.0" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - flutter_web_plugins: - dependency: transitive - description: flutter - source: sdk - version: "0.0.0" - go_router: - dependency: "direct main" - description: - name: go_router - sha256: "5540e4a3f416dd4a93458257b908eb88353cbd0fb5b0a3d1bd7d849ba1e88735" - url: "https://pub.dev" - source: hosted - version: "17.2.1" - immich_ui: - dependency: "direct main" - description: - path: ".." - relative: true - source: path - version: "0.0.0" - irondash_engine_context: - dependency: transitive - description: - name: irondash_engine_context - sha256: "2bb0bc13dfda9f5aaef8dde06ecc5feb1379f5bb387d59716d799554f3f305d7" - url: "https://pub.dev" - source: hosted - version: "0.5.5" - irondash_message_channel: - dependency: transitive - description: - name: irondash_message_channel - sha256: b4101669776509c76133b8917ab8cfc704d3ad92a8c450b92934dd8884a2f060 - url: "https://pub.dev" - source: hosted - version: "0.7.0" - leak_tracker: - dependency: transitive - description: - name: leak_tracker - sha256: "33e2e26bdd85a0112ec15400c8cbffea70d0f9c3407491f672a2fad47915e2de" - url: "https://pub.dev" - source: hosted - version: "11.0.2" - leak_tracker_flutter_testing: - dependency: transitive - description: - name: leak_tracker_flutter_testing - sha256: "1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1" - url: "https://pub.dev" - source: hosted - version: "3.0.10" - leak_tracker_testing: - dependency: transitive - description: - name: leak_tracker_testing - sha256: "8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1" - url: "https://pub.dev" - source: hosted - version: "3.0.2" - lints: - dependency: transitive - description: - name: lints - sha256: "12f842a479589fea194fe5c5a3095abc7be0c1f2ddfa9a0e76aed1dbd26a87df" - url: "https://pub.dev" - source: hosted - version: "6.1.0" - logging: - dependency: transitive - description: - name: logging - sha256: c8245ada5f1717ed44271ed1c26b8ce85ca3228fd2ffdb75468ab01979309d61 - url: "https://pub.dev" - source: hosted - version: "1.3.0" - matcher: - dependency: transitive - description: - name: matcher - sha256: dc0b7dc7651697ea4ff3e69ef44b0407ea32c487a39fff6a4004fa585e901861 - url: "https://pub.dev" - source: hosted - version: "0.12.19" - material_color_utilities: - dependency: transitive - description: - name: material_color_utilities - sha256: "9c337007e82b1889149c82ed242ed1cb24a66044e30979c44912381e9be4c48b" - url: "https://pub.dev" - source: hosted - version: "0.13.0" - meta: - dependency: transitive - description: - name: meta - sha256: "23f08335362185a5ea2ad3a4e597f1375e78bce8a040df5c600c8d3552ef2394" - url: "https://pub.dev" - source: hosted - version: "1.17.0" - path: - dependency: transitive - description: - name: path - sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5" - url: "https://pub.dev" - source: hosted - version: "1.9.1" - pixel_snap: - dependency: transitive - description: - name: pixel_snap - sha256: "677410ea37b07cd37ecb6d5e6c0d8d7615a7cf3bd92ba406fd1ac57e937d1fb0" - url: "https://pub.dev" - source: hosted - version: "0.1.5" - plugin_platform_interface: - dependency: transitive - description: - name: plugin_platform_interface - sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02" - url: "https://pub.dev" - source: hosted - version: "2.1.8" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.0" - source_span: - dependency: transitive - description: - name: source_span - sha256: "254ee5351d6cb365c859e20ee823c3bb479bf4a293c22d17a9f1bf144ce86f7c" - url: "https://pub.dev" - source: hosted - version: "1.10.1" - stack_trace: - dependency: transitive - description: - name: stack_trace - sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1" - url: "https://pub.dev" - source: hosted - version: "1.12.1" - stream_channel: - dependency: transitive - description: - name: stream_channel - sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d" - url: "https://pub.dev" - source: hosted - version: "2.1.4" - string_scanner: - dependency: transitive - description: - name: string_scanner - sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43" - url: "https://pub.dev" - source: hosted - version: "1.4.1" - super_clipboard: - dependency: transitive - description: - name: super_clipboard - sha256: e73f3bb7e66cc9260efa1dc507f979138e7e106c3521e2dda2d0311f6d728a16 - url: "https://pub.dev" - source: hosted - version: "0.9.1" - super_native_extensions: - dependency: transitive - description: - name: super_native_extensions - sha256: b9611dcb68f1047d6f3ef11af25e4e68a21b1a705bbcc3eb8cb4e9f5c3148569 - url: "https://pub.dev" - source: hosted - version: "0.9.1" - syntax_highlight: - dependency: "direct main" - description: - name: syntax_highlight - sha256: "4d3ba40658cadba6ba55d697f29f00b43538ebb6eb4a0ca0e895c568eaced138" - url: "https://pub.dev" - source: hosted - version: "0.5.0" - term_glyph: - dependency: transitive - description: - name: term_glyph - sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e" - url: "https://pub.dev" - source: hosted - version: "1.2.2" - test_api: - dependency: transitive - description: - name: test_api - sha256: "8161c84903fd860b26bfdefb7963b3f0b68fee7adea0f59ef805ecca346f0c7a" - url: "https://pub.dev" - source: hosted - version: "0.7.10" - typed_data: - dependency: transitive - description: - name: typed_data - sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006 - url: "https://pub.dev" - source: hosted - version: "1.4.0" - uuid: - dependency: transitive - description: - name: uuid - sha256: a11b666489b1954e01d992f3d601b1804a33937b5a8fe677bd26b8a9f96f96e8 - url: "https://pub.dev" - source: hosted - version: "4.5.2" - vector_math: - dependency: transitive - description: - name: vector_math - sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b - url: "https://pub.dev" - source: hosted - version: "2.2.0" - vm_service: - dependency: transitive - description: - name: vm_service - sha256: "45caa6c5917fa127b5dbcfbd1fa60b14e583afdc08bfc96dda38886ca252eb60" - url: "https://pub.dev" - source: hosted - version: "15.0.2" - web: - dependency: transitive - description: - name: web - sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a" - url: "https://pub.dev" - source: hosted - version: "1.1.1" - win32: - dependency: transitive - description: - name: win32 - sha256: d7cb55e04cd34096cd3a79b3330245f54cb96a370a1c27adb3c84b917de8b08e - url: "https://pub.dev" - source: hosted - version: "5.15.0" - win32_registry: - dependency: transitive - description: - name: win32_registry - sha256: "6f1b564492d0147b330dd794fee8f512cec4977957f310f9951b5f9d83618dae" - url: "https://pub.dev" - source: hosted - version: "2.1.0" -sdks: - dart: ">=3.11.0 <4.0.0" - flutter: ">=3.35.0" diff --git a/mobile/packages/ui/showcase/pubspec.yaml b/mobile/packages/ui/showcase/pubspec.yaml deleted file mode 100644 index 6353600ce3..0000000000 --- a/mobile/packages/ui/showcase/pubspec.yaml +++ /dev/null @@ -1,47 +0,0 @@ -name: showcase -publish_to: 'none' - -version: 1.0.0+1 - -environment: - sdk: ^3.11.0 - -dependencies: - flutter: - sdk: flutter - immich_ui: - path: ../ - go_router: ^17.2.1 - syntax_highlight: ^0.5.0 - -dev_dependencies: - flutter_test: - sdk: flutter - flutter_lints: ^6.0.0 - -flutter: - uses-material-design: true - assets: - - assets/ - - assets/themes/ - - lib/pages/components/examples/ - - fonts: - - family: GoogleSans - fonts: - - asset: ../../../fonts/GoogleSans/GoogleSans-Regular.ttf - - asset: ../../../fonts/GoogleSans/GoogleSans-Italic.ttf - style: italic - - asset: ../../../fonts/GoogleSans/GoogleSans-Medium.ttf - weight: 500 - - asset: ../../../fonts/GoogleSans/GoogleSans-SemiBold.ttf - weight: 600 - - asset: ../../../fonts/GoogleSans/GoogleSans-Bold.ttf - weight: 700 - - family: GoogleSansCode - fonts: - - asset: ../../../fonts/GoogleSansCode/GoogleSansCode-Regular.ttf - - asset: ../../../fonts/GoogleSansCode/GoogleSansCode-Medium.ttf - weight: 500 - - asset: ../../../fonts/GoogleSansCode/GoogleSansCode-SemiBold.ttf - weight: 600 \ No newline at end of file diff --git a/mobile/packages/ui/showcase/web/favicon.ico b/mobile/packages/ui/showcase/web/favicon.ico deleted file mode 100644 index 7ec34e9e53..0000000000 Binary files a/mobile/packages/ui/showcase/web/favicon.ico and /dev/null differ diff --git a/mobile/packages/ui/showcase/web/icons/Icon-maskable-192.png b/mobile/packages/ui/showcase/web/icons/Icon-maskable-192.png deleted file mode 100644 index 49fd3ae289..0000000000 Binary files a/mobile/packages/ui/showcase/web/icons/Icon-maskable-192.png and /dev/null differ diff --git a/mobile/packages/ui/showcase/web/icons/Icon-maskable-512.png b/mobile/packages/ui/showcase/web/icons/Icon-maskable-512.png deleted file mode 100644 index a7220554bc..0000000000 Binary files a/mobile/packages/ui/showcase/web/icons/Icon-maskable-512.png and /dev/null differ diff --git a/mobile/packages/ui/showcase/web/icons/apple-icon-180.png b/mobile/packages/ui/showcase/web/icons/apple-icon-180.png deleted file mode 100644 index 4e642631a3..0000000000 Binary files a/mobile/packages/ui/showcase/web/icons/apple-icon-180.png and /dev/null differ diff --git a/mobile/packages/ui/showcase/web/index.html b/mobile/packages/ui/showcase/web/index.html deleted file mode 100644 index abf42ad1fd..0000000000 --- a/mobile/packages/ui/showcase/web/index.html +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - - - - - - - - - - - - - - - @immich/ui - - - - - - diff --git a/mobile/packages/ui/showcase/web/manifest.json b/mobile/packages/ui/showcase/web/manifest.json deleted file mode 100644 index 25b44bd1ae..0000000000 --- a/mobile/packages/ui/showcase/web/manifest.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "name": "@immich/ui Showcase", - "short_name": "@immich/ui", - "start_url": ".", - "display": "standalone", - "background_color": "#FCFCFD", - "theme_color": "#4250AF", - "description": "Immich UI component library showcase and documentation", - "orientation": "landscape", - "prefer_related_applications": false, - "icons": [ - { - "src": "icons/Icon-maskable-192.png", - "sizes": "192x192", - "type": "image/png", - "purpose": "any" - }, - { - "src": "icons/Icon-maskable-192.png", - "sizes": "192x192", - "type": "image/png", - "purpose": "maskable" - }, - { - "src": "icons/Icon-maskable-512.png", - "sizes": "512x512", - "type": "image/png", - "purpose": "any" - }, - { - "src": "icons/Icon-maskable-512.png", - "sizes": "512x512", - "type": "image/png", - "purpose": "maskable" - } - ] -} diff --git a/mobile/pigeon/native_sync_api.dart b/mobile/pigeon/native_sync_api.dart index e215ab9447..9775973694 100644 --- a/mobile/pigeon/native_sync_api.dart +++ b/mobile/pigeon/native_sync_api.dart @@ -11,14 +11,7 @@ import 'package:pigeon/pigeon.dart'; dartPackageName: 'immich_mobile', ), ) -enum PlatformAssetPlaybackStyle { - unknown, - image, - video, - imageAnimated, - livePhoto, - videoLooping, -} +enum PlatformAssetPlaybackStyle { unknown, image, video, imageAnimated, livePhoto, videoLooping } class PlatformAsset { final String id; @@ -142,6 +135,9 @@ abstract class NativeSyncApi { @TaskQueue(type: TaskQueueType.serialBackgroundThread) Map> getTrashedAssets(); + @async + bool restoreFromTrashById(String mediaId, int type); + @TaskQueue(type: TaskQueueType.serialBackgroundThread) List getCloudIdForAssetIds(List assetIds); } diff --git a/mobile/pigeon/network_api.dart b/mobile/pigeon/network_api.dart index 704efed770..a701995342 100644 --- a/mobile/pigeon/network_api.dart +++ b/mobile/pigeon/network_api.dart @@ -44,4 +44,6 @@ abstract class NetworkApi { int getClientPointer(); void setRequestHeaders(Map headers, List serverUrls, String? token); + + String getAppGroupId(); } diff --git a/mobile/pigeon/permission_api.dart b/mobile/pigeon/permission_api.dart new file mode 100644 index 0000000000..a924f32e27 --- /dev/null +++ b/mobile/pigeon/permission_api.dart @@ -0,0 +1,23 @@ +import 'package:pigeon/pigeon.dart'; + +@ConfigurePigeon( + PigeonOptions( + dartOut: 'lib/platform/permission_api.g.dart', + swiftOut: 'ios/Runner/Permission/PermissionApi.g.swift', + swiftOptions: SwiftOptions(), + kotlinOut: 'android/app/src/main/kotlin/app/alextran/immich/permission/PermissionApi.g.kt', + kotlinOptions: KotlinOptions(package: 'app.alextran.immich.permission'), + dartOptions: DartOptions(), + dartPackageName: 'immich_mobile', + ), +) +@HostApi() +abstract class PermissionApi { + bool hasManageMediaPermission(); + + @async + bool requestManageMediaPermission(); + + @async + bool manageMediaPermission(); +} diff --git a/mobile/pubspec.lock b/mobile/pubspec.lock index 5be3ff9768..2708e80c78 100644 --- a/mobile/pubspec.lock +++ b/mobile/pubspec.lock @@ -5,18 +5,18 @@ packages: dependency: transitive description: name: _fe_analyzer_shared - sha256: "8d7ff3948166b8ec5da0fbb5962000926b8e02f2ed9b3e51d1738905fbd4c98d" + sha256: "3b19a47f6ea7c2632760777c78174f47f6aec1e05f0cd611380d4593b8af1dbc" url: "https://pub.dev" source: hosted - version: "93.0.0" + version: "96.0.0" analyzer: dependency: transitive description: name: analyzer - sha256: de7148ed2fcec579b19f122c1800933dfa028f6d9fd38a152b04b1516cec120b + sha256: "0c516bc4ad36a1a75759e54d5047cb9d15cded4459df01aa35a0b5ec7db2c2a0" url: "https://pub.dev" source: hosted - version: "10.0.1" + version: "10.2.0" ansicolor: dependency: transitive description: @@ -133,10 +133,10 @@ packages: dependency: transitive description: name: build - sha256: aadd943f4f8cc946882c954c187e6115a84c98c81ad1d9c6cbf0895a8c85da9c + sha256: a156715e7cd728130c592f30552575908aae5b100005fbc1f0fb16b3c03a3d10 url: "https://pub.dev" source: hosted - version: "4.0.5" + version: "4.0.6" build_config: dependency: transitive description: @@ -157,10 +157,10 @@ packages: dependency: "direct dev" description: name: build_runner - sha256: "521daf8d189deb79ba474e43a696b41c49fb3987818dbacf3308f1e03673a75e" + sha256: "1523ce62448ebac2c15a8ba5fbad8acac169788658a7dd2a1c2d9c2a9318b9a6" url: "https://pub.dev" source: hosted - version: "2.13.1" + version: "2.15.0" built_collection: dependency: transitive description: @@ -173,10 +173,10 @@ packages: dependency: transitive description: name: built_value - sha256: "0730c18c770d05636a8f945c32a4d7d81cb6e0f0148c8db4ad12e7748f7e49af" + sha256: "34e4067d30ce212937df995f03b69992eea683539ceeac7f679a1f1eba055b56" url: "https://pub.dev" source: hosted - version: "8.12.5" + version: "8.12.6" cast: dependency: "direct main" description: @@ -358,18 +358,18 @@ packages: dependency: "direct main" description: name: drift - sha256: "055c249d1f91be5a47fe447f88afc24c4ca6f4cd6c5ed66767b4797d48acc2e5" + sha256: "8033500116b24398fba0cca0369cc31678cd627c01e41753a61186911cea743e" url: "https://pub.dev" source: hosted - version: "2.32.1" + version: "2.33.0" drift_dev: dependency: "direct dev" description: name: drift_dev - sha256: "88a9de3af8571518148a6d8a513b57779fd1e60a026d3ab8a481a878fba01d91" + sha256: b3dd5b75e30522a91da8abda9f5bb17230cb038097f6d15fa75d42bb563428aa url: "https://pub.dev" source: hosted - version: "2.32.1" + version: "2.33.0" drift_flutter: dependency: "direct main" description: @@ -613,10 +613,10 @@ packages: dependency: "direct main" description: name: flutter_svg - sha256: "1ded017b39c8e15c8948ea855070a5ff8ff8b3d5e83f3446e02d6bb12add7ad9" + sha256: "35882981abcbfb8c15b286f0cd690ff25bac12d95eff3e25ee207f37d4c42e7f" url: "https://pub.dev" source: hosted - version: "2.2.4" + version: "2.3.0" flutter_test: dependency: "direct dev" description: flutter @@ -772,10 +772,10 @@ packages: dependency: transitive description: name: hooks - sha256: e79ed1e8e1929bc6ecb6ec85f0cb519c887aa5b423705ded0d0f2d9226def388 + sha256: "025f060e86d2d4c3c47b56e33caf7f93bf9283340f26d23424ebcfccf34f621e" url: "https://pub.dev" source: hosted - version: "1.0.2" + version: "1.0.3" hooks_riverpod: dependency: "direct main" description: @@ -844,18 +844,18 @@ packages: dependency: "direct main" description: name: image_picker - sha256: "784210112be18ea55f69d7076e2c656a4e24949fa9e76429fe53af0c0f4fa320" + sha256: "91c025426c2881c551100bce834e201c835a170151545f58d17da5180ca7d9ac" url: "https://pub.dev" source: hosted - version: "1.2.1" + version: "1.2.2" image_picker_android: dependency: transitive description: name: image_picker_android - sha256: "66810af8e99b2657ee98e5c6f02064f69bb63f7a70e343937f70946c5f8c6622" + sha256: d5b3e1774af29c9ab00103afb0d4614070f924d2e0057ac867ec98800114793f url: "https://pub.dev" source: hosted - version: "0.8.13+16" + version: "0.8.13+17" image_picker_for_web: dependency: transitive description: @@ -952,10 +952,10 @@ packages: dependency: transitive description: name: json_annotation - sha256: cb09e7dac6210041fad964ed7fbee004f14258b4eca4040f72d1234062ace4c8 + sha256: "2a743920d81b7910627f68ee2c9ac1fc0bfee32b9fc3403587d7c6791ca12f80" url: "https://pub.dev" source: hosted - version: "4.11.0" + version: "4.12.0" leak_tracker: dependency: transitive description: @@ -984,10 +984,10 @@ packages: dependency: transitive description: name: lean_builder - sha256: ee4117b03e93a4eb83e1a78c8e7a1dc22188d43bb142309982be48673a1b3a53 + sha256: c16e95ddf7b2d49dd551357b7212fe2ce9f13ec7ad1b1e660c157184031e96c0 url: "https://pub.dev" source: hosted - version: "0.1.7" + version: "0.1.10" lints: dependency: transitive description: @@ -1088,10 +1088,10 @@ packages: dependency: transitive description: name: meta - sha256: "23f08335362185a5ea2ad3a4e597f1375e78bce8a040df5c600c8d3552ef2394" + sha256: "1741988757a65eb6b36abe716829688cf01910bbf91c34354ff7ec1c3de2b349" url: "https://pub.dev" source: hosted - version: "1.17.0" + version: "1.18.0" mime: dependency: transitive description: @@ -1429,6 +1429,14 @@ packages: url: "https://pub.dev" source: hosted version: "4.1.0" + record_use: + dependency: transitive + description: + name: record_use + sha256: "2551bd8eecfe95d14ae75f6021ad0248be5c27f138c2ec12fcb52b500b3ba1ed" + url: "https://pub.dev" + source: hosted + version: "0.6.0" riverpod: dependency: transitive description: @@ -1607,10 +1615,10 @@ packages: dependency: transitive description: name: source_gen - sha256: "732792cfd197d2161a65bb029606a46e0a18ff30ef9e141a7a82172b05ea8ecd" + sha256: ec37cc0e6694374cbef59ed79685572c870a54ede6fa30a3e420feb3adffea02 url: "https://pub.dev" source: hosted - version: "4.2.2" + version: "4.2.3" source_span: dependency: transitive description: @@ -1647,10 +1655,10 @@ packages: dependency: transitive description: name: sqlparser - sha256: ab2b467425f1d4f3acfa5fd11a08226f7d6c26ff102c06be1807e1dff34e050b + sha256: ecdc06d4a7d79dcbc928d99afd2f7f5b0f98a637c46f89be83d911617f759978 url: "https://pub.dev" source: hosted - version: "0.44.3" + version: "0.44.4" stack_trace: dependency: transitive description: @@ -1711,10 +1719,10 @@ packages: dependency: transitive description: name: test_api - sha256: "8161c84903fd860b26bfdefb7963b3f0b68fee7adea0f59ef805ecca346f0c7a" + sha256: "949a932224383300f01be9221c39180316445ecb8e7547f70a41a35bf421fb9e" url: "https://pub.dev" source: hosted - version: "0.7.10" + version: "0.7.11" thumbhash: dependency: "direct main" description: @@ -1767,10 +1775,10 @@ packages: dependency: transitive description: name: url_launcher_android - sha256: "3bb000251e55d4a209aa0e2e563309dc9bb2befea2295fd0cec1f51760aac572" + sha256: "17bc677f0b301615530dd1d67e0a9828cafa2d0b6b6eae4cd3679b7eac4a273c" url: "https://pub.dev" source: hosted - version: "6.3.29" + version: "6.3.30" url_launcher_ios: dependency: transitive description: @@ -1807,10 +1815,10 @@ packages: dependency: transitive description: name: url_launcher_web - sha256: d0412fcf4c6b31ecfdb7762359b7206ffba3bbffd396c6d9f9c4616ece476c1f + sha256: "85c81589622fbc87c1c683aaea164d3604a7777495a79d91e39ffcdec39ddb34" url: "https://pub.dev" source: hosted - version: "2.4.2" + version: "2.4.3" url_launcher_windows: dependency: transitive description: @@ -1831,10 +1839,10 @@ packages: dependency: transitive description: name: vector_graphics - sha256: "81da85e9ca8885ade47f9685b953cb098970d11be4821ac765580a6607ea4373" + sha256: "2306c03da2ba81724afeb589c351ebbc0aa7d86005925be8f8735856dbe5e42d" url: "https://pub.dev" source: hosted - version: "1.1.21" + version: "1.2.2" vector_graphics_codec: dependency: transitive description: @@ -1847,10 +1855,10 @@ packages: dependency: transitive description: name: vector_graphics_compiler - sha256: "5a88dd14c0954a5398af544651c7fb51b457a2a556949bfb25369b210ef73a74" + sha256: b9b3f391857781aa96acacef96066f2f49b4cd03cf9fce3ca4d8da2ef5ea129e url: "https://pub.dev" source: hosted - version: "1.2.0" + version: "1.2.3" vector_math: dependency: transitive description: @@ -1863,10 +1871,10 @@ packages: dependency: transitive description: name: vm_service - sha256: "046d3928e16fa4dc46e8350415661755ab759d9fc97fc21b5ab295f71e4f0499" + sha256: "0016aef94fc66495ac78af5859181e3f3bf2026bd8eecc72b9565601e19ab360" url: "https://pub.dev" source: hosted - version: "15.1.0" + version: "15.2.0" wakelock_plus: dependency: "direct main" description: @@ -1879,10 +1887,10 @@ packages: dependency: transitive description: name: wakelock_plus_platform_interface - sha256: "14b2e5b9e35c2631e656913c47adecdd71633ae92896a27a64c8f1fcfabc21cc" + sha256: b13f99e992e7ae6a152e16c5559d3c07ff445b13330192662494e614ca3e7d7b url: "https://pub.dev" source: hosted - version: "1.5.0" + version: "1.5.1" watcher: dependency: transitive description: @@ -1988,5 +1996,5 @@ packages: source: hosted version: "3.1.3" sdks: - dart: ">=3.11.0 <4.0.0" - flutter: "3.41.9" + dart: ">=3.12.0 <4.0.0" + flutter: "3.44.0" diff --git a/mobile/pubspec.yaml b/mobile/pubspec.yaml index 491ecada07..5070cd3af9 100644 --- a/mobile/pubspec.yaml +++ b/mobile/pubspec.yaml @@ -5,8 +5,8 @@ publish_to: 'none' version: 3.0.0+3047 environment: - sdk: '>=3.11.0 <4.0.0' - flutter: 3.41.9 + sdk: '>=3.12.0 <4.0.0' + flutter: 3.44.0 dependencies: async: ^2.13.1 diff --git a/mobile/test/domain/services/local_sync_service_test.dart b/mobile/test/domain/services/local_sync_service_test.dart index c15bf9b2d0..e0e6b663a7 100644 --- a/mobile/test/domain/services/local_sync_service_test.dart +++ b/mobile/test/domain/services/local_sync_service_test.dart @@ -10,17 +10,15 @@ import 'package:immich_mobile/entities/store.entity.dart'; import 'package:immich_mobile/infrastructure/repositories/db.repository.dart'; import 'package:immich_mobile/infrastructure/repositories/local_album.repository.dart'; import 'package:immich_mobile/infrastructure/repositories/local_asset.repository.dart'; -import 'package:immich_mobile/infrastructure/repositories/storage.repository.dart'; import 'package:immich_mobile/infrastructure/repositories/store.repository.dart'; import 'package:immich_mobile/infrastructure/repositories/trashed_local_asset.repository.dart'; import 'package:immich_mobile/platform/native_sync_api.g.dart'; -import 'package:immich_mobile/repositories/local_files_manager.repository.dart'; +import 'package:immich_mobile/repositories/asset_media.repository.dart'; import 'package:mocktail/mocktail.dart'; import '../../domain/service.mock.dart'; import '../../fixtures/asset.stub.dart'; import '../../infrastructure/repository.mock.dart'; -import '../../mocks/asset_entity.mock.dart'; import '../../repository.mocks.dart'; void main() { @@ -28,8 +26,8 @@ void main() { late DriftLocalAlbumRepository mockLocalAlbumRepository; late DriftLocalAssetRepository mockLocalAssetRepository; late DriftTrashedLocalAssetRepository mockTrashedLocalAssetRepository; - late LocalFilesManagerRepository mockLocalFilesManager; - late StorageRepository mockStorageRepository; + late AssetMediaRepository mockAssetMediaRepository; + late MockPermissionRepository mockPermissionRepository; late MockNativeSyncApi mockNativeSyncApi; late Drift db; @@ -51,8 +49,8 @@ void main() { mockLocalAlbumRepository = MockLocalAlbumRepository(); mockLocalAssetRepository = MockLocalAssetRepository(); mockTrashedLocalAssetRepository = MockTrashedLocalAssetRepository(); - mockLocalFilesManager = MockLocalFilesManagerRepository(); - mockStorageRepository = MockStorageRepository(); + mockAssetMediaRepository = MockAssetMediaRepository(); + mockPermissionRepository = MockPermissionRepository(); mockNativeSyncApi = MockNativeSyncApi(); when(() => mockNativeSyncApi.shouldFullSync()).thenAnswer((_) async => false); @@ -65,25 +63,28 @@ void main() { when(() => mockTrashedLocalAssetRepository.getToTrash()).thenAnswer((_) async => {}); when(() => mockTrashedLocalAssetRepository.applyRestoredAssets(any())).thenAnswer((_) async {}); when(() => mockTrashedLocalAssetRepository.trashLocalAsset(any())).thenAnswer((_) async {}); - when(() => mockLocalFilesManager.moveToTrash(any>())).thenAnswer((_) async => true); + when(() => mockAssetMediaRepository.deleteAll(any())).thenAnswer((invocation) async { + final ids = invocation.positionalArguments.first as List; + return ids; + }); sut = LocalSyncService( localAlbumRepository: mockLocalAlbumRepository, localAssetRepository: mockLocalAssetRepository, trashedLocalAssetRepository: mockTrashedLocalAssetRepository, - localFilesManager: mockLocalFilesManager, - storageRepository: mockStorageRepository, + assetMediaRepository: mockAssetMediaRepository, + permissionRepository: mockPermissionRepository, nativeSyncApi: mockNativeSyncApi, ); await Store.put(StoreKey.manageLocalMediaAndroid, false); - when(() => mockLocalFilesManager.hasManageMediaPermission()).thenAnswer((_) async => false); + when(() => mockPermissionRepository.hasManageMediaPermission()).thenAnswer((_) async => false); }); group('LocalSyncService - syncTrashedAssets gating', () { test('invokes syncTrashedAssets when Android flag enabled and permission granted', () async { await Store.put(StoreKey.manageLocalMediaAndroid, true); - when(() => mockLocalFilesManager.hasManageMediaPermission()).thenAnswer((_) async => true); + when(() => mockPermissionRepository.hasManageMediaPermission()).thenAnswer((_) async => true); await sut.sync(); @@ -93,7 +94,7 @@ void main() { test('skips syncTrashedAssets when store flag disabled', () async { await Store.put(StoreKey.manageLocalMediaAndroid, false); - when(() => mockLocalFilesManager.hasManageMediaPermission()).thenAnswer((_) async => true); + when(() => mockPermissionRepository.hasManageMediaPermission()).thenAnswer((_) async => true); await sut.sync(); @@ -102,7 +103,7 @@ void main() { test('skips syncTrashedAssets when MANAGE_MEDIA permission absent', () async { await Store.put(StoreKey.manageLocalMediaAndroid, true); - when(() => mockLocalFilesManager.hasManageMediaPermission()).thenAnswer((_) async => false); + when(() => mockPermissionRepository.hasManageMediaPermission()).thenAnswer((_) async => false); await sut.sync(); @@ -114,7 +115,7 @@ void main() { addTearDown(() => debugDefaultTargetPlatformOverride = TargetPlatform.android); await Store.put(StoreKey.manageLocalMediaAndroid, true); - when(() => mockLocalFilesManager.hasManageMediaPermission()).thenAnswer((_) async => true); + when(() => mockPermissionRepository.hasManageMediaPermission()).thenAnswer((_) async => true); await sut.sync(); @@ -131,13 +132,13 @@ void main() { durationMs: 0, orientation: 0, isFavorite: false, - playbackStyle: PlatformAssetPlaybackStyle.image + playbackStyle: PlatformAssetPlaybackStyle.image, ); final assetsToRestore = [LocalAssetStub.image1]; when(() => mockTrashedLocalAssetRepository.getToRestore()).thenAnswer((_) async => assetsToRestore); final restoredIds = ['image1']; - when(() => mockLocalFilesManager.restoreAssetsFromTrash(any())).thenAnswer((invocation) async { + when(() => mockAssetMediaRepository.restoreAssetsFromTrash(any())).thenAnswer((invocation) async { final Iterable requested = invocation.positionalArguments.first as Iterable; expect(requested, orderedEquals(assetsToRestore)); return restoredIds; @@ -150,10 +151,6 @@ void main() { }, ); - final assetEntity = MockAssetEntity(); - when(() => assetEntity.getMediaUrl()).thenAnswer((_) async => 'content://local-trash'); - when(() => mockStorageRepository.getAssetEntityForAsset(localAssetToTrash)).thenAnswer((_) async => assetEntity); - await sut.processTrashedAssets({ 'album-a': [platformAsset], }); @@ -168,12 +165,11 @@ void main() { expect(trashedEntry.asset.name, platformAsset.name); verify(() => mockTrashedLocalAssetRepository.getToTrash()).called(1); - verify(() => mockLocalFilesManager.restoreAssetsFromTrash(any())).called(1); + verify(() => mockAssetMediaRepository.restoreAssetsFromTrash(any())).called(1); verify(() => mockTrashedLocalAssetRepository.applyRestoredAssets(restoredIds)).called(1); - verify(() => mockStorageRepository.getAssetEntityForAsset(localAssetToTrash)).called(1); - final moveArgs = verify(() => mockLocalFilesManager.moveToTrash(captureAny())).captured.single as List; - expect(moveArgs, ['content://local-trash']); + final moveArgs = verify(() => mockAssetMediaRepository.deleteAll(captureAny())).captured.single as List; + expect(moveArgs, ['local-trash']); final trashArgs = verify(() => mockTrashedLocalAssetRepository.trashLocalAsset(captureAny())).captured.single as Map>; @@ -181,6 +177,26 @@ void main() { expect(trashArgs['album-a'], [localAssetToTrash]); }); + test('records only local assets that were moved to device trash', () async { + final movedAsset = LocalAssetStub.image1.copyWith(id: 'moved-local', checksum: 'checksum-moved'); + final skippedAsset = LocalAssetStub.image2.copyWith(id: 'skipped-local', checksum: 'checksum-skipped'); + when(() => mockTrashedLocalAssetRepository.getToTrash()).thenAnswer( + (_) async => { + 'album-a': [movedAsset], + 'album-b': [skippedAsset], + }, + ); + when(() => mockAssetMediaRepository.deleteAll(any())).thenAnswer((_) async => ['moved-local']); + + await sut.processTrashedAssets({}); + + final trashArgs = + verify(() => mockTrashedLocalAssetRepository.trashLocalAsset(captureAny())).captured.single + as Map>; + expect(trashArgs.keys, ['album-a']); + expect(trashArgs['album-a'], [movedAsset]); + }); + test('does not attempt restore when repository has no assets to restore', () async { when(() => mockTrashedLocalAssetRepository.getToRestore()).thenAnswer((_) async => []); @@ -190,7 +206,7 @@ void main() { verify(() => mockTrashedLocalAssetRepository.processTrashSnapshot(captureAny())).captured.single as Iterable; expect(trashedSnapshot, isEmpty); - verifyNever(() => mockLocalFilesManager.restoreAssetsFromTrash(any())); + verifyNever(() => mockAssetMediaRepository.restoreAssetsFromTrash(any())); verifyNever(() => mockTrashedLocalAssetRepository.applyRestoredAssets(any())); }); @@ -199,7 +215,7 @@ void main() { await sut.processTrashedAssets({}); - verifyNever(() => mockLocalFilesManager.moveToTrash(any())); + verifyNever(() => mockAssetMediaRepository.deleteAll(any())); verifyNever(() => mockTrashedLocalAssetRepository.trashLocalAsset(any())); }); }); @@ -215,7 +231,7 @@ void main() { isFavorite: false, createdAt: 1700000000, updatedAt: 1732000000, - playbackStyle: PlatformAssetPlaybackStyle.image + playbackStyle: PlatformAssetPlaybackStyle.image, ); final localAsset = platformAsset.toLocalAsset(); diff --git a/mobile/test/domain/services/log_service_test.dart b/mobile/test/domain/services/log_service_test.dart index ee596f449e..6a82d1dce3 100644 --- a/mobile/test/domain/services/log_service_test.dart +++ b/mobile/test/domain/services/log_service_test.dart @@ -1,9 +1,9 @@ import 'package:collection/collection.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:immich_mobile/constants/constants.dart'; -import 'package:immich_mobile/domain/models/config/system_config.dart'; +import 'package:immich_mobile/domain/models/config/app_config.dart'; import 'package:immich_mobile/domain/models/log.model.dart'; -import 'package:immich_mobile/domain/models/metadata_key.dart'; +import 'package:immich_mobile/domain/models/settings_key.dart'; import 'package:immich_mobile/domain/services/log.service.dart'; import 'package:immich_mobile/infrastructure/repositories/log.repository.dart'; import 'package:logging/logging.dart'; @@ -29,23 +29,23 @@ final _kWarnLog = LogMessage( void main() { late LogService sut; late LogRepository mockLogRepo; - late MockMetadataRepository mockMetadataRepository; + late MockSettingsRepository mockSettingsRepository; setUp(() async { mockLogRepo = MockLogRepository(); - mockMetadataRepository = MockMetadataRepository(); + mockSettingsRepository = MockSettingsRepository(); registerFallbackValue(_kInfoLog); registerFallbackValue(LogLevel.info); when(() => mockLogRepo.truncate(limit: any(named: 'limit'))).thenAnswer((_) async => {}); - when(() => mockMetadataRepository.systemConfig).thenReturn(const SystemConfig(logLevel: LogLevel.fine)); - when(() => mockMetadataRepository.write(MetadataKey.logLevel, any())).thenAnswer((_) async {}); + when(() => mockSettingsRepository.appConfig).thenReturn(const AppConfig(logLevel: LogLevel.fine)); + when(() => mockSettingsRepository.write(SettingsKey.logLevel, any())).thenAnswer((_) async {}); when(() => mockLogRepo.getAll()).thenAnswer((_) async => []); when(() => mockLogRepo.insert(any())).thenAnswer((_) async => true); when(() => mockLogRepo.insertAll(any())).thenAnswer((_) async => true); - sut = await LogService.create(logRepository: mockLogRepo, metadataRepository: mockMetadataRepository); + sut = await LogService.create(logRepository: mockLogRepo, settingsRepository: mockSettingsRepository); }); tearDown(() async { @@ -59,7 +59,7 @@ void main() { }); test('Sets log level based on the metadata repository', () { - verify(() => mockMetadataRepository.systemConfig).called(1); + verify(() => mockSettingsRepository.appConfig).called(1); expect(Logger.root.level, Level.FINE); }); }); @@ -71,7 +71,7 @@ void main() { test('Updates the log level via metadata repository', () { final captured = verify( - () => mockMetadataRepository.write(MetadataKey.logLevel, captureAny()), + () => mockSettingsRepository.write(SettingsKey.logLevel, captureAny()), ).captured.firstOrNull; expect(captured, LogLevel.shout); }); @@ -86,7 +86,7 @@ void main() { TestUtils.fakeAsync((time) async { sut = await LogService.create( logRepository: mockLogRepo, - metadataRepository: mockMetadataRepository, + settingsRepository: mockSettingsRepository, shouldBuffer: true, ); @@ -104,7 +104,7 @@ void main() { TestUtils.fakeAsync((time) async { sut = await LogService.create( logRepository: mockLogRepo, - metadataRepository: mockMetadataRepository, + settingsRepository: mockSettingsRepository, shouldBuffer: true, ); @@ -125,7 +125,7 @@ void main() { TestUtils.fakeAsync((time) async { sut = await LogService.create( logRepository: mockLogRepo, - metadataRepository: mockMetadataRepository, + settingsRepository: mockSettingsRepository, shouldBuffer: false, ); @@ -159,7 +159,7 @@ void main() { TestUtils.fakeAsync((time) async { sut = await LogService.create( logRepository: mockLogRepo, - metadataRepository: mockMetadataRepository, + settingsRepository: mockSettingsRepository, shouldBuffer: true, ); diff --git a/mobile/test/domain/services/sync_stream_service_test.dart b/mobile/test/domain/services/sync_stream_service_test.dart index 1bee1dccde..ef29997e0b 100644 --- a/mobile/test/domain/services/sync_stream_service_test.dart +++ b/mobile/test/domain/services/sync_stream_service_test.dart @@ -12,12 +12,11 @@ import 'package:immich_mobile/domain/services/sync_stream.service.dart'; import 'package:immich_mobile/entities/store.entity.dart'; import 'package:immich_mobile/infrastructure/repositories/db.repository.dart'; import 'package:immich_mobile/infrastructure/repositories/local_asset.repository.dart'; -import 'package:immich_mobile/infrastructure/repositories/storage.repository.dart'; import 'package:immich_mobile/infrastructure/repositories/store.repository.dart'; import 'package:immich_mobile/infrastructure/repositories/sync_api.repository.dart'; import 'package:immich_mobile/infrastructure/repositories/sync_stream.repository.dart'; import 'package:immich_mobile/infrastructure/repositories/trashed_local_asset.repository.dart'; -import 'package:immich_mobile/repositories/local_files_manager.repository.dart'; +import 'package:immich_mobile/repositories/asset_media.repository.dart'; import 'package:immich_mobile/utils/semver.dart'; import 'package:mocktail/mocktail.dart'; import 'package:openapi/api.dart'; @@ -26,7 +25,6 @@ import '../../api.mocks.dart'; import '../../fixtures/asset.stub.dart'; import '../../fixtures/sync_stream.stub.dart'; import '../../infrastructure/repository.mock.dart'; -import '../../mocks/asset_entity.mock.dart'; import '../../repository.mocks.dart'; import '../../service.mocks.dart'; @@ -52,8 +50,8 @@ void main() { late SyncApiRepository mockSyncApiRepo; late DriftLocalAssetRepository mockLocalAssetRepo; late DriftTrashedLocalAssetRepository mockTrashedLocalAssetRepo; - late LocalFilesManagerRepository mockLocalFilesManagerRepo; - late StorageRepository mockStorageRepo; + late AssetMediaRepository mockAssetMediaRepo; + late MockPermissionRepository mockPermissionRepo; late MockApiService mockApi; late MockServerApi mockServerApi; late MockSyncMigrationRepository mockSyncMigrationRepo; @@ -86,8 +84,8 @@ void main() { mockSyncApiRepo = MockSyncApiRepository(); mockLocalAssetRepo = MockLocalAssetRepository(); mockTrashedLocalAssetRepo = MockTrashedLocalAssetRepository(); - mockLocalFilesManagerRepo = MockLocalFilesManagerRepository(); - mockStorageRepo = MockStorageRepository(); + mockAssetMediaRepo = MockAssetMediaRepository(); + mockPermissionRepo = MockPermissionRepository(); mockAbortCallbackWrapper = _MockAbortCallbackWrapper(); mockResetCallbackWrapper = _MockAbortCallbackWrapper(); mockApi = MockApiService(); @@ -159,8 +157,8 @@ void main() { syncStreamRepository: mockSyncStreamRepo, localAssetRepository: mockLocalAssetRepo, trashedLocalAssetRepository: mockTrashedLocalAssetRepo, - localFilesManager: mockLocalFilesManagerRepo, - storageRepository: mockStorageRepo, + assetMediaRepository: mockAssetMediaRepo, + permissionRepository: mockPermissionRepo, api: mockApi, syncMigrationRepository: mockSyncMigrationRepo, ); @@ -170,10 +168,12 @@ void main() { when(() => mockTrashedLocalAssetRepo.getToRestore()).thenAnswer((_) async => []); when(() => mockTrashedLocalAssetRepo.applyRestoredAssets(any())).thenAnswer((_) async {}); hasManageMediaPermission = false; - when(() => mockLocalFilesManagerRepo.hasManageMediaPermission()).thenAnswer((_) async => hasManageMediaPermission); - when(() => mockLocalFilesManagerRepo.moveToTrash(any())).thenAnswer((_) async => true); - when(() => mockLocalFilesManagerRepo.restoreAssetsFromTrash(any())).thenAnswer((_) async => []); - when(() => mockStorageRepo.getAssetEntityForAsset(any())).thenAnswer((_) async => null); + when(() => mockPermissionRepo.hasManageMediaPermission()).thenAnswer((_) async => hasManageMediaPermission); + when(() => mockAssetMediaRepo.deleteAll(any())).thenAnswer((invocation) async { + final ids = invocation.positionalArguments.first as List; + return ids; + }); + when(() => mockAssetMediaRepo.restoreAssetsFromTrash(any())).thenAnswer((_) async => []); await Store.put(StoreKey.manageLocalMediaAndroid, false); }); @@ -241,8 +241,8 @@ void main() { syncStreamRepository: mockSyncStreamRepo, localAssetRepository: mockLocalAssetRepo, trashedLocalAssetRepository: mockTrashedLocalAssetRepo, - localFilesManager: mockLocalFilesManagerRepo, - storageRepository: mockStorageRepo, + assetMediaRepository: mockAssetMediaRepo, + permissionRepository: mockPermissionRepo, cancelChecker: cancellationChecker.call, api: mockApi, syncMigrationRepository: mockSyncMigrationRepo, @@ -282,8 +282,8 @@ void main() { syncStreamRepository: mockSyncStreamRepo, localAssetRepository: mockLocalAssetRepo, trashedLocalAssetRepository: mockTrashedLocalAssetRepo, - localFilesManager: mockLocalFilesManagerRepo, - storageRepository: mockStorageRepo, + assetMediaRepository: mockAssetMediaRepo, + permissionRepository: mockPermissionRepo, cancelChecker: cancellationChecker.call, api: mockApi, syncMigrationRepository: mockSyncMigrationRepo, @@ -424,18 +424,10 @@ void main() { return assetsByAlbum; }); - final localEntity = MockAssetEntity(); - when(() => localEntity.getMediaUrl()).thenAnswer((_) async => 'content://local-only'); - when(() => mockStorageRepo.getAssetEntityForAsset(localAsset)).thenAnswer((_) async => localEntity); - - final mergedEntity = MockAssetEntity(); - when(() => mergedEntity.getMediaUrl()).thenAnswer((_) async => 'content://merged-local'); - when(() => mockStorageRepo.getAssetEntityForAsset(mergedAsset)).thenAnswer((_) async => mergedEntity); - - when(() => mockLocalFilesManagerRepo.moveToTrash(any())).thenAnswer((invocation) async { - final urls = invocation.positionalArguments.first as List; - expect(urls, unorderedEquals(['content://local-only', 'content://merged-local'])); - return true; + when(() => mockAssetMediaRepo.deleteAll(any())).thenAnswer((invocation) async { + final ids = invocation.positionalArguments.first as List; + expect(ids, unorderedEquals(['local-only', 'merged-local'])); + return ids; }); final events = [ @@ -461,10 +453,51 @@ void main() { await simulateEvents(events); - verify(() => mockTrashedLocalAssetRepo.trashLocalAsset(assetsByAlbum)).called(1); + final trashArgs = + verify(() => mockTrashedLocalAssetRepo.trashLocalAsset(captureAny())).captured.single + as Map>; + expect(trashArgs.keys, unorderedEquals(['album-a', 'album-b'])); + expect(trashArgs['album-a'], [localAsset]); + expect(trashArgs['album-b'], [mergedAsset]); + verify(() => mockAssetMediaRepo.deleteAll(any())).called(1); verify(() => mockSyncApiRepo.ack(['asset-remote-only-3'])).called(1); }); + test("records only assets that were moved to device trash", () async { + final movedAsset = LocalAssetStub.image1.copyWith(id: 'moved-local', checksum: 'checksum-moved'); + final skippedAsset = LocalAssetStub.image2.copyWith(id: 'skipped-local', checksum: 'checksum-skipped'); + when(() => mockLocalAssetRepo.getAssetsFromBackupAlbums(any())).thenAnswer( + (_) async => { + 'album-a': [movedAsset], + 'album-b': [skippedAsset], + }, + ); + when(() => mockAssetMediaRepo.deleteAll(any())).thenAnswer((_) async => ['moved-local']); + + final events = [ + SyncStreamStub.assetTrashed( + id: 'remote-moved', + checksum: movedAsset.checksum!, + ack: 'asset-remote-moved', + trashedAt: DateTime(2025, 5, 1), + ), + SyncStreamStub.assetTrashed( + id: 'remote-skipped', + checksum: skippedAsset.checksum!, + ack: 'asset-remote-skipped', + trashedAt: DateTime(2025, 5, 2), + ), + ]; + + await simulateEvents(events); + + final trashArgs = + verify(() => mockTrashedLocalAssetRepo.trashLocalAsset(captureAny())).captured.single + as Map>; + expect(trashArgs.keys, ['album-a']); + expect(trashArgs['album-a'], [movedAsset]); + }); + test("skips device trashing when no local assets match the remote trash payload", () async { final events = [ SyncStreamStub.assetTrashed( @@ -478,7 +511,7 @@ void main() { await simulateEvents(events); verify(() => mockLocalAssetRepo.getAssetsFromBackupAlbums(any())).called(1); - verifyNever(() => mockLocalFilesManagerRepo.moveToTrash(any())); + verifyNever(() => mockAssetMediaRepo.deleteAll(any())); verifyNever(() => mockTrashedLocalAssetRepo.trashLocalAsset(any())); }); @@ -494,7 +527,7 @@ void main() { await simulateEvents(events); verify(() => mockLocalAssetRepo.getAssetsFromBackupAlbums(any())).called(1); - verifyNever(() => mockLocalFilesManagerRepo.moveToTrash(any())); + verifyNever(() => mockAssetMediaRepo.deleteAll(any())); verify(() => mockSyncStreamRepo.deleteAssetsV1(any())).called(1); }); @@ -505,7 +538,7 @@ void main() { when(() => mockTrashedLocalAssetRepo.getToRestore()).thenAnswer((_) async => trashedAssets); final restoredIds = ['trashed-1']; - when(() => mockLocalFilesManagerRepo.restoreAssetsFromTrash(any())).thenAnswer((invocation) async { + when(() => mockAssetMediaRepo.restoreAssetsFromTrash(any())).thenAnswer((invocation) async { final Iterable requestedAssets = invocation.positionalArguments.first as Iterable; expect(requestedAssets, orderedEquals(trashedAssets)); return restoredIds; diff --git a/mobile/test/drift/main/generated/schema.dart b/mobile/test/drift/main/generated/schema.dart index a1bae8f6dd..c5d57e9a4b 100644 --- a/mobile/test/drift/main/generated/schema.dart +++ b/mobile/test/drift/main/generated/schema.dart @@ -30,6 +30,7 @@ import 'schema_v23.dart' as v23; import 'schema_v24.dart' as v24; import 'schema_v25.dart' as v25; import 'schema_v26.dart' as v26; +import 'schema_v27.dart' as v27; class GeneratedHelper implements SchemaInstantiationHelper { @override @@ -87,6 +88,8 @@ class GeneratedHelper implements SchemaInstantiationHelper { return v25.DatabaseAtV25(db); case 26: return v26.DatabaseAtV26(db); + case 27: + return v27.DatabaseAtV27(db); default: throw MissingSchemaException(version, versions); } @@ -119,5 +122,6 @@ class GeneratedHelper implements SchemaInstantiationHelper { 24, 25, 26, + 27, ]; } diff --git a/mobile/test/drift/main/generated/schema_v27.dart b/mobile/test/drift/main/generated/schema_v27.dart new file mode 100644 index 0000000000..2b02946175 --- /dev/null +++ b/mobile/test/drift/main/generated/schema_v27.dart @@ -0,0 +1,9384 @@ +// dart format width=80 +import 'dart:typed_data' as i2; +// GENERATED BY drift_dev, DO NOT MODIFY. +// ignore_for_file: type=lint,unused_import +// +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, + $customConstraints: 'NOT NULL', + ); + late final GeneratedColumn name = GeneratedColumn( + 'name', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL', + ); + late final GeneratedColumn email = GeneratedColumn( + 'email', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL', + ); + late final GeneratedColumn hasProfileImage = GeneratedColumn( + 'has_profile_image', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: + 'NOT NULL DEFAULT 0 CHECK (has_profile_image IN (0, 1))', + defaultValue: const CustomExpression('0'), + ); + late final GeneratedColumn profileChangedAt = GeneratedColumn( + 'profile_changed_at', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: false, + $customConstraints: 'NOT NULL DEFAULT CURRENT_TIMESTAMP', + defaultValue: const CustomExpression('CURRENT_TIMESTAMP'), + ); + late final GeneratedColumn avatarColor = GeneratedColumn( + 'avatar_color', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NOT NULL DEFAULT 0', + 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.int, + data['${effectivePrefix}has_profile_image'], + )!, + profileChangedAt: attachedDatabase.typeMapping.read( + DriftSqlType.string, + 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; + @override + List get customConstraints => const ['PRIMARY KEY(id)']; + @override + bool get dontWriteConstraints => true; +} + +class UserEntityData extends DataClass implements Insertable { + final String id; + final String name; + final String email; + final int hasProfileImage; + final String 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, + int? hasProfileImage, + String? 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, + $customConstraints: 'NOT NULL', + ); + late final GeneratedColumn type = GeneratedColumn( + 'type', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL', + ); + late final GeneratedColumn createdAt = GeneratedColumn( + 'created_at', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: false, + $customConstraints: 'NOT NULL DEFAULT CURRENT_TIMESTAMP', + defaultValue: const CustomExpression('CURRENT_TIMESTAMP'), + ); + late final GeneratedColumn updatedAt = GeneratedColumn( + 'updated_at', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: false, + $customConstraints: 'NOT NULL DEFAULT CURRENT_TIMESTAMP', + defaultValue: const CustomExpression('CURRENT_TIMESTAMP'), + ); + late final GeneratedColumn width = GeneratedColumn( + 'width', + aliasedName, + true, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn height = GeneratedColumn( + 'height', + aliasedName, + true, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn durationMs = GeneratedColumn( + 'duration_ms', + aliasedName, + true, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn id = GeneratedColumn( + 'id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL', + ); + late final GeneratedColumn checksum = GeneratedColumn( + 'checksum', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL', + ); + late final GeneratedColumn isFavorite = GeneratedColumn( + 'is_favorite', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NOT NULL DEFAULT 0 CHECK (is_favorite IN (0, 1))', + defaultValue: const CustomExpression('0'), + ); + late final GeneratedColumn ownerId = GeneratedColumn( + 'owner_id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL REFERENCES user_entity(id)ON DELETE CASCADE', + ); + late final GeneratedColumn localDateTime = GeneratedColumn( + 'local_date_time', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn thumbHash = GeneratedColumn( + 'thumb_hash', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn deletedAt = GeneratedColumn( + 'deleted_at', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn uploadedAt = GeneratedColumn( + 'uploaded_at', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn livePhotoVideoId = GeneratedColumn( + 'live_photo_video_id', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn visibility = GeneratedColumn( + 'visibility', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL', + ); + late final GeneratedColumn stackId = GeneratedColumn( + 'stack_id', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn libraryId = GeneratedColumn( + 'library_id', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn isEdited = GeneratedColumn( + 'is_edited', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NOT NULL DEFAULT 0 CHECK (is_edited IN (0, 1))', + defaultValue: const CustomExpression('0'), + ); + @override + List get $columns => [ + name, + type, + createdAt, + updatedAt, + width, + height, + durationMs, + id, + checksum, + isFavorite, + ownerId, + localDateTime, + thumbHash, + deletedAt, + uploadedAt, + livePhotoVideoId, + visibility, + stackId, + libraryId, + isEdited, + ]; + @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.string, + data['${effectivePrefix}created_at'], + )!, + updatedAt: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}updated_at'], + )!, + width: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}width'], + ), + height: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}height'], + ), + durationMs: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}duration_ms'], + ), + id: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}id'], + )!, + checksum: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}checksum'], + )!, + isFavorite: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}is_favorite'], + )!, + ownerId: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}owner_id'], + )!, + localDateTime: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}local_date_time'], + ), + thumbHash: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}thumb_hash'], + ), + deletedAt: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}deleted_at'], + ), + uploadedAt: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}uploaded_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'], + ), + isEdited: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}is_edited'], + )!, + ); + } + + @override + RemoteAssetEntity createAlias(String alias) { + return RemoteAssetEntity(attachedDatabase, alias); + } + + @override + bool get withoutRowId => true; + @override + bool get isStrict => true; + @override + List get customConstraints => const ['PRIMARY KEY(id)']; + @override + bool get dontWriteConstraints => true; +} + +class RemoteAssetEntityData extends DataClass + implements Insertable { + final String name; + final int type; + final String createdAt; + final String updatedAt; + final int? width; + final int? height; + final int? durationMs; + final String id; + final String checksum; + final int isFavorite; + final String ownerId; + final String? localDateTime; + final String? thumbHash; + final String? deletedAt; + final String? uploadedAt; + final String? livePhotoVideoId; + final int visibility; + final String? stackId; + final String? libraryId; + final int isEdited; + const RemoteAssetEntityData({ + required this.name, + required this.type, + required this.createdAt, + required this.updatedAt, + this.width, + this.height, + this.durationMs, + required this.id, + required this.checksum, + required this.isFavorite, + required this.ownerId, + this.localDateTime, + this.thumbHash, + this.deletedAt, + this.uploadedAt, + this.livePhotoVideoId, + required this.visibility, + this.stackId, + this.libraryId, + required this.isEdited, + }); + @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 || durationMs != null) { + map['duration_ms'] = Variable(durationMs); + } + 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 || uploadedAt != null) { + map['uploaded_at'] = Variable(uploadedAt); + } + 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); + } + map['is_edited'] = Variable(isEdited); + 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']), + durationMs: serializer.fromJson(json['durationMs']), + 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']), + uploadedAt: serializer.fromJson(json['uploadedAt']), + livePhotoVideoId: serializer.fromJson(json['livePhotoVideoId']), + visibility: serializer.fromJson(json['visibility']), + stackId: serializer.fromJson(json['stackId']), + libraryId: serializer.fromJson(json['libraryId']), + isEdited: serializer.fromJson(json['isEdited']), + ); + } + @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), + 'durationMs': serializer.toJson(durationMs), + '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), + 'uploadedAt': serializer.toJson(uploadedAt), + 'livePhotoVideoId': serializer.toJson(livePhotoVideoId), + 'visibility': serializer.toJson(visibility), + 'stackId': serializer.toJson(stackId), + 'libraryId': serializer.toJson(libraryId), + 'isEdited': serializer.toJson(isEdited), + }; + } + + RemoteAssetEntityData copyWith({ + String? name, + int? type, + String? createdAt, + String? updatedAt, + Value width = const Value.absent(), + Value height = const Value.absent(), + Value durationMs = const Value.absent(), + String? id, + String? checksum, + int? isFavorite, + String? ownerId, + Value localDateTime = const Value.absent(), + Value thumbHash = const Value.absent(), + Value deletedAt = const Value.absent(), + Value uploadedAt = const Value.absent(), + Value livePhotoVideoId = const Value.absent(), + int? visibility, + Value stackId = const Value.absent(), + Value libraryId = const Value.absent(), + int? isEdited, + }) => 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, + durationMs: durationMs.present ? durationMs.value : this.durationMs, + 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, + uploadedAt: uploadedAt.present ? uploadedAt.value : this.uploadedAt, + 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, + isEdited: isEdited ?? this.isEdited, + ); + 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, + durationMs: data.durationMs.present + ? data.durationMs.value + : this.durationMs, + 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, + uploadedAt: data.uploadedAt.present + ? data.uploadedAt.value + : this.uploadedAt, + 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, + isEdited: data.isEdited.present ? data.isEdited.value : this.isEdited, + ); + } + + @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('durationMs: $durationMs, ') + ..write('id: $id, ') + ..write('checksum: $checksum, ') + ..write('isFavorite: $isFavorite, ') + ..write('ownerId: $ownerId, ') + ..write('localDateTime: $localDateTime, ') + ..write('thumbHash: $thumbHash, ') + ..write('deletedAt: $deletedAt, ') + ..write('uploadedAt: $uploadedAt, ') + ..write('livePhotoVideoId: $livePhotoVideoId, ') + ..write('visibility: $visibility, ') + ..write('stackId: $stackId, ') + ..write('libraryId: $libraryId, ') + ..write('isEdited: $isEdited') + ..write(')')) + .toString(); + } + + @override + int get hashCode => Object.hash( + name, + type, + createdAt, + updatedAt, + width, + height, + durationMs, + id, + checksum, + isFavorite, + ownerId, + localDateTime, + thumbHash, + deletedAt, + uploadedAt, + livePhotoVideoId, + visibility, + stackId, + libraryId, + isEdited, + ); + @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.durationMs == this.durationMs && + 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.uploadedAt == this.uploadedAt && + other.livePhotoVideoId == this.livePhotoVideoId && + other.visibility == this.visibility && + other.stackId == this.stackId && + other.libraryId == this.libraryId && + other.isEdited == this.isEdited); +} + +class RemoteAssetEntityCompanion + extends UpdateCompanion { + final Value name; + final Value type; + final Value createdAt; + final Value updatedAt; + final Value width; + final Value height; + final Value durationMs; + final Value id; + final Value checksum; + final Value isFavorite; + final Value ownerId; + final Value localDateTime; + final Value thumbHash; + final Value deletedAt; + final Value uploadedAt; + final Value livePhotoVideoId; + final Value visibility; + final Value stackId; + final Value libraryId; + final Value isEdited; + 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.durationMs = 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.uploadedAt = const Value.absent(), + this.livePhotoVideoId = const Value.absent(), + this.visibility = const Value.absent(), + this.stackId = const Value.absent(), + this.libraryId = const Value.absent(), + this.isEdited = 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.durationMs = 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.uploadedAt = const Value.absent(), + this.livePhotoVideoId = const Value.absent(), + required int visibility, + this.stackId = const Value.absent(), + this.libraryId = const Value.absent(), + this.isEdited = 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? durationMs, + Expression? id, + Expression? checksum, + Expression? isFavorite, + Expression? ownerId, + Expression? localDateTime, + Expression? thumbHash, + Expression? deletedAt, + Expression? uploadedAt, + Expression? livePhotoVideoId, + Expression? visibility, + Expression? stackId, + Expression? libraryId, + Expression? isEdited, + }) { + 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 (durationMs != null) 'duration_ms': durationMs, + 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 (uploadedAt != null) 'uploaded_at': uploadedAt, + 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, + if (isEdited != null) 'is_edited': isEdited, + }); + } + + RemoteAssetEntityCompanion copyWith({ + Value? name, + Value? type, + Value? createdAt, + Value? updatedAt, + Value? width, + Value? height, + Value? durationMs, + Value? id, + Value? checksum, + Value? isFavorite, + Value? ownerId, + Value? localDateTime, + Value? thumbHash, + Value? deletedAt, + Value? uploadedAt, + Value? livePhotoVideoId, + Value? visibility, + Value? stackId, + Value? libraryId, + Value? isEdited, + }) { + 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, + durationMs: durationMs ?? this.durationMs, + 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, + uploadedAt: uploadedAt ?? this.uploadedAt, + livePhotoVideoId: livePhotoVideoId ?? this.livePhotoVideoId, + visibility: visibility ?? this.visibility, + stackId: stackId ?? this.stackId, + libraryId: libraryId ?? this.libraryId, + isEdited: isEdited ?? this.isEdited, + ); + } + + @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 (durationMs.present) { + map['duration_ms'] = Variable(durationMs.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 (uploadedAt.present) { + map['uploaded_at'] = Variable(uploadedAt.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); + } + if (isEdited.present) { + map['is_edited'] = Variable(isEdited.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('durationMs: $durationMs, ') + ..write('id: $id, ') + ..write('checksum: $checksum, ') + ..write('isFavorite: $isFavorite, ') + ..write('ownerId: $ownerId, ') + ..write('localDateTime: $localDateTime, ') + ..write('thumbHash: $thumbHash, ') + ..write('deletedAt: $deletedAt, ') + ..write('uploadedAt: $uploadedAt, ') + ..write('livePhotoVideoId: $livePhotoVideoId, ') + ..write('visibility: $visibility, ') + ..write('stackId: $stackId, ') + ..write('libraryId: $libraryId, ') + ..write('isEdited: $isEdited') + ..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, + $customConstraints: 'NOT NULL', + ); + late final GeneratedColumn createdAt = GeneratedColumn( + 'created_at', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: false, + $customConstraints: 'NOT NULL DEFAULT CURRENT_TIMESTAMP', + defaultValue: const CustomExpression('CURRENT_TIMESTAMP'), + ); + late final GeneratedColumn updatedAt = GeneratedColumn( + 'updated_at', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: false, + $customConstraints: 'NOT NULL DEFAULT CURRENT_TIMESTAMP', + defaultValue: const CustomExpression('CURRENT_TIMESTAMP'), + ); + late final GeneratedColumn ownerId = GeneratedColumn( + 'owner_id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL REFERENCES user_entity(id)ON DELETE CASCADE', + ); + late final GeneratedColumn primaryAssetId = GeneratedColumn( + 'primary_asset_id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL', + ); + @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.string, + data['${effectivePrefix}created_at'], + )!, + updatedAt: attachedDatabase.typeMapping.read( + DriftSqlType.string, + 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; + @override + List get customConstraints => const ['PRIMARY KEY(id)']; + @override + bool get dontWriteConstraints => true; +} + +class StackEntityData extends DataClass implements Insertable { + final String id; + final String createdAt; + final String 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, + String? createdAt, + String? 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, + $customConstraints: 'NOT NULL', + ); + late final GeneratedColumn type = GeneratedColumn( + 'type', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL', + ); + late final GeneratedColumn createdAt = GeneratedColumn( + 'created_at', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: false, + $customConstraints: 'NOT NULL DEFAULT CURRENT_TIMESTAMP', + defaultValue: const CustomExpression('CURRENT_TIMESTAMP'), + ); + late final GeneratedColumn updatedAt = GeneratedColumn( + 'updated_at', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: false, + $customConstraints: 'NOT NULL DEFAULT CURRENT_TIMESTAMP', + defaultValue: const CustomExpression('CURRENT_TIMESTAMP'), + ); + late final GeneratedColumn width = GeneratedColumn( + 'width', + aliasedName, + true, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn height = GeneratedColumn( + 'height', + aliasedName, + true, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn durationMs = GeneratedColumn( + 'duration_ms', + aliasedName, + true, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn id = GeneratedColumn( + 'id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL', + ); + late final GeneratedColumn checksum = GeneratedColumn( + 'checksum', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn isFavorite = GeneratedColumn( + 'is_favorite', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NOT NULL DEFAULT 0 CHECK (is_favorite IN (0, 1))', + defaultValue: const CustomExpression('0'), + ); + late final GeneratedColumn orientation = GeneratedColumn( + 'orientation', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NOT NULL DEFAULT 0', + defaultValue: const CustomExpression('0'), + ); + late final GeneratedColumn iCloudId = GeneratedColumn( + 'i_cloud_id', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn adjustmentTime = GeneratedColumn( + 'adjustment_time', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn latitude = GeneratedColumn( + 'latitude', + aliasedName, + true, + type: DriftSqlType.double, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn longitude = GeneratedColumn( + 'longitude', + aliasedName, + true, + type: DriftSqlType.double, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn playbackStyle = GeneratedColumn( + 'playback_style', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NOT NULL DEFAULT 0', + defaultValue: const CustomExpression('0'), + ); + @override + List get $columns => [ + name, + type, + createdAt, + updatedAt, + width, + height, + durationMs, + id, + checksum, + isFavorite, + orientation, + iCloudId, + adjustmentTime, + latitude, + longitude, + playbackStyle, + ]; + @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.string, + data['${effectivePrefix}created_at'], + )!, + updatedAt: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}updated_at'], + )!, + width: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}width'], + ), + height: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}height'], + ), + durationMs: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}duration_ms'], + ), + id: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}id'], + )!, + checksum: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}checksum'], + ), + isFavorite: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}is_favorite'], + )!, + orientation: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}orientation'], + )!, + iCloudId: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}i_cloud_id'], + ), + adjustmentTime: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}adjustment_time'], + ), + latitude: attachedDatabase.typeMapping.read( + DriftSqlType.double, + data['${effectivePrefix}latitude'], + ), + longitude: attachedDatabase.typeMapping.read( + DriftSqlType.double, + data['${effectivePrefix}longitude'], + ), + playbackStyle: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}playback_style'], + )!, + ); + } + + @override + LocalAssetEntity createAlias(String alias) { + return LocalAssetEntity(attachedDatabase, alias); + } + + @override + bool get withoutRowId => true; + @override + bool get isStrict => true; + @override + List get customConstraints => const ['PRIMARY KEY(id)']; + @override + bool get dontWriteConstraints => true; +} + +class LocalAssetEntityData extends DataClass + implements Insertable { + final String name; + final int type; + final String createdAt; + final String updatedAt; + final int? width; + final int? height; + final int? durationMs; + final String id; + final String? checksum; + final int isFavorite; + final int orientation; + final String? iCloudId; + final String? adjustmentTime; + final double? latitude; + final double? longitude; + final int playbackStyle; + const LocalAssetEntityData({ + required this.name, + required this.type, + required this.createdAt, + required this.updatedAt, + this.width, + this.height, + this.durationMs, + required this.id, + this.checksum, + required this.isFavorite, + required this.orientation, + this.iCloudId, + this.adjustmentTime, + this.latitude, + this.longitude, + required this.playbackStyle, + }); + @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 || durationMs != null) { + map['duration_ms'] = Variable(durationMs); + } + map['id'] = Variable(id); + if (!nullToAbsent || checksum != null) { + map['checksum'] = Variable(checksum); + } + map['is_favorite'] = Variable(isFavorite); + map['orientation'] = Variable(orientation); + if (!nullToAbsent || iCloudId != null) { + map['i_cloud_id'] = Variable(iCloudId); + } + if (!nullToAbsent || adjustmentTime != null) { + map['adjustment_time'] = Variable(adjustmentTime); + } + if (!nullToAbsent || latitude != null) { + map['latitude'] = Variable(latitude); + } + if (!nullToAbsent || longitude != null) { + map['longitude'] = Variable(longitude); + } + map['playback_style'] = Variable(playbackStyle); + 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']), + durationMs: serializer.fromJson(json['durationMs']), + id: serializer.fromJson(json['id']), + checksum: serializer.fromJson(json['checksum']), + isFavorite: serializer.fromJson(json['isFavorite']), + orientation: serializer.fromJson(json['orientation']), + iCloudId: serializer.fromJson(json['iCloudId']), + adjustmentTime: serializer.fromJson(json['adjustmentTime']), + latitude: serializer.fromJson(json['latitude']), + longitude: serializer.fromJson(json['longitude']), + playbackStyle: serializer.fromJson(json['playbackStyle']), + ); + } + @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), + 'durationMs': serializer.toJson(durationMs), + 'id': serializer.toJson(id), + 'checksum': serializer.toJson(checksum), + 'isFavorite': serializer.toJson(isFavorite), + 'orientation': serializer.toJson(orientation), + 'iCloudId': serializer.toJson(iCloudId), + 'adjustmentTime': serializer.toJson(adjustmentTime), + 'latitude': serializer.toJson(latitude), + 'longitude': serializer.toJson(longitude), + 'playbackStyle': serializer.toJson(playbackStyle), + }; + } + + LocalAssetEntityData copyWith({ + String? name, + int? type, + String? createdAt, + String? updatedAt, + Value width = const Value.absent(), + Value height = const Value.absent(), + Value durationMs = const Value.absent(), + String? id, + Value checksum = const Value.absent(), + int? isFavorite, + int? orientation, + Value iCloudId = const Value.absent(), + Value adjustmentTime = const Value.absent(), + Value latitude = const Value.absent(), + Value longitude = const Value.absent(), + int? playbackStyle, + }) => 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, + durationMs: durationMs.present ? durationMs.value : this.durationMs, + id: id ?? this.id, + checksum: checksum.present ? checksum.value : this.checksum, + isFavorite: isFavorite ?? this.isFavorite, + orientation: orientation ?? this.orientation, + iCloudId: iCloudId.present ? iCloudId.value : this.iCloudId, + adjustmentTime: adjustmentTime.present + ? adjustmentTime.value + : this.adjustmentTime, + latitude: latitude.present ? latitude.value : this.latitude, + longitude: longitude.present ? longitude.value : this.longitude, + playbackStyle: playbackStyle ?? this.playbackStyle, + ); + 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, + durationMs: data.durationMs.present + ? data.durationMs.value + : this.durationMs, + 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, + iCloudId: data.iCloudId.present ? data.iCloudId.value : this.iCloudId, + adjustmentTime: data.adjustmentTime.present + ? data.adjustmentTime.value + : this.adjustmentTime, + latitude: data.latitude.present ? data.latitude.value : this.latitude, + longitude: data.longitude.present ? data.longitude.value : this.longitude, + playbackStyle: data.playbackStyle.present + ? data.playbackStyle.value + : this.playbackStyle, + ); + } + + @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('durationMs: $durationMs, ') + ..write('id: $id, ') + ..write('checksum: $checksum, ') + ..write('isFavorite: $isFavorite, ') + ..write('orientation: $orientation, ') + ..write('iCloudId: $iCloudId, ') + ..write('adjustmentTime: $adjustmentTime, ') + ..write('latitude: $latitude, ') + ..write('longitude: $longitude, ') + ..write('playbackStyle: $playbackStyle') + ..write(')')) + .toString(); + } + + @override + int get hashCode => Object.hash( + name, + type, + createdAt, + updatedAt, + width, + height, + durationMs, + id, + checksum, + isFavorite, + orientation, + iCloudId, + adjustmentTime, + latitude, + longitude, + playbackStyle, + ); + @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.durationMs == this.durationMs && + other.id == this.id && + other.checksum == this.checksum && + other.isFavorite == this.isFavorite && + other.orientation == this.orientation && + other.iCloudId == this.iCloudId && + other.adjustmentTime == this.adjustmentTime && + other.latitude == this.latitude && + other.longitude == this.longitude && + other.playbackStyle == this.playbackStyle); +} + +class LocalAssetEntityCompanion extends UpdateCompanion { + final Value name; + final Value type; + final Value createdAt; + final Value updatedAt; + final Value width; + final Value height; + final Value durationMs; + final Value id; + final Value checksum; + final Value isFavorite; + final Value orientation; + final Value iCloudId; + final Value adjustmentTime; + final Value latitude; + final Value longitude; + final Value playbackStyle; + 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.durationMs = const Value.absent(), + this.id = const Value.absent(), + this.checksum = const Value.absent(), + this.isFavorite = const Value.absent(), + this.orientation = const Value.absent(), + this.iCloudId = const Value.absent(), + this.adjustmentTime = const Value.absent(), + this.latitude = const Value.absent(), + this.longitude = const Value.absent(), + this.playbackStyle = 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.durationMs = const Value.absent(), + required String id, + this.checksum = const Value.absent(), + this.isFavorite = const Value.absent(), + this.orientation = const Value.absent(), + this.iCloudId = const Value.absent(), + this.adjustmentTime = const Value.absent(), + this.latitude = const Value.absent(), + this.longitude = const Value.absent(), + this.playbackStyle = 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? durationMs, + Expression? id, + Expression? checksum, + Expression? isFavorite, + Expression? orientation, + Expression? iCloudId, + Expression? adjustmentTime, + Expression? latitude, + Expression? longitude, + Expression? playbackStyle, + }) { + 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 (durationMs != null) 'duration_ms': durationMs, + if (id != null) 'id': id, + if (checksum != null) 'checksum': checksum, + if (isFavorite != null) 'is_favorite': isFavorite, + if (orientation != null) 'orientation': orientation, + if (iCloudId != null) 'i_cloud_id': iCloudId, + if (adjustmentTime != null) 'adjustment_time': adjustmentTime, + if (latitude != null) 'latitude': latitude, + if (longitude != null) 'longitude': longitude, + if (playbackStyle != null) 'playback_style': playbackStyle, + }); + } + + LocalAssetEntityCompanion copyWith({ + Value? name, + Value? type, + Value? createdAt, + Value? updatedAt, + Value? width, + Value? height, + Value? durationMs, + Value? id, + Value? checksum, + Value? isFavorite, + Value? orientation, + Value? iCloudId, + Value? adjustmentTime, + Value? latitude, + Value? longitude, + Value? playbackStyle, + }) { + 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, + durationMs: durationMs ?? this.durationMs, + id: id ?? this.id, + checksum: checksum ?? this.checksum, + isFavorite: isFavorite ?? this.isFavorite, + orientation: orientation ?? this.orientation, + iCloudId: iCloudId ?? this.iCloudId, + adjustmentTime: adjustmentTime ?? this.adjustmentTime, + latitude: latitude ?? this.latitude, + longitude: longitude ?? this.longitude, + playbackStyle: playbackStyle ?? this.playbackStyle, + ); + } + + @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 (durationMs.present) { + map['duration_ms'] = Variable(durationMs.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); + } + if (iCloudId.present) { + map['i_cloud_id'] = Variable(iCloudId.value); + } + if (adjustmentTime.present) { + map['adjustment_time'] = Variable(adjustmentTime.value); + } + if (latitude.present) { + map['latitude'] = Variable(latitude.value); + } + if (longitude.present) { + map['longitude'] = Variable(longitude.value); + } + if (playbackStyle.present) { + map['playback_style'] = Variable(playbackStyle.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('durationMs: $durationMs, ') + ..write('id: $id, ') + ..write('checksum: $checksum, ') + ..write('isFavorite: $isFavorite, ') + ..write('orientation: $orientation, ') + ..write('iCloudId: $iCloudId, ') + ..write('adjustmentTime: $adjustmentTime, ') + ..write('latitude: $latitude, ') + ..write('longitude: $longitude, ') + ..write('playbackStyle: $playbackStyle') + ..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, + $customConstraints: 'NOT NULL', + ); + late final GeneratedColumn name = GeneratedColumn( + 'name', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL', + ); + late final GeneratedColumn description = GeneratedColumn( + 'description', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: false, + $customConstraints: 'NOT NULL DEFAULT \'\'', + defaultValue: const CustomExpression('\'\''), + ); + late final GeneratedColumn createdAt = GeneratedColumn( + 'created_at', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: false, + $customConstraints: 'NOT NULL DEFAULT CURRENT_TIMESTAMP', + defaultValue: const CustomExpression('CURRENT_TIMESTAMP'), + ); + late final GeneratedColumn updatedAt = GeneratedColumn( + 'updated_at', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: false, + $customConstraints: 'NOT NULL DEFAULT CURRENT_TIMESTAMP', + defaultValue: const CustomExpression('CURRENT_TIMESTAMP'), + ); + late final GeneratedColumn thumbnailAssetId = GeneratedColumn( + 'thumbnail_asset_id', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + $customConstraints: + 'NULL REFERENCES remote_asset_entity(id)ON DELETE SET NULL', + ); + late final GeneratedColumn isActivityEnabled = GeneratedColumn( + 'is_activity_enabled', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: + 'NOT NULL DEFAULT 1 CHECK (is_activity_enabled IN (0, 1))', + defaultValue: const CustomExpression('1'), + ); + late final GeneratedColumn order = GeneratedColumn( + 'order', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL', + ); + @override + List get $columns => [ + id, + name, + description, + createdAt, + updatedAt, + 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.string, + data['${effectivePrefix}created_at'], + )!, + updatedAt: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}updated_at'], + )!, + thumbnailAssetId: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}thumbnail_asset_id'], + ), + isActivityEnabled: attachedDatabase.typeMapping.read( + DriftSqlType.int, + 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; + @override + List get customConstraints => const ['PRIMARY KEY(id)']; + @override + bool get dontWriteConstraints => true; +} + +class RemoteAlbumEntityData extends DataClass + implements Insertable { + final String id; + final String name; + final String description; + final String createdAt; + final String updatedAt; + final String? thumbnailAssetId; + final int isActivityEnabled; + final int order; + const RemoteAlbumEntityData({ + required this.id, + required this.name, + required this.description, + required this.createdAt, + required this.updatedAt, + 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); + 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']), + 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), + 'thumbnailAssetId': serializer.toJson(thumbnailAssetId), + 'isActivityEnabled': serializer.toJson(isActivityEnabled), + 'order': serializer.toJson(order), + }; + } + + RemoteAlbumEntityData copyWith({ + String? id, + String? name, + String? description, + String? createdAt, + String? updatedAt, + Value thumbnailAssetId = const Value.absent(), + int? isActivityEnabled, + int? order, + }) => RemoteAlbumEntityData( + id: id ?? this.id, + name: name ?? this.name, + description: description ?? this.description, + createdAt: createdAt ?? this.createdAt, + updatedAt: updatedAt ?? this.updatedAt, + 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, + 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('thumbnailAssetId: $thumbnailAssetId, ') + ..write('isActivityEnabled: $isActivityEnabled, ') + ..write('order: $order') + ..write(')')) + .toString(); + } + + @override + int get hashCode => Object.hash( + id, + name, + description, + createdAt, + updatedAt, + 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.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 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.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(), + this.thumbnailAssetId = const Value.absent(), + this.isActivityEnabled = const Value.absent(), + required int order, + }) : id = Value(id), + name = Value(name), + order = Value(order); + static Insertable custom({ + Expression? id, + Expression? name, + Expression? description, + Expression? createdAt, + Expression? updatedAt, + 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 (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? 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, + 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 (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('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, + $customConstraints: 'NOT NULL', + ); + late final GeneratedColumn name = GeneratedColumn( + 'name', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL', + ); + late final GeneratedColumn updatedAt = GeneratedColumn( + 'updated_at', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: false, + $customConstraints: 'NOT NULL DEFAULT CURRENT_TIMESTAMP', + defaultValue: const CustomExpression('CURRENT_TIMESTAMP'), + ); + late final GeneratedColumn backupSelection = GeneratedColumn( + 'backup_selection', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL', + ); + late final GeneratedColumn isIosSharedAlbum = GeneratedColumn( + 'is_ios_shared_album', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: + 'NOT NULL DEFAULT 0 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, + $customConstraints: + 'NULL REFERENCES remote_album_entity(id)ON DELETE SET NULL', + ); + late final GeneratedColumn marker = GeneratedColumn( + 'marker', + aliasedName, + true, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NULL 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.string, + data['${effectivePrefix}updated_at'], + )!, + backupSelection: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}backup_selection'], + )!, + isIosSharedAlbum: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}is_ios_shared_album'], + )!, + linkedRemoteAlbumId: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}linked_remote_album_id'], + ), + marker: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}marker'], + ), + ); + } + + @override + LocalAlbumEntity createAlias(String alias) { + return LocalAlbumEntity(attachedDatabase, alias); + } + + @override + bool get withoutRowId => true; + @override + bool get isStrict => true; + @override + List get customConstraints => const ['PRIMARY KEY(id)']; + @override + bool get dontWriteConstraints => true; +} + +class LocalAlbumEntityData extends DataClass + implements Insertable { + final String id; + final String name; + final String updatedAt; + final int backupSelection; + final int isIosSharedAlbum; + final String? linkedRemoteAlbumId; + final int? 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, + String? updatedAt, + int? backupSelection, + int? 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, + $customConstraints: + 'NOT NULL REFERENCES local_asset_entity(id)ON DELETE CASCADE', + ); + late final GeneratedColumn albumId = GeneratedColumn( + 'album_id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + $customConstraints: + 'NOT NULL REFERENCES local_album_entity(id)ON DELETE CASCADE', + ); + late final GeneratedColumn marker = GeneratedColumn( + 'marker', + aliasedName, + true, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NULL 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.int, + data['${effectivePrefix}marker'], + ), + ); + } + + @override + LocalAlbumAssetEntity createAlias(String alias) { + return LocalAlbumAssetEntity(attachedDatabase, alias); + } + + @override + bool get withoutRowId => true; + @override + bool get isStrict => true; + @override + List get customConstraints => const [ + 'PRIMARY KEY(asset_id, album_id)', + ]; + @override + bool get dontWriteConstraints => true; +} + +class LocalAlbumAssetEntityData extends DataClass + implements Insertable { + final String assetId; + final String albumId; + final int? 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, + $customConstraints: 'NOT NULL', + ); + late final GeneratedColumn name = GeneratedColumn( + 'name', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL', + ); + late final GeneratedColumn email = GeneratedColumn( + 'email', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL', + ); + late final GeneratedColumn isAdmin = GeneratedColumn( + 'is_admin', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NOT NULL DEFAULT 0 CHECK (is_admin IN (0, 1))', + defaultValue: const CustomExpression('0'), + ); + late final GeneratedColumn hasProfileImage = GeneratedColumn( + 'has_profile_image', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: + 'NOT NULL DEFAULT 0 CHECK (has_profile_image IN (0, 1))', + defaultValue: const CustomExpression('0'), + ); + late final GeneratedColumn profileChangedAt = GeneratedColumn( + 'profile_changed_at', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: false, + $customConstraints: 'NOT NULL DEFAULT CURRENT_TIMESTAMP', + defaultValue: const CustomExpression('CURRENT_TIMESTAMP'), + ); + late final GeneratedColumn avatarColor = GeneratedColumn( + 'avatar_color', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL', + ); + late final GeneratedColumn quotaSizeInBytes = GeneratedColumn( + 'quota_size_in_bytes', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NOT NULL DEFAULT 0', + defaultValue: const CustomExpression('0'), + ); + late final GeneratedColumn quotaUsageInBytes = GeneratedColumn( + 'quota_usage_in_bytes', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NOT NULL DEFAULT 0', + defaultValue: const CustomExpression('0'), + ); + late final GeneratedColumn pinCode = GeneratedColumn( + 'pin_code', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + @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.int, + data['${effectivePrefix}is_admin'], + )!, + hasProfileImage: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}has_profile_image'], + )!, + profileChangedAt: attachedDatabase.typeMapping.read( + DriftSqlType.string, + 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; + @override + List get customConstraints => const ['PRIMARY KEY(id)']; + @override + bool get dontWriteConstraints => true; +} + +class AuthUserEntityData extends DataClass + implements Insertable { + final String id; + final String name; + final String email; + final int isAdmin; + final int hasProfileImage; + final String 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, + int? isAdmin, + int? hasProfileImage, + String? 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, + $customConstraints: 'NOT NULL REFERENCES user_entity(id)ON DELETE CASCADE', + ); + late final GeneratedColumn key = GeneratedColumn( + 'key', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL', + ); + late final GeneratedColumn value = + GeneratedColumn( + 'value', + aliasedName, + false, + type: DriftSqlType.blob, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL', + ); + @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; + @override + List get customConstraints => const ['PRIMARY KEY(user_id, "key")']; + @override + bool get dontWriteConstraints => true; +} + +class UserMetadataEntityData extends DataClass + implements Insertable { + final String userId; + final int key; + final i2.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, + i2.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 i2.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, + $customConstraints: 'NOT NULL REFERENCES user_entity(id)ON DELETE CASCADE', + ); + late final GeneratedColumn sharedWithId = GeneratedColumn( + 'shared_with_id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL REFERENCES user_entity(id)ON DELETE CASCADE', + ); + late final GeneratedColumn inTimeline = GeneratedColumn( + 'in_timeline', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NOT NULL DEFAULT 0 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.int, + data['${effectivePrefix}in_timeline'], + )!, + ); + } + + @override + PartnerEntity createAlias(String alias) { + return PartnerEntity(attachedDatabase, alias); + } + + @override + bool get withoutRowId => true; + @override + bool get isStrict => true; + @override + List get customConstraints => const [ + 'PRIMARY KEY(shared_by_id, shared_with_id)', + ]; + @override + bool get dontWriteConstraints => true; +} + +class PartnerEntityData extends DataClass + implements Insertable { + final String sharedById; + final String sharedWithId; + final int 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, + int? 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, + $customConstraints: + 'NOT NULL REFERENCES remote_asset_entity(id)ON DELETE CASCADE', + ); + late final GeneratedColumn city = GeneratedColumn( + 'city', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn state = GeneratedColumn( + 'state', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn country = GeneratedColumn( + 'country', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn dateTimeOriginal = GeneratedColumn( + 'date_time_original', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn description = GeneratedColumn( + 'description', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn height = GeneratedColumn( + 'height', + aliasedName, + true, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn width = GeneratedColumn( + 'width', + aliasedName, + true, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn exposureTime = GeneratedColumn( + 'exposure_time', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn fNumber = GeneratedColumn( + 'f_number', + aliasedName, + true, + type: DriftSqlType.double, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn fileSize = GeneratedColumn( + 'file_size', + aliasedName, + true, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn focalLength = GeneratedColumn( + 'focal_length', + aliasedName, + true, + type: DriftSqlType.double, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn latitude = GeneratedColumn( + 'latitude', + aliasedName, + true, + type: DriftSqlType.double, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn longitude = GeneratedColumn( + 'longitude', + aliasedName, + true, + type: DriftSqlType.double, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn iso = GeneratedColumn( + 'iso', + aliasedName, + true, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn make = GeneratedColumn( + 'make', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn model = GeneratedColumn( + 'model', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn lens = GeneratedColumn( + 'lens', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn orientation = GeneratedColumn( + 'orientation', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn timeZone = GeneratedColumn( + 'time_zone', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn rating = GeneratedColumn( + 'rating', + aliasedName, + true, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn projectionType = GeneratedColumn( + 'projection_type', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + @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.string, + 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; + @override + List get customConstraints => const ['PRIMARY KEY(asset_id)']; + @override + bool get dontWriteConstraints => true; +} + +class RemoteExifEntityData extends DataClass + implements Insertable { + final String assetId; + final String? city; + final String? state; + final String? country; + final String? 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, + $customConstraints: + 'NOT NULL REFERENCES remote_asset_entity(id)ON DELETE CASCADE', + ); + late final GeneratedColumn albumId = GeneratedColumn( + 'album_id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + $customConstraints: + 'NOT NULL 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; + @override + List get customConstraints => const [ + 'PRIMARY KEY(asset_id, album_id)', + ]; + @override + bool get dontWriteConstraints => 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, + $customConstraints: + 'NOT NULL REFERENCES remote_album_entity(id)ON DELETE CASCADE', + ); + late final GeneratedColumn userId = GeneratedColumn( + 'user_id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL REFERENCES user_entity(id)ON DELETE CASCADE', + ); + late final GeneratedColumn role = GeneratedColumn( + 'role', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL', + ); + @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; + @override + List get customConstraints => const [ + 'PRIMARY KEY(album_id, user_id)', + ]; + @override + bool get dontWriteConstraints => 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 RemoteAssetCloudIdEntity extends Table + with TableInfo { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + RemoteAssetCloudIdEntity(this.attachedDatabase, [this._alias]); + late final GeneratedColumn assetId = GeneratedColumn( + 'asset_id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + $customConstraints: + 'NOT NULL REFERENCES remote_asset_entity(id)ON DELETE CASCADE', + ); + late final GeneratedColumn cloudId = GeneratedColumn( + 'cloud_id', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn createdAt = GeneratedColumn( + 'created_at', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn adjustmentTime = GeneratedColumn( + 'adjustment_time', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn latitude = GeneratedColumn( + 'latitude', + aliasedName, + true, + type: DriftSqlType.double, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn longitude = GeneratedColumn( + 'longitude', + aliasedName, + true, + type: DriftSqlType.double, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + @override + List get $columns => [ + assetId, + cloudId, + createdAt, + adjustmentTime, + latitude, + longitude, + ]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'remote_asset_cloud_id_entity'; + @override + Set get $primaryKey => {assetId}; + @override + RemoteAssetCloudIdEntityData map( + Map data, { + String? tablePrefix, + }) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return RemoteAssetCloudIdEntityData( + assetId: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}asset_id'], + )!, + cloudId: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}cloud_id'], + ), + createdAt: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}created_at'], + ), + adjustmentTime: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}adjustment_time'], + ), + latitude: attachedDatabase.typeMapping.read( + DriftSqlType.double, + data['${effectivePrefix}latitude'], + ), + longitude: attachedDatabase.typeMapping.read( + DriftSqlType.double, + data['${effectivePrefix}longitude'], + ), + ); + } + + @override + RemoteAssetCloudIdEntity createAlias(String alias) { + return RemoteAssetCloudIdEntity(attachedDatabase, alias); + } + + @override + bool get withoutRowId => true; + @override + bool get isStrict => true; + @override + List get customConstraints => const ['PRIMARY KEY(asset_id)']; + @override + bool get dontWriteConstraints => true; +} + +class RemoteAssetCloudIdEntityData extends DataClass + implements Insertable { + final String assetId; + final String? cloudId; + final String? createdAt; + final String? adjustmentTime; + final double? latitude; + final double? longitude; + const RemoteAssetCloudIdEntityData({ + required this.assetId, + this.cloudId, + this.createdAt, + this.adjustmentTime, + this.latitude, + this.longitude, + }); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['asset_id'] = Variable(assetId); + if (!nullToAbsent || cloudId != null) { + map['cloud_id'] = Variable(cloudId); + } + if (!nullToAbsent || createdAt != null) { + map['created_at'] = Variable(createdAt); + } + if (!nullToAbsent || adjustmentTime != null) { + map['adjustment_time'] = Variable(adjustmentTime); + } + if (!nullToAbsent || latitude != null) { + map['latitude'] = Variable(latitude); + } + if (!nullToAbsent || longitude != null) { + map['longitude'] = Variable(longitude); + } + return map; + } + + factory RemoteAssetCloudIdEntityData.fromJson( + Map json, { + ValueSerializer? serializer, + }) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return RemoteAssetCloudIdEntityData( + assetId: serializer.fromJson(json['assetId']), + cloudId: serializer.fromJson(json['cloudId']), + createdAt: serializer.fromJson(json['createdAt']), + adjustmentTime: serializer.fromJson(json['adjustmentTime']), + latitude: serializer.fromJson(json['latitude']), + longitude: serializer.fromJson(json['longitude']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'assetId': serializer.toJson(assetId), + 'cloudId': serializer.toJson(cloudId), + 'createdAt': serializer.toJson(createdAt), + 'adjustmentTime': serializer.toJson(adjustmentTime), + 'latitude': serializer.toJson(latitude), + 'longitude': serializer.toJson(longitude), + }; + } + + RemoteAssetCloudIdEntityData copyWith({ + String? assetId, + Value cloudId = const Value.absent(), + Value createdAt = const Value.absent(), + Value adjustmentTime = const Value.absent(), + Value latitude = const Value.absent(), + Value longitude = const Value.absent(), + }) => RemoteAssetCloudIdEntityData( + assetId: assetId ?? this.assetId, + cloudId: cloudId.present ? cloudId.value : this.cloudId, + createdAt: createdAt.present ? createdAt.value : this.createdAt, + adjustmentTime: adjustmentTime.present + ? adjustmentTime.value + : this.adjustmentTime, + latitude: latitude.present ? latitude.value : this.latitude, + longitude: longitude.present ? longitude.value : this.longitude, + ); + RemoteAssetCloudIdEntityData copyWithCompanion( + RemoteAssetCloudIdEntityCompanion data, + ) { + return RemoteAssetCloudIdEntityData( + assetId: data.assetId.present ? data.assetId.value : this.assetId, + cloudId: data.cloudId.present ? data.cloudId.value : this.cloudId, + createdAt: data.createdAt.present ? data.createdAt.value : this.createdAt, + adjustmentTime: data.adjustmentTime.present + ? data.adjustmentTime.value + : this.adjustmentTime, + latitude: data.latitude.present ? data.latitude.value : this.latitude, + longitude: data.longitude.present ? data.longitude.value : this.longitude, + ); + } + + @override + String toString() { + return (StringBuffer('RemoteAssetCloudIdEntityData(') + ..write('assetId: $assetId, ') + ..write('cloudId: $cloudId, ') + ..write('createdAt: $createdAt, ') + ..write('adjustmentTime: $adjustmentTime, ') + ..write('latitude: $latitude, ') + ..write('longitude: $longitude') + ..write(')')) + .toString(); + } + + @override + int get hashCode => Object.hash( + assetId, + cloudId, + createdAt, + adjustmentTime, + latitude, + longitude, + ); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is RemoteAssetCloudIdEntityData && + other.assetId == this.assetId && + other.cloudId == this.cloudId && + other.createdAt == this.createdAt && + other.adjustmentTime == this.adjustmentTime && + other.latitude == this.latitude && + other.longitude == this.longitude); +} + +class RemoteAssetCloudIdEntityCompanion + extends UpdateCompanion { + final Value assetId; + final Value cloudId; + final Value createdAt; + final Value adjustmentTime; + final Value latitude; + final Value longitude; + const RemoteAssetCloudIdEntityCompanion({ + this.assetId = const Value.absent(), + this.cloudId = const Value.absent(), + this.createdAt = const Value.absent(), + this.adjustmentTime = const Value.absent(), + this.latitude = const Value.absent(), + this.longitude = const Value.absent(), + }); + RemoteAssetCloudIdEntityCompanion.insert({ + required String assetId, + this.cloudId = const Value.absent(), + this.createdAt = const Value.absent(), + this.adjustmentTime = const Value.absent(), + this.latitude = const Value.absent(), + this.longitude = const Value.absent(), + }) : assetId = Value(assetId); + static Insertable custom({ + Expression? assetId, + Expression? cloudId, + Expression? createdAt, + Expression? adjustmentTime, + Expression? latitude, + Expression? longitude, + }) { + return RawValuesInsertable({ + if (assetId != null) 'asset_id': assetId, + if (cloudId != null) 'cloud_id': cloudId, + if (createdAt != null) 'created_at': createdAt, + if (adjustmentTime != null) 'adjustment_time': adjustmentTime, + if (latitude != null) 'latitude': latitude, + if (longitude != null) 'longitude': longitude, + }); + } + + RemoteAssetCloudIdEntityCompanion copyWith({ + Value? assetId, + Value? cloudId, + Value? createdAt, + Value? adjustmentTime, + Value? latitude, + Value? longitude, + }) { + return RemoteAssetCloudIdEntityCompanion( + assetId: assetId ?? this.assetId, + cloudId: cloudId ?? this.cloudId, + createdAt: createdAt ?? this.createdAt, + adjustmentTime: adjustmentTime ?? this.adjustmentTime, + latitude: latitude ?? this.latitude, + longitude: longitude ?? this.longitude, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (assetId.present) { + map['asset_id'] = Variable(assetId.value); + } + if (cloudId.present) { + map['cloud_id'] = Variable(cloudId.value); + } + if (createdAt.present) { + map['created_at'] = Variable(createdAt.value); + } + if (adjustmentTime.present) { + map['adjustment_time'] = Variable(adjustmentTime.value); + } + if (latitude.present) { + map['latitude'] = Variable(latitude.value); + } + if (longitude.present) { + map['longitude'] = Variable(longitude.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('RemoteAssetCloudIdEntityCompanion(') + ..write('assetId: $assetId, ') + ..write('cloudId: $cloudId, ') + ..write('createdAt: $createdAt, ') + ..write('adjustmentTime: $adjustmentTime, ') + ..write('latitude: $latitude, ') + ..write('longitude: $longitude') + ..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, + $customConstraints: 'NOT NULL', + ); + late final GeneratedColumn createdAt = GeneratedColumn( + 'created_at', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: false, + $customConstraints: 'NOT NULL DEFAULT CURRENT_TIMESTAMP', + defaultValue: const CustomExpression('CURRENT_TIMESTAMP'), + ); + late final GeneratedColumn updatedAt = GeneratedColumn( + 'updated_at', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: false, + $customConstraints: 'NOT NULL DEFAULT CURRENT_TIMESTAMP', + defaultValue: const CustomExpression('CURRENT_TIMESTAMP'), + ); + late final GeneratedColumn deletedAt = GeneratedColumn( + 'deleted_at', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn ownerId = GeneratedColumn( + 'owner_id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL REFERENCES user_entity(id)ON DELETE CASCADE', + ); + late final GeneratedColumn type = GeneratedColumn( + 'type', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL', + ); + late final GeneratedColumn data = GeneratedColumn( + 'data', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL', + ); + late final GeneratedColumn isSaved = GeneratedColumn( + 'is_saved', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NOT NULL DEFAULT 0 CHECK (is_saved IN (0, 1))', + defaultValue: const CustomExpression('0'), + ); + late final GeneratedColumn memoryAt = GeneratedColumn( + 'memory_at', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL', + ); + late final GeneratedColumn seenAt = GeneratedColumn( + 'seen_at', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn showAt = GeneratedColumn( + 'show_at', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn hideAt = GeneratedColumn( + 'hide_at', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + @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.string, + data['${effectivePrefix}created_at'], + )!, + updatedAt: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}updated_at'], + )!, + deletedAt: attachedDatabase.typeMapping.read( + DriftSqlType.string, + 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.int, + data['${effectivePrefix}is_saved'], + )!, + memoryAt: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}memory_at'], + )!, + seenAt: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}seen_at'], + ), + showAt: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}show_at'], + ), + hideAt: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}hide_at'], + ), + ); + } + + @override + MemoryEntity createAlias(String alias) { + return MemoryEntity(attachedDatabase, alias); + } + + @override + bool get withoutRowId => true; + @override + bool get isStrict => true; + @override + List get customConstraints => const ['PRIMARY KEY(id)']; + @override + bool get dontWriteConstraints => true; +} + +class MemoryEntityData extends DataClass + implements Insertable { + final String id; + final String createdAt; + final String updatedAt; + final String? deletedAt; + final String ownerId; + final int type; + final String data; + final int isSaved; + final String memoryAt; + final String? seenAt; + final String? showAt; + final String? 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, + String? createdAt, + String? updatedAt, + Value deletedAt = const Value.absent(), + String? ownerId, + int? type, + String? data, + int? isSaved, + String? 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 String 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, + $customConstraints: + 'NOT NULL REFERENCES remote_asset_entity(id)ON DELETE CASCADE', + ); + late final GeneratedColumn memoryId = GeneratedColumn( + 'memory_id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + $customConstraints: + 'NOT NULL 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; + @override + List get customConstraints => const [ + 'PRIMARY KEY(asset_id, memory_id)', + ]; + @override + bool get dontWriteConstraints => 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, + $customConstraints: 'NOT NULL', + ); + late final GeneratedColumn createdAt = GeneratedColumn( + 'created_at', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: false, + $customConstraints: 'NOT NULL DEFAULT CURRENT_TIMESTAMP', + defaultValue: const CustomExpression('CURRENT_TIMESTAMP'), + ); + late final GeneratedColumn updatedAt = GeneratedColumn( + 'updated_at', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: false, + $customConstraints: 'NOT NULL DEFAULT CURRENT_TIMESTAMP', + defaultValue: const CustomExpression('CURRENT_TIMESTAMP'), + ); + late final GeneratedColumn ownerId = GeneratedColumn( + 'owner_id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL REFERENCES user_entity(id)ON DELETE CASCADE', + ); + late final GeneratedColumn name = GeneratedColumn( + 'name', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL', + ); + late final GeneratedColumn faceAssetId = GeneratedColumn( + 'face_asset_id', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn isFavorite = GeneratedColumn( + 'is_favorite', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL CHECK (is_favorite IN (0, 1))', + ); + late final GeneratedColumn isHidden = GeneratedColumn( + 'is_hidden', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL CHECK (is_hidden IN (0, 1))', + ); + late final GeneratedColumn color = GeneratedColumn( + 'color', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn birthDate = GeneratedColumn( + 'birth_date', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + @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.string, + data['${effectivePrefix}created_at'], + )!, + updatedAt: attachedDatabase.typeMapping.read( + DriftSqlType.string, + 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.int, + data['${effectivePrefix}is_favorite'], + )!, + isHidden: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}is_hidden'], + )!, + color: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}color'], + ), + birthDate: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}birth_date'], + ), + ); + } + + @override + PersonEntity createAlias(String alias) { + return PersonEntity(attachedDatabase, alias); + } + + @override + bool get withoutRowId => true; + @override + bool get isStrict => true; + @override + List get customConstraints => const ['PRIMARY KEY(id)']; + @override + bool get dontWriteConstraints => true; +} + +class PersonEntityData extends DataClass + implements Insertable { + final String id; + final String createdAt; + final String updatedAt; + final String ownerId; + final String name; + final String? faceAssetId; + final int isFavorite; + final int isHidden; + final String? color; + final String? 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, + String? createdAt, + String? updatedAt, + String? ownerId, + String? name, + Value faceAssetId = const Value.absent(), + int? isFavorite, + int? 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 int isFavorite, + required int 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, + $customConstraints: 'NOT NULL', + ); + late final GeneratedColumn assetId = GeneratedColumn( + 'asset_id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + $customConstraints: + 'NOT NULL REFERENCES remote_asset_entity(id)ON DELETE CASCADE', + ); + late final GeneratedColumn personId = GeneratedColumn( + 'person_id', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + $customConstraints: 'NULL REFERENCES person_entity(id)ON DELETE SET NULL', + ); + late final GeneratedColumn imageWidth = GeneratedColumn( + 'image_width', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL', + ); + late final GeneratedColumn imageHeight = GeneratedColumn( + 'image_height', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL', + ); + late final GeneratedColumn boundingBoxX1 = GeneratedColumn( + 'bounding_box_x1', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL', + ); + late final GeneratedColumn boundingBoxY1 = GeneratedColumn( + 'bounding_box_y1', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL', + ); + late final GeneratedColumn boundingBoxX2 = GeneratedColumn( + 'bounding_box_x2', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL', + ); + late final GeneratedColumn boundingBoxY2 = GeneratedColumn( + 'bounding_box_y2', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL', + ); + late final GeneratedColumn sourceType = GeneratedColumn( + 'source_type', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL', + ); + late final GeneratedColumn isVisible = GeneratedColumn( + 'is_visible', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NOT NULL DEFAULT 1 CHECK (is_visible IN (0, 1))', + defaultValue: const CustomExpression('1'), + ); + late final GeneratedColumn deletedAt = GeneratedColumn( + 'deleted_at', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + @override + List get $columns => [ + id, + assetId, + personId, + imageWidth, + imageHeight, + boundingBoxX1, + boundingBoxY1, + boundingBoxX2, + boundingBoxY2, + sourceType, + isVisible, + deletedAt, + ]; + @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'], + )!, + isVisible: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}is_visible'], + )!, + deletedAt: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}deleted_at'], + ), + ); + } + + @override + AssetFaceEntity createAlias(String alias) { + return AssetFaceEntity(attachedDatabase, alias); + } + + @override + bool get withoutRowId => true; + @override + bool get isStrict => true; + @override + List get customConstraints => const ['PRIMARY KEY(id)']; + @override + bool get dontWriteConstraints => 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; + final int isVisible; + final String? deletedAt; + 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, + required this.isVisible, + this.deletedAt, + }); + @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); + map['is_visible'] = Variable(isVisible); + if (!nullToAbsent || deletedAt != null) { + map['deleted_at'] = Variable(deletedAt); + } + 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']), + isVisible: serializer.fromJson(json['isVisible']), + deletedAt: serializer.fromJson(json['deletedAt']), + ); + } + @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), + 'isVisible': serializer.toJson(isVisible), + 'deletedAt': serializer.toJson(deletedAt), + }; + } + + 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, + int? isVisible, + Value deletedAt = const Value.absent(), + }) => 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, + isVisible: isVisible ?? this.isVisible, + deletedAt: deletedAt.present ? deletedAt.value : this.deletedAt, + ); + 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, + isVisible: data.isVisible.present ? data.isVisible.value : this.isVisible, + deletedAt: data.deletedAt.present ? data.deletedAt.value : this.deletedAt, + ); + } + + @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('isVisible: $isVisible, ') + ..write('deletedAt: $deletedAt') + ..write(')')) + .toString(); + } + + @override + int get hashCode => Object.hash( + id, + assetId, + personId, + imageWidth, + imageHeight, + boundingBoxX1, + boundingBoxY1, + boundingBoxX2, + boundingBoxY2, + sourceType, + isVisible, + deletedAt, + ); + @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 && + other.isVisible == this.isVisible && + other.deletedAt == this.deletedAt); +} + +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; + final Value isVisible; + final Value deletedAt; + 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(), + this.isVisible = const Value.absent(), + this.deletedAt = 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, + this.isVisible = const Value.absent(), + this.deletedAt = const Value.absent(), + }) : 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, + Expression? isVisible, + Expression? deletedAt, + }) { + 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, + if (isVisible != null) 'is_visible': isVisible, + if (deletedAt != null) 'deleted_at': deletedAt, + }); + } + + AssetFaceEntityCompanion copyWith({ + Value? id, + Value? assetId, + Value? personId, + Value? imageWidth, + Value? imageHeight, + Value? boundingBoxX1, + Value? boundingBoxY1, + Value? boundingBoxX2, + Value? boundingBoxY2, + Value? sourceType, + Value? isVisible, + Value? deletedAt, + }) { + 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, + isVisible: isVisible ?? this.isVisible, + deletedAt: deletedAt ?? this.deletedAt, + ); + } + + @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); + } + if (isVisible.present) { + map['is_visible'] = Variable(isVisible.value); + } + if (deletedAt.present) { + map['deleted_at'] = Variable(deletedAt.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('isVisible: $isVisible, ') + ..write('deletedAt: $deletedAt') + ..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, + $customConstraints: 'NOT NULL', + ); + late final GeneratedColumn stringValue = GeneratedColumn( + 'string_value', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn intValue = GeneratedColumn( + 'int_value', + aliasedName, + true, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + @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; + @override + List get customConstraints => const ['PRIMARY KEY(id)']; + @override + bool get dontWriteConstraints => 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 TrashedLocalAssetEntity extends Table + with TableInfo { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + TrashedLocalAssetEntity(this.attachedDatabase, [this._alias]); + late final GeneratedColumn name = GeneratedColumn( + 'name', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL', + ); + late final GeneratedColumn type = GeneratedColumn( + 'type', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL', + ); + late final GeneratedColumn createdAt = GeneratedColumn( + 'created_at', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: false, + $customConstraints: 'NOT NULL DEFAULT CURRENT_TIMESTAMP', + defaultValue: const CustomExpression('CURRENT_TIMESTAMP'), + ); + late final GeneratedColumn updatedAt = GeneratedColumn( + 'updated_at', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: false, + $customConstraints: 'NOT NULL DEFAULT CURRENT_TIMESTAMP', + defaultValue: const CustomExpression('CURRENT_TIMESTAMP'), + ); + late final GeneratedColumn width = GeneratedColumn( + 'width', + aliasedName, + true, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn height = GeneratedColumn( + 'height', + aliasedName, + true, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn durationMs = GeneratedColumn( + 'duration_ms', + aliasedName, + true, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn id = GeneratedColumn( + 'id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL', + ); + late final GeneratedColumn albumId = GeneratedColumn( + 'album_id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL', + ); + late final GeneratedColumn checksum = GeneratedColumn( + 'checksum', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); + late final GeneratedColumn isFavorite = GeneratedColumn( + 'is_favorite', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NOT NULL DEFAULT 0 CHECK (is_favorite IN (0, 1))', + defaultValue: const CustomExpression('0'), + ); + late final GeneratedColumn orientation = GeneratedColumn( + 'orientation', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NOT NULL DEFAULT 0', + defaultValue: const CustomExpression('0'), + ); + late final GeneratedColumn source = GeneratedColumn( + 'source', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL', + ); + late final GeneratedColumn playbackStyle = GeneratedColumn( + 'playback_style', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NOT NULL DEFAULT 0', + defaultValue: const CustomExpression('0'), + ); + @override + List get $columns => [ + name, + type, + createdAt, + updatedAt, + width, + height, + durationMs, + id, + albumId, + checksum, + isFavorite, + orientation, + source, + playbackStyle, + ]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'trashed_local_asset_entity'; + @override + Set get $primaryKey => {id, albumId}; + @override + TrashedLocalAssetEntityData map( + Map data, { + String? tablePrefix, + }) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return TrashedLocalAssetEntityData( + name: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}name'], + )!, + type: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}type'], + )!, + createdAt: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}created_at'], + )!, + updatedAt: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}updated_at'], + )!, + width: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}width'], + ), + height: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}height'], + ), + durationMs: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}duration_ms'], + ), + id: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}id'], + )!, + albumId: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}album_id'], + )!, + checksum: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}checksum'], + ), + isFavorite: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}is_favorite'], + )!, + orientation: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}orientation'], + )!, + source: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}source'], + )!, + playbackStyle: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}playback_style'], + )!, + ); + } + + @override + TrashedLocalAssetEntity createAlias(String alias) { + return TrashedLocalAssetEntity(attachedDatabase, alias); + } + + @override + bool get withoutRowId => true; + @override + bool get isStrict => true; + @override + List get customConstraints => const ['PRIMARY KEY(id, album_id)']; + @override + bool get dontWriteConstraints => true; +} + +class TrashedLocalAssetEntityData extends DataClass + implements Insertable { + final String name; + final int type; + final String createdAt; + final String updatedAt; + final int? width; + final int? height; + final int? durationMs; + final String id; + final String albumId; + final String? checksum; + final int isFavorite; + final int orientation; + final int source; + final int playbackStyle; + const TrashedLocalAssetEntityData({ + required this.name, + required this.type, + required this.createdAt, + required this.updatedAt, + this.width, + this.height, + this.durationMs, + required this.id, + required this.albumId, + this.checksum, + required this.isFavorite, + required this.orientation, + required this.source, + required this.playbackStyle, + }); + @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 || durationMs != null) { + map['duration_ms'] = Variable(durationMs); + } + map['id'] = Variable(id); + map['album_id'] = Variable(albumId); + if (!nullToAbsent || checksum != null) { + map['checksum'] = Variable(checksum); + } + map['is_favorite'] = Variable(isFavorite); + map['orientation'] = Variable(orientation); + map['source'] = Variable(source); + map['playback_style'] = Variable(playbackStyle); + return map; + } + + factory TrashedLocalAssetEntityData.fromJson( + Map json, { + ValueSerializer? serializer, + }) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return TrashedLocalAssetEntityData( + 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']), + durationMs: serializer.fromJson(json['durationMs']), + id: serializer.fromJson(json['id']), + albumId: serializer.fromJson(json['albumId']), + checksum: serializer.fromJson(json['checksum']), + isFavorite: serializer.fromJson(json['isFavorite']), + orientation: serializer.fromJson(json['orientation']), + source: serializer.fromJson(json['source']), + playbackStyle: serializer.fromJson(json['playbackStyle']), + ); + } + @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), + 'durationMs': serializer.toJson(durationMs), + 'id': serializer.toJson(id), + 'albumId': serializer.toJson(albumId), + 'checksum': serializer.toJson(checksum), + 'isFavorite': serializer.toJson(isFavorite), + 'orientation': serializer.toJson(orientation), + 'source': serializer.toJson(source), + 'playbackStyle': serializer.toJson(playbackStyle), + }; + } + + TrashedLocalAssetEntityData copyWith({ + String? name, + int? type, + String? createdAt, + String? updatedAt, + Value width = const Value.absent(), + Value height = const Value.absent(), + Value durationMs = const Value.absent(), + String? id, + String? albumId, + Value checksum = const Value.absent(), + int? isFavorite, + int? orientation, + int? source, + int? playbackStyle, + }) => TrashedLocalAssetEntityData( + 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, + durationMs: durationMs.present ? durationMs.value : this.durationMs, + id: id ?? this.id, + albumId: albumId ?? this.albumId, + checksum: checksum.present ? checksum.value : this.checksum, + isFavorite: isFavorite ?? this.isFavorite, + orientation: orientation ?? this.orientation, + source: source ?? this.source, + playbackStyle: playbackStyle ?? this.playbackStyle, + ); + TrashedLocalAssetEntityData copyWithCompanion( + TrashedLocalAssetEntityCompanion data, + ) { + return TrashedLocalAssetEntityData( + 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, + durationMs: data.durationMs.present + ? data.durationMs.value + : this.durationMs, + id: data.id.present ? data.id.value : this.id, + albumId: data.albumId.present ? data.albumId.value : this.albumId, + 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, + source: data.source.present ? data.source.value : this.source, + playbackStyle: data.playbackStyle.present + ? data.playbackStyle.value + : this.playbackStyle, + ); + } + + @override + String toString() { + return (StringBuffer('TrashedLocalAssetEntityData(') + ..write('name: $name, ') + ..write('type: $type, ') + ..write('createdAt: $createdAt, ') + ..write('updatedAt: $updatedAt, ') + ..write('width: $width, ') + ..write('height: $height, ') + ..write('durationMs: $durationMs, ') + ..write('id: $id, ') + ..write('albumId: $albumId, ') + ..write('checksum: $checksum, ') + ..write('isFavorite: $isFavorite, ') + ..write('orientation: $orientation, ') + ..write('source: $source, ') + ..write('playbackStyle: $playbackStyle') + ..write(')')) + .toString(); + } + + @override + int get hashCode => Object.hash( + name, + type, + createdAt, + updatedAt, + width, + height, + durationMs, + id, + albumId, + checksum, + isFavorite, + orientation, + source, + playbackStyle, + ); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is TrashedLocalAssetEntityData && + 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.durationMs == this.durationMs && + other.id == this.id && + other.albumId == this.albumId && + other.checksum == this.checksum && + other.isFavorite == this.isFavorite && + other.orientation == this.orientation && + other.source == this.source && + other.playbackStyle == this.playbackStyle); +} + +class TrashedLocalAssetEntityCompanion + extends UpdateCompanion { + final Value name; + final Value type; + final Value createdAt; + final Value updatedAt; + final Value width; + final Value height; + final Value durationMs; + final Value id; + final Value albumId; + final Value checksum; + final Value isFavorite; + final Value orientation; + final Value source; + final Value playbackStyle; + const TrashedLocalAssetEntityCompanion({ + 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.durationMs = const Value.absent(), + this.id = const Value.absent(), + this.albumId = const Value.absent(), + this.checksum = const Value.absent(), + this.isFavorite = const Value.absent(), + this.orientation = const Value.absent(), + this.source = const Value.absent(), + this.playbackStyle = const Value.absent(), + }); + TrashedLocalAssetEntityCompanion.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.durationMs = const Value.absent(), + required String id, + required String albumId, + this.checksum = const Value.absent(), + this.isFavorite = const Value.absent(), + this.orientation = const Value.absent(), + required int source, + this.playbackStyle = const Value.absent(), + }) : name = Value(name), + type = Value(type), + id = Value(id), + albumId = Value(albumId), + source = Value(source); + static Insertable custom({ + Expression? name, + Expression? type, + Expression? createdAt, + Expression? updatedAt, + Expression? width, + Expression? height, + Expression? durationMs, + Expression? id, + Expression? albumId, + Expression? checksum, + Expression? isFavorite, + Expression? orientation, + Expression? source, + Expression? playbackStyle, + }) { + 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 (durationMs != null) 'duration_ms': durationMs, + if (id != null) 'id': id, + if (albumId != null) 'album_id': albumId, + if (checksum != null) 'checksum': checksum, + if (isFavorite != null) 'is_favorite': isFavorite, + if (orientation != null) 'orientation': orientation, + if (source != null) 'source': source, + if (playbackStyle != null) 'playback_style': playbackStyle, + }); + } + + TrashedLocalAssetEntityCompanion copyWith({ + Value? name, + Value? type, + Value? createdAt, + Value? updatedAt, + Value? width, + Value? height, + Value? durationMs, + Value? id, + Value? albumId, + Value? checksum, + Value? isFavorite, + Value? orientation, + Value? source, + Value? playbackStyle, + }) { + return TrashedLocalAssetEntityCompanion( + name: name ?? this.name, + type: type ?? this.type, + createdAt: createdAt ?? this.createdAt, + updatedAt: updatedAt ?? this.updatedAt, + width: width ?? this.width, + height: height ?? this.height, + durationMs: durationMs ?? this.durationMs, + id: id ?? this.id, + albumId: albumId ?? this.albumId, + checksum: checksum ?? this.checksum, + isFavorite: isFavorite ?? this.isFavorite, + orientation: orientation ?? this.orientation, + source: source ?? this.source, + playbackStyle: playbackStyle ?? this.playbackStyle, + ); + } + + @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 (durationMs.present) { + map['duration_ms'] = Variable(durationMs.value); + } + if (id.present) { + map['id'] = Variable(id.value); + } + if (albumId.present) { + map['album_id'] = Variable(albumId.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); + } + if (source.present) { + map['source'] = Variable(source.value); + } + if (playbackStyle.present) { + map['playback_style'] = Variable(playbackStyle.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('TrashedLocalAssetEntityCompanion(') + ..write('name: $name, ') + ..write('type: $type, ') + ..write('createdAt: $createdAt, ') + ..write('updatedAt: $updatedAt, ') + ..write('width: $width, ') + ..write('height: $height, ') + ..write('durationMs: $durationMs, ') + ..write('id: $id, ') + ..write('albumId: $albumId, ') + ..write('checksum: $checksum, ') + ..write('isFavorite: $isFavorite, ') + ..write('orientation: $orientation, ') + ..write('source: $source, ') + ..write('playbackStyle: $playbackStyle') + ..write(')')) + .toString(); + } +} + +class AssetEditEntity extends Table + with TableInfo { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + AssetEditEntity(this.attachedDatabase, [this._alias]); + late final GeneratedColumn id = GeneratedColumn( + 'id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL', + ); + late final GeneratedColumn assetId = GeneratedColumn( + 'asset_id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + $customConstraints: + 'NOT NULL REFERENCES remote_asset_entity(id)ON DELETE CASCADE', + ); + late final GeneratedColumn action = GeneratedColumn( + 'action', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL', + ); + late final GeneratedColumn parameters = + GeneratedColumn( + 'parameters', + aliasedName, + false, + type: DriftSqlType.blob, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL', + ); + late final GeneratedColumn sequence = GeneratedColumn( + 'sequence', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL', + ); + @override + List get $columns => [ + id, + assetId, + action, + parameters, + sequence, + ]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'asset_edit_entity'; + @override + Set get $primaryKey => {id}; + @override + AssetEditEntityData map(Map data, {String? tablePrefix}) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return AssetEditEntityData( + id: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}id'], + )!, + assetId: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}asset_id'], + )!, + action: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}action'], + )!, + parameters: attachedDatabase.typeMapping.read( + DriftSqlType.blob, + data['${effectivePrefix}parameters'], + )!, + sequence: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}sequence'], + )!, + ); + } + + @override + AssetEditEntity createAlias(String alias) { + return AssetEditEntity(attachedDatabase, alias); + } + + @override + bool get withoutRowId => true; + @override + bool get isStrict => true; + @override + List get customConstraints => const ['PRIMARY KEY(id)']; + @override + bool get dontWriteConstraints => true; +} + +class AssetEditEntityData extends DataClass + implements Insertable { + final String id; + final String assetId; + final int action; + final i2.Uint8List parameters; + final int sequence; + const AssetEditEntityData({ + required this.id, + required this.assetId, + required this.action, + required this.parameters, + required this.sequence, + }); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['id'] = Variable(id); + map['asset_id'] = Variable(assetId); + map['action'] = Variable(action); + map['parameters'] = Variable(parameters); + map['sequence'] = Variable(sequence); + return map; + } + + factory AssetEditEntityData.fromJson( + Map json, { + ValueSerializer? serializer, + }) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return AssetEditEntityData( + id: serializer.fromJson(json['id']), + assetId: serializer.fromJson(json['assetId']), + action: serializer.fromJson(json['action']), + parameters: serializer.fromJson(json['parameters']), + sequence: serializer.fromJson(json['sequence']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'id': serializer.toJson(id), + 'assetId': serializer.toJson(assetId), + 'action': serializer.toJson(action), + 'parameters': serializer.toJson(parameters), + 'sequence': serializer.toJson(sequence), + }; + } + + AssetEditEntityData copyWith({ + String? id, + String? assetId, + int? action, + i2.Uint8List? parameters, + int? sequence, + }) => AssetEditEntityData( + id: id ?? this.id, + assetId: assetId ?? this.assetId, + action: action ?? this.action, + parameters: parameters ?? this.parameters, + sequence: sequence ?? this.sequence, + ); + AssetEditEntityData copyWithCompanion(AssetEditEntityCompanion data) { + return AssetEditEntityData( + id: data.id.present ? data.id.value : this.id, + assetId: data.assetId.present ? data.assetId.value : this.assetId, + action: data.action.present ? data.action.value : this.action, + parameters: data.parameters.present + ? data.parameters.value + : this.parameters, + sequence: data.sequence.present ? data.sequence.value : this.sequence, + ); + } + + @override + String toString() { + return (StringBuffer('AssetEditEntityData(') + ..write('id: $id, ') + ..write('assetId: $assetId, ') + ..write('action: $action, ') + ..write('parameters: $parameters, ') + ..write('sequence: $sequence') + ..write(')')) + .toString(); + } + + @override + int get hashCode => Object.hash( + id, + assetId, + action, + $driftBlobEquality.hash(parameters), + sequence, + ); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is AssetEditEntityData && + other.id == this.id && + other.assetId == this.assetId && + other.action == this.action && + $driftBlobEquality.equals(other.parameters, this.parameters) && + other.sequence == this.sequence); +} + +class AssetEditEntityCompanion extends UpdateCompanion { + final Value id; + final Value assetId; + final Value action; + final Value parameters; + final Value sequence; + const AssetEditEntityCompanion({ + this.id = const Value.absent(), + this.assetId = const Value.absent(), + this.action = const Value.absent(), + this.parameters = const Value.absent(), + this.sequence = const Value.absent(), + }); + AssetEditEntityCompanion.insert({ + required String id, + required String assetId, + required int action, + required i2.Uint8List parameters, + required int sequence, + }) : id = Value(id), + assetId = Value(assetId), + action = Value(action), + parameters = Value(parameters), + sequence = Value(sequence); + static Insertable custom({ + Expression? id, + Expression? assetId, + Expression? action, + Expression? parameters, + Expression? sequence, + }) { + return RawValuesInsertable({ + if (id != null) 'id': id, + if (assetId != null) 'asset_id': assetId, + if (action != null) 'action': action, + if (parameters != null) 'parameters': parameters, + if (sequence != null) 'sequence': sequence, + }); + } + + AssetEditEntityCompanion copyWith({ + Value? id, + Value? assetId, + Value? action, + Value? parameters, + Value? sequence, + }) { + return AssetEditEntityCompanion( + id: id ?? this.id, + assetId: assetId ?? this.assetId, + action: action ?? this.action, + parameters: parameters ?? this.parameters, + sequence: sequence ?? this.sequence, + ); + } + + @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 (action.present) { + map['action'] = Variable(action.value); + } + if (parameters.present) { + map['parameters'] = Variable(parameters.value); + } + if (sequence.present) { + map['sequence'] = Variable(sequence.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('AssetEditEntityCompanion(') + ..write('id: $id, ') + ..write('assetId: $assetId, ') + ..write('action: $action, ') + ..write('parameters: $parameters, ') + ..write('sequence: $sequence') + ..write(')')) + .toString(); + } +} + +class Settings extends Table with TableInfo { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + Settings(this.attachedDatabase, [this._alias]); + late final GeneratedColumn key = GeneratedColumn( + 'key', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL', + ); + late final GeneratedColumn value = GeneratedColumn( + 'value', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL', + ); + late final GeneratedColumn updatedAt = GeneratedColumn( + 'updated_at', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: false, + $customConstraints: 'NOT NULL DEFAULT CURRENT_TIMESTAMP', + defaultValue: const CustomExpression('CURRENT_TIMESTAMP'), + ); + @override + List get $columns => [key, value, updatedAt]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'settings'; + @override + Set get $primaryKey => {key}; + @override + SettingsData map(Map data, {String? tablePrefix}) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return SettingsData( + key: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}key'], + )!, + value: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}value'], + )!, + updatedAt: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}updated_at'], + )!, + ); + } + + @override + Settings createAlias(String alias) { + return Settings(attachedDatabase, alias); + } + + @override + bool get withoutRowId => true; + @override + bool get isStrict => true; + @override + List get customConstraints => const ['PRIMARY KEY("key")']; + @override + bool get dontWriteConstraints => true; +} + +class SettingsData extends DataClass implements Insertable { + final String key; + final String value; + final String updatedAt; + const SettingsData({ + required this.key, + required this.value, + required this.updatedAt, + }); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['key'] = Variable(key); + map['value'] = Variable(value); + map['updated_at'] = Variable(updatedAt); + return map; + } + + factory SettingsData.fromJson( + Map json, { + ValueSerializer? serializer, + }) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return SettingsData( + key: serializer.fromJson(json['key']), + value: serializer.fromJson(json['value']), + updatedAt: serializer.fromJson(json['updatedAt']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'key': serializer.toJson(key), + 'value': serializer.toJson(value), + 'updatedAt': serializer.toJson(updatedAt), + }; + } + + SettingsData copyWith({String? key, String? value, String? updatedAt}) => + SettingsData( + key: key ?? this.key, + value: value ?? this.value, + updatedAt: updatedAt ?? this.updatedAt, + ); + SettingsData copyWithCompanion(SettingsCompanion data) { + return SettingsData( + key: data.key.present ? data.key.value : this.key, + value: data.value.present ? data.value.value : this.value, + updatedAt: data.updatedAt.present ? data.updatedAt.value : this.updatedAt, + ); + } + + @override + String toString() { + return (StringBuffer('SettingsData(') + ..write('key: $key, ') + ..write('value: $value, ') + ..write('updatedAt: $updatedAt') + ..write(')')) + .toString(); + } + + @override + int get hashCode => Object.hash(key, value, updatedAt); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is SettingsData && + other.key == this.key && + other.value == this.value && + other.updatedAt == this.updatedAt); +} + +class SettingsCompanion extends UpdateCompanion { + final Value key; + final Value value; + final Value updatedAt; + const SettingsCompanion({ + this.key = const Value.absent(), + this.value = const Value.absent(), + this.updatedAt = const Value.absent(), + }); + SettingsCompanion.insert({ + required String key, + required String value, + this.updatedAt = const Value.absent(), + }) : key = Value(key), + value = Value(value); + static Insertable custom({ + Expression? key, + Expression? value, + Expression? updatedAt, + }) { + return RawValuesInsertable({ + if (key != null) 'key': key, + if (value != null) 'value': value, + if (updatedAt != null) 'updated_at': updatedAt, + }); + } + + SettingsCompanion copyWith({ + Value? key, + Value? value, + Value? updatedAt, + }) { + return SettingsCompanion( + key: key ?? this.key, + value: value ?? this.value, + updatedAt: updatedAt ?? this.updatedAt, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (key.present) { + map['key'] = Variable(key.value); + } + if (value.present) { + map['value'] = Variable(value.value); + } + if (updatedAt.present) { + map['updated_at'] = Variable(updatedAt.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('SettingsCompanion(') + ..write('key: $key, ') + ..write('value: $value, ') + ..write('updatedAt: $updatedAt') + ..write(')')) + .toString(); + } +} + +class DatabaseAtV27 extends GeneratedDatabase { + DatabaseAtV27(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 idxLocalAlbumAssetAlbumAsset = Index( + 'idx_local_album_asset_album_asset', + 'CREATE INDEX IF NOT EXISTS idx_local_album_asset_album_asset ON local_album_asset_entity (album_id, asset_id)', + ); + 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 idxLocalAssetCloudId = Index( + 'idx_local_asset_cloud_id', + 'CREATE INDEX IF NOT EXISTS idx_local_asset_cloud_id ON local_asset_entity (i_cloud_id)', + ); + late final Index idxStackPrimaryAssetId = Index( + 'idx_stack_primary_asset_id', + 'CREATE INDEX IF NOT EXISTS idx_stack_primary_asset_id ON stack_entity (primary_asset_id)', + ); + 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 Index idxRemoteAssetStackId = Index( + 'idx_remote_asset_stack_id', + 'CREATE INDEX IF NOT EXISTS idx_remote_asset_stack_id ON remote_asset_entity (stack_id)', + ); + late final Index idxRemoteAssetOwnerVisibilityDeletedCreated = Index( + 'idx_remote_asset_owner_visibility_deleted_created', + 'CREATE INDEX IF NOT EXISTS idx_remote_asset_owner_visibility_deleted_created ON remote_asset_entity (owner_id, visibility, deleted_at, created_at DESC)', + ); + 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 RemoteAssetCloudIdEntity remoteAssetCloudIdEntity = + RemoteAssetCloudIdEntity(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 TrashedLocalAssetEntity trashedLocalAssetEntity = + TrashedLocalAssetEntity(this); + late final AssetEditEntity assetEditEntity = AssetEditEntity(this); + late final Settings settings = Settings(this); + late final Index idxPartnerSharedWithId = Index( + 'idx_partner_shared_with_id', + 'CREATE INDEX IF NOT EXISTS idx_partner_shared_with_id ON partner_entity (shared_with_id)', + ); + late final Index idxLatLng = Index( + 'idx_lat_lng', + 'CREATE INDEX IF NOT EXISTS idx_lat_lng ON remote_exif_entity (latitude, longitude)', + ); + late final Index idxRemoteExifCity = Index( + 'idx_remote_exif_city', + 'CREATE INDEX IF NOT EXISTS idx_remote_exif_city ON remote_exif_entity (city) WHERE city IS NOT NULL', + ); + late final Index idxRemoteAlbumAssetAlbumAsset = Index( + 'idx_remote_album_asset_album_asset', + 'CREATE INDEX IF NOT EXISTS idx_remote_album_asset_album_asset ON remote_album_asset_entity (album_id, asset_id)', + ); + late final Index idxRemoteAssetCloudId = Index( + 'idx_remote_asset_cloud_id', + 'CREATE INDEX IF NOT EXISTS idx_remote_asset_cloud_id ON remote_asset_cloud_id_entity (cloud_id)', + ); + late final Index idxPersonOwnerId = Index( + 'idx_person_owner_id', + 'CREATE INDEX IF NOT EXISTS idx_person_owner_id ON person_entity (owner_id)', + ); + late final Index idxAssetFacePersonId = Index( + 'idx_asset_face_person_id', + 'CREATE INDEX IF NOT EXISTS idx_asset_face_person_id ON asset_face_entity (person_id)', + ); + late final Index idxAssetFaceAssetId = Index( + 'idx_asset_face_asset_id', + 'CREATE INDEX IF NOT EXISTS idx_asset_face_asset_id ON asset_face_entity (asset_id)', + ); + late final Index idxAssetFaceVisiblePerson = Index( + 'idx_asset_face_visible_person', + 'CREATE INDEX IF NOT EXISTS idx_asset_face_visible_person ON asset_face_entity (person_id, asset_id) WHERE is_visible = 1 AND deleted_at IS NULL', + ); + late final Index idxTrashedLocalAssetChecksum = Index( + 'idx_trashed_local_asset_checksum', + 'CREATE INDEX IF NOT EXISTS idx_trashed_local_asset_checksum ON trashed_local_asset_entity (checksum)', + ); + late final Index idxTrashedLocalAssetAlbum = Index( + 'idx_trashed_local_asset_album', + 'CREATE INDEX IF NOT EXISTS idx_trashed_local_asset_album ON trashed_local_asset_entity (album_id)', + ); + late final Index idxAssetEditAssetId = Index( + 'idx_asset_edit_asset_id', + 'CREATE INDEX IF NOT EXISTS idx_asset_edit_asset_id ON asset_edit_entity (asset_id)', + ); + @override + Iterable> get allTables => + allSchemaEntities.whereType>(); + @override + List get allSchemaEntities => [ + userEntity, + remoteAssetEntity, + stackEntity, + localAssetEntity, + remoteAlbumEntity, + localAlbumEntity, + localAlbumAssetEntity, + idxLocalAlbumAssetAlbumAsset, + idxLocalAssetChecksum, + idxLocalAssetCloudId, + idxStackPrimaryAssetId, + uQRemoteAssetsOwnerChecksum, + uQRemoteAssetsOwnerLibraryChecksum, + idxRemoteAssetChecksum, + idxRemoteAssetStackId, + idxRemoteAssetOwnerVisibilityDeletedCreated, + authUserEntity, + userMetadataEntity, + partnerEntity, + remoteExifEntity, + remoteAlbumAssetEntity, + remoteAlbumUserEntity, + remoteAssetCloudIdEntity, + memoryEntity, + memoryAssetEntity, + personEntity, + assetFaceEntity, + storeEntity, + trashedLocalAssetEntity, + assetEditEntity, + settings, + idxPartnerSharedWithId, + idxLatLng, + idxRemoteExifCity, + idxRemoteAlbumAssetAlbumAsset, + idxRemoteAssetCloudId, + idxPersonOwnerId, + idxAssetFacePersonId, + idxAssetFaceAssetId, + idxAssetFaceVisiblePerson, + idxTrashedLocalAssetChecksum, + idxTrashedLocalAssetAlbum, + idxAssetEditAssetId, + ]; + @override + StreamQueryUpdateRules get streamUpdateRules => const StreamQueryUpdateRules([ + WritePropagation( + on: TableUpdateQuery.onTableName( + 'user_entity', + limitUpdateKind: UpdateKind.delete, + ), + result: [TableUpdate('remote_asset_entity', kind: UpdateKind.delete)], + ), + WritePropagation( + on: TableUpdateQuery.onTableName( + 'user_entity', + limitUpdateKind: UpdateKind.delete, + ), + result: [TableUpdate('stack_entity', kind: UpdateKind.delete)], + ), + WritePropagation( + on: TableUpdateQuery.onTableName( + 'remote_asset_entity', + limitUpdateKind: UpdateKind.delete, + ), + result: [TableUpdate('remote_album_entity', kind: UpdateKind.update)], + ), + WritePropagation( + on: TableUpdateQuery.onTableName( + 'remote_album_entity', + limitUpdateKind: UpdateKind.delete, + ), + result: [TableUpdate('local_album_entity', kind: UpdateKind.update)], + ), + WritePropagation( + on: TableUpdateQuery.onTableName( + 'local_asset_entity', + limitUpdateKind: UpdateKind.delete, + ), + result: [ + TableUpdate('local_album_asset_entity', kind: UpdateKind.delete), + ], + ), + WritePropagation( + on: TableUpdateQuery.onTableName( + 'local_album_entity', + limitUpdateKind: UpdateKind.delete, + ), + result: [ + TableUpdate('local_album_asset_entity', kind: UpdateKind.delete), + ], + ), + WritePropagation( + on: TableUpdateQuery.onTableName( + 'user_entity', + limitUpdateKind: UpdateKind.delete, + ), + result: [TableUpdate('user_metadata_entity', kind: UpdateKind.delete)], + ), + WritePropagation( + on: TableUpdateQuery.onTableName( + 'user_entity', + limitUpdateKind: UpdateKind.delete, + ), + result: [TableUpdate('partner_entity', kind: UpdateKind.delete)], + ), + WritePropagation( + on: TableUpdateQuery.onTableName( + 'user_entity', + limitUpdateKind: UpdateKind.delete, + ), + result: [TableUpdate('partner_entity', kind: UpdateKind.delete)], + ), + WritePropagation( + on: TableUpdateQuery.onTableName( + 'remote_asset_entity', + limitUpdateKind: UpdateKind.delete, + ), + result: [TableUpdate('remote_exif_entity', kind: UpdateKind.delete)], + ), + WritePropagation( + on: TableUpdateQuery.onTableName( + 'remote_asset_entity', + limitUpdateKind: UpdateKind.delete, + ), + result: [ + TableUpdate('remote_album_asset_entity', kind: UpdateKind.delete), + ], + ), + WritePropagation( + on: TableUpdateQuery.onTableName( + 'remote_album_entity', + limitUpdateKind: UpdateKind.delete, + ), + result: [ + TableUpdate('remote_album_asset_entity', kind: UpdateKind.delete), + ], + ), + WritePropagation( + on: TableUpdateQuery.onTableName( + 'remote_album_entity', + limitUpdateKind: UpdateKind.delete, + ), + result: [ + TableUpdate('remote_album_user_entity', kind: UpdateKind.delete), + ], + ), + WritePropagation( + on: TableUpdateQuery.onTableName( + 'user_entity', + limitUpdateKind: UpdateKind.delete, + ), + result: [ + TableUpdate('remote_album_user_entity', kind: UpdateKind.delete), + ], + ), + WritePropagation( + on: TableUpdateQuery.onTableName( + 'remote_asset_entity', + limitUpdateKind: UpdateKind.delete, + ), + result: [ + TableUpdate('remote_asset_cloud_id_entity', kind: UpdateKind.delete), + ], + ), + WritePropagation( + on: TableUpdateQuery.onTableName( + 'user_entity', + limitUpdateKind: UpdateKind.delete, + ), + result: [TableUpdate('memory_entity', kind: UpdateKind.delete)], + ), + WritePropagation( + on: TableUpdateQuery.onTableName( + 'remote_asset_entity', + limitUpdateKind: UpdateKind.delete, + ), + result: [TableUpdate('memory_asset_entity', kind: UpdateKind.delete)], + ), + WritePropagation( + on: TableUpdateQuery.onTableName( + 'memory_entity', + limitUpdateKind: UpdateKind.delete, + ), + result: [TableUpdate('memory_asset_entity', kind: UpdateKind.delete)], + ), + WritePropagation( + on: TableUpdateQuery.onTableName( + 'user_entity', + limitUpdateKind: UpdateKind.delete, + ), + result: [TableUpdate('person_entity', kind: UpdateKind.delete)], + ), + WritePropagation( + on: TableUpdateQuery.onTableName( + 'remote_asset_entity', + limitUpdateKind: UpdateKind.delete, + ), + result: [TableUpdate('asset_face_entity', kind: UpdateKind.delete)], + ), + WritePropagation( + on: TableUpdateQuery.onTableName( + 'person_entity', + limitUpdateKind: UpdateKind.delete, + ), + result: [TableUpdate('asset_face_entity', kind: UpdateKind.update)], + ), + WritePropagation( + on: TableUpdateQuery.onTableName( + 'remote_asset_entity', + limitUpdateKind: UpdateKind.delete, + ), + result: [TableUpdate('asset_edit_entity', kind: UpdateKind.delete)], + ), + ]); + @override + int get schemaVersion => 27; + @override + DriftDatabaseOptions get options => + const DriftDatabaseOptions(storeDateTimeAsText: true); +} diff --git a/mobile/test/infrastructure/repository.mock.dart b/mobile/test/infrastructure/repository.mock.dart index 74ecf39038..9c1cdae416 100644 --- a/mobile/test/infrastructure/repository.mock.dart +++ b/mobile/test/infrastructure/repository.mock.dart @@ -2,7 +2,7 @@ import 'package:immich_mobile/infrastructure/repositories/backup.repository.dart import 'package:immich_mobile/infrastructure/repositories/local_album.repository.dart'; import 'package:immich_mobile/infrastructure/repositories/local_asset.repository.dart'; import 'package:immich_mobile/infrastructure/repositories/log.repository.dart'; -import 'package:immich_mobile/infrastructure/repositories/metadata.repository.dart'; +import 'package:immich_mobile/infrastructure/repositories/settings.repository.dart'; import 'package:immich_mobile/infrastructure/repositories/remote_album.repository.dart'; import 'package:immich_mobile/infrastructure/repositories/remote_asset.repository.dart'; import 'package:immich_mobile/infrastructure/repositories/storage.repository.dart'; @@ -18,7 +18,7 @@ import 'package:mocktail/mocktail.dart'; class MockDriftStoreRepository extends Mock implements DriftStoreRepository {} -class MockMetadataRepository extends Mock implements MetadataRepository {} +class MockSettingsRepository extends Mock implements SettingsRepository {} class MockLogRepository extends Mock implements LogRepository {} diff --git a/mobile/test/medium/repositories/metadata_repository_test.dart b/mobile/test/medium/repositories/settings_repository_test.dart similarity index 54% rename from mobile/test/medium/repositories/metadata_repository_test.dart rename to mobile/test/medium/repositories/settings_repository_test.dart index 7b185f3bec..6a3f79badb 100644 --- a/mobile/test/medium/repositories/metadata_repository_test.dart +++ b/mobile/test/medium/repositories/settings_repository_test.dart @@ -2,19 +2,19 @@ import 'package:drift/drift.dart'; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:immich_mobile/domain/models/log.model.dart'; -import 'package:immich_mobile/domain/models/metadata_key.dart'; -import 'package:immich_mobile/infrastructure/entities/metadata.entity.drift.dart'; -import 'package:immich_mobile/infrastructure/repositories/metadata.repository.dart'; +import 'package:immich_mobile/domain/models/settings_key.dart'; +import 'package:immich_mobile/infrastructure/entities/settings.entity.drift.dart'; +import 'package:immich_mobile/infrastructure/repositories/settings.repository.dart'; import '../repository_context.dart'; void main() { late MediumRepositoryContext ctx; - late MetadataRepository sut; + late SettingsRepository sut; setUpAll(() async { ctx = MediumRepositoryContext(); - sut = await MetadataRepository.ensureInitialized(ctx.db); + sut = await SettingsRepository.ensureInitialized(ctx.db); }); tearDownAll(() async { @@ -22,8 +22,8 @@ void main() { }); setUp(() async { - await ctx.db.delete(ctx.db.metadataEntity).go(); - await MetadataRepository.refresh(); + await ctx.db.delete(ctx.db.settingsEntity).go(); + await SettingsRepository.instance.refresh(); }); group('defaults', () { @@ -31,8 +31,8 @@ void main() { expect(sut.appConfig.theme.mode, ThemeMode.system); }); - test('systemConfig returns key defaults when DB is empty', () { - expect(sut.systemConfig.logLevel, LogLevel.info); + test('appConfig returns key defaults when DB is empty', () { + expect(sut.appConfig.logLevel, LogLevel.info); }); }); @@ -46,30 +46,30 @@ void main() { await sut.write(.themeMode, ThemeMode.light); await sut.write(.logLevel, LogLevel.severe); expect(sut.appConfig.theme.mode, ThemeMode.light); - expect(sut.systemConfig.logLevel, LogLevel.severe); + expect(sut.appConfig.logLevel, LogLevel.severe); }); - }); - group('delete', () { test('removes the row and reverts to default', () async { await sut.write(.themeMode, ThemeMode.dark); expect(sut.appConfig.theme.mode, ThemeMode.dark); - await sut.delete(.themeMode); + await sut.write(.themeMode, ThemeMode.system); expect(sut.appConfig.theme.mode, ThemeMode.system); - final rows = await ctx.db.select(ctx.db.metadataEntity).get(); + final rows = await ctx.db.select(ctx.db.settingsEntity).get(); expect(rows, isEmpty); }); }); - group('refresh', () { + group('delete', () {}); + + group('sync', () { test('picks up rows that were inserted directly into the DB', () async { await ctx.db - .into(ctx.db.metadataEntity) + .into(ctx.db.settingsEntity) .insert( - MetadataEntityCompanion.insert( - key: MetadataKey.themeMode.key, + SettingsEntityCompanion.insert( + key: SettingsKey.themeMode.name, value: ThemeMode.dark.name, updatedAt: Value(DateTime.now()), ), @@ -78,58 +78,46 @@ void main() { // Cache hasn't seen this row yet — view still returns the default. expect(sut.appConfig.theme.mode, ThemeMode.system); - await MetadataRepository.refresh(); + await SettingsRepository.instance.refresh(); expect(sut.appConfig.theme.mode, ThemeMode.dark); }); test('drops cached values for rows that were deleted out from under the repo', () async { await sut.write(.themeMode, ThemeMode.dark); // Wipe the row directly. Cache still holds the old value. - await ctx.db.delete(ctx.db.metadataEntity).go(); + await ctx.db.delete(ctx.db.settingsEntity).go(); expect(sut.appConfig.theme.mode, ThemeMode.dark); - await MetadataRepository.refresh(); + await SettingsRepository.instance.refresh(); expect(sut.appConfig.theme.mode, ThemeMode.system); }); - test('skips rows whose key is unknown to MetadataKey', () async { + test('skips rows whose key is unknown to SettingsKey', () async { await ctx.db - .into(ctx.db.metadataEntity) + .into(ctx.db.settingsEntity) .insert( - MetadataEntityCompanion.insert( + SettingsEntityCompanion.insert( key: 'app-config.unknown.future-key', value: 'whatever', updatedAt: Value(DateTime.now()), ), ); - await MetadataRepository.refresh(); + await SettingsRepository.instance.refresh(); expect(sut.appConfig.theme.mode, ThemeMode.system); }); }); group('watch', () { test('watchAppConfig emits the new value after a write', () async { - final expectation = expectLater(sut.watchAppConfig().map((c) => c.theme.mode), emitsThrough(ThemeMode.dark)); - await sut.write(MetadataKey.themeMode, ThemeMode.dark); + final expectation = expectLater(sut.watchConfig().map((c) => c.theme.mode), emitsThrough(ThemeMode.dark)); + await sut.write(SettingsKey.themeMode, ThemeMode.dark); await expectation; }); - test('watchAppConfig does not emit when only system-config rows change', () async { - final emissions = []; - // skip(1) drops the on-subscribe replay so we only capture emissions caused by the write below. - final sub = sut.watchAppConfig().skip(1).listen((c) => emissions.add(c.theme.mode)); - - await sut.write(MetadataKey.logLevel, LogLevel.severe); - await pumpEventQueue(); - await sub.cancel(); - - expect(emissions, isEmpty); - }); - - test('watchSystemConfig emits the new value after a write', () async { - final expectation = expectLater(sut.watchSystemConfig().map((c) => c.logLevel), emitsThrough(LogLevel.warning)); - await sut.write(MetadataKey.logLevel, LogLevel.warning); + test('watchConfig emits the new value after a write', () async { + final expectation = expectLater(sut.watchConfig().map((c) => c.logLevel), emitsThrough(LogLevel.warning)); + await sut.write(SettingsKey.logLevel, LogLevel.warning); await expectation; }); }); diff --git a/mobile/test/repository.mocks.dart b/mobile/test/repository.mocks.dart index 4b27541246..80786420fd 100644 --- a/mobile/test/repository.mocks.dart +++ b/mobile/test/repository.mocks.dart @@ -3,17 +3,17 @@ import 'package:immich_mobile/repositories/asset_media.repository.dart'; import 'package:immich_mobile/repositories/auth.repository.dart'; import 'package:immich_mobile/repositories/auth_api.repository.dart'; import 'package:immich_mobile/domain/services/tag.service.dart'; -import 'package:immich_mobile/repositories/local_files_manager.repository.dart'; +import 'package:immich_mobile/repositories/permission.repository.dart'; import 'package:mocktail/mocktail.dart'; class MockAssetApiRepository extends Mock implements AssetApiRepository {} class MockAssetMediaRepository extends Mock implements AssetMediaRepository {} +class MockPermissionRepository extends Mock implements IPermissionRepository {} + class MockAuthApiRepository extends Mock implements AuthApiRepository {} class MockAuthRepository extends Mock implements AuthRepository {} -class MockLocalFilesManagerRepository extends Mock implements LocalFilesManagerRepository {} - class MockTagService extends Mock implements TagService {} diff --git a/mobile/test/services/background_upload.service_test.dart b/mobile/test/services/background_upload.service_test.dart index dd19f2b1cc..310f2f4d49 100644 --- a/mobile/test/services/background_upload.service_test.dart +++ b/mobile/test/services/background_upload.service_test.dart @@ -11,7 +11,7 @@ import 'package:immich_mobile/domain/models/store.model.dart'; import 'package:immich_mobile/domain/services/store.service.dart'; import 'package:immich_mobile/entities/store.entity.dart'; import 'package:immich_mobile/infrastructure/repositories/db.repository.dart'; -import 'package:immich_mobile/infrastructure/repositories/metadata.repository.dart'; +import 'package:immich_mobile/infrastructure/repositories/settings.repository.dart'; import 'package:immich_mobile/infrastructure/repositories/store.repository.dart'; import 'package:immich_mobile/services/background_upload.service.dart'; import 'package:mocktail/mocktail.dart'; @@ -38,7 +38,7 @@ void main() { ); db = Drift(DatabaseConnection(NativeDatabase.memory(), closeStreamsSynchronously: true)); await StoreService.init(storeRepository: DriftStoreRepository(db)); - await MetadataRepository.ensureInitialized(db); + await SettingsRepository.ensureInitialized(db); await Store.put(StoreKey.serverEndpoint, 'http://test-server.com'); await Store.put(StoreKey.deviceId, 'test-device-id'); diff --git a/mobile/test/unit/repositories/metadata_repository_test.dart b/mobile/test/unit/repositories/metadata_repository_test.dart deleted file mode 100644 index 75b34da7cb..0000000000 --- a/mobile/test/unit/repositories/metadata_repository_test.dart +++ /dev/null @@ -1,28 +0,0 @@ -import 'package:flutter_test/flutter_test.dart'; -import 'package:immich_mobile/domain/models/metadata_key.dart'; - -void main() { - group('MetadataKey', () { - test('every key round-trips its default value losslessly', () { - for (final key in MetadataKey.values) { - final encoded = key.encode(key.defaultValue); - final decoded = key.decode(encoded); - expect(decoded, key.defaultValue, reason: 'round-trip failed for ${key.name}'); - } - }); - - test('decode falls back to the default value when the raw input is unparseable', () { - for (final key in MetadataKey.values) { - // String keys can decode any string. So skip them - if (key.defaultValue is String) { - continue; - } - expect( - key.decode('not a valid encoding for any key'), - key.defaultValue, - reason: 'fallback failed for ${key.name}', - ); - } - }); - }); -} diff --git a/mobile/test/unit/repositories/settings_repository_test.dart b/mobile/test/unit/repositories/settings_repository_test.dart new file mode 100644 index 0000000000..80214dd298 --- /dev/null +++ b/mobile/test/unit/repositories/settings_repository_test.dart @@ -0,0 +1,16 @@ +import 'package:flutter_test/flutter_test.dart'; +import 'package:immich_mobile/domain/models/config/app_config.dart'; +import 'package:immich_mobile/domain/models/settings_key.dart'; + +void main() { + group('SettingsKey', () { + for (final key in SettingsKey.values) { + test('verify codec for $key', () { + final defaultValue = defaultConfig.read(key); + final encoded = key.encode(defaultValue); + final decoded = key.decode(encoded); + expect(decoded, defaultValue, reason: 'round-trip failed for ${key.name}'); + }); + } + }); +} diff --git a/open-api/immich-openapi-specs.json b/open-api/immich-openapi-specs.json index 94ea9435c1..94dfec933b 100644 --- a/open-api/immich-openapi-specs.json +++ b/open-api/immich-openapi-specs.json @@ -1627,6 +1627,17 @@ "type": "string" } }, + { + "name": "id", + "required": false, + "in": "query", + "description": "Album ID", + "schema": { + "format": "uuid", + "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$", + "type": "string" + } + }, { "name": "isOwned", "required": false, @@ -1644,6 +1655,15 @@ "schema": { "type": "boolean" } + }, + { + "name": "name", + "required": false, + "in": "query", + "description": "Album name (exact match)", + "schema": { + "type": "string" + } } ], "responses": { @@ -8818,6 +8838,50 @@ "x-immich-permission": "plugin.read" } }, + "/plugins/templates": { + "get": { + "description": "Retrieve workflow templates provided by installed plugins", + "operationId": "searchPluginTemplates", + "parameters": [], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/PluginTemplateResponseDto" + }, + "type": "array" + } + } + }, + "description": "" + } + }, + "security": [ + { + "bearer": [] + }, + { + "cookie": [] + }, + { + "api_key": [] + } + ], + "summary": "Retrieve workflow templates", + "tags": [ + "Plugins" + ], + "x-immich-history": [ + { + "version": "v3.0.0", + "state": "Added" + } + ], + "x-immich-permission": "plugin.read" + } + }, "/plugins/{id}": { "get": { "description": "Retrieve information about a specific plugin by its ID.", @@ -19468,7 +19532,7 @@ "VersionCheck", "OcrQueueAll", "Ocr", - "WorkflowAssetCreate" + "WorkflowAssetTrigger" ], "type": "string" }, @@ -21573,6 +21637,72 @@ ], "type": "object" }, + "PluginTemplateResponseDto": { + "properties": { + "description": { + "description": "Template description", + "type": "string" + }, + "key": { + "description": "Template key (unique across all templates)", + "type": "string" + }, + "steps": { + "description": "Workflow steps", + "items": { + "$ref": "#/components/schemas/PluginTemplateStepResponseDto" + }, + "type": "array" + }, + "title": { + "description": "Template title", + "type": "string" + }, + "trigger": { + "$ref": "#/components/schemas/WorkflowTrigger", + "description": "Workflow trigger" + }, + "uiHints": { + "description": "Ui hints, for example \"smart-album\"", + "items": { + "type": "string" + }, + "type": "array" + } + }, + "required": [ + "description", + "key", + "steps", + "title", + "trigger", + "uiHints" + ], + "type": "object" + }, + "PluginTemplateStepResponseDto": { + "properties": { + "config": { + "additionalProperties": {}, + "description": "Step configuration", + "nullable": true, + "type": "object" + }, + "enabled": { + "description": "Whether the step is enabled", + "type": "boolean" + }, + "method": { + "description": "Step plugin method", + "type": "string" + } + }, + "required": [ + "config", + "method" + ], + "type": "object" + }, "PurchaseResponse": { "properties": { "hideBuyButtonUntil": { @@ -22719,7 +22849,14 @@ "description": "Total number of matching assets", "maximum": 9007199254740991, "minimum": 0, - "type": "integer" + "type": "integer", + "x-immich-history": [ + { + "version": "v3.0.0", + "state": "Deprecated" + } + ], + "x-immich-state": "Deprecated" } }, "required": [ @@ -27214,8 +27351,6 @@ } }, "required": [ - "city", - "country", "createdAt", "duration", "fileCreatedAt", @@ -28219,6 +28354,7 @@ "description": "Plugin trigger type", "enum": [ "AssetCreate", + "AssetMetadataExtraction", "PersonRecognized" ], "type": "string" diff --git a/open-api/patch/api_client.dart.patch b/open-api/patch/api_client.dart.patch index 8996e79413..55acb0d3cd 100644 --- a/open-api/patch/api_client.dart.patch +++ b/open-api/patch/api_client.dart.patch @@ -1,21 +1,96 @@ -@@ -143,19 +143,19 @@ - ); +@@ -13,7 +13,7 @@ + class ApiClient { + ApiClient({this.basePath = '/api', this.authentication,}); + +- final String basePath; ++ String basePath; + final Authentication? authentication; + + var _client = Client(); +@@ -44,8 +44,9 @@ + Object? body, + Map headerParams, + Map formParams, +- String? contentType, +- ) async { ++ String? contentType, { ++ Future? abortTrigger, ++ }) async { + await authentication?.applyToParams(queryParams, headerParams); + + headerParams.addAll(_defaultHeaderMap); +@@ -63,7 +64,7 @@ + body is MultipartFile && (contentType == null || + !contentType.toLowerCase().startsWith('multipart/form-data')) + ) { +- final request = StreamedRequest(method, uri); ++ final request = AbortableStreamedRequest(method, uri, abortTrigger: abortTrigger); + request.headers.addAll(headerParams); + request.contentLength = body.length; + body.finalize().listen( +@@ -78,7 +79,7 @@ + } + + if (body is MultipartRequest) { +- final request = MultipartRequest(method, uri); ++ final request = AbortableMultipartRequest(method, uri, abortTrigger: abortTrigger); + request.fields.addAll(body.fields); + request.files.addAll(body.files); + request.headers.addAll(body.headers); +@@ -92,14 +93,19 @@ + : await serializeAsync(body); + final nullableHeaderParams = headerParams.isEmpty ? null : headerParams; + +- switch(method) { +- case 'POST': return await _client.post(uri, headers: nullableHeaderParams, body: msgBody,); +- case 'PUT': return await _client.put(uri, headers: nullableHeaderParams, body: msgBody,); +- case 'DELETE': return await _client.delete(uri, headers: nullableHeaderParams, body: msgBody,); +- case 'PATCH': return await _client.patch(uri, headers: nullableHeaderParams, body: msgBody,); +- case 'HEAD': return await _client.head(uri, headers: nullableHeaderParams,); +- case 'GET': return await _client.get(uri, headers: nullableHeaderParams,); ++ final request = AbortableRequest(method, uri, abortTrigger: abortTrigger); ++ if (nullableHeaderParams != null) { ++ request.headers.addAll(nullableHeaderParams); + } ++ if (msgBody is String) { ++ request.body = msgBody; ++ } else if (msgBody is List) { ++ request.bodyBytes = msgBody; ++ } else if (msgBody is Map) { ++ request.bodyFields = msgBody; ++ } ++ final response = await _client.send(request); ++ return Response.fromStream(response); + } on SocketException catch (error, trace) { + throw ApiException.withInner( + HttpStatus.badRequest, +@@ -136,26 +146,21 @@ + trace, + ); + } +- +- throw ApiException( +- HttpStatus.badRequest, +- 'Invalid HTTP operation: $method $path', +- ); } - + - Future deserializeAsync(String value, String targetType, {bool growable = false,}) async => + Future deserializeAsync(String value, String targetType, {bool growable = false,}) => // ignore: deprecated_member_use_from_same_package deserialize(value, targetType, growable: growable); - + @Deprecated('Scheduled for removal in OpenAPI Generator 6.x. Use deserializeAsync() instead.') - dynamic deserialize(String value, String targetType, {bool growable = false,}) { + Future deserialize(String value, String targetType, {bool growable = false,}) async { // Remove all spaces. Necessary for regular expressions as well. targetType = targetType.replaceAll(' ', ''); // ignore: parameter_assignments - + // If the expected target type is String, nothing to do... return targetType == 'String' ? value - : fromJson(json.decode(value), targetType, growable: growable); + : fromJson(await compute((String j) => json.decode(j), value), targetType, growable: growable); } + + // ignore: deprecated_member_use_from_same_package diff --git a/open-api/templates/mobile/api.mustache b/open-api/templates/mobile/api.mustache index ac32571123..2cd4c0f04e 100644 --- a/open-api/templates/mobile/api.mustache +++ b/open-api/templates/mobile/api.mustache @@ -49,7 +49,7 @@ class {{{classname}}} { /// {{/-last}} {{/allParams}} - Future {{{nickname}}}WithHttpInfo({{#allParams}}{{#required}}{{{dataType}}} {{{paramName}}},{{^-last}} {{/-last}}{{/required}}{{/allParams}}{{#hasOptionalParams}}{ {{#allParams}}{{^required}}{{{dataType}}}? {{{paramName}}},{{^-last}} {{/-last}}{{/required}}{{/allParams}} }{{/hasOptionalParams}}) async { + Future {{{nickname}}}WithHttpInfo({{#allParams}}{{#required}}{{{dataType}}} {{{paramName}}}, {{/required}}{{/allParams}}{ {{#allParams}}{{^required}}{{{dataType}}}? {{{paramName}}}, {{/required}}{{/allParams}}Future? abortTrigger, }) async { // ignore: prefer_const_declarations final apiPath = r'{{{path}}}'{{#pathParams}} .replaceAll({{=<% %>=}}'{<% baseName %>}'<%={{ }}=%>, {{{paramName}}}{{^isString}}.toString(){{/isString}}){{/pathParams}}; @@ -128,6 +128,7 @@ class {{{classname}}} { headerParams, formParams, contentTypes.isEmpty ? null : contentTypes.first, + abortTrigger: abortTrigger, ); } @@ -161,8 +162,8 @@ class {{{classname}}} { /// {{/-last}} {{/allParams}} - Future<{{#returnType}}{{{.}}}?{{/returnType}}{{^returnType}}void{{/returnType}}> {{{nickname}}}({{#allParams}}{{#required}}{{{dataType}}} {{{paramName}}},{{^-last}} {{/-last}}{{/required}}{{/allParams}}{{#hasOptionalParams}}{ {{#allParams}}{{^required}}{{{dataType}}}? {{{paramName}}},{{^-last}} {{/-last}}{{/required}}{{/allParams}} }{{/hasOptionalParams}}) async { - final response = await {{{nickname}}}WithHttpInfo({{#allParams}}{{#required}}{{{paramName}}},{{^-last}} {{/-last}}{{/required}}{{/allParams}}{{#hasOptionalParams}} {{#allParams}}{{^required}}{{{paramName}}}: {{{paramName}}},{{^-last}} {{/-last}}{{/required}}{{/allParams}} {{/hasOptionalParams}}); + Future<{{#returnType}}{{{.}}}?{{/returnType}}{{^returnType}}void{{/returnType}}> {{{nickname}}}({{#allParams}}{{#required}}{{{dataType}}} {{{paramName}}}, {{/required}}{{/allParams}}{ {{#allParams}}{{^required}}{{{dataType}}}? {{{paramName}}}, {{/required}}{{/allParams}}Future? abortTrigger, }) async { + final response = await {{{nickname}}}WithHttpInfo({{#allParams}}{{#required}}{{{paramName}}}, {{/required}}{{/allParams}}{{#allParams}}{{^required}}{{{paramName}}}: {{{paramName}}}, {{/required}}{{/allParams}}abortTrigger: abortTrigger,); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } diff --git a/open-api/templates/mobile/api.mustache.patch b/open-api/templates/mobile/api.mustache.patch index e3f888d6d7..feb5f40047 100644 --- a/open-api/templates/mobile/api.mustache.patch +++ b/open-api/templates/mobile/api.mustache.patch @@ -1,8 +1,11 @@ ---- api.mustache 2025-01-22 05:50:25 -+++ api.mustache.modified 2025-01-22 05:52:23 -@@ -51,7 +51,7 @@ +--- api.mustache ++++ api.mustache.modified +@@ -49,9 +49,9 @@ + /// + {{/-last}} {{/allParams}} - Future {{{nickname}}}WithHttpInfo({{#allParams}}{{#required}}{{{dataType}}} {{{paramName}}},{{^-last}} {{/-last}}{{/required}}{{/allParams}}{{#hasOptionalParams}}{ {{#allParams}}{{^required}}{{{dataType}}}? {{{paramName}}},{{^-last}} {{/-last}}{{/required}}{{/allParams}} }{{/hasOptionalParams}}) async { +- Future {{{nickname}}}WithHttpInfo({{#allParams}}{{#required}}{{{dataType}}} {{{paramName}}},{{^-last}} {{/-last}}{{/required}}{{/allParams}}{{#hasOptionalParams}}{ {{#allParams}}{{^required}}{{{dataType}}}? {{{paramName}}},{{^-last}} {{/-last}}{{/required}}{{/allParams}} }{{/hasOptionalParams}}) async { ++ Future {{{nickname}}}WithHttpInfo({{#allParams}}{{#required}}{{{dataType}}} {{{paramName}}}, {{/required}}{{/allParams}}{ {{#allParams}}{{^required}}{{{dataType}}}? {{{paramName}}}, {{/required}}{{/allParams}}Future? abortTrigger, }) async { // ignore: prefer_const_declarations - final path = r'{{{path}}}'{{#pathParams}} + final apiPath = r'{{{path}}}'{{#pathParams}} @@ -18,7 +21,7 @@ {{#formParams}} {{^isFile}} if ({{{paramName}}} != null) { -@@ -121,7 +121,7 @@ +@@ -121,13 +121,14 @@ {{/isMultipart}} return apiClient.invokeAPI( @@ -27,3 +30,21 @@ '{{{httpMethod}}}', queryParams, postBody, + headerParams, + formParams, + contentTypes.isEmpty ? null : contentTypes.first, ++ abortTrigger: abortTrigger, + ); + } + +@@ -161,8 +162,8 @@ + /// + {{/-last}} + {{/allParams}} +- Future<{{#returnType}}{{{.}}}?{{/returnType}}{{^returnType}}void{{/returnType}}> {{{nickname}}}({{#allParams}}{{#required}}{{{dataType}}} {{{paramName}}},{{^-last}} {{/-last}}{{/required}}{{/allParams}}{{#hasOptionalParams}}{ {{#allParams}}{{^required}}{{{dataType}}}? {{{paramName}}},{{^-last}} {{/-last}}{{/required}}{{/allParams}} }{{/hasOptionalParams}}) async { +- final response = await {{{nickname}}}WithHttpInfo({{#allParams}}{{#required}}{{{paramName}}},{{^-last}} {{/-last}}{{/required}}{{/allParams}}{{#hasOptionalParams}} {{#allParams}}{{^required}}{{{paramName}}}: {{{paramName}}},{{^-last}} {{/-last}}{{/required}}{{/allParams}} {{/hasOptionalParams}}); ++ Future<{{#returnType}}{{{.}}}?{{/returnType}}{{^returnType}}void{{/returnType}}> {{{nickname}}}({{#allParams}}{{#required}}{{{dataType}}} {{{paramName}}}, {{/required}}{{/allParams}}{ {{#allParams}}{{^required}}{{{dataType}}}? {{{paramName}}}, {{/required}}{{/allParams}}Future? abortTrigger, }) async { ++ final response = await {{{nickname}}}WithHttpInfo({{#allParams}}{{#required}}{{{paramName}}}, {{/required}}{{/allParams}}{{#allParams}}{{^required}}{{{paramName}}}: {{{paramName}}}, {{/required}}{{/allParams}}abortTrigger: abortTrigger,); + if (response.statusCode >= HttpStatus.badRequest) { + throw ApiException(response.statusCode, await _decodeBodyBytes(response)); + } diff --git a/package.json b/package.json index 4d361b329d..c6d1041f5a 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "format": "prettier --cache --check i18n/", "format:fix": "prettier --cache --write --list-different i18n" }, - "packageManager": "pnpm@10.33.1+sha512.05ba3c1d5d1c18f68df06470d74055e62d41fc110a0c660db1b2dfb2785327f04cf0f68345d4609bc52089e7fa0343c31593b2f9594e2c5d5da426230acc9820", + "packageManager": "pnpm@10.33.4+sha512.1c67b3b359b2d408119ba1ed289f34b8fc3c6873412bec6fd264fbdc82489e510fcbecb9ce9d22dae7f3b76269d8441046014bdca53b9979cd7a561ad631b800", "engines": { "pnpm": ">=10.0.0" }, diff --git a/packages/cli/package.json b/packages/cli/package.json index 534b213f2b..988cf034a5 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -25,7 +25,7 @@ "@types/lodash-es": "^4.17.12", "@types/micromatch": "^4.0.9", "@types/mock-fs": "^4.13.1", - "@types/node": "^24.12.2", + "@types/node": "^24.12.4", "@vitest/coverage-v8": "^4.0.0", "byte-size": "^9.0.0", "cli-progress": "^3.12.0", diff --git a/packages/e2e-auth-server/package.json b/packages/e2e-auth-server/package.json index 0e1928d34c..c9df258557 100644 --- a/packages/e2e-auth-server/package.json +++ b/packages/e2e-auth-server/package.json @@ -13,5 +13,5 @@ "oidc-provider": "^9.0.0", "tsx": "^4.20.6" }, - "packageManager": "pnpm@10.33.1" + "packageManager": "pnpm@10.33.4" } diff --git a/packages/plugin-core/manifest.json b/packages/plugin-core/manifest.json index 1dc6d21409..6157005cab 100644 --- a/packages/plugin-core/manifest.json +++ b/packages/plugin-core/manifest.json @@ -5,6 +5,58 @@ "description": "Core workflow capabilities for Immich", "author": "Immich Team", "wasmPath": "dist/plugin.wasm", + "templates": [ + { + "name": "screenshots-smart-album", + "title": "Archive screenshots", + "description": "Archive uploads with \"screenshot\" in the filename and optionally add them to an album", + "trigger": "AssetCreate", + "steps": [ + { + "method": "immich-plugin-core#assetFileFilter", + "config": { + "pattern": "screenshot", + "matchType": "contains", + "caseSensitive": false + } + }, + { + "method": "immich-plugin-core#assetArchive", + "config": { + "inverse": false + } + }, + { + "method": "immich-plugin-core#assetAddToAlbums", + "config": { + "albumName": "Screenshots", + "albumIds": [] + } + } + ], + "uiHints": ["SmartAlbum"] + }, + { + "name": "missing-timezone-smart-album", + "title": "Missing timezone", + "description": "Automatically create an album for assets without a time zone", + "trigger": "AssetMetadataExtraction", + "steps": [ + { + "method": "immich-plugin-core#assetMissingTimeZoneFilter", + "config": {} + }, + { + "method": "immich-plugin-core#assetAddToAlbums", + "config": { + "albumName": "Missing time zone", + "albumIds": [] + } + } + ], + "uiHints": ["SmartAlbum"] + } + ], "methods": [ { "name": "assetFileFilter", @@ -35,7 +87,25 @@ }, "required": ["pattern"] }, - "uiHints": ["filter"] + "uiHints": ["Filter"] + }, + { + "name": "assetMissingTimeZoneFilter", + "title": "Filter by missing time zone", + "description": "Filter assets that have no time zone information", + "types": ["AssetV1"], + "schema": { + "type": "object", + "properties": { + "inverse": { + "type": "boolean", + "title": "Inverse", + "description": "Missing by default, set to true to filter assets with a time zone", + "default": false + } + } + }, + "uiHints": ["Filter"] }, { "name": "filterFileType", @@ -55,7 +125,7 @@ }, "required": ["fileTypes"] }, - "uiHints": ["filter"] + "uiHints": ["Filter"] }, { "name": "filterPerson", @@ -69,7 +139,7 @@ "array": true, "title": "Person IDs", "description": "List of person to match", - "uiHint": "personI" + "uiHint": "personId" }, "matchAny": { "type": "boolean", @@ -80,7 +150,7 @@ }, "required": ["personIds"] }, - "uiHints": ["filter"] + "uiHints": ["Filter"] }, { "name": "assetArchive", @@ -157,7 +227,13 @@ "title": "Album IDs", "array": true, "description": "Target album IDs", - "uiHint": "albumId" + "uiHint": "AlbumId" + }, + "albumName": { + "type": "string", + "title": "Album name", + "array": true, + "description": "Use an album with this name if one exists, otherwise create a new one" } }, "required": ["albumIds"] @@ -242,14 +318,14 @@ "type": "string", "title": "Album ID", "description": "Target album ID", - "uiHint": "albumId" + "uiHint": "AlbumId" }, "albumIds": { "type": "string", "title": "Album IDs", "description": "Target album IDs", "array": true, - "uiHint": "albumId" + "uiHint": "AlbumId" } } } diff --git a/packages/plugin-core/package.json b/packages/plugin-core/package.json index 7c0bdf9af2..26b5124426 100644 --- a/packages/plugin-core/package.json +++ b/packages/plugin-core/package.json @@ -13,6 +13,7 @@ "license": "AGPL-3.0", "devDependencies": { "@extism/js-pdk": "^1.0.1", + "@immich/sdk": "workspace:*", "@immich/plugin-sdk": "workspace:*", "esbuild": "^0.28.0", "typescript": "^6.0.0" diff --git a/packages/plugin-core/src/index.d.ts b/packages/plugin-core/src/index.d.ts index ae45184cbe..170fa13102 100644 --- a/packages/plugin-core/src/index.d.ts +++ b/packages/plugin-core/src/index.d.ts @@ -1,14 +1,20 @@ -// copy from -// import '@immich/plugin-sdk/host-functions'; +// keep in sync with plugin-sdk/host-functions.ts'; declare module 'extism:host' { interface user { - albumAddAssets(ptr: PTR): I64; + searchAlbums(ptr: PTR): I64; + createAlbum(ptr: PTR): I64; + addAssetsToAlbum(ptr: PTR): I64; addAssetsToAlbums(ptr: PTR): I64; } } +// keep in sync with manifest.json declare module 'main' { + // filters export function assetFileFilter(): I32; + export function assetMissingTimeZoneFilter(): I32; + + // updates export function assetFavorite(): I32; export function assetVisibility(): I32; export function assetArchive(): I32; diff --git a/packages/plugin-core/src/index.ts b/packages/plugin-core/src/index.ts index de54e52bb0..bcb05cfa19 100644 --- a/packages/plugin-core/src/index.ts +++ b/packages/plugin-core/src/index.ts @@ -1,4 +1,5 @@ -import { AssetStatus, AssetVisibility, WorkflowType, wrapper } from '@immich/plugin-sdk'; +import { wrapper } from '@immich/plugin-sdk'; +import { AssetVisibility, WorkflowType } from '@immich/sdk'; type AssetFileFilterConfig = { pattern: string; @@ -41,6 +42,14 @@ export const assetFileFilter = () => { }); }; +export const assetMissingTimeZoneFilter = () => { + return wrapper(({ config, data }) => { + const hasTimeZone = !!data.asset?.exifInfo?.timeZone; + const needsTimeZone = config.inverse ? true : false; + return { workflow: { continue: hasTimeZone === needsTimeZone } }; + }); +}; + export const assetFavorite = () => { return wrapper(({ config, data }) => { const target = config.inverse ? false : true; @@ -89,23 +98,35 @@ export const assetLock = () => { }; export const assetTrash = () => { - return wrapper(({ config, data }) => ({ - changes: { - asset: config.inverse - ? { deletedAt: null, status: AssetStatus.Active } - : { deletedAt: new Date(), status: AssetStatus.Trashed }, - }, - })); + // TODO use trash/untrash host functions + return wrapper(() => ({})); }; export const assetAddToAlbums = () => { - return wrapper(({ config, data, functions }) => { + return wrapper(({ config, data, functions }) => { + const assetId = data.asset.id; + + if (config.albumIds.length === 0) { + if (!config.albumName) { + return {}; + } + + const [existing] = functions.searchAlbums({ name: config.albumName }); + if (!existing) { + const created = functions.createAlbum({ albumName: config.albumName, assetIds: [assetId] }); + config.albumIds.push(created.id); + return {}; + } + + config.albumIds.push(existing.id); + } + if (config.albumIds.length === 1) { - functions.albumAddAssets(config.albumIds[0], [data.asset.id]); + functions.addAssetsToAlbum(config.albumIds[0], [assetId]); return {}; } - functions.addAssetsToAlbums({ albumIds: config.albumIds, assetIds: [data.asset.id] }); + functions.addAssetsToAlbums({ albumIds: config.albumIds, assetIds: [assetId] }); return {}; }); }; diff --git a/packages/plugin-sdk/package.json b/packages/plugin-sdk/package.json index ff06c681fb..7c44368fbc 100644 --- a/packages/plugin-sdk/package.json +++ b/packages/plugin-sdk/package.json @@ -2,7 +2,6 @@ "name": "@immich/plugin-sdk", "version": "0.0.0", "description": "", - "main": "index.js", "type": "module", "exports": { "./host-functions": { @@ -11,7 +10,8 @@ }, ".": { "import": "./dist/index.js", - "types": "./dist/index.d.ts" + "types": "./dist/index.d.ts", + "default": "./dist/index.js" } }, "scripts": { @@ -24,11 +24,12 @@ "keywords": [], "author": "", "license": "GNU Affero General Public License version 3", - "packageManager": "pnpm@10.30.3", + "packageManager": "pnpm@10.33.4", "devDependencies": { "@extism/js-pdk": "^1.1.1", - "@types/node": "^24.11.0", - "esbuild": "^0.27.3", + "@immich/sdk": "workspace:*", + "@types/node": "^24.12.4", + "esbuild": "^0.28.0", "tsc-alias": "^1.8.16", "typescript": "^5.9.3" }, diff --git a/packages/plugin-sdk/src/enum.ts b/packages/plugin-sdk/src/enum.ts deleted file mode 100644 index a11dab64da..0000000000 --- a/packages/plugin-sdk/src/enum.ts +++ /dev/null @@ -1,33 +0,0 @@ -export enum WorkflowTrigger { - AssetCreate = 'AssetCreate', - PersonRecognized = 'PersonRecognized', -} - -export enum WorkflowType { - AssetV1 = 'AssetV1', - AssetPersonV1 = 'AssetPersonV1', -} - -export enum AssetType { - Image = 'IMAGE', - Video = 'VIDEO', - Audio = 'AUDIO', - Other = 'OTHER', -} - -export enum AssetStatus { - Active = 'active', - Trashed = 'trashed', - Deleted = 'deleted', -} - -export enum AssetVisibility { - Archive = 'archive', - Timeline = 'timeline', - - /** - * Video part of the LivePhotos and MotionPhotos - */ - Hidden = 'hidden', - Locked = 'locked', -} diff --git a/packages/plugin-sdk/src/host-functions.ts b/packages/plugin-sdk/src/host-functions.ts index d0f8a3ef17..281e27c83c 100644 --- a/packages/plugin-sdk/src/host-functions.ts +++ b/packages/plugin-sdk/src/host-functions.ts @@ -1,12 +1,26 @@ +import { + getAllAlbums, + type AlbumResponseDto, + type BulkIdResponseDto, + type BulkIdsDto, + type CreateAlbumDto, +} from '@immich/sdk'; + +// keep in sync with plugin-core/src/index.d.ts'; declare module 'extism:host' { interface user { - albumAddAssets(ptr: PTR): I64; + searchAlbums(ptr: PTR): I64; + createAlbum(ptr: PTR): I64; + addAssetsToAlbum(ptr: PTR): I64; addAssetsToAlbums(ptr: PTR): I64; } } -const host = Host.getFunctions(); -type HostFunctionName = keyof typeof host; +type AlbumsToAssets = { + assetIds: string[]; + albumIds: string[]; +}; + type HostFunctionSuccessResult = { success: true; response: T }; type HostFunctionErrorResult = { success: false; @@ -17,35 +31,49 @@ type HostFunctionResult = | HostFunctionSuccessResult | HostFunctionErrorResult; -const call = (name: HostFunctionName, authToken: string, args: T) => { - const pointer1 = Memory.fromString(JSON.stringify({ authToken, args })); - const fn = host[name]; - const handler = Memory.find(fn(pointer1.offset)); +type QueryParams any> = Parameters[0]; +type AlbumSearchDto = QueryParams; - try { - const result = JSON.parse(handler.readString()) as HostFunctionResult; +export const hostFunctions = (authToken: string) => { + const host = Host.getFunctions(); + type HostFunctionName = keyof typeof host; - if (result.success) { - return result.response; + const call = (name: HostFunctionName, authToken: string, args: T) => { + const pointer1 = Memory.fromString(JSON.stringify({ authToken, args })); + const fn = host[name]; + const handler = Memory.find(fn(pointer1.offset)); + + try { + const result = JSON.parse(handler.readString()) as HostFunctionResult; + + if (result.success) { + return result.response; + } + + throw new Error( + `Failed to call host function "${String(name)}", received ${result.status} - ${JSON.stringify(result.message)}`, + ); + } finally { + handler.free(); + pointer1.free(); } + }; - throw new Error( - `Failed to call host function "${String(name)}", received ${result.status} - ${JSON.stringify(result.message)}`, - ); - } finally { - handler.free(); - pointer1.free(); - } + return { + // album + searchAlbums: (dto: AlbumSearchDto) => + call<[AlbumSearchDto], AlbumResponseDto[]>('searchAlbums', authToken, [ + dto, + ]), + createAlbum: (dto: CreateAlbumDto) => + call<[CreateAlbumDto], AlbumResponseDto>('createAlbum', authToken, [dto]), + addAssetsToAlbum: (albumId: string, assetIds: string[]) => + call<[string, BulkIdsDto], BulkIdResponseDto[]>( + 'addAssetsToAlbum', + authToken, + [albumId, { ids: assetIds }], + ), + addAssetsToAlbums: ({ assetIds, albumIds }: AlbumsToAssets) => + call('addAssetsToAlbums', authToken, [{ albumIds, assetIds }]), + }; }; - -type AlbumsToAssets = { - assetIds: string[]; - albumIds: string[]; -}; - -export const hostFunctions = (authToken: string) => ({ - albumAddAssets: (albumId: string, assetIds: string[]) => - call('albumAddAssets', authToken, [albumId, { ids: assetIds }]), - addAssetsToAlbums: ({ assetIds, albumIds }: AlbumsToAssets) => - call('addAssetsToAlbums', authToken, [{ albumIds, assetIds }]), -}); diff --git a/packages/plugin-sdk/src/index.ts b/packages/plugin-sdk/src/index.ts index 6d4deb2053..c83369410a 100644 --- a/packages/plugin-sdk/src/index.ts +++ b/packages/plugin-sdk/src/index.ts @@ -1,4 +1,3 @@ -export * from 'src/enum.js'; export * from 'src/host-functions.js'; export * from 'src/sdk.js'; export * from 'src/types.js'; diff --git a/packages/plugin-sdk/src/sdk.ts b/packages/plugin-sdk/src/sdk.ts index f0ff8723a6..283e9c3dd5 100644 --- a/packages/plugin-sdk/src/sdk.ts +++ b/packages/plugin-sdk/src/sdk.ts @@ -1,9 +1,10 @@ -import type { WorkflowType } from 'src/enum.js'; +import type { WorkflowType } from '@immich/sdk'; import { hostFunctions } from 'src/host-functions.js'; import type { ConfigValue, WorkflowEventPayload, WorkflowResponse, + WorkflowStepConfig, } from 'src/types.js'; export const wrapper = < @@ -19,19 +20,28 @@ export const wrapper = < const input = Host.inputString(); try { - const event = JSON.parse(input) as WorkflowEventPayload; - // const debug = event.workflow.debug ?? false; + const payload = JSON.parse(input) as WorkflowEventPayload; + const event = { + ...payload, + functions: hostFunctions(payload.workflow.authToken), + }; + + const eventConfigBefore = JSON.stringify(event.config); console.debug( - `Inputs: trigger=${event.trigger}, event=${event.type}, config=${JSON.stringify(event.config)}`, + `Inputs: trigger=${event.trigger}, event=${event.type}, config=${eventConfigBefore}`, ); - const response = - fn({ ...event, functions: hostFunctions(event.workflow.authToken) }) ?? - {}; + const response = fn(event) ?? {}; + + // if config changed, notify host + const eventConfigAfter = JSON.stringify(event.config); + if (!response.config && eventConfigBefore !== eventConfigAfter) { + response.config = event.config as WorkflowStepConfig; + } console.debug( - `Outputs: workflow=${JSON.stringify(response.workflow)}, changes=${JSON.stringify(response.changes)}, data=${JSON.stringify(response.data)}`, + `Outputs: workflow=${JSON.stringify(response.workflow)}, changes=${JSON.stringify(response.changes)}, data=${JSON.stringify(response.data)}, config=${JSON.stringify(response.config)}`, ); const output = JSON.stringify(response); diff --git a/packages/plugin-sdk/src/types.ts b/packages/plugin-sdk/src/types.ts index 54cca3a5aa..67c179f4a6 100644 --- a/packages/plugin-sdk/src/types.ts +++ b/packages/plugin-sdk/src/types.ts @@ -1,10 +1,4 @@ -import type { - AssetStatus, - AssetType, - AssetVisibility, - WorkflowTrigger, - WorkflowType, -} from 'src/enum.js'; +import type { AssetTypeEnum, AssetVisibility, WorkflowType } from '@immich/sdk'; type DeepPartial = T extends Date ? T @@ -21,6 +15,12 @@ export type WorkflowEventMap = { export type WorkflowEventData = WorkflowEventMap[T]; +export enum WorkflowTrigger { + AssetCreate = 'AssetCreate', + AssetMetadataExtraction = 'AssetMetadataExtraction', + PersonRecognized = 'PersonRecognized', +} + export type WorkflowEventPayload< T extends WorkflowType = WorkflowType, TConfig = WorkflowStepConfig, @@ -48,6 +48,8 @@ export type WorkflowResponse = { changes?: WorkflowChanges; /** data to be passed to the next workflow step */ data?: Record; + /** update step config */ + config?: WorkflowStepConfig; }; export type WorkflowStepConfig = { @@ -66,24 +68,23 @@ export type AssetV1 = { asset: { id: string; ownerId: string; - type: AssetType; + type: AssetTypeEnum; originalPath: string; - fileCreatedAt: Date; - fileModifiedAt: Date; + fileCreatedAt: string; + fileModifiedAt: string; isFavorite: boolean; checksum: Buffer; // sha1 checksum livePhotoVideoId: string | null; - updatedAt: Date; - createdAt: Date; + updatedAt: string; + createdAt: string; originalFileName: string; isOffline: boolean; libraryId: string | null; isExternal: boolean; - deletedAt: Date | null; - localDateTime: Date; + deletedAt: string | null; + localDateTime: string; stackId: string | null; duplicateId: string | null; - status: AssetStatus; visibility: AssetVisibility; isEdited: boolean; exifInfo: { @@ -93,8 +94,8 @@ export type AssetV1 = { exifImageHeight: number | null; fileSizeInByte: number | null; orientation: string | null; - dateTimeOriginal: Date | null; - modifyDate: Date | null; + dateTimeOriginal: string | null; + modifyDate: string | null; lensModel: string | null; fNumber: number | null; focalLength: number | null; @@ -116,7 +117,7 @@ export type AssetV1 = { autoStackId: string | null; rating: number | null; tags: string[] | null; - updatedAt: Date | null; + updatedAt: string | null; } | null; }; }; diff --git a/packages/sdk/package.json b/packages/sdk/package.json index 926a30ba88..2ef3fac60c 100644 --- a/packages/sdk/package.json +++ b/packages/sdk/package.json @@ -24,7 +24,7 @@ "@oazapfts/runtime": "^1.0.2" }, "devDependencies": { - "@types/node": "^24.12.2", + "@types/node": "^24.12.4", "typescript": "^6.0.0" } } diff --git a/packages/sdk/src/fetch-client.ts b/packages/sdk/src/fetch-client.ts index bfeccd0c57..66a25a04f3 100644 --- a/packages/sdk/src/fetch-client.ts +++ b/packages/sdk/src/fetch-client.ts @@ -1514,6 +1514,30 @@ export type PluginResponseDto = { /** Plugin version */ version: string; }; +export type PluginTemplateStepResponseDto = { + /** Step configuration */ + config: { + [key: string]: any; + } | null; + /** Whether the step is enabled */ + enabled?: boolean; + /** Step plugin method */ + method: string; +}; +export type PluginTemplateResponseDto = { + /** Template description */ + description: string; + /** Template key (unique across all templates) */ + key: string; + /** Workflow steps */ + steps: PluginTemplateStepResponseDto[]; + /** Template title */ + title: string; + /** Workflow trigger */ + trigger: WorkflowTrigger; + /** Ui hints, for example "smart-album" */ + uiHints: string[]; +}; export type QueueResponseDto = { /** Whether the queue is paused */ isPaused: boolean; @@ -2590,9 +2614,9 @@ export type TagUpdateDto = { }; export type TimeBucketAssetResponseDto = { /** Array of city names extracted from EXIF GPS data */ - city: (string | null)[]; + city?: (string | null)[]; /** Array of country names extracted from EXIF GPS data */ - country: (string | null)[]; + country?: (string | null)[]; /** Array of UTC timestamps when each asset was originally uploaded to Immich */ createdAt: string[]; /** Array of video/gif durations in milliseconds (null for static images) */ @@ -3805,18 +3829,22 @@ export function getUserStatisticsAdmin({ id, isFavorite, isTrashed, visibility } /** * List all albums */ -export function getAllAlbums({ assetId, isOwned, isShared }: { +export function getAllAlbums({ assetId, id, isOwned, isShared, name }: { assetId?: string; + id?: string; isOwned?: boolean; isShared?: boolean; + name?: string; }, opts?: Oazapfts.RequestOpts) { return oazapfts.ok(oazapfts.fetchJson<{ status: 200; data: AlbumResponseDto[]; }>(`/albums${QS.query(QS.explode({ assetId, + id, isOwned, - isShared + isShared, + name }))}`, { ...opts })); @@ -5472,6 +5500,17 @@ export function searchPluginMethods({ description, enabled, id, name, pluginName ...opts })); } +/** + * Retrieve workflow templates + */ +export function searchPluginTemplates(opts?: Oazapfts.RequestOpts) { + return oazapfts.ok(oazapfts.fetchJson<{ + status: 200; + data: PluginTemplateResponseDto[]; + }>("/plugins/templates", { + ...opts + })); +} /** * Retrieve a plugin */ @@ -7627,6 +7666,7 @@ export enum WorkflowType { } export enum WorkflowTrigger { AssetCreate = "AssetCreate", + AssetMetadataExtraction = "AssetMetadataExtraction", PersonRecognized = "PersonRecognized" } export enum QueueJobStatus { @@ -7692,7 +7732,7 @@ export enum JobName { VersionCheck = "VersionCheck", OcrQueueAll = "OcrQueueAll", Ocr = "Ocr", - WorkflowAssetCreate = "WorkflowAssetCreate" + WorkflowAssetTrigger = "WorkflowAssetTrigger" } export enum SearchSuggestionType { Country = "country", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e7f2a45473..0db36c0ec2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -10,7 +10,7 @@ overrides: sharp: ^0.34.5 webpackbar: ^7.0.0 -packageExtensionsChecksum: sha256-3l4AQg4iuprBDup+q+2JaPvbPg/7XodWCE0ZteH+s54= +packageExtensionsChecksum: sha256-W6pFzyf+6QXnV91iA6oob0OGVkergPXDN1afLgoF53k= pnpmfileChecksum: sha256-un98do36L0wZyqsjcLozQ3YUadCAn2yz5bXcBbOuyDA= @@ -35,16 +35,16 @@ importers: dependencies: '@docusaurus/core': specifier: ~3.10.0 - version: 3.10.0(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3) + version: 3.10.1(@mdx-js/react@3.1.1(@types/react@19.2.15)(react@19.2.6))(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.3) '@docusaurus/preset-classic': specifier: ~3.10.0 - version: 3.10.0(@algolia/client-search@5.46.0)(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(search-insights@2.17.3)(typescript@6.0.3) + version: 3.10.1(@algolia/client-search@5.52.1)(@mdx-js/react@3.1.1(@types/react@19.2.15)(react@19.2.6))(@types/react@19.2.15)(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(search-insights@2.17.3)(typescript@6.0.3) '@docusaurus/theme-common': specifier: ~3.10.0 - version: 3.10.0(@docusaurus/plugin-content-docs@3.10.0(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3))(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + version: 3.10.1(@docusaurus/plugin-content-docs@3.10.1(@mdx-js/react@3.1.1(@types/react@19.2.15)(react@19.2.6))(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.3))(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) '@docusaurus/theme-mermaid': specifier: ~3.10.0 - version: 3.10.0(@docusaurus/plugin-content-docs@3.10.0(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3) + version: 3.10.1(@docusaurus/plugin-content-docs@3.10.1(@mdx-js/react@3.1.1(@types/react@19.2.15)(react@19.2.6))(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.3))(@mdx-js/react@3.1.1(@types/react@19.2.15)(react@19.2.6))(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.3) '@mdi/js': specifier: ^7.3.67 version: 7.4.47 @@ -53,47 +53,47 @@ importers: version: 1.6.1 '@mdx-js/react': specifier: ^3.0.0 - version: 3.1.1(@types/react@19.2.14)(react@19.2.5) + version: 3.1.1(@types/react@19.2.15)(react@19.2.6) autoprefixer: specifier: ^10.4.17 - version: 10.5.0(postcss@8.5.12) + version: 10.5.0(postcss@8.5.15) docusaurus-lunr-search: specifier: ^3.3.2 - version: 3.6.0(@docusaurus/core@3.10.0(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3))(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + version: 3.6.0(@docusaurus/core@3.10.1(@mdx-js/react@3.1.1(@types/react@19.2.15)(react@19.2.6))(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.3))(react-dom@19.2.6(react@19.2.6))(react@19.2.6) lunr: specifier: ^2.3.9 version: 2.3.9 postcss: specifier: ^8.4.25 - version: 8.5.12 + version: 8.5.15 prism-react-renderer: specifier: ^2.3.1 - version: 2.4.1(react@19.2.5) + version: 2.4.1(react@19.2.6) raw-loader: specifier: ^4.0.2 - version: 4.0.2(webpack@5.106.2) + version: 4.0.2(webpack@5.107.0(postcss@8.5.15)) react: specifier: ^19.0.0 - version: 19.2.5 + version: 19.2.6 react-dom: specifier: ^19.0.0 - version: 19.2.5(react@19.2.5) + version: 19.2.6(react@19.2.6) tailwindcss: specifier: ^3.2.4 - version: 3.4.19(tsx@4.21.0)(yaml@2.8.3) + version: 3.4.19(tsx@4.22.3)(yaml@2.9.0) url: specifier: ^0.11.0 version: 0.11.4 devDependencies: '@docusaurus/module-type-aliases': specifier: ~3.10.0 - version: 3.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + version: 3.10.1(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) '@docusaurus/tsconfig': specifier: ^3.10.0 - version: 3.10.0 + version: 3.10.1 '@docusaurus/types': specifier: ^3.10.0 - version: 3.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + version: 3.10.1(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) prettier: specifier: ^3.7.4 version: 3.8.3 @@ -105,13 +105,13 @@ importers: devDependencies: '@eslint/js': specifier: ^10.0.0 - version: 10.0.1(eslint@10.2.1(jiti@2.6.1)) + version: 10.0.1(eslint@10.4.0(jiti@2.7.0)) '@faker-js/faker': specifier: ^10.1.0 version: 10.4.0 '@futo-org/backups-orchestrator-ui': specifier: 0.1.73 - version: 0.1.73(svelte@5.55.8) + version: 0.1.73(@sveltejs/kit@2.60.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.1.2(svelte@5.55.8(@typescript-eslint/types@8.59.4))(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0)))(svelte@5.55.8(@typescript-eslint/types@8.59.4))(typescript@6.0.3)(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0)))(svelte@5.55.8(@typescript-eslint/types@8.59.4)) '@immich/cli': specifier: workspace:* version: link:../packages/cli @@ -123,7 +123,7 @@ importers: version: link:../packages/sdk '@playwright/test': specifier: ^1.44.1 - version: 1.59.1 + version: 1.60.0 '@socket.io/component-emitter': specifier: ^3.1.2 version: 3.1.2 @@ -131,8 +131,8 @@ importers: specifier: ^3.4.2 version: 3.7.1 '@types/node': - specifier: ^24.12.2 - version: 24.12.2 + specifier: ^24.12.4 + version: 24.12.4 '@types/pg': specifier: ^8.15.1 version: 8.20.0 @@ -147,28 +147,28 @@ importers: version: 17.4.2 eslint: specifier: ^10.0.0 - version: 10.2.1(jiti@2.6.1) + version: 10.4.0(jiti@2.7.0) eslint-config-prettier: specifier: ^10.1.8 - version: 10.1.8(eslint@10.2.1(jiti@2.6.1)) + version: 10.1.8(eslint@10.4.0(jiti@2.7.0)) eslint-plugin-prettier: specifier: ^5.1.3 - version: 5.5.5(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@10.2.1(jiti@2.6.1)))(eslint@10.2.1(jiti@2.6.1))(prettier@3.8.3) + version: 5.5.5(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@10.4.0(jiti@2.7.0)))(eslint@10.4.0(jiti@2.7.0))(prettier@3.8.3) eslint-plugin-unicorn: specifier: ^64.0.0 - version: 64.0.0(eslint@10.2.1(jiti@2.6.1)) + version: 64.0.0(eslint@10.4.0(jiti@2.7.0)) exiftool-vendored: specifier: ^35.0.0 version: 35.19.0 globals: specifier: ^17.0.0 - version: 17.5.0 + version: 17.6.0 luxon: specifier: ^3.4.4 version: 3.7.2 pg: specifier: ^8.11.3 - version: 8.20.0 + version: 8.21.0 pngjs: specifier: ^7.0.0 version: 7.0.0 @@ -192,16 +192,16 @@ importers: version: 6.0.3 typescript-eslint: specifier: ^8.28.0 - version: 8.59.0(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3) + version: 8.59.4(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3) utimes: specifier: ^5.2.1 - version: 5.2.1(encoding@0.1.13) + version: 5.2.1 vite-tsconfig-paths: specifier: ^6.1.1 - version: 6.1.1(typescript@6.0.3)(vite@8.0.10(@types/node@24.12.2)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)) + version: 6.1.1(typescript@6.0.3)(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0)) vitest: specifier: ^4.0.0 - version: 4.1.5(@opentelemetry/api@1.9.1)(@types/node@24.12.2)(@vitest/coverage-v8@4.1.5)(happy-dom@20.9.0)(jsdom@26.1.0(canvas@3.2.3))(vite@8.0.10(@types/node@24.12.2)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)) + version: 4.1.7(@opentelemetry/api@1.9.1)(@types/node@24.12.4)(@vitest/coverage-v8@4.1.7)(happy-dom@20.9.0)(jsdom@26.1.0(canvas@3.2.3))(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0)) packages/cli: dependencies: @@ -223,7 +223,7 @@ importers: devDependencies: '@eslint/js': specifier: ^10.0.0 - version: 10.0.1(eslint@10.2.1(jiti@2.6.1)) + version: 10.0.1(eslint@10.4.0(jiti@2.7.0)) '@immich/sdk': specifier: workspace:* version: link:../sdk @@ -243,11 +243,11 @@ importers: specifier: ^4.13.1 version: 4.13.4 '@types/node': - specifier: ^24.12.2 - version: 24.12.2 + specifier: ^24.12.4 + version: 24.12.4 '@vitest/coverage-v8': specifier: ^4.0.0 - version: 4.1.5(vitest@4.1.5) + version: 4.1.7(vitest@4.1.7) byte-size: specifier: ^9.0.0 version: 9.0.1 @@ -259,19 +259,19 @@ importers: version: 12.1.0 eslint: specifier: ^10.0.0 - version: 10.2.1(jiti@2.6.1) + version: 10.4.0(jiti@2.7.0) eslint-config-prettier: specifier: ^10.1.8 - version: 10.1.8(eslint@10.2.1(jiti@2.6.1)) + version: 10.1.8(eslint@10.4.0(jiti@2.7.0)) eslint-plugin-prettier: specifier: ^5.1.3 - version: 5.5.5(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@10.2.1(jiti@2.6.1)))(eslint@10.2.1(jiti@2.6.1))(prettier@3.8.3) + version: 5.5.5(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@10.4.0(jiti@2.7.0)))(eslint@10.4.0(jiti@2.7.0))(prettier@3.8.3) eslint-plugin-unicorn: specifier: ^64.0.0 - version: 64.0.0(eslint@10.2.1(jiti@2.6.1)) + version: 64.0.0(eslint@10.4.0(jiti@2.7.0)) globals: specifier: ^17.0.0 - version: 17.5.0 + version: 17.6.0 mock-fs: specifier: ^5.2.0 version: 5.5.0 @@ -286,19 +286,19 @@ importers: version: 6.0.3 typescript-eslint: specifier: ^8.58.0 - version: 8.59.0(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3) + version: 8.59.4(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3) vite: specifier: ^8.0.0 - version: 8.0.10(@types/node@24.12.2)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3) + version: 8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0) vitest: specifier: ^4.0.0 - version: 4.1.5(@opentelemetry/api@1.9.1)(@types/node@24.12.2)(@vitest/coverage-v8@4.1.5)(happy-dom@20.9.0)(jsdom@26.1.0(canvas@3.2.3))(vite@8.0.10(@types/node@24.12.2)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)) + version: 4.1.7(@opentelemetry/api@1.9.1)(@types/node@24.12.4)(@vitest/coverage-v8@4.1.7)(happy-dom@20.9.0)(jsdom@26.1.0(canvas@3.2.3))(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0)) vitest-fetch-mock: specifier: ^0.4.0 - version: 0.4.5(vitest@4.1.5) + version: 0.4.5(vitest@4.1.7) yaml: specifier: ^2.3.1 - version: 2.8.3 + version: 2.9.0 packages/e2e-auth-server: devDependencies: @@ -307,13 +307,13 @@ importers: version: 9.5.0 jose: specifier: ^6.0.0 - version: 6.2.2 + version: 6.2.3 oidc-provider: specifier: ^9.0.0 - version: 9.8.2 + version: 9.8.3 tsx: specifier: ^4.20.6 - version: 4.21.0 + version: 4.22.3 packages/plugin-core: devDependencies: @@ -323,6 +323,9 @@ importers: '@immich/plugin-sdk': specifier: workspace:* version: link:../plugin-sdk + '@immich/sdk': + specifier: workspace:* + version: link:../sdk esbuild: specifier: ^0.28.0 version: 0.28.0 @@ -335,15 +338,18 @@ importers: '@extism/js-pdk': specifier: ^1.1.1 version: 1.1.1 + '@immich/sdk': + specifier: workspace:* + version: link:../sdk '@types/node': - specifier: ^24.11.0 - version: 24.12.2 + specifier: ^24.12.4 + version: 24.12.4 esbuild: - specifier: ^0.27.3 - version: 0.27.4 + specifier: ^0.28.0 + version: 0.28.0 tsc-alias: specifier: ^1.8.16 - version: 1.8.16 + version: 1.8.17 typescript: specifier: ^5.9.3 version: 5.9.3 @@ -355,8 +361,8 @@ importers: version: 1.2.0 devDependencies: '@types/node': - specifier: ^24.12.2 - version: 24.12.2 + specifier: ^24.12.4 + version: 24.12.4 typescript: specifier: ^6.0.0 version: 6.0.3 @@ -368,7 +374,7 @@ importers: version: 2.0.0-rc13 '@futo-org/backups-orchestrator-api': specifier: 0.1.73 - version: 0.1.73(@nestjs/platform-express@11.1.19)(class-transformer@0.5.1)(reflect-metadata@0.2.2) + version: 0.1.73(@nestjs/platform-express@11.1.21)(class-transformer@0.5.1)(reflect-metadata@0.2.2) '@immich/plugin-sdk': specifier: workspace:* version: link:../packages/plugin-sdk @@ -377,28 +383,28 @@ importers: version: 0.5.2 '@nestjs/bullmq': specifier: ^11.0.1 - version: 11.0.4(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19)(bullmq@5.76.1) + version: 11.0.4(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21)(bullmq@5.76.10) '@nestjs/common': specifier: ^11.0.4 - version: 11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) + version: 11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) '@nestjs/core': specifier: ^11.0.4 - version: 11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.19)(@nestjs/websockets@11.1.19)(reflect-metadata@0.2.2)(rxjs@7.8.2) + version: 11.1.21(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.21)(@nestjs/websockets@11.1.21)(reflect-metadata@0.2.2)(rxjs@7.8.2) '@nestjs/platform-express': specifier: ^11.0.4 - version: 11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19) + version: 11.1.21(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21) '@nestjs/platform-socket.io': specifier: ^11.0.4 - version: 11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/websockets@11.1.19)(rxjs@7.8.2) + version: 11.1.21(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/websockets@11.1.21)(rxjs@7.8.2) '@nestjs/schedule': specifier: ^6.0.0 - version: 6.1.3(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19) + version: 6.1.3(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21) '@nestjs/swagger': specifier: ^11.4.2 - version: 11.4.2(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19)(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2) + version: 11.4.3(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21)(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(typescript@6.0.3) '@nestjs/websockets': specifier: ^11.0.4 - version: 11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19)(@nestjs/platform-socket.io@11.1.19)(reflect-metadata@0.2.2)(rxjs@7.8.2) + version: 11.1.21(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21)(@nestjs/platform-socket.io@11.1.21)(reflect-metadata@0.2.2)(rxjs@7.8.2) '@opentelemetry/api': specifier: ^1.9.0 version: 1.9.1 @@ -406,20 +412,20 @@ importers: specifier: ^2.0.0 version: 2.7.0(@opentelemetry/api@1.9.1) '@opentelemetry/exporter-prometheus': - specifier: ^0.217.0 - version: 0.217.0(@opentelemetry/api@1.9.1) + specifier: ^0.218.0 + version: 0.218.0(@opentelemetry/api@1.9.1) '@opentelemetry/instrumentation-http': - specifier: ^0.215.0 - version: 0.215.0(@opentelemetry/api@1.9.1) + specifier: ^0.218.0 + version: 0.218.0(@opentelemetry/api@1.9.1) '@opentelemetry/instrumentation-ioredis': - specifier: ^0.63.0 - version: 0.63.0(@opentelemetry/api@1.9.1) + specifier: ^0.66.0 + version: 0.66.0(@opentelemetry/api@1.9.1) '@opentelemetry/instrumentation-nestjs-core': - specifier: ^0.61.0 - version: 0.61.0(@opentelemetry/api@1.9.1) + specifier: ^0.64.0 + version: 0.64.0(@opentelemetry/api@1.9.1) '@opentelemetry/instrumentation-pg': - specifier: ^0.67.0 - version: 0.67.0(@opentelemetry/api@1.9.1) + specifier: ^0.70.0 + version: 0.70.0(@opentelemetry/api@1.9.1) '@opentelemetry/resources': specifier: ^2.0.1 version: 2.7.0(@opentelemetry/api@1.9.1) @@ -427,20 +433,20 @@ importers: specifier: ^2.0.1 version: 2.7.0(@opentelemetry/api@1.9.1) '@opentelemetry/sdk-node': - specifier: ^0.217.0 - version: 0.217.0(@opentelemetry/api@1.9.1) + specifier: ^0.218.0 + version: 0.218.0(@opentelemetry/api@1.9.1) '@opentelemetry/semantic-conventions': specifier: ^1.34.0 - version: 1.40.0 + version: 1.41.1 '@react-email/components': specifier: ^1.0.0 - version: 1.0.12(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + version: 1.0.12(react-dom@19.2.6(react@19.2.6))(react@19.2.6) '@react-email/render': specifier: ^2.0.0 - version: 2.0.7(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + version: 2.0.8(react-dom@19.2.6(react@19.2.6))(react@19.2.6) '@socket.io/redis-adapter': specifier: ^8.3.0 - version: 8.3.0(socket.io-adapter@2.5.6) + version: 8.3.0(socket.io-adapter@2.5.7) archiver: specifier: ^7.0.0 version: 7.0.1 @@ -455,7 +461,7 @@ importers: version: 2.2.2 bullmq: specifier: ^5.51.0 - version: 5.76.1 + version: 5.76.10 chokidar: specifier: ^4.0.3 version: 4.0.3 @@ -488,7 +494,7 @@ importers: version: 3.9.0 geo-tz: specifier: ^8.0.0 - version: 8.1.6 + version: 8.1.7 handlebars: specifier: ^4.7.8 version: 4.7.9 @@ -503,7 +509,7 @@ importers: version: 5.10.1 jose: specifier: ^6.0.0 - version: 6.2.2 + version: 6.2.3 js-yaml: specifier: ^4.1.0 version: 4.1.1 @@ -524,34 +530,34 @@ importers: version: 3.7.2 mnemonist: specifier: ^0.40.3 - version: 0.40.3 + version: 0.40.4 multer: specifier: ^2.0.2 version: 2.1.1 nest-commander: specifier: ^3.16.0 - version: 3.20.1(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19)(@types/inquirer@8.2.12)(@types/node@24.12.2)(typescript@6.0.3) + version: 3.20.1(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21)(@types/inquirer@8.2.12)(@types/node@24.12.4)(typescript@6.0.3) nestjs-cls: specifier: ^6.0.0 - version: 6.2.0(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19)(reflect-metadata@0.2.2)(rxjs@7.8.2) + version: 6.2.0(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21)(reflect-metadata@0.2.2)(rxjs@7.8.2) nestjs-kysely: specifier: 3.1.2 - version: 3.1.2(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19)(kysely@0.28.17)(reflect-metadata@0.2.2) + version: 3.1.2(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21)(kysely@0.28.17)(reflect-metadata@0.2.2) nestjs-otel: specifier: ^8.0.0 - version: 8.0.2(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19) + version: 8.0.3(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21) nestjs-zod: specifier: ^5.3.0 - version: 5.3.0(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/swagger@11.4.2(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19)(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2))(rxjs@7.8.2)(zod@4.3.6) + version: 5.4.0(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/swagger@11.4.3(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21)(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(typescript@6.0.3))(rxjs@7.8.2)(zod@4.3.6) nodemailer: specifier: ^8.0.0 - version: 8.0.5 + version: 8.0.7 openid-client: specifier: ^6.3.3 - version: 6.8.3 + version: 6.8.4 pg: specifier: ^8.11.3 - version: 8.20.0 + version: 8.21.0 picomatch: specifier: ^4.0.2 version: 4.0.4 @@ -560,10 +566,10 @@ importers: version: 3.4.9 react: specifier: ^19.0.0 - version: 19.2.5 + version: 19.2.6 react-dom: specifier: ^19.0.0 - version: 19.2.5(react@19.2.5) + version: 19.2.6(react@19.2.6) react-email: specifier: ^5.0.0 version: 5.2.11 @@ -578,7 +584,7 @@ importers: version: 1.6.4 semver: specifier: ^7.6.2 - version: 7.7.4 + version: 7.8.0 sharp: specifier: ^0.34.5 version: 0.34.5 @@ -590,7 +596,7 @@ importers: version: 4.8.3 tailwindcss-preset-email: specifier: ^1.4.0 - version: 1.4.1(tailwindcss@3.4.19(tsx@4.21.0)(yaml@2.8.3)) + version: 1.4.1(tailwindcss@3.4.19(tsx@4.22.3)(yaml@2.9.0)) thumbhash: specifier: ^0.1.1 version: 0.1.1 @@ -607,24 +613,24 @@ importers: specifier: ^13.12.0 version: 13.15.35 zod: - specifier: ^4.3.6 + specifier: 4.3.6 version: 4.3.6 devDependencies: '@eslint/js': specifier: ^10.0.0 - version: 10.0.1(eslint@10.2.1(jiti@2.6.1)) + version: 10.0.1(eslint@10.4.0(jiti@2.7.0)) '@nestjs/cli': specifier: ^11.0.2 - version: 11.0.21(@swc/core@1.15.30(@swc/helpers@0.5.21))(@types/node@24.12.2)(esbuild@0.28.0)(prettier@3.8.3) + version: 11.0.21(@swc/core@1.15.33(@swc/helpers@0.5.22))(@types/node@24.12.4)(esbuild@0.28.0)(lightningcss@1.32.0)(prettier@3.8.3) '@nestjs/schematics': specifier: ^11.0.0 version: 11.1.0(chokidar@4.0.3)(prettier@3.8.3)(typescript@6.0.3) '@nestjs/testing': specifier: ^11.0.4 - version: 11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19)(@nestjs/platform-express@11.1.19) + version: 11.1.21(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21)(@nestjs/platform-express@11.1.21) '@swc/core': specifier: ^1.4.14 - version: 1.15.30(@swc/helpers@0.5.21) + version: 1.15.33(@swc/helpers@0.5.22) '@types/archiver': specifier: ^7.0.0 version: 7.0.0 @@ -668,8 +674,8 @@ importers: specifier: ^2.0.0 version: 2.1.0 '@types/node': - specifier: ^24.12.2 - version: 24.12.2 + specifier: ^24.12.4 + version: 24.12.4 '@types/nodemailer': specifier: ^8.0.0 version: 8.0.0 @@ -681,7 +687,7 @@ importers: version: 6.0.5 '@types/react': specifier: ^19.0.0 - version: 19.2.14 + version: 19.2.15 '@types/semver': specifier: ^7.5.8 version: 7.7.1 @@ -696,22 +702,22 @@ importers: version: 13.15.10 '@vitest/coverage-v8': specifier: ^3.0.0 - version: 3.2.4(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.12.2)(happy-dom@20.9.0)(jiti@2.6.1)(jsdom@26.1.0(canvas@3.2.3))(lightningcss@1.32.0)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)) + version: 3.2.4(vitest@3.2.4(@types/debug@4.1.13)(@types/node@24.12.4)(happy-dom@20.9.0)(jiti@2.7.0)(jsdom@26.1.0(canvas@3.2.3))(lightningcss@1.32.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0)) eslint: specifier: ^10.0.0 - version: 10.2.1(jiti@2.6.1) + version: 10.4.0(jiti@2.7.0) eslint-config-prettier: specifier: ^10.1.8 - version: 10.1.8(eslint@10.2.1(jiti@2.6.1)) + version: 10.1.8(eslint@10.4.0(jiti@2.7.0)) eslint-plugin-prettier: specifier: ^5.1.3 - version: 5.5.5(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@10.2.1(jiti@2.6.1)))(eslint@10.2.1(jiti@2.6.1))(prettier@3.8.3) + version: 5.5.5(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@10.4.0(jiti@2.7.0)))(eslint@10.4.0(jiti@2.7.0))(prettier@3.8.3) eslint-plugin-unicorn: specifier: ^64.0.0 - version: 64.0.0(eslint@10.2.1(jiti@2.6.1)) + version: 64.0.0(eslint@10.4.0(jiti@2.7.0)) globals: specifier: ^17.0.0 - version: 17.5.0 + version: 17.6.0 mock-fs: specifier: ^5.2.0 version: 5.5.0 @@ -726,13 +732,13 @@ importers: version: 4.3.0(prettier@3.8.3)(typescript@6.0.3) sql-formatter: specifier: ^15.0.0 - version: 15.7.3 + version: 15.8.0 supertest: specifier: ^7.1.0 version: 7.2.2 tailwindcss: specifier: ^3.4.0 - version: 3.4.19(tsx@4.21.0)(yaml@2.8.3) + version: 3.4.19(tsx@4.22.3)(yaml@2.9.0) testcontainers: specifier: ^11.0.0 version: 11.14.0 @@ -741,25 +747,25 @@ importers: version: 6.0.3 typescript-eslint: specifier: ^8.28.0 - version: 8.59.0(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3) + version: 8.59.4(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3) unplugin-swc: specifier: ^1.4.5 - version: 1.5.9(@swc/core@1.15.30(@swc/helpers@0.5.21))(rollup@4.55.1) + version: 1.5.9(@swc/core@1.15.33(@swc/helpers@0.5.22))(rollup@4.60.4) vite-tsconfig-paths: specifier: ^6.0.0 - version: 6.1.1(typescript@6.0.3)(vite@8.0.10(@types/node@24.12.2)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)) + version: 6.1.1(typescript@6.0.3)(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0)) vitest: specifier: ^3.0.0 - version: 3.2.4(@types/debug@4.1.12)(@types/node@24.12.2)(happy-dom@20.9.0)(jiti@2.6.1)(jsdom@26.1.0(canvas@3.2.3))(lightningcss@1.32.0)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3) + version: 3.2.4(@types/debug@4.1.13)(@types/node@24.12.4)(happy-dom@20.9.0)(jiti@2.7.0)(jsdom@26.1.0(canvas@3.2.3))(lightningcss@1.32.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0) web: dependencies: '@formatjs/icu-messageformat-parser': specifier: ^3.0.0 - version: 3.5.4 + version: 3.5.9 '@futo-org/backups-orchestrator-ui': specifier: 0.1.73 - version: 0.1.73(@sveltejs/kit@2.57.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.55.8)(vite@8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)))(svelte@5.55.8)(typescript@6.0.3)(vite@8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)))(svelte@5.55.8) + version: 0.1.73(@sveltejs/kit@2.60.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.1.2(svelte@5.55.8(@typescript-eslint/types@8.59.4))(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0)))(svelte@5.55.8(@typescript-eslint/types@8.59.4))(typescript@6.0.3)(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0)))(svelte@5.55.8(@typescript-eslint/types@8.59.4)) '@immich/justified-layout-wasm': specifier: ^0.4.3 version: 0.4.3 @@ -767,8 +773,8 @@ importers: specifier: workspace:* version: link:../packages/sdk '@immich/ui': - specifier: ^0.77.0 - version: 0.77.3(@sveltejs/kit@2.57.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.55.8)(vite@8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)))(svelte@5.55.8)(typescript@6.0.3)(vite@8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)))(svelte@5.55.8) + specifier: ^0.79.2 + version: 0.79.2(@sveltejs/kit@2.60.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.1.2(svelte@5.55.8(@typescript-eslint/types@8.59.4))(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0)))(svelte@5.55.8(@typescript-eslint/types@8.59.4))(typescript@6.0.3)(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0)))(svelte@5.55.8(@typescript-eslint/types@8.59.4)) '@mapbox/mapbox-gl-rtl-text': specifier: 0.4.0 version: 0.4.0 @@ -804,13 +810,13 @@ importers: version: 0.42.0 '@zoom-image/svelte': specifier: ^0.3.0 - version: 0.3.9(svelte@5.55.8) + version: 0.3.9(svelte@5.55.8(@typescript-eslint/types@8.59.4)) dom-to-image: specifier: ^2.6.0 version: 2.6.0 fabric: specifier: ^7.0.0 - version: 7.3.1 + version: 7.4.0 geo-coordinates-parser: specifier: ^1.7.4 version: 1.7.4 @@ -825,7 +831,7 @@ importers: version: 20.9.0 intl-messageformat: specifier: ^11.0.0 - version: 11.2.1 + version: 11.2.6 justified-layout: specifier: ^4.1.0 version: 4.1.0 @@ -840,7 +846,7 @@ importers: version: 5.24.0 media-chrome: specifier: ^4.19.0 - version: 4.19.0(react@19.2.5) + version: 4.19.0(react@19.2.6) pmtiles: specifier: ^4.3.0 version: 4.4.1 @@ -849,7 +855,7 @@ importers: version: 1.5.4 simple-icons: specifier: ^16.0.0 - version: 16.17.0 + version: 16.20.0 socket.io-client: specifier: ~4.8.0 version: 4.8.3 @@ -858,25 +864,25 @@ importers: version: 5.2.2 svelte-i18n: specifier: ^4.0.1 - version: 4.0.1(svelte@5.55.8) + version: 4.0.1(svelte@5.55.8(@typescript-eslint/types@8.59.4)) svelte-jsoneditor: specifier: ^3.10.0 - version: 3.12.0(svelte@5.55.8) + version: 3.12.0(svelte@5.55.8(@typescript-eslint/types@8.59.4)) svelte-maplibre: specifier: ^1.2.5 - version: 1.3.0(svelte@5.55.8) + version: 1.3.0(svelte@5.55.8(@typescript-eslint/types@8.59.4)) svelte-persisted-store: specifier: ^0.12.0 - version: 0.12.0(svelte@5.55.8) + version: 0.12.0(svelte@5.55.8(@typescript-eslint/types@8.59.4)) tabbable: specifier: ^6.2.0 version: 6.4.0 tailwind-merge: specifier: ^3.5.0 - version: 3.5.0 + version: 3.6.0 tailwind-variants: specifier: ^3.2.2 - version: 3.2.2(tailwind-merge@3.5.0)(tailwindcss@4.2.4) + version: 3.2.2(tailwind-merge@3.6.0)(tailwindcss@4.3.0) thumbhash: specifier: ^0.1.1 version: 0.1.1 @@ -889,43 +895,43 @@ importers: devDependencies: '@eslint/js': specifier: ^10.0.0 - version: 10.0.1(eslint@10.2.1(jiti@2.6.1)) + version: 10.0.1(eslint@10.4.0(jiti@2.7.0)) '@faker-js/faker': specifier: ^10.0.0 version: 10.4.0 '@koddsson/eslint-plugin-tscompat': specifier: ^0.2.0 - version: 0.2.0(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3) + version: 0.2.0(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3) '@socket.io/component-emitter': specifier: ^3.1.0 version: 3.1.2 '@sveltejs/adapter-static': specifier: ^3.0.8 - version: 3.0.10(@sveltejs/kit@2.57.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.55.8)(vite@8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)))(svelte@5.55.8)(typescript@6.0.3)(vite@8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))) + version: 3.0.10(@sveltejs/kit@2.60.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.1.2(svelte@5.55.8(@typescript-eslint/types@8.59.4))(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0)))(svelte@5.55.8(@typescript-eslint/types@8.59.4))(typescript@6.0.3)(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0))) '@sveltejs/enhanced-img': specifier: ^0.10.4 - version: 0.10.4(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.55.8)(vite@8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)))(rollup@4.55.1)(svelte@5.55.8)(vite@8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)) + version: 0.10.4(@sveltejs/vite-plugin-svelte@7.1.2(svelte@5.55.8(@typescript-eslint/types@8.59.4))(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0)))(rollup@4.60.4)(svelte@5.55.8(@typescript-eslint/types@8.59.4))(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0)) '@sveltejs/kit': specifier: ^2.56.1 - version: 2.57.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.55.8)(vite@8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)))(svelte@5.55.8)(typescript@6.0.3)(vite@8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)) + version: 2.60.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.1.2(svelte@5.55.8(@typescript-eslint/types@8.59.4))(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0)))(svelte@5.55.8(@typescript-eslint/types@8.59.4))(typescript@6.0.3)(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0)) '@sveltejs/vite-plugin-svelte': - specifier: 7.0.0 - version: 7.0.0(svelte@5.55.8)(vite@8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)) + specifier: 7.1.2 + version: 7.1.2(svelte@5.55.8(@typescript-eslint/types@8.59.4))(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0)) '@tailwindcss/vite': specifier: ^4.2.4 - version: 4.2.4(vite@8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)) + version: 4.3.0(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0)) '@testing-library/jest-dom': specifier: ^6.4.2 version: 6.9.1 '@testing-library/svelte': specifier: ^5.2.8 - version: 5.3.1(svelte@5.55.8)(vite@8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))(vitest@4.1.5) + version: 5.3.1(svelte@5.55.8(@typescript-eslint/types@8.59.4))(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0))(vitest@4.1.7) '@testing-library/user-event': specifier: ^14.5.2 version: 14.6.1(@testing-library/dom@10.4.1) '@trivago/prettier-plugin-sort-imports': specifier: ^6.0.2 - version: 6.0.2(prettier-plugin-svelte@3.5.1(prettier@3.8.3)(svelte@5.55.8))(prettier@3.8.3)(svelte@5.55.8) + version: 6.0.2(prettier-plugin-svelte@3.5.2(prettier@3.8.3)(svelte@5.55.8(@typescript-eslint/types@8.59.4)))(prettier@3.8.3)(svelte@5.55.8(@typescript-eslint/types@8.59.4)) '@types/chromecast-caf-sender': specifier: ^1.0.11 version: 1.0.11 @@ -946,34 +952,34 @@ importers: version: 1.5.6 '@vitest/coverage-v8': specifier: ^4.0.0 - version: 4.1.5(vitest@4.1.5) + version: 4.1.7(vitest@4.1.7) dotenv: specifier: ^17.0.0 version: 17.4.2 eslint: specifier: ^10.2.1 - version: 10.2.1(jiti@2.6.1) + version: 10.4.0(jiti@2.7.0) eslint-config-prettier: specifier: ^10.1.8 - version: 10.1.8(eslint@10.2.1(jiti@2.6.1)) + version: 10.1.8(eslint@10.4.0(jiti@2.7.0)) eslint-plugin-better-tailwindcss: specifier: ^4.5.0 - version: 4.5.0(eslint@10.2.1(jiti@2.6.1))(tailwindcss@4.2.4)(typescript@6.0.3) + version: 4.5.0(eslint@10.4.0(jiti@2.7.0))(tailwindcss@4.3.0)(typescript@6.0.3) eslint-plugin-compat: specifier: ^7.0.0 - version: 7.0.1(eslint@10.2.1(jiti@2.6.1)) + version: 7.0.2(eslint@10.4.0(jiti@2.7.0)) eslint-plugin-svelte: specifier: ^3.12.4 - version: 3.17.1(eslint@10.2.1(jiti@2.6.1))(svelte@5.55.8) + version: 3.17.1(eslint@10.4.0(jiti@2.7.0))(svelte@5.55.8(@typescript-eslint/types@8.59.4)) eslint-plugin-unicorn: specifier: ^64.0.0 - version: 64.0.0(eslint@10.2.1(jiti@2.6.1)) + version: 64.0.0(eslint@10.4.0(jiti@2.7.0)) factory.ts: specifier: ^1.4.1 version: 1.4.2 globals: specifier: ^17.0.0 - version: 17.5.0 + version: 17.6.0 prettier: specifier: ^3.7.4 version: 3.8.3 @@ -982,137 +988,125 @@ importers: version: 4.2.0(prettier@3.8.3) prettier-plugin-svelte: specifier: ^3.3.3 - version: 3.5.1(prettier@3.8.3)(svelte@5.55.8) + version: 3.5.2(prettier@3.8.3)(svelte@5.55.8(@typescript-eslint/types@8.59.4)) rollup-plugin-visualizer: specifier: ^7.0.0 - version: 7.0.1(rolldown@1.0.0-rc.17)(rollup@4.55.1) + version: 7.0.1(rolldown@1.0.1)(rollup@4.60.4) svelte: specifier: 5.55.8 - version: 5.55.8 + version: 5.55.8(@typescript-eslint/types@8.59.4) svelte-check: specifier: ^4.4.6 - version: 4.4.6(picomatch@4.0.4)(svelte@5.55.8)(typescript@6.0.3) + version: 4.4.8(picomatch@4.0.4)(svelte@5.55.8(@typescript-eslint/types@8.59.4))(typescript@6.0.3) svelte-eslint-parser: specifier: ^1.3.3 - version: 1.6.0(svelte@5.55.8) + version: 1.6.1(svelte@5.55.8(@typescript-eslint/types@8.59.4)) tailwindcss: specifier: ^4.2.4 - version: 4.2.4 + version: 4.3.0 typescript: specifier: ^6.0.0 version: 6.0.3 typescript-eslint: specifier: ^8.45.0 - version: 8.59.0(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3) + version: 8.59.4(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3) vite: specifier: ^8.0.0 - version: 8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3) + version: 8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0) vitest: specifier: ^4.0.0 - version: 4.1.5(@opentelemetry/api@1.9.1)(@types/node@25.6.0)(@vitest/coverage-v8@4.1.5)(happy-dom@20.9.0)(jsdom@26.1.0(canvas@3.2.3))(vite@8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)) + version: 4.1.7(@opentelemetry/api@1.9.1)(@types/node@24.12.4)(@vitest/coverage-v8@4.1.7)(happy-dom@20.9.0)(jsdom@26.1.0(canvas@3.2.3))(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0)) packages: '@adobe/css-tools@4.4.4': resolution: {integrity: sha512-Elp+iwUx5rN5+Y8xLt5/GRoG20WGoDCQ/1Fb+1LiGtvwbDavuSk0jhD/eZdckHAuzcDzccnkv+rEjyWfRx18gg==} - '@ai-sdk/gateway@2.0.21': - resolution: {integrity: sha512-BwV7DU/lAm3Xn6iyyvZdWgVxgLu3SNXzl5y57gMvkW4nGhAOV5269IrJzQwGt03bb107sa6H6uJwWxc77zXoGA==} - engines: {node: '>=18'} - peerDependencies: - zod: ^3.25.76 || ^4.1.8 - - '@ai-sdk/provider-utils@3.0.19': - resolution: {integrity: sha512-W41Wc9/jbUVXVwCN/7bWa4IKe8MtxO3EyA0Hfhx6grnmiYlCvpI8neSYWFE0zScXJkgA/YK3BRybzgyiXuu6JA==} - engines: {node: '>=18'} - peerDependencies: - zod: ^3.25.76 || ^4.1.8 - - '@ai-sdk/provider@2.0.0': - resolution: {integrity: sha512-6o7Y2SeO9vFKB8lArHXehNuusnpddKPk7xqL7T2/b+OvXMRIXUO1rR4wcv1hAFUAT9avGZshty3Wlua/XA7TvA==} - engines: {node: '>=18'} - - '@ai-sdk/react@2.0.115': - resolution: {integrity: sha512-Etu7gWSEi2dmXss1PoR5CAZGwGShXsF9+Pon1eRO6EmatjYaBMhq1CfHPyYhGzWrint8jJIK2VaAhiMef29qZw==} - engines: {node: '>=18'} - peerDependencies: - react: ^18 || ~19.0.1 || ~19.1.2 || ^19.2.1 - zod: ^3.25.76 || ^4.1.8 - peerDependenciesMeta: - zod: - optional: true - - '@algolia/abtesting@1.12.0': - resolution: {integrity: sha512-EfW0bfxjPs+C7ANkJDw2TATntfBKsFiy7APh+KO0pQ8A6HYa5I0NjFuCGCXWfzzzLXNZta3QUl3n5Kmm6aJo9Q==} + '@algolia/abtesting@1.18.1': + resolution: {integrity: sha512-aehCadlWOGvrT91KUIZpC0MbB8KBW9yUuvTJFd2xesR7le/IsT4nJUnjCCZ4ZqZCeTcPHPV5mo//fZ5oxcSVYw==} engines: {node: '>= 14.0.0'} '@algolia/autocomplete-core@1.19.2': resolution: {integrity: sha512-mKv7RyuAzXvwmq+0XRK8HqZXt9iZ5Kkm2huLjgn5JoCPtDy+oh9yxUMfDDaVCw0oyzZ1isdJBc7l9nuCyyR7Nw==} + '@algolia/autocomplete-core@1.19.8': + resolution: {integrity: sha512-3YEorYg44niXcm7gkft3nXYItHd44e8tmh4D33CTszPgP0QWkaLEaFywiNyJBo7UL/mqObA/G9RYuU7R8tN1IA==} + '@algolia/autocomplete-plugin-algolia-insights@1.19.2': resolution: {integrity: sha512-TjxbcC/r4vwmnZaPwrHtkXNeqvlpdyR+oR9Wi2XyfORkiGkLTVhX2j+O9SaCCINbKoDfc+c2PB8NjfOnz7+oKg==} peerDependencies: search-insights: '>= 1 < 3' + '@algolia/autocomplete-plugin-algolia-insights@1.19.8': + resolution: {integrity: sha512-ZvJWO8ZZJDpc1LNM2TTBdmQsZBLMR4rU5iNR2OYvEeFBiaf/0ESnRSSLQbryarJY4SVxtoz6A2ZtDMNM+iQEAA==} + peerDependencies: + search-insights: '>= 1 < 3' + '@algolia/autocomplete-shared@1.19.2': resolution: {integrity: sha512-jEazxZTVD2nLrC+wYlVHQgpBoBB5KPStrJxLzsIFl6Kqd1AlG9sIAGl39V5tECLpIQzB3Qa2T6ZPJ1ChkwMK/w==} peerDependencies: '@algolia/client-search': '>= 4.9.1 < 6' algoliasearch: '>= 4.9.1 < 6' - '@algolia/client-abtesting@5.46.0': - resolution: {integrity: sha512-eG5xV8rujK4ZIHXrRshvv9O13NmU/k42Rnd3w43iKH5RaQ2zWuZO6Q7XjaoJjAFVCsJWqRbXzbYyPGrbF3wGNg==} + '@algolia/autocomplete-shared@1.19.8': + resolution: {integrity: sha512-h5hf2t8ejF6vlOgvLaZzQbWs5SyH2z4PAWygNAvvD/2RI29hdQ54ldUGwqVuj9Srs+n8XUKTPUqb7fvhBhQrnQ==} + peerDependencies: + '@algolia/client-search': '>= 4.9.1 < 6' + algoliasearch: '>= 4.9.1 < 6' + + '@algolia/client-abtesting@5.52.1': + resolution: {integrity: sha512-HmXOGBOAOJPounpBzBpuY0zDYeiCpxgHnQmuA7JO6ScukcBdGp3/XM9zJk5pJx/xNGD68mbPGXWpDxGtl6BwDQ==} engines: {node: '>= 14.0.0'} - '@algolia/client-analytics@5.46.0': - resolution: {integrity: sha512-AYh2uL8IUW9eZrbbT+wZElyb7QkkeV3US2NEKY7doqMlyPWE8lErNfkVN1NvZdVcY4/SVic5GDbeDz2ft8YIiQ==} + '@algolia/client-analytics@5.52.1': + resolution: {integrity: sha512-5oo4+I8iixie9vXhCyNFCzeIr8pqA3FQ//VsLHTDvZAV4ttYOPGvYHGQq5NSalrLx5Jc3dRro/5uDOlnUMcBJg==} engines: {node: '>= 14.0.0'} - '@algolia/client-common@5.46.0': - resolution: {integrity: sha512-0emZTaYOeI9WzJi0TcNd2k3SxiN6DZfdWc2x2gHt855Jl9jPUOzfVTL6gTvCCrOlT4McvpDGg5nGO+9doEjjig==} + '@algolia/client-common@5.52.1': + resolution: {integrity: sha512-qCDoZfx5MpX7XQzvQ3bC4tSEMkQWQMaF/ABtLuoze03Y/flR563CCSws02qIJ23oX7lxl92LsilZjINVyTdtLw==} engines: {node: '>= 14.0.0'} - '@algolia/client-insights@5.46.0': - resolution: {integrity: sha512-wrBJ8fE+M0TDG1As4DDmwPn2TXajrvmvAN72Qwpuv8e2JOKNohF7+JxBoF70ZLlvP1A1EiH8DBu+JpfhBbNphQ==} + '@algolia/client-insights@5.52.1': + resolution: {integrity: sha512-hnGs0/lsFJ2PWDxNBz7pxreXo/Xz7gxYRcfePBUjsH26ad0kU/sgnVZd9LwWBpsQv65z2jlb5dkyaB9WE9M9FQ==} engines: {node: '>= 14.0.0'} - '@algolia/client-personalization@5.46.0': - resolution: {integrity: sha512-LnkeX4p0ENt0DoftDJJDzQQJig/sFQmD1eQifl/iSjhUOGUIKC/7VTeXRcKtQB78naS8njUAwpzFvxy1CDDXDQ==} + '@algolia/client-personalization@5.52.1': + resolution: {integrity: sha512-2VxxNc/uBysyKvGeBdSM5n9eIDKH8kWD7wd9/yqbJAiVwU4Yv6tU1LSJusHKrXV/aCu1KW7t9Gug9QyeEmtn/Q==} engines: {node: '>= 14.0.0'} - '@algolia/client-query-suggestions@5.46.0': - resolution: {integrity: sha512-aF9tc4ex/smypXw+W3lBPB1jjKoaGHpZezTqofvDOI/oK1dR2sdTpFpK2Ru+7IRzYgwtRqHF3znmTlyoNs9dpA==} + '@algolia/client-query-suggestions@5.52.1': + resolution: {integrity: sha512-O6mPtsw3xEfNOe6gWFpYLeAZAIljNa4Hgna3bq15PwyN7nbjTY0wXJFRbzs/0YVf75Br+SbOQUmjKxXYjDiSiQ==} engines: {node: '>= 14.0.0'} - '@algolia/client-search@5.46.0': - resolution: {integrity: sha512-22SHEEVNjZfFWkFks3P6HilkR3rS7a6GjnCIqR22Zz4HNxdfT0FG+RE7efTcFVfLUkTTMQQybvaUcwMrHXYa7Q==} + '@algolia/client-search@5.52.1': + resolution: {integrity: sha512-gA8oJOV1LnQQkDf91iebNnFInHuW0gRPEgLSOQ7EfipCEjYTHm5swm1DlH9H5RaRw4RrHuzHBegnlzc0MAstcg==} engines: {node: '>= 14.0.0'} '@algolia/events@4.0.1': resolution: {integrity: sha512-FQzvOCgoFXAbf5Y6mYozw2aj5KCJoA3m4heImceldzPSMbdyS4atVjJzXKMsfX3wnZTFYwkkt8/z8UesLHlSBQ==} - '@algolia/ingestion@1.46.0': - resolution: {integrity: sha512-2LT0/Z+/sFwEpZLH6V17WSZ81JX2uPjgvv5eNlxgU7rPyup4NXXfuMbtCJ+6uc4RO/LQpEJd3Li59ke3wtyAsA==} + '@algolia/ingestion@1.52.1': + resolution: {integrity: sha512-U9zZfc5xIu9wRxZkt+HceJUAD4VKHKbAyLSloJdEyMRmphXeibfrY9cxqIXBcmPeZzGhn3Imb35Dq8l19PkJhw==} engines: {node: '>= 14.0.0'} - '@algolia/monitoring@1.46.0': - resolution: {integrity: sha512-uivZ9wSWZ8mz2ZU0dgDvQwvVZV8XBv6lYBXf8UtkQF3u7WeTqBPeU8ZoeTyLpf0jAXCYOvc1mAVmK0xPLuEwOQ==} + '@algolia/monitoring@1.52.1': + resolution: {integrity: sha512-a3SGNceHmkQfq77iG8Ka+w1pvwfZa/0lzEIgse30fL0kD+yKnd/dg0dQvSfFPAEt2f21DMcGkDSSeJlO3KdQjQ==} engines: {node: '>= 14.0.0'} - '@algolia/recommend@5.46.0': - resolution: {integrity: sha512-O2BB8DuySuddgOAbhyH4jsGbL+KyDGpzJRtkDZkv091OMomqIA78emhhMhX9d/nIRrzS1wNLWB/ix7Hb2eV5rg==} + '@algolia/recommend@5.52.1': + resolution: {integrity: sha512-z98QEguCFDpxb4S/PyrUK1igqF8tPsdbqOUUO6ON91vJ58w+Gwa6ncrI0oNXSFcrkxA5EqPKPQ2A1PBCn08TYQ==} engines: {node: '>= 14.0.0'} - '@algolia/requester-browser-xhr@5.46.0': - resolution: {integrity: sha512-eW6xyHCyYrJD0Kjk9Mz33gQ40LfWiEA51JJTVfJy3yeoRSw/NXhAL81Pljpa0qslTs6+LO/5DYPZddct6HvISQ==} + '@algolia/requester-browser-xhr@5.52.1': + resolution: {integrity: sha512-CI7+/0I11QeZM59Uc8whd2or0kqzFVjpaPn9Qpwll/krHcBAxk24WkAQ6WX+IwDVMfpont4YGbKwAmCre3vE8Q==} engines: {node: '>= 14.0.0'} - '@algolia/requester-fetch@5.46.0': - resolution: {integrity: sha512-Vn2+TukMGHy4PIxmdvP667tN/MhS7MPT8EEvEhS6JyFLPx3weLcxSa1F9gVvrfHWCUJhLWoMVJVB2PT8YfRGcw==} + '@algolia/requester-fetch@5.52.1': + resolution: {integrity: sha512-S6bDuw9byfOvm3T71cgdoZgrgnZq6hpdMLkx52Louh57nUAmvGQESz2aojOynQHjbTiV55smvAFbgn0qT4tJrg==} engines: {node: '>= 14.0.0'} - '@algolia/requester-node-http@5.46.0': - resolution: {integrity: sha512-xaqXyna5yBZ+r1SJ9my/DM6vfTqJg9FJgVydRJ0lnO+D5NhqGW/qaRG/iBGKr/d4fho34el6WakV7BqJvrl/HQ==} + '@algolia/requester-node-http@5.52.1': + resolution: {integrity: sha512-tqZXM+54rWo4mk5jL5Z/flE11nPmNEdXwFBM5py9DkOmbjeCNemfVd45FyM97XdzfZ0dl9uOJC6PYn1FpkeyQg==} engines: {node: '>= 14.0.0'} '@alloc/quick-lru@5.2.0': @@ -1151,12 +1145,12 @@ packages: resolution: {integrity: sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==} engines: {node: '>=6.9.0'} - '@babel/compat-data@7.28.5': - resolution: {integrity: sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA==} + '@babel/compat-data@7.29.3': + resolution: {integrity: sha512-LIVqM46zQWZhj17qA8wb4nW/ixr2y1Nw+r1etiAWgRM6U1IqP+LNhL1yg440jYZR72jCWcWbLWzIosH+uP1fqg==} engines: {node: '>=6.9.0'} - '@babel/core@7.28.5': - resolution: {integrity: sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==} + '@babel/core@7.29.0': + resolution: {integrity: sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==} engines: {node: '>=6.9.0'} '@babel/generator@7.29.1': @@ -1167,12 +1161,12 @@ packages: resolution: {integrity: sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==} engines: {node: '>=6.9.0'} - '@babel/helper-compilation-targets@7.27.2': - resolution: {integrity: sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==} + '@babel/helper-compilation-targets@7.28.6': + resolution: {integrity: sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==} engines: {node: '>=6.9.0'} - '@babel/helper-create-class-features-plugin@7.28.5': - resolution: {integrity: sha512-q3WC4JfdODypvxArsJQROfupPBq9+lMwjKq7C33GhbFYJsufD0yd/ziwD+hJucLeWsnFPWZjsU2DNFqBPE7jwQ==} + '@babel/helper-create-class-features-plugin@7.29.3': + resolution: {integrity: sha512-RpLYy2sb51oNLjuu1iD3bwBqCBWUzjO0ocp+iaCP/lJtb2CPLcnC2Fftw+4sAzaMELGeWTgExSKADbdo0GFVzA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 @@ -1183,8 +1177,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0 - '@babel/helper-define-polyfill-provider@0.6.5': - resolution: {integrity: sha512-uJnGFcPsWQK8fvjgGP5LZUZZsYGIoPeRjSF5PGwrelYgq7Q15/Ft9NGFp1zglwgIv//W0uG4BevRuSJRyylZPg==} + '@babel/helper-define-polyfill-provider@0.6.8': + resolution: {integrity: sha512-47UwBLPpQi1NoWzLuHNjRoHlYXMwIJoBf7MFou6viC/sIHWYygpvr0B6IAyh5sBdA2nr2LPIRww8lfaUVQINBA==} peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 @@ -1196,12 +1190,12 @@ packages: resolution: {integrity: sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg==} engines: {node: '>=6.9.0'} - '@babel/helper-module-imports@7.27.1': - resolution: {integrity: sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==} + '@babel/helper-module-imports@7.28.6': + resolution: {integrity: sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==} engines: {node: '>=6.9.0'} - '@babel/helper-module-transforms@7.28.3': - resolution: {integrity: sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==} + '@babel/helper-module-transforms@7.28.6': + resolution: {integrity: sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 @@ -1210,8 +1204,8 @@ packages: resolution: {integrity: sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==} engines: {node: '>=6.9.0'} - '@babel/helper-plugin-utils@7.27.1': - resolution: {integrity: sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==} + '@babel/helper-plugin-utils@7.28.6': + resolution: {integrity: sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==} engines: {node: '>=6.9.0'} '@babel/helper-remap-async-to-generator@7.27.1': @@ -1220,8 +1214,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0 - '@babel/helper-replace-supers@7.27.1': - resolution: {integrity: sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA==} + '@babel/helper-replace-supers@7.28.6': + resolution: {integrity: sha512-mq8e+laIk94/yFec3DxSjCRD2Z0TAjhVbEJY3UQrlwVo15Lmt7C2wAUbK4bjnTs4APkwsYLTahXRraQXhb1WCg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 @@ -1242,12 +1236,12 @@ packages: resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} engines: {node: '>=6.9.0'} - '@babel/helper-wrap-function@7.28.3': - resolution: {integrity: sha512-zdf983tNfLZFletc0RRXYrHrucBEg95NIFMkn6K9dbeMYnsgHaSBGcQqdsCSStG2PYwRre0Qc2NNSCXbG+xc6g==} + '@babel/helper-wrap-function@7.28.6': + resolution: {integrity: sha512-z+PwLziMNBeSQJonizz2AGnndLsP2DeGHIxDAn+wdHOGuo4Fo1x1HBPPXeE9TAOPHNNWQKCSlA2VZyYyyibDnQ==} engines: {node: '>=6.9.0'} - '@babel/helpers@7.28.4': - resolution: {integrity: sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==} + '@babel/helpers@7.29.2': + resolution: {integrity: sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==} engines: {node: '>=6.9.0'} '@babel/parser@7.27.0': @@ -1255,8 +1249,8 @@ packages: engines: {node: '>=6.0.0'} hasBin: true - '@babel/parser@7.29.2': - resolution: {integrity: sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==} + '@babel/parser@7.29.3': + resolution: {integrity: sha512-b3ctpQwp+PROvU/cttc4OYl4MzfJUWy6FZg+PMXfzmt/+39iHVF0sDfqay8TQM3JA2EUOyKcFZt75jWriQijsA==} engines: {node: '>=6.0.0'} hasBin: true @@ -1278,14 +1272,20 @@ packages: peerDependencies: '@babel/core': ^7.0.0 + '@babel/plugin-bugfix-safari-rest-destructuring-rhs-array@7.29.3': + resolution: {integrity: sha512-SRS46DFR4HqzUzCVgi90/xMoL+zeBDBvWdKYXSEzh79kXswNFEglUpMKxR04//dPqwYXWUBJ3mpUd933ru9Kmg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.27.1': resolution: {integrity: sha512-oO02gcONcD5O1iTLi/6frMJBIwWEHceWGSGqrpCmEL8nogiS6J9PBlE48CaK20/Jx1LuRml9aDftLgdjXT8+Cw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.13.0 - '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.28.3': - resolution: {integrity: sha512-b6YTX108evsvE4YgWyQ921ZAFFQm3Bn+CA3+ZXlNVnPhx+UfsVURoPjfGAPCjBgrqo30yX/C2nZGX96DxvR9Iw==} + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.28.6': + resolution: {integrity: sha512-a0aBScVTlNaiUe35UtfxAN7A/tehvvG4/ByO6+46VPKTRSlfnAFsgKy0FUh+qAkQrDTmhDkT+IBOKlOoMUxQ0g==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 @@ -1301,26 +1301,26 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-syntax-import-assertions@7.27.1': - resolution: {integrity: sha512-UT/Jrhw57xg4ILHLFnzFpPDlMbcdEicaAtjPQpbj9wa8T4r5KVWCimHcL/460g8Ht0DMxDyjsLgiWSkVjnwPFg==} + '@babel/plugin-syntax-import-assertions@7.28.6': + resolution: {integrity: sha512-pSJUpFHdx9z5nqTSirOCMtYVP2wFgoWhP0p3g8ONK/4IHhLIBd0B9NYqAvIUAhq+OkhO4VM1tENCt0cjlsNShw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-syntax-import-attributes@7.27.1': - resolution: {integrity: sha512-oFT0FrKHgF53f4vOsZGi2Hh3I35PfSmVs4IBFLFj4dnafP+hIWDLg3VyKmUHfLoLHlyxY4C7DGtmHuJgn+IGww==} + '@babel/plugin-syntax-import-attributes@7.28.6': + resolution: {integrity: sha512-jiLC0ma9XkQT3TKJ9uYvlakm66Pamywo+qwL+oL8HJOvc6TWdZXVfhqJr8CCzbSGUAbDOzlGHJC1U+vRfLQDvw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-syntax-jsx@7.27.1': - resolution: {integrity: sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w==} + '@babel/plugin-syntax-jsx@7.28.6': + resolution: {integrity: sha512-wgEmr06G6sIpqr8YDwA2dSRTE3bJ+V0IfpzfSY3Lfgd7YWOaAdlykvJi13ZKBt8cZHfgH1IXN+CL656W3uUa4w==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-syntax-typescript@7.27.1': - resolution: {integrity: sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ==} + '@babel/plugin-syntax-typescript@7.28.6': + resolution: {integrity: sha512-+nDNmQye7nlnuuHDboPbGm00Vqg3oO8niRRL27/4LYHUsHYh0zJ1xWOz0uRwNFmM1Avzk8wZbc6rdiYhomzv/A==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1337,14 +1337,14 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-async-generator-functions@7.28.0': - resolution: {integrity: sha512-BEOdvX4+M765icNPZeidyADIvQ1m1gmunXufXxvRESy/jNNyfovIqUyE7MVgGBjWktCoJlzvFA1To2O4ymIO3Q==} + '@babel/plugin-transform-async-generator-functions@7.29.0': + resolution: {integrity: sha512-va0VdWro4zlBr2JsXC+ofCPB2iG12wPtVGTWFx2WLDOM3nYQZZIGP82qku2eW/JR83sD+k2k+CsNtyEbUqhU6w==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-async-to-generator@7.27.1': - resolution: {integrity: sha512-NREkZsZVJS4xmTr8qzE5y8AfIPqsdQfRuUiLRTEzb7Qii8iFWCyDKaUV2c0rCuh4ljDZ98ALHP/PetiBV2nddA==} + '@babel/plugin-transform-async-to-generator@7.28.6': + resolution: {integrity: sha512-ilTRcmbuXjsMmcZ3HASTe4caH5Tpo93PkTxF9oG2VZsSWsahydmcEHhix9Ik122RcTnZnUzPbmux4wh1swfv7g==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1355,32 +1355,32 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-block-scoping@7.28.5': - resolution: {integrity: sha512-45DmULpySVvmq9Pj3X9B+62Xe+DJGov27QravQJU1LLcapR6/10i+gYVAucGGJpHBp5mYxIMK4nDAT/QDLr47g==} + '@babel/plugin-transform-block-scoping@7.28.6': + resolution: {integrity: sha512-tt/7wOtBmwHPNMPu7ax4pdPz6shjFrmHDghvNC+FG9Qvj7D6mJcoRQIF5dy4njmxR941l6rgtvfSB2zX3VlUIw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-class-properties@7.27.1': - resolution: {integrity: sha512-D0VcalChDMtuRvJIu3U/fwWjf8ZMykz5iZsg77Nuj821vCKI3zCyRLwRdWbsuJ/uRwZhZ002QtCqIkwC/ZkvbA==} + '@babel/plugin-transform-class-properties@7.28.6': + resolution: {integrity: sha512-dY2wS3I2G7D697VHndN91TJr8/AAfXQNt5ynCTI/MpxMsSzHp+52uNivYT5wCPax3whc47DR8Ba7cmlQMg24bw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-class-static-block@7.28.3': - resolution: {integrity: sha512-LtPXlBbRoc4Njl/oh1CeD/3jC+atytbnf/UqLoqTDcEYGUPj022+rvfkbDYieUrSj3CaV4yHDByPE+T2HwfsJg==} + '@babel/plugin-transform-class-static-block@7.28.6': + resolution: {integrity: sha512-rfQ++ghVwTWTqQ7w8qyDxL1XGihjBss4CmTgGRCTAC9RIbhVpyp4fOeZtta0Lbf+dTNIVJer6ych2ibHwkZqsQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.12.0 - '@babel/plugin-transform-classes@7.28.4': - resolution: {integrity: sha512-cFOlhIYPBv/iBoc+KS3M6et2XPtbT2HiCRfBXWtfpc9OAyostldxIf9YAYB6ypURBBbx+Qv6nyrLzASfJe+hBA==} + '@babel/plugin-transform-classes@7.28.6': + resolution: {integrity: sha512-EF5KONAqC5zAqT783iMGuM2ZtmEBy+mJMOKl2BCvPZ2lVrwvXnB6o+OBWCS+CoeCCpVRF2sA2RBKUxvT8tQT5Q==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-computed-properties@7.27.1': - resolution: {integrity: sha512-lj9PGWvMTVksbWiDT2tW68zGS/cyo4AkZ/QTp0sQT0mjPopCmrSkzxeXkznjqBxzDI6TclZhOJbBmbBLjuOZUw==} + '@babel/plugin-transform-computed-properties@7.28.6': + resolution: {integrity: sha512-bcc3k0ijhHbc2lEfpFHgx7eYw9KNXqOerKWfzbxEHUGKnS3sz9C4CNL9OiFN1297bDNfUiSO7DaLzbvHQQQ1BQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1391,8 +1391,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-dotall-regex@7.27.1': - resolution: {integrity: sha512-gEbkDVGRvjj7+T1ivxrfgygpT7GUd4vmODtYpbs0gZATdkX8/iSnOtZSxiZnsgm1YjTgjI6VKBGSJJevkrclzw==} + '@babel/plugin-transform-dotall-regex@7.28.6': + resolution: {integrity: sha512-SljjowuNKB7q5Oayv4FoPzeB74g3QgLt8IVJw9ADvWy3QnUb/01aw8I4AVv8wYnPvQz2GDDZ/g3GhcNyDBI4Bg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1403,8 +1403,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.27.1': - resolution: {integrity: sha512-hkGcueTEzuhB30B3eJCbCYeCaaEQOmQR0AdvzpD4LoN0GXMWzzGSuRrxR2xTnCrvNbVwK9N6/jQ92GSLfiZWoQ==} + '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.29.0': + resolution: {integrity: sha512-zBPcW2lFGxdiD8PUnPwJjag2J9otbcLQzvbiOzDxpYXyCuYX9agOwMPGn1prVH0a4qzhCKu24rlH4c1f7yA8rw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 @@ -1415,14 +1415,14 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-explicit-resource-management@7.28.0': - resolution: {integrity: sha512-K8nhUcn3f6iB+P3gwCv/no7OdzOZQcKchW6N389V6PD8NUWKZHzndOd9sPDVbMoBsbmjMqlB4L9fm+fEFNVlwQ==} + '@babel/plugin-transform-explicit-resource-management@7.28.6': + resolution: {integrity: sha512-Iao5Konzx2b6g7EPqTy40UZbcdXE126tTxVFr/nAIj+WItNxjKSYTEw3RC+A2/ZetmdJsgueL1KhaMCQHkLPIg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-exponentiation-operator@7.28.5': - resolution: {integrity: sha512-D4WIMaFtwa2NizOp+dnoFjRez/ClKiC2BqqImwKd1X28nqBtZEyCYJ2ozQrrzlxAFrcrjxo39S6khe9RNDlGzw==} + '@babel/plugin-transform-exponentiation-operator@7.28.6': + resolution: {integrity: sha512-WitabqiGjV/vJ0aPOLSFfNY1u9U3R7W36B03r5I2KoNix+a3sOhJ3pKFB3R5It9/UiK78NiO0KE9P21cMhlPkw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1445,8 +1445,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-json-strings@7.27.1': - resolution: {integrity: sha512-6WVLVJiTjqcQauBhn1LkICsR2H+zm62I3h9faTDKt1qP4jn2o72tSvqMwtGFKGTpojce0gJs+76eZ2uCHRZh0Q==} + '@babel/plugin-transform-json-strings@7.28.6': + resolution: {integrity: sha512-Nr+hEN+0geQkzhbdgQVPoqr47lZbm+5fCUmO70722xJZd0Mvb59+33QLImGj6F+DkK3xgDi1YVysP8whD6FQAw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1457,8 +1457,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-logical-assignment-operators@7.28.5': - resolution: {integrity: sha512-axUuqnUTBuXyHGcJEVVh9pORaN6wC5bYfE7FGzPiaWa3syib9m7g+/IT/4VgCOe2Upef43PHzeAvcrVek6QuuA==} + '@babel/plugin-transform-logical-assignment-operators@7.28.6': + resolution: {integrity: sha512-+anKKair6gpi8VsM/95kmomGNMD0eLz1NQ8+Pfw5sAwWH9fGYXT50E55ZpV0pHUHWf6IUTWPM+f/7AAff+wr9A==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1475,14 +1475,14 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-modules-commonjs@7.27.1': - resolution: {integrity: sha512-OJguuwlTYlN0gBZFRPqwOGNWssZjfIUdS7HMYtN8c1KmwpwHFBwTeFZrg9XZa+DFTitWOW5iTAG7tyCUPsCCyw==} + '@babel/plugin-transform-modules-commonjs@7.28.6': + resolution: {integrity: sha512-jppVbf8IV9iWWwWTQIxJMAJCWBuuKx71475wHwYytrRGQ2CWiDvYlADQno3tcYpS/T2UUWFQp3nVtYfK/YBQrA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-modules-systemjs@7.28.5': - resolution: {integrity: sha512-vn5Jma98LCOeBy/KpeQhXcV2WZgaRUtjwQmjoBuLNlOmkg0fB5pdvYVeWRYI69wWKwK2cD1QbMiUQnoujWvrew==} + '@babel/plugin-transform-modules-systemjs@7.29.4': + resolution: {integrity: sha512-N7QmZ0xRZfjHOfZeQLJjwgX2zS9pdGHSVl/cjSGlo4dXMqvurfxXDMKY4RqEKzPozV78VMcd0lxyG13mlbKc4w==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1493,8 +1493,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-named-capturing-groups-regex@7.27.1': - resolution: {integrity: sha512-SstR5JYy8ddZvD6MhV0tM/j16Qds4mIpJTOd1Yu9J9pJjH93bxHECF7pgtc28XvkzTD6Pxcm/0Z73Hvk7kb3Ng==} + '@babel/plugin-transform-named-capturing-groups-regex@7.29.0': + resolution: {integrity: sha512-1CZQA5KNAD6ZYQLPw7oi5ewtDNxH/2vuCh+6SmvgDfhumForvs8a1o9n0UrEoBD8HU4djO2yWngTQlXl1NDVEQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 @@ -1505,20 +1505,20 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-nullish-coalescing-operator@7.27.1': - resolution: {integrity: sha512-aGZh6xMo6q9vq1JGcw58lZ1Z0+i0xB2x0XaauNIUXd6O1xXc3RwoWEBlsTQrY4KQ9Jf0s5rgD6SiNkaUdJegTA==} + '@babel/plugin-transform-nullish-coalescing-operator@7.28.6': + resolution: {integrity: sha512-3wKbRgmzYbw24mDJXT7N+ADXw8BC/imU9yo9c9X9NKaLF1fW+e5H1U5QjMUBe4Qo4Ox/o++IyUkl1sVCLgevKg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-numeric-separator@7.27.1': - resolution: {integrity: sha512-fdPKAcujuvEChxDBJ5c+0BTaS6revLV7CJL08e4m3de8qJfNIuCc2nc7XJYOjBoTMJeqSmwXJ0ypE14RCjLwaw==} + '@babel/plugin-transform-numeric-separator@7.28.6': + resolution: {integrity: sha512-SJR8hPynj8outz+SlStQSwvziMN4+Bq99it4tMIf5/Caq+3iOc0JtKyse8puvyXkk3eFRIA5ID/XfunGgO5i6w==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-object-rest-spread@7.28.4': - resolution: {integrity: sha512-373KA2HQzKhQCYiRVIRr+3MjpCObqzDlyrM6u4I201wL8Mp2wHf7uB8GhDwis03k2ti8Zr65Zyyqs1xOxUF/Ew==} + '@babel/plugin-transform-object-rest-spread@7.28.6': + resolution: {integrity: sha512-5rh+JR4JBC4pGkXLAcYdLHZjXudVxWMXbB6u6+E9lRL5TrGVbHt1TjxGbZ8CkmYw9zjkB7jutzOROArsqtncEA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1529,14 +1529,14 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-optional-catch-binding@7.27.1': - resolution: {integrity: sha512-txEAEKzYrHEX4xSZN4kJ+OfKXFVSWKB2ZxM9dpcE3wT7smwkNmXo5ORRlVzMVdJbD+Q8ILTgSD7959uj+3Dm3Q==} + '@babel/plugin-transform-optional-catch-binding@7.28.6': + resolution: {integrity: sha512-R8ja/Pyrv0OGAvAXQhSTmWyPJPml+0TMqXlO5w+AsMEiwb2fg3WkOvob7UxFSL3OIttFSGSRFKQsOhJ/X6HQdQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-optional-chaining@7.28.5': - resolution: {integrity: sha512-N6fut9IZlPnjPwgiQkXNhb+cT8wQKFlJNqcZkWlcTqkcqx6/kU4ynGmLFoa4LViBSirn05YAwk+sQBbPfxtYzQ==} + '@babel/plugin-transform-optional-chaining@7.28.6': + resolution: {integrity: sha512-A4zobikRGJTsX9uqVFdafzGkqD30t26ck2LmOzAuLL8b2x6k3TIqRiT2xVvA9fNmFeTX484VpsdgmKNA0bS23w==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1547,14 +1547,14 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-private-methods@7.27.1': - resolution: {integrity: sha512-10FVt+X55AjRAYI9BrdISN9/AQWHqldOeZDUoLyif1Kn05a56xVBXb8ZouL8pZ9jem8QpXaOt8TS7RHUIS+GPA==} + '@babel/plugin-transform-private-methods@7.28.6': + resolution: {integrity: sha512-piiuapX9CRv7+0st8lmuUlRSmX6mBcVeNQ1b4AYzJxfCMuBfB0vBXDiGSmm03pKJw1v6cZ8KSeM+oUnM6yAExg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-private-property-in-object@7.27.1': - resolution: {integrity: sha512-5J+IhqTi1XPa0DXF83jYOaARrX+41gOewWbkPyjMNRDqgOCqdffGh8L3f/Ek5utaEBZExjSAzcyjmV9SSAWObQ==} + '@babel/plugin-transform-private-property-in-object@7.28.6': + resolution: {integrity: sha512-b97jvNSOb5+ehyQmBpmhOCiUC5oVK4PMnpRvO7+ymFBoqYjeDHIU9jnrNUuwHOiL9RpGDoKBpSViarV+BU+eVA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1583,8 +1583,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-react-jsx@7.27.1': - resolution: {integrity: sha512-2KH4LWGSrJIkVf5tSiBFYuXDAoWRq2MMwgivCf+93dd0GQi8RXLjKA/0EvRnVV5G0hrHczsquXuD01L8s6dmBw==} + '@babel/plugin-transform-react-jsx@7.28.6': + resolution: {integrity: sha512-61bxqhiRfAACulXSLd/GxqmAedUSrRZIu/cbaT18T1CetkTmtDN15it7i80ru4DVqRK1WMxQhXs+Lf9kajm5Ow==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1595,14 +1595,14 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-regenerator@7.28.4': - resolution: {integrity: sha512-+ZEdQlBoRg9m2NnzvEeLgtvBMO4tkFBw5SQIUgLICgTrumLoU7lr+Oghi6km2PFj+dbUt2u1oby2w3BDO9YQnA==} + '@babel/plugin-transform-regenerator@7.29.0': + resolution: {integrity: sha512-FijqlqMA7DmRdg/aINBSs04y8XNTYw/lr1gJ2WsmBnnaNw1iS43EPkJW+zK7z65auG3AWRFXWj+NcTQwYptUog==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-regexp-modifiers@7.27.1': - resolution: {integrity: sha512-TtEciroaiODtXvLZv4rmfMhkCv8jx3wgKpL68PuiPh2M4fvz5jhsA7697N1gMvkvr/JTF13DrFYyEbY9U7cVPA==} + '@babel/plugin-transform-regexp-modifiers@7.28.6': + resolution: {integrity: sha512-QGWAepm9qxpaIs7UM9FvUSnCGlb8Ua1RhyM4/veAxLwt3gMat/LSGrZixyuj4I6+Kn9iwvqCyPTtbdxanYoWYg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 @@ -1613,8 +1613,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-runtime@7.28.5': - resolution: {integrity: sha512-20NUVgOrinudkIBzQ2bNxP08YpKprUkRTiRSd2/Z5GOdPImJGkoN4Z7IQe1T5AdyKI1i5L6RBmluqdSzvaq9/w==} + '@babel/plugin-transform-runtime@7.29.0': + resolution: {integrity: sha512-jlaRT5dJtMaMCV6fAuLbsQMSwz/QkvaHOHOSXRitGGwSpR1blCY4KUKoyP2tYO8vJcqYe8cEj96cqSztv3uF9w==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1625,8 +1625,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-spread@7.27.1': - resolution: {integrity: sha512-kpb3HUqaILBJcRFVhFUs6Trdd4mkrzcGXss+6/mxUd273PfbWqSDHRzMT2234gIg2QYfAjvXLSquP1xECSg09Q==} + '@babel/plugin-transform-spread@7.28.6': + resolution: {integrity: sha512-9U4QObUC0FtJl05AsUcodau/RWDytrU6uKgkxu09mLR9HLDAtUMoPuuskm5huQsoktmsYpI+bGmq+iapDcriKA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1649,8 +1649,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-typescript@7.28.5': - resolution: {integrity: sha512-x2Qa+v/CuEoX7Dr31iAfr0IhInrVOWZU/2vJMJ00FOR/2nM0BcBEclpaf9sWCDc+v5e9dMrhSH8/atq/kX7+bA==} + '@babel/plugin-transform-typescript@7.28.6': + resolution: {integrity: sha512-0YWL2RFxOqEm9Efk5PvreamxPME8OyY0wM5wh5lHjF+VtVhdneCWGzZeSqzOfiobVqQaNCd2z0tQvnI9DaPWPw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1661,8 +1661,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-unicode-property-regex@7.27.1': - resolution: {integrity: sha512-uW20S39PnaTImxp39O5qFlHLS9LJEmANjMG7SxIhap8rCHqu0Ik+tLEPX5DKmHn6CsWQ7j3lix2tFOa5YtL12Q==} + '@babel/plugin-transform-unicode-property-regex@7.28.6': + resolution: {integrity: sha512-4Wlbdl/sIZjzi/8St0evF0gEZrgOswVO6aOzqxh1kDZOl9WmLrHq2HtGhnOJZmHZYKP8WZ1MDLCt5DAWwRo57A==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1673,14 +1673,14 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-unicode-sets-regex@7.27.1': - resolution: {integrity: sha512-EtkOujbc4cgvb0mlpQefi4NTPBzhSIevblFevACNLUspmrALgmEBdL/XfnyyITfd8fKBZrZys92zOWcik7j9Tw==} + '@babel/plugin-transform-unicode-sets-regex@7.28.6': + resolution: {integrity: sha512-/wHc/paTUmsDYN7SZkpWxogTOBNnlx7nBQYfy6JJlCT7G3mVhltk3e++N7zV0XfgGsrqBxd4rJQt9H16I21Y1Q==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/preset-env@7.28.5': - resolution: {integrity: sha512-S36mOoi1Sb6Fz98fBfE+UZSpYw5mJm0NUHtIKrOuNcqeFauy1J6dIvXm2KRVKobOSaGq4t/hBXdN4HGU3wL9Wg==} + '@babel/preset-env@7.29.5': + resolution: {integrity: sha512-/69t2aEzGKHD76DyLbHysF/QH2LJOB8iFnYO37unDTKBTubzcMRv0f3H5EiN1Q6ajOd/eB7dAInF0qdFVS06kA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1706,6 +1706,10 @@ packages: resolution: {integrity: sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==} engines: {node: '>=6.9.0'} + '@babel/runtime@7.29.7': + resolution: {integrity: sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==} + engines: {node: '>=6.9.0'} + '@babel/template@7.28.6': resolution: {integrity: sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==} engines: {node: '>=6.9.0'} @@ -1732,26 +1736,14 @@ packages: '@borewit/text-codec@0.2.2': resolution: {integrity: sha512-DDaRehssg1aNrH4+2hnj1B7vnUGEjU6OIlyRdkMd0aUdIUvKXrJfXsy8LVtXAy7DRvYVluWbMspsRhz2lcW0mQ==} - '@braintree/sanitize-url@7.1.1': - resolution: {integrity: sha512-i1L7noDNxtFyL5DmZafWy1wRVhGehQmzZaz1HiN5e7iylJMSZR7ekOV7NsIqa5qBldlLrsKv4HbgFUVlQrz8Mw==} + '@braintree/sanitize-url@7.1.2': + resolution: {integrity: sha512-jigsZK+sMF/cuiB7sERuo9V7N9jx+dhmHHnQyDSVdpZwVutaBu7WvNYqMDLSgFgfB30n452TP3vjDAvFC973mA==} - '@chevrotain/cst-dts-gen@11.0.3': - resolution: {integrity: sha512-BvIKpRLeS/8UbfxXxgC33xOumsacaeCKAjAeLyOn7Pcp95HiRbrpl14S+9vaZLolnbssPIUuiUd8IvgkRyt6NQ==} + '@chevrotain/types@11.1.2': + resolution: {integrity: sha512-U+HFai5+zmJCkK86QsaJtoITlboZHBqrVketcO2ROv865xfCMSFpELQoz1GkX5GzME8pTa+3kbKrZHQtI0gdbw==} - '@chevrotain/gast@11.0.3': - resolution: {integrity: sha512-+qNfcoNk70PyS/uxmj3li5NiECO+2YKZZQMbmjTqRI3Qchu8Hig/Q9vgkHpI3alNjr7M+a2St5pw5w5F6NL5/Q==} - - '@chevrotain/regexp-to-ast@11.0.3': - resolution: {integrity: sha512-1fMHaBZxLFvWI067AVbGJav1eRY7N8DDvYCTwGBiE/ytKBgP8azTdgyrKyWZ9Mfh09eHWb5PgTSO8wi7U824RA==} - - '@chevrotain/types@11.0.3': - resolution: {integrity: sha512-gsiM3G8b58kZC2HaWR50gu6Y1440cHiJ+i3JUvcp/35JchYejb2+5MVeJK0iKThYpAa/P2PYFV4hoi44HD+aHQ==} - - '@chevrotain/utils@11.0.3': - resolution: {integrity: sha512-YslZMgtJUyuMbZ+aKvfF3x1f5liK4mWNxghFRv7jqRR9C3R3fAOGTTKvxXDa2Y1s9zSbcpuO0cAxDYsc9SrXoQ==} - - '@codemirror/autocomplete@6.20.1': - resolution: {integrity: sha512-1cvg3Vz1dSSToCNlJfRA2WSI4ht3K+WplO0UMOgmUYPivCyy2oueZY6Lx7M9wThm7SDUBViRmuT+OG/i8+ON9A==} + '@codemirror/autocomplete@6.20.2': + resolution: {integrity: sha512-G5FPkgIiLjOgZMjqVjvuKQ1rGPtHogLldJr33eFJdVLtmwY+giGrlv/ewljLz6b9BSQLkjxuwBc6g6omDM+YxQ==} '@codemirror/commands@6.10.3': resolution: {integrity: sha512-JFRiqhKu+bvSkDLI+rUhJwSxQxYb759W5GBezE8Uc8mHLqC9aV/9aTC7yJSqCtB3F00pylrLCwnyS91Ap5ej4Q==} @@ -1762,8 +1754,8 @@ packages: '@codemirror/language@6.12.3': resolution: {integrity: sha512-QwCZW6Tt1siP37Jet9Tb02Zs81TQt6qQrZR2H+eGMcFsL1zMrk2/b9CLC7/9ieP1fjIUMgviLWMmgiHoJrj+ZA==} - '@codemirror/lint@6.9.5': - resolution: {integrity: sha512-GElsbU9G7QT9xXhpUg1zWGmftA/7jamh+7+ydKRuT0ORpWS3wOSP0yT1FOlIZa7mIJjpVPipErsyvVqB9cfTFA==} + '@codemirror/lint@6.9.6': + resolution: {integrity: sha512-6Kp7r6XfCi/D/5sdXieMfg9pJU1bUEx96WITuLU6ESaKizCz0QHFMjY/TaFSbigDdEAIgi93itLBIUETP4oK+A==} '@codemirror/search@6.7.0': resolution: {integrity: sha512-ZvGm99wc/s2cITtMT15LFdn8aH/aS+V+DqyGq/N5ZlV5vWtH+nILvC2nw0zX7ByNoHHDZ2IxxdW38O0tc5nVHg==} @@ -1771,8 +1763,8 @@ packages: '@codemirror/state@6.6.0': resolution: {integrity: sha512-4nbvra5R5EtiCzr9BTHiTLc+MLXK2QGiAVYMyi8PkQd3SR+6ixar/Q/01Fa21TBIDOZXgeWV4WppsQolSreAPQ==} - '@codemirror/view@6.41.1': - resolution: {integrity: sha512-ToDnWKbBnke+ZLrP6vgTTDScGi5H37YYuZGniQaBzxMVdtCxMrslsmtnOvbPZk4RX9bvkQqnWR/WS/35tJA0qg==} + '@codemirror/view@6.43.0': + resolution: {integrity: sha512-V7ZCLQO3Jus9hzh2jVCCPW3mO4IBMr43O37PqSUYautJSnnJF41YlgLw21x0fLJTYvJ+Vkm6Gp+qKGH9pltgXA==} '@colors/colors@1.5.0': resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==} @@ -1970,8 +1962,8 @@ packages: peerDependencies: postcss: ^8.4 - '@csstools/postcss-normalize-display-values@4.0.0': - resolution: {integrity: sha512-HlEoG0IDRoHXzXnkV4in47dzsxdsjdz6+j7MLjaACABX2NfvjFS6XVAnpaDyGesz9gK2SC7MbNwdCHusObKJ9Q==} + '@csstools/postcss-normalize-display-values@4.0.1': + resolution: {integrity: sha512-TQUGBuRvxdc7TgNSTevYqrL8oItxiwPDixk20qCB5me/W8uF7BPbhRrAvFuhEoywQp/woRsUZ6SJ+sU5idZAIA==} engines: {node: '>=18'} peerDependencies: postcss: ^8.4 @@ -1994,6 +1986,12 @@ packages: peerDependencies: postcss: ^8.4 + '@csstools/postcss-property-rule-prelude-list@1.0.0': + resolution: {integrity: sha512-IxuQjUXq19fobgmSSvUDO7fVwijDJaZMvWQugxfEUxmjBeDCVaDuMpsZ31MsTm5xbnhA+ElDi0+rQ7sQQGisFA==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + '@csstools/postcss-random-function@2.0.1': resolution: {integrity: sha512-q+FQaNiRBhnoSNo+GzqGOIBKoHQ43lYz0ICrV+UudfWnEF6ksS6DsBIJSISKQT2Bvu3g4k6r7t0zYrk5pDlo8w==} engines: {node: '>=18'} @@ -2024,6 +2022,12 @@ packages: peerDependencies: postcss: ^8.4 + '@csstools/postcss-syntax-descriptor-syntax-production@1.0.1': + resolution: {integrity: sha512-GneqQWefjM//f4hJ/Kbox0C6f2T7+pi4/fqTqOFGTL3EjnvOReTqO1qUQ30CaUjkwjYq9qZ41hzarrAxCc4gow==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + '@csstools/postcss-system-ui-font-family@1.0.0': resolution: {integrity: sha512-s3xdBvfWYfoPSBsikDXbuorcMG1nN1M6GdU0qBsGfcmNR0A/qhloQZpTxjA3Xsyrk1VJvwb2pOfiOT3at/DuIQ==} engines: {node: '>=18'} @@ -2070,8 +2074,8 @@ packages: resolution: {integrity: sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==} engines: {node: '>=10.0.0'} - '@docsearch/core@4.3.1': - resolution: {integrity: sha512-ktVbkePE+2h9RwqCUMbWXOoebFyDOxHqImAqfs+lC8yOU+XwEW4jgvHGJK079deTeHtdhUNj0PXHSnhJINvHzQ==} + '@docsearch/core@4.6.3': + resolution: {integrity: sha512-rUOujwIpxJRgD7+kicVsI3D5sqBvdiRTquzWBpTEXZs8ZXfGbfzpus5HqumaNYTppN2HvH8E2yNuRwYdHJeOlA==} peerDependencies: '@types/react': '>= 16.8.0 < 20.0.0' react: '>= 16.8.0 < 20.0.0' @@ -2084,11 +2088,11 @@ packages: react-dom: optional: true - '@docsearch/css@4.3.2': - resolution: {integrity: sha512-K3Yhay9MgkBjJJ0WEL5MxnACModX9xuNt3UlQQkDEDZJZ0+aeWKtOkxHNndMRkMBnHdYvQjxkm6mdlneOtU1IQ==} + '@docsearch/css@4.6.3': + resolution: {integrity: sha512-nlOwcXcsNAptQl4vlL4MA78qNJKO0Qlds5GuBjCoePgkebTXLSf8Qt1oyZ3YBshYupKXG9VRGEsk1zr23d+bzQ==} - '@docsearch/react@4.3.2': - resolution: {integrity: sha512-74SFD6WluwvgsOPqifYOviEEVwDxslxfhakTlra+JviaNcs7KK/rjsPj89kVEoQc9FUxRkAofaJnHIR7pb4TSQ==} + '@docsearch/react@4.6.3': + resolution: {integrity: sha512-Bg2wdDsoQVlNCcEKuEJAU04tvHCqgx8rIu+uIoM4pRtcx3TBKJuXutJik3LTA8LRc9YEyHkrYUrmcC0D7BYf+g==} peerDependencies: '@types/react': '>= 16.8.0 < 20.0.0' react: '>= 16.8.0 < 20.0.0' @@ -2104,12 +2108,12 @@ packages: search-insights: optional: true - '@docusaurus/babel@3.10.0': - resolution: {integrity: sha512-mqCJhCZNZUDg0zgDEaPTM4DnRsisa24HdqTy/qn/MQlbwhTb4WVaZg6ZyX6yIVKqTz8fS1hBMgM+98z+BeJJDg==} + '@docusaurus/babel@3.10.1': + resolution: {integrity: sha512-DZzFO1K3v/GoEt1fx1DiYHF4en+PuhtQf1AkQJa5zu3CoeKSpr5cpQRUlz3jr0m44wyzmSXu9bVpfir+N4+8bg==} engines: {node: '>=20.0'} - '@docusaurus/bundler@3.10.0': - resolution: {integrity: sha512-iONUGZGgp+lAkw/cJZH6irONcF4p8+278IsdRlq8lYhxGjkoNUs0w7F4gVXBYSNChq5KG5/JleTSsdJySShxow==} + '@docusaurus/bundler@3.10.1': + resolution: {integrity: sha512-HIqQPvbqnnQRe4NsBd1774KRarjXqS6wHsWELtyuSs1gCfvixJO2jUGH/OEBtr1Gvzpw+ze5CjGMvSJ8UE1KUw==} engines: {node: '>=20.0'} peerDependencies: '@docusaurus/faster': '*' @@ -2117,8 +2121,8 @@ packages: '@docusaurus/faster': optional: true - '@docusaurus/core@3.10.0': - resolution: {integrity: sha512-mgLdQsO8xppnQZc3LPi+Mf+PkPeyxJeIx11AXAq/14fsaMefInQiMEZUUmrc7J+956G/f7MwE7tn8KZgi3iRcA==} + '@docusaurus/core@3.10.1': + resolution: {integrity: sha512-3pf2fXXw0eVk8WnC3T4LIigRDupcpvngpKo9Vy7mYyBhuddc0klDUuZAIfzMoK6z05pdlk6EFC/vBSX43+1O5w==} engines: {node: '>=20.0'} hasBin: true peerDependencies: @@ -2130,97 +2134,97 @@ packages: '@docusaurus/faster': optional: true - '@docusaurus/cssnano-preset@3.10.0': - resolution: {integrity: sha512-qzSshTO1DB3TYW+dPUal5KHM7XPc5YQfzF3Kdb2NDACJUyGbNcFtw3tGkCJlYwhNCRKbZcmwraKUS1i5dcHdGg==} + '@docusaurus/cssnano-preset@3.10.1': + resolution: {integrity: sha512-eNfHGcTKCSq6xmcavAkX3RRclHaE2xRCMParlDXLdXVP01/a2e/jKXMj/0ULnLFQSNwwuI62L0Ge8J+nZsR7UQ==} engines: {node: '>=20.0'} - '@docusaurus/logger@3.10.0': - resolution: {integrity: sha512-9jrZzFuBH1LDRlZ7cznAhCLmAZ3HSDqgwdrSSZdGHq9SPUOQgXXu8mnxe2ZRB9NS1PCpMTIOVUqDtZPIhMafZg==} + '@docusaurus/logger@3.10.1': + resolution: {integrity: sha512-oPjNFnfJsRCkePVjkGrxWGq4MvJKRQT0r9jOP0eRBTZ7Wr9FAbzdP/Gjs0I2Ss6YRkPoEgygKG112OkE6skvJw==} engines: {node: '>=20.0'} - '@docusaurus/mdx-loader@3.10.0': - resolution: {integrity: sha512-mQQV97080AH4PYNs087l202NMDqRopZA4mg5W76ZZyTFrmWhJ3mHg+8A+drJVENxw5/Q+wHMHLgsx+9z1nEs0A==} + '@docusaurus/mdx-loader@3.10.1': + resolution: {integrity: sha512-GRmeb/wQ+iXRrFwcHBfgQhrJxGElgCsoTWZYDhccjsZVne1p8MK/EpQVIloXttz76TCe78kKD5AEG9n1xc1oxQ==} engines: {node: '>=20.0'} peerDependencies: react: ^18.0.0 || ^19.0.0 react-dom: ^18.0.0 || ^19.0.0 - '@docusaurus/module-type-aliases@3.10.0': - resolution: {integrity: sha512-/1O0Zg8w3DFrYX/I6Fbss7OJrtZw1QoyjDhegiFNHVi9A9Y0gQ3jUAytVxF6ywpAWpLyLxch8nN8H/V3XfzdJQ==} + '@docusaurus/module-type-aliases@3.10.1': + resolution: {integrity: sha512-YoOZKUdGlp8xSYhuAkGdSo5Ydkbq4V4eK3sD8v0a2hloxCWdQbNBhkc+Ko9QyjpESc0BYcIGM5iHVAy5hdFV6w==} peerDependencies: react: '*' react-dom: '*' - '@docusaurus/plugin-content-blog@3.10.0': - resolution: {integrity: sha512-RuTz68DhB7CL96QO5UsFbciD7GPYq6QV+YMfF9V0+N4ZgLhJIBgpVAr8GobrKF6NRe5cyWWETU5z5T834piG9g==} + '@docusaurus/plugin-content-blog@3.10.1': + resolution: {integrity: sha512-mmkgE6Q2+K74tnkou7tXlpDLvoCU/qkSa2GSQ3XUiHWvcebCoDQzS670RR3tO8PmaWlIyWWISYWzZLuMfxunRA==} engines: {node: '>=20.0'} peerDependencies: '@docusaurus/plugin-content-docs': '*' react: ^18.0.0 || ^19.0.0 react-dom: ^18.0.0 || ^19.0.0 - '@docusaurus/plugin-content-docs@3.10.0': - resolution: {integrity: sha512-9BjHhf15ct8Z7TThTC0xRndKDVvMKmVsAGAN7W9FpNRzfMdScOGcXtLmcCWtJGvAezjOJIm6CxOYCy3Io5+RnQ==} + '@docusaurus/plugin-content-docs@3.10.1': + resolution: {integrity: sha512-2jRVrtzjf8LClGTHQlwlwuD3wQXRx3WEoF7XUarJ8Ou+0onV+SLtejsyfY9JLpfUh9hPhXM4pbBGkyAY4Bi3HQ==} engines: {node: '>=20.0'} peerDependencies: react: ^18.0.0 || ^19.0.0 react-dom: ^18.0.0 || ^19.0.0 - '@docusaurus/plugin-content-pages@3.10.0': - resolution: {integrity: sha512-5amX8kEJI+nIGtuLVjYk59Y5utEJ3CHETFOPEE4cooIRLA4xM4iBsA6zFgu4ljcopeYwvBzFEWf5g2I6Yb9SkA==} + '@docusaurus/plugin-content-pages@3.10.1': + resolution: {integrity: sha512-huJpaRPMl42nsFwuCXvV8bVDj2MazuwRJIUylI/RSlmZeJssVoZXeCjVf1y+1Drtpa9SKcdGn8yoJ76IRJijtw==} engines: {node: '>=20.0'} peerDependencies: react: ^18.0.0 || ^19.0.0 react-dom: ^18.0.0 || ^19.0.0 - '@docusaurus/plugin-css-cascade-layers@3.10.0': - resolution: {integrity: sha512-6q1vtt5FJcg5osgkHeM1euErECNqEZ5Z1j69yiNx2luEBIso+nxCkS9nqj8w+MK5X7rvKEToGhFfOFWncs51pQ==} + '@docusaurus/plugin-css-cascade-layers@3.10.1': + resolution: {integrity: sha512-r//fn+MNHkE1wCof8T29VAQezt1enGCpsFxoziBbvLgBM4JfXN2P3rxrBaavHmvLvm7lYkpJeitcDthwnmWCTw==} engines: {node: '>=20.0'} - '@docusaurus/plugin-debug@3.10.0': - resolution: {integrity: sha512-XcljKN+G+nmmK69uQA1d9BlYU3ZftG3T3zpK8/7Hf/wrOlV7TA4Ampdrdwkg0jElKdKAoSnPhCO0/U3bQGsVQQ==} + '@docusaurus/plugin-debug@3.10.1': + resolution: {integrity: sha512-9KqOpKNfAyqGZykRb9LhIT/vyRF6sm/ykhjj/39JvaJahDS+jZJE0Z1Wfz9q3DUNDTMNN0Q7u/kk4rKKU+IJuA==} engines: {node: '>=20.0'} peerDependencies: react: ^18.0.0 || ^19.0.0 react-dom: ^18.0.0 || ^19.0.0 - '@docusaurus/plugin-google-analytics@3.10.0': - resolution: {integrity: sha512-hTEoodatpBZnUat5nFExbuTGA1lhWGy7vZGuTew5Q3QDtGKFpSJLYmZJhdTjvCFwv1+qQ67hgAVlKdJOB8TXow==} + '@docusaurus/plugin-google-analytics@3.10.1': + resolution: {integrity: sha512-8o0P1KtmgdYQHH+oInitPpRWI0Of5XednAX4+DMhQNSmGSRNrsEEHg1ebv35m9AgRClfAytCJ5jA9KvcASTyuA==} engines: {node: '>=20.0'} peerDependencies: react: ^18.0.0 || ^19.0.0 react-dom: ^18.0.0 || ^19.0.0 - '@docusaurus/plugin-google-gtag@3.10.0': - resolution: {integrity: sha512-iB/Zzjv/eelJRbdULZqzWCbgMgJ7ht4ONVjXtN3+BI/muil6S87gQ1OJyPwlXD+ELdKkitC7bWv5eJdYOZLhrQ==} + '@docusaurus/plugin-google-gtag@3.10.1': + resolution: {integrity: sha512-pu3xIUo5o/zCMLfUY9BO5KOwSH0zIsAGyFRPvXHayFSA5XIhCU/SFuB0g0ZNjFn9niZLCaNvoeAuOGFJZq0fdw==} engines: {node: '>=20.0'} peerDependencies: react: ^18.0.0 || ^19.0.0 react-dom: ^18.0.0 || ^19.0.0 - '@docusaurus/plugin-google-tag-manager@3.10.0': - resolution: {integrity: sha512-FEjZxqKgLHa+Wez/EgKxRwvArNCWIScfyEQD95rot7jkxp6nonjI5XIbGfO/iYhM5Qinwe8aIEQHP2KZtpqVuA==} + '@docusaurus/plugin-google-tag-manager@3.10.1': + resolution: {integrity: sha512-f6fyGHiCm7kJHBtAisGQS5oNBnpnMTYQZxDXeVrnw/3zWU+LMA22pr6UHGYkBKDbN+qPC5QHG3NuOfzQLq3+Lw==} engines: {node: '>=20.0'} peerDependencies: react: ^18.0.0 || ^19.0.0 react-dom: ^18.0.0 || ^19.0.0 - '@docusaurus/plugin-sitemap@3.10.0': - resolution: {integrity: sha512-DVTSLjB97hIjmayGnGcBfognCeI7ZuUKgEnU7Oz81JYqXtVg94mVTthDjq3QHTylYNeCUbkaW8VF0FDLcc8pPw==} + '@docusaurus/plugin-sitemap@3.10.1': + resolution: {integrity: sha512-C26MbmmqgdjkDq1htaZ3aD7LzEDKFWXfpyQpt0EOUThuq5nV77zDaedV20yHcVo9p+3ey9aZ4pbHA0D3QcZTzg==} engines: {node: '>=20.0'} peerDependencies: react: ^18.0.0 || ^19.0.0 react-dom: ^18.0.0 || ^19.0.0 - '@docusaurus/plugin-svgr@3.10.0': - resolution: {integrity: sha512-lNljBESaETZqVBMPqkrGchr+UPT1eZzEPLmJhz8I76BxbjqgsUnRvrq6lQJ9sYjgmgX52KB7kkgczqd2yzoswQ==} + '@docusaurus/plugin-svgr@3.10.1': + resolution: {integrity: sha512-6SFxsmjWFkVLDmBUvFK6i72QjUwqyQFe4Ovz+SUJophJjOyVG3ZZG5IQpBC/kX/Gfv1yWeU9nWauH6F6Q7QX/Q==} engines: {node: '>=20.0'} peerDependencies: react: ^18.0.0 || ^19.0.0 react-dom: ^18.0.0 || ^19.0.0 - '@docusaurus/preset-classic@3.10.0': - resolution: {integrity: sha512-kw/Ye02Hc6xP1OdTswy8yxQEHg0fdPpyWAQRxr5b2x3h7LlG2Zgbb5BDFROnXDDMpUxB7YejlocJIE5HIEfpNA==} + '@docusaurus/preset-classic@3.10.1': + resolution: {integrity: sha512-YO/FL8v1zmbxoTso6mjMz/RDjhaTJxb1UpFFTDdY5847LLDCeyYiYlrhyTbgN1RIN3xnkLKZ9Lj1x8hUzI4JOg==} engines: {node: '>=20.0'} peerDependencies: react: ^18.0.0 || ^19.0.0 @@ -2231,23 +2235,23 @@ packages: peerDependencies: react: '*' - '@docusaurus/theme-classic@3.10.0': - resolution: {integrity: sha512-9msCAsRdN+UG+RwPwCFb0uKy4tGoPh5YfBozXeGUtIeAgsMdn6f3G/oY861luZ3t8S2ET8S9Y/1GnpJAGWytww==} + '@docusaurus/theme-classic@3.10.1': + resolution: {integrity: sha512-VU1RK0qb2pab0si4r7HFK37cYco8VzqLj3u1PspVipSr/z/GPVKHO4/HXbnePqHoWDk8urjyGSeatH0NIMBM1A==} engines: {node: '>=20.0'} peerDependencies: react: ^18.0.0 || ^19.0.0 react-dom: ^18.0.0 || ^19.0.0 - '@docusaurus/theme-common@3.10.0': - resolution: {integrity: sha512-Dkp1YXKn16ByCJAdIjbDIOpVb4Z66MsVD694/ilX1vAAHaVEMrVsf/NPd9VgreyFx08rJ9GqV1MtzsbTcU73Kg==} + '@docusaurus/theme-common@3.10.1': + resolution: {integrity: sha512-0YtmIeoNo1fIw65LO8+/1dPgmDV86UmhMkow37gzjytuiCSQm9xob6PJy0L4kuQEMTLfUOGvkXvZr7GPrHquMA==} engines: {node: '>=20.0'} peerDependencies: '@docusaurus/plugin-content-docs': '*' react: ^18.0.0 || ^19.0.0 react-dom: ^18.0.0 || ^19.0.0 - '@docusaurus/theme-mermaid@3.10.0': - resolution: {integrity: sha512-Y2xrlwhIJ80oOZIO3PXL6A7J869splfcMI87E3NKpYsy3zJxOyV+BP1QMtGi59ajKgU868HPuyyn6J+6BZGOBg==} + '@docusaurus/theme-mermaid@3.10.1': + resolution: {integrity: sha512-2gxpmln8Pc4EN1oWzshQEx2HTs67jk14v7MmgqGs8ZU7Nm8oihg+fTouof2u4vN8DtB3Fln4cDJu4UprSX1S3Q==} engines: {node: '>=20.0'} peerDependencies: '@mermaid-js/layout-elk': ^0.1.9 @@ -2257,36 +2261,36 @@ packages: '@mermaid-js/layout-elk': optional: true - '@docusaurus/theme-search-algolia@3.10.0': - resolution: {integrity: sha512-f5FPKI08e3JRG63vR/o4qeuUVHUHzFzM0nnF+AkB67soAZgNsKJRf2qmUZvlQkGwlV+QFkKe4D0ANMh1jToU3g==} + '@docusaurus/theme-search-algolia@3.10.1': + resolution: {integrity: sha512-OTaARARVZj2GvkJQjB+1jOIxntRaXea+G+fMsNqrZBAU1O1vJKDW22R7kECOHW27oJCLFN9HKaZeRrfAUyviug==} engines: {node: '>=20.0'} peerDependencies: react: ^18.0.0 || ^19.0.0 react-dom: ^18.0.0 || ^19.0.0 - '@docusaurus/theme-translations@3.10.0': - resolution: {integrity: sha512-L9IbFLwTc5+XdgH45iQYufLn0SVZd6BUNelDbKIFlH+E4hhjuj/XHWAFMX/w2K59rfy8wak9McOaei7BSUfRPA==} + '@docusaurus/theme-translations@3.10.1': + resolution: {integrity: sha512-cLMyaKivjBVWKMJuWqyFVVgtqe8DPJNPkog0bn8W1MDVAKcPdxRFycBfC1We1RaNp7Rdk513bmtW78RR6OBxBw==} engines: {node: '>=20.0'} - '@docusaurus/tsconfig@3.10.0': - resolution: {integrity: sha512-TXdC3WXuPrdQAexLvjUJfnYf3YKEgEqAs5nK0Q88pRBCW7t7oN4ILvWYb3A5Z1wlSXyXGWW/mCUmLEhdWsjnDQ==} + '@docusaurus/tsconfig@3.10.1': + resolution: {integrity: sha512-rYvB7yqkdqWIpAbDzQljGfM4cDBkLTbhmagZBEcsyj6oPUsz47lmW2pYdN1j+7sGFgltbAmQH62xfbrij4Eh6Q==} - '@docusaurus/types@3.10.0': - resolution: {integrity: sha512-F0dOt3FOoO20rRaFK7whGFQZ3ggyrWEdQc/c8/UiRuzhtg4y1w9FspXH5zpCT07uMnJKBPGh+qNazbNlCQqvSw==} + '@docusaurus/types@3.10.1': + resolution: {integrity: sha512-XYMK8k1szDCFMw2V+Xyen0g7Kee1sP3dtFnl7vkGkZOkeAJ/oPDQPL8iz4HBKOo/cwU8QeV6onVjMqtP+tFzsw==} peerDependencies: react: ^18.0.0 || ^19.0.0 react-dom: ^18.0.0 || ^19.0.0 - '@docusaurus/utils-common@3.10.0': - resolution: {integrity: sha512-JyL7sb9QVDgYvudIS81Dv0lsWm7le0vGZSDwsztxWam1SPBqrnkvBy9UYL/amh6pbybkyYTd3CMTkO24oMlCSw==} + '@docusaurus/utils-common@3.10.1': + resolution: {integrity: sha512-5mFSgEADtnFxFH7RLw02QA5MpU5JVUCj0MPeIvi/aF4Fi45tQRIuTwXoXDqJ+1VfQJuYJGz3SI63wmGz4HvXzA==} engines: {node: '>=20.0'} - '@docusaurus/utils-validation@3.10.0': - resolution: {integrity: sha512-c+6n2+ZPOJtWWc8Bb/EYdpSDfjYEScdCu9fB/SNjOmSCf1IdVnGf2T53o0tsz0gDRtCL90tifTL0JE/oMuP1Mw==} + '@docusaurus/utils-validation@3.10.1': + resolution: {integrity: sha512-cRv1X69jwaWv47waglllgZVWzeBFLhl53XT/XED/83BerVBTC5FTP8WTcVl8Z6sZOegDSwitu/wpCSPCDOT6lg==} engines: {node: '>=20.0'} - '@docusaurus/utils@3.10.0': - resolution: {integrity: sha512-T3B0WTigsIthe0D4LQa2k+7bJY+c3WS+Wq2JhcznOSpn1lSN64yNtHQXboCj3QnUs1EuAZszQG1SHKu5w5ZrlA==} + '@docusaurus/utils@3.10.1': + resolution: {integrity: sha512-3ojeJry9xBYdJO6qoyyzqeJFSJBVx2mXhyDzSdjwL2+URFQMf+h25gG38iswGImicK0ELjTd1EL2xzk8hf3QPw==} engines: {node: '>=20.0'} '@emnapi/core@1.10.0': @@ -2310,6 +2314,12 @@ packages: cpu: [ppc64] os: [aix] + '@esbuild/aix-ppc64@0.27.7': + resolution: {integrity: sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + '@esbuild/aix-ppc64@0.28.0': resolution: {integrity: sha512-lhRUCeuOyJQURhTxl4WkpFTjIsbDayJHih5kZC1giwE+MhIzAb7mEsQMqMf18rHLsrb5qI1tafG20mLxEWcWlA==} engines: {node: '>=18'} @@ -2328,6 +2338,12 @@ packages: cpu: [arm64] os: [android] + '@esbuild/android-arm64@0.27.7': + resolution: {integrity: sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + '@esbuild/android-arm64@0.28.0': resolution: {integrity: sha512-+WzIXQOSaGs33tLEgYPYe/yQHf0WTU0X42Jca3y8NWMbUVhp7rUnw+vAsRC/QiDrdD31IszMrZy+qwPOPjd+rw==} engines: {node: '>=18'} @@ -2346,6 +2362,12 @@ packages: cpu: [arm] os: [android] + '@esbuild/android-arm@0.27.7': + resolution: {integrity: sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + '@esbuild/android-arm@0.28.0': resolution: {integrity: sha512-wqh0ByljabXLKHeWXYLqoJ5jKC4XBaw6Hk08OfMrCRd2nP2ZQ5eleDZC41XHyCNgktBGYMbqnrJKq/K/lzPMSQ==} engines: {node: '>=18'} @@ -2364,6 +2386,12 @@ packages: cpu: [x64] os: [android] + '@esbuild/android-x64@0.27.7': + resolution: {integrity: sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + '@esbuild/android-x64@0.28.0': resolution: {integrity: sha512-+VJggoaKhk2VNNqVL7f6S189UzShHC/mR9EE8rDdSkdpN0KflSwWY/gWjDrNxxisg8Fp1ZCD9jLMo4m0OUfeUA==} engines: {node: '>=18'} @@ -2382,6 +2410,12 @@ packages: cpu: [arm64] os: [darwin] + '@esbuild/darwin-arm64@0.27.7': + resolution: {integrity: sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + '@esbuild/darwin-arm64@0.28.0': resolution: {integrity: sha512-0T+A9WZm+bZ84nZBtk1ckYsOvyA3x7e2Acj1KdVfV4/2tdG4fzUp91YHx+GArWLtwqp77pBXVCPn2We7Letr0Q==} engines: {node: '>=18'} @@ -2400,6 +2434,12 @@ packages: cpu: [x64] os: [darwin] + '@esbuild/darwin-x64@0.27.7': + resolution: {integrity: sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + '@esbuild/darwin-x64@0.28.0': resolution: {integrity: sha512-fyzLm/DLDl/84OCfp2f/XQ4flmORsjU7VKt8HLjvIXChJoFFOIL6pLJPH4Yhd1n1gGFF9mPwtlN5Wf82DZs+LQ==} engines: {node: '>=18'} @@ -2418,6 +2458,12 @@ packages: cpu: [arm64] os: [freebsd] + '@esbuild/freebsd-arm64@0.27.7': + resolution: {integrity: sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + '@esbuild/freebsd-arm64@0.28.0': resolution: {integrity: sha512-l9GeW5UZBT9k9brBYI+0WDffcRxgHQD8ShN2Ur4xWq/NFzUKm3k5lsH4PdaRgb2w7mI9u61nr2gI2mLI27Nh3Q==} engines: {node: '>=18'} @@ -2436,6 +2482,12 @@ packages: cpu: [x64] os: [freebsd] + '@esbuild/freebsd-x64@0.27.7': + resolution: {integrity: sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + '@esbuild/freebsd-x64@0.28.0': resolution: {integrity: sha512-BXoQai/A0wPO6Es3yFJ7APCiKGc1tdAEOgeTNy3SsB491S3aHn4S4r3e976eUnPdU+NbdtmBuLncYir2tMU9Nw==} engines: {node: '>=18'} @@ -2454,6 +2506,12 @@ packages: cpu: [arm64] os: [linux] + '@esbuild/linux-arm64@0.27.7': + resolution: {integrity: sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + '@esbuild/linux-arm64@0.28.0': resolution: {integrity: sha512-RVyzfb3FWsGA55n6WY0MEIEPURL1FcbhFE6BffZEMEekfCzCIMtB5yyDcFnVbTnwk+CLAgTujmV/Lgvih56W+A==} engines: {node: '>=18'} @@ -2472,6 +2530,12 @@ packages: cpu: [arm] os: [linux] + '@esbuild/linux-arm@0.27.7': + resolution: {integrity: sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + '@esbuild/linux-arm@0.28.0': resolution: {integrity: sha512-CjaaREJagqJp7iTaNQjjidaNbCKYcd4IDkzbwwxtSvjI7NZm79qiHc8HqciMddQ6CKvJT6aBd8lO9kN/ZudLlw==} engines: {node: '>=18'} @@ -2490,6 +2554,12 @@ packages: cpu: [ia32] os: [linux] + '@esbuild/linux-ia32@0.27.7': + resolution: {integrity: sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + '@esbuild/linux-ia32@0.28.0': resolution: {integrity: sha512-KBnSTt1kxl9x70q+ydterVdl+Cn0H18ngRMRCEQfrbqdUuntQQ0LoMZv47uB97NljZFzY6HcfqEZ2SAyIUTQBQ==} engines: {node: '>=18'} @@ -2508,6 +2578,12 @@ packages: cpu: [loong64] os: [linux] + '@esbuild/linux-loong64@0.27.7': + resolution: {integrity: sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + '@esbuild/linux-loong64@0.28.0': resolution: {integrity: sha512-zpSlUce1mnxzgBADvxKXX5sl8aYQHo2ezvMNI8I0lbblJtp8V4odlm3Yzlj7gPyt3T8ReksE6bK+pT3WD+aJRg==} engines: {node: '>=18'} @@ -2526,6 +2602,12 @@ packages: cpu: [mips64el] os: [linux] + '@esbuild/linux-mips64el@0.27.7': + resolution: {integrity: sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + '@esbuild/linux-mips64el@0.28.0': resolution: {integrity: sha512-2jIfP6mmjkdmeTlsX/9vmdmhBmKADrWqN7zcdtHIeNSCH1SqIoNI63cYsjQR8J+wGa4Y5izRcSHSm8K3QWmk3w==} engines: {node: '>=18'} @@ -2544,6 +2626,12 @@ packages: cpu: [ppc64] os: [linux] + '@esbuild/linux-ppc64@0.27.7': + resolution: {integrity: sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + '@esbuild/linux-ppc64@0.28.0': resolution: {integrity: sha512-bc0FE9wWeC0WBm49IQMPSPILRocGTQt3j5KPCA8os6VprfuJ7KD+5PzESSrJ6GmPIPJK965ZJHTUlSA6GNYEhg==} engines: {node: '>=18'} @@ -2562,6 +2650,12 @@ packages: cpu: [riscv64] os: [linux] + '@esbuild/linux-riscv64@0.27.7': + resolution: {integrity: sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + '@esbuild/linux-riscv64@0.28.0': resolution: {integrity: sha512-SQPZOwoTTT/HXFXQJG/vBX8sOFagGqvZyXcgLA3NhIqcBv1BJU1d46c0rGcrij2B56Z2rNiSLaZOYW5cUk7yLQ==} engines: {node: '>=18'} @@ -2580,6 +2674,12 @@ packages: cpu: [s390x] os: [linux] + '@esbuild/linux-s390x@0.27.7': + resolution: {integrity: sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + '@esbuild/linux-s390x@0.28.0': resolution: {integrity: sha512-SCfR0HN8CEEjnYnySJTd2cw0k9OHB/YFzt5zgJEwa+wL/T/raGWYMBqwDNAC6dqFKmJYZoQBRfHjgwLHGSrn3Q==} engines: {node: '>=18'} @@ -2598,6 +2698,12 @@ packages: cpu: [x64] os: [linux] + '@esbuild/linux-x64@0.27.7': + resolution: {integrity: sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + '@esbuild/linux-x64@0.28.0': resolution: {integrity: sha512-us0dSb9iFxIi8srnpl931Nvs65it/Jd2a2K3qs7fz2WfGPHqzfzZTfec7oxZJRNPXPnNYZtanmRc4AL/JwVzHQ==} engines: {node: '>=18'} @@ -2610,6 +2716,12 @@ packages: cpu: [arm64] os: [netbsd] + '@esbuild/netbsd-arm64@0.27.7': + resolution: {integrity: sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + '@esbuild/netbsd-arm64@0.28.0': resolution: {integrity: sha512-CR/RYotgtCKwtftMwJlUU7xCVNg3lMYZ0RzTmAHSfLCXw3NtZtNpswLEj/Kkf6kEL3Gw+BpOekRX0BYCtklhUw==} engines: {node: '>=18'} @@ -2628,6 +2740,12 @@ packages: cpu: [x64] os: [netbsd] + '@esbuild/netbsd-x64@0.27.7': + resolution: {integrity: sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + '@esbuild/netbsd-x64@0.28.0': resolution: {integrity: sha512-nU1yhmYutL+fQ71Kxnhg8uEOdC0pwEW9entHykTgEbna2pw2dkbFSMeqjjyHZoCmt8SBkOSvV+yNmm94aUrrqw==} engines: {node: '>=18'} @@ -2640,6 +2758,12 @@ packages: cpu: [arm64] os: [openbsd] + '@esbuild/openbsd-arm64@0.27.7': + resolution: {integrity: sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + '@esbuild/openbsd-arm64@0.28.0': resolution: {integrity: sha512-cXb5vApOsRsxsEl4mcZ1XY3D4DzcoMxR/nnc4IyqYs0rTI8ZKmW6kyyg+11Z8yvgMfAEldKzP7AdP64HnSC/6g==} engines: {node: '>=18'} @@ -2658,6 +2782,12 @@ packages: cpu: [x64] os: [openbsd] + '@esbuild/openbsd-x64@0.27.7': + resolution: {integrity: sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + '@esbuild/openbsd-x64@0.28.0': resolution: {integrity: sha512-8wZM2qqtv9UP3mzy7HiGYNH/zjTA355mpeuA+859TyR+e+Tc08IHYpLJuMsfpDJwoLo1ikIJI8jC3GFjnRClzA==} engines: {node: '>=18'} @@ -2670,6 +2800,12 @@ packages: cpu: [arm64] os: [openharmony] + '@esbuild/openharmony-arm64@0.27.7': + resolution: {integrity: sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + '@esbuild/openharmony-arm64@0.28.0': resolution: {integrity: sha512-FLGfyizszcef5C3YtoyQDACyg95+dndv79i2EekILBofh5wpCa1KuBqOWKrEHZg3zrL3t5ouE5jgr94vA+Wb2w==} engines: {node: '>=18'} @@ -2688,6 +2824,12 @@ packages: cpu: [x64] os: [sunos] + '@esbuild/sunos-x64@0.27.7': + resolution: {integrity: sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + '@esbuild/sunos-x64@0.28.0': resolution: {integrity: sha512-1ZgjUoEdHZZl/YlV76TSCz9Hqj9h9YmMGAgAPYd+q4SicWNX3G5GCyx9uhQWSLcbvPW8Ni7lj4gDa1T40akdlw==} engines: {node: '>=18'} @@ -2706,6 +2848,12 @@ packages: cpu: [arm64] os: [win32] + '@esbuild/win32-arm64@0.27.7': + resolution: {integrity: sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + '@esbuild/win32-arm64@0.28.0': resolution: {integrity: sha512-Q9StnDmQ/enxnpxCCLSg0oo4+34B9TdXpuyPeTedN/6+iXBJ4J+zwfQI28u/Jl40nOYAxGoNi7mFP40RUtkmUA==} engines: {node: '>=18'} @@ -2724,6 +2872,12 @@ packages: cpu: [ia32] os: [win32] + '@esbuild/win32-ia32@0.27.7': + resolution: {integrity: sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + '@esbuild/win32-ia32@0.28.0': resolution: {integrity: sha512-zF3ag/gfiCe6U2iczcRzSYJKH1DCI+ByzSENHlM2FcDbEeo5Zd2C86Aq0tKUYAJJ1obRP84ymxIAksZUcdztHA==} engines: {node: '>=18'} @@ -2742,6 +2896,12 @@ packages: cpu: [x64] os: [win32] + '@esbuild/win32-x64@0.27.7': + resolution: {integrity: sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + '@esbuild/win32-x64@0.28.0': resolution: {integrity: sha512-pEl1bO9mfAmIC+tW5btTmrKaujg3zGtUmWNdCw/xs70FBjwAL3o9OEKNHvNmnyylD6ubxUERiEhdsL0xBQ9efw==} engines: {node: '>=18'} @@ -2762,16 +2922,16 @@ packages: resolution: {integrity: sha512-Y3kKLvC1dvTOT+oGlqNQ1XLqK6D1HU2YXPc52NmAlJZbMMWDzGYXMiPRJ8TYD39muD/OTjlZmNJ4ib7dvSrMBA==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} - '@eslint/config-helpers@0.5.5': - resolution: {integrity: sha512-eIJYKTCECbP/nsKaaruF6LW967mtbQbsw4JTtSVkUQc9MneSkbrgPJAbKl9nWr0ZeowV8BfsarBmPpBzGelA2w==} + '@eslint/config-helpers@0.6.0': + resolution: {integrity: sha512-ii6Bw9jJ2zi2cWA2Z+9/QZ/+3DX6kwaV5Q986D/CdP3Lap3w/pgQZ373FV7byY/i7L4IRH/G43I5dz1ClsCbpA==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} '@eslint/core@1.2.1': resolution: {integrity: sha512-MwcE1P+AZ4C6DWlpin/OmOA54mmIZ/+xZuJiQd4SyB29oAJjN30UW9wkKNptW2ctp4cEsvhlLY/CsQ1uoHDloQ==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} - '@eslint/css-tree@4.0.2': - resolution: {integrity: sha512-eqSkC3mka2tiqOuPZKqvxNJoRzpxMss3Np3Yqi4sW7nTTRCpTKB2hzrY4JRsi0ZP3QbVfp23sgEm7VCoOjesmw==} + '@eslint/css-tree@4.0.3': + resolution: {integrity: sha512-lMgQJ5zg4YwsGPWtKS7Rc5Z4xqc2B9iOTtmDvhjMRa8GJ8/9zoKRtz26D7gCtWquy0J7oyeOJBwRP5M8slM/4w==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} '@eslint/js@10.0.1': @@ -2821,20 +2981,20 @@ packages: '@formatjs/fast-memoize@2.2.7': resolution: {integrity: sha512-Yabmi9nSvyOMrlSeGGWDiH7rf3a7sIwplbvo/dlz9WCIjzIQAfy1RMf4S0X3yG724n5Ghu2GmEl5NJIV6O9sZQ==} - '@formatjs/fast-memoize@3.1.2': - resolution: {integrity: sha512-vPnriihkfK0lzoQGaXq+qXH23VsYyansRTkTgo2aTG0k1NjLFyZimFVdfj4C9JkSE5dm7CEngcQ5TTc1yAyBfQ==} + '@formatjs/fast-memoize@3.1.5': + resolution: {integrity: sha512-KLi3fan6WnCHmigd9pmEEN8Hid0v4wiFBW576M/d07KMWYecf1CvyMI3n34vCmHT4AoVqG2n702kiHbXjzZX2A==} '@formatjs/icu-messageformat-parser@2.11.4': resolution: {integrity: sha512-7kR78cRrPNB4fjGFZg3Rmj5aah8rQj9KPzuLsmcSn4ipLXQvC04keycTI1F7kJYDwIXtT2+7IDEto842CfZBtw==} - '@formatjs/icu-messageformat-parser@3.5.4': - resolution: {integrity: sha512-JVY39ROgLt+pIYngo6piyj4OVfZmXs/2FkC4wLS+ql1Eig/sGJKB7YwDO/5bkJFkfwaFAeIpgEiJc8hiYxNalw==} + '@formatjs/icu-messageformat-parser@3.5.9': + resolution: {integrity: sha512-PZm6O9JI/gUPtQV9r2eaMuLb4yWqV2vz+ot03ORHWTKO343LSpZi0TqeXLB2ZZGDXLCw2SbfgsQ0GxoxXMl79g==} '@formatjs/icu-skeleton-parser@1.8.16': resolution: {integrity: sha512-H13E9Xl+PxBd8D5/6TVUluSpxGNvFSlN/b3coUp0e0JpuWXXnQDiavIpY3NnvSp4xhEMoXyyBvVfdFX8jglOHQ==} - '@formatjs/icu-skeleton-parser@2.1.4': - resolution: {integrity: sha512-8bSFZbrlvGX11ywMZxtgkPBt5Q8/etyts7j7j+GWpOVK1g43zwMIH3LZxk43HAtEP7L/jtZ+OZaMiFTOiBj9CA==} + '@formatjs/icu-skeleton-parser@2.1.9': + resolution: {integrity: sha512-rsxswgHMfU1zUgB2byc08fesf83wLGjFnzLCEtuf00mx2doiqc6pYrf67raI37XqdRcGUviQepk2UKGqpng74Q==} '@formatjs/intl-localematcher@0.6.2': resolution: {integrity: sha512-XOMO2Hupl0wdd172Y06h6kLpBz6Dv+J4okPLl4LPtzbr8f66WbIoy4ev98EBuZ6ZK4h5ydTN6XneT4QVpD7cdA==} @@ -2881,8 +3041,8 @@ packages: engines: {node: '>=6'} hasBin: true - '@grpc/proto-loader@0.8.0': - resolution: {integrity: sha512-rc1hOQtjIWGxcxpb9aHAfLpIctjEnsDehj0DAiVfBlmT84uvR0uUtN2hEi/ecvWVjXUGf5qPF4qEgiLOx1YIMQ==} + '@grpc/proto-loader@0.8.1': + resolution: {integrity: sha512-wtF6h+DY6M3YaDBPAmvuuA6jV8Sif9MjtOI5euKFWRgCDl5PeDpPsHR9u2l6St5ceY8AZgoNDww5+HvEsXFsGg==} engines: {node: '>=6'} hasBin: true @@ -2915,11 +3075,11 @@ packages: '@iconify/types@2.0.0': resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==} - '@iconify/utils@3.1.0': - resolution: {integrity: sha512-Zlzem1ZXhI1iHeeERabLNzBHdOa4VhQbqAcOQaMKuTuyZCpwKbC2R4Dd0Zo3g9EAc+Y4fiarO8HIHRAth7+skw==} + '@iconify/utils@3.1.3': + resolution: {integrity: sha512-LPKOXPn/zV+zis1oOfGWogaXVpqUybF3ZS6SCZIsz8vg0ivVp9+fVqyYB7xq0aiST/VhUQYGO1qo6uoYSiEJqw==} - '@img/colour@1.0.0': - resolution: {integrity: sha512-A5P/LfWGFSl6nsckYtjw9da+19jB8hkJ6ACTGcDfEJ0aE+l2n2El7dsVM7UVHZQ9s2lmYMWlrS21YLy2IR1LUw==} + '@img/colour@1.1.0': + resolution: {integrity: sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==} engines: {node: '>=18'} '@img/sharp-darwin-arm64@0.34.5': @@ -3088,8 +3248,8 @@ packages: peerDependencies: svelte: ^5.0.0 - '@immich/ui@0.77.3': - resolution: {integrity: sha512-h3jrYE3JyGDOwXF7A4tVUHenP0L7TsDV22FyFInBTdwlWjjXoknwE1HWeTvvLxLeMuO5SHCZ9Q2D2al84xVjNw==} + '@immich/ui@0.79.2': + resolution: {integrity: sha512-tnpYhYHrjrFJK18QglRMzPUtHv6q5V6tW38HiAraQJBv7MCg+yaJDrdF8omM2L5F311FGlv1PZLJYvmR4e49PA==} peerDependencies: '@sveltejs/kit': ^2.13.0 svelte: ^5.0.0 @@ -3425,8 +3585,8 @@ packages: resolution: {integrity: sha512-x/iUDjcS90W69PryLDIMgFyV21YLTnG9zOpPXS7Bkt2b8AsY3zZsIpOLBkYr9fBcF3HbkKaER5hOBZLfpLgYNw==} engines: {node: '>= 14.0.0'} - '@koa/router@15.4.0': - resolution: {integrity: sha512-vKYlXtoCfcAN8z4dHiveYX55rTYOgHEYJNumK1WM9ZAwaArhreGVkyC1LTMGfUQUJyIO/SbwRFBOHeOCY8/MaQ==} + '@koa/router@15.5.0': + resolution: {integrity: sha512-KSC0oG/5t6ITu5wqX4lJseA/dngoj14hEaohrLZEXtlUT2RRyJvwaJ0KV+5uQoaWrY3A8ClHOrBEU4g8dujn8Q==} engines: {node: '>= 20'} peerDependencies: koa: ^2.0.0 || ^3.0.0 @@ -3470,8 +3630,8 @@ packages: '@mapbox/point-geometry@1.1.0': resolution: {integrity: sha512-YGcBz1cg4ATXDCM/71L9xveh4dynfGmcLDqufR+nQQy3fKwsAZsWd/x4621/6uJaeB9mwOHE6hPeDgXz9uViUQ==} - '@mapbox/tiny-sdf@2.1.0': - resolution: {integrity: sha512-uFJhNh36BR4OCuWIEiWaEix9CA2WzT6CAIcqVjWYpnx8+QDtS+oC4QehRrx5cX4mgWs37MmKnwUejeHxVymzNg==} + '@mapbox/tiny-sdf@2.2.0': + resolution: {integrity: sha512-LVL4wgI9YAum5V+LNVQO6QgFBPw7/MIIY4XJPNsPDMrjEwcE+JfKk1LuIl8GnF197ejVdC9QdPaxrx5gfgdGXg==} '@mapbox/unitbezier@0.0.1': resolution: {integrity: sha512-nMkuDXFv60aBr9soUG5q+GvZYL+2KZHVvsqFCzqnkGEf46U2fvmytHaEVc1/YZbiLn8X+eR3QzX1+dwDO1lxlw==} @@ -3489,8 +3649,8 @@ packages: '@maplibre/geojson-vt@6.1.0': resolution: {integrity: sha512-2eIY4gZxeKIVOZVNkAMb+5NgXhgsMQpOveTQAvnp53LYqHGJZDidk7Ew0Tged9PThidpbS+NFTh0g4zivhPDzQ==} - '@maplibre/maplibre-gl-style-spec@24.8.1': - resolution: {integrity: sha512-zxa92qF96ZNojLxeAjnaRpjVCy+swoUNJvDhtpC90k7u5F0TMr4GmvNqMKvYrMoPB8d7gRSXbMG1hBbmgESIsw==} + '@maplibre/maplibre-gl-style-spec@24.8.5': + resolution: {integrity: sha512-EzEJmMt6thioRH7GI9LWS7ahXTcAhAPGWCe6oTP2Ps4YnsXOOAfeqx854lZaiDnwURfHmcCKV1mr6oo0i23x6w==} hasBin: true '@maplibre/mlt@1.1.9': @@ -3523,8 +3683,8 @@ packages: '@types/react': '>=16' react: '>=16' - '@mermaid-js/parser@0.6.3': - resolution: {integrity: sha512-lnjOhe7zyHjc+If7yT4zoedx2vo4sHaTmtkl1+or8BRTnCtDmcTpAjpzDSfCZrshM5bCoz0GyidzadJAH1xobA==} + '@mermaid-js/parser@1.1.1': + resolution: {integrity: sha512-VuHdsYMK1bT6X2JbcAaWAhugTRvRBRyuZgd+c22swUeI9g/ntaxF7CY7dYarhZovofCbUNO0G7JesfmNtjYOCw==} '@microsoft/tsdoc@0.16.0': resolution: {integrity: sha512-xgAyonlVVS+q7Vc7qLW0UrJU7rSFcETRWsqdXZtjzRU8dF+6CkozTK4V4y1LwOX7j8r/vHphjDeMeGI4tNGeGA==} @@ -3607,6 +3767,19 @@ packages: class-validator: optional: true + '@nestjs/common@11.1.21': + resolution: {integrity: sha512-YV1HYDGsm2rnR0vrLKidtrG6jYX5yqiIjeur1j8++dKGqhhsJ6cjMs0RfQRSTUH7IjgDemA59/znQ8nRrE0D9g==} + peerDependencies: + class-transformer: '>=0.4.1' + class-validator: '>=0.13.2' + reflect-metadata: ^0.1.12 || ^0.2.0 + rxjs: ^7.1.0 + peerDependenciesMeta: + class-transformer: + optional: true + class-validator: + optional: true + '@nestjs/core@11.1.19': resolution: {integrity: sha512-6nJkWa2efrYi+XlU686J9y5L7OvxpLVjT0T/sxRKE7Jvpffiihelup4WSvLvRhdHDjj/5SuoWEwqReXAaaeHmw==} engines: {node: '>= 20'} @@ -3625,6 +3798,24 @@ packages: '@nestjs/websockets': optional: true + '@nestjs/core@11.1.21': + resolution: {integrity: sha512-fqo0BHgny3MOuAL8GSfG3ZUKFVVBaBQD/0iyibnwTONT5vPexjQxJzu+945iloVvBDmrnAaRWxC1gqCDEs/AXQ==} + engines: {node: '>= 20'} + peerDependencies: + '@nestjs/common': ^11.0.0 + '@nestjs/microservices': ^11.0.0 + '@nestjs/platform-express': ^11.0.0 + '@nestjs/websockets': ^11.0.0 + reflect-metadata: ^0.1.12 || ^0.2.0 + rxjs: ^7.1.0 + peerDependenciesMeta: + '@nestjs/microservices': + optional: true + '@nestjs/platform-express': + optional: true + '@nestjs/websockets': + optional: true + '@nestjs/event-emitter@3.1.0': resolution: {integrity: sha512-DOY/4XBGyIjYyOJKkO6jl1kzFE0ZfX0wV+M2HR5NWymPT9Z0zdCEcZGxTXXkoMRwPtglnvCGJALSjOpXPIcM3g==} peerDependencies: @@ -3644,8 +3835,8 @@ packages: class-validator: optional: true - '@nestjs/platform-express@11.1.19': - resolution: {integrity: sha512-Vpdv8jyCQdThfoTx+UTn+DRYr6H6X02YUqcpZ3qP6G3ZUwtVp7eS+hoQPGd4UuCnlnFG8Wqr2J9bGEzQdi1rIg==} + '@nestjs/platform-express@11.1.21': + resolution: {integrity: sha512-lA3ViycOnz4Df3EstIKpuAVFhqxQixTnjAVk0M+LRyNBlGM6VSCaNJaAIrb9Pcry39T4hTHpNVbRqGLSvhL8gA==} peerDependencies: '@nestjs/common': ^11.0.0 '@nestjs/core': ^11.0.0 @@ -3657,6 +3848,13 @@ packages: '@nestjs/websockets': ^11.0.0 rxjs: ^7.1.0 + '@nestjs/platform-socket.io@11.1.21': + resolution: {integrity: sha512-Tq5JgaVS+auD3DXuRBy8UMU3mf69HJO8Ep+BuRS9GYMXGd/5sdMHqIQvXlXkGih9tQXdeeG9WoqURe/+IjPKng==} + peerDependencies: + '@nestjs/common': ^11.0.0 + '@nestjs/websockets': ^11.0.0 + rxjs: ^7.1.0 + '@nestjs/schedule@6.1.3': resolution: {integrity: sha512-RflMFOpR16Dwd1jAUbeB4mfGTCh65fvEdL4mSjQPJChpkRGRjIXjb+6YQcK2faQrVT60c9DmLmoVR7/ONCtuYQ==} peerDependencies: @@ -3672,8 +3870,8 @@ packages: prettier: optional: true - '@nestjs/swagger@11.4.2': - resolution: {integrity: sha512-aBihEogDMj/bLEcaqhkvyX/ZVWUw/bmnhKzR0zwUoyGJikvZyaq7rOPYl/H7Lxkkr3c90SJxyuv1AX2UT1WKlw==} + '@nestjs/swagger@11.4.3': + resolution: {integrity: sha512-LR4BuOj+iBFzhGRnNP0OHjmrPXliDEjrmniXtLsfLDIELjkuUXYCTGjZMqgDdOY+QSabeF59LndaDzOOe+vMmw==} peerDependencies: '@fastify/static': ^8.0.0 || ^9.0.0 '@nestjs/common': ^11.0.1 @@ -3681,6 +3879,7 @@ packages: class-transformer: '*' class-validator: '*' reflect-metadata: ^0.1.12 || ^0.2.0 + typescript: '*' peerDependenciesMeta: '@fastify/static': optional: true @@ -3689,8 +3888,8 @@ packages: class-validator: optional: true - '@nestjs/testing@11.1.19': - resolution: {integrity: sha512-/UFNWXvPEdu4v4DlC5oWLbGKmD27LehLK06b8oLzs6D6lf4vAQTdST8LRAXBadyMUQnVEQWMuBo3CtAVtlfXtQ==} + '@nestjs/testing@11.1.21': + resolution: {integrity: sha512-RhzaUFxr6/bpXWjKIzr7p2eHKMFMLwPgsxJNFcCf2CkkT3UEjW+KRGb7E2JY+fh+ck3zAdvQJrzATDnSsVlFZw==} peerDependencies: '@nestjs/common': ^11.0.0 '@nestjs/core': ^11.0.0 @@ -3714,6 +3913,22 @@ packages: '@nestjs/platform-socket.io': optional: true + '@nestjs/websockets@11.1.21': + resolution: {integrity: sha512-2L+jFf6Nbjv7WacngvSoYGYTalqNuXlOkFl9Q5e92XiPK4gR6c4Zw6zFcb7btTY5zf7pITvOoAJIGwf3+gciRA==} + peerDependencies: + '@nestjs/common': ^11.0.0 + '@nestjs/core': ^11.0.0 + '@nestjs/platform-socket.io': ^11.0.0 + reflect-metadata: ^0.1.12 || ^0.2.0 + rxjs: ^7.1.0 + peerDependenciesMeta: + '@nestjs/platform-socket.io': + optional: true + + '@noble/hashes@1.4.0': + resolution: {integrity: sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==} + engines: {node: '>= 16'} + '@noble/hashes@1.8.0': resolution: {integrity: sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==} engines: {node: ^14.21.3 || >=16} @@ -3734,14 +3949,6 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} - '@npmcli/agent@4.0.0': - resolution: {integrity: sha512-kAQTcEN9E8ERLVg5AsGwLNoFb+oEG6engbqAU2P43gD4JEIkNGMHdVQ096FsOAAYpZPB0RSt0zgInKIAS1l5QA==} - engines: {node: ^20.17.0 || >=22.9.0} - - '@npmcli/fs@5.0.0': - resolution: {integrity: sha512-7OsC1gNORBEawOa5+j2pXN9vsicaIOH5cPXxoR6fJOmH6/EXpJB2CajXOu1fPRFun2m1lktEFX11+P89hqO/og==} - engines: {node: ^20.17.0 || >=22.9.0} - '@nuxt/opencollective@0.4.1': resolution: {integrity: sha512-GXD3wy50qYbxCJ652bDrDzgMr3NFEkIS374+IgFQKkCvk9yiYcLvX2XDYr7UyQxf4wK0e+yqDYRubZ0DtOxnmQ==} engines: {node: ^14.18.0 || >=16.10.0, npm: '>=5.10.0'} @@ -3750,24 +3957,16 @@ packages: '@oazapfts/runtime@1.2.0': resolution: {integrity: sha512-fi7dp7dNayyh/vzqhf0ZdoPfC7tJvYfjaE8MBL1yR+iIsH7cFoqHt+DV70VU49OMCqLc7wQa+yVJcSmIRnV4wA==} - '@opentelemetry/api-logs@0.215.0': - resolution: {integrity: sha512-xrFlqhdhUyO8wSRn6DjE0145/HPWSJ5Nm0C7vWua6TdL/FSEAZvEyvdsa9CRXuxo9ebb7j/NEPhEcO62IJ0qUA==} - engines: {node: '>=8.0.0'} - - '@opentelemetry/api-logs@0.217.0': - resolution: {integrity: sha512-Cdq0jW2lknrNfrAm92MyEAvpe2cRsKjdnQLHUL6xRA4IVUnsWx6P65E7NcUO0Y+L4w1Aee5iV8FvjSwd+lrs9A==} - engines: {node: '>=8.0.0'} - - '@opentelemetry/api@1.9.0': - resolution: {integrity: sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==} + '@opentelemetry/api-logs@0.218.0': + resolution: {integrity: sha512-fmEWp5kXlGEc3i/lR698Hz41DfGyN4Tbe4g7L1AxSc7fF8Xeh/FQ9Quqpa9dVA413Q1Ad43QOLzU4JoXgbFPWw==} engines: {node: '>=8.0.0'} '@opentelemetry/api@1.9.1': resolution: {integrity: sha512-gLyJlPHPZYdAk1JENA9LeHejZe1Ti77/pTeFm/nMXmQH/HFZlcS/O2XJB+L8fkbrNSqhdtlvjBVjxwUYanNH5Q==} engines: {node: '>=8.0.0'} - '@opentelemetry/configuration@0.217.0': - resolution: {integrity: sha512-xCtrYOhBqdy6ZOMfe0Oa73ZKF+2LMhoOv4L5vmwAHVvOXUg+V3fvKuEIr9ZyD0Ow+vxllEjWO6PV1wd0DOtyvw==} + '@opentelemetry/configuration@0.218.0': + resolution: {integrity: sha512-W8wIz7H2R1pufR5jfjb3gU2XkMpm2x/7b1RJcsuzvd70Il/rWWE+g5/Od7hQKrxRTSrTrOWlru101PWXz5I1EQ==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.9.0 @@ -3796,62 +3995,62 @@ packages: peerDependencies: '@opentelemetry/api': '>=1.0.0 <1.10.0' - '@opentelemetry/exporter-logs-otlp-grpc@0.217.0': - resolution: {integrity: sha512-vC5S0Dc+noxD86CVtNu1+awCHPA5Kewi1Sg23ps+9lh4YifwsKXh3pe4XTNEKtUJiAcjpJ5dqStGakLbrSE+YQ==} + '@opentelemetry/exporter-logs-otlp-grpc@0.218.0': + resolution: {integrity: sha512-hoxrNH1l/Xy6F9WTJ5IK+6j1r9nQFlPOmrnTlhYHTySdunfXLmUCPv3bQtKYntxag9h3wLYBZQ2HI6FOx+BT2g==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/exporter-logs-otlp-http@0.217.0': - resolution: {integrity: sha512-KfLAdt1uilVE+3FxbgVnp2ZrzqbIawzcesnRoi+Kh9ckB5Ld5D8btUgoBvwTbdmuNx1j6b132Wsh72azq+pPNQ==} + '@opentelemetry/exporter-logs-otlp-http@0.218.0': + resolution: {integrity: sha512-Qx+4rpVHzgg89dawcWRHyt+XRXeLnhFz/qBtvggmjkcgPUdr+NAB0/u/eIPA8yAeJV0J80Vz43JZCh/XFvZFGw==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/exporter-logs-otlp-proto@0.217.0': - resolution: {integrity: sha512-Se0GG/ZO24mQTlQj7zprR4pNI0nKe4lPDPBsuJmi6508b9TlZEuUd3EfyuHk6oJxzL7fGyDFYAbxNigQvRP2ZQ==} + '@opentelemetry/exporter-logs-otlp-proto@0.218.0': + resolution: {integrity: sha512-1/noQNsp9gXD75HPzgjBrcF1+XTtry7pFAUfxVEJgg7mPv2AawKQuYkhMmJ8qjxz4Ubc3Y8bwvfxevXsKTq4cg==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/exporter-metrics-otlp-grpc@0.217.0': - resolution: {integrity: sha512-0GpJKnCoVaVA1rKBMVPHziznfOQlXgH72S9ktjBAF1AnAVPzX7vVEBGrhwiSxxHDAiefXk+J8znApsMb/K6Z3w==} + '@opentelemetry/exporter-metrics-otlp-grpc@0.218.0': + resolution: {integrity: sha512-YapQ9vNMX0NSZF6LK5pWAFfjpJleV2O9uYWfYGeb/5F1Kb9rPGK8tZDMJFa/sOksgdFuflDvYuA0B4qjDB4fjQ==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/exporter-metrics-otlp-http@0.217.0': - resolution: {integrity: sha512-1zkMzzhiNJdVmLxuwkltqWGw4fOOam47bqRxmuQNjyKJe/9NmY5cIrZ4kiQV7sVGxoOgT0ZvGUfLcjvtpC/b9Q==} + '@opentelemetry/exporter-metrics-otlp-http@0.218.0': + resolution: {integrity: sha512-bV7d2OuMpZu2+gAaxUAhzfZ0h3WVZk8ETQUEE3DNSntbTaMpuITjtm8I0rNyHFdm7Ax57K6ty7SgFXlBmOLIvQ==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/exporter-metrics-otlp-proto@0.217.0': - resolution: {integrity: sha512-nfxt/KxVGFkjkO/M+58y1ugHu/dwPtxG4eYq0KApcQ7xk5CHzhdn+IuLZfDSvNDrJ3Uy5q++Fj/wbK7i8yryfQ==} + '@opentelemetry/exporter-metrics-otlp-proto@0.218.0': + resolution: {integrity: sha512-ubLddKjWULhla9YZRCj/rTBeppjJYE4e9w0icx5mTu3eFhWjQzbV75NYjXuIlEG+NJsBl6d+sTFw5Qu+oej4oQ==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/exporter-prometheus@0.217.0': - resolution: {integrity: sha512-U9MCXxJu0sBCh5aEkylYRR4xVIL8D1CW6dGwvYXbfFr0qveSorfD0XJchCAWoW6QfAAIcY/yxjf4Dj8OgkHBPw==} + '@opentelemetry/exporter-prometheus@0.218.0': + resolution: {integrity: sha512-RT5oEyu1kddZJ1vt7/BUo5wV+P7hpNAESsR3dUd3+8deHuX7gWNoCOZn+SfDT+hJHlIJ5h/AxiCLXIrutswDJg==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/exporter-trace-otlp-grpc@0.217.0': - resolution: {integrity: sha512-fPZs2fw7veLH3pEKu8vSepUa2fQpAE2P7al6qU10aH9GrEJJ8YaPgsd5xON7by5rbcEVS71FOU2aWyK6nzB7VQ==} + '@opentelemetry/exporter-trace-otlp-grpc@0.218.0': + resolution: {integrity: sha512-3fXxVQEj9TNAFaCi79JeFKfeLd0sDtInaR3gaZDVlzNSPHtz8PZuCV34JKWjD4XXzT20IdMe8IpX6mRVNDA4Tw==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/exporter-trace-otlp-http@0.217.0': - resolution: {integrity: sha512-38YQoqtYjglz2GV94LGUN/djLvxtvGIQO68o6qAFPVshjmwSdX1F2i0c7vn3lEl1L5B/YqjB/bgKXaVx7KO+RQ==} + '@opentelemetry/exporter-trace-otlp-http@0.218.0': + resolution: {integrity: sha512-8dqezsmPhtKitIK/eTipZhYl9EX2/gNQ5zUMhaz3uxEURwfkNf8IPvo6yNfrzbxdtpAOybS/+h7wmIWYqFSpiw==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/exporter-trace-otlp-proto@0.217.0': - resolution: {integrity: sha512-nPV8gKHUiSuTZpQcnZU3/pBlK7crSyEGpZuh5MtWySB0vv6NNG0QvvfKitQt+Fc2Mc6qfyU54KlZcurwoTbrVg==} + '@opentelemetry/exporter-trace-otlp-proto@0.218.0': + resolution: {integrity: sha512-r1Msf8SNLRmwh9J6XQ5uh82D7CdDWMNHnPB7LAVHjzut0TkSeKc5KcIvr4SvHvfk/xwN5gxC+VLKQ1k0o8PSPw==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 @@ -3868,56 +4067,50 @@ packages: peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/instrumentation-http@0.215.0': - resolution: {integrity: sha512-ip9iNoRRVxDyP8LVfdqqI6OwbOwzxTl4SaP1WDKJq0sDsgpOr7rIOFj7gV8yKl4F5PdDOUYy8VqdgIOWZRlGBw==} + '@opentelemetry/instrumentation-http@0.218.0': + resolution: {integrity: sha512-x9djaqdzpT8WAboep1H9nCAQ1E+MMsm08TNfA02TqM3bNNddZeiim+E3KMWVQFaX6JpUy7V0nm/wfN/K2Em+Zw==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/instrumentation-ioredis@0.63.0': - resolution: {integrity: sha512-x+h/uq7mstqr7TwU1q0MdmMkyU1SDZcmd/ErXbdNfScmXMcYfo8sCRzMsL9UwukSdaU3ccYYpYweGXghv9xN0Q==} + '@opentelemetry/instrumentation-ioredis@0.66.0': + resolution: {integrity: sha512-UfTAcaBKCzLUZ9opvfOLV4bH46XiNFqUsKykfPCIefDIxJ1iUYtMOucNaiZ+/kjQdPy5i6Ef5tk2IAjxol4X1w==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/instrumentation-nestjs-core@0.61.0': - resolution: {integrity: sha512-e/zpwFbEyQFK8uINyFqbeQsA6PW5+hKI+eJj8L98lz1FnQSbRsNMz3Z8c0KYWcDqbg857DpB97s9P3lXdtwccg==} + '@opentelemetry/instrumentation-nestjs-core@0.64.0': + resolution: {integrity: sha512-PW1ArxryMwF8/IXq1nzlQs7tmr/fWd1tf71AHevZT3Fm0hW7jRX9JEfYgIAcKDvmbqcJEr5K1224NEimrRPbuQ==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/instrumentation-pg@0.67.0': - resolution: {integrity: sha512-1b1o/9nelDwoE3+EucZ9eHZsdUgji799C94lX1ZPy6O0EVjdTj3HczLL6z3GqPGZHmV4OpmJjGz8kuLtuPjCGA==} + '@opentelemetry/instrumentation-pg@0.70.0': + resolution: {integrity: sha512-g8WXwwOUXfjiEmATwjB/33QKE2AkIpNe4KIuJJh4djtXgCL0Wne+AzAfjuDIAspGvO1txQp8ibKsLd3SBmcvJA==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/instrumentation@0.215.0': - resolution: {integrity: sha512-SyJONuqypQ2xWdYMy99vF7JhZ2kDTGx4oRmM/jZV+kRtZ96JTnJmEINbIJgHz7Gnhtw0bimHwbPy/pguA5wpPQ==} + '@opentelemetry/instrumentation@0.218.0': + resolution: {integrity: sha512-mIZil8Es+sYDK5m+DQiwAwF57F14TF2YlEqvIjZ/RQWcxDBwRGsKfdK2Tv65OU9meQKCMzSIFS9mxAcnAb6Bkg==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/instrumentation@0.217.0': - resolution: {integrity: sha512-24ucQMjz7Y34Kw3trbxL2ZrssbtgWnR+Clpaa+YdeWuuyH3Cvk23Q03PcQvqiZrDvt8AmQmjgg9v6Y9PHoxG7w==} + '@opentelemetry/otlp-exporter-base@0.218.0': + resolution: {integrity: sha512-ZwqpkNL5W7RyGJPDZ9g06DvKp8KFTWPJPN12anpMQYSKpTSU0z3EIZuPq9vPGpS8siFyOqDYDAuCwlNO9FqgbA==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/otlp-exporter-base@0.217.0': - resolution: {integrity: sha512-eYfqnB3UhKu/5frhd1R6+FprKygbhkomuaceMXDyzxbfXB9tKgZOVmjaJ02CkLA6Tdzumxl+e2H+vo2a8jiMPQ==} + '@opentelemetry/otlp-grpc-exporter-base@0.218.0': + resolution: {integrity: sha512-H/lCGJ536N98VpYJOaWTQOkv4Dx6TnmStK6Rqfu1W7KkFbPAx04hjdYEMZF/YbnHzPUSIK4kM6OE2GKGBTpV9A==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/otlp-grpc-exporter-base@0.217.0': - resolution: {integrity: sha512-7RTAdZuOsCDnsyqTCG4+bDzrfnsWdzkRs7z0AVi/V3tEQx0oKeyc+OuRWYxnRsmaJXgxcmB8vb/lfxn58Dj6Ag==} - engines: {node: ^18.19.0 || >=20.6.0} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/otlp-transformer@0.217.0': - resolution: {integrity: sha512-MKK8UHKFUOGAvbZRWh90MhwHG+Fxm6OROBdjKPCF+HQobjuJ/Kuf8Chs8CR45X1aqotxrMj7OxTdsXe8sXuGVA==} + '@opentelemetry/otlp-transformer@0.218.0': + resolution: {integrity: sha512-CFaKH87WAzjuJ4awowTTLzUvMfaRfiOFG5+qm5S5ncyalRtN4ecQ+YmuANJSCrVPuvZFEkUgKhBPBndxi3rHsQ==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 @@ -3950,8 +4143,8 @@ packages: peerDependencies: '@opentelemetry/api': '>=1.3.0 <1.10.0' - '@opentelemetry/sdk-logs@0.217.0': - resolution: {integrity: sha512-BB+PcHItcZDL63dPMW+mJvwN9rk37wuIDjRxbVlg6pPDvDR/7GL7UJHbGsllgoggOoTimsKgENaWPoGch/oE1A==} + '@opentelemetry/sdk-logs@0.218.0': + resolution: {integrity: sha512-QvnNdugatFTVCJXH0Mcu7GOOJSylA9j127kIezOE4YwTI4YbowRons2K4WZTv5FMS8T4q9P0NdaRHdkSmeAIag==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': '>=1.4.0 <1.10.0' @@ -3968,8 +4161,8 @@ packages: peerDependencies: '@opentelemetry/api': '>=1.9.0 <1.10.0' - '@opentelemetry/sdk-node@0.217.0': - resolution: {integrity: sha512-K/60pSv42+NQiZKy1pAH18nYDkxltsDV4O3SJ233J0E9raU1ksyL9gsKuS8p30bYBb4AMPCfDuutHQaHYpcv0Q==} + '@opentelemetry/sdk-node@0.218.0': + resolution: {integrity: sha512-tPMjHrLV5gsfNdYqoRHjeGbCAZBXXD9c1Qo/2ut7VwnUABDNh76xNxrT0SEhkIIJuCN45bbN1vZnYL1gY0IkOg==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': '>=1.3.0 <1.10.0' @@ -3986,8 +4179,8 @@ packages: peerDependencies: '@opentelemetry/api': '>=1.0.0 <1.10.0' - '@opentelemetry/semantic-conventions@1.40.0': - resolution: {integrity: sha512-cifvXDhcqMwwTlTK04GBNeIe7yyo28Mfby85QXFe1Yk8nmi36Ab/5UQwptOx84SsoGNRg+EVSjwzfSZMy6pmlw==} + '@opentelemetry/semantic-conventions@1.41.1': + resolution: {integrity: sha512-/UhIkaZgPutTFmQ7RnIJGgDXZmtEJ7Dvi86xNTFWcnRxVRNk/aotsqDJYeEvDP+FSMB2SdW+pQzNMcWP0rwuNA==} engines: {node: '>=14'} '@opentelemetry/sql-common@0.41.2': @@ -3996,8 +4189,8 @@ packages: peerDependencies: '@opentelemetry/api': ^1.1.0 - '@oxc-project/types@0.127.0': - resolution: {integrity: sha512-aIYXQBo4lCbO4z0R3FHeucQHpF46l2LbMdxRvqvuRuW2OxdnSkcng5B8+K12spgLDj93rtN3+J2Vac/TIO+ciQ==} + '@oxc-project/types@0.130.0': + resolution: {integrity: sha512-ibD2usx9JRu7f5pu2tMKMI4cpA4NgXJQoYRP4pQ7Pxmn1l6k/53qWtQWZayhYy3X4QZkt90Ot+mJEaeXouio6Q==} '@paralleldrive/cuid2@2.3.1': resolution: {integrity: sha512-XO7cAxhnTZl0Yggq6jOgjiOHhbgcO4NqFqwSmQpjK3b6TEE6Uj/jfSk6wzYyemh3+I0sHirKSetjQwn5cZktFw==} @@ -4090,6 +4283,43 @@ packages: resolution: {integrity: sha512-tmmZ3lQxAe/k/+rNnXQRawJ4NjxO2hqiOLTHvWchtGZULp4RyFeh6aU4XdOYBFe2KE1oShQTv4AblOs2iOrNnQ==} engines: {node: '>= 10.0.0'} + '@peculiar/asn1-cms@2.7.0': + resolution: {integrity: sha512-hew63shtzzvBcSHbhm+cyAmKe6AIfinT9hzEqSPjDC6opTTMKmTkQ0gHuN2KsWlvqiKw1S/fS94fhag/FJkioQ==} + + '@peculiar/asn1-csr@2.7.0': + resolution: {integrity: sha512-VVsAyGqErT9D1SY4aEqozThXMVI+ssVRiv2DDeYuvpBKLIgZ3hYs3Ay3u/VSoKq6ESFi9cf6rf3IOOzfwh7oMA==} + + '@peculiar/asn1-ecc@2.7.0': + resolution: {integrity: sha512-n7KEs/Q/wrB415cxy4fHOBhegp4NdJ15fkJPwcB/3/8iNBQC2L/N7SChJPKDJPZGYH0jD4Tg4/0vnHmwghnbKw==} + + '@peculiar/asn1-pfx@2.7.0': + resolution: {integrity: sha512-V/nrlQVmhg7lYAsM7E13UDL5erAwFv6kCIVFqNaMIHSVi7dngcT839JkRTkQBqznMG98l2XjxYk74ZztAohZzA==} + + '@peculiar/asn1-pkcs8@2.7.0': + resolution: {integrity: sha512-9GTl1nE8Mx1kTZ+7QyYatDyKsm34QcWRBFkY1iPvWC3X4Dona5s/tlLiQsx5WzVdZqiMBZNYT0buyw4/vbhnjw==} + + '@peculiar/asn1-pkcs9@2.7.0': + resolution: {integrity: sha512-Bh7m+OuIaSEllPQcSd9OSp93F4ROWH7sbITWV8MI+8dwsjE5111/87VxiWVvYFKyww3vp39geLv9ENqhwWHcew==} + + '@peculiar/asn1-rsa@2.7.0': + resolution: {integrity: sha512-/qvENQrXyTZURjMqSeofHul0JJt2sNSzSwk36pl2olkHbaioMQgrASDZAlHXl0xUlnVbHj0uGgOrBMTb5x2aJQ==} + + '@peculiar/asn1-schema@2.7.0': + resolution: {integrity: sha512-W8ZfWzLmQnrcky+eh3tni4IozMdqBDiHWU0N+vve/UGjMaUs8c0L7A2oEdkBXS8rTpWDpK/aoI3DG/L/hxmxPg==} + + '@peculiar/asn1-x509-attr@2.7.0': + resolution: {integrity: sha512-NS8e7SOgXipkzUPLF/sce7ukpMpWjhxYsH0n6Y+bHYo4TTxOb95Zv7hqwSuL212mj5YxovjdOKQOgH1As3E94w==} + + '@peculiar/asn1-x509@2.7.0': + resolution: {integrity: sha512-mUn9RRrkGDnG4ALfunDmzyRW5dg+sWCj/pfnCCqEHYbkGxEpvUt6iVJv8Yw1cyp6SWZ26ZE5oSmI5SqEaen15g==} + + '@peculiar/utils@2.0.3': + resolution: {integrity: sha512-+oL3HPFRIZ1St2K50lWCXiioIgSoxzz7R1J3uF6neO2yl1sgmpgY6XXJH4BdpoDkMWznQTeYF6oWNDZLCdQ4eQ==} + + '@peculiar/x509@1.14.3': + resolution: {integrity: sha512-C2Xj8FZ0uHWeCXXqX5B4/gVFQmtSkiuOolzAgutjTfseNOHT3pUjljDZsTSxXFGgio54bCzVFqmEOUrIVk8RDA==} + engines: {node: '>=20.0.0'} + '@photo-sphere-viewer/core@5.14.1': resolution: {integrity: sha512-qrwUudrX9YZms4c2shlY/H3jUP0oh9FyGEqIDr/95ulNZgKbhQ6C/i8zDQ4j8ooFR4+z5FDORQtGvLgPyX8VCA==} @@ -4131,8 +4361,8 @@ packages: resolution: {integrity: sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==} engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} - '@playwright/test@1.59.1': - resolution: {integrity: sha512-PG6q63nQg5c9rIi4/Z5lR5IVF7yU5MqmKaPOe0HSc0O2cX1fPi96sUQu5j7eo4gKCkB2AnNGoWt7y4/Xx3Kcqg==} + '@playwright/test@1.60.0': + resolution: {integrity: sha512-O71yZIbAh/PxDMNGns37GHBIfrVkEVyn+AXyIa5dOTfb4/xNvRWV+Vv/NMbNCtODB/pO7vLlF2OTmMVLhmr7Ag==} engines: {node: '>=18'} hasBin: true @@ -4144,8 +4374,8 @@ packages: resolution: {integrity: sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA==} engines: {node: '>=12.22.0'} - '@pnpm/npm-conf@2.3.1': - resolution: {integrity: sha512-c83qWb22rNRuB0UaVCI0uRPNRr8Z0FWnEIvT47jiHAmOIUHbBOg5XvV7pM5x+rKn9HRpjxquDbXYSXr3fAKFcw==} + '@pnpm/npm-conf@3.0.2': + resolution: {integrity: sha512-h104Kh26rR8tm+a3Qkc5S4VLYint3FE48as7+/5oCEcKR2idC/pF1G6AhIXKI+eHPJa/3J9i5z0Al47IeGHPkA==} engines: {node: '>=12'} '@polka/url@1.0.0-next.29': @@ -4157,20 +4387,20 @@ packages: '@protobufjs/base64@1.1.2': resolution: {integrity: sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==} - '@protobufjs/codegen@2.0.4': - resolution: {integrity: sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==} + '@protobufjs/codegen@2.0.5': + resolution: {integrity: sha512-zgXFLzW3Ap33e6d0Wlj4MGIm6Ce8O89n/apUaGNB/jx+hw+ruWEp7EwGUshdLKVRCxZW12fp9r40E1mQrf/34g==} '@protobufjs/eventemitter@1.1.0': resolution: {integrity: sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==} - '@protobufjs/fetch@1.1.0': - resolution: {integrity: sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==} + '@protobufjs/fetch@1.1.1': + resolution: {integrity: sha512-GpptLrs57adMSuHi3VNj0mAF8dwh36LMaYF6XyJ6JMWlVsc+t42tm1HSEDmOs3A8fC9yyeisgLhsTVQokOZ0zw==} '@protobufjs/float@1.0.2': resolution: {integrity: sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==} - '@protobufjs/inquire@1.1.0': - resolution: {integrity: sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==} + '@protobufjs/inquire@1.1.2': + resolution: {integrity: sha512-pa0vFRuws4wkvaXKK1uXZMAwAX4/t8ANaJo45iw/oQHNQ9q5xUzwgFmVJGXiga2BeN+zpX7Vf9vmsiIa2J+MUw==} '@protobufjs/path@1.1.2': resolution: {integrity: sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==} @@ -4178,8 +4408,8 @@ packages: '@protobufjs/pool@1.1.0': resolution: {integrity: sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==} - '@protobufjs/utf8@1.1.0': - resolution: {integrity: sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==} + '@protobufjs/utf8@1.1.1': + resolution: {integrity: sha512-oOAWABowe8EAbMyWKM0tYDKi8Yaox52D+HWZhAIJqQXbqe0xI/GV7FhLWqlEKreMkfDjshR5FKgi3mnle0h6Eg==} '@react-email/body@0.3.0': resolution: {integrity: sha512-uGo0BOOzjbMUo3lu+BIDWayvn5o6Xyfmnlla5VGf05n8gHMvO1ll7U4FtzWe3hxMLwt53pmc4iE0M+B5slG+Ug==} @@ -4300,8 +4530,8 @@ packages: react: ^18.0 || ^19.0 || ^19.0.0-rc react-dom: ^18.0 || ^19.0 || ^19.0.0-rc - '@react-email/render@2.0.7': - resolution: {integrity: sha512-XCsqujKURb4egU8+z7RX1/yxRx1Qo89uGhy6UXyB5Oxq1SK+48t0AD/3qeuDGgDvyS+Ti+0oDT3nn5/dcG4Ttg==} + '@react-email/render@2.0.8': + resolution: {integrity: sha512-5udvVr3U/WuGJZfLdLBOhkzrqRWd2Q5ZYmF7ppcy7FzWcwgshdqLMNqJOXcVzAXJXg/2bm7D+WGJzTtZOZMQnQ==} engines: {node: '>=20.0.0'} peerDependencies: react: ^18.0 || ^19.0 || ^19.0.0-rc @@ -4374,103 +4604,103 @@ packages: '@codemirror/state': ^6.0.0 '@codemirror/view': ^6.0.0 - '@rolldown/binding-android-arm64@1.0.0-rc.17': - resolution: {integrity: sha512-s70pVGhw4zqGeFnXWvAzJDlvxhlRollagdCCKRgOsgUOH3N1l0LIxf83AtGzmb5SiVM4Hjl5HyarMRfdfj3DaQ==} + '@rolldown/binding-android-arm64@1.0.1': + resolution: {integrity: sha512-fJI3I0r3C3Oj/zdBCpaCmBRZYf07xpaq4yCfDDoSFm+beWNzbIl26puW8RraUdugoJw/95zerNOn6jasAhzSmg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [android] - '@rolldown/binding-darwin-arm64@1.0.0-rc.17': - resolution: {integrity: sha512-4ksWc9n0mhlZpZ9PMZgTGjeOPRu8MB1Z3Tz0Mo02eWfWCHMW1zN82Qz/pL/rC+yQa+8ZnutMF0JjJe7PjwasYw==} + '@rolldown/binding-darwin-arm64@1.0.1': + resolution: {integrity: sha512-cKnAhWEsV7TPcA/5EAteDp6KcJZBQ2G+BqE7zayMMi7kMvwRsbv7WT9aOnn0WNl4SKEIf43vjS31iUPu80nzXg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] - '@rolldown/binding-darwin-x64@1.0.0-rc.17': - resolution: {integrity: sha512-SUSDOI6WwUVNcWxd02QEBjLdY1VPHvlEkw6T/8nYG322iYWCTxRb1vzk4E+mWWYehTp7ERibq54LSJGjmouOsw==} + '@rolldown/binding-darwin-x64@1.0.1': + resolution: {integrity: sha512-YKrVwQjIRBPo+5G/u03wGjbdy4q7pyzCe93DK9VJ7zkVmeg8LJ7GbgsiHWdR4xSoe4CAXRD7Bcjgbtr64bkXNg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] - '@rolldown/binding-freebsd-x64@1.0.0-rc.17': - resolution: {integrity: sha512-hwnz3nw9dbJ05EDO/PvcjaaewqqDy7Y1rn1UO81l8iIK1GjenME75dl16ajbvSSMfv66WXSRCYKIqfgq2KCfxw==} + '@rolldown/binding-freebsd-x64@1.0.1': + resolution: {integrity: sha512-z/oBsREo46SsFqBwYtFe0kpJeBijAT48O/WXLI4suiCLBkr03RTtTJMCzSdDd2znlh8VJizL09XVkQgk8IZonw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] - '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.17': - resolution: {integrity: sha512-IS+W7epTcwANmFSQFrS1SivEXHtl1JtuQA9wlxrZTcNi6mx+FDOYrakGevvvTwgj2JvWiK8B29/qD9BELZPyXQ==} + '@rolldown/binding-linux-arm-gnueabihf@1.0.1': + resolution: {integrity: sha512-ik8q7GM11zxvYxFc2PeDcT6TBvhCQMaUxfph/M5l9sKuTs/Sjg3L+Byw0F7w0ZVLBZmx30P+gG0ECzzN+MFcmQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.17': - resolution: {integrity: sha512-e6usGaHKW5BMNZOymS1UcEYGowQMWcgZ71Z17Sl/h2+ZziNJ1a9n3Zvcz6LdRyIW5572wBCTH/Z+bKuZouGk9Q==} + '@rolldown/binding-linux-arm64-gnu@1.0.1': + resolution: {integrity: sha512-QoSx2EkyrrdZ6kcyE8stqZ62t0Yra8Fs5ia9lOxJrh6TMQJK7gQKmscdTHf7pOXKREKrVwOtJcQG3qVSfc866A==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [glibc] - '@rolldown/binding-linux-arm64-musl@1.0.0-rc.17': - resolution: {integrity: sha512-b/CgbwAJpmrRLp02RPfhbudf5tZnN9nsPWK82znefso832etkem8H7FSZwxrOI9djcdTP7U6YfNhbRnh7djErg==} + '@rolldown/binding-linux-arm64-musl@1.0.1': + resolution: {integrity: sha512-uwNwFpwKeNiZawfAWBgg0VIztPTV3ihhh1vV334h9ivnNLorxnQMU6Fz8wG1Zb4Qh9LC1/MkcyT3YlDXG3Rsgg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [musl] - '@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.17': - resolution: {integrity: sha512-4EII1iNGRUN5WwGbF/kOh/EIkoDN9HsupgLQoXfY+D1oyJm7/F4t5PYU5n8SWZgG0FEwakyM8pGgwcBYruGTlA==} + '@rolldown/binding-linux-ppc64-gnu@1.0.1': + resolution: {integrity: sha512-zY1bul7OWr7DFBiJ++wofXvnr8B45ce3QsQUhKrIhXsygAh7bTkwyeM1bi1a2g5C/yC/N8TZyGDEoMfm/l9mpg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ppc64] os: [linux] libc: [glibc] - '@rolldown/binding-linux-s390x-gnu@1.0.0-rc.17': - resolution: {integrity: sha512-AH8oq3XqQo4IibpVXvPeLDI5pzkpYn0WiZAfT05kFzoJ6tQNzwRdDYQ45M8I/gslbodRZwW8uxLhbSBbkv96rA==} + '@rolldown/binding-linux-s390x-gnu@1.0.1': + resolution: {integrity: sha512-0frlsT/f4Ft6I7SMESTKnF3cZsdicQn1dCMkF/jT9wDLE+gGoiQfv1nmT9e+s7s/fekvvy6tZM2jHvI2tkbJDQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [s390x] os: [linux] libc: [glibc] - '@rolldown/binding-linux-x64-gnu@1.0.0-rc.17': - resolution: {integrity: sha512-cLnjV3xfo7KslbU41Z7z8BH/E1y5mzUYzAqih1d1MDaIGZRCMqTijqLv76/P7fyHuvUcfGsIpqCdddbxLLK9rA==} + '@rolldown/binding-linux-x64-gnu@1.0.1': + resolution: {integrity: sha512-XABVmGp9Tg0WspTVvwduTc4fpqy6JnAUrSQe6OuyqD/03nI7r0O9OWUkMIwFrjKAIqolvqoA4ZrJppgwE0Gxmw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [glibc] - '@rolldown/binding-linux-x64-musl@1.0.0-rc.17': - resolution: {integrity: sha512-0phclDw1spsL7dUB37sIARuis2tAgomCJXAHZlpt8PXZ4Ba0dRP1e+66lsRqrfhISeN9bEGNjQs+T/Fbd7oYGw==} + '@rolldown/binding-linux-x64-musl@1.0.1': + resolution: {integrity: sha512-bV4fzswuzVcKD90o/VM6QqKxnxlDq0g2BISDLNVmxrnhpv1DDbyPhCIjYfvzYLV+MvkKKnQt2Q6AO86SEBULUQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [musl] - '@rolldown/binding-openharmony-arm64@1.0.0-rc.17': - resolution: {integrity: sha512-0ag/hEgXOwgw4t8QyQvUCxvEg+V0KBcA6YuOx9g0r02MprutRF5dyljgm3EmR02O292UX7UeS6HzWHAl6KgyhA==} + '@rolldown/binding-openharmony-arm64@1.0.1': + resolution: {integrity: sha512-/Mh0Zhq3OP7fVs0kcQHZP6lZEthMGTaSf8UBQYSFEZDWGXXlEC+nJ6EqenaK2t4LBXMe3A+K/G2BVXXdtOr4PQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [openharmony] - '@rolldown/binding-wasm32-wasi@1.0.0-rc.17': - resolution: {integrity: sha512-LEXei6vo0E5wTGwpkJ4KoT3OZJRnglwldt5ziLzOlc6qqb55z4tWNq2A+PFqCJuvWWdP53CVhG1Z9NtToDPJrA==} + '@rolldown/binding-wasm32-wasi@1.0.1': + resolution: {integrity: sha512-+1xc9X45l8ufsBAm6Gjvx2qDRIY9lTVt0cgWNcJ+1gdhXvkbxePA60yRTwSTuXL09CMhyJmjpV7E3NoyxbqFQQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [wasm32] - '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.17': - resolution: {integrity: sha512-gUmyzBl3SPMa6hrqFUth9sVfcLBlYsbMzBx5PlexMroZStgzGqlZ26pYG89rBb45Mnia+oil6YAIFeEWGWhoZA==} + '@rolldown/binding-win32-arm64-msvc@1.0.1': + resolution: {integrity: sha512-1D+UqZdfnuR+Jy1GgMJwi85bD40H21uNmOPRWQhw4oRSuolZ/B5rixZ45DK2KXOTCvmVCecauWgEhbw8bI7tOw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [win32] - '@rolldown/binding-win32-x64-msvc@1.0.0-rc.17': - resolution: {integrity: sha512-3hkiolcUAvPB9FLb3UZdfjVVNWherN1f/skkGWJP/fgSQhYUZpSIRr0/I8ZK9TkF3F7kxvJAk0+IcKvPHk9qQg==} + '@rolldown/binding-win32-x64-msvc@1.0.1': + resolution: {integrity: sha512-INAycaWuhlOK3wk4mRHGsdgwYWmd9cChdPdE9bwWmy6rn9VqVNYNFGhOdXrofXUxwHIncSiPNb8tNm8knDVIeQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [win32] - '@rolldown/pluginutils@1.0.0-rc.17': - resolution: {integrity: sha512-n8iosDOt6Ig1UhJ2AYqoIhHWh/isz0xpicHTzpKBeotdVsTEcxsSA/i3EVM7gQAj0rU27OLAxCjzlj15IWY7bg==} + '@rolldown/pluginutils@1.0.1': + resolution: {integrity: sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==} '@rollup/pluginutils@5.3.0': resolution: {integrity: sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==} @@ -4481,141 +4711,141 @@ packages: rollup: optional: true - '@rollup/rollup-android-arm-eabi@4.55.1': - resolution: {integrity: sha512-9R0DM/ykwfGIlNu6+2U09ga0WXeZ9MRC2Ter8jnz8415VbuIykVuc6bhdrbORFZANDmTDvq26mJrEVTl8TdnDg==} + '@rollup/rollup-android-arm-eabi@4.60.4': + resolution: {integrity: sha512-F5QXMSiFebS9hKZj02XhWLLnRpJ3B3AROP0tWbFBSj+6kCbg5m9j5JoHKd4mmSVy5mS/IMQloYgYxCuJC0fxEQ==} cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.55.1': - resolution: {integrity: sha512-eFZCb1YUqhTysgW3sj/55du5cG57S7UTNtdMjCW7LwVcj3dTTcowCsC8p7uBdzKsZYa8J7IDE8lhMI+HX1vQvg==} + '@rollup/rollup-android-arm64@4.60.4': + resolution: {integrity: sha512-GxxTKApUpzRhof7poWvCJHRF51C67u1R7D6DiluBE8wKU1u5GWE8t+v81JvJYtbawoBFX1hLv5Ei4eVjkWokaw==} cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.55.1': - resolution: {integrity: sha512-p3grE2PHcQm2e8PSGZdzIhCKbMCw/xi9XvMPErPhwO17vxtvCN5FEA2mSLgmKlCjHGMQTP6phuQTYWUnKewwGg==} + '@rollup/rollup-darwin-arm64@4.60.4': + resolution: {integrity: sha512-tua0TaJxMOB1R0V0RS1jFZ/RpURFDJIOR2A6jWwQeawuFyS4gBW+rntLRaQd0EQ4bd6Vp44Z2rXW+YYDBsj6IA==} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.55.1': - resolution: {integrity: sha512-rDUjG25C9qoTm+e02Esi+aqTKSBYwVTaoS1wxcN47/Luqef57Vgp96xNANwt5npq9GDxsH7kXxNkJVEsWEOEaQ==} + '@rollup/rollup-darwin-x64@4.60.4': + resolution: {integrity: sha512-CSKq7MsP+5PFIcydhAiR1K0UhEI1A2jWXVKHPCBZ151yOutENwvnPocgVHkivu2kviURtCEB6zUQw0vs8RrhMg==} cpu: [x64] os: [darwin] - '@rollup/rollup-freebsd-arm64@4.55.1': - resolution: {integrity: sha512-+JiU7Jbp5cdxekIgdte0jfcu5oqw4GCKr6i3PJTlXTCU5H5Fvtkpbs4XJHRmWNXF+hKmn4v7ogI5OQPaupJgOg==} + '@rollup/rollup-freebsd-arm64@4.60.4': + resolution: {integrity: sha512-+O8OkVdyvXMtJEciu2wS/pzm1IxntEEQx3z5TAVy4l32G0etZn+RsA48ARRrFm6Ri8fvqPQfgrvNxSjKAbnd3g==} cpu: [arm64] os: [freebsd] - '@rollup/rollup-freebsd-x64@4.55.1': - resolution: {integrity: sha512-V5xC1tOVWtLLmr3YUk2f6EJK4qksksOYiz/TCsFHu/R+woubcLWdC9nZQmwjOAbmExBIVKsm1/wKmEy4z4u4Bw==} + '@rollup/rollup-freebsd-x64@4.60.4': + resolution: {integrity: sha512-Iw3oMskH3AfNuhU0MSN7vNbdi4me/NiYo2azqPz/Le16zHSa+3RRmliCMWWQmh4lcndccU40xcJuTYJZxNo/lw==} cpu: [x64] os: [freebsd] - '@rollup/rollup-linux-arm-gnueabihf@4.55.1': - resolution: {integrity: sha512-Rn3n+FUk2J5VWx+ywrG/HGPTD9jXNbicRtTM11e/uorplArnXZYsVifnPPqNNP5BsO3roI4n8332ukpY/zN7rQ==} + '@rollup/rollup-linux-arm-gnueabihf@4.60.4': + resolution: {integrity: sha512-EIPRXTVQpHyF8WOo219AD2yEltPehLTcTMz2fn6JsatLYSzQf00hj3rulF+yauOlF9/FtM2WpkT/hJh/KJFGhA==} cpu: [arm] os: [linux] libc: [glibc] - '@rollup/rollup-linux-arm-musleabihf@4.55.1': - resolution: {integrity: sha512-grPNWydeKtc1aEdrJDWk4opD7nFtQbMmV7769hiAaYyUKCT1faPRm2av8CX1YJsZ4TLAZcg9gTR1KvEzoLjXkg==} + '@rollup/rollup-linux-arm-musleabihf@4.60.4': + resolution: {integrity: sha512-J3Yh9PzzF1Ovah2At+lHiGQdsYgArxBbXv/zHfSyaiFQEqvNv7DcW98pCrmdjCZBrqBiKrKKe2V+aaSGWuBe/w==} cpu: [arm] os: [linux] libc: [musl] - '@rollup/rollup-linux-arm64-gnu@4.55.1': - resolution: {integrity: sha512-a59mwd1k6x8tXKcUxSyISiquLwB5pX+fJW9TkWU46lCqD/GRDe9uDN31jrMmVP3feI3mhAdvcCClhV8V5MhJFQ==} + '@rollup/rollup-linux-arm64-gnu@4.60.4': + resolution: {integrity: sha512-BFDEZMYfUvLn37ONE1yMBojPxnMlTFsdyNoqncT0qFq1mAfllL+ATMMJd8TeuVMiX84s1KbcxcZbXInmcO2mRg==} cpu: [arm64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-arm64-musl@4.55.1': - resolution: {integrity: sha512-puS1MEgWX5GsHSoiAsF0TYrpomdvkaXm0CofIMG5uVkP6IBV+ZO9xhC5YEN49nsgYo1DuuMquF9+7EDBVYu4uA==} + '@rollup/rollup-linux-arm64-musl@4.60.4': + resolution: {integrity: sha512-pc9EYOSlOgdQ2uPl1o9PF6/kLSgaUosia7gOuS8mB69IxJvlclko1MECXysjs5ryez1/5zjYqx3+xYU0TU6R1A==} cpu: [arm64] os: [linux] libc: [musl] - '@rollup/rollup-linux-loong64-gnu@4.55.1': - resolution: {integrity: sha512-r3Wv40in+lTsULSb6nnoudVbARdOwb2u5fpeoOAZjFLznp6tDU8kd+GTHmJoqZ9lt6/Sys33KdIHUaQihFcu7g==} + '@rollup/rollup-linux-loong64-gnu@4.60.4': + resolution: {integrity: sha512-NxnomyxYerDh5n4iLrNa+sH+Z+U4BMEE46V2PgQ/hoB909i8gV1M5wPojWg9fk1jWpO3IQnOs20K4wyZuFLEFQ==} cpu: [loong64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-loong64-musl@4.55.1': - resolution: {integrity: sha512-MR8c0+UxAlB22Fq4R+aQSPBayvYa3+9DrwG/i1TKQXFYEaoW3B5b/rkSRIypcZDdWjWnpcvxbNaAJDcSbJU3Lw==} + '@rollup/rollup-linux-loong64-musl@4.60.4': + resolution: {integrity: sha512-nbJnQ8a3z1mtmrwImCYhc6BGpThAyYVRQxw9uKSKG4wR6aAYno9sVjJ0zaZcW9BPJX1GbrDPf+SvdWjgTuDmnw==} cpu: [loong64] os: [linux] libc: [musl] - '@rollup/rollup-linux-ppc64-gnu@4.55.1': - resolution: {integrity: sha512-3KhoECe1BRlSYpMTeVrD4sh2Pw2xgt4jzNSZIIPLFEsnQn9gAnZagW9+VqDqAHgm1Xc77LzJOo2LdigS5qZ+gw==} + '@rollup/rollup-linux-ppc64-gnu@4.60.4': + resolution: {integrity: sha512-2EU6acNrQLd8tYvo/LXW535wupT3m6fo7HKo6lr7ktQoItxTyOL1ZCR/GfGCuXl2vR+zmfI6eRXkSemafv+iVg==} cpu: [ppc64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-ppc64-musl@4.55.1': - resolution: {integrity: sha512-ziR1OuZx0vdYZZ30vueNZTg73alF59DicYrPViG0NEgDVN8/Jl87zkAPu4u6VjZST2llgEUjaiNl9JM6HH1Vdw==} + '@rollup/rollup-linux-ppc64-musl@4.60.4': + resolution: {integrity: sha512-WeBtoMuaMxiiIrO2IYP3xs6GMWkJP2C0EoT8beTLkUPmzV1i/UcOSVw1d5r9KBODtHKilG5yFxsGRnBbK3wJ4A==} cpu: [ppc64] os: [linux] libc: [musl] - '@rollup/rollup-linux-riscv64-gnu@4.55.1': - resolution: {integrity: sha512-uW0Y12ih2XJRERZ4jAfKamTyIHVMPQnTZcQjme2HMVDAHY4amf5u414OqNYC+x+LzRdRcnIG1YodLrrtA8xsxw==} + '@rollup/rollup-linux-riscv64-gnu@4.60.4': + resolution: {integrity: sha512-FJHFfqpKUI3A10WrWKiFbBZ7yVbGT4q4B5o1qKFFojqpaYoh9LrQgqWCmmcxQzVSXYtyB5bzkXrYzlHTs21MYA==} cpu: [riscv64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-riscv64-musl@4.55.1': - resolution: {integrity: sha512-u9yZ0jUkOED1BFrqu3BwMQoixvGHGZ+JhJNkNKY/hyoEgOwlqKb62qu+7UjbPSHYjiVy8kKJHvXKv5coH4wDeg==} + '@rollup/rollup-linux-riscv64-musl@4.60.4': + resolution: {integrity: sha512-mcEl6CUT5IAUmQf1m9FYSmVqCJlpQ8r8eyftFUHG8i9OhY7BkBXSUdnLH5DOf0wCOjcP9v/QO93zpmF1SptCCw==} cpu: [riscv64] os: [linux] libc: [musl] - '@rollup/rollup-linux-s390x-gnu@4.55.1': - resolution: {integrity: sha512-/0PenBCmqM4ZUd0190j7J0UsQ/1nsi735iPRakO8iPciE7BQ495Y6msPzaOmvx0/pn+eJVVlZrNrSh4WSYLxNg==} + '@rollup/rollup-linux-s390x-gnu@4.60.4': + resolution: {integrity: sha512-ynt3JxVd2w2buzoKDWIyiV1pJW93xlQic1THVLXilz429oijRpSHivZAgp65KBu+cMcgf1eVVjdnTLvPxgCuoQ==} cpu: [s390x] os: [linux] libc: [glibc] - '@rollup/rollup-linux-x64-gnu@4.55.1': - resolution: {integrity: sha512-a8G4wiQxQG2BAvo+gU6XrReRRqj+pLS2NGXKm8io19goR+K8lw269eTrPkSdDTALwMmJp4th2Uh0D8J9bEV1vg==} + '@rollup/rollup-linux-x64-gnu@4.60.4': + resolution: {integrity: sha512-Boiz5+MsaROEWDf+GGEwF8VMHGhlUoQMtIPjOgA5fv4osupqTVnJteQNKJwUcnUog2G55jYXH7KZFFiJe0TEzQ==} cpu: [x64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-x64-musl@4.55.1': - resolution: {integrity: sha512-bD+zjpFrMpP/hqkfEcnjXWHMw5BIghGisOKPj+2NaNDuVT+8Ds4mPf3XcPHuat1tz89WRL+1wbcxKY3WSbiT7w==} + '@rollup/rollup-linux-x64-musl@4.60.4': + resolution: {integrity: sha512-+qfSY27qIrFfI/Hom04KYFw3GKZSGU4lXus51wsb5EuySfFlWRwjkKWoE9emgRw/ukoT4Udsj4W/+xxG8VbPKg==} cpu: [x64] os: [linux] libc: [musl] - '@rollup/rollup-openbsd-x64@4.55.1': - resolution: {integrity: sha512-eLXw0dOiqE4QmvikfQ6yjgkg/xDM+MdU9YJuP4ySTibXU0oAvnEWXt7UDJmD4UkYialMfOGFPJnIHSe/kdzPxg==} + '@rollup/rollup-openbsd-x64@4.60.4': + resolution: {integrity: sha512-VpTfOPHgVXEBeeR8hZ2O0F3aSso+JDWqTWmTmzcQKted54IAdUVbxE+j/MVxUsKa8L20HJhv3vUezVPoquqWjA==} cpu: [x64] os: [openbsd] - '@rollup/rollup-openharmony-arm64@4.55.1': - resolution: {integrity: sha512-xzm44KgEP11te3S2HCSyYf5zIzWmx3n8HDCc7EE59+lTcswEWNpvMLfd9uJvVX8LCg9QWG67Xt75AuHn4vgsXw==} + '@rollup/rollup-openharmony-arm64@4.60.4': + resolution: {integrity: sha512-IPOsh5aRYuLv/nkU51X10Bf75Bsf6+gZdx1X+QP5QM6lIJFHHqbHLG0uJn/hWthzo13UAc2umiUorqZy3axoZg==} cpu: [arm64] os: [openharmony] - '@rollup/rollup-win32-arm64-msvc@4.55.1': - resolution: {integrity: sha512-yR6Bl3tMC/gBok5cz/Qi0xYnVbIxGx5Fcf/ca0eB6/6JwOY+SRUcJfI0OpeTpPls7f194as62thCt/2BjxYN8g==} + '@rollup/rollup-win32-arm64-msvc@4.60.4': + resolution: {integrity: sha512-4QzE9E81OohJ/HKzHhsqU+zcYYojVOXlFMs1DdyMT6qXl/niOH7AVElmmEdUNHHS/oRkc++d5k6Vy85zFs0DEw==} cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.55.1': - resolution: {integrity: sha512-3fZBidchE0eY0oFZBnekYCfg+5wAB0mbpCBuofh5mZuzIU/4jIVkbESmd2dOsFNS78b53CYv3OAtwqkZZmU5nA==} + '@rollup/rollup-win32-ia32-msvc@4.60.4': + resolution: {integrity: sha512-zTPgT1YuHHcd+Tmx7h8aml0FWFVelV5N54oHow9SLj+GfoDy/huQ+UV396N/C7KpMDMiPspRktzM1/0r1usYEA==} cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-gnu@4.55.1': - resolution: {integrity: sha512-xGGY5pXj69IxKb4yv/POoocPy/qmEGhimy/FoTpTSVju3FYXUQQMFCaZZXJVidsmGxRioZAwpThl/4zX41gRKg==} + '@rollup/rollup-win32-x64-gnu@4.60.4': + resolution: {integrity: sha512-DRS4G7mi9lJxqEDezIkKCaUIKCrLUUDCUaCsTPCi/rtqaC6D/jjwslMQyiDU50Ka0JKpeXeRBFBAXwArY52vBw==} cpu: [x64] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.55.1': - resolution: {integrity: sha512-SPEpaL6DX4rmcXtnhdrQYgzQ5W2uW3SCJch88lB2zImhJRhIIK44fkUrgIV/Q8yUNfw5oyZ5vkeQsZLhCb06lw==} + '@rollup/rollup-win32-x64-msvc@4.60.4': + resolution: {integrity: sha512-QVTUovf40zgTqlFVrKA1uXMVvU2QWEFWfAH8Wdc48IxLvrJMQVMBRjuQyUpzZCDkakImib9eVazbWlC6ksWtJw==} cpu: [x64] os: [win32] @@ -4634,8 +4864,8 @@ packages: '@sideway/pinpoint@2.0.0': resolution: {integrity: sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==} - '@sinclair/typebox@0.27.8': - resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} + '@sinclair/typebox@0.27.10': + resolution: {integrity: sha512-MTBk/3jGLNB2tVxv6uLlFh1iu64iYOQ2PbdOSK3NW8JZsmlaOh2q6sdtKowBhfw8QFLmYNzTW4/oK4uATIi6ZA==} '@sindresorhus/is@4.6.0': resolution: {integrity: sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==} @@ -4669,8 +4899,8 @@ packages: '@standard-schema/spec@1.1.0': resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} - '@sveltejs/acorn-typescript@1.0.9': - resolution: {integrity: sha512-lVJX6qEgs/4DOcRTpo56tmKzVPtoWAaVbL4hfO7t7NVwl9AAXzQR6cihesW1BmNMPl+bK6dreu2sOKBP2Q9CIA==} + '@sveltejs/acorn-typescript@1.0.10': + resolution: {integrity: sha512-4WfKk68eTih+MiJD4fSbxN7E8kVBmTMPWHUPYjvl2N0rMs53YLTT8/YjKU5Dtnz5LqDjl7LEw4U7lXR2W3J5WA==} peerDependencies: acorn: ^8.9.0 @@ -4686,8 +4916,8 @@ packages: svelte: ^5.0.0 vite: ^6.3.0 || >=7.0.0 - '@sveltejs/kit@2.57.1': - resolution: {integrity: sha512-VRdSbB96cI1EnRh09CqmnQqP/YJvET5buj8S6k7CxaJqBJD4bw4fRKDjcarAj/eX9k2eHifQfDH8NtOh+ZxxPw==} + '@sveltejs/kit@2.60.1': + resolution: {integrity: sha512-mQjlkNo+rJvpln7V2IGY2j99BqhcFbS4UN0AQNKNYfhBAFZTuCDAdW3a1sgf330mvtNvsBXn3HpAhcmvdJTcIQ==} engines: {node: '>=18.13'} hasBin: true peerDependencies: @@ -4702,8 +4932,8 @@ packages: typescript: optional: true - '@sveltejs/vite-plugin-svelte@7.0.0': - resolution: {integrity: sha512-ILXmxC7HAsnkK2eslgPetrqqW1BKSL7LktsFgqzNj83MaivMGZzluWq32m25j2mDOjmSKX7GGWahePhuEs7P/g==} + '@sveltejs/vite-plugin-svelte@7.1.2': + resolution: {integrity: sha512-DrUBA2UXRfDmUX/ZTiEopd3X40yavsJF1FX2RygcuIScHL7o5YX1fMvoYnDhjeJQC4weCOklirpNWlcb2NiSeA==} engines: {node: ^20.19 || ^22.12 || >=24} peerDependencies: svelte: ^5.46.4 @@ -4787,86 +5017,86 @@ packages: resolution: {integrity: sha512-LnhVjMWyMQV9ZmeEy26maJk+8HTIbd59cH4F2MJ439k9DqejRisfFNGAPvRYlKETuh9LrImlS8aKsBgKjMA8WA==} engines: {node: '>=14'} - '@swc/core-darwin-arm64@1.15.30': - resolution: {integrity: sha512-VvpP+vq08HmGYewMWvrdsxh9s2lthz/808zXm8Yu5kaqeR8Yia2b0eYXleHQ3VAjoStUDk6LzTheBW9KXYQdMA==} + '@swc/core-darwin-arm64@1.15.33': + resolution: {integrity: sha512-N+L0uXhuO7FIfzqwgxmzv0zIpV0qEp8wPX3QQs2p4atjMoywup2JTeDlXPw+z9pWJGCae3JjM+tZ6myclI+2gA==} engines: {node: '>=10'} cpu: [arm64] os: [darwin] - '@swc/core-darwin-x64@1.15.30': - resolution: {integrity: sha512-WiJA0hiZI3nwQAO6mu5RqigtWGDtth4Hiq6rbZxAaQyhIcqKIg5IoMRc1Y071lrNJn29eEDMC86Rq58xgUxlDg==} + '@swc/core-darwin-x64@1.15.33': + resolution: {integrity: sha512-/Il4QHSOhV4FekbsDtkrNmKbsX26oSysvgrRswa/RYOHXAkwXDbB4jaeKq6PsJLSPkzJ2KzQ061gtBnk0vNHfA==} engines: {node: '>=10'} cpu: [x64] os: [darwin] - '@swc/core-linux-arm-gnueabihf@1.15.30': - resolution: {integrity: sha512-YANuFUo48kIT6plJgCD0keae9HFXfjxsbvsgevqc0hr/07X/p7sAWTFOGYEc2SXcASaK7UvuQqzlbW8pr7R79g==} + '@swc/core-linux-arm-gnueabihf@1.15.33': + resolution: {integrity: sha512-C64hBnBxq4viOPQ8hlx+2lJ23bzZBGnjw7ryALmS+0Q3zHmwO8lw1/DArLENw4Q18/0w5wdEO1k3m1wWNtKGqQ==} engines: {node: '>=10'} cpu: [arm] os: [linux] - '@swc/core-linux-arm64-gnu@1.15.30': - resolution: {integrity: sha512-VndG8jaR4ugY6u+iVOT0Q+d2fZd7sLgjPgN8W/Le+3EbZKl+cRfFxV7Eoz4gfLqhmneZPdcIzf9T3LkgkmqNLg==} + '@swc/core-linux-arm64-gnu@1.15.33': + resolution: {integrity: sha512-TRJfnJbX3jqpxRDRoieMzRiCBS5jOmXNb3iQXmcgjFEHKLnAgK1RZRU8Cq1MsPqO4jAJp/ld1G4O3fXuxv85uw==} engines: {node: '>=10'} cpu: [arm64] os: [linux] libc: [glibc] - '@swc/core-linux-arm64-musl@1.15.30': - resolution: {integrity: sha512-1SYGs2l0Yyyi0pR/P/NKz/x0kqxkoiw+BXeJjLUdecSk/KasncWlJrc6hOvFSgKHOBrzgM5jwuluKtlT8dnrcA==} + '@swc/core-linux-arm64-musl@1.15.33': + resolution: {integrity: sha512-il7tYM+CpUNzieQbwAjFT1P8zqAhmGWNAGhQZBnxurXZ0aNn+5nqYFTEUKNZl7QibtT0uQXzTZrNGHCIj6Y1Og==} engines: {node: '>=10'} cpu: [arm64] os: [linux] libc: [musl] - '@swc/core-linux-ppc64-gnu@1.15.30': - resolution: {integrity: sha512-TXREtiXeRhbfDFbmhnkIsXpKfzbfT73YkV2ZF6w0sfxgjC5zI2ZAbaCOq25qxvegofj2K93DtOpm9RLaBgqR2g==} + '@swc/core-linux-ppc64-gnu@1.15.33': + resolution: {integrity: sha512-ZtNBwN0Z7CFj9Il0FcPaKdjgP7URyKu/3RfH46vq+0paOBqLj4NYldD6Qo//Duif/7IOtAraUfDOmp0PLAufog==} engines: {node: '>=10'} cpu: [ppc64] os: [linux] libc: [glibc] - '@swc/core-linux-s390x-gnu@1.15.30': - resolution: {integrity: sha512-DCR2YYeyd6DQE4OuDhImouuNcjXEiEdnn1Y0DyGteugPEDvVuvYk8Xddi+4o2SgWH6jiW8/I+3emZvbep1NC+g==} + '@swc/core-linux-s390x-gnu@1.15.33': + resolution: {integrity: sha512-De1IyajoOmhOYYjw/lx66bKlyDpHZTueqwpDrWgf5O7T6d1ODeJJO9/OqMBmrBQc5C+dNnlmIufHsp4QVCWufA==} engines: {node: '>=10'} cpu: [s390x] os: [linux] libc: [glibc] - '@swc/core-linux-x64-gnu@1.15.30': - resolution: {integrity: sha512-5Pizw3NgfOJ5BJOBK8TIRa59xFW2avESTOBDPTAYwZYa1JNDs+KMF9lUfjJiJLM5HiMs/wPheA9eiT0q9m2AoA==} + '@swc/core-linux-x64-gnu@1.15.33': + resolution: {integrity: sha512-mGTH0YxmUN+x6vRN/I6NOk5X0ogNktkwPnJ94IMvR7QjhRDwL0O8RXEDhyUM0YtwWrryBOqaJQBX4zruxEPRGw==} engines: {node: '>=10'} cpu: [x64] os: [linux] libc: [glibc] - '@swc/core-linux-x64-musl@1.15.30': - resolution: {integrity: sha512-qyqydP/wyH8alcIP4a2hnGSjHLJjm9H7yDFup+CPy9oTahFgLLwnNcv5UHXqO2Qs3AIND+cls5f/Bb6hqpxdgA==} + '@swc/core-linux-x64-musl@1.15.33': + resolution: {integrity: sha512-hj628ZkSEJf6zMf5VMbYrG2O6QqyTIp2qwY6VlCjvIa9lAEZ5c2lfPblCLVGYubTeLJDxadLB/CxqQYOQABeEQ==} engines: {node: '>=10'} cpu: [x64] os: [linux] libc: [musl] - '@swc/core-win32-arm64-msvc@1.15.30': - resolution: {integrity: sha512-CaQENgDHVGOg1mSF5sQVgvfFHG9kjMor2rkLMLeLOkfZYNj13ppnJ9+lfaBZLZUMMbnlGQnavCJb8PVBUOso7Q==} + '@swc/core-win32-arm64-msvc@1.15.33': + resolution: {integrity: sha512-GV2oohtN2/5+KSccl86VULu3aT+LrISC8uzgSq0FRnikpD+Zwc+sBlXmoKQ+Db6jI57ITUOIB8jRkdGMABC29g==} engines: {node: '>=10'} cpu: [arm64] os: [win32] - '@swc/core-win32-ia32-msvc@1.15.30': - resolution: {integrity: sha512-30VdLeGk6fugiUs/kUdJ/pAg7z/zpvVbR11RH60jZ0Z42WIeIniYx0rLEWN7h/pKJ3CopqsQ3RsogCAkRKiA2g==} + '@swc/core-win32-ia32-msvc@1.15.33': + resolution: {integrity: sha512-gtyvzSNR8DHKfFEA2uqb8Ld1myqi6uEg2jyeUq3ikn5ytYs7H8RpZYC8mdy4NXr8hfcdJfCLXPlYaqqfBXpoEQ==} engines: {node: '>=10'} cpu: [ia32] os: [win32] - '@swc/core-win32-x64-msvc@1.15.30': - resolution: {integrity: sha512-4iObHPR+Q4oDY110EF5SF5eIaaVJNpMdG9C0q3Q92BsJ5y467uHz7sYQhP60WYlLFsLQ1el2YrIPUItUAQGOKg==} + '@swc/core-win32-x64-msvc@1.15.33': + resolution: {integrity: sha512-d6fRqQSkJI+kmMEBWaDQ7TMl8+YjLYbwRUPZQ9DY0ORBJeTzOrG0twvfvlZ2xgw6jA0ScQKgfBm4vHLSLl5Hqg==} engines: {node: '>=10'} cpu: [x64] os: [win32] - '@swc/core@1.15.30': - resolution: {integrity: sha512-R8VQbQY1BZcbIF2p3gjlTCwAQzx1A194ugWfwld5y+WgVVWqVKm7eURGGOVbQVubgKWzidP2agomBbg96rZilQ==} + '@swc/core@1.15.33': + resolution: {integrity: sha512-jOlwnFV2xhuuZeAUILGFULeR6vDPfijEJ57evfocwznQldLU3w2cZ9bSDryY9ip+AsM3r1NJKzf47V2NXebkeQ==} engines: {node: '>=10'} peerDependencies: '@swc/helpers': '>=0.5.17' @@ -4877,8 +5107,8 @@ packages: '@swc/counter@0.1.3': resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} - '@swc/helpers@0.5.21': - resolution: {integrity: sha512-jI/VAmtdjB/RnI8GTnokyX7Ug8c+g+ffD6QRLa6XQewtnGyukKkKSk3wLTM3b5cjt1jNh9x0jfVlagdN2gDKQg==} + '@swc/helpers@0.5.22': + resolution: {integrity: sha512-/e2Ly3Docn9kYByap6TV4oquJ3wQuz3c+kC74riqtkwU9CwTMeuj6t2rW+bRr4pyOx/CYQM4wr0RgaKQwGEz0A==} '@swc/types@0.1.26': resolution: {integrity: sha512-lyMwd7WGgG79RS7EERZV3T8wMdmPq3xwyg+1nmAM64kIhx5yl+juO2PYIHb7vTiPgPCj8LYjsNV2T5wiQHUEaw==} @@ -4887,69 +5117,69 @@ packages: resolution: {integrity: sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==} engines: {node: '>=14.16'} - '@tailwindcss/node@4.2.4': - resolution: {integrity: sha512-Ai7+yQPxz3ddrDQzFfBKdHEVBg0w3Zl83jnjuwxnZOsnH9pGn93QHQtpU0p/8rYWxvbFZHneni6p1BSLK4DkGA==} + '@tailwindcss/node@4.3.0': + resolution: {integrity: sha512-aFb4gUhFOgdh9AXo4IzBEOzBkkAxm9VigwDJnMIYv3lcfXCJVesNfbEaBl4BNgVRyid92AmdviqwBUBRKSeY3g==} - '@tailwindcss/oxide-android-arm64@4.2.4': - resolution: {integrity: sha512-e7MOr1SAn9U8KlZzPi1ZXGZHeC5anY36qjNwmZv9pOJ8E4Q6jmD1vyEHkQFmNOIN7twGPEMXRHmitN4zCMN03g==} + '@tailwindcss/oxide-android-arm64@4.3.0': + resolution: {integrity: sha512-TJPiq67tKlLuObP6RkwvVGDoxCMBVtDgKkLfa/uyj7/FyxvQwHS+UOnVrXXgbEsfUaMgiVvC4KbJnRr26ho4Ng==} engines: {node: '>= 20'} cpu: [arm64] os: [android] - '@tailwindcss/oxide-darwin-arm64@4.2.4': - resolution: {integrity: sha512-tSC/Kbqpz/5/o/C2sG7QvOxAKqyd10bq+ypZNf+9Fi2TvbVbv1zNpcEptcsU7DPROaSbVgUXmrzKhurFvo5eDg==} + '@tailwindcss/oxide-darwin-arm64@4.3.0': + resolution: {integrity: sha512-oMN/WZRb+SO37BmUElEgeEWuU8E/HXRkiODxJxLe1UTHVXLrdVSgfaJV7pSlhRGMSOiXLuxTIjfsF3wYvz8cgQ==} engines: {node: '>= 20'} cpu: [arm64] os: [darwin] - '@tailwindcss/oxide-darwin-x64@4.2.4': - resolution: {integrity: sha512-yPyUXn3yO/ufR6+Kzv0t4fCg2qNr90jxXc5QqBpjlPNd0NqyDXcmQb/6weunH/MEDXW5dhyEi+agTDiqa3WsGg==} + '@tailwindcss/oxide-darwin-x64@4.3.0': + resolution: {integrity: sha512-N6CUmu4a6bKVADfw77p+iw6Yd9Q3OBhe0veaDX+QazfuVYlQsHfDgxBrsjQ/IW+zywL8mTrNd0SdJT/zgtvMdA==} engines: {node: '>= 20'} cpu: [x64] os: [darwin] - '@tailwindcss/oxide-freebsd-x64@4.2.4': - resolution: {integrity: sha512-BoMIB4vMQtZsXdGLVc2z+P9DbETkiopogfWZKbWwM8b/1Vinbs4YcUwo+kM/KeLkX3Ygrf4/PsRndKaYhS8Eiw==} + '@tailwindcss/oxide-freebsd-x64@4.3.0': + resolution: {integrity: sha512-zDL5hBkQdH5C6MpqbK3gQAgP80tsMwSI26vjOzjJtNCMUo0lFgOItzHKBIupOZNQxt3ouPH7RPhvNhiTfCe5CQ==} engines: {node: '>= 20'} cpu: [x64] os: [freebsd] - '@tailwindcss/oxide-linux-arm-gnueabihf@4.2.4': - resolution: {integrity: sha512-7pIHBLTHYRAlS7V22JNuTh33yLH4VElwKtB3bwchK/UaKUPpQ0lPQiOWcbm4V3WP2I6fNIJ23vABIvoy2izdwA==} + '@tailwindcss/oxide-linux-arm-gnueabihf@4.3.0': + resolution: {integrity: sha512-R06HdNi7A7OEoMsf6d4tjZ71RCWnZQPHj2mnotSFURjNLdBC+cIgXQ7l81CqeoiQftjf6OOblxXMInMgN2VzMA==} engines: {node: '>= 20'} cpu: [arm] os: [linux] - '@tailwindcss/oxide-linux-arm64-gnu@4.2.4': - resolution: {integrity: sha512-+E4wxJ0ZGOzSH325reXTWB48l42i93kQqMvDyz5gqfRzRZ7faNhnmvlV4EPGJU3QJM/3Ab5jhJ5pCRUsKn6OQw==} + '@tailwindcss/oxide-linux-arm64-gnu@4.3.0': + resolution: {integrity: sha512-qTJHELX8jetjhRQHCLilkVLmybpzNQAtaI/gaoVoidn/ufbNDbAo8KlK2J+yPoc8wQxvDxCmh/5lr8nC1+lTbg==} engines: {node: '>= 20'} cpu: [arm64] os: [linux] libc: [glibc] - '@tailwindcss/oxide-linux-arm64-musl@4.2.4': - resolution: {integrity: sha512-bBADEGAbo4ASnppIziaQJelekCxdMaxisrk+fB7Thit72IBnALp9K6ffA2G4ruj90G9XRS2VQ6q2bCKbfFV82g==} + '@tailwindcss/oxide-linux-arm64-musl@4.3.0': + resolution: {integrity: sha512-Z6sukiQsngnWO+l39X4pPbiWT81IC+PLKF+PHxIlyZbGNb9MODfYlXEVlFvej5BOZInWX01kVyzeLvHsXhfczQ==} engines: {node: '>= 20'} cpu: [arm64] os: [linux] libc: [musl] - '@tailwindcss/oxide-linux-x64-gnu@4.2.4': - resolution: {integrity: sha512-7Mx25E4WTfnht0TVRTyC00j3i0M+EeFe7wguMDTlX4mRxafznw0CA8WJkFjWYH5BlgELd1kSjuU2JiPnNZbJDA==} + '@tailwindcss/oxide-linux-x64-gnu@4.3.0': + resolution: {integrity: sha512-DRNdQRpSGzRGfARVuVkxvM8Q12nh19l4BF/G7zGA1oe+9wcC6saFBHTISrpIcKzhiXtSrlSrluCfvMuledoCTQ==} engines: {node: '>= 20'} cpu: [x64] os: [linux] libc: [glibc] - '@tailwindcss/oxide-linux-x64-musl@4.2.4': - resolution: {integrity: sha512-2wwJRF7nyhOR0hhHoChc04xngV3iS+akccHTGtz965FwF0up4b2lOdo6kI1EbDaEXKgvcrFBYcYQQ/rrnWFVfA==} + '@tailwindcss/oxide-linux-x64-musl@4.3.0': + resolution: {integrity: sha512-Z0IADbDo8bh6I7h2IQMx601AdXBLfFpEdUotft86evd/8ZPflZe9COPO8Q1vw+pfLWIUo9zN/JGZvwuAJqduqg==} engines: {node: '>= 20'} cpu: [x64] os: [linux] libc: [musl] - '@tailwindcss/oxide-wasm32-wasi@4.2.4': - resolution: {integrity: sha512-FQsqApeor8Fo6gUEklzmaa9994orJZZDBAlQpK2Mq+DslRKFJeD6AjHpBQ0kZFQohVr8o85PPh8eOy86VlSCmw==} + '@tailwindcss/oxide-wasm32-wasi@4.3.0': + resolution: {integrity: sha512-HNZGOUxEmElksYR7S6sC5jTeNGpobAsy9u7Gu0AskJ8/20FR9GqebUyB+HBcU/ax6BHuiuJi+Oda4B+YX6H1yA==} engines: {node: '>=14.0.0'} cpu: [wasm32] bundledDependencies: @@ -4960,24 +5190,24 @@ packages: - '@emnapi/wasi-threads' - tslib - '@tailwindcss/oxide-win32-arm64-msvc@4.2.4': - resolution: {integrity: sha512-L9BXqxC4ToVgwMFqj3pmZRqyHEztulpUJzCxUtLjobMCzTPsGt1Fa9enKbOpY2iIyVtaHNeNvAK8ERP/64sqGQ==} + '@tailwindcss/oxide-win32-arm64-msvc@4.3.0': + resolution: {integrity: sha512-Pe+RPVTi1T+qymuuRpcdvwSVZjnll/f7n8gBxMMh3xLTctMDKqpdfGimbMyioqtLhUYZxdJ9wGNhV7MKHvgZsQ==} engines: {node: '>= 20'} cpu: [arm64] os: [win32] - '@tailwindcss/oxide-win32-x64-msvc@4.2.4': - resolution: {integrity: sha512-ESlKG0EpVJQwRjXDDa9rLvhEAh0mhP1sF7sap9dNZT0yyl9SAG6T7gdP09EH0vIv0UNTlo6jPWyujD6559fZvw==} + '@tailwindcss/oxide-win32-x64-msvc@4.3.0': + resolution: {integrity: sha512-Mvrf2kXW/yeW/OTezZlCGOirXRcUuLIBx/5Y12BaPM7wJoryG6dfS/NJL8aBPqtTEx/Vm4T4vKzFUcKDT+TKUA==} engines: {node: '>= 20'} cpu: [x64] os: [win32] - '@tailwindcss/oxide@4.2.4': - resolution: {integrity: sha512-9El/iI069DKDSXwTvB9J4BwdO5JhRrOweGaK25taBAvBXyXqJAX+Jqdvs8r8gKpsI/1m0LeJLyQYTf/WLrBT1Q==} + '@tailwindcss/oxide@4.3.0': + resolution: {integrity: sha512-F7HZGBeN9I0/AuuJS5PwcD8xayx5ri5GhjYUDBEVYUkexyA/giwbDNjRVrxSezE3T250OU2K/wp/ltWx3UOefg==} engines: {node: '>= 20'} - '@tailwindcss/vite@4.2.4': - resolution: {integrity: sha512-pCvohwOCspk3ZFn6eJzrrX3g4n2JY73H6MmYC87XfGPyTty4YsCjYTMArRZm/zOI8dIt3+EcrLHAFPe5A4bgtw==} + '@tailwindcss/vite@4.3.0': + resolution: {integrity: sha512-t6J3OrB5Fc0ExuhohouH0fWUGMYL6PTLhW+E7zIk/pdbnJARZDCwjBznFnkh5ynRnIRSI4YjtTH0t6USjJISrw==} peerDependencies: vite: ^5.2.0 || ^6 || ^7 || ^8 @@ -5048,21 +5278,17 @@ packages: svelte: optional: true - '@trysound/sax@0.2.0': - resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==} - engines: {node: '>=10.13.0'} + '@turf/boolean-point-in-polygon@7.3.5': + resolution: {integrity: sha512-ba7+B0wzaS9GtERZOoXUZ6oW8IcIJHNQZf3c+tiD9ESjcsPO1Q/4qIJGTKl92nBLhhracHJxMWBM/U6hAVkaRg==} - '@turf/boolean-point-in-polygon@7.3.4': - resolution: {integrity: sha512-v/4hfyY90Vz9cDgs2GwjQf+Lft8o7mNCLJOTz/iv8SHAIgMMX0czEoIaNVOJr7tBqPqwin1CGwsncrkf5C9n8Q==} + '@turf/helpers@7.3.5': + resolution: {integrity: sha512-E/NMGV5MwbjjP7AJXBtsanC3yY8N2MQ87IGdIgkB2ji5AtBpwnH4L3gEqpYN4RlCJJWbLbzO91BbKv2waUd0eg==} - '@turf/helpers@7.3.4': - resolution: {integrity: sha512-U/S5qyqgx3WTvg4twaH0WxF3EixoTCfDsmk98g1E3/5e2YKp7JKYZdz0vivsS5/UZLJeZDEElOSFH4pUgp+l7g==} + '@turf/invariant@7.3.5': + resolution: {integrity: sha512-ZVIvsBvjr8lO7WxC5zYNjRsjSDvyGvWkJMjuWaJjTU8x+1tmfNnw3gDX/TI2Sit83gcRYLYkNo23lB/udqx/Hg==} - '@turf/invariant@7.3.4': - resolution: {integrity: sha512-88Eo4va4rce9sNZs6XiMJowWkikM3cS2TBhaCKlU+GFHdNf8PFEpiU42VDU8q5tOF6/fu21Rvlke5odgOGW4AQ==} - - '@tybys/wasm-util@0.10.1': - resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==} + '@tybys/wasm-util@0.10.2': + resolution: {integrity: sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg==} '@types/accepts@1.3.7': resolution: {integrity: sha512-Pay9fq2lM2wXPWbteBsRAGiWH2hig4ZE2asK+mm7kUzlxRTfL961rj89I6zV/E3PcIkDqyuBEcMxFT7rccugeQ==} @@ -5094,8 +5320,8 @@ packages: '@types/chai@5.2.3': resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==} - '@types/chrome@0.1.32': - resolution: {integrity: sha512-n5Cqlh7zyAqRLQWLXkeV5K/1BgDZdVcO/dJSTa8x+7w+sx7m73UrDmduAptg4KorMtyTW2TNnPu8RGeaDMKNGg==} + '@types/chrome@0.1.42': + resolution: {integrity: sha512-tdT2roFqGecZZDjA9fUEAINb2STxSPifHMDvY6EfRjNRCjdrs/0FwKt5RCIA9MKMd1arAYZZL3nwEkp6ZLZu2w==} '@types/chromecast-caf-sender@1.0.11': resolution: {integrity: sha512-Pv3xvNYtxD/cTM/tKfuZRlLasvpxAm+CFni0GJd6Cp8XgiZS9g9tMZkR1uymsi5fIFv057SZKKAWVFFgy7fJtw==} @@ -5225,8 +5451,8 @@ packages: '@types/d3@7.4.3': resolution: {integrity: sha512-lZXZ9ckh5R8uiFVt8ogUNf+pIrK4EsWrx2Np75WvF/eTpJ0FMHNhjXk8CKEx/+gpHbNQyJWehbFaTvqmHWB3ww==} - '@types/debug@4.1.12': - resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==} + '@types/debug@4.1.13': + resolution: {integrity: sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw==} '@types/deep-eql@4.0.2': resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} @@ -5255,11 +5481,14 @@ packages: '@types/estree@1.0.8': resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} - '@types/express-serve-static-core@4.19.7': - resolution: {integrity: sha512-FvPtiIf1LfhzsaIXhv/PHan/2FeQBbtBDtfX2QfvPxdUelMDEckK08SM6nqo1MIZY3RUlfA+HV8+hFUSio78qg==} + '@types/estree@1.0.9': + resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==} - '@types/express-serve-static-core@5.1.0': - resolution: {integrity: sha512-jnHMsrd0Mwa9Cf4IdOzbz543y4XJepXrbia2T4b6+spXC2We3t1y6K44D3mR8XMFSXMCf3/l7rCgddfx7UNVBA==} + '@types/express-serve-static-core@4.19.8': + resolution: {integrity: sha512-02S5fmqeoKzVZCHPZid4b8JH2eM5HzQLZWN2FohQEy/0eXTq8VXZfSN6Pcr3F6N9R/vNrj7cpgbhjie6m/1tCA==} + + '@types/express-serve-static-core@5.1.1': + resolution: {integrity: sha512-v4zIMr/cX7/d2BpAEX3KNKL/JrT1s43s96lLvvdTmza1oEvDudCqK9aF/djc/SWgy8Yh0h30TZx5VpzqFCxk5A==} '@types/express@4.17.25': resolution: {integrity: sha512-dVd04UKsfpINUnK0yBoYHDF3xu7xVH4BuDotC/xGuycx4CgbP48X/KF/586bcObxT0HENHXEU8Nqtu6NR+eKhw==} @@ -5300,8 +5529,8 @@ packages: '@types/http-assert@1.5.6': resolution: {integrity: sha512-TTEwmtjgVbYAzZYWyeHPrrtWnfVkm8tQkP8P21uQifPgMRgjrow3XDEYqucuC8SKZJT7pUnhU/JymvjggxO9vw==} - '@types/http-cache-semantics@4.0.4': - resolution: {integrity: sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==} + '@types/http-cache-semantics@4.2.0': + resolution: {integrity: sha512-L3LgimLHXtGkWikKnsPg0/VFx9OGZaC+eN1u4r+OB1XRqH3meBIAVC2zr1WdMH+RHmnRkqliQAOHNJ/E0j/e0Q==} '@types/http-errors@2.0.5': resolution: {integrity: sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==} @@ -5339,8 +5568,8 @@ packages: '@types/koa-compose@3.2.9': resolution: {integrity: sha512-BroAZ9FTvPiCy0Pi8tjD1OfJ7bgU1gQf0eR6e1Vm+JJATy9eKOG3hQMFtMciMawiSOVnLMdmUOC46s7HBhSTsA==} - '@types/koa@3.0.1': - resolution: {integrity: sha512-VkB6WJUQSe0zBpR+Q7/YIUESGp5wPHcaXr0xueU5W0EOUWtlSbblsl+Kl31lyRQ63nIILh0e/7gXjQ09JXJIHw==} + '@types/koa@3.0.3': + resolution: {integrity: sha512-TdtNEJ7sYSrFQcVuS2ySsVqnq5EyE3oJbnfFJvkC9UtGP4Kpem5KE7r+ivHIbIAQAofSqnlB5D3vkfYO69TQpg==} '@types/leaflet@1.9.21': resolution: {integrity: sha512-TbAd9DaPGSnzp6QvtYngntMZgcRk+igFELwR2N99XZn7RXUdKgsXMR+28bUO0rPsWp8MIu/f47luLIQuSLYv/w==} @@ -5378,20 +5607,14 @@ packages: '@types/multer@2.1.0': resolution: {integrity: sha512-zYZb0+nJhOHtPpGDb3vqPjwpdeGlGC157VpkqNQL+UU2qwoacoQ7MpsAmUptI/0Oa127X32JzWDqQVEXp2RcIA==} - '@types/node-forge@1.3.14': - resolution: {integrity: sha512-mhVF2BnD4BO+jtOp7z1CdzaK4mbuK0LLQYAvdOLqHTavxFNq4zA1EmYkpnFjP8HOUzedfQkRnp0E2ulSAYSzAw==} - '@types/node@17.0.45': resolution: {integrity: sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==} '@types/node@18.19.130': resolution: {integrity: sha512-GRaXQx6jGfL8sKfaIDD6OupbIHBr9jv7Jnaml9tB7l4v068PAOXqfcujMMo5PhbIs6ggR1XODELqahT2R8v0fg==} - '@types/node@24.12.2': - resolution: {integrity: sha512-A1sre26ke7HDIuY/M23nd9gfB+nrmhtYyMINbjI1zHJxYteKR6qSMX56FsmjMcDb3SMcjJg5BiRRgOCC/yBD0g==} - - '@types/node@25.6.0': - resolution: {integrity: sha512-+qIYRKdNYJwY3vRCZMdJbPLJAtGjQBudzZzdzwQYkEPQd+PJGixUL5QfvCLDaULoLv+RhT3LDkwEfKaAkgSmNQ==} + '@types/node@24.12.4': + resolution: {integrity: sha512-GUUEShf+PBCGW2KaXwcIt3Yk+e3pkKwWKb9GSyM9WQVE+ep2jzmHdGsHzu4wgcZy5fN9FBdVzjpBQsYlpfpgLA==} '@types/nodemailer@8.0.0': resolution: {integrity: sha512-fyf8jWULsCo0d0BuoQ75i6IeoHs47qcqxWc7yUdUcV0pOZGjUTTOvwdG1PRXUDqN/8A64yQdQdnA2pZgcdi+cA==} @@ -5417,14 +5640,14 @@ packages: '@types/pngjs@6.0.5': resolution: {integrity: sha512-0k5eKfrA83JOZPppLtS2C7OUtyNAl2wKNxfyYl9Q5g9lPkgBl/9hNyAu6HuEH2J4XmIv2znEpkDd0SaZVxW6iQ==} - '@types/prismjs@1.26.5': - resolution: {integrity: sha512-AUZTa7hQ2KY5L7AmtSiqxlhWxb4ina0yd8hNbl4TWuqnv/pFP0nDMb3YrfSBf4hJVGLh2YEIBfKaBW/9UEl6IQ==} + '@types/prismjs@1.26.6': + resolution: {integrity: sha512-vqlvI7qlMvcCBbVe0AKAb4f97//Hy0EBTaiW8AalRnG/xAN5zOiWWyrNqNXeq8+KAuvRewjCVY1+IPxk4RdNYw==} '@types/qrcode@1.5.6': resolution: {integrity: sha512-te7NQcV2BOvdj2b1hCAHzAoMNuj65kNBMz0KBaxM6c3VGBOhU0dURQKOtH8CFNI/dsKkwlv32p26qYQTWoB5bw==} - '@types/qs@6.14.0': - resolution: {integrity: sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==} + '@types/qs@6.15.1': + resolution: {integrity: sha512-GZHUBZR9hckSUhrxmp1nG6NwdpM9fCunJwyThLW1X3AyHgd9IlHb6VANpQQqDr2o/qQp6McZ3y/IA2rVzKzSbw==} '@types/range-parser@1.2.7': resolution: {integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==} @@ -5438,8 +5661,8 @@ packages: '@types/react-router@5.1.20': resolution: {integrity: sha512-jGjmu/ZqS7FjSH6owMcD5qpq19+1RS9DeVRqfl1FeBMxTDQAGwlMWOcs52NDoXaNKyG3d1cYQFMs9rCrb88o9Q==} - '@types/react@19.2.14': - resolution: {integrity: sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==} + '@types/react@19.2.15': + resolution: {integrity: sha512-eRwcGNHve+E8qtEQSSRl6urh+rFop4v8gm6O8rGv25CodbvFdLjA1vVQ1KkiFE0w0UPOnb8tDiFKL5lp0rtY5Q==} '@types/readdir-glob@1.1.5': resolution: {integrity: sha512-raiuEPUYqXu+nvtY2Pe8s8FEmZ3x5yAH4VkLdihcPdalvsHltomrRC9BzuStrJ9yk06470hS0Crw0f1pXqD+Hg==} @@ -5480,8 +5703,8 @@ packages: '@types/ssh2@1.15.5': resolution: {integrity: sha512-N1ASjp/nXH3ovBHddRJpli4ozpk6UdDYIX4RJWFa9L1YKnzdhTlVmiGHm4DZnj/jLbqZpes4aeR30EFGQtvhQQ==} - '@types/superagent@8.1.9': - resolution: {integrity: sha512-pTVjI73witn+9ILmoJdajHGW2jkSaOzhiFYF1Rd3EQ94kymLqB9PjD9ISg7WaALC7+dCHT0FGe9T2LktLq/3GQ==} + '@types/superagent@8.1.10': + resolution: {integrity: sha512-nbt4IWXABhW0jGmmpRzCFNlbmwCTzZ2gTUsNIr+X+ItdqPms+PAJZbWsNzpS2USqXjcoNLQcO6nXo60zcPQiIg==} '@types/supercluster@7.1.3': resolution: {integrity: sha512-Z0pOY34GDFl3Q6hUFYf3HkTwKEE02e7QgtJppBt+beEAxnyOpJua+voGFvxINBHa06GwLFFym7gRPY2SiKIfIA==} @@ -5519,77 +5742,75 @@ packages: '@types/yargs@17.0.35': resolution: {integrity: sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg==} - '@typescript-eslint/eslint-plugin@8.59.0': - resolution: {integrity: sha512-HyAZtpdkgZwpq8Sz3FSUvCR4c+ScbuWa9AksK2Jweub7w4M3yTz4O11AqVJzLYjy/B9ZWPyc81I+mOdJU/bDQw==} + '@typescript-eslint/eslint-plugin@8.59.4': + resolution: {integrity: sha512-PegsU+XfyJJNjd4+u/k6f9yTyp0lEXXiPopUNobZcIAUJFGICFLN+sP0Rb3JehVmiij1Ph0dFGYqODoRo/2+6A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - '@typescript-eslint/parser': ^8.59.0 + '@typescript-eslint/parser': ^8.59.4 eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/parser@8.59.0': - resolution: {integrity: sha512-TI1XGwKbDpo9tRW8UDIXCOeLk55qe9ZFGs8MTKU6/M08HWTw52DD/IYhfQtOEhEdPhLMT26Ka/x7p70nd3dzDg==} + '@typescript-eslint/parser@8.59.4': + resolution: {integrity: sha512-zORHqO/tuhxY1zWuTvMUqddRxpiFJ72xVfcNoWpqdLjs6lfPbuQBJuW4pk+49/uBMy7Ssr4bzgjiKmmDB1UbZQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/project-service@8.59.0': - resolution: {integrity: sha512-Lw5ITrR5s5TbC19YSvlr63ZfLaJoU6vtKTHyB0GQOpX0W7d5/Ir6vUahWi/8Sps/nOukZQ0IB3SmlxZnjaKVnw==} + '@typescript-eslint/project-service@8.59.4': + resolution: {integrity: sha512-Ly00Vu4oAacfDeHp2Zg85ioNG6l8HG+tN1D7J+xTHSxu9y0awYKJ2zH1rFBn8ZSfuGK+7FxK3Cgl3uAz0aZZLg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/scope-manager@8.59.0': - resolution: {integrity: sha512-UzR16Ut8IpA3Mc4DbgAShlPPkVm8xXMWafXxB0BocaVRHs8ZGakAxGRskF7FId3sdk9lgGD73GSFaWmWFDE4dg==} + '@typescript-eslint/scope-manager@8.59.4': + resolution: {integrity: sha512-mUeR/3H1WrTAddJrwut8OoPjfauaztMQmRwV5fQTUyNVJCLiUXXe4lGEyYIL2oFDpP7UtgbGJXCt72wT0z2S3Q==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/tsconfig-utils@8.59.0': - resolution: {integrity: sha512-91Sbl3s4Kb3SybliIY6muFBmHVv+pYXfybC4Oolp3dvk8BvIE3wOPc+403CWIT7mJNkfQRGtdqghzs2+Z91Tqg==} + '@typescript-eslint/tsconfig-utils@8.59.4': + resolution: {integrity: sha512-DLCpnKgD4alVxTBSKulK+gU1KCqOgUXfDRDXh2mZgzokQKa/70ax93I2uVO3m/LLvIAtWZIFoiifudmIqAxpMA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/type-utils@8.59.0': - resolution: {integrity: sha512-3TRiZaQSltGqGeNrJzzr1+8YcEobKH9rHnqIp/1psfKFmhRQDNMGP5hBufanYTGznwShzVLs3Mz+gDN7HkWfXg==} + '@typescript-eslint/type-utils@8.59.4': + resolution: {integrity: sha512-uonTuPAAKr9XaBGqJ3LjYTh72zy5DyGesljO9gtmk/eFW0W1fRHjnwVYKB35Lm8d5Q5CluEW3gPHjTvZTmgrfA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/types@8.59.0': - resolution: {integrity: sha512-nLzdsT1gdOgFxxxwrlNVUBzSNBEEHJ86bblmk4QAS6stfig7rcJzWKqCyxFy3YRRHXDWEkb2NralA1nOYkkm/A==} + '@typescript-eslint/types@8.59.4': + resolution: {integrity: sha512-F1o7WJcCq+bc8dwcO/YsSEOudAH8RDtaOhM6wcAQhcUsFhnWQl81JKy48q1hoxAU0qrzM89+31GYh1515Zde3Q==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/typescript-estree@8.59.0': - resolution: {integrity: sha512-O9Re9P1BmBLFJyikRbQpLku/QA3/AueZNO9WePLBwQrvkixTmDe8u76B6CYUAITRl/rHawggEqUGn5QIkVRLMw==} + '@typescript-eslint/typescript-estree@8.59.4': + resolution: {integrity: sha512-F+RuOmcDXo4+TPdfd/TCLS3m2nw8gE9XXyZLrA3JBfaA5tz9TtdkyD3YJFmPxulyc2cKbEok/CvFE3MgSLWnag==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/utils@8.59.0': - resolution: {integrity: sha512-I1R/K7V07XsMJ12Oaxg/O9GfrysGTmCRhvZJBv0RE0NcULMzjqVpR5kRRQjHsz3J/bElU7HwCO7zkqL+MSUz+g==} + '@typescript-eslint/utils@8.59.4': + resolution: {integrity: sha512-cYXeNAUsG4lJo5dbc1FcKm+JwIWrj1/UpTORsC6tGMjEZ81DYcvIr9/ueikhMa/Y/gDQYGp+YX9/xQrXje5BJw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/visitor-keys@8.59.0': - resolution: {integrity: sha512-/uejZt4dSere1bx12WLlPfv8GktzcaDtuJ7s42/HEZ5zGj9oxRaD4bj7qwSunXkf+pbAhFt2zjpHYUiT5lHf0Q==} + '@typescript-eslint/visitor-keys@8.59.4': + resolution: {integrity: sha512-U3gxVaDVnuZKhSspW/MzMxE1kq7zOdc072FcSNoqA1I9p8HyKbBFfEHoWckBAMgNMph4MamwS5iTVzFmrnt8TQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@ungap/structured-clone@1.3.0': - resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==} - deprecated: Potential CWE-502 - Update to 1.3.1 or higher + '@ungap/structured-clone@1.3.1': + resolution: {integrity: sha512-mUFwbeTqrVgDQxFveS+df2yfap6iuP20NAKAsBt5jDEoOTDew+zwLAOilHCeQJOVSvmgCX4ogqIrA0mnyr08yQ==} - '@valibot/to-json-schema@1.6.0': - resolution: {integrity: sha512-d6rYyK5KVa2XdqamWgZ4/Nr+cXhxjy7lmpe6Iajw15J/jmU+gyxl2IEd1Otg1d7Rl3gOQL5reulnSypzBtYy1A==} + '@upsetjs/venn.js@2.0.0': + resolution: {integrity: sha512-WbBhLrooyePuQ1VZxrJjtLvTc4NVfpOyKx0sKqioq9bX1C1m7Jgykkn8gLrtwumBioXIqam8DLxp88Adbue6Hw==} + + '@valibot/to-json-schema@1.7.0': + resolution: {integrity: sha512-Y3pPVibbIOHzohrlxSINvO7w/bvXkoYS3BQHoImV9ynE+bXKf171bdMucPurV2zp7gdmt0L1HCcNAsbo7cFRQw==} peerDependencies: - valibot: ^1.3.0 - - '@vercel/oidc@3.0.5': - resolution: {integrity: sha512-fnYhv671l+eTTp48gB4zEsTW/YtRgRPnkI2nT7x6qw5rkI1Lq2hTmQIpHPgyThI0znLK+vX2n9XxKdXZ7BUbbw==} - engines: {node: '>= 20'} + valibot: ^1.4.0 '@vitest/coverage-v8@3.2.4': resolution: {integrity: sha512-EyF9SXU6kS5Ku/U82E259WSnvg6c8KTjppUncuNdm5QHpe17mwREHnjDzozC8x9MZ0xfBUFSaLkRv4TMA75ALQ==} @@ -5600,11 +5821,11 @@ packages: '@vitest/browser': optional: true - '@vitest/coverage-v8@4.1.5': - resolution: {integrity: sha512-38C0/Ddb7HcRG0Z4/DUem8x57d2p9jYgp18mkaYswEOQBGsI1CG4f/hjm0ZCeaJfWhSZ4k7jgs29V1Zom7Ki9A==} + '@vitest/coverage-v8@4.1.7': + resolution: {integrity: sha512-qsYPeXc5Q9dFLd1i8Ap+Bx8sQgcp+rFVQo4R0dDsWNBzl26ldVF1qOO+RL24K7FDrR6pA+50XedRLSoSG24bVQ==} peerDependencies: - '@vitest/browser': 4.1.5 - vitest: 4.1.5 + '@vitest/browser': 4.1.7 + vitest: 4.1.7 peerDependenciesMeta: '@vitest/browser': optional: true @@ -5612,8 +5833,8 @@ packages: '@vitest/expect@3.2.4': resolution: {integrity: sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig==} - '@vitest/expect@4.1.5': - resolution: {integrity: sha512-PWBaRY5JoKuRnHlUHfpV/KohFylaDZTupcXN1H9vYryNLOnitSw60Mw9IAE2r67NbwwzBw/Cc/8q9BK3kIX8Kw==} + '@vitest/expect@4.1.7': + resolution: {integrity: sha512-1R+tw0ortHEbZDGMymm+pN7/AFQ/RkFFdtd7EN+VBpynKmLbP8A3rpEXdshBJ7+8hQ9zBJh/i1s0yKNtxAnU7w==} '@vitest/mocker@3.2.4': resolution: {integrity: sha512-46ryTE9RZO/rfDd7pEqFl7etuyzekzEhUbTW3BvmeO/BcCMEgq59BKhek3dXDWgAj4oMK6OZi+vRr1wPW6qjEQ==} @@ -5626,8 +5847,8 @@ packages: vite: optional: true - '@vitest/mocker@4.1.5': - resolution: {integrity: sha512-/x2EmFC4mT4NNzqvC3fmesuV97w5FC903KPmey4gsnJiMQ3Be1IlDKVaDaG8iqaLFHqJ2FVEkxZk5VmeLjIItw==} + '@vitest/mocker@4.1.7': + resolution: {integrity: sha512-vY7nuamKgfvpA1Koa3oYIw/k7D6kZnpGyNMZW8loow2bsBYla1TFdqTaXncWdRn4pgwNs+90RhnXhJScDwQeJA==} peerDependencies: msw: ^2.4.9 vite: ^6.0.0 || ^7.0.0 || ^8.0.0 @@ -5640,32 +5861,32 @@ packages: '@vitest/pretty-format@3.2.4': resolution: {integrity: sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA==} - '@vitest/pretty-format@4.1.5': - resolution: {integrity: sha512-7I3q6l5qr03dVfMX2wCo9FxwSJbPdwKjy2uu/YPpU3wfHvIL4QHwVRp57OfGrDFeUJ8/8QdfBKIV12FTtLn00g==} + '@vitest/pretty-format@4.1.7': + resolution: {integrity: sha512-umgCarTOYQWIaDMvGDRZij+6b9oVeLIyJzfN+AS88e0ZOU3QTgNNSTtjQOpcvWr3np1N0j4WgZj+sb3oYBDscw==} '@vitest/runner@3.2.4': resolution: {integrity: sha512-oukfKT9Mk41LreEW09vt45f8wx7DordoWUZMYdY/cyAk7w5TWkTRCNZYF7sX7n2wB7jyGAl74OxgwhPgKaqDMQ==} - '@vitest/runner@4.1.5': - resolution: {integrity: sha512-2D+o7Pr82IEO46YPpoA/YU0neeyr6FTerQb5Ro7BUnBuv6NQtT/kmVnczngiMEBhzgqz2UZYl5gArejsyERDSQ==} + '@vitest/runner@4.1.7': + resolution: {integrity: sha512-BapjmAQ2aI78WdMEfeUWivnfVzB+VPGwWRQcJE0OUq7qEeEcBsCSf+0T5iREBNE5nBb4wA5Ya0W6IA+sghdEFw==} '@vitest/snapshot@3.2.4': resolution: {integrity: sha512-dEYtS7qQP2CjU27QBC5oUOxLE/v5eLkGqPE0ZKEIDGMs4vKWe7IjgLOeauHsR0D5YuuycGRO5oSRXnwnmA78fQ==} - '@vitest/snapshot@4.1.5': - resolution: {integrity: sha512-zypXEt4KH/XgKGPUz4eC2AvErYx0My5hfL8oDb1HzGFpEk1P62bxSohdyOmvz+d9UJwanI68MKwr2EquOaOgMQ==} + '@vitest/snapshot@4.1.7': + resolution: {integrity: sha512-ZacLzja+TmJeZ1h14xW2FB/WpeimUD3haBXQPyJqxvo8jQTmfeA8zv58mtjN2C7EHXZDYVcVYdYmAxjkWVvKCw==} '@vitest/spy@3.2.4': resolution: {integrity: sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw==} - '@vitest/spy@4.1.5': - resolution: {integrity: sha512-2lNOsh6+R2Idnf1TCZqSwYlKN2E/iDlD8sgU59kYVl+OMDmvldO1VDk39smRfpUNwYpNRVn3w4YfuC7KfbBnkQ==} + '@vitest/spy@4.1.7': + resolution: {integrity: sha512-kbkI5LMWakyuTIvs6fUJ5qdIVb1XVKsYJAT4OJ938cHMROYMSfmoQdZy0aaAnjbbc8F61vkoTqz/Az+/HiIu5Q==} '@vitest/utils@3.2.4': resolution: {integrity: sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==} - '@vitest/utils@4.1.5': - resolution: {integrity: sha512-76wdkrmfXfqGjueGgnb45ITPyUi1ycZ4IHgC2bhPDUfWHklY/q3MdLOAB+TF1e6xfl8NxNY0ZYaPCFNWSsw3Ug==} + '@vitest/utils@4.1.7': + resolution: {integrity: sha512-T532WBu791cBxJlCl6SO+J14l81DQx6uQHm1bQbmCDY7nqlEIgkza/UFnSBNaUtSf41unldDFjdOBYEQC4b5Hw==} '@webassemblyjs/ast@1.14.1': resolution: {integrity: sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==} @@ -5761,8 +5982,8 @@ packages: peerDependencies: acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - acorn-walk@8.3.4: - resolution: {integrity: sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==} + acorn-walk@8.3.5: + resolution: {integrity: sha512-HEHNfbars9v4pgpW6SO1KSPkfoS0xVOM/9UzkJltjlsHZmJasxg8aXkuZa7SMf8vKGIBhpUsPluQSqhJFCqebw==} engines: {node: '>=0.4.0'} acorn@8.16.0: @@ -5786,12 +6007,6 @@ packages: resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==} engines: {node: '>=8'} - ai@5.0.113: - resolution: {integrity: sha512-26vivpSO/mzZj0k1Si2IpsFspp26ttQICHRySQiMrtWcRd5mnJMX2a8sG28vmZ38C+JUn1cWmfZrsLMxkSMw9g==} - engines: {node: '>=18'} - peerDependencies: - zod: ^3.25.76 || ^4.1.8 - ajv-formats@2.1.1: resolution: {integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==} peerDependencies: @@ -5818,19 +6033,22 @@ packages: peerDependencies: ajv: ^8.8.2 - ajv@6.14.0: - resolution: {integrity: sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==} + ajv@6.15.0: + resolution: {integrity: sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==} ajv@8.18.0: resolution: {integrity: sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==} - algoliasearch-helper@3.26.1: - resolution: {integrity: sha512-CAlCxm4fYBXtvc5MamDzP6Svu8rW4z9me4DCBY1rQ2UDJ0u0flWmusQ8M3nOExZsLLRcUwUPoRAPMrhzOG3erw==} + ajv@8.20.0: + resolution: {integrity: sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==} + + algoliasearch-helper@3.29.1: + resolution: {integrity: sha512-6ck2YFudF2Pje7szQoPBiRFTGfd+1I+0I/WfLPGn0bj1kvrFoOQmNyedNiDxTk3/r4IfSLDYk+RA4G7u8H6+yA==} peerDependencies: algoliasearch: '>= 3.1 < 6' - algoliasearch@5.46.0: - resolution: {integrity: sha512-7ML6fa2K93FIfifG3GMWhDEwT5qQzPTmoHKCTvhzGEwdbQ4n0yYUWZlLYT75WllTGJCJtNUI0C1ybN4BCegqvg==} + algoliasearch@5.52.1: + resolution: {integrity: sha512-fHA8+kXTbjagw3jkLiaS7KKrH8qe2DyOsiUhGlN4cdT77PEsfqXZl7ewDk1hsg+pJnPlnE50XtLxjR91iJOpmg==} engines: {node: '>= 14.0.0'} ansi-align@3.0.1: @@ -5942,6 +6160,10 @@ packages: asn1@0.2.6: resolution: {integrity: sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==} + asn1js@3.0.10: + resolution: {integrity: sha512-S2s3aOytiKdFRdulw2qPE51MzjzVOisppcVv7jVFR+Kw0kxwvFrDcYA0h7Ndqbmj0HkMIXYWaoj7fli8kgx1eg==} + engines: {node: '>=12.0.0'} + assertion-error@2.0.1: resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} engines: {node: '>=12'} @@ -5988,8 +6210,8 @@ packages: resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} engines: {node: '>= 0.4'} - b4a@1.8.0: - resolution: {integrity: sha512-qRuSmNSkGQaHwNbM7J78Wwy+ghLEYF1zNrSeMxj4Kgw6y33O3mXcQ6Ie9fRvfU/YnxWkOchPXbaLb73TkIsfdg==} + b4a@1.8.1: + resolution: {integrity: sha512-aiqre1Nr0B/6DgE2N5vwTc+2/oQZ4Wh1t4NznYY4E00y8LCt6NqdRv81so00oo27D8MVKTpUa/MwUUtBLXCoDw==} peerDependencies: react-native-b4a: '*' peerDependenciesMeta: @@ -6006,8 +6228,8 @@ packages: babel-plugin-dynamic-import-node@2.3.3: resolution: {integrity: sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==} - babel-plugin-polyfill-corejs2@0.4.14: - resolution: {integrity: sha512-Co2Y9wX854ts6U8gAAPXfn0GmAyctHuK8n0Yhfjd6t30g7yvKjspvvOo9yG+z52PZRgFErt7Ka2pYnXCjLKEpg==} + babel-plugin-polyfill-corejs2@0.4.17: + resolution: {integrity: sha512-aTyf30K/rqAsNwN76zYrdtx8obu0E4KoUME29B1xj+B3WxgvWkp943vYQ+z8Mv3lw9xHXMHpvSPOBxzAkIa94w==} peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 @@ -6016,8 +6238,13 @@ packages: peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 - babel-plugin-polyfill-regenerator@0.6.5: - resolution: {integrity: sha512-ISqQ2frbiNU9vIJkzg7dlPpznPZ4jOiUQ1uSmB0fEHeowtN3COYRsXr/xexn64NpU13P06jc/L5TgiJXOgrbEg==} + babel-plugin-polyfill-corejs3@0.14.2: + resolution: {integrity: sha512-coWpDLJ410R781Npmn/SIBZEsAetR4xVi0SxLMXPaMO4lSf1MwnkGYMtkFxew0Dn8B3/CpbpYxN0JCgg8mn67g==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + + babel-plugin-polyfill-regenerator@0.6.8: + resolution: {integrity: sha512-M762rNHfSF1EV3SLtnCJXFoQbbIIz0OyRwnCmV0KPC7qosSfCO0QLTSuJX3ayAebubhE6oYBAYPrBA5ljowaZg==} peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 @@ -6034,8 +6261,8 @@ packages: resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} engines: {node: 18 || 20 || >=22} - bare-events@2.8.2: - resolution: {integrity: sha512-riJjyv1/mHLIPX4RwiK+oW9/4c3TEUeORHKefKAKnZ5kyslbN+HXowtbaVEqt4IMUB7OXlfixcs6gsFeo/jhiQ==} + bare-events@2.8.3: + resolution: {integrity: sha512-HdUm8EMQBLaJvGUdidNNbqpA1kYkwNcb+MYxkxCLAPJGQzlv9J0C24h8V65Z4c5GLd/JEALDvpFCQgpLJqc0zw==} peerDependencies: bare-abort-controller: '*' peerDependenciesMeta: @@ -6051,15 +6278,15 @@ packages: bare-buffer: optional: true - bare-os@3.9.0: - resolution: {integrity: sha512-JTjuZyNIDpw+GytMO4a6TK1VXdVKKJr6DRxEHasyuYyShV2deuiHJK/ahGZlebc+SG0/wJCB9XK8gprBGDFi/Q==} + bare-os@3.9.1: + resolution: {integrity: sha512-6M5XjcnsygQNPMCMPXSK379xrJFiZ/AEMNBmFEmQW8d/789VQATvriyi5r0HYTL9TkQ26rn3kgdTG3aisbrXkQ==} engines: {bare: '>=1.14.0'} bare-path@3.0.0: resolution: {integrity: sha512-tyfW2cQcB5NN8Saijrhqn0Zh7AnFNsnczRcuWODH0eYAXBsJ5gVxAUuNr7tsHSC6IZ77cA0SitzT+s47kot8Mw==} - bare-stream@2.13.0: - resolution: {integrity: sha512-3zAJRZMDFGjdn+RVnNpF9kuELw+0Fl3lpndM4NcEOhb9zwtSo/deETfuIwMSE5BXanA0FrN1qVjffGwAg2Y7EA==} + bare-stream@2.13.1: + resolution: {integrity: sha512-Vp0cnjYyrEC4whYTymQ+YZi6pBpfiICZO3cfRG8sy67ZNWe951urv1x4eW1BKNngw3U+3fPYb5JQvHbCtxH7Ow==} peerDependencies: bare-abort-controller: '*' bare-buffer: '*' @@ -6072,8 +6299,8 @@ packages: bare-events: optional: true - bare-url@2.4.2: - resolution: {integrity: sha512-/9a2j4ac6ckpmAHvod/ob7x439OAHst/drc2Clnq+reRYd/ovddwcF4LfoxHyNk5AuGBnPg+HqFjmE/Zpq6v0A==} + bare-url@2.4.3: + resolution: {integrity: sha512-Kccpc7ACfXaxfeInfqKcZtW4pT5YBn1mesc4sCsun6sRwtbJ4h+sNOaksUpYEJUKfN65YWC6Bw2OJEFiKxq8nQ==} base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} @@ -6082,8 +6309,8 @@ packages: resolution: {integrity: sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==} engines: {node: ^4.5.0 || >= 5.9} - baseline-browser-mapping@2.10.20: - resolution: {integrity: sha512-1AaXxEPfXT+GvTBJFuy4yXVHWJBXa4OdbIebGN/wX5DlsIkU0+wzGnd2lOzokSk51d5LUmqjgBLRLlypLUqInQ==} + baseline-browser-mapping@2.10.31: + resolution: {integrity: sha512-MujYO3eP72uvmSE0i4wltsodRfIpZATP3jvzRNRGGxgzId7aVocVJJV3nf01qnzzKFGxQVC9bpWxl5cjxTr/7Q==} engines: {node: '>=6.0.0'} hasBin: true @@ -6125,11 +6352,18 @@ packages: '@internationalized/date': ^3.8.1 svelte: ^5.33.0 + bits-ui@2.18.1: + resolution: {integrity: sha512-KkemzKFH4T3gt3H+P86JcnAWExjByv/6vlwjm/BoCwTPHu03yiCdxbghdJLvFReQTe0acCAiRcKfmixxD6XvlA==} + engines: {node: '>=20'} + peerDependencies: + '@internationalized/date': ^3.8.1 + svelte: ^5.33.0 + bl@4.1.0: resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} - body-parser@1.20.4: - resolution: {integrity: sha512-ZTgYYLMOXY9qKU/57FAo8F+HA2dGX7bqGc71txDRC1rS4frdFI5R7NhluHxH6M0YItAP0sHB4uqAOcYKxO6uGA==} + body-parser@1.20.5: + resolution: {integrity: sha512-3grm+/2tUOvu2cjJkvsIxrv/wVpfXQW4PsQHYm7yk4vfpu7Ekl6nEsYBoJUL6qDwZUx8wUhQ8tR2qz+ad9c9OA==} engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} body-parser@2.2.2: @@ -6150,14 +6384,14 @@ packages: resolution: {integrity: sha512-2hCgjEmP8YLWQ130n2FerGv7rYpfBmnmp9Uy2Le1vge6X3gZIfSmEzP5QTDElFxcvVcXlEn8Aq6MU/PZygIOog==} engines: {node: '>=14.16'} - brace-expansion@1.1.12: - resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==} + brace-expansion@1.1.14: + resolution: {integrity: sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==} brace-expansion@2.1.0: resolution: {integrity: sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w==} - brace-expansion@5.0.5: - resolution: {integrity: sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==} + brace-expansion@5.0.6: + resolution: {integrity: sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==} engines: {node: 18 || 20 || >=22} braces@3.0.3: @@ -6189,12 +6423,13 @@ packages: resolution: {integrity: sha512-lHblz4ahamxpTmnsk+MNTRWsjYKv965MwOrSJyeD588rR3Jcu7swE+0wN5F+PbL5cjgu/9ObkhfzEPuofEMwLA==} engines: {node: '>=10.0.0'} - builtin-modules@5.0.0: - resolution: {integrity: sha512-bkXY9WsVpY7CvMhKSR6pZilZu9Ln5WDrKVBUXf2S443etkmEO4V58heTecXcUIsNsi4Rx8JUO4NfX1IcQl4deg==} + builtin-modules@5.2.0: + resolution: {integrity: sha512-02yxLeyxF4dNl6SlY6/5HfRSrSdZ/sCPoxy2kZNP5dZZX8LSAD9aE2gtJIUgWrsQTiMPl3mxESyrobSwvRGisQ==} engines: {node: '>=18.20'} - bullmq@5.76.1: - resolution: {integrity: sha512-9Xc5Pj4Ho0clodowuuUSydMOR4gCn+YxYYVQXbGJycO8r4jyxsff1rZl3CKj3k50c/B42gDDNTLJH6uwb3dYmg==} + bullmq@5.76.10: + resolution: {integrity: sha512-LWve7SpQjYSpCP2GEsWmoyzTz2H37L8HRmSTu3YihYsTOr5kJxrfEX6aEV7m6eskEMWXSHZYTMZepX6qNaH6CQ==} + engines: {node: '>=12.22.0'} bundle-name@4.1.0: resolution: {integrity: sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==} @@ -6225,14 +6460,14 @@ packages: resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} engines: {node: '>= 0.8'} + bytestreamjs@2.0.1: + resolution: {integrity: sha512-U1Z/ob71V/bXfVABvNr/Kumf5VyeQRBEm6Txb0PQ6S7V5GpBM3w4Cbqz/xPDicR5tN0uvDifng8C+5qECeGwyQ==} + engines: {node: '>=6.0.0'} + cac@6.7.14: resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} engines: {node: '>=8'} - cacache@20.0.3: - resolution: {integrity: sha512-3pUp4e8hv07k1QlijZu6Kn7c9+ZpWWk4j3F8N3xPuCExULobqJydKYOTj1FTq58srkJsXvO7LbGAH4C0ZU3WGw==} - engines: {node: ^20.17.0 || >=22.9.0} - cacheable-lookup@7.0.0: resolution: {integrity: sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==} engines: {node: '>=14.16'} @@ -6245,8 +6480,8 @@ packages: resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} engines: {node: '>= 0.4'} - call-bind@1.0.8: - resolution: {integrity: sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==} + call-bind@1.0.9: + resolution: {integrity: sha512-a/hy+pNsFUTR+Iz8TCJvXudKVLAnz/DyeSUo10I5yvFDQJBFU2s9uqQpoSrJlroHUKoKqzg+epxyP9lqFdzfBQ==} engines: {node: '>= 0.4'} call-bound@1.0.4: @@ -6279,8 +6514,8 @@ packages: caniuse-api@3.0.0: resolution: {integrity: sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==} - caniuse-lite@1.0.30001790: - resolution: {integrity: sha512-bOoxfJPyYo+ds6W0YfptaCWbFnJYjh2Y1Eow5lRv+vI2u8ganPZqNm1JwNh0t2ELQCqIWg4B3dWEusgAmsoyOw==} + caniuse-lite@1.0.30001793: + resolution: {integrity: sha512-iwSsYWaCOoh26cV8NwNRViHlrfUvYsHDfRVcbtmw0Kg6PJIZZXwMkj1442FYLBGkeUf1juAsU3DTfxW579mrPA==} canvas@3.2.3: resolution: {integrity: sha512-PzE5nJZPz72YUAfo8oTp0u3fqqY7IzlTubneAihqDYAUcBk7ryeCmBbdJBEdaH0bptSOe2VT2Zwcb3UaFyaSWw==} @@ -6343,14 +6578,6 @@ packages: resolution: {integrity: sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==} engines: {node: '>= 6'} - chevrotain-allstar@0.3.1: - resolution: {integrity: sha512-b7g+y9A0v4mxCW1qUhf3BSVPg+/NvGErk/dOkrDaHA0nQIQGAtrOjlX//9OQtRlSCy+x9rfB5N8yC71lH1nvMw==} - peerDependencies: - chevrotain: ^11.0.0 - - chevrotain@11.0.3: - resolution: {integrity: sha512-ci2iJH6LeIkvP9eJW6gpueU8cnZhv85ELY8w8WiFtNjMHA5ad6pQLaJo9mEly/9qUyCpvqX8/POVUTf18/HFdw==} - chokidar@3.6.0: resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} engines: {node: '>= 8.10.0'} @@ -6586,9 +6813,6 @@ packages: resolution: {integrity: sha512-Uy5YN9KEu0WWDaZAVJ5FAmZoaJt9rdK6kH+utItPyGsCqCgaTKkrmZx3zoE0/3q6S3bcp3Ihkk+ZqPxWxFK5og==} engines: {node: '>=20'} - confbox@0.1.8: - resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} - config-chain@1.1.13: resolution: {integrity: sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==} @@ -6619,10 +6843,18 @@ packages: resolution: {integrity: sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q==} engines: {node: '>=18'} + content-disposition@1.1.0: + resolution: {integrity: sha512-5jRCH9Z/+DRP7rkvY83B+yGIGX96OYdJmzngqnw2SBSxqCFPd0w2km3s5iawpGX8krnwSGmF0FW5Nhr0Hfai3g==} + engines: {node: '>=18'} + content-type@1.0.5: resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} engines: {node: '>= 0.6'} + content-type@2.0.0: + resolution: {integrity: sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ==} + engines: {node: '>=18'} + convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} @@ -6672,8 +6904,8 @@ packages: core-js-compat@3.49.0: resolution: {integrity: sha512-VQXt1jr9cBz03b331DFDCCP90b3fanciLkgiOoy8SBHy06gNf+vQ1A3WFLqG7I8TipYIKeYK9wxd0tUrvHcOZA==} - core-js@3.47.0: - resolution: {integrity: sha512-c3Q2VVkGAUyupsjRnaNX6u8Dq2vAdzm9iuPj5FW0fRxzlxgq9Q39MDq10IvmQSpLgHQNyQzQmOo6bgGHmH3NNg==} + core-js@3.49.0: + resolution: {integrity: sha512-es1U2+YTtzpwkxVLwAFdSpaIMyQaq0PBgm3YD1W3Qpsn1NAmO3KSgZfu+oGSWVu6NvLHoHCV/aYcsE5wiB7ALg==} core-util-is@1.0.3: resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} @@ -6742,8 +6974,8 @@ packages: peerDependencies: postcss: ^8.4 - css-declaration-sorter@7.3.0: - resolution: {integrity: sha512-LQF6N/3vkAMYF4xoHLJfG718HRJh34Z8BnNhd6bosOMIVjMlhuZK5++oZa3uYAgrI5+7x2o27gUqTR2U/KjUOQ==} + css-declaration-sorter@7.4.0: + resolution: {integrity: sha512-LTuzjPoyA2vMGKKcaOqKSp7Ub2eGrNfKiZH4LpezxpNrsICGCSFvsQOI29psISxNZtaXibkC2CXzrQ5enMeGGw==} engines: {node: ^14 || ^16 || >=18} peerDependencies: postcss: ^8.0.9 @@ -6821,8 +7053,8 @@ packages: css.escape@1.5.1: resolution: {integrity: sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==} - cssdb@8.5.2: - resolution: {integrity: sha512-Pmoj9RmD8RIoIzA2EQWO4D4RMeDts0tgAH0VXdlNdxjuBGI3a9wMOIcUwaPNmD4r2qtIa06gqkIf7sECl+cBCg==} + cssdb@8.9.0: + resolution: {integrity: sha512-J8jOU/hLjaXcO1LldOLraJSQpfLXRKof0I7mtbRyOy2AAXgqst0x9rlgi2qXeD6d0ou3ZLqcPAMqYVbpCbrxEw==} cssesc@3.0.0: resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} @@ -6874,8 +7106,8 @@ packages: peerDependencies: cytoscape: ^3.2.0 - cytoscape@3.33.1: - resolution: {integrity: sha512-iJc4TwyANnOGR1OmWhsS9ayRS3s+XQ185FmuHObThD+5AeJCakAAbWv8KimMTt08xCCLNgneQwFp+JRJOr9qGQ==} + cytoscape@3.33.4: + resolution: {integrity: sha512-HIN5Pmd9MrX9BkV7tDwnOcEJCSFvCpc8X97h3f508J6I5FsqAY65wKOCvgH2CuP42CaahWaz4tuh32SOOIH7ww==} engines: {node: '>=0.10'} d3-array@2.12.1: @@ -6934,8 +7166,8 @@ packages: resolution: {integrity: sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==} engines: {node: '>=12'} - d3-format@3.1.0: - resolution: {integrity: sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==} + d3-format@3.1.2: + resolution: {integrity: sha512-AJDdYOdnyRDV5b6ArilzCPPwc1ejkHcoyFarqlPqT7zRYjhavcT3uSrqcMvsgh2CgoPbK3RCwyHaVyxYcP2Arg==} engines: {node: '>=12'} d3-geo@3.1.1: @@ -7021,15 +7253,15 @@ packages: resolution: {integrity: sha512-MOqHvMWF9/9MX6nza0KgvFH4HpMU0EF5uUDXqX/BtxtU8NfB0QzRtJ8Oe/6SuS4kbhyzVJwjd97EA4PKrzJ8bw==} engines: {node: '>=0.12'} - dagre-d3-es@7.0.13: - resolution: {integrity: sha512-efEhnxpSuwpYOKRm/L5KbqoZmNNukHa/Flty4Wp62JRvgH2ojwVgPgdYyr4twpieZnyRDdIH7PY2mopX26+j2Q==} + dagre-d3-es@7.0.14: + resolution: {integrity: sha512-P4rFMVq9ESWqmOgK+dlXvOtLwYg0i7u0HBGJER0LZDJT2VHIPAMZ/riPxqJceWMStH5+E61QxFra9kIS3AqdMg==} data-urls@5.0.0: resolution: {integrity: sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==} engines: {node: '>=18'} - dayjs@1.11.19: - resolution: {integrity: sha512-t5EcLVS6QPBNqM2z8fakk/NKel+Xzshgt8FFKAn+qwlD1pzZWxh0nVCrvFK7ZDb6XucZeF9z8C7CBWTRIVApAw==} + dayjs@1.11.20: + resolution: {integrity: sha512-YbwwqR/uYpeoP4pu043q+LTDLFBLApUP6VxRihdfNTqu4ubqMlGDLd6ErXhEgsyvY0K6nCs7nggYumAN+9uEuQ==} debounce-fn@6.0.0: resolution: {integrity: sha512-rBMW+F2TXryBwB54Q0d8drNEI+TfoS9JpNTAoVpukbWEhjXQq4rySFYLaqXMFXwdv61Zb2OHtj5bviSoimqxRQ==} @@ -7075,8 +7307,8 @@ packages: decimal.js@10.6.0: resolution: {integrity: sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==} - decode-named-character-reference@1.2.0: - resolution: {integrity: sha512-c6fcElNV6ShtZXmsgNgFFV5tVX2PaV4g+MOAkb8eXHvn6sryJBrZa9r0zV6+dtTyoCKxtDy5tyQ5ZwQuidtd+Q==} + decode-named-character-reference@1.3.0: + resolution: {integrity: sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==} decompress-response@6.0.0: resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} @@ -7104,8 +7336,8 @@ packages: resolution: {integrity: sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q==} engines: {node: '>=18'} - default-browser@5.4.0: - resolution: {integrity: sha512-XDuvSq38Hr1MdN47EDvYtx3U0MTqpCEn+F6ft8z2vYDzMrvQhVp0ui9oQdqW3MvK3vqUETglt1tVGgjLuJ5izg==} + default-browser@5.5.0: + resolution: {integrity: sha512-H9LMLr5zwIbSxrmvikGuI/5KGhZ8E2zH3stkMgM5LpOWDutGM2JZaj460Udnf1a+946zc7YBgrqEWwbk7zHvGw==} engines: {node: '>=18'} defaults@1.0.4: @@ -7131,8 +7363,8 @@ packages: resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} engines: {node: '>= 0.4'} - delaunator@5.0.1: - resolution: {integrity: sha512-8nvh+XBe96aCESrGOqMp/84b13H9cdKbG5P2ejQCh4d4sK9RL4371qou9drQjMhvnPmhWl5hnmqbEE0fXr9Xnw==} + delaunator@5.1.0: + resolution: {integrity: sha512-AGrQ4QSgssa1NGmWmLPqN5NY2KajF5MqxetNEO+o0n3ZwZZeTmt7bBnvzHWrmkZFxGgr4HdyFgelzgi06otLuQ==} delayed-stream@1.0.0: resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} @@ -7224,8 +7456,8 @@ packages: resolution: {integrity: sha512-XJgGhoR/CLpqshm4d3L7rzH6t8NgDFUIIpztYlLHIApeJjMZKYJMz2zxPsYxnejq5h3ELYSw/RBsi3t5h7gNTA==} engines: {node: '>= 8.0'} - dockerode@4.0.10: - resolution: {integrity: sha512-8L/P9JynLBiG7/coiA4FlQXegHltRqS0a+KqI44P1zgQh8QLHTg7FKOwhkBgSJwZTeHsq30WRoVFLuwkfK0YFg==} + dockerode@4.0.12: + resolution: {integrity: sha512-/bCZd6KlGcjZO8Buqmi/vXuqEGVEZ0PNjx/biBNqJD3MhK9DmdiAuKxqfNhflgDESDIiBz3qF+0e55+CpnrUcw==} engines: {node: '>= 8.0'} docusaurus-lunr-search@3.6.0: @@ -7265,8 +7497,8 @@ packages: resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} engines: {node: '>= 4'} - dompurify@3.3.1: - resolution: {integrity: sha512-qkdCKzLNtrgPFP1Vo+98FRzJnBRGe4ffyCea9IwHB1fyxPOeNTHpLKYGd4Uk9xvNoH0ZoOjwZxNptyMwqrId1Q==} + dompurify@3.4.5: + resolution: {integrity: sha512-OrwIBKsdNSVEeubdJ1HBv/wNENRM9ytAVCv7YXt//A3vPdVMNuACRqK9mXCGCBW2ln7BT/A4X0jXHo2Gu89miA==} domutils@2.8.0: resolution: {integrity: sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==} @@ -7308,8 +7540,8 @@ packages: ee-first@1.1.1: resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} - electron-to-chromium@1.5.343: - resolution: {integrity: sha512-YHnQ3MXI08icvL9ZKnEBy05F2EQ8ob01UaMOuMbM8l+4UcAq6MPPbBTJBbsBUg3H8JeZNt+O4fjsoWth3p6IFg==} + electron-to-chromium@1.5.360: + resolution: {integrity: sha512-GkcBt6YYAw9SxFWn+xVar4cLVGlXVuswwtRLBozi2zp0GjXs4ZnOrqV4zbXzg35n7w81hCkyJNYicgXlVHAmBA==} emoji-regex@10.6.0: resolution: {integrity: sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==} @@ -7334,25 +7566,22 @@ packages: resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} engines: {node: '>= 0.8'} - encoding@0.1.13: - resolution: {integrity: sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==} - end-of-stream@1.4.5: resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==} - engine.io-client@6.6.4: - resolution: {integrity: sha512-+kjUJnZGwzewFDw951CDWcwj35vMNf2fcj7xQWOctq1F2i1jkDdVvdFG9kM/BEChymCH36KgjnW0NsL58JYRxw==} + engine.io-client@6.6.5: + resolution: {integrity: sha512-QCwxUDULPlXv8F6tqMMKx5dNkTe6OaBYRMPYeXKBlyOoKvAmE0ac6pW7fFhSscJ/5SI7666/U/B+MElbsrJlIg==} engine.io-parser@5.2.3: resolution: {integrity: sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==} engines: {node: '>=10.0.0'} - engine.io@6.6.5: - resolution: {integrity: sha512-2RZdgEbXmp5+dVbRm0P7HQUImZpICccJy7rN7Tv+SFa55pH+lxnuw6/K1ZxxBfHoYpSkHLAO92oa8O4SwFXA2A==} + engine.io@6.6.8: + resolution: {integrity: sha512-2agL3ueZhqxoVrfmntO8yuVj+uNSlIOnhykYHk3Cq0ShYPdUjjUiSJrQvXjq01I9jAuI0Zl2YO8Evv5Mqytm5g==} engines: {node: '>=10.2.0'} - enhanced-resolve@5.21.0: - resolution: {integrity: sha512-otxSQPw4lkOZWkHpB3zaEQs6gWYEsmX4xQF68ElXC/TWvGxGMSGOvoNbaLXm6/cS/fSfHtsEdw90y20PCd+sCA==} + enhanced-resolve@5.21.5: + resolution: {integrity: sha512-mLCNbrQli11K1ySUmuNt4ZUB3OpGIDq4q2vTBTf5cL2lpsRjI9QKqSD0ndjW8FyvcW/Jj46gMe9syyHAsvMa/A==} engines: {node: '>=10.13.0'} entities@2.2.0: @@ -7378,9 +7607,6 @@ packages: resolution: {integrity: sha512-dtJUTepzMW3Lm/NPxRf3wP4642UWhjL2sQxc+ym2YMj1m/H2zDNQOlezafzkHwn6sMstjHTwG6iQQsctDW/b1A==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - err-code@2.0.3: - resolution: {integrity: sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==} - error-ex@1.3.4: resolution: {integrity: sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==} @@ -7406,6 +7632,9 @@ packages: resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} engines: {node: '>= 0.4'} + es-toolkit@1.46.1: + resolution: {integrity: sha512-5eNtXOs3tbfxXOj04tjjseeWkRWaoCjdEI+96DgwzZoe6c9juL49pXlzAFTI72aWC9Y8p7168g6XIKjh7k6pyQ==} + es5-ext@0.10.64: resolution: {integrity: sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg==} engines: {node: '>=0.10'} @@ -7436,6 +7665,11 @@ packages: engines: {node: '>=18'} hasBin: true + esbuild@0.27.7: + resolution: {integrity: sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w==} + engines: {node: '>=18'} + hasBin: true + esbuild@0.28.0: resolution: {integrity: sha512-sNR9MHpXSUV/XB4zmsFKN+QgVG82Cc7+/aaxJ8Adi8hyOac+EXptIp45QBPaVyX3N70664wRbTcLTOemCAnyqw==} engines: {node: '>=18'} @@ -7483,9 +7717,9 @@ packages: oxlint: optional: true - eslint-plugin-compat@7.0.1: - resolution: {integrity: sha512-wDID2fVIAfxV9R1uSkCn5HscnNu8yMxDF1IaQGyD1C6XuWwJbuaDgMOSkVgOom0LzY8z0fXXXCy7AQQTERQUvQ==} - engines: {node: '>=18.x'} + eslint-plugin-compat@7.0.2: + resolution: {integrity: sha512-gN8hF+4NzMsHUbr4m/TYZK0FtW3DcV4g8rXpTsY2EV5xiRD8jsilUlB9lNSkGGX0veDCxMhKSWbSd+faJByQDA==} + engines: {node: '>=22.x'} peerDependencies: eslint: ^9.0.0 || ^10.0.0 @@ -7543,8 +7777,8 @@ packages: resolution: {integrity: sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} - eslint@10.2.1: - resolution: {integrity: sha512-wiyGaKsDgqXvF40P8mDwiUp/KQjE1FdrIEJsM8PZ3XCiniTMXS3OHWWUe5FI5agoCnr8x4xPrTDZuxsBlNHl+Q==} + eslint@10.4.0: + resolution: {integrity: sha512-loXy6bWOoP3EP6JA7jo6p5jMpBJmHmsNZM5SFRHLdh1MGOPurMnNBj4ZlAbaqUAaQWbCr7jHV4P7gzAyryZWkQ==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} hasBin: true peerDependencies: @@ -7577,8 +7811,13 @@ packages: resolution: {integrity: sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==} engines: {node: '>=0.10'} - esrap@2.2.4: - resolution: {integrity: sha512-suICpxAmZ9A8bzJjEl/+rLJiDKC0X4gYWUxT6URAWBLvlXmtbZd5ySMu/N2ZGEtMCAmflUDPSehrP9BQcsGcSg==} + esrap@2.2.9: + resolution: {integrity: sha512-4KijP+NxCWthMCUC3qHbE6n4vCjqgJS1uAYKhuT/GWfFTf1Qyive2TgOjep+gzbSzRfnNyaN/UU9YmdOt8Eg0A==} + peerDependencies: + '@typescript-eslint/types': ^8.2.0 + peerDependenciesMeta: + '@typescript-eslint/types': + optional: true esrecurse@4.3.0: resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} @@ -7627,8 +7866,8 @@ packages: resolution: {integrity: sha512-UVQ72Rqjy/ZKQalzV5dCCJP80GrmPrMxh6NlNf+erV6ObL0ZFkhCstWRawS85z3smdr3d2wXPsZEY7rDPfGd2g==} engines: {node: '>=6.0.0'} - eta@4.5.1: - resolution: {integrity: sha512-EaNCGm+8XEIU7YNcc+THptWAO5NfKBHHARxt+wxZljj9bTr/+arRoOm9/MpGt4n6xn9fLnPFRSoLD0WFYGFUxQ==} + eta@4.6.0: + resolution: {integrity: sha512-lW6is4T1NFOYnmqGZIfvixqj7A7sSvScF+DN8EK6K58xI5MZ5UvYe0GjopxOXQtZvUn4eDdVuZ8XSoYWTMEKwA==} engines: {node: '>=20'} etag@1.8.1: @@ -7711,8 +7950,8 @@ packages: exponential-backoff@3.1.3: resolution: {integrity: sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA==} - express@4.22.1: - resolution: {integrity: sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g==} + express@4.22.2: + resolution: {integrity: sha512-IuL+Elrou2ZvCFHs18/CIzy2Nzvo25nZ1/D2eIZlz7c+QUayAcYoiM2BthCjs+EBHVpjYjcuLDAiCWgeIX3X1Q==} engines: {node: '>= 0.10.0'} express@5.2.1: @@ -7729,8 +7968,8 @@ packages: extend@3.0.2: resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} - fabric@7.3.1: - resolution: {integrity: sha512-RoLAQzUX+/3RNMYKliuN0P2HXdSDEGzyjS7FnmEbo3nhb8LFh59T+l3f6ApIu5LT4YB49YfMNrEajeIbutmD7Q==} + fabric@7.4.0: + resolution: {integrity: sha512-NalYDc3eifTl1C33zryQwpH6+XA/2ClxQrH9vkASkZw3tbkRmorpikhYMmxhUTmi7O3e9ODz0vOT8qfaCh9IVA==} engines: {node: '>=20.0.0'} factory.ts@1.4.2: @@ -7759,8 +7998,8 @@ packages: fast-safe-stringify@2.1.1: resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==} - fast-uri@3.1.0: - resolution: {integrity: sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==} + fast-uri@3.1.2: + resolution: {integrity: sha512-rVjf7ArG3LTk+FS6Yw81V1DLuZl1bRbNrev6Tmd/9RaroeeRRJhAt7jg/6YFxbvAQXUCavSoZhPPj6oOx+5KjQ==} fastq@1.20.1: resolution: {integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==} @@ -7785,8 +8024,8 @@ packages: resolution: {integrity: sha512-u5/sxGfiMfZNtJ3OvQpXcvotFpYkL0n9u9mM2vkui2nGo8b4wvDkJ8gAkYqbA8QpGyFCv3RK0Z+Iv+9veCS9bQ==} engines: {node: '>=0.4.0'} - fflate@0.8.2: - resolution: {integrity: sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==} + fflate@0.8.3: + resolution: {integrity: sha512-tbZNuJrLwGUp3zshBtdy4W+ORxZuIh8a5ilyIEQDC5rY1f3U20JMry0Ll3WBzU58EZKsEuJFXhb5gwv8CsPvgA==} figures@3.2.0: resolution: {integrity: sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==} @@ -7860,8 +8099,8 @@ packages: engines: {node: '>=18'} deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. - follow-redirects@1.15.11: - resolution: {integrity: sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==} + follow-redirects@1.16.0: + resolution: {integrity: sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==} engines: {node: '>=4.0'} peerDependencies: debug: '*' @@ -7921,18 +8160,14 @@ packages: resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==} engines: {node: '>=12'} - fs-extra@11.3.4: - resolution: {integrity: sha512-CTXd6rk/M3/ULNQj8FBqBWHYBVYybQ3VPBw0xGKFe3tuH7ytT6ACnvzpIQ3UZtB8yvUKC2cXn1a+x+5EVQLovA==} + fs-extra@11.3.5: + resolution: {integrity: sha512-eKpRKAovdpZtR1WopLHxlBWvAgPny3c4gX1G5Jhwmmw4XJj0ifSD5qB5TOo8hmA0wlRKDAOAhEE1yVPgs6Fgcg==} engines: {node: '>=14.14'} fs-minipass@2.1.0: resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==} engines: {node: '>= 8'} - fs-minipass@3.0.3: - resolution: {integrity: sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - fs-monkey@1.1.0: resolution: {integrity: sha512-QMUezzXWII9EV5aTFXW1UBVUO77wYPpjqIF8/AviUCThNeSYZykpoTixUeaNNBwmCev0AMDWMAni+f8Hxb1IFw==} @@ -7968,8 +8203,8 @@ packages: geo-coordinates-parser@1.7.4: resolution: {integrity: sha512-gVGxBW+s1csexXVMf5bIwz3TH9n4sCEglOOOqmrPk8YazUI5f79jCowKjTw05m/0h1//3+Z2m/nv8IIozgZyUw==} - geo-tz@8.1.6: - resolution: {integrity: sha512-6YEper1rtHi1l3ZS99oy9ZBvrBO4qsLzvQwZoxYtV3fyxPuxh7yqiOUWRVs1bzSj693EXEO4k60jKXQmkY/JnQ==} + geo-tz@8.1.7: + resolution: {integrity: sha512-skkwQunTD1hpixwESUv8GeLLl8DElpUmnZfp9trQVgVGVIRTeQJHmCcWELCr8lsiVKdu661TWzR9hsdlGCEEKA==} engines: {node: '>=16'} geobuf@3.0.2: @@ -7984,8 +8219,8 @@ packages: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} - get-east-asian-width@1.5.0: - resolution: {integrity: sha512-CQ+bEO+Tva/qlmw24dCejulK5pMzVnUOFOijVogd3KQs07HnRIgp8TGipvCCRT06xeYEbpbgwaCxglFyiuIcmA==} + get-east-asian-width@1.6.0: + resolution: {integrity: sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA==} engines: {node: '>=18'} get-intrinsic@1.3.0: @@ -8007,8 +8242,8 @@ packages: resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} engines: {node: '>=10'} - get-tsconfig@4.13.0: - resolution: {integrity: sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ==} + get-tsconfig@4.14.0: + resolution: {integrity: sha512-yTb+8DXzDREzgvYmh6s9vHsSVCHeC0G3PI5bEXNBHtmshPnO+S5O7qgLEOn0I5QvMy6kpZN8K1NKGyilLb93wA==} github-from-package@0.0.0: resolution: {integrity: sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==} @@ -8065,8 +8300,8 @@ packages: resolution: {integrity: sha512-c/c15i26VrJ4IRt5Z89DnIzCGDn9EcebibhAOjw5ibqEHsE1wLUgkPn9RDmNcUKyU87GeaL633nyJ+pplFR2ZQ==} engines: {node: '>=18'} - globals@17.5.0: - resolution: {integrity: sha512-qoV+HK2yFl/366t2/Cb3+xxPUo5BuMynomoDmiaZBIdbs+0pYbjfZU+twLhGKp4uCZ/+NbtpVepH5bGCxRyy2g==} + globals@17.6.0: + resolution: {integrity: sha512-sepffkT8stwnIYbsMBpoCHJuJM5l98FUF2AnE07hfvE0m/qp3R586hw4jF4uadbhvg1ooIdzuu7CsfD2jzCaNA==} engines: {node: '>=18'} globalyzer@0.1.0: @@ -8145,8 +8380,8 @@ packages: resolution: {integrity: sha512-IrsVwUHhEULx3R8f/aA8AHuEzAorplsab/v8HBzEiIukwq5i/EC+xmOW+HfP1OaDP+2JkgT1yILHN2O3UFIbcA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - hasown@2.0.2: - resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + hasown@2.0.3: + resolution: {integrity: sha512-ej4AhfhfL2Q2zpMmLo7U1Uv9+PyhIZpgQLGT1F9miIGmiCJIoCgSmczFdrc97mWT4kVY72KA+WnnhJ5pghSvSg==} engines: {node: '>= 0.4'} hast-util-from-parse5@6.0.1: @@ -8253,8 +8488,8 @@ packages: html-void-elements@3.0.0: resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==} - html-webpack-plugin@5.6.5: - resolution: {integrity: sha512-4xynFbKNNk+WlzXeQQ+6YYsH2g7mpfPszQZUi3ovKlj+pDmngQ7vRXjrrmGROabmKwyQkcgcX5hqfOwHbFmK5g==} + html-webpack-plugin@5.6.7: + resolution: {integrity: sha512-md+vXtdCAe60s1k6AU3dUyMJnDxUyQAwfwPKoLisvgUF1IXjtlLsk2se54+qfL9Mdm26bbwvjJybpNx48NKRLw==} engines: {node: '>=10.13.0'} peerDependencies: '@rspack/core': 0.x || 1.x @@ -8281,10 +8516,6 @@ packages: http-deceiver@1.2.7: resolution: {integrity: sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==} - http-errors@1.6.3: - resolution: {integrity: sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==} - engines: {node: '>= 0.6'} - http-errors@1.8.1: resolution: {integrity: sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==} engines: {node: '>= 0.6'} @@ -8388,14 +8619,17 @@ packages: resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} engines: {node: '>=6'} - import-in-the-middle@3.0.0: - resolution: {integrity: sha512-OnGy+eYT7wVejH2XWgLRgbmzujhhVIATQH0ztIeRilwHBjTeG3pD+XnH3PKX0r9gJ0BuJmJ68q/oh9qgXnNDQg==} + import-in-the-middle@3.0.1: + resolution: {integrity: sha512-pYkiyXVL2Mf3pozdlDGV6NAObxQx13Ae8knZk1UJRJ6uRW/ZRmTGHlQYtrsSl7ubuE5F8CD1z+s1n4RHNuTtuA==} engines: {node: '>=18'} import-lazy@4.0.0: resolution: {integrity: sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==} engines: {node: '>=8'} + import-meta-resolve@4.2.0: + resolution: {integrity: sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==} + imurmurhash@0.1.4: resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} engines: {node: '>=0.8.19'} @@ -8416,9 +8650,6 @@ packages: resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. - inherits@2.0.3: - resolution: {integrity: sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==} - inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} @@ -8446,8 +8677,8 @@ packages: intl-messageformat@10.7.18: resolution: {integrity: sha512-m3Ofv/X/tV8Y3tHXLohcuVuhWKo7BBq62cqY15etqmLxg2DZ34AGGgQDeR+SCta2+zICb1NX83af0GJmbQ1++g==} - intl-messageformat@11.2.1: - resolution: {integrity: sha512-1gAVEUt3wEPvTqML4Fsw9klZV5j0vszQxayP/fi6gUroAc8AUHiNaisBKLWxybL1AdWq1mP07YV1q8v4N92ilQ==} + intl-messageformat@11.2.6: + resolution: {integrity: sha512-afAN2yNN7zjB77G1ZC5L8GtLrEshyBvOQXz88flxCO/ocTIQist98gu0r/O6H/SSiQhQsOOtWPxmCEvtDABXXQ==} invariant@2.2.4: resolution: {integrity: sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==} @@ -8456,16 +8687,12 @@ packages: resolution: {integrity: sha512-HuEDBTI70aYdx1v6U97SbNx9F1+svQKBDo30o0b9fw055LMepzpOOd0Ccg9Q6tbqmBSJaMuY0fB7yw9/vjBYCA==} engines: {node: '>=12.22.0'} - ip-address@10.1.0: - resolution: {integrity: sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==} - engines: {node: '>= 12'} - ipaddr.js@1.9.1: resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} engines: {node: '>= 0.10'} - ipaddr.js@2.3.0: - resolution: {integrity: sha512-Zv/pA+ciVFbCSBBjGfaKUya/CcGmUHzTydLMaTwrUUEM2DIEO3iZvueGxmacvmN50fGpGVKeTXpb2LcYQxeVdg==} + ipaddr.js@2.4.0: + resolution: {integrity: sha512-9VGk3HGanVE6JoZXHiCpnGy5X0jYDnN4EA4lntFPj+1vIWlFhIylq2CrrCOJH9EAhc5CYhq18F2Av2tgoAPsYQ==} engines: {node: '>= 10'} is-alphabetical@2.0.1: @@ -8493,8 +8720,8 @@ packages: resolution: {integrity: sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==} hasBin: true - is-core-module@2.16.1: - resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} + is-core-module@2.16.2: + resolution: {integrity: sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA==} engines: {node: '>= 0.4'} is-decimal@2.0.1: @@ -8550,8 +8777,8 @@ packages: resolution: {integrity: sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==} engines: {node: '>=12'} - is-network-error@1.3.0: - resolution: {integrity: sha512-6oIwpsgRfnDiyEDLMay/GqCl3HoAtH5+RUKW29gYkL0QA+ipzpDLA16yQs7/RHCSu+BwgbJaOUqa4A99qNVQVw==} + is-network-error@1.3.2: + resolution: {integrity: sha512-PhBY86zaxNZUuWP6h13Vu5oFe0XY6/UlKzQnYFELzGVHygP3MxmvTfYSG7GN3aIab/iWudSMgjSnG9Dq+nHrgA==} engines: {node: '>=16'} is-npm@6.1.0: @@ -8703,8 +8930,8 @@ packages: resolution: {integrity: sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==} hasBin: true - jiti@2.6.1: - resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==} + jiti@2.7.0: + resolution: {integrity: sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==} hasBin: true jmespath@0.16.0: @@ -8714,8 +8941,8 @@ packages: joi@17.13.3: resolution: {integrity: sha512-otDA4ldcIx+ZXsKHWmp0YizCweVRZG96J10b0FevjfuncLO1oX59THoAmHkNubYJ+9gWsYsp5k8v4ib6oDv1fA==} - jose@6.2.2: - resolution: {integrity: sha512-d7kPDd34KO/YnzaDOlikGpOurfF0ByC2sEV4cANCtdqLlTfBlw2p14O/5d/zv40gJPbIQxfES3nSx1/oYNyuZQ==} + jose@6.2.3: + resolution: {integrity: sha512-YYVDInQKFJfR/xa3ojUTl8c2KoTwiL1R5Wg9YCydwH0x0B9grbzlg5HC7mMjCtUJjbQ/YnGEZIhI5tCgfTb4Hw==} js-tokens@10.0.0: resolution: {integrity: sha512-lM/UBzQmfJRo9ABXbPWemivdCW8V2G8FHaHdypQaIy523snUjog0W71ayWXTjiR+ixeMyVHN2XcpnTd/liPg/Q==} @@ -8767,9 +8994,6 @@ packages: json-schema-typed@8.0.2: resolution: {integrity: sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==} - json-schema@0.4.0: - resolution: {integrity: sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==} - json-source-map@0.6.1: resolution: {integrity: sha512-1QoztHPsMQqhDq0hlXY5ZqcEdUzxQEIxgFkKl4WUp2pgShObl+9ovi4kRh2TfvAfxAoHOJ9vIMEqk3k4iex7tg==} @@ -8815,12 +9039,12 @@ packages: jws@4.0.1: resolution: {integrity: sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==} - katex@0.16.27: - resolution: {integrity: sha512-aeQoDkuRWSqQN6nSvVCEFvfXdqo1OQiCmmW1kc9xSdjutPv7BGO7pqY9sQRJpMOGrEdfDgF2TfRXe5eUAD2Waw==} + katex@0.16.47: + resolution: {integrity: sha512-Eeo8Ys1doU1z+x8AZsPpQu+p/QcZBI5PeOo7QGQdy2x2m0MU/hYagBbGOmXwr5KVbEfVuWv9LpnQWeehogurjg==} hasBin: true - kdbush@4.0.2: - resolution: {integrity: sha512-WbCVYJ27Sz8zi9Q7Q0xHC+05iwkm3Znipc2XTlrnJbsHMYktW4hPhXUE8Ys1engBrvffoSCqbil1JQAa7clRpA==} + kdbush@4.1.0: + resolution: {integrity: sha512-e9vurzrXJQrFX6ckpHP3bvj5l+9CnYzkxDNnNQ1h2QTqdWsUAJgXiKdGNcOa1EY85dU8KbQ+z/FdQdB7P+9yfQ==} keygrip@1.1.0: resolution: {integrity: sha512-iYSchDJ+liQ8iwbSI2QqsQOvqv58eJCEanyJPJi+Khyu8smkcKSFUCbPwzFcL7YVtZ6eONjqRX/38caJ7QjRAQ==} @@ -8872,16 +9096,12 @@ packages: resolution: {integrity: sha512-4YAVLoF0Sf0UTqlhgQMFU9iQECdah7n+13ANkiuVfRvlK+uI0Etbgd7bVP36dKlG+NXWbhGua8vnGt+sdhvT7A==} engines: {node: '>=18.0.0'} - langium@3.3.1: - resolution: {integrity: sha512-QJv/h939gDpvT+9SiLVlY7tZC3xB2qK57v0J04Sh9wpMb6MP1q8gB21L3WIo8T5P1MSMg3Ep14L7KkDCFG3y4w==} - engines: {node: '>=16.0.0'} - latest-version@7.0.0: resolution: {integrity: sha512-KvNT4XqAMzdcL6ka6Tl3i2lYeFDgXNCuIX+xNx6ZMVR1dFq+idXd9FLKNMOIx0t9mJ9/HudyX4oZWXZQ0UJHeg==} engines: {node: '>=14.16'} - launch-editor@2.12.0: - resolution: {integrity: sha512-giOHXoOtifjdHqUamwKq6c49GzBdLjvxrd2D+Q4V6uOHopJv7p9VJxikDsQ/CBXZbEITgUqSVHXLTG3VhPP1Dg==} + launch-editor@2.13.2: + resolution: {integrity: sha512-4VVDnbOpLXy/s8rdRCSXb+zfMeFR0WlJWpET1iA9CQdlZDfwyLjUuGQzXU4VeOoey6AicSAluWan7Etga6Kcmg==} layout-base@1.0.2: resolution: {integrity: sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg==} @@ -9000,8 +9220,8 @@ packages: resolution: {integrity: sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - loader-runner@4.3.1: - resolution: {integrity: sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q==} + loader-runner@4.3.2: + resolution: {integrity: sha512-DFEqQ3ihfS9blba08cLfYf1NRAIEm+dDjic073DRDc3/JspI/8wYmtDsHwd3+4hwvdxSK7PGaElfTmm0awWJ4w==} engines: {node: '>=6.11.5'} loader-utils@2.0.4: @@ -9023,9 +9243,6 @@ packages: resolution: {integrity: sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - lodash-es@4.17.21: - resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==} - lodash-es@4.18.1: resolution: {integrity: sha512-J8xewKD/Gk22OZbhpOVSwcs60zhd95ESDwezOFuA3/099925PdHJ7OFHNTGtajL3AlZkykD32HykiMo+BIBI8A==} @@ -9106,8 +9323,8 @@ packages: lru-cache@10.4.3: resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} - lru-cache@11.3.5: - resolution: {integrity: sha512-NxVFwLAnrd9i7KUBxC4DrUhmgjzOs+1Qm50D3oF1/oL+r1NpZ4gA7xvG0/zJ8evR7zIKn4vLf7qTNduWFtCrRw==} + lru-cache@11.5.0: + resolution: {integrity: sha512-5YgH9UJd7wVb9hIouI2adWpgqrrICkt070Dnj8EUY1+B4B2P9eRLPAkAAo6NICA7CEhOIeBHl46u9zSNpNu7zA==} engines: {node: 20 || >=22} lru-cache@5.1.1: @@ -9116,8 +9333,8 @@ packages: lru-queue@0.1.0: resolution: {integrity: sha512-BpdYkt9EvGl8OfWHDQPISVpcl5xZthb+XPsbELj5AQXxIC8IriDZIQYjBJPEm5rS420sjZ0TLEzRcq5KdBhYrQ==} - lunr-languages@1.14.0: - resolution: {integrity: sha512-hWUAb2KqM3L7J5bcrngszzISY4BxrXn/Xhbb9TTCJYEGqlR1nG67/M14sp09+PTIRklobrn57IAxcdcO/ZFyNA==} + lunr-languages@1.20.0: + resolution: {integrity: sha512-3LVgE7ekWXt04NBci/hjm+NXJxXZeRXuyClL0kA0HONyBOjxhP3ZQkuWIM4Ok3pbeptUW/rj3XcJcJuJVPwPYA==} lunr@2.3.9: resolution: {integrity: sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==} @@ -9139,8 +9356,8 @@ packages: magicast@0.3.5: resolution: {integrity: sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ==} - magicast@0.5.2: - resolution: {integrity: sha512-E3ZJh4J3S9KfwdjZhe2afj6R9lGIN5Pher1pF39UGrXRqq/VDaGVIGN13BjHd2u8B61hArAGOnso7nBOouW3TQ==} + magicast@0.5.3: + resolution: {integrity: sha512-pVKE4UdSQ7DvHzivsCIFx2BJn1mHG6KsyrFcaxFx6tONdneEuThrDx0Cj3AMg58KyN4pzYT+LHOotxDQDjNvkw==} make-dir@3.1.0: resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==} @@ -9150,10 +9367,6 @@ packages: resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} engines: {node: '>=10'} - make-fetch-happen@15.0.3: - resolution: {integrity: sha512-iyyEpDty1mwW3dGlYXAJqC/azFn5PPvgKVwXayOGBSmKLxhKZ9fg4qIan2ePpp1vJIwfFiO34LAPZgq9SZW9Aw==} - engines: {node: ^20.17.0 || >=22.9.0} - maplibre-gl@5.24.0: resolution: {integrity: sha512-ALyFxgtd5R+65UqZ/++lOqwWcC0SNho9c27fYSyLmG7AfnAul2o46F05aDJGPbFU57wos9dgcIySHs0Xe6ia3A==} engines: {node: '>=16.14.0', npm: '>=8.1.0'} @@ -9188,8 +9401,8 @@ packages: mdast-util-find-and-replace@3.0.2: resolution: {integrity: sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==} - mdast-util-from-markdown@2.0.2: - resolution: {integrity: sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==} + mdast-util-from-markdown@2.0.3: + resolution: {integrity: sha512-W4mAWTvSlKvf8L6J+VN9yLSqQ9AOAAvHuoDAmPkz4dHf553m5gVj2ejadHJhoJmcmxEnOv6Pa8XJhpxE93kb8Q==} mdast-util-frontmatter@2.0.1: resolution: {integrity: sha512-LRqI9+wdgC25P0URIJY9vwocIzCcksduHQ9OF2joxQoyTNVduwLAFUzjoopuRJbJAReaKrNQKAZKL3uCMugWJA==} @@ -9242,8 +9455,8 @@ packages: mdn-data@2.0.30: resolution: {integrity: sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==} - mdn-data@2.27.1: - resolution: {integrity: sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==} + mdn-data@2.28.0: + resolution: {integrity: sha512-uy9AS1yt+wW5eUEefgE3lOpqPghanUttycV0GXKbiXyBjwvbeE8XPj4u1C+voRfz7dEjwU4NDHTMfZ/s/JtZrQ==} media-chrome@4.19.0: resolution: {integrity: sha512-HWhDTwts+BSbdPkkB1VsJXp5kvL0IxY7xFT5tBwliM2+89kTPVTnHnev+9it2f9PweANjT/C8/C/S0PW9oyZbA==} @@ -9286,8 +9499,8 @@ packages: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} - mermaid@11.12.2: - resolution: {integrity: sha512-n34QPDPEKmaeCG4WDMGy0OT6PSyxKCfy2pJgShP+Qow2KLrvWjclwbc3yXfSIf4BanqWEhQEpngWwNp/XhZt6w==} + mermaid@11.15.0: + resolution: {integrity: sha512-pTMbcf3rWdtLiYGpmoTjHEpeY8seiy6sR+9nD7LOs8KfUbHE4lOUAprTRqRAcWSQ6MQpdX+YEsxShtGsINtPtw==} methods@1.1.2: resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} @@ -9474,8 +9687,8 @@ packages: resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} engines: {node: '>=4'} - mini-css-extract-plugin@2.9.4: - resolution: {integrity: sha512-ZWYT7ln73Hptxqxk2DxPU9MmapXRhxkJD6tkSR04dnQxm8BGu2hzgKLugK5yySD97u/8yy7Ma7E76k9ZdvtjkQ==} + mini-css-extract-plugin@2.10.2: + resolution: {integrity: sha512-AOSS0IdEB95ayVkxn5oGzNQwqAi2J0Jb/kKm43t7H73s8+f5873g0yuj0PNvK4dO75mu5DHg4nlgp4k6Kga8eg==} engines: {node: '>= 12.13.0'} peerDependencies: webpack: ^5.0.0 @@ -9501,26 +9714,6 @@ packages: minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} - minipass-collect@2.0.1: - resolution: {integrity: sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw==} - engines: {node: '>=16 || 14 >=14.17'} - - minipass-fetch@5.0.1: - resolution: {integrity: sha512-yHK8pb0iCGat0lDrs/D6RZmCdaBT64tULXjdxjSMAqoDi18Q3qKEUTHypHQZQd9+FYpIS+lkvpq6C/R6SbUeRw==} - engines: {node: ^20.17.0 || >=22.9.0} - - minipass-flush@1.0.5: - resolution: {integrity: sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==} - engines: {node: '>= 8'} - - minipass-pipeline@1.2.4: - resolution: {integrity: sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==} - engines: {node: '>=8'} - - minipass-sized@2.0.0: - resolution: {integrity: sha512-zSsHhto5BcUVM2m1LurnXY6M//cGhVaegT71OfOXoprxT6o780GZd792ea6FfrQkuU4usHZIUczAQMRUE2plzA==} - engines: {node: '>=8'} - minipass@3.3.6: resolution: {integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==} engines: {node: '>=8'} @@ -9558,11 +9751,8 @@ packages: engines: {node: '>=10'} hasBin: true - mlly@1.8.0: - resolution: {integrity: sha512-l8D9ODSRWLe2KHJSifWGwBqpTZXIXTeo8mlKjY+E2HAakaTeNpqAyBZ8GSqLzHgw4XmHmC8whvpjJNMbFZN7/g==} - - mnemonist@0.40.3: - resolution: {integrity: sha512-Vjyr90sJ23CKKH/qPAgUKicw/v6pRoamxIEDFOF8uSgFME7DqPRpHgRTejWVjkdGg5dXj0/NyxZHZ9bcjH+2uQ==} + mnemonist@0.40.4: + resolution: {integrity: sha512-ZAv+KNavneRVzu4tUeOgzkScI3W5BGwZ3rkxIpKtzzVgfTtWQFN1CgX0U72cyvyh3iTuHL3SiSmrQxTlryEIcw==} mock-fs@5.5.0: resolution: {integrity: sha512-d/P1M/RacgM3dB0sJ8rjeRNXxtapkPCUnMGmIN0ixJ16F/E4GUZCvWcSGfWGz8eaXYvn1s9baUwNjI4LOPEjiA==} @@ -9592,8 +9782,8 @@ packages: resolution: {integrity: sha512-P0efT1C9jIdVRefqjzOQ9Xml57zpOXnIuS+csaB4MdZbTdmGDLo8XhzBG1N7aO11gKDDkJvBLULeFTo46wwreA==} hasBin: true - msgpackr@1.11.5: - resolution: {integrity: sha512-UjkUHN0yqp9RWKy0Lplhh+wlpdt9oQBYgULZOiFhV3VclSF1JnSQWZ5r9gORQlNYaUKQoR8itv7g7z1xDDuACA==} + msgpackr@2.0.1: + resolution: {integrity: sha512-9J+tqTEsbHqY8YohazYgty7LgerFIWxvMLpUjqETSmjHojtJm2WnX2kK/2a1fLI7CO7ERP1YSEUXMucz4j+yBA==} multer@2.1.1: resolution: {integrity: sha512-mo+QTzKlx8R7E5ylSXxWzGoXoZbOsRMpyitcht8By2KHvMbf3tjwosZ/Mu/XYU6UuJ3VZnODIrak5ZrPiPyB6A==} @@ -9620,16 +9810,16 @@ packages: mz@2.7.0: resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} - nan@2.26.2: - resolution: {integrity: sha512-0tTvBTYkt3tdGw22nrAy50x7gpbGCCFH3AFcyS5WiUu7Eu4vWlri1woE6qHBSfy11vksDqkiwjOnlR7WV8G1Hw==} + nan@2.27.0: + resolution: {integrity: sha512-hC+0LidcL3XE4rp1C4H54KujgXKzbfyTngZTwBByQxsOxCEKZT0MPQ4hOKUH2jU1OYstqdDH4onyHPDzcV0XdQ==} - nanoid@3.3.11: - resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} + nanoid@3.3.12: + resolution: {integrity: sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true - nanoid@5.1.9: - resolution: {integrity: sha512-ZUvP7KeBLe3OZ1ypw6dI/TzYJuvHP77IM4Ry73waSQTLn8/g8rpdjfyVAh7t1/+FjBtG4lCP42MEbDxOsRpBMw==} + nanoid@5.1.11: + resolution: {integrity: sha512-v+KEsUv2ps74PaSKv0gHTxTCgMXOIfBEbaqa6w6ISIGC7ZsvHN4N9oJ8d4cmf0n5oTzQz2SLmThbQWhjd/8eKg==} engines: {node: ^18 || >=20} hasBin: true @@ -9685,15 +9875,15 @@ packages: kysely: 0.x reflect-metadata: ^0.1.13 || ^0.2.2 - nestjs-otel@8.0.2: - resolution: {integrity: sha512-IQZ4MRb54WqRPooFPWrbqdOt+RckwaBjPoQy+axm9Jtri0DlOM6B3mSfzKHAJOwjj6YFaq10DXLOcYrqI8IsXA==} + nestjs-otel@8.0.3: + resolution: {integrity: sha512-48W0ksSnvRZSO7GUY3R76TeHtPwThAhjPOeyH7EOzhLnsrPQ7Msk8nPrU5FpTiIzUapoubdx+jfolRlJC8L21g==} engines: {node: '>= 22'} peerDependencies: '@nestjs/common': '>= 11 < 12' '@nestjs/core': '>= 11 < 12' - nestjs-zod@5.3.0: - resolution: {integrity: sha512-QY6imXm9heMOpWigjFHgMWPvc1ZQHeNQ7pdogo9Q5xj5F8HpqZ972vKlVdkaTyzYlOXJP/yVy3wlF1EjubDQPg==} + nestjs-zod@5.4.0: + resolution: {integrity: sha512-dxVpy1fjfK4kp+ztK+7xQP46fpvZxkeR/jcEdIvEGh/2o71iwXuy/hrKOWSPhJ1nQXV4iBdHqMizndn2GTaXDg==} peerDependencies: '@nestjs/common': ^10.0.0 || ^11.0.0 '@nestjs/swagger': ^7.4.2 || ^8.0.0 || ^11.0.0 @@ -9722,8 +9912,8 @@ packages: node-addon-api@7.1.1: resolution: {integrity: sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==} - node-addon-api@8.5.0: - resolution: {integrity: sha512-/bRZty2mXUIFY/xU5HLvveNHlswNJej+RnxBjOMkidWfwZzgTbPG1E3K5TOxRLOR+5hX7bSofy8yf1hZevMS8A==} + node-addon-api@8.7.0: + resolution: {integrity: sha512-9MdFxmkKaOYVTV+XVRG8ArDwwQ77XIgIPyKASB1k3JPq3M8fGQQQE3YpMOrKm6g//Ktx8ivZr8xo1Qmtqub+GA==} engines: {node: ^18 || ^20 || >= 21} node-emoji@1.11.0: @@ -9742,10 +9932,6 @@ packages: encoding: optional: true - node-forge@1.3.3: - resolution: {integrity: sha512-rLvcdSyRCyouf6jcOIPe/BgwG/d7hKjzMKOas33/pHEr6gbq18IK9zV7DiPvzsz0oBJPme6qr6H6kGZuI9/DZg==} - engines: {node: '>= 6.13.0'} - node-gyp-build-optional-packages@5.2.2: resolution: {integrity: sha512-s+w+rBWnpTMwSFbaE0UXsRlg7hU4FjekKU4eyAih5T8nJuNZT1nNsskXpxmeqSK9UzkBl6UgRlnKc8hz8IEqOw==} hasBin: true @@ -9754,16 +9940,16 @@ packages: resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==} hasBin: true - node-gyp@12.2.0: - resolution: {integrity: sha512-q23WdzrQv48KozXlr0U1v9dwO/k59NHeSzn6loGcasyf0UnSrtzs8kRxM+mfwJSf0DkX0s43hcqgnSO4/VNthQ==} + node-gyp@12.3.0: + resolution: {integrity: sha512-QNcUWM+HgJplcPzBvFBZ9VXacyGZ4+VTOb80PwWR+TlVzoHbRKULNEzpRsnaoxG3Wzr7Qh7BYxGDU3CbKib2Yg==} engines: {node: ^20.17.0 || >=22.9.0} hasBin: true - node-releases@2.0.38: - resolution: {integrity: sha512-3qT/88Y3FbH/Kx4szpQQ4HzUbVrHPKTLVpVocKiLfoYvw9XSGOX2FmD2d6DrXbVYyAQTF2HeF6My8jmzx7/CRw==} + node-releases@2.0.44: + resolution: {integrity: sha512-5WUyunoPMsvvEhS8AxHtRzP+oA8UCkJ7YRxatWKjngndhDGLiqEVAQKWjFAiAiuL8zMRGzGSJxFnLetoa43qGQ==} - nodemailer@8.0.5: - resolution: {integrity: sha512-0PF8Yb1yZuQfQbq+5/pZJrtF6WQcjTd5/S4JOHs9PGFxuTqoB/icwuB44pOdURHJbRKX1PPoJZtY7R4VUoCC8w==} + nodemailer@8.0.7: + resolution: {integrity: sha512-pkjE4mkBzQjdJT4/UmlKl3pX0rC9fZmjh7c6C9o7lv66Ac6w9WCnzPzhbPNxwZAzlF4mdq4CSWB5+FbK6FWCow==} engines: {node: '>=6.0.0'} nopt@1.0.10: @@ -9784,8 +9970,8 @@ packages: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} - normalize-url@8.1.0: - resolution: {integrity: sha512-X06Mfd/5aKsRHc0O0J5CUedwnPmnDtLF2+nq+KN9KSDlJHkPuh0JUviWjEWMe0SW/9TDdSLVPuk7L5gGTIA1/w==} + normalize-url@8.1.1: + resolution: {integrity: sha512-JYc0DPlpGWB40kH5g07gGTrYuMqV653k3uBKY6uITPWds3M0ov3GaWGp9lbE3Bzngx8+XkfzgvASb9vk9JDFXQ==} engines: {node: '>=14.16'} not@0.1.0: @@ -9822,8 +10008,8 @@ packages: engines: {node: '>=18'} hasBin: true - oauth4webapi@3.8.5: - resolution: {integrity: sha512-A8jmyUckVhRJj5lspguklcl90Ydqk61H3dcU0oLhH3Yv13KpAliKTt5hknpGGPZSSfOwGyraNEFmofDYH+1kSg==} + oauth4webapi@3.8.6: + resolution: {integrity: sha512-iwemM91xz8nryHti2yTmg5fhyEMVOkOXwHNqbvcATjyajb5oQxCQzrNOA6uElRHuMhQQTKUyFKV9y/CNyg25BQ==} object-assign@4.1.1: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} @@ -9854,8 +10040,8 @@ packages: obug@2.1.1: resolution: {integrity: sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==} - oidc-provider@9.8.2: - resolution: {integrity: sha512-Iu/VahRoAhgmzKdvqSX/4ZzrG11Zf6NHuhu1wLkoblBnMUIwud++D2lftK8jV/gLhRl3Fppa3RINYCf/675cjw==} + oidc-provider@9.8.3: + resolution: {integrity: sha512-YkchaAyVAZbsn/l7IQhcEMdeDL3lwSo/PNUtnsXSqPqT7EG8DRko0EAWzHd/n9VfCtKVkxGjYOY4h4UwFcWnUA==} on-finished@2.4.1: resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} @@ -9892,8 +10078,8 @@ packages: resolution: {integrity: sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==} hasBin: true - openid-client@6.8.3: - resolution: {integrity: sha512-AoY/NaN9esS3+xvHInFSK0g3skSfeE0uqQAKRj4rB6/GsBIvzwTUaYo9+HcqpKIaP0dP85p5W07hayKgS4GAeA==} + openid-client@6.8.4: + resolution: {integrity: sha512-QSw0BA08piujetEwfZsHoTrDpMEha7GDZDicQqVwX4u0ChCjefvjDB++TZ8BTg76UpwhzIQgdvvfgfl3HpCSAw==} optionator@0.9.4: resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} @@ -9943,10 +10129,6 @@ packages: resolution: {integrity: sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==} engines: {node: '>=10'} - p-map@7.0.4: - resolution: {integrity: sha512-tkAQEw8ysMzmkhgw8k+1U/iPhWNhykKnSk4Rd5zLoPJCuJaGRPo6YposrZgaxHKzDHdDWWZvE/Sk7hsL2X/CpQ==} - engines: {node: '>=18'} - p-queue@6.6.2: resolution: {integrity: sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ==} engines: {node: '>=8'} @@ -10085,30 +10267,30 @@ packages: peberminta@0.9.0: resolution: {integrity: sha512-XIxfHpEuSJbITd1H3EeQwpcZbTLHc+VVr8ANI9t5sit565tsI4/xK3KWTUFE2e6QiangUkh3B0jihzmGnNrRsQ==} - pg-cloudflare@1.3.0: - resolution: {integrity: sha512-6lswVVSztmHiRtD6I8hw4qP/nDm1EJbKMRhf3HCYaqud7frGysPv7FYJ5noZQdhQtN2xJnimfMtvQq21pdbzyQ==} + pg-cloudflare@1.4.0: + resolution: {integrity: sha512-Vo7z/6rrQYxpNRylp4Tlob2elzbh+N/MOQbxFVWCxS7oEx6jF53GTJFxK2WWpKuBRkmiin4Mt+xofFDjx09R0A==} - pg-connection-string@2.12.0: - resolution: {integrity: sha512-U7qg+bpswf3Cs5xLzRqbXbQl85ng0mfSV/J0nnA31MCLgvEaAo7CIhmeyrmJpOr7o+zm0rXK+hNnT5l9RHkCkQ==} + pg-connection-string@2.13.0: + resolution: {integrity: sha512-EMnU9E2fSULdsbErBbMaXJvFeD9B4+nPcM3f+4lsiCR0BHLPrLVjv3DbyM2hgQQviKJaTWIRRTjKjWlHg3p2ig==} pg-int8@1.0.1: resolution: {integrity: sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==} engines: {node: '>=4.0.0'} - pg-pool@3.13.0: - resolution: {integrity: sha512-gB+R+Xud1gLFuRD/QgOIgGOBE2KCQPaPwkzBBGC9oG69pHTkhQeIuejVIk3/cnDyX39av2AxomQiyPT13WKHQA==} + pg-pool@3.14.0: + resolution: {integrity: sha512-gKtPkFdQPU3DksooVLi9LsjZxrsBUZIpa+7aVx+LV5pNh0KzP4Zleud2po+ConrxbuXGBJ6Hfer6hdgpIBpBaw==} peerDependencies: pg: '>=8.0' - pg-protocol@1.13.0: - resolution: {integrity: sha512-zzdvXfS6v89r6v7OcFCHfHlyG/wvry1ALxZo4LqgUoy7W9xhBDMaqOuMiF3qEV45VqsN6rdlcehHrfDtlCPc8w==} + pg-protocol@1.14.0: + resolution: {integrity: sha512-n5taZ1kO3s9ngDTVxsEznOqCyToTgz0FLuPq0B33COy5pPpuWJpY3/2oRBVETuOgzdqRXfWpM9HIhp2LBBT1BA==} pg-types@2.2.0: resolution: {integrity: sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==} engines: {node: '>=4'} - pg@8.20.0: - resolution: {integrity: sha512-ldhMxz2r8fl/6QkXnBD3CR9/xg694oT6DZQ2s6c/RI28OjtSOpxnPrUCGOBJ46RCUxcWdx3p6kw/xnDHjKvaRA==} + pg@8.21.0: + resolution: {integrity: sha512-AUP1EYJuHraQGsVoCQVIcM7TEJVGtDzxWtGFZd8rds9d+CCXlU5Js1rYgfLNvxy9iJrpHjGrRjoi/3BT9fRyiA==} engines: {node: '>= 16.0.0'} peerDependencies: pg-native: '>=3.0.1' @@ -10142,16 +10324,17 @@ packages: resolution: {integrity: sha512-Ie9z/WINcxxLp27BKOCHGde4ITq9UklYKDzVo1nhk5sqGEXU3FpkwP5GM2voTGJkGd9B3Otl+Q4uwSOeSUtOBA==} engines: {node: '>=14.16'} - pkg-types@1.3.1: - resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==} + pkijs@3.4.0: + resolution: {integrity: sha512-emEcLuomt2j03vxD54giVB4SxTjnsqkU692xZOZXHDVoYyypEm+b3jpiTcc+Cf+myooc+/Ly0z01jqeNHVgJGw==} + engines: {node: '>=16.0.0'} - playwright-core@1.59.1: - resolution: {integrity: sha512-HBV/RJg81z5BiiZ9yPzIiClYV/QMsDCKUyogwH9p3MCP6IYjUFu/MActgYAvK0oWyV9NlwM3GLBjADyWgydVyg==} + playwright-core@1.60.0: + resolution: {integrity: sha512-9bW6zvX/m0lEbgTKJ6YppOKx8H3VOPBMOCFh2irXFOT4BbHgrx5hPjwJYLT40Lu+4qtD36qKc/Hn56StUW57IA==} engines: {node: '>=18'} hasBin: true - playwright@1.59.1: - resolution: {integrity: sha512-C8oWjPR3F81yljW9o5OxcWzfh6avkVwDD2VYdwIGqTkl+OGFISgypqzfu7dOe4QNLL2aqcWBmI3PMtLIK233lw==} + playwright@1.60.0: + resolution: {integrity: sha512-hheHdokM8cdqCb0lcE3s+zT4t4W+vvjpGxsZlDnikarzx8tSzMebh3UiFtgqwFwnTnjYQcsyMF8ei2mCO/tpeA==} engines: {node: '>=18'} hasBin: true @@ -10545,8 +10728,8 @@ packages: peerDependencies: postcss: ^8.4 - postcss-preset-env@10.5.0: - resolution: {integrity: sha512-xgxFQPAPxeWmsgy8cR7GM1PGAL/smA5E9qU7K//D4vucS01es3M0fDujhDJn3kY8Ip7/vVYcecbe1yY+vBo3qQ==} + postcss-preset-env@10.6.1: + resolution: {integrity: sha512-yrk74d9EvY+W7+lO9Aj1QmjWY9q5NsKjK2V9drkOPZB/X6KZ0B3igKsHUYakb7oYVhnioWypQX3xGuePf89f3g==} engines: {node: '>=18'} peerDependencies: postcss: ^8.4 @@ -10633,8 +10816,8 @@ packages: peerDependencies: postcss: ^8.4.31 - postcss@8.5.12: - resolution: {integrity: sha512-W62t/Se6rA0Az3DfCL0AqJwXuKwBeYg6nOaIgzP+xZ7N5BFCI7DYi1qs6ygUYT6rvfi6t9k65UMLJC+PHZpDAA==} + postcss@8.5.15: + resolution: {integrity: sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==} engines: {node: ^10 || ^12 || >=14} postgres-array@2.0.0: @@ -10694,8 +10877,8 @@ packages: peerDependencies: prettier: ^3.0.0 - prettier-plugin-svelte@3.5.1: - resolution: {integrity: sha512-65+fr5+cgIKWKiqM1Doum4uX6bY8iFCdztvvp2RcF+AJoieaw9kJOFMNcJo/bkmKYsxFaM9OsVZK/gWauG/5mg==} + prettier-plugin-svelte@3.5.2: + resolution: {integrity: sha512-ItFouLvzSFE3ulNl4DKoWM3BGcbDCNVpIyy/Y3F2gC3aNiGLxtFUdffVqO5Z5hhYG+DFT5KULWaxmeFFpdbvaQ==} peerDependencies: prettier: ^3.0.0 svelte: ^3.2.0 || ^4.0.0-next.0 || ^5.0.0-next.0 @@ -10736,10 +10919,6 @@ packages: resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} engines: {node: '>= 0.6.0'} - promise-retry@2.0.1: - resolution: {integrity: sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==} - engines: {node: '>=10'} - prompts@2.4.2: resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} engines: {node: '>= 6'} @@ -10766,12 +10945,8 @@ packages: proto-list@1.2.4: resolution: {integrity: sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==} - protobufjs@7.5.5: - resolution: {integrity: sha512-3wY1AxV+VBNW8Yypfd1yQY9pXnqTAN+KwQxL8iYm3/BjKYMNg4i0owhEe26PWDOMaIrzeeF98Lqd5NGz4omiIg==} - engines: {node: '>=12.0.0'} - - protobufjs@8.0.1: - resolution: {integrity: sha512-NWWCCscLjs+cOKF/s/XVNFRW7Yih0fdH+9brffR5NZCy8k42yRdl5KlWKMVXuI1vfCoy4o1z80XR/W/QUb3V3w==} + protobufjs@7.6.0: + resolution: {integrity: sha512-LtESOsMPTZgyYtwxhvdgdjGL0HmXEaRA/hVD6sol4zA60hVXXXP/SGmxnqDbgGE8gy7pYex7cym+5vYPcmaXBQ==} engines: {node: '>=12.0.0'} protocol-buffers-schema@3.6.1: @@ -10795,13 +10970,20 @@ packages: resolution: {integrity: sha512-LjgDO2zPtoXP2wJpDjZrGdojii1uqO0cnwKoIoUzkfS98HDmbeiGmYiXo3lXeFlq2xvne1QFQhwYXSUCLKtEuA==} engines: {node: '>=12.20'} + pvtsutils@1.3.6: + resolution: {integrity: sha512-PLgQXQ6H2FWCaeRak8vvk1GW462lMxB5s3Jm673N82zI4vqtVUPuZdffdZbPDFRoU8kAhItWFtPCWiPpp4/EDg==} + + pvutils@1.1.5: + resolution: {integrity: sha512-KTqnxsgGiQ6ZAzZCVlJH5eOjSnvlyEgx1m8bkRJfOhmGRqfo5KLvmAlACQkrjEtOQ4B7wF9TdSLIs9O90MX9xA==} + engines: {node: '>=16.0.0'} + qrcode@1.5.4: resolution: {integrity: sha512-1ca71Zgiu6ORjHqFBDpnSMTR2ReToX4l1Au1VFLyVeBTFavzQnv5JxMFr3ukHVKpSrSA2MCk0lNJSykjUfz7Zg==} engines: {node: '>=10.13.0'} hasBin: true - qs@6.14.1: - resolution: {integrity: sha512-4EK3+xJl8Ts67nLYNwqw/dsFVnCf+qR7RgXSK9jEEm9unao3njwMDdmsdvoKBKHzxd7tCYz5e5M+SnMjdtXGQQ==} + qs@6.15.2: + resolution: {integrity: sha512-Rzq0KEyX/w/tEybncDgdkZrJgVUsUMk3xjh3t5bv3S1HTAtg+uOYt72+ZfwiQwKdysThkTBdL/rTi6HDmX9Ddw==} engines: {node: '>=0.6'} queue-lit@1.5.2: @@ -10858,10 +11040,10 @@ packages: resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} hasBin: true - react-dom@19.2.5: - resolution: {integrity: sha512-J5bAZz+DXMMwW/wV3xzKke59Af6CHY7G4uYLN1OvBcKEsWOs4pQExj86BBKamxl/Ik5bx9whOrvBlSDfWzgSag==} + react-dom@19.2.6: + resolution: {integrity: sha512-0prMI+hvBbPjsWnxDLxlCGyM8PN6UuWjEUCYmZhO67xIV9Xasa/r/vDnq+Xyq4Lo27g8QSbO5YzARu0D1Sps3g==} peerDependencies: - react: ^19.2.5 + react: ^19.2.6 react-email@5.2.11: resolution: {integrity: sha512-9TzTGRGeavli/iv1RICVOePnFOeG2YRyr8kAyXj6Zgudteq60uA0txDwe4q1zIjQ+08fcbzBkSnI9HgPkSK5OA==} @@ -10906,8 +11088,8 @@ packages: peerDependencies: react: '>=15' - react@19.2.5: - resolution: {integrity: sha512-llUJLzz1zTUBrskt2pwZgLq59AemifIftw4aB7JxOqf1HY2FDaGDxgwpAPVzHU1kdWabH7FauP4i1oEeer2WCA==} + react@19.2.6: + resolution: {integrity: sha512-sfWGGfavi0xr8Pg0sVsyHMAOziVYKgPLNrS7ig+ivMNb3wbCBw3KxtflsGBAwD3gYQlE/AEZsTLgToRrSCjb0Q==} engines: {node: '>=0.10.0'} read-cache@1.0.0: @@ -10979,8 +11161,8 @@ packages: resolution: {integrity: sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA==} engines: {node: '>=4'} - registry-auth-token@5.1.0: - resolution: {integrity: sha512-GdekYuwLXLxMuFTwAPg5UKGLW/UXzQrZvH/Zj791BQif5T05T0RsaLfHc9q3ZOKi7n+BoprPD9mJ0O0k4xzUlw==} + registry-auth-token@5.1.1: + resolution: {integrity: sha512-P7B4+jq8DeD2nMsAcdfaqHbssgHtZ7Z5+++a5ask90fvmJ8p5je4mOa+wzu+DB4vQ5tdJV/xywY+UnVFeQLV5Q==} engines: {node: '>=14'} registry-url@6.0.1: @@ -10990,8 +11172,8 @@ packages: regjsgen@0.8.0: resolution: {integrity: sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==} - regjsparser@0.13.0: - resolution: {integrity: sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q==} + regjsparser@0.13.1: + resolution: {integrity: sha512-dLsljMd9sqwRkby8zhO1gSg3PnJIBFid8f4CQj/sXx+7cKx+E7u0PKhZ+U4wmhx7EfmtvnA318oVaIkAB1lRJw==} hasBin: true rehype-parse@7.0.1: @@ -11076,8 +11258,8 @@ packages: resolve-protobuf-schema@2.1.0: resolution: {integrity: sha512-kI5ffTiZWmJaS/huM8wZfEMer1eRd7oJQhDuxeCLe3t7N7mX3z94CN0xPxBQxFYQTSNz9T0i+v6inKqSdK8xrQ==} - resolve@1.22.11: - resolution: {integrity: sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==} + resolve@1.22.12: + resolution: {integrity: sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==} engines: {node: '>= 0.4'} hasBin: true @@ -11117,8 +11299,8 @@ packages: robust-predicates@3.0.3: resolution: {integrity: sha512-NS3levdsRIUOmiJ8FZWCP7LG3QpJyrs/TE0Zpf1yvZu8cAJJ6QMW92H1c7kWpdIHo8RvmLxN/o2JXTKHp74lUA==} - rolldown@1.0.0-rc.17: - resolution: {integrity: sha512-ZrT53oAKrtA4+YtBWPQbtPOxIbVDbxT0orcYERKd63VJTF13zPcgXTvD4843L8pcsI7M6MErt8QtON6lrB9tyA==} + rolldown@1.0.1: + resolution: {integrity: sha512-X0KQHljNnEkWNqqiz9zJrGunh1B0HgOxLXvnFpCOcadzcy5qohZ3tqMEUg00vncoRovXuK3ZqCT9KnnKzoInFQ==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true @@ -11135,8 +11317,8 @@ packages: rollup: optional: true - rollup@4.55.1: - resolution: {integrity: sha512-wDv/Ht1BNHB4upNbK74s9usvl7hObDnvVzknxqY/E/O3X6rW1U1rV1aENEfJ54eFZDTNo7zv1f5N4edCluH7+A==} + rollup@4.60.4: + resolution: {integrity: sha512-WHeFSbZYsPu3+bLoNRUuAO+wavNlocOPf3wSHTP7hcFKVnJeWsYlCDbr3mTS14FCizf9ccIxXA8sGL8zKeQN3g==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true @@ -11205,8 +11387,9 @@ packages: engines: {node: '>=14.0.0'} hasBin: true - sax@1.4.3: - resolution: {integrity: sha512-yqYn1JhPczigF94DMS+shiDMjDowYO6y9+wB/4WgO0Y19jWYk0lQ4tuG5KI7kj4FTp1wxPj5IFfcrz/s1c3jjQ==} + sax@1.6.0: + resolution: {integrity: sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA==} + engines: {node: '>=11.0.0'} saxes@6.0.0: resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==} @@ -11239,9 +11422,9 @@ packages: select-hose@2.0.0: resolution: {integrity: sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==} - selfsigned@2.4.1: - resolution: {integrity: sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==} - engines: {node: '>=10'} + selfsigned@5.5.0: + resolution: {integrity: sha512-ftnu3TW4+3eBfLRFnDEkzGxSF/10BJBkaLJuBHZX0kiPS7bRdlpZGu6YGt4KngMkdTwJE6MbjavFpqHvqVt+Ew==} + engines: {node: '>=18'} semver-diff@4.0.0: resolution: {integrity: sha512-0Ju4+6A8iOnpL/Thra7dZsSlOHYAHIeMxfhWQRI1/VLcT3WDBZKKtQt/QkBOsiIN9ZpuvHE6cGZ0x4glCMmfiA==} @@ -11251,8 +11434,8 @@ packages: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true - semver@7.7.4: - resolution: {integrity: sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==} + semver@7.8.0: + resolution: {integrity: sha512-AcM7dV/5ul4EekoQ29Agm5vri8JNqRyj39o0qpX6vDF2GZrtutZl5RwgD1XnZjiTAfncsJhMI48QQH3sN87YNA==} engines: {node: '>=10'} hasBin: true @@ -11270,8 +11453,8 @@ packages: serve-handler@6.1.7: resolution: {integrity: sha512-CinAq1xWb0vR3twAv9evEU8cNWkXCb9kd5ePAHUKJBkOsUpR1wt/CvGdeca7vqumL1U5cSaeVQ6zZMxiJ3yWsg==} - serve-index@1.9.1: - resolution: {integrity: sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==} + serve-index@1.9.2: + resolution: {integrity: sha512-KDj11HScOaLmrPxl70KYNW1PksP4Nb/CLL2yvC+Qd2kHMPEEpfc4Re2e4FOay+bC/+XQl/7zAcWON3JVo5v3KQ==} engines: {node: '>= 0.8.0'} serve-static@1.16.3: @@ -11292,9 +11475,6 @@ packages: resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} engines: {node: '>= 0.4'} - setprototypeof@1.1.0: - resolution: {integrity: sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==} - setprototypeof@1.2.0: resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} @@ -11325,8 +11505,8 @@ packages: resolution: {integrity: sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==} engines: {node: '>= 0.4'} - side-channel-list@1.0.0: - resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} + side-channel-list@1.0.1: + resolution: {integrity: sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==} engines: {node: '>= 0.4'} side-channel-map@1.0.1: @@ -11357,8 +11537,8 @@ packages: simple-get@4.0.1: resolution: {integrity: sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==} - simple-icons@16.17.0: - resolution: {integrity: sha512-bRrGtzM6NLgxeMWmRcfDdrRksECk101lRrCn6jjj6qzUB6lQ+E5smnr52rqS1kLPmbLpS/g6iF463j50M4BT7A==} + simple-icons@16.20.0: + resolution: {integrity: sha512-2b7Xu+Zy+iwLiuLSAcWuxnM1ETNFy7JmxWSjh0Y/A8P3KGjFFcokbpWbUf/IivMNbR9WuZ/QQlirh5bGh3Q2vA==} engines: {node: '>=0.12.18'} sirv@2.0.4: @@ -11372,8 +11552,8 @@ packages: sisteransi@1.0.5: resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} - sitemap@7.1.2: - resolution: {integrity: sha512-ARCqzHJ0p4gWt+j7NlU5eDlIO9+Rkr/JhPFZKKQ1l5GCus7rJH4UdrlVAh0xC/gDS/Qir2UMxqYNHtsKr2rpCw==} + sitemap@7.1.3: + resolution: {integrity: sha512-tAjEd+wt/YwnEbfNB2ht51ybBJxbEWwe5ki/Z//Wh0rpBFTCUSj46GnxUKEWzhfuJTsee8x3lybHxFgUMig2hw==} engines: {node: '>=12.0.0', npm: '>=5.6.0'} hasBin: true @@ -11392,22 +11572,18 @@ packages: slice-source@0.4.1: resolution: {integrity: sha512-YiuPbxpCj4hD9Qs06hGAz/OZhQ0eDuALN0lRWJez0eD/RevzKqGdUx1IOMUnXgpr+sXZLq3g8ERwbAH0bCb8vg==} - smart-buffer@4.2.0: - resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==} - engines: {node: '>= 6.0.0', npm: '>= 3.0.0'} - snake-case@3.0.4: resolution: {integrity: sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==} - socket.io-adapter@2.5.6: - resolution: {integrity: sha512-DkkO/dz7MGln0dHn5bmN3pPy+JmywNICWrJqVWiVOyvXjWQFIv9c2h24JrQLLFJ2aQVQf/Cvl1vblnd4r2apLQ==} + socket.io-adapter@2.5.7: + resolution: {integrity: sha512-e0LyK91f3cUxTmv95/KzoLg47+zF+s/sbxRGDNsyG4dmIP8ZSX8ax6byOxfJXeNNtS/8AZlfD+uP7gBeR7DLlg==} socket.io-client@4.8.3: resolution: {integrity: sha512-uP0bpjWrjQmUt5DTHq9RuoCBdFJF10cdX9X+a368j/Ft0wmaVgxlrjvK3kjvgCODOMMOz9lcaRzxmso0bTWZ/g==} engines: {node: '>=10.0.0'} - socket.io-parser@4.2.5: - resolution: {integrity: sha512-bPMmpy/5WWKHea5Y/jYAP6k74A+hvmRCQaJuJB6I/ML5JZq/KfNieUVo/3Mh7SAqn7TyFdIo6wqYHInG1MU1bQ==} + socket.io-parser@4.2.6: + resolution: {integrity: sha512-asJqbVBDsBCJx0pTqw3WfesSY0iRX+2xzWEWzrpcH7L6fLzrhyF8WPI8UaeM4YCuDfpwA/cgsdugMsmtz8EJeg==} engines: {node: '>=10.0.0'} socket.io@4.8.3: @@ -11417,14 +11593,6 @@ packages: sockjs@0.3.24: resolution: {integrity: sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==} - socks-proxy-agent@8.0.5: - resolution: {integrity: sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==} - engines: {node: '>= 14'} - - socks@2.8.7: - resolution: {integrity: sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A==} - engines: {node: '>= 10.0.0', npm: '>= 3.0.0'} - sort-css-media-queries@2.2.0: resolution: {integrity: sha512-0xtkGhWCC9MGt/EzgnvbbbKhqWjl1+/rncmhTh5qCpbYguXh6S/qwePfv/JQ8jePXXmqingylxoC49pCkSPIbA==} engines: {node: '>= 6.3.0'} @@ -11471,8 +11639,8 @@ packages: sprintf-js@1.0.3: resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} - sql-formatter@15.7.3: - resolution: {integrity: sha512-5+zl9Nqg5aNjss0tb1G+StpC4dJKbjv3+g8CL/+V+00PfZop+2RKGyi53ScFl0dr+Dkx1LjmUO54Q3N7K3EtMw==} + sql-formatter@15.8.0: + resolution: {integrity: sha512-HnjdRHlSsO4Ap2erB5YXAvWggrnk/S4TezUn8zmpq9J/hEKn9+6gGaqiKPyDtI10Xf4zJmHYPREGjMjZmmP1fg==} hasBin: true srcset@4.0.0: @@ -11486,10 +11654,6 @@ packages: resolution: {integrity: sha512-wPldCk3asibAjQ/kziWQQt1Wh3PgDFpC0XpwclzKcdT1vql6KeYxf5LIt4nlFkUeR8WuphYMKqUA56X4rjbfgQ==} engines: {node: '>=10.16.0'} - ssri@13.0.1: - resolution: {integrity: sha512-QUiRf1+u9wPTL/76GTYlKttDEBWV1ga9ZXW8BG6kfdeyyM8LGPix9gROyg9V2+P0xNyF3X2Go526xKFdMZrHSQ==} - engines: {node: ^20.17.0 || >=22.9.0} - stackback@0.0.2: resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} @@ -11613,8 +11777,8 @@ packages: peerDependencies: postcss: ^8.4.31 - stylis@4.3.6: - resolution: {integrity: sha512-yQ3rwFWRfwNUY7H5vpU0wfdkNSnvnJinhF9830Swlaxl03zsOjCfmX0ugac+3LtK0lYSgwL/KXc8oYL3mG4YFQ==} + stylis@4.4.0: + resolution: {integrity: sha512-5Z9ZpRzfuH6l/UAvCPAPUo3665Nk2wLaZU3x+TLHKVzIz33+sbJqbtrYoC3KD4/uVOr2Zp+L0LySezP9OHV9yA==} sucrase@3.35.1: resolution: {integrity: sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==} @@ -11649,17 +11813,17 @@ packages: peerDependencies: svelte: '>= 3.43.1 < 6' - svelte-check@4.4.6: - resolution: {integrity: sha512-kP1zG81EWaFe9ZyTv4ZXv44Csi6Pkdpb7S3oj6m+K2ec/IcDg/a8LsFsnVLqm2nxtkSwsd5xPj/qFkTBgXHXjg==} + svelte-check@4.4.8: + resolution: {integrity: sha512-67adfgBox5eNSNIvIIwgFizKGdcRrGpiMoNO2obHcYuLz7iTa8Xgm/NGU3ntMFnNm8K1grFOIG6HhMLX/vcN8w==} engines: {node: '>= 18.0.0'} hasBin: true peerDependencies: svelte: ^4.0.0 || ^5.0.0-next.0 typescript: '>=5.0.0' - svelte-eslint-parser@1.6.0: - resolution: {integrity: sha512-qoB1ehychT6OxEtQAqc/guSqLS20SlA53Uijl7x375s8nlUT0lb9ol/gzraEEatQwsyPTJo87s2CmKL9Xab+Uw==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0, pnpm: 10.30.3} + svelte-eslint-parser@1.6.1: + resolution: {integrity: sha512-hhvSH6kRj46UzrBVO5TaotD+Iuvruj5ccKBcO4wAhVcPTLmIc/c32D8UllBTYO0on4LzYuM0rNzf1lM/gBlkSQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0, pnpm: 10.33.0} peerDependencies: svelte: ^3.37.0 || ^4.0.0 || ^5.0.0 peerDependenciesMeta: @@ -11732,18 +11896,13 @@ packages: svg-parser@2.0.4: resolution: {integrity: sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==} - svgo@3.3.2: - resolution: {integrity: sha512-OoohrmuUlBs8B8o6MB2Aevn+pRIH9zDALSR+6hhqVfa6fRwG/Qw9VUMSMW9VNg2CFc/MTIfabtdOVl9ODIJjpw==} + svgo@3.3.3: + resolution: {integrity: sha512-+wn7I4p7YgJhHs38k2TNjy1vCfPIfLIJWR5MnCStsN8WuuTcBnRKcMHQLMM2ijxGZmDoZwNv8ipl5aTTen62ng==} engines: {node: '>=14.0.0'} hasBin: true - swagger-ui-dist@5.32.4: - resolution: {integrity: sha512-0AADFFQNJzExEN49SrD/34Nn9cxNxVLiydYl2MBwSZFPVXNkVwC/EFAjoezGGqE8oDegiDC+p47t8lKObCinMQ==} - - swr@2.3.8: - resolution: {integrity: sha512-gaCPRVoMq8WGDcWj9p4YWzCMPHzE0WNl6W8ADIx9c3JBEIdMkJGMzW+uzXvxHMltwcYACr9jP+32H8/hgwMR7w==} - peerDependencies: - react: ^16.11.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + swagger-ui-dist@5.32.6: + resolution: {integrity: sha512-75ttZNaYCLoFPnozPZcTUU6mS3wKT8l7WLjU5zJSHFeJa23i5vtnze6IiCl4jDMPeQTXVXIgovq4M11NNfQvSA==} symbol-observable@4.0.0: resolution: {integrity: sha512-b19dMThMV4HVFynSAM1++gBHAbk2Tc/osgLIBZMKsyqh34jb2e8Os7T6ZW/Bt3pJFdBTd2JwAnAAEQV7rSNvcQ==} @@ -11756,8 +11915,8 @@ packages: resolution: {integrity: sha512-Bh7QjT8/SuKUIfObSXNHNSK6WHo6J1tHCqJsuaFDP7gP0fkzSfTxI8y85JrppZ0h8l0maIgc2tfuZQ6/t3GtnQ==} engines: {node: ^14.18.0 || >=16.0.0} - systeminformation@5.31.5: - resolution: {integrity: sha512-5SyLdip4/3alxD4Kh+63bUQTJmu7YMfYQTC+koZy7X73HgNqZSD2P4wOZQWtUncvPvcEmnfIjCoygN4MRoEejQ==} + systeminformation@5.31.6: + resolution: {integrity: sha512-Uv2b2uGGM6ns+26czgW2cYRabYdnswM0ddSOOlryHOaelzsmDSet1iM/NT7VOYxW8x/BW+HkY+b1Ve2pLTSGSA==} engines: {node: '>=8.0.0'} os: [darwin, linux, win32, freebsd, openbsd, netbsd, sunos, android] hasBin: true @@ -11782,8 +11941,8 @@ packages: '@eslint/css': optional: true - tailwind-merge@3.5.0: - resolution: {integrity: sha512-I8K9wewnVDkL1NTGoqWmVEIlUcB9gFriAEkXkfCjX5ib8ezGxtR3xD7iZIxrfArjEsH7F1CHD4RFUtxefdqV/A==} + tailwind-merge@3.6.0: + resolution: {integrity: sha512-uxL7qAVQriqRQPAyK3pj66VqskWqoZ37PW94jwOTwNfq/z9oyu1V+eqrZqtR2+fCiXdYOZe/Modt8GtvqNzu+w==} tailwind-variants@3.2.2: resolution: {integrity: sha512-Mi4kHeMTLvKlM98XPnK+7HoBPmf4gygdFmqQPaDivc3DpYS6aIY6KiG/PgThrGvii5YZJqRsPz0aPyhoFzmZgg==} @@ -11817,8 +11976,8 @@ packages: engines: {node: '>=14.0.0'} hasBin: true - tailwindcss@4.2.4: - resolution: {integrity: sha512-HhKppgO81FQof5m6TEnuBWCZGgfRAWbaeOaGT00KOy/Pf/j6oUihdvBpA7ltCeAvZpFhW3j0PTclkxsd4IXYDA==} + tailwindcss@4.3.0: + resolution: {integrity: sha512-y6nxMGB1nMW9R6k96e5gdIFzcfL/gTJRNaqGes1YvkLnPVXzWgbqFF2yLC0T8G774n24cx3Pe8XrKoniCOAH+Q==} tapable@2.3.3: resolution: {integrity: sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==} @@ -11834,40 +11993,66 @@ packages: resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} engines: {node: '>=6'} - tar-stream@3.1.8: - resolution: {integrity: sha512-U6QpVRyCGHva435KoNWy9PRoi2IFYCgtEhq9nmrPPpbRacPs9IH4aJ3gbrFC8dPcXvdSZ4XXfXT5Fshbp2MtlQ==} + tar-stream@3.2.0: + resolution: {integrity: sha512-ojzvCvVaNp6aOTFmG7jaRD0meowIAuPc3cMMhSgKiVWws1GyHbGd/xvnyuRKcKlMpt3qvxx6r0hreCNITP9hIg==} tar@6.2.1: resolution: {integrity: sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==} engines: {node: '>=10'} deprecated: Old versions of tar are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me - tar@7.5.7: - resolution: {integrity: sha512-fov56fJiRuThVFXD6o6/Q354S7pnWMJIVlDBYijsTNx6jKSE4pvrDTs6lUnmGvNyfJwFQQwWy3owKz1ucIhveQ==} + tar@7.5.15: + resolution: {integrity: sha512-dzGK0boVlC4W5QFuQN1EFSl3bIDYsk7Tj40U6eIBnK2k/8ml7TZ5agbI5j5+qnoVcAA+rNtBml8SEiLxZpNqRQ==} engines: {node: '>=18'} - deprecated: Old versions of tar are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me teex@1.0.1: resolution: {integrity: sha512-eYE6iEI62Ni1H8oIa7KlDU6uQBtqr4Eajni3wX7rpfXD8ysFx8z0+dri+KWEPWpBsxXfxu58x/0jvTVT1ekOSg==} - terser-webpack-plugin@5.4.0: - resolution: {integrity: sha512-Bn5vxm48flOIfkdl5CaD2+1CiUVbonWQ3KQPyP7/EuIl9Gbzq/gQFOzaMFUEgVjB1396tcK0SG8XcNJ/2kDH8g==} + terser-webpack-plugin@5.6.0: + resolution: {integrity: sha512-Eum+5ajkaOhf5KbM26osvv21kLD7BaGqQ1UA4Ami4arYwylmGUQTgHFpHDdmJod1q4QXa66p0to/FBKID+J1vA==} engines: {node: '>= 10.13.0'} peerDependencies: + '@minify-html/node': '*' '@swc/core': '*' + '@swc/css': '*' + '@swc/html': '*' + clean-css: '*' + cssnano: '*' + csso: '*' esbuild: '*' + html-minifier-terser: '*' + lightningcss: '*' + postcss: '*' uglify-js: '*' webpack: ^5.1.0 peerDependenciesMeta: + '@minify-html/node': + optional: true '@swc/core': optional: true + '@swc/css': + optional: true + '@swc/html': + optional: true + clean-css: + optional: true + cssnano: + optional: true + csso: + optional: true esbuild: optional: true + html-minifier-terser: + optional: true + lightningcss: + optional: true + postcss: + optional: true uglify-js: optional: true - terser@5.46.1: - resolution: {integrity: sha512-vzCjQO/rgUuK9sf8VJZvjqiqiHFaZLnOiimmUuOKODxWL8mm/xua7viT7aqX7dgPY60otQjUotzFMmCB4VdmqQ==} + terser@5.47.1: + resolution: {integrity: sha512-tPbLXTI6ohPASb/1YViL428oEHu6/qv1OxqYnfaonVCFHqx4+wCd95pHrQWsL5X4pl90CTyW9piSAsS2L0VoMw==} engines: {node: '>=10'} hasBin: true @@ -11892,8 +12077,8 @@ packages: thenify@3.3.1: resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} - thingies@2.5.0: - resolution: {integrity: sha512-s+2Bwztg6PhWUD7XMfeYm5qliDdSiZm7M7n8KjTkIsm3l/2lgVRc2/Gx/v+ZX8lT4FMA+i8aQvhcWylldc+ZNw==} + thingies@2.6.0: + resolution: {integrity: sha512-rMHRjmlFLM1R96UYPvpmnc3LYtdFrT33JIB7L9hetGue1qAPfn1N2LJeEjxUSidu1Iku+haLZXDuEXUHNGO/lg==} engines: {node: '>=10.18'} peerDependencies: tslib: ^2 @@ -11901,12 +12086,8 @@ packages: three@0.179.1: resolution: {integrity: sha512-5y/elSIQbrvKOISxpwXCR4sQqHtGiOI+MKLc3SsBdDXA2hz3Mdp3X59aUp8DyybMa34aeBwbFTpdoLJaUDEWSw==} - three@0.182.0: - resolution: {integrity: sha512-GbHabT+Irv+ihI1/f5kIIsZ+Ef9Sl5A1Y7imvS5RQjWgtTPfPnZ43JmlYI7NtCRDK9zir20lQpfg8/9Yd02OvQ==} - - throttleit@2.1.0: - resolution: {integrity: sha512-nt6AMGKW1p/70DF/hGBdJB57B8Tspmbp5gfJ8ilhLnt7kkr2ye7hzD6NVG8GGErk2HWF34igrL2CXmNIkzKqKw==} - engines: {node: '>=18'} + three@0.184.0: + resolution: {integrity: sha512-wtTRjG92pM5eUg/KuUnHsqSAlPM296brTOcLgMRqEeylYTh/CdtvKUvCyyCQTzFuStieWxvZb8mVTMvdPyUpxg==} through@2.3.8: resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} @@ -11939,8 +12120,8 @@ packages: tinyexec@0.3.2: resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} - tinyexec@1.1.1: - resolution: {integrity: sha512-VKS/ZaQhhkKFMANmAOhhXVoIfBXblQxGX1myCQ2faQrfmobMftXeJPcZGp0gS07ocvGJWDLZGyOZDadDBqYIJg==} + tinyexec@1.1.2: + resolution: {integrity: sha512-dAqSqE/RabpBKI8+h26GfLq6Vb3JVXs30XYQjdMjaj/c2tS8IYYMbIzP599KtRj7c57/wYApb3QjgRgXmrCukA==} engines: {node: '>=18'} tinyglobby@0.2.16: @@ -12044,8 +12225,8 @@ packages: ts-interface-checker@0.1.13: resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} - tsc-alias@1.8.16: - resolution: {integrity: sha512-QjCyu55NFyRSBAl6+MTFwplpFcnm2Pq01rR/uxfqJoLMm6X3O14KEGtaSDZpJYaE1bJBGDjD0eSuiIWPe2T58g==} + tsc-alias@1.8.17: + resolution: {integrity: sha512-EIduCZHqbNwPm8BZYfq1aD7BQ697A4h6uSGMOFQfYGoQwfrYFTKwYfy9Bv42YxHkduVBcn9Zx0DkX111DKskyg==} engines: {node: '>=16.20.2'} hasBin: true @@ -12067,6 +12248,9 @@ packages: resolution: {integrity: sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==} engines: {node: '>=6'} + tslib@1.14.1: + resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} + tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} @@ -12074,11 +12258,15 @@ packages: resolution: {integrity: sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA==} engines: {node: '>=0.6.x'} - tsx@4.21.0: - resolution: {integrity: sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==} + tsx@4.22.3: + resolution: {integrity: sha512-mdoNxBC/cSQObGGVQ5Bpn5i+yv7j68gk3Nfm3wFjcJg3Z0Mix9jzAFfP12prmm5eVGmDKtp0yyArrs0Q+8gZHg==} engines: {node: '>=18.0.0'} hasBin: true + tsyringe@4.10.0: + resolution: {integrity: sha512-axr3IdNuVIxnaK5XGEUFTu3YmAQ6lllgrvqfEoR16g/HGnYY/6We4oWENtAnzK6/LpJ2ur9PAb80RBt7/U4ugw==} + engines: {node: '>= 6.0.0'} + tunnel-agent@0.6.0: resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} @@ -12109,9 +12297,9 @@ packages: resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} engines: {node: '>= 0.6'} - type-is@2.0.1: - resolution: {integrity: sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==} - engines: {node: '>= 0.6'} + type-is@2.1.0: + resolution: {integrity: sha512-faYHw0anBbc/kWF3zFTEnxSFOAGUX9GFbOBthvDdLsIlEoWOFOtS0zgCiQYwIskL9iGXZL3kAXD8OoZ4GmMATA==} + engines: {node: '>= 18'} type@2.7.3: resolution: {integrity: sha512-8j+1QmAbPvLZow5Qpi6NCaN8FB60p/6x8/vfNqOk/hC+HuvFZhL4+WfekuhQLiqFZXOgQdrs3B+XxEmCc6b3FQ==} @@ -12122,8 +12310,8 @@ packages: typedarray@0.0.6: resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==} - typescript-eslint@8.59.0: - resolution: {integrity: sha512-BU3ONW9X+v90EcCH9ZS6LMackcVtxRLlI3XrYyqZIwVSHIk7Qf7bFw1z0M9Q0IUxhTMZCf8piY9hTYaNEIASrw==} + typescript-eslint@8.59.4: + resolution: {integrity: sha512-Rw6+44QNFaXtgHSjPy+Kw8hrJniMYzR85E9yLmOLcfZ91/rz+JXQbDTCmc6ccxMPY6K6PgAq26f0JCBfR7LIPQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 @@ -12146,9 +12334,6 @@ packages: resolution: {integrity: sha512-OsqGhxyo/wGdLSXMSJxuMGN6H4gDnKz6Fb3IBm4bxZFMnyy0sdf6MN96Ie8tC6z/btdO+Bsy8guxlvLdwT076w==} hasBin: true - ufo@1.6.2: - resolution: {integrity: sha512-heMioaxBcG9+Znsda5Q8sQbWnLJSl98AFDXTO80wELWEzX3hordXsTdxrIfMQoO9IY1MEnoGoPjpoKpMj+Yx0Q==} - uglify-js@3.19.3: resolution: {integrity: sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==} engines: {node: '>=0.8.0'} @@ -12172,8 +12357,9 @@ packages: undici-types@7.16.0: resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==} - undici-types@7.19.2: - resolution: {integrity: sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg==} + undici@6.25.0: + resolution: {integrity: sha512-ZgpWDC5gmNiuY9CnLVXEH8rl50xhRCuLNA97fAUnKi8RRuV4E6KG31pDTsLVUKnohJE0I3XDrTeEydAXRw47xg==} + engines: {node: '>=18.17'} undici@7.25.0: resolution: {integrity: sha512-xXnp4kTyor2Zq+J1FfPI6Eq3ew5h6Vl0F/8d9XU5zZQf1tX9s2Su1/3PiMmUANFULpmksxkClamIZcaUqryHsQ==} @@ -12205,14 +12391,6 @@ packages: unified@9.2.2: resolution: {integrity: sha512-Sg7j110mtefBD+qunSLO1lqOEKdrwBFBrR6Qd8f4uwkhWNlbkaqwHse6e7QvD3AP/MNoJdEDLaf8OxYyoWgorQ==} - unique-filename@5.0.0: - resolution: {integrity: sha512-2RaJTAvAb4owyjllTfXzFClJ7WsGxlykkPvCr9pA//LD9goVq+m4PPAeBgNodGZ7nSrntT/auWpJ6Y5IFXcfjg==} - engines: {node: ^20.17.0 || >=22.9.0} - - unique-slug@6.0.0: - resolution: {integrity: sha512-4Lup7Ezn8W3d52/xBhZBVdx323ckxa7DEvd9kPQHppTkLoJXw6ltrBCyj5pnrxj0qKDxYMJ56CoxNuFCscdTiw==} - engines: {node: ^20.17.0 || >=22.9.0} - unique-string@3.0.0: resolution: {integrity: sha512-VGXBUVwxKMBUznyffQweQABPRRW1vHZAbadFZud4pLFAqRGvv/96vafgjWFqzourzr8YonlQiPgH0YCJfawoGQ==} engines: {node: '>=12'} @@ -12247,8 +12425,8 @@ packages: unist-util-visit@2.0.3: resolution: {integrity: sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q==} - unist-util-visit@5.0.0: - resolution: {integrity: sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==} + unist-util-visit@5.1.0: + resolution: {integrity: sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==} universalify@2.0.1: resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} @@ -12300,11 +12478,6 @@ packages: urlpattern-polyfill@8.0.2: resolution: {integrity: sha512-Qp95D4TPJl1kC9SKigDcqgyM2VDVO4RiJc2d4qe5GrYm+zbIQCWWKAFaJNQ4BhdFeDGwBmAxqJBwWSJDb9T3BQ==} - use-sync-external-store@1.6.0: - resolution: {integrity: sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==} - peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - utf8-byte-length@1.0.5: resolution: {integrity: sha512-Xn0w3MtiQ6zoz2vFyUVruaCL53O/DwUvkEeOvj+uulMm0BkUGYWmBYVyElqZaSLhY6ZD0ulfU3aBra2aVT4xfA==} @@ -12331,10 +12504,6 @@ packages: deprecated: uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028). hasBin: true - uuid@11.1.0: - resolution: {integrity: sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==} - hasBin: true - uuid@14.0.0: resolution: {integrity: sha512-Qo+uWgilfSmAhXCMav1uYFynlQO7fMFiMVZsQqZRMIXp0O7rR7qjkj+cPvBHLgBqi960QCoo/PH2/6ZtVqKvrg==} hasBin: true @@ -12344,8 +12513,8 @@ packages: deprecated: uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028). hasBin: true - valibot@1.3.1: - resolution: {integrity: sha512-sfdRir/QFM0JaF22hqTroPc5xy4DimuGQVKFrzF1YfGwaS1nJot3Y8VqMdLO2Lg27fMzat2yD3pY5PbAYO39Gg==} + valibot@1.4.0: + resolution: {integrity: sha512-iC/x7fVcSyOwlm/VSt7RlHnzNGLGvR9GnxdifUeWoCJo0q4ZZvrVkIHC6faTlkxG47I2Y4UrFquPuVHCrOnrLg==} peerDependencies: typescript: '>=5' peerDependenciesMeta: @@ -12398,8 +12567,8 @@ packages: peerDependencies: vite: '*' - vite@7.3.2: - resolution: {integrity: sha512-Bby3NOsna2jsjfLVOHKes8sGwgl4TT0E6vvpYgnAYDIF/tie7MRaFthmKuHx1NSXjiTueXH3do80FMQgvEktRg==} + vite@7.3.3: + resolution: {integrity: sha512-/4XH147Ui7OGTjg3HbdWe5arnZQSbfuRzdr9Ec7TQi5I7R+ir0Rlc9GIvD4v0XZurELqA035KVXJXpR61xhiTA==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true peerDependencies: @@ -12438,13 +12607,13 @@ packages: yaml: optional: true - vite@8.0.10: - resolution: {integrity: sha512-rZuUu9j6J5uotLDs+cAA4O5H4K1SfPliUlQwqa6YEwSrWDZzP4rhm00oJR5snMewjxF5V/K3D4kctsUTsIU9Mw==} + vite@8.0.13: + resolution: {integrity: sha512-MFtjBYgzmSxmgA4RAfjIyXWpGe1oALnjgUTzzV7QLx/TKxCzjtMH6Fd9/eVK+5Fg1qNoz5VAwsmMs/NofrmJvw==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true peerDependencies: '@types/node': ^20.19.0 || >=22.12.0 - '@vitejs/devtools': ^0.1.0 + '@vitejs/devtools': ^0.1.18 esbuild: ^0.27.0 || ^0.28.0 jiti: '>=1.21.0' less: ^4.0.0 @@ -12481,10 +12650,10 @@ packages: yaml: optional: true - vitefu@1.1.2: - resolution: {integrity: sha512-zpKATdUbzbsycPFBN71nS2uzBUQiVnFoOrr2rvqv34S1lcAgMKKkjWleLGeiJlZ8lwCXvtWaRn7R3ZC16SYRuw==} + vitefu@1.1.3: + resolution: {integrity: sha512-ub4okH7Z5KLjb6hDyjqrGXqWtWvoYdU3IGm/NorpgHncKoLTCfRIbvlhBm7r0YstIaQRYlp4yEbFqDcKSzXSSg==} peerDependencies: - vite: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-beta.0 + vite: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 peerDependenciesMeta: vite: optional: true @@ -12523,20 +12692,20 @@ packages: jsdom: optional: true - vitest@4.1.5: - resolution: {integrity: sha512-9Xx1v3/ih3m9hN+SbfkUyy0JAs72ap3r7joc87XL6jwF0jGg6mFBvQ1SrwaX+h8BlkX6Hz9shdd1uo6AF+ZGpg==} + vitest@4.1.7: + resolution: {integrity: sha512-flYyaFd2CgoCoU+0UKt3pxksgC+S02iTDN0n3LtqaMeXsI9SBcdNujc2k0DeFLzUn/0k538yNjOSdwgCqcrwJA==} engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0} hasBin: true peerDependencies: '@edge-runtime/vm': '*' '@opentelemetry/api': ^1.9.0 '@types/node': ^20.0.0 || ^22.0.0 || >=24.0.0 - '@vitest/browser-playwright': 4.1.5 - '@vitest/browser-preview': 4.1.5 - '@vitest/browser-webdriverio': 4.1.5 - '@vitest/coverage-istanbul': 4.1.5 - '@vitest/coverage-v8': 4.1.5 - '@vitest/ui': 4.1.5 + '@vitest/browser-playwright': 4.1.7 + '@vitest/browser-preview': 4.1.7 + '@vitest/browser-webdriverio': 4.1.7 + '@vitest/coverage-istanbul': 4.1.7 + '@vitest/coverage-v8': 4.1.7 + '@vitest/ui': 4.1.7 happy-dom: '*' jsdom: '*' vite: ^6.0.0 || ^7.0.0 || ^8.0.0 @@ -12564,26 +12733,6 @@ packages: jsdom: optional: true - vscode-jsonrpc@8.2.0: - resolution: {integrity: sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA==} - engines: {node: '>=14.0.0'} - - vscode-languageserver-protocol@3.17.5: - resolution: {integrity: sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg==} - - vscode-languageserver-textdocument@1.0.12: - resolution: {integrity: sha512-cxWNPesCnQCcMPeenjKKsOCKQZ/L6Tv19DTRIGuLWe32lyzWhihGVJ/rcckZXJxfdKCFvRLS3fpBIsV/ZGX4zA==} - - vscode-languageserver-types@3.17.5: - resolution: {integrity: sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==} - - vscode-languageserver@9.0.1: - resolution: {integrity: sha512-woByF3PDpkHFUreUa7Hos7+pUWdeWMXRd26+ZX2A8cFx6v/JPTtd4/uN0/jB6XQHYaOlHbio03NTHCqrgG5n7g==} - hasBin: true - - vscode-uri@3.0.8: - resolution: {integrity: sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw==} - w3c-keyname@2.2.8: resolution: {integrity: sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==} @@ -12628,8 +12777,8 @@ packages: webpack: optional: true - webpack-dev-server@5.2.2: - resolution: {integrity: sha512-QcQ72gh8a+7JO63TAx/6XZf/CWhgMzu5m0QirvPfGvptOusAxG12w2+aua1Jkjr7hzaWDnJ2n6JFeexMHI+Zjg==} + webpack-dev-server@5.2.4: + resolution: {integrity: sha512-GqDPGZN9bRqKBTkp4aWkobDDHMsrXKoGSdOH56smIri8qR0JG8gfL8/v/f/OZR3/OKXjG8uwJbFVhKm/FNU/UA==} engines: {node: '>= 18.12.0'} hasBin: true peerDependencies: @@ -12653,8 +12802,8 @@ packages: resolution: {integrity: sha512-LnL6Z3GGDPht/AigwRh2dvL9PQPFQ8skEpVrWZXLWBYmqcaojHNN0onvHzie6rq7EWKrrBfPYqNEzTJgiwEQDQ==} engines: {node: '>=6'} - webpack-sources@3.3.4: - resolution: {integrity: sha512-7tP1PdV4vF+lYPnkMR0jMY5/la2ub5Fc/8VQrrU+lXkiM6C4TjVfGw7iKfyhnTQOsD+6Q/iKw0eFciziRgD58Q==} + webpack-sources@3.4.1: + resolution: {integrity: sha512-eACpxRN02yaawnt+uUNIF7Qje6A9zArxBbcAJjK1PK3S9Ycg5jIuJ8pW4q8EMnwNZCEGltcjkRx1QzOxOkKD8A==} engines: {node: '>=10.13.0'} webpack-virtual-modules@0.6.2: @@ -12670,8 +12819,8 @@ packages: webpack-cli: optional: true - webpack@5.106.2: - resolution: {integrity: sha512-wGN3qcrBQIFmQ/c0AiOAQBvrZ5lmY8vbbMv4Mxfgzqd/B6+9pXtLo73WuS1dSGXM5QYY3hZnIbvx+K1xxe6FyA==} + webpack@5.107.0: + resolution: {integrity: sha512-PSxeHk/dmLYZlnTU+vL1Gej6Evg5RNtl3flhxBresfznFnzxinHMzHKloHnywM/3ouQv7/AlZCswWDIkNSggUA==} engines: {node: '>=10.13.0'} hasBin: true peerDependencies: @@ -12796,20 +12945,8 @@ packages: utf-8-validate: optional: true - ws@8.18.3: - resolution: {integrity: sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==} - engines: {node: '>=10.0.0'} - peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: '>=5.0.2' - peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true - - ws@8.20.0: - resolution: {integrity: sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA==} + ws@8.20.1: + resolution: {integrity: sha512-It4dO0K5v//JtTXuPkfEOaI3uUN87iYPnqo/ZzqCoG3g8uhA66QUMs/SrM0YK7/NAu+r4LMh/9dq2A7k+rHs+w==} engines: {node: '>=10.0.0'} peerDependencies: bufferutil: ^4.0.1 @@ -12872,8 +13009,8 @@ packages: resolution: {integrity: sha512-vIYeF1u3CjlhAFekPPAk2h/Kv4T3mAkMox5OymRiJQB0spDP10LHvt+K7G9Ny6NuuMAb25/6n1qyUjAcGNf/AA==} engines: {node: '>= 6'} - yaml@2.8.3: - resolution: {integrity: sha512-AvbaCLOO2Otw/lW5bmh9d/WEdcDFdQp2Z2ZUH3pX9U2ihyUY0nvLv7J6TrWowklRGPYbB/IuIMfYgxaCPg5Bpg==} + yaml@2.9.0: + resolution: {integrity: sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==} engines: {node: '>= 14.6'} hasBin: true @@ -12940,141 +13077,135 @@ snapshots: '@adobe/css-tools@4.4.4': {} - '@ai-sdk/gateway@2.0.21(zod@4.3.6)': + '@algolia/abtesting@1.18.1': dependencies: - '@ai-sdk/provider': 2.0.0 - '@ai-sdk/provider-utils': 3.0.19(zod@4.3.6) - '@vercel/oidc': 3.0.5 - zod: 4.3.6 + '@algolia/client-common': 5.52.1 + '@algolia/requester-browser-xhr': 5.52.1 + '@algolia/requester-fetch': 5.52.1 + '@algolia/requester-node-http': 5.52.1 - '@ai-sdk/provider-utils@3.0.19(zod@4.3.6)': + '@algolia/autocomplete-core@1.19.2(@algolia/client-search@5.52.1)(algoliasearch@5.52.1)(search-insights@2.17.3)': dependencies: - '@ai-sdk/provider': 2.0.0 - '@standard-schema/spec': 1.1.0 - eventsource-parser: 3.0.6 - zod: 4.3.6 - - '@ai-sdk/provider@2.0.0': - dependencies: - json-schema: 0.4.0 - - '@ai-sdk/react@2.0.115(react@19.2.5)(zod@4.3.6)': - dependencies: - '@ai-sdk/provider-utils': 3.0.19(zod@4.3.6) - ai: 5.0.113(zod@4.3.6) - react: 19.2.5 - swr: 2.3.8(react@19.2.5) - throttleit: 2.1.0 - optionalDependencies: - zod: 4.3.6 - - '@algolia/abtesting@1.12.0': - dependencies: - '@algolia/client-common': 5.46.0 - '@algolia/requester-browser-xhr': 5.46.0 - '@algolia/requester-fetch': 5.46.0 - '@algolia/requester-node-http': 5.46.0 - - '@algolia/autocomplete-core@1.19.2(@algolia/client-search@5.46.0)(algoliasearch@5.46.0)(search-insights@2.17.3)': - dependencies: - '@algolia/autocomplete-plugin-algolia-insights': 1.19.2(@algolia/client-search@5.46.0)(algoliasearch@5.46.0)(search-insights@2.17.3) - '@algolia/autocomplete-shared': 1.19.2(@algolia/client-search@5.46.0)(algoliasearch@5.46.0) + '@algolia/autocomplete-plugin-algolia-insights': 1.19.2(@algolia/client-search@5.52.1)(algoliasearch@5.52.1)(search-insights@2.17.3) + '@algolia/autocomplete-shared': 1.19.2(@algolia/client-search@5.52.1)(algoliasearch@5.52.1) transitivePeerDependencies: - '@algolia/client-search' - algoliasearch - search-insights - '@algolia/autocomplete-plugin-algolia-insights@1.19.2(@algolia/client-search@5.46.0)(algoliasearch@5.46.0)(search-insights@2.17.3)': + '@algolia/autocomplete-core@1.19.8(@algolia/client-search@5.52.1)(algoliasearch@5.52.1)(search-insights@2.17.3)': dependencies: - '@algolia/autocomplete-shared': 1.19.2(@algolia/client-search@5.46.0)(algoliasearch@5.46.0) + '@algolia/autocomplete-plugin-algolia-insights': 1.19.8(@algolia/client-search@5.52.1)(algoliasearch@5.52.1)(search-insights@2.17.3) + '@algolia/autocomplete-shared': 1.19.8(@algolia/client-search@5.52.1)(algoliasearch@5.52.1) + transitivePeerDependencies: + - '@algolia/client-search' + - algoliasearch + - search-insights + + '@algolia/autocomplete-plugin-algolia-insights@1.19.2(@algolia/client-search@5.52.1)(algoliasearch@5.52.1)(search-insights@2.17.3)': + dependencies: + '@algolia/autocomplete-shared': 1.19.2(@algolia/client-search@5.52.1)(algoliasearch@5.52.1) search-insights: 2.17.3 transitivePeerDependencies: - '@algolia/client-search' - algoliasearch - '@algolia/autocomplete-shared@1.19.2(@algolia/client-search@5.46.0)(algoliasearch@5.46.0)': + '@algolia/autocomplete-plugin-algolia-insights@1.19.8(@algolia/client-search@5.52.1)(algoliasearch@5.52.1)(search-insights@2.17.3)': dependencies: - '@algolia/client-search': 5.46.0 - algoliasearch: 5.46.0 + '@algolia/autocomplete-shared': 1.19.8(@algolia/client-search@5.52.1)(algoliasearch@5.52.1) + search-insights: 2.17.3 + transitivePeerDependencies: + - '@algolia/client-search' + - algoliasearch - '@algolia/client-abtesting@5.46.0': + '@algolia/autocomplete-shared@1.19.2(@algolia/client-search@5.52.1)(algoliasearch@5.52.1)': dependencies: - '@algolia/client-common': 5.46.0 - '@algolia/requester-browser-xhr': 5.46.0 - '@algolia/requester-fetch': 5.46.0 - '@algolia/requester-node-http': 5.46.0 + '@algolia/client-search': 5.52.1 + algoliasearch: 5.52.1 - '@algolia/client-analytics@5.46.0': + '@algolia/autocomplete-shared@1.19.8(@algolia/client-search@5.52.1)(algoliasearch@5.52.1)': dependencies: - '@algolia/client-common': 5.46.0 - '@algolia/requester-browser-xhr': 5.46.0 - '@algolia/requester-fetch': 5.46.0 - '@algolia/requester-node-http': 5.46.0 + '@algolia/client-search': 5.52.1 + algoliasearch: 5.52.1 - '@algolia/client-common@5.46.0': {} - - '@algolia/client-insights@5.46.0': + '@algolia/client-abtesting@5.52.1': dependencies: - '@algolia/client-common': 5.46.0 - '@algolia/requester-browser-xhr': 5.46.0 - '@algolia/requester-fetch': 5.46.0 - '@algolia/requester-node-http': 5.46.0 + '@algolia/client-common': 5.52.1 + '@algolia/requester-browser-xhr': 5.52.1 + '@algolia/requester-fetch': 5.52.1 + '@algolia/requester-node-http': 5.52.1 - '@algolia/client-personalization@5.46.0': + '@algolia/client-analytics@5.52.1': dependencies: - '@algolia/client-common': 5.46.0 - '@algolia/requester-browser-xhr': 5.46.0 - '@algolia/requester-fetch': 5.46.0 - '@algolia/requester-node-http': 5.46.0 + '@algolia/client-common': 5.52.1 + '@algolia/requester-browser-xhr': 5.52.1 + '@algolia/requester-fetch': 5.52.1 + '@algolia/requester-node-http': 5.52.1 - '@algolia/client-query-suggestions@5.46.0': - dependencies: - '@algolia/client-common': 5.46.0 - '@algolia/requester-browser-xhr': 5.46.0 - '@algolia/requester-fetch': 5.46.0 - '@algolia/requester-node-http': 5.46.0 + '@algolia/client-common@5.52.1': {} - '@algolia/client-search@5.46.0': + '@algolia/client-insights@5.52.1': dependencies: - '@algolia/client-common': 5.46.0 - '@algolia/requester-browser-xhr': 5.46.0 - '@algolia/requester-fetch': 5.46.0 - '@algolia/requester-node-http': 5.46.0 + '@algolia/client-common': 5.52.1 + '@algolia/requester-browser-xhr': 5.52.1 + '@algolia/requester-fetch': 5.52.1 + '@algolia/requester-node-http': 5.52.1 + + '@algolia/client-personalization@5.52.1': + dependencies: + '@algolia/client-common': 5.52.1 + '@algolia/requester-browser-xhr': 5.52.1 + '@algolia/requester-fetch': 5.52.1 + '@algolia/requester-node-http': 5.52.1 + + '@algolia/client-query-suggestions@5.52.1': + dependencies: + '@algolia/client-common': 5.52.1 + '@algolia/requester-browser-xhr': 5.52.1 + '@algolia/requester-fetch': 5.52.1 + '@algolia/requester-node-http': 5.52.1 + + '@algolia/client-search@5.52.1': + dependencies: + '@algolia/client-common': 5.52.1 + '@algolia/requester-browser-xhr': 5.52.1 + '@algolia/requester-fetch': 5.52.1 + '@algolia/requester-node-http': 5.52.1 '@algolia/events@4.0.1': {} - '@algolia/ingestion@1.46.0': + '@algolia/ingestion@1.52.1': dependencies: - '@algolia/client-common': 5.46.0 - '@algolia/requester-browser-xhr': 5.46.0 - '@algolia/requester-fetch': 5.46.0 - '@algolia/requester-node-http': 5.46.0 + '@algolia/client-common': 5.52.1 + '@algolia/requester-browser-xhr': 5.52.1 + '@algolia/requester-fetch': 5.52.1 + '@algolia/requester-node-http': 5.52.1 - '@algolia/monitoring@1.46.0': + '@algolia/monitoring@1.52.1': dependencies: - '@algolia/client-common': 5.46.0 - '@algolia/requester-browser-xhr': 5.46.0 - '@algolia/requester-fetch': 5.46.0 - '@algolia/requester-node-http': 5.46.0 + '@algolia/client-common': 5.52.1 + '@algolia/requester-browser-xhr': 5.52.1 + '@algolia/requester-fetch': 5.52.1 + '@algolia/requester-node-http': 5.52.1 - '@algolia/recommend@5.46.0': + '@algolia/recommend@5.52.1': dependencies: - '@algolia/client-common': 5.46.0 - '@algolia/requester-browser-xhr': 5.46.0 - '@algolia/requester-fetch': 5.46.0 - '@algolia/requester-node-http': 5.46.0 + '@algolia/client-common': 5.52.1 + '@algolia/requester-browser-xhr': 5.52.1 + '@algolia/requester-fetch': 5.52.1 + '@algolia/requester-node-http': 5.52.1 - '@algolia/requester-browser-xhr@5.46.0': + '@algolia/requester-browser-xhr@5.52.1': dependencies: - '@algolia/client-common': 5.46.0 + '@algolia/client-common': 5.52.1 - '@algolia/requester-fetch@5.46.0': + '@algolia/requester-fetch@5.52.1': dependencies: - '@algolia/client-common': 5.46.0 + '@algolia/client-common': 5.52.1 - '@algolia/requester-node-http@5.46.0': + '@algolia/requester-node-http@5.52.1': dependencies: - '@algolia/client-common': 5.46.0 + '@algolia/client-common': 5.52.1 '@alloc/quick-lru@5.2.0': {} @@ -13094,11 +13225,11 @@ snapshots: optionalDependencies: chokidar: 4.0.3 - '@angular-devkit/schematics-cli@19.2.24(@types/node@24.12.2)(chokidar@4.0.3)': + '@angular-devkit/schematics-cli@19.2.24(@types/node@24.12.4)(chokidar@4.0.3)': dependencies: '@angular-devkit/core': 19.2.24(chokidar@4.0.3) '@angular-devkit/schematics': 19.2.24(chokidar@4.0.3) - '@inquirer/prompts': 7.3.2(@types/node@24.12.2) + '@inquirer/prompts': 7.3.2(@types/node@24.12.4) ansi-colors: 4.1.3 symbol-observable: 4.0.0 yargs-parser: 21.1.1 @@ -13119,7 +13250,7 @@ snapshots: '@antfu/install-pkg@1.1.0': dependencies: package-manager-detector: 1.6.0 - tinyexec: 1.1.1 + tinyexec: 1.1.2 '@asamuzakjp/css-color@3.2.0': dependencies: @@ -13136,16 +13267,16 @@ snapshots: js-tokens: 4.0.0 picocolors: 1.1.1 - '@babel/compat-data@7.28.5': {} + '@babel/compat-data@7.29.3': {} - '@babel/core@7.28.5': + '@babel/core@7.29.0': dependencies: '@babel/code-frame': 7.29.0 '@babel/generator': 7.29.1 - '@babel/helper-compilation-targets': 7.27.2 - '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.5) - '@babel/helpers': 7.28.4 - '@babel/parser': 7.29.2 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) + '@babel/helpers': 7.29.2 + '@babel/parser': 7.29.3 '@babel/template': 7.28.6 '@babel/traverse': 7.29.0 '@babel/types': 7.29.0 @@ -13160,7 +13291,7 @@ snapshots: '@babel/generator@7.29.1': dependencies: - '@babel/parser': 7.29.2 + '@babel/parser': 7.29.3 '@babel/types': 7.29.0 '@jridgewell/gen-mapping': 0.3.13 '@jridgewell/trace-mapping': 0.3.31 @@ -13170,42 +13301,42 @@ snapshots: dependencies: '@babel/types': 7.29.0 - '@babel/helper-compilation-targets@7.27.2': + '@babel/helper-compilation-targets@7.28.6': dependencies: - '@babel/compat-data': 7.28.5 + '@babel/compat-data': 7.29.3 '@babel/helper-validator-option': 7.27.1 browserslist: 4.28.2 lru-cache: 5.1.1 semver: 6.3.1 - '@babel/helper-create-class-features-plugin@7.28.5(@babel/core@7.28.5)': + '@babel/helper-create-class-features-plugin@7.29.3(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.29.0 '@babel/helper-annotate-as-pure': 7.27.3 '@babel/helper-member-expression-to-functions': 7.28.5 '@babel/helper-optimise-call-expression': 7.27.1 - '@babel/helper-replace-supers': 7.27.1(@babel/core@7.28.5) + '@babel/helper-replace-supers': 7.28.6(@babel/core@7.29.0) '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 '@babel/traverse': 7.29.0 semver: 6.3.1 transitivePeerDependencies: - supports-color - '@babel/helper-create-regexp-features-plugin@7.28.5(@babel/core@7.28.5)': + '@babel/helper-create-regexp-features-plugin@7.28.5(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.29.0 '@babel/helper-annotate-as-pure': 7.27.3 regexpu-core: 6.4.0 semver: 6.3.1 - '@babel/helper-define-polyfill-provider@0.6.5(@babel/core@7.28.5)': + '@babel/helper-define-polyfill-provider@0.6.8(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-compilation-targets': 7.27.2 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-plugin-utils': 7.28.6 debug: 4.4.3 lodash.debounce: 4.0.8 - resolve: 1.22.11 + resolve: 1.22.12 transitivePeerDependencies: - supports-color @@ -13218,17 +13349,17 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/helper-module-imports@7.27.1': + '@babel/helper-module-imports@7.28.6': dependencies: '@babel/traverse': 7.29.0 '@babel/types': 7.29.0 transitivePeerDependencies: - supports-color - '@babel/helper-module-transforms@7.28.3(@babel/core@7.28.5)': + '@babel/helper-module-transforms@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-module-imports': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-module-imports': 7.28.6 '@babel/helper-validator-identifier': 7.28.5 '@babel/traverse': 7.29.0 transitivePeerDependencies: @@ -13238,20 +13369,20 @@ snapshots: dependencies: '@babel/types': 7.29.0 - '@babel/helper-plugin-utils@7.27.1': {} + '@babel/helper-plugin-utils@7.28.6': {} - '@babel/helper-remap-async-to-generator@7.27.1(@babel/core@7.28.5)': + '@babel/helper-remap-async-to-generator@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.29.0 '@babel/helper-annotate-as-pure': 7.27.3 - '@babel/helper-wrap-function': 7.28.3 + '@babel/helper-wrap-function': 7.28.6 '@babel/traverse': 7.29.0 transitivePeerDependencies: - supports-color - '@babel/helper-replace-supers@7.27.1(@babel/core@7.28.5)': + '@babel/helper-replace-supers@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.29.0 '@babel/helper-member-expression-to-functions': 7.28.5 '@babel/helper-optimise-call-expression': 7.27.1 '@babel/traverse': 7.29.0 @@ -13271,7 +13402,7 @@ snapshots: '@babel/helper-validator-option@7.27.1': {} - '@babel/helper-wrap-function@7.28.3': + '@babel/helper-wrap-function@7.28.6': dependencies: '@babel/template': 7.28.6 '@babel/traverse': 7.29.0 @@ -13279,7 +13410,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/helpers@7.28.4': + '@babel/helpers@7.29.2': dependencies: '@babel/template': 7.28.6 '@babel/types': 7.29.0 @@ -13288,589 +13419,600 @@ snapshots: dependencies: '@babel/types': 7.29.0 - '@babel/parser@7.29.2': + '@babel/parser@7.29.3': dependencies: '@babel/types': 7.29.0 - '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.28.5(@babel/core@7.28.5)': + '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.28.5(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 '@babel/traverse': 7.29.0 transitivePeerDependencies: - supports-color - '@babel/plugin-bugfix-safari-class-field-initializer-scope@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-bugfix-safari-class-field-initializer-scope@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-bugfix-safari-rest-destructuring-rhs-array@7.29.3(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 - '@babel/plugin-transform-optional-chaining': 7.28.5(@babel/core@7.28.5) transitivePeerDependencies: - supports-color - '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.28.3(@babel/core@7.28.5)': + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + '@babel/plugin-transform-optional-chaining': 7.28.6(@babel/core@7.29.0) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 '@babel/traverse': 7.29.0 transitivePeerDependencies: - supports-color - '@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.28.5)': + '@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.29.0 - '@babel/plugin-syntax-dynamic-import@7.8.3(@babel/core@7.28.5)': + '@babel/plugin-syntax-dynamic-import@7.8.3(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-syntax-import-assertions@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-syntax-import-assertions@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-syntax-import-attributes@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-syntax-import-attributes@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-syntax-typescript@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-syntax-typescript@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.28.5)': + '@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.28.5) - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-arrow-functions@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-arrow-functions@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-async-generator-functions@7.28.0(@babel/core@7.28.5)': + '@babel/plugin-transform-async-generator-functions@7.29.0(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 - '@babel/helper-remap-async-to-generator': 7.27.1(@babel/core@7.28.5) + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-remap-async-to-generator': 7.27.1(@babel/core@7.29.0) '@babel/traverse': 7.29.0 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-async-to-generator@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-async-to-generator@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-module-imports': 7.27.1 - '@babel/helper-plugin-utils': 7.27.1 - '@babel/helper-remap-async-to-generator': 7.27.1(@babel/core@7.28.5) + '@babel/core': 7.29.0 + '@babel/helper-module-imports': 7.28.6 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-remap-async-to-generator': 7.27.1(@babel/core@7.29.0) transitivePeerDependencies: - supports-color - '@babel/plugin-transform-block-scoped-functions@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-block-scoped-functions@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-block-scoping@7.28.5(@babel/core@7.28.5)': + '@babel/plugin-transform-block-scoping@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-class-properties@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-class-properties@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-create-class-features-plugin': 7.28.5(@babel/core@7.28.5) - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-create-class-features-plugin': 7.29.3(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-class-static-block@7.28.3(@babel/core@7.28.5)': + '@babel/plugin-transform-class-static-block@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-create-class-features-plugin': 7.28.5(@babel/core@7.28.5) - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-create-class-features-plugin': 7.29.3(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-classes@7.28.4(@babel/core@7.28.5)': + '@babel/plugin-transform-classes@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.29.0 '@babel/helper-annotate-as-pure': 7.27.3 - '@babel/helper-compilation-targets': 7.27.2 + '@babel/helper-compilation-targets': 7.28.6 '@babel/helper-globals': 7.28.0 - '@babel/helper-plugin-utils': 7.27.1 - '@babel/helper-replace-supers': 7.27.1(@babel/core@7.28.5) + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-replace-supers': 7.28.6(@babel/core@7.29.0) '@babel/traverse': 7.29.0 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-computed-properties@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-computed-properties@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 '@babel/template': 7.28.6 - '@babel/plugin-transform-destructuring@7.28.5(@babel/core@7.28.5)': + '@babel/plugin-transform-destructuring@7.28.5(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 '@babel/traverse': 7.29.0 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-dotall-regex@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-dotall-regex@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.28.5) - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-duplicate-keys@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-duplicate-keys@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.29.0(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.28.5) - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-dynamic-import@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-dynamic-import@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-explicit-resource-management@7.28.0(@babel/core@7.28.5)': + '@babel/plugin-transform-explicit-resource-management@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-destructuring': 7.28.5(@babel/core@7.28.5) + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/plugin-transform-destructuring': 7.28.5(@babel/core@7.29.0) transitivePeerDependencies: - supports-color - '@babel/plugin-transform-exponentiation-operator@7.28.5(@babel/core@7.28.5)': + '@babel/plugin-transform-exponentiation-operator@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-export-namespace-from@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-export-namespace-from@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-for-of@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-for-of@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-function-name@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-function-name@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-compilation-targets': 7.27.2 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-plugin-utils': 7.28.6 '@babel/traverse': 7.29.0 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-json-strings@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-json-strings@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-literals@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-literals@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-logical-assignment-operators@7.28.5(@babel/core@7.28.5)': + '@babel/plugin-transform-logical-assignment-operators@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-member-expression-literals@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-member-expression-literals@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-modules-amd@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-modules-amd@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.5) - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-modules-commonjs@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-modules-commonjs@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.5) - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-modules-systemjs@7.28.5(@babel/core@7.28.5)': + '@babel/plugin-transform-modules-systemjs@7.29.4(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.5) - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 '@babel/helper-validator-identifier': 7.28.5 '@babel/traverse': 7.29.0 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-modules-umd@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-modules-umd@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.5) - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-named-capturing-groups-regex@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-named-capturing-groups-regex@7.29.0(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.28.5) - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-new-target@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-new-target@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-nullish-coalescing-operator@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-nullish-coalescing-operator@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-numeric-separator@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-numeric-separator@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-object-rest-spread@7.28.4(@babel/core@7.28.5)': + '@babel/plugin-transform-object-rest-spread@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-compilation-targets': 7.27.2 - '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-destructuring': 7.28.5(@babel/core@7.28.5) - '@babel/plugin-transform-parameters': 7.27.7(@babel/core@7.28.5) + '@babel/core': 7.29.0 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/plugin-transform-destructuring': 7.28.5(@babel/core@7.29.0) + '@babel/plugin-transform-parameters': 7.27.7(@babel/core@7.29.0) '@babel/traverse': 7.29.0 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-object-super@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-object-super@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 - '@babel/helper-replace-supers': 7.27.1(@babel/core@7.28.5) + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-replace-supers': 7.28.6(@babel/core@7.29.0) transitivePeerDependencies: - supports-color - '@babel/plugin-transform-optional-catch-binding@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-optional-catch-binding@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-optional-chaining@7.28.5(@babel/core@7.28.5)': + '@babel/plugin-transform-optional-chaining@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-parameters@7.27.7(@babel/core@7.28.5)': + '@babel/plugin-transform-parameters@7.27.7(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-private-methods@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-private-methods@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-create-class-features-plugin': 7.28.5(@babel/core@7.28.5) - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-create-class-features-plugin': 7.29.3(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-private-property-in-object@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-private-property-in-object@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.29.0 '@babel/helper-annotate-as-pure': 7.27.3 - '@babel/helper-create-class-features-plugin': 7.28.5(@babel/core@7.28.5) - '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-create-class-features-plugin': 7.29.3(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-property-literals@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-property-literals@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-react-constant-elements@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-react-constant-elements@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-react-display-name@7.28.0(@babel/core@7.28.5)': + '@babel/plugin-transform-react-display-name@7.28.0(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-react-jsx-development@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-react-jsx-development@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/plugin-transform-react-jsx': 7.27.1(@babel/core@7.28.5) + '@babel/core': 7.29.0 + '@babel/plugin-transform-react-jsx': 7.28.6(@babel/core@7.29.0) transitivePeerDependencies: - supports-color - '@babel/plugin-transform-react-jsx@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-react-jsx@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.29.0 '@babel/helper-annotate-as-pure': 7.27.3 - '@babel/helper-module-imports': 7.27.1 - '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.28.5) + '@babel/helper-module-imports': 7.28.6 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/plugin-syntax-jsx': 7.28.6(@babel/core@7.29.0) '@babel/types': 7.29.0 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-react-pure-annotations@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-react-pure-annotations@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.29.0 '@babel/helper-annotate-as-pure': 7.27.3 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-regenerator@7.28.4(@babel/core@7.28.5)': + '@babel/plugin-transform-regenerator@7.29.0(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-regexp-modifiers@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-regexp-modifiers@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.28.5) - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-reserved-words@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-reserved-words@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-runtime@7.28.5(@babel/core@7.28.5)': + '@babel/plugin-transform-runtime@7.29.0(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-module-imports': 7.27.1 - '@babel/helper-plugin-utils': 7.27.1 - babel-plugin-polyfill-corejs2: 0.4.14(@babel/core@7.28.5) - babel-plugin-polyfill-corejs3: 0.13.0(@babel/core@7.28.5) - babel-plugin-polyfill-regenerator: 0.6.5(@babel/core@7.28.5) + '@babel/core': 7.29.0 + '@babel/helper-module-imports': 7.28.6 + '@babel/helper-plugin-utils': 7.28.6 + babel-plugin-polyfill-corejs2: 0.4.17(@babel/core@7.29.0) + babel-plugin-polyfill-corejs3: 0.13.0(@babel/core@7.29.0) + babel-plugin-polyfill-regenerator: 0.6.8(@babel/core@7.29.0) semver: 6.3.1 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-shorthand-properties@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-shorthand-properties@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-spread@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-spread@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-sticky-regex@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-sticky-regex@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-template-literals@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-template-literals@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-typeof-symbol@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-typeof-symbol@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-typescript@7.28.5(@babel/core@7.28.5)': + '@babel/plugin-transform-typescript@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.29.0 '@babel/helper-annotate-as-pure': 7.27.3 - '@babel/helper-create-class-features-plugin': 7.28.5(@babel/core@7.28.5) - '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-create-class-features-plugin': 7.29.3(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 - '@babel/plugin-syntax-typescript': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-syntax-typescript': 7.28.6(@babel/core@7.29.0) transitivePeerDependencies: - supports-color - '@babel/plugin-transform-unicode-escapes@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-unicode-escapes@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-unicode-property-regex@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-unicode-property-regex@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.28.5) - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-unicode-regex@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-unicode-regex@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.28.5) - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-unicode-sets-regex@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-unicode-sets-regex@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.28.5) - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 - '@babel/preset-env@7.28.5(@babel/core@7.28.5)': + '@babel/preset-env@7.29.5(@babel/core@7.29.0)': dependencies: - '@babel/compat-data': 7.28.5 - '@babel/core': 7.28.5 - '@babel/helper-compilation-targets': 7.27.2 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/compat-data': 7.29.3 + '@babel/core': 7.29.0 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-plugin-utils': 7.28.6 '@babel/helper-validator-option': 7.27.1 - '@babel/plugin-bugfix-firefox-class-in-computed-class-key': 7.28.5(@babel/core@7.28.5) - '@babel/plugin-bugfix-safari-class-field-initializer-scope': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly': 7.28.3(@babel/core@7.28.5) - '@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.28.5) - '@babel/plugin-syntax-import-assertions': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-syntax-import-attributes': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.28.5) - '@babel/plugin-transform-arrow-functions': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-async-generator-functions': 7.28.0(@babel/core@7.28.5) - '@babel/plugin-transform-async-to-generator': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-block-scoped-functions': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-block-scoping': 7.28.5(@babel/core@7.28.5) - '@babel/plugin-transform-class-properties': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-class-static-block': 7.28.3(@babel/core@7.28.5) - '@babel/plugin-transform-classes': 7.28.4(@babel/core@7.28.5) - '@babel/plugin-transform-computed-properties': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-destructuring': 7.28.5(@babel/core@7.28.5) - '@babel/plugin-transform-dotall-regex': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-duplicate-keys': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-duplicate-named-capturing-groups-regex': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-dynamic-import': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-explicit-resource-management': 7.28.0(@babel/core@7.28.5) - '@babel/plugin-transform-exponentiation-operator': 7.28.5(@babel/core@7.28.5) - '@babel/plugin-transform-export-namespace-from': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-for-of': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-function-name': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-json-strings': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-literals': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-logical-assignment-operators': 7.28.5(@babel/core@7.28.5) - '@babel/plugin-transform-member-expression-literals': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-modules-amd': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-modules-commonjs': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-modules-systemjs': 7.28.5(@babel/core@7.28.5) - '@babel/plugin-transform-modules-umd': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-named-capturing-groups-regex': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-new-target': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-nullish-coalescing-operator': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-numeric-separator': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-object-rest-spread': 7.28.4(@babel/core@7.28.5) - '@babel/plugin-transform-object-super': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-optional-catch-binding': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-optional-chaining': 7.28.5(@babel/core@7.28.5) - '@babel/plugin-transform-parameters': 7.27.7(@babel/core@7.28.5) - '@babel/plugin-transform-private-methods': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-private-property-in-object': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-property-literals': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-regenerator': 7.28.4(@babel/core@7.28.5) - '@babel/plugin-transform-regexp-modifiers': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-reserved-words': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-shorthand-properties': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-spread': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-sticky-regex': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-template-literals': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-typeof-symbol': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-unicode-escapes': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-unicode-property-regex': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-unicode-regex': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-unicode-sets-regex': 7.27.1(@babel/core@7.28.5) - '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.28.5) - babel-plugin-polyfill-corejs2: 0.4.14(@babel/core@7.28.5) - babel-plugin-polyfill-corejs3: 0.13.0(@babel/core@7.28.5) - babel-plugin-polyfill-regenerator: 0.6.5(@babel/core@7.28.5) + '@babel/plugin-bugfix-firefox-class-in-computed-class-key': 7.28.5(@babel/core@7.29.0) + '@babel/plugin-bugfix-safari-class-field-initializer-scope': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-bugfix-safari-rest-destructuring-rhs-array': 7.29.3(@babel/core@7.29.0) + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.29.0) + '@babel/plugin-syntax-import-assertions': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-syntax-import-attributes': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.29.0) + '@babel/plugin-transform-arrow-functions': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-async-generator-functions': 7.29.0(@babel/core@7.29.0) + '@babel/plugin-transform-async-to-generator': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-block-scoped-functions': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-block-scoping': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-class-properties': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-class-static-block': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-classes': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-computed-properties': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-destructuring': 7.28.5(@babel/core@7.29.0) + '@babel/plugin-transform-dotall-regex': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-duplicate-keys': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-duplicate-named-capturing-groups-regex': 7.29.0(@babel/core@7.29.0) + '@babel/plugin-transform-dynamic-import': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-explicit-resource-management': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-exponentiation-operator': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-export-namespace-from': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-for-of': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-function-name': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-json-strings': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-literals': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-logical-assignment-operators': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-member-expression-literals': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-modules-amd': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-modules-commonjs': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-modules-systemjs': 7.29.4(@babel/core@7.29.0) + '@babel/plugin-transform-modules-umd': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-named-capturing-groups-regex': 7.29.0(@babel/core@7.29.0) + '@babel/plugin-transform-new-target': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-nullish-coalescing-operator': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-numeric-separator': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-object-rest-spread': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-object-super': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-optional-catch-binding': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-optional-chaining': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-parameters': 7.27.7(@babel/core@7.29.0) + '@babel/plugin-transform-private-methods': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-private-property-in-object': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-property-literals': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-regenerator': 7.29.0(@babel/core@7.29.0) + '@babel/plugin-transform-regexp-modifiers': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-reserved-words': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-shorthand-properties': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-spread': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-sticky-regex': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-template-literals': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-typeof-symbol': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-unicode-escapes': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-unicode-property-regex': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-unicode-regex': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-unicode-sets-regex': 7.28.6(@babel/core@7.29.0) + '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.29.0) + babel-plugin-polyfill-corejs2: 0.4.17(@babel/core@7.29.0) + babel-plugin-polyfill-corejs3: 0.14.2(@babel/core@7.29.0) + babel-plugin-polyfill-regenerator: 0.6.8(@babel/core@7.29.0) core-js-compat: 3.49.0 semver: 6.3.1 transitivePeerDependencies: - supports-color - '@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.28.5)': + '@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 '@babel/types': 7.29.0 esutils: 2.0.3 - '@babel/preset-react@7.28.5(@babel/core@7.28.5)': + '@babel/preset-react@7.28.5(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 '@babel/helper-validator-option': 7.27.1 - '@babel/plugin-transform-react-display-name': 7.28.0(@babel/core@7.28.5) - '@babel/plugin-transform-react-jsx': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-react-jsx-development': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-react-pure-annotations': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-react-display-name': 7.28.0(@babel/core@7.29.0) + '@babel/plugin-transform-react-jsx': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-react-jsx-development': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-react-pure-annotations': 7.27.1(@babel/core@7.29.0) transitivePeerDependencies: - supports-color - '@babel/preset-typescript@7.28.5(@babel/core@7.28.5)': + '@babel/preset-typescript@7.28.5(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 '@babel/helper-validator-option': 7.27.1 - '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-modules-commonjs': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-typescript': 7.28.5(@babel/core@7.28.5) + '@babel/plugin-syntax-jsx': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-modules-commonjs': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-typescript': 7.28.6(@babel/core@7.29.0) transitivePeerDependencies: - supports-color '@babel/runtime@7.29.2': {} + '@babel/runtime@7.29.7': {} + '@babel/template@7.28.6': dependencies: '@babel/code-frame': 7.29.0 - '@babel/parser': 7.29.2 + '@babel/parser': 7.29.3 '@babel/types': 7.29.0 '@babel/traverse@7.27.0': dependencies: '@babel/code-frame': 7.29.0 '@babel/generator': 7.29.1 - '@babel/parser': 7.29.2 + '@babel/parser': 7.29.3 '@babel/template': 7.28.6 '@babel/types': 7.29.0 debug: 4.4.3 @@ -13883,7 +14025,7 @@ snapshots: '@babel/code-frame': 7.29.0 '@babel/generator': 7.29.1 '@babel/helper-globals': 7.28.0 - '@babel/parser': 7.29.2 + '@babel/parser': 7.29.3 '@babel/template': 7.28.6 '@babel/types': 7.29.0 debug: 4.4.3 @@ -13901,37 +14043,22 @@ snapshots: '@borewit/text-codec@0.2.2': {} - '@braintree/sanitize-url@7.1.1': {} + '@braintree/sanitize-url@7.1.2': {} - '@chevrotain/cst-dts-gen@11.0.3': - dependencies: - '@chevrotain/gast': 11.0.3 - '@chevrotain/types': 11.0.3 - lodash-es: 4.17.21 + '@chevrotain/types@11.1.2': {} - '@chevrotain/gast@11.0.3': - dependencies: - '@chevrotain/types': 11.0.3 - lodash-es: 4.17.21 - - '@chevrotain/regexp-to-ast@11.0.3': {} - - '@chevrotain/types@11.0.3': {} - - '@chevrotain/utils@11.0.3': {} - - '@codemirror/autocomplete@6.20.1': + '@codemirror/autocomplete@6.20.2': dependencies: '@codemirror/language': 6.12.3 '@codemirror/state': 6.6.0 - '@codemirror/view': 6.41.1 + '@codemirror/view': 6.43.0 '@lezer/common': 1.5.2 '@codemirror/commands@6.10.3': dependencies: '@codemirror/language': 6.12.3 '@codemirror/state': 6.6.0 - '@codemirror/view': 6.41.1 + '@codemirror/view': 6.43.0 '@lezer/common': 1.5.2 '@codemirror/lang-json@6.0.2': @@ -13942,29 +14069,29 @@ snapshots: '@codemirror/language@6.12.3': dependencies: '@codemirror/state': 6.6.0 - '@codemirror/view': 6.41.1 + '@codemirror/view': 6.43.0 '@lezer/common': 1.5.2 '@lezer/highlight': 1.2.3 '@lezer/lr': 1.4.10 style-mod: 4.1.3 - '@codemirror/lint@6.9.5': + '@codemirror/lint@6.9.6': dependencies: '@codemirror/state': 6.6.0 - '@codemirror/view': 6.41.1 + '@codemirror/view': 6.43.0 crelt: 1.0.6 '@codemirror/search@6.7.0': dependencies: '@codemirror/state': 6.6.0 - '@codemirror/view': 6.41.1 + '@codemirror/view': 6.43.0 crelt: 1.0.6 '@codemirror/state@6.6.0': dependencies: '@marijn/find-cluster-break': 1.0.2 - '@codemirror/view@6.41.1': + '@codemirror/view@6.43.0': dependencies: '@codemirror/state': 6.6.0 crelt: 1.0.6 @@ -14004,261 +14131,272 @@ snapshots: '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) '@csstools/css-tokenizer': 3.0.4 - '@csstools/postcss-alpha-function@1.0.1(postcss@8.5.12)': + '@csstools/postcss-alpha-function@1.0.1(postcss@8.5.15)': dependencies: '@csstools/css-color-parser': 3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) '@csstools/css-tokenizer': 3.0.4 - '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.12) - '@csstools/utilities': 2.0.0(postcss@8.5.12) - postcss: 8.5.12 + '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.15) + '@csstools/utilities': 2.0.0(postcss@8.5.15) + postcss: 8.5.15 - '@csstools/postcss-cascade-layers@5.0.2(postcss@8.5.12)': + '@csstools/postcss-cascade-layers@5.0.2(postcss@8.5.15)': dependencies: '@csstools/selector-specificity': 5.0.0(postcss-selector-parser@7.1.1) - postcss: 8.5.12 + postcss: 8.5.15 postcss-selector-parser: 7.1.1 - '@csstools/postcss-color-function-display-p3-linear@1.0.1(postcss@8.5.12)': + '@csstools/postcss-color-function-display-p3-linear@1.0.1(postcss@8.5.15)': dependencies: '@csstools/css-color-parser': 3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) '@csstools/css-tokenizer': 3.0.4 - '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.12) - '@csstools/utilities': 2.0.0(postcss@8.5.12) - postcss: 8.5.12 + '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.15) + '@csstools/utilities': 2.0.0(postcss@8.5.15) + postcss: 8.5.15 - '@csstools/postcss-color-function@4.0.12(postcss@8.5.12)': + '@csstools/postcss-color-function@4.0.12(postcss@8.5.15)': dependencies: '@csstools/css-color-parser': 3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) '@csstools/css-tokenizer': 3.0.4 - '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.12) - '@csstools/utilities': 2.0.0(postcss@8.5.12) - postcss: 8.5.12 + '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.15) + '@csstools/utilities': 2.0.0(postcss@8.5.15) + postcss: 8.5.15 - '@csstools/postcss-color-mix-function@3.0.12(postcss@8.5.12)': + '@csstools/postcss-color-mix-function@3.0.12(postcss@8.5.15)': dependencies: '@csstools/css-color-parser': 3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) '@csstools/css-tokenizer': 3.0.4 - '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.12) - '@csstools/utilities': 2.0.0(postcss@8.5.12) - postcss: 8.5.12 + '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.15) + '@csstools/utilities': 2.0.0(postcss@8.5.15) + postcss: 8.5.15 - '@csstools/postcss-color-mix-variadic-function-arguments@1.0.2(postcss@8.5.12)': + '@csstools/postcss-color-mix-variadic-function-arguments@1.0.2(postcss@8.5.15)': dependencies: '@csstools/css-color-parser': 3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) '@csstools/css-tokenizer': 3.0.4 - '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.12) - '@csstools/utilities': 2.0.0(postcss@8.5.12) - postcss: 8.5.12 + '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.15) + '@csstools/utilities': 2.0.0(postcss@8.5.15) + postcss: 8.5.15 - '@csstools/postcss-content-alt-text@2.0.8(postcss@8.5.12)': + '@csstools/postcss-content-alt-text@2.0.8(postcss@8.5.15)': dependencies: '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) '@csstools/css-tokenizer': 3.0.4 - '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.12) - '@csstools/utilities': 2.0.0(postcss@8.5.12) - postcss: 8.5.12 + '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.15) + '@csstools/utilities': 2.0.0(postcss@8.5.15) + postcss: 8.5.15 - '@csstools/postcss-contrast-color-function@2.0.12(postcss@8.5.12)': + '@csstools/postcss-contrast-color-function@2.0.12(postcss@8.5.15)': dependencies: '@csstools/css-color-parser': 3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) '@csstools/css-tokenizer': 3.0.4 - '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.12) - '@csstools/utilities': 2.0.0(postcss@8.5.12) - postcss: 8.5.12 + '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.15) + '@csstools/utilities': 2.0.0(postcss@8.5.15) + postcss: 8.5.15 - '@csstools/postcss-exponential-functions@2.0.9(postcss@8.5.12)': + '@csstools/postcss-exponential-functions@2.0.9(postcss@8.5.15)': dependencies: '@csstools/css-calc': 2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) '@csstools/css-tokenizer': 3.0.4 - postcss: 8.5.12 + postcss: 8.5.15 - '@csstools/postcss-font-format-keywords@4.0.0(postcss@8.5.12)': + '@csstools/postcss-font-format-keywords@4.0.0(postcss@8.5.15)': dependencies: - '@csstools/utilities': 2.0.0(postcss@8.5.12) - postcss: 8.5.12 + '@csstools/utilities': 2.0.0(postcss@8.5.15) + postcss: 8.5.15 postcss-value-parser: 4.2.0 - '@csstools/postcss-gamut-mapping@2.0.11(postcss@8.5.12)': + '@csstools/postcss-gamut-mapping@2.0.11(postcss@8.5.15)': dependencies: '@csstools/css-color-parser': 3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) '@csstools/css-tokenizer': 3.0.4 - postcss: 8.5.12 + postcss: 8.5.15 - '@csstools/postcss-gradients-interpolation-method@5.0.12(postcss@8.5.12)': + '@csstools/postcss-gradients-interpolation-method@5.0.12(postcss@8.5.15)': dependencies: '@csstools/css-color-parser': 3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) '@csstools/css-tokenizer': 3.0.4 - '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.12) - '@csstools/utilities': 2.0.0(postcss@8.5.12) - postcss: 8.5.12 + '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.15) + '@csstools/utilities': 2.0.0(postcss@8.5.15) + postcss: 8.5.15 - '@csstools/postcss-hwb-function@4.0.12(postcss@8.5.12)': + '@csstools/postcss-hwb-function@4.0.12(postcss@8.5.15)': dependencies: '@csstools/css-color-parser': 3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) '@csstools/css-tokenizer': 3.0.4 - '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.12) - '@csstools/utilities': 2.0.0(postcss@8.5.12) - postcss: 8.5.12 + '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.15) + '@csstools/utilities': 2.0.0(postcss@8.5.15) + postcss: 8.5.15 - '@csstools/postcss-ic-unit@4.0.4(postcss@8.5.12)': + '@csstools/postcss-ic-unit@4.0.4(postcss@8.5.15)': dependencies: - '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.12) - '@csstools/utilities': 2.0.0(postcss@8.5.12) - postcss: 8.5.12 + '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.15) + '@csstools/utilities': 2.0.0(postcss@8.5.15) + postcss: 8.5.15 postcss-value-parser: 4.2.0 - '@csstools/postcss-initial@2.0.1(postcss@8.5.12)': + '@csstools/postcss-initial@2.0.1(postcss@8.5.15)': dependencies: - postcss: 8.5.12 + postcss: 8.5.15 - '@csstools/postcss-is-pseudo-class@5.0.3(postcss@8.5.12)': + '@csstools/postcss-is-pseudo-class@5.0.3(postcss@8.5.15)': dependencies: '@csstools/selector-specificity': 5.0.0(postcss-selector-parser@7.1.1) - postcss: 8.5.12 + postcss: 8.5.15 postcss-selector-parser: 7.1.1 - '@csstools/postcss-light-dark-function@2.0.11(postcss@8.5.12)': + '@csstools/postcss-light-dark-function@2.0.11(postcss@8.5.15)': dependencies: '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) '@csstools/css-tokenizer': 3.0.4 - '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.12) - '@csstools/utilities': 2.0.0(postcss@8.5.12) - postcss: 8.5.12 + '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.15) + '@csstools/utilities': 2.0.0(postcss@8.5.15) + postcss: 8.5.15 - '@csstools/postcss-logical-float-and-clear@3.0.0(postcss@8.5.12)': + '@csstools/postcss-logical-float-and-clear@3.0.0(postcss@8.5.15)': dependencies: - postcss: 8.5.12 + postcss: 8.5.15 - '@csstools/postcss-logical-overflow@2.0.0(postcss@8.5.12)': + '@csstools/postcss-logical-overflow@2.0.0(postcss@8.5.15)': dependencies: - postcss: 8.5.12 + postcss: 8.5.15 - '@csstools/postcss-logical-overscroll-behavior@2.0.0(postcss@8.5.12)': + '@csstools/postcss-logical-overscroll-behavior@2.0.0(postcss@8.5.15)': dependencies: - postcss: 8.5.12 + postcss: 8.5.15 - '@csstools/postcss-logical-resize@3.0.0(postcss@8.5.12)': + '@csstools/postcss-logical-resize@3.0.0(postcss@8.5.15)': dependencies: - postcss: 8.5.12 + postcss: 8.5.15 postcss-value-parser: 4.2.0 - '@csstools/postcss-logical-viewport-units@3.0.4(postcss@8.5.12)': + '@csstools/postcss-logical-viewport-units@3.0.4(postcss@8.5.15)': dependencies: '@csstools/css-tokenizer': 3.0.4 - '@csstools/utilities': 2.0.0(postcss@8.5.12) - postcss: 8.5.12 + '@csstools/utilities': 2.0.0(postcss@8.5.15) + postcss: 8.5.15 - '@csstools/postcss-media-minmax@2.0.9(postcss@8.5.12)': + '@csstools/postcss-media-minmax@2.0.9(postcss@8.5.15)': dependencies: '@csstools/css-calc': 2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) '@csstools/css-tokenizer': 3.0.4 '@csstools/media-query-list-parser': 4.0.3(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) - postcss: 8.5.12 + postcss: 8.5.15 - '@csstools/postcss-media-queries-aspect-ratio-number-values@3.0.5(postcss@8.5.12)': + '@csstools/postcss-media-queries-aspect-ratio-number-values@3.0.5(postcss@8.5.15)': dependencies: '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) '@csstools/css-tokenizer': 3.0.4 '@csstools/media-query-list-parser': 4.0.3(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) - postcss: 8.5.12 + postcss: 8.5.15 - '@csstools/postcss-nested-calc@4.0.0(postcss@8.5.12)': + '@csstools/postcss-nested-calc@4.0.0(postcss@8.5.15)': dependencies: - '@csstools/utilities': 2.0.0(postcss@8.5.12) - postcss: 8.5.12 + '@csstools/utilities': 2.0.0(postcss@8.5.15) + postcss: 8.5.15 postcss-value-parser: 4.2.0 - '@csstools/postcss-normalize-display-values@4.0.0(postcss@8.5.12)': + '@csstools/postcss-normalize-display-values@4.0.1(postcss@8.5.15)': dependencies: - postcss: 8.5.12 + postcss: 8.5.15 postcss-value-parser: 4.2.0 - '@csstools/postcss-oklab-function@4.0.12(postcss@8.5.12)': + '@csstools/postcss-oklab-function@4.0.12(postcss@8.5.15)': dependencies: '@csstools/css-color-parser': 3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) '@csstools/css-tokenizer': 3.0.4 - '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.12) - '@csstools/utilities': 2.0.0(postcss@8.5.12) - postcss: 8.5.12 + '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.15) + '@csstools/utilities': 2.0.0(postcss@8.5.15) + postcss: 8.5.15 - '@csstools/postcss-position-area-property@1.0.0(postcss@8.5.12)': + '@csstools/postcss-position-area-property@1.0.0(postcss@8.5.15)': dependencies: - postcss: 8.5.12 + postcss: 8.5.15 - '@csstools/postcss-progressive-custom-properties@4.2.1(postcss@8.5.12)': + '@csstools/postcss-progressive-custom-properties@4.2.1(postcss@8.5.15)': dependencies: - postcss: 8.5.12 + postcss: 8.5.15 postcss-value-parser: 4.2.0 - '@csstools/postcss-random-function@2.0.1(postcss@8.5.12)': + '@csstools/postcss-property-rule-prelude-list@1.0.0(postcss@8.5.15)': + dependencies: + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + postcss: 8.5.15 + + '@csstools/postcss-random-function@2.0.1(postcss@8.5.15)': dependencies: '@csstools/css-calc': 2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) '@csstools/css-tokenizer': 3.0.4 - postcss: 8.5.12 + postcss: 8.5.15 - '@csstools/postcss-relative-color-syntax@3.0.12(postcss@8.5.12)': + '@csstools/postcss-relative-color-syntax@3.0.12(postcss@8.5.15)': dependencies: '@csstools/css-color-parser': 3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) '@csstools/css-tokenizer': 3.0.4 - '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.12) - '@csstools/utilities': 2.0.0(postcss@8.5.12) - postcss: 8.5.12 + '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.15) + '@csstools/utilities': 2.0.0(postcss@8.5.15) + postcss: 8.5.15 - '@csstools/postcss-scope-pseudo-class@4.0.1(postcss@8.5.12)': + '@csstools/postcss-scope-pseudo-class@4.0.1(postcss@8.5.15)': dependencies: - postcss: 8.5.12 + postcss: 8.5.15 postcss-selector-parser: 7.1.1 - '@csstools/postcss-sign-functions@1.1.4(postcss@8.5.12)': + '@csstools/postcss-sign-functions@1.1.4(postcss@8.5.15)': dependencies: '@csstools/css-calc': 2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) '@csstools/css-tokenizer': 3.0.4 - postcss: 8.5.12 + postcss: 8.5.15 - '@csstools/postcss-stepped-value-functions@4.0.9(postcss@8.5.12)': + '@csstools/postcss-stepped-value-functions@4.0.9(postcss@8.5.15)': dependencies: '@csstools/css-calc': 2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) '@csstools/css-tokenizer': 3.0.4 - postcss: 8.5.12 + postcss: 8.5.15 - '@csstools/postcss-system-ui-font-family@1.0.0(postcss@8.5.12)': + '@csstools/postcss-syntax-descriptor-syntax-production@1.0.1(postcss@8.5.15)': + dependencies: + '@csstools/css-tokenizer': 3.0.4 + postcss: 8.5.15 + + '@csstools/postcss-system-ui-font-family@1.0.0(postcss@8.5.15)': dependencies: '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) '@csstools/css-tokenizer': 3.0.4 - postcss: 8.5.12 + postcss: 8.5.15 - '@csstools/postcss-text-decoration-shorthand@4.0.3(postcss@8.5.12)': + '@csstools/postcss-text-decoration-shorthand@4.0.3(postcss@8.5.15)': dependencies: '@csstools/color-helpers': 5.1.0 - postcss: 8.5.12 + postcss: 8.5.15 postcss-value-parser: 4.2.0 - '@csstools/postcss-trigonometric-functions@4.0.9(postcss@8.5.12)': + '@csstools/postcss-trigonometric-functions@4.0.9(postcss@8.5.15)': dependencies: '@csstools/css-calc': 2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) '@csstools/css-tokenizer': 3.0.4 - postcss: 8.5.12 + postcss: 8.5.15 - '@csstools/postcss-unset-value@4.0.0(postcss@8.5.12)': + '@csstools/postcss-unset-value@4.0.0(postcss@8.5.15)': dependencies: - postcss: 8.5.12 + postcss: 8.5.15 '@csstools/selector-resolve-nested@3.1.0(postcss-selector-parser@7.1.1)': dependencies: @@ -14268,94 +14406,135 @@ snapshots: dependencies: postcss-selector-parser: 7.1.1 - '@csstools/utilities@2.0.0(postcss@8.5.12)': + '@csstools/utilities@2.0.0(postcss@8.5.15)': dependencies: - postcss: 8.5.12 + postcss: 8.5.15 '@discoveryjs/json-ext@0.5.7': {} - '@docsearch/core@4.3.1(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + '@docsearch/core@4.6.3(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': optionalDependencies: - '@types/react': 19.2.14 - react: 19.2.5 - react-dom: 19.2.5(react@19.2.5) + '@types/react': 19.2.15 + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) - '@docsearch/css@4.3.2': {} + '@docsearch/css@4.6.3': {} - '@docsearch/react@4.3.2(@algolia/client-search@5.46.0)(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(search-insights@2.17.3)': + '@docsearch/react@4.6.3(@algolia/client-search@5.52.1)(@types/react@19.2.15)(algoliasearch@5.52.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(search-insights@2.17.3)': dependencies: - '@ai-sdk/react': 2.0.115(react@19.2.5)(zod@4.3.6) - '@algolia/autocomplete-core': 1.19.2(@algolia/client-search@5.46.0)(algoliasearch@5.46.0)(search-insights@2.17.3) - '@docsearch/core': 4.3.1(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docsearch/css': 4.3.2 - ai: 5.0.113(zod@4.3.6) - algoliasearch: 5.46.0 - marked: 16.4.2 - zod: 4.3.6 + '@algolia/autocomplete-core': 1.19.2(@algolia/client-search@5.52.1)(algoliasearch@5.52.1)(search-insights@2.17.3) + '@docsearch/core': 4.6.3(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docsearch/css': 4.6.3 optionalDependencies: - '@types/react': 19.2.14 - react: 19.2.5 - react-dom: 19.2.5(react@19.2.5) + '@types/react': 19.2.15 + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) search-insights: 2.17.3 transitivePeerDependencies: - '@algolia/client-search' + - algoliasearch - '@docusaurus/babel@3.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + '@docusaurus/babel@3.10.1(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.15))(html-minifier-terser@7.2.0)(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.29.0 '@babel/generator': 7.29.1 - '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.28.5) - '@babel/plugin-transform-runtime': 7.28.5(@babel/core@7.28.5) - '@babel/preset-env': 7.28.5(@babel/core@7.28.5) - '@babel/preset-react': 7.28.5(@babel/core@7.28.5) - '@babel/preset-typescript': 7.28.5(@babel/core@7.28.5) + '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.29.0) + '@babel/plugin-transform-runtime': 7.29.0(@babel/core@7.29.0) + '@babel/preset-env': 7.29.5(@babel/core@7.29.0) + '@babel/preset-react': 7.28.5(@babel/core@7.29.0) + '@babel/preset-typescript': 7.28.5(@babel/core@7.29.0) '@babel/runtime': 7.29.2 '@babel/traverse': 7.29.0 - '@docusaurus/logger': 3.10.0 - '@docusaurus/utils': 3.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@docusaurus/logger': 3.10.1 + '@docusaurus/utils': 3.10.1(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.15))(html-minifier-terser@7.2.0)(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) babel-plugin-dynamic-import-node: 2.3.3 - fs-extra: 11.3.4 + fs-extra: 11.3.5 tslib: 2.8.1 transitivePeerDependencies: + - '@minify-html/node' - '@swc/core' + - '@swc/css' + - '@swc/html' + - clean-css + - cssnano + - csso - esbuild + - html-minifier-terser + - lightningcss + - postcss - react - react-dom - supports-color - uglify-js - webpack-cli - '@docusaurus/bundler@3.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3)': + '@docusaurus/babel@3.10.1(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': dependencies: - '@babel/core': 7.28.5 - '@docusaurus/babel': 3.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/cssnano-preset': 3.10.0 - '@docusaurus/logger': 3.10.0 - '@docusaurus/types': 3.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/utils': 3.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - babel-loader: 9.2.1(@babel/core@7.28.5)(webpack@5.106.2) - clean-css: 5.3.3 - copy-webpack-plugin: 11.0.0(webpack@5.106.2) - css-loader: 6.11.0(webpack@5.106.2) - css-minimizer-webpack-plugin: 5.0.1(clean-css@5.3.3)(webpack@5.106.2) - cssnano: 6.1.2(postcss@8.5.12) - file-loader: 6.2.0(webpack@5.106.2) - html-minifier-terser: 7.2.0 - mini-css-extract-plugin: 2.9.4(webpack@5.106.2) - null-loader: 4.0.1(webpack@5.106.2) - postcss: 8.5.12 - postcss-loader: 7.3.4(postcss@8.5.12)(typescript@6.0.3)(webpack@5.106.2) - postcss-preset-env: 10.5.0(postcss@8.5.12) - terser-webpack-plugin: 5.4.0(webpack@5.106.2) + '@babel/core': 7.29.0 + '@babel/generator': 7.29.1 + '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.29.0) + '@babel/plugin-transform-runtime': 7.29.0(@babel/core@7.29.0) + '@babel/preset-env': 7.29.5(@babel/core@7.29.0) + '@babel/preset-react': 7.28.5(@babel/core@7.29.0) + '@babel/preset-typescript': 7.28.5(@babel/core@7.29.0) + '@babel/runtime': 7.29.2 + '@babel/traverse': 7.29.0 + '@docusaurus/logger': 3.10.1 + '@docusaurus/utils': 3.10.1(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + babel-plugin-dynamic-import-node: 2.3.3 + fs-extra: 11.3.5 tslib: 2.8.1 - url-loader: 4.1.1(file-loader@6.2.0(webpack@5.106.2))(webpack@5.106.2) - webpack: 5.106.2 - webpackbar: 7.0.0(webpack@5.106.2) transitivePeerDependencies: + - '@minify-html/node' + - '@swc/core' + - '@swc/css' + - '@swc/html' + - clean-css + - cssnano + - csso + - esbuild + - html-minifier-terser + - lightningcss + - postcss + - react + - react-dom + - supports-color + - uglify-js + - webpack-cli + + '@docusaurus/bundler@3.10.1(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.3)': + dependencies: + '@babel/core': 7.29.0 + '@docusaurus/babel': 3.10.1(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.15))(html-minifier-terser@7.2.0)(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/cssnano-preset': 3.10.1 + '@docusaurus/logger': 3.10.1 + '@docusaurus/types': 3.10.1(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.15))(html-minifier-terser@7.2.0)(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/utils': 3.10.1(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.15))(html-minifier-terser@7.2.0)(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + babel-loader: 9.2.1(@babel/core@7.29.0)(webpack@5.107.0(postcss@8.5.15)) + clean-css: 5.3.3 + copy-webpack-plugin: 11.0.0(webpack@5.107.0(postcss@8.5.15)) + css-loader: 6.11.0(webpack@5.107.0(postcss@8.5.15)) + css-minimizer-webpack-plugin: 5.0.1(clean-css@5.3.3)(webpack@5.107.0(postcss@8.5.15)) + cssnano: 6.1.2(postcss@8.5.15) + file-loader: 6.2.0(webpack@5.107.0(postcss@8.5.15)) + html-minifier-terser: 7.2.0 + mini-css-extract-plugin: 2.10.2(webpack@5.107.0(postcss@8.5.15)) + null-loader: 4.0.1(webpack@5.107.0(postcss@8.5.15)) + postcss: 8.5.15 + postcss-loader: 7.3.4(postcss@8.5.15)(typescript@6.0.3)(webpack@5.107.0(postcss@8.5.15)) + postcss-preset-env: 10.6.1(postcss@8.5.15) + terser-webpack-plugin: 5.6.0(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.15))(html-minifier-terser@7.2.0)(postcss@8.5.15)(webpack@5.107.0(postcss@8.5.15)) + tslib: 2.8.1 + url-loader: 4.1.1(file-loader@6.2.0(webpack@5.107.0(postcss@8.5.15)))(webpack@5.107.0(postcss@8.5.15)) + webpack: 5.107.0(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.15))(html-minifier-terser@7.2.0)(postcss@8.5.15) + webpackbar: 7.0.0(webpack@5.107.0(postcss@8.5.15)) + transitivePeerDependencies: + - '@minify-html/node' - '@parcel/css' - '@rspack/core' - '@swc/core' - '@swc/css' + - '@swc/html' - csso - esbuild - lightningcss @@ -14366,97 +14545,103 @@ snapshots: - uglify-js - webpack-cli - '@docusaurus/core@3.10.0(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3)': + '@docusaurus/core@3.10.1(@mdx-js/react@3.1.1(@types/react@19.2.15)(react@19.2.6))(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.3)': dependencies: - '@docusaurus/babel': 3.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/bundler': 3.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3) - '@docusaurus/logger': 3.10.0 - '@docusaurus/mdx-loader': 3.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/utils': 3.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/utils-common': 3.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/utils-validation': 3.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@mdx-js/react': 3.1.1(@types/react@19.2.14)(react@19.2.5) + '@docusaurus/babel': 3.10.1(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/bundler': 3.10.1(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.3) + '@docusaurus/logger': 3.10.1 + '@docusaurus/mdx-loader': 3.10.1(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/utils': 3.10.1(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/utils-common': 3.10.1(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/utils-validation': 3.10.1(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@mdx-js/react': 3.1.1(@types/react@19.2.15)(react@19.2.6) boxen: 6.2.1 chalk: 4.1.2 chokidar: 3.6.0 cli-table3: 0.6.5 combine-promises: 1.2.0 commander: 5.1.0 - core-js: 3.47.0 + core-js: 3.49.0 detect-port: 1.6.1 escape-html: 1.0.3 eta: 2.2.0 eval: 0.1.8 execa: 5.1.1 - fs-extra: 11.3.4 + fs-extra: 11.3.5 html-tags: 3.3.1 - html-webpack-plugin: 5.6.5(webpack@5.106.2) + html-webpack-plugin: 5.6.7(webpack@5.107.0(postcss@8.5.15)) leven: 3.1.0 lodash: 4.18.1 open: 8.4.2 p-map: 4.0.0 prompts: 2.4.2 - react: 19.2.5 - react-dom: 19.2.5(react@19.2.5) - react-helmet-async: '@slorber/react-helmet-async@1.3.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5)' - react-loadable: '@docusaurus/react-loadable@6.0.0(react@19.2.5)' - react-loadable-ssr-addon-v5-slorber: 1.0.3(@docusaurus/react-loadable@6.0.0(react@19.2.5))(webpack@5.106.2) - react-router: 5.3.4(react@19.2.5) - react-router-config: 5.1.1(react-router@5.3.4(react@19.2.5))(react@19.2.5) - react-router-dom: 5.3.4(react@19.2.5) - semver: 7.7.4 + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + react-helmet-async: '@slorber/react-helmet-async@1.3.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6)' + react-loadable: '@docusaurus/react-loadable@6.0.0(react@19.2.6)' + react-loadable-ssr-addon-v5-slorber: 1.0.3(@docusaurus/react-loadable@6.0.0(react@19.2.6))(webpack@5.107.0(postcss@8.5.15)) + react-router: 5.3.4(react@19.2.6) + react-router-config: 5.1.1(react-router@5.3.4(react@19.2.6))(react@19.2.6) + react-router-dom: 5.3.4(react@19.2.6) + semver: 7.8.0 serve-handler: 6.1.7 tinypool: 1.1.1 tslib: 2.8.1 update-notifier: 6.0.2 - webpack: 5.106.2 + webpack: 5.107.0(postcss@8.5.15) webpack-bundle-analyzer: 4.10.2 - webpack-dev-server: 5.2.2(tslib@2.8.1)(webpack@5.106.2) + webpack-dev-server: 5.2.4(tslib@2.8.1)(webpack@5.107.0(postcss@8.5.15)) webpack-merge: 6.0.1 transitivePeerDependencies: + - '@minify-html/node' - '@parcel/css' - '@rspack/core' - '@swc/core' - '@swc/css' + - '@swc/html' - bufferutil + - clean-css + - cssnano - csso - debug - esbuild + - html-minifier-terser - lightningcss + - postcss - supports-color - typescript - uglify-js - utf-8-validate - webpack-cli - '@docusaurus/cssnano-preset@3.10.0': + '@docusaurus/cssnano-preset@3.10.1': dependencies: - cssnano-preset-advanced: 6.1.2(postcss@8.5.12) - postcss: 8.5.12 - postcss-sort-media-queries: 5.2.0(postcss@8.5.12) + cssnano-preset-advanced: 6.1.2(postcss@8.5.15) + postcss: 8.5.15 + postcss-sort-media-queries: 5.2.0(postcss@8.5.15) tslib: 2.8.1 - '@docusaurus/logger@3.10.0': + '@docusaurus/logger@3.10.1': dependencies: chalk: 4.1.2 tslib: 2.8.1 - '@docusaurus/mdx-loader@3.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + '@docusaurus/mdx-loader@3.10.1(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': dependencies: - '@docusaurus/logger': 3.10.0 - '@docusaurus/utils': 3.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/utils-validation': 3.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@docusaurus/logger': 3.10.1 + '@docusaurus/utils': 3.10.1(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/utils-validation': 3.10.1(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) '@mdx-js/mdx': 3.1.1 '@slorber/remark-comment': 1.0.0 escape-html: 1.0.3 estree-util-value-to-estree: 3.5.0 - file-loader: 6.2.0(webpack@5.106.2) - fs-extra: 11.3.4 + file-loader: 6.2.0(webpack@5.107.0(postcss@8.5.15)) + fs-extra: 11.3.5 image-size: 2.0.2 mdast-util-mdx: 3.0.0 mdast-util-to-string: 4.0.0 - react: 19.2.5 - react-dom: 19.2.5(react@19.2.5) + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) rehype-raw: 7.0.0 remark-directive: 3.0.1 remark-emoji: 4.0.1 @@ -14465,166 +14650,208 @@ snapshots: stringify-object: 3.3.0 tslib: 2.8.1 unified: 11.0.5 - unist-util-visit: 5.0.0 - url-loader: 4.1.1(file-loader@6.2.0(webpack@5.106.2))(webpack@5.106.2) + unist-util-visit: 5.1.0 + url-loader: 4.1.1(file-loader@6.2.0(webpack@5.107.0(postcss@8.5.15)))(webpack@5.107.0(postcss@8.5.15)) vfile: 6.0.3 - webpack: 5.106.2 + webpack: 5.107.0(postcss@8.5.15) transitivePeerDependencies: + - '@minify-html/node' - '@swc/core' + - '@swc/css' + - '@swc/html' + - clean-css + - cssnano + - csso - esbuild + - html-minifier-terser + - lightningcss + - postcss - supports-color - uglify-js - webpack-cli - '@docusaurus/module-type-aliases@3.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + '@docusaurus/module-type-aliases@3.10.1(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': dependencies: - '@docusaurus/types': 3.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@docusaurus/types': 3.10.1(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) '@types/history': 4.7.11 - '@types/react': 19.2.14 + '@types/react': 19.2.15 '@types/react-router-config': 5.0.11 '@types/react-router-dom': 5.3.3 - react: 19.2.5 - react-dom: 19.2.5(react@19.2.5) - react-helmet-async: '@slorber/react-helmet-async@1.3.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5)' - react-loadable: '@docusaurus/react-loadable@6.0.0(react@19.2.5)' + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + react-helmet-async: '@slorber/react-helmet-async@1.3.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6)' + react-loadable: '@docusaurus/react-loadable@6.0.0(react@19.2.6)' transitivePeerDependencies: + - '@minify-html/node' - '@swc/core' + - '@swc/css' + - '@swc/html' + - clean-css + - cssnano + - csso - esbuild + - html-minifier-terser + - lightningcss + - postcss - supports-color - uglify-js - webpack-cli - '@docusaurus/plugin-content-blog@3.10.0(@docusaurus/plugin-content-docs@3.10.0(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3)': + '@docusaurus/plugin-content-blog@3.10.1(@docusaurus/plugin-content-docs@3.10.1(@mdx-js/react@3.1.1(@types/react@19.2.15)(react@19.2.6))(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.3))(@mdx-js/react@3.1.1(@types/react@19.2.15)(react@19.2.6))(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.3)': dependencies: - '@docusaurus/core': 3.10.0(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3) - '@docusaurus/logger': 3.10.0 - '@docusaurus/mdx-loader': 3.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/plugin-content-docs': 3.10.0(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3) - '@docusaurus/theme-common': 3.10.0(@docusaurus/plugin-content-docs@3.10.0(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3))(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/types': 3.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/utils': 3.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/utils-common': 3.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/utils-validation': 3.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@docusaurus/core': 3.10.1(@mdx-js/react@3.1.1(@types/react@19.2.15)(react@19.2.6))(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.3) + '@docusaurus/logger': 3.10.1 + '@docusaurus/mdx-loader': 3.10.1(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/plugin-content-docs': 3.10.1(@mdx-js/react@3.1.1(@types/react@19.2.15)(react@19.2.6))(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.3) + '@docusaurus/theme-common': 3.10.1(@docusaurus/plugin-content-docs@3.10.1(@mdx-js/react@3.1.1(@types/react@19.2.15)(react@19.2.6))(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.3))(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/types': 3.10.1(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/utils': 3.10.1(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/utils-common': 3.10.1(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/utils-validation': 3.10.1(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) cheerio: 1.0.0-rc.12 combine-promises: 1.2.0 feed: 4.2.2 - fs-extra: 11.3.4 + fs-extra: 11.3.5 lodash: 4.18.1 - react: 19.2.5 - react-dom: 19.2.5(react@19.2.5) + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) schema-dts: 1.1.5 srcset: 4.0.0 tslib: 2.8.1 - unist-util-visit: 5.0.0 + unist-util-visit: 5.1.0 utility-types: 3.11.0 - webpack: 5.106.2 + webpack: 5.107.0(postcss@8.5.15) transitivePeerDependencies: - '@docusaurus/faster' - '@mdx-js/react' + - '@minify-html/node' - '@parcel/css' - '@rspack/core' - '@swc/core' - '@swc/css' + - '@swc/html' - bufferutil + - clean-css + - cssnano - csso - debug - esbuild + - html-minifier-terser - lightningcss + - postcss - supports-color - typescript - uglify-js - utf-8-validate - webpack-cli - '@docusaurus/plugin-content-docs@3.10.0(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3)': + '@docusaurus/plugin-content-docs@3.10.1(@mdx-js/react@3.1.1(@types/react@19.2.15)(react@19.2.6))(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.3)': dependencies: - '@docusaurus/core': 3.10.0(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3) - '@docusaurus/logger': 3.10.0 - '@docusaurus/mdx-loader': 3.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/module-type-aliases': 3.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/theme-common': 3.10.0(@docusaurus/plugin-content-docs@3.10.0(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3))(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/types': 3.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/utils': 3.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/utils-common': 3.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/utils-validation': 3.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@docusaurus/core': 3.10.1(@mdx-js/react@3.1.1(@types/react@19.2.15)(react@19.2.6))(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.3) + '@docusaurus/logger': 3.10.1 + '@docusaurus/mdx-loader': 3.10.1(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/module-type-aliases': 3.10.1(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/theme-common': 3.10.1(@docusaurus/plugin-content-docs@3.10.1(@mdx-js/react@3.1.1(@types/react@19.2.15)(react@19.2.6))(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.3))(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/types': 3.10.1(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/utils': 3.10.1(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/utils-common': 3.10.1(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/utils-validation': 3.10.1(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) '@types/react-router-config': 5.0.11 combine-promises: 1.2.0 - fs-extra: 11.3.4 + fs-extra: 11.3.5 js-yaml: 4.1.1 lodash: 4.18.1 - react: 19.2.5 - react-dom: 19.2.5(react@19.2.5) + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) schema-dts: 1.1.5 tslib: 2.8.1 utility-types: 3.11.0 - webpack: 5.106.2 + webpack: 5.107.0(postcss@8.5.15) transitivePeerDependencies: - '@docusaurus/faster' - '@mdx-js/react' + - '@minify-html/node' - '@parcel/css' - '@rspack/core' - '@swc/core' - '@swc/css' + - '@swc/html' - bufferutil + - clean-css + - cssnano - csso - debug - esbuild + - html-minifier-terser - lightningcss + - postcss - supports-color - typescript - uglify-js - utf-8-validate - webpack-cli - '@docusaurus/plugin-content-pages@3.10.0(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3)': + '@docusaurus/plugin-content-pages@3.10.1(@mdx-js/react@3.1.1(@types/react@19.2.15)(react@19.2.6))(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.3)': dependencies: - '@docusaurus/core': 3.10.0(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3) - '@docusaurus/mdx-loader': 3.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/types': 3.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/utils': 3.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/utils-validation': 3.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - fs-extra: 11.3.4 - react: 19.2.5 - react-dom: 19.2.5(react@19.2.5) + '@docusaurus/core': 3.10.1(@mdx-js/react@3.1.1(@types/react@19.2.15)(react@19.2.6))(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.3) + '@docusaurus/mdx-loader': 3.10.1(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/types': 3.10.1(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/utils': 3.10.1(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/utils-validation': 3.10.1(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + fs-extra: 11.3.5 + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) tslib: 2.8.1 - webpack: 5.106.2 + webpack: 5.107.0(postcss@8.5.15) transitivePeerDependencies: - '@docusaurus/faster' - '@mdx-js/react' + - '@minify-html/node' - '@parcel/css' - '@rspack/core' - '@swc/core' - '@swc/css' + - '@swc/html' - bufferutil + - clean-css + - cssnano - csso - debug - esbuild + - html-minifier-terser - lightningcss + - postcss - supports-color - typescript - uglify-js - utf-8-validate - webpack-cli - '@docusaurus/plugin-css-cascade-layers@3.10.0(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3)': + '@docusaurus/plugin-css-cascade-layers@3.10.1(@mdx-js/react@3.1.1(@types/react@19.2.15)(react@19.2.6))(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.3)': dependencies: - '@docusaurus/core': 3.10.0(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3) - '@docusaurus/types': 3.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/utils': 3.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/utils-validation': 3.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@docusaurus/core': 3.10.1(@mdx-js/react@3.1.1(@types/react@19.2.15)(react@19.2.6))(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.3) + '@docusaurus/types': 3.10.1(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/utils': 3.10.1(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/utils-validation': 3.10.1(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) tslib: 2.8.1 transitivePeerDependencies: - '@docusaurus/faster' - '@mdx-js/react' + - '@minify-html/node' - '@parcel/css' - '@rspack/core' - '@swc/core' - '@swc/css' + - '@swc/html' - bufferutil + - clean-css + - cssnano - csso - debug - esbuild + - html-minifier-terser - lightningcss + - postcss - react - react-dom - supports-color @@ -14633,207 +14860,249 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/plugin-debug@3.10.0(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3)': + '@docusaurus/plugin-debug@3.10.1(@mdx-js/react@3.1.1(@types/react@19.2.15)(react@19.2.6))(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.3)': dependencies: - '@docusaurus/core': 3.10.0(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3) - '@docusaurus/types': 3.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/utils': 3.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - fs-extra: 11.3.4 - react: 19.2.5 - react-dom: 19.2.5(react@19.2.5) - react-json-view-lite: 2.5.0(react@19.2.5) + '@docusaurus/core': 3.10.1(@mdx-js/react@3.1.1(@types/react@19.2.15)(react@19.2.6))(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.3) + '@docusaurus/types': 3.10.1(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/utils': 3.10.1(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + fs-extra: 11.3.5 + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + react-json-view-lite: 2.5.0(react@19.2.6) tslib: 2.8.1 transitivePeerDependencies: - '@docusaurus/faster' - '@mdx-js/react' + - '@minify-html/node' - '@parcel/css' - '@rspack/core' - '@swc/core' - '@swc/css' + - '@swc/html' - bufferutil + - clean-css + - cssnano - csso - debug - esbuild + - html-minifier-terser - lightningcss + - postcss - supports-color - typescript - uglify-js - utf-8-validate - webpack-cli - '@docusaurus/plugin-google-analytics@3.10.0(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3)': + '@docusaurus/plugin-google-analytics@3.10.1(@mdx-js/react@3.1.1(@types/react@19.2.15)(react@19.2.6))(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.3)': dependencies: - '@docusaurus/core': 3.10.0(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3) - '@docusaurus/types': 3.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/utils-validation': 3.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - react: 19.2.5 - react-dom: 19.2.5(react@19.2.5) + '@docusaurus/core': 3.10.1(@mdx-js/react@3.1.1(@types/react@19.2.15)(react@19.2.6))(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.3) + '@docusaurus/types': 3.10.1(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/utils-validation': 3.10.1(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) tslib: 2.8.1 transitivePeerDependencies: - '@docusaurus/faster' - '@mdx-js/react' + - '@minify-html/node' - '@parcel/css' - '@rspack/core' - '@swc/core' - '@swc/css' + - '@swc/html' - bufferutil + - clean-css + - cssnano - csso - debug - esbuild + - html-minifier-terser - lightningcss + - postcss - supports-color - typescript - uglify-js - utf-8-validate - webpack-cli - '@docusaurus/plugin-google-gtag@3.10.0(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3)': + '@docusaurus/plugin-google-gtag@3.10.1(@mdx-js/react@3.1.1(@types/react@19.2.15)(react@19.2.6))(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.3)': dependencies: - '@docusaurus/core': 3.10.0(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3) - '@docusaurus/types': 3.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/utils-validation': 3.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@docusaurus/core': 3.10.1(@mdx-js/react@3.1.1(@types/react@19.2.15)(react@19.2.6))(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.3) + '@docusaurus/types': 3.10.1(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/utils-validation': 3.10.1(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) '@types/gtag.js': 0.0.20 - react: 19.2.5 - react-dom: 19.2.5(react@19.2.5) + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) tslib: 2.8.1 transitivePeerDependencies: - '@docusaurus/faster' - '@mdx-js/react' + - '@minify-html/node' - '@parcel/css' - '@rspack/core' - '@swc/core' - '@swc/css' + - '@swc/html' - bufferutil + - clean-css + - cssnano - csso - debug - esbuild + - html-minifier-terser - lightningcss + - postcss - supports-color - typescript - uglify-js - utf-8-validate - webpack-cli - '@docusaurus/plugin-google-tag-manager@3.10.0(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3)': + '@docusaurus/plugin-google-tag-manager@3.10.1(@mdx-js/react@3.1.1(@types/react@19.2.15)(react@19.2.6))(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.3)': dependencies: - '@docusaurus/core': 3.10.0(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3) - '@docusaurus/types': 3.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/utils-validation': 3.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - react: 19.2.5 - react-dom: 19.2.5(react@19.2.5) + '@docusaurus/core': 3.10.1(@mdx-js/react@3.1.1(@types/react@19.2.15)(react@19.2.6))(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.3) + '@docusaurus/types': 3.10.1(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/utils-validation': 3.10.1(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) tslib: 2.8.1 transitivePeerDependencies: - '@docusaurus/faster' - '@mdx-js/react' + - '@minify-html/node' - '@parcel/css' - '@rspack/core' - '@swc/core' - '@swc/css' + - '@swc/html' - bufferutil + - clean-css + - cssnano - csso - debug - esbuild + - html-minifier-terser - lightningcss + - postcss - supports-color - typescript - uglify-js - utf-8-validate - webpack-cli - '@docusaurus/plugin-sitemap@3.10.0(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3)': + '@docusaurus/plugin-sitemap@3.10.1(@mdx-js/react@3.1.1(@types/react@19.2.15)(react@19.2.6))(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.3)': dependencies: - '@docusaurus/core': 3.10.0(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3) - '@docusaurus/logger': 3.10.0 - '@docusaurus/types': 3.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/utils': 3.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/utils-common': 3.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/utils-validation': 3.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - fs-extra: 11.3.4 - react: 19.2.5 - react-dom: 19.2.5(react@19.2.5) - sitemap: 7.1.2 + '@docusaurus/core': 3.10.1(@mdx-js/react@3.1.1(@types/react@19.2.15)(react@19.2.6))(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.3) + '@docusaurus/logger': 3.10.1 + '@docusaurus/types': 3.10.1(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/utils': 3.10.1(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/utils-common': 3.10.1(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/utils-validation': 3.10.1(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + fs-extra: 11.3.5 + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + sitemap: 7.1.3 tslib: 2.8.1 transitivePeerDependencies: - '@docusaurus/faster' - '@mdx-js/react' + - '@minify-html/node' - '@parcel/css' - '@rspack/core' - '@swc/core' - '@swc/css' + - '@swc/html' - bufferutil + - clean-css + - cssnano - csso - debug - esbuild + - html-minifier-terser - lightningcss + - postcss - supports-color - typescript - uglify-js - utf-8-validate - webpack-cli - '@docusaurus/plugin-svgr@3.10.0(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3)': + '@docusaurus/plugin-svgr@3.10.1(@mdx-js/react@3.1.1(@types/react@19.2.15)(react@19.2.6))(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.3)': dependencies: - '@docusaurus/core': 3.10.0(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3) - '@docusaurus/types': 3.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/utils': 3.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/utils-validation': 3.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@docusaurus/core': 3.10.1(@mdx-js/react@3.1.1(@types/react@19.2.15)(react@19.2.6))(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.3) + '@docusaurus/types': 3.10.1(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/utils': 3.10.1(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/utils-validation': 3.10.1(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) '@svgr/core': 8.1.0(typescript@6.0.3) '@svgr/webpack': 8.1.0(typescript@6.0.3) - react: 19.2.5 - react-dom: 19.2.5(react@19.2.5) + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) tslib: 2.8.1 - webpack: 5.106.2 + webpack: 5.107.0(postcss@8.5.15) transitivePeerDependencies: - '@docusaurus/faster' - '@mdx-js/react' + - '@minify-html/node' - '@parcel/css' - '@rspack/core' - '@swc/core' - '@swc/css' + - '@swc/html' - bufferutil + - clean-css + - cssnano - csso - debug - esbuild + - html-minifier-terser - lightningcss + - postcss - supports-color - typescript - uglify-js - utf-8-validate - webpack-cli - '@docusaurus/preset-classic@3.10.0(@algolia/client-search@5.46.0)(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(search-insights@2.17.3)(typescript@6.0.3)': + '@docusaurus/preset-classic@3.10.1(@algolia/client-search@5.52.1)(@mdx-js/react@3.1.1(@types/react@19.2.15)(react@19.2.6))(@types/react@19.2.15)(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(search-insights@2.17.3)(typescript@6.0.3)': dependencies: - '@docusaurus/core': 3.10.0(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3) - '@docusaurus/plugin-content-blog': 3.10.0(@docusaurus/plugin-content-docs@3.10.0(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3) - '@docusaurus/plugin-content-docs': 3.10.0(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3) - '@docusaurus/plugin-content-pages': 3.10.0(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3) - '@docusaurus/plugin-css-cascade-layers': 3.10.0(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3) - '@docusaurus/plugin-debug': 3.10.0(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3) - '@docusaurus/plugin-google-analytics': 3.10.0(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3) - '@docusaurus/plugin-google-gtag': 3.10.0(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3) - '@docusaurus/plugin-google-tag-manager': 3.10.0(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3) - '@docusaurus/plugin-sitemap': 3.10.0(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3) - '@docusaurus/plugin-svgr': 3.10.0(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3) - '@docusaurus/theme-classic': 3.10.0(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3) - '@docusaurus/theme-common': 3.10.0(@docusaurus/plugin-content-docs@3.10.0(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3))(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/theme-search-algolia': 3.10.0(@algolia/client-search@5.46.0)(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(search-insights@2.17.3)(typescript@6.0.3) - '@docusaurus/types': 3.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - react: 19.2.5 - react-dom: 19.2.5(react@19.2.5) + '@docusaurus/core': 3.10.1(@mdx-js/react@3.1.1(@types/react@19.2.15)(react@19.2.6))(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.3) + '@docusaurus/plugin-content-blog': 3.10.1(@docusaurus/plugin-content-docs@3.10.1(@mdx-js/react@3.1.1(@types/react@19.2.15)(react@19.2.6))(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.3))(@mdx-js/react@3.1.1(@types/react@19.2.15)(react@19.2.6))(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.3) + '@docusaurus/plugin-content-docs': 3.10.1(@mdx-js/react@3.1.1(@types/react@19.2.15)(react@19.2.6))(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.3) + '@docusaurus/plugin-content-pages': 3.10.1(@mdx-js/react@3.1.1(@types/react@19.2.15)(react@19.2.6))(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.3) + '@docusaurus/plugin-css-cascade-layers': 3.10.1(@mdx-js/react@3.1.1(@types/react@19.2.15)(react@19.2.6))(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.3) + '@docusaurus/plugin-debug': 3.10.1(@mdx-js/react@3.1.1(@types/react@19.2.15)(react@19.2.6))(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.3) + '@docusaurus/plugin-google-analytics': 3.10.1(@mdx-js/react@3.1.1(@types/react@19.2.15)(react@19.2.6))(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.3) + '@docusaurus/plugin-google-gtag': 3.10.1(@mdx-js/react@3.1.1(@types/react@19.2.15)(react@19.2.6))(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.3) + '@docusaurus/plugin-google-tag-manager': 3.10.1(@mdx-js/react@3.1.1(@types/react@19.2.15)(react@19.2.6))(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.3) + '@docusaurus/plugin-sitemap': 3.10.1(@mdx-js/react@3.1.1(@types/react@19.2.15)(react@19.2.6))(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.3) + '@docusaurus/plugin-svgr': 3.10.1(@mdx-js/react@3.1.1(@types/react@19.2.15)(react@19.2.6))(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.3) + '@docusaurus/theme-classic': 3.10.1(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.3) + '@docusaurus/theme-common': 3.10.1(@docusaurus/plugin-content-docs@3.10.1(@mdx-js/react@3.1.1(@types/react@19.2.15)(react@19.2.6))(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.3))(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/theme-search-algolia': 3.10.1(@algolia/client-search@5.52.1)(@mdx-js/react@3.1.1(@types/react@19.2.15)(react@19.2.6))(@types/react@19.2.15)(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(search-insights@2.17.3)(typescript@6.0.3) + '@docusaurus/types': 3.10.1(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) transitivePeerDependencies: - '@algolia/client-search' - '@docusaurus/faster' - '@mdx-js/react' + - '@minify-html/node' - '@parcel/css' - '@rspack/core' - '@swc/core' - '@swc/css' + - '@swc/html' - '@types/react' - bufferutil + - clean-css + - cssnano - csso - debug - esbuild + - html-minifier-terser - lightningcss + - postcss - search-insights - supports-color - typescript @@ -14841,52 +15110,57 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/react-loadable@6.0.0(react@19.2.5)': + '@docusaurus/react-loadable@6.0.0(react@19.2.6)': dependencies: - '@types/react': 19.2.14 - react: 19.2.5 + '@types/react': 19.2.15 + react: 19.2.6 - '@docusaurus/theme-classic@3.10.0(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3)': + '@docusaurus/theme-classic@3.10.1(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.3)': dependencies: - '@docusaurus/core': 3.10.0(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3) - '@docusaurus/logger': 3.10.0 - '@docusaurus/mdx-loader': 3.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/module-type-aliases': 3.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/plugin-content-blog': 3.10.0(@docusaurus/plugin-content-docs@3.10.0(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3) - '@docusaurus/plugin-content-docs': 3.10.0(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3) - '@docusaurus/plugin-content-pages': 3.10.0(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3) - '@docusaurus/theme-common': 3.10.0(@docusaurus/plugin-content-docs@3.10.0(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3))(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/theme-translations': 3.10.0 - '@docusaurus/types': 3.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/utils': 3.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/utils-common': 3.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/utils-validation': 3.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@mdx-js/react': 3.1.1(@types/react@19.2.14)(react@19.2.5) + '@docusaurus/core': 3.10.1(@mdx-js/react@3.1.1(@types/react@19.2.15)(react@19.2.6))(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.3) + '@docusaurus/logger': 3.10.1 + '@docusaurus/mdx-loader': 3.10.1(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/module-type-aliases': 3.10.1(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/plugin-content-blog': 3.10.1(@docusaurus/plugin-content-docs@3.10.1(@mdx-js/react@3.1.1(@types/react@19.2.15)(react@19.2.6))(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.3))(@mdx-js/react@3.1.1(@types/react@19.2.15)(react@19.2.6))(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.3) + '@docusaurus/plugin-content-docs': 3.10.1(@mdx-js/react@3.1.1(@types/react@19.2.15)(react@19.2.6))(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.3) + '@docusaurus/plugin-content-pages': 3.10.1(@mdx-js/react@3.1.1(@types/react@19.2.15)(react@19.2.6))(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.3) + '@docusaurus/theme-common': 3.10.1(@docusaurus/plugin-content-docs@3.10.1(@mdx-js/react@3.1.1(@types/react@19.2.15)(react@19.2.6))(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.3))(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/theme-translations': 3.10.1 + '@docusaurus/types': 3.10.1(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/utils': 3.10.1(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/utils-common': 3.10.1(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/utils-validation': 3.10.1(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@mdx-js/react': 3.1.1(@types/react@19.2.15)(react@19.2.6) clsx: 2.1.1 copy-text-to-clipboard: 3.2.2 infima: 0.2.0-alpha.45 lodash: 4.18.1 nprogress: 0.2.0 - postcss: 8.5.12 - prism-react-renderer: 2.4.1(react@19.2.5) + postcss: 8.5.15 + prism-react-renderer: 2.4.1(react@19.2.6) prismjs: 1.30.0 - react: 19.2.5 - react-dom: 19.2.5(react@19.2.5) - react-router-dom: 5.3.4(react@19.2.5) + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + react-router-dom: 5.3.4(react@19.2.6) rtlcss: 4.3.0 tslib: 2.8.1 utility-types: 3.11.0 transitivePeerDependencies: - '@docusaurus/faster' + - '@minify-html/node' - '@parcel/css' - '@rspack/core' - '@swc/core' - '@swc/css' + - '@swc/html' - '@types/react' - bufferutil + - clean-css + - cssnano - csso - debug - esbuild + - html-minifier-terser - lightningcss - supports-color - typescript @@ -14894,95 +15168,116 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/theme-common@3.10.0(@docusaurus/plugin-content-docs@3.10.0(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + '@docusaurus/theme-common@3.10.1(@docusaurus/plugin-content-docs@3.10.1(@mdx-js/react@3.1.1(@types/react@19.2.15)(react@19.2.6))(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.3))(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': dependencies: - '@docusaurus/mdx-loader': 3.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/module-type-aliases': 3.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/plugin-content-docs': 3.10.0(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3) - '@docusaurus/utils': 3.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/utils-common': 3.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@docusaurus/mdx-loader': 3.10.1(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/module-type-aliases': 3.10.1(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/plugin-content-docs': 3.10.1(@mdx-js/react@3.1.1(@types/react@19.2.15)(react@19.2.6))(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.3) + '@docusaurus/utils': 3.10.1(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/utils-common': 3.10.1(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) '@types/history': 4.7.11 - '@types/react': 19.2.14 + '@types/react': 19.2.15 '@types/react-router-config': 5.0.11 clsx: 2.1.1 parse-numeric-range: 1.3.0 - prism-react-renderer: 2.4.1(react@19.2.5) - react: 19.2.5 - react-dom: 19.2.5(react@19.2.5) + prism-react-renderer: 2.4.1(react@19.2.6) + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) tslib: 2.8.1 utility-types: 3.11.0 transitivePeerDependencies: + - '@minify-html/node' - '@swc/core' + - '@swc/css' + - '@swc/html' + - clean-css + - cssnano + - csso - esbuild + - html-minifier-terser + - lightningcss + - postcss - supports-color - uglify-js - webpack-cli - '@docusaurus/theme-mermaid@3.10.0(@docusaurus/plugin-content-docs@3.10.0(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3)': + '@docusaurus/theme-mermaid@3.10.1(@docusaurus/plugin-content-docs@3.10.1(@mdx-js/react@3.1.1(@types/react@19.2.15)(react@19.2.6))(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.3))(@mdx-js/react@3.1.1(@types/react@19.2.15)(react@19.2.6))(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.3)': dependencies: - '@docusaurus/core': 3.10.0(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3) - '@docusaurus/module-type-aliases': 3.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/theme-common': 3.10.0(@docusaurus/plugin-content-docs@3.10.0(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3))(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/types': 3.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/utils-validation': 3.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - mermaid: 11.12.2 - react: 19.2.5 - react-dom: 19.2.5(react@19.2.5) + '@docusaurus/core': 3.10.1(@mdx-js/react@3.1.1(@types/react@19.2.15)(react@19.2.6))(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.3) + '@docusaurus/module-type-aliases': 3.10.1(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/theme-common': 3.10.1(@docusaurus/plugin-content-docs@3.10.1(@mdx-js/react@3.1.1(@types/react@19.2.15)(react@19.2.6))(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.3))(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/types': 3.10.1(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/utils-validation': 3.10.1(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + mermaid: 11.15.0 + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) tslib: 2.8.1 transitivePeerDependencies: - '@docusaurus/faster' - '@docusaurus/plugin-content-docs' - '@mdx-js/react' + - '@minify-html/node' - '@parcel/css' - '@rspack/core' - '@swc/core' - '@swc/css' + - '@swc/html' - bufferutil + - clean-css + - cssnano - csso - debug - esbuild + - html-minifier-terser - lightningcss + - postcss - supports-color - typescript - uglify-js - utf-8-validate - webpack-cli - '@docusaurus/theme-search-algolia@3.10.0(@algolia/client-search@5.46.0)(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(search-insights@2.17.3)(typescript@6.0.3)': + '@docusaurus/theme-search-algolia@3.10.1(@algolia/client-search@5.52.1)(@mdx-js/react@3.1.1(@types/react@19.2.15)(react@19.2.6))(@types/react@19.2.15)(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(search-insights@2.17.3)(typescript@6.0.3)': dependencies: - '@algolia/autocomplete-core': 1.19.2(@algolia/client-search@5.46.0)(algoliasearch@5.46.0)(search-insights@2.17.3) - '@docsearch/react': 4.3.2(@algolia/client-search@5.46.0)(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(search-insights@2.17.3) - '@docusaurus/core': 3.10.0(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3) - '@docusaurus/logger': 3.10.0 - '@docusaurus/plugin-content-docs': 3.10.0(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3) - '@docusaurus/theme-common': 3.10.0(@docusaurus/plugin-content-docs@3.10.0(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3))(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/theme-translations': 3.10.0 - '@docusaurus/utils': 3.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/utils-validation': 3.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - algoliasearch: 5.46.0 - algoliasearch-helper: 3.26.1(algoliasearch@5.46.0) + '@algolia/autocomplete-core': 1.19.8(@algolia/client-search@5.52.1)(algoliasearch@5.52.1)(search-insights@2.17.3) + '@docsearch/react': 4.6.3(@algolia/client-search@5.52.1)(@types/react@19.2.15)(algoliasearch@5.52.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(search-insights@2.17.3) + '@docusaurus/core': 3.10.1(@mdx-js/react@3.1.1(@types/react@19.2.15)(react@19.2.6))(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.3) + '@docusaurus/logger': 3.10.1 + '@docusaurus/plugin-content-docs': 3.10.1(@mdx-js/react@3.1.1(@types/react@19.2.15)(react@19.2.6))(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.3) + '@docusaurus/theme-common': 3.10.1(@docusaurus/plugin-content-docs@3.10.1(@mdx-js/react@3.1.1(@types/react@19.2.15)(react@19.2.6))(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.3))(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/theme-translations': 3.10.1 + '@docusaurus/utils': 3.10.1(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/utils-validation': 3.10.1(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + algoliasearch: 5.52.1 + algoliasearch-helper: 3.29.1(algoliasearch@5.52.1) clsx: 2.1.1 eta: 2.2.0 - fs-extra: 11.3.4 + fs-extra: 11.3.5 lodash: 4.18.1 - react: 19.2.5 - react-dom: 19.2.5(react@19.2.5) + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) tslib: 2.8.1 utility-types: 3.11.0 transitivePeerDependencies: - '@algolia/client-search' - '@docusaurus/faster' - '@mdx-js/react' + - '@minify-html/node' - '@parcel/css' - '@rspack/core' - '@swc/core' - '@swc/css' + - '@swc/html' - '@types/react' - bufferutil + - clean-css + - cssnano - csso - debug - esbuild + - html-minifier-terser - lightningcss + - postcss - search-insights - supports-color - typescript @@ -14990,75 +15285,154 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/theme-translations@3.10.0': + '@docusaurus/theme-translations@3.10.1': dependencies: - fs-extra: 11.3.4 + fs-extra: 11.3.5 tslib: 2.8.1 - '@docusaurus/tsconfig@3.10.0': {} + '@docusaurus/tsconfig@3.10.1': {} - '@docusaurus/types@3.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + '@docusaurus/types@3.10.1(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.15))(html-minifier-terser@7.2.0)(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': dependencies: '@mdx-js/mdx': 3.1.1 '@types/history': 4.7.11 '@types/mdast': 4.0.4 - '@types/react': 19.2.14 + '@types/react': 19.2.15 commander: 5.1.0 joi: 17.13.3 - react: 19.2.5 - react-dom: 19.2.5(react@19.2.5) - react-helmet-async: '@slorber/react-helmet-async@1.3.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5)' + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + react-helmet-async: '@slorber/react-helmet-async@1.3.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6)' utility-types: 3.11.0 - webpack: 5.106.2 + webpack: 5.107.0(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.15))(html-minifier-terser@7.2.0)(postcss@8.5.15) webpack-merge: 5.10.0 transitivePeerDependencies: + - '@minify-html/node' - '@swc/core' + - '@swc/css' + - '@swc/html' + - clean-css + - cssnano + - csso - esbuild + - html-minifier-terser + - lightningcss + - postcss - supports-color - uglify-js - webpack-cli - '@docusaurus/utils-common@3.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + '@docusaurus/types@3.10.1(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': dependencies: - '@docusaurus/types': 3.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@mdx-js/mdx': 3.1.1 + '@types/history': 4.7.11 + '@types/mdast': 4.0.4 + '@types/react': 19.2.15 + commander: 5.1.0 + joi: 17.13.3 + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + react-helmet-async: '@slorber/react-helmet-async@1.3.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6)' + utility-types: 3.11.0 + webpack: 5.107.0(postcss@8.5.15) + webpack-merge: 5.10.0 + transitivePeerDependencies: + - '@minify-html/node' + - '@swc/core' + - '@swc/css' + - '@swc/html' + - clean-css + - cssnano + - csso + - esbuild + - html-minifier-terser + - lightningcss + - postcss + - supports-color + - uglify-js + - webpack-cli + + '@docusaurus/utils-common@3.10.1(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.15))(html-minifier-terser@7.2.0)(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + dependencies: + '@docusaurus/types': 3.10.1(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.15))(html-minifier-terser@7.2.0)(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) tslib: 2.8.1 transitivePeerDependencies: + - '@minify-html/node' - '@swc/core' + - '@swc/css' + - '@swc/html' + - clean-css + - cssnano + - csso - esbuild + - html-minifier-terser + - lightningcss + - postcss - react - react-dom - supports-color - uglify-js - webpack-cli - '@docusaurus/utils-validation@3.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + '@docusaurus/utils-common@3.10.1(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': dependencies: - '@docusaurus/logger': 3.10.0 - '@docusaurus/utils': 3.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/utils-common': 3.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - fs-extra: 11.3.4 + '@docusaurus/types': 3.10.1(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + tslib: 2.8.1 + transitivePeerDependencies: + - '@minify-html/node' + - '@swc/core' + - '@swc/css' + - '@swc/html' + - clean-css + - cssnano + - csso + - esbuild + - html-minifier-terser + - lightningcss + - postcss + - react + - react-dom + - supports-color + - uglify-js + - webpack-cli + + '@docusaurus/utils-validation@3.10.1(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + dependencies: + '@docusaurus/logger': 3.10.1 + '@docusaurus/utils': 3.10.1(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/utils-common': 3.10.1(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + fs-extra: 11.3.5 joi: 17.13.3 js-yaml: 4.1.1 lodash: 4.18.1 tslib: 2.8.1 transitivePeerDependencies: + - '@minify-html/node' - '@swc/core' + - '@swc/css' + - '@swc/html' + - clean-css + - cssnano + - csso - esbuild + - html-minifier-terser + - lightningcss + - postcss - react - react-dom - supports-color - uglify-js - webpack-cli - '@docusaurus/utils@3.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + '@docusaurus/utils@3.10.1(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.15))(html-minifier-terser@7.2.0)(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': dependencies: - '@docusaurus/logger': 3.10.0 - '@docusaurus/types': 3.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/utils-common': 3.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@docusaurus/logger': 3.10.1 + '@docusaurus/types': 3.10.1(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.15))(html-minifier-terser@7.2.0)(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/utils-common': 3.10.1(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.15))(html-minifier-terser@7.2.0)(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) escape-string-regexp: 4.0.0 execa: 5.1.1 - file-loader: 6.2.0(webpack@5.106.2) - fs-extra: 11.3.4 + file-loader: 6.2.0(webpack@5.107.0(postcss@8.5.15)) + fs-extra: 11.3.5 github-slugger: 1.5.0 globby: 11.1.0 gray-matter: 4.0.3 @@ -15070,12 +15444,62 @@ snapshots: prompts: 2.4.2 resolve-pathname: 3.0.0 tslib: 2.8.1 - url-loader: 4.1.1(file-loader@6.2.0(webpack@5.106.2))(webpack@5.106.2) + url-loader: 4.1.1(file-loader@6.2.0(webpack@5.107.0(postcss@8.5.15)))(webpack@5.107.0(postcss@8.5.15)) utility-types: 3.11.0 - webpack: 5.106.2 + webpack: 5.107.0(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.15))(html-minifier-terser@7.2.0)(postcss@8.5.15) transitivePeerDependencies: + - '@minify-html/node' - '@swc/core' + - '@swc/css' + - '@swc/html' + - clean-css + - cssnano + - csso - esbuild + - html-minifier-terser + - lightningcss + - postcss + - react + - react-dom + - supports-color + - uglify-js + - webpack-cli + + '@docusaurus/utils@3.10.1(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + dependencies: + '@docusaurus/logger': 3.10.1 + '@docusaurus/types': 3.10.1(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/utils-common': 3.10.1(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + escape-string-regexp: 4.0.0 + execa: 5.1.1 + file-loader: 6.2.0(webpack@5.107.0(postcss@8.5.15)) + fs-extra: 11.3.5 + github-slugger: 1.5.0 + globby: 11.1.0 + gray-matter: 4.0.3 + jiti: 1.21.7 + js-yaml: 4.1.1 + lodash: 4.18.1 + micromatch: 4.0.8 + p-queue: 6.6.2 + prompts: 2.4.2 + resolve-pathname: 3.0.0 + tslib: 2.8.1 + url-loader: 4.1.1(file-loader@6.2.0(webpack@5.107.0(postcss@8.5.15)))(webpack@5.107.0(postcss@8.5.15)) + utility-types: 3.11.0 + webpack: 5.107.0(postcss@8.5.15) + transitivePeerDependencies: + - '@minify-html/node' + - '@swc/core' + - '@swc/css' + - '@swc/html' + - clean-css + - cssnano + - csso + - esbuild + - html-minifier-terser + - lightningcss + - postcss - react - react-dom - supports-color @@ -15104,6 +15528,9 @@ snapshots: '@esbuild/aix-ppc64@0.27.4': optional: true + '@esbuild/aix-ppc64@0.27.7': + optional: true + '@esbuild/aix-ppc64@0.28.0': optional: true @@ -15113,6 +15540,9 @@ snapshots: '@esbuild/android-arm64@0.27.4': optional: true + '@esbuild/android-arm64@0.27.7': + optional: true + '@esbuild/android-arm64@0.28.0': optional: true @@ -15122,6 +15552,9 @@ snapshots: '@esbuild/android-arm@0.27.4': optional: true + '@esbuild/android-arm@0.27.7': + optional: true + '@esbuild/android-arm@0.28.0': optional: true @@ -15131,6 +15564,9 @@ snapshots: '@esbuild/android-x64@0.27.4': optional: true + '@esbuild/android-x64@0.27.7': + optional: true + '@esbuild/android-x64@0.28.0': optional: true @@ -15140,6 +15576,9 @@ snapshots: '@esbuild/darwin-arm64@0.27.4': optional: true + '@esbuild/darwin-arm64@0.27.7': + optional: true + '@esbuild/darwin-arm64@0.28.0': optional: true @@ -15149,6 +15588,9 @@ snapshots: '@esbuild/darwin-x64@0.27.4': optional: true + '@esbuild/darwin-x64@0.27.7': + optional: true + '@esbuild/darwin-x64@0.28.0': optional: true @@ -15158,6 +15600,9 @@ snapshots: '@esbuild/freebsd-arm64@0.27.4': optional: true + '@esbuild/freebsd-arm64@0.27.7': + optional: true + '@esbuild/freebsd-arm64@0.28.0': optional: true @@ -15167,6 +15612,9 @@ snapshots: '@esbuild/freebsd-x64@0.27.4': optional: true + '@esbuild/freebsd-x64@0.27.7': + optional: true + '@esbuild/freebsd-x64@0.28.0': optional: true @@ -15176,6 +15624,9 @@ snapshots: '@esbuild/linux-arm64@0.27.4': optional: true + '@esbuild/linux-arm64@0.27.7': + optional: true + '@esbuild/linux-arm64@0.28.0': optional: true @@ -15185,6 +15636,9 @@ snapshots: '@esbuild/linux-arm@0.27.4': optional: true + '@esbuild/linux-arm@0.27.7': + optional: true + '@esbuild/linux-arm@0.28.0': optional: true @@ -15194,6 +15648,9 @@ snapshots: '@esbuild/linux-ia32@0.27.4': optional: true + '@esbuild/linux-ia32@0.27.7': + optional: true + '@esbuild/linux-ia32@0.28.0': optional: true @@ -15203,6 +15660,9 @@ snapshots: '@esbuild/linux-loong64@0.27.4': optional: true + '@esbuild/linux-loong64@0.27.7': + optional: true + '@esbuild/linux-loong64@0.28.0': optional: true @@ -15212,6 +15672,9 @@ snapshots: '@esbuild/linux-mips64el@0.27.4': optional: true + '@esbuild/linux-mips64el@0.27.7': + optional: true + '@esbuild/linux-mips64el@0.28.0': optional: true @@ -15221,6 +15684,9 @@ snapshots: '@esbuild/linux-ppc64@0.27.4': optional: true + '@esbuild/linux-ppc64@0.27.7': + optional: true + '@esbuild/linux-ppc64@0.28.0': optional: true @@ -15230,6 +15696,9 @@ snapshots: '@esbuild/linux-riscv64@0.27.4': optional: true + '@esbuild/linux-riscv64@0.27.7': + optional: true + '@esbuild/linux-riscv64@0.28.0': optional: true @@ -15239,6 +15708,9 @@ snapshots: '@esbuild/linux-s390x@0.27.4': optional: true + '@esbuild/linux-s390x@0.27.7': + optional: true + '@esbuild/linux-s390x@0.28.0': optional: true @@ -15248,12 +15720,18 @@ snapshots: '@esbuild/linux-x64@0.27.4': optional: true + '@esbuild/linux-x64@0.27.7': + optional: true + '@esbuild/linux-x64@0.28.0': optional: true '@esbuild/netbsd-arm64@0.27.4': optional: true + '@esbuild/netbsd-arm64@0.27.7': + optional: true + '@esbuild/netbsd-arm64@0.28.0': optional: true @@ -15263,12 +15741,18 @@ snapshots: '@esbuild/netbsd-x64@0.27.4': optional: true + '@esbuild/netbsd-x64@0.27.7': + optional: true + '@esbuild/netbsd-x64@0.28.0': optional: true '@esbuild/openbsd-arm64@0.27.4': optional: true + '@esbuild/openbsd-arm64@0.27.7': + optional: true + '@esbuild/openbsd-arm64@0.28.0': optional: true @@ -15278,12 +15762,18 @@ snapshots: '@esbuild/openbsd-x64@0.27.4': optional: true + '@esbuild/openbsd-x64@0.27.7': + optional: true + '@esbuild/openbsd-x64@0.28.0': optional: true '@esbuild/openharmony-arm64@0.27.4': optional: true + '@esbuild/openharmony-arm64@0.27.7': + optional: true + '@esbuild/openharmony-arm64@0.28.0': optional: true @@ -15293,6 +15783,9 @@ snapshots: '@esbuild/sunos-x64@0.27.4': optional: true + '@esbuild/sunos-x64@0.27.7': + optional: true + '@esbuild/sunos-x64@0.28.0': optional: true @@ -15302,6 +15795,9 @@ snapshots: '@esbuild/win32-arm64@0.27.4': optional: true + '@esbuild/win32-arm64@0.27.7': + optional: true + '@esbuild/win32-arm64@0.28.0': optional: true @@ -15311,6 +15807,9 @@ snapshots: '@esbuild/win32-ia32@0.27.4': optional: true + '@esbuild/win32-ia32@0.27.7': + optional: true + '@esbuild/win32-ia32@0.28.0': optional: true @@ -15320,12 +15819,15 @@ snapshots: '@esbuild/win32-x64@0.27.4': optional: true + '@esbuild/win32-x64@0.27.7': + optional: true + '@esbuild/win32-x64@0.28.0': optional: true - '@eslint-community/eslint-utils@4.9.1(eslint@10.2.1(jiti@2.6.1))': + '@eslint-community/eslint-utils@4.9.1(eslint@10.4.0(jiti@2.7.0))': dependencies: - eslint: 10.2.1(jiti@2.6.1) + eslint: 10.4.0(jiti@2.7.0) eslint-visitor-keys: 3.4.3 '@eslint-community/regexpp@4.12.2': {} @@ -15338,7 +15840,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@eslint/config-helpers@0.5.5': + '@eslint/config-helpers@0.6.0': dependencies: '@eslint/core': 1.2.1 @@ -15346,14 +15848,14 @@ snapshots: dependencies: '@types/json-schema': 7.0.15 - '@eslint/css-tree@4.0.2': + '@eslint/css-tree@4.0.3': dependencies: - mdn-data: 2.27.1 + mdn-data: 2.28.0 source-map-js: 1.2.1 - '@eslint/js@10.0.1(eslint@10.2.1(jiti@2.6.1))': + '@eslint/js@10.0.1(eslint@10.4.0(jiti@2.7.0))': optionalDependencies: - eslint: 10.2.1(jiti@2.6.1) + eslint: 10.4.0(jiti@2.7.0) '@eslint/object-schema@3.0.5': {} @@ -15397,7 +15899,7 @@ snapshots: dependencies: tslib: 2.8.1 - '@formatjs/fast-memoize@3.1.2': {} + '@formatjs/fast-memoize@3.1.5': {} '@formatjs/icu-messageformat-parser@2.11.4': dependencies: @@ -15405,16 +15907,16 @@ snapshots: '@formatjs/icu-skeleton-parser': 1.8.16 tslib: 2.8.1 - '@formatjs/icu-messageformat-parser@3.5.4': + '@formatjs/icu-messageformat-parser@3.5.9': dependencies: - '@formatjs/icu-skeleton-parser': 2.1.4 + '@formatjs/icu-skeleton-parser': 2.1.9 '@formatjs/icu-skeleton-parser@1.8.16': dependencies: '@formatjs/ecma402-abstract': 2.3.6 tslib: 2.8.1 - '@formatjs/icu-skeleton-parser@2.1.4': {} + '@formatjs/icu-skeleton-parser@2.1.9': {} '@formatjs/intl-localematcher@0.6.2': dependencies: @@ -15434,12 +15936,12 @@ snapshots: dependencies: '@oazapfts/runtime': 1.2.0 - '@futo-org/backups-orchestrator-api@0.1.73(@nestjs/platform-express@11.1.19)(class-transformer@0.5.1)(reflect-metadata@0.2.2)': + '@futo-org/backups-orchestrator-api@0.1.73(@nestjs/platform-express@11.1.21)(class-transformer@0.5.1)(reflect-metadata@0.2.2)': dependencies: '@futo-org/backups-api-client': 0.1.73 '@futo-org/restic-wrapper': 1.2.1 '@nestjs/common': 11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.19)(@nestjs/websockets@11.1.19)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.21)(@nestjs/websockets@11.1.19)(reflect-metadata@0.2.2)(rxjs@7.8.2) '@nestjs/event-emitter': 3.1.0(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19) '@nestjs/platform-socket.io': 11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/websockets@11.1.19)(rxjs@7.8.2) '@nestjs/schedule': 6.1.3(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19) @@ -15453,7 +15955,7 @@ snapshots: express: 5.2.1 kysely: 0.28.2 nestjs-kysely: 3.1.2(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19)(kysely@0.28.2)(reflect-metadata@0.2.2) - openid-client: 6.8.3 + openid-client: 6.8.4 rxjs: 7.8.2 socket.io: 4.8.3 tail: 2.2.6 @@ -15466,38 +15968,19 @@ snapshots: - supports-color - utf-8-validate - '@futo-org/backups-orchestrator-ui@0.1.73(@sveltejs/kit@2.57.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.55.8)(vite@8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)))(svelte@5.55.8)(typescript@6.0.3)(vite@8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)))(svelte@5.55.8)': + '@futo-org/backups-orchestrator-ui@0.1.73(@sveltejs/kit@2.60.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.1.2(svelte@5.55.8(@typescript-eslint/types@8.59.4))(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0)))(svelte@5.55.8(@typescript-eslint/types@8.59.4))(typescript@6.0.3)(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0)))(svelte@5.55.8(@typescript-eslint/types@8.59.4))': dependencies: '@futo-org/backups-api-client': 0.1.73 - '@immich/ui': 0.59.0(@sveltejs/kit@2.57.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.55.8)(vite@8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)))(svelte@5.55.8)(typescript@6.0.3)(vite@8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)))(svelte@5.55.8) + '@immich/ui': 0.59.0(@sveltejs/kit@2.60.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.1.2(svelte@5.55.8(@typescript-eslint/types@8.59.4))(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0)))(svelte@5.55.8(@typescript-eslint/types@8.59.4))(typescript@6.0.3)(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0)))(svelte@5.55.8(@typescript-eslint/types@8.59.4)) '@mdi/js': 7.4.47 '@oazapfts/runtime': 1.2.0 - '@tanstack/svelte-query': 6.1.28(svelte@5.55.8) + '@tanstack/svelte-query': 6.1.28(svelte@5.55.8(@typescript-eslint/types@8.59.4)) cron-validate: 1.5.3 cronstrue: 3.14.0 lodash.debounce: 4.0.8 luxon: 3.7.2 socket.io-client: 4.8.3 - svelte: 5.55.8 - transitivePeerDependencies: - - '@sveltejs/kit' - - bufferutil - - supports-color - - utf-8-validate - - '@futo-org/backups-orchestrator-ui@0.1.73(svelte@5.55.8)': - dependencies: - '@futo-org/backups-api-client': 0.1.73 - '@immich/ui': 0.59.0(svelte@5.55.8) - '@mdi/js': 7.4.47 - '@oazapfts/runtime': 1.2.0 - '@tanstack/svelte-query': 6.1.28(svelte@5.55.8) - cron-validate: 1.5.3 - cronstrue: 3.14.0 - lodash.debounce: 4.0.8 - luxon: 3.7.2 - socket.io-client: 4.8.3 - svelte: 5.55.8 + svelte: 5.55.8(@typescript-eslint/types@8.59.4) transitivePeerDependencies: - '@sveltejs/kit' - bufferutil @@ -15508,29 +15991,29 @@ snapshots: dependencies: zod: 4.3.6 - '@golevelup/nestjs-discovery@5.0.0(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19)': + '@golevelup/nestjs-discovery@5.0.0(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21)': dependencies: - '@nestjs/common': 11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.19)(@nestjs/websockets@11.1.19)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.21(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.21)(@nestjs/websockets@11.1.21)(reflect-metadata@0.2.2)(rxjs@7.8.2) lodash: 4.18.1 '@grpc/grpc-js@1.14.3': dependencies: - '@grpc/proto-loader': 0.8.0 + '@grpc/proto-loader': 0.8.1 '@js-sdsl/ordered-map': 4.4.2 '@grpc/proto-loader@0.7.15': dependencies: lodash.camelcase: 4.3.0 long: 5.3.2 - protobufjs: 7.5.5 + protobufjs: 7.6.0 yargs: 17.7.2 - '@grpc/proto-loader@0.8.0': + '@grpc/proto-loader@0.8.1': dependencies: lodash.camelcase: 4.3.0 long: 5.3.2 - protobufjs: 7.5.5 + protobufjs: 7.6.0 yargs: 17.7.2 '@hapi/hoek@9.3.0': {} @@ -15557,13 +16040,13 @@ snapshots: '@iconify/types@2.0.0': {} - '@iconify/utils@3.1.0': + '@iconify/utils@3.1.3': dependencies: '@antfu/install-pkg': 1.1.0 '@iconify/types': 2.0.0 - mlly: 1.8.0 + import-meta-resolve: 4.2.0 - '@img/colour@1.0.0': {} + '@img/colour@1.1.0': {} '@img/sharp-darwin-arm64@0.34.5': optionalDependencies: @@ -15667,202 +16150,186 @@ snapshots: graph-data-structure: 4.5.0 kysely: 0.28.17 kysely-postgres-js: 3.0.0(kysely@0.28.17)(postgres@3.4.9) - pg-connection-string: 2.12.0 + pg-connection-string: 2.13.0 postgres: 3.4.9 - '@immich/svelte-markdown-preprocess@0.1.0(svelte@5.55.8)': + '@immich/svelte-markdown-preprocess@0.1.0(svelte@5.55.8(@typescript-eslint/types@8.59.4))': dependencies: - svelte: 5.55.8 + svelte: 5.55.8(@typescript-eslint/types@8.59.4) - '@immich/ui@0.59.0(@sveltejs/kit@2.57.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.55.8)(vite@8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)))(svelte@5.55.8)(typescript@6.0.3)(vite@8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)))(svelte@5.55.8)': + '@immich/ui@0.59.0(@sveltejs/kit@2.60.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.1.2(svelte@5.55.8(@typescript-eslint/types@8.59.4))(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0)))(svelte@5.55.8(@typescript-eslint/types@8.59.4))(typescript@6.0.3)(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0)))(svelte@5.55.8(@typescript-eslint/types@8.59.4))': dependencies: - '@immich/svelte-markdown-preprocess': 0.1.0(svelte@5.55.8) + '@immich/svelte-markdown-preprocess': 0.1.0(svelte@5.55.8(@typescript-eslint/types@8.59.4)) '@internationalized/date': 3.12.1 '@mdi/js': 7.4.47 - bits-ui: 2.18.0(@internationalized/date@3.12.1)(@sveltejs/kit@2.57.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.55.8)(vite@8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)))(svelte@5.55.8)(typescript@6.0.3)(vite@8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)))(svelte@5.55.8) + bits-ui: 2.18.0(@internationalized/date@3.12.1)(@sveltejs/kit@2.60.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.1.2(svelte@5.55.8(@typescript-eslint/types@8.59.4))(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0)))(svelte@5.55.8(@typescript-eslint/types@8.59.4))(typescript@6.0.3)(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0)))(svelte@5.55.8(@typescript-eslint/types@8.59.4)) luxon: 3.7.2 - simple-icons: 16.17.0 - svelte: 5.55.8 + simple-icons: 16.20.0 + svelte: 5.55.8(@typescript-eslint/types@8.59.4) svelte-highlight: 7.9.0 - tailwind-merge: 3.5.0 - tailwind-variants: 3.2.2(tailwind-merge@3.5.0)(tailwindcss@4.2.4) - tailwindcss: 4.2.4 + tailwind-merge: 3.6.0 + tailwind-variants: 3.2.2(tailwind-merge@3.6.0)(tailwindcss@4.3.0) + tailwindcss: 4.3.0 transitivePeerDependencies: - '@sveltejs/kit' - '@immich/ui@0.59.0(svelte@5.55.8)': - dependencies: - '@immich/svelte-markdown-preprocess': 0.1.0(svelte@5.55.8) - '@internationalized/date': 3.12.1 - '@mdi/js': 7.4.47 - bits-ui: 2.18.0(@internationalized/date@3.12.1)(svelte@5.55.8) - luxon: 3.7.2 - simple-icons: 16.17.0 - svelte: 5.55.8 - svelte-highlight: 7.9.0 - tailwind-merge: 3.5.0 - tailwind-variants: 3.2.2(tailwind-merge@3.5.0)(tailwindcss@4.2.4) - tailwindcss: 4.2.4 - transitivePeerDependencies: - - '@sveltejs/kit' - - '@immich/ui@0.77.3(@sveltejs/kit@2.57.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.55.8)(vite@8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)))(svelte@5.55.8)(typescript@6.0.3)(vite@8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)))(svelte@5.55.8)': + '@immich/ui@0.79.2(@sveltejs/kit@2.60.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.1.2(svelte@5.55.8(@typescript-eslint/types@8.59.4))(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0)))(svelte@5.55.8(@typescript-eslint/types@8.59.4))(typescript@6.0.3)(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0)))(svelte@5.55.8(@typescript-eslint/types@8.59.4))': dependencies: '@internationalized/date': 3.12.1 '@mdi/js': 7.4.47 - '@sveltejs/kit': 2.57.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.55.8)(vite@8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)))(svelte@5.55.8)(typescript@6.0.3)(vite@8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)) - bits-ui: 2.18.0(@internationalized/date@3.12.1)(@sveltejs/kit@2.57.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.55.8)(vite@8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)))(svelte@5.55.8)(typescript@6.0.3)(vite@8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)))(svelte@5.55.8) + '@sveltejs/kit': 2.60.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.1.2(svelte@5.55.8(@typescript-eslint/types@8.59.4))(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0)))(svelte@5.55.8(@typescript-eslint/types@8.59.4))(typescript@6.0.3)(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0)) + bits-ui: 2.18.1(@internationalized/date@3.12.1)(@sveltejs/kit@2.60.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.1.2(svelte@5.55.8(@typescript-eslint/types@8.59.4))(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0)))(svelte@5.55.8(@typescript-eslint/types@8.59.4))(typescript@6.0.3)(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0)))(svelte@5.55.8(@typescript-eslint/types@8.59.4)) luxon: 3.7.2 - simple-icons: 16.17.0 - svelte: 5.55.8 + simple-icons: 16.20.0 + svelte: 5.55.8(@typescript-eslint/types@8.59.4) svelte-highlight: 7.9.0 - tailwind-merge: 3.5.0 - tailwind-variants: 3.2.2(tailwind-merge@3.5.0)(tailwindcss@4.2.4) - tailwindcss: 4.2.4 + tailwind-merge: 3.6.0 + tailwind-variants: 3.2.2(tailwind-merge@3.6.0)(tailwindcss@4.3.0) + tailwindcss: 4.3.0 '@inquirer/ansi@1.0.2': {} - '@inquirer/checkbox@4.3.2(@types/node@24.12.2)': + '@inquirer/checkbox@4.3.2(@types/node@24.12.4)': dependencies: '@inquirer/ansi': 1.0.2 - '@inquirer/core': 10.3.2(@types/node@24.12.2) + '@inquirer/core': 10.3.2(@types/node@24.12.4) '@inquirer/figures': 1.0.15 - '@inquirer/type': 3.0.10(@types/node@24.12.2) + '@inquirer/type': 3.0.10(@types/node@24.12.4) yoctocolors-cjs: 2.1.3 optionalDependencies: - '@types/node': 24.12.2 + '@types/node': 24.12.4 - '@inquirer/confirm@5.1.21(@types/node@24.12.2)': + '@inquirer/confirm@5.1.21(@types/node@24.12.4)': dependencies: - '@inquirer/core': 10.3.2(@types/node@24.12.2) - '@inquirer/type': 3.0.10(@types/node@24.12.2) + '@inquirer/core': 10.3.2(@types/node@24.12.4) + '@inquirer/type': 3.0.10(@types/node@24.12.4) optionalDependencies: - '@types/node': 24.12.2 + '@types/node': 24.12.4 - '@inquirer/core@10.3.2(@types/node@24.12.2)': + '@inquirer/core@10.3.2(@types/node@24.12.4)': dependencies: '@inquirer/ansi': 1.0.2 '@inquirer/figures': 1.0.15 - '@inquirer/type': 3.0.10(@types/node@24.12.2) + '@inquirer/type': 3.0.10(@types/node@24.12.4) cli-width: 4.1.0 mute-stream: 2.0.0 signal-exit: 4.1.0 wrap-ansi: 6.2.0 yoctocolors-cjs: 2.1.3 optionalDependencies: - '@types/node': 24.12.2 + '@types/node': 24.12.4 - '@inquirer/editor@4.2.23(@types/node@24.12.2)': + '@inquirer/editor@4.2.23(@types/node@24.12.4)': dependencies: - '@inquirer/core': 10.3.2(@types/node@24.12.2) - '@inquirer/external-editor': 1.0.3(@types/node@24.12.2) - '@inquirer/type': 3.0.10(@types/node@24.12.2) + '@inquirer/core': 10.3.2(@types/node@24.12.4) + '@inquirer/external-editor': 1.0.3(@types/node@24.12.4) + '@inquirer/type': 3.0.10(@types/node@24.12.4) optionalDependencies: - '@types/node': 24.12.2 + '@types/node': 24.12.4 - '@inquirer/expand@4.0.23(@types/node@24.12.2)': + '@inquirer/expand@4.0.23(@types/node@24.12.4)': dependencies: - '@inquirer/core': 10.3.2(@types/node@24.12.2) - '@inquirer/type': 3.0.10(@types/node@24.12.2) + '@inquirer/core': 10.3.2(@types/node@24.12.4) + '@inquirer/type': 3.0.10(@types/node@24.12.4) yoctocolors-cjs: 2.1.3 optionalDependencies: - '@types/node': 24.12.2 + '@types/node': 24.12.4 - '@inquirer/external-editor@1.0.3(@types/node@24.12.2)': + '@inquirer/external-editor@1.0.3(@types/node@24.12.4)': dependencies: chardet: 2.1.1 iconv-lite: 0.7.2 optionalDependencies: - '@types/node': 24.12.2 + '@types/node': 24.12.4 '@inquirer/figures@1.0.15': {} - '@inquirer/input@4.3.1(@types/node@24.12.2)': + '@inquirer/input@4.3.1(@types/node@24.12.4)': dependencies: - '@inquirer/core': 10.3.2(@types/node@24.12.2) - '@inquirer/type': 3.0.10(@types/node@24.12.2) + '@inquirer/core': 10.3.2(@types/node@24.12.4) + '@inquirer/type': 3.0.10(@types/node@24.12.4) optionalDependencies: - '@types/node': 24.12.2 + '@types/node': 24.12.4 - '@inquirer/number@3.0.23(@types/node@24.12.2)': + '@inquirer/number@3.0.23(@types/node@24.12.4)': dependencies: - '@inquirer/core': 10.3.2(@types/node@24.12.2) - '@inquirer/type': 3.0.10(@types/node@24.12.2) + '@inquirer/core': 10.3.2(@types/node@24.12.4) + '@inquirer/type': 3.0.10(@types/node@24.12.4) optionalDependencies: - '@types/node': 24.12.2 + '@types/node': 24.12.4 - '@inquirer/password@4.0.23(@types/node@24.12.2)': + '@inquirer/password@4.0.23(@types/node@24.12.4)': dependencies: '@inquirer/ansi': 1.0.2 - '@inquirer/core': 10.3.2(@types/node@24.12.2) - '@inquirer/type': 3.0.10(@types/node@24.12.2) + '@inquirer/core': 10.3.2(@types/node@24.12.4) + '@inquirer/type': 3.0.10(@types/node@24.12.4) optionalDependencies: - '@types/node': 24.12.2 + '@types/node': 24.12.4 - '@inquirer/prompts@7.10.1(@types/node@24.12.2)': + '@inquirer/prompts@7.10.1(@types/node@24.12.4)': dependencies: - '@inquirer/checkbox': 4.3.2(@types/node@24.12.2) - '@inquirer/confirm': 5.1.21(@types/node@24.12.2) - '@inquirer/editor': 4.2.23(@types/node@24.12.2) - '@inquirer/expand': 4.0.23(@types/node@24.12.2) - '@inquirer/input': 4.3.1(@types/node@24.12.2) - '@inquirer/number': 3.0.23(@types/node@24.12.2) - '@inquirer/password': 4.0.23(@types/node@24.12.2) - '@inquirer/rawlist': 4.1.11(@types/node@24.12.2) - '@inquirer/search': 3.2.2(@types/node@24.12.2) - '@inquirer/select': 4.4.2(@types/node@24.12.2) + '@inquirer/checkbox': 4.3.2(@types/node@24.12.4) + '@inquirer/confirm': 5.1.21(@types/node@24.12.4) + '@inquirer/editor': 4.2.23(@types/node@24.12.4) + '@inquirer/expand': 4.0.23(@types/node@24.12.4) + '@inquirer/input': 4.3.1(@types/node@24.12.4) + '@inquirer/number': 3.0.23(@types/node@24.12.4) + '@inquirer/password': 4.0.23(@types/node@24.12.4) + '@inquirer/rawlist': 4.1.11(@types/node@24.12.4) + '@inquirer/search': 3.2.2(@types/node@24.12.4) + '@inquirer/select': 4.4.2(@types/node@24.12.4) optionalDependencies: - '@types/node': 24.12.2 + '@types/node': 24.12.4 - '@inquirer/prompts@7.3.2(@types/node@24.12.2)': + '@inquirer/prompts@7.3.2(@types/node@24.12.4)': dependencies: - '@inquirer/checkbox': 4.3.2(@types/node@24.12.2) - '@inquirer/confirm': 5.1.21(@types/node@24.12.2) - '@inquirer/editor': 4.2.23(@types/node@24.12.2) - '@inquirer/expand': 4.0.23(@types/node@24.12.2) - '@inquirer/input': 4.3.1(@types/node@24.12.2) - '@inquirer/number': 3.0.23(@types/node@24.12.2) - '@inquirer/password': 4.0.23(@types/node@24.12.2) - '@inquirer/rawlist': 4.1.11(@types/node@24.12.2) - '@inquirer/search': 3.2.2(@types/node@24.12.2) - '@inquirer/select': 4.4.2(@types/node@24.12.2) + '@inquirer/checkbox': 4.3.2(@types/node@24.12.4) + '@inquirer/confirm': 5.1.21(@types/node@24.12.4) + '@inquirer/editor': 4.2.23(@types/node@24.12.4) + '@inquirer/expand': 4.0.23(@types/node@24.12.4) + '@inquirer/input': 4.3.1(@types/node@24.12.4) + '@inquirer/number': 3.0.23(@types/node@24.12.4) + '@inquirer/password': 4.0.23(@types/node@24.12.4) + '@inquirer/rawlist': 4.1.11(@types/node@24.12.4) + '@inquirer/search': 3.2.2(@types/node@24.12.4) + '@inquirer/select': 4.4.2(@types/node@24.12.4) optionalDependencies: - '@types/node': 24.12.2 + '@types/node': 24.12.4 - '@inquirer/rawlist@4.1.11(@types/node@24.12.2)': + '@inquirer/rawlist@4.1.11(@types/node@24.12.4)': dependencies: - '@inquirer/core': 10.3.2(@types/node@24.12.2) - '@inquirer/type': 3.0.10(@types/node@24.12.2) + '@inquirer/core': 10.3.2(@types/node@24.12.4) + '@inquirer/type': 3.0.10(@types/node@24.12.4) yoctocolors-cjs: 2.1.3 optionalDependencies: - '@types/node': 24.12.2 + '@types/node': 24.12.4 - '@inquirer/search@3.2.2(@types/node@24.12.2)': + '@inquirer/search@3.2.2(@types/node@24.12.4)': dependencies: - '@inquirer/core': 10.3.2(@types/node@24.12.2) + '@inquirer/core': 10.3.2(@types/node@24.12.4) '@inquirer/figures': 1.0.15 - '@inquirer/type': 3.0.10(@types/node@24.12.2) + '@inquirer/type': 3.0.10(@types/node@24.12.4) yoctocolors-cjs: 2.1.3 optionalDependencies: - '@types/node': 24.12.2 + '@types/node': 24.12.4 - '@inquirer/select@4.4.2(@types/node@24.12.2)': + '@inquirer/select@4.4.2(@types/node@24.12.4)': dependencies: '@inquirer/ansi': 1.0.2 - '@inquirer/core': 10.3.2(@types/node@24.12.2) + '@inquirer/core': 10.3.2(@types/node@24.12.4) '@inquirer/figures': 1.0.15 - '@inquirer/type': 3.0.10(@types/node@24.12.2) + '@inquirer/type': 3.0.10(@types/node@24.12.4) yoctocolors-cjs: 2.1.3 optionalDependencies: - '@types/node': 24.12.2 + '@types/node': 24.12.4 - '@inquirer/type@3.0.10(@types/node@24.12.2)': + '@inquirer/type@3.0.10(@types/node@24.12.4)': optionalDependencies: - '@types/node': 24.12.2 + '@types/node': 24.12.4 '@internationalized/date@3.12.1': dependencies: - '@swc/helpers': 0.5.21 + '@swc/helpers': 0.5.22 '@ioredis/commands@1.5.1': {} @@ -15883,14 +16350,14 @@ snapshots: '@jest/schemas@29.6.3': dependencies: - '@sinclair/typebox': 0.27.8 + '@sinclair/typebox': 0.27.10 '@jest/types@29.6.3': dependencies: '@jest/schemas': 29.6.3 '@types/istanbul-lib-coverage': 2.0.6 '@types/istanbul-reports': 3.0.4 - '@types/node': 24.12.2 + '@types/node': 24.12.4 '@types/yargs': 17.0.35 chalk: 4.1.2 @@ -15956,7 +16423,7 @@ snapshots: dependencies: '@jsonjoy.com/fs-node-builtins': 4.57.2(tslib@2.8.1) '@jsonjoy.com/fs-node-utils': 4.57.2(tslib@2.8.1) - thingies: 2.5.0(tslib@2.8.1) + thingies: 2.6.0(tslib@2.8.1) tslib: 2.8.1 '@jsonjoy.com/fs-fsa@4.57.2(tslib@2.8.1)': @@ -15964,7 +16431,7 @@ snapshots: '@jsonjoy.com/fs-core': 4.57.2(tslib@2.8.1) '@jsonjoy.com/fs-node-builtins': 4.57.2(tslib@2.8.1) '@jsonjoy.com/fs-node-utils': 4.57.2(tslib@2.8.1) - thingies: 2.5.0(tslib@2.8.1) + thingies: 2.6.0(tslib@2.8.1) tslib: 2.8.1 '@jsonjoy.com/fs-node-builtins@4.57.2(tslib@2.8.1)': @@ -15991,7 +16458,7 @@ snapshots: '@jsonjoy.com/fs-print': 4.57.2(tslib@2.8.1) '@jsonjoy.com/fs-snapshot': 4.57.2(tslib@2.8.1) glob-to-regex.js: 1.2.0(tslib@2.8.1) - thingies: 2.5.0(tslib@2.8.1) + thingies: 2.6.0(tslib@2.8.1) tslib: 2.8.1 '@jsonjoy.com/fs-print@4.57.2(tslib@2.8.1)': @@ -16016,7 +16483,7 @@ snapshots: '@jsonjoy.com/json-pointer': 1.0.2(tslib@2.8.1) '@jsonjoy.com/util': 1.9.0(tslib@2.8.1) hyperdyperid: 1.2.0 - thingies: 2.5.0(tslib@2.8.1) + thingies: 2.6.0(tslib@2.8.1) tree-dump: 1.1.0(tslib@2.8.1) tslib: 2.8.1 @@ -16028,7 +16495,7 @@ snapshots: '@jsonjoy.com/json-pointer': 17.67.0(tslib@2.8.1) '@jsonjoy.com/util': 17.67.0(tslib@2.8.1) hyperdyperid: 1.2.0 - thingies: 2.5.0(tslib@2.8.1) + thingies: 2.6.0(tslib@2.8.1) tree-dump: 1.1.0(tslib@2.8.1) tslib: 2.8.1 @@ -16061,7 +16528,7 @@ snapshots: dependencies: vary: 1.1.2 - '@koa/router@15.4.0(koa@3.2.0)': + '@koa/router@15.5.0(koa@3.2.0)': dependencies: debug: 4.4.3 http-errors: 2.0.1 @@ -16071,11 +16538,11 @@ snapshots: transitivePeerDependencies: - supports-color - '@koddsson/eslint-plugin-tscompat@0.2.0(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3)': + '@koddsson/eslint-plugin-tscompat@0.2.0(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3)': dependencies: '@mdn/browser-compat-data': 6.1.5 - '@typescript-eslint/type-utils': 8.59.0(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3) - '@typescript-eslint/utils': 8.59.0(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3) + '@typescript-eslint/type-utils': 8.59.4(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3) + '@typescript-eslint/utils': 8.59.4(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3) browserslist: 4.28.2 transitivePeerDependencies: - eslint @@ -16112,16 +16579,16 @@ snapshots: '@mapbox/mapbox-gl-rtl-text@0.4.0': {} - '@mapbox/node-pre-gyp@1.0.11(encoding@0.1.13)': + '@mapbox/node-pre-gyp@1.0.11': dependencies: detect-libc: 2.1.2 https-proxy-agent: 5.0.1 make-dir: 3.1.0 - node-fetch: 2.7.0(encoding@0.1.13) + node-fetch: 2.7.0 nopt: 5.0.0 npmlog: 5.0.1 rimraf: 3.0.2 - semver: 7.7.4 + semver: 7.8.0 tar: 6.2.1 transitivePeerDependencies: - encoding @@ -16129,7 +16596,7 @@ snapshots: '@mapbox/point-geometry@1.1.0': {} - '@mapbox/tiny-sdf@2.1.0': {} + '@mapbox/tiny-sdf@2.2.0': {} '@mapbox/unitbezier@0.0.1': {} @@ -16145,16 +16612,15 @@ snapshots: '@maplibre/geojson-vt@6.1.0': dependencies: - kdbush: 4.0.2 + kdbush: 4.1.0 - '@maplibre/maplibre-gl-style-spec@24.8.1': + '@maplibre/maplibre-gl-style-spec@24.8.5': dependencies: '@mapbox/jsonlint-lines-primitives': 2.0.2 '@mapbox/unitbezier': 0.0.1 json-stringify-pretty-compact: 4.0.0 minimist: 1.2.8 quickselect: 3.0.0 - rw: 1.3.3 tinyqueue: 3.0.0 '@maplibre/mlt@1.1.9': @@ -16185,7 +16651,7 @@ snapshots: '@mdx-js/mdx@3.1.1': dependencies: - '@types/estree': 1.0.8 + '@types/estree': 1.0.9 '@types/estree-jsx': 1.0.5 '@types/hast': 3.0.4 '@types/mdx': 2.0.13 @@ -16208,20 +16674,20 @@ snapshots: unified: 11.0.5 unist-util-position-from-estree: 2.0.0 unist-util-stringify-position: 4.0.0 - unist-util-visit: 5.0.0 + unist-util-visit: 5.1.0 vfile: 6.0.3 transitivePeerDependencies: - supports-color - '@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5)': + '@mdx-js/react@3.1.1(@types/react@19.2.15)(react@19.2.6)': dependencies: '@types/mdx': 2.0.13 - '@types/react': 19.2.14 - react: 19.2.5 + '@types/react': 19.2.15 + react: 19.2.6 - '@mermaid-js/parser@0.6.3': + '@mermaid-js/parser@1.1.1': dependencies: - langium: 3.3.1 + '@chevrotain/types': 11.1.2 '@microsoft/tsdoc@0.16.0': {} @@ -16249,48 +16715,57 @@ snapshots: dependencies: '@emnapi/core': 1.10.0 '@emnapi/runtime': 1.10.0 - '@tybys/wasm-util': 0.10.1 + '@tybys/wasm-util': 0.10.2 optional: true - '@nestjs/bull-shared@11.0.4(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19)': + '@nestjs/bull-shared@11.0.4(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21)': dependencies: - '@nestjs/common': 11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.19)(@nestjs/websockets@11.1.19)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.21(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.21)(@nestjs/websockets@11.1.21)(reflect-metadata@0.2.2)(rxjs@7.8.2) tslib: 2.8.1 - '@nestjs/bullmq@11.0.4(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19)(bullmq@5.76.1)': + '@nestjs/bullmq@11.0.4(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21)(bullmq@5.76.10)': dependencies: - '@nestjs/bull-shared': 11.0.4(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19) - '@nestjs/common': 11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.19)(@nestjs/websockets@11.1.19)(reflect-metadata@0.2.2)(rxjs@7.8.2) - bullmq: 5.76.1 + '@nestjs/bull-shared': 11.0.4(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21) + '@nestjs/common': 11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.21(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.21)(@nestjs/websockets@11.1.21)(reflect-metadata@0.2.2)(rxjs@7.8.2) + bullmq: 5.76.10 tslib: 2.8.1 - '@nestjs/cli@11.0.21(@swc/core@1.15.30(@swc/helpers@0.5.21))(@types/node@24.12.2)(esbuild@0.28.0)(prettier@3.8.3)': + '@nestjs/cli@11.0.21(@swc/core@1.15.33(@swc/helpers@0.5.22))(@types/node@24.12.4)(esbuild@0.28.0)(lightningcss@1.32.0)(prettier@3.8.3)': dependencies: '@angular-devkit/core': 19.2.24(chokidar@4.0.3) '@angular-devkit/schematics': 19.2.24(chokidar@4.0.3) - '@angular-devkit/schematics-cli': 19.2.24(@types/node@24.12.2)(chokidar@4.0.3) - '@inquirer/prompts': 7.10.1(@types/node@24.12.2) + '@angular-devkit/schematics-cli': 19.2.24(@types/node@24.12.4)(chokidar@4.0.3) + '@inquirer/prompts': 7.10.1(@types/node@24.12.4) '@nestjs/schematics': 11.1.0(chokidar@4.0.3)(prettier@3.8.3)(typescript@5.9.3) ansis: 4.2.0 chokidar: 4.0.3 cli-table3: 0.6.5 commander: 4.1.1 - fork-ts-checker-webpack-plugin: 9.1.0(typescript@5.9.3)(webpack@5.106.0(@swc/core@1.15.30(@swc/helpers@0.5.21))(esbuild@0.28.0)) + fork-ts-checker-webpack-plugin: 9.1.0(typescript@5.9.3)(webpack@5.106.0(@swc/core@1.15.33(@swc/helpers@0.5.22))(esbuild@0.28.0)(lightningcss@1.32.0)) glob: 13.0.6 node-emoji: 1.11.0 ora: 5.4.1 tsconfig-paths: 4.2.0 tsconfig-paths-webpack-plugin: 4.2.0 typescript: 5.9.3 - webpack: 5.106.0(@swc/core@1.15.30(@swc/helpers@0.5.21))(esbuild@0.28.0) + webpack: 5.106.0(@swc/core@1.15.33(@swc/helpers@0.5.22))(esbuild@0.28.0)(lightningcss@1.32.0) webpack-node-externals: 3.0.0 optionalDependencies: - '@swc/core': 1.15.30(@swc/helpers@0.5.21) + '@swc/core': 1.15.33(@swc/helpers@0.5.22) transitivePeerDependencies: + - '@minify-html/node' + - '@swc/css' + - '@swc/html' - '@types/node' + - clean-css + - cssnano + - csso - esbuild + - html-minifier-terser + - lightningcss + - postcss - prettier - uglify-js - webpack-cli @@ -16310,7 +16785,22 @@ snapshots: transitivePeerDependencies: - supports-color - '@nestjs/core@11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.19)(@nestjs/websockets@11.1.19)(reflect-metadata@0.2.2)(rxjs@7.8.2)': + '@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2)': + dependencies: + file-type: 21.3.4 + iterare: 1.2.1 + load-esm: 1.0.3 + reflect-metadata: 0.2.2 + rxjs: 7.8.2 + tslib: 2.8.1 + uid: 2.0.2 + optionalDependencies: + class-transformer: 0.5.1 + class-validator: 0.14.4 + transitivePeerDependencies: + - supports-color + + '@nestjs/core@11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.21)(@nestjs/websockets@11.1.19)(reflect-metadata@0.2.2)(rxjs@7.8.2)': dependencies: '@nestjs/common': 11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) '@nuxt/opencollective': 0.4.1 @@ -16322,27 +16812,42 @@ snapshots: tslib: 2.8.1 uid: 2.0.2 optionalDependencies: - '@nestjs/platform-express': 11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19) + '@nestjs/platform-express': 11.1.21(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21) '@nestjs/websockets': 11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19)(@nestjs/platform-socket.io@11.1.19)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core@11.1.21(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.21)(@nestjs/websockets@11.1.21)(reflect-metadata@0.2.2)(rxjs@7.8.2)': + dependencies: + '@nestjs/common': 11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nuxt/opencollective': 0.4.1 + fast-safe-stringify: 2.1.1 + iterare: 1.2.1 + path-to-regexp: 8.4.2 + reflect-metadata: 0.2.2 + rxjs: 7.8.2 + tslib: 2.8.1 + uid: 2.0.2 + optionalDependencies: + '@nestjs/platform-express': 11.1.21(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21) + '@nestjs/websockets': 11.1.21(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21)(@nestjs/platform-socket.io@11.1.21)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/event-emitter@3.1.0(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19)': dependencies: '@nestjs/common': 11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.19)(@nestjs/websockets@11.1.19)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.21)(@nestjs/websockets@11.1.19)(reflect-metadata@0.2.2)(rxjs@7.8.2) eventemitter2: 6.4.9 - '@nestjs/mapped-types@2.1.1(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)': + '@nestjs/mapped-types@2.1.1(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)': dependencies: - '@nestjs/common': 11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) reflect-metadata: 0.2.2 optionalDependencies: class-transformer: 0.5.1 class-validator: 0.14.4 - '@nestjs/platform-express@11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19)': + '@nestjs/platform-express@11.1.21(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21)': dependencies: - '@nestjs/common': 11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.19)(@nestjs/websockets@11.1.19)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.21(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.21)(@nestjs/websockets@11.1.21)(reflect-metadata@0.2.2)(rxjs@7.8.2) cors: 2.8.6 express: 5.2.1 multer: 2.1.1 @@ -16363,10 +16868,28 @@ snapshots: - supports-color - utf-8-validate + '@nestjs/platform-socket.io@11.1.21(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/websockets@11.1.21)(rxjs@7.8.2)': + dependencies: + '@nestjs/common': 11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/websockets': 11.1.21(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21)(@nestjs/platform-socket.io@11.1.21)(reflect-metadata@0.2.2)(rxjs@7.8.2) + rxjs: 7.8.2 + socket.io: 4.8.3 + tslib: 2.8.1 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + '@nestjs/schedule@6.1.3(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19)': dependencies: '@nestjs/common': 11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.19)(@nestjs/websockets@11.1.19)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.21)(@nestjs/websockets@11.1.19)(reflect-metadata@0.2.2)(rxjs@7.8.2) + cron: 4.4.0 + + '@nestjs/schedule@6.1.3(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21)': + dependencies: + '@nestjs/common': 11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.21(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.21)(@nestjs/websockets@11.1.21)(reflect-metadata@0.2.2)(rxjs@7.8.2) cron: 4.4.0 '@nestjs/schematics@11.1.0(chokidar@4.0.3)(prettier@3.8.3)(typescript@5.9.3)': @@ -16395,33 +16918,34 @@ snapshots: transitivePeerDependencies: - chokidar - '@nestjs/swagger@11.4.2(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19)(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)': + '@nestjs/swagger@11.4.3(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21)(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(typescript@6.0.3)': dependencies: '@microsoft/tsdoc': 0.16.0 - '@nestjs/common': 11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.19)(@nestjs/websockets@11.1.19)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/mapped-types': 2.1.1(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2) + '@nestjs/common': 11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.21(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.21)(@nestjs/websockets@11.1.21)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/mapped-types': 2.1.1(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2) js-yaml: 4.1.1 lodash: 4.18.1 path-to-regexp: 8.4.2 reflect-metadata: 0.2.2 - swagger-ui-dist: 5.32.4 + swagger-ui-dist: 5.32.6 + typescript: 6.0.3 optionalDependencies: class-transformer: 0.5.1 class-validator: 0.14.4 - '@nestjs/testing@11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19)(@nestjs/platform-express@11.1.19)': + '@nestjs/testing@11.1.21(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21)(@nestjs/platform-express@11.1.21)': dependencies: - '@nestjs/common': 11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.19)(@nestjs/websockets@11.1.19)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.21(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.21)(@nestjs/websockets@11.1.21)(reflect-metadata@0.2.2)(rxjs@7.8.2) tslib: 2.8.1 optionalDependencies: - '@nestjs/platform-express': 11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19) + '@nestjs/platform-express': 11.1.21(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21) '@nestjs/websockets@11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19)(@nestjs/platform-socket.io@11.1.19)(reflect-metadata@0.2.2)(rxjs@7.8.2)': dependencies: '@nestjs/common': 11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.19)(@nestjs/websockets@11.1.19)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.21)(@nestjs/websockets@11.1.19)(reflect-metadata@0.2.2)(rxjs@7.8.2) iterare: 1.2.1 object-hash: 3.0.0 reflect-metadata: 0.2.2 @@ -16430,6 +16954,20 @@ snapshots: optionalDependencies: '@nestjs/platform-socket.io': 11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/websockets@11.1.19)(rxjs@7.8.2) + '@nestjs/websockets@11.1.21(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21)(@nestjs/platform-socket.io@11.1.21)(reflect-metadata@0.2.2)(rxjs@7.8.2)': + dependencies: + '@nestjs/common': 11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.21(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.21)(@nestjs/websockets@11.1.21)(reflect-metadata@0.2.2)(rxjs@7.8.2) + iterare: 1.2.1 + object-hash: 3.0.0 + reflect-metadata: 0.2.2 + rxjs: 7.8.2 + tslib: 2.8.1 + optionalDependencies: + '@nestjs/platform-socket.io': 11.1.21(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/websockets@11.1.21)(rxjs@7.8.2) + + '@noble/hashes@1.4.0': {} + '@noble/hashes@1.8.0': {} '@noble/hashes@2.2.0': {} @@ -16446,43 +16984,23 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.20.1 - '@npmcli/agent@4.0.0': - dependencies: - agent-base: 7.1.4 - http-proxy-agent: 7.0.2 - https-proxy-agent: 7.0.6 - lru-cache: 11.3.5 - socks-proxy-agent: 8.0.5 - transitivePeerDependencies: - - supports-color - - '@npmcli/fs@5.0.0': - dependencies: - semver: 7.7.4 - '@nuxt/opencollective@0.4.1': dependencies: consola: 3.4.2 '@oazapfts/runtime@1.2.0': {} - '@opentelemetry/api-logs@0.215.0': + '@opentelemetry/api-logs@0.218.0': dependencies: '@opentelemetry/api': 1.9.1 - '@opentelemetry/api-logs@0.217.0': - dependencies: - '@opentelemetry/api': 1.9.1 - - '@opentelemetry/api@1.9.0': {} - '@opentelemetry/api@1.9.1': {} - '@opentelemetry/configuration@0.217.0(@opentelemetry/api@1.9.1)': + '@opentelemetry/configuration@0.218.0(@opentelemetry/api@1.9.1)': dependencies: '@opentelemetry/api': 1.9.1 '@opentelemetry/core': 2.7.1(@opentelemetry/api@1.9.1) - yaml: 2.8.3 + yaml: 2.9.0 '@opentelemetry/context-async-hooks@2.7.0(@opentelemetry/api@1.9.1)': dependencies: @@ -16495,108 +17013,108 @@ snapshots: '@opentelemetry/core@2.7.0(@opentelemetry/api@1.9.1)': dependencies: '@opentelemetry/api': 1.9.1 - '@opentelemetry/semantic-conventions': 1.40.0 + '@opentelemetry/semantic-conventions': 1.41.1 '@opentelemetry/core@2.7.1(@opentelemetry/api@1.9.1)': dependencies: '@opentelemetry/api': 1.9.1 - '@opentelemetry/semantic-conventions': 1.40.0 + '@opentelemetry/semantic-conventions': 1.41.1 - '@opentelemetry/exporter-logs-otlp-grpc@0.217.0(@opentelemetry/api@1.9.1)': + '@opentelemetry/exporter-logs-otlp-grpc@0.218.0(@opentelemetry/api@1.9.1)': dependencies: '@grpc/grpc-js': 1.14.3 '@opentelemetry/api': 1.9.1 '@opentelemetry/core': 2.7.1(@opentelemetry/api@1.9.1) - '@opentelemetry/otlp-exporter-base': 0.217.0(@opentelemetry/api@1.9.1) - '@opentelemetry/otlp-grpc-exporter-base': 0.217.0(@opentelemetry/api@1.9.1) - '@opentelemetry/otlp-transformer': 0.217.0(@opentelemetry/api@1.9.1) - '@opentelemetry/sdk-logs': 0.217.0(@opentelemetry/api@1.9.1) + '@opentelemetry/otlp-exporter-base': 0.218.0(@opentelemetry/api@1.9.1) + '@opentelemetry/otlp-grpc-exporter-base': 0.218.0(@opentelemetry/api@1.9.1) + '@opentelemetry/otlp-transformer': 0.218.0(@opentelemetry/api@1.9.1) + '@opentelemetry/sdk-logs': 0.218.0(@opentelemetry/api@1.9.1) - '@opentelemetry/exporter-logs-otlp-http@0.217.0(@opentelemetry/api@1.9.1)': + '@opentelemetry/exporter-logs-otlp-http@0.218.0(@opentelemetry/api@1.9.1)': dependencies: '@opentelemetry/api': 1.9.1 - '@opentelemetry/api-logs': 0.217.0 + '@opentelemetry/api-logs': 0.218.0 '@opentelemetry/core': 2.7.1(@opentelemetry/api@1.9.1) - '@opentelemetry/otlp-exporter-base': 0.217.0(@opentelemetry/api@1.9.1) - '@opentelemetry/otlp-transformer': 0.217.0(@opentelemetry/api@1.9.1) - '@opentelemetry/sdk-logs': 0.217.0(@opentelemetry/api@1.9.1) + '@opentelemetry/otlp-exporter-base': 0.218.0(@opentelemetry/api@1.9.1) + '@opentelemetry/otlp-transformer': 0.218.0(@opentelemetry/api@1.9.1) + '@opentelemetry/sdk-logs': 0.218.0(@opentelemetry/api@1.9.1) - '@opentelemetry/exporter-logs-otlp-proto@0.217.0(@opentelemetry/api@1.9.1)': + '@opentelemetry/exporter-logs-otlp-proto@0.218.0(@opentelemetry/api@1.9.1)': dependencies: '@opentelemetry/api': 1.9.1 - '@opentelemetry/api-logs': 0.217.0 + '@opentelemetry/api-logs': 0.218.0 '@opentelemetry/core': 2.7.1(@opentelemetry/api@1.9.1) - '@opentelemetry/otlp-exporter-base': 0.217.0(@opentelemetry/api@1.9.1) - '@opentelemetry/otlp-transformer': 0.217.0(@opentelemetry/api@1.9.1) + '@opentelemetry/otlp-exporter-base': 0.218.0(@opentelemetry/api@1.9.1) + '@opentelemetry/otlp-transformer': 0.218.0(@opentelemetry/api@1.9.1) '@opentelemetry/resources': 2.7.1(@opentelemetry/api@1.9.1) - '@opentelemetry/sdk-logs': 0.217.0(@opentelemetry/api@1.9.1) + '@opentelemetry/sdk-logs': 0.218.0(@opentelemetry/api@1.9.1) '@opentelemetry/sdk-trace-base': 2.7.1(@opentelemetry/api@1.9.1) - '@opentelemetry/exporter-metrics-otlp-grpc@0.217.0(@opentelemetry/api@1.9.1)': + '@opentelemetry/exporter-metrics-otlp-grpc@0.218.0(@opentelemetry/api@1.9.1)': dependencies: '@grpc/grpc-js': 1.14.3 '@opentelemetry/api': 1.9.1 '@opentelemetry/core': 2.7.1(@opentelemetry/api@1.9.1) - '@opentelemetry/exporter-metrics-otlp-http': 0.217.0(@opentelemetry/api@1.9.1) - '@opentelemetry/otlp-exporter-base': 0.217.0(@opentelemetry/api@1.9.1) - '@opentelemetry/otlp-grpc-exporter-base': 0.217.0(@opentelemetry/api@1.9.1) - '@opentelemetry/otlp-transformer': 0.217.0(@opentelemetry/api@1.9.1) + '@opentelemetry/exporter-metrics-otlp-http': 0.218.0(@opentelemetry/api@1.9.1) + '@opentelemetry/otlp-exporter-base': 0.218.0(@opentelemetry/api@1.9.1) + '@opentelemetry/otlp-grpc-exporter-base': 0.218.0(@opentelemetry/api@1.9.1) + '@opentelemetry/otlp-transformer': 0.218.0(@opentelemetry/api@1.9.1) '@opentelemetry/resources': 2.7.1(@opentelemetry/api@1.9.1) '@opentelemetry/sdk-metrics': 2.7.1(@opentelemetry/api@1.9.1) - '@opentelemetry/exporter-metrics-otlp-http@0.217.0(@opentelemetry/api@1.9.1)': + '@opentelemetry/exporter-metrics-otlp-http@0.218.0(@opentelemetry/api@1.9.1)': dependencies: '@opentelemetry/api': 1.9.1 '@opentelemetry/core': 2.7.1(@opentelemetry/api@1.9.1) - '@opentelemetry/otlp-exporter-base': 0.217.0(@opentelemetry/api@1.9.1) - '@opentelemetry/otlp-transformer': 0.217.0(@opentelemetry/api@1.9.1) + '@opentelemetry/otlp-exporter-base': 0.218.0(@opentelemetry/api@1.9.1) + '@opentelemetry/otlp-transformer': 0.218.0(@opentelemetry/api@1.9.1) '@opentelemetry/resources': 2.7.1(@opentelemetry/api@1.9.1) '@opentelemetry/sdk-metrics': 2.7.1(@opentelemetry/api@1.9.1) - '@opentelemetry/exporter-metrics-otlp-proto@0.217.0(@opentelemetry/api@1.9.1)': + '@opentelemetry/exporter-metrics-otlp-proto@0.218.0(@opentelemetry/api@1.9.1)': dependencies: '@opentelemetry/api': 1.9.1 '@opentelemetry/core': 2.7.1(@opentelemetry/api@1.9.1) - '@opentelemetry/exporter-metrics-otlp-http': 0.217.0(@opentelemetry/api@1.9.1) - '@opentelemetry/otlp-exporter-base': 0.217.0(@opentelemetry/api@1.9.1) - '@opentelemetry/otlp-transformer': 0.217.0(@opentelemetry/api@1.9.1) + '@opentelemetry/exporter-metrics-otlp-http': 0.218.0(@opentelemetry/api@1.9.1) + '@opentelemetry/otlp-exporter-base': 0.218.0(@opentelemetry/api@1.9.1) + '@opentelemetry/otlp-transformer': 0.218.0(@opentelemetry/api@1.9.1) '@opentelemetry/resources': 2.7.1(@opentelemetry/api@1.9.1) '@opentelemetry/sdk-metrics': 2.7.1(@opentelemetry/api@1.9.1) - '@opentelemetry/exporter-prometheus@0.217.0(@opentelemetry/api@1.9.1)': + '@opentelemetry/exporter-prometheus@0.218.0(@opentelemetry/api@1.9.1)': dependencies: '@opentelemetry/api': 1.9.1 '@opentelemetry/core': 2.7.1(@opentelemetry/api@1.9.1) '@opentelemetry/resources': 2.7.1(@opentelemetry/api@1.9.1) '@opentelemetry/sdk-metrics': 2.7.1(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.40.0 + '@opentelemetry/semantic-conventions': 1.41.1 - '@opentelemetry/exporter-trace-otlp-grpc@0.217.0(@opentelemetry/api@1.9.1)': + '@opentelemetry/exporter-trace-otlp-grpc@0.218.0(@opentelemetry/api@1.9.1)': dependencies: '@grpc/grpc-js': 1.14.3 '@opentelemetry/api': 1.9.1 '@opentelemetry/core': 2.7.1(@opentelemetry/api@1.9.1) - '@opentelemetry/otlp-exporter-base': 0.217.0(@opentelemetry/api@1.9.1) - '@opentelemetry/otlp-grpc-exporter-base': 0.217.0(@opentelemetry/api@1.9.1) - '@opentelemetry/otlp-transformer': 0.217.0(@opentelemetry/api@1.9.1) + '@opentelemetry/otlp-exporter-base': 0.218.0(@opentelemetry/api@1.9.1) + '@opentelemetry/otlp-grpc-exporter-base': 0.218.0(@opentelemetry/api@1.9.1) + '@opentelemetry/otlp-transformer': 0.218.0(@opentelemetry/api@1.9.1) '@opentelemetry/resources': 2.7.1(@opentelemetry/api@1.9.1) '@opentelemetry/sdk-trace-base': 2.7.1(@opentelemetry/api@1.9.1) - '@opentelemetry/exporter-trace-otlp-http@0.217.0(@opentelemetry/api@1.9.1)': + '@opentelemetry/exporter-trace-otlp-http@0.218.0(@opentelemetry/api@1.9.1)': dependencies: '@opentelemetry/api': 1.9.1 '@opentelemetry/core': 2.7.1(@opentelemetry/api@1.9.1) - '@opentelemetry/otlp-exporter-base': 0.217.0(@opentelemetry/api@1.9.1) - '@opentelemetry/otlp-transformer': 0.217.0(@opentelemetry/api@1.9.1) + '@opentelemetry/otlp-exporter-base': 0.218.0(@opentelemetry/api@1.9.1) + '@opentelemetry/otlp-transformer': 0.218.0(@opentelemetry/api@1.9.1) '@opentelemetry/resources': 2.7.1(@opentelemetry/api@1.9.1) '@opentelemetry/sdk-trace-base': 2.7.1(@opentelemetry/api@1.9.1) - '@opentelemetry/exporter-trace-otlp-proto@0.217.0(@opentelemetry/api@1.9.1)': + '@opentelemetry/exporter-trace-otlp-proto@0.218.0(@opentelemetry/api@1.9.1)': dependencies: '@opentelemetry/api': 1.9.1 '@opentelemetry/core': 2.7.1(@opentelemetry/api@1.9.1) - '@opentelemetry/otlp-exporter-base': 0.217.0(@opentelemetry/api@1.9.1) - '@opentelemetry/otlp-transformer': 0.217.0(@opentelemetry/api@1.9.1) + '@opentelemetry/otlp-exporter-base': 0.218.0(@opentelemetry/api@1.9.1) + '@opentelemetry/otlp-transformer': 0.218.0(@opentelemetry/api@1.9.1) '@opentelemetry/resources': 2.7.1(@opentelemetry/api@1.9.1) '@opentelemetry/sdk-trace-base': 2.7.1(@opentelemetry/api@1.9.1) @@ -16606,94 +17124,84 @@ snapshots: '@opentelemetry/core': 2.7.1(@opentelemetry/api@1.9.1) '@opentelemetry/resources': 2.7.1(@opentelemetry/api@1.9.1) '@opentelemetry/sdk-trace-base': 2.7.1(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.40.0 + '@opentelemetry/semantic-conventions': 1.41.1 - '@opentelemetry/host-metrics@0.38.3(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - systeminformation: 5.31.5 - - '@opentelemetry/instrumentation-http@0.215.0(@opentelemetry/api@1.9.1)': + '@opentelemetry/host-metrics@0.38.3(@opentelemetry/api@1.9.1)': dependencies: '@opentelemetry/api': 1.9.1 - '@opentelemetry/core': 2.7.0(@opentelemetry/api@1.9.1) - '@opentelemetry/instrumentation': 0.215.0(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.40.0 + systeminformation: 5.31.6 + + '@opentelemetry/instrumentation-http@0.218.0(@opentelemetry/api@1.9.1)': + dependencies: + '@opentelemetry/api': 1.9.1 + '@opentelemetry/core': 2.7.1(@opentelemetry/api@1.9.1) + '@opentelemetry/instrumentation': 0.218.0(@opentelemetry/api@1.9.1) + '@opentelemetry/semantic-conventions': 1.41.1 forwarded-parse: 2.1.2 transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation-ioredis@0.63.0(@opentelemetry/api@1.9.1)': + '@opentelemetry/instrumentation-ioredis@0.66.0(@opentelemetry/api@1.9.1)': dependencies: '@opentelemetry/api': 1.9.1 - '@opentelemetry/instrumentation': 0.215.0(@opentelemetry/api@1.9.1) + '@opentelemetry/instrumentation': 0.218.0(@opentelemetry/api@1.9.1) '@opentelemetry/redis-common': 0.38.3 - '@opentelemetry/semantic-conventions': 1.40.0 + '@opentelemetry/semantic-conventions': 1.41.1 transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation-nestjs-core@0.61.0(@opentelemetry/api@1.9.1)': + '@opentelemetry/instrumentation-nestjs-core@0.64.0(@opentelemetry/api@1.9.1)': dependencies: '@opentelemetry/api': 1.9.1 - '@opentelemetry/instrumentation': 0.215.0(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.40.0 + '@opentelemetry/instrumentation': 0.218.0(@opentelemetry/api@1.9.1) + '@opentelemetry/semantic-conventions': 1.41.1 transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation-pg@0.67.0(@opentelemetry/api@1.9.1)': + '@opentelemetry/instrumentation-pg@0.70.0(@opentelemetry/api@1.9.1)': dependencies: '@opentelemetry/api': 1.9.1 - '@opentelemetry/core': 2.7.0(@opentelemetry/api@1.9.1) - '@opentelemetry/instrumentation': 0.215.0(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.40.0 + '@opentelemetry/core': 2.7.1(@opentelemetry/api@1.9.1) + '@opentelemetry/instrumentation': 0.218.0(@opentelemetry/api@1.9.1) + '@opentelemetry/semantic-conventions': 1.41.1 '@opentelemetry/sql-common': 0.41.2(@opentelemetry/api@1.9.1) '@types/pg': 8.15.6 '@types/pg-pool': 2.0.7 transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation@0.215.0(@opentelemetry/api@1.9.1)': + '@opentelemetry/instrumentation@0.218.0(@opentelemetry/api@1.9.1)': dependencies: '@opentelemetry/api': 1.9.1 - '@opentelemetry/api-logs': 0.215.0 - import-in-the-middle: 3.0.0 + '@opentelemetry/api-logs': 0.218.0 + import-in-the-middle: 3.0.1 require-in-the-middle: 8.0.1 transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation@0.217.0(@opentelemetry/api@1.9.1)': - dependencies: - '@opentelemetry/api': 1.9.1 - '@opentelemetry/api-logs': 0.217.0 - import-in-the-middle: 3.0.0 - require-in-the-middle: 8.0.1 - transitivePeerDependencies: - - supports-color - - '@opentelemetry/otlp-exporter-base@0.217.0(@opentelemetry/api@1.9.1)': + '@opentelemetry/otlp-exporter-base@0.218.0(@opentelemetry/api@1.9.1)': dependencies: '@opentelemetry/api': 1.9.1 '@opentelemetry/core': 2.7.1(@opentelemetry/api@1.9.1) - '@opentelemetry/otlp-transformer': 0.217.0(@opentelemetry/api@1.9.1) + '@opentelemetry/otlp-transformer': 0.218.0(@opentelemetry/api@1.9.1) - '@opentelemetry/otlp-grpc-exporter-base@0.217.0(@opentelemetry/api@1.9.1)': + '@opentelemetry/otlp-grpc-exporter-base@0.218.0(@opentelemetry/api@1.9.1)': dependencies: '@grpc/grpc-js': 1.14.3 '@opentelemetry/api': 1.9.1 '@opentelemetry/core': 2.7.1(@opentelemetry/api@1.9.1) - '@opentelemetry/otlp-exporter-base': 0.217.0(@opentelemetry/api@1.9.1) - '@opentelemetry/otlp-transformer': 0.217.0(@opentelemetry/api@1.9.1) + '@opentelemetry/otlp-exporter-base': 0.218.0(@opentelemetry/api@1.9.1) + '@opentelemetry/otlp-transformer': 0.218.0(@opentelemetry/api@1.9.1) - '@opentelemetry/otlp-transformer@0.217.0(@opentelemetry/api@1.9.1)': + '@opentelemetry/otlp-transformer@0.218.0(@opentelemetry/api@1.9.1)': dependencies: '@opentelemetry/api': 1.9.1 - '@opentelemetry/api-logs': 0.217.0 + '@opentelemetry/api-logs': 0.218.0 '@opentelemetry/core': 2.7.1(@opentelemetry/api@1.9.1) '@opentelemetry/resources': 2.7.1(@opentelemetry/api@1.9.1) - '@opentelemetry/sdk-logs': 0.217.0(@opentelemetry/api@1.9.1) + '@opentelemetry/sdk-logs': 0.218.0(@opentelemetry/api@1.9.1) '@opentelemetry/sdk-metrics': 2.7.1(@opentelemetry/api@1.9.1) '@opentelemetry/sdk-trace-base': 2.7.1(@opentelemetry/api@1.9.1) - protobufjs: 8.0.1 '@opentelemetry/propagator-b3@2.7.1(@opentelemetry/api@1.9.1)': dependencies: @@ -16711,21 +17219,21 @@ snapshots: dependencies: '@opentelemetry/api': 1.9.1 '@opentelemetry/core': 2.7.0(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.40.0 + '@opentelemetry/semantic-conventions': 1.41.1 '@opentelemetry/resources@2.7.1(@opentelemetry/api@1.9.1)': dependencies: '@opentelemetry/api': 1.9.1 '@opentelemetry/core': 2.7.1(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.40.0 + '@opentelemetry/semantic-conventions': 1.41.1 - '@opentelemetry/sdk-logs@0.217.0(@opentelemetry/api@1.9.1)': + '@opentelemetry/sdk-logs@0.218.0(@opentelemetry/api@1.9.1)': dependencies: '@opentelemetry/api': 1.9.1 - '@opentelemetry/api-logs': 0.217.0 + '@opentelemetry/api-logs': 0.218.0 '@opentelemetry/core': 2.7.1(@opentelemetry/api@1.9.1) '@opentelemetry/resources': 2.7.1(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.40.0 + '@opentelemetry/semantic-conventions': 1.41.1 '@opentelemetry/sdk-metrics@2.7.0(@opentelemetry/api@1.9.1)': dependencies: @@ -16739,34 +17247,34 @@ snapshots: '@opentelemetry/core': 2.7.1(@opentelemetry/api@1.9.1) '@opentelemetry/resources': 2.7.1(@opentelemetry/api@1.9.1) - '@opentelemetry/sdk-node@0.217.0(@opentelemetry/api@1.9.1)': + '@opentelemetry/sdk-node@0.218.0(@opentelemetry/api@1.9.1)': dependencies: '@opentelemetry/api': 1.9.1 - '@opentelemetry/api-logs': 0.217.0 - '@opentelemetry/configuration': 0.217.0(@opentelemetry/api@1.9.1) + '@opentelemetry/api-logs': 0.218.0 + '@opentelemetry/configuration': 0.218.0(@opentelemetry/api@1.9.1) '@opentelemetry/context-async-hooks': 2.7.1(@opentelemetry/api@1.9.1) '@opentelemetry/core': 2.7.1(@opentelemetry/api@1.9.1) - '@opentelemetry/exporter-logs-otlp-grpc': 0.217.0(@opentelemetry/api@1.9.1) - '@opentelemetry/exporter-logs-otlp-http': 0.217.0(@opentelemetry/api@1.9.1) - '@opentelemetry/exporter-logs-otlp-proto': 0.217.0(@opentelemetry/api@1.9.1) - '@opentelemetry/exporter-metrics-otlp-grpc': 0.217.0(@opentelemetry/api@1.9.1) - '@opentelemetry/exporter-metrics-otlp-http': 0.217.0(@opentelemetry/api@1.9.1) - '@opentelemetry/exporter-metrics-otlp-proto': 0.217.0(@opentelemetry/api@1.9.1) - '@opentelemetry/exporter-prometheus': 0.217.0(@opentelemetry/api@1.9.1) - '@opentelemetry/exporter-trace-otlp-grpc': 0.217.0(@opentelemetry/api@1.9.1) - '@opentelemetry/exporter-trace-otlp-http': 0.217.0(@opentelemetry/api@1.9.1) - '@opentelemetry/exporter-trace-otlp-proto': 0.217.0(@opentelemetry/api@1.9.1) + '@opentelemetry/exporter-logs-otlp-grpc': 0.218.0(@opentelemetry/api@1.9.1) + '@opentelemetry/exporter-logs-otlp-http': 0.218.0(@opentelemetry/api@1.9.1) + '@opentelemetry/exporter-logs-otlp-proto': 0.218.0(@opentelemetry/api@1.9.1) + '@opentelemetry/exporter-metrics-otlp-grpc': 0.218.0(@opentelemetry/api@1.9.1) + '@opentelemetry/exporter-metrics-otlp-http': 0.218.0(@opentelemetry/api@1.9.1) + '@opentelemetry/exporter-metrics-otlp-proto': 0.218.0(@opentelemetry/api@1.9.1) + '@opentelemetry/exporter-prometheus': 0.218.0(@opentelemetry/api@1.9.1) + '@opentelemetry/exporter-trace-otlp-grpc': 0.218.0(@opentelemetry/api@1.9.1) + '@opentelemetry/exporter-trace-otlp-http': 0.218.0(@opentelemetry/api@1.9.1) + '@opentelemetry/exporter-trace-otlp-proto': 0.218.0(@opentelemetry/api@1.9.1) '@opentelemetry/exporter-zipkin': 2.7.1(@opentelemetry/api@1.9.1) - '@opentelemetry/instrumentation': 0.217.0(@opentelemetry/api@1.9.1) - '@opentelemetry/otlp-exporter-base': 0.217.0(@opentelemetry/api@1.9.1) + '@opentelemetry/instrumentation': 0.218.0(@opentelemetry/api@1.9.1) + '@opentelemetry/otlp-exporter-base': 0.218.0(@opentelemetry/api@1.9.1) '@opentelemetry/propagator-b3': 2.7.1(@opentelemetry/api@1.9.1) '@opentelemetry/propagator-jaeger': 2.7.1(@opentelemetry/api@1.9.1) '@opentelemetry/resources': 2.7.1(@opentelemetry/api@1.9.1) - '@opentelemetry/sdk-logs': 0.217.0(@opentelemetry/api@1.9.1) + '@opentelemetry/sdk-logs': 0.218.0(@opentelemetry/api@1.9.1) '@opentelemetry/sdk-metrics': 2.7.1(@opentelemetry/api@1.9.1) '@opentelemetry/sdk-trace-base': 2.7.1(@opentelemetry/api@1.9.1) '@opentelemetry/sdk-trace-node': 2.7.1(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.40.0 + '@opentelemetry/semantic-conventions': 1.41.1 transitivePeerDependencies: - supports-color @@ -16775,7 +17283,7 @@ snapshots: '@opentelemetry/api': 1.9.1 '@opentelemetry/core': 2.7.1(@opentelemetry/api@1.9.1) '@opentelemetry/resources': 2.7.1(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.40.0 + '@opentelemetry/semantic-conventions': 1.41.1 '@opentelemetry/sdk-trace-node@2.7.1(@opentelemetry/api@1.9.1)': dependencies: @@ -16784,14 +17292,14 @@ snapshots: '@opentelemetry/core': 2.7.1(@opentelemetry/api@1.9.1) '@opentelemetry/sdk-trace-base': 2.7.1(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions@1.40.0': {} + '@opentelemetry/semantic-conventions@1.41.1': {} '@opentelemetry/sql-common@0.41.2(@opentelemetry/api@1.9.1)': dependencies: '@opentelemetry/api': 1.9.1 - '@opentelemetry/core': 2.7.0(@opentelemetry/api@1.9.1) + '@opentelemetry/core': 2.7.1(@opentelemetry/api@1.9.1) - '@oxc-project/types@0.127.0': {} + '@oxc-project/types@0.130.0': {} '@paralleldrive/cuid2@2.3.1': dependencies: @@ -16858,6 +17366,100 @@ snapshots: '@parcel/watcher-win32-x64': 2.5.6 optional: true + '@peculiar/asn1-cms@2.7.0': + dependencies: + '@peculiar/asn1-schema': 2.7.0 + '@peculiar/asn1-x509': 2.7.0 + '@peculiar/asn1-x509-attr': 2.7.0 + asn1js: 3.0.10 + tslib: 2.8.1 + + '@peculiar/asn1-csr@2.7.0': + dependencies: + '@peculiar/asn1-schema': 2.7.0 + '@peculiar/asn1-x509': 2.7.0 + asn1js: 3.0.10 + tslib: 2.8.1 + + '@peculiar/asn1-ecc@2.7.0': + dependencies: + '@peculiar/asn1-schema': 2.7.0 + '@peculiar/asn1-x509': 2.7.0 + asn1js: 3.0.10 + tslib: 2.8.1 + + '@peculiar/asn1-pfx@2.7.0': + dependencies: + '@peculiar/asn1-cms': 2.7.0 + '@peculiar/asn1-pkcs8': 2.7.0 + '@peculiar/asn1-rsa': 2.7.0 + '@peculiar/asn1-schema': 2.7.0 + asn1js: 3.0.10 + tslib: 2.8.1 + + '@peculiar/asn1-pkcs8@2.7.0': + dependencies: + '@peculiar/asn1-schema': 2.7.0 + '@peculiar/asn1-x509': 2.7.0 + asn1js: 3.0.10 + tslib: 2.8.1 + + '@peculiar/asn1-pkcs9@2.7.0': + dependencies: + '@peculiar/asn1-cms': 2.7.0 + '@peculiar/asn1-pfx': 2.7.0 + '@peculiar/asn1-pkcs8': 2.7.0 + '@peculiar/asn1-schema': 2.7.0 + '@peculiar/asn1-x509': 2.7.0 + '@peculiar/asn1-x509-attr': 2.7.0 + asn1js: 3.0.10 + tslib: 2.8.1 + + '@peculiar/asn1-rsa@2.7.0': + dependencies: + '@peculiar/asn1-schema': 2.7.0 + '@peculiar/asn1-x509': 2.7.0 + asn1js: 3.0.10 + tslib: 2.8.1 + + '@peculiar/asn1-schema@2.7.0': + dependencies: + '@peculiar/utils': 2.0.3 + asn1js: 3.0.10 + tslib: 2.8.1 + + '@peculiar/asn1-x509-attr@2.7.0': + dependencies: + '@peculiar/asn1-schema': 2.7.0 + '@peculiar/asn1-x509': 2.7.0 + asn1js: 3.0.10 + tslib: 2.8.1 + + '@peculiar/asn1-x509@2.7.0': + dependencies: + '@peculiar/asn1-schema': 2.7.0 + '@peculiar/utils': 2.0.3 + asn1js: 3.0.10 + tslib: 2.8.1 + + '@peculiar/utils@2.0.3': + dependencies: + tslib: 2.8.1 + + '@peculiar/x509@1.14.3': + dependencies: + '@peculiar/asn1-cms': 2.7.0 + '@peculiar/asn1-csr': 2.7.0 + '@peculiar/asn1-ecc': 2.7.0 + '@peculiar/asn1-pkcs9': 2.7.0 + '@peculiar/asn1-rsa': 2.7.0 + '@peculiar/asn1-schema': 2.7.0 + '@peculiar/asn1-x509': 2.7.0 + pvtsutils: 1.3.6 + reflect-metadata: 0.2.2 + tslib: 2.8.1 + tsyringe: 4.10.0 + '@photo-sphere-viewer/core@5.14.1': dependencies: three: 0.179.1 @@ -16866,7 +17468,7 @@ snapshots: dependencies: '@photo-sphere-viewer/core': 5.14.1 '@photo-sphere-viewer/video-plugin': 5.14.1(@photo-sphere-viewer/core@5.14.1) - three: 0.182.0 + three: 0.184.0 '@photo-sphere-viewer/markers-plugin@5.14.1(@photo-sphere-viewer/core@5.14.1)': dependencies: @@ -16884,7 +17486,7 @@ snapshots: '@photo-sphere-viewer/video-plugin@5.14.1(@photo-sphere-viewer/core@5.14.1)': dependencies: '@photo-sphere-viewer/core': 5.14.1 - three: 0.182.0 + three: 0.184.0 '@photostructure/tz-lookup@11.5.0': {} @@ -16893,9 +17495,9 @@ snapshots: '@pkgr/core@0.2.9': {} - '@playwright/test@1.59.1': + '@playwright/test@1.60.0': dependencies: - playwright: 1.59.1 + playwright: 1.60.0 '@pnpm/config.env-replace@1.1.0': {} @@ -16903,7 +17505,7 @@ snapshots: dependencies: graceful-fs: 4.2.10 - '@pnpm/npm-conf@2.3.1': + '@pnpm/npm-conf@3.0.2': dependencies: '@pnpm/config.env-replace': 1.1.0 '@pnpm/network.ca-file': 1.0.2 @@ -16915,294 +17517,293 @@ snapshots: '@protobufjs/base64@1.1.2': {} - '@protobufjs/codegen@2.0.4': {} + '@protobufjs/codegen@2.0.5': {} '@protobufjs/eventemitter@1.1.0': {} - '@protobufjs/fetch@1.1.0': + '@protobufjs/fetch@1.1.1': dependencies: '@protobufjs/aspromise': 1.1.2 - '@protobufjs/inquire': 1.1.0 '@protobufjs/float@1.0.2': {} - '@protobufjs/inquire@1.1.0': {} + '@protobufjs/inquire@1.1.2': {} '@protobufjs/path@1.1.2': {} '@protobufjs/pool@1.1.0': {} - '@protobufjs/utf8@1.1.0': {} + '@protobufjs/utf8@1.1.1': {} - '@react-email/body@0.3.0(react@19.2.5)': + '@react-email/body@0.3.0(react@19.2.6)': dependencies: - react: 19.2.5 + react: 19.2.6 - '@react-email/button@0.2.1(react@19.2.5)': + '@react-email/button@0.2.1(react@19.2.6)': dependencies: - react: 19.2.5 + react: 19.2.6 - '@react-email/code-block@0.2.1(react@19.2.5)': + '@react-email/code-block@0.2.1(react@19.2.6)': dependencies: prismjs: 1.30.0 - react: 19.2.5 + react: 19.2.6 - '@react-email/code-inline@0.0.6(react@19.2.5)': + '@react-email/code-inline@0.0.6(react@19.2.6)': dependencies: - react: 19.2.5 + react: 19.2.6 - '@react-email/column@0.0.14(react@19.2.5)': + '@react-email/column@0.0.14(react@19.2.6)': dependencies: - react: 19.2.5 + react: 19.2.6 - '@react-email/components@1.0.12(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + '@react-email/components@1.0.12(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': dependencies: - '@react-email/body': 0.3.0(react@19.2.5) - '@react-email/button': 0.2.1(react@19.2.5) - '@react-email/code-block': 0.2.1(react@19.2.5) - '@react-email/code-inline': 0.0.6(react@19.2.5) - '@react-email/column': 0.0.14(react@19.2.5) - '@react-email/container': 0.0.16(react@19.2.5) - '@react-email/font': 0.0.10(react@19.2.5) - '@react-email/head': 0.0.13(react@19.2.5) - '@react-email/heading': 0.0.16(react@19.2.5) - '@react-email/hr': 0.0.12(react@19.2.5) - '@react-email/html': 0.0.12(react@19.2.5) - '@react-email/img': 0.0.12(react@19.2.5) - '@react-email/link': 0.0.13(react@19.2.5) - '@react-email/markdown': 0.0.18(react@19.2.5) - '@react-email/preview': 0.0.14(react@19.2.5) - '@react-email/render': 2.0.6(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@react-email/row': 0.0.13(react@19.2.5) - '@react-email/section': 0.0.17(react@19.2.5) - '@react-email/tailwind': 2.0.7(@react-email/body@0.3.0(react@19.2.5))(@react-email/button@0.2.1(react@19.2.5))(@react-email/code-block@0.2.1(react@19.2.5))(@react-email/code-inline@0.0.6(react@19.2.5))(@react-email/container@0.0.16(react@19.2.5))(@react-email/heading@0.0.16(react@19.2.5))(@react-email/hr@0.0.12(react@19.2.5))(@react-email/img@0.0.12(react@19.2.5))(@react-email/link@0.0.13(react@19.2.5))(@react-email/preview@0.0.14(react@19.2.5))(@react-email/text@0.1.6(react@19.2.5))(react@19.2.5) - '@react-email/text': 0.1.6(react@19.2.5) - react: 19.2.5 + '@react-email/body': 0.3.0(react@19.2.6) + '@react-email/button': 0.2.1(react@19.2.6) + '@react-email/code-block': 0.2.1(react@19.2.6) + '@react-email/code-inline': 0.0.6(react@19.2.6) + '@react-email/column': 0.0.14(react@19.2.6) + '@react-email/container': 0.0.16(react@19.2.6) + '@react-email/font': 0.0.10(react@19.2.6) + '@react-email/head': 0.0.13(react@19.2.6) + '@react-email/heading': 0.0.16(react@19.2.6) + '@react-email/hr': 0.0.12(react@19.2.6) + '@react-email/html': 0.0.12(react@19.2.6) + '@react-email/img': 0.0.12(react@19.2.6) + '@react-email/link': 0.0.13(react@19.2.6) + '@react-email/markdown': 0.0.18(react@19.2.6) + '@react-email/preview': 0.0.14(react@19.2.6) + '@react-email/render': 2.0.6(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@react-email/row': 0.0.13(react@19.2.6) + '@react-email/section': 0.0.17(react@19.2.6) + '@react-email/tailwind': 2.0.7(@react-email/body@0.3.0(react@19.2.6))(@react-email/button@0.2.1(react@19.2.6))(@react-email/code-block@0.2.1(react@19.2.6))(@react-email/code-inline@0.0.6(react@19.2.6))(@react-email/container@0.0.16(react@19.2.6))(@react-email/heading@0.0.16(react@19.2.6))(@react-email/hr@0.0.12(react@19.2.6))(@react-email/img@0.0.12(react@19.2.6))(@react-email/link@0.0.13(react@19.2.6))(@react-email/preview@0.0.14(react@19.2.6))(@react-email/text@0.1.6(react@19.2.6))(react@19.2.6) + '@react-email/text': 0.1.6(react@19.2.6) + react: 19.2.6 transitivePeerDependencies: - react-dom - '@react-email/container@0.0.16(react@19.2.5)': + '@react-email/container@0.0.16(react@19.2.6)': dependencies: - react: 19.2.5 + react: 19.2.6 - '@react-email/font@0.0.10(react@19.2.5)': + '@react-email/font@0.0.10(react@19.2.6)': dependencies: - react: 19.2.5 + react: 19.2.6 - '@react-email/head@0.0.13(react@19.2.5)': + '@react-email/head@0.0.13(react@19.2.6)': dependencies: - react: 19.2.5 + react: 19.2.6 - '@react-email/heading@0.0.16(react@19.2.5)': + '@react-email/heading@0.0.16(react@19.2.6)': dependencies: - react: 19.2.5 + react: 19.2.6 - '@react-email/hr@0.0.12(react@19.2.5)': + '@react-email/hr@0.0.12(react@19.2.6)': dependencies: - react: 19.2.5 + react: 19.2.6 - '@react-email/html@0.0.12(react@19.2.5)': + '@react-email/html@0.0.12(react@19.2.6)': dependencies: - react: 19.2.5 + react: 19.2.6 - '@react-email/img@0.0.12(react@19.2.5)': + '@react-email/img@0.0.12(react@19.2.6)': dependencies: - react: 19.2.5 + react: 19.2.6 - '@react-email/link@0.0.13(react@19.2.5)': + '@react-email/link@0.0.13(react@19.2.6)': dependencies: - react: 19.2.5 + react: 19.2.6 - '@react-email/markdown@0.0.18(react@19.2.5)': + '@react-email/markdown@0.0.18(react@19.2.6)': dependencies: marked: 15.0.12 - react: 19.2.5 + react: 19.2.6 - '@react-email/preview@0.0.14(react@19.2.5)': + '@react-email/preview@0.0.14(react@19.2.6)': dependencies: - react: 19.2.5 + react: 19.2.6 - '@react-email/render@2.0.6(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + '@react-email/render@2.0.6(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': dependencies: html-to-text: 9.0.5 prettier: 3.8.3 - react: 19.2.5 - react-dom: 19.2.5(react@19.2.5) + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) - '@react-email/render@2.0.7(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + '@react-email/render@2.0.8(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': dependencies: html-to-text: 9.0.5 prettier: 3.8.3 - react: 19.2.5 - react-dom: 19.2.5(react@19.2.5) + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) - '@react-email/row@0.0.13(react@19.2.5)': + '@react-email/row@0.0.13(react@19.2.6)': dependencies: - react: 19.2.5 + react: 19.2.6 - '@react-email/section@0.0.17(react@19.2.5)': + '@react-email/section@0.0.17(react@19.2.6)': dependencies: - react: 19.2.5 + react: 19.2.6 - '@react-email/tailwind@2.0.7(@react-email/body@0.3.0(react@19.2.5))(@react-email/button@0.2.1(react@19.2.5))(@react-email/code-block@0.2.1(react@19.2.5))(@react-email/code-inline@0.0.6(react@19.2.5))(@react-email/container@0.0.16(react@19.2.5))(@react-email/heading@0.0.16(react@19.2.5))(@react-email/hr@0.0.12(react@19.2.5))(@react-email/img@0.0.12(react@19.2.5))(@react-email/link@0.0.13(react@19.2.5))(@react-email/preview@0.0.14(react@19.2.5))(@react-email/text@0.1.6(react@19.2.5))(react@19.2.5)': + '@react-email/tailwind@2.0.7(@react-email/body@0.3.0(react@19.2.6))(@react-email/button@0.2.1(react@19.2.6))(@react-email/code-block@0.2.1(react@19.2.6))(@react-email/code-inline@0.0.6(react@19.2.6))(@react-email/container@0.0.16(react@19.2.6))(@react-email/heading@0.0.16(react@19.2.6))(@react-email/hr@0.0.12(react@19.2.6))(@react-email/img@0.0.12(react@19.2.6))(@react-email/link@0.0.13(react@19.2.6))(@react-email/preview@0.0.14(react@19.2.6))(@react-email/text@0.1.6(react@19.2.6))(react@19.2.6)': dependencies: - '@react-email/text': 0.1.6(react@19.2.5) - react: 19.2.5 - tailwindcss: 4.2.4 + '@react-email/text': 0.1.6(react@19.2.6) + react: 19.2.6 + tailwindcss: 4.3.0 optionalDependencies: - '@react-email/body': 0.3.0(react@19.2.5) - '@react-email/button': 0.2.1(react@19.2.5) - '@react-email/code-block': 0.2.1(react@19.2.5) - '@react-email/code-inline': 0.0.6(react@19.2.5) - '@react-email/container': 0.0.16(react@19.2.5) - '@react-email/heading': 0.0.16(react@19.2.5) - '@react-email/hr': 0.0.12(react@19.2.5) - '@react-email/img': 0.0.12(react@19.2.5) - '@react-email/link': 0.0.13(react@19.2.5) - '@react-email/preview': 0.0.14(react@19.2.5) + '@react-email/body': 0.3.0(react@19.2.6) + '@react-email/button': 0.2.1(react@19.2.6) + '@react-email/code-block': 0.2.1(react@19.2.6) + '@react-email/code-inline': 0.0.6(react@19.2.6) + '@react-email/container': 0.0.16(react@19.2.6) + '@react-email/heading': 0.0.16(react@19.2.6) + '@react-email/hr': 0.0.12(react@19.2.6) + '@react-email/img': 0.0.12(react@19.2.6) + '@react-email/link': 0.0.13(react@19.2.6) + '@react-email/preview': 0.0.14(react@19.2.6) - '@react-email/text@0.1.6(react@19.2.5)': + '@react-email/text@0.1.6(react@19.2.6)': dependencies: - react: 19.2.5 + react: 19.2.6 - '@replit/codemirror-indentation-markers@6.5.3(@codemirror/language@6.12.3)(@codemirror/state@6.6.0)(@codemirror/view@6.41.1)': + '@replit/codemirror-indentation-markers@6.5.3(@codemirror/language@6.12.3)(@codemirror/state@6.6.0)(@codemirror/view@6.43.0)': dependencies: '@codemirror/language': 6.12.3 '@codemirror/state': 6.6.0 - '@codemirror/view': 6.41.1 + '@codemirror/view': 6.43.0 - '@rolldown/binding-android-arm64@1.0.0-rc.17': + '@rolldown/binding-android-arm64@1.0.1': optional: true - '@rolldown/binding-darwin-arm64@1.0.0-rc.17': + '@rolldown/binding-darwin-arm64@1.0.1': optional: true - '@rolldown/binding-darwin-x64@1.0.0-rc.17': + '@rolldown/binding-darwin-x64@1.0.1': optional: true - '@rolldown/binding-freebsd-x64@1.0.0-rc.17': + '@rolldown/binding-freebsd-x64@1.0.1': optional: true - '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.17': + '@rolldown/binding-linux-arm-gnueabihf@1.0.1': optional: true - '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.17': + '@rolldown/binding-linux-arm64-gnu@1.0.1': optional: true - '@rolldown/binding-linux-arm64-musl@1.0.0-rc.17': + '@rolldown/binding-linux-arm64-musl@1.0.1': optional: true - '@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.17': + '@rolldown/binding-linux-ppc64-gnu@1.0.1': optional: true - '@rolldown/binding-linux-s390x-gnu@1.0.0-rc.17': + '@rolldown/binding-linux-s390x-gnu@1.0.1': optional: true - '@rolldown/binding-linux-x64-gnu@1.0.0-rc.17': + '@rolldown/binding-linux-x64-gnu@1.0.1': optional: true - '@rolldown/binding-linux-x64-musl@1.0.0-rc.17': + '@rolldown/binding-linux-x64-musl@1.0.1': optional: true - '@rolldown/binding-openharmony-arm64@1.0.0-rc.17': + '@rolldown/binding-openharmony-arm64@1.0.1': optional: true - '@rolldown/binding-wasm32-wasi@1.0.0-rc.17': + '@rolldown/binding-wasm32-wasi@1.0.1': dependencies: '@emnapi/core': 1.10.0 '@emnapi/runtime': 1.10.0 '@napi-rs/wasm-runtime': 1.1.4(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) optional: true - '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.17': + '@rolldown/binding-win32-arm64-msvc@1.0.1': optional: true - '@rolldown/binding-win32-x64-msvc@1.0.0-rc.17': + '@rolldown/binding-win32-x64-msvc@1.0.1': optional: true - '@rolldown/pluginutils@1.0.0-rc.17': {} + '@rolldown/pluginutils@1.0.1': {} - '@rollup/pluginutils@5.3.0(rollup@4.55.1)': + '@rollup/pluginutils@5.3.0(rollup@4.60.4)': dependencies: - '@types/estree': 1.0.8 + '@types/estree': 1.0.9 estree-walker: 2.0.2 picomatch: 4.0.4 optionalDependencies: - rollup: 4.55.1 + rollup: 4.60.4 - '@rollup/rollup-android-arm-eabi@4.55.1': + '@rollup/rollup-android-arm-eabi@4.60.4': optional: true - '@rollup/rollup-android-arm64@4.55.1': + '@rollup/rollup-android-arm64@4.60.4': optional: true - '@rollup/rollup-darwin-arm64@4.55.1': + '@rollup/rollup-darwin-arm64@4.60.4': optional: true - '@rollup/rollup-darwin-x64@4.55.1': + '@rollup/rollup-darwin-x64@4.60.4': optional: true - '@rollup/rollup-freebsd-arm64@4.55.1': + '@rollup/rollup-freebsd-arm64@4.60.4': optional: true - '@rollup/rollup-freebsd-x64@4.55.1': + '@rollup/rollup-freebsd-x64@4.60.4': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.55.1': + '@rollup/rollup-linux-arm-gnueabihf@4.60.4': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.55.1': + '@rollup/rollup-linux-arm-musleabihf@4.60.4': optional: true - '@rollup/rollup-linux-arm64-gnu@4.55.1': + '@rollup/rollup-linux-arm64-gnu@4.60.4': optional: true - '@rollup/rollup-linux-arm64-musl@4.55.1': + '@rollup/rollup-linux-arm64-musl@4.60.4': optional: true - '@rollup/rollup-linux-loong64-gnu@4.55.1': + '@rollup/rollup-linux-loong64-gnu@4.60.4': optional: true - '@rollup/rollup-linux-loong64-musl@4.55.1': + '@rollup/rollup-linux-loong64-musl@4.60.4': optional: true - '@rollup/rollup-linux-ppc64-gnu@4.55.1': + '@rollup/rollup-linux-ppc64-gnu@4.60.4': optional: true - '@rollup/rollup-linux-ppc64-musl@4.55.1': + '@rollup/rollup-linux-ppc64-musl@4.60.4': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.55.1': + '@rollup/rollup-linux-riscv64-gnu@4.60.4': optional: true - '@rollup/rollup-linux-riscv64-musl@4.55.1': + '@rollup/rollup-linux-riscv64-musl@4.60.4': optional: true - '@rollup/rollup-linux-s390x-gnu@4.55.1': + '@rollup/rollup-linux-s390x-gnu@4.60.4': optional: true - '@rollup/rollup-linux-x64-gnu@4.55.1': + '@rollup/rollup-linux-x64-gnu@4.60.4': optional: true - '@rollup/rollup-linux-x64-musl@4.55.1': + '@rollup/rollup-linux-x64-musl@4.60.4': optional: true - '@rollup/rollup-openbsd-x64@4.55.1': + '@rollup/rollup-openbsd-x64@4.60.4': optional: true - '@rollup/rollup-openharmony-arm64@4.55.1': + '@rollup/rollup-openharmony-arm64@4.60.4': optional: true - '@rollup/rollup-win32-arm64-msvc@4.55.1': + '@rollup/rollup-win32-arm64-msvc@4.60.4': optional: true - '@rollup/rollup-win32-ia32-msvc@4.55.1': + '@rollup/rollup-win32-ia32-msvc@4.60.4': optional: true - '@rollup/rollup-win32-x64-gnu@4.55.1': + '@rollup/rollup-win32-x64-gnu@4.60.4': optional: true - '@rollup/rollup-win32-x64-msvc@4.55.1': + '@rollup/rollup-win32-x64-msvc@4.60.4': optional: true '@scarf/scarf@1.4.0': {} @@ -17220,19 +17821,19 @@ snapshots: '@sideway/pinpoint@2.0.0': {} - '@sinclair/typebox@0.27.8': {} + '@sinclair/typebox@0.27.10': {} '@sindresorhus/is@4.6.0': {} '@sindresorhus/is@5.6.0': {} - '@slorber/react-helmet-async@1.3.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + '@slorber/react-helmet-async@1.3.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': dependencies: - '@babel/runtime': 7.29.2 + '@babel/runtime': 7.29.7 invariant: 2.2.4 prop-types: 15.8.1 - react: 19.2.5 - react-dom: 19.2.5(react@19.2.5) + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) react-fast-compare: 3.2.2 shallowequal: 1.1.0 @@ -17244,11 +17845,11 @@ snapshots: '@socket.io/component-emitter@3.1.2': {} - '@socket.io/redis-adapter@8.3.0(socket.io-adapter@2.5.6)': + '@socket.io/redis-adapter@8.3.0(socket.io-adapter@2.5.7)': dependencies: debug: 4.3.7 notepack.io: 3.0.1 - socket.io-adapter: 2.5.6 + socket.io-adapter: 2.5.7 uid2: 1.0.0 transitivePeerDependencies: - supports-color @@ -17257,33 +17858,32 @@ snapshots: '@standard-schema/spec@1.1.0': {} - '@sveltejs/acorn-typescript@1.0.9(acorn@8.16.0)': + '@sveltejs/acorn-typescript@1.0.10(acorn@8.16.0)': dependencies: acorn: 8.16.0 - '@sveltejs/adapter-static@3.0.10(@sveltejs/kit@2.57.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.55.8)(vite@8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)))(svelte@5.55.8)(typescript@6.0.3)(vite@8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)))': + '@sveltejs/adapter-static@3.0.10(@sveltejs/kit@2.60.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.1.2(svelte@5.55.8(@typescript-eslint/types@8.59.4))(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0)))(svelte@5.55.8(@typescript-eslint/types@8.59.4))(typescript@6.0.3)(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0)))': dependencies: - '@sveltejs/kit': 2.57.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.55.8)(vite@8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)))(svelte@5.55.8)(typescript@6.0.3)(vite@8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)) + '@sveltejs/kit': 2.60.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.1.2(svelte@5.55.8(@typescript-eslint/types@8.59.4))(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0)))(svelte@5.55.8(@typescript-eslint/types@8.59.4))(typescript@6.0.3)(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0)) - '@sveltejs/enhanced-img@0.10.4(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.55.8)(vite@8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)))(rollup@4.55.1)(svelte@5.55.8)(vite@8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))': + '@sveltejs/enhanced-img@0.10.4(@sveltejs/vite-plugin-svelte@7.1.2(svelte@5.55.8(@typescript-eslint/types@8.59.4))(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0)))(rollup@4.60.4)(svelte@5.55.8(@typescript-eslint/types@8.59.4))(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0))': dependencies: - '@sveltejs/vite-plugin-svelte': 7.0.0(svelte@5.55.8)(vite@8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)) + '@sveltejs/vite-plugin-svelte': 7.1.2(svelte@5.55.8(@typescript-eslint/types@8.59.4))(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0)) magic-string: 0.30.21 sharp: 0.34.5 - svelte: 5.55.8 - svelte-parse-markup: 0.1.5(svelte@5.55.8) - vite: 8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3) - vite-imagetools: 9.0.3(rollup@4.55.1) + svelte: 5.55.8(@typescript-eslint/types@8.59.4) + svelte-parse-markup: 0.1.5(svelte@5.55.8(@typescript-eslint/types@8.59.4)) + vite: 8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0) + vite-imagetools: 9.0.3(rollup@4.60.4) zimmerframe: 1.1.4 transitivePeerDependencies: - rollup - - supports-color - '@sveltejs/kit@2.57.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.55.8)(vite@8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)))(svelte@5.55.8)(typescript@6.0.3)(vite@8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))': + '@sveltejs/kit@2.60.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.1.2(svelte@5.55.8(@typescript-eslint/types@8.59.4))(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0)))(svelte@5.55.8(@typescript-eslint/types@8.59.4))(typescript@6.0.3)(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0))': dependencies: '@standard-schema/spec': 1.1.0 - '@sveltejs/acorn-typescript': 1.0.9(acorn@8.16.0) - '@sveltejs/vite-plugin-svelte': 7.0.0(svelte@5.55.8)(vite@8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)) + '@sveltejs/acorn-typescript': 1.0.10(acorn@8.16.0) + '@sveltejs/vite-plugin-svelte': 7.1.2(svelte@5.55.8(@typescript-eslint/types@8.59.4))(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0)) '@types/cookie': 0.6.0 acorn: 8.16.0 cookie: 0.6.0 @@ -17294,69 +17894,69 @@ snapshots: mrmime: 2.0.1 set-cookie-parser: 3.1.0 sirv: 3.0.2 - svelte: 5.55.8 - vite: 8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3) + svelte: 5.55.8(@typescript-eslint/types@8.59.4) + vite: 8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0) optionalDependencies: '@opentelemetry/api': 1.9.1 typescript: 6.0.3 - '@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.55.8)(vite@8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))': + '@sveltejs/vite-plugin-svelte@7.1.2(svelte@5.55.8(@typescript-eslint/types@8.59.4))(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0))': dependencies: deepmerge: 4.3.1 magic-string: 0.30.21 obug: 2.1.1 - svelte: 5.55.8 - vite: 8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3) - vitefu: 1.1.2(vite@8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)) + svelte: 5.55.8(@typescript-eslint/types@8.59.4) + vite: 8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0) + vitefu: 1.1.3(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0)) - '@svgr/babel-plugin-add-jsx-attribute@8.0.0(@babel/core@7.28.5)': + '@svgr/babel-plugin-add-jsx-attribute@8.0.0(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.29.0 - '@svgr/babel-plugin-remove-jsx-attribute@8.0.0(@babel/core@7.28.5)': + '@svgr/babel-plugin-remove-jsx-attribute@8.0.0(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.29.0 - '@svgr/babel-plugin-remove-jsx-empty-expression@8.0.0(@babel/core@7.28.5)': + '@svgr/babel-plugin-remove-jsx-empty-expression@8.0.0(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.29.0 - '@svgr/babel-plugin-replace-jsx-attribute-value@8.0.0(@babel/core@7.28.5)': + '@svgr/babel-plugin-replace-jsx-attribute-value@8.0.0(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.29.0 - '@svgr/babel-plugin-svg-dynamic-title@8.0.0(@babel/core@7.28.5)': + '@svgr/babel-plugin-svg-dynamic-title@8.0.0(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.29.0 - '@svgr/babel-plugin-svg-em-dimensions@8.0.0(@babel/core@7.28.5)': + '@svgr/babel-plugin-svg-em-dimensions@8.0.0(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.29.0 - '@svgr/babel-plugin-transform-react-native-svg@8.1.0(@babel/core@7.28.5)': + '@svgr/babel-plugin-transform-react-native-svg@8.1.0(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.29.0 - '@svgr/babel-plugin-transform-svg-component@8.0.0(@babel/core@7.28.5)': + '@svgr/babel-plugin-transform-svg-component@8.0.0(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.29.0 - '@svgr/babel-preset@8.1.0(@babel/core@7.28.5)': + '@svgr/babel-preset@8.1.0(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@svgr/babel-plugin-add-jsx-attribute': 8.0.0(@babel/core@7.28.5) - '@svgr/babel-plugin-remove-jsx-attribute': 8.0.0(@babel/core@7.28.5) - '@svgr/babel-plugin-remove-jsx-empty-expression': 8.0.0(@babel/core@7.28.5) - '@svgr/babel-plugin-replace-jsx-attribute-value': 8.0.0(@babel/core@7.28.5) - '@svgr/babel-plugin-svg-dynamic-title': 8.0.0(@babel/core@7.28.5) - '@svgr/babel-plugin-svg-em-dimensions': 8.0.0(@babel/core@7.28.5) - '@svgr/babel-plugin-transform-react-native-svg': 8.1.0(@babel/core@7.28.5) - '@svgr/babel-plugin-transform-svg-component': 8.0.0(@babel/core@7.28.5) + '@babel/core': 7.29.0 + '@svgr/babel-plugin-add-jsx-attribute': 8.0.0(@babel/core@7.29.0) + '@svgr/babel-plugin-remove-jsx-attribute': 8.0.0(@babel/core@7.29.0) + '@svgr/babel-plugin-remove-jsx-empty-expression': 8.0.0(@babel/core@7.29.0) + '@svgr/babel-plugin-replace-jsx-attribute-value': 8.0.0(@babel/core@7.29.0) + '@svgr/babel-plugin-svg-dynamic-title': 8.0.0(@babel/core@7.29.0) + '@svgr/babel-plugin-svg-em-dimensions': 8.0.0(@babel/core@7.29.0) + '@svgr/babel-plugin-transform-react-native-svg': 8.1.0(@babel/core@7.29.0) + '@svgr/babel-plugin-transform-svg-component': 8.0.0(@babel/core@7.29.0) '@svgr/core@8.1.0(typescript@6.0.3)': dependencies: - '@babel/core': 7.28.5 - '@svgr/babel-preset': 8.1.0(@babel/core@7.28.5) + '@babel/core': 7.29.0 + '@svgr/babel-preset': 8.1.0(@babel/core@7.29.0) camelcase: 6.3.0 cosmiconfig: 8.3.6(typescript@6.0.3) snake-case: 3.0.4 @@ -17371,8 +17971,8 @@ snapshots: '@svgr/plugin-jsx@8.1.0(@svgr/core@8.1.0(typescript@6.0.3))': dependencies: - '@babel/core': 7.28.5 - '@svgr/babel-preset': 8.1.0(@babel/core@7.28.5) + '@babel/core': 7.29.0 + '@svgr/babel-preset': 8.1.0(@babel/core@7.29.0) '@svgr/core': 8.1.0(typescript@6.0.3) '@svgr/hast-util-to-babel-ast': 8.0.0 svg-parser: 2.0.4 @@ -17384,17 +17984,17 @@ snapshots: '@svgr/core': 8.1.0(typescript@6.0.3) cosmiconfig: 8.3.6(typescript@6.0.3) deepmerge: 4.3.1 - svgo: 3.3.2 + svgo: 3.3.3 transitivePeerDependencies: - typescript '@svgr/webpack@8.1.0(typescript@6.0.3)': dependencies: - '@babel/core': 7.28.5 - '@babel/plugin-transform-react-constant-elements': 7.27.1(@babel/core@7.28.5) - '@babel/preset-env': 7.28.5(@babel/core@7.28.5) - '@babel/preset-react': 7.28.5(@babel/core@7.28.5) - '@babel/preset-typescript': 7.28.5(@babel/core@7.28.5) + '@babel/core': 7.29.0 + '@babel/plugin-transform-react-constant-elements': 7.27.1(@babel/core@7.29.0) + '@babel/preset-env': 7.29.5(@babel/core@7.29.0) + '@babel/preset-react': 7.28.5(@babel/core@7.29.0) + '@babel/preset-typescript': 7.28.5(@babel/core@7.29.0) '@svgr/core': 8.1.0(typescript@6.0.3) '@svgr/plugin-jsx': 8.1.0(@svgr/core@8.1.0(typescript@6.0.3)) '@svgr/plugin-svgo': 8.1.0(@svgr/core@8.1.0(typescript@6.0.3))(typescript@6.0.3) @@ -17402,64 +18002,64 @@ snapshots: - supports-color - typescript - '@swc/core-darwin-arm64@1.15.30': + '@swc/core-darwin-arm64@1.15.33': optional: true - '@swc/core-darwin-x64@1.15.30': + '@swc/core-darwin-x64@1.15.33': optional: true - '@swc/core-linux-arm-gnueabihf@1.15.30': + '@swc/core-linux-arm-gnueabihf@1.15.33': optional: true - '@swc/core-linux-arm64-gnu@1.15.30': + '@swc/core-linux-arm64-gnu@1.15.33': optional: true - '@swc/core-linux-arm64-musl@1.15.30': + '@swc/core-linux-arm64-musl@1.15.33': optional: true - '@swc/core-linux-ppc64-gnu@1.15.30': + '@swc/core-linux-ppc64-gnu@1.15.33': optional: true - '@swc/core-linux-s390x-gnu@1.15.30': + '@swc/core-linux-s390x-gnu@1.15.33': optional: true - '@swc/core-linux-x64-gnu@1.15.30': + '@swc/core-linux-x64-gnu@1.15.33': optional: true - '@swc/core-linux-x64-musl@1.15.30': + '@swc/core-linux-x64-musl@1.15.33': optional: true - '@swc/core-win32-arm64-msvc@1.15.30': + '@swc/core-win32-arm64-msvc@1.15.33': optional: true - '@swc/core-win32-ia32-msvc@1.15.30': + '@swc/core-win32-ia32-msvc@1.15.33': optional: true - '@swc/core-win32-x64-msvc@1.15.30': + '@swc/core-win32-x64-msvc@1.15.33': optional: true - '@swc/core@1.15.30(@swc/helpers@0.5.21)': + '@swc/core@1.15.33(@swc/helpers@0.5.22)': dependencies: '@swc/counter': 0.1.3 '@swc/types': 0.1.26 optionalDependencies: - '@swc/core-darwin-arm64': 1.15.30 - '@swc/core-darwin-x64': 1.15.30 - '@swc/core-linux-arm-gnueabihf': 1.15.30 - '@swc/core-linux-arm64-gnu': 1.15.30 - '@swc/core-linux-arm64-musl': 1.15.30 - '@swc/core-linux-ppc64-gnu': 1.15.30 - '@swc/core-linux-s390x-gnu': 1.15.30 - '@swc/core-linux-x64-gnu': 1.15.30 - '@swc/core-linux-x64-musl': 1.15.30 - '@swc/core-win32-arm64-msvc': 1.15.30 - '@swc/core-win32-ia32-msvc': 1.15.30 - '@swc/core-win32-x64-msvc': 1.15.30 - '@swc/helpers': 0.5.21 + '@swc/core-darwin-arm64': 1.15.33 + '@swc/core-darwin-x64': 1.15.33 + '@swc/core-linux-arm-gnueabihf': 1.15.33 + '@swc/core-linux-arm64-gnu': 1.15.33 + '@swc/core-linux-arm64-musl': 1.15.33 + '@swc/core-linux-ppc64-gnu': 1.15.33 + '@swc/core-linux-s390x-gnu': 1.15.33 + '@swc/core-linux-x64-gnu': 1.15.33 + '@swc/core-linux-x64-musl': 1.15.33 + '@swc/core-win32-arm64-msvc': 1.15.33 + '@swc/core-win32-ia32-msvc': 1.15.33 + '@swc/core-win32-x64-msvc': 1.15.33 + '@swc/helpers': 0.5.22 '@swc/counter@0.1.3': {} - '@swc/helpers@0.5.21': + '@swc/helpers@0.5.22': dependencies: tslib: 2.8.1 @@ -17471,80 +18071,80 @@ snapshots: dependencies: defer-to-connect: 2.0.1 - '@tailwindcss/node@4.2.4': + '@tailwindcss/node@4.3.0': dependencies: '@jridgewell/remapping': 2.3.5 - enhanced-resolve: 5.21.0 - jiti: 2.6.1 + enhanced-resolve: 5.21.5 + jiti: 2.7.0 lightningcss: 1.32.0 magic-string: 0.30.21 source-map-js: 1.2.1 - tailwindcss: 4.2.4 + tailwindcss: 4.3.0 - '@tailwindcss/oxide-android-arm64@4.2.4': + '@tailwindcss/oxide-android-arm64@4.3.0': optional: true - '@tailwindcss/oxide-darwin-arm64@4.2.4': + '@tailwindcss/oxide-darwin-arm64@4.3.0': optional: true - '@tailwindcss/oxide-darwin-x64@4.2.4': + '@tailwindcss/oxide-darwin-x64@4.3.0': optional: true - '@tailwindcss/oxide-freebsd-x64@4.2.4': + '@tailwindcss/oxide-freebsd-x64@4.3.0': optional: true - '@tailwindcss/oxide-linux-arm-gnueabihf@4.2.4': + '@tailwindcss/oxide-linux-arm-gnueabihf@4.3.0': optional: true - '@tailwindcss/oxide-linux-arm64-gnu@4.2.4': + '@tailwindcss/oxide-linux-arm64-gnu@4.3.0': optional: true - '@tailwindcss/oxide-linux-arm64-musl@4.2.4': + '@tailwindcss/oxide-linux-arm64-musl@4.3.0': optional: true - '@tailwindcss/oxide-linux-x64-gnu@4.2.4': + '@tailwindcss/oxide-linux-x64-gnu@4.3.0': optional: true - '@tailwindcss/oxide-linux-x64-musl@4.2.4': + '@tailwindcss/oxide-linux-x64-musl@4.3.0': optional: true - '@tailwindcss/oxide-wasm32-wasi@4.2.4': + '@tailwindcss/oxide-wasm32-wasi@4.3.0': optional: true - '@tailwindcss/oxide-win32-arm64-msvc@4.2.4': + '@tailwindcss/oxide-win32-arm64-msvc@4.3.0': optional: true - '@tailwindcss/oxide-win32-x64-msvc@4.2.4': + '@tailwindcss/oxide-win32-x64-msvc@4.3.0': optional: true - '@tailwindcss/oxide@4.2.4': + '@tailwindcss/oxide@4.3.0': optionalDependencies: - '@tailwindcss/oxide-android-arm64': 4.2.4 - '@tailwindcss/oxide-darwin-arm64': 4.2.4 - '@tailwindcss/oxide-darwin-x64': 4.2.4 - '@tailwindcss/oxide-freebsd-x64': 4.2.4 - '@tailwindcss/oxide-linux-arm-gnueabihf': 4.2.4 - '@tailwindcss/oxide-linux-arm64-gnu': 4.2.4 - '@tailwindcss/oxide-linux-arm64-musl': 4.2.4 - '@tailwindcss/oxide-linux-x64-gnu': 4.2.4 - '@tailwindcss/oxide-linux-x64-musl': 4.2.4 - '@tailwindcss/oxide-wasm32-wasi': 4.2.4 - '@tailwindcss/oxide-win32-arm64-msvc': 4.2.4 - '@tailwindcss/oxide-win32-x64-msvc': 4.2.4 + '@tailwindcss/oxide-android-arm64': 4.3.0 + '@tailwindcss/oxide-darwin-arm64': 4.3.0 + '@tailwindcss/oxide-darwin-x64': 4.3.0 + '@tailwindcss/oxide-freebsd-x64': 4.3.0 + '@tailwindcss/oxide-linux-arm-gnueabihf': 4.3.0 + '@tailwindcss/oxide-linux-arm64-gnu': 4.3.0 + '@tailwindcss/oxide-linux-arm64-musl': 4.3.0 + '@tailwindcss/oxide-linux-x64-gnu': 4.3.0 + '@tailwindcss/oxide-linux-x64-musl': 4.3.0 + '@tailwindcss/oxide-wasm32-wasi': 4.3.0 + '@tailwindcss/oxide-win32-arm64-msvc': 4.3.0 + '@tailwindcss/oxide-win32-x64-msvc': 4.3.0 - '@tailwindcss/vite@4.2.4(vite@8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))': + '@tailwindcss/vite@4.3.0(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0))': dependencies: - '@tailwindcss/node': 4.2.4 - '@tailwindcss/oxide': 4.2.4 - tailwindcss: 4.2.4 - vite: 8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3) + '@tailwindcss/node': 4.3.0 + '@tailwindcss/oxide': 4.3.0 + tailwindcss: 4.3.0 + vite: 8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0) '@tanstack/query-core@5.100.9': {} - '@tanstack/svelte-query@6.1.28(svelte@5.55.8)': + '@tanstack/svelte-query@6.1.28(svelte@5.55.8(@typescript-eslint/types@8.59.4))': dependencies: '@tanstack/query-core': 5.100.9 - svelte: 5.55.8 + svelte: 5.55.8(@typescript-eslint/types@8.59.4) '@testing-library/dom@10.4.1': dependencies: @@ -17566,18 +18166,18 @@ snapshots: picocolors: 1.1.1 redent: 3.0.0 - '@testing-library/svelte-core@1.0.0(svelte@5.55.8)': + '@testing-library/svelte-core@1.0.0(svelte@5.55.8(@typescript-eslint/types@8.59.4))': dependencies: - svelte: 5.55.8 + svelte: 5.55.8(@typescript-eslint/types@8.59.4) - '@testing-library/svelte@5.3.1(svelte@5.55.8)(vite@8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))(vitest@4.1.5)': + '@testing-library/svelte@5.3.1(svelte@5.55.8(@typescript-eslint/types@8.59.4))(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0))(vitest@4.1.7)': dependencies: '@testing-library/dom': 10.4.1 - '@testing-library/svelte-core': 1.0.0(svelte@5.55.8) - svelte: 5.55.8 + '@testing-library/svelte-core': 1.0.0(svelte@5.55.8(@typescript-eslint/types@8.59.4)) + svelte: 5.55.8(@typescript-eslint/types@8.59.4) optionalDependencies: - vite: 8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3) - vitest: 4.1.5(@opentelemetry/api@1.9.1)(@types/node@25.6.0)(@vitest/coverage-v8@4.1.5)(happy-dom@20.9.0)(jsdom@26.1.0(canvas@3.2.3))(vite@8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)) + vite: 8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0) + vitest: 4.1.7(@opentelemetry/api@1.9.1)(@types/node@24.12.4)(@vitest/coverage-v8@4.1.7)(happy-dom@20.9.0)(jsdom@26.1.0(canvas@3.2.3))(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0)) '@testing-library/user-event@14.6.1(@testing-library/dom@10.4.1)': dependencies: @@ -17592,10 +18192,10 @@ snapshots: '@tokenizer/token@0.3.0': {} - '@trivago/prettier-plugin-sort-imports@6.0.2(prettier-plugin-svelte@3.5.1(prettier@3.8.3)(svelte@5.55.8))(prettier@3.8.3)(svelte@5.55.8)': + '@trivago/prettier-plugin-sort-imports@6.0.2(prettier-plugin-svelte@3.5.2(prettier@3.8.3)(svelte@5.55.8(@typescript-eslint/types@8.59.4)))(prettier@3.8.3)(svelte@5.55.8(@typescript-eslint/types@8.59.4))': dependencies: '@babel/generator': 7.29.1 - '@babel/parser': 7.29.2 + '@babel/parser': 7.29.3 '@babel/traverse': 7.29.0 '@babel/types': 7.29.0 javascript-natural-sort: 0.7.1 @@ -17604,40 +18204,38 @@ snapshots: parse-imports-exports: 0.2.4 prettier: 3.8.3 optionalDependencies: - prettier-plugin-svelte: 3.5.1(prettier@3.8.3)(svelte@5.55.8) - svelte: 5.55.8 + prettier-plugin-svelte: 3.5.2(prettier@3.8.3)(svelte@5.55.8(@typescript-eslint/types@8.59.4)) + svelte: 5.55.8(@typescript-eslint/types@8.59.4) transitivePeerDependencies: - supports-color - '@trysound/sax@0.2.0': {} - - '@turf/boolean-point-in-polygon@7.3.4': + '@turf/boolean-point-in-polygon@7.3.5': dependencies: - '@turf/helpers': 7.3.4 - '@turf/invariant': 7.3.4 + '@turf/helpers': 7.3.5 + '@turf/invariant': 7.3.5 '@types/geojson': 7946.0.16 point-in-polygon-hao: 1.2.4 tslib: 2.8.1 - '@turf/helpers@7.3.4': + '@turf/helpers@7.3.5': dependencies: '@types/geojson': 7946.0.16 tslib: 2.8.1 - '@turf/invariant@7.3.4': + '@turf/invariant@7.3.5': dependencies: - '@turf/helpers': 7.3.4 + '@turf/helpers': 7.3.5 '@types/geojson': 7946.0.16 tslib: 2.8.1 - '@tybys/wasm-util@0.10.1': + '@tybys/wasm-util@0.10.2': dependencies: tslib: 2.8.1 optional: true '@types/accepts@1.3.7': dependencies: - '@types/node': 24.12.2 + '@types/node': 24.12.4 '@types/archiver@7.0.0': dependencies: @@ -17649,16 +18247,16 @@ snapshots: '@types/bcrypt@6.0.0': dependencies: - '@types/node': 24.12.2 + '@types/node': 24.12.4 '@types/body-parser@1.19.6': dependencies: '@types/connect': 3.4.38 - '@types/node': 24.12.2 + '@types/node': 24.12.4 '@types/bonjour@3.5.13': dependencies: - '@types/node': 24.12.2 + '@types/node': 24.12.4 '@types/braces@3.0.5': {} @@ -17669,32 +18267,32 @@ snapshots: '@types/deep-eql': 4.0.2 assertion-error: 2.0.1 - '@types/chrome@0.1.32': + '@types/chrome@0.1.42': dependencies: '@types/filesystem': 0.0.36 '@types/har-format': 1.2.16 '@types/chromecast-caf-sender@1.0.11': dependencies: - '@types/chrome': 0.1.32 + '@types/chrome': 0.1.42 '@types/cli-progress@3.11.6': dependencies: - '@types/node': 24.12.2 + '@types/node': 24.12.4 '@types/compression@1.8.1': dependencies: '@types/express': 5.0.6 - '@types/node': 24.12.2 + '@types/node': 24.12.4 '@types/connect-history-api-fallback@1.5.4': dependencies: - '@types/express-serve-static-core': 5.1.0 - '@types/node': 24.12.2 + '@types/express-serve-static-core': 5.1.1 + '@types/node': 24.12.4 '@types/connect@3.4.38': dependencies: - '@types/node': 24.12.2 + '@types/node': 24.12.4 '@types/content-disposition@0.5.9': {} @@ -17711,11 +18309,11 @@ snapshots: '@types/connect': 3.4.38 '@types/express': 5.0.6 '@types/keygrip': 1.0.6 - '@types/node': 24.12.2 + '@types/node': 24.12.4 '@types/cors@2.8.19': dependencies: - '@types/node': 24.12.2 + '@types/node': 24.12.4 '@types/d3-array@3.2.2': {} @@ -17834,7 +18432,7 @@ snapshots: '@types/d3-transition': 3.0.9 '@types/d3-zoom': 3.0.8 - '@types/debug@4.1.12': + '@types/debug@4.1.13': dependencies: '@types/ms': 2.1.0 @@ -17842,13 +18440,13 @@ snapshots: '@types/docker-modem@3.0.6': dependencies: - '@types/node': 24.12.2 + '@types/node': 24.12.4 '@types/ssh2': 1.15.5 '@types/dockerode@4.0.1': dependencies: '@types/docker-modem': 3.0.6 - '@types/node': 24.12.2 + '@types/node': 24.12.4 '@types/ssh2': 1.15.5 '@types/dom-to-image@2.6.7': {} @@ -17856,46 +18454,48 @@ snapshots: '@types/eslint-scope@3.7.7': dependencies: '@types/eslint': 9.6.1 - '@types/estree': 1.0.8 + '@types/estree': 1.0.9 '@types/eslint@9.6.1': dependencies: - '@types/estree': 1.0.8 + '@types/estree': 1.0.9 '@types/json-schema': 7.0.15 '@types/esrecurse@4.3.1': {} '@types/estree-jsx@1.0.5': dependencies: - '@types/estree': 1.0.8 + '@types/estree': 1.0.9 '@types/estree@1.0.8': {} - '@types/express-serve-static-core@4.19.7': + '@types/estree@1.0.9': {} + + '@types/express-serve-static-core@4.19.8': dependencies: - '@types/node': 24.12.2 - '@types/qs': 6.14.0 + '@types/node': 24.12.4 + '@types/qs': 6.15.1 '@types/range-parser': 1.2.7 '@types/send': 1.2.1 - '@types/express-serve-static-core@5.1.0': + '@types/express-serve-static-core@5.1.1': dependencies: - '@types/node': 24.12.2 - '@types/qs': 6.14.0 + '@types/node': 24.12.4 + '@types/qs': 6.15.1 '@types/range-parser': 1.2.7 '@types/send': 1.2.1 '@types/express@4.17.25': dependencies: '@types/body-parser': 1.19.6 - '@types/express-serve-static-core': 4.19.7 - '@types/qs': 6.14.0 + '@types/express-serve-static-core': 4.19.8 + '@types/qs': 6.15.1 '@types/serve-static': 1.15.10 '@types/express@5.0.6': dependencies: '@types/body-parser': 1.19.6 - '@types/express-serve-static-core': 5.1.0 + '@types/express-serve-static-core': 5.1.1 '@types/serve-static': 2.2.0 '@types/filesystem@0.0.36': @@ -17906,7 +18506,7 @@ snapshots: '@types/fluent-ffmpeg@2.1.28': dependencies: - '@types/node': 24.12.2 + '@types/node': 24.12.4 '@types/geojson@7946.0.16': {} @@ -17928,13 +18528,13 @@ snapshots: '@types/http-assert@1.5.6': {} - '@types/http-cache-semantics@4.0.4': {} + '@types/http-cache-semantics@4.2.0': {} '@types/http-errors@2.0.5': {} '@types/http-proxy@1.17.17': dependencies: - '@types/node': 24.12.2 + '@types/node': 24.12.4 '@types/inquirer@8.2.12': dependencies: @@ -17958,7 +18558,7 @@ snapshots: '@types/jsonwebtoken@9.0.10': dependencies: '@types/ms': 2.1.0 - '@types/node': 24.12.2 + '@types/node': 24.12.4 '@types/justified-layout@4.1.4': {} @@ -17966,9 +18566,9 @@ snapshots: '@types/koa-compose@3.2.9': dependencies: - '@types/koa': 3.0.1 + '@types/koa': 3.0.3 - '@types/koa@3.0.1': + '@types/koa@3.0.3': dependencies: '@types/accepts': 1.3.7 '@types/content-disposition': 0.5.9 @@ -17977,7 +18577,7 @@ snapshots: '@types/http-errors': 2.0.5 '@types/keygrip': 1.0.6 '@types/koa-compose': 3.2.9 - '@types/node': 24.12.2 + '@types/node': 24.12.4 '@types/leaflet@1.9.21': dependencies: @@ -18007,7 +18607,7 @@ snapshots: '@types/mock-fs@4.13.4': dependencies: - '@types/node': 24.12.2 + '@types/node': 24.12.4 '@types/ms@2.1.0': {} @@ -18015,34 +18615,25 @@ snapshots: dependencies: '@types/express': 5.0.6 - '@types/node-forge@1.3.14': - dependencies: - '@types/node': 24.12.2 - '@types/node@17.0.45': {} '@types/node@18.19.130': dependencies: undici-types: 5.26.5 - '@types/node@24.12.2': + '@types/node@24.12.4': dependencies: undici-types: 7.16.0 - '@types/node@25.6.0': - dependencies: - undici-types: 7.19.2 - optional: true - '@types/nodemailer@8.0.0': dependencies: - '@types/node': 24.12.2 + '@types/node': 24.12.4 '@types/oidc-provider@9.5.0': dependencies: '@types/keygrip': 1.0.6 - '@types/koa': 3.0.1 - '@types/node': 24.12.2 + '@types/koa': 3.0.3 + '@types/node': 24.12.4 '@types/parse5@5.0.3': {} @@ -18052,73 +18643,73 @@ snapshots: '@types/pg@8.15.6': dependencies: - '@types/node': 24.12.2 - pg-protocol: 1.13.0 + '@types/node': 24.12.4 + pg-protocol: 1.14.0 pg-types: 2.2.0 '@types/pg@8.20.0': dependencies: - '@types/node': 24.12.2 - pg-protocol: 1.13.0 + '@types/node': 24.12.4 + pg-protocol: 1.14.0 pg-types: 2.2.0 '@types/picomatch@4.0.3': {} '@types/pngjs@6.0.5': dependencies: - '@types/node': 24.12.2 + '@types/node': 24.12.4 - '@types/prismjs@1.26.5': {} + '@types/prismjs@1.26.6': {} '@types/qrcode@1.5.6': dependencies: - '@types/node': 24.12.2 + '@types/node': 24.12.4 - '@types/qs@6.14.0': {} + '@types/qs@6.15.1': {} '@types/range-parser@1.2.7': {} '@types/react-router-config@5.0.11': dependencies: '@types/history': 4.7.11 - '@types/react': 19.2.14 + '@types/react': 19.2.15 '@types/react-router': 5.1.20 '@types/react-router-dom@5.3.3': dependencies: '@types/history': 4.7.11 - '@types/react': 19.2.14 + '@types/react': 19.2.15 '@types/react-router': 5.1.20 '@types/react-router@5.1.20': dependencies: '@types/history': 4.7.11 - '@types/react': 19.2.14 + '@types/react': 19.2.15 - '@types/react@19.2.14': + '@types/react@19.2.15': dependencies: csstype: 3.2.3 '@types/readdir-glob@1.1.5': dependencies: - '@types/node': 24.12.2 + '@types/node': 24.12.4 '@types/retry@0.12.2': {} '@types/sax@1.2.7': dependencies: - '@types/node': 24.12.2 + '@types/node': 24.12.4 '@types/semver@7.7.1': {} '@types/send@0.17.6': dependencies: '@types/mime': 1.3.5 - '@types/node': 24.12.2 + '@types/node': 24.12.4 '@types/send@1.2.1': dependencies: - '@types/node': 24.12.2 + '@types/node': 24.12.4 '@types/serve-index@1.9.4': dependencies: @@ -18127,36 +18718,36 @@ snapshots: '@types/serve-static@1.15.10': dependencies: '@types/http-errors': 2.0.5 - '@types/node': 24.12.2 + '@types/node': 24.12.4 '@types/send': 0.17.6 '@types/serve-static@2.2.0': dependencies: '@types/http-errors': 2.0.5 - '@types/node': 24.12.2 + '@types/node': 24.12.4 '@types/sockjs@0.3.36': dependencies: - '@types/node': 24.12.2 + '@types/node': 24.12.4 '@types/ssh2-streams@0.1.13': dependencies: - '@types/node': 24.12.2 + '@types/node': 24.12.4 '@types/ssh2@0.5.52': dependencies: - '@types/node': 24.12.2 + '@types/node': 24.12.4 '@types/ssh2-streams': 0.1.13 '@types/ssh2@1.15.5': dependencies: '@types/node': 18.19.130 - '@types/superagent@8.1.9': + '@types/superagent@8.1.10': dependencies: '@types/cookiejar': 2.1.5 '@types/methods': 1.1.4 - '@types/node': 24.12.2 + '@types/node': 24.12.4 form-data: 4.0.5 '@types/supercluster@7.1.3': @@ -18166,11 +18757,11 @@ snapshots: '@types/supertest@7.2.0': dependencies: '@types/methods': 1.1.4 - '@types/superagent': 8.1.9 + '@types/superagent': 8.1.10 '@types/through@0.0.33': dependencies: - '@types/node': 24.12.2 + '@types/node': 24.12.4 '@types/trusted-types@2.0.7': {} @@ -18186,7 +18777,7 @@ snapshots: '@types/ws@8.18.1': dependencies: - '@types/node': 24.12.2 + '@types/node': 24.12.4 '@types/yargs-parser@21.0.3': {} @@ -18194,15 +18785,15 @@ snapshots: dependencies: '@types/yargs-parser': 21.0.3 - '@typescript-eslint/eslint-plugin@8.59.0(@typescript-eslint/parser@8.59.0(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3))(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3)': + '@typescript-eslint/eslint-plugin@8.59.4(@typescript-eslint/parser@8.59.4(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3)': dependencies: '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 8.59.0(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3) - '@typescript-eslint/scope-manager': 8.59.0 - '@typescript-eslint/type-utils': 8.59.0(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3) - '@typescript-eslint/utils': 8.59.0(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3) - '@typescript-eslint/visitor-keys': 8.59.0 - eslint: 10.2.1(jiti@2.6.1) + '@typescript-eslint/parser': 8.59.4(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3) + '@typescript-eslint/scope-manager': 8.59.4 + '@typescript-eslint/type-utils': 8.59.4(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3) + '@typescript-eslint/utils': 8.59.4(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3) + '@typescript-eslint/visitor-keys': 8.59.4 + eslint: 10.4.0(jiti@2.7.0) ignore: 7.0.5 natural-compare: 1.4.0 ts-api-utils: 2.5.0(typescript@6.0.3) @@ -18210,90 +18801,93 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.59.0(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3)': + '@typescript-eslint/parser@8.59.4(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3)': dependencies: - '@typescript-eslint/scope-manager': 8.59.0 - '@typescript-eslint/types': 8.59.0 - '@typescript-eslint/typescript-estree': 8.59.0(typescript@6.0.3) - '@typescript-eslint/visitor-keys': 8.59.0 + '@typescript-eslint/scope-manager': 8.59.4 + '@typescript-eslint/types': 8.59.4 + '@typescript-eslint/typescript-estree': 8.59.4(typescript@6.0.3) + '@typescript-eslint/visitor-keys': 8.59.4 debug: 4.4.3 - eslint: 10.2.1(jiti@2.6.1) + eslint: 10.4.0(jiti@2.7.0) typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/project-service@8.59.0(typescript@6.0.3)': + '@typescript-eslint/project-service@8.59.4(typescript@6.0.3)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.59.0(typescript@6.0.3) - '@typescript-eslint/types': 8.59.0 + '@typescript-eslint/tsconfig-utils': 8.59.4(typescript@6.0.3) + '@typescript-eslint/types': 8.59.4 debug: 4.4.3 typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@8.59.0': + '@typescript-eslint/scope-manager@8.59.4': dependencies: - '@typescript-eslint/types': 8.59.0 - '@typescript-eslint/visitor-keys': 8.59.0 + '@typescript-eslint/types': 8.59.4 + '@typescript-eslint/visitor-keys': 8.59.4 - '@typescript-eslint/tsconfig-utils@8.59.0(typescript@6.0.3)': + '@typescript-eslint/tsconfig-utils@8.59.4(typescript@6.0.3)': dependencies: typescript: 6.0.3 - '@typescript-eslint/type-utils@8.59.0(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3)': + '@typescript-eslint/type-utils@8.59.4(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3)': dependencies: - '@typescript-eslint/types': 8.59.0 - '@typescript-eslint/typescript-estree': 8.59.0(typescript@6.0.3) - '@typescript-eslint/utils': 8.59.0(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3) + '@typescript-eslint/types': 8.59.4 + '@typescript-eslint/typescript-estree': 8.59.4(typescript@6.0.3) + '@typescript-eslint/utils': 8.59.4(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3) debug: 4.4.3 - eslint: 10.2.1(jiti@2.6.1) + eslint: 10.4.0(jiti@2.7.0) ts-api-utils: 2.5.0(typescript@6.0.3) typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/types@8.59.0': {} + '@typescript-eslint/types@8.59.4': {} - '@typescript-eslint/typescript-estree@8.59.0(typescript@6.0.3)': + '@typescript-eslint/typescript-estree@8.59.4(typescript@6.0.3)': dependencies: - '@typescript-eslint/project-service': 8.59.0(typescript@6.0.3) - '@typescript-eslint/tsconfig-utils': 8.59.0(typescript@6.0.3) - '@typescript-eslint/types': 8.59.0 - '@typescript-eslint/visitor-keys': 8.59.0 + '@typescript-eslint/project-service': 8.59.4(typescript@6.0.3) + '@typescript-eslint/tsconfig-utils': 8.59.4(typescript@6.0.3) + '@typescript-eslint/types': 8.59.4 + '@typescript-eslint/visitor-keys': 8.59.4 debug: 4.4.3 minimatch: 10.2.5 - semver: 7.7.4 + semver: 7.8.0 tinyglobby: 0.2.16 ts-api-utils: 2.5.0(typescript@6.0.3) typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.59.0(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3)': + '@typescript-eslint/utils@8.59.4(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3)': dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@10.2.1(jiti@2.6.1)) - '@typescript-eslint/scope-manager': 8.59.0 - '@typescript-eslint/types': 8.59.0 - '@typescript-eslint/typescript-estree': 8.59.0(typescript@6.0.3) - eslint: 10.2.1(jiti@2.6.1) + '@eslint-community/eslint-utils': 4.9.1(eslint@10.4.0(jiti@2.7.0)) + '@typescript-eslint/scope-manager': 8.59.4 + '@typescript-eslint/types': 8.59.4 + '@typescript-eslint/typescript-estree': 8.59.4(typescript@6.0.3) + eslint: 10.4.0(jiti@2.7.0) typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/visitor-keys@8.59.0': + '@typescript-eslint/visitor-keys@8.59.4': dependencies: - '@typescript-eslint/types': 8.59.0 + '@typescript-eslint/types': 8.59.4 eslint-visitor-keys: 5.0.1 - '@ungap/structured-clone@1.3.0': {} + '@ungap/structured-clone@1.3.1': {} - '@valibot/to-json-schema@1.6.0(valibot@1.3.1(typescript@6.0.3))': + '@upsetjs/venn.js@2.0.0': + optionalDependencies: + d3-selection: 3.0.0 + d3-transition: 3.0.1(d3-selection@3.0.0) + + '@valibot/to-json-schema@1.7.0(valibot@1.4.0(typescript@6.0.3))': dependencies: - valibot: 1.3.1(typescript@6.0.3) + valibot: 1.4.0(typescript@6.0.3) - '@vercel/oidc@3.0.5': {} - - '@vitest/coverage-v8@3.2.4(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.12.2)(happy-dom@20.9.0)(jiti@2.6.1)(jsdom@26.1.0(canvas@3.2.3))(lightningcss@1.32.0)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))': + '@vitest/coverage-v8@3.2.4(vitest@3.2.4(@types/debug@4.1.13)(@types/node@24.12.4)(happy-dom@20.9.0)(jiti@2.7.0)(jsdom@26.1.0(canvas@3.2.3))(lightningcss@1.32.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0))': dependencies: '@ampproject/remapping': 2.3.0 '@bcoe/v8-coverage': 1.0.2 @@ -18308,23 +18902,23 @@ snapshots: std-env: 3.10.0 test-exclude: 7.0.2 tinyrainbow: 2.0.0 - vitest: 3.2.4(@types/debug@4.1.12)(@types/node@24.12.2)(happy-dom@20.9.0)(jiti@2.6.1)(jsdom@26.1.0(canvas@3.2.3))(lightningcss@1.32.0)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3) + vitest: 3.2.4(@types/debug@4.1.13)(@types/node@24.12.4)(happy-dom@20.9.0)(jiti@2.7.0)(jsdom@26.1.0(canvas@3.2.3))(lightningcss@1.32.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0) transitivePeerDependencies: - supports-color - '@vitest/coverage-v8@4.1.5(vitest@4.1.5)': + '@vitest/coverage-v8@4.1.7(vitest@4.1.7)': dependencies: '@bcoe/v8-coverage': 1.0.2 - '@vitest/utils': 4.1.5 + '@vitest/utils': 4.1.7 ast-v8-to-istanbul: 1.0.0 istanbul-lib-coverage: 3.2.2 istanbul-lib-report: 3.0.1 istanbul-reports: 3.2.0 - magicast: 0.5.2 + magicast: 0.5.3 obug: 2.1.1 std-env: 4.1.0 tinyrainbow: 3.1.0 - vitest: 4.1.5(@opentelemetry/api@1.9.1)(@types/node@24.12.2)(@vitest/coverage-v8@4.1.5)(happy-dom@20.9.0)(jsdom@26.1.0(canvas@3.2.3))(vite@8.0.10(@types/node@24.12.2)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)) + vitest: 4.1.7(@opentelemetry/api@1.9.1)(@types/node@24.12.4)(@vitest/coverage-v8@4.1.7)(happy-dom@20.9.0)(jsdom@26.1.0(canvas@3.2.3))(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0)) '@vitest/expect@3.2.4': dependencies: @@ -18334,44 +18928,36 @@ snapshots: chai: 5.3.3 tinyrainbow: 2.0.0 - '@vitest/expect@4.1.5': + '@vitest/expect@4.1.7': dependencies: '@standard-schema/spec': 1.1.0 '@types/chai': 5.2.3 - '@vitest/spy': 4.1.5 - '@vitest/utils': 4.1.5 + '@vitest/spy': 4.1.7 + '@vitest/utils': 4.1.7 chai: 6.2.2 tinyrainbow: 3.1.0 - '@vitest/mocker@3.2.4(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))': + '@vitest/mocker@3.2.4(vite@7.3.3(@types/node@24.12.4)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0))': dependencies: '@vitest/spy': 3.2.4 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3) + vite: 7.3.3(@types/node@24.12.4)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0) - '@vitest/mocker@4.1.5(vite@8.0.10(@types/node@24.12.2)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))': + '@vitest/mocker@4.1.7(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0))': dependencies: - '@vitest/spy': 4.1.5 + '@vitest/spy': 4.1.7 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 8.0.10(@types/node@24.12.2)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3) - - '@vitest/mocker@4.1.5(vite@8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))': - dependencies: - '@vitest/spy': 4.1.5 - estree-walker: 3.0.3 - magic-string: 0.30.21 - optionalDependencies: - vite: 8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3) + vite: 8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0) '@vitest/pretty-format@3.2.4': dependencies: tinyrainbow: 2.0.0 - '@vitest/pretty-format@4.1.5': + '@vitest/pretty-format@4.1.7': dependencies: tinyrainbow: 3.1.0 @@ -18381,9 +18967,9 @@ snapshots: pathe: 2.0.3 strip-literal: 3.1.0 - '@vitest/runner@4.1.5': + '@vitest/runner@4.1.7': dependencies: - '@vitest/utils': 4.1.5 + '@vitest/utils': 4.1.7 pathe: 2.0.3 '@vitest/snapshot@3.2.4': @@ -18392,10 +18978,10 @@ snapshots: magic-string: 0.30.21 pathe: 2.0.3 - '@vitest/snapshot@4.1.5': + '@vitest/snapshot@4.1.7': dependencies: - '@vitest/pretty-format': 4.1.5 - '@vitest/utils': 4.1.5 + '@vitest/pretty-format': 4.1.7 + '@vitest/utils': 4.1.7 magic-string: 0.30.21 pathe: 2.0.3 @@ -18403,7 +18989,7 @@ snapshots: dependencies: tinyspy: 4.0.4 - '@vitest/spy@4.1.5': {} + '@vitest/spy@4.1.7': {} '@vitest/utils@3.2.4': dependencies: @@ -18411,9 +18997,9 @@ snapshots: loupe: 3.2.1 tinyrainbow: 2.0.0 - '@vitest/utils@4.1.5': + '@vitest/utils@4.1.7': dependencies: - '@vitest/pretty-format': 4.1.5 + '@vitest/pretty-format': 4.1.7 convert-source-map: 2.0.0 tinyrainbow: 3.1.0 @@ -18501,10 +19087,10 @@ snapshots: dependencies: '@namnode/store': 0.1.0 - '@zoom-image/svelte@0.3.9(svelte@5.55.8)': + '@zoom-image/svelte@0.3.9(svelte@5.55.8(@typescript-eslint/types@8.59.4))': dependencies: '@zoom-image/core': 0.42.0 - svelte: 5.55.8 + svelte: 5.55.8(@typescript-eslint/types@8.59.4) abbrev@1.1.1: {} @@ -18536,7 +19122,7 @@ snapshots: dependencies: acorn: 8.16.0 - acorn-walk@8.3.4: + acorn-walk@8.3.5: dependencies: acorn: 8.16.0 @@ -18550,39 +19136,36 @@ snapshots: transitivePeerDependencies: - supports-color - agent-base@7.1.4: {} + agent-base@7.1.4: + optional: true aggregate-error@3.1.0: dependencies: clean-stack: 2.2.0 indent-string: 4.0.0 - ai@5.0.113(zod@4.3.6): - dependencies: - '@ai-sdk/gateway': 2.0.21(zod@4.3.6) - '@ai-sdk/provider': 2.0.0 - '@ai-sdk/provider-utils': 3.0.19(zod@4.3.6) - '@opentelemetry/api': 1.9.0 - zod: 4.3.6 - - ajv-formats@2.1.1(ajv@8.18.0): + ajv-formats@2.1.1(ajv@8.20.0): optionalDependencies: - ajv: 8.18.0 + ajv: 8.20.0 ajv-formats@3.0.1(ajv@8.18.0): optionalDependencies: ajv: 8.18.0 - ajv-keywords@3.5.2(ajv@6.14.0): - dependencies: - ajv: 6.14.0 + ajv-formats@3.0.1(ajv@8.20.0): + optionalDependencies: + ajv: 8.20.0 - ajv-keywords@5.1.0(ajv@8.18.0): + ajv-keywords@3.5.2(ajv@6.15.0): dependencies: - ajv: 8.18.0 + ajv: 6.15.0 + + ajv-keywords@5.1.0(ajv@8.20.0): + dependencies: + ajv: 8.20.0 fast-deep-equal: 3.1.3 - ajv@6.14.0: + ajv@6.15.0: dependencies: fast-deep-equal: 3.1.3 fast-json-stable-stringify: 2.1.0 @@ -18592,31 +19175,38 @@ snapshots: ajv@8.18.0: dependencies: fast-deep-equal: 3.1.3 - fast-uri: 3.1.0 + fast-uri: 3.1.2 json-schema-traverse: 1.0.0 require-from-string: 2.0.2 - algoliasearch-helper@3.26.1(algoliasearch@5.46.0): + ajv@8.20.0: + dependencies: + fast-deep-equal: 3.1.3 + fast-uri: 3.1.2 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + + algoliasearch-helper@3.29.1(algoliasearch@5.52.1): dependencies: '@algolia/events': 4.0.1 - algoliasearch: 5.46.0 + algoliasearch: 5.52.1 - algoliasearch@5.46.0: + algoliasearch@5.52.1: dependencies: - '@algolia/abtesting': 1.12.0 - '@algolia/client-abtesting': 5.46.0 - '@algolia/client-analytics': 5.46.0 - '@algolia/client-common': 5.46.0 - '@algolia/client-insights': 5.46.0 - '@algolia/client-personalization': 5.46.0 - '@algolia/client-query-suggestions': 5.46.0 - '@algolia/client-search': 5.46.0 - '@algolia/ingestion': 1.46.0 - '@algolia/monitoring': 1.46.0 - '@algolia/recommend': 5.46.0 - '@algolia/requester-browser-xhr': 5.46.0 - '@algolia/requester-fetch': 5.46.0 - '@algolia/requester-node-http': 5.46.0 + '@algolia/abtesting': 1.18.1 + '@algolia/client-abtesting': 5.52.1 + '@algolia/client-analytics': 5.52.1 + '@algolia/client-common': 5.52.1 + '@algolia/client-insights': 5.52.1 + '@algolia/client-personalization': 5.52.1 + '@algolia/client-query-suggestions': 5.52.1 + '@algolia/client-search': 5.52.1 + '@algolia/ingestion': 1.52.1 + '@algolia/monitoring': 1.52.1 + '@algolia/recommend': 5.52.1 + '@algolia/requester-browser-xhr': 5.52.1 + '@algolia/requester-fetch': 5.52.1 + '@algolia/requester-node-http': 5.52.1 ansi-align@3.0.1: dependencies: @@ -18674,7 +19264,7 @@ snapshots: buffer-crc32: 1.0.0 readable-stream: 4.7.0 readdir-glob: 1.1.3 - tar-stream: 3.1.8 + tar-stream: 3.2.0 zip-stream: 6.0.1 transitivePeerDependencies: - bare-abort-controller @@ -18716,6 +19306,12 @@ snapshots: dependencies: safer-buffer: 2.1.2 + asn1js@3.0.10: + dependencies: + pvtsutils: 1.3.6 + pvutils: 1.1.5 + tslib: 2.8.1 + assertion-error@2.0.1: {} ast-metadata-inferer@0.8.1: @@ -18753,51 +19349,59 @@ snapshots: dependencies: immediate: 3.3.0 - autoprefixer@10.5.0(postcss@8.5.12): + autoprefixer@10.5.0(postcss@8.5.15): dependencies: browserslist: 4.28.2 - caniuse-lite: 1.0.30001790 + caniuse-lite: 1.0.30001793 fraction.js: 5.3.4 picocolors: 1.1.1 - postcss: 8.5.12 + postcss: 8.5.15 postcss-value-parser: 4.2.0 axobject-query@4.1.0: {} - b4a@1.8.0: {} + b4a@1.8.1: {} - babel-loader@9.2.1(@babel/core@7.28.5)(webpack@5.106.2): + babel-loader@9.2.1(@babel/core@7.29.0)(webpack@5.107.0(postcss@8.5.15)): dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.29.0 find-cache-dir: 4.0.0 schema-utils: 4.3.3 - webpack: 5.106.2 + webpack: 5.107.0(postcss@8.5.15) babel-plugin-dynamic-import-node@2.3.3: dependencies: object.assign: 4.1.7 - babel-plugin-polyfill-corejs2@0.4.14(@babel/core@7.28.5): + babel-plugin-polyfill-corejs2@0.4.17(@babel/core@7.29.0): dependencies: - '@babel/compat-data': 7.28.5 - '@babel/core': 7.28.5 - '@babel/helper-define-polyfill-provider': 0.6.5(@babel/core@7.28.5) + '@babel/compat-data': 7.29.3 + '@babel/core': 7.29.0 + '@babel/helper-define-polyfill-provider': 0.6.8(@babel/core@7.29.0) semver: 6.3.1 transitivePeerDependencies: - supports-color - babel-plugin-polyfill-corejs3@0.13.0(@babel/core@7.28.5): + babel-plugin-polyfill-corejs3@0.13.0(@babel/core@7.29.0): dependencies: - '@babel/core': 7.28.5 - '@babel/helper-define-polyfill-provider': 0.6.5(@babel/core@7.28.5) + '@babel/core': 7.29.0 + '@babel/helper-define-polyfill-provider': 0.6.8(@babel/core@7.29.0) core-js-compat: 3.49.0 transitivePeerDependencies: - supports-color - babel-plugin-polyfill-regenerator@0.6.5(@babel/core@7.28.5): + babel-plugin-polyfill-corejs3@0.14.2(@babel/core@7.29.0): dependencies: - '@babel/core': 7.28.5 - '@babel/helper-define-polyfill-provider': 0.6.5(@babel/core@7.28.5) + '@babel/core': 7.29.0 + '@babel/helper-define-polyfill-provider': 0.6.8(@babel/core@7.29.0) + core-js-compat: 3.49.0 + transitivePeerDependencies: + - supports-color + + babel-plugin-polyfill-regenerator@0.6.8(@babel/core@7.29.0): + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-define-polyfill-provider': 0.6.8(@babel/core@7.29.0) transitivePeerDependencies: - supports-color @@ -18809,35 +19413,35 @@ snapshots: balanced-match@4.0.4: {} - bare-events@2.8.2: {} + bare-events@2.8.3: {} bare-fs@4.7.1: dependencies: - bare-events: 2.8.2 + bare-events: 2.8.3 bare-path: 3.0.0 - bare-stream: 2.13.0(bare-events@2.8.2) - bare-url: 2.4.2 + bare-stream: 2.13.1(bare-events@2.8.3) + bare-url: 2.4.3 fast-fifo: 1.3.2 transitivePeerDependencies: - bare-abort-controller - react-native-b4a - bare-os@3.9.0: {} + bare-os@3.9.1: {} bare-path@3.0.0: dependencies: - bare-os: 3.9.0 + bare-os: 3.9.1 - bare-stream@2.13.0(bare-events@2.8.2): + bare-stream@2.13.1(bare-events@2.8.3): dependencies: streamx: 2.25.0 teex: 1.0.1 optionalDependencies: - bare-events: 2.8.2 + bare-events: 2.8.3 transitivePeerDependencies: - react-native-b4a - bare-url@2.4.2: + bare-url@2.4.3: dependencies: bare-path: 3.0.0 @@ -18845,7 +19449,7 @@ snapshots: base64id@2.0.0: {} - baseline-browser-mapping@2.10.20: {} + baseline-browser-mapping@2.10.31: {} batch-cluster@17.3.1: {} @@ -18859,11 +19463,9 @@ snapshots: bcrypt@6.0.0: dependencies: - node-addon-api: 8.5.0 - node-gyp: 12.2.0 + node-addon-api: 8.7.0 + node-gyp: 12.3.0 node-gyp-build: 4.8.4 - transitivePeerDependencies: - - supports-color better-sqlite3@12.9.0: dependencies: @@ -18878,28 +19480,28 @@ snapshots: dependencies: file-uri-to-path: 1.0.0 - bits-ui@2.18.0(@internationalized/date@3.12.1)(@sveltejs/kit@2.57.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.55.8)(vite@8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)))(svelte@5.55.8)(typescript@6.0.3)(vite@8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)))(svelte@5.55.8): + bits-ui@2.18.0(@internationalized/date@3.12.1)(@sveltejs/kit@2.60.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.1.2(svelte@5.55.8(@typescript-eslint/types@8.59.4))(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0)))(svelte@5.55.8(@typescript-eslint/types@8.59.4))(typescript@6.0.3)(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0)))(svelte@5.55.8(@typescript-eslint/types@8.59.4)): dependencies: '@floating-ui/core': 1.7.5 '@floating-ui/dom': 1.7.6 '@internationalized/date': 3.12.1 esm-env: 1.2.2 - runed: 0.35.1(@sveltejs/kit@2.57.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.55.8)(vite@8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)))(svelte@5.55.8)(typescript@6.0.3)(vite@8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)))(svelte@5.55.8) - svelte: 5.55.8 - svelte-toolbelt: 0.10.6(@sveltejs/kit@2.57.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.55.8)(vite@8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)))(svelte@5.55.8)(typescript@6.0.3)(vite@8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)))(svelte@5.55.8) + runed: 0.35.1(@sveltejs/kit@2.60.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.1.2(svelte@5.55.8(@typescript-eslint/types@8.59.4))(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0)))(svelte@5.55.8(@typescript-eslint/types@8.59.4))(typescript@6.0.3)(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0)))(svelte@5.55.8(@typescript-eslint/types@8.59.4)) + svelte: 5.55.8(@typescript-eslint/types@8.59.4) + svelte-toolbelt: 0.10.6(@sveltejs/kit@2.60.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.1.2(svelte@5.55.8(@typescript-eslint/types@8.59.4))(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0)))(svelte@5.55.8(@typescript-eslint/types@8.59.4))(typescript@6.0.3)(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0)))(svelte@5.55.8(@typescript-eslint/types@8.59.4)) tabbable: 6.4.0 transitivePeerDependencies: - '@sveltejs/kit' - bits-ui@2.18.0(@internationalized/date@3.12.1)(svelte@5.55.8): + bits-ui@2.18.1(@internationalized/date@3.12.1)(@sveltejs/kit@2.60.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.1.2(svelte@5.55.8(@typescript-eslint/types@8.59.4))(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0)))(svelte@5.55.8(@typescript-eslint/types@8.59.4))(typescript@6.0.3)(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0)))(svelte@5.55.8(@typescript-eslint/types@8.59.4)): dependencies: '@floating-ui/core': 1.7.5 '@floating-ui/dom': 1.7.6 '@internationalized/date': 3.12.1 esm-env: 1.2.2 - runed: 0.35.1(svelte@5.55.8) - svelte: 5.55.8 - svelte-toolbelt: 0.10.6(svelte@5.55.8) + runed: 0.35.1(@sveltejs/kit@2.60.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.1.2(svelte@5.55.8(@typescript-eslint/types@8.59.4))(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0)))(svelte@5.55.8(@typescript-eslint/types@8.59.4))(typescript@6.0.3)(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0)))(svelte@5.55.8(@typescript-eslint/types@8.59.4)) + svelte: 5.55.8(@typescript-eslint/types@8.59.4) + svelte-toolbelt: 0.10.6(@sveltejs/kit@2.60.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.1.2(svelte@5.55.8(@typescript-eslint/types@8.59.4))(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0)))(svelte@5.55.8(@typescript-eslint/types@8.59.4))(typescript@6.0.3)(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0)))(svelte@5.55.8(@typescript-eslint/types@8.59.4)) tabbable: 6.4.0 transitivePeerDependencies: - '@sveltejs/kit' @@ -18910,7 +19512,7 @@ snapshots: inherits: 2.0.4 readable-stream: 3.6.2 - body-parser@1.20.4: + body-parser@1.20.5: dependencies: bytes: 3.1.2 content-type: 1.0.5 @@ -18920,7 +19522,7 @@ snapshots: http-errors: 2.0.1 iconv-lite: 0.4.24 on-finished: 2.4.1 - qs: 6.14.1 + qs: 6.15.2 raw-body: 2.5.3 type-is: 1.6.18 unpipe: 1.0.0 @@ -18935,9 +19537,9 @@ snapshots: http-errors: 2.0.1 iconv-lite: 0.7.2 on-finished: 2.4.1 - qs: 6.14.1 + qs: 6.15.2 raw-body: 3.0.2 - type-is: 2.0.1 + type-is: 2.1.0 transitivePeerDependencies: - supports-color @@ -18970,7 +19572,7 @@ snapshots: widest-line: 4.0.1 wrap-ansi: 8.1.0 - brace-expansion@1.1.12: + brace-expansion@1.1.14: dependencies: balanced-match: 1.0.2 concat-map: 0.0.1 @@ -18979,7 +19581,7 @@ snapshots: dependencies: balanced-match: 1.0.2 - brace-expansion@5.0.5: + brace-expansion@5.0.6: dependencies: balanced-match: 4.0.4 @@ -18989,10 +19591,10 @@ snapshots: browserslist@4.28.2: dependencies: - baseline-browser-mapping: 2.10.20 - caniuse-lite: 1.0.30001790 - electron-to-chromium: 1.5.343 - node-releases: 2.0.38 + baseline-browser-mapping: 2.10.31 + caniuse-lite: 1.0.30001793 + electron-to-chromium: 1.5.360 + node-releases: 2.0.44 update-browserslist-db: 1.2.3(browserslist@4.28.2) buffer-crc32@1.0.0: {} @@ -19014,17 +19616,16 @@ snapshots: buildcheck@0.0.7: optional: true - builtin-modules@5.0.0: {} + builtin-modules@5.2.0: {} - bullmq@5.76.1: + bullmq@5.76.10: dependencies: cron-parser: 4.9.0 ioredis: 5.10.1 - msgpackr: 1.11.5 + msgpackr: 2.0.1 node-abort-controller: 3.1.1 - semver: 7.7.4 + semver: 7.8.0 tslib: 2.8.1 - uuid: 11.1.0 transitivePeerDependencies: - supports-color @@ -19044,32 +19645,20 @@ snapshots: bytes@3.1.2: {} - cac@6.7.14: {} + bytestreamjs@2.0.1: {} - cacache@20.0.3: - dependencies: - '@npmcli/fs': 5.0.0 - fs-minipass: 3.0.3 - glob: 13.0.6 - lru-cache: 11.3.5 - minipass: 7.1.3 - minipass-collect: 2.0.1 - minipass-flush: 1.0.5 - minipass-pipeline: 1.2.4 - p-map: 7.0.4 - ssri: 13.0.1 - unique-filename: 5.0.0 + cac@6.7.14: {} cacheable-lookup@7.0.0: {} cacheable-request@10.2.14: dependencies: - '@types/http-cache-semantics': 4.0.4 + '@types/http-cache-semantics': 4.2.0 get-stream: 6.0.1 http-cache-semantics: 4.2.0 keyv: 4.5.4 mimic-response: 4.0.0 - normalize-url: 8.1.0 + normalize-url: 8.1.1 responselike: 3.0.0 call-bind-apply-helpers@1.0.2: @@ -19077,7 +19666,7 @@ snapshots: es-errors: 1.3.0 function-bind: 1.1.2 - call-bind@1.0.8: + call-bind@1.0.9: dependencies: call-bind-apply-helpers: 1.0.2 es-define-property: 1.0.1 @@ -19107,11 +19696,11 @@ snapshots: caniuse-api@3.0.0: dependencies: browserslist: 4.28.2 - caniuse-lite: 1.0.30001790 + caniuse-lite: 1.0.30001793 lodash.memoize: 4.1.2 lodash.uniq: 4.5.0 - caniuse-lite@1.0.30001790: {} + caniuse-lite@1.0.30001793: {} canvas@3.2.3: dependencies: @@ -19121,9 +19710,9 @@ snapshots: ccount@2.0.1: {} - ce-la-react@0.3.2(react@19.2.5): + ce-la-react@0.3.2(react@19.2.6): dependencies: - react: 19.2.5 + react: 19.2.6 chai@5.3.3: dependencies: @@ -19177,20 +19766,6 @@ snapshots: parse5: 7.3.0 parse5-htmlparser2-tree-adapter: 7.1.0 - chevrotain-allstar@0.3.1(chevrotain@11.0.3): - dependencies: - chevrotain: 11.0.3 - lodash-es: 4.18.1 - - chevrotain@11.0.3: - dependencies: - '@chevrotain/cst-dts-gen': 11.0.3 - '@chevrotain/gast': 11.0.3 - '@chevrotain/regexp-to-ast': 11.0.3 - '@chevrotain/types': 11.0.3 - '@chevrotain/utils': 11.0.3 - lodash-es: 4.17.21 - chokidar@3.6.0: dependencies: anymatch: 3.1.3 @@ -19306,11 +19881,11 @@ snapshots: cluster-key-slot@1.1.2: {} - codemirror-wrapped-line-indent@1.0.9(@codemirror/language@6.12.3)(@codemirror/state@6.6.0)(@codemirror/view@6.41.1): + codemirror-wrapped-line-indent@1.0.9(@codemirror/language@6.12.3)(@codemirror/state@6.6.0)(@codemirror/view@6.43.0): dependencies: '@codemirror/language': 6.12.3 '@codemirror/state': 6.6.0 - '@codemirror/view': 6.41.1 + '@codemirror/view': 6.43.0 collapse-white-space@2.1.0: {} @@ -19402,18 +19977,16 @@ snapshots: conf@15.1.0: dependencies: - ajv: 8.18.0 - ajv-formats: 3.0.1(ajv@8.18.0) + ajv: 8.20.0 + ajv-formats: 3.0.1(ajv@8.20.0) atomically: 2.1.1 debounce-fn: 6.0.0 dot-prop: 10.1.0 env-paths: 3.0.0 json-schema-typed: 8.0.2 - semver: 7.7.4 + semver: 7.8.0 uint8array-extras: 1.5.0 - confbox@0.1.8: {} - config-chain@1.1.13: dependencies: ini: 1.3.8 @@ -19441,8 +20014,12 @@ snapshots: content-disposition@1.0.1: {} + content-disposition@1.1.0: {} + content-type@1.0.5: {} + content-type@2.0.0: {} + convert-source-map@2.0.0: {} cookie-parser@1.4.7: @@ -19471,7 +20048,7 @@ snapshots: copy-text-to-clipboard@3.2.2: {} - copy-webpack-plugin@11.0.0(webpack@5.106.2): + copy-webpack-plugin@11.0.0(webpack@5.107.0(postcss@8.5.15)): dependencies: fast-glob: 3.3.3 glob-parent: 6.0.2 @@ -19479,13 +20056,13 @@ snapshots: normalize-path: 3.0.0 schema-utils: 4.3.3 serialize-javascript: 6.0.2 - webpack: 5.106.2 + webpack: 5.107.0(postcss@8.5.15) core-js-compat@3.49.0: dependencies: browserslist: 4.28.2 - core-js@3.47.0: {} + core-js@3.49.0: {} core-util-is@1.0.3: {} @@ -19523,7 +20100,7 @@ snapshots: cpu-features@0.0.10: dependencies: buildcheck: 0.0.7 - nan: 2.26.2 + nan: 2.27.0 optional: true crc-32@1.2.2: {} @@ -19560,50 +20137,50 @@ snapshots: dependencies: type-fest: 1.4.0 - css-blank-pseudo@7.0.1(postcss@8.5.12): + css-blank-pseudo@7.0.1(postcss@8.5.15): dependencies: - postcss: 8.5.12 + postcss: 8.5.15 postcss-selector-parser: 7.1.1 - css-declaration-sorter@7.3.0(postcss@8.5.12): + css-declaration-sorter@7.4.0(postcss@8.5.15): dependencies: - postcss: 8.5.12 + postcss: 8.5.15 - css-has-pseudo@7.0.3(postcss@8.5.12): + css-has-pseudo@7.0.3(postcss@8.5.15): dependencies: '@csstools/selector-specificity': 5.0.0(postcss-selector-parser@7.1.1) - postcss: 8.5.12 + postcss: 8.5.15 postcss-selector-parser: 7.1.1 postcss-value-parser: 4.2.0 - css-loader@6.11.0(webpack@5.106.2): + css-loader@6.11.0(webpack@5.107.0(postcss@8.5.15)): dependencies: - icss-utils: 5.1.0(postcss@8.5.12) - postcss: 8.5.12 - postcss-modules-extract-imports: 3.1.0(postcss@8.5.12) - postcss-modules-local-by-default: 4.2.0(postcss@8.5.12) - postcss-modules-scope: 3.2.1(postcss@8.5.12) - postcss-modules-values: 4.0.0(postcss@8.5.12) + icss-utils: 5.1.0(postcss@8.5.15) + postcss: 8.5.15 + postcss-modules-extract-imports: 3.1.0(postcss@8.5.15) + postcss-modules-local-by-default: 4.2.0(postcss@8.5.15) + postcss-modules-scope: 3.2.1(postcss@8.5.15) + postcss-modules-values: 4.0.0(postcss@8.5.15) postcss-value-parser: 4.2.0 - semver: 7.7.4 + semver: 7.8.0 optionalDependencies: - webpack: 5.106.2 + webpack: 5.107.0(postcss@8.5.15) - css-minimizer-webpack-plugin@5.0.1(clean-css@5.3.3)(webpack@5.106.2): + css-minimizer-webpack-plugin@5.0.1(clean-css@5.3.3)(webpack@5.107.0(postcss@8.5.15)): dependencies: '@jridgewell/trace-mapping': 0.3.31 - cssnano: 6.1.2(postcss@8.5.12) + cssnano: 6.1.2(postcss@8.5.15) jest-worker: 29.7.0 - postcss: 8.5.12 + postcss: 8.5.15 schema-utils: 4.3.3 serialize-javascript: 6.0.2 - webpack: 5.106.2 + webpack: 5.107.0(postcss@8.5.15) optionalDependencies: clean-css: 5.3.3 - css-prefers-color-scheme@10.0.0(postcss@8.5.12): + css-prefers-color-scheme@10.0.0(postcss@8.5.15): dependencies: - postcss: 8.5.12 + postcss: 8.5.15 css-select@4.3.0: dependencies: @@ -19637,64 +20214,64 @@ snapshots: css.escape@1.5.1: {} - cssdb@8.5.2: {} + cssdb@8.9.0: {} cssesc@3.0.0: {} - cssnano-preset-advanced@6.1.2(postcss@8.5.12): + cssnano-preset-advanced@6.1.2(postcss@8.5.15): dependencies: - autoprefixer: 10.5.0(postcss@8.5.12) + autoprefixer: 10.5.0(postcss@8.5.15) browserslist: 4.28.2 - cssnano-preset-default: 6.1.2(postcss@8.5.12) - postcss: 8.5.12 - postcss-discard-unused: 6.0.5(postcss@8.5.12) - postcss-merge-idents: 6.0.3(postcss@8.5.12) - postcss-reduce-idents: 6.0.3(postcss@8.5.12) - postcss-zindex: 6.0.2(postcss@8.5.12) + cssnano-preset-default: 6.1.2(postcss@8.5.15) + postcss: 8.5.15 + postcss-discard-unused: 6.0.5(postcss@8.5.15) + postcss-merge-idents: 6.0.3(postcss@8.5.15) + postcss-reduce-idents: 6.0.3(postcss@8.5.15) + postcss-zindex: 6.0.2(postcss@8.5.15) - cssnano-preset-default@6.1.2(postcss@8.5.12): + cssnano-preset-default@6.1.2(postcss@8.5.15): dependencies: browserslist: 4.28.2 - css-declaration-sorter: 7.3.0(postcss@8.5.12) - cssnano-utils: 4.0.2(postcss@8.5.12) - postcss: 8.5.12 - postcss-calc: 9.0.1(postcss@8.5.12) - postcss-colormin: 6.1.0(postcss@8.5.12) - postcss-convert-values: 6.1.0(postcss@8.5.12) - postcss-discard-comments: 6.0.2(postcss@8.5.12) - postcss-discard-duplicates: 6.0.3(postcss@8.5.12) - postcss-discard-empty: 6.0.3(postcss@8.5.12) - postcss-discard-overridden: 6.0.2(postcss@8.5.12) - postcss-merge-longhand: 6.0.5(postcss@8.5.12) - postcss-merge-rules: 6.1.1(postcss@8.5.12) - postcss-minify-font-values: 6.1.0(postcss@8.5.12) - postcss-minify-gradients: 6.0.3(postcss@8.5.12) - postcss-minify-params: 6.1.0(postcss@8.5.12) - postcss-minify-selectors: 6.0.4(postcss@8.5.12) - postcss-normalize-charset: 6.0.2(postcss@8.5.12) - postcss-normalize-display-values: 6.0.2(postcss@8.5.12) - postcss-normalize-positions: 6.0.2(postcss@8.5.12) - postcss-normalize-repeat-style: 6.0.2(postcss@8.5.12) - postcss-normalize-string: 6.0.2(postcss@8.5.12) - postcss-normalize-timing-functions: 6.0.2(postcss@8.5.12) - postcss-normalize-unicode: 6.1.0(postcss@8.5.12) - postcss-normalize-url: 6.0.2(postcss@8.5.12) - postcss-normalize-whitespace: 6.0.2(postcss@8.5.12) - postcss-ordered-values: 6.0.2(postcss@8.5.12) - postcss-reduce-initial: 6.1.0(postcss@8.5.12) - postcss-reduce-transforms: 6.0.2(postcss@8.5.12) - postcss-svgo: 6.0.3(postcss@8.5.12) - postcss-unique-selectors: 6.0.4(postcss@8.5.12) + css-declaration-sorter: 7.4.0(postcss@8.5.15) + cssnano-utils: 4.0.2(postcss@8.5.15) + postcss: 8.5.15 + postcss-calc: 9.0.1(postcss@8.5.15) + postcss-colormin: 6.1.0(postcss@8.5.15) + postcss-convert-values: 6.1.0(postcss@8.5.15) + postcss-discard-comments: 6.0.2(postcss@8.5.15) + postcss-discard-duplicates: 6.0.3(postcss@8.5.15) + postcss-discard-empty: 6.0.3(postcss@8.5.15) + postcss-discard-overridden: 6.0.2(postcss@8.5.15) + postcss-merge-longhand: 6.0.5(postcss@8.5.15) + postcss-merge-rules: 6.1.1(postcss@8.5.15) + postcss-minify-font-values: 6.1.0(postcss@8.5.15) + postcss-minify-gradients: 6.0.3(postcss@8.5.15) + postcss-minify-params: 6.1.0(postcss@8.5.15) + postcss-minify-selectors: 6.0.4(postcss@8.5.15) + postcss-normalize-charset: 6.0.2(postcss@8.5.15) + postcss-normalize-display-values: 6.0.2(postcss@8.5.15) + postcss-normalize-positions: 6.0.2(postcss@8.5.15) + postcss-normalize-repeat-style: 6.0.2(postcss@8.5.15) + postcss-normalize-string: 6.0.2(postcss@8.5.15) + postcss-normalize-timing-functions: 6.0.2(postcss@8.5.15) + postcss-normalize-unicode: 6.1.0(postcss@8.5.15) + postcss-normalize-url: 6.0.2(postcss@8.5.15) + postcss-normalize-whitespace: 6.0.2(postcss@8.5.15) + postcss-ordered-values: 6.0.2(postcss@8.5.15) + postcss-reduce-initial: 6.1.0(postcss@8.5.15) + postcss-reduce-transforms: 6.0.2(postcss@8.5.15) + postcss-svgo: 6.0.3(postcss@8.5.15) + postcss-unique-selectors: 6.0.4(postcss@8.5.15) - cssnano-utils@4.0.2(postcss@8.5.12): + cssnano-utils@4.0.2(postcss@8.5.15): dependencies: - postcss: 8.5.12 + postcss: 8.5.15 - cssnano@6.1.2(postcss@8.5.12): + cssnano@6.1.2(postcss@8.5.15): dependencies: - cssnano-preset-default: 6.1.2(postcss@8.5.12) + cssnano-preset-default: 6.1.2(postcss@8.5.15) lilconfig: 3.1.3 - postcss: 8.5.12 + postcss: 8.5.15 csso@5.0.5: dependencies: @@ -19708,17 +20285,17 @@ snapshots: csstype@3.2.3: {} - cytoscape-cose-bilkent@4.1.0(cytoscape@3.33.1): + cytoscape-cose-bilkent@4.1.0(cytoscape@3.33.4): dependencies: cose-base: 1.0.3 - cytoscape: 3.33.1 + cytoscape: 3.33.4 - cytoscape-fcose@2.2.0(cytoscape@3.33.1): + cytoscape-fcose@2.2.0(cytoscape@3.33.4): dependencies: cose-base: 2.2.0 - cytoscape: 3.33.1 + cytoscape: 3.33.4 - cytoscape@3.33.1: {} + cytoscape@3.33.4: {} d3-array@2.12.1: dependencies: @@ -19750,7 +20327,7 @@ snapshots: d3-delaunay@6.0.4: dependencies: - delaunator: 5.0.1 + delaunator: 5.1.0 d3-dispatch@3.0.1: {} @@ -19777,7 +20354,7 @@ snapshots: d3-quadtree: 3.0.1 d3-timer: 3.0.1 - d3-format@3.1.0: {} + d3-format@3.1.2: {} d3-geo@3.1.1: dependencies: @@ -19812,7 +20389,7 @@ snapshots: d3-scale@4.0.2: dependencies: d3-array: 3.2.4 - d3-format: 3.1.0 + d3-format: 3.1.2 d3-interpolate: 3.0.1 d3-time: 3.1.0 d3-time-format: 4.1.0 @@ -19869,7 +20446,7 @@ snapshots: d3-ease: 3.0.1 d3-fetch: 3.0.1 d3-force: 3.0.0 - d3-format: 3.1.0 + d3-format: 3.1.2 d3-geo: 3.1.1 d3-hierarchy: 3.1.2 d3-interpolate: 3.0.1 @@ -19892,7 +20469,7 @@ snapshots: es5-ext: 0.10.64 type: 2.7.3 - dagre-d3-es@7.0.13: + dagre-d3-es@7.0.14: dependencies: d3: 7.9.0 lodash-es: 4.18.1 @@ -19903,7 +20480,7 @@ snapshots: whatwg-url: 14.2.0 optional: true - dayjs@1.11.19: {} + dayjs@1.11.20: {} debounce-fn@6.0.0: dependencies: @@ -19929,7 +20506,7 @@ snapshots: decimal.js@10.6.0: {} - decode-named-character-reference@1.2.0: + decode-named-character-reference@1.3.0: dependencies: character-entities: 2.0.2 @@ -19949,7 +20526,7 @@ snapshots: default-browser-id@5.0.1: {} - default-browser@5.4.0: + default-browser@5.5.0: dependencies: bundle-name: 4.1.0 default-browser-id: 5.0.1 @@ -19976,7 +20553,7 @@ snapshots: has-property-descriptors: 1.0.2 object-keys: 1.1.1 - delaunator@5.0.1: + delaunator@5.1.0: dependencies: robust-predicates: 3.0.3 @@ -20042,7 +20619,7 @@ snapshots: docker-compose@1.4.2: dependencies: - yaml: 2.8.3 + yaml: 2.9.0 docker-modem@5.0.7: dependencies: @@ -20053,21 +20630,21 @@ snapshots: transitivePeerDependencies: - supports-color - dockerode@4.0.10: + dockerode@4.0.12: dependencies: '@balena/dockerignore': 1.0.2 '@grpc/grpc-js': 1.14.3 '@grpc/proto-loader': 0.7.15 docker-modem: 5.0.7 - protobufjs: 7.5.5 + protobufjs: 7.6.0 tar-fs: 2.1.4 uuid: 10.0.0 transitivePeerDependencies: - supports-color - docusaurus-lunr-search@3.6.0(@docusaurus/core@3.10.0(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3))(react-dom@19.2.5(react@19.2.5))(react@19.2.5): + docusaurus-lunr-search@3.6.0(@docusaurus/core@3.10.1(@mdx-js/react@3.1.1(@types/react@19.2.15)(react@19.2.6))(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.3))(react-dom@19.2.6(react@19.2.6))(react@19.2.6): dependencies: - '@docusaurus/core': 3.10.0(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3) + '@docusaurus/core': 3.10.1(@mdx-js/react@3.1.1(@types/react@19.2.15)(react@19.2.6))(postcss@8.5.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.3) autocomplete.js: 0.37.1 clsx: 2.1.1 gauge: 3.0.2 @@ -20075,11 +20652,11 @@ snapshots: hast-util-to-text: 2.0.1 hogan.js: 3.0.2 lunr: 2.3.9 - lunr-languages: 1.14.0 + lunr-languages: 1.20.0 mark.js: 8.11.1 minimatch: 3.1.5 - react: 19.2.5 - react-dom: 19.2.5(react@19.2.5) + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) rehype-parse: 7.0.1 to-vfile: 6.1.0 unified: 9.2.2 @@ -20117,7 +20694,7 @@ snapshots: dependencies: domelementtype: 2.3.0 - dompurify@3.3.1: + dompurify@3.4.5: optionalDependencies: '@types/trusted-types': 2.0.7 @@ -20166,7 +20743,7 @@ snapshots: ee-first@1.1.1: {} - electron-to-chromium@1.5.343: {} + electron-to-chromium@1.5.360: {} emoji-regex@10.6.0: {} @@ -20182,21 +20759,16 @@ snapshots: encodeurl@2.0.0: {} - encoding@0.1.13: - dependencies: - iconv-lite: 0.6.3 - optional: true - end-of-stream@1.4.5: dependencies: once: 1.4.0 - engine.io-client@6.6.4: + engine.io-client@6.6.5: dependencies: '@socket.io/component-emitter': 3.1.2 debug: 4.4.3 engine.io-parser: 5.2.3 - ws: 8.18.3 + ws: 8.20.1 xmlhttprequest-ssl: 2.1.2 transitivePeerDependencies: - bufferutil @@ -20205,23 +20777,24 @@ snapshots: engine.io-parser@5.2.3: {} - engine.io@6.6.5: + engine.io@6.6.8: dependencies: '@types/cors': 2.8.19 - '@types/node': 24.12.2 + '@types/node': 24.12.4 + '@types/ws': 8.18.1 accepts: 1.3.8 base64id: 2.0.0 cookie: 0.7.2 cors: 2.8.6 debug: 4.4.3 engine.io-parser: 5.2.3 - ws: 8.18.3 + ws: 8.20.1 transitivePeerDependencies: - bufferutil - supports-color - utf-8-validate - enhanced-resolve@5.21.0: + enhanced-resolve@5.21.5: dependencies: graceful-fs: 4.2.11 tapable: 2.3.3 @@ -20238,8 +20811,6 @@ snapshots: env-paths@3.0.0: {} - err-code@2.0.3: {} - error-ex@1.3.4: dependencies: is-arrayish: 0.2.1 @@ -20261,7 +20832,9 @@ snapshots: es-errors: 1.3.0 get-intrinsic: 1.3.0 has-tostringtag: 1.0.2 - hasown: 2.0.2 + hasown: 2.0.3 + + es-toolkit@1.46.1: {} es5-ext@0.10.64: dependencies: @@ -20357,6 +20930,35 @@ snapshots: '@esbuild/win32-ia32': 0.27.4 '@esbuild/win32-x64': 0.27.4 + esbuild@0.27.7: + optionalDependencies: + '@esbuild/aix-ppc64': 0.27.7 + '@esbuild/android-arm': 0.27.7 + '@esbuild/android-arm64': 0.27.7 + '@esbuild/android-x64': 0.27.7 + '@esbuild/darwin-arm64': 0.27.7 + '@esbuild/darwin-x64': 0.27.7 + '@esbuild/freebsd-arm64': 0.27.7 + '@esbuild/freebsd-x64': 0.27.7 + '@esbuild/linux-arm': 0.27.7 + '@esbuild/linux-arm64': 0.27.7 + '@esbuild/linux-ia32': 0.27.7 + '@esbuild/linux-loong64': 0.27.7 + '@esbuild/linux-mips64el': 0.27.7 + '@esbuild/linux-ppc64': 0.27.7 + '@esbuild/linux-riscv64': 0.27.7 + '@esbuild/linux-s390x': 0.27.7 + '@esbuild/linux-x64': 0.27.7 + '@esbuild/netbsd-arm64': 0.27.7 + '@esbuild/netbsd-x64': 0.27.7 + '@esbuild/openbsd-arm64': 0.27.7 + '@esbuild/openbsd-x64': 0.27.7 + '@esbuild/openharmony-arm64': 0.27.7 + '@esbuild/sunos-x64': 0.27.7 + '@esbuild/win32-arm64': 0.27.7 + '@esbuild/win32-ia32': 0.27.7 + '@esbuild/win32-x64': 0.27.7 + esbuild@0.28.0: optionalDependencies: '@esbuild/aix-ppc64': 0.28.0 @@ -20398,84 +21000,84 @@ snapshots: escape-string-regexp@5.0.0: {} - eslint-config-prettier@10.1.8(eslint@10.2.1(jiti@2.6.1)): + eslint-config-prettier@10.1.8(eslint@10.4.0(jiti@2.7.0)): dependencies: - eslint: 10.2.1(jiti@2.6.1) + eslint: 10.4.0(jiti@2.7.0) - eslint-plugin-better-tailwindcss@4.5.0(eslint@10.2.1(jiti@2.6.1))(tailwindcss@4.2.4)(typescript@6.0.3): + eslint-plugin-better-tailwindcss@4.5.0(eslint@10.4.0(jiti@2.7.0))(tailwindcss@4.3.0)(typescript@6.0.3): dependencies: - '@eslint/css-tree': 4.0.2 - '@valibot/to-json-schema': 1.6.0(valibot@1.3.1(typescript@6.0.3)) - enhanced-resolve: 5.21.0 - jiti: 2.6.1 + '@eslint/css-tree': 4.0.3 + '@valibot/to-json-schema': 1.7.0(valibot@1.4.0(typescript@6.0.3)) + enhanced-resolve: 5.21.5 + jiti: 2.7.0 synckit: 0.11.12 tailwind-csstree: 0.3.1 - tailwindcss: 4.2.4 + tailwindcss: 4.3.0 tsconfig-paths-webpack-plugin: 4.2.0 - valibot: 1.3.1(typescript@6.0.3) + valibot: 1.4.0(typescript@6.0.3) optionalDependencies: - eslint: 10.2.1(jiti@2.6.1) + eslint: 10.4.0(jiti@2.7.0) transitivePeerDependencies: - '@eslint/css' - typescript - eslint-plugin-compat@7.0.1(eslint@10.2.1(jiti@2.6.1)): + eslint-plugin-compat@7.0.2(eslint@10.4.0(jiti@2.7.0)): dependencies: '@mdn/browser-compat-data': 6.1.5 ast-metadata-inferer: 0.8.1 browserslist: 4.28.2 - eslint: 10.2.1(jiti@2.6.1) + eslint: 10.4.0(jiti@2.7.0) find-up: 5.0.0 globals: 15.15.0 lodash.memoize: 4.1.2 - semver: 7.7.4 + semver: 7.8.0 - eslint-plugin-prettier@5.5.5(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@10.2.1(jiti@2.6.1)))(eslint@10.2.1(jiti@2.6.1))(prettier@3.8.3): + eslint-plugin-prettier@5.5.5(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@10.4.0(jiti@2.7.0)))(eslint@10.4.0(jiti@2.7.0))(prettier@3.8.3): dependencies: - eslint: 10.2.1(jiti@2.6.1) + eslint: 10.4.0(jiti@2.7.0) prettier: 3.8.3 prettier-linter-helpers: 1.0.1 synckit: 0.11.12 optionalDependencies: '@types/eslint': 9.6.1 - eslint-config-prettier: 10.1.8(eslint@10.2.1(jiti@2.6.1)) + eslint-config-prettier: 10.1.8(eslint@10.4.0(jiti@2.7.0)) - eslint-plugin-svelte@3.17.1(eslint@10.2.1(jiti@2.6.1))(svelte@5.55.8): + eslint-plugin-svelte@3.17.1(eslint@10.4.0(jiti@2.7.0))(svelte@5.55.8(@typescript-eslint/types@8.59.4)): dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@10.2.1(jiti@2.6.1)) + '@eslint-community/eslint-utils': 4.9.1(eslint@10.4.0(jiti@2.7.0)) '@jridgewell/sourcemap-codec': 1.5.5 - eslint: 10.2.1(jiti@2.6.1) + eslint: 10.4.0(jiti@2.7.0) esutils: 2.0.3 globals: 16.5.0 known-css-properties: 0.37.0 - postcss: 8.5.12 - postcss-load-config: 3.1.4(postcss@8.5.12) - postcss-safe-parser: 7.0.1(postcss@8.5.12) - semver: 7.7.4 - svelte-eslint-parser: 1.6.0(svelte@5.55.8) + postcss: 8.5.15 + postcss-load-config: 3.1.4(postcss@8.5.15) + postcss-safe-parser: 7.0.1(postcss@8.5.15) + semver: 7.8.0 + svelte-eslint-parser: 1.6.1(svelte@5.55.8(@typescript-eslint/types@8.59.4)) optionalDependencies: - svelte: 5.55.8 + svelte: 5.55.8(@typescript-eslint/types@8.59.4) transitivePeerDependencies: - ts-node - eslint-plugin-unicorn@64.0.0(eslint@10.2.1(jiti@2.6.1)): + eslint-plugin-unicorn@64.0.0(eslint@10.4.0(jiti@2.7.0)): dependencies: '@babel/helper-validator-identifier': 7.28.5 - '@eslint-community/eslint-utils': 4.9.1(eslint@10.2.1(jiti@2.6.1)) + '@eslint-community/eslint-utils': 4.9.1(eslint@10.4.0(jiti@2.7.0)) change-case: 5.4.4 ci-info: 4.4.0 clean-regexp: 1.0.0 core-js-compat: 3.49.0 - eslint: 10.2.1(jiti@2.6.1) + eslint: 10.4.0(jiti@2.7.0) find-up-simple: 1.0.1 - globals: 17.5.0 + globals: 17.6.0 indent-string: 5.0.0 is-builtin-module: 5.0.0 jsesc: 3.1.0 pluralize: 8.0.0 regexp-tree: 0.1.27 - regjsparser: 0.13.0 - semver: 7.7.4 + regjsparser: 0.13.1 + semver: 7.8.0 strip-indent: 4.1.1 eslint-scope@5.1.1: @@ -20491,7 +21093,7 @@ snapshots: eslint-scope@9.1.2: dependencies: '@types/esrecurse': 4.3.1 - '@types/estree': 1.0.8 + '@types/estree': 1.0.9 esrecurse: 4.3.0 estraverse: 5.3.0 @@ -20501,19 +21103,19 @@ snapshots: eslint-visitor-keys@5.0.1: {} - eslint@10.2.1(jiti@2.6.1): + eslint@10.4.0(jiti@2.7.0): dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@10.2.1(jiti@2.6.1)) + '@eslint-community/eslint-utils': 4.9.1(eslint@10.4.0(jiti@2.7.0)) '@eslint-community/regexpp': 4.12.2 '@eslint/config-array': 0.23.5 - '@eslint/config-helpers': 0.5.5 + '@eslint/config-helpers': 0.6.0 '@eslint/core': 1.2.1 '@eslint/plugin-kit': 0.7.1 '@humanfs/node': 0.16.8 '@humanwhocodes/module-importer': 1.0.1 '@humanwhocodes/retry': 0.4.3 - '@types/estree': 1.0.8 - ajv: 6.14.0 + '@types/estree': 1.0.9 + ajv: 6.15.0 cross-spawn: 7.0.6 debug: 4.4.3 escape-string-regexp: 4.0.0 @@ -20534,7 +21136,7 @@ snapshots: natural-compare: 1.4.0 optionator: 0.9.4 optionalDependencies: - jiti: 2.6.1 + jiti: 2.7.0 transitivePeerDependencies: - supports-color @@ -20565,10 +21167,11 @@ snapshots: dependencies: estraverse: 5.3.0 - esrap@2.2.4: + esrap@2.2.9(@typescript-eslint/types@8.59.4): dependencies: '@jridgewell/sourcemap-codec': 1.5.5 - '@typescript-eslint/types': 8.59.0 + optionalDependencies: + '@typescript-eslint/types': 8.59.4 esrecurse@4.3.0: dependencies: @@ -20580,7 +21183,7 @@ snapshots: estree-util-attach-comments@3.0.0: dependencies: - '@types/estree': 1.0.8 + '@types/estree': 1.0.9 estree-util-build-jsx@3.0.1: dependencies: @@ -20593,7 +21196,7 @@ snapshots: estree-util-scope@1.0.0: dependencies: - '@types/estree': 1.0.8 + '@types/estree': 1.0.9 devlop: 1.1.0 estree-util-to-js@2.0.0: @@ -20604,7 +21207,7 @@ snapshots: estree-util-value-to-estree@3.5.0: dependencies: - '@types/estree': 1.0.8 + '@types/estree': 1.0.9 estree-util-visit@2.0.0: dependencies: @@ -20615,19 +21218,19 @@ snapshots: estree-walker@3.0.3: dependencies: - '@types/estree': 1.0.8 + '@types/estree': 1.0.9 esutils@2.0.3: {} eta@2.2.0: {} - eta@4.5.1: {} + eta@4.6.0: {} etag@1.8.1: {} eval@0.1.8: dependencies: - '@types/node': 24.12.2 + '@types/node': 24.12.4 require-like: 0.1.2 event-emitter@0.3.5: @@ -20645,7 +21248,7 @@ snapshots: events-universal@1.0.1: dependencies: - bare-events: 2.8.2 + bare-events: 2.8.3 transitivePeerDependencies: - bare-abort-controller @@ -20707,11 +21310,11 @@ snapshots: exponential-backoff@3.1.3: {} - express@4.22.1: + express@4.22.2: dependencies: accepts: 1.3.8 array-flatten: 1.1.1 - body-parser: 1.20.4 + body-parser: 1.20.5 content-disposition: 0.5.4 content-type: 1.0.5 cookie: 0.7.2 @@ -20730,7 +21333,7 @@ snapshots: parseurl: 1.3.3 path-to-regexp: 0.1.13 proxy-addr: 2.0.7 - qs: 6.14.1 + qs: 6.15.2 range-parser: 1.2.1 safe-buffer: 5.2.1 send: 0.19.2 @@ -20747,7 +21350,7 @@ snapshots: dependencies: accepts: 2.0.0 body-parser: 2.2.2 - content-disposition: 1.0.1 + content-disposition: 1.1.0 content-type: 1.0.5 cookie: 0.7.2 cookie-signature: 1.2.2 @@ -20765,13 +21368,13 @@ snapshots: once: 1.4.0 parseurl: 1.3.3 proxy-addr: 2.0.7 - qs: 6.14.1 + qs: 6.15.2 range-parser: 1.2.1 router: 2.2.0 send: 1.2.1 serve-static: 2.2.1 statuses: 2.0.2 - type-is: 2.0.1 + type-is: 2.1.0 vary: 1.1.2 transitivePeerDependencies: - supports-color @@ -20786,7 +21389,7 @@ snapshots: extend@3.0.2: {} - fabric@7.3.1: + fabric@7.4.0: optionalDependencies: canvas: 3.2.3 jsdom: 26.1.0(canvas@3.2.3) @@ -20820,7 +21423,7 @@ snapshots: fast-safe-stringify@2.1.1: {} - fast-uri@3.1.0: {} + fast-uri@3.1.2: {} fastq@1.20.1: dependencies: @@ -20842,7 +21445,7 @@ snapshots: dependencies: xml-js: 1.6.11 - fflate@0.8.2: {} + fflate@0.8.3: {} figures@3.2.0: dependencies: @@ -20852,11 +21455,11 @@ snapshots: dependencies: flat-cache: 4.0.1 - file-loader@6.2.0(webpack@5.106.2): + file-loader@6.2.0(webpack@5.107.0(postcss@8.5.15)): dependencies: loader-utils: 2.0.4 schema-utils: 3.3.0 - webpack: 5.106.2 + webpack: 5.107.0(postcss@8.5.15) file-source@0.6.1: dependencies: @@ -20936,14 +21539,14 @@ snapshots: async: 0.2.10 which: 1.3.1 - follow-redirects@1.15.11: {} + follow-redirects@1.16.0: {} 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.9.3)(webpack@5.106.0(@swc/core@1.15.30(@swc/helpers@0.5.21))(esbuild@0.28.0)): + fork-ts-checker-webpack-plugin@9.1.0(typescript@5.9.3)(webpack@5.106.0(@swc/core@1.15.33(@swc/helpers@0.5.22))(esbuild@0.28.0)(lightningcss@1.32.0)): dependencies: '@babel/code-frame': 7.29.0 chalk: 4.1.2 @@ -20955,10 +21558,10 @@ snapshots: minimatch: 3.1.5 node-abort-controller: 3.1.1 schema-utils: 3.3.0 - semver: 7.7.4 + semver: 7.8.0 tapable: 2.3.3 typescript: 5.9.3 - webpack: 5.106.0(@swc/core@1.15.30(@swc/helpers@0.5.21))(esbuild@0.28.0) + webpack: 5.106.0(@swc/core@1.15.33(@swc/helpers@0.5.22))(esbuild@0.28.0)(lightningcss@1.32.0) form-data-encoder@2.1.4: {} @@ -20967,7 +21570,7 @@ snapshots: asynckit: 0.4.0 combined-stream: 1.0.8 es-set-tostringtag: 2.1.0 - hasown: 2.0.2 + hasown: 2.0.3 mime-types: 2.1.35 format@0.2.2: {} @@ -20996,7 +21599,7 @@ snapshots: jsonfile: 6.2.1 universalify: 2.0.1 - fs-extra@11.3.4: + fs-extra@11.3.5: dependencies: graceful-fs: 4.2.11 jsonfile: 6.2.1 @@ -21006,10 +21609,6 @@ snapshots: dependencies: minipass: 3.3.6 - fs-minipass@3.0.3: - dependencies: - minipass: 7.1.3 - fs-monkey@1.1.0: {} fs.realpath@1.0.0: {} @@ -21040,10 +21639,10 @@ snapshots: geo-coordinates-parser@1.7.4: {} - geo-tz@8.1.6: + geo-tz@8.1.7: dependencies: - '@turf/boolean-point-in-polygon': 7.3.4 - '@turf/helpers': 7.3.4 + '@turf/boolean-point-in-polygon': 7.3.5 + '@turf/helpers': 7.3.5 geobuf: 3.0.2 pbf: 3.3.0 @@ -21057,7 +21656,7 @@ snapshots: get-caller-file@2.0.5: {} - get-east-asian-width@1.5.0: {} + get-east-asian-width@1.6.0: {} get-intrinsic@1.3.0: dependencies: @@ -21069,7 +21668,7 @@ snapshots: get-proto: 1.0.1 gopd: 1.2.0 has-symbols: 1.1.0 - hasown: 2.0.2 + hasown: 2.0.3 math-intrinsics: 1.1.0 get-own-enumerable-property-symbols@3.0.2: {} @@ -21083,7 +21682,7 @@ snapshots: get-stream@6.0.1: {} - get-tsconfig@4.13.0: + get-tsconfig@4.14.0: dependencies: resolve-pkg-maps: 1.0.0 @@ -21141,7 +21740,7 @@ snapshots: globals@16.5.0: {} - globals@17.5.0: {} + globals@17.6.0: {} globalyzer@0.1.0: {} @@ -21212,12 +21811,12 @@ snapshots: happy-dom@20.9.0: dependencies: - '@types/node': 24.12.2 + '@types/node': 24.12.4 '@types/whatwg-mimetype': 3.0.2 '@types/ws': 8.18.1 entities: 7.0.1 whatwg-mimetype: 3.0.0 - ws: 8.20.0 + ws: 8.20.1 transitivePeerDependencies: - bufferutil - utf-8-validate @@ -21238,7 +21837,7 @@ snapshots: has-yarn@3.0.0: {} - hasown@2.0.2: + hasown@2.0.3: dependencies: function-bind: 1.1.2 @@ -21276,14 +21875,14 @@ snapshots: dependencies: '@types/hast': 3.0.4 '@types/unist': 3.0.3 - '@ungap/structured-clone': 1.3.0 + '@ungap/structured-clone': 1.3.1 hast-util-from-parse5: 8.0.3 hast-util-to-parse5: 8.0.1 html-void-elements: 3.0.0 mdast-util-to-hast: 13.2.1 parse5: 7.3.0 unist-util-position: 5.0.0 - unist-util-visit: 5.0.0 + unist-util-visit: 5.1.0 vfile: 6.0.3 web-namespaces: 2.0.1 zwitch: 2.0.4 @@ -21307,7 +21906,7 @@ snapshots: hast-util-to-estree@3.1.3: dependencies: - '@types/estree': 1.0.8 + '@types/estree': 1.0.9 '@types/estree-jsx': 1.0.5 '@types/hast': 3.0.4 comma-separated-tokens: 2.0.3 @@ -21328,7 +21927,7 @@ snapshots: hast-util-to-jsx-runtime@2.3.6: dependencies: - '@types/estree': 1.0.8 + '@types/estree': 1.0.9 '@types/hast': 3.0.4 '@types/unist': 3.0.3 comma-separated-tokens: 2.0.3 @@ -21432,7 +22031,7 @@ snapshots: he: 1.2.0 param-case: 3.0.4 relateurl: 0.2.7 - terser: 5.46.1 + terser: 5.47.1 html-minifier-terser@7.2.0: dependencies: @@ -21442,7 +22041,7 @@ snapshots: entities: 4.5.0 param-case: 3.0.4 relateurl: 0.2.7 - terser: 5.46.1 + terser: 5.47.1 html-tags@3.3.1: {} @@ -21456,7 +22055,7 @@ snapshots: html-void-elements@3.0.0: {} - html-webpack-plugin@5.6.5(webpack@5.106.2): + html-webpack-plugin@5.6.7(webpack@5.107.0(postcss@8.5.15)): dependencies: '@types/html-minifier-terser': 6.1.0 html-minifier-terser: 6.1.0 @@ -21464,7 +22063,7 @@ snapshots: pretty-error: 4.0.0 tapable: 2.3.3 optionalDependencies: - webpack: 5.106.2 + webpack: 5.107.0(postcss@8.5.15) htmlparser2@6.1.0: dependencies: @@ -21489,13 +22088,6 @@ snapshots: http-deceiver@1.2.7: {} - http-errors@1.6.3: - dependencies: - depd: 1.1.2 - inherits: 2.0.3 - setprototypeof: 1.1.0 - statuses: 1.5.0 - http-errors@1.8.1: dependencies: depd: 1.1.2 @@ -21520,6 +22112,7 @@ snapshots: debug: 4.4.3 transitivePeerDependencies: - supports-color + optional: true http-proxy-middleware@2.0.9(@types/express@4.17.25): dependencies: @@ -21536,7 +22129,7 @@ snapshots: http-proxy@1.18.1: dependencies: eventemitter3: 4.0.7 - follow-redirects: 1.15.11 + follow-redirects: 1.16.0 requires-port: 1.0.0 transitivePeerDependencies: - debug @@ -21559,6 +22152,7 @@ snapshots: debug: 4.4.3 transitivePeerDependencies: - supports-color + optional: true human-signals@2.1.0: {} @@ -21580,9 +22174,9 @@ snapshots: dependencies: safer-buffer: 2.1.2 - icss-utils@5.1.0(postcss@8.5.12): + icss-utils@5.1.0(postcss@8.5.15): dependencies: - postcss: 8.5.12 + postcss: 8.5.15 ieee754@1.2.1: {} @@ -21605,7 +22199,7 @@ snapshots: parent-module: 1.0.1 resolve-from: 4.0.0 - import-in-the-middle@3.0.0: + import-in-the-middle@3.0.1: dependencies: acorn: 8.16.0 acorn-import-attributes: 1.9.5(acorn@8.16.0) @@ -21614,6 +22208,8 @@ snapshots: import-lazy@4.0.0: {} + import-meta-resolve@4.2.0: {} + imurmurhash@0.1.4: {} indent-string@4.0.0: {} @@ -21627,8 +22223,6 @@ snapshots: once: 1.4.0 wrappy: 1.0.2 - inherits@2.0.3: {} - inherits@2.0.4: {} ini@1.3.8: {} @@ -21637,9 +22231,9 @@ snapshots: inline-style-parser@0.2.7: {} - inquirer@8.2.7(@types/node@24.12.2): + inquirer@8.2.7(@types/node@24.12.4): dependencies: - '@inquirer/external-editor': 1.0.3(@types/node@24.12.2) + '@inquirer/external-editor': 1.0.3(@types/node@24.12.4) ansi-escapes: 4.3.2 chalk: 4.1.2 cli-cursor: 3.1.0 @@ -21668,10 +22262,10 @@ snapshots: '@formatjs/icu-messageformat-parser': 2.11.4 tslib: 2.8.1 - intl-messageformat@11.2.1: + intl-messageformat@11.2.6: dependencies: - '@formatjs/fast-memoize': 3.1.2 - '@formatjs/icu-messageformat-parser': 3.5.4 + '@formatjs/fast-memoize': 3.1.5 + '@formatjs/icu-messageformat-parser': 3.5.9 invariant@2.2.4: dependencies: @@ -21691,11 +22285,9 @@ snapshots: transitivePeerDependencies: - supports-color - ip-address@10.1.0: {} - ipaddr.js@1.9.1: {} - ipaddr.js@2.3.0: {} + ipaddr.js@2.4.0: {} is-alphabetical@2.0.1: {} @@ -21714,15 +22306,15 @@ snapshots: is-builtin-module@5.0.0: dependencies: - builtin-modules: 5.0.0 + builtin-modules: 5.2.0 is-ci@3.0.1: dependencies: ci-info: 3.9.0 - is-core-module@2.16.1: + is-core-module@2.16.2: dependencies: - hasown: 2.0.2 + hasown: 2.0.3 is-decimal@2.0.1: {} @@ -21757,7 +22349,7 @@ snapshots: is-interactive@2.0.0: {} - is-network-error@1.3.0: {} + is-network-error@1.3.2: {} is-npm@6.1.0: {} @@ -21788,7 +22380,7 @@ snapshots: is-reference@3.0.3: dependencies: - '@types/estree': 1.0.8 + '@types/estree': 1.0.9 is-regexp@1.0.0: {} @@ -21858,7 +22450,7 @@ snapshots: jest-util@29.7.0: dependencies: '@jest/types': 29.6.3 - '@types/node': 24.12.2 + '@types/node': 24.12.4 chalk: 4.1.2 ci-info: 3.9.0 graceful-fs: 4.2.11 @@ -21866,13 +22458,13 @@ snapshots: jest-worker@27.5.1: dependencies: - '@types/node': 24.12.2 + '@types/node': 24.12.4 merge-stream: 2.0.0 supports-color: 8.1.1 jest-worker@29.7.0: dependencies: - '@types/node': 24.12.2 + '@types/node': 24.12.4 jest-util: 29.7.0 merge-stream: 2.0.0 supports-color: 8.1.1 @@ -21881,7 +22473,7 @@ snapshots: jiti@2.4.2: {} - jiti@2.6.1: {} + jiti@2.7.0: {} jmespath@0.16.0: {} @@ -21893,7 +22485,7 @@ snapshots: '@sideway/formula': 3.0.1 '@sideway/pinpoint': 2.0.0 - jose@6.2.2: {} + jose@6.2.3: {} js-tokens@10.0.0: {} @@ -21930,7 +22522,7 @@ snapshots: whatwg-encoding: 3.1.1 whatwg-mimetype: 4.0.0 whatwg-url: 14.2.0 - ws: 8.20.0 + ws: 8.20.1 xml-name-validator: 5.0.0 optionalDependencies: canvas: 3.2.3 @@ -21954,8 +22546,6 @@ snapshots: json-schema-typed@8.0.2: {} - json-schema@0.4.0: {} - json-source-map@0.6.1: {} json-stable-stringify-without-jsonify@1.0.1: {} @@ -21991,7 +22581,7 @@ snapshots: lodash.isstring: 4.0.1 lodash.once: 4.1.1 ms: 2.1.3 - semver: 7.7.4 + semver: 7.8.0 just-compare@2.3.0: {} @@ -22008,11 +22598,11 @@ snapshots: jwa: 2.0.1 safe-buffer: 5.2.1 - katex@0.16.27: + katex@0.16.47: dependencies: commander: 8.3.0 - kdbush@4.0.2: {} + kdbush@4.1.0: {} keygrip@1.1.0: dependencies: @@ -22052,7 +22642,7 @@ snapshots: on-finished: 2.4.1 parseurl: 1.3.3 statuses: 2.0.2 - type-is: 2.0.1 + type-is: 2.1.0 vary: 1.1.2 kysely-postgres-js@3.0.0(kysely@0.28.17)(postgres@3.4.9): @@ -22065,19 +22655,11 @@ snapshots: kysely@0.28.2: {} - langium@3.3.1: - dependencies: - chevrotain: 11.0.3 - chevrotain-allstar: 0.3.1(chevrotain@11.0.3) - vscode-languageserver: 9.0.1 - vscode-languageserver-textdocument: 1.0.12 - vscode-uri: 3.0.8 - latest-version@7.0.0: dependencies: package-json: 8.1.1 - launch-editor@2.12.0: + launch-editor@2.13.2: dependencies: picocolors: 1.1.1 shell-quote: 1.8.3 @@ -22160,7 +22742,7 @@ snapshots: load-tsconfig@0.2.5: {} - loader-runner@4.3.1: {} + loader-runner@4.3.2: {} loader-utils@2.0.4: dependencies: @@ -22182,8 +22764,6 @@ snapshots: dependencies: p-locate: 6.0.0 - lodash-es@4.17.21: {} - lodash-es@4.18.1: {} lodash.camelcase@4.3.0: {} @@ -22247,7 +22827,7 @@ snapshots: lru-cache@10.4.3: {} - lru-cache@11.3.5: {} + lru-cache@11.5.0: {} lru-cache@5.1.1: dependencies: @@ -22257,7 +22837,7 @@ snapshots: dependencies: es5-ext: 0.10.64 - lunr-languages@1.14.0: {} + lunr-languages@1.20.0: {} lunr@2.3.9: {} @@ -22275,13 +22855,13 @@ snapshots: magicast@0.3.5: dependencies: - '@babel/parser': 7.29.2 + '@babel/parser': 7.29.3 '@babel/types': 7.29.0 source-map-js: 1.2.1 - magicast@0.5.2: + magicast@0.5.3: dependencies: - '@babel/parser': 7.29.2 + '@babel/parser': 7.29.3 '@babel/types': 7.29.0 source-map-js: 1.2.1 @@ -22291,40 +22871,24 @@ snapshots: make-dir@4.0.0: dependencies: - semver: 7.7.4 - - make-fetch-happen@15.0.3: - dependencies: - '@npmcli/agent': 4.0.0 - cacache: 20.0.3 - http-cache-semantics: 4.2.0 - minipass: 7.1.3 - minipass-fetch: 5.0.1 - minipass-flush: 1.0.5 - minipass-pipeline: 1.2.4 - negotiator: 1.0.0 - proc-log: 6.1.0 - promise-retry: 2.0.1 - ssri: 13.0.1 - transitivePeerDependencies: - - supports-color + semver: 7.8.0 maplibre-gl@5.24.0: dependencies: '@mapbox/jsonlint-lines-primitives': 2.0.2 '@mapbox/point-geometry': 1.1.0 - '@mapbox/tiny-sdf': 2.1.0 + '@mapbox/tiny-sdf': 2.2.0 '@mapbox/unitbezier': 0.0.1 '@mapbox/vector-tile': 2.0.4 '@mapbox/whoots-js': 3.1.0 '@maplibre/geojson-vt': 6.1.0 - '@maplibre/maplibre-gl-style-spec': 24.8.1 + '@maplibre/maplibre-gl-style-spec': 24.8.5 '@maplibre/mlt': 1.1.9 '@maplibre/vt-pbf': 4.3.0 '@types/geojson': 7946.0.16 earcut: 3.0.2 gl-matrix: 3.4.4 - kdbush: 4.0.2 + kdbush: 4.1.0 murmurhash-js: 1.0.0 pbf: 4.0.1 potpack: 2.1.0 @@ -22349,7 +22913,7 @@ snapshots: '@types/unist': 3.0.3 ccount: 2.0.1 devlop: 1.1.0 - mdast-util-from-markdown: 2.0.2 + mdast-util-from-markdown: 2.0.3 mdast-util-to-markdown: 2.1.2 parse-entities: 4.0.2 stringify-entities: 4.0.4 @@ -22364,11 +22928,11 @@ snapshots: unist-util-is: 6.0.1 unist-util-visit-parents: 6.0.2 - mdast-util-from-markdown@2.0.2: + mdast-util-from-markdown@2.0.3: dependencies: '@types/mdast': 4.0.4 '@types/unist': 3.0.3 - decode-named-character-reference: 1.2.0 + decode-named-character-reference: 1.3.0 devlop: 1.1.0 mdast-util-to-string: 4.0.0 micromark: 4.0.2 @@ -22386,7 +22950,7 @@ snapshots: '@types/mdast': 4.0.4 devlop: 1.1.0 escape-string-regexp: 5.0.0 - mdast-util-from-markdown: 2.0.2 + mdast-util-from-markdown: 2.0.3 mdast-util-to-markdown: 2.1.2 micromark-extension-frontmatter: 2.0.0 transitivePeerDependencies: @@ -22404,7 +22968,7 @@ snapshots: dependencies: '@types/mdast': 4.0.4 devlop: 1.1.0 - mdast-util-from-markdown: 2.0.2 + mdast-util-from-markdown: 2.0.3 mdast-util-to-markdown: 2.1.2 micromark-util-normalize-identifier: 2.0.1 transitivePeerDependencies: @@ -22413,7 +22977,7 @@ snapshots: mdast-util-gfm-strikethrough@2.0.0: dependencies: '@types/mdast': 4.0.4 - mdast-util-from-markdown: 2.0.2 + mdast-util-from-markdown: 2.0.3 mdast-util-to-markdown: 2.1.2 transitivePeerDependencies: - supports-color @@ -22423,7 +22987,7 @@ snapshots: '@types/mdast': 4.0.4 devlop: 1.1.0 markdown-table: 3.0.4 - mdast-util-from-markdown: 2.0.2 + mdast-util-from-markdown: 2.0.3 mdast-util-to-markdown: 2.1.2 transitivePeerDependencies: - supports-color @@ -22432,14 +22996,14 @@ snapshots: dependencies: '@types/mdast': 4.0.4 devlop: 1.1.0 - mdast-util-from-markdown: 2.0.2 + mdast-util-from-markdown: 2.0.3 mdast-util-to-markdown: 2.1.2 transitivePeerDependencies: - supports-color mdast-util-gfm@3.1.0: dependencies: - mdast-util-from-markdown: 2.0.2 + mdast-util-from-markdown: 2.0.3 mdast-util-gfm-autolink-literal: 2.0.1 mdast-util-gfm-footnote: 2.1.0 mdast-util-gfm-strikethrough: 2.0.0 @@ -22455,7 +23019,7 @@ snapshots: '@types/hast': 3.0.4 '@types/mdast': 4.0.4 devlop: 1.1.0 - mdast-util-from-markdown: 2.0.2 + mdast-util-from-markdown: 2.0.3 mdast-util-to-markdown: 2.1.2 transitivePeerDependencies: - supports-color @@ -22468,7 +23032,7 @@ snapshots: '@types/unist': 3.0.3 ccount: 2.0.1 devlop: 1.1.0 - mdast-util-from-markdown: 2.0.2 + mdast-util-from-markdown: 2.0.3 mdast-util-to-markdown: 2.1.2 parse-entities: 4.0.2 stringify-entities: 4.0.4 @@ -22479,7 +23043,7 @@ snapshots: mdast-util-mdx@3.0.0: dependencies: - mdast-util-from-markdown: 2.0.2 + mdast-util-from-markdown: 2.0.3 mdast-util-mdx-expression: 2.0.1 mdast-util-mdx-jsx: 3.2.0 mdast-util-mdxjs-esm: 2.0.1 @@ -22493,7 +23057,7 @@ snapshots: '@types/hast': 3.0.4 '@types/mdast': 4.0.4 devlop: 1.1.0 - mdast-util-from-markdown: 2.0.2 + mdast-util-from-markdown: 2.0.3 mdast-util-to-markdown: 2.1.2 transitivePeerDependencies: - supports-color @@ -22507,12 +23071,12 @@ snapshots: dependencies: '@types/hast': 3.0.4 '@types/mdast': 4.0.4 - '@ungap/structured-clone': 1.3.0 + '@ungap/structured-clone': 1.3.1 devlop: 1.1.0 micromark-util-sanitize-uri: 2.0.1 trim-lines: 3.0.1 unist-util-position: 5.0.0 - unist-util-visit: 5.0.0 + unist-util-visit: 5.1.0 vfile: 6.0.3 mdast-util-to-markdown@2.1.2: @@ -22524,7 +23088,7 @@ snapshots: mdast-util-to-string: 4.0.0 micromark-util-classify-character: 2.0.1 micromark-util-decode-string: 2.0.1 - unist-util-visit: 5.0.0 + unist-util-visit: 5.1.0 zwitch: 2.0.4 mdast-util-to-string@4.0.0: @@ -22535,11 +23099,11 @@ snapshots: mdn-data@2.0.30: {} - mdn-data@2.27.1: {} + mdn-data@2.28.0: {} - media-chrome@4.19.0(react@19.2.5): + media-chrome@4.19.0(react@19.2.6): dependencies: - ce-la-react: 0.3.2(react@19.2.5) + ce-la-react: 0.3.2(react@19.2.6) transitivePeerDependencies: - react @@ -22564,7 +23128,7 @@ snapshots: '@jsonjoy.com/json-pack': 1.21.0(tslib@2.8.1) '@jsonjoy.com/util': 1.9.0(tslib@2.8.1) glob-to-regex.js: 1.2.0(tslib@2.8.1) - thingies: 2.5.0(tslib@2.8.1) + thingies: 2.6.0(tslib@2.8.1) tree-dump: 1.1.0(tslib@2.8.1) tslib: 2.8.1 @@ -22589,34 +23153,35 @@ snapshots: merge2@1.4.1: {} - mermaid@11.12.2: + mermaid@11.15.0: dependencies: - '@braintree/sanitize-url': 7.1.1 - '@iconify/utils': 3.1.0 - '@mermaid-js/parser': 0.6.3 + '@braintree/sanitize-url': 7.1.2 + '@iconify/utils': 3.1.3 + '@mermaid-js/parser': 1.1.1 '@types/d3': 7.4.3 - cytoscape: 3.33.1 - cytoscape-cose-bilkent: 4.1.0(cytoscape@3.33.1) - cytoscape-fcose: 2.2.0(cytoscape@3.33.1) + '@upsetjs/venn.js': 2.0.0 + cytoscape: 3.33.4 + cytoscape-cose-bilkent: 4.1.0(cytoscape@3.33.4) + cytoscape-fcose: 2.2.0(cytoscape@3.33.4) d3: 7.9.0 d3-sankey: 0.12.3 - dagre-d3-es: 7.0.13 - dayjs: 1.11.19 - dompurify: 3.3.1 - katex: 0.16.27 + dagre-d3-es: 7.0.14 + dayjs: 1.11.20 + dompurify: 3.4.5 + es-toolkit: 1.46.1 + katex: 0.16.47 khroma: 2.1.0 - lodash-es: 4.18.1 marked: 16.4.2 roughjs: 4.6.6 - stylis: 4.3.6 + stylis: 4.4.0 ts-dedent: 2.2.0 - uuid: 11.1.0 + uuid: 14.0.0 methods@1.1.2: {} micromark-core-commonmark@2.0.3: dependencies: - decode-named-character-reference: 1.2.0 + decode-named-character-reference: 1.3.0 devlop: 1.1.0 micromark-factory-destination: 2.0.1 micromark-factory-label: 2.0.1 @@ -22710,7 +23275,7 @@ snapshots: micromark-extension-mdx-expression@3.0.1: dependencies: - '@types/estree': 1.0.8 + '@types/estree': 1.0.9 devlop: 1.1.0 micromark-factory-mdx-expression: 2.0.3 micromark-factory-space: 2.0.1 @@ -22721,7 +23286,7 @@ snapshots: micromark-extension-mdx-jsx@3.0.2: dependencies: - '@types/estree': 1.0.8 + '@types/estree': 1.0.9 devlop: 1.1.0 estree-util-is-identifier-name: 3.0.0 micromark-factory-mdx-expression: 2.0.3 @@ -22738,7 +23303,7 @@ snapshots: micromark-extension-mdxjs-esm@3.0.0: dependencies: - '@types/estree': 1.0.8 + '@types/estree': 1.0.9 devlop: 1.1.0 micromark-core-commonmark: 2.0.3 micromark-util-character: 2.1.1 @@ -22774,7 +23339,7 @@ snapshots: micromark-factory-mdx-expression@2.0.3: dependencies: - '@types/estree': 1.0.8 + '@types/estree': 1.0.9 devlop: 1.1.0 micromark-factory-space: 2.0.1 micromark-util-character: 2.1.1 @@ -22839,7 +23404,7 @@ snapshots: micromark-util-decode-string@2.0.1: dependencies: - decode-named-character-reference: 1.2.0 + decode-named-character-reference: 1.3.0 micromark-util-character: 2.1.1 micromark-util-decode-numeric-character-reference: 2.0.2 micromark-util-symbol: 2.0.1 @@ -22848,7 +23413,7 @@ snapshots: micromark-util-events-to-acorn@2.0.3: dependencies: - '@types/estree': 1.0.8 + '@types/estree': 1.0.9 '@types/unist': 3.0.3 devlop: 1.1.0 estree-util-visit: 2.0.0 @@ -22889,9 +23454,9 @@ snapshots: micromark@4.0.2: dependencies: - '@types/debug': 4.1.12 + '@types/debug': 4.1.13 debug: 4.4.3 - decode-named-character-reference: 1.2.0 + decode-named-character-reference: 1.3.0 devlop: 1.1.0 micromark-core-commonmark: 2.0.3 micromark-factory-space: 2.0.1 @@ -22946,21 +23511,21 @@ snapshots: min-indent@1.0.1: {} - mini-css-extract-plugin@2.9.4(webpack@5.106.2): + mini-css-extract-plugin@2.10.2(webpack@5.107.0(postcss@8.5.15)): dependencies: schema-utils: 4.3.3 tapable: 2.3.3 - webpack: 5.106.2 + webpack: 5.107.0(postcss@8.5.15) minimalistic-assert@1.0.1: {} minimatch@10.2.5: dependencies: - brace-expansion: 5.0.5 + brace-expansion: 5.0.6 minimatch@3.1.5: dependencies: - brace-expansion: 1.1.12 + brace-expansion: 1.1.14 minimatch@5.1.9: dependencies: @@ -22972,30 +23537,6 @@ snapshots: minimist@1.2.8: {} - minipass-collect@2.0.1: - dependencies: - minipass: 7.1.3 - - minipass-fetch@5.0.1: - dependencies: - minipass: 7.1.3 - minipass-sized: 2.0.0 - minizlib: 3.1.0 - optionalDependencies: - encoding: 0.1.13 - - minipass-flush@1.0.5: - dependencies: - minipass: 3.3.6 - - minipass-pipeline@1.2.4: - dependencies: - minipass: 3.3.6 - - minipass-sized@2.0.0: - dependencies: - minipass: 7.1.3 - minipass@3.3.6: dependencies: yallist: 4.0.0 @@ -23021,14 +23562,7 @@ snapshots: mkdirp@3.0.1: {} - mlly@1.8.0: - dependencies: - acorn: 8.16.0 - pathe: 2.0.3 - pkg-types: 1.3.1 - ufo: 1.6.2 - - mnemonist@0.40.3: + mnemonist@0.40.4: dependencies: obliterator: 2.0.5 @@ -23058,7 +23592,7 @@ snapshots: '@msgpackr-extract/msgpackr-extract-win32-x64': 3.0.3 optional: true - msgpackr@1.11.5: + msgpackr@2.0.1: optionalDependencies: msgpackr-extract: 3.0.3 @@ -23088,12 +23622,12 @@ snapshots: object-assign: 4.1.1 thenify-all: 1.6.0 - nan@2.26.2: + nan@2.27.0: optional: true - nanoid@3.3.11: {} + nanoid@3.3.12: {} - nanoid@5.1.9: {} + nanoid@5.1.11: {} napi-build-utils@2.0.0: {} @@ -23116,59 +23650,59 @@ snapshots: neo-async@2.6.2: {} - nest-commander@3.20.1(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19)(@types/inquirer@8.2.12)(@types/node@24.12.2)(typescript@6.0.3): + nest-commander@3.20.1(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21)(@types/inquirer@8.2.12)(@types/node@24.12.4)(typescript@6.0.3): dependencies: '@fig/complete-commander': 3.2.0(commander@11.1.0) - '@golevelup/nestjs-discovery': 5.0.0(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19) - '@nestjs/common': 11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.19)(@nestjs/websockets@11.1.19)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@golevelup/nestjs-discovery': 5.0.0(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21) + '@nestjs/common': 11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.21(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.21)(@nestjs/websockets@11.1.21)(reflect-metadata@0.2.2)(rxjs@7.8.2) '@types/inquirer': 8.2.12 commander: 11.1.0 cosmiconfig: 8.3.6(typescript@6.0.3) - inquirer: 8.2.7(@types/node@24.12.2) + inquirer: 8.2.7(@types/node@24.12.4) transitivePeerDependencies: - '@types/node' - typescript - nestjs-cls@6.2.0(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19)(reflect-metadata@0.2.2)(rxjs@7.8.2): + nestjs-cls@6.2.0(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21)(reflect-metadata@0.2.2)(rxjs@7.8.2): dependencies: - '@nestjs/common': 11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.19)(@nestjs/websockets@11.1.19)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.21(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.21)(@nestjs/websockets@11.1.21)(reflect-metadata@0.2.2)(rxjs@7.8.2) reflect-metadata: 0.2.2 rxjs: 7.8.2 - nestjs-kysely@3.1.2(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19)(kysely@0.28.17)(reflect-metadata@0.2.2): - dependencies: - '@nestjs/common': 11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.19)(@nestjs/websockets@11.1.19)(reflect-metadata@0.2.2)(rxjs@7.8.2) - kysely: 0.28.17 - reflect-metadata: 0.2.2 - tslib: 2.8.1 - nestjs-kysely@3.1.2(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19)(kysely@0.28.2)(reflect-metadata@0.2.2): dependencies: '@nestjs/common': 11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.19)(@nestjs/websockets@11.1.19)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.21)(@nestjs/websockets@11.1.19)(reflect-metadata@0.2.2)(rxjs@7.8.2) kysely: 0.28.2 reflect-metadata: 0.2.2 tslib: 2.8.1 - nestjs-otel@8.0.2(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19): + nestjs-kysely@3.1.2(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21)(kysely@0.28.17)(reflect-metadata@0.2.2): dependencies: - '@nestjs/common': 11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.19)(@nestjs/websockets@11.1.19)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@opentelemetry/api': 1.9.0 - '@opentelemetry/host-metrics': 0.38.3(@opentelemetry/api@1.9.0) + '@nestjs/common': 11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.21(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.21)(@nestjs/websockets@11.1.21)(reflect-metadata@0.2.2)(rxjs@7.8.2) + kysely: 0.28.17 + reflect-metadata: 0.2.2 tslib: 2.8.1 - nestjs-zod@5.3.0(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/swagger@11.4.2(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19)(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2))(rxjs@7.8.2)(zod@4.3.6): + nestjs-otel@8.0.3(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21): dependencies: - '@nestjs/common': 11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.21(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.21)(@nestjs/websockets@11.1.21)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@opentelemetry/api': 1.9.1 + '@opentelemetry/host-metrics': 0.38.3(@opentelemetry/api@1.9.1) + tslib: 2.8.1 + + nestjs-zod@5.4.0(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/swagger@11.4.3(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21)(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(typescript@6.0.3))(rxjs@7.8.2)(zod@4.3.6): + dependencies: + '@nestjs/common': 11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) deepmerge: 4.3.1 rxjs: 7.8.2 zod: 4.3.6 optionalDependencies: - '@nestjs/swagger': 11.4.2(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19)(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2) + '@nestjs/swagger': 11.4.3(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21)(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(typescript@6.0.3) next-tick@1.1.0: {} @@ -23179,7 +23713,7 @@ snapshots: node-abi@3.92.0: dependencies: - semver: 7.7.4 + semver: 7.8.0 node-abort-controller@3.1.1: {} @@ -23188,7 +23722,7 @@ snapshots: node-addon-api@7.1.1: optional: true - node-addon-api@8.5.0: {} + node-addon-api@8.7.0: {} node-emoji@1.11.0: dependencies: @@ -23201,13 +23735,9 @@ snapshots: emojilib: 2.4.0 skin-tone: 2.0.0 - node-fetch@2.7.0(encoding@0.1.13): + node-fetch@2.7.0: dependencies: whatwg-url: 5.0.0 - optionalDependencies: - encoding: 0.1.13 - - node-forge@1.3.3: {} node-gyp-build-optional-packages@5.2.2: dependencies: @@ -23216,24 +23746,22 @@ snapshots: node-gyp-build@4.8.4: {} - node-gyp@12.2.0: + node-gyp@12.3.0: dependencies: env-paths: 2.2.1 exponential-backoff: 3.1.3 graceful-fs: 4.2.11 - make-fetch-happen: 15.0.3 nopt: 9.0.0 proc-log: 6.1.0 - semver: 7.7.4 - tar: 7.5.7 + semver: 7.8.0 + tar: 7.5.15 tinyglobby: 0.2.16 + undici: 6.25.0 which: 6.0.1 - transitivePeerDependencies: - - supports-color - node-releases@2.0.38: {} + node-releases@2.0.44: {} - nodemailer@8.0.5: {} + nodemailer@8.0.7: {} nopt@1.0.10: dependencies: @@ -23249,7 +23777,7 @@ snapshots: normalize-path@3.0.0: {} - normalize-url@8.1.0: {} + normalize-url@8.1.1: {} not@0.1.0: {} @@ -23272,11 +23800,11 @@ snapshots: dependencies: boolbase: 1.0.0 - null-loader@4.0.1(webpack@5.106.2): + null-loader@4.0.1(webpack@5.107.0(postcss@8.5.15)): dependencies: loader-utils: 2.0.4 schema-utils: 3.3.0 - webpack: 5.106.2 + webpack: 5.107.0(postcss@8.5.15) nwsapi@2.2.23: optional: true @@ -23285,9 +23813,9 @@ snapshots: dependencies: citty: 0.2.2 pathe: 2.0.3 - tinyexec: 1.1.1 + tinyexec: 1.1.2 - oauth4webapi@3.8.5: {} + oauth4webapi@3.8.6: {} object-assign@4.1.1: {} @@ -23299,7 +23827,7 @@ snapshots: object.assign@4.1.7: dependencies: - call-bind: 1.0.8 + call-bind: 1.0.9 call-bound: 1.0.4 define-properties: 1.2.1 es-object-atoms: 1.1.1 @@ -23312,16 +23840,16 @@ snapshots: obug@2.1.1: {} - oidc-provider@9.8.2: + oidc-provider@9.8.3: dependencies: '@koa/cors': 5.0.0 - '@koa/router': 15.4.0(koa@3.2.0) + '@koa/router': 15.5.0(koa@3.2.0) debug: 4.4.3 - eta: 4.5.1 - jose: 6.2.2 + eta: 4.6.0 + jose: 6.2.3 jsesc: 3.1.0 koa: 3.2.0 - nanoid: 5.1.9 + nanoid: 5.1.11 quick-lru: 7.3.0 raw-body: 3.0.2 transitivePeerDependencies: @@ -23347,14 +23875,14 @@ snapshots: open@10.2.0: dependencies: - default-browser: 5.4.0 + default-browser: 5.5.0 define-lazy-prop: 3.0.0 is-inside-container: 1.0.0 wsl-utils: 0.1.0 open@11.0.0: dependencies: - default-browser: 5.4.0 + default-browser: 5.5.0 define-lazy-prop: 3.0.0 is-in-ssh: 1.0.0 is-inside-container: 1.0.0 @@ -23369,10 +23897,10 @@ snapshots: opener@1.5.2: {} - openid-client@6.8.3: + openid-client@6.8.4: dependencies: - jose: 6.2.2 - oauth4webapi: 3.8.5 + jose: 6.2.3 + oauth4webapi: 3.8.6 optionator@0.9.4: dependencies: @@ -23439,8 +23967,6 @@ snapshots: dependencies: aggregate-error: 3.1.0 - p-map@7.0.4: {} - p-queue@6.6.2: dependencies: eventemitter3: 4.0.7 @@ -23449,7 +23975,7 @@ snapshots: p-retry@6.2.1: dependencies: '@types/retry': 0.12.2 - is-network-error: 1.3.0 + is-network-error: 1.3.2 retry: 0.13.1 p-timeout@3.2.0: @@ -23463,9 +23989,9 @@ snapshots: package-json@8.1.1: dependencies: got: 12.6.1 - registry-auth-token: 5.1.0 + registry-auth-token: 5.1.1 registry-url: 6.0.1 - semver: 7.7.4 + semver: 7.8.0 package-manager-detector@1.6.0: {} @@ -23483,7 +24009,7 @@ snapshots: '@types/unist': 2.0.11 character-entities-legacy: 3.0.0 character-reference-invalid: 2.0.1 - decode-named-character-reference: 1.2.0 + decode-named-character-reference: 1.3.0 is-alphanumerical: 2.0.1 is-decimal: 2.0.1 is-hexadecimal: 2.0.1 @@ -23547,7 +24073,7 @@ snapshots: path-scurry@2.0.2: dependencies: - lru-cache: 11.3.5 + lru-cache: 11.5.0 minipass: 7.1.3 path-source@0.1.3: @@ -23582,18 +24108,18 @@ snapshots: peberminta@0.9.0: {} - pg-cloudflare@1.3.0: + pg-cloudflare@1.4.0: optional: true - pg-connection-string@2.12.0: {} + pg-connection-string@2.13.0: {} pg-int8@1.0.1: {} - pg-pool@3.13.0(pg@8.20.0): + pg-pool@3.14.0(pg@8.21.0): dependencies: - pg: 8.20.0 + pg: 8.21.0 - pg-protocol@1.13.0: {} + pg-protocol@1.14.0: {} pg-types@2.2.0: dependencies: @@ -23603,15 +24129,15 @@ snapshots: postgres-date: 1.0.7 postgres-interval: 1.2.0 - pg@8.20.0: + pg@8.21.0: dependencies: - pg-connection-string: 2.12.0 - pg-pool: 3.13.0(pg@8.20.0) - pg-protocol: 1.13.0 + pg-connection-string: 2.13.0 + pg-pool: 3.14.0(pg@8.21.0) + pg-protocol: 1.14.0 pg-types: 2.2.0 pgpass: 1.0.5 optionalDependencies: - pg-cloudflare: 1.3.0 + pg-cloudflare: 1.4.0 pgpass@1.0.5: dependencies: @@ -23631,17 +24157,20 @@ snapshots: dependencies: find-up: 6.3.0 - pkg-types@1.3.1: + pkijs@3.4.0: dependencies: - confbox: 0.1.8 - mlly: 1.8.0 - pathe: 2.0.3 + '@noble/hashes': 1.4.0 + asn1js: 3.0.10 + bytestreamjs: 2.0.1 + pvtsutils: 1.3.6 + pvutils: 1.1.5 + tslib: 2.8.1 - playwright-core@1.59.1: {} + playwright-core@1.60.0: {} - playwright@1.59.1: + playwright@1.60.0: dependencies: - playwright-core: 1.59.1 + playwright-core: 1.60.0 optionalDependencies: fsevents: 2.3.2 @@ -23654,11 +24183,11 @@ snapshots: pmtiles@3.2.1: dependencies: '@types/leaflet': 1.9.21 - fflate: 0.8.2 + fflate: 0.8.3 pmtiles@4.4.1: dependencies: - fflate: 0.8.2 + fflate: 0.8.3 pngjs@5.0.0: {} @@ -23675,446 +24204,448 @@ snapshots: path-data-parser: 0.1.0 points-on-curve: 0.2.0 - postcss-attribute-case-insensitive@7.0.1(postcss@8.5.12): + postcss-attribute-case-insensitive@7.0.1(postcss@8.5.15): dependencies: - postcss: 8.5.12 + postcss: 8.5.15 postcss-selector-parser: 7.1.1 - postcss-calc@9.0.1(postcss@8.5.12): + postcss-calc@9.0.1(postcss@8.5.15): dependencies: - postcss: 8.5.12 + postcss: 8.5.15 postcss-selector-parser: 6.1.2 postcss-value-parser: 4.2.0 - postcss-clamp@4.1.0(postcss@8.5.12): + postcss-clamp@4.1.0(postcss@8.5.15): dependencies: - postcss: 8.5.12 + postcss: 8.5.15 postcss-value-parser: 4.2.0 - postcss-color-functional-notation@7.0.12(postcss@8.5.12): + postcss-color-functional-notation@7.0.12(postcss@8.5.15): dependencies: '@csstools/css-color-parser': 3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) '@csstools/css-tokenizer': 3.0.4 - '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.12) - '@csstools/utilities': 2.0.0(postcss@8.5.12) - postcss: 8.5.12 + '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.15) + '@csstools/utilities': 2.0.0(postcss@8.5.15) + postcss: 8.5.15 - postcss-color-hex-alpha@10.0.0(postcss@8.5.12): + postcss-color-hex-alpha@10.0.0(postcss@8.5.15): dependencies: - '@csstools/utilities': 2.0.0(postcss@8.5.12) - postcss: 8.5.12 + '@csstools/utilities': 2.0.0(postcss@8.5.15) + postcss: 8.5.15 postcss-value-parser: 4.2.0 - postcss-color-rebeccapurple@10.0.0(postcss@8.5.12): + postcss-color-rebeccapurple@10.0.0(postcss@8.5.15): dependencies: - '@csstools/utilities': 2.0.0(postcss@8.5.12) - postcss: 8.5.12 + '@csstools/utilities': 2.0.0(postcss@8.5.15) + postcss: 8.5.15 postcss-value-parser: 4.2.0 - postcss-colormin@6.1.0(postcss@8.5.12): + postcss-colormin@6.1.0(postcss@8.5.15): dependencies: browserslist: 4.28.2 caniuse-api: 3.0.0 colord: 2.9.3 - postcss: 8.5.12 + postcss: 8.5.15 postcss-value-parser: 4.2.0 - postcss-convert-values@6.1.0(postcss@8.5.12): + postcss-convert-values@6.1.0(postcss@8.5.15): dependencies: browserslist: 4.28.2 - postcss: 8.5.12 + postcss: 8.5.15 postcss-value-parser: 4.2.0 - postcss-custom-media@11.0.6(postcss@8.5.12): + postcss-custom-media@11.0.6(postcss@8.5.15): dependencies: '@csstools/cascade-layer-name-parser': 2.0.5(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) '@csstools/css-tokenizer': 3.0.4 '@csstools/media-query-list-parser': 4.0.3(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) - postcss: 8.5.12 + postcss: 8.5.15 - postcss-custom-properties@14.0.6(postcss@8.5.12): + postcss-custom-properties@14.0.6(postcss@8.5.15): dependencies: '@csstools/cascade-layer-name-parser': 2.0.5(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) '@csstools/css-tokenizer': 3.0.4 - '@csstools/utilities': 2.0.0(postcss@8.5.12) - postcss: 8.5.12 + '@csstools/utilities': 2.0.0(postcss@8.5.15) + postcss: 8.5.15 postcss-value-parser: 4.2.0 - postcss-custom-selectors@8.0.5(postcss@8.5.12): + postcss-custom-selectors@8.0.5(postcss@8.5.15): dependencies: '@csstools/cascade-layer-name-parser': 2.0.5(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) '@csstools/css-tokenizer': 3.0.4 - postcss: 8.5.12 + postcss: 8.5.15 postcss-selector-parser: 7.1.1 - postcss-dir-pseudo-class@9.0.1(postcss@8.5.12): + postcss-dir-pseudo-class@9.0.1(postcss@8.5.15): dependencies: - postcss: 8.5.12 + postcss: 8.5.15 postcss-selector-parser: 7.1.1 - postcss-discard-comments@6.0.2(postcss@8.5.12): + postcss-discard-comments@6.0.2(postcss@8.5.15): dependencies: - postcss: 8.5.12 + postcss: 8.5.15 - postcss-discard-duplicates@6.0.3(postcss@8.5.12): + postcss-discard-duplicates@6.0.3(postcss@8.5.15): dependencies: - postcss: 8.5.12 + postcss: 8.5.15 - postcss-discard-empty@6.0.3(postcss@8.5.12): + postcss-discard-empty@6.0.3(postcss@8.5.15): dependencies: - postcss: 8.5.12 + postcss: 8.5.15 - postcss-discard-overridden@6.0.2(postcss@8.5.12): + postcss-discard-overridden@6.0.2(postcss@8.5.15): dependencies: - postcss: 8.5.12 + postcss: 8.5.15 - postcss-discard-unused@6.0.5(postcss@8.5.12): + postcss-discard-unused@6.0.5(postcss@8.5.15): dependencies: - postcss: 8.5.12 + postcss: 8.5.15 postcss-selector-parser: 6.1.2 - postcss-double-position-gradients@6.0.4(postcss@8.5.12): + postcss-double-position-gradients@6.0.4(postcss@8.5.15): dependencies: - '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.12) - '@csstools/utilities': 2.0.0(postcss@8.5.12) - postcss: 8.5.12 + '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.15) + '@csstools/utilities': 2.0.0(postcss@8.5.15) + postcss: 8.5.15 postcss-value-parser: 4.2.0 - postcss-focus-visible@10.0.1(postcss@8.5.12): + postcss-focus-visible@10.0.1(postcss@8.5.15): dependencies: - postcss: 8.5.12 + postcss: 8.5.15 postcss-selector-parser: 7.1.1 - postcss-focus-within@9.0.1(postcss@8.5.12): + postcss-focus-within@9.0.1(postcss@8.5.15): dependencies: - postcss: 8.5.12 + postcss: 8.5.15 postcss-selector-parser: 7.1.1 - postcss-font-variant@5.0.0(postcss@8.5.12): + postcss-font-variant@5.0.0(postcss@8.5.15): dependencies: - postcss: 8.5.12 + postcss: 8.5.15 - postcss-gap-properties@6.0.0(postcss@8.5.12): + postcss-gap-properties@6.0.0(postcss@8.5.15): dependencies: - postcss: 8.5.12 + postcss: 8.5.15 - postcss-image-set-function@7.0.0(postcss@8.5.12): + postcss-image-set-function@7.0.0(postcss@8.5.15): dependencies: - '@csstools/utilities': 2.0.0(postcss@8.5.12) - postcss: 8.5.12 + '@csstools/utilities': 2.0.0(postcss@8.5.15) + postcss: 8.5.15 postcss-value-parser: 4.2.0 - postcss-import@15.1.0(postcss@8.5.12): + postcss-import@15.1.0(postcss@8.5.15): dependencies: - postcss: 8.5.12 + postcss: 8.5.15 postcss-value-parser: 4.2.0 read-cache: 1.0.0 - resolve: 1.22.11 + resolve: 1.22.12 - postcss-js@4.1.0(postcss@8.5.12): + postcss-js@4.1.0(postcss@8.5.15): dependencies: camelcase-css: 2.0.1 - postcss: 8.5.12 + postcss: 8.5.15 - postcss-lab-function@7.0.12(postcss@8.5.12): + postcss-lab-function@7.0.12(postcss@8.5.15): dependencies: '@csstools/css-color-parser': 3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) '@csstools/css-tokenizer': 3.0.4 - '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.12) - '@csstools/utilities': 2.0.0(postcss@8.5.12) - postcss: 8.5.12 + '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.15) + '@csstools/utilities': 2.0.0(postcss@8.5.15) + postcss: 8.5.15 - postcss-load-config@3.1.4(postcss@8.5.12): + postcss-load-config@3.1.4(postcss@8.5.15): dependencies: lilconfig: 2.1.0 yaml: 1.10.3 optionalDependencies: - postcss: 8.5.12 + postcss: 8.5.15 - postcss-load-config@6.0.1(jiti@1.21.7)(postcss@8.5.12)(tsx@4.21.0)(yaml@2.8.3): + postcss-load-config@6.0.1(jiti@1.21.7)(postcss@8.5.15)(tsx@4.22.3)(yaml@2.9.0): dependencies: lilconfig: 3.1.3 optionalDependencies: jiti: 1.21.7 - postcss: 8.5.12 - tsx: 4.21.0 - yaml: 2.8.3 + postcss: 8.5.15 + tsx: 4.22.3 + yaml: 2.9.0 - postcss-loader@7.3.4(postcss@8.5.12)(typescript@6.0.3)(webpack@5.106.2): + postcss-loader@7.3.4(postcss@8.5.15)(typescript@6.0.3)(webpack@5.107.0(postcss@8.5.15)): dependencies: cosmiconfig: 8.3.6(typescript@6.0.3) jiti: 1.21.7 - postcss: 8.5.12 - semver: 7.7.4 - webpack: 5.106.2 + postcss: 8.5.15 + semver: 7.8.0 + webpack: 5.107.0(postcss@8.5.15) transitivePeerDependencies: - typescript - postcss-logical@8.1.0(postcss@8.5.12): + postcss-logical@8.1.0(postcss@8.5.15): dependencies: - postcss: 8.5.12 + postcss: 8.5.15 postcss-value-parser: 4.2.0 - postcss-merge-idents@6.0.3(postcss@8.5.12): + postcss-merge-idents@6.0.3(postcss@8.5.15): dependencies: - cssnano-utils: 4.0.2(postcss@8.5.12) - postcss: 8.5.12 + cssnano-utils: 4.0.2(postcss@8.5.15) + postcss: 8.5.15 postcss-value-parser: 4.2.0 - postcss-merge-longhand@6.0.5(postcss@8.5.12): + postcss-merge-longhand@6.0.5(postcss@8.5.15): dependencies: - postcss: 8.5.12 + postcss: 8.5.15 postcss-value-parser: 4.2.0 - stylehacks: 6.1.1(postcss@8.5.12) + stylehacks: 6.1.1(postcss@8.5.15) - postcss-merge-rules@6.1.1(postcss@8.5.12): + postcss-merge-rules@6.1.1(postcss@8.5.15): dependencies: browserslist: 4.28.2 caniuse-api: 3.0.0 - cssnano-utils: 4.0.2(postcss@8.5.12) - postcss: 8.5.12 + cssnano-utils: 4.0.2(postcss@8.5.15) + postcss: 8.5.15 postcss-selector-parser: 6.1.2 - postcss-minify-font-values@6.1.0(postcss@8.5.12): + postcss-minify-font-values@6.1.0(postcss@8.5.15): dependencies: - postcss: 8.5.12 + postcss: 8.5.15 postcss-value-parser: 4.2.0 - postcss-minify-gradients@6.0.3(postcss@8.5.12): + postcss-minify-gradients@6.0.3(postcss@8.5.15): dependencies: colord: 2.9.3 - cssnano-utils: 4.0.2(postcss@8.5.12) - postcss: 8.5.12 + cssnano-utils: 4.0.2(postcss@8.5.15) + postcss: 8.5.15 postcss-value-parser: 4.2.0 - postcss-minify-params@6.1.0(postcss@8.5.12): + postcss-minify-params@6.1.0(postcss@8.5.15): dependencies: browserslist: 4.28.2 - cssnano-utils: 4.0.2(postcss@8.5.12) - postcss: 8.5.12 + cssnano-utils: 4.0.2(postcss@8.5.15) + postcss: 8.5.15 postcss-value-parser: 4.2.0 - postcss-minify-selectors@6.0.4(postcss@8.5.12): + postcss-minify-selectors@6.0.4(postcss@8.5.15): dependencies: - postcss: 8.5.12 + postcss: 8.5.15 postcss-selector-parser: 6.1.2 - postcss-modules-extract-imports@3.1.0(postcss@8.5.12): + postcss-modules-extract-imports@3.1.0(postcss@8.5.15): dependencies: - postcss: 8.5.12 + postcss: 8.5.15 - postcss-modules-local-by-default@4.2.0(postcss@8.5.12): + postcss-modules-local-by-default@4.2.0(postcss@8.5.15): dependencies: - icss-utils: 5.1.0(postcss@8.5.12) - postcss: 8.5.12 + icss-utils: 5.1.0(postcss@8.5.15) + postcss: 8.5.15 postcss-selector-parser: 7.1.1 postcss-value-parser: 4.2.0 - postcss-modules-scope@3.2.1(postcss@8.5.12): + postcss-modules-scope@3.2.1(postcss@8.5.15): dependencies: - postcss: 8.5.12 + postcss: 8.5.15 postcss-selector-parser: 7.1.1 - postcss-modules-values@4.0.0(postcss@8.5.12): + postcss-modules-values@4.0.0(postcss@8.5.15): dependencies: - icss-utils: 5.1.0(postcss@8.5.12) - postcss: 8.5.12 + icss-utils: 5.1.0(postcss@8.5.15) + postcss: 8.5.15 - postcss-nested@6.2.0(postcss@8.5.12): + postcss-nested@6.2.0(postcss@8.5.15): dependencies: - postcss: 8.5.12 + postcss: 8.5.15 postcss-selector-parser: 6.1.2 - postcss-nesting@13.0.2(postcss@8.5.12): + postcss-nesting@13.0.2(postcss@8.5.15): dependencies: '@csstools/selector-resolve-nested': 3.1.0(postcss-selector-parser@7.1.1) '@csstools/selector-specificity': 5.0.0(postcss-selector-parser@7.1.1) - postcss: 8.5.12 + postcss: 8.5.15 postcss-selector-parser: 7.1.1 - postcss-normalize-charset@6.0.2(postcss@8.5.12): + postcss-normalize-charset@6.0.2(postcss@8.5.15): dependencies: - postcss: 8.5.12 + postcss: 8.5.15 - postcss-normalize-display-values@6.0.2(postcss@8.5.12): + postcss-normalize-display-values@6.0.2(postcss@8.5.15): dependencies: - postcss: 8.5.12 + postcss: 8.5.15 postcss-value-parser: 4.2.0 - postcss-normalize-positions@6.0.2(postcss@8.5.12): + postcss-normalize-positions@6.0.2(postcss@8.5.15): dependencies: - postcss: 8.5.12 + postcss: 8.5.15 postcss-value-parser: 4.2.0 - postcss-normalize-repeat-style@6.0.2(postcss@8.5.12): + postcss-normalize-repeat-style@6.0.2(postcss@8.5.15): dependencies: - postcss: 8.5.12 + postcss: 8.5.15 postcss-value-parser: 4.2.0 - postcss-normalize-string@6.0.2(postcss@8.5.12): + postcss-normalize-string@6.0.2(postcss@8.5.15): dependencies: - postcss: 8.5.12 + postcss: 8.5.15 postcss-value-parser: 4.2.0 - postcss-normalize-timing-functions@6.0.2(postcss@8.5.12): + postcss-normalize-timing-functions@6.0.2(postcss@8.5.15): dependencies: - postcss: 8.5.12 + postcss: 8.5.15 postcss-value-parser: 4.2.0 - postcss-normalize-unicode@6.1.0(postcss@8.5.12): + postcss-normalize-unicode@6.1.0(postcss@8.5.15): dependencies: browserslist: 4.28.2 - postcss: 8.5.12 + postcss: 8.5.15 postcss-value-parser: 4.2.0 - postcss-normalize-url@6.0.2(postcss@8.5.12): + postcss-normalize-url@6.0.2(postcss@8.5.15): dependencies: - postcss: 8.5.12 + postcss: 8.5.15 postcss-value-parser: 4.2.0 - postcss-normalize-whitespace@6.0.2(postcss@8.5.12): + postcss-normalize-whitespace@6.0.2(postcss@8.5.15): dependencies: - postcss: 8.5.12 + postcss: 8.5.15 postcss-value-parser: 4.2.0 - postcss-opacity-percentage@3.0.0(postcss@8.5.12): + postcss-opacity-percentage@3.0.0(postcss@8.5.15): dependencies: - postcss: 8.5.12 + postcss: 8.5.15 - postcss-ordered-values@6.0.2(postcss@8.5.12): + postcss-ordered-values@6.0.2(postcss@8.5.15): dependencies: - cssnano-utils: 4.0.2(postcss@8.5.12) - postcss: 8.5.12 + cssnano-utils: 4.0.2(postcss@8.5.15) + postcss: 8.5.15 postcss-value-parser: 4.2.0 - postcss-overflow-shorthand@6.0.0(postcss@8.5.12): + postcss-overflow-shorthand@6.0.0(postcss@8.5.15): dependencies: - postcss: 8.5.12 + postcss: 8.5.15 postcss-value-parser: 4.2.0 - postcss-page-break@3.0.4(postcss@8.5.12): + postcss-page-break@3.0.4(postcss@8.5.15): dependencies: - postcss: 8.5.12 + postcss: 8.5.15 - postcss-place@10.0.0(postcss@8.5.12): + postcss-place@10.0.0(postcss@8.5.15): dependencies: - postcss: 8.5.12 + postcss: 8.5.15 postcss-value-parser: 4.2.0 - postcss-preset-env@10.5.0(postcss@8.5.12): + postcss-preset-env@10.6.1(postcss@8.5.15): dependencies: - '@csstools/postcss-alpha-function': 1.0.1(postcss@8.5.12) - '@csstools/postcss-cascade-layers': 5.0.2(postcss@8.5.12) - '@csstools/postcss-color-function': 4.0.12(postcss@8.5.12) - '@csstools/postcss-color-function-display-p3-linear': 1.0.1(postcss@8.5.12) - '@csstools/postcss-color-mix-function': 3.0.12(postcss@8.5.12) - '@csstools/postcss-color-mix-variadic-function-arguments': 1.0.2(postcss@8.5.12) - '@csstools/postcss-content-alt-text': 2.0.8(postcss@8.5.12) - '@csstools/postcss-contrast-color-function': 2.0.12(postcss@8.5.12) - '@csstools/postcss-exponential-functions': 2.0.9(postcss@8.5.12) - '@csstools/postcss-font-format-keywords': 4.0.0(postcss@8.5.12) - '@csstools/postcss-gamut-mapping': 2.0.11(postcss@8.5.12) - '@csstools/postcss-gradients-interpolation-method': 5.0.12(postcss@8.5.12) - '@csstools/postcss-hwb-function': 4.0.12(postcss@8.5.12) - '@csstools/postcss-ic-unit': 4.0.4(postcss@8.5.12) - '@csstools/postcss-initial': 2.0.1(postcss@8.5.12) - '@csstools/postcss-is-pseudo-class': 5.0.3(postcss@8.5.12) - '@csstools/postcss-light-dark-function': 2.0.11(postcss@8.5.12) - '@csstools/postcss-logical-float-and-clear': 3.0.0(postcss@8.5.12) - '@csstools/postcss-logical-overflow': 2.0.0(postcss@8.5.12) - '@csstools/postcss-logical-overscroll-behavior': 2.0.0(postcss@8.5.12) - '@csstools/postcss-logical-resize': 3.0.0(postcss@8.5.12) - '@csstools/postcss-logical-viewport-units': 3.0.4(postcss@8.5.12) - '@csstools/postcss-media-minmax': 2.0.9(postcss@8.5.12) - '@csstools/postcss-media-queries-aspect-ratio-number-values': 3.0.5(postcss@8.5.12) - '@csstools/postcss-nested-calc': 4.0.0(postcss@8.5.12) - '@csstools/postcss-normalize-display-values': 4.0.0(postcss@8.5.12) - '@csstools/postcss-oklab-function': 4.0.12(postcss@8.5.12) - '@csstools/postcss-position-area-property': 1.0.0(postcss@8.5.12) - '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.12) - '@csstools/postcss-random-function': 2.0.1(postcss@8.5.12) - '@csstools/postcss-relative-color-syntax': 3.0.12(postcss@8.5.12) - '@csstools/postcss-scope-pseudo-class': 4.0.1(postcss@8.5.12) - '@csstools/postcss-sign-functions': 1.1.4(postcss@8.5.12) - '@csstools/postcss-stepped-value-functions': 4.0.9(postcss@8.5.12) - '@csstools/postcss-system-ui-font-family': 1.0.0(postcss@8.5.12) - '@csstools/postcss-text-decoration-shorthand': 4.0.3(postcss@8.5.12) - '@csstools/postcss-trigonometric-functions': 4.0.9(postcss@8.5.12) - '@csstools/postcss-unset-value': 4.0.0(postcss@8.5.12) - autoprefixer: 10.5.0(postcss@8.5.12) + '@csstools/postcss-alpha-function': 1.0.1(postcss@8.5.15) + '@csstools/postcss-cascade-layers': 5.0.2(postcss@8.5.15) + '@csstools/postcss-color-function': 4.0.12(postcss@8.5.15) + '@csstools/postcss-color-function-display-p3-linear': 1.0.1(postcss@8.5.15) + '@csstools/postcss-color-mix-function': 3.0.12(postcss@8.5.15) + '@csstools/postcss-color-mix-variadic-function-arguments': 1.0.2(postcss@8.5.15) + '@csstools/postcss-content-alt-text': 2.0.8(postcss@8.5.15) + '@csstools/postcss-contrast-color-function': 2.0.12(postcss@8.5.15) + '@csstools/postcss-exponential-functions': 2.0.9(postcss@8.5.15) + '@csstools/postcss-font-format-keywords': 4.0.0(postcss@8.5.15) + '@csstools/postcss-gamut-mapping': 2.0.11(postcss@8.5.15) + '@csstools/postcss-gradients-interpolation-method': 5.0.12(postcss@8.5.15) + '@csstools/postcss-hwb-function': 4.0.12(postcss@8.5.15) + '@csstools/postcss-ic-unit': 4.0.4(postcss@8.5.15) + '@csstools/postcss-initial': 2.0.1(postcss@8.5.15) + '@csstools/postcss-is-pseudo-class': 5.0.3(postcss@8.5.15) + '@csstools/postcss-light-dark-function': 2.0.11(postcss@8.5.15) + '@csstools/postcss-logical-float-and-clear': 3.0.0(postcss@8.5.15) + '@csstools/postcss-logical-overflow': 2.0.0(postcss@8.5.15) + '@csstools/postcss-logical-overscroll-behavior': 2.0.0(postcss@8.5.15) + '@csstools/postcss-logical-resize': 3.0.0(postcss@8.5.15) + '@csstools/postcss-logical-viewport-units': 3.0.4(postcss@8.5.15) + '@csstools/postcss-media-minmax': 2.0.9(postcss@8.5.15) + '@csstools/postcss-media-queries-aspect-ratio-number-values': 3.0.5(postcss@8.5.15) + '@csstools/postcss-nested-calc': 4.0.0(postcss@8.5.15) + '@csstools/postcss-normalize-display-values': 4.0.1(postcss@8.5.15) + '@csstools/postcss-oklab-function': 4.0.12(postcss@8.5.15) + '@csstools/postcss-position-area-property': 1.0.0(postcss@8.5.15) + '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.15) + '@csstools/postcss-property-rule-prelude-list': 1.0.0(postcss@8.5.15) + '@csstools/postcss-random-function': 2.0.1(postcss@8.5.15) + '@csstools/postcss-relative-color-syntax': 3.0.12(postcss@8.5.15) + '@csstools/postcss-scope-pseudo-class': 4.0.1(postcss@8.5.15) + '@csstools/postcss-sign-functions': 1.1.4(postcss@8.5.15) + '@csstools/postcss-stepped-value-functions': 4.0.9(postcss@8.5.15) + '@csstools/postcss-syntax-descriptor-syntax-production': 1.0.1(postcss@8.5.15) + '@csstools/postcss-system-ui-font-family': 1.0.0(postcss@8.5.15) + '@csstools/postcss-text-decoration-shorthand': 4.0.3(postcss@8.5.15) + '@csstools/postcss-trigonometric-functions': 4.0.9(postcss@8.5.15) + '@csstools/postcss-unset-value': 4.0.0(postcss@8.5.15) + autoprefixer: 10.5.0(postcss@8.5.15) browserslist: 4.28.2 - css-blank-pseudo: 7.0.1(postcss@8.5.12) - css-has-pseudo: 7.0.3(postcss@8.5.12) - css-prefers-color-scheme: 10.0.0(postcss@8.5.12) - cssdb: 8.5.2 - postcss: 8.5.12 - postcss-attribute-case-insensitive: 7.0.1(postcss@8.5.12) - postcss-clamp: 4.1.0(postcss@8.5.12) - postcss-color-functional-notation: 7.0.12(postcss@8.5.12) - postcss-color-hex-alpha: 10.0.0(postcss@8.5.12) - postcss-color-rebeccapurple: 10.0.0(postcss@8.5.12) - postcss-custom-media: 11.0.6(postcss@8.5.12) - postcss-custom-properties: 14.0.6(postcss@8.5.12) - postcss-custom-selectors: 8.0.5(postcss@8.5.12) - postcss-dir-pseudo-class: 9.0.1(postcss@8.5.12) - postcss-double-position-gradients: 6.0.4(postcss@8.5.12) - postcss-focus-visible: 10.0.1(postcss@8.5.12) - postcss-focus-within: 9.0.1(postcss@8.5.12) - postcss-font-variant: 5.0.0(postcss@8.5.12) - postcss-gap-properties: 6.0.0(postcss@8.5.12) - postcss-image-set-function: 7.0.0(postcss@8.5.12) - postcss-lab-function: 7.0.12(postcss@8.5.12) - postcss-logical: 8.1.0(postcss@8.5.12) - postcss-nesting: 13.0.2(postcss@8.5.12) - postcss-opacity-percentage: 3.0.0(postcss@8.5.12) - postcss-overflow-shorthand: 6.0.0(postcss@8.5.12) - postcss-page-break: 3.0.4(postcss@8.5.12) - postcss-place: 10.0.0(postcss@8.5.12) - postcss-pseudo-class-any-link: 10.0.1(postcss@8.5.12) - postcss-replace-overflow-wrap: 4.0.0(postcss@8.5.12) - postcss-selector-not: 8.0.1(postcss@8.5.12) + css-blank-pseudo: 7.0.1(postcss@8.5.15) + css-has-pseudo: 7.0.3(postcss@8.5.15) + css-prefers-color-scheme: 10.0.0(postcss@8.5.15) + cssdb: 8.9.0 + postcss: 8.5.15 + postcss-attribute-case-insensitive: 7.0.1(postcss@8.5.15) + postcss-clamp: 4.1.0(postcss@8.5.15) + postcss-color-functional-notation: 7.0.12(postcss@8.5.15) + postcss-color-hex-alpha: 10.0.0(postcss@8.5.15) + postcss-color-rebeccapurple: 10.0.0(postcss@8.5.15) + postcss-custom-media: 11.0.6(postcss@8.5.15) + postcss-custom-properties: 14.0.6(postcss@8.5.15) + postcss-custom-selectors: 8.0.5(postcss@8.5.15) + postcss-dir-pseudo-class: 9.0.1(postcss@8.5.15) + postcss-double-position-gradients: 6.0.4(postcss@8.5.15) + postcss-focus-visible: 10.0.1(postcss@8.5.15) + postcss-focus-within: 9.0.1(postcss@8.5.15) + postcss-font-variant: 5.0.0(postcss@8.5.15) + postcss-gap-properties: 6.0.0(postcss@8.5.15) + postcss-image-set-function: 7.0.0(postcss@8.5.15) + postcss-lab-function: 7.0.12(postcss@8.5.15) + postcss-logical: 8.1.0(postcss@8.5.15) + postcss-nesting: 13.0.2(postcss@8.5.15) + postcss-opacity-percentage: 3.0.0(postcss@8.5.15) + postcss-overflow-shorthand: 6.0.0(postcss@8.5.15) + postcss-page-break: 3.0.4(postcss@8.5.15) + postcss-place: 10.0.0(postcss@8.5.15) + postcss-pseudo-class-any-link: 10.0.1(postcss@8.5.15) + postcss-replace-overflow-wrap: 4.0.0(postcss@8.5.15) + postcss-selector-not: 8.0.1(postcss@8.5.15) - postcss-pseudo-class-any-link@10.0.1(postcss@8.5.12): + postcss-pseudo-class-any-link@10.0.1(postcss@8.5.15): dependencies: - postcss: 8.5.12 + postcss: 8.5.15 postcss-selector-parser: 7.1.1 - postcss-reduce-idents@6.0.3(postcss@8.5.12): + postcss-reduce-idents@6.0.3(postcss@8.5.15): dependencies: - postcss: 8.5.12 + postcss: 8.5.15 postcss-value-parser: 4.2.0 - postcss-reduce-initial@6.1.0(postcss@8.5.12): + postcss-reduce-initial@6.1.0(postcss@8.5.15): dependencies: browserslist: 4.28.2 caniuse-api: 3.0.0 - postcss: 8.5.12 + postcss: 8.5.15 - postcss-reduce-transforms@6.0.2(postcss@8.5.12): + postcss-reduce-transforms@6.0.2(postcss@8.5.15): dependencies: - postcss: 8.5.12 + postcss: 8.5.15 postcss-value-parser: 4.2.0 - postcss-replace-overflow-wrap@4.0.0(postcss@8.5.12): + postcss-replace-overflow-wrap@4.0.0(postcss@8.5.15): dependencies: - postcss: 8.5.12 + postcss: 8.5.15 - postcss-safe-parser@7.0.1(postcss@8.5.12): + postcss-safe-parser@7.0.1(postcss@8.5.15): dependencies: - postcss: 8.5.12 + postcss: 8.5.15 - postcss-scss@4.0.9(postcss@8.5.12): + postcss-scss@4.0.9(postcss@8.5.15): dependencies: - postcss: 8.5.12 + postcss: 8.5.15 - postcss-selector-not@8.0.1(postcss@8.5.12): + postcss-selector-not@8.0.1(postcss@8.5.15): dependencies: - postcss: 8.5.12 + postcss: 8.5.15 postcss-selector-parser: 7.1.1 postcss-selector-parser@6.1.2: @@ -24127,31 +24658,31 @@ snapshots: cssesc: 3.0.0 util-deprecate: 1.0.2 - postcss-sort-media-queries@5.2.0(postcss@8.5.12): + postcss-sort-media-queries@5.2.0(postcss@8.5.15): dependencies: - postcss: 8.5.12 + postcss: 8.5.15 sort-css-media-queries: 2.2.0 - postcss-svgo@6.0.3(postcss@8.5.12): + postcss-svgo@6.0.3(postcss@8.5.15): dependencies: - postcss: 8.5.12 + postcss: 8.5.15 postcss-value-parser: 4.2.0 - svgo: 3.3.2 + svgo: 3.3.3 - postcss-unique-selectors@6.0.4(postcss@8.5.12): + postcss-unique-selectors@6.0.4(postcss@8.5.15): dependencies: - postcss: 8.5.12 + postcss: 8.5.15 postcss-selector-parser: 6.1.2 postcss-value-parser@4.2.0: {} - postcss-zindex@6.0.2(postcss@8.5.12): + postcss-zindex@6.0.2(postcss@8.5.15): dependencies: - postcss: 8.5.12 + postcss: 8.5.15 - postcss@8.5.12: + postcss@8.5.15: dependencies: - nanoid: 3.3.11 + nanoid: 3.3.12 picocolors: 1.1.1 source-map-js: 1.2.1 @@ -24201,10 +24732,10 @@ snapshots: dependencies: prettier: 3.8.3 - prettier-plugin-svelte@3.5.1(prettier@3.8.3)(svelte@5.55.8): + prettier-plugin-svelte@3.5.2(prettier@3.8.3)(svelte@5.55.8(@typescript-eslint/types@8.59.4)): dependencies: prettier: 3.8.3 - svelte: 5.55.8 + svelte: 5.55.8(@typescript-eslint/types@8.59.4) prettier@3.8.3: {} @@ -24221,11 +24752,11 @@ snapshots: pretty-time@1.1.0: {} - prism-react-renderer@2.4.1(react@19.2.5): + prism-react-renderer@2.4.1(react@19.2.6): dependencies: - '@types/prismjs': 1.26.5 + '@types/prismjs': 1.26.6 clsx: 2.1.1 - react: 19.2.5 + react: 19.2.6 prismjs@1.30.0: {} @@ -24235,11 +24766,6 @@ snapshots: process@0.11.10: {} - promise-retry@2.0.1: - dependencies: - err-code: 2.0.3 - retry: 0.12.0 - prompts@2.4.2: dependencies: kleur: 3.0.3 @@ -24274,34 +24800,19 @@ snapshots: proto-list@1.2.4: {} - protobufjs@7.5.5: + protobufjs@7.6.0: dependencies: '@protobufjs/aspromise': 1.1.2 '@protobufjs/base64': 1.1.2 - '@protobufjs/codegen': 2.0.4 + '@protobufjs/codegen': 2.0.5 '@protobufjs/eventemitter': 1.1.0 - '@protobufjs/fetch': 1.1.0 + '@protobufjs/fetch': 1.1.1 '@protobufjs/float': 1.0.2 - '@protobufjs/inquire': 1.1.0 + '@protobufjs/inquire': 1.1.2 '@protobufjs/path': 1.1.2 '@protobufjs/pool': 1.1.0 - '@protobufjs/utf8': 1.1.0 - '@types/node': 24.12.2 - long: 5.3.2 - - protobufjs@8.0.1: - dependencies: - '@protobufjs/aspromise': 1.1.2 - '@protobufjs/base64': 1.1.2 - '@protobufjs/codegen': 2.0.4 - '@protobufjs/eventemitter': 1.1.0 - '@protobufjs/fetch': 1.1.0 - '@protobufjs/float': 1.0.2 - '@protobufjs/inquire': 1.1.0 - '@protobufjs/path': 1.1.2 - '@protobufjs/pool': 1.1.0 - '@protobufjs/utf8': 1.1.0 - '@types/node': 24.12.2 + '@protobufjs/utf8': 1.1.1 + '@types/node': 24.12.4 long: 5.3.2 protocol-buffers-schema@3.6.1: {} @@ -24324,13 +24835,19 @@ snapshots: dependencies: escape-goat: 4.0.0 + pvtsutils@1.3.6: + dependencies: + tslib: 2.8.1 + + pvutils@1.1.5: {} + qrcode@1.5.4: dependencies: dijkstrajs: 1.0.3 pngjs: 5.0.0 yargs: 15.4.1 - qs@6.14.1: + qs@6.15.2: dependencies: side-channel: 1.1.0 @@ -24373,11 +24890,11 @@ snapshots: iconv-lite: 0.7.2 unpipe: 1.0.0 - raw-loader@4.0.2(webpack@5.106.2): + raw-loader@4.0.2(webpack@5.107.0(postcss@8.5.15)): dependencies: loader-utils: 2.0.4 schema-utils: 3.3.0 - webpack: 5.106.2 + webpack: 5.107.0(postcss@8.5.15) rc@1.2.8: dependencies: @@ -24386,9 +24903,9 @@ snapshots: minimist: 1.2.8 strip-json-comments: 2.0.1 - react-dom@19.2.5(react@19.2.5): + react-dom@19.2.6(react@19.2.6): dependencies: - react: 19.2.5 + react: 19.2.6 scheduler: 0.27.0 react-email@5.2.11: @@ -24421,34 +24938,34 @@ snapshots: react-is@17.0.2: {} - react-json-view-lite@2.5.0(react@19.2.5): + react-json-view-lite@2.5.0(react@19.2.6): dependencies: - react: 19.2.5 + react: 19.2.6 - react-loadable-ssr-addon-v5-slorber@1.0.3(@docusaurus/react-loadable@6.0.0(react@19.2.5))(webpack@5.106.2): + react-loadable-ssr-addon-v5-slorber@1.0.3(@docusaurus/react-loadable@6.0.0(react@19.2.6))(webpack@5.107.0(postcss@8.5.15)): dependencies: '@babel/runtime': 7.29.2 - react-loadable: '@docusaurus/react-loadable@6.0.0(react@19.2.5)' - webpack: 5.106.2 + react-loadable: '@docusaurus/react-loadable@6.0.0(react@19.2.6)' + webpack: 5.107.0(postcss@8.5.15) - react-router-config@5.1.1(react-router@5.3.4(react@19.2.5))(react@19.2.5): + react-router-config@5.1.1(react-router@5.3.4(react@19.2.6))(react@19.2.6): dependencies: '@babel/runtime': 7.29.2 - react: 19.2.5 - react-router: 5.3.4(react@19.2.5) + react: 19.2.6 + react-router: 5.3.4(react@19.2.6) - react-router-dom@5.3.4(react@19.2.5): + react-router-dom@5.3.4(react@19.2.6): dependencies: '@babel/runtime': 7.29.2 history: 4.10.1 loose-envify: 1.4.0 prop-types: 15.8.1 - react: 19.2.5 - react-router: 5.3.4(react@19.2.5) + react: 19.2.6 + react-router: 5.3.4(react@19.2.6) tiny-invariant: 1.3.3 tiny-warning: 1.0.3 - react-router@5.3.4(react@19.2.5): + react-router@5.3.4(react@19.2.6): dependencies: '@babel/runtime': 7.29.2 history: 4.10.1 @@ -24456,12 +24973,12 @@ snapshots: loose-envify: 1.4.0 path-to-regexp: 1.9.0 prop-types: 15.8.1 - react: 19.2.5 + react: 19.2.6 react-is: 16.13.1 tiny-invariant: 1.3.3 tiny-warning: 1.0.3 - react@19.2.5: {} + react@19.2.6: {} read-cache@1.0.0: dependencies: @@ -24503,7 +25020,7 @@ snapshots: recma-build-jsx@1.0.0: dependencies: - '@types/estree': 1.0.8 + '@types/estree': 1.0.9 estree-util-build-jsx: 3.0.1 vfile: 6.0.3 @@ -24518,14 +25035,14 @@ snapshots: recma-parse@1.0.0: dependencies: - '@types/estree': 1.0.8 + '@types/estree': 1.0.9 esast-util-from-js: 2.0.1 unified: 11.0.5 vfile: 6.0.3 recma-stringify@1.0.0: dependencies: - '@types/estree': 1.0.8 + '@types/estree': 1.0.9 estree-util-to-js: 2.0.0 unified: 11.0.5 vfile: 6.0.3 @@ -24556,13 +25073,13 @@ snapshots: regenerate: 1.4.2 regenerate-unicode-properties: 10.2.2 regjsgen: 0.8.0 - regjsparser: 0.13.0 + regjsparser: 0.13.1 unicode-match-property-ecmascript: 2.0.0 unicode-match-property-value-ecmascript: 2.2.1 - registry-auth-token@5.1.0: + registry-auth-token@5.1.1: dependencies: - '@pnpm/npm-conf': 2.3.1 + '@pnpm/npm-conf': 3.0.2 registry-url@6.0.1: dependencies: @@ -24570,7 +25087,7 @@ snapshots: regjsgen@0.8.0: {} - regjsparser@0.13.0: + regjsparser@0.13.1: dependencies: jsesc: 3.1.0 @@ -24587,7 +25104,7 @@ snapshots: rehype-recma@1.0.0: dependencies: - '@types/estree': 1.0.8 + '@types/estree': 1.0.9 '@types/hast': 3.0.4 hast-util-to-estree: 3.1.3 transitivePeerDependencies: @@ -24642,7 +25159,7 @@ snapshots: remark-parse@11.0.0: dependencies: '@types/mdast': 4.0.4 - mdast-util-from-markdown: 2.0.2 + mdast-util-from-markdown: 2.0.3 micromark-util-types: 2.0.2 unified: 11.0.5 transitivePeerDependencies: @@ -24701,9 +25218,10 @@ snapshots: dependencies: protocol-buffers-schema: 3.6.1 - resolve@1.22.11: + resolve@1.22.12: dependencies: - is-core-module: 2.16.1 + es-errors: 1.3.0 + is-core-module: 2.16.2 path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 @@ -24735,66 +25253,66 @@ snapshots: robust-predicates@3.0.3: {} - rolldown@1.0.0-rc.17: + rolldown@1.0.1: dependencies: - '@oxc-project/types': 0.127.0 - '@rolldown/pluginutils': 1.0.0-rc.17 + '@oxc-project/types': 0.130.0 + '@rolldown/pluginutils': 1.0.1 optionalDependencies: - '@rolldown/binding-android-arm64': 1.0.0-rc.17 - '@rolldown/binding-darwin-arm64': 1.0.0-rc.17 - '@rolldown/binding-darwin-x64': 1.0.0-rc.17 - '@rolldown/binding-freebsd-x64': 1.0.0-rc.17 - '@rolldown/binding-linux-arm-gnueabihf': 1.0.0-rc.17 - '@rolldown/binding-linux-arm64-gnu': 1.0.0-rc.17 - '@rolldown/binding-linux-arm64-musl': 1.0.0-rc.17 - '@rolldown/binding-linux-ppc64-gnu': 1.0.0-rc.17 - '@rolldown/binding-linux-s390x-gnu': 1.0.0-rc.17 - '@rolldown/binding-linux-x64-gnu': 1.0.0-rc.17 - '@rolldown/binding-linux-x64-musl': 1.0.0-rc.17 - '@rolldown/binding-openharmony-arm64': 1.0.0-rc.17 - '@rolldown/binding-wasm32-wasi': 1.0.0-rc.17 - '@rolldown/binding-win32-arm64-msvc': 1.0.0-rc.17 - '@rolldown/binding-win32-x64-msvc': 1.0.0-rc.17 + '@rolldown/binding-android-arm64': 1.0.1 + '@rolldown/binding-darwin-arm64': 1.0.1 + '@rolldown/binding-darwin-x64': 1.0.1 + '@rolldown/binding-freebsd-x64': 1.0.1 + '@rolldown/binding-linux-arm-gnueabihf': 1.0.1 + '@rolldown/binding-linux-arm64-gnu': 1.0.1 + '@rolldown/binding-linux-arm64-musl': 1.0.1 + '@rolldown/binding-linux-ppc64-gnu': 1.0.1 + '@rolldown/binding-linux-s390x-gnu': 1.0.1 + '@rolldown/binding-linux-x64-gnu': 1.0.1 + '@rolldown/binding-linux-x64-musl': 1.0.1 + '@rolldown/binding-openharmony-arm64': 1.0.1 + '@rolldown/binding-wasm32-wasi': 1.0.1 + '@rolldown/binding-win32-arm64-msvc': 1.0.1 + '@rolldown/binding-win32-x64-msvc': 1.0.1 - rollup-plugin-visualizer@7.0.1(rolldown@1.0.0-rc.17)(rollup@4.55.1): + rollup-plugin-visualizer@7.0.1(rolldown@1.0.1)(rollup@4.60.4): dependencies: open: 11.0.0 picomatch: 4.0.4 source-map: 0.7.6 yargs: 18.0.0 optionalDependencies: - rolldown: 1.0.0-rc.17 - rollup: 4.55.1 + rolldown: 1.0.1 + rollup: 4.60.4 - rollup@4.55.1: + rollup@4.60.4: dependencies: '@types/estree': 1.0.8 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.55.1 - '@rollup/rollup-android-arm64': 4.55.1 - '@rollup/rollup-darwin-arm64': 4.55.1 - '@rollup/rollup-darwin-x64': 4.55.1 - '@rollup/rollup-freebsd-arm64': 4.55.1 - '@rollup/rollup-freebsd-x64': 4.55.1 - '@rollup/rollup-linux-arm-gnueabihf': 4.55.1 - '@rollup/rollup-linux-arm-musleabihf': 4.55.1 - '@rollup/rollup-linux-arm64-gnu': 4.55.1 - '@rollup/rollup-linux-arm64-musl': 4.55.1 - '@rollup/rollup-linux-loong64-gnu': 4.55.1 - '@rollup/rollup-linux-loong64-musl': 4.55.1 - '@rollup/rollup-linux-ppc64-gnu': 4.55.1 - '@rollup/rollup-linux-ppc64-musl': 4.55.1 - '@rollup/rollup-linux-riscv64-gnu': 4.55.1 - '@rollup/rollup-linux-riscv64-musl': 4.55.1 - '@rollup/rollup-linux-s390x-gnu': 4.55.1 - '@rollup/rollup-linux-x64-gnu': 4.55.1 - '@rollup/rollup-linux-x64-musl': 4.55.1 - '@rollup/rollup-openbsd-x64': 4.55.1 - '@rollup/rollup-openharmony-arm64': 4.55.1 - '@rollup/rollup-win32-arm64-msvc': 4.55.1 - '@rollup/rollup-win32-ia32-msvc': 4.55.1 - '@rollup/rollup-win32-x64-gnu': 4.55.1 - '@rollup/rollup-win32-x64-msvc': 4.55.1 + '@rollup/rollup-android-arm-eabi': 4.60.4 + '@rollup/rollup-android-arm64': 4.60.4 + '@rollup/rollup-darwin-arm64': 4.60.4 + '@rollup/rollup-darwin-x64': 4.60.4 + '@rollup/rollup-freebsd-arm64': 4.60.4 + '@rollup/rollup-freebsd-x64': 4.60.4 + '@rollup/rollup-linux-arm-gnueabihf': 4.60.4 + '@rollup/rollup-linux-arm-musleabihf': 4.60.4 + '@rollup/rollup-linux-arm64-gnu': 4.60.4 + '@rollup/rollup-linux-arm64-musl': 4.60.4 + '@rollup/rollup-linux-loong64-gnu': 4.60.4 + '@rollup/rollup-linux-loong64-musl': 4.60.4 + '@rollup/rollup-linux-ppc64-gnu': 4.60.4 + '@rollup/rollup-linux-ppc64-musl': 4.60.4 + '@rollup/rollup-linux-riscv64-gnu': 4.60.4 + '@rollup/rollup-linux-riscv64-musl': 4.60.4 + '@rollup/rollup-linux-s390x-gnu': 4.60.4 + '@rollup/rollup-linux-x64-gnu': 4.60.4 + '@rollup/rollup-linux-x64-musl': 4.60.4 + '@rollup/rollup-openbsd-x64': 4.60.4 + '@rollup/rollup-openharmony-arm64': 4.60.4 + '@rollup/rollup-win32-arm64-msvc': 4.60.4 + '@rollup/rollup-win32-ia32-msvc': 4.60.4 + '@rollup/rollup-win32-x64-gnu': 4.60.4 + '@rollup/rollup-win32-x64-msvc': 4.60.4 fsevents: 2.3.3 roughjs@4.6.6: @@ -24821,7 +25339,7 @@ snapshots: dependencies: escalade: 3.2.0 picocolors: 1.1.1 - postcss: 8.5.12 + postcss: 8.5.15 strip-json-comments: 3.1.1 run-applescript@7.1.0: {} @@ -24832,21 +25350,14 @@ snapshots: dependencies: queue-microtask: 1.2.3 - runed@0.35.1(@sveltejs/kit@2.57.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.55.8)(vite@8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)))(svelte@5.55.8)(typescript@6.0.3)(vite@8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)))(svelte@5.55.8): + runed@0.35.1(@sveltejs/kit@2.60.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.1.2(svelte@5.55.8(@typescript-eslint/types@8.59.4))(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0)))(svelte@5.55.8(@typescript-eslint/types@8.59.4))(typescript@6.0.3)(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0)))(svelte@5.55.8(@typescript-eslint/types@8.59.4)): dependencies: dequal: 2.0.3 esm-env: 1.2.2 lz-string: 1.5.0 - svelte: 5.55.8 + svelte: 5.55.8(@typescript-eslint/types@8.59.4) optionalDependencies: - '@sveltejs/kit': 2.57.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.55.8)(vite@8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)))(svelte@5.55.8)(typescript@6.0.3)(vite@8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)) - - runed@0.35.1(svelte@5.55.8): - dependencies: - dequal: 2.0.3 - esm-env: 1.2.2 - lz-string: 1.5.0 - svelte: 5.55.8 + '@sveltejs/kit': 2.60.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.1.2(svelte@5.55.8(@typescript-eslint/types@8.59.4))(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0)))(svelte@5.55.8(@typescript-eslint/types@8.59.4))(typescript@6.0.3)(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0)) rw@1.3.3: {} @@ -24880,7 +25391,7 @@ snapshots: optionalDependencies: '@parcel/watcher': 2.5.6 - sax@1.4.3: {} + sax@1.6.0: {} saxes@6.0.0: dependencies: @@ -24894,15 +25405,15 @@ snapshots: schema-utils@3.3.0: dependencies: '@types/json-schema': 7.0.15 - ajv: 6.14.0 - ajv-keywords: 3.5.2(ajv@6.14.0) + ajv: 6.15.0 + ajv-keywords: 3.5.2(ajv@6.15.0) schema-utils@4.3.3: dependencies: '@types/json-schema': 7.0.15 - ajv: 8.18.0 - ajv-formats: 2.1.1(ajv@8.18.0) - ajv-keywords: 5.1.0(ajv@8.18.0) + ajv: 8.20.0 + ajv-formats: 2.1.1(ajv@8.20.0) + ajv-keywords: 5.1.0(ajv@8.20.0) search-insights@2.17.3: {} @@ -24917,18 +25428,18 @@ snapshots: select-hose@2.0.0: {} - selfsigned@2.4.1: + selfsigned@5.5.0: dependencies: - '@types/node-forge': 1.3.14 - node-forge: 1.3.3 + '@peculiar/x509': 1.14.3 + pkijs: 3.4.0 semver-diff@4.0.0: dependencies: - semver: 7.7.4 + semver: 7.8.0 semver@6.3.1: {} - semver@7.7.4: {} + semver@7.8.0: {} send@0.19.2: dependencies: @@ -24978,13 +25489,13 @@ snapshots: path-to-regexp: 3.3.0 range-parser: 1.2.0 - serve-index@1.9.1: + serve-index@1.9.2: dependencies: accepts: 1.3.8 batch: 0.6.1 debug: 2.6.9 escape-html: 1.0.3 - http-errors: 1.6.3 + http-errors: 1.8.1 mime-types: 2.1.35 parseurl: 1.3.3 transitivePeerDependencies: @@ -25021,8 +25532,6 @@ snapshots: gopd: 1.2.0 has-property-descriptors: 1.0.2 - setprototypeof@1.1.0: {} - setprototypeof@1.2.0: {} shallow-clone@3.0.1: @@ -25042,11 +25551,11 @@ snapshots: sharp@0.34.5: dependencies: - '@img/colour': 1.0.0 + '@img/colour': 1.1.0 detect-libc: 2.1.2 - node-addon-api: 8.5.0 - node-gyp: 12.2.0 - semver: 7.7.4 + node-addon-api: 8.7.0 + node-gyp: 12.3.0 + semver: 7.8.0 optionalDependencies: '@img/sharp-darwin-arm64': 0.34.5 '@img/sharp-darwin-x64': 0.34.5 @@ -25072,8 +25581,6 @@ snapshots: '@img/sharp-win32-arm64': 0.34.5 '@img/sharp-win32-ia32': 0.34.5 '@img/sharp-win32-x64': 0.34.5 - transitivePeerDependencies: - - supports-color shebang-command@2.0.0: dependencies: @@ -25083,7 +25590,7 @@ snapshots: shell-quote@1.8.3: {} - side-channel-list@1.0.0: + side-channel-list@1.0.1: dependencies: es-errors: 1.3.0 object-inspect: 1.13.4 @@ -25107,7 +25614,7 @@ snapshots: dependencies: es-errors: 1.3.0 object-inspect: 1.13.4 - side-channel-list: 1.0.0 + side-channel-list: 1.0.1 side-channel-map: 1.0.1 side-channel-weakmap: 1.0.2 @@ -25125,7 +25632,7 @@ snapshots: once: 1.4.0 simple-concat: 1.0.1 - simple-icons@16.17.0: {} + simple-icons@16.20.0: {} sirv@2.0.4: dependencies: @@ -25141,12 +25648,12 @@ snapshots: sisteransi@1.0.5: {} - sitemap@7.1.2: + sitemap@7.1.3: dependencies: '@types/node': 17.0.45 '@types/sax': 1.2.7 arg: 5.0.2 - sax: 1.4.3 + sax: 1.6.0 skin-tone@2.0.0: dependencies: @@ -25158,17 +25665,15 @@ snapshots: slice-source@0.4.1: {} - smart-buffer@4.2.0: {} - snake-case@3.0.4: dependencies: dot-case: 3.0.4 tslib: 2.8.1 - socket.io-adapter@2.5.6: + socket.io-adapter@2.5.7: dependencies: debug: 4.4.3 - ws: 8.18.3 + ws: 8.20.1 transitivePeerDependencies: - bufferutil - supports-color @@ -25178,14 +25683,14 @@ snapshots: dependencies: '@socket.io/component-emitter': 3.1.2 debug: 4.4.3 - engine.io-client: 6.6.4 - socket.io-parser: 4.2.5 + engine.io-client: 6.6.5 + socket.io-parser: 4.2.6 transitivePeerDependencies: - bufferutil - supports-color - utf-8-validate - socket.io-parser@4.2.5: + socket.io-parser@4.2.6: dependencies: '@socket.io/component-emitter': 3.1.2 debug: 4.4.3 @@ -25198,9 +25703,9 @@ snapshots: base64id: 2.0.0 cors: 2.8.6 debug: 4.4.3 - engine.io: 6.6.5 - socket.io-adapter: 2.5.6 - socket.io-parser: 4.2.5 + engine.io: 6.6.8 + socket.io-adapter: 2.5.7 + socket.io-parser: 4.2.6 transitivePeerDependencies: - bufferutil - supports-color @@ -25212,19 +25717,6 @@ snapshots: uuid: 8.3.2 websocket-driver: 0.7.4 - socks-proxy-agent@8.0.5: - dependencies: - agent-base: 7.1.4 - debug: 4.4.3 - socks: 2.8.7 - transitivePeerDependencies: - - supports-color - - socks@2.8.7: - dependencies: - ip-address: 10.1.0 - smart-buffer: 4.2.0 - sort-css-media-queries@2.2.0: {} source-map-js@1.2.1: {} @@ -25271,7 +25763,7 @@ snapshots: sprintf-js@1.0.3: {} - sql-formatter@15.7.3: + sql-formatter@15.8.0: dependencies: argparse: 2.0.1 nearley: 2.20.1 @@ -25289,11 +25781,7 @@ snapshots: bcrypt-pbkdf: 1.0.2 optionalDependencies: cpu-features: 0.0.10 - nan: 2.26.2 - - ssri@13.0.1: - dependencies: - minipass: 7.1.3 + nan: 2.27.0 stackback@0.0.2: {} @@ -25337,7 +25825,7 @@ snapshots: string-width@7.2.0: dependencies: emoji-regex: 10.6.0 - get-east-asian-width: 1.5.0 + get-east-asian-width: 1.6.0 strip-ansi: 7.2.0 string_decoder@1.1.1: @@ -25407,13 +25895,13 @@ snapshots: dependencies: inline-style-parser: 0.2.7 - stylehacks@6.1.1(postcss@8.5.12): + stylehacks@6.1.1(postcss@8.5.15): dependencies: browserslist: 4.28.2 - postcss: 8.5.12 + postcss: 8.5.15 postcss-selector-parser: 6.1.2 - stylis@4.3.6: {} + stylis@4.4.0: {} sucrase@3.35.1: dependencies: @@ -25435,13 +25923,13 @@ snapshots: formidable: 3.5.4 methods: 1.1.2 mime: 2.6.0 - qs: 6.14.1 + qs: 6.15.2 transitivePeerDependencies: - supports-color supercluster@8.0.1: dependencies: - kdbush: 4.0.2 + kdbush: 4.1.0 supertest@7.2.2: dependencies: @@ -25461,33 +25949,33 @@ snapshots: supports-preserve-symlinks-flag@1.0.0: {} - svelte-awesome@3.3.5(svelte@5.55.8): + svelte-awesome@3.3.5(svelte@5.55.8(@typescript-eslint/types@8.59.4)): dependencies: - svelte: 5.55.8 + svelte: 5.55.8(@typescript-eslint/types@8.59.4) - svelte-check@4.4.6(picomatch@4.0.4)(svelte@5.55.8)(typescript@6.0.3): + svelte-check@4.4.8(picomatch@4.0.4)(svelte@5.55.8(@typescript-eslint/types@8.59.4))(typescript@6.0.3): dependencies: '@jridgewell/trace-mapping': 0.3.31 chokidar: 4.0.3 fdir: 6.5.0(picomatch@4.0.4) picocolors: 1.1.1 sade: 1.8.1 - svelte: 5.55.8 + svelte: 5.55.8(@typescript-eslint/types@8.59.4) typescript: 6.0.3 transitivePeerDependencies: - picomatch - svelte-eslint-parser@1.6.0(svelte@5.55.8): + svelte-eslint-parser@1.6.1(svelte@5.55.8(@typescript-eslint/types@8.59.4)): dependencies: eslint-scope: 8.4.0 eslint-visitor-keys: 4.2.1 espree: 10.4.0 - postcss: 8.5.12 - postcss-scss: 4.0.9(postcss@8.5.12) + postcss: 8.5.15 + postcss-scss: 4.0.9(postcss@8.5.15) postcss-selector-parser: 7.1.1 - semver: 7.7.4 + semver: 7.8.0 optionalDependencies: - svelte: 5.55.8 + svelte: 5.55.8(@typescript-eslint/types@8.59.4) svelte-floating-ui@1.5.8: dependencies: @@ -25500,7 +25988,7 @@ snapshots: dependencies: highlight.js: 11.11.1 - svelte-i18n@4.0.1(svelte@5.55.8): + svelte-i18n@4.0.1(svelte@5.55.8(@typescript-eslint/types@8.59.4)): dependencies: cli-color: 2.0.4 deepmerge: 4.3.1 @@ -25508,26 +25996,26 @@ snapshots: estree-walker: 2.0.2 intl-messageformat: 10.7.18 sade: 1.8.1 - svelte: 5.55.8 + svelte: 5.55.8(@typescript-eslint/types@8.59.4) tiny-glob: 0.2.9 - svelte-jsoneditor@3.12.0(svelte@5.55.8): + svelte-jsoneditor@3.12.0(svelte@5.55.8(@typescript-eslint/types@8.59.4)): dependencies: - '@codemirror/autocomplete': 6.20.1 + '@codemirror/autocomplete': 6.20.2 '@codemirror/commands': 6.10.3 '@codemirror/lang-json': 6.0.2 '@codemirror/language': 6.12.3 - '@codemirror/lint': 6.9.5 + '@codemirror/lint': 6.9.6 '@codemirror/search': 6.7.0 '@codemirror/state': 6.6.0 - '@codemirror/view': 6.41.1 + '@codemirror/view': 6.43.0 '@fortawesome/free-regular-svg-icons': 7.2.0 '@fortawesome/free-solid-svg-icons': 7.2.0 '@jsonquerylang/jsonquery': 5.1.1 '@lezer/highlight': 1.2.3 - '@replit/codemirror-indentation-markers': 6.5.3(@codemirror/language@6.12.3)(@codemirror/state@6.6.0)(@codemirror/view@6.41.1) - ajv: 8.18.0 - codemirror-wrapped-line-indent: 1.0.9(@codemirror/language@6.12.3)(@codemirror/state@6.6.0)(@codemirror/view@6.41.1) + '@replit/codemirror-indentation-markers': 6.5.3(@codemirror/language@6.12.3)(@codemirror/state@6.6.0)(@codemirror/view@6.43.0) + ajv: 8.20.0 + codemirror-wrapped-line-indent: 1.0.9(@codemirror/language@6.12.3)(@codemirror/state@6.6.0)(@codemirror/view@6.43.0) diff-sequences: 29.6.3 immutable-json-patch: 6.0.2 jmespath: 0.16.0 @@ -25538,56 +26026,47 @@ snapshots: memoize-one: 6.0.0 natural-compare-lite: 1.4.0 sass: 1.99.0 - svelte: 5.55.8 - svelte-awesome: 3.3.5(svelte@5.55.8) + svelte: 5.55.8(@typescript-eslint/types@8.59.4) + svelte-awesome: 3.3.5(svelte@5.55.8(@typescript-eslint/types@8.59.4)) svelte-select: 5.8.3 vanilla-picker: 2.12.3 - svelte-maplibre@1.3.0(svelte@5.55.8): + svelte-maplibre@1.3.0(svelte@5.55.8(@typescript-eslint/types@8.59.4)): dependencies: d3-geo: 3.1.1 dequal: 2.0.3 just-compare: 2.3.0 maplibre-gl: 5.24.0 pmtiles: 3.2.1 - svelte: 5.55.8 + svelte: 5.55.8(@typescript-eslint/types@8.59.4) - svelte-parse-markup@0.1.5(svelte@5.55.8): + svelte-parse-markup@0.1.5(svelte@5.55.8(@typescript-eslint/types@8.59.4)): dependencies: - svelte: 5.55.8 + svelte: 5.55.8(@typescript-eslint/types@8.59.4) - svelte-persisted-store@0.12.0(svelte@5.55.8): + svelte-persisted-store@0.12.0(svelte@5.55.8(@typescript-eslint/types@8.59.4)): dependencies: - svelte: 5.55.8 + svelte: 5.55.8(@typescript-eslint/types@8.59.4) svelte-select@5.8.3: dependencies: svelte-floating-ui: 1.5.8 - svelte-toolbelt@0.10.6(@sveltejs/kit@2.57.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.55.8)(vite@8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)))(svelte@5.55.8)(typescript@6.0.3)(vite@8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)))(svelte@5.55.8): + svelte-toolbelt@0.10.6(@sveltejs/kit@2.60.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.1.2(svelte@5.55.8(@typescript-eslint/types@8.59.4))(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0)))(svelte@5.55.8(@typescript-eslint/types@8.59.4))(typescript@6.0.3)(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0)))(svelte@5.55.8(@typescript-eslint/types@8.59.4)): dependencies: clsx: 2.1.1 - runed: 0.35.1(@sveltejs/kit@2.57.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.55.8)(vite@8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)))(svelte@5.55.8)(typescript@6.0.3)(vite@8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)))(svelte@5.55.8) + runed: 0.35.1(@sveltejs/kit@2.60.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.1.2(svelte@5.55.8(@typescript-eslint/types@8.59.4))(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0)))(svelte@5.55.8(@typescript-eslint/types@8.59.4))(typescript@6.0.3)(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0)))(svelte@5.55.8(@typescript-eslint/types@8.59.4)) style-to-object: 1.0.14 - svelte: 5.55.8 + svelte: 5.55.8(@typescript-eslint/types@8.59.4) transitivePeerDependencies: - '@sveltejs/kit' - svelte-toolbelt@0.10.6(svelte@5.55.8): - dependencies: - clsx: 2.1.1 - runed: 0.35.1(svelte@5.55.8) - style-to-object: 1.0.14 - svelte: 5.55.8 - transitivePeerDependencies: - - '@sveltejs/kit' - - svelte@5.55.8: + svelte@5.55.8(@typescript-eslint/types@8.59.4): dependencies: '@jridgewell/remapping': 2.3.5 '@jridgewell/sourcemap-codec': 1.5.5 - '@sveltejs/acorn-typescript': 1.0.9(acorn@8.16.0) - '@types/estree': 1.0.8 + '@sveltejs/acorn-typescript': 1.0.10(acorn@8.16.0) + '@types/estree': 1.0.9 '@types/trusted-types': 2.0.7 acorn: 8.16.0 aria-query: 5.3.1 @@ -25595,34 +26074,30 @@ snapshots: clsx: 2.1.1 devalue: 5.8.1 esm-env: 1.2.2 - esrap: 2.2.4 + esrap: 2.2.9(@typescript-eslint/types@8.59.4) is-reference: 3.0.3 locate-character: 3.0.0 magic-string: 0.30.21 zimmerframe: 1.1.4 + transitivePeerDependencies: + - '@typescript-eslint/types' svg-parser@2.0.4: {} - svgo@3.3.2: + svgo@3.3.3: dependencies: - '@trysound/sax': 0.2.0 commander: 7.2.0 css-select: 5.2.2 css-tree: 2.3.1 css-what: 6.2.2 csso: 5.0.5 picocolors: 1.1.1 + sax: 1.6.0 - swagger-ui-dist@5.32.4: + swagger-ui-dist@5.32.6: dependencies: '@scarf/scarf': 1.4.0 - swr@2.3.8(react@19.2.5): - dependencies: - dequal: 2.0.3 - react: 19.2.5 - use-sync-external-store: 1.6.0(react@19.2.5) - symbol-observable@4.0.0: {} symbol-tree@3.2.4: @@ -25632,7 +26107,7 @@ snapshots: dependencies: '@pkgr/core': 0.2.9 - systeminformation@5.31.5: {} + systeminformation@5.31.6: {} tabbable@6.4.0: {} @@ -25642,29 +26117,29 @@ snapshots: tailwind-csstree@0.3.1: {} - tailwind-merge@3.5.0: {} + tailwind-merge@3.6.0: {} - tailwind-variants@3.2.2(tailwind-merge@3.5.0)(tailwindcss@4.2.4): + tailwind-variants@3.2.2(tailwind-merge@3.6.0)(tailwindcss@4.3.0): dependencies: - tailwindcss: 4.2.4 + tailwindcss: 4.3.0 optionalDependencies: - tailwind-merge: 3.5.0 + tailwind-merge: 3.6.0 - tailwindcss-email-variants@3.0.5(tailwindcss@3.4.19(tsx@4.21.0)(yaml@2.8.3)): + tailwindcss-email-variants@3.0.5(tailwindcss@3.4.19(tsx@4.22.3)(yaml@2.9.0)): dependencies: - tailwindcss: 3.4.19(tsx@4.21.0)(yaml@2.8.3) + tailwindcss: 3.4.19(tsx@4.22.3)(yaml@2.9.0) - tailwindcss-mso@2.0.3(tailwindcss@3.4.19(tsx@4.21.0)(yaml@2.8.3)): + tailwindcss-mso@2.0.3(tailwindcss@3.4.19(tsx@4.22.3)(yaml@2.9.0)): dependencies: - tailwindcss: 3.4.19(tsx@4.21.0)(yaml@2.8.3) + tailwindcss: 3.4.19(tsx@4.22.3)(yaml@2.9.0) - tailwindcss-preset-email@1.4.1(tailwindcss@3.4.19(tsx@4.21.0)(yaml@2.8.3)): + tailwindcss-preset-email@1.4.1(tailwindcss@3.4.19(tsx@4.22.3)(yaml@2.9.0)): dependencies: - tailwindcss: 3.4.19(tsx@4.21.0)(yaml@2.8.3) - tailwindcss-email-variants: 3.0.5(tailwindcss@3.4.19(tsx@4.21.0)(yaml@2.8.3)) - tailwindcss-mso: 2.0.3(tailwindcss@3.4.19(tsx@4.21.0)(yaml@2.8.3)) + tailwindcss: 3.4.19(tsx@4.22.3)(yaml@2.9.0) + tailwindcss-email-variants: 3.0.5(tailwindcss@3.4.19(tsx@4.22.3)(yaml@2.9.0)) + tailwindcss-mso: 2.0.3(tailwindcss@3.4.19(tsx@4.22.3)(yaml@2.9.0)) - tailwindcss@3.4.19(tsx@4.21.0)(yaml@2.8.3): + tailwindcss@3.4.19(tsx@4.22.3)(yaml@2.9.0): dependencies: '@alloc/quick-lru': 5.2.0 arg: 5.0.2 @@ -25680,19 +26155,19 @@ snapshots: normalize-path: 3.0.0 object-hash: 3.0.0 picocolors: 1.1.1 - postcss: 8.5.12 - postcss-import: 15.1.0(postcss@8.5.12) - postcss-js: 4.1.0(postcss@8.5.12) - postcss-load-config: 6.0.1(jiti@1.21.7)(postcss@8.5.12)(tsx@4.21.0)(yaml@2.8.3) - postcss-nested: 6.2.0(postcss@8.5.12) + postcss: 8.5.15 + postcss-import: 15.1.0(postcss@8.5.15) + postcss-js: 4.1.0(postcss@8.5.15) + postcss-load-config: 6.0.1(jiti@1.21.7)(postcss@8.5.15)(tsx@4.22.3)(yaml@2.9.0) + postcss-nested: 6.2.0(postcss@8.5.15) postcss-selector-parser: 6.1.2 - resolve: 1.22.11 + resolve: 1.22.12 sucrase: 3.35.1 transitivePeerDependencies: - tsx - yaml - tailwindcss@4.2.4: {} + tailwindcss@4.3.0: {} tapable@2.3.3: {} @@ -25706,7 +26181,7 @@ snapshots: tar-fs@3.1.2: dependencies: pump: 3.0.4 - tar-stream: 3.1.8 + tar-stream: 3.2.0 optionalDependencies: bare-fs: 4.7.1 bare-path: 3.0.0 @@ -25723,9 +26198,9 @@ snapshots: inherits: 2.0.4 readable-stream: 3.6.2 - tar-stream@3.1.8: + tar-stream@3.2.0: dependencies: - b4a: 1.8.0 + b4a: 1.8.1 bare-fs: 4.7.1 fast-fifo: 1.3.2 streamx: 2.25.0 @@ -25743,7 +26218,7 @@ snapshots: mkdirp: 1.0.4 yallist: 4.0.0 - tar@7.5.7: + tar@7.5.15: dependencies: '@isaacs/fs-minipass': 4.0.1 chownr: 3.0.0 @@ -25758,26 +26233,42 @@ snapshots: - bare-abort-controller - react-native-b4a - terser-webpack-plugin@5.4.0(@swc/core@1.15.30(@swc/helpers@0.5.21))(esbuild@0.28.0)(webpack@5.106.0(@swc/core@1.15.30(@swc/helpers@0.5.21))(esbuild@0.28.0)): + terser-webpack-plugin@5.6.0(@swc/core@1.15.33(@swc/helpers@0.5.22))(esbuild@0.28.0)(lightningcss@1.32.0)(webpack@5.106.0(@swc/core@1.15.33(@swc/helpers@0.5.22))(esbuild@0.28.0)(lightningcss@1.32.0)): dependencies: '@jridgewell/trace-mapping': 0.3.31 jest-worker: 27.5.1 schema-utils: 4.3.3 - terser: 5.46.1 - webpack: 5.106.0(@swc/core@1.15.30(@swc/helpers@0.5.21))(esbuild@0.28.0) + terser: 5.47.1 + webpack: 5.106.0(@swc/core@1.15.33(@swc/helpers@0.5.22))(esbuild@0.28.0)(lightningcss@1.32.0) optionalDependencies: - '@swc/core': 1.15.30(@swc/helpers@0.5.21) + '@swc/core': 1.15.33(@swc/helpers@0.5.22) esbuild: 0.28.0 + lightningcss: 1.32.0 - terser-webpack-plugin@5.4.0(webpack@5.106.2): + terser-webpack-plugin@5.6.0(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.15))(html-minifier-terser@7.2.0)(postcss@8.5.15)(webpack@5.107.0(postcss@8.5.15)): dependencies: '@jridgewell/trace-mapping': 0.3.31 jest-worker: 27.5.1 schema-utils: 4.3.3 - terser: 5.46.1 - webpack: 5.106.2 + terser: 5.47.1 + webpack: 5.107.0(postcss@8.5.15) + optionalDependencies: + clean-css: 5.3.3 + cssnano: 6.1.2(postcss@8.5.15) + html-minifier-terser: 7.2.0 + postcss: 8.5.15 - terser@5.46.1: + terser-webpack-plugin@5.6.0(postcss@8.5.15)(webpack@5.107.0(postcss@8.5.15)): + dependencies: + '@jridgewell/trace-mapping': 0.3.31 + jest-worker: 27.5.1 + schema-utils: 4.3.3 + terser: 5.47.1 + webpack: 5.107.0(postcss@8.5.15) + optionalDependencies: + postcss: 8.5.15 + + terser@5.47.1: dependencies: '@jridgewell/source-map': 0.3.11 acorn: 8.16.0 @@ -25799,7 +26290,7 @@ snapshots: byline: 5.0.0 debug: 4.4.3 docker-compose: 1.4.2 - dockerode: 4.0.10 + dockerode: 4.0.12 get-port: 7.2.0 proper-lockfile: 4.1.2 properties-reader: 3.0.1 @@ -25815,7 +26306,7 @@ snapshots: text-decoder@1.2.7: dependencies: - b4a: 1.8.0 + b4a: 1.8.1 transitivePeerDependencies: - react-native-b4a @@ -25829,15 +26320,13 @@ snapshots: dependencies: any-promise: 1.3.0 - thingies@2.5.0(tslib@2.8.1): + thingies@2.6.0(tslib@2.8.1): dependencies: tslib: 2.8.1 three@0.179.1: {} - three@0.182.0: {} - - throttleit@2.1.0: {} + three@0.184.0: {} through@2.3.8: {} @@ -25865,7 +26354,7 @@ snapshots: tinyexec@0.3.2: {} - tinyexec@1.1.1: {} + tinyexec@1.1.2: {} tinyglobby@0.2.16: dependencies: @@ -25949,11 +26438,11 @@ snapshots: ts-interface-checker@0.1.13: {} - tsc-alias@1.8.16: + tsc-alias@1.8.17: dependencies: chokidar: 3.6.0 commander: 9.5.0 - get-tsconfig: 4.13.0 + get-tsconfig: 4.14.0 globby: 11.1.0 mylas: 2.1.14 normalize-path: 3.0.0 @@ -25966,7 +26455,7 @@ snapshots: tsconfig-paths-webpack-plugin@4.2.0: dependencies: chalk: 4.1.2 - enhanced-resolve: 5.21.0 + enhanced-resolve: 5.21.5 tapable: 2.3.3 tsconfig-paths: 4.2.0 @@ -25976,17 +26465,22 @@ snapshots: minimist: 1.2.8 strip-bom: 3.0.0 + tslib@1.14.1: {} + tslib@2.8.1: {} tsscmp@1.0.6: {} - tsx@4.21.0: + tsx@4.22.3: dependencies: - esbuild: 0.27.4 - get-tsconfig: 4.13.0 + esbuild: 0.28.0 optionalDependencies: fsevents: 2.3.3 + tsyringe@4.10.0: + dependencies: + tslib: 1.14.1 + tunnel-agent@0.6.0: dependencies: safe-buffer: 5.2.1 @@ -26012,9 +26506,9 @@ snapshots: media-typer: 0.3.0 mime-types: 2.1.35 - type-is@2.0.1: + type-is@2.1.0: dependencies: - content-type: 1.0.5 + content-type: 2.0.0 media-typer: 1.1.0 mime-types: 3.0.2 @@ -26026,13 +26520,13 @@ snapshots: typedarray@0.0.6: {} - typescript-eslint@8.59.0(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3): + typescript-eslint@8.59.4(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3): dependencies: - '@typescript-eslint/eslint-plugin': 8.59.0(@typescript-eslint/parser@8.59.0(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3))(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3) - '@typescript-eslint/parser': 8.59.0(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3) - '@typescript-eslint/typescript-estree': 8.59.0(typescript@6.0.3) - '@typescript-eslint/utils': 8.59.0(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3) - eslint: 10.2.1(jiti@2.6.1) + '@typescript-eslint/eslint-plugin': 8.59.4(@typescript-eslint/parser@8.59.4(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3) + '@typescript-eslint/parser': 8.59.4(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3) + '@typescript-eslint/typescript-estree': 8.59.4(typescript@6.0.3) + '@typescript-eslint/utils': 8.59.4(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3) + eslint: 10.4.0(jiti@2.7.0) typescript: 6.0.3 transitivePeerDependencies: - supports-color @@ -26049,8 +26543,6 @@ snapshots: is-standalone-pwa: 0.1.1 ua-is-frozen: 0.1.2 - ufo@1.6.2: {} - uglify-js@3.19.3: optional: true @@ -26066,8 +26558,7 @@ snapshots: undici-types@7.16.0: {} - undici-types@7.19.2: - optional: true + undici@6.25.0: {} undici@7.25.0: {} @@ -26104,14 +26595,6 @@ snapshots: trough: 1.0.5 vfile: 4.2.1 - unique-filename@5.0.0: - dependencies: - unique-slug: 6.0.0 - - unique-slug@6.0.0: - dependencies: - imurmurhash: 0.1.4 - unique-string@3.0.0: dependencies: crypto-random-string: 4.0.0 @@ -26158,7 +26641,7 @@ snapshots: unist-util-is: 4.1.0 unist-util-visit-parents: 3.1.1 - unist-util-visit@5.0.0: + unist-util-visit@5.1.0: dependencies: '@types/unist': 3.0.3 unist-util-is: 6.0.1 @@ -26168,10 +26651,10 @@ snapshots: unpipe@1.0.0: {} - unplugin-swc@1.5.9(@swc/core@1.15.30(@swc/helpers@0.5.21))(rollup@4.55.1): + unplugin-swc@1.5.9(@swc/core@1.15.33(@swc/helpers@0.5.22))(rollup@4.60.4): dependencies: - '@rollup/pluginutils': 5.3.0(rollup@4.55.1) - '@swc/core': 1.15.30(@swc/helpers@0.5.21) + '@rollup/pluginutils': 5.3.0(rollup@4.60.4) + '@swc/core': 1.15.33(@swc/helpers@0.5.22) load-tsconfig: 0.2.5 unplugin: 2.3.11 transitivePeerDependencies: @@ -26203,7 +26686,7 @@ snapshots: is-yarn-global: 0.4.1 latest-version: 7.0.0 pupa: 3.3.0 - semver: 7.7.4 + semver: 7.8.0 semver-diff: 4.0.0 xdg-basedir: 5.1.0 @@ -26213,26 +26696,22 @@ snapshots: dependencies: punycode: 2.3.1 - url-loader@4.1.1(file-loader@6.2.0(webpack@5.106.2))(webpack@5.106.2): + url-loader@4.1.1(file-loader@6.2.0(webpack@5.107.0(postcss@8.5.15)))(webpack@5.107.0(postcss@8.5.15)): dependencies: loader-utils: 2.0.4 mime-types: 2.1.35 schema-utils: 3.3.0 - webpack: 5.106.2 + webpack: 5.107.0(postcss@8.5.15) optionalDependencies: - file-loader: 6.2.0(webpack@5.106.2) + file-loader: 6.2.0(webpack@5.107.0(postcss@8.5.15)) url@0.11.4: dependencies: punycode: 1.4.1 - qs: 6.14.1 + qs: 6.15.2 urlpattern-polyfill@8.0.2: {} - use-sync-external-store@1.6.0(react@19.2.5): - dependencies: - react: 19.2.5 - utf8-byte-length@1.0.5: {} util-deprecate@1.0.2: {} @@ -26243,9 +26722,9 @@ snapshots: utils-merge@1.0.1: {} - utimes@5.2.1(encoding@0.1.13): + utimes@5.2.1: dependencies: - '@mapbox/node-pre-gyp': 1.0.11(encoding@0.1.13) + '@mapbox/node-pre-gyp': 1.0.11 node-addon-api: 4.3.0 transitivePeerDependencies: - encoding @@ -26253,13 +26732,11 @@ snapshots: uuid@10.0.0: {} - uuid@11.1.0: {} - uuid@14.0.0: {} uuid@8.3.2: {} - valibot@1.3.1(typescript@6.0.3): + valibot@1.4.0(typescript@6.0.3): optionalDependencies: typescript: 6.0.3 @@ -26302,22 +26779,21 @@ snapshots: '@types/unist': 3.0.3 vfile-message: 4.0.3 - vite-imagetools@9.0.3(rollup@4.55.1): + vite-imagetools@9.0.3(rollup@4.60.4): dependencies: - '@rollup/pluginutils': 5.3.0(rollup@4.55.1) + '@rollup/pluginutils': 5.3.0(rollup@4.60.4) imagetools-core: 9.1.0 sharp: 0.34.5 transitivePeerDependencies: - rollup - - supports-color - vite-node@3.2.4(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3): + vite-node@3.2.4(@types/node@24.12.4)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0): dependencies: cac: 6.7.14 debug: 4.4.3 es-module-lexer: 1.7.0 pathe: 2.0.3 - vite: 7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3) + vite: 7.3.3(@types/node@24.12.4)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0) transitivePeerDependencies: - '@types/node' - jiti @@ -26332,81 +26808,64 @@ snapshots: - tsx - yaml - vite-tsconfig-paths@6.1.1(typescript@6.0.3)(vite@8.0.10(@types/node@24.12.2)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)): + vite-tsconfig-paths@6.1.1(typescript@6.0.3)(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0)): dependencies: debug: 4.4.3 globrex: 0.1.2 tsconfck: 3.1.6(typescript@6.0.3) - vite: 8.0.10(@types/node@24.12.2)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3) + vite: 8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0) transitivePeerDependencies: - supports-color - typescript - vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3): + vite@7.3.3(@types/node@24.12.4)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0): dependencies: - esbuild: 0.27.4 + esbuild: 0.27.7 fdir: 6.5.0(picomatch@4.0.4) picomatch: 4.0.4 - postcss: 8.5.12 - rollup: 4.55.1 + postcss: 8.5.15 + rollup: 4.60.4 tinyglobby: 0.2.16 optionalDependencies: - '@types/node': 24.12.2 + '@types/node': 24.12.4 fsevents: 2.3.3 - jiti: 2.6.1 + jiti: 2.7.0 lightningcss: 1.32.0 sass: 1.99.0 - terser: 5.46.1 - tsx: 4.21.0 - yaml: 2.8.3 + terser: 5.47.1 + tsx: 4.22.3 + yaml: 2.9.0 - vite@8.0.10(@types/node@24.12.2)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3): + vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0): dependencies: lightningcss: 1.32.0 picomatch: 4.0.4 - postcss: 8.5.12 - rolldown: 1.0.0-rc.17 + postcss: 8.5.15 + rolldown: 1.0.1 tinyglobby: 0.2.16 optionalDependencies: - '@types/node': 24.12.2 + '@types/node': 24.12.4 esbuild: 0.28.0 fsevents: 2.3.3 - jiti: 2.6.1 + jiti: 2.7.0 sass: 1.99.0 - terser: 5.46.1 - tsx: 4.21.0 - yaml: 2.8.3 + terser: 5.47.1 + tsx: 4.22.3 + yaml: 2.9.0 - vite@8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3): - dependencies: - lightningcss: 1.32.0 - picomatch: 4.0.4 - postcss: 8.5.12 - rolldown: 1.0.0-rc.17 - tinyglobby: 0.2.16 + vitefu@1.1.3(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0)): optionalDependencies: - '@types/node': 25.6.0 - esbuild: 0.28.0 - fsevents: 2.3.3 - jiti: 2.6.1 - sass: 1.99.0 - terser: 5.46.1 - tsx: 4.21.0 - yaml: 2.8.3 + vite: 8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0) - vitefu@1.1.2(vite@8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)): - optionalDependencies: - vite: 8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3) - - vitest-fetch-mock@0.4.5(vitest@4.1.5): + vitest-fetch-mock@0.4.5(vitest@4.1.7): dependencies: - vitest: 4.1.5(@opentelemetry/api@1.9.1)(@types/node@24.12.2)(@vitest/coverage-v8@4.1.5)(happy-dom@20.9.0)(jsdom@26.1.0(canvas@3.2.3))(vite@8.0.10(@types/node@24.12.2)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)) + vitest: 4.1.7(@opentelemetry/api@1.9.1)(@types/node@24.12.4)(@vitest/coverage-v8@4.1.7)(happy-dom@20.9.0)(jsdom@26.1.0(canvas@3.2.3))(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0)) - vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.12.2)(happy-dom@20.9.0)(jiti@2.6.1)(jsdom@26.1.0(canvas@3.2.3))(lightningcss@1.32.0)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3): + vitest@3.2.4(@types/debug@4.1.13)(@types/node@24.12.4)(happy-dom@20.9.0)(jiti@2.7.0)(jsdom@26.1.0(canvas@3.2.3))(lightningcss@1.32.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0): dependencies: '@types/chai': 5.2.3 '@vitest/expect': 3.2.4 - '@vitest/mocker': 3.2.4(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)) + '@vitest/mocker': 3.2.4(vite@7.3.3(@types/node@24.12.4)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0)) '@vitest/pretty-format': 3.2.4 '@vitest/runner': 3.2.4 '@vitest/snapshot': 3.2.4 @@ -26424,12 +26883,12 @@ snapshots: tinyglobby: 0.2.16 tinypool: 1.1.1 tinyrainbow: 2.0.0 - vite: 7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3) - vite-node: 3.2.4(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3) + vite: 7.3.3(@types/node@24.12.4)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0) + vite-node: 3.2.4(@types/node@24.12.4)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0) why-is-node-running: 2.3.0 optionalDependencies: - '@types/debug': 4.1.12 - '@types/node': 24.12.2 + '@types/debug': 4.1.13 + '@types/node': 24.12.4 happy-dom: 20.9.0 jsdom: 26.1.0(canvas@3.2.3) transitivePeerDependencies: @@ -26446,15 +26905,15 @@ snapshots: - tsx - yaml - vitest@4.1.5(@opentelemetry/api@1.9.1)(@types/node@24.12.2)(@vitest/coverage-v8@4.1.5)(happy-dom@20.9.0)(jsdom@26.1.0(canvas@3.2.3))(vite@8.0.10(@types/node@24.12.2)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)): + vitest@4.1.7(@opentelemetry/api@1.9.1)(@types/node@24.12.4)(@vitest/coverage-v8@4.1.7)(happy-dom@20.9.0)(jsdom@26.1.0(canvas@3.2.3))(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0)): dependencies: - '@vitest/expect': 4.1.5 - '@vitest/mocker': 4.1.5(vite@8.0.10(@types/node@24.12.2)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)) - '@vitest/pretty-format': 4.1.5 - '@vitest/runner': 4.1.5 - '@vitest/snapshot': 4.1.5 - '@vitest/spy': 4.1.5 - '@vitest/utils': 4.1.5 + '@vitest/expect': 4.1.7 + '@vitest/mocker': 4.1.7(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0)) + '@vitest/pretty-format': 4.1.7 + '@vitest/runner': 4.1.7 + '@vitest/snapshot': 4.1.7 + '@vitest/spy': 4.1.7 + '@vitest/utils': 4.1.7 es-module-lexer: 2.1.0 expect-type: 1.3.0 magic-string: 0.30.21 @@ -26463,68 +26922,20 @@ snapshots: picomatch: 4.0.4 std-env: 4.1.0 tinybench: 2.9.0 - tinyexec: 1.1.1 + tinyexec: 1.1.2 tinyglobby: 0.2.16 tinyrainbow: 3.1.0 - vite: 8.0.10(@types/node@24.12.2)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3) + vite: 8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0) why-is-node-running: 2.3.0 optionalDependencies: '@opentelemetry/api': 1.9.1 - '@types/node': 24.12.2 - '@vitest/coverage-v8': 4.1.5(vitest@4.1.5) + '@types/node': 24.12.4 + '@vitest/coverage-v8': 4.1.7(vitest@4.1.7) happy-dom: 20.9.0 jsdom: 26.1.0(canvas@3.2.3) transitivePeerDependencies: - msw - vitest@4.1.5(@opentelemetry/api@1.9.1)(@types/node@25.6.0)(@vitest/coverage-v8@4.1.5)(happy-dom@20.9.0)(jsdom@26.1.0(canvas@3.2.3))(vite@8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)): - dependencies: - '@vitest/expect': 4.1.5 - '@vitest/mocker': 4.1.5(vite@8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)) - '@vitest/pretty-format': 4.1.5 - '@vitest/runner': 4.1.5 - '@vitest/snapshot': 4.1.5 - '@vitest/spy': 4.1.5 - '@vitest/utils': 4.1.5 - es-module-lexer: 2.1.0 - expect-type: 1.3.0 - magic-string: 0.30.21 - obug: 2.1.1 - pathe: 2.0.3 - picomatch: 4.0.4 - std-env: 4.1.0 - tinybench: 2.9.0 - tinyexec: 1.1.1 - tinyglobby: 0.2.16 - tinyrainbow: 3.1.0 - vite: 8.0.10(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3) - why-is-node-running: 2.3.0 - optionalDependencies: - '@opentelemetry/api': 1.9.1 - '@types/node': 25.6.0 - '@vitest/coverage-v8': 4.1.5(vitest@4.1.5) - happy-dom: 20.9.0 - jsdom: 26.1.0(canvas@3.2.3) - transitivePeerDependencies: - - msw - - vscode-jsonrpc@8.2.0: {} - - vscode-languageserver-protocol@3.17.5: - dependencies: - vscode-jsonrpc: 8.2.0 - vscode-languageserver-types: 3.17.5 - - vscode-languageserver-textdocument@1.0.12: {} - - vscode-languageserver-types@3.17.5: {} - - vscode-languageserver@9.0.1: - dependencies: - vscode-languageserver-protocol: 3.17.5 - - vscode-uri@3.0.8: {} - w3c-keyname@2.2.8: {} w3c-xmlserializer@5.0.0: @@ -26558,7 +26969,7 @@ snapshots: dependencies: '@discoveryjs/json-ext': 0.5.7 acorn: 8.16.0 - acorn-walk: 8.3.4 + acorn-walk: 8.3.5 commander: 7.2.0 debounce: 1.2.1 escape-string-regexp: 4.0.0 @@ -26572,7 +26983,7 @@ snapshots: - bufferutil - utf-8-validate - webpack-dev-middleware@7.4.5(tslib@2.8.1)(webpack@5.106.2): + webpack-dev-middleware@7.4.5(tslib@2.8.1)(webpack@5.107.0(postcss@8.5.15)): dependencies: colorette: 2.0.20 memfs: 4.57.2(tslib@2.8.1) @@ -26581,16 +26992,16 @@ snapshots: range-parser: 1.2.1 schema-utils: 4.3.3 optionalDependencies: - webpack: 5.106.2 + webpack: 5.107.0(postcss@8.5.15) transitivePeerDependencies: - tslib - webpack-dev-server@5.2.2(tslib@2.8.1)(webpack@5.106.2): + webpack-dev-server@5.2.4(tslib@2.8.1)(webpack@5.107.0(postcss@8.5.15)): dependencies: '@types/bonjour': 3.5.13 '@types/connect-history-api-fallback': 1.5.4 '@types/express': 4.17.25 - '@types/express-serve-static-core': 4.19.7 + '@types/express-serve-static-core': 4.19.8 '@types/serve-index': 1.9.4 '@types/serve-static': 1.15.10 '@types/sockjs': 0.3.36 @@ -26601,22 +27012,22 @@ snapshots: colorette: 2.0.20 compression: 1.8.1 connect-history-api-fallback: 2.0.0 - express: 4.22.1 + express: 4.22.2 graceful-fs: 4.2.11 http-proxy-middleware: 2.0.9(@types/express@4.17.25) - ipaddr.js: 2.3.0 - launch-editor: 2.12.0 + ipaddr.js: 2.4.0 + launch-editor: 2.13.2 open: 10.2.0 p-retry: 6.2.1 schema-utils: 4.3.3 - selfsigned: 2.4.1 - serve-index: 1.9.1 + selfsigned: 5.5.0 + serve-index: 1.9.2 sockjs: 0.3.24 spdy: 4.0.2 - webpack-dev-middleware: 7.4.5(tslib@2.8.1)(webpack@5.106.2) - ws: 8.20.0 + webpack-dev-middleware: 7.4.5(tslib@2.8.1)(webpack@5.107.0(postcss@8.5.15)) + ws: 8.20.1 optionalDependencies: - webpack: 5.106.2 + webpack: 5.107.0(postcss@8.5.15) transitivePeerDependencies: - bufferutil - debug @@ -26638,14 +27049,14 @@ snapshots: webpack-node-externals@3.0.0: {} - webpack-sources@3.3.4: {} + webpack-sources@3.4.1: {} webpack-virtual-modules@0.6.2: {} - webpack@5.106.0(@swc/core@1.15.30(@swc/helpers@0.5.21))(esbuild@0.28.0): + webpack@5.106.0(@swc/core@1.15.33(@swc/helpers@0.5.22))(esbuild@0.28.0)(lightningcss@1.32.0): dependencies: '@types/eslint-scope': 3.7.7 - '@types/estree': 1.0.8 + '@types/estree': 1.0.9 '@types/json-schema': 7.0.15 '@webassemblyjs/ast': 1.14.1 '@webassemblyjs/wasm-edit': 1.14.1 @@ -26654,30 +27065,38 @@ snapshots: acorn-import-phases: 1.0.4(acorn@8.16.0) browserslist: 4.28.2 chrome-trace-event: 1.0.4 - enhanced-resolve: 5.21.0 + enhanced-resolve: 5.21.5 es-module-lexer: 2.1.0 eslint-scope: 5.1.1 events: 3.3.0 glob-to-regexp: 0.4.1 graceful-fs: 4.2.11 json-parse-even-better-errors: 2.3.1 - loader-runner: 4.3.1 + loader-runner: 4.3.2 mime-types: 2.1.35 neo-async: 2.6.2 schema-utils: 4.3.3 tapable: 2.3.3 - terser-webpack-plugin: 5.4.0(@swc/core@1.15.30(@swc/helpers@0.5.21))(esbuild@0.28.0)(webpack@5.106.0(@swc/core@1.15.30(@swc/helpers@0.5.21))(esbuild@0.28.0)) + terser-webpack-plugin: 5.6.0(@swc/core@1.15.33(@swc/helpers@0.5.22))(esbuild@0.28.0)(lightningcss@1.32.0)(webpack@5.106.0(@swc/core@1.15.33(@swc/helpers@0.5.22))(esbuild@0.28.0)(lightningcss@1.32.0)) watchpack: 2.5.1 - webpack-sources: 3.3.4 + webpack-sources: 3.4.1 transitivePeerDependencies: + - '@minify-html/node' - '@swc/core' + - '@swc/css' + - '@swc/html' + - clean-css + - cssnano + - csso - esbuild + - html-minifier-terser + - lightningcss + - postcss - uglify-js - webpack@5.106.2: + webpack@5.107.0(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.15))(html-minifier-terser@7.2.0)(postcss@8.5.15): dependencies: - '@types/eslint-scope': 3.7.7 - '@types/estree': 1.0.8 + '@types/estree': 1.0.9 '@types/json-schema': 7.0.15 '@webassemblyjs/ast': 1.14.1 '@webassemblyjs/wasm-edit': 1.14.1 @@ -26686,33 +27105,81 @@ snapshots: acorn-import-phases: 1.0.4(acorn@8.16.0) browserslist: 4.28.2 chrome-trace-event: 1.0.4 - enhanced-resolve: 5.21.0 + enhanced-resolve: 5.21.5 es-module-lexer: 2.1.0 eslint-scope: 5.1.1 events: 3.3.0 glob-to-regexp: 0.4.1 graceful-fs: 4.2.11 - loader-runner: 4.3.1 + loader-runner: 4.3.2 mime-db: 1.54.0 neo-async: 2.6.2 schema-utils: 4.3.3 tapable: 2.3.3 - terser-webpack-plugin: 5.4.0(webpack@5.106.2) + terser-webpack-plugin: 5.6.0(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.15))(html-minifier-terser@7.2.0)(postcss@8.5.15)(webpack@5.107.0(postcss@8.5.15)) watchpack: 2.5.1 - webpack-sources: 3.3.4 + webpack-sources: 3.4.1 transitivePeerDependencies: + - '@minify-html/node' - '@swc/core' + - '@swc/css' + - '@swc/html' + - clean-css + - cssnano + - csso - esbuild + - html-minifier-terser + - lightningcss + - postcss - uglify-js - webpackbar@7.0.0(webpack@5.106.2): + webpack@5.107.0(postcss@8.5.15): + dependencies: + '@types/estree': 1.0.9 + '@types/json-schema': 7.0.15 + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/wasm-edit': 1.14.1 + '@webassemblyjs/wasm-parser': 1.14.1 + acorn: 8.16.0 + acorn-import-phases: 1.0.4(acorn@8.16.0) + browserslist: 4.28.2 + chrome-trace-event: 1.0.4 + enhanced-resolve: 5.21.5 + es-module-lexer: 2.1.0 + eslint-scope: 5.1.1 + events: 3.3.0 + glob-to-regexp: 0.4.1 + graceful-fs: 4.2.11 + loader-runner: 4.3.2 + mime-db: 1.54.0 + neo-async: 2.6.2 + schema-utils: 4.3.3 + tapable: 2.3.3 + terser-webpack-plugin: 5.6.0(postcss@8.5.15)(webpack@5.107.0(postcss@8.5.15)) + watchpack: 2.5.1 + webpack-sources: 3.4.1 + transitivePeerDependencies: + - '@minify-html/node' + - '@swc/core' + - '@swc/css' + - '@swc/html' + - clean-css + - cssnano + - csso + - esbuild + - html-minifier-terser + - lightningcss + - postcss + - uglify-js + + webpackbar@7.0.0(webpack@5.107.0(postcss@8.5.15)): dependencies: ansis: 3.17.0 consola: 3.4.2 pretty-time: 1.1.0 std-env: 3.10.0 optionalDependencies: - webpack: 5.106.2 + webpack: 5.107.0(postcss@8.5.15) websocket-driver@0.7.4: dependencies: @@ -26813,9 +27280,7 @@ snapshots: ws@7.5.10: {} - ws@8.18.3: {} - - ws@8.20.0: {} + ws@8.20.1: {} wsl-utils@0.1.0: dependencies: @@ -26830,7 +27295,7 @@ snapshots: xml-js@1.6.11: dependencies: - sax: 1.4.3 + sax: 1.6.0 xml-name-validator@5.0.0: optional: true @@ -26854,7 +27319,7 @@ snapshots: yaml@1.10.3: {} - yaml@2.8.3: {} + yaml@2.9.0: {} yargs-parser@18.1.3: dependencies: diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 89a5337358..a848deca82 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -8,9 +8,6 @@ packages: - web - .github - packages/* - -dedupePeerDependents: false - ignoredBuiltDependencies: - '@nestjs/core' - '@parcel/watcher' @@ -27,51 +24,47 @@ ignoredBuiltDependencies: - protobufjs - ssh2 - utimes - -injectWorkspacePackages: true - onlyBuiltDependencies: + - sharp - '@tailwindcss/oxide' - bcrypt - - better-sqlite3 - - sharp - overrides: canvas: 3.2.3 sharp: ^0.34.5 # pending docusaurus 3.10.1 webpackbar: ^7.0.0 - packageExtensions: - '@immich/ui': - dependencies: - tailwindcss: '>=4.1' - '@photo-sphere-viewer/equirectangular-video-adapter': - dependencies: - three: '*' - '@photo-sphere-viewer/video-plugin': - dependencies: - three: '*' - bcrypt: - dependencies: - node-addon-api: '*' - node-gyp: '*' nestjs-kysely: dependencies: tslib: '*' nestjs-otel: dependencies: tslib: '*' + '@photo-sphere-viewer/equirectangular-video-adapter': + dependencies: + three: '*' + '@photo-sphere-viewer/video-plugin': + dependencies: + three: '*' sharp: dependencies: node-addon-api: '*' node-gyp: '*' + '@immich/ui': + dependencies: + tailwindcss: '>=4.1' tailwind-variants: dependencies: tailwindcss: '>=4.1' - + bcrypt: + dependencies: + node-addon-api: '*' + node-gyp: '*' + '@nestjs/swagger': + peerDependencies: + typescript: '*' +dedupePeerDependents: false preferWorkspacePackages: true - +injectWorkspacePackages: true shamefullyHoist: false - verifyDepsBeforeRun: install diff --git a/server/Dockerfile b/server/Dockerfile index 96888ff5c3..1d4729142b 100644 --- a/server/Dockerfile +++ b/server/Dockerfile @@ -13,14 +13,15 @@ FROM builder AS server WORKDIR /usr/src/app COPY ./server ./server/ +COPY ./packages/sdk ./packages/sdk/ COPY ./packages/plugin-sdk ./packages/plugin-sdk/ RUN --mount=type=cache,id=pnpm-server,target=/buildcache/pnpm-store \ --mount=type=bind,source=package.json,target=package.json \ --mount=type=bind,source=.pnpmfile.cjs,target=.pnpmfile.cjs \ --mount=type=bind,source=pnpm-lock.yaml,target=pnpm-lock.yaml \ --mount=type=bind,source=pnpm-workspace.yaml,target=pnpm-workspace.yaml \ - SHARP_IGNORE_GLOBAL_LIBVIPS=true pnpm --filter immich --filter @immich/plugin-sdk --frozen-lockfile build && \ - SHARP_FORCE_GLOBAL_LIBVIPS=true pnpm --filter immich --frozen-lockfile --prod --no-optional deploy /output/server-pruned + SHARP_IGNORE_GLOBAL_LIBVIPS=true pnpm --filter @immich/sdk --filter @immich/plugin-sdk --filter immich --frozen-lockfile build && \ + SHARP_FORCE_GLOBAL_LIBVIPS=true pnpm --filter immich --frozen-lockfile --prod --no-optional deploy /output/server-pruned FROM builder AS web @@ -55,7 +56,7 @@ FROM builder AS plugins ARG TARGETPLATFORM -COPY --from=ghcr.io/jdx/mise:2026.3.12@sha256:0210678cbf58413806531a27adb2c7daf1c37238e56e8f7ea381d73521571775 /usr/local/bin/mise /usr/local/bin/mise +COPY --from=ghcr.io/jdx/mise:2026.5.11@sha256:2ba959e4827f845fe0c4cfb4814089e790dc513040ef74f9e14925f446412a51 /usr/local/bin/mise /usr/local/bin/mise WORKDIR /app COPY ./mise.toml ./mise.toml @@ -66,6 +67,7 @@ ENV MISE_DISABLE_TOOLS=flutter RUN --mount=type=cache,id=mise-tools-${TARGETPLATFORM},target=/buildcache/mise \ mise install +COPY ./packages/sdk ./packages/sdk/ COPY ./packages/plugin-core ./packages/plugin-core/ COPY ./packages/plugin-sdk ./packages/plugin-sdk/ @@ -88,8 +90,8 @@ ENV NODE_ENV=production \ COPY --from=server /output/server-pruned ./server COPY --from=web /usr/src/app/web/build /build/www COPY --from=cli /output/cli-pruned ./cli -COPY --from=plugins /app/packages/plugin-core/dist /build/plugins/immich-core-plugin/dist -COPY --from=plugins /app/packages/plugin-core/manifest.json /build/plugins/immich-core-plugin/manifest.json +COPY --from=plugins /app/packages/plugin-core/dist /build/plugins/immich-plugin-core/dist +COPY --from=plugins /app/packages/plugin-core/manifest.json /build/plugins/immich-plugin-core/manifest.json RUN ln -s ../../cli/bin/immich server/bin/immich COPY LICENSE /licenses/LICENSE.txt COPY LICENSE /LICENSE diff --git a/server/Dockerfile.dev b/server/Dockerfile.dev index d30d0c41fe..1dcd44d04c 100644 --- a/server/Dockerfile.dev +++ b/server/Dockerfile.dev @@ -1,14 +1,10 @@ # dev build FROM ghcr.io/immich-app/base-server-dev:202605051129@sha256:d07d8fcdb7e9f3ac22a811e87761ebf341ed0bb91956b89097540c2ed3fb9ca3 AS dev -ENV COREPACK_ENABLE_DOWNLOAD_PROMPT=0 \ - CI=1 \ - COREPACK_HOME=/tmp \ - PNPM_HOME=/buildcache/pnpm-store -RUN npm install --global corepack@latest && \ - corepack enable pnpm && \ - echo "devdir=/buildcache/node-gyp" >> /usr/local/etc/npmrc && \ +COPY --from=ghcr.io/jdx/mise:2026.5.11@sha256:2ba959e4827f845fe0c4cfb4814089e790dc513040ef74f9e14925f446412a51 /usr/local/bin/mise /usr/local/bin/mise + +RUN echo "devdir=/buildcache/node-gyp" >> /usr/local/etc/npmrc && \ echo "store-dir=/buildcache/pnpm-store" >> /usr/local/etc/npmrc && \ echo "cache-dir=/buildcache/pnpm-cache" >> /usr/local/etc/npmrc && \ echo "# Retry configuration - default is 2" >> /usr/local/etc/npmrc && \ @@ -16,12 +12,17 @@ RUN npm install --global corepack@latest && \ mkdir -p /buildcache/pnpm-store /buildcache/pnpm-cache /buildcache/node-gyp && \ chmod -R o+rw /buildcache +ENV CI=1 +ENV PNPM_HOME=/buildcache/pnpm-store +ENV MISE_DATA_DIR=/buildcache/mise +ENV MISE_TRUSTED_CONFIG_PATHS=/usr/src/app/mise.toml +ENV PATH="${MISE_DATA_DIR}/shims:${PATH}:/usr/src/app/server/bin:/usr/src/app/web/bin" +ENV IMMICH_ENV=development +ENV NVIDIA_DRIVER_CAPABILITIES=all +ENV NVIDIA_VISIBLE_DEVICES=all + WORKDIR /usr/src/app -ENV PATH="${PATH}:/usr/src/app/server/bin:/usr/src/app/web/bin" \ - IMMICH_ENV=development \ - NVIDIA_DRIVER_CAPABILITIES=all \ - NVIDIA_VISIBLE_DEVICES=all ENTRYPOINT ["tini", "--", "/bin/bash", "-c"] FROM dev AS dev-container-server diff --git a/server/mise.toml b/server/mise.toml index f7e4f92a26..1462af0c52 100644 --- a/server/mise.toml +++ b/server/mise.toml @@ -68,6 +68,7 @@ run = [ [tasks.ci-medium] run = [ { task = ":install" }, + { task = "//:plugins" }, { task = "//packages/plugin-core:build" }, { task = ":test-medium --run" }, ] diff --git a/server/package.json b/server/package.json index 2e9c729c2f..a4f8a73244 100644 --- a/server/package.json +++ b/server/package.json @@ -50,14 +50,14 @@ "@nestjs/websockets": "^11.0.4", "@opentelemetry/api": "^1.9.0", "@opentelemetry/context-async-hooks": "^2.0.0", - "@opentelemetry/exporter-prometheus": "^0.217.0", - "@opentelemetry/instrumentation-http": "^0.215.0", - "@opentelemetry/instrumentation-ioredis": "^0.63.0", - "@opentelemetry/instrumentation-nestjs-core": "^0.61.0", - "@opentelemetry/instrumentation-pg": "^0.67.0", + "@opentelemetry/exporter-prometheus": "^0.218.0", + "@opentelemetry/instrumentation-http": "^0.218.0", + "@opentelemetry/instrumentation-ioredis": "^0.66.0", + "@opentelemetry/instrumentation-nestjs-core": "^0.64.0", + "@opentelemetry/instrumentation-pg": "^0.70.0", "@opentelemetry/resources": "^2.0.1", "@opentelemetry/sdk-metrics": "^2.0.1", - "@opentelemetry/sdk-node": "^0.217.0", + "@opentelemetry/sdk-node": "^0.218.0", "@opentelemetry/semantic-conventions": "^1.34.0", "@react-email/components": "^1.0.0", "@react-email/render": "^2.0.0", @@ -117,7 +117,7 @@ "ua-parser-js": "^2.0.0", "uuid": "^14.0.0", "validator": "^13.12.0", - "zod": "^4.3.6" + "zod": "4.3.6" }, "devDependencies": { "@eslint/js": "^10.0.0", @@ -139,7 +139,7 @@ "@types/luxon": "^3.6.2", "@types/mock-fs": "^4.13.1", "@types/multer": "^2.0.0", - "@types/node": "^24.12.2", + "@types/node": "^24.12.4", "@types/nodemailer": "^8.0.0", "@types/picomatch": "^4.0.0", "@types/pngjs": "^6.0.5", diff --git a/server/src/controllers/plugin.controller.ts b/server/src/controllers/plugin.controller.ts index fb1bda287e..10eb4ba514 100644 --- a/server/src/controllers/plugin.controller.ts +++ b/server/src/controllers/plugin.controller.ts @@ -6,6 +6,7 @@ import { PluginMethodSearchDto, PluginResponseDto, PluginSearchDto, + PluginTemplateResponseDto, } from 'src/dtos/plugin.dto'; import { Permission } from 'src/enum'; import { Authenticated } from 'src/middleware/auth.guard'; @@ -39,6 +40,17 @@ export class PluginController { return this.service.searchMethods(dto); } + @Get('templates') + @Authenticated({ permission: Permission.PluginRead }) + @Endpoint({ + summary: 'Retrieve workflow templates', + description: 'Retrieve workflow templates provided by installed plugins', + history: HistoryBuilder.v3(), + }) + searchPluginTemplates(): Promise { + return this.service.searchTemplates(); + } + @Get(':id') @Authenticated({ permission: Permission.PluginRead }) @Endpoint({ diff --git a/server/src/controllers/workflow.controller.spec.ts b/server/src/controllers/workflow.controller.spec.ts index 7bc164e285..140fb00e95 100644 --- a/server/src/controllers/workflow.controller.spec.ts +++ b/server/src/controllers/workflow.controller.spec.ts @@ -1,5 +1,5 @@ +import { WorkflowTrigger } from '@immich/plugin-sdk'; import { WorkflowController } from 'src/controllers/workflow.controller'; -import { WorkflowTrigger } from 'src/enum'; import { LoggingRepository } from 'src/repositories/logging.repository'; import { WorkflowService } from 'src/services/workflow.service'; import request from 'supertest'; diff --git a/server/src/dtos/album.dto.ts b/server/src/dtos/album.dto.ts index 095e399b96..100550659d 100644 --- a/server/src/dtos/album.dto.ts +++ b/server/src/dtos/album.dto.ts @@ -65,6 +65,8 @@ const UpdateAlbumSchema = z const GetAlbumsSchema = z .object({ + id: z.uuidv4().optional().describe('Album ID'), + name: z.string().optional().describe('Album name (exact match)'), isOwned: stringToBool .optional() .describe('Filter by ownership: true = only owned, false = only shared-with-me, undefined = no filter'), diff --git a/server/src/dtos/plugin-manifest.dto.ts b/server/src/dtos/plugin-manifest.dto.ts index 4d004a375d..b175c6e1bb 100644 --- a/server/src/dtos/plugin-manifest.dto.ts +++ b/server/src/dtos/plugin-manifest.dto.ts @@ -1,6 +1,6 @@ import { createZodDto } from 'nestjs-zod'; import { JsonSchemaSchema } from 'src/dtos/json-schema.dto'; -import { WorkflowTypeSchema } from 'src/enum'; +import { WorkflowTriggerSchema, WorkflowTypeSchema } from 'src/enum'; import z from 'zod'; const pluginNameRegex = /^[a-z0-9-]+[a-z0-9]$/; @@ -23,6 +23,25 @@ const PluginManifestMethodSchema = z }) .meta({ id: 'PluginManifestMethodDto' }); +const PluginManifestTemplateStepSchema = z + .object({ + method: z.string().min(1).describe('Step plugin method (pluginName#methodName)'), + config: z.record(z.string(), z.unknown()).nullable().optional().describe('Step configuration'), + enabled: z.boolean().optional().describe('Whether the step is enabled'), + }) + .meta({ id: 'PluginManifestTemplateStepDto' }); + +const PluginManifestTemplateSchema = z + .object({ + name: z.string().min(1).describe('Template name (must be unique within the manifest)'), + title: z.string().min(1).describe('Template title'), + description: z.string().min(1).describe('Template description'), + trigger: WorkflowTriggerSchema.describe('Workflow trigger'), + steps: z.array(PluginManifestTemplateStepSchema).describe('Workflow steps'), + uiHints: z.array(z.string()).optional().default([]).describe('Ui hints, for example "smart-album"'), + }) + .meta({ id: 'PluginManifestTemplateDto' }); + const PluginManifestSchema = z .object({ name: z @@ -39,6 +58,14 @@ const PluginManifestSchema = z wasmPath: z.string().min(1).describe('WASM file path'), author: z.string().min(1).describe('Plugin author'), methods: z.array(PluginManifestMethodSchema).optional().default([]).describe('Plugin methods'), + templates: z + .array(PluginManifestTemplateSchema) + .optional() + .default([]) + .refine((templates) => new Set(templates.map((t) => t.name)).size === templates.length, { + error: 'Template names must be unique within the manifest', + }) + .describe('Workflow templates'), }) .meta({ id: 'PluginManifestDto' }); diff --git a/server/src/dtos/plugin.dto.ts b/server/src/dtos/plugin.dto.ts index 410ada4b53..8ee695d61c 100644 --- a/server/src/dtos/plugin.dto.ts +++ b/server/src/dtos/plugin.dto.ts @@ -1,7 +1,8 @@ +import { WorkflowTrigger } from '@immich/plugin-sdk'; import { createZodDto } from 'nestjs-zod'; import { JsonSchemaDto } from 'src/dtos/json-schema.dto'; import { WorkflowTriggerSchema, WorkflowType, WorkflowTypeSchema } from 'src/enum'; -import { asMethodString } from 'src/utils/workflow'; +import { asPluginKey } from 'src/utils/workflow'; import z from 'zod'; const PluginSearchSchema = z @@ -43,6 +44,25 @@ const PluginResponseSchema = z }) .meta({ id: 'PluginResponseDto' }); +const PluginTemplateStepResponseSchema = z + .object({ + method: z.string().describe('Step plugin method'), + config: z.record(z.string(), z.unknown()).nullable().describe('Step configuration'), + enabled: z.boolean().optional().describe('Whether the step is enabled'), + }) + .meta({ id: 'PluginTemplateStepResponseDto' }); + +const PluginTemplateResponseSchema = z + .object({ + key: z.string().describe('Template key (unique across all templates)'), + title: z.string().describe('Template title'), + description: z.string().describe('Template description'), + trigger: WorkflowTriggerSchema.describe('Workflow trigger'), + steps: z.array(PluginTemplateStepResponseSchema).describe('Workflow steps'), + uiHints: z.array(z.string()).describe('Ui hints, for example "smart-album"'), + }) + .meta({ id: 'PluginTemplateResponseDto' }); + const PluginMethodSearchSchema = z .object({ id: z.uuidv4().optional().describe('Plugin method ID'), @@ -61,6 +81,35 @@ export class PluginSearchDto extends createZodDto(PluginSearchSchema) {} export class PluginResponseDto extends createZodDto(PluginResponseSchema) {} export class PluginMethodSearchDto extends createZodDto(PluginMethodSearchSchema) {} export class PluginMethodResponseDto extends createZodDto(PluginMethodResponseSchema) {} +export class PluginTemplateResponseDto extends createZodDto(PluginTemplateResponseSchema) {} + +export type PluginTemplate = { + name: string; + title: string; + description: string; + trigger: WorkflowTrigger; + steps: Array<{ + method: string; + config?: Record | null; + enabled?: boolean; + }>; + uiHints: string[]; +}; + +export const mapTemplate = (plugin: { name: string }, template: PluginTemplate): PluginTemplateResponseDto => { + return { + key: asPluginKey({ pluginName: plugin.name, name: template.name }), + title: template.title, + description: template.description, + trigger: template.trigger, + steps: template.steps.map((step) => ({ + method: step.method, + config: step.config ?? null, + enabled: step.enabled, + })), + uiHints: template.uiHints ?? [], + }; +}; type Plugin = { id: string; @@ -101,7 +150,7 @@ export function mapPlugin(plugin: Plugin): PluginResponseDto { export const mapMethod = (method: PluginMethod): PluginMethodResponseDto => { return { - key: asMethodString({ pluginName: method.pluginName, methodName: method.name }), + key: asPluginKey({ pluginName: method.pluginName, name: method.name }), name: method.name, title: method.title, hostFunctions: method.hostFunctions, diff --git a/server/src/dtos/search.dto.ts b/server/src/dtos/search.dto.ts index ae5b5e2c8c..c9a92b165f 100644 --- a/server/src/dtos/search.dto.ts +++ b/server/src/dtos/search.dto.ts @@ -186,7 +186,11 @@ const SearchAlbumResponseSchema = z const SearchAssetResponseSchema = z .object({ - total: z.int().min(0).describe('Total number of matching assets'), + total: z + .int() + .min(0) + .describe('Total number of matching assets') + .meta(new HistoryBuilder().deprecated('v3.0.0').getExtensions()), count: z.int().min(0).describe('Number of assets in this page'), items: z.array(AssetResponseSchema), facets: z.array(SearchFacetResponseSchema), diff --git a/server/src/dtos/time-bucket.dto.ts b/server/src/dtos/time-bucket.dto.ts index f63860a1df..a2ee06c878 100644 --- a/server/src/dtos/time-bucket.dto.ts +++ b/server/src/dtos/time-bucket.dto.ts @@ -107,8 +107,8 @@ const TimeBucketAssetResponseSchema = z livePhotoVideoId: z .array(z.string().nullable()) .describe('Array of live photo video asset IDs (null for non-live photos)'), - city: z.array(z.string().nullable()).describe('Array of city names extracted from EXIF GPS data'), - country: z.array(z.string().nullable()).describe('Array of country names extracted from EXIF GPS data'), + city: z.array(z.string().nullable()).optional().describe('Array of city names extracted from EXIF GPS data'), + country: z.array(z.string().nullable()).optional().describe('Array of country names extracted from EXIF GPS data'), latitude: z .array(z.number().nullable()) .optional() diff --git a/server/src/dtos/workflow.dto.ts b/server/src/dtos/workflow.dto.ts index 8a5960470d..1a2c2ac9f9 100644 --- a/server/src/dtos/workflow.dto.ts +++ b/server/src/dtos/workflow.dto.ts @@ -1,6 +1,6 @@ -import type { WorkflowStepConfig } from '@immich/plugin-sdk'; +import type { WorkflowStepConfig, WorkflowTrigger } from '@immich/plugin-sdk'; import { createZodDto } from 'nestjs-zod'; -import { WorkflowTrigger, WorkflowTriggerSchema, WorkflowTypeSchema } from 'src/enum'; +import { WorkflowTriggerSchema, WorkflowTypeSchema } from 'src/enum'; import z from 'zod'; const WorkflowTriggerResponseSchema = z diff --git a/server/src/enum.ts b/server/src/enum.ts index ba6d1ed843..1a41a774b0 100644 --- a/server/src/enum.ts +++ b/server/src/enum.ts @@ -1,3 +1,4 @@ +import { WorkflowTrigger } from '@immich/plugin-sdk'; import z from 'zod'; export enum AuthType { @@ -866,7 +867,7 @@ export enum JobName { Ocr = 'Ocr', // Workflow - WorkflowAssetCreate = 'WorkflowAssetCreate', + WorkflowAssetTrigger = 'WorkflowAssetTrigger', } export const JobNameSchema = z.enum(JobName).describe('Job name').meta({ id: 'JobName' }); @@ -1165,11 +1166,6 @@ export enum PluginContext { export const PluginContextSchema = z.enum(PluginContext).describe('Plugin context').meta({ id: 'PluginContextType' }); -export enum WorkflowTrigger { - AssetCreate = 'AssetCreate', - PersonRecognized = 'PersonRecognized', -} - export const WorkflowTriggerSchema = z .enum(WorkflowTrigger) .describe('Plugin trigger type') diff --git a/server/src/queries/asset.repository.sql b/server/src/queries/asset.repository.sql index 4d90bbf0d5..819ec4f838 100644 --- a/server/src/queries/asset.repository.sql +++ b/server/src/queries/asset.repository.sql @@ -384,8 +384,6 @@ with asset."fileCreatedAt" at time zone 'utc' as "fileCreatedAt", asset."createdAt" at time zone 'utc' as "createdAt", encode("asset"."thumbhash", 'base64') as "thumbhash", - "asset_exif"."city", - "asset_exif"."country", "asset_exif"."projectionType", coalesce( case @@ -398,6 +396,8 @@ with end, 1 ) as "ratio", + "asset_exif"."city", + "asset_exif"."country", "stack" from "asset" @@ -432,8 +432,6 @@ with ), "agg" as ( select - coalesce(array_agg("city"), '{}') as "city", - coalesce(array_agg("country"), '{}') as "country", coalesce(array_agg("duration"), '{}') as "duration", coalesce(array_agg("id"), '{}') as "id", coalesce(array_agg("visibility"), '{}') as "visibility", @@ -449,6 +447,8 @@ with coalesce(array_agg("ratio"), '{}') as "ratio", coalesce(array_agg("status"), '{}') as "status", coalesce(array_agg("thumbhash"), '{}') as "thumbhash", + coalesce(array_agg("city"), '{}') as "city", + coalesce(array_agg("country"), '{}') as "country", coalesce(json_agg("stack"), '[]') as "stack" from "cte" diff --git a/server/src/queries/plugin.repository.sql b/server/src/queries/plugin.repository.sql index 2c920b7ab0..824602ba86 100644 --- a/server/src/queries/plugin.repository.sql +++ b/server/src/queries/plugin.repository.sql @@ -35,6 +35,7 @@ select "plugin"."version", "plugin"."createdAt", "plugin"."updatedAt", + "plugin"."templates", ( select coalesce(json_agg(agg), '[]') @@ -60,6 +61,42 @@ from order by "plugin"."name" +-- PluginRepository.getByHash +select + "plugin"."id", + "plugin"."name", + "plugin"."title", + "plugin"."description", + "plugin"."author", + "plugin"."version", + "plugin"."createdAt", + "plugin"."updatedAt", + "plugin"."templates", + ( + select + coalesce(json_agg(agg), '[]') + from + ( + select + "plugin_method"."name", + "plugin_method"."title", + "plugin_method"."description", + "plugin_method"."types", + "plugin_method"."schema", + "plugin_method"."hostFunctions", + "plugin_method"."uiHints", + "plugin"."name" as "pluginName" + from + "plugin_method" + where + "plugin_method"."pluginId" = "plugin"."id" + ) as agg + ) as "methods" +from + "plugin" +where + "plugin"."sha256hash" = $1 + -- PluginRepository.getByName select "plugin"."id", @@ -70,6 +107,7 @@ select "plugin"."version", "plugin"."createdAt", "plugin"."updatedAt", + "plugin"."templates", ( select coalesce(json_agg(agg), '[]') @@ -105,6 +143,7 @@ select "plugin"."version", "plugin"."createdAt", "plugin"."updatedAt", + "plugin"."templates", ( select coalesce(json_agg(agg), '[]') diff --git a/server/src/repositories/album.repository.ts b/server/src/repositories/album.repository.ts index a712151355..724788fa74 100644 --- a/server/src/repositories/album.repository.ts +++ b/server/src/repositories/album.repository.ts @@ -209,11 +209,16 @@ export class AlbumRepository { } @GenerateSql({ params: [DummyValue.UUID, { isOwned: true, isShared: true }] }) - getAll(ownerId: string, options: { isOwned?: boolean; isShared?: boolean } = {}): Promise { + getAll( + ownerId: string, + options: { id?: string; isOwned?: boolean; isShared?: boolean; name?: string } = {}, + ): Promise { return this.buildAlbumBaseQuery(ownerId, options) .selectAll('album') .select(withAlbumUsers(ownerId)) .select(withSharedLink) + .$if(!!options.id, (qb) => qb.where('album.id', '=', options.id!)) + .$if(!!options.name, (qb) => qb.where('album.albumName', '=', options.name!)) .orderBy('album.createdAt', 'desc') .execute(); } diff --git a/server/src/repositories/asset.repository.ts b/server/src/repositories/asset.repository.ts index b144666773..5488f747ad 100644 --- a/server/src/repositories/asset.repository.ts +++ b/server/src/repositories/asset.repository.ts @@ -786,8 +786,6 @@ export class AssetRepository { sql`asset."fileCreatedAt" at time zone 'utc'`.as('fileCreatedAt'), sql`asset."createdAt" at time zone 'utc'`.as('createdAt'), eb.fn('encode', ['asset.thumbhash', sql.lit('base64')]).as('thumbhash'), - 'asset_exif.city', - 'asset_exif.country', 'asset_exif.projectionType', eb.fn .coalesce( @@ -801,6 +799,9 @@ export class AssetRepository { ) .as('ratio'), ]) + .$if(!auth.sharedLink || auth.sharedLink.showExif, (qb) => + qb.select(['asset_exif.city', 'asset_exif.country']), + ) .$if(!!options.withCoordinates, (qb) => qb.select(['asset_exif.latitude', 'asset_exif.longitude'])) .where('asset.deletedAt', options.isTrashed ? 'is not' : 'is', null) .$if(options.visibility == undefined, withDefaultVisibility) @@ -875,8 +876,6 @@ export class AssetRepository { qb .selectFrom('cte') .select((eb) => [ - eb.fn.coalesce(eb.fn('array_agg', ['city']), sql.lit('{}')).as('city'), - eb.fn.coalesce(eb.fn('array_agg', ['country']), sql.lit('{}')).as('country'), eb.fn.coalesce(eb.fn('array_agg', ['duration']), sql.lit('{}')).as('duration'), eb.fn.coalesce(eb.fn('array_agg', ['id']), sql.lit('{}')).as('id'), eb.fn.coalesce(eb.fn('array_agg', ['visibility']), sql.lit('{}')).as('visibility'), @@ -894,6 +893,12 @@ export class AssetRepository { eb.fn.coalesce(eb.fn('array_agg', ['status']), sql.lit('{}')).as('status'), eb.fn.coalesce(eb.fn('array_agg', ['thumbhash']), sql.lit('{}')).as('thumbhash'), ]) + .$if(!auth.sharedLink || auth.sharedLink.showExif, (qb) => + qb.select((eb) => [ + eb.fn.coalesce(eb.fn('array_agg', ['city']), sql.lit('{}')).as('city'), + eb.fn.coalesce(eb.fn('array_agg', ['country']), sql.lit('{}')).as('country'), + ]), + ) .$if(!!options.withCoordinates, (qb) => qb.select((eb) => [ eb.fn.coalesce(eb.fn('array_agg', ['latitude']), sql.lit('{}')).as('latitude'), diff --git a/server/src/repositories/database.repository.ts b/server/src/repositories/database.repository.ts index a86e929ef4..df69e85d84 100644 --- a/server/src/repositories/database.repository.ts +++ b/server/src/repositories/database.repository.ts @@ -274,6 +274,7 @@ export class DatabaseRepository { columns: { ignoreExtra: true }, functions: { ignoreExtra: false }, parameters: { ignoreExtra: true }, + extensions: { ignoreExtra: true }, }); return drift; diff --git a/server/src/repositories/event.repository.ts b/server/src/repositories/event.repository.ts index 8cff1cbbb8..4404395d90 100644 --- a/server/src/repositories/event.repository.ts +++ b/server/src/repositories/event.repository.ts @@ -10,7 +10,7 @@ import { AuthDto } from 'src/dtos/auth.dto'; import { ImmichWorker, JobStatus, MetadataKey, QueueName, UserAvatarColor, UserStatus } from 'src/enum'; import { ConfigRepository } from 'src/repositories/config.repository'; import { LoggingRepository } from 'src/repositories/logging.repository'; -import { JobItem, JobSource } from 'src/types'; +import { JobItem, JobSource, UploadFile } from 'src/types'; type EmitHandlers = Partial<{ [T in EmitEvent]: Array> }>; @@ -43,7 +43,7 @@ type EventMap = { AlbumInvite: [{ id: string; userId: string; senderName: string }]; // asset events - AssetCreate: [{ asset: Asset }]; + AssetCreate: [{ asset: Asset; file: UploadFile }]; AssetTag: [{ assetId: string }]; AssetUntag: [{ assetId: string }]; AssetHide: [{ assetId: string; userId: string }]; diff --git a/server/src/repositories/plugin.repository.ts b/server/src/repositories/plugin.repository.ts index a07f433541..43006c6aa6 100644 --- a/server/src/repositories/plugin.repository.ts +++ b/server/src/repositories/plugin.repository.ts @@ -81,6 +81,7 @@ export class PluginRepository { 'plugin.version', 'plugin.createdAt', 'plugin.updatedAt', + 'plugin.templates', jsonArrayFrom( eb .selectFrom('plugin_method') @@ -102,6 +103,11 @@ export class PluginRepository { .execute(); } + @GenerateSql({ params: [DummyValue.STRING] }) + getByHash(hash: Buffer) { + return this.queryBuilder().where('plugin.sha256hash', '=', hash).executeTakeFirst(); + } + @GenerateSql({ params: [DummyValue.STRING] }) getByName(name: string) { return this.queryBuilder().where('plugin.name', '=', name).executeTakeFirst(); @@ -151,6 +157,8 @@ export class PluginRepository { author: eb.ref('excluded.author'), version: eb.ref('excluded.version'), wasmBytes: eb.ref('excluded.wasmBytes'), + templates: eb.ref('excluded.templates'), + sha256hash: eb.ref('excluded.sha256hash'), })), ) .returning(['id', 'name']) diff --git a/server/src/repositories/workflow.repository.ts b/server/src/repositories/workflow.repository.ts index cd5aa6431f..9ceef72a50 100644 --- a/server/src/repositories/workflow.repository.ts +++ b/server/src/repositories/workflow.repository.ts @@ -45,9 +45,10 @@ export class WorkflowRepository { } @GenerateSql({ params: [DummyValue.UUID] }) - search(dto: WorkflowSearchDto & { ownerId?: string }) { + search(dto: WorkflowSearchDto & { userId?: string }) { return this.queryBuilder() - .$if(!!dto.ownerId, (qb) => qb.where('ownerId', '=', dto.ownerId!)) + .$if(!!dto.id, (qb) => qb.where('id', '=', dto.id!)) + .$if(!!dto.userId, (qb) => qb.where('ownerId', '=', dto.userId!)) .$if(!!dto.trigger, (qb) => qb.where('trigger', '=', dto.trigger!)) .$if(dto.enabled !== undefined, (qb) => qb.where('enabled', '=', dto.enabled!)) .orderBy('createdAt', 'desc') @@ -102,6 +103,10 @@ export class WorkflowRepository { }); } + async updateStep(id: string, dto: Updateable) { + await this.db.updateTable('workflow_step').where('workflow_step.id', '=', id).set(dto).execute(); + } + private async replaceAndReturn(tx: Kysely, workflowId: string, steps?: WorkflowStepUpsert[]) { if (steps) { await tx.deleteFrom('workflow_step').where('workflowId', '=', workflowId).execute(); diff --git a/server/src/schema/migrations/1773175313374-Test.ts b/server/src/schema/migrations/1773175313374-Test.ts deleted file mode 100644 index 03479a760c..0000000000 --- a/server/src/schema/migrations/1773175313374-Test.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { Kysely, sql } from 'kysely'; - -export async function up(db: Kysely): Promise { - await sql`ALTER TABLE "workflow" ADD "updateId" uuid NOT NULL DEFAULT immich_uuid_v7();`.execute(db); -} - -export async function down(db: Kysely): Promise { - await sql`ALTER TABLE "workflow" DROP COLUMN "updateId";`.execute(db); -} diff --git a/server/src/schema/migrations/1779806699547-AddPluginTemplates.ts b/server/src/schema/migrations/1779806699547-AddPluginTemplates.ts new file mode 100644 index 0000000000..9e0e75a443 --- /dev/null +++ b/server/src/schema/migrations/1779806699547-AddPluginTemplates.ts @@ -0,0 +1,13 @@ +import { Kysely, sql } from 'kysely'; + +export async function up(db: Kysely): Promise { + await sql`ALTER TABLE "plugin" ADD "templates" jsonb NOT NULL DEFAULT '[]';`.execute(db); + await sql`ALTER TABLE "plugin" ADD "sha256hash" bytea NOT NULL DEFAULT decode('20464b37ad726d03d878d38d873c40a52d1fdfb754feda956ebb464afd689e2f', 'hex');`.execute(db); + await sql`ALTER TABLE "plugin" ALTER COLUMN "sha256hash" DROP DEFAULT;`.execute(db); + await sql`ALTER TABLE "plugin" ALTER COLUMN "templates" DROP DEFAULT;`.execute(db); +} + +export async function down(db: Kysely): Promise { + await sql`ALTER TABLE "plugin" DROP COLUMN "templates";`.execute(db); + await sql`ALTER TABLE "plugin" DROP COLUMN "sha256hash";`.execute(db); +} diff --git a/server/src/schema/tables/notification.table.ts b/server/src/schema/tables/notification.table.ts index 6bf65808f1..fd1afc35c7 100644 --- a/server/src/schema/tables/notification.table.ts +++ b/server/src/schema/tables/notification.table.ts @@ -41,7 +41,7 @@ export class NotificationTable { type!: Generated; @Column({ type: 'jsonb', nullable: true }) - data!: any | null; + data!: unknown | null; @Column() title!: string; diff --git a/server/src/schema/tables/plugin.table.ts b/server/src/schema/tables/plugin.table.ts index 99763a4d43..5de5a329d1 100644 --- a/server/src/schema/tables/plugin.table.ts +++ b/server/src/schema/tables/plugin.table.ts @@ -8,6 +8,7 @@ import { Unique, UpdateDateColumn, } from '@immich/sql-tools'; +import { PluginTemplate } from 'src/dtos/plugin.dto'; @Unique({ columns: ['name', 'version'] }) @Table('plugin') @@ -36,6 +37,12 @@ export class PluginTable { @Column({ type: 'bytea' }) wasmBytes!: Buffer; + @Column({ type: 'jsonb' }) + templates!: PluginTemplate[]; + + @Column({ type: 'bytea' }) + sha256hash!: Buffer; + @CreateDateColumn() createdAt!: Generated; diff --git a/server/src/schema/tables/workflow.table.ts b/server/src/schema/tables/workflow.table.ts index 8ac89d4b65..944fffd9d5 100644 --- a/server/src/schema/tables/workflow.table.ts +++ b/server/src/schema/tables/workflow.table.ts @@ -1,3 +1,4 @@ +import { WorkflowTrigger } from '@immich/plugin-sdk'; import { Column, CreateDateColumn, @@ -9,7 +10,6 @@ import { UpdateDateColumn, } from '@immich/sql-tools'; import { UpdatedAtTrigger, UpdateIdColumn } from 'src/decorators'; -import { WorkflowTrigger } from 'src/enum'; import { UserTable } from 'src/schema/tables/user.table'; @Table('workflow') diff --git a/server/src/services/album.service.ts b/server/src/services/album.service.ts index 723288e5b5..31c4ff2e38 100644 --- a/server/src/services/album.service.ts +++ b/server/src/services/album.service.ts @@ -37,15 +37,12 @@ export class AlbumService extends BaseService { }; } - async getAll( - { user: { id: ownerId } }: AuthDto, - { assetId, isOwned, isShared }: GetAlbumsDto, - ): Promise { + async getAll({ user: { id: ownerId } }: AuthDto, { assetId, ...rest }: GetAlbumsDto): Promise { await this.albumRepository.updateThumbnails(); const albums = assetId ? await this.albumRepository.getByAssetId(ownerId, assetId) - : await this.albumRepository.getAll(ownerId, { isOwned, isShared }); + : await this.albumRepository.getAll(ownerId, rest); if (albums.length === 0) { return []; diff --git a/server/src/services/asset-media.service.spec.ts b/server/src/services/asset-media.service.spec.ts index cb3cc4d62a..9ef72a0897 100644 --- a/server/src/services/asset-media.service.spec.ts +++ b/server/src/services/asset-media.service.spec.ts @@ -339,7 +339,6 @@ describe(AssetMediaService.name, () => { }); expect(mocks.asset.create).toHaveBeenCalled(); - expect(mocks.user.updateUsage).toHaveBeenCalledWith(authStub.user1.user.id, file.size); expect(mocks.storage.utimes).toHaveBeenCalledWith( file.originalPath, expect.any(Date), diff --git a/server/src/services/asset-media.service.ts b/server/src/services/asset-media.service.ts index 6b0d73b77b..de8c2bbc91 100644 --- a/server/src/services/asset-media.service.ts +++ b/server/src/services/asset-media.service.ts @@ -146,17 +146,79 @@ export class AssetMediaService extends BaseService { { userId: auth.user.id, livePhotoVideoId: dto.livePhotoVideoId }, ); } - const asset = await this.create(auth.user.id, dto, file, sidecarFile); + + const asset = await this.assetRepository.create({ + ownerId: auth.user.id, + libraryId: null, + + checksum: file.checksum, + checksumAlgorithm: ChecksumAlgorithm.sha1File, + originalPath: file.originalPath, + + fileCreatedAt: dto.fileCreatedAt, + fileModifiedAt: dto.fileModifiedAt, + localDateTime: dto.fileCreatedAt, + + type: mimeTypes.assetType(file.originalPath), + isFavorite: dto.isFavorite, + duration: dto.duration || null, + visibility: dto.visibility ?? AssetVisibility.Timeline, + livePhotoVideoId: dto.livePhotoVideoId, + originalFileName: dto.filename || file.originalName, + }); + + if (dto.metadata?.length) { + await this.assetRepository.upsertMetadata(asset.id, dto.metadata); + } + + if (sidecarFile) { + await this.assetRepository.upsertFile({ + assetId: asset.id, + path: sidecarFile.originalPath, + type: AssetFileType.Sidecar, + }); + await this.storageRepository.utimes(sidecarFile.originalPath, new Date(), new Date(dto.fileModifiedAt)); + } + await this.storageRepository.utimes(file.originalPath, new Date(), new Date(dto.fileModifiedAt)); + await this.assetRepository.upsertExif({ + exif: { assetId: asset.id, fileSizeInByte: file.size }, + lockedPropertiesBehavior: 'override', + }); + + await this.jobRepository.queue({ name: JobName.AssetExtractMetadata, data: { id: asset.id, source: 'upload' } }); if (auth.sharedLink) { await this.addToSharedLink(auth.sharedLink, asset.id); } - await this.userRepository.updateUsage(auth.user.id, file.size); + await this.eventRepository.emit('AssetCreate', { asset, file }); return { id: asset.id, status: AssetMediaStatus.CREATED }; } catch (error: any) { - return this.handleUploadError(error, auth, file, sidecarFile); + // clean up files + await this.jobRepository.queue({ + name: JobName.FileDelete, + data: { files: [file.originalPath, sidecarFile?.originalPath] }, + }); + + // handle duplicates with a success response + if (isAssetChecksumConstraint(error)) { + const duplicateId = await this.assetRepository.getUploadAssetIdByChecksum(auth.user.id, file.checksum); + if (!duplicateId) { + this.logger.error(`Error locating duplicate for checksum constraint`); + throw new InternalServerErrorException(); + } + + if (auth.sharedLink) { + await this.addToSharedLink(auth.sharedLink, duplicateId); + } + + this.logger.debug(`Duplicate asset upload rejected: existing asset ${duplicateId}`); + return { status: AssetMediaStatus.DUPLICATE, id: duplicateId }; + } + + this.logger.error(`Error uploading file ${error}`, error?.stack); + throw error; } } @@ -285,84 +347,6 @@ export class AssetMediaService extends BaseService { : this.sharedLinkRepository.addAssets(sharedLink.id, [assetId])); } - private async handleUploadError( - error: any, - auth: AuthDto, - file: UploadFile, - sidecarFile?: UploadFile, - ): Promise { - // clean up files - await this.jobRepository.queue({ - name: JobName.FileDelete, - data: { files: [file.originalPath, sidecarFile?.originalPath] }, - }); - - // handle duplicates with a success response - if (isAssetChecksumConstraint(error)) { - const duplicateId = await this.assetRepository.getUploadAssetIdByChecksum(auth.user.id, file.checksum); - if (!duplicateId) { - this.logger.error(`Error locating duplicate for checksum constraint`); - throw new InternalServerErrorException(); - } - - if (auth.sharedLink) { - await this.addToSharedLink(auth.sharedLink, duplicateId); - } - - this.logger.debug(`Duplicate asset upload rejected: existing asset ${duplicateId}`); - return { status: AssetMediaStatus.DUPLICATE, id: duplicateId }; - } - - this.logger.error(`Error uploading file ${error}`, error?.stack); - throw error; - } - - private async create(ownerId: string, dto: AssetMediaCreateDto, file: UploadFile, sidecarFile?: UploadFile) { - const asset = await this.assetRepository.create({ - ownerId, - libraryId: null, - - checksum: file.checksum, - checksumAlgorithm: ChecksumAlgorithm.sha1File, - originalPath: file.originalPath, - - fileCreatedAt: dto.fileCreatedAt, - fileModifiedAt: dto.fileModifiedAt, - localDateTime: dto.fileCreatedAt, - - type: mimeTypes.assetType(file.originalPath), - isFavorite: dto.isFavorite, - duration: dto.duration || null, - visibility: dto.visibility ?? AssetVisibility.Timeline, - livePhotoVideoId: dto.livePhotoVideoId, - originalFileName: dto.filename || file.originalName, - }); - - if (dto.metadata?.length) { - await this.assetRepository.upsertMetadata(asset.id, dto.metadata); - } - - if (sidecarFile) { - await this.assetRepository.upsertFile({ - assetId: asset.id, - path: sidecarFile.originalPath, - type: AssetFileType.Sidecar, - }); - await this.storageRepository.utimes(sidecarFile.originalPath, new Date(), new Date(dto.fileModifiedAt)); - } - await this.storageRepository.utimes(file.originalPath, new Date(), new Date(dto.fileModifiedAt)); - await this.assetRepository.upsertExif({ - exif: { assetId: asset.id, fileSizeInByte: file.size }, - lockedPropertiesBehavior: 'override', - }); - - await this.eventRepository.emit('AssetCreate', { asset }); - - await this.jobRepository.queue({ name: JobName.AssetExtractMetadata, data: { id: asset.id, source: 'upload' } }); - - return asset; - } - private requireQuota(auth: AuthDto, size: number) { if (auth.user.quotaSizeInBytes !== null && auth.user.quotaSizeInBytes < auth.user.quotaUsageInBytes + size) { throw new BadRequestException('Quota has been exceeded!'); diff --git a/server/src/services/plugin.service.ts b/server/src/services/plugin.service.ts index 62edf8438b..f9c4d0e2b8 100644 --- a/server/src/services/plugin.service.ts +++ b/server/src/services/plugin.service.ts @@ -2,10 +2,12 @@ import { BadRequestException, Injectable } from '@nestjs/common'; import { mapMethod, mapPlugin, + mapTemplate, PluginMethodResponseDto, PluginMethodSearchDto, PluginResponseDto, PluginSearchDto, + PluginTemplateResponseDto, } from 'src/dtos/plugin.dto'; import { BaseService } from 'src/services/base.service'; import { isMethodCompatible } from 'src/utils/workflow'; @@ -31,4 +33,9 @@ export class PluginService extends BaseService { .filter((method) => !dto.trigger || isMethodCompatible(method, dto.trigger)) .map((method) => mapMethod(method)); } + + async searchTemplates(): Promise { + const plugins = await this.pluginRepository.search(); + return plugins.flatMap((plugin) => plugin.templates.map((template) => mapTemplate(plugin, template))); + } } diff --git a/server/src/services/search.service.ts b/server/src/services/search.service.ts index c03f7bacaa..bd50ab3083 100644 --- a/server/src/services/search.service.ts +++ b/server/src/services/search.service.ts @@ -75,7 +75,7 @@ export class SearchService extends BaseService { const page = dto.page ?? 1; const size = dto.size || 250; - const userIds = await this.getUserIdsToSearch(auth); + const userIds = await this.getUserIdsToSearch(auth, dto.visibility); const { hasNextPage, items } = await this.searchRepository.searchMetadata( { page, size }, { @@ -103,7 +103,7 @@ export class SearchService extends BaseService { requireElevatedPermission(auth); } - const userIds = await this.getUserIdsToSearch(auth); + const userIds = await this.getUserIdsToSearch(auth, dto.visibility); const items = await this.searchRepository.searchRandom(dto.size || 250, { ...dto, userIds }); return items.map((item) => mapAsset(item, { auth })); } @@ -113,7 +113,7 @@ export class SearchService extends BaseService { requireElevatedPermission(auth); } - const userIds = await this.getUserIdsToSearch(auth); + const userIds = await this.getUserIdsToSearch(auth, dto.visibility); const items = await this.searchRepository.searchLargeAssets(dto.size || 250, { ...dto, userIds }); return items.map((item) => mapAsset(item, { auth })); } @@ -128,7 +128,7 @@ export class SearchService extends BaseService { throw new BadRequestException('Smart search is not enabled'); } - const userIds = this.getUserIdsToSearch(auth); + const userIds = this.getUserIdsToSearch(auth, dto.visibility); let embedding; if (dto.query) { const key = machineLearning.clip.modelName + dto.query + dto.language; @@ -202,7 +202,11 @@ export class SearchService extends BaseService { } } - private async getUserIdsToSearch(auth: AuthDto): Promise { + private async getUserIdsToSearch(auth: AuthDto, visibility?: AssetVisibility): Promise { + // Locked assets are personal. Never include partner IDs, regardless of A's elevated session. + if (visibility === AssetVisibility.Locked) { + return [auth.user.id]; + } const partnerIds = await getMyPartnerIds({ userId: auth.user.id, repository: this.partnerRepository, diff --git a/server/src/services/timeline.service.spec.ts b/server/src/services/timeline.service.spec.ts index 4f447f6c3d..ca668b6068 100644 --- a/server/src/services/timeline.service.spec.ts +++ b/server/src/services/timeline.service.spec.ts @@ -204,5 +204,16 @@ describe(TimelineService.name, () => { }), ).rejects.toThrow(BadRequestException); }); + + it('should throw an error if withPartners is true and visibility is locked', async () => { + await expect( + sut.getTimeBucket(authStub.adminWithElevatedPermission, { + timeBucket: 'bucket', + visibility: AssetVisibility.Locked, + withPartners: true, + userId: authStub.adminWithElevatedPermission.user.id, + }), + ).rejects.toThrow(BadRequestException); + }); }); }); diff --git a/server/src/services/timeline.service.ts b/server/src/services/timeline.service.ts index b840883fa9..b7ecbad9a9 100644 --- a/server/src/services/timeline.service.ts +++ b/server/src/services/timeline.service.ts @@ -66,14 +66,19 @@ export class TimelineService extends BaseService { await this.requireAccess({ auth, permission: Permission.TagRead, ids: [dto.tagId] }); } + if (auth.sharedLink && !auth.sharedLink.showExif) { + dto.withCoordinates = false; + } + if (dto.withPartners) { + const requestedLocked = dto.visibility === AssetVisibility.Locked; const requestedArchived = dto.visibility === AssetVisibility.Archive || dto.visibility === undefined; const requestedFavorite = dto.isFavorite === true || dto.isFavorite === false; const requestedTrash = dto.isTrashed === true; - if (requestedArchived || requestedFavorite || requestedTrash) { + if (requestedLocked || requestedArchived || requestedFavorite || requestedTrash) { throw new BadRequestException( - 'withPartners is only supported for non-archived, non-trashed, non-favorited assets', + 'withPartners is only supported for non-archived, non-trashed, non-favorited, non-locked assets', ); } } diff --git a/server/src/services/user.service.ts b/server/src/services/user.service.ts index 82ab90a590..27084eb3b4 100644 --- a/server/src/services/user.service.ts +++ b/server/src/services/user.service.ts @@ -3,7 +3,7 @@ import { Updateable } from 'kysely'; import { DateTime } from 'luxon'; import { SALT_ROUNDS } from 'src/constants'; import { StorageCore } from 'src/cores/storage.core'; -import { OnJob } from 'src/decorators'; +import { OnEvent, OnJob } from 'src/decorators'; import { AuthDto } from 'src/dtos/auth.dto'; import { LicenseKeyDto, LicenseResponseDto } from 'src/dtos/license.dto'; import { OnboardingDto, OnboardingResponseDto } from 'src/dtos/onboarding.dto'; @@ -11,6 +11,7 @@ import { UserPreferencesResponseDto, UserPreferencesUpdateDto, mapPreferences } import { CreateProfileImageResponseDto } from 'src/dtos/user-profile.dto'; import { UserAdminResponseDto, UserResponseDto, UserUpdateMeDto, mapUser, mapUserAdmin } from 'src/dtos/user.dto'; import { CacheControl, JobName, JobStatus, QueueName, StorageFolder, UserMetadataKey } from 'src/enum'; +import { ArgOf } from 'src/repositories/event.repository'; import { UserFindOptions } from 'src/repositories/user.repository'; import { UserTable } from 'src/schema/tables/user.table'; import { BaseService } from 'src/services/base.service'; @@ -230,6 +231,11 @@ export class UserService extends BaseService { }; } + @OnEvent({ name: 'AssetCreate' }) + async onAssetCreate({ asset, file }: ArgOf<'AssetCreate'>) { + await this.userRepository.updateUsage(asset.ownerId, file.size); + } + @OnJob({ name: JobName.UserSyncUsage, queue: QueueName.BackgroundTask }) async handleUserSyncUsage(): Promise { await this.userRepository.syncUsage(); diff --git a/server/src/services/workflow-execution.service.ts b/server/src/services/workflow-execution.service.ts index b2e106a251..0a5f025fc1 100644 --- a/server/src/services/workflow-execution.service.ts +++ b/server/src/services/workflow-execution.service.ts @@ -1,25 +1,31 @@ import { CurrentPlugin } from '@extism/extism'; -import { WorkflowChanges, WorkflowEventData, WorkflowEventPayload, WorkflowResponse } from '@immich/plugin-sdk'; +import { + WorkflowChanges, + WorkflowEventData, + WorkflowEventPayload, + WorkflowResponse, + WorkflowTrigger, +} from '@immich/plugin-sdk'; import { HttpException, UnauthorizedException } from '@nestjs/common'; -import _ from 'lodash'; import { join } from 'node:path'; -import { OnEvent, OnJob } from 'src/decorators'; -import { AlbumsAddAssetsDto } from 'src/dtos/album.dto'; +import { DummyValue, OnEvent, OnJob } from 'src/decorators'; +import { AlbumsAddAssetsDto, CreateAlbumDto, GetAlbumsDto } from 'src/dtos/album.dto'; import { BulkIdsDto } from 'src/dtos/asset-ids.response.dto'; import { AuthDto } from 'src/dtos/auth.dto'; import { PluginManifestDto } from 'src/dtos/plugin-manifest.dto'; import { BootstrapEventPriority, DatabaseLock, + ImmichEnvironment, ImmichWorker, JobName, JobStatus, QueueName, - WorkflowTrigger, WorkflowType, } from 'src/enum'; import { ArgOf } from 'src/repositories/event.repository'; import { AlbumService } from 'src/services/album.service'; +import { AssetService } from 'src/services/asset.service'; import { BaseService } from 'src/services/base.service'; import { JobOf } from 'src/types'; @@ -31,9 +37,11 @@ const dummy = () => { type ExecuteOptions = { read: (type: T) => Promise<{ authUserId: string; data: WorkflowEventData }>; - write: (changes: WorkflowChanges) => Promise; + write: (auth: AuthDto, changes: WorkflowChanges) => Promise; }; +type AssetTrigger = { userId: string; assetId: string; trigger: WorkflowTrigger }; + export class WorkflowExecutionService extends BaseService { private jwtSecret!: string; @@ -43,8 +51,8 @@ export class WorkflowExecutionService extends BaseService { // TODO avoid importing plugins in each worker // Can this use system metadata similar to geocoding? - const { resourcePaths, plugins } = this.configRepository.getEnv(); - await this.importFolder(resourcePaths.corePlugin, { force: true }); + const { environment, resourcePaths, plugins } = this.configRepository.getEnv(); + await this.importFolder(resourcePaths.corePlugin, { force: environment === ImmichEnvironment.Development }); if (plugins.external.allow && plugins.external.installFolder) { await this.importFolders(plugins.external.installFolder); @@ -58,21 +66,26 @@ export class WorkflowExecutionService extends BaseService { const albumService = BaseService.create(AlbumService, this); - const albumAddAssets = this.wrap<[id: string, dto: BulkIdsDto]>((authDto, args) => + const searchAlbums = this.wrap<[dto: GetAlbumsDto]>((authDto, args) => albumService.getAll(authDto, ...args)); + const createAlbum = this.wrap<[dto: CreateAlbumDto]>((authDto, args) => albumService.create(authDto, ...args)); + const addAssetsToAlbum = this.wrap<[id: string, dto: BulkIdsDto]>((authDto, args) => albumService.addAssets(authDto, ...args), ); - const addAssetsToAlbums = this.wrap<[dto: AlbumsAddAssetsDto]>((authDto, args) => albumService.addAssetsToAlbums(authDto, ...args), ); const functions = { - albumAddAssets, + searchAlbums, + createAlbum, + addAssetsToAlbum, addAssetsToAlbums, }; - const stubs = { - albumAddAssets: dummy, + const stubs: typeof functions = { + searchAlbums: dummy, + createAlbum: dummy, + addAssetsToAlbum: dummy, addAssetsToAlbums: dummy, }; @@ -166,7 +179,19 @@ export class WorkflowExecutionService extends BaseService { private async importFolder(folder: string, options?: { force?: boolean }) { try { const manifestPath = join(folder, 'manifest.json'); - const dto = await this.storageRepository.readJsonFile(manifestPath); + const bytes = await this.storageRepository.readFile(manifestPath); + const contents = bytes.toString('utf8'); + const sha256hash = this.cryptoRepository.hashSha256(contents) as Buffer; + + if (!options?.force) { + const match = await this.pluginRepository.getByHash(sha256hash); + if (match) { + this.logger.log(`Plugin up to date (name=${match.name}@${match.version}, hash=${sha256hash.toString('hex')}`); + return; + } + } + + const dto = JSON.parse(contents); const result = PluginManifestDto.schema.safeParse(dto); if (!result.success) { const issues = result.error.issues.map((issue) => ` - [${issue.path.join('.')}] ${issue.message}`).join('\n'); @@ -176,22 +201,21 @@ export class WorkflowExecutionService extends BaseService { const manifest = result.data; const existing = await this.pluginRepository.getByName(manifest.name); - if (existing && existing.version === manifest.version && options?.force !== true) { - return; - } - const wasmPath = `${folder}/${manifest.wasmPath}`; const wasmBytes = await this.storageRepository.readFile(wasmPath); const plugin = await this.pluginRepository.upsert( { + // NOTE: new properties here need to be added to the on conflict clause in the repository enabled: true, name: manifest.name, title: manifest.title, description: manifest.description, author: manifest.author, version: manifest.version, + templates: manifest.templates, wasmBytes, + sha256hash, }, manifest.methods, ); @@ -235,20 +259,36 @@ export class WorkflowExecutionService extends BaseService { } @OnEvent({ name: 'AssetCreate' }) - async onAssetCreate({ asset }: ArgOf<'AssetCreate'>) { - const dto = { ownerId: asset.ownerId, trigger: WorkflowTrigger.AssetCreate }; - const items = await this.workflowRepository.search(dto); + onAssetCreate({ asset: { ownerId: userId, id: assetId } }: ArgOf<'AssetCreate'>) { + return this.onAssetTrigger({ userId, assetId, trigger: WorkflowTrigger.AssetCreate }); + } + + @OnEvent({ name: 'AssetMetadataExtracted' }) + onAssetMetadataExtracted({ userId, assetId, source }: ArgOf<'AssetMetadataExtracted'>) { + // prevent loops + // TODO loop detection in job service directly + if (source === 'sidecar-write') { + return; + } + + return this.onAssetTrigger({ userId, assetId, trigger: WorkflowTrigger.AssetMetadataExtraction }); + } + + private async onAssetTrigger({ userId, assetId, trigger }: AssetTrigger) { + const items = await this.workflowRepository.search({ userId, trigger }); await this.jobRepository.queueAll( items.map((workflow) => ({ - name: JobName.WorkflowAssetCreate, - data: { workflowId: workflow.id, assetId: asset.id }, + name: JobName.WorkflowAssetTrigger, + data: { workflowId: workflow.id, assetId, trigger }, })), ); } - @OnJob({ name: JobName.WorkflowAssetCreate, queue: QueueName.Workflow }) - handleAssetCreate({ workflowId, assetId }: JobOf) { + @OnJob({ name: JobName.WorkflowAssetTrigger, queue: QueueName.Workflow }) + handleAssetTrigger({ workflowId, assetId }: JobOf) { return this.execute(workflowId, (type) => { + const assetService = BaseService.create(AssetService, this); + switch (type) { case WorkflowType.AssetV1: { return { @@ -259,19 +299,35 @@ export class WorkflowExecutionService extends BaseService { authUserId: asset.ownerId, }; }, - write: async (changes) => { - if (changes.asset) { - await this.assetRepository.update({ - id: assetId, - ..._.omitBy( - { - isFavorite: changes.asset?.isFavorite, - visibility: changes.asset?.visibility, - }, - _.isUndefined, - ), - }); + write: async (auth, changes) => { + const asset = changes.asset; + if (!asset) { + return; } + + await assetService.update(auth, assetId, { + isFavorite: asset.isFavorite, + visibility: asset.visibility, + dateTimeOriginal: asset.exifInfo?.dateTimeOriginal ?? undefined, + // TODO allow setting to null + longitude: asset.exifInfo?.longitude ?? undefined, + // TODO allow setting to null + latitude: asset.exifInfo?.latitude ?? undefined, + // TODO allow setting to null + description: asset.exifInfo?.description ?? undefined, + rating: asset.exifInfo?.rating, + + // TODO add to update dto + // make: asset.exifInfo?.make, + // model: asset.exifInfo?.model, + // city: asset.exifInfo?.city, + // state: asset.exifInfo?.state, + // country: asset.exifInfo?.country, + // lensModel: asset.exifInfo?.lensModel, + // fNumber: asset.exifInfo?.fNumber, + // fps: asset.exifInfo?.fps, + // iso: asset.exifInfo?.iso, + }); }, } satisfies ExecuteOptions; } @@ -289,7 +345,19 @@ export class WorkflowExecutionService extends BaseService { } // TODO infer from steps - const type = 'AssetV1' as T; + let type: T | undefined; + for (const targetType of Object.values(WorkflowType)) { + const missing = workflow.steps.some((step) => !step.types.includes(targetType)); + if (!missing) { + type = targetType as unknown as T; + break; + } + } + + if (!type) { + throw new Error('Unable to infer workflow event type from steps'); + } + const handler = getHandler(type); if (!handler) { this.logger.error(`Misconfigured workflow ${workflowId}: no handler for type ${type}`); @@ -325,10 +393,25 @@ export class WorkflowExecutionService extends BaseService { payload, ); if (result?.changes) { - await write(result.changes); + await write( + { + user: { + id: readResult.authUserId, + }, + session: { + id: DummyValue.UUID, + hasElevatedPermission: true, + }, + } as AuthDto, + result.changes, + ); ({ data } = await read(type)); } + if (result?.config) { + await this.workflowRepository.updateStep(step.id, { config: result.config }); + } + const shouldContinue = result?.workflow?.continue ?? true; if (!shouldContinue) { break; diff --git a/server/src/services/workflow.service.ts b/server/src/services/workflow.service.ts index 0a62a60887..850b4ac086 100644 --- a/server/src/services/workflow.service.ts +++ b/server/src/services/workflow.service.ts @@ -1,4 +1,4 @@ -import { WorkflowStepConfig } from '@immich/plugin-sdk'; +import { WorkflowStepConfig, WorkflowTrigger } from '@immich/plugin-sdk'; import { BadRequestException, Injectable } from '@nestjs/common'; import { AuthDto } from 'src/dtos/auth.dto'; import { @@ -11,7 +11,7 @@ import { WorkflowTriggerResponseDto, WorkflowUpdateDto, } from 'src/dtos/workflow.dto'; -import { Permission, WorkflowTrigger } from 'src/enum'; +import { Permission } from 'src/enum'; import { PluginMethodSearchResponse } from 'src/repositories/plugin.repository'; import { BaseService } from 'src/services/base.service'; import { getWorkflowTriggers, isMethodCompatible, resolveMethod } from 'src/utils/workflow'; @@ -23,7 +23,7 @@ export class WorkflowService extends BaseService { } async search(auth: AuthDto, dto: WorkflowSearchDto): Promise { - const workflows = await this.workflowRepository.search({ ...dto, ownerId: auth.user.id }); + const workflows = await this.workflowRepository.search({ ...dto, userId: auth.user.id }); return workflows.map((workflow) => mapWorkflow(workflow)); } diff --git a/server/src/types.ts b/server/src/types.ts index c7dc1f5e18..6b985af662 100644 --- a/server/src/types.ts +++ b/server/src/types.ts @@ -1,3 +1,4 @@ +import { WorkflowTrigger } from '@immich/plugin-sdk'; import { ShallowDehydrateObject } from 'kysely'; import { SystemConfig } from 'src/config'; import { VECTOR_EXTENSIONS } from 'src/constants'; @@ -29,7 +30,6 @@ import { TranscodeTarget, UserMetadataKey, VideoCodec, - WorkflowTrigger, WorkflowType, } from 'src/enum'; @@ -404,7 +404,7 @@ export type JobItem = | { name: JobName.Ocr; data: IEntityJob } // Workflow - | { name: JobName.WorkflowAssetCreate; data: { workflowId: string; assetId: string } } + | { name: JobName.WorkflowAssetTrigger; data: { workflowId: string; assetId: string } } // Editor | { name: JobName.AssetEditThumbnailGeneration; data: IEntityJob }; diff --git a/server/src/utils/misc.ts b/server/src/utils/misc.ts index 450563cf7e..37fff07fd9 100644 --- a/server/src/utils/misc.ts +++ b/server/src/utils/misc.ts @@ -1,16 +1,12 @@ import { INestApplication } from '@nestjs/common'; import { + ApiBodyOptions, DocumentBuilder, OpenAPIObject, SwaggerCustomOptions, SwaggerDocumentOptions, SwaggerModule, } from '@nestjs/swagger'; -import { - OperationObject, - ReferenceObject, - SchemaObject, -} from '@nestjs/swagger/dist/interfaces/open-api-spec.interface'; import _ from 'lodash'; import { cleanupOpenApiDoc } from 'nestjs-zod'; import { writeFileSync } from 'node:fs'; @@ -23,6 +19,11 @@ import { extraSyncModels } from 'src/dtos/sync.dto'; import { ApiCustomExtension, ImmichCookie, ImmichHeader, MetadataKey } from 'src/enum'; import { LoggingRepository } from 'src/repositories/logging.repository'; +type OperationObject = NonNullable; +type ReferenceOrSchemaObject = Extract['schema']; +type ReferenceObject = Extract; +type SchemaObject = Exclude; + export class ImmichStartupError extends Error {} export const isStartUpError = (error: unknown): error is ImmichStartupError => error instanceof ImmichStartupError; diff --git a/server/src/utils/workflow.spec.ts b/server/src/utils/workflow.spec.ts index 86bdd94e5b..5defe92d90 100644 --- a/server/src/utils/workflow.spec.ts +++ b/server/src/utils/workflow.spec.ts @@ -1,4 +1,5 @@ -import { WorkflowTrigger, WorkflowType } from 'src/enum'; +import { WorkflowTrigger } from '@immich/plugin-sdk'; +import { WorkflowType } from 'src/enum'; import { isMethodCompatible } from 'src/utils/workflow'; const tests: Array<{ trigger: WorkflowTrigger; types: WorkflowType[]; expected: boolean }> = [ diff --git a/server/src/utils/workflow.ts b/server/src/utils/workflow.ts index 5803fca342..5383db818e 100644 --- a/server/src/utils/workflow.ts +++ b/server/src/utils/workflow.ts @@ -1,9 +1,11 @@ -import { WorkflowTrigger, WorkflowType } from 'src/enum'; +import { WorkflowTrigger } from '@immich/plugin-sdk'; +import { WorkflowType } from 'src/enum'; import { PluginMethodSearchResponse } from 'src/repositories/plugin.repository'; export const triggerMap: Record = { [WorkflowTrigger.AssetCreate]: [WorkflowType.AssetV1], [WorkflowTrigger.PersonRecognized]: [WorkflowType.AssetPersonV1], + [WorkflowTrigger.AssetMetadataExtraction]: [WorkflowType.AssetV1], }; export const getWorkflowTriggers = () => @@ -50,8 +52,8 @@ export const resolveMethod = (methods: PluginMethodSearchResponse[], method: str return methods.find((method) => method.pluginName === pluginName && method.name === methodName); }; -export const asMethodString = (method: { pluginName: string; methodName: string }) => { - return `${method.pluginName}#${method.methodName}`; +export const asPluginKey = (method: { pluginName: string; name: string }) => { + return `${method.pluginName}#${method.name}`; }; const METHOD_REGEX = /^(?[^@#\s]+)(?:@(?[^#\s]*))?#(?[^@#\s]+)$/; diff --git a/server/test/fixtures/auth.stub.ts b/server/test/fixtures/auth.stub.ts index 85d52f14a1..88a2278898 100644 --- a/server/test/fixtures/auth.stub.ts +++ b/server/test/fixtures/auth.stub.ts @@ -41,6 +41,13 @@ export const authStub = { id: 'token-id', } as AuthSession, }), + adminWithElevatedPermission: Object.freeze({ + user: authUser.admin, + session: { + id: 'token-id-elevated', + hasElevatedPermission: true, + } as AuthSession, + }), adminSharedLink: Object.freeze({ user: authUser.admin, sharedLink: { diff --git a/server/test/medium/specs/services/asset-media.service.spec.ts b/server/test/medium/specs/services/asset-media.service.spec.ts index 1cfe8e9f84..e9395bfebf 100644 --- a/server/test/medium/specs/services/asset-media.service.spec.ts +++ b/server/test/medium/specs/services/asset-media.service.spec.ts @@ -43,9 +43,11 @@ describe(AssetService.name, () => { ctx.getMock(EventRepository).emit.mockResolvedValue(); ctx.getMock(JobRepository).queue.mockResolvedValue(); + const fileSizeInByte = 12_345; + const { user } = await ctx.newUser(); const { asset } = await ctx.newAsset({ ownerId: user.id }); - await ctx.newExif({ assetId: asset.id, fileSizeInByte: 12_345 }); + await ctx.newExif({ assetId: asset.id, fileSizeInByte }); const auth = factory.auth({ user: { id: user.id } }); await expect( @@ -56,7 +58,7 @@ describe(AssetService.name, () => { fileCreatedAt: new Date(), assetData: Buffer.from('some data'), }, - mediumFactory.uploadFile(), + mediumFactory.uploadFile({ size: fileSizeInByte }), ), ).resolves.toEqual({ id: expect.any(String), @@ -65,6 +67,7 @@ describe(AssetService.name, () => { expect(ctx.getMock(EventRepository).emit).toHaveBeenCalledWith('AssetCreate', { asset: expect.objectContaining({}), + file: expect.objectContaining({ size: fileSizeInByte }), }); }); diff --git a/server/test/medium/specs/services/plugin.service.spec.ts b/server/test/medium/specs/services/plugin.service.spec.ts index 88254db17e..de4882a575 100644 --- a/server/test/medium/specs/services/plugin.service.spec.ts +++ b/server/test/medium/specs/services/plugin.service.spec.ts @@ -11,6 +11,7 @@ import { getKyselyDB } from 'test/utils'; let defaultDatabase: Kysely; const wasmBytes = Buffer.from('some-wasm-binary-data'); +const sha256hash = Buffer.from('some-manifest-hash'); const setup = (db?: Kysely) => { return newMediumService(PluginService, { @@ -46,7 +47,9 @@ describe(PluginService.name, () => { description: 'A test plugin', author: 'Test Author', version: '1.0.0', + templates: [], wasmBytes, + sha256hash, }, [], ); @@ -75,7 +78,9 @@ describe(PluginService.name, () => { description: 'A plugin with multiple methods', author: 'Test Author', version: '1.0.0', + templates: [], wasmBytes, + sha256hash, }, [ { @@ -130,7 +135,9 @@ describe(PluginService.name, () => { description: 'First plugin', author: 'Author 1', version: '1.0.0', + templates: [], wasmBytes, + sha256hash, }, [ { @@ -150,7 +157,9 @@ describe(PluginService.name, () => { description: 'Second plugin', author: 'Author 2', version: '2.0.0', + templates: [], wasmBytes, + sha256hash, }, [ { @@ -183,7 +192,9 @@ describe(PluginService.name, () => { description: 'Plugin with multiple methods', author: 'Test Author', version: '1.0.0', + templates: [], wasmBytes, + sha256hash, }, [ { @@ -242,6 +253,8 @@ describe(PluginService.name, () => { description: 'A single plugin', author: 'Test Author', version: '1.0.0', + templates: [], + sha256hash, wasmBytes, }, [ diff --git a/server/test/medium/specs/services/timeline.service.spec.ts b/server/test/medium/specs/services/timeline.service.spec.ts index 092a523010..d7013b84be 100644 --- a/server/test/medium/specs/services/timeline.service.spec.ts +++ b/server/test/medium/specs/services/timeline.service.spec.ts @@ -1,10 +1,11 @@ import { BadRequestException } from '@nestjs/common'; import { Kysely } from 'kysely'; -import { AssetVisibility } from 'src/enum'; +import { AssetVisibility, SharedLinkType } from 'src/enum'; import { AccessRepository } from 'src/repositories/access.repository'; import { AssetRepository } from 'src/repositories/asset.repository'; import { LoggingRepository } from 'src/repositories/logging.repository'; import { PartnerRepository } from 'src/repositories/partner.repository'; +import { SharedLinkRepository } from 'src/repositories/shared-link.repository'; import { DB } from 'src/schema'; import { TimelineService } from 'src/services/timeline.service'; import { newMediumService } from 'test/medium.factory'; @@ -50,13 +51,13 @@ describe(TimelineService.name, () => { const response1 = sut.getTimeBuckets(auth, { withPartners: true, visibility: AssetVisibility.Archive }); await expect(response1).rejects.toBeInstanceOf(BadRequestException); await expect(response1).rejects.toThrow( - 'withPartners is only supported for non-archived, non-trashed, non-favorited assets', + 'withPartners is only supported for non-archived, non-trashed, non-favorited, non-locked assets', ); const response2 = sut.getTimeBuckets(auth, { withPartners: true }); await expect(response2).rejects.toBeInstanceOf(BadRequestException); await expect(response2).rejects.toThrow( - 'withPartners is only supported for non-archived, non-trashed, non-favorited assets', + 'withPartners is only supported for non-archived, non-trashed, non-favorited, non-locked assets', ); }); @@ -66,13 +67,13 @@ describe(TimelineService.name, () => { const response1 = sut.getTimeBuckets(auth, { withPartners: true, isFavorite: false }); await expect(response1).rejects.toBeInstanceOf(BadRequestException); await expect(response1).rejects.toThrow( - 'withPartners is only supported for non-archived, non-trashed, non-favorited assets', + 'withPartners is only supported for non-archived, non-trashed, non-favorited, non-locked assets', ); const response2 = sut.getTimeBuckets(auth, { withPartners: true, isFavorite: true }); await expect(response2).rejects.toBeInstanceOf(BadRequestException); await expect(response2).rejects.toThrow( - 'withPartners is only supported for non-archived, non-trashed, non-favorited assets', + 'withPartners is only supported for non-archived, non-trashed, non-favorited, non-locked assets', ); }); @@ -82,7 +83,7 @@ describe(TimelineService.name, () => { const response = sut.getTimeBuckets(auth, { withPartners: true, isTrashed: true }); await expect(response).rejects.toBeInstanceOf(BadRequestException); await expect(response).rejects.toThrow( - 'withPartners is only supported for non-archived, non-trashed, non-favorited assets', + 'withPartners is only supported for non-archived, non-trashed, non-favorited, non-locked assets', ); }); @@ -207,4 +208,32 @@ describe(TimelineService.name, () => { expect(response2).toEqual(expect.objectContaining({ id: [asset2.id, asset1.id], isFavorite: [true, false] })); }); }); + + it('should strip geodata metadata if shared link without exif', async () => { + const { sut, ctx } = setup(); + const sharedLinkRepo = ctx.get(SharedLinkRepository); + + const { user } = await ctx.newUser(); + const { asset } = await ctx.newAsset({ + ownerId: user.id, + localDateTime: new Date('1970-02-12'), + deletedAt: new Date(), + }); + const { album } = await ctx.newAlbum({ ownerId: user.id }); + await ctx.newAlbumAsset({ albumId: album.id, assetId: asset.id }); + + const { id: sharedLinkId } = await sharedLinkRepo.create({ + allowUpload: false, + key: Buffer.from('123'), + type: SharedLinkType.Album, + userId: user.id, + albumId: album.id, + }); + + await ctx.newExif({ assetId: asset.id, city: 'Austin', country: 'USA' }); + const auth = factory.auth({ sharedLink: { id: sharedLinkId, showExif: false } }); + const rawResponse = await sut.getTimeBucket(auth, { albumId: album.id, timeBucket: '1970-02-01', isTrashed: true }); + const response = JSON.parse(rawResponse); + expect(response).not.toEqual(expect.objectContaining({ city: expect.any(Array), country: expect.any(Array) })); + }); }); diff --git a/server/test/medium/specs/services/workflow.service.spec.ts b/server/test/medium/specs/services/workflow.service.spec.ts index b16b359b85..b4b52be98c 100644 --- a/server/test/medium/specs/services/workflow.service.spec.ts +++ b/server/test/medium/specs/services/workflow.service.spec.ts @@ -1,5 +1,6 @@ +import { WorkflowTrigger } from '@immich/plugin-sdk'; import { Kysely } from 'kysely'; -import { WorkflowTrigger, WorkflowType } from 'src/enum'; +import { WorkflowType } from 'src/enum'; import { AccessRepository } from 'src/repositories/access.repository'; import { LoggingRepository } from 'src/repositories/logging.repository'; import { PluginRepository } from 'src/repositories/plugin.repository'; @@ -21,6 +22,7 @@ const setup = (db?: Kysely) => { }; const wasmBytes = Buffer.from('random-wasm-bytes'); +const sha256hash = Buffer.from('some-manifest-hash'); beforeAll(async () => { defaultDatabase = await getKyselyDB(); @@ -41,7 +43,9 @@ describe(WorkflowService.name, () => { description: 'A test core plugin for workflow tests', author: 'Test Author', version: '1.0.0', + templates: [], wasmBytes, + sha256hash, }, [ { diff --git a/server/test/medium/specs/workflow/workflow-core-plugin.spec.ts b/server/test/medium/specs/workflow/workflow-core-plugin.spec.ts index 99f6c67d5c..2bb9de6af1 100644 --- a/server/test/medium/specs/workflow/workflow-core-plugin.spec.ts +++ b/server/test/medium/specs/workflow/workflow-core-plugin.spec.ts @@ -1,8 +1,8 @@ -import { WorkflowStepConfig } from '@immich/plugin-sdk'; +import { WorkflowStepConfig, WorkflowTrigger } from '@immich/plugin-sdk'; import { Kysely } from 'kysely'; import { readFileSync } from 'node:fs'; import { PluginManifestDto } from 'src/dtos/plugin-manifest.dto'; -import { AssetVisibility, LogLevel, WorkflowTrigger } from 'src/enum'; +import { AssetVisibility, LogLevel } from 'src/enum'; import { AccessRepository } from 'src/repositories/access.repository'; import { AlbumRepository } from 'src/repositories/album.repository'; import { AssetRepository } from 'src/repositories/asset.repository'; @@ -12,6 +12,7 @@ import { DatabaseRepository } from 'src/repositories/database.repository'; import { LoggingRepository } from 'src/repositories/logging.repository'; import { PluginRepository } from 'src/repositories/plugin.repository'; import { StorageRepository } from 'src/repositories/storage.repository'; +import { UserRepository } from 'src/repositories/user.repository'; import { WorkflowRepository } from 'src/repositories/workflow.repository'; import { DB } from 'src/schema'; import { WorkflowExecutionService } from 'src/services/workflow-execution.service'; @@ -33,8 +34,9 @@ class WorkflowTestContext extends MediumTestContext { CryptoRepository, DatabaseRepository, LoggingRepository, - StorageRepository, PluginRepository, + StorageRepository, + UserRepository, WorkflowRepository, ], mock: [ConfigRepository], @@ -137,7 +139,7 @@ describe('core plugin', () => { steps: [{ method: 'immich-plugin-core#assetArchive' }], }); - await expect(ctx.sut.handleAssetCreate({ workflowId: workflow.id, assetId: asset.id })).resolves.toBeUndefined(); + await expect(ctx.sut.handleAssetTrigger({ workflowId: workflow.id, assetId: asset.id })).resolves.toBeUndefined(); await expect(ctx.get(AssetRepository).getById(asset.id)).resolves.toMatchObject({ visibility: AssetVisibility.Archive, @@ -154,7 +156,7 @@ describe('core plugin', () => { steps: [{ method: 'immich-plugin-core#assetArchive', config: { inverse: true } }], }); - await expect(ctx.sut.handleAssetCreate({ workflowId: workflow.id, assetId: asset.id })).resolves.toBeUndefined(); + await expect(ctx.sut.handleAssetTrigger({ workflowId: workflow.id, assetId: asset.id })).resolves.toBeUndefined(); await expect(ctx.get(AssetRepository).getById(asset.id)).resolves.toMatchObject({ visibility: AssetVisibility.Timeline, @@ -173,7 +175,7 @@ describe('core plugin', () => { steps: [{ method: 'immich-plugin-core#assetLock' }], }); - await expect(ctx.sut.handleAssetCreate({ workflowId: workflow.id, assetId: asset.id })).resolves.toBeUndefined(); + await expect(ctx.sut.handleAssetTrigger({ workflowId: workflow.id, assetId: asset.id })).resolves.toBeUndefined(); await expect(ctx.get(AssetRepository).getById(asset.id)).resolves.toMatchObject({ visibility: AssetVisibility.Locked, @@ -190,7 +192,7 @@ describe('core plugin', () => { steps: [{ method: 'immich-plugin-core#assetLock', config: { inverse: true } }], }); - await expect(ctx.sut.handleAssetCreate({ workflowId: workflow.id, assetId: asset.id })).resolves.toBeUndefined(); + await expect(ctx.sut.handleAssetTrigger({ workflowId: workflow.id, assetId: asset.id })).resolves.toBeUndefined(); await expect(ctx.get(AssetRepository).getById(asset.id)).resolves.toMatchObject({ visibility: AssetVisibility.Timeline, @@ -209,7 +211,7 @@ describe('core plugin', () => { steps: [{ method: 'immich-plugin-core#assetFavorite' }], }); - await expect(ctx.sut.handleAssetCreate({ workflowId: workflow.id, assetId: asset.id })).resolves.toBeUndefined(); + await expect(ctx.sut.handleAssetTrigger({ workflowId: workflow.id, assetId: asset.id })).resolves.toBeUndefined(); await expect(ctx.get(AssetRepository).getById(asset.id)).resolves.toMatchObject({ isFavorite: true }); }); @@ -224,13 +226,59 @@ describe('core plugin', () => { steps: [{ method: 'immich-plugin-core#assetFavorite', config: { inverse: true } }], }); - await expect(ctx.sut.handleAssetCreate({ workflowId: workflow.id, assetId: asset.id })).resolves.toBeUndefined(); + await expect(ctx.sut.handleAssetTrigger({ workflowId: workflow.id, assetId: asset.id })).resolves.toBeUndefined(); await expect(ctx.get(AssetRepository).getById(asset.id)).resolves.toMatchObject({ isFavorite: false }); }); }); describe('assetAddToAlbums', () => { + it('should create an album by name', async () => { + const { user } = await ctx.newUser(); + const { asset } = await ctx.newAsset({ ownerId: user.id, isFavorite: true }); + + const workflow = await createWorkflow({ + ownerId: user.id, + trigger: WorkflowTrigger.AssetCreate, + steps: [{ method: 'immich-plugin-core#assetAddToAlbums', config: { albumIds: [], albumName: 'Screenshots' } }], + }); + + await expect(ctx.sut.handleAssetTrigger({ workflowId: workflow.id, assetId: asset.id })).resolves.toBeUndefined(); + + const albums = await ctx.get(AlbumRepository).getAll(user.id); + expect(albums).toHaveLength(1); + + const album = albums[0]!; + expect(album.albumName).toEqual('Screenshots'); + + const updated = await ctx.get(WorkflowRepository).get(workflow.id); + expect(updated?.steps[0].config).toEqual({ albumIds: [album.id], albumName: 'Screenshots' }); + + await expect(ctx.get(AlbumRepository).getAssetIds(album.id, [asset.id])).resolves.toContain(asset.id); + }); + + it('should not use the name when there is an albumId', async () => { + const { user } = await ctx.newUser(); + const { asset } = await ctx.newAsset({ ownerId: user.id, isFavorite: true }); + const { album } = await ctx.newAlbum({ ownerId: user.id }); + + const workflow = await createWorkflow({ + ownerId: user.id, + trigger: WorkflowTrigger.AssetCreate, + steps: [ + { method: 'immich-plugin-core#assetAddToAlbums', config: { albumIds: [album.id], albumName: 'Screenshots' } }, + ], + }); + + const albums = await ctx.get(AlbumRepository).getAll(user.id); + expect(albums).toHaveLength(1); + expect(albums[0].albumName).toEqual(album.albumName); + + await expect(ctx.sut.handleAssetTrigger({ workflowId: workflow.id, assetId: asset.id })).resolves.toBeUndefined(); + + await expect(ctx.get(AlbumRepository).getAssetIds(album.id, [asset.id])).resolves.toContain(asset.id); + }); + it('should add an asset to an album', async () => { const { user } = await ctx.newUser(); const { asset } = await ctx.newAsset({ ownerId: user.id, isFavorite: true }); @@ -242,7 +290,7 @@ describe('core plugin', () => { steps: [{ method: 'immich-plugin-core#assetAddToAlbums', config: { albumIds: [album.id] } }], }); - await expect(ctx.sut.handleAssetCreate({ workflowId: workflow.id, assetId: asset.id })).resolves.toBeUndefined(); + await expect(ctx.sut.handleAssetTrigger({ workflowId: workflow.id, assetId: asset.id })).resolves.toBeUndefined(); await expect(ctx.get(AlbumRepository).getAssetIds(album.id, [asset.id])).resolves.toContain(asset.id); }); @@ -261,7 +309,7 @@ describe('core plugin', () => { steps: [{ method: 'immich-plugin-core#assetAddToAlbums', config: { albumIds: [album1.id, album2.id] } }], }); - await expect(ctx.sut.handleAssetCreate({ workflowId: workflow.id, assetId: asset.id })).resolves.toBeUndefined(); + await expect(ctx.sut.handleAssetTrigger({ workflowId: workflow.id, assetId: asset.id })).resolves.toBeUndefined(); await expect(ctx.get(AlbumRepository).getAssetIds(album1.id, [asset.id])).resolves.toContain(asset.id); await expect(ctx.get(AlbumRepository).getAssetIds(album2.id, [asset.id])).resolves.toContain(asset.id); @@ -279,7 +327,7 @@ describe('core plugin', () => { steps: [{ method: 'immich-plugin-core#assetAddToAlbums', config: { albumIds: [album.id] } }], }); - await expect(ctx.sut.handleAssetCreate({ workflowId: workflow.id, assetId: asset.id })).resolves.toBeTruthy(); + await expect(ctx.sut.handleAssetTrigger({ workflowId: workflow.id, assetId: asset.id })).resolves.toBeTruthy(); await expect(ctx.get(AlbumRepository).getAssetIds(album.id, [asset.id])).resolves.not.toContain(asset.id); }); diff --git a/web/package.json b/web/package.json index dd2173c9d2..56b24e0dcb 100644 --- a/web/package.json +++ b/web/package.json @@ -28,7 +28,7 @@ "@futo-org/backups-orchestrator-ui": "0.1.73", "@immich/justified-layout-wasm": "^0.4.3", "@immich/sdk": "workspace:*", - "@immich/ui": "^0.77.0", + "@immich/ui": "^0.79.2", "@mapbox/mapbox-gl-rtl-text": "0.4.0", "@mdi/js": "^7.4.47", "@noble/hashes": "^2.2.0", @@ -77,7 +77,7 @@ "@sveltejs/adapter-static": "^3.0.8", "@sveltejs/enhanced-img": "^0.10.4", "@sveltejs/kit": "^2.56.1", - "@sveltejs/vite-plugin-svelte": "7.0.0", + "@sveltejs/vite-plugin-svelte": "7.1.2", "@tailwindcss/vite": "^4.2.4", "@testing-library/jest-dom": "^6.4.2", "@testing-library/svelte": "^5.2.8", diff --git a/web/src/app.css b/web/src/app.css index 07226be41f..4435b255d2 100644 --- a/web/src/app.css +++ b/web/src/app.css @@ -34,7 +34,7 @@ } @utility immich-form-input { - @apply bg-gray-100 ring-1 ring-gray-200 transition outline-none focus-within:ring-1 disabled:cursor-not-allowed dark:bg-gray-800 dark:ring-neutral-900 flex w-full items-center rounded-lg disabled:bg-gray-300 disabled:text-dark dark:disabled:bg-gray-900 dark:disabled:text-gray-200 flex-1 py-2.5 text-base pl-4 pr-4; + @apply bg-gray-100 ring-1 ring-gray-200 transition outline-none focus-within:ring-primary focus-within:ring-1 disabled:cursor-not-allowed dark:bg-gray-800 dark:ring-neutral-900 dark:focus-within:ring-primary flex w-full items-center rounded-lg disabled:bg-gray-300 disabled:text-dark dark:disabled:bg-gray-900 dark:disabled:text-gray-200 flex-1 py-2.5 text-base pl-4 pr-4; } @utility immich-form-label { diff --git a/web/src/lib/commands.ts b/web/src/lib/commands.ts index 59c25179f2..ddc90a4a42 100644 --- a/web/src/lib/commands.ts +++ b/web/src/lib/commands.ts @@ -1,17 +1,35 @@ import { defaultProvider, screencastManager, themeManager, ThemePreference, type ActionItem } from '@immich/ui'; import { mdiAccountMultipleOutline, + mdiAccountOutline, + mdiArchiveArrowDownOutline, mdiBookshelf, mdiCog, + mdiContentDuplicate, + mdiCrosshairsGps, + mdiFolderOutline, + mdiHeartOutline, + mdiImageAlbum, + mdiImageMultipleOutline, + mdiImageSizeSelectLarge, mdiKeyboard, + mdiLink, + mdiLockOutline, + mdiMagnify, + mdiMapOutline, mdiServer, + mdiStateMachine, mdiSync, + mdiTagMultipleOutline, mdiThemeLightDark, + mdiToolboxOutline, + mdiTrashCanOutline, } from '@mdi/js'; import type { MessageFormatter } from 'svelte-i18n'; import { goto } from '$app/navigation'; import { page } from '$app/state'; import { authManager } from '$lib/managers/auth-manager.svelte'; +import { featureFlagsManager } from '$lib/managers/feature-flags-manager.svelte'; import { Route } from '$lib/route'; import { copyToClipboard } from '$lib/utils'; @@ -49,7 +67,133 @@ export const getPagesProvider = ($t: MessageFormatter) => { }, ].map((route) => ({ ...route, $if: () => authManager.authenticated && authManager.user.isAdmin })); - return defaultProvider({ name: $t('page'), actions: adminPages }); + const userPages: ActionItem[] = [ + { + title: $t('photos'), + icon: mdiImageMultipleOutline, + onAction: () => goto(Route.photos()), + }, + { + title: $t('explore'), + icon: mdiMagnify, + onAction: () => goto(Route.explore()), + $if: () => authManager.authenticated && featureFlagsManager.value.search, + }, + + { + title: $t('map'), + icon: mdiMapOutline, + onAction: () => goto(Route.map()), + $if: () => authManager.authenticated && featureFlagsManager.value.map, + }, + { + title: $t('people'), + description: $t('people_feature_description'), + icon: mdiAccountOutline, + onAction: () => goto(Route.people()), + $if: () => authManager.authenticated && authManager.preferences.people.enabled, + }, + { + title: $t('shared_links'), + icon: mdiLink, + onAction: () => goto(Route.sharedLinks()), + $if: () => authManager.authenticated && authManager.preferences.sharedLinks.enabled, + }, + { + title: $t('recently_added'), + icon: mdiMagnify, + onAction: () => goto(Route.recentlyAdded()), + $if: () => authManager.authenticated, + }, + { + title: $t('sharing'), + icon: mdiAccountMultipleOutline, + onAction: () => goto(Route.sharing()), + $if: () => authManager.authenticated, + }, + { + title: $t('favorites'), + icon: mdiHeartOutline, + onAction: () => goto(Route.favorites()), + $if: () => authManager.authenticated, + }, + { + title: $t('albums'), + description: $t('albums_feature_description'), + icon: mdiImageAlbum, + onAction: () => goto(Route.albums()), + $if: () => authManager.authenticated, + }, + { + title: $t('tags'), + description: $t('tag_feature_description'), + icon: mdiTagMultipleOutline, + onAction: () => goto(Route.tags()), + $if: () => authManager.authenticated && authManager.preferences.tags.enabled, + }, + { + title: $t('folders'), + description: $t('folders_feature_description'), + icon: mdiFolderOutline, + onAction: () => goto(Route.folders()), + $if: () => authManager.authenticated && authManager.preferences.folders.enabled, + }, + { + title: $t('utilities'), + icon: mdiToolboxOutline, + onAction: () => goto(Route.utilities()), + $if: () => authManager.authenticated, + }, + { + title: $t('archive'), + icon: mdiArchiveArrowDownOutline, + onAction: () => goto(Route.archive()), + $if: () => authManager.authenticated, + }, + { + title: $t('locked_folder'), + icon: mdiLockOutline, + onAction: () => goto(Route.locked()), + $if: () => authManager.authenticated, + }, + { + title: $t('trash'), + icon: mdiTrashCanOutline, + onAction: () => goto(Route.trash()), + $if: () => authManager.authenticated && featureFlagsManager.value.trash, + }, + { + title: $t('admin.user_settings'), + icon: mdiCog, + onAction: () => goto(Route.userSettings()), + $if: () => authManager.authenticated, + }, + ].map((route) => ({ $if: () => authManager.authenticated, ...route })); + + const utilityPages: ActionItem[] = [ + { + title: $t('review_duplicates'), + icon: mdiContentDuplicate, + onAction: () => goto(Route.duplicatesUtility()), + }, + { + title: $t('review_large_files'), + icon: mdiImageSizeSelectLarge, + onAction: () => goto(Route.largeFileUtility()), + }, + { + title: $t('manage_geolocation'), + icon: mdiCrosshairsGps, + onAction: () => goto(Route.geolocationUtility()), + }, + { + title: $t('workflows'), + icon: mdiStateMachine, + onAction: () => goto(Route.workflows()), + }, + ].map((route) => ({ ...route, $if: () => authManager.authenticated })); + + return defaultProvider({ name: $t('page'), actions: [...userPages, ...utilityPages, ...adminPages] }); }; const getMyImmichLink = () => { diff --git a/web/src/lib/components/AdaptiveImage.svelte b/web/src/lib/components/AdaptiveImage.svelte index 4f3522887c..04136c721c 100644 --- a/web/src/lib/components/AdaptiveImage.svelte +++ b/web/src/lib/components/AdaptiveImage.svelte @@ -149,29 +149,35 @@ return { width: 1, height: 1 }; }); - const { insetInlineStart, top, rasterWidth, rasterHeight, rasterScale } = $derived.by(() => { - const scaleFn = objectFit === 'cover' ? scaleToCover : scaleToFit; - const { width, height } = scaleFn(imageDimensions, container); - if (maxRasterPixels === 0) { + const { insetInlineStart, top, displayWidth, displayHeight, rasterWidth, rasterHeight, rasterScale } = $derived.by( + () => { + const scaleFn = objectFit === 'cover' ? scaleToCover : scaleToFit; + const { width, height } = scaleFn(imageDimensions, container); + if (maxRasterPixels === 0) { + return { + insetInlineStart: (container.width - width) / 2 + 'px', + top: (container.height - height) / 2 + 'px', + displayWidth: width + 'px', + displayHeight: height + 'px', + rasterWidth: width + 'px', + rasterHeight: height + 'px', + rasterScale: 1, + }; + } + const nativeRatio = imageDimensions.width / width; + const budgetRatio = Math.sqrt(maxRasterPixels / Math.max(width * height, 1)); + const rasterRatio = Math.max(1, Math.min(nativeRatio, budgetRatio)); return { insetInlineStart: (container.width - width) / 2 + 'px', top: (container.height - height) / 2 + 'px', - rasterWidth: width + 'px', - rasterHeight: height + 'px', - rasterScale: 1, + displayWidth: width + 'px', + displayHeight: height + 'px', + rasterWidth: width * rasterRatio + 'px', + rasterHeight: height * rasterRatio + 'px', + rasterScale: 1 / rasterRatio, }; - } - const nativeRatio = imageDimensions.width / width; - const budgetRatio = Math.sqrt(maxRasterPixels / Math.max(width * height, 1)); - const rasterRatio = Math.max(1, Math.min(nativeRatio, budgetRatio)); - return { - insetInlineStart: (container.width - width) / 2 + 'px', - top: (container.height - height) / 2 + 'px', - rasterWidth: width * rasterRatio + 'px', - rasterHeight: height * rasterRatio + 'px', - rasterScale: 1 / rasterRatio, - }; - }); + }, + ); const { status } = $derived(adaptiveImageLoader); const alt = $derived(status.urls.preview ? $getAltText(toTimelineAsset(asset)) : ''); @@ -216,69 +222,78 @@ {@render backdrop?.()}
0 ? 'transform' : undefined} + style:width={displayWidth} + style:height={displayHeight} > - {#if show.alphaBackground} - - {/if} - - {#if show.thumbhash} - {#if asset.thumbhash} - - - {:else if show.spinner} - +
0 ? 'transform' : undefined} + > + {#if show.alphaBackground} + {/if} - {/if} - {#if show.thumbnail} - - {/if} + {#if show.thumbhash} + {#if asset.thumbhash} + + + {:else if show.spinner} + + {/if} + {/if} - {#if show.brokenAsset} - - {/if} + {#if show.thumbnail} + + {/if} - {#if show.preview} - - {/if} + {#if show.brokenAsset} + + {/if} - {#if show.original} - + {#if show.preview} + + {/if} + + {#if show.original} + + {/if} +
+ + {#if overlays} +
+ {@render overlays()} +
{/if}
diff --git a/web/src/lib/components/ImageLayer.svelte b/web/src/lib/components/ImageLayer.svelte index 1ac854259d..40bf7d6965 100644 --- a/web/src/lib/components/ImageLayer.svelte +++ b/web/src/lib/components/ImageLayer.svelte @@ -1,7 +1,6 @@ {#key adaptiveImageLoader} @@ -42,6 +30,5 @@ draggable={false} data-testid={quality} /> - {@render overlays?.()} {/key} diff --git a/web/src/lib/components/SchemaConfiguration.svelte b/web/src/lib/components/SchemaConfiguration.svelte index e48f46a402..2cc0b68089 100644 --- a/web/src/lib/components/SchemaConfiguration.svelte +++ b/web/src/lib/components/SchemaConfiguration.svelte @@ -64,7 +64,7 @@ {/each} -{:else if schema.uiHint === 'albumId'} +{:else if schema.uiHint === 'AlbumId'} {:else if schema.enum && schema.array} diff --git a/web/src/lib/components/album-page/AlbumThumbnail.svelte b/web/src/lib/components/album-page/AlbumThumbnail.svelte index 037bb78ab9..e585809dec 100644 --- a/web/src/lib/components/album-page/AlbumThumbnail.svelte +++ b/web/src/lib/components/album-page/AlbumThumbnail.svelte @@ -2,7 +2,7 @@ import AlbumCover from '$lib/components/album-page/AlbumCover.svelte'; import { authManager } from '$lib/managers/auth-manager.svelte'; import { getAlbumInfo } from '@immich/sdk'; - import { IconButton, LoadingSpinner } from '@immich/ui'; + import { IconButton, Text, LoadingSpinner } from '@immich/ui'; import { mdiTrashCanOutline } from '@mdi/js'; import { t } from 'svelte-i18n'; @@ -46,5 +46,22 @@ /> + {:catch} +
+
+ {$t('unknown')} + {albumId} +
+
+ +
+
{/await} diff --git a/web/src/lib/components/album-page/AlbumViewer.svelte b/web/src/lib/components/album-page/AlbumViewer.svelte index 85a032067f..4e7d6bce1a 100644 --- a/web/src/lib/components/album-page/AlbumViewer.svelte +++ b/web/src/lib/components/album-page/AlbumViewer.svelte @@ -103,7 +103,7 @@ {/if} {:else} - + {#snippet leading()} diff --git a/web/src/lib/components/asset-viewer/ActivityViewer.svelte b/web/src/lib/components/asset-viewer/ActivityViewer.svelte index cd952fe08b..803495c8bb 100644 --- a/web/src/lib/components/asset-viewer/ActivityViewer.svelte +++ b/web/src/lib/components/asset-viewer/ActivityViewer.svelte @@ -128,7 +128,7 @@ {#if innerHeight}
{#each activityManager.activities as reaction, index (reaction.id)} diff --git a/web/src/lib/components/assets/thumbnail/Thumbnail.svelte b/web/src/lib/components/assets/thumbnail/Thumbnail.svelte index a087aaf809..aef52d0cfd 100644 --- a/web/src/lib/components/assets/thumbnail/Thumbnail.svelte +++ b/web/src/lib/components/assets/thumbnail/Thumbnail.svelte @@ -205,11 +205,7 @@
{:else} -
+
{#each showPeople as person (person.id)} {#if !editedFace.person || person.id !== editedFace.person.id}
diff --git a/web/src/lib/components/pages/SharedLinkPage.svelte b/web/src/lib/components/pages/SharedLinkPage.svelte index 40cf0a193f..8cb4aadd7b 100644 --- a/web/src/lib/components/pages/SharedLinkPage.svelte +++ b/web/src/lib/components/pages/SharedLinkPage.svelte @@ -91,7 +91,7 @@
- + {#snippet leading()} diff --git a/web/src/lib/components/share-page/IndividualSharedViewer.svelte b/web/src/lib/components/share-page/IndividualSharedViewer.svelte index 86b716da40..936ccb0f41 100644 --- a/web/src/lib/components/share-page/IndividualSharedViewer.svelte +++ b/web/src/lib/components/share-page/IndividualSharedViewer.svelte @@ -18,7 +18,7 @@ import { toTimelineAsset } from '$lib/utils/timeline-util'; import { getAssetInfo, type SharedLinkResponseDto } from '@immich/sdk'; import { IconButton, Logo, toastManager } from '@immich/ui'; - import { mdiArrowLeft, mdiDownload, mdiFileImagePlusOutline, mdiSelectAll } from '@mdi/js'; + import { mdiDownload, mdiFileImagePlusOutline, mdiSelectAll } from '@mdi/js'; import { t } from 'svelte-i18n'; import ControlAppBar from '../shared-components/ControlAppBar.svelte'; import GalleryViewer from '../shared-components/gallery-viewer/GalleryViewer.svelte'; @@ -97,7 +97,7 @@ {/if} {:else} - goto(Route.photos())} backIcon={mdiArrowLeft} showBackButton={false}> + {#snippet leading()} diff --git a/web/src/lib/components/shared-components/ControlAppBar.svelte b/web/src/lib/components/shared-components/ControlAppBar.svelte index 85990a3b5c..eb021be775 100644 --- a/web/src/lib/components/shared-components/ControlAppBar.svelte +++ b/web/src/lib/components/shared-components/ControlAppBar.svelte @@ -1,97 +1,49 @@ -
- + {#if trailing} + + {@render trailing()} + + {/if} +
diff --git a/web/src/lib/components/shared-components/context-menu/ContextMenu.svelte b/web/src/lib/components/shared-components/context-menu/ContextMenu.svelte index 9d849cfbfc..729a4a4ea9 100644 --- a/web/src/lib/components/shared-components/context-menu/ContextMenu.svelte +++ b/web/src/lib/components/shared-components/context-menu/ContextMenu.svelte @@ -64,7 +64,7 @@
+
{$t('people')}
{#each peopleList as person (person.id)} diff --git a/web/src/lib/components/shared-components/tree/Breadcrumbs.svelte b/web/src/lib/components/shared-components/tree/Breadcrumbs.svelte index 1c58e8feb1..b065888244 100644 --- a/web/src/lib/components/shared-components/tree/Breadcrumbs.svelte +++ b/web/src/lib/components/shared-components/tree/Breadcrumbs.svelte @@ -35,7 +35,7 @@ {/if}
  1. diff --git a/web/src/lib/components/sidebar/Sidebar.svelte b/web/src/lib/components/sidebar/Sidebar.svelte index fa7560e314..54f96a5c09 100644 --- a/web/src/lib/components/sidebar/Sidebar.svelte +++ b/web/src/lib/components/sidebar/Sidebar.svelte @@ -35,7 +35,7 @@ id="sidebar" aria-label={ariaLabel} tabindex="-1" - class="relative z-1 w-0 overflow-x-hidden overflow-y-auto bg-light pt-8 transition-all duration-200 immich-scrollbar sidebar:w-64" + class="relative z-1 w-0 immich-scrollbar overflow-x-hidden overflow-y-auto bg-light pt-8 transition-all duration-200 sidebar:w-64" class:shadow-2xl={isExpanded} class:dark:border-e-immich-dark-gray={isExpanded} class:border-r={isExpanded} diff --git a/web/src/lib/components/timeline/AssetLayout.svelte b/web/src/lib/components/timeline/AssetLayout.svelte index 4ecf71f517..59b8499d79 100644 --- a/web/src/lib/components/timeline/AssetLayout.svelte +++ b/web/src/lib/components/timeline/AssetLayout.svelte @@ -1,6 +1,5 @@ - + {#snippet leading()} -
    +

    {assets.length}

    diff --git a/web/src/lib/components/timeline/Month.svelte b/web/src/lib/components/timeline/Month.svelte index 3f4b9b0661..7cbfd67ddf 100644 --- a/web/src/lib/components/timeline/Month.svelte +++ b/web/src/lib/components/timeline/Month.svelte @@ -100,7 +100,7 @@
    diff --git a/web/src/lib/managers/edit/edit-manager.svelte.ts b/web/src/lib/managers/edit/edit-manager.svelte.ts index 083a446938..dc454f854a 100644 --- a/web/src/lib/managers/edit/edit-manager.svelte.ts +++ b/web/src/lib/managers/edit/edit-manager.svelte.ts @@ -127,7 +127,7 @@ export class EditManager { try { // Setup the websocket listener before sending the edit request - const editCompleted = waitForWebsocketEvent('AssetEditReadyV1', (event) => event.asset.id === assetId, 10_000); + const editCompleted = waitForWebsocketEvent('AssetEditReadyV2', (event) => event.asset.id === assetId, 10_000); await (edits.length === 0 ? removeAssetEdits({ id: assetId }) diff --git a/web/src/lib/managers/plugin-manager.svelte.ts b/web/src/lib/managers/plugin-manager.svelte.ts index 57ca8fded5..5f9ee315a5 100644 --- a/web/src/lib/managers/plugin-manager.svelte.ts +++ b/web/src/lib/managers/plugin-manager.svelte.ts @@ -1,8 +1,10 @@ import { getWorkflowTriggers, searchPluginMethods, + searchPluginTemplates, WorkflowTrigger, type PluginMethodResponseDto, + type PluginTemplateResponseDto, type WorkflowTriggerResponseDto, } from '@immich/sdk'; import { t } from 'svelte-i18n'; @@ -16,6 +18,7 @@ class PluginManager { #methodMap = new SvelteMap(); #methods = $state([]); #triggers = $state([]); + #templates = $state([]); constructor() { eventManager.on({ @@ -33,6 +36,10 @@ class PluginManager { return this.#triggers; } + get templates() { + return this.#templates; + } + ready() { return this.initialize(); } @@ -70,7 +77,11 @@ class PluginManager { } private async load() { - const [methods, triggers] = await Promise.all([searchPluginMethods({}), getWorkflowTriggers()]); + const [methods, triggers, templates] = await Promise.all([ + searchPluginMethods({}), + getWorkflowTriggers(), + searchPluginTemplates(), + ]); this.#methods = methods; for (const method of this.#methods) { @@ -78,6 +89,7 @@ class PluginManager { } this.#triggers = triggers; + this.#templates = templates; } } diff --git a/web/src/lib/managers/timeline-manager/internal/intersection-support.svelte.ts b/web/src/lib/managers/timeline-manager/internal/intersection-support.svelte.ts index bb3ae72c81..3175fd3c3e 100644 --- a/web/src/lib/managers/timeline-manager/internal/intersection-support.svelte.ts +++ b/web/src/lib/managers/timeline-manager/internal/intersection-support.svelte.ts @@ -53,17 +53,3 @@ export function updateTimelineMonthViewportProximity(timelineManager: TimelineMa timelineManager.clearDeferredLayout(month); } } - -export function calculateViewerAssetViewportProximity( - timelineManager: TimelineManager, - positionTop: number, - positionHeight: number, -) { - const headerHeight = timelineManager.headerHeight; - return calculateViewportProximity( - positionTop, - positionTop + positionHeight, - timelineManager.visibleWindow.top - headerHeight, - timelineManager.visibleWindow.bottom + headerHeight, - ); -} diff --git a/web/src/lib/managers/timeline-manager/timeline-day.svelte.ts b/web/src/lib/managers/timeline-manager/timeline-day.svelte.ts index 73b2c259ae..2515acc385 100644 --- a/web/src/lib/managers/timeline-manager/timeline-day.svelte.ts +++ b/web/src/lib/managers/timeline-manager/timeline-day.svelte.ts @@ -1,12 +1,31 @@ import { AssetOrder, AssetOrderBy } from '@immich/sdk'; import { SvelteSet } from 'svelte/reactivity'; -import type { CommonLayoutOptions } from '$lib/utils/layout-utils'; +import type { CommonLayoutOptions, CommonPosition } from '$lib/utils/layout-utils'; import { getJustifiedLayoutFromAssets } from '$lib/utils/layout-utils'; import { getOrderingDate, plainDateTimeCompare } from '$lib/utils/timeline-util'; +import { TUNABLES } from '$lib/utils/tunables'; import type { TimelineMonth } from './timeline-month.svelte'; import type { Direction, MoveAsset, TimelineAsset } from './types'; import { ViewerAsset } from './viewer-asset.svelte'; +const { + TIMELINE: { INTERSECTION_EXPAND_TOP, INTERSECTION_EXPAND_BOTTOM }, +} = TUNABLES; + +function lowerBound(assets: ViewerAsset[], target: number, key: (pos: CommonPosition) => number): number { + let lo = 0; + let hi = assets.length; + while (lo < hi) { + const mid = Math.floor((lo + hi) / 2); + if (key(assets[mid].position!) < target) { + lo = mid + 1; + } else { + hi = mid; + } + } + return lo; +} + export class TimelineDay { readonly timelineMonth: TimelineMonth; readonly index: number; @@ -17,7 +36,10 @@ export class TimelineDay { height = $state(0); width = $state(0); - isInOrNearViewport = $derived.by(() => this.viewerAssets.some((viewAsset) => viewAsset.isInOrNearViewport)); + + // Assets in or near the viewport; active assets should be added to the DOM. + activeViewerAssets: ViewerAsset[] = $state([]); + isInOrNearViewport = $state(false); #top: number = $state(0); #start: number = $state(0); @@ -149,6 +171,29 @@ export class TimelineDay { for (let i = 0; i < this.viewerAssets.length; i++) { this.viewerAssets[i].position = geometry.getPosition(i); } + this.updateAssetBoundaries(); + } + + updateAssetBoundaries() { + const manager = this.timelineMonth.timelineManager; + const visibleWindow = manager.visibleWindow; + if (this.viewerAssets.length === 0 || !this.viewerAssets[0].position) { + this.activeViewerAssets = []; + this.isInOrNearViewport = false; + return; + } + + const dayOffset = this.absoluteTimelineDayTop; + const headerHeight = manager.headerHeight; + const expandedTop = visibleWindow.top - headerHeight - INTERSECTION_EXPAND_TOP - dayOffset; + const expandedBottom = visibleWindow.bottom + headerHeight + INTERSECTION_EXPAND_BOTTOM - dayOffset; + + const first = lowerBound(this.viewerAssets, expandedTop, (p) => p.top + p.height); + const last = lowerBound(this.viewerAssets, expandedBottom, (p) => p.top) - 1; + + const hasActive = last >= first && first < this.viewerAssets.length; + this.activeViewerAssets = hasActive ? this.viewerAssets.slice(first, last + 1) : []; + this.isInOrNearViewport = hasActive; } get absoluteTimelineDayTop() { diff --git a/web/src/lib/managers/timeline-manager/timeline-manager.svelte.ts b/web/src/lib/managers/timeline-manager/timeline-manager.svelte.ts index 32e6d90d1c..5ac2deaa54 100644 --- a/web/src/lib/managers/timeline-manager/timeline-manager.svelte.ts +++ b/web/src/lib/managers/timeline-manager/timeline-manager.svelte.ts @@ -214,6 +214,11 @@ export class TimelineManager extends VirtualScrollManager { for (const month of this.months) { updateTimelineMonthViewportProximity(this, month); + if (month.isInOrNearViewport && month.isLoaded) { + for (const day of month.timelineDays) { + day.updateAssetBoundaries(); + } + } } const month = this.months.find((month) => month.isInViewport); diff --git a/web/src/lib/managers/timeline-manager/timeline-month.svelte.ts b/web/src/lib/managers/timeline-manager/timeline-month.svelte.ts index bee53151f7..54a0edc784 100644 --- a/web/src/lib/managers/timeline-manager/timeline-month.svelte.ts +++ b/web/src/lib/managers/timeline-manager/timeline-month.svelte.ts @@ -179,8 +179,8 @@ export class TimelineMonth { ); const timelineAsset: TimelineAsset = { - city: bucketAssets.city[i], - country: bucketAssets.country[i], + city: bucketAssets.city?.[i] ?? null, + country: bucketAssets.country?.[i] ?? null, duration: bucketAssets.duration[i], id: bucketAssets.id[i], visibility: bucketAssets.visibility[i], @@ -254,7 +254,7 @@ export class TimelineMonth { addContext.newTimelineDays.add(timelineDay); } - const viewerAsset = new ViewerAsset(timelineDay, timelineAsset); + const viewerAsset = new ViewerAsset(timelineAsset); timelineDay.viewerAssets.push(viewerAsset); addContext.changedTimelineDays.add(timelineDay); } diff --git a/web/src/lib/managers/timeline-manager/viewer-asset.svelte.ts b/web/src/lib/managers/timeline-manager/viewer-asset.svelte.ts index 0179dd9e74..3a4ed4545c 100644 --- a/web/src/lib/managers/timeline-manager/viewer-asset.svelte.ts +++ b/web/src/lib/managers/timeline-manager/viewer-asset.svelte.ts @@ -1,36 +1,12 @@ import type { CommonPosition } from '$lib/utils/layout-utils'; -import { - ViewportProximity, - calculateViewerAssetViewportProximity, - isInOrNearViewport, -} from './internal/intersection-support.svelte'; -import type { TimelineDay } from './timeline-day.svelte'; import type { TimelineAsset } from './types'; export class ViewerAsset { - readonly #group: TimelineDay; - - #viewportProximity = $derived.by(() => { - if (!this.position) { - return ViewportProximity.FarFromViewport; - } - - const store = this.#group.timelineMonth.timelineManager; - const positionTop = this.#group.absoluteTimelineDayTop + this.position.top; - - return calculateViewerAssetViewportProximity(store, positionTop, this.position.height); - }); - - get isInOrNearViewport() { - return isInOrNearViewport(this.#viewportProximity); - } - position: CommonPosition | undefined = $state.raw(); asset: TimelineAsset = $state() as TimelineAsset; id: string = $derived(this.asset.id); - constructor(group: TimelineDay, asset: TimelineAsset) { - this.#group = group; + constructor(asset: TimelineAsset) { this.asset = asset; } } diff --git a/web/src/lib/modals/AlbumPickerModal.svelte b/web/src/lib/modals/AlbumPickerModal.svelte index 43ed575eb2..3674a21acd 100644 --- a/web/src/lib/modals/AlbumPickerModal.svelte +++ b/web/src/lib/modals/AlbumPickerModal.svelte @@ -172,7 +172,7 @@ bind:value={search} use:initInput /> -
    +
    {#each albumModalRows as row} {#if row.type === AlbumModalRowType.NEW_ALBUM} diff --git a/web/src/lib/modals/PartnerSelectionModal.svelte b/web/src/lib/modals/PartnerSelectionModal.svelte index fdebcfecb4..d3f7f7dce7 100644 --- a/web/src/lib/modals/PartnerSelectionModal.svelte +++ b/web/src/lib/modals/PartnerSelectionModal.svelte @@ -41,7 +41,7 @@
    {:then _} {#if availableUsers.length > 0} -
    +
    {#each availableUsers as user (user.id)} selectUser(user)} selected={selectedUsers.includes(user)}> diff --git a/web/src/lib/modals/PeoplePickerModal.svelte b/web/src/lib/modals/PeoplePickerModal.svelte index 0b6520105b..10d7ee5033 100644 --- a/web/src/lib/modals/PeoplePickerModal.svelte +++ b/web/src/lib/modals/PeoplePickerModal.svelte @@ -61,7 +61,7 @@
    -
    +
    {#if loading}
    diff --git a/web/src/lib/modals/PluginMethodPicker.svelte b/web/src/lib/modals/PluginMethodPicker.svelte index 7000fed2cc..230f5a2257 100644 --- a/web/src/lib/modals/PluginMethodPicker.svelte +++ b/web/src/lib/modals/PluginMethodPicker.svelte @@ -12,7 +12,7 @@ const { trigger, selectedKey, onClose }: Props = $props(); - + {#await searchPluginMethods({ trigger })}
    @@ -24,7 +24,7 @@
    {method.title} - {#if method.uiHints.includes('filter')} + {#if method.uiHints.includes('Filter')} {$t('plugin_method_filter_type')} diff --git a/web/src/lib/modals/WorkflowAddStepModal.svelte b/web/src/lib/modals/WorkflowAddStepModal.svelte index 889e175de0..d347a1feb3 100644 --- a/web/src/lib/modals/WorkflowAddStepModal.svelte +++ b/web/src/lib/modals/WorkflowAddStepModal.svelte @@ -38,7 +38,7 @@ {#if method} - +
    {method.title} diff --git a/web/src/lib/modals/WorkflowDuplicateModal.svelte b/web/src/lib/modals/WorkflowDuplicateModal.svelte new file mode 100644 index 0000000000..0b1286d499 --- /dev/null +++ b/web/src/lib/modals/WorkflowDuplicateModal.svelte @@ -0,0 +1,53 @@ + + + + + + + + + +