diff --git a/.config/cypress-devcontainer.yml b/.config/cypress-devcontainer.yml index 0d10a3cdff..e58f1f3599 100644 --- a/.config/cypress-devcontainer.yml +++ b/.config/cypress-devcontainer.yml @@ -215,20 +215,9 @@ proxyBypassHosts: # Media Proxy #mediaProxy: https://example.com/proxy -# Proxy remote files (default: true) -proxyRemoteFiles: true - -# Sign to ActivityPub GET request (default: true) -signToActivityPubGet: true - allowedPrivateNetworks: [ '127.0.0.1/32' ] -# Disable automatic redirect for ActivityPub object lookup. (default: false) -# This is a strong defense against potential impersonation attacks if the viewer instance has inadequate validation. -# However it will make it impossible for other instances to lookup third-party user and notes through your URL. -#disallowExternalApRedirect: true - # Upload or download file size limits (bytes) #maxFileSize: 262144000 diff --git a/.config/docker_example.yml b/.config/docker_example.yml index 3bf5871e32..4398191e01 100644 --- a/.config/docker_example.yml +++ b/.config/docker_example.yml @@ -236,12 +236,6 @@ proxyBypassHosts: # Media Proxy #mediaProxy: https://example.com/proxy -# Proxy remote files (default: true) -proxyRemoteFiles: true - -# Sign to ActivityPub GET request (default: true) -signToActivityPubGet: true - # For security reasons, uploading attachments from the intranet is prohibited, # but exceptions can be made from the following settings. Default value is "undefined". # Read changelog to learn more (Improvements of 12.90.0 (2021/09/04)). @@ -249,11 +243,6 @@ signToActivityPubGet: true # '127.0.0.1/32' #] -# Disable automatic redirect for ActivityPub object lookup. (default: false) -# This is a strong defense against potential impersonation attacks if the viewer instance has inadequate validation. -# However it will make it impossible for other instances to lookup third-party user and notes through your URL. -#disallowExternalApRedirect: true - # Upload or download file size limits (bytes) #maxFileSize: 262144000 diff --git a/.config/example.yml b/.config/example.yml index e0ba5cbef6..153026fc8f 100644 --- a/.config/example.yml +++ b/.config/example.yml @@ -105,6 +105,16 @@ port: 3000 # socket: /path/to/cherrypick.sock # chmodSocket: '777' +# Proxy trust settings +# +# Changes how the server interpret the origin IP of the request. +# +# Any format supported by Fastify is accepted. +# Default: trust all proxies (i.e. trustProxy: true) +# See: https://fastify.dev/docs/latest/reference/server/#trustproxy +# +# trustProxy: 1 + # ┌──────────────────────────┐ #───┘ PostgreSQL configuration └──────────────────────────────── @@ -328,19 +338,12 @@ proxyBypassHosts: # * Perform image compression (on a different server resource than the main process) #mediaProxy: https://example.com/proxy -# Proxy remote files (default: true) -# Proxy remote files by this instance or mediaProxy to prevent remote files from running in remote domains. -proxyRemoteFiles: true - # Movie Thumbnail Generation URL # There is no reference implementation. # For example, CherryPick will point to the following URL: # https://example.com/thumbnail.webp?thumbnail=1&url=https%3A%2F%2Fstorage.example.com%2Fpath%2Fto%2Fvideo.mp4 #videoThumbnailGenerator: https://example.com -# Sign to ActivityPub GET request (default: true) -signToActivityPubGet: true - # For security reasons, uploading attachments from the intranet is prohibited, # but exceptions can be made from the following settings. Default value is "undefined". # Read changelog to learn more (Improvements of 12.90.0 (2021/09/04)). @@ -348,11 +351,6 @@ signToActivityPubGet: true # '127.0.0.1/32' #] -# Disable automatic redirect for ActivityPub object lookup. (default: false) -# This is a strong defense against potential impersonation attacks if the viewer instance has inadequate validation. -# However it will make it impossible for other instances to lookup third-party user and notes through your URL. -#disallowExternalApRedirect: true - # Upload or download file size limits (bytes) #maxFileSize: 262144000 diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index a44a255c2c..b4416daa19 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -5,7 +5,7 @@ "workspaceFolder": "/workspace", "features": { "ghcr.io/devcontainers/features/node:1": { - "version": "22.15.0" + "version": "24.10.0" }, "ghcr.io/devcontainers-extra/features/pnpm:2": { "version": "10.10.0" @@ -21,7 +21,8 @@ "Vue.volar", "Orta.vscode-jest", "dbaeumer.vscode-eslint", - "mrmlnc.vscode-json5" + "mrmlnc.vscode-json5", + "eamodio.gitlens" ] } } diff --git a/.devcontainer/devcontainer.yml b/.devcontainer/devcontainer.yml index c6291edad6..4361b0e8fe 100644 --- a/.devcontainer/devcontainer.yml +++ b/.devcontainer/devcontainer.yml @@ -211,12 +211,6 @@ proxyBypassHosts: # Media Proxy #mediaProxy: https://example.com/proxy -# Proxy remote files (default: true) -proxyRemoteFiles: true - -# Sign to ActivityPub GET request (default: true) -signToActivityPubGet: true - allowedPrivateNetworks: [ '127.0.0.1/32' ] diff --git a/.editorconfig b/.editorconfig index def7baa1a8..ccf388f06e 100644 --- a/.editorconfig +++ b/.editorconfig @@ -13,3 +13,7 @@ trim_trailing_whitespace = false [*.{yml,yaml}] indent_style = space + +[packages/backend/migration/*.js] +indent_style = space +indent_size = 4 diff --git a/.github/cherrypick/test.yml b/.github/cherrypick/test.yml index c4ce858ad2..120cce7987 100644 --- a/.github/cherrypick/test.yml +++ b/.github/cherrypick/test.yml @@ -15,3 +15,5 @@ redis: host: 127.0.0.1 port: 56312 id: aidx + +proxyRemoteFiles: true diff --git a/.github/min.node-version b/.github/min.node-version index d5a159609d..b8ffd70759 100644 --- a/.github/min.node-version +++ b/.github/min.node-version @@ -1 +1 @@ -20.10.0 +22.15.0 diff --git a/.github/workflows/api-cherrypick-js.yml b/.github/workflows/api-cherrypick-js.yml index c3c84c9a46..f8e862d562 100644 --- a/.github/workflows/api-cherrypick-js.yml +++ b/.github/workflows/api-cherrypick-js.yml @@ -16,10 +16,10 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v4.2.2 + uses: actions/checkout@v4.3.0 - name: Setup pnpm - uses: pnpm/action-setup@v4.1.0 + uses: pnpm/action-setup@v4.2.0 - name: Setup Node.js uses: actions/setup-node@v4.4.0 diff --git a/.github/workflows/changelog-check.yml b/.github/workflows/changelog-check.yml index 033115c67e..89e06281ab 100644 --- a/.github/workflows/changelog-check.yml +++ b/.github/workflows/changelog-check.yml @@ -12,7 +12,7 @@ jobs: steps: - name: Checkout head - uses: actions/checkout@v4.2.2 + uses: actions/checkout@v4.3.0 - name: Setup Node.js uses: actions/setup-node@v4.4.0 with: diff --git a/.github/workflows/check-cherrypick-js-autogen.yml b/.github/workflows/check-cherrypick-js-autogen.yml index 18c3e8fb90..5682335481 100644 --- a/.github/workflows/check-cherrypick-js-autogen.yml +++ b/.github/workflows/check-cherrypick-js-autogen.yml @@ -18,14 +18,14 @@ jobs: if: ${{ github.event.pull_request.mergeable == null || github.event.pull_request.mergeable == true }} steps: - name: checkout - uses: actions/checkout@v4.2.2 + uses: actions/checkout@v4.3.0 with: submodules: true persist-credentials: false ref: refs/pull/${{ github.event.pull_request.number }}/merge - name: setup pnpm - uses: pnpm/action-setup@v4 + uses: pnpm/action-setup@v4.2.0 - name: setup node id: setup-node @@ -66,7 +66,7 @@ jobs: if: ${{ github.event.pull_request.mergeable == null || github.event.pull_request.mergeable == true }} steps: - name: checkout - uses: actions/checkout@v4.2.2 + uses: actions/checkout@v4.3.0 with: submodules: true persist-credentials: false diff --git a/.github/workflows/check-cherrypick-js-version.yml b/.github/workflows/check-cherrypick-js-version.yml index 9f2e915927..3708876862 100644 --- a/.github/workflows/check-cherrypick-js-version.yml +++ b/.github/workflows/check-cherrypick-js-version.yml @@ -20,7 +20,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v4.2.2 + uses: actions/checkout@v4.3.0 - name: Check version run: | if [ "$(jq -r '.version' package.json)" != "$(jq -r '.version' packages/cherrypick-js/package.json)" ]; then diff --git a/.github/workflows/check-spdx-license-id.yml b/.github/workflows/check-spdx-license-id.yml index 2f97eda2eb..003551154e 100644 --- a/.github/workflows/check-spdx-license-id.yml +++ b/.github/workflows/check-spdx-license-id.yml @@ -12,7 +12,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v4.2.2 + uses: actions/checkout@v4.3.0 - name: Check run: | counter=0 @@ -50,6 +50,7 @@ jobs: "packages/backend/test" "packages/frontend-shared/@types" "packages/frontend-shared/js" + "packages/frontend-builder" "packages/frontend/.storybook" "packages/frontend/@types" "packages/frontend/lib" @@ -58,6 +59,7 @@ jobs: "packages/frontend/test" "packages/frontend-embed/@types" "packages/frontend-embed/src" + "packages/icons-subsetter/src" "packages/misskey-bubble-game/src" "packages/misskey-reversi/src" "packages/sw/src" diff --git a/.github/workflows/check_copyright_year.yml b/.github/workflows/check_copyright_year.yml index eaf922d4bc..d891a538c6 100644 --- a/.github/workflows/check_copyright_year.yml +++ b/.github/workflows/check_copyright_year.yml @@ -10,7 +10,7 @@ jobs: check_copyright_year: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4.2.2 + - uses: actions/checkout@v4.3.0 - run: | if [ "$(grep Copyright COPYING | sed -e 's/.*2014-\([0-9]*\) .*/\1/g')" -ne "$(date +%Y)" ]; then echo "Please change copyright year!" diff --git a/.github/workflows/deploy-test-environment.yml b/.github/workflows/deploy-test-environment.yml index 46baf7421b..a888e09514 100644 --- a/.github/workflows/deploy-test-environment.yml +++ b/.github/workflows/deploy-test-environment.yml @@ -28,7 +28,7 @@ jobs: wait_time: ${{ steps.get-wait-time.outputs.wait_time }} steps: - name: Checkout - uses: actions/checkout@v4.2.2 + uses: actions/checkout@v4.3.0 - name: Check allowed users id: check-allowed-users @@ -43,9 +43,9 @@ jobs: "https://api.github.com/organizations/$ORG_ID/public_members/$COMMENT_AUTHOR" \ -o /dev/null -w '%{http_code}\n' -s) if [ "$MEMBERSHIP_STATUS" -eq 204 ]; then - echo "is-allowed-user=true" > $GITHUB_OUTPUT + echo "is-allowed-user=true" >> $GITHUB_OUTPUT else - echo "is-allowed-user=false" > $GITHUB_OUTPUT + echo "is-allowed-user=false" >> $GITHUB_OUTPUT fi - name: Get PR ref @@ -60,7 +60,7 @@ jobs: COMMENT_BODY: ${{ github.event.comment.body }} run: | WAIT_TIME=$(echo "$COMMENT_BODY" | grep -oP '(?<=/preview\s)\d+' || echo "1800") - echo "wait_time=$WAIT_TIME" > $GITHUB_OUTPUT + echo "wait_time=$WAIT_TIME" >> $GITHUB_OUTPUT deploy-test-environment-pr-comment: needs: get-pr-ref diff --git a/.github/workflows/docker-develop.yml b/.github/workflows/docker-develop.yml index 329413eb92..3d1a300dbf 100644 --- a/.github/workflows/docker-develop.yml +++ b/.github/workflows/docker-develop.yml @@ -38,7 +38,7 @@ jobs: platform=${{ matrix.platform }} echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV - name: Check out the repo - uses: actions/checkout@v4.2.2 + uses: actions/checkout@v4.3.0 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Log in to Docker Hub diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 89b72dc6fd..2a8c78081c 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -43,7 +43,7 @@ jobs: platform=${{ matrix.platform }} echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV - name: Check out the repo - uses: actions/checkout@v4.2.2 + uses: actions/checkout@v4.3.0 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Docker meta diff --git a/.github/workflows/dockle.yml b/.github/workflows/dockle.yml index fc953d3cf3..c4e0d5086b 100644 --- a/.github/workflows/dockle.yml +++ b/.github/workflows/dockle.yml @@ -15,7 +15,7 @@ jobs: DOCKER_CONTENT_TRUST: 1 DOCKLE_VERSION: 0.4.14 steps: - - uses: actions/checkout@v4.2.2 + - uses: actions/checkout@v4.3.0 - name: Download and install dockle v${{ env.DOCKLE_VERSION }} run: | curl -L -o dockle.deb "https://github.com/goodwithtech/dockle/releases/download/v${DOCKLE_VERSION}/dockle_${DOCKLE_VERSION}_Linux-64bit.deb" @@ -25,7 +25,7 @@ jobs: cp ./compose_example.yml ./compose.yml - run: | docker compose up -d web - docker tag "$(docker compose images web | awk 'OFS=":" {print $4}' | tail -n +2)" cherrypick-web:latest + docker tag "$(docker compose images --format json web | jq -r '.[] | .ID')" cherrypick-web:latest - run: | cmd="dockle --exit-code 1 cherrypick-web:latest ${image_name}" echo "> ${cmd}" diff --git a/.github/workflows/get-api-diff.yml b/.github/workflows/get-api-diff.yml index 11b5dbc3f6..a7b45a21a0 100644 --- a/.github/workflows/get-api-diff.yml +++ b/.github/workflows/get-api-diff.yml @@ -25,12 +25,12 @@ jobs: ref: refs/pull/${{ github.event.number }}/merge steps: - - uses: actions/checkout@v4.2.2 + - uses: actions/checkout@v4.3.0 with: ref: ${{ matrix.ref }} submodules: true - name: Setup pnpm - uses: pnpm/action-setup@v4.1.0 + uses: pnpm/action-setup@v4.2.0 - name: Use Node.js uses: actions/setup-node@v4.4.0 with: diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 0a807418e3..25f155784f 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -9,7 +9,9 @@ on: - packages/backend/** - packages/frontend/** - packages/frontend-shared/** + - packages/frontend-builder/** - packages/frontend-embed/** + - packages/icons-subsetter/** - packages/sw/** - packages/cherrypick-js/** - packages/misskey-bubble-game/** @@ -21,7 +23,9 @@ on: - packages/backend/** - packages/frontend/** - packages/frontend-shared/** + - packages/frontend-builder/** - packages/frontend-embed/** + - packages/icons-subsetter/** - packages/sw/** - packages/cherrypick-js/** - packages/misskey-bubble-game/** @@ -32,12 +36,12 @@ jobs: pnpm_install: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4.2.2 + - uses: actions/checkout@v4.3.0 with: fetch-depth: 0 submodules: true - name: Setup pnpm - uses: pnpm/action-setup@v4.1.0 + uses: pnpm/action-setup@v4.2.0 - uses: actions/setup-node@v4.4.0 with: node-version-file: '.node-version' @@ -54,7 +58,9 @@ jobs: - backend - frontend - frontend-shared + - frontend-builder - frontend-embed + - icons-subsetter - sw - cherrypick-js - misskey-bubble-game @@ -63,19 +69,19 @@ jobs: eslint-cache-version: v1 eslint-cache-path: ${{ github.workspace }}/node_modules/.cache/eslint-${{ matrix.workspace }} steps: - - uses: actions/checkout@v4.2.2 + - uses: actions/checkout@v4.3.0 with: fetch-depth: 0 submodules: true - name: Setup pnpm - uses: pnpm/action-setup@v4.1.0 + uses: pnpm/action-setup@v4.2.0 - uses: actions/setup-node@v4.4.0 with: node-version-file: '.node-version' cache: 'pnpm' - run: pnpm i --frozen-lockfile - name: Restore eslint cache - uses: actions/cache@v4.2.3 + uses: actions/cache@v4.3.0 with: path: ${{ env.eslint-cache-path }} key: eslint-${{ env.eslint-cache-version }}-${{ matrix.workspace }}-${{ hashFiles('**/pnpm-lock.yaml') }}-${{ github.ref_name }}-${{ github.sha }} @@ -93,12 +99,12 @@ jobs: - sw - cherrypick-js steps: - - uses: actions/checkout@v4.2.2 + - uses: actions/checkout@v4.3.0 with: fetch-depth: 0 submodules: true - name: Setup pnpm - uses: pnpm/action-setup@v4.1.0 + uses: pnpm/action-setup@v4.2.0 - uses: actions/setup-node@v4.4.0 with: node-version-file: '.node-version' diff --git a/.github/workflows/locale.yml b/.github/workflows/locale.yml index 68e45fdf61..e63d83997b 100644 --- a/.github/workflows/locale.yml +++ b/.github/workflows/locale.yml @@ -14,12 +14,12 @@ jobs: runs-on: ubuntu-latest continue-on-error: true steps: - - uses: actions/checkout@v4.2.2 + - uses: actions/checkout@v4.3.0 with: fetch-depth: 0 submodules: true - name: Setup pnpm - uses: pnpm/action-setup@v4.1.0 + uses: pnpm/action-setup@v4.2.0 - uses: actions/setup-node@v4.4.0 with: node-version-file: '.node-version' diff --git a/.github/workflows/on-release-created.yml b/.github/workflows/on-release-created.yml index 6b36248393..f8b32511fb 100644 --- a/.github/workflows/on-release-created.yml +++ b/.github/workflows/on-release-created.yml @@ -16,16 +16,18 @@ jobs: id-token: write steps: - - uses: actions/checkout@v4.2.2 + - uses: actions/checkout@v4.3.0 with: submodules: true - name: Setup pnpm - uses: pnpm/action-setup@v4.1.0 + uses: pnpm/action-setup@v4.2.0 - name: Use Node.js uses: actions/setup-node@v4.4.0 with: node-version-file: '.node-version' cache: 'pnpm' + # see https://docs.github.com/actions/use-cases-and-examples/publishing-packages/publishing-nodejs-packages#publishing-packages-to-the-npm-registry + registry-url: 'https://registry.npmjs.org' - name: Publish package run: | pnpm i --frozen-lockfile diff --git a/.github/workflows/release-edit-with-push.yml b/.github/workflows/release-edit-with-push.yml index 662d5c984c..0da48d0718 100644 --- a/.github/workflows/release-edit-with-push.yml +++ b/.github/workflows/release-edit-with-push.yml @@ -45,4 +45,4 @@ jobs: gh pr edit "$PR_NUMBER" --body "$CHANGELOG_CHERRYPICK" env: PR_NUMBER: ${{ steps.get_pr.outputs.pr_number }} - CHANGELOG: ${{ steps.changelog.outputs.changelog }} + CHANGELOG_CHERRYPICK: ${{ steps.changelog.outputs.changelog }} diff --git a/.github/workflows/release-with-dispatch.yml b/.github/workflows/release-with-dispatch.yml index 53bcf91493..fb26872daf 100644 --- a/.github/workflows/release-with-dispatch.yml +++ b/.github/workflows/release-with-dispatch.yml @@ -3,16 +3,16 @@ name: "Release Manager [Dispatch]" on: workflow_dispatch: inputs: - ## Specify the type of the next release. - #version_increment_type: - # type: choice - # description: 'VERSION INCREMENT TYPE' - # default: 'patch' - # required: false - # options: - # - 'major' - # - 'minor' - # - 'patch' + # Specify the type of the next release. + version_increment_type: + type: choice + description: 'VERSION INCREMENT TYPE' + default: 'patch' + required: false + options: + - 'major' + - 'minor' + - 'patch' merge: type: boolean description: 'MERGE RELEASE BRANCH TO MAIN' @@ -45,9 +45,52 @@ jobs: env: STABLE_BRANCH: ${{ vars.STABLE_BRANCH }} + prepare-merge: + runs-on: ubuntu-latest + needs: get-pr + if: ${{ needs.get-pr.outputs.pr_number != '' && inputs.merge == true }} + outputs: + changes_template: ${{ steps.generate-template.outputs.template }} + steps: + - uses: actions/checkout@v4 + - name: Read package.json + id: read-package + run: | + BASED_MISSKEY_VERSION=$(node -p "require('./package.json').basedMisskeyVersion") + echo "based_misskey_version=$BASED_MISSKEY_VERSION" >> $GITHUB_OUTPUT + CHANGELOG_ANCHOR=$(echo $BASED_MISSKEY_VERSION | sed 's/\.//g') + echo "changelog_anchor=$CHANGELOG_ANCHOR" >> $GITHUB_OUTPUT + - name: Generate changes template + id: generate-template + env: + BASED_VERSION: ${{ steps.read-package.outputs.based_misskey_version }} + CHANGELOG_ANCHOR: ${{ steps.read-package.outputs.changelog_anchor }} + run: | + { + echo 'template<> $GITHUB_OUTPUT + merge: uses: kokonect-link/release-manager-actions/.github/workflows/merge.yml@v2 - needs: get-pr + needs: [get-pr, prepare-merge] if: ${{ needs.get-pr.outputs.pr_number != '' && inputs.merge == true }} with: pr_number: ${{ needs.get-pr.outputs.pr_number }} @@ -55,18 +98,7 @@ jobs: package_jsons_to_rewrite: ${{ vars.PACKAGE_JSONS_TO_REWRITE }} # Text to prepend to the changelog # The first line must be `## Unreleased` - changes_template: | - ## Unreleased - - ### General - - - - ### Client - - - - ### Server - - - + changes_template: ${{ needs.prepare-merge.outputs.changes_template }} use_external_app_to_release: ${{ vars.USE_RELEASE_APP == 'true' }} indent: ${{ vars.INDENT }} secrets: @@ -101,31 +133,31 @@ jobs: # process.env.CURRENT_VERSION: The current version. # # Misskey calender versioning (yyyy.MM.patch) example - version_increment_script: | - const now = new Date(); - const year = now.toLocaleDateString('en-US', { year: 'numeric', timeZone: 'Asia/Tokyo' }); - const month = now.toLocaleDateString('en-US', { month: 'numeric', timeZone: 'Asia/Tokyo' }); - const [major, minor, _patch] = process.env.CURRENT_VERSION.split('.'); - const patch = Number(_patch.split('-')[0]); - if (Number.isNaN(patch)) { - console.error('Invalid patch version', year, month, process.env.CURRENT_VERSION, major, minor, _patch); - throw new Error('Invalid patch version'); - } - if (year !== major || month !== minor) { - return `${year}.${month}.0`; - } else { - return `${major}.${minor}.${patch + 1}`; - } - ##Semver example #version_increment_script: | - # const [major, minor, patch] = process.env.CURRENT_VERSION.split('.'); - # if ("${{ inputs.version_increment_type }}" === "major") { - # return `${Number(major) + 1}.0.0`; - # } else if ("${{ inputs.version_increment_type }}" === "minor") { - # return `${major}.${Number(minor) + 1}.0`; + # const now = new Date(); + # const year = now.toLocaleDateString('en-US', { year: 'numeric', timeZone: 'Asia/Tokyo' }); + # const month = now.toLocaleDateString('en-US', { month: 'numeric', timeZone: 'Asia/Tokyo' }); + # const [major, minor, _patch] = process.env.CURRENT_VERSION.split('.'); + # const patch = Number(_patch.split('-')[0]); + # if (Number.isNaN(patch)) { + # console.error('Invalid patch version', year, month, process.env.CURRENT_VERSION, major, minor, _patch); + # throw new Error('Invalid patch version'); + # } + # if (year !== major || month !== minor) { + # return `${year}.${month}.0`; # } else { - # return `${major}.${minor}.${Number(patch) + 1}`; + # return `${major}.${minor}.${patch + 1}`; # } + #Semver example + version_increment_script: | + const [major, minor, patch] = process.env.CURRENT_VERSION.split('.'); + if ("${{ inputs.version_increment_type }}" === "major") { + return `${Number(major) + 1}.0.0`; + } else if ("${{ inputs.version_increment_type }}" === "minor") { + return `${major}.${Number(minor) + 1}.0`; + } else { + return `${major}.${minor}.${Number(patch) + 1}`; + } package_jsons_to_rewrite: ${{ vars.PACKAGE_JSONS_TO_REWRITE }} use_external_app_to_release: ${{ vars.USE_RELEASE_APP == 'true' }} indent: ${{ vars.INDENT }} diff --git a/.github/workflows/report-api-diff.yml b/.github/workflows/report-api-diff.yml index 10c4f5b562..bca270f59e 100644 --- a/.github/workflows/report-api-diff.yml +++ b/.github/workflows/report-api-diff.yml @@ -16,7 +16,7 @@ jobs: # api-artifact steps: - name: Download artifact - uses: actions/github-script@v7.0.1 + uses: actions/github-script@v7.1.0 with: script: | const fs = require('fs'); @@ -85,7 +85,7 @@ jobs: echo '```diff' >> ./output.md cat ./api.json.diff >> ./output.md echo '```' >> ./output.md - echo '' >> .output.md + echo '' >> ./output.md fi echo "$FOOTER" >> ./output.md diff --git a/.github/workflows/request-release-review.yml b/.github/workflows/request-release-review.yml new file mode 100644 index 0000000000..cebdb4e704 --- /dev/null +++ b/.github/workflows/request-release-review.yml @@ -0,0 +1,51 @@ +name: Request release review + +on: + issue_comment: + types: [created] + +jobs: + reply: + if: github.event.comment.body == '/request-release-review' + runs-on: ubuntu-latest + permissions: + contents: read + issues: write + pull-requests: write + steps: + - name: Reply + uses: actions/github-script@v7.1.0 + with: + script: | + const body = `To dev team (@kokonect-link/dev): + + リリースが提案されています :rocket: + + GOの場合はapprove、NO GOの場合はその旨コメントをお願いいたします。 + + 判断にあたって考慮すべき観点は、 + + - やり残したことはないか? + - CHANGELOG_CHERRYPICKは過不足ないか? + - バージョンに問題はないか?(月跨いでいるのに更新忘れているなど) + - 再考すべき仕様・実装はないか? + - ベータ版を検証したサーバーから不具合の報告等は上がってないか? + - (セキュリティの修正や重要なバグ修正などのため)リリースを急いだ方が良いか?そうではないか? + - Actionsが落ちていないか? + + などが挙げられます。 + + ご協力ありがとうございます :sparkles: + ` + + const issue_number = context.payload.issue ? context.payload.issue.number : (context.payload.pull_request && context.payload.pull_request.number) + if (!issue_number) { + console.log('No issue or PR number found in payload; skipping') + } else { + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number, + body, + }) + } diff --git a/.github/workflows/storybook.yml b/.github/workflows/storybook.yml index 35ebdffcbe..18e0307182 100644 --- a/.github/workflows/storybook.yml +++ b/.github/workflows/storybook.yml @@ -22,12 +22,12 @@ jobs: NODE_OPTIONS: "--max_old_space_size=7168" steps: - - uses: actions/checkout@v4.2.2 + - uses: actions/checkout@v4.3.0 if: github.event_name != 'pull_request_target' with: fetch-depth: 0 submodules: true - - uses: actions/checkout@v4.2.2 + - uses: actions/checkout@v4.3.0 if: github.event_name == 'pull_request_target' with: fetch-depth: 0 @@ -37,7 +37,7 @@ jobs: if: github.event_name == 'pull_request_target' run: git checkout "$(git rev-list --parents -n1 HEAD | cut -d" " -f3)" - name: Setup pnpm - uses: pnpm/action-setup@v4.1.0 + uses: pnpm/action-setup@v4.2.0 - name: Use Node.js uses: actions/setup-node@v4.4.0 with: @@ -90,7 +90,7 @@ jobs: env: CHROMATIC_PROJECT_TOKEN: ${{ secrets.CHROMATIC_PROJECT_TOKEN }} - name: Notify that Chromatic detects changes - uses: actions/github-script@v7.0.1 + uses: actions/github-script@v7.1.0 if: github.event_name != 'pull_request_target' && steps.chromatic_push.outputs.success == 'false' with: github-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/test-backend.yml b/.github/workflows/test-backend.yml index 02c9544694..b7beddee0c 100644 --- a/.github/workflows/test-backend.yml +++ b/.github/workflows/test-backend.yml @@ -18,6 +18,14 @@ on: - packages/cherrypick-js/** - .github/workflows/test-backend.yml - .github/cherrypick/test.yml + workflow_dispatch: + inputs: + force_ffmpeg_cache_update: + description: 'Force update ffmpeg cache' + required: false + default: false + type: boolean + jobs: unit: name: Unit tests (backend) @@ -42,12 +50,27 @@ jobs: - 56312:6379 steps: - - uses: actions/checkout@v4.2.2 + - uses: actions/checkout@v4.3.0 with: submodules: true - name: Setup pnpm - uses: pnpm/action-setup@v4.1.0 + uses: pnpm/action-setup@v4.2.0 + - name: Get current date + id: current-date + run: echo "today=$(date +'%Y-%m-%d')" >> $GITHUB_OUTPUT + - name: Setup and Restore ffmpeg/ffprobe Cache + id: cache-ffmpeg + uses: actions/cache@v4.3.0 + with: + path: | + /usr/local/bin/ffmpeg + /usr/local/bin/ffprobe + # daily cache + key: ${{ runner.os }}-ffmpeg-${{ steps.current-date.outputs.today }} + restore-keys: | + ${{ runner.os }}-ffmpeg-${{ steps.current-date.outputs.today }} - name: Install FFmpeg + if: steps.cache-ffmpeg.outputs.cache-hit != 'true' || github.event.inputs.force_ffmpeg_cache_update == true run: | for i in {1..3}; do echo "Attempt $i: Installing FFmpeg..." @@ -86,6 +109,7 @@ jobs: name: E2E tests (backend) runs-on: ubuntu-latest strategy: + fail-fast: false matrix: node-version-file: - .node-version @@ -105,11 +129,11 @@ jobs: - 56312:6379 steps: - - uses: actions/checkout@v4.2.2 + - uses: actions/checkout@v4.3.0 with: submodules: true - name: Setup pnpm - uses: pnpm/action-setup@v4.1.0 + uses: pnpm/action-setup@v4.2.0 - name: Use Node.js uses: actions/setup-node@v4.4.0 with: @@ -129,3 +153,47 @@ jobs: with: token: ${{ secrets.CODECOV_TOKEN }} files: ./packages/backend/coverage/coverage-final.json + + migration: + name: Migration tests (backend) + runs-on: ubuntu-latest + strategy: + matrix: + node-version-file: + - .node-version + #- .github/min.node-version + + services: + postgres: + image: postgres:15 + ports: + - 54312:5432 + env: + POSTGRES_DB: test-cherrypick + POSTGRES_HOST_AUTH_METHOD: trust + + steps: + - uses: actions/checkout@v4.3.0 + with: + submodules: true + - name: Setup pnpm + uses: pnpm/action-setup@v4.2.0 + - name: Get current date + id: current-date + run: echo "today=$(date +'%Y-%m-%d')" >> $GITHUB_OUTPUT + - name: Use Node.js + uses: actions/setup-node@v4.4.0 + with: + node-version-file: ${{ matrix.node-version-file }} + cache: 'pnpm' + - run: pnpm i --frozen-lockfile + - name: Check pnpm-lock.yaml + run: git diff --exit-code pnpm-lock.yaml + - name: Copy Configure + run: cp .github/cherrypick/test.yml .config + - name: Build + run: pnpm build + - name: Run migrations + run: CHERRYPICK_CONFIG_YML=test.yml pnpm --filter backend migrate + - name: Check no migrations are remaining + run: CHERRYPICK_CONFIG_YML=test.yml pnpm --filter backend check-migrations diff --git a/.github/workflows/test-cherrypick-js.yml b/.github/workflows/test-cherrypick-js.yml index 5d2352b3e6..c8c62a59a4 100644 --- a/.github/workflows/test-cherrypick-js.yml +++ b/.github/workflows/test-cherrypick-js.yml @@ -22,10 +22,10 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v4.2.2 + uses: actions/checkout@v4.3.0 - name: Setup pnpm - uses: pnpm/action-setup@v4.1.0 + uses: pnpm/action-setup@v4.2.0 - name: Setup Node.js uses: actions/setup-node@v4.4.0 diff --git a/.github/workflows/test-federation.yml b/.github/workflows/test-federation.yml index 27c10c67c2..66a6dfd2a1 100644 --- a/.github/workflows/test-federation.yml +++ b/.github/workflows/test-federation.yml @@ -14,6 +14,13 @@ on: - packages/backend/** - packages/cherrypick-js/** - .github/workflows/test-federation.yml + workflow_dispatch: + inputs: + force_ffmpeg_cache_update: + description: 'Force update ffmpeg cache' + required: false + default: false + type: boolean jobs: test: @@ -25,12 +32,27 @@ jobs: - .node-version - .github/min.node-version steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v4.3.0 with: submodules: true - name: Setup pnpm - uses: pnpm/action-setup@v4.1.0 + uses: pnpm/action-setup@v4.2.0 + - name: Get current date + id: current-date + run: echo "today=$(date +'%Y-%m-%d')" >> $GITHUB_OUTPUT + - name: Setup and Restore ffmpeg/ffprobe Cache + id: cache-ffmpeg + uses: actions/cache@v4.3.0 + with: + path: | + /usr/local/bin/ffmpeg + /usr/local/bin/ffprobe + # daily cache + key: ${{ runner.os }}-ffmpeg-${{ steps.current-date.outputs.today }} + restore-keys: | + ${{ runner.os }}-ffmpeg-${{ steps.current-date.outputs.today }} - name: Install FFmpeg + if: steps.cache-ffmpeg.outputs.cache-hit != 'true' || github.event.inputs.force_ffmpeg_cache_update == true run: | for i in {1..3}; do echo "Attempt $i: Installing FFmpeg..." diff --git a/.github/workflows/test-frontend.yml b/.github/workflows/test-frontend.yml index 78b67ab8bb..8895c3b472 100644 --- a/.github/workflows/test-frontend.yml +++ b/.github/workflows/test-frontend.yml @@ -28,11 +28,11 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4.2.2 + - uses: actions/checkout@v4.3.0 with: submodules: true - name: Setup pnpm - uses: pnpm/action-setup@v4.1.0 + uses: pnpm/action-setup@v4.2.0 - name: Use Node.js uses: actions/setup-node@v4.4.0 with: @@ -76,7 +76,7 @@ jobs: - 56312:6379 steps: - - uses: actions/checkout@v4.2.2 + - uses: actions/checkout@v4.3.0 with: submodules: true # https://github.com/cypress-io/cypress-docker-images/issues/150 @@ -86,7 +86,7 @@ jobs: #- uses: browser-actions/setup-firefox@latest # if: ${{ matrix.browser == 'firefox' }} - name: Setup pnpm - uses: pnpm/action-setup@v4.1.0 + uses: pnpm/action-setup@v4.2.0 - name: Use Node.js uses: actions/setup-node@v4.4.0 with: diff --git a/.github/workflows/test-production.yml b/.github/workflows/test-production.yml index 9af6827190..e5f2f77f14 100644 --- a/.github/workflows/test-production.yml +++ b/.github/workflows/test-production.yml @@ -16,11 +16,11 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4.2.2 + - uses: actions/checkout@v4.3.0 with: submodules: true - name: Setup pnpm - uses: pnpm/action-setup@v4.1.0 + uses: pnpm/action-setup@v4.2.0 - name: Use Node.js uses: actions/setup-node@v4.4.0 with: diff --git a/.github/workflows/validate-api-json.yml b/.github/workflows/validate-api-json.yml index edff7dbecb..82c522c65c 100644 --- a/.github/workflows/validate-api-json.yml +++ b/.github/workflows/validate-api-json.yml @@ -17,11 +17,11 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4.2.2 + - uses: actions/checkout@v4.3.0 with: submodules: true - name: Setup pnpm - uses: pnpm/action-setup@v4.1.0 + uses: pnpm/action-setup@v4.2.0 - name: Use Node.js uses: actions/setup-node@v4.4.0 with: diff --git a/.gitignore b/.gitignore index 1863995156..dc23dc83fc 100644 --- a/.gitignore +++ b/.gitignore @@ -80,3 +80,6 @@ vite.config.local-dev.ts.timestamp-* # VSCode addon .favorites.json + +# Serena +.serena diff --git a/.node-version b/.node-version index b8ffd70759..21651351e2 100644 --- a/.node-version +++ b/.node-version @@ -1 +1 @@ -22.15.0 +24.10.0 diff --git a/.vscode/settings.json b/.vscode/settings.json index 0ceec23acd..da4e9ee3a4 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -6,8 +6,12 @@ "files.associations": { "*.test.ts": "typescript" }, - "jest.jestCommandLine": "pnpm run jest", "jest.runMode": "on-demand", + "jest.virtualFolders": [ + { "name": "backend unit", "jestCommandLine": "pnpm -F backend run test" }, + { "name": "backend e2e", "jestCommandLine": "pnpm -F backend run test:e2e"}, + { "name": "cherrypick-js", "jestCommandLine": "pnpm -F cherrypick-js run jest" } + ], "editor.codeActionsOnSave": { "source.fixAll": "explicit" }, diff --git a/CHANGELOG.md b/CHANGELOG.md index 3ba13d34c6..829459d953 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,343 @@ +## Unreleased + +### General +- Enhance: Node.js 24.10.0をサポートするようになりました +- Enhance: DockerのNode.jsが24.10.0に更新されました + +### Client +- Fix: 紙吹雪エフェクトがアニメーション設定を考慮せず常に表示される問題を修正 +- Fix: ナビゲーションバーのリアルタイムモード切替ボタンの状態をよりわかりやすく表示するように + +### Server +- + + +## 2025.10.2 + +### Client +- Fix: アプリ内からキャッシュをクリアするとテーマ再適用するまでレンダリングが正しく行われない問題を修正 +- Fix: 期限が無期限のアンケートに投票できない問題を修正 + +## 2025.10.1 + +### General +- Enhance: リモートユーザーに付与したロールバッジを表示できるように(オプトイン) + パフォーマンス上の問題からデフォルトで無効化されています。「コントロールパネル > パフォーマンス」から有効化できます。 +- 依存関係の更新 + +### Client +- Enhance: デッキのメインカラムのヘッダをクリックしてページ上部/下部にスクロールできるように +- Enhance: 下書き/予約投稿一覧は投稿フォームのアカウントメニュー内に移動し、下書き保存は「...」メニュー内に移動されました +- Fix: カスタム絵文字画面(beta)のaliasesで使用される区切り文字が一致していないのを修正 #15614 +- Fix: バナー画像の幅が表示領域と一致していない問題を修正 +- Fix: 一部のブラウザでバナー画像が上下中央に表示されない問題を修正 +- Fix: ナビゲーションバーの設定で削除した項目をその場で再追加できない問題を修正 +- Fix: ロールポリシーによりダイレクトメッセージが無効化されている際のデッキのダイレクトメッセージカラムの挙動を改善 +- Fix: 画像のマスクでタッチ操作が不安定な問題を修正 +- Fix: ウォーターマークの各種挙動修正 + - ウォーターマークを回転させると歪む問題を修正 + - ウォーターマークを敷き詰めると上下左右反転した画像/文字が表示される問題を修正 + - ウォーターマークを回転させた際に画面からはみ出た部分を考慮できるように +- Fix: 投票が終了した後に投票結果が正しく表示されない問題を修正 +- Fix: ダークモードの同期が機能しない場合がある問題を修正 +- Fix: iOSで動画の圧縮を行うと音声トラックが失われる問題を修正 + +### Server +- Enhance: 管理者/モデレーターはファイルのアップロード制限をバイパスするように +- Enhance: セキュリティの向上 + +## 2025.10.0 + +### NOTE +- pnpm 10.16.0 が必要です +- ロールのインポート機能の利用可否ポリシーのデフォルト値が「いいえ」に変わったため、デフォルトから変更していないサーバーでは適宜設定を変更してください。 +- ロールのアップロード可能なファイル種別ポリシーのデフォルト値に「text/*」が追加されたため、デフォルトから変更していないサーバーでは適宜設定を変更してください。 + +### General +- Feat: 予約投稿ができるようになりました + - デフォルトで作成可能数は1になっています。適宜ロールのポリシーで設定を行ってください。 +- Enhance: 広告ごとにセンシティブフラグを設定できるようになりました +- Enhance: 依存関係の更新 +- Enhance: 翻訳の更新 + +### Client +- Feat: アカウントのQRコードを表示・読み取りできるようになりました +- Feat: 動画を圧縮してアップロードできるようになりました +- Feat: (実験的) ブラウザ上でノートの翻訳を行えるように +- Enhance: チャットの日本語名称がダイレクトメッセージに戻るとともに、ベータ版機能ではなくなりました +- Enhance: 画像編集にマスクエフェクト(塗りつぶし、ぼかし、モザイク)を追加 +- Enhance: 画像編集の集中線エフェクトを強化 +- Enhance: ウォーターマークにアカウントのQRコードを追加できるように +- Enhance: テーマをドラッグ&ドロップできるように +- Enhance: 絵文字ピッカーのサイズをより大きくできるように +- Enhance: カスタム絵文字が多い場合にサーバーの絵文字一覧ページがフリーズしないように +- Enhance: 時刻計算のための基準値を一か所で管理するようにし、パフォーマンスを向上 +- Enhance: 「お問い合わせ」ページから、バグの調査等に役立つ情報(OSやブラウザのバージョン等)を取得・コピーできるように +- Fix: iOSで、デバイスがダークモードだと初回読み込み時にエラーになる問題を修正 +- Fix: アクティビティウィジェットのグラフモードが動作しない問題を修正 +- Fix: ユニコード絵文字の追加辞書をインストールするとユニコード絵文字が絵文字ピッカーで検索できなくなる絵文字があるバグを修正 + +### Server +- Enhance: ユーザーIPを確実に取得できるために設定ファイルにFastifyOptions.trustProxyを追加しました + +## 2025.9.0 + +### Client +- Enhance: AiScriptAppウィジェットで構文エラーを検知してもダイアログではなくウィジェット内にエラーを表示するように +- Enhance: /flushページでサイトキャッシュをクリアできるようになりました +- Enhance: クリップ/リスト/アンテナ/ロール追加系メニュー項目において、表示件数を拡張 +- Enhance: 「キャッシュを削除」ボタンでブラウザの内部キャッシュの削除も行えるように +- Enhance: Ctrlキー(Commandキー)を押下しながらリンクをクリックすると新しいタブで開くように +- Fix: プッシュ通知を有効にできない問題を修正 +- Fix: RSSティッカーウィジェットが正しく動作しない問題を修正 +- Fix: プロファイルを復元後アカウントの切り替えができない問題を修正 +- Fix: エラー画像が横に引き伸ばされてしまう問題に対応 + +### Server +- Fix: webpなどの画像に対してセンシティブなメディアの検出が適用されていなかった問題を修正 + +## 2025.8.0 + +### Note +- サポートされるNode.jsの最小バージョンが**22.15.0**になりました + +### General +- ノートを削除した際、関連するノートが同時に削除されないようになりました + - APIで、「replyIdが存在しているのにreplyがnull」や「renoteIdが存在しているのにrenoteがnull」であるという、今までにはなかったパターンが表れることになります +- 定期的に古いリモートの投稿を削除する機能が実装されました + - コントロールパネル→パフォーマンス→Remote Notes Cleaning で有効化できます + - データベースの肥大化を防止することが可能です + - 既存のサーバーで当機能を有効化した場合は、処理量が多くなるため、一時的にストレージ使用量が増加する可能性があります。 + - 増加量を抑えるには、最大処理継続時間をデフォルトより短くしてください。 + - データベースサイズへの効果が見られない場合はautovacuumが有効になっているか確認してください +- サーバーの初期設定が完了するまでは連合がオンにならないようになりました +- 日本語における公開範囲名称の「ダイレクト」が「指名」に改称されました + - 実際の動作に即した名称になり、馴染みのない人でも理解しやすくなりました + - 他サービスにおける「ダイレクトメッセージ」に相当するMisskeyの機能は「チャット」ですが(過去のバージョンのMisskeyでも、当該機能は「チャット」ではなく「ダイレクトメッセージ」でした)、「ダイレクト投稿」という名称の機能が存在するとそちらがダイレクトメッセージ機能であるような誤解を生んでいました + - 今後、「チャット」の名称を「ダイレクトメッセージ」に戻す可能性があります +- mfm.jsをアップデートしました + - Enhance: Unicode 15.1 および 16.0 に収録されている絵文字に対応 + - Enhance: acctに `.` が入っているユーザーのメンションに対応 + - Fix: Unicode絵文字に隣接する異体字セレクタ(`U+FE0F`)が絵文字として認識される問題を修正 +- Enhance: ユーザー検索をロールポリシーで制限できるように + +### Client +- Feat: AiScriptが1.1.0に更新されました + - プラグインは1.xに対応したものが必要です + - Playはそのまま動作しますが、新規に作られるプリセットは1.xになります + - 以前のバージョンから無効化されていた note_view_interruptor が有効になりました + - ハンドラは同期的である必要があります +- Feat: セーフモード + - プラグイン・テーマ・カスタムCSSの使用でクライアントの起動に問題が発生した際に、これらを無効にして起動できます + - 以下の方法でセーフモードを起動できます + - `g` キーを連打する + - URLに`?safemode=true`を付ける + - PWAのショートカットで Safemode を選択して起動する +- Feat: 非ログイン時に表示されるトップページのスタイルを選択できるように + - コントロールパネル→ブランディング→エントランスページのスタイル +- Feat: ページのタブバーを下部に表示できるように +- Feat: (実験的)iOSでの触覚フィードバックを有効にできるように +- Feat: コントロールパネルを検索できるように +- Enhance: 「自動でもっと見る」オプションが有効になり、安定性が向上しました +- Enhance: トルコ語 (tr-TR) に対応 +- Enhance: 不必要な翻訳データを読み込まなくなり、パフォーマンスが向上しました +- Enhance: 画像エフェクトのパラメータ名の多言語対応 +- Enhance: ノートを非表示にする相対期間を1ヶ月単位で自由に指定できるように +- Enhance: メールアドレス確認画面のUIを改善 +- Enhance: アイコンのスクロール追従を無効化する際の適用範囲を強化 +- Enhance: レンダリングパフォーマンスの向上 +- Enhance: 依存ソフトウェアの更新 +- Fix: 投稿フォームでファイルのアップロードが中止または失敗した際のハンドリングを修正 +- Fix: 一部の設定検索結果が存在しないパスになる問題を修正 + (Cherry-picked from https://activitypub.software/TransFem-org/Sharkey/-/merge_requests/1171) +- Fix: テーマエディタが動作しない問題を修正 +- Fix: チャンネルのハイライトページにノートが表示されない問題を修正 +- Fix: カラムの名前が正しくリスト/チャンネルの名前にならない問題を修正 +- Fix: 複数のメンションを1行に記述した場合に、サジェストが正しく表示されない問題を修正 +- Fix: メンションとしての条件を満たしていても、特定の条件(`-`が含まれる場合など)で正しくサジェストされない問題を一部修正 +- Fix: ユーザーの前後ノートを閲覧する機能が動作しない問題を修正 +- Fix: 照会ダイアログでap/showでローカルユーザーを解決した際@username@nullに飛ばされる問題を修正 +- Fix: アイコンのデコレーションを付ける際にデコレーションが表示されなくなる問題を修正 +- Fix: タッチ操作時にマウスホバー時のユーザープレビューが開くことがある問題を修正 +- Fix: 管理中アカウント一覧で正しい表示が行われない問題を修正 +- Fix: lookupページでリモートURLを指定した際に正しく動作しない問題を修正 + +### Server +- Feat: サーバー管理コマンド + - `pnpm cli foo` の形式で実行可能です + - 現在以下のコマンドが利用可能です + - `reset-captcha` - CAPTCHA設定をリセットします +- Enhance: ノートの削除処理の効率化 +- Enhance: 全体的なパフォーマンスの向上 +- Enhance: 依存ソフトウェアの更新 +- Enhance: `clips/list` APIがページネーションに対応しました +- Fix: `notes/mentions` で場合によっては並び順が正しく返されない問題を修正 +- Fix: SystemWebhook設定でsecretを空に出来ない問題を修正 +- Fix: 削除されたユーザーがチャットメッセージにリアクションしている場合`chat/history`などでエラーになる問題を修正 +- Fix: Pageのアイキャッチ画像をドライブから消してもPageごと消えないように +- Fix: タイムラインAPIの withRenotes: false 時のレスポンスを修正 + + +## 2025.7.0 + +### Note +- Node.jsの最小バージョンを20.10.0から20.18.1に引き上げました + - なお、特に必要がない限りNode.jsは推奨バージョンであるv22を使用するようにしてください + +### General +- Feat: ノートの下書き機能 +- Feat: クリップ内でノートを検索できるように +- Feat: Playを検索できるように +- Feat: モデレーションにおいて、特定のドライブファイルを添付しているチャットメッセージを一覧できるように +- Enhance: ウォーターマーク機能をロールで制御可能に + +### Client +- Note: 「自動でもっと見る」オプションは無効になっています +- Feat: モデログを検索できるように +- Enhance: 設定の自動バックアップをオンにした直後に自動バックアップするように +- Enhance: ファイルアップロード前にキャプション設定を行えるように +- Enhance: ファイルアップロード時にセンシティブ設定されているか表示するように +- Enhance: 投稿フォームにファイルをペースト/ドロップした際のUXを改善 +- Enhance: ページネーション(一覧表示)の並び順を逆にできるように +- Enhance: ページネーション(一覧表示)の基準日時を指定できるように +- Enhance: レンダリングパフォーマンスの向上 +- Fix: ファイルがドライブの既定アップロード先に指定したフォルダにアップロードされない問題を修正 +- Fix: プラグインをアンインストールしてもセーブデータが残る問題を修正 +- Fix: 数時間後Misskeyのタブに戻った際に、タブがスロットリングされている間の更新アニメーションを延々見せ続けられる問題を修正 +- Fix: 非ログイン時のハイライトノートの画像がCWの有無を考慮せず表示される問題を修正 +- Fix: レンジ選択・ドロップダウンにて、操作を無効にすべきところで無効にならない問題を修正 +- Fix: Pull to refreshが有効なときに横スクロールができない問題を修正 + +### Server +- Enhance: sinceId/untilIdが指定可能なエンドポイントにおいて、sinceDate/untilDateも指定可能に +- Enhance: メールの送信者としてサーバー名を表示するように (サーバー名が設定されている場合) +- Fix: ジョブキューのProgressの値を正しく計算する + + +## 2025.6.3 + +### Client +- Fix: キャッシュを削除しないとクライアントが使用できないことがある問題を修正 + +## 2025.6.2 + +### Client +- Fix: キャッシュを削除しないとクライアントが使用できないことがある問題を修正 +- 翻訳の更新 + +## 2025.6.1 + +### Note +- AiScript Misskey拡張API(Misskey Webプラグイン)の[note_view_interruptor](https://misskey-hub.net/ja/docs/for-developers/plugin/plugin-api-reference/#pluginregister_note_view_interruptorfn)は不具合の影響により現在一時的に無効化されています。 +- Misskey Web投稿フォームのプレビュー切り替えは「...」メニュー内に配置されました + +### Client +- Feat: 画像にウォーターマークを付与できるようになりました +- Feat: 画像の加工ができるようになりました(実験的) +- Enhance: ノートのリアクション一覧で、押せるリアクションを優先して表示できるようにするオプションを追加 +- Enhance: 全てのチャットメッセージを既読にできるように(設定→その他) +- Enhance: ミュートした絵文字をデバイス間で同期できるように +- Fix: ドライブファイルの選択が不安定な問題を修正 +- Fix: コントロールパネルのファイル欄などのデザインが崩れている問題を修正 +- Fix: ユーザーの検索結果を追加で読み込むことができない問題を修正 +- Fix: タッチ操作時にチャートのツールチップが消えなくなる場合がある問題を修正 +- Fix: ウェルカムタイムラインでリアクションが表示されない問題を修正 +- Fix: デッキのタイムラインカラムで新着ノート時のサウンドが再生されない問題を修正 + +### Server +- Feat: 全てのチャットメッセージを既読にするAPIを追加(chat/read-all) +- Fix: アカウント削除が正常に行われないことがあった問題を修正 +- Fix: outboxのページネーションが正しく行われない問題を修正 + +### Misskey.js +- Fix: misskey-jsの drive/file/create でファイルアップロードができない問題を修正 + +## 2025.6.0 + +### Client +- Enhance: 非同期的なコンポーネントの読み込み時のハンドリングを強化 +- Fix: リアクションの一部の絵文字が重複して表示されることがある問題を修正 +- Fix: 非利用者に対するユーザー作成コンテンツの公開範囲が全て非公開になっている場合にログインできない問題を修正 + +### Server +- Fix: 非利用者に対するユーザー作成コンテンツの公開範囲が全て非公開になっている場合でもusers/showを許可するように + +## 2025.5.1 + +### Note +- 設定ファイルの以下の項目がコントロールパネルから設定するようになりました + - signToActivityPubGet + - proxyRemoteFiles + - disallowExternalApRedirect + - 許可しないかどうかではなく、許可するかどうかの設定(allowExternalApRedirect)になりました + +### General +- Feat: 非ログインでサーバーを閲覧された際に、サーバー内のコンテンツを非公開にすることができるようになりました + - モデレーションが行き届きにくい不適切なリモートコンテンツなどが、自サーバー経由で図らずもインターネットに公開されてしまうことによるトラブル防止などに役立ちます + - 「全て公開(今までの挙動)」「ローカルのコンテンツだけ公開(=サーバー内で受信されたリモートのコンテンツは公開しない)」「何も公開しない」から選択できます + - デフォルト値は「ローカルのコンテンツだけ公開」になっています +- Feat: ロールでアップロード可能なファイル種別を設定可能になりました + - デフォルトは**テキスト、JSON、画像、動画、音声ファイル**になっています。zipなど、その他の種別のファイルは含まれていないため、必要に応じて設定を変更してください。 + - 場合によってはファイル種別を正しく検出できないことがあります(特にテキストフォーマット)。その場合、ファイル種別は application/octet-stream と見做されます。 + - したがって、それらの種別不明ファイルを許可したい場合は application/octet-stream を指定に追加してください。 +- Feat: プレビュー先がリダイレクトを伴う場合、リダイレクト先のコンテンツを取得しに行くか否かを設定できるように(#16043) +- Enhance: UIのアイコンデータの読み込みを軽量化 + +### Client +- Feat: ドライブのUIが強化されました + - 複数のファイルをまとめて移動できるようになりました +- Feat: ファイルのアップロードUIが一新されました + - アップロード前にファイル情報を確認できるようになりました + - 圧縮の品質を選択できるようになりました + - アップロードに失敗したときに再試行できるようになりました + - アップロード前に画像のクロッピングを行えるようになりました + - ファイルサイズのチェックは圧縮後の実際にアップロードされるサイズで行われるようになりました + - ファイルのアップロードを中断できるようになりました +- Feat: サーバー初期設定ウィザードが実装されました + - 簡単なウィザードに従うだけで、サーバーに最適な設定が適用されます +- Feat: Websocket接続を行わずにMisskeyを利用するNo Websocketモードが実装されました(beta) + - サーバーのパフォーマンス向上に寄与することが期待されます + - 何らの理由によりWebsocket接続が行えない環境でも快適に利用可能です + - 従来のWebsocket接続を行うモードはリアルタイムモードとして再定義されました + - チャットなど、一部の機能は引き続き設定に関わらずWebsocket接続が行われます +- Feat: 絵文字をミュート可能にする機能 + - 絵文字(ユニコードの絵文字・カスタム絵文字)毎にミュートし、不可視化することができるようになりました +- Feat: モバイルデバイスで折りたたまれたUIの展開表示に全画面ページを使用できるように(実験的) +- Enhance: 設定の同期をオンにするときに競合したときに値をマージできるように +- Enhance: メモリ使用量を軽減しました +- Enhance: 画像の高品質なプレースホルダを無効化してパフォーマンスを向上させるオプションを追加 +- Enhance: 招待されているが参加していないルームを開いたときに、招待を承認するかどうか尋ねるように +- Enhance: リプライ元にアンケートがあることが表示されるように +- Enhance: ノートのサーバー情報のデザインを改善・パフォーマンス向上 + (Based on https://github.com/taiyme/misskey/pull/198, https://github.com/taiyme/misskey/pull/211, https://github.com/taiyme/misskey/pull/283) +- Enhance: ユーザー設定でURLプレビューを無効化できるように +- Enhance: ヒントとコツを追加 +- Enhance: ヒントとコツを再表示できるように +- Enhance: AiScriptからtoastを表示する関数 `Mk:toast` を追加 +- Enhance: シンタックスハイライトのエンジンをJavaScriptベースのものに変更 + - フロントエンドの読み込みサイズを軽量化しました + - ほとんどの言語のハイライトは問題なく行えますが、互換性の問題により一部の言語が正常にハイライトできなくなる可能性があります。詳しくは https://shiki.style/references/engine-js-compat をご覧ください。 +- Fix: チャットに動画ファイルを送付すると、動画の表示が崩れてしまい視聴出来ない問題を修正 +- Fix: アカウント依存かつ初期状態である設定値をサーバー同期しようとした際に正しくコンフリクト検出されない問題を修正 +- Fix: "時計"ウィジェット(Clock)において、Transparent設定が有効でも、その背景が透過されない問題を修正 +- Fix: 一定時間操作がなかったら動画プレイヤーのコントロールを隠すように +- Fix: Twitchのクリップがプレイヤーで再生できない問題を修正 + +### Server +- Enhance: リストやフォローをエクスポートする際にリプライを含むかどうかの情報を含むように +- Enhance: チャットルームの最大メンバー数を30人から50人に調整 +- Enhance: ノートのレスポンスにアンケートが添付されているかどうかを示すフラグ`hasPoll`を追加 +- Enhance: チャットルームのレスポンスに招待されているかどうかを示すフラグ`invitationExists`を追加 +- Enhance: レートリミットの計算方法を調整 (#13997) +- Enhance: 外部サイトのOGPのキャッシュ期間を調整 +- Fix: チャットルームが削除された場合・チャットルームから抜けた場合に、未読状態が残り続けることがあるのを修正 +- Fix: ユーザ除外アンテナをインポートできない問題を修正 +- Fix: アンテナのセンシティブなチャンネルのノートを含むかどうかの情報がエクスポートされない問題を修正 +- Fix: ミュート対象ユーザーが引用されているノートがRNされたときにミュートを貫通してしまう問題を修正 #16009 +- Fix: 連合モードが「なし」の場合に、生成されるHTML内のactivity jsonへのリンクタグを省略するように +- Fix: コントロールパネルから招待コードを作成すると作成者の情報が記録されない問題を修正 +- Fix: コントロールパネルのジョブキューページからPausedなジョブ一覧を閲覧できない問題を修正 + ## 2025.5.0 ### Note diff --git a/CHANGELOG_CHERRYPICK.md b/CHANGELOG_CHERRYPICK.md index 3f1c403e93..7eda132131 100644 --- a/CHANGELOG_CHERRYPICK.md +++ b/CHANGELOG_CHERRYPICK.md @@ -1,28 +1,117 @@ - - -# 릴리스 노트 -이 문서는 CherryPick의 변경 사항만 포함합니다. - ## 4.16.0 출시일: 2025/6/15
기반 Misskey 버전: 2025.5.0
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 25bc1e8d51..2d800ef95d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -258,6 +258,12 @@ CherryPick uses Vue(v3) as its front-end framework. - **When creating a new component, please use the Composition API (with [setup sugar](https://v3.vuejs.org/api/sfc-script-setup.html) and [ref sugar](https://github.com/vuejs/rfcs/discussions/369)) instead of the Options API.** - Some of the existing components are implemented in the Options API, but it is an old implementation. Refactors that migrate those components to the Composition API are also welcome. +## Tabler Icons +アイコンは、Production Build時に使用されていないものが削除されるようになっています。 + +**アイコンを動的に設定する際には、 `ti-${someVal}` のような、アイコン名のみを動的に変化させる実装を行わないでください。** +必ず `ti-xxx` のような完全なクラス名を含めるようにしてください。 + ## nirax niraxは、CherryPickで使用しているオリジナルのフロントエンドルーティングシステムです。 **vue-routerから影響を多大に受けているので、まずはvue-routerについて学ぶことをお勧めします。** @@ -575,27 +581,6 @@ pnpm dlx typeorm migration:generate -d ormconfig.js -o - 生成後、ファイルをmigration下に移してください - 作成されたスクリプトは不必要な変更を含むため除去してください -### JSON SchemaのobjectでanyOfを使うとき -JSON Schemaで、objectに対してanyOfを使う場合、anyOfの中でpropertiesを定義しないこと。 -バリデーションが効かないため。(SchemaTypeもそのように作られており、objectのanyOf内のpropertiesは捨てられます) -https://github.com/misskey-dev/misskey/pull/10082 - -テキストhogeおよびfugaについて、片方を必須としつつ両方の指定もありうる場合: - -```ts -export const paramDef = { - type: 'object', - properties: { - hoge: { type: 'string', minLength: 1 }, - fuga: { type: 'string', minLength: 1 }, - }, - anyOf: [ - { required: ['hoge'] }, - { required: ['fuga'] }, - ], -} as const; -``` - ### コネクションには`markRaw`せよ **Vueのコンポーネントのdataオプションとして**cherrypick.jsのコネクションを設定するとき、必ず`markRaw`でラップしてください。インスタンスが不必要にリアクティブ化されることで、cherrypick.js内の処理で不具合が発生するとともに、パフォーマンス上の問題にも繋がる。なお、Composition APIを使う場合はこの限りではない(リアクティブ化はマニュアルなため)。 @@ -633,3 +618,25 @@ color: hsl(from var(--MI_THEME-accent) h s calc(l - 10)); color: color(from var(--MI_THEME-accent) srgb r g b / 0.5); ``` +## 考え方 +この内容はMisskeyに限定されたもので、CherryPickの意思を代表しません。 + +### DRYに囚われるな +必要なのは一般化ではなく抽象化と考えます。 +盲信せず、誤った・不必要な共通化は避け、それが自然だと感じる場合は重複させる勇気を持ちましょう。 + +### Misskeyを複雑にしない実装 +それがいくら複雑であっても、Misskey固有のコンテキストと関心が分離されている(もしくは事実上分離されていると見做すことができる)実装であれば、それはMisskeyのコードベースに対する複雑性に影響を与えないと考えます。 + +例えるなら、VueやAiScriptといったMisskeyが使用しているライブラリの内部実装がいくら複雑だったとしても、「それを使用しているからMisskeyの実装は複雑である」ということにはならないのと同じです。 + +Misskeyのドメイン知識から関心が分離されているということは、Misskeyの実装について考える時にそれらの内部実装を考慮する必要が無く、認知負荷を増やさないからです。 + +また重要な点は、その実装が、Misskeyリポジトリの外部にあるか・内部にあるかということや、Misskeyがメンテナンスするものか・第三者がメンテナンスするものかといったことは複雑性を考える上ではほとんど無視できるという点です。 + +もちろんその実装がMisskeyリポジトリにあり、Misskeyがメンテナンスしなければならないものは、保守のコストはかかります。 +しかし、Misskeyの本質的な設計・実装という観点で見たときは、その実装は実質的に外部ライブラリのように振る舞います。 +換言すれば「たまたまMisskeyの開発者と同じ人たちがメンテナンスしているし、たまたまMisskeyのリポジトリ内に置いてあるだけの外部ライブラリ」です。 + +そのため、実装をなるべくMisskeyのドメイン知識から独立したものにすれば、Misskeyのコードベースの複雑性を上げることなく機能実装を行うことができ、お得であると言えます。 +もちろんそれにこだわって、些細な実装でもそのように分離してしまうとかえって認知負荷が増えたり、実装量が増えてメリットをデメリットが上回る場合もあるので、ケースバイケースではあります。 diff --git a/Dockerfile b/Dockerfile index b3f2f7a7fa..d4acec7dd9 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,6 @@ # syntax = docker/dockerfile:1.4 -ARG NODE_VERSION=22.15.0-bookworm +ARG NODE_VERSION=24.10.0-bookworm # build assets & compile TypeScript @@ -18,10 +18,13 @@ WORKDIR /cherrypick COPY --link ["pnpm-lock.yaml", "pnpm-workspace.yaml", "package.json", "./"] COPY --link ["scripts", "./scripts"] +COPY --link ["patches", "./patches"] COPY --link ["packages/backend/package.json", "./packages/backend/"] COPY --link ["packages/frontend-shared/package.json", "./packages/frontend-shared/"] COPY --link ["packages/frontend/package.json", "./packages/frontend/"] COPY --link ["packages/frontend-embed/package.json", "./packages/frontend-embed/"] +COPY --link ["packages/frontend-builder/package.json", "./packages/frontend-builder/"] +COPY --link ["packages/icons-subsetter/package.json", "./packages/icons-subsetter/"] COPY --link ["packages/sw/package.json", "./packages/sw/"] COPY --link ["packages/cherrypick-js/package.json", "./packages/cherrypick-js/"] COPY --link ["packages/misskey-reversi/package.json", "./packages/misskey-reversi/"] @@ -52,6 +55,7 @@ WORKDIR /cherrypick COPY --link ["pnpm-lock.yaml", "pnpm-workspace.yaml", "package.json", "./"] COPY --link ["scripts", "./scripts"] +COPY --link ["patches", "./patches"] COPY --link ["packages/backend/package.json", "./packages/backend/"] COPY --link ["packages/cherrypick-js/package.json", "./packages/cherrypick-js/"] COPY --link ["packages/misskey-reversi/package.json", "./packages/misskey-reversi/"] diff --git a/chart/files/default.yml b/chart/files/default.yml index 58ed547892..502651014e 100644 --- a/chart/files/default.yml +++ b/chart/files/default.yml @@ -230,9 +230,6 @@ id: "aidx" # Media Proxy #mediaProxy: https://example.com/proxy -# Sign to ActivityPub GET request (default: true) -signToActivityPubGet: true - #allowedPrivateNetworks: [ # '127.0.0.1/32' #] diff --git a/cypress.config.ts b/cypress.config.ts index e390c41a54..361acaf6e5 100644 --- a/cypress.config.ts +++ b/cypress.config.ts @@ -2,11 +2,6 @@ import { defineConfig } from 'cypress' export default defineConfig({ e2e: { - // We've imported your old cypress plugins here. - // You may want to clean this up later by importing these. - setupNodeEvents(on, config) { - return require('./cypress/plugins/index.js')(on, config) - }, baseUrl: 'http://localhost:61812', }, }) diff --git a/cypress/e2e/basic.cy.ts b/cypress/e2e/basic.cy.ts index 2781157459..5561a9c9ef 100644 --- a/cypress/e2e/basic.cy.ts +++ b/cypress/e2e/basic.cy.ts @@ -31,6 +31,14 @@ describe('Before setup instance', () => { // なぜか動かない //cy.wait('@signup').should('have.property', 'response.statusCode'); cy.wait('@signup'); + + cy.intercept('POST', '/api/admin/update-meta').as('update-meta'); + + cy.get('[data-cy-next]').click(); + cy.get('[data-cy-server-name] input').type('Testskey'); + cy.get('[data-cy-server-setup-wizard-apply]').click(); + + cy.wait('@update-meta'); }); }); @@ -70,6 +78,8 @@ describe('After setup instance', () => { cy.get('[data-cy-signup-password] input').type('alice1234'); cy.get('[data-cy-signup-submit]').should('be.disabled'); cy.get('[data-cy-signup-password-retype] input').type('alice1234'); + cy.get('[data-cy-signup-submit]').should('be.disabled'); + cy.get('[data-cy-signup-invitation-code] input').type('test-invitation-code'); cy.get('[data-cy-signup-submit]').should('not.be.disabled'); cy.get('[data-cy-signup-submit]').click(); diff --git a/cypress/plugins/index.js b/cypress/plugins/index.js deleted file mode 100644 index 59b2bab6e4..0000000000 --- a/cypress/plugins/index.js +++ /dev/null @@ -1,22 +0,0 @@ -/// -// *********************************************************** -// This example plugins/index.js can be used to load plugins -// -// You can change the location of this file or turn off loading -// the plugins file with the 'pluginsFile' configuration option. -// -// You can read more here: -// https://on.cypress.io/plugins-guide -// *********************************************************** - -// This function is called when a project is opened or re-opened (e.g. due to -// the project's config changing) - -/** - * @type {Cypress.PluginConfig} - */ -// eslint-disable-next-line no-unused-vars -module.exports = (on, config) => { - // `on` is used to hook into various events Cypress emits - // `config` is the resolved Cypress config -} diff --git a/idea/MkAbuseReport.stories.impl.ts b/idea/MkAbuseReport.stories.impl.ts index bcbda133f6..138e5cd0cd 100644 --- a/idea/MkAbuseReport.stories.impl.ts +++ b/idea/MkAbuseReport.stories.impl.ts @@ -3,7 +3,8 @@ * SPDX-License-Identifier: AGPL-3.0-only */ -import { action } from '@storybook/addon-actions'; +/* eslint-disable @typescript-eslint/explicit-function-return-type */ +import { action } from 'storybook/actions'; import type { StoryObj } from '@storybook/vue3'; import { HttpResponse, http } from 'msw'; import { abuseUserReport } from '../packages/frontend/.storybook/fakes.js'; diff --git a/idea/MkAnimatedBg.dotted-ripples.vue b/idea/MkAnimatedBg.dotted-ripples.vue new file mode 100644 index 0000000000..f8f809c8ce --- /dev/null +++ b/idea/MkAnimatedBg.dotted-ripples.vue @@ -0,0 +1,232 @@ + + + + + + + diff --git a/idea/MkAnimatedBg.dotted.vue b/idea/MkAnimatedBg.dotted.vue new file mode 100644 index 0000000000..7f68b8972a --- /dev/null +++ b/idea/MkAnimatedBg.dotted.vue @@ -0,0 +1,190 @@ + + + + + + + diff --git a/locales/ar-SA.yml b/locales/ar-SA.yml index 8123edf167..bf8dad6db6 100644 --- a/locales/ar-SA.yml +++ b/locales/ar-SA.yml @@ -68,7 +68,7 @@ receiveFollowRequest: "تلقيت طلب متابعة" followRequestAccepted: "قُبل طلب المتابعة" mention: "أشر الى" mentions: "الإشارات" -directNotes: "الملاحظات المباشرة" +directNotes: "رسالة خاصة" importAndExport: "إستورد / صدر" import: "استيراد" export: "تصدير" @@ -215,7 +215,6 @@ noUsers: "ليس هناك مستخدمون" editProfile: "تعديل الملف التعريفي" noteDeleteConfirm: "هل تريد حذف هذه الملاحظة؟" pinLimitExceeded: "لا يمكنك تثبيت الملاحظات بعد الآن." -intro: "لقد انتهت عملية تنصيب CherryPick. الرجاء إنشاء حساب إداري." done: "تمّ" processing: "المعالجة جارية" preview: "معاينة" @@ -1022,6 +1021,9 @@ lastNDays: "آخر {n} أيام" surrender: "ألغِ" postForm: "أنشئ ملاحظة" information: "عن" +inMinutes: "د" +inDays: "ي" +widgets: "التطبيقات المُصغّرة" _chat: invitations: "دعوة" noHistory: "السجل فارغ" @@ -1266,7 +1268,6 @@ _theme: buttonBg: "خلفية الأزرار" buttonHoverBg: "خلفية الأزرار (عند التمرير فوقها)" inputBorder: "حواف حقل الإدخال" - driveFolderBg: "خلفية مجلد قرص التخزين" messageBg: "خلفية المحادثة" _sfx: note: "الملاحظات" @@ -1606,3 +1607,21 @@ _search: searchScopeAll: "الكل" searchScopeLocal: "المحلي" searchScopeUser: "مستخدم محدد" +_watermarkEditor: + opacity: "الشفافية" + scale: "الحجم" + text: "نص" + position: "الموضع" + type: "نوع" + image: "صور" + advanced: "متقدم" +_imageEffector: + _fxProps: + scale: "الحجم" + size: "الحجم" + offset: "الموضع" + color: "اللون" + opacity: "الشفافية" +_qr: + showTabTitle: "المظهر" + raw: "نص" diff --git a/locales/bn-BD.yml b/locales/bn-BD.yml index 825133da0a..e6a3847b23 100644 --- a/locales/bn-BD.yml +++ b/locales/bn-BD.yml @@ -215,7 +215,6 @@ noUsers: "কোন ব্যাবহারকারী নেই" editProfile: "প্রোফাইল সম্পাদনা করুন" noteDeleteConfirm: "আপনি কি নোট ডিলিট করার ব্যাপারে নিশ্চিত?" pinLimitExceeded: "আপনি আর কোন নোট পিন করতে পারবেন না" -intro: "CherryPick এর ইন্সটলেশন সম্পন্ন হয়েছে!দয়া করে অ্যাডমিন ইউজার তৈরি করুন।" done: "সম্পন্ন" processing: "প্রক্রিয়াধীন..." preview: "পূর্বরূপ দেখুন" @@ -861,6 +860,9 @@ sourceCode: "সোর্স কোড" flip: "উল্টান" postForm: "নোট লিখুন" information: "আপনার সম্পর্কে" +inMinutes: "মিনিট" +inDays: "দিন" +widgets: "উইজেটগুলি" _chat: invitations: "আমন্ত্রণ" noHistory: "কোনো ইতিহাস নেই" @@ -1094,7 +1096,6 @@ _theme: buttonBg: "বাটনের পটভূমি" buttonHoverBg: "বাটনের পটভূমি (হভার)" inputBorder: "ইনপুট ফিল্ডের বর্ডার" - driveFolderBg: "ড্রাইভ ফোল্ডারের পটভূমি" badge: "ব্যাজ" messageBg: "চ্যাটের পটভূমি" fgHighlighted: "হাইলাইট করা পাঠ্য" @@ -1430,3 +1431,19 @@ _remoteLookupErrors: _search: searchScopeAll: "সবগুলো" searchScopeLocal: "স্থানীয়" +_watermarkEditor: + opacity: "অস্বচ্ছতা" + scale: "আকার" + text: "লেখা" + image: "ছবি" + advanced: "উন্নত" +_imageEffector: + _fxProps: + scale: "আকার" + size: "আকার" + color: "রং" + opacity: "অস্বচ্ছতা" + lightness: "উজ্জ্বল করুন" +_qr: + showTabTitle: "প্রদর্শন" + raw: "লেখা" diff --git a/locales/ca-ES.yml b/locales/ca-ES.yml index a40dd6a050..a2e2c93783 100644 --- a/locales/ca-ES.yml +++ b/locales/ca-ES.yml @@ -251,9 +251,9 @@ noUsers: "No hi ha usuaris" editProfile: "Edita el perfil" noteDeleteConfirm: "Segur que voleu eliminar aquesta publicació?" pinLimitExceeded: "No podeu fixar més publicacions" -intro: "La instal·lació de CherryPick ha acabat! Crea un usuari d'administrador." done: "Fet" processing: "S'està processant..." +preprocessing: "Preparant" preview: "Vista prèvia" default: "Per defecte" defaultValueIs: "Per defecte: {value}" @@ -299,6 +299,7 @@ uploadFromUrl: "Carrega des d'un enllaç" uploadFromUrlDescription: "Enllaç del fitxer que vols carregar" uploadFromUrlRequested: "Càrrega sol·licitada" uploadFromUrlMayTakeTime: "La càrrega des de l'enllaç pot trigar un temps" +uploadNFiles: "Pujar {n} arxius" explore: "Explora" messageRead: "Vist" noMoreHistory: "No hi ha res més per veure" @@ -327,11 +328,13 @@ dark: "Fosc" lightThemes: "Temes clars" darkThemes: "Temes foscos" syncDeviceDarkMode: "Sincronitza el mode fosc amb la configuració del dispositiu" +switchDarkModeManuallyWhenSyncEnabledConfirm: "\"{x}\" es troba activat. Vols desactivar la sincronització i canviar de mode manualment?" drive: "Disc" fileName: "Nom del Fitxer" selectFile: "Selecciona un fitxer" selectFiles: "Selecciona fitxers" selectFolder: "Selecció de carpeta" +unselectFolder: "Deixa de seleccionar la carpeta" selectFolders: "Selecció de carpetes" fileNotSelected: "Cap fitxer seleccionat" renameFile: "Canvia el nom del fitxer" @@ -344,6 +347,7 @@ addFile: "Afegeix un fitxer" showFile: "Mostrar fitxer" emptyDrive: "El teu Disc és buit" emptyFolder: "La carpeta està buida" +dropHereToUpload: "Arrossega els arxius fins aquí per pujar-los al servidor" unableToDelete: "No es pot eliminar" inputNewFileName: "Introduïu el nom de fitxer nou" inputNewDescription: "Escriu el peu de foto." @@ -576,8 +580,10 @@ showFixedPostForm: "Mostrar el formulari per escriure a l'inici de la línia de showFixedPostFormInChannel: "Mostrar el formulari d'escriptura al principi de la línia de temps (Canals)" withRepliesByDefaultForNewlyFollowed: "Inclou les respostes d'usuaris nous que segueixes a la línia de temps per defecte." newNoteRecived: "Hi ha publicacions noves" +newNote: "Notes noves" sounds: "Sons" sound: "So" +notificationSoundSettings: "Configuració del so de notificació" listen: "Escoltar" none: "Res" showInPage: "Mostrar a la pàgina " @@ -645,7 +651,7 @@ disablePlayer: "Tanca el reproductor de vídeo" expandPost: "Expandir post" themeEditor: "Editor de temes" description: "Descripció" -describeFile: "Afegeix una descripció " +describeFile: "Afegir text alternatiu" enterFileDescription: "Escriu un peu de foto" author: "Autor" leaveConfirm: "Hi ha canvis sense guardar. Els vols descartar?" @@ -769,6 +775,7 @@ lockedAccountInfo: "Tret que establiu la visibilitat de la nota a \"Només segui alwaysMarkSensitive: "Marcar com a sensible per defecte" loadRawImages: "Carregar les imatges originals en comptes de miniatures " disableShowingAnimatedImages: "No reproduir imatges animades" +disableShowingAnimatedImages_caption: "Si les imatges animades no es reprodueixen, independentment d'aquesta configuració, és possible que la configuració d'accessibilitat del navegador i el sistema operatiu, els modes d'estalvi d'energia i similars estiguin interferint." highlightSensitiveMedia: "Ressalta els medis marcats com a sensibles" verificationEmailSent: "S'ha enviat un correu electrònic de verificació. Fes clic a l'enllaç per completar la verificació." notSet: "Sense definir" @@ -793,6 +800,7 @@ wide: "Gran" narrow: "Estret" reloadToApplySetting: "Aquest ajust només s'aplicarà després de recarregar la pàgina. Vols fer-ho ara?" needReloadToApply: "Es requereix recarregar per reflectir aquesta opció " +needToRestartServerToApply: "És necessari reiniciar el servidor perquè tinguin efecte els canvis." showTitlebar: "Mostra la barra del títol " clearCache: "Esborra la memòria cau" onlineUsersCount: "{n} Usuaris es troben en línia " @@ -893,7 +901,7 @@ searchResult: "Resultats de la cerca" hashtags: "Etiquetes" troubleshooting: "Solucionar problemes" useBlurEffect: "Fes servir efectes de desenfocament a la interfície" -learnMore: "Saber més " +learnMore: "Saber-ne més " misskeyUpdated: "CherryPick s'ha actualitzat " whatIsNew: "Mostra canvis" translate: "Traduir " @@ -999,6 +1007,7 @@ failedToUpload: "Ha fallat la pujada" cannotUploadBecauseInappropriate: "Aquest fitxer no es pot pujar perquè s'ha trobat que algunes parts són inapropiades." cannotUploadBecauseNoFreeSpace: "Ha fallat la pujada del fitxer perquè no hi ha capacitat al Disc." cannotUploadBecauseExceedsFileSizeLimit: "Aquest fitxer no es pot pujar perquè supera la mida permesa." +cannotUploadBecauseUnallowedFileType: "Impossible pujar l'arxiu no és un tipus de fitxer autoritzat." beta: "Proves" enableAutoSensitive: "Marcar com a sensible automàticament " enableAutoSensitiveDescription: "Permet la detecció i el marcat automàtic dels mitjans sensibles fent servir aprenentatge automàtic quan sigui possible. Si aquesta opció es troba desactivada potser que estigui activada per a tota la instància. " @@ -1050,6 +1059,7 @@ permissionDeniedError: "Operació no permesa " permissionDeniedErrorDescription: "Aquest compte no té suficients permisos per dur a terme aquesta acció " preset: "Predefinit" selectFromPresets: "Escull des dels predefinits" +custom: "Personalitzat" achievements: "Assoliments" gotInvalidResponseError: "Resposta del servidor invàlida " gotInvalidResponseErrorDescription: "No es pot contactar amb el servidor o potser es troba fora de línia per manteniment. Provar-ho de nou més tard." @@ -1088,6 +1098,7 @@ prohibitedWordsDescription2: "Fent servir espais crearà expressions AND si l'ex hiddenTags: "Etiquetes ocultes" hiddenTagsDescription: "La visibilitat de totes les notes que continguin qualsevol de les paraules configurades seran, automàticament, afegides a \"Inici\". Pots llistar diferents paraules separant les per línies noves." notesSearchNotAvailable: "La cerca de notes no es troba disponible." +usersSearchNotAvailable: "La cerca d'usuaris no està disponible." license: "Llicència" unfavoriteConfirm: "Esborrar dels favorits?" myClips: "Els meus retalls" @@ -1162,6 +1173,7 @@ installed: "Instal·lats " branding: "Marca" enableServerMachineStats: "Publicar estadístiques del maquinari del servidor" enableIdenticonGeneration: "Activar la generació d'icones d'identificació " +showRoleBadgesOfRemoteUsers: "Mostrar insígnies de rols d'instàncies remotes " turnOffToImprovePerformance: "Desactivant aquesta opció es pot millorar el rendiment." createInviteCode: "Crear codi d'invitació " createWithOptions: "Crear invitació amb opcions" @@ -1238,9 +1250,8 @@ showAvatarDecorations: "Mostrar les decoracions dels avatars" releaseToRefresh: "Deixar anar per actualitzar" refreshing: "Recarregant..." pullDownToRefresh: "Llisca cap a baix per recarregar" -disableStreamingTimeline: "Desactivar l'actualització en temps real de les línies de temps" useGroupedNotifications: "Mostrar les notificacions agrupades " -signupPendingError: "Hi ha hagut un problema verificant l'adreça de correu electrònic. L'enllaç pot haver caducat." +emailVerificationFailedError: "Hem tingut un problema en verificar la teva adreça de correu electrònic. És probable que l'enllaç estigui caducat." cwNotationRequired: "Si està activat \"Amagar contingut\" s'ha d'escriure una descripció " doReaction: "Afegeix una reacció " code: "Codi" @@ -1310,6 +1321,8 @@ availableRoles: "Roles disponibles " acknowledgeNotesAndEnable: "Activa'l després de comprendre els possibles perills." federationSpecified: "Aquest servidor treballa amb una federació de llistes blanques. No pot interactuar amb altres servidors que no siguin els especificats per l'administrador." federationDisabled: "La unió es troba deshabilitada en aquest servidor. No es pot interactuar amb usuaris d'altres servidors." +draft: "Esborrany " +draftsAndScheduledNotes: "Esborranys i publicacions programades" confirmOnReact: "Confirmar en reaccionar" reactAreYouSure: "Vols reaccionar amb \"{emoji}\"?" markAsSensitiveConfirm: "Vols marcar aquest contingut com a sensible?" @@ -1327,6 +1340,7 @@ restore: "Restaurar " syncBetweenDevices: "Sincronització entre dispositius" preferenceSyncConflictTitle: "Els valors de la configuració ja existeixen al dispositiu" preferenceSyncConflictText: "Un element de la configuració amb sincronització activada desa els seus valors al servidor, però s'ha trobat un valor a la configuració desat al servidor per aquest element de la configuració. Quin valor us sobreescriure?" +preferenceSyncConflictChoiceMerge: "Integració " preferenceSyncConflictChoiceServer: "Valors de configuració del servidor" preferenceSyncConflictChoiceDevice: "Punts d'ajustos del dispositiu " preferenceSyncConflictChoiceCancel: "Cancel·lar l'activació de la sincronització " @@ -1336,6 +1350,8 @@ postForm: "Formulari de publicació" textCount: "Nombre de caràcters " information: "Informació" chat: "Xat" +directMessage: "Xateja amb aquest usuari" +directMessage_short: "Missatge" migrateOldSettings: "Migrar la configuració anterior" migrateOldSettings_description: "Normalment això es fa automàticament, però si la transició no es fa, el procés es pot iniciar manualment. S'esborrarà la configuració actual." compress: "Comprimir " @@ -1346,10 +1362,55 @@ embed: "Incrustar" settingsMigrating: "Estem migrant la teva configuració. Si us plau espera un moment... (També pots fer la migració més tard, manualment, anant a Preferències → Altres → Migrar configuració antiga)" readonly: "Només lectura" goToDeck: "Tornar al tauler" -federationJobs: "Treballs sindicats " +federationJobs: "Treballs de federació" driveAboutTip: "Al Disc veure's una llista de tots els arxius que has anat pujant.
\nPots tornar-los a fer servir adjuntant-los a notes noves o pots adelantar-te i pujar arxius per publicar-los més tard!
\nTingués en compte que si esborres un arxiu també desapareixerà de tots els llocs on l'has fet servir (notes, pàgines, avatars, imatges de capçalera, etc.)
\nTambé pots crear carpetes per organitzar les." scrollToClose: "Desplaçar per tancar" +advice: "Consell" +realtimeMode: "Mode en temps real" +turnItOn: "Activar" +turnItOff: "Desactivar" +emojiMute: "Silenciar emojis" +emojiUnmute: "Deixar de silenciar emojis" +muteX: "Silenciar {x}" +unmuteX: "Deixar de silenciar {x}" +abort: "Cancel·lar" +tip: "Trucs i consells" +redisplayAllTips: "Torna ha mostrat tots els trucs i consells" +hideAllTips: "Amagar tots els trucs i consells" +defaultImageCompressionLevel: "Nivell de comprensió de la imatge per defecte" +defaultImageCompressionLevel_description: "Baixa, conserva la qualitat de la imatge però la mida de l'arxiu és més gran.
Alta, redueix la mida de l'arxiu però també la qualitat de la imatge." +defaultCompressionLevel: "Nivell de compressió predeterminat" +defaultCompressionLevel_description: "Si el redueixes augmentaràs la qualitat de la imatge, però la mida de l'arxiu serà més gran.
Si augmentes l'opció redueixes la mida de l'arxiu i la qualitat de la imatge és pitjor." +inMinutes: "Minut(s)" +inDays: "Di(a)(es)" +safeModeEnabled: "Mode segur activat" +pluginsAreDisabledBecauseSafeMode: "Els afegits no estan activats perquè el mode segur està activat." +customCssIsDisabledBecauseSafeMode: "El CSS personalitzat no s'aplica perquè el mode segur es troba activat." +themeIsDefaultBecauseSafeMode: "El tema predeterminat es farà servir mentre el mode segur estigui activat. Una vegada es desactivi el mode segur es restablirà el tema escollit." +thankYouForTestingBeta: "Gràcies per ajudar-nos a provar la versió beta!" +createUserSpecifiedNote: "Crear notes especificades per l'usuari " +schedulePost: "Programar una nota" +scheduleToPostOnX: "Programar una nota per {x}" +scheduledToPostOnX: "S'ha programat la nota per {x}" +schedule: "Programa" +scheduled: "Programat" +widgets: "Ginys" +deviceInfo: "Informació del dispositiu" +deviceInfoDescription: "En fer consultes tècniques influir la següent informació pot ajudar a resoldre'l més ràpidament." +_compression: + _quality: + high: "Qualitat alta" + medium: "Qualitat mitjana" + low: "Qualitat baixa" + _size: + large: "Mida gran" + medium: "Mida mitjana" + small: "Mida petita" +_order: + newest: "Més recent" + oldest: "Antigues primer" _chat: + messages: "Missatge" noMessagesYet: "Encara no tens missatges " newMessage: "Missatge nou" individualChat: "Xat individual " @@ -1382,6 +1443,8 @@ _chat: chatNotAvailableInOtherAccount: "La funció de xat es troba desactivada al compte de l'altre usuari." cannotChatWithTheUser: "No pots xatejar amb aquest usuari" cannotChatWithTheUser_description: "El xat està desactivat o l'altra part encara no l'ha obert." + youAreNotAMemberOfThisRoomButInvited: "No participes en aquesta sala, però has rebut una invitació. Per participar accepta la invitació." + doYouAcceptInvitation: "Acceptes la invitació?" chatWithThisUser: "Xateja amb aquest usuari" thisUserAllowsChatOnlyFromFollowers: "Aquest usuari només accepta xats d'usuaris que el segueixen." thisUserAllowsChatOnlyFromFollowing: "Aquest usuari només accepta xats d'usuaris que segueix." @@ -1421,12 +1484,21 @@ _settings: makeEveryTextElementsSelectable: "Fes que tots els elements del text siguin seleccionables" makeEveryTextElementsSelectable_description: "L'activació pot reduir la usabilitat en determinades ocasions." useStickyIcons: "Utilitza icones fixes" + enableHighQualityImagePlaceholders: "Mostrar marcadors de posició per imatges d'alta qualitat" + uiAnimations: "Animacions de la interfície" showNavbarSubButtons: "Mostrar sub botons a la barra de navegació " ifOn: "Quan s'activa" ifOff: "Quan es desactiva" enableSyncThemesBetweenDevices: "Sincronitzar els temes instal·lats entre dispositius" enablePullToRefresh: "Lliscar i actualitzar " enablePullToRefresh_description: "Amb el ratolí, llisca mentre prems la roda." + realtimeMode_description: "Estableix una connexió amb el servidor i actualitza el contingut en temps real. Pot consumir més dades i bateria." + contentsUpdateFrequency: "Freqüència d'adquisició del contingut" + contentsUpdateFrequency_description: "Com més alt sigui l'adquisició de contingut en temps real, més baixa el rendiment i més consum de dades i bateria." + contentsUpdateFrequency_description2: "Quan s'activa el mode en temps real, el contingut s'actualitza en temps real, independentment d'aquesta configuració." + showUrlPreview: "Mostrar vista prèvia d'URL" + showAvailableReactionsFirstInNote: "Mostra les reacciones que pots fer servir al damunt" + showPageTabBarBottom: "Mostrar les pestanyes de les línies de temps a la part inferior" _chat: showSenderName: "Mostrar el nom del remitent" sendOnEnter: "Introdueix per enviar" @@ -1434,6 +1506,7 @@ _preferencesProfile: profileName: "Nom del perfil" profileNameDescription: "Estableix un nom que identifiqui aquest dispositiu." profileNameDescription2: "Per exemple: \"PC Principal\", \"Smartphone\", etc" + manageProfiles: "Gestionar perfils" _preferencesBackup: autoBackup: "Còpia de seguretat automàtica " restoreFromBackup: "Restaurar des d'una còpia de seguretat" @@ -1494,7 +1567,7 @@ _announcement: needConfirmationToRead: "Es necessita confirmació de lectura de la notificació " needConfirmationToReadDescription: "Si s'activa es mostrarà un diàleg per confirmar la lectura d'aquesta notificació. A més aquesta notificació serà exclosa de qualsevol funcionalitat com \"Marcar tot com a llegit\"." end: "Final de la notificació " - tooManyActiveAnnouncementDescription: "Tenir massa notificacions actives pot empitjorar l'experiència de l'usuari. Considera finalitzar els avisos que siguin antics." + tooManyActiveAnnouncementDescription: "Tenir masses notificacions actives pot empitjorar l'experiència de l'usuari. Considera finalitzar els avisos que siguin antics." readConfirmTitle: "Marcar com llegida?" readConfirmText: "Això marcarà el contingut de \"{title}\" com llegit." shouldNotBeUsedToPresentPermanentInfo: "Ja que l'ús de notificacions pot impactar l'experiència dels nous usuaris, és recomanable fer servir les notificacions amb el flux d'informació en comptes de fer-les servir en un únic bloc." @@ -1599,6 +1672,10 @@ _serverSettings: fanoutTimelineDbFallback: "Carregar de la base de dades" fanoutTimelineDbFallbackDescription: "Quan s'activa, la línia de temps fa servir la base de dades per consultes adicionals si la línia de temps no es troba a la memòria cau. Si és desactiva la càrrega del servidor és veure reduïda, però també és reduirà el nombre de línies de temps que és poden obtenir." reactionsBufferingDescription: "Quan s'activa aquesta opció millora bastant el rendiment en recuperar les línies de temps reduint la càrrega de la base. Com a contrapunt, augmentarà l'ús de memòria de Redís. Desactiva aquesta opció en cas de tenir un servidor amb poca memòria o si tens problemes d'inestabilitat." + remoteNotesCleaning: "Neteja automàtica de notes remotes" + remoteNotesCleaning_description: "Quan activis aquesta opció, periòdicament es netejaran les notes remotes que no es consultin, això evitarà que la base de dades se" + remoteNotesCleaningMaxProcessingDuration: "Duració màxima del temps de funcionament del procés de neteja" + remoteNotesCleaningExpiryDaysForEachNotes: "Duració mínima de conservació de les notes" inquiryUrl: "URL de consulta " inquiryUrlDescription: "Escriu adreça URL per al formulari de consulta per al mantenidor del servidor o una pàgina web amb el contacte d'informació." openRegistration: "Registres oberts" @@ -1606,6 +1683,26 @@ _serverSettings: thisSettingWillAutomaticallyOffWhenModeratorsInactive: "Si no es detecta activitat per part del moderador durant un període de temps, aquesta opció es desactiva automàticament per evitar el correu brossa." deliverSuspendedSoftware: "Programari que ja no es distribueix" deliverSuspendedSoftwareDescription: "Pots especificar un rang de noms i versions del programari del servidor per detenir l'entrega, per exemple, degut a vulnerabilitats. Aquesta informació la proporciona el servidor i la seva fiabilitat no es garantitzada. Es pot fer servir una especificació de rang sencer per especificar una versió, però es recomana especificar una versió anterior, com >= 2024.3.1-0, perquè especificar >= 2024.3.1 no incloure versions personalitzades com 2024.3.1-custom.0." + singleUserMode: "Mode un usuari" + singleUserMode_description: "Si ets l'únic usuari d'aquesta instància, activant aquest mode optimitzaràs el funcionament." + signToActivityPubGet: "Formar sol·licituds GET" + signToActivityPubGet_description: " Això normalment hauria d'estar activat. Desactivar aquesta opció pot millorar els problemes de comunicació amb algunes de les instàncies federades, però també pot fer impossibles les comunicacions amb altres servidors." + proxyRemoteFiles: "Proxy d'arxius remots" + proxyRemoteFiles_description: "Quan està habilitat, fa de proxy i serveix arxius remots. Això ajuda a generar les miniatures de les imatges i a protegir la privacitat dels usuaris." + allowExternalApRedirect: "Permetre el reencaminament per consultes fent servir ActivityPub." + allowExternalApRedirect_description: "Si aquesta opció s'activa, altres servidors poden consultar continguts de tercers mitjançant aquest servidor, però això pot donar peu a la suplantació de continguts." + userGeneratedContentsVisibilityForVisitor: "L'abast de la publicació del contingut generat per l'usuari" + userGeneratedContentsVisibilityForVisitor_description: "Això ajuda a evitar problemes com que continguts remots inadequats que no hagin estat moderats correctament es publiquin a internet mitjançant el teu servidor." + userGeneratedContentsVisibilityForVisitor_description2: "La publicació incondicional de tots els continguts del servidor a internet, incloent-hi els continguts remots rebuts pel servidor, comporta riscos. Això és extremadament important per els espectadors que desconeixen el caràcter descentralitzat dels continguts, ja que poden percebre erroneament els continguts remots com contingut generat per el propi servidor." + restartServerSetupWizardConfirm_title: "Vols tornar a executar l'assistent de configuració inicial del servidor?" + restartServerSetupWizardConfirm_text: "Algunes configuracions actuals seran restablertes." + entrancePageStyle: "Estil de la pàgina d'inici" + showTimelineForVisitor: "Mostrar la línia de temps" + showActivitiesForVisitor: "Mostrar activitat" + _userGeneratedContentsVisibilityForVisitor: + all: "Tot obert al públic " + localOnly: "Només es publiquen els continguts locals, el contingut remot es manté privat" + none: "Tot privat" _accountMigration: moveFrom: "Migrar un altre compte a aquest" moveFromSub: "Crear un àlies per un altre compte" @@ -1924,6 +2021,7 @@ _role: canManageAvatarDecorations: "Gestiona les decoracions dels avatars " driveCapacity: "Capacitat del disc" maxFileSize: "Mida màxima de l'arxiu que es pot carregar" + maxFileSize_caption: "Pot haver-hi la possibilitat que existeixin altres opcions de configuració de l'etapa anterior, com podria ser el proxy invers i la CDN." alwaysMarkNsfw: "Marca sempre els fitxers com a sensibles" canUpdateBioMedia: "Permet l'edició d'una icona o un bàner" pinMax: "Nombre màxim de notes fixades" @@ -1938,6 +2036,7 @@ _role: descriptionOfRateLimitFactor: "Límits baixos són menys restrictius, límits alts són més restrictius." canHideAds: "Pot amagar la publicitat" canSearchNotes: "Pot cercar notes" + canSearchUsers: "Pot cercar usuaris" canUseTranslator: "Pot fer servir el traductor" avatarDecorationLimit: "Nombre màxim de decoracions que es poden aplicar els avatars" canImportAntennas: "Autoritza la importació d'antenes " @@ -1946,6 +2045,12 @@ _role: canImportMuting: "Autoritza la importació de silenciats" canImportUserLists: "Autoritza la importació de llistes d'usuaris " chatAvailability: "Es permet xatejar" + uploadableFileTypes: "Tipus de fitxers que en podeu pujar" + uploadableFileTypes_caption: "Especifica el tipus MIME. Es poden especificar diferents tipus MIME separats amb una nova línia, i es poden especificar comodins amb asteriscs (*). (Per exemple: image/*)" + uploadableFileTypes_caption2: "Pot que no sigui possible determinar el tipus MIME d'alguns arxius. Per permetre aquests tipus d'arxius afegeix {x} a les especificacions." + noteDraftLimit: "Nombre possible d'esborranys de notes al servidor" + scheduledNoteLimit: "Màxim nombre de notes programades que es poden crear simultàniament" + watermarkAvailable: "Pots fer servir la marca d'aigua" _condition: roleAssignedTo: "Assignat a rols manuals" isLocal: "Usuari local" @@ -2003,7 +2108,7 @@ _ad: timezoneinfo: "El dia de la setmana ve determinat del fus horari del servidor." adsSettings: "Configurar la publicitat" notesPerOneAd: "Interval d'emplaçament publicitari en temps real (Notes per anuncis)" - setZeroToDisable: "Ajusta aquest valor a 0 per deshabilitar l'actualització d'anuncis en temps real" + setZeroToDisable: "Ajusta aquest valor a 0 per deshabilitar l'actualització de publicitat en temps real" adsTooClose: "L'interval actual pot fer que l'experiència de l'usuari sigui dolenta perquè l'interval és molt baix." _forgotPassword: enterEmail: "Escriu l'adreça de correu electrònic amb la que et vas registrar. S'enviarà un correu electrònic amb un enllaç perquè puguis canviar-la." @@ -2105,6 +2210,7 @@ _theme: install: "Instal·lar un tema" manage: "Gestionar els temes " code: "Codi del tema" + copyThemeCode: "Copiar el codi del tema" description: "Descripció" installed: "{name} Instal·lat " installedThemes: "Temes instal·lats " @@ -2163,7 +2269,6 @@ _theme: buttonBg: "Fons botó " buttonHoverBg: "Fons botó (en passar-hi per sobre)" inputBorder: "Contorn del cap d'introducció " - driveFolderBg: "Fons de la carpeta Disc" badge: "Insígnia " messageBg: "Fons del xat" fgHighlighted: "Text ressaltat" @@ -2171,7 +2276,6 @@ _sfx: note: "Notes" noteMy: "Nota (per mi)" notification: "Notificacions" - chat: "Xat" reaction: "Quan se selecciona una reacció " chatMessage: "Missatges del xat" _soundSettings: @@ -2206,6 +2310,7 @@ _time: minute: "Minut(s)" hour: "Hor(a)(es)" day: "Di(a)(es)" + month: "Mes(os)" _2fa: alreadyRegistered: "J has registrat un dispositiu d'autenticació de doble factor." registerTOTP: "Registrar una aplicació autenticadora" @@ -2335,6 +2440,7 @@ _auth: scopeUser: "Opera com si fossis aquest usuari" pleaseLogin: "Si us plau, identificat per autoritzar l'aplicació." byClickingYouWillBeRedirectedToThisUrl: "Si es garanteix l'accés, seràs redirigit automàticament a la següent adreça URL" + alreadyAuthorized: "Aquesta aplicació ja té accés." _antennaSources: all: "Totes les publicacions" homeTimeline: "Publicacions dels usuaris seguits" @@ -2380,7 +2486,7 @@ _widgets: chooseList: "Tria una llista" clicker: "Clicker" birthdayFollowings: "Usuaris que fan l'aniversari avui" - chat: "Xat" + chat: "Xateja amb aquest usuari" _cw: hide: "Amagar" show: "Carregar més" @@ -2420,6 +2526,8 @@ _visibility: disableFederation: "Sense federar" disableFederationDescription: "No enviar a altres servidors" _postForm: + quitInspiteOfThereAreUnuploadedFilesConfirm: "Hi ha arxius que no s'han carregat, vols descartar-los i tancar el formulari?" + uploaderTip: "L'arxiu encara no s'ha carregat. Des del menú arxiu pots canviar el nom, retallar imatges, posar marques d'aigua i comprimir o no l'arxiu. Els arxius es carreguen automàticament quan públiques una nota." replyPlaceholder: "Contestar..." quotePlaceholder: "Citar..." channelPlaceholder: "Publicar a un canal..." @@ -2568,6 +2676,8 @@ _notification: youReceivedFollowRequest: "Has rebut una petició de seguiment" yourFollowRequestAccepted: "La teva petició de seguiment ha sigut acceptada" pollEnded: "Ja pots veure els resultats de l'enquesta " + scheduledNotePosted: "Una nota programada ha sigut publicada" + scheduledNotePostFailed: "Ha fallat la publicació d'una nota programada" newNote: "Nota nova" unreadAntennaNote: "Antena {name}" roleAssigned: "Rol assignat " @@ -2597,6 +2707,8 @@ _notification: quote: "Citar" reaction: "Reaccions" pollEnded: "Enquesta terminada" + scheduledNotePosted: "Nota programada amb èxit " + scheduledNotePostFailed: "Ha fallat la programació de la nota" receiveFollowRequest: "Rebuda una petició de seguiment" followRequestAccepted: "Petició de seguiment acceptada" roleAssigned: "Rol donat" @@ -2647,7 +2759,7 @@ _deck: mentions: "Mencions" direct: "Publicacions directes" roleTimeline: "Línia de temps dels rols" - chat: "Xat" + chat: "Xateja amb aquest usuari" _dialog: charactersExceeded: "Has arribat al màxim de caràcters! Actualment és {current} de {max}" charactersBelow: "Ets per sota del mínim de caràcters! Actualment és {current} de {min}" @@ -2753,6 +2865,7 @@ _fileViewer: url: "URL" uploadedAt: "Pujat el" attachedNotes: "Notes amb aquest fitxer" + usage: "Ús " thisPageCanBeSeenFromTheAuthor: "Aquesta pàgina només la pot veure l'usuari que ha pujat aquest fitxer." _externalResourceInstaller: title: "Instal·lar des d'un lloc extern" @@ -2800,9 +2913,12 @@ _dataSaver: _avatar: title: "Avatars animats" description: "Detenir l'animació dels avatars animats. Les imatges animades solen tenir un pes més gran que les imatges normals, reduint el tràfic disponible." - _urlPreview: - title: "Miniatures vista prèvia de l'URL" - description: "Les imatges en miniatura que serveixen com a vista prèvia de les URLs no es tornaran a carregar." + _urlPreviewThumbnail: + title: "Amagar les miniatures de la vista prèvia d'URL" + description: "Les imatges en miniatura de la vista prèvia d'URL ja no es carreguen" + _disableUrlPreview: + title: "Desactivar la vista prèvia d'URL" + description: "Desactiva la funció de previsualització d'URL. A diferència de les imatges en miniatura soles, això redueix la càrrega de la mateixa informació vinculada." _code: title: "Ressaltat del codi " description: "Quan s'utilitza codi MFC, no es llegeix fins que es copiï. En els punts destacats del codi s'han de llegir els fitxers definits per a cada llengua que resulti alt, però no es poden llegir automàticament, per la qual cosa es poden reduir les quantitats de comunicació." @@ -2860,6 +2976,8 @@ _offlineScreen: _urlPreviewSetting: title: "Configuració per a la previsualització de l'URL" enable: "Activa la previsualització de l'URL" + allowRedirect: "Permet la redirecció de la visualització prèvia " + allowRedirectDescription: "Estableix si es mostra o no la redirecció a la vista prèvia quan l'adreça URL introduïda té una redirecció. Si es desactiva s'estalvien recursos del servidor, però no es mostrarà el contingut de la redirecció." timeout: "Temps màxim per carregar la previsualització de l'URL (ms)" timeoutDescription: "Si l'obtenció de la previsualització triga més que el temps establert, no es generarà la vista prèvia." maximumContentLength: "Longitud màxima del contingut (bytes)" @@ -2933,10 +3051,6 @@ _customEmojisManager: uploadSettingDescription: "En aquesta pantalla pots configurar el que s'ha de fer quan es puja un Emoji." directoryToCategoryLabel: "Escriu el nom del directori al camp de \"categoria\"" directoryToCategoryCaption: "Quan arrossegues un directori, escriu el nom del directori al camp categoria." - emojiInputAreaCaption: "Selecciona els Emojis que vols registrar gent servir un dels mètodes." - emojiInputAreaList1: "Arrossega i deixar anar fitxers o directoris dintre del quadrat." - emojiInputAreaList2: "Clica l'enllaç per seleccionar un fitxer des del teu ordinador." - emojiInputAreaList3: "Clica aquest enllaç per seleccionar del Disc" confirmRegisterEmojisDescription: "Registrar els Emojis de la llista com a nous Emojis personalitzats. Vols continuar? (Per evitar una sobrecàrrega només {count} Emojis es poden registrar d'una sola vegada)" confirmClearEmojisDescription: "Descartar els canvis i esborrar els Emojis de la llista. Vols continuar?" confirmUploadEmojisDescription: "Pujar els {count} fitxers que has arrossegat al disc. Vols continuar?" @@ -3004,6 +3118,7 @@ _bootErrors: otherOption1: "Esborrar la configuració i la memòria cau del client" otherOption2: "Iniciar client senzill" otherOption3: "Iniciar l'eina de reparació " + otherOption4: "Iniciar CherryPick en mode segur" _search: searchScopeAll: "Tot" searchScopeLocal: "Local" @@ -3012,3 +3127,195 @@ _search: pleaseEnterServerHost: "Introdueix l'adreça de la instància " pleaseSelectUser: "Selecciona un usuari" serverHostPlaceholder: "Ex: cherrypick.example.com" +_serverSetupWizard: + installCompleted: "La instal·lació de CherryPick ha finalitzat!" + firstCreateAccount: "Primer crea un compte d'administrador." + accountCreated: "Compte d'administrador creat." + serverSetting: "Configuració del servidor" + youCanEasilyConfigureOptimalServerSettingsWithThisWizard: "Aquest assistent t'ajuda a fer una configuració òptima del servidor." + settingsYouMakeHereCanBeChangedLater: "Els canvis que facis ara poden modificar-se més tard." + howWillYouUseMisskey: "Com es fa servir CherryPick?" + _use: + single: "Servidor per una sola persona" + single_description: "Fes-ho servir com el teu propi servidor dedicat" + single_youCanCreateMultipleAccounts: "Es poden crear diferents comptes segons siguin les teves necessitats, inclús quan es fa servir com a servidor unipersonal." + group: "Servidor per a grups" + group_description: "Invita altres usuaris de la teva confiança i fes-ho servir amb més d'una persona." + open: "Servidor obert" + open_description: "Operar per donar cabuda a un nombre no determinat d'usuaris." + openServerAdvice: "Acceptar un nombre no determinat d'usuaris comporta alguns riscos. Es recomana operar amb un sistema de moderació fiable per fer front als problemes." + openServerAntiSpamAdvice: "També s'ha de tenir molta cura amb la seguretat, per exemple habilitant funcions anti-bot com reCAPTCHA, per assegurar-te que el teu servidor no es converteix en un trampolí per contingut brossa." + howManyUsersDoYouExpect: "Quantes persones preveus?" + _scale: + small: "Menys de 100 (petita escala)" + medium: "Més de 100 i menys de 1000 (mida mitjana)" + large: "Més de 1000 persones (gran escala)" + largeScaleServerAdvice: "Els grans servidors poden requerir coneixements avançats d'infraestructures, com balanceig de càrregues i replicació de base de dades." + doYouConnectToFediverse: "Desitges connectar-te amb el Fedivers?" + doYouConnectToFediverse_description1: "Quan es connecta amb una xarxa de servidors distribuïts (Fedivers), els continguts poden intercanviar-se amb altres servidors i entre ells." + doYouConnectToFediverse_description2: "La connexió amb el Fedivers també es coneix com a \"federació\"." + youCanConfigureMoreFederationSettingsLater: "Les configuracions avançades, com especificar els servidors amb els quals es pot federar, es poden fer més tard." + remoteContentsCleaning: "Neteja automàtica del contingut rebut" + remoteContentsCleaning_description: "Quan es comença a federar es rep un munt de contingut, quan s'activa la neteja automàtica el contingut antic que no es consulta serà eliminat del servidor, el que permet estalviar espai d'emmagatzematge." + adminInfo: "Informació de l'administrador " + adminInfo_description: "Estableix la informació de l'administrador que es farà servir per rebre consultes." + adminInfo_mustBeFilled: "Aquesta informació ha de ser omplerta si el servidor té els registres oberts o la federació es troba activada." + followingSettingsAreRecommended: "Es recomana la següent configuració " + applyTheseSettings: "Aplicar aquesta configuració " + skipSettings: "Saltar la configuració " + settingsCompleted: "Configuració finalitzada " + settingsCompleted_description: "Gràcies per la teva ajuda. Ara que ja està tot llest, pots començar a fer servir el servidor immediatament." + settingsCompleted_description2: "La configuració avançada del servidor també poden fer-se des del \"Tauler de control\"." + donationRequest: "Una donació, si us plau" + _donationRequest: + text1: "CherryPick és un programari gratuït fet per voluntaris." + text2: "Si ho desitges, agrairíem molt la teva donació per poder seguir desenvolupant el projecte." + text3: "També hi ha privilegis especials per als donants!" +_uploader: + editImage: "Edició d'imatges" + compressedToX: "Comprimit a {x}" + savedXPercent: "{x}% d'estalvi " + abortConfirm: "Hi ha un arxiu que no s'ha pujat, vols cancel·lar?" + doneConfirm: "Hi han fitxers no pujats, vols completar-los?" + maxFileSizeIsX: "La mida màxima d'arxiu que es pot pujar és {x}." + allowedTypes: "Tipus de fitxers que en podeu pujar" + tip: "L'arxiu encara no s'ha carregat. En aquest quadre de diàleg, pots comprovar, canviar el nom, comprimir i retallar l'arxiu abans de pujar-lo. Quan estigui llest pots iniciar la càrrega polsant el boto \"Pujar\"" +_clientPerformanceIssueTip: + title: "Si creus que el consum de bateria és molt alt" + makeSureDisabledAdBlocker: "Desactiva els bloquejadors de publicitat" + makeSureDisabledAdBlocker_description: "Els bloquejadors d'anuncis pot afectar el rendiment, comprova que no estiguin activats per característiques del sistema operatiu o del navegador." + makeSureDisabledCustomCss: "Desactiva CSS personalitzat" + makeSureDisabledCustomCss_description: "L'anul·lació dels estils pot afectar el rendiment. Comprova que el CSS personalitzat o les extensions que reescriuen estils no estiguin activats." + makeSureDisabledAddons: "Desactiva extensions" + makeSureDisabledAddons_description: "Algunes extensions poden interferir en el comportament del client i afectar el rendiment. Desactiva les extensions del navegador i comprovar-ho." +_clip: + tip: "Clip és una funció que permet organitzar les teves notes." +_userLists: + tip: "Es poden crear llistes amb qualsevol usuari. La llista creada es pot mostrar com una línia de temps." +watermark: "Marca d'aigua " +defaultPreset: "Per defecte" +_watermarkEditor: + tip: "A la imatge es pot afegir una marca d'aigua com informació sobre drets." + quitWithoutSaveConfirm: "Sortir sense desar?" + driveFileTypeWarn: "Aquest arxiu no és compatible" + driveFileTypeWarnDescription: "Selecciona un arxiu d'imatge " + title: "Editar la marca d'aigua " + cover: "Cobrir-ho tot" + repeat: "Repetir" + preserveBoundingRect: "Ajusta'l per evitar que sobresortir en fer la rotació " + opacity: "Opacitat" + scale: "Mida" + text: "Text" + qr: "Codi QR" + position: "Posició " + margin: "Marge" + type: "Tipus" + image: "Imatges" + advanced: "Avançat" + angle: "Angle" + stripe: "Bandes" + stripeWidth: "Amplada de la banda" + stripeFrequency: "Freqüència de la banda" + polkadot: "Lunars" + checker: "Escacs" + polkadotMainDotOpacity: "Opacitat del lunar principal" + polkadotMainDotRadius: "Mida del lunar principal" + polkadotSubDotOpacity: "Opacitat del lunar secundari" + polkadotSubDotRadius: "Mida del lunar secundari" + polkadotSubDotDivisions: "Nombre de punts secundaris" + leaveBlankToAccountUrl: "Si deixes aquest camp buit, es farà servir l'URL del teu compte" +_imageEffector: + title: "Efecte" + addEffect: "Afegeix un efecte" + discardChangesConfirm: "Vols descartar els canvis i sortir?" + nothingToConfigure: "No hi ha opcions de configuració disponibles" + _fxs: + chromaticAberration: "Aberració cromàtica" + glitch: "Glitch" + mirror: "Mirall" + invert: "Inversió cromàtica " + grayscale: "Monocrom " + blur: "Desenfocament" + pixelate: "Mosaic" + colorAdjust: "Correcció de color" + colorClamp: "Compressió cromàtica " + colorClampAdvanced: "Compressió de cromàtica avançada " + distort: "Distorsió " + threshold: "Binarització" + zoomLines: "Saturació de línies " + stripe: "Bandes" + polkadot: "Lunars" + checker: "Escacs" + blockNoise: "Bloqueig de soroll" + tearing: "Trencament d'imatge " + fill: "Omplir" + _fxProps: + angle: "Angle" + scale: "Mida" + size: "Mida" + radius: "Radi" + samples: "Mida de la mostra" + offset: "Posició " + color: "Color" + opacity: "Opacitat" + normalize: "Normalitzar" + amount: "Quantitat" + lightness: "Brillantor" + contrast: "Contrast" + hue: "Tonalitat" + brightness: "Brillantor" + saturation: "Saturació" + max: "Màxim" + min: "Mínim" + direction: "Direcció " + phase: "Fase" + frequency: "Freqüència " + strength: "Intensitat" + glitchChannelShift: "Canvi de canal " + seed: "Llavors" + redComponent: "Component vermell" + greenComponent: "Component verd" + blueComponent: "Component blau" + threshold: "Llindar" + centerX: "Centre de X" + centerY: "Centre de Y" + zoomLinesSmoothing: "Suavitzat" + zoomLinesSmoothingDescription: "Els paràmetres de suavitzat i amplada de línia en augmentar no es poden fer servir junts." + zoomLinesThreshold: "Amplada de línia a l'augmentar " + zoomLinesMaskSize: "Diàmetre del centre" + zoomLinesBlack: "Obscurir" + circle: "Cercle" +drafts: "Esborrany " +_drafts: + select: "Seleccionar esborrany" + cannotCreateDraftAnymore: "S'ha sobrepassat el nombre màxim d'esborranys que es poden crear." + cannotCreateDraft: "Amb aquest contingut no es poden crear esborranys." + delete: "Esborrar esborranys" + deleteAreYouSure: "Vols esborrar els esborranys?" + noDrafts: "No hi ha esborranys" + replyTo: "Respondre a {user}" + quoteOf: "Citar les notes de {user}" + postTo: "Destinat a {channel}" + saveToDraft: "Desar com a esborrany" + restoreFromDraft: "Restaurar des dels esborranys" + restore: "Restaurar esborrany" + listDrafts: "Llistat d'esborranys" + schedule: "Programació esborranys" + listScheduledNotes: "Llista de notes programades" + cancelSchedule: "Cancel·lar la programació" +qr: "Codi QR" +_qr: + showTabTitle: "Veure" + readTabTitle: "Escanejar " + shareTitle: "{name} {acct}" + shareText: "Segueix-me al Fediverse" + chooseCamera: "Seleccionar càmera " + cannotToggleFlash: "No es pot activar el flaix" + turnOnFlash: "Activar el flaix" + turnOffFlash: "Apagar el flaix" + startQr: "Reiniciar el lector de codis QR" + stopQr: "Parar el lector de codis QR" + noQrCodeFound: "No s'ha trobat cap codi QR" + scanFile: "Escanejar la imatge des del dispositiu" + raw: "Text" + mfm: "MFC" diff --git a/locales/cs-CZ.yml b/locales/cs-CZ.yml index f48d4f38ea..38ec2e2363 100644 --- a/locales/cs-CZ.yml +++ b/locales/cs-CZ.yml @@ -1,7 +1,7 @@ --- _lang_: "Čeština" headlineMisskey: "Síť propojená poznámkami" -introMisskey: "Vítejte! CherryPick je otevřený a decentralizovaný microblogový servis.\n\"Poznámkami\" můžete sdílet co se zrovna děje se všemi ve Vašem okolí. 📡\nPomocí \"reakcí\" můžete sdílet své názory a pocity na ostatní poznámky. 👍\nPojďte objevovat nový svět! 🚀" +introMisskey: "Vítejte! CherryPick je otevřená a decentralizovaná microblogovací služba.\n\"Poznámkami\" můžete sdílet co se zrovna děje se všemi ve Vašem okolí. 📡\nPomocí \"reakcí\" můžete sdílet své názory a pocity na ostatní poznámky. 👍\nPojďte objevovat nový svět! 🚀" poweredByMisskeyDescription: "{name} je jeden ze serverů využívající open source platformu CherryPick (nazývaná \"CherryPick instance\")." monthAndDay: "{day}. {month}." search: "Vyhledávání" @@ -19,7 +19,7 @@ gotIt: "Rozumím!" cancel: "Zrušit" noThankYou: "Ne děkuji" enterUsername: "Zadej uživatelské jméno" -renotedBy: "{user} přeposla/a" +renotedBy: "{user} přeposlal*a" noNotes: "Žádné poznámky" noNotifications: "Žádná oznámení" instance: "Instance" @@ -65,6 +65,7 @@ copyFileId: "Kopírovat ID souboru" copyFolderId: "Kopírovat ID složky" copyProfileUrl: "Kopírovat URL profilu" searchUser: "Vyhledat uživatele" +searchThisUsersNotes: "Prohledat poznámky uživatele" reply: "Odpovědět" loadMore: "Zobrazit více" showMore: "Zobrazit více" @@ -228,7 +229,6 @@ noUsers: "Žádní uživatelé" editProfile: "Upravit můj profil" noteDeleteConfirm: "Jste si jistí že chcete smazat tuhle poznámku?" pinLimitExceeded: "Nemůžete připnout další poznámky." -intro: "Instalace CherryPick byla dokončena! Prosím vytvořte admina." done: "Hotovo" processing: "Zpracovávám" preview: "Náhled" @@ -1108,6 +1108,9 @@ lastNDays: "Posledních {n} dnů" surrender: "Zrušit" postForm: "Formulář pro odeslání" information: "Informace" +inMinutes: "Minut" +inDays: "Dnů" +widgets: "Widgety" _chat: invitations: "Pozvat" noHistory: "Žádná historie" @@ -1650,7 +1653,6 @@ _theme: buttonBg: "Pozadí tlačítka" buttonHoverBg: "Pozadí tlačítka (Hover)" inputBorder: "Ohraničení vstupního pole" - driveFolderBg: "Pozadí složky disku" badge: "Odznak" messageBg: "Pozadí chatu" fgHighlighted: "Zvýrazněný text" @@ -2007,7 +2009,7 @@ _deck: list: "Seznamy" channel: "Kanály" mentions: "Zmínění" - direct: "Přímý" + direct: "Přímé poznámky" roleTimeline: "Časová osa role" _dialog: charactersExceeded: "Překročili jste maximální počet znaků! V současné době je na hodnotě {current} z {max}." @@ -2048,3 +2050,22 @@ _search: searchScopeAll: "Vše" searchScopeLocal: "Místní" searchScopeUser: "Upřesnit uživatele" +_watermarkEditor: + opacity: "Průhlednost" + scale: "Velikost" + text: "Text" + position: "Pozice" + type: "Typ" + image: "Obrázky" + advanced: "Pokročilé" +_imageEffector: + _fxProps: + scale: "Velikost" + size: "Velikost" + offset: "Pozice" + color: "Barva" + opacity: "Průhlednost" + lightness: "Zesvětlit" +_qr: + showTabTitle: "Zobrazit" + raw: "Text" diff --git a/locales/de-DE.yml b/locales/de-DE.yml index 4bb39e2fe0..549d433613 100644 --- a/locales/de-DE.yml +++ b/locales/de-DE.yml @@ -251,7 +251,6 @@ noUsers: "Keine Benutzer gefunden" editProfile: "Profil bearbeiten" noteDeleteConfirm: "Möchtest du diese Notiz wirklich löschen?" pinLimitExceeded: "Du kannst nicht noch mehr Notizen anheften." -intro: "CherryPick ist installiert! Lass uns nun ein Administratorkonto einrichten." done: "Fertig" processing: "In Bearbeitung …" preview: "Vorschau" @@ -299,6 +298,7 @@ uploadFromUrl: "Von einer URL hochladen" uploadFromUrlDescription: "URL der hochzuladenden Datei" uploadFromUrlRequested: "Upload angefordert" uploadFromUrlMayTakeTime: "Es kann eine Weile dauern, bis das Hochladen abgeschlossen ist." +uploadNFiles: "Lade {n} Dateien hoch" explore: "Erkunden" messageRead: "Gelesen" noMoreHistory: "Kein weiterer Verlauf vorhanden" @@ -327,6 +327,7 @@ dark: "Dunkel" lightThemes: "Helle Farbschemata" darkThemes: "Dunkle Farbschemata" syncDeviceDarkMode: "Einstellung deines Geräts übernehmen" +switchDarkModeManuallyWhenSyncEnabledConfirm: "\"{x}\" ist eingeschaltet. Möchtest du die Synchronisation ausschalten und den Modus manuell wechseln?" drive: "Drive" fileName: "Dateiname" selectFile: "Datei auswählen" @@ -586,8 +587,10 @@ showFixedPostForm: "Bereich zum Schreiben neuer Notizen am Anfang der Chronik an showFixedPostFormInChannel: "Bereich zum Schreiben neuer Notizen am Anfang der Chronik anzeigen (Kanäle)" withRepliesByDefaultForNewlyFollowed: "Standardmäßig Antworten von neu gefolgten Benutzern in der Chronik anzeigen" newNoteRecived: "Es gibt neue Notizen" +newNote: "Neue Notiz" sounds: "Töne" sound: "Töne" +notificationSoundSettings: "Benachrichtigungston festlegen" listen: "Anhören" none: "Nichts" showInPage: "In einer Seite anzeigen" @@ -803,6 +806,7 @@ wide: "Breit" narrow: "Schmal" reloadToApplySetting: "Diese Einstellung tritt nach einer Aktualisierung der Seite in Kraft. Jetzt aktualisieren?" needReloadToApply: "Diese Einstellung tritt nach einer Aktualisierung der Seite in Kraft." +needToRestartServerToApply: "Diese Einstellung tritt nach einem Neustart des Servers in Kraft." showTitlebar: "Titelleiste anzeigen" clearCache: "Cache leeren" onlineUsersCount: "{n} Benutzer sind online" @@ -1011,6 +1015,7 @@ failedToUpload: "Hochladen fehlgeschlagen" cannotUploadBecauseInappropriate: "Diese Datei kann nicht hochgeladen werden, da Anteile der Datei als möglicherweise unangebracht festgestellt wurden." cannotUploadBecauseNoFreeSpace: "Die Datei konnte nicht hochgeladen werden, da dein Drive-Speicherplatz aufgebraucht ist." cannotUploadBecauseExceedsFileSizeLimit: "Diese Datei kann wegen Überschreitung der Maximalgröße nicht hochgeladen werden." +cannotUploadBecauseUnallowedFileType: "Hochladen nicht möglich wegen unzulässigem Dateityp." beta: "Beta" enableAutoSensitive: "Automarkierung sensibler Medien" enableAutoSensitiveDescription: "Setzt soweit möglich durch Verwendung von Machine Learning automatisch Markierungen für sensible Medien. Auch wenn du diese Option deaktiviert hast, ist sie möglicherweise auf Instanzebene aktiviert." @@ -1250,9 +1255,7 @@ showAvatarDecorations: "Profilbilddekoration anzeigen" releaseToRefresh: "Zum Aktualisieren loslassen" refreshing: "Wird aktualisiert..." pullDownToRefresh: "Zum Aktualisieren ziehen" -disableStreamingTimeline: "Echtzeitaktualisierung der Chronik deaktivieren" useGroupedNotifications: "Benachrichtigungen gruppieren" -signupPendingError: "Beim Überprüfen der Mailadresse ist etwas schiefgelaufen. Der Link könnte abgelaufen sein." cwNotationRequired: "Ist \"Inhaltswarnung verwenden\" aktiviert, muss eine Beschreibung gegeben werden." doReaction: "Reagieren" code: "Code" @@ -1322,6 +1325,7 @@ availableRoles: "Verfügbare Rollen" acknowledgeNotesAndEnable: "Schalten Sie dies erst ein, wenn Sie die Vorsichtsmaßnahmen verstanden haben." federationSpecified: "Dieser Server arbeitet mit Whitelist-Föderation. Er kann nicht mit anderen als den vom Administrator angegebenen Servern interagieren." federationDisabled: "Föderation ist auf diesem Server deaktiviert. Es ist nicht möglich, mit Benutzern auf anderen Servern zu interagieren." +draft: "Entwurf" confirmOnReact: "Reagieren bestätigen" reactAreYouSure: "Willst du eine \"{emoji}\"-Reaktion hinzufügen?" markAsSensitiveConfirm: "Möchtest du dieses Medium als sensibel kennzeichnen?" @@ -1339,6 +1343,7 @@ restore: "Wiederherstellen" syncBetweenDevices: "Zwischen Geräten synchronisieren" preferenceSyncConflictTitle: "Der konfigurierte Wert ist auf dem Server bereits vorhanden." preferenceSyncConflictText: "Die Einstellungen mit aktivierter Synchronisierung werden ihre Werte auf dem Server speichern. Es gibt jedoch bereits Werte auf dem Server. Welche Einstellungswerte sollen überschrieben werden?" +preferenceSyncConflictChoiceMerge: "Zusammenführen" preferenceSyncConflictChoiceServer: "Konfigurierte Werte auf dem Server" preferenceSyncConflictChoiceDevice: "Konfigurierte Werte auf dem Gerät" preferenceSyncConflictChoiceCancel: "Einrichten der Synchronisierung abbrechen" @@ -1348,6 +1353,7 @@ postForm: "Notizfenster" textCount: "Zeichenanzahl" information: "Über" chat: "Chat" +directMessage: "Mit dem Benutzer chatten" migrateOldSettings: "Alte Client-Einstellungen migrieren" migrateOldSettings_description: "Dies sollte normalerweise automatisch geschehen, aber wenn die Migration aus irgendeinem Grund nicht erfolgreich war, kannst du den Migrationsprozess selbst manuell auslösen. Die aktuellen Konfigurationsinformationen werden dabei überschrieben." compress: "Komprimieren" @@ -1355,12 +1361,32 @@ right: "Rechts" bottom: "Unten" top: "Oben" embed: "Einbetten" -settingsMigrating: "Ihre Einstellungen werden gerade migriert, Bitte warten Sie einen Moment... (Sie können die Einstellungen später auch manuell migrieren, indem Sie zu Einstellungen → Sonstiges → Alte Einstellungen migrieren gehen)" +settingsMigrating: "Deine Einstellungen werden gerade migriert. Bitte warte einen Moment... (Du kannst die Einstellungen später auch manuell migrieren, indem du zu Einstellungen → Anderes → Alte Einstellungen migrieren gehst)" readonly: "Nur Lesezugriff" goToDeck: "Zurück zum Deck" federationJobs: "Föderation Jobs" driveAboutTip: "In Drive sehen Sie eine Liste der Dateien, die Sie in der Vergangenheit hochgeladen haben.
\nSie können diese Dateien wiederverwenden um sie zu beispiel an Notizen anzuhängen, oder sie können Dateien vorab hochzuladen, um sie später zu versenden!
\nWenn Sie eine Datei löschen, verschwindet sie auch von allen Stellen, an denen Sie sie verwendet haben (Notizen, Seiten, Avatare, Banner usw.).
\nSie können auch Ordner erstellen, um sie zu organisieren." scrollToClose: "Zum Schließen scrollen" +advice: "Tipps" +realtimeMode: "Echtzeit-Modus" +turnItOn: "Einschalten" +turnItOff: "Ausschalten" +emojiMute: "Emoji stummschalten" +emojiUnmute: "Emoji-Stummschaltung aufheben" +muteX: "{x} stummschalten" +unmuteX: "Stummschaltung von {x} aufheben" +abort: "Abbrechen" +tip: "Tipps und Tricks" +redisplayAllTips: "Alle „Tipps und Tricks“ wieder anzeigen" +hideAllTips: "Alle „Tipps und Tricks“ ausblenden" +defaultImageCompressionLevel: "Standard-Bildkomprimierungsstufe" +defaultImageCompressionLevel_description: "Ein niedrigerer Wert erhält die Bildqualität, erhöht aber die Dateigröße.
Höhere Werte reduzieren die Dateigröße, verringern aber die Bildqualität." +inMinutes: "Minute(n)" +inDays: "Tag(en)" +widgets: "Widgets" +_order: + newest: "Neueste zuerst" + oldest: "Älteste zuerst" _chat: noMessagesYet: "Noch keine Nachrichten" newMessage: "Neue Nachricht" @@ -1394,6 +1420,8 @@ _chat: chatNotAvailableInOtherAccount: "Die Chatfunktion wurde vom anderen Benutzer deaktiviert." cannotChatWithTheUser: "Starten eines Chats mit diesem Benutzer nicht möglich" cannotChatWithTheUser_description: "Der Chat ist entweder nicht verfügbar oder die andere Seite hat den Chat nicht aktiviert." + youAreNotAMemberOfThisRoomButInvited: "Du bist kein Teilnehmer in diesem Raum, aber du hast eine Einladung erhalten. Bitte nimm die Einladung an, um beizutreten." + doYouAcceptInvitation: "Nimmst du die Einladung an?" chatWithThisUser: "Mit dem Benutzer chatten" thisUserAllowsChatOnlyFromFollowers: "Dieser Benutzer nimmt nur Chats von Followern an." thisUserAllowsChatOnlyFromFollowing: "Dieser Benutzer nimmt nur Chats von Benutzern an, denen er folgt." @@ -1433,12 +1461,20 @@ _settings: makeEveryTextElementsSelectable: "Alle Textelemente auswählbar machen" makeEveryTextElementsSelectable_description: "Die Aktivierung kann in manchen Situationen die Benutzerfreundlichkeit beeinträchtigen." useStickyIcons: "Icons beim Scrollen folgen lassen" + enableHighQualityImagePlaceholders: "Zeige Platzhalter für Bilder in hoher Qualität an" + uiAnimations: "Animationen der Benutzeroberfläche" showNavbarSubButtons: "Unterschaltflächen in der Navigationsleiste anzeigen" ifOn: "Wenn eingeschaltet" ifOff: "Wenn ausgeschaltet" enableSyncThemesBetweenDevices: "Synchronisierung von installierten Themen auf verschiedenen Endgeräten" enablePullToRefresh: "Ziehen zum Aktualisieren" enablePullToRefresh_description: "Bei Benutzung einer Maus, mit gedrücktem Mausrad ziehen" + realtimeMode_description: "Stellt eine Verbindung mit dem Server her und aktualisiert die Inhalte in Echtzeit. Kann zu mehr Datenverkehr einem höheren Akkuverbrauch führen." + contentsUpdateFrequency: "Häufigkeit des Abrufs von Inhalten" + contentsUpdateFrequency_description: "Je höher der Wert, desto häufiger werden die Inhalte aktualisiert, aber die Leistung sinkt und der Datenverkehr und der Akkuverbrauch steigen." + contentsUpdateFrequency_description2: "Wenn der Echtzeitmodus aktiviert ist, werden die Inhalte unabhängig von dieser Einstellung in Echtzeit aktualisiert." + showUrlPreview: "URL-Vorschau anzeigen" + showAvailableReactionsFirstInNote: "Zeige die verfügbaren Reaktionen im oberen Bereich an." _chat: showSenderName: "Name des Absenders anzeigen" sendOnEnter: "Eingabetaste sendet Nachricht" @@ -1446,6 +1482,7 @@ _preferencesProfile: profileName: "Profilname" profileNameDescription: "Lege einen Namen fest, der dieses Gerät identifiziert." profileNameDescription2: "Beispiel: \"Haupt-PC\", \"Smartphone\"" + manageProfiles: "Profile verwalten" _preferencesBackup: autoBackup: "Automatische Sicherung" restoreFromBackup: "Wiederherstellen aus der Sicherung" @@ -1618,6 +1655,21 @@ _serverSettings: thisSettingWillAutomaticallyOffWhenModeratorsInactive: "Wenn über einen bestimmten Zeitraum keine Moderatorenaktivität festgestellt wird, wird diese Einstellung automatisch deaktiviert, um Spam zu verhindern." deliverSuspendedSoftware: "Software, die nicht mehr beliefert wird" deliverSuspendedSoftwareDescription: "Sie können eine Auswahl von Namen und Versionen verschiedener Serversoftware angeben, um die Zustellung zu stoppen, z. B. aufgrund von Sicherheitslücken. Diese Versionsinformationen werden vom Server bereitgestellt und ihre Zuverlässigkeit ist nicht garantiert. Es wird jedoch empfohlen, eine Vorabversion anzugeben, wie z. B. >= 2024.3.1-0, da die Angabe >= 2024.3.1 keine benutzerdefinierten Versionen wie 2024.3.1-custom.0 einschließt." + singleUserMode: "Einzelbenutzermodus" + singleUserMode_description: "Wenn du der einzige Benutzer dieses Servers bist, optimiert die Aktivierung dieses Modus die Leistung des Servers." + signToActivityPubGet: "ActivityPub-GET-Anfragen signieren" + signToActivityPubGet_description: "Normalerweise sollte diese Option aktiviert sein. Die Deaktivierung kann Probleme im Zusammenhang mit der Föderation beheben, aber andererseits könnte sie die Föderation mit einigen anderen Servern deaktivieren." + proxyRemoteFiles: "Proxy für Dateien fremder Instanzen" + proxyRemoteFiles_description: "Wenn diese Einstellung aktiviert ist, werden fremde Dateien über einen Proxyserver übertragen und bereitgestellt. Dies hilft bei der Erstellung von Vorschaubildern und schützt die Privatsphäre der Benutzer." + allowExternalApRedirect: "Weiterleitungen für Anfragen über ActivityPub zulassen" + allowExternalApRedirect_description: "Wenn diese Option aktiviert ist, können andere Server Inhalte von Drittanbietern über diesen Server abfragen, was jedoch zu Content-Spoofing führen kann." + userGeneratedContentsVisibilityForVisitor: "Sichtbarkeit von nutzergenerierten Inhalten für Gäste" + userGeneratedContentsVisibilityForVisitor_description: "Dies ist nützlich, um zu verhindern, dass unangemessene Inhalte, die nicht gut moderiert sind, ungewollt über deinen eigenen Server im Internet veröffentlicht werden." + userGeneratedContentsVisibilityForVisitor_description2: "Die uneingeschränkte Veröffentlichung aller Inhalte des Servers im Internet, einschließlich der vom Server empfangenen Fremdinhalte, birgt Risiken. Dies ist besonders wichtig für Betrachter, die sich des dezentralen Charakters der Inhalte nicht bewusst sind, da sie selbst fremde Inhalte fälschlicherweise als auf dem Server erstellte Inhalte wahrnehmen könnten." + _userGeneratedContentsVisibilityForVisitor: + all: "Alles ist öffentlich" + localOnly: "Nur lokale Inhalte werden veröffentlicht, fremde Inhalte bleiben privat" + none: "Alles ist privat" _accountMigration: moveFrom: "Von einem anderen Konto zu diesem migrieren" moveFromSub: "Alias für ein anderes Konto erstellen" @@ -1962,6 +2014,11 @@ _role: canImportMuting: "Importieren von Stummgeschalteten zulassen" canImportUserLists: "Importieren von Listen erlauben" chatAvailability: "Chatten erlauben" + uploadableFileTypes: "Hochladbare Dateitypen" + uploadableFileTypes_caption: "Gibt die zulässigen MIME-/Dateitypen an. Mehrere MIME-Typen können durch einen Zeilenumbruch getrennt angegeben werden, und Platzhalter können mit einem Sternchen (*) angegeben werden. (z. B. image/*)" + uploadableFileTypes_caption2: "Bei manchen Dateien ist es nicht möglich, den Typ zu bestimmen. Um solche Dateien zuzulassen, füge {x} der Spezifikation hinzu." + noteDraftLimit: "Anzahl der möglichen Entwürfe für serverseitige Notizen" + watermarkAvailable: "Kann die Wasserzeichenfunktion verwenden" _condition: roleAssignedTo: "Manuellen Rollen zugewiesen" isLocal: "Lokaler Benutzer" @@ -2187,6 +2244,7 @@ _theme: install: "Farbschemata installieren" manage: "Farbschemaverwaltung" code: "Farbschemencode" + copyThemeCode: "Farbschemencode kopieren" description: "Beschreibung" installed: "{name} wurde installiert" installedThemes: "Installierte Farbschemata" @@ -2245,7 +2303,6 @@ _theme: buttonBg: "Hintergrund von Schaltflächen" buttonHoverBg: "Hintergrund von Schaltflächen (Mouseover)" inputBorder: "Rahmen von Eingabefeldern" - driveFolderBg: "Hintergrund von Drive-Ordnern" badge: "Wappen" messageBg: "Hintergrund von Chats" fgHighlighted: "Hervorgehobener Text" @@ -2462,7 +2519,7 @@ _widgets: chooseList: "Liste auswählen" clicker: "Klickzähler" birthdayFollowings: "Nutzer, die heute Geburtstag haben" - chat: "Chat" + chat: "Mit dem Benutzer chatten" _cw: hide: "Inhalt verbergen" show: "Inhalt anzeigen" @@ -2502,6 +2559,8 @@ _visibility: disableFederation: "Deföderieren" disableFederationDescription: "Nicht an andere Instanzen übertragen" _postForm: + quitInspiteOfThereAreUnuploadedFilesConfirm: "Es gibt Dateien, die nicht hochgeladen wurden. Möchtest du diese verwerfen und das Formular schließen?" + uploaderTip: "Die Datei wurde noch nicht hochgeladen. Über das Dateimenü kannst du sie umbenennen, das Bild zuschneiden, ein Wasserzeichen hinzufügen, komprimieren usw. Die Datei wird automatisch hochgeladen, wenn du eine Notiz veröffentlichst." replyPlaceholder: "Dieser Notiz antworten …" quotePlaceholder: "Diese Notiz zitieren …" channelPlaceholder: "In einen Kanal senden" @@ -2732,7 +2791,7 @@ _deck: mentions: "Erwähnungen" direct: "Direktnachrichten" roleTimeline: "Rollenchronik" - chat: "Chat" + chat: "Mit dem Benutzer chatten" _dialog: charactersExceeded: "Maximallänge überschritten! Momentan {current} von {max}" charactersBelow: "Minimallänge unterschritten! Momentan {current} von {min}" @@ -2885,9 +2944,12 @@ _dataSaver: _avatar: title: "Animierte Profilbilder deaktivieren" description: "Die Animation von Profilbildern wird angehalten. Da animierte Bilder eine größere Dateigröße haben können als normale Bilder, kann dies den Datenverkehr weiter reduzieren." - _urlPreview: + _urlPreviewThumbnail: title: "URL-Vorschaubilder ausblenden" description: "URL-Vorschaubilder werden nicht mehr geladen." + _disableUrlPreview: + title: "URL-Vorschau deaktivieren" + description: "Deaktiviert die URL-Vorschaufunktion. Anders als bei reinen Vorschaubildern wird dadurch das Laden der verlinkten Informationen selbst reduziert." _code: title: "Code-Hervorhebungen ausblenden" description: "Wenn Code-Hervorhebungen in MFC usw. verwendet werden, werden sie erst geladen, wenn sie angetippt werden. Die Syntaxhervorhebung erfordert das Herunterladen der Definitionsdateien für jede Programmiersprache. Es ist daher zu erwarten, dass die Deaktivierung des automatischen Ladens dieser Dateien die Menge des Datenverkehrs reduziert." @@ -2945,6 +3007,8 @@ _offlineScreen: _urlPreviewSetting: title: "Einstellungen der URL-Vorschau" enable: "URL-Vorschau aktivieren" + allowRedirect: "Umleitung von URL-Vorschauen erlauben" + allowRedirectDescription: "Wenn für eine URL eine Umleitung festgelegt ist, kann diese Funktion aktiviert werden, um der Umleitung zu folgen und eine Vorschau des umgeleiteten Inhalts anzuzeigen. Die Deaktivierung spart Serverressourcen, aber der Inhalt des Weiterleitungsziels wird nicht angezeigt." timeout: "Zeitüberschreitung beim Abrufen der Vorschau (ms)" timeoutDescription: "Übersteigt die für die Vorschau benötigte Zeit diesen Wert, wird keine Vorschau generiert." maximumContentLength: "Maximale Content-Length (Bytes)" @@ -3018,10 +3082,6 @@ _customEmojisManager: uploadSettingDescription: "Hier kannst du das Verhalten beim Hochladen von Emojis konfigurieren." directoryToCategoryLabel: "Gib den Namen des Verzeichnisses in das Feld „Kategorie“ ein" directoryToCategoryCaption: "Wenn du ein Verzeichnis ziehst und ablegst, gib den Verzeichnisnamen in das Feld „Kategorie“ ein." - emojiInputAreaCaption: "Wählen Sie die Emojis aus, die Sie mit einer der folgenden Methoden speichern möchten." - emojiInputAreaList1: "Ziehe Bilddateien oder Verzeichnisse per Drag-and-drop in diesen Rahmen" - emojiInputAreaList2: "Klicke auf diesen Link, um von deinem PC aus zu wählen" - emojiInputAreaList3: "Klicke auf diesen Link, um vom Drive aus zu wählen" confirmRegisterEmojisDescription: "Füge die in der Liste aufgeführten Emojis als neue benutzerdefinierte Emojis hinzu. Bist du sicher? (Um eine Überlastung zu vermeiden, können nur {count} Emoji(s) in einem Vorgang hinzugefügt werden)" confirmClearEmojisDescription: "Verwerfe die Bearbeitungen und lösche die Emojis aus der Liste. Bist du sicher, dass du fortfahren möchtest?" confirmUploadEmojisDescription: "Lade die {count} abgelegte(n) Datei(en) in das Drive hoch. Bist du sicher, dass du fortfahren möchtest?" @@ -3097,3 +3157,132 @@ _search: pleaseEnterServerHost: "Gib den Server-Host ein" pleaseSelectUser: "Benutzer auswählen" serverHostPlaceholder: "Beispiel: cherrypick.example.com" +_serverSetupWizard: + installCompleted: "Die Installation von CherryPick ist abgeschlossen!" + firstCreateAccount: "Erstelle zunächst ein Administratorkonto." + accountCreated: "Ein Administratorkonto wurde angelegt!" + serverSetting: "Servereinstellungen" + youCanEasilyConfigureOptimalServerSettingsWithThisWizard: "Mit diesem Assistenten lässt sich die optimale Serverkonfiguration leicht einrichten." + settingsYouMakeHereCanBeChangedLater: "Die Einstellungen hier können später geändert werden." + howWillYouUseMisskey: "Wie wirst du CherryPick verwenden?" + _use: + single: "Ein-Personen-Server" + single_description: "Verwende den Server alleine als deinen eigenen." + single_youCanCreateMultipleAccounts: "Bei Bedarf können mehrere Konten eingerichtet werden, auch wenn es sich um einen Ein-Personen-Server handelt." + group: "Gruppenserver" + group_description: "Lade andere vertrauenswürdige Benutzer ein und verwende es mit mehreren Personen." + open: "Offener Server" + open_description: "Registrierung für alle öffnen." + openServerAdvice: "Die Aufnahme einer unbestimmten Anzahl von Nutzern birgt Risiken. Es wird empfohlen, mit einem zuverlässigen Moderationssystem zu arbeiten, um eventuell auftretende Probleme behandeln zu können." + openServerAntiSpamAdvice: "Große Sorgfalt muss auch auf die Sicherheit gelegt werden, z. B. durch die Aktivierung von Anti-Bot-Funktionen wie reCAPTCHA, um sicherzustellen, dass der Server nicht zum Verbreiten von Spam genutzt wird." + howManyUsersDoYouExpect: "Mit wie vielen Benutzern rechnest du?" + _scale: + small: "Weniger als 100 (kleiner Maßstab)" + medium: "Mehr als 100 und weniger als 1000 Benutzer (mittelgroß)" + large: "Mehr als 1000 (großer Maßstab)" + largeScaleServerAdvice: "Für große Server sind unter Umständen fortgeschrittene Kenntnisse erforderlich, z. B. Lastverteilung und Datenbankreplikation." + doYouConnectToFediverse: "Mit dem Fediverse verbinden?" + doYouConnectToFediverse_description1: "Bei Anschluss an ein Netz von verteilten Servern (Fediverse) können Inhalte mit anderen Servern ausgetauscht werden." + doYouConnectToFediverse_description2: "Die Verbindung mit dem Fediverse wird auch als „Föderation“ bezeichnet." + youCanConfigureMoreFederationSettingsLater: "Erweiterte Einstellungen, wie z. B. die Angabe von föderierbaren Servern, können später vorgenommen werden." + adminInfo: "Administrator-Informationen" + adminInfo_description: "Legt die Administrator-Informationen fest, die für den Empfang von Anfragen verwendet werden." + adminInfo_mustBeFilled: "Dies ist auf einem offenen Server oder bei aktivierter Föderation erforderlich." + followingSettingsAreRecommended: "Die folgenden Einstellungen werden empfohlen" + applyTheseSettings: "Diese Einstellungen anwenden" + skipSettings: "Konfiguration überspringen" + settingsCompleted: "Einrichtung abgeschlossen!" + settingsCompleted_description: "Vielen Dank für deine Zeit. Jetzt, wo alles fertig ist, kannst du den Server sofort benutzen." + settingsCompleted_description2: "Detaillierte Servereinstellungen können über die „Systemsteuerung“ vorgenommen werden." + donationRequest: "Spendenaufruf" + _donationRequest: + text1: "CherryPick ist eine freie Software, die von Freiwilligen entwickelt wird." + text2: "Wir würden uns über deine Unterstützung freuen, damit wir dieses Projekt auch in Zukunft weiterentwickeln können." + text3: "Für Unterstützer gibt es auch besondere Vorteile!" +_uploader: + editImage: "Bild bearbeiten" + compressedToX: "Komprimiert zu {x}" + savedXPercent: "{x}% gespart" + abortConfirm: "Einige Dateien wurden nicht hochgeladen. Möchtest du den Vorgang abbrechen?" + doneConfirm: "Einige Dateien wurden nicht hochgeladen. Möchtest du den Vorgang fortsetzen?" + maxFileSizeIsX: "Die maximale Dateigröße, die hochgeladen werden kann, beträgt {x}." + allowedTypes: "Hochladbare Dateitypen" + tip: "Die Datei ist noch nicht hochgeladen worden. In diesem Dialog kannst du die Datei vor dem Hochladen anzeigen, umbenennen, komprimieren und zuschneiden. Wenn du fertig bist, klicke auf „Hochladen“, um den Upload zu starten." +_clientPerformanceIssueTip: + makeSureDisabledAdBlocker: "Deaktiviere deinen Adblocker" + makeSureDisabledAdBlocker_description: "Adblocker können die Leistung beeinträchtigen; vergewissere dich, ob in deinem Betriebssystem, Browser oder deinen Add-ons Adblocker aktiviert sind." + makeSureDisabledCustomCss: "Benutzerdefiniertes CSS deaktivieren" + makeSureDisabledCustomCss_description: "Das Überschreiben von Stilen kann die Leistung beeinträchtigen. Stelle daher sicher, dass du kein benutzerdefiniertes CSS oder Erweiterungen aktiviert hast, die Stile überschreiben." + makeSureDisabledAddons: "Erweiterungen deaktivieren" + makeSureDisabledAddons_description: "Einige Erweiterungen können das Verhalten des Clients stören und die Leistung beeinträchtigen. Deaktiviere die Browser-Erweiterungen und prüfe, ob sich die Situation dadurch verbessert." +_clip: + tip: "Clips sind eine Funktion, mit der du Notizen gruppieren kannst." +_userLists: + tip: "Es können Listen mit beliebigen Benutzern erstellt werden. Die erstellte Liste kann als eigene Chronik angezeigt werden." +watermark: "Wasserzeichen" +defaultPreset: "Standard-Voreinstellungen" +_watermarkEditor: + tip: "Dem Bild kann ein Wasserzeichen, z. B. eine Quellenangabe, hinzugefügt werden." + quitWithoutSaveConfirm: "Nicht gespeicherte Änderungen verwerfen?" + driveFileTypeWarn: "Diese Datei wird nicht unterstützt" + driveFileTypeWarnDescription: "Bilddatei auswählen" + title: "Wasserzeichen bearbeiten" + cover: "Alles bedecken" + opacity: "Transparenz" + scale: "Größe" + text: "Text" + position: "Position" + type: "Art" + image: "Bilder" + advanced: "Fortgeschritten" + angle: "Winkel" + stripe: "Streifen" + stripeWidth: "Linienbreite" + stripeFrequency: "Linienanzahl" + polkadot: "Punktmuster" + polkadotMainDotOpacity: "Deckkraft des Hauptpunktes" + polkadotMainDotRadius: "Größe des Hauptpunktes" + polkadotSubDotOpacity: "Deckkraft des Unterpunktes" + polkadotSubDotRadius: "Größe des Unterpunktes" + polkadotSubDotDivisions: "Anzahl der Unterpunkte" +_imageEffector: + title: "Effekte" + addEffect: "Effekte hinzufügen" + discardChangesConfirm: "Änderungen verwerfen und beenden?" + _fxs: + chromaticAberration: "Chromatische Abweichung" + glitch: "Glitch" + mirror: "Spiegeln" + invert: "Farben umkehren" + grayscale: "Schwarzweiß" + colorAdjust: "Farbkorrektur" + colorClamp: "Farbkomprimierung" + colorClampAdvanced: "Farbkomprimierung (erweitert)" + distort: "Verzerrung" + stripe: "Streifen" + polkadot: "Punktmuster" + _fxProps: + angle: "Winkel" + scale: "Größe" + size: "Größe" + offset: "Position" + color: "Farbe" + opacity: "Transparenz" + lightness: "Erhellen" +drafts: "Entwurf" +_drafts: + select: "Entwurf auswählen" + cannotCreateDraftAnymore: "Die Anzahl der Entwürfe, die erstellt werden können, wurde überschritten." + cannotCreateDraft: "Mit diesem Inhalt kann kein Entwurf erstellt werden." + delete: "Entwurf löschen" + deleteAreYouSure: "Entwurf löschen?" + noDrafts: "Keine Entwürfe" + replyTo: "Antwort an {user}" + quoteOf: "Zitat von {user}s Notiz" + saveToDraft: "Als Entwurf speichern" + restoreFromDraft: "Aus Entwurf wiederherstellen" + restore: "Wiederherstellen" + listDrafts: "Liste der Entwürfe" +_qr: + showTabTitle: "Anzeigeart" + raw: "Text" diff --git a/locales/el-GR.yml b/locales/el-GR.yml index c8aff304d2..a4874fb156 100644 --- a/locales/el-GR.yml +++ b/locales/el-GR.yml @@ -288,6 +288,7 @@ replies: "Απάντηση" renotes: "Κοινοποίηση σημειώματος" postForm: "Φόρμα δημοσίευσης" information: "Πληροφορίες" +widgets: "Μαραφέτια" _chat: members: "Μέλη" home: "Κεντρικό" @@ -353,6 +354,7 @@ _visibility: home: "Κεντρικό" homeDescription: "Δημοσίευση στο κεντρικό χρονολόγιο μόνο" followers: "Ακολουθούν" + specified: "Απευθείας σημειώματα" _profile: name: "Όνομα" username: "Όνομα μέλους" @@ -395,6 +397,7 @@ _deck: antenna: "Αντένες" list: "Λίστα" mentions: "Επισημάνσεις" + direct: "Απευθείας σημειώματα" _webhookSettings: name: "Όνομα" _moderationLogTypes: @@ -403,3 +406,5 @@ _reversi: total: "Σύνολο" _search: searchScopeLocal: "Τοπικό" +_watermarkEditor: + image: "Εικόνες" diff --git a/locales/en-US.yml b/locales/en-US.yml index 9244af8ff9..c2f688ace3 100644 --- a/locales/en-US.yml +++ b/locales/en-US.yml @@ -1,5 +1,21 @@ --- _lang_: "English" +compareContent: "Compare content" +editHistory: "Edit history" +unRenoteAll: "Remove all renote from notes" +unRenoteAllConfirm: "Remove all renote from notes" +unRenoteAllConfirmDescription: "All renotes for this note will be deleted. Still continue?" +alreadyRenotedConfirm: "Already renoted" +alreadyRenotedConfirmDescription: "You have already renoted this post. Renote it again?" +alreadyRenotedConfirmCaption: "Some software(e.g. Mastodon) only processes the first renote, so subsequent renotes may not appear." +autoDeleteNotes: "Auto-delete notes" +autoDeleteNotesDescription: "Automatically delete notes after a specified period." +autoDeleteNotesAfterDays: "Auto-delete period" +autoDeleteNotesAfterDaysDescription: "Notes older than this period will be automatically deleted. Leave empty to disable." +autoDeleteKeepFavorites: "Protect favorited notes" +autoDeleteKeepFavoritesDescription: "Favorited notes will not be automatically deleted." +autoDeleteNotesWarning: "This action cannot be undone. Deleted notes cannot be recovered." +scheduledToDeleteOnX: "Deletion is scheduled for {x}" showGapBodyOfTheNote: "Show a gap between body on the note" replyTo: "Replying to {user}" forceCollapseAllRenotes: "Collapse all renotes" @@ -19,8 +35,6 @@ disableRegistrationWhenInactive: "Disable new user registration when moderator i disablePublicNoteWhenInactive: "Disable 'Can send public notes' when moderator is inactivated" youBlocked: "You’re blocked" youBlockedDescription: "You can’t follow or see {user}’s posts." -schedulePost: "Posting a scheduled note" -schedulePostList: "List of scheduled notes" thereIsSchedulePost: "There are {n} notes scheduled for posting." welcomeBackToast: "Display a welcome message when you log in after a certain period of time" invalidTextLengthError: "Too many characters entered" @@ -31,7 +45,6 @@ useAutoTranslate: "Automatic translation" useAutoTranslateDescription: "Enabling the automatic translation feature automatically translates all notes in the timeline, which could potentially result in the API restriction policy set by the translation service provider temporarily disabling the translation feature.\n\nDo you still want to activate it?" cantUseThisFunctionDescription: "The server administrator has disabled {name}.\nPlease contact your server administrator to enable {name}." cantUseThisFunctionCaption: "When enabled, {name} will be applied when available again." -widgets: "Widgets" postNote: "Post note" bottomNavbar: "Bottom navigation bar" bottomNavbarDescription: "This setting is only available in a mobile environment." @@ -83,9 +96,9 @@ noteEdited: "Note are now edited." noteDrafted: "Note are now drafted." createSchedulePost: "Note are now scheduled to be posted." removeModalBgColorForBlur: "Remove modal background color" -skipThisVersion: "Skip this release" -enableReceivePrerelease: "Get notified of pre-release versions" -youAreRunningBetaClient: "Unreleased version of CherryPick in use!" +skipThisVersion: "Skip this versions" +enableReceivePrerelease: "Get notified of prerelease versions" +youAreRunningBetaClient: "Prerelease version of CherryPick in use!" cherrypickUpdate: "CherryPick Update" allMediaNoteCollapse: "Collapse all media notes" showingAnimatedImagesDescription: "When set to \"Animate on interaction\", the image will play when you hover over it or touch it." @@ -212,7 +225,7 @@ import: "Import" export: "Export" files: "Files" download: "Download" -driveFileDeleteConfirm: "Do you want to remove the file \"{name}\"? Some content using this file will also be removed." +driveFileDeleteConfirm: "Are you sure you want to delete \"{name}\"? All notes with this file attached will also be deleted." unfollowConfirm: "Are you sure you want to unfollow {name}?" exportRequested: "You've requested an export. This may take a while. It will be added to your Drive once completed." importRequested: "You've requested an import. This may take a while." @@ -388,9 +401,9 @@ noUsers: "There are no users" editProfile: "Edit profile" noteDeleteConfirm: "Are you sure you want to delete this note?" pinLimitExceeded: "You cannot pin any more notes" -intro: "Installation of CherryPick has been finished! Please create an admin user." done: "Done" processing: "Processing..." +preprocessing: "Preparing..." preview: "Preview" default: "Default" defaultValueIs: "Default: {value}" @@ -436,6 +449,7 @@ uploadFromUrl: "Upload from a URL" uploadFromUrlDescription: "URL of the file you want to upload" uploadFromUrlRequested: "Upload requested" uploadFromUrlMayTakeTime: "It may take some time until the upload is complete." +uploadNFiles: "Upload {n} files" explore: "Explore" messageRead: "Read" noMoreHistory: "There is no further history" @@ -465,11 +479,13 @@ dark: "Dark" lightThemes: "Light themes" darkThemes: "Dark themes" syncDeviceDarkMode: "Sync Dark Mode with your device settings" +switchDarkModeManuallyWhenSyncEnabledConfirm: "\"{x}\" is turned on. Would you like to turn off synchronization and switch modes manually?" drive: "Drive" fileName: "Filename" selectFile: "Select a file" selectFiles: "Select files" selectFolder: "Select a folder" +unselectFolder: "Deselect folder" selectFolders: "Select folders" fileNotSelected: "No file selected" renameFile: "Rename file" @@ -482,6 +498,7 @@ addFile: "Add a file" showFile: "Show files" emptyDrive: "Your Drive is empty" emptyFolder: "This folder is empty" +dropHereToUpload: "Drop files here to upload" unableToDelete: "Unable to delete" inputNewFileName: "Enter a new filename" inputNewDescription: "Enter new alt text" @@ -637,7 +654,6 @@ inviteToGroup: "Invite to group" quoteAttached: "Quote" quoteQuestion: "Append as quote?" attachAsFileQuestion: "The text in clipboard is long. Would you want to attach it as text file?" -newMessageExists: "There are new messages" onlyOneFileCanBeAttached: "You can only attach one file to a message" signinRequired: "Please register or sign in before continuing" signinOrContinueOnRemote: "To continue, you need to move your server or sign up / log in to this server." @@ -728,13 +744,10 @@ showFixedPostFormInChannel: "Display the posting form at the top of the timeline withRepliesByDefaultForNewlyFollowed: "Include replies by newly followed users in the timeline by default" newNoteRecived: "There are new notes" newNoteRecivedCount: "There are {n} new notes" +newNote: "New Note" sounds: "Sounds" sound: "Sounds" -vibrations: "Vibrations" -soundsAndVibrations: "Sounds & Vibrations" -playVibrations: "Play vibrations" -playVibrationsDescription: "This feature is not supported on iOS/iPadOS." -testVibrations: "Play test vibrations" +notificationSoundSettings: "Notification sound settings" listen: "Listen" none: "None" showInPage: "Show in page" @@ -927,6 +940,7 @@ alwaysMarkSensitive: "Mark as sensitive by default" loadRawImages: "Load original images instead of showing thumbnails" disableShowingAnimatedImages: "Don't play animated images" disableShowingAnimatedImagesDescription: "When disabled, the animated images will play. Be careful as it may cause photosensitive seizures." +disableShowingAnimatedImages_caption: "If animated images do not play even if this setting is disabled, it may be due to browser or OS accessibility settings, power-saving settings, or similar factors." highlightSensitiveMedia: "Highlight sensitive media" verificationEmailSent: "A verification email has been sent. Please follow the included link to complete verification.\nIf you do not receive an email, please check your spam folder." notSet: "Not set" @@ -952,6 +966,7 @@ narrow: "Narrow" reloadToApplySetting: "This setting will only apply after a page reload. Reload now?" reloadToApplySetting2: "This setting will only apply after a page reload." needReloadToApply: "A reload is required for this to be reflected." +needToRestartServerToApply: "A CherryPick restart is required to reflect the change." showTitlebar: "Show title bar" clearCache: "Clear cache" onlineUsersCount: "{n} users are online" @@ -976,8 +991,8 @@ registry: "Registry" closeAccount: "Close account" currentVersion: "Current version" latestVersion: "Newest version" -youAreRunningUpToDateClient: "You are using the newest version of your client." -newVersionOfClientAvailable: "There is a newer version of your client available." +youAreRunningUpToDateClient: "CherryPick is up to date." +newVersionOfClientAvailable: "There is a newer version of CherryPick available." usageAmount: "Usage" capacity: "Capacity" inUse: "Used" @@ -1161,6 +1176,7 @@ failedToUpload: "Upload failed" cannotUploadBecauseInappropriate: "This file could not be uploaded because parts of it have been detected as potentially inappropriate." cannotUploadBecauseNoFreeSpace: "Upload failed due to lack of Drive capacity." cannotUploadBecauseExceedsFileSizeLimit: "This file cannot be uploaded as it exceeds the file size limit." +cannotUploadBecauseUnallowedFileType: "Unable to upload due to unauthorized file type." beta: "Beta" enableAutoSensitive: "Automatic marking as sensitive" enableAutoSensitiveDescription: "Allows automatic detection and marking of sensitive media through Machine Learning where possible. Even if this option is disabled, it may be enabled instance-wide." @@ -1212,6 +1228,7 @@ permissionDeniedError: "Operation denied" permissionDeniedErrorDescription: "This account does not have the permission to perform this action." preset: "Preset" selectFromPresets: "Choose from presets" +custom: "Custom" achievements: "Achievements" gotInvalidResponseError: "Invalid server response" gotInvalidResponseErrorDescription: "The server may be unreachable or undergoing maintenance. Please try again later." @@ -1251,6 +1268,7 @@ prohibitedWordsDescription2: "Using spaces will create AND expressions and surro hiddenTags: "Hidden hashtags" hiddenTagsDescription: "Select tags which will not shown on trend list.\nMultiple tags could be registered by lines." notesSearchNotAvailable: "Note search is unavailable." +usersSearchNotAvailable: "User search is not available." license: "License" unfavoriteConfirm: "Really remove from favorites?" myClips: "My clips" @@ -1328,6 +1346,7 @@ installed: "Installed" branding: "Branding" enableServerMachineStats: "Publish server hardware stats" enableIdenticonGeneration: "Enable user identicon generation" +showRoleBadgesOfRemoteUsers: "Display the role badges assigned to remote users" turnOffToImprovePerformance: "Turning this off can increase performance." createInviteCode: "Generate invite" createWithOptions: "Generate with options" @@ -1381,8 +1400,8 @@ showRepliesToOthersInTimeline: "Show replies to others in timeline" hideRepliesToOthersInTimeline: "Hide replies to others from timeline" showRepliesToOthersInTimelineAll: "Show replies to others from everyone you follow in timeline" hideRepliesToOthersInTimelineAll: "Hide replies to others from everyone you follow in timeline" -confirmShowRepliesAll: "This operation is irreversible. Would you really like to show replies to others from everyone you follow in your timeline?" -confirmHideRepliesAll: "This operation is irreversible. Would you really like to hide replies to others from everyone you follow in your timeline?" +confirmShowRepliesAll: "Are you sure you want to show replies from everyone you follow in your timeline? This action is irreversible." +confirmHideRepliesAll: "Are you sure you want to hide replies from everyone you follow in your timeline? This action is irreversible." externalServices: "External Services" sourceCode: "Source code" sourceCodeIsNotYetProvided: "Source code is not yet available. Contact the administrator to fix this problem." @@ -1409,9 +1428,8 @@ showAvatarDecorations: "Show avatar decorations" releaseToRefresh: "Release to refresh" refreshing: "Refreshing..." pullDownToRefresh: "Pull down to refresh" -disableStreamingTimeline: "Disable real-time timeline updates" useGroupedNotifications: "Display grouped notifications" -signupPendingError: "There was a problem verifying the email address. The link may have expired." +emailVerificationFailedError: "A problem occurred while verifying your email address. The link may have expired." cwNotationRequired: "If \"Hide content\" is enabled, a description must be provided." doReaction: "Add reaction" code: "Code" @@ -1473,7 +1491,7 @@ passkeyVerificationSucceededButPasswordlessLoginDisabled: "Passkey verification messageToFollower: "Message to followers" target: "Target" testCaptchaWarning: "This function is intended for CAPTCHA testing purposes.\nDo not use in a production environment." -prohibitedWordsForNameOfUser: "Prohibited words for user names" +prohibitedWordsForNameOfUser: "Prohibited words for usernames" prohibitedWordsForNameOfUserDescription: "If any of the strings in this list are included in the user's name, the name will be denied. Users with moderator privileges are not affected by this restriction." yourNameContainsProhibitedWords: "Your name contains prohibited words" yourNameContainsProhibitedWordsDescription: "If you wish to use this name, please contact your server administrator." @@ -1484,6 +1502,8 @@ availableRoles: "Available roles" acknowledgeNotesAndEnable: "Turn on after understanding the precautions." federationSpecified: "This server is operated in a whitelist federation. Interacting with servers other than those designated by the administrator is not allowed." federationDisabled: "Federation is disabled on this server. You cannot interact with users on other servers." +draft: "Drafts" +draftsAndScheduledNotes: "Drafts and scheduled notes" confirmOnReact: "Confirm when reacting" reactAreYouSure: "Would you like to add a \"{emoji}\" reaction?" markAsSensitiveConfirm: "Do you want to set this media as sensitive?" @@ -1501,6 +1521,7 @@ restore: "Restore" syncBetweenDevices: "Sync between devices" preferenceSyncConflictTitle: "The configured value exists on the server." preferenceSyncConflictText: "The sync enabled settings will save their values to the server. However, there are existing values on the server. Which set of values would you like to overwrite?" +preferenceSyncConflictChoiceMerge: "Merge" preferenceSyncConflictChoiceServer: "Configured value on server" preferenceSyncConflictChoiceDevice: "Configured value on device" preferenceSyncConflictChoiceCancel: "Cancel enabling sync" @@ -1510,6 +1531,8 @@ postForm: "Posting form" textCount: "Character count" information: "About" chat: "Chat" +directMessage: "Chat with user" +directMessage_short: "Message" migrateOldSettings: "Migrate old client settings" migrateOldSettings_description: "This should be done automatically but if for some reason the migration was not successful, you can trigger the migration process yourself manually. The current configuration information will be overwritten." compress: "Compress" @@ -1523,7 +1546,38 @@ goToDeck: "Return to Deck" federationJobs: "Federation Jobs" driveAboutTip: "In Drive, a list of files you've uploaded in the past will be displayed.
\nYou can reuse these files when attaching them to notes, or you can upload files in advance to post later.
\nBe careful when deleting a file, as it will not be available in all places where it was used (such as notes, pages, avatars, banners, etc.).
\nYou can also create folders to organize your files." scrollToClose: "Scroll to close" -draft: "Draft" +advice: "Advice" +realtimeMode: "Real-time mode" +turnItOn: "Turn on" +turnItOff: "Turn off" +emojiMute: "Mute emoji" +emojiUnmute: "Unmute emoji" +muteX: "Mute {x}" +unmuteX: "Unmute {x}" +abort: "Abort" +tip: "Tips & Tricks" +redisplayAllTips: "Show all “Tips & Tricks” again" +hideAllTips: "Hide all \"Tips & Tricks\"" +defaultImageCompressionLevel: "Default image compression level" +defaultImageCompressionLevel_description: "Lower level preserves image quality but increases file size.
Higher level reduce file size, but reduce image quality." +defaultCompressionLevel: "Default compression level" +defaultCompressionLevel_description: "Lower compression preserves quality but increases file size.
Higher compression reduces file size but lowers quality." +inMinutes: "Minute(s)" +inDays: "Day(s)" +safeModeEnabled: "Safe mode is enabled" +pluginsAreDisabledBecauseSafeMode: "All plugins are disabled because safe mode is enabled." +customCssIsDisabledBecauseSafeMode: "Custom CSS is not applied because safe mode is enabled." +themeIsDefaultBecauseSafeMode: "While safe mode is active, the default theme is used. Disabling safe mode will revert these changes." +thankYouForTestingBeta: "Thank you for helping us test the beta version!" +createUserSpecifiedNote: "Create a direct note" +schedulePost: "Schedule note" +scheduleToPostOnX: "Scheduled to note on {x}" +scheduledToPostOnX: "Note is scheduled for {x}" +schedule: "Schedule" +scheduled: "Scheduled" +widgets: "Widgets" +deviceInfo: "Device information" +deviceInfoDescription: "When making technical inquiries, including the following information may help resolve the issue." draftNoteList: "List of draft notes" saveAsDraft: "Save as Draft" showUnreadNotificationsCount: "Show the number of unread notifications" @@ -1538,16 +1592,24 @@ open: "Open" _nsfwOpenBehavior: click: "Click to open" doubleClick: "Double click to open" -_vibrations: - click: "When an element is clicked" - note: "When a new note is posted on the timeline" - notification: "When a receive the notifications" - system: "System Haptics" _showingAnimatedImages: always: "Always animate" interaction: "Animate on interaction" inactive: "Stop after a certain amount of time" +_compression: + _quality: + high: "High quality" + medium: "Medium quality" + low: "Low quality" + _size: + large: "Large size" + medium: "Medium size" + small: "Small size" +_order: + newest: "Newest First" + oldest: "Oldest First" _chat: + messages: "Messages" noMessagesYet: "No messages yet" newMessage: "New message" individualChat: "Private Chat" @@ -1566,6 +1628,7 @@ _chat: inviteUser: "Invite Users" sentInvitations: "Sent Invites" join: "Join" + reject: "Reject" ignore: "Ignore" leave: "Leave room" members: "Members" @@ -1576,10 +1639,12 @@ _chat: muteThisRoom: "Mute room" deleteRoom: "Delete room" chatNotAvailableForThisAccountOrServer: "Chat is not enabled on this server or for this account." - chatIsReadOnlyForThisAccountOrServer: "Chat is read-only on this instance or this account. You cannot write new messages or create/join chat rooms." - chatNotAvailableInOtherAccount: "The chat function is disabled for the other user." + chatIsReadOnlyForThisAccountOrServer: "Chat is read-only on this server or this account. You cannot write new messages or create/join chat rooms." + chatNotAvailableInOtherAccount: "The chat function is disabled for the other user. If you send a message, it will be sent in a direct note, and if the other party replies to the direct note, you can see it here." cannotChatWithTheUser: "Cannot start a chat with this user" cannotChatWithTheUser_description: "Chat is either unavailable or the other party has not enabled chat." + youAreNotAMemberOfThisRoomButInvited: "You are not a participant in this room, but you have received an invitation. Please accept the invitation to join." + doYouAcceptInvitation: "Do you accept the invitation?" chatWithThisUser: "Chat with user" thisUserAllowsChatOnlyFromFollowers: "This user accepts chats from followers only." thisUserAllowsChatOnlyFromFollowing: "This user accepts chats only from users they follow." @@ -1600,7 +1665,10 @@ _chat: following: "Only users you are following" mutual: "Mutual followers only" none: "Nobody" - + usersCount: "{n} Participants" + invitationCancelAreYouSure: "Are you sure you want to cancel the invitation sent to {x}?" + ignoreThisInvitation: "If you ignore this invitation, you can only be invited if the room administrator cancels the invitation and invites it again, or if you delete the room and recreate it." + doYouIgnoreInvitation: "Do you ignore the invitation?" _emojiPalette: palettes: "Palette" enableSyncBetweenDevicesForPalettes: "Enable palette sync between devices" @@ -1628,12 +1696,22 @@ _settings: makeEveryTextElementsSelectable: "Make all text elements selectable" makeEveryTextElementsSelectable_description: "Enabling this may reduce usability in some situations." useStickyIcons: "Make icons follow while scrolling" + enableHighQualityImagePlaceholders: "Display placeholders for high quality images" + uiAnimations: "UI Animations" showNavbarSubButtons: "Show sub-buttons on the navigation bar" ifOn: "When turned on" ifOff: "When turned off" enableSyncThemesBetweenDevices: "Synchronize installed themes across devices" enablePullToRefresh: "Pull to Refresh" enablePullToRefresh_description: "When using a mouse, drag while pressing in the scroll wheel." + realtimeMode_description: "Establishes a connection with the server and updates content in real time. This may increase traffic and memory consumption." + contentsUpdateFrequency: "Frequency of content retrieval" + contentsUpdateFrequency_description: "The higher the value the more the content updates but it lowers the performance and increases the traffic and memory consumption." + contentsUpdateFrequency_description2: "When real-time mode is on, content is updated in real time regardless of this setting." + showUrlPreview: "Show URL preview" + showAvailableReactionsFirstInNote: "Show available reactions at the top." + showPageTabBarBottom: "Show page tab bar at the bottom" + smoothTransitionAnimations: "Smooth transition animation" _chat: showSenderName: "Show sender's name" sendOnEnter: "Press Enter to send" @@ -1641,6 +1719,7 @@ _preferencesProfile: profileName: "Profile name" profileNameDescription: "Set a name that identifies this device." profileNameDescription2: "Example: \"Main PC\", \"Smartphone\"" + manageProfiles: "Manage Profiles" _preferencesBackup: autoBackup: "Auto backup" restoreFromBackup: "Restore from backup" @@ -1672,7 +1751,7 @@ _abuseUserReport: resolveTutorial: "If the report's content is legitimate, select \"Accept\" to mark it as resolved.\nIf the report's content is illegitimate, select \"Reject\" to ignore it." _delivery: status: "Delivery status" - stop: "Suspended" + stop: "Suspend" resume: "Delivery resume" _type: none: "Publishing" @@ -1812,6 +1891,8 @@ _initialTutorial: local: "You can view notes from all users on this server." social: "Notes from the Home and Local timelines will be displayed." global: "You can view notes from all connected servers." + media: "Notes from the Home and Local timelines that contain media will be displayed." + bubble: "You can see notes from servers set up by the administrator." description2: "You can switch between timelines at the top of the screen at any time." description3: "Additionally, there are list timelines and channel timelines. For more details, please refer to {link}." _postNote: @@ -1850,6 +1931,7 @@ _timelineDescription: local: "In the Local timeline, you can see notes from all users on this server." social: "The Social timeline displays notes from both the Home and Local timelines." global: "In the Global timeline, you can see notes from all connected servers." + media: "The Media timeline displays notes that contain media from both the Home and Local timelines." bubble: "In the Bubble timeline, you can see notes from servers set up by the administrator." _serverRules: description: "A set of rules to be displayed before registration. Setting a summary of the Terms of Service is recommended." @@ -1892,6 +1974,10 @@ _serverSettings: fanoutTimelineDbFallback: "Fallback to database" fanoutTimelineDbFallbackDescription: "When enabled, the timeline will fall back to the database for additional queries if the timeline is not cached. Disabling it further reduces the server load by eliminating the fallback process, but limits the range of timelines that can be retrieved." reactionsBufferingDescription: "When enabled, performance during reaction creation will be greatly improved, reducing the load on the database. However, Redis memory usage will increase." + remoteNotesCleaning: "Automatic cleanup of remote notes" + remoteNotesCleaning_description: "When enabled, unused and outdated remote notes will be periodically cleaned up to prevent database bloat." + remoteNotesCleaningMaxProcessingDuration: "Maximum cleanup processing time" + remoteNotesCleaningExpiryDaysForEachNotes: "Minimum days to retain notes" inquiryUrl: "Inquiry URL" inquiryUrlDescription: "Specify a URL for the inquiry form to the server maintainer or a web page for the contact information." openRegistration: "Make the account creation open" @@ -1899,6 +1985,26 @@ _serverSettings: thisSettingWillAutomaticallyOffWhenModeratorsInactive: "If no moderator activity is detected for a while, this setting will be automatically turned off to prevent spam." deliverSuspendedSoftware: "Suspended Software" deliverSuspendedSoftwareDescription: "You can specify a range of names and versions of the server's software to stop delivery for vulnerability or other reasons. This version information is provided by the server and is not guaranteed to be reliable. A semver range specification can be used to specify the version, but specifying >= 2024.3.1 will not include custom versions such as 2024.3.1-custom.0, so it is recommended that a prerelease specification be used, such as >= 2024.3.1-0" + singleUserMode: "Single user mode" + singleUserMode_description: "If you are the only user of this server, enabling this mode will optimize its performance." + signToActivityPubGet: "Sign ActivityPub GET requests" + signToActivityPubGet_description: "Normally, this should be enabled. Disabling it may improve issues related to federation, but on the other hand it could disable federation towards some other servers." + proxyRemoteFiles: "Proxy remote files" + proxyRemoteFiles_description: "When enabled, the server will proxy and serve remote files. This is useful for generating image thumbnails and protecting user privacy." + allowExternalApRedirect: "Allow redirects for queries via ActivityPub" + allowExternalApRedirect_description: "If enabled, other servers can query third-party content through this server but this may result in content spoofing." + userGeneratedContentsVisibilityForVisitor: "Visibility of user-generated content to guests" + userGeneratedContentsVisibilityForVisitor_description: "This is useful for preventing problems caused by inappropriate remote content that is not well moderated from being unintentionally published on the Internet via your own server." + userGeneratedContentsVisibilityForVisitor_description2: "Unconditionally publishing all content on the server to the Internet, including remote content received by the server is risky. This is especially important for guests who are unaware of the distributed nature of the content, as they may mistakenly believe that even remote content is content created by users on the server." + restartServerSetupWizardConfirm_title: "Restart server setup wizard?" + restartServerSetupWizardConfirm_text: "Some current settings will be reset." + entrancePageStyle: "Entrance page style" + showTimelineForVisitor: "Show timeline" + showActivitiesForVisitor: "Show activities" + _userGeneratedContentsVisibilityForVisitor: + all: "Everything is public" + localOnly: "Only local content is published, remote content is kept private" + none: "Everything is private" _accountMigration: moveFrom: "Migrate another account to this one" moveFromSub: "Create alias to another account" @@ -2213,7 +2319,6 @@ _role: btlAvailable: "Can view the bubble timeline" canPublicNote: "Can send public notes" canEditNote: "Note editing" - scheduleNoteMax: "Maximum number of scheduled notes" mentionMax: "Maximum number of mentions in a note" canInvite: "Can create instance invite codes" inviteLimit: "Invite limit" @@ -2223,6 +2328,7 @@ _role: canManageAvatarDecorations: "Manage avatar decorations" driveCapacity: "Drive capacity" maxFileSize: "Upload-able max file size" + maxFileSize_caption: "Reverse proxies, CDNs, and other front-end components may have their own configuration settings." alwaysMarkNsfw: "Always mark files as NSFW" canUpdateBioMedia: "Can edit an icon or a banner image" pinMax: "Maximum number of pinned notes" @@ -2237,17 +2343,23 @@ _role: descriptionOfRateLimitFactor: "Lower rate limits are less restrictive, higher ones more restrictive. " canHideAds: "Can hide ads" canSearchNotes: "Usage of note search" + canSearchUsers: "User search" canUseTranslator: "Translator usage" canUseAutoTranslate: "Automatic translation usage" canUseAutoTranslateDescription: "Users who enable the automatic translation feature will have all notes in their timeline automatically translated, which can very quickly reach the API limits set by the translation service provider, potentially temporarily disabling the translation feature.\nThis means that all users on the server may be temporarily unable to use the API.\nAdditionally, depending on the translation service provider, you may be charged excessive fees for API usage.\n\nDo you still want to enable it?" - avatarDecorationLimit: "Maximum number of avatar decorations that can be applied" - canImportAntennas: "Allow importing antennas" - canImportBlocking: "Allow importing blocking" - canImportFollowing: "Allow importing following" - canImportMuting: "Allow importing muting" - canImportUserLists: "Allow importing lists" - chatAvailability: "Allow Chat" - noteDraftLimit: "Maximum number of server-side note drafts available" + avatarDecorationLimit: "Maximum number of avatar decorations" + canImportAntennas: "Can import antennas" + canImportBlocking: "Can import blocking" + canImportFollowing: "Can import following" + canImportMuting: "Can import muting" + canImportUserLists: "Can import lists" + chatAvailability: "Chat" + uploadableFileTypes: "Uploadable file types" + uploadableFileTypes_caption: "Specifies the allowed MIME/file types. Multiple MIME types can be specified by separating them with a new line, and wildcards can be specified with an asterisk (*). (e.g., image/*)" + uploadableFileTypes_caption2: "Some files types might fail to be detected. To allow such files, add {x} to the specification." + noteDraftLimit: "Number of possible drafts of server notes" + scheduledNoteLimit: "Maximum number of simultaneous scheduled notes" + watermarkAvailable: "Watermark function" canSetFederationAvatarShape: "Allow federation of avatar shape settings" _condition: roleAssignedTo: "Assigned to manual roles" @@ -2499,6 +2611,7 @@ _theme: install: "Install a theme" manage: "Manage themes" code: "Theme code" + copyThemeCode: "Copy theme code" description: "Description" installed: "{name} has been installed" installedThemes: "Installed themes" @@ -2557,7 +2670,6 @@ _theme: buttonBg: "Button background" buttonHoverBg: "Button background (Hover)" inputBorder: "Input field border" - driveFolderBg: "Drive folder background" badge: "Badge" messageBg: "Chat background" fgHighlighted: "Highlighted Text" @@ -2601,6 +2713,7 @@ _time: minute: "Minute(s)" hour: "Hour(s)" day: "Day(s)" + month: "Month(s)" _2fa: alreadyRegistered: "You have already registered a 2-factor authentication device." registerTOTP: "Register authenticator app" @@ -2646,8 +2759,6 @@ _permissions: "read:mutes": "View your list of muted users" "write:mutes": "Edit your list of muted users" "write:notes": "Compose or delete notes" - "read:notes-schedule": "View your list of scheduled notes" - "write:notes-schedule": "Compose or delete scheduled notes" "read:notifications": "View your notifications" "write:notifications": "Manage your notifications" "read:reactions": "View your reactions" @@ -2675,7 +2786,7 @@ _permissions: "read:admin:index-stats": "View database index stats" "read:admin:table-stats": "View database table stats" "read:admin:user-ips": "View user IP addresses" - "read:admin:meta": "View instance metadata" + "read:admin:meta": "View server metadata" "write:admin:reset-password": "Reset user password" "write:admin:resolve-abuse-user-report": "Resolve user report" "write:admin:send-email": "Send email" @@ -2686,7 +2797,7 @@ _permissions: "write:admin:unset-user-avatar": "Remove user avatar" "write:admin:unset-user-banner": "Remove user banner" "write:admin:unsuspend-user": "Unsuspend user" - "write:admin:meta": "Manage instance metadata" + "write:admin:meta": "Manage server metadata" "write:admin:user-note": "Manage moderation note" "write:admin:roles": "Manage roles" "read:admin:roles": "View roles" @@ -2732,6 +2843,7 @@ _auth: scopeUser: "Operate as the following user" pleaseLogin: "Please log in to authorize applications." byClickingYouWillBeRedirectedToThisUrl: "When access is granted, you will automatically be redirected to the following URL" + alreadyAuthorized: "This application already has access permission." _antennaSources: all: "All notes" homeTimeline: "Notes from followed users" @@ -2778,7 +2890,7 @@ _widgets: chooseList: "Select a list" clicker: "Clicker" birthdayFollowings: "Today's Birthdays" - chat: "Chat" + chat: "Chat with user" search: "Search" dice: "Dice" weather: "Weather" @@ -2821,6 +2933,8 @@ _visibility: disableFederation: "Defederate" disableFederationDescription: "Don't transmit to other instances" _postForm: + quitInspiteOfThereAreUnuploadedFilesConfirm: "There are files that have not been uploaded, do you want to discard them and close the form?" + uploaderTip: "The file has not yet been uploaded. From the file menu, you can rename, crop images, watermark and compress or uncompress the file. Files are automatically uploaded when you publish a note." signinRequiredPlaceholder: "You must be logged in to create a notes." replyPlaceholder: "Reply to this note..." quotePlaceholder: "Quote this note..." @@ -2898,6 +3012,7 @@ _timelines: local: "Local" social: "Social" global: "Global" + media: "Media" bubble: "Bubble" _play: new: "Create Play" @@ -2980,6 +3095,8 @@ _notification: yourFollowRequestAccepted: "Your follow request was accepted" youWereInvitedToGroup: "{userName} invited you to a group" pollEnded: "Poll results have become available" + scheduledNotePosted: "Scheduled note has been posted" + scheduledNotePostFailed: "Failed to post scheduled note" newNote: "New note" unreadAntennaNote: "Antenna {name}" roleAssigned: "Role given" @@ -3011,6 +3128,8 @@ _notification: quote: "Quotes" reaction: "Reactions" pollEnded: "Polls ending" + scheduledNotePosted: "Scheduled note was successful" + scheduledNotePostFailed: "Scheduled note failed" receiveFollowRequest: "Received follow requests" followRequestAccepted: "Accepted follow requests" groupInvited: "Group invitations" @@ -3027,12 +3146,6 @@ _notification: followBack: "followed you back" reply: "Reply" renote: "Renote" - _scheduleNote: - unknown: "The cause is unknown" - renoteTargetNotFound: "Renote target note not found" - channelTargetNotFound: "Channel not found" - replyTargetNotFound: "Reply target note not found" - invalidFilesCount: "No attachments" _deck: alwaysShowMainColumn: "Always show main column" columnAlign: "Align columns" @@ -3069,7 +3182,7 @@ _deck: mentions: "Mentions" direct: "Direct notes" roleTimeline: "Role Timeline" - chat: "Chat" + chat: "Chat with user" _dialog: charactersExceeded: "You've exceeded the maximum character limit! Currently at {current} of {max}." charactersBelow: "You're below the minimum character limit! Currently at {current} of {min}." @@ -3142,7 +3255,7 @@ _moderationLogTypes: resetPassword: "Password reset" suspendRemoteInstance: "Remote instance suspended" unsuspendRemoteInstance: "Remote instance unsuspended" - updateRemoteInstanceNote: "Moderation note updated for remote instance." + updateRemoteInstanceNote: "Updated moderation note for remote servers" markSensitiveDriveFile: "File marked as sensitive" unmarkSensitiveDriveFile: "File unmarked as sensitive" resolveAbuseReport: "Report resolved" @@ -3176,6 +3289,7 @@ _fileViewer: url: "URL" uploadedAt: "Uploaded at" attachedNotes: "Attached notes" + usage: "Used" thisPageCanBeSeenFromTheAuthor: "This page can only be seen by the user who uploaded this file." _externalResourceInstaller: title: "Install from external site" @@ -3223,9 +3337,12 @@ _dataSaver: _avatar: title: "Avatar image" description: "Stop avatar image animation. Animated images can be larger in file size than normal images, potentially leading to further reductions in data traffic." - _urlPreview: - title: "URL preview thumbnails" + _urlPreviewThumbnail: + title: "Hide URL preview thumbnails" description: "URL preview thumbnail images will no longer be loaded." + _disableUrlPreview: + title: "Disable URL preview" + description: "Disables the URL preview function. Unlike thumbnail images, this function reduces the loading of the linked information itself." _code: title: "Code highlighting" description: "If code highlighting notations are used in MFC, etc., they will not load until tapped. Syntax highlighting requires downloading the highlight definition files for each programming language. Therefore, disabling the automatic loading of these files is expected to reduce the amount of communication data." @@ -3284,6 +3401,8 @@ _offlineScreen: _urlPreviewSetting: title: "URL preview settings" enable: "Enable URL preview" + allowRedirect: "Allow URL preview redirection" + allowRedirectDescription: "If a URL has a redirection set, you can enable this feature to follow the redirection and display a preview of the redirected content. Disabling this will save server resources, but redirected content will not be displayed." timeout: "Time out when getting preview (ms)" timeoutDescription: "If it takes longer than this value to get the preview, the preview won’t be generated." maximumContentLength: "Maximum Content-Length (bytes)" @@ -3345,7 +3464,7 @@ _customEmojisManager: markAsDeleteTargetRanges: "Mark rows in the selection as a target to delete" alertUpdateEmojisNothingDescription: "There are no updated Emojis." alertDeleteEmojisNothingDescription: "There are no Emojis to be deleted." - confirmMovePage: "" + confirmMovePage: "Would you like to move pages?" confirmChangeView: "" confirmUpdateEmojisDescription: "Update {count} Emoji(s). Are you sure to continue?" confirmDeleteEmojisDescription: "Delete checked {count} Emoji(s). Are you sure to continue?" @@ -3357,10 +3476,6 @@ _customEmojisManager: uploadSettingDescription: "On this screen, you can configure the behavior when uploading Emojis." directoryToCategoryLabel: "Enter the directory name in the \"category\" field" directoryToCategoryCaption: "When you drag and drop a directory, enter the directory name in the \"category\" field." - emojiInputAreaCaption: "Select the Emojis you wish to register using one of the methods." - emojiInputAreaList1: "Drag and drop image files or a directory into this frame" - emojiInputAreaList2: "Click this link to select from your computer" - emojiInputAreaList3: "Click this link to select from the drive" confirmRegisterEmojisDescription: "Register the Emojis from the list as new custom Emojis. Are you sure to continue? (To avoid overload, only {count} Emoji(s) can be registered in a single operation)" confirmClearEmojisDescription: "Discard the edits and clear the Emojis from the list. Are you sure to continue?" confirmUploadEmojisDescription: "Upload the dragged and dropped {count} file(s) to the drive. Are you sure to continue?" @@ -3429,6 +3544,7 @@ _bootErrors: otherOption1: "Delete client settings and cache" otherOption2: "Start the simple client" otherOption3: "Launch the repair tool" + otherOption4: "Launch CherryPick in safe mode" _search: searchScopeAll: "All" searchScopeLocal: "Local" @@ -3437,14 +3553,198 @@ _search: pleaseEnterServerHost: "Enter the server host" pleaseSelectUser: "Select user" serverHostPlaceholder: "Example: cherrypick.example.com" +_serverSetupWizard: + installCompleted: "CherryPick installation is now complete!" + firstCreateAccount: "To begin, create an administrator account." + accountCreated: "Administrator account has been created!" + serverSetting: "Server Settings" + youCanEasilyConfigureOptimalServerSettingsWithThisWizard: "This wizard makes it easier to configure the server settings." + settingsYouMakeHereCanBeChangedLater: "The settings that were changed via this wizard can be adjusted later." + howWillYouUseMisskey: "How will you use CherryPick?" + _use: + single: "Single User server" + single_description: "Use it alone as your own server." + single_youCanCreateMultipleAccounts: "Multiple accounts can be created as needed, even when operated as a single user server." + group: "Group server" + group_description: "Invite other trusted users to use it with more than one user." + open: "Public server" + open_description: "Allow anyone to register." + openServerAdvice: "Accepting a large number of unknown users involves risk. We recommend that you operate with a reliable moderation system to handle any problems." + openServerAntiSpamAdvice: "To prevent your server from becoming a stepping stone for spam, you should also pay close attention to security by enabling anti-bot functions such as reCAPTCHA." + howManyUsersDoYouExpect: "How many users do you expect?" + _scale: + small: "Less than 100 (small scale)" + medium: "More than 100 and less than 1000 users (medium size)" + large: "More than 1000 (Large scale)" + largeScaleServerAdvice: "Large servers may require advanced infrastructure knowledge, such as load balancing and database replication." + doYouConnectToFediverse: "Do you want to connect to the Fediverse?" + doYouConnectToFediverse_description1: "When connected to a network of distributed servers (Fediverse) content can be exchanged with other servers." + doYouConnectToFediverse_description2: "Connecting with the Fediverse is also called \"federation\"" + youCanConfigureMoreFederationSettingsLater: "Advanced settings such as specifying federated servers can be configured later." + remoteContentsCleaning: "Automatic cleanup of received contents" + remoteContentsCleaning_description: "Federation may result in a continuous inflow of content. Enabling automatic cleanup will remove outdated and unreferenced content from the server to save storage." + adminInfo: "Administrator information" + adminInfo_description: "Sets the administrator information used to receive inquiries." + adminInfo_mustBeFilled: "Must be entered if public server or federation is on." + followingSettingsAreRecommended: "The following settings are recommended" + applyTheseSettings: "Apply these settings" + skipSettings: "Skip settings" + settingsCompleted: "Setup is now complete!" + settingsCompleted_description: "Thank you for your time. Now that everything is ready, you can start using the server right away." + settingsCompleted_description2: "The server settings can be changed from the “Control Panel”" + donationRequest: "Donation Request" + _donationRequest: + text1: "CherryPick is a free software developed by volunteers." + text2: "We would appreciate your support so that we can continue to develop this software further into the future." + text3: "There are also special benefits for supporters!" +_uploader: + editImage: "Edit Image" + compressedToX: "Compressed to {x}" + savedXPercent: "Saving {x}%" + abortConfirm: "Some files have not been uploaded, do you want to abort?" + doneConfirm: "Some files have not been uploaded, do you want to continue anyway?" + maxFileSizeIsX: "The maximum file size that can be uploaded is {x}" + allowedTypes: "Uploadable file types" + tip: "The file has not yet been uploaded so this dialog allows you to confirm, rename, compress, and crop the file before uploading. When ready, you can start uploading by pressing the “Upload” button." +_clientPerformanceIssueTip: + title: "Performance tips" + makeSureDisabledAdBlocker: "Disable your adblocker" + makeSureDisabledAdBlocker_description: "Adblockers can affect performance, please make sure that adblockers are not enabled by your system or browser features/extensions." + makeSureDisabledCustomCss: "Disable custom CSS" + makeSureDisabledCustomCss_description: "Overriding styles can affect performance. Please make sure that custom CSS or extensions that override styles are not enabled." + makeSureDisabledAddons: "Disable extensions" + makeSureDisabledAddons_description: "Some extensions may interfere with client behavior and affect performance. Please disable your browser extensions and see if this improves the situation." +_clip: + tip: "Clip is a feature that allows you to organize your notes." +_userLists: + tip: "Lists can contain any user you specify when creating, the created list can then be displayed as a timeline showing only the specified users." +watermark: "Watermark" +defaultPreset: "Default Preset" +_watermarkEditor: + tip: "A watermark, such as credit information, can be added to the image." + quitWithoutSaveConfirm: "Discard unsaved changes?" + driveFileTypeWarn: "This file is not supported" + driveFileTypeWarnDescription: "Choose an image file" + title: "Edit Watermark" + cover: "Cover everything" + repeat: "spread all over" + preserveBoundingRect: "Adjust to prevent overflow when rotating" + opacity: "Opacity" + scale: "Size" + text: "Text" + qr: "QR Code" + position: "Position" + margin: "Margin" + type: "Type" + image: "Images" + advanced: "Advanced" + angle: "Angle" + stripe: "Stripes" + stripeWidth: "Line width" + stripeFrequency: "Lines count" + polkadot: "Polkadot" + checker: "Checker" + polkadotMainDotOpacity: "Opacity of the main dot" + polkadotMainDotRadius: "Size of the main dot" + polkadotSubDotOpacity: "Opacity of the secondary dot" + polkadotSubDotRadius: "Size of the secondary dot" + polkadotSubDotDivisions: "Number of sub-dots." + leaveBlankToAccountUrl: "Leave blank to use account URL" +_imageEffector: + title: "Effects" + addEffect: "Add Effects" + discardChangesConfirm: "Are you sure you want to leave? You have unsaved changes." + nothingToConfigure: "No configurable options available" + _fxs: + chromaticAberration: "Chromatic Aberration" + glitch: "Glitch" + mirror: "Mirror" + invert: "Invert Colors" + grayscale: "Grayscale" + blur: "Blur" + pixelate: "Pixelate" + colorAdjust: "Color Correction" + colorClamp: "Color Compression" + colorClampAdvanced: "Color Compression (Advanced)" + distort: "Distortion" + threshold: "Binarize" + zoomLines: "Saturated lines" + stripe: "Stripes" + polkadot: "Polkadot" + checker: "Checker" + blockNoise: "Block Noise" + tearing: "Tearing" + fill: "Fill" + _fxProps: + angle: "Angle" + scale: "Size" + size: "Size" + radius: "Radius" + samples: "Sample count" + offset: "Position" + color: "Color" + opacity: "Opacity" + normalize: "Normalize" + amount: "Amount" + lightness: "Lighten" + contrast: "Contrast" + hue: "Hue" + brightness: "Brightness" + saturation: "Saturation" + max: "Maximum" + min: "Minimum" + direction: "Direction" + phase: "Phase" + frequency: "Frequency" + strength: "Strength" + glitchChannelShift: "Channel shift" + seed: "Seed value" + redComponent: "Red component" + greenComponent: "Green component" + blueComponent: "Blue component" + threshold: "Threshold" + centerX: "Center X" + centerY: "Center Y" + zoomLinesSmoothing: "Smoothing" + zoomLinesSmoothingDescription: "Smoothing and zoom line width cannot be used together." + zoomLinesThreshold: "Zoom line width" + zoomLinesMaskSize: "Center diameter" + zoomLinesBlack: "Make black" + circle: "Circular" +drafts: "Drafts" _drafts: select: "Select Draft" + cannotCreateDraftAnymore: "The number of drafts that can be created has been exceeded." + cannotCreateDraft: "You cannot create a draft with this content." delete: "Delete Draft" - deleteAreYouSure: "Do you delete the draft?" - noDrafts: "There is no draft." + deleteAreYouSure: "Delete draft?" + noDrafts: "No drafts" replyTo: "Reply to {user}" - quoteOf: "Quote to {user}" - postTo: "Post to {channel}" + quoteOf: "Citation to {user}'s note" + postTo: "Posting to {channel}" + saveToDraft: "Save to Draft" + restoreFromDraft: "Restore from Draft" + restore: "Restore" + listDrafts: "List of Drafts" + schedule: "Schedule note" + listScheduledNotes: "Scheduled notes list" + cancelSchedule: "Cancel schedule" +qr: "QR Code" +_qr: + showTabTitle: "Display" + readTabTitle: "Scan" + shareTitle: "{name} {acct}" + shareText: "Follow me on the Fediverse!" + chooseCamera: "Choose camera" + cannotToggleFlash: "Unable to toggle flashlight" + turnOnFlash: "Turn on flashlight" + turnOffFlash: "Turn off flashlight" + startQr: "Resume QR code reader" + stopQr: "Stop QR code reader" + noQrCodeFound: "No QR code found" + scanFile: "Scan image from device" + raw: "Text" + mfm: "MFC" _abuse: _resolver: 1hour: "one hour" @@ -3462,13 +3762,6 @@ _abuse: reportContentPattern: "Patterns of Reported Contents" list: "List" resolver: "Resolver" -_imageCompressionMode: - title: "Image compression format" - description: "If you do not want to keep the original image, you can select the compression format of the image for web publishing. If the image is to be reduced in size, it will be reduced to be smaller than 2048x2048. If lossy compression is not specified, either lossy or lossy compression will be automatically selected depending on the original image." - resizeCompress: "Resize and compression" - noResizeCompress: "Compression without resize" - resizeCompressLossy: "Resize and lossy compression" - noResizeCompressLossy: "Lossy compression without resize" _externalNavigationWarning: title: "Navigate to an external site" description: "Leave {host} and go to an external site" @@ -3531,6 +3824,17 @@ _weather: humidity: "Humidity" pressure: "Pressure" precipitation: "Precipitation" +_deliveryTargetControl: + deliveryTargetControl: "Delivery Target Control" + deliveryTargetInclude: "Deliver only to selected servers" + deliveryTargetExclude: "Deliver excluding selected servers" + noFollowersFromRemoteServers: "No followers from remote servers" + loadError: "Failed to load server list" + followersCount: "{count} followers" + searchResults: "Found {count} results (out of {total})" + deliveryTargetsInclude: "Public only to some servers" + deliveryTargetsExclude: "Not public to some servers" + hasDeliveryTargets: "Delivery targets are selected" noSendActivity: "Don't send activity" diff --git a/locales/es-ES.yml b/locales/es-ES.yml index 91ccb40007..8c22d397ae 100644 --- a/locales/es-ES.yml +++ b/locales/es-ES.yml @@ -9,7 +9,7 @@ reset: "Reiniciar" notifications: "Notificaciones" username: "Nombre de usuario" password: "Contraseña" -initialPasswordForSetup: "Contraseña para iniciar la inicialización" +initialPasswordForSetup: "Contraseña de configuración inicial" initialPasswordIsIncorrect: "La contraseña para iniciar la configuración inicial es incorrecta." initialPasswordForSetupDescription: "Si ha instalado CherryPick usted mismo, utilice la contraseña introducida en el archivo de configuración.\nSi utiliza un servicio de alojamiento de CherryPick o similar, utilice la contraseña proporcionada.\nSi no ha establecido una contraseña, déjela en blanco para continuar." forgotPassword: "Olvidé mi contraseña" @@ -61,11 +61,11 @@ copyRSS: "Copiar RSS" copyUsername: "Copiar nombre de usuario" copyUserId: "Copiar ID del usuario" copyNoteId: "Copiar ID de la nota" -copyFileId: "Copiar ID del archivo" +copyFileId: "Copiar ID de archivo" copyFolderId: "Copiar ID de carpeta" copyProfileUrl: "Copiar la URL del perfil" searchUser: "Buscar un usuario" -searchThisUsersNotes: "" +searchThisUsersNotes: "Buscar en las notas de este usuario" reply: "Responder" loadMore: "Ver más" showMore: "Ver más" @@ -83,10 +83,10 @@ files: "Archivos" download: "Descargar" driveFileDeleteConfirm: "¿Desea borrar el archivo \"{name}\"? Las notas que tengan este archivo como adjunto serán eliminadas" unfollowConfirm: "¿Desea dejar de seguir a {name}?" -exportRequested: "Se ha solicitado la exportación. Puede tomar un tiempo. Cuando termine la exportación, se añadirá en el drive" -importRequested: "Se ha solicitado la importación. Puede tomar un tiempo." +exportRequested: "Has solicitado la exportación. Puede llevar un tiempo. Cuando termine la exportación, se añadirá al drive" +importRequested: "Has solicitado la importación. Puede llevar un tiempo." lists: "Listas" -noLists: "No tiene listas" +noLists: "No tienes ninguna lista" note: "Notas" notes: "Notas" following: "Siguiendo" @@ -99,9 +99,9 @@ somethingHappened: "Ocurrió un error" retry: "Reintentar" pageLoadError: "Error al leer la página" pageLoadErrorDescription: "Normalmente es debido a la red o al caché del navegador. Por favor limpie el caché o intente más tarde." -serverIsDead: "No hay respuesta del servidor. Espere un momento y vuelva a intentarlo." -youShouldUpgradeClient: "Para ver esta página, por favor refrezca el navegador y utiliza una versión más reciente del cliente." -enterListName: "Ingrese nombre de lista" +serverIsDead: "No hay respuesta del servidor. Espera un momento y vuelve a intentarlo." +youShouldUpgradeClient: "Para ver esta página, recarga el navegador para actualizar el cliente." +enterListName: "Introduce un nombre para la lista" privacy: "Privacidad" makeFollowManuallyApprove: "Aprobar manualmente las solicitudes de seguimiento" defaultNoteVisibility: "Visibilidad por defecto" @@ -125,7 +125,7 @@ renoteToOtherChannel: "Renotar a otro canal" pinnedNote: "Nota fijada" pinned: "Fijar al perfil" you: "Tú" -clickToShow: "Click para ver" +clickToShow: "Haz clic para verlo" sensitive: "Marcado como sensible" add: "Agregar" reaction: "Reacción" @@ -134,28 +134,28 @@ emojiPicker: "Selector de emojis" pinnedEmojisForReactionSettingDescription: "Puedes seleccionar reacciones para fijarlos en el selector" pinnedEmojisSettingDescription: "Puedes seleccionar emojis para fijarlos en el selector" emojiPickerDisplay: "Mostrar el selector de emojis" -overwriteFromPinnedEmojisForReaction: "Sobreescribir las reacciones fijadas" -overwriteFromPinnedEmojis: "Sobreescribir los emojis fijados" -reactionSettingDescription2: "Arrastre para reordenar, click para borrar, apriete la tecla + para añadir." +overwriteFromPinnedEmojisForReaction: "Sobreescribir los ajustes de reacciones" +overwriteFromPinnedEmojis: "Sobreescribir los ajustes generales" +reactionSettingDescription2: "Arrastra para reordenar, click para borrar, pulsa \"+\" para añadir." rememberNoteVisibility: "Recordar visibilidad" attachCancel: "Quitar adjunto" -deleteFile: "Archivo eliminado" +deleteFile: "Eliminar archivo" markAsSensitive: "Marcar como sensible" unmarkAsSensitive: "Desmarcar como sensible" -enterFileName: "Ingrese el nombre del archivo" +enterFileName: "Introduce el nombre del archivo" mute: "Silenciar" unmute: "Dejar de silenciar" renoteMute: "Silenciar renota" renoteUnmute: "Desilenciar renota" block: "Bloquear" -unblock: "Dejar de bloquear" +unblock: "Desbloquear" suspend: "Suspender" unsuspend: "Dejar de suspender" -blockConfirm: "¿Quiere bloquear esta cuenta?" -unblockConfirm: "¿Quiere dejar de bloquear esta cuenta?" -suspendConfirm: "¿Quiere suspender esta cuenta?" -unsuspendConfirm: "¿Quiere dejar de suspender esta cuenta?" -selectList: "Seleccione una lista" +blockConfirm: "¿Quieres bloquear esta cuenta?" +unblockConfirm: "¿Quieres desbloquear esta cuenta?" +suspendConfirm: "¿Quieres suspender esta cuenta?" +unsuspendConfirm: "¿Quieres dejar de suspender esta cuenta?" +selectList: "Selecciona una lista" editList: "Editar lista" selectChannel: "Seleccionar canal" selectAntenna: "Seleccionar antena" @@ -163,55 +163,55 @@ editAntenna: "Editar antena" createAntenna: "Crear una antena" selectWidget: "Seleccionar widget" editWidgets: "Editar widgets" -editWidgetsExit: "Terminar edición" +editWidgetsExit: "Hecho" customEmojis: "Emojis personalizados" emoji: "Emoji" -emojis: "Emoji" +emojis: "Emojis" emojiName: "Nombre del emoji" -emojiUrl: "URL de la imágen del emoji" -addEmoji: "Agregar emoji" -settingGuide: "Configuración sugerida" -cacheRemoteFiles: "Mantener en cache los archivos remotos" -cacheRemoteFilesDescription: "Si desactiva esta configuración, Los archivos remotos se cargarán desde el link directo sin usar la caché. Con eso se puede ahorrar almacenamiento del servidor, pero eso aumentará el tráfico al no crear miniaturas." +emojiUrl: "URL del emoji" +addEmoji: "Añadir emoji" +settingGuide: "Configuración recomendada" +cacheRemoteFiles: "Mantener los archivos remotos en caché" +cacheRemoteFilesDescription: "Si desactivas esta configuración, los archivos remotos se cargarán directamente de los servidores remotos. Desactivar esto reducirá el uso de almacenamiento, pero incrementará el uso de tráfico, ya que no se generarán miniaturas." youCanCleanRemoteFilesCache: "Puedes vaciar la caché pulsando en el botón 🗑️ en el administrador de archivos." -cacheRemoteSensitiveFiles: "Cachear archivos remotos sensibles" -cacheRemoteSensitiveFilesDescription: "Cuando esta opción está desactivada, los archivos remotos sensibles son cargador directamente de la instancia origen sin ser cacheados." +cacheRemoteSensitiveFiles: "Mantener los archivos remotos sensibles en caché" +cacheRemoteSensitiveFilesDescription: "Cuando esta opción está desactivada, los archivos remotos sensibles se cargarán directamente desde los servidores remotos." flagAsBot: "Esta cuenta es un bot" -flagAsBotDescription: "En caso de que esta cuenta fuera usada por un programa, active esta opción. Al hacerlo, esta opción servirá para otros desarrolladores para evitar cadenas infinitas de reacciones, y ajustará los sistemas internos de CherryPick para que trate a esta cuenta como un bot." -flagAsCat: "Esta cuenta es un gato" -flagAsCatDescription: "En caso de que declare que esta cuenta es de un gato, active esta opción." -flagShowTimelineReplies: "Mostrar respuestas a las notas en la biografía" -flagShowTimelineRepliesDescription: "Cuando se marca, la línea de tiempo muestra respuestas a otras notas además de las notas del usuario" +flagAsBotDescription: "Activa esta opción si la cuenta es utilizada por un programa. Si se activa, actuará como una etiqueta para otros desarrolladores para prevenir cadenas eternas de interacción con otros bots, y ajustará los sistemas internos de CherryPick para tratar esta cuenta de manera acorde." +flagAsCat: "Marcar esta cuenta como gato" +flagAsCatDescription: "Activa esta opción para marcar esta cuenta como un gato." +flagShowTimelineReplies: "Mostrar respuestas en la línea de tiempo" +flagShowTimelineRepliesDescription: "Muestra respuestas de los usuarios a las notas de otros usuarios en la línea de tiempo al activar esta opción." autoAcceptFollowed: "Aceptar automáticamente las solicitudes de seguimiento de los usuarios que sigues" -addAccount: "Agregar Cuenta" +addAccount: "Agregar cuenta" reloadAccountsList: "Recargar lista de cuentas" loginFailed: "Error al iniciar sesión." -showOnRemote: "Ver en una instancia remota" -continueOnRemote: "Ver en una instancia remota" +showOnRemote: "Ver en instancia remota" +continueOnRemote: "Continuar en una instancia remota" chooseServerOnMisskeyHub: "Elegir un servidor en Misskey Hub" specifyServerHost: "Especifica una instancia directamente" -inputHostName: "Introduzca el dominio" +inputHostName: "Introduce el dominio" general: "General" wallpaper: "Fondo de pantalla" setWallpaper: "Establecer fondo de pantalla" removeWallpaper: "Quitar fondo de pantalla" searchWith: "Buscar: {q}" -youHaveNoLists: "No tienes listas" -followConfirm: "¿Desea seguir a {name}?" +youHaveNoLists: "No tienes ninguna lista" +followConfirm: "¿Quieres seguir a {name}?" proxyAccount: "Cuenta proxy" -proxyAccountDescription: "Una cuenta proxy es una cuenta que actúa como un seguidor remoto de un usuario bajo ciertas condiciones. Por ejemplo, cuando un usuario añade un usuario remoto a una lista, si ningún usuario local sigue al usuario agregado a la lista, la instancia no puede obtener su actividad. Así que la cuenta proxy sigue al usuario añadido a la lista" -host: "Host" +proxyAccountDescription: "Una cuenta proxy es una cuenta que actúa como un seguidor remoto de un usuario bajo ciertas condiciones. Por ejemplo, cuando un usuario añade un usuario remoto a una lista, si ningún usuario local sigue al usuario agregado a la lista, la instancia no puede obtener su actividad, así que la cuenta proxy sigue al usuario añadido a la lista" +host: "Instancia" selectSelf: "Elígete a ti mismo" selectUser: "Elegir usuario" -recipient: "Recipiente" +recipient: "Receptor" annotation: "Anotación" federation: "Federación" -instances: "Instancia" +instances: "Instancias" registeredAt: "Registrado en" -latestRequestReceivedAt: "Ultimo pedido recibido" -latestStatus: "Último status" +latestRequestReceivedAt: "Última petición recibida" +latestStatus: "Último estado" storageUsage: "Almacenamiento usado" -charts: "Chat" +charts: "Métricas" perHour: "por hora" perDay: "por día" stopActivityDelivery: "Dejar de enviar actividades" @@ -220,46 +220,47 @@ silenceThisInstance: "Silenciar esta instancia" mediaSilenceThisInstance: "Silencia la Multimedia(Imágenes,videos...) para este servidor" operations: "Operaciones" software: "Software" +softwareName: "Nombre del software" version: "Versión" metadata: "Metadatos" withNFiles: "{n} archivos" monitor: "Monitor" jobQueue: "Cola de trabajos" -cpuAndMemory: "CPU y Memoria" +cpuAndMemory: "CPU y memoria" network: "Red" disk: "Disco" -instanceInfo: "información de la instancia" +instanceInfo: "Información de la instancia" statistics: "Estadísticas" clearQueue: "Limpiar cola" -clearQueueConfirmTitle: "¿Desea limpiar la cola?" +clearQueueConfirmTitle: "¿Quieres limpiar la cola?" clearQueueConfirmText: "Las notas aún no entregadas no se federarán. Normalmente no se necesita ejecutar esta operación" clearCachedFiles: "Limpiar caché" -clearCachedFilesConfirm: "¿Desea borrar todos los archivos remotos cacheados?" +clearCachedFilesConfirm: "¿Quieres borrar todos los archivos remotos en caché?" blockedInstances: "Instancias bloqueadas" -blockedInstancesDescription: "Seleccione los hosts de las instancias que desea bloquear, separadas por una linea nueva. Las instancias bloqueadas no podrán comunicarse con esta instancia." +blockedInstancesDescription: "La lista de los dominios de las instancias que quieres bloquear, separadas por una linea nueva. Las instancias bloqueadas no podrán comunicarse con esta instancia." silencedInstances: "Instancias silenciadas" -silencedInstancesDescription: "Listar los hostname de las instancias que quieres silenciar. Todas las cuentas de las instancias listadas serán tratadas como silenciadas, solo podrán hacer peticiones de seguimiento, y no podrán mencionar cuentas locales si no las siguen. Esto no afecta a las instancias bloqueadas." -mediaSilencedInstances: "Servidores silenciados (Multimedia)" -mediaSilencedInstancesDescription: "Listar las instancias que quieres silenciar. Todas las cuentas de las instancias listadas serán tratadas como silenciadas, solo podrán hacer peticiones de seguimiento, y no podrán mencionar cuentas locales si no las siguen. Esto no afecta a las instancias bloqueadas." +silencedInstancesDescription: "La lista de los dominios de las instancias que quieres silenciar. Todas las cuentas de las instancias listadas serán tratadas como silenciadas, solo podrán hacer peticiones de seguimiento, y no podrán mencionar cuentas locales si no las siguen. Esto no afecta a las instancias bloqueadas." +mediaSilencedInstances: "Servidores con multimedia silenciada" +mediaSilencedInstancesDescription: "La lista de los dominios de las instancias cuya multimedia quieres silenciar. Todas las cuentas que pertenezcan a estas instancias serán marcadas como sensibles, y no podrán usar sus emojis personalizados. Esto no afectará a las instancias bloqueadas" federationAllowedHosts: "Servidores federados" -federationAllowedHostsDescription: "Establezca los nombres de los servidores que pueden federarse, separados por una nueva línea." +federationAllowedHostsDescription: "La lista de los dominios de las instancias cuya federación está permitida, separadas por saltos de línea." muteAndBlock: "Silenciar y bloquear" mutedUsers: "Usuarios silenciados" blockedUsers: "Usuarios bloqueados" noUsers: "No hay usuarios" editProfile: "Editar perfil" -noteDeleteConfirm: "¿Desea borrar esta nota?" -pinLimitExceeded: "Ya no se pueden fijar más posts" -intro: "¡La instalación de CherryPick ha terminado! Crea el usuario administrador." +noteDeleteConfirm: "¿Quieres borrar esta nota?" +pinLimitExceeded: "Ya no se pueden fijar más notas" done: "Terminado" -processing: "Procesando" +processing: "Procesando..." +preprocessing: "Preparando" preview: "Vista previa" default: "Predeterminado" defaultValueIs: "Por defecto: {value}" noCustomEmojis: "No hay emojis personalizados" noJobs: "No hay trabajos" federating: "Federando" -blocked: "Bloqueando" +blocked: "Bloqueado" suspended: "Suspendido" all: "Todo" subscribing: "Suscribiendo" @@ -280,8 +281,8 @@ featured: "Destacados" usernameOrUserId: "Nombre o ID del usuario" noSuchUser: "No se encuentra el usuario" lookup: "Búsqueda" -announcements: "Anuncios" -imageUrl: "URL de la imágen" +announcements: "Avisos" +imageUrl: "URL de la imagen." remove: "Borrar" removed: "Borrado" removeAreYouSure: "¿Desea borrar \"{x}\"?" @@ -298,6 +299,7 @@ uploadFromUrl: "Subir desde una URL" uploadFromUrlDescription: "URL del fichero que quieres subir" uploadFromUrlRequested: "Subida solicitada" uploadFromUrlMayTakeTime: "Subir el fichero puede tardar un tiempo." +uploadNFiles: "Subir {n} archivos" explore: "Explorar" messageRead: "Ya leído" noMoreHistory: "El historial se ha acabado" @@ -326,11 +328,13 @@ dark: "Oscuro" lightThemes: "Tema claro" darkThemes: "Tema oscuro" syncDeviceDarkMode: "Sincronice el Modo Oscuro con la configuración de su dispositivo" +switchDarkModeManuallyWhenSyncEnabledConfirm: "{x} está activado ¿Te gustaría desactivar la sincronización y cambiar al modo manual?" drive: "Drive" fileName: "Nombre de archivo" selectFile: "Elegir archivo" selectFiles: "Elegir archivos" selectFolder: "Seleccione una carpeta" +unselectFolder: "Deseleccionar carpeta" selectFolders: "Seleccione carpetas" fileNotSelected: "Archivo no seleccionado." renameFile: "Renombrar archivo" @@ -343,6 +347,7 @@ addFile: "Agregar archivo" showFile: "Examinar archivos" emptyDrive: "El drive está vacío" emptyFolder: "La carpeta está vacía" +dropHereToUpload: "Arrastra los archivos aquí para subirlos." unableToDelete: "No se puede borrar" inputNewFileName: "Ingrese un nuevo nombre de archivo" inputNewDescription: "Ingrese nueva descripción" @@ -585,8 +590,10 @@ showFixedPostForm: "Mostrar el formulario de las entradas encima de la línea de showFixedPostFormInChannel: "Mostrar el formulario de publicación por encima de la cronología (Canales)" withRepliesByDefaultForNewlyFollowed: "Incluir por defecto respuestas de usuarios recién seguidos en la línea de tiempo" newNoteRecived: "Tienes una nota nueva" +newNote: "Nueva nota" sounds: "Sonidos" sound: "Sonidos" +notificationSoundSettings: "Configuración del sonido de las notificaciones" listen: "Escuchar" none: "Ninguna" showInPage: "Mostrar en la página" @@ -654,7 +661,7 @@ disablePlayer: "Cerrar reproductor" expandPost: "Expandir tweet" themeEditor: "Editor de temas" description: "Descripción" -describeFile: "Añade una descripción" +describeFile: "Añadir texto alternativo" enterFileDescription: "Introducir un título" author: "Autor" leaveConfirm: "Hay modificaciones sin guardar. ¿Desea descartarlas?" @@ -778,6 +785,7 @@ lockedAccountInfo: "A menos que configures la visibilidad de tus notas como \"S alwaysMarkSensitive: "Marcar los medios de comunicación como contenido sensible por defecto" loadRawImages: "Cargar las imágenes originales en lugar de mostrar las miniaturas" disableShowingAnimatedImages: "No reproducir imágenes animadas" +disableShowingAnimatedImages_caption: "Si las imágenes animadas no se reproducen independientemente de esta configuración, es posible que la configuración de accesibilidad del navegador o del sistema operativo, los modos de ahorro de energía o funciones similares estén interfiriendo." highlightSensitiveMedia: "Resaltar medios marcados como sensibles" verificationEmailSent: "Se le ha enviado un correo electrónico de confirmación. Por favor, acceda al enlace proporcionado en el correo electrónico para completar la configuración." notSet: "Sin especificar" @@ -802,6 +810,7 @@ wide: "Ancho" narrow: "Estrecho" reloadToApplySetting: "Esta configuración sólo se aplicará después de recargar la página. ¿Recargar ahora?" needReloadToApply: "Se requiere un reinicio para la aplicar los cambios" +needToRestartServerToApply: "Se requiere un reinicio para la aplicar los cambios" showTitlebar: "Mostrar la barra de título" clearCache: "Limpiar caché" onlineUsersCount: "{n} usuarios en línea" @@ -848,13 +857,13 @@ unlikeConfirm: "¿Quitar como favorito?" fullView: "Vista completa" quitFullView: "quitar vista completa" addDescription: "Agregar descripción" -userPagePinTip: "Puede mantener sus notas visibles aquí seleccionando Pin en el menú de notas individuales" +userPagePinTip: "Puede mantener sus notas visibles aquí seleccionando 'Fijar al perfil' en el menú de notas individuales" notSpecifiedMentionWarning: "Algunas menciones no están incluidas en el destino" info: "Información" userInfo: "Información del usuario" unknown: "Desconocido" onlineStatus: "En línea" -hideOnlineStatus: "mostrarse como desconectado" +hideOnlineStatus: "Mostrarse como desconectado" hideOnlineStatusDescription: "Ocultar su estado en línea puede reducir la eficacia de algunas funciones, como la búsqueda" online: "En línea" active: "Activo" @@ -883,7 +892,7 @@ popularPosts: "Más vistos" shareWithNote: "Compartir con una nota" ads: "Anuncios" expiration: "Termina el" -startingperiod: "periodo de inicio" +startingperiod: "Comienzo" memo: "Notas" priority: "Prioridad" high: "Alta" @@ -916,7 +925,7 @@ pubSub: "Cuentas Pub/Sub" lastCommunication: "Última comunicación" resolved: "Resuelto" unresolved: "Sin resolver" -breakFollow: "Dejar de seguir" +breakFollow: "Eliminar seguidor" breakFollowConfirm: "¿Quieres dejar de seguir?" itsOn: "¡Está encendido!" itsOff: "¡Está apagado!" @@ -970,7 +979,7 @@ threeDays: "Tres días" reflectMayTakeTime: "Puede pasar un tiempo hasta que se reflejen los cambios" failedToFetchAccountInformation: "No se pudo obtener información de la cuenta" rateLimitExceeded: "Se excedió el límite de peticiones" -cropImage: "Recortar imágen" +cropImage: "Recortar Imagen" cropImageAsk: "¿Desea recortar la imagen?" cropYes: "Recortar" cropNo: "Usar como está" @@ -1010,6 +1019,7 @@ failedToUpload: "La subida falló" cannotUploadBecauseInappropriate: "Este archivo no se puede subir debido a que algunas partes han sido detectadas comoNSFW." cannotUploadBecauseNoFreeSpace: "La subida falló debido a falta de espacio libre en la unidad del usuario." cannotUploadBecauseExceedsFileSizeLimit: "Este archivo supera el peso máximo y no puede ser subido." +cannotUploadBecauseUnallowedFileType: "Incapaz de subir el archivo debido a que es un tipo de archivo no autorizado." beta: "Beta" enableAutoSensitive: "Marcar automáticamente contenido NSFW" enableAutoSensitiveDescription: "Permite la detección y marcado automático de contenido NSFW usando 'Machine Learning' cuando sea posible. Incluso si esta opción está desactivada, puede ser activado para toda la instancia." @@ -1028,7 +1038,7 @@ sendPushNotificationReadMessageCaption: "La notificación \"{emptyPushNotificati windowMaximize: "Maximizar" windowMinimize: "Minimizar" windowRestore: "Regresar" -caption: "Pie de foto" +caption: "Texto alternativo" loggedInAsBot: "Inicio sesión como cuenta bot." tools: "Utilidades" cannotLoad: "No se puede cargar." @@ -1061,6 +1071,7 @@ permissionDeniedError: "Operación denegada" permissionDeniedErrorDescription: "Esta cuenta no tiene permisos para hacer esa acción." preset: "Predefinido" selectFromPresets: "Escoger desde predefinidos" +custom: "Personalizado" achievements: "Logros" gotInvalidResponseError: "Respuesta del servidor inválida" gotInvalidResponseErrorDescription: "Puede que el servidor esté caído o en mantenimiento. Favor de intentar más tarde" @@ -1099,6 +1110,7 @@ prohibitedWordsDescription2: "Si se usan espacios se crearán expresiones AND y hiddenTags: "Hashtags ocultos" hiddenTagsDescription: "Selecciona las etiquetas que no se mostrarán en tendencias. Una etiqueta por línea." notesSearchNotAvailable: "No se puede buscar una nota" +usersSearchNotAvailable: "La búsqueda de usuarios no está disponible." license: "Licencia" unfavoriteConfirm: "¿Desea quitar de favoritos?" myClips: "Mis clips" @@ -1150,7 +1162,7 @@ channelArchiveConfirmTitle: "¿Seguro de archivar {name}?" channelArchiveConfirmDescription: "Un canal archivado no aparecerá en la lista de canales ni en los resultados. Las nuevas publicaciones tampoco serán añadidas." thisChannelArchived: "El canal ha sido archivado." displayOfNote: "Mostrar notas" -initialAccountSetting: "Configración inicial de su cuenta\nか\nConfigración de inicio" +initialAccountSetting: "Configración inicial de su cuenta" youFollowing: "Siguiendo" preventAiLearning: "Rechazar el uso en el Aprendizaje de Máquinas. (IA Generativa)" preventAiLearningDescription: "Pedirle a las arañas (crawlers) no usar los textos publicados o imágenes en el aprendizaje automático (IA Predictiva / Generativa). Ésto se logra añadiendo una marca respuesta HTML con la cadena \"noai\" al cantenido. Una prevención total no podría lograrse sólo usando ésta marca, ya que puede ser simplemente ignorada." @@ -1173,6 +1185,7 @@ installed: "Instalado" branding: "Marca" enableServerMachineStats: "Publicar estadísticas de hardware del servidor" enableIdenticonGeneration: "Activar generación de identicon por usuario" +showRoleBadgesOfRemoteUsers: "Mostrar la insignia de rol asignada a los usuarios remotos." turnOffToImprovePerformance: "Desactivar esto puede aumentar el rendimiento." createInviteCode: "Generar invitación" createWithOptions: "Generar con opciones" @@ -1249,9 +1262,8 @@ showAvatarDecorations: "Mostrar decoraciones de avatar" releaseToRefresh: "Soltar para recargar" refreshing: "Recargando..." pullDownToRefresh: "Tira hacia abajo para recargar" -disableStreamingTimeline: "Desactivar actualizaciones en tiempo real de la línea de tiempo" useGroupedNotifications: "Mostrar notificaciones agrupadas" -signupPendingError: "Ha habido un problema al verificar tu dirección de correo electrónico. Es posible que el enlace haya caducado." +emailVerificationFailedError: "Se ha producido un error al confirmar tu dirección de correo electrónico. Es posible que el enlace haya caducado." cwNotationRequired: "Si se ha activado \"ocultar contenido\", es necesario proporcionar una descripción." doReaction: "Añadir reacción" code: "Código" @@ -1321,6 +1333,8 @@ availableRoles: "Roles disponibles " acknowledgeNotesAndEnable: "Activar después de comprender las precauciones" federationSpecified: "Este servidor opera en una federación de listas blancas. No puede interactuar con otros servidores que no sean los especificados por el administrador." federationDisabled: "La federación está desactivada en este servidor. No puede interactuar con usuarios de otros servidores" +draft: "Borrador" +draftsAndScheduledNotes: "Borradores y notas programadas" confirmOnReact: "Confirmar la reacción" reactAreYouSure: "¿Quieres añadir una reacción «{emoji}»?" markAsSensitiveConfirm: "¿Desea establecer este medio multimedia(Imagen,vídeo...) como sensible?" @@ -1338,14 +1352,21 @@ restore: "Restaurar" syncBetweenDevices: "Sincronizar entre dispositivos" preferenceSyncConflictTitle: "Los valores configurados existen en el servidor." preferenceSyncConflictText: "Los ajustes de sincronización activados guardarán sus valores en el servidor. Sin embargo, hay valores existentes en el servidor. ¿Qué conjunto de valores desea sobrescribir?" +preferenceSyncConflictChoiceMerge: "Fusionar" preferenceSyncConflictChoiceServer: "Valores de configuración del servidor" preferenceSyncConflictChoiceDevice: "Valor configurado en el dispositivo" +preferenceSyncConflictChoiceCancel: "Cancelar la activación de la sincronización" paste: "Pegar" emojiPalette: "Paleta emoji" postForm: "Formulario" +textCount: "caracteres" information: "Información" chat: "Chat" +directMessage: "Chatear" +directMessage_short: "Mensaje" migrateOldSettings: "Migrar la configuración anterior" +migrateOldSettings_description: "Esto debería hacerse automáticamente, pero si por alguna razón la migración no ha tenido éxito, puede activar usted mismo el proceso de migración manualmente. Se sobrescribirá la información de configuración actual." +compress: "Compresión de la imagen" right: "Derecha" bottom: "Abajo" top: "Arriba" @@ -1354,7 +1375,54 @@ settingsMigrating: "La configuración está siendo migrada, por favor espera un readonly: "Solo Lectura" goToDeck: "Volver al Deck" federationJobs: "Trabajos de Federación" +driveAboutTip: "En Drive, aparecerá una lista de los archivos que has subido en el pasado.
\nPuedes reutilizar estos archivos al adjuntarlos a notas, o puedes subir archivos por adelantado para publicarlos más tarde.
\nTen cuidado al eliminar un archivo, ya que no estará disponible en todos los lugares donde se utilizó (como notas, páginas, avatares, banners, etc.).
\nTambién puedes crear carpetas para organizar tus archivos." +scrollToClose: "Desliza para cerrar" +advice: "Consejos" +realtimeMode: "Modo en tiempo real" +turnItOn: "Activar" +turnItOff: "Desactivar" +emojiMute: "Silenciar emoji" +emojiUnmute: "No silenciar emoji" +muteX: "Silenciar {x}" +unmuteX: "Dejar de silenciar {x}" +abort: "Abortar" +tip: "Consejos y trucos" +redisplayAllTips: "Volver a mostrar todos \"Trucos y consejos\"" +hideAllTips: "Ocultar todos los \"Trucos y consejos\"" +defaultImageCompressionLevel: "Nivel de compresión de la imagen por defecto" +defaultImageCompressionLevel_description: "Baja, conserva la calidad de la imagen pero la medida del archivo es más grande.
Alta, reduce la medida del archivo pero también la calidad de la imagen." +defaultCompressionLevel: "Nivel de compresión predeterminado" +defaultCompressionLevel_description: "Al reducir el ajuste se conserva la calidad, pero aumenta el tamaño del archivo.
Al aumentar el ajuste se reduce el tamaño del archivo, pero disminuye la calidad." +inMinutes: "Minutos" +inDays: "Días" +safeModeEnabled: "El modo seguro está activado" +pluginsAreDisabledBecauseSafeMode: "El modo seguro está activado, por lo que todos los plugins están desactivados." +customCssIsDisabledBecauseSafeMode: "El modo seguro está activado, por lo que no se aplica el CSS personalizado." +themeIsDefaultBecauseSafeMode: "Mientras el modo seguro esté activado, se utilizará el tema predeterminado. Cuando se desactive el modo seguro, se volverá al tema original." +thankYouForTestingBeta: "¡Gracias por tu colaboración en la prueba de la versión beta!" +createUserSpecifiedNote: "Mencionar al usuario (Nota Directa)" +schedulePost: "Programar una nota" +scheduleToPostOnX: "Programar una nota para {x}" +scheduledToPostOnX: "La nota está programada para {x}." +schedule: "Programado" +scheduled: "Programado" +widgets: "Widgets" +deviceInfo: "Información del dispositivo" +deviceInfoDescription: "Al realizar consultas técnicas, incluir la siguiente información puede ayudar a resolver el problema." +_compression: + _quality: + high: "Calidad alta" + medium: "Calidad media" + low: "Calidad baja" + _size: + large: "Tamaño grande" + medium: "Tamaño mediano" + small: "Tamaño pequeño" +_order: + newest: "Los más recientes primero" + oldest: "Los más antiguos primero" _chat: + messages: "Mensaje" noMessagesYet: "Aún no hay mensajes" newMessage: "Mensajes nuevos" individualChat: "Chat individual" @@ -1369,7 +1437,7 @@ _chat: noInvitations: "No hay invitación." history: "Historial" noHistory: "No hay datos en el historial" - noRooms: "Sala no encontrada" + noRooms: "No te has unido a ninguna sala " inviteUser: "Invitar usuarios" sentInvitations: "Invitaciones enviadas" join: "Unirse" @@ -1387,6 +1455,8 @@ _chat: chatNotAvailableInOtherAccount: "La función de chat está desactivada para el otro usuario." cannotChatWithTheUser: "No se puede iniciar un chat con este usuario" cannotChatWithTheUser_description: "El chat no está disponible o la otra parte no ha habilitado el chat." + youAreNotAMemberOfThisRoomButInvited: "No eres participante en esta sala, pero has recibido una invitación. Por favor, acepta la invitación para unirte." + doYouAcceptInvitation: "¿Aceptas la invitación?" chatWithThisUser: "Chatear" thisUserAllowsChatOnlyFromFollowers: "Este usuario sólo acepta chats de seguidores." thisUserAllowsChatOnlyFromFollowing: "Este usuario sólo acepta chats de los usuarios a los que sigue." @@ -1403,15 +1473,44 @@ _chat: _emojiPalette: palettes: "Paleta\n" enableSyncBetweenDevicesForPalettes: "Activar la sincronización de paletas entre dispositivos" + paletteForMain: "Paleta principal" + paletteForReaction: "Paleta de reacción" _settings: + driveBanner: "Puedes gestionar y configurar la unidad, comprobar su uso y configurar los ajustes de carga de archivos." + pluginBanner: "Puedes ampliar las funciones del cliente con plugins. Puedes instalar plugins, configurarlos y gestionarlos individualmente." + notificationsBanner: "Puede configurar los tipos y el alcance de las notificaciones del servidor y las notificaciones push." api: "API" webhook: "Webhook" + serviceConnection: "Integraciones" + serviceConnectionBanner: "Gestione y configure tokens de acceso y Webhooks para integrarse con aplicaciones o servicios externos." + accountData: "Datos de la cuenta" + accountDataBanner: "Exportación e importación para gestionar los datos de la cuenta." + muteAndBlockBanner: "Puedes configurar y gestionar ajustes para ocultar contenidos y restringir acciones a usuarios específicos." + accessibilityBanner: "Puedes personalizar los visuales y el comportamiento del cliente, y configurar los ajustes para optimizar el uso." + privacyBanner: "Puedes configurar opciones relacionadas con la privacidad de la cuenta, como la visibilidad del contenido, la posibilidad de descubrir la cuenta y la aprobación de seguimiento." + securityBanner: "Puedes configurar opciones relacionadas con la seguridad de la cuenta, como la contraseña, los métodos de inicio de sesión, las aplicaciones de autenticación y Passkeys." + preferencesBanner: "Puedes configurar el comportamiento general del cliente según tus preferencias." + appearanceBanner: "Puedes configurar el aspecto y la visualización del cliente según tus preferencias." + soundsBanner: "Puedes configurar los ajustes de sonido para la reproducción en el cliente." timelineAndNote: "Líneas del tiempo y notas" + makeEveryTextElementsSelectable: "Hacer que todos los elementos de texto sean seleccionables" makeEveryTextElementsSelectable_description: "Activar esta opción puede reducir la usabilidad en algunas situaciones." useStickyIcons: "Hacer que los iconos te sigan cuando desplaces" + enableHighQualityImagePlaceholders: "Mostrar marcadores de posición para imágenes de alta calidad" + uiAnimations: "Animaciones de la interfaz de usuario" showNavbarSubButtons: "Mostrar los sub-botones en la barra de navegación." ifOn: "Si está activado" + ifOff: "Si está desactivado" enableSyncThemesBetweenDevices: "Sincronizar los temas instalados entre dispositivos." + enablePullToRefresh: "Tirar para actualizar" + enablePullToRefresh_description: "Si utiliza un ratón, arrastre mientras pulsa la rueda de desplazamiento." + realtimeMode_description: "Establece una conexión con el servidor y actualiza el contenido en tiempo real. Esto puede aumentar el tráfico y el consumo de memoria." + contentsUpdateFrequency: "Frecuencia de adquisición del contenido." + contentsUpdateFrequency_description: "Cuanto mayor sea el valor, más se actualiza el contenido, pero disminuye el rendimiento y aumenta el tráfico y el consumo de memoria." + contentsUpdateFrequency_description2: "Cuando el modo en tiempo real está activado, el contenido se actualiza en tiempo real independientemente de esta configuración." + showUrlPreview: "Mostrar la vista previa de la URL" + showAvailableReactionsFirstInNote: "Mostrar las reacciones disponibles en la parte superior." + showPageTabBarBottom: "Mostrar la barra de pestañas de la página en la parte inferior." _chat: showSenderName: "Mostrar el nombre del remitente" sendOnEnter: "Intro para enviar" @@ -1419,20 +1518,46 @@ _preferencesProfile: profileName: "Nombre de perfil" profileNameDescription: "Establece un nombre que identifique al dispositivo" profileNameDescription2: "Por ejemplo: \"PC Principal\",\"Teléfono\"" + manageProfiles: "Administrar perfiles" _preferencesBackup: autoBackup: "Respaldo automático" restoreFromBackup: "Restaurar desde copia de seguridad" noBackupsFoundTitle: "No se encontró una copia de seguridad" + noBackupsFoundDescription: "No se han encontrado copias de seguridad creadas automáticamente, pero si has guardado manualmente un archivo de copia de seguridad, puedes importarlo y restaurarlo." + selectBackupToRestore: "Selecciona una copia de seguridad para restaurar" + youNeedToNameYourProfileToEnableAutoBackup: "Se debe establecer un nombre de perfil para activar la copia de seguridad automática." + autoPreferencesBackupIsNotEnabledForThisDevice: "La copia de seguridad automática de los ajustes no está activada en este dispositivo." + backupFound: "Copia de seguridad de los ajustes encontrada " _accountSettings: requireSigninToViewContents: "Se requiere iniciar sesión para ver el contenido" requireSigninToViewContentsDescription1: "Requiere iniciar sesión para ver todas las notas y otros contenidos que hayas creado. Se espera que esto evite que los rastreadores recopilen información." + requireSigninToViewContentsDescription2: "El contenido no se mostrará en vistas previas de URL (OGP), incrustado en páginas web o en servidores que no admitan citas de notas." + requireSigninToViewContentsDescription3: "Estas restricciones pueden no aplicarse a los contenidos federados de otros servidores remotos." + makeNotesFollowersOnlyBefore: "Hacer que las notas antiguas sólo se muestren a los seguidores" + makeNotesFollowersOnlyBeforeDescription: "Mientras esta función esté activada, sólo los seguidores podrán ver las notas que hayan superado la fecha y hora establecidas o que hayan estado visibles durante un tiempo determinado. Cuando se desactive, también se restablecerá el estado de publicación de la nota." + makeNotesHiddenBefore: "Hacer privadas las notas antiguas " + makeNotesHiddenBeforeDescription: "Mientras esta función esté activada, las notas que hayan pasado la fecha y hora fijadas o hayan transcurrido el tiempo establecido sólo serán visibles para ti (se harán privadas). Si la desactivas, también se restablecerá el estado público de las notas." + mayNotEffectForFederatedNotes: "Notas federadas por un servidor remoto pueden no verse afectadas." + mayNotEffectSomeSituations: "Estas restricciones son simplificadas. Pueden no aplicarse en algunas situaciones, como cuando se visualiza en un servidor remoto o durante la moderación." + notesHavePassedSpecifiedPeriod: "Notas publicadas durante el siguiente tiempo específico" + notesOlderThanSpecifiedDateAndTime: "Notas antes de la fecha y hora especificadas" _abuseUserReport: + forward: "Reenviar" + forwardDescription: "Reenvía el informe a un servidor/instancia remoto como cuenta anónima del sistema." + resolve: "Resuelto" accept: "Acepte" reject: "repudio" + resolveTutorial: "Si el contenido del informe es legítimo, selecciona \"Aceptar\" para marcarlo como resuelto.\nSi el contenido del informe es ilegítimo, selecciona \"Rechazar\" para ignorarlo." _delivery: + status: "Estado de la entrega" stop: "Suspendido" + resume: "Resumen de entrega" _type: none: "Publicando" + manuallySuspended: "Suspendido manualmente" + goneSuspended: "El servidor se ha suspendido debido a la eliminación del servidor" + autoSuspendedForNotResponding: "El servidor se suspende debido a que el servidor no responde." + softwareSuspended: "Suspendido porque este software ya no se distribuye a" _bubbleGame: howToPlay: "Cómo jugar" hold: "Mantener" @@ -1457,7 +1582,7 @@ _announcement: tooManyActiveAnnouncementDescription: "Tener demasiados anuncios activos empeora la experiencia de usuario. Por favor, considera archivar aquellos anuncios que hayan quedado obsoletos." readConfirmTitle: "¿Marcar como leído?" readConfirmText: "Esto marcará el contenido de \"{title}\" como leído." - shouldNotBeUsedToPresentPermanentInfo: "Dado que puede impactar en la experiencia de usuario de forma significativa, es recomendable usar notificaciones en el flujo de información en vez de información persistente." + shouldNotBeUsedToPresentPermanentInfo: "Se recomienda utilizar los avisos para publicar información que requiera inmediatez, en lugar de hacerlo constantemente, ya que esto perjudica especialmente la UX de los nuevos usuarios." dialogAnnouncementUxWarn: "Mostrar dos o más notificaciones en formato diálogo a la vez puede impactar en la experiencia de usuario de forma significativa, úsalos con cuidado." silence: "Silenciar notificaciones" silenceDescription: "Si lo activas, no enviarás notificación sobre este anuncio y el usuario no tendrá que leerlo." @@ -1558,6 +1683,38 @@ _serverSettings: fanoutTimelineDescription: "Incrementa el rendimiento de forma significativa cuando se obtienen las líneas de tiempo y reduce la carga en la base de datos. A cambio, el uso de la memoria en Redis incrementará. Considera desactivar esta opción en caso de que tu servidor tenga poca memoria o detectes inestabilidad." fanoutTimelineDbFallback: "Cargar desde la base de datos" fanoutTimelineDbFallbackDescription: "Cuando esta opción está habilitada, la carga de peticiones adicionales de la línea de tiempo se hará desde la base de datos cuando éstas no se encuentren en la caché. Al deshabilitar esta opción se reduce la carga del servidor, pero limita el número de líneas de tiempo que pueden obtenerse." + reactionsBufferingDescription: "Cuando se activa, el rendimiento durante la creación de reacciones mejorará considerablemente, reduciendo la carga de la base de datos. Sin embargo, aumentará el uso de memoria de Redis." + remoteNotesCleaning: "Limpieza automática de notas (publicaciones) remotas" + remoteNotesCleaning_description: "Al habilitar esta opción, se limpiarán periódicamente las entradas remotas antiguas que no se consultan, lo que evitará que la base de datos se sature." + remoteNotesCleaningMaxProcessingDuration: "Tiempo máximo de funcionamiento continuo del proceso de limpieza" + remoteNotesCleaningExpiryDaysForEachNotes: "Días mínimos para conservar las notas" + inquiryUrl: "URL de consulta " + inquiryUrlDescription: "Especifica una URL para el formulario de consulta al responsable del servidor o una página web para la información de contacto." + openRegistration: "Registros Abiertos" + openRegistrationWarning: "Abrir registros conlleva riesgos. Se recomienda solo habilitarlos si tienes un sistema en el cual puedes monitorear continuamente el servidor y respondes inmediatamente en caso de que haya cualquier problema." + thisSettingWillAutomaticallyOffWhenModeratorsInactive: "Si no se ha detectado por un tiempo actividad de un moderador, este ajuste será automáticamente desactivado para prevenir el spam. " + deliverSuspendedSoftware: "Software suspendido." + deliverSuspendedSoftwareDescription: "Puede especificar un rango de nombres y versiones del software del servidor para detener la entrega, por ejemplo, debido a vulnerabilidades. Esta información sobre la versión la proporciona el servidor y su fiabilidad no está garantizada. Se puede utilizar una especificación de rango para especificar una versión, pero se recomienda especificar una versión previa, como >= 2024.3.1-0, ya que especificar >= 2024.3.1 no incluirá versiones personalizadas como 2024.3.1-custom.0." + singleUserMode: "Modo de usuario único" + singleUserMode_description: "Si eres el único usuario de este servidor, activar este modo optimizará su rendimiento." + signToActivityPubGet: "Firmar solicitudes GET de Activitypub." + signToActivityPubGet_description: "Normalmente, debería estar activada. Deshabilitarlo puede mejorar los problemas relacionados con la federación, pero por otro lado podría deshabilitar la federación hacia otros servidores." + proxyRemoteFiles: "Proxy de archivos remotos" + proxyRemoteFiles_description: "Cuando se activa, el servidor proxy sirve archivos remotos. Esto es útil para generar miniaturas de imágenes y proteger la privacidad del usuario." + allowExternalApRedirect: "Permitir redirecciones para consultas vía ActivityPub" + allowExternalApRedirect_description: "Si se activa, otros servidores pueden consultar contenidos de terceros a través de este servidor, pero esto puede dar lugar a la suplantación de contenidos." + userGeneratedContentsVisibilityForVisitor: "Visibilidad de contenido generado por un usuario a invitados" + userGeneratedContentsVisibilityForVisitor_description: "Esto es útil para evitar problemas causados por contenidos remotos inapropiados que no estén bien moderados y que se publiquen involuntariamente en Internet a través de su propio servidor." + userGeneratedContentsVisibilityForVisitor_description2: "Publicar incondicionalmente todo el contenido del servidor en Internet, incluido el contenido remoto recibido por el servidor, es arriesgado. Esto es especialmente importante para los invitados que desconocen la naturaleza distribuida del contenido, ya que pueden creer erróneamente que incluso el contenido remoto es contenido creado por usuarios en el servidor." + restartServerSetupWizardConfirm_title: "¿Reiniciar el asistente de configuración del servidor?" + restartServerSetupWizardConfirm_text: "Algunas configuraciones actuales se restablecerán" + entrancePageStyle: "Estilo de la página de inicio" + showTimelineForVisitor: "Mostrar la línea de tiempo" + showActivitiesForVisitor: "Mostrar actividades" + _userGeneratedContentsVisibilityForVisitor: + all: "Todo es público." + localOnly: "Sólo se publica el contenido local, el remoto se mantiene privado" + none: "Todo es privado" _accountMigration: moveFrom: "Trasladar de otra cuenta a ésta" moveFromSub: "Crear un alias para otra cuenta." @@ -1857,6 +2014,8 @@ _role: descriptionOfIsExplorable: "La línea de tiempo de éste rol y la lista de usuarios serán públicos si se activa.." displayOrder: "Posición" descriptionOfDisplayOrder: "Entre más alto el número, mayor es la posición en la interfaz." + preserveAssignmentOnMoveAccount: "Preservar los roles asignados durante la migración" + preserveAssignmentOnMoveAccount_description: "Si está activada, este rol se transferirá a la cuenta de destino cuando se migre una cuenta con este rol." canEditMembersByModerator: "Permitir a los moderadores editar los miembros" descriptionOfCanEditMembersByModerator: "Si se activa, los moderadores, al igual que los administradores, serán capaces de asignar/quitar usuarios a éste rol. Si se desactiva, sólo los administradores podrán hacerlo." priority: "Prioridad" @@ -1876,7 +2035,10 @@ _role: canManageCustomEmojis: "Administrar emojis personalizados" canManageAvatarDecorations: "Administrar decoraciones de avatar" driveCapacity: "Capacidad del drive" + maxFileSize: "Tamaño máximo de archivo que se puede cargar." + maxFileSize_caption: "Los proxies inversos o las CDN pueden tener diferentes valores de configuración aguas arriba." alwaysMarkNsfw: "Siempre marcar archivos como NSFW" + canUpdateBioMedia: "Puede editar un icono o una imagen de fondo (banner)" pinMax: "Máximo de notas fijadas" antennaMax: "Máximo de antenas" wordMuteMax: "Máximo de caracteres en palabras silenciadas" @@ -1889,8 +2051,21 @@ _role: descriptionOfRateLimitFactor: "Límites más bajos son menos restrictivos, más altos menos restrictivos" canHideAds: "Puede ocultar anuncios" canSearchNotes: "Uso de la búsqueda de notas" + canSearchUsers: "Uso de la búsqueda de usuarios" canUseTranslator: "Uso de traductor" avatarDecorationLimit: "Número máximo de decoraciones de avatar" + canImportAntennas: "Permitir la importación de antenas" + canImportBlocking: "Permitir la importación de bloqueos" + canImportFollowing: "Permitir la importación de seguidos" + canImportMuting: "Permitir la importación de silenciados" + canImportUserLists: "Permitir la importación de listas" + chatAvailability: "Permitir Chats" + uploadableFileTypes: "Tipos de archivos que se pueden cargar." + uploadableFileTypes_caption: "Especifica los tipos MIME/archivos permitidos. Se pueden especificar varios tipos MIME separándolos con una nueva línea, y se pueden especificar comodines con un asterisco (*). (por ejemplo, image/*)" + uploadableFileTypes_caption2: "Es posible que no se detecten algunos tipos de archivos. Para permitir estos archivos, añade {x} a la especificación." + noteDraftLimit: "Número de posibles borradores de notas del servidor" + scheduledNoteLimit: "Máximo número de notas programadas que se pueden crear simultáneamente." + watermarkAvailable: "Disponibilidad de la función de marca de agua" _condition: roleAssignedTo: "Asignado a roles manuales" isLocal: "Usuario local" @@ -1899,6 +2074,7 @@ _role: isBot: "Usuarios Bot" isSuspended: "Usuario suspendido" isLocked: "Cuentas privadas" + isExplorable: "Hacer que la cuenta sea visible en las búsquedas" createdLessThan: "Menos de X han pasado desde la creación de la cuenta" createdMoreThan: "Más de X han pasado desde la creación de la cuenta" followersLessThanOrEq: "Tiene X o menos seguidores" @@ -2008,7 +2184,7 @@ _aboutMisskey: _displayOfSensitiveMedia: respect: "Esconder medios marcados como sensibles" ignore: "Mostrar medios marcados como sensibles" - force: "Esconder todala multimedia" + force: "Esconder toda la multimedia" _mfc: cheatSheet: "Hoja de referencia de MFC" intro: "MFC es un lenguaje de marcado dedicado que se puede usar en varios lugares dentro de CherryPick. Aquí puede ver una lista de sintaxis disponibles en MFC." @@ -2115,10 +2291,12 @@ _theme: install: "Instalar tema" manage: "Gestor de temas" code: "Código del tema" + copyThemeCode: "Copiar el código del tema" description: "Descripción" installed: "{name} ha sido instalado" installedThemes: "Temas instalados" builtinThemes: "Temas integrados" + instanceTheme: "Tema del servidor (o también denominado: tema de la instancia)" alreadyInstalled: "Este tema ya está instalado" invalid: "El formato del tema no es válido" make: "Crear tema" @@ -2172,7 +2350,6 @@ _theme: buttonBg: "Fondo de botón" buttonHoverBg: "Fondo de botón (hover)" inputBorder: "Borde de los campos de entrada" - driveFolderBg: "Fondo de capeta del drive" badge: "Medalla" messageBg: "Fondo de chat" fgHighlighted: "Texto resaltado" @@ -2181,6 +2358,7 @@ _sfx: noteMy: "Nota (a mí mismo)" notification: "Notificaciones" reaction: "Al seleccionar una reacción" + chatMessage: "Mensajes del Chat" _soundSettings: driveFile: "Usar un archivo de audio en Drive" driveFileWarn: "Selecciona un archivo de audio en Drive." @@ -2188,6 +2366,7 @@ _soundSettings: driveFileTypeWarnDescription: "Selecciona un archivo de audio" driveFileDurationWarn: "La duración del audio es demasiado larga." driveFileDurationWarnDescription: "Usar un audio de larga duración puede llegar a molestar mientras usas CherryPick. ¿Quieres continuar?" + driveFileError: "No puedo cargar el sonido. Por favor cambia la configuración." _ago: future: "Futuro" justNow: "Justo ahora" @@ -2212,6 +2391,7 @@ _time: minute: "Minutos" hour: "Horas" day: "Días" + month: "Mes(es)" _2fa: alreadyRegistered: "Ya has completado la configuración." registerTOTP: "Registrar aplicación autenticadora" @@ -2223,7 +2403,7 @@ _2fa: setupCompleted: "Configuración completada" step4: "Ahora cuando inicie sesión, ingrese el mismo token" securityKeyNotSupported: "Tu navegador no soporta claves de autenticación." - registerTOTPBeforeKey: "Please set up an authenticator app to register a security or pass key.\npor favor. configura una aplicación de autenticación para registrar una llave de seguridad." + registerTOTPBeforeKey: "Por favor. configura una aplicación de autenticación para registrar una llave de seguridad." securityKeyInfo: "Se puede configurar el inicio de sesión usando una clave de seguridad de hardware que soporte FIDO2 o con un certificado de huella digital o con un PIN" registerSecurityKey: "Registrar una llave de seguridad" securityKeyName: "Ingresa un nombre para la clave" @@ -2327,6 +2507,7 @@ _permissions: "read:federation": "Ver instancias federadas" "write:report-abuse": "Crear reportes de usuario" "write:chat": "Administrar chat" + "read:chat": "Explorar Chats" _auth: shareAccessTitle: "Permisos de la aplicación" shareAccess: "¿Desea permitir el acceso a la cuenta \"{name}\"?" @@ -2335,8 +2516,12 @@ _auth: permissionAsk: "Esta aplicación requiere los siguientes permisos" pleaseGoBack: "Por favor, vuelve a la aplicación" callback: "Volviendo a la aplicación" + accepted: "Acceso concedido." denied: "Acceso denegado" + scopeUser: "Operar como el siguiente usuario" pleaseLogin: "Se requiere un inicio de sesión para darle permisos a la aplicación" + byClickingYouWillBeRedirectedToThisUrl: "Cuando el acceso es concedido, serás automáticamente redireccionado a la siguiente URL" + alreadyAuthorized: "Esta aplicación ya ha obtenido acceso." _antennaSources: all: "Todas las notas" homeTimeline: "Notas de los usuarios que sigues" @@ -2383,7 +2568,7 @@ _widgets: chooseList: "Seleccione una lista" clicker: "Cliqueador" birthdayFollowings: "Hoy cumplen años" - chat: "Chat" + chat: "Chatear" _cw: hide: "Ocultar" show: "Ver más" @@ -2423,6 +2608,8 @@ _visibility: disableFederation: "No federado" disableFederationDescription: "No enviar a otras instancias" _postForm: + quitInspiteOfThereAreUnuploadedFilesConfirm: "Hay archivos que no se han cargado, ¿deseas descartarlos y cerrar el formulario?" + uploaderTip: "El archivo aún no se ha cargado. Desde el menú de archivos, puedes cambiar el nombre, recortar la imagen, añadir una marca de agua y configurar la compresión, entre otras opciones. Los archivos se suben automáticamente al publicar una nota." replyPlaceholder: "Responder a esta nota" quotePlaceholder: "Citar esta nota" channelPlaceholder: "Publicar en el canal" @@ -2447,6 +2634,9 @@ _profile: changeBanner: "Cambiar banner" verifiedLinkDescription: "Introduciendo una URL que contiene un enlace a tu perfil, se puede mostrar un icono de verificación de propiedad al lado del campo." avatarDecorationMax: "Puedes añadir un máximo de {max} decoraciones de avatar." + followedMessage: "Mensaje cuando te han seguido" + followedMessageDescription: "Puedes establecer un mensaje de bienvenida para nuevos seguidores." + followedMessageDescriptionForLockedAccount: "Si apruebas manualmente seguidores, el mensaje se mostrará al seguidor en el momento de la aprobación." _exportOrImport: allNotes: "Todas las notas" favoritedNotes: "Notas favoritas" @@ -2537,6 +2727,7 @@ _pages: eyeCatchingImageSet: "Elegir imagen llamativa" eyeCatchingImageRemove: "Borrar imagen llamativa" chooseBlock: "Agregar bloque" + enterSectionTitle: "Escribe el título de la sección" selectType: "Elegir tipo" contentBlocks: "Contenido" inputBlocks: "Entrada" @@ -2569,9 +2760,12 @@ _notification: yourFollowRequestAccepted: "Tu solicitud de seguimiento fue aceptada" youWereInvitedToGroup: "{userName} Invitado al grupo" pollEnded: "Estan disponibles los resultados de la encuesta" + scheduledNotePosted: "Una nota programada ha sido publicada" + scheduledNotePostFailed: "Ha fallado la publicación de una nota programada" newNote: "Nueva nota" unreadAntennaNote: "Antena {name}" roleAssigned: "Rol asignado" + chatRoomInvitationReceived: "Invitado a la sala de chat." emptyPushNotificationMessage: "Se han actualizado las notificaciones push" achievementEarned: "Logro desbloqueado" testNotification: "Notificación de prueba" @@ -2579,8 +2773,14 @@ _notification: sendTestNotification: "Enviar notificación de prueba" notificationWillBeDisplayedLikeThis: "Las notificaciones tendrán este aspecto" reactedBySomeUsers: "{n} usuarios han reaccionado" + likedBySomeUsers: "{n} usuarios les gustó tu nota" renotedBySomeUsers: "{n} usuarios han renotado" followedBySomeUsers: "Seguido por {n} usuarios" + flushNotification: "Limpiar notificaciones" + exportOfXCompleted: "La exportación de {x} ha sido completada." + login: "Alguien ha iniciado sesión" + createToken: "Token de acceso creado" + createTokenDescription: "Si no tienes ni idea, elimina el token de acceso a través de \"{text}\"." _types: all: "Todo" note: "Nuevas notas" @@ -2591,12 +2791,17 @@ _notification: quote: "Citar" reaction: "Reacción" pollEnded: "La encuesta terminó" + scheduledNotePosted: "Publicación programada con éxito" + scheduledNotePostFailed: "Publicación programada fallida" receiveFollowRequest: "Recibió una solicitud de seguimiento" followRequestAccepted: "El seguimiento fue aceptado" groupInvited: "Invitado al grupo" roleAssigned: "Rol asignado" + chatRoomInvitationReceived: "Invitado a la sala de chat." achievementEarned: "Logro desbloqueado" + exportCompleted: "La exportación se ha completado" login: "Iniciar sesión" + createToken: "Crear tokens de acceso" test: "Pruebas de nofiticaciones" app: "Notificaciones desde aplicaciones" _actions: @@ -2606,7 +2811,11 @@ _notification: _deck: alwaysShowMainColumn: "Siempre mostrar la columna principal" columnAlign: "Alinear columnas" + columnGap: "Margen entre columnas" + deckMenuPosition: "Posición del menú Deck" + navbarPosition: "Posición de la barra de navegación" addColumn: "Agregar columna" + newNoteNotificationSettings: "Configuración de las notificaciones para notas nuevas" configureColumn: "Ajustes de columna" swapLeft: "Mover a la izquierda" swapRight: "Mover a la derecha" @@ -2623,6 +2832,7 @@ _deck: useSimpleUiForNonRootPages: "Mostrar páginas no pertenecientes a la raíz con la interfaz simple" usedAsMinWidthWhenFlexible: "Se usará el ancho mínimo cuando la opción \"Autoajustar ancho\" esté habilitada" flexible: "Autoajustar ancho" + enableSyncBetweenDevicesForProfiles: "Activar la sincronización de la información de perfiles entre dispositivos." _columns: main: "Principal" widgets: "Widgets" @@ -2634,7 +2844,7 @@ _deck: mentions: "Menciones" direct: "Notas directas" roleTimeline: "Linea de tiempo del rol" - chat: "Chat" + chat: "Chatear" _dialog: charactersExceeded: "¡Has excedido el límite de caracteres! Actualmente {current} de {max}." charactersBelow: "¡Estás por debajo del límite de caracteres! Actualmente {current} de {min}." @@ -2646,8 +2856,10 @@ _drivecleaner: orderByCreatedAtAsc: "Fecha ascendente" _webhookSettings: createWebhook: "Crear Webhook" + modifyWebhook: "Editar webhook" name: "Nombre" secret: "Secreto" + trigger: "Disparador" active: "Activado" _events: follow: "Cuando se sigue a alguien" @@ -2658,13 +2870,28 @@ _webhookSettings: reaction: "Cuando se recibe una reacción" mention: "Cuando hay una mención" _systemEvents: + abuseReport: "Cuando se recibe un nuevo informe de moderación" + abuseReportResolved: "Cuando se resuelve un informe de moderación" userCreated: "Cuando se crea el usuario." + inactiveModeratorsWarning: "Cuando un moderador ha estado inactivo por un tiempo" + inactiveModeratorsInvitationOnlyChanged: "Cuando un moderador ha estado inactivo durante un tiempo, y el servidor se cambia a sólo por invitación" + deleteConfirm: "¿Estás seguro de querer eliminar el Webhook?" + testRemarks: "Haz clic en el botón de la derecha del switch para mandar una prueba Webhook con datos ficticios" _abuseReport: _notificationRecipient: + createRecipient: "Añadir destinatario a los informes" + modifyRecipient: "Editar un destinatario en el informe de moderación\n" + recipientType: "Tipo de notificación" _recipientType: mail: "Correo" webhook: "Webhook" + _captions: + mail: "Enviar un correo electrónico a todos los moderadores cuando reciban un informe de moderación" + webhook: "Enviar una notificación al SystemWebhook cuando se reciba o se resuelva un informe de moderación" keywords: "Palabras Clave" + notifiedUser: "Usuarios a notificar" + notifiedWebhook: "Webhook a utilizar" + deleteConfirm: "¿Estás seguro de que deseas borrar el destinatario del informe de moderación?" _moderationLogTypes: createRole: "Rol creado" deleteRole: "Rol eliminado" @@ -2689,9 +2916,12 @@ _moderationLogTypes: resetPassword: "Resetear contraseña" suspendRemoteInstance: "Instancia remota suspendida" unsuspendRemoteInstance: "Suspensión de instancia remota retirada" + updateRemoteInstanceNote: "Nota de moderación de una instancia remota actualizada" markSensitiveDriveFile: "Archivo marcado como sensible" unmarkSensitiveDriveFile: "Archivo marcado como no sensible" resolveAbuseReport: "Reporte resuelto" + forwardAbuseReport: "Informe reenviado" + updateAbuseReportNote: "Nota de moderación de un informe actualizada" createInvitation: "Generar invitación" createAd: "Anuncio creado" deleteAd: "Anuncio eliminado" @@ -2701,6 +2931,18 @@ _moderationLogTypes: deleteAvatarDecoration: "Decoración de avatar eliminada" unsetUserAvatar: "Quitar decoración de avatar de este usuario" unsetUserBanner: "Quitar banner de este usuario" + createSystemWebhook: "Crear un SystemWebhook" + updateSystemWebhook: "Actualizar SystemWebhook " + deleteSystemWebhook: "Borrar SystemWebHook" + createAbuseReportNotificationRecipient: "Crear un destinatario para el informe de moderación" + updateAbuseReportNotificationRecipient: "Destinatario de los informes actualizados" + deleteAbuseReportNotificationRecipient: "Destinatario de los informes borrado" + deleteAccount: "Cuenta Borrada" + deletePage: "Página borrada" + deleteFlash: "Juego borrado" + deleteGalleryPost: "Publicación de la galería, eliminada" + deleteChatRoom: "Borrar sala del chat" + updateProxyAccountDescription: "Actualizar la descripción de la cuenta proxy" _fileViewer: title: "Detalles del archivo" type: "Tipo de archivo" @@ -2708,6 +2950,7 @@ _fileViewer: url: "URL" uploadedAt: "Subido el" attachedNotes: "Notas adjuntas" + usage: "Utilizado" thisPageCanBeSeenFromTheAuthor: "Esta página solo puede ser vista por el autor." _externalResourceInstaller: title: "Instalar desde sitio externo" @@ -2755,35 +2998,409 @@ _dataSaver: _avatar: title: "Avatares animados" description: "Desactiva la animación de los avatares. Las imágenes animadas pueden llegar a ser de mayor tamaño que las normales, por lo que al desactivarlas puedes reducir el consumo de datos." - _urlPreview: - title: "Vista previa de URLs" - description: "Desactiva la carga de vistas previas de las URLs." + _urlPreviewThumbnail: + title: "Ocultar las miniaturas de las vistas previas de URL" + description: "Las imágenes en miniatura de la vista previa de URL no se pueden cargar " + _disableUrlPreview: + title: "Desactivar la vista previa de las URL" + description: "Desactiva la función de previsualización de la URL. A diferencia de solo las imágenes en miniatura, esta función reduce la carga de la propia información vinculada." _code: title: "Resaltar código" description: "Si se usa resaltado de código en MFC, etc., no se cargará hasta pulsar en ello. El resaltado de sintaxis requiere la descarga de archivos de definición para cada lenguaje de programación. Debido a esto, al deshabilitar la carga automática de estos archivos reducirás el consumo de datos." _hemisphere: N: "Hemisferio norte" S: "Hemisferio sur" + caption: "Usado en algunos clientes para determinar la estación del año" _reversi: reversi: "Reversi" + gameSettings: "Configuración del juego" + chooseBoard: "Elegir tablero" + blackOrWhite: "Negras/Blancas" + blackIs: "{name} juega con negras" rules: "Reglas" + thisGameIsStartedSoon: "El juego comenzará en breve" + waitingForOther: "Esperando el turno del adversario" + waitingForMe: "Esperando tu turno" + waitingBoth: "Prepárate" + ready: "Listo" + cancelReady: "No estoy listo" + opponentTurn: "Turno del oponente" + myTurn: "¡Tu turno!" + turnOf: "Le toca a {name}" + pastTurnOf: "Turno de {name}" + surrender: "Rendirse" + surrendered: "Te has rendido" + timeout: "Se acabó el tiempo" + drawn: "Empate" won: "{name} ha ganado" + black: "Negras" + white: "Blancas" total: "Total" + turnCount: "Turno {count}" + myGames: "Mis rondas" + allGames: "Todos los juegos" + ended: "Finalizado" + playing: "Jugando actualmente" + isLlotheo: "El que tenga menos fichas gana (LLoTheO)" + loopedMap: "Mapa en bucle" + canPutEverywhere: "Las fichas se pueden poner a cualquier lugar\n" + timeLimitForEachTurn: "Tiempo límite por jugada." + freeMatch: "Partida libre." + lookingForPlayer: "Buscando oponente" + gameCanceled: "La partida ha sido cancelada." + shareToTlTheGameWhenStart: "Compartir la partida en la línea de tiempo cuando comience " + iStartedAGame: "¡La partida ha comenzado!" + opponentHasSettingsChanged: "El oponente ha cambiado su configuración" + allowIrregularRules: "Reglas irregulares (completamente libre)" + disallowIrregularRules: "Sin reglas irregulares " + showBoardLabels: "Mostrar el número de línea y la letra de columna en el tablero de juego." + useAvatarAsStone: "Usar los avatares de los usuarios como fichas\n" +_offlineScreen: + title: "Fuera de línea. No se puede conectar con el servidor" + header: "Incapaz de conectar con el servidor" _urlPreviewSetting: + title: "Configuración para la previsualización de la URL" + enable: "Activar la vista previa de URL" + allowRedirect: "Permitir la redirección de la visualización previa" + allowRedirectDescription: "Si una URL tiene una redirección establecida, puede activar esta función para seguir la redirección y mostrar una vista previa del contenido redirigido. Si se desactiva, se ahorrarán recursos del servidor, pero no se mostrará el contenido redirigido." timeout: "Timeout de la carga de vista previa de las URLs (ms)" + timeoutDescription: "Si se tarda más de este valor en obtener la vista previa, ésta no se generará." maximumContentLength: "Content-Length Máximo (bytes)" + maximumContentLengthDescription: "Si Content-Length es superior a este valor, no se generará la vista previa." + requireContentLength: "Genere la vista previa sólo si puede obtener Content-Length" + requireContentLengthDescription: "Si el otro servidor no devuelve Content-Length, no se generará la vista previa." userAgent: "User-Agent" + userAgentDescription: "Establece el User-Agent que se utilizará al recuperar vistas previas. Si se deja en blanco, se utilizará el User-Agent por defecto." + summaryProxy: "Proxy endpoints para generar vistas previas" + summaryProxyDescription: "La vista previa se genera usando Summaly proxy, no la genera el mismo CherryPick." + summaryProxyDescription2: "Los siguientes parámetros se vinculan al proxy como cadena de consulta (query string). Si el proxy no los admite, los valores se ignoran." _mediaControls: pip: "Picture in Picture" playbackRate: "Velocidad de reproducción" loop: "Reproducción en bucle" +_contextMenu: + title: "Menú contextual" + app: "Aplicación" + appWithShift: "Aplicación con la tecla shift" + native: "Interfaz nativa (del navegador web)" +_gridComponent: + _error: + requiredValue: "Este valor es obligatorio" + columnTypeNotSupport: "La validación con expresión regular sólo se admite para columnas de tipo:texto." + patternNotMatch: "Este valor no coincide con el patrón en {pattern}" + notUnique: "Este valor debe ser único" +_roleSelectDialog: + notSelected: "No seleccionado" +_customEmojisManager: + _gridCommon: + copySelectionRows: "Copiar filas seleccionadas" + copySelectionRanges: "Copiar selección" + deleteSelectionRows: "Borrar las líneas seleccionadas" + deleteSelectionRanges: "Borrar las filas de la selección" + searchSettings: "Ajustes de búsqueda" + searchSettingCaption: "Establecer criterios de búsqueda detallados." + searchLimit: "Límite de resultados" + sortOrder: "Ordenar" + registrationLogs: "Log de registros " + registrationLogsCaption: "Los registros se mostrarán al actualizar o borrar Emojis. Desaparecerán después de actualizarlos o eliminarlos, pasar a una nueva página o recargar." + alertEmojisRegisterFailedDescription: "No se ha podido actualizar o borrar el emoji. Por favor comprueba el log del registro para más detalles." + _logs: + showSuccessLogSwitch: "Mostrar registro de éxito" + failureLogNothing: "No hay log de fallos" + logNothing: "No hay logs" + _remote: + selectionRowDetail: "Detalle de la línea seleccionada" + importSelectionRows: "Importar las líneas seleccionadas" + importSelectionRangesRows: "Importar las filas seleccionadas" + importEmojisButton: "Importar los Emojis marcados" + confirmImportEmojisTitle: "Importar Emojis" + confirmImportEmojisDescription: "Importar {count} Emoji(s) recibidos del servidor remoto. Por favor, presta mucha atención a la licencia del Emoji. ¿Estás seguro de continuar?" + _local: + tabTitleList: "Lista de emojis registrados" + tabTitleRegister: "Registro de Emojis" + _list: + emojisNothing: "No hay Emojis registrados" + markAsDeleteTargetRows: "Marcar las filas seleccionadas como objetivo a eliminar" + markAsDeleteTargetRanges: "Selección de filas para su eliminación" + alertUpdateEmojisNothingDescription: "No hay Emojis actualizados" + alertDeleteEmojisNothingDescription: "No hay Emojis para borrar" + confirmMovePage: "¿Quieres cambiar de página?" + confirmChangeView: "¿De verdad quieres cambiar la vista?" + confirmUpdateEmojisDescription: "Actualizar {count} Emoji(s). ¿Deseas continuar?" + confirmDeleteEmojisDescription: "Borrar {count} Emoji(s) seleccionados. ¿Deseas continuar?" + confirmResetDescription: "Se restablecerán todos los cambios hechos hasta ahora." + confirmMovePageDesciption: "Se han realizado cambios en los Emojis de esta página.\nSi abandonas la página sin guardar, se descartarán todos los cambios realizados en esta página." + dialogSelectRoleTitle: "Buscar Emojis por rol" + _register: + uploadSettingTitle: "Ajustes de carga" + uploadSettingDescription: "En esta pantalla, puedes configurar el comportamiento al cargar Emojis." + directoryToCategoryLabel: "Introduce el nombre del directorio en el campo \"categoría\"" + directoryToCategoryCaption: "Cuando arrastres y sueltes un directorio, introduce el nombre del directorio en el campo \"categoría\"." + confirmRegisterEmojisDescription: "Registra los Emojis de la lista como nuevos Emojis personalizados. ¿Estás seguro de continuar? (Para evitar sobrecargas, sólo {count} Emoji(s) en una sola operación)" + confirmClearEmojisDescription: "Descartar las ediciones y borrar los Emojis de la lista. ¿Estás seguro de continuar?" + confirmUploadEmojisDescription: "Cargar los {count} archivo(s) arrastrado(s) y soltado(s) en la unidad. ¿Estás seguro de continuar?" +_embedCodeGen: + title: "Personalizar el código de incrustación" + header: "Mostrar encabezados" + autoload: "Cargar más automáticamente (no recomendado)" + maxHeight: "Altura máxima" + maxHeightDescription: "0 desactiva el ajuste del valor máximo. Para evitar que el widget siga creciendo verticalmente, especifica algún valor." + maxHeightWarn: "El límite de altura máxima está desactivado (0). Si esto no estaba previsto, establece la altura máxima en algún valor." + previewIsNotActual: "La visualización difiere de la incrustación real porque excede el rango mostrado en la pantalla de vista previa." + rounded: "Bordes Redondeados" + border: "Añadir un borde al marco exterior" + applyToPreview: "Aplicar a la vista previa" + generateCode: "Crear el código para incrustar" + codeGenerated: "El código ha sido generado" + codeGeneratedDescription: "Pegue el código generado en su sitio web para incrustar el contenido." +_selfXssPrevention: + warning: "Advertencia" + title: "\"Pegar algo en esta pantalla\" es un timo." + description1: "Si pegas algo aquí, un usuario malintencionado podría secuestrar tu cuenta o robar tu información personal." + description2: "Si no entiendes que estás pegando exactamente, %cdetente ahora mismo y cierra esta ventana" + description3: "Para más información visita esto {link}" _followRequest: recieved: "Petición de seguimiento recibida" sent: "Petición de seguimiento enviada" _remoteLookupErrors: + _federationNotAllowed: + title: "Incapaz de comunicarse con este servidor." + description: "Es posible que se haya desactivado la comunicación con este servidor o que haya sido bloqueado.\nPonte en contacto con el administrador del servidor.." + _uriInvalid: + title: "La URI es inválida" + description: "Ha habido un problema con la dirección introducida. Comprueba que no hayas escrito caracteres que no pueden ser usados en la URI" + _requestFailed: + title: "Solicitud fallida." + description: "Ha fallado la comunicación con este servidor. Es posible que el servidor no funcione. Asegúrese también de que no ha introducido un URI no válido o inexistente." + _responseInvalid: + title: "La respuesta no es válida" + description: "Has podido comunicarte con este servidor, pero los datos obtenidos eran incorrectos. Si estás consultando contenidos remotos a través de un servidor de terceros, vuelve a realizar la consulta utilizando un URI que pueda obtenerse del servidor de origen." _noSuchObject: title: "No se encuentra" + description: "No se ha encontrado el recurso solicitado, por favor, vuelve a comprobar el URI." +_captcha: + verify: "Por favor verifica el CAPTCHA" + testSiteKeyMessage: "Puedes comprobar la vista previa introduciendo los valores de prueba para el sitio y las claves secretas.\nPara más detalles, consulta la página siguiente.\n" + _error: + _requestFailed: + title: "Ha fallado la solicitud del CAPTCHA" + text: "Por favor, ejecútalo después de un rato o comprueba los ajustes de nuevo." + _verificationFailed: + title: "Ha fallado la validación del CAPTCHA" + text: "Comprueba que los ajustes son los correctos." + _unknown: + title: "Error en el CAPTCHA." + text: "Se ha producido un error inesperado." +_bootErrors: + title: "Fallo al cargar" + serverError: "Si el problema persiste después de esperar un momento y volver a cargar, póngase en contacto con el administrador del servidor con el siguiente ID de error." + solution: "Lo siguiente puede resolver el problema." + solution1: "Actualiza tu navegador web y el sistema operativo a la última versión" + solution2: "Desactiva el AdBlocker" + solution3: "Borra la memoria caché del navegador web " + solution4: "(Navegador Tor) configura dom.webaudio.enabled a true" + otherOption: "Otras opciones" + otherOption1: "Borra la configuración y la memoria caché del cliente" + otherOption2: "Iniciar el cliente simple" + otherOption3: "Iniciar la herramienta de reparación" + otherOption4: "Iniciar CherryPick en modo seguro" _search: searchScopeAll: "Todo" searchScopeLocal: "Local" + searchScopeServer: "Especifica el servidor (Instancia)" searchScopeUser: "Especificar usuario" + pleaseEnterServerHost: "Introduce la dirección del servidor/Instancia" + pleaseSelectUser: "Selecciona un usuario, por favor" + serverHostPlaceholder: "Ejemplo: cherrypick.example.com" +_serverSetupWizard: + installCompleted: "¡La instalación de CherryPick se ha completado!" + firstCreateAccount: "Para comenzar, crea una cuenta de administrador" + accountCreated: "¡La cuenta de administrador se ha creado! " + serverSetting: "Configuración del servidor" + youCanEasilyConfigureOptimalServerSettingsWithThisWizard: "Este asistente te facilita una configuración óptima del servidor." + settingsYouMakeHereCanBeChangedLater: "Los ajustes que han sido cambiados a través de este asistente pueden ser modificados más tarde." + howWillYouUseMisskey: "¿Cómo vas a usar CherryPick?" + _use: + single: "Servidor para un único usuario." + single_description: "Utilízalo como tu propio servidor dedicado." + single_youCanCreateMultipleAccounts: "Se pueden crear múltiples cuentas según sea necesario, incluso cuando se opera como servidor unipersonal." + group: "Servidor de grupo" + group_description: "Invita otros usuarios de confianza y úsalo con más de una persona.\n" + open: "Servidor público" + open_description: "Permite a cualquiera registrarse" + openServerAdvice: "Aceptar un número no determinado de usuarios comporta algunos riesgos. Se recomienda operar con un sistema de moderación fiable para hacer frente a los problemas." + openServerAntiSpamAdvice: "Para evitar que su servidor se convierta en un trampolín para el spam, también debe prestar mucha atención a la seguridad habilitando funciones anti-bot como reCAPTCHA." + howManyUsersDoYouExpect: "¿Cuántas personas esperas?" + _scale: + small: "Menos de 100 (escala pequeña)" + medium: "Más de 100 y menos de 1000 (escala media)\n" + large: "Más de 1000(escala grande)" + largeScaleServerAdvice: "Los grandes servidores pueden requerir conocimientos avanzados de infraestructura, como equilibrio de carga y replicación de bases de datos." + doYouConnectToFediverse: "¿Quieres conectarte al Fediverso?" + doYouConnectToFediverse_description1: "Cuando se conecta a una red de servidores distribuidos (Fediverso), el contenido puede intercambiarse con otros servidores." + doYouConnectToFediverse_description2: "Conectarse con el Fediverso también se conoce como \"federación\"." + youCanConfigureMoreFederationSettingsLater: "Los ajustes avanzados, como la especificación de servidores federados, pueden configurarse más adelante." + remoteContentsCleaning: "Limpieza automática de los contenidos recibidos" + remoteContentsCleaning_description: "La federación puede dar lugar a un flujo continuo de contenido. Al habilitar la limpieza automática, se eliminará del servidor el contenido obsoleto y sin referencias para ahorrar espacio de almacenamiento." + adminInfo: "Información del administrador" + adminInfo_description: "Establece la información del administrador para recibir consultas." + adminInfo_mustBeFilled: "Esta información debe ser introducida en el caso de registros abiertos o la federación esté activada." + followingSettingsAreRecommended: "Se recomienda los siguientes ajustes" + applyTheseSettings: "Aplicar estos ajustes" + skipSettings: "Omitir configuración" + settingsCompleted: "¡Configuración inicial del servidor completada!" + settingsCompleted_description: "Gracias por tu tiempo. Ahora que está todo listo puedes empezar a utilizar el servidor inmediatamente." + settingsCompleted_description2: "La configuración avanzada del servidor pueden realizarse a través del \"Panel de control\"." + donationRequest: "Por favor Dona" + _donationRequest: + text1: "CherryPick es un software libre desarrollado por voluntarios." + text2: "Agradeceríamos su apoyo para que podamos seguir desarrollando este software en el futuro." + text3: "También hay beneficios especiales para los donantes" +_uploader: + editImage: "Editar la imagen" + compressedToX: "Comprimir a {x}" + savedXPercent: "Guardando {x}%" + abortConfirm: "Algunos archivos no se han cargado, ¿deseas cancelar?" + doneConfirm: "Algunos archivos no se han cargado, ¿deseas continuar de todos modos?" + maxFileSizeIsX: "El tamaño máximo de archivo que se puede cargar es de {x}" + allowedTypes: "Tipos de archivos que se pueden cargar." + tip: "El archivo aún no se ha cargado, por lo que este cuadro de diálogo te permite confirmar, renombrar, comprimir y recortar el archivo antes de cargarlo. Cuando esté listo, puedes iniciar la carga pulsando el botón \"Cargar\"." +_clientPerformanceIssueTip: + title: "Si crees que el consumo de batería es demasiado alto" + makeSureDisabledAdBlocker: "Por favor, desactiva el bloqueador de publicidad." + makeSureDisabledAdBlocker_description: "Los bloqueadores de anuncios pueden afectar al rendimiento. Asegúrate de que no están activados en tu sistema o en las funciones/extensiones de tu navegador." + makeSureDisabledCustomCss: "Desactiva el CSS personalizado" + makeSureDisabledCustomCss_description: "Anular estilos puede afectar al rendimiento. Asegúrate de que el CSS personalizado o las extensiones que sobrescriben estilos no están activados." + makeSureDisabledAddons: "Desactiva las extensiones " + makeSureDisabledAddons_description: "Algunas extensiones pueden interferir con el comportamiento del cliente y afectar al rendimiento. Por favor, deshabilita las extensiones de tu navegador y comprueba si esto mejora la situación." +_clip: + tip: "Clip es una función que permite organizar varias notas." +_userLists: + tip: "Las listas pueden contener cualquier usuario que especifiques al crearlas, la lista creada puede mostrarse entonces como una línea de tiempo mostrando solo los usuarios especificados." +watermark: "Marca de Agua" +defaultPreset: "Por defecto" +_watermarkEditor: + tip: "Se puede añadir a la imagen una marca de agua, como información crediticia." + quitWithoutSaveConfirm: "¿Descartar cambios no guardados?" + driveFileTypeWarn: "Este archivo es incompatible" + driveFileTypeWarnDescription: "Elegir una imagen" + title: "Editar la marca de agua" + cover: "Cubrir todo" + repeat: "Repetir" + preserveBoundingRect: "Ajuste para evitar que se desborde al rotar." + opacity: "Opacidad" + scale: "Tamaño" + text: "Texto" + qr: "Código QR" + position: "Posición" + margin: "Margen" + type: "Tipo" + image: "Imágenes" + advanced: "Avanzado" + angle: "Ángulo" + stripe: "Rayas" + stripeWidth: "Anchura de línea" + stripeFrequency: "Número de líneas." + polkadot: "Patrón de Lunares" + checker: "Patrón de Damas / Tablero de Ajedrez" + polkadotMainDotOpacity: "Opacidad del círculo principal" + polkadotMainDotRadius: "Tamaño del círculo principal." + polkadotSubDotOpacity: "Opacidad del círculo secundario" + polkadotSubDotRadius: "Tamaño del círculo secundario." + polkadotSubDotDivisions: "Número de subpuntos." + leaveBlankToAccountUrl: "Si dejas este campo en blanco, se utilizará la URL de tu cuenta." +_imageEffector: + title: "Efecto" + addEffect: "Añadir Efecto" + discardChangesConfirm: "¿Ignorar cambios y salir?" + nothingToConfigure: "No hay opciones configurables disponibles." + _fxs: + chromaticAberration: "Aberración Cromática" + glitch: "Glitch" + mirror: "Espejo" + invert: "Invertir colores" + grayscale: "Blanco y negro" + blur: "Difuminar" + pixelate: "Pixelar" + colorAdjust: "Corrección de Color" + colorClamp: "Ajuste de Tono" + colorClampAdvanced: "Ajuste de Tono avanzado" + distort: "Distorsión" + threshold: "Binarización" + zoomLines: "Líneas de Impacto" + stripe: "Rayas" + polkadot: "Patrón de Lunares" + checker: "Patrón de Damas / Tablero de Ajedrez" + blockNoise: "Ruido de Bloque" + tearing: "Rasgado de Imagen (Tearing)" + fill: "Relleno de color" + _fxProps: + angle: "Ángulo" + scale: "Tamaño" + size: "Tamaño" + radius: "Radio" + samples: "Tamaño de muestra" + offset: "Posición" + color: "Color" + opacity: "Opacidad" + normalize: "Normalización" + amount: "Cantidad" + lightness: "Brillo" + contrast: "Contraste" + hue: "Tonalidad" + brightness: "Luminancia" + saturation: "Saturación" + max: "Valor máximo" + min: "Valor mínimo" + direction: "Dirección" + phase: "Fase" + frequency: "Frecuencia" + strength: "Intensidad" + glitchChannelShift: "Desfase" + seed: "Valor de la semilla" + redComponent: "Canal Rojo" + greenComponent: "Canal Verde" + blueComponent: "Canal Azul" + threshold: "Umbral" + centerX: "Centrar X" + centerY: "Centrar Y" + zoomLinesSmoothing: "Suavizado" + zoomLinesSmoothingDescription: "El suavizado y el ancho de línea de zoom no se pueden utilizar juntos." + zoomLinesThreshold: "Ancho de línea del zoom" + zoomLinesMaskSize: "Diámetro del centro" + zoomLinesBlack: "Cambiar color de las líneas de impacto a negro." + circle: "Círculo" +drafts: "Borrador" +_drafts: + select: "Seleccionar borradores" + cannotCreateDraftAnymore: "Se ha superado el número de borradores que se pueden crear." + cannotCreateDraft: "No se pueden crear borradores con este contenido." + delete: "Eliminar borrador" + deleteAreYouSure: "¿Quieres borrar el borrador?" + noDrafts: "No hay borradores disponibles." + replyTo: "Responder a {user}" + quoteOf: "Citar las notas de {user}" + postTo: "Destino a {channel}" + saveToDraft: "Guardar como borrador" + restoreFromDraft: "Restaurar desde los borradores" + restore: "Restaurar" + listDrafts: "Listar los borradores" + schedule: "Programar Nota" + listScheduledNotes: "Lista de notas programadas" + cancelSchedule: "Cancelar programación" +qr: "Código QR" +_qr: + showTabTitle: "Apariencia" + readTabTitle: "Escanear" + shareTitle: "{name} {acct}" + shareText: "¡Sígueme en el Fediverso!" + chooseCamera: "Seleccione cámara" + cannotToggleFlash: "No se puede activar el flash" + turnOnFlash: "Encender el flash" + turnOffFlash: "Apagar el flash" + startQr: "Reiniciar el lector de códigos QR" + stopQr: "Detener el lector de códigos QR" + noQrCodeFound: "No se encontró el código QR" + scanFile: "Escanear imagen desde un dispositivo" + raw: "Texto" + mfm: "MFC" diff --git a/locales/fr-FR.yml b/locales/fr-FR.yml index f2730d89fa..812b62b22d 100644 --- a/locales/fr-FR.yml +++ b/locales/fr-FR.yml @@ -238,7 +238,6 @@ noUsers: "Il n’y a pas d’utilisateur·rice·s" editProfile: "Modifier votre profil" noteDeleteConfirm: "Êtes-vous sûr·e de vouloir supprimer cette note ?" pinLimitExceeded: "Vous ne pouvez plus épingler d’autres notes." -intro: "L’installation de CherryPick est terminée ! Veuillez créer un compte administrateur." done: "Terminé" processing: "Traitement en cours" preview: "Aperçu" @@ -1221,9 +1220,7 @@ showAvatarDecorations: "Afficher les décorations d'avatar" releaseToRefresh: "Relâcher pour rafraîchir" refreshing: "Rafraîchissement..." pullDownToRefresh: "Tirer vers le bas pour rafraîchir" -disableStreamingTimeline: "Désactiver les mises à jour en temps réel de la ligne du temps" useGroupedNotifications: "Grouper les notifications" -signupPendingError: "Un problème est survenu lors de la vérification de votre adresse e-mail. Le lien a peut-être expiré." cwNotationRequired: "Si « Masquer le contenu » est activé, une description doit être fournie." doReaction: "Réagir" code: "Code" @@ -1287,6 +1284,9 @@ pleaseSelectAccount: "Sélectionner un compte" availableRoles: "Rôles disponibles" postForm: "Formulaire de publication" information: "Informations" +inMinutes: "min" +inDays: "j" +widgets: "Widgets" _chat: invitations: "Inviter" noHistory: "Pas d'historique" @@ -1917,7 +1917,6 @@ _theme: buttonBg: "Arrière-plan du bouton" buttonHoverBg: "Arrière-plan du bouton (survolé)" inputBorder: "Cadre de la zone de texte" - driveFolderBg: "Arrière-plan du dossier de disque" badge: "Badge" messageBg: "Arrière plan de la discussion" fgHighlighted: "Texte mis en évidence" @@ -2420,9 +2419,6 @@ _dataSaver: _avatar: title: "Animation d'avatars" description: "Arrête l'animation d'avatars. Comme les images animées peuvent être plus volumineuses que les images normales, cela permet de réduire davantage le trafic de données." - _urlPreview: - title: "Vignettes d'aperçu des URL" - description: "Les vignettes d'aperçu des URL ne seront plus chargées." _code: title: "Mise en évidence du code" description: "Si la notation de mise en évidence du code est utilisée, par exemple dans la MFC, elle ne sera pas chargée tant qu'elle n'aura pas été tapée. La mise en évidence du code nécessite le chargement du fichier de définition de chaque langue à mettre en évidence, mais comme ces fichiers ne sont plus chargés automatiquement, on peut s'attendre à une réduction du trafic de données." @@ -2451,3 +2447,25 @@ _search: searchScopeAll: "Tous" searchScopeLocal: "Local" searchScopeUser: "Spécifier l'utilisateur·rice" +_watermarkEditor: + driveFileTypeWarn: "Ce fichier n'est pas pris en charge" + opacity: "Transparence" + scale: "Taille" + text: "Texte" + position: "Position" + type: "Type" + image: "Images" + advanced: "Avancé" + angle: "Angle" +_imageEffector: + _fxProps: + angle: "Angle" + scale: "Taille" + size: "Taille" + offset: "Position" + color: "Couleur" + opacity: "Transparence" + lightness: "Clair" +_qr: + showTabTitle: "Affichage" + raw: "Texte" diff --git a/locales/generateDTS.js b/locales/generateDTS.js index 49807144ec..ab0613cc82 100644 --- a/locales/generateDTS.js +++ b/locales/generateDTS.js @@ -73,7 +73,7 @@ export default function generateDTS() { ts.NodeFlags.Const, ), ), - ts.factory.createInterfaceDeclaration( + ts.factory.createTypeAliasDeclaration( [ts.factory.createToken(ts.SyntaxKind.ExportKeyword)], ts.factory.createIdentifier('ParameterizedString'), [ @@ -84,20 +84,22 @@ export default function generateDTS() { ts.factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword), ), ], - undefined, - [ - ts.factory.createPropertySignature( - undefined, - ts.factory.createComputedPropertyName( - ts.factory.createIdentifier('kParameters'), - ), - undefined, - ts.factory.createTypeReferenceNode( - ts.factory.createIdentifier('T'), + ts.factory.createIntersectionTypeNode([ + ts.factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword), + ts.factory.createTypeLiteralNode([ + ts.factory.createPropertySignature( undefined, + ts.factory.createComputedPropertyName( + ts.factory.createIdentifier('kParameters'), + ), + undefined, + ts.factory.createTypeReferenceNode( + ts.factory.createIdentifier('T'), + undefined, + ), ), - ), - ], + ]) + ]), ), ts.factory.createInterfaceDeclaration( [ts.factory.createToken(ts.SyntaxKind.ExportKeyword)], diff --git a/locales/id-ID.yml b/locales/id-ID.yml index 6de4c7544b..9183601c8e 100644 --- a/locales/id-ID.yml +++ b/locales/id-ID.yml @@ -5,9 +5,13 @@ introMisskey: "Selamat datang! CherryPick adalah perangkat mikroblog tercatu ber poweredByMisskeyDescription: "{name} adalah sebuah layanan (instance) yang menggunakan platform sumber terbuka CherryPick." monthAndDay: "{day} {month}" search: "Penelusuran" +reset: "Reset" notifications: "Notifikasi" username: "Nama Pengguna" password: "Kata sandi" +initialPasswordForSetup: "Kata sandi untuk memulai konfigurasi awal" +initialPasswordIsIncorrect: "Kata sandi untuk memulai konfigurasi awal salah." +initialPasswordForSetupDescription: "Jika Anda menginstal CherryPick sendiri, gunakan kata sandi yang Anda masukkan di berkas konfigurasi.\nJika Anda menggunakan layanan hosting CherryPick, gunakan kata sandi yang diberikan.\nJika Anda belum mengatur kata sandi, biarkan kosong dan lanjutkan." forgotPassword: "Lupa Kata Sandi" fetchingAsApObject: "Mengambil data dari Fediverse..." ok: "OK" @@ -45,6 +49,7 @@ pin: "Sematkan ke profil" unpin: "Lepas sematan dari profil" copyContent: "Salin konten" copyLink: "Salin tautan" +copyRemoteLink: "Salin tautan jarak jauh" copyLinkRenote: "Salin tautan renote" delete: "Hapus" deleteAndEdit: "Hapus dan sunting" @@ -212,8 +217,10 @@ perDay: "per Hari" stopActivityDelivery: "Berhenti mengirim aktivitas" blockThisInstance: "Blokir instansi ini" silenceThisInstance: "Senyapkan instansi ini" +mediaSilenceThisInstance: "Server media senyap" operations: "Tindakan" software: "Perangkat lunak" +softwareName: "Nama Perangkat Lunak" version: "Versi" metadata: "Metadata" withNFiles: "{n} berkas" @@ -241,7 +248,6 @@ noUsers: "Tidak ada pengguna" editProfile: "Sunting profil" noteDeleteConfirm: "Apakah kamu yakin ingin menghapus catatan ini?" pinLimitExceeded: "Kamu tidak dapat menyematkan catatan lagi" -intro: "Instalasi CherryPick telah selesai! Mohon untuk membuat pengguna admin." done: "Selesai" processing: "Memproses" preview: "Pratinjau" @@ -292,6 +298,7 @@ uploadFromUrlMayTakeTime: "Membutuhkan beberapa waktu hingga pengunggahan selesa explore: "Jelajahi" messageRead: "Telah dibaca" noMoreHistory: "Tidak ada sejarah lagi" +startChat: "Kirim pesan" nUsersRead: "Dibaca oleh {n}" agreeTo: "Saya setuju kepada {0}" agree: "Setuju" @@ -512,6 +519,7 @@ emojiStyle: "Gaya emoji" native: "Native" menuStyle: "Gaya menu" style: "Gaya" +popup: "Pemunculan" youHaveNoGroups: "Kamu tidak memiliki grup" joinOrCreateGroup: "Bergabunglah dengan grup atau kamu dapat membuat grupmu sendiri." showNoteActionsOnlyHover: "Hanya tampilkan aksi catatan saat ditunjuk" @@ -570,6 +578,7 @@ showFixedPostForm: "Tampilkan form posting di atas lini masa" showFixedPostFormInChannel: "Tampilkan form posting di atas lini masa (Kanal)" withRepliesByDefaultForNewlyFollowed: "Termasuk balasan dari pengguna baru yang diikuti pada lini masa secara bawaan" newNoteRecived: "Kamu mendapat catatan baru" +newNote: "Catatan baru" sounds: "Bunyi" sound: "Bunyi" listen: "Dengarkan" @@ -1035,6 +1044,7 @@ permissionDeniedError: "Operasi ditolak" permissionDeniedErrorDescription: "Akun ini tidak memiliki izin untuk melakukan aksi ini." preset: "Prasetel" selectFromPresets: "Pilih dari prasetel" +custom: "Penyesuaian" achievements: "Pencapaian" gotInvalidResponseError: "Respon peladen tidak valid" gotInvalidResponseErrorDescription: "Peladen tidak dapat dijangkau atau sedang dalam perawatan. Mohon coba lagi nanti." @@ -1054,7 +1064,7 @@ disableFederationConfirmWarn: "Mematikan federasi tidak membuat kiriman menjadi disableFederationOk: "Matikan federasi" invitationRequiredToRegister: "Instansi ini dalam mode undangan-saja. Kamu harus memasukkan kode undangan yang valid untuk mendaftar." emailNotSupported: "Instansi ini tidak mendukung mengirim surel" -postToTheChannel: "Catat ke kanal" +postToTheChannel: "Buat Catatan ke Kanal" cannotBeChangedLater: "Hal ini nantinya tidak dapat diubah lagi." reactionAcceptance: "Penerimaan reaksi" likeOnly: "Hanya suka" @@ -1117,6 +1127,7 @@ preservedUsernamesDescription: "Daftar nama pengguna yang dicadangkan dipisah de createNoteFromTheFile: "Buat catatan dari berkas ini" archive: "Arsipkan" archived: "Diarsipkan" +unarchive: "Batalkan pengarsipan" channelArchiveConfirmTitle: "Yakin untuk mengarsipkan {name}?" channelArchiveConfirmDescription: "Kanal yang diarsipkan tidak akan muncul pada daftar kanal atau hasil pencarian. Postingan baru juga tidak dapat ditambahkan lagi." thisChannelArchived: "Kanal ini telah diarsipkan." @@ -1218,9 +1229,7 @@ showAvatarDecorations: "Tampilkan dekorasi avatar" releaseToRefresh: "Lepaskan untuk memuat ulang" refreshing: "Sedang memuat ulang..." pullDownToRefresh: "Tarik ke bawah untuk memuat ulang" -disableStreamingTimeline: "Nonaktifkan pembaharuan lini masa real-time" useGroupedNotifications: "Tampilkan notifikasi secara dikelompokkan" -signupPendingError: "Terdapat masalah ketika memverifikasi alamat surel. Tautan kemungkinan telah kedaluwarsa." cwNotationRequired: "Jika \"Sembunyikan konten\" diaktifkan, deskripsi harus disediakan." doReaction: "Tambahkan reaksi" code: "Kode" @@ -1260,6 +1269,7 @@ noDescription: "Tidak ada deskripsi" alwaysConfirmFollow: "Selalu konfirmasi ketika mengikuti" inquiry: "Hubungi kami" tryAgain: "Silahkan coba lagi." +sensitiveMediaRevealConfirm: "Media sensitif. Apakah ingin melihat?" createdLists: "Senarai yang dibuat" createdAntennas: "Antena yang dibuat" fromX: "Dari {x}" @@ -1267,18 +1277,43 @@ noteOfThisUser: "Catatan oleh pengguna ini" clipNoteLimitExceeded: "Klip ini tak bisa ditambahi lagi catatan." performance: "Kinerja" modified: "Diubah" +discard: "Buang" thereAreNChanges: "Ada {n} perubahan" +signinWithPasskey: "Masuk dengan kunci sandi" +unknownWebAuthnKey: "Kunci sandi tidak terdaftar." +passkeyVerificationFailed: "Verifikasi kunci sandi gagal." +passkeyVerificationSucceededButPasswordlessLoginDisabled: "Verifikasi kunci sandi berhasil, namun pemasukan tanpa sandi dinonaktifkan." +messageToFollower: "Pesan kepada pengikut" prohibitedWordsForNameOfUser: "Kata yang dilarang untuk nama pengguna" +lockdown: "Kuncitara" +noName: "Tidak ada nama" +skip: "Lewati" +paste: "Tempel" +emojiPalette: "Palet emoji" postForm: "Buat catatan" information: "Informasi" +chat: "Obrolan" +directMessage: "Obrolan pengguna" +right: "Kanan" +bottom: "Bawah" +top: "Atas" +advice: "Saran" +inMinutes: "menit" +inDays: "hari" +widgets: "Widget" _chat: invitations: "Undang" + history: "Riwayat obrolan" noHistory: "Tidak ada riwayat" members: "Anggota" home: "Beranda" send: "Kirim" + chatWithThisUser: "Obrolan pengguna" _settings: webhook: "Webhook" + contentsUpdateFrequency: "Frekuensi pembaruan konten" +_preferencesProfile: + profileName: "Nama profil" _abuseUserReport: accept: "Setuju" reject: "Tolak" @@ -2031,7 +2066,6 @@ _theme: buttonBg: "Latar belakang tombol" buttonHoverBg: "Latar belakang tombol (Mengambang)" inputBorder: "Batas bidang masukan" - driveFolderBg: "Latar belakang folder drive" badge: "Lencana" messageBg: "Latar belakang obrolan" fgHighlighted: "Teks yang disorot" @@ -2040,6 +2074,7 @@ _sfx: noteMy: "Catatan (Saya)" notification: "Notifikasi" reaction: "Ketika memilih reaksi" + chatMessage: "Obrolan pengguna" _soundSettings: driveFile: "Menggunakan berkas audio dalam Drive" driveFileWarn: "Pilih berkas audio dari Drive" @@ -2243,6 +2278,7 @@ _widgets: chooseList: "Pilih daftar" clicker: "Pengeklik" birthdayFollowings: "Pengguna yang merayakan hari ulang tahunnya hari ini" + chat: "Obrolan pengguna" _cw: hide: "Sembunyikan" show: "Lihat konten" @@ -2487,13 +2523,14 @@ _deck: main: "Utama" widgets: "Widget" notifications: "Notifikasi" - tl: "Lini masa" + tl: "Beranda" antenna: "Antena" list: "Daftar" channel: "Kanal" mentions: "Sebutan" direct: "Langsung" roleTimeline: "Lini masa peran" + chat: "Obrolan pengguna" _dialog: charactersExceeded: "Kamu telah melebihi batas karakter maksimum! Saat ini pada {current} dari {max}." charactersBelow: "Kamu berada di bawah batas minimum karakter! Saat ini pada {current} dari {min}." @@ -2616,9 +2653,6 @@ _dataSaver: _avatar: title: "Gambar avatar" description: "Hentikan animasi gambar avatar. Gambar animasi dapat berukuran lebih besar dari gambar biasa, berpotensi pada pengurangan lalu lintas data lebih jauh." - _urlPreview: - title: "Gambar kecil URL pratinjau" - description: "Gambar kecil URL pratinjau tidak akan dimuat lagi." _code: title: "Penyorotan kode" description: "Jika notasi penyorotan kode digunakan di MFC, dll. Fungsi tersebut tidak akan dimuat apabila tidak diketuk. Penyorotan sintaks membutuhkan pengunduhan berkas definisi penyorotan untuk setiap bahasa pemrograman. Oleh sebab itu, menonaktifkan pemuatan otomatis dari berkas ini dilakukan untuk mengurangi jumlah komunikasi data." @@ -2698,3 +2732,25 @@ _search: searchScopeAll: "Semua" searchScopeLocal: "Lokal" searchScopeUser: "Pengguna spesifik" +_watermarkEditor: + driveFileTypeWarn: "Berkas ini tidak didukung" + opacity: "Opasitas" + scale: "Ukuran" + text: "Teks" + position: "Posisi" + type: "Tipe" + image: "Gambar" + advanced: "Tingkat lanjut" + angle: "Sudut" +_imageEffector: + _fxProps: + angle: "Sudut" + scale: "Ukuran" + size: "Ukuran" + offset: "Posisi" + color: "Warna" + opacity: "Opasitas" + lightness: "Menerangkan" +_qr: + showTabTitle: "Tampilkan" + raw: "Teks" diff --git a/locales/index.d.ts b/locales/index.d.ts index 197eea2f5e..79fabe94d2 100644 --- a/locales/index.d.ts +++ b/locales/index.d.ts @@ -2,9 +2,9 @@ // This file is generated by locales/generateDTS.js // Do not edit this file directly. declare const kParameters: unique symbol; -export interface ParameterizedString { +export type ParameterizedString = string & { [kParameters]: T; -} +}; export interface ILocale { [_: string]: string | ParameterizedString | ILocale; } @@ -13,6 +13,70 @@ export interface Locale extends ILocale { * 日本語 */ "_lang_": string; + /** + * 内容比較 + */ + "compareContent": string; + /** + * 修正履歴 + */ + "editHistory": string; + /** + * 全リノート解除 + */ + "unRenoteAll": string; + /** + * 全リノート解除 + */ + "unRenoteAllConfirm": string; + /** + * このノートのすべてのリノットを削除しようとしています。実行しますか? + */ + "unRenoteAllConfirmDescription": string; + /** + * 既にリノートしました + */ + "alreadyRenotedConfirm": string; + /** + * このノートは既にリノートしました。もう一度リノートしますか? + */ + "alreadyRenotedConfirmDescription": string; + /** + * Mastodonなど、一部のソフトウェアは最初のリノートのみを処理するため、それ以降のリノートは表示されないことがあります。 + */ + "alreadyRenotedConfirmCaption": string; + /** + * ノート自動削除 + */ + "autoDeleteNotes": string; + /** + * 指定した期間が経過したノートを自動的に削除します。 + */ + "autoDeleteNotesDescription": string; + /** + * 自動削除期間 + */ + "autoDeleteNotesAfterDays": string; + /** + * この期間が経過したノートが自動的に削除されます。無効にするには空欄にしてください。 + */ + "autoDeleteNotesAfterDaysDescription": string; + /** + * お気に入りのノートを保護 + */ + "autoDeleteKeepFavorites": string; + /** + * お気に入りに追加したノートは自動削除されません。 + */ + "autoDeleteKeepFavoritesDescription": string; + /** + * この操作は取り消せません。削除されたノートは復元できません。 + */ + "autoDeleteNotesWarning": string; + /** + * {x}に削除が予約されています + */ + "scheduledToDeleteOnX": ParameterizedString<"x">; /** * ノートの本文を離して表示 */ @@ -86,17 +150,9 @@ export interface Locale extends ILocale { */ "youBlocked": string; /** - * {user}さんのフォローやノートの表示はできません。 + * {user}さんのフォローやポストの表示はできません。 */ "youBlockedDescription": ParameterizedString<"user">; - /** - * 予約投稿 - */ - "schedulePost": string; - /** - * 予約投稿一覧 - */ - "schedulePostList": string; /** * {n}個の投稿が予約されたノートがあります。 */ @@ -140,10 +196,6 @@ export interface Locale extends ILocale { * 有効にすると、再利用できるときに{name}を適用します。 */ "cantUseThisFunctionCaption": ParameterizedString<"name">; - /** - * ウィジェット - */ - "widgets": string; /** * ノートを作成 */ @@ -846,7 +898,7 @@ export interface Locale extends ILocale { */ "mention": string; /** - * あなた宛て + * メンション */ "mentions": string; /** @@ -854,7 +906,7 @@ export interface Locale extends ILocale { */ "newNotes": string; /** - * ダイレクト投稿 + * 指名 */ "directNotes": string; /** @@ -1259,7 +1311,7 @@ export interface Locale extends ILocale { */ "cacheRemoteFiles": string; /** - * この設定を有効にすると、リモートファイルをこのサーバーのストレージにキャッシュするようになります。画像の表示が高速になりますが、サーバーのストレージを多く消費します。リモートユーザーがどれほどキャッシュを保持するかは、ロールによるドライブ容量制限によって決定されます。この制限を超えた場合、古いファイルからキャッシュが削除されリンクになります。この設定が無効の場合、リモートのファイルを最初からリンクとして保持しますが、画像のサムネイル生成やユーザーのプライバシー保護のために、default.ymlでproxyRemoteFilesをtrueにすることをお勧めします。 + * この設定を有効にすると、リモートファイルをこのサーバーのストレージにキャッシュするようになります。画像の表示が高速になりますが、サーバーのストレージを多く消費します。リモートユーザーがどれほどキャッシュを保持するかは、ロールによるドライブ容量制限によって決定されます。この制限を超えた場合、古いファイルからキャッシュが削除されリンクになります。この設定が無効の場合、リモートのファイルを最初からリンクとして保持します。 */ "cacheRemoteFilesDescription": string; /** @@ -1299,7 +1351,7 @@ export interface Locale extends ILocale { */ "flagShowTimelineRepliesDescription": string; /** - * フォロー中ユーザーからのフォロリクを自動承認 + * フォロー中ユーザーからのフォロー申請を自動承認 */ "autoAcceptFollowed": string; /** @@ -1583,10 +1635,6 @@ export interface Locale extends ILocale { * これ以上ピン留めできません */ "pinLimitExceeded": string; - /** - * CherryPickのインストールが完了しました!管理者アカウントを作成しましょう。 - */ - "intro": string; /** * 完了 */ @@ -1595,6 +1643,10 @@ export interface Locale extends ILocale { * 処理中 */ "processing": string; + /** + * 準備中 + */ + "preprocessing": string; /** * プレビュー */ @@ -1775,6 +1827,10 @@ export interface Locale extends ILocale { * アップロードが完了するまで時間がかかる場合があります。 */ "uploadFromUrlMayTakeTime": string; + /** + * {n}個のファイルをアップロード + */ + "uploadNFiles": ParameterizedString<"n">; /** * みつける */ @@ -1788,7 +1844,7 @@ export interface Locale extends ILocale { */ "noMoreHistory": string; /** - * チャットを始める + * メッセージを送る */ "startChat": string; /** @@ -1891,6 +1947,10 @@ export interface Locale extends ILocale { * デバイスのダークモードと同期する */ "syncDeviceDarkMode": string; + /** + * 「{x}」がオンになっています。同期をオフにして手動でモードを切り替えますか? + */ + "switchDarkModeManuallyWhenSyncEnabledConfirm": ParameterizedString<"x">; /** * ドライブ */ @@ -1911,6 +1971,10 @@ export interface Locale extends ILocale { * フォルダーを選択 */ "selectFolder": string; + /** + * フォルダーの選択を解除 + */ + "unselectFolder": string; /** * フォルダーを選択 */ @@ -1959,6 +2023,10 @@ export interface Locale extends ILocale { * フォルダーは空です */ "emptyFolder": string; + /** + * ここにファイルをドロップしてアップロード + */ + "dropHereToUpload": string; /** * 削除できません */ @@ -2488,7 +2556,7 @@ export interface Locale extends ILocale { */ "markAsReadAllUnreadNotes": string; /** - * すべてのチャットを既読にする + * すべてのダイレクトメッセージを既読にする */ "markAsReadAllTalkMessages": string; /** @@ -2947,6 +3015,10 @@ export interface Locale extends ILocale { * {n}個の新しいノートがあります */ "newNoteRecivedCount": ParameterizedString<"n">; + /** + * 新しいノート + */ + "newNote": string; /** * サウンド */ @@ -2956,25 +3028,9 @@ export interface Locale extends ILocale { */ "sound": string; /** - * 振動 - */ - "vibrations": string; - /** - * サウンドと振動 - */ - "soundsAndVibrations": string; - /** - * 振動再生 - */ - "playVibrations": string; - /** - * この機能はiOS/iPadOSではサポートされていません。 + * 通知音の設定 */ - "playVibrationsDescription": string; - /** - * 振動再生テスト - */ - "testVibrations": string; + "notificationSoundSettings": string; /** * 聴く */ @@ -3200,11 +3256,11 @@ export interface Locale extends ILocale { */ "serviceworkerInfo": string; /** - * 削除された投稿 + * 削除されたノート */ "deletedNote": string; /** - * 非公開の投稿 + * 非公開のノート */ "invisibleNote": string; /** @@ -3743,6 +3799,10 @@ export interface Locale extends ILocale { * 無効にすると、動く画像が再生されます。光敏感性発作を起こすことがありますので、ご注意ください。 */ "disableShowingAnimatedImagesDescription": string; + /** + * この設定に関わらずアニメーション画像が再生されないときは、ブラウザ・OSのアクセシビリティ設定や省電力設定等が干渉している場合があります。 + */ + "disableShowingAnimatedImages_caption": string; /** * メディアがセンシティブであることを分かりやすく表示 */ @@ -3844,6 +3904,10 @@ export interface Locale extends ILocale { * 反映には再起動が必要です。 */ "needReloadToApply": string; + /** + * 反映にはサーバーの再起動が必要です。 + */ + "needToRestartServerToApply": string; /** * タイトルバーを表示する */ @@ -3941,11 +4005,11 @@ export interface Locale extends ILocale { */ "latestVersion": string; /** - * お使いのクライアントは最新です。 + * CherryPickは最新です。 */ "youAreRunningUpToDateClient": string; /** - * 新しいバージョンのクライアントが利用可能です。 + * 新しいバージョンのCherryPickが利用可能です。 */ "newVersionOfClientAvailable": string; /** @@ -4680,6 +4744,10 @@ export interface Locale extends ILocale { * ファイルサイズの制限を超えているためアップロードできません。 */ "cannotUploadBecauseExceedsFileSizeLimit": string; + /** + * 許可されていないファイル種別のためアップロードできません。 + */ + "cannotUploadBecauseUnallowedFileType": string; /** * ベータ */ @@ -4884,6 +4952,10 @@ export interface Locale extends ILocale { * プリセットから選択 */ "selectFromPresets": string; + /** + * カスタム + */ + "custom": string; /** * 実績 */ @@ -5052,6 +5124,10 @@ export interface Locale extends ILocale { * ノート検索は利用できません。 */ "notesSearchNotAvailable": string; + /** + * ユーザー検索は利用できません。 + */ + "usersSearchNotAvailable": string; /** * ライセンス */ @@ -5360,6 +5436,10 @@ export interface Locale extends ILocale { * ユーザーごとのIdenticon生成を有効にする */ "enableIdenticonGeneration": string; + /** + * リモートユーザーに付与したロールバッジを表示する + */ + "showRoleBadgesOfRemoteUsers": string; /** * オフにするとパフォーマンスが向上します。 */ @@ -5684,10 +5764,6 @@ export interface Locale extends ILocale { * 引っ張ってリロード */ "pullDownToRefresh": string; - /** - * タイムラインのリアルタイム更新を無効にする - */ - "disableStreamingTimeline": string; /** * 通知をグルーピング */ @@ -5695,7 +5771,7 @@ export interface Locale extends ILocale { /** * メールアドレスの確認中に問題が発生しました。リンクの有効期限が切れている可能性があります。 */ - "signupPendingError": string; + "emailVerificationFailedError": string; /** * 「内容を隠す」がオンの場合は注釈の記述が必要です。 */ @@ -5945,7 +6021,7 @@ export interface Locale extends ILocale { */ "prohibitedWordsForNameOfUser": string; /** - * このリストに含まれる文字列がユーザーの名前に含まれる場合、ユーザーの名前の変更を拒否します。モデレーター権限を持つユーザーはこの制限の影響を受けません。 + * このリストに含まれる文字列がユーザーの名前に含まれる場合、ユーザーの名前の変更を拒否します。モデレーター権限を持つユーザーはこの制限の影響を受けません。ユーザー名(username)に対しても全て小文字に置き換えて検査します。 */ "prohibitedWordsForNameOfUserDescription": string; /** @@ -5984,6 +6060,14 @@ export interface Locale extends ILocale { * このサーバーは連合が無効化されています。他のサーバーのユーザーとやり取りすることはできません。 */ "federationDisabled": string; + /** + * 下書き + */ + "draft": string; + /** + * 下書きと予約投稿 + */ + "draftsAndScheduledNotes": string; /** * リアクションする際に確認する */ @@ -6049,15 +6133,19 @@ export interface Locale extends ILocale { */ "preferenceSyncConflictTitle": string; /** - * 同期が有効にされた設定項目は設定値をサーバーに保存しますが、この設定項目のサーバーに保存された設定値が見つかりました。どちらの設定値で上書きしますか? + * 同期が有効にされた設定項目は設定値をサーバーに保存しますが、この設定項目のサーバーに保存された設定値が見つかりました。どうしますか? */ "preferenceSyncConflictText": string; /** - * サーバーの設定値 + * 統合する + */ + "preferenceSyncConflictChoiceMerge": string; + /** + * サーバーの設定値で上書き */ "preferenceSyncConflictChoiceServer": string; /** - * デバイスの設定値 + * デバイスの設定値で上書き */ "preferenceSyncConflictChoiceDevice": string; /** @@ -6088,6 +6176,14 @@ export interface Locale extends ILocale { * チャット */ "chat": string; + /** + * ダイレクトメッセージ + */ + "directMessage": string; + /** + * メッセージ + */ + "directMessage_short": string; /** * 旧設定情報を移行 */ @@ -6144,9 +6240,133 @@ export interface Locale extends ILocale { */ "scrollToClose": string; /** - * 下書き + * アドバイス */ - "draft": string; + "advice": string; + /** + * リアルタイムモード + */ + "realtimeMode": string; + /** + * オンにする + */ + "turnItOn": string; + /** + * オフにする + */ + "turnItOff": string; + /** + * 絵文字ミュート + */ + "emojiMute": string; + /** + * 絵文字ミュート解除 + */ + "emojiUnmute": string; + /** + * {x}をミュート + */ + "muteX": ParameterizedString<"x">; + /** + * {x}のミュートを解除 + */ + "unmuteX": ParameterizedString<"x">; + /** + * 中止 + */ + "abort": string; + /** + * ヒントとコツ + */ + "tip": string; + /** + * 全ての「ヒントとコツ」を再表示 + */ + "redisplayAllTips": string; + /** + * 全ての「ヒントとコツ」を非表示 + */ + "hideAllTips": string; + /** + * デフォルトの画像圧縮度 + */ + "defaultImageCompressionLevel": string; + /** + * 低くすると画質を保てますが、ファイルサイズは増加します。
高くするとファイルサイズを減らせますが、画質は低下します。 + */ + "defaultImageCompressionLevel_description": string; + /** + * デフォルトの圧縮度 + */ + "defaultCompressionLevel": string; + /** + * 低くすると品質を保てますが、ファイルサイズは増加します。
高くするとファイルサイズを減らせますが、品質は低下します。 + */ + "defaultCompressionLevel_description": string; + /** + * 分 + */ + "inMinutes": string; + /** + * 日 + */ + "inDays": string; + /** + * セーフモードが有効です + */ + "safeModeEnabled": string; + /** + * セーフモードが有効なため、プラグインはすべて無効化されています。 + */ + "pluginsAreDisabledBecauseSafeMode": string; + /** + * セーフモードが有効なため、カスタムCSSは適用されていません。 + */ + "customCssIsDisabledBecauseSafeMode": string; + /** + * セーフモードが有効な間はデフォルトのテーマが使用されます。セーフモードをオフにすると元に戻ります。 + */ + "themeIsDefaultBecauseSafeMode": string; + /** + * ベータ版の検証にご協力いただきありがとうございます! + */ + "thankYouForTestingBeta": string; + /** + * ユーザー指定ノートを作成 + */ + "createUserSpecifiedNote": string; + /** + * 投稿を予約 + */ + "schedulePost": string; + /** + * {x}に投稿を予約します + */ + "scheduleToPostOnX": ParameterizedString<"x">; + /** + * {x}に投稿が予約されています + */ + "scheduledToPostOnX": ParameterizedString<"x">; + /** + * 予約 + */ + "schedule": string; + /** + * 予約 + */ + "scheduled": string; + /** + * ウィジェット + */ + "widgets": string; + /** + * デバイス情報 + */ + "deviceInfo": string; + /** + * 技術的なお問い合わせの際に、以下の情報を併記すると問題の解決に役立つことがあります。 + */ + "deviceInfoDescription": string; /** * 下書き一覧 */ @@ -6201,24 +6421,6 @@ export interface Locale extends ILocale { */ "doubleClick": string; }; - "_vibrations": { - /** - * 要素をクリックしたとき - */ - "click": string; - /** - * タイムラインに新しいノートがあるとき - */ - "note": string; - /** - * 通知を受け取ったとき - */ - "notification": string; - /** - * システムの触覚 - */ - "system": string; - }; "_showingAnimatedImages": { /** * 常に再生 @@ -6233,7 +6435,51 @@ export interface Locale extends ILocale { */ "inactive": string; }; + "_compression": { + "_quality": { + /** + * 高品質 + */ + "high": string; + /** + * 中品質 + */ + "medium": string; + /** + * 低品質 + */ + "low": string; + }; + "_size": { + /** + * サイズ大 + */ + "large": string; + /** + * サイズ中 + */ + "medium": string; + /** + * サイズ小 + */ + "small": string; + }; + }; + "_order": { + /** + * 新しい順 + */ + "newest": string; + /** + * 古い順 + */ + "oldest": string; + }; "_chat": { + /** + * メッセージ + */ + "messages": string; /** * まだメッセージはありません */ @@ -6243,36 +6489,36 @@ export interface Locale extends ILocale { */ "newMessage": string; /** - * 個人チャット + * 個別 */ "individualChat": string; /** - * 特定ユーザーとの一対一のチャットができます。 + * 特定ユーザーと個別にメッセージのやりとりができます。 */ "individualChat_description": string; /** - * ルームチャット + * グループ */ "roomChat": string; /** - * 複数人でのチャットができます。 - * また、個人チャットを許可していないユーザーとでも、相手が受け入れればチャットができます。 + * 複数人でメッセージのやりとりができます。 + * また、個別のメッセージを許可していないユーザーとでも、相手が受け入れればやりとりできます。 */ "roomChat_description": string; /** - * ルームを作成 + * グループを作成 */ "createRoom": string; /** - * ユーザーを招待してチャットを始めましょう + * ユーザーを招待してメッセージを送信しましょう */ "inviteUserToChat": string; /** - * 作成したルーム + * 作成したグループ */ "yourRooms": string; /** - * 参加中のルーム + * 参加中のグループ */ "joiningRooms": string; /** @@ -6292,7 +6538,7 @@ export interface Locale extends ILocale { */ "noHistory": string; /** - * ルームはありません + * グループはありません */ "noRooms": string; /** @@ -6307,12 +6553,16 @@ export interface Locale extends ILocale { * 参加 */ "join": string; + /** + * 拒否 + */ + "reject": string; /** * 無視 */ "ignore": string; /** - * ルームから退出 + * グループから退出 */ "leave": string; /** @@ -6335,6 +6585,14 @@ export interface Locale extends ILocale { * 改行 */ "newline": string; + /** + * あなたはこのグループの参加者ではありませんが、招待が届いています。参加するには、招待を承認してください。 + */ + "youAreNotAMemberOfThisRoomButInvited": string; + /** + * 招待を承認しますか? + */ + "doYouAcceptInvitation": string; /** * このルームをミュート */ @@ -6388,7 +6646,7 @@ export interface Locale extends ILocale { */ "chatAllowedUsers": string; /** - * 自分からチャットメッセージを送った相手とはこの設定に関わらずチャットが可能です。 + * 自分からダイレクトメッセージを送った相手とはこの設定に関わらずチャットが可能です。 */ "chatAllowedUsers_note": string; /** @@ -6441,6 +6699,22 @@ export interface Locale extends ILocale { */ "none": string; }; + /** + * {n}人が参加中 + */ + "usersCount": ParameterizedString<"n">; + /** + * {x}さんに送信された招待をキャンセルしますか? + */ + "invitationCancelAreYouSure": ParameterizedString<"x">; + /** + * この招待を無視すると、グループの管理者が招待を取り消して再度招待したり、グループを削除して再作成した場合にのみ招待されることができます。 + */ + "ignoreThisInvitation": string; + /** + * 招待を無視しますか? + */ + "doYouIgnoreInvitation": string; }; "_emojiPalette": { /** @@ -6545,6 +6819,14 @@ export interface Locale extends ILocale { * アイコンをスクロールに追従させる */ "useStickyIcons": string; + /** + * 高品質な画像のプレースホルダを表示 + */ + "enableHighQualityImagePlaceholders": string; + /** + * UIのアニメーション + */ + "uiAnimations": string; /** * ナビゲーションバーに副ボタンを表示 */ @@ -6569,6 +6851,42 @@ export interface Locale extends ILocale { * マウスでは、ホイールを押し込みながらドラッグします。 */ "enablePullToRefresh_description": string; + /** + * サーバーと接続を確立し、リアルタイムでコンテンツを更新します。通信量とバッテリーの消費が多くなる場合があります。 + */ + "realtimeMode_description": string; + /** + * コンテンツの取得頻度 + */ + "contentsUpdateFrequency": string; + /** + * 高いほどリアルタイムにコンテンツが更新されますが、パフォーマンスが低下し、通信量とバッテリーの消費が多くなります。 + */ + "contentsUpdateFrequency_description": string; + /** + * リアルタイムモードがオンのときは、この設定に関わらずリアルタイムでコンテンツが更新されます。 + */ + "contentsUpdateFrequency_description2": string; + /** + * URLプレビューを表示する + */ + "showUrlPreview": string; + /** + * 利用できるリアクションを先頭に表示 + */ + "showAvailableReactionsFirstInNote": string; + /** + * ページのタブバーを下部に表示 + */ + "showPageTabBarBottom": string; + /** + * 絵文字ピッカーに固定表示するプリセットをパレットとして登録したり、ピッカーの表示方法をカスタマイズしたりできます。 + */ + "emojiPaletteBanner": string; + /** + * 柔らかい転換アニメーション + */ + "smoothTransitionAnimations": string; "_chat": { /** * 送信者の名前を表示 @@ -7240,6 +7558,14 @@ export interface Locale extends ILocale { * 接続している他のすべてのサーバーからの投稿を見られます。 */ "global": string; + /** + * メディアを含むホームタイムラインとローカルタイムラインの投稿が表示されます。 + */ + "media": string; + /** + * 管理者が設定したサーバーの投稿を見ることができます。 + */ + "bubble": string; /** * それぞれのタイムラインは、画面上部でいつでも切り替えられます。 */ @@ -7276,7 +7602,7 @@ export interface Locale extends ILocale { */ "followers": string; /** - * 指定したユーザーにのみ公開され、また相手に通知が入ります。ダイレクトメッセージのかわりにお使いいただけます。 + * 指定したユーザーにのみ公開され、また相手に通知が入ります。 */ "direct": string; /** @@ -7284,7 +7610,7 @@ export interface Locale extends ILocale { */ "doNotSendConfidencialOnDirect1": string; /** - * 送信先のサーバーの管理者は投稿内容を見ることが可能なので、信頼できないサーバーのユーザーにダイレクト投稿を送信する場合は、機密情報の扱いに注意が必要です。 + * 送信先のサーバーの管理者は投稿内容を見ることが可能なので、信頼できないサーバーのユーザーが含まれる限定公開のノートを作成する際は、機密情報の扱いに注意が必要です。 */ "doNotSendConfidencialOnDirect2": string; /** @@ -7377,6 +7703,10 @@ export interface Locale extends ILocale { * グローバルタイムラインでは、接続している他のすべてのサーバーからの投稿を見られます。 */ "global": string; + /** + * メディアタイムラインでは、メディアを含むホームタイムラインとローカルタイムラインの投稿が表示されます。 + */ + "media": string; /** * バブルタイムラインでは、管理者が設定したサーバーの投稿を見ることができます。 */ @@ -7539,6 +7869,22 @@ export interface Locale extends ILocale { * 有効にすると、リアクション作成時のパフォーマンスが大幅に向上し、データベースへの負荷を軽減することが可能です。ただし、Redisのメモリ使用量は増加します。 */ "reactionsBufferingDescription": string; + /** + * リモート投稿の自動クリーニング + */ + "remoteNotesCleaning": string; + /** + * 有効にすると、一定期間経過したリモートの投稿を定期的にクリーンアップしてデータベースの肥大化を抑制します。 + */ + "remoteNotesCleaning_description": string; + /** + * 最大クリーニング処理継続時間 + */ + "remoteNotesCleaningMaxProcessingDuration": string; + /** + * 最低ノート保持日数 + */ + "remoteNotesCleaningExpiryDaysForEachNotes": string; /** * 問い合わせ先URL */ @@ -7567,20 +7913,98 @@ export interface Locale extends ILocale { * 脆弱性などの理由で、サーバーのソフトウェアの名前及びバージョンの範囲を指定して配信を停止できます。このバージョン情報はサーバーが提供したものであり、信頼性は保証されません。バージョン指定には semver の範囲指定が使用できますが、>= 2024.3.1 と指定すると 2024.3.1-custom.0 のようなカスタムバージョンが含まれないため、>= 2024.3.1-0 のように prerelease の指定を行うことを推奨します。 */ "deliverSuspendedSoftwareDescription": string; - }; - "_accountMigration": { /** - * 別のアカウントからこのアカウントに移行 + * お一人様モード */ - "moveFrom": string; + "singleUserMode": string; /** - * 別のアカウントへエイリアスを作成 + * このサーバーを利用するのが自分だけの場合、このモードを有効にすることで動作が最適化されます。 */ - "moveFromSub": string; + "singleUserMode_description": string; /** - * 移行元のアカウント #{n} + * GETリクエストに署名する */ - "moveFromLabel": ParameterizedString<"n">; + "signToActivityPubGet": string; + /** + * 通常は有効にしてください。連合の通信に関する問題がある場合に、無効にすると改善することがありますが、逆にサーバーによっては通信が不可になることがあります。 + */ + "signToActivityPubGet_description": string; + /** + * リモートファイルをプロキシする + */ + "proxyRemoteFiles": string; + /** + * 有効にすると、リモートのファイルをプロキシして提供します。画像のサムネイル生成やユーザーのプライバシー保護に役立ちます。 + */ + "proxyRemoteFiles_description": string; + /** + * ActivityPub経由の照会にリダイレクトを許可する + */ + "allowExternalApRedirect": string; + /** + * 有効にすると、他のサーバーがこのサーバーを通して第三者のコンテンツを照会することが可能になりますが、コンテンツのなりすましが発生する可能性があります。 + */ + "allowExternalApRedirect_description": string; + /** + * 非利用者に対するユーザー作成コンテンツの公開範囲 + */ + "userGeneratedContentsVisibilityForVisitor": string; + /** + * モデレーションが行き届きにくい不適切なリモートコンテンツなどが、自サーバー経由で図らずもインターネットに公開されてしまうことによるトラブル防止などに役立ちます。 + */ + "userGeneratedContentsVisibilityForVisitor_description": string; + /** + * サーバーで受信したリモートのコンテンツを含め、サーバー内の全てのコンテンツを無条件でインターネットに公開することはリスクが伴います。特に、分散型の特性を知らない閲覧者にとっては、リモートのコンテンツであってもサーバー内で作成されたコンテンツであると誤って認識してしまう可能性があるため、注意が必要です。 + */ + "userGeneratedContentsVisibilityForVisitor_description2": string; + /** + * サーバーの初期設定ウィザードをやり直しますか? + */ + "restartServerSetupWizardConfirm_title": string; + /** + * 現在の一部の設定はリセットされます。 + */ + "restartServerSetupWizardConfirm_text": string; + /** + * エントランスページのスタイル + */ + "entrancePageStyle": string; + /** + * タイムラインを表示する + */ + "showTimelineForVisitor": string; + /** + * アクティビティを表示する + */ + "showActivitiesForVisitor": string; + "_userGeneratedContentsVisibilityForVisitor": { + /** + * 全て公開 + */ + "all": string; + /** + * ローカルコンテンツのみ公開し、リモートコンテンツは非公開 + */ + "localOnly": string; + /** + * 全て非公開 + */ + "none": string; + }; + }; + "_accountMigration": { + /** + * 別のアカウントからこのアカウントに移行 + */ + "moveFrom": string; + /** + * 別のアカウントへエイリアスを作成 + */ + "moveFromSub": string; + /** + * 移行元のアカウント #{n} + */ + "moveFromLabel": ParameterizedString<"n">; /** * 別のアカウントからこのアカウントに移行したい場合、ここでエイリアスを作成しておく必要があります。 * 移行元のアカウントをこのように入力してください: @username@server.example.com @@ -8769,6 +9193,10 @@ export interface Locale extends ILocale { * アップロード可能な最大ファイルサイズ */ "maxFileSize": string; + /** + * リバースプロキシやCDNなど、前段で別の設定値が存在する場合があります。 + */ + "maxFileSize_caption": string; /** * ファイルにNSFWを常に付与 */ @@ -8825,6 +9253,10 @@ export interface Locale extends ILocale { * ノート検索の利用 */ "canSearchNotes": string; + /** + * ユーザー検索の利用 + */ + "canSearchUsers": string; /** * 翻訳機能の利用 */ @@ -8866,13 +9298,33 @@ export interface Locale extends ILocale { */ "canImportUserLists": string; /** - * チャットを許可 + * ダイレクトメッセージを許可 */ "chatAvailability": string; + /** + * アップロード可能なファイル種別 + */ + "uploadableFileTypes": string; + /** + * MIMEタイプを指定します。改行で区切って複数指定できるほか、アスタリスク(*)でワイルドカード指定できます。(例: image/*) + */ + "uploadableFileTypes_caption": string; + /** + * ファイルによっては種別を判定できないことがあります。そのようなファイルを許可する場合は {x} を指定に追加してください。 + */ + "uploadableFileTypes_caption2": ParameterizedString<"x">; /** * サーバーサイドのノートの下書きの作成可能数 */ "noteDraftLimit": string; + /** + * 予約投稿の同時作成可能数 + */ + "scheduledNoteLimit": string; + /** + * ウォーターマーク機能の使用可否 + */ + "watermarkAvailable": string; /** * アイコンの形設定の連合を許可 */ @@ -9858,6 +10310,10 @@ export interface Locale extends ILocale { * テーマコード */ "code": string; + /** + * テーマコードをコピー + */ + "copyThemeCode": string; /** * 説明 */ @@ -10087,16 +10543,12 @@ export interface Locale extends ILocale { * 入力ボックスの縁取り */ "inputBorder": string; - /** - * ドライブフォルダーの背景 - */ - "driveFolderBg": string; /** * バッジ */ "badge": string; /** - * チャットの背景 + * メッセージの背景 */ "messageBg": string; /** @@ -10131,7 +10583,7 @@ export interface Locale extends ILocale { */ "reaction": string; /** - * チャットのメッセージ + * ダイレクトメッセージ */ "chatMessage": string; }; @@ -10254,6 +10706,10 @@ export interface Locale extends ILocale { * 日 */ "day": string; + /** + * ヶ月 + */ + "month": string; }; "_2fa": { /** @@ -10411,11 +10867,11 @@ export interface Locale extends ILocale { */ "write:following": string; /** - * チャットを見る + * ダイレクトメッセージを見る */ "read:messaging": string; /** - * チャットを操作する + * ダイレクトメッセージを操作する */ "write:messaging": string; /** @@ -10430,14 +10886,6 @@ export interface Locale extends ILocale { * ノートを作成・削除する */ "write:notes": string; - /** - * 予約投稿を見る - */ - "read:notes-schedule": string; - /** - * 予約投稿を作成・削除する - */ - "write:notes-schedule": string; /** * 通知を見る */ @@ -10715,11 +11163,11 @@ export interface Locale extends ILocale { */ "write:report-abuse": string; /** - * チャットを操作する + * ダイレクトメッセージを操作する */ "write:chat": string; /** - * チャットを閲覧する + * ダイレクトメッセージを閲覧する */ "read:chat": string; }; @@ -10772,6 +11220,10 @@ export interface Locale extends ILocale { * アクセスを許可すると、自動で以下のURLに遷移します */ "byClickingYouWillBeRedirectedToThisUrl": string; + /** + * このアプリケーションは既にアクセスが許可されています。 + */ + "alreadyAuthorized": string; }; "_antennaSources": { /** @@ -10949,7 +11401,7 @@ export interface Locale extends ILocale { */ "birthdayFollowings": string; /** - * チャット + * ダイレクトメッセージ */ "chat": string; /** @@ -11095,7 +11547,7 @@ export interface Locale extends ILocale { */ "followersDescription": string; /** - * ダイレクト + * 指名 */ "specified": string; /** @@ -11112,6 +11564,14 @@ export interface Locale extends ILocale { "disableFederationDescription": string; }; "_postForm": { + /** + * アップロードされていないファイルがありますが、破棄してフォームを閉じますか? + */ + "quitInspiteOfThereAreUnuploadedFilesConfirm": string; + /** + * ファイルはまだアップロードされていません。ファイルのメニューから、リネームや画像のクロップ、ウォーターマークの付与、圧縮の有無などを設定できます。ファイルはノート投稿時に自動でアップロードされます。 + */ + "uploaderTip": string; /** * ノートを作成するにはログインが必要です。 */ @@ -11281,7 +11741,7 @@ export interface Locale extends ILocale { */ "excludeInactiveUsers": string; /** - * インポートした人による返信をTLに含むようにする + * 返信をTLに含むかの情報がファイルにない場合に、インポートした人による返信をTLに含むようにする */ "withReplies": string; }; @@ -11402,6 +11862,10 @@ export interface Locale extends ILocale { * グローバル */ "global": string; + /** + * メディア + */ + "media": string; /** * バブル */ @@ -11718,6 +12182,14 @@ export interface Locale extends ILocale { * アンケートの結果が出ました */ "pollEnded": string; + /** + * 予約ノートが投稿されました + */ + "scheduledNotePosted": string; + /** + * 予約ノートの投稿に失敗しました + */ + "scheduledNotePostFailed": string; /** * 新しい投稿 */ @@ -11731,7 +12203,7 @@ export interface Locale extends ILocale { */ "roleAssigned": string; /** - * チャットルームへ招待されました + * ダイレクトメッセージのグループへ招待されました */ "chatRoomInvitationReceived": string; /** @@ -11840,6 +12312,14 @@ export interface Locale extends ILocale { * アンケートが終了 */ "pollEnded": string; + /** + * 予約投稿が成功した + */ + "scheduledNotePosted": string; + /** + * 予約投稿が失敗した + */ + "scheduledNotePostFailed": string; /** * フォロー申請を受け取った */ @@ -11857,7 +12337,7 @@ export interface Locale extends ILocale { */ "roleAssigned": string; /** - * チャットルームへ招待された + * ダイレクトメッセージのグループへ招待された */ "chatRoomInvitationReceived": string; /** @@ -11903,28 +12383,6 @@ export interface Locale extends ILocale { */ "renote": string; }; - "_scheduleNote": { - /** - * 原因は不明です - */ - "unknown": string; - /** - * 引用元がありません - */ - "renoteTargetNotFound": string; - /** - * 対象のチャンネルがありません - */ - "channelTargetNotFound": string; - /** - * 返信先がありません - */ - "replyTargetNotFound": string; - /** - * 添付ファイルがありません - */ - "invalidFilesCount": string; - }; }; "_deck": { /** @@ -12053,11 +12511,11 @@ export interface Locale extends ILocale { */ "channel": string; /** - * あなた宛て + * メンション */ "mentions": string; /** - * ダイレクト + * 指名 */ "direct": string; /** @@ -12065,7 +12523,7 @@ export interface Locale extends ILocale { */ "roleTimeline": string; /** - * チャット + * ダイレクトメッセージ */ "chat": string; }; @@ -12436,7 +12894,7 @@ export interface Locale extends ILocale { */ "deleteGalleryPost": string; /** - * チャットルームを削除 + * ダイレクトメッセージのグループを削除 */ "deleteChatRoom": string; /** @@ -12473,6 +12931,10 @@ export interface Locale extends ILocale { * 添付されているノート */ "attachedNotes": string; + /** + * 利用 + */ + "usage": string; /** * このページは、このファイルをアップロードしたユーザーしか閲覧できません。 */ @@ -12631,7 +13093,7 @@ export interface Locale extends ILocale { */ "description": string; }; - "_urlPreview": { + "_urlPreviewThumbnail": { /** * URLプレビューのサムネイルを非表示 */ @@ -12641,6 +13103,16 @@ export interface Locale extends ILocale { */ "description": string; }; + "_disableUrlPreview": { + /** + * URLプレビューを無効化 + */ + "title": string; + /** + * URLプレビュー機能を無効化します。サムネイル画像だけと違い、リンク先の情報の読み込み自体を削減できます。 + */ + "description": string; + }; "_code": { /** * コードハイライトを非表示 @@ -12863,6 +13335,14 @@ export interface Locale extends ILocale { * URLプレビューを有効にする */ "enable": string; + /** + * プレビュー先のリダイレクトを許可 + */ + "allowRedirect": string; + /** + * 入力されたURLがリダイレクトされる場合に、そのリダイレクト先をたどってプレビューを表示するかどうかを設定します。無効にするとサーバーリソースの節約になりますが、リダイレクト先の内容は表示されなくなります。 + */ + "allowRedirectDescription": string; /** * プレビュー取得時のタイムアウト(ms) */ @@ -13130,22 +13610,6 @@ export interface Locale extends ILocale { * ディレクトリをドラッグ・ドロップした時に、ディレクトリ名を"category"に入力します。 */ "directoryToCategoryCaption": string; - /** - * いずれかの方法で登録する絵文字を選択してください。 - */ - "emojiInputAreaCaption": string; - /** - * この枠に画像ファイルまたはディレクトリをドラッグ&ドロップ - */ - "emojiInputAreaList1": string; - /** - * このリンクをクリックしてPCから選択する - */ - "emojiInputAreaList2": string; - /** - * このリンクをクリックしてドライブから選択する - */ - "emojiInputAreaList3": string; /** * リストに表示されている絵文字を新たなカスタム絵文字として登録します。よろしいですか?(負荷を避けるため、一度の操作で登録可能な絵文字は{count}件までです) */ @@ -13392,6 +13856,10 @@ export interface Locale extends ILocale { * 修復ツールを起動 */ "otherOption3": string; + /** + * CherryPickをセーフモードで起動 + */ + "otherOption4": string; }; "_search": { /** @@ -13423,233 +13891,917 @@ export interface Locale extends ILocale { */ "serverHostPlaceholder": string; }; - "_drafts": { + "_serverSetupWizard": { /** - * 下書きを選択 + * CherryPickのインストールが完了しました! */ - "select": string; + "installCompleted": string; /** - * 下書きを削除 + * まずは、管理者アカウントを作成しましょう。 */ - "delete": string; + "firstCreateAccount": string; /** - * 下書きを削除しますか? + * 管理者アカウントが作成されました! */ - "deleteAreYouSure": string; + "accountCreated": string; /** - * 下書きはありません。 + * サーバーの設定 */ - "noDrafts": string; + "serverSetting": string; /** - * {user}への返信 + * このウィザードで簡単に最適なサーバーの設定が行えます。 */ - "replyTo": ParameterizedString<"user">; + "youCanEasilyConfigureOptimalServerSettingsWithThisWizard": string; /** - * {user}のノートへの引用 + * ここでの設定は、あとからでも変更できます。 */ - "quoteOf": ParameterizedString<"user">; + "settingsYouMakeHereCanBeChangedLater": string; /** - * {channel}への投稿 + * CherryPickをどのように使いますか? */ - "postTo": ParameterizedString<"channel">; - }; - "_abuse": { - "_resolver": { - /** - * 一時間 - */ - "1hour": string; - /** - * 半日 - */ - "12hours": string; - /** - * 一日 - */ - "1day": string; + "howWillYouUseMisskey": string; + "_use": { /** - * 一週間 + * お一人様サーバー */ - "1week": string; + "single": string; /** - * 一ヶ月 + * 自分専用のサーバーとして、一人で使う */ - "1month": string; + "single_description": string; /** - * 三ヶ月 + * お一人様サーバーとして運用する場合でも、アカウントは必要に応じて複数作成可能です。 */ - "3months": string; + "single_youCanCreateMultipleAccounts": string; /** - * 六ヶ月 + * グループサーバー */ - "6months": string; + "group": string; /** - * 一年 + * 信頼できる他の利用者を招待して、複数人で使う */ - "1year": string; + "group_description": string; /** - * 無期限 + * オープンサーバー */ - "indefinitely": string; + "open": string; /** - * この条件の有効期限 + * 不特定多数の利用者を受け入れる運営を行う */ - "expiresAt": string; + "open_description": string; + }; + /** + * 不特定多数の利用者を受け入れることはリスクが伴います。トラブルに対処できるよう、確実なモデレーション体制で運営することを推奨します。 + */ + "openServerAdvice": string; + /** + * 自サーバーがスパムの踏み台にならないように、reCAPTCHAといったアンチボット機能を有効にするなど、セキュリティについても細心の注意が必要です。 + */ + "openServerAntiSpamAdvice": string; + /** + * どれくらいの人数を想定していますか? + */ + "howManyUsersDoYouExpect": string; + "_scale": { /** - * 通報先のパターン + * 100人以下 (小規模) */ - "targetUserPattern": string; + "small": string; /** - * 通報元のパターン + * 100人以上1000人以下 (中規模) */ - "reporterPattern": string; + "medium": string; /** - * 通報内容のパターン + * 1000人以上 (大規模) */ - "reportContentPattern": string; + "large": string; }; /** - * 一覧 + * 大規模なサーバーでは、ロードバランシングやデータベースのレプリケーションなど、高度なインフラストラクチャーの知識が必要になる場合があります。 */ - "list": string; + "largeScaleServerAdvice": string; /** - * リソルバー + * Fediverseと接続しますか? */ - "resolver": string; - }; - "_imageCompressionMode": { + "doYouConnectToFediverse": string; /** - * 画像の圧縮形式 + * 分散型サーバーで構成されるネットワーク(Fediverse)に接続すると、他のサーバーと相互にコンテンツのやり取りが可能です。 */ - "title": string; + "doYouConnectToFediverse_description1": string; /** - * オリジナル画像を保持しない場合に、Web公開用画像の圧縮形式を選択できます。縮小する場合は2048x2048より小さくなるように縮小されます。非可逆圧縮を指定しない場合は、元画像に応じて非可逆圧縮か可逆圧縮かが自動的に選択されます。 + * Fediverseと接続することは「連合」とも呼ばれます。 */ - "description": string; + "doYouConnectToFediverse_description2": string; /** - * 縮小して再圧縮する + * 連合可能なサーバーの指定など、高度な設定も後ほど可能です。 */ - "resizeCompress": string; + "youCanConfigureMoreFederationSettingsLater": string; /** - * 縮小せず再圧縮する + * リモートコンテンツの自動クリーニング */ - "noResizeCompress": string; + "remoteContentsCleaning": string; /** - * 縮小して非可逆圧縮する + * 連合を行うと、継続して多くのコンテンツを受信します。自動クリーニングを有効にすると、一定期間経過したリモートコンテンツを自動でサーバーから削除し、ストレージを節約できます。 */ - "resizeCompressLossy": string; + "remoteContentsCleaning_description": string; /** - * 縮小せず非可逆圧縮する + * 管理者情報 */ - "noResizeCompressLossy": string; - }; - "_externalNavigationWarning": { + "adminInfo": string; /** - * 外部サイトに移動します + * 問い合わせを受け付けるために使用される管理者情報を設定します。 */ - "title": string; + "adminInfo_description": string; /** - * {host}を離れて外部サイトに移動します + * オープンサーバー、または連合がオンの場合は必ず入力が必要です。 */ - "description": ParameterizedString<"host">; + "adminInfo_mustBeFilled": string; /** - * このデバイスで今後このドメインを信頼する + * 以下の設定が推奨されます */ - "trustThisDomain": string; + "followingSettingsAreRecommended": string; /** - * 外部サイトに移動する際の警告 + * この設定を適用 */ - "externalNavigationWarning": string; + "applyTheseSettings": string; /** - * 外部サイトに移動する際の警告を表示 + * 設定をスキップ */ - "enableExternalNavigationWarning": string; + "skipSettings": string; /** - * 信頼するドメインリスト + * 設定が完了しました! */ - "trustedDomainList": string; + "settingsCompleted": string; /** - * `http://`と`https://`を省略して入力してください。 + * お疲れ様でした。準備が整ったので、さっそくサーバーの使用を開始できます。 */ - "trustedDomainListDescription": string; + "settingsCompleted_description": string; /** - * 改行で区切って設定します + * 詳細なサーバー設定は、「コントロールパネル」から行えます。 */ - "trustedDomainListDescription2": string; + "settingsCompleted_description2": string; /** - * 信頼するドメインリストのリセット + * 寄付のお願い */ - "deleteTrustedDomainList": string; + "donationRequest": string; + "_donationRequest": { + /** + * CherryPickは有志によって開発されている無料のソフトウェアです。 + */ + "text1": string; + /** + * 今後も開発を続けられるように、よろしければぜひカンパをお願いいたします。 + */ + "text2": string; + /** + * 支援者向け特典もあります! + */ + "text3": string; + }; }; - "_altWarning": { + "_uploader": { /** - * ファイルに代替テキストが設定されていません。 + * 画像の編集 */ - "noAltWarning": string; + "editImage": string; /** - * この設定は「設定 → アピアランス」で変更できます。 + * {x}に圧縮 */ - "noAltWarningDescription": string; - }; - "_dice": { + "compressedToX": ParameterizedString<"x">; /** - * サイコロを振る + * {x}%節約 */ - "rollDice": string; + "savedXPercent": ParameterizedString<"x">; /** - * サイコロの数 + * アップロードされていないファイルがありますが、中止しますか? */ - "diceCount": string; + "abortConfirm": string; /** - * サイコロの面数 + * アップロードされていないファイルがありますが、完了しますか? */ - "diceFaces": string; - }; - "_scheduledNoteDelete": { + "doneConfirm": string; /** - * 期限 + * アップロード可能な最大ファイルサイズは{x}です。 */ - "expiration": string; + "maxFileSizeIsX": ParameterizedString<"x">; /** - * 日時指定 + * アップロード可能なファイル種別 */ - "at": string; + "allowedTypes": string; /** - * 経過指定 + * ファイルはまだアップロードされていません。このダイアログで、アップロード前の確認・リネーム・圧縮・クロッピングなどが行えます。準備が出来たら、「アップロード」ボタンを押してアップロードを開始できます。 */ - "after": string; + "tip": string; + }; + "_clientPerformanceIssueTip": { /** - * 期日 + * バッテリー消費が多いと感じたら */ - "deadlineDate": string; + "title": string; /** - * 時間 + * アドブロッカーを無効にしてください */ - "deadlineTime": string; + "makeSureDisabledAdBlocker": string; /** - * 期間 + * アドブロッカーはパフォーマンスに影響を及ぼすことがあります。OSの機能やブラウザの機能・アドオンなどでアドブロッカーが有効になっていないか確認してください。 */ - "duration": string; - }; - "_getQRCode": { + "makeSureDisabledAdBlocker_description": string; /** - * QRコードをスキャンする + * カスタムCSSを無効にしてください */ - "title": string; + "makeSureDisabledCustomCss": string; /** - * 以下のQRコードをスキャンまたは共有できます。 + * スタイルを上書きするとパフォーマンスに影響を及ぼすことがあります。カスタムCSSや、スタイルを上書きする拡張機能が有効になっていないか確認してください。 */ - "description": string; - }; - "_searchSite": { + "makeSureDisabledCustomCss_description": string; /** - * 検索エンジン + * 拡張機能を無効にしてください */ - "title": string; + "makeSureDisabledAddons": string; /** - * MFCの検索構文で検索できるサイトを変更します。 + * 一部の拡張機能はクライアントの動作に干渉しパフォーマンスに影響を及ぼすことがあります。ブラウザの拡張機能を無効にして改善するか確認してください。 */ - "description": string; + "makeSureDisabledAddons_description": string; + }; + "_clip": { + /** + * クリップは、ノートをまとめることができる機能です。 + */ + "tip": string; + }; + "_userLists": { + /** + * 任意のユーザーが含まれるリストを作成できます。作成したリストはタイムラインとして表示可能です。 + */ + "tip": string; + }; + /** + * ウォーターマーク + */ + "watermark": string; + /** + * デフォルトのプリセット + */ + "defaultPreset": string; + "_watermarkEditor": { + /** + * 画像にクレジット情報などのウォーターマークを追加することができます。 + */ + "tip": string; + /** + * 保存せずに終了しますか? + */ + "quitWithoutSaveConfirm": string; + /** + * このファイルは対応していません + */ + "driveFileTypeWarn": string; + /** + * 画像ファイルを選択してください + */ + "driveFileTypeWarnDescription": string; + /** + * ウォーターマークの編集 + */ + "title": string; + /** + * 全体に被せる + */ + "cover": string; + /** + * 敷き詰める + */ + "repeat": string; + /** + * 回転時はみ出ないように調整する + */ + "preserveBoundingRect": string; + /** + * 不透明度 + */ + "opacity": string; + /** + * サイズ + */ + "scale": string; + /** + * テキスト + */ + "text": string; + /** + * 二次元コード + */ + "qr": string; + /** + * 位置 + */ + "position": string; + /** + * マージン + */ + "margin": string; + /** + * タイプ + */ + "type": string; + /** + * 画像 + */ + "image": string; + /** + * 高度 + */ + "advanced": string; + /** + * 角度 + */ + "angle": string; + /** + * ストライプ + */ + "stripe": string; + /** + * ラインの幅 + */ + "stripeWidth": string; + /** + * ラインの数 + */ + "stripeFrequency": string; + /** + * ポルカドット + */ + "polkadot": string; + /** + * チェッカー + */ + "checker": string; + /** + * メインドットの不透明度 + */ + "polkadotMainDotOpacity": string; + /** + * メインドットの大きさ + */ + "polkadotMainDotRadius": string; + /** + * サブドットの不透明度 + */ + "polkadotSubDotOpacity": string; + /** + * サブドットの大きさ + */ + "polkadotSubDotRadius": string; + /** + * サブドットの数 + */ + "polkadotSubDotDivisions": string; + /** + * 空欄にするとアカウントのURLになります + */ + "leaveBlankToAccountUrl": string; + }; + "_imageEffector": { + /** + * エフェクト + */ + "title": string; + /** + * エフェクトを追加 + */ + "addEffect": string; + /** + * 変更を破棄して終了しますか? + */ + "discardChangesConfirm": string; + /** + * 設定項目はありません + */ + "nothingToConfigure": string; + "_fxs": { + /** + * 色収差 + */ + "chromaticAberration": string; + /** + * グリッチ + */ + "glitch": string; + /** + * ミラー + */ + "mirror": string; + /** + * 色の反転 + */ + "invert": string; + /** + * 白黒 + */ + "grayscale": string; + /** + * ぼかし + */ + "blur": string; + /** + * モザイク + */ + "pixelate": string; + /** + * 色調補正 + */ + "colorAdjust": string; + /** + * 色の圧縮 + */ + "colorClamp": string; + /** + * 色の圧縮(高度) + */ + "colorClampAdvanced": string; + /** + * 歪み + */ + "distort": string; + /** + * 二値化 + */ + "threshold": string; + /** + * 集中線 + */ + "zoomLines": string; + /** + * ストライプ + */ + "stripe": string; + /** + * ポルカドット + */ + "polkadot": string; + /** + * チェッカー + */ + "checker": string; + /** + * ブロックノイズ + */ + "blockNoise": string; + /** + * ティアリング + */ + "tearing": string; + /** + * 塗りつぶし + */ + "fill": string; + }; + "_fxProps": { + /** + * 角度 + */ + "angle": string; + /** + * サイズ + */ + "scale": string; + /** + * サイズ + */ + "size": string; + /** + * 半径 + */ + "radius": string; + /** + * サンプル数 + */ + "samples": string; + /** + * 位置 + */ + "offset": string; + /** + * 色 + */ + "color": string; + /** + * 不透明度 + */ + "opacity": string; + /** + * 正規化 + */ + "normalize": string; + /** + * 量 + */ + "amount": string; + /** + * 明るさ + */ + "lightness": string; + /** + * コントラスト + */ + "contrast": string; + /** + * 色相 + */ + "hue": string; + /** + * 輝度 + */ + "brightness": string; + /** + * 彩度 + */ + "saturation": string; + /** + * 最大値 + */ + "max": string; + /** + * 最小値 + */ + "min": string; + /** + * 方向 + */ + "direction": string; + /** + * 位相 + */ + "phase": string; + /** + * 頻度 + */ + "frequency": string; + /** + * 強さ + */ + "strength": string; + /** + * ズレ + */ + "glitchChannelShift": string; + /** + * シード値 + */ + "seed": string; + /** + * 赤色成分 + */ + "redComponent": string; + /** + * 緑色成分 + */ + "greenComponent": string; + /** + * 青色成分 + */ + "blueComponent": string; + /** + * しきい値 + */ + "threshold": string; + /** + * 中心X + */ + "centerX": string; + /** + * 中心Y + */ + "centerY": string; + /** + * スムージング + */ + "zoomLinesSmoothing": string; + /** + * スムージングと集中線の幅の設定は併用できません。 + */ + "zoomLinesSmoothingDescription": string; + /** + * 集中線の幅 + */ + "zoomLinesThreshold": string; + /** + * 中心径 + */ + "zoomLinesMaskSize": string; + /** + * 黒色にする + */ + "zoomLinesBlack": string; + /** + * 円形 + */ + "circle": string; + }; + }; + /** + * 下書き + */ + "drafts": string; + "_drafts": { + /** + * 下書きを選択 + */ + "select": string; + /** + * 下書きの作成可能数を超えています。 + */ + "cannotCreateDraftAnymore": string; + /** + * この内容では下書きを作成できません。 + */ + "cannotCreateDraft": string; + /** + * 下書きを削除 + */ + "delete": string; + /** + * 下書きを削除しますか? + */ + "deleteAreYouSure": string; + /** + * 下書きはありません + */ + "noDrafts": string; + /** + * {user}への返信 + */ + "replyTo": ParameterizedString<"user">; + /** + * {user}のノートへの引用 + */ + "quoteOf": ParameterizedString<"user">; + /** + * {channel}への投稿 + */ + "postTo": ParameterizedString<"channel">; + /** + * 下書きへ保存 + */ + "saveToDraft": string; + /** + * 下書きから復元 + */ + "restoreFromDraft": string; + /** + * 復元 + */ + "restore": string; + /** + * 下書き一覧 + */ + "listDrafts": string; + /** + * 投稿予約 + */ + "schedule": string; + /** + * 予約投稿一覧 + */ + "listScheduledNotes": string; + /** + * 予約解除 + */ + "cancelSchedule": string; + }; + /** + * 二次元コード + */ + "qr": string; + "_qr": { + /** + * 表示 + */ + "showTabTitle": string; + /** + * 読み取る + */ + "readTabTitle": string; + /** + * {name} {acct} + */ + "shareTitle": ParameterizedString<"name" | "acct">; + /** + * Fediverseで私をフォローしてください! + */ + "shareText": string; + /** + * カメラを選択 + */ + "chooseCamera": string; + /** + * ライト選択不可 + */ + "cannotToggleFlash": string; + /** + * ライトをオンにする + */ + "turnOnFlash": string; + /** + * ライトをオフにする + */ + "turnOffFlash": string; + /** + * コードリーダーを再開 + */ + "startQr": string; + /** + * コードリーダーを停止 + */ + "stopQr": string; + /** + * QRコードが見つかりません + */ + "noQrCodeFound": string; + /** + * 端末の画像をスキャン + */ + "scanFile": string; + /** + * テキスト + */ + "raw": string; + /** + * MFC + */ + "mfm": string; + }; + "_abuse": { + "_resolver": { + /** + * 一時間 + */ + "1hour": string; + /** + * 半日 + */ + "12hours": string; + /** + * 一日 + */ + "1day": string; + /** + * 一週間 + */ + "1week": string; + /** + * 一ヶ月 + */ + "1month": string; + /** + * 三ヶ月 + */ + "3months": string; + /** + * 六ヶ月 + */ + "6months": string; + /** + * 一年 + */ + "1year": string; + /** + * 無期限 + */ + "indefinitely": string; + /** + * この条件の有効期限 + */ + "expiresAt": string; + /** + * 通報先のパターン + */ + "targetUserPattern": string; + /** + * 通報元のパターン + */ + "reporterPattern": string; + /** + * 通報内容のパターン + */ + "reportContentPattern": string; + }; + /** + * 一覧 + */ + "list": string; + /** + * リソルバー + */ + "resolver": string; + }; + "_externalNavigationWarning": { + /** + * 外部サイトに移動します + */ + "title": string; + /** + * {host}を離れて外部サイトに移動します + */ + "description": ParameterizedString<"host">; + /** + * このデバイスで今後このドメインを信頼する + */ + "trustThisDomain": string; + /** + * 外部サイトに移動する際の警告 + */ + "externalNavigationWarning": string; + /** + * 外部サイトに移動する際の警告を表示 + */ + "enableExternalNavigationWarning": string; + /** + * 信頼するドメインリスト + */ + "trustedDomainList": string; + /** + * `http://`と`https://`を省略して入力してください。 + */ + "trustedDomainListDescription": string; + /** + * 改行で区切って設定します + */ + "trustedDomainListDescription2": string; + /** + * 信頼するドメインリストのリセット + */ + "deleteTrustedDomainList": string; + }; + "_altWarning": { + /** + * ファイルに代替テキストが設定されていません。 + */ + "noAltWarning": string; + /** + * この設定は「設定 → アピアランス」で変更できます。 + */ + "noAltWarningDescription": string; + }; + "_dice": { + /** + * サイコロを振る + */ + "rollDice": string; + /** + * サイコロの数 + */ + "diceCount": string; + /** + * サイコロの面数 + */ + "diceFaces": string; + }; + "_scheduledNoteDelete": { + /** + * 期限 + */ + "expiration": string; + /** + * 日時指定 + */ + "at": string; + /** + * 経過指定 + */ + "after": string; + /** + * 期日 + */ + "deadlineDate": string; + /** + * 時間 + */ + "deadlineTime": string; + /** + * 期間 + */ + "duration": string; + }; + "_getQRCode": { + /** + * QRコードをスキャンする + */ + "title": string; + /** + * 以下のQRコードをスキャンまたは共有できます。 + */ + "description": string; + }; + "_searchSite": { + /** + * 検索エンジン + */ + "title": string; + /** + * MFCの検索構文で検索できるサイトを変更します。 + */ + "description": string; /** * その他の検索エンジン */ @@ -13767,10 +14919,52 @@ export interface Locale extends ILocale { */ "precipitation": string; }; - /** - * アクティビティを送信しない - */ - "noSendActivity": string; + "_deliveryTargetControl": { + /** + * 配送先制御 + */ + "deliveryTargetControl": string; + /** + * 選択したサーバーのみに配送 + */ + "deliveryTargetInclude": string; + /** + * 選択したサーバーを除外して配送 + */ + "deliveryTargetExclude": string; + /** + * リモートサーバーのフォロワーがいません + */ + "noFollowersFromRemoteServers": string; + /** + * サーバー一覧の読み込みに失敗しました + */ + "loadError": string; + /** + * {count}人のフォロワー + */ + "followersCount": ParameterizedString<"count">; + /** + * {count}件見つかりました(全{total}件中) + */ + "searchResults": ParameterizedString<"count" | "total">; + /** + * 一部のサーバーにのみ公開 + */ + "deliveryTargetsInclude": string; + /** + * 一部のサーバーに非公開 + */ + "deliveryTargetsExclude": string; + /** + * 配送先が選択されています + */ + "hasDeliveryTargets": string; + /** + * アクティビティを送信しない + */ + "noSendActivity": string; + }; /** * IPアドレス */ @@ -13855,48 +15049,6 @@ export interface Locale extends ILocale { "set": string; }; }; - "_deliveryTargetControl": { - /** - * 配送先制御 - */ - "deliveryTargetControl": string; - /** - * 選択したサーバーのみに配送 - */ - "deliveryTargetInclude": string; - /** - * 選択したサーバーを除外して配送 - */ - "deliveryTargetExclude": string; - /** - * リモートサーバーのフォロワーがいません - */ - "noFollowersFromRemoteServers": string; - /** - * サーバー一覧の読み込みに失敗しました - */ - "loadError": string; - /** - * {count}人のフォロワー - */ - "followersCount": ParameterizedString<"count">; - /** - * {count}件見つかりました(全{total}件中) - */ - "searchResults": ParameterizedString<"count" | "total">; - /** - * 一部のサーバーにのみ公開 - */ - "deliveryTargetsInclude": string; - /** - * 一部のサーバーに非公開 - */ - "deliveryTargetsExclude": string; - /** - * 配送先が選択されています - */ - "hasDeliveryTargets": string; - }; "_hideReason": { /** * この投稿は非公開です diff --git a/locales/index.js b/locales/index.js index 811ef2f11f..139df6a451 100644 --- a/locales/index.js +++ b/locales/index.js @@ -36,6 +36,7 @@ const languages = [ 'ru-RU', 'sk-SK', 'th-TH', + 'tr-TR', 'ug-CN', 'uk-UA', 'vi-VN', diff --git a/locales/it-IT.yml b/locales/it-IT.yml index d84f5a0e03..99c339daf4 100644 --- a/locales/it-IT.yml +++ b/locales/it-IT.yml @@ -139,7 +139,7 @@ overwriteFromPinnedEmojis: "Sovrascrivi con le impostazioni globali" reactionSettingDescription2: "Trascina per riorganizzare, clicca per cancellare, usa il pulsante \"+\" per aggiungere." rememberNoteVisibility: "Ricordare le impostazioni di visibilità delle note" attachCancel: "Rimuovi allegato" -deleteFile: "File da Drive eliminato" +deleteFile: "Elimina un file dal Drive" markAsSensitive: "Segna come esplicito" unmarkAsSensitive: "Non segnare come esplicito " enterFileName: "Nome del file" @@ -220,6 +220,7 @@ silenceThisInstance: "Silenziare l'istanza" mediaSilenceThisInstance: "Silenzia i media dell'istanza" operations: "Operazioni" software: "Software" +softwareName: "Nome del software" version: "Versione" metadata: "Metadato" withNFiles: "{n} file in allegato" @@ -250,9 +251,9 @@ noUsers: "Non ci sono profili" editProfile: "Modifica profilo" noteDeleteConfirm: "Vuoi davvero eliminare questa Nota?" pinLimitExceeded: "Non puoi fissare altre note " -intro: "L'installazione di CherryPick è terminata! Si prega di creare il profilo amministratore." done: "Fine" processing: "In elaborazione" +preprocessing: "In preparazione" preview: "Anteprima" default: "Predefinito" defaultValueIs: "Predefinito: {value}" @@ -298,6 +299,7 @@ uploadFromUrl: "Incolla URL immagine" uploadFromUrlDescription: "URL del file che vuoi caricare" uploadFromUrlRequested: "Caricamento richiesto" uploadFromUrlMayTakeTime: "Il caricamento del file può richiedere tempo." +uploadNFiles: "Caricare {n} file singolarmente" explore: "Esplora" messageRead: "Visualizzato" noMoreHistory: "Non c'è più cronologia da visualizzare" @@ -326,11 +328,13 @@ dark: "Scuro" lightThemes: "Tema Chiaro" darkThemes: "Tema Scuro" syncDeviceDarkMode: "Sincronizza il tema scuro con le impostazioni del dispositivo" +switchDarkModeManuallyWhenSyncEnabledConfirm: "({x}) è attiva. Vuoi disattivare la sincronizzazione e passare alla modalità manuale?" drive: "Drive" fileName: "Nome dell'allegato" selectFile: "Scelta allegato" selectFiles: "Scelta allegato" selectFolder: "Seleziona cartella" +unselectFolder: "Deseleziona la cartella" selectFolders: "Seleziona cartella" fileNotSelected: "Nessun file selezionato" renameFile: "Rinomina file" @@ -343,6 +347,7 @@ addFile: "Allega" showFile: "Visualizza file" emptyDrive: "Il Drive è vuoto" emptyFolder: "La cartella è vuota" +dropHereToUpload: "Trascina qui il tuo file per caricarlo" unableToDelete: "Eliminazione impossibile" inputNewFileName: "Inserisci nome del nuovo file" inputNewDescription: "Inserisci una nuova descrizione" @@ -453,7 +458,7 @@ setupOf2fa: "Impostare l'autenticazione a due fattori" totp: "App di autenticazione a due fattori (2FA/MFA)" totpDescription: "Puoi autenticarti inserendo un codice OTP tramite la tua App di autenticazione a due fattori (2FA/MFA)" moderator: "Moderatore" -moderation: "moderazione" +moderation: "Moderazione" moderationNote: "Promemoria di moderazione" moderationNoteDescription: "Puoi scrivere promemoria condivisi solo tra moderatori." addModerationNote: "Aggiungi promemoria di moderazione" @@ -501,7 +506,7 @@ attachAsFileQuestion: "Il testo copiato eccede le dimensioni, vuoi allegarlo?" onlyOneFileCanBeAttached: "È possibile allegare al messaggio soltanto uno file" signinRequired: "Occorre avere un profilo registrato su questa istanza" signinOrContinueOnRemote: "Per continuare, devi accedere alla tua istanza o registrarti su questa e poi accedere" -invitations: "Invita" +invitations: "Inviti" invitationCode: "Codice di invito" checking: "Confermando" available: "Disponibile" @@ -585,10 +590,12 @@ showFixedPostForm: "Visualizzare la finestra di pubblicazione in cima alla timel showFixedPostFormInChannel: "Per i canali, mostra il modulo di pubblicazione in cima alla timeline" withRepliesByDefaultForNewlyFollowed: "Quando segui nuovi profili, includi le risposte in TL come impostazione predefinita" newNoteRecived: "Nuove Note da leggere" +newNote: "Nuove Note" sounds: "Impostazioni suoni" sound: "Suono" +notificationSoundSettings: "Preferenze di notifica" listen: "Ascolta" -none: "Nessuno" +none: "Nessuna" showInPage: "Visualizza in pagina" popout: "Finestra pop-out" volume: "Volume" @@ -778,6 +785,7 @@ lockedAccountInfo: "A meno che non imposti la visibilità delle tue note su \"So alwaysMarkSensitive: "Segnare automaticamente come espliciti gli allegati" loadRawImages: "Visualizza le intere immagini allegate invece delle miniature." disableShowingAnimatedImages: "Disabilitare le immagini animate" +disableShowingAnimatedImages_caption: "L'attivazione delle animazioni immagini potrebbe interferire sull'accessibilità e sul risparmio energetico nel dispositivo." highlightSensitiveMedia: "Evidenzia i media espliciti" verificationEmailSent: "Una mail di verifica è stata inviata. Si prega di accedere al collegamento per compiere la verifica." notSet: "Non impostato" @@ -802,6 +810,7 @@ wide: "Largo" narrow: "Stretto" reloadToApplySetting: "Le tue preferenze verranno impostate dopo il ricaricamento della pagina. Vuoi ricaricare adesso?" needReloadToApply: "È necessario riavviare per rendere effettive le modifiche." +needToRestartServerToApply: "Per attivare le modifiche, occorre riavviare il server." showTitlebar: "Visualizza la barra del titolo" clearCache: "Svuota la cache" onlineUsersCount: "{n} persone attive adesso" @@ -905,7 +914,7 @@ useBlurEffect: "Utilizza effetto sfocatura" learnMore: "Per saperne di più" misskeyUpdated: "CherryPick è stato aggiornato!" whatIsNew: "Informazioni sull'aggiornamento" -translate: "Traduci" +translate: "Traduzione" translatedFrom: "Traduzione da {x}" accountDeletionInProgress: "È in corso l'eliminazione del profilo" usernameInfo: "Un nome per identificare univocamente il tuo profilo sull'istanza. Puoi utilizzare caratteri alfanumerici maiuscoli, minuscoli e il trattino basso (_). Non potrai cambiare nome utente in seguito." @@ -916,7 +925,7 @@ pubSub: "Publish/Subscribe del profilo" lastCommunication: "La comunicazione più recente" resolved: "Risolto" unresolved: "Non risolto" -breakFollow: "Rimuovi Follower" +breakFollow: "Rimuovere Follower" breakFollowConfirm: "Vuoi davvero togliere questo Follower?" itsOn: "Abilitato" itsOff: "Disabilitato" @@ -1010,6 +1019,7 @@ failedToUpload: "errore di caricamento" cannotUploadBecauseInappropriate: "Non è possibile caricarlo perché è stato stabilito che potrebbe contenere contenuti inappropriati." cannotUploadBecauseNoFreeSpace: "Impossibile caricare a causa della mancanza di spazio libero sul drive." cannotUploadBecauseExceedsFileSizeLimit: "Il file non può essere caricato perché eccede le dimensioni consentite." +cannotUploadBecauseUnallowedFileType: "Impossibile caricare a causa di un tipo file non autorizzato." beta: "Versione beta" enableAutoSensitive: "Determinazione automatica del NSFW" enableAutoSensitiveDescription: "Se disponibile, il flag NSFW viene impostato automaticamente sui media utilizzando l'apprendimento automatico. Anche se questa funzione è disattivata, in alcuni casi può essere impostata automaticamente." @@ -1061,6 +1071,7 @@ permissionDeniedError: "Errore, attività non autorizzata" permissionDeniedErrorDescription: "Non si dispone dell'autorizzazione per eseguire questa operazione." preset: "Preimpostato" selectFromPresets: "Seleziona preimpostato" +custom: "Personalizzato" achievements: "Conquiste" gotInvalidResponseError: "Risposta del server non valida" gotInvalidResponseErrorDescription: "Il server potrebbe essere irraggiungibile o in manutenzione. Riprova più tardi." @@ -1099,6 +1110,7 @@ prohibitedWordsDescription2: "Gli spazi creano la relazione \"E\" tra parole (qu hiddenTags: "Hashtag nascosti" hiddenTagsDescription: "Impedire la visualizzazione del tag impostato nei trend. Puoi impostare più valori, uno per riga." notesSearchNotAvailable: "Non è possibile cercare tra le Note." +usersSearchNotAvailable: "La ricerca profili non è disponibile." license: "Licenza" unfavoriteConfirm: "Vuoi davvero rimuovere la preferenza?" myClips: "Le mie Clip" @@ -1173,6 +1185,7 @@ installed: "Installazione avvenuta" branding: "Branding" enableServerMachineStats: "Pubblicare le informazioni sul server" enableIdenticonGeneration: "Generazione automatica delle Identicon" +showRoleBadgesOfRemoteUsers: "Visualizza i badge per i ruoli concessi ai profili remoti" turnOffToImprovePerformance: "Disattiva, per migliorare le prestazioni" createInviteCode: "Genera codice di invito" createWithOptions: "Genera con opzioni" @@ -1205,7 +1218,7 @@ replies: "Risposte" renotes: "Rinota" loadReplies: "Leggi le risposte" loadConversation: "Leggi la conversazione" -pinnedList: "Elenco in primo piano" +pinnedList: "Lista in primo piano" keepScreenOn: "Mantenere lo schermo acceso" verifiedLink: "Abbiamo confermato la validità di questo collegamento" notifyNotes: "Notifica nuove Note" @@ -1249,9 +1262,8 @@ showAvatarDecorations: "Mostra decorazione della foto profilo" releaseToRefresh: "Rilascia per aggiornare" refreshing: "Aggiornamento..." pullDownToRefresh: "Trascinare per aggiornare" -disableStreamingTimeline: "Disabilitare gli aggiornamenti della TL in tempo reale" useGroupedNotifications: "Mostra le notifiche raggruppate" -signupPendingError: "Si è verificato un problema durante la verifica del tuo indirizzo email. Potrebbe essere scaduto il collegamento temporaneo." +emailVerificationFailedError: "La verifica dell'indirizzo e-mail non è andata a buon fine. Il link potrebbe essere scaduto." cwNotationRequired: "Devi indicare perché il contenuto è indicato come esplicito." doReaction: "Reagisci" code: "Codice" @@ -1296,7 +1308,7 @@ sensitiveMediaRevealConfirm: "Questo allegato è esplicito, vuoi vederlo?" createdLists: "Liste create" createdAntennas: "Antenne create" fromX: "Da {x}" -genEmbedCode: "Ottieni il codice di incorporamento" +genEmbedCode: "Ottieni il codice per incorporare" noteOfThisUser: "Elenco di Note di questo profilo" clipNoteLimitExceeded: "Non è possibile aggiungere ulteriori Note a questa Clip." performance: "Prestazioni" @@ -1321,13 +1333,15 @@ availableRoles: "Ruoli disponibili" acknowledgeNotesAndEnable: "Attivare dopo averne compreso il comportamento." federationSpecified: "Questo server è federato solo con istanze specifiche del Fediverso. Puoi interagire solo con quelle scelte dall'amministrazione." federationDisabled: "Questo server ha la federazione disabilitata. Non puoi interagire con profili provenienti da altri server." +draft: "Bozza" +draftsAndScheduledNotes: "Bozze e Note pianificate" confirmOnReact: "Confermare le reazioni" reactAreYouSure: "Vuoi davvero reagire con {emoji} ?" markAsSensitiveConfirm: "Vuoi davvero indicare questo contenuto multimediale come esplicito?" unmarkAsSensitiveConfirm: "Vuoi davvero indicare come non esplicito il contenuto multimediale?" preferences: "Preferenze" accessibility: "Accessibilità" -preferencesProfile: "Profilo preferenze" +preferencesProfile: "Preferenze del profilo" copyPreferenceId: "Copia ID preferenze" resetToDefaultValue: "Ripristina a predefinito" overrideByAccount: "Sovrascrivere col profilo" @@ -1338,6 +1352,7 @@ restore: "Ripristina" syncBetweenDevices: "Sincronizzazione tra i dispositivi" preferenceSyncConflictTitle: "Sul server esiste già il valore impostato" preferenceSyncConflictText: "Le impostazione sincronizzata salverà il valore sul server. Però, bada che esiste già un valore sul server. Quale vorresti sovrascrivere?" +preferenceSyncConflictChoiceMerge: "Integra" preferenceSyncConflictChoiceServer: "Valore del server" preferenceSyncConflictChoiceDevice: "Valore del dispositivo" preferenceSyncConflictChoiceCancel: "Annulla la sincronizzazione" @@ -1347,9 +1362,11 @@ postForm: "Finestra di pubblicazione" textCount: "Il numero di caratteri" information: "Informazioni" chat: "Chat" +directMessage: "Chattare insieme" +directMessage_short: "Messaggio" migrateOldSettings: "Migrare le vecchie impostazioni" migrateOldSettings_description: "Di solito, viene fatto automaticamente. Se per qualche motivo non fossero migrate con successo, è possibile avviare il processo di migrazione manualmente, sovrascrivendo le configurazioni attuali." -compress: "Comprimi" +compress: "Compressione" right: "Destra" bottom: "Sotto" top: "Sopra" @@ -1357,7 +1374,55 @@ embed: "Incorporare" settingsMigrating: "Migrazione delle impostazioni. Attendere prego ... (Puoi anche migrare manualmente in un secondo momento, nel menu: Impostazioni → Altro → Migrazione delle impostazioni)" readonly: "Sola lettura" goToDeck: "Torna al Deck" +federationJobs: "Coda di federazione" +driveAboutTip: "Il Drive mostra l'elenco di file caricati in passato. Puoi organizzarli in cartelle, riusarli allegandoli ad altre note, o caricarli in anticipo e poi pubblicarli in un secondo momento. Tieni presente che se elimini un file, non sarà più visibile in nessuno degli oggetti a cui è allegato (Note, pagine, avatar, banner, ecc.)" +scrollToClose: "Scorri per chiudere" +advice: "Consiglio" +realtimeMode: "Modalità in tempo reale" +turnItOn: "Attivare" +turnItOff: "Disattivare" +emojiMute: "Silenzia emoji" +emojiUnmute: "De silenzia emoji" +muteX: "Silenzia {x}" +unmuteX: "De silenzia {x}" +abort: "Annulla" +tip: "Suggerimento" +redisplayAllTips: "Mostra tutti i suggerimenti" +hideAllTips: "Nascondi tutti i suggerimenti" +defaultImageCompressionLevel: "Livello predefinito di compressione immagini" +defaultImageCompressionLevel_description: "La compressione diminuisce la qualità dell'immagine, poca compressione mantiene alta qualità delle immagini. Aumentandola, si riducono le dimensioni del file, a discapito della qualità dell'immagine." +defaultCompressionLevel: "Compressione predefinita" +defaultCompressionLevel_description: "Diminuisci per mantenere la qualità aumentando le dimensioni del file.
Aumenta per ridurre le dimensioni del file e anche la qualità." +inMinutes: "min" +inDays: "giorni" +safeModeEnabled: "La modalità sicura è attiva" +pluginsAreDisabledBecauseSafeMode: "Tutti i plugin sono disattivati, poiché la modalità sicura è attiva." +customCssIsDisabledBecauseSafeMode: "Il CSS personalizzato non è stato applicato, poiché la modalità sicura è attiva." +themeIsDefaultBecauseSafeMode: "Quando la modalità sicura è attiva, viene utilizzato il tema predefinito. Quando la modalità sicura viene disattivata, il tema torna a essere quello precedente." +thankYouForTestingBeta: "Grazie per la tua collaborazione nella verifica delle versioni beta!" +createUserSpecifiedNote: "Crea Nota privata" +schedulePost: "Pianificare la pubblicazione" +scheduleToPostOnX: "Pianificare la pubblicazione {x}" +scheduledToPostOnX: "Pubblicazione pianificata {x}" +schedule: "Pianificare" +scheduled: "Pianificata" +widgets: "Riquadri" +deviceInfo: "Informazioni sul dispositivo" +deviceInfoDescription: "Se ci contatti per ricevere supporto tecnico, ti preghiamo di includere le seguenti informazioni per aiutarci a risolvere il tuo problema." +_compression: + _quality: + high: "Alta qualità" + medium: "Media qualità" + low: "Bassa qualità" + _size: + large: "Taglia grande" + medium: "Taglia media" + small: "Taglia piccola" +_order: + newest: "Prima i più recenti" + oldest: "Meno recenti prima" _chat: + messages: "Messaggi" noMessagesYet: "Ancora nessun messaggio" newMessage: "Nuovo messaggio" individualChat: "Chat individuale" @@ -1368,12 +1433,12 @@ _chat: inviteUserToChat: "Invita a chattare altre persone" yourRooms: "Le tue stanze" joiningRooms: "Stanze a cui partecipi" - invitations: "Invita" + invitations: "Inviti" noInvitations: "Nessun invito" history: "Cronologia" noHistory: "Nessuna cronologia" noRooms: "Nessuna stanza" - inviteUser: "Invita" + inviteUser: "Invita persona" sentInvitations: "Inviti spediti" join: "Entra" ignore: "Ignora" @@ -1390,6 +1455,8 @@ _chat: chatNotAvailableInOtherAccount: "La chat non è disponibile nel profilo dell'altra persona." cannotChatWithTheUser: "Impossibile chattare con questa persona" cannotChatWithTheUser_description: "La chat potrebbe non essere disponibile, oppure l'altra persona potrebbe non esserlo." + youAreNotAMemberOfThisRoomButInvited: "Non partecipi a questa stanza di chat, ma hai ricevuto un invito. Per partecipare, accetta l'invito." + doYouAcceptInvitation: "Intendi accettare l'invito?" chatWithThisUser: "Chatta con questa persona" thisUserAllowsChatOnlyFromFollowers: "Questa persona permette di chattare soltanto i propri Follower." thisUserAllowsChatOnlyFromFollowing: "Questa persona permette di chattare soltanto ai suoi Follow." @@ -1429,10 +1496,21 @@ _settings: makeEveryTextElementsSelectable: "Imposta ogni elemento come selezionabile" makeEveryTextElementsSelectable_description: "Potrebbe ridurre l'usabilità in alcune situazioni." useStickyIcons: "Fissa le icone durante lo scorrimento" + enableHighQualityImagePlaceholders: "Mostra un segnaposto per immagini in alta qualità" + uiAnimations: "Animazione dell'interfaccia" showNavbarSubButtons: "Mostra i pulsanti secondari nella barra di navigazione" ifOn: "Quando attivato" ifOff: "Quando disattivato" enableSyncThemesBetweenDevices: "Sincronizzare il tema tra i dispositivi" + enablePullToRefresh: "Scorri e aggiorna" + enablePullToRefresh_description: "Clicca col mouse e gira la rotella." + realtimeMode_description: "Connette al server e aggiorna il contenuto in tempo reale. Potrebbe aumentare l'uso dei dati e il consumo della batteria." + contentsUpdateFrequency: "Frequenza di ricezione contenuti" + contentsUpdateFrequency_description: "Se l'impostazione è alta, verranno aggiornati più frequentemente, consumando più dati e più batteria." + contentsUpdateFrequency_description2: "Quando la modalità è in tempo reale, arriveranno a prescindere." + showUrlPreview: "Mostra anteprima dell'URL" + showAvailableReactionsFirstInNote: "Mostra le reazioni disponibili in alto" + showPageTabBarBottom: "Visualizza le schede della pagina nella parte inferiore" _chat: showSenderName: "Mostra il nome del mittente" sendOnEnter: "Invio spedisce" @@ -1440,6 +1518,7 @@ _preferencesProfile: profileName: "Nome del profilo" profileNameDescription: "Impostare il nome che indentifica questo dispositivo." profileNameDescription2: "Es: \"PC principale\" o \"Cellulare\"" + manageProfiles: "Gestione profili" _preferencesBackup: autoBackup: "Backup automatico" restoreFromBackup: "Ripristinare da backup" @@ -1478,6 +1557,7 @@ _delivery: manuallySuspended: "Sospesa manualmente" goneSuspended: "Sospensione server a causa dell'eliminazione" autoSuspendedForNotResponding: "Sospensione del server a causa di mancata risposta" + softwareSuspended: "Attualmente non disponibile perché il software non è più distribuito" _bubbleGame: howToPlay: "Come giocare" hold: "Tieni" @@ -1604,11 +1684,37 @@ _serverSettings: fanoutTimelineDbFallback: "Elaborazione dati alternativa" fanoutTimelineDbFallbackDescription: "Attivando l'elaborazione alternativa, verrà interrogato ulteriormente il database se la timeline non è nella cache. \nDisattivando, si può ridurre ulteriormente il carico del server, evitando l'elaborazione alternativa, ma limitando l'intervallo recuperabile delle timeline." reactionsBufferingDescription: "Attivando questa opzione, puoi migliorare significativamente le prestazioni durante la creazione delle reazioni e ridurre il carico sul database. Tuttavia, aumenterà l'impiego di memoria Redis." + remoteNotesCleaning: "Pulizia automatica dei contenuti remoti" + remoteNotesCleaning_description: "Se abilitata, verranno periodicamente rimosse le vecchie Note remote senza relazioni, per ridurre il sovraccarico del sistema." + remoteNotesCleaningMaxProcessingDuration: "Durata massima del processo di pulizia" + remoteNotesCleaningExpiryDaysForEachNotes: "Periodo minimo di conservazione delle note" inquiryUrl: "URL di contatto" inquiryUrlDescription: "Specificare l'URL al modulo di contatto, oppure le informazioni con i dati di contatto dell'amministrazione." openRegistration: "Registrazioni aperte" openRegistrationWarning: "L’apertura della registrazione comporta dei rischi. Ti consigliamo di attivarla solo se hai predisposto il monitoraggio continuo del tuo server e puoi rispondere immediatamente se si verifica un problema." thisSettingWillAutomaticallyOffWhenModeratorsInactive: "Per prevenire SPAM, questa impostazione verrà disattivata automaticamente, se non si rileva alcuna attività di moderazione durante un certo periodo di tempo." + deliverSuspendedSoftware: "Software fuori produzione" + deliverSuspendedSoftwareDescription: "A causa di vulnerabilità o altri motivi, puoi interrompere la distribuzione di un software da un server specificandone il nome e la versione. Le informazioni sono fornite dall'altro server e l'autenticità non è garantita. Puoi indicare un intervallo di versione semantica, ma specificando >= 2024.3.1 non verranno incluse le versioni personalizzate come ad esempio 2024.3.1-custom.0, pertanto ti consigliamo di specificare una versione come >= 2024.3.1-0." + singleUserMode: "Modalità utente singolo" + singleUserMode_description: "Se sei l'unica persona a utilizzare questo server, l'abilitazione di questa modalità ottimizzerà le prestazioni." + signToActivityPubGet: "Firma delle richieste GET" + signToActivityPubGet_description: "Normalmente questa opzione dovrebbe essere abilitata. Se si verificano problemi con la comunicazione federata, disabilitarla potrebbe migliorare la situazione, ma d'altro canto potrebbe rendere impossibile la comunicazione, a seconda del server." + proxyRemoteFiles: "Proxy di file remoti" + proxyRemoteFiles_description: "Se abilitato, i file remoti verranno serviti tramite proxy. Utile per generare miniature delle immagini e proteggere la privacy degli utenti." + allowExternalApRedirect: "Consenti reindirizzamenti per le query tramite ActivityPub" + allowExternalApRedirect_description: "Se abilitata, consente ad altri server di interrogare contenuti di terze parti tramite il tuo server, con conseguente potenziale falsificazione dei contenuti." + userGeneratedContentsVisibilityForVisitor: "Visibilità dei contenuti generati dagli utenti ai non utenti" + userGeneratedContentsVisibilityForVisitor_description: "Questa funzionalità è utile per impedire che contenuti remoti inappropriati e difficili da moderare vengano inavvertitamente resi pubblici su Internet tramite il proprio server." + userGeneratedContentsVisibilityForVisitor_description2: "Esistono dei rischi nell'esporre incondizionatamente su internet tutto il contenuto del tuo server, incluso il contenuto remoto ricevuto da altri server. In particolare, occorre prestare attenzione, perché le persone non consapevoli della federazione potrebbero erroneamente credere che il contenuto remoto sia stato invece creato all'interno del proprio server." + restartServerSetupWizardConfirm_title: "Vuoi ripetere la procedura guidata di configurazione iniziale del server?" + restartServerSetupWizardConfirm_text: "Verranno ripristinate alcune tue impostazioni personalizzate." + entrancePageStyle: "Stile della pagina di ingresso" + showTimelineForVisitor: "Mostra la Timeline a visitatori non autenticati" + showActivitiesForVisitor: "Mostrare la propria attività" + _userGeneratedContentsVisibilityForVisitor: + all: "Tutto pubblico" + localOnly: "Pubblica solo contenuti locali, mantieni privati ​​i contenuti remoti" + none: "Tutto privato" _accountMigration: moveFrom: "Migra un altro profilo dentro a questo" moveFromSub: "Crea un alias verso un altro profilo remoto" @@ -1929,6 +2035,8 @@ _role: canManageCustomEmojis: "Gestire le emoji personalizzate" canManageAvatarDecorations: "Gestisce le decorazioni di immagini del profilo" driveCapacity: "Capienza del Drive" + maxFileSize: "Dimensione massima del file caricabile" + maxFileSize_caption: "Potrebbero esserci altre impostazioni nella fase precedente, come reverse proxy o CDN." alwaysMarkNsfw: "Impostare sempre come esplicito (NSFW)" canUpdateBioMedia: "Può aggiornare foto profilo e di testata" pinMax: "Quantità massima di Note in primo piano" @@ -1943,6 +2051,7 @@ _role: descriptionOfRateLimitFactor: "I rapporti più bassi sono meno restrittivi, quelli più alti lo sono di più." canHideAds: "Nascondere i banner" canSearchNotes: "Ricercare nelle Note" + canSearchUsers: "Può cercare profili" canUseTranslator: "Tradurre le Note" avatarDecorationLimit: "Numero massimo di decorazioni foto profilo installabili" canImportAntennas: "Può importare Antenne" @@ -1951,6 +2060,12 @@ _role: canImportMuting: "Può importare Silenziati" canImportUserLists: "Può importare liste di Profili" chatAvailability: "Chat consentita" + uploadableFileTypes: "Tipi di file caricabili" + uploadableFileTypes_caption: "Specifica il tipo MIME. Puoi specificare più valori separandoli andando a capo, oppure indicare caratteri jolly con un asterisco (*). Ad esempio: image/*" + uploadableFileTypes_caption2: "A seconda del file, il tipo potrebbe non essere determinato. Se si desidera consentire tali file, aggiungere {x} alla specifica." + noteDraftLimit: "Numero massimo di Note in bozza, lato server" + scheduledNoteLimit: "Quantità di Note pianificabili contemporaneamente" + watermarkAvailable: "Disponibilità della funzione filigrana" _condition: roleAssignedTo: "Assegnato a ruoli manualmente" isLocal: "Profilo locale" @@ -2176,6 +2291,7 @@ _theme: install: "Installa un tema" manage: "Gestione dei temi" code: "Codice tema" + copyThemeCode: "Copia il codice del Tema" description: "Descrizione" installed: "{name} è installato" installedThemes: "Temi installati" @@ -2219,7 +2335,7 @@ _theme: hashtag: "Hashtag" mention: "Menzioni" mentionMe: "Menzioni (di me)" - renote: "Renota" + renote: "Rinota" modalBg: "Sfondo modale." divider: "Interruzione di linea" scrollbarHandle: "Maniglie della barra di scorrimento" @@ -2234,7 +2350,6 @@ _theme: buttonBg: "Sfondo del pulsante" buttonHoverBg: "Sfondo del pulsante (sorvolato)" inputBorder: "Inquadra casella di testo" - driveFolderBg: "Sfondo della cartella di disco" badge: "Distintivo" messageBg: "Sfondo della chat" fgHighlighted: "Testo in evidenza." @@ -2276,6 +2391,7 @@ _time: minute: "min" hour: "ore" day: "giorni" + month: "Mese" _2fa: alreadyRegistered: "La configurazione è stata già completata." registerTOTP: "Registra una App di autenticazione a due fattori (2FA/MFA)" @@ -2405,6 +2521,7 @@ _auth: scopeUser: "Sto funzionando per il seguente profilo" pleaseLogin: "Per favore accedi al tuo account per cambiare i permessi dell'applicazione" byClickingYouWillBeRedirectedToThisUrl: "Consentendo l'accesso, si verrà reindirizzati presso questo indirizzo URL" + alreadyAuthorized: "Questa applicazione è già autorizzata ad accedere." _antennaSources: all: "Tutte le note" homeTimeline: "Note dai tuoi Following" @@ -2451,7 +2568,7 @@ _widgets: chooseList: "Seleziona una lista" clicker: "Cliccheria" birthdayFollowings: "Compleanni del giorno" - chat: "Chat" + chat: "Chatta con questa persona" _cw: hide: "Nascondere" show: "Continua la lettura..." @@ -2491,6 +2608,8 @@ _visibility: disableFederation: "Senza federazione" disableFederationDescription: "Non spedire attività alle altre istanze remote" _postForm: + quitInspiteOfThereAreUnuploadedFilesConfirm: "Alcuni file non sono stati caricati. Vuoi annullare l'operazione?" + uploaderTip: "Il file non è ancora stato caricato. Nel menu file (tre puntini), puoi ritagliare l'immagine, mettere la filigrana, decidere la presenza o l'assenza di compressione... Il file verrà caricato automaticamente quando pubblichi la Nota." replyPlaceholder: "Rispondi a questa nota..." quotePlaceholder: "Cita questa nota..." channelPlaceholder: "Pubblica sul canale..." @@ -2641,6 +2760,8 @@ _notification: yourFollowRequestAccepted: "La tua richiesta di follow è stata accettata" youWereInvitedToGroup: "{userName} Invitat@ al gruppo" pollEnded: "Risultati del sondaggio." + scheduledNotePosted: "Pubblicazione Nota pianificata" + scheduledNotePostFailed: "Impossibile pubblicare la Nota pianificata" newNote: "Nuove Note" unreadAntennaNote: "Antenna {name}" roleAssigned: "Ruolo assegnato" @@ -2661,7 +2782,7 @@ _notification: createToken: "È stato creato un token di accesso" createTokenDescription: "In caso contrario, eliminare il token di accesso tramite ({text})." _types: - all: "Tutto" + all: "Tutte" note: "Nuove Note" follow: "Follower" mention: "Menzioni" @@ -2669,7 +2790,9 @@ _notification: renote: "Rinota" quote: "Cita" reaction: "Reazioni" - pollEnded: "Sondaggio chiuso." + pollEnded: "Sondaggio terminato" + scheduledNotePosted: "Nota pianificata correttamente" + scheduledNotePostFailed: "La pianificazione della Nota è fallita" receiveFollowRequest: "Richieste di follow in arrivo" followRequestAccepted: "Richieste di follow accettate" groupInvited: "Invito a un gruppo" @@ -2678,7 +2801,7 @@ _notification: achievementEarned: "Risultato raggiunto" exportCompleted: "Esportazione completata" login: "Accessi" - createToken: "Creare un token di accesso" + createToken: "Aggiunto un token di accesso" test: "Notifiche di test" app: "Notifiche da applicazioni" _actions: @@ -2686,7 +2809,7 @@ _notification: reply: "Rispondi" renote: "Rinota" _deck: - alwaysShowMainColumn: "Mostra sempre la colonna principale" + alwaysShowMainColumn: "Mostrare sempre la colonna Principale" columnAlign: "Allineamento delle colonne" columnGap: "Spessore del margine tra colonne" deckMenuPosition: "Posizione del menu Deck" @@ -2703,8 +2826,8 @@ _deck: profile: "Profilo" newProfile: "Nuovo profilo" deleteProfile: "Cancellare il profilo." - introduction: "Combinate le colonne per creare la vostra interfaccia!" - introduction2: "È possibile aggiungere colonne in qualsiasi momento premendo + sulla destra dello schermo." + introduction: "Crea la tua interfaccia combinando le colonne!" + introduction2: "Per aggiungere una colonna, cliccare il bottone + (più) visibile al margine dello schermo." widgetsIntroduction: "Dal menu della colonna, selezionare \"Modifica i riquadri\" per aggiungere un un riquadro con funzionalità" useSimpleUiForNonRootPages: "Visualizza sotto pagine con interfaccia web semplice" usedAsMinWidthWhenFlexible: "Se \"larghezza flessibile\" è abilitato, questa diventa la larghezza minima" @@ -2721,7 +2844,7 @@ _deck: mentions: "Menzioni" direct: "Note Dirette" roleTimeline: "Timeline Ruolo" - chat: "Chat" + chat: "Chatta con questa persona" _dialog: charactersExceeded: "Hai superato il limite di {max} caratteri! ({current})" charactersBelow: "Sei al di sotto del minimo di {min} caratteri! ({current})" @@ -2770,56 +2893,56 @@ _abuseReport: notifiedWebhook: "Webhook da usare" deleteConfirm: "Vuoi davvero rimuovere il destinatario della notifica?" _moderationLogTypes: - createRole: "Ruolo creato" - deleteRole: "Ruolo eliminato" - updateRole: "Ruolo aggiornato" - assignRole: "Ruolo assegnato" - unassignRole: "Ruolo disassegnato" - suspend: "Sospensione" - unsuspend: "Sospensione rimossa" - addCustomEmoji: "Emoji personalizzata aggiunta" - updateCustomEmoji: "Emoji personalizzata aggiornata" - deleteCustomEmoji: "Emoji personalizzata eliminata" - updateServerSettings: "Impostazioni del server aggiornate" - updateUserNote: "Promemoria di moderazione aggiornato" - deleteDriveFile: "File da Drive eliminato" - deleteNote: "Nota eliminata" - createGlobalAnnouncement: "Annuncio globale creato" - createUserAnnouncement: "Annuncio ai profili iscritti creato" - updateGlobalAnnouncement: "Annuncio globale aggiornato" - updateUserAnnouncement: "Annuncio ai profili iscritti aggiornato" - deleteGlobalAnnouncement: "Annuncio globale eliminato" - deleteUserAnnouncement: "Annuncio ai profili iscritti eliminato" - resetPassword: "Password azzerata" - suspendRemoteInstance: "Istanza remota sospesa" - unsuspendRemoteInstance: "Istanza remota riattivata" - updateRemoteInstanceNote: "Aggiornamento del promemoria di moderazione per il server remoto" - markSensitiveDriveFile: "File nel Drive segnato come esplicito" - unmarkSensitiveDriveFile: "File nel Drive segnato come non esplicito" - resolveAbuseReport: "Segnalazione risolta" - forwardAbuseReport: "Segnalazione inoltrata" - updateAbuseReportNote: "Ha aggiornato la segnalazione" - createInvitation: "Genera codice di invito" - createAd: "Banner creato" - deleteAd: "Banner eliminato" - updateAd: "Banner aggiornato" - createAvatarDecoration: "Creazione decorazione della foto profilo" - updateAvatarDecoration: "Aggiornamento decorazione foto profilo" - deleteAvatarDecoration: "Eliminazione decorazione della foto profilo" - unsetUserAvatar: "Rimossa foto profilo" - unsetUserBanner: "Rimossa intestazione profilo" - createSystemWebhook: "Crea un SystemWebhook" - updateSystemWebhook: "Modifica SystemWebhook" - deleteSystemWebhook: "Elimina SystemWebhook" + createRole: "Crea un Ruolo" + deleteRole: "Elimina un Ruolo" + updateRole: "Modifica un ruolo" + assignRole: "Assegna un Ruolo" + unassignRole: "Toglie un Ruolo al Profilo" + suspend: "Sospende" + unsuspend: "Solleva la sospensione" + addCustomEmoji: "Aggiunge Emoji personalizzata" + updateCustomEmoji: "Modifica Emoji personalizzata" + deleteCustomEmoji: "Elimina Emoji personalizzata" + updateServerSettings: "Modifica le impostazioni del server" + updateUserNote: "Modifica un promemoria di moderazione" + deleteDriveFile: "Elimina un file dal Drive" + deleteNote: "Elimina una Nota" + createGlobalAnnouncement: "Crea un annuncio globale" + createUserAnnouncement: "Crea un annuncio ai profili già iscritti" + updateGlobalAnnouncement: "Modifica un annuncio globale" + updateUserAnnouncement: "Modifica un annuncio ai profili già iscritti" + deleteGlobalAnnouncement: "Elimina un annuncio globale" + deleteUserAnnouncement: "Elimina un annuncio ai profili già iscritti" + resetPassword: "Azzera la password" + suspendRemoteInstance: "Sospende una istanza remota" + unsuspendRemoteInstance: "Riattiva una istanza remota" + updateRemoteInstanceNote: "Modifica il promemoria di moderazione per il server remoto" + markSensitiveDriveFile: "Aggiunge NSFW a un file nel Drive" + unmarkSensitiveDriveFile: "Toglie NSFW da un file nel Drive" + resolveAbuseReport: "Risolve una segnalazione" + forwardAbuseReport: "Inoltra una segnalazione" + updateAbuseReportNote: "Modifica una segnalazione" + createInvitation: "Genera un codice di invito" + createAd: "Aggiunge un Banner" + deleteAd: "Elimina un Banner" + updateAd: "Modifica un Banner" + createAvatarDecoration: "Crea una decorazione della foto profilo" + updateAvatarDecoration: "Modifica una decorazione della foto profilo" + deleteAvatarDecoration: "Elimina una decorazione della foto profilo" + unsetUserAvatar: "Toglie una foto profilo" + unsetUserBanner: "Toglie una immagine di intestazione profilo" + createSystemWebhook: "Aggiunge un System Webhook" + updateSystemWebhook: "Modifica un System Webhook" + deleteSystemWebhook: "Elimina un System Webhook" createAbuseReportNotificationRecipient: "Crea destinatario per le notifiche di segnalazioni" - updateAbuseReportNotificationRecipient: "Aggiorna destinatario notifiche di segnalazioni" - deleteAbuseReportNotificationRecipient: "Elimina destinatario notifiche di segnalazioni" - deleteAccount: "Quando viene eliminato un profilo" - deletePage: "Pagina eliminata" - deleteFlash: "Play eliminato" - deleteGalleryPost: "Eliminazione pubblicazione nella Galleria" - deleteChatRoom: "Elimina chat" - updateProxyAccountDescription: "Aggiornata la descrizione del profilo proxy" + updateAbuseReportNotificationRecipient: "Modifica un destinatario per le notifiche di segnalazioni" + deleteAbuseReportNotificationRecipient: "Elimina un destinatario per le notifiche di segnalazioni" + deleteAccount: "Elimina un profilo" + deletePage: "Elimina una Pagina" + deleteFlash: "Elimina un Play" + deleteGalleryPost: "Elimina pubblicazione nella Galleria" + deleteChatRoom: "Elimina una Chat" + updateProxyAccountDescription: "Aggiorna la descrizione del profilo proxy" _fileViewer: title: "Dettagli del file" type: "Tipo di file" @@ -2827,6 +2950,7 @@ _fileViewer: url: "URL" uploadedAt: "Caricato il" attachedNotes: "Note a cui è allegato" + usage: "In uso" thisPageCanBeSeenFromTheAuthor: "Questa pagina può essere vista solo da chi ha caricato il file." _externalResourceInstaller: title: "Installa da sito esterno" @@ -2874,9 +2998,12 @@ _dataSaver: _avatar: title: "Immagine del profilo" description: "Impedire l'animazione per l'immagine del profilo. Le immagini animate possono avere dimensioni file maggiori rispetto a quelle normali, puoi ridurre ulteriormente l'utilizzo dei dati." - _urlPreview: - title: "Anteprime delle URL" - description: "Impedire il caricamento delle anteprime URL." + _urlPreviewThumbnail: + title: "Nascondi le miniature nell'anteprima URL" + description: "Le immagini in miniatura nell'anteprima URL non verranno più caricate." + _disableUrlPreview: + title: "Disabilita l'anteprima URL" + description: "Disabilita la funzione di anteprima URL. A differenza di una semplice immagine in miniatura, questo riduce il tempo necessario per caricare le informazioni collegate." _code: title: "Codice evidenziato" description: "Impedire che il codice sorgente sia automaticamente evidenziato. Evidenziare il codice richiede il caricamento di un file per ogni linguaggio. Puoi evidenziare soltanto il codice che intendi leggere e ridurre il traffico inutilizzato." @@ -2934,6 +3061,8 @@ _offlineScreen: _urlPreviewSetting: title: "Impostazioni per l'anteprima delle URL" enable: "Attiva l'anteprima delle URL" + allowRedirect: "Segui i reindirizzamenti per visualizzare le anteprime" + allowRedirectDescription: "Se la URL inserita contiene un reindirizzamento, decidi di seguire il reindirizzamento fino alla destinazione, visualizzandone l'anteprima. Disabilitando questa opzione si risparmiano risorse del server, ma il contenuto effettivo dal reindirizzamento, non verrà visualizzato." timeout: "Timeout dell'anteprima in millisecondi" timeoutDescription: "Impegna al massimo il tempo indicato, altrimenti ignora l'anteprima" maximumContentLength: "Grandezza del contenuto (Content-Length in byte)" @@ -3007,15 +3136,11 @@ _customEmojisManager: uploadSettingDescription: "Questa schermata ti permette di scegliere il comportamento durante il caricamento delle emoji." directoryToCategoryLabel: "Inseriscile in una cartella omonima alla categoria" directoryToCategoryCaption: "Crea il campo categoria in base alla cartella." - emojiInputAreaCaption: "Seleziona l'emoji da registrare utilizzando uno dei metodi." - emojiInputAreaList1: "Trascinare una immagine o una cartella in quest'area" - emojiInputAreaList2: "Clicca per scegliere file dal tuo dispositivo" - emojiInputAreaList3: "Clicca per selezionare dal Drive" confirmRegisterEmojisDescription: "Registrazione delle emoji elencate come nuove emoji personalizzate. Vuoi davvero procedere? (Per evitare sovraccarichi, puoi registrare al massimo {count} emoji per volta)" confirmClearEmojisDescription: "Annullare le modifiche e cancella le emoji nell'elenco. Confermi?" confirmUploadEmojisDescription: "Caricamento sul Drive di {count} file locali. Vuoi davvero procedere?" _embedCodeGen: - title: "Personalizza il codice di incorporamento" + title: "Personalizza il codice per incorporare" header: "Mostra la testata" autoload: "Carica automaticamente di più (sconsigliato)" maxHeight: "Altezza massima" @@ -3024,8 +3149,8 @@ _embedCodeGen: previewIsNotActual: "Poiché supera l'intervallo che può essere visualizzato in anteprima, la visualizzazione vera e propria sarà diversa quando effettivamente incorporata." rounded: "Bordo arrotondato" border: "Aggiungi un bordo al contenitore" - applyToPreview: "Applica all'anteprima" - generateCode: "Crea il codice di incorporamento" + applyToPreview: "Aggiorna l'anteprima" + generateCode: "Crea il codice per incorporare" codeGenerated: "Codice generato" codeGeneratedDescription: "Incolla il codice appena generato sul tuo sito web." _selfXssPrevention: @@ -3078,6 +3203,7 @@ _bootErrors: otherOption1: "Nelle impostazioni, cancellare le impostazioni del client e svuotare la cache" otherOption2: "Avviare il client predefinito" otherOption3: "Avviare lo strumento di riparazione" + otherOption4: "Avvia CherryPick in modalità sicura" _search: searchScopeAll: "Tutte" searchScopeLocal: "Locale" @@ -3086,3 +3212,194 @@ _search: pleaseEnterServerHost: "Inserire il nome host" pleaseSelectUser: "Per favore, seleziona un profilo" serverHostPlaceholder: "Es: cherrypick.example.com" +_serverSetupWizard: + installCompleted: "L'installazione di CherryPick è completata!" + firstCreateAccount: "Per prima cosa, crea un account amministratore." + accountCreated: "Il tuo account amministratore è stato creato!" + serverSetting: "Configurazione del server" + youCanEasilyConfigureOptimalServerSettingsWithThisWizard: "Questa procedura guidata ti aiuterà a configurare facilmente il tuo server in modo ottimale." + settingsYouMakeHereCanBeChangedLater: "Potrai anche modificare le impostazioni in seguito." + howWillYouUseMisskey: "Come si usa CherryPick?" + _use: + single: "Modalità utenza singola" + single_description: "Se intendi usarlo come tuo server personale" + single_youCanCreateMultipleAccounts: "Anche se lo utilizzi come server per una sola persona, puoi creare più account in base alle tue esigenze." + group: "Modalità multi utentza" + group_description: "Invita altre persone fidate ad usare il server insieme a te" + open: "Server aperto" + open_description: "Per ospitare un numero imprecisato di persone" + openServerAdvice: "Ospitare un numero imprecisato di persone comporta dei rischi. Ti consigliamo di adottare un solido sistema di moderazione, in modo da poter gestire eventuali problemi che potrebbero presentarsi pubblicando contenuti proposti da altre persone, che potrebbero essere sconosciute." + openServerAntiSpamAdvice: "Presta molta attenzione alla sicurezza, ad esempio attivando funzionalità anti-bot (iscrizioni automatiche) come reCAPTCHA. Questo può evitare che il tuo server diventi un trampolino di lancio per lo spam di altri." + howManyUsersDoYouExpect: "Quante persone pensi che parteciperanno?" + _scale: + small: "100 persone o meno (piccolo)" + medium: "Da 100 a 1000 persone (medio)" + large: "Oltre 1000 persone (grande)" + largeScaleServerAdvice: "Configurare grandi server potrebbe richiedere conoscenze infrastrutturali avanzate, ad esempio, il bilanciamento del carico e la replicazione del database." + doYouConnectToFediverse: "Vuoi connetterti al Fediverso?" + doYouConnectToFediverse_description1: "Collegandosi a una rete di server distribuiti, denominata Fediverso, potrai scambiare contenuti con altri server, tramite il protocollo di comunicazione ActivityPub." + doYouConnectToFediverse_description2: "Connettersi al Fediverso è anche detto \"federazione\"." + youCanConfigureMoreFederationSettingsLater: "Puoi svolgere la configurazione avanzata anche dopo. Ad esempio specificando quali server possono federarsi." + remoteContentsCleaning: "Pulizia automatica dei contenuti in arrivo" + remoteContentsCleaning_description: "Con la federazione funzionante, riceverai sempre più contenuti. Abilitando la pulizia automatica, i contenuti non referenziati e obsoleti verranno rimossi automaticamente dai tuoi server, risparmiando spazio di archiviazione." + adminInfo: "Informazioni sull'amministratore" + adminInfo_description: "Imposta le informazioni dell'amministratore utilizzate per accettare le richieste." + adminInfo_mustBeFilled: "Questa operazione è necessaria su un server aperto o se è attiva la federazione." + followingSettingsAreRecommended: "Si consigliano le seguenti impostazioni:" + applyTheseSettings: "Applica questa impostazione" + skipSettings: "Salta l'installazione" + settingsCompleted: "Installazione completata!" + settingsCompleted_description: "Grazie per il tuo impegno. Adesso che hai completato la configurazione, puoi iniziare a utilizzare il tuo server." + settingsCompleted_description2: "Le impostazioni dettagliate del server possono essere effettuate tramite il Pannello di controllo." + donationRequest: "Per favore Fai una donazione" + _donationRequest: + text1: "CherryPick è un software libero sviluppato da volontari." + text2: "Se puoi, ti preghiamo di prendere in considerazione l'idea di fare una donazione, così potremo continuare a sviluppare." + text3: "Sono previsti anche dei vantaggi speciali per i sostenitori!" +_uploader: + editImage: "Modifica immagine" + compressedToX: "Compresso in {x}" + savedXPercent: "{x}% risparmiati" + abortConfirm: "Alcuni file non sono stati caricati. Vuoi annullare l'operazione?" + doneConfirm: "Alcuni file non sono stati caricati. Vuoi completarli?" + maxFileSizeIsX: "La dimensione massima del file che puoi caricare è {x}." + allowedTypes: "Tipi di file caricabili" + tip: "Il file non è ancora stato caricato. Puoi controllare, rinominare, comprimere, ritagliare, prima del caricamento. Quando hai finito, premi il bottone \"Carica\" ​​per completare." +_clientPerformanceIssueTip: + title: "Se ritieni che la batteria si stia scaricando troppo" + makeSureDisabledAdBlocker: "Disattiva il tuo AdBlocker" + makeSureDisabledAdBlocker_description: "Gli AdBlocker possono influire sulle prestazioni. Controlla se nel tuo sistema operativo, nel browser o nei componenti aggiuntivi è abilitato un AdBlocker." + makeSureDisabledCustomCss: "Disabilita CSS personalizzato" + makeSureDisabledCustomCss_description: "La riscrittura degli stili CSS può influire sulle prestazioni. Assicurati di non avere CSS personalizzati o estensioni abilitate che sovrascrivano i tuoi stili." + makeSureDisabledAddons: "Disabilitare le estensioni" + makeSureDisabledAddons_description: "Alcune estensioni potrebbero interferire con il funzionamento del client e comprometterne le prestazioni. Prova a disattivare le estensioni del browser e vedi se il problema persiste." +_clip: + tip: "Le clip sono una funzionalità che consente di raggruppare le Note." +_userLists: + tip: "Puoi creare un elenco di Note create da qualsiasi profilo. L'elenco è visualizzato come una sequenza temporale." +watermark: "Filigrana" +defaultPreset: "Impostazioni predefinite" +_watermarkEditor: + tip: "Puoi aggiungere una filigrana, ad esempio con i crediti alle tue immagini." + quitWithoutSaveConfirm: "Uscire senza salvare?" + driveFileTypeWarn: "Formato file non supportato" + driveFileTypeWarnDescription: "Per favore seleziona un file immagine" + title: "Modifica la filigrana" + cover: "Coprire tutto" + repeat: "Disposizione" + opacity: "Opacità" + scale: "Dimensioni" + text: "Testo" + qr: "QR Code" + position: "Posizione" + margin: "Margine" + type: "Tipo" + image: "Immagini" + advanced: "Avanzato" + angle: "Angolo" + stripe: "Strisce" + stripeWidth: "Larghezza della linea" + stripeFrequency: "Il numero di linee" + polkadot: "A pallini" + checker: "revisore" + polkadotMainDotOpacity: "Opacità del punto principale" + polkadotMainDotRadius: "Dimensione del punto principale" + polkadotSubDotOpacity: "Opacità del punto secondario" + polkadotSubDotRadius: "Dimensione del punto secondario" + polkadotSubDotDivisions: "Quantità di punti secondari" + leaveBlankToAccountUrl: "Il valore vuoto indica la URL dell'account" +_imageEffector: + title: "Effetto" + addEffect: "Aggiungi effetto" + discardChangesConfirm: "Scarta le modifiche ed esci?" + nothingToConfigure: "Nessuna impostazione configurabile." + _fxs: + chromaticAberration: "Aberrazione cromatica" + glitch: "Glitch" + mirror: "Specchio" + invert: "Inversione colore" + grayscale: "Bianco e nero" + blur: "Sfocatura" + pixelate: "Mosaico" + colorAdjust: "Correzione Colore" + colorClamp: "Compressione del colore" + colorClampAdvanced: "Compressione del colore (avanzata)" + distort: "Distorsione" + threshold: "Soglia" + zoomLines: "Linea di saturazione" + stripe: "Strisce" + polkadot: "A pallini" + checker: "revisore" + blockNoise: "Attenua rumore" + tearing: "Strappa immagine" + fill: "Riempimento" + _fxProps: + angle: "Angolo" + scale: "Dimensioni" + size: "Dimensioni" + radius: "Raggio" + samples: "Quantità di campioni" + offset: "Posizione" + color: "Colore" + opacity: "Opacità" + normalize: "Normalizza" + amount: "Quantità" + lightness: "Chiaro" + contrast: "Contrasto" + hue: "Tinta" + brightness: "Luminosità" + saturation: "Saturazione" + max: "Valore massimo" + min: "Valore minimo" + direction: "Orientamento" + phase: "Fasare" + frequency: "Frequenza" + strength: "Forza" + glitchChannelShift: "Glitch cambio canale" + seed: "Seme" + redComponent: "Rosso composito" + greenComponent: "Verde composito" + blueComponent: "Blu composito" + threshold: "Soglia" + centerX: "Centro orizzontale" + centerY: "Centro verticale" + zoomLinesSmoothing: "Levigatura" + zoomLinesSmoothingDescription: "Non si possono usare insieme la levigatura e la larghezza della linea centrale." + zoomLinesThreshold: "Limite delle linee zoom" + zoomLinesMaskSize: "Ampiezza del diametro" + zoomLinesBlack: "Bande nere" + circle: "Circolare" +drafts: "Bozze" +_drafts: + select: "Selezionare bozza" + cannotCreateDraftAnymore: "Hai superato il numero massimo di bozze ammissibili." + cannotCreateDraft: "Impossibile creare una bozza di questo contenuto." + delete: "Elimina bozza" + deleteAreYouSure: "Vuoi davvero eliminare la bozza?" + noDrafts: "Non c'è nessuna bozza." + replyTo: "Rispondere a {user}" + quoteOf: "Citare la nota di {user}" + postTo: "Inserire in {channel}" + saveToDraft: "Salva come bozza" + restoreFromDraft: "Recuperare dalle bozze" + restore: "Ripristina" + listDrafts: "Elenco bozze" + schedule: "Pianifica pubblicazione" + listScheduledNotes: "Elenca Note pianificate" + cancelSchedule: "Annulla pianificazione" +qr: "QR Code" +_qr: + showTabTitle: "Visualizza" + readTabTitle: "Leggere" + shareTitle: "{name} {acct}" + shareText: "Seguimi nel Fediverso!" + chooseCamera: "Seleziona fotocamera" + cannotToggleFlash: "Flash non controllabile" + turnOnFlash: "Accendi il flash" + turnOffFlash: "Spegni il flash" + startQr: "Inizia lettura QR Code" + stopQr: "Interrompi lettura QR Code" + noQrCodeFound: "Non trovo alcun QR Code" + scanFile: "Scansiona immagine nel dispositivo" + raw: "Testo" + mfm: "MFC" diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index 04f1d438aa..4a01e58bb3 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -1,5 +1,21 @@ _lang_: "日本語" +compareContent: "内容比較" +editHistory: "修正履歴" +unRenoteAll: "全リノート解除" +unRenoteAllConfirm: "全リノート解除" +unRenoteAllConfirmDescription: "このノートのすべてのリノットを削除しようとしています。実行しますか?" +alreadyRenotedConfirm: "既にリノートしました" +alreadyRenotedConfirmDescription: "このノートは既にリノートしました。もう一度リノートしますか?" +alreadyRenotedConfirmCaption: "Mastodonなど、一部のソフトウェアは最初のリノートのみを処理するため、それ以降のリノートは表示されないことがあります。" +autoDeleteNotes: "ノート自動削除" +autoDeleteNotesDescription: "指定した期間が経過したノートを自動的に削除します。" +autoDeleteNotesAfterDays: "自動削除期間" +autoDeleteNotesAfterDaysDescription: "この期間が経過したノートが自動的に削除されます。無効にするには空欄にしてください。" +autoDeleteKeepFavorites: "お気に入りのノートを保護" +autoDeleteKeepFavoritesDescription: "お気に入りに追加したノートは自動削除されません。" +autoDeleteNotesWarning: "この操作は取り消せません。削除されたノートは復元できません。" +scheduledToDeleteOnX: "{x}に削除が予約されています" showGapBodyOfTheNote: "ノートの本文を離して表示" replyTo: "{user}さんに返信" forceCollapseAllRenotes: "すべてのリノートの省略" @@ -18,9 +34,7 @@ selectReaction: "いいねボタンで使うリアクションを選択" disableRegistrationWhenInactive: "モデレーターが一定期間非アクティブになったとき、新規登録を無効化" disablePublicNoteWhenInactive: "モデレーターが一定期間非アクティブになったとき、「パブリック投稿の許可」を無効化" youBlocked: "ブロックされています" -youBlockedDescription: "{user}さんのフォローやノートの表示はできません。" -schedulePost: "予約投稿" -schedulePostList: "予約投稿一覧" +youBlockedDescription: "{user}さんのフォローやポストの表示はできません。" thereIsSchedulePost: "{n}個の投稿が予約されたノートがあります。" welcomeBackToast: "一定時間が経過した後に接続したときに歓迎メッセージを表示" invalidTextLengthError: "入力された文字数が多すぎます" @@ -31,7 +45,6 @@ useAutoTranslate: "自動翻訳" useAutoTranslateDescription: "自動翻訳機能を有効にすると、タイムラインのすべてのノートが自動的に翻訳され、これにより翻訳サービス提供者が設定したAPI制限ポリシーにより、翻訳機能を一時的に使用できなくなる可能性があります。\n\nそれでも続けましょうか?" cantUseThisFunctionDescription: "サーバー管理者が{name}を使用できないように設定しました。\n{name}を使用するには、サーバー管理者にお問い合わせください。" cantUseThisFunctionCaption: "有効にすると、再利用できるときに{name}を適用します。" -widgets: "ウィジェット" postNote: "ノートを作成" bottomNavbar: "下のナビゲーションバー" bottomNavbarDescription: "この設定は、モバイル環境でのみ使用できます。" @@ -204,9 +217,9 @@ youGotNewFollower: "フォローされました" receiveFollowRequest: "フォローリクエストされました" followRequestAccepted: "フォローが承認されました" mention: "メンション" -mentions: "あなた宛て" +mentions: "メンション" newNotes: "新規投稿" -directNotes: "ダイレクト投稿" +directNotes: "指名" importAndExport: "インポートとエクスポート" import: "インポート" export: "エクスポート" @@ -307,7 +320,7 @@ emojiUrl: "絵文字画像URL" addEmoji: "絵文字を追加" settingGuide: "おすすめ設定" cacheRemoteFiles: "リモートのファイルをキャッシュする" -cacheRemoteFilesDescription: "この設定を有効にすると、リモートファイルをこのサーバーのストレージにキャッシュするようになります。画像の表示が高速になりますが、サーバーのストレージを多く消費します。リモートユーザーがどれほどキャッシュを保持するかは、ロールによるドライブ容量制限によって決定されます。この制限を超えた場合、古いファイルからキャッシュが削除されリンクになります。この設定が無効の場合、リモートのファイルを最初からリンクとして保持しますが、画像のサムネイル生成やユーザーのプライバシー保護のために、default.ymlでproxyRemoteFilesをtrueにすることをお勧めします。" +cacheRemoteFilesDescription: "この設定を有効にすると、リモートファイルをこのサーバーのストレージにキャッシュするようになります。画像の表示が高速になりますが、サーバーのストレージを多く消費します。リモートユーザーがどれほどキャッシュを保持するかは、ロールによるドライブ容量制限によって決定されます。この制限を超えた場合、古いファイルからキャッシュが削除されリンクになります。この設定が無効の場合、リモートのファイルを最初からリンクとして保持します。" youCanCleanRemoteFilesCache: "ファイル管理の🗑️ボタンで全てのキャッシュを削除できます。" cacheRemoteSensitiveFiles: "リモートのセンシティブなファイルをキャッシュする" cacheRemoteSensitiveFilesDescription: "この設定を無効にすると、リモートのセンシティブなファイルはキャッシュせず直リンクするようになります。" @@ -317,7 +330,7 @@ flagAsCat: "にゃああああああああああああああ!!!!!! flagAsCatDescription: "にゃにゃにゃ??" flagShowTimelineReplies: "タイムラインにノートへの返信を表示する" flagShowTimelineRepliesDescription: "オンにすると、タイムラインにユーザーのノート以外にもそのユーザーの他のノートへの返信を表示します。" -autoAcceptFollowed: "フォロー中ユーザーからのフォロリクを自動承認" +autoAcceptFollowed: "フォロー中ユーザーからのフォロー申請を自動承認" addAccount: "アカウントを追加" reloadAccountsList: "アカウントリストの情報を更新" loginFailed: "ログインに失敗しました" @@ -388,9 +401,9 @@ noUsers: "ユーザーはいません" editProfile: "プロフィールを編集" noteDeleteConfirm: "このノートを削除しますか?" pinLimitExceeded: "これ以上ピン留めできません" -intro: "CherryPickのインストールが完了しました!管理者アカウントを作成しましょう。" done: "完了" processing: "処理中" +preprocessing: "準備中" preview: "プレビュー" default: "デフォルト" defaultValueIs: "デフォルト: {value}" @@ -436,10 +449,11 @@ uploadFromUrl: "URLアップロード" uploadFromUrlDescription: "アップロードしたいファイルのURL" uploadFromUrlRequested: "アップロードをリクエストしました" uploadFromUrlMayTakeTime: "アップロードが完了するまで時間がかかる場合があります。" +uploadNFiles: "{n}個のファイルをアップロード" explore: "みつける" messageRead: "既読" noMoreHistory: "これより過去の履歴はありません" -startChat: "チャットを始める" +startChat: "メッセージを送る" nUsersRead: "{n}人が読みました" agreeTo: "{0}に同意" agree: "同意する" @@ -465,11 +479,13 @@ dark: "ダーク" lightThemes: "明るいテーマ" darkThemes: "暗いテーマ" syncDeviceDarkMode: "デバイスのダークモードと同期する" +switchDarkModeManuallyWhenSyncEnabledConfirm: "「{x}」がオンになっています。同期をオフにして手動でモードを切り替えますか?" drive: "ドライブ" fileName: "ファイル名" selectFile: "ファイルを選択" selectFiles: "ファイルを選択" selectFolder: "フォルダーを選択" +unselectFolder: "フォルダーの選択を解除" selectFolders: "フォルダーを選択" fileNotSelected: "ファイルが選択されていません" renameFile: "ファイル名を変更" @@ -482,6 +498,7 @@ addFile: "ファイルを追加" showFile: "ファイルを表示" emptyDrive: "ドライブは空です" emptyFolder: "フォルダーは空です" +dropHereToUpload: "ここにファイルをドロップしてアップロード" unableToDelete: "削除できません" inputNewFileName: "新しいファイル名を入力してください" inputNewDescription: "新しいキャプションを入力してください" @@ -614,7 +631,7 @@ notFoundDescription: "ここには何もないようです…" uploadFolder: "既定アップロード先" markAsReadAllNotifications: "すべての通知を既読にする" markAsReadAllUnreadNotes: "すべての投稿を既読にする" -markAsReadAllTalkMessages: "すべてのチャットを既読にする" +markAsReadAllTalkMessages: "すべてのダイレクトメッセージを既読にする" help: "ヘルプ" inputMessageHere: "ここにメッセージを入力" close: "閉じる" @@ -729,13 +746,10 @@ showFixedPostFormInChannel: "タイムライン上部に投稿フォームを表 withRepliesByDefaultForNewlyFollowed: "フォローする際、デフォルトで返信をTLに含むようにする" newNoteRecived: "新しいノートがあります" newNoteRecivedCount: "{n}個の新しいノートがあります" +newNote: "新しいノート" sounds: "サウンド" sound: "サウンド" -vibrations: "振動" -soundsAndVibrations: "サウンドと振動" -playVibrations: "振動再生" -playVibrationsDescription: "この機能はiOS/iPadOSではサポートされていません。" -testVibrations: "振動再生テスト" +notificationSoundSettings: "通知音の設定" listen: "聴く" none: "なし" showInPage: "ページで表示" @@ -792,8 +806,8 @@ addRelay: "リレーの追加" inboxUrl: "inboxのURL" addedRelays: "追加済みのリレー" serviceworkerInfo: "プッシュ通知を行うには有効にする必要があります。" -deletedNote: "削除された投稿" -invisibleNote: "非公開の投稿" +deletedNote: "削除されたノート" +invisibleNote: "非公開のノート" enableInfiniteScroll: "自動でもっと見る" visibility: "公開範囲" poll: "アンケート" @@ -928,6 +942,7 @@ alwaysMarkSensitive: "デフォルトでメディアをセンシティブ設定 loadRawImages: "添付画像のサムネイルをオリジナル画質にする" disableShowingAnimatedImages: "アニメーション画像を再生しない" disableShowingAnimatedImagesDescription: "無効にすると、動く画像が再生されます。光敏感性発作を起こすことがありますので、ご注意ください。" +disableShowingAnimatedImages_caption: "この設定に関わらずアニメーション画像が再生されないときは、ブラウザ・OSのアクセシビリティ設定や省電力設定等が干渉している場合があります。" highlightSensitiveMedia: "メディアがセンシティブであることを分かりやすく表示" verificationEmailSent: "確認のメールを送信しました。メールに記載されたリンクにアクセスして、設定を完了してください。\nもしメールが来なかったらスパムメールボックスを確認してください。" notSet: "未設定" @@ -953,6 +968,7 @@ narrow: "狭い" reloadToApplySetting: "設定はページリロード後に反映されます。" reloadToApplySetting2: "設定はページリロード後に反映されます。" needReloadToApply: "反映には再起動が必要です。" +needToRestartServerToApply: "反映にはサーバーの再起動が必要です。" showTitlebar: "タイトルバーを表示する" clearCache: "キャッシュをクリア" onlineUsersCount: "{n}人がオンライン" @@ -977,8 +993,8 @@ registry: "レジストリ" closeAccount: "アカウントを閉鎖する" currentVersion: "現在のバージョン" latestVersion: "最新のバージョン" -youAreRunningUpToDateClient: "お使いのクライアントは最新です。" -newVersionOfClientAvailable: "新しいバージョンのクライアントが利用可能です。" +youAreRunningUpToDateClient: "CherryPickは最新です。" +newVersionOfClientAvailable: "新しいバージョンのCherryPickが利用可能です。" usageAmount: "使用量" capacity: "容量" inUse: "使用中" @@ -1162,6 +1178,7 @@ failedToUpload: "アップロード失敗" cannotUploadBecauseInappropriate: "不適切な内容を含む可能性があると判定されたためアップロードできません。" cannotUploadBecauseNoFreeSpace: "ドライブの空き容量が無いためアップロードできません。" cannotUploadBecauseExceedsFileSizeLimit: "ファイルサイズの制限を超えているためアップロードできません。" +cannotUploadBecauseUnallowedFileType: "許可されていないファイル種別のためアップロードできません。" beta: "ベータ" enableAutoSensitive: "自動センシティブ判定" enableAutoSensitiveDescription: "利用可能な場合は、機械学習を利用して自動でメディアにセンシティブフラグを設定します。この機能をオフにしても、サーバーによっては自動で設定されることがあります。" @@ -1213,6 +1230,7 @@ permissionDeniedError: "操作が拒否されました" permissionDeniedErrorDescription: "このアカウントにはこの操作を行うための権限がありません。" preset: "プリセット" selectFromPresets: "プリセットから選択" +custom: "カスタム" achievements: "実績" gotInvalidResponseError: "サーバーの応答が無効です" gotInvalidResponseErrorDescription: "サーバーがダウンまたはメンテナンスしている可能性があります。しばらくしてから再度お試しください。" @@ -1255,6 +1273,7 @@ prohibitedWordsDescription2: "スペースで区切るとAND指定になり、 hiddenTags: "非表示ハッシュタグ" hiddenTagsDescription: "設定したタグをトレンドに表示させないようにします。改行で区切って複数設定できます。" notesSearchNotAvailable: "ノート検索は利用できません。" +usersSearchNotAvailable: "ユーザー検索は利用できません。" license: "ライセンス" unfavoriteConfirm: "お気に入り解除しますか?" myClips: "自分のクリップ" @@ -1332,6 +1351,7 @@ installed: "インストール済み" branding: "ブランディング" enableServerMachineStats: "サーバーのマシン情報を公開する" enableIdenticonGeneration: "ユーザーごとのIdenticon生成を有効にする" +showRoleBadgesOfRemoteUsers: "リモートユーザーに付与したロールバッジを表示する" turnOffToImprovePerformance: "オフにするとパフォーマンスが向上します。" createInviteCode: "招待コードを作成" createWithOptions: "オプションを指定して作成" @@ -1413,9 +1433,8 @@ showAvatarDecorations: "アイコンのデコレーションを表示" releaseToRefresh: "離してリロード" refreshing: "リロード中" pullDownToRefresh: "引っ張ってリロード" -disableStreamingTimeline: "タイムラインのリアルタイム更新を無効にする" useGroupedNotifications: "通知をグルーピング" -signupPendingError: "メールアドレスの確認中に問題が発生しました。リンクの有効期限が切れている可能性があります。" +emailVerificationFailedError: "メールアドレスの確認中に問題が発生しました。リンクの有効期限が切れている可能性があります。" cwNotationRequired: "「内容を隠す」がオンの場合は注釈の記述が必要です。" doReaction: "リアクションする" code: "コード" @@ -1478,7 +1497,7 @@ messageToFollower: "フォロワーへのメッセージ" target: "対象" testCaptchaWarning: "CAPTCHAのテストを目的とした機能です。本番環境で使用しないでください。" prohibitedWordsForNameOfUser: "禁止ワード(ユーザーの名前)" -prohibitedWordsForNameOfUserDescription: "このリストに含まれる文字列がユーザーの名前に含まれる場合、ユーザーの名前の変更を拒否します。モデレーター権限を持つユーザーはこの制限の影響を受けません。" +prohibitedWordsForNameOfUserDescription: "このリストに含まれる文字列がユーザーの名前に含まれる場合、ユーザーの名前の変更を拒否します。モデレーター権限を持つユーザーはこの制限の影響を受けません。ユーザー名(username)に対しても全て小文字に置き換えて検査します。" yourNameContainsProhibitedWords: "変更しようとした名前に禁止された文字列が含まれています" yourNameContainsProhibitedWordsDescription: "名前に禁止されている文字列が含まれています。この名前を使用したい場合は、サーバー管理者にお問い合わせください。" thisContentsAreMarkedAsSigninRequiredByAuthor: "投稿者により、表示にはログインが必要と設定されています" @@ -1488,6 +1507,8 @@ availableRoles: "利用可能なロール" acknowledgeNotesAndEnable: "注意事項を理解した上でオンにします。" federationSpecified: "このサーバーはホワイトリスト連合で運用されています。管理者が指定したサーバー以外とやり取りすることはできません。" federationDisabled: "このサーバーは連合が無効化されています。他のサーバーのユーザーとやり取りすることはできません。" +draft: "下書き" +draftsAndScheduledNotes: "下書きと予約投稿" confirmOnReact: "リアクションする際に確認する" reactAreYouSure: "\" {emoji} \" をリアクションしますか?" markAsSensitiveConfirm: "このメディアをセンシティブとして設定しますか?" @@ -1504,9 +1525,10 @@ skip: "スキップ" restore: "復元" syncBetweenDevices: "デバイス間で同期" preferenceSyncConflictTitle: "サーバーに設定値が存在します" -preferenceSyncConflictText: "同期が有効にされた設定項目は設定値をサーバーに保存しますが、この設定項目のサーバーに保存された設定値が見つかりました。どちらの設定値で上書きしますか?" -preferenceSyncConflictChoiceServer: "サーバーの設定値" -preferenceSyncConflictChoiceDevice: "デバイスの設定値" +preferenceSyncConflictText: "同期が有効にされた設定項目は設定値をサーバーに保存しますが、この設定項目のサーバーに保存された設定値が見つかりました。どうしますか?" +preferenceSyncConflictChoiceMerge: "統合する" +preferenceSyncConflictChoiceServer: "サーバーの設定値で上書き" +preferenceSyncConflictChoiceDevice: "デバイスの設定値で上書き" preferenceSyncConflictChoiceCancel: "同期の有効化をキャンセル" paste: "ペースト" emojiPalette: "絵文字パレット" @@ -1514,6 +1536,8 @@ postForm: "投稿フォーム" textCount: "文字数" information: "情報" chat: "チャット" +directMessage: "ダイレクトメッセージ" +directMessage_short: "メッセージ" migrateOldSettings: "旧設定情報を移行" migrateOldSettings_description: "通常これは自動で行われていますが、何らかの理由により上手く移行されなかった場合は手動で移行処理をトリガーできます。現在の設定情報は上書きされます。" compress: "圧縮" @@ -1527,7 +1551,38 @@ goToDeck: "デッキへ戻る" federationJobs: "連合ジョブ" driveAboutTip: "ドライブでは、過去にアップロードしたファイルの一覧が表示されます。
\nノートに添付する際に再利用したり、あとで投稿するファイルを予めアップロードしておくこともできます。
\nファイルを削除すると、今までそのファイルを使用した全ての場所(ノート、ページ、アバター、バナー等)からも見えなくなるので注意してください。
\nフォルダを作って整理することもできます。" scrollToClose: "スクロールして閉じる" -draft: "下書き" +advice: "アドバイス" +realtimeMode: "リアルタイムモード" +turnItOn: "オンにする" +turnItOff: "オフにする" +emojiMute: "絵文字ミュート" +emojiUnmute: "絵文字ミュート解除" +muteX: "{x}をミュート" +unmuteX: "{x}のミュートを解除" +abort: "中止" +tip: "ヒントとコツ" +redisplayAllTips: "全ての「ヒントとコツ」を再表示" +hideAllTips: "全ての「ヒントとコツ」を非表示" +defaultImageCompressionLevel: "デフォルトの画像圧縮度" +defaultImageCompressionLevel_description: "低くすると画質を保てますが、ファイルサイズは増加します。
高くするとファイルサイズを減らせますが、画質は低下します。" +defaultCompressionLevel: "デフォルトの圧縮度" +defaultCompressionLevel_description: "低くすると品質を保てますが、ファイルサイズは増加します。
高くするとファイルサイズを減らせますが、品質は低下します。" +inMinutes: "分" +inDays: "日" +safeModeEnabled: "セーフモードが有効です" +pluginsAreDisabledBecauseSafeMode: "セーフモードが有効なため、プラグインはすべて無効化されています。" +customCssIsDisabledBecauseSafeMode: "セーフモードが有効なため、カスタムCSSは適用されていません。" +themeIsDefaultBecauseSafeMode: "セーフモードが有効な間はデフォルトのテーマが使用されます。セーフモードをオフにすると元に戻ります。" +thankYouForTestingBeta: "ベータ版の検証にご協力いただきありがとうございます!" +createUserSpecifiedNote: "ユーザー指定ノートを作成" +schedulePost: "投稿を予約" +scheduleToPostOnX: "{x}に投稿を予約します" +scheduledToPostOnX: "{x}に投稿が予約されています" +schedule: "予約" +scheduled: "予約" +widgets: "ウィジェット" +deviceInfo: "デバイス情報" +deviceInfoDescription: "技術的なお問い合わせの際に、以下の情報を併記すると問題の解決に役立つことがあります。" draftNoteList: "下書き一覧" saveAsDraft: "下書きで保存" showUnreadNotificationsCount: "未読の通知の数を表示する" @@ -1544,43 +1599,55 @@ _nsfwOpenBehavior: click: "タップして開く" doubleClick: "二回タップして開く" -_vibrations: - click: "要素をクリックしたとき" - note: "タイムラインに新しいノートがあるとき" - notification: "通知を受け取ったとき" - system: "システムの触覚" - _showingAnimatedImages: always: "常に再生" interaction: "インタラクト時に再生" inactive: "一定時間経過すると再生" +_compression: + _quality: + high: "高品質" + medium: "中品質" + low: "低品質" + _size: + large: "サイズ大" + medium: "サイズ中" + small: "サイズ小" + +_order: + newest: "新しい順" + oldest: "古い順" + _chat: + messages: "メッセージ" noMessagesYet: "まだメッセージはありません" newMessage: "新しいメッセージ" - individualChat: "個人チャット" - individualChat_description: "特定ユーザーとの一対一のチャットができます。" - roomChat: "ルームチャット" - roomChat_description: "複数人でのチャットができます。\nまた、個人チャットを許可していないユーザーとでも、相手が受け入れればチャットができます。" - createRoom: "ルームを作成" - inviteUserToChat: "ユーザーを招待してチャットを始めましょう" - yourRooms: "作成したルーム" - joiningRooms: "参加中のルーム" + individualChat: "個別" + individualChat_description: "特定ユーザーと個別にメッセージのやりとりができます。" + roomChat: "グループ" + roomChat_description: "複数人でメッセージのやりとりができます。\nまた、個別のメッセージを許可していないユーザーとでも、相手が受け入れればやりとりできます。" + createRoom: "グループを作成" + inviteUserToChat: "ユーザーを招待してメッセージを送信しましょう" + yourRooms: "作成したグループ" + joiningRooms: "参加中のグループ" invitations: "招待" noInvitations: "招待はありません" history: "履歴" noHistory: "履歴はありません" - noRooms: "ルームはありません" + noRooms: "グループはありません" inviteUser: "ユーザーを招待" sentInvitations: "送信した招待" join: "参加" + reject: "拒否" ignore: "無視" - leave: "ルームから退出" + leave: "グループから退出" members: "メンバー" searchMessages: "メッセージを検索" home: "ホーム" send: "送信" newline: "改行" + youAreNotAMemberOfThisRoomButInvited: "あなたはこのグループの参加者ではありませんが、招待が届いています。参加するには、招待を承認してください。" + doYouAcceptInvitation: "招待を承認しますか?" muteThisRoom: "このルームをミュート" deleteRoom: "ルームを削除" chatNotAvailableForThisAccountOrServer: "このサーバー、またはこのアカウントでチャットは有効化されていません。" @@ -1594,7 +1661,7 @@ _chat: thisUserAllowsChatOnlyFromMutualFollowing: "このユーザーは相互フォローのユーザーからのみチャットを受け付けています。" thisUserNotAllowedChatAnyone: "このユーザーは誰からもチャットを受け付けていません。" chatAllowedUsers: "チャットを許可する相手" - chatAllowedUsers_note: "自分からチャットメッセージを送った相手とはこの設定に関わらずチャットが可能です。" + chatAllowedUsers_note: "自分からダイレクトメッセージを送った相手とはこの設定に関わらずチャットが可能です。" dateSinceRegistedBy: "{year}年{month}月から利用しています" dateSinceRemoteRegistedBy: "{year}年{month}月から観測しています" countOfFollowers: "{value} 人のフォロワー" @@ -1608,6 +1675,10 @@ _chat: following: "自分がフォローしているユーザーのみ" mutual: "相互フォローのユーザーのみ" none: "誰も許可しない" + usersCount: "{n}人が参加中" + invitationCancelAreYouSure: "{x}さんに送信された招待をキャンセルしますか?" + ignoreThisInvitation: "この招待を無視すると、グループの管理者が招待を取り消して再度招待したり、グループを削除して再作成した場合にのみ招待されることができます。" + doYouIgnoreInvitation: "招待を無視しますか?" _emojiPalette: palettes: "パレット" @@ -1637,12 +1708,23 @@ _settings: makeEveryTextElementsSelectable: "全てのテキスト要素を選択可能にする" makeEveryTextElementsSelectable_description: "有効にすると、一部のシチュエーションでのユーザビリティが低下する場合があります。" useStickyIcons: "アイコンをスクロールに追従させる" + enableHighQualityImagePlaceholders: "高品質な画像のプレースホルダを表示" + uiAnimations: "UIのアニメーション" showNavbarSubButtons: "ナビゲーションバーに副ボタンを表示" ifOn: "オンのとき" ifOff: "オフのとき" enableSyncThemesBetweenDevices: "デバイス間でインストールしたテーマを同期" enablePullToRefresh: "ひっぱって更新" enablePullToRefresh_description: "マウスでは、ホイールを押し込みながらドラッグします。" + realtimeMode_description: "サーバーと接続を確立し、リアルタイムでコンテンツを更新します。通信量とバッテリーの消費が多くなる場合があります。" + contentsUpdateFrequency: "コンテンツの取得頻度" + contentsUpdateFrequency_description: "高いほどリアルタイムにコンテンツが更新されますが、パフォーマンスが低下し、通信量とバッテリーの消費が多くなります。" + contentsUpdateFrequency_description2: "リアルタイムモードがオンのときは、この設定に関わらずリアルタイムでコンテンツが更新されます。" + showUrlPreview: "URLプレビューを表示する" + showAvailableReactionsFirstInNote: "利用できるリアクションを先頭に表示" + showPageTabBarBottom: "ページのタブバーを下部に表示" + emojiPaletteBanner: "絵文字ピッカーに固定表示するプリセットをパレットとして登録したり、ピッカーの表示方法をカスタマイズしたりできます。" + smoothTransitionAnimations: "柔らかい転換アニメーション" _chat: showSenderName: "送信者の名前を表示" @@ -1836,6 +1918,8 @@ _initialTutorial: local: "このサーバーにいるユーザー全員の投稿を見られます。" social: "ホームタイムラインとローカルタイムラインの投稿が両方表示されます。" global: "接続している他のすべてのサーバーからの投稿を見られます。" + media: "メディアを含むホームタイムラインとローカルタイムラインの投稿が表示されます。" + bubble: "管理者が設定したサーバーの投稿を見ることができます。" description2: "それぞれのタイムラインは、画面上部でいつでも切り替えられます。" description3: "その他にも、リストタイムラインやチャンネルタイムラインなどがあります。詳しくは{link}をご覧ください。" _postNote: @@ -1846,9 +1930,9 @@ _initialTutorial: public: "すべてのユーザーに公開。" home: "ホームタイムラインのみに公開。フォロワー・プロフィールを見に来た人・リノートから、他のユーザーも見ることができます。" followers: "フォロワーにのみ公開。本人以外がリノートすることはできず、またフォロワー以外は閲覧できません。" - direct: "指定したユーザーにのみ公開され、また相手に通知が入ります。ダイレクトメッセージのかわりにお使いいただけます。" + direct: "指定したユーザーにのみ公開され、また相手に通知が入ります。" doNotSendConfidencialOnDirect1: "機密情報は送信する際は注意してください。" - doNotSendConfidencialOnDirect2: "送信先のサーバーの管理者は投稿内容を見ることが可能なので、信頼できないサーバーのユーザーにダイレクト投稿を送信する場合は、機密情報の扱いに注意が必要です。" + doNotSendConfidencialOnDirect2: "送信先のサーバーの管理者は投稿内容を見ることが可能なので、信頼できないサーバーのユーザーが含まれる限定公開のノートを作成する際は、機密情報の扱いに注意が必要です。" localOnly: "他のサーバーに投稿を連合しません。上記の公開範囲に関わらず、他のサーバーのユーザーは、この設定がついたノートを直接閲覧することができなくなります。" _cw: title: "内容を隠す(CW)" @@ -1875,6 +1959,7 @@ _timelineDescription: local: "ローカルタイムラインでは、このサーバーにいるユーザー全員の投稿を見られます。" social: "ソーシャルタイムラインには、ホームタイムラインとローカルタイムラインの投稿が両方表示されます。" global: "グローバルタイムラインでは、接続している他のすべてのサーバーからの投稿を見られます。" + media: "メディアタイムラインでは、メディアを含むホームタイムラインとローカルタイムラインの投稿が表示されます。" bubble: "バブルタイムラインでは、管理者が設定したサーバーの投稿を見ることができます。" _serverRules: @@ -1920,6 +2005,10 @@ _serverSettings: fanoutTimelineDbFallback: "データベースへのフォールバック" fanoutTimelineDbFallbackDescription: "有効にすると、タイムラインがキャッシュされていない場合にDBへ追加で問い合わせを行うフォールバック処理を行います。無効にすると、フォールバック処理を行わないことでさらにサーバーの負荷を軽減することができますが、タイムラインが取得できる範囲に制限が生じます。" reactionsBufferingDescription: "有効にすると、リアクション作成時のパフォーマンスが大幅に向上し、データベースへの負荷を軽減することが可能です。ただし、Redisのメモリ使用量は増加します。" + remoteNotesCleaning: "リモート投稿の自動クリーニング" + remoteNotesCleaning_description: "有効にすると、一定期間経過したリモートの投稿を定期的にクリーンアップしてデータベースの肥大化を抑制します。" + remoteNotesCleaningMaxProcessingDuration: "最大クリーニング処理継続時間" + remoteNotesCleaningExpiryDaysForEachNotes: "最低ノート保持日数" inquiryUrl: "問い合わせ先URL" inquiryUrlDescription: "サーバー運営者へのお問い合わせフォームのURLや、運営者の連絡先等が記載されたWebページのURLを指定します。" openRegistration: "アカウントの作成をオープンにする" @@ -1927,6 +2016,27 @@ _serverSettings: thisSettingWillAutomaticallyOffWhenModeratorsInactive: "一定期間モデレーターのアクティビティが検出されなかった場合、スパム防止のためこの設定は自動でオフになります。" deliverSuspendedSoftware: "配信停止中のソフトウェア" deliverSuspendedSoftwareDescription: "脆弱性などの理由で、サーバーのソフトウェアの名前及びバージョンの範囲を指定して配信を停止できます。このバージョン情報はサーバーが提供したものであり、信頼性は保証されません。バージョン指定には semver の範囲指定が使用できますが、>= 2024.3.1 と指定すると 2024.3.1-custom.0 のようなカスタムバージョンが含まれないため、>= 2024.3.1-0 のように prerelease の指定を行うことを推奨します。" + singleUserMode: "お一人様モード" + singleUserMode_description: "このサーバーを利用するのが自分だけの場合、このモードを有効にすることで動作が最適化されます。" + signToActivityPubGet: "GETリクエストに署名する" + signToActivityPubGet_description: "通常は有効にしてください。連合の通信に関する問題がある場合に、無効にすると改善することがありますが、逆にサーバーによっては通信が不可になることがあります。" + proxyRemoteFiles: "リモートファイルをプロキシする" + proxyRemoteFiles_description: "有効にすると、リモートのファイルをプロキシして提供します。画像のサムネイル生成やユーザーのプライバシー保護に役立ちます。" + allowExternalApRedirect: "ActivityPub経由の照会にリダイレクトを許可する" + allowExternalApRedirect_description: "有効にすると、他のサーバーがこのサーバーを通して第三者のコンテンツを照会することが可能になりますが、コンテンツのなりすましが発生する可能性があります。" + userGeneratedContentsVisibilityForVisitor: "非利用者に対するユーザー作成コンテンツの公開範囲" + userGeneratedContentsVisibilityForVisitor_description: "モデレーションが行き届きにくい不適切なリモートコンテンツなどが、自サーバー経由で図らずもインターネットに公開されてしまうことによるトラブル防止などに役立ちます。" + userGeneratedContentsVisibilityForVisitor_description2: "サーバーで受信したリモートのコンテンツを含め、サーバー内の全てのコンテンツを無条件でインターネットに公開することはリスクが伴います。特に、分散型の特性を知らない閲覧者にとっては、リモートのコンテンツであってもサーバー内で作成されたコンテンツであると誤って認識してしまう可能性があるため、注意が必要です。" + restartServerSetupWizardConfirm_title: "サーバーの初期設定ウィザードをやり直しますか?" + restartServerSetupWizardConfirm_text: "現在の一部の設定はリセットされます。" + entrancePageStyle: "エントランスページのスタイル" + showTimelineForVisitor: "タイムラインを表示する" + showActivitiesForVisitor: "アクティビティを表示する" + + _userGeneratedContentsVisibilityForVisitor: + all: "全て公開" + localOnly: "ローカルコンテンツのみ公開し、リモートコンテンツは非公開" + none: "全て非公開" _accountMigration: moveFrom: "別のアカウントからこのアカウントに移行" @@ -2269,6 +2379,7 @@ _role: canManageAvatarDecorations: "アバターデコレーションの管理" driveCapacity: "ドライブ容量" maxFileSize: "アップロード可能な最大ファイルサイズ" + maxFileSize_caption: "リバースプロキシやCDNなど、前段で別の設定値が存在する場合があります。" alwaysMarkNsfw: "ファイルにNSFWを常に付与" canUpdateBioMedia: "アイコンとバナーの更新を許可" pinMax: "ノートのピン留めの最大数" @@ -2283,6 +2394,7 @@ _role: descriptionOfRateLimitFactor: "小さいほど制限が緩和され、大きいほど制限が強化されます。" canHideAds: "広告の非表示" canSearchNotes: "ノート検索の利用" + canSearchUsers: "ユーザー検索の利用" canUseTranslator: "翻訳機能の利用" canUseAutoTranslate: "自動翻訳機能の利用" canUseAutoTranslateDescription: "自動翻訳機能を有効にしたユーザーは、タイムラインのすべてのノートが自動的に翻訳され、これにより翻訳サービス提供者が設定したAPI制限に非常に早く到達し、翻訳機能を一時的に使用できなくなる可能性があります。\nこれは、サーバー内のすべてのユーザーがAPIを一時的に使用できなくなる可能性があることを意味します。\nまた、翻訳サービスの提供者によっては、APIの使用による料金が過度に発生する可能性があります。\n\nそれでも続けましょうか?" @@ -2292,8 +2404,13 @@ _role: canImportFollowing: "フォローのインポートを許可" canImportMuting: "ミュートのインポートを許可" canImportUserLists: "リストのインポートを許可" - chatAvailability: "チャットを許可" + chatAvailability: "ダイレクトメッセージを許可" + uploadableFileTypes: "アップロード可能なファイル種別" + uploadableFileTypes_caption: "MIMEタイプを指定します。改行で区切って複数指定できるほか、アスタリスク(*)でワイルドカード指定できます。(例: image/*)" + uploadableFileTypes_caption2: "ファイルによっては種別を判定できないことがあります。そのようなファイルを許可する場合は {x} を指定に追加してください。" noteDraftLimit: "サーバーサイドのノートの下書きの作成可能数" + scheduledNoteLimit: "予約投稿の同時作成可能数" + watermarkAvailable: "ウォーターマーク機能の使用可否" canSetFederationAvatarShape: "アイコンの形設定の連合を許可" canDeleteAccount: "アカウントの削除の許可" canTruncateAccount: "アカウントの整理の許可" @@ -2577,6 +2694,7 @@ _theme: install: "テーマのインストール" manage: "テーマの管理" code: "テーマコード" + copyThemeCode: "テーマコードをコピー" description: "説明" installed: "{name}をインストールしました" installedThemes: "インストールされたテーマ" @@ -2636,9 +2754,8 @@ _theme: buttonBg: "ボタンの背景" buttonHoverBg: "ボタンの背景 (ホバー)" inputBorder: "入力ボックスの縁取り" - driveFolderBg: "ドライブフォルダーの背景" badge: "バッジ" - messageBg: "チャットの背景" + messageBg: "メッセージの背景" fgHighlighted: "強調された文字" _sfx: @@ -2648,7 +2765,7 @@ _sfx: noteEdited: "ノートを編集" notification: "通知" reaction: "リアクション選択時" - chatMessage: "チャットのメッセージ" + chatMessage: "ダイレクトメッセージ" _soundSettings: driveFile: "ドライブの音声を使用" @@ -2685,6 +2802,7 @@ _time: minute: "分" hour: "時間" day: "日" + month: "ヶ月" _2fa: alreadyRegistered: "既に設定は完了しています。" @@ -2727,13 +2845,11 @@ _permissions: "write:favorites": "お気に入りを操作する" "read:following": "フォローの情報を見る" "write:following": "フォロー・フォロー解除する" - "read:messaging": "チャットを見る" - "write:messaging": "チャットを操作する" + "read:messaging": "ダイレクトメッセージを見る" + "write:messaging": "ダイレクトメッセージを操作する" "read:mutes": "ミュートを見る" "write:mutes": "ミュートを操作する" "write:notes": "ノートを作成・削除する" - "read:notes-schedule": "予約投稿を見る" - "write:notes-schedule": "予約投稿を作成・削除する" "read:notifications": "通知を見る" "write:notifications": "通知を操作する" "read:reactions": "リアクションを見る" @@ -2803,8 +2919,8 @@ _permissions: "read:clip-favorite": "クリップのいいねを見る" "read:federation": "連合に関する情報を取得する" "write:report-abuse": "違反を報告する" - "write:chat": "チャットを操作する" - "read:chat": "チャットを閲覧する" + "write:chat": "ダイレクトメッセージを操作する" + "read:chat": "ダイレクトメッセージを閲覧する" _auth: shareAccessTitle: "アプリへのアクセス許可" @@ -2819,6 +2935,7 @@ _auth: scopeUser: "以下のユーザーとして操作しています" pleaseLogin: "アプリケーションにアクセス許可を与えるには、ログインが必要です。" byClickingYouWillBeRedirectedToThisUrl: "アクセスを許可すると、自動で以下のURLに遷移します" + alreadyAuthorized: "このアプリケーションは既にアクセスが許可されています。" _antennaSources: all: "全てのノート" @@ -2868,7 +2985,7 @@ _widgets: chooseList: "リストを選択" clicker: "クリッカー" birthdayFollowings: "今日誕生日のユーザー" - chat: "チャット" + chat: "ダイレクトメッセージ" search: "検索" dice: "サイコロ" weather: "天気" @@ -2909,12 +3026,14 @@ _visibility: homeDescription: "ホームタイムラインのみに公開" followers: "フォロワー" followersDescription: "自分のフォロワーのみに公開" - specified: "ダイレクト" + specified: "指名" specifiedDescription: "指定したユーザーのみに公開" disableFederation: "連合なし" disableFederationDescription: "他サーバーへの配信を行いません" _postForm: + quitInspiteOfThereAreUnuploadedFilesConfirm: "アップロードされていないファイルがありますが、破棄してフォームを閉じますか?" + uploaderTip: "ファイルはまだアップロードされていません。ファイルのメニューから、リネームや画像のクロップ、ウォーターマークの付与、圧縮の有無などを設定できます。ファイルはノート投稿時に自動でアップロードされます。" signinRequiredPlaceholder: "ノートを作成するにはログインが必要です。" replyPlaceholder: "このノートに返信..." quotePlaceholder: "このノートを引用..." @@ -2961,7 +3080,7 @@ _exportOrImport: userLists: "リスト" excludeMutingUsers: "ミュートしているユーザーを除外" excludeInactiveUsers: "使われていないアカウントを除外" - withReplies: "インポートした人による返信をTLに含むようにする" + withReplies: "返信をTLに含むかの情報がファイルにない場合に、インポートした人による返信をTLに含むようにする" _charts: federation: "連合" @@ -2996,6 +3115,7 @@ _timelines: local: "ローカル" social: "ソーシャル" global: "グローバル" + media: "メディア" bubble: "バブル" _play: @@ -3083,10 +3203,12 @@ _notification: yourFollowRequestAccepted: "フォローリクエストが承認されました" youWereInvitedToGroup: "{userName}があなたをグループに招待しました" pollEnded: "アンケートの結果が出ました" + scheduledNotePosted: "予約ノートが投稿されました" + scheduledNotePostFailed: "予約ノートの投稿に失敗しました" newNote: "新しい投稿" unreadAntennaNote: "アンテナ {name}" roleAssigned: "ロールが付与されました" - chatRoomInvitationReceived: "チャットルームへ招待されました" + chatRoomInvitationReceived: "ダイレクトメッセージのグループへ招待されました" emptyPushNotificationMessage: "プッシュ通知の更新をしました" achievementEarned: "実績を獲得" testNotification: "通知テスト" @@ -3115,11 +3237,13 @@ _notification: quote: "引用" reaction: "リアクション" pollEnded: "アンケートが終了" + scheduledNotePosted: "予約投稿が成功した" + scheduledNotePostFailed: "予約投稿が失敗した" receiveFollowRequest: "フォロー申請を受け取った" followRequestAccepted: "フォローが受理された" groupInvited: "グループに招待された" roleAssigned: "ロールが付与された" - chatRoomInvitationReceived: "チャットルームへ招待された" + chatRoomInvitationReceived: "ダイレクトメッセージのグループへ招待された" achievementEarned: "実績の獲得" exportCompleted: "エクスポートが完了した" login: "ログイン" @@ -3133,13 +3257,6 @@ _notification: reply: "返信" renote: "リノート" - _scheduleNote: - unknown: "原因は不明です" - renoteTargetNotFound: "引用元がありません" - channelTargetNotFound: "対象のチャンネルがありません" - replyTargetNotFound: "返信先がありません" - invalidFilesCount: "添付ファイルがありません" - _deck: alwaysShowMainColumn: "常にメインカラムを表示" columnAlign: "カラムの寄せ" @@ -3174,10 +3291,10 @@ _deck: antenna: "アンテナ" list: "リスト" channel: "チャンネル" - mentions: "あなた宛て" - direct: "ダイレクト" + mentions: "メンション" + direct: "指名" roleTimeline: "ロールタイムライン" - chat: "チャット" + chat: "ダイレクトメッセージ" _dialog: charactersExceeded: "最大文字数を超えています! 現在 {current} / 制限 {max}" @@ -3281,7 +3398,7 @@ _moderationLogTypes: deletePage: "ページを削除" deleteFlash: "Playを削除" deleteGalleryPost: "ギャラリーの投稿を削除" - deleteChatRoom: "チャットルームを削除" + deleteChatRoom: "ダイレクトメッセージのグループを削除" updateProxyAccountDescription: "プロキシアカウントの説明を更新" changeExperienceRole: "ロールの経験値を変更" @@ -3292,6 +3409,7 @@ _fileViewer: url: "URL" uploadedAt: "追加日" attachedNotes: "添付されているノート" + usage: "利用" thisPageCanBeSeenFromTheAuthor: "このページは、このファイルをアップロードしたユーザーしか閲覧できません。" _externalResourceInstaller: @@ -3342,9 +3460,12 @@ _dataSaver: _avatar: title: "アイコン画像のアニメーションを無効化" description: "アイコン画像のアニメーションが停止します。アニメーション画像は通常の画像よりファイルサイズが大きいことがあるので、データ通信量をさらに削減できます。" - _urlPreview: + _urlPreviewThumbnail: title: "URLプレビューのサムネイルを非表示" description: "URLプレビューのサムネイル画像が読み込まれなくなります。" + _disableUrlPreview: + title: "URLプレビューを無効化" + description: "URLプレビュー機能を無効化します。サムネイル画像だけと違い、リンク先の情報の読み込み自体を削減できます。" _code: title: "コードハイライトを非表示" description: "MFCなどでコードハイライト記法が使われている場合、タップするまで読み込まれなくなります。コードハイライトではハイライトする言語ごとにその定義ファイルを読み込む必要がありますが、それらが自動で読み込まれなくなるため、通信量の削減が見込めます。" @@ -3407,6 +3528,8 @@ _offlineScreen: _urlPreviewSetting: title: "URLプレビューの設定" enable: "URLプレビューを有効にする" + allowRedirect: "プレビュー先のリダイレクトを許可" + allowRedirectDescription: "入力されたURLがリダイレクトされる場合に、そのリダイレクト先をたどってプレビューを表示するかどうかを設定します。無効にするとサーバーリソースの節約になりますが、リダイレクト先の内容は表示されなくなります。" timeout: "プレビュー取得時のタイムアウト(ms)" timeoutDescription: "プレビュー取得の所要時間がこの値を超えた場合、プレビューは生成されません。" maximumContentLength: "Content-Lengthの最大値(byte)" @@ -3485,10 +3608,6 @@ _customEmojisManager: uploadSettingDescription: "この画面で絵文字アップロードを行う際の動作を設定できます。" directoryToCategoryLabel: "ディレクトリ名を\"category\"に入力する" directoryToCategoryCaption: "ディレクトリをドラッグ・ドロップした時に、ディレクトリ名を\"category\"に入力します。" - emojiInputAreaCaption: "いずれかの方法で登録する絵文字を選択してください。" - emojiInputAreaList1: "この枠に画像ファイルまたはディレクトリをドラッグ&ドロップ" - emojiInputAreaList2: "このリンクをクリックしてPCから選択する" - emojiInputAreaList3: "このリンクをクリックしてドライブから選択する" confirmRegisterEmojisDescription: "リストに表示されている絵文字を新たなカスタム絵文字として登録します。よろしいですか?(負荷を避けるため、一度の操作で登録可能な絵文字は{count}件までです)" confirmClearEmojisDescription: "編集内容を破棄し、リストに表示されている絵文字をクリアします。よろしいですか?" confirmUploadEmojisDescription: "ドラッグ&ドロップされた{count}個のファイルをドライブにアップロードします。実行しますか?" @@ -3563,6 +3682,7 @@ _bootErrors: otherOption1: "クライアント設定とキャッシュを削除" otherOption2: "簡易クライアントを起動" otherOption3: "修復ツールを起動" + otherOption4: "CherryPickをセーフモードで起動" _search: searchScopeAll: "全て" @@ -3573,14 +3693,208 @@ _search: pleaseSelectUser: "ユーザーを選択してください" serverHostPlaceholder: "例: cherrypick.example.com" +_serverSetupWizard: + installCompleted: "CherryPickのインストールが完了しました!" + firstCreateAccount: "まずは、管理者アカウントを作成しましょう。" + accountCreated: "管理者アカウントが作成されました!" + serverSetting: "サーバーの設定" + youCanEasilyConfigureOptimalServerSettingsWithThisWizard: "このウィザードで簡単に最適なサーバーの設定が行えます。" + settingsYouMakeHereCanBeChangedLater: "ここでの設定は、あとからでも変更できます。" + howWillYouUseMisskey: "CherryPickをどのように使いますか?" + _use: + single: "お一人様サーバー" + single_description: "自分専用のサーバーとして、一人で使う" + single_youCanCreateMultipleAccounts: "お一人様サーバーとして運用する場合でも、アカウントは必要に応じて複数作成可能です。" + group: "グループサーバー" + group_description: "信頼できる他の利用者を招待して、複数人で使う" + open: "オープンサーバー" + open_description: "不特定多数の利用者を受け入れる運営を行う" + openServerAdvice: "不特定多数の利用者を受け入れることはリスクが伴います。トラブルに対処できるよう、確実なモデレーション体制で運営することを推奨します。" + openServerAntiSpamAdvice: "自サーバーがスパムの踏み台にならないように、reCAPTCHAといったアンチボット機能を有効にするなど、セキュリティについても細心の注意が必要です。" + howManyUsersDoYouExpect: "どれくらいの人数を想定していますか?" + _scale: + small: "100人以下 (小規模)" + medium: "100人以上1000人以下 (中規模)" + large: "1000人以上 (大規模)" + largeScaleServerAdvice: "大規模なサーバーでは、ロードバランシングやデータベースのレプリケーションなど、高度なインフラストラクチャーの知識が必要になる場合があります。" + doYouConnectToFediverse: "Fediverseと接続しますか?" + doYouConnectToFediverse_description1: "分散型サーバーで構成されるネットワーク(Fediverse)に接続すると、他のサーバーと相互にコンテンツのやり取りが可能です。" + doYouConnectToFediverse_description2: "Fediverseと接続することは「連合」とも呼ばれます。" + youCanConfigureMoreFederationSettingsLater: "連合可能なサーバーの指定など、高度な設定も後ほど可能です。" + remoteContentsCleaning: "リモートコンテンツの自動クリーニング" + remoteContentsCleaning_description: "連合を行うと、継続して多くのコンテンツを受信します。自動クリーニングを有効にすると、一定期間経過したリモートコンテンツを自動でサーバーから削除し、ストレージを節約できます。" + adminInfo: "管理者情報" + adminInfo_description: "問い合わせを受け付けるために使用される管理者情報を設定します。" + adminInfo_mustBeFilled: "オープンサーバー、または連合がオンの場合は必ず入力が必要です。" + followingSettingsAreRecommended: "以下の設定が推奨されます" + applyTheseSettings: "この設定を適用" + skipSettings: "設定をスキップ" + settingsCompleted: "設定が完了しました!" + settingsCompleted_description: "お疲れ様でした。準備が整ったので、さっそくサーバーの使用を開始できます。" + settingsCompleted_description2: "詳細なサーバー設定は、「コントロールパネル」から行えます。" + donationRequest: "寄付のお願い" + _donationRequest: + text1: "CherryPickは有志によって開発されている無料のソフトウェアです。" + text2: "今後も開発を続けられるように、よろしければぜひカンパをお願いいたします。" + text3: "支援者向け特典もあります!" + +_uploader: + editImage: "画像の編集" + compressedToX: "{x}に圧縮" + savedXPercent: "{x}%節約" + abortConfirm: "アップロードされていないファイルがありますが、中止しますか?" + doneConfirm: "アップロードされていないファイルがありますが、完了しますか?" + maxFileSizeIsX: "アップロード可能な最大ファイルサイズは{x}です。" + allowedTypes: "アップロード可能なファイル種別" + tip: "ファイルはまだアップロードされていません。このダイアログで、アップロード前の確認・リネーム・圧縮・クロッピングなどが行えます。準備が出来たら、「アップロード」ボタンを押してアップロードを開始できます。" + +_clientPerformanceIssueTip: + title: "バッテリー消費が多いと感じたら" + makeSureDisabledAdBlocker: "アドブロッカーを無効にしてください" + makeSureDisabledAdBlocker_description: "アドブロッカーはパフォーマンスに影響を及ぼすことがあります。OSの機能やブラウザの機能・アドオンなどでアドブロッカーが有効になっていないか確認してください。" + makeSureDisabledCustomCss: "カスタムCSSを無効にしてください" + makeSureDisabledCustomCss_description: "スタイルを上書きするとパフォーマンスに影響を及ぼすことがあります。カスタムCSSや、スタイルを上書きする拡張機能が有効になっていないか確認してください。" + makeSureDisabledAddons: "拡張機能を無効にしてください" + makeSureDisabledAddons_description: "一部の拡張機能はクライアントの動作に干渉しパフォーマンスに影響を及ぼすことがあります。ブラウザの拡張機能を無効にして改善するか確認してください。" + +_clip: + tip: "クリップは、ノートをまとめることができる機能です。" + +_userLists: + tip: "任意のユーザーが含まれるリストを作成できます。作成したリストはタイムラインとして表示可能です。" + +watermark: "ウォーターマーク" +defaultPreset: "デフォルトのプリセット" +_watermarkEditor: + tip: "画像にクレジット情報などのウォーターマークを追加することができます。" + quitWithoutSaveConfirm: "保存せずに終了しますか?" + driveFileTypeWarn: "このファイルは対応していません" + driveFileTypeWarnDescription: "画像ファイルを選択してください" + title: "ウォーターマークの編集" + cover: "全体に被せる" + repeat: "敷き詰める" + preserveBoundingRect: "回転時はみ出ないように調整する" + opacity: "不透明度" + scale: "サイズ" + text: "テキスト" + qr: "二次元コード" + position: "位置" + margin: "マージン" + type: "タイプ" + image: "画像" + advanced: "高度" + angle: "角度" + stripe: "ストライプ" + stripeWidth: "ラインの幅" + stripeFrequency: "ラインの数" + polkadot: "ポルカドット" + checker: "チェッカー" + polkadotMainDotOpacity: "メインドットの不透明度" + polkadotMainDotRadius: "メインドットの大きさ" + polkadotSubDotOpacity: "サブドットの不透明度" + polkadotSubDotRadius: "サブドットの大きさ" + polkadotSubDotDivisions: "サブドットの数" + leaveBlankToAccountUrl: "空欄にするとアカウントのURLになります" + +_imageEffector: + title: "エフェクト" + addEffect: "エフェクトを追加" + discardChangesConfirm: "変更を破棄して終了しますか?" + nothingToConfigure: "設定項目はありません" + + _fxs: + chromaticAberration: "色収差" + glitch: "グリッチ" + mirror: "ミラー" + invert: "色の反転" + grayscale: "白黒" + blur: "ぼかし" + pixelate: "モザイク" + colorAdjust: "色調補正" + colorClamp: "色の圧縮" + colorClampAdvanced: "色の圧縮(高度)" + distort: "歪み" + threshold: "二値化" + zoomLines: "集中線" + stripe: "ストライプ" + polkadot: "ポルカドット" + checker: "チェッカー" + blockNoise: "ブロックノイズ" + tearing: "ティアリング" + fill: "塗りつぶし" + + _fxProps: + angle: "角度" + scale: "サイズ" + size: "サイズ" + radius: "半径" + samples: "サンプル数" + offset: "位置" + color: "色" + opacity: "不透明度" + normalize: "正規化" + amount: "量" + lightness: "明るさ" + contrast: "コントラスト" + hue: "色相" + brightness: "輝度" + saturation: "彩度" + max: "最大値" + min: "最小値" + direction: "方向" + phase: "位相" + frequency: "頻度" + strength: "強さ" + glitchChannelShift: "ズレ" + seed: "シード値" + redComponent: "赤色成分" + greenComponent: "緑色成分" + blueComponent: "青色成分" + threshold: "しきい値" + centerX: "中心X" + centerY: "中心Y" + zoomLinesSmoothing: "スムージング" + zoomLinesSmoothingDescription: "スムージングと集中線の幅の設定は併用できません。" + zoomLinesThreshold: "集中線の幅" + zoomLinesMaskSize: "中心径" + zoomLinesBlack: "黒色にする" + circle: "円形" + +drafts: "下書き" _drafts: select: "下書きを選択" + cannotCreateDraftAnymore: "下書きの作成可能数を超えています。" + cannotCreateDraft: "この内容では下書きを作成できません。" delete: "下書きを削除" deleteAreYouSure: "下書きを削除しますか?" - noDrafts: "下書きはありません。" + noDrafts: "下書きはありません" replyTo: "{user}への返信" quoteOf: "{user}のノートへの引用" postTo: "{channel}への投稿" + saveToDraft: "下書きへ保存" + restoreFromDraft: "下書きから復元" + restore: "復元" + listDrafts: "下書き一覧" + schedule: "投稿予約" + listScheduledNotes: "予約投稿一覧" + cancelSchedule: "予約解除" + +qr: "二次元コード" +_qr: + showTabTitle: "表示" + readTabTitle: "読み取る" + shareTitle: "{name} {acct}" + shareText: "Fediverseで私をフォローしてください!" + chooseCamera: "カメラを選択" + cannotToggleFlash: "ライト選択不可" + turnOnFlash: "ライトをオンにする" + turnOffFlash: "ライトをオフにする" + startQr: "コードリーダーを再開" + stopQr: "コードリーダーを停止" + noQrCodeFound: "QRコードが見つかりません" + scanFile: "端末の画像をスキャン" + raw: "テキスト" + mfm: "MFC" _abuse: _resolver: @@ -3600,14 +3914,6 @@ _abuse: list: "一覧" resolver: "リソルバー" -_imageCompressionMode: - title: "画像の圧縮形式" - description: "オリジナル画像を保持しない場合に、Web公開用画像の圧縮形式を選択できます。縮小する場合は2048x2048より小さくなるように縮小されます。非可逆圧縮を指定しない場合は、元画像に応じて非可逆圧縮か可逆圧縮かが自動的に選択されます。" - resizeCompress: "縮小して再圧縮する" - noResizeCompress: "縮小せず再圧縮する" - resizeCompressLossy: "縮小して非可逆圧縮する" - noResizeCompressLossy: "縮小せず非可逆圧縮する" - _externalNavigationWarning: title: "外部サイトに移動します" description: "{host}を離れて外部サイトに移動します" @@ -3678,7 +3984,20 @@ _weather: humidity: "湿度" pressure: "気圧" precipitation: "降水量" -noSendActivity: "アクティビティを送信しない" + +_deliveryTargetControl: + deliveryTargetControl: "配送先制御" + deliveryTargetInclude: "選択したサーバーのみに配送" + deliveryTargetExclude: "選択したサーバーを除外して配送" + noFollowersFromRemoteServers: "リモートサーバーのフォロワーがいません" + loadError: "サーバー一覧の読み込みに失敗しました" + followersCount: "{count}人のフォロワー" + searchResults: "{count}件見つかりました(全{total}件中)" + deliveryTargetsInclude: "一部のサーバーにのみ公開" + deliveryTargetsExclude: "一部のサーバーに非公開" + hasDeliveryTargets: "配送先が選択されています" + + noSendActivity: "アクティビティを送信しない" ipAddress: "IPアドレス" searchIpAddress: "IPアドレスを検索" @@ -3705,17 +4024,5 @@ _experience: multiplier: "乗算" set: "固定値" -_deliveryTargetControl: - deliveryTargetControl: "配送先制御" - deliveryTargetInclude: "選択したサーバーのみに配送" - deliveryTargetExclude: "選択したサーバーを除外して配送" - noFollowersFromRemoteServers: "リモートサーバーのフォロワーがいません" - loadError: "サーバー一覧の読み込みに失敗しました" - followersCount: "{count}人のフォロワー" - searchResults: "{count}件見つかりました(全{total}件中)" - deliveryTargetsInclude: "一部のサーバーにのみ公開" - deliveryTargetsExclude: "一部のサーバーに非公開" - hasDeliveryTargets: "配送先が選択されています" - _hideReason: privateNote: "この投稿は非公開です" diff --git a/locales/ja-KS.yml b/locales/ja-KS.yml index 5bb97d2d02..59a9035603 100644 --- a/locales/ja-KS.yml +++ b/locales/ja-KS.yml @@ -234,7 +234,7 @@ clearQueue: "キューをほかす" clearQueueConfirmTitle: "キューをほかしとこか?" clearQueueConfirmText: "未配達の投稿は配送されんなるで。ふつうこの操作を行う必要は無いんやけどな。" clearCachedFiles: "キャッシュをほかす" -clearCachedFilesConfirm: "キャッシュされとるリモートファイルをみんなほかしてええか?" +clearCachedFilesConfirm: "キャッシュされとるリモートファイルを全部ほかしてええか?" blockedInstances: "ブロックしたサーバー" blockedInstancesDescription: "ブロックしたいサーバーのホストを改行で区切って設定してな。ブロックされてもうたサーバーとはもう金輪際やり取りできひんくなるで。" silencedInstances: "サーバーサイレンスされてんねん" @@ -250,7 +250,6 @@ noUsers: "ユーザーはおらん" editProfile: "プロフィールをいじる" noteDeleteConfirm: "このノートをほかしてええか?" pinLimitExceeded: "これ以上ピン留めできひん" -intro: "CherryPickのインストールが完了したで!管理者アカウントを作ってや。" done: "でけた" processing: "処理しとる" preview: "プレビュー" @@ -301,6 +300,7 @@ uploadFromUrlMayTakeTime: "アップロード終わるんにちょい時間か explore: "みつける" messageRead: "もう読んだ" noMoreHistory: "これより昔のんはあらへんで" +startChat: "チャットを始めよか" nUsersRead: "{n}人が読んでもうた" agreeTo: "{0}に同意したで" agree: "せやな" @@ -325,6 +325,7 @@ dark: "ダーク" lightThemes: "デイゲーム" darkThemes: "ナイトゲーム" syncDeviceDarkMode: "デバイスのダークモードと一緒にする" +switchDarkModeManuallyWhenSyncEnabledConfirm: "「{x}」がオンになってるで。同期をオフにして手動でモードを切り替えることにします?" drive: "ドライブ" fileName: "ファイル名" selectFile: "ファイル選んでや" @@ -423,6 +424,7 @@ antennaExcludeBots: "Botアカウントを除外" antennaKeywordsDescription: "スペースで区切ったるとAND指定で、改行で区切ったるとOR指定や" notifyAntenna: "新しいノートを通知すんで" withFileAntenna: "なんか添付されたノートだけ" +excludeNotesInSensitiveChannel: "センシティブなチャンネルのノートは入れんとくわ" enableServiceworker: "ブラウザにプッシュ通知が行くようにする" antennaUsersDescription: "ユーザー名を改行で区切ったってな" caseSensitive: "大文字と小文字は別もんや" @@ -704,6 +706,7 @@ userSaysSomethingAbout: "{name}が「{word}」についてなんか言うてた makeActive: "使うで" display: "表示" copy: "コピー" +copiedToClipboard: "クリップボードにコピーされたで" metrics: "メトリクス" overview: "概要" logs: "ログ" @@ -799,6 +802,7 @@ wide: "広い" narrow: "狭い" reloadToApplySetting: "設定はページリロード後に反映されるで。今リロードしとくか?" needReloadToApply: "反映には再起動せなあかんで" +needToRestartServerToApply: "反映にはサーバーを再起動せなあかんのよ。" showTitlebar: "タイトルバーを見せる" clearCache: "キャッシュをほかす" onlineUsersCount: "{n}人が起きとるで" @@ -988,6 +992,7 @@ document: "ドキュメント" numberOfPageCache: "ページ、どんだけキャッシュすんの?" numberOfPageCacheDescription: "増やすと使いやすくなるけど、負荷とメモリ使用量が増えてくで。一長一短やな。" logoutConfirm: "ログアウトしまっか?" +logoutWillClearClientData: "ログアウトするとクライアントの設定情報がブラウザから消されてまうで。再ログイン時に設定情報を復元できるようにするためには、設定の自動バックアップを有効にするとええで。" lastActiveDate: "最後に使った日時" statusbar: "ステータスバー" pleaseSelect: "選んだってやー" @@ -1006,6 +1011,7 @@ failedToUpload: "アップロードに失敗してもうたわ…" cannotUploadBecauseInappropriate: "きわどい内容を含むかもしれへんって言われたからアップロードできへんわ。" cannotUploadBecauseNoFreeSpace: "ドライブがもうパンパンやからアップロードできへんわ。" cannotUploadBecauseExceedsFileSizeLimit: "ファイルが思うたよりも大きいさかいアップロードできへんでこれ。" +cannotUploadBecauseUnallowedFileType: "許可されてへんファイル種別やからアップロードできへんっぽい。" beta: "ベータ" enableAutoSensitive: "自動できわどいか判断する" enableAutoSensitiveDescription: "使える時は、機械学習を使って自動でメディアにNSFWフラグを設定するで。この機能をオフにしても、サーバーによっては自動で設定されることがあるで。" @@ -1245,9 +1251,7 @@ showAvatarDecorations: "アイコンのデコレーション映す" releaseToRefresh: "離したらリロード" refreshing: "リロードしとる" pullDownToRefresh: "引っ張ってリロードするで" -disableStreamingTimeline: "タイムラインのリアルタイム更新をやめるで" useGroupedNotifications: "通知をグループ分けして出すで" -signupPendingError: "メアド確認してたらなんか変なことなったわ。リンクの期限切れてるかもしれん。" cwNotationRequired: "「内容を隠す」んやったら注釈書かなアカンで。" doReaction: "ツッコむで" code: "コード" @@ -1322,16 +1326,99 @@ federationSpecified: "このサーバーはホワイトリスト連合で運用 federationDisabled: "このサーバーは連合が無効化されてるで。他のサーバーのユーザーとやり取りすることはできひんで。" confirmOnReact: "ツッコむときに確認とる" reactAreYouSure: "\" {emoji} \" でツッコむ?" +markAsSensitiveConfirm: "このメディアをきわどい扱いしときますか?" +unmarkAsSensitiveConfirm: "このメディアはやっぱきわどくなかったってことでええんか?" +noName: "名前はあらへんで" +preferenceSyncConflictTitle: "サーバーに設定値があるみたいやわ" +preferenceSyncConflictText: "同期が有効にされた設定項目は設定値をサーバーに保存するねんけど、この設定項目はサーバーに保存されたやつがあるみたいやわ。どないするん?" +preferenceSyncConflictChoiceMerge: "ガッチャンコしよか" +preferenceSyncConflictChoiceCancel: "同期の有効化はやめとくわ" postForm: "投稿フォーム" information: "情報" +directMessage: "チャットしよか" +migrateOldSettings: "旧設定情報をお引っ越し" +migrateOldSettings_description: "通常これは自動で行われるはずなんやけど、なんかの理由で上手く移行できへんかったときは手動で移行処理をポチっとできるで。今の設定情報は上書きされるで。" +settingsMigrating: "設定を移行しとるで。ちょっと待っとってな... (後で、設定→その他→旧設定情報を移行 で手動で移行することもできるで)" +driveAboutTip: "ドライブでは、今までアップロードしたファイルがずらーっと表示されるで。
\nノートにファイルをもっかいのっけたり、あとで投稿するファイルをその辺に置いとくこともできるねん。
\nファイルをほかすと、前にそのファイルをのっけた全部の場所(ノート、ページ、アバター、バナー等)からも見えんくなるから気いつけてな。
\nフォルダを作って整理することもできるで。" +turnItOn: "オンにしとこ" +turnItOff: "オフでええわ" +emojiUnmute: "絵文字ミュートやめたる" +unmuteX: "{x}のミュートやめたる" +redisplayAllTips: "全部の「ヒントとコツ」をもっかい見して" +hideAllTips: "「ヒントとコツ」は全部表示せんでええ" +defaultImageCompressionLevel_description: "低くすると画質は保てるんやけど、ファイルサイズが増えるで。
高くするとファイルサイズは減らせるんやけど、画質が落ちるで。" +inMinutes: "分" +inDays: "日" +safeModeEnabled: "セーフモードがオンになってるで" +pluginsAreDisabledBecauseSafeMode: "セーフモードがオンやから、プラグインは全部無効化されてるで。" +customCssIsDisabledBecauseSafeMode: "セーフモードがオンやから、カスタムCSSは適用されてへんで。" +themeIsDefaultBecauseSafeMode: "セーフモードがオンの間はデフォルトのテーマを使うで。セーフモードをオフにれば元に戻るで。" +widgets: "ウィジェット" _chat: + noMessagesYet: "まだメッセージはあらへんで" + individualChat_description: "特定のユーザーと一対一でチャットができるで。" + roomChat_description: "複数人でチャットできるで。\nあと、個人チャットを許可してへんユーザーとでも、相手がええって言うならチャットできるで。" + inviteUserToChat: "ユーザーを招待してチャットを始めてみ" invitations: "来てや" + noInvitations: "招待はあらへんで" noHistory: "履歴はないわ。" + noRooms: "ルームはあらへんで" members: "メンバーはん" home: "ホーム" send: "送信" + deleteRoom: "ルームをほかす" + chatNotAvailableForThisAccountOrServer: "このサーバー、もしくはこのアカウントでチャットが有効にされてへんで。" + chatIsReadOnlyForThisAccountOrServer: "このサーバー、もしくはこのアカウントでチャットが読み取り専用になっとるわ。新しく書き込んだり、チャットルームを作ったり参加したりはできへんで。" + chatNotAvailableInOtherAccount: "相手のアカウントでチャット機能が使えんくなっとるみたいやわ。" + cannotChatWithTheUser: "このユーザーとのチャットを開始できへんみたいやわ" + cannotChatWithTheUser_description: "チャットが使えん状態になっとるか、相手がチャットを開放してへんみたいやわ。" + youAreNotAMemberOfThisRoomButInvited: "あんたはこのルームの参加者ちゃうけど、招待が届いとるで。参加するんやったら、招待を承認してな。" + doYouAcceptInvitation: "招待を承認してもええんか?" + chatWithThisUser: "チャットしよか" + thisUserAllowsChatOnlyFromFollowers: "このユーザーはフォロワーからのチャットしか受け付けとらんみたいやわ。" + thisUserAllowsChatOnlyFromFollowing: "このユーザーは、このユーザーがフォローしとるユーザーからのチャットしか受け付けとらんみたいやわ。" + thisUserAllowsChatOnlyFromMutualFollowing: "このユーザーは相互フォローのユーザーからのチャットしか受け付けとらんみたいやわ。" + thisUserNotAllowedChatAnyone: "このユーザーは誰からのチャットも受け付けとらんみたいやわ。" + chatAllowedUsers: "チャットしてもええ相手" + chatAllowedUsers_note: "自分からチャットメッセージを送った相手やったらこの設定に関わらずチャットできるで。" + _chatAllowedUsers: + followers: "自分のフォロワーだけ" + following: "自分がフォローしとるユーザーだけ" + mutual: "相互フォローのユーザーだけ" + none: "誰もかもあかん" +_emojiPalette: + enableSyncBetweenDevicesForPalettes: "パレットのデバイス間同期をつけとく" + paletteForMain: "メインで使うパレット" + paletteForReaction: "リアクションで使うパレット" _settings: + driveBanner: "ドライブの管理と設定、使用量の確認、ファイルをアップロードするときの設定ができるで。" + pluginBanner: "プラグインを使うとクライアントの機能を拡張できるねん。プラグインのインストール、個別の設定と管理ができるで。" + notificationsBanner: "サーバーから受け取る通知の種類とか範囲、プッシュ通知の設定ができるで。" webhook: "Webhook" + serviceConnectionBanner: "外部のアプリ・サービスと連携するのに使うとるアクセストークンとかWebhookの管理と設定ができるで。" + accountDataBanner: "アカウントデータのアーカイブをエクスポート/インポートして管理できるで。" + muteAndBlockBanner: "見せんでええコンテンツの設定とか、特定のユーザーからのアクションを制限する設定と管理ができるで。" + accessibilityBanner: "クライアントの視覚や動作に関わるパーソナライズをして、よりええ感じに使えるように設定できるで。" + privacyBanner: "コンテンツの公開範囲、見つけやすさ、フォローの承認制とかアカウントのプライバシーに関わる設定ができるで。" + securityBanner: "パスワード、ログイン方法、認証アプリ、パスキーとかアカウントのセキュリティに関わる設定ができるで。" + preferencesBanner: "好みに応じた、クライアントの全体的な動作の設定ができるで。" + appearanceBanner: "好みに応じた、クライアントの見た目・表示方法に関わる設定ができるで。" + soundsBanner: "クライアントで流すサウンドの設定ができるで。" + makeEveryTextElementsSelectable: "全部のテキスト要素を選択できるようにする" + makeEveryTextElementsSelectable_description: "これをつけると、一部のシチュエーションでユーザビリティが低下するかもしれん。" + enablePullToRefresh_description: "マウスやったら、ホイールを押し込みながらドラッグしてな。" + realtimeMode_description: "サーバーと接続を確立して、リアルタイムでコンテンツを更新するで。通信量とバッテリーの消費が多くなるかもしれへん。" + contentsUpdateFrequency_description: "高いほどリアルタイムにコンテンツが更新されるんやけど、そのぶんパフォーマンスが低くなるし、通信量とバッテリーの消費も増えるねん。" + contentsUpdateFrequency_description2: "リアルタイムモードをつけてるんやったら、この設定がどうであれリアルタイムでコンテンツが更新されるで。" +_preferencesProfile: + profileNameDescription: "このデバイスはなんて呼んだらええんや?" +_preferencesBackup: + noBackupsFoundTitle: "バックアップが見つからへんね" + noBackupsFoundDescription: "自動で作られたバックアップは見つからんかったけど、バックアップファイルを手動で保存してるんやったら、それをインポートして復元できるで。" + selectBackupToRestore: "復元するバックアップを選んでや" + youNeedToNameYourProfileToEnableAutoBackup: "自動バックアップを有効するんやったらプロファイル名の設定が必要やな。" + autoPreferencesBackupIsNotEnabledForThisDevice: "このデバイスで設定の自動バックアップは有効になってへんで。" + backupFound: "設定のバックアップがあるみたいやわ" _accountSettings: requireSigninToViewContents: "ログインしてもらってからコンテンツ見てもらう" requireSigninToViewContentsDescription1: "あなたが作成した全部のノートとかのコンテンツを見れるようにするのにログインがいるようにするで。クローラーにいろいろ収集されるんを防げるかもしれん。" @@ -1340,8 +1427,9 @@ _accountSettings: makeNotesFollowersOnlyBefore: "昔のノートをフォロワーだけに見てもらう" makeNotesFollowersOnlyBeforeDescription: "この機能が有効になってる間は、設定された日時より前、それか設定された時間が経ったノートがフォロワーのみ見れるようになるで。無効に戻すと、ノートの公開状態も戻るで。" makeNotesHiddenBefore: "昔のノートを見れんようにする" - makeNotesHiddenBeforeDescription: "この機能が有効になってる間は、設定された日時より前、それか設定された時間が経ったノートが自分のみ見れるようになるで。無効に戻すと、ノートの公開状態も戻るで。あとピン止めには影響せえへん。" + makeNotesHiddenBeforeDescription: "この機能が有効になってる間は、設定された日時より前、それか設定された時間が経ったノートがあんただけ見れるようになるで。無効に戻すと、ノートの公開状態も戻るで。" mayNotEffectForFederatedNotes: "リモートサーバーに連合されたノートには効果が及ばんかもしれん。" + mayNotEffectSomeSituations: "これらの制限は簡易的なものやで。リモートサーバーでの閲覧とかモデレーション時とか、一部のシチュエーションでは適用されへんかもしれん。" notesHavePassedSpecifiedPeriod: "決めた時間が経ったノート" notesOlderThanSpecifiedDateAndTime: "決めた日時より前のノート" _abuseUserReport: @@ -1360,6 +1448,7 @@ _delivery: manuallySuspended: "手動停止中" goneSuspended: "サーバー削除のため停止中" autoSuspendedForNotResponding: "サーバー応答せえへんから停止中" + softwareSuspended: "配信停止中のソフトウェアやから停止中" _bubbleGame: howToPlay: "遊び方" hold: "ホールド" @@ -1486,11 +1575,21 @@ _serverSettings: fanoutTimelineDbFallback: "データベースにフォールバックする" fanoutTimelineDbFallbackDescription: "有効にしたら、タイムラインがキャッシュん中に入ってないときにDBにもっかい問い合わせるフォールバック処理ってのをやっとくで。切ったらフォールバック処理をやらんからサーバーはもっと軽くなんねんけど、タイムラインの取得範囲がちょっと減るで。" reactionsBufferingDescription: "有効にしたら、リアクション作るときのパフォーマンスがすっごい上がって、データベースへの負荷が減るで。代わりに、Redisのメモリ使用は増えるで。" + remoteNotesCleaning_description: "つけると、参照されてへん古いリモートの投稿を定期的にクリーンアップしてデータベースの肥大化を抑えてくれるで。" inquiryUrl: "問い合わせ先URL" inquiryUrlDescription: "サーバー運営者へのお問い合わせフォームのURLや、運営者の連絡先等が記載されたWebページのURLを指定するで。" openRegistration: "アカウントの作成をオープンにする" openRegistrationWarning: "登録を解放するのはリスクが伴うで。サーバーをいっつも監視して、なんか起きたらすぐに対応できるんやったら、オンにしてもええと思う。" thisSettingWillAutomaticallyOffWhenModeratorsInactive: "一定期間モデレーターがおらんかったら、スパムを防ぐためにこの設定は勝手に切られるで。" + deliverSuspendedSoftwareDescription: "脆弱性とかの理由で、サーバーのソフトウェアの名前とバージョンの範囲を決めて配信を止められるで。このバージョン情報はサーバーが提供したものやから、信頼性は保証されへん。バージョン指定には semver の範囲指定が使えるねんけど、>= 2024.3.1と指定すると 2024.3.1-custom.0 みたいなカスタムバージョンが含まれへんから、>= 2024.3.1-0 みたいに prerelease を指定するとええかもしれへんな。" + singleUserMode_description: "このサーバーを使うとるんが自分だけなんやったら、このモードを有効にすると動作がええ感じになるで。" + signToActivityPubGet_description: "通常はつけといてな。連合の通信に関わる問題があるんやったら、無効にすると改善するかもしれへんけど、逆にサーバーによっては通信ができんくなることがあるで。" + proxyRemoteFiles_description: "つけると、リモートのファイルをプロキシして提供するで。画像のサムネイル生成とかユーザーのプライバシー保護にええな。" + allowExternalApRedirect_description: "つけると、他のサーバーがうちのサーバーを通して第三者のコンテンツを照会できるようになるんやけど、コンテンツのなりすましが発生するかもしれへん。" + userGeneratedContentsVisibilityForVisitor_description: "モデレーションが行き届きにくい不適切なリモートコンテンツとかが、うちのサーバー経由で図らずもインターネットに公開されてまうことによるトラブルを防止できたりするで。" + userGeneratedContentsVisibilityForVisitor_description2: "サーバーで受け取ったリモートのコンテンツを含め、サーバー内の全部のコンテンツを何でもかんでもインターネットに公開するのはリスクを伴うねん。特に、分散型の特性を知らん閲覧者にとっては、リモートのコンテンツやったとしてもサーバー内で作られたコンテンツやと誤認してまうかもしれへんから、注意が必要やな。" + restartServerSetupWizardConfirm_title: "サーバーの初期設定ウィザードをやり直すん?" + restartServerSetupWizardConfirm_text: "現在の一部の設定はリセットされるで。" _accountMigration: moveFrom: "別のアカウントからこのアカウントに引っ越す" moveFromSub: "別のアカウントへエイリアスを作る" @@ -1790,6 +1889,7 @@ _role: descriptionOfIsExplorable: "オンにしたらロールの面子一覧が「みつける」で公開されるし、ロールのタイムラインが使えるようになるで。" displayOrder: "表示順" descriptionOfDisplayOrder: "数がでかいほど、UI上で先に表示されるで。" + preserveAssignmentOnMoveAccount_description: "つけると、このロールがのっかったアカウントが引っ越したときに、引っ越し先アカウントにもこのロールがのっかるようになるで。" canEditMembersByModerator: "モデレーターがメンバーいじるのを許す" descriptionOfCanEditMembersByModerator: "オンにすると、管理者だけやなくてモデレーターもこのロールにユーザーを入れたり抜いたりできるで。オフにすると管理者だけしかやれへんくなるで。" priority: "優先度" @@ -1830,6 +1930,8 @@ _role: canImportFollowing: "フォローのインポートを許す" canImportMuting: "ミュートのインポートを許す" canImportUserLists: "リストのインポートを許す" + uploadableFileTypes_caption: "MIMEタイプを指定してや。改行で区切って複数指定もできるし、アスタリスク(*)でワイルドカード指定もできるで。(例: image/*)" + uploadableFileTypes_caption2: "ファイルによっては種別がわからんこともあるで。そないなファイルを許可するんやったら {x} を指定に追加してな。" _condition: roleAssignedTo: "マニュアルロールにアサイン済み" isLocal: "ローカルユーザー" @@ -2095,7 +2197,7 @@ _theme: navIndicator: "サイドバーのインジケーター" link: "リンク" hashtag: "ハッシュタグ" - mention: "メンション" + mention: "あんた宛て" mentionMe: "うち宛てのメンション" renote: "Renote" modalBg: "モーダルの背景" @@ -2112,7 +2214,6 @@ _theme: buttonBg: "ボタンの背景" buttonHoverBg: "ボタンの背景 (ホバー)" inputBorder: "入力ボックスの縁取り" - driveFolderBg: "ドライブフォルダーの背景" badge: "バッジ" messageBg: "チャットの背景" fgHighlighted: "強調されとる文字" @@ -2121,6 +2222,7 @@ _sfx: noteMy: "ノート(自分)" notification: "通知" reaction: "ツッコミ選んどるとき" + chatMessage: "チャットしよか" _soundSettings: driveFile: "ドライブん中の音使う" driveFileWarn: "ドライブん中のファイル選びや" @@ -2327,6 +2429,7 @@ _widgets: chooseList: "リストを選ぶ" clicker: "クリッカー" birthdayFollowings: "今日誕生日のツレ" + chat: "チャットしよか" _cw: hide: "隠す" show: "続き見して!" @@ -2366,6 +2469,8 @@ _visibility: disableFederation: "連合なし" disableFederationDescription: "他サーバーへは送らんとくわ" _postForm: + quitInspiteOfThereAreUnuploadedFilesConfirm: "アップロードされてへんファイルがあるんやけど、ほかしてフォームを閉じてもええんか?" + uploaderTip: "ファイルはまだアップロードされてへんで。ファイルのメニューから、リネームとか画像のクロップ、ウォーターマークをのっける、圧縮するかどうかなんかを設定できるで。ファイルはノートを投稿するときに自動でアップロードされるで。" replyPlaceholder: "このノートに返信..." quotePlaceholder: "このノートを引用..." channelPlaceholder: "チャンネルに投稿..." @@ -2519,6 +2624,7 @@ _notification: newNote: "さらの投稿" unreadAntennaNote: "アンテナ {name}" roleAssigned: "ロールが付与されたで" + chatRoomInvitationReceived: "チャットルームへ招待されたで" emptyPushNotificationMessage: "プッシュ通知の更新をしといたで" achievementEarned: "実績を獲得しとるで" testNotification: "通知テスト" @@ -2538,7 +2644,7 @@ _notification: all: "すべて" note: "あんたらの新規投稿" follow: "フォロー" - mention: "メンション" + mention: "あんた宛て" reply: "リプライ" renote: "リノート" quote: "引用" @@ -2589,6 +2695,7 @@ _deck: mentions: "あんた宛て" direct: "ダイレクト" roleTimeline: "ロールタイムライン" + chat: "チャットしよか" _dialog: charactersExceeded: "最大の文字数を上回っとるで!今は {current} / 最大でも {max}" charactersBelow: "最小の文字数を下回っとるで!今は {current} / 最低でも {min}" @@ -2709,7 +2816,7 @@ _externalResourceInstaller: _errors: _invalidParams: title: "" - description: "" + description: "外部サイトからデータを持ってくるのに欲しい情報が足らへんみたいやわ。URLは合っとる?" _resourceTypeNotSupported: title: "" description: "" @@ -2739,12 +2846,13 @@ _dataSaver: _avatar: title: "アイコンの絵" description: "アイコン画像のアニメが止まるで。普通の画像よりもデータ量がでかいから、もっと通信量を節約できるねん。" - _urlPreview: - title: "URLプレビューのサムネイル画像" - description: "URLプレビューのサムネイル画像が読み込まへんなるで。" + _urlPreviewThumbnail: + description: "URLプレビューのサムネイル画像が読み込まれへんくなるで。" + _disableUrlPreview: + description: "URLプレビュー機能を切るで。サムネイル画像だけと違って、リンク先の情報の読み込み自体を削減できるで。" _code: - title: "コードハイライト" - description: "MFMとかでコードハイライト記法が使われてるとき、タップするまで読み込まれへんくなるで。コードハイライトではハイライトする言語ごとにその決めてるファイルを読む必要はあんねんな。けどな、それは自動で読み込まれなくなるから、通信量を少なくできることができるねん。" + title: "コードハイライトは表示せんでええ" + description: "MFCとかでコードハイライト記法が使われてるとき、タップするまで読み込まれへんくなるで。コードハイライトではハイライトする言語ごとにその決めてるファイルを読む必要はあんねんな。けどな、それは自動で読み込まれなくなるから、通信量を少なくできることができるねん。" _hemisphere: N: "北半球" S: "南半球" @@ -2799,6 +2907,7 @@ _offlineScreen: _urlPreviewSetting: title: "URLプレビューの設定" enable: "URLプレビューを有効にする" + allowRedirectDescription: "入力されたURLがリダイレクトされるとき、そのリダイレクト先をたどってプレビューを表示するかどうかを設定できるで。無効にするとサーバーリソースを節約できるんやけど、リダイレクト先の内容は表示されへんくなるで。" timeout: "プレビュー取得時のタイムアウト(ms)" timeoutDescription: "プレビュー取得の所要時間がこの値を超えた場合、プレビューは生成されへんで。" maximumContentLength: "Content-Lengthの最大値(byte)" @@ -2872,10 +2981,6 @@ _customEmojisManager: uploadSettingDescription: "この画面で絵文字アップロードするときの動きを設定できるで。" directoryToCategoryLabel: "ディレクトリ名を\"category\"に入力する" directoryToCategoryCaption: "ディレクトリをドラッグ・ドロップした時に、ディレクトリ名を\"category\"に入力します。" - emojiInputAreaCaption: "どれかの方法で登録する絵文字を選択して。" - emojiInputAreaList1: "この枠に画像ファイルかディレクトリをドラッグ&ドロップ" - emojiInputAreaList2: "このリンクをクリックしてPCから選択する" - emojiInputAreaList3: "このリンクをクリックしてドライブから選択する" confirmRegisterEmojisDescription: "リストに表示されてる絵文字を新たなカスタム絵文字として登録するで。ほんまにええか? (サーバーがしんどくなるから、一回で登録できる絵文字は{count}件までやで)" confirmClearEmojisDescription: "編集内容をほかして、リストに表示されている絵文字をクリアするで。ほんまにええか?" confirmUploadEmojisDescription: "ドラッグ&ドロップされた{count}個のファイルをドライブにアップロードするで。ほんまにええか?" @@ -2947,5 +3052,83 @@ _search: searchScopeAll: "みんな" searchScopeLocal: "ローカル" searchScopeUser: "ユーザー指定" + pleaseEnterServerHost: "サーバーのホストはどないするん?" + pleaseSelectUser: "ユーザーを選んでや" +_serverSetupWizard: + installCompleted: "CherryPickのインストールが終わったで!" + firstCreateAccount: "最初は、管理者アカウントを作成しよか。" + accountCreated: "管理者アカウントができたで!" + youCanEasilyConfigureOptimalServerSettingsWithThisWizard: "このウィザードで簡単にええ感じのサーバーの設定ができるで。" + settingsYouMakeHereCanBeChangedLater: "ここでの設定は、あとからでも変えられるで。" + howWillYouUseMisskey: "CherryPickをどんな感じに使うん?" + _use: + single_youCanCreateMultipleAccounts: "お一人様サーバーとして運用するとしても、アカウントは必要に応じて複数作れるで。" + openServerAdvice: "不特定多数の利用者を受け入れるには相応のリスクがあるで。トラブルに対処できるよう、ちゃんとしたモデレーション体制で運営しいや。" + openServerAntiSpamAdvice: "うちのサーバーがスパムの踏み台にならへんように、reCAPTCHAとかのアンチボット機能を使う、みたいなセキュリティ対策もしっかり考えてな。" + howManyUsersDoYouExpect: "どれくらいの人数を考えとるん?" + largeScaleServerAdvice: "大規模なサーバーやったら、ロードバランシングとかデータベースのレプリケーションみたいな、高度なインフラストラクチャーの知識が必要になるかもしれへんわ。" + doYouConnectToFediverse: "Fediverseと接続するんやっけ?" + doYouConnectToFediverse_description1: "分散型サーバーでできたネットワーク(Fediverse)に繋げると、他のサーバーと相互にコンテンツのやり取りができるようになるで。" + doYouConnectToFediverse_description2: "Fediverseと接続することは「連合」とも呼ばれるな。" + youCanConfigureMoreFederationSettingsLater: "連合してもええサーバーの指定とか、高度な設定も後でできるで。" + remoteContentsCleaning_description: "連合すると、ぎょうさんコンテンツを受け取り続けることになるねん。自動クリーニングをつけると、参照されてない古いコンテンツを自動でサーバーからほかして、ストレージを節約できるで。" + adminInfo_description: "問い合わせを受け付けるのに使う管理者情報を設定しよか。" + adminInfo_mustBeFilled: "オープンサーバー、もしくは連合を入れとるんやったら必ず入力せなあかんで。" + followingSettingsAreRecommended: "こういう設定がええかもな" + settingsCompleted: "設定が終わったで!" + settingsCompleted_description: "お疲れさん。準備ができたから、さっそくサーバーを使い始められるで。" + settingsCompleted_description2: "細かいサーバー設定は、「コントロールパネル」を見てみてな。" + _donationRequest: + text1: "CherryPickは有志で開発されとる無料のソフトウェアやで。" + text2: "今後も開発を続けられるように、よかったらぜひカンパをお願いするわ。" + text3: "支援者向け特典もあるで!" +_uploader: + abortConfirm: "アップロードされてへんファイルがあるんやけど、やめてもええんか?" + doneConfirm: "アップロードされてへんファイルがあるんやけど、完了してもええんか?" + maxFileSizeIsX: "アップロードできるファイルサイズは{x}までやで。" + tip: "ファイルはまだアップロードされてへんで。このダイアログで、アップロードする前に確認・リネーム・圧縮・クロッピングとかをできるで。準備が出来たら、「アップロード」ボタンを押してアップロードしてな。" +_clientPerformanceIssueTip: + makeSureDisabledAdBlocker: "アドブロッカーを切ってみてや" + makeSureDisabledAdBlocker_description: "アドブロッカーはパフォーマンスに影響があるかもしれへん。OSの機能とかブラウザの機能・アドオンとかでアドブロッカーが有効になってないか確認してや。" + makeSureDisabledCustomCss: "カスタムCSSを無効にしてみてや" + makeSureDisabledCustomCss_description: "スタイルを上書きするとパフォーマンスに影響があるかもしれへん。カスタムCSSとか、スタイルを上書きする拡張機能が有効になってないか確認してや。" + makeSureDisabledAddons: "拡張機能を無効にしてみてや" + makeSureDisabledAddons_description: "なんかの拡張機能がクライアントの動作にちょっかいをかけてパフォーマンスに影響を与えてるかもしれへん。ブラウザの拡張機能を無効にして良くなるか確認してや。" +_clip: + tip: "クリップは、ノートをまとめられる機能やで。" +_userLists: + tip: "好きなユーザーを含むリストを作れるねん。作ったリストはタイムラインとして表示できるで。" +_watermarkEditor: + tip: "画像にクレジット情報とかのウォーターマークをのっけられるで。" + quitWithoutSaveConfirm: "保存せずに終わってもええんか?" + driveFileTypeWarn: "このファイルは対応しとらへん" + driveFileTypeWarnDescription: "画像ファイルを選んでや" + opacity: "不透明度" + scale: "大きさ" + text: "テキスト" + position: "位置" + type: "タイプ" + image: "画像" + advanced: "高度" + angle: "角度" +_imageEffector: + discardChangesConfirm: "変更をせんで終わるか?" + _fxProps: + angle: "角度" + scale: "大きさ" + size: "大きさ" + offset: "位置" + color: "色" + opacity: "不透明度" + lightness: "明るさ" +_drafts: + cannotCreateDraftAnymore: "下書きはこれ以上は作れへんな。" + cannotCreateDraft: "この内容で下書きは作れへんな。" + delete: "下書きをほかす" + deleteAreYouSure: "下書きをほかしてもええか?" + noDrafts: "下書きはあらへん" +_qr: + showTabTitle: "表示" + raw: "テキスト" noSendActivity: "アクティビティ送らへん" diff --git a/locales/kn-IN.yml b/locales/kn-IN.yml index f50ab8ebf4..cd5a2a2907 100644 --- a/locales/kn-IN.yml +++ b/locales/kn-IN.yml @@ -44,6 +44,7 @@ showMore: "ಇನ್ನಷ್ಟು ನೋಡು" youGotNewFollower: "ಹಿಂಬಾಲಿಸಿದರು" receiveFollowRequest: "ಹಿಂಬಾಲನೆ ವಿನಂತಿ ಬಂದಿದೆ" followRequestAccepted: "ಹಿಂಬಾಲನೆ ವಿನಂತಿ ಸ್ವೀಕರಿಸಲಾಯಿತು" +mention: "ಹೆಸರಿಸಿದ" mentions: "ಹೆಸರಿಸಿದ" directNotes: "ನೇರ ಟಿಪ್ಪಣಿಗಳು" importAndExport: "ಆಮದು/ರಫ್ತು" @@ -65,6 +66,9 @@ replies: "ಉತ್ತರಿಸು" _email: _follow: title: "ಹಿಂಬಾಲಿಸಿದರು" +_theme: + keys: + mention: "ಹೆಸರಿಸಿದ" _sfx: notification: "ಅಧಿಸೂಚನೆಗಳು" _widgets: @@ -73,11 +77,14 @@ _widgets: timeline: "ಸಮಯಸಾಲು" _cw: show: "ಇನ್ನಷ್ಟು ನೋಡು" +_visibility: + specified: "ನೇರ ಟಿಪ್ಪಣಿಗಳು" _profile: username: "ಬಳಕೆಹೆಸರು" _notification: youWereFollowed: "ಹಿಂಬಾಲಿಸಿದರು" _types: + mention: "ಹೆಸರಿಸಿದ" login: "ಪ್ರವೇಶ" _actions: reply: "ಉತ್ತರಿಸು" @@ -86,3 +93,4 @@ _deck: notifications: "ಅಧಿಸೂಚನೆಗಳು" tl: "ಸಮಯಸಾಲು" mentions: "ಹೆಸರಿಸಿದ" + direct: "ನೇರ ಟಿಪ್ಪಣಿಗಳು" diff --git a/locales/ko-GS.yml b/locales/ko-GS.yml index 4dcbb1ddb5..3cd2ddfa69 100644 --- a/locales/ko-GS.yml +++ b/locales/ko-GS.yml @@ -224,7 +224,6 @@ noUsers: "사용자가 어ᇝ십니다" editProfile: "프로필 적기" noteDeleteConfirm: "요 노트럴 뭉캡니꺼?" pinLimitExceeded: "더 몬 붙입니다" -intro: "CherryPick럴 다 깔앗십니다! 간리자 게정얼 맨걸어 보입시다." done: "햇어예" processing: "처리하고 잇어예" preview: "미리보기" @@ -746,7 +745,7 @@ _menuDisplay: _theme: description: "설멩" keys: - mention: "멘션" + mention: "받언 멘션" renote: "리노트" _sfx: note: "새 노트" @@ -776,6 +775,7 @@ _cw: _visibility: home: "덜머리" followers: "팔로워" + specified: "쪽지 서기" _postForm: _placeholders: e: "옇다 서 주이소" @@ -810,7 +810,7 @@ _notification: newNote: "새 걸" _types: follow: "팔로잉" - mention: "멘션" + mention: "받언 멘션" renote: "리노트" quote: "따오기" reaction: "반엉" @@ -825,6 +825,7 @@ _deck: antenna: "안테나" list: "리스트" mentions: "받언 멘션" + direct: "쪽지 서기" _webhookSettings: name: "이럼" _abuseReport: @@ -849,3 +850,7 @@ _remoteLookupErrors: _search: searchScopeAll: "말캉" searchScopeUser: "사용자 지정" +_watermarkEditor: + image: "이미지" +_qr: + showTabTitle: "보기" diff --git a/locales/ko-KR.yml b/locales/ko-KR.yml index d5368686c5..ae8456e0d3 100644 --- a/locales/ko-KR.yml +++ b/locales/ko-KR.yml @@ -1,5 +1,21 @@ --- _lang_: "한국어" +compareContent: "내용 비교하기" +editHistory: "편집 기록" +unRenoteAll: "모든 리노트 삭제" +unRenoteAllConfirm: "모든 리노트 삭제" +unRenoteAllConfirmDescription: "이 노트에 대한 모든 리노트를 삭제하려고 해요. 계속할까요?" +alreadyRenotedConfirm: "이미 리노트한 노트에요" +alreadyRenotedConfirmDescription: "이 노트를 이미 리노트했어요. 다시 리노트할까요?" +alreadyRenotedConfirmCaption: "Mastodon과 같은 일부 소프트웨어는 첫 번째 리노트만 취급하기 때문에 다시 리노트하면 이러한 서버에서는 표시되지 않을 수 있어요." +autoDeleteNotes: "노트 자동 삭제" +autoDeleteNotesDescription: "지정한 기간이 지난 노트를 자동으로 삭제해요." +autoDeleteNotesAfterDays: "자동 삭제 기간" +autoDeleteNotesAfterDaysDescription: "이 기간이 지난 노트는 자동으로 삭제돼요. 비활성화하려면 비워두세요." +autoDeleteKeepFavorites: "즐겨찾기한 노트 제외" +autoDeleteKeepFavoritesDescription: "활성화하면 즐겨찾기한 노트는 자동으로 삭제되지 않아요." +autoDeleteNotesWarning: "이 작업은 취소할 수 없으며, 삭제된 노트는 복구할 수 없으니 신중하게 결정해 주세요!" +scheduledToDeleteOnX: "{x}에 삭제가 예약되어 있어요." showGapBodyOfTheNote: "노트 본문 사이를 띄워서 표시" replyTo: "{user}님에게 보내는 답글" forceCollapseAllRenotes: "모든 리노트 간략화하기" @@ -10,7 +26,7 @@ setFederationAvatarShape: "프로필 아이콘 모양 설정 연합" setFederationAvatarShapeDescription: "이 설정을 켜면 내 프로필 아이콘의 모양(원형, 사각형)을 로컬 사용자 및 리모트 사용자에게 연합시킬 수 있고, 대응하는 서버의 사용자는 기능을 사용하고 있다면 해당 사용자가 지정한 프로필 아이콘 모양으로 보이게 돼요. 끄면 모든 사용자가 내가 설정한 프로필 아이콘 모양으로 보여요." keyboardShortcuts: "키보드 단축키" truncateAccount: "계정 정리" -truncateAccountConfirm: "다이렉트 메시지 및 고정된 노트와 관련된 파일을 제외한 모든 노트와 파일이 삭제돼요. 그래도 계속할까요?" +truncateAccountConfirm: "다이렉트 노트 및 고정된 노트와 관련된 파일을 제외한 모든 노트와 파일이 삭제돼요. 그래도 계속할까요?" bubbleTimeline: "버블 타임라인" bubbleTimelineDescription: "이 옵션을 활성화하고 모더레이션으로 이동해 버블 타임라인에 표시할 서버를 구성해 주세요." bubbleInstancesDescription: "버블 타임라인에 표시할 서버의 호스트 이름을 줄 바꿈으로 구분하여 설정해요." @@ -19,8 +35,6 @@ disableRegistrationWhenInactive: "모더레이터 부재 시 신규 회원가입 disablePublicNoteWhenInactive: "모더레이터 부재 시 '공개 노트 허용' 비활성화" youBlocked: "앗.. 차단당했어요.." youBlockedDescription: "{user} 님을 팔로우하거나 해당 사용자의 게시물을 볼 수 없어요." -schedulePost: "노트 게시 예약" -schedulePostList: "게시 예약된 노트 목록" thereIsSchedulePost: "{n}개의 게시 예약된 노트가 있어요." welcomeBackToast: "일정 시간이 지난 후 접속했을 때 환영 메시지 표시" invalidTextLengthError: "입력된 문자수가 너무 많아요" @@ -31,7 +45,6 @@ useAutoTranslate: "자동 번역" useAutoTranslateDescription: "자동 번역 기능을 활성화하면 타임라인의 모든 노트가 자동으로 번역되며, 이로 인해 번역 서비스 제공자가 설정한 API 제한 정책에 의해 번역 기능을 일시적으로 사용하지 못하게 될 가능성이 있어요.\n\n그래도 활성화 하시겠어요?" cantUseThisFunctionDescription: "서버 관리자가 {name}을(를) 사용할 수 없도록 설정했어요.\n{name}을(를) 사용하려면 서버 관리자에게 문의해 주세요." cantUseThisFunctionCaption: "활성화하면 다시 사용할 수 있을 때 {name}을(를) 적용해요." -widgets: "위젯" postNote: "노트 작성" bottomNavbar: "하단 내비게이션 바" bottomNavbarDescription: "이 설정은 모바일 환경에서만 사용할 수 있어요." @@ -79,8 +92,8 @@ noteEdited: "노트를 편집했어요!" noteDrafted: "노트를 저장했어요!" createSchedulePost: "노트 게시를 예약했어요!" removeModalBgColorForBlur: "모달 배경색 제거" -skipThisVersion: "이 릴리즈 건너뛰기" -enableReceivePrerelease: "출시 전 버전 알림 받기" +skipThisVersion: "이 버전 건너뛰기" +enableReceivePrerelease: "베타 버전 알림 받기" youAreRunningBetaClient: "아직 출시되지 않은 버전의 CherryPick을 이용하고 있어요!" cherrypickUpdate: "CherryPick 업데이트" allMediaNoteCollapse: "모든 미디어 노트 간략화하기" @@ -254,8 +267,8 @@ renoteToOtherChannel: "다른 채널에 리노트" pinnedNote: "고정된 노트" pinned: "프로필에 고정" you: "나" -clickToShow: "클릭하여 보기" -doubleClickToShow: "두 번 탭하여 보기" +clickToShow: "클릭해서 보기" +doubleClickToShow: "두 번 탭해서 보기" sensitive: "열람 주의" add: "추가" reaction: "리액션" @@ -340,7 +353,7 @@ instances: "서버" registeredAt: "등록 날짜" latestRequestReceivedAt: "마지막으로 요청을 받은 시간" latestStatus: "마지막 상태" -storageUsage: "스토리지 사용량" +storageUsage: "저장 공간 사용량" charts: "차트" perHour: "1시간마다" perDay: "1일마다" @@ -350,6 +363,7 @@ silenceThisInstance: "서버를 사일런스" mediaSilenceThisInstance: "서버의 미디어를 사일런스" operations: "작업" software: "소프트웨어" +softwareName: "소프트웨어 이름" version: "버전" metadata: "메타데이터" withNFiles: "{n}개의 파일" @@ -380,9 +394,9 @@ noUsers: "아무도 없어요" editProfile: "프로필 수정" noteDeleteConfirm: "이 노트를 삭제할까요?" pinLimitExceeded: "더 이상 고정할 수 없어요." -intro: "CherryPick의 설치를 완료했어요! 이제 관리자 계정을 만들 차례에요." done: "완료" processing: "처리 중" +preprocessing: "준비 중" preview: "미리보기" default: "기본값" defaultValueIs: "기본값: {value}" @@ -428,10 +442,11 @@ uploadFromUrl: "URL 업로드" uploadFromUrlDescription: "업로드하려는 파일의 URL" uploadFromUrlRequested: "업로드를 요청했어요" uploadFromUrlMayTakeTime: "업로드가 완료될 때까지 약간의 시간이 필요할 수 있어요." +uploadNFiles: "{n}개의 파일 업로드" explore: "둘러보기" messageRead: "읽음" noMoreHistory: "타임머신이 더 이상은 돌아갈 수 없대요!" -startChat: "채팅 시작하기" +startChat: "쪽지 보내기" nUsersRead: "{n}명이 읽음" agreeTo: "{0}에 동의" agree: "동의합니다" @@ -456,11 +471,13 @@ dark: "다크" lightThemes: "밝은 테마" darkThemes: "어두운 테마" syncDeviceDarkMode: "디바이스의 다크 모드 설정과 동기화" +switchDarkModeManuallyWhenSyncEnabledConfirm: "'{x}'가 켜져 있어요. 동기화를 끄고 수동으로 모드를 변경하시겠어요?" drive: "드라이브" fileName: "파일명" selectFile: "파일 선택" selectFiles: "파일 선택" selectFolder: "폴더 선택" +unselectFolder: "폴더 선택 해제" selectFolders: "폴더 선택" fileNotSelected: "파일을 선택하지 않았어요." renameFile: "파일 이름 변경" @@ -473,6 +490,7 @@ addFile: "파일 추가" showFile: "파일 표시하기" emptyDrive: "드라이브에 아무것도 없어요!" emptyFolder: "폴더에 아무것도 없어요!" +dropHereToUpload: "업로드할 파일을 여기로 끌어서 놓아주세요." unableToDelete: "삭제할 수 없어요!" inputNewFileName: "바꿀 파일명을 입력해 주세요" inputNewDescription: "새 캡션을 입력해 주세요" @@ -485,7 +503,7 @@ avatar: "아바타" banner: "배너" displayOfSensitiveMedia: "민감한 미디어 표시" whenServerDisconnected: "서버와의 접속이 끊겼을 때" -disconnectedFromServer: "접속이 끊어졌어요!" +disconnectedFromServer: "서버와 접속이 끊어졌어요!" reload: "새로고침" doNothing: "무시하기" reloadConfirm: "페이지를 다시 불러올까요?" @@ -552,7 +570,7 @@ antennaKeywords: "받을 키워드" antennaExcludeKeywords: "제외할 키워드" antennaExcludeBots: "봇 계정 제외" antennaKeywordsDescription: "공백으로 구분하는 경우 AND, 줄 바꿈으로 구분하는 경우 OR로 지정할 수 있어요" -notifyAntenna: "새로운 노트를 알림" +notifyAntenna: "새 노트가 있으면 알리기" withFileAntenna: "파일이 첨부된 노트만" excludeNotesInSensitiveChannel: "민감한 채널의 노트 제외" enableServiceworker: "ServiceWorker 사용" @@ -628,8 +646,7 @@ inviteToGroup: "그룹에 초대하기" quoteAttached: "인용함" quoteQuestion: "인용해서 작성하시겠어요?" attachAsFileQuestion: "붙여 넣으려는 글이 너무 길어요. 텍스트 파일로 첨부할까요?" -newMessageExists: "새로운 메시지가 있어요!" -onlyOneFileCanBeAttached: "메시지에는 하나의 파일만 첨부할 수 있어요!" +onlyOneFileCanBeAttached: "쪽지에는 하나의 파일만 첨부할 수 있어요!" signinRequired: "진행하기 전에 먼저 로그인이 필요해요" signinOrContinueOnRemote: "계속하려면 사용하는 계정이 있는 서버로 이동하거나 이 서버에 가입 또는 로그인해야 해요." invitations: "초대" @@ -719,13 +736,10 @@ showFixedPostFormInChannel: "채널 타임라인 상단에 글 입력란 표시" withRepliesByDefaultForNewlyFollowed: "팔로우 할 때 기본적으로 답글을 타임라인에 나오게 하기" newNoteRecived: "새 노트가 있어요!" newNoteRecivedCount: "{n}개의 새 노트가 있어요!" +newNote: "새로운 노트" sounds: "소리" sound: "소리" -vibrations: "진동" -soundsAndVibrations: "소리 및 진동" -playVibrations: "진동 재생" -playVibrationsDescription: "이 기능을 지원하지 않는 브라우저이거나 디바이스가 iOS/iPadOS인 경우에는 지원되지 않아요." -testVibrations: "진동 테스트" +notificationSoundSettings: "알림 설정" listen: "듣기" none: "없음" showInPage: "페이지로 보기" @@ -893,7 +907,7 @@ unclip: "클립 해제" confirmToUnclipAlreadyClippedNote: "이 노트는 이미 ‘{name}’ 클립에 포함되어 있어요. 노트를 클립에서 제외할까요?" public: "공개" private: "비공개" -i18nInfo: "CherryPick은 자원봉사자들에 의해 다양한 언어로 번역되고 있어요. {link}에서 번역에 참가할 수 있어요." +i18nInfo: "CherryPick은 기여자들에 의해 다양한 언어로 번역되고 있어요. {link}에서 번역에 참가할 수 있어요." manageAccessTokens: "액세스 토큰 관리" accountInfo: "계정 정보" notesCount: "노트 수" @@ -917,7 +931,8 @@ lockedAccountInfo: "팔로우를 승인으로만 받더라도 노트의 공개 alwaysMarkSensitive: "미디어를 항상 열람 주의로 설정" loadRawImages: "첨부한 이미지의 썸네일을 원본 화질로 표시" disableShowingAnimatedImages: "움직이는 이미지를 자동으로 재생하지 않음" -disableShowingAnimatedImagesDescription: "비활성화 하면 움직이는 이미지가 재생돼요. 광과민성 발작을 일으킬 수 있으므로 주의해 주세요." +disableShowingAnimatedImagesDescription: "비활성화하면 움직이는 이미지가 재생돼요. 광과민성 발작을 일으킬 수 있으므로 주의해 주세요." +disableShowingAnimatedImages_caption: "이 설정을 비활성화해도 움직이는 이미지가 재생되지 않으면 브라우저나 OS의 접근성 설정이나 절전 설정 등의 영향을 받고 있을 수 있어요." highlightSensitiveMedia: "민감한 미디어를 돋보이게 표시" verificationEmailSent: "확인 메일을 발송했어요! 설정을 완료하려면 메일에 첨부된 링크를 확인해 주세요.\n만약 메일이 오지 않는다면 스팸 메일함을 확인해 주세요!" notSet: "설정되지 않음" @@ -943,6 +958,7 @@ narrow: "좁게" reloadToApplySetting: "이 설정을 적용하려면 페이지를 다시 불러와야 해요. 지금 페이지를 새로 고칠까요?" reloadToApplySetting2: "이 설정을 적용하려면 페이지를 다시 불러와야 해요." needReloadToApply: "변경 사항은 페이지를 다시 불러오면 적용돼요." +needToRestartServerToApply: "변경 사항은 서버를 재시작하면 적용돼요." showTitlebar: "타이틀 바 표시하기" clearCache: "캐시 비우기" onlineUsersCount: "{n}명이 접속 중" @@ -967,7 +983,7 @@ registry: "레지스트리" closeAccount: "계정 폐쇄" currentVersion: "현재 버전" latestVersion: "최신 버전" -youAreRunningUpToDateClient: "최신 버전의 클라이언트를 사용하고 있어요!" +youAreRunningUpToDateClient: "최신 버전의 CherryPick을 사용하고 있어요!" newVersionOfClientAvailable: "CherryPick의 새 업데이트를 이용할 수 있어요!" usageAmount: "사용량" capacity: "용량" @@ -1043,7 +1059,7 @@ searchResult: "검색 결과" hashtags: "해시태그" troubleshooting: "문제 해결" useBlurEffect: "UI에 흐림 효과 사용" -useBlurEffectDescription: "활성화 하면 더욱 아름다운 테마를 사용할 수 있어요!" +useBlurEffectDescription: "활성화하면 더욱 아름다운 테마를 사용할 수 있어요!" learnMore: "자세히" misskeyUpdated: "CherryPick이 업데이트 되었어요!" whatIsNew: "패치 정보 보기" @@ -1152,6 +1168,7 @@ failedToUpload: "업로드 실패" cannotUploadBecauseInappropriate: "이 파일은 부적절한 내용을 포함한다고 판단되어 업로드할 수 없어요!" cannotUploadBecauseNoFreeSpace: "드라이브에 용량이 부족해서 업로드할 수 없었어요.." cannotUploadBecauseExceedsFileSizeLimit: "파일 크기가 너무 크기 때문에 업로드할 수 없어요!" +cannotUploadBecauseUnallowedFileType: "이 파일은 허용되지 않은 유형의 파일이므로 업로드할 수 없어요." beta: "베타" enableAutoSensitive: "자동으로 민감한 미디어 탐지" enableAutoSensitiveDescription: "사용 가능한 경우, 기계학습을 통해 자동으로 미디어에 NSFW를 설정할 거예요. 이 기능을 해제하더라도, 서버 정책에 따라 자동으로 설정될 수 있어요." @@ -1165,8 +1182,8 @@ subscribePushNotification: "푸시 알림 켜기" unsubscribePushNotification: "푸시 알림 끄기" pushNotificationAlreadySubscribed: "푸시 알림이 이미 켜져 있어요!" pushNotificationNotSupported: "브라우저나 서버에서 푸시 알림을 지원하지 않아요.." -sendPushNotificationReadMessage: "푸시 알림이나 메시지를 읽은 뒤 푸시 알림을 삭제하기" -sendPushNotificationReadMessageCaption: "「{emptyPushNotificationMessage}」 라는 알림이 잠깐 표시돼요. 기기의 전력 소비량이 증가할 수 있어요." +sendPushNotificationReadMessage: "푸시 알림이나 쪽지를 읽은 뒤 푸시 알림을 삭제하기" +sendPushNotificationReadMessageCaption: "기기의 전력 소비량이 증가할 수 있어요." windowMaximize: "최대화" windowMinimize: "최소화" windowRestore: "복구" @@ -1203,6 +1220,7 @@ permissionDeniedError: "작업이 거부되었어요" permissionDeniedErrorDescription: "이 작업을 수행할 권한이 없어요." preset: "프리셋" selectFromPresets: "프리셋에서 선택" +custom: "사용자 지정" achievements: "도전 과제" gotInvalidResponseError: "서버의 응답이 올바르지 않아요.." gotInvalidResponseErrorDescription: "서버가 다운되었거나 점검 중일 가능성이 있어요. 잠시 후에 다시 접속해 주세요." @@ -1242,6 +1260,7 @@ prohibitedWordsDescription2: "공백으로 구분하면 AND로 지정되고, 키 hiddenTags: "숨긴 해시태그" hiddenTagsDescription: "설정한 태그가 트렌드에 표시되지 않아요. 줄 바꿈으로 하나씩 나눠서 설정할 수 있어요." notesSearchNotAvailable: "노트 검색을 이용할 수 없어요." +usersSearchNotAvailable: "사용자 검색을 이용할 수 없어요." license: "라이선스" unfavoriteConfirm: "즐겨찾기를 해제할까요?" myClips: "내 클립" @@ -1313,12 +1332,13 @@ rolesThatCanBeUsedThisEmojiAsReactionPublicRoleWarn: "역할은 공개로 설정 cancelReactionConfirm: "리액션을 취소할까요?" changeReactionConfirm: "리액션을 변경할까요?" later: "나중에" -goToMisskey: "CherryPick으로" +goToMisskey: "CherryPick으로 이동" additionalEmojiDictionary: "이모지 추가 사전" installed: "설치됨" branding: "브랜딩" enableServerMachineStats: "서버의 머신 사양을 공개하기" -enableIdenticonGeneration: "사용자마다 Identicon 생성 유효화" +enableIdenticonGeneration: "사용자마다 Identicon 생성" +showRoleBadgesOfRemoteUsers: "리모트 사용자 역할 배지 표시" turnOffToImprovePerformance: "이 기능을 끄면 성능이 향상될 수 있어요." createInviteCode: "초대 코드 생성" createWithOptions: "옵션을 지정하여 생성" @@ -1326,7 +1346,7 @@ createCount: "초대 수" inviteCodeCreated: "초대 코드 생성됨" inviteLimitExceeded: "초대 코드의 생성 한도를 초과했어요." createLimitRemaining: "초대 한도: {limit}회 남음" -inviteLimitResetCycle: " {time}시간 이내에 최대 {limit}개의 초대 코드를 생성할 수 있어요." +inviteLimitResetCycle: "{time}시간 이내에 최대 {limit}개의 초대 코드를 생성할 수 있어요." expirationDate: "만료 날짜" noExpirationDate: "만료기간 없음" inviteCodeUsedAt: "다음에 사용된 초대 코드" @@ -1366,8 +1386,8 @@ showRenotes: "리노트 표시" edited: "편집됨" notificationRecieveConfig: "알림 설정" mutualFollow: "맞팔로우" -followingOrFollower: "팔로 중이거나 팔로워" -fileAttachedOnly: "미디어를 포함한 노트만" +followingOrFollower: "팔로잉 또는 팔로워" +fileAttachedOnly: "미디어가 포함된 노트만 표시" showRepliesToOthersInTimeline: "타임라인에 다른 사람에게 보내는 답글을 포함" hideRepliesToOthersInTimeline: "타임라인에 다른 사람에게 보내는 답글을 포함하지 않음" showRepliesToOthersInTimelineAll: "타임라인에 팔로우 중인 모든 사람의 답글 표시" @@ -1401,7 +1421,8 @@ releaseToRefresh: "놓아서 새로 고침" refreshing: "새로 고침 중" pullDownToRefresh: "당겨서 새로 고침" disableStreamingTimeline: "타임라인 실시간 업데이트 비활성화" -useGroupedNotifications: "알림을 묶어서 표시" +useGroupedNotifications: "그룹으로 알림 표시" +emailVerificationFailedError: "메일 주소 확인에 실패했어요. 확인에 사용되는 URL의 기간이 만료되었을 수 있어요." signupPendingError: "메일 주소 확인중에 문제가 발생했어요. 링크의 유효기간이 지났을 수도 있어요." cwNotationRequired: "'내용 가리기'를 체크했을 경우 주석을 작성해야 해요." doReaction: "리액션 추가" @@ -1472,6 +1493,8 @@ availableRoles: "사용 가능한 역할" acknowledgeNotesAndEnable: "이 기능을 활성화 하기 전에 주의 사항을 확인했어요." federationSpecified: "이 서버는 화이트 리스트 제도로 운영되고 있어요. 정해진 리모트 서버가 아닌 경우 연합되지 않아요." federationDisabled: "이 서버는 다른 서버와 연합하지 않도록 설정되었어요. 따라서 리모트 서버의 사용자와 통신할 수 없어요." +draft: "초안" +draftsAndScheduledNotes: "초안 및 예약 게시물" confirmOnReact: "리액션할 때 확인하기" reactAreYouSure: "\" {emoji} \"로 리액션할까요?" markAsSensitiveConfirm: "이 미디어를 민감한 미디어로 설정할까요?" @@ -1489,6 +1512,7 @@ restore: "복원" syncBetweenDevices: "장치 간 동기화" preferenceSyncConflictTitle: "서버에 설정값이 이미 존재하는 것 같아요." preferenceSyncConflictText: "동기화를 활성화 한 항목의 설정 값은 서버에 저장돼요. 이 항목은 이미 설정 값이 서버에 저장되어 있어요. 어느 쪽의 설정 값을 덮어쓸까요?" +preferenceSyncConflictChoiceMerge: "병합" preferenceSyncConflictChoiceServer: "서버 설정값" preferenceSyncConflictChoiceDevice: "장치 설정값" preferenceSyncConflictChoiceCancel: "동기화 취소" @@ -1498,6 +1522,8 @@ postForm: "글 입력란" textCount: "문자 수" information: "정보" chat: "채팅" +directMessage: "쪽지 보내기" +directMessage_short: "쪽지" migrateOldSettings: "기존 설정 정보 이전" migrateOldSettings_description: "보통은 자동으로 진행되지만, 이전 과정에서 문제가 발생해 성공적으로 이전이 이루어지지 않은 경우 수동으로 이전을 실행할 수 있어요. 현재 설정 정보는 덮어쓰게 돼요." compress: "압축" @@ -1509,7 +1535,40 @@ settingsMigrating: "설정을 이전하고 있어요. 잠시만 기다려 주세 readonly: "읽기 전용" goToDeck: "덱으로 돌아가기" federationJobs: "연합 작업" -draft: "초안" +driveAboutTip: "드라이브는 이전에 업로드한 파일 목록을 표시해요.
\n노트에 첨부할 때 다시 사용하거나 나중에 게시할 파일을 미리 업로드할 수 있어요.
\n파일을 삭제하면, 지금까지 그 파일을 사용한 모든 장소(노트, 페이지, 아바타, 배너 등)에서도 보이지 않게 되므로 주의해 주세요. 폴더를 만들고 정리할 수도 있어요.
" +scrollToClose: "스크롤해서 닫기" +advice: "참고" +realtimeMode: "실시간 모드" +turnItOn: "켜기" +turnItOff: "끄기" +emojiMute: "이모티콘 뮤트" +emojiUnmute: "이모티콘 뮤트 해제" +muteX: "{x} 뮤트" +unmuteX: "{x}의 뮤트 해제" +abort: "중지" +tip: "팁과 유용한 정보" +redisplayAllTips: "모든 '팁과 유용한 정보'를 다시 표시하기" +hideAllTips: "모든 '팁과 유용한 정보'를 표시하지 않도록 설정" +defaultImageCompressionLevel: "기본 이미지 압축률" +defaultImageCompressionLevel_description: "이 값을 낮추면 화질을 유지하지만 파일 크기가 증가해요.
값을 높이면 파일 크기가 줄어들지만 화질이 저하돼요." +defaultCompressionLevel: "기본 압축률" +defaultCompressionLevel_description: "이 값을 낮추면 품질을 유지하지만 파일 크기가 증가해요.
값을 높이면 파일 크기가 줄어들지만 품질이 저하돼요." +inMinutes: "분" +inDays: "일" +safeModeEnabled: "안전 모드가 켜져있어요" +pluginsAreDisabledBecauseSafeMode: "안전 모드가 활성화되어 플러그인이 모두 비활성화되었어요." +customCssIsDisabledBecauseSafeMode: "안전 모드가 활성화되어 CSS 사용자화가 적용되지 않아요." +themeIsDefaultBecauseSafeMode: "안전 모드를 사용하는 동안에는 기본 테마가 사용돼요. 안전 모드를 비활성화하면 기존 테마로 다시 복원돼요." +thankYouForTestingBeta: "베타 버전 검증에 협력해 주셔서 감사합니다!" +createUserSpecifiedNote: "다이렉트 노트 작성" +schedulePost: "게시 예약" +scheduleToPostOnX: "{x}에 게시를 예약했어요." +scheduledToPostOnX: "{x}에 게시가 예약되어 있어요." +schedule: "예약" +scheduled: "예약" +widgets: "위젯" +deviceInfo: "장치 정보" +deviceInfoDescription: "기술적인 부분에 대한 문의는 아래 정보를 포함하면 문제 해결에 많은 도움이 돼요." draftNoteList: "초안으로 저장된 노트 목록" saveAsDraft: "초안으로 저장" showUnreadNotificationsCount: "읽지 않은 알림 수 표시" @@ -1524,61 +1583,76 @@ open: "열기" _nsfwOpenBehavior: click: "탭하여 열기" doubleClick: "두 번 탭하여 열기" -_vibrations: - click: "요소를 클릭했을 때" - note: "타임라인에 새 노트가 올라왔을 때" - notification: "알림을 수신했을 때" - system: "시스템 햅틱" _showingAnimatedImages: always: "항상 움직임" interaction: "건드리면 움직임" inactive: "일정 시간이 지나면 멈춤" +_compression: + _quality: + high: "높음" + medium: "보통" + low: "낮음" + _size: + large: "큼" + medium: "보통" + small: "작음" +_order: + newest: "최신 순" + oldest: "오래된 순" _chat: - noMessagesYet: "아직 메시지가 없어요.\n간단하게 인사로 시작해 보는 것은 어떨까요?" - newMessage: "새로운 메시지" - individualChat: "개인 대화" - individualChat_description: "특정 사용자와 일대일 채팅을 할 수 있어요." - roomChat: "룸 채팅" - roomChat_description: "여러 명이 함께 채팅할 수 있어요.\n또한, 개인 채팅을 허용하지 않은 사용자도 상대방이 수락하면 채팅을 할 수 있어요." - createRoom: "룸 생성" - inviteUserToChat: "사용자를 초대해 채팅을 시작하세요" - yourRooms: "생성한 룸" - joiningRooms: "참가 중인 룸" + messages: "쪽지" + noMessagesYet: "아직 아무런 대화도 시작하지 않았어요.\n간단하게 인사로 시작해 보는 것은 어떨까요?" + newMessage: "새로운 쪽지" + individualChat: "개인" + individualChat_description: "단일 사용자와 대화를 주고 받을 수 있어요." + roomChat: "그룹" + roomChat_description: "여러 명이 함께 대화할 수 있어요.\n또한, 개인 쪽지를 허용하지 않는 사용자도 상대방이 수락하면 쪽지를 보낼 수 있어요." + createRoom: "그룹 생성" + inviteUserToChat: "사용자를 초대하고 대화를 시작해 보세요!" + yourRooms: "생성한 그룹" + joiningRooms: "참가 중인 그룹" invitations: "초대" - noInvitations: "초대장이 없어요" - history: "채팅 내역" + noInvitations: "받은 초대가 없어요" + history: "대화 기록" noHistory: "너무.. 너무 조용해요.." - noRooms: "룸이 없어요" + noRooms: "그룹이 없어요" inviteUser: "사용자 초대" - sentInvitations: "초대 보내기" + sentInvitations: "보낸 초대" join: "참여" + reject: "거부" ignore: "무시" - leave: "룸 떠나기" + leave: "그룹 나가기" members: "멤버" - searchMessages: "메시지 검색" + searchMessages: "쪽지 검색" home: "홈" send: "전송" newline: "줄 바꿈" - muteThisRoom: "이 룸 뮤트" - deleteRoom: "룸 삭제" - chatNotAvailableForThisAccountOrServer: "이 서버 또는 이 계정에서 채팅이 활성화되어 있지 않아요." - chatIsReadOnlyForThisAccountOrServer: "이 서버 또는 이 계정에서의 채팅은 읽기 전용으로 설정되어 있어요. 채팅을 새로 전송하거나, 채팅 룸을 만들거나 참가할 수 없어요." - chatNotAvailableInOtherAccount: "상대방 계정에서 채팅 기능을 사용할 수 없는 상태에요." - cannotChatWithTheUser: "이 사용자와 채팅을 시작할 수 없어요" - cannotChatWithTheUser_description: "채팅을 사용할 수 없는 상태이거나 상대방이 채팅을 열지 않은 상태에요." - chatWithThisUser: "채팅하기" - thisUserAllowsChatOnlyFromFollowers: "이 사용자는 팔로워만 채팅을 할 수 있도록 설정했어요." - thisUserAllowsChatOnlyFromFollowing: "이 사용자는 자신이 팔로우 중인 사용자만 채팅을 허용하고 있어요." - thisUserAllowsChatOnlyFromMutualFollowing: "이 사용자는 서로 팔로우하고 있는 사용자만 채팅을 허용하고 있어요." - thisUserNotAllowedChatAnyone: "이 사용자는 다른 사람의 채팅을 받지 않도록 설정했어요." - chatAllowedUsers: "채팅을 허용한 상대" - chatAllowedUsers_note: "내가 채팅 메시지를 보낸 상대와는 이 설정에 영향을 받지 않고 채팅을 할 수 있어요." + muteThisRoom: "이 그룹 뮤트" + deleteRoom: "그룹 삭제" + chatNotAvailableForThisAccountOrServer: "이 서버 또는 계정에서 쪽지가 활성화되어 있지 않아요." + chatIsReadOnlyForThisAccountOrServer: "이 서버 또는 계정에서 쪽지가 읽기 전용으로 설정되어 있어요. 쪽지를 새로 전송하거나, 그룹을 만들거나 참가할 수 없어요." + chatNotAvailableInOtherAccount: "상대방이 쪽지를 사용할 수 없는 상태에요. 쪽지를 보내면 다이렉트 노트로 전송되며, 상대방이 다이렉트 노트에 답장하면 여기서 볼 수 있어요." + cannotChatWithTheUser: "이 사용자와 대화를 시작할 수 없어요" + cannotChatWithTheUser_description: "쪽지를 사용할 수 없는 상태이거나 상대방이 아직 쪽지를 열지 않은 상태에요." + youAreNotAMemberOfThisRoomButInvited: "이 그룹의 참가자가 아니지만 초대를 받은 상태에요. 참가하려면 초대를 수락해 주세요." + doYouAcceptInvitation: "초대를 수락하시겠어요?" + chatWithThisUser: "쪽지 보내기" + thisUserAllowsChatOnlyFromFollowers: "이 사용자는 팔로워만 쪽지를 보낼 수 있도록 설정했어요." + thisUserAllowsChatOnlyFromFollowing: "이 사용자는 자신이 팔로우 중인 사용자의 쪽지만 허용하고 있어요." + thisUserAllowsChatOnlyFromMutualFollowing: "이 사용자는 서로 팔로우하고 있는 사용자의 쪽지만 허용하고 있어요." + thisUserNotAllowedChatAnyone: "이 사용자는 다른 사람의 쪽지를 받지 않도록 설정했어요." + chatAllowedUsers: "쪽지를 허용한 상대" + chatAllowedUsers_note: "내가 먼저 쪽지를 보낸 상대와는 이 설정에 영향을 받지 않고 쪽지를 보낼 수 있어요." _chatAllowedUsers: everyone: "누구나" followers: "나를 팔로우하는 사용자만" following: "내가 팔로우한 사용자만" mutual: "서로 팔로우한 사용자만" - none: "아무도 채팅을 보낼 수 없음" + none: "아무도 쪽지를 보낼 수 없음" + usersCount: "{n}명이 참여 중" + invitationCancelAreYouSure: "{x}님에게 보낸 초대를 취소할까요?" + ignoreThisInvitation: "이 초대를 무시하면 그룹의 관리자가 초대를 취소하고 다시 초대하거나, 그룹을 삭제하고 다시 만든 경우에만 초대받을 수 있어요." + doYouIgnoreInvitation: "이 초대를 무시하시겠어요?" _emojiPalette: palettes: "팔레트" enableSyncBetweenDevicesForPalettes: "팔레트의 디바이스 간 동기화" @@ -1603,20 +1677,33 @@ _settings: appearanceBanner: "취향에 알맞는 클라이언트의 디스플레이, 표시 방법에 관한 설정을 변경할 수 있어요." soundsBanner: "클라이언트에서 재생되는 소리에 대한 설정을 변경할 수 있어요." timelineAndNote: "타임라인과 노트" - makeEveryTextElementsSelectable: "모든 텍스트 요소를 선택할 수 있도록 함" - makeEveryTextElementsSelectable_description: "활성화 시, 일부 동작에서 사용자의 접근성이 나빠질 수도 있어요." - useStickyIcons: "아이콘이 스크롤을 따라가도록 하기" + makeEveryTextElementsSelectable: "모든 텍스트 요소를 선택 가능하도록 설정" + makeEveryTextElementsSelectable_description: "활성화하면 일부 동작에서 접근성이 나빠질 수도 있어요." + useStickyIcons: "프로필 아이콘이 스크롤에 반응하도록 설정" + enableHighQualityImagePlaceholders: "고품질 이미지를 위한 자리 표시자 표시" + uiAnimations: "UI 애니메이션" showNavbarSubButtons: "내비게이션 바에 보조 버튼 표시" ifOn: "켜져 있을 때" ifOff: "꺼져 있을 때" enableSyncThemesBetweenDevices: "기기 간 설치한 테마 동기화" + enablePullToRefresh: "당겨서 새로 고침" + enablePullToRefresh_description: "마우스를 사용하는 경우 스크롤 휠을 누른 채로 드래그 하세요." + realtimeMode_description: "서버에 접속하여 콘텐츠를 실시간으로 업데이트하게 돼요. 데이터 사용량과 배터리 및 메모리의 소비가 증가할 수 있어요." + contentsUpdateFrequency: "콘텐츠 업데이트 빈도" + contentsUpdateFrequency_description: "높을수록 콘텐츠가 더 자주 업데이트되지만 성능이 저하되고 데이터 사용량과 배터리 소비가 증가해요." + contentsUpdateFrequency_description2: "실시간 모드가 켜져 있을 때는 이 설정과 관계없이 콘텐츠가 실시간으로 업데이트돼요." + showUrlPreview: "URL 미리보기 표시" + showAvailableReactionsFirstInNote: "사용 가능한 리액션을 맨 위에 표시" + showPageTabBarBottom: "페이지 탭 바를 아래쪽에 표시" + smoothTransitionAnimations: "부드러운 전환 애니메이션" _chat: - showSenderName: "발신자 이름 표시" - sendOnEnter: "엔터로 보내기" + showSenderName: "보낸 사람 이름 표시" + sendOnEnter: "엔터로 쪽지 전송" _preferencesProfile: profileName: "프로필 이름" profileNameDescription: "이 디바이스를 식별할 이름을 설정해 주세요." profileNameDescription2: "예: '메인 PC', '스마트폰' 등" + manageProfiles: "프로필 관리" _preferencesBackup: autoBackup: "자동 백업" restoreFromBackup: "백업으로 복구" @@ -1652,9 +1739,10 @@ _delivery: resume: "전송 재개" _type: none: "배포 중" - manuallySuspended: "수동 정지 상태" - goneSuspended: "서버 삭제로 인한 정지 상태" + manuallySuspended: "수동으로 정지됨" + goneSuspended: "서버 삭제로 인해 정지됨" autoSuspendedForNotResponding: "서버가 응답하지 않아 일시적으로 정지됨" + softwareSuspended: "전달이 중지된 소프트웨어이므로 정지됨" _bubbleGame: howToPlay: "플레이 방법" hold: "홀드" @@ -1693,13 +1781,13 @@ _cherrypick: nickname: "닉네임 기능" nicknameDescription: "사용자 페이지에서 이름을 클릭 또는 탭하여 원하는 이름으로 변경할 수 있어요. 변경한 이름은 자신에게만 반영돼요.\n자주 이름을 바꾸는 사용자를 식별하는 데 사용할 수 있어요." useEnterToSend: "Enter 키를 눌러 보내기" - useEnterToSendDescription: "옵션을 활성화하면 줄 바꿈은 Shift + Enter 키로 할 수 있어요. 대화를 전송할 때는 옵션의 영향을 받지 않아요." + useEnterToSendDescription: "옵션을 활성화하면 줄 바꿈은 Shift + Enter 키로 할 수 있어요. 대화를 전송할 때는 이 설정의 영향을 받지 않아요." postFormVisibilityHotkey: "단축키로 공개 범위 전환하기" postFormVisibilityHotkeyDescription: "노트를 작성할 때, Ctrl(control) + Shift 키를 누르면 공개 범위를 전환할 수 있어요. 로컬에만 보이게 하는 단축키는 Ctrl(command 또는 control) + Alt(option) 키에요." showRenoteConfirmPopup: "리노트할 때 확인 팝업 표시" showRenoteConfirmPopupDescription: "이 설정은 '일반 → 리노트와 인용 버튼을 분리해서 표시하기' 설정이 켜져 있어야 해요." - expandOnNoteClick: "노트를 클릭하여 자세히 표시" - expandOnNoteClickDescription: "비활성화한 경우에도 노트 메뉴에서 '자세히'를 클릭하거나 타임스탬프를 클릭하여 열 수 있어요." + expandOnNoteClick: "노트를 클릭해 자세히 표시" + expandOnNoteClickDescription: "비활성화한 경우에도 노트 메뉴에서 '자세히'를 클릭하거나, 타임스탬프를 클릭하면 열 수 있어요." expandOnNoteClickBehavior: "노트를 클릭해서 열 때" _expandOnNoteClickBehavior: click: "클릭해서 열기" @@ -1776,7 +1864,7 @@ _initialTutorial: _reaction: title: "'리액션'이란 무엇인가요?" description: "노트에 '리액션'을 보낼 수 있어요. '좋아요!' 만으로는 충분히 전해지지 않는 감정을, 이모지에 실어서 보낼 수 있어요." - letsTryReacting: "리액션은 노트의 '+' 버튼을 클릭하여 붙일 수 있어요. 지금 표시되는 예시 노트에 리액션을 달아보세요!" + letsTryReacting: "리액션은 노트의 '+' 버튼을 클릭해서 붙일 수 있어요. 지금 표시되는 예시 노트에 리액션을 달아보세요!" reactToContinue: "다음 단계를 진행하기 위해서는 먼저 예시 노트에 리액션을 달아야 해요." reactNotification: "누군가가 나의 노트에 리액션을 보내면 실시간으로 알림을 받을 수 있어요." reactDone: "'-' 버튼을 눌러서 리액션을 취소할 수 있어요." @@ -1787,6 +1875,8 @@ _initialTutorial: local: "이 서버에 있는 모든 사용자의 게시물을 볼 수 있어요." social: "홈 타임라인과 로컬 타임라인의 게시물을 모두 볼 수 있어요." global: "연결되어 있는 모든 서버의 게시물을 볼 수 있어요." + media: "미디어가 포함된 홈 타임라인과 로컬 타임라인의 게시물을 볼 수 있어요." + bubble: "관리자가 설정한 서버의 게시물을 볼 수 있어요." description2: "각각의 타임라인은 화면 상단에서 언제든지 변경할 수 있어요." description3: "이 외에도, '리스트 타임라인'이나 '채널 타임라인' 등이 있어요. 자세한 사항은 {link}에서 확인하실 수 있어요." _postNote: @@ -1799,7 +1889,7 @@ _initialTutorial: followers: "팔로워에게만 노트를 공개해요. 자기 자신을 제외하고는 리노트를 할 수 없고, 팔로워 외에는 노트의 내용을 볼 수 없어요." direct: "지정한 사용자에게만 노트가 공개되며, 노트에 지정된 상대방에게 알림이 보내져요." doNotSendConfidencialOnDirect1: "민감한 정보를 보낼 때에는 주의해 주세요." - doNotSendConfidencialOnDirect2: "서버 관리자는 기술적으로 노트의 내용을 열람할 수 있기 때문에, 신뢰할 수 없는 서버의 사용자에게 다이렉트 메시지를 보내는 경우, 노트를 보내기 전에 민감한 정보가 포함되어 있는지 먼저 확인해 주세요." + doNotSendConfidencialOnDirect2: "서버 관리자는 기술적으로 노트의 내용을 열람할 수 있기 때문에, 신뢰할 수 없는 서버의 사용자에게 다이렉트 노트를 보내는 경우, 노트를 보내기 전에 민감한 정보가 포함되어 있는지 먼저 확인해 주세요." localOnly: "다른 서버에 노트를 보내지 않아요. 앞서 설정한 공개 범위와 상관 없이 다른 서버의 사용자는 이 노트를 볼 수 없어요." _cw: title: "내용 가리기 (CW)" @@ -1814,18 +1904,19 @@ _initialTutorial: tryThisFile: "이 입력란에 첨부된 이미지를 열람 주의로 설정해 보세요!" _exampleNote: note: "낫토 뚜껑 뜯다가 실수했다…" - method: "첨부 파일을 열람 주의로 설정하려면, 해당 파일을 클릭하여 메뉴를 열고, '열람 주의로 설정'을 클릭해 주세요." + method: "첨부 파일을 열람 주의로 설정하려면 해당 파일을 클릭해서 메뉴를 열고, '열람 주의로 설정'을 클릭해 주세요." sensitiveSucceeded: "파일을 첨부할 때에는 서버의 가이드라인에 따라 열람 주의를 적절히 사용해 주세요." doItToContinue: "이미지를 열람 주의로 설정하면 다음 단계로 넘어갈 수 있어요." _done: title: "튜토리얼이 끝났습니다! 🎉" description: "여기에서 소개한 기능은 최소한의 사용을 위한 가장 기본적인 기능만을 다뤘어요. CherryPick의 사용 방법을 더 자세히 알아보려면 {link}를 확인해 주세요!" _timelineDescription: - home: "홈 타임라인에서는, 내가 팔로우한 계정의 게시물을 볼 수 있어요." - local: "로컬 타임라인에서는, 이 서버의 모든 사용자의 게시물을 볼 수 있어요." - social: "소셜 타임라인에서는, 홈 타임라인과 로컬 타임라인의 게시물을 모두 볼 수 있어요." - global: "글로벌 타임라인에서는, 여기와 연결된 다른 모든 서버의 게시물을 볼 수 있어요." - bubble: "버블 타임라인에서는, 관리자가 설정한 서버의 게시물을 볼 수 있어요." + home: "홈 타임라인에서는 내가 팔로우한 계정의 게시물을 볼 수 있어요." + local: "로컬 타임라인에서는 이 서버의 모든 사용자의 게시물을 볼 수 있어요." + social: "소셜 타임라인에서는 홈 타임라인과 로컬 타임라인의 게시물을 모두 볼 수 있어요." + global: "글로벌 타임라인에서는 여기와 연결된 다른 모든 서버의 게시물을 볼 수 있어요." + media: "미디어 타임라인에서는 미디어가 포함된 홈 타임라인과 로컬 타임라인의 게시물을 볼 수 있어요." + bubble: "버블 타임라인에서는 관리자가 설정한 서버의 게시물을 볼 수 있어요." _serverRules: description: "회원 가입 이전에 간단하게 표시할 서버 규칙이에요. 이용 약관의 요약으로 구성하는 것을 추천해요." _event: @@ -1867,11 +1958,37 @@ _serverSettings: fanoutTimelineDbFallback: "데이터베이스 폴백" fanoutTimelineDbFallbackDescription: "활성화하면 타임라인의 캐시되어 있지 않은 부분에 대해서는 DB에 추가로 쿼리하는 폴백 처리를 수행해요. 비활성화하면 폴백 처리를 하지 않아 서버의 부하를 줄일 수 있지만, 타임라인을 가져올 수 있는 범위가 한정돼요." reactionsBufferingDescription: "활성화하면 노트에 리액션할 때의 성능이 대폭 향상되어 DB의 부하를 줄일 수 있지만, Redis의 메모리 사용량이 많아져요." + remoteNotesCleaning: "리모트 서버 노트 자동 정리" + remoteNotesCleaning_description: "더 이상 사용하지 않는 오래된 리모트 노트를 정기적으로 정리해 데이터베이스의 사용량을 절약할 수 있어요." + remoteNotesCleaningMaxProcessingDuration: "자동 정리 최대 처리 시간" + remoteNotesCleaningExpiryDaysForEachNotes: "노트 보관 최소 일수" inquiryUrl: "문의처 URL" inquiryUrlDescription: "서버 운영자에게 보내는 문의 양식의 URL이나 운영자의 연락처 등이 적힌 웹 페이지의 URL을 설정할 수 있어요." openRegistration: "공개 회원 가입 활성화" openRegistrationWarning: "누구나 회원 가입을 할 수 있도록 설정하는 것은 리스크가 따르게 돼요. 관리자 또는 모더레이터가 서버를 항상 감시할 수 있고, 문제가 발생했을 때 바로 대응할 수 있는 상태에서만 활성화 하는 것을 권장해요." thisSettingWillAutomaticallyOffWhenModeratorsInactive: "일정 기간동안 모더레이터가 활동이 없으면 스팸 방지를 위해 이 설정은 자동으로 비활성화 돼요." + deliverSuspendedSoftware: "전달 중지 중인 소프트웨어" + deliverSuspendedSoftwareDescription: "취약점과 같은 이유로 서버의 소프트웨어 이름 및 버전 범위를 지정해 전달을 정지할 수 있어요. 이 버전 정보는 서버에서 제공된 것으로 신뢰성은 보장되지 않아요. 버전 지정에는 semver의 범위 지정을 사용할 수 있지만, >= 2024.3.1로 지정하면 2024.3.1-custom.0과 같은 custom.0과 같은 custom 버전이 포함되지 않기 때문에 >= 2024.3.1-0과 같이 prerelease를 지정하는 것이 좋아요." + singleUserMode: "단일 사용자 모드" + singleUserMode_description: "이 서버를 혼자 사용하고 있다면, 이 모드를 활성화해 동작을 최적화할 수 있어요." + signToActivityPubGet: "ActivityPub GET 요청 서명" + signToActivityPubGet_description: "일반적으로 이 기능은 활성화되어 있어야 해요. 연합 간 통신에 문제가 있는 경우에는 비활성화하면 문제가 해결될 수도 있지만, 서버에 따라서는 연합 간 통신이 불가능해질 수 있어요." + proxyRemoteFiles: "리모트 파일 프록시" + proxyRemoteFiles_description: "활성화하면 리모트 파일을 프록시를 통해 제공해요. 이미지의 섬네일을 생성해 사용자의 개인 정보를 보호할 수 있어요." + allowExternalApRedirect: "ActivityPub을 통한 리디렉션 허용" + allowExternalApRedirect_description: "활성화하면 다른 서버가 이 서버를 통해 제3자의 콘텐츠를 조회할 수 있지만, 콘텐츠 스푸핑과 같은 문제가 발생할 수 있어요." + userGeneratedContentsVisibilityForVisitor: "게스트에게 사용자 생성 콘텐츠의 표시 여부" + userGeneratedContentsVisibilityForVisitor_description: "이 기능은 적절하게 관리되지 않은 부적절한 리모트 콘텐츠가 사용자의 서버를 통해 의도치 않게 인터넷에 게시되는 것을 방지하는 데 유용해요." + userGeneratedContentsVisibilityForVisitor_description2: "서버에 수신된 리모트 콘텐츠를 포함하여 서버의 모든 콘텐츠를 인터넷에 무조건 게시하는 것은 위험해요. 특히, 콘텐츠의 분산된 특성을 모르는 게스트는 리모트 콘텐츠조차도 서버 내 사용자가 생성한 콘텐츠라고 오해할 수 있기 때문이에요." + restartServerSetupWizardConfirm_title: "서버 설정 마법사를 다시 시작할까요?" + restartServerSetupWizardConfirm_text: "이미 설정한 항목들 중 일부가 재설정돼요." + entrancePageStyle: "로그인 페이지 스타일" + showTimelineForVisitor: "타임라인 표시" + showActivitiesForVisitor: "활동 표시" + _userGeneratedContentsVisibilityForVisitor: + all: "모두 공개" + localOnly: "로컬 콘텐츠만 공개하고 리모트 콘텐츠는 비공개" + none: "모두 비공개" _accountMigration: moveFrom: "다른 계정에서 이 계정으로 이사" moveFromSub: "다른 계정에 대한 별칭을 생성" @@ -2196,6 +2313,8 @@ _role: canManageCustomEmojis: "커스텀 이모지 관리" canManageAvatarDecorations: "아바타 장식 관리" driveCapacity: "드라이브 용량" + maxFileSize: "업로드 가능한 최대 파일 크기" + maxFileSize_caption: "역방향 프록시 또는 CDN과 같은 다른 환경에서 지정된 값이 있을 수 있어요. 만약 역방향 프록시 또는 CDN 등에서 최대 파일 크기를 지정한 경우, 여기에서 설정한 값보다 작다면 해당 값을 따르게 돼요." alwaysMarkNsfw: "파일을 항상 NSFW로 지정" canUpdateBioMedia: "아바타 및 배너 이미지 변경 허용" pinMax: "고정할 수 있는 최대 노트 수" @@ -2210,6 +2329,7 @@ _role: descriptionOfRateLimitFactor: "작을수록 제한이 완화되고, 클수록 제한이 강화돼요." canHideAds: "광고 숨기기" canSearchNotes: "노트 검색 이용" + canSearchUsers: "사용자 검색 이용" canUseTranslator: "번역 기능 이용" canUseAutoTranslate: "자동 번역 기능 이용" canUseAutoTranslateDescription: "자동 번역 기능을 활성화한 사용자는 타임라인의 모든 노트가 자동으로 번역되며, 이로 인해 번역 서비스 제공자가 설정한 API 제한에 매우 빠르게 도달해 번역 기능을 일시적으로 사용하지 못하게 될 가능성이 있어요.\n이는 서버 내 모든 사용자가 API를 일시적으로 사용하지 못하게 될 수도 있다는 것을 의미해요.\n또한 번역 서비스 제공자에 따라 API 사용으로 인한 요금이 과도하게 발생할 수 있어요.\n\n그래도 활성화 하시겠어요?" @@ -2219,8 +2339,13 @@ _role: canImportFollowing: "팔로우 가져오기 허용" canImportMuting: "뮤트 목록 가져오기 허용" canImportUserLists: "리스트 목록 가져오기 허용" - chatAvailability: "채팅 사용 허용" + chatAvailability: "쪽지 사용 허용" + uploadableFileTypes: "업로드 가능한 파일 유형" + uploadableFileTypes_caption: "허용할 MIME/파일 유형을 지정할 수 있어요. 여러 MIME 유형은 줄 바꿈으로 구분해서 지정할 수 있고, 와일드카드는 별표(*)로 지정할 수 있어요." + uploadableFileTypes_caption2: "파일에 따라서는 유형을 검사하지 못할 수 있어요. 이러한 파일을 허용하려면 사양에 {x}을(를) 추가해 주세요." noteDraftLimit: "서버에 저장 가능한 최대 노트 초안 수" + scheduledNoteLimit: "예약 게시물의 최대 작성 가능 수" + watermarkAvailable: "워터마크 기능 사용 여부" canSetFederationAvatarShape: "프로필 아이콘 모양 설정 연합 허용" _condition: roleAssignedTo: "수동 역할에 이미 할당됨" @@ -2452,7 +2577,7 @@ _channel: notesCount: "{n}노트" nameAndDescription: "이름과 설명" nameOnly: "이름만" - allowRenoteToExternal: "채널 외부로의 리노트와 인용 리노트를 허가" + allowRenoteToExternal: "채널 외부에서 리노트 및 인용 허용" _menuDisplay: sideFull: "가로" sideIcon: "가로(아이콘)" @@ -2472,6 +2597,7 @@ _theme: install: "테마 설치" manage: "테마 관리" code: "테마 코드" + copyThemeCode: "테마 코드 복사" description: "설명" installed: "{name} 테마를 설치했어요!" installedThemes: "설치된 테마" @@ -2530,7 +2656,6 @@ _theme: buttonBg: "버튼 배경" buttonHoverBg: "버튼 배경 (호버)" inputBorder: "입력 필드 테두리" - driveFolderBg: "드라이브 폴더 배경" badge: "배지" messageBg: "대화 배경" fgHighlighted: "강조된 텍스트" @@ -2541,7 +2666,7 @@ _sfx: noteEdited: "노트 편집" notification: "알림" reaction: "리액션 선택" - chatMessage: "채팅 메시지" + chatMessage: "쪽지 수신" _soundSettings: driveFile: "드라이브에 있는 오디오 파일 사용" driveFileWarn: "드라이브에 있는 파일을 선택해 주세요." @@ -2574,6 +2699,7 @@ _time: minute: "분" hour: "시간" day: "일" + month: "개월" _2fa: alreadyRegistered: "이미 설정되어 있어요!" registerTOTP: "인증 앱 설정 시작" @@ -2597,7 +2723,7 @@ _2fa: renewTOTPConfirm: "기존에 등록되어 있던 인증 키는 더 이상 사용할 수 없게 돼요." renewTOTPOk: "재설정" renewTOTPCancel: "취소" - checkBackupCodesBeforeCloseThisWizard: "이 위자드를 닫기 전에 아래 백업 코드를 확인하십시오" + checkBackupCodesBeforeCloseThisWizard: "이 창을 닫기 전에 아래 백업 코드를 반드시 확인해 주세요." backupCodes: "백업 코드" backupCodesDescription: "인증 앱을 사용할 수 없게 된 경우, 아래 백업 코드를 사용하여 계정에 접근할 수 있어요. 이 코드들은 반드시 안전한 장소에 보관해 주세요! 각 코드는 한 번만 사용할 수 있어요." backupCodeUsedWarning: "백업 코드가 사용됐어요. 인증 앱을 사용할 수 없게 된 경우, 반드시 인증 앱을 다시 설정해 주세요!" @@ -2614,13 +2740,11 @@ _permissions: "write:favorites": "즐겨찾기에 추가하거나 삭제합니다" "read:following": "팔로우 상태를 봅니다" "write:following": "팔로우하거나 팔로우를 해제합니다" - "read:messaging": "대화를 읽습니다" - "write:messaging": "대화를 시작하거나 메시지를 보냅니다" + "read:messaging": "쪽지를 읽습니다" + "write:messaging": "대화를 시작하거나 쪽지를 보냅니다" "read:mutes": "뮤트 여부를 확인합니다" "write:mutes": "뮤트를 하거나 해제합니다" "write:notes": "노트를 작성하거나 삭제합니다" - "read:notes-schedule": "게시를 예약한 노트를 봅니다" - "write:notes-schedule": "노트 게시를 예약하거나 삭제합니다" "read:notifications": "알림을 확인합니다" "write:notifications": "알림을 모두 읽음 처리합니다" "read:reactions": "리액션을 확인합니다" @@ -2690,7 +2814,8 @@ _permissions: "read:clip-favorite": "클립의 좋아요 보기" "read:federation": "연합 정보 불러오기" "write:report-abuse": "위반 내용 신고하기" - "write:chat": "대화를 시작하거나 메시지 보내기" + "write:chat": "대화를 시작하거나 쪽지 보내기" + "read:chat": "쪽지 읽기" _auth: shareAccessTitle: "애플리케이션 접근 허가" shareAccess: "‘{name}’에서 계정에 접근하는 것을 허용할까요?" @@ -2704,6 +2829,7 @@ _auth: scopeUser: "이 사용자로 활동하고 있어요." pleaseLogin: "애플리케이션의 접근을 허가하려면 먼저 로그인해 주세요." byClickingYouWillBeRedirectedToThisUrl: "접근을 허용하게 되면 다음 URL로 이동해요." + alreadyAuthorized: "이 애플리케이션은 이미 접근이 허가되었어요." _antennaSources: all: "모든 노트" homeTimeline: "팔로우중인 사용자의 노트" @@ -2750,7 +2876,7 @@ _widgets: chooseList: "리스트 선택" clicker: "클리커" birthdayFollowings: "오늘 생일인 사용자" - chat: "채팅" + chat: "쪽지" search: "검색" dice: "주사위" weather: "날씨" @@ -2794,6 +2920,8 @@ _visibility: disableFederationDescription: "다른 서버로 보내지 않을래요" _postForm: signinRequiredPlaceholder: "노트를 작성하려면 로그인이 필요해요." + quitInspiteOfThereAreUnuploadedFilesConfirm: "아직 업로드되지 않은 파일이 있어요. 그래도 창을 닫을까요?" + uploaderTip: "파일이 아직 업로드되지 않았어요. 파일 메뉴에서 파일 이름 변경, 이미지 자르기, 워터마크 추가, 파일 압축/압축 해제할 수 있어요. 노트를 게시하면 파일이 자동으로 업로드돼요." replyPlaceholder: "이 노트에 답글..." quotePlaceholder: "이 노트를 인용..." channelPlaceholder: "채널에 게시하기..." @@ -2844,8 +2972,8 @@ _charts: notesTotal: "노트 수 합계" filesIncDec: "파일 수 변동" filesTotal: "파일 수 합계" - storageUsageIncDec: "스토리지 사용량 변동" - storageUsageTotal: "스토리지 사용량 합계" + storageUsageIncDec: "저장 공간 사용량 변동" + storageUsageTotal: "저장 공간 사용량 합계" _instanceCharts: requests: "요청" users: "사용자 수 변동" @@ -2863,6 +2991,7 @@ _timelines: local: "로컬" social: "소셜" global: "글로벌" + media: "미디어" bubble: "버블" _play: new: "Play 만들기" @@ -2945,10 +3074,12 @@ _notification: yourFollowRequestAccepted: "팔로우 요청이 수락됐어요!" youWereInvitedToGroup: "{userName} 님이 그룹에 초대했어요!" pollEnded: "투표 결과가 발표됐어요!" + scheduledNotePosted: "예약한 노트가 게시됐어요!" + scheduledNotePostFailed: "예약한 노트를 게시하지 못했어요.." newNote: "새 게시물" unreadAntennaNote: "안테나 {name}" roleAssigned: "새 역할이 할당됐어요!" - chatRoomInvitationReceived: "채팅 룸에 초대됐어요!" + chatRoomInvitationReceived: "그룹에 초대됐어요!" emptyPushNotificationMessage: "새 알림이 있어요!" achievementEarned: "도전 과제를 달성했어요!" testNotification: "알림 테스트" @@ -2967,7 +3098,7 @@ _notification: createToken: "액세스 토큰이 생성됐어요" createTokenDescription: "만약 본인이 생성한 것이 아니라면 '{text}'를 통해 액세스 토큰을 삭제해 주세요." _types: - all: "전부" + all: "모든 알림" note: "사용자의 새 게시물" follow: "팔로잉" mention: "멘션" @@ -2976,11 +3107,13 @@ _notification: quote: "인용" reaction: "리액션" pollEnded: "투표가 종료됨" + scheduledNotePosted: "예약한 노트 게시" + scheduledNotePostFailed: "예약한 노트 게시에 실패함" receiveFollowRequest: "팔로우 요청을 받음" followRequestAccepted: "팔로우 요청이 승인됨" groupInvited: "그룹에 초대됨" roleAssigned: "역할이 할당됨" - chatRoomInvitationReceived: "채팅 룸에 초대됨" + chatRoomInvitationReceived: "그룹에 초대됨" achievementEarned: "도전 과제 획득" exportCompleted: "내보내기를 완료함" login: "로그인" @@ -2992,12 +3125,6 @@ _notification: followBack: "팔로우" reply: "답글" renote: "리노트" - _scheduleNote: - unknown: "알 수 없는 오류가 발생했어요" - renoteTargetNotFound: "인용할 대상이 없어요" - channelTargetNotFound: "해당 채널이 존재하지 않아요" - replyTargetNotFound: "답글을 작성할 대상이 없어요" - invalidFilesCount: "첨부 파일이 없어요" _deck: alwaysShowMainColumn: "메인 칼럼 항상 표시" columnAlign: "칼럼 정렬" @@ -3034,7 +3161,7 @@ _deck: mentions: "받은 멘션" direct: "다이렉트" roleTimeline: "역할 타임라인" - chat: "채팅" + chat: "쪽지" _dialog: charactersExceeded: "최대 글자수를 초과했어요! 현재 {current} / 최대 {max}" charactersBelow: "최소 글자수 미만이에요! 현재 {current} / 최소 {min}" @@ -3132,7 +3259,7 @@ _moderationLogTypes: deletePage: "페이지를 삭제" deleteFlash: "Play를 삭제" deleteGalleryPost: "갤러리 게시물 삭제" - deleteChatRoom: "채팅 룸 삭제" + deleteChatRoom: "그룹 삭제" updateProxyAccountDescription: "프록시 계정의 설명 업데이트" _fileViewer: title: "파일 상세" @@ -3141,6 +3268,7 @@ _fileViewer: url: "URL" uploadedAt: "업로드 날짜" attachedNotes: "첨부된 노트" + usage: "이용" thisPageCanBeSeenFromTheAuthor: "이 페이지는 파일 소유자만 열람할 수 있어요" _externalResourceInstaller: title: "외부 사이트에서 설치" @@ -3187,13 +3315,16 @@ _dataSaver: title: "미디어 불러오기 방지" description: "이미지/동영상이 자동으로 로드되는 것을 방지해요. 탭하면 숨겨진 이미지/동영상을 불러올 수 있어요." _avatar: - title: "움직이는 프로필 아이콘" + title: "움직이는 프로필 아이콘 비활성화" description: "움직이는 프로필 아이콘이 정적 이미지로 변경되어 표시돼요. 움직이는 이미지는 일반 이미지보다 파일 크기가 클 수 있기 때문에 데이터 통신량을 더욱 줄일 수 있어요." - _urlPreview: - title: "URL 미리보기 썸네일" + _urlPreviewThumbnail: + title: "URL 미리보기 썸네일 비활성화" description: "URL 미리보기의 썸네일 이미지를 불러오지 않아요." + _disableUrlPreview: + title: "URL 미리보기 비활성화" + description: "URL 미리보기를 표시하지 않아요. 이 기능은 링크된 정보를 불러오는 시간을 단축시킬 수 있어요." _code: - title: "코드 문법 강조" + title: "코드 문법 자동 강조 비활성화" description: "MFC 등에서 코드 문법 강조 기법을 사용할 때, 클릭하기 전까지는 불러오지 않아요. 코드 문법 강조 기능은 강조할 언어마다 해당 정의 파일을 불러와야 하지만, 이를 자동으로 불러오지 않게 되어 데이터 사용량을 줄일 수 있어요." _hemisphere: N: "북반구" @@ -3250,17 +3381,19 @@ _offlineScreen: _urlPreviewSetting: title: "URL 미리보기 설정" enable: "URL 미리보기 활성화" - timeout: "미리보기를 불러올 때의 타임아웃 (ms)" - timeoutDescription: "미리보기를 로딩하는데 걸리는 시간이 지정한 시간보다 오래 걸리면 미리보기를 생성하지 않아요." - maximumContentLength: "Content-Length의 최대치 (byte)" + allowRedirect: "URL 미리보기 리디렉션 허용" + allowRedirectDescription: "URL에 리디렉션이 설정된 경우, 이 기능을 활성화하면 리디렉션된 콘텐츠의 미리보기를 표시할 수 있어요. 이 기능을 비활성화하면 서버 리소스는 절약되지만, 리디렉션된 콘텐츠가 표시되지 않아요." + timeout: "미리보기 로드 타임아웃(ms)" + timeoutDescription: "미리보기를 불러올 때 걸리는 시간이 지정한 시간을 초과하는 경우 미리보기를 생성하지 않아요." + maximumContentLength: "최대 콘텐츠 길이(바이트)" maximumContentLengthDescription: "Content-Length가 이 값을 넘어서면 미리보기를 생성하지 않아요." requireContentLength: "Content-Length를 반환했을 때만 미리보기 만들기" requireContentLengthDescription: "리모트 서버가 Content-Length를 반환하지 않는다면 미리보기를 만들지 않아요." userAgent: "User-Agent" userAgentDescription: "미리보기를 얻을 때 사용한 User-Agent를 설정해요. 비어 있다면 기본값의 User-Agent를 사용해요." - summaryProxy: "미리보기를 만든 프록시의 엔드포인트" - summaryProxyDescription: "CherryPick에서 미리보기를 만들지 않고 Summary Proxy를 경유해 미리보기를 만들어요." - summaryProxyDescription2: "프록시는 아래 변수를 쿼리 문자열로 연동해요. 프록시에서 이를 지원하지 않으면 설정값을 무시해요." + summaryProxy: "미리보기 생성에 사용할 프록시 엔드포인트" + summaryProxyDescription: "CherryPick이 아닌 Summary Proxy를 사용해 미리보기를 생성해요." + summaryProxyDescription2: "프록시는 아래 변수를 쿼리 문자열로 연동해요. 프록시에서 이 변수를 지원하지 않으면 설정값은 무시돼요." _mediaControls: pip: "화면 속 화면" playbackRate: "재생 속도" @@ -3323,11 +3456,7 @@ _customEmojisManager: uploadSettingDescription: "여기서 이모지를 업로드 할 때의 동작을 설정할 수 있어요." directoryToCategoryLabel: "디렉토리 이름을 \"category\"로 입력하기" directoryToCategoryCaption: "디렉토리를 끌어서 놓으면 디렉토리의 이름을 \"category\"로 입력해요." - emojiInputAreaCaption: "이모지를 등록할 방법을 선택해 주세요." - emojiInputAreaList1: "이 틀 안에 이미지 파일 또는 디렉토리를 끌어서 가져오기" - emojiInputAreaList2: "이 링크를 클릭해서 PC에서 선택하기" - emojiInputAreaList3: "이 링크를 클릭해서 드라이브에서 선택하기" - confirmRegisterEmojisDescription: "리스트에 표시되어진 이모지를 새로운 커스텀 이모지로 등록하려고 해요. 계속할까요? (부하를 피하기 위해, 한 번에 등록할 수 있는 이모지는 {count}건까지 등록할 수 있어요.)" + confirmRegisterEmojisDescription: "리스트에 표시된 이모지를 새로운 커스텀 이모지로 등록하려고 해요. 계속할까요? (서버 부하를 방지하기 위해 한 번에 {count}개까지 등록할 수 있어요.)" confirmClearEmojisDescription: "편집 내용을 지우고, 목록에 표시되어진 이모지를 지우려고 해요. 계속할까요?" confirmUploadEmojisDescription: "끌어서 놓은 {count}개의 파일을 드라이브에 업로드하려고 해요. 계속할까요?" _embedCodeGen: @@ -3395,6 +3524,7 @@ _bootErrors: otherOption1: "클라이언트 설정 및 캐시 삭제" otherOption2: "임시 클라이언트 실행" otherOption3: "복구 도구 실행" + otherOption4: "안전 모드로 CherryPick 실행" _search: searchScopeAll: "전체" searchScopeLocal: "로컬" @@ -3403,14 +3533,198 @@ _search: pleaseEnterServerHost: "서버 호스트를 입력해 주세요" pleaseSelectUser: "사용자를 선택해 주세요" serverHostPlaceholder: "예: cherrypick.example.com" +_serverSetupWizard: + installCompleted: "CherryPick 설치를 완료했어요!" + firstCreateAccount: "이제 관리자 계정을 만들 차례에요." + accountCreated: "관리자 계정을 생성했어요!" + serverSetting: "서버 설정" + youCanEasilyConfigureOptimalServerSettingsWithThisWizard: "이 마법사를 통해 서버 설정을 더 쉽게 구성할 수 있어요." + settingsYouMakeHereCanBeChangedLater: "이 설정은 나중에 변경할 수 있어요." + howWillYouUseMisskey: "CherryPick을 어떻게 사용할 예정이신가요?" + _use: + single: "단일 사용자 서버" + single_description: "서버를 혼자서 사용하는 경우에 적합" + single_youCanCreateMultipleAccounts: "단일 사용자 서버로 운영하는 경우에도 계정은 여러 개 만들 수 있어요." + group: "그룹 서버" + group_description: "다른 사용자를 초대할 수 있으며, 가입하기 위해서는 초대 코드가 필요함" + open: "공개 서버" + open_description: "불특정 다수의 사용자가 가입할 수 있도록 서버를 공개함" + openServerAdvice: "불특정 다수의 사용자가 가입할 수 있도록 설정하는 것은 책임이 따르게 돼요. 문제에 대응할 수 있도록 신뢰할 수 있는 관리 시스템을 사용하는 것을 권장해요." + openServerAntiSpamAdvice: "서버가 스팸 공격 등에 사용되지 않도록 reCAPTCHA와 같은 봇 방지 기능을 활성화하여 보안에 세심한 주의를 기울여야 해요." + howManyUsersDoYouExpect: "서버를 이용할 예상 사용자 수는 어느 정도인가요?" + _scale: + small: "100명 이하(소규모)" + medium: "100명 이상 1000명 이하(중간 규모)" + large: "1000명 이상(대규모)" + largeScaleServerAdvice: "대규모 서버에서는 부하 분산 및 데이터베이스 복제와 같은 고급 인프라 지식이 필요할 수 있어요." + doYouConnectToFediverse: "Fediverse에 연결할까요?" + doYouConnectToFediverse_description1: "분산형 서버로 구성된 네트워크(Fediverse)에 연결하면 다른 서버와 노트, 이미지, 쪽지 등의 콘텐츠를 주고 받을 수 있어요." + doYouConnectToFediverse_description2: "Fediverse에 연결하는 것을 '연합'이라고 불러요." + youCanConfigureMoreFederationSettingsLater: "연합 가능한 서버 지정과 같은 고급 설정은 나중에 구성할 수 있어요." + remoteContentsCleaning: "수신된 콘텐츠 자동 정리" + remoteContentsCleaning_description: "연합으로 인해 콘텐츠가 지속적으로 서버에 저장돼요. 자동 정리 기능을 활성화하면 오래되고 서버에서 더 이상 참조하지 않는 콘텐츠를 자동으로 제거해 저장 공간을 절약할 수 있어요." + adminInfo: "관리자 정보" + adminInfo_description: "문의 접수를 위해 사용되는 관리자 정보를 설정할 수 있어요." + adminInfo_mustBeFilled: "공개 서버로 설정했거나 연합을 사용하도록 설정한 경우 반드시 입력해야 해요." + followingSettingsAreRecommended: "다음 설정이 권장돼요." + applyTheseSettings: "이 설정 적용" + skipSettings: "설정 건너뛰기" + settingsCompleted: "설정을 완료했어요!" + settingsCompleted_description: "수고하셨어요! 이제 모든 준비가 완료되었어요. 지금 바로 서버를 이용해 보세요." + settingsCompleted_description2: "더욱 세세한 서버 설정은 '제어판'에서 하실 수 있어요." + donationRequest: "기부 요청" + _donationRequest: + text1: "CherryPick은 기여자들에 의해 개발되는 무료 소프트웨어입니다." + text2: "앞으로도 계속해서 개발을 할 수 있도록 괜찮으시다면 마음을 나누어 주세요!" + text3: "지원자 대상 특전도 있어요!" +_uploader: + editImage: "이미지 편집" + compressedToX: "{x}로 압축" + savedXPercent: "{x}% 절약" + abortConfirm: "일부 파일이 업로드되지 않았어요. 그래도 중단할까요?" + doneConfirm: "일부 파일이 업로드되지 않았어요. 그래도 계속할까요?" + maxFileSizeIsX: "업로드 가능한 최대 파일 크기는 {x}에요." + allowedTypes: "업로드 가능한 파일 유형" + tip: "파일을 아직 업로드하기 전이에요. 이 창에서 업로드 전에 파일을 확인하거나, 이름 바꾸기, 압축 및 자르기 등을 할 수 있어요. 파일을 업로드할 준비가 되면 '업로드' 버튼을 눌러 업로드를 시작할 수 있어요." +_clientPerformanceIssueTip: + title: "성능 향상을 위한 팁" + makeSureDisabledAdBlocker: "광고 차단기 비활성화 하기" + makeSureDisabledAdBlocker_description: "광고 차단은 성능에 영향을 미칠 수 있어요. OS 또는 브라우저의 기능이나 확장 프로그램 등을 통해 광고 차단이 활성화되어 있지 않은지 확인해 주세요. 또한 광고 차단기는 CherryPick의 동작에 영향을 미칠 수 있어요." + makeSureDisabledCustomCss: "CSS 사용자화 비활성화" + makeSureDisabledCustomCss_description: "스타일을 재정의하면 성능에 영향을 미칠 수 있어요. 스타일을 재정의하는 CSS 사용자화 또는 확장 프로그램이 활성화되어 있지 않은지 확인해 주세요." + makeSureDisabledAddons: "확장 프로그램 비활성화" + makeSureDisabledAddons_description: "일부 확장 프로그램은 클라이언트의 동작을 방해하고 성능에 영향을 미칠 수 있어요. 브라우저 확장 프로그램을 비활성화하고 문제가 해결되는지 확인해 주세요." +_clip: + tip: "클립은 노트를 정리할 수 있는 기능이에요." +_userLists: + tip: "지정한 사용자가 포함된 리스트를 만들 수 있어요. 생성한 리스트는 지정한 사용자만 보여주는 타임라인으로 사용할 수 있어요." +watermark: "워터마크" +defaultPreset: "기본 프리셋" +_watermarkEditor: + tip: "이미지에 크레딧 정보 등의 워터마크를 추가할 수 있어요." + quitWithoutSaveConfirm: "저장되지 않은 변경 사항을 모두 취소할까요?" + driveFileTypeWarn: "이 파일은 지원되지 않아요." + driveFileTypeWarnDescription: "이미지 파일을 선택해 주세요." + title: "워터마크 편집" + cover: "채우기" + repeat: "반복" + preserveBoundingRect: "회전 시 튀어나오지 않도록 조정" + opacity: "불투명도" + scale: "크기" + text: "텍스트" + qr: "QR 코드" + position: "위치" + margin: "여백" + type: "종류" + image: "이미지" + advanced: "고급" + angle: "각도" + stripe: "줄무늬" + stripeWidth: "줄무늬 너비" + stripeFrequency: "줄무늬 개수" + polkadot: "도트" + checker: "체크 무늬" + polkadotMainDotOpacity: "메인 도트 불투명도" + polkadotMainDotRadius: "메인 도트 크기" + polkadotSubDotOpacity: "서브 도트 불투명도" + polkadotSubDotRadius: "서브 도트 크기" + polkadotSubDotDivisions: "서브 도트 수" + leaveBlankToAccountUrl: "계정 URL을 사용하려면 비워두세요." +_imageEffector: + title: "효과" + addEffect: "효과 추가" + discardChangesConfirm: "저장되지 않은 변경 사항이 있어요. 그래도 종료할까요?" + nothingToConfigure: "구성 가능한 옵션이 없어요." + _fxs: + chromaticAberration: "색수차" + glitch: "글리치" + mirror: "미러" + invert: "색 반전" + grayscale: "흑백" + blur: "흐림 효과" + pixelate: "모자이크" + colorAdjust: "색조 보정" + colorClamp: "색상 압축" + colorClampAdvanced: "색상 압축(고급)" + distort: "왜곡" + threshold: "이진화" + zoomLines: "집중선" + stripe: "줄무늬" + polkadot: "도트" + checker: "체크 무늬" + blockNoise: "블록 노이즈" + tearing: "티어링" + fill: "채우기" + _fxProps: + angle: "각도" + scale: "크기" + size: "크기" + radius: "반지름" + samples: "샘플 수" + offset: "위치" + color: "색" + opacity: "불투명도" + normalize: "정규화" + amount: "수치" + lightness: "밝기" + contrast: "대비" + hue: "색조" + brightness: "명도" + saturation: "채도" + max: "최대 값" + min: "최소 값" + direction: "방향" + phase: "위상" + frequency: "빈도" + strength: "강도" + glitchChannelShift: "글리치" + seed: "시드 값" + redComponent: "빨간색 요소" + greenComponent: "녹색 요소" + blueComponent: "파란색 요소" + threshold: "한계 값" + centerX: "X축 중심" + centerY: "Y축 중심" + zoomLinesSmoothing: "스무딩" + zoomLinesSmoothingDescription: "스무딩과 집중선 폭 설정은 같이 쓸 수 없어요." + zoomLinesThreshold: "집중선 폭" + zoomLinesMaskSize: "중앙 값" + zoomLinesBlack: "검은색으로 설정" + circle: "원형" +drafts: "초안" _drafts: select: "초안 선택" + cannotCreateDraftAnymore: "작성 가능한 초안 수를 초과했어요." + cannotCreateDraft: "이 내용으로는 초안을 작성할 수 없어요." delete: "초안 삭제" deleteAreYouSure: "초안을 삭제할까요?" noDrafts: "초안이 없어요." replyTo: "{user}님에게 답글" quoteOf: "{user}님의 노트에 인용" postTo: "{channel}에 게시" + saveToDraft: "초안으로 저장" + restoreFromDraft: "초안에서 복원" + restore: "복원" + listDrafts: "초안 목록" + schedule: "게시 예약" + listScheduledNotes: "예약 게시물 목록" + cancelSchedule: "예약 취소" +qr: "QR 코드" +_qr: + showTabTitle: "표시" + readTabTitle: "스캔" + shareTitle: "{name} {acct}" + shareText: "Fediverse에서 저를 팔로우하세요!" + chooseCamera: "카메라 선택" + cannotToggleFlash: "플래시 선택 불가" + turnOnFlash: "플래시 켜기" + turnOffFlash: "플래시 끄기" + startQr: "QR 코드 리더 재개" + stopQr: "QR 코드 리더 중지" + noQrCodeFound: "QR 코드를 찾지 못했어요." + scanFile: "장치에서 이미지 스캔" + raw: "텍스트" + mfm: "MFC" _abuse: _resolver: 1hour: "1시간" @@ -3428,13 +3742,6 @@ _abuse: reportContentPattern: "신고 내용 패턴" list: "목록" resolver: "리졸버" -_imageCompressionMode: - title: "이미지 압축 형식" - description: "웹 공개용 이미지의 압축 형식을 선택할 수 있어요. 축소할 경우 2048x2048보다 작게 축소돼요. 압축 방식을 지정하지 않으면 원본 이미지의 형식에 따라 무손실 압축 또는 손실 압축이 자동으로 선택돼요." - resizeCompress: "해상도 축소 및 압축" - noResizeCompress: "해상도를 축소하지 않고 압축" - resizeCompressLossy: "해상도 축소 및 손실 압축" - noResizeCompressLossy: "해상도를 축소하지 않고 손실 압축" _externalNavigationWarning: title: "외부 사이트로 이동할까요?" description: "{host}을(를) 떠나 외부 사이트로 이동하려고 해요" @@ -3497,3 +3804,14 @@ _weather: humidity: "습도" pressure: "기압" precipitation: "강수량" +_deliveryTargetControl: + deliveryTargetControl: "배포 대상 제한" + deliveryTargetInclude: "선택한 서버에만 전송" + deliveryTargetExclude: "선택한 서버를 제외하고 전송" + noFollowersFromRemoteServers: "리모트 서버에 팔로워가 없어요" + loadError: "서버 목록을 불러오지 못했어요..." + followersCount: "팔로워 {count}명" + searchResults: "총 {total}개 중 {count}개의 결과를 찾았어요." + deliveryTargetsInclude: "일부 서버에서만 공개됨" + deliveryTargetsExclude: "일부 서버에서 비공개됨" + hasDeliveryTargets: "배포 대상이 선택되어 있어요" diff --git a/locales/lo-LA.yml b/locales/lo-LA.yml index 401242b846..bc0f44d26f 100644 --- a/locales/lo-LA.yml +++ b/locales/lo-LA.yml @@ -416,7 +416,6 @@ _theme: _sfx: note: "ບັນທຶກ" notification: "ການແຈ້ງເຕືອນ" - chat: "ແຊ໋ດ" _2fa: renewTOTPCancel: "ບໍ່​ແມ່ນ​ຕອນ​ນີ້" _widgets: @@ -434,6 +433,7 @@ _cw: _visibility: home: "ໜ້າຫຼັກ" followers: "ຜູ້ຕິດຕາມ" + specified: "ໂພສ Direct note" _profile: name: "ຊື່" username: "ຊື່ຜູ້ໃຊ້" @@ -471,6 +471,7 @@ _deck: list: "ລາຍການ" channel: "ຊ່ອງ" mentions: "ກ່າວເຖິງເຈົ້າ" + direct: "ໂພສ Direct note" _webhookSettings: name: "ຊື່" _abuseReport: @@ -484,3 +485,5 @@ _remoteLookupErrors: title: "ບໍ່ພົບ" _search: searchScopeAll: "ທັງໝົດ" +_watermarkEditor: + image: "ຮູບພາບ" diff --git a/locales/nl-NL.yml b/locales/nl-NL.yml index b1367c7bb3..f5751a2cd2 100644 --- a/locales/nl-NL.yml +++ b/locales/nl-NL.yml @@ -250,7 +250,6 @@ noUsers: "Er zijn geen gebruikers." editProfile: "Bewerk Profiel" noteDeleteConfirm: "Ben je zeker dat je dit bericht wil verwijderen?" pinLimitExceeded: "Je kunt geen berichten meer vastprikken" -intro: "Installatie van CherryPick geëindigd! Maak nu een beheerder aan." done: "Klaar" processing: "Bezig met verwerken" preview: "Voorbeeld" @@ -523,8 +522,8 @@ showNoteActionsOnlyHover: "Toon notitiemenu alleen bij muisaanwijzer" showReactionsCount: "Zie het aantal reacties op notities" noHistory: "Geen geschiedenis gevonden" signinHistory: "Inloggeschiedenis" -enableAdvancedMfm: "Uitgebreide MFM activeren" -enableAnimatedMfm: "Geanimeerde MFM activeren" +enableAdvancedMfm: "Uitgebreide MFC activeren" +enableAnimatedMfm: "Geanimeerde MFC activeren" doing: "In uitvoering..." category: "Categorie" tags: "Aliassen" @@ -1004,7 +1003,6 @@ _theme: _sfx: note: "Notities" notification: "Meldingen" - chat: "Chat" _2fa: renewTOTPCancel: "Nee, bedankt" _widgets: @@ -1022,6 +1020,7 @@ _cw: _visibility: home: "Startpagina" followers: "Volgers" + specified: "Directe notities" _profile: name: "Naam" username: "Gebruikersnaam" @@ -1064,6 +1063,7 @@ _deck: list: "Lijsten" channel: "Kanalen" mentions: "Vermeldingen" + direct: "Directe notities" _webhookSettings: name: "Naam" active: "Ingeschakeld" @@ -1081,3 +1081,8 @@ _remoteLookupErrors: title: "Niet gevonden" _search: searchScopeAll: "Alle" +_watermarkEditor: + image: "Afbeeldingen" + advanced: "Geavanceerd" +_qr: + showTabTitle: "Weergave" diff --git a/locales/no-NO.yml b/locales/no-NO.yml index 6b8e840c12..36b93f1712 100644 --- a/locales/no-NO.yml +++ b/locales/no-NO.yml @@ -171,7 +171,6 @@ noUsers: "Det er ingen brukere" editProfile: "Rediger profil" noteDeleteConfirm: "Er du sikker på at du vil slette denne Noten?" pinLimitExceeded: "Du kan ikke feste flere." -intro: "Installasjonen av CherryPick er ferdig! Vennligst opprett en administratorkonto." done: "Ferdig" default: "Standard" defaultValueIs: "Standard: {value}" @@ -462,6 +461,8 @@ replies: "Svar" renotes: "Renote" surrender: "Avbryt" information: "Informasjon" +inMinutes: "Minutter" +inDays: "Dager" _chat: invitations: "Inviter" members: "Medlemmer" @@ -738,3 +739,15 @@ _remoteLookupErrors: title: "Ikke funnet" _search: searchScopeAll: "Alle" +_watermarkEditor: + scale: "Størrelse" + text: "Tekst" + type: "Type" + image: "Bilder" +_imageEffector: + _fxProps: + scale: "Størrelse" + size: "Størrelse" + color: "Farge" +_qr: + raw: "Tekst" diff --git a/locales/pl-PL.yml b/locales/pl-PL.yml index adbbf34424..ad41d8945a 100644 --- a/locales/pl-PL.yml +++ b/locales/pl-PL.yml @@ -230,7 +230,6 @@ noUsers: "Brak użytkowników" editProfile: "Edytuj profil" noteDeleteConfirm: "Czy na pewno chcesz usunąć ten wpis?" pinLimitExceeded: "Nie możesz przypiąć więcej wpisów." -intro: "Zakończono instalację CherryPick! Utwórz konto administratora." done: "Gotowe" processing: "Przetwarzanie" preview: "Podgląd" @@ -1054,6 +1053,9 @@ surrender: "Odrzuć" gameRetry: "Spróbuj ponownie" postForm: "Formularz tworzenia wpisu" information: "Informacje" +inMinutes: "minuta" +inDays: "dzień" +widgets: "Widżety" _chat: invitations: "Zaproś" noHistory: "Brak historii" @@ -1307,7 +1309,6 @@ _theme: buttonBg: "Tło przycisku" buttonHoverBg: "Tło przycisku (po najechaniu)" inputBorder: "Obramowanie pola wejścia" - driveFolderBg: "Tło folderu na dysku" badge: "Odznaka" messageBg: "Tło czatu" fgHighlighted: "Wyróżniony tekst" @@ -1663,3 +1664,20 @@ _remoteLookupErrors: _search: searchScopeAll: "Wszystkie" searchScopeLocal: "Lokalne" +_watermarkEditor: + opacity: "Przezroczystość" + scale: "Rozmiar" + text: "Tekst" + type: "Typ" + image: "Zdjęcia" + advanced: "Zaawansowane" +_imageEffector: + _fxProps: + scale: "Rozmiar" + size: "Rozmiar" + color: "Kolor" + opacity: "Przezroczystość" + lightness: "Rozjaśnij" +_qr: + showTabTitle: "Wyświetlanie" + raw: "Tekst" diff --git a/locales/pt-PT.yml b/locales/pt-PT.yml index c12623bbd9..3674e8d7e6 100644 --- a/locales/pt-PT.yml +++ b/locales/pt-PT.yml @@ -143,9 +143,9 @@ deleteFile: "Excluir arquivo" markAsSensitive: "Marcar como sensível" unmarkAsSensitive: "Desmarcar como sensível" enterFileName: "Digite o nome do arquivo" -mute: "Mutar" +mute: "Silenciar" unmute: "Desmutar" -renoteMute: "Mutar repostagens" +renoteMute: "Silenciar repostagens" renoteUnmute: "Reativar repostagens" block: "Bloquear" unblock: "Desbloquear" @@ -220,6 +220,7 @@ silenceThisInstance: "Silenciar essa instância" mediaSilenceThisInstance: "Silenciar a mídia dessa instância" operations: "Operações" software: "Software" +softwareName: "Software" version: "Versão" metadata: "Metadados" withNFiles: "{n} arquivo(s)" @@ -250,9 +251,9 @@ noUsers: "Sem usuários" editProfile: "Editar Perfil" noteDeleteConfirm: "Deseja excluir esta nota?" pinLimitExceeded: "Não é possível fixar novas notas" -intro: "A instalação do CherryPick está completa! Crie uma conta de administrador." done: "Concluído" processing: "Em Progresso" +preprocessing: "Preparando..." preview: "Pré-visualizar" default: "Predefinição" defaultValueIs: "Predefinição: {value}" @@ -298,6 +299,7 @@ uploadFromUrl: "Enviar por URL" uploadFromUrlDescription: "URL do arquivo que você deseja enviar" uploadFromUrlRequested: "Upload solicitado" uploadFromUrlMayTakeTime: "Pode levar algum tempo para que o upload seja concluído." +uploadNFiles: "Enviar {n} arquivos" explore: "Explorar" messageRead: "Lida" noMoreHistory: "Não existe histórico anterior" @@ -326,6 +328,7 @@ dark: "Escuro" lightThemes: "Tema claro" darkThemes: "Tema escuro" syncDeviceDarkMode: "Sincronize com o modo escuro do dispositivo" +switchDarkModeManuallyWhenSyncEnabledConfirm: "\"{x}\" está ativado. Você gostaria de desligar a sincronização e alterar manualmente?" drive: "Drive" fileName: "Nome do Ficheiro" selectFile: "Selecione os arquivos" @@ -444,7 +447,7 @@ exploreUsersCount: "Há um utilizador de {count}" exploreFediverse: "Explorar Fediverse" popularTags: "Tags populares" userList: "Listas" -about: "Informações" +about: "Sobre" aboutMisskey: "Sobre CherryPick" administrator: "Administrador" token: "Símbolo" @@ -575,8 +578,10 @@ showFixedPostForm: "Exibir o formulário de postagem na parte superior da linha showFixedPostFormInChannel: "Exibir o campo de postagem na parte superior da linha do tempo (canais)" withRepliesByDefaultForNewlyFollowed: "Incluir respostas por usuários recém-seguidos na linha do tempo por padrão" newNoteRecived: "Nova nota recebida" +newNote: "Nova Nota" sounds: "Sons" sound: "Sons" +notificationSoundSettings: "Configurações de som de notificações" listen: "Ouvir" none: "Nenhum" showInPage: "Ver na página" @@ -792,6 +797,7 @@ wide: "Largo" narrow: "Estreito" reloadToApplySetting: "As configurações serão refletidas após recarregar a página. Deseja recarregar agora?" needReloadToApply: "É necessário recarregar a página para refletir as alterações." +needToRestartServerToApply: "É necessário reiniciar o servidor para aplicar as mudanças." showTitlebar: "Exibir barra de título" clearCache: "Limpar o cache" onlineUsersCount: "{n} Pessoas Online" @@ -998,6 +1004,7 @@ failedToUpload: "Falha ao enviar" cannotUploadBecauseInappropriate: "Esse arquivo não pôde ser enviado porque partes dele foram detectadas como potencialmente inapropriadas." cannotUploadBecauseNoFreeSpace: "Envio falhou devido à falta de capacidade no Drive." cannotUploadBecauseExceedsFileSizeLimit: "Não é possível realizar o upload deste arquivo porque ele excede o tamanho máximo permitido." +cannotUploadBecauseUnallowedFileType: "Não foi possível fazer o envio, pois o formato do arquivo não foi autorizado." beta: "Beta" enableAutoSensitive: "Marcar automaticamente como conteúdo sensível" enableAutoSensitiveDescription: "Quando disponível, a marcação de mídia sensível será automaticamente atribuído ao conteúdo de mídia usando aprendizado de máquina. Mesmo que você desative essa função, em alguns servidores, isso pode ser configurado automaticamente." @@ -1049,6 +1056,7 @@ permissionDeniedError: "Operação recusada" permissionDeniedErrorDescription: "Esta conta não tem permissão para executar esta ação." preset: "Predefinições" selectFromPresets: "Escolher de predefinições" +custom: "Personalizado" achievements: "Conquistas" gotInvalidResponseError: "Resposta do servidor inválida" gotInvalidResponseErrorDescription: "Servidor fora do ar ou em manutenção. Favor tentar mais tarde." @@ -1087,6 +1095,7 @@ prohibitedWordsDescription2: "Utilizar espaços irá criar expressões aditivas hiddenTags: "Hashtags escondidas" hiddenTagsDescription: "Selecione tags que não serão exibidas na lista de destaques. Várias tags podem ser escolhidas, separadas por linha." notesSearchNotAvailable: "A pesquisa de notas está indisponível." +usersSearchNotAvailable: "Pesquisa de usuário está indisponível." license: "Licença" unfavoriteConfirm: "Deseja realmente remover dos favoritos?" myClips: "Meus clipes" @@ -1237,9 +1246,8 @@ showAvatarDecorations: "Exibir decorações de avatar" releaseToRefresh: "Solte para atualizar" refreshing: "Atualizando..." pullDownToRefresh: "Puxe para baixo para atualizar" -disableStreamingTimeline: "Desabilitar atualizações em tempo real da linha do tempo" useGroupedNotifications: "Agrupar notificações" -signupPendingError: "Houve um problema ao verificar o endereço de email. O link pode ter expirado." +emailVerificationFailedError: "Houve um problema ao verificar seu endereço de email. O link pode ter expirado." cwNotationRequired: "Se \"Esconder conteúdo\" está habilitado, uma descrição deve ser adicionada." doReaction: "Adicionar reação" code: "Código" @@ -1309,6 +1317,8 @@ availableRoles: "Cargos disponíveis" acknowledgeNotesAndEnable: "Ative após compreender as precauções." federationSpecified: "Esse servidor opera com uma lista branca de federação. Interagir com servidores diferentes daqueles designados pela administração não é permitido." federationDisabled: "Federação está desabilitada nesse servidor. Você não pode interagir com usuários de outros servidores." +draft: "Rascunhos" +draftsAndScheduledNotes: "Rascunhos e notas agendadas." confirmOnReact: "Confirmar ao reagir" reactAreYouSure: "Você deseja adicionar uma reação \"{emoji}\"?" markAsSensitiveConfirm: "Você deseja definir essa mídia como sensível?" @@ -1326,6 +1336,7 @@ restore: "Redefinir" syncBetweenDevices: "Sincronizar entre dispositivos" preferenceSyncConflictTitle: "O valor configurado já existe no servidor." preferenceSyncConflictText: "As preferências com a sincronização ativada irão salvar os seus valores no servidor. Porém, já existem valores no servidor. Qual conjunto de valores você deseja sobrescrever?" +preferenceSyncConflictChoiceMerge: "Combinar" preferenceSyncConflictChoiceServer: "Valor configurado no servidor" preferenceSyncConflictChoiceDevice: "Valor configurado no dispositivo" preferenceSyncConflictChoiceCancel: "Cancelar a habilitação de sincronização" @@ -1333,8 +1344,10 @@ paste: "Colar" emojiPalette: "Paleta de emojis" postForm: "Campo de postagem" textCount: "Contagem de caracteres" -information: "Informações" +information: "Sobre" chat: "Conversas" +directMessage: "Conversar com usuário" +directMessage_short: "Mensagem" migrateOldSettings: "Migrar configurações antigas de cliente" migrateOldSettings_description: "Isso deve ser feito automaticamente. Caso o processo de migração tenha falhado, você pode acioná-lo manualmente. As informações atuais de migração serão substituídas." compress: "Comprimir" @@ -1346,7 +1359,52 @@ settingsMigrating: "Configurações estão sendo migradas, aguarde... (Você pod readonly: "Ler apenas" goToDeck: "Voltar ao Deck" federationJobs: "Tarefas de Federação" +driveAboutTip: "No Drive, uma lista de arquivos enviados no passado será exibida.
\nVocê pode reutilizar esses arquivos anexando-os às notas, ou você pode enviar arquivos para publicar posteriormente.
\nCuidado ao excluir um arquivo, pois ele será removido de quaisquer outros lugares onde está sendo utilizado (notas, páginas, avatares, banners, etc.)
\nVocê também pode criar pastas para organizar seus arquivos." +scrollToClose: "Role a página para fechar" +advice: "Dica" +realtimeMode: "Modo tempo-real" +turnItOn: "Ativar" +turnItOff: "Desativar" +emojiMute: "Silenciar emoji" +emojiUnmute: "Reativar emoji" +muteX: "Silenciar {x}" +unmuteX: "Reativar {x}" +abort: "Abortar" +tip: "Dicas e Truques" +redisplayAllTips: "Mostrar todas as \"Dicas e Truques\" novamente" +hideAllTips: "Ocultas todas as \"Dicas e Truques\"" +defaultImageCompressionLevel: "Nível de compressão de imagem padrão" +defaultImageCompressionLevel_description: "Alto, reduz o tamanho do arquivo mas, também, a qualidade da imagem.
Alto, reduz o tamanho do arquivo mas, também, a qualidade da imagem." +defaultCompressionLevel: "Nível padrão de compressão" +defaultCompressionLevel_description: "Menor compressão preserva a qualidade mas aumenta o tamanho do arquivo.
Maior compressão reduz o tamanho do arquivo mas diminui a qualidade." +inMinutes: "Minuto(s)" +inDays: "Dia(s)" +safeModeEnabled: "Modo seguro está habilitado" +pluginsAreDisabledBecauseSafeMode: "Todos os plugins estão desabilitados porque o modo seguro está habilitado." +customCssIsDisabledBecauseSafeMode: "CSS personalizado não está aplicado porque o modo seguro está habilitado." +themeIsDefaultBecauseSafeMode: "Enquanto o modo seguro estiver ativo, o tema padrão é utilizado. Desabilitar o modo seguro reverterá essas mudanças." +thankYouForTestingBeta: "Obrigado por nos ajudar a testar a versão beta!" +createUserSpecifiedNote: "Criar uma nota direta" +schedulePost: "Agendar publicação" +scheduleToPostOnX: "Agendar nota para {x}" +scheduledToPostOnX: "A nota está agendada para {x}" +schedule: "Agendar" +scheduled: "Agendado" +widgets: "Widgets" +_compression: + _quality: + high: "Qualidade alta" + medium: "Qualidade média" + low: "Qualidade baixa" + _size: + large: "Tamanho grande" + medium: "Tamanho médio" + small: "Tamanho pequeno" +_order: + newest: "Priorizar Mais Novos" + oldest: "Priorizar Mais Antigos" _chat: + messages: "Mensagem" noMessagesYet: "Ainda não há mensagens" newMessage: "Nova mensagem" individualChat: "Conversa Particular" @@ -1379,6 +1437,8 @@ _chat: chatNotAvailableInOtherAccount: "A função de conversas está desabilitadas para o outro usuário." cannotChatWithTheUser: "Não é possível conversar com esse usuário." cannotChatWithTheUser_description: "Conversas estão indisponíveis ou o outro usuário não as habilitou." + youAreNotAMemberOfThisRoomButInvited: "Você não é um participante da sala, mas recebeu um convite. Por favor, aceite o convite para entrar." + doYouAcceptInvitation: "Aceita o convite?" chatWithThisUser: "Conversar com usuário" thisUserAllowsChatOnlyFromFollowers: "Esse usuário aceita conversar apenas com seguidores." thisUserAllowsChatOnlyFromFollowing: "Esse usuário aceita conversar apenas com quem segue." @@ -1418,10 +1478,21 @@ _settings: makeEveryTextElementsSelectable: "Tornar todos os elementos de texto selecionáveis" makeEveryTextElementsSelectable_description: "Habilitar isso pode reduzir a usabilidade em algumas situações" useStickyIcons: "Fazer ícones acompanharem a rolagem da tela" + enableHighQualityImagePlaceholders: "Exibir prévias para imagens de alta qualidade" + uiAnimations: "Animações de UI" showNavbarSubButtons: "Mostrar sub-botões na barra de navegação" ifOn: "Quando ligado" ifOff: "Quando desligado" enableSyncThemesBetweenDevices: "Sincronizar temas instalados entre dispositivos" + enablePullToRefresh: "Puxe para atualizar" + enablePullToRefresh_description: "Quando estiver utilizando um mouse, arraste enquanto aperta a roda de rolagem." + realtimeMode_description: "Estabelece uma conexão com o servidor e atualiza o conteúdo em tempo real. Isso pode aumentar o tráfego e uso de memória." + contentsUpdateFrequency: "Frequência da obtenção de conteúdo" + contentsUpdateFrequency_description: "Quanto maior o valor, mais o conteúdo atualiza. Porém, há uma diminuição do desempenho e aumento do tráfego e consumo de memória." + contentsUpdateFrequency_description2: "Quando o modo tempo-real está ativado, o conteúdo é atualizado em tempo real, ignorando essa opção." + showUrlPreview: "Exibir prévia de URL" + showAvailableReactionsFirstInNote: "Exibir reações disponíveis no topo." + showPageTabBarBottom: "Mostrar barra de aba da página inferiormente" _chat: showSenderName: "Exibir nome de usuário do remetente" sendOnEnter: "Pressionar Enter para enviar" @@ -1429,6 +1500,7 @@ _preferencesProfile: profileName: "Nome do perfil" profileNameDescription: "Defina o nome que identifica esse dispositivo." profileNameDescription2: "Exemplo: \"Computador Principal\", \"Celular\"" + manageProfiles: "Gerenciar Perfis" _preferencesBackup: autoBackup: "Backup automático" restoreFromBackup: "Restaurar backup" @@ -1467,6 +1539,7 @@ _delivery: manuallySuspended: "Suspenso manualmente" goneSuspended: "Servidor foi suspenso devido ao seu apagamento" autoSuspendedForNotResponding: "Servidor foi suspenso por não responder" + softwareSuspended: "Suspenso, pois esse software não está recebendo conteúdo" _bubbleGame: howToPlay: "Como jogar" hold: "Próximos" @@ -1593,11 +1666,37 @@ _serverSettings: fanoutTimelineDbFallback: "\"Fallback\" ao banco de dados" fanoutTimelineDbFallbackDescription: "Quando habilitado, a linha do tempo irá recuar ao banco de dados caso consultas adicionais sejam feitas e ela não estiver em cache. Quando desabilitado, o impacto no servidor será reduzido ao eliminar o recuo, mas limita a quantidade de linhas do tempo que podem ser recebidas." reactionsBufferingDescription: "Quando ativado, o desempenho durante a criação de uma reação será melhorado substancialmente, reduzindo a carga do banco de dados. Porém, a o uso de memória do Redis irá aumentar." + remoteNotesCleaning: "Limpeza automática de notas remotas" + remoteNotesCleaning_description: "Quando habilitado, notas remotas obsoletas e não utilizadas serão periodicamente limpadas para previnir sobrecarga no banco de dados." + remoteNotesCleaningMaxProcessingDuration: "Maximizar tempo de processamento da limpeza" + remoteNotesCleaningExpiryDaysForEachNotes: "Mínimo de dias para retenção de notas" inquiryUrl: "URL de inquérito" inquiryUrlDescription: "Especifique um URL para um formulário de inquérito para a administração ou uma página web com informações de contato." openRegistration: "Abrir a criação de contas" openRegistrationWarning: "Abrir cadastros contém riscos. É recomendado apenas habilitá-los se houver um sistema de monitoramento contínuo e resolução imediata de problemas." thisSettingWillAutomaticallyOffWhenModeratorsInactive: "Se nenhuma atividade da moderação for detectada por um tempo, essa configuração será desativada para prevenir spam." + deliverSuspendedSoftware: "Software Suspenso" + deliverSuspendedSoftwareDescription: "Você pode especificar uma faixa de nomes e versões do software de servidores para cancelar o envio de conteúdo por motivos como vulnerabilidades. Essa informação da versão é providenciada pelo servidor e pode não ser confiável. Uma faixa semver pode ser utilizada para especificar a versão, mas colocar '>= 2024.3.1' não incluirá versões personalizadas como '2024.3.1-custom.0'. Logo, é recomendado inserir uma especificação como '>= 2024.3.1-0'" + singleUserMode: "Modo de usuário único" + singleUserMode_description: "Se você é o único usuário desse servidor, habilitar esse modo irá otimizar a performance." + signToActivityPubGet: "Assinar solicitações GET do ActivityPub" + signToActivityPubGet_description: "Normalmente, isso deve ser habilitado. Desabilitar pode melhorar o desempenho na federação, mas também pode cortar a federação com alguns servidores." + proxyRemoteFiles: "Passar arquivos remotos por proxy" + proxyRemoteFiles_description: "Se habilitado, o servidor irá servir arquivos remotos através de um proxy. Isso é útil para gerar prévias de imagens e proteger a privacidade do usuário." + allowExternalApRedirect: "Permitir redirecionamento de conteúdo pelo ActivityPub" + allowExternalApRedirect_description: "Se habilitado, outros servidores podem solicitar conteúdo de terceiros através desse servidor, o que pode resultar em falsificação de conteúdo (spoofing)." + userGeneratedContentsVisibilityForVisitor: "Visibilidade de conteúdo dos usuários para visitantes" + userGeneratedContentsVisibilityForVisitor_description: "Isso é útil para prevenir problemas causados por conteúdo inapropriado de usuários remotos de servidores com pouca ou nenhuma moderação, que pode ser hospedado na internet a partir desse servidor." + userGeneratedContentsVisibilityForVisitor_description2: "Publicar todo o conteúdo do servidor para a internet pode ser arriscado. Isso é especialmente importante para visitantes que desconhecem a natureza distribuída do conteúdo na internet, pois eles podem acreditar que o conteúdo remoto é criado por usuários desse servidor." + restartServerSetupWizardConfirm_title: "Reiniciar o assistente de configuração?" + restartServerSetupWizardConfirm_text: "Algumas configurações atuais serão reiniciadas." + entrancePageStyle: "Estilo da página de entrada" + showTimelineForVisitor: "Mostrar linha do tempo" + showActivitiesForVisitor: "Mostrar atividades" + _userGeneratedContentsVisibilityForVisitor: + all: "Tudo é público" + localOnly: "Conteúdo local é publicado, conteúdo remoto é privado" + none: "Tudo é privado" _accountMigration: moveFrom: "Migrar outra conta para essa" moveFromSub: "Criar um 'alias' a outra conta" @@ -1915,6 +2014,7 @@ _role: canManageCustomEmojis: "Permitir gerenciar emojis personalizados" canManageAvatarDecorations: "Gerenciar decorações de avatar" driveCapacity: "Capacidade do drive" + maxFileSize: "Tamanho máximo de envio de arquivos" alwaysMarkNsfw: "Sempre marcar arquivos como NSFW" canUpdateBioMedia: "Permitir a edição de ícone ou imagem do banner." pinMax: "Número máximo de notas fixadas" @@ -1929,6 +2029,7 @@ _role: descriptionOfRateLimitFactor: "Valores menores são menos restritivos, valores maiores são mais restritivos." canHideAds: "Permitir ocultar anúncios" canSearchNotes: "Permitir a busca de notas" + canSearchUsers: "Busca de usuário" canUseTranslator: "Uso do tradutor" avatarDecorationLimit: "Número máximo de decorações de avatar que podem ser aplicadas" canImportAntennas: "Permitir importação de antenas" @@ -1937,6 +2038,12 @@ _role: canImportMuting: "Permitir importação de silenciamentos" canImportUserLists: "Permitir importação de listas" chatAvailability: "Permitir Conversas" + uploadableFileTypes: "Tipos de arquivo enviáveis" + uploadableFileTypes_caption: "Especifica tipos MIME permitidos. Múltiplos tipos MIME podem ser especificados separando-os por linha. Curingas podem ser especificados com um asterisco (*). (exemplo, image/*)" + uploadableFileTypes_caption2: "Alguns tipos de arquivos podem não ser detectados. Para permiti-los, adicione {x} à especificação." + noteDraftLimit: "Limite de rascunhos possíveis" + scheduledNoteLimit: "Número máximo de notas agendadas simultâneas" + watermarkAvailable: "Disponibilidade da função de marca d'água" _condition: roleAssignedTo: "Atribuído a cargos manuais" isLocal: "Usuário local" @@ -2096,6 +2203,7 @@ _theme: install: "Instalar um tema" manage: "Gerenciar temas" code: "Código do tema" + copyThemeCode: "Copiar código do tema" description: "Descrição" installed: "{name} foi instalado" installedThemes: "Temas instalados" @@ -2154,7 +2262,6 @@ _theme: buttonBg: "Plano de fundo de botão" buttonHoverBg: "Plano de fundo de botão (Selecionado)" inputBorder: "Borda de campo digitável" - driveFolderBg: "Plano de fundo da pasta no Drive" badge: "Emblema" messageBg: "Plano de fundo do chat" fgHighlighted: "Texto Destacado" @@ -2162,7 +2269,6 @@ _sfx: note: "Posts" noteMy: "Própria nota" notification: "Notificações" - chat: "Chat" reaction: "Ao selecionar uma reação" chatMessage: "Mensagens em Conversas" _soundSettings: @@ -2197,6 +2303,7 @@ _time: minute: "Minuto(s)" hour: "Hora(s)" day: "Dia(s)" + month: "Mês(es)" _2fa: alreadyRegistered: "Você já cadastrou um dispositivo de autenticação de dois fatores." registerTOTP: "Cadastrar aplicativo autenticador" @@ -2371,7 +2478,7 @@ _widgets: chooseList: "Selecione uma lista" clicker: "Clicker" birthdayFollowings: "Usuários de aniversário hoje" - chat: "Conversas" + chat: "Conversar com usuário" _cw: hide: "Esconder" show: "Carregar mais" @@ -2411,6 +2518,8 @@ _visibility: disableFederation: "Defederar" disableFederationDescription: "Não transmitir às outras instâncias" _postForm: + quitInspiteOfThereAreUnuploadedFilesConfirm: "Há arquivos que não foram enviados, gostaria de descartá-los e fechar o editor?" + uploaderTip: "O arquivo ainda não foi enviado. No menu do arquivo, você pode renomear, cortar, adicionar uma marca d'água, comprimir ou descomprimir um arquivo. Arquivos serão enviados automaticamente ao publicar a nota." replyPlaceholder: "Responder a essa nota..." quotePlaceholder: "Citar essa nota..." channelPlaceholder: "Postar em canal..." @@ -2559,6 +2668,8 @@ _notification: youReceivedFollowRequest: "Você recebeu um pedido de seguidor" yourFollowRequestAccepted: "Seu pedido de seguidor foi aceito" pollEnded: "Os resultados da enquete agora estão disponíveis" + scheduledNotePosted: "Nota agendada foi publicada" + scheduledNotePostFailed: "Não foi possível publicar nota agendada" newNote: "Nova nota" unreadAntennaNote: "Antena {name}" roleAssigned: "Cargo dado" @@ -2638,7 +2749,7 @@ _deck: mentions: "Menções" direct: "Notas diretas" roleTimeline: "Linha do tempo do cargo" - chat: "Conversas" + chat: "Conversar com usuário" _dialog: charactersExceeded: "Você excedeu o limite de caracteres! Atualmente em {current} de {max}." charactersBelow: "Você está abaixo do limite mínimo de caracteres! Atualmente em {current} of {min}." @@ -2744,6 +2855,7 @@ _fileViewer: url: "URL" uploadedAt: "Adicionado em" attachedNotes: "Notas anexadas" + usage: "Usado" thisPageCanBeSeenFromTheAuthor: "Essa página só pode ser vista pelo usuário que enviou esse arquivo." _externalResourceInstaller: title: "Instalar de site externo" @@ -2791,9 +2903,12 @@ _dataSaver: _avatar: title: "Imagem do avatar" description: "Parar animação de avatares. Imagens animadas podem ter um arquivo mais pesado do que imagens normais, potencialmente levando a reduções no tráfego de dados." - _urlPreview: - title: "Miniaturas na prévia de URLs" - description: "Miniaturas na prévia de URLs não serão mais carregadas." + _urlPreviewThumbnail: + title: "Esconder miniaturas em prévias de URL" + description: "Miniaturas em prévias de URL não serão carregadas." + _disableUrlPreview: + title: "Desabilitar prévias de URL" + description: "Desabilita a função de prévias de URL. Diferente das miniaturas, essa função impede o carregamento de toda informação do link." _code: title: "Destaque de código" description: "Se as notações de formatação de código forem utilizadas em MFC, elas não irão carregar até serem selecionadas. Destaque de código exige baixar arquivos de alta definição para cada linguagem de programação. Logo, desabilitar o carregamento automático desses arquivos diminui a quantidade de informação comunicada." @@ -2851,6 +2966,8 @@ _offlineScreen: _urlPreviewSetting: title: "Configurações da prévia de URL" enable: "Habilitar prévia de URL" + allowRedirect: "Permitir redirecionamentos de URL em prévias." + allowRedirectDescription: "Se um URL tem um redirecionamento, você pode habilitar essa função para segui-lo e exibir a prévia do conteúdo redirecionado. Desabilitar isso irá economizar recursos, mas o conteúdo não será exibido." timeout: "Tempo máximo para obter a prévia (ms)" timeoutDescription: "Se demorar mais que esse valor para obter uma prévia, ela não será gerada." maximumContentLength: "Content-Length máximo (em bytes)" @@ -2924,10 +3041,6 @@ _customEmojisManager: uploadSettingDescription: "Nessa tela, você pode configurar o comportamento ao enviar Emojis." directoryToCategoryLabel: "Transformar as pastas em categorias" directoryToCategoryCaption: "Quando você arrastar um diretório, converter o caminho das pastas no campo \"categoria\"." - emojiInputAreaCaption: "Selecione Emojis que você deseja registrar utilizando um dos métodos." - emojiInputAreaList1: "Arraste arquivos de imagem ou diretórios dentro desse quadro" - emojiInputAreaList2: "Clique nesse link para abrir a seleção de arquivos" - emojiInputAreaList3: "Clique nesse link para selecionar do drive" confirmRegisterEmojisDescription: "Registrando os Emojis da lista como novos Emojis personalizados. Deseja continuar? (Para evitar sobrecarga, apenas {count} Emoji(s) podem ser registrados em uma única operação)" confirmClearEmojisDescription: "Descartando edições e limpando Emojis da lista. Deseja continuar?" confirmUploadEmojisDescription: "Enviando {count} arquivo(s) arrastados ao drive. Deseja continuar?" @@ -2995,6 +3108,7 @@ _bootErrors: otherOption1: "Excluir ajustes de cliente e cache" otherOption2: "Iniciar o cliente simples" otherOption3: "Iniciar ferramenta de reparo" + otherOption4: "Abrir CherryPick no modo seguro" _search: searchScopeAll: "Todos" searchScopeLocal: "Local" @@ -3003,3 +3117,194 @@ _search: pleaseEnterServerHost: "Insira o endereço do servidor" pleaseSelectUser: "Selecione um usuário" serverHostPlaceholder: "Exemplo: cherrypick.example.com" +_serverSetupWizard: + installCompleted: "Instalação do CherryPick concluída!" + firstCreateAccount: "Para iniciar, crie uma conta de administrador." + accountCreated: "Conta de administrador foi criada!" + serverSetting: "Configurações de Servidor" + youCanEasilyConfigureOptimalServerSettingsWithThisWizard: "O assistente facilita a configuração do servidor." + settingsYouMakeHereCanBeChangedLater: "Configurações alteradas pelo assistente podem ser ajustadas posteriormente." + howWillYouUseMisskey: "Como você usará o CherryPick?" + _use: + single: "Servidor de Usuário Único" + single_description: "Utilizar servidor sozinho." + single_youCanCreateMultipleAccounts: "Múltiplas contas podem ser criadas se necessário, mesmo operando como servidor de usuário único." + group: "Servidor de Grupo" + group_description: "Convide outros usuários confiáveis para utilizar com mais de um usuário" + open: "Servidor Público" + open_description: "Permitir registro de todos." + openServerAdvice: "Aceitar um número alto de pessoas desconhecidas pode envolve um risco. Recomendamos que você opere com um sistema de moderação confiável para resolver quaisquer problemas." + openServerAntiSpamAdvice: "Para prevenir que o seu servidor se torne alvo de spam, é essencial cuidar da segurança habilitando recursos antibot como o reCAPTCHA." + howManyUsersDoYouExpect: "Quantos usuários você espera?" + _scale: + small: "Menos que 100 (pequeno porte)" + medium: "Entre 100 e 1000 usuários (médio porte)" + large: "Mais que 1000 usuários (larga escala)" + largeScaleServerAdvice: "Servidores de larga escala podem precisar de conhecimento avançado de infraestrutura, como balanceamento de carga e replicação de banco de dados." + doYouConnectToFediverse: "Você deseja conectar-se com o Fediverso?" + doYouConnectToFediverse_description1: "Quando conectado com uma rede distribuída de servidores (Fediverso), o conteúdo pode ser trocado com outros servidores." + doYouConnectToFediverse_description2: "Conectar com o Fediverso também é chamado de \"federação\"" + youCanConfigureMoreFederationSettingsLater: "Configurações adicionais como especificar servidores para conectar-se com podem ser feitas posteriormente" + remoteContentsCleaning: "Limpeza automática de conteúdos recebidos" + remoteContentsCleaning_description: "A federação pode resultar em uma entrada contínua de conteúdo. Habilitar a limpeza automática removerá conteúdo obsoleto e não referenciado do servidor para economizar armazenamento." + adminInfo: "Informações da administração" + adminInfo_description: "Define as informações do administrador usadas para receber consultas." + adminInfo_mustBeFilled: "Deve ser preenchido se o servidor é público ou se a federação está ativa." + followingSettingsAreRecommended: "As configurações a seguir são recomendadas" + applyTheseSettings: "Aplicar essas configurações" + skipSettings: "Pular configuração" + settingsCompleted: "Instalação concluída!" + settingsCompleted_description: "Obrigado pelo seu tempo. Agora que tudo está pronto, você pode começar a utilizar o servidor." + settingsCompleted_description2: "As configurações do servidor podem ser alteradas no \"Painel de Controle\"" + donationRequest: "Solicitação de Doação" + _donationRequest: + text1: "CherryPick é software aberto desenvolvido por voluntários." + text2: "Nós apreciaríamos o seu apoio para podermos continuar o desenvolvimento desse software no futuro." + text3: "Também há benefícios especiais para apoiadores!" +_uploader: + editImage: "Editar Imagem" + compressedToX: "Comprimido para {x}" + savedXPercent: "Salvando {x}%" + abortConfirm: "Alguns arquivos não foram enviados, deseja abortar?" + doneConfirm: "Alguns arquivos não foram enviados, deseja continuar mesmo assim?" + maxFileSizeIsX: "O tamanho máximo de arquivos enviados é {x}" + allowedTypes: "Tipos de arquivo enviáveis" + tip: "O arquivo não foi enviado. Então, esse diálogo permite que você confirme, renomeie, comprima e recorte o arquivo antes de enviar. Quando estiver pronto, você pode enviar apertando o botão \"Enviar\"." +_clientPerformanceIssueTip: + title: "Dicas de desempenho" + makeSureDisabledAdBlocker: "Desative o seu bloqueador de anúncios" + makeSureDisabledAdBlocker_description: "Bloqueadores de anúncios podem afetar o desempenho. Certifique-se que eles não estão habilitados no seu sistema ou nos recursos/extensões do navegador. " + makeSureDisabledCustomCss: "Desabilite CSS personalizado" + makeSureDisabledCustomCss_description: "Substituir o estilo da página pode afetar o desempenho. Certifique-se que o CSS personalizado ou extensões que modifiquem o estilo da página estejam desabilitados." + makeSureDisabledAddons: "Desabilite extensões" + makeSureDisabledAddons_description: "Algumas extensões podem afetar comportamentos do cliente e afetar o desempenho. Por favor, desative as extensões do seu navegador e veja se isso melhora a situação." +_clip: + tip: "Clip é uma função que permite organização das suas notas." +_userLists: + tip: "Listas podem conter qualquer usuário que você especificar em sua criação. A lista criada aparece como uma linha do tempo exibindo usuários selecionados." +watermark: "Marca d'água" +defaultPreset: "Predefinição Padrão" +_watermarkEditor: + tip: "Uma marca d'água, como informação de autoria, pode ser adicionada à imagem." + quitWithoutSaveConfirm: "Descartar mudanças?" + driveFileTypeWarn: "Esse arquivo não é compatível" + driveFileTypeWarnDescription: "Escolha um arquivo de imagem" + title: "Editar marca d'água" + cover: "Cobrir tudo" + repeat: "Espalhar pelo conteúdo" + opacity: "Opacidade" + scale: "Tamanho" + text: "Texto" + qr: "Código QR" + position: "Posição" + margin: "Margem" + type: "Tipo" + image: "imagem" + advanced: "Avançado" + angle: "Ângulo" + stripe: "Listras" + stripeWidth: "Largura da linha" + stripeFrequency: "Número de linhas" + polkadot: "Bolinhas" + checker: "Xadrez" + polkadotMainDotOpacity: "Opacidade da bolinha principal" + polkadotMainDotRadius: "Raio da bolinha principal" + polkadotSubDotOpacity: "Opacidade da bolinha secundária" + polkadotSubDotRadius: "Raio das bolinhas adicionais" + polkadotSubDotDivisions: "Número de bolinhas adicionais" + leaveBlankToAccountUrl: "Deixe em branco para utilizar URL da conta" +_imageEffector: + title: "Efeitos" + addEffect: "Adicionar efeitos" + discardChangesConfirm: "Tem certeza que deseja sair? Há mudanças não salvas." + nothingToConfigure: "Não há nada para configurar" + _fxs: + chromaticAberration: "Aberração cromática" + glitch: "Glitch" + mirror: "Espelho" + invert: "Inverter Cores" + grayscale: "Tons de Cinza" + blur: "Desfoque" + pixelate: "Pixelizar" + colorAdjust: "Correção de Cores" + colorClamp: "Compressão de Cores" + colorClampAdvanced: "Compressão Avançada de Cores" + distort: "Distorção" + threshold: "Limiarização Binária" + zoomLines: "Linhas de Ação" + stripe: "Listras" + polkadot: "Bolinhas" + checker: "Xadrez" + blockNoise: "Bloquear Ruído" + tearing: "Descontinuidade" + fill: "Preencher" + _fxProps: + angle: "Ângulo" + scale: "Tamanho" + size: "Tamanho" + radius: "Raio" + samples: "Número de amostras" + offset: "Posição" + color: "Cor" + opacity: "Opacidade" + normalize: "Normalizar" + amount: "Quantidade" + lightness: "Esclarecer" + contrast: "Contraste" + hue: "Matiz" + brightness: "Brilho" + saturation: "Saturação" + max: "Máximo" + min: "Mínimo" + direction: "Direção" + phase: "Fase" + frequency: "Frequência" + strength: "Força" + glitchChannelShift: "Mudança de canal" + seed: "Valor da semente" + redComponent: "Componente vermelho" + greenComponent: "Componente verde" + blueComponent: "Componente azul" + threshold: "Limiar" + centerX: "Centralizar X" + centerY: "Centralizar Y" + zoomLinesSmoothing: "Suavização" + zoomLinesSmoothingDescription: "Suavização e largura das linhas de zoom não podem ser utilizados simultaneamente." + zoomLinesThreshold: "Largura das linhas de zoom" + zoomLinesMaskSize: "Diâmetro do centro" + zoomLinesBlack: "Linhas pretas" + circle: "Circular" +drafts: "Rascunhos" +_drafts: + select: "Selecionar Rascunho" + cannotCreateDraftAnymore: "O número máximo de rascunhos foi excedido." + cannotCreateDraft: "Você não pode criar um rascunho com esse conteúdo." + delete: "Excluir Rascunho" + deleteAreYouSure: "Excluir rascunho?" + noDrafts: "Sem rascunhos" + replyTo: "Resposta a {user}" + quoteOf: "Citação à nota de {user}" + postTo: "Publicando em {channel}" + saveToDraft: "Salvar como Rascunho" + restoreFromDraft: "Restaurar de Rascunho" + restore: "Redefinir" + listDrafts: "Lista de Rascunhos" + schedule: "Agendar nota" + listScheduledNotes: "Lista de notas agendadas" + cancelSchedule: "Cancelar agendamento" +qr: "Código QR" +_qr: + showTabTitle: "Visualizar" + readTabTitle: "Escanear" + shareTitle: "{name} {acct}" + shareText: "Siga-me no Fediverso!" + chooseCamera: "Escolher câmera" + cannotToggleFlash: "Não foi possível ligar a lanterna" + turnOnFlash: "Ligar a lanterna" + turnOffFlash: "Desligar a lanterna" + startQr: "Retornar ao leitor de códigos QR" + stopQr: "Deixar o leitor de códigos QR" + noQrCodeFound: "Nenhum código QR encontrado" + scanFile: "Escanear imagem de dispositivo" + raw: "Texto" + mfm: "MFC" diff --git a/locales/ro-RO.yml b/locales/ro-RO.yml index 361d718ef8..cdc2530358 100644 --- a/locales/ro-RO.yml +++ b/locales/ro-RO.yml @@ -250,7 +250,6 @@ noUsers: "Niciun utilizator" editProfile: "Editează profilul" noteDeleteConfirm: "Ești sigur(ă) că vrei să ștergi această notă?" pinLimitExceeded: "Nu poți mai fixa mai multe note" -intro: "CherryPick s-a instalat! Te rog crează un utilizator admin." done: "Gata" processing: "Se procesează" preview: "Previzualizare" @@ -523,8 +522,8 @@ showNoteActionsOnlyHover: "Afișează acțiunile de notare numai la trecerea cur showReactionsCount: "Afișează numărul de reacții la note" noHistory: "Nu există istoric" signinHistory: "Istoric autentificări" -enableAdvancedMfm: "Permite autentificarea multiplă(MFM) avansată" -enableAnimatedMfm: "Permite autentificarea multiplă(MFM) animată" +enableAdvancedMfm: "Permite autentificarea multiplă(MFC) avansată" +enableAnimatedMfm: "Permite autentificarea multiplă(MFC) animată" doing: "Se procesează..." category: "Categorie" tags: "Etichete" @@ -1280,7 +1279,6 @@ _theme: _sfx: note: "Note" notification: "Notificări" - chat: "Chat" _ago: invalid: "Nu e nimic de văzut aici" _2fa: @@ -1305,6 +1303,7 @@ _cw: _visibility: home: "Acasă" followers: "Urmăritori" + specified: "Note directe" _postForm: replyPlaceholder: "Răspunde la această notă..." quotePlaceholder: "Citează aceasta nota..." @@ -1359,6 +1358,7 @@ _deck: list: "Liste" channel: "Canale" mentions: "Mențiuni" + direct: "Note directe" roleTimeline: "Cronologia rolului" _webhookSettings: name: "Nume" @@ -1394,3 +1394,18 @@ _search: searchScopeLocal: "Local" searchScopeUser: "Utilizator specific" serverHostPlaceholder: "Exemplu: cherrypick.example.com" +_watermarkEditor: + scale: "Dimensiune" + text: "Text" + position: "Poziție" + type: "Tip" + image: "Imagini" + advanced: "Avansat" +_imageEffector: + _fxProps: + scale: "Dimensiune" + size: "Dimensiune" + offset: "Poziție" +_qr: + showTabTitle: "Arată" + raw: "Text" diff --git a/locales/ru-RU.yml b/locales/ru-RU.yml index fdfb5a83f4..52d5686bad 100644 --- a/locales/ru-RU.yml +++ b/locales/ru-RU.yml @@ -2,7 +2,7 @@ _lang_: "Русский" headlineMisskey: "Сеть, сплетённая из заметок" introMisskey: "Добро пожаловать! CherryPick — это децентрализованный сервис микроблогов с открытым исходным кодом.\nПишите «заметки» — делитесь со всеми происходящим вокруг или рассказывайте о себе 📡\nСтавьте «реакции» — выражайте свои чувства и эмоции от заметок других 👍\nОткройте для себя новый мир 🚀" -poweredByMisskeyDescription: "{name} – сервис на платформе с открытым исходным кодом CherryPick, называемый экземпляром CherryPick." +poweredByMisskeyDescription: "{name} – один из инстансов (также называемый экземпляром CherryPick), использующий платформу с открытым исходным кодом CherryPick." monthAndDay: "{day}.{month}" search: "Поиск" reset: "Сброс" @@ -82,7 +82,7 @@ export: "Экспорт" files: "Файлы" download: "Скачать" driveFileDeleteConfirm: "Удалить файл «{name}»? Заметки с ним также будут удалены." -unfollowConfirm: "Удалить из подписок пользователя {name}?" +unfollowConfirm: "Отписаться от {name} ?" exportRequested: "Вы запросили экспорт. Это может занять некоторое время. Результат будет добавлен на «Диск»." importRequested: "Вы запросили импорт. Это может занять некоторое время." lists: "Списки" @@ -251,7 +251,6 @@ noUsers: "Нет ни одного пользователя" editProfile: "Редактировать профиль" noteDeleteConfirm: "Вы хотите удалить эту заметку?" pinLimitExceeded: "Нельзя закрепить ещё больше заметок" -intro: "Установка CherryPick завершена! А теперь создайте учетную запись администратора." done: "Готово" processing: "Обработка" preview: "Предпросмотр" @@ -299,6 +298,7 @@ uploadFromUrl: "Загрузить по ссылке" uploadFromUrlDescription: "Ссылка на файл, который хотите загрузить" uploadFromUrlRequested: "Загрузка выбранного" uploadFromUrlMayTakeTime: "Загрузка может занять некоторое время." +uploadNFiles: "Загрузить {n} файл" explore: "Обзор" messageRead: "Прочитали" noMoreHistory: "История закончилась" @@ -586,8 +586,10 @@ showFixedPostForm: "Показывать поле для ввода новой showFixedPostFormInChannel: "Показывать поле для ввода новой заметки наверху ленты (каналы)" withRepliesByDefaultForNewlyFollowed: "По умолчанию включайте ответы новых пользователей, на которых вы подписались, во временную шкалу" newNoteRecived: "Появилась новая заметка" +newNote: "Новая заметка" sounds: "Звуки" sound: "Звуки" +notificationSoundSettings: "Настройки звука уведомлений" listen: "Слушать" none: "Ничего" showInPage: "Показать страницу" @@ -803,6 +805,7 @@ wide: "Толстый" narrow: "Тонкий" reloadToApplySetting: "Это настройка вступает в силу при загрузке страницы. Перезагрузить сейчас?" needReloadToApply: "Изменения вступят в силу после перезагрузки страницы." +needToRestartServerToApply: "Для вступления изменений в силу необходимо перезапустить сервер." showTitlebar: "Показать заголовок" clearCache: "Очистить кэш" onlineUsersCount: "Пользователей сейчас в сети: {n}" @@ -1190,13 +1193,25 @@ unused: "Неиспользованное" used: "Использован" expired: "Срок действия приглашения истёк" doYouAgree: "Согласны?" +beSureToReadThisAsItIsImportant: "Это важно, поэтому, пожалуйста, прочтите это." +iHaveReadXCarefullyAndAgree: "Я прочитал(а) и согласен(сна) с условиями \"{x}" +dialog: "Диалог" icon: "Аватар" +currentAnnouncements: "Текущие новости" +pastAnnouncements: "Предыдущие новости" +youHaveUnreadAnnouncements: "У вас есть непрочитанные уведомления" replies: "Ответы" renotes: "Репост" loadReplies: "Показать ответы" +loadConversation: "Загрузить беседу" pinnedList: "Закреплённый список" keepScreenOn: "Держать экран включённым" +unnotifyNotes: "Отписаться от сообщений" +authentication: "Аутентификация" +authenticationRequiredToContinue: "Пожалуйста, пройдите аутентификацию, чтобы продолжить" +dateAndTime: "Дата и время" showRenotes: "Показывать репосты" +edited: "Изменено" mutualFollow: "Взаимные подписки" followingOrFollower: "Подписки или подписчики" fileAttachedOnly: "Только заметки с файлами" @@ -1207,31 +1222,75 @@ sourceCode: "Исходный код" sourceCodeIsNotYetProvided: "Исходный код пока не доступен. Свяжитесь с администратором, чтобы исправить эту проблему." repositoryUrl: "Ссылка на репозиторий" repositoryUrlDescription: "Если вы используете CherryPick как есть (без изменений в исходном коде), введите https://github.com/kokonect-link/cherrypick" +feedback: "Обратная связь" privacyPolicy: "Политика Конфиденциальности" privacyPolicyUrl: "Ссылка на Политику Конфиденциальности" +tosAndPrivacyPolicy: "Условия использования и политика конфиденциальности" +avatarDecorations: "Украшения для аватара" attach: "Прикрепить" +detachAll: "Убрать всё" angle: "Угол" flip: "Переворот" -disableStreamingTimeline: "Отключить обновление ленты в режиме реального времени" +showAvatarDecorations: "Показать украшения для аватара" +pullDownToRefresh: "Опустите что бы обновить" useGroupedNotifications: "Отображать уведомления сгруппировано" +cwNotationRequired: "Если включена опция «Скрыть содержимое», необходимо написать аннотацию." doReaction: "Добавить реакцию" code: "Код" +reloadRequiredToApplySettings: "Для применения настроек необходима обновить страницу." remainingN: "Остаётся: {n}" +overwriteContentConfirm: "Текущее содержимое будет перезаписано. Вы уверены?" seasonalScreenEffect: "Эффект времени года на экране" decorate: "Украсить" addMfmFunction: "Добавить MFC" +bubbleGame: "BubbleGame" +sfx: "Звуковые эффекты" +soundWillBePlayed: "Будет воспроизведен звук" +showReplay: "Показать повтор" +endReplay: "Конец повтора" lastNDays: "Последние {n} сут" hemisphere: "Место проживания" +userSaysSomethingSensitive: "Сообщение, содержит конфиденциальные файлы от {name}" enableHorizontalSwipe: "Смахните в сторону, чтобы сменить вкладки" surrender: "Этот пост не может быть отменен." +gameRetry: "Повторить попытку" +notUsePleaseLeaveBlank: "Если не используется, оставьте пустым" useNativeUIForVideoAudioPlayer: "Использовать интерфейс браузера при проигрывании видео и звука" keepOriginalFilename: "Сохранять исходное имя файла" keepOriginalFilenameDescription: "Если вы выключите данную настройку, имена файлов будут автоматически заменены случайной строкой при загрузке." alwaysConfirmFollow: "Всегда подтверждать подписку" inquiry: "Связаться" +fromX: "Из {x}" +genEmbedCode: "Сгенерировать код для " +noteOfThisUser: "Список заметок этого пользователя" +clipNoteLimitExceeded: "К этому клипу больше нельзя добавить заметки" +performance: "Производительность" +modified: "Изменено" +signinWithPasskey: "Войдите в систему, используя свой пароль" +unknownWebAuthnKey: "Неизвестный ключ" +passkeyVerificationFailed: "Ошибка проверка ключа доступа " messageToFollower: "Сообщение подписчикам" +testCaptchaWarning: "Эта функция предназначена для тестирования CAPTCHA. Не использовать это в рабочей среде" +prohibitedWordsForNameOfUser: "Запрещенные слова (имя пользователя)" +prohibitedWordsForNameOfUserDescription: "Если имя пользователя содержит строку из этого списка, изменение имени пользователя будет запрещено. На пользователей с правами модератора это ограничение не распространяется. Имена пользователей также проверяются путём замены всех букв в нижнем регистре" +yourNameContainsProhibitedWords: "Имя, которое вы пытаетесь изменить, содержит запрещенную строку символов" +yourNameContainsProhibitedWordsDescription: "Имя содержит запрещённую строку символов. Если вы хотите использовать это имя, обратитесь к администратору сервера" +thisContentsAreMarkedAsSigninRequiredByAuthor: "Автор сообщения установил требование в виде авторизации для просмотра" +lockdown: "Доступ ограничен" +pleaseSelectAccount: "Выберите свой аккаунт" +availableRoles: "Доступные роли" +federationDisabled: "Федерация отключена для этого сервера. Вы не можете взаимодействовать с пользователями на других серверах." +draft: "Черновик" +markAsSensitiveConfirm: "Отметить контент как чувствительный?" +preferences: "Основное" +resetToDefaultValue: "Сбросить настройки до стандартных" +syncBetweenDevices: "Синхронизировать между устройствами" postForm: "Форма отправки" +textCount: "Количество символов" information: "Описание" +inMinutes: "мин" +inDays: "сут" +widgets: "Виджеты" _chat: invitations: "Пригласить" noHistory: "История пока пуста" @@ -1240,6 +1299,11 @@ _chat: send: "Отправить" _settings: webhook: "Вебхук" + preferencesBanner: "Вы можете настроить общее поведение клиента по вашим предпочтениям" + timelineAndNote: "Лента и заметки" + _chat: + showSenderName: "Показывать имя отправителя" + sendOnEnter: "Использовать Enter для отправки" _delivery: stop: "Заморожено" _type: @@ -1488,7 +1552,7 @@ _achievements: description: "Нажато здесь" _justPlainLucky: title: "Чистая удача" - description: "Может достаться с вероятностью 0,01% каждые 10 секунд." + description: "Может достаться с вероятностью 0,005% каждые 10 секунд." _setNameToSyuilo: title: "Комплекс бога" description: "Установлено «syuilo» в качестве имени" @@ -1519,6 +1583,12 @@ _achievements: title: "Brain Diver" description: "Опубликована ссылка на песню «Brain Diver»" flavor: "Мисски-Мисски Ла-Ту-Ма" + _bubbleGameExplodingHead: + title: "🤯" + description: "Самый большой объект в Bubble game" + _bubbleGameDoubleExplodingHead: + title: "Двойной🤯" + description: "Два самых больших объекта в Bubble game одновременно!" _role: new: "Новая роль" edit: "Изменить роль" @@ -1737,7 +1807,7 @@ _mfc: rotate: "Повернуть" rotateDescription: "Поворачивает на заданный угол." plain: "Буквально" - plainDescription: "MFM внутри отключается, и текст отображается как есть" + plainDescription: "MFC внутри отключается, и текст отображается как есть" _instanceTicker: none: "Не показывать" remote: "Только для других сайтов" @@ -1832,7 +1902,6 @@ _theme: buttonBg: "Фон кнопки" buttonHoverBg: "Текст кнопки" inputBorder: "Рамка поля ввода" - driveFolderBg: "Фон папки «Диска»" badge: "Значок" messageBg: "Фон беседы" fgHighlighted: "Подсвеченный текст" @@ -2280,3 +2349,25 @@ _search: searchScopeAll: "Все" searchScopeLocal: "Местная" searchScopeUser: "Указанный пользователь" +_watermarkEditor: + opacity: "Непрозрачность" + scale: "Размер" + text: "Текст" + position: "Позиция" + type: "Тип" + image: "Изображения" + advanced: "Для продвинутых" + angle: "Угол" +_imageEffector: + _fxProps: + angle: "Угол" + scale: "Размер" + size: "Размер" + offset: "Позиция" + color: "Цвет" + opacity: "Непрозрачность" + lightness: "Осветление" +drafts: "Черновик" +_qr: + showTabTitle: "Отображение" + raw: "Текст" diff --git a/locales/si-LK.yml b/locales/si-LK.yml index c43f3d860d..841fb10585 100644 --- a/locales/si-LK.yml +++ b/locales/si-LK.yml @@ -1,10 +1,18 @@ --- _lang_: "සිංහල" monthAndDay: "{month}-{day}" +search: "සොයන්න" +reset: "යළි සකසන්න" +notifications: "දැනුම්දීම්" username: "පරිශීලක නාමය" password: "මුරපදය" +ok: "හරි" +gotIt: "තේරුණා" cancel: "අවලංගු කරන්න" +noThankYou: "එපා, ස්තුතියි" +noNotifications: "දැනුම්දීම් නැත" instance: "සර්වර්" +settings: "සැකසුම්" login: "පිවිසෙන්න" users: "පරිශීලක" note: "නෝට්" @@ -13,10 +21,19 @@ instances: "සර්වර්" smtpUser: "පරිශීලක නාමය" smtpPass: "මුරපදය" user: "පරිශීලක" +searchByGoogle: "සොයන්න" _sfx: note: "නෝට්" + notification: "දැනුම්දීම්" +_2fa: + renewTOTPCancel: "එපා, ස්තුතියි" +_widgets: + notifications: "දැනුම්දීම්" _profile: username: "පරිශීලක නාමය" _notification: _types: login: "පිවිසෙන්න" +_deck: + _columns: + notifications: "දැනුම්දීම්" diff --git a/locales/sk-SK.yml b/locales/sk-SK.yml index 942a08e436..a3f3b3053e 100644 --- a/locales/sk-SK.yml +++ b/locales/sk-SK.yml @@ -204,7 +204,6 @@ noUsers: "Žiadni používatelia" editProfile: "Upraviť profil" noteDeleteConfirm: "Naozaj chcete odstrániť túto poznámku?" pinLimitExceeded: "Ďalšie poznámky už nemôžete pripnúť." -intro: "Inštalácia CherryPick je dokončená! Prosím vytvorte administrátora." done: "Hotovo" processing: "Pracujem..." preview: "Náhľad" @@ -927,6 +926,9 @@ flip: "Preklopiť" lastNDays: "Posledných {n} dní" postForm: "Napísať poznámku" information: "Informácie" +inMinutes: "min" +inDays: "dní" +widgets: "Widgety" _chat: invitations: "Pozvať" noHistory: "Žiadna história" @@ -1029,7 +1031,7 @@ _aboutMisskey: morePatrons: "Takisto oceňujeme podporu mnoých ďalších, ktorí tu nie sú uvedení. Ďakujeme! 🥰" patrons: "Prispievatelia" _mfc: - cheatSheet: "MFM Cheatsheet" + cheatSheet: "MFC Cheatsheet" intro: "MFC je CherryPick exkluzívny značkovací jazyk, ktorý sa dá používať na viacerých miestach. Tu môžete vidieť zoznam všetkej dostupnej MFC syntaxe." dummy: "CherryPick rozširuje svet Fediverza" mention: "Zmienka" @@ -1188,7 +1190,6 @@ _theme: buttonBg: "Pozadie tlačidla" buttonHoverBg: "Pozadie tlačidla (pod kurzorom)" inputBorder: "Okraj vstupného poľa" - driveFolderBg: "Pozadie priečinu disku" badge: "Odznak" messageBg: "Pozadie chatu" fgHighlighted: "Zvýraznený text" @@ -1535,3 +1536,20 @@ _remoteLookupErrors: _search: searchScopeAll: "Všetko" searchScopeLocal: "Lokálne" +_watermarkEditor: + opacity: "Priehľadnosť" + scale: "Veľkosť" + text: "Text" + type: "Typ" + image: "Obrázky" + advanced: "Rozšírené" +_imageEffector: + _fxProps: + scale: "Veľkosť" + size: "Veľkosť" + color: "Farba" + opacity: "Priehľadnosť" + lightness: "Zosvetliť" +_qr: + showTabTitle: "Zobraziť" + raw: "Text" diff --git a/locales/sv-SE.yml b/locales/sv-SE.yml index c17968959b..5f6757211e 100644 --- a/locales/sv-SE.yml +++ b/locales/sv-SE.yml @@ -211,7 +211,6 @@ noUsers: "Det finns inga användare" editProfile: "Redigera profil" noteDeleteConfirm: "Är du säker på att du vill ta bort denna not?" pinLimitExceeded: "Du kan inte fästa fler noter" -intro: "CherryPick har installerats! Vänligen skapa en adminanvändare." done: "Klar" processing: "Bearbetar..." preview: "Förhandsvisning" @@ -611,7 +610,6 @@ _theme: _sfx: note: "Noter" notification: "Notifikationer" - chat: "Chatt" _ago: justNow: "Just nu" _2fa: @@ -648,6 +646,7 @@ _poll: _visibility: home: "Hem" followers: "Följare" + specified: "Direktnoter" _profile: name: "Namn" username: "Användarnamn" @@ -694,6 +693,7 @@ _deck: list: "Listor" channel: "kanal" mentions: "Omnämningar" + direct: "Direktnoter" _webhookSettings: name: "Namn" active: "Aktiverad" @@ -713,3 +713,11 @@ _selfXssPrevention: warning: "VARNING" _search: searchScopeAll: "Allt" +_watermarkEditor: + scale: "Storlek" + image: "Bilder" +_imageEffector: + _fxProps: + scale: "Storlek" + size: "Storlek" + color: "Färg" diff --git a/locales/th-TH.yml b/locales/th-TH.yml index 1d1bb5deb5..a9b1bcd08f 100644 --- a/locales/th-TH.yml +++ b/locales/th-TH.yml @@ -146,7 +146,7 @@ enterFileName: "พิมพ์ชื่อไฟล์" mute: "ปิดเสียง" unmute: "ยกเลิกการปิดเสียง" renoteMute: "ปิดเสียงรีโน้ต" -renoteUnmute: "เปิดเสียง รีโน้ต" +renoteUnmute: "เลิกปิดเสียงรีโน้ต" block: "บล็อก" unblock: "เลิกบล็อก" suspend: "ระงับ" @@ -220,6 +220,7 @@ silenceThisInstance: "ปิดปากเซิร์ฟเวอร์นี mediaSilenceThisInstance: "ปิดปากสื่อของเซิร์ฟเวอร์นี้" operations: "ดำเนินการ" software: "ซอฟต์แวร์" +softwareName: "ชื่อซอฟต์แวร์" version: "เวอร์ชั่น" metadata: "Metadata" withNFiles: "{n} ไฟล์" @@ -241,8 +242,8 @@ silencedInstances: "ปิดปากเซิร์ฟเวอร์นี้ silencedInstancesDescription: "ระบุโฮสต์ของเซิร์ฟเวอร์ที่ต้องการปิดปาก คั่นด้วยการขึ้นบรรทัดใหม่, บัญชีทั้งหมดของเซิร์ฟเวอร์ดังกล่าวจะถือว่าถูกปิดปากเช่นกัน ทำได้เฉพาะคำขอติดตามเท่านั้น และไม่สามารถกล่าวถึงบัญชีในเซิร์ฟเวอร์นี้ได้หากไม่ได้ถูกติดตามกลับ | สิ่งนี้ไม่มีผลต่ออินสแตนซ์ที่ถูกบล็อก" mediaSilencedInstances: "เซิร์ฟเวอร์ที่ถูกปิดปากสื่อ" mediaSilencedInstancesDescription: "ระบุโฮสต์ของเซิร์ฟเวอร์ที่ต้องการปิดปากสื่อ คั่นด้วยการขึ้นบรรทัดใหม่, ไฟล์ที่ถูกส่งจากบัญชีของเซิร์ฟเวอร์ดังกล่าวจะถือว่าถูกปิดปาก แล้วจะถูกติดเครื่องหมายว่ามีเนื้อหาละเอียดอ่อน และเอโมจิแบบกำหนดเองก็จะใช้ไม่ได้ด้วย | สิ่งนี้ไม่มีผลต่ออินสแตนซ์ที่ถูกบล็อก" -federationAllowedHosts: "เซิร์ฟเวอร์ที่เปิดให้บริการแบบเฟเดอเรชั่น" -federationAllowedHostsDescription: "ระบุชื่อโฮสต์ของเซิร์ฟเวอร์ที่คุณต้องการอนุญาตให้เชื่อมต่อแบบเฟเดอเรชั่น โดยต้องเว้นวรรคแต่ละบรรทัด" +federationAllowedHosts: "เซิร์ฟเวอร์ที่อนุญาตให้เชื่อมกับสหพันธ์" +federationAllowedHostsDescription: "ระบุโฮสต์ของเซิร์ฟเวอร์ที่อนุญาตให้เชื่อมกับสหพันธ์ โดยแยกแต่ละรายการด้วยบรรทัดใหม่" muteAndBlock: "ปิดเสียงและบล็อก" mutedUsers: "ผู้ใช้ที่ถูกปิดเสียง" blockedUsers: "ผู้ใช้ที่ถูกบล็อก" @@ -250,9 +251,9 @@ noUsers: "ไม่พบผู้ใช้งาน" editProfile: "แก้ไขโปรไฟล์" noteDeleteConfirm: "ต้องการลบโน้ตนี้ใช่ไหม?" pinLimitExceeded: "คุณไม่สามารถปักหมุดโน้ตเพิ่มเติมใดๆได้อีก" -intro: "การติดตั้ง CherryPick เสร็จสิ้นแล้วนะ! โปรดสร้างผู้ใช้งานที่เป็นผู้ดูแลระบบ" done: "เสร็จสิ้น" processing: "กำลังประมวลผล..." +preprocessing: "กำลังจัดเตรียม..." preview: "แสดงตัวอย่าง" default: "ค่าเริ่มต้น" defaultValueIs: "ค่าเริ่มต้น: {value}" @@ -298,9 +299,11 @@ uploadFromUrl: "อัปโหลดจาก URL" uploadFromUrlDescription: "URL ของไฟล์ที่คุณต้องการอัปโหลด" uploadFromUrlRequested: "ร้องขอการอัปโหลดแล้ว" uploadFromUrlMayTakeTime: "การอัปโหลดอาจใช้เวลาสักครู่จึงจะเสร็จสมบูรณ์" +uploadNFiles: "อัปโหลด {n} ไฟล์" explore: "สำรวจ" messageRead: "อ่านแล้ว" noMoreHistory: "ไม่มีประวัติเพิ่มเติม" +startChat: "เริ่มแชต" nUsersRead: "อ่านโดย {n}" agreeTo: "ฉันยอมรับ {0}" agree: "ยอมรับ" @@ -325,6 +328,7 @@ dark: "มืด" lightThemes: "ธีมสว่าง" darkThemes: "ธีมมืด" syncDeviceDarkMode: "ซิงค์โหมดมืดกับการตั้งค่าอุปกรณ์ของคุณ" +switchDarkModeManuallyWhenSyncEnabledConfirm: "“{x}” เปิดอยู่ ต้องการปิดการซิงค์และสลับโหมดด้วยตนเองหรือไม่?" drive: "ไดรฟ์" fileName: "ชื่อไฟล์" selectFile: "เลือกไฟล์" @@ -365,7 +369,7 @@ reject: "ปฏิเสธ" normal: "ปกติ" instanceName: "ชื่อเซิร์ฟเวอร์" instanceDescription: "คำอธิบายแนะนำเซิร์ฟเวอร์" -maintainerName: "ผู้ดูแล" +maintainerName: "ชื่อผู้ดูแลระบบ" maintainerEmail: "อีเมลผู้ดูแลระบบ" tosUrl: "URL เงื่อนไขการให้บริการ" thisYear: "ปีนี้" @@ -423,6 +427,7 @@ antennaExcludeBots: "ยกเว้นบัญชีบอต" antennaKeywordsDescription: "คั่นด้วยเว้นวรรคสำหรับเงื่อนไข AND, หรือขึ้นบรรทัดใหม่สำหรับเงื่อนไข OR" notifyAntenna: "แจ้งเตือนเกี่ยวกับโน้ตใหม่" withFileAntenna: "เฉพาะโน้ตที่มีไฟล์" +excludeNotesInSensitiveChannel: "ไม่รวมโน้ตจากช่องเนื้อหาละเอียดอ่อน" enableServiceworker: "เปิดใช้งานการแจ้งเตือนแบบพุชไปยังเบราว์เซอร์ของคุณ" antennaUsersDescription: "ระบุหนึ่งชื่อผู้ใช้ต่อบรรทัด" caseSensitive: "อักษรพิมพ์ใหญ่-พิมพ์เล็กความหมายต่างกัน" @@ -453,17 +458,17 @@ totpDescription: "ใช้แอปยืนยันตัวตนเพื moderator: "ผู้ควบคุม" moderation: "การกลั่นกรอง" moderationNote: "โน้ตการกลั่นกรอง" -moderationNoteDescription: "คุณสามารถใส่โน้ตส่วนตัวที่เฉพาะผู้ดูแลระบบเท่านั้นที่สามารถเข้าถึงได้" +moderationNoteDescription: "สามารถจดเมโมที่จะแบ่งปันเฉพาะระหว่างผู้ควบคุมได้" addModerationNote: "เพิ่มโน้ตการกลั่นกรอง" moderationLogs: "ปูมการควบคุมดูแล" nUsersMentioned: "กล่าวถึงโดยผู้ใช้ {n} ราย" -securityKeyAndPasskey: "ความปลอดภัยและรหัสผ่าน" -securityKey: "กุญแจความปลอดภัย" +securityKeyAndPasskey: "Security key และ Passkey" +securityKey: "Security Key" lastUsed: "ใช้ล่าสุด" lastUsedAt: "ใช้งานครั้งล่าสุด: {t}" unregister: "เลิกติดตาม" passwordLessLogin: "เข้าสู่ระบบแบบไม่ใช้รหัสผ่าน" -passwordLessLoginDescription: "อนุญาตให้เข้าสู่ระบบโดยไม่ต้องใช้รหัสผ่านโดยใช้รหัสรักษาความปลอดภัยหรือรหัสผ่านเท่านั้น" +passwordLessLoginDescription: "เข้าสู่ระบบโดยไม่ใช้รหัสผ่าน โดยใช้เฉพาะ Security Key หรือ Passkey เท่านั้น" resetPassword: "รีเซ็ตรหัสผ่าน" newPasswordIs: "รหัสผ่านใหม่คือ “{password}”" reduceUiAnimation: "ลดภาพเคลื่อนไหว UI" @@ -583,8 +588,10 @@ showFixedPostForm: "แสดงแบบฟอร์มการโพสต์ showFixedPostFormInChannel: "แสดงแบบฟอร์มการโพสต์ที่ด้านบนของไทม์ไลน์ (ช่อง)" withRepliesByDefaultForNewlyFollowed: "แสดงการตอบกลับจากผู้ใช้ที่คุณเพิ่งติดตามลงไทม์ไลน์ตามค่าเริ่มต้น" newNoteRecived: "มีโน้ตใหม่" +newNote: "โน้ตใหม่" sounds: "เสียง" sound: "เสียง" +notificationSoundSettings: "ตั้งค่าเสียงแจ้งเตือน" listen: "ฟัง" none: "ไม่มี" showInPage: "แสดงในเพจ" @@ -594,6 +601,7 @@ masterVolume: "ระดับเสียงหลัก" notUseSound: "ไม่ใช้เสียง" useSoundOnlyWhenActive: "มีเสียงออกเฉพาะตอนกำลังใช้ CherryPick อยู่เท่านั้น" details: "รายละเอียด" +renoteDetails: "รายละเอียดรีโน้ต" chooseEmoji: "เลือกเอโมจิ" unableToProcess: "ไม่สามารถดำเนินการให้เสร็จสิ้นได้" recentUsed: "ใช้ล่าสุด" @@ -615,8 +623,8 @@ output: "เอาท์พุต" script: "สคริปต์" disablePagesScript: "ปิดการใช้งาน AiScript บนเพจ" updateRemoteUser: "อัปเดตข้อมูลผู้ใช้งานระยะไกล" -unsetUserAvatar: "เลิกตั้งอวตาร" -unsetUserAvatarConfirm: "ต้องการเลิกตั้งอวตารใข่ไหม?" +unsetUserAvatar: "เลิกตั้งไอคอน" +unsetUserAvatarConfirm: "ต้องการเลิกตั้งไอคอนประจำตัวหรือไม่?" unsetUserBanner: "เลิกตั้งแบนเนอร์" unsetUserBannerConfirm: "ต้องการเลิกตั้งแบนเนอร์?" deleteAllFiles: "ลบไฟล์ทั้งหมด" @@ -691,16 +699,19 @@ smtpSecure: "ใช้โดยนัย SSL/TLS สำหรับการเ smtpSecureInfo: "ปิดสิ่งนี้เมื่อใช้ STARTTLS" testEmail: "ทดสอบการส่งอีเมล" wordMute: "ปิดเสียงคำ" +wordMuteDescription: "ย่อโน้ตที่มีวลีที่ระบุ สามารถดูโน้ตที่ย่อแล้วได้โดยคลิกที่โน้ตเหล่านั้น" hardWordMute: "ปิดเสียงคำแบบแข็งโป๊ก" -hardWordMuteDescription: "ซ่อนหมายเหตุที่มีวลีที่ระบุ ต่างจากการปิดเสียงคำ โน้ตต่างๆ จะถูกซ่อนไว้อย่างสมบูรณ์" +showMutedWord: "แสดงคำที่ถูกปิดเสียง" +hardWordMuteDescription: "จะซ่อนโน้ตที่มีคำที่ระบุไว้ ซึ่งไม่เหมือนการปิดเสียงคำ ในกรณีนี้โน้ตจะไม่แสดงเลย" regexpError: "เกิดข้อผิดพลาดใน regular expression" regexpErrorDescription: "เกิดข้อผิดพลาดใน regular expression บรรทัดที่ {line} ของการปิดเสียงคำ {tab} :" instanceMute: "ปิดเสียงเซิร์ฟเวอร์" userSaysSomething: "{name} พูดอะไรบางอย่าง" -userSaysSomethingAbout: "{name} พูดอะไรบางอย่างเกี่ยวกับ \"{word}\"" +userSaysSomethingAbout: "{name} พูดบางอย่างเกี่ยวกับ “{word}”" makeActive: "เปิดใช้งาน" display: "แสดงผล" copy: "คัดลอก" +copiedToClipboard: "คัดลอกไปยังคลิปบอร์ดแล้ว" metrics: "เมตริก" overview: "ภาพรวม" logs: "ปูม" @@ -766,7 +777,7 @@ yes: "ใช่" no: "ไม่" driveFilesCount: "จำนวนไฟล์ไดรฟ์" driveUsage: "การใช้พื้นที่ไดรฟ์" -noCrawle: "ปฏิเสธการจัดทำดัชนีของโปรแกรมรวบรวมข้อมูล" +noCrawle: "ปฏิเสธการจัดทำดัชนีของ Crawler (โปรแกรมรวบรวมข้อมูล)" noCrawleDescription: "ขอให้เครื่องมือค้นหาไม่จัดทำดัชนีหน้าโปรไฟล์ โน้ต หน้าเพจ ฯลฯ" lockedAccountInfo: "แม้ว่าการอนุมัติการติดตามถูกเปิดใช้งานอยู่ทุกคนก็ยังคงสามารถเห็นโน้ตของคุณได้ เว้นแต่ว่าคุณจะเปลี่ยนการเปิดเผยโน้ตของคุณเป็น “เฉพาะผู้ติดตาม”" alwaysMarkSensitive: "ทำเครื่องหมายว่ามีเนื้อหาละเอียดอ่อนเป็นค่าเริ่มต้น" @@ -776,7 +787,7 @@ highlightSensitiveMedia: "ไฮไลท์สื่อที่มีเนื verificationEmailSent: "ได้ส่งอีเมลยืนยันแล้ว กรุณาเข้าลิงก์ที่ระบุในอีเมลเพื่อทำการตั้งค่าให้เสร็จสิ้น" notSet: "ไม่ได้ตั้งค่า" emailVerified: "อีเมลได้รับการยืนยันแล้ว" -noteFavoritesCount: "จำนวนโน้ตที่ชื่นชอบ" +noteFavoritesCount: "จำนวนโน้ตโปรด" pageLikesCount: "จำนวนเพจที่ถูกใจ" pageLikedCount: "จำนวนการกดถูกใจเพจที่ได้รับแล้ว" contact: "ติดต่อ" @@ -796,6 +807,7 @@ wide: "กว้าง" narrow: "ชิด" reloadToApplySetting: "การตั้งค่านี้จะมีผลหลังจากโหลดหน้าซ้ำเท่านั้น ต้องการที่จะโหลดใหม่เลยไหม?" needReloadToApply: "ต้องรีโหลดเพื่อให้การเปลี่ยนแปลงมีผล" +needToRestartServerToApply: "จำเป็นต้องรีสตาร์ทเซิร์ฟเวอร์เพื่อให้การเปลี่ยนแปลงมีผล" showTitlebar: "แสดงแถบชื่อ" clearCache: "ล้างแคช" onlineUsersCount: "{n} รายกำลังออนไลน์" @@ -889,7 +901,7 @@ previewNoteText: "แสดงตัวอย่าง" customCss: "CSS ที่กำหนดเอง" customCssWarn: "ควรใช้การตั้งค่านี้เฉพาะต่อเมื่อคุณรู้มันใช้ทำอะไร การตั้งค่าที่ไม่เหมาะสมอาจทำให้ไคลเอ็นต์ไม่สามารถใช้งานได้อย่างถูกต้อง" global: "ทั่วโลก" -squareAvatars: "แสดงผลอวตารเป็นสี่เหลี่ยม" +squareAvatars: "แสดงไอคอนประจำตัวเป็นสี่เหลี่ยม" sent: "ส่ง" received: "ได้รับแล้ว" searchResult: "ผลการค้นหา" @@ -958,6 +970,9 @@ oneHour: "1 ชั่วโมง" oneDay: "1 วัน" oneWeek: "1 สัปดาห์" oneMonth: "หนึ่งเดือน" +threeMonths: "3 เดือน" +oneYear: "1 ปี" +threeDays: "3 วัน" reflectMayTakeTime: "อาจจำเป็นต้องใช้เวลาสักระยะหนึ่งจึงจะเห็นแสดงผลได้นะ" failedToFetchAccountInformation: "ไม่สามารถเรียกดึงข้อมูลบัญชีได้" rateLimitExceeded: "เกินขีดจำกัดอัตรา" @@ -982,6 +997,7 @@ document: "เอกสาร" numberOfPageCache: "จำนวนหน้าเพจที่แคช" numberOfPageCacheDescription: "การเพิ่มจำนวนนี้จะช่วยเพิ่มความสะดวกให้กับผู้ใช้งาน แต่จะทำให้เซิร์ฟเวอร์โหลดมากขึ้นและต้องใช้หน่วยความจำมากขึ้นอีกด้วย" logoutConfirm: "ต้องการออกจากระบบใช่ไหม?" +logoutWillClearClientData: "เมื่อออกจากระบบ ข้อมูลการตั้งค่าของไคลเอนต์จะถูกลบออกจากเบราว์เซอร์ เพื่อให้สามารถกู้คืนข้อมูลการตั้งค่าได้เมื่อกลับมาเข้าสู่ระบบอีกครั้ง โปรดเปิดใช้งานการสำรองข้อมูลการตั้งค่าอัตโนมัติ" lastActiveDate: "ใช้งานล่าสุดเมื่อ" statusbar: "แถบสถานะ" pleaseSelect: "ตัวเลือก" @@ -1000,6 +1016,7 @@ failedToUpload: "การอัปโหลดล้มเหลว" cannotUploadBecauseInappropriate: "ไม่สามารถอัปโหลดไฟล์นี้ได้เนื่องจากระบบตรวจพบบางส่วนของไฟล์ว่านี้อาจจะเป็น NSFW" cannotUploadBecauseNoFreeSpace: "ไม่สามารถอัปโหลดได้เนื่องจากไม่มีพื้นที่ว่างในไดรฟ์เหลือแล้ว" cannotUploadBecauseExceedsFileSizeLimit: "ไม่สามารถอัปโหลดไฟล์นี้ได้แล้วเนื่องจากเกินขีดจำกัดของขนาดไฟล์แล้ว" +cannotUploadBecauseUnallowedFileType: "ไม่สามารถอัปโหลดได้เนื่องจากเป็นชนิดไฟล์ที่ไม่ได้รับอนุญาต" beta: "เบต้า" enableAutoSensitive: "ทำเครื่องหมายว่ามีเนื้อหาที่ละเอียดอ่อนโดยอัตโนมัติ" enableAutoSensitiveDescription: "อนุญาตให้ตรวจหาและทำเครื่องหมายสื่อว่ามีเนื้อหาโดยละเอียดอ่อนโดยอัตโนมัติ ผ่าน Machine Learning หากเป็นไปได้ แม้ว่าคุณจะปิดคุณสมบัตินี้ ก็อาจถูกตั้งค่าโดยอัตโนมัติ ทั้งนี้ขึ้นอยู่กับเซิร์ฟเวอร์" @@ -1019,7 +1036,7 @@ windowMaximize: "ขยายใหญ่สุด" windowMinimize: "ย่อเล็กที่สุด" windowRestore: "เลิกทำ" caption: "คำอธิบาย" -loggedInAsBot: "ล็อกอินเป็นบอตอยู่ในขณะนี้" +loggedInAsBot: "เข้าสู่ระบบเป็นบอตอยู่ในขณะนี้" tools: "เครื่องมือ" cannotLoad: "ไม่สามารถโหลดได้" numberOfProfileView: "มุมมองโปรไฟล์" @@ -1051,6 +1068,7 @@ permissionDeniedError: "การดำเนินถูกปฏิเสธ" permissionDeniedErrorDescription: "บัญชีนี้ไม่มีสิทธิ์อนุญาตในการดำเนินการนี้" preset: "พรีเซ็ต" selectFromPresets: "เลือกจากการพรีเซ็ต" +custom: "แบบกำหนดเอง" achievements: "ความสำเร็จ" gotInvalidResponseError: "การตอบสนองเซิร์ฟเวอร์ไม่ถูกต้อง" gotInvalidResponseErrorDescription: "เซิร์ฟเวอร์อาจไม่สามารถเข้าถึงได้หรืออาจจะกำลังอยู่ในระหว่างปรับปรุง กรุณาลองใหม่อีกครั้งในภายหลังนะคะ" @@ -1068,7 +1086,7 @@ exploreOtherServers: "มองหาเซิร์ฟเวอร์อื่ letsLookAtTimeline: "มาดูไทม์ไลน์กัน" disableFederationConfirm: "ปิดใช้งานสหพันธ์เลยใช่ไหม?" disableFederationConfirmWarn: "โพสต์จะยังคงเป็นสาธารณะต่อไป เว้นแต่จะตั้งค่าเป็นอย่างอื่น" -disableFederationOk: "ปิดการใช้งาน" +disableFederationOk: "ปิดการใช้งานสหพันธ์" invitationRequiredToRegister: "เซิร์ฟเวอร์นี้เป็นแบบรับเชิญ เฉพาะผู้มีรหัสเชิญเท่านั้นถึงสามารถลงทะเบียนได้" emailNotSupported: "เซิร์ฟเวอร์นี้ไม่รองรับการส่งอีเมล" postToTheChannel: "โพสต์ลงช่อง" @@ -1089,6 +1107,7 @@ prohibitedWordsDescription2: "ถ้าแยกด้วยเว้นวร hiddenTags: "แฮชแท็กที่ซ่อนอยู่" hiddenTagsDescription: "เลือกแท็กที่จะไม่แสดงในรายการเทรนด์ สามารถลงทะเบียนหลายแท็กได้โดยขึ้นบรรทัดใหม่" notesSearchNotAvailable: "การค้นหาโน้ตไม่พร้อมใช้งาน" +usersSearchNotAvailable: "การค้นหาผู้ใช้ไม่พร้อมใช้งาน" license: "ใบอนุญาต" unfavoriteConfirm: "ลบออกจากรายการโปรดแน่ใจหรอ?" myClips: "คลิปของฉัน" @@ -1098,7 +1117,7 @@ retryAllQueuesConfirmTitle: "ลองใหม่ทั้งหมดจริ retryAllQueuesConfirmText: "สิ่งนี้จะเพิ่มการโหลดเซิร์ฟเวอร์ชั่วคราวนะ" enableChartsForRemoteUser: "สร้างแผนภูมิข้อมูลผู้ใช้ระยะไกล" enableChartsForFederatedInstances: "สร้างแผนภูมิของเซิร์ฟเวอร์ระยะไกล" -enableStatsForFederatedInstances: "ดึงข้อมูลสถิติจากเซิร์ฟเวอร์ที่อยู่ห่างไกล" +enableStatsForFederatedInstances: "ดึงข้อมูลจากเซิร์ฟเวอร์ระยะไกล" showClipButtonInNoteFooter: "เพิ่ม “คลิป” ไปยังเมนูสั่งการของโน้ต" reactionsDisplaySize: "ขนาดของรีแอคชั่น" limitWidthOfReaction: "จำกัดความกว้างสูงสุดของรีแอคชั่นและแสดงให้เล็กลง" @@ -1229,19 +1248,18 @@ impressumDescription: "การติดป้ายกำกับ (Impressum) privacyPolicy: "นโยบายความเป็นส่วนตัว" privacyPolicyUrl: "URL นโยบายความเป็นส่วนตัว" tosAndPrivacyPolicy: "เงื่อนไขในการให้บริการและนโยบายความเป็นส่วนตัว" -avatarDecorations: "การตกแต่งอวตาร" +avatarDecorations: "ของตกแต่งไอคอน" attach: "แนบ" detach: "นำออก" detachAll: "เอาออกทั้งหมด" angle: "แองเกิล" flip: "พลิก" -showAvatarDecorations: "แสดงตกแต่งอวตาร" +showAvatarDecorations: "แสดงของตกแต่งไอคอน" releaseToRefresh: "ปล่อยเพื่อรีเฟรช" refreshing: "กำลังรีเฟรช..." pullDownToRefresh: "ดึงลงเพื่อรีเฟรช" -disableStreamingTimeline: "ปิดใช้งานอัปเดตไทม์ไลน์แบบเรียลไทม์" useGroupedNotifications: "แสดงผลการแจ้งเตือนแบบกลุ่มแล้ว" -signupPendingError: "มีปัญหาในการตรวจสอบที่อยู่อีเมลลิงก์อาจหมดอายุแล้ว" +emailVerificationFailedError: "เกิดปัญหาในขณะตรวจสอบอีเมล อาจเป็นไปได้ว่าลิงก์หมดอายุแล้ว" cwNotationRequired: "หากเปิดใช้งาน “ซ่อนเนื้อหา” จะต้องระบุคำอธิบาย" doReaction: "เพิ่มรีแอคชั่น" code: "โค้ด" @@ -1292,46 +1310,238 @@ clipNoteLimitExceeded: "ไม่สามารถเพิ่มโน้ต performance: "ประสิทธิภาพ​" modified: "แก้ไข" discard: "ละทิ้ง" -thereAreNChanges: "มีอยู่ {n} เปลี่ยนแปลง(s)" +thereAreNChanges: "มีการเปลี่ยนแปลง {n} รายการ" signinWithPasskey: "ลงชื่อเข้าใช้ด้วย Passkey" -unknownWebAuthnKey: "พาสคีย์ไม่ถูกต้องค่ะ" -passkeyVerificationFailed: "การยืนยันกุญแจดิจิทัลไม่สำเร็จค่ะ" -passkeyVerificationSucceededButPasswordlessLoginDisabled: "การยืนยันพาสคีย์สำเร็จแล้ว แต่การลงชื่อเข้าใช้แบบไม่ต้องใส่รหัสผ่านถูกปิดใช้งานแล้ว" +unknownWebAuthnKey: "เป็น Passkey ที่ยังไม่ได้ลงทะเบียน" +passkeyVerificationFailed: "การยืนยัน Passkey ล้มเหลว" +passkeyVerificationSucceededButPasswordlessLoginDisabled: "การยืนยัน Passkey สำเร็จ แต่การเข้าสู่ระบบแบบไม่ใช้รหัสผ่านถูกปิดใช้งานอยู่" messageToFollower: "ข้อความถึงผู้ติดตาม" target: "เป้า" testCaptchaWarning: "ฟังก์ชันนี้มีไว้สำหรับทดสอบ CAPTCHA เท่านั้น\nห้ามนำไปใช้ในระบบจริงโดยเด็ดขาด" prohibitedWordsForNameOfUser: "คำนี้ไม่สามารถใช้เป็นชื่อผู้ใช้ได้" -prohibitedWordsForNameOfUserDescription: "หากมีสตริงใดๆ ในรายการนี้ปรากฏอยู่ในชื่อของผู้ใช้ ชื่อนั้นจะถูกปฏิเสธ ผู้ใช้ที่มีสิทธิ์แต่ผู้ดูแลระบบนั้นจะไม่ได้รับผลกระทบใดๆจากข้อจำกัดนี้ค่ะ" +prohibitedWordsForNameOfUserDescription: "จะไม่อนุญาตให้เปลี่ยนชื่อผู้ใช้หากชื่อของผู้ใช้มีข้อความที่อยู่ในรายการนี้ แต่ผู้ใช้ที่มีสิทธิ์เป็นผู้ควบคุมจะไม่ได้รับผลกระทบจากข้อจำกัดนี้" yourNameContainsProhibitedWords: "ชื่อของคุณนั้นมีคำที่ต้องห้าม" yourNameContainsProhibitedWordsDescription: "ถ้าหากคุณต้องการใช้ชื่อนี้ กรุณาติดต่อผู้ดูแลระบบของเซิร์ฟเวอร์นะค่ะ" -federationDisabled: "เซิร์ฟเวอร์นี้ปิดการใช้งานการรวมกลุ่ม คุณไม่สามารถโต้ตอบกับผู้ใช้บนเซิร์ฟเวอร์อื่นได้" -reactAreYouSure: "คุณต้องการที่จะตอบสนองต่อ \" {emoji}\" หรือไม่?" -markAsSensitiveConfirm: "คุณต้องการทำเครื่องหมายสื่อนี้ว่าละเอียดอ่อนหรือไม่?" -unmarkAsSensitiveConfirm: "คุณต้องการลบการกำหนดความไวของสื่อนี้หรือไม่?" +thisContentsAreMarkedAsSigninRequiredByAuthor: "ผู้โพสต์ได้ตั้งค่าว่าต้องเข้าสู่ระบบจึงจะสามารถดูได้" +lockdown: "ล็อกดาวน์" +pleaseSelectAccount: "โปรดเลือกบัญชี" +availableRoles: "บทบาทที่ใช้ได้" +acknowledgeNotesAndEnable: "เปิดใช้งานหลังจากที่เข้าใจข้อควรระวังแล้ว" +federationSpecified: "เซิร์ฟเวอร์นี้ดำเนินงานในระบบกลุ่มไวท์ลิสต์ ไม่สามารถติดต่อกับเซิร์ฟเวอร์อื่นที่ไม่ได้รับอนุญาตจากผู้ดูแลระบบได้" +federationDisabled: "เซิร์ฟเวอร์นี้ปิดใช้งานสหพันธ์ ไม่สามารถติดต่อหรือแลกเปลี่ยนข้อมูลกับผู้ใช้จากเซิร์ฟเวอร์อื่นได้" +draft: "ร่าง" +draftsAndScheduledNotes: "ร่างและกำหนดเวลาโพสต์" +confirmOnReact: "ยืนยันเมื่อทำการรีแอคชั่น" +reactAreYouSure: "ต้องการใส่รีแอคชั่นด้วย \"{emoji}\" หรือไม่?" +markAsSensitiveConfirm: "ต้องการตั้งค่าสื่อนี้ว่าเป็นเนื้อหาละเอียดอ่อนหรือไม่?" +unmarkAsSensitiveConfirm: "ต้องการยกเลิกการระบุว่าสื่อนี้มีเนื้อหาละเอียดอ่อนหรือไม่?" +preferences: "การตั้งค่าสภาพแวดล้อม" +accessibility: "การช่วยการเข้าถึง" +preferencesProfile: "โปรไฟล์การกำหนดค่า" +copyPreferenceId: "คัดลือก ID การตั้งค่า" +resetToDefaultValue: "คืนค่าเป็นค่าเริ่มต้น" +overrideByAccount: "เขียนทับด้วยบัญชี" +untitled: "ไม่มีชื่อ" +noName: "ไม่มีชื่อ" +skip: "ข้าม" +restore: "กู้คืน" +syncBetweenDevices: "ซิงค์ระหว่างอุปกรณ์" +preferenceSyncConflictTitle: "การตั้งค่ามีอยู่บนเซิร์ฟเวอร์" +preferenceSyncConflictText: "การตั้งค่าที่เปิดใช้งานการซิงค์จะบันทึกค่าลงในเซิร์ฟเวอร์ อย่างไรก็ดี พบว่ามีค่าการตั้งค่านี้ที่เคยบันทึกไว้ในเซิร์ฟเวอร์แล้ว ต้องการดำเนินการอย่างไร?" +preferenceSyncConflictChoiceMerge: "รวมเข้าด้วยกัน" +preferenceSyncConflictChoiceServer: "เขียนทับด้วยค่าการตั้งค่าเซิร์ฟเวอร์" +preferenceSyncConflictChoiceDevice: "เขียนทับด้วยค่าการตั้งค่าอุปกรณ์" +preferenceSyncConflictChoiceCancel: "ยกเลิกการเปิดใช้งานการซิงค์" +paste: "วาง" +emojiPalette: "จานสีเอโมจิ" postForm: "แบบฟอร์มการโพสต์" +textCount: "จำนวนอักขระ" information: "เกี่ยวกับ" +chat: "แชต" +directMessage: "แชตเลย" +directMessage_short: "ข้อความ" +migrateOldSettings: "ย้ายข้อมูลการตั้งค่าเก่า" +migrateOldSettings_description: "โดยปกติจะทำโดยอัตโนมัติ แต่หากด้วยเหตุผลบางประการที่ไม่สามารถย้ายได้สำเร็จ สามารถสั่งย้ายด้วยตนเองได้ การตั้งค่าปัจจุบันจะถูกเขียนทับ" +compress: "บีบอัด" right: "ขวา" bottom: "ภายใต้" +top: "บน" +embed: "ฝัง" +settingsMigrating: "กำลังย้ายการตั้งค่า กรุณารอสักครู่... (สามารถย้ายด้วยตนเองภายหลังได้ที่ การตั้งค่า → อื่นๆ → ย้ายข้อมูลการตั้งค่าเก่า)" +readonly: "อ่านได้อย่างเดียว" +goToDeck: "กลับไปยังเด็ค" +federationJobs: "งานสหพันธ์" +driveAboutTip: "ในไดรฟ์จะแสดงรายการไฟล์ที่เคยอัปโหลดไว้ก่อนหน้า
\nสามารถนำมาใช้ซ้ำเมื่อแนบไฟล์ในโน้ต หรือตั้งค่าให้อัปโหลดไฟล์ล่วงหน้าเพื่อนำไปโพสต์ทีหลังได้
\nโปรดระวัง เมื่อลบไฟล์ ไฟล์นั้นจะไม่แสดงในทุกที่ที่เคยใช้ไฟล์นี้ (โน้ต, หน้าเพจ, อวตาร, แบนเนอร์ ฯลฯ)
\nสามารถสร้างโฟลเดอร์เพื่อจัดระเบียบได้" +scrollToClose: "เลื่อนเพื่อปิด" +advice: "คำแนะนำ" +realtimeMode: "โหมดเรียลไทม์" +turnItOn: "เปิดใช้งาน" +turnItOff: "ปิดใช้งาน" +emojiMute: "ปิดเสียงเอโมจิ" +emojiUnmute: "เลิกปิดเสียงเอโมจิ" +muteX: "ปิดเสียง {x}" +unmuteX: "เลิกปิดเสียง {x}" +abort: "หยุดและยกเลิก" +tip: "คำแนะนำและเคล็ดลับ" +redisplayAllTips: "แสดงคำแนะนำและเคล็ดลับทั้งหมดอีกครั้ง" +hideAllTips: "ซ่อนคำแนะนำและเคล็ดลับทั้งหมด" +defaultImageCompressionLevel: "ค่าการบีบอัดภาพเริ่มต้น" +defaultImageCompressionLevel_description: "หากตั้งค่าต่ำ จะรักษาคุณภาพภาพได้ดีขึ้นแต่ขนาดไฟล์จะเพิ่มขึ้น
หากตั้งค่าสูง จะลดขนาดไฟล์ได้ แต่คุณภาพภาพจะลดลง" +defaultCompressionLevel: "ค่าการบีบอัดเริ่มต้น" +defaultCompressionLevel_description: "ถ้าต่ำ จะรักษาคุณภาพได้ แต่ขนาดไฟล์จะเพิ่มขึ้น
ถ้าสูง จะลดขนาดไฟล์ได้ แต่คุณภาพจะลดลง" +inMinutes: "นาที" +inDays: "วัน" +safeModeEnabled: "โหมดปลอดภัยถูกเปิดใช้งาน" +pluginsAreDisabledBecauseSafeMode: "เนื่องจากโหมดปลอดภัยถูกเปิดใช้งาน ปลั๊กอินทั้งหมดจึงถูกปิดใช้งาน" +customCssIsDisabledBecauseSafeMode: "เนื่องจากโหมดปลอดภัยถูกเปิดใช้งาน CSS แบบกำหนดเองจึงไม่ได้ถูกนำมาใช้" +themeIsDefaultBecauseSafeMode: "ในระหว่างที่โหมดปลอดภัยถูกเปิดใช้งาน จะใช้ธีมเริ่มต้น เมื่อปิดโหมดปลอดภัยจะกลับคืนดังเดิม" +thankYouForTestingBeta: "ขอบคุณที่ให้ความร่วมมือในการทดสอบเวอร์ชันเบต้า!" +createUserSpecifiedNote: "สร้างโน้ตแบบไดเร็กต์" +schedulePost: "กำหนดเวลาให้โพสต์" +scheduleToPostOnX: "กำหนดเวลาให้โพสต์ไว้ที่ {x}" +scheduledToPostOnX: "มีการกำหนดเวลาให้โพสต์ไว้ที่ {x}" +schedule: "กำหนดเวลา" +scheduled: "กำหนดเวลา" +widgets: "วิดเจ็ต" +_compression: + _quality: + high: "คุณภาพสูง" + medium: "คุณภาพปานกลาง" + low: "คุณภาพต่ำ" + _size: + large: "ขนาดใหญ่" + medium: "ขนาดปานกลาง" + small: "ขนาดเล็ก" +_order: + newest: "เรียงจากใหม่ไปเก่า" + oldest: "เรียงจากเก่าไปใหม่" _chat: + messages: "ข้อความ" + noMessagesYet: "ยังไม่มีข้อความ" + newMessage: "ข้อความใหม่" + individualChat: "แชตส่วนตัว" + individualChat_description: "สามารถแชตแบบตัวต่อตัวกับผู้ใช้ที่ระบุไว้ได้" + roomChat: "ห้องแชต" + roomChat_description: "สามารถแชตแบบกลุ่มหลายคนได้\nและสามารถแชตกับผู้ใช้ที่ไม่ได้อนุญาตแชตส่วนตัวได้ หากอีกฝ่ายยอมรับ" + createRoom: "สร้างห้อง" + inviteUserToChat: "เชิญผู้ใช้และเริ่มแชตได้เลย" + yourRooms: "ห้องที่สร้างไว้" + joiningRooms: "ห้องที่เข้าร่วมอยู่" invitations: "คำเชิญ" + noInvitations: "ไม่มีคำเชิญ" + history: "ประวัติ" noHistory: "ไม่มีประวัติ" + noRooms: "ไม่มีห้อง" + inviteUser: "เชิญผู้ใช้" + sentInvitations: "คำเชิญที่ส่งไปแล้ว" + join: "เข้าร่วม" + ignore: "ไม่สนใจ" + leave: "ออกจากห้อง" members: "สมาชิก" + searchMessages: "ค้นหาข้อความ" home: "หน้าหลัก" send: "ส่ง" + newline: "ขึ้นบรรทัดใหม่" + muteThisRoom: "ปิดเสียงห้องนี้" + deleteRoom: "ลบห้อง" + chatNotAvailableForThisAccountOrServer: "แชตไม่ได้เปิดใช้งานบนเซิร์ฟเวอร์นี้ หรือบัญชีนี้" + chatIsReadOnlyForThisAccountOrServer: "แชตบนเซิร์ฟเวอร์นี้ หรือบัญชีนี้ เป็นแบบอ่านอย่างเดียว ไม่สามารถส่งข้อความใหม่ สร้างหรือเข้าร่วมห้องแชตได้" + chatNotAvailableInOtherAccount: "บัญชีคู่สนทนาไม่สามารถใช้ฟังก์ชันแชตได้" + cannotChatWithTheUser: "ไม่สามารถเริ่มแชตกับผู้ใช้นี้ได้" + cannotChatWithTheUser_description: "แชตใช้งานไม่ได้ หรือคู่สนทนายังไม่ได้เปิดแชต" + youAreNotAMemberOfThisRoomButInvited: "คุณไม่ได้เป็นผู้เข้าร่วมห้องนี้ แต่มีคำเชิญส่งมา หากต้องการเข้าร่วม กรุณายืนยันคำเชิญ" + doYouAcceptInvitation: "ต้องการยอมรับคำเชิญหรือไม่?" + chatWithThisUser: "แชตเลย" + thisUserAllowsChatOnlyFromFollowers: "ผู้ใช้นี้รับแชตเฉพาะจากผู้ติดตามเท่านั้น" + thisUserAllowsChatOnlyFromFollowing: "ผู้ใช้นี้รับแชตเฉพาะจากผู้ที่เขาติดตามเท่านั้น" + thisUserAllowsChatOnlyFromMutualFollowing: "ผู้ใช้นี้รับแชตเฉพาะจากผู้ที่ติดตามซึ่งกันและกันทั้งสองฝ่ายเท่านั้น" + thisUserNotAllowedChatAnyone: "ผู้ใช้นี้ไม่รับแชตจากใครเลย" + chatAllowedUsers: "ผู้ที่อนุญาตให้แชตด้วย" + chatAllowedUsers_note: "ไม่ว่าจะตั้งค่ายังไง คุณยังสามารถแชตกับคนที่คุณส่งข้อความไปหาได้" + _chatAllowedUsers: + everyone: "ใครก็ได้หมด" + followers: "เฉพาะผู้ติดตามเท่านั้น" + following: "เฉพาะผู้ที่ตัวเองติดตามเท่านั้น" + mutual: "เฉพาะผู้ใช้ที่ติดตามซึ่งกันและกันทั้งสองฝ่ายเท่านั้น" + none: "ไม่อนุญาตให้ใครเลย" +_emojiPalette: + palettes: "จานสี" + enableSyncBetweenDevicesForPalettes: "เปิดใช้งานการซิงค์จานสีระหว่างอุปกรณ์" + paletteForMain: "จานสีหลักที่ใช้" + paletteForReaction: "จานสีที่ใช้ในการรีแอคชั่น" _settings: + driveBanner: "สามารถจัดการและตั้งค่าไดรฟ์ ตรวจสอบการใช้งาน และตั้งค่าการอัปโหลดไฟล์ได้" + pluginBanner: "สามารถขยายความสามารถของไคลเอนต์ด้วยปลั๊กอินได้ ติดตั้ง ตั้งค่า และจัดการปลั๊กอินแต่ละตัวได้" + notificationsBanner: "สามารถตั้งค่าประเภทและขอบเขตของการแจ้งเตือนที่รับจากเซิร์ฟเวอร์ รวมถึงการแจ้งเตือนแบบพุช" + api: "API" webhook: "Webhook" + serviceConnection: "การเชื่อมต่อกับบริการ" + serviceConnectionBanner: "สามารถจัดการและตั้งค่าโทเค็นการเข้าถึงและ Webhook เพื่อเชื่อมต่อกับแอปหรือบริการภายนอกได้" + accountData: "ข้อมูลบัญชี" + accountDataBanner: "สามารถจัดการข้อมูลบัญชีได้โดยส่งออกหรือนำเข้าไฟล์เก็บถาวร" + muteAndBlockBanner: "สามารถตั้งค่าการซ่อนเนื้อหา และจำกัดการกระทำจากผู้ใช้เฉพาะรายได้" + accessibilityBanner: "สามารถปรับแต่งรูปลักษณ์และพฤติกรรมของไคลเอนต์เพื่อให้เหมาะกับการใช้งานของตนเองมากขึ้น" + privacyBanner: "สามารถตั้งค่าความเป็นส่วนตัวของบัญชี เช่น ขอบเขตการเผยแพร่เนื้อหา ความสามารถในการค้นหา และการอนุมัติผู้ติดตาม" + securityBanner: "สามารถตั้งค่าความปลอดภัยของบัญชี เช่น รหัสผ่าน วิธีการเข้าสู่ระบบ แอปยืนยันตัวตน Passkey เป็นต้น" + preferencesBanner: "คุณสามารถกำหนดค่าพฤติกรรมโดยรวมของไคลเอนต์ได้ตามความต้องการของคุณ" + appearanceBanner: "สามารถตั้งค่ารูปลักษณ์และวิธีการแสดงผลของไคลเอนต์ตามความชอบได้" + soundsBanner: "สามารถตั้งค่าเสียงที่จะเล่นบนไคลเอนต์ได้" + timelineAndNote: "ไทม์ไลน์และโน้ต" + makeEveryTextElementsSelectable: "อนุญาตให้เลือกข้อความทั้งหมดได้" + makeEveryTextElementsSelectable_description: "หากเปิดใช้งาน อาจทำให้ความสะดวกในการใช้งานลดลงในบางสถานการณ์" + useStickyIcons: "ทำให้ไอคอนเคลื่อนตามการเลื่อน" + enableHighQualityImagePlaceholders: "แสดงภาพตัวแทนคุณภาพสูง" + uiAnimations: "ภาพเคลื่อนไหวของ UI" + showNavbarSubButtons: "แสดงปุ่มรองบนแถบนำทาง" + ifOn: "เมื่อเปิดใช้งาน" + ifOff: "เมื่อปิดใช้งาน" + enableSyncThemesBetweenDevices: "ซิงค์ธีมที่ติดตั้งระหว่างอุปกรณ์" + enablePullToRefresh: "ดึงเพื่ออัปเดต" + enablePullToRefresh_description: "สำหรับเมาส์ ให้กดปุ่มล้อกลางค้างไว้แล้วลาก" + realtimeMode_description: "เชื่อมต่อกับเซิร์ฟเวอร์และอัปเดตเนื้อหาแบบเรียลไทม์ อาจทำให้ใช้ปริมาณข้อมูลและแบตเตอรี่มากขึ้นได้" + contentsUpdateFrequency: "ความถี่ในการดึงข้อมูลเนื้อหา" + contentsUpdateFrequency_description: "ยิ่งตั้งค่าสูง เนื้อหาจะอัปเดตแบบเรียลไทม์มากขึ้น แต่ประสิทธิภาพอาจลดลง และการใช้ข้อมูลกับแบตเตอรี่จะเพิ่มมากขึ้น" + contentsUpdateFrequency_description2: "เมื่อโหมดเรียลไทม์เปิดอยู่ เนื้อหาจะอัปเดตแบบเรียลไทม์โดยไม่ขึ้นกับการตั้งค่านี้" + showUrlPreview: "แสดงตัวอย่าง URL" + showAvailableReactionsFirstInNote: "แสดงรีแอคชั่นที่ใช้ได้ไว้หน้าสุด" + showPageTabBarBottom: "แสดงแท็บบาร์ของเพจที่ด้านล่าง" + _chat: + showSenderName: "แสดงชื่อผู้ส่ง" + sendOnEnter: "กด Enter เพื่อส่ง" +_preferencesProfile: + profileName: "ชื่อโปรไฟล์" + profileNameDescription: "กรุณาตั้งชื่อเพื่อระบุอุปกรณ์นี้" + profileNameDescription2: "เช่น: “คอมเครื่องหลัก”, “มือถือ” ฯลฯ" + manageProfiles: "จัดการโปรไฟล์" +_preferencesBackup: + autoBackup: "สำรองโดยอัตโนมัติ" + restoreFromBackup: "คืนค่าจากข้อมูลสำรอง" + noBackupsFoundTitle: "ไม่พบข้อมูลสำรอง" + noBackupsFoundDescription: "ไม่พบข้อมูลสำรองที่สร้างโดยอัตโนมัติ แต่หากมีข้อมูลสำรองที่บันทึกด้วยตนเอง สามารถนำเข้ามาเพื่อกู้คืนได้" + selectBackupToRestore: "กรุณาเลือกข้อมูลสำรองที่ต้องการกู้คืน" + youNeedToNameYourProfileToEnableAutoBackup: "จำเป็นต้องตั้งชื่อโปรไฟล์ก่อนจึงจะเปิดใช้งานการสำรองข้อมูลอัตโนมัติได้" + autoPreferencesBackupIsNotEnabledForThisDevice: "ยังไม่ได้เปิดใช้งานการสำรองข้อมูลอัตโนมัติบนอุปกรณ์นี้" + backupFound: "พบข้อมูลสำรองของการตั้งค่าแล้ว" _accountSettings: requireSigninToViewContents: "ต้องเข้าสู่ระบบเพื่อดูเนื้อหา" - requireSigninToViewContentsDescription1: "ต้องเข้าสู่ระบบเพื่อดูบันทึกและเนื้อหาอื่น ๆ ทั้งหมดที่คุณสร้าง คาดว่าจะมีประสิทธิผลในการป้องกันไม่ให้ข้อมูลถูกเก็บรวบรวมโดยโปรแกรมรวบรวมข้อมูล" - requireSigninToViewContentsDescription2: "นอกจากนี้ จะไม่สามารถดูจากเซิร์ฟเวอร์ที่ไม่รองรับการดูตัวอย่าง URL (OGP), การฝังในหน้าเว็บ หรือการอ้างอิงหมายเหตุได้" - requireSigninToViewContentsDescription3: "เนื้อหาที่ถูกรวมเข้ากับเซิร์ฟเวอร์ระยะไกลอาจไม่อยู่ภายใต้ข้อจำกัดเหล่านี้" + requireSigninToViewContentsDescription1: "กำหนดให้ต้องเข้าสู่ระบบก่อนจึงจะสามารถดูโน้ตหรือเนื้อหาทั้งหมดที่สร้างไว้ได้ ซึ่งช่วยป้องกันไม่ให้ข้อมูลถูกเก็บโดยบอตหรือ Crawler (โปรแกรมรวบรวมข้อมูล)" + requireSigninToViewContentsDescription2: "จะไม่สามารถแสดงผลจากเซิร์ฟเวอร์ที่ไม่รองรับการแสดงตัวอย่าง URL (OGP), การฝังในหน้าเว็บ, หรือการอ้างอิงโน้ตได้" + requireSigninToViewContentsDescription3: "เนื้อหาที่ถูกรวมผ่านสหพันธ์จากเซิร์ฟเวอร์ระยะไกลอาจไม่อยู่ภายใต้ข้อจำกัดเหล่านี้" + makeNotesFollowersOnlyBefore: "แสดงโน้ตเก่าเฉพาะกับผู้ติดตามเท่านั้น" + makeNotesFollowersOnlyBeforeDescription: "ขณะที่เปิดฟังก์ชันนี้ โน้ตที่เก่ากว่าหรือเลยเวลาที่กำหนดจะแสดงเฉพาะกับผู้ติดตามเท่านั้น หากปิดใช้งาน สถานะการเปิดเผยจะกลับไปเป็นแบบเดิม" + makeNotesHiddenBefore: "ทำให้โน้ตเก่าทั้งหมดเป็นแบบส่วนตัว" + makeNotesHiddenBeforeDescription: "ขณะที่เปิดฟังก์ชันนี้ โน้ตที่เก่ากว่าหรือเลยเวลาที่กำหนดจะแสดงเฉพาะกับตนเอง (กลายเป็นแบบส่วนตัว) หากปิดใช้งาน สถานะการเปิดเผยจะกลับไปเป็นแบบเดิม" + mayNotEffectForFederatedNotes: "โน้ตที่ถูกรวมผ่านสหพันธ์จากเซิร์ฟเวอร์ระยะไกลอาจไม่ได้รับผลจากการตั้งค่านี้" + mayNotEffectSomeSituations: "ข้อจำกัดเหล่านี้เป็นเพียงการกรองเบื้องต้น ในบางกรณี เช่น การดูจากเซิร์ฟเวอร์อื่นหรือในระหว่างการตรวจสอบโดยผู้ดูแล อาจไม่สามารถใช้งานได้" + notesHavePassedSpecifiedPeriod: "โน้ตที่เลยเวลาที่กำหนดไว้แล้ว" + notesOlderThanSpecifiedDateAndTime: "โน้ตก่อนเวลาที่กำหนดไว้" _abuseUserReport: forward: "ส่ง​ต่อ" forwardDescription: "ส่งรายงานไปยังเซิร์ฟเวอร์ระยะไกลโดยใช้บัญชีระบบที่ไม่ระบุตัวตน" resolve: "แก้ไข" accept: "ยอมรับ" reject: "ปฏิเสธ" - resolveTutorial: "ถ้าหากรายงานนี้มีเนื้อหาถูกต้อง ให้เลือก \"ยอมรับ\" เพื่อปิดเคสกรณีนี้โดยถือว่าได้รับการแก้ไขแล้ว\nถ้าหากเนื้อหาในรายงานนี้นั้นไม่ถูกต้อง ให้เลือก \"ปฏิเสธ\" เพื่อปิดเคสกรณีนี้โดยถือว่าไม่ได้รับการแก้ไข" + resolveTutorial: "ให้เลือก “ยอมรับ” หากรายงานนี้มีเนื้อหาชอบธรรม เพื่อทำเครื่องหมายว่ากรณีนี้ได้รับการแก้ไขในทางบวก\nให้เลือก “ปฏิเสธ” หากรายงานนี้มีเนื้อหาไม่สมเหตุผล เพื่อทำเครื่องหมายว่ากรณีนี้ได้รับการแก้ไขในทางลบ" _delivery: status: "สถานะการจัดส่ง" stop: "ระงับการส่ง" @@ -1341,6 +1551,7 @@ _delivery: manuallySuspended: "หยุดชั่วคราวด้วยตนเอง" goneSuspended: "เซิร์ฟเวอร์ถูกระงับเนื่องจากมีการลบเซิร์ฟเวอร์นี้" autoSuspendedForNotResponding: "เซิร์ฟเวอร์ถูกระงับเนื่องจากไม่ตอบสนอง" + softwareSuspended: "หยุดให้บริการ เนื่องจากเป็นซอฟต์แวร์ที่ถูกระงับการเผยแพร่" _bubbleGame: howToPlay: "วิธีเล่น" hold: "ถือไว้" @@ -1455,7 +1666,7 @@ _timelineDescription: _serverRules: description: "ชุดของกฎที่จะแสดงก่อนการลงทะเบียนเราขอแนะนำให้ตั้งค่าสรุปข้อกำหนดในการให้บริการ" _serverSettings: - iconUrl: "URL ไอคอน" + iconUrl: "URL ของไอคอน" appIconDescription: "ระบุไอคอนที่จะใช้เมื่อ {host} แสดงเป็นแอป" appIconUsageExample: "ตัวอย่างเช่น เมื่อถูกเพิ่มเป็น PWA หรือบุ๊กมาร์กบนหน้าจอหลักในสมาร์ทโฟน" appIconStyleRecommendation: "เนื่องจากอาจถูกครอบตัดเป็นสี่เหลี่ยมหรือวงกลม จึงแนะนำให้ใช้ภาพที่เผื่อพื้นที่รอบๆ ตัวโลโก้ไอคอนไว้" @@ -1467,9 +1678,37 @@ _serverSettings: fanoutTimelineDbFallback: "ฟอลแบ๊กกลับฐานข้อมูล" fanoutTimelineDbFallbackDescription: "เมื่อเปิดใช้งาน หากไม่ได้แคชไทม์ไลน์ ไทม์ไลน์จะฟอลแบ๊กไปยังฐานข้อมูลสำหรับการ query เพิ่มเติม การปิดใช้งานจะช่วยลดภาระของเซิร์ฟเวอร์ด้วยการกำจัดกระบวนฟอลแบ๊ก แต่มันก็จะจำกัดช่วงเวลาไทม์ไลน์ที่สามารถดึงข้อมูลได้" reactionsBufferingDescription: "เมื่อเปิดใช้งานฟังก์ชันนี้ก็จะช่วยลด latency ในการสร้างปฏิกิริยา แต่อาจจะส่งผลให้ memory footprint ของ Redis เพิ่มขึ้นนะ" + remoteNotesCleaning: "การล้างข้อมูลโพสต์จากระยะไกลโดยอัตโนมัติ" + remoteNotesCleaning_description: "เมื่อเปิดใช้งาน จะทำการล้างโพสต์จากระยะไกลเก่าที่ไม่ถูกอ้างอิง เป็นระยะ เพื่อลดการขยายตัวของฐานข้อมูล" + remoteNotesCleaningMaxProcessingDuration: "ระยะเวลาสูงสุดของการประมวลผลการล้างข้อมูล" + remoteNotesCleaningExpiryDaysForEachNotes: "จำนวนวันที่ต้องเก็บโน้ตไว้อย่างน้อย" inquiryUrl: "URL สำหรับการติดต่อสอบถาม" inquiryUrlDescription: "ระบุ URL ของหน้าเว็บที่มีแบบฟอร์มสำหรับติดต่อผู้ดูแลเซิร์ฟเวอร์ หรือข้อมูลการติดต่อของผู้ดูแลเซิร์ฟเวอร์" - thisSettingWillAutomaticallyOffWhenModeratorsInactive: "ถ้าหากไม่มีการตรวจสอบจากผู้ดูแลระบบหรือไม่มีความเคลื่อนไหวมาเป็นระยะเวลาหนึ่ง ระบบจะทำการปิดใช้งานฟังก์ชันนี้โดยอัตโนมัติ เพื่อลดความเสี่ยงในการถูกโจมตีด้วยสแปมและอื่นๆ" + openRegistration: "เปิดให้สร้างบัญชีได้" + openRegistrationWarning: "การเปิดให้ลงทะเบียนมีความเสี่ยง แนะนำให้เปิดใช้งานเฉพาะในกรณีที่สามารถตรวจสอบเซิร์ฟเวอร์อย่างสม่ำเสมอและมีระบบรับมือกับปัญหาได้ทันท่วงที" + thisSettingWillAutomaticallyOffWhenModeratorsInactive: "หากไม่พบกิจกรรมของผู้ควบคุมในช่วงระยะเวลาหนึ่ง การตั้งค่านี้จะถูกปิดโดยอัตโนมัติเพื่อป้องกันสแปม" + deliverSuspendedSoftware: "ซอฟต์แวร์ที่หยุดการเผยแพร่" + deliverSuspendedSoftwareDescription: "เนื่องจากเหตุผลด้านช่องโหว่ เป็นต้น สามารถหยุดการแจกจ่ายโดยระบุชื่อซอฟต์แวร์ของเซิร์ฟเวอร์และช่วงของเวอร์ชันได้ ข้อมูลเวอร์ชันนี้เป็นข้อมูลที่เซิร์ฟเวอร์ให้มา จึงไม่สามารถรับประกันความน่าเชื่อถือได้ สามารถใช้การระบุช่วงเวอร์ชันแบบ semver ได้ แต่ถ้าระบุเป็น >= 2024.3.1 จะไม่รวมเวอร์ชันแบบกำหนดเอง เช่น 2024.3.1-custom.0 จึงแนะนำให้ระบุเป็น >= 2024.3.1-0 ซึ่งเป็นการระบุแบบ prerelease" + singleUserMode: "โหมดผู้ใช้คนเดียว" + singleUserMode_description: "หากมีเพียงตัวเองคนเดียวที่ใช้เซิร์ฟเวอร์นี้ การเปิดใช้งานโหมดนี้จะช่วยปรับการทำงานให้เหมาะสมที่สุด" + signToActivityPubGet: "ลงนามในคำขอ GET" + signToActivityPubGet_description: "โดยปกติควรเปิดใช้งาน แต่หากพบปัญหาเกี่ยวกับการสื่อสารในสหพันธ์ การปิดใช้งานอาจช่วยแก้ไขได้ แต่ในบางกรณี เซิร์ฟเวอร์อาจไม่สามารถสื่อสารได้เลยหากปิดใช้งานนี้" + proxyRemoteFiles: "พร็อกซีไฟล์ระยะไกล" + proxyRemoteFiles_description: "เมื่อเปิดใช้งาน จะทำหน้าที่เป็นพร็อกซีสำหรับไฟล์จากระยะไกล ช่วยในการสร้างภาพขนาดย่อและปกป้องความเป็นส่วนตัวของผู้ใช้" + allowExternalApRedirect: "อนุญาตการเปลี่ยนเส้นทางการสืบค้นผ่าน ActivityPub" + allowExternalApRedirect_description: "เมื่อเปิดใช้งาน จะอนุญาตให้เซิร์ฟเวอร์อื่นสืบค้นเนื้อหาของบุคคลที่สามผ่านเซิร์ฟเวอร์นี้ได้ แต่มีความเสี่ยงที่อาจเกิดการปลอมแปลงเนื้อหา" + userGeneratedContentsVisibilityForVisitor: "ขอบเขตการเปิดเผยเนื้อหาที่ผู้ใช้สร้างต่อบุคคลที่ไม่ได้เข้าร่วม (แขก)" + userGeneratedContentsVisibilityForVisitor_description: "ช่วยป้องกันปัญหาที่อาจเกิดขึ้นจากเนื้อหาระยะไกลที่ไม่เหมาะสม ซึ่งอาจถูกเผยแพร่ออกสู่อินเทอร์เน็ตโดยไม่ตั้งใจผ่านเซิร์ฟเวอร์ของตนเอง โดยเฉพาะในกรณีที่การดูแลควบคุมไม่ทั่วถึง" + userGeneratedContentsVisibilityForVisitor_description2: "การเปิดเผยเนื้อหาทั้งหมดในเซิร์ฟเวอร์รวมทั้งเนื้อหาที่รับมาจากระยะไกลสู่สาธารณะบนอินเทอร์เน็ตโดยไม่มีข้อจำกัดใดๆ มีความเสี่ยงโดยเฉพาะอย่างยิ่งสำหรับผู้ชมที่ไม่เข้าใจลักษณะของระบบแบบกระจาย อาจทำให้เกิดความเข้าใจผิดคิดว่าเนื้อหาที่มาจากระยะไกลนั้นเป็นเนื้อหาที่สร้างขึ้นภายในเซิร์ฟเวอร์นี้ จึงควรใช้ความระมัดระวังอย่างมาก" + restartServerSetupWizardConfirm_title: "ต้องการเริ่มวิซาร์ดการตั้งค่าเซิร์ฟเวอร์ใหม่หรือไม่?" + restartServerSetupWizardConfirm_text: "การตั้งค่าบางส่วนในปัจจุบันจะถูกรีเซ็ต" + entrancePageStyle: "สไตล์ของหน้าเพจทางเข้า" + showTimelineForVisitor: "แสดงไทม์ไลน์" + showActivitiesForVisitor: "แสดงกิจกรรม" + _userGeneratedContentsVisibilityForVisitor: + all: "ทั้งหมดสาธารณะ" + localOnly: "เผยแพร่เป็นสาธารณะเฉพาะเนื้อหาท้องถิ่น เนื้อหาระยะไกลให้เป็นส่วนตัว" + none: "ทั้งหมดส่วนตัว" _accountMigration: moveFrom: "ย้ายจากบัญชีอื่นมาที่บัญชีนี้" moveFromSub: "สร้างนามแฝงไปยังบัญชีอื่น" @@ -1762,13 +2001,15 @@ _role: baseRole: "แม่แบบบทบาท" useBaseValue: "ใช้ตามแม่แบบบทบาท" chooseRoleToAssign: "เลือกบทบาทที่ต้องการกำหนด" - iconUrl: "URL ไอคอน" + iconUrl: "URL ของไอคอน" asBadge: "แสดงเป็นตรา" - descriptionOfAsBadge: "เมื่อเปิดใช้งาน ไอคอนบทบาทจะปรากฏถัดจากชื่อผู้ใช้" + descriptionOfAsBadge: "หากเปิดใช้งาน จะมีไอคอนของบทบาท แสดงถัดจากชื่อผู้ใช้" isExplorable: "ค้นหาผู้ใช้ได้ง่ายขึ้นโดยดูจากบทบาท" descriptionOfIsExplorable: "เมื่อเปิดใช้งาน ไทมไลน์บทบาทนี้และสมาชิกที่มีบทบาทนี้จะเปิดเผยเป็นสาธารณะ" displayOrder: "ลำดับการแสดงผล" descriptionOfDisplayOrder: "เลขที่สูงกว่าจะแสดงบน UI ก่อน" + preserveAssignmentOnMoveAccount: "โอนสถานะการมอบหมายไปยังบัญชีที่ย้ายไป" + preserveAssignmentOnMoveAccount_description: "เมื่อเปิดใช้งาน บัญชีที่ได้รับบทบาทนี้เมื่อถูกย้ายไปบัญชีใหม่ บทบาทนี้จะถูกถ่ายทอดไปยังบัญชีปลายทางด้วย" canEditMembersByModerator: "อนุญาตให้ผู้ควบคุมแก้ไขสมาชิก" descriptionOfCanEditMembersByModerator: "เมื่อเปิดใช้ นอกเหนือจากผู้ควบคุมและผู้ดูแลระบบแล้ว จะสามารถเพิ่มถอนบทบาทนี้แก่ผู้ใช้ได้ แต่เมื่อปิดใช้ จะมีเฉพาะผู้ดูแลระบบเท่านั้นที่จะสามารถดำเนินการได้" priority: "ลำดับความสำคัญ" @@ -1789,8 +2030,9 @@ _role: canManageCustomEmojis: "จัดการเอโมจิที่กำหนดเอง" canManageAvatarDecorations: "จัดการตกแต่งอวตาร" driveCapacity: "ความจุของไดรฟ์" + maxFileSize: "ขนาดไฟล์สูงสุดที่สามารถอัปโหลดได้" alwaysMarkNsfw: "ทำเครื่องหมายไฟล์ว่าเป็น NSFW เสมอ" - canUpdateBioMedia: "อนุญาตให้ปรับปรุงไอคอนและแบนเนอร์" + canUpdateBioMedia: "อนุญาตให้เปลี่ยนไอคอนประจำตัวและแบนเนอร์" pinMax: "จํานวนสูงสุดของโน้ตที่ปักหมุดไว้" antennaMax: "จำนวนสูงสุดของเสาอากาศ" wordMuteMax: "จำนวนอักขระสูงสุดที่อนุญาตในการปิดเสียงคำ" @@ -1803,13 +2045,21 @@ _role: descriptionOfRateLimitFactor: "ยิ่งตัวเลขน้อยก็ยิ่งจำกัดน้อย ยิ่งมากก็ยิ่งเข้มงวดมากขึ้น" canHideAds: "ซ่อนโฆษณา" canSearchNotes: "การใช้การค้นหาโน้ต" + canSearchUsers: "ค้นหาผู้ใช้" canUseTranslator: "การใช้งานแปล" - avatarDecorationLimit: "จำนวนการตกแต่งไอคอนสูงสุดที่สามารถติดตั้งได้" + avatarDecorationLimit: "จำนวนของตกแต่งไอคอนสูงสุดที่สามารถติดตั้งได้" canImportAntennas: "อนุญาตให้นำเข้าเสาอากาศ" canImportBlocking: "อนุญาตให้นำเข้าการบล็อก" canImportFollowing: "อนุญาตให้นำเข้ารายการต่อไปนี้" - canImportMuting: "อนุญาตให้นำเข้าการปิดกั้น" + canImportMuting: "อนุญาตให้นำเข้าการปิดเสียง" canImportUserLists: "อนุญาตให้นำเข้ารายการ" + chatAvailability: "อนุญาตให้แชต" + uploadableFileTypes: "ประเภทไฟล์ที่สามารถอัปโหลดได้" + uploadableFileTypes_caption: "สามารถระบุ MIME type ได้ โดยใช้การขึ้นบรรทัดใหม่เพื่อแยกหลายรายการ และสามารถใช้ดอกจัน (*) เพื่อระบุแบบไวลด์การ์ดได้ (เช่น: image/*)" + uploadableFileTypes_caption2: "ไฟล์บางประเภทอาจไม่สามารถระบุชนิดได้ หากต้องการอนุญาตไฟล์ลักษณะนั้น กรุณาเพิ่ม {x} ลงในรายการที่อนุญาต" + noteDraftLimit: "จำนวนโน้ตฉบับร่างที่สามารถสร้างได้บนฝั่งเซิร์ฟเวอร์" + scheduledNoteLimit: "จำนวนโพสต์กำหนดเวลาที่สร้างพร้อมกันได้" + watermarkAvailable: "มีฟังก์ชั่นลายน้ำให้เลือกใช้" _condition: roleAssignedTo: "มอบหมายให้มีบทบาทแบบทำมือ" isLocal: "ผู้ใช้ท้องถิ่น" @@ -2035,10 +2285,12 @@ _theme: install: "ติดตั้งธีม" manage: "จัดการธีม" code: "โค้ดธีม" - description: "รายละเอียด" + copyThemeCode: "คัดลอกรหัสธีม" + description: "คำอธิบาย" installed: "{name} ได้รับการติดตั้ง" installedThemes: "ธีมที่ติดตั้ง" builtinThemes: "ธีมในตัว" + instanceTheme: "ธีมของเซิร์ฟเวอร์" alreadyInstalled: "ธีมนี้ได้รับการติดตั้งแล้ว" invalid: "รูปแบบของธีมนี้ไม่ถูกต้องนะ" make: "ทำธีม" @@ -2066,7 +2318,7 @@ _theme: fg: "ข้อความ" focus: "โฟกัส" indicator: "ตัวบ่งชี้" - panel: "แผงควบคุม" + panel: "แผง" shadow: "เงา" header: "ส่วนหัว" navBg: "พื้นหลังแถบด้านข้าง" @@ -2076,7 +2328,7 @@ _theme: link: "ลิงก์" hashtag: "แฮชแท็ก" mention: "กล่าวถึง" - mentionMe: "ได้กล่าวถึง (ฉัน)" + mentionMe: "ได้กล่าวถึงคุณ" renote: "รีโน้ต" modalBg: "พื้นหลังโมดอล" divider: "ตัวแบ่ง" @@ -2092,7 +2344,6 @@ _theme: buttonBg: "ปุ่มพื้นหลัง" buttonHoverBg: "ปุ่มพื้นหลัง (โฮเวอร์)" inputBorder: "เส้นขอบของช่องป้อนข้อมูล" - driveFolderBg: "พื้นหลังโฟลเดอร์ไดรฟ์" badge: "ตรา" messageBg: "พื้นหลังแชท" fgHighlighted: "ข้อความที่ไฮไลต์" @@ -2101,6 +2352,7 @@ _sfx: noteMy: "โน้ตของตัวเอง" notification: "การเเจ้งเตือน" reaction: "เมื่อเลือกรีแอคชั่น" + chatMessage: "ข้อความของแชต" _soundSettings: driveFile: "ใช้เสียงจากไดรฟ์" driveFileWarn: "เลือกไฟล์ในไดรฟ์ของคุณ" @@ -2133,6 +2385,7 @@ _time: minute: "นาที" hour: "ชั่วโมง" day: "วัน" + month: "เดือน" _2fa: alreadyRegistered: "คุณได้ลงทะเบียนอุปกรณ์ยืนยันตัวตนแบบ 2 ชั้นแล้ว" registerTOTP: "ลงทะเบียนแอพตัวตรวจสอบสิทธิ์" @@ -2143,15 +2396,15 @@ _2fa: step3: "ป้อนโทเค็นที่แอปของคุณให้มาเพื่อเสร็จสิ้นการตั้งค่า" setupCompleted: "ตั้งค่าสำเร็จแล้ว" step4: "นับจากนี้เป็นต้นไปการพยายามเข้าสู่ระบบในอนาคตนั้น อาจจะต้องขอโทเค็นในการเข้าสู่ระบบดังกล่าว" - securityKeyNotSupported: "เบราว์เซอร์ของคุณไม่รองรับคีย์ความปลอดภัยนะ" - registerTOTPBeforeKey: "กรุณาตั้งค่าแอปยืนยันตัวตนเพื่อลงทะเบียนรหัสความปลอดภัยหรือรหัสผ่าน" - securityKeyInfo: "นอกจากนี้การตรวจสอบความถูกต้องด้วยลายนิ้วมือหรือ PIN แล้ว คุณยังสามารถตั้งค่าการตรวจสอบสิทธิ์ผ่านคีย์ความปลอดภัยของฮาร์ดแวร์ที่รองรับ FIDO2 เพื่อเพิ่มความปลอดภัยให้กับบัญชีของคุณ" - registerSecurityKey: "ลงทะเบียนรหัสความปลอดภัยหรือรหัสผ่าน" + securityKeyNotSupported: "เว็บเบราว์เซอร์ที่ใช้งานอยู่ไม่รองรับ Security Key" + registerTOTPBeforeKey: "ก่อนลงทะเบียน Security Key หรือ Passkey กรุณาตั้งค่าแอปยืนยันตัวตนก่อน" + securityKeyInfo: "ลงทะเบียนกุญแจที่มาจาก WebAuthn เช่น Security Key แบบฮาร์ดแวร์ที่รองรับ FIDO2 การยืนยันตัวตนด้วยชีวมิติหรือ PIN บนอุปกรณ์ และ Passkey" + registerSecurityKey: "ลงทะเบียน Security Key หรือ Passkey" securityKeyName: "ป้อนชื่อคีย์" - tapSecurityKey: "กรุณาทำตามเบราว์เซอร์ของคุณเพื่อลงทะเบียนรหัสความปลอดภัยหรือรหัสผ่าน" - removeKey: "ลบคีย์ความปลอดภัยออก" + tapSecurityKey: "กรุณาทำตามคำแนะนำของเบราว์เซอร์เพื่อลงทะเบียน Security Key หรือ Passkey" + removeKey: "ลบ Security Key ออก" removeKeyConfirm: "ลบข้อมูลสำรอง {name} มั้ย?" - whyTOTPOnlyRenew: "ไม่สามารถลบแอปตัวรับรองความถูกต้องได้ตราบใดที่มีการลงทะเบียนคีย์ความปลอดภัยไว้แล้ว" + whyTOTPOnlyRenew: "ไม่สามารถลบแอปตัวรับรองความถูกต้องได้ตราบใดที่ยังมีการลงทะเบียน Security Key อยู่" renewTOTP: "ตั้งค่าแอปยืนยันตัวตน" renewTOTPConfirm: "วิธีการแบบนี้จะทําให้รหัสยืนยันจากแอพก่อนหน้าของคุณหยุดทํางานเลยนะ" renewTOTPOk: "ตั้งค่าคอนฟิกใหม่" @@ -2248,6 +2501,7 @@ _permissions: "read:federation": "รับข้อมูลเกี่ยวกับสหพันธ์" "write:report-abuse": "รายงานการละเมิด" "write:chat": "เขียนหรือลบข้อความแชท" + "read:chat": "อ่านแชต" _auth: shareAccessTitle: "การให้สิทธิ์แอปพลิเคชัน" shareAccess: "คุณต้องการอนุญาตให้ \"{name}\" เข้าถึงบัญชีนี้เลยมั้ย?" @@ -2256,8 +2510,11 @@ _auth: permissionAsk: "แอปพลิเคชันนี้ขอสิทธิ์ดังต่อไปนี้" pleaseGoBack: "กรุณากลับไปที่แอปพลิเคชัน" callback: "กำลังกลับไปที่แอปพลิเคชัน" + accepted: "การเข้าถึงได้รับอนุญาต" denied: "ปฏิเสธการเข้าใช้" + scopeUser: "กำลังดำเนินการในฐานะผู้ใช้ต่อไปนี้" pleaseLogin: "กรุณาเข้าสู่ระบบเพื่ออนุมัติแอปพลิเคชัน" + byClickingYouWillBeRedirectedToThisUrl: "หากอนุญาตการเข้าถึง ระบบจะเปลี่ยนเส้นทางไปยัง URL ด้านล่างโดยอัตโนมัติ" _antennaSources: all: "โน้ตทั้งหมด" homeTimeline: "โน้ตจากผู้ใช้ที่ติดตาม" @@ -2304,6 +2561,7 @@ _widgets: chooseList: "เลือกรายชื่อ" clicker: "คลิกเกอร์" birthdayFollowings: "วันเกิดผู้ใช้ในวันนี้" + chat: "แชตเลย" _cw: hide: "ซ่อน" show: "โหลดเพิ่มเติม" @@ -2343,6 +2601,8 @@ _visibility: disableFederation: "การปิดใช้งานสหพันธ์" disableFederationDescription: "อย่าส่งข้อมูลไปยังเซิร์ฟเวอร์อื่น" _postForm: + quitInspiteOfThereAreUnuploadedFilesConfirm: "มีไฟล์ที่ยังไม่ได้อัปโหลด ต้องการละทิ้งและปิดฟอร์มหรือไม่?" + uploaderTip: "ไฟล์ยังไม่ได้อัปโหลด สามารถตั้งค่าต่างๆ ได้จากเมนูของไฟล์ เช่น การเปลี่ยนชื่อ การครอปรูป การใส่ลายน้ำ และการบีบอัด ไฟล์จะถูกอัปโหลดโดยอัตโนมัติเมื่อโพสต์โน้ต" replyPlaceholder: "ตอบกลับโน้ตนี้..." quotePlaceholder: "อ้างโน้ตนี้..." channelPlaceholder: "โพสต์ลงช่อง..." @@ -2363,7 +2623,7 @@ _profile: metadataDescription: "ใช้สิ่งเหล่านี้ คุณสามารถแสดงฟิลด์ข้อมูลเพิ่มเติมในโปรไฟล์ของคุณ" metadataLabel: "ป้ายชื่อ" metadataContent: "เนื้อหา" - changeAvatar: "เปลี่ยนอวาตาร์" + changeAvatar: "เปลี่ยนไอคอนประจำตัว" changeBanner: "เปลี่ยนแบนเนอร์" verifiedLinkDescription: "หากป้อน URL ที่มีลิงก์ไปยังโปรไฟล์ของคุณ ไอคอนการยืนยันความเป็นเจ้าของจะแสดงถัดจากฟิลด์นั้น ๆ" avatarDecorationMax: "คุณสามารถเพิ่มการตกแต่งได้สูงสุด {max}" @@ -2376,7 +2636,7 @@ _exportOrImport: clips: "คลิป" followingList: "กำลังติดตาม" muteList: "ปิดเสียง" - blockingList: "บล็อค" + blockingList: "บล็อก" userLists: "รายชื่อ" excludeMutingUsers: "ยกเว้นผู้ใช้ที่ปิดเสียง" excludeInactiveUsers: "ยกเว้นผู้ใช้ที่ไม่ได้ใช้งาน" @@ -2446,7 +2706,7 @@ _pages: featured: "เป็นที่นิยม" inspector: "ตัวตรวจสอบ" contents: "เนื้อหา" - content: "บล็อคหน้าเพจ" + content: "บล็อกหน้าเพจ" variables: "ตัวแปร" title: "หัวข้อ" url: "URL ของหน้า" @@ -2458,7 +2718,7 @@ _pages: fontSansSerif: "Sans Serif" eyeCatchingImageSet: "ตั้งค่าภาพขนาดย่อ" eyeCatchingImageRemove: "ลบภาพขนาดย่อ" - chooseBlock: "เพิ่มบล็อค" + chooseBlock: "เพิ่มบล็อก" enterSectionTitle: "ป้อนชื่อหัวข้อ" selectType: "เลือกชนิด" contentBlocks: "เนื้อหา" @@ -2492,9 +2752,12 @@ _notification: yourFollowRequestAccepted: "คำขอติดตามได้รับการอนุมัติแล้ว" youWereInvitedToGroup: "{userName} ได้เชิญคุณเข้ากลุ่ม" pollEnded: "ผลโพลออกมาแล้ว" + scheduledNotePosted: "โน้ตที่กำหนดเวลาไว้ได้ถูกโพสต์แล้ว" + scheduledNotePostFailed: "ล้มเหลวในการโพสต์โน้ตที่กำหนดเวลาไว้" newNote: "โพสต์ใหม่" unreadAntennaNote: "เสาอากาศ {name}" roleAssigned: "ได้รับบทบาท" + chatRoomInvitationReceived: "ได้รับคำเชิญเข้าร่วมห้องแชต" emptyPushNotificationMessage: "อัปเดตการแจ้งเตือนแบบพุชแล้ว" achievementEarned: "รับความสำเร็จ" testNotification: "ทดสอบการแจ้งเตือน" @@ -2507,7 +2770,9 @@ _notification: followedBySomeUsers: "มีผู้ติดตาม {n} ราย" flushNotification: "ล้างประวัติการแจ้งเตือน" exportOfXCompleted: "การดำเนินการส่งออก {x} ได้เสร็จสิ้นลงแล้ว" - login: "มีคนล็อกอิน" + login: "มีการเข้าสู่ระบบ" + createToken: "สร้างโทเค็นการเข้าถึงแล้ว" + createTokenDescription: "หากไม่ทราบสาเหตุของคำเชิญ กรุณาลบโทเค็นการเข้าถึงผ่านทาง “{text}”" _types: all: "ทั้งหมด" note: "โน้ตใหม่" @@ -2522,9 +2787,11 @@ _notification: followRequestAccepted: "อนุมัติให้ติดตามแล้ว" groupInvited: "ได้รับคำเชิญเข้ากลุ่ม" roleAssigned: "ให้บทบาท" + chatRoomInvitationReceived: "เชิญเข้าห้องแชต" achievementEarned: "ปลดล็อกความสำเร็จแล้ว" exportCompleted: "กระบวนการส่งออกข้อมูลได้เสร็จสิ้นสมบูรณ์แล้ว" login: "เข้าสู่ระบบ" + createToken: "สร้างโทเค็นการเข้าถึง" test: "ทดสอบระบบแจ้งเตือน" app: "การแจ้งเตือนจากแอปที่มีลิงก์" _actions: @@ -2534,6 +2801,9 @@ _notification: _deck: alwaysShowMainColumn: "แสดงคอลัมน์หลักเสมอ" columnAlign: "จัดแนวคอลัมน์" + columnGap: "ช่องห่างระว่างคอลัมน์" + deckMenuPosition: "ตำแหน่งเมนูเด็ค" + navbarPosition: "ตำแหน่งของแถบนำทาง" addColumn: "เพิ่มคอลัมน์" newNoteNotificationSettings: "ตั้งค่าการแจ้งเตือนเมื่อมีโน้ตใหม่" configureColumn: "ตั้งค่าคอลัมน์" @@ -2552,6 +2822,7 @@ _deck: useSimpleUiForNonRootPages: "แสดง UI ของ Root Page อย่างง่าย " usedAsMinWidthWhenFlexible: "ความกว้างขั้นต่ำนั้นจะถูกใช้งานสำหรับสิ่งนี้เมื่อเปิดใช้งานตัวเลือก \"ปรับความกว้างอัตโนมัติ\" หากเลือกเปิดใช้งานแล้ว" flexible: "ปรับความกว้างอัตโนมัติ" + enableSyncBetweenDevicesForProfiles: "เปิดใช้งานการซิงค์ข้อมูลโปรไฟล์ระหว่างอุปกรณ์" _columns: main: "หลัก" widgets: "วิดเจ็ต" @@ -2563,6 +2834,7 @@ _deck: mentions: "กล่าวถึงคุณ" direct: "ไดเร็กต์" roleTimeline: "บทบาทไทม์ไลน์" + chat: "แชตเลย" _dialog: charactersExceeded: "คุณกำลังมีตัวอักขระเกินขีดจำกัดสูงสุดแล้วนะ! ปัจจุบันอยู่ที่ {current} จาก {max}" charactersBelow: "คุณกำลังใช้อักขระต่ำกว่าขีดจำกัดขั้นต่ำเลยนะ! ปัจจุบันอยู่ที่ {current} จาก {min}" @@ -2591,8 +2863,8 @@ _webhookSettings: abuseReport: "เมื่อมีการรายงานจากผู้ใช้" abuseReportResolved: "เมื่อมีการจัดการกับการรายงานจากผู้ใช้" userCreated: "เมื่อผู้ใช้ถูกสร้างขึ้น" - inactiveModeratorsWarning: "เมื่อผู้ดูแลระบบไม่ได้ใช้งานมานานระยะหนึ่ง" - inactiveModeratorsInvitationOnlyChanged: "เมื่อผู้ดูแลระบบที่ไม่ได้ใช้งานมานาน และเซิร์ฟเวอร์เปลี่ยนเป็นแบบเชิญเข้าร่วมเท่านั้น" + inactiveModeratorsWarning: "เมื่อผู้ควบคุมไม่มีความเคลื่อนไหวในช่วงระยะเวลาหนึ่ง" + inactiveModeratorsInvitationOnlyChanged: "เมื่อผู้ควบคุมไม่มีความเคลื่อนไหวในช่วงระยะเวลาหนึ่ง ระบบจะเปลี่ยนเป็นแบบใช้คำเชิญโดยอัตโนมัติ" deleteConfirm: "ต้องการลบ Webhook ใช่ไหม?" testRemarks: "คลิกปุ่มทางด้านขวาของสวิตช์เพื่อส่ง Webhook ทดสอบที่มีข้อมูลจำลอง" _abuseReport: @@ -2644,10 +2916,10 @@ _moderationLogTypes: createAd: "สร้างโฆษณาแล้ว" deleteAd: "ลบโฆษณาออกแล้ว" updateAd: "อัปเดตโฆษณาแล้ว" - createAvatarDecoration: "สร้างการตกแต่งไอคอนแล้ว" - updateAvatarDecoration: "อัปเดตการตกแต่งไอคอนแล้ว" - deleteAvatarDecoration: "ลบการตกแต่งไอคอนแล้ว" - unsetUserAvatar: "ลบไอคอนผู้ใช้" + createAvatarDecoration: "สร้างของตกแต่งไอคอนแล้ว" + updateAvatarDecoration: "อัปเดตของตกแต่งไอคอนแล้ว" + deleteAvatarDecoration: "ลบของตกแต่งไอคอนแล้ว" + unsetUserAvatar: "เลิกตั้งไอคอนประจำตัวแล้ว" unsetUserBanner: "ลบแบนเนอร์ผู้ใช้" createSystemWebhook: "สร้าง SystemWebhook" updateSystemWebhook: "อัปเดต SystemWebhook" @@ -2659,6 +2931,8 @@ _moderationLogTypes: deletePage: "เพจถูกลบออกไปแล้ว" deleteFlash: "Play ถูกลบออกไปแล้ว" deleteGalleryPost: "โพสต์แกลเลอรี่ถูกลบออกแล้ว" + deleteChatRoom: "ลบห้องแชต" + updateProxyAccountDescription: "อัปเดตคำอธิบายของบัญชีพร็อกซี" _fileViewer: title: "รายละเอียดไฟล์" type: "ประเภทไฟล์" @@ -2666,6 +2940,7 @@ _fileViewer: url: "URL" uploadedAt: "วันที่เข้าร่วม" attachedNotes: "โน้ตที่แนบมาด้วย" + usage: "ใช้แล้ว" thisPageCanBeSeenFromTheAuthor: "หน้าเพจนี้จะสามารถปรากฏได้โดยผู้ใช้ที่อัปโหลดไฟล์นี้เท่านั้น" _externalResourceInstaller: title: "ติดตั้งจากไซต์ภายนอก" @@ -2711,11 +2986,14 @@ _dataSaver: title: "โหลดสื่อ" description: "กันไม่ให้ภาพและวิดีโอโหลดโดยอัตโนมัติ แตะรูปภาพ/วิดีโอที่ซ่อนอยู่เพื่อโหลด" _avatar: - title: "รูปไอคอน" - description: "ระงับการเคลื่อนไหวของภาพไอคอน ภาพเคลื่อนไหวอาจมีขนาดไฟล์ใหญ่กว่าภาพปกติ ดังนั้นจึงสามารถช่วยในการลดการใช้ข้อมูล" - _urlPreview: - title: "ธัมบ์เนลแสดงตัวอย่าง URL" - description: "ธัมบ์เนลแสดงตัวอย่าง URL จะไม่โหลดโดยอัตโนมัติ" + title: "ปิดใช้งานภาพเคลื่อนไหวของไอคอนประจำตัว" + description: "ภาพเคลื่อนไหวของไอคอนประจำตัวจะหยุดทำงาน ภาพแบบเคลื่อนไหวมักมีขนาดไฟล์ใหญ่กว่าภาพปกติ จึงช่วยลดปริมาณการใช้ข้อมูลได้มากขึ้น" + _urlPreviewThumbnail: + title: "ซ่อนภาพขนาดย่อของการแสดงตัวอย่าง URL" + description: "ภาพขนาดย่อของการตัวอย่าง URL จะไม่ถูกโหลดอีกต่อไป" + _disableUrlPreview: + title: "ปิดการใช้งานแสดงตัวอย่าง URL" + description: "ปิดฟังก์ชันแสดงตัวอย่าง URL แตกต่างจากการซ่อนเพียงภาพขนาดย่อ ฟังก์ชันนี้จะช่วยลดการโหลดข้อมูลจากลิงก์ปลายทางทั้งหมด" _code: title: "ไฮไลต์โค้ด" description: "หากใช้สัญลักษณ์ไฮไลต์โค้ดใน MFC ฯลฯ สัญลักษณ์เหล่านั้นจะไม่โหลดจนกว่าจะแตะ การไฮไลต์ไวยากรณ์(syntax)จำเป็นต้องดาวน์โหลดไฟล์คำจำกัดความของไฮไลต์สำหรับแต่ละภาษา ดังนั้นการปิดใช้งานการโหลดไฟล์เหล่านี้โดยอัตโนมัติจึงคาดว่าจะช่วยลดปริมาณข้อมูลการสื่อสารได้" @@ -2766,13 +3044,15 @@ _reversi: allowIrregularRules: "อนุญาตกฎที่ไม่ปรกติ (โหมดฟรีทุกอย่าง)" disallowIrregularRules: "ไม่อนุญาตกฎที่ไม่ปรกติ" showBoardLabels: "แสดงหมายเลขแถว/คอลัมน์บนกระดาน" - useAvatarAsStone: "ใช้รูปอวตารเป็นหมาก" + useAvatarAsStone: "ใช้ไอคอนประจำตัวเป็นหมาก" _offlineScreen: title: "ออฟไลน์ - ไม่สามารถเชื่อมต่อกับเซิร์ฟเวอร์ได้" header: "ไม่สามารถเชื่อมต่อกับเซิร์ฟเวอร์ได้" _urlPreviewSetting: title: "การตั้งค่าการแสดงตัวอย่าง URL" enable: "เปิดใช้งานการแสดงตัวอย่าง URL" + allowRedirect: "อนุญาตการเปลี่ยนเส้นทางไปยังปลายทางของการแสดงตัวอย่าง" + allowRedirectDescription: "ตั้งค่าว่าจะติดตามลิงก์ที่เปลี่ยนเส้นทาง (redirect) เพื่อแสดงตัวอย่างหรือไม่ เมื่อมีการป้อน URL ที่มีการเปลี่ยนเส้นทาง หากปิดการใช้งาน จะช่วยประหยัดทรัพยากรของเซิร์ฟเวอร์ แต่จะไม่สามารถแสดงเนื้อหาจากปลายทางที่เปลี่ยนเส้นทางได้" timeout: "เวลาจำกัดในการโหลดตัวอย่าง URL (ms)" timeoutDescription: "หากเวลาที่ใช้ในการโหลดเกินค่านี้ จะไม่มีการสร้างการแสดงตัวอย่าง" maximumContentLength: "ค่าสูงสุดของ Content-Length (byte)" @@ -2793,6 +3073,62 @@ _contextMenu: app: "แอปพลิเคชัน" appWithShift: "แอปฟลิเคชันด้วยปุ่มยกแคร่ (Shift)" native: "UI ของเบราว์เซอร์" +_gridComponent: + _error: + requiredValue: "ค่านี้จำเป็นต้องกรอก" + columnTypeNotSupport: "การตรวจสอบค่าด้วย regex รองรับเฉพาะคอลัมน์ที่เป็น type:text" + patternNotMatch: "ค่านี้ไม่ตรงกับรูปแบบ {pattern}" + notUnique: "ค่านี้ต้องไม่ซ้ำกับค่าที่มีอยู่" +_roleSelectDialog: + notSelected: "ยังไม่มีการเลือก" +_customEmojisManager: + _gridCommon: + copySelectionRows: "คัดลอกแถวที่เลือกไว้" + copySelectionRanges: "คัดลือกที่เลือกไว้" + deleteSelectionRows: "ลบแถวที่เลือกไว้" + deleteSelectionRanges: "ล้างค่าช่วงที่เลือก" + searchSettings: "ตั้งค่าการค้นหา" + searchSettingCaption: "ตั้งค่าเงื่อนไขการค้นหาอย่างละเอียด" + searchLimit: "จำนวนรายการที่แสดง" + sortOrder: "ลำดับการเรียง" + registrationLogs: "ปูมการลงทะเบียน" + registrationLogsCaption: "จะแสดงปูมเมื่อมีการอัปเดตหรือลบเอโมจิ หากดำเนินการอัปเดต/ลบ หรือเปลี่ยนหน้า/รีโหลด หน้านี้ ปูมจะหายไป" + alertEmojisRegisterFailedDescription: "การอัปเดตหรือลบเอโมจิล้มเหลว กรุณาตรวจสอบรายละเอียดในปูมการลงทะเบียน" + _logs: + showSuccessLogSwitch: "แสดงปูมที่สำเร็จ" + failureLogNothing: "ไม่มีปูมความล้มเหลว" + logNothing: "ไม่มีปูม" + _remote: + selectionRowDetail: "รายละเอียดของแถวที่เลือก" + importSelectionRows: "นำเข้าแถวที่เลือก" + importSelectionRangesRows: "นำเข้าแถวในช่วงที่เลือก" + importEmojisButton: "นำเข้าเอโมจิที่ทำเครื่องหมายไว้" + confirmImportEmojisTitle: "นำเข้าเอโมจิ" + confirmImportEmojisDescription: "จะนำเข้าเอโมจิ {count} รายการที่ได้รับจากระยะไกล ทั้งนี้โปรดระมัดระวังเรื่องสิทธิ์การใช้งานเอโมจิ ดำเนินการหรือไม่?" + _local: + tabTitleList: "รายการเอโมจิที่ลงทะเบียนไว้แล้ว" + tabTitleRegister: "ลงทะเบียนเอโมจิ" + _list: + emojisNothing: "ยังไม่มีเอโมจิที่ลงทะเบียนไว้" + markAsDeleteTargetRows: "กำหนดแถวที่เลือกให้เป็นรายการสำหรับลบ" + markAsDeleteTargetRanges: "กำหนดช่วงแถวที่เลือกให้เป็นรายการสำหรับลบ" + alertUpdateEmojisNothingDescription: "ไม่มีการเปลี่ยนแปลงเอโมจิ" + alertDeleteEmojisNothingDescription: "ไม่มีเอโมจิที่อยู่ในรายการสำหรับลบ" + confirmMovePage: "ต้องการเปลี่ยนหน้าหรือไม่?" + confirmChangeView: "ต้องการเปลี่ยนการแสดงผลหรือไม่?" + confirmUpdateEmojisDescription: "จะอัปเดตเอโมจิ {count} รายการ ดำเนินการหรือไม่?" + confirmDeleteEmojisDescription: "จะลบเอโมจิที่ถูกทำเครื่องหมายไว้ {count} รายการ ดำเนินการหรือไม่?" + confirmResetDescription: "การเปลี่ยนแปลงทั้งหมดที่ทำมาจะถูกรีเซ็ต" + confirmMovePageDesciption: "มีการเปลี่ยนแปลงเอโมจิในหน้านี้ หากเปลี่ยนหน้าโดยไม่บันทึก การเปลี่ยนแปลงทั้งหมดจะถูกละทิ้ง" + dialogSelectRoleTitle: "ค้นหาบทบาทที่ตั้งค่าไว้ด้วยเอโมจิ" + _register: + uploadSettingTitle: "ตั้งค่าการอัปโหลด" + uploadSettingDescription: "สามารถกำหนดพฤติกรรมขณะอัปโหลดเอโมจิจากหน้าจอนี้ได้" + directoryToCategoryLabel: "ป้อนชื่อไดเรกทอรีเป็น \"category\"" + directoryToCategoryCaption: "เมื่อทำการลากและวางไดเรกทอรี ชื่อจะถูกป้อนเป็น \"category\"" + confirmRegisterEmojisDescription: "จะลงทะเบียนเอโมจิที่แสดงในรายการเป็นเอโมจิแบบกำหนดเองใหม่\nดำเนินการต่อหรือไม่? (เพื่อหลีกเลี่ยงภาระโหลดหนัก ระบบจะสามารถลงทะเบียนอีโมจิได้สูงสุด {count} รายการต่อครั้ง)" + confirmClearEmojisDescription: "ต้องการยกเลิกการแก้ไขและล้างรายการเอโมจิที่แสดงอยู่หรือไม่?" + confirmUploadEmojisDescription: "จะอัปโหลดไฟล์ {count} รายการที่ลากและวางไปยังไดรฟ์ ดำเนินการหรือไม่?" _embedCodeGen: title: "ปรับแต่งโค้ดฝัง" header: "แสดงส่วนหัว" @@ -2807,10 +3143,253 @@ _embedCodeGen: generateCode: "สร้างโค้ดสำหรับการฝัง" codeGenerated: "รหัสถูกสร้างขึ้นแล้ว" codeGeneratedDescription: "นำโค้ดที่สร้างแล้วไปวางในเว็บไซต์ของคุณเพื่อฝังเนื้อหา" +_selfXssPrevention: + warning: "คำเตือน" + title: "“ข้อความที่บอกให้วางบางอย่างในหน้าจอนี้” ทั้งหมดเป็นการหลอกลวง" + description1: "ถ้าวางบางอย่างที่นี่ อาจทำให้ผู้ไม่หวังดีเข้าควบคุมบัญชี หรือขโมยข้อมูลส่วนตัวได้" + description2: "ถ้าไม่เข้าใจอย่างชัดเจนว่าสิ่งที่กำลังจะวางคืออะไร %cให้หยุดการทำงานทันทีแล้วปิดหน้าต่างนี้" + description3: "ดูรายละเอียดเพิ่มเติมได้ที่นี่: {link}" +_followRequest: + recieved: "คำขอที่ได้รับ" + sent: "คำที่ส่งไป" _remoteLookupErrors: + _federationNotAllowed: + title: "ไม่สามารถสื่อสารกับเซิร์ฟเวอร์นี้ได้" + description: "การสื่อสารกับเซิร์ฟเวอร์นี้อาจถูกปิดใช้งาน หรือเซิร์ฟเวอร์นี้อาจจะได้บล็อกคุณ หรือคุณอาจจะได้บล็อกเซิร์ฟเวอร์นี้อยู่\nกรุณาติดต่อผู้ดูแลระบบเซิร์ฟเวอร์เพื่อสอบถามรายละเอียดเพิ่มเติม" + _uriInvalid: + title: "URI ไม่ถูกต้อง" + description: "มีปัญหาเกี่ยวกับ URI ที่ป้อน โปรดตรวจสอบว่าไม่มีอักขระที่ไม่สามารถใช้กับ URI" + _requestFailed: + title: "การร้องขอล้มเหลว" + description: "การสื่อสารกับเซิร์ฟเวอร์นี้ล้มเหลว เซิร์ฟเวอร์ปลายทางอาจล่ม หรืออาจป้อน URI ที่ไม่ถูกต้องหรือไม่มีอยู่" + _responseInvalid: + title: "ข้อมูลตอบสนองกลับไม่ถูกต้อง" + description: "สามารถเชื่อมต่อกับเซิร์ฟเวอร์นี้ได้ แต่ข้อมูลที่ได้รับไม่ถูกต้อง หากกำลังดึงข้อมูลจากเซิร์ฟเวอร์บุคคลที่สาม โปรดใช้ URI ที่สามารถดึงข้อมูลได้จากเซิร์ฟเวอร์ต้นทางโดยตรง" _noSuchObject: title: "ไม่พบหน้าที่ต้องการ" + description: "ไม่พบทรัพยากรที่ร้องขอ กรุณาตรวจสอบ URI อีกครั้ง" +_captcha: + verify: "กรุณาผ่าน CAPTCHA" + testSiteKeyMessage: "สามารถดูตัวอย่างได้โดยป้อนค่าทดสอบใน site key และ secret key\nดูรายละเอียดเพิ่มเติมได้ที่หน้าด้านล่างนี้" + _error: + _requestFailed: + title: "การร้องขอ CAPTCHA ล้มเหลว" + text: "โปรดลองใหม่ภายหลัง หรือ ตรวจสอบการตั้งค่าอีกครั้ง" + _verificationFailed: + title: "การยืนยัน CAPTCHA ล้มเหลว" + text: "กรุณาตรวจสอบอีกครั้งว่าการตั้งค่าถูกต้องหรือไม่" + _unknown: + title: "CAPTCHA เกิดข้อผิดพลาด" + text: "เกิดข้อผิดพลาดที่ไม่คาดคิด" +_bootErrors: + title: "การโหลดล้มเหลว" + serverError: "หากปัญหายังคงอยู่แม้ว่าจะรอสักครู่แล้วโหลดหน้าใหม่อีกครั้ง โปรดติดต่อผู้ดูแลระบบเซิร์ฟเวอร์พร้อมรหัสข้อผิดพลาดต่อไปนี้" + solution: "สิ่งต่อไปนี้อาจช่วยแก้ไขปัญหาได้" + solution1: "อัปเดตเบราว์เซอร์และระบบปฏิบัติการเป็นรุ่นล่าสุด" + solution2: "ปิดใช้งานตัวบล็อกโฆษณา" + solution3: "ล้างแคชเบราว์เซอร์" + solution4: "(Tor Browser) ตั้งค่า dom.webaudio.enabled เป็น true" + otherOption: "ตัวเลือกเพิ่มเติม" + otherOption1: "ลบการตั้งค่าและแคชของไคลเอนต์" + otherOption2: "เริ่มใช้งานไคลเอนต์แบบง่าย" + otherOption3: "เปิดเครื่องมือซ่อมแซม" + otherOption4: "เริ่มทำงาน CherryPick ในโหมดปลอดภัย" _search: searchScopeAll: "ทั้งหมด" searchScopeLocal: "ท้องถิ่น" + searchScopeServer: "ระบุเซิร์ฟเวอร์" searchScopeUser: "ผู้ใช้เฉพาะ" + pleaseEnterServerHost: "กรุณากรอกโฮสต์ของเซิร์ฟเวอร์" + pleaseSelectUser: "กรุณาเลือกผู้ใช้" + serverHostPlaceholder: "ตัวอย่าง: cherrypick.example.com" +_serverSetupWizard: + installCompleted: "การติดตั้ง CherryPick เสร็จสมบูรณ์แล้ว!" + firstCreateAccount: "ขั้นแรก ให้สร้างบัญชีผู้ดูแลระบบ" + accountCreated: "บัญชีผู้ดูแลระบบถูกสร้างขึ้นแล้ว!" + serverSetting: "การตั้งค่าเซิร์ฟเวอร์" + youCanEasilyConfigureOptimalServerSettingsWithThisWizard: "สามารถตั้งค่าเซิร์ฟเวอร์ได้อย่างง่ายดายด้วยวิซาร์ดนี้" + settingsYouMakeHereCanBeChangedLater: "สามารถเปลี่ยนแปลงการตั้งค่าเหล่านี้ในภายหลังได้" + howWillYouUseMisskey: "ต้องการใช้ CherryPick อย่างไร?" + _use: + single: "เซิร์ฟเวอร์คนเดียว" + single_description: "ใช้งานเป็นเซิร์ฟเวอร์ส่วนตัวสำหรับตัวเองคนเดียว" + single_youCanCreateMultipleAccounts: "แม้จะใช้งานเป็นเซิร์ฟเวอร์ส่วนตัวสำหรับคนเดียว ก็สามารถสร้างบัญชีผู้ใช้หลายบัญชีได้ตามความจำเป็น" + group: "เซิร์ฟเวอร์กลุ่ม" + group_description: "เชิญผู้ใช้ที่เชื่อถือได้ มาเข้าร่วมใช้งานแบบหลายคน" + open: "เซิร์ฟเวอร์สาธารณะ" + open_description: "เปิดรับผู้ใช้จำนวนมากแบบไม่จำกัด" + openServerAdvice: "การเปิดรับผู้ใช้จำนวนมากมีความเสี่ยง ควรบริหารจัดการด้วยระบบดูแลที่เข้มงวดเพื่อรับมือกับปัญหาที่อาจเกิดขึ้น" + openServerAntiSpamAdvice: "เพื่อป้องกันไม่ให้เซิร์ฟเวอร์ของตนกลายเป็นแหล่งส่งสแปม ควรเปิดใช้งานฟีเจอร์ป้องกันบอต เช่น reCAPTCHA และใส่ใจเรื่องความปลอดภัยอย่างเคร่งครัด" + howManyUsersDoYouExpect: "คาดว่าจะมีผู้ใช้งานประมาณกี่คน?" + _scale: + small: "น้อยกว่า 100 คน (ขนาดเล็ก)" + medium: "เกิน 100 คน แต่น้อยกว่า 1000 คน (ขนาดกลาง)" + large: "เกิน 1000 คน (ขนาดใหญ่)" + largeScaleServerAdvice: "เซิร์ฟเวอร์ขนาดใหญ่อาจต้องการความรู้ด้านโครงสร้างพื้นฐานขั้นสูง เช่น การบาลานซ์โหลด หรือการทำสำเนาฐานข้อมูล" + doYouConnectToFediverse: "เชื่อมต่อกับ Fediverse หรือไม่?" + doYouConnectToFediverse_description1: "หากเชื่อมต่อกับเครือข่ายที่ประกอบด้วยเซิร์ฟเวอร์แบบกระจาย (Fediverse) จะสามารถแลกเปลี่ยนเนื้อหากับเซิร์ฟเวอร์อื่นๆ ได้" + doYouConnectToFediverse_description2: "การเชื่อมต่อกับ Fediverse เรียกว่า “สหพันธ์”" + youCanConfigureMoreFederationSettingsLater: "หลังจากนี้ยังสามารถตั้งค่าแบบขั้นสูง เช่น การกำหนดเซิร์ฟเวอร์ที่อนุญาตให้สหพันธ์ต่อกันได้เพิ่มเติม" + remoteContentsCleaning: "การล้างข้อมูลเนื้อหาที่ได้รับโดยอัตโนมัติ" + remoteContentsCleaning_description: "เมื่อมีการเชื่อมโยงสหพันธ์ จะได้รับเนื้อหาเป็นจำนวนมากอย่างต่อเนื่อง เมื่อเปิดใช้งานการล้างข้อมูลอัตโนมัติ จะทำการลบเนื้อหาเก่าที่ไม่ถูกอ้างอิง ไปจากเซิร์ฟเวอร์โดยอัตโนมัติ เพื่อประหยัดพื้นที่จัดเก็บข้อมูล" + adminInfo: "ข้อมูลผู้ดูแลระบ" + adminInfo_description: "ตั้งค่าข้อมูลผู้ดูแลระบบที่จะใช้รับคำถามและติดต่อ" + adminInfo_mustBeFilled: "หากเปิดใช้เซิร์ฟเวอร์สาธารณะ หรือเปิดใช้งานสหพันธ์ จะต้องกรอกข้อมูลนี้" + followingSettingsAreRecommended: "แนะนำให้ตั้งค่าตามด้านล่างนี้" + applyTheseSettings: "ใช้การตั้งค่านี้" + skipSettings: "ข้ามการตั้งค่า" + settingsCompleted: "การตั้งค่าเสร็จสมบูรณ์แล้ว!" + settingsCompleted_description: "ขอบคุณที่สละเวลามาตั้งค่า ตอนนี้เซิร์ฟเวอร์พร้อมใช้งานได้ทันที" + settingsCompleted_description2: "การตั้งค่าเซิร์ฟเวอร์อย่างละเอียดสามารถทำได้จาก “แผงควบคุม”" + donationRequest: "คำขอรับบริจาค" + _donationRequest: + text1: "CherryPick เป็นซอฟต์แวร์ฟรีที่พัฒนาโดยอาสาสมัคร" + text2: "เพื่อให้การพัฒนางานนี้สามารถดำเนินต่อไปได้ในอนาคต หากไม่เป็นการรบกวน รบกวนพิจารณาร่วมสมทบทุนด้วยนะคะ" + text3: "นอกจากนี้ยังมีสิทธิพิเศษสำหรับผู้สนับสนุนอีกด้วยค่ะ" +_uploader: + editImage: "แก้ไขรูปภาพ" + compressedToX: "บีบอัดเป็น {x}" + savedXPercent: "ประหยัดไป {x}%" + abortConfirm: "มีไฟล์ที่ยังไม่ได้อัปโหลด ต้องการยกเลิกหรือไม่?" + doneConfirm: "มีไฟล์ที่ยังไม่ได้อัปโหลด ต้องการดำเนินการให้เสร็จสิ้นหรือไม่?" + maxFileSizeIsX: "ขนาดไฟล์สูงสุดที่สามารถอัปโหลดได้คือ {x}" + allowedTypes: "ประเภทไฟล์ที่สามารถอัปโหลดได้" + tip: "ยังไม่มีไฟล์ถูกอัปโหลด สามารถ ตรวจสอบ ลบชื่อไฟล์ บีบอัด หรือครอปตัดภาพ ก่อนอัปโหลดได้ในหน้านี้ เมื่อพร้อมแล้วให้กดปุ่ม “อัปโหลด” เพื่อเริ่มการอัปโหลด" +_clientPerformanceIssueTip: + title: "หากรู้สึกว่าแบตเตอรี่หมดเร็ว" + makeSureDisabledAdBlocker: "โปรดปิดการใช้งานตัวบล็อกโฆษณา" + makeSureDisabledAdBlocker_description: "ตัวบล็อกโฆษณาอาจส่งผลต่อประสิทธิภาพ โปรดตรวจสอบว่าไม่ได้เปิดใช้งานผ่านฟังก์ชันของระบบปฏิบัติการ เบราว์เซอร์ หรือส่วนเสริมใดๆ" + makeSureDisabledCustomCss: "โปรดปิดการใช้งาน CSS แบบกำหนดเอง" + makeSureDisabledCustomCss_description: "การเขียนทับสไตล์อาจส่งผลต่อประสิทธิภาพ โปรดตรวจสอบว่าไม่มี CSS แบบกำหนดเองหรือส่วนเสริมที่แก้ไขสไตล์เปิดใช้งานอยู่" + makeSureDisabledAddons: "โปรดปิดการใช้งานส่วนเสริม" + makeSureDisabledAddons_description: "ส่วนเสริมบางตัวอาจรบกวนการทำงานของไคลเอนต์และทำให้ประสิทธิภาพลดลง กรุณาลองปิดส่วนเสริมในเบราว์เซอร์แล้วตรวจสอบอีกครั้ง" +_clip: + tip: "คลิปเป็นฟังก์ชันที่สามารถรวมโน้ตเข้าด้วยกัน" +_userLists: + tip: "สามารถสร้างรายชื่อที่มีผู้ใช้ใดก็ได้ เมื่อสร้างแล้ว รายชื่อนั้นจะแสดงเป็นไทม์ไลน์ได้" +watermark: "ลายน้ำ" +defaultPreset: "พรีเซ็ตเริ่มต้น" +_watermarkEditor: + tip: "สามารถเพิ่มลายน้ำ เช่น ข้อมูลเครดิต ลงในภาพได้" + quitWithoutSaveConfirm: "ต้องการออกโดยไม่บันทึกหรือไม่?" + driveFileTypeWarn: "ไม่รองรับไฟล์นี้" + driveFileTypeWarnDescription: "กรุณาเลือกไฟล์ภาพ" + title: "แก้ไขลายน้ำ" + cover: "ซ้อนทับทั่วทั้งพื้นที่" + repeat: "ปูให้เต็มพื้นที่" + opacity: "ความทึบแสง" + scale: "ขนาด" + text: "ข้อความ" + qr: "QR โค้ด" + position: "ตำแหน่ง" + margin: "ระยะขอบ" + type: "รูปแบบ" + image: "รูปภาพ" + advanced: "ขั้นสูง" + angle: "แองเกิล" + stripe: "ริ้ว" + stripeWidth: "ความกว้างเส้น" + stripeFrequency: "จำนวนเส้น" + polkadot: "ลายจุด" + checker: "ช่องตาราง" + polkadotMainDotOpacity: "ความทึบของจุดหลัก" + polkadotMainDotRadius: "ขนาดของจุดหลัก" + polkadotSubDotOpacity: "ความทึบของจุดรอง" + polkadotSubDotRadius: "ขนาดของจุดรอง" + polkadotSubDotDivisions: "จำนวนจุดรอง" + leaveBlankToAccountUrl: "เว้นว่างไว้หากต้องการใช้ URL ของบัญชีแทน" +_imageEffector: + title: "เอฟเฟกต์" + addEffect: "เพิ่มเอฟเฟกต์" + discardChangesConfirm: "ต้องการทิ้งการเปลี่ยนแปลงแล้วออกหรือไม่?" + nothingToConfigure: "ไม่มีอะไรให้ตั้งค่า" + _fxs: + chromaticAberration: "ความคลาดสี" + glitch: "กลิตช์" + mirror: "กระจก" + invert: "กลับสี" + grayscale: "ขาวดำเทา" + blur: "มัว" + pixelate: "โมเสก" + colorAdjust: "ปรับแก้สี" + colorClamp: "บีบอัดสี" + colorClampAdvanced: "บีบอัดสี (ขั้นสูง)" + distort: "บิดเบี้ยว" + threshold: "สองสี" + zoomLines: "เส้นความเข้มข้น" + stripe: "ริ้ว" + polkadot: "ลายจุด" + checker: "ช่องตาราง" + blockNoise: "บล็อกที่มีการรบกวน" + tearing: "ฉีกขาด" + fill: "เติมเต็ม" + _fxProps: + angle: "แองเกิล" + scale: "ขนาด" + size: "ขนาด" + radius: "รัศสี" + samples: "จำนวนตัวอย่าง" + offset: "ตำแหน่ง" + color: "สี" + opacity: "ความทึบแสง" + normalize: "นอร์มัลไลซ์" + amount: "จำนวน" + lightness: "สว่าง" + contrast: "คอนทราสต์" + hue: "HUE" + brightness: "ความสว่าง" + saturation: "ความอิ่มตัว" + max: "สูงสุด" + min: "ต่ำสุด" + direction: "ทิศทาง" + phase: "ระยะ" + frequency: "ความถี่" + strength: "ความแรง" + glitchChannelShift: "ความเคลื่อน" + seed: "ซีด" + redComponent: "ส่วนสีแดง" + greenComponent: "ส่วนสีเขียว" + blueComponent: "ส่วนสีน้ำเงิน" + threshold: "เทรชโฮลด์" + centerX: "กลาง X" + centerY: "กลาง Y" + zoomLinesSmoothing: "ทำให้สมูธ" + zoomLinesSmoothingDescription: "ตั้งให้สมูธไม่สามารถใช้ร่วมกับตั้งความกว้างเส้นรวมศูนย์ได้" + zoomLinesThreshold: "ความกว้างเส้นรวมศูนย์" + zoomLinesMaskSize: "ขนาดพื้นที่ตรงกลาง" + zoomLinesBlack: "ทำให้ดำ" + circle: "ทรงกลม" +drafts: "ร่าง" +_drafts: + select: "เลือกฉบับร่าง" + cannotCreateDraftAnymore: "ถึงจำนวนจำกัดที่ฉบับร่างที่สามารถสร้างได้แล้ว" + cannotCreateDraft: "ไม่สามารถสร้างฉบับร่างด้วยเนื้อหานี้ได้" + delete: "ลบฉบับร่าง" + deleteAreYouSure: "ต้องการลบฉบับร่างหรือไม่?" + noDrafts: "ไม่มีฉบับร่าง" + replyTo: "ตอบกลับ {user}" + quoteOf: "อ้างอิงถึงโน้ตของ {user}" + postTo: "โพสต์ไปยัง {channel}" + saveToDraft: "บันทึกเป็นฉบับร่าง" + restoreFromDraft: "คืนค่าจากฉบับร่าง" + restore: "กู้คืน" + listDrafts: "รายการฉบับร่าง" + schedule: "โพสต์กำหนดเวลา" + listScheduledNotes: "รายการโน้ตที่กำหนดเวลาไว้" + cancelSchedule: "ยกเลิกกำหนดเวลา" +qr: "QR โค้ด" +_qr: + showTabTitle: "แสดงผล" + readTabTitle: "แสกน" + shareTitle: "{name}{acct}" + shareText: "โปรดติดตามฉันบน Fediverse ด้วย!" + chooseCamera: "เลือกกล้อง" + cannotToggleFlash: "ไม่สามารถเลือกแสงแฟลชได้" + turnOnFlash: "ปิดแสงแฟลช" + turnOffFlash: "เปิดแสงแฟลช" + startQr: "เริ่มตัวอ่าน QR โค้ด" + stopQr: "หยุดตัวอ่าน QR โค้ด" + noQrCodeFound: "ไม่พบ QR โค้ด" + scanFile: "สแกนภาพจากอุปกรณ์" + raw: "ข้อความ" + mfm: "MFC" diff --git a/locales/tr-TR.yml b/locales/tr-TR.yml index 77e8bd333d..5aa544475d 100644 --- a/locales/tr-TR.yml +++ b/locales/tr-TR.yml @@ -1,150 +1,166 @@ --- _lang_: "Türkçe" -headlineMisskey: "Notlarla bağlanmış bir ağ" -introMisskey: "Açık kaynaklı bir dağıtılmış mikroblog hizmeti olan CherryPick'e hoş geldiniz.\nCherryPick, neler olup bittiğini paylaşmak ve herkese sizden bahsetmek için \"notlar\" oluşturmanıza olanak tanıyan, açık kaynaklı, dağıtılmış bir mikroblog hizmetidir.\nHerkesin notlarına kendi tepkilerinizi hızlıca eklemek için \"Tepkiler\" özelliğini de kullanabilirsiniz👍.\nYeni bir dünyayı keşfedin🚀." -poweredByMisskeyDescription: "name}Açık kaynak bir platform\nCherryPickDünya'nın en sunucularında biri。" -monthAndDay: "{month}Ay {day}Gün" -search: "Arama" -notifications: "Bildirim" +headlineMisskey: "Notlarla birbirine bağlı bir ağ" +introMisskey: "Hoş geldiniz! CherryPick, merkezi olmayan bir açık kaynaklı mikroblog platformudur.\n“Notlar” yazarak şu anda neler olduğunu anlatabilir veya olayları başkalarıyla paylaşabilirsiniz. 📡\n“Tepkiler” ile diğer kullanıcıların notları hakkındaki duygularınızı hızlı bir şekilde ifade edebilirsiniz. 👍\nYeni bir dünya sizi bekliyor! 🚀" +poweredByMisskeyDescription: "{name}, açık kaynak platformu CherryPick (kısaca “CherryPick örneği” olarak anılır) tarafından desteklenen hizmetlerden biridir." +monthAndDay: "{day}.{month}." +search: "Ara" +reset: "Sıfırla" +notifications: "Bildirimler" username: "Kullanıcı Adı" password: "Şifre" -initialPasswordForSetup: "" -forgotPassword: "şifremi unuttum" -fetchingAsApObject: "從聯邦宇宙取得中..." -ok: "TAMAM" -gotIt: "Anladım" -cancel: "İptal" -noThankYou: "Hayır, teşekkürler" -enterUsername: "Kullanıcı adınızı giriniz" -renotedBy: "{user} tarafından Renotelandı" -noNotes: "Notlar mevcut değil." -noNotifications: "Bildirim bulunmuyor" +initialPasswordForSetup: "Kurulum için ilk şifre" +initialPasswordIsIncorrect: "Kurulum için ilk şifre yanlış" +initialPasswordForSetupDescription: "CherryPick'i kendiniz kurduysan, yapılandırma dosyasında belirtilen şifreyi kullan.\nCherryPick barındırma hizmeti veya benzeri bir hizmet kullanıyorsan, orada belirtilen şifreyi kullan.\nŞifre belirlemediysen, devam etmek için boş bırak." +forgotPassword: "Şifremi unuttum" +fetchingAsApObject: "Fediverse'den talep ediliyor..." +ok: "Tamam" +gotIt: "Anladım!" +cancel: "Vazgeç" +noThankYou: "Hayır, teşekkürler." +enterUsername: "Kullanıcı adı gir" +renotedBy: "{user} renote etti" +noNotes: "Not yok" +noNotifications: "Bildirim yok" instance: "Sunucu" settings: "Ayarlar" notificationSettings: "Bildirim Ayarları" basicSettings: "Temel Ayarlar" otherSettings: "Diğer Ayarlar" -openInWindow: "Bir pencere ile aç" +openInWindow: "Pencerede aç" profile: "Profil" -timeline: "Zaman çizelgesi" -noAccountDescription: "Bu kullanıcı henüz biyografisini yazmadı" -login: "Giriş Yap " -loggingIn: "Oturum aç" +timeline: "Pano" +noAccountDescription: "Bu kullanıcı henüz biyografisini yazmamış." +login: "Oturum Aç" +loggingIn: "Giriş Yapılıyor..." logout: "Çıkış Yap" -signup: "Kayıt Ol" -uploading: "Yükleniyor" +signup: "Kaydol" +uploading: "Yükleniyor..." save: "Kaydet" -users: "Kullanıcı" -addUser: "Kullanıcı Ekle" -favorite: "Favoriler" +users: "Kullanıcılar" +addUser: "Kullanıcı ekle" +favorite: "Favori" favorites: "Favoriler" -unfavorite: "Favorilerden Kaldır" -favorited: "Favorilerime eklendi." -alreadyFavorited: "Zaten favorilerinizde kayıtlı." -cantFavorite: "Favorilere kayıt yapılamadı" -pin: "Sabitlenmiş" -unpin: "Sabitlemeyi kaldır" +unfavorite: "Favoriden kaldır" +favorited: "Favoriye eklendi." +alreadyFavorited: "Zaten favoride" +cantFavorite: "Favoriye eklenemedi" +pin: "Profiline sabitle" +unpin: "Profilden sabitlemeyi kaldır" copyContent: "İçeriği kopyala" -copyLink: "Bağlantıyı Kopyala" -copyLinkRenote: "Turkish" +copyLink: "Link kopyala" +copyRemoteLink: "Uzak linki kopyala" +copyLinkRenote: "Renote linkini kopyala" delete: "Sil" deleteAndEdit: "Sil ve yeniden düzenle" -deleteAndEditConfirm: "Bu notu silip yeniden düzenlemek istiyor musunuz? Bu nota ilişkin tüm Tepkiler, Yeniden Notlar ve Yanıtlar da silinecektir." +deleteAndEditConfirm: "Bu notu silip yeniden düzenlemek ister misin? Bu notla ilgili tüm Tepki, Renote ve Yanıtlar da silinecek." addToList: "Listeye ekle" -addToAntenna: "Antene ekle" -sendMessage: "Mesaj Gönder" -copyRSS: "RSSKopyala" -copyUsername: "Kullanıcı Adını Kopyala" -copyUserId: "KullanıcıyıKopyala" -copyNoteId: "Kimlik notunu kopyala" -copyFileId: "Dosya ID'sini kopyala" -copyFolderId: "Klasör ID'sini kopyala" -copyProfileUrl: "Profil URL'sini kopyala" -searchUser: "Kullanıcıları ara" -reply: "yanıt" -loadMore: "Devamını yükle" -showMore: "Devamını yükle" +addToAntenna: "Anten'e ekle" +sendMessage: "Mesaj gönder" +copyRSS: "RSS kopyala" +copyUsername: "Kullanıcı adını kopyala" +copyUserId: "Kullanıcı ID'yi kopyala" +copyNoteId: "Not ID'yi kopyala" +copyFileId: "Dosya ID'yi kopyala" +copyFolderId: "Klasör ID'yi kopyala" +copyProfileUrl: "Profil URL kopyala" +searchUser: "Kullanıcı ara" +searchThisUsersNotes: "Kullanıcının notlarını ara" +reply: "Yanıtla" +loadMore: "Daha fazla yükle" +showMore: "Daha fazlasını göster" showLess: "Kapat" youGotNewFollower: "seni takip etti" receiveFollowRequest: "Takip isteği alındı" followRequestAccepted: "Takip isteği kabul edildi" mention: "Bahset" mentions: "Bahsetmeler" -directNotes: "Kişisel mesajlar" +directNotes: "Doğrudan notlar" importAndExport: "İçeri/Dışarı aktar" import: "İçeri aktar" export: "Dışa aktar" files: "Dosyalar" download: "İndir" -driveFileDeleteConfirm: "\"{name}\" dosyası silinsin mi? Dosya kullanıldığı tüm notlardan kaybolacaktır." -unfollowConfirm: "{name} takipten çıkarılsın mı?" -exportRequested: "Dışa aktarım talep ettiniz. Bu biraz zaman alabilir. İşlem bitince Sürücünüze eklenecektir." -importRequested: "Dışa aktarım talep ettiniz. Bu işlem biraz zaman alabilir." +driveFileDeleteConfirm: "“{name}” dosyasını silmek istediğinden emin misin? Bu dosyaya ekli tüm notlar da silinecek." +unfollowConfirm: "{name} kullanıcısını cidden takipden çıkmak istiyor musun?" +exportRequested: "Dışa aktarma işlemi talep ettin. Bu işlem biraz zaman alabilir. İşlem tamamlandığında Drive'ına eklenecek." +importRequested: "İçe aktarma talebinde bulundun. Bu işlem biraz zaman alabilir." lists: "Listeler" -noLists: "Liste yok" -note: "not" -notes: "notlar" -following: "takipçi" -followers: "takipçi" -followsYou: "seni takip ediyor" +noLists: "Hiç liste yok" +note: "Not" +notes: "Notlar" +following: "Takip" +followers: "Takipçi" +followsYou: "Sizi takip ediyor" createList: "Liste oluştur" -manageLists: "Yönetici Listeleri" -error: "hata" +manageLists: "Listeleri yönet" +error: "Hata" somethingHappened: "Bir hata oluştu" retry: "Tekrar dene" -pageLoadError: "Sayfa yüklenemedi." -pageLoadErrorDescription: "Bu genelde ağ veya tarayıcı ön belleği hatalarından olur. Lütfen ön belleği temizlemeyi veya birkaç dakika beklemeyi ve sayfayı yenilemeyi deneyin." -serverIsDead: "Sunucu yanıt vermiyor. Birkaç dakika sonra tekrar deneyin." -youShouldUpgradeClient: "Sayfayı görüntülemek için yenileyin." -enterListName: "Liste ismi" +pageLoadError: "Sayfa yüklenirken bir hata oluştu." +pageLoadErrorDescription: "Bu durum genellikle ağ hataları veya tarayıcının önbelleği nedeniyle oluşur. Önbelleği temizleyin ve bir süre bekledikten sonra tekrar dene." +serverIsDead: "Bu sunucu yanıt vermiyor. Lütfen bir süre bekleyin ve tekrar dene." +youShouldUpgradeClient: "Bu sayfayı görüntülemek için lütfen yenileyerek istemcini güncelle." +enterListName: "Listeye bir ad girin" privacy: "Gizlilik" -makeFollowManuallyApprove: "Takip istekleri elle onaylansın" +makeFollowManuallyApprove: "Takip istekleri onay gerektirir" defaultNoteVisibility: "Varsayılan görünürlük" -follow: "takipçi" -followRequest: "Takip isteği" +follow: "Takip et" +followRequest: "Takip isteği gönder" followRequests: "Takip istekleri" -unfollow: "takip etmeyi bırak" -followRequestPending: "Bekleyen Takip Etme Talebi" -enterEmoji: "Emoji Giriniz" -renote: "vazgeçme" -unrenote: "not alma" -renoted: "yeniden adlandırılmış" -cantRenote: "Ayrılamama" -cantReRenote: "not alabilirmiyim" -quote: "alıntı" -inChannelRenote: "Kanal içi Renote" -inChannelQuote: "Kanal içi Alıntı" -pinnedNote: "Sabitlenen" -pinned: "Sabitlenmiş" -you: "sen" -clickToShow: "Görüntülemek için tıkla" -sensitive: "Hassas içerik" +unfollow: "Takibi bırak" +followRequestPending: "Takip isteği beklemede" +enterEmoji: "Bir emoji gir" +renote: "Renote" +unrenote: "Renote geri al" +renoted: "Renote yapıldı." +renotedToX: "{name} adresine Renote" +cantRenote: "Bu not renote edilemez." +cantReRenote: "Renote yeniden Renote edilemez." +quote: "Alıntı" +inChannelRenote: "Kanal içi renote" +inChannelQuote: "Kanal içi alıntı" +renoteToChannel: "Kanala Renote" +renoteToOtherChannel: "Diğer kanala Renote\n" +pinnedNote: "Sabit not" +pinned: "Profiline sabitle" +you: "Sen" +clickToShow: "Göstermek için tıklayın" +sensitive: "Hassas" add: "Ekle" -reaction: "Tepkiler" +reaction: "Tepki" reactions: "Tepkiler" -reactionSettingDescription2: "Sıralamak için sürükleyin, silmek için tıklayın, eklemek için \"+\" tuşuna tıklayın." -rememberNoteVisibility: "Görünürlük ayarlarını hatırla" -attachCancel: "Eki sil" +emojiPicker: "Emoji seçici" +pinnedEmojisForReactionSettingDescription: "Tepki verirken sabitlenecek ve görüntülenecek emojileri ayarlayın." +pinnedEmojisSettingDescription: "Emoji seçiciyi görüntülerken sabitlenecek ve görüntülenecek emojileri ayarlayın" +emojiPickerDisplay: "Emoji seçici ekranı" +overwriteFromPinnedEmojisForReaction: "Tepki ayarlarından geçersiz kılma" +overwriteFromPinnedEmojis: "Genel ayarlardan geçersiz kılma" +reactionSettingDescription2: "Sıralamayı değiştirmek için sürükle, silmek için tıkla, eklemek için “+” tuşuna bas." +rememberNoteVisibility: "Not görünürlük ayarlarını hatırla" +attachCancel: "Eki kaldır" +deleteFile: "Dosyayı sil" markAsSensitive: "Hassas içerik olarak işaretle" unmarkAsSensitive: "Hassas içerik işaretini kaldır" enterFileName: "Dosya ismini gir" mute: "Gizle" unmute: "sesi aç" renoteMute: "sesi kapat" -renoteUnmute: "sesi açmayı iptal et" +renoteUnmute: "Renote sessiz modunu kaldır" block: "engelle" unblock: "engellemeyi kaldır" suspend: "askıya al" -unsuspend: "askıya alma" -blockConfirm: "Onayı engelle" -unblockConfirm: "engellemeyi kaldır onayla" +unsuspend: "askıya almayı kaldır" +blockConfirm: "Engeli onayla" +unblockConfirm: "Engel kaldırmayı onayla" suspendConfirm: "Hesap askıya alınsın mı?" -unsuspendConfirm: "Hesap askıdan kaldırılsın mı" +unsuspendConfirm: "Hesap askıdan kaldırılsın mı?" selectList: "Bir liste seç" editList: "Listeyi düzenle" selectChannel: "Kanal seç" selectAntenna: "Bir anten seç" editAntenna: "Anteni düzenle" +createAntenna: "Bir anten oluşturun" selectWidget: "Araç seç" editWidgets: "Araçları düzenle" editWidgetsExit: "Tamam" @@ -156,309 +172,3089 @@ emojiUrl: "Emoji URL'si" addEmoji: "Emoji ekle" settingGuide: "Önerilen ayarlar" cacheRemoteFiles: "Uzak dosyalar ön belleğe alınsın" -cacheRemoteFilesDescription: "Bu ayar açık olduğunda diğer sitelerin dosyaları doğrudan uzak sunucudan yüklenecektir. Bu ayarı kapatmak depolama kullanımını azaltacak ama küçük resimler oluşturulmadığından trafiği arttıracaktır." -youCanCleanRemoteFilesCache: "" +cacheRemoteFilesDescription: "Bu ayar açık olduğunda diğer sitelerin dosyaları doğrudan uzak sunucudan yüklenece. Bu ayarı kapatmak depolama kullanımını azaltacak ama küçük resimler oluşturulmadığından trafiği arttıracak." +youCanCleanRemoteFilesCache: "Dosya yönetimi görünümünde 🗑️ düğmesine tıklayarak önbelleği temizleyebilirsin." cacheRemoteSensitiveFiles: "Hassas uzak dosyalar ön belleğe alınsın" -cacheRemoteSensitiveFilesDescription: "Bu ayar kapalı olduğunda hassas uzak dosyalar ön belleğe alınmadan doğrudan uzak sunucudan yüklenecektir." +cacheRemoteSensitiveFilesDescription: "Bu ayar kapalı olduğunda hassas uzak dosyalar ön belleğe alınmadan doğrudan uzak sunucudan yüklenecek." flagAsBot: "Bot olarak işaretle" -flagAsBotDescription: "Bu seçeneği hesap bir program tarafından kontrol ediliyorsa işaretleyin. Bu, diğer geliştiricilerin sonsuz etkileşim zincirleri oluşturmasını engellemeye yardımcı olur ve CherryPick'in iç sisteminin hesaba bir bot gibi davranmasını sağlar." +flagAsBotDescription: "Bu hesap bir program tarafından kontrol ediliyorsa bu seçeneği etkinleştir. Etkinleştirildiğinde, diğer geliştiriciler için bir işaret görevi görerek diğer botlarla sonsuz etkileşim zincirlerini önleyecek ve CherryPick'in iç sistemlerini bu hesabı bir bot olarak ele alacak şekilde ayarlayacak." flagAsCat: "Kedi hesabı" flagAsCatDescription: "Kedi hesabı" -flagShowTimelineReplies: "Zaman akışında notlara gelen cevapları göster" -flagShowTimelineRepliesDescription: "Açık olduğu durumda, zaman akışında kullanıcıların başkalarına verdiği cevaplar gözükür." +flagShowTimelineReplies: "Pano'da notlara gelen cevapları göster" +flagShowTimelineRepliesDescription: "Açık olduğu durumda, Pano'da kullanıcıların başkalarına verdiği cevaplar gözükür." autoAcceptFollowed: "Takip edilen hesapların takip isteklerini kabul et" addAccount: "Hesap ekle" reloadAccountsList: "Hesap listesini güncelle" loginFailed: "Giriş başarısız oldu" showOnRemote: "Uzak sunucuda görüntüle" +continueOnRemote: "Uzak bir sunucuda devam edin" +chooseServerOnMisskeyHub: "Misskey Hub'dan bir sunucu seçin." +specifyServerHost: "Doğrudan bir sunucu ana bilgisayarı belirtin" +inputHostName: "Alan adını girin" general: "Genel" wallpaper: "Duvar kağıdı" setWallpaper: "Duvar kağıdını ayarla" -removeWallpaper: "Duvar kağıdını sil" -searchWith: "Arama: {q}" -youHaveNoLists: "Hiç listeniz yok" -followConfirm: "{name} takip edilsin mi?" -proxyAccount: "Vekil hesabı" -proxyAccountDescription: "Proxy hesabı, belirli koşullar altında kullanıcılar için uzaktan takipçi işlevi gören bir hesaptır. Örneğin, bir kullanıcı listeye bir uzak kullanıcı eklediğinde, o kullanıcıyı takip eden yerel bir kullanıcı yoksa uzak kullanıcının etkinliği örneğe teslim edilmeyecektir, dolayısıyla bunun yerine proxy hesabı takip edilecektir." -host: "Sağlayıcı" +removeWallpaper: "Duvar kağıdını kaldır" +searchWith: "Ara: {q}" +youHaveNoLists: "Hiç listeniz yok." +followConfirm: "{name} kullanıcısını takip etmek istediğinden emin misin?" +proxyAccount: "Proxy hesabı" +proxyAccountDescription: "Proxy hesabı, belirli koşullar altında kullanıcılar için uzaktan takipçi görevi gören bir hesap. Örneğin, bir kullanıcı listeye uzaktan bir kullanıcı eklediğinde, o kullanıcıyı takip eden yerel kullanıcı yoksa uzaktan kullanıcının etkinliği örneğe iletilmez, bunun yerine proxy hesabı takip eder." +host: "Host" +selectSelf: "Kendimi seç" selectUser: "Kullanıcı seç" -recipient: "Kime" -annotation: "Açıklamalar" +recipient: "Alıcı" +annotation: "Yorumlar" federation: "Federasyon" -instances: "Sunucu" -registeredAt: "Katılma tarihi" -latestRequestReceivedAt: "Alınan son talep" -latestStatus: "En son durum" +instances: "Sunucular" +registeredAt: "Kayıtlı" +latestRequestReceivedAt: "Son talep alındı" +latestStatus: "Son durum" storageUsage: "Depolama kullanımı" -charts: "Çizelgeler" +charts: "Grafikler" perHour: "Saatlik" perDay: "Günlük" -stopActivityDelivery: "Durum güncellemelerini gönderme" +stopActivityDelivery: "Etkinlik göndermeyi durdur" blockThisInstance: "Bu sunucuyu engelle" -silenceThisInstance: "" -operations: "İşlemler" -software: "Yazılımlar" +silenceThisInstance: "Bu sunucuyu sustur" +mediaSilenceThisInstance: "Medya bu sunucuyu sustursun" +operations: "Operasyonlar" +software: "Yazılım" +softwareName: "Yazılım" version: "Sürüm" -metadata: "Meta Verileri" -withNFiles: "{n} tane dosya" +metadata: "Meta veri" +withNFiles: "{n} dosya" monitor: "Monitör" jobQueue: "İşlem sırası" -cpuAndMemory: "İşlemci ve Hafıza" +cpuAndMemory: "CPU ve Bellek" network: "Ağ" disk: "Disk" instanceInfo: "Sunucu Bilgisi" statistics: "İstatistikler" -clearQueue: "Sırayı temizle" -clearQueueConfirmTitle: "Sıra silinsin mi?" -clearQueueConfirmText: "Sırada kalan hiçbir şey iletilmeyecek. Genelde bu işlem gerekli değildir." -clearCachedFiles: "Ön belleği temizle" -clearCachedFilesConfirm: "Ön belleğe alınmış tüm uzak sunucu dosyaları silinsin mi?" -blockedInstances: "Engellenen sunucular" -blockedInstancesDescription: "Engellemek istediğiniz sunucuların alan adlarını satır sonlarıyla ayırarak yazın. Yazılan sunucular bu sunucuyla iletişime geçemeyecek." -silencedInstances: "Turkısh" -silencedInstancesDescription: "" -muteAndBlock: "Susturma ve Engelleme" -mutedUsers: "Susturulan kullanıcılar" +clearQueue: "Kuyruğu temizle" +clearQueueConfirmTitle: "Kuyruğu silmek istediğinden emin misin?" +clearQueueConfirmText: "Kuyrukta kalan teslim edilmemiş notlar birleştirilmeyecek. Genellikle bu işlem gerekli değildir." +clearCachedFiles: "Önbelleği temizle" +clearCachedFilesConfirm: "Tüm önbelleğe alınmış uzak dosyaları silmek istediğinden emin misin?" +blockedInstances: "Engellenen Sunucu" +blockedInstancesDescription: "Engellemek istediğin sunucuların ana bilgisayar adlarını satır sonlarıyla ayırarak liste. Listelenen örnekler artık bu örnekle iletişim kuramayacaktır." +silencedInstances: "Susturulmuş sunucular" +silencedInstancesDescription: "Sessize almak istediğin sunucuların ana bilgisayar adlarını yeni bir satırla ayırarak listele. Listelenen sunuculara ait tüm hesaplar sessize alınmış olarak kabul edilecek ve yalnızca takip isteklerinde bulunabilecek, takip edilmedikleri takdirde yerel hesapları etiketleyemeyeceklerdir. Bu, engellenen sunucuları etkilemeyecek." +mediaSilencedInstances: "Medya susturulmuş sunucular" +mediaSilencedInstancesDescription: "Medya sessize almak istediğin sunucuların ana bilgisayar adlarını yeni bir satırla ayırarak liste. Listelenen sunuculara ait tüm hesaplar hassas hesap olarak değerlendirilecek ve özel emojiler kullanılamayacaktır. Bu durum, engellenen sunucuları etkilemeyecek." +federationAllowedHosts: "Federasyona izin verilen sunucular" +federationAllowedHostsDescription: "Federasyona izin vermek istediğiniz sunucuların ana bilgisayar adlarını satır sonlarıyla ayırın." +muteAndBlock: "Sessize Alma ve Engelleme" +mutedUsers: "Sessize alınan kullanıcılar" blockedUsers: "Engellenen kullanıcılar" noUsers: "Kullanıcı yok" editProfile: "Profili düzenle" -noteDeleteConfirm: "Bu notu silmek istediğinizden emin misiniz?" -pinLimitExceeded: "Daha fazla not sabitlenemez" -intro: "CherryPick yüklemesi tamamlandı! Lütfen yönetici hesabını oluşturun." -done: "Tamamlandı" +noteDeleteConfirm: "Bu notu silmek istediğinden emin misin?" +pinLimitExceeded: "Artık daha fazla not sabitleyemezsin" +done: "Tamam" +processing: "İşleniyor..." preview: "Önizleme" default: "Varsayılan" defaultValueIs: "Varsayılan: {value}" -noCustomEmojis: "Emoji bulunamadı" -noJobs: "Hiç işlem yok" -federating: "Federe ediliyor" +noCustomEmojis: "Emoji yok" +noJobs: "Hiç ş yok" +federating: "Birleştirme" blocked: "Engellenmiş" suspended: "Askıya alınmış" all: "Tümü" subscribing: "Abonelik" publishing: "Paylaşım" -notResponding: "Cevap yok" -instanceFollowing: "Sunucuda takip edenler" +notResponding: "Yanıt vermiyor" +instanceFollowing: "Sunucuda takip" instanceFollowers: "Sunucu takipçileri" -instanceUsers: "Sunucu kullanıcıları" +instanceUsers: "Bu sunucunun kullanıcıları" changePassword: "Şifreyi değiştir" security: "Güvenlik" -retypedNotMatch: "Girişler uyuşmuyor." -currentPassword: "Geçerli şifre" +retypedNotMatch: "Girişler eşleşmiyor." +currentPassword: "Mevcut şifre" newPassword: "Yeni şifre" -newPasswordRetype: "Yeni şifre (tekrar)" -attachFile: "Dosya ekle" -more: "Daha!" -featured: "Öne Çıkan" -usernameOrUserId: "Kullanıcı adı veya ID'si" +newPasswordRetype: "Yeni şifreyi tekrar girin" +attachFile: "Dosyaları ekle" +more: "Daha fazlası!" +featured: "Öne çıkan" +usernameOrUserId: "Kullanıcı adı veya ID" noSuchUser: "Kullanıcı bulunamadı" lookup: "Sorgu" announcements: "Duyurular" -imageUrl: "Görsel URL'si" +imageUrl: "Görsel URL" remove: "Sil" removed: "Silindi" -removeAreYouSure: "\"{x}\" silmek istediğinizden emin misiniz?" -deleteAreYouSure: "\"{x}\" silmek istediğinizden emin misiniz?" -resetAreYouSure: "Sıfırlansın mı?" +removeAreYouSure: "“{x}” öğesini kaldırmak istediğinizden emin misin?" +deleteAreYouSure: "“{x}” öğesini silmek istediğinizden emin misin?" +resetAreYouSure: "Cidden sıfırlansın mı?" +areYouSure: "Emin misin?" saved: "Kaydedildi" upload: "Yükle" -keepOriginalUploading: "Orijinal görseli koru" -keepOriginalUploadingDescription: "Orijinal olarak yüklenen görüntüyü olduğu gibi kaydeder. Kapatılırsa, yükleme sırasında web'de görüntülenecek bir sürüm oluşturulur." -fromDrive: "Drive Dosyasından" -fromUrl: "Bağlantıdan" -uploadFromUrl: "Bağlantıdan yükle" -uploadFromUrlDescription: "Yüklemek istediğiniz dosyanın bağlantısı" -uploadFromUrlRequested: "Yükleme talep edildi" -uploadFromUrlMayTakeTime: "Yüklemenin tamamlanması biraz süre alabilir." +keepOriginalUploading: "Orijinal görüntüyü koru" +keepOriginalUploadingDescription: "Orijinal olarak yüklenen görüntüyü olduğu gibi kaydeder. Kapalıysa, yükleme sırasında web'de görüntülenecek bir sürüm oluşturulur." +fromDrive: "Drive'den" +fromUrl: "URL'den" +uploadFromUrl: "URL'den yükle" +uploadFromUrlDescription: "Yüklemek istediğiniz dosyanın URL'si" +uploadFromUrlRequested: "Yükleme istendi" +uploadFromUrlMayTakeTime: "Yükleme işleminin tamamlanması biraz zaman alabilir." +uploadNFiles: "{n} dosya yükle" explore: "Keşfet" -messageRead: "Okundu" -noMoreHistory: "Bundan öncesi yok" -nUsersRead: "{n} kişi okudu" -agreeTo: "Kabul Ediyorum: {0}" -agree: "Kabul Et" -agreeBelow: "Aşağıdakileri kabul ederim" +messageRead: "Oku" +noMoreHistory: "Daha fazla geçmiş bilgisi yok." +startChat: "Sohbete başla" +nUsersRead: "{n} tarafından okundu" +agreeTo: "{0}'ı kabul ediyorum." +agree: "Kabul ediyorum" +agreeBelow: "Aşağıdakileri kabul ediyorum" basicNotesBeforeCreateAccount: "Önemli notlar" -termsOfService: "Şartlar ve Koşullar" +termsOfService: "Hizmet Şartları" start: "Başla" -home: "Ana sayfa" -remoteUserCaution: "Bu kullanıcı bir uzak sunucudan olduğu için alınan bilgiler tam olmayabilir." +home: "Pano" +remoteUserCaution: "Bu kullanıcı uzak bir sunucudan geldiği için, gösterilen bilgiler eksik olabilir." activity: "Etkinlik" images: "Görseller" -image: "Görseller" +image: "Görsel" birthday: "Doğum günü" yearsOld: "{age} yaşında" -registeredDate: "Kayıt tarihi" +registeredDate: "Katılma tarihi" location: "Konum" -theme: "Temalar" -themeForLightMode: "Aydınlık Tema" -themeForDarkMode: "Karanlık Tema" +theme: "Tema" +themeForLightMode: "Aydınlık Mod'da kullanılacak tema" +themeForDarkMode: "Karanlık Mod'da kullanılacak tema" light: "Aydınlık" dark: "Karanlık" -lightThemes: "Aydınlık Temalar" -darkThemes: "Karanlık Temalar" -syncDeviceDarkMode: "Sistem Koyu Modu ile senkronize et" -drive: "Sürücü" +lightThemes: "Aydınlık temalar" +darkThemes: "Karanlık temalar" +syncDeviceDarkMode: "Karanlık Modu cihaz ayarlarınızla senkronize et" +switchDarkModeManuallyWhenSyncEnabledConfirm: "\"{x}\" açık. Senkronizasyonu kapatıp modları manuel olarak değiştirmek ister misin?" +drive: "Drive" fileName: "Dosya adı" -selectFile: "Dosya seç" -selectFiles: "Dosya seç" -selectFolder: "Klasör seç" -selectFolders: "Klasör seç" +selectFile: "Dosya seçin" +selectFiles: "Dosyaları seçin" +selectFolder: "Klasör seçin" +selectFolders: "Klasörleri seçin" +fileNotSelected: "Hiç dosya seçilmedi" renameFile: "Dosyayı yeniden adlandır" folderName: "Klasör adı" -createFolder: "Klasör oluştur" -renameFolder: "Klasörü Yeniden Adlandır" -deleteFolder: "Klasörü sil" -addFile: "Dosya ekle" -emptyDrive: "Sürücü boş" +createFolder: "Bir klasör oluşturun" +renameFolder: "Bu klasörü yeniden adlandır" +deleteFolder: "Bu klasörü sil" +folder: "Dosya" +addFile: "Bir dosya ekle" +showFile: "Dosyaları göster" +emptyDrive: "Drive boş" emptyFolder: "Bu klasör boş" -unableToDelete: "Silme mümkün değil" -inputNewFileName: "Yeni dosya ismini girin" -inputNewDescription: "Yeni bir başlık gir" -inputNewFolderName: "Yeni klasör ismini girin" -circularReferenceFolder: "Hedef klasör taşınan klasörün bir alt klasörü." -hasChildFilesOrFolders: "Klasör boş olmadığından silinemiyor" -copyUrl: "URL'yi kopyala" +unableToDelete: "Silinemiyor" +inputNewFileName: "Yeni bir dosya adı girin" +inputNewDescription: "Yeni alternatif metin girin" +inputNewFolderName: "Yeni bir klasör adı girin" +circularReferenceFolder: "Hedef klasör, taşımak istediğiniz klasörün bir alt klasörü." +hasChildFilesOrFolders: "Bu klasör boş olmadığı için silinemez." +copyUrl: "URL kopyala" rename: "Yeniden adlandır" avatar: "Avatar" banner: "Banner" -displayOfSensitiveMedia: "Hassas içerik gösterimi" -whenServerDisconnected: "Sunucu bağlantısı kesildiğinde" -disconnectedFromServer: "Sunucu bağlantısı koptu" +displayOfSensitiveMedia: "Hassas ortamların görüntülenmesi" +whenServerDisconnected: "Sunucu ile bağlantı kesildiğinde" +disconnectedFromServer: "Sunucu bağlantısı kesildi" reload: "Yenile" -doNothing: "Bir şey yapma" -reloadConfirm: "Zaman akışı yenilensin mi?" +doNothing: "Yoksay" +reloadConfirm: "Panoyu yenilemek ister misin?" watch: "İzle" unwatch: "İzlemeyi bırak" accept: "Kabul et" reject: "Reddet" normal: "Normal" -instanceName: "Sunucu ismi" +instanceName: "Sunucu adı" instanceDescription: "Sunucu açıklaması" -maintainerName: "Yönetici ismi" -maintainerEmail: "Yöneticinin e-postası" -tosUrl: "Hizmet Koşulları Bağlantısı" -thisYear: "Bu yıl" -thisMonth: "Bu ay" +maintainerName: "Bakım sorumlusu" +maintainerEmail: "Bakım sorumlusu E-Posta adresi" +tosUrl: "Hizmet Şartları URL'si" +thisYear: "Yıl" +thisMonth: "Ay" today: "Bugün" -monthX: "{month} ay" +dayX: "{day}" +monthX: "{month}" +yearX: "{year}" pages: "Sayfalar" integration: "Entegrasyon" +connectService: "Bağlan" +disconnectService: "Bağlantıyı kes" +enableLocalTimeline: "Yerel Pano'yu etkinleştir" +enableGlobalTimeline: "Global Pano'yu etkinleştir" +disablingTimelinesInfo: "Yöneticiler ve Moderatörler, etkinleştirilmemiş olsalar bile her zaman tüm Pano'ya erişebilecekler." +registration: "Kaydol" +invite: "Davet et" +driveCapacityPerLocalAccount: "Yerel kullanıcı başına Drive kapasitesi" +driveCapacityPerRemoteAccount: "Uzak kullanıcı başına Drive kapasitesi" +inMb: "Megabayt cinsinden" +bannerUrl: "Banner görseli URL" +backgroundImageUrl: "Arka plan görseli URL" basicInfo: "Temel bilgiler" pinnedUsers: "Sabitlenmiş kullanıcılar" -pinnedNotes: "Sabitlenen" -manageAntennas: "Anten ayarları" +pinnedUsersDescription: "“Keşfet” sekmesinde sabitlenecek kullanıcı adlarını satır sonlarıyla ayırarak liste." +pinnedPages: "Sabitlenmiş Sayfalar" +pinnedPagesDescription: "Bu örneğin üst sayfasına sabitlemek istediğin Sayfaların yollarını satır sonlarıyla ayırarak gir." +pinnedClipId: "Sabitlenecek klibin ID" +pinnedNotes: "Sabitlenmiş notlar" +hcaptcha: "hCaptcha" +enableHcaptcha: "hCaptcha etkinleştir" +hcaptchaSiteKey: "Site anahtar" +hcaptchaSecretKey: "Gizli anahtar" +mcaptcha: "mCaptcha" +enableMcaptcha: "mCaptcha etkinleştir" +mcaptchaSiteKey: "Site anahtarı" +mcaptchaSecretKey: "Gizli anahtar" +mcaptchaInstanceUrl: "mCaptcha sunucu URL'si" +recaptcha: "reCAPTCHA" +enableRecaptcha: "reCAPTCHA etkinleştir" +recaptchaSiteKey: "Site anahtar" +recaptchaSecretKey: "Gizli anahtar" +turnstile: "Turnstile" +enableTurnstile: "Turnstile etkinleştir" +turnstileSiteKey: "Site anahtar" +turnstileSecretKey: "Gizli anahtar" +avoidMultiCaptchaConfirm: "Birden fazla Captcha sistemi kullanmak, aralarında çakışmaya neden olabilir. Şu anda etkin olan diğer Captcha sistemlerini devre dışı bırakmak ister misiniz? Etkin kalmalarını istiyorsan, iptal düğmesine bas." +antennas: "Antenler" +manageAntennas: "Antenleri Yönet" +name: "İsim" +antennaSource: "Anten kaynağı" +antennaKeywords: "Dinlenecek anahtar kelimeler" +antennaExcludeKeywords: "Hariç tutulacak anahtar kelimeler" +antennaExcludeBots: "Bot hesaplarını hariç tut" +antennaKeywordsDescription: "VE koşulu için boşluklarla, VEYA koşulu için satır sonlarıyla ayırın." +notifyAntenna: "Yeni notlar hakkında bildirimde bulunun" +withFileAntenna: "Sadece dosyalı notlar" +excludeNotesInSensitiveChannel: "Hassas kanallardan gelen notları hariç tutun" +enableServiceworker: "Tarayıcınız için Push Bildirimlerini Etkinleştir" +antennaUsersDescription: "Satır başına bir kullanıcı adı listele" +caseSensitive: "Harfe duyarlı" +withReplies: "Yanıtları ekle" +connectedTo: "Aşağıdaki hesap(lar) bağlı" +notesAndReplies: "Notlar ve yanıtlar" +withFiles: "Dosyalar dahil" +silence: "Sessize al" +silenceConfirm: "Bu kullanıcıyı susturmak istediğinden emin misin?" +unsilence: "Sessize almayı geri al" +unsilenceConfirm: "Bu kullanıcının sessize alınmasını geri almak istediğinden emin misin?" +popularUsers: "Popüler kullanıcılar" +recentlyUpdatedUsers: "Son zamanlarda aktif olan kullanıcılar" +recentlyRegisteredUsers: "Yeni katılan kullanıcılar" +recentlyDiscoveredUsers: "Yeni keşfedilen kullanıcılar" +exploreUsersCount: "{count} kullanıcı var" +exploreFediverse: "Fediverse'i keşfedin" +popularTags: "Popüler etiketler" userList: "Listeler" -resetPassword: "Şifre sıfırlama" -details: "Detaylar" -deck: "Güverte" -smtpHost: "Sağlayıcı" -smtpUser: "Kullanıcı Adı" +about: "Hakkında" +aboutMisskey: "CherryPick Hakkında" +administrator: "Yönetici" +token: "Token" +2fa: "İki faktörlü kimlik doğrulama" +setupOf2fa: "İki faktörlü kimlik doğrulamayı ayarlayın" +totp: "Authenticator Uygulaması" +totpDescription: "Tek seferlik şifreleri girmek için bir kimlik doğrulama uygulaması kullanın" +moderator: "Moderatör" +moderation: "Moderasyon" +moderationNote: "Moderasyon notu" +moderationNoteDescription: "Moderatörler arasında paylaşılacak notları girebilirsin." +addModerationNote: "Moderasyon notu ekle" +moderationLogs: "Moderasyon günlükleri" +nUsersMentioned: "{n} kullanıcı bahsetti" +securityKeyAndPasskey: "Güvenlik ve geçiş anahtarları" +securityKey: "Güvenlik anahtarı" +lastUsed: "Son kullanılan" +lastUsedAt: "Son kullanım: {t}" +unregister: "Kayıttan çık" +passwordLessLogin: "Şifresiz giriş" +passwordLessLoginDescription: "Yalnızca güvenlik anahtarı veya şifre anahtarı kullanarak şifresiz oturum açmaya izin verir." +resetPassword: "Şifreyi sıfırla" +newPasswordIs: "Yeni şifre \"{password}\"" +reduceUiAnimation: "UI animasyonlarını azaltın." +share: "Paylaş" +notFound: "Bulunamadı" +notFoundDescription: "Bu URL'ye karşılık gelen sayfa bulunamadı." +uploadFolder: "Yüklemeler için varsayılan klasör" +markAsReadAllNotifications: "Tüm bildirimleri okundu olarak işaretle" +markAsReadAllUnreadNotes: "Tüm notları okundu olarak işaretle" +markAsReadAllTalkMessages: "Tüm mesajları okundu olarak işaretle" +help: "Yardım" +inputMessageHere: "Mesajınızı buraya girin" +close: "Kapat" +invites: "Davetler" +members: "Üyeler" +transfer: "Transfer" +title: "Başlık" +text: "Metin" +enable: "Etkin" +next: "Sonraki" +retype: "Tekrar girin" +noteOf: "{user} not'u" +quoteAttached: "Alıntı" +quoteQuestion: "Alıntı olarak ekle?" +attachAsFileQuestion: "Panodaki metin uzun. Metin dosyası olarak eklemek ister misin?" +onlyOneFileCanBeAttached: "Bir mesaja yalnızca bir dosya ekleyebilirsin." +signinRequired: "Devam etmeden önce lütfen kayıt olun veya giriş yapın." +signinOrContinueOnRemote: "Devam etmek için sunucunuzu taşıyın veya bu sunucuya kaydolun / giriş yapın." +invitations: "Davetler" +invitationCode: "Davet kodu" +checking: "Kontrol ediliyor..." +available: "Kullanılabilir" +unavailable: "Kullanılamaz" +usernameInvalidFormat: "Büyük ve küçük harfler, rakamlar ve alt çizgi kullanabilirsin. (a~z、A~Z、0~9)" +tooShort: "Çok kısa" +tooLong: "Çok uzun" +weakPassword: "Zayıf şifre" +normalPassword: "Ortalama şifre" +strongPassword: "Güçlü şifre" +passwordMatched: "Eşleşti" +passwordNotMatched: "Eşleşmedi" +signinWith: "{x} ile giriş yapın" +signinFailed: "Giriş yapılamıyor. Girilen kullanıcı adı veya şifre yanlış." +or: "veya" +language: "Dil" +uiLanguage: "Kullanıcı arayüzü dili" +aboutX: "{x} hakkında" +emojiStyle: "Emoji stili" +native: "Yerli" +menuStyle: "Menü stili" +style: "Stil" +drawer: "Çekmece" +popup: "Pop-up" +showNoteActionsOnlyHover: "Not eylemlerini yalnızca üzerine gelindiğinde göster" +showReactionsCount: "Notlardaki tepki sayısını gör" +noHistory: "Geçmiş mevcut değil" +signinHistory: "Giriş geçmişi" +enableAdvancedMfm: "Gelişmiş MFC'yi etkinleştir" +enableAnimatedMfm: "Animasyonlu MFC'yi etkinleştir" +doing: "İşleniyor..." +category: "Kategori" +tags: "Takma adlar" +docSource: "Bu belgenin kaynağı" +createAccount: "Hesap oluştur" +existingAccount: "Mevcut hesap" +regenerate: "Yeniden oluştur" +fontSize: "Yazı tipi boyutu" +mediaListWithOneImageAppearance: "Tek bir resim içeren medya listelerinin yüksekliği" +limitTo: "{x} ile sınırlandır" +noFollowRequests: "Bekleyen takip istekleri yok." +openImageInNewTab: "Görüntüleri yeni sekmede aç" +dashboard: "Gösterge paneli" +local: "Yerel" +remote: "Uzak" +total: "Toplam" +weekOverWeekChanges: "Geçen haftadan beri yapılan değişiklikler" +dayOverDayChanges: "Dünkü değişiklikler" +appearance: "Görünüm" +clientSettings: "İstemci Ayarları" +accountSettings: "Hesap Ayarları" +promotion: "Tanıtım" +promote: "Tanıtıldı" +numberOfDays: "Gün sayısı" +hideThisNote: "Bu notu gizle" +showFeaturedNotesInTimeline: "Pano'da öne çıkan notları göster" +objectStorage: "Nesne Depolama" +useObjectStorage: "Nesne depolamayı kullanın" +objectStorageBaseUrl: "Temel URL" +objectStorageBaseUrlDesc: "Referans olarak kullanılan URL. CDN veya Proxy kullanıyorsanız, bunların URL'sini belirtin.\nS3 için ‘https://.s3.amazonaws.com’ ve GCS veya eşdeğer hizmetler için ‘https://storage.googleapis.com/’ vb. kullanın." +objectStorageBucket: "Kova" +objectStorageBucketDesc: "Lütfen sağlayıcınızda kullanılan kova adını belirtin." +objectStoragePrefix: "Ön ek" +objectStoragePrefixDesc: "Dosyalar bu öneke sahip dizinler altında saklanacaktır." +objectStorageEndpoint: "Uç nokta" +objectStorageEndpointDesc: "AWS S3 kullanıyorsanız bu alanı boş bırakın, aksi takdirde kullandığınız hizmete bağlı olarak uç noktayı ‘’ veya ‘:’ olarak belirtin." +objectStorageRegion: "Bölge" +objectStorageRegionDesc: "'xx-east-1' gibi bir bölge belirt. Hizmetin bölgeler arasında ayrım yapmıyorsa, ‘us-east-1’ girin. AWS yapılandırma dosyalarını veya ortam değişkenlerini kullanıyorsan boş bırak." +objectStorageUseSSL: "SSL kullanın" +objectStorageUseSSLDesc: "API bağlantıları için HTTPS kullanmayacaksanız bunu kapatın." +objectStorageUseProxy: "Proxy üzerinden bağlan" +objectStorageUseProxyDesc: "API bağlantıları için Proxy kullanmayacaksanız bunu kapatın." +objectStorageSetPublicRead: "Yükleme sırasında \"genel-okuma\" ayarını yapın" +s3ForcePathStyleDesc: "s3ForcePathStyle etkinleştirilirse, kova adı URL'nin ana bilgisayar adı yerine URL yoluna eklenmelidir. Kendi kendine barındırılan bir Minio örneği gibi hizmetleri kullanırken bu ayarı etkinleştirmen gerekebilir." +serverLogs: "Sunucu log kayıtları" +deleteAll: "Tümünü sil" +showFixedPostForm: "Gönderi formunu pano üstünde görüntüle" +showFixedPostFormInChannel: "Gönderi formunu pano üstünde görüntüle (Kanallar)" +withRepliesByDefaultForNewlyFollowed: "Yeni takip edilen kullanıcıların yanıtlarını varsayılan olarak panoya dahil et" +newNoteRecived: "Yeni Not'lar var" +newNote: "Yeni Not" +sounds: "Sesler" +sound: "Ses" +notificationSoundSettings: "Bildirim sesi ayarları" +listen: "Dinle" +none: "Hiçbiri" +showInPage: "Sayfada göster" +popout: "Açılır pencere" +volume: "Ses hacmi" +masterVolume: "Ana ses seviyesi" +notUseSound: "Sesi kapat" +useSoundOnlyWhenActive: "CherryPick etkin olduğunda ses çıkarılır." +details: "Ayrıntılar" +renoteDetails: "Renote detayları" +chooseEmoji: "Bir emoji seçin" +unableToProcess: "İşlem tamamlanamadı." +recentUsed: "Son kullanılan" +install: "Yükle" +uninstall: "Kaldır" +installedApps: "Yetkili Uygulamalar" +nothing: "Burada görülecek bir şey yok." +installedDate: "Yetkili" +lastUsedDate: "En son kullanıldığı tarih" +state: "Durum" +sort: "Sıralama düzeni" +ascendingOrder: "Artan" +descendingOrder: "Azalan" +scratchpad: "Not defteri" +scratchpadDescription: "Scratchpad, AiScript deneyleri için bir ortam sağlar. CherryPick ile etkileşim halindeyken yazabilir, çalıştırabilir ve sonuçlarını kontrol edebilirsin." +uiInspector: "UI denetçisi" +uiInspectorDescription: "Bellekteki UI bileşeni sunucu listesini görebilirsin. UI bileşeni, Ui:C: işlevi tarafından oluşturulacak." +output: "Çıktı" +script: "Script" +disablePagesScript: "Sayfalarda AiScript'i devre dışı bırak" +updateRemoteUser: "Uzak kullanıcı bilgilerini güncelle" +unsetUserAvatar: "Avatar'ı kaldır" +unsetUserAvatarConfirm: "Avatarı silmek istediğinden emin misin?" +unsetUserBanner: "Banner'ı kaldır" +unsetUserBannerConfirm: "Banner'ı kaldırmak istediğinden emin misin?" +deleteAllFiles: "Tüm dosyaları sil" +deleteAllFilesConfirm: "Tüm dosyaları silmek istediğinden emin misin?" +removeAllFollowing: "Takip ettiğin tüm kullanıcıları takipten çıkar" +removeAllFollowingDescription: "Bu komutu çalıştırmak, {host} adresindeki tüm hesapları takipten çıkarır. Örneğin, sunucu artık mevcut değilse bu komutu çalıştırın." +userSuspended: "Bu kullanıcı askıya alınmıştır." +userSilenced: "Bu kullanıcı susturuluyor." +yourAccountSuspendedTitle: "Bu hesap askıya alınmıştır." +yourAccountSuspendedDescription: "Bu hesap, sunucunun hizmet şartlarını veya benzerlerini ihlal ettiği için askıya alınmıştır. Daha ayrıntılı bir neden öğrenmek istersen yöneticiyle iletişime geç. Lütfen yeni bir hesap oluşturma." +tokenRevoked: "Geçersiz jeton" +tokenRevokedDescription: "Bu jetonun süresi doldu. Lütfen tekrar giriş yapın." +accountDeleted: "Hesap silindi" +accountDeletedDescription: "Bu hesap silinmiş." +menu: "Menü" +divider: "Bölücü" +addItem: "Öğe Ekle" +rearrange: "Yeniden düzenle" +relays: "Röleler" +addRelay: "Röle ekle" +inboxUrl: "Gelen Kutusu URL" +addedRelays: "Eklenen Röleler" +serviceworkerInfo: "Push bildirimleri için etkinleştirilmeli." +deletedNote: "Silinen not" +invisibleNote: "Görünmez not" +enableInfiniteScroll: "Otomatik olarak daha fazlasını yükle" +visibility: "Görünürlük" +poll: "Anket" +useCw: "İçeriği gizle" +enablePlayer: "Video oynatıcıyı aç" +disablePlayer: "Video oynatıcıyı kapat" +expandTweet: "Notu genişlet" +themeEditor: "Tema düzenleyici" +description: "Açıklama" +describeFile: "Alternatif metin ekle" +enterFileDescription: "Alternatif metin girin" +author: "Yazar" +leaveConfirm: "Kaydedilmemiş değişiklikler var. Bunları silmek istiyor musunuz?" +manage: "Yönetim" +plugins: "Eklentiler" +preferencesBackups: "Tercih yedeklemeleri" +deck: "Deck" +undeck: "Güverteden Ayrıl" +useBlurEffectForModal: "Modaller için bulanıklaştırma efekti kullanın" +useFullReactionPicker: "Tam boy tepki seçiciyi kullanın" +width: "Genişlik" +height: "Yükseklik" +large: "Büyük" +medium: "Orta" +small: "Küçük" +generateAccessToken: "Erişim jetonu oluştur" +permission: "İzinler" +adminPermission: "Yönetici İzinleri" +enableAll: "Tümünü etkinleştir" +disableAll: "Tümünü devre dışı bırak" +tokenRequested: "Hesaba erişim izni ver" +pluginTokenRequestedDescription: "Bu eklenti, burada ayarlanan izinleri kullanabilecek." +notificationType: "Bildirim türü" +edit: "Düzenle" +emailServer: "E-posta sunucusu" +enableEmail: "E-posta dağıtımını etkinleştir" +emailConfigInfo: "Kayıt sırasında veya şifreni unuttuğunda E-postanı doğrulamak için kullanılır." +email: "E-Posta" +emailAddress: "E-Posta adresi" +smtpConfig: "SMTP Sunucu yapılandırması" +smtpHost: "Host" +smtpPort: "Port" +smtpUser: "Kullanıcı adı" smtpPass: "Şifre" +emptyToDisableSmtpAuth: "SMTP kimlik doğrulamasını devre dışı bırakmak için kullanıcı adı ve şifre alanlarını boş bırakın." +smtpSecure: "SMTP bağlantıları için örtük SSL/TLS kullanın" +smtpSecureInfo: "STARTTLS kullanırken bunu kapatın." +testEmail: "Test E-postası gönderimi" +wordMute: "Kelime sustur" +wordMuteDescription: "Belirtilen kelime veya kelime öbeğini içeren notları küçültün. Küçültülmüş notlar, üzerlerine tıklanarak görüntülenebilir." +hardWordMute: "Zorla kelime sustur" +showMutedWord: "Sessize alınan kelimeleri göster" +hardWordMuteDescription: "Belirtilen kelime veya kelime öbeğini içeren notları gizle. Kelime sessize alma özelliğinden farklı olarak, not tamamen görünmez hale gelir." +regexpError: "Düzenli ifade hatası" +regexpErrorDescription: "{tab} kelimesinin {line} satırındaki düzenli ifadede bir hata oluştu:" +instanceMute: "Sunucu Sessizleştirme" +userSaysSomething: "{name} bir şey söyledi." +userSaysSomethingAbout: "{name} “{word}” hakkında bir şey söyledi." +makeActive: "Etkinleştir" +display: "Ekran" +copy: "Kopyala" +copiedToClipboard: "Panoya kopyalandı" +metrics: "Metrikler" +overview: "Genel Bakış" +logs: "Günlükler" +delayed: "Gecikmeli" +database: "Veritabanı" +channel: "Kanallar" +create: "Oluştur" notificationSetting: "Bildirim ayarları" +notificationSettingDesc: "Görüntülemek istediğiniz bildirim türlerini seçin." +useGlobalSetting: "Genel ayarları kullan" +useGlobalSettingDesc: "Etkinleştirildiğinde, hesabınızın bildirim ayarları kullanılır. Devre dışı bırakıldığında, bireysel yapılandırmalar yapılabilir." +other: "Diğer" +regenerateLoginToken: "Giriş jetonunu yeniden oluştur" +regenerateLoginTokenDescription: "Giriş sırasında dahili olarak kullanılan jetonu yeniden oluşturur. Normalde bu işlem gerekli değildir. Yeniden oluşturulursa, tüm cihazlar oturumu kapatılır." +theKeywordWhenSearchingForCustomEmoji: "Bu, kendi emojilerini ararken kullanılan anahtar kelimedir." +setMultipleBySeparatingWithSpace: "Birden fazla girişi boşluklarla ayırın." +fileIdOrUrl: "Dosya ID veya URL" +behavior: "Davranış" +sample: "Örnek" +abuseReports: "Raporlar" +reportAbuse: "Rapor" +reportAbuseRenote: "Raporu yeniden gönder" +reportAbuseOf: "{name} raporu" +fillAbuseReportDescription: "Bu raporla ilgili ayrıntıları lütfen doldur. Belirli bir notla ilgiliyse, lütfen URL'sini de ekle." +abuseReported: "Raporunuz gönderildi. Çok teşekkür ederiz." +reporter: "Raporlayan" +reporteeOrigin: "Bildirim Kaynağı" +reporterOrigin: "Bildirenin Kaynağı" +send: "Gönder" +openInNewTab: "Yeni sekmede aç" +openInSideView: "Yan görünümde aç" +defaultNavigationBehaviour: "Varsayılan gezinme davranışı" +editTheseSettingsMayBreakAccount: "Bu ayarları düzenlemek hesabınıza zarar verebilir." instanceTicker: "Notların sunucu bilgileri" +waitingFor: "{x} bekleniyor" +random: "Rastgele" +system: "Sistem" +switchUi: "UI değiştir" +desktop: "Masaüstü " +clip: "Klip" +createNew: "Yeni oluştur" +optional: "Opsiyonel" +createNewClip: "Klip oluştur" +unclip: "Klip kaldır" +confirmToUnclipAlreadyClippedNote: "Bu not zaten “{name}” klibinin bir parçası. Bu klipten silmek ister misin?" +public: "Herkese açık" +private: "Özel" +i18nInfo: "CherryPick, gönüllüler tarafından çeşitli dillere çevrilmektedir. {link} adresinden yardımcı olabilirsin." +manageAccessTokens: "Acces Tokens yönet" +accountInfo: "Hesap bilgileri" +notesCount: "Not sayısı" +repliesCount: "Yanıt sayısı" +renotesCount: "Renote sayısı" +repliedCount: "Alınan yanıt sayısı" +renotedCount: "Alınan Renote sayısı" +followingCount: "Takip sayısı" +followersCount: "Takipçi sayısı" +sentReactionsCount: "Tepki sayısı" +receivedReactionsCount: "Alınan tepki sayısı" +pollVotesCount: "Anket oy sayısı" +pollVotedCount: "Alınan anket oy sayısı" +yes: "Evet" +no: "Hayır" +driveFilesCount: "Drive dosya sayısı" +driveUsage: "Drive alanı kullanımı" +noCrawle: "Tarayıcı indekslemesini reddet" noCrawleDescription: "Arama motorlarından profilinde, notlarında, sayfalarında vb. dolaşılmamasını ve dizine eklememesini talep et." -clearCache: "Ön belleği temizle" +lockedAccountInfo: "Notunuzun görünürlüğünü “Yalnızca takipçiler” olarak ayarlamadığınız sürece, takipçilerin manuel olarak onaylanmasını gerektirse bile notlarınız herkes tarafından görülebilir." +alwaysMarkSensitive: "Varsayılan olarak hassas olarak işaretle" +loadRawImages: "Küçük resimleri göstermek yerine orijinal resimleri yükle" +disableShowingAnimatedImages: "Animasyonlu görüntüleri oynatmayın" +highlightSensitiveMedia: "Hassas medyayı vurgulayın" +verificationEmailSent: "Doğrulama e-postası gönderildi. Doğrulamayı tamamlamak için e-postadaki bağlantıyı takip edin." +notSet: "Ayarlı değil" +emailVerified: "E-posta adresi doğrulandı." +noteFavoritesCount: "Favori not sayısı" +pageLikesCount: "Beğenilen sayfa sayısı" +pageLikedCount: "Alınan sayfa beğen sayısı" +contact: "İletişim" +useSystemFont: "Sistemin varsayılan yazı tipini kullanın" +clips: "Klipler" +experimentalFeatures: "Deneysel özellikler" +experimental: "Deneysel" +thisIsExperimentalFeature: "Bu deneysel bir özellik. İşlevselliği değişebilir ve amaçlandığı gibi çalışmayabilir." +developer: "Geliştirici" +makeExplorable: "Hesabı “Keşfet” bölümünde görünür hale getir" +makeExplorableDescription: "Bunu kapatırsanız, hesabınız “Keşfet” bölümünde görünmez." +duplicate: "Çoğalt" +left: "Sol" +center: "Merkez" +wide: "Geniş" +narrow: "Dar" +reloadToApplySetting: "Bu ayar, sayfa yeniden yüklendikten sonra geçerli olacaktır. Şimdi yeniden yüklemek ister misin?" +needReloadToApply: "Bunun yansıtılması için yeniden yükleme yapılması gerekir." +needToRestartServerToApply: "Değişikliğin yansıtılması için CherryPick'in yeniden başlatılması gerekir." +showTitlebar: "Başlık çubuğunu göster" +clearCache: "Önbellek temizle" onlineUsersCount: "{n} kullanıcı çevrim içi" +nUsers: "{n} Kullanıcı" +nNotes: "{n} Not" +sendErrorReports: "Hata raporları gönder" +sendErrorReportsDescription: "Etkinleştirildiğinde, bir sorun oluştuğunda ayrıntılı hata bilgileri CherryPick ile paylaşılacak ve bu da CherryPick'in kalitesinin iyileştirilmesine yardımcı olacak.\nBu bilgiler arasında işletim sisteminizin sürümü, kullandığınız tarayıcı, CherryPick'deki faaliyetlerin vb. yer alacaktır." +myTheme: "Benim temam" +backgroundColor: "Arka plan rengi" +accentColor: "Vurgu rengi" +textColor: "Metin rengi" +saveAs: "Farklı kaydet" +advanced: "Gelişmiş" +advancedSettings: "Gelişmiş ayarlar" +value: "Değer" +createdAt: "Oluşturuldu" +updatedAt: "Güncellendi" +saveConfirm: "Değişiklikleri kaydetmek ister misin?" +deleteConfirm: "Cidden silmek istiyor musunuz?" +invalidValue: "Geçersiz değer." +registry: "Kayıt Defteri" +closeAccount: "Hesabı kapat" +currentVersion: "Şu anki sürüm" +latestVersion: "En yeni sürüm" +youAreRunningUpToDateClient: "İstemci yazılımınızın en yeni sürümünü kullanıyorsunuz." +newVersionOfClientAvailable: "İstemcinin daha yeni bir sürümü var." +usageAmount: "Kullanım" +capacity: "Kapasite" +inUse: "Kullanılıyor" +editCode: "Kodu düzenle" +apply: "Uygula" +receiveAnnouncementFromInstance: "Bu sunucudan bildirimler alın" +emailNotification: "E-posta bildirimi" +publish: "Yayınla" +inChannelSearch: "Kanalda ara" +useReactionPickerForContextMenu: "Sağ tıklama ile tepki seçiciyi aç" +typingUsers: "{users} yazıyor..." +jumpToSpecifiedDate: "Belirli bir tarihe atla" +showingPastTimeline: "Şu anda eski bir Pano görüntüleniyor." +clear: "Temizle" +markAllAsRead: "Tümünü okundu olarak işaretle" +goBack: "Geri" +unlikeConfirm: "Cidden beğenini kaldırmak mı istiyorsun?" +fullView: "Tam görünüm" +quitFullView: "Tam ekranı kapat" +addDescription: "Açıklama ekle" +userPagePinTip: "Bireysel notların menüsünden “Profiline sabitle” seçeneğini seçerek notları burada görüntüleyebilirsin." +notSpecifiedMentionWarning: "Bu notta, alıcılar arasında yer almayan kullanıcılar hakkında bilgiler bulunmaktadır." +info: "Hakkında" +userInfo: "Kullanıcı hakkında" +unknown: "Bilinmiyor" +onlineStatus: "Çevrimiçi durumu" +hideOnlineStatus: "Çevrimiçi durumunu gizle" +hideOnlineStatusDescription: "Çevrimiçi durumunuzu gizlemek, arama gibi bazı özelliklerin kullanışlılığını azaltır." +online: "Online" +active: "Aktif" +offline: "Offline" +notRecommended: "Tavsiye edilmez" +botProtection: "Bot Koruması" +instanceBlocking: "Blocked/Silenced Instances" +selectAccount: "Hesap seç" +switchAccount: "Hesap değiştir" +enabled: "Aktif" +disabled: "Devre Dışı" +quickAction: "Hızlı eylemler" user: "Kullanıcı" -global: "Küresel" +administration: "Yönetim" +accounts: "Hesaplar" +switch: "Anahtar" +noMaintainerInformationWarning: "Bakımcı bilgileri yapılandırılmamıştır." +noInquiryUrlWarning: "Sorgu URL'si ayarlanmadı" +noBotProtectionWarning: "Bot koruması yapılandırılmamıştır." +configure: "Yeniden Yapılandır" +postToGallery: "Yeni galeri gönderisi oluştur" +postToHashtag: "Bu hashtag'e gönder" +gallery: "Galeri" +recentPosts: "Son gönderiler" +popularPosts: "Popüler gönderiler" +shareWithNote: "Notla paylaş" +ads: "Reklamlar" +expiration: "Son tarih" +startingperiod: "Başla" +memo: "Hatırlatıcı" +priority: "Öncelik" +high: "Yüksek" +middle: "Orta" +low: "Düşük" +emailNotConfiguredWarning: "E-posta adresi ayarlanmamış." +ratio: "Oran" +previewNoteText: "Önizlemeyi göster" +customCss: "Özel CSS" +customCssWarn: "Bu ayar, yalnızca ne işe yaradığını biliyorsanız kullanılmalıdır. Yanlış değerler girilmesi, istemcinin normal şekilde çalışmamasına neden olabilir." +global: "Global" squareAvatars: "Kare avatarlar" +sent: "Gönderilen" +received: "Alınan" +searchResult: "Arama sonuçları" +hashtags: "Hashtag'ler" +troubleshooting: "Sorun Giderme" +useBlurEffect: "UI'da bulanıklık efektleri kullanın" +learnMore: "Daha fazla bilgi edinin" +misskeyUpdated: "CherryPick güncellendi!" +whatIsNew: "Değişiklikleri göster" +translate: "Çevir" +translatedFrom: "{x}'ten çevrilmiştir." +accountDeletionInProgress: "Hesap silme işlemi şu anda devam ediyor." +usernameInfo: "Bu sunucudaki diğer hesaplardan hesabını ayıran bir isim. Alfabe (a~z, A~Z), rakamlar (0~9) veya alt çizgi (_) kullanabilirsin. Kullanıcı adları daha sonra değiştirilemez." +aiChanMode: "Ai Modu" +devMode: "Geliştirici modu" +keepCw: "İçerik uyarılarını sakla" +pubSub: "Yayın/Abonelik Hesapları" +lastCommunication: "Son iletişim" +resolved: "Çözülmüş" +unresolved: "Çözülmemiş" +breakFollow: "Takipçiyi kaldır" +breakFollowConfirm: "Bu takipçiyi ciddden silmek istiyor musun?" +itsOn: "Etkin" +itsOff: "Devre Dışı" +on: "Açık" +off: "Kapalı" +emailRequiredForSignup: "Kayıt için E-posta adresi gereklidir." +unread: "Okunmamış" +filter: "Filtre" +controlPanel: "Kontrol Paneli" +manageAccounts: "Hesapları Yönet" +makeReactionsPublic: "Tepki geçmişini herkese açık olarak ayarla" +makeReactionsPublicDescription: "Bu, geçmişteki tüm tepkilerinin listesini herkese açık hale getirecek." +classic: "Klasik" +muteThread: "Konuyu sessize al" +unmuteThread: "Konuyu sessizden çıkar" +followingVisibility: "Takip edilenlerin görünürlüğü" +followersVisibility: "Takipçilerin görünürlüğü" +continueThread: "Konunun devamını görüntüle" +deleteAccountConfirm: "Bu, hesabını geri dönüşü olmayan bir şekilde silecek. Devam etmek istiyor musun?" +incorrectPassword: "Yanlış şifre." +incorrectTotp: "Tek kullanımlık şifre yanlış veya süresi dolmuş." +voteConfirm: "\"{choice}\" için oyunuzu onaylıyor musunuz?" +hide: "Gizle" +useDrawerReactionPickerForMobile: "Mobil cihazlarda tepki seçiciyi çekmece olarak göster" +welcomeBackWithName: "Hoş geldin, {name}" +clickToFinishEmailVerification: "E-posta doğrulamasını tamamlamak için lütfen [{ok}] düğmesine tıklayın." +overridedDeviceKind: "Cihaz türü" +smartphone: "Akıllı telefon" +tablet: "Tablet" +auto: "Otomatik" +themeColor: "Örnek Ticker Rengi" +size: "Boyut" +numberOfColumn: "Sütun sayısı" searchByGoogle: "Arama" +instanceDefaultLightTheme: "Sunucu genelinde varsayılan açık tema" +instanceDefaultDarkTheme: "Sunucu genelinde varsayılan koyu tema" +instanceDefaultThemeDescription: "Tema kodunu nesne biçiminde girin." +mutePeriod: "Sessiz kalma süresi" +period: "Zaman sınırı" +indefinitely: "Kalıcı olarak" +tenMinutes: "10 dakika" +oneHour: "1 saat" +oneDay: "1 gün" +oneWeek: "1 hafta" +oneMonth: "1 ay" +threeMonths: "3 ay" +oneYear: "1 yıl" +threeDays: "3 gün" +reflectMayTakeTime: "Bunun yansıtılması biraz zaman alabilir." +failedToFetchAccountInformation: "Hesap bilgileri alınamadı" +rateLimitExceeded: "Hız sınırı aşıldı" +cropImage: "Görüntüyü kırp" +cropImageAsk: "Bu görüntüyü kırpmak ister misin?" +cropYes: "Kırp" +cropNo: "Olduğu gibi kullanın" file: "Dosyalar" +recentNHours: "Son {n} saat" +recentNDays: "Son {n} gün" +noEmailServerWarning: "E-posta sunucusu yapılandırılmamış." +thereIsUnresolvedAbuseReportWarning: "Çözülmemiş raporlar var." +recommended: "Önerilen" +check: "Kontrol" +driveCapOverrideLabel: "Bu kullanıcının Drive kapasitesini değiştir" +driveCapOverrideCaption: "Kapasiteyi varsayılan değere sıfırlamak için 0 veya daha düşük bir değer girin." +requireAdminForView: "Bunu görüntülemek için yönetici hesabıyla oturum açmanız gerekir." +isSystemAccount: "Sistem tarafından oluşturulan ve otomatik olarak işletilen bir hesap." +typeToConfirm: "Onaylamak için lütfen {x} girin." +deleteAccount: "Hesabı sil" +document: "Dokümantasyon" +numberOfPageCache: "Önbelleğe alınmış sayfa sayısı" +numberOfPageCacheDescription: "Bu sayıyı artırmak, kullanıcının cihazında daha fazla bellek kullanımı nedeniyle daha fazla yük oluşturmakla birlikte, kullanıcının rahatlığını artıracaktır." +logoutConfirm: "Çıkmak istediğinden emin misin?" +logoutWillClearClientData: "Oturumu kapatmak, tarayıcıdan istemcinin ayarlarını siler. Tekrar oturum açtığında ayarları geri yükleyebilmek için, ayarlarının otomatik yedeklenmesini etkinleştirmen gerekir." +lastActiveDate: "Son kullanımı" +statusbar: "Durum çubuğu" +pleaseSelect: "Bir seçenek seçin" +reverse: "Tersine" +colored: "Renkli" +refreshInterval: "Güncelleme aralığı" +label: "Etiket" +type: "Tür" +speed: "Hız" +slow: "Yavaş" +fast: "Hızlı" +sensitiveMediaDetection: "Hassas ortamların tespiti" +localOnly: "Yalnızca yerel" +remoteOnly: "Sadece uzaktan" +failedToUpload: "Yükleme başarısız" +cannotUploadBecauseInappropriate: "Bu dosya, dosyanın bazı kısımlarının uygunsuz olabileceği tespit edildiği için yüklenemiyor." +cannotUploadBecauseNoFreeSpace: "Drive kapasitesi yetersiz olduğu için yükleme başarısız oldu." +cannotUploadBecauseExceedsFileSizeLimit: "Bu dosya, dosya boyutu sınırını aştığı için yüklenemiyor." +cannotUploadBecauseUnallowedFileType: "Yetkisiz dosya türü nedeniyle yükleme yapılamıyor." +beta: "Beta" +enableAutoSensitive: "Otomatik olarak hassas olarak işaretleme" +enableAutoSensitiveDescription: "Mümkün olduğunda, Makine Öğrenimi yoluyla hassas ortamların otomatik olarak algılanmasını ve işaretlenmesini sağlar. Bu seçenek devre dışı bırakılmış olsa bile, örnek genelinde etkinleştirilebilir." +activeEmailValidationDescription: "E-posta adreslerinin daha sıkı bir şekilde doğrulanmasını sağlar. Bu, tek kullanımlık adreslerin kontrol edilmesini ve adresin gerçekten iletişim kurulabilir olup olmadığının kontrol edilmesini içerir. İşaretlenmediğinde, yalnızca e-postanın biçimi doğrulanır." +navbar: "Gezinti çubuğu" +shuffle: "Karıştır" +account: "Hesap" +move: "Taşı" pushNotification: "Push bildirimleri" subscribePushNotification: "Push bildirimlerini etkinleştir" unsubscribePushNotification: "Push bildirimlerini kapat" pushNotificationAlreadySubscribed: "Push bildirimleri zaten açık" pushNotificationNotSupported: "Push bildirimleri sunucu veya tarayıcı tarafından desteklenmiyor" +sendPushNotificationReadMessage: "Okunduktan sonra push bildirimlerini silin" +sendPushNotificationReadMessageCaption: "Bu, cihazınızın güç tüketimini artırabilir." +windowMaximize: "Maksimize et" +windowMinimize: "Minimize et" +windowRestore: "Geri yükle" +caption: "Alternatif metin" +loggedInAsBot: "Şu anda bot olarak oturum açmış durumdasınız." +tools: "Araçlar" +cannotLoad: "Yüklenemiyor" +numberOfProfileView: "Profil görüntülemeleri" +like: "Beğen" +unlike: "Beğenme" +numberOfLikes: "Beğeniler" +show: "Göster" +neverShow: "Bir daha gösterme" +remindMeLater: "Belki daha sonra" +didYouLikeMisskey: "CherryPick'i sevdin mi?" +pleaseDonate: "{host} ücretsiz yazılım CherryPick kullanmaktadır. CherryPick'in geliştirilmesinin devam edebilmesi için bağışlarınızı çok takdir ederiz!" +correspondingSourceIsAvailable: "İlgili kaynak kodu {anchor} adresinde mevcuttur." +roles: "Roller" +role: "Rol" noRole: "Rol bulunamadı" +normalUser: "Normal kullanıcı" +undefined: "Tanımlanmamış" +assign: "Atama" +unassign: "Atamayı kaldır" color: "Renk" +manageCustomEmojis: "Özel Emojileri Yönet" +manageAvatarDecorations: "Avatar süslerini yönet" +youCannotCreateAnymore: "Oluşturma sınırına ulaştınız." +cannotPerformTemporary: "Geçici olarak kullanılamıyor" +cannotPerformTemporaryDescription: "Bu işlem, yürütme sınırını aştığı için geçici olarak gerçekleştirilememekte. Lütfen bir süre bekle ve tekrar dene." +invalidParamError: "Geçersiz parametreler" +invalidParamErrorDescription: "İstek parametreleri geçersiz. Bu durum genellikle bir hata nedeniyle oluşur, ancak boyut sınırlarını aşan girdiler veya benzer nedenlerden de kaynaklanabilir." +permissionDeniedError: "İşlem reddedildi" +permissionDeniedErrorDescription: "Bu hesap bu işlemi gerçekleştirmek için gerekli izne sahip değildir." +preset: "Ön ayar" +selectFromPresets: "Ön ayarlardan seçim yapın" +custom: "Özel" +achievements: "Başarılar" +gotInvalidResponseError: "Geçersiz sunucu yanıtı" +gotInvalidResponseErrorDescription: "Sunucu erişilemez durumda olabilir veya bakım çalışması yapılmaktadır. Lütfen daha sonra tekrar dene." +thisPostMayBeAnnoying: "Bu not başkalarını rahatsız edebilir." +thisPostMayBeAnnoyingHome: "Ana panoya gönder" +thisPostMayBeAnnoyingCancel: "İptal" +thisPostMayBeAnnoyingIgnore: "Yine de gönder" +collapseRenotes: "Daha önce görüntülenen Renote'lari kısaltılmış olarak göster" +collapseRenotesDescription: "Zaten yanıtladığın veya renote aldığın notları kapat." +internalServerError: "İç Sunucu Hatası" +internalServerErrorDescription: "Sunucu beklenmedik bir hatayla karşılaştı." +copyErrorInfo: "Hata ayrıntılarını kopyala" +joinThisServer: "Kaydol" +exploreOtherServers: "Diğer sunucuları keşfet" +letsLookAtTimeline: "Pano'ya bir göz atın" +disableFederationConfirm: "Federasyonu cidden devre dışı bırakmak istiyor musun?" +disableFederationConfirmWarn: "Federasyondan ayrılsa bile, aksi belirtilmedikçe gönderiler herkese açık olmaya devam edecek. Genellikle bunu yapmanız gerekmez." +disableFederationOk: "Devre Dışı" +invitationRequiredToRegister: "Bu etkinlik davetle katılımlıdır. Geçerli bir davet kodu girerek kaydolmanız gerekir." +emailNotSupported: "Bu sunucu, E-Posta göndermeyi desteklemiyor." +postToTheChannel: "Kanalına gönder" +cannotBeChangedLater: "Bu daha sonra değiştirilemez." +reactionAcceptance: "Tepki Kabulü" +likeOnly: "Sadece beğeniler" +likeOnlyForRemote: "Tüm (Yalnızca uzak sunucu için beğeniler)" +nonSensitiveOnly: "Hassas olmayanlar için" +nonSensitiveOnlyForLocalLikeOnlyForRemote: "Yalnızca hassas olmayanlar (Yalnızca uzaktan beğeniler)" +rolesAssignedToMe: "Bana atanan roller" +resetPasswordConfirm: "Şifreni gerçekten sıfırlamak istiyor musun?" +sensitiveWords: "Hassas kelimeler" +sensitiveWordsDescription: "Yapılandırılan kelimelerden herhangi birini içeren tüm notların görünürlüğü otomatik olarak “Ana Sayfa” olarak ayarlanacaktır. Satır sonları ile ayırarak birden fazla not listeleyebilirsin." +sensitiveWordsDescription2: "Boşluk kullanmak AND ifadeleri oluşturur ve anahtar kelimeleri eğik çizgi ile çevrelemek bunları düzenli ifadeye dönüştürür." +prohibitedWords: "Yasaklanmış kelimeler" +prohibitedWordsDescription: "Belirlenen kelime(ler)i içeren bir not göndermeye çalışıldığında hata verir. Birden fazla kelime, yeni satırla ayrılmış olarak ayarlanabilir." +prohibitedWordsDescription2: "Boşluk kullanmak AND ifadeleri oluşturur ve anahtar kelimeleri eğik çizgi ile çevrelemek bunları düzenli ifadeye dönüştürür." +hiddenTags: "Gizli hashtag'ler" +hiddenTagsDescription: "Trend listesinde gösterilmeyecek etiketleri seçin.\nSatırlarla birden fazla etiket kaydedilebilir." +notesSearchNotAvailable: "Not arama özelliği kullanılamıyor." +usersSearchNotAvailable: "Kullanıcı araması mevcut değildir." +license: "Lisans" +unfavoriteConfirm: "Cidden favorilerden kaldırmak istiyor musunuz?" +myClips: "Kliplerim" +drivecleaner: "Drive Temizleyici" +retryAllQueuesNow: "Tüm kuyrukları yeniden çalıştırmayı deneyin" +retryAllQueuesConfirmTitle: "Cidden hepsini tekrar denemek istiyor musunuz?" +retryAllQueuesConfirmText: "Bu, sunucu yükünü geçici olarak artıracaktır." +enableChartsForRemoteUser: "Uzak kullanıcı veri grafikleri oluşturun" +enableChartsForFederatedInstances: "Uzak sunucu veri grafikleri oluşturun" +enableStatsForFederatedInstances: "Uzak sunucu istatistiklerini alın" +showClipButtonInNoteFooter: "Not eylem menüsüne “Klip” ekle" +reactionsDisplaySize: "Tepki ekran boyutu" +limitWidthOfReaction: "Tepkilerin maksimum genişliğini sınırla ve bunları küçültülmüş boyutta görüntüle." +noteIdOrUrl: "Not ID veya URL" +video: "Video" +videos: "Videolar" +audio: "Ses" +audioFiles: "Ses Dosyası" +dataSaver: "Veri Tasarrufu" +accountMigration: "Hesap Taşıma" +accountMoved: "Bu kullanıcı yeni bir hesaba taşındı:" +accountMovedShort: "Bu hesap taşınmıştır." +operationForbidden: "İşlem yasak" +forceShowAds: "Her zaman reklamları göster" addMemo: "Kısa not ekle" +editMemo: "Kısa not düzenle" +reactionsList: "Tepkiler" +renotesList: "Renote'lar" +notificationDisplay: "Bildirimler" +leftTop: "Sol üst" +rightTop: "Sağ üst" +leftBottom: "Sol alt" +rightBottom: "Sağ alt" +stackAxis: "Yığınlama yönü" +vertical: "Dikey" +horizontal: "Yatay" +position: "Pozisyon" +serverRules: "Sunucu kuralları" +pleaseConfirmBelowBeforeSignup: "Bu sunucuya kaydolmak için aşağıdakileri gözden geçirip kabul etmelisin:" +pleaseAgreeAllToContinue: "Devam etmek için yukarıdaki tüm alanları kabul etmelisin." +continue: "Devam et" +preservedUsernames: "Rezerve edilmiş kullanıcı adları" +preservedUsernamesDescription: "Rezervasyon yapmak için kullanıcı adlarını satır sonlarıyla ayırarak listele. Bu kullanıcı adları normal hesap oluşturma sırasında kullanılamaz hale gelir, ancak yöneticiler tarafından manuel olarak hesap oluşturmak için kullanılabilir. Bu kullanıcı adlarını kullanan mevcut hesaplar etkilenmez." +createNoteFromTheFile: "Bu dosyadan not oluşturun" +archive: "Arşiv" +archived: "Arşivle" +unarchive: "Arşivden çıkar" +channelArchiveConfirmTitle: "Cidden {name} arşivlemek mi istiyorsun?" +channelArchiveConfirmDescription: "Arşivlenmiş bir kanal artık kanal listesinde veya arama sonuçlarında görünmeyecektir. Ayrıca, bu kanala yeni gönderiler eklenemeyecek." +thisChannelArchived: "Bu kanal arşivlenmiş." +displayOfNote: "Not ekranı" +initialAccountSetting: "Profil ayarları" +youFollowing: "Takip edildi" +preventAiLearning: "Makine Öğreniminde (Üretken Ai) kullanımını reddet" +preventAiLearningDescription: "Tarayıcılardan, makine öğrenimi (Tahminsel / Üretken Ai) veri kümelerinde yayınlanan metin veya görsel materyalleri vb. kullanmamalarını talep eder. Bu, ilgili içeriğe “noai” HTML-Response bayrağı eklenerek gerçekleştirilir. Ancak, bu bayrakla tam bir önleme sağlanamaz, çünkü bu bayrak basitçe göz ardı edilebilir." +options: "Seçenekler" +specifyUser: "Belirli kullanıcı" +lookupConfirm: "Yukarı bakmak ister misin?" +openTagPageConfirm: "Bir hashtag sayfası açmak ister misin?" +specifyHost: "Belirli ana bilgisayar" +failedToPreviewUrl: "Önizleme yapılamadı" +update: "Güncelle" +rolesThatCanBeUsedThisEmojiAsReaction: "Bu emojiyi tepki olarak kullanabileceğin roller" +rolesThatCanBeUsedThisEmojiAsReactionEmptyDescription: "Herhangi bir rol belirtilmezse, herkes bu emojiyi tepki olarak kullanabilir." +rolesThatCanBeUsedThisEmojiAsReactionPublicRoleWarn: "Bu roller herkese açık olmalıdır." +cancelReactionConfirm: "Tepkini cidden silmek istiyor musun?" +changeReactionConfirm: "Tepkini cidden değiştirmek istiyor musun?" +later: "Daha sonra" +goToMisskey: "CherryPick'e" +additionalEmojiDictionary: "Ek emoji sözlükleri" +installed: "Yüklendi" +branding: "Markalaşma" +enableServerMachineStats: "Sunucu donanım istatistiklerini yayınla" +enableIdenticonGeneration: "Kullanıcı identicon oluşturmayı etkinleştir" +turnOffToImprovePerformance: "Devre dışı bırakma, daha yüksek performansa yol açabilir." +createInviteCode: "Davet Kodu oluştur" +createWithOptions: "Seçeneklerle oluştur" +createCount: "Davet sayısı" +inviteCodeCreated: "Davet oluşturuldu" +inviteLimitExceeded: "Oluşturulabilecek davetiyelerin maksimum sayısına ulaştın." +createLimitRemaining: "{limit} Davet limiti kaldı" +inviteLimitResetCycle: "Bu limit {time} tarihinde {limit} değerine sıfırlanacaktır." +expirationDate: "Son kullanma tarihi" +noExpirationDate: "Son kullanma tarihi yok" +inviteCodeUsedAt: "Kullanılan davet kodu" +registeredUserUsingInviteCode: "Kullanılan davet" +waitingForMailAuth: "E-Posta doğrulama beklemede" +inviteCodeCreator: "Davet oluşturuldu" +usedAt: "Kullanıldığı yer" +unused: "Kullanılmamış" +used: "Kullanılmış" +expired: "Süresi dolmuş" +doYouAgree: "Katılıyor musunuz?" +beSureToReadThisAsItIsImportant: "Lütfen bu önemli bilgileri okuyun." +iHaveReadXCarefullyAndAgree: "“{x}” metnini okudum ve kabul ediyorum." +dialog: "Diyalog" icon: "Avatar" -replies: "yanıt" -renotes: "vazgeçme" +forYou: "Senin için" +currentAnnouncements: "Güncel duyurular" +pastAnnouncements: "Geçmiş duyurular" +youHaveUnreadAnnouncements: "Okunmamış duyurular var." +useSecurityKey: "Güvenlik anahtarını veya şifreni kullanmak için lütfen tarayıcının veya cihazının talimatlarını izle." +replies: "Yanıtla" +renotes: "Renote'lar" +loadReplies: "Yanıtları göster" +loadConversation: "Konuşmayı göster" +pinnedList: "Sabitlenmiş liste" +keepScreenOn: "Ekranı açık tut" +verifiedLink: "Bağlantı sahipliği doğrulanmıştır." +notifyNotes: "Yeni notlar hakkında bildirimde bulun" +unnotifyNotes: "Yeni notlar hakkında bildirim almayı durdur" +authentication: "Kimlik doğrulama" +authenticationRequiredToContinue: "Devam etmek için lütfen kimlik doğrulaması yapın." +dateAndTime: "Zaman damgası" +showRenotes: "Renote'ları göster" +edited: "Düzenlendi" +notificationRecieveConfig: "Bildirim Ayarları" +mutualFollow: "Karşılıklı takip" +followingOrFollower: "Takip eden veya takipçi" +fileAttachedOnly: "Yalnızca dosya içeren notlar" +showRepliesToOthersInTimeline: "Pano'da diğer kişilere verilen yanıtları göster" +hideRepliesToOthersInTimeline: "Pano'dan diğer kişilerin yanıtlarını gizle" +showRepliesToOthersInTimelineAll: "Pano'da takip ettiğin herkesin diğerlerine verdiği yanıtları göster" +hideRepliesToOthersInTimelineAll: "Pano'da takip ettiğin herkesten diğer kişilere verilen yanıtları gizle" +confirmShowRepliesAll: "Bu işlem geri alınamaz. Takip ettiğin herkesin yanıtlarını panoda diğer kullanıcılara göstermek istiyor musun?" +confirmHideRepliesAll: "Bu işlem geri alınamaz. Şu anda takip ettiğin tüm kullanıcıların yanıtlarını panoda cidden göstermeyecek misin?" +externalServices: "Dış Hizmetler" +sourceCode: "Kaynak kodu" +sourceCodeIsNotYetProvided: "Kaynak kodu henüz mevcut değildir. Bu sorunu gidermek için yöneticiyle iletişime geçin." +repositoryUrl: "Depo URL'si" +repositoryUrlDescription: "CherryPick'i olduğu gibi kullanıyorsanız (kaynak kodunda herhangi bir değişiklik yapmadan), https://github.com/kokonect-link/cherrypick adresini girin." +repositoryUrlOrTarballRequired: "Bir depo yayınlamadıysanız, bunun yerine bir tarball sağlamalısınız. Daha fazla bilgi için .config/example.yml dosyasına bakın." +feedback: "Feedback" +feedbackUrl: "Geri Bildirim URL'si" +impressum: "Yayıncı Bilgileri" +impressumUrl: "Yayıncı Bilgileri URL'si" +impressumDescription: "Almanya gibi bazı ülkelerde, ticari web sitelerinde işletmeci iletişim bilgilerinin (Yayıncı) yer alması yasal olarak zorunludur." +privacyPolicy: "Gizlilik Politikası" +privacyPolicyUrl: "Gizlilik Politikası URL'si" +tosAndPrivacyPolicy: "Hizmet Şartları ve Gizlilik Politikası" +avatarDecorations: "Avatar süsleri" +attach: "Ek" +detach: "Kaldır" +detachAll: "Tümünü Kaldır" +angle: "Açı" +flip: "Çevir" +showAvatarDecorations: "Avatar süslerini göster" +releaseToRefresh: "Yenilemek için serbest bırak" +refreshing: "Yenileniyor..." +pullDownToRefresh: "Yenilemek için aşağı çekin" +useGroupedNotifications: "Gruplandırılmış bildirimleri göster" +emailVerificationFailedError: "E-posta adresi doğrulanırken bir sorun oluştu. Bağlantının geçerlilik süresi dolmuş olabilir." +cwNotationRequired: "“İçeriği gizle” seçeneği etkinleştirilirse, bir açıklama sağlanmalı." +doReaction: "Tepki ekle" +code: "Kod" +reloadRequiredToApplySettings: "Ayarları uygulamak için yeniden yükleme gereklidir." +remainingN: "Kalan: {n}" +overwriteContentConfirm: "Mevcut içeriği üzerine yazmak istediğinden emin misin?" +seasonalScreenEffect: "Mevsimsel Ekran Efekti" +decorate: "Süsle" +addMfmFunction: "MFC ekle" +enableQuickAddMfmFunction: "Gelişmiş MFC seçiciyi göster" +bubbleGame: "Kabarcık Oyunu" +sfx: "Ses Efektleri" +soundWillBePlayed: "Ses çalınacaktır" +showReplay: "Tekrarı izle" +replay: "Tekrar oynat" +replaying: "Tekrar gösteriliyor" +endReplay: "Tekrardan çık" +copyReplayData: "Tekrar oynatma verilerini kopyala" +ranking: "Sıralama" +lastNDays: "Son {n} gün" +backToTitle: "Başlığa geri dön" +hemisphere: "Yaşadığınız yer" +withSensitive: "Hassas dosyalara notlar ekle" +userSaysSomethingSensitive: "{name} tarafından gönderilen mesaj hassas içerik barındırmaktadır." +enableHorizontalSwipe: "Kaydırarak sekmeler arasında geçiş yapın" +loading: "Yükleniyor" +surrender: "İptal" +gameRetry: "Tekrar dene" +notUsePleaseLeaveBlank: "Kullanılmıyorsa boş bırakın." +useTotp: "Tek Kullanımlık Şifreyi Girin" +useBackupCode: "Yedek kodları kullanın" +launchApp: "Uygulamayı başlatın" +useNativeUIForVideoAudioPlayer: "Video ve ses oynatımı için tarayıcı kullanıcı arayüzünü kullan" +keepOriginalFilename: "Orijinal dosya adını koru" +keepOriginalFilenameDescription: "Bu ayarı kapatırsan, dosya yüklediğinde dosya adları otomatik olarak rastgele bir dizeyle değiştirilecek." +noDescription: "Açıklama yok" +alwaysConfirmFollow: "Takip ederken her zaman onaylayın" +inquiry: "İletişim" +tryAgain: "Lütfen daha sonra tekrar dene." +confirmWhenRevealingSensitiveMedia: "Confirm when revealing sensitive media" +sensitiveMediaRevealConfirm: "Bu hassas bir medya olabilir. Açıklamakta emin misin?" +createdLists: "Oluşturulan listeler" +createdAntennas: "Oluşturulan antenler" +fromX: "{x}'den" +genEmbedCode: "Gömme kodu oluştur" +noteOfThisUser: "Bu kullanıcının notları" +clipNoteLimitExceeded: "Bu klibe daha fazla not eklenemez." +performance: "Başarım" +modified: "Değiştirilmiş" +discard: "At" +thereAreNChanges: "{n} değişiklik var." +signinWithPasskey: "Geçiş Anahtarı ile giriş yapın" +unknownWebAuthnKey: "Bilinmeyen Geçiş Anahtarı" +passkeyVerificationFailed: "Geçiş Anahtarı doğrulama başarısız oldu." +passkeyVerificationSucceededButPasswordlessLoginDisabled: "Geçiş anahtarı doğrulaması başarılı oldu ancak şifresiz oturum açma devre dışıdır." +messageToFollower: "Takipçilere mesaj" +target: "Hedef" +testCaptchaWarning: "Bu işlev CAPTCHA testi amacıyla tasarlanmıştır.\nÜretim ortamında kullanmayın." +prohibitedWordsForNameOfUser: "Kullanıcı adları için yasaklanmış kelimeler" +prohibitedWordsForNameOfUserDescription: "Bu listedeki dizilerden herhangi biri kullanıcının adında yer alıyorsa, ad reddedilecektir. Moderatör ayrıcalıklarına sahip kullanıcılar bu kısıtlamadan etkilenmez." +yourNameContainsProhibitedWords: "Adınız yasaklanmış kelimeler içeriyor" +yourNameContainsProhibitedWordsDescription: "Bu adı kullanmak istiyorsan, lütfen sunucu yöneticinizle iletişime geç." +thisContentsAreMarkedAsSigninRequiredByAuthor: "Yazar tarafından görüntülemek için oturum açma gerektirir." +lockdown: "Karantina" +pleaseSelectAccount: "Hesap seçin" +availableRoles: "Mevcut roller" +acknowledgeNotesAndEnable: "Önlemleri anladıktan sonra açın." +federationSpecified: "Bu sunucu, beyaz liste federasyonunda çalıştırılmaktadır. Yönetici tarafından belirlenen sunucular dışında diğer sunucularla etkileşim kurmak yasaktır." +federationDisabled: "Bu sunucuda federasyon devre dışıdır. Diğer sunuculardaki kullanıcılarla etkileşim kuramazsınız." +draft: "Taslaklar" +confirmOnReact: "Tepki verirken onaylayın" +reactAreYouSure: "“{emoji}” tepkisini eklemek ister misin?" +markAsSensitiveConfirm: "Bu medyayı hassas olarak ayarlamak ister misin?" +unmarkAsSensitiveConfirm: "Bu medya için hassas işaretini kaldırmak ister misin?" +preferences: "Tercihler" +accessibility: "Erişilebilirlik" +preferencesProfile: "Tercihler profili" +copyPreferenceId: "Tercih ID kopyala" +resetToDefaultValue: "Varsayılana dön" +overrideByAccount: "Hesap tarafından geçersiz kılma" +untitled: "İsimsiz" +noName: "İsim yok" +skip: "Atla" +restore: "Geri yükle" +syncBetweenDevices: "Cihazlar arasında senkronizasyon" +preferenceSyncConflictTitle: "Yapılandırılan değer sunucuda mevcuttur." +preferenceSyncConflictText: "Senkronizasyon etkin ayarlar, değerlerini sunucuya kaydeder. Ancak, sunucuda mevcut değerler bulunmaktadır. Hangi değerleri üzerine yazmak istersin?" +preferenceSyncConflictChoiceMerge: "Birleştir" +preferenceSyncConflictChoiceServer: "Sunucuda yapılandırılan değer" +preferenceSyncConflictChoiceDevice: "Cihazda yapılandırılan değer" +preferenceSyncConflictChoiceCancel: "Senkronizasyonu etkinleştirmeyi iptal et" +paste: "Yapıştır" +emojiPalette: "Emoji paleti" +postForm: "Gönderim formu" +textCount: "Karakter sayısı" +information: "Hakkında" +chat: "Sohbet" +directMessage: "Kullanıcıyla sohbet et" +migrateOldSettings: "Eski istemci ayarlarını taşıma" +migrateOldSettings_description: "Bu işlem otomatik olarak yapılmalıdır, ancak herhangi bir nedenle geçiş başarısız olursa, geçiş işlemini manuel olarak kendin başlatabilirsin. Mevcut yapılandırma bilgileri üzerine yazılacaktır." +compress: "Sıkıştır" +right: "Sağ" +bottom: "Alt" +top: "Üst" +embed: "Göm" +settingsMigrating: "Ayarlar taşınıyor, lütfen bir dakika bekle... (Daha sonra Ayarlar→Diğerler→Eski ayarları taşı seçeneğine giderek manuel olarak da taşıyabilirsin)" +readonly: "Sadece okuma" +goToDeck: "Güverteye Dön" +federationJobs: "Federasyon İşleri" +driveAboutTip: "Drive'da, geçmişte yüklediğin dosyaların bir listesi görüntülenir.
\nBu dosyaları notlara eklerken yeniden kullanabilir veya daha sonra paylaşmak üzere önceden yükleyebilirsin.
\nBir dosyayı silerken dikkatli ol, çünkü kullanıldığı her yerde (notlar, sayfalar, avatarlar, afişler vb.) mevcut olmayacakt.
\nAyrıca dosyalarını düzenlemek için klasörler oluşturabilirsin." +scrollToClose: "Kaydırarak kapatın" +advice: "Tavsiye" +realtimeMode: "Gerçek zamanlı mod" +turnItOn: "Aç" +turnItOff: "Kapat" +emojiMute: "Emoji ses kapat" +emojiUnmute: "Emoji ses aç" +muteX: "Sessiz {x}" +unmuteX: "Sesi aç {x}" +abort: "İptal" +tip: "İpucu & Püf Nokta" +redisplayAllTips: "Tüm “İpucu & Püf Nokta” tekrar göster" +hideAllTips: "Tüm “İpucu & Püf Nokta” gizle" +defaultImageCompressionLevel: "Varsayılan görüntü sıkıştırma düzeyi" +defaultImageCompressionLevel_description: "Düşük seviye görüntü kalitesini korur ancak dosya boyutunu artırır.
Yüksek seviye dosya boyutunu azaltır ancak görüntü kalitesini düşürür." +inMinutes: "Dakika(lar)" +inDays: "Gün(ler)" +safeModeEnabled: "Güvenli mod etkinleştirildi" +pluginsAreDisabledBecauseSafeMode: "Güvenli mod etkinleştirildiği için tüm eklentiler devre dışı bırakılmıştır." +customCssIsDisabledBecauseSafeMode: "Güvenli mod etkin olduğu için özel CSS uygulanmıyor." +themeIsDefaultBecauseSafeMode: "Güvenli mod etkinken, varsayılan tema kullanılır. Güvenli modu devre dışı bırakmak bu değişiklikleri geri alır." +thankYouForTestingBeta: "Beta sürümünü test ettiğin için teşekkür ederiz!" +widgets: "Widget'lar" +_order: + newest: "Önce yeni" + oldest: "Önce eski" _chat: - home: "Ana sayfa" + noMessagesYet: "Henüz mesaj yok" + newMessage: "Yeni mesaj" + individualChat: "Özel Sohbet" + individualChat_description: "Başka bir kişiyle özel sohbet edin." + roomChat: "Sohbet Odası" + roomChat_description: "Birden fazla kişinin katılabileceği bir sohbet odası.\nÖzel sohbetlere izin vermeyen kişileri de davet edebilirsin, ancak davetini kabul etmeleri gerekir." + createRoom: "Oda Oluştur" + inviteUserToChat: "Kullanıcıları sohbete davet edin" + yourRooms: "Oluşturulan odalar" + joiningRooms: "Katıldığı odalar" + invitations: "Davet" + noInvitations: "Davet yok" + history: "Tarih" + noHistory: "Geçmiş bilgisi mevcut değil" + noRooms: "Oda bulunamadı" + inviteUser: "Kullanıcıları Davet Et" + sentInvitations: "Gönderilen Davetler" + join: "Katıl" + ignore: "Yoksay" + leave: "Odadan çık" + members: "Üyeler" + searchMessages: "Mesajları ara" + home: "Ana Sayfa" + send: "Gönder" + newline: "Yeni satır" + muteThisRoom: "Sessiz oda" + deleteRoom: "Odayı sil" + chatNotAvailableForThisAccountOrServer: "Bu sunucuda veya bu hesapta sohbet özelliği etkin değildir." + chatIsReadOnlyForThisAccountOrServer: "Bu sunucuda veya bu hesapta sohbet okunur modundadır. Yeni mesaj yazamaz veya sohbet odası oluşturamaz/katılamazsınız." + chatNotAvailableInOtherAccount: "Sohbet işlevi diğer kullanıcı için devre dışı bırakılmıştır." + cannotChatWithTheUser: "Bu kullanıcıyla sohbet başlatılamıyor." + cannotChatWithTheUser_description: "Sohbet kullanılamıyor veya karşı taraf sohbeti etkinleştirmedi." + youAreNotAMemberOfThisRoomButInvited: "Bu odanın katılımcısı değilsin, ancak bir davet aldın. Lütfen daveti kabul ederek katıl." + doYouAcceptInvitation: "Daveti kabul ediyor musunuz?" + chatWithThisUser: "Kullanıcıyla sohbet et" + thisUserAllowsChatOnlyFromFollowers: "Bu kullanıcı yalnızca takipçilerinden gelen sohbetleri kabul eder." + thisUserAllowsChatOnlyFromFollowing: "Bu kullanıcı, yalnızca takip ettiği kullanıcılardan gelen sohbetleri kabul eder." + thisUserAllowsChatOnlyFromMutualFollowing: "Bu kullanıcı, yalnızca karşılıklı takip eden kullanıcıların sohbetlerini kabul eder." + thisUserNotAllowedChatAnyone: "Bu kullanıcı kimseyle sohbet etmiyor." + chatAllowedUsers: "Sohbet etmesine izin verilecek kişiler" + chatAllowedUsers_note: "Bu ayardan bağımsız olarak, sohbet mesajı gönderdiğin herkesle sohbet edebilirsin." + _chatAllowedUsers: + everyone: "Herkes" + followers: "Sadece takipçilerin" + following: "Only users you are following" + mutual: "Sadece takiplerin" + none: "Kimse" +_emojiPalette: + palettes: "Palet" + enableSyncBetweenDevicesForPalettes: "Cihazlar arasında palet senkronizasyonunu etkinleştir" + paletteForMain: "Ana palet" + paletteForReaction: "Reaksiyon paleti" +_settings: + driveBanner: "Drive'ı yönetebilir ve yapılandırabilir, kullanımı kontrol edebilir ve dosya yükleme ayarlarını yapılandırabilirsin." + pluginBanner: "Eklentilerle istemci özelliklerini genişletebilirsin. Eklentileri yükleyebilir, ayrı ayrı yapılandırabilir ve yönetebilirsin." + notificationsBanner: "Sunucudan gelen bildirimlerin türlerini ve kapsamını ve push bildirimlerini yapılandırabilirsin." + api: "API" + webhook: "Webhook" + serviceConnection: "Hizmet entegrasyonu" + serviceConnectionBanner: "Dış uygulamalar veya hizmetlerle entegrasyon sağlamak için erişim belirteçlerini ve Webhook'ları yönetin ve yapılandırın." + accountData: "Hesap verileri" + accountDataBanner: "Hesap verilerini yönetmek için dışa ve içe aktarma." + muteAndBlockBanner: "İçeriği gizlemek ve belirli kullanıcıların eylemlerini kısıtlamak için ayarları yapılandırabilir ve yönetebilirsin." + accessibilityBanner: "İstemci, görünüm ve davranışları açısından en iyi şekilde kullanılmak üzere kişiselleştirilebilir ve ayarlanabilir." + privacyBanner: "Hesap gizliliği ile ilgili ayarları, örneğin içerik görünürlüğü, bulunabilirlik ve takip onayı gibi ayarları yapılandırabilirsin." + securityBanner: "Şifre, oturum açma yöntemleri, kimlik doğrulama uygulamaları ve Passkeys gibi hesap güvenliği ile ilgili ayarları yapılandırabilirsin." + preferencesBanner: "İstediğin şekilde istemcinin genel davranışını yapılandırabilirsin." + appearanceBanner: "İstemcinin görünüm ve ekran ayarlarını tercihlerini göre yapılandırabilirsin." + soundsBanner: "İstemcide oynatma için ses ayarlarını yapılandırabilirsin." + timelineAndNote: "Pano ve not" + makeEveryTextElementsSelectable: "Tüm metin öğelerini seçilebilir hale getir" + makeEveryTextElementsSelectable_description: "Bunu etkinleştirmek bazı durumlarda kullanılabilirliği azaltabilir." + useStickyIcons: "Kaydırma sırasında simgeleri takip et" + enableHighQualityImagePlaceholders: "Yüksek kaliteli görüntüler için yer tutucuları göster" + uiAnimations: "UI Animasyonları" + showNavbarSubButtons: "Navigasyon çubuğunda alt düğmeleri göster" + ifOn: "Açıkken" + ifOff: "Kapalıyken" + enableSyncThemesBetweenDevices: "Yüklü temaları cihazlar arasında senkronize edin" + enablePullToRefresh: "Yenilemek için çekin" + enablePullToRefresh_description: "Fareyi kullanırken, kaydırma tekerleğini basılı tutarken sürükle." + realtimeMode_description: "Sunucu ile bağlantı kurar ve içeriği gerçek zamanlı olarak günceller. Bu, trafik ve bellek tüketimini artırabilir." + contentsUpdateFrequency: "İçerik erişim sıklığı" + contentsUpdateFrequency_description: "Değer ne kadar yüksek olursa içerik o kadar sık güncellenir, ancak bu durum performansı düşürür ve trafik ile bellek tüketimini artırır." + contentsUpdateFrequency_description2: "Gerçek zamanlı mod açık olduğunda, bu ayardan bağımsız olarak içerik gerçek zamanlı olarak güncellenir." + showUrlPreview: "URL önizlemesi" + showAvailableReactionsFirstInNote: "Mevcut tepkileri en üstte göster." + showPageTabBarBottom: "Sayfa sekme çubuğunu aşağıda göster" + _chat: + showSenderName: "Gönderenin adını göster" + sendOnEnter: "Enter tuşuna basarak gönderin" +_preferencesProfile: + profileName: "Profil adı" + profileNameDescription: "Bu cihazı tanımlayan bir ad belirle." + profileNameDescription2: "Örnek: “Ana bilgisayar”, “Akıllı telefon”" + manageProfiles: "Profilleri Yönet" +_preferencesBackup: + autoBackup: "Otomatik yedekleme" + restoreFromBackup: "Yedeklemeden geri yükle" + noBackupsFoundTitle: "Yedekleme bulunamadı" + noBackupsFoundDescription: "Otomatik olarak oluşturulan yedekleme bulunamadı, ancak manuel olarak bir yedekleme dosyası kaydettiysen, bunu içe aktarabilir ve geri yükleyebilirsin." + selectBackupToRestore: "Geri yüklemek için bir yedekleme seçin" + youNeedToNameYourProfileToEnableAutoBackup: "Otomatik yedeklemeyi etkinleştirmek için bir profil adı ayarlanmalıdır." + autoPreferencesBackupIsNotEnabledForThisDevice: "Bu cihazda ayarların otomatik yedeklemesi etkinleştirilmemiş." + backupFound: "Ayarların yedeği bulundu" +_accountSettings: + requireSigninToViewContents: "İçeriği görüntülemek için oturum açmanız gerekir." + requireSigninToViewContentsDescription1: "Oluşturduğun tüm notları ve diğer içeriği görüntülemek için oturum açman gerekir. Bu, tarayıcıların bilgilerini toplamasına engel olacaktır." + requireSigninToViewContentsDescription2: "İçerik, URL önizlemelerinde (OGP), web sayfalarına gömülü olarak veya not alıntıları desteklemeyen sunucularda görüntülenmeyecek." + requireSigninToViewContentsDescription3: "Bu kısıtlamalar, diğer uzak sunuculardan gelen birleştirilmiş içerik için geçerli olmayabilir." + makeNotesFollowersOnlyBefore: "Geçmiş notların yalnızca takipçilere gösterilmesini sağlayın" + makeNotesFollowersOnlyBeforeDescription: "Bu özellik etkinleştirildiğinde, yalnızca takipçiler belirlenen tarih ve saatten sonra veya belirlenen süre boyunca görünür olan notları görebilir. Bu özellik devre dışı bırakıldığında, notun yayın durumu da geri yüklenir." + makeNotesHiddenBefore: "Geçmiş notları gizli yap" + makeNotesHiddenBeforeDescription: "Bu özellik etkinleştirildiğinde, belirlenen tarih ve saatten geçmiş olan veya yalnızca sizin görebildiğiniz notlar. Bu özellik devre dışı bırakıldığında, notun yayın durumu da geri yüklenecek." + mayNotEffectForFederatedNotes: "Uzak sunucuya bağlı notlar etkilenmeyebilir." + mayNotEffectSomeSituations: "Bu kısıtlamalar basitleştirilmiştir. Uzaktaki bir sunucuda görüntüleme veya moderasyon sırasında gibi bazı durumlarda geçerli olmayabilir." + notesHavePassedSpecifiedPeriod: "Belirtilen sürenin geçtiğini unutmayın." + notesOlderThanSpecifiedDateAndTime: "Belirtilen tarih ve saatten önceki notlar" +_abuseUserReport: + forward: "İleri" + forwardDescription: "Raporu, anonim bir sistem hesabı olarak uzak bir sunucuya iletin." + resolve: "Çözüm" + accept: "Kabul et" + reject: "Reddet" + resolveTutorial: "Raporun içeriği meşruysa, “Kabul Et” seçeneğini seçerek sorunu çözülmüş olarak işaretle.\nRaporun içeriği meşru değilse, “Reddet” seçeneğini seçerek raporu yok say." _delivery: - stop: "Askıya alınmış" + status: "Teslimat durumu" + stop: "Askıya al" + resume: "Teslimat özgeçmişi" _type: none: "Paylaşım" + manuallySuspended: "Manuel olarak askıya alınmış" + goneSuspended: "Sunucu, sunucunun silinmesi nedeniyle askıya alınmıştır." + autoSuspendedForNotResponding: "Sunucu yanıt vermediği için askıya alınmıştır." + softwareSuspended: "Bu yazılım artık dağıtılmadığı için askıya alınmıştır." +_bubbleGame: + howToPlay: "Nasıl oynanır" + hold: "Tut" + _score: + score: "Skor" + scoreYen: "Kazanılan para miktarı" + highScore: "Yüksek puan" + maxChain: "Maksimum zincir sayısı" + yen: "{yen} Yen" + estimatedQty: "{qty} Adet" + scoreSweets: "{onigiriQtyWithUnit} Onigiri" + _howToPlay: + section1: "Konumu ayarlayın ve nesneyi kutuya bırakın." + section2: "Aynı türden iki nesne birbirine dokunduğunda, farklı bir nesneye dönüşür ve puan kazanırsınız." + section3: "Kutu dolduğunda oyun biter. Kutuyu doldurmadan nesneleri birleştirerek yüksek puan almaya çalış!" +_announcement: + forExistingUsers: "Sadece mevcut kullanıcılar" + forExistingUsersDescription: "Bu duyuru, etkinleştirildiğinde yalnızca yayınlandığı anda mevcut olan kullanıcılara gösterilecek. Devre dışı bırakıldığında, yayınlandıktan sonra yeni kaydolan kullanıcılar da bu duyuruyu görecek." + needConfirmationToRead: "Ayrı okuma onayı gerektirir" + needConfirmationToReadDescription: "Etkinleştirildiğinde, bu duyuruyu okundu olarak işaretlemek için ayrı bir onay mesajı görüntülenir. Bu duyuru, “Tümünü okundu olarak işaretle” işlevinden de hariç tutulur." + end: "Arşiv duyurusu" + tooManyActiveAnnouncementDescription: "Çok fazla aktif duyuru olması kullanıcı deneyimini kötüleştirebilir. Artık geçerliliğini yitirmiş duyuruları arşivlemeyi düşün." + readConfirmTitle: "Okundu olarak işaretle?" + readConfirmText: "Bu, “{title}” içeriğini okundu olarak işaretleyecek." + shouldNotBeUsedToPresentPermanentInfo: "Duyuruları, uzun vadede geçerli olacak bilgiler için değil, güncel ve zaman sınırlı bilgileri yayınlamak için kullanmak en iyisidir." + dialogAnnouncementUxWarn: "Aynı anda iki veya daha fazla diyalog tarzı bildirim olması, kullanıcı deneyimini önemli ölçüde etkileyebilir, bu nedenle lütfen bunları dikkatli kullanın." + silence: "Bildirim yok" + silenceDescription: "Bu seçeneği etkinleştirdiğinde, bu duyurunun bildirimi atlanacak ve kullanıcı bunu okumak zorunda kalmayacak." +_initialAccountSetting: + accountCreated: "Hesabınız başarıyla oluşturuldu!" + letsStartAccountSetup: "Şimdi hesabını oluşturalım." + letsFillYourProfile: "Önce profilini oluşturalım." + profileSetting: "Profil ayarları" + privacySetting: "Gizlilik ayarları" + theseSettingsCanEditLater: "Bu ayarları daha sonra istediğin zaman değiştirebilirsin." + youCanEditMoreSettingsInSettingsPageLater: "“Ayarlar” sayfasından yapılandırabileceğin daha birçok ayar bulunmaktadır. Daha sonra mutlaka ziyaret et." + followUsers: "İlgilendiğiniz bazı kullanıcıları takip ederek zaman akışını oluşturmaya çalış." + pushNotificationDescription: "Push bildirimlerini etkinleştirdiğinde, {name} adresinden gelen bildirimleri doğrudan cihazınıza alabilirsin." + initialAccountSettingCompleted: "Profil kurulumu tamamlandı!" + haveFun: "{name} ile iyi eğlenceler!" + youCanContinueTutorial: "{name} (CherryPick) öğreticisine geçebilir veya buradan kurulumu sonlandırıp hemen kullanabilirsin." + startTutorial: "Öğreticiye başla" + skipAreYouSure: "Profil kurulumunu cidden atlamak mı istiyorsun?" + laterAreYouSure: "Profil ayarlarını cidden daha sonra mı yapacaksın?" +_initialTutorial: + launchTutorial: "Öğreticiyi izle" + title: "Öğretici" + wellDone: "Tebrikler!" + skipAreYouSure: "Öğreticiyi kapatmak mı istiyorsunuz?" + _landing: + title: "Öğreticiye hoş geldin" + description: "Burada, CherryPick'i kullanmanın temellerini ve özelliklerini öğrenebilirsin." + _note: + title: "Not nedir?" + description: "CherryPick'deki gönderiler “Notlar” olarak adlandırılır. Notlar panoda kronolojik olarak düzenlenir ve gerçek zamanlı olarak güncellenir." + reply: "Bir mesaja yanıt vermek için bu düğmeye tıklayın. Yanıtlara yanıt vermek de mümkündür, böylece konuşma bir konu başlığı gibi devam eder." + renote: "Bu notu kendi panonda paylaşabilirsin. Ayrıca yorumlarınla birlikte alıntı da yapabilirsin." + reaction: "Not'a tepkiler ekleyebilirsin. Daha fazla ayrıntı bir sonraki sayfada açıklanacak." + menu: "Not ayrıntılarını görüntüleyebilir, bağlantıları kopyalayabilir ve çeşitli diğer işlemleri gerçekleştirebilirsin." + _reaction: + title: "Reaksiyonlar nedir?" + description: "Notlara çeşitli emojilerle tepki verilebilir. Tepkiler, sadece bir ‘beğeni’ ile ifade edilemeyen nüansları ifade etmeni sağlar." + letsTryReacting: "Notun üzerindeki ‘+’ düğmesine tıklayarak tepkiler eklenebilir. Bu örnek nota tepki verin!" + reactToContinue: "Devam etmek için bir tepki ekle." + reactNotification: "Biri notunuza tepki verdiğinde gerçek zamanlı bildirimler alacaksınız." + reactDone: "“-” düğmesine basarak bir tepkiyi geri alabilirsin." + _timeline: + title: "Pano Kavramı" + description1: "CherryPick, kullanıma göre birden fazla Pano sunar (Bazı Pano'lar sunucunun politikalarına bağlı olarak kullanılamayabilir)." + home: "Takip ettiğin hesapların notlarını görüntüleyebilirsin." + local: "Bu sunucudaki tüm kullanıcıların notlarını görüntüleyebilirsin." + social: "Ev ve Yerel Pano'dan notlar görüntülenecek." + global: "Bağlı tüm sunuculardan gelen notları görüntüleyebilirsin." + description2: "Ekranın üst kısmındaki Pano'lar arasında istediğin zaman geçiş yapabilirsin." + description3: "Ayrıca, Liste Pano ve Kanal Pano da bulunmaktadır. Daha fazla ayrıntı için lütfen {link} adresine bakın." + _postNote: + title: "Not Yayınlama Ayarları" + description1: "CherryPick'de not yayınlarken çeşitli seçenekler mevcuttur. Yayınlama formu şu şekildedir." + _visibility: + description: "Notunu kimlerin görüntüleyebileceğini sınırlayabilirsin." + public: "Notunuz tüm kullanıcılar tarafından görülebilir olacaktır." + home: "Yalnızca Ana zaman akışında herkese açık. Profilinizi ziyaret edenler, takipçilerin ve yeniden notlar aracılığıyla bunu görebilirler." + followers: "Sadece takipçiler tarafından görülebilir. Sadece takipçiler görebilir, başkaları göremez ve başkaları tarafından yeniden not edilemez." + direct: "Yalnızca belirli kullanıcılar tarafından görülebilir ve alıcıya bildirim gönderilir. Doğrudan mesajlaşma yerine alternatif olarak kullanılabilir." + doNotSendConfidencialOnDirect1: "Hassas bilgileri gönderirken dikkatli olun!" + doNotSendConfidencialOnDirect2: "Sunucu yöneticileri yazdıklarınızı görebilir. Güvenilir olmayan sunuculardaki kullanıcılara doğrudan not gönderirken hassas bilgilere dikkat edin." + localOnly: "Bu bayrakla yayınlamak, notu diğer sunuculara aktarmaz. Diğer sunuculardaki kullanıcılar, yukarıdaki görüntüleme ayarlarından bağımsız olarak bu notları doğrudan görüntüleyemezler." + _cw: + title: "İçerik Uyarısı" + description: "Gövde yerine, “Yorumlar” alanına yazılan içerik görüntülenecek. “Devamını oku” düğmesine basıldığında gövde görüntülenecek." + _exampleNote: + cw: "Bu kesinlikle sizi acıktıracak!" + note: "Az önce çikolata kaplı bir donut yedim 🍩😋" + useCases: "Bu, sunucu kurallarına uyulurken, gerekli notlar için veya spoiler veya hassas metinlerin kendi kendine kısıtlanması için kullanılır." + _howToMakeAttachmentsSensitive: + title: "Ekleri Hassas Olarak İşaretleme" + description: "Sunucu kuralları gereği gerekli olan veya bozulmaması gereken ekler için “hassas” bayrağı ekle." + tryThisFile: "Bu forma ekli resmi hassas olarak işaretlemeyi dene!" + _exampleNote: + note: "Oops, natto kapağını açarken berbat ettim..." + method: "Bir eki hassas olarak işaretlemek için, dosya küçük resmini tıklayın, menüyü açın ve “Hassas Olarak İşaretle” seçeneğini tıklayın." + sensitiveSucceeded: "Dosya eklerken, lütfen sunucu kurallarına uygun olarak hassasiyet ayarlarını yapın." + doItToContinue: "Devam etmek için ek dosyayı hassas olarak işaretle." + _done: + title: "Eğitimi tamamladınız! 🎉" + description: "Burada tanıtılan işlevler sadece küçük bir kısmıdır. CherryPick'i kullanma konusunda daha ayrıntılı bilgi için lütfen şu kaynağa bakın: {link}." +_timelineDescription: + home: "Ana Pano'da, takip ettiğin hesapların notlarını görebilirsin." + local: "Yerel Pano'da, bu sunucudaki tüm kullanıcıların notlarını görebilirsin." + social: "Pano, Sosyal Pano ve Yerel Pano'dan gelen notları görüntüler." + global: "Global Pano'da, bağlı tüm sunuculardan gelen notları görebilirsin." +_serverRules: + description: "Kayıt öncesinde gösterilecek bir dizi kural. Hizmet Şartlarının özetini belirlemen önerilir." +_serverSettings: + iconUrl: "Simge URL'si" + appIconDescription: " {host} bir uygulama olarak görüntülendiğinde kullanılacak simgeyi belirtir." + appIconUsageExample: "Örneğin, PWA olarak veya bir telefonda ana ekran yer imi olarak görüntülendiğinde" + appIconStyleRecommendation: "Simge kare veya daire şeklinde kırpılabileceğinden, içeriğin etrafında renkli kenar boşluğu bulunan bir simge kullanılması önerilir." + appIconResolutionMustBe: "Minimum çözünürlük {resolution}'tür." + manifestJsonOverride: "manifest.json Geçersiz Kılma" + shortName: "Kısa ad" + shortNameDescription: "Resmi adın uzun olması durumunda görüntülenebilen, örneğin adının kısaltması." + fanoutTimelineDescription: "Etkinleştirildiğinde Pano alma performansını büyük ölçüde artırır ve veritabanı yükünü azaltır. Bunun karşılığında Redis'in bellek kullanımı artacaktır. Sunucu belleği düşükse veya sunucu kararsızsa bunu devre dışı bırakmayı düşün." + fanoutTimelineDbFallback: "Veritabanına geri dön" + fanoutTimelineDbFallbackDescription: "Etkinleştirildiğinde, Pano önbelleğe alınmamışsa ek sorgular için veritabanına geri döner. Bu özelliği devre dışı bırakmak, geri dönüş sürecini ortadan kaldırarak sunucu yükünü daha da azaltır, ancak alınabilecek panoların aralığını sınırlar." + reactionsBufferingDescription: "Etkinleştirildiğinde, reaksiyon oluşturma sırasında performans büyük ölçüde artacak ve veritabanı üzerindeki yük azalacaktır. Ancak, Redis bellek kullanımı artacakt." + remoteNotesCleaning: "Uzak notların otomatik olarak temizlenmesi" + remoteNotesCleaning_description: "Etkinleştirildiğinde, kullanılmayan ve güncelliğini yitirmiş uzak notlar, veritabanının şişmesini önlemek için periyodik olarak temizlenecek." + remoteNotesCleaningMaxProcessingDuration: "Maksimum temizleme işlem süresi" + remoteNotesCleaningExpiryDaysForEachNotes: "Notları saklamak için minimum gün sayısı" + inquiryUrl: "Sorgu URL'si" + inquiryUrlDescription: "Sorgu formu için sunucu yöneticisine bir URL veya iletişim bilgileri için bir web sayfası belirtin." + openRegistration: "Hesap oluşturmayı açık hale getir" + openRegistrationWarning: "Kayıt açma işlemi riskler içerir. Sunucuyu sürekli olarak izleyen ve herhangi bir sorun durumunda hemen müdahale edebilen bir sistemin varsa, bu işlemi etkinleştirmen önerilir." + thisSettingWillAutomaticallyOffWhenModeratorsInactive: "Bir süre boyunca moderatör etkinliği algılanmazsa, spam'ı önlemek için bu ayar otomatik olarak kapatılır." + deliverSuspendedSoftware: "Askıya Alınan Yazılım" + deliverSuspendedSoftwareDescription: "Güvenlik açığı veya diğer nedenlerle sunucunun yazılımının belirli bir isim ve sürüm aralığı için teslimatı durdurabilirsiniz. Bu sürüm bilgileri sunucu tarafından sağlanır ve güvenilirliği garanti edilmez. Sürümü belirtmek için semver aralığı belirtilebilir, ancak >= 2024.3.1 belirtildiğinde 2024.3.1-custom.0 gibi özel sürümler dahil edilmez, bu nedenle >= 2024.3.1-0 gibi ön sürüm belirtimi kullanılması önerilir." + singleUserMode: "Tek kullanıcı modu" + singleUserMode_description: "Bu sunucunun tek kullanıcısıysanız, bu modu etkinleştirerek performansını optimize edebilirsin." + signToActivityPubGet: "ActivityPub GET isteklerini imzalayın" + signToActivityPubGet_description: "Normalde bu özellik etkinleştirilmiş olmalıdır. Bu özelliği devre dışı bırakmak federasyonla ilgili sorunları iyileştirebilir, ancak diğer yandan bazı diğer sunuculara yönelik federasyonu devre dışı bırakabilir." + proxyRemoteFiles: "Proxy uzak dosyalar" + proxyRemoteFiles_description: "Etkinleştirildiğinde, sunucu uzak dosyaları proxy olarak kullanır ve sunar. Bu, resim küçük resimleri oluşturmak ve kullanıcı gizliliğini korumak için kullanışlıdır." + allowExternalApRedirect: "ActivityPub aracılığıyla yapılan sorgular için yönlendirmelere izin ver" + allowExternalApRedirect_description: "Etkinleştirildiğinde, diğer sunucular bu sunucu aracılığıyla üçüncü taraf içeriğini sorgulayabilir, ancak bu durum içerik sahteciliğine yol açabilir." + userGeneratedContentsVisibilityForVisitor: "Kullanıcılar tarafından oluşturulan içeriğin misafirlere görünürlüğü" + userGeneratedContentsVisibilityForVisitor_description: "Bu, uygunsuz ve iyi denetlenmemiş uzaktaki içeriğin kendi sunucunuz aracılığıyla istemeden internette yayınlanmasını önlemek için yararlıdır." + userGeneratedContentsVisibilityForVisitor_description2: "Sunucu tarafından alınan uzak içerik dahil olmak üzere sunucudaki tüm içeriği koşulsuz olarak İnternet'e yayınlamak risklidir. Bu, içeriğin dağıtılmış yapısından haberdar olmayan misafirler için özellikle önemlidir, çünkü onlar yanlışlıkla uzak içeriğin bile sunucudaki kullanıcılar tarafından oluşturulan içerik olduğunu düşünebilirler." + restartServerSetupWizardConfirm_title: "Sunucu kurulum sihirbazını yeniden başlatmak ister misin?" + restartServerSetupWizardConfirm_text: "Bazı mevcut ayarlar sıfırlanacaktır." + entrancePageStyle: "Giriş sayfası stili" + showTimelineForVisitor: "Panoyu göster" + showActivitiesForVisitor: "Aktiviteleri göster" + _userGeneratedContentsVisibilityForVisitor: + all: "Her şey halka açıktır." + localOnly: "Yalnızca yerel içerik yayınlanır, uzak içerik gizli tutulur." + none: "Her şey gizlidir." +_accountMigration: + moveFrom: "Başka bir hesabı bu hesaba taşıyın" + moveFromSub: "Başka bir hesaba takma ad oluşturun" + moveFromLabel: "Orijinal Hesap #{n}" + moveFromDescription: "Bu hesaptan taşınacak hesap için bir takma ad oluşturmalısınız.\nTaşınacak hesabı aşağıdaki biçimde girin: @username@server.example.com\nTakma adı silmek için alanı boş bırakın (önerilmez)." + moveTo: "Bu hesabı başka bir hesaba taşıyın" + moveToLabel: "Taşınacak hesap:" + moveCannotBeUndone: "Hesap taşıma işlemi geri alınamaz." + moveAccountDescription: "Bu işlem, hesabını farklı bir hesaba taşıyacaktır.\n・Bu hesabın takipçileri otomatik olarak yeni hesaba taşınacak.\n・Bu hesap, şu anda takip ettiği tüm kullanıcıları takipten çıkaracak.\n・Bu hesapta yeni notlar vb. oluşturamayacaksın.\n\nTakipçilerin taşınması otomatik olarak gerçekleşirken, takip ettiğin kullanıcıların listesini taşımak için bazı adımları manuel olarak hazırlaman gerekir. Bunu yapmak için, ayarlar menüsünden takipçilerini dışa aktar ve daha sonra yeni hesaba içe aktar. Aynı prosedür, listelerinin yanı sıra sessize aldığın ve engellediğin kullanıcılar için de geçerli.\n\n(Bu açıklama CherryPick v13.12.0 ve sonraki sürümler için geçerlidir. Mastodon gibi diğer ActivityPub yazılımları farklı şekilde çalışabilir.)" + moveAccountHowTo: "Geçiş yapmak için, önce taşınacak hesapta bu hesap için bir takma ad oluşturun.\nTakma adı oluşturduktan sonra, taşınacak hesabı aşağıdaki biçimde girin: @username@server.example.com" + startMigration: "Taşın" + migrationConfirm: "Bu hesabı {account} hesabına gerçekten taşımak istiyor musun? Bu işlem başlatıldıktan sonra durdurulamaz veya geri alınamaz ve bu hesabı artık orijinal haliyle kullanamazsın." + movedAndCannotBeUndone: "\nBu hesap taşınmıştır.\nTaşıma işlemi geri alınamaz." + postMigrationNote: "Bu hesap, geçiş işlemi tamamlandıktan 24 saat sonra şu anda takip ettiği tüm hesapları takipten çıkaracak.\nHem takipçi sayısı hem de takip edilenler sayısı sıfır olacak. Takipçilerinin bu hesabın yalnızca takipçilere açık gönderilerini görememesi durumunu önlemek için, takipçilerin bu hesabı takip etmeye devam edecek." + movedTo: "Yeni hesap:" +_achievements: + earnedAt: "Şurada açıldı" + _types: + _notes1: + title: "msky'ımı kuruyorum" + description: "İlk notunuzu yayınlayın" + flavor: "CherryPick ile iyi vakit geçirin!" + _notes10: + title: "Bazı notlar" + description: "10 not gönder" + _notes100: + title: "Çok sayıda not" + description: "100 notu yayınla" + _notes500: + title: "Notlarla kaplı" + description: "500 notu yayınla" + _notes1000: + title: "Notlardan oluşan bir dağ" + description: "1.000 not yayınla" + _notes5000: + title: "Taşan notlar" + description: "5.000 not yayınla" + _notes10000: + title: "Süper not" + description: "10.000 not yayınla" + _notes20000: + title: "Daha... fazla... not... lazım..." + description: "20.000 not yayınla" + _notes30000: + title: "Notlar notlar notlar!" + description: "30.000 not yayınla" + _notes40000: + title: "Not fabrikası" + description: "40.000 not yayınla" + _notes50000: + title: "Notların gezegeni" + description: "50.000 not yayınla" + _notes60000: + title: "Not kuasar" + description: "60.000 not yayınla" + _notes70000: + title: "Not kara deliği" + description: "70.000 not yayınla" + _notes80000: + title: "Not galaksisi" + description: "80.000 not yayınla" + _notes90000: + title: "Not evreni" + description: "90.000 not yayınla" + _notes100000: + title: "TÜM NOTLARINIZ BİZE AİTTİR" + description: "100.000 yayınlanmış not" + flavor: "Gerçekten söyleyecek çok şeyin var." + _login3: + title: "Başlangıç I" + description: "Log in for a total of 3 days" + flavor: "Toplam 3 gün boyunca oturum açın" + _login7: + title: "Başlangıç II" + description: "Toplam 7 gün boyunca oturum açın" + flavor: "Henüz işlerin nasıl yürüdüğünü anladığını hissediyor musun?" + _login15: + title: "Başlangıç III" + description: "Toplam 15 gün boyunca oturum açın" + _login30: + title: "Misskist I" + description: "Toplam 30 gün boyunca oturum açın" + _login60: + title: "Misskist II" + description: "Toplam 60 gün boyunca oturum açın" + _login100: + title: "Misskist III" + description: "Toplam 100 gün boyunca oturum açın" + flavor: "Şiddetli Misskist" + _login200: + title: "Düzenli I" + description: "Toplam 200 gün boyunca oturum açın." + _login300: + title: "Düzenli II" + description: "Toplam 300 gün boyunca oturum açın" + _login400: + title: "Düzenli III" + description: "Toplam 400 gün boyunca oturum açın" + _login500: + title: "Uzman I" + description: "Toplam 500 gün boyunca oturum açın" + flavor: "Arkadaşlar, sık sık not almayı sevdiğim söylenir." + _login600: + title: "Uzman II" + description: "Toplam 600 gün boyunca oturum açın" + _login700: + title: "Uzman III" + description: "Toplam 700 gün boyunca oturum açın" + _login800: + title: "Notların Ustası I" + description: "Toplam 800 gün boyunca oturum açın" + _login900: + title: "Notların Ustası II" + description: "Toplam 900 gün boyunca oturum açın" + _login1000: + title: "Notların Ustası III" + description: "Toplam 1.000 gün boyunca oturum açın." + flavor: "CherryPick'i kullandığınız için teşekkür ederiz!" + _noteClipped1: + title: "Kesinlikle... kesmeliyim..." + description: "İlk notunu ekle" + _noteFavorited1: + title: "Yıldız gözlemcisi" + description: "İlk notunu favorilerine ekle" + _myNoteFavorited1: + title: "Yıldızları Arayış" + description: "Başka birinin notlarınızdan birini favorilerine eklemesini sağlayın" + _profileFilled: + title: "İyi hazırlanmış" + description: "Profilini oluştur" + _markedAsCat: + title: "Ben bir kediyim." + description: "Hesabını kedi olarak işaretle" + flavor: "Sana daha sonra bir isim vereceğim." + _following1: + title: "İlk kullanıcınızı takip edin" + description: "Bir kullanıcıyı takip et" + _following10: + title: "Devam et... devam et..." + description: "10 kullanıcıyı takip et" + _following50: + title: "Bir sürü arkadaş" + description: "50 hesabı takip et" + _following100: + title: "100 Arkadaş" + description: "100 hesabı takip et" + _following300: + title: "Arkadaş yüklemesi" + description: "300 hesabı takip et" + _followers1: + title: "İlk takipçi" + description: "1 takipçi kazanın" + _followers10: + title: "Beni takip edin!" + description: "10 takipçi kazanın" + _followers50: + title: "Kalabalıklar halinde gelmek" + description: "50 takipçi kazanın" + _followers100: + title: "Popüler" + description: "100 takipçi kazanın" + _followers300: + title: "Lütfen tek sıra halinde dizilin." + description: "300 takipçi kazanın" + _followers500: + title: "Radyo Kulesi" + description: "500 takipçi kazanın" + _followers1000: + title: "Etkileyici" + description: "1.000 takipçi kazanın" + _collectAchievements30: + title: "Başarı Koleksiyoncusu" + description: "30 başarı kazan" + _viewAchievements3min: + title: "Beğeniler Başarılar" + description: "Likes Achievements" + _iLoveMisskey: + title: "CherryPick'i seviyorum" + description: "“I ❤ #CherryPick” yazısını paylaş" + flavor: "CherryPick geliştirme ekibi desteğin için çok teşekkür eder!" + _foundTreasure: + title: "Hazine Avı" + description: "Gizli hazineyi buldunuz." + _client30min: + title: "Kısa mola" + description: "CherryPick'i en az 30 dakika açık tutun." + _client60min: + title: "CherryPick'de “Miss” yok" + description: "CherryPick'i en az 60 dakika açık tutun." + _noteDeletedWithin1min: + title: "Nevermind" + description: "Boş ver" + _postedAtLateNight: + title: "Gececi" + description: "Gece geç saatlerde bir not yayınlayın" + flavor: "Yatma vakti geldi." + _postedAt0min0sec: + title: "Konuşan Saat" + description: "00:00'da bir not yayınlayın." + flavor: "Tık tık tık, güm!" + _selfQuote: + title: "Öz Referans" + description: "Kendi notunuzu alıntı yapın" + _htl20npm: + title: "Akış Panosu" + description: "Ev zaman çizelgenizin hızı 20 npm'yi (dakika başına not sayısı) aşıyor mu?" + _viewInstanceChart: + title: "Analist" + description: "Sunucunun grafiklerini görüntüle" + _outputHelloWorldOnScratchpad: + title: "Merhaba, dünya!" + description: "Scratchpad'de “hello world” yazdırın." + _open3windows: + title: "Çoklu Pencere" + description: "Aynı anda en az 3 pencere açık olsun." + _driveFolderCircularReference: + title: "Döngüsel Referans" + description: "Drive'da yinelemeli olarak iç içe geçmiş bir klasör oluşturmaya çalış." + _reactWithoutRead: + title: "Cidden okudun mu?" + description: "100 karakterden uzun bir notun yayınlanmasından itibaren 3 saniye içinde yanıt verin." + _clickedClickHere: + title: "Buraya tıklayın" + description: "Buraya tıkladınız" + _justPlainLucky: + title: "Sadece Şanslı" + description: "Her 10 saniyede bir %0,005 olasılıkla elde edilme şansı vardır." + _setNameToSyuilo: + title: "Tanrı Kompleksi" + description: "Adınızı “syuilo” olarak ayarlayın." + _passedSinceAccountCreated1: + title: "Birinci Yıl Dönümü" + description: "Hesabınızın oluşturulmasından bu yana bir yıl geçti." + _passedSinceAccountCreated2: + title: "İki Yıllık Yıldönümü" + description: "Hesabınızın oluşturulmasından bu yana iki yıl geçti." + _passedSinceAccountCreated3: + title: "Üçüncü Yıl Dönümü" + description: "Hesabınızın oluşturulmasından bu yana üç yıl geçti." + _loggedInOnBirthday: + title: "Doğum günün kutlu olsun" + description: "Doğum gününüzde giriş yapın" + _loggedInOnNewYearsDay: + title: "Yeni yılınız kutlu olsun!" + description: "Yılın ilk gününde oturum açıldı" + flavor: "Bu sunucuda bir başka harika yıla" + _cookieClicked: + title: "Çerezleri tıklayarak oynanan bir oyun" + description: "Çerezi tıkladı" + flavor: "Wait, are you on the correct website?" + _brainDiver: + title: "Brain Diver" + description: "Brain Diver bağlantısını paylaşın" + flavor: "Misskey-Misskey La-Tu-Ma" + _smashTestNotificationButton: + title: "Test taşması" + description: "Bildirim testini çok kısa bir süre içinde tekrar tekrar tetikle." + _tutorialCompleted: + title: "CherryPick Temel Kurs Diploması" + description: "Eğitim tamamlandı" + _bubbleGameExplodingHead: + title: "🤯" + description: "Kabarcık oyunundaki en büyük nesne" + _bubbleGameDoubleExplodingHead: + title: "Çift🤯" + description: "Aynı anda balon oyunundaki en büyük iki nesne" + flavor: "Öğle yemeği kutunu şöyle doldurabilirsin 🤯 🤯 biraz." +_role: + new: "Yeni rol" + edit: "Rolü düzenle" + name: "Rol adı" + description: "Rol tanımı" + permission: "Rol izinleri" + descriptionOfPermission: "Moderators temel moderasyon işlemlerini gerçekleştirebilir.\nAdministrators örneğin tüm ayarlarını değiştirebilir." + assignTarget: "Görev türü" + descriptionOfAssignTarget: "Bu rolün parçası olan ve olmayan kişileri manuel olarak değiştirmek için
manuel
.\nKullanıcıların bir koşula bağlı olarak bu role otomatik olarak atanmasını ve bu rolden çıkarılmasını sağlamak için koşullu." + manual: "Kılavuz" + manualRoles: "Manuel roller" + conditional: "Koşullu" + conditionalRoles: "Koşullu roller" + condition: "Durum" + isConditionalRole: "Bu, koşullu bir roldür." + isPublic: "Kamu rolü" + descriptionOfIsPublic: "Bu rol, atanan kullanıcıların profillerinde görüntülenecek." + options: "Seçenekler" + policies: "Politikalar" + baseRole: "Rol şablonu" + useBaseValue: "Rol şablonu değerini kullan" + chooseRoleToAssign: "Atamak istediğin rolü seç" + iconUrl: "Simge URL'si" + asBadge: "Rozet olarak göster" + descriptionOfAsBadge: "This role's icon will be displayed next to the username of users with this role if turned on." + isExplorable: "Rolü keşfedilebilir hale getir" + descriptionOfIsExplorable: "Bu rolün panosu ve bu role sahip kullanıcıların listesi, etkinleştirilirse kamuya açık hale getirilecek." + displayOrder: "Pozisyon" + descriptionOfDisplayOrder: "Sayı ne kadar yüksekse, UI pozisyonu da o kadar yüksek olur." + preserveAssignmentOnMoveAccount: "Geçiş sırasında rol atamalarını koruyun" + preserveAssignmentOnMoveAccount_description: "Etkinleştirildiğinde, bu rol, bu role sahip bir hesap taşındığında hedef hesaba aktarılacak." + canEditMembersByModerator: "Moderatörlerin bu rol için üye listesini düzenlemesine izin ver" + descriptionOfCanEditMembersByModerator: "Etkinleştirildiğinde, moderatörler ve yöneticiler bu role kullanıcıları atayabilir ve atamalarını kaldırabilir. Devre dışı bırakıldığında, yalnızca yöneticiler kullanıcıları atayabilir." + priority: "Öncelik" + _priority: + low: "Düşük" + middle: "Orta" + high: "Yüksek" + _options: + gtlAvailable: "Global Pano'yu görüntüleyebilir" + ltlAvailable: "Yerel panoyu görüntüleyebilir" + canPublicNote: "Halka açık notlar gönderebilir" + mentionMax: "Bir notta maksimum bahsetme sayısı" + canInvite: "Sunucu davet kodları oluşturabilir" + inviteLimit: "Davet sınırı" + inviteLimitCycle: "Davet sınırı bekleme süresi" + inviteExpirationTime: "Davet süresi dolma aralığı" + canManageCustomEmojis: "Özel emojileri yönetebilir" + canManageAvatarDecorations: "Avatar süslerini yönet" + driveCapacity: "Drive kapasitesi" + maxFileSize: "Yükleyebileceğin maksimum dosya boyutu" + alwaysMarkNsfw: "Dosyaları her zaman NSFW olarak işaretle" + canUpdateBioMedia: "Bir simge veya banner görüntüsünü düzenleyebilir" + pinMax: "Sabitlenmiş notların maksimum sayısı" + antennaMax: "Maksimum anten sayısı" + wordMuteMax: "Kelime sessizlerinde izin verilen maksimum karakter sayısı" + webhookMax: "Maksimum Webhook sayısı" + clipMax: "Maksimum klip sayısı" + noteEachClipsMax: "Bir klip içindeki maksimum not sayısı" + userListMax: "Maksimum kullanıcı listesi sayısı" + userEachUserListsMax: "Kullanıcı listesindeki maksimum kullanıcı sayısı" + rateLimitFactor: "Hız Sınırı" + descriptionOfRateLimitFactor: "Daha düşük oran sınırları daha az kısıtlayıcıdır, daha yüksek olanlar ise daha kısıtlayıcıdır." + canHideAds: "Reklamları gizleyebilir" + canSearchNotes: "Not arama kullanımı" + canSearchUsers: "Kullanıcı arama" + canUseTranslator: "Çevirmen kullanımı" + avatarDecorationLimit: "Maksimum avatar süsü sayısı" + canImportAntennas: "Antenlerin içe aktarılmasına izin ver" + canImportBlocking: "Engellemeyi içe aktarmaya izin ver" + canImportFollowing: "Aşağıdakilerin içe aktarılmasına izin ver" + canImportMuting: "Sessize alma özelliğini içe aktarmaya izin ver" + canImportUserLists: "Listelerin içe aktarılmasına izin ver" + chatAvailability: "Sohbeti İzin Ver" + uploadableFileTypes: "Yüklenebilir dosya türleri" + uploadableFileTypes_caption: "İzin verilen MIME/dosya türlerini belirtir. Birden fazla MIME türü, yeni bir satırla ayırarak belirtilebilir ve joker karakterler yıldız işareti (*) ile belirtilebilir. (örneğin, image/*)" + uploadableFileTypes_caption2: "Bazı dosya türleri algılanamayabilir. Bu tür dosyalara izin vermek için, spesifikasyona {x} ekle." + noteDraftLimit: "Sunucu notlarının olası taslak sayısı" + watermarkAvailable: "Filigran işlevinin kullanılabilirliği" + _condition: + roleAssignedTo: "Manuel rollere atanmış" + isLocal: "Yerel kullanıcı" + isRemote: "Uzak kullanıcı" + isCat: "Kedi Kullanıcıları" + isBot: "Bot Kullanıcıları" + isSuspended: "Askıya alınmış kullanıcı" + isLocked: "Özel hesaplar" + isExplorable: "“Hesabı bulunabilir hale getir” özelliğini etkili bir şekilde kullanan kullanıcı" + createdLessThan: "Hesap oluşturulduktan sonra X'ten az zaman geçti." + createdMoreThan: "Hesap oluşturulmasından bu yana X'ten fazla zaman geçti." + followersLessThanOrEq: "X veya daha az takipçisi var" + followersMoreThanOrEq: "X veya daha fazla takipçisi var" + followingLessThanOrEq: "X veya daha az sayıda hesabı takip ediyor" + followingMoreThanOrEq: "X veya daha fazla hesabı takip ediyor" + notesLessThanOrEq: "Gönderi sayısı şundan az/eşit" + notesMoreThanOrEq: "Gönderi sayısı şundan büyük/eşit" + and: "Koşul-AND" + or: "Koşul-QR" + not: "Koşul-NOT" +_sensitiveMediaDetection: + description: "Makine öğrenimi yoluyla hassas medyayı otomatik olarak tanıyarak sunucu moderasyonunun yükünü azaltır. Bu, sunucu üzerindeki yükü biraz artıracaktır." + sensitivity: "Algılama hassasiyeti" + sensitivityDescription: "Hassasiyeti azaltmak, yanlış algılamaların (yanlış pozitifler) azalmasına neden olurken, hassasiyeti artırmak ise algılamaların kaçırılmasının (yanlış negatifler) azalmasına neden olur." + setSensitiveFlagAutomatically: "Hassas olarak işaretle" + setSensitiveFlagAutomaticallyDescription: "Bu seçenek kapatılsa bile, dahili algılama sonuçları korunacaktır." + analyzeVideos: "Videoların analizini etkinleştir" + analyzeVideosDescription: "Görüntülerin yanı sıra videoları da analiz eder. Bu, sunucu üzerindeki yükü biraz artıracaktır." +_emailUnavailable: + used: "Bu E-Posta adresi zaten kullanılıyor." + format: "Bu E-Posta adresinin biçimi geçersizdir." + disposable: "Tek kullanımlık E-Posta adresleri kullanılamaz." + mx: "Bu E-Posta sunucusu geçersizdir." + smtp: "Bu E-Posta sunucusu yanıt vermiyor." + banned: "Bu E-Posta adresiyle kayıt olamazsınız." +_ffVisibility: + public: "Bu e-posta adresiyle kayıt olamazsınız." + followers: "Sadece takipçiler tarafından görülebilir" + private: "Özel" +_signup: + almostThere: "Neredeyse vardık" + emailAddressInfo: "Lütfen E-Posta adresini gir. Bu adres kamuya açık hale getirilmeyecek." + emailSent: "Onay e-postası E-Posta adresine ({email}) gönderilmiştir. Hesap oluşturma işlemini tamamlamak için e-postadaki bağlantıya tıkla." _accountDelete: - started: "Silme işlemi başlatıldı" + accountDelete: "Hesabı sil" + mayTakeTime: "Hesap silme işlemi kaynak yoğun bir işlem olduğundan, oluşturduğun içerik miktarına ve yüklediğin dosya sayısına bağlı olarak tamamlanması biraz zaman alabilir." + sendEmail: "Hesap silme işlemi tamamlandıktan sonra, bu hesaba kayıtlı E-Posta adresine bir e-posta gönderilecek." + requestAccountDelete: "Hesap silme talebi" + started: "Silme işlemi başlatıldı." + inProgress: "Silme işlemi şu anda devam ediyor." +_ad: + back: "Geri" + reduceFrequencyOfThisAd: "Bu reklamı daha az göster" + hide: "Gizle" + timezoneinfo: "Haftanın günü, sunucunun saat diliminden belirlenir." + adsSettings: "Reklam ayarları" + notesPerOneAd: "Gerçek zamanlı güncelleme reklam yerleşim aralığı (Reklam başına notlar)" + setZeroToDisable: "Bu değeri 0 olarak ayarlayarak gerçek zamanlı güncelleme reklamlarını devre dışı bırakın." + adsTooClose: "Mevcut reklam aralığı çok düşük olduğu için kullanıcı deneyimini önemli ölçüde kötüleştirebilir." +_forgotPassword: + enterEmail: "Kayıt olurken kullandığın E-Posta adresini gir. Şifreni sıfırlayabileceğin bir bağlantı bu adrese gönderilecek." + ifNoEmail: "Kayıt sırasında E-Posta kullanmadıysanız, lütfen bunun yerine sunucu yöneticisiyle iletişime geçin." + contactAdmin: "This instance does not support using email addresses, please contact the instance administrator to reset your password instead." +_gallery: + my: "Benim Galerim" + liked: "Beğenilen Gönderiler" + like: "Beğen" + unlike: "Benzerlerini kaldır" _email: _follow: - title: "seni takip etti" + title: "Yeni bir takipçin var." + _receiveFollowRequest: + title: "Bir takip isteği aldınız." +_plugin: + install: "Eklentileri yükle takip isteği aldınız" + installWarn: "Güvenilir olmayan eklentileri yükleme." + manage: "Eklentileri yönet" + viewSource: "Kaynak görüntüle" + viewLog: "Günlüğü göster" +_preferencesBackups: + list: "Created backups" + saveNew: "Yeni yedeklemeyi kaydet" + loadFile: "Dosyadan yükle" + apply: "Bu cihaza başvur" + save: "Değişiklikleri kaydet" + inputName: "Lütfen bu yedekleme için bir ad girin." + cannotSave: "Kaydetme başarısız oldu" + nameAlreadyExists: "“{name}” adlı bir yedekleme zaten mevcut. Lütfen farklı bir ad girin." + applyConfirm: "Bu cihaza “{name}” yedeklemesini cidden uygulamak istiyor musun? Bu cihazın mevcut ayarları üzerine yazılacaktır." + saveConfirm: "Yedeklemeyi {name} olarak kaydedin?" + deleteConfirm: "{name} yedeklemesini silmek ister misin?" + renameConfirm: "Bu yedeğin adını “{old}” den “{new}” ye değiştirmek ister misin?" + noBackups: "Yedekleme mevcut değil. “Yeni yedekleme oluştur” seçeneğini kullanarak bu sunucudaki istemci ayarlarınızı yedekleyebilirsin." + createdAt: "Oluşturulma tarihi: {date} {time}" + updatedAt: "Güncelleme tarihi: {date} {time}" + cannotLoad: "Yükleme başarısız" + invalidFile: "Geçersiz dosya biçimi" +_registry: + scope: "Kapsam" + key: "Anahtar" + keys: "Anahtarlar" + domain: "Alan adı" + createKey: "Anahtar oluştur" +_aboutMisskey: + about: "Misskey, 2014 yılından beri syuilo tarafından geliştirilen açık kaynaklı bir yazılımdır." + contributors: "Başlıca katkıda bulunanlar" + allContributors: "Tüm katkıda bulunanlar" + source: "Kaynak kodu" + original: "Orijinal" + thisIsModifiedVersion: "{name} orijinal CherryPick'in değiştirilmiş bir sürümünü kullanır." + translation: "Misskey'i çevir" + donate: "Misskey'e bağış yapın" + morePatrons: "Burada adı geçmeyen diğer birçok yardımseverin desteğine de teşekkür ederiz. Teşekkürler! 🥰" + patrons: "Müşteriler" + projectMembers: "Proje üyeleri" +_displayOfSensitiveMedia: + respect: "Hassas olarak işaretlenmiş medyayı gizle" + ignore: "Hassas olarak işaretlenmiş medya görüntüleme" + force: "Hide all media" +_instanceTicker: + none: "Asla gösterme" + remote: "Uzak kullanıcılar için göster" + always: "Her zaman göster" +_serverDisconnectedBehavior: + reload: "Otomatik olarak yeniden yükle" + dialog: "Otomatik olarak yeniden yükle" + quiet: "Göze batmayan uyarı göster" +_channel: + create: "Kanal oluştur" + edit: "Kanalı düzenle" + setBanner: "Afiş ayarla" + removeBanner: "Afişi kaldır" + featured: "Trend olan" + owned: "Sahip olunan" + following: "Takip edildi" + usersCount: "{n} Katılımcılar" + notesCount: "{n} Notlar" + nameAndDescription: "Adı ve açıklaması" + nameOnly: "Sadece isim" + allowRenoteToExternal: "Kanal dışında yeniden not alma ve alıntı yapmaya izin ver" +_menuDisplay: + sideFull: "Yan" + sideIcon: "Yan (Simgeler)" + top: "En üst" + hide: "Gizle" +_wordMute: + muteWords: "Sessiz kelimeler" + muteWordsDescription: "AND koşulu için boşluklarla, OR koşulu için satır sonlarıyla ayırın." + muteWordsDescription2: "Surround keywords with slashes to use regular expressions." +_instanceMute: + instanceMuteDescription: "Bu, listelenen sunuculardan gelen tüm notları/yeniden notları sessize alır, sessize alınan bir sunucudan bir kullanıcıya yanıt veren kullanıcıların notları da dahil olmak üzere." + instanceMuteDescription2: "Yeni satırlarla ayırın" + title: "Listelenen sunuculardan notları gizler." + heading: "Sessize alınacak sunucuların listesi" _theme: + explore: "Temaları Keşfedin" + install: "Bir tema yükle" + manage: "Temaları yönet" + code: "Tema kodu" + copyThemeCode: "Tema kodunu kopyala" + description: "Açıklama" + installed: "{name} kuruldu" + installedThemes: "Yüklü temalar" + builtinThemes: "Yerleşik temalar" + instanceTheme: "Sunucu teması" + alreadyInstalled: "Bu tema zaten yüklenmiş." + invalid: "Bu temanın biçimi geçersizdir." + make: "Bir tema oluşturun" + base: "Base" + addConstant: "Sabit ekle" + constant: "Sabit" + defaultValue: "Varsayılan değer" color: "Renk" + refProp: "Bir özelliği referans al" + refConst: "Sabiti referans al" + key: "Anahtar" + func: "İşlevler" + funcKind: "İşlev türü" + argument: "Tartışma" + basedProp: "Referans verilen mülk" + alpha: "Opaklık" + darken: "Koyulaştır" + lighten: "Hafiflet" + inputConstantName: "Bu sabit için bir ad girin" + importInfo: "Buraya tema kodunu girersen, onu tema düzenleyicisine aktarabilirsin." + deleteConstantConfirm: "{const} sabitini cidden silmek istiyor musun?" keys: - mention: "Bahset" - renote: "vazgeçme" + accent: "Aksan" + bg: "Arka plan" + fg: "Metin" + focus: "Odak" + indicator: "Gösterge" + panel: "Panel" + shadow: "Gölge" + header: "Başlık" + navBg: "Kenar çubuğu arka planı" + navFg: "Kenar çubuğu metni" + navActive: "Kenar çubuğu metni (Etkin)" + navIndicator: "Kenar çubuğu göstergesi" + link: "Link" + hashtag: "Hashtag" + mention: "Bahsetmeler" + mentionMe: "Bahsetmeler (Ben)" + renote: "Renote" + modalBg: "Modal arka plan" + divider: "Bölücü" + scrollbarHandle: "Kaydırma çubuğu" + scrollbarHandleHover: "Kaydırma çubuğu (Fareyi üzerine getir)" + dateLabelFg: "Tarih etiketi metni" + infoBg: "Bilgi arka planı" + infoFg: "Bilgi metni" + infoWarnBg: "Uyarı arka planı" + infoWarnFg: "Uyarı metni" + toastBg: "Bildirim arka planı" + toastFg: "Bildirim metni" + buttonBg: "Düğme arka planı" + buttonHoverBg: "Button background (Hover)" + inputBorder: "Giriş alanı kenarlığı" + badge: "Rozet" + messageBg: "Sohbet arka planı" + fgHighlighted: "Vurgulanan Metin" _sfx: - note: "notlar" - notification: "Bildirim" - chat: "Mesajlar" + note: "Yeni not" + noteMy: "Kendi notu" + notification: "Bildirimler" + reaction: "Reaksiyon seçimi hakkında" + chatMessage: "Sohbet Mesajları" +_soundSettings: + driveFile: "Drive'da bir ses dosyası kullanın." + driveFileWarn: "Drive'dan bir ses dosyası seçin." + driveFileTypeWarn: "Bu dosya desteklenmiyor" + driveFileTypeWarnDescription: "Bir ses dosyası seçin" + driveFileDurationWarn: "Ses kaydı çok uzun." + driveFileDurationWarnDescription: "Uzun sesli mesajlar CherryPick'in kullanımını engelleyebilir. Devam etmek istiyor musunuz?" + driveFileError: "Ses yüklenemedi. Lütfen ayarları değiştir." +_ago: + future: "Gelecek" + justNow: "Şimdi" + secondsAgo: "{n} sn" + minutesAgo: "{n} dk" + hoursAgo: "{n} sa" + daysAgo: "{n} gün" + weeksAgo: "{n} hafta" + monthsAgo: "{n} ay" + yearsAgo: "{n} yıl" + invalid: "Geçersiz" +_timeIn: + seconds: "{n} saniye içinde" + minutes: "{n} dakika içinde" + hours: "{n} saat içinde" + days: "{n} gün içinde" + weeks: "{n} hafta içinde" + months: "{n} ay içinde" + years: "{n} yıl içinde" +_time: + second: "Saniye(ler)" + minute: "Dakika(lar)" + hour: "Saat(ler)" + day: "Gün(ler)" + month: "Ay" _2fa: - renewTOTPCancel: "Hayır, teşekkürler" + alreadyRegistered: "2fa kimlik doğrulama cihazını zaten kaydettin." + registerTOTP: "Kimlik doğrulama uygulamasını kaydet" + step1: "Öncelikle, cihazınıza bir kimlik doğrulama uygulaması (örneğin {a} veya {b}) yükleyin." + step2: "Ardından, bu ekranda görüntülenen QR kodunu tarayın." + step2Uri: "Masaüstü programı kullanıyorsanız aşağıdaki URI'yi girin" + step3Title: "Doğrulama kodunu girin" + step3: "Uygulamanız tarafından sağlanan kimlik doğrulama kodunu (token) girerek kurulumu tamamlayın." + setupCompleted: "Kurulum tamamlandı" + step4: "Bundan sonra, gelecekteki tüm oturum açma girişimlerinde bu tür bir oturum açma jetonu istenecek." + securityKeyNotSupported: "Tarayıcınız güvenlik anahtarlarını desteklemiyor." + registerTOTPBeforeKey: "Güvenlik veya geçiş anahtarını kaydetmek için bir kimlik doğrulama uygulaması kurun." + securityKeyInfo: "Parmak izi veya PIN kimlik doğrulamasının yanı sıra, hesabını daha da güvenli hale getirmek için FIDO2'yi destekleyen donanım güvenlik anahtarları aracılığıyla kimlik doğrulama da ayarlayabilirsin." + registerSecurityKey: "Güvenlik veya geçiş anahtarını kaydedin" + securityKeyName: "Bir anahtar adı girin" + tapSecurityKey: "Güvenlik veya geçiş anahtarını kaydetmek için lütfen tarayıcınızı takip edin." + removeKey: "Güvenlik anahtarını kaldır" + removeKeyConfirm: "{name} anahtarını cidden silmek istiyor musun?" + whyTOTPOnlyRenew: "Güvenlik anahtarı kayıtlı olduğu sürece kimlik doğrulama uygulaması kaldırılamaz." + renewTOTP: "Kimlik doğrulama uygulamasını yeniden yapılandırın" + renewTOTPConfirm: "Bu, önceki uygulamanızdaki doğrulama kodlarının çalışmamasına neden olacaktır." + renewTOTPOk: "Yeniden yapılandır" + renewTOTPCancel: "İptal" + checkBackupCodesBeforeCloseThisWizard: "Bu pencereyi kapatmadan önce, lütfen aşağıdaki yedek kodları not edin." + backupCodes: "Yedek kodlar" + backupCodesDescription: "İki faktörlü kimlik doğrulama uygulamasını kullanamaz hale gelmen durumunda, bu kodları kullanarak hesabınıza erişebilirsin. Her kod yalnızca bir kez kullanılabilir. Lütfen bu kodları güvenli bir yerde sakla." + backupCodeUsedWarning: "Yedek kod kullanıldı. Artık kullanamıyorsanız, lütfen iki faktörlü kimlik doğrulamayı mümkün olan en kısa sürede yeniden yapılandırın." + backupCodesExhaustedWarning: "Tüm yedek kodlar kullanıldı. İki faktörlü kimlik doğrulama uygulamana erişimini kaybedersen, bu hesaba erişemezsin. Lütfen iki faktörlü kimlik doğrulamayı yeniden yapılandır." + moreDetailedGuideHere: "İşte ayrıntılı kılavuz" _permissions: - "read:blocks": "Engellenen hesapları gör" - "write:blocks": "Engellenen hesap listesini düzenle" + "read:account": "Hesap bilgilerini gör" + "write:account": "Hesap bilgilerini düzenle" + "read:blocks": "Engellenen kullanıcıların listesini görüntüle" + "write:blocks": "Engellenen kullanıcılar listeni düzenle" + "read:drive": "Drive dosyalarına ve klasörlerine eriş" + "write:drive": "Drive dosyalarını ve klasörlerini düzenle veya sil" + "read:favorites": "Favoriler listeni görüntüle" + "write:favorites": "Favoriler listeni düzenle" + "read:following": "Takip ettiğin kişilerle ilgili bilgileri görüntüle" + "write:following": "Diğer hesapları takip et veya takipten çıkar" + "read:messaging": "Sohbetlerini görüntüle" + "write:messaging": "Sohbet mesajlarını oluşturun veya silin" + "read:mutes": "Sessize alınan kullanıcıların listesini görüntüle" + "write:mutes": "Sessize alınan kullanıcıların listesini düzenle" + "write:notes": "Notlar oluşturun veya silin" + "read:notifications": "Bildirimlerini görüntüle" + "write:notifications": "Bildirimlerini yönet" + "read:reactions": "Tepkilerini görüntüle" + "write:reactions": "Tepkilerini düzenle" + "write:votes": "Ankete oy verin" + "read:pages": "Sayfalarını görüntüle" + "write:pages": "Sayfalarını düzenle veya sil" + "read:page-likes": "Beğenilen sayfaların listesini görüntüle" + "write:page-likes": "Beğenilen sayfaların listesini düzenle" + "read:user-groups": "Kullanıcı gruplarını görüntüle" + "write:user-groups": "Kullanıcı gruplarını düzenle veya sil" + "read:channels": "Kanallarını görüntüle" + "write:channels": "Kanallarını düzenle" + "read:gallery": "Galeriyi görüntüle" + "write:gallery": "Galeri düzenle" + "read:gallery-likes": "Beğendiğin galeri gönderilerinin listesini görüntüle" + "write:gallery-likes": "Beğendiğin galeri gönderilerinin listesini düzenle" + "read:flash": "Oynat" + "write:flash": "Oyunları Düzenle" + "read:flash-likes": "Beğenilen Oyunların listesini görüntüle" + "write:flash-likes": "Beğenilen Oyunlar listesini düzenle" + "read:admin:abuse-user-reports": "Kullanıcı raporlarını görüntüle" + "write:admin:delete-account": "Kullanıcı hesabını sil" + "write:admin:delete-all-files-of-a-user": "Bir kullanıcının tüm dosyalarını sil" + "read:admin:index-stats": "Veritabanı dizin istatistiklerini görüntüle" + "read:admin:table-stats": "Veritabanı tablosu istatistiklerini görüntüle" + "read:admin:user-ips": "Kullanıcı IP adreslerini görüntüle" + "read:admin:meta": "Sunucu meta verilerini görüntüle" + "write:admin:reset-password": "Kullanıcı şifresini sıfırla" + "write:admin:resolve-abuse-user-report": "Kullanıcı raporunu çözme" + "write:admin:send-email": "E-Posta gönder" + "read:admin:server-info": "Sunucu bilgilerini görüntüle" + "read:admin:show-moderation-log": "Moderasyon günlüğünü görüntüle" + "read:admin:show-user": "Özel kullanıcı bilgilerini görüntüle" + "write:admin:suspend-user": "Kullanıcıyı askıya al" + "write:admin:unset-user-avatar": "Kullanıcı avatarını kaldır" + "write:admin:unset-user-banner": "Kullanıcı afişini kaldır" + "write:admin:unsuspend-user": "Kullanıcı askıya alma işlemini kaldır" + "write:admin:meta": "Sunucu meta verilerini yönetme" + "write:admin:user-note": "Moderasyon notunu yönet" + "write:admin:roles": "Rolleri yönet" + "read:admin:roles": "Rolü görüntüle" + "write:admin:relays": "Röleleri yönetme" + "read:admin:relays": "Röleleri görüntüle" + "write:admin:invite-codes": "Davet kodlarını yönet" + "read:admin:invite-codes": "Davet kodlarını görüntüle" + "write:admin:announcements": "Duyuruları yönet" + "read:admin:announcements": "Duyuruları görüntüle" + "write:admin:avatar-decorations": "Avatar süslerini yönetebilir" + "read:admin:avatar-decorations": "Avatar süslerini görüntüle" + "write:admin:federation": "Federasyon verilerini yönetme" + "write:admin:account": "Kullanıcı hesabını yönet" + "read:admin:account": "Kullanıcı hesabını görüntüle" + "write:admin:emoji": "Emoji'leri yönet" + "read:admin:emoji": "Emojiyi görüntüle" + "write:admin:queue": "İş kuyruğunu yönet" + "read:admin:queue": "İş kuyruğu bilgilerini görüntüle" + "write:admin:promo": "Promosyon notlarını yönet" + "write:admin:drive": "Kullanıcı Drive'ını yönet" + "read:admin:drive": "Kullanıcı Drive bilgilerini görüntüle" + "read:admin:stream": "Yönetici için WebSocket API'sını kullanın" + "write:admin:ad": "Reklamları yönet" + "read:admin:ad": "Reklamları görüntüle" + "write:invite-codes": "Davet kodları oluşturun" + "read:invite-codes": "Davet kodlarını alın" + "write:clip-favorite": "Favorilere eklenen klipleri yönet" + "read:clip-favorite": "Favorilere eklenen klipleri görüntüle" + "read:federation": "Federasyon verilerini alın" + "write:report-abuse": "İhlali bildir" + "write:chat": "Sohbet mesajlarını oluşturun veya silin" + "read:chat": "Sohbeti Gözat" +_auth: + shareAccessTitle: "Uygulama izinlerinin verilmesi" + shareAccess: "“{name}”nin bu hesaba erişmesine izin vermek ister misiniz?" + shareAccessAsk: "Bu uygulamanın hesabınıza erişmesine izin vermek istediğinden emin misin?" + permission: "{name} aşağıdaki izinleri talep etmektedir." + permissionAsk: "Bu uygulama aşağıdaki izinleri talep etmektedir" + pleaseGoBack: "Lütfen uygulamaya geri dönün." + callback: "Uygulamaya geri dönmek" + accepted: "Erişim izni verildi" + denied: "Erişim reddedildi" + scopeUser: "Aşağıdaki kullanıcı olarak çalıştırın" + pleaseLogin: "Uygulamaları yetkilendirmek için lütfen giriş yapın." + byClickingYouWillBeRedirectedToThisUrl: "Erişim izni verildiğinde, otomatik olarak aşağıdaki URL'ye yönlendirileceksin." +_antennaSources: + all: "Tüm notlar" + homeTimeline: "Takip edilen kullanıcıların notları" + users: "Belirli kullanıcılardan gelen notlar" + userList: "Belirtilen kullanıcı listesinden notlar" + userBlacklist: "Bir veya daha fazla belirli kullanıcıya ait olanlar hariç tüm notlar" +_weekday: + sunday: "Pazar" + monday: "Pazartesi" + tuesday: "Salı" + wednesday: "Çarşamba" + thursday: "Perşembe" + friday: "Cuma" + saturday: "Cumartesi" _widgets: profile: "Profil" instanceInfo: "Sunucu Bilgisi" - notifications: "Bildirim" - timeline: "Zaman çizelgesi" + memo: "Yapışkan notlar" + notifications: "Bildirimler" + timeline: "Pano" calendar: "Takvim" + trends: "Trend olan" clock: "Saat" + rss: "RSS okuyucu" + rssTicker: "RSS-Ticker" activity: "Etkinlik" + photos: "Fotoğraflar" + digitalClock: "Dijital saat" + unixClock: "UNIX saati" federation: "Federasyon" - jobQueue: "İşlem sırası" + instanceCloud: "Bulut sunucu" + postForm: "Gönderim formu" + slideshow: "Slayt gösterisi" + button: "Düğme" + onlineUsers: "Çevrimiçi kullanıcılar" + jobQueue: "İş Kuyruğu" + serverMetric: "Sunucu ölçümleri" + aiscript: "AiScript konsolu" + aiscriptApp: "AiScript Uygulaması" + aichan: "Ai" + userList: "Kullanıcı listesi" _userList: - chooseList: "Bir liste seç" + chooseList: "Bir liste seçin" + clicker: "Tıklayıcı" + birthdayFollowings: "Bugünün Doğum Günleri" + chat: "Sohbet" _cw: - show: "Devamını yükle" + hide: "Gizle" + show: "İçeriği göster" + chars: "{count} karakter" + files: "{count} dosya(lar)" _poll: - vote: "Oy kullan" + noOnlyOneChoice: "En az iki seçenek gereklidir." + choiceN: "Seçim {n}" + noMore: "Daha fazla seçenek ekleyemezsin." + canMultipleVote: "Birden fazla seçenek seçilmesine izin ver" + expiration: "Anketi sonlandır" + infinite: "Asla" + at: "Şurada bitir..." + after: "Sonrasında bitir..." + deadlineDate: "Bitiş tarihi" + deadlineTime: "Zaman" + duration: "Süre" + votesCount: "{n} oy" + totalVotes: "Toplam {n} oy" + vote: "Oy ver" + showResult: "Sonuçları görüntüle" + voted: "Oylandı" + closed: "Sona erdi" + remainingDays: "{d} gün {h} saat kaldı" + remainingHours: "{h} saat {m} dakika kaldı" + remainingMinutes: "{m} dakika {s} saniye kaldı" + remainingSeconds: "{s} saniye kaldı" _visibility: - publicDescription: "Herkese açık" - home: "Ana sayfa" - followers: "takipçi" + public: "Halka açık" + publicDescription: "Notunuz tüm kullanıcılar tarafından görülebilir olacaktır." + home: "Pano" + homeDescription: "Yalnızca ana panoya gönder" + followers: "Takipçiler" + followersDescription: "Sadece takipçilerine görünür hale getir" + specified: "Doğrudan" + specifiedDescription: "Yalnızca belirli kullanıcılar için görünür hale getir" + disableFederation: "Federasyon olmadan" + disableFederationDescription: "Diğer sunuculara aktarma" +_postForm: + quitInspiteOfThereAreUnuploadedFilesConfirm: "Yüklenmemiş dosyalar var, bunları silip formu kapatmak ister misin?" + uploaderTip: "Dosya henüz yüklenmemiş. Dosya menüsünden dosyayı yeniden adlandırabilir, görüntüleri kırpabilir, filigran ekleyebilir ve dosyayı sıkıştırabilir veya sıkıştırmayı kaldırabilirsin. Notu yayınladığında dosyalar otomatik olarak yüklenir." + replyPlaceholder: "Bu notu yanıtla..." + quotePlaceholder: "Bu notu alıntı yap..." + channelPlaceholder: "Bir kanala gönder..." + _placeholders: + a: "Ne yapıyorsun?" + b: "Çevrende neler oluyor?" + c: "Aklında ne var?" + d: "Ne söylemek istiyorsun?" + e: "Yazmaya başlayın..." + f: "Yazmanızı bekliyoruz..." _profile: - username: "Kullanıcı Adı" + name: "Ad" + username: "Kullanıcı adı" + description: "Biyografi" + youCanIncludeHashtags: "Biyografinize hashtag'ler de ekleyebilirsiniz." + metadata: "Ek Bilgiler" + metadataEdit: "Ek bilgileri düzenle" + metadataDescription: "Bunları kullanarak profilinde ek bilgi alanları görüntüleyebilirsin." + metadataLabel: "Etiket" + metadataContent: "İçerik" + changeAvatar: "Avatar değiştir" + changeBanner: "Banner değiştir" + verifiedLinkDescription: "Buraya profiline bağlantı içeren bir URL girerek, alanın yanında bir sahiplik doğrulama simgesi görüntülenebilir." + avatarDecorationMax: "En fazla {max} süs ekleyebilirsin." + followedMessage: "Takip edildiğinizde gönderilen mesaj" + followedMessageDescription: "Abonelerin seni takip ettiklerinde görüntülenmesini istediğin kısa bir mesaj ayarlayabilirsin." + followedMessageDescriptionForLockedAccount: "Takip isteklerinin onay gerektirmesini ayarladıysan, bir takip isteğini kabul ettiğinde bu mesaj görüntülenir." _exportOrImport: - followingList: "takipçi" - muteList: "Gizle" - blockingList: "engelle" - userLists: "Listeler" + allNotes: "Tüm notlar" + favoritedNotes: "Favori notlar" + clips: "Klip" + followingList: "Takip edilen kullanıcılar" + muteList: "Sessize alınan kullanıcılar" + blockingList: "Engellenen kullanıcılar" + userLists: "Kullanıcı listeleri" + excludeMutingUsers: "Sessize alınan kullanıcıları hariç tut" + excludeInactiveUsers: "Etkin olmayan kullanıcıları hariç tut" + withReplies: "İçe aktarılan kullanıcıların yanıtlarını panoya dahil edin" _charts: federation: "Federasyon" + apRequest: "Talepler" + usersIncDec: "Kullanıcı sayısındaki fark" + usersTotal: "Toplam kullanıcı sayısı" + activeUsers: "Aktif kullanıcılar" + notesIncDec: "Not sayısındaki fark" + localNotesIncDec: "Yerel notaların sayısındaki fark" + remoteNotesIncDec: "Uzak notların sayısındaki fark" + notesTotal: "Toplam not sayısı" + filesIncDec: "Dosya sayısındaki fark" + filesTotal: "Toplam dosya sayısı" + storageUsageIncDec: "Depolama kullanımı farkı" + storageUsageTotal: "Total storage usage" +_instanceCharts: + requests: "Talepler" + users: "Kullanıcı sayısındaki fark" + usersTotal: "Toplam kullanıcı sayısı" + notes: "Not sayısındaki fark" + notesTotal: "Toplam not sayısı" + ff: "Takip / Takipçi sayısı farkı" + ffTotal: "Takip / Takipçi toplam sayısı" + cacheSize: "Önbellek boyutundaki fark" + cacheSizeTotal: "Önbelleğin toplam boyutu" + files: "Dosya sayısındaki fark" + filesTotal: "Toplam dosya sayısı" _timelines: - home: "Ana sayfa" - global: "Küresel" + home: "Pano" + local: "Yerel" + social: "Sosyal" + global: "Global" +_play: + new: "Oyun Oluştur" + edit: "Düzenle Oynat" + created: "Oyun oluşturuldu" + updated: "Düzenlenmiş oynat" + deleted: "Oyun silindi" + pageSetting: "Oyun ayarları" + editThisPage: "Bu Oyunu Düzenle" + viewSource: "Kaynak görüntüle" + my: "Oyunlarım" + liked: "Beğenilen Oyunlar" + featured: "Popüler" + title: "Başlık" + script: "Senaryo" + summary: "Açıklama" + visibilityDescription: "Özel olarak ayarlamak, profilinde görünmeyeceği anlamına gelir, ancak URL'ye sahip olan herkes yine de erişebilir." _pages: + newPage: "Yeni bir Sayfa oluşturun" + editPage: "Bu sayfayı düzenle" + readPage: "Bu Sayfanın Kaynağını Görüntüleme" + pageSetting: "Sayfa ayarları" + nameAlreadyExists: "Belirtilen Sayfa URL'si zaten mevcut." + invalidNameTitle: "Belirtilen Sayfa URL geçersiz" + invalidNameText: "Sayfa başlığının boş olmadığından emin olun." + editThisPage: "Bu sayfayı düzenle" + viewSource: "Kaynak görüntüle" + viewPage: "Sayfalarını görüntüle" + like: "Beğen" + unlike: "Benzerlerini kaldır" + my: "Benzerlerini kaldır" + liked: "Beğenilen Sayfalar" + featured: "Popüler" + inspector: "Müfettiş" + contents: "İçindekiler" + content: "Sayfa bloğu" + variables: "Değişkenler" + title: "Başlık" + url: "Sayfa URL'si" + summary: "Sayfa özeti" + alignCenter: "Merkez öğeleri" + hideTitleWhenPinned: "Profiline sabitlendiğinde sayfa başlığını gizle" + font: "Yazı tipi" + fontSerif: "Serif" + fontSansSerif: "Sans Serif" + eyeCatchingImageSet: "Küçük resmi ayarla" + eyeCatchingImageRemove: "Küçük resmi sil" + chooseBlock: "Blok ekle" + enterSectionTitle: "Bölüm başlığını girin" + selectType: "Bir tür seçin" + contentBlocks: "İçerik" + inputBlocks: "Giriş" + specialBlocks: "Özel" blocks: + text: "Metin" + textarea: "Metin alanı" + section: "Bölüm" image: "Görseller" + button: "Düğme" + dynamic: "Dinamik Bloklar" + dynamicDescription: "Bu blok kaldırılmıştır. Bundan sonra lütfen {play} kullanın." + note: "Gömülü not" + _note: + id: "Not Kimliği" + idDescription: "Alternatif olarak notun URL buraya yapıştırabilirsin." + detailed: "Ayrıntılı görünüm" +_relayStatus: + requesting: "Beklemede" + accepted: "Accepted" + rejected: "Reddedildi" _notification: + fileUploaded: "Dosya başarıyla yüklendi" + youGotMention: "{name} sizden bahsetti." + youGotReply: "{name} size yanıt verdi" + youGotQuote: "{name} sizden alıntı yaptı" + youRenoted: "{name}'den Renote" youWereFollowed: "seni takip etti" + youReceivedFollowRequest: "Bir takip isteği aldınız." + yourFollowRequestAccepted: "Takip isteğin kabul edildi." + pollEnded: "Anket sonuçları açıklandı." + newNote: "Yeni not" unreadAntennaNote: "{name} anteni" + roleAssigned: "Verilen rol" + chatRoomInvitationReceived: "Sohbet odasına davet edildin." + emptyPushNotificationMessage: "Push bildirimleri güncellendi" + achievementEarned: "Achievement unlocked" + testNotification: "Test bildirimi" + checkNotificationBehavior: "Bildirim görünümünü kontrol edin" + sendTestNotification: "Test bildirimi gönder" + notificationWillBeDisplayedLikeThis: "Bildirimler şöyle görünür" + reactedBySomeUsers: "{n} kullanıcı tepki gösterdi" + likedBySomeUsers: "{n} kullanıcı notunuzu beğendi." + renotedBySomeUsers: "{n} kullanıcıdan gelen hatırlatma" + followedBySomeUsers: "{n} kullanıcı tarafından takip ediliyor" + flushNotification: "Bildirimleri temizle" + exportOfXCompleted: "{x} ihracatı tamamlandı." + login: "Biri oturum açtı" + createToken: "Bir erişim jetonu oluşturuldu." + createTokenDescription: "Eğer bilmiyorsanız, “{text}” aracılığıyla erişim jetonunu silin." _types: - follow: "takipçi" - mention: "Bahset" - renote: "vazgeçme" - quote: "alıntı" - reaction: "Tepkiler" - receiveFollowRequest: "Takip isteği alındı" - followRequestAccepted: "Takip isteği kabul edildi" - login: "Giriş Yap " + all: "Tümü" + note: "Yeni notlar" + follow: "Yeni takipçiler" + mention: "Bahsetmeler" + reply: "Yanıtlar" + renote: "Renote" + quote: "Alıntılar" + reaction: "Tepki" + pollEnded: "Anketler sona eriyor" + receiveFollowRequest: "Takip istekleri alındı" + followRequestAccepted: "Kabul edilen takip istekleri" + roleAssigned: "Verilen rol" + chatRoomInvitationReceived: "Sohbet odasına davet edildi" + achievementEarned: "Başarı kilidi açıldı" + exportCompleted: "İhracat işlemi tamamlandı." + login: "Oturum Aç" + createToken: "Erişim jetonu oluştur" + test: "Bildirim testi" + app: "Bağlı uygulamalardan gelen bildirimler" _actions: - reply: "yanıt" - renote: "vazgeçme" + followBack: "seni takip ettim" + reply: "Yanıtla" + renote: "Renote" _deck: - configureColumn: "Sütun seçenekleri" + alwaysShowMainColumn: "Ana sütunu her zaman göster" + columnAlign: "Sütunları hizala" + columnGap: "Sütunlar arasındaki kenar boşluğu" + deckMenuPosition: "Sütunlar arasındaki kenar boşluğu" + navbarPosition: "Gezinti çubuğu konumu" + addColumn: "Sütun ekle" + newNoteNotificationSettings: "Notification setting for new notes" + configureColumn: "Sütun ayarları" + swapLeft: "Sol sütunla değiştir" + swapRight: "Sağ sütunla değiştir" + swapUp: "Yukarıdaki sütunla değiştir" + swapDown: "Aşağıdaki sütunla değiştir" + stackLeft: "Sol sütunda yığın" + popRight: "Sağdaki pop sütunu" + profile: "Profil" + newProfile: "Yeni profil" + deleteProfile: "Profili sil" + introduction: "Sütunları serbestçe düzenleyerek size en uygun arayüzü oluşturun!" + introduction2: "Ekranın sağındaki + işaretine tıklayarak istediğin zaman yeni sütunlar ekleyebilirsin." + widgetsIntroduction: "Lütfen sütun menüsünden “Widget'ları düzenle” seçeneğini seç ve bir widget ekle." + useSimpleUiForNonRootPages: "Gezinilen sayfalar için basit kullanıcı arayüzü kullanın" + usedAsMinWidthWhenFlexible: "“Otomatik genişlik ayarı” seçeneği etkinleştirildiğinde, bunun için minimum genişlik kullanılacak." + flexible: "Otomatik genişlik ayarı" + enableSyncBetweenDevicesForProfiles: "Cihazlar arasında profil bilgilerinin senkronizasyonunu etkinleştir" _columns: - notifications: "Bildirim" - tl: "Zaman çizelgesi" - list: "Listeler" + main: "Ana" + widgets: "Widget'lar" + notifications: "Bildirimler" + tl: "Pano" + antenna: "Antenler" + list: "Liste" + channel: "Kanal" mentions: "Bahsetmeler" + direct: "Doğrudan notlar" + roleTimeline: "Rol Pano" + chat: "Sohbet" +_dialog: + charactersExceeded: "Maksimum karakter sınırını aştınız! Şu anda {current} karakterde {max} karakterlik sınırın {current} karakterinde bulunuyorsunuz." + charactersBelow: "You're below the minimum character limit! Currently at {current} of {min}." +_disabledTimeline: + title: "Pano devre dışı bırakıldı" + description: "Mevcut rollerinle bu Pano kullanılamaz." +_drivecleaner: + orderBySizeDesc: "Azalan Dosya Boyutları" + orderByCreatedAtAsc: "Yükselen Tarihler" +_webhookSettings: + createWebhook: "Webhook oluştur" + modifyWebhook: "Webhook'u değiştir" + name: "Webhook'u değiştir" + secret: "Gizli" + trigger: "Tetikleyici" + active: "Etkin" + _events: + follow: "Bir kullanıcıyı takip ederken" + followed: "Takip edildiğinde" + note: "Not gönderirken" + reply: "Yanıt alındığında" + renote: "Yeniden not edildiğinde" + reaction: "Tepki aldığınızda" + mention: "Bahsedildiğinde" + _systemEvents: + abuseReport: "Yeni bir rapor alındığında" + abuseReportResolved: "Çözüldüğünde rapor" + userCreated: "Kullanıcı oluşturulduğunda" + inactiveModeratorsWarning: "Moderatörler bir süredir aktif olmadıklarında" + inactiveModeratorsInvitationOnlyChanged: "Bir moderatör bir süre aktif olmadığında ve sunucu davetle erişilebilir hale getirildiğinde" + deleteConfirm: "Webhook'u silmek istediğinden emin misin?" + testRemarks: "Anahtarın sağındaki düğmeyi tıklayarak sahte verilerle bir test Webhook gönderin." +_abuseReport: + _notificationRecipient: + createRecipient: "Raporlar için alıcı ekle" + modifyRecipient: "Raporlar için alıcıyı düzenle" + recipientType: "Bildirim türü" + _recipientType: + mail: "E-Posta" + webhook: "Webhook" + _captions: + mail: "Raporları aldığınızda, E-Postayı moderatörlerin e-posta adreslerine gönderin." + webhook: "Raporları aldığınızda veya çözdüğünüzde Sistem Webhook'una bir bildirim gönderin." + keywords: "Anahtar kelimeler" + notifiedUser: "Bildirilecek kullanıcılar" + notifiedWebhook: "Kullanılacak webhook" + deleteConfirm: "Bildirim alıcısını silmek istediğinden emin misin?" _moderationLogTypes: - suspend: "askıya al" - resetPassword: "Şifre sıfırlama" + createRole: "Rol oluşturuldu" + deleteRole: "Rol silindi" + updateRole: "Rol güncellendi" + assignRole: "Rol atandı" + unassignRole: "Görevinden alınmış" + suspend: "Askıya alınmış" + unsuspend: "Askıya alınmamış" + addCustomEmoji: "Özel emoji eklendi" + updateCustomEmoji: "Özel emoji güncellendi" + deleteCustomEmoji: "Özel emoji silindi" + updateServerSettings: "Sunucu ayarları güncellendi" + updateUserNote: "Moderasyon notu güncellendi" + deleteDriveFile: "Dosya silindi" + deleteNote: "Not silindi" + createGlobalAnnouncement: "Global duyuru oluşturuldu" + createUserAnnouncement: "Kullanıcı duyurusu oluşturuldu" + updateGlobalAnnouncement: "Global duyuru güncellendi" + updateUserAnnouncement: "Kullanıcı duyurusu güncellendi" + deleteGlobalAnnouncement: "Global duyuru silindi" + deleteUserAnnouncement: "Kullanıcı duyurusu silindi" + resetPassword: "Şifreyi sıfırla" + suspendRemoteInstance: "Uzak sunucu askıya alındı" + unsuspendRemoteInstance: "Uzak sunucu askıya alınmadı" + updateRemoteInstanceNote: "Uzak sunucular için güncellenmiş moderasyon notu" + markSensitiveDriveFile: "Hassas olarak işaretlenmiş dosya" + unmarkSensitiveDriveFile: "Dosya hassas olarak işaretlenmemiş" + resolveAbuseReport: "Rapor çözüldü" + forwardAbuseReport: "Rapor iletildi" + updateAbuseReportNote: "Güncellenen raporun moderasyon notu" + createInvitation: "Davet oluşturuldu" + createAd: "Reklam oluşturuldu" + deleteAd: "Reklam silindi" + updateAd: "Reklam güncellendi" + createAvatarDecoration: "Avatar dekorasyonu oluşturuldu" + updateAvatarDecoration: "Avatar dekorasyonu güncellendi" + deleteAvatarDecoration: "Avatar süsü silindi" + unsetUserAvatar: "Kullanıcı avatarı ayarlanmamış" + unsetUserBanner: "Kullanıcı başlığı ayarlanmamış" + createSystemWebhook: "Sistem Webhook oluşturuldu" + updateSystemWebhook: "Sistem Webhook güncellendi" + deleteSystemWebhook: "Sistem Webhook silindi" + createAbuseReportNotificationRecipient: "Oluşturulan raporlar için alıcı" + updateAbuseReportNotificationRecipient: "Raporlar için alıcı güncellendi" + deleteAbuseReportNotificationRecipient: "Silinen raporlar için alıcı" + deleteAccount: "Hesap silindi" + deletePage: "Sayfa silindi" + deleteFlash: "Oyun silindi" + deleteGalleryPost: "Galeri gönderisi silindi" + deleteChatRoom: "Deleted Chat Room" + updateProxyAccountDescription: "Proxy hesabının açıklamasını güncelle" +_fileViewer: + title: "Dosya ayrıntıları" + type: "Dosya türü" + size: "Dosya boyutu" + url: "URL" + uploadedAt: "Yüklendiği tarih" + attachedNotes: "Ekli notlar" + usage: "Kullanılmış" + thisPageCanBeSeenFromTheAuthor: "Bu sayfa, bu dosyayı yükleyen kullanıcı tarafından görülebilir." +_externalResourceInstaller: + title: "Harici siteden yükle" + checkVendorBeforeInstall: "Yüklemeden önce bu kaynağın dağıtımcısının güvenilir olduğundan emin olun." + _plugin: + title: "Bu eklentiyi yüklemek ister misin?" + _theme: + title: "Bu temayı yüklemek ister misin?" + _meta: + base: "Temel renk şeması" + _vendorInfo: + title: "Dağıtıcı bilgileri" + endpoint: "Referans uç nokta" + hashVerify: "Hash doğrulama" + _errors: + _invalidParams: + title: "Geçersiz parametreler" + description: "Harici bir siteden veri yüklemek için yeterli bilgi yok. Lütfen girdiğin URL'yi kontrol et." + _resourceTypeNotSupported: + title: "Bu harici kaynak desteklenmemektedir." + description: "Bu harici kaynağın türü desteklenmemektedir. Lütfen site yöneticisiyle iletişime geç." + _failedToFetch: + title: "Veriler alınamadı" + fetchErrorDescription: "Harici siteyle iletişim sırasında bir hata oluştu. Tekrar denemen sorunu çözmezse, lütfen site yöneticisine başvur." + parseErrorDescription: "Harici siteden yüklenen veriler işlenirken bir hata oluştu. Lütfen site yöneticisiyle iletişime geçin." + _hashUnmatched: + title: "Veri doğrulama başarısız oldu" + description: "Alınan verilerin bütünlüğünü doğrularken bir hata oluştu. Güvenlik önlemi olarak, kurulum devam edemez. Lütfen site yöneticisiyle iletişime geçin." + _pluginParseFailed: + title: "AiScript Hatası" + description: "İstenen veriler başarıyla alındı, ancak AiScript ayrıştırma sırasında bir hata oluştu. Lütfen eklenti yazarına başvurun. Hata ayrıntıları Javascript konsolunda görüntülenebilir." + _pluginInstallFailed: + title: "Eklenti kurulumu başarısız oldu" + description: "Eklenti yükleme sırasında bir sorun oluştu. Lütfen tekrar dene. Hata ayrıntıları Javascript konsolunda görüntülenebilir." + _themeParseFailed: + title: "Tema ayrıştırma başarısız oldu" + description: "İstenen veriler başarıyla alındı, ancak tema ayrıştırma sırasında bir hata oluştu. Lütfen tema yazarıyla iletişime geçin. Hata ayrıntıları Javascript konsolunda görüntülenebilir." + _themeInstallFailed: + title: "Tema yüklenemedi" + description: "Tema yükleme sırasında bir sorun oluştu. Lütfen tekrar dene. Hata ayrıntıları Javascript konsolunda görüntülenebilir." +_dataSaver: + _media: + title: "Medya yükleniyor" + description: "Görüntülerin/videoların otomatik olarak yüklenmesini engeller. Gizli görüntüler/videolar dokunulduğunda yüklenir." + _avatar: + title: "Avatar resmi" + description: "Avatar görüntüsünün animasyonunu durdurun. Animasyonlu görüntüler normal görüntülere göre dosya boyutu açısından daha büyük olabilir ve bu da veri trafiğinde daha fazla azalmaya yol açabilir." + _urlPreviewThumbnail: + title: "URL önizleme küçük resimlerini gizle" + description: "URL önizleme küçük resimleri artık yüklenmeyecek." + _disableUrlPreview: + title: "URL önizlemesini devre dışı bırak" + description: "URL önizleme işlevini devre dışı bırakır. Küçük resimler aksine, bu işlev bağlantılı bilgilerin kendisinin yüklenmesini azaltır." + _code: + title: "Kod vurgulama" + description: "MFC vb. programlarda kod vurgulama notasyonları kullanılıyorsa, bunlar dokunulana kadar yüklenmez. Sözdizimi vurgulama, her programlama dili için vurgu tanım dosyalarının indirilmesini gerektirir. Bu nedenle, bu dosyaların otomatik olarak yüklenmesinin devre dışı bırakılması, iletişim verisi miktarını azaltması beklenir." +_hemisphere: + N: "Kuzey Yarımküre" + S: "Güney Yarımküre" + caption: "Bazı istemci ayarlarında mevsimi belirlemek için kullanılır." +_reversi: + reversi: "Tersine çevirme" + gameSettings: "Oyun ayarları" + chooseBoard: "Bir tahta seçin" + blackOrWhite: "Siyah/Beyaz" + blackIs: "{name} siyah oynuyor." + rules: "Kurallar" + thisGameIsStartedSoon: "Oyun kısa süre içinde başlayacak." + waitingForOther: "Rakibin sırasını bekle" + waitingForMe: "Sıranı bekliyorsun" + waitingBoth: "Hazır olun" + ready: "Hazır" + cancelReady: "Hazır değil" + opponentTurn: "Rakibin sırası" + myTurn: "Sıra sende" + turnOf: "Sıra {name}'de." + pastTurnOf: "{name}'nin sırası" + surrender: "Teslimiyet" + surrendered: "Teslim oldu" + timeout: "Zaman doldu" + drawn: "Çiz" + won: "{name} kazandı" + black: "Siyah" + white: "Beyaz" + total: "Toplam" + turnCount: "{count} döndür" + myGames: "Benim turlarım" + allGames: "Tüm turlar" + ended: "Sona erdi" + playing: "Şu anda oynatılıyor" + isLlotheo: "Taş sayısı daha az olan kazanır (Llotheo)" + loopedMap: "Döngüsel harita" + canPutEverywhere: "Fayanslar her yere yerleştirilebilir." + timeLimitForEachTurn: "Sıra için zaman sınırı" + freeMatch: "Ücretsiz Eşleştirme" + lookingForPlayer: "Rakip aranıyor..." + gameCanceled: "Oyun iptal edildi." + shareToTlTheGameWhenStart: "Oyun başlatıldığında panoda paylaş" + iStartedAGame: "Oyun başladı! #MisskeyReversi" + opponentHasSettingsChanged: "Rakip ayarlarını değiştirmiş." + allowIrregularRules: "Düzensiz kurallar (tamamen ücretsiz)" + disallowIrregularRules: "Düzensiz kurallar yok" + showBoardLabels: "Tahtada satır ve sütun numaralarını göster" + useAvatarAsStone: "Taşları kullanıcı avatarlarına dönüştürün" +_offlineScreen: + title: "Çevrimdışı - sunucuya bağlanılamıyor" + header: "Sunucuya bağlanılamıyor" +_urlPreviewSetting: + title: "URL önizleme ayarları" + enable: "URL önizlemesini etkinleştir" + allowRedirect: "URL önizleme yönlendirmesine izin ver" + allowRedirectDescription: "Bir URL'de yönlendirme ayarlanmışsa, bu özelliği etkinleştirerek yönlendirmeyi takip edebilir ve yönlendirilen içeriğin önizlemesini görüntüleyebilirsin. Bu özelliği devre dışı bırakmak sunucu kaynaklarından tasarruf sağlar, ancak yönlendirilen içerik görüntülenmez." + timeout: "Önizleme alırken zaman aşımı (ms)" + timeoutDescription: "Önizlemeyi almak bu değerden daha uzun sürerse, önizleme oluşturulmaz." + maximumContentLength: "Maksimum İçerik Uzunluğu (bayt)" + maximumContentLengthDescription: "Content-Length bu değerden yüksekse, önizleme oluşturulmaz." + requireContentLength: "Yalnızca Content-Length değerini alabiliyorsanız önizlemeyi oluşturun." + requireContentLengthDescription: "Diğer sunucu Content-Length değerini döndürmezse, önizleme oluşturulmaz." + userAgent: "Kullanıcı Aracısı" + userAgentDescription: "Önizlemeleri alırken kullanılacak Kullanıcı Aracısını ayarlar. Boş bırakılırsa, varsayılan Kullanıcı Aracısı kullanılır." + summaryProxy: "Önizlemeler oluşturan proxy uç noktaları" + summaryProxyDescription: "CherryPick'in kendisi değil, Summaly Proxy kullanarak önizlemeler oluştur." + summaryProxyDescription2: "Aşağıdaki parametreler, sorgu dizesi olarak proxy'ye bağlanır. Proxy bunları desteklemiyorsa, değerler yok sayılır." +_mediaControls: + pip: "Resim içinde resim" + playbackRate: "Oynatma Hızı" + loop: "Döngüsel oynatma" +_contextMenu: + title: "Bağlam menüsü" + app: "Uygulama" + appWithShift: "Shift tuşuyla uygulama" + native: "Doğal" +_gridComponent: + _error: + requiredValue: "Bu değer gereklidir." + columnTypeNotSupport: "Düzenli ifade ile doğrulama yalnızca type:text sütunları için desteklenir." + patternNotMatch: "Bu değer {pattern} içindeki desenle eşleşmiyor." + notUnique: "Bu değer benzersiz olmalıdır." +_roleSelectDialog: + notSelected: "Seçilmedi" +_customEmojisManager: + _gridCommon: + copySelectionRows: "Seçili satırları kopyala" + copySelectionRanges: "Seçimi kopyala" + deleteSelectionRows: "Seçili satırları sil" + deleteSelectionRanges: "Seçimdeki satırları sil" + searchSettings: "Arama ayarları" + searchSettingCaption: "Ayrıntılı arama kriterleri belirle." + searchLimit: "Sonuç sayısı" + sortOrder: "Sıralama düzeni" + registrationLogs: "Kayıt günlüğü" + registrationLogsCaption: "Emojileri güncellerken veya silerken günlükler görüntülenecek. Güncelleme veya silme işleminden sonra, yeni bir sayfaya geçildiğinde veya yeniden yüklendiğinde günlükler kaybolacak." + alertEmojisRegisterFailedDescription: "Emojileri güncelleyemedi veya silemedi. Ayrıntılar için kayıt günlüğünü kontrol edin." + _logs: + showSuccessLogSwitch: "Başarı günlüğünü göster" + failureLogNothing: "Hata günlüğü yoktur." + logNothing: "Günlük kaydı yok." + _remote: + selectionRowDetail: "Seçilen satırın ayrıntıları" + importSelectionRows: "Seçilen satırları içe aktar" + importSelectionRangesRows: "Seçimdeki satırları içe aktar" + importEmojisButton: "Kontrol edilen Emojileri içe aktar" + confirmImportEmojisTitle: "Emoji'leri İçe Aktar" + confirmImportEmojisDescription: "Uzak sunucudan alınan {count} Emoji(ler)i içe aktarın. Emoji lisansına dikkat edin. Devam etmek istediğinizden emin misiniz?" + _local: + tabTitleList: "Kayıtlı emojiler" + tabTitleRegister: "Emoji kaydı" + _list: + emojisNothing: "Kayıtlı Emoji yok." + markAsDeleteTargetRows: "Silinecek hedef olarak seçilen satırları işaretle" + markAsDeleteTargetRanges: "Seçimdeki satırları silinecek hedef olarak işaretle" + alertUpdateEmojisNothingDescription: "Güncellenmiş Emoji yok." + alertDeleteEmojisNothingDescription: "Silinecek Emoji yok." + confirmMovePage: "Sayfaları taşımak ister misin?" + confirmChangeView: "Görüntüleme şeklini değiştirmek ister misn?" + confirmUpdateEmojisDescription: "{count} Emoji'yi güncelle. Devam etmek istediğinden emin misin?" + confirmDeleteEmojisDescription: "İşaretli {count} Emoji(leri) silin. Devam etmek istediğinden emin misin?" + confirmResetDescription: "Şimdiye kadar yapılan tüm değişiklikler geri alınacaktır." + confirmMovePageDesciption: "Bu sayfadaki Emojilerde değişiklikler yapılmış.\nSayfayı kaydetmeden terk ederseniz, bu sayfada yapılan tüm değişiklikler silinecek." + dialogSelectRoleTitle: "Emojilerde rol setine göre arama yapın" + _register: + uploadSettingTitle: "Yükleme ayarları" + uploadSettingDescription: "Bu ekranda, Emoji yüklerken davranışı yapılandırabilirsin." + directoryToCategoryLabel: "“Kategori” alanına dizin adını girin." + directoryToCategoryCaption: "Bir dizini sürükleyip bıraktığınızda, “kategori” alanına dizin adını girin." + confirmRegisterEmojisDescription: "Listeden Emojileri yeni özel Emojiler olarak kaydet. Devam etmek istediğinden emin misin? (Aşırı yüklemeyi önlemek için, tek bir işlemde yalnızca {count} Emoji kaydedilebilir)" + confirmClearEmojisDescription: "Düzenlemeleri sil ve listeden Emojileri temizle. Devam etmek istediğinden emin misiniz?" + confirmUploadEmojisDescription: "Drive'a sürüklenip bırakılan {count} dosyayı yükle. Devam etmek istediğinden emin misin?" +_embedCodeGen: + title: "Gömme kodunu özelleştir" + header: "Başlığı göster" + autoload: "Otomatik olarak daha fazlasını yükle (kullanımdan kaldırıldı)" + maxHeight: "Maksimum yükseklik" + maxHeightDescription: "0 olarak ayarlandığında maksimum yükseklik ayarı devre dışı bırakılır. Widget'ın dikey olarak genişlemeye devam etmesini önlemek için bir değer belirt." + maxHeightWarn: "Maksimum yükseklik sınırı devre dışıdır (0). Bu istenmeyen bir durumsa, maksimum yüksekliği bir değer olarak ayarla." + previewIsNotActual: "Ekran, önizleme ekranında görüntülenen aralığı aştığı için gerçek gömme işleminden farklıdır." + rounded: "Yuvarlak hale getir" + border: "Dış çerçeveye kenarlık ekle" + applyToPreview: "Önizlemeye başvur" + generateCode: "Gömme kodu oluştur" + codeGenerated: "Kod oluşturuldu" + codeGeneratedDescription: "Oluşturulan kodu web sitene yapıştırarak içeriği göm." +_selfXssPrevention: + warning: "UYARI" + title: "“Bu ekrana bir şey yapıştırın” tamamen bir aldatmaca." + description1: "Buraya bir şey yapıştırırsan, kötü niyetli bir kullanıcı hesabını ele geçirebilir veya kişisel bilgilerini çalabilir." + description2: "Yapıştırmaya çalıştığınız şeyi tam olarak anlamıyorsanız, %c hemen çalışmayı bırakın ve bu pencereyi kapatın." + description3: "Daha fazla bilgi için lütfen buraya bakın. {link}" +_followRequest: + recieved: "Talep alındı" + sent: "İstek gönderildi" +_remoteLookupErrors: + _federationNotAllowed: + title: "Bu sunucuyla iletişim kurulamıyor" + description: "Bu sunucu ile iletişim devre dışı bırakılmış olabilir veya bu sunucu engellenmiş olabilir.\nLütfen sunucu yöneticisi ile iletişime geçin." + _uriInvalid: + title: "URI geçersiz" + description: "Girdiğin URI ile ilgili bir sorun var. Lütfen URI'da kullanılamayan karakterler girip girmediğini kontrol et." + _requestFailed: + title: "İstek başarısız oldu" + description: "Bu sunucuyla iletişim kurulamadı. Sunucu kapalı olabilir. Ayrıca, geçersiz veya mevcut olmayan bir URI girmediğinizden emin ol." + _responseInvalid: + title: "Yanıt geçersiz" + description: "Bu sunucuyla iletişim kurabildi, ancak elde edilen veriler yanlıştı." + _noSuchObject: + title: "Bulunamadı" + description: "İstenen kaynak bulunamadı, lütfen URI'yi tekrar kontrol edin." +_captcha: + verify: "Lütfen CAPTCHA'yı doğrulayın" + testSiteKeyMessage: "Site ve gizli anahtarlar için test değerlerini girerek önizlemeyi kontrol edebilirsin.\nAyrıntılar için lütfen aşağıdaki sayfaya bak." + _error: + _requestFailed: + title: "CAPTCHA isteği başarısız oldu" + text: "Lütfen bir süre sonra tekrar çalıştırın veya ayarları tekrar kontrol edin." + _verificationFailed: + title: "CAPTCHA doğrulaması başarısız oldu" + text: "Ayarların doğru olup olmadığını lütfen tekrar kontrol edin." + _unknown: + title: "CAPTCHA hatası" + text: "Beklenmedik bir hata oluştu." +_bootErrors: + title: "Yükleme başarısız" + serverError: "Bir süre bekledikten ve yeniden yükledikten sonra sorun devam ederse, lütfen aşağıdaki Hata ID ile sunucu yöneticisine başvurun." + solution: "Aşağıdakiler sorunu çözebilir." + solution1: "Tarayıcını ve işletim sistemini en son sürüme güncelle." + solution2: "Reklam engelleyiciyi devre dışı bırak" + solution3: "Tarayıcı önbelleğini temizle" + solution4: "Tor Tarayıcı için dom.webaudio.enabled değerini true olarak ayarlayın." + otherOption: "Diğer seçenekler" + otherOption1: "İstemci ayarlarını ve önbelleği sil" + otherOption2: "Basit istemciyi başlatın" + otherOption3: "Onarım aracını başlatın" + otherOption4: "CherryPick'i güvenli modda başlatın" _search: searchScopeAll: "Tümü" + searchScopeLocal: "Yerel" + searchScopeServer: "Spesifik sunucu" + searchScopeUser: "Spesifik kullanıcı" + pleaseEnterServerHost: "Sunucu ana bilgisayarını girin" + pleaseSelectUser: "Kullanıcı seç" + serverHostPlaceholder: "Örnek: cherrypick.example.com" +_serverSetupWizard: + installCompleted: "CherryPick kurulumu tamamlandı!" + firstCreateAccount: "Başlamak için bir yönetici hesabı oluşturun." + accountCreated: "Yönetici hesabı oluşturuldu!" + serverSetting: "Sunucu Ayarları" + youCanEasilyConfigureOptimalServerSettingsWithThisWizard: "Bu sihirbaz, sunucu ayarlarını yapılandırmayı kolaylaştırır." + settingsYouMakeHereCanBeChangedLater: "Bu sihirbaz aracılığıyla değiştirilen ayarlar daha sonra yeniden düzenlenebilir." + howWillYouUseMisskey: "CherryPick'i nasıl kullanacaksınız?" + _use: + single: "Tek Kullanıcı Sunucusu" + single_description: "Kendi sunucunuz olarak tek başına kullanın." + single_youCanCreateMultipleAccounts: "Tek kullanıcı sunucusu olarak çalıştırıldığında bile, gerektiğinde birden fazla hesap oluşturulabilir." + group: "Grup sunucusu" + group_description: "Diğer güvenilir kullanıcıları birden fazla kullanıcıyla birlikte kullanmaya davet edin." + open: "Genel sunucu" + open_description: "Herkesin kayıt olmasına izin verin." + openServerAdvice: "Çok sayıda bilinmeyen kullanıcıyı kabul etmek risklidir. Herhangi bir sorunu çözmek için güvenilir bir moderasyon sistemi kullanmanızı öneririz." + openServerAntiSpamAdvice: "Sunucunuzun spam için bir basamak haline gelmesini önlemek için, reCAPTCHA gibi anti-bot işlevlerini etkinleştirerek güvenliğe de özen göstermelisin." + howManyUsersDoYouExpect: "Kaç kullanıcı bekliyorsunuz?" + _scale: + small: "100'den az (küçük ölçekli)" + medium: "100'den fazla ve 1000'den az kullanıcı (orta büyüklükte)" + large: "1000'den fazla (Büyük ölçekli)" + largeScaleServerAdvice: "Büyük sunucular, yük dengeleme ve veritabanı çoğaltma gibi gelişmiş altyapı bilgisi gerektirebilir." + doYouConnectToFediverse: "Fediverse'e bağlanmak ister misin?" + doYouConnectToFediverse_description1: "Dağıtılmış sunucular ağına (Fediverse) bağlandığında, içerik diğer sunucularla paylaşılabilir." + doYouConnectToFediverse_description2: "Fediverse ile bağlantı kurmak “federasyon” olarak da adlandırılır." + youCanConfigureMoreFederationSettingsLater: "Birleştirilmiş sunucuları belirtme gibi gelişmiş ayarlar daha sonra yapılandırılabilir." + remoteContentsCleaning: "Alınan içeriklerin otomatik olarak temizlenmesi" + remoteContentsCleaning_description: "Federasyon, sürekli içerik akışına neden olabilir. Otomatik temizleme özelliğini etkinleştirmek, depolama alanından tasarruf etmek için sunucudan eski ve referanslanmamış içeriği kaldıracak." + adminInfo: "Yönetici bilgileri" + adminInfo_description: "Sorguları almak için kullanılan yönetici bilgilerini ayarlar." + adminInfo_mustBeFilled: "Genel sunucu veya federasyon açıksa girilmelidir." + followingSettingsAreRecommended: "Aşağıdaki ayarlar önerilir" + applyTheseSettings: "Bu ayarları uygulayın" + skipSettings: "Ayarları atla" + settingsCompleted: "Kurulum tamamlandı!" + settingsCompleted_description: "Zaman ayırdığınız için teşekkür ederiz. Artık her şey hazır olduğuna göre, sunucuyu hemen kullanmaya başlayabilirsin." + settingsCompleted_description2: "Sunucu ayarları “Kontrol Paneli”nden değiştirilebilir." + donationRequest: "Bağış Talebi" + _donationRequest: + text1: "CherryPick, gönüllüler tarafından geliştirilen ücretsiz bir yazılımdır." + text2: "Bu yazılımı gelecekte de geliştirmeye devam edebilmemiz için desteğini rica ederiz." + text3: "Destekçilere özel avantajlar da var!" +_uploader: + editImage: "Resmi Düzenle" + compressedToX: "{x} boyutuna sıkıştırıldı" + savedXPercent: "{x}% tasarruf" + abortConfirm: "Bazı dosyalar yüklenmedi, iptal etmek ister misin?" + doneConfirm: "Bazı dosyalar yüklenmedi, yine de devam etmek istiyor musun?" + maxFileSizeIsX: "Yükleyebileceğin maksimum dosya boyutu {x}" + allowedTypes: "Yüklenebilir dosya türleri" + tip: "Dosya henüz yüklenmediğinden, bu iletişim kutusu yüklemeden önce dosyayı onaylamanıza, yeniden adlandırmana, sıkıştırmana ve kırpmana olanak tanır. Hazır olduğunda, “Yükle” düğmesine basarak yüklemeyi başlatabilirsin." +_clientPerformanceIssueTip: + title: "Performans ipuçları" + makeSureDisabledAdBlocker: "Reklam engelleyicini devre dışı bırak" + makeSureDisabledAdBlocker_description: "Reklam engelleyiciler performansı etkileyebilir, lütfen sisteminde veya tarayıcının özelliklerinde/uzantılarında reklam engelleyicilerin etkinleştirilmediğinden emin ol." + makeSureDisabledCustomCss: "Özel CSS'yi devre dışı bırak" + makeSureDisabledCustomCss_description: "Stil geçersiz kılma, performansı etkileyebilir. Stil geçersiz kılan özel CSS veya uzantıların etkinleştirilmediğinden emin ol." + makeSureDisabledAddons: "Uzantıları devre dışı bırak" + makeSureDisabledAddons_description: "Bazı uzantılar istemci davranışını engelleyebilir ve performansı etkileyebilir. Lütfen tarayıcı uzantılarınızı devre dışı bırakın ve durumun düzelip düzelmediğini kontrol edin." +_clip: + tip: "Klip, notları gruplandırmanıza olanak tanıyan bir özelliktir." +_userLists: + tip: "Listeler, oluşturulurken belirttiğin herhangi bir kullanıcıyı içerebilir. Oluşturulan liste, yalnızca belirtilen kullanıcıları gösteren bir pano olarak görüntülenebilir." +watermark: "Filigran" +defaultPreset: "Varsayılan Ön Ayar" +_watermarkEditor: + tip: "Kredi bilgileri gibi bir filigran görüntüye eklenebilir." + quitWithoutSaveConfirm: "Kaydedilmemiş değişiklikleri silmek ister misin?" + driveFileTypeWarn: "Bu dosya desteklenmiyor" + driveFileTypeWarnDescription: "Bir görüntü dosyası seçin" + title: "Filigranı Düzenle" + cover: "Her şeyi örtün" + repeat: "her yere yayılmış" + opacity: "Opaklık" + scale: "Boyut" + text: "Metin" + position: "Pozisyon" + type: "Tür" + image: "Görseller" + advanced: "Gelişmiş" + angle: "Açı" + stripe: "Çizgiler" + stripeWidth: "Çizgi genişliği" + stripeFrequency: "Satır sayısı" + polkadot: "Nokta deseni" + checker: "Kontrolcü" + polkadotMainDotOpacity: "Ana noktanın opaklığı" + polkadotMainDotRadius: "Ana noktanın boyutu" + polkadotSubDotOpacity: "İkincil noktanın opaklığı" + polkadotSubDotRadius: "İkincil noktanın boyutu" + polkadotSubDotDivisions: "Alt nokta sayısı." +_imageEffector: + title: "Effektler" + addEffect: "Efektler Ekle" + discardChangesConfirm: "Cidden çıkmak istiyor musun? Kaydedilmemiş değişikliklerin var." + nothingToConfigure: "Yapılandırılabilir seçenekler mevcut değildir." + _fxs: + chromaticAberration: "Renk Sapması" + glitch: "Bozulma" + mirror: "Ayna" + invert: "Renkleri Ters Çevir" + grayscale: "Gri tonlama" + colorAdjust: "Renk Düzeltme" + colorClamp: "Renk Sıkıştırma" + colorClampAdvanced: "Renk Sıkıştırma (Gelişmiş)" + distort: "Bozulma" + threshold: "Binarize" + zoomLines: "Doymuş hatlar" + stripe: "Çizgiler" + polkadot: "Nokta deseni" + checker: "Denetleyici" + blockNoise: "Gürültüyü Engelle" + tearing: "Yırtılma" + _fxProps: + angle: "Açı" + scale: "Boyut" + size: "Boyut" + offset: "Pozisyon" + color: "Renk" + opacity: "Opaklık" + normalize: "Normalize" + amount: "Miktar" + lightness: "Hafiflet" + contrast: "Kontrast" + hue: "Hue" + brightness: "Parlaklık" + saturation: "Doygunluk" + max: "Maksimum" + min: "Minimum" + direction: "Yön" + phase: "Aşama" + frequency: "Sıklık" + strength: "Güç" + glitchChannelShift: "Kanal değişimi" + seed: "Tohum değeri" + redComponent: "Kırmızı bileşen" + greenComponent: "Yeşil bileşen" + blueComponent: "Mavi bileşen" + threshold: "Eşik" + centerX: "Merkez X" + centerY: "Merkez Y" + zoomLinesSmoothing: "Düzeltme" + zoomLinesSmoothingDescription: "Düzeltme ve yakınlaştırma çizgi genişliği birlikte kullanılamaz." + zoomLinesThreshold: "Zoom çizgi genişliği" + zoomLinesMaskSize: "Merkez çapı" + zoomLinesBlack: "Siyah yap" +drafts: "Taslaklar" +_drafts: + select: "Taslak Seç" + cannotCreateDraftAnymore: "Oluşturulabilecek taslak sayısı aşılmıştır." + cannotCreateDraft: "Bu içerikle taslak oluşturamazsınız." + delete: "Taslak Sil" + deleteAreYouSure: "Taslağı silmek ister misin?" + noDrafts: "Taslak yok" + replyTo: "{user} notunu yanıtla" + quoteOf: "{user} notuna alıntı" + postTo: "{channel}'a gönder" + saveToDraft: "Taslak olarak kaydet" + restoreFromDraft: "Taslaktan geri yükle" + restore: "Geri yükle" + listDrafts: "Taslaklar Listesi" +_qr: + showTabTitle: "Ekran" + raw: "Metin" diff --git a/locales/uk-UA.yml b/locales/uk-UA.yml index f0955c5239..99228b87ed 100644 --- a/locales/uk-UA.yml +++ b/locales/uk-UA.yml @@ -8,6 +8,9 @@ search: "Пошук" notifications: "Сповіщення" username: "Ім'я користувача" password: "Пароль" +initialPasswordForSetup: "Початковий пароль для налаштування" +initialPasswordIsIncorrect: "Початковий пароль для налаштування неправильний" +initialPasswordForSetupDescription: "Використайте пароль, вказаний у конфігураційному файлі, якщо ви встановлювали CherryPick власноруч.\nЯкщо використовуєте сервіси хостингу CherryPick, використайте наданий пароль.\nЯкщо ви не маєте паролю, лишіть порожнім щоб продовжити. " forgotPassword: "Я забув пароль" fetchingAsApObject: "Отримуємо з федіверсу..." ok: "OK" @@ -45,6 +48,7 @@ pin: "Закріпити" unpin: "Відкріпити" copyContent: "Скопіювати контент" copyLink: "Скопіювати посилання" +copyRemoteLink: "Копіювати віддалене посилання" delete: "Видалити" deleteAndEdit: "Видалити й редагувати" deleteAndEditConfirm: "Ви впевнені, що хочете видалити цю нотатку та відредагувати її? Ви втратите всі реакції, поширення та відповіді на неї." @@ -57,6 +61,7 @@ copyUserId: "Копіювати ID користувача" copyNoteId: "блокнот ID користувача" copyFileId: "Скопіювати ідентифікатор файлу." searchUser: "Пошук користувачів" +searchThisUsersNotes: "Пошук нотаток користувача" reply: "Відповісти" loadMore: "Показати більше" showMore: "Показати більше" @@ -105,9 +110,11 @@ enterEmoji: "Введіть емодзі" renote: "Поширити" unrenote: "Відміна поширення" renoted: "Поширити запис." +renotedToX: "Поширено до {name}" cantRenote: "Неможливо поширити." cantReRenote: "Поширення не можливо поширити." quote: "Цитата" +inChannelRenote: "Поширено у канал" pinnedNote: "Закріплений запис" pinned: "Закріпити" you: "Ви" @@ -116,6 +123,7 @@ sensitive: "NSFW" add: "Додати" reaction: "Реакції" reactions: "Реакції" +emojiPicker: "Вибір реакції" reactionSettingDescription2: "Перемістити щоб змінити порядок, Клацнути мишою щоб видалити, Натиснути \"+\" щоб додати." rememberNoteVisibility: "Пам’ятати параметри видимісті" attachCancel: "Видалити вкладення" @@ -208,7 +216,6 @@ noUsers: "Немає користувачів" editProfile: "Редагувати обліковий запис" noteDeleteConfirm: "Ви дійсно хочете видалити цей запис?" pinLimitExceeded: "Більше записів не можна закріпити" -intro: "Встановлення CherryPick завершено! Будь ласка, створіть обліковий запис адміністратора." done: "Готово" processing: "Обробка" preview: "Попередній перегляд" @@ -290,7 +297,9 @@ folderName: "Ім'я теки" createFolder: "Створити теку" renameFolder: "Перейменувати теку" deleteFolder: "Видалити теку" +folder: "Тека" addFile: "Додати файл" +showFile: "Показати файл" emptyDrive: "Диск порожній" emptyFolder: "Тека порожня" unableToDelete: "Видалення неможливе" @@ -303,6 +312,7 @@ copyUrl: "Копіювати URL" rename: "Перейменувати" avatar: "Аватар" banner: "Банер" +displayOfSensitiveMedia: "Показ чутливого медіа" whenServerDisconnected: "Коли зв’язок із сервером втрачено" disconnectedFromServer: "Зв’язок із сервером було перервано" reload: "Оновити" @@ -349,8 +359,11 @@ hcaptcha: "hCaptcha" enableHcaptcha: "Увімкнути hCaptcha" hcaptchaSiteKey: "Ключ сайту" hcaptchaSecretKey: "Секретний ключ" +mcaptcha: "MCaptcha" +enableMcaptcha: "Увімкнути MCaptcha" mcaptchaSiteKey: "Ключ сайту" mcaptchaSecretKey: "Секретний ключ" +mcaptchaInstanceUrl: "Посилання на сервер MCaptcha" recaptcha: "reCAPTCHA" enableRecaptcha: "Увімкнути reCAPTCHA" recaptchaSiteKey: "Ключ сайту" @@ -919,6 +932,9 @@ flip: "Перевернути" lastNDays: "Останні {n} днів" postForm: "Створення нотатки" information: "Інформація" +inMinutes: "х" +inDays: "д" +widgets: "Віджети" _chat: invitations: "Запросити" noHistory: "Історія порожня" @@ -1378,7 +1394,6 @@ _theme: buttonBg: "Фон кнопки" buttonHoverBg: "Фон кнопки (при наведенні)" inputBorder: "Край поля вводу" - driveFolderBg: "Фон папки на диску" badge: "Значок" messageBg: "Фон переписки" fgHighlighted: "Виділений текст" @@ -1705,3 +1720,20 @@ _remoteLookupErrors: _search: searchScopeAll: "Всі" searchScopeLocal: "Локальна" +_watermarkEditor: + opacity: "Непрозорість" + scale: "Розмір" + text: "Текст" + type: "Тип" + image: "Зображення" + advanced: "Розширені" +_imageEffector: + _fxProps: + scale: "Розмір" + size: "Розмір" + color: "Колір" + opacity: "Непрозорість" + lightness: "Яскравість" +_qr: + showTabTitle: "Відображення" + raw: "Текст" diff --git a/locales/uz-UZ.yml b/locales/uz-UZ.yml index 68abca0960..2040e73143 100644 --- a/locales/uz-UZ.yml +++ b/locales/uz-UZ.yml @@ -219,7 +219,6 @@ noUsers: "Foydalanuvchilar yo‘q" editProfile: "Profilni o'zgartirish" noteDeleteConfirm: "Haqiqatan ham bu qaydni oʻchirib tashlamoqchimisiz?" pinLimitExceeded: "Siz boshqa qaydlarni mahkamlay olmaysiz" -intro: "CherryPickni o'rnatish tugallandi! Iltimos, administrator foydalanuvchi yarating." done: "Bajarildi" processing: "Amaliyotda" preview: "Ko'rish" @@ -904,14 +903,13 @@ _theme: header: "Sarlavha" navBg: "Yon panel foni" navFg: "Yon panel matni" - mention: "Murojat" + mention: "Eslatib o'tish" renote: "Qayta qayd etish" divider: "Ajratrmoq" fgHighlighted: "Belgilangan matn" _sfx: note: "Qaydlar" notification: "Xabarnomalar" - chat: "Suhbat" _ago: minutesAgo: "{n} daqiqa oldin" hoursAgo: "{n} soat oldin" @@ -1047,7 +1045,7 @@ _notification: _types: all: "Barchasi" follow: "Obuna bo‘lish" - mention: "Murojat" + mention: "Eslatib o'tish" renote: "Qayta qayd etish" quote: "Iqtibos keltirish" reaction: "Reaktsiyalar" @@ -1099,3 +1097,15 @@ _remoteLookupErrors: _search: searchScopeAll: "Barcha" searchScopeLocal: "Mahalliy" +_watermarkEditor: + text: "Matn" + type: "turi" + image: "Rasmlar" + advanced: "Murakkab" +_imageEffector: + _fxProps: + color: "Rang" + lightness: "Yoritish" +_qr: + showTabTitle: "Displey" + raw: "Matn" diff --git a/locales/vi-VN.yml b/locales/vi-VN.yml index f49c685cb0..b3540b2369 100644 --- a/locales/vi-VN.yml +++ b/locales/vi-VN.yml @@ -102,7 +102,7 @@ pageLoadErrorDescription: "Có thể là do bộ nhớ đệm của trình duy serverIsDead: "Máy chủ không phản hồi. Vui lòng thử lại sau giây lát." youShouldUpgradeClient: "Để xem trang này, hãy làm tươi để cập nhật ứng dụng." enterListName: "Đặt tên cho danh sách" -privacy: "Bảo mật" +privacy: "Riêng tư" makeFollowManuallyApprove: "Yêu cầu theo dõi cần được duyệt" defaultNoteVisibility: "Kiểu tút mặc định" follow: "Theo dõi" @@ -220,6 +220,7 @@ silenceThisInstance: "Máy chủ im lặng" mediaSilenceThisInstance: "Tắt nội dung đa phương tiện từ máy chủ này" operations: "Vận hành" software: "Phần mềm" +softwareName: "Tên phần mềm" version: "Phiên bản" metadata: "Metadata" withNFiles: "{n} tập tin" @@ -250,7 +251,6 @@ noUsers: "Chưa có ai" editProfile: "Sửa hồ sơ" noteDeleteConfirm: "Bạn có chắc muốn xóa tút này?" pinLimitExceeded: "Bạn không thể ghim bài viết nữa" -intro: "Đã cài đặt CherryPick! Xin hãy tạo tài khoản admin." done: "Xong" processing: "Đang xử lý" preview: "Xem trước" @@ -298,6 +298,7 @@ uploadFromUrl: "Tải lên bằng một URL" uploadFromUrlDescription: "URL của tập tin bạn muốn tải lên" uploadFromUrlRequested: "Đã yêu cầu tải lên" uploadFromUrlMayTakeTime: "Sẽ mất một khoảng thời gian để tải lên xong." +uploadNFiles: "Tải lên {n} tập tin" explore: "Khám phá" messageRead: "Đã đọc" noMoreHistory: "Không còn gì để đọc" @@ -587,6 +588,7 @@ withRepliesByDefaultForNewlyFollowed: "Mặc định hiển thị trả lời t newNoteRecived: "Đã nhận tút mới" sounds: "Âm thanh" sound: "Âm thanh" +notificationSoundSettings: "Cài đặt âm thanh thông báo" listen: "Nghe" none: "Không" showInPage: "Hiện trong trang" @@ -1188,9 +1190,12 @@ mutualFollow: "Theo dõi lẫn nhau" followingOrFollower: "Đang theo dõi hoặc người theo dõi" externalServices: "Các dịch vụ bên ngoài" sourceCode: "Mã nguồn" +sourceCodeIsNotYetProvided: "Mã nguồn hiện chưa có sẵn, vui lòng liên hệ với quản trị viên để khắc phục sự cố này." repositoryUrlDescription: "Nếu bạn có kho lưu trữ mã nguồn có thể truy cập công khai, hãy nhập URL. Nếu bạn đang sử dụng CherryPick theo mặc định (không thực hiện bất kỳ thay đổi nào đối với mã nguồn), hãy nhập https://github.com/kokonect-link/cherrypick." feedback: "Phản hồi" feedbackUrl: "URL phản hồi" +impressum: "Thông tin nhà điều hành" +impressumUrl: "URL thông tin nhà điều hành" privacyPolicy: "Chính sách bảo mật" privacyPolicyUrl: "URL Chính sách bảo mật" tosAndPrivacyPolicy: "Điều khoản sử dụng và Chính sách bảo mật" @@ -1214,17 +1219,31 @@ passkeyVerificationFailed: "Xác minh mật khẩu không thành công." messageToFollower: "Tin nhắn cho người theo dõi" yourNameContainsProhibitedWords: "Tên bạn đang cố gắng đổi có chứa chuỗi ký tự bị cấm." yourNameContainsProhibitedWordsDescription: "Tên có chứa chuỗi ký tự bị cấm. Nếu bạn muốn sử dụng tên này, hãy liên hệ với quản trị viên máy chủ của bạn." +pleaseSelectAccount: "Chọn tài khoản của bạn" federationDisabled: "Liên kết bị vô hiệu hóa trên máy chủ này. Bạn không thể tương tác với người dùng trên các máy chủ khác." reactAreYouSure: "Bạn có muốn phản hồi với \" {emoji} \" không?" +preferences: "Thiết lập môi trường" +accessibility: "Khả năng tiếp cận" +preferencesProfile: "Hồ sơ sở thích" +preferenceSyncConflictTitle: "Cài đặt tồn tại trên máy chủ" +preferenceSyncConflictText: "Các thiết lập đồng bộ hóa được bật sẽ lưu các giá trị của chúng vào máy chủ. Tuy nhiên, có những giá trị hiện có trên máy chủ. Bạn muốn ghi đè lên bộ giá trị nào?" paste: "dán" postForm: "Mẫu đăng" information: "Giới thiệu" +chat: "Trò chuyện" +migrateOldSettings: "Di chuyển cài đặt cũ" +migrateOldSettings_description: "Thông thường, quá trình này diễn ra tự động, nhưng nếu vì lý do nào đó mà quá trình di chuyển không thành công, bạn có thể kích hoạt thủ công quy trình di chuyển, quá trình này sẽ ghi đè lên thông tin cấu hình hiện tại của bạn." +inMinutes: "phút" +inDays: "ngày" +widgets: "Tiện ích" _chat: invitations: "Mời" noHistory: "Không có dữ liệu" members: "Thành viên" home: "Trang chính" send: "Gửi" +_settings: + preferencesBanner: "Bạn có thể cấu hình hành vi chung của máy khách theo sở thích của mình." _accountSettings: requireSigninToViewContents: "Yêu cầu đăng nhập để xem nội dung" requireSigninToViewContentsDescription1: "Yêu cầu đăng nhập để xem tất cả ghi chú và nội dung khác mà bạn tạo. Điều này được kỳ vọng sẽ có hiệu quả trong việc ngăn chặn thông tin bị thu thập bởi các trình thu thập thông tin." @@ -1750,7 +1769,6 @@ _theme: buttonBg: "Nền nút" buttonHoverBg: "Nền nút (Chạm)" inputBorder: "Đường viền khung soạn thảo" - driveFolderBg: "Nền thư mục Ổ đĩa" badge: "Huy hiệu" messageBg: "Nền chat" fgHighlighted: "Chữ nổi bật" @@ -2148,3 +2166,24 @@ _search: searchScopeAll: "Tất cả" searchScopeLocal: "Máy chủ này" searchScopeUser: "Người dùng chỉ định" +_watermarkEditor: + opacity: "Độ trong suốt" + scale: "Kích thước" + text: "Văn bản" + position: "Vị trí" + type: "Loại" + image: "Hình ảnh" + advanced: "Nâng cao" + angle: "Góc" +_imageEffector: + _fxProps: + angle: "Góc" + scale: "Kích thước" + size: "Kích thước" + offset: "Vị trí" + color: "Màu sắc" + opacity: "Độ trong suốt" + lightness: "Độ sáng" +_qr: + showTabTitle: "Hiển thị" + raw: "Văn bản" diff --git a/locales/zh-CN.yml b/locales/zh-CN.yml index 2236d73925..226b8e696b 100644 --- a/locales/zh-CN.yml +++ b/locales/zh-CN.yml @@ -56,7 +56,7 @@ deleteAndEdit: "删除并编辑" deleteAndEditConfirm: "要删除此帖并再次编辑吗?对此帖的所有回应、转发和回复也将被删除。" addToList: "添加至列表" addToAntenna: "添加到天线" -sendMessage: "发送" +sendMessage: "发送消息" copyRSS: "复制RSS" copyUsername: "复制用户名" copyUserId: "复制用户 ID" @@ -87,7 +87,7 @@ exportRequested: "导出请求已提交,这可能需要花一些时间,导 importRequested: "导入请求已提交,这可能需要花一点时间。" lists: "列表" noLists: "列表为空" -note: "帖子" +note: "发帖" notes: "帖子" following: "关注中" followers: "关注者" @@ -106,8 +106,8 @@ privacy: "隐私" makeFollowManuallyApprove: "关注请求需要批准" defaultNoteVisibility: "默认可见性" follow: "关注" -followRequest: "关注申请" -followRequests: "关注申请" +followRequest: "申请关注" +followRequests: "关注请求" unfollow: "取消关注" followRequestPending: "关注请求待批准" enterEmoji: "输入表情符号" @@ -144,15 +144,15 @@ markAsSensitive: "标记为敏感内容" unmarkAsSensitive: "取消标记为敏感内容" enterFileName: "输入文件名" mute: "屏蔽" -unmute: "取消隐藏" -renoteMute: "隐藏转帖" -renoteUnmute: "解除隐藏转帖" -block: "屏蔽" -unblock: "取消屏蔽" +unmute: "取消屏蔽" +renoteMute: "屏蔽转帖" +renoteUnmute: "取消屏蔽转帖" +block: "拉黑" +unblock: "取消拉黑" suspend: "冻结" unsuspend: "解除冻结" -blockConfirm: "确定要屏蔽吗?" -unblockConfirm: "确定要取消屏蔽吗?" +blockConfirm: "确定要拉黑吗?" +unblockConfirm: "确定要取消拉黑吗?" suspendConfirm: "要冻结吗?" unsuspendConfirm: "要解除冻结吗?" selectList: "选择列表" @@ -239,28 +239,28 @@ clearCachedFilesConfirm: "确定要清除所有缓存的远程文件吗?" blockedInstances: "被屏蔽的服务器" blockedInstancesDescription: "设定要屏蔽的服务器,以换行分隔。被屏蔽的服务器将无法与本服务器进行交换通讯。子域名也同样会被屏蔽。" silencedInstances: "被静音的服务器" -silencedInstancesDescription: "设置要静音的服务器,以换行分隔。被静音的服务器内所有的账户将默认处于「静音」状态,仅能发送关注请求,并且在未关注状态下无法提及本地账户。被阻止的实例不受影响。" +silencedInstancesDescription: "设置要静音的服务器,以换行分隔。被静音的服务器内所有的账户都被视为「静音」状态,且关注操作均需要被批准。被阻止的实例不受影响。" mediaSilencedInstances: "已隐藏媒体文件的服务器" -mediaSilencedInstancesDescription: "设置要隐藏媒体文件的服务器,以换行分隔。被设置为隐藏媒体文件服务器内所有账号的文件均按照「敏感内容」处理,且将无法使用自定义表情符号。被阻止的实例不受影响。" +mediaSilencedInstancesDescription: "设置要隐藏媒体文件的服务器,以换行分隔。被设置的服务器内所有账号的文件均按照「敏感内容」处理,且将无法使用自定义表情符号。被阻止的实例不受影响。" federationAllowedHosts: "允许联合的服务器" federationAllowedHostsDescription: "设定允许联合的服务器,以换行分隔。" -muteAndBlock: "隐藏和屏蔽" -mutedUsers: "已隐藏用户" -blockedUsers: "已屏蔽的用户" +muteAndBlock: "屏蔽/拉黑" +mutedUsers: "已屏蔽用户" +blockedUsers: "已拉黑的用户" noUsers: "无用户" editProfile: "编辑资料" noteDeleteConfirm: "确定要删除该帖子吗?" pinLimitExceeded: "无法置顶更多了" -intro: "CherryPick 的部署结束啦!创建管理员账号吧!" done: "完成" processing: "正在处理" +preprocessing: "准备中" preview: "预览" default: "默认" defaultValueIs: "默认值: {value}" noCustomEmojis: "没有自定义表情符号" noJobs: "没有任务" federating: "联合中" -blocked: "已屏蔽" +blocked: "已拉黑" suspended: "停止投递" all: "全部" subscribing: "已订阅" @@ -299,11 +299,12 @@ uploadFromUrl: "从网址上传" uploadFromUrlDescription: "输入文件的 URL" uploadFromUrlRequested: "请求上传" uploadFromUrlMayTakeTime: "上传可能需要一些时间完成。" +uploadNFiles: "上传 {n} 个文件" explore: "发现" messageRead: "已读" noMoreHistory: "没有更多的历史记录" startChat: "开始聊天" -nUsersRead: "{n} 人已读" +nUsersRead: "{n}人已读" agreeTo: "勾选则表示已阅读并同意 {0}" agree: "同意" agreeBelow: "同意以下内容" @@ -327,11 +328,13 @@ dark: "深色" lightThemes: "浅色主题" darkThemes: "深色主题" syncDeviceDarkMode: "将深色模式与设备设置同步" +switchDarkModeManuallyWhenSyncEnabledConfirm: "「{x}」已开启。要关闭同步并手动切换模式吗?" drive: "网盘" fileName: "文件名称" selectFile: "选择文件" selectFiles: "选择文件" selectFolder: "选择文件夹" +unselectFolder: "取消全选文件夹" selectFolders: "选择多个文件夹" fileNotSelected: "未选择文件" renameFile: "重命名文件" @@ -344,6 +347,7 @@ addFile: "添加文件" showFile: "显示文件" emptyDrive: "网盘中无文件" emptyFolder: "此文件夹中无文件" +dropHereToUpload: "将文件拖动到这里来上传" unableToDelete: "无法删除" inputNewFileName: "请输入新文件名" inputNewDescription: "请输入新标题" @@ -394,7 +398,7 @@ basicInfo: "基本信息" pinnedUsers: "置顶用户" pinnedUsersDescription: "输入您想要固定到“发现”页面的用户,一行一个。" pinnedPages: "固定页面" -pinnedPagesDescription: "输入您要固定到服务器首页的页面路径,一行一个。" +pinnedPagesDescription: "输入您要固定到服务器首页的页面路径,以换行符分隔。" pinnedClipId: "置顶的便签 ID" pinnedNotes: "已置顶的帖子" hcaptcha: "hCaptcha" @@ -427,7 +431,7 @@ notifyAntenna: "开启通知" withFileAntenna: "仅带有附件的帖子" excludeNotesInSensitiveChannel: "排除敏感频道内的帖子" enableServiceworker: "启用 ServiceWorker" -antennaUsersDescription: "指定用户名,一行一个" +antennaUsersDescription: "指定用户名,用换行符进行分隔" caseSensitive: "区分大小写" withReplies: "包括回复" connectedTo: "您的账号已连到接以下第三方账号" @@ -459,7 +463,7 @@ moderationNote: "管理笔记" moderationNoteDescription: "可以用来记录仅在管理员之间共享的笔记。" addModerationNote: "添加管理笔记" moderationLogs: "管理日志" -nUsersMentioned: "{n} 被提到" +nUsersMentioned: "{n}人投稿" securityKeyAndPasskey: "安全密钥或 Passkey" securityKey: "安全密钥" lastUsed: "最后使用:" @@ -476,7 +480,7 @@ notFoundDescription: "没有与指定 URL 对应的页面。" uploadFolder: "默认上传文件夹" markAsReadAllNotifications: "将所有通知标为已读" markAsReadAllUnreadNotes: "将所有帖子标记为已读" -markAsReadAllTalkMessages: "将所有聊天标记为已读" +markAsReadAllTalkMessages: "将所有私信标记为已读" help: "帮助" inputMessageHere: "在此键入信息" close: "关闭" @@ -546,7 +550,7 @@ regenerate: "重新生成" fontSize: "字体大小" mediaListWithOneImageAppearance: "仅一张图片的媒体列表高度" limitTo: "上限为 {x}" -noFollowRequests: "没有关注申请" +noFollowRequests: "没有关注请求" openImageInNewTab: "在新标签页中打开图片" dashboard: "管理面板" local: "本地" @@ -586,8 +590,10 @@ showFixedPostForm: "在时间线顶部显示发帖框" showFixedPostFormInChannel: "在时间线顶部显示发帖对话框(频道)" withRepliesByDefaultForNewlyFollowed: "在时间线中默认包含新关注用户的回复" newNoteRecived: "有新的帖子" +newNote: "新帖子" sounds: "提示音" sound: "提示音" +notificationSoundSettings: "设置通知声音" listen: "试听" none: "无" showInPage: "在页面中显示" @@ -604,7 +610,7 @@ recentUsed: "最近使用" install: "安装" uninstall: "卸载" installedApps: "已授权的应用" -nothing: "没有" +nothing: "无" installedDate: "授权日期" lastUsedDate: "最近使用" state: "状态" @@ -694,10 +700,10 @@ emptyToDisableSmtpAuth: "用户名和密码留空可以禁用 SMTP 验证" smtpSecure: "在 SMTP 连接中使用隐式 SSL / TLS" smtpSecureInfo: "使用 STARTTLS 时关闭。" testEmail: "邮件发送测试" -wordMute: "隐藏关键词" +wordMute: "屏蔽关键词" wordMuteDescription: "折叠包含指定关键词的帖子。被折叠的帖子可单击展开。" -hardWordMute: "隐藏硬关键词" -showMutedWord: "显示已隐藏的关键词" +hardWordMute: "强屏蔽关键词" +showMutedWord: "显示屏蔽关键词" hardWordMuteDescription: "隐藏包含指定关键词的帖子。与隐藏关键词不同,帖子将完全不会显示。" regexpError: "正则表达式错误" regexpErrorDescription: "{tab} 隐藏文字的第 {line} 行的正则表达式有错误:" @@ -779,6 +785,7 @@ lockedAccountInfo: "即使启用该功能,只要帖子可见范围不是「仅 alwaysMarkSensitive: "默认将媒体文件标记为敏感内容" loadRawImages: "添加附件图像的缩略图时使用原始图像质量" disableShowingAnimatedImages: "不播放动画" +disableShowingAnimatedImages_caption: "如果即使关闭了此设置但动画仍无法播放,则可能是浏览器或操作系统的辅助功能设置,又或者是省电设置等产生了干扰。" highlightSensitiveMedia: "高亮显示敏感媒体" verificationEmailSent: "已发送确认电子邮件。请访问电子邮件中的链接以完成设置。" notSet: "未设置" @@ -786,7 +793,7 @@ emailVerified: "电子邮件地址已验证" noteFavoritesCount: "收藏的帖子数" pageLikesCount: "页面点赞次数" pageLikedCount: "页面被点赞次数" -contact: "联系人" +contact: "联系方式" useSystemFont: "使用系统默认字体" clips: "便签" experimentalFeatures: "实验性功能" @@ -803,11 +810,12 @@ wide: "宽" narrow: "窄" reloadToApplySetting: "页面刷新后设置才会生效。是否现在刷新页面?" needReloadToApply: "重新载入后应用才会生效。" +needToRestartServerToApply: "需要重启服务才能应用更改。" showTitlebar: "显示标题栏" clearCache: "清除缓存" onlineUsersCount: "{n} 人在线" nUsers: "{n} 用户" -nNotes: "{n} 帖子" +nNotes: "{n}帖子" sendErrorReports: "发送错误报告" sendErrorReportsDescription: "启用后,如果出现问题,可以与 CherryPick 共享详细的错误信息,从而帮助提高软件的质量。错误信息包括操作系统版本、浏览器类型、行为历史记录等。" myTheme: "我的主题" @@ -831,7 +839,7 @@ youAreRunningUpToDateClient: "您所使用的客户端已经是最新的。" newVersionOfClientAvailable: "新版本的客户端可用。" usageAmount: "使用量" capacity: "容量" -inUse: "已使用" +inUse: "使用中" editCode: "编辑代码" apply: "应用" receiveAnnouncementFromInstance: "从服务器接收通知" @@ -876,12 +884,12 @@ noMaintainerInformationWarning: "尚未设置管理员信息。" noInquiryUrlWarning: "尚未设置联络地址。" noBotProtectionWarning: "尚未设置 Bot 防御。" configure: "设置" -postToGallery: "发送到图库" +postToGallery: "创建新图集" postToHashtag: "投稿到这个标签" -gallery: "图库" +gallery: "图集" recentPosts: "最新发布" popularPosts: "热门投稿" -shareWithNote: "在帖子中分享" +shareWithNote: "分享到帖文" ads: "广告" expiration: "截止时间" startingperiod: "开始时间" @@ -892,7 +900,7 @@ middle: "中" low: "低" emailNotConfiguredWarning: "尚未设置电子邮件地址。" ratio: "比率" -previewNoteText: "预览文本" +previewNoteText: "预览正文" customCss: "自定义 CSS" customCssWarn: "这些设置必须有相关的基础知识,不当的配置可能导致客户端无法正常使用。" global: "全局" @@ -931,8 +939,8 @@ manageAccounts: "管理账户" makeReactionsPublic: "将回应设置为公开" makeReactionsPublicDescription: "将您发表过的回应设置成公开可见。" classic: "经典" -muteThread: "隐藏帖子列表" -unmuteThread: "取消隐藏帖子列表" +muteThread: "屏蔽帖文串" +unmuteThread: "取消屏蔽帖文串" followingVisibility: "关注的人的公开范围" followersVisibility: "关注者的公开范围" continueThread: "查看更多帖子" @@ -957,17 +965,17 @@ searchByGoogle: "Google" instanceDefaultLightTheme: "服务器默认浅色主题" instanceDefaultDarkTheme: "服务器默认深色主题" instanceDefaultThemeDescription: "以对象格式输入主题代码" -mutePeriod: "隐藏期限" +mutePeriod: "屏蔽期限" period: "截止时间" indefinitely: "永久" -tenMinutes: "10 分钟" +tenMinutes: "10分钟" oneHour: "1 小时" -oneDay: "1 天" +oneDay: "1天" oneWeek: "1 周" -oneMonth: "1 个月" -threeMonths: "3 个月" +oneMonth: "1个月" +threeMonths: "3个月" oneYear: "1 年" -threeDays: "3 天" +threeDays: "3天" reflectMayTakeTime: "可能需要一些时间才能体现出效果。" failedToFetchAccountInformation: "获取账户信息失败" rateLimitExceeded: "已超过速率限制" @@ -976,8 +984,8 @@ cropImageAsk: "是否要裁剪图像?" cropYes: "去裁剪" cropNo: "就这样吧!" file: "文件" -recentNHours: "最近 {n} 小时" -recentNDays: "最近 {n} 天" +recentNHours: "最近{n}小时" +recentNDays: "最近{n}天" noEmailServerWarning: "电子邮件服务器未设置。" thereIsUnresolvedAbuseReportWarning: "有未解决的报告" recommended: "推荐" @@ -1011,6 +1019,7 @@ failedToUpload: "上传失败" cannotUploadBecauseInappropriate: "因为可能含有不适宜的内容,无法上传。" cannotUploadBecauseNoFreeSpace: "因为已无可用空间,无法上传。" cannotUploadBecauseExceedsFileSizeLimit: "无法上传文件,超过文件大小限制。" +cannotUploadBecauseUnallowedFileType: "因文件类型被禁止而无法上传。" beta: "测试" enableAutoSensitive: "自动 NSFW 识别" enableAutoSensitiveDescription: "使用机器学习在可用时自动使用 NSFW 标记来标记媒体。即使您关闭此功能,根据服务器的不同,它仍然可能会自动设置。" @@ -1035,7 +1044,7 @@ tools: "工具" cannotLoad: "无法加载" numberOfProfileView: "个人资料展示次数" like: "点赞!" -unlike: "取消赞" +unlike: "取消喜欢" numberOfLikes: "点赞数" show: "显示" neverShow: "不再显示" @@ -1062,6 +1071,7 @@ permissionDeniedError: "操作被拒绝" permissionDeniedErrorDescription: "本账户没有执行该操作的权限。" preset: "预设值" selectFromPresets: "从预设值中选择" +custom: "自定义" achievements: "成就" gotInvalidResponseError: "服务器无应答" gotInvalidResponseErrorDescription: "您的网络连接可能出现了问题, 或是远程服务器暂时不可用. 请稍后重试。" @@ -1070,7 +1080,7 @@ thisPostMayBeAnnoyingHome: "发到首页" thisPostMayBeAnnoyingCancel: "取消" thisPostMayBeAnnoyingIgnore: "就这样发布" collapseRenotes: "省略显示已经看过的转发内容" -collapseRenotesDescription: "将回应过或转贴过的贴子折叠表示。" +collapseRenotesDescription: "折叠显示回应或转发过的帖文。" internalServerError: "内部服务器错误" internalServerErrorDescription: "内部服务器发生了预期外的错误" copyErrorInfo: "复制错误信息" @@ -1086,7 +1096,7 @@ postToTheChannel: "发布到频道" cannotBeChangedLater: "之后不能再更改。" reactionAcceptance: "接受表情回应" likeOnly: "仅点赞" -likeOnlyForRemote: "远程仅点赞" +likeOnlyForRemote: "全部(远程仅点赞)" nonSensitiveOnly: "仅限非敏感内容" nonSensitiveOnlyForLocalLikeOnlyForRemote: "仅限非敏感内容(远程仅点赞)" rolesAssignedToMe: "指派给自己的角色" @@ -1100,6 +1110,7 @@ prohibitedWordsDescription2: "AND 条件用空格分隔,正则表达式用斜 hiddenTags: "隐藏标签" hiddenTagsDescription: "设定的标签将不会在时间线上显示。可使用换行来设置多个标签。" notesSearchNotAvailable: "帖子检索不可用" +usersSearchNotAvailable: "用户检索不可用" license: "许可信息" unfavoriteConfirm: "确定要取消收藏吗?" myClips: "我的便签" @@ -1110,7 +1121,7 @@ retryAllQueuesConfirmText: "可能会使服务器负荷在一定时间内增加" enableChartsForRemoteUser: "生成远程用户的图表" enableChartsForFederatedInstances: "生成远程服务器的图表" enableStatsForFederatedInstances: "获取远程服务器的信息" -showClipButtonInNoteFooter: "在贴文下方显示便签按钮" +showClipButtonInNoteFooter: "在帖文下方显示便签按钮" reactionsDisplaySize: "回应显示大小" limitWidthOfReaction: "限制回应的最大宽度,并将其缩小显示" noteIdOrUrl: "帖子 ID 或 URL" @@ -1148,15 +1159,15 @@ archive: "归档" archived: "已归档" unarchive: "取消归档" channelArchiveConfirmTitle: "要将 {name} 归档吗?" -channelArchiveConfirmDescription: "归档后,在频道列表与搜索结果中不会显示,也无法发布新的贴文。" +channelArchiveConfirmDescription: "归档后,不会在频道列表与搜索结果中显示,也无法发布新的帖文。" thisChannelArchived: "该频道已被归档。" displayOfNote: "显示帖子" -initialAccountSetting: "初始设置" +initialAccountSetting: "初始设定" youFollowing: "正在关注" preventAiLearning: "拒绝接受生成式 AI 的学习" preventAiLearningDescription: "要求文章生成 AI 或图像生成 AI 不能够以发布的帖子和图像等内容作为学习对象。这是通过在 HTML 响应中包含 noai 标志来实现的,这不能完全阻止 AI 学习你的发布内容,并不是所有 AI 都会遵守这类请求。" options: "选项" -specifyUser: "用户指定" +specifyUser: "指定用户" lookupConfirm: "确定查询?" openTagPageConfirm: "确定打开话题标签页面?" specifyHost: "指定主机名" @@ -1174,6 +1185,7 @@ installed: "已安装" branding: "品牌" enableServerMachineStats: "公开服务器硬件统计信息" enableIdenticonGeneration: "启用生成用户 Identicon" +showRoleBadgesOfRemoteUsers: "显示远程用户的角色徽章" turnOffToImprovePerformance: "关闭该选项可以提高性能。" createInviteCode: "生成邀请码" createWithOptions: "使用选项来创建" @@ -1250,9 +1262,8 @@ showAvatarDecorations: "显示头像挂件" releaseToRefresh: "松开以刷新" refreshing: "刷新中" pullDownToRefresh: "下拉以刷新" -disableStreamingTimeline: "禁止实时更新时间线" useGroupedNotifications: "分组显示通知" -signupPendingError: "确认电子邮件时出现错误。链接可能已过期。" +emailVerificationFailedError: "确认电子邮件时出现错误。链接可能已过期。" cwNotationRequired: "在启用「隐藏内容」时必须输入注释" doReaction: "回应" code: "代码" @@ -1272,7 +1283,7 @@ replaying: "重播中" endReplay: "结束回放" copyReplayData: "复制回放数据" ranking: "排行榜" -lastNDays: "最近 {n} 天" +lastNDays: "最近{n}天" backToTitle: "返回标题" hemisphere: "居住地区" withSensitive: "显示包含敏感媒体的帖子" @@ -1322,11 +1333,13 @@ availableRoles: "可用角色" acknowledgeNotesAndEnable: "理解注意事项后再开启。" federationSpecified: "此服务器已开启联合白名单。只能与管理员指定的服务器通信。" federationDisabled: "此服务器已禁用联合。无法与其它服务器上的用户通信。" +draft: "草稿" +draftsAndScheduledNotes: "草稿和定时发送" confirmOnReact: "发送回应前需要确认" reactAreYouSure: "要用「{emoji}」进行回应吗?" markAsSensitiveConfirm: "要将此媒体标记为敏感吗?" unmarkAsSensitiveConfirm: "要将此媒体解除敏感标记吗?" -preferences: "设置" +preferences: "偏好设置" accessibility: "辅助功能" preferencesProfile: "设置的配置" copyPreferenceId: "复制设置 ID" @@ -1339,6 +1352,7 @@ restore: "恢复" syncBetweenDevices: "设备间同步" preferenceSyncConflictTitle: "服务器上已存在设定值" preferenceSyncConflictText: "服务器上已有此设置的设定值。要覆盖哪个设定值?" +preferenceSyncConflictChoiceMerge: "合并" preferenceSyncConflictChoiceServer: "服务器上的设定值" preferenceSyncConflictChoiceDevice: "设备上的设定值" preferenceSyncConflictChoiceCancel: "取消同步" @@ -1348,6 +1362,8 @@ postForm: "投稿窗口" textCount: "字数" information: "关于" chat: "聊天" +directMessage: "私信" +directMessage_short: "消息" migrateOldSettings: "迁移旧设置信息" migrateOldSettings_description: "通常设置信息将自动迁移。但如果由于某种原因迁移不成功,则可以手动触发迁移过程。当前的配置信息将被覆盖。" compress: "压缩" @@ -1360,22 +1376,68 @@ readonly: "只读" goToDeck: "返回至 Deck" federationJobs: "联合作业" driveAboutTip: "网盘可以显示以前上传的文件。
\n也可以在发布帖子时重复使用文件,或在发布帖子前预先上传文件。
\n删除文件时,其将从至今为止所有用到该文件的地方(如帖子、页面、头像、横幅)消失。
\n也可以新建文件夹来整理文件。" +scrollToClose: "滑动并关闭" +advice: "建议" +realtimeMode: "实时模式" +turnItOn: "开启" +turnItOff: "关闭" +emojiMute: "屏蔽表情符号" +emojiUnmute: "取消屏蔽表情符号" +muteX: "屏蔽{x}" +unmuteX: "取消屏蔽{x}" +abort: "中止" +tip: "提示和技巧" +redisplayAllTips: "重新显示所有的提示和技巧" +hideAllTips: "隐藏所有的提示和技巧" +defaultImageCompressionLevel: "默认图像压缩等级" +defaultImageCompressionLevel_description: "较低的等级可以保持画质,但会增加文件大小。
较高的等级可以减少文件大小,但相对应的画质将会降低。" +defaultCompressionLevel: "默认压缩等级" +defaultCompressionLevel_description: "较低的等级可以保持质量,但会增加文件大小。
较高的等级可以减少文件大小,但相对应的质量将会降低。" +inMinutes: "分钟" +inDays: "天" +safeModeEnabled: "已启用安全模式" +pluginsAreDisabledBecauseSafeMode: "因启用了安全模式,所有插件均已被禁用。" +customCssIsDisabledBecauseSafeMode: "因启用了安全模式,无法应用自定义 CSS。" +themeIsDefaultBecauseSafeMode: "启用安全模式时将使用默认主题。关闭安全模式后将还原。" +thankYouForTestingBeta: "感谢您协助测试 beta 版!" +createUserSpecifiedNote: "创建指定用户的帖子" +schedulePost: "定时发布" +scheduleToPostOnX: "预定在 {x} 发出" +scheduledToPostOnX: "已预定在 {x} 发出" +schedule: "定时" +scheduled: "定时" +widgets: "小工具" +deviceInfo: "设备信息" +deviceInfoDescription: "咨询技术问题时,将以下信息一并发送有助于解决问题。" +_compression: + _quality: + high: "高质量" + medium: "中质量" + low: "低质量" + _size: + large: "大" + medium: "中" + small: "小" +_order: + newest: "从新到旧" + oldest: "从旧到新" _chat: + messages: "消息" noMessagesYet: "还没有消息" newMessage: "新消息" individualChat: "私聊" individualChat_description: "可以与特定用户进行一对一聊天。" roomChat: "群聊" - roomChat_description: "可以进行多人聊天。\n就算用户未允许私聊,只要接受了邀请,仍可以聊天。" - createRoom: "创建房间" + roomChat_description: "支持多人同时进行消息交流。\n即使部分用户未开放私信权限,只要接受了邀请,仍可进行聊天。" + createRoom: "创建群组" inviteUserToChat: "邀请用户来开始聊天" - yourRooms: "已创建的房间" - joiningRooms: "已加入的房间" + yourRooms: "创建的群组" + joiningRooms: "已加入的群组" invitations: "邀请" noInvitations: "没有邀请" history: "历史" noHistory: "没有历史记录" - noRooms: "没有房间" + noRooms: "没有群组" inviteUser: "邀请用户" sentInvitations: "已发送的邀请" join: "加入" @@ -1386,14 +1448,16 @@ _chat: home: "首页" send: "发送" newline: "换行" - muteThisRoom: "静音此房间" - deleteRoom: "删除房间" + muteThisRoom: "屏蔽该群组" + deleteRoom: "删除群组" chatNotAvailableForThisAccountOrServer: "此服务器或者账户还未开启聊天功能。" chatIsReadOnlyForThisAccountOrServer: "此服务器或者账户内的聊天为只读。无法发布新信息或创建及加入群聊。" - chatNotAvailableInOtherAccount: "对方账户目前处于无法使用聊天的状态。" - cannotChatWithTheUser: "无法与此用户聊天" + chatNotAvailableInOtherAccount: "对方的账户当前无法使用私信。" + cannotChatWithTheUser: "无法私信该用户" cannotChatWithTheUser_description: "可能现在无法使用聊天,或者对方未开启聊天。" - chatWithThisUser: "聊天" + youAreNotAMemberOfThisRoomButInvited: "您还未加入此房间,但已收到邀请。如要加入,请接受邀请。" + doYouAcceptInvitation: "要接受邀请吗?" + chatWithThisUser: "私信" thisUserAllowsChatOnlyFromFollowers: "此用户仅接受关注者发起的聊天。" thisUserAllowsChatOnlyFromFollowing: "此用户仅接受关注的人发起的聊天。" thisUserAllowsChatOnlyFromMutualFollowing: "此用户仅接受互相关注的人发起的聊天。" @@ -1432,11 +1496,21 @@ _settings: makeEveryTextElementsSelectable: "使所有的文字均可选择" makeEveryTextElementsSelectable_description: "若开启,在某些情况下可能降低用户体验。" useStickyIcons: "使图标跟随滚动" + enableHighQualityImagePlaceholders: "显示高质量图像的占位符" + uiAnimations: "UI 动画" showNavbarSubButtons: "在导航栏中显示副按钮" ifOn: "启用时" ifOff: "关闭时" + enableSyncThemesBetweenDevices: "在设备间同步已安装的主题" enablePullToRefresh: "开启下拉刷新" enablePullToRefresh_description: "使用鼠标时按下滚轮来拖动" + realtimeMode_description: "与服务器建立连接并实时更新内容。将会增加流量和电池消耗。" + contentsUpdateFrequency: "内容获取频率" + contentsUpdateFrequency_description: "设置越高,内容更新越实时,但性能会降低,并且会消耗更多的流量和电池。" + contentsUpdateFrequency_description2: "当实时模式开启时,无论此设置如何,内容都会实时更新。" + showUrlPreview: "显示 URL 预览" + showAvailableReactionsFirstInNote: "在顶部显示可用的回应" + showPageTabBarBottom: "在下方显示页面标签栏" _chat: showSenderName: "显示发送者的名字" sendOnEnter: "回车键发送" @@ -1444,6 +1518,7 @@ _preferencesProfile: profileName: "配置名" profileNameDescription: "请指定用于识别此设备的名称" profileNameDescription2: "如「PC」、「手机」等" + manageProfiles: "管理配置文件" _preferencesBackup: autoBackup: "自动备份" restoreFromBackup: "从备份恢复" @@ -1482,7 +1557,7 @@ _delivery: manuallySuspended: "手动停止中" goneSuspended: "因服务器被删除而停止" autoSuspendedForNotResponding: "因服务器无应答而停止" - softwareSuspended: "因有不可用的软件而停止" + softwareSuspended: "因有停止投递的软件而停止" _bubbleGame: howToPlay: "游戏说明" hold: "抓住" @@ -1507,13 +1582,13 @@ _announcement: tooManyActiveAnnouncementDescription: "若有大量活动公告,可能会造成用户体验下降。请考虑归档已完成的公告。" readConfirmTitle: "标记为已读?" readConfirmText: "阅读“{title}”的内容并将其标记为已读。" - shouldNotBeUsedToPresentPermanentInfo: "我们建议使用公告来发布临时性的流动信息而不是固定的常规信息,因为这可能损害用户体验,尤其是对于新用户而言。" + shouldNotBeUsedToPresentPermanentInfo: "因可能损坏新用户的 UX 体验,建议将通知用于发布具有时效性的信息,而不是用于长期展示的信息。" dialogAnnouncementUxWarn: "同时存在 2 个或以上的对话框公告极有可能对用户体验产生负面的影响,建议谨慎使用。" silence: "不发送通知" silenceDescription: "开启后,此条公告将不会发送通知,也不强制用户阅读。" _initialAccountSetting: accountCreated: "账户创建完成了!" - letsStartAccountSetup: "来进行帐户的初始设置吧。" + letsStartAccountSetup: "马上来进行账户的初始设定吧。" letsFillYourProfile: "首先,来设定你的个人档案吧!" profileSetting: "个人资料设置" privacySetting: "隐私设置" @@ -1525,7 +1600,7 @@ _initialAccountSetting: haveFun: "希望 {name} 在这里玩得开心!" youCanContinueTutorial: "您可以继续了解 {name}(CherryPick) 的使用教程,也可以在此停止教程并立即开始使用它。\n" startTutorial: "开始教学" - skipAreYouSure: "要跳过初始设置吗?" + skipAreYouSure: "要跳过初始设定吗?" laterAreYouSure: "要稍后再进行初始设定吗?" _initialTutorial: launchTutorial: "观看教学" @@ -1609,12 +1684,37 @@ _serverSettings: fanoutTimelineDbFallback: "回退到数据库" fanoutTimelineDbFallbackDescription: "当启用时,若时间线未被缓存,则将额外查询数据库。禁用该功能可通过不执行回退处理进一步减少服务器负载,但会限制可检索的时间线范围。" reactionsBufferingDescription: "开启时可显著提高发送回应时的性能,及减轻数据库负荷。但 Redis 的内存用量会相应增加。" + remoteNotesCleaning: "自动清理远程投稿" + remoteNotesCleaning_description: "启用后,将自动清理已无法找到的旧的远程投稿,可减缓数据库的增长。" + remoteNotesCleaningMaxProcessingDuration: "最长清理持续时间" + remoteNotesCleaningExpiryDaysForEachNotes: "最短帖子保留期限" inquiryUrl: "联络地址" inquiryUrlDescription: "用来指定诸如向服务运营商咨询的论坛地址,或记载了运营商联系方式之类的网页地址。" openRegistration: "开放注册" - openRegistrationWarning: "开放注册有风险。建议仅当能够持续监控服务器并在出现问题时能够立即响应时才打开它。" + openRegistrationWarning: "开放注册有风险。建议仅当能够持续监控服务器,并在出现问题时能够立即响应时才打开它。" thisSettingWillAutomaticallyOffWhenModeratorsInactive: "若在一段时间内没有检测到管理活动,为防止垃圾信息,此设定将自动关闭。" - deliverSuspendedSoftware: "不可用的软件" + deliverSuspendedSoftware: "停止投递的软件" + deliverSuspendedSoftwareDescription: "可因安全漏洞之类的原因,停止向指定的服务器及服务器版本送信。版本信息由服务器提供,不保证可靠性。可使用 semver 范围来指定版本,但指定 >= 2024.3.1 将不包括如 2024.3.1-custom.0 等自定义版本,因此建议像 >= 2024.3.1-0 这样指定 prerelease 版本。" + singleUserMode: "单用户模式" + singleUserMode_description: "若此服务器只有自己使用,开启此模式将最佳化性能。" + signToActivityPubGet: "对 GET 请求签名" + signToActivityPubGet_description: "通常情况下请保持启用。若遇到联合通信方面的问题,将其关闭可能会有所改善,但另一方面有可能会造成无法通信。" + proxyRemoteFiles: "代理远程文件" + proxyRemoteFiles_description: "如果启用,远程服务器的文件将由代理提供。可有效保护图像预览缩略图的生成与用户隐私。" + allowExternalApRedirect: "允许通过 ActivityPub 重定向查询" + allowExternalApRedirect_description: "启用时,将允许其它服务器通过此服务器查询第三方内容,但有可能导致内容欺骗。" + userGeneratedContentsVisibilityForVisitor: "用户生成内容对非用户的可见性" + userGeneratedContentsVisibilityForVisitor_description: "对于防止诸如难以管理的不适当的远程内容通过自己的服务器意外地在互联网上公开等问题很有用。" + userGeneratedContentsVisibilityForVisitor_description2: "包含服务器接收到的远程内容在内,无条件将服务器上的所有内容公开在互联网上存在风险。特别是对去中心化的特性不是很了解的访问者有可能将远程服务器上的内容误认为是在此服务器内生成的,需要特别留意。" + restartServerSetupWizardConfirm_title: "要重新开始服务器初始设定向导吗?" + restartServerSetupWizardConfirm_text: "现有的部分设定将重置。" + entrancePageStyle: "入口页面样式" + showTimelineForVisitor: "显示时间线" + showActivitiesForVisitor: "显示活动" + _userGeneratedContentsVisibilityForVisitor: + all: "全部公开" + localOnly: "仅公开本地内容,隐藏远程内容" + none: "全部隐藏" _accountMigration: moveFrom: "从别的账号迁移到此账户" moveFromSub: "为另一个账户建立别名" @@ -1716,7 +1816,7 @@ _achievements: _login500: title: "老熟人Ⅰ" description: "累计登录 500 天" - flavor: "诸君,我喜欢贴文" + flavor: "诸君,我喜欢帖文" _login600: title: "老熟人Ⅱ" description: "累计登录 600 天" @@ -1735,7 +1835,7 @@ _achievements: flavor: "感谢您使用 CherryPick!" _noteClipped1: title: "忍不住要收藏到便签" - description: "第一次将贴文贴进便签" + description: "第一次将帖子加入便签" _noteFavorited1: title: "观星者" description: "第一次将帖子加入收藏" @@ -1835,7 +1935,7 @@ _achievements: description: "试图对网盘中的文件夹进行循环嵌套" _reactWithoutRead: title: "有好好读过吗?" - description: "在含有 100 字以上的帖子被发出三秒内做出回应" + description: "在含有100字以上的帖子被发出三秒内做出回应" _clickedClickHere: title: "点这里" description: "点了这里" @@ -1891,7 +1991,7 @@ _role: name: "角色名称" description: "角色描述" permission: "角色权限" - descriptionOfPermission: "监察员可以执行基本地审核操作。\n管理员可以更改服务器的所有设置。" + descriptionOfPermission: "监察员可以执行基本的审核操作。\n管理员可以更改实例的所有设置。" assignTarget: "授权对象" descriptionOfAssignTarget: "手动指手动选择谁被包括在这个角色中。\n符合条件指设置条件以自动包括符合条件的用户。" manual: "手动" @@ -1937,20 +2037,22 @@ _role: canManageAvatarDecorations: "管理头像挂件" driveCapacity: "网盘容量" maxFileSize: "可上传的最大文件大小" + maxFileSize_caption: "可能在反向代理或 CDN 等前端存在其它设定值。" alwaysMarkNsfw: "总是将文件标记为 NSFW" canUpdateBioMedia: "可以更新头像和横幅" pinMax: "帖子置顶数量限制" antennaMax: "可创建的最大天线数量" - wordMuteMax: "隐藏词的字数限制" + wordMuteMax: "屏蔽词的字数限制" webhookMax: "Webhook 创建数量限制" clipMax: "便签创建数量限制" - noteEachClipsMax: "单个便签内的贴文数量限制" + noteEachClipsMax: "便签内贴文的最大数量" userListMax: "用户列表创建数量限制" userEachUserListsMax: "单个用户列表内用户数量限制" rateLimitFactor: "速率限制" descriptionOfRateLimitFactor: "值越小限制越少,值越大限制越多。" canHideAds: "可以隐藏广告" canSearchNotes: "是否可以搜索帖子" + canSearchUsers: "使用用户检索" canUseTranslator: "使用翻译功能" avatarDecorationLimit: "可添加头像挂件的最大个数" canImportAntennas: "允许导入天线" @@ -1958,7 +2060,13 @@ _role: canImportFollowing: "允许导入关注列表" canImportMuting: "允许导入隐藏列表" canImportUserLists: "允许导入用户列表" - chatAvailability: "允许聊天" + chatAvailability: "允许私信" + uploadableFileTypes: "可上传的文件类型" + uploadableFileTypes_caption: "指定 MIME 类型。可用换行指定多个类型,也可以用星号(*)作为通配符。(如 image/*)" + uploadableFileTypes_caption2: "文件根据文件的不同,可能无法判断其类型。若要允许此类文件,请在指定中添加 {x}。" + noteDraftLimit: "可在服务器上创建多少草稿" + scheduledNoteLimit: "可同时创建的定时帖子数量" + watermarkAvailable: "能否使用水印功能" _condition: roleAssignedTo: "已分配给手动角色" isLocal: "是本地用户" @@ -2023,9 +2131,9 @@ _forgotPassword: ifNoEmail: "如果您没有设置电子邮件地址,请联系管理员。" contactAdmin: "该服务器不支持发送电子邮件。如果您想重设密码,请联系管理员。" _gallery: - my: "我的图库" - liked: "喜欢的图片" - like: "喜欢" + my: "我的图集" + liked: "喜欢的图集" + like: "喜欢!" unlike: "取消喜欢" _email: _follow: @@ -2157,14 +2265,14 @@ _channel: edit: "编辑频道" setBanner: "设置横幅" removeBanner: "删除横幅" - featured: "热点" - owned: "管理中" + featured: "热门" + owned: "正在管理" following: "正在关注" - usersCount: "有 {n} 人参与" - notesCount: "有 {n} 个帖子" + usersCount: "有{n}人参与" + notesCount: "有{n}个帖子" nameAndDescription: "名称与描述" nameOnly: "仅名称" - allowRenoteToExternal: "允许在频道外转帖及引用" + allowRenoteToExternal: "允许转发到频道外和引用" _menuDisplay: sideFull: "横向" sideIcon: "横向(图标)" @@ -2175,15 +2283,16 @@ _wordMute: muteWordsDescription: "AND 条件用空格分隔,OR 条件用换行符分隔。" muteWordsDescription2: "正则表达式用斜线包裹" _instanceMute: - instanceMuteDescription: "隐藏服务器中的所有帖子和转帖,包括这些服务器上的用户回复。" - instanceMuteDescription2: "一行一个" + instanceMuteDescription: "屏蔽服务器中所有的帖子和转帖,包括该服务器内用户的回复。" + instanceMuteDescription2: "通过换行符分隔进行设置" title: "下面实例中的帖子将被隐藏。" - heading: "已隐藏的服务器" + heading: "已屏蔽的服务器" _theme: explore: "寻找主题" install: "安装主题" manage: "主题管理" code: "主题代码" + copyThemeCode: "复制主题代码" description: "描述" installed: "{name} 已安装" installedThemes: "已安装的主题" @@ -2242,7 +2351,6 @@ _theme: buttonBg: "按钮背景" buttonHoverBg: "按钮背景(悬停)" inputBorder: "输入框边框" - driveFolderBg: "网盘的文件夹背景" badge: "徽章" messageBg: "聊天背景" fgHighlighted: "高亮显示文本" @@ -2251,7 +2359,7 @@ _sfx: noteMy: "我的帖子" notification: "通知" reaction: "选择回应时" - chatMessage: "聊天信息" + chatMessage: "私信" _soundSettings: driveFile: "使用网盘内的音频" driveFileWarn: "选择网盘上的文件" @@ -2262,28 +2370,29 @@ _soundSettings: driveFileError: "无法读取声音。请更改设置。" _ago: future: "未来" - justNow: "最近" - secondsAgo: "{n} 秒前" - minutesAgo: "{n} 分前" - hoursAgo: "{n} 小时前" - daysAgo: "{n} 日前" - weeksAgo: "{n} 周前" - monthsAgo: "{n} 月前" - yearsAgo: "{n} 年前" + justNow: "刚刚" + secondsAgo: "{n}秒前" + minutesAgo: "{n}分钟前" + hoursAgo: "{n}小时前" + daysAgo: "{n}天前" + weeksAgo: "{n}周前" + monthsAgo: "{n}个月前" + yearsAgo: "{n}年前" invalid: "没有" _timeIn: seconds: "{n}秒后" - minutes: "{n} 分后" - hours: "{n} 小时后" + minutes: "{n}分钟后" + hours: "{n}小时后" days: "{n}天后" - weeks: "{n} 周后" - months: "{n} 月后" - years: "{n} 年后" + weeks: "{n}周后" + months: "{n}个月后" + years: "{n}年后" _time: second: "秒" - minute: "分" + minute: "分钟" hour: "小时" - day: "日" + day: "天" + month: "个月" _2fa: alreadyRegistered: "此设备已被注册" registerTOTP: "开始设置验证器" @@ -2316,36 +2425,36 @@ _2fa: _permissions: "read:account": "查看账户信息" "write:account": "更改帐户信息" - "read:blocks": "查看屏蔽列表" - "write:blocks": "编辑屏蔽列表" + "read:blocks": "查看黑名单" + "write:blocks": "编辑黑名单" "read:drive": "查看网盘" "write:drive": "管理网盘文件" "read:favorites": "查看收藏夹" "write:favorites": "编辑收藏夹" "read:following": "查看关注信息" "write:following": "关注/取消关注" - "read:messaging": "查看消息" + "read:messaging": "查看私信" "write:messaging": "撰写或删除消息" - "read:mutes": "查看隐藏列表" - "write:mutes": "编辑隐藏列表" + "read:mutes": "查看屏蔽列表" + "write:mutes": "编辑屏蔽列表" "write:notes": "撰写或删除帖子" "read:notifications": "查看通知" "write:notifications": "管理通知" "read:reactions": "查看回应" - "write:reactions": "回应操作" + "write:reactions": "编辑回应" "write:votes": "投票" "read:pages": "查看页面" - "write:pages": "操作页面" + "write:pages": "编辑页面" "read:page-likes": "查看喜欢的页面" - "write:page-likes": "操作喜欢的页面" + "write:page-likes": "管理喜欢的页面" "read:user-groups": "查看用户组" - "write:user-groups": "操作用户组" + "write:user-groups": "编辑用户组" "read:channels": "查看频道" "write:channels": "管理频道" - "read:gallery": "浏览图库" - "write:gallery": "操作图库" - "read:gallery-likes": "读取喜欢的图片" - "write:gallery-likes": "操作喜欢的图片" + "read:gallery": "浏览图集" + "write:gallery": "编辑图集" + "read:gallery-likes": "浏览喜欢的图集" + "write:gallery-likes": "管理喜欢的图集" "read:flash": "查看 Play" "write:flash": "编辑 Play" "read:flash-likes": "查看 Play 的点赞" @@ -2373,33 +2482,33 @@ _permissions: "read:admin:roles": "查看角色" "write:admin:relays": "编辑中继" "read:admin:relays": "查看中继" - "write:admin:invite-codes": "编辑邀请码" + "write:admin:invite-codes": "管理邀请码" "read:admin:invite-codes": "查看邀请码" - "write:admin:announcements": "编辑公告" + "write:admin:announcements": "管理公告" "read:admin:announcements": "查看公告" "write:admin:avatar-decorations": "编辑头像挂件" "read:admin:avatar-decorations": "查看头像挂件" "write:admin:federation": "编辑联合相关信息" "write:admin:account": "编辑用户账户" "read:admin:account": "查看用户相关情报" - "write:admin:emoji": "编辑表情文字" - "read:admin:emoji": "查看表情文字" + "write:admin:emoji": "编辑表情符号" + "read:admin:emoji": "查看表情符号" "write:admin:queue": "编辑作业队列" "read:admin:queue": "查看作业队列相关情报" "write:admin:promo": "运营推广说明" - "write:admin:drive": "编辑用户网盘" + "write:admin:drive": "管理用户网盘" "read:admin:drive": "查看用户网盘相关情报" "read:admin:stream": "使用管理员用的 Websocket API" - "write:admin:ad": "编辑广告" + "write:admin:ad": "管理广告" "read:admin:ad": "查看广告" "write:invite-codes": "生成邀请码" "read:invite-codes": "获取已发行的邀请码" - "write:clip-favorite": "编辑便签的点赞" + "write:clip-favorite": "管理喜欢的便签" "read:clip-favorite": "查看便签的点赞" "read:federation": "查看联合相关信息" "write:report-abuse": "举报用户" "write:chat": "撰写或删除消息" - "read:chat": "查看聊天" + "read:chat": "查看私信" _auth: shareAccessTitle: "应用程序授权许可" shareAccess: "您要授权允许 “{name}” 访问您的帐户吗?" @@ -2413,13 +2522,14 @@ _auth: scopeUser: "以下面的用户进行操作" pleaseLogin: "在对应用进行授权许可之前,请先登录" byClickingYouWillBeRedirectedToThisUrl: "允许访问后将会自动重定向到以下 URL" + alreadyAuthorized: "此应用已有访问许可。" _antennaSources: all: "所有帖子" homeTimeline: "已关注用户的帖子" users: "来自指定用户的帖子" userList: "来自指定列表中的帖子" userGroup: "来自指定群组中用户的帖子" - userBlacklist: "除掉已选择用户后所有的帖子" + userBlacklist: "过滤指定用户后的所有帖子" _weekday: sunday: "星期日" monday: "星期一" @@ -2459,7 +2569,7 @@ _widgets: chooseList: "选择列表" clicker: "点击器" birthdayFollowings: "今天是他们的生日" - chat: "聊天" + chat: "私信" _cw: hide: "隐藏" show: "查看更多" @@ -2467,26 +2577,26 @@ _cw: files: "{count} 个文件" _poll: noOnlyOneChoice: "需要至少两个选项" - choiceN: "选择 {n}" + choiceN: "选项{n}" noMore: "无法再添加更多了" - canMultipleVote: "允许多个投票" + canMultipleVote: "允许选择多个选项" expiration: "截止时间" infinite: "永久" at: "指定日期" after: "指定时间" deadlineDate: "截止日期" - deadlineTime: "小时" - duration: "时长" - votesCount: "{n} 票" + deadlineTime: "时间" + duration: "期限" + votesCount: "{n}票" totalVotes: "总票数 {n}" vote: "投票" showResult: "显示结果" voted: "已投票" closed: "已截止" - remainingDays: "{d} 天 {h} 小时后截止" + remainingDays: "{d}天{h}小时后截止" remainingHours: "{h} 小时 {m} 分后截止" - remainingMinutes: "{m} 分 {s} 秒后截止" - remainingSeconds: "{s} 秒后截止" + remainingMinutes: "{m}分{s}秒后截止" + remainingSeconds: "{s}秒后截止" _visibility: public: "公开" publicDescription: "您的帖子将出现在全局时间线上" @@ -2499,13 +2609,15 @@ _visibility: disableFederation: "不参与联合" disableFederationDescription: "不发送到其他服务器" _postForm: + quitInspiteOfThereAreUnuploadedFilesConfirm: "还有未上传的文件,要丢弃并关闭窗口吗?" + uploaderTip: "文件还未上传。可以在文件菜单中进行重命名、裁剪、添加水印、设置是否压缩等操作。文件将在发帖时自动上传。" replyPlaceholder: "回复这个帖子..." quotePlaceholder: "引用这个帖子..." channelPlaceholder: "发布到频道…" _placeholders: - a: "现在如何?" - b: "发生了什么?" - c: "你有什么想法?" + a: "现在怎么样?" + b: "想好发些什么了吗?" + c: "在想些什么呢?" d: "你想要发布些什么吗?" e: "请写下来吧" f: "等待您的发布..." @@ -2525,14 +2637,14 @@ _profile: avatarDecorationMax: "最多可添加 {max} 个挂件" followedMessage: "被关注时显示的消息" followedMessageDescription: "可以设置被关注时向对方显示的短消息。" - followedMessageDescriptionForLockedAccount: "需要批准才能关注的情况下,消息是在请求被批准后显示。" + followedMessageDescriptionForLockedAccount: "需要批准才能关注的情况下,消息会在请求被批准后显示。" _exportOrImport: allNotes: "所有帖子" favoritedNotes: "收藏的帖子" clips: "便签" followingList: "关注中" - muteList: "隐藏" - blockingList: "屏蔽" + muteList: "屏蔽" + blockingList: "拉黑" userLists: "列表" excludeMutingUsers: "排除屏蔽用户" excludeInactiveUsers: "排除不活跃用户" @@ -2579,7 +2691,7 @@ _play: editThisPage: "编辑此 Play" viewSource: "查看源代码" my: "我的 Play" - liked: "点赞的 Play" + liked: "喜欢的 Play" featured: "热门" title: "标题" script: "脚本" @@ -2596,7 +2708,7 @@ _pages: editThisPage: "编辑此页面" viewSource: "查看源代码" viewPage: "查看页面" - like: "赞" + like: "喜欢" unlike: "取消喜欢" my: "我的页面" liked: "喜欢的页面" @@ -2644,11 +2756,13 @@ _notification: youGotReply: "来自{name}的回复" youGotQuote: "来自{name}的引用" youRenoted: "来自{name}的转发" - youWereFollowed: "关注了你。" + youWereFollowed: "关注了你" youReceivedFollowRequest: "您有新的关注请求" yourFollowRequestAccepted: "您的关注请求已通过" youWereInvitedToGroup: "{userName} 您有新的群组邀请" pollEnded: "问卷调查结果已生成。" + scheduledNotePosted: "定时帖子已发布" + scheduledNotePostFailed: "定时帖子发布失败" newNote: "新的帖子" unreadAntennaNote: "天线 {name}" roleAssigned: "授予的角色" @@ -2678,6 +2792,8 @@ _notification: quote: "引用" reaction: "回应" pollEnded: "问卷调查结束" + scheduledNotePosted: "定时发送成功" + scheduledNotePostFailed: "定时发送失败" receiveFollowRequest: "收到关注请求" followRequestAccepted: "关注请求已通过" groupInvited: "加入群组邀请" @@ -2729,7 +2845,7 @@ _deck: mentions: "提及" direct: "指定用户" roleTimeline: "角色时间线" - chat: "聊天" + chat: "私信" _dialog: charactersExceeded: "已经超过了最大字符数! 当前字符数 {current} / 限制字符数 {max}" charactersBelow: "低于最小字符数!当前字符数 {current} / 限制字符数 {min}" @@ -2749,7 +2865,7 @@ _webhookSettings: _events: follow: "关注时" followed: "被关注时" - note: "发布贴文时" + note: "发布帖文时" reply: "收到回复时" renote: "被转发时" reaction: "被回应时" @@ -2825,7 +2941,7 @@ _moderationLogTypes: deleteAccount: "删除了账户" deletePage: "删除了页面" deleteFlash: "删除了 Play" - deleteGalleryPost: "删除了图库稿件" + deleteGalleryPost: "删除图集内容" deleteChatRoom: "删除聊天室" updateProxyAccountDescription: "更新代理账户的简介" _fileViewer: @@ -2835,6 +2951,7 @@ _fileViewer: url: "URL" uploadedAt: "添加日期" attachedNotes: "附加到的帖子" + usage: "使用" thisPageCanBeSeenFromTheAuthor: "此页只能被该文件的上传者查看。" _externalResourceInstaller: title: "从外部站点安装" @@ -2882,9 +2999,12 @@ _dataSaver: _avatar: title: "头像" description: "停止播放头像的动画。 由于动画图片的文件大小可能比普通图像大,这可以进一步减少数据流量。" - _urlPreview: - title: "URL预览缩略图\n" + _urlPreviewThumbnail: + title: "不显示 URL预览缩略图" description: "将不再加载 URL 预览缩略图。" + _disableUrlPreview: + title: "禁用 URL 预览" + description: "关闭 URL 预览功能。与预览缩略图不同,减少了链接信息的加载。" _code: title: "代码高亮" description: "如果使用了代码高亮标记,例如在 MFC 中,则在点击之前不会加载。 代码高亮要求加载每种高亮语言的定义文件,由于这些文件不再自动加载,因此有望减少数据传输量。" @@ -2942,6 +3062,8 @@ _offlineScreen: _urlPreviewSetting: title: "设置 URL 预览" enable: "启用 URL 预览" + allowRedirect: "允许预览目标的重定向" + allowRedirectDescription: "如果输入的 URL 被重定向,可设置是否跟随重定向目标并显示预览。禁用此选项将节省服务器资源,但重定向目标的内容将不会显示。" timeout: "超时阈值(ms)" timeoutDescription: "如果获取预览所用时间超过这个值,则不生成预览。" maximumContentLength: "Content-Length 的最大值(byte)" @@ -3015,10 +3137,6 @@ _customEmojisManager: uploadSettingDescription: "可以在此页面设置上传表情符号时的行为。" directoryToCategoryLabel: "将目录名设为「category」" directoryToCategoryCaption: "拖放目录时,将目录名设置为「category」" - emojiInputAreaCaption: "请使用其中一种方法选择要注册的表情符号。" - emojiInputAreaList1: "在此区域内拖放图像文件或者目录" - emojiInputAreaList2: "单击此链接以从电脑中选择" - emojiInputAreaList3: "单击此链接以从网盘中选择" confirmRegisterEmojisDescription: "要将列表内显示的表情符号替换为新的自定义表情符号吗?(为降低服务器负载,一次操作最多只能注册 {count} 个表情符号)" confirmClearEmojisDescription: "要放弃编辑并将列表内表示的表情符号清空吗?" confirmUploadEmojisDescription: "要将拖放的 {count} 个文件上传到网盘上吗?" @@ -3043,8 +3161,8 @@ _selfXssPrevention: description2: "如果不能完全理解将要粘贴的内容,%c 请立即停止操作并关闭这个窗口。" description3: "详情请看这里。{link}" _followRequest: - recieved: "已收到申请" - sent: "已发送申请" + recieved: "收到的请求" + sent: "已发送的请求" _remoteLookupErrors: _federationNotAllowed: title: "无法与此服务器通信" @@ -3079,13 +3197,14 @@ _bootErrors: serverError: "请稍等片刻再重试。若问题仍无法解决,请将以下 Error ID 一起发送给管理员。" solution: "以下方法或许可以解决问题:" solution1: "将浏览器及操作系统更新到最新版本" - solution2: "禁用广告屏蔽插件" + solution2: "禁用广告拦截插件" solution3: "清除浏览器缓存" solution4: "(Tor Browser)将 dom.webaudio.enabled 设定为 true" otherOption: "其它选项" otherOption1: "清除客户端设定与缓存" otherOption2: "使用简易客户端" otherOption3: "启动修复工具" + otherOption4: "以安全模式启动 CherryPick" _search: searchScopeAll: "全部" searchScopeLocal: "本地" @@ -3094,3 +3213,195 @@ _search: pleaseEnterServerHost: "请填写服务器主机名" pleaseSelectUser: "请选择用户" serverHostPlaceholder: "如:cherrypick.example.com" +_serverSetupWizard: + installCompleted: "CherryPick 安装完成!" + firstCreateAccount: "首先来创建管理员账号吧。" + accountCreated: "管理员账号已创建!" + serverSetting: "服务器设置" + youCanEasilyConfigureOptimalServerSettingsWithThisWizard: "用此向导来轻松地以最佳方式配置服务器。" + settingsYouMakeHereCanBeChangedLater: "这里的设置在之后也能更改。" + howWillYouUseMisskey: "打算怎样使用 CherryPick?" + _use: + single: "单用户服务器" + single_description: "仅供自己使用的单人服务器" + single_youCanCreateMultipleAccounts: "使用单用户服务器模式使用时,也可以根据需要创建多个账号。" + group: "小圈子服务器" + group_description: "邀请其他可信用户一起使用的多人服务器" + open: "开放服务器" + open_description: "以容纳不限定数量的用户的模式运行" + openServerAdvice: "容纳不限定数量的用户有风险。推荐建立能应对各种问题的强大的管理体制来运营。" + openServerAntiSpamAdvice: "为防止自己的服务器成为广告发信基地,请打开如 reCAPTCHA 等 Bot 防御功能,并谨慎关注安全性。" + howManyUsersDoYouExpect: "预计会有多少用户?" + _scale: + small: "100 人以下(小规模)" + medium: "100 人以上 1000 人以下(中规模)" + large: "1000 人以上(大规模)" + largeScaleServerAdvice: "运营大规模服务器可能需要高级基础设施知识,如负载均衡和数据库复制。" + doYouConnectToFediverse: "要加入 Fediverse 吗?" + doYouConnectToFediverse_description1: "若加入由分散性服务器所构成的网络(Fediverse),将能与其它服务器交换内容。" + doYouConnectToFediverse_description2: "加入 Fediverse 在这里被称为「联合」。" + youCanConfigureMoreFederationSettingsLater: "可在之后进行如哪些服务器可以进行联合等高级设置。" + remoteContentsCleaning: "自动清理传入内容" + remoteContentsCleaning_description: "加入联合后,服务器将持续接收大量内容。打开自动清理后,将自动删除无法找到的旧内容,可节省存储空间。" + adminInfo: "管理员信息" + adminInfo_description: "设置用于接受询问的管理员信息。" + adminInfo_mustBeFilled: "开放服务器或开启了联合的情况下必须输入。" + followingSettingsAreRecommended: "推荐以下设置" + applyTheseSettings: "使用此设置" + skipSettings: "跳过设置" + settingsCompleted: "设置完成!" + settingsCompleted_description: "辛苦了。设置已完成,可以立即开始使用服务器了。" + settingsCompleted_description2: "服务器的详细设置可在「控制面板」进行。" + donationRequest: "请求捐助" + _donationRequest: + text1: "CherryPick 是由志愿者开发的免费软件。" + text2: "为了今后也能继续开发,如果可以的话,请考虑一下捐助。" + text3: "也有面向支援者的特典!" +_uploader: + editImage: "编辑图像" + compressedToX: "压缩 {x}" + savedXPercent: "节省了 {x}% 的空间" + abortConfirm: "还有未上传的文件,要中止吗?" + doneConfirm: "还有未上传的文件,要完成吗?" + maxFileSizeIsX: "可上传最大 {x} 的文件。" + allowedTypes: "可上传的文件类型" + tip: "文件还没有被上传。可在此对话框中进行上传前确认、重命名、压缩、裁剪等操作。准备完成后,点击「上传」即可开始上传。" +_clientPerformanceIssueTip: + title: "如果觉得电池耗电过高" + makeSureDisabledAdBlocker: "请关闭广告拦截器" + makeSureDisabledAdBlocker_description: "广告拦截器会影响性能。请检查操作系统功能、浏览器功能或附加组件是否启用了广告拦截器。" + makeSureDisabledCustomCss: "请关闭自定义 CSS" + makeSureDisabledCustomCss_description: "覆盖样式可能会影响性能。请确保没有启用任何自定义 CSS 或覆盖样式的扩展。" + makeSureDisabledAddons: "请关闭扩展" + makeSureDisabledAddons_description: "某些扩展可能会干扰客户端的运行并影响性能。尝试禁用浏览器扩展并查看是否有改善。" +_clip: + tip: "便签功能可以将帖子合并在一起。" +_userLists: + tip: "可创建包含任意用户的列表。已创建的列表可作为时间线查看。" +watermark: "水印" +defaultPreset: "默认预设" +_watermarkEditor: + tip: "可在图像内增加包含作者等信息的水印。" + quitWithoutSaveConfirm: "不保存就退出吗?" + driveFileTypeWarn: "不支持此文件" + driveFileTypeWarnDescription: "请选择图像文件" + title: "编辑水印" + cover: "覆盖全体" + repeat: "平铺" + preserveBoundingRect: "调整为旋转时不超出范围" + opacity: "不透明度" + scale: "大小" + text: "文本" + qr: "二维码" + position: "位置" + margin: "边距" + type: "类型" + image: "图片" + advanced: "高级" + angle: "角度" + stripe: "条纹" + stripeWidth: "线条宽度" + stripeFrequency: "线条数量" + polkadot: "波点" + checker: "检查" + polkadotMainDotOpacity: "主波点的不透明度" + polkadotMainDotRadius: "主波点的大小" + polkadotSubDotOpacity: "副波点的不透明度" + polkadotSubDotRadius: "副波点的大小" + polkadotSubDotDivisions: "副波点的数量" + leaveBlankToAccountUrl: "留空则为账户 URL" +_imageEffector: + title: "效果" + addEffect: "添加效果" + discardChangesConfirm: "丢弃当前设置并退出?" + nothingToConfigure: "还没有设置" + _fxs: + chromaticAberration: "色差" + glitch: "故障" + mirror: "镜像" + invert: "反转颜色" + grayscale: "黑白" + blur: "模糊" + pixelate: "马赛克" + colorAdjust: "色彩校正" + colorClamp: "颜色限制" + colorClampAdvanced: "颜色限制(高级)" + distort: "失真" + threshold: "二值化" + zoomLines: "集中线" + stripe: "条纹" + polkadot: "波点" + checker: "检查" + blockNoise: "块状噪点" + tearing: "撕裂" + fill: "填充" + _fxProps: + angle: "角度" + scale: "大小" + size: "大小" + radius: "半径" + samples: "采样数" + offset: "位置" + color: "颜色" + opacity: "不透明度" + normalize: "标准化" + amount: "数量" + lightness: "浅色" + contrast: "对比度" + hue: "色调" + brightness: "亮度" + saturation: "饱和度" + max: "最大值" + min: "最小值" + direction: "方向" + phase: "相位" + frequency: "频率" + strength: "强度" + glitchChannelShift: "错位" + seed: "种子" + redComponent: "红色成分" + greenComponent: "绿色成分" + blueComponent: "蓝色成分" + threshold: "阈值" + centerX: "中心 X " + centerY: "中心 Y" + zoomLinesSmoothing: "平滑" + zoomLinesSmoothingDescription: "平滑和集中线宽度设置不能同时使用。" + zoomLinesThreshold: "集中线宽度" + zoomLinesMaskSize: "中心直径" + zoomLinesBlack: "变成黑色" + circle: "圆形" +drafts: "草稿" +_drafts: + select: "选择草稿" + cannotCreateDraftAnymore: "已超过可创建的草稿数量。" + cannotCreateDraft: "此内容无法创建草稿。" + delete: "删除草稿" + deleteAreYouSure: "要删除草稿吗?" + noDrafts: "没有草稿" + replyTo: "回复给 {user}" + quoteOf: "对 {user} 帖子的引用" + postTo: "向 {channel} 的投稿" + saveToDraft: "保存到草稿" + restoreFromDraft: "从草稿恢复" + restore: "恢复" + listDrafts: "草稿一览" + schedule: "定时发布" + listScheduledNotes: "定时发布列表" + cancelSchedule: "取消定时" +qr: "二维码" +_qr: + showTabTitle: "显示" + readTabTitle: "读取" + shareTitle: "{name} {acct}" + shareText: "请在 Fediverse 上关注我!" + chooseCamera: "选择相机" + cannotToggleFlash: "无法开关闪光灯" + turnOnFlash: "打开闪光灯" + turnOffFlash: "关闭闪光灯" + startQr: "重新打开二维码扫描器" + stopQr: "关闭二维码扫描器" + noQrCodeFound: "未找到二维码" + scanFile: "扫描设备上的图像" + raw: "文本" + mfm: "MFC" diff --git a/locales/zh-TW.yml b/locales/zh-TW.yml index 08ff5fbdb5..486a1858c6 100644 --- a/locales/zh-TW.yml +++ b/locales/zh-TW.yml @@ -75,7 +75,7 @@ receiveFollowRequest: "您有新的追隨請求" followRequestAccepted: "追隨請求已被接受" mention: "提及" mentions: "提及" -directNotes: "私訊" +directNotes: "指定使用者" importAndExport: "匯入與匯出" import: "匯入" export: "匯出" @@ -251,9 +251,9 @@ noUsers: "沒有任何使用者" editProfile: "編輯個人檔案" noteDeleteConfirm: "確定刪除此貼文嗎?" pinLimitExceeded: "不能置頂更多貼文了" -intro: "CherryPick 部署完成!請建立管理員帳戶。" done: "完成" processing: "處理中" +preprocessing: "準備中" preview: "預覽" default: "預設" defaultValueIs: "預設值:{value}" @@ -299,6 +299,7 @@ uploadFromUrl: "從網址上傳" uploadFromUrlDescription: "您要上傳的檔案網址" uploadFromUrlRequested: "已請求上傳" uploadFromUrlMayTakeTime: "還需要一些時間才能完成上傳。" +uploadNFiles: "上傳了 {n} 個檔案" explore: "探索" messageRead: "已讀" noMoreHistory: "沒有更多歷史紀錄" @@ -327,11 +328,13 @@ dark: "深色" lightThemes: "淺色佈景主題" darkThemes: "深色佈景主題" syncDeviceDarkMode: "與裝置的深色模式同步" +switchDarkModeManuallyWhenSyncEnabledConfirm: "「{x}」已開啟。要關閉同步並手動切換模式嗎?\n" drive: "雲端硬碟" fileName: "檔案名稱" selectFile: "選擇檔案" selectFiles: "選擇檔案" selectFolder: "選擇資料夾" +unselectFolder: "取消選擇資料夾" selectFolders: "選擇資料夾" fileNotSelected: "尚未選擇檔案" renameFile: "重新命名檔案" @@ -344,6 +347,7 @@ addFile: "加入附件" showFile: "瀏覽文件" emptyDrive: "雲端硬碟為空" emptyFolder: "資料夾為空" +dropHereToUpload: "將檔案拖放至此處即可上傳" unableToDelete: "無法刪除" inputNewFileName: "輸入檔案名稱" inputNewDescription: "請輸入新標題 " @@ -586,8 +590,10 @@ showFixedPostForm: "於時間軸頁頂顯示「發送貼文」方框" showFixedPostFormInChannel: "於時間軸頁頂顯示「發送貼文」方框(頻道)" withRepliesByDefaultForNewlyFollowed: "在追隨其他人後,預設在時間軸納入回覆的貼文" newNoteRecived: "發現新貼文" +newNote: "新的貼文" sounds: "音效" sound: "音效" +notificationSoundSettings: "設定通知音效" listen: "聆聽" none: "無" showInPage: "在頁面中顯示" @@ -645,7 +651,7 @@ inboxUrl: "收件夾 URL" addedRelays: "已加入的中繼器" serviceworkerInfo: "如要使用推播通知,需要啟用此選項並設定金鑰。" deletedNote: "已刪除的貼文" -invisibleNote: "私人貼文" +invisibleNote: "私密的貼文" enableInfiniteScroll: "啟用自動滾動頁面模式" visibility: "可見性" poll: "票選活動" @@ -779,6 +785,7 @@ lockedAccountInfo: "即使追隨需要核准,除非你將貼文的可見性設 alwaysMarkSensitive: "預設標記檔案為敏感內容" loadRawImages: "以原始圖檔顯示附件圖檔的縮圖" disableShowingAnimatedImages: "不播放動態圖檔" +disableShowingAnimatedImages_caption: "無論這個設定如何,如果動畫圖片無法播放,可能是因為瀏覽器或作業系統的無障礙設定、省電設定等產生了干擾。" highlightSensitiveMedia: "強調敏感標記" verificationEmailSent: "已發送驗證電子郵件。請點擊進入電子郵件中的連結以完成驗證。" notSet: "未設定" @@ -803,6 +810,7 @@ wide: "寬" narrow: "窄" reloadToApplySetting: "設定將會在頁面重新載入之後生效。要現在就重載頁面嗎?" needReloadToApply: "必須重新載入才會生效。" +needToRestartServerToApply: "必須重新啟動伺服器才會使變更生效。" showTitlebar: "顯示標題列" clearCache: "清除快取資料" onlineUsersCount: "{n} 人上線" @@ -1011,6 +1019,7 @@ failedToUpload: "上傳失敗" cannotUploadBecauseInappropriate: "由於判定可能包含不適當的內容,因此無法上傳。" cannotUploadBecauseNoFreeSpace: "由於雲端硬碟沒有可用空間,因此無法上傳。" cannotUploadBecauseExceedsFileSizeLimit: "由於超過了檔案大小的限制,無法上傳。" +cannotUploadBecauseUnallowedFileType: "由於檔案類型不被允許,無法上傳。\n" beta: "測試版" enableAutoSensitive: "自動 NSFW 判定" enableAutoSensitiveDescription: "如果可行,它將使用機器學習技術判斷檔案是否需要標記為敏感。即使關閉此功能,也可能會依伺服器規則而自動啟用。" @@ -1062,6 +1071,7 @@ permissionDeniedError: "操作被拒絕" permissionDeniedErrorDescription: "此帳戶沒有執行這個操作的權限。" preset: "預設值" selectFromPresets: "從預設值中選擇" +custom: "自訂" achievements: "成就" gotInvalidResponseError: "伺服器的回應無效" gotInvalidResponseErrorDescription: "伺服器可能已關閉或者在維護中,請稍後再試。" @@ -1100,6 +1110,7 @@ prohibitedWordsDescription2: "空格代表「以及」(AND),斜線包圍 hiddenTags: "隱藏標籤" hiddenTagsDescription: "設定的標籤不會在趨勢中顯示,換行可以設定多個標籤。" notesSearchNotAvailable: "無法使用搜尋貼文功能。" +usersSearchNotAvailable: "無法使用使用者搜尋功能。" license: "授權" unfavoriteConfirm: "要取消收錄我的最愛嗎?" myClips: "我的摘錄" @@ -1250,9 +1261,8 @@ showAvatarDecorations: "顯示頭像裝飾" releaseToRefresh: "放開以更新內容" refreshing: "載入更新中" pullDownToRefresh: "往下拉來更新內容" -disableStreamingTimeline: "停用時間軸的即時更新" useGroupedNotifications: "分組顯示通知訊息" -signupPendingError: "驗證您的電子郵件地址時出現問題。連結可能已過期。" +emailVerificationFailedError: "驗證您的電子郵件地址時出現問題。連結可能已過期。" cwNotationRequired: "如果開啟「隱藏內容」,則需要註解說明。" doReaction: "做出反應" code: "程式碼" @@ -1322,6 +1332,8 @@ availableRoles: "可用角色" acknowledgeNotesAndEnable: "了解注意事項後再開啟。" federationSpecified: "此伺服器以白名單聯邦的方式運作。除了管理員指定的伺服器外,它無法與其他伺服器互動。" federationDisabled: "此伺服器未開啟站台聯邦。無法與其他伺服器上的使用者互動。" +draft: "草稿\n" +draftsAndScheduledNotes: "草稿與排定發布" confirmOnReact: "在做出反應前先確認" reactAreYouSure: "用「 {emoji} 」反應嗎?" markAsSensitiveConfirm: "要將這個媒體設定為敏感嗎?" @@ -1339,6 +1351,7 @@ restore: "還原" syncBetweenDevices: "裝置之間的同步化" preferenceSyncConflictTitle: "伺服器上存在設定值" preferenceSyncConflictText: "已啟用同步的設定項目會將設定值儲存至伺服器,並已找到該設定項目在伺服器上儲存的設定值。請選擇要使用哪個設定值進行覆寫。" +preferenceSyncConflictChoiceMerge: "合併至" preferenceSyncConflictChoiceServer: "伺服器設定值" preferenceSyncConflictChoiceDevice: "裝置的設定值" preferenceSyncConflictChoiceCancel: "取消啟用同步" @@ -1348,6 +1361,8 @@ postForm: "發文視窗" textCount: "字數" information: "關於" chat: "聊天" +directMessage: "直接訊息" +directMessage_short: "訊息" migrateOldSettings: "遷移舊設定資訊" migrateOldSettings_description: "通常情況下,這會自動進行,但若因某些原因未能順利遷移,您可以手動觸發遷移處理。請注意,當前的設定資訊將會被覆寫。" compress: "壓縮" @@ -1361,7 +1376,52 @@ goToDeck: "回去甲板" federationJobs: "聯邦通訊作業" driveAboutTip: "在「雲端硬碟」中,會顯示過去上傳的檔案列表。
\n可以在附加到貼文時重新利用,或者事先上傳之後再用於發布。
\n請注意,刪除檔案後,之前使用過該檔案的所有地方(貼文、頁面、大頭貼、橫幅等)也會一併無法顯示。
\n也可以建立資料夾來整理檔案。" scrollToClose: "用滾輪關閉" +advice: "建議" +realtimeMode: "即時模式" +turnItOn: "開啟" +turnItOff: "關閉" +emojiMute: "表情符號靜音" +emojiUnmute: "表情符號解除靜音" +muteX: "將 {x} 靜音" +unmuteX: "將 {x} 解除靜音" +abort: "取消" +tip: "提示與技巧" +redisplayAllTips: "重新顯示所有「提示與技巧」" +hideAllTips: "隱藏所有「提示與技巧」" +defaultImageCompressionLevel: "預設的影像壓縮程度" +defaultImageCompressionLevel_description: "低的話可以保留畫質,但是會增加檔案的大小。
高的話可以減少檔案大小,但是會降低畫質。" +defaultCompressionLevel: "預設的壓縮程度" +defaultCompressionLevel_description: "低的話可以保留品質,但是會增加檔案的大小。
高的話可以減少檔案大小,但是會降低品質。" +inMinutes: "分鐘" +inDays: "日" +safeModeEnabled: "啟用安全模式" +pluginsAreDisabledBecauseSafeMode: "由於啟用安全模式,所有的外掛都被停用。" +customCssIsDisabledBecauseSafeMode: "由於啟用安全模式,所有的客製 CSS 都被停用。" +themeIsDefaultBecauseSafeMode: "在安全模式啟用期間將使用預設主題。關閉安全模式後會恢復原本的設定。" +thankYouForTestingBeta: "感謝您協助驗證 beta 版!" +createUserSpecifiedNote: "建立使用者指定的筆記" +schedulePost: "排定發布" +scheduleToPostOnX: "排定在 {x} 發布" +scheduledToPostOnX: "已排定在 {x} 發布貼文" +schedule: "排定" +scheduled: "排定" +widgets: "小工具" +deviceInfo: "硬體資訊" +deviceInfoDescription: "在提出技術性諮詢時,若能同時提供以下資訊,將有助於解決問題。" +_compression: + _quality: + high: "高品質" + medium: "中品質" + low: "低品質" + _size: + large: "大" + medium: "中" + small: "小" +_order: + newest: "最新的在前" + oldest: "最舊的在前" _chat: + messages: "訊息" noMessagesYet: "尚無訊息" newMessage: "新訊息" individualChat: "ㄧ對一聊天室" @@ -1394,6 +1454,8 @@ _chat: chatNotAvailableInOtherAccount: "對方的帳號無法使用聊天功能。" cannotChatWithTheUser: "無法與此使用者聊天" cannotChatWithTheUser_description: "聊天功能目前無法使用,或對方尚未開放聊天功能。" + youAreNotAMemberOfThisRoomButInvited: "您不是此聊天室的參與者,但已收到邀請。若要加入,請先接受邀請。\n" + doYouAcceptInvitation: "您要接受這個邀請嗎?\n" chatWithThisUser: "聊天" thisUserAllowsChatOnlyFromFollowers: "此使用者僅接受來自追隨者的聊天訊息。" thisUserAllowsChatOnlyFromFollowing: "此使用者僅接受自己追隨的使用者傳送聊天訊息。" @@ -1433,12 +1495,21 @@ _settings: makeEveryTextElementsSelectable: "允許選取所有文字" makeEveryTextElementsSelectable_description: "啟用此功能後,可能會在某些情境下降低可用性。" useStickyIcons: "使大頭貼跟隨捲動" + enableHighQualityImagePlaceholders: "顯示高品質的圖片預覽圖" + uiAnimations: "使用者介面的動畫效果\n" showNavbarSubButtons: "在導覽列顯示輔助按鈕" ifOn: "開啟時" ifOff: "關閉時" enableSyncThemesBetweenDevices: "在裝置之間同步已安裝的主題" enablePullToRefresh: "下拉更新" enablePullToRefresh_description: "使用滑鼠,按下並拖曳滾輪。" + realtimeMode_description: "已與伺服器建立連線,將即時更新內容。這可能會增加資料傳輸量與電池消耗。\n" + contentsUpdateFrequency: "內容取得頻率" + contentsUpdateFrequency_description: "頻率越高,內容更新越即時,但可能會降低效能,並增加資料傳輸量與電池消耗。\n" + contentsUpdateFrequency_description2: "當即時模式開啟時,不論此設定為何,內容都會即時更新。" + showUrlPreview: "顯示網址預覽" + showAvailableReactionsFirstInNote: "將可用的反應顯示在頂部" + showPageTabBarBottom: "在底部顯示頁面的標籤列" _chat: showSenderName: "顯示發送者的名稱" sendOnEnter: "按下 Enter 發送訊息" @@ -1446,6 +1517,7 @@ _preferencesProfile: profileName: "設定檔案名稱" profileNameDescription: "設定一個名稱來識別此裝置。" profileNameDescription2: "例如:「主要個人電腦」、「智慧型手機」等" + manageProfiles: "管理個人檔案" _preferencesBackup: autoBackup: "自動備份" restoreFromBackup: "從備份還原" @@ -1522,7 +1594,7 @@ _initialAccountSetting: theseSettingsCanEditLater: "這裡的設定可以在之後變更。" youCanEditMoreSettingsInSettingsPageLater: "除此之外,還可以在「設定」頁面進行各種設定。之後請確認看看。" followUsers: "為了構築時間軸,試著追隨您感興趣的使用者吧。" - pushNotificationDescription: "啟用推送通知後,就可以在裝置上接收來自{name}的通知了。" + pushNotificationDescription: "啟用推送通知後,就可以在裝置上接收來自 {name} 的通知了。" initialAccountSettingCompleted: "初始設定完成了!" haveFun: "盡情享受{name}吧!" youCanContinueTutorial: "您可以繼續學習如何使用{name}(CherryPick),也可以就此打住,立即開始使用。" @@ -1611,6 +1683,10 @@ _serverSettings: fanoutTimelineDbFallback: "資料庫的回退" fanoutTimelineDbFallbackDescription: "若啟用,在時間軸沒有快取的情況下將執行回退處理以額外查詢資料庫。若停用,可以透過不執行回退處理來進一步減少伺服器的負荷,但會限制可取得的時間軸範圍。" reactionsBufferingDescription: "啟用時,可以顯著提高建立反應時的效能並減少資料庫的負載。 但是,Redis 記憶體使用量會增加。" + remoteNotesCleaning: "自動清除遠端發佈內容" + remoteNotesCleaning_description: "啟用後,系統會定期清理未被參照的舊遠端貼文,以抑制資料庫的膨脹。" + remoteNotesCleaningMaxProcessingDuration: "清理作業的最長持續時間" + remoteNotesCleaningExpiryDaysForEachNotes: "貼文最短保留天數" inquiryUrl: "聯絡表單網址" inquiryUrlDescription: "指定伺服器運營者的聯絡表單網址,或包含運營者聯絡資訊網頁的網址。" openRegistration: "允許建立帳戶" @@ -1618,6 +1694,26 @@ _serverSettings: thisSettingWillAutomaticallyOffWhenModeratorsInactive: "如果在一段期間內沒有偵測到任何審查員活動,此設定將自動關閉,以防止垃圾內容。" deliverSuspendedSoftware: "已停止發佈的軟體" deliverSuspendedSoftwareDescription: "由於脆弱性等原因,可以指定伺服器軟體的名稱與版本範圍來停止其發佈。這些版本資訊是由伺服器所提供,其可靠性無法保證。版本的指定可以使用 semver(語意化版本控制) 的範圍語法,但如果指定為 >= 2024.3.1,則像 2024.3.1-custom.0 這樣的自訂版本將不會被包含在內,因此建議使用 >= 2024.3.1-0 的方式來同時包含預發佈版本。" + singleUserMode: "單人模式" + singleUserMode_description: "如果只有自己使用此伺服器的話,啟用此模式將使效能最佳化。" + signToActivityPubGet: "簽署 GET 請求" + signToActivityPubGet_description: "通常應該啟用此功能。停用可能會改善聯邦通訊的問題,但反過來也可能會使某些伺服器無法通訊。" + proxyRemoteFiles: "代理提供遠端檔案" + proxyRemoteFiles_description: "啟用時,它會代理並提供遠端檔案。 這有助於產生影像縮圖和保護使用者隱私。" + allowExternalApRedirect: "允許透過 ActivityPub 查詢時進行重新導向" + allowExternalApRedirect_description: "啟用後,其他伺服器可以透過此伺服器查詢第三方的內容,但也可能導致內容遭到冒充的風險。" + userGeneratedContentsVisibilityForVisitor: "使用者建立的內容對訪客的公開範圍" + userGeneratedContentsVisibilityForVisitor_description: "這有助於防止一些問題的發生,例如未經適當審核的不適當遠端內容無意中透過您自己的伺服器發佈到網際網路上。" + userGeneratedContentsVisibilityForVisitor_description2: "包括伺服器接收到的遠端內容在內,無條件地將伺服器內所有內容公開到網際網路上是具有風險的。特別是對於不了解分散式架構特性的瀏覽者來說,他們可能會誤以為這些遠端內容是由該伺服器所創建的,因此需要特別留意。" + restartServerSetupWizardConfirm_title: "要重新執行伺服器的初始設定精靈嗎?" + restartServerSetupWizardConfirm_text: "當前的部分設定將會被重設。" + entrancePageStyle: "入口頁面的樣式" + showTimelineForVisitor: "顯示時間軸" + showActivitiesForVisitor: "顯示活動" + _userGeneratedContentsVisibilityForVisitor: + all: "全部公開\n" + localOnly: "僅公開本地內容,遠端內容則不公開\n" + none: "全部不公開" _accountMigration: moveFrom: "從其他帳戶遷移到這個帳戶" moveFromSub: "為另一個帳戶建立別名" @@ -1940,6 +2036,7 @@ _role: canManageAvatarDecorations: "管理頭像裝飾" driveCapacity: "雲端硬碟容量" maxFileSize: "可上傳的最大檔案大小" + maxFileSize_caption: "前端可能還有其他設定值,例如反向代理或 CDN。" alwaysMarkNsfw: "總是將檔案標記為NSFW" canUpdateBioMedia: "允許更新大頭貼和橫幅" pinMax: "置頂貼文的最大數量" @@ -1954,6 +2051,7 @@ _role: descriptionOfRateLimitFactor: "值越小限制越少,值越大限制越多。" canHideAds: "不顯示廣告" canSearchNotes: "可否搜尋貼文" + canSearchUsers: "可使用使用者搜尋功能" canUseTranslator: "使用翻譯功能" avatarDecorationLimit: "頭像可掛上的最大裝飾數量" canImportAntennas: "允許匯入天線" @@ -1962,6 +2060,12 @@ _role: canImportMuting: "允許匯入靜音名單" canImportUserLists: "允許匯入清單" chatAvailability: "允許聊天" + uploadableFileTypes: "可上傳的檔案類型" + uploadableFileTypes_caption: "請指定 MIME 類型。可以用換行區隔多個類型,也可以使用星號(*)作為萬用字元進行指定。(例如:image/*)\n" + uploadableFileTypes_caption2: "有些檔案可能無法判斷其類型。若要允許這類檔案,請在指定中加入 {x}。" + noteDraftLimit: "伺服器端可建立的貼文草稿數量上限\n" + scheduledNoteLimit: "同時建立的排定發布數量" + watermarkAvailable: "浮水印功能是否可用" _condition: roleAssignedTo: "手動指派角色完成" isLocal: "本地使用者" @@ -2187,6 +2291,7 @@ _theme: install: "安裝佈景主題" manage: "管理佈景主題" code: "佈景主題代碼" + copyThemeCode: "複製主題代碼" description: "描述" installed: "{name}已安裝" installedThemes: "已經安裝的佈景主題" @@ -2245,9 +2350,8 @@ _theme: buttonBg: "按鈕背景" buttonHoverBg: "按鈕背景 (漂浮)" inputBorder: "輸入框邊框" - driveFolderBg: "雲端硬碟文件夾背景" badge: "徽章" - messageBg: "私訊背景" + messageBg: "聊天的背景" fgHighlighted: "突顯文字" _sfx: note: "貼文" @@ -2287,6 +2391,7 @@ _time: minute: "分鐘" hour: "小時" day: "日" + month: "個月" _2fa: alreadyRegistered: "此裝置已被註冊過了" registerTOTP: "開始設定驗證應用程式" @@ -2416,6 +2521,7 @@ _auth: scopeUser: "以下列使用者身分操作" pleaseLogin: "必須登入以提供應用程式的存取權限。" byClickingYouWillBeRedirectedToThisUrl: "如果授予存取權限,就會自動導向到以下的網址" + alreadyAuthorized: "此應用程式已被授予存取權限。" _antennaSources: all: "全部貼文" homeTimeline: "來自已追隨使用者的貼文" @@ -2502,6 +2608,8 @@ _visibility: disableFederation: "停用聯邦" disableFederationDescription: "不發送到其他伺服器" _postForm: + quitInspiteOfThereAreUnuploadedFilesConfirm: "尚有未上傳的檔案,確定要放棄並關閉表單嗎?" + uploaderTip: "檔案尚未上傳。您可以從檔案選單中設定重新命名、裁切圖片、加上浮水印、是否壓縮等選項。檔案會在發布貼文時自動上傳。\n" replyPlaceholder: "回覆此貼文..." quotePlaceholder: "引用此貼文..." channelPlaceholder: "發佈到頻道" @@ -2652,6 +2760,8 @@ _notification: yourFollowRequestAccepted: "您的追隨請求已被核准" youWereInvitedToGroup: "{userName} 您有新的群組邀請" pollEnded: "問卷調查已產生結果" + scheduledNotePosted: "已排定發布貼文" + scheduledNotePostFailed: "排定發布貼文失敗了" newNote: "新的貼文" unreadAntennaNote: "天線 {name}" roleAssigned: "已授予角色" @@ -2681,6 +2791,8 @@ _notification: quote: "引用" reaction: "反應" pollEnded: "問卷調查結束" + scheduledNotePosted: "預約發佈成功" + scheduledNotePostFailed: "預約發佈失敗" receiveFollowRequest: "已收到追隨請求" followRequestAccepted: "追隨請求已接受" groupInvited: "加入社群邀請" @@ -2838,6 +2950,7 @@ _fileViewer: url: "URL" uploadedAt: "加入日期" attachedNotes: "含有附件的貼文" + usage: "使用情況" thisPageCanBeSeenFromTheAuthor: "本頁面僅限上傳了這個檔案的使用者可以檢視。" _externalResourceInstaller: title: "從外部網站安裝" @@ -2885,9 +2998,12 @@ _dataSaver: _avatar: title: "大頭貼" description: "停止顯示大頭貼的動畫。由於動畫圖片的檔案大小可能比普通圖片大,這可以進一步減少資料流量。" - _urlPreview: - title: "網址預覽縮圖" + _urlPreviewThumbnail: + title: "不顯示網址預覽縮圖" description: "將不再自動載入網址預覽縮圖。" + _disableUrlPreview: + title: "停用網址預覽" + description: "停用網址預覽功能。與單獨使用縮圖不同,這樣可以減少載入連結資訊本身。" _code: title: "程式碼突出顯示" description: "如果使用了程式碼突顯語法(如 MFC),則在點擊之前不會被載入。由於需要為對應的程式語言下載突顯定義檔案,因此關閉自動載入有助於減少資料流量。" @@ -2945,6 +3061,8 @@ _offlineScreen: _urlPreviewSetting: title: "URL 預覽設定" enable: "啟用 URL 預覽" + allowRedirect: "允許預覽目標的重新導向" + allowRedirectDescription: "設定當輸入的 URL 發生重新導向時,是否追蹤該重新導向並顯示預覽。若停用此功能,雖可節省伺服器資源,但將無法顯示重新導向後的內容。\n" timeout: "取得預覽的逾時時間 (ms)" timeoutDescription: "若取得預覽所需的時間超過這個值,則不會產生預覽。" maximumContentLength: "Content-Length 的最大値 (byte)" @@ -3018,10 +3136,6 @@ _customEmojisManager: uploadSettingDescription: "您可以在此畫面設定表情符號上傳時的操作。" directoryToCategoryLabel: "在「類別」欄位中輸入目錄名稱" directoryToCategoryCaption: "拖放目錄時,請在「類別」欄位中輸入目錄名稱。" - emojiInputAreaCaption: "以下列其中一種方式選擇您想要註冊的表情符號" - emojiInputAreaList1: "將圖片檔案或目錄拖放到此框中" - emojiInputAreaList2: "點擊此連結從電腦中選擇" - emojiInputAreaList3: "點擊此連結從雲端硬碟中選擇" confirmRegisterEmojisDescription: "將列表中顯示的表情符號登錄為新的自定表情符號。是否確定?(為避免過高負荷,每次操作最多可登錄{count}個表情符號)" confirmClearEmojisDescription: "放棄編輯內容並清除列表中顯示的表情符號。是否確定?" confirmUploadEmojisDescription: "將拖放的{count}個檔案上傳到雲端硬碟。是否執行此操作?" @@ -3089,6 +3203,7 @@ _bootErrors: otherOption1: "刪除用戶端設定和快取" otherOption2: "啟動簡易用戶端" otherOption3: "啟動修復工具" + otherOption4: "以安全模式啟動 CherryPick" _search: searchScopeAll: "全部" searchScopeLocal: "本地" @@ -3097,3 +3212,195 @@ _search: pleaseEnterServerHost: "請輸入伺服器的主機名稱" pleaseSelectUser: "請選擇使用者" serverHostPlaceholder: "例:cherrypick.example.com" +_serverSetupWizard: + installCompleted: "CherryPick 的安裝已經完成了!" + firstCreateAccount: "首先,請建立管理者帳戶。" + accountCreated: "已建立管理者帳戶!" + serverSetting: "伺服器設定" + youCanEasilyConfigureOptimalServerSettingsWithThisWizard: "利用這個精靈,可以簡單地最佳化伺服器的設定。" + settingsYouMakeHereCanBeChangedLater: "這裡的設定之後也可以進行更改。\n" + howWillYouUseMisskey: "您打算如何使用 CherryPick?\n" + _use: + single: "單人伺服器" + single_description: "作為自己專用的伺服器,單獨使用。\n" + single_youCanCreateMultipleAccounts: "即使作為單人伺服器運行,根據需要也可以創建多個帳戶。\n" + group: "群組伺服器\n" + group_description: "邀請可信賴的其他使用者,共同使用伺服器。\n" + open: "開放式伺服器" + open_description: "運營時接納不特定多數的使用者。" + openServerAdvice: "接納不特定多數使用者會帶來風險。為了能夠有效處理問題,建議建立完善的審查機制來進行運營。\n" + openServerAntiSpamAdvice: "為了防止自家伺服器成為垃圾郵件的跳板,必須啟用如 reCAPTCHA 等反機器人功能,並對安全性保持高度警覺。\n" + howManyUsersDoYouExpect: "您預計有多少人使用呢?\n" + _scale: + small: "100人以下(小規模)\n" + medium: "100人以上1000人以下(中規模)\n" + large: "1000人以上(大規模)\n" + largeScaleServerAdvice: "在大規模伺服器中,可能需要具備高階基礎設施知識,如負載平衡和資料庫複寫等。\n" + doYouConnectToFediverse: "您要連接到聯邦宇宙(Fediverse)嗎?\n" + doYouConnectToFediverse_description1: "連接到由分散型伺服器構成的網絡(聯邦宇宙)後,您可以與其他伺服器進行內容的互相交流。\n" + doYouConnectToFediverse_description2: "連接到聯邦宇宙被稱為「聯邦」。\n" + youCanConfigureMoreFederationSettingsLater: "您可以在稍後進行更高級的設定,例如指定可以聯繫的伺服器等。\n" + remoteContentsCleaning: "自動清理接收的內容" + remoteContentsCleaning_description: "進行聯邦後,會持續接收大量內容。啟用自動清理功能後,系統會自動從伺服器中刪除未被參照的過時內容,以節省儲存空間。" + adminInfo: "管理員資訊" + adminInfo_description: "設定用於接收查詢的管理者資訊。\n" + adminInfo_mustBeFilled: "當設置為開放伺服器或啟用聯邦時,必須填寫此資訊。\n" + followingSettingsAreRecommended: "建議使用下列設定" + applyTheseSettings: "套用此設定" + skipSettings: "跳過設定" + settingsCompleted: "設定完成!" + settingsCompleted_description: "辛苦了!準備已經完成,您可以立即開始使用伺服器了。\n" + settingsCompleted_description2: "詳細的伺服器設定可透過「控制臺」進行。" + donationRequest: "請求捐款" + _donationRequest: + text1: "CherryPick 是由志願者開發的免費軟體。" + text2: "為了能夠繼續開發,若您願意的話,請考慮進行捐款。\n" + text3: "也有提供支援者專屬的特典!\n" +_uploader: + editImage: "編輯圖片" + compressedToX: "壓縮為 {x}" + savedXPercent: "節省了 {x}%" + abortConfirm: "有些檔案尚未上傳,您要中止嗎?" + doneConfirm: "有些檔案尚未上傳,是否要完成上傳?" + maxFileSizeIsX: "可上傳的最大檔案大小為 {x}。" + allowedTypes: "可上傳的檔案類型。" + tip: "檔案尚未上傳。您可以在此對話框中進行上傳前的確認、重新命名、壓縮、裁切等操作。準備完成後,請點選「上傳」按鈕開始上傳。\n" +_clientPerformanceIssueTip: + title: "如果覺得電池消耗過快的話" + makeSureDisabledAdBlocker: "請將廣告阻擋器停用" + makeSureDisabledAdBlocker_description: "廣告阻擋器可能會影響效能。請確認作業系統功能、瀏覽器設定或擴充功能中是否啟用了廣告阻擋器。\n" + makeSureDisabledCustomCss: "請停用自訂 CSS" + makeSureDisabledCustomCss_description: "覆蓋樣式可能會影響效能。請確認是否啟用了自訂 CSS 或其他會覆蓋樣式的擴充功能。\n" + makeSureDisabledAddons: "請停用擴充功能" + makeSureDisabledAddons_description: "部分擴充功能可能會干擾用戶端的運作並影響效能。請嘗試停用瀏覽器的擴充功能,以確認是否能改善情況" +_clip: + tip: "摘錄是一項可以用來整理貼文的功能。" +_userLists: + tip: "您可以建立包含任意使用者的清單。建立後的清單可以作為時間軸顯示。\n" +watermark: "浮水印" +defaultPreset: "預設值" +_watermarkEditor: + tip: "可以在圖片中以浮水印加上出處等資訊。" + quitWithoutSaveConfirm: "不儲存就退出嗎?" + driveFileTypeWarn: "不支援此檔案" + driveFileTypeWarnDescription: "請選擇圖片檔案" + title: "編輯浮水印" + cover: "覆蓋整體" + repeat: "佈局" + preserveBoundingRect: "調整使其在旋轉時不會突出" + opacity: "透明度" + scale: "大小" + text: "文字" + qr: "二維條碼" + position: "位置" + margin: "邊界" + type: "類型" + image: "圖片" + advanced: "進階" + angle: "角度" + stripe: "條紋" + stripeWidth: "線條寬度" + stripeFrequency: "線條數量" + polkadot: "波卡圓點" + checker: "棋盤格" + polkadotMainDotOpacity: "主圓點的不透明度" + polkadotMainDotRadius: "主圓點的尺寸" + polkadotSubDotOpacity: "子圓點的不透明度" + polkadotSubDotRadius: "子圓點的尺寸" + polkadotSubDotDivisions: "子圓點的數量" + leaveBlankToAccountUrl: "若留空則使用帳戶的 URL" +_imageEffector: + title: "特效" + addEffect: "新增特效" + discardChangesConfirm: "捨棄更改並退出嗎?" + nothingToConfigure: "無可設定的項目" + _fxs: + chromaticAberration: "色差" + glitch: "異常雜訊效果" + mirror: "鏡像" + invert: "反轉色彩" + grayscale: "黑白" + blur: "模糊" + pixelate: "馬賽克" + colorAdjust: "色彩校正" + colorClamp: "壓縮色彩" + colorClampAdvanced: "壓縮色彩(進階)" + distort: "變形" + threshold: "閾值" + zoomLines: "速度線" + stripe: "條紋" + polkadot: "波卡圓點" + checker: "棋盤格" + blockNoise: "阻擋雜訊" + tearing: "撕裂" + fill: "填充" + _fxProps: + angle: "角度" + scale: "大小" + size: "大小" + radius: "半徑" + samples: "取樣數" + offset: "位置" + color: "顏色" + opacity: "透明度" + normalize: "正規化" + amount: "數量" + lightness: "亮度" + contrast: "對比度" + hue: "色相" + brightness: "亮度" + saturation: "彩度" + max: "最大值" + min: "最小值" + direction: "方向" + phase: "相位" + frequency: "頻率" + strength: "強度" + glitchChannelShift: "偏移" + seed: "種子值" + redComponent: "紅色成分" + greenComponent: "綠色成分" + blueComponent: "青色成分" + threshold: "閾值" + centerX: "X中心座標" + centerY: "Y中心座標" + zoomLinesSmoothing: "平滑化" + zoomLinesSmoothingDescription: "平滑化與集中線寬度設定不能同時使用。" + zoomLinesThreshold: "集中線的寬度" + zoomLinesMaskSize: "中心直徑" + zoomLinesBlack: "變成黑色" + circle: "圓形" +drafts: "草稿\n" +_drafts: + select: "選擇草槁" + cannotCreateDraftAnymore: "已超出可建立的草稿數量上限。\n" + cannotCreateDraft: "無法以此內容建立草稿。\n" + delete: "刪除草稿" + deleteAreYouSure: "確定要刪除草稿嗎?\n" + noDrafts: "沒有草稿。\n" + replyTo: "回覆給 {user}\n" + quoteOf: "引用自 {user} 的貼文\n" + postTo: "發佈到 {channel}\n" + saveToDraft: "儲存為草稿" + restoreFromDraft: "從草稿復原\n" + restore: "還原" + listDrafts: "草稿清單" + schedule: "排定發布" + listScheduledNotes: "排定發布列表" + cancelSchedule: "解除排定" +qr: "二維條碼" +_qr: + showTabTitle: "檢視" + readTabTitle: "讀取" + shareTitle: "{name} {acct}" + shareText: "請在聯邦宇宙追隨我吧!" + chooseCamera: "選擇相機" + cannotToggleFlash: "無法切換閃光燈" + turnOnFlash: "開啟閃光燈" + turnOffFlash: "關閉閃光燈" + startQr: "啟動條碼掃描器" + stopQr: "停止條碼掃描器" + noQrCodeFound: "找不到 QR code" + scanFile: "掃描在裝置上的影像" + raw: "文字" + mfm: "MFC" diff --git a/package.json b/package.json index 4830cafbdd..5613782caa 100644 --- a/package.json +++ b/package.json @@ -1,17 +1,18 @@ { "name": "cherrypick", - "version": "4.16.0-misaki.6", - "basedMisskeyVersion": "2025.5.0", + "version": "4.17.0-misaki", + "basedMisskeyVersion": "2025.10.2", "codename": "nasubi", "repository": { "type": "git", "url": "https://github.com/Misaki-Project/cherrypick.git" }, - "packageManager": "pnpm@10.10.0", + "packageManager": "pnpm@10.18.2", "workspaces": [ "packages/frontend-shared", "packages/frontend", "packages/frontend-embed", + "packages/icons-subsetter", "packages/backend", "packages/sw", "packages/cherrypick-js", @@ -27,6 +28,7 @@ "build-cherrypick-js-with-types": "pnpm build-pre && pnpm --filter backend... --filter=!cherrypick-js build && pnpm --filter backend generate-api-json --no-build && ncp packages/backend/built/api.json packages/cherrypick-js/generator/api.json && pnpm --filter cherrypick-js update-autogen-code && pnpm --filter cherrypick-js build && pnpm --filter cherrypick-js api", "start": "pnpm check:connect && cd packages/backend && node ./built/boot/entry.js", "start:test": "ncp ./.github/cherrypick/test.yml ./.config/test.yml && cd packages/backend && cross-env NODE_ENV=test node ./built/boot/entry.js", + "cli": "cd packages/backend && pnpm cli", "init": "pnpm migrate", "migrate": "cd packages/backend && pnpm migrate", "revert": "cd packages/backend && pnpm revert", @@ -36,7 +38,7 @@ "dev": "node scripts/dev.mjs", "lint": "pnpm -r lint", "biome-lint": "pnpm -r biome-lint", - "cy:open": "pnpm cypress open --browser --e2e --config-file=cypress.config.ts", + "cy:open": "pnpm cypress open --config-file=cypress.config.ts", "cy:run": "pnpm cypress run", "e2e": "pnpm start-server-and-test start:test http://localhost:61812 cy:run", "e2e-dev-container": "ncp ./.config/cypress-devcontainer.yml ./.config/test.yml && pnpm start-server-and-test start:test http://localhost:61812 cy:run", @@ -54,32 +56,32 @@ "lodash": "4.17.21" }, "dependencies": { - "cssnano": "7.0.6", - "esbuild": "0.25.3", - "execa": "9.5.2", + "cssnano": "7.1.1", + "esbuild": "0.25.10", + "execa": "9.6.0", "fast-glob": "3.3.3", - "glob": "11.0.2", - "ignore-walk": "7.0.0", + "glob": "11.0.3", + "ignore-walk": "8.0.0", "js-yaml": "4.1.0", - "postcss": "8.5.3", - "tar": "7.4.3", - "terser": "5.39.0", - "typescript": "5.8.3", - "vite": "^5.4.19" + "postcss": "8.5.6", + "tar": "7.5.1", + "terser": "5.44.0", + "typescript": "5.9.3" }, "devDependencies": { - "@biomejs/biome": "1.9.4", + "@biomejs/biome": "2.3.1", "@misskey-dev/eslint-plugin": "2.1.0", - "@types/node": "22.15.2", - "@typescript-eslint/eslint-plugin": "8.31.0", - "@typescript-eslint/parser": "8.31.0", - "cross-env": "7.0.3", - "cypress": "14.3.2", - "eslint": "9.25.1", - "globals": "16.0.0", + "@types/js-yaml": "4.0.9", + "@types/node": "24.9.1", + "@typescript-eslint/eslint-plugin": "8.46.1", + "@typescript-eslint/parser": "8.46.1", + "cross-env": "10.1.0", + "cypress": "15.4.0", + "eslint": "9.37.0", + "globals": "16.4.0", "ncp": "2.0.0", - "pnpm": "10.10.0", - "start-server-and-test": "2.0.11" + "pnpm": "10.18.2", + "start-server-and-test": "2.1.2" }, "optionalDependencies": { "@tensorflow/tfjs-core": "4.22.0" @@ -87,6 +89,9 @@ "pnpm": { "overrides": { "@aiscript-dev/aiscript-languageserver": "-" - } + }, + "ignoredBuiltDependencies": [ + "@sentry-internal/node-cpu-profiler" + ] } } diff --git a/packages/backend/assets/embed.js b/packages/backend/assets/embed.js index 55cf0dddc6..c75b165b7d 100644 --- a/packages/backend/assets/embed.js +++ b/packages/backend/assets/embed.js @@ -13,17 +13,17 @@ return; } - const id = el.dataset.misskeyEmbedId; + const id = el.dataset.cherrypickEmbedId; - if (event.data.type === 'misskey:embed:ready') { + if (event.data.type === 'cherrypick:embed:ready') { el.contentWindow?.postMessage({ - type: 'misskey:embedParent:registerIframeId', + type: 'cherrypick:embedParent:registerIframeId', payload: { iframeId: id, }, }, '*'); } - if (event.data.type === 'misskey:embed:changeHeight' && event.data.iframeId === id) { + if (event.data.type === 'cherrypick:embed:changeHeight' && event.data.iframeId === id) { el.style.height = event.data.payload.height + 'px'; } }); diff --git a/packages/backend/biome.json b/packages/backend/biome.json index ab73fd8682..dd157a36de 100644 --- a/packages/backend/biome.json +++ b/packages/backend/biome.json @@ -1,6 +1,5 @@ { - "$schema": "https://biomejs.dev/schemas/1.8.3/schema.json", - "organizeImports": { "enabled": true }, + "$schema": "https://biomejs.dev/schemas/2.3.1/schema.json", "linter": { "enabled": true, "rules": { @@ -8,10 +7,9 @@ "complexity": { "noBannedTypes": "error", "noExtraBooleanCast": "error", - "noMultipleSpacesInRegularExpressionLiterals": "error", + "noAdjacentSpacesInRegex": "error", "noUselessCatch": "error", - "noUselessTypeConstraint": "error", - "noWith": "error" + "noUselessTypeConstraint": "error" }, "correctness": { "noConstAssign": "error", @@ -21,7 +19,7 @@ "noGlobalObjectCalls": "error", "noInnerDeclarations": "off", "noInvalidConstructorSuper": "error", - "noNewSymbol": "error", + "noInvalidBuiltinInstantiation": "error", "noNonoctalDecimalEscape": "error", "noPrecisionLoss": "error", "noSelfAssign": "error", @@ -34,7 +32,6 @@ "noUnsafeOptionalChaining": "error", "noUnusedLabels": "error", "noUnusedVariables": "error", - "useArrayLiterals": "off", "useIsNan": "error", "useValidForDirection": "error", "useYield": "error" @@ -49,7 +46,6 @@ "level": "error", "options": { "deniedGlobals": ["__dirname", "__filename"] } }, - "noVar": "error", "useAsConstAssertion": "error" }, "suspicious": { @@ -78,36 +74,27 @@ "noShadowRestrictedNames": "error", "noUnsafeDeclarationMerging": "error", "noUnsafeNegation": "error", - "useGetterReturn": "error", - "useValidTypeof": "error" + "useGetterReturn": "error" } - }, - "ignore": [ - "**/node_modules", - "built", - "@types/**/*", - "migration" - ] + } }, + "javascript": { "globals": [] }, "overrides": [ { - "include": ["*.ts", "*.tsx", "*.mts", "*.cts"], + "includes": ["*.ts", "*.tsx", "*.mts", "*.cts"], "linter": { "rules": { "correctness": { "noConstAssign": "off", "noGlobalObjectCalls": "off", "noInvalidConstructorSuper": "off", - "noInvalidNewBuiltin": "off", - "noNewSymbol": "off", + "noInvalidBuiltinInstantiation": "off", "noSetterReturn": "off", "noUndeclaredVariables": "off", "noUnreachable": "off", "noUnreachableSuper": "off" }, "style": { - "noArguments": "error", - "noVar": "error", "useConst": "error" }, "suspicious": { diff --git a/packages/backend/eslint.config.js b/packages/backend/eslint.config.js index d15a703ba2..ba7c705def 100644 --- a/packages/backend/eslint.config.js +++ b/packages/backend/eslint.config.js @@ -25,6 +25,7 @@ export default [ }, }, rules: { + '@typescript-eslint/no-unused-vars': 'off', 'import/order': ['warn', { groups: [ 'builtin', diff --git a/packages/backend/jest.js b/packages/backend/jest.js index 0cb2c2ab77..61f6b00e85 100644 --- a/packages/backend/jest.js +++ b/packages/backend/jest.js @@ -10,11 +10,22 @@ const __dirname = path.dirname(__filename); const args = []; args.push(...[ - ...semver.satisfies(process.version, '^20.17.0 || ^22.0.0') ? ['--no-experimental-require-module'] : [], + ...semver.satisfies(process.version, '^20.17.0 || ^22.0.0 || ^24.10.0') ? ['--no-experimental-require-module'] : [], '--experimental-vm-modules', '--experimental-import-meta-resolve', path.join(__dirname, 'node_modules/jest/bin/jest.js'), ...process.argv.slice(2), ]); -child_process.spawn(process.execPath, args, { stdio: 'inherit' }); +const child = child_process.spawn(process.execPath, args, { stdio: 'inherit' }); +child.on('error', (err) => { + console.error('Failed to start Jest:', err); + process.exit(1); +}); +child.on('exit', (code, signal) => { + if (code === null) { + process.exit(128 + signal); + } else { + process.exit(code); + } +}); diff --git a/packages/backend/migration/1699437894737-scheduleNote.js b/packages/backend/migration/1699437894737-scheduleNote.js index 28dc290f25..f298da7037 100644 --- a/packages/backend/migration/1699437894737-scheduleNote.js +++ b/packages/backend/migration/1699437894737-scheduleNote.js @@ -9,7 +9,7 @@ export class ScheduleNote1699437894737 { async up(queryRunner) { await queryRunner.query(`CREATE TABLE "note_schedule" ("id" character varying(32) NOT NULL, "note" jsonb NOT NULL, "userId" character varying(260) NOT NULL, "scheduledAt" TIMESTAMP WITH TIME ZONE NOT NULL, CONSTRAINT "PK_3a1ae2db41988f4994268218436" PRIMARY KEY ("id"))`); await queryRunner.query(`CREATE INDEX "IDX_e798958c40009bf0cdef4f28b5" ON "note_schedule" ("userId") `); - } + } async down(queryRunner) { await queryRunner.query(`DROP TABLE "note_schedule"`); diff --git a/packages/backend/migration/1725344700039-NoteHistory.js b/packages/backend/migration/1725344700039-NoteHistory.js new file mode 100644 index 0000000000..fdb8ba9e60 --- /dev/null +++ b/packages/backend/migration/1725344700039-NoteHistory.js @@ -0,0 +1,24 @@ +/* + * SPDX-FileCopyrightText: noridev and cherrypick-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +export class NoteHistory1725344700039 { + name = 'NoteHistory1725344700039'; + + async up(queryRunner) { + await queryRunner.query('CREATE TYPE "public"."note_history_visibility_enum" AS ENUM(\'public\', \'home\', \'followers\', \'specified\')'); + await queryRunner.query('CREATE TABLE "note_history" ("id" character varying(32) NOT NULL, "noteId" character varying(32) NOT NULL, "updatedAt" TIMESTAMP WITH TIME ZONE NOT NULL, "userId" character varying(32) NOT NULL, "fileIds" character varying(32) array NOT NULL DEFAULT \'{}\', "attachedFileTypes" character varying(256) array NOT NULL DEFAULT \'{}\', "emojis" character varying(128) array NOT NULL DEFAULT \'{}\', "text" text, "visibility" "public"."note_history_visibility_enum" NOT NULL, "visibleUserIds" character varying(32) array NOT NULL DEFAULT \'{}\', CONSTRAINT "PK_b8603c8aa42b803c7687e52c2c0" PRIMARY KEY ("id"))'); + await queryRunner.query('CREATE INDEX "IDX_1e2492ba7582bf830b750a2962" ON "note_history" ("noteId") '); + await queryRunner.query('ALTER TABLE "note_history" ADD CONSTRAINT "FK_1e2492ba7582bf830b750a29627" FOREIGN KEY ("noteId") REFERENCES "note"("id") ON DELETE CASCADE ON UPDATE NO ACTION'); + await queryRunner.query('ALTER TABLE "note_history" ADD CONSTRAINT "FK_95a9f7f6939a5cd4ec5d84979af" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION'); + } + + async down(queryRunner) { + await queryRunner.query('ALTER TABLE "note_history" DROP CONSTRAINT "FK_95a9f7f6939a5cd4ec5d84979af"'); + await queryRunner.query('ALTER TABLE "note_history" DROP CONSTRAINT "FK_1e2492ba7582bf830b750a29627"'); + await queryRunner.query('DROP INDEX "public"."IDX_1e2492ba7582bf830b750a2962"'); + await queryRunner.query('DROP TABLE "note_history"'); + await queryRunner.query('DROP TYPE "public"."note_history_visibility_enum"'); + } +}; diff --git a/packages/backend/migration/1725517326637-NoteHistory-2.js b/packages/backend/migration/1725517326637-NoteHistory-2.js new file mode 100644 index 0000000000..d06026cb24 --- /dev/null +++ b/packages/backend/migration/1725517326637-NoteHistory-2.js @@ -0,0 +1,18 @@ +/* + * SPDX-FileCopyrightText: noridev and cherrypick-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +export class NoteHistory2_1725517326637 { + name = 'NoteHistory2_1725517326637'; + + async up(queryRunner) { + await queryRunner.query('ALTER TABLE "note_history" ADD COLUMN "createdAt" TIMESTAMP WITH TIME ZONE NULL'); + await queryRunner.query('UPDATE "note_history" set "createdAt" = \'1972.11.21\' where "createdAt" IS NULL'); + await queryRunner.query('ALTER TABLE "note_history" ALTER COLUMN "createdAt" set NOT NULL'); + } + + async down(queryRunner) { + await queryRunner.query('ALTER TABLE "note_history" DROP COLUMN "createdAt"'); + } +}; diff --git a/packages/backend/migration/1746330901644-visibleUserGeneratedContentsForNonLoggedInVisitors.js b/packages/backend/migration/1746330901644-visibleUserGeneratedContentsForNonLoggedInVisitors.js new file mode 100644 index 0000000000..115698a420 --- /dev/null +++ b/packages/backend/migration/1746330901644-visibleUserGeneratedContentsForNonLoggedInVisitors.js @@ -0,0 +1,16 @@ +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +export class VisibleUserGeneratedContentsForNonLoggedInVisitors1746330901644 { + name = 'VisibleUserGeneratedContentsForNonLoggedInVisitors1746330901644' + + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "meta" ADD "ugcVisibilityForVisitor" character varying(128) NOT NULL DEFAULT 'local'`); + } + + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "ugcVisibilityForVisitor"`); + } +} diff --git a/packages/backend/migration/1746361416550-UserIpsAddDnsNames.js b/packages/backend/migration/1746361416550-UserIpsAddDnsNames.js new file mode 100644 index 0000000000..5d5545c7b0 --- /dev/null +++ b/packages/backend/migration/1746361416550-UserIpsAddDnsNames.js @@ -0,0 +1,14 @@ +/* + * SPDX-FileCopyrightText: noridev and cherrypick-project + * SPDX-License-Identifier: AGPL-3.0-only + */ +export class UserIpsAddDnsNames1746361416550 { + name = 'UserIpsAddDnsNames1746361416550' + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "user_ip" ADD "dnsNames" character varying(512) array NOT NULL DEFAULT '{}'::varchar[]`); + } + + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "user_ip" DROP COLUMN "dnsNames"`); + } +} diff --git a/packages/backend/migration/1746422049376-singleUserMode.js b/packages/backend/migration/1746422049376-singleUserMode.js new file mode 100644 index 0000000000..9a79d46d5b --- /dev/null +++ b/packages/backend/migration/1746422049376-singleUserMode.js @@ -0,0 +1,16 @@ +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +export class SingleUserMode1746422049376 { + name = 'SingleUserMode1746422049376' + + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "meta" ADD "singleUserMode" boolean NOT NULL DEFAULT false`); + } + + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "singleUserMode"`); + } +} diff --git a/packages/backend/migration/1746949539915-migrateSomeConfigFileSettingsToMeta.js b/packages/backend/migration/1746949539915-migrateSomeConfigFileSettingsToMeta.js new file mode 100644 index 0000000000..3243f43b91 --- /dev/null +++ b/packages/backend/migration/1746949539915-migrateSomeConfigFileSettingsToMeta.js @@ -0,0 +1,24 @@ +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import {loadConfig} from "./js/migration-config.js"; + +export class MigrateSomeConfigFileSettingsToMeta1746949539915 { + name = 'MigrateSomeConfigFileSettingsToMeta1746949539915' + + async up(queryRunner) { + const config = loadConfig(); + // $1 cannot be used in ALTER TABLE queries + await queryRunner.query(`ALTER TABLE "meta" ADD "proxyRemoteFiles" boolean NOT NULL DEFAULT ${config.proxyRemoteFiles}`); + await queryRunner.query(`ALTER TABLE "meta" ADD "signToActivityPubGet" boolean NOT NULL DEFAULT ${config.signToActivityPubGet}`); + await queryRunner.query(`ALTER TABLE "meta" ADD "allowExternalApRedirect" boolean NOT NULL DEFAULT ${!config.disallowExternalApRedirect}`); + } + + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "allowExternalApRedirect"`); + await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "signToActivityPubGet"`); + await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "proxyRemoteFiles"`); + } +} diff --git a/packages/backend/migration/1748310233000-addUrlPreviewAllowRedirect.js b/packages/backend/migration/1748310233000-addUrlPreviewAllowRedirect.js new file mode 100644 index 0000000000..a895d0a941 --- /dev/null +++ b/packages/backend/migration/1748310233000-addUrlPreviewAllowRedirect.js @@ -0,0 +1,16 @@ +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +export class AddUrlPreviewAllowRedirect1748310233000 { + name = 'AddUrlPreviewAllowRedirect1748310233000' + + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "meta" ADD "urlPreviewAllowRedirect" boolean NOT NULL DEFAULT true`); + } + + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "urlPreviewAllowRedirect"`); + } +} diff --git a/packages/backend/migration/1750729939704-FixAvatarUrl.js b/packages/backend/migration/1750729939704-FixAvatarUrl.js new file mode 100644 index 0000000000..81a598136b --- /dev/null +++ b/packages/backend/migration/1750729939704-FixAvatarUrl.js @@ -0,0 +1,15 @@ +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ +export class FixAvatarUrl1750729939704 { + name = 'FixAvatarUrl1750729939704' + + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "user" ALTER COLUMN "avatarUrl" TYPE character varying(1024)`); + } + + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "user" ALTER COLUMN "avatarUrl" TYPE character varying(512)`); + } +} diff --git a/packages/backend/migration/1751828594933-AddDeliveryTargets.js b/packages/backend/migration/1751828594933-AddDeliveryTargets.js index b96eb14294..e30ec21e86 100644 --- a/packages/backend/migration/1751828594933-AddDeliveryTargets.js +++ b/packages/backend/migration/1751828594933-AddDeliveryTargets.js @@ -1,18 +1,23 @@ /* - * SPDX-FileCopyrightText: lqvp + * SPDX-FileCopyrightText: noridev and cherrypick-project * SPDX-License-Identifier: AGPL-3.0-only */ export class AddDeliveryTargets1751828594933 { - name = 'AddDeliveryTargets1751828594933'; + name = 'AddDeliveryTargets1751828594933'; - async up(queryRunner) { - await queryRunner.query(`ALTER TABLE "note" ADD "deliveryTargets" jsonb DEFAULT NULL`); - await queryRunner.query(`CREATE INDEX "IDX_note_deliveryTargets" ON "note" USING gin ("deliveryTargets")`); - } + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "note" ADD "deliveryTargets" jsonb DEFAULT NULL`); + await queryRunner.query(`ALTER TABLE "note_draft" ADD "deliveryTargets" jsonb DEFAULT NULL`); + await queryRunner.query(`CREATE INDEX "IDX_note_deliveryTargets" ON "note" USING gin ("deliveryTargets")`); + await queryRunner.query(`CREATE INDEX "IDX_note_draft_deliveryTargets" ON "note_draft" USING gin ("deliveryTargets")`); + } - async down(queryRunner) { - await queryRunner.query(`DROP INDEX "IDX_note_deliveryTargets"`); - await queryRunner.query(`ALTER TABLE "note" DROP COLUMN "deliveryTargets"`); - } + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "note" DROP COLUMN "deliveryTargets"`); + await queryRunner.query(`ALTER TABLE "note_draft" DROP COLUMN "deliveryTargets"`); + await queryRunner.query(`DROP INDEX "IDX_note_deliveryTargets"`); + await queryRunner.query(`DROP INDEX "IDX_note_draft_deliveryTargets"`); + + } } diff --git a/packages/backend/migration/1752502434151-no-action-on-draft-relation.js b/packages/backend/migration/1752502434151-no-action-on-draft-relation.js new file mode 100644 index 0000000000..e3c63b79c7 --- /dev/null +++ b/packages/backend/migration/1752502434151-no-action-on-draft-relation.js @@ -0,0 +1,24 @@ +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +export class NoActionOnDraftRelation1752502434151 { + name = 'NoActionOnDraftRelation1752502434151' + + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "note_draft" DROP CONSTRAINT "FK_NOTE_DRAFT_CHANNEL_ID"`); + await queryRunner.query(`ALTER TABLE "note_draft" DROP CONSTRAINT "FK_NOTE_DRAFT_USER_ID"`); + await queryRunner.query(`ALTER TABLE "note_draft" DROP CONSTRAINT "FK_NOTE_DRAFT_RENOTE_ID"`); + await queryRunner.query(`ALTER TABLE "note_draft" DROP CONSTRAINT "FK_NOTE_DRAFT_REPLY_ID"`); + await queryRunner.query(`ALTER TABLE "note_draft" ADD CONSTRAINT "FK_e4983f28b4b18b03491536052f5" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + } + + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "note_draft" DROP CONSTRAINT "FK_e4983f28b4b18b03491536052f5"`); + await queryRunner.query(`ALTER TABLE "note_draft" ADD CONSTRAINT "FK_NOTE_DRAFT_REPLY_ID" FOREIGN KEY ("replyId") REFERENCES "note"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "note_draft" ADD CONSTRAINT "FK_NOTE_DRAFT_RENOTE_ID" FOREIGN KEY ("renoteId") REFERENCES "note"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "note_draft" ADD CONSTRAINT "FK_NOTE_DRAFT_USER_ID" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "note_draft" ADD CONSTRAINT "FK_NOTE_DRAFT_CHANNEL_ID" FOREIGN KEY ("channelId") REFERENCES "channel"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + } +} diff --git a/packages/backend/migration/1752509043847-migration-cleanup.js b/packages/backend/migration/1752509043847-migration-cleanup.js new file mode 100644 index 0000000000..450e22af0c --- /dev/null +++ b/packages/backend/migration/1752509043847-migration-cleanup.js @@ -0,0 +1,79 @@ +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +export class MigrationCleanup1752509043847 { + name = 'MigrationCleanup1752509043847' + + async up(queryRunner) { + // 1745378064470-composite-note-index.js created a index ON "note" ("userId", "id" DESC) as IDX_724b311e6f883751f261ebe378 but should be named IDX_a6f649630f55af3888e5a42919 + await queryRunner.query(`ALTER INDEX "IDX_724b311e6f883751f261ebe378" RENAME TO "IDX_a6f649630f55af3888e5a42919"`); + + // 1713656541000-abuse-report-notification.js generated system_webhook with hand-written SQL with CURRENT_TIMESTAMP as the default value, but its representation in TypeORM is `now()` + // see https://github.com/typeorm/typeorm/blob/f351757a15b9d2bd9d4222c69dcfd2316f46b5d1/src/driver/postgres/PostgresDriver.ts#L1575 + await queryRunner.query(`ALTER TABLE "system_webhook" ALTER COLUMN "updatedAt" SET DEFAULT now()`); + + // 1702718871541-ffVisibility.js defined a enum type "user_profile_followersVisibility_enum" but it should be "user_profile_followersvisibility_enum" (lowercase 'v') in typeorm + await queryRunner.query(`ALTER TYPE "public"."user_profile_followersVisibility_enum" RENAME TO "user_profile_followersvisibility_enum"`); + + // 1713656541000-abuse-report-notification.js generated abuse_report_notification_recipient with hand-written SQL with CURRENT_TIMESTAMP as the default value, but its representation in TypeORM is `now()` + await queryRunner.query(`ALTER TABLE "abuse_report_notification_recipient" ALTER COLUMN "updatedAt" SET DEFAULT now()`); + + // 1690796169261-play-visibility.js added visibility column to flash table but it forgot to set NOT NULL constraint + await queryRunner.query(`ALTER TABLE "flash" ALTER COLUMN "visibility" SET NOT NULL`); + + // 1736686850345-createNoteDraft.js created note_draft with hand-written SQL but several types and comments are not correctly defined + await queryRunner.query(`CREATE TYPE "public"."note_draft_visibility_enum" AS ENUM('public', 'home', 'followers', 'specified')`); + await queryRunner.query(`ALTER TABLE "note_draft" ALTER COLUMN "id" SET DATA TYPE character varying(32)`); + await queryRunner.query(`ALTER TABLE "note_draft" ALTER COLUMN "replyId" SET DATA TYPE character varying(32)`); + await queryRunner.query(`ALTER TABLE "note_draft" ALTER COLUMN "renoteId" SET DATA TYPE character varying(32)`); + await queryRunner.query(`ALTER TABLE "note_draft" ALTER COLUMN "userId" SET DATA TYPE character varying(32)`); + await queryRunner.query(`ALTER TABLE "note_draft" ALTER COLUMN "channelId" SET DATA TYPE character varying(32)`); + await queryRunner.query(`ALTER TABLE "note_draft" ALTER COLUMN "fileIds" SET DATA TYPE character varying(32) array`); + await queryRunner.query(`ALTER TABLE "note_draft" ALTER COLUMN "visibleUserIds" SET DATA TYPE character varying(32) array`); + await queryRunner.query(`ALTER TABLE "note_draft" ALTER COLUMN "visibility" SET DATA TYPE "public"."note_draft_visibility_enum" USING visibility::note_draft_visibility_enum`); + await queryRunner.query(`COMMENT ON COLUMN "note_draft"."replyId" IS 'The ID of reply target.'`); + await queryRunner.query(`COMMENT ON COLUMN "note_draft"."renoteId" IS 'The ID of renote target.'`); + await queryRunner.query(`COMMENT ON COLUMN "note_draft"."userId" IS 'The ID of author.'`); + await queryRunner.query(`COMMENT ON COLUMN "note_draft"."channelId" IS 'The ID of source channel.'`); + await queryRunner.query(`ALTER TABLE "note_draft" ALTER COLUMN "fileIds" SET NOT NULL`); + await queryRunner.query(`ALTER TABLE "note_draft" ALTER COLUMN "hasPoll" SET NOT NULL`); + await queryRunner.query(`ALTER TABLE "note_draft" ALTER COLUMN "pollChoices" SET NOT NULL`); + await queryRunner.query(`ALTER TABLE "note_draft" ALTER COLUMN "pollMultiple" SET NOT NULL`); + await queryRunner.query(`ALTER TABLE "note_draft" ALTER COLUMN "localOnly" SET NOT NULL`); + await queryRunner.query(`ALTER TABLE "note_draft" ALTER COLUMN "visibleUserIds" SET NOT NULL`); + } + + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "note_draft" ALTER COLUMN "visibleUserIds" DROP NOT NULL`); + await queryRunner.query(`ALTER TABLE "note_draft" ALTER COLUMN "localOnly" DROP NOT NULL`); + await queryRunner.query(`ALTER TABLE "note_draft" ALTER COLUMN "pollMultiple" DROP NOT NULL`); + await queryRunner.query(`ALTER TABLE "note_draft" ALTER COLUMN "pollChoices" DROP NOT NULL`); + await queryRunner.query(`ALTER TABLE "note_draft" ALTER COLUMN "hasPoll" DROP NOT NULL`); + await queryRunner.query(`ALTER TABLE "note_draft" ALTER COLUMN "fileIds" DROP NOT NULL`); + await queryRunner.query(`COMMENT ON COLUMN "note_draft"."channelId" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "note_draft"."userId" IS 'The ID of author.'`); + await queryRunner.query(`COMMENT ON COLUMN "note_draft"."renoteId" IS NULL`); + await queryRunner.query(`COMMENT ON COLUMN "note_draft"."replyId" IS NULL`); + await queryRunner.query(`ALTER TABLE "note_draft" ALTER COLUMN "visibility" SET DATA TYPE varchar`); + await queryRunner.query(`ALTER TABLE "note_draft" ALTER COLUMN "visibleUserIds" SET DATA TYPE varchar[]`); + await queryRunner.query(`ALTER TABLE "note_draft" ALTER COLUMN "fileIds" SET DATA TYPE varchar[]`); + await queryRunner.query(`ALTER TABLE "note_draft" ALTER COLUMN "channelId" SET DATA TYPE varchar`); + await queryRunner.query(`ALTER TABLE "note_draft" ALTER COLUMN "userId" SET DATA TYPE varchar`); + await queryRunner.query(`ALTER TABLE "note_draft" ALTER COLUMN "renoteId" SET DATA TYPE varchar`); + await queryRunner.query(`ALTER TABLE "note_draft" ALTER COLUMN "replyId" SET DATA TYPE varchar`); + await queryRunner.query(`ALTER TABLE "note_draft" ALTER COLUMN "id" SET DATA TYPE varchar`); + await queryRunner.query(`DROP TYPE "public"."note_draft_visibility_enum"`); + + await queryRunner.query(`ALTER TABLE "flash" ALTER COLUMN "visibility" DROP NOT NULL`); + + await queryRunner.query(`ALTER TABLE "abuse_report_notification_recipient" ALTER COLUMN "updatedAt" SET DEFAULT CURRENT_TIMESTAMP`); + + await queryRunner.query(`ALTER TYPE "public"."user_profile_followersvisibility_enum" RENAME TO "user_profile_followersVisibility_enum"`); + + await queryRunner.query(`ALTER TABLE "system_webhook" ALTER COLUMN "updatedAt" SET DEFAULT CURRENT_TIMESTAMP`); + + await queryRunner.query(`ALTER INDEX "IDX_a6f649630f55af3888e5a42919" RENAME TO "IDX_724b311e6f883751f261ebe378"`); + } +} diff --git a/packages/backend/migration/1753863104203-remoteNotesCleaning.js b/packages/backend/migration/1753863104203-remoteNotesCleaning.js new file mode 100644 index 0000000000..8250d8d0df --- /dev/null +++ b/packages/backend/migration/1753863104203-remoteNotesCleaning.js @@ -0,0 +1,20 @@ +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +export class RemoteNotesCleaning1753863104203 { + name = 'RemoteNotesCleaning1753863104203' + + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "meta" ADD "enableRemoteNotesCleaning" boolean NOT NULL DEFAULT false`); + await queryRunner.query('ALTER TABLE "meta" ADD "remoteNotesCleaningMaxProcessingDurationInMinutes" integer NOT NULL DEFAULT \'60\''); + await queryRunner.query('ALTER TABLE "meta" ADD "remoteNotesCleaningExpiryDaysForEachNotes" integer NOT NULL DEFAULT \'90\''); + } + + async down(queryRunner) { + await queryRunner.query('ALTER TABLE "meta" DROP COLUMN "remoteNotesCleaningExpiryDaysForEachNotes"'); + await queryRunner.query('ALTER TABLE "meta" DROP COLUMN "remoteNotesCleaningMaxProcessingDurationInMinutes"'); + await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "enableRemoteNotesCleaning"`); + } +} diff --git a/packages/backend/migration/1753868431598-remove_note_constraints.js b/packages/backend/migration/1753868431598-remove_note_constraints.js new file mode 100644 index 0000000000..29540cf9de --- /dev/null +++ b/packages/backend/migration/1753868431598-remove_note_constraints.js @@ -0,0 +1,18 @@ +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +export class RemoveNoteConstraints1753868431598 { + name = 'RemoveNoteConstraints1753868431598' + + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "note" DROP CONSTRAINT "FK_52ccc804d7c69037d558bac4c96"`); + await queryRunner.query(`ALTER TABLE "note" DROP CONSTRAINT "FK_17cb3553c700a4985dff5a30ff5"`); + } + + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "note" ADD CONSTRAINT "FK_17cb3553c700a4985dff5a30ff5" FOREIGN KEY ("replyId") REFERENCES "note"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "note" ADD CONSTRAINT "FK_52ccc804d7c69037d558bac4c96" FOREIGN KEY ("renoteId") REFERENCES "note"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + } +} diff --git a/packages/backend/migration/1754019326356-tweakDefaultFederationSettings.js b/packages/backend/migration/1754019326356-tweakDefaultFederationSettings.js new file mode 100644 index 0000000000..1051b18e1b --- /dev/null +++ b/packages/backend/migration/1754019326356-tweakDefaultFederationSettings.js @@ -0,0 +1,16 @@ +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +export class TweakDefaultFederationSettings1754019326356 { + name = 'TweakDefaultFederationSettings1754019326356' + + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "meta" ALTER COLUMN "federation" SET DEFAULT 'none'`); + } + + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "meta" ALTER COLUMN "federation" SET DEFAULT 'all'`); + } +} diff --git a/packages/backend/migration/1755168347001-PageCountInNote.js b/packages/backend/migration/1755168347001-PageCountInNote.js new file mode 100644 index 0000000000..9f1894ab2f --- /dev/null +++ b/packages/backend/migration/1755168347001-PageCountInNote.js @@ -0,0 +1,58 @@ +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +export class PageCountInNote1755168347001 { + name = 'PageCountInNote1755168347001' + + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "note" ADD "pageCount" smallint NOT NULL DEFAULT '0'`); + + // Update existing notes + // block_list CTE collects all page blocks on the pages including child blocks in the section blocks. + // The clipped_notes CTE counts how many distinct pages each note block is referenced in. + // Finally, we update the note table with the count of pages for each referenced note. + await queryRunner.query(` + WITH RECURSIVE block_list AS ( + ( + SELECT + page.id as page_id, + block as block + FROM page + CROSS JOIN LATERAL jsonb_array_elements(page.content) block + WHERE block->>'type' = 'note' OR block->>'type' = 'section' + ) + UNION ALL + ( + SELECT + block_list.page_id, + child_block AS block + FROM LATERAL ( + SELECT page_id, block + FROM block_list + WHERE block_list.block->>'type' = 'section' + ) block_list + CROSS JOIN LATERAL jsonb_array_elements(block_list.block->'children') child_block + WHERE child_block->>'type' = 'note' OR child_block->>'type' = 'section' + ) + ), + clipped_notes AS ( + SELECT + (block->>'note') AS note_id, + COUNT(distinct block_list.page_id) AS count + FROM block_list + WHERE block_list.block->>'type' = 'note' + GROUP BY block->>'note' + ) + UPDATE note + SET "pageCount" = clipped_notes.count + FROM clipped_notes + WHERE note.id = clipped_notes.note_id; + `); + } + + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "note" DROP COLUMN "pageCount"`); + } +} diff --git a/packages/backend/migration/1755574887486-entrancePageStyle.js b/packages/backend/migration/1755574887486-entrancePageStyle.js new file mode 100644 index 0000000000..ba40764b94 --- /dev/null +++ b/packages/backend/migration/1755574887486-entrancePageStyle.js @@ -0,0 +1,16 @@ +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +export class EntrancePageStyle1755574887486 { + name = 'EntrancePageStyle1755574887486' + + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "meta" ADD "clientOptions" jsonb NOT NULL DEFAULT '{}'`); + } + + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "clientOptions"`); + } +} diff --git a/packages/backend/migration/1756062689648-NonCascadingPageEyeCatching.js b/packages/backend/migration/1756062689648-NonCascadingPageEyeCatching.js new file mode 100644 index 0000000000..8554cc4304 --- /dev/null +++ b/packages/backend/migration/1756062689648-NonCascadingPageEyeCatching.js @@ -0,0 +1,18 @@ +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +export class NonCascadingPageEyeCatching1756062689648 { + name = 'NonCascadingPageEyeCatching1756062689648' + + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "page" DROP CONSTRAINT "FK_a9ca79ad939bf06066b81c9d3aa"`); + await queryRunner.query(`ALTER TABLE "page" ADD CONSTRAINT "FK_a9ca79ad939bf06066b81c9d3aa" FOREIGN KEY ("eyeCatchingImageId") REFERENCES "drive_file"("id") ON DELETE SET NULL ON UPDATE NO ACTION`); + } + + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "page" DROP CONSTRAINT "FK_a9ca79ad939bf06066b81c9d3aa"`); + await queryRunner.query(`ALTER TABLE "page" ADD CONSTRAINT "FK_a9ca79ad939bf06066b81c9d3aa" FOREIGN KEY ("eyeCatchingImageId") REFERENCES "drive_file"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + } +} diff --git a/packages/backend/migration/1757823175259-sensitive-ad.js b/packages/backend/migration/1757823175259-sensitive-ad.js new file mode 100644 index 0000000000..46f0f270ab --- /dev/null +++ b/packages/backend/migration/1757823175259-sensitive-ad.js @@ -0,0 +1,16 @@ +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +export class SensitiveAd1757823175259 { + name = 'SensitiveAd1757823175259' + + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "ad" ADD "isSensitive" boolean NOT NULL DEFAULT false`); + } + + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "ad" DROP COLUMN "isSensitive"`); + } +} diff --git a/packages/backend/migration/1758677617888-scheduled-post.js b/packages/backend/migration/1758677617888-scheduled-post.js new file mode 100644 index 0000000000..b31313d9db --- /dev/null +++ b/packages/backend/migration/1758677617888-scheduled-post.js @@ -0,0 +1,24 @@ +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +export class ScheduledPost1758677617888 { + name = 'ScheduledPost1758677617888' + + /** + * @param {QueryRunner} queryRunner + */ + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "note_draft" ADD "scheduledAt" TIMESTAMP WITH TIME ZONE`); + await queryRunner.query(`ALTER TABLE "note_draft" ADD "isActuallyScheduled" boolean NOT NULL DEFAULT false`); + } + + /** + * @param {QueryRunner} queryRunner + */ + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "note_draft" DROP COLUMN "isActuallyScheduled"`); + await queryRunner.query(`ALTER TABLE "note_draft" DROP COLUMN "scheduledAt"`); + } +} diff --git a/packages/backend/migration/1760607435831-RoleBadgesRemoteUsers.js b/packages/backend/migration/1760607435831-RoleBadgesRemoteUsers.js new file mode 100644 index 0000000000..483d35a91b --- /dev/null +++ b/packages/backend/migration/1760607435831-RoleBadgesRemoteUsers.js @@ -0,0 +1,16 @@ +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +export class RoleBadgesRemoteUsers1760607435831 { + name = 'RoleBadgesRemoteUsers1760607435831' + + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "meta" ADD "showRoleBadgesOfRemoteUsers" boolean NOT NULL DEFAULT false`); + } + + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "showRoleBadgesOfRemoteUsers"`); + } +} diff --git a/packages/backend/migration/1760790899857-unnecessary-null-default.js b/packages/backend/migration/1760790899857-unnecessary-null-default.js new file mode 100644 index 0000000000..d34758315f --- /dev/null +++ b/packages/backend/migration/1760790899857-unnecessary-null-default.js @@ -0,0 +1,26 @@ +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +export class UnnecessaryNullDefault1760790899857 { + name = 'UnnecessaryNullDefault1760790899857' + + /** + * @param {QueryRunner} queryRunner + */ + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "abuse_report_notification_recipient" ALTER COLUMN "userId" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "abuse_report_notification_recipient" ALTER COLUMN "systemWebhookId" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "meta" ALTER COLUMN "urlPreviewUserAgent" DROP DEFAULT`); + } + + /** + * @param {QueryRunner} queryRunner + */ + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "meta" ALTER COLUMN "urlPreviewUserAgent" SET DEFAULT NULL`); + await queryRunner.query(`ALTER TABLE "abuse_report_notification_recipient" ALTER COLUMN "systemWebhookId" SET DEFAULT NULL`); + await queryRunner.query(`ALTER TABLE "abuse_report_notification_recipient" ALTER COLUMN "userId" SET DEFAULT NULL`); + } +} diff --git a/packages/backend/migration/1760797772000-dropScheduleNote.js b/packages/backend/migration/1760797772000-dropScheduleNote.js new file mode 100644 index 0000000000..00d4c9f045 --- /dev/null +++ b/packages/backend/migration/1760797772000-dropScheduleNote.js @@ -0,0 +1,12 @@ +/* + * SPDX-FileCopyrightText: noridev and cherrypick-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +export class DropScheduleNote1760797772000 { + name = 'DropScheduleNote1760797772000' + + async up(queryRunner) { + await queryRunner.query(`DROP TABLE "note_schedule"`); + } +} diff --git a/packages/backend/migration/1761287521000-AddAutoDeleteNoteSettings.js b/packages/backend/migration/1761287521000-AddAutoDeleteNoteSettings.js new file mode 100644 index 0000000000..61947b44ae --- /dev/null +++ b/packages/backend/migration/1761287521000-AddAutoDeleteNoteSettings.js @@ -0,0 +1,18 @@ +/* + * SPDX-FileCopyrightText: noridev and cherrypick-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +export class AddAutoDeleteNoteSettings1761287521000 { + name = 'AddAutoDeleteNoteSettings1761287521000' + + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "user" ADD "autoDeleteNotesAfterDays" integer`); + await queryRunner.query(`ALTER TABLE "user" ADD "autoDeleteKeepFavorites" boolean NOT NULL DEFAULT true`); + } + + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "user" DROP COLUMN "autoDeleteKeepFavorites"`); + await queryRunner.query(`ALTER TABLE "user" DROP COLUMN "autoDeleteNotesAfterDays"`); + } +} diff --git a/packages/backend/migration/1761583921158-RemoveNoteEditHistory.js b/packages/backend/migration/1761583921158-RemoveNoteEditHistory.js new file mode 100644 index 0000000000..1c0a891c64 --- /dev/null +++ b/packages/backend/migration/1761583921158-RemoveNoteEditHistory.js @@ -0,0 +1,16 @@ +/* + * SPDX-FileCopyrightText: noridev and cherrypick-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +export class RemoveNoteEditHistory1761583921158 { + name = 'RemoveNoteEditHistory1761583921158'; + + async up(queryRunner) { + await queryRunner.query('ALTER TABLE "note" DROP COLUMN "noteEditHistory"'); + } + + async down(queryRunner) { + await queryRunner.query('ALTER TABLE "note" ADD "noteEditHistory" character varying(3000) array NOT NULL DEFAULT \'{}\''); + } +} diff --git a/packages/backend/migration/1761584610791-NoteHistoryAddCwPollEvent.js b/packages/backend/migration/1761584610791-NoteHistoryAddCwPollEvent.js new file mode 100644 index 0000000000..87e00037f5 --- /dev/null +++ b/packages/backend/migration/1761584610791-NoteHistoryAddCwPollEvent.js @@ -0,0 +1,20 @@ +/* + * SPDX-FileCopyrightText: noridev and cherrypick-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +export class NoteHistoryAddCwPollEvent1761584610791 { + name = 'NoteHistoryAddCwPollEvent1761584610791'; + + async up(queryRunner) { + await queryRunner.query('ALTER TABLE "note_history" ADD "cw" character varying(512)'); + await queryRunner.query('ALTER TABLE "note_history" ADD "poll" jsonb'); + await queryRunner.query('ALTER TABLE "note_history" ADD "event" jsonb'); + } + + async down(queryRunner) { + await queryRunner.query('ALTER TABLE "note_history" DROP COLUMN "event"'); + await queryRunner.query('ALTER TABLE "note_history" DROP COLUMN "poll"'); + await queryRunner.query('ALTER TABLE "note_history" DROP COLUMN "cw"'); + } +} diff --git a/packages/backend/migration/1761595707656-chart-federation-software.js b/packages/backend/migration/1761595707656-chart-federation-software.js new file mode 100644 index 0000000000..e8b706b75b --- /dev/null +++ b/packages/backend/migration/1761595707656-chart-federation-software.js @@ -0,0 +1,19 @@ +/* + * SPDX-FileCopyrightText: noridev and cherrypick-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +export class chartFederationSoftware1761595707656 { + name = 'chartFederationSoftware1761595707656' + + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "__chart__federation" ADD "___software" smallint NOT NULL DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE "__chart_day__federation" ADD "___software" smallint NOT NULL DEFAULT '0'`); + } + + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "__chart_day__federation" DROP COLUMN "___software"`); + await queryRunner.query(`ALTER TABLE "__chart__federation" DROP COLUMN "___software"`); + } +} + diff --git a/packages/backend/migration/1762351977309-AddChatMessageEmojis.js b/packages/backend/migration/1762351977309-AddChatMessageEmojis.js new file mode 100644 index 0000000000..bd4b13dda6 --- /dev/null +++ b/packages/backend/migration/1762351977309-AddChatMessageEmojis.js @@ -0,0 +1,16 @@ +/* + * SPDX-FileCopyrightText: noridev and cherrypick-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +export class AddChatMessageEmojis1762351977309 { + name = 'AddChatMessageEmojis1762351977309' + + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "chat_message" ADD "emojis" character varying(128) array NOT NULL DEFAULT '{}'`); + } + + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "chat_message" DROP COLUMN "emojis"`); + } +} diff --git a/packages/backend/migration/1762447519068-AddUserCanChat.js b/packages/backend/migration/1762447519068-AddUserCanChat.js new file mode 100644 index 0000000000..4384b6c62e --- /dev/null +++ b/packages/backend/migration/1762447519068-AddUserCanChat.js @@ -0,0 +1,16 @@ +/* + * SPDX-FileCopyrightText: noridev and cherrypick-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +export class AddUserCanChat1762447519068 { + name = 'AddUserCanChat1762447519068' + + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "user" ADD "canChat" boolean DEFAULT true`); + } + + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "user" DROP COLUMN "canChat"`); + } +} diff --git a/packages/backend/migration/1762797644990-AddInstanceQuarantineLimited.js b/packages/backend/migration/1762797644990-AddInstanceQuarantineLimited.js new file mode 100644 index 0000000000..7bf7c0c12a --- /dev/null +++ b/packages/backend/migration/1762797644990-AddInstanceQuarantineLimited.js @@ -0,0 +1,17 @@ +/* + * SPDX-FileCopyrightText: noridev and cherrypick-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +export class AddInstanceQuarantineLimited1762797644990 { + name = 'AddInstanceQuarantineLimited1762797644990' + + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "instance" ADD "quarantineLimited" boolean NOT NULL DEFAULT false`); + } + + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "instance" DROP COLUMN "quarantineLimited"`); + } +} + diff --git a/packages/backend/migration/1766922191000-AddDeliveryTargets-misaki.js b/packages/backend/migration/1766922191000-AddDeliveryTargets-misaki.js new file mode 100644 index 0000000000..37120cf896 --- /dev/null +++ b/packages/backend/migration/1766922191000-AddDeliveryTargets-misaki.js @@ -0,0 +1,19 @@ +/* + * SPDX-FileCopyrightText: noridev and cherrypick-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +export class AddDeliveryTargets1766922191000 { + name = 'AddDeliveryTargets1766922191000'; + + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "note_draft" ADD "deliveryTargets" jsonb DEFAULT NULL`); + await queryRunner.query(`CREATE INDEX "IDX_note_draft_deliveryTargets" ON "note_draft" USING gin ("deliveryTargets")`); + } + + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "note_draft" DROP COLUMN "deliveryTargets"`); + await queryRunner.query(`DROP INDEX "IDX_note_draft_deliveryTargets"`); + + } +} diff --git a/packages/backend/migration/js/migration-config.js b/packages/backend/migration/js/migration-config.js index 93cac7795f..0b167d277e 100644 --- a/packages/backend/migration/js/migration-config.js +++ b/packages/backend/migration/js/migration-config.js @@ -3,6 +3,29 @@ * SPDX-License-Identifier: AGPL-3.0-only */ +import { path as configYamlPath } from '../../built/config.js'; +import * as yaml from 'js-yaml'; +import fs from "node:fs"; + export function isConcurrentIndexMigrationEnabled() { return process.env.CHERRYPICK_MIGRATION_CREATE_INDEX_CONCURRENTLY === '1'; } + +let loadedConfigCache = undefined; + +function loadConfigInternal() { + const config = yaml.load(fs.readFileSync(configYamlPath, 'utf-8')); + + return { + disallowExternalApRedirect: Boolean(config.disallowExternalApRedirect ?? false), + proxyRemoteFiles: Boolean(config.proxyRemoteFiles ?? false), + signToActivityPubGet: Boolean(config.signToActivityPubGet ?? true), + } +} + +export function loadConfig() { + if (loadedConfigCache === undefined) { + loadedConfigCache = loadConfigInternal(); + } + return loadedConfigCache; +} diff --git a/packages/backend/package.json b/packages/backend/package.json index 543a450925..72fa3f5048 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -4,13 +4,14 @@ "private": true, "type": "module", "engines": { - "node": "^20.10.0 || ^22.0.0" + "node": "^22.15.0 || ^24.10.0" }, "scripts": { "start": "node ./built/boot/entry.js", "start:test": "cross-env NODE_ENV=test node ./built/boot/entry.js", "migrate": "pnpm typeorm migration:run -d ormconfig.js", "revert": "pnpm typeorm migration:revert -d ormconfig.js", + "cli": "node ./built/boot/cli.js", "check:connect": "node ./scripts/check_connect.js", "build": "swc src -d built -D --strip-leading-paths", "build:test": "swc test-server -d built-test -D --config-file test-server/.swcrc --strip-leading-paths", @@ -33,6 +34,7 @@ "test:fed": "pnpm jest:fed", "test-and-coverage": "pnpm jest-and-coverage", "test-and-coverage:e2e": "pnpm build && pnpm build:test && pnpm jest-and-coverage:e2e", + "check-migrations": "node scripts/check_migrations_clean.js", "generate-api-json": "node ./scripts/generate_api_json.js", "biome-lint": "pnpm typecheck && pnpm biome lint", "format": "pnpm biome format", @@ -41,17 +43,17 @@ }, "optionalDependencies": { "@swc/core-android-arm64": "1.3.11", - "@swc/core-darwin-arm64": "1.11.22", - "@swc/core-darwin-x64": "1.11.22", + "@swc/core-darwin-arm64": "1.13.20", + "@swc/core-darwin-x64": "1.13.20", "@swc/core-freebsd-x64": "1.3.11", - "@swc/core-linux-arm-gnueabihf": "1.11.22", - "@swc/core-linux-arm64-gnu": "1.11.22", - "@swc/core-linux-arm64-musl": "1.11.22", - "@swc/core-linux-x64-gnu": "1.11.22", - "@swc/core-linux-x64-musl": "1.11.22", - "@swc/core-win32-arm64-msvc": "1.11.22", - "@swc/core-win32-ia32-msvc": "1.11.22", - "@swc/core-win32-x64-msvc": "1.11.22", + "@swc/core-linux-arm-gnueabihf": "1.13.20", + "@swc/core-linux-arm64-gnu": "1.13.20", + "@swc/core-linux-arm64-musl": "1.13.20", + "@swc/core-linux-x64-gnu": "1.13.20", + "@swc/core-linux-x64-musl": "1.13.20", + "@swc/core-win32-arm64-msvc": "1.13.20", + "@swc/core-win32-ia32-msvc": "1.13.20", + "@swc/core-win32-x64-msvc": "1.13.20", "@tensorflow/tfjs": "4.22.0", "@tensorflow/tfjs-node": "4.22.0", "bufferutil": "4.0.9", @@ -71,34 +73,34 @@ "utf-8-validate": "6.0.5" }, "dependencies": { - "@aws-sdk/client-s3": "3.797.0", - "@aws-sdk/lib-storage": "3.797.0", - "@discordapp/twemoji": "15.1.0", - "@fastify/accepts": "5.0.2", + "@aws-sdk/client-s3": "3.908.0", + "@aws-sdk/lib-storage": "3.908.0", + "@discordapp/twemoji": "16.0.1", + "@fastify/accepts": "5.0.3", "@fastify/cookie": "11.0.2", "@fastify/cors": "10.1.0", "@fastify/express": "4.0.2", "@fastify/http-proxy": "10.0.2", - "@fastify/multipart": "9.0.3", - "@fastify/static": "8.1.1", + "@fastify/multipart": "9.2.1", + "@fastify/static": "8.2.0", "@fastify/view": "10.0.2", "@google-cloud/logging": "^10.5.0", "@google-cloud/translate": "^7.2.1", "@misskey-dev/sharp-read-bmp": "1.2.0", - "@misskey-dev/summaly": "5.2.1", - "@napi-rs/canvas": "0.1.69", - "@nestjs/common": "11.1.0", - "@nestjs/core": "11.1.0", - "@nestjs/testing": "11.1.0", + "@misskey-dev/summaly": "5.2.4", + "@napi-rs/canvas": "0.1.80", + "@nestjs/common": "11.1.6", + "@nestjs/core": "11.1.6", + "@nestjs/testing": "11.1.6", "@peertube/http-signature": "1.7.0", - "@sentry/node": "8.55.0", - "@sentry/profiling-node": "8.55.0", + "@sentry/node": "10.20.0", + "@sentry/profiling-node": "10.20.0", "@simplewebauthn/server": "12.0.0", "@sinonjs/fake-timers": "11.3.1", "@smithy/node-http-handler": "2.5.0", - "@swc/cli": "0.7.3", - "@swc/core": "1.11.22", - "@twemoji/parser": "15.1.1", + "@swc/cli": "0.7.8", + "@swc/core": "1.13.5", + "@twemoji/parser": "16.0.0", "@types/redis-info": "3.0.3", "@vitalets/google-translate-api": "9.2.1", "accepts": "1.3.8", @@ -109,30 +111,30 @@ "bcryptjs": "2.4.3", "blurhash": "2.0.5", "body-parser": "1.20.3", - "bullmq": "5.51.1", + "bullmq": "5.61.0", "cacheable-lookup": "7.0.0", "cbor": "9.0.2", - "chalk": "5.4.1", - "chalk-template": "1.1.0", + "chalk": "5.6.2", + "chalk-template": "1.1.2", "cherrypick-js": "workspace:*", - "chokidar": "3.6.0", + "chokidar": "4.0.3", "cli-highlight": "2.1.11", "color-convert": "2.0.1", "content-disposition": "0.5.4", "date-fns": "2.30.0", "deep-email-validator": "0.1.21", - "fastify": "5.3.2", + "fastify": "5.6.1", "fastify-raw-body": "5.0.0", "feed": "4.2.2", - "file-type": "19.6.0", + "file-type": "21.0.0", "fluent-ffmpeg": "2.1.3", - "form-data": "4.0.2", - "got": "14.4.7", - "happy-dom": "16.8.1", + "form-data": "4.0.4", + "got": "14.5.0", + "happy-dom": "20.0.7", "hpagent": "1.2.0", "htmlescape": "1.1.1", "http-link-header": "1.1.3", - "ioredis": "5.6.1", + "ioredis": "5.8.1", "ip-cidr": "4.0.2", "ipaddr.js": "2.2.0", "is-svg": "5.1.0", @@ -141,25 +143,25 @@ "json5": "2.2.3", "jsonld": "8.3.3", "jsrsasign": "11.1.0", - "juice": "11.0.1", - "meilisearch": "0.50.0", - "mfc-js": "0.24.0-cherrypick.9", - "microformats-parser": "2.0.2", + "juice": "11.0.3", + "meilisearch": "0.53.0", + "mfc-js": "0.1.0", + "microformats-parser": "2.0.4", "mime-types": "2.1.35", "misskey-reversi": "workspace:*", - "ms": "3.0.0-canary.1", - "nanoid": "5.1.5", + "ms": "3.0.0-canary.202508261828", + "nanoid": "5.1.6", "nested-property": "4.0.0", "node-fetch": "3.3.2", - "nodemailer": "6.10.1", + "nodemailer": "7.0.9", "nsfwjs": "4.2.0", "oauth": "0.10.2", "oauth2orize": "1.12.0", "oauth2orize-pkce": "0.1.2", "os-utils": "0.0.14", - "otpauth": "9.4.0", + "otpauth": "9.4.1", "parse5": "7.3.0", - "pg": "8.15.6", + "pg": "8.16.3", "pkce-challenge": "4.1.0", "probe-image-size": "7.2.3", "promise-limit": "2.7.0", @@ -167,47 +169,47 @@ "qrcode": "1.5.4", "random-seed": "0.3.0", "ratelimiter": "3.4.1", - "re2": "1.21.4", + "re2": "1.22.1", "redis-info": "3.1.0", "redis-lock": "0.1.4", "reflect-metadata": "0.2.2", "rename": "1.0.4", "rss-parser": "3.13.0", "rxjs": "7.8.2", - "sanitize-html": "2.16.0", + "sanitize-html": "2.17.0", "secure-json-parse": "3.0.2", "sharp": "0.33.5", - "semver": "7.7.1", + "semver": "7.7.3", "slacc": "0.0.10", "strict-event-emitter-types": "2.0.0", "stringz": "2.1.0", "strip-ansi": "^7.1.0", - "systeminformation": "5.25.11", + "systeminformation": "5.27.11", "tinycolor2": "1.6.0", - "tmp": "0.2.3", - "tsc-alias": "1.8.15", + "tmp": "0.2.5", + "tsc-alias": "1.8.16", "tsconfig-paths": "4.2.0", - "typeorm": "0.3.22", - "typescript": "5.8.3", + "typeorm": "0.3.27", + "typescript": "5.9.3", "ulid": "2.4.0", "vary": "1.1.2", "web-push": "3.6.7", - "ws": "8.18.1", + "ws": "8.18.3", "xev": "3.0.2" }, "devDependencies": { - "@biomejs/biome": "1.9.4", + "@biomejs/biome": "2.3.1", "@jest/globals": "29.7.0", - "@nestjs/platform-express": "10.4.17", - "@sentry/vue": "9.14.0", + "@nestjs/platform-express": "10.4.20", + "@sentry/vue": "10.20.0", "@simplewebauthn/types": "12.0.0", - "@swc/jest": "0.2.38", + "@swc/jest": "0.2.39", "@types/accepts": "1.3.7", "@types/archiver": "6.0.3", "@types/bcryptjs": "2.4.6", - "@types/body-parser": "1.19.5", + "@types/body-parser": "1.19.6", "@types/color-convert": "2.0.4", - "@types/content-disposition": "0.5.8", + "@types/content-disposition": "0.5.9", "@types/fluent-ffmpeg": "2.1.27", "@types/htmlescape": "1.1.3", "@types/http-link-header": "1.0.7", @@ -218,19 +220,19 @@ "@types/jsrsasign": "10.5.15", "@types/mime-types": "2.1.4", "@types/ms": "0.7.34", - "@types/node": "22.15.2", - "@types/nodemailer": "6.4.17", + "@types/node": "24.9.1", + "@types/nodemailer": "6.4.20", "@types/oauth": "0.9.6", "@types/oauth2orize": "1.11.5", "@types/oauth2orize-pkce": "0.1.2", - "@types/pg": "8.11.14", + "@types/pg": "8.15.5", "@types/pug": "2.0.10", "@types/qrcode": "1.5.5", "@types/random-seed": "0.3.5", "@types/ratelimiter": "3.4.6", "@types/rename": "1.0.7", - "@types/sanitize-html": "2.15.0", - "@types/semver": "7.7.0", + "@types/sanitize-html": "2.16.0", + "@types/semver": "7.7.1", "@types/simple-oauth2": "5.0.7", "@types/sinonjs__fake-timers": "8.1.5", "@types/supertest": "6.0.3", @@ -239,11 +241,11 @@ "@types/vary": "1.1.3", "@types/web-push": "3.6.4", "@types/ws": "8.18.1", - "@typescript-eslint/eslint-plugin": "8.31.0", - "@typescript-eslint/parser": "8.31.0", + "@typescript-eslint/eslint-plugin": "8.46.1", + "@typescript-eslint/parser": "8.46.1", "aws-sdk-client-mock": "4.1.0", "cross-env": "7.0.3", - "eslint-plugin-import": "2.31.0", + "eslint-plugin-import": "2.32.0", "execa": "8.0.1", "fkill": "9.0.0", "jest": "29.7.0", @@ -251,6 +253,6 @@ "nodemon": "3.1.10", "pid-port": "1.0.2", "simple-oauth2": "5.1.0", - "supertest": "7.1.0" + "supertest": "7.1.4" } } diff --git a/packages/backend/scripts/check_migrations_clean.js b/packages/backend/scripts/check_migrations_clean.js new file mode 100644 index 0000000000..ce67b1cd81 --- /dev/null +++ b/packages/backend/scripts/check_migrations_clean.js @@ -0,0 +1,26 @@ +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +// This script checks if the database migrations has been generated correctly. + +import dataSource from '../ormconfig.js'; + +await dataSource.initialize(); + +const sqlInMemory = await dataSource.driver.createSchemaBuilder().log(); + +if (sqlInMemory.upQueries.length > 0 || sqlInMemory.downQueries.length > 0) { + console.error('There are several pending migrations. Please make sure you have generated the migrations correctly, or configured entities class correctly.'); + for (const query of sqlInMemory.upQueries) { + console.error(`- ${query.query}`); + } + for (const query of sqlInMemory.downQueries) { + console.error(`- ${query.query}`); + } + process.exit(1); +} else { + console.log('All migrations are clean.'); + process.exit(0); +} diff --git a/packages/backend/scripts/dev.mjs b/packages/backend/scripts/dev.mjs index cf82ca34bf..6f3bd9b72d 100644 --- a/packages/backend/scripts/dev.mjs +++ b/packages/backend/scripts/dev.mjs @@ -42,7 +42,7 @@ async function killProc() { './node_modules/nodemon/bin/nodemon.js', [ '-w', 'src', - '-e', 'ts,js,mjs,cjs,json', + '-e', 'ts,js,mjs,cjs,json,pug', '--exec', 'pnpm', 'run', 'build', ], { diff --git a/packages/backend/src/boot/cli.ts b/packages/backend/src/boot/cli.ts new file mode 100644 index 0000000000..8a466f3ca5 --- /dev/null +++ b/packages/backend/src/boot/cli.ts @@ -0,0 +1,49 @@ +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import 'reflect-metadata'; +import { EventEmitter } from 'node:events'; +import { NestFactory } from '@nestjs/core'; +import { CommandModule } from '@/cli/CommandModule.js'; +import { NestLogger } from '@/NestLogger.js'; +import { CommandService } from '@/cli/CommandService.js'; + +process.title = 'CherryPick Cli'; + +Error.stackTraceLimit = Infinity; +EventEmitter.defaultMaxListeners = 128; + +const app = await NestFactory.createApplicationContext(CommandModule, { + logger: new NestLogger(), +}); + +const commandService = app.get(CommandService); + +const command = process.argv[2] ?? 'help'; + +switch (command) { + case 'help': { + console.log('Available commands:'); + console.log(' help - Displays this help message'); + console.log(' reset-captcha - Resets the captcha'); + break; + } + case 'ping': { + await commandService.ping(); + break; + } + case 'reset-captcha': { + await commandService.resetCaptcha(); + console.log('Captcha has been reset.'); + break; + } + default: { + console.error(`Unrecognized command: ${command}`); + console.error('Use "help" to see available commands.'); + process.exit(1); + } +} + +process.exit(0); diff --git a/packages/backend/src/cli/CommandModule.ts b/packages/backend/src/cli/CommandModule.ts new file mode 100644 index 0000000000..f4b1d25c18 --- /dev/null +++ b/packages/backend/src/cli/CommandModule.ts @@ -0,0 +1,23 @@ +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { Module } from '@nestjs/common'; +import { CoreModule } from '@/core/CoreModule.js'; +import { GlobalModule } from '@/GlobalModule.js'; +import { CommandService } from './CommandService.js'; + +@Module({ + imports: [ + GlobalModule, + CoreModule, + ], + providers: [ + CommandService, + ], + exports: [ + CommandService, + ], +}) +export class CommandModule {} diff --git a/packages/backend/src/cli/CommandService.ts b/packages/backend/src/cli/CommandService.ts new file mode 100644 index 0000000000..cdb2a9f382 --- /dev/null +++ b/packages/backend/src/cli/CommandService.ts @@ -0,0 +1,49 @@ +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { Inject, Injectable } from '@nestjs/common'; +import type { Config } from '@/config.js'; +import { DI } from '@/di-symbols.js'; +import type Logger from '@/logger.js'; +import { bindThis } from '@/decorators.js'; +import { MetaService } from '@/core/MetaService.js'; + +@Injectable() +export class CommandService { + private logger: Logger; + + constructor( + @Inject(DI.config) + private config: Config, + + private metaService: MetaService, + ) { + } + + @bindThis + public async ping() { + console.log('pong'); + } + + @bindThis + public async resetCaptcha() { + await this.metaService.update({ + enableHcaptcha: false, + hcaptchaSiteKey: null, + hcaptchaSecretKey: null, + enableMcaptcha: false, + mcaptchaSitekey: null, + mcaptchaSecretKey: null, + mcaptchaInstanceUrl: null, + enableRecaptcha: false, + recaptchaSiteKey: null, + recaptchaSecretKey: null, + enableTurnstile: false, + turnstileSiteKey: null, + turnstileSecretKey: null, + enableTestcaptcha: false, + }); + } +} diff --git a/packages/backend/src/config.ts b/packages/backend/src/config.ts index b6f7af10e1..7793377768 100644 --- a/packages/backend/src/config.ts +++ b/packages/backend/src/config.ts @@ -7,6 +7,7 @@ import * as fs from 'node:fs'; import { fileURLToPath } from 'node:url'; import { dirname, resolve } from 'node:path'; import * as yaml from 'js-yaml'; +import { type FastifyServerOptions } from 'fastify'; import type * as Sentry from '@sentry/node'; import type * as SentryVue from '@sentry/vue'; import type { RedisOptions } from 'ioredis'; @@ -27,6 +28,7 @@ type Source = { url?: string; port?: number; socket?: string; + trustProxy?: FastifyServerOptions['trustProxy']; chmodSocket?: string; disableHsts?: boolean; db: { @@ -79,7 +81,6 @@ type Source = { proxyBypassHosts?: string[]; allowedPrivateNetworks?: string[]; - disallowExternalApRedirect?: boolean; maxFileSize?: number; @@ -108,11 +109,8 @@ type Source = { apFileBaseUrl?: string; mediaProxy?: string; - proxyRemoteFiles?: boolean; videoThumbnailGenerator?: string; - signToActivityPubGet?: boolean; - perChannelMaxNoteCacheCount?: number; perUserNotificationsMaxCount?: number; deactivateAntennaThreshold?: number; @@ -130,6 +128,7 @@ export type Config = { url: string; port: number; socket: string | undefined; + trustProxy: FastifyServerOptions['trustProxy']; chmodSocket: string | undefined; disableHsts: boolean | undefined; db: { @@ -164,7 +163,6 @@ export type Config = { proxySmtp: string | undefined; proxyBypassHosts: string[] | undefined; allowedPrivateNetworks: string[] | undefined; - disallowExternalApRedirect: boolean; maxFileSize: number; clusterLimit: number | undefined; id: string; @@ -178,16 +176,12 @@ export type Config = { relationshipJobPerSec: number | undefined; deliverJobMaxAttempts: number | undefined; inboxJobMaxAttempts: number | undefined; - cloudLogging?: { projectId: string; saKeyPath: string; logName?: string; } - apFileBaseUrl: string | undefined; - proxyRemoteFiles: boolean | undefined; - signToActivityPubGet: boolean | undefined; logging?: { sql?: { disableQueryTruncation?: boolean, @@ -208,9 +202,9 @@ export type Config = { authUrl: string; driveUrl: string; userAgent: string; - frontendEntry: string; + frontendEntry: { file: string | null }; frontendManifestExists: boolean; - frontendEmbedEntry: string; + frontendEmbedEntry: { file: string | null }; frontendEmbedManifestExists: boolean; mediaProxy: string; externalMediaProxyEnabled: boolean; @@ -246,7 +240,7 @@ const dir = `${_dirname}/../../../.config`; /** * Path of configuration file */ -const path = process.env.CHERRYPICK_CONFIG_YML +export const path = process.env.CHERRYPICK_CONFIG_YML ? resolve(dir, process.env.CHERRYPICK_CONFIG_YML) : process.env.NODE_ENV === 'test' ? resolve(dir, 'test.yml') @@ -259,10 +253,10 @@ export function loadConfig(): Config { const frontendEmbedManifestExists = fs.existsSync(_dirname + '/../../../built/_frontend_embed_vite_/manifest.json'); const frontendManifest = frontendManifestExists ? JSON.parse(fs.readFileSync(`${_dirname}/../../../built/_frontend_vite_/manifest.json`, 'utf-8')) - : { 'src/_boot_.ts': { file: 'src/_boot_.ts' } }; + : { 'src/_boot_.ts': { file: null } }; const frontendEmbedManifest = frontendEmbedManifestExists ? JSON.parse(fs.readFileSync(`${_dirname}/../../../built/_frontend_embed_vite_/manifest.json`, 'utf-8')) - : { 'src/boot.ts': { file: 'src/boot.ts' } }; + : { 'src/boot.ts': { file: null } }; const config = yaml.load(fs.readFileSync(path, 'utf-8')) as Source; @@ -292,6 +286,7 @@ export function loadConfig(): Config { url: url.origin, port: config.port ?? parseInt(process.env.PORT ?? '', 10), socket: config.socket, + trustProxy: config.trustProxy, chmodSocket: config.chmodSocket, disableHsts: config.disableHsts, host, @@ -319,7 +314,6 @@ export function loadConfig(): Config { proxySmtp: config.proxySmtp, proxyBypassHosts: config.proxyBypassHosts, allowedPrivateNetworks: config.allowedPrivateNetworks, - disallowExternalApRedirect: config.disallowExternalApRedirect ?? false, maxFileSize: config.maxFileSize ?? 262144000, clusterLimit: config.clusterLimit, outgoingAddress: config.outgoingAddress, @@ -332,8 +326,6 @@ export function loadConfig(): Config { relationshipJobPerSec: config.relationshipJobPerSec, deliverJobMaxAttempts: config.deliverJobMaxAttempts, inboxJobMaxAttempts: config.inboxJobMaxAttempts, - proxyRemoteFiles: config.proxyRemoteFiles, - signToActivityPubGet: config.signToActivityPubGet ?? true, apFileBaseUrl: config.apFileBaseUrl, mediaProxy: externalMediaProxy ?? internalMediaProxy, externalMediaProxyEnabled: externalMediaProxy !== null && externalMediaProxy !== internalMediaProxy, diff --git a/packages/backend/src/core/ActivityPubAccessControlService.ts b/packages/backend/src/core/ActivityPubAccessControlService.ts index aa1a206756..fb44f86185 100644 --- a/packages/backend/src/core/ActivityPubAccessControlService.ts +++ b/packages/backend/src/core/ActivityPubAccessControlService.ts @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: lqvp + * SPDX-FileCopyrightText: noridev and cherrypick-project * SPDX-License-Identifier: AGPL-3.0-only */ diff --git a/packages/backend/src/core/AiService.ts b/packages/backend/src/core/AiService.ts index 248a9b8979..23ab8082ed 100644 --- a/packages/backend/src/core/AiService.ts +++ b/packages/backend/src/core/AiService.ts @@ -29,7 +29,7 @@ export class AiService { } @bindThis - public async detectSensitive(path: string): Promise { + public async detectSensitive(source: string | Buffer): Promise { try { if (isSupportedCpu === undefined) { isSupportedCpu = await this.computeIsSupportedCpu(); @@ -51,7 +51,7 @@ export class AiService { }); } - const buffer = await fs.promises.readFile(path); + const buffer = source instanceof Buffer ? source : await fs.promises.readFile(source); const image = await tf.node.decodeImage(buffer, 3) as any; try { const predictions = await this.model.classify(image); diff --git a/packages/backend/src/core/AvatarDecorationService.ts b/packages/backend/src/core/AvatarDecorationService.ts index 6ed3d29f41..f43136d54a 100644 --- a/packages/backend/src/core/AvatarDecorationService.ts +++ b/packages/backend/src/core/AvatarDecorationService.ts @@ -225,6 +225,8 @@ export class AvatarDecorationService implements OnApplicationShutdown { if (!(await this.usersRepository.update({ id: user.id, isDeleted: false }, updates)).affected) { return 'skip'; } + + return undefined; } @bindThis diff --git a/packages/backend/src/core/ChatService.ts b/packages/backend/src/core/ChatService.ts index 9d294a80cb..1b5a74e4a9 100644 --- a/packages/backend/src/core/ChatService.ts +++ b/packages/backend/src/core/ChatService.ts @@ -4,8 +4,9 @@ */ import { Inject, Injectable } from '@nestjs/common'; +import * as mfm from 'mfc-js'; import * as Redis from 'ioredis'; -import { Brackets } from 'typeorm'; +import { Brackets, In } from 'typeorm'; import { DI } from '@/di-symbols.js'; import type { Config } from '@/config.js'; import { QueueService } from '@/core/QueueService.js'; @@ -25,11 +26,12 @@ import { MiChatRoomInvitation } from '@/models/ChatRoomInvitation.js'; import { Packed } from '@/misc/json-schema.js'; import { sqlLikeEscape } from '@/misc/sql-like-escape.js'; import { CustomEmojiService } from '@/core/CustomEmojiService.js'; -import { emojiRegex } from '@/misc/emoji-regex.js'; +import { extractCustomEmojisFromMfm } from '@/misc/extract-custom-emojis-from-mfm.js'; import { NotificationService } from '@/core/NotificationService.js'; import { ModerationLogService } from '@/core/ModerationLogService.js'; +import { emojiRegex } from '@/misc/emoji-regex.js'; -const MAX_ROOM_MEMBERS = 30; +const MAX_ROOM_MEMBERS = 50; const MAX_REACTIONS_PER_MESSAGE = 100; const isCustomEmojiRegexp = /^:([\w+-]+)(?:@\.)?:$/; @@ -133,6 +135,7 @@ export class ChatService { text?: string | null; file?: MiDriveFile | null; uri?: string | null; + emojis?: string[]; }): Promise> { if (fromUser.id === toUser.id) { throw new Error('yourself'); @@ -183,6 +186,15 @@ export class ChatService { throw new Error('blocked'); } + // Extract emojis from text if not provided + // Store only emoji names (like notes do), not name@host format + let emojis = params.emojis ?? []; + if (!params.emojis && params.text) { + // Parse MFM and extract custom emojis, same as notes do + const tokens = mfm.parse(params.text); + emojis = extractCustomEmojisFromMfm(tokens); + } + const message = { id: this.idService.gen(), fromUserId: fromUser.id, @@ -191,6 +203,7 @@ export class ChatService { fileId: params.file ? params.file.id : null, reads: [], uri: params.uri ?? null, + emojis, } satisfies Partial; const inserted = await this.chatMessagesRepository.insertOne(message); @@ -236,6 +249,19 @@ export class ChatService { }, 3000); } + // Federation: Send to remote user if applicable + if (this.userEntityService.isLocalUser(fromUser) && this.userEntityService.isRemoteUser(toUser)) { + const fullFromUser = await this.usersRepository.findOneByOrFail({ id: fromUser.id }); + const chatMessageObject = await this.apRendererService.renderChatMessage(inserted, fullFromUser, [toUser]); + const activity = { + type: 'Create', + actor: this.userEntityService.genLocalUserUri(fullFromUser.id), + object: chatMessageObject, + published: this.idService.parse(inserted.id).date.toISOString(), + }; + this.queueService.deliver(fullFromUser, this.apRendererService.addContext(activity), toUser.inbox, false); + } + return packedMessage; } @@ -244,6 +270,7 @@ export class ChatService { text?: string | null; file?: MiDriveFile | null; uri?: string | null; + emojis?: string[]; }): Promise> { const memberships = (await this.chatRoomMembershipsRepository.findBy({ roomId: toRoom.id })).map(m => ({ userId: m.userId, @@ -259,6 +286,15 @@ export class ChatService { const membershipsOtherThanMe = memberships.filter(member => member.userId !== fromUser.id); + // Extract emojis from text if not provided + // Store only emoji names (like notes do), not name@host format + let emojis = params.emojis ?? []; + if (!params.emojis && params.text) { + // Parse MFM and extract custom emojis, same as notes do + const tokens = mfm.parse(params.text); + emojis = extractCustomEmojisFromMfm(tokens); + } + const message = { id: this.idService.gen(), fromUserId: fromUser.id, @@ -267,6 +303,7 @@ export class ChatService { fileId: params.file ? params.file.id : null, reads: [], uri: params.uri ?? null, + emojis, } satisfies Partial; const inserted = await this.chatMessagesRepository.insertOne(message); @@ -306,6 +343,33 @@ export class ChatService { } }, 3000); + // Federation: Send to remote members if applicable + if (this.userEntityService.isLocalUser(fromUser)) { + // Get all members (including owner) + const allMembers = await Promise.all( + memberships.map(m => this.usersRepository.findOneBy({ id: m.userId })), + ); + const remoteMembers = allMembers.filter(m => m && this.userEntityService.isRemoteUser(m)) as any[]; + + if (remoteMembers.length > 0) { + const fullFromUser = await this.usersRepository.findOneByOrFail({ id: fromUser.id }); + const allMembersForRendering = allMembers.filter(m => m != null) as MiUser[]; + const chatMessageObject = await this.apRendererService.renderChatMessage(inserted, fullFromUser, allMembersForRendering, toRoom.id); + const activity = { + type: 'Create', + actor: this.userEntityService.genLocalUserUri(fullFromUser.id), + object: chatMessageObject, + published: this.idService.parse(inserted.id).date.toISOString(), + }; + const contextedActivity = this.apRendererService.addContext(activity); + + // Send to each remote member + for (const remoteMember of remoteMembers) { + this.queueService.deliver(fullFromUser, contextedActivity, remoteMember.inbox, false); + } + } + } + return packedMessage; } @@ -331,6 +395,16 @@ export class ChatService { await redisPipeline.exec(); } + @bindThis + public async readAllChatMessages( + readerId: MiUser['id'], + ): Promise { + const redisPipeline = this.redisClient.pipeline(); + // TODO: newUserChatMessageExists とか newRoomChatMessageExists も消したい(けどキーの列挙が必要になって面倒) + redisPipeline.del(`newChatMessagesExists:${readerId}`); + await redisPipeline.exec(); + } + @bindThis public findMessageById(messageId: MiChatMessage['id']) { return this.chatMessagesRepository.findOneBy({ id: messageId }); @@ -578,6 +652,20 @@ export class ChatService { @bindThis public async deleteRoom(room: MiChatRoom, deleter?: MiUser) { + const memberships = (await this.chatRoomMembershipsRepository.findBy({ roomId: room.id })).map(m => ({ + userId: m.userId, + })).concat({ // ownerはmembershipレコードを作らないため + userId: room.ownerId, + }); + + // 未読フラグ削除 + const redisPipeline = this.redisClient.pipeline(); + for (const membership of memberships) { + redisPipeline.del(`newRoomChatMessageExists:${membership.userId}:${room.id}`); + redisPipeline.srem(`newChatMessagesExists:${membership.userId}`, `room:${room.id}`); + } + await redisPipeline.exec(); + await this.chatRoomsRepository.delete(room.id); if (deleter) { @@ -641,9 +729,28 @@ export class ChatService { const created = await this.chatRoomInvitationsRepository.insertOne(invitation); - this.notificationService.createNotification(inviteeId, 'chatRoomInvitationReceived', { - invitationId: invitation.id, - }, inviterId); + // Get inviter and invitee users + const inviter = await this.usersRepository.findOneByOrFail({ id: inviterId }); + const invitee = await this.usersRepository.findOneByOrFail({ id: inviteeId }); + + // Send local notification if invitee is local + if (this.userEntityService.isLocalUser(invitee)) { + this.notificationService.createNotification(inviteeId, 'chatRoomInvitationReceived', { + invitationId: invitation.id, + }, inviterId); + } + + // Federation: Send Invite activity to remote user if applicable + if (this.userEntityService.isLocalUser(inviter) && this.userEntityService.isRemoteUser(invitee)) { + const roomObject = this.apRendererService.renderChatRoom(room, inviter); + const inviteeUri = invitee.uri; + const inviteActivity = this.apRendererService.renderInvite(roomObject, inviteeUri, inviter); + const activity = { + ...inviteActivity, + published: this.idService.parse(invitation.id).date.toISOString(), + }; + this.queueService.deliver(inviter, this.apRendererService.addContext(activity), invitee.inbox, false); + } return created; } @@ -697,6 +804,54 @@ export class ChatService { // TODO: transaction await this.chatRoomMembershipsRepository.insertOne(membership); await this.chatRoomInvitationsRepository.delete(invitation.id); + + // Federation: Notify about acceptance and new member + const room = await this.chatRoomsRepository.findOneByOrFail({ id: roomId }); + const joiningUser = await this.usersRepository.findOneByOrFail({ id: userId }); + const owner = await this.usersRepository.findOneByOrFail({ id: room.ownerId }); + + // Send Accept activity to the inviter (room owner) if they are remote + if (this.userEntityService.isLocalUser(joiningUser) && this.userEntityService.isRemoteUser(owner)) { + const roomObject = this.apRendererService.renderChatRoom(room, owner); + // Create a simplified invite object reference for the Accept activity + const inviteObject = { + type: 'Invite', + actor: owner.uri, + object: roomObject, + target: this.userEntityService.genLocalUserUri(joiningUser.id), + }; + const acceptActivity = this.apRendererService.renderAccept(inviteObject, joiningUser); + const activity = { + ...acceptActivity, + published: this.idService.parse(membership.id).date.toISOString(), + }; + this.queueService.deliver(joiningUser, this.apRendererService.addContext(activity), owner.inbox, false); + } + + // Get all members (including owner, excluding the joining user) + const memberships = await this.chatRoomMembershipsRepository.findBy({ roomId }); + const memberUserIds = [room.ownerId, ...memberships.map(m => m.userId)].filter(id => id !== userId); + const memberUsers = await this.usersRepository.findBy({ id: In(memberUserIds) }); + const remoteMembers = memberUsers.filter(m => this.userEntityService.isRemoteUser(m)); + + // Send Add activity to other remote members (not the owner, as they got Accept) + if (remoteMembers.length > 0 && this.userEntityService.isLocalUser(owner)) { + const roomUri = `${this.config.url}/chat/rooms/${room.id}`; + const joiningUserUri = this.userEntityService.isLocalUser(joiningUser) + ? this.userEntityService.genLocalUserUri(joiningUser.id) + : joiningUser.uri; + + const addActivity = this.apRendererService.renderAdd(owner, roomUri, joiningUserUri ?? ''); + const activity = { + ...addActivity, + published: this.idService.parse(membership.id).date.toISOString(), + }; + const contextedActivity = this.apRendererService.addContext(activity); + + for (const remoteMember of remoteMembers) { + this.queueService.deliver(owner, contextedActivity, remoteMember.inbox, false); + } + } } @bindThis @@ -705,10 +860,156 @@ export class ChatService { await this.chatRoomInvitationsRepository.update(invitation.id, { ignored: true }); } + @bindThis + public async rejectRoomInvitation(userId: MiUser['id'], roomId: MiChatRoom['id']) { + const invitation = await this.chatRoomInvitationsRepository.findOneByOrFail({ roomId, userId }); + const room = await this.chatRoomsRepository.findOneByOrFail({ id: roomId }); + + // Delete the invitation + await this.chatRoomInvitationsRepository.delete({ id: invitation.id }); + + // Federation: Send Reject activity to the inviter if applicable + const inviter = await this.usersRepository.findOneByOrFail({ id: room.ownerId }); + const invitee = await this.usersRepository.findOneByOrFail({ id: userId }); + + if (this.userEntityService.isLocalUser(invitee) && this.userEntityService.isRemoteUser(inviter)) { + const roomUri = inviter.uri?.replace(/\/users\/.*$/, `/chat/rooms/${room.id}`) ?? `${this.config.url}/chat/rooms/${room.id}`; + + // Create a simplified invite object reference for the Reject activity + const inviteObject = { + type: 'Invite', + actor: inviter.uri, + object: roomUri, + target: this.userEntityService.genLocalUserUri(invitee.id), + }; + const rejectActivity = this.apRendererService.renderReject(inviteObject, invitee); + const activity = { + ...rejectActivity, + published: new Date().toISOString(), + }; + this.queueService.deliver(invitee, this.apRendererService.addContext(activity), inviter.inbox, false); + } + } + + @bindThis + public async cancelRoomInvitation(inviterId: MiUser['id'], invitationId: MiChatRoomInvitation['id']): Promise { + const invitation = await this.chatRoomInvitationsRepository.findOneBy({ id: invitationId }); + if (!invitation) return false; + + const room = await this.chatRoomsRepository.findOneByOrFail({ id: invitation.roomId }); + + // Check if the inviter is the room owner + if (room.ownerId !== inviterId) { + throw new Error('not owner'); + } + + // Get inviter and invitee users + const inviter = await this.usersRepository.findOneByOrFail({ id: inviterId }); + const invitee = await this.usersRepository.findOneByOrFail({ id: invitation.userId }); + + // Delete the invitation + await this.chatRoomInvitationsRepository.delete({ id: invitation.id }); + + // Federation: Send Undo(Invite) activity to remote invitee + if (this.userEntityService.isLocalUser(inviter) && this.userEntityService.isRemoteUser(invitee)) { + const roomObject = this.apRendererService.renderChatRoom(room, inviter); + const inviteObject = this.apRendererService.renderInvite(roomObject, invitee.uri, inviter); + + // Generate activity ID for the original Invite + const inviteActivityId = `${this.config.url}/invitations/${invitation.id}`; + const inviteWithId = { + ...inviteObject, + id: inviteActivityId, + }; + + // Create Undo activity + const undoActivity = this.apRendererService.renderUndo(inviteWithId, inviter); + const activityId = `${this.config.url}/activities/${this.idService.gen()}`; + const contextedActivity = this.apRendererService.addContext({ + ...undoActivity, + id: activityId, + }); + + this.queueService.deliver(inviter, contextedActivity, invitee.inbox, false); + } + + return true; + } + @bindThis public async leaveRoom(userId: MiUser['id'], roomId: MiChatRoom['id']) { const membership = await this.chatRoomMembershipsRepository.findOneByOrFail({ roomId, userId }); + const room = await this.chatRoomsRepository.findOne({ where: { id: roomId }, relations: ['owner'] }); + const leavingUser = await this.usersRepository.findOneByOrFail({ id: userId }); + await this.chatRoomMembershipsRepository.delete(membership.id); + + // 未読フラグを消す (「既読にする」というわけでもないのでreadメソッドは使わないでおく) + const redisPipeline = this.redisClient.pipeline(); + redisPipeline.del(`newRoomChatMessageExists:${userId}:${roomId}`); + redisPipeline.srem(`newChatMessagesExists:${userId}`, `room:${roomId}`); + await redisPipeline.exec(); + + // Federation: Send Remove activity when local user leaves + if (room && this.userEntityService.isLocalUser(leavingUser)) { + // Load owner if not already loaded + const owner = room.owner ?? await this.usersRepository.findOneByOrFail({ id: room.ownerId }); + + if (!owner) { + console.log('[ChatService.leaveRoom] Owner not found for room:', room.id); + return; + } + + console.log('[ChatService.leaveRoom] Processing federation for room:', room.id, 'owner:', owner.id, 'isRemote:', this.userEntityService.isRemoteUser(owner)); + + // Get all members including owner + const allMemberIds = (await this.chatRoomMembershipsRepository.findBy({ roomId: room.id })) + .map(m => m.userId) + .concat(room.ownerId); + + const allMembers = await this.usersRepository.findBy({ id: In(allMemberIds) }); + const remoteMembers = allMembers.filter(u => this.userEntityService.isRemoteUser(u)); + + // Send Remove activity to remote members and owner + if (remoteMembers.length > 0 || this.userEntityService.isRemoteUser(owner)) { + // Generate the correct room URI based on the owner's server + const roomUri = this.userEntityService.isLocalUser(owner) + ? `${this.config.url}/chat/rooms/${room.id}` + : `${owner.uri?.replace(/\/users\/.*$/, '')}/chat/rooms/${room.id}`; + + console.log('[ChatService.leaveRoom] Generated roomUri:', roomUri); + + const leavingUserUri = this.userEntityService.genLocalUserUri(leavingUser.id) ?? ''; + const removeActivity = this.apRendererService.renderRemove( + leavingUser, + roomUri, + leavingUserUri, + ); + + // Add id and @context to the activity + const activityId = `${this.config.url}/activities/${this.idService.gen()}`; + const contextedActivity = this.apRendererService.addContext({ + ...removeActivity, + id: activityId, + }); + + console.log('[ChatService.leaveRoom] Remove activity:', JSON.stringify(contextedActivity, null, 2)); + + // Send to all remote members + for (const remoteMember of remoteMembers) { + console.log('[ChatService.leaveRoom] Sending Remove to remote member:', remoteMember.id, remoteMember.inbox); + this.queueService.deliver(leavingUser, contextedActivity, remoteMember.inbox, false); + } + + // Send to room owner if remote + if (this.userEntityService.isRemoteUser(owner) && !remoteMembers.some(m => m.id === owner.id)) { + console.log('[ChatService.leaveRoom] Sending Remove to room owner:', owner.id, owner.inbox); + this.queueService.deliver(leavingUser, contextedActivity, owner.inbox, false); + } + } else { + console.log('[ChatService.leaveRoom] No remote members or owner, skipping federation'); + } + } } @bindThis diff --git a/packages/backend/src/core/CoreModule.ts b/packages/backend/src/core/CoreModule.ts index a0d1c67601..f022289ca4 100644 --- a/packages/backend/src/core/CoreModule.ts +++ b/packages/backend/src/core/CoreModule.ts @@ -80,6 +80,7 @@ import { ChannelFollowingService } from './ChannelFollowingService.js'; import { ChatService } from './ChatService.js'; import { RegistryApiService } from './RegistryApiService.js'; import { ReversiService } from './ReversiService.js'; +import { PageService } from './PageService.js'; import { ActivityPubAccessControlService } from './ActivityPubAccessControlService.js'; import { ChartLoggerService } from './chart/ChartLoggerService.js'; @@ -159,6 +160,8 @@ import { ApEventService } from './activitypub/models/ApEventService.js'; import { QueueModule } from './QueueModule.js'; import { QueueService } from './QueueService.js'; import { LoggerService } from './LoggerService.js'; +import { NoteHistorySerivce } from './NoteHistoryService.js'; +import { NoteHistoryEntityService } from './entities/NoteHistoryEntityService.js'; import type { Provider } from '@nestjs/common'; //#region 文字列ベースでのinjection用(循環参照対応のため) @@ -235,6 +238,7 @@ const $ChannelFollowingService: Provider = { provide: 'ChannelFollowingService', const $ChatService: Provider = { provide: 'ChatService', useExisting: ChatService }; const $RegistryApiService: Provider = { provide: 'RegistryApiService', useExisting: RegistryApiService }; const $ReversiService: Provider = { provide: 'ReversiService', useExisting: ReversiService }; +const $PageService: Provider = { provide: 'PageService', useExisting: PageService }; const $ActivityPubAccessControlService: Provider = { provide: 'ActivityPubAccessControlService', useExisting: ActivityPubAccessControlService }; const $ChartLoggerService: Provider = { provide: 'ChartLoggerService', useExisting: ChartLoggerService }; @@ -277,6 +281,7 @@ const $MutingEntityService: Provider = { provide: 'MutingEntityService', useExis const $RenoteMutingEntityService: Provider = { provide: 'RenoteMutingEntityService', useExisting: RenoteMutingEntityService }; const $NoteEntityService: Provider = { provide: 'NoteEntityService', useExisting: NoteEntityService }; const $NoteFavoriteEntityService: Provider = { provide: 'NoteFavoriteEntityService', useExisting: NoteFavoriteEntityService }; +const $NoteHistoryEntityService: Provider = { provide: 'NoteHistoryEntityService', useExisting: NoteHistoryEntityService }; const $NoteReactionEntityService: Provider = { provide: 'NoteReactionEntityService', useExisting: NoteReactionEntityService }; const $NoteDraftEntityService: Provider = { provide: 'NoteDraftEntityService', useExisting: NoteDraftEntityService }; const $NotificationEntityService: Provider = { provide: 'NotificationEntityService', useExisting: NotificationEntityService }; @@ -393,6 +398,8 @@ const $ApEventService: Provider = { provide: 'ApEventService', useExisting: ApEv ChatService, RegistryApiService, ReversiService, + PageService, + NoteHistorySerivce, ActivityPubAccessControlService, ChartLoggerService, @@ -435,6 +442,7 @@ const $ApEventService: Provider = { provide: 'ApEventService', useExisting: ApEv RenoteMutingEntityService, NoteEntityService, NoteFavoriteEntityService, + NoteHistoryEntityService, NoteReactionEntityService, NoteDraftEntityService, NotificationEntityService, @@ -547,6 +555,7 @@ const $ApEventService: Provider = { provide: 'ApEventService', useExisting: ApEv $ChatService, $RegistryApiService, $ReversiService, + $PageService, $ActivityPubAccessControlService, $ChartLoggerService, @@ -589,6 +598,7 @@ const $ApEventService: Provider = { provide: 'ApEventService', useExisting: ApEv $RenoteMutingEntityService, $NoteEntityService, $NoteFavoriteEntityService, + $NoteHistoryEntityService, $NoteReactionEntityService, $NoteDraftEntityService, $NotificationEntityService, @@ -702,6 +712,8 @@ const $ApEventService: Provider = { provide: 'ApEventService', useExisting: ApEv ChatService, RegistryApiService, ReversiService, + PageService, + NoteHistorySerivce, ActivityPubAccessControlService, FederationChart, @@ -743,6 +755,7 @@ const $ApEventService: Provider = { provide: 'ApEventService', useExisting: ApEv RenoteMutingEntityService, NoteEntityService, NoteFavoriteEntityService, + NoteHistoryEntityService, NoteReactionEntityService, NoteDraftEntityService, NotificationEntityService, @@ -854,6 +867,7 @@ const $ApEventService: Provider = { provide: 'ApEventService', useExisting: ApEv $ChatService, $RegistryApiService, $ReversiService, + $PageService, $ActivityPubAccessControlService, $FederationChart, @@ -895,6 +909,7 @@ const $ApEventService: Provider = { provide: 'ApEventService', useExisting: ApEv $RenoteMutingEntityService, $NoteEntityService, $NoteFavoriteEntityService, + $NoteHistoryEntityService, $NoteReactionEntityService, $NoteDraftEntityService, $NotificationEntityService, diff --git a/packages/backend/src/core/DriveService.ts b/packages/backend/src/core/DriveService.ts index e3ec6ecb1a..3c23733879 100644 --- a/packages/backend/src/core/DriveService.ts +++ b/packages/backend/src/core/DriveService.ts @@ -8,7 +8,7 @@ import * as fs from 'node:fs'; import { Inject, Injectable } from '@nestjs/common'; import sharp from 'sharp'; import { sharpBmp } from '@misskey-dev/sharp-read-bmp'; -import { IsNull } from 'typeorm'; +import { In, IsNull } from 'typeorm'; import { DeleteObjectCommandInput, PutObjectCommandInput, NoSuchKey } from '@aws-sdk/client-s3'; import { DI } from '@/di-symbols.js'; import type { DriveFilesRepository, UsersRepository, DriveFoldersRepository, UserProfilesRepository, MiMeta } from '@/models/_.js'; @@ -506,13 +506,14 @@ export class DriveService { if (user && this.meta.sensitiveMediaDetection === 'remote' && this.userEntityService.isLocalUser(user)) skipNsfwCheck = true; const info = await this.fileInfoService.getFileInfo(path, { + fileName: name, skipSensitiveDetection: skipNsfwCheck, sensitiveThreshold: // 感度が高いほどしきい値は低くすることになる - this.meta.sensitiveMediaDetectionSensitivity === 'veryHigh' ? 0.1 : - this.meta.sensitiveMediaDetectionSensitivity === 'high' ? 0.3 : - this.meta.sensitiveMediaDetectionSensitivity === 'low' ? 0.7 : - this.meta.sensitiveMediaDetectionSensitivity === 'veryLow' ? 0.9 : - 0.5, + this.meta.sensitiveMediaDetectionSensitivity === 'veryHigh' ? 0.1 : + this.meta.sensitiveMediaDetectionSensitivity === 'high' ? 0.3 : + this.meta.sensitiveMediaDetectionSensitivity === 'low' ? 0.7 : + this.meta.sensitiveMediaDetectionSensitivity === 'veryLow' ? 0.9 : + 0.5, sensitiveThresholdForPorn: 0.75, enableSensitiveMediaDetectionForVideos: this.meta.enableSensitiveMediaDetectionForVideos, }); @@ -552,29 +553,44 @@ export class DriveService { this.registerLogger.debug(`ADD DRIVE FILE: user ${user?.id ?? 'not set'}, name ${detectedName}, tmp ${path}`); - //#region Check drive usage - if (user && !isLink) { - const usage = await this.driveFileEntityService.calcDriveUsageOf(user); + //#region Check drive usage and mime type + if (user != null && !isLink) { const isLocalUser = this.userEntityService.isLocalUser(user); + const isModerator = isLocalUser ? await this.roleService.isModerator(user) : false; + if (!isModerator) { + const policies = await this.roleService.getUserPolicies(user.id); + + const allowedMimeTypes = policies.uploadableFileTypes; + const isAllowed = allowedMimeTypes.some((mimeType) => { + if (mimeType === '*' || mimeType === '*/*') return true; + if (mimeType.endsWith('/*')) return info.type.mime.startsWith(mimeType.slice(0, -1)); + return info.type.mime === mimeType; + }); + if (!isAllowed) { + throw new IdentifiableError('bd71c601-f9b0-4808-9137-a330647ced9b', `Unallowed file type: ${info.type.mime}`); + } - const policies = await this.roleService.getUserPolicies(user.id); - const driveCapacity = 1024 * 1024 * policies.driveCapacityMb; - const maxFileSize = 1024 * 1024 * policies.maxFileSizeMb; - this.registerLogger.debug('drive capacity override applied'); - this.registerLogger.debug(`overrideCap: ${driveCapacity}bytes, usage: ${usage}bytes, u+s: ${usage + info.size}bytes`); + const driveCapacity = 1024 * 1024 * policies.driveCapacityMb; + const maxFileSize = 1024 * 1024 * policies.maxFileSizeMb; - if (maxFileSize < info.size) { - if (isLocalUser) { - throw new IdentifiableError('f9e4e5f3-4df4-40b5-b400-f236945f7073', 'Max file size exceeded.'); + if (maxFileSize < info.size) { + if (isLocalUser) { + throw new IdentifiableError('f9e4e5f3-4df4-40b5-b400-f236945f7073', 'Max file size exceeded.'); + } } - } - // If usage limit exceeded - if (driveCapacity < usage + info.size) { - if (isLocalUser) { - throw new IdentifiableError('c6244ed2-a39a-4e1c-bf93-f0fbd7764fa6', 'No free space.'); + const usage = await this.driveFileEntityService.calcDriveUsageOf(user); + + this.registerLogger.debug('drive capacity override applied'); + this.registerLogger.debug(`overrideCap: ${driveCapacity}bytes, usage: ${usage}bytes, u+s: ${usage + info.size}bytes`); + + // If usage limit exceeded + if (driveCapacity < usage + info.size) { + if (isLocalUser) { + throw new IdentifiableError('c6244ed2-a39a-4e1c-bf93-f0fbd7764fa6', 'No free space.'); + } + await this.expireOldFile(await this.usersRepository.findOneByOrFail({ id: user.id }) as MiRemoteUser, driveCapacity - info.size); } - await this.expireOldFile(await this.usersRepository.findOneByOrFail({ id: user.id }) as MiRemoteUser, driveCapacity - info.size); } } //#endregion @@ -758,6 +774,21 @@ export class DriveService { return fileObj; } + @bindThis + public async moveFiles(fileIds: MiDriveFile['id'][], folderId: MiDriveFolder['id'] | null, userId: MiUser['id']) { + const folder = folderId ? await this.driveFoldersRepository.findOneByOrFail({ + id: folderId, + userId: userId, + }) : null; + + await this.driveFilesRepository.update({ + id: In(fileIds), + userId: userId, + }, { + folderId: folder ? folder.id : null, + }); + } + @bindThis public async deleteFile(file: MiDriveFile, isExpired = false, deleter?: MiUser) { if (file.storedInternal) { @@ -813,14 +844,14 @@ export class DriveService { await Promise.all(promises); } - this.deletePostProcess(file, isExpired, deleter); + await this.deletePostProcess(file, isExpired, deleter); } @bindThis private async deletePostProcess(file: MiDriveFile, isExpired = false, deleter?: MiUser) { // リモートファイル期限切れ削除後は直リンクにする if (isExpired && file.userHost !== null && file.uri != null) { - this.driveFilesRepository.update(file.id, { + await this.driveFilesRepository.update(file.id, { isLink: true, url: file.uri, thumbnailUrl: null, @@ -832,7 +863,7 @@ export class DriveService { webpublicAccessKey: 'webpublic-' + randomUUID(), }); } else { - this.driveFilesRepository.delete(file.id); + await this.driveFilesRepository.delete(file.id); } this.driveChart.update(file, false); diff --git a/packages/backend/src/core/EmailService.ts b/packages/backend/src/core/EmailService.ts index 55e84444b9..31e91edadb 100644 --- a/packages/backend/src/core/EmailService.ts +++ b/packages/backend/src/core/EmailService.ts @@ -144,7 +144,10 @@ export class EmailService { try { // TODO: htmlサニタイズ const info = await transporter.sendMail({ - from: this.meta.email!, + from: this.meta.name ? { + name: this.meta.name, + address: this.meta.email!, + } : this.meta.email!, to: to, subject: subject, text: text, diff --git a/packages/backend/src/core/FanoutTimelineEndpointService.ts b/packages/backend/src/core/FanoutTimelineEndpointService.ts index ab94454c11..a19db06f89 100644 --- a/packages/backend/src/core/FanoutTimelineEndpointService.ts +++ b/packages/backend/src/core/FanoutTimelineEndpointService.ts @@ -20,6 +20,8 @@ import { CacheService } from '@/core/CacheService.js'; import { isReply } from '@/misc/is-reply.js'; import { isInstanceMuted } from '@/misc/is-instance-muted.js'; +type NoteFilter = (note: MiNote) => boolean; + type TimelineOptions = { untilId: string | null, sinceId: string | null, @@ -28,7 +30,7 @@ type TimelineOptions = { me?: { id: MiUser['id'] } | undefined | null, useDbFallback: boolean, redisTimelines: FanoutTimelineName[], - noteFilter?: (note: MiNote) => boolean, + noteFilter?: NoteFilter, alwaysIncludeMyNotes?: boolean; ignoreAuthorFromBlock?: boolean; ignoreAuthorFromMute?: boolean; @@ -80,7 +82,7 @@ export class FanoutTimelineEndpointService { const shouldFallbackToDb = noteIds.length === 0 || ps.sinceId != null && ps.sinceId < oldestNoteId; if (!shouldFallbackToDb) { - let filter = ps.noteFilter ?? (_note => true); + let filter = ps.noteFilter ?? (_note => true) as NoteFilter; if (ps.alwaysIncludeMyNotes && ps.me) { const me = ps.me; @@ -126,6 +128,8 @@ export class FanoutTimelineEndpointService { filter = (note) => { if (isUserRelated(note, userIdsWhoBlockingMe, ps.ignoreAuthorFromBlock)) return false; if (isUserRelated(note, userIdsWhoMeMuting, ps.ignoreAuthorFromMute)) return false; + if (isUserRelated(note.renote, userIdsWhoBlockingMe, ps.ignoreAuthorFromBlock)) return false; + if (isUserRelated(note.renote, userIdsWhoMeMuting, ps.ignoreAuthorFromMute)) return false; if (!ps.ignoreAuthorFromMute && isRenote(note) && !isQuote(note) && userIdsWhoMeMutingRenotes.has(note.userId)) return false; if (isInstanceMuted(note, userMutedInstances)) return false; @@ -149,15 +153,11 @@ export class FanoutTimelineEndpointService { { const parentFilter = filter; filter = (note) => { - const noteJoined = note as MiNote & { - renoteUser: MiUser | null; - replyUser: MiUser | null; - }; if (!ps.ignoreAuthorFromUserSuspension) { if (note.user!.isSuspended) return false; } - if (note.userId !== note.renoteUserId && noteJoined.renoteUser?.isSuspended) return false; - if (note.userId !== note.replyUserId && noteJoined.replyUser?.isSuspended) return false; + if (note.userId !== note.renoteUserId && note.renote?.user?.isSuspended) return false; + if (note.userId !== note.replyUserId && note.reply?.user?.isSuspended) return false; return parentFilter(note); }; @@ -204,7 +204,7 @@ export class FanoutTimelineEndpointService { return await ps.dbFallback(ps.untilId, ps.sinceId, ps.limit); } - private async getAndFilterFromDb(noteIds: string[], noteFilter: (note: MiNote) => boolean, idCompare: (a: string, b: string) => number): Promise { + private async getAndFilterFromDb(noteIds: string[], noteFilter: NoteFilter, idCompare: (a: string, b: string) => number): Promise { const query = this.notesRepository.createQueryBuilder('note') .where('note.id IN (:...noteIds)', { noteIds: noteIds }) .innerJoinAndSelect('note.user', 'user') diff --git a/packages/backend/src/core/FileInfoService.ts b/packages/backend/src/core/FileInfoService.ts index efa2559a7b..af4d0b8c6b 100644 --- a/packages/backend/src/core/FileInfoService.ts +++ b/packages/backend/src/core/FileInfoService.ts @@ -20,6 +20,7 @@ import { AiService } from '@/core/AiService.js'; import { LoggerService } from '@/core/LoggerService.js'; import type Logger from '@/logger.js'; import { bindThis } from '@/decorators.js'; +import { isMimeImage } from '@/misc/is-mime-image.js'; import type { PredictionType } from 'nsfwjs'; export type FileInfo = { @@ -64,6 +65,7 @@ export class FileInfoService { */ @bindThis public async getFileInfo(path: string, opts: { + fileName?: string | null; skipSensitiveDetection: boolean; sensitiveThreshold?: number; sensitiveThresholdForPorn?: number; @@ -76,6 +78,26 @@ export class FileInfoService { let type = await this.detectType(path); + if (type.mime === TYPE_OCTET_STREAM.mime && opts.fileName != null) { + const ext = opts.fileName.split('.').pop(); + if (ext === 'txt') { + type = { + mime: 'text/plain', + ext: 'txt', + }; + } else if (ext === 'csv') { + type = { + mime: 'text/csv', + ext: 'csv', + }; + } else if (ext === 'json') { + type = { + mime: 'application/json', + ext: 'json', + }; + } + } + // image dimensions let width: number | undefined; let height: number | undefined; @@ -183,16 +205,7 @@ export class FileInfoService { return [sensitive, porn]; } - if ([ - 'image/jpeg', - 'image/png', - 'image/webp', - ].includes(mime)) { - const result = await this.aiService.detectSensitive(source); - if (result) { - [sensitive, porn] = judgePrediction(result); - } - } else if (analyzeVideo && (mime === 'image/apng' || mime.startsWith('video/'))) { + if (analyzeVideo && (mime === 'image/apng' || mime.startsWith('video/'))) { const [outDir, disposeOutDir] = await createTempDir(); try { const command = FFmpeg() @@ -260,6 +273,23 @@ export class FileInfoService { } finally { disposeOutDir(); } + } else if (isMimeImage(mime, 'sharp-convertible-image-with-bmp')) { + /* + * tfjs-node は限られた画像形式しか受け付けないため、sharp で PNG に変換する + * せっかくなので内部処理で使われる最大サイズの299x299に事前にリサイズする + */ + const png = await (await sharpBmp(source, mime)) + .resize(299, 299, { + withoutEnlargement: false, + }) + .rotate() + .flatten({ background: { r: 119, g: 119, b: 119 } }) // 透過部分を18%グレーで塗りつぶす + .png() + .toBuffer(); + const result = await this.aiService.detectSensitive(png); + if (result) { + [sensitive, porn] = judgePrediction(result); + } } return [sensitive, porn]; @@ -309,7 +339,7 @@ export class FileInfoService { } @bindThis - public fixMime(mime: string | fileType.MimeType): string { + public fixMime(mime: string): string { // see https://github.com/misskey-dev/misskey/pull/10686 if (mime === 'audio/x-flac') { return 'audio/flac'; diff --git a/packages/backend/src/core/FlashService.ts b/packages/backend/src/core/FlashService.ts index 2a98225382..8caffe9e45 100644 --- a/packages/backend/src/core/FlashService.ts +++ b/packages/backend/src/core/FlashService.ts @@ -4,8 +4,11 @@ */ import { Inject, Injectable } from '@nestjs/common'; +import { Brackets } from 'typeorm'; import { DI } from '@/di-symbols.js'; -import { type FlashsRepository } from '@/models/_.js'; +import { type FlashLikesRepository, MiUser, type FlashsRepository } from '@/models/_.js'; +import { QueryService } from '@/core/QueryService.js'; +import { sqlLikeEscape } from '@/misc/sql-like-escape.js'; /** * MisskeyPlay関係のService @@ -15,6 +18,11 @@ export class FlashService { constructor( @Inject(DI.flashsRepository) private flashRepository: FlashsRepository, + + @Inject(DI.flashLikesRepository) + private flashLikesRepository: FlashLikesRepository, + + private queryService: QueryService, ) { } @@ -37,4 +45,43 @@ export class FlashService { return await builder.getMany(); } + + public async myLikes(meId: MiUser['id'], opts: { sinceId?: string, untilId?: string, sinceDate?: number, untilDate?: number, limit?: number, search?: string | null }) { + const query = this.queryService.makePaginationQuery(this.flashLikesRepository.createQueryBuilder('like'), opts.sinceId, opts.untilId, opts.sinceDate, opts.untilDate) + .andWhere('like.userId = :meId', { meId }) + .leftJoinAndSelect('like.flash', 'flash'); + + if (opts.search != null) { + for (const word of opts.search.trim().split(' ')) { + query.andWhere(new Brackets(qb => { + qb.orWhere('flash.title ILIKE :search', { search: `%${sqlLikeEscape(word)}%` }); + qb.orWhere('flash.summary ILIKE :search', { search: `%${sqlLikeEscape(word)}%` }); + })); + } + } + + const likes = await query + .limit(opts.limit) + .getMany(); + + return likes; + } + + public async search(searchQuery: string, opts: { sinceId?: string, untilId?: string, sinceDate?: number, untilDate?: number, limit?: number }) { + const query = this.queryService.makePaginationQuery(this.flashRepository.createQueryBuilder('flash'), opts.sinceId, opts.untilId, opts.sinceDate, opts.untilDate) + .andWhere('flash.visibility = \'public\''); + + for (const word of searchQuery.trim().split(' ')) { + query.andWhere(new Brackets(qb => { + qb.orWhere('flash.title ILIKE :search', { search: `%${sqlLikeEscape(word)}%` }); + qb.orWhere('flash.summary ILIKE :search', { search: `%${sqlLikeEscape(word)}%` }); + })); + } + + const result = await query + .limit(opts.limit) + .getMany(); + + return result; + } } diff --git a/packages/backend/src/core/HttpRequestService.ts b/packages/backend/src/core/HttpRequestService.ts index fb041274c5..fb811eca57 100644 --- a/packages/backend/src/core/HttpRequestService.ts +++ b/packages/backend/src/core/HttpRequestService.ts @@ -6,6 +6,7 @@ import * as http from 'node:http'; import * as https from 'node:https'; import * as net from 'node:net'; +import * as stream from 'node:stream'; import ipaddr from 'ipaddr.js'; import CacheableLookup from 'cacheable-lookup'; import fetch from 'node-fetch'; @@ -26,12 +27,6 @@ export type HttpRequestSendOptions = { validators?: ((res: Response) => void)[]; }; -declare module 'node:http' { - interface Agent { - createConnection(options: net.NetConnectOpts, callback?: (err: unknown, stream: net.Socket) => void): net.Socket; - } -} - class HttpRequestServiceAgent extends http.Agent { constructor( private config: Config, @@ -41,18 +36,24 @@ class HttpRequestServiceAgent extends http.Agent { } @bindThis - public createConnection(options: net.NetConnectOpts, callback?: (err: unknown, stream: net.Socket) => void): net.Socket { - const socket = super.createConnection(options, callback) - .on('connect', () => { + public createConnection(options: http.ClientRequestArgs, callback?: (err: Error | null, stream: stream.Duplex) => void): stream.Duplex { + const socket = super.createConnection(options, callback); + + if (socket == null) { + throw new Error('Failed to create socket'); + } + + socket.on('connect', () => { + if (socket instanceof net.Socket && process.env.NODE_ENV === 'production') { const address = socket.remoteAddress; - if (process.env.NODE_ENV === 'production') { - if (address && ipaddr.isValid(address)) { - if (this.isPrivateIp(address)) { - socket.destroy(new Error(`Blocked address: ${address}`)); - } + if (address && ipaddr.isValid(address)) { + if (this.isPrivateIp(address)) { + socket.destroy(new Error(`Blocked address: ${address}`)); } } - }); + } + }); + return socket; } @@ -80,18 +81,24 @@ class HttpsRequestServiceAgent extends https.Agent { } @bindThis - public createConnection(options: net.NetConnectOpts, callback?: (err: unknown, stream: net.Socket) => void): net.Socket { - const socket = super.createConnection(options, callback) - .on('connect', () => { + public createConnection(options: http.ClientRequestArgs, callback?: (err: Error | null, stream: stream.Duplex) => void): stream.Duplex { + const socket = super.createConnection(options, callback); + + if (socket == null) { + throw new Error('Failed to create socket'); + } + + socket.on('connect', () => { + if (socket instanceof net.Socket && process.env.NODE_ENV === 'production') { const address = socket.remoteAddress; - if (process.env.NODE_ENV === 'production') { - if (address && ipaddr.isValid(address)) { - if (this.isPrivateIp(address)) { - socket.destroy(new Error(`Blocked address: ${address}`)); - } + if (address && ipaddr.isValid(address)) { + if (this.isPrivateIp(address)) { + socket.destroy(new Error(`Blocked address: ${address}`)); } } - }); + } + }); + return socket; } diff --git a/packages/backend/src/core/NoteCreateService.ts b/packages/backend/src/core/NoteCreateService.ts index f346bb2366..f441760587 100644 --- a/packages/backend/src/core/NoteCreateService.ts +++ b/packages/backend/src/core/NoteCreateService.ts @@ -15,7 +15,7 @@ import type { IMentionedRemoteUsers } from '@/models/Note.js'; import { MiNote } from '@/models/Note.js'; import { MiEvent } from '@/models/Event.js'; import type { IEvent } from '@/models/Event.js'; -import type { ChannelFollowingsRepository, ChannelsRepository, FollowingsRepository, InstancesRepository, MiFollowing, MiMeta, MutingsRepository, NotesRepository, NoteThreadMutingsRepository, UserListMembershipsRepository, UserProfilesRepository, UsersRepository } from '@/models/_.js'; +import type { BlockingsRepository, ChannelFollowingsRepository, ChannelsRepository, DriveFilesRepository, FollowingsRepository, InstancesRepository, MiFollowing, MiMeta, MutingsRepository, NotesRepository, NoteThreadMutingsRepository, UserListMembershipsRepository, UserProfilesRepository, UsersRepository } from '@/models/_.js'; import type { MiDriveFile } from '@/models/DriveFile.js'; import type { MiApp } from '@/models/App.js'; import { concat } from '@/misc/prelude/array.js'; @@ -58,6 +58,7 @@ import { trackPromise } from '@/misc/promise-tracker.js'; import { IdentifiableError } from '@/misc/identifiable-error.js'; import { CollapsedQueue } from '@/misc/collapsed-queue.js'; import { CacheService } from '@/core/CacheService.js'; +import { isQuote, isRenote } from '@/misc/is-renote.js'; type NotificationType = 'reply' | 'renote' | 'quote' | 'mention'; @@ -199,6 +200,12 @@ export class NoteCreateService implements OnApplicationShutdown { @Inject(DI.channelFollowingsRepository) private channelFollowingsRepository: ChannelFollowingsRepository, + @Inject(DI.blockingsRepository) + private blockingsRepository: BlockingsRepository, + + @Inject(DI.driveFilesRepository) + private driveFilesRepository: DriveFilesRepository, + private userEntityService: UserEntityService, private noteEntityService: NoteEntityService, private idService: IdService, @@ -228,6 +235,185 @@ export class NoteCreateService implements OnApplicationShutdown { this.updateNotesCountQueue = new CollapsedQueue(process.env.NODE_ENV !== 'test' ? 60 * 1000 * 5 : 0, this.collapseNotesCount, this.performUpdateNotesCount); } + @bindThis + public async fetchAndCreate(user: { + id: MiUser['id']; + username: MiUser['username']; + host: MiUser['host']; + isBot: MiUser['isBot']; + isCat: MiUser['isCat']; + }, data: { + createdAt: Date; + updatedAt?: Date | null; + replyId: MiNote['id'] | null; + renoteId: MiNote['id'] | null; + fileIds: MiDriveFile['id'][]; + text: string | null; + cw: string | null; + visibility: string; + visibleUserIds: MiUser['id'][]; + channelId: MiChannel['id'] | null; + localOnly: boolean; + reactionAcceptance: MiNote['reactionAcceptance']; + disableRightClick: boolean | null; + poll: IPoll | null; + event: IEvent | null; + apMentions?: MinimumUser[] | null; + apHashtags?: string[] | null; + apEmojis?: string[] | null; + deleteAt?: Date | null; + deliveryTargets?: { mode: 'include' | 'exclude'; hosts: string[] } | null; + }): Promise { + const visibleUsers = data.visibleUserIds.length > 0 ? await this.usersRepository.findBy({ + id: In(data.visibleUserIds), + }) : []; + + let files: MiDriveFile[] = []; + if (data.fileIds.length > 0) { + files = await this.driveFilesRepository.createQueryBuilder('file') + .where('file.userId = :userId AND file.id IN (:...fileIds)', { + userId: user.id, + fileIds: data.fileIds, + }) + .orderBy('array_position(ARRAY[:...fileIds], "id"::text)') + .setParameters({ fileIds: data.fileIds }) + .getMany(); + + if (files.length !== data.fileIds.length) { + throw new IdentifiableError('801c046c-5bf5-4234-ad2b-e78fc20a2ac7', 'No such file'); + } + } + + let renote: MiNote | null = null; + if (data.renoteId != null) { + // Fetch renote to note + renote = await this.notesRepository.findOne({ + where: { id: data.renoteId }, + relations: ['user', 'renote', 'reply'], + }); + + if (renote == null) { + throw new IdentifiableError('53983c56-e163-45a6-942f-4ddc485d4290', 'No such renote target'); + } else if (isRenote(renote) && !isQuote(renote)) { + throw new IdentifiableError('bde24c37-121f-4e7d-980d-cec52f599f02', 'Cannot renote pure renote'); + } + + // Check blocking + if (renote.userId !== user.id) { + const blockExist = await this.blockingsRepository.exists({ + where: { + blockerId: renote.userId, + blockeeId: user.id, + }, + }); + if (blockExist) { + throw new IdentifiableError('2b4fe776-4414-4a2d-ae39-f3418b8fd4d3', 'You have been blocked by the user'); + } + } + + if (renote.visibility === 'followers' && renote.userId !== user.id) { + // 他人のfollowers noteはreject + throw new IdentifiableError('90b9d6f0-893a-4fef-b0f1-e9a33989f71a', 'Renote target visibility'); + } else if (renote.visibility === 'specified') { + // specified / direct noteはreject + throw new IdentifiableError('48d7a997-da5c-4716-b3c3-92db3f37bf7d', 'Renote target visibility'); + } + + if (renote.channelId && renote.channelId !== data.channelId) { + // チャンネルのノートに対しリノート要求がきたとき、チャンネル外へのリノート可否をチェック + // リノートのユースケースのうち、チャンネル内→チャンネル外は少数だと考えられるため、JOINはせず必要な時に都度取得する + const renoteChannel = await this.channelsRepository.findOneBy({ id: renote.channelId }); + if (renoteChannel == null) { + // リノートしたいノートが書き込まれているチャンネルが無い + throw new IdentifiableError('b060f9a6-8909-4080-9e0b-94d9fa6f6a77', 'No such channel'); + } else if (!renoteChannel.allowRenoteToExternal) { + // リノート作成のリクエストだが、対象チャンネルがリノート禁止だった場合 + throw new IdentifiableError('7e435f4a-780d-4cfc-a15a-42519bd6fb67', 'Channel does not allow renote to external'); + } + } + } + + let reply: MiNote | null = null; + if (data.replyId != null) { + // Fetch reply + reply = await this.notesRepository.findOne({ + where: { id: data.replyId }, + relations: ['user'], + }); + + if (reply == null) { + throw new IdentifiableError('60142edb-1519-408e-926d-4f108d27bee0', 'No such reply target'); + } else if (isRenote(reply) && !isQuote(reply)) { + throw new IdentifiableError('f089e4e2-c0e7-4f60-8a23-e5a6bf786b36', 'Cannot reply to pure renote'); + } else if (!await this.noteEntityService.isVisibleForMe(reply, user.id)) { + throw new IdentifiableError('11cd37b3-a411-4f77-8633-c580ce6a8dce', 'No such reply target'); + } else if (reply.visibility === 'specified' && data.visibility !== 'specified') { + throw new IdentifiableError('ced780a1-2012-4caf-bc7e-a95a291294cb', 'Cannot reply to specified note with different visibility'); + } + + // Check blocking + if (reply.userId !== user.id) { + const blockExist = await this.blockingsRepository.exists({ + where: { + blockerId: reply.userId, + blockeeId: user.id, + }, + }); + if (blockExist) { + throw new IdentifiableError('b0df6025-f2e8-44b4-a26a-17ad99104612', 'You have been blocked by the user'); + } + } + } + + if (data.poll) { + if (data.poll.expiresAt != null) { + if (data.poll.expiresAt.getTime() < Date.now()) { + throw new IdentifiableError('0c11c11e-0c8d-48e7-822c-76ccef660068', 'Poll expiration must be future time'); + } + } + } + + if (data.event) { + if (data.event.end != null) { + if (data.event.end.getTime() < Date.now()) { + throw new IdentifiableError('4d0d475c-2d2f-4f4f-a581-7fa54b501e52', 'Event end time must be future time'); + } + } + } + + let channel: MiChannel | null = null; + if (data.channelId != null) { + channel = await this.channelsRepository.findOneBy({ id: data.channelId, isArchived: false }); + + if (channel == null) { + throw new IdentifiableError('bfa3905b-25f5-4894-b430-da331a490e4b', 'No such channel'); + } + } + + return this.create(user, { + createdAt: data.createdAt, + updatedAt: data.updatedAt, + files: files, + poll: data.poll, + event: data.event, + text: data.text, + reply, + renote, + cw: data.cw, + localOnly: data.localOnly, + reactionAcceptance: data.reactionAcceptance, + disableRightClick: data.disableRightClick, + visibility: data.visibility, + visibleUsers, + channel, + apMentions: data.apMentions, + apHashtags: data.apHashtags, + apEmojis: data.apEmojis, + deleteAt: data.deleteAt, + deliveryTargets: data.deliveryTargets, + }); + } + @bindThis public async create(user: { id: MiUser['id']; @@ -446,7 +632,7 @@ export class NoteCreateService implements OnApplicationShutdown { emojis, userId: user.id, localOnly: data.localOnly!, - reactionAcceptance: data.reactionAcceptance, + reactionAcceptance: data.reactionAcceptance ?? null, disableRightClick: data.disableRightClick!, deleteAt: data.deleteAt, deliveryTargets: data.deliveryTargets ?? null, @@ -528,7 +714,11 @@ export class NoteCreateService implements OnApplicationShutdown { await this.notesRepository.insert(insert); } - return insert; + return { + ...insert, + reply: data.reply ?? null, + renote: data.renote ?? null, + }; } catch (e) { // duplicate key error if (isDuplicateKeyValueError(e)) { @@ -710,11 +900,8 @@ export class NoteCreateService implements OnApplicationShutdown { // フォロワーに配送 if (['public', 'home', 'followers'].includes(note.visibility)) { - if (data.deliveryTargets) { - dm.addSelectiveFollowersRecipe(data.deliveryTargets); - } else { - dm.addFollowersRecipe(); - } + if (data.deliveryTargets) dm.addSelectiveFollowersRecipe(data.deliveryTargets); + else dm.addFollowersRecipe(); } if (['public'].includes(note.visibility)) { diff --git a/packages/backend/src/core/NoteDeleteService.ts b/packages/backend/src/core/NoteDeleteService.ts index cec1384605..af1f0eda9a 100644 --- a/packages/backend/src/core/NoteDeleteService.ts +++ b/packages/backend/src/core/NoteDeleteService.ts @@ -62,7 +62,6 @@ export class NoteDeleteService { */ async delete(user: { id: MiUser['id']; uri: MiUser['uri']; host: MiUser['host']; isBot: MiUser['isBot']; }, note: MiNote, quiet = false, deleter?: MiUser) { const deletedAt = new Date(); - // const cascadingNotes = await this.findCascadingNotes(note); if (note.replyId) { await this.notesRepository.decrement({ id: note.replyId }, 'repliesCount', 1); @@ -90,17 +89,6 @@ export class NoteDeleteService { this.deliverToConcerned(user, note, content); } - - /* - // also deliver delete activity to cascaded notes - const federatedLocalCascadingNotes = (cascadingNotes).filter(note => !note.localOnly && note.userHost == null); // filter out local-only notes - for (const cascadingNote of federatedLocalCascadingNotes) { - if (!cascadingNote.user) continue; - if (!this.userEntityService.isLocalUser(cascadingNote.user)) continue; - const content = this.apRendererService.addContext(this.apRendererService.renderDelete(this.apRendererService.renderTombstone(`${this.config.url}/notes/${cascadingNote.id}`), cascadingNote.user)); - this.deliverToConcerned(cascadingNote.user, cascadingNote, content); - } - */ //#endregion this.notesChart.update(note, false); @@ -120,11 +108,6 @@ export class NoteDeleteService { } } - /* - for (const cascadingNote of cascadingNotes) { - this.searchService.unindexNote(cascadingNote); - } - */ this.searchService.unindexNote(note); await this.notesRepository.delete({ @@ -144,31 +127,6 @@ export class NoteDeleteService { } } - /* - @bindThis - private async findCascadingNotes(note: MiNote): Promise { - const recursive = async (noteId: string): Promise => { - const query = this.notesRepository.createQueryBuilder('note') - .where('note.replyId = :noteId', { noteId }) - .orWhere(new Brackets(q => { - q.where('note.renoteId = :noteId', { noteId }) - .andWhere('note.text IS NOT NULL'); - })) - .leftJoinAndSelect('note.user', 'user'); - const replies = await query.getMany(); - - return [ - replies, - ...await Promise.all(replies.map(reply => recursive(reply.id))), - ].flat(); - }; - - const cascadingNotes: MiNote[] = await recursive(note.id); - - return cascadingNotes; - } - */ - @bindThis private async getMentionedRemoteUsers(note: MiNote) { const where = [] as any[]; diff --git a/packages/backend/src/core/NoteDraftService.ts b/packages/backend/src/core/NoteDraftService.ts index 7c30ed6fd8..619b6ab592 100644 --- a/packages/backend/src/core/NoteDraftService.ts +++ b/packages/backend/src/core/NoteDraftService.ts @@ -4,43 +4,48 @@ */ import { Inject, Injectable } from '@nestjs/common'; +import { In } from 'typeorm'; import type { noteVisibilities, noteReactionAcceptances } from '@/types.js'; import { DI } from '@/di-symbols.js'; -import type { MiNoteDraft, NoteDraftsRepository, MiNote, MiDriveFile, MiChannel } from '@/models/_.js'; +import type { MiNoteDraft, NoteDraftsRepository, MiNote, MiDriveFile, MiChannel, UsersRepository, DriveFilesRepository, NotesRepository, BlockingsRepository, ChannelsRepository } from '@/models/_.js'; import { bindThis } from '@/decorators.js'; import { RoleService } from '@/core/RoleService.js'; import { IdService } from '@/core/IdService.js'; import type { MiLocalUser, MiUser } from '@/models/User.js'; import { IPoll } from '@/models/Poll.js'; import { IdentifiableError } from '@/misc/identifiable-error.js'; +import { isRenote, isQuote } from '@/misc/is-renote.js'; +import { NoteEntityService } from '@/core/entities/NoteEntityService.js'; +import { QueueService } from '@/core/QueueService.js'; import type { IEvent } from '@/models/Event.js'; -export type NoteDraftOptions = { - reply?: MiNote | null; - renote?: MiNote | null; - text?: string | null; - cw?: string | null; - localOnly?: boolean | null; - reactionAcceptance?: typeof noteReactionAcceptances[number]; - visibility?: typeof noteVisibilities[number]; - files?: MiDriveFile[]; - visibleUsers?: MiUser[]; - hashtag?: string; - channel?: MiChannel | null; - poll?: (IPoll & { expiredAfter?: number | null }) | null; - event?: IEvent | null; - disableRightClick?: boolean | null; - deleteAt?: Date | null; -}; +export type NoteDraftOptions = Omit; @Injectable() export class NoteDraftService { constructor( + @Inject(DI.blockingsRepository) + private blockingsRepository: BlockingsRepository, + @Inject(DI.noteDraftsRepository) private noteDraftsRepository: NoteDraftsRepository, + @Inject(DI.notesRepository) + private notesRepository: NotesRepository, + + @Inject(DI.usersRepository) + private usersRepository: UsersRepository, + + @Inject(DI.driveFilesRepository) + private driveFilesRepository: DriveFilesRepository, + + @Inject(DI.channelsRepository) + private channelsRepository: ChannelsRepository, + private roleService: RoleService, private idService: IdService, + private noteEntityService: NoteEntityService, + private queueService: QueueService, ) { } @@ -56,97 +61,83 @@ export class NoteDraftService { @bindThis public async create(me: MiLocalUser, data: NoteDraftOptions): Promise { - if (data.visibility == null) data.visibility = 'public'; - if (data.localOnly == null) data.localOnly = false; - if (data.reactionAcceptance === undefined) data.reactionAcceptance = null; - if (data.disableRightClick == null) data.disableRightClick = false; - if (data.channel != null) { - data.visibility = 'public'; - data.visibleUsers = []; - data.localOnly = true; - } + //#region check draft limit + const policies = await this.roleService.getUserPolicies(me.id); const currentCount = await this.noteDraftsRepository.countBy({ userId: me.id, }); - if (currentCount >= (await this.roleService.getUserPolicies(me.id)).noteDraftLimit) { - throw new IdentifiableError('c9a2c1d8-d153-40be-9cac-9fc2eb56b581', 'Too many drafts'); + if (currentCount >= policies.noteDraftLimit) { + throw new IdentifiableError('9ee33bbe-fde3-4c71-9b51-e50492c6b9c8', 'Too many drafts'); + } + + if (data.isActuallyScheduled) { + const currentScheduledCount = await this.noteDraftsRepository.countBy({ + userId: me.id, + isActuallyScheduled: true, + }); + if (currentScheduledCount >= policies.scheduledNoteLimit) { + throw new IdentifiableError('c3275f19-4558-4c59-83e1-4f684b5fab66', 'Too many scheduled notes'); + } } + //#endregion + + await this.validate(me, data); const draft = await this.noteDraftsRepository.insertOne({ + ...data, id: this.idService.gen(), - visibility: data.visibility, - cw: data.cw, - fileIds: data.files ? data.files.map(file => file.id) : [], - replyId: data.reply ? data.reply.id : null, - renoteId: data.renote ? data.renote.id : null, - channelId: data.channel ? data.channel.id : null, - text: data.text ?? null, - hashtag: data.hashtag, - hasPoll: data.poll != null, - hasEvent: data.event != null, - pollChoices: data.poll ? data.poll.choices : [], - pollMultiple: data.poll ? data.poll.multiple : false, - pollExpiresAt: data.poll ? data.poll.expiresAt : null, - pollExpiredAfter: data.poll ? data.poll.expiredAfter : null, - eventTitle: data.event ? data.event.title : undefined, - eventStart: data.event ? data.event.start : undefined, - eventEnd: data.event ? data.event.end : undefined, - eventMetadata: data.event ? data.event.metadata : {}, - localOnly: data.localOnly, - disableRightClick: data.disableRightClick!, - deleteAt: data.deleteAt, - visibleUserIds: data.visibleUsers ? data.visibleUsers.map(user => user.id) : [], userId: me.id, }); + if (draft.scheduledAt && draft.isActuallyScheduled) { + this.schedule(draft); + } + return draft; } @bindThis - public async update(me: MiLocalUser, draftId: MiNoteDraft['id'], data: NoteDraftOptions): Promise { - if (data.visibility == null) data.visibility = 'public'; - if (data.localOnly == null) data.localOnly = false; - if (data.reactionAcceptance === undefined) data.reactionAcceptance = null; - if (data.channel != null) { - data.visibility = 'public'; - data.visibleUsers = []; - data.localOnly = true; - } - + public async update(me: MiLocalUser, draftId: MiNoteDraft['id'], data: Partial): Promise { const draft = await this.noteDraftsRepository.findOneBy({ id: draftId, userId: me.id, }); if (draft == null) { - throw new IdentifiableError('03a9514d-ff73-4c48-a55a-0282c8311ec6', 'No such note draft'); + throw new IdentifiableError('49cd6b9d-848e-41ee-b0b9-adaca711a6b1', 'No such note draft'); } - await this.noteDraftsRepository.update(draft.id, { - visibility: data.visibility, - cw: data.cw, - fileIds: data.files ? data.files.map(file => file.id) : [], - replyId: data.reply ? data.reply.id : null, - renoteId: data.renote ? data.renote.id : null, - channelId: data.channel ? data.channel.id : null, - text: data.text ?? null, - hashtag: data.hashtag, - hasPoll: data.poll != null, - hasEvent: data.event != null, - pollChoices: data.poll ? data.poll.choices : [], - pollMultiple: data.poll ? data.poll.multiple : false, - pollExpiresAt: data.poll ? data.poll.expiresAt : null, - pollExpiredAfter: data.poll ? data.poll.expiredAfter : null, - eventTitle: data.event?.title, - eventStart: data.event?.start, - eventEnd: data.event?.end ?? undefined, - eventMetadata: data.event ? data.event.metadata : {}, - visibleUserIds: data.visibleUsers ? data.visibleUsers.map(user => user.id) : [], - localOnly: data.localOnly, - disableRightClick: data.disableRightClick!, - deleteAt: data.deleteAt, + //#region check draft limit + const policies = await this.roleService.getUserPolicies(me.id); + + if (!draft.isActuallyScheduled && data.isActuallyScheduled) { + const currentScheduledCount = await this.noteDraftsRepository.countBy({ + userId: me.id, + isActuallyScheduled: true, + }); + if (currentScheduledCount >= policies.scheduledNoteLimit) { + throw new IdentifiableError('bacdf856-5c51-4159-b88a-804fa5103be5', 'Too many scheduled notes'); + } + } + //#endregion + + await this.validate(me, data); + + const updatedDraft = await this.noteDraftsRepository.createQueryBuilder().update() + .set(data) + .where('id = :id', { id: draftId }) + .returning('*') + .execute() + .then((response) => response.raw[0]); + + this.clearSchedule(draftId).then(() => { + if (updatedDraft.scheduledAt != null && updatedDraft.isActuallyScheduled) { + this.schedule(updatedDraft); + } }); + + return updatedDraft; } @bindThis @@ -157,9 +148,195 @@ export class NoteDraftService { }); if (draft == null) { - throw new IdentifiableError('03a9514d-ff73-4c48-a55a-0282c8311ec6', 'No such note draft'); + throw new IdentifiableError('49cd6b9d-848e-41ee-b0b9-adaca711a6b1', 'No such note draft'); } await this.noteDraftsRepository.delete(draft.id); + + this.clearSchedule(draftId); + } + + @bindThis + public async getDraft(me: MiLocalUser, draftId: MiNoteDraft['id']): Promise { + const draft = await this.noteDraftsRepository.findOneBy({ + id: draftId, + userId: me.id, + }); + + if (draft == null) { + throw new IdentifiableError('49cd6b9d-848e-41ee-b0b9-adaca711a6b1', 'No such note draft'); + } + + return draft; + } + + @bindThis + public async validate( + me: MiLocalUser, + data: Partial, + ): Promise { + if (data.isActuallyScheduled) { + if (data.scheduledAt == null) { + throw new IdentifiableError('94a89a43-3591-400a-9c17-dd166e71fdfa', 'scheduledAt is required when isActuallyScheduled is true'); + } else if (data.scheduledAt.getTime() < Date.now()) { + throw new IdentifiableError('b34d0c1b-996f-4e34-a428-c636d98df457', 'scheduledAt must be in the future'); + } + } + + if (data.pollExpiresAt != null) { + if (data.pollExpiresAt.getTime() < Date.now()) { + throw new IdentifiableError('04da457d-b083-4055-9082-955525eda5a5', 'Cannot create expired poll'); + } + } + + //#region visibleUsers + let visibleUsers: MiUser[] = []; + if (data.visibleUserIds != null && data.visibleUserIds.length > 0) { + visibleUsers = await this.usersRepository.findBy({ + id: In(data.visibleUserIds), + }); + } + //#endregion + + //#region files + let files: MiDriveFile[] = []; + const fileIds = data.fileIds ?? null; + if (fileIds != null && fileIds.length > 0) { + files = await this.driveFilesRepository.createQueryBuilder('file') + .where('file.userId = :userId AND file.id IN (:...fileIds)', { + userId: me.id, + fileIds: fileIds, + }) + .orderBy('array_position(ARRAY[:...fileIds], "id"::text)') + .setParameters({ fileIds }) + .getMany(); + + if (files.length !== fileIds.length) { + throw new IdentifiableError('b6992544-63e7-67f0-fa7f-32444b1b5306', 'No such drive file'); + } + } + //#endregion + + //#region renote + let renote: MiNote | null = null; + if (data.renoteId != null) { + renote = await this.notesRepository.findOneBy({ id: data.renoteId }); + + if (renote == null) { + throw new IdentifiableError('64929870-2540-4d11-af41-3b484d78c956', 'No such renote'); + } else if (isRenote(renote) && !isQuote(renote)) { + throw new IdentifiableError('76cc5583-5a14-4ad3-8717-0298507e32db', 'Cannot renote'); + } + + // Check blocking + if (renote.userId !== me.id) { + const blockExist = await this.blockingsRepository.exists({ + where: { + blockerId: renote.userId, + blockeeId: me.id, + }, + }); + if (blockExist) { + throw new IdentifiableError('075ca298-e6e7-485a-b570-51a128bb5168', 'You have been blocked by the user'); + } + } + + if (renote.visibility === 'followers' && renote.userId !== me.id) { + // 他人のfollowers noteはreject + throw new IdentifiableError('81eb8188-aea1-4e35-9a8f-3334a3be9855', 'Cannot Renote Due to Visibility'); + } else if (renote.visibility === 'specified') { + // specified / direct noteはreject + throw new IdentifiableError('81eb8188-aea1-4e35-9a8f-3334a3be9855', 'Cannot Renote Due to Visibility'); + } + + if (renote.channelId && renote.channelId !== data.channelId) { + // チャンネルのノートに対しリノート要求がきたとき、チャンネル外へのリノート可否をチェック + // リノートのユースケースのうち、チャンネル内→チャンネル外は少数だと考えられるため、JOINはせず必要な時に都度取得する + const renoteChannel = await this.channelsRepository.findOneBy({ id: renote.channelId }); + if (renoteChannel == null) { + // リノートしたいノートが書き込まれているチャンネルがない + throw new IdentifiableError('6815399a-6f13-4069-b60d-ed5156249d12', 'No such channel'); + } else if (!renoteChannel.allowRenoteToExternal) { + // リノート作成のリクエストだが、対象チャンネルがリノート禁止だった場合 + throw new IdentifiableError('ed1952ac-2d26-4957-8b30-2deda76bedf7', 'Cannot Renote to External'); + } + } + } + //#endregion + + //#region reply + let reply: MiNote | null = null; + if (data.replyId != null) { + // Fetch reply + reply = await this.notesRepository.findOneBy({ id: data.replyId }); + + if (reply == null) { + throw new IdentifiableError('c4721841-22fc-4bb7-ad3d-897ef1d375b5', 'No such reply'); + } else if (isRenote(reply) && !isQuote(reply)) { + throw new IdentifiableError('e6c10b57-2c09-4da3-bd4d-eda05d51d140', 'Cannot reply To Pure Renote'); + } else if (!await this.noteEntityService.isVisibleForMe(reply, me.id)) { + throw new IdentifiableError('593c323c-6b6a-4501-a25c-2f36bd2a93d6', 'Cannot reply To Invisible Note'); + } else if (reply.visibility === 'specified' && data.visibility !== 'specified') { + throw new IdentifiableError('215dbc76-336c-4d2a-9605-95766ba7dab0', 'Cannot reply To Specified Note With Extended Visibility'); + } + + // Check blocking + if (reply.userId !== me.id) { + const blockExist = await this.blockingsRepository.exists({ + where: { + blockerId: reply.userId, + blockeeId: me.id, + }, + }); + if (blockExist) { + throw new IdentifiableError('075ca298-e6e7-485a-b570-51a128bb5168', 'You have been blocked by the user'); + } + } + } + //#endregion + + //#region channel + let channel: MiChannel | null = null; + if (data.channelId != null) { + channel = await this.channelsRepository.findOneBy({ id: data.channelId, isArchived: false }); + + if (channel == null) { + throw new IdentifiableError('6815399a-6f13-4069-b60d-ed5156249d12', 'No such channel'); + } + } + //#endregion + } + + @bindThis + public async schedule(draft: MiNoteDraft): Promise { + if (!draft.isActuallyScheduled) return; + if (draft.scheduledAt == null) return; + if (draft.scheduledAt.getTime() <= Date.now()) return; + + const delay = draft.scheduledAt.getTime() - Date.now(); + this.queueService.postScheduledNoteQueue.add(draft.id, { + noteDraftId: draft.id, + }, { + delay, + removeOnComplete: { + age: 3600 * 24 * 7, // keep up to 7 days + count: 30, + }, + removeOnFail: { + age: 3600 * 24 * 7, // keep up to 7 days + count: 100, + }, + }); + } + + @bindThis + public async clearSchedule(draftId: MiNoteDraft['id']): Promise { + // TODO: 線形探索なのをどうにかする + const jobs = await this.queueService.postScheduledNoteQueue.getJobs(['delayed', 'waiting', 'active']); + for (const job of jobs) { + if (job.data.noteDraftId === draftId) { + await job.remove(); + } + } } } diff --git a/packages/backend/src/core/NoteHistoryService.ts b/packages/backend/src/core/NoteHistoryService.ts new file mode 100644 index 0000000000..c34748d68b --- /dev/null +++ b/packages/backend/src/core/NoteHistoryService.ts @@ -0,0 +1,167 @@ +/* + * SPDX-FileCopyrightText: noridev and cherrypick-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { Inject, Injectable, OnApplicationShutdown } from '@nestjs/common'; +import { LessThan, MoreThan } from 'typeorm'; +import { MiNote } from '@/models/Note.js'; +import Logger from '@/logger.js'; +import { IdService } from '@/core/IdService.js'; + +import { DI } from '@/di-symbols.js'; +import type { NoteHistoryRepository, PollsRepository, EventsRepository } from '@/models/_.js'; +import { bindThis } from '@/decorators.js'; +import { NoteHistory } from '@/models/NoteHistory.js'; +import { LoggerService } from './LoggerService.js'; +import { AppLockService } from './AppLockService.js'; + +type Option = { + updatedAt?: Date | null; +}; + +@Injectable() +export class NoteHistorySerivce implements OnApplicationShutdown { + #shutdownController = new AbortController(); + private logger: Logger; + constructor ( + @Inject(DI.noteHistoryRepository) + private noteHistoryRepository: NoteHistoryRepository, + + @Inject(DI.pollsRepository) + private pollsRepository: PollsRepository, + + @Inject(DI.eventsRepository) + private eventsRepository: EventsRepository, + + private idService: IdService, + + private loggerService: LoggerService, + private appLockService: AppLockService, + + ) { + this.logger = this.loggerService.getLogger('NoteHistorySerivce'); + } + + /** + * Back up contents of the current note to the history record. + * @param newData Update된 노트 + * @param originalNote Update 되기 전의 원래 노트 내용 + * @param originalPoll Update 되기 전의 원래 poll 데이터 + * @param originalEvent Update 되기 전의 원래 event 데이터 + * @param options 옵션 + */ + @bindThis + public async recordHistory ( + newData: MiNote, + originalNote: MiNote, + originalPoll: NoteHistory['poll'] | null, + originalEvent: NoteHistory['event'] | null, + options: Option, + ) { + const unlock = await this.appLockService.getApLock(`record-note-history:${originalNote.id}`); + + try { + // 이전에 이미 기록된 히스토리가 있는 경우 가장 최근의 히스토리를 가져오기 + const lastRecord = await this.noteHistoryRepository.findOne({ + where: { noteId: originalNote.id }, + order: { id: 'DESC' }, + }); + + const lastRecord_createdAt = lastRecord?.updatedAt ?? this.idService.parse(originalNote.id).date; + + const history_data: NoteHistory = { + id: this.idService.gen(new Date().getTime()), + noteId: originalNote.id, + createdAt: lastRecord_createdAt, // 백업할 원래 노트가 만들어졌던 시간 + updatedAt: options.updatedAt ?? new Date(), // 노트가 수정된 시간 (현재) + userId: originalNote.userId, + fileIds: originalNote.fileIds, + attachedFileTypes: originalNote.attachedFileTypes, + emojis: originalNote.emojis, + text: originalNote.text, + cw: originalNote.cw, + poll: originalPoll, + event: originalEvent, + visibility: originalNote.visibility, + visibleUserIds: originalNote.visibleUserIds, + }; + + const newFileIds = newData.fileIds; + const lastRecordFileIds = lastRecord?.fileIds; + const originalFileIds = originalNote.fileIds; + + const textChanged = newData.text !== originalNote.text; + const cwChanged = newData.cw !== originalNote.cw; + const filesChanged = newFileIds.length !== originalFileIds.length || !newFileIds.every((v) => originalFileIds.includes(v)); + + let pollChanged = newData.hasPoll !== originalNote.hasPoll; + if (!pollChanged && originalPoll && lastRecord?.poll) { + pollChanged = + originalPoll.choices.length !== lastRecord.poll.choices.length || + !originalPoll.choices.every((choice, i) => choice === lastRecord.poll!.choices[i]) || + originalPoll.multiple !== lastRecord.poll.multiple || + originalPoll.expiresAt?.getTime() !== (lastRecord.poll.expiresAt ? new Date(lastRecord.poll.expiresAt).getTime() : null); + } + + let eventChanged = newData.hasEvent !== originalNote.hasEvent; + if (!eventChanged && originalEvent && lastRecord?.event) { + eventChanged = + originalEvent.title !== lastRecord.event.title || + originalEvent.start.getTime() !== new Date(lastRecord.event.start).getTime() || + originalEvent.end?.getTime() !== (lastRecord.event.end ? new Date(lastRecord.event.end).getTime() : null) || + JSON.stringify(originalEvent.metadata) !== JSON.stringify(lastRecord.event.metadata); + } + + if (!textChanged && !cwChanged && !filesChanged && !pollChanged && !eventChanged) { + this.logger.info(`Skip Record History (No changes): ${originalNote.id}`); + } else { + this.logger.info(`Record History for: ${originalNote.id}`); + await this.noteHistoryRepository.insert(history_data); + } + } catch (e) { + this.logger.error(`Note History record Error! ${e}`); + } finally { + unlock(); + } + } + + @bindThis + public async getHistory ( + note_id: MiNote['id'], + limit: number, + sinceId?: NoteHistory['id'], + untilId?: NoteHistory['id'], + ): Promise { + this.logger.info(`Get history of note ${note_id}`); + try { + const history = await this.noteHistoryRepository.find({ + where: { + noteId: note_id, + ...(sinceId ? { id: MoreThan(sinceId) } : {}), + ...(untilId ? { id: LessThan(untilId) } : {}), + }, + take: limit, + order: { id: 'DESC' }, + }); + if (history.length > 0) { + return history; + } else { + return null; + } + } catch (e) { + this.logger.error(`Note History find error: ${e}`); + throw e; + } + } + + @bindThis + public dispose(): void { + this.#shutdownController.abort(); + } + + @bindThis + public onApplicationShutdown(signal?: string | undefined): void { + this.dispose(); + } +} diff --git a/packages/backend/src/core/NoteUpdateService.ts b/packages/backend/src/core/NoteUpdateService.ts index f134c4591b..add6830541 100644 --- a/packages/backend/src/core/NoteUpdateService.ts +++ b/packages/backend/src/core/NoteUpdateService.ts @@ -31,13 +31,7 @@ import { MiPoll, IPoll } from '@/models/Poll.js'; import { concat } from '@/misc/prelude/array.js'; import { extractHashtags } from '@/misc/extract-hashtags.js'; import { extractCustomEmojisFromMfm } from '@/misc/extract-custom-emojis-from-mfm.js'; - -type MinimumUser = { - id: MiUser['id']; - host: MiUser['host']; - username: MiUser['username']; - uri: MiUser['uri']; -}; +import { NoteHistorySerivce } from './NoteHistoryService.js'; type Option = { updatedAt?: Date | null; @@ -75,6 +69,7 @@ export class NoteUpdateService implements OnApplicationShutdown { private apRendererService: ApRendererService, private searchService: SearchService, private activeUsersChart: ActiveUsersChart, + private noteHistoryService: NoteHistorySerivce, ) { } @bindThis @@ -134,7 +129,7 @@ export class NoteUpdateService implements OnApplicationShutdown { const updatedAtHistory = note.updatedAtHistory ? note.updatedAtHistory : []; const values = new MiNote({ - updatedAt: data.updatedAt!, + updatedAt: data.updatedAt, fileIds: data.files ? data.files.map(file => file.id) : [], text: data.text, hasPoll: data.poll != null, @@ -145,20 +140,43 @@ export class NoteUpdateService implements OnApplicationShutdown { disableRightClick: data.disableRightClick!, attachedFileTypes: data.files ? data.files.map(file => file.type) : [], updatedAtHistory: [...updatedAtHistory, new Date()], - noteEditHistory: [...note.noteEditHistory, (note.cw ? note.cw + '\n' : '') + note.text!], deleteAt: data.deleteAt!, }); // 投稿を更新 try { - if ((note.hasPoll && values.hasPoll) || (note.hasEvent && values.hasEvent)) { - // Start transaction + const [originalPoll, originalEvent] = await Promise.all([ + note.hasPoll + ? this.db.getRepository(MiPoll).findOneBy({ noteId: note.id }).then(poll => + poll ? { + choices: poll.choices, + multiple: poll.multiple, + expiresAt: poll.expiresAt, + } : null, + ) + : Promise.resolve(null), + note.hasEvent + ? this.db.getRepository(MiEvent).findOneBy({ noteId: note.id }).then(event => + event ? { + title: event.title, + start: event.start, + end: event.end, + metadata: event.metadata, + } : null, + ) + : Promise.resolve(null), + ]); + + // Start transaction for any poll or event changes + const needsTransaction = note.hasPoll || values.hasPoll || note.hasEvent || values.hasEvent; + + if (needsTransaction) { await this.db.transaction(async transactionalEntityManager => { await transactionalEntityManager.update(MiNote, { id: note.id }, values); - if (values.hasPoll) { + if (note.hasPoll && values.hasPoll) { const old_poll = await transactionalEntityManager.findOneBy(MiPoll, { noteId: note.id }); - if (old_poll!.choices.toString() !== data.poll!.choices.toString() || old_poll!.multiple !== data.poll!.multiple) { + if (old_poll && (old_poll.choices.toString() !== data.poll!.choices.toString() || old_poll.multiple !== data.poll!.multiple)) { await transactionalEntityManager.delete(MiPoll, { noteId: note.id }); const poll = new MiPoll({ noteId: note.id, @@ -172,22 +190,37 @@ export class NoteUpdateService implements OnApplicationShutdown { }); await transactionalEntityManager.insert(MiPoll, poll); } + } else if (!note.hasPoll && values.hasPoll) { + const poll = new MiPoll({ + noteId: note.id, + choices: data.poll!.choices, + expiresAt: data.poll!.expiresAt, + multiple: data.poll!.multiple, + votes: new Array(data.poll!.choices.length).fill(0), + noteVisibility: note.visibility, + userId: user.id, + userHost: user.host, + }); + await transactionalEntityManager.insert(MiPoll, poll); + } else if (note.hasPoll && !values.hasPoll) { + // Remove poll + await transactionalEntityManager.delete(MiPoll, { noteId: note.id }); } - if (values.hasEvent) { + if (note.hasEvent && values.hasEvent) { const old_event = await transactionalEntityManager.findOneBy(MiEvent, { noteId: note.id }); - if ( - old_event!.start !== data.event!.start || - old_event!.end !== data.event!.end || - old_event!.title !== data.event!.title || - old_event!.metadata !== data.event!.metadata - ) { + if (old_event && ( + old_event.start !== data.event!.start || + old_event.end !== data.event!.end || + old_event.title !== data.event!.title || + old_event.metadata !== data.event!.metadata + )) { await transactionalEntityManager.delete(MiEvent, { noteId: note.id }); const event = new MiEvent({ noteId: note.id, + title: data.event!.title, start: data.event!.start, end: data.event!.end ?? undefined, - title: data.event!.title, metadata: data.event!.metadata, noteVisibility: note.visibility, userId: user.id, @@ -195,53 +228,19 @@ export class NoteUpdateService implements OnApplicationShutdown { }); await transactionalEntityManager.insert(MiEvent, event); } - } - }); - } else if ((!note.hasPoll && values.hasPoll) || (!note.hasEvent && values.hasEvent)) { - // Start transaction - await this.db.transaction(async transactionalEntityManager => { - await transactionalEntityManager.update(MiNote, { id: note.id }, values); - - if (values.hasPoll) { - const poll = new MiPoll({ - noteId: note.id, - choices: data.poll!.choices, - expiresAt: data.poll!.expiresAt, - multiple: data.poll!.multiple, - votes: new Array(data.poll!.choices.length).fill(0), - noteVisibility: note.visibility, - userId: user.id, - userHost: user.host, - }); - - await transactionalEntityManager.insert(MiPoll, poll); - } - - if (values.hasEvent) { + } else if (!note.hasEvent && values.hasEvent) { const event = new MiEvent({ noteId: note.id, + title: data.event!.title, start: data.event!.start, end: data.event!.end ?? undefined, - title: data.event!.title, metadata: data.event!.metadata, noteVisibility: note.visibility, userId: user.id, userHost: user.host, }); - await transactionalEntityManager.insert(MiEvent, event); - } - }); - } else if ((note.hasPoll && !values.hasPoll) || (note.hasEvent && !values.hasEvent)) { - // Start transaction - await this.db.transaction(async transactionalEntityManager => { - await transactionalEntityManager.update(MiNote, { id: note.id }, values); - - if (!values.hasPoll) { - await transactionalEntityManager.delete(MiPoll, { noteId: note.id }); - } - - if (!values.hasEvent) { + } else if (note.hasEvent && !values.hasEvent) { await transactionalEntityManager.delete(MiEvent, { noteId: note.id }); } }); @@ -249,6 +248,8 @@ export class NoteUpdateService implements OnApplicationShutdown { await this.notesRepository.update({ id: note.id }, values); } + await this.noteHistoryService.recordHistory(values, note, originalPoll, originalEvent, { updatedAt: data.updatedAt }); + return await this.notesRepository.findOneBy({ id: note.id }); } catch (e) { console.error(e); diff --git a/packages/backend/src/core/PageService.ts b/packages/backend/src/core/PageService.ts new file mode 100644 index 0000000000..1f1ab0847b --- /dev/null +++ b/packages/backend/src/core/PageService.ts @@ -0,0 +1,223 @@ +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { Inject, Injectable } from '@nestjs/common'; +import { DataSource, In, Not } from 'typeorm'; +import { DI } from '@/di-symbols.js'; +import { + type NotesRepository, + MiPage, + type PagesRepository, + MiDriveFile, + type UsersRepository, + MiNote, +} from '@/models/_.js'; +import { bindThis } from '@/decorators.js'; +import { RoleService } from '@/core/RoleService.js'; +import { IdService } from '@/core/IdService.js'; +import type { MiUser } from '@/models/User.js'; +import { IdentifiableError } from '@/misc/identifiable-error.js'; +import { ModerationLogService } from '@/core/ModerationLogService.js'; + +export interface PageBody { + title: string; + name: string; + summary: string | null; + content: Array>; + variables: Array>; + script: string; + eyeCatchingImage?: MiDriveFile | null; + font: string; + alignCenter: boolean; + hideTitleWhenPinned: boolean; +} + +@Injectable() +export class PageService { + constructor( + @Inject(DI.db) + private db: DataSource, + + @Inject(DI.pagesRepository) + private pagesRepository: PagesRepository, + + @Inject(DI.notesRepository) + private notesRepository: NotesRepository, + + @Inject(DI.usersRepository) + private usersRepository: UsersRepository, + + private roleService: RoleService, + private moderationLogService: ModerationLogService, + private idService: IdService, + ) { + } + + @bindThis + public async create( + me: MiUser, + body: PageBody, + ): Promise { + await this.pagesRepository.findBy({ + userId: me.id, + name: body.name, + }).then(result => { + if (result.length > 0) { + throw new IdentifiableError('1a79e38e-3d83-4423-845b-a9d83ff93b61'); + } + }); + + const page = await this.pagesRepository.insertOne(new MiPage({ + id: this.idService.gen(), + updatedAt: new Date(), + title: body.title, + name: body.name, + summary: body.summary, + content: body.content, + variables: body.variables, + script: body.script, + eyeCatchingImageId: body.eyeCatchingImage ? body.eyeCatchingImage.id : null, + userId: me.id, + visibility: 'public', + alignCenter: body.alignCenter, + hideTitleWhenPinned: body.hideTitleWhenPinned, + font: body.font, + })); + + const referencedNotes = this.collectReferencedNotes(page.content); + if (referencedNotes.length > 0) { + await this.notesRepository.increment({ id: In(referencedNotes) }, 'pageCount', 1); + } + + return page; + } + + @bindThis + public async update( + me: MiUser, + pageId: MiPage['id'], + body: Partial, + ): Promise { + await this.db.transaction(async (transaction) => { + const page = await transaction.findOne(MiPage, { + where: { + id: pageId, + }, + lock: { mode: 'for_no_key_update' }, + }); + + if (page == null) { + throw new IdentifiableError('66aefd3c-fdb2-4a71-85ae-cc18bea85d3f'); + } + if (page.userId !== me.id) { + throw new IdentifiableError('d0017699-8256-46f1-aed4-bc03bed73616'); + } + + if (body.name != null) { + await transaction.findBy(MiPage, { + id: Not(pageId), + userId: me.id, + name: body.name, + }).then(result => { + if (result.length > 0) { + throw new IdentifiableError('d05bfe24-24b6-4ea2-a3ec-87cc9bf4daa4'); + } + }); + } + + await transaction.update(MiPage, page.id, { + updatedAt: new Date(), + title: body.title, + name: body.name, + summary: body.summary === undefined ? page.summary : body.summary, + content: body.content, + variables: body.variables, + script: body.script, + alignCenter: body.alignCenter, + hideTitleWhenPinned: body.hideTitleWhenPinned, + font: body.font, + eyeCatchingImageId: body.eyeCatchingImage === undefined ? undefined : (body.eyeCatchingImage?.id ?? null), + }); + + console.log('page.content', page.content); + + if (body.content != null) { + const beforeReferencedNotes = this.collectReferencedNotes(page.content); + const afterReferencedNotes = this.collectReferencedNotes(body.content); + + const removedNotes = beforeReferencedNotes.filter(noteId => !afterReferencedNotes.includes(noteId)); + const addedNotes = afterReferencedNotes.filter(noteId => !beforeReferencedNotes.includes(noteId)); + + if (removedNotes.length > 0) { + await transaction.decrement(MiNote, { id: In(removedNotes) }, 'pageCount', 1); + } + if (addedNotes.length > 0) { + await transaction.increment(MiNote, { id: In(addedNotes) }, 'pageCount', 1); + } + } + }); + } + + @bindThis + public async delete(me: MiUser, pageId: MiPage['id']): Promise { + await this.db.transaction(async (transaction) => { + const page = await transaction.findOne(MiPage, { + where: { + id: pageId, + }, + lock: { mode: 'pessimistic_write' }, // same lock level as DELETE + }); + + if (page == null) { + throw new IdentifiableError('66aefd3c-fdb2-4a71-85ae-cc18bea85d3f'); + } + + if (!await this.roleService.isModerator(me) && page.userId !== me.id) { + throw new IdentifiableError('d0017699-8256-46f1-aed4-bc03bed73616'); + } + + await transaction.delete(MiPage, page.id); + + if (page.userId !== me.id) { + const user = await this.usersRepository.findOneByOrFail({ id: page.userId }); + this.moderationLogService.log(me, 'deletePage', { + pageId: page.id, + pageUserId: page.userId, + pageUserUsername: user.username, + page, + }); + } + + const referencedNotes = this.collectReferencedNotes(page.content); + if (referencedNotes.length > 0) { + await transaction.decrement(MiNote, { id: In(referencedNotes) }, 'pageCount', 1); + } + }); + } + + collectReferencedNotes(content: MiPage['content']): string[] { + const referencingNotes = new Set(); + const recursiveCollect = (content: unknown[]) => { + for (const contentElement of content) { + if (typeof contentElement === 'object' + && contentElement !== null + && 'type' in contentElement) { + if (contentElement.type === 'note' + && 'note' in contentElement + && typeof contentElement.note === 'string') { + referencingNotes.add(contentElement.note); + } + if (contentElement.type === 'section' + && 'children' in contentElement + && Array.isArray(contentElement.children)) { + recursiveCollect(contentElement.children); + } + } + } + }; + recursiveCollect(content); + return [...referencingNotes]; + } +} diff --git a/packages/backend/src/core/QueryService.ts b/packages/backend/src/core/QueryService.ts index b9cef5b0ec..49f93ad108 100644 --- a/packages/backend/src/core/QueryService.ts +++ b/packages/backend/src/core/QueryService.ts @@ -77,9 +77,51 @@ export class QueryService { return q; } + /** + * ミュートやブロックのようにすべてのタイムラインで共通に使用するフィルターを定義します。 + * + * 特別な事情がない限り、各タイムラインはこの関数を呼び出してフィルターを適用してください。 + * + * Notes for future maintainers: + * 1) この関数で生成するクエリと同等の処理が FanoutTimelineEndpointService にあります。 + * この関数を変更した場合、FanoutTimelineEndpointService の方も変更する必要があります。 + * 2) 以下のエンドポイントでは特別な事情があるため queryService のそれぞれの関数を呼び出しています。 + * この関数を変更した場合、以下のエンドポイントの方も変更する必要があることがあります。 + * - packages/backend/src/server/api/endpoints/clips/notes.ts + */ + @bindThis + public generateBaseNoteFilteringQuery( + query: SelectQueryBuilder, + me: { id: MiUser['id'] } | null, + { + excludeUserFromMute, + excludeAuthor, + }: { + excludeUserFromMute?: MiUser['id'], + excludeAuthor?: boolean, + } = {}, + ): void { + this.generateBlockedHostQueryForNote(query, excludeAuthor); + this.generateSuspendedUserQueryForNote(query, excludeAuthor); + if (me) { + this.generateMutedUserQueryForNotes(query, me, { excludeUserFromMute }); + this.generateBlockedUserQueryForNotes(query, me); + this.generateMutedUserQueryForNotes(query, me, { noteColumn: 'renote', excludeUserFromMute }); + this.generateBlockedUserQueryForNotes(query, me, { noteColumn: 'renote' }); + } + } + // ここでいうBlockedは被Blockedの意 @bindThis - public generateBlockedUserQueryForNotes(q: SelectQueryBuilder, me: { id: MiUser['id'] }): void { + public generateBlockedUserQueryForNotes( + q: SelectQueryBuilder, + me: { id: MiUser['id'] }, + { + noteColumn = 'note', + }: { + noteColumn?: string, + } = {}, + ): void { const blockingQuery = this.blockingsRepository.createQueryBuilder('blocking') .select('blocking.blockerId') .where('blocking.blockeeId = :blockeeId', { blockeeId: me.id }); @@ -88,16 +130,20 @@ export class QueryService { // 投稿の返信先の作者にブロックされていない かつ // 投稿の引用元の作者にブロックされていない q - .andWhere(`note.userId NOT IN (${ blockingQuery.getQuery() })`) .andWhere(new Brackets(qb => { qb - .where('note.replyUserId IS NULL') - .orWhere(`note.replyUserId NOT IN (${ blockingQuery.getQuery() })`); + .where(`${noteColumn}.userId IS NULL`) + .orWhere(`${noteColumn}.userId NOT IN (${ blockingQuery.getQuery() })`); + })) + .andWhere(new Brackets(qb => { + qb + .where(`${noteColumn}.replyUserId IS NULL`) + .orWhere(`${noteColumn}.replyUserId NOT IN (${ blockingQuery.getQuery() })`); })) .andWhere(new Brackets(qb => { qb - .where('note.renoteUserId IS NULL') - .orWhere(`note.renoteUserId NOT IN (${ blockingQuery.getQuery() })`); + .where(`${noteColumn}.renoteUserId IS NULL`) + .orWhere(`${noteColumn}.renoteUserId NOT IN (${ blockingQuery.getQuery() })`); })); q.setParameters(blockingQuery.getParameters()); @@ -137,13 +183,23 @@ export class QueryService { } @bindThis - public generateMutedUserQueryForNotes(q: SelectQueryBuilder, me: { id: MiUser['id'] }, exclude?: { id: MiUser['id'] }): void { + public generateMutedUserQueryForNotes( + q: SelectQueryBuilder, + me: { id: MiUser['id'] }, + { + excludeUserFromMute, + noteColumn = 'note', + }: { + excludeUserFromMute?: MiUser['id'], + noteColumn?: string, + } = {}, + ): void { const mutingQuery = this.mutingsRepository.createQueryBuilder('muting') .select('muting.muteeId') .where('muting.muterId = :muterId', { muterId: me.id }); - if (exclude) { - mutingQuery.andWhere('muting.muteeId != :excludeId', { excludeId: exclude.id }); + if (excludeUserFromMute) { + mutingQuery.andWhere('muting.muteeId != :excludeId', { excludeId: excludeUserFromMute }); } const mutingInstanceQuery = this.userProfilesRepository.createQueryBuilder('user_profile') @@ -154,32 +210,36 @@ export class QueryService { // 投稿の返信先の作者をミュートしていない かつ // 投稿の引用元の作者をミュートしていない q - .andWhere(`note.userId NOT IN (${ mutingQuery.getQuery() })`) .andWhere(new Brackets(qb => { qb - .where('note.replyUserId IS NULL') - .orWhere(`note.replyUserId NOT IN (${ mutingQuery.getQuery() })`); + .where(`${noteColumn}.userId IS NULL`) + .orWhere(`${noteColumn}.userId NOT IN (${ mutingQuery.getQuery() })`); + })) + .andWhere(new Brackets(qb => { + qb + .where(`${noteColumn}.replyUserId IS NULL`) + .orWhere(`${noteColumn}.replyUserId NOT IN (${ mutingQuery.getQuery() })`); })) .andWhere(new Brackets(qb => { qb - .where('note.renoteUserId IS NULL') - .orWhere(`note.renoteUserId NOT IN (${ mutingQuery.getQuery() })`); + .where(`${noteColumn}.renoteUserId IS NULL`) + .orWhere(`${noteColumn}.renoteUserId NOT IN (${ mutingQuery.getQuery() })`); })) // mute instances .andWhere(new Brackets(qb => { qb - .andWhere('note.userHost IS NULL') - .orWhere(`NOT ((${ mutingInstanceQuery.getQuery() })::jsonb ? note.userHost)`); + .andWhere(`${noteColumn}.userHost IS NULL`) + .orWhere(`NOT ((${ mutingInstanceQuery.getQuery() })::jsonb ? ${noteColumn}.userHost)`); })) .andWhere(new Brackets(qb => { qb - .where('note.replyUserHost IS NULL') - .orWhere(`NOT ((${ mutingInstanceQuery.getQuery() })::jsonb ? note.replyUserHost)`); + .where(`${noteColumn}.replyUserHost IS NULL`) + .orWhere(`NOT ((${ mutingInstanceQuery.getQuery() })::jsonb ? ${noteColumn}.replyUserHost)`); })) .andWhere(new Brackets(qb => { qb - .where('note.renoteUserHost IS NULL') - .orWhere(`NOT ((${ mutingInstanceQuery.getQuery() })::jsonb ? note.renoteUserHost)`); + .where(`${noteColumn}.renoteUserHost IS NULL`) + .orWhere(`NOT ((${ mutingInstanceQuery.getQuery() })::jsonb ? ${noteColumn}.renoteUserHost)`); })); q.setParameters(mutingQuery.getParameters()); @@ -300,7 +360,7 @@ export class QueryService { public generateSuspendedUserQueryForNote(q: SelectQueryBuilder, excludeAuthor?: boolean): void { if (excludeAuthor) { const brakets = (user: string) => new Brackets(qb => qb - .where(`note.${user}Id IS NULL`) + .where(`${user}.id IS NULL`) // そもそもreplyやrenoteではない、もしくはleftjoinなどでuserが存在しなかった場合を考慮 .orWhere(`user.id = ${user}.id`) .orWhere(`${user}.isSuspended = FALSE`)); q @@ -308,7 +368,7 @@ export class QueryService { .andWhere(brakets('renoteUser')); } else { const brakets = (user: string) => new Brackets(qb => qb - .where(`note.${user}Id IS NULL`) + .where(`${user}.id IS NULL`) // そもそもreplyやrenoteではない、もしくはleftjoinなどでuserが存在しなかった場合を考慮 .orWhere(`${user}.isSuspended = FALSE`)); q .andWhere('user.isSuspended = FALSE') diff --git a/packages/backend/src/core/QueueModule.ts b/packages/backend/src/core/QueueModule.ts index a10949f361..623dfc3bba 100644 --- a/packages/backend/src/core/QueueModule.ts +++ b/packages/backend/src/core/QueueModule.ts @@ -17,13 +17,14 @@ import { RelationshipJobData, UserWebhookDeliverJobData, SystemWebhookDeliverJobData, + PostScheduledNoteJobData, ScheduledNoteDeleteJobData, - ScheduleNotePostJobData, } from '../queue/types.js'; import type { Provider } from '@nestjs/common'; export type SystemQueue = Bull.Queue>; export type EndedPollNotificationQueue = Bull.Queue; +export type PostScheduledNoteQueue = Bull.Queue; export type DeliverQueue = Bull.Queue; export type InboxQueue = Bull.Queue; export type DbQueue = Bull.Queue; @@ -32,7 +33,6 @@ export type ObjectStorageQueue = Bull.Queue; export type UserWebhookDeliverQueue = Bull.Queue; export type SystemWebhookDeliverQueue = Bull.Queue; export type ScheduledNoteDeleteQueue = Bull.Queue; -export type ScheduleNotePostQueue = Bull.Queue; const $system: Provider = { provide: 'queue:system', @@ -46,6 +46,12 @@ const $endedPollNotification: Provider = { inject: [DI.config, DI.redisForJobQueue], }; +const $postScheduledNote: Provider = { + provide: 'queue:postScheduledNote', + useFactory: (config: Config, redisForJobQueue: Redis.Redis) => new Bull.Queue(QUEUE.POST_SCHEDULED_NOTE, baseQueueOptions(config, QUEUE.POST_SCHEDULED_NOTE, redisForJobQueue)), + inject: [DI.config, DI.redisForJobQueue], +}; + const $deliver: Provider = { provide: 'queue:deliver', useFactory: (config: Config, redisForJobQueue: Redis.Redis) => new Bull.Queue(QUEUE.DELIVER, baseQueueOptions(config, QUEUE.DELIVER, redisForJobQueue)), @@ -94,18 +100,13 @@ const $scheduledNoteDelete: Provider = { inject: [DI.config, DI.redisForJobQueue], }; -const $scheduleNotePost: Provider = { - provide: 'queue:scheduleNotePost', - useFactory: (config: Config, redisForJobQueue: Redis.Redis) => new Bull.Queue(QUEUE.SCHEDULE_NOTE_POST, baseQueueOptions(config, QUEUE.SCHEDULE_NOTE_POST, redisForJobQueue)), - inject: [DI.config, DI.redisForJobQueue], -}; - @Module({ imports: [ ], providers: [ $system, $endedPollNotification, + $postScheduledNote, $deliver, $inbox, $db, @@ -114,11 +115,11 @@ const $scheduleNotePost: Provider = { $userWebhookDeliver, $systemWebhookDeliver, $scheduledNoteDelete, - $scheduleNotePost, ], exports: [ $system, $endedPollNotification, + $postScheduledNote, $deliver, $inbox, $db, @@ -127,13 +128,13 @@ const $scheduleNotePost: Provider = { $userWebhookDeliver, $systemWebhookDeliver, $scheduledNoteDelete, - $scheduleNotePost, ], }) export class QueueModule implements OnApplicationShutdown { constructor( @Inject('queue:system') public systemQueue: SystemQueue, @Inject('queue:endedPollNotification') public endedPollNotificationQueue: EndedPollNotificationQueue, + @Inject('queue:postScheduledNote') public postScheduledNoteQueue: PostScheduledNoteQueue, @Inject('queue:deliver') public deliverQueue: DeliverQueue, @Inject('queue:inbox') public inboxQueue: InboxQueue, @Inject('queue:db') public dbQueue: DbQueue, @@ -142,7 +143,6 @@ export class QueueModule implements OnApplicationShutdown { @Inject('queue:userWebhookDeliver') public userWebhookDeliverQueue: UserWebhookDeliverQueue, @Inject('queue:systemWebhookDeliver') public systemWebhookDeliverQueue: SystemWebhookDeliverQueue, @Inject('queue:scheduledNoteDelete') public scheduledNoteDeleteQueue: ScheduledNoteDeleteQueue, - @Inject('queue:scheduleNotePost') public scheduleNotePostQueue: ScheduleNotePostQueue, ) {} public async dispose(): Promise { @@ -152,6 +152,7 @@ export class QueueModule implements OnApplicationShutdown { await Promise.all([ this.systemQueue.close(), this.endedPollNotificationQueue.close(), + this.postScheduledNoteQueue.close(), this.deliverQueue.close(), this.inboxQueue.close(), this.dbQueue.close(), @@ -160,7 +161,6 @@ export class QueueModule implements OnApplicationShutdown { this.userWebhookDeliverQueue.close(), this.systemWebhookDeliverQueue.close(), this.scheduledNoteDeleteQueue.close(), - this.scheduleNotePostQueue.close(), ]); } diff --git a/packages/backend/src/core/QueueService.ts b/packages/backend/src/core/QueueService.ts index 1cdcbd8152..c853b1fc0b 100644 --- a/packages/backend/src/core/QueueService.ts +++ b/packages/backend/src/core/QueueService.ts @@ -4,7 +4,7 @@ */ import { randomUUID } from 'node:crypto'; -import { Inject, Injectable } from '@nestjs/common'; +import { Inject, Injectable, OnModuleInit } from '@nestjs/common'; import { MetricsTime, type JobType } from 'bullmq'; import { parse as parseRedisInfo } from 'redis-info'; import type { IActivity } from '@/core/activitypub/type.js'; @@ -18,6 +18,7 @@ import { bindThis } from '@/decorators.js'; import type { Antenna } from '@/server/api/endpoints/i/import-antennas.js'; import { ApRequestCreator } from '@/core/activitypub/ApRequestService.js'; import { type SystemWebhookPayload } from '@/core/SystemWebhookService.js'; +import type { Packed } from '@/misc/json-schema.js'; import { type UserWebhookPayload } from './UserWebhookService.js'; import type { DbJobData, @@ -31,6 +32,7 @@ import type { DbQueue, DeliverQueue, EndedPollNotificationQueue, + PostScheduledNoteQueue, InboxQueue, ObjectStorageQueue, RelationshipQueue, @@ -38,7 +40,6 @@ import type { SystemWebhookDeliverQueue, UserWebhookDeliverQueue, ScheduledNoteDeleteQueue, - ScheduleNotePostQueue, } from './QueueModule.js'; import type httpSignature from '@peertube/http-signature'; import type * as Bull from 'bullmq'; @@ -46,6 +47,7 @@ import type * as Bull from 'bullmq'; export const QUEUE_TYPES = [ 'system', 'endedPollNotification', + 'postScheduledNote', 'deliver', 'inbox', 'db', @@ -55,14 +57,50 @@ export const QUEUE_TYPES = [ 'systemWebhookDeliver', ] as const; +const REPEATABLE_SYSTEM_JOB_DEF = [{ + name: 'tickCharts', + pattern: '55 * * * *', +}, { + name: 'resyncCharts', + pattern: '0 0 * * *', +}, { + name: 'cleanCharts', + pattern: '0 0 * * *', +}, { + name: 'aggregateRetention', + pattern: '0 0 * * *', +}, { + name: 'clean', + pattern: '0 0 * * *', +}, { + name: 'checkExpiredMutings', + pattern: '*/5 * * * *', +}, { + name: 'bakeBufferedReactions', + pattern: '0 0 * * *', +}, { + name: 'checkModeratorsActivity', + // 毎時30分に起動 + pattern: '30 * * * *', +}, { + name: 'cleanRemoteNotes', + // 毎日午前4時に起動(最も人の少ない時間帯) + pattern: '0 4 * * *', +}, { + name: 'autoDeleteNotes', + // 매일 오전 3시에 실행 + pattern: '0 3 * * *', +}]; + @Injectable() -export class QueueService { +export class QueueService implements OnModuleInit { constructor( @Inject(DI.config) private config: Config, @Inject('queue:system') public systemQueue: SystemQueue, @Inject('queue:endedPollNotification') public endedPollNotificationQueue: EndedPollNotificationQueue, + @Inject('queue:postScheduledNote') public postScheduledNoteQueue: PostScheduledNoteQueue, @Inject('queue:deliver') public deliverQueue: DeliverQueue, @Inject('queue:inbox') public inboxQueue: InboxQueue, @Inject('queue:db') public dbQueue: DbQueue, @@ -71,64 +109,44 @@ export class QueueService { @Inject('queue:userWebhookDeliver') public userWebhookDeliverQueue: UserWebhookDeliverQueue, @Inject('queue:systemWebhookDeliver') public systemWebhookDeliverQueue: SystemWebhookDeliverQueue, @Inject('queue:scheduledNoteDelete') public scheduledNoteDeleteQueue: ScheduledNoteDeleteQueue, - @Inject('queue:scheduleNotePost') public ScheduleNotePostQueue: ScheduleNotePostQueue, - ) { - this.systemQueue.add('tickCharts', { - }, { - repeat: { pattern: '55 * * * *' }, - removeOnComplete: 10, - removeOnFail: 30, - }); - - this.systemQueue.add('resyncCharts', { - }, { - repeat: { pattern: '0 0 * * *' }, - removeOnComplete: 10, - removeOnFail: 30, - }); - - this.systemQueue.add('cleanCharts', { - }, { - repeat: { pattern: '0 0 * * *' }, - removeOnComplete: 10, - removeOnFail: 30, - }); - - this.systemQueue.add('aggregateRetention', { - }, { - repeat: { pattern: '0 0 * * *' }, - removeOnComplete: 10, - removeOnFail: 30, - }); - - this.systemQueue.add('clean', { - }, { - repeat: { pattern: '0 0 * * *' }, - removeOnComplete: 10, - removeOnFail: 30, - }); - - this.systemQueue.add('checkExpiredMutings', { - }, { - repeat: { pattern: '*/5 * * * *' }, - removeOnComplete: 10, - removeOnFail: 30, - }); - - this.systemQueue.add('bakeBufferedReactions', { - }, { - repeat: { pattern: '0 0 * * *' }, - removeOnComplete: 10, - removeOnFail: 30, - }); + ) { } + + async onModuleInit() { + console.log('[QueueService] onModuleInit: Setting up', REPEATABLE_SYSTEM_JOB_DEF.length, 'repeatable jobs'); + try { + for (const def of REPEATABLE_SYSTEM_JOB_DEF) { + console.log('[QueueService] Setting up repeatable job:', def.name, 'pattern:', def.pattern); + const result = await this.systemQueue.upsertJobScheduler(def.name, { + pattern: def.pattern, + immediately: false, + }, { + name: def.name, + opts: { + // 期限ではなくcountで設定したいが、ジョブごとではなくキュー全体でカウントされるため、高頻度で実行されるジョブによって低頻度で実行されるジョブのログが消えることになる + removeOnComplete: { + age: 3600 * 24 * 7, // keep up to 7 days + }, + removeOnFail: { + age: 3600 * 24 * 7, // keep up to 7 days + }, + }, + }); + console.log('[QueueService] Result:', def.name, result); + } - this.systemQueue.add('checkModeratorsActivity', { - }, { - // 毎時30分に起動 - repeat: { pattern: '30 * * * *' }, - removeOnComplete: 10, - removeOnFail: 30, - }); + // 古いバージョンで作成され現在使われなくなったrepeatableジョブをクリーンアップ + const schedulers = await this.systemQueue.getJobSchedulers(); + console.log('[QueueService] Found', schedulers.length, 'existing schedulers'); + for (const scheduler of schedulers) { + if (!REPEATABLE_SYSTEM_JOB_DEF.some(def => def.name === scheduler.key)) { + await this.systemQueue.removeJobScheduler(scheduler.key); + } + } + console.log('[QueueService] onModuleInit: All repeatable jobs set up successfully'); + } catch (error) { + console.error('[QueueService] ERROR in onModuleInit:', error); + throw error; + } } @bindThis @@ -738,6 +756,7 @@ export class QueueService { switch (type) { case 'system': return this.systemQueue; case 'endedPollNotification': return this.endedPollNotificationQueue; + case 'postScheduledNote': return this.postScheduledNoteQueue; case 'deliver': return this.deliverQueue; case 'inbox': return this.inboxQueue; case 'db': return this.dbQueue; @@ -777,8 +796,8 @@ export class QueueService { @bindThis public async queueRetryJob(queueType: typeof QUEUE_TYPES[number], jobId: string) { const queue = this.getQueue(queueType); - const job: Bull.Job | null = await queue.getJob(jobId); - if (job) { + const job = await queue.getJob(jobId); + if (job != null) { if (job.finishedOn != null) { await job.retry(); } else { @@ -790,20 +809,20 @@ export class QueueService { @bindThis public async queueRemoveJob(queueType: typeof QUEUE_TYPES[number], jobId: string) { const queue = this.getQueue(queueType); - const job: Bull.Job | null = await queue.getJob(jobId); - if (job) { + const job = await queue.getJob(jobId); + if (job != null) { await job.remove(); } } @bindThis - private packJobData(job: Bull.Job) { + private packJobData(job: Bull.Job): Packed<'QueueJob'> { // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition const stacktrace = job.stacktrace ? job.stacktrace.filter(Boolean) : []; stacktrace.reverse(); return { - id: job.id, + id: job.id!, name: job.name, data: job.data, opts: job.opts, @@ -824,14 +843,21 @@ export class QueueService { @bindThis public async queueGetJob(queueType: typeof QUEUE_TYPES[number], jobId: string) { const queue = this.getQueue(queueType); - const job: Bull.Job | null = await queue.getJob(jobId); - if (job) { + const job = await queue.getJob(jobId); + if (job != null) { return this.packJobData(job); } else { throw new Error(`Job not found: ${jobId}`); } } + @bindThis + public async queueGetJobLogs(queueType: typeof QUEUE_TYPES[number], jobId: string) { + const queue = this.getQueue(queueType); + const result = await queue.getJobLogs(jobId); + return result.logs; + } + @bindThis public async queueGetJobs(queueType: typeof QUEUE_TYPES[number], jobTypes: JobType[], search?: string) { const RETURN_LIMIT = 100; diff --git a/packages/backend/src/core/RoleService.ts b/packages/backend/src/core/RoleService.ts index 8dee995ad2..6cb6fda025 100644 --- a/packages/backend/src/core/RoleService.ts +++ b/packages/backend/src/core/RoleService.ts @@ -33,6 +33,7 @@ import { NotificationService } from '@/core/NotificationService.js'; import { UserExperience } from '@/models/Role.js'; import type { OnApplicationShutdown, OnModuleInit } from '@nestjs/common'; +// cherrypick-js の rolePolicies と同期すべし export type RolePolicies = { gtlAvailable: boolean; ltlAvailable: boolean; @@ -57,6 +58,7 @@ export type RolePolicies = { canManageCustomEmojis: boolean; canManageAvatarDecorations: boolean; canSearchNotes: boolean; + canSearchUsers: boolean; canUseTranslator: boolean; canUseAutoTranslate: boolean; canHideAds: boolean; @@ -80,7 +82,10 @@ export type RolePolicies = { canImportMuting: boolean; canImportUserLists: boolean; chatAvailability: 'available' | 'readonly' | 'unavailable'; + uploadableFileTypes: string[]; noteDraftLimit: number; + scheduledNoteLimit: number; + watermarkAvailable: boolean; canSetFederationAvatarShape: boolean; canDeleteAccount: boolean; canTruncateAccount: boolean; @@ -90,7 +95,7 @@ export type RolePolicies = { export const DEFAULT_POLICIES: RolePolicies = { gtlAvailable: true, ltlAvailable: true, - btlAvailable: false, + btlAvailable: true, canPublicNote: true, canPublicReplyNote: true, canPublicQuoteNote: true, @@ -111,11 +116,12 @@ export const DEFAULT_POLICIES: RolePolicies = { canManageCustomEmojis: false, canManageAvatarDecorations: false, canSearchNotes: false, + canSearchUsers: true, canUseTranslator: true, canUseAutoTranslate: false, canHideAds: false, driveCapacityMb: 100, - maxFileSizeMb: 10, + maxFileSizeMb: 30, alwaysMarkNsfw: false, canUpdateBioMedia: true, pinLimit: 5, @@ -128,13 +134,22 @@ export const DEFAULT_POLICIES: RolePolicies = { userEachUserListsLimit: 50, rateLimitFactor: 1, avatarDecorationLimit: 1, - canImportAntennas: true, - canImportBlocking: true, - canImportFollowing: true, - canImportMuting: true, - canImportUserLists: true, + canImportAntennas: false, + canImportBlocking: false, + canImportFollowing: false, + canImportMuting: false, + canImportUserLists: false, chatAvailability: 'available', + uploadableFileTypes: [ + 'text/*', + 'application/json', + 'image/*', + 'video/*', + 'audio/*', + ], noteDraftLimit: 10, + scheduledNoteLimit: 3, + watermarkAvailable: true, canSetFederationAvatarShape: true, canDeleteAccount: true, canTruncateAccount: true, @@ -736,6 +751,7 @@ export class RoleService implements OnApplicationShutdown, OnModuleInit { canManageCustomEmojis: calc('canManageCustomEmojis', vs => vs.some(v => v === true)), canManageAvatarDecorations: calc('canManageAvatarDecorations', vs => vs.some(v => v === true)), canSearchNotes: calc('canSearchNotes', vs => vs.some(v => v === true)), + canSearchUsers: calc('canSearchUsers', vs => vs.some(v => v === true)), canUseTranslator: calc('canUseTranslator', vs => vs.some(v => v === true)), canUseAutoTranslate: calc('canUseAutoTranslate', vs => vs.some(v => v === true)), canHideAds: calc('canHideAds', vs => vs.some(v => v === true)), @@ -759,7 +775,19 @@ export class RoleService implements OnApplicationShutdown, OnModuleInit { canImportMuting: calc('canImportMuting', vs => vs.some(v => v === true)), canImportUserLists: calc('canImportUserLists', vs => vs.some(v => v === true)), chatAvailability: calc('chatAvailability', aggregateChatAvailability), + uploadableFileTypes: calc('uploadableFileTypes', vs => { + const set = new Set(); + for (const v of vs) { + for (const type of v) { + if (type.trim() === '') continue; + set.add(type.trim()); + } + } + return [...set]; + }), noteDraftLimit: calc('noteDraftLimit', vs => Math.max(...vs)), + scheduledNoteLimit: calc('scheduledNoteLimit', vs => Math.max(...vs)), + watermarkAvailable: calc('watermarkAvailable', vs => vs.some(v => v === true)), canSetFederationAvatarShape: calc('canSetFederationAvatarShape', vs => vs.some(v => v === true)), canDeleteAccount: calc('canDeleteAccount', vs => vs.some(v => v === true)), canTruncateAccount: calc('canTruncateAccount', vs => vs.some(v => v === true)), diff --git a/packages/backend/src/core/SearchService.ts b/packages/backend/src/core/SearchService.ts index 20a776ded8..71dc718916 100644 --- a/packages/backend/src/core/SearchService.ts +++ b/packages/backend/src/core/SearchService.ts @@ -227,17 +227,14 @@ export class SearchService { if (opts.host) { if (opts.host === '.') { - query.andWhere('user.host IS NULL'); + query.andWhere('note.userHost IS NULL'); } else { - query.andWhere('user.host = :host', { host: opts.host }); + query.andWhere('note.userHost = :host', { host: opts.host }); } } this.queryService.generateVisibilityQuery(query, me); - this.queryService.generateBlockedHostQueryForNote(query); - this.queryService.generateSuspendedUserQueryForNote(query); - if (me) this.queryService.generateMutedUserQueryForNotes(query, me); - if (me) this.queryService.generateBlockedUserQueryForNotes(query, me); + this.queryService.generateBaseNoteFilteringQuery(query, me); return query.limit(pagination.limit).getMany(); } diff --git a/packages/backend/src/core/SignupService.ts b/packages/backend/src/core/SignupService.ts index 017822a75c..947ae4ac2a 100644 --- a/packages/backend/src/core/SignupService.ts +++ b/packages/backend/src/core/SignupService.ts @@ -94,6 +94,11 @@ export class SignupService { if (isPreserved) { throw new Error('USED_USERNAME'); } + + const hasProhibitedWords = this.utilityService.isKeyWordIncluded(username.toLowerCase(), this.meta.prohibitedWordsForNameOfUser); + if (hasProhibitedWords) { + throw new Error('USED_USERNAME'); + } } const keyPair = await new Promise((res, rej) => diff --git a/packages/backend/src/core/UserListService.ts b/packages/backend/src/core/UserListService.ts index f0a8768c8f..61435500b7 100644 --- a/packages/backend/src/core/UserListService.ts +++ b/packages/backend/src/core/UserListService.ts @@ -91,7 +91,7 @@ export class UserListService implements OnApplicationShutdown, OnModuleInit { } @bindThis - public async addMember(target: MiUser, list: MiUserList, me: MiUser) { + public async addMember(target: MiUser, list: MiUserList, me: MiUser, options: { withReplies?: boolean } = {}) { const currentCount = await this.userListMembershipsRepository.countBy({ userListId: list.id, }); @@ -104,6 +104,7 @@ export class UserListService implements OnApplicationShutdown, OnModuleInit { userId: target.id, userListId: list.id, userListUserId: list.userId, + withReplies: options.withReplies ?? false, } as MiUserListMembership); this.globalEventService.publishInternalEvent('userListMemberAdded', { userListId: list.id, memberId: target.id }); diff --git a/packages/backend/src/core/WebhookTestService.ts b/packages/backend/src/core/WebhookTestService.ts index ffc3d502db..7e44e6ef7e 100644 --- a/packages/backend/src/core/WebhookTestService.ts +++ b/packages/backend/src/core/WebhookTestService.ts @@ -65,6 +65,9 @@ function generateDummyUser(override?: Partial): MiUser { token: null, setFederationAvatarShape: null, isSquareAvatars: null, + autoDeleteNotesAfterDays: null, + autoDeleteKeepFavorites: true, + canChat: null, ...override, }; } @@ -87,6 +90,7 @@ function generateDummyNote(override?: Partial): MiNote { renoteCount: 10, repliesCount: 5, clippedCount: 0, + pageCount: 0, reactions: {}, visibility: 'public', uri: null, @@ -109,7 +113,6 @@ function generateDummyNote(override?: Partial): MiNote { renoteUserHost: null, updatedAt: null, updatedAtHistory: null, - noteEditHistory: [], hasEvent: false, disableRightClick: false, deleteAt: null, @@ -252,7 +255,6 @@ export class WebhookTestService { case 'reaction': return; default: { - // eslint-disable-next-line @typescript-eslint/no-unused-vars const _exhaustiveAssertion: never = params.type; return; } @@ -339,7 +341,6 @@ export class WebhookTestService { break; } default: { - // eslint-disable-next-line @typescript-eslint/no-unused-vars const _exhaustiveAssertion: never = params.type; return; } @@ -407,6 +408,7 @@ export class WebhookTestService { uri: note.uri ?? undefined, url: note.url ?? undefined, reactionAndUserPairCache: note.reactionAndUserPairCache, + hasDeliveryTargets: note.deliveryTargets != null, ...(detail ? { clippedCount: note.clippedCount, reply: note.reply ? await this.toPackedNote(note.reply, false) : null, @@ -424,7 +426,7 @@ export class WebhookTestService { name: user.name, username: user.username, host: user.host, - avatarUrl: user.avatarId == null ? null : user.avatarUrl, + avatarUrl: (user.avatarId == null ? null : user.avatarUrl) ?? '', avatarBlurhash: user.avatarId == null ? null : user.avatarBlurhash, avatarDecorations: user.avatarDecorations.map(it => ({ id: it.id, @@ -433,6 +435,8 @@ export class WebhookTestService { url: 'https://example.com/dummy-image001.png', offsetX: it.offsetX, offsetY: it.offsetY, + scale: it.scale, + opacity: it.opacity, })), isLocked: user.isLocked, isBot: user.isBot, diff --git a/packages/backend/src/core/activitypub/ApDbResolverService.ts b/packages/backend/src/core/activitypub/ApDbResolverService.ts index 5c16744a77..652ee46e9b 100644 --- a/packages/backend/src/core/activitypub/ApDbResolverService.ts +++ b/packages/backend/src/core/activitypub/ApDbResolverService.ts @@ -14,6 +14,8 @@ import { UtilityService } from '@/core/UtilityService.js'; import type { MiNote } from '@/models/Note.js'; import { bindThis } from '@/decorators.js'; import { MiLocalUser, MiRemoteUser } from '@/models/User.js'; +import { QueueService } from '@/core/QueueService.js'; +import type { DbQueue } from '@/core/QueueModule.js'; import { getApId } from './type.js'; import { ApPersonService } from './models/ApPersonService.js'; import type { IObject } from './type.js'; @@ -52,6 +54,10 @@ export class ApDbResolverService implements OnApplicationShutdown { @Inject(DI.userPublickeysRepository) private userPublickeysRepository: UserPublickeysRepository, + @Inject('queue:db') + public dbQueue: DbQueue, + + private queueService: QueueService, private cacheService: CacheService, private apPersonService: ApPersonService, private utilityService: UtilityService, @@ -159,7 +165,21 @@ export class ApDbResolverService implements OnApplicationShutdown { key: MiUserPublickey | null; } | null> { const user = await this.apPersonService.resolvePerson(uri) as MiRemoteUser; - if (user.isDeleted) return null; + if (user.isDeleted) { + const jobs = await this.dbQueue.getJobs(['active', 'delayed', 'paused', 'wait', 'waiting', 'waiting-children']); + + const isUserDeletingNow = jobs.filter(e => e.name === 'deleteAccount').map(e => JSON.parse(e.data)).find(e => e.user.id === user.id); + + if (isUserDeletingNow) { + return null; + } else { + // If user deleted but job not running, job may failed so re-run the job + // @FIXME: soft deleted account will be forced to hard deleted, but soft deletion not used at this time + await this.queueService.createDeleteAccountJob(user); + + return null; + } + } const key = await this.publicKeyByUserIdCache.fetch( user.id, diff --git a/packages/backend/src/core/activitypub/ApInboxService.ts b/packages/backend/src/core/activitypub/ApInboxService.ts index 652f5565dd..92236d2350 100644 --- a/packages/backend/src/core/activitypub/ApInboxService.ts +++ b/packages/backend/src/core/activitypub/ApInboxService.ts @@ -15,6 +15,9 @@ import { UserBlockingService } from '@/core/UserBlockingService.js'; import { NoteDeleteService } from '@/core/NoteDeleteService.js'; import { NoteCreateService } from '@/core/NoteCreateService.js'; import { NoteUpdateService } from '@/core/NoteUpdateService.js'; +import { NotificationService } from '@/core/NotificationService.js'; +import { ChatService } from '@/core/ChatService.js'; +import { RoleService } from '@/core/RoleService.js'; import { concat, toArray, toSingle, unique } from '@/misc/prelude/array.js'; import { AppLockService } from '@/core/AppLockService.js'; import type Logger from '@/logger.js'; @@ -24,13 +27,13 @@ import { UtilityService } from '@/core/UtilityService.js'; import { NoteEntityService } from '@/core/entities/NoteEntityService.js'; import { UserEntityService } from '@/core/entities/UserEntityService.js'; import { QueueService } from '@/core/QueueService.js'; -import type { UsersRepository, NotesRepository, FollowingsRepository, AbuseUserReportsRepository, FollowRequestsRepository, MiMeta } from '@/models/_.js'; +import type { UsersRepository, NotesRepository, FollowingsRepository, AbuseUserReportsRepository, FollowRequestsRepository, MiMeta, ChatMessagesRepository, ChatRoomsRepository, ChatRoomInvitationsRepository, ChatRoomMembershipsRepository } from '@/models/_.js'; import { bindThis } from '@/decorators.js'; import type { MiRemoteUser } from '@/models/User.js'; import { GlobalEventService } from '@/core/GlobalEventService.js'; import { AbuseReportService } from '@/core/AbuseReportService.js'; import { IdentifiableError } from '@/misc/identifiable-error.js'; -import { getApHrefNullable, getApId, getApIds, getApType, isAccept, isActor, isAdd, isAnnounce, isBlock, isCollection, isCollectionOrOrderedCollection, isCreate, isDelete, isFlag, isFollow, isLike, isMove, isPost, isReject, isRemove, isTombstone, isUndo, isUpdate, validActor, validPost } from './type.js'; +import { getApHrefNullable, getApId, getApIds, getApType, isAccept, isActor, isAdd, isAnnounce, isBlock, isCollection, isCollectionOrOrderedCollection, isCreate, isDelete, isFlag, isFollow, isInvite, isLike, isMove, isPost, isReject, isRemove, isTombstone, isUndo, isUpdate, validActor, validPost } from './type.js'; import { ApNoteService } from './models/ApNoteService.js'; import { ApLoggerService } from './ApLoggerService.js'; import { ApDbResolverService } from './ApDbResolverService.js'; @@ -38,8 +41,10 @@ import { ApResolverService } from './ApResolverService.js'; import { ApAudienceService } from './ApAudienceService.js'; import { ApPersonService } from './models/ApPersonService.js'; import { ApQuestionService } from './models/ApQuestionService.js'; +import { ApImageService } from './models/ApImageService.js'; +import { ApMfmService } from './ApMfmService.js'; import type { Resolver } from './ApResolverService.js'; -import type { IAccept, IAdd, IAnnounce, IBlock, ICreate, IDelete, IFlag, IFollow, ILike, IObject, IRead, IReject, IRemove, IUndo, IUpdate, IMove, IPost } from './type.js'; +import type { IAccept, IAdd, IAnnounce, IBlock, ICreate, IDelete, IFlag, IFollow, IInvite, ILike, IObject, IRead, IReject, IRemove, IUndo, IUpdate, IMove, IPost } from './type.js'; @Injectable() export class ApInboxService { @@ -64,6 +69,18 @@ export class ApInboxService { @Inject(DI.followRequestsRepository) private followRequestsRepository: FollowRequestsRepository, + @Inject(DI.chatMessagesRepository) + private chatMessagesRepository: ChatMessagesRepository, + + @Inject(DI.chatRoomsRepository) + private chatRoomsRepository: ChatRoomsRepository, + + @Inject(DI.chatRoomInvitationsRepository) + private chatRoomInvitationsRepository: ChatRoomInvitationsRepository, + + @Inject(DI.chatRoomMembershipsRepository) + private chatRoomMembershipsRepository: ChatRoomMembershipsRepository, + private userEntityService: UserEntityService, private noteEntityService: NoteEntityService, private utilityService: UtilityService, @@ -78,6 +95,9 @@ export class ApInboxService { private noteCreateService: NoteCreateService, private noteUpdateService: NoteUpdateService, private noteDeleteService: NoteDeleteService, + private notificationService: NotificationService, + private chatService: ChatService, + private roleService: RoleService, private appLockService: AppLockService, private apResolverService: ApResolverService, private apDbResolverService: ApDbResolverService, @@ -85,6 +105,8 @@ export class ApInboxService { private apNoteService: ApNoteService, private apPersonService: ApPersonService, private apQuestionService: ApQuestionService, + private apImageService: ApImageService, + private apMfmService: ApMfmService, private queueService: QueueService, private globalEventService: GlobalEventService, ) { @@ -173,6 +195,8 @@ export class ApInboxService { return await this.flag(actor, activity); } else if (isMove(activity)) { return await this.move(actor, activity, resolver); + } else if (isInvite(activity)) { + return await this.invite(actor, activity, resolver); } else { return `unrecognized activity type: ${activity.type}`; } @@ -231,6 +255,7 @@ export class ApInboxService { }); if (isFollow(object)) return await this.acceptFollow(actor, object); + if (isInvite(object)) return await this.acceptInvite(actor, object); return `skip: Unknown Accept type: ${getApType(object)}`; } @@ -259,6 +284,59 @@ export class ApInboxService { return 'ok'; } + @bindThis + private async acceptInvite(actor: MiRemoteUser, activity: IInvite): Promise { + // actor is the one who accepted the invitation (invitee) + // activity.target should be the actor who accepted + // activity.object should be the room + + const roomObject = activity.object; + if (typeof roomObject === 'string') return 'skip: object must be a full object, not a URI'; + + const roomUri = getApId(roomObject); + if (!roomUri) return 'skip: invalid room object'; + + // Extract room ID from URI + const roomIdMatch = roomUri.match(/\/chat\/rooms\/([a-zA-Z0-9]+)$/); + if (!roomIdMatch) return 'skip: invalid room URI format'; + const roomId = roomIdMatch[1]; + + // Find the room + const room = await this.chatRoomsRepository.findOneBy({ id: roomId }); + if (!room) { + this.logger.warn(`Room not found: ${roomId}`); + return 'skip: room not found'; + } + + // Delete the invitation + const invitation = await this.chatRoomInvitationsRepository.findOneBy({ + roomId, + userId: actor.id, + }); + if (invitation) { + await this.chatRoomInvitationsRepository.delete(invitation.id); + } + + // Check if already a member + const existingMembership = await this.chatService.isRoomMember(room, actor.id); + if (existingMembership) { + this.logger.info(`User ${actor.id} is already a member of room ${roomId}`); + return 'ok'; + } + + // Add membership + const membership = { + id: this.idService.gen(), + roomId: room.id, + userId: actor.id, + }; + + await this.chatRoomMembershipsRepository.insertOne(membership); + + this.logger.info(`Remote user ${actor.id} accepted invitation and joined room ${roomId}`); + return 'ok'; + } + @bindThis private async add(actor: MiRemoteUser, activity: IAdd, resolver?: Resolver): Promise { if (actor.uri !== activity.actor) { @@ -425,7 +503,42 @@ export class ApInboxService { }); if (isPost(object)) { - await this.createNote(resolver, actor, object, false, activity); + // Check if this is a chat message (legacy Misskey format) + if (typeof object === 'object' && '_misskey_talk' in object && object._misskey_talk === true) { + await this.createChatMessage(resolver, actor, object, activity); + } else { + // Check if this is a reply to a chat message + // If so, treat it as a chat message even without `_misskey_talk` flag + let isReplyToChatMessage = false; + if (typeof object === 'object' && object.inReplyTo) { + try { + const inReplyToUri = getApId(object.inReplyTo); + // Check if inReplyTo is our chat message by checking the URI pattern and host + const url = new URL(inReplyToUri); + if (this.utilityService.isSelfHost(url.hostname) && inReplyToUri.includes('/chat/messages/')) { + isReplyToChatMessage = true; + } else { + // Check if inReplyTo exists in our chat_messages table + // This handles cases where the reply is to a previous reply that was saved as a chat message + const inReplyToId = inReplyToUri.split('/').pop(); + if (inReplyToId) { + const chatMessage = await this.chatMessagesRepository.findOneBy({ uri: inReplyToUri }); + if (chatMessage) { + isReplyToChatMessage = true; + } + } + } + } catch (e) { + // Ignore error, treat as normal note + } + } + + if (isReplyToChatMessage) { + await this.createChatMessage(resolver, actor, object, activity); + } else { + await this.createNote(resolver, actor, object, false, activity); + } + } } else { return `Unknown type: ${getApType(object)}`; } @@ -468,6 +581,156 @@ export class ApInboxService { } } + @bindThis + private async createChatMessage(resolver: Resolver, actor: MiRemoteUser, object: IPost, activity: ICreate): Promise { + this.logger.info('Receiving chat message from remote'); + + if (typeof object !== 'object') return 'skip: object is not an object'; + if (!object.id) return 'skip: object has no id'; + + // Check if this message already exists (by URI) + // Note: Cannot use fetchNote because chat messages are not in the notes table + // For now, let ChatService handle duplicates + this.logger.info(`Processing chat message: ${object.id}`); + + // Get recipients from the 'to' field + const toUris = getApIds(object.to); + if (!toUris || toUris.length === 0) return 'skip: no recipients'; + + // Resolve recipient users + const recipients = []; + for (const uri of toUris) { + try { + const user = await this.apPersonService.resolvePerson(uri, resolver); + if (user) { + recipients.push(user); + } + } catch (e) { + this.logger.warn(`Failed to resolve recipient: ${uri}`); + } + } + + if (recipients.length === 0) return 'skip: no valid recipients'; + + // Extract message content + let text: string | null = null; + if (object.source?.mediaType === 'text/x.misskeymarkdown' && typeof object.source.content === 'string') { + text = object.source.content; + } else if (typeof object._misskey_content !== 'undefined') { + text = object._misskey_content; + } else if (typeof object.content === 'string') { + text = this.apMfmService.htmlToMfm(object.content, object.tag); + } + const uri = object.id; + + // Handle file attachments + let file = null; + if (object.attachment && Array.isArray(object.attachment) && object.attachment.length > 0) { + try { + const attach = object.attachment[0]; // Take first attachment for now + attach.sensitive ??= object.sensitive; + file = await this.apImageService.resolveImage(actor, attach); + } catch (e) { + this.logger.warn(`Failed to resolve attachment: ${e}`); + } + } + + // Extract emojis + const emojis = await this.apNoteService.extractEmojis(object.tag ?? [], actor.host).catch(e => { + this.logger.info(`extractEmojis: ${e}`); + return []; + }); + + const apEmojis = emojis.map(emoji => emoji.name); + + try { + // Determine if this is a 1:1 chat or group chat + if (recipients.length === 1) { + // 1:1 chat + const recipient = recipients[0]; + + // Check if recipient can use chat + let recipientCanChat = true; + if (this.userEntityService.isLocalUser(recipient)) { + // For local users, check their role policies + const policies = await this.roleService.getUserPolicies(recipient.id); + recipientCanChat = policies.chatAvailability !== 'unavailable'; + } else { + // For remote users, check the canChat field from their server + recipientCanChat = recipient.canChat ?? true; + } + + if (!recipientCanChat) { + // If recipient cannot use chat, convert to DM + this.logger.info(`Recipient ${recipient.username} cannot use chat, converting to DM`); + await this.apNoteService.createNote(object, actor, resolver, true); + } else { + // Normal chat message + await this.chatService.createMessageToUser(actor, recipient, { + text, + file, + uri, + emojis: apEmojis, + }); + } + } else { + // Group chat + // Extract room ID from context + const contextUri = object['@context']; + if (!contextUri || typeof contextUri !== 'string') { + this.logger.warn('Group chat message missing context'); + return 'skip: group chat message missing context'; + } + + const roomIdMatch = contextUri.match(/\/chat\/rooms\/([a-zA-Z0-9]+)$/); + if (!roomIdMatch) { + this.logger.warn(`Invalid context URI format: ${contextUri}`); + return 'skip: invalid context URI format'; + } + + const roomId = roomIdMatch[1]; + + // Check if the room exists locally + const room = await this.chatRoomsRepository.findOneBy({ id: roomId }); + if (!room) { + this.logger.warn(`Room not found: ${roomId}`); + return 'skip: room not found'; + } + + // Check if at least one recipient is a local user who is a member of the room + let hasLocalMember = false; + for (const recipient of recipients) { + if (this.userEntityService.isLocalUser(recipient)) { + // Check if this local user is a member of the room + const isMember = await this.chatService.isRoomMember(room, recipient.id); + if (isMember) { + hasLocalMember = true; + break; + } + } + } + + if (!hasLocalMember) { + this.logger.warn('No local members found in the room'); + return 'skip: no local members in room'; + } + + // Create the message to the room + await this.chatService.createMessageToRoom(actor, room, { + text, + file, + uri, + emojis: apEmojis, + }); + } + + return 'ok'; + } catch (err) { + this.logger.error(`Failed to create chat message: ${err}`); + throw err; + } + } + @bindThis private async delete(actor: MiRemoteUser, activity: IDelete): Promise { if (actor.uri !== activity.actor) { @@ -595,6 +858,7 @@ export class ApInboxService { }); if (isFollow(object)) return await this.rejectFollow(actor, object); + if (isInvite(object)) return await this.rejectInvite(actor, activity); return `skip: Unknown Reject type: ${getApType(object)}`; } @@ -623,6 +887,70 @@ export class ApInboxService { return 'ok'; } + @bindThis + private async rejectInvite(actor: MiRemoteUser, activity: IReject): Promise { + // actor is the one who rejected the invitation (invitee) + // activity is the Reject activity + // activity.object should be the Invite object being rejected + // activity.object.object should be the room URI + + this.logger.info(`[rejectInvite] Processing rejection from actor: ${actor.id}, username: ${actor.username}@${actor.host}`); + + const inviteObject = activity.object; + if (typeof inviteObject === 'string') { + this.logger.warn(`[rejectInvite] inviteObject is a string: ${inviteObject}`); + return 'skip: object must be a full Invite object, not a URI'; + } + + this.logger.info(`[rejectInvite] inviteObject type: ${(inviteObject as any).type}`); + + // The Invite object contains the room URI in its object property + const roomObject = (inviteObject as any).object; + if (!roomObject) { + this.logger.warn('[rejectInvite] invite object missing room'); + return 'skip: invite object missing room'; + } + + const roomUri = getApId(roomObject); + if (!roomUri) { + this.logger.warn('[rejectInvite] invalid room object'); + return 'skip: invalid room object'; + } + + this.logger.info(`[rejectInvite] Room URI: ${roomUri}`); + + // Extract room ID from URI + const roomIdMatch = roomUri.match(/\/chat\/rooms\/([a-zA-Z0-9]+)$/); + if (!roomIdMatch) return 'skip: invalid room URI format'; + const roomId = roomIdMatch[1]; + + this.logger.info(`[rejectInvite] Searching for invitation - roomId: ${roomId}, userId: ${actor.id}`); + + // Find the invitation and delete it + const invitation = await this.chatRoomInvitationsRepository.findOneBy({ + roomId, + userId: actor.id, + }); + + if (!invitation) { + this.logger.warn(`[rejectInvite] Invitation not found for roomId: ${roomId}, userId: ${actor.id}`); + // Try to find all invitations for this room to debug + const allInvitations = await this.chatRoomInvitationsRepository.findBy({ roomId }); + this.logger.warn(`[rejectInvite] All invitations for room ${roomId}: ${JSON.stringify(allInvitations.map(i => ({ id: i.id, userId: i.userId })))}`); + return 'skip: invitation not found'; + } + + this.logger.info(`[rejectInvite] Found invitation: ${invitation.id}, deleting...`); + + // Delete the invitation + const deleteResult = await this.chatRoomInvitationsRepository.delete({ id: invitation.id }); + + this.logger.info(`[rejectInvite] Delete result: ${JSON.stringify(deleteResult)}`); + this.logger.info(`[rejectInvite] Successfully deleted invitation ${invitation.id} from user ${actor.id} for room ${roomId}`); + + return 'ok'; + } + @bindThis private async remove(actor: MiRemoteUser, activity: IRemove, resolver?: Resolver): Promise { if (actor.uri !== activity.actor) { @@ -640,6 +968,31 @@ export class ApInboxService { return; } + // Handle chat room membership removal + const targetUri = getApId(activity.target); + this.logger.info(`[ApInboxService.remove] Processing Remove activity, target: ${targetUri}`); + + const roomIdMatch = targetUri.match(/\/chat\/rooms\/([a-zA-Z0-9]+)$/); + if (roomIdMatch) { + const roomId = roomIdMatch[1]; + this.logger.info(`[ApInboxService.remove] Matched room ID: ${roomId}, actor: ${actor.uri}`); + + const room = await this.chatRoomsRepository.findOneBy({ id: roomId }); + if (!room) { + this.logger.warn(`[ApInboxService.remove] Room not found: ${roomId}`); + return 'room not found'; + } + + // Delete the membership + const result = await this.chatRoomMembershipsRepository.delete({ + roomId: room.id, + userId: actor.id, + }); + + this.logger.info(`[ApInboxService.remove] Deleted membership, affected rows: ${result.affected}, room: ${room.id}, user: ${actor.id}`); + return 'ok: removed from chat room'; + } + return `unknown target: ${activity.target}`; } @@ -667,6 +1020,7 @@ export class ApInboxService { if (isLike(object)) return await this.undoLike(actor, object); if (isAnnounce(object)) return await this.undoAnnounce(actor, object); if (isAccept(object)) return await this.undoAccept(actor, object); + if (isInvite(object)) return await this.undoInvite(actor, object); return `skip: unknown object type ${getApType(object)}`; } @@ -693,6 +1047,45 @@ export class ApInboxService { return 'skip: フォローされていない'; } + @bindThis + private async undoInvite(actor: MiRemoteUser, activity: IInvite): Promise { + // Parse the room object from the Invite activity + const roomObject = activity.object; + if (typeof roomObject === 'string') return 'skip: object must be a full object, not a URI'; + + const roomUri = getApId(roomObject); + if (!roomUri) return 'skip: invalid room object'; + + // Extract room ID from URI + const roomIdMatch = roomUri.match(/\/chat\/rooms\/([a-zA-Z0-9]+)$/); + if (!roomIdMatch) return 'skip: invalid room URI format'; + const roomId = roomIdMatch[1]; + + // Get the target user (invitee) + const targetUri = getApHrefNullable(activity.target); + if (!targetUri) return 'skip: invalid activity target'; + + const invitee = await this.apDbResolverService.getUserFromApId(targetUri); + if (!invitee) return 'skip: target user not found'; + if (!this.userEntityService.isLocalUser(invitee)) return 'skip: target user is not local'; + + // Find and delete the invitation + const invitation = await this.chatRoomInvitationsRepository.findOneBy({ + roomId: roomId, + userId: invitee.id, + }); + + if (!invitation) { + this.logger.warn(`Invitation not found: room=${roomId}, user=${invitee.id}`); + return 'skip: invitation not found'; + } + + await this.chatRoomInvitationsRepository.delete(invitation.id); + + this.logger.info(`Cancelled invitation: room=${roomId}, user=${invitee.id}`); + return 'ok: invitation cancelled'; + } + @bindThis private async undoAnnounce(actor: MiRemoteUser, activity: IAnnounce): Promise { const uri = getApId(activity); @@ -851,4 +1244,88 @@ export class ApInboxService { return await this.apPersonService.updatePerson(actor.uri, resolver) ?? 'skip: nothing to do'; } + + @bindThis + private async invite(actor: MiRemoteUser, activity: IInvite, resolver?: Resolver): Promise { + // Parse the room object + const roomObject = activity.object; + if (typeof roomObject === 'string') return 'skip: object must be a full object, not a URI'; + + const roomUri = getApId(roomObject); + if (!roomUri) return 'skip: invalid room object'; + + // Extract room ID from URI (format: https://example.com/chat/rooms/{roomId}) + const roomIdMatch = roomUri.match(/\/chat\/rooms\/([a-zA-Z0-9]+)$/); + if (!roomIdMatch) return 'skip: invalid room URI format'; + const roomId = roomIdMatch[1]; + + // Get the target user (invitee) + const targetUri = getApHrefNullable(activity.target); + if (!targetUri) return 'skip: invalid activity target'; + + const invitee = await this.apDbResolverService.getUserFromApId(targetUri); + if (!invitee) return 'skip: target user not found'; + if (!this.userEntityService.isLocalUser(invitee)) return 'skip: target user is not local'; + + // Check if the room already exists locally + let room = await this.chatRoomsRepository.findOneBy({ id: roomId }); + + // If the room doesn't exist, create a local copy for the remote room + if (!room) { + const roomName = typeof roomObject.name === 'string' ? roomObject.name : 'Remote Chat Room'; + const roomDescription = typeof roomObject.summary === 'string' ? roomObject.summary : ''; + + // Extract owner from attributedTo field + let ownerId = actor.id; // Default to actor if attributedTo is not available + + if (roomObject.attributedTo) { + // Handle both single value and array + const attributedTo = Array.isArray(roomObject.attributedTo) + ? roomObject.attributedTo[0] + : roomObject.attributedTo; + const ownerUri = getApHrefNullable(attributedTo); + + if (ownerUri) { + const owner = await this.apDbResolverService.getUserFromApId(ownerUri); + if (owner) { + ownerId = owner.id; + } + } + } + + room = await this.chatRoomsRepository.insertOne({ + id: roomId, + name: roomName, + description: roomDescription, + ownerId: ownerId, + isArchived: false, + }); + } + + // Check if invitation already exists + const existingInvitation = await this.chatRoomInvitationsRepository.findOneBy({ + roomId: room.id, + userId: invitee.id, + }); + if (existingInvitation) { + return 'skip: invitation already exists'; + } + + // Create the invitation directly + const invitation = { + id: this.idService.gen(), + roomId: room.id, + userId: invitee.id, + }; + + await this.chatRoomInvitationsRepository.insertOne(invitation); + + // Send local notification + this.notificationService.createNotification(invitee.id, 'chatRoomInvitationReceived', { + invitationId: invitation.id, + }, actor.id); + + this.logger.info(`Created chat room invitation for local user ${invitee.id} to remote room ${room.id}`); + return 'ok'; + } } diff --git a/packages/backend/src/core/activitypub/ApRendererService.ts b/packages/backend/src/core/activitypub/ApRendererService.ts index 6648441d69..5a0644b794 100644 --- a/packages/backend/src/core/activitypub/ApRendererService.ts +++ b/packages/backend/src/core/activitypub/ApRendererService.ts @@ -28,10 +28,11 @@ import { bindThis } from '@/decorators.js'; import { CustomEmojiService } from '@/core/CustomEmojiService.js'; import { IdService } from '@/core/IdService.js'; import { UtilityService } from '@/core/UtilityService.js'; +import { RoleService } from '@/core/RoleService.js'; import { JsonLdService } from './JsonLdService.js'; import { ApMfmService } from './ApMfmService.js'; import { CONTEXT } from './misc/contexts.js'; -import type { IAccept, IActivity, IAdd, IAnnounce, IApDocument, IApEmoji, IApHashtag, IApImage, IApMention, IBlock, ICreate, IDelete, IFlag, IFollow, IKey, ILike, IMove, IObject, IPost, IQuestion, IRead, IReject, IRemove, ITombstone, IUndo, IUpdate } from './type.js'; +import type { IAccept, IActivity, IAdd, IAnnounce, IApDocument, IApEmoji, IApHashtag, IApImage, IApMention, IBlock, ICreate, IDelete, IFlag, IFollow, IInvite, IKey, ILike, IMove, IObject, IPost, IQuestion, IRead, IReject, IRemove, ITombstone, IUndo, IUpdate } from './type.js'; @Injectable() export class ApRendererService { @@ -69,6 +70,7 @@ export class ApRendererService { private mfmService: MfmService, private idService: IdService, private utilityService: UtilityService, + private roleService: RoleService, ) { } @@ -81,6 +83,16 @@ export class ApRendererService { }; } + @bindThis + public renderInvite(object: string | IObject, target: string, user: { id: MiUser['id']; host: null }): IInvite { + return { + type: 'Invite', + actor: this.userEntityService.genLocalUserUri(user.id), + object, + target, + }; + } + @bindThis public renderAdd(user: MiLocalUser, target: string | IObject | undefined, object: string | IObject): IAdd { return { @@ -484,7 +496,6 @@ export class ApRendererService { if (note.hasEvent) { const event = await this.eventsRepository.findOneBy({ noteId: note.id }); asEvent = event ? { - type: 'Event', name: event.title, startTime: event.start, endTime: event.end, @@ -535,10 +546,11 @@ export class ApRendererService { const id = this.userEntityService.genLocalUserUri(user.id); const isSystem = user.username.includes('.'); - const [avatar, banner, profile] = await Promise.all([ + const [avatar, banner, profile, policies] = await Promise.all([ user.avatarId ? this.driveFilesRepository.findOneBy({ id: user.avatarId }) : undefined, user.bannerId ? this.driveFilesRepository.findOneBy({ id: user.bannerId }) : undefined, this.userProfilesRepository.findOneByOrFail({ userId: user.id }), + this.roleService.getUserPolicies(user.id), ]); const tryRewriteUrl = (maybeUrl: string) => { @@ -597,6 +609,7 @@ export class ApRendererService { _misskey_requireSigninToViewContents: user.requireSigninToViewContents, _misskey_makeNotesFollowersOnlyBefore: user.makeNotesFollowersOnlyBefore, _misskey_makeNotesHiddenBefore: user.makeNotesHiddenBefore, + _misskey_canChat: policies.chatAvailability !== 'unavailable', icon: avatar ? this.renderImage(avatar) : isSystem ? this.renderSystemAvatar(user) : this.renderIdenticon(user), image: banner ? this.renderImage(banner) : isSystem ? this.renderSystemBanner() : null, tag, @@ -794,4 +807,73 @@ export class ApRendererService { return emojis; } + + /** + * Renders a chat message as an ActivityPub Note with `_misskey_talk` flag + * Compatible with legacy Misskey chat federation + */ + @bindThis + public async renderChatMessage(message: any, fromUser: MiUser, toUsers: MiUser[], roomId?: string): Promise { + const attributedTo = this.userEntityService.genLocalUserUri(fromUser.id); + + // Render recipients + const to: string[] = toUsers.map(user => + this.userEntityService.isRemoteUser(user) + ? user.uri! + : this.userEntityService.genLocalUserUri(user.id), + ); + + // Get file if attached + let attachment: IApDocument | undefined; + if (message.fileId) { + const file = await this.driveFilesRepository.findOneBy({ id: message.fileId }); + if (file) { + attachment = this.renderDocument(file); + } + } + + // Get emojis + const emojis = message.emojis && message.emojis.length > 0 ? await this.getEmojis(message.emojis) : []; + const apemojis = emojis.filter(emoji => !emoji.localOnly).map(emoji => this.renderEmoji(emoji)); + + const note: IPost = { + id: message.uri ?? `${this.config.url}/chat/messages/${message.id}`, + type: 'Note', + attributedTo, + content: message.text ?? '', + to, + published: this.idService.parse(message.id).date.toISOString(), + _misskey_talk: true, // Legacy Misskey chat + }; + + // Add context for group chat + if (roomId) { + note['@context'] = `${this.config.url}/chat/rooms/${roomId}`; + } + + if (attachment) { + note.attachment = [attachment]; + } + + if (apemojis.length > 0) { + note.tag = apemojis; + } + + return note; + } + + @bindThis + public renderChatRoom(room: any, owner: MiUser): IObject { + const ownerUri = this.userEntityService.isLocalUser(owner) + ? this.userEntityService.genLocalUserUri(owner.id) + : owner.uri; + + return { + type: 'Group', + id: `${this.config.url}/chat/rooms/${room.id}`, + name: room.name, + summary: room.description || undefined, + attributedTo: ownerUri || undefined, + }; + } } diff --git a/packages/backend/src/core/activitypub/ApResolverService.ts b/packages/backend/src/core/activitypub/ApResolverService.ts index 2534899ad1..646150455b 100644 --- a/packages/backend/src/core/activitypub/ApResolverService.ts +++ b/packages/backend/src/core/activitypub/ApResolverService.ts @@ -104,7 +104,7 @@ export class Resolver { throw new IdentifiableError('09d79f9e-64f1-4316-9cfa-e75c4d091574', 'Instance is blocked'); } - if (this.config.signToActivityPubGet && !this.user) { + if (this.meta.signToActivityPubGet && !this.user) { this.user = await this.systemAccountService.fetch('actor'); } diff --git a/packages/backend/src/core/activitypub/models/ApEventService.ts b/packages/backend/src/core/activitypub/models/ApEventService.ts index 77cdb0beb9..48ab6c68af 100644 --- a/packages/backend/src/core/activitypub/models/ApEventService.ts +++ b/packages/backend/src/core/activitypub/models/ApEventService.ts @@ -26,9 +26,15 @@ export class ApEventService { @bindThis public async extractEventFromNote(source: string | IObject, resolverParam?: Resolver): Promise { - const resolver = resolverParam ?? this.apResolverService.createResolver(); + let note: IObject; - const note = await resolver.resolve(source); + if (typeof source === 'object') { + note = source; + } else { + const resolver = resolverParam ?? this.apResolverService.createResolver(); + + note = await resolver.resolve(source); + } if (!isEvent(note)) { throw new Error('invalid type'); @@ -36,8 +42,8 @@ export class ApEventService { if (note.name && note.startTime) { const title = note.name; - const start = note.startTime; - const end = note.endTime ?? null; + const start = new Date(note.startTime); + const end = note.endTime ? new Date(note.endTime) : null; return { title, @@ -47,8 +53,8 @@ export class ApEventService { '@type': 'Event', name: note.name, url: note.href, - startDate: note.startTime.toISOString(), - endDate: note.endTime?.toISOString(), + startDate: start.toISOString(), + endDate: end?.toISOString(), description: note.summary, identifier: note.id, }, diff --git a/packages/backend/src/core/activitypub/models/ApPersonService.ts b/packages/backend/src/core/activitypub/models/ApPersonService.ts index c8b31b9e32..b4c488a0ef 100644 --- a/packages/backend/src/core/activitypub/models/ApPersonService.ts +++ b/packages/backend/src/core/activitypub/models/ApPersonService.ts @@ -472,6 +472,7 @@ export class ApPersonService implements OnModuleInit { emojis, setFederationAvatarShape: person.setFederationAvatarShape, isSquareAvatars: person.isSquareAvatars, + canChat: (person as any)._misskey_canChat ?? true, })) as MiRemoteUser; let _description: string | null = null; @@ -722,6 +723,7 @@ export class ApPersonService implements OnModuleInit { isExplorable: person.discoverable, setFederationAvatarShape: person.setFederationAvatarShape, isSquareAvatars: person.isSquareAvatars, + canChat: (person as any)._misskey_canChat ?? true, ...(await this.resolveAvatarAndBanner(exist, person.icon, person.image).catch(() => ({}))), } as Partial & Pick; diff --git a/packages/backend/src/core/activitypub/type.ts b/packages/backend/src/core/activitypub/type.ts index 1c4a50f5de..d39e205289 100644 --- a/packages/backend/src/core/activitypub/type.ts +++ b/packages/backend/src/core/activitypub/type.ts @@ -133,6 +133,7 @@ export interface IPost extends IObject { }; _misskey_quote?: string; _misskey_content?: string; + _misskey_talk?: boolean; quoteUrl?: string; } @@ -343,6 +344,10 @@ export interface IMove extends IActivity { target: IObject | string; } +export interface IInvite extends IActivity { + type: 'Invite'; +} + export const isCreate = (object: IObject): object is ICreate => getApType(object) === 'Create'; export const isDelete = (object: IObject): object is IDelete => getApType(object) === 'Delete'; export const isUpdate = (object: IObject): object is IUpdate => getApType(object) === 'Update'; @@ -360,4 +365,5 @@ export const isAnnounce = (object: IObject): object is IAnnounce => getApType(ob export const isBlock = (object: IObject): object is IBlock => getApType(object) === 'Block'; export const isFlag = (object: IObject): object is IFlag => getApType(object) === 'Flag'; export const isMove = (object: IObject): object is IMove => getApType(object) === 'Move'; +export const isInvite = (object: IObject): object is IInvite => getApType(object) === 'Invite'; export const isNote = (object: IObject): object is IPost => getApType(object) === 'Note'; diff --git a/packages/backend/src/core/chart/charts/entities/federation.ts b/packages/backend/src/core/chart/charts/entities/federation.ts index 5ed7804343..d1b226da4a 100644 --- a/packages/backend/src/core/chart/charts/entities/federation.ts +++ b/packages/backend/src/core/chart/charts/entities/federation.ts @@ -16,6 +16,7 @@ export const schema = { 'pubsub': { accumulate: true, range: 'small' }, 'subActive': { accumulate: true, range: 'small' }, 'pubActive': { accumulate: true, range: 'small' }, + 'software': { accumulate: true, range: 'small' }, } as const; export const entity = Chart.schemaToEntity(name, schema); diff --git a/packages/backend/src/core/chart/charts/federation.ts b/packages/backend/src/core/chart/charts/federation.ts index c9b43cc66d..626dfd6e7b 100644 --- a/packages/backend/src/core/chart/charts/federation.ts +++ b/packages/backend/src/core/chart/charts/federation.ts @@ -60,7 +60,7 @@ export default class FederationChart extends Chart { // eslint-di .select('f.followerHost') .where('f.followerHost IS NOT NULL'); - const [sub, pub, pubsub, subActive, pubActive] = await Promise.all([ + const [sub, pub, pubsub, subActive, pubActive, software] = await Promise.all([ this.followingsRepository.createQueryBuilder('following') .select('COUNT(DISTINCT following.followeeHost)') .where('following.followeeHost IS NOT NULL') @@ -100,6 +100,14 @@ export default class FederationChart extends Chart { // eslint-di .andWhere('instance.isNotResponding = false') .getRawOne() .then(x => parseInt(x.count, 10)), + this.instancesRepository.createQueryBuilder('instance') + .select('COUNT(DISTINCT instance.softwareName)') + .where('instance.host IS NOT NULL') + .andWhere(this.meta.blockedHosts.length === 0 ? '1=1' : 'instance.host NOT ILIKE ALL(ARRAY[:...blocked])', { blocked: this.meta.blockedHosts.flatMap(x => [x, `%.${x}`]) }) + .andWhere('instance.suspensionState = \'none\'') + .andWhere('instance.isNotResponding = false') + .getRawOne() + .then(x => parseInt(x.count, 10)), ]); return { @@ -108,6 +116,7 @@ export default class FederationChart extends Chart { // eslint-di 'pubsub': pubsub, 'subActive': subActive, 'pubActive': pubActive, + 'software': software, }; } diff --git a/packages/backend/src/core/entities/ChatEntityService.ts b/packages/backend/src/core/entities/ChatEntityService.ts index da112d5444..f88d886e38 100644 --- a/packages/backend/src/core/entities/ChatEntityService.ts +++ b/packages/backend/src/core/entities/ChatEntityService.ts @@ -4,16 +4,17 @@ */ import { Inject, Injectable } from '@nestjs/common'; +import { In } from 'typeorm'; import { DI } from '@/di-symbols.js'; -import type { MiUser, ChatMessagesRepository, MiChatMessage, ChatRoomsRepository, MiChatRoom, MiChatRoomInvitation, ChatRoomInvitationsRepository, MiChatRoomMembership, ChatRoomMembershipsRepository } from '@/models/_.js'; +import type { MiUser, ChatMessagesRepository, MiChatMessage, ChatRoomsRepository, MiChatRoom, MiChatRoomInvitation, ChatRoomInvitationsRepository, MiChatRoomMembership, ChatRoomMembershipsRepository, UsersRepository } from '@/models/_.js'; import { awaitAll } from '@/misc/prelude/await-all.js'; import type { Packed } from '@/misc/json-schema.js'; import type { } from '@/models/Blocking.js'; import { bindThis } from '@/decorators.js'; import { IdService } from '@/core/IdService.js'; +import { CustomEmojiService } from '@/core/CustomEmojiService.js'; import { UserEntityService } from './UserEntityService.js'; import { DriveFileEntityService } from './DriveFileEntityService.js'; -import { In } from 'typeorm'; @Injectable() export class ChatEntityService { @@ -30,8 +31,12 @@ export class ChatEntityService { @Inject(DI.chatRoomMembershipsRepository) private chatRoomMembershipsRepository: ChatRoomMembershipsRepository, + @Inject(DI.usersRepository) + private usersRepository: UsersRepository, + private userEntityService: UserEntityService, private driveFileEntityService: DriveFileEntityService, + private customEmojiService: CustomEmojiService, private idService: IdService, ) { } @@ -54,29 +59,40 @@ export class ChatEntityService { const message = typeof src === 'object' ? src : await this.chatMessagesRepository.findOneByOrFail({ id: src }); - const reactions: { user: Packed<'UserLite'>; reaction: string; }[] = []; + // userは削除されている可能性があるのでnull許容 + const reactions: { user: Packed<'UserLite'> | null; reaction: string; }[] = []; for (const record of message.reactions) { const [userId, reaction] = record.split('/'); reactions.push({ - user: packedUsers?.get(userId) ?? await this.userEntityService.pack(userId), + user: packedUsers?.get(userId) ?? await this.userEntityService.pack(userId).catch(() => null), reaction, }); } + // Get fromUser host for emoji URL resolution + const fromUser = message.fromUser ?? await this.usersRepository.findOneBy({ id: message.fromUserId }); + const fromUserHost = fromUser?.host ?? null; + + // Populate emoji URLs - only for remote users, like notes do + const emojis = fromUserHost != null + ? await this.customEmojiService.populateEmojis(message.emojis, fromUserHost) + : undefined; + return { id: message.id, createdAt: this.idService.parse(message.id).date.toISOString(), text: message.text, fromUserId: message.fromUserId, - fromUser: packedUsers?.get(message.fromUserId) ?? await this.userEntityService.pack(message.fromUser ?? message.fromUserId, me), + fromUser: packedUsers?.get(message.fromUserId) ?? await this.userEntityService.pack(fromUser ?? message.fromUserId, me), toUserId: message.toUserId, toUser: message.toUserId ? (packedUsers?.get(message.toUserId) ?? await this.userEntityService.pack(message.toUser ?? message.toUserId, me)) : undefined, toRoomId: message.toRoomId, toRoom: message.toRoomId ? (packedRooms?.get(message.toRoomId) ?? await this.packRoom(message.toRoom ?? message.toRoomId, me)) : undefined, fileId: message.fileId, file: message.fileId ? (packedFiles?.get(message.fileId) ?? await this.driveFileEntityService.pack(message.file ?? message.fileId)) : null, - reactions, + reactions: reactions.filter((r): r is { user: Packed<'UserLite'>; reaction: string; } => r.user != null), + emojis: emojis, }; } @@ -108,6 +124,7 @@ export class ChatEntityService { } } + // TODO: packedUsersに削除されたユーザーもnullとして含める const [packedUsers, packedFiles, packedRooms] = await Promise.all([ this.userEntityService.packMany(users, me) .then(users => new Map(users.map(u => [u.id, u]))), @@ -142,6 +159,15 @@ export class ChatEntityService { }); } + // Get fromUser host for emoji URL resolution + const fromUser = message.fromUser ?? await this.usersRepository.findOneBy({ id: message.fromUserId }); + const fromUserHost = fromUser?.host ?? null; + + // Populate emoji URLs - only for remote users, like notes do + const emojis = fromUserHost != null + ? await this.customEmojiService.populateEmojis(message.emojis, fromUserHost) + : undefined; + return { id: message.id, createdAt: this.idService.parse(message.id).date.toISOString(), @@ -151,6 +177,7 @@ export class ChatEntityService { fileId: message.fileId, file: message.fileId ? (packedFiles?.get(message.fileId) ?? await this.driveFileEntityService.pack(message.file ?? message.fileId)) : null, reactions, + emojis: emojis, }; } @@ -183,26 +210,37 @@ export class ChatEntityService { const message = typeof src === 'object' ? src : await this.chatMessagesRepository.findOneByOrFail({ id: src }); - const reactions: { user: Packed<'UserLite'>; reaction: string; }[] = []; + // userは削除されている可能性があるのでnull許容 + const reactions: { user: Packed<'UserLite'> | null; reaction: string; }[] = []; for (const record of message.reactions) { const [userId, reaction] = record.split('/'); reactions.push({ - user: packedUsers?.get(userId) ?? await this.userEntityService.pack(userId), + user: packedUsers?.get(userId) ?? await this.userEntityService.pack(userId).catch(() => null), reaction, }); } + // Get fromUser host for emoji URL resolution + const fromUser = message.fromUser ?? await this.usersRepository.findOneBy({ id: message.fromUserId }); + const fromUserHost = fromUser?.host ?? null; + + // Populate emoji URLs - only for remote users, like notes do + const emojis = fromUserHost != null + ? await this.customEmojiService.populateEmojis(message.emojis, fromUserHost) + : undefined; + return { id: message.id, createdAt: this.idService.parse(message.id).date.toISOString(), text: message.text, fromUserId: message.fromUserId, - fromUser: packedUsers?.get(message.fromUserId) ?? await this.userEntityService.pack(message.fromUser ?? message.fromUserId), + fromUser: packedUsers?.get(message.fromUserId) ?? await this.userEntityService.pack(fromUser ?? message.fromUserId), toRoomId: message.toRoomId!, fileId: message.fileId, file: message.fileId ? (packedFiles?.get(message.fileId) ?? await this.driveFileEntityService.pack(message.file ?? message.fileId)) : null, - reactions, + reactions: reactions.filter((r): r is { user: Packed<'UserLite'>; reaction: string; } => r.user != null), + emojis: emojis, }; } @@ -238,13 +276,15 @@ export class ChatEntityService { options?: { _hint_?: { packedOwners: Map>; - memberships?: Map; + myMemberships?: Map; + myInvitations?: Map; }; }, ): Promise> { const room = typeof src === 'object' ? src : await this.chatRoomsRepository.findOneByOrFail({ id: src }); - const membership = me && me.id !== room.ownerId ? (options?._hint_?.memberships?.get(room.id) ?? await this.chatRoomMembershipsRepository.findOneBy({ roomId: room.id, userId: me.id })) : null; + const membership = me && me.id !== room.ownerId ? (options?._hint_?.myMemberships?.get(room.id) ?? await this.chatRoomMembershipsRepository.findOneBy({ roomId: room.id, userId: me.id })) : null; + const invitation = me && me.id !== room.ownerId ? (options?._hint_?.myInvitations?.get(room.id) ?? await this.chatRoomInvitationsRepository.findOneBy({ roomId: room.id, userId: me.id })) : null; return { id: room.id, @@ -254,6 +294,7 @@ export class ChatEntityService { ownerId: room.ownerId, owner: options?._hint_?.packedOwners.get(room.ownerId) ?? await this.userEntityService.pack(room.owner ?? room.ownerId, me), isMuted: membership != null ? membership.isMuted : false, + invitationExists: invitation != null, }; } @@ -278,7 +319,7 @@ export class ChatEntityService { const owners = _rooms.map(x => x.owner ?? x.ownerId); - const [packedOwners, memberships] = await Promise.all([ + const [packedOwners, myMemberships, myInvitations] = await Promise.all([ this.userEntityService.packMany(owners, me) .then(users => new Map(users.map(u => [u.id, u]))), this.chatRoomMembershipsRepository.find({ @@ -287,9 +328,15 @@ export class ChatEntityService { userId: me.id, }, }).then(memberships => new Map(_rooms.map(r => [r.id, memberships.find(m => m.roomId === r.id)]))), + this.chatRoomInvitationsRepository.find({ + where: { + roomId: In(_rooms.map(x => x.id)), + userId: me.id, + }, + }).then(invitations => new Map(_rooms.map(r => [r.id, invitations.find(i => i.roomId === r.id)]))), ]); - return Promise.all(_rooms.map(room => this.packRoom(room, me, { _hint_: { packedOwners, memberships } }))); + return Promise.all(_rooms.map(room => this.packRoom(room, me, { _hint_: { packedOwners, myMemberships, myInvitations } }))); } @bindThis diff --git a/packages/backend/src/core/entities/DriveFileEntityService.ts b/packages/backend/src/core/entities/DriveFileEntityService.ts index 9d4c5e1f68..67c8115caf 100644 --- a/packages/backend/src/core/entities/DriveFileEntityService.ts +++ b/packages/backend/src/core/entities/DriveFileEntityService.ts @@ -6,7 +6,7 @@ import { forwardRef, Inject, Injectable } from '@nestjs/common'; import { In } from 'typeorm'; import { DI } from '@/di-symbols.js'; -import type { DriveFilesRepository } from '@/models/_.js'; +import type { DriveFilesRepository, MiMeta } from '@/models/_.js'; import type { Config } from '@/config.js'; import type { Packed } from '@/misc/json-schema.js'; import { awaitAll } from '@/misc/prelude/await-all.js'; @@ -34,6 +34,9 @@ export class DriveFileEntityService { @Inject(DI.config) private config: Config, + @Inject(DI.meta) + private meta: MiMeta, + @Inject(DI.driveFilesRepository) private driveFilesRepository: DriveFilesRepository, @@ -95,7 +98,7 @@ export class DriveFileEntityService { return this.getProxiedUrl(file.uri, 'static'); } - if (file.uri != null && file.isLink && this.config.proxyRemoteFiles) { + if (file.uri != null && file.isLink && this.meta.proxyRemoteFiles) { // リモートかつ期限切れはローカルプロキシを試みる // 従来は/files/${thumbnailAccessKey}にアクセスしていたが、 // /filesはメディアプロキシにリダイレクトするようにしたため直接メディアプロキシを指定する @@ -115,7 +118,7 @@ export class DriveFileEntityService { } // リモートかつ期限切れはローカルプロキシを試みる - if (file.uri != null && file.isLink && this.config.proxyRemoteFiles) { + if (file.uri != null && file.isLink && this.meta.proxyRemoteFiles) { const key = file.webpublicAccessKey; if (key && !key.match('/')) { // 古いものはここにオブジェクトストレージキーが入ってるので除外 diff --git a/packages/backend/src/core/entities/MetaEntityService.ts b/packages/backend/src/core/entities/MetaEntityService.ts index 82a72a3edb..0e51e35a6f 100644 --- a/packages/backend/src/core/entities/MetaEntityService.ts +++ b/packages/backend/src/core/entities/MetaEntityService.ts @@ -116,6 +116,7 @@ export class MetaEntityService { defaultDarkTheme, customHidedNoteLightText: instance.customHidedNoteLightText, customHidedNoteDarkText: instance.customHidedNoteDarkText, + clientOptions: instance.clientOptions, ads: ads.map(ad => ({ id: ad.id, url: ad.url, @@ -123,6 +124,7 @@ export class MetaEntityService { ratio: ad.ratio, imageUrl: ad.imageUrl, dayOfWeek: ad.dayOfWeek, + isSensitive: ad.isSensitive ? true : undefined, })), trustedLinkUrlPatterns: instance.trustedLinkUrlPatterns, notesPerOneAd: instance.notesPerOneAd, diff --git a/packages/backend/src/core/entities/NoteDraftEntityService.ts b/packages/backend/src/core/entities/NoteDraftEntityService.ts index 68a1e19b1f..f8f0209519 100644 --- a/packages/backend/src/core/entities/NoteDraftEntityService.ts +++ b/packages/backend/src/core/entities/NoteDraftEntityService.ts @@ -5,6 +5,7 @@ import { Inject, Injectable } from '@nestjs/common'; import { ModuleRef } from '@nestjs/core'; +import { EntityNotFoundError } from 'typeorm'; import { DI } from '@/di-symbols.js'; import type { Packed } from '@/misc/json-schema.js'; import { awaitAll } from '@/misc/prelude/await-all.js'; @@ -90,9 +91,22 @@ export class NoteDraftEntityService implements OnModuleInit { const packedFiles = options?._hint_?.packedFiles; const packedUsers = options?._hint_?.packedUsers; + async function nullIfEntityNotFound(promise: Promise): Promise { + try { + return await promise; + } catch (err) { + if (err instanceof EntityNotFoundError) { + return null; + } + throw err; + } + } + const packed: Packed<'NoteDraft'> = await awaitAll({ id: noteDraft.id, createdAt: this.idService.parse(noteDraft.id).date.toISOString(), + scheduledAt: noteDraft.scheduledAt?.getTime() ?? null, + isActuallyScheduled: noteDraft.isActuallyScheduled, deleteAt: noteDraft.deleteAt ? noteDraft.deleteAt.toISOString() : undefined, userId: noteDraft.userId, user: packedUsers?.get(noteDraft.userId) ?? this.userEntityService.pack(noteDraft.user ?? noteDraft.userId, me), @@ -101,14 +115,14 @@ export class NoteDraftEntityService implements OnModuleInit { visibility: noteDraft.visibility, localOnly: noteDraft.localOnly, reactionAcceptance: noteDraft.reactionAcceptance, - visibleUserIds: noteDraft.visibility === 'specified' ? noteDraft.visibleUserIds : undefined, + visibleUserIds: noteDraft.visibleUserIds, disableRightClick: noteDraft.disableRightClick || undefined, hashtag: noteDraft.hashtag, fileIds: noteDraft.fileIds, files: packedFiles != null ? this.packAttachedFiles(noteDraft.fileIds, packedFiles) : this.driveFileEntityService.packManyByIds(noteDraft.fileIds), replyId: noteDraft.replyId, renoteId: noteDraft.renoteId, - channelId: noteDraft.channelId ?? undefined, + channelId: noteDraft.channelId, channel: channel ? { id: channel.id, name: channel.name, @@ -117,31 +131,30 @@ export class NoteDraftEntityService implements OnModuleInit { allowRenoteToExternal: channel.allowRenoteToExternal, userId: channel.userId, } : undefined, + poll: noteDraft.hasPoll ? { + choices: noteDraft.pollChoices, + multiple: noteDraft.pollMultiple, + expiresAt: noteDraft.pollExpiresAt?.toISOString(), + expiredAfter: noteDraft.pollExpiredAfter, + } : null, + event: noteDraft.hasEvent ? { + title: noteDraft.eventTitle, + start: noteDraft.eventStart?.getTime(), + end: noteDraft.eventEnd?.getTime(), + metadata: noteDraft.eventMetadata, + } : undefined, + deliveryTargets: noteDraft.deliveryTargets ?? undefined, ...(opts.detail ? { - reply: noteDraft.replyId ? this.noteEntityService.pack(noteDraft.replyId, me, { + reply: noteDraft.replyId ? nullIfEntityNotFound(this.noteEntityService.pack(noteDraft.replyId, me, { detail: false, skipHide: opts.skipHide, - }) : undefined, + })) : undefined, - renote: noteDraft.renoteId ? this.noteEntityService.pack(noteDraft.renoteId, me, { + renote: noteDraft.renoteId ? nullIfEntityNotFound(this.noteEntityService.pack(noteDraft.renoteId, me, { detail: true, skipHide: opts.skipHide, - }) : undefined, - - poll: noteDraft.hasPoll ? { - choices: noteDraft.pollChoices, - multiple: noteDraft.pollMultiple, - expiresAt: noteDraft.pollExpiresAt?.toISOString(), - expiredAfter: noteDraft.pollExpiredAfter, - } : undefined, - - event: noteDraft.hasEvent ? { - title: noteDraft.eventTitle, - start: noteDraft.eventStart.getTime(), - end: noteDraft.eventEnd?.getTime(), - metadata: noteDraft.eventMetadata, - } : undefined, + })) : undefined, } : {} ), }); diff --git a/packages/backend/src/core/entities/NoteEntityService.ts b/packages/backend/src/core/entities/NoteEntityService.ts index 321c7fe2da..b218bad305 100644 --- a/packages/backend/src/core/entities/NoteEntityService.ts +++ b/packages/backend/src/core/entities/NoteEntityService.ts @@ -4,18 +4,19 @@ */ import { Inject, Injectable } from '@nestjs/common'; -import { In } from 'typeorm'; +import { EntityNotFoundError, In } from 'typeorm'; import { ModuleRef } from '@nestjs/core'; import { DI } from '@/di-symbols.js'; import type { Packed } from '@/misc/json-schema.js'; import { awaitAll } from '@/misc/prelude/await-all.js'; import type { MiUser } from '@/models/User.js'; import type { MiNote } from '@/models/Note.js'; -import type { UsersRepository, NotesRepository, FollowingsRepository, PollsRepository, PollVotesRepository, NoteReactionsRepository, ChannelsRepository, MiMeta, EventsRepository } from '@/models/_.js'; +import type { UsersRepository, NotesRepository, FollowingsRepository, PollsRepository, PollVotesRepository, NoteReactionsRepository, ChannelsRepository, InstancesRepository, MiMeta, EventsRepository } from '@/models/_.js'; import { bindThis } from '@/decorators.js'; import { DebounceLoader } from '@/misc/loader.js'; import { IdService } from '@/core/IdService.js'; import { ReactionsBufferingService } from '@/core/ReactionsBufferingService.js'; +import { RoleService } from '@/core/RoleService.js'; import type { OnModuleInit } from '@nestjs/common'; import type { CustomEmojiService } from '../CustomEmojiService.js'; import type { ReactionService } from '../ReactionService.js'; @@ -47,6 +48,17 @@ function getAppearNoteIds(notes: MiNote[]): Set { return appearNoteIds; } +async function nullIfEntityNotFound(promise: Promise): Promise { + try { + return await promise; + } catch (err) { + if (err instanceof EntityNotFoundError) { + return null; + } + throw err; + } +} + @Injectable() export class NoteEntityService implements OnModuleInit { private userEntityService: UserEntityService; @@ -57,6 +69,7 @@ export class NoteEntityService implements OnModuleInit { private idService: IdService; private roleService: RoleService; private noteLoader = new DebounceLoader(this.findNoteOrFail); + private roleService: RoleService; constructor( private moduleRef: ModuleRef, @@ -88,6 +101,9 @@ export class NoteEntityService implements OnModuleInit { @Inject(DI.channelsRepository) private channelsRepository: ChannelsRepository, + @Inject(DI.instancesRepository) + private instancesRepository: InstancesRepository, + //private userEntityService: UserEntityService, //private driveFileEntityService: DriveFileEntityService, //private customEmojiService: CustomEmojiService, @@ -397,9 +413,9 @@ export class NoteEntityService implements OnModuleInit { }, options); const meId = me ? me.id : null; - const iAmModerator = me ? await this.roleService.isModerator(me as MiUser) : false; const note = typeof src === 'object' ? src : await this.noteLoader.load(src); const host = note.userHost; + const iAmModerator = me ? await this.roleService.isModerator(me as MiUser) : false; const bufferedReactions = opts._hint_?.bufferedReactions != null ? (opts._hint_.bufferedReactions.get(note.id) ?? { deltas: {}, pairs: [] }) @@ -412,7 +428,7 @@ export class NoteEntityService implements OnModuleInit { let text = note.text; - if (note.name && (note.url ?? note.uri)) { + if (note.name && (note.url ?? note.uri) && !note.hasEvent) { text = `【${note.name}】\n${(note.text ?? '').trim()}\n\n${note.url ?? note.uri}`; } @@ -434,7 +450,6 @@ export class NoteEntityService implements OnModuleInit { createdAt: this.idService.parse(note.id).date.toISOString(), updatedAt: note.updatedAt ? note.updatedAt.toISOString() : undefined, updatedAtHistory: note.updatedAtHistory ? note.updatedAtHistory.map(x => x.toISOString()) : undefined, - noteEditHistory: note.noteEditHistory.length ? note.noteEditHistory : undefined, deleteAt: note.deleteAt ? note.deleteAt.toISOString() : undefined, userId: note.userId, user: packedUsers?.get(note.userId) ?? this.userEntityService.pack(note.user ?? note.userId, me), @@ -467,29 +482,46 @@ export class NoteEntityService implements OnModuleInit { userId: channel.userId, } : undefined, mentions: note.mentions.length > 0 ? note.mentions : undefined, + hasPoll: note.hasPoll || undefined, + uri: note.uri ?? undefined, + url: note.url ?? undefined, hasDeliveryTargets: note.deliveryTargets != null, ...((meId === note.userId || iAmModerator) ? { - deliveryTargets: note.deliveryTargets ?? undefined, + deliveryTargets: note.deliveryTargets ? await (async () => { + const deliveryTargets = note.deliveryTargets!; + const instances = await this.instancesRepository.findBy({ + host: In(deliveryTargets.hosts), + }); + const instanceMap = new Map(instances.map(i => [i.host, i.name])); + + return { + mode: deliveryTargets.mode, + hosts: deliveryTargets.hosts, + names: deliveryTargets.hosts.map(host => instanceMap.get(host) ?? null), + }; + })() : undefined, } : {}), - uri: note.uri ?? undefined, - url: note.url ?? undefined, ...(opts.detail ? { clippedCount: note.clippedCount, - reply: note.replyId ? this.pack(note.reply ?? note.replyId, me, { - detail: false, + // そもそもJOINしていない場合はundefined、JOINしたけど存在していなかった場合はnullで区別される + reply: (note.replyId && note.reply === null) ? null : note.replyId ? nullIfEntityNotFound(this.pack(note.reply ?? note.replyId, me, { + // NOTE: 기본값은 false 이지만, 2025.10.0 대응 과정에서 코드가 변경됨에 따라 MkSubNoteContent에서 myReaction을 불러오지 못하는 문제가 있으므로 true로 변경됨. + // myReaction을 불러오지 못하면 자신이 리액션 했다는 정보를 불러오지 못하므로 이미 리액션을 했더라도 다시 눌러 리액션을 취소하는 기능을 사용할 수 없고, 리액션을 중복으로 등록하려고 시도하게됨. + detail: true, skipHide: opts.skipHide, withReactionAndUserPairCache: opts.withReactionAndUserPairCache, _hint_: options?._hint_, - }) : undefined, + })) : undefined, - renote: note.renoteId ? this.pack(note.renote ?? note.renoteId, me, { + // そもそもJOINしていない場合はundefined、JOINしたけど存在していなかった場合はnullで区別される + renote: (note.renoteId && note.renote === null) ? null : note.renoteId ? nullIfEntityNotFound(this.pack(note.renote ?? note.renoteId, me, { detail: true, skipHide: opts.skipHide, withReactionAndUserPairCache: opts.withReactionAndUserPairCache, _hint_: options?._hint_, - }) : undefined, + })) : undefined, poll: note.hasPoll ? this.populatePoll(note, meId) : undefined, event: note.hasEvent ? this.populateEvent(note) : undefined, @@ -593,8 +625,7 @@ export class NoteEntityService implements OnModuleInit { ]; const packedUsers = await this.userEntityService.packMany(users, me) .then(users => new Map(users.map(u => [u.id, u]))); - - return await Promise.all(notes.map(n => this.pack(n, me, { + const packedNotes = await Promise.all(notes.map(n => this.pack(n, me, { ...options, _hint_: { bufferedReactions, @@ -603,6 +634,8 @@ export class NoteEntityService implements OnModuleInit { packedUsers, }, }))); + + return packedNotes.filter(note => !note.isHidden); } @bindThis @@ -633,7 +666,45 @@ export class NoteEntityService implements OnModuleInit { private findNoteOrFail(id: string): Promise { return this.notesRepository.findOneOrFail({ where: { id }, - relations: ['user'], + relations: ['user', 'renote', 'reply'], + }); + } + + @bindThis + public async fetchDiffs(noteIds: MiNote['id'][]) { + if (noteIds.length === 0) return []; + + const notes = await this.notesRepository.find({ + where: { + id: In(noteIds), + }, + select: { + id: true, + userHost: true, + reactions: true, + reactionAndUserPairCache: true, + }, }); + + const bufferedReactionsMap = this.meta.enableReactionsBuffering ? await this.reactionsBufferingService.getMany(noteIds) : null; + + const packings = notes.map(note => { + const bufferedReactions = bufferedReactionsMap?.get(note.id); + //const reactionAndUserPairCache = note.reactionAndUserPairCache.concat(bufferedReactions.pairs.map(x => x.join('/'))); + + const reactions = this.reactionService.convertLegacyReactions(this.reactionsBufferingService.mergeReactions(note.reactions, bufferedReactions?.deltas ?? {})); + + const reactionEmojiNames = Object.keys(reactions) + .filter(x => x.startsWith(':') && x.includes('@') && !x.includes('@.')) // リモートカスタム絵文字のみ + .map(x => this.reactionService.decodeReaction(x).reaction.replaceAll(':', '')); + + return this.customEmojiService.populateEmojis(reactionEmojiNames, note.userHost).then(reactionEmojis => ({ + id: note.id, + reactions, + reactionEmojis, + })); + }); + + return await Promise.all(packings); } } diff --git a/packages/backend/src/core/entities/NoteHistoryEntityService.ts b/packages/backend/src/core/entities/NoteHistoryEntityService.ts new file mode 100644 index 0000000000..077be26e0a --- /dev/null +++ b/packages/backend/src/core/entities/NoteHistoryEntityService.ts @@ -0,0 +1,183 @@ +/* + * SPDX-FileCopyrightText: noridev and cherrypick-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { Inject, Injectable } from '@nestjs/common'; +import { In } from 'typeorm'; +import { ModuleRef } from '@nestjs/core'; +import { DI } from '@/di-symbols.js'; +import type { Packed } from '@/misc/json-schema.js'; +import { awaitAll } from '@/misc/prelude/await-all.js'; +import type { MiUser } from '@/models/User.js'; +import type { MiNote } from '@/models/Note.js'; +import type { UsersRepository, NotesRepository, FollowingsRepository, PollsRepository, PollVotesRepository, NoteReactionsRepository, ChannelsRepository, NoteHistoryRepository } from '@/models/_.js'; +import { bindThis } from '@/decorators.js'; +import { DebounceLoader } from '@/misc/loader.js'; +import { IdService } from '@/core/IdService.js'; +import { NoteHistory } from '@/models/NoteHistory.js'; +import type { OnModuleInit } from '@nestjs/common'; +import type { CustomEmojiService } from '../CustomEmojiService.js'; +import type { UserEntityService } from './UserEntityService.js'; +import type { DriveFileEntityService } from './DriveFileEntityService.js'; + +@Injectable() +export class NoteHistoryEntityService implements OnModuleInit { + private userEntityService: UserEntityService; + private driveFileEntityService: DriveFileEntityService; + private customEmojiService: CustomEmojiService; + private idService: IdService; + private historyLoader = new DebounceLoader(this.findNoteHistoryOrFail); + + constructor( + private moduleRef: ModuleRef, + + @Inject(DI.usersRepository) + private usersRepository: UsersRepository, + + @Inject(DI.notesRepository) + private notesRepository: NotesRepository, + + @Inject(DI.noteHistoryRepository) + private noteHistoryRepository: NoteHistoryRepository, + + @Inject(DI.followingsRepository) + private followingsRepository: FollowingsRepository, + + //private userEntityService: UserEntityService, + //private driveFileEntityService: DriveFileEntityService, + //private customEmojiService: CustomEmojiService, + //private reactionService: ReactionService, + ) { + } + + onModuleInit() { + this.userEntityService = this.moduleRef.get('UserEntityService'); + this.driveFileEntityService = this.moduleRef.get('DriveFileEntityService'); + this.customEmojiService = this.moduleRef.get('CustomEmojiService'); + this.idService = this.moduleRef.get('IdService'); + } + + @bindThis + public async packAttachedFiles(fileIds: NoteHistory['fileIds'], packedFiles: Map | null>): Promise[]> { + const missingIds = []; + for (const id of fileIds) { + if (!packedFiles.has(id)) missingIds.push(id); + } + if (missingIds.length) { + const additionalMap = await this.driveFileEntityService.packManyByIdsMap(missingIds); + for (const [k, v] of additionalMap) { + packedFiles.set(k, v); + } + } + return fileIds.map(id => packedFiles.get(id)).filter(x => x != null); + } + + @bindThis + private async pack( + src: NoteHistory['id'], + host: MiNote['userHost'], + options?: { + _hint_?: { + packedFiles: Map | null>; + }; + }, + ): Promise> { + const history = await this.historyLoader.load(src); + + const text = history.text; + const packedFiles = options?._hint_?.packedFiles; + + const packed: Packed<'NoteHistory'> = await awaitAll({ + id: history.id, + noteId: history.noteId, + createdAt: history.createdAt.toISOString(), + updatedAt: history.updatedAt.toISOString(), + userId: history.userId, + text: text, + cw: history.cw ?? undefined, + poll: history.poll ? { + choices: history.poll.choices, + multiple: history.poll.multiple, + expiresAt: history.poll.expiresAt ? new Date(history.poll.expiresAt).toISOString() : null, + } : undefined, + event: history.event ? { + title: history.event.title, + start: new Date(history.event.start).toISOString(), + end: history.event.end ? new Date(history.event.end).toISOString() : null, + metadata: history.event.metadata, + } : undefined, + visibility: history.visibility, + visibleUserIds: history.visibility === 'specified' ? history.visibleUserIds : undefined, + emojis: host != null ? this.customEmojiService.populateEmojis(history.emojis, host) : undefined, + fileIds: history.fileIds, + files: packedFiles != null ? this.packAttachedFiles(history.fileIds, packedFiles) : this.driveFileEntityService.packManyByIds(history.fileIds), + }); + + return packed; + } + + @bindThis + public async packMany ( + histories: NoteHistory[], + noteHost: MiNote['userHost'] | null, + me?: MiUser | null, + ): Promise[]> { + const packed: Packed<'NoteHistory'>[] = []; + const meId = me?.id ?? null; + for (const history of histories) { + const packed_history = await this.pack(history.id, noteHost); + const isVisibleForMe = await this.isVisible(packed_history, meId); + if (isVisibleForMe) { + packed.push(packed_history); + } + } + return packed; + } + + @bindThis + private findNoteHistoryOrFail(id: string): Promise { + return this.noteHistoryRepository.findOneOrFail({ + where: { id }, + }); + } + + @bindThis + private async isVisible(packedHistory: Packed<'NoteHistory'>, meId: MiUser['id'] | null) { + let hide = false; + if (packedHistory.visibility === 'specified') { + if (meId == null) { + hide = true; + } else if (meId === packedHistory.userId) { + hide = false; + } else { + const specified = packedHistory.visibleUserIds?.some((id: string) => meId === id); + if (specified) { + hide = false; + } else { + hide = true; + } + } + } + if (packedHistory.visibility === 'followers') { + if (meId == null) { + hide = true; + } else if (meId === packedHistory.userId) { + hide = false; + } else { + const isFollowing = await this.followingsRepository.exists({ + where: { + followeeId: packedHistory.userId, + followerId: meId, + }, + }); + + hide = !isFollowing; + } + } + if (packedHistory.userId === meId) { + hide = false; + } + return !hide; + } +} diff --git a/packages/backend/src/core/entities/NoteReactionEntityService.ts b/packages/backend/src/core/entities/NoteReactionEntityService.ts index 46ec13704c..54ce4d472a 100644 --- a/packages/backend/src/core/entities/NoteReactionEntityService.ts +++ b/packages/backend/src/core/entities/NoteReactionEntityService.ts @@ -49,15 +49,12 @@ export class NoteReactionEntityService implements OnModuleInit { public async pack( src: MiNoteReaction['id'] | MiNoteReaction, me?: { id: MiUser['id'] } | null | undefined, - options?: { - withNote: boolean; - }, + options?: object, hints?: { packedUser?: Packed<'UserLite'> }, ): Promise> { const opts = Object.assign({ - withNote: false, }, options); const reaction = typeof src === 'object' ? src : await this.noteReactionsRepository.findOneByOrFail({ id: src }); @@ -67,9 +64,6 @@ export class NoteReactionEntityService implements OnModuleInit { createdAt: this.idService.parse(reaction.id).date.toISOString(), user: hints?.packedUser ?? await this.userEntityService.pack(reaction.user ?? reaction.userId, me), type: this.reactionService.convertLegacyReaction(reaction.reaction), - ...(opts.withNote ? { - note: await this.noteEntityService.pack(reaction.note ?? reaction.noteId, me), - } : {}), }; } @@ -77,16 +71,50 @@ export class NoteReactionEntityService implements OnModuleInit { public async packMany( reactions: MiNoteReaction[], me?: { id: MiUser['id'] } | null | undefined, - options?: { - withNote: boolean; - }, + options?: object, ): Promise[]> { const opts = Object.assign({ - withNote: false, }, options); const _users = reactions.map(({ user, userId }) => user ?? userId); const _userMap = await this.userEntityService.packMany(_users, me) .then(users => new Map(users.map(u => [u.id, u]))); return Promise.all(reactions.map(reaction => this.pack(reaction, me, opts, { packedUser: _userMap.get(reaction.userId) }))); } + + @bindThis + public async packWithNote( + src: MiNoteReaction['id'] | MiNoteReaction, + me?: { id: MiUser['id'] } | null | undefined, + options?: object, + hints?: { + packedUser?: Packed<'UserLite'> + }, + ): Promise> { + const opts = Object.assign({ + }, options); + + const reaction = typeof src === 'object' ? src : await this.noteReactionsRepository.findOneByOrFail({ id: src }); + + return { + id: reaction.id, + createdAt: this.idService.parse(reaction.id).date.toISOString(), + user: hints?.packedUser ?? await this.userEntityService.pack(reaction.user ?? reaction.userId, me), + type: this.reactionService.convertLegacyReaction(reaction.reaction), + note: await this.noteEntityService.pack(reaction.note ?? reaction.noteId, me), + }; + } + + @bindThis + public async packManyWithNote( + reactions: MiNoteReaction[], + me?: { id: MiUser['id'] } | null | undefined, + options?: object, + ): Promise[]> { + const opts = Object.assign({ + }, options); + const _users = reactions.map(({ user, userId }) => user ?? userId); + const _userMap = await this.userEntityService.packMany(_users, me) + .then(users => new Map(users.map(u => [u.id, u]))); + return Promise.all(reactions.map(reaction => this.packWithNote(reaction, me, opts, { packedUser: _userMap.get(reaction.userId) }))); + } } diff --git a/packages/backend/src/core/entities/NotificationEntityService.ts b/packages/backend/src/core/entities/NotificationEntityService.ts index 92ba3057ef..7c2699d28a 100644 --- a/packages/backend/src/core/entities/NotificationEntityService.ts +++ b/packages/backend/src/core/entities/NotificationEntityService.ts @@ -22,7 +22,18 @@ import type { UserEntityService } from './UserEntityService.js'; import type { NoteEntityService } from './NoteEntityService.js'; import type { UserGroupInvitationEntityService } from './UserGroupInvitationEntityService.js'; -const NOTE_REQUIRED_NOTIFICATION_TYPES = new Set(['note', 'mention', 'reply', 'renote', 'renote:grouped', 'quote', 'reaction', 'reaction:grouped', 'pollEnded'] as (typeof groupedNotificationTypes[number])[]); +const NOTE_REQUIRED_NOTIFICATION_TYPES = new Set([ + 'note', + 'mention', + 'reply', + 'renote', + 'renote:grouped', + 'quote', + 'reaction', + 'reaction:grouped', + 'pollEnded', + 'scheduledNotePosted', +] as (typeof groupedNotificationTypes[number])[]); @Injectable() export class NotificationEntityService implements OnModuleInit { @@ -211,9 +222,6 @@ export class NotificationEntityService implements OnModuleInit { ...(notification.type === 'login' ? { ip: notification.userIp, } : {}), - ...(notification.type === 'scheduleNote' ? { - errorType: notification.errorType, - } : {}), ...(notification.type === 'app' ? { body: notification.customBody, header: notification.customHeader, diff --git a/packages/backend/src/core/entities/UserEntityService.ts b/packages/backend/src/core/entities/UserEntityService.ts index 3bcb60d6e7..9229e80107 100644 --- a/packages/backend/src/core/entities/UserEntityService.ts +++ b/packages/backend/src/core/entities/UserEntityService.ts @@ -474,8 +474,8 @@ export class UserEntityService implements OnModuleInit { (profile.followersVisibility === 'followers') && (relation && relation.isFollowing) ? user.followersCount : null; - const isModerator = isMe && isDetailed ? this.roleService.isModerator(user) : null; - const isAdmin = isMe && isDetailed ? this.roleService.isAdministrator(user) : null; + const isModerator = isMe && isDetailed ? this.roleService.isModerator(user) : undefined; + const isAdmin = isMe && isDetailed ? this.roleService.isAdministrator(user) : undefined; const unreadAnnouncements = isMe && isDetailed ? (await this.announcementService.getUnreadAnnouncements(user)).map((announcement) => ({ createdAt: this.idService.parse(announcement.id).date.toISOString(), @@ -484,6 +484,7 @@ export class UserEntityService implements OnModuleInit { const notificationsInfo = isMe && isDetailed ? await this.getNotificationsInfo(user.id) : null; + // TODO: 例えば avatarUrl: true など間違った型を設定しても型エラーにならないのをどうにかする(ジェネリクス使わない方法で実装するしかなさそう?) const packed = { id: user.id, name: user.name, @@ -504,6 +505,7 @@ export class UserEntityService implements OnModuleInit { isLocked: user.isLocked, isBot: user.isBot, isCat: user.isCat, + // @ts-expect-error - proxyAccountId is not defined in MiMeta isProxy: this.meta.proxyAccountId === user.id, requireSigninToViewContents: user.requireSigninToViewContents === false ? undefined : true, makeNotesFollowersOnlyBefore: user.makeNotesFollowersOnlyBefore ?? undefined, @@ -518,8 +520,8 @@ export class UserEntityService implements OnModuleInit { } : undefined) : undefined, emojis: this.customEmojiService.populateEmojis(user.emojis, user.host), onlineStatus: this.getOnlineStatus(user), - // パフォーマンス上の理由でローカルユーザーのみ - badgeRoles: user.host == null ? this.roleService.getUserBadgeRoles(user.id).then((rs) => rs + // パフォーマンス上の理由で、明示的に設定しない場合はローカルユーザーのみ取得 + badgeRoles: (this.meta.showRoleBadgesOfRemoteUsers || user.host == null) ? this.roleService.getUserBadgeRoles(user.id).then((rs) => rs .filter((r) => r.isPublic || iAmModerator) .sort((a, b) => b.displayOrder - a.displayOrder) .map((r) => ({ @@ -565,7 +567,7 @@ export class UserEntityService implements OnModuleInit { followersVisibility: profile!.followersVisibility, followingVisibility: profile!.followingVisibility, chatScope: user.chatScope, - canChat: this.roleService.getUserPolicies(user.id).then(r => r.chatAvailability === 'available'), + canChat: this.isLocalUser(user) ? this.roleService.getUserPolicies(user.id).then(r => r.chatAvailability !== 'unavailable') : (user.canChat ?? true), roles: this.roleService.getUserRoles(user.id).then(roles => roles.filter(role => role.isPublic).sort((a, b) => b.displayOrder - a.displayOrder).map(role => ({ id: role.id, name: role.name, diff --git a/packages/backend/src/di-symbols.ts b/packages/backend/src/di-symbols.ts index 761630a24a..1d0f9ca8d9 100644 --- a/packages/backend/src/di-symbols.ts +++ b/packages/backend/src/di-symbols.ts @@ -97,6 +97,6 @@ export const DI = { bubbleGameRecordsRepository: Symbol('bubbleGameRecordsRepository'), reversiGamesRepository: Symbol('reversiGamesRepository'), noteDraftsRepository: Symbol('noteDraftsRepository'), - noteScheduleRepository: Symbol('noteScheduleRepository'), + noteHistoryRepository: Symbol('noteHistoryRepository'), //#endregion }; diff --git a/packages/backend/src/misc/emoji-regex.ts b/packages/backend/src/misc/emoji-regex.ts index 6d03b433ba..fabbdc335f 100644 --- a/packages/backend/src/misc/emoji-regex.ts +++ b/packages/backend/src/misc/emoji-regex.ts @@ -4,6 +4,6 @@ */ // taken from @twemoji/parser/dist/lib/regex.js -const twemojiRegex = /(?:\ud83d\udc68\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffc-\udfff]|\ud83e\uddd1\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffb\udffd-\udfff]|\ud83e\uddd1\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffb\udffc\udffe\udfff]|\ud83e\uddd1\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffb-\udffd\udfff]|\ud83e\uddd1\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffb-\udffe]|\ud83d\udc68\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffc-\udfff]|\ud83d\udc68\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffd-\udfff]|\ud83d\udc68\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc68\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffd\udfff]|\ud83d\udc68\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffe]|\ud83d\udc69\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffc-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffc-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffd-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb\udffd-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc69\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc69\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffd\udfff]|\ud83d\udc69\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb-\udffd\udfff]|\ud83d\udc69\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffe]|\ud83d\udc69\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb-\udffe]|\ud83e\uddd1\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffc-\udfff]|\ud83e\uddd1\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffb\udffd-\udfff]|\ud83e\uddd1\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffb\udffc\udffe\udfff]|\ud83e\uddd1\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffb-\udffd\udfff]|\ud83e\uddd1\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffb-\udffe]|\ud83e\uddd1\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83d\udc68\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68|\ud83d\udc69\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d[\udc68\udc69]|\ud83e\udef1\ud83c\udffb\u200d\ud83e\udef2\ud83c[\udffc-\udfff]|\ud83e\udef1\ud83c\udffc\u200d\ud83e\udef2\ud83c[\udffb\udffd-\udfff]|\ud83e\udef1\ud83c\udffd\u200d\ud83e\udef2\ud83c[\udffb\udffc\udffe\udfff]|\ud83e\udef1\ud83c\udffe\u200d\ud83e\udef2\ud83c[\udffb-\udffd\udfff]|\ud83e\udef1\ud83c\udfff\u200d\ud83e\udef2\ud83c[\udffb-\udffe]|\ud83d\udc68\u200d\u2764\ufe0f\u200d\ud83d\udc68|\ud83d\udc69\u200d\u2764\ufe0f\u200d\ud83d[\udc68\udc69]|\ud83e\uddd1\u200d\ud83e\udd1d\u200d\ud83e\uddd1|\ud83d\udc6b\ud83c[\udffb-\udfff]|\ud83d\udc6c\ud83c[\udffb-\udfff]|\ud83d\udc6d\ud83c[\udffb-\udfff]|\ud83d\udc8f\ud83c[\udffb-\udfff]|\ud83d\udc91\ud83c[\udffb-\udfff]|\ud83e\udd1d\ud83c[\udffb-\udfff]|\ud83d[\udc6b-\udc6d\udc8f\udc91]|\ud83e\udd1d)|(?:\ud83d[\udc68\udc69]|\ud83e\uddd1)(?:\ud83c[\udffb-\udfff])?\u200d(?:\u2695\ufe0f|\u2696\ufe0f|\u2708\ufe0f|\ud83c[\udf3e\udf73\udf7c\udf84\udf93\udfa4\udfa8\udfeb\udfed]|\ud83d[\udcbb\udcbc\udd27\udd2c\ude80\ude92]|\ud83e[\uddaf-\uddb3\uddbc\uddbd])|(?:\ud83c[\udfcb\udfcc]|\ud83d[\udd74\udd75]|\u26f9)((?:\ud83c[\udffb-\udfff]|\ufe0f)\u200d[\u2640\u2642]\ufe0f)|(?:\ud83c[\udfc3\udfc4\udfca]|\ud83d[\udc6e\udc70\udc71\udc73\udc77\udc81\udc82\udc86\udc87\ude45-\ude47\ude4b\ude4d\ude4e\udea3\udeb4-\udeb6]|\ud83e[\udd26\udd35\udd37-\udd39\udd3d\udd3e\uddb8\uddb9\uddcd-\uddcf\uddd4\uddd6-\udddd])(?:\ud83c[\udffb-\udfff])?\u200d[\u2640\u2642]\ufe0f|(?:\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83c\udff3\ufe0f\u200d\u26a7\ufe0f|\ud83c\udff3\ufe0f\u200d\ud83c\udf08|\ud83d\ude36\u200d\ud83c\udf2b\ufe0f|\u2764\ufe0f\u200d\ud83d\udd25|\u2764\ufe0f\u200d\ud83e\ude79|\ud83c\udff4\u200d\u2620\ufe0f|\ud83d\udc15\u200d\ud83e\uddba|\ud83d\udc3b\u200d\u2744\ufe0f|\ud83d\udc41\u200d\ud83d\udde8|\ud83d\udc68\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83d\udc6f\u200d\u2640\ufe0f|\ud83d\udc6f\u200d\u2642\ufe0f|\ud83d\ude2e\u200d\ud83d\udca8|\ud83d\ude35\u200d\ud83d\udcab|\ud83e\udd3c\u200d\u2640\ufe0f|\ud83e\udd3c\u200d\u2642\ufe0f|\ud83e\uddde\u200d\u2640\ufe0f|\ud83e\uddde\u200d\u2642\ufe0f|\ud83e\udddf\u200d\u2640\ufe0f|\ud83e\udddf\u200d\u2642\ufe0f|\ud83d\udc08\u200d\u2b1b|\ud83d\udc26\u200d\u2b1b)|[#*0-9]\ufe0f?\u20e3|(?:[©®\u2122\u265f]\ufe0f)|(?:\ud83c[\udc04\udd70\udd71\udd7e\udd7f\ude02\ude1a\ude2f\ude37\udf21\udf24-\udf2c\udf36\udf7d\udf96\udf97\udf99-\udf9b\udf9e\udf9f\udfcd\udfce\udfd4-\udfdf\udff3\udff5\udff7]|\ud83d[\udc3f\udc41\udcfd\udd49\udd4a\udd6f\udd70\udd73\udd76-\udd79\udd87\udd8a-\udd8d\udda5\udda8\uddb1\uddb2\uddbc\uddc2-\uddc4\uddd1-\uddd3\udddc-\uddde\udde1\udde3\udde8\uddef\uddf3\uddfa\udecb\udecd-\udecf\udee0-\udee5\udee9\udef0\udef3]|[\u203c\u2049\u2139\u2194-\u2199\u21a9\u21aa\u231a\u231b\u2328\u23cf\u23ed-\u23ef\u23f1\u23f2\u23f8-\u23fa\u24c2\u25aa\u25ab\u25b6\u25c0\u25fb-\u25fe\u2600-\u2604\u260e\u2611\u2614\u2615\u2618\u2620\u2622\u2623\u2626\u262a\u262e\u262f\u2638-\u263a\u2640\u2642\u2648-\u2653\u2660\u2663\u2665\u2666\u2668\u267b\u267f\u2692-\u2697\u2699\u269b\u269c\u26a0\u26a1\u26a7\u26aa\u26ab\u26b0\u26b1\u26bd\u26be\u26c4\u26c5\u26c8\u26cf\u26d1\u26d3\u26d4\u26e9\u26ea\u26f0-\u26f5\u26f8\u26fa\u26fd\u2702\u2708\u2709\u270f\u2712\u2714\u2716\u271d\u2721\u2733\u2734\u2744\u2747\u2757\u2763\u2764\u27a1\u2934\u2935\u2b05-\u2b07\u2b1b\u2b1c\u2b50\u2b55\u3030\u303d\u3297\u3299])(?:\ufe0f|(?!\ufe0e))|(?:(?:\ud83c[\udfcb\udfcc]|\ud83d[\udd74\udd75\udd90]|\ud83e\udef0|[\u261d\u26f7\u26f9\u270c\u270d])(?:\ufe0f|(?!\ufe0e))|(?:\ud83c[\udf85\udfc2-\udfc4\udfc7\udfca]|\ud83d[\udc42\udc43\udc46-\udc50\udc66-\udc69\udc6e\udc70-\udc78\udc7c\udc81-\udc83\udc85-\udc87\udcaa\udd7a\udd95\udd96\ude45-\ude47\ude4b-\ude4f\udea3\udeb4-\udeb6\udec0\udecc]|\ud83e[\udd0c\udd0f\udd18-\udd1c\udd1e\udd1f\udd26\udd30-\udd39\udd3d\udd3e\udd77\uddb5\uddb6\uddb8\uddb9\uddbb\uddcd-\uddcf\uddd1-\udddd\udec3-\udec5\udef1-\udef8]|[\u270a\u270b]))(?:\ud83c[\udffb-\udfff])?|(?:\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc65\udb40\udc6e\udb40\udc67\udb40\udc7f|\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc73\udb40\udc63\udb40\udc74\udb40\udc7f|\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc77\udb40\udc6c\udb40\udc73\udb40\udc7f|\ud83c\udde6\ud83c[\udde8-\uddec\uddee\uddf1\uddf2\uddf4\uddf6-\uddfa\uddfc\uddfd\uddff]|\ud83c\udde7\ud83c[\udde6\udde7\udde9-\uddef\uddf1-\uddf4\uddf6-\uddf9\uddfb\uddfc\uddfe\uddff]|\ud83c\udde8\ud83c[\udde6\udde8\udde9\uddeb-\uddee\uddf0-\uddf5\uddf7\uddfa-\uddff]|\ud83c\udde9\ud83c[\uddea\uddec\uddef\uddf0\uddf2\uddf4\uddff]|\ud83c\uddea\ud83c[\udde6\udde8\uddea\uddec\udded\uddf7-\uddfa]|\ud83c\uddeb\ud83c[\uddee-\uddf0\uddf2\uddf4\uddf7]|\ud83c\uddec\ud83c[\udde6\udde7\udde9-\uddee\uddf1-\uddf3\uddf5-\uddfa\uddfc\uddfe]|\ud83c\udded\ud83c[\uddf0\uddf2\uddf3\uddf7\uddf9\uddfa]|\ud83c\uddee\ud83c[\udde8-\uddea\uddf1-\uddf4\uddf6-\uddf9]|\ud83c\uddef\ud83c[\uddea\uddf2\uddf4\uddf5]|\ud83c\uddf0\ud83c[\uddea\uddec-\uddee\uddf2\uddf3\uddf5\uddf7\uddfc\uddfe\uddff]|\ud83c\uddf1\ud83c[\udde6-\udde8\uddee\uddf0\uddf7-\uddfb\uddfe]|\ud83c\uddf2\ud83c[\udde6\udde8-\udded\uddf0-\uddff]|\ud83c\uddf3\ud83c[\udde6\udde8\uddea-\uddec\uddee\uddf1\uddf4\uddf5\uddf7\uddfa\uddff]|\ud83c\uddf4\ud83c\uddf2|\ud83c\uddf5\ud83c[\udde6\uddea-\udded\uddf0-\uddf3\uddf7-\uddf9\uddfc\uddfe]|\ud83c\uddf6\ud83c\udde6|\ud83c\uddf7\ud83c[\uddea\uddf4\uddf8\uddfa\uddfc]|\ud83c\uddf8\ud83c[\udde6-\uddea\uddec-\uddf4\uddf7-\uddf9\uddfb\uddfd-\uddff]|\ud83c\uddf9\ud83c[\udde6\udde8\udde9\uddeb-\udded\uddef-\uddf4\uddf7\uddf9\uddfb\uddfc\uddff]|\ud83c\uddfa\ud83c[\udde6\uddec\uddf2\uddf3\uddf8\uddfe\uddff]|\ud83c\uddfb\ud83c[\udde6\udde8\uddea\uddec\uddee\uddf3\uddfa]|\ud83c\uddfc\ud83c[\uddeb\uddf8]|\ud83c\uddfd\ud83c\uddf0|\ud83c\uddfe\ud83c[\uddea\uddf9]|\ud83c\uddff\ud83c[\udde6\uddf2\uddfc]|\ud83c[\udccf\udd8e\udd91-\udd9a\udde6-\uddff\ude01\ude32-\ude36\ude38-\ude3a\ude50\ude51\udf00-\udf20\udf2d-\udf35\udf37-\udf7c\udf7e-\udf84\udf86-\udf93\udfa0-\udfc1\udfc5\udfc6\udfc8\udfc9\udfcf-\udfd3\udfe0-\udff0\udff4\udff8-\udfff]|\ud83d[\udc00-\udc3e\udc40\udc44\udc45\udc51-\udc65\udc6a\udc6f\udc79-\udc7b\udc7d-\udc80\udc84\udc88-\udc8e\udc90\udc92-\udca9\udcab-\udcfc\udcff-\udd3d\udd4b-\udd4e\udd50-\udd67\udda4\uddfb-\ude44\ude48-\ude4a\ude80-\udea2\udea4-\udeb3\udeb7-\udebf\udec1-\udec5\uded0-\uded2\uded5-\uded7\udedc-\udedf\udeeb\udeec\udef4-\udefc\udfe0-\udfeb\udff0]|\ud83e[\udd0d\udd0e\udd10-\udd17\udd20-\udd25\udd27-\udd2f\udd3a\udd3c\udd3f-\udd45\udd47-\udd76\udd78-\uddb4\uddb7\uddba\uddbc-\uddcc\uddd0\uddde-\uddff\ude70-\ude7c\ude80-\ude88\ude90-\udebd\udebf-\udec2\udece-\udedb\udee0-\udee8]|[\u23e9-\u23ec\u23f0\u23f3\u267e\u26ce\u2705\u2728\u274c\u274e\u2753-\u2755\u2795-\u2797\u27b0\u27bf\ue50a])|\ufe0f/g; +const twemojiRegex = /(?:\ud83d\udc68\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffc-\udfff]|\ud83e\uddd1\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffb\udffd-\udfff]|\ud83e\uddd1\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffb\udffc\udffe\udfff]|\ud83e\uddd1\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffb-\udffd\udfff]|\ud83e\uddd1\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffb-\udffe]|\ud83d\udc68\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffc-\udfff]|\ud83d\udc68\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffd-\udfff]|\ud83d\udc68\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc68\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffd\udfff]|\ud83d\udc68\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffe]|\ud83d\udc69\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffc-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffc-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffd-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb\udffd-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc69\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc69\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffd\udfff]|\ud83d\udc69\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb-\udffd\udfff]|\ud83d\udc69\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffe]|\ud83d\udc69\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb-\udffe]|\ud83e\uddd1\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffc-\udfff]|\ud83e\uddd1\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffb\udffd-\udfff]|\ud83e\uddd1\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffb\udffc\udffe\udfff]|\ud83e\uddd1\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffb-\udffd\udfff]|\ud83e\uddd1\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffb-\udffe]|\ud83e\uddd1\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83d\udc68\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68|\ud83d\udc69\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d[\udc68\udc69]|\ud83e\udef1\ud83c\udffb\u200d\ud83e\udef2\ud83c[\udffc-\udfff]|\ud83e\udef1\ud83c\udffc\u200d\ud83e\udef2\ud83c[\udffb\udffd-\udfff]|\ud83e\udef1\ud83c\udffd\u200d\ud83e\udef2\ud83c[\udffb\udffc\udffe\udfff]|\ud83e\udef1\ud83c\udffe\u200d\ud83e\udef2\ud83c[\udffb-\udffd\udfff]|\ud83e\udef1\ud83c\udfff\u200d\ud83e\udef2\ud83c[\udffb-\udffe]|\ud83d\udc68\u200d\u2764\ufe0f\u200d\ud83d\udc68|\ud83d\udc69\u200d\u2764\ufe0f\u200d\ud83d[\udc68\udc69]|\ud83e\uddd1\u200d\ud83e\udd1d\u200d\ud83e\uddd1|\ud83d\udc6b\ud83c[\udffb-\udfff]|\ud83d\udc6c\ud83c[\udffb-\udfff]|\ud83d\udc6d\ud83c[\udffb-\udfff]|\ud83d\udc8f\ud83c[\udffb-\udfff]|\ud83d\udc91\ud83c[\udffb-\udfff]|\ud83e\udd1d\ud83c[\udffb-\udfff]|\ud83d[\udc6b-\udc6d\udc8f\udc91]|\ud83e\udd1d)|(?:\ud83d[\udc68\udc69]|\ud83e\uddd1)(?:\ud83c[\udffb-\udfff])?\u200d(?:\u2695\ufe0f|\u2696\ufe0f|\u2708\ufe0f|\ud83c[\udf3e\udf73\udf7c\udf84\udf93\udfa4\udfa8\udfeb\udfed]|\ud83d[\udcbb\udcbc\udd27\udd2c\ude80\ude92]|\ud83e[\uddaf-\uddb3\uddbc\uddbd])(?:\u200d\u27a1\ufe0f)?|(?:\ud83c[\udfcb\udfcc]|\ud83d[\udd74\udd75]|\u26f9)((?:\ud83c[\udffb-\udfff]|\ufe0f)\u200d[\u2640\u2642]\ufe0f(?:\u200d\u27a1\ufe0f)?)|(?:\ud83c[\udfc3\udfc4\udfca]|\ud83d[\udc6e\udc70\udc71\udc73\udc77\udc81\udc82\udc86\udc87\ude45-\ude47\ude4b\ude4d\ude4e\udea3\udeb4-\udeb6]|\ud83e[\udd26\udd35\udd37-\udd39\udd3d\udd3e\uddb8\uddb9\uddcd-\uddcf\uddd4\uddd6-\udddd])(?:\ud83c[\udffb-\udfff])?\u200d[\u2640\u2642]\ufe0f(?:\u200d\u27a1\ufe0f)?|(?:\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83e\uddd1\u200d\ud83e\uddd1\u200d\ud83e\uddd2\u200d\ud83e\uddd2|\ud83d\udc68\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83e\uddd1\u200d\ud83e\uddd1\u200d\ud83e\uddd2|\ud83e\uddd1\u200d\ud83e\uddd2\u200d\ud83e\uddd2|\ud83c\udff3\ufe0f\u200d\u26a7\ufe0f|\ud83c\udff3\ufe0f\u200d\ud83c\udf08|\ud83d\ude36\u200d\ud83c\udf2b\ufe0f|\u26d3\ufe0f\u200d\ud83d\udca5|\u2764\ufe0f\u200d\ud83d\udd25|\u2764\ufe0f\u200d\ud83e\ude79|\ud83c\udf44\u200d\ud83d\udfeb|\ud83c\udf4b\u200d\ud83d\udfe9|\ud83c\udff4\u200d\u2620\ufe0f|\ud83d\udc15\u200d\ud83e\uddba|\ud83d\udc26\u200d\ud83d\udd25|\ud83d\udc3b\u200d\u2744\ufe0f|\ud83d\udc41\u200d\ud83d\udde8|\ud83d\udc68\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83d\udc6f\u200d\u2640\ufe0f|\ud83d\udc6f\u200d\u2642\ufe0f|\ud83d\ude2e\u200d\ud83d\udca8|\ud83d\ude35\u200d\ud83d\udcab|\ud83d\ude42\u200d\u2194\ufe0f|\ud83d\ude42\u200d\u2195\ufe0f|\ud83e\udd3c\u200d\u2640\ufe0f|\ud83e\udd3c\u200d\u2642\ufe0f|\ud83e\uddd1\u200d\ud83e\uddd2|\ud83e\uddde\u200d\u2640\ufe0f|\ud83e\uddde\u200d\u2642\ufe0f|\ud83e\udddf\u200d\u2640\ufe0f|\ud83e\udddf\u200d\u2642\ufe0f|\ud83d\udc08\u200d\u2b1b|\ud83d\udc26\u200d\u2b1b)|[#*0-9]\ufe0f?\u20e3|(?:[©®\u2122\u265f]\ufe0f)|(?:\ud83c[\udc04\udd70\udd71\udd7e\udd7f\ude02\ude1a\ude2f\ude37\udf21\udf24-\udf2c\udf36\udf7d\udf96\udf97\udf99-\udf9b\udf9e\udf9f\udfcd\udfce\udfd4-\udfdf\udff3\udff5\udff7]|\ud83d[\udc3f\udc41\udcfd\udd49\udd4a\udd6f\udd70\udd73\udd76-\udd79\udd87\udd8a-\udd8d\udda5\udda8\uddb1\uddb2\uddbc\uddc2-\uddc4\uddd1-\uddd3\udddc-\uddde\udde1\udde3\udde8\uddef\uddf3\uddfa\udecb\udecd-\udecf\udee0-\udee5\udee9\udef0\udef3]|[\u203c\u2049\u2139\u2194-\u2199\u21a9\u21aa\u231a\u231b\u2328\u23cf\u23ed-\u23ef\u23f1\u23f2\u23f8-\u23fa\u24c2\u25aa\u25ab\u25b6\u25c0\u25fb-\u25fe\u2600-\u2604\u260e\u2611\u2614\u2615\u2618\u2620\u2622\u2623\u2626\u262a\u262e\u262f\u2638-\u263a\u2640\u2642\u2648-\u2653\u2660\u2663\u2665\u2666\u2668\u267b\u267f\u2692-\u2697\u2699\u269b\u269c\u26a0\u26a1\u26a7\u26aa\u26ab\u26b0\u26b1\u26bd\u26be\u26c4\u26c5\u26c8\u26cf\u26d1\u26d3\u26d4\u26e9\u26ea\u26f0-\u26f5\u26f8\u26fa\u26fd\u2702\u2708\u2709\u270f\u2712\u2714\u2716\u271d\u2721\u2733\u2734\u2744\u2747\u2757\u2763\u2764\u27a1\u2934\u2935\u2b05-\u2b07\u2b1b\u2b1c\u2b50\u2b55\u3030\u303d\u3297\u3299])(?:\ufe0f|(?!\ufe0e))|(?:(?:\ud83c[\udfcb\udfcc]|\ud83d[\udd74\udd75\udd90]|\ud83e\udef0|[\u261d\u26f7\u26f9\u270c\u270d])(?:\ufe0f|(?!\ufe0e))|(?:\ud83c\udfc3|\ud83d\udeb6|\ud83e\uddce)(?:\ud83c[\udffb-\udfff])?(?:\u200d\u27a1\ufe0f)?|(?:\ud83c[\udf85\udfc2\udfc4\udfc7\udfca]|\ud83d[\udc42\udc43\udc46-\udc50\udc66-\udc69\udc6e\udc70-\udc78\udc7c\udc81-\udc83\udc85-\udc87\udcaa\udd7a\udd95\udd96\ude45-\ude47\ude4b-\ude4f\udea3\udeb4\udeb5\udec0\udecc]|\ud83e[\udd0c\udd0f\udd18-\udd1c\udd1e\udd1f\udd26\udd30-\udd39\udd3d\udd3e\udd77\uddb5\uddb6\uddb8\uddb9\uddbb\uddcd\uddcf\uddd1-\udddd\udec3-\udec5\udef1-\udef8]|[\u270a\u270b]))(?:\ud83c[\udffb-\udfff])?|(?:\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc65\udb40\udc6e\udb40\udc67\udb40\udc7f|\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc73\udb40\udc63\udb40\udc74\udb40\udc7f|\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc77\udb40\udc6c\udb40\udc73\udb40\udc7f|\ud83c\udde6\ud83c[\udde8-\uddec\uddee\uddf1\uddf2\uddf4\uddf6-\uddfa\uddfc\uddfd\uddff]|\ud83c\udde7\ud83c[\udde6\udde7\udde9-\uddef\uddf1-\uddf4\uddf6-\uddf9\uddfb\uddfc\uddfe\uddff]|\ud83c\udde8\ud83c[\udde6\udde8\udde9\uddeb-\uddee\uddf0-\uddf7\uddfa-\uddff]|\ud83c\udde9\ud83c[\uddea\uddec\uddef\uddf0\uddf2\uddf4\uddff]|\ud83c\uddea\ud83c[\udde6\udde8\uddea\uddec\udded\uddf7-\uddfa]|\ud83c\uddeb\ud83c[\uddee-\uddf0\uddf2\uddf4\uddf7]|\ud83c\uddec\ud83c[\udde6\udde7\udde9-\uddee\uddf1-\uddf3\uddf5-\uddfa\uddfc\uddfe]|\ud83c\udded\ud83c[\uddf0\uddf2\uddf3\uddf7\uddf9\uddfa]|\ud83c\uddee\ud83c[\udde8-\uddea\uddf1-\uddf4\uddf6-\uddf9]|\ud83c\uddef\ud83c[\uddea\uddf2\uddf4\uddf5]|\ud83c\uddf0\ud83c[\uddea\uddec-\uddee\uddf2\uddf3\uddf5\uddf7\uddfc\uddfe\uddff]|\ud83c\uddf1\ud83c[\udde6-\udde8\uddee\uddf0\uddf7-\uddfb\uddfe]|\ud83c\uddf2\ud83c[\udde6\udde8-\udded\uddf0-\uddff]|\ud83c\uddf3\ud83c[\udde6\udde8\uddea-\uddec\uddee\uddf1\uddf4\uddf5\uddf7\uddfa\uddff]|\ud83c\uddf4\ud83c\uddf2|\ud83c\uddf5\ud83c[\udde6\uddea-\udded\uddf0-\uddf3\uddf7-\uddf9\uddfc\uddfe]|\ud83c\uddf6\ud83c\udde6|\ud83c\uddf7\ud83c[\uddea\uddf4\uddf8\uddfa\uddfc]|\ud83c\uddf8\ud83c[\udde6-\uddea\uddec-\uddf4\uddf7-\uddf9\uddfb\uddfd-\uddff]|\ud83c\uddf9\ud83c[\udde6\udde8\udde9\uddeb-\udded\uddef-\uddf4\uddf7\uddf9\uddfb\uddfc\uddff]|\ud83c\uddfa\ud83c[\udde6\uddec\uddf2\uddf3\uddf8\uddfe\uddff]|\ud83c\uddfb\ud83c[\udde6\udde8\uddea\uddec\uddee\uddf3\uddfa]|\ud83c\uddfc\ud83c[\uddeb\uddf8]|\ud83c\uddfd\ud83c\uddf0|\ud83c\uddfe\ud83c[\uddea\uddf9]|\ud83c\uddff\ud83c[\udde6\uddf2\uddfc]|\ud83c[\udccf\udd8e\udd91-\udd9a\udde6-\uddff\ude01\ude32-\ude36\ude38-\ude3a\ude50\ude51\udf00-\udf20\udf2d-\udf35\udf37-\udf7c\udf7e-\udf84\udf86-\udf93\udfa0-\udfc1\udfc5\udfc6\udfc8\udfc9\udfcf-\udfd3\udfe0-\udff0\udff4\udff8-\udfff]|\ud83d[\udc00-\udc3e\udc40\udc44\udc45\udc51-\udc65\udc6a\udc6f\udc79-\udc7b\udc7d-\udc80\udc84\udc88-\udc8e\udc90\udc92-\udca9\udcab-\udcfc\udcff-\udd3d\udd4b-\udd4e\udd50-\udd67\udda4\uddfb-\ude44\ude48-\ude4a\ude80-\udea2\udea4-\udeb3\udeb7-\udebf\udec1-\udec5\uded0-\uded2\uded5-\uded7\udedc-\udedf\udeeb\udeec\udef4-\udefc\udfe0-\udfeb\udff0]|\ud83e[\udd0d\udd0e\udd10-\udd17\udd20-\udd25\udd27-\udd2f\udd3a\udd3c\udd3f-\udd45\udd47-\udd76\udd78-\uddb4\uddb7\uddba\uddbc-\uddcc\uddd0\uddde-\uddff\ude70-\ude7c\ude80-\ude89\ude8f-\udec2\udec6\udece-\udedc\udedf-\udee9]|[\u23e9-\u23ec\u23f0\u23f3\u267e\u26ce\u2705\u2728\u274c\u274e\u2753-\u2755\u2795-\u2797\u27b0\u27bf\ue50a])|\ufe0f/g; export const emojiRegex = new RegExp(`(${twemojiRegex.source})`); diff --git a/packages/backend/src/misc/is-user-related.ts b/packages/backend/src/misc/is-user-related.ts index 862d6e6a38..6f72082733 100644 --- a/packages/backend/src/misc/is-user-related.ts +++ b/packages/backend/src/misc/is-user-related.ts @@ -3,7 +3,17 @@ * SPDX-License-Identifier: AGPL-3.0-only */ -export function isUserRelated(note: any, userIds: Set, ignoreAuthor = false): boolean { +import type { MiUser } from '@/models/_.js'; + +interface NoteLike { + userId: MiUser['id']; + reply?: NoteLike | null; + renote?: NoteLike | null; + replyUserId?: MiUser['id'] | null; + renoteUserId?: MiUser['id'] | null; +} + +export function isUserRelated(note: NoteLike | null | undefined, userIds: Set, ignoreAuthor = false): boolean { if (!note) { return false; } @@ -12,13 +22,16 @@ export function isUserRelated(note: any, userIds: Set, ignoreAuthor = fa return true; } - if (note.reply != null && note.reply.userId !== note.userId && userIds.has(note.reply.userId)) { + const replyUserId = note.replyUserId ?? note.reply?.userId; + if (replyUserId != null && replyUserId !== note.userId && userIds.has(replyUserId)) { return true; } - if (note.renote != null && note.renote.userId !== note.userId && userIds.has(note.renote.userId)) { + const renoteUserId = note.renoteUserId ?? note.renote?.userId; + if (renoteUserId != null && renoteUserId !== note.userId && userIds.has(renoteUserId)) { return true; } return false; } + diff --git a/packages/backend/src/misc/json-schema.ts b/packages/backend/src/misc/json-schema.ts index e7d127b729..4d4bc9248a 100644 --- a/packages/backend/src/misc/json-schema.ts +++ b/packages/backend/src/misc/json-schema.ts @@ -22,7 +22,7 @@ import { packedFollowingSchema } from '@/models/json-schema/following.js'; import { packedMutingSchema } from '@/models/json-schema/muting.js'; import { packedRenoteMutingSchema } from '@/models/json-schema/renote-muting.js'; import { packedBlockingSchema } from '@/models/json-schema/blocking.js'; -import { packedNoteReactionSchema } from '@/models/json-schema/note-reaction.js'; +import { packedNoteReactionSchema, packedNoteReactionWithNoteSchema } from '@/models/json-schema/note-reaction.js'; import { packedHashtagSchema } from '@/models/json-schema/hashtag.js'; import { packedInviteCodeSchema } from '@/models/json-schema/invite-code.js'; import { packedPageBlockSchema, packedPageSchema } from '@/models/json-schema/page.js'; @@ -32,7 +32,11 @@ import { packedChannelSchema } from '@/models/json-schema/channel.js'; import { packedAntennaSchema } from '@/models/json-schema/antenna.js'; import { packedClipSchema } from '@/models/json-schema/clip.js'; import { packedFederationInstanceSchema } from '@/models/json-schema/federation-instance.js'; -import { packedQueueCountSchema } from '@/models/json-schema/queue.js'; +import { + packedQueueCountSchema, + packedQueueMetricsSchema, + packedQueueJobSchema, +} from '@/models/json-schema/queue.js'; import { packedGalleryPostSchema } from '@/models/json-schema/gallery-post.js'; import { packedEmojiDetailedAdminSchema, @@ -62,6 +66,7 @@ import { packedMetaDetailedSchema, packedMetaLiteSchema, } from '@/models/json-schema/meta.js'; +import { packedUserWebhookSchema } from '@/models/json-schema/user-webhook.js'; import { packedSystemWebhookSchema } from '@/models/json-schema/system-webhook.js'; import { packedAbuseReportNotificationRecipientSchema } from '@/models/json-schema/abuse-report-notification-recipient.js'; import { packedChatMessageSchema, packedChatMessageLiteSchema, packedChatMessageLiteForRoomSchema, packedChatMessageLiteFor1on1Schema } from '@/models/json-schema/chat-message.js'; @@ -70,6 +75,7 @@ import { packedChatRoomInvitationSchema } from '@/models/json-schema/chat-room-i import { packedChatRoomMembershipSchema } from '@/models/json-schema/chat-room-membership.js'; import { packedAchievementNameSchema, packedAchievementSchema } from '@/models/json-schema/achievement.js'; import { packedNoteDraftSchema } from '@/models/json-schema/note-draft.js'; +import { packedNoteHistorySchema } from '@/models/json-schema/note-history.js'; export const refs = { UserLite: packedUserLiteSchema, @@ -90,6 +96,7 @@ export const refs = { Note: packedNoteSchema, NoteDraft: packedNoteDraftSchema, NoteReaction: packedNoteReactionSchema, + NoteReactionWithNote: packedNoteReactionWithNoteSchema, NoteFavorite: packedNoteFavoriteSchema, Notification: packedNotificationSchema, DriveFile: packedDriveFileSchema, @@ -104,6 +111,8 @@ export const refs = { PageBlock: packedPageBlockSchema, Channel: packedChannelSchema, QueueCount: packedQueueCountSchema, + QueueMetrics: packedQueueMetricsSchema, + QueueJob: packedQueueJobSchema, Antenna: packedAntennaSchema, Clip: packedClipSchema, FederationInstance: packedFederationInstanceSchema, @@ -129,6 +138,7 @@ export const refs = { MetaLite: packedMetaLiteSchema, MetaDetailedOnly: packedMetaDetailedOnlySchema, MetaDetailed: packedMetaDetailedSchema, + UserWebhook: packedUserWebhookSchema, SystemWebhook: packedSystemWebhookSchema, AbuseReportNotificationRecipient: packedAbuseReportNotificationRecipientSchema, ChatMessage: packedChatMessageSchema, @@ -138,6 +148,7 @@ export const refs = { ChatRoom: packedChatRoomSchema, ChatRoomInvitation: packedChatRoomInvitationSchema, ChatRoomMembership: packedChatRoomMembershipSchema, + NoteHistory: packedNoteHistorySchema, }; export type Packed = SchemaType; @@ -216,7 +227,17 @@ type NullOrUndefined

= // https://stackoverflow.com/questions/54938141/typescript-convert-union-to-intersection // Get intersection from union type UnionToIntersection = (U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never; -type PartialIntersection = Partial>; + +type ArrayToIntersection> = + T extends readonly [infer Head, ...infer Tail] + ? Head extends Schema + ? Tail extends ReadonlyArray + ? Tail extends [] + ? SchemaType + : SchemaType & ArrayToIntersection + : never + : never + : never; // https://github.com/misskey-dev/misskey/pull/8144#discussion_r785287552 // To get union, we use `Foo extends any ? Hoge : never` @@ -234,8 +255,8 @@ type ObjectSchemaTypeDef

= : never : ObjType> : - p['anyOf'] extends ReadonlyArray ? never : // see CONTRIBUTING.md - p['allOf'] extends ReadonlyArray ? UnionToIntersection> : + p['anyOf'] extends ReadonlyArray ? UnionSchemaType : + p['allOf'] extends ReadonlyArray ? ArrayToIntersection : p['additionalProperties'] extends true ? Record : p['additionalProperties'] extends Schema ? p['additionalProperties'] extends infer AdditionalProperties ? @@ -275,7 +296,8 @@ export type SchemaTypeDef

= p['items'] extends NonNullable ? SchemaType[] : any[] ) : - p['anyOf'] extends ReadonlyArray ? UnionSchemaType & PartialIntersection> : + p['anyOf'] extends ReadonlyArray ? UnionSchemaType : + p['allOf'] extends ReadonlyArray ? ArrayToIntersection : p['oneOf'] extends ReadonlyArray ? UnionSchemaType : any; diff --git a/packages/backend/src/models/AbuseReportNotificationRecipient.ts b/packages/backend/src/models/AbuseReportNotificationRecipient.ts index fbff880afc..17ec6abed5 100644 --- a/packages/backend/src/models/AbuseReportNotificationRecipient.ts +++ b/packages/backend/src/models/AbuseReportNotificationRecipient.ts @@ -22,7 +22,7 @@ export class MiAbuseReportNotificationRecipient { /** * 有効かどうか. */ - @Index() + @Index('IDX_abuse_report_notification_recipient_isActive') @Column('boolean', { default: true, }) @@ -47,7 +47,7 @@ export class MiAbuseReportNotificationRecipient { /** * 通知方法. */ - @Index() + @Index('IDX_abuse_report_notification_recipient_method') @Column('varchar', { length: 64, }) @@ -56,10 +56,11 @@ export class MiAbuseReportNotificationRecipient { /** * 通知先のユーザID. */ - @Index() + @Index('IDX_abuse_report_notification_recipient_userId') @Column({ ...id(), nullable: true, + default: null, }) public userId: MiUser['id'] | null; @@ -75,17 +76,20 @@ export class MiAbuseReportNotificationRecipient { /** * 通知先のユーザプロフィール. */ - @ManyToOne(type => MiUserProfile, {}) + @ManyToOne(type => MiUserProfile, { + onDelete: 'CASCADE', + }) @JoinColumn({ name: 'userId', referencedColumnName: 'userId', foreignKeyConstraintName: 'FK_abuse_report_notification_recipient_userId2' }) public userProfile: MiUserProfile | null; /** * 通知先のシステムWebhookId. */ - @Index() + @Index('IDX_abuse_report_notification_recipient_systemWebhookId') @Column({ ...id(), nullable: true, + default: null, }) public systemWebhookId: string | null; @@ -95,6 +99,6 @@ export class MiAbuseReportNotificationRecipient { @ManyToOne(type => MiSystemWebhook, { onDelete: 'CASCADE', }) - @JoinColumn() + @JoinColumn({ name: 'systemWebhookId', referencedColumnName: 'id', foreignKeyConstraintName: 'FK_abuse_report_notification_recipient_systemWebhookId' }) public systemWebhook: MiSystemWebhook | null; } diff --git a/packages/backend/src/models/Ad.ts b/packages/backend/src/models/Ad.ts index 108e991c70..0d402fcbe8 100644 --- a/packages/backend/src/models/Ad.ts +++ b/packages/backend/src/models/Ad.ts @@ -54,10 +54,17 @@ export class MiAd { length: 8192, nullable: false, }) public memo: string; + @Column('integer', { default: 0, nullable: false, }) public dayOfWeek: number; + + @Column('boolean', { + default: false, + }) + public isSensitive: boolean; + constructor(data: Partial) { if (data == null) return; diff --git a/packages/backend/src/models/Antenna.ts b/packages/backend/src/models/Antenna.ts index cbfbe4960a..57d729bfbd 100644 --- a/packages/backend/src/models/Antenna.ts +++ b/packages/backend/src/models/Antenna.ts @@ -119,3 +119,6 @@ export class MiAntenna { }) public excludeNotesInSensitiveChannel: boolean; } +// Note for future developers: When you added a new column, +// You should update ExportAntennaProcessorService and ImportAntennaProcessorService +// to export and import antennas correctly. diff --git a/packages/backend/src/models/ChatMessage.ts b/packages/backend/src/models/ChatMessage.ts index 3d2b64268e..5c83f91edc 100644 --- a/packages/backend/src/models/ChatMessage.ts +++ b/packages/backend/src/models/ChatMessage.ts @@ -82,4 +82,9 @@ export class MiChatMessage { length: 1024, array: true, default: '{}', }) public reactions: string[]; + + @Column('varchar', { + length: 128, array: true, default: '{}', + }) + public emojis: string[]; } diff --git a/packages/backend/src/models/Emoji.ts b/packages/backend/src/models/Emoji.ts index d62b6e9f6f..8dff8fd153 100644 --- a/packages/backend/src/models/Emoji.ts +++ b/packages/backend/src/models/Emoji.ts @@ -8,6 +8,7 @@ import { id } from './util/id.js'; @Entity('emoji') @Index(['name', 'host'], { unique: true }) +@Index('IDX_EMOJI_ROLE_IDS', { synchronize: false }) // GIN for roleIdsThatCanBeUsedThisEmojiAsReaction in production export class MiEmoji { @PrimaryColumn(id()) public id: string; @@ -32,6 +33,7 @@ export class MiEmoji { @Column('varchar', { length: 128, nullable: true, }) + @Index('IDX_EMOJI_CATEGORY') public category: string | null; @Column('varchar', { diff --git a/packages/backend/src/models/Instance.ts b/packages/backend/src/models/Instance.ts index 17cd5c6665..c40d7d35ad 100644 --- a/packages/backend/src/models/Instance.ts +++ b/packages/backend/src/models/Instance.ts @@ -98,6 +98,14 @@ export class MiInstance { }) public suspensionState: 'none' | 'manuallySuspended' | 'goneSuspended' | 'autoSuspendedForNotResponding'; + /** + * このインスタンスが隔離制限されているかどうか + */ + @Column('boolean', { + default: false, + }) + public quarantineLimited: boolean; + @Column('varchar', { length: 64, nullable: true, comment: 'The software of the Instance.', diff --git a/packages/backend/src/models/Meta.ts b/packages/backend/src/models/Meta.ts index ca2c79ad9b..42cadc1449 100644 --- a/packages/backend/src/models/Meta.ts +++ b/packages/backend/src/models/Meta.ts @@ -59,7 +59,7 @@ export class MiMeta { public maintainerEmail: string | null; @Column('boolean', { - default: false, + default: true, }) public disableRegistration: boolean; @@ -696,7 +696,7 @@ export class MiMeta { public bannedEmailDomains: string[]; @Column('varchar', { - length: 1024, array: true, default: '{ "admin", "administrator", "root", "system", "maintainer", "host", "mod", "moderator", "owner", "superuser", "staff", "auth", "i", "me", "everyone", "all", "mention", "mentions", "example", "user", "users", "account", "accounts", "official", "help", "helps", "support", "supports", "info", "information", "informations", "announce", "announces", "announcement", "announcements", "notice", "notification", "notifications", "dev", "developer", "developers", "tech", "misskey", "cherrypick" }', + length: 1024, array: true, default: ['admin', 'administrator', 'root', 'system', 'maintainer', 'host', 'mod', 'moderator', 'owner', 'superuser', 'staff', 'auth', 'i', 'me', 'everyone', 'all', 'mention', 'mentions', 'example', 'user', 'users', 'account', 'accounts', 'official', 'help', 'helps', 'support', 'supports', 'info', 'information', 'informations', 'announce', 'announces', 'announcement', 'announcements', 'notice', 'notification', 'notifications', 'dev', 'developer', 'developers', 'tech', 'misskey', 'cherrypick'], }) public preservedUsernames: string[]; @@ -745,6 +745,11 @@ export class MiMeta { }) public urlPreviewEnabled: boolean; + @Column('boolean', { + default: true, + }) + public urlPreviewAllowRedirect: boolean; + @Column('integer', { default: 10000, }) @@ -756,7 +761,7 @@ export class MiMeta { public urlPreviewMaximumContentLength: number; @Column('boolean', { - default: true, + default: false, }) public urlPreviewRequireContentLength: boolean; @@ -777,12 +782,13 @@ export class MiMeta { @Column('varchar', { length: 1024, nullable: true, + default: null, }) public urlPreviewUserAgent: string | null; @Column('varchar', { length: 128, - default: 'all', + default: 'none', }) public federation: 'all' | 'specified' | 'none'; @@ -793,6 +799,12 @@ export class MiMeta { }) public federationHosts: string[]; + @Column('varchar', { + length: 128, + default: 'local', + }) + public ugcVisibilityForVisitor: 'all' | 'local' | 'none'; + @Column('varchar', { length: 64, nullable: true, @@ -804,6 +816,51 @@ export class MiMeta { }) public deliverSuspendedSoftware: SoftwareSuspension[]; + @Column('boolean', { + default: false, + }) + public singleUserMode: boolean; + + @Column('boolean', { + default: true, + }) + public proxyRemoteFiles: boolean; + + @Column('boolean', { + default: true, + }) + public signToActivityPubGet: boolean; + + @Column('boolean', { + default: true, + }) + public allowExternalApRedirect: boolean; + + @Column('boolean', { + default: false, + }) + public enableRemoteNotesCleaning: boolean; + + @Column('integer', { + default: 60, // minutes + }) + public remoteNotesCleaningMaxProcessingDurationInMinutes: number; + + @Column('integer', { + default: 90, // days + }) + public remoteNotesCleaningExpiryDaysForEachNotes: number; + + @Column('boolean', { + default: false, + }) + public showRoleBadgesOfRemoteUsers: boolean; + + @Column('jsonb', { + default: { }, + }) + public clientOptions: Record; + @Column('boolean', { default: false, }) diff --git a/packages/backend/src/models/Note.ts b/packages/backend/src/models/Note.ts index 43e4311714..f538a7d9e0 100644 --- a/packages/backend/src/models/Note.ts +++ b/packages/backend/src/models/Note.ts @@ -20,7 +20,8 @@ import type { MiDriveFile } from './DriveFile.js'; // You should not use `@Index({ concurrent: true })` decorator because database initialization for test will fail // because it will always run CREATE INDEX in transaction based on decorators. // Not appending `{ concurrent: true }` to `@Index` will not cause any problem in production, -@Index(['userId', 'id']) + +@Index(['userId', 'id']) // Note: this index is ("userId", "id" DESC) in production, but not in test. @Entity('note') export class MiNote { @PrimaryColumn(id()) @@ -37,13 +38,6 @@ export class MiNote { }) public updatedAtHistory: Date[] | null; - @Column('varchar', { - length: 3000, - array: true, - default: '{}', - }) - public noteEditHistory: string[]; - @Column('timestamp with time zone', { nullable: true, }) @@ -67,8 +61,7 @@ export class MiNote { public replyId: MiNote['id'] | null; @ManyToOne(type => MiNote, { - // onDelete: 'CASCADE', - onDelete: 'SET NULL', + createForeignKeyConstraints: false, }) @JoinColumn() public reply: MiNote | null; @@ -82,7 +75,7 @@ export class MiNote { public renoteId: MiNote['id'] | null; @ManyToOne(type => MiNote, { - onDelete: 'CASCADE', + createForeignKeyConstraints: false, }) @JoinColumn() public renote: MiNote | null; @@ -156,6 +149,13 @@ export class MiNote { }) public clippedCount: number; + // The number of note page blocks referencing this note. + // This column is used by Remote Note Cleaning and manually updated rather than automatically with triggers. + @Column('smallint', { + default: 0, + }) + public pageCount: number; + @Column('jsonb', { default: {}, }) diff --git a/packages/backend/src/models/NoteDraft.ts b/packages/backend/src/models/NoteDraft.ts index b241620edd..cc4710c7a5 100644 --- a/packages/backend/src/models/NoteDraft.ts +++ b/packages/backend/src/models/NoteDraft.ts @@ -13,11 +13,13 @@ import { MiNote } from './Note.js'; import type { MiDriveFile } from './DriveFile.js'; @Entity('note_draft') +@Index('IDX_NOTE_DRAFT_FILE_IDS', { synchronize: false }) // GIN for fileIds in production +@Index('IDX_NOTE_DRAFT_VISIBLE_USER_IDS', { synchronize: false }) // GIN for visibleUserIds in production export class MiNoteDraft { @PrimaryColumn(id()) public id: string; - @Index() + @Index('IDX_NOTE_DRAFT_REPLY_ID') @Column({ ...id(), nullable: true, @@ -25,13 +27,14 @@ export class MiNoteDraft { }) public replyId: MiNote['id'] | null; + // There is a possibility that replyId is not null but reply is null when the reply note is deleted. @ManyToOne(type => MiNote, { - onDelete: 'CASCADE', + createForeignKeyConstraints: false, }) @JoinColumn() public reply: MiNote | null; - @Index() + @Index('IDX_NOTE_DRAFT_RENOTE_ID') @Column({ ...id(), nullable: true, @@ -39,8 +42,9 @@ export class MiNoteDraft { }) public renoteId: MiNote['id'] | null; + // There is a possibility that renoteId is not null but renote is null when the renote note is deleted. @ManyToOne(type => MiNote, { - onDelete: 'CASCADE', + createForeignKeyConstraints: false, }) @JoinColumn() public renote: MiNote | null; @@ -61,7 +65,7 @@ export class MiNoteDraft { }) public cw: string | null; - @Index() + @Index('IDX_NOTE_DRAFT_USER_ID') @Column({ ...id(), comment: 'The ID of author.', @@ -115,9 +119,9 @@ export class MiNoteDraft { @Column('varchar', { length: 128, nullable: true, }) - public hashtag: string; + public hashtag: string | null; - @Index() + @Index('IDX_NOTE_DRAFT_CHANNEL_ID') @Column({ ...id(), nullable: true, @@ -125,13 +129,15 @@ export class MiNoteDraft { }) public channelId: MiChannel['id'] | null; + // There is a possibility that channelId is not null but channel is null when the channel is deleted. + // (deleting channel is not implemented so it's not happening now but may happen in the future) @ManyToOne(type => MiChannel, { - onDelete: 'CASCADE', + createForeignKeyConstraints: false, }) @JoinColumn() public channel: MiChannel | null; - // 以下、Pollについて追加 + //#region 以下、Pollについて追加 @Column('boolean', { default: false, @@ -156,11 +162,27 @@ export class MiNoteDraft { }) public pollExpiredAfter: number | null; + //#endregion + + // 予約日時 + // これがあるだけでは実際に予約されているかどうかはわからない + @Column('timestamp with time zone', { + nullable: true, + }) + public scheduledAt: Date | null; + + // scheduledAtに基づいて実際にスケジュールされているか + @Column('boolean', { + default: false, + }) + public isActuallyScheduled: boolean; + @Index() @Column('timestamp with time zone', { comment: 'The start time of the event', + nullable: true, }) - public eventStart: Date; + public eventStart: Date | null; @Column('timestamp with time zone', { comment: 'The end of the event', @@ -172,8 +194,9 @@ export class MiNoteDraft { type: 'varchar', length: 128, comment: 'short name of event', + nullable: true, }) - public eventTitle: string; + public eventTitle: string | null; @Column('jsonb', { default: { @@ -189,13 +212,12 @@ export class MiNoteDraft { }) public deleteAt: Date | null; - // ここまで追加 - - constructor(data: Partial) { - if (data == null) return; - - for (const [k, v] of Object.entries(data)) { - (this as any)[k] = v; - } - } + @Column('jsonb', { + nullable: true, + default: {}, + }) + public deliveryTargets: { + mode: 'include' | 'exclude'; + hosts: string[]; + } | null; } diff --git a/packages/backend/src/models/NoteHistory.ts b/packages/backend/src/models/NoteHistory.ts new file mode 100644 index 0000000000..0fe0509e3d --- /dev/null +++ b/packages/backend/src/models/NoteHistory.ts @@ -0,0 +1,101 @@ +/* + * SPDX-FileCopyrightText: noridev and cherrypick-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { Entity, Index, JoinColumn, Column, PrimaryColumn, ManyToOne, OneToOne, OneToMany } from 'typeorm'; +import { noteVisibilities } from '@/types.js'; +import { id } from './util/id.js'; +import { MiUser } from './User.js'; +import { MiNote } from './Note.js'; +import type { MiDriveFile } from './DriveFile.js'; + +@Entity() +export class NoteHistory { + @PrimaryColumn(id()) + public id: string; + + @Index() + @Column(id()) + public noteId: MiNote['id']; + + @ManyToOne(type => MiNote, { + onDelete: 'CASCADE', + }) + @JoinColumn() + public note?: MiNote | null; + + /** 내용을 백업할 노트가 만들어졌던 시간 */ + @Column('timestamp with time zone') + public createdAt: Date; + + /** 새로운 내용으로 대체된 시간 (이 히스토리가 기록된 시간) */ + @Column('timestamp with time zone') + public updatedAt: Date; + + @Column(id()) + public userId: MiUser['id']; + + @ManyToOne(type => MiUser, { + onDelete: 'CASCADE', + }) + @JoinColumn() + public user?: MiUser | null; + + @Column({ + ...id(), + array: true, default: '{}', + }) + public fileIds: MiDriveFile['id'][]; + + @Column('varchar', { + length: 256, array: true, default: '{}', + }) + public attachedFileTypes: string[]; + + @Column('varchar', { + length: 128, array: true, default: '{}', + }) + public emojis: string[]; + + @Column('text', { + nullable: true, + }) + public text: string | null; + + @Column('varchar', { + length: 512, + nullable: true, + }) + public cw: string | null; + + @Column('jsonb', { + nullable: true, + default: null, + }) + public poll: { + choices: string[]; + multiple: boolean; + expiresAt: Date | null; + } | null; + + @Column('jsonb', { + nullable: true, + default: null, + }) + public event: { + title: string; + start: Date; + end: Date | null; + metadata: Record; + } | null; + + @Column('enum', { enum: noteVisibilities }) + public visibility: typeof noteVisibilities[number]; + + @Column({ + ...id(), + array: true, default: '{}', + }) + public visibleUserIds: MiUser['id'][]; +} diff --git a/packages/backend/src/models/NoteSchedule.ts b/packages/backend/src/models/NoteSchedule.ts deleted file mode 100644 index 206cbcb9b2..0000000000 --- a/packages/backend/src/models/NoteSchedule.ts +++ /dev/null @@ -1,75 +0,0 @@ -/* - * SPDX-FileCopyrightText: syuilo and misskey-project - * SPDX-License-Identifier: AGPL-3.0-only - */ - -import { Entity, Index, Column, PrimaryColumn } from 'typeorm'; -import { MiNote } from '@/models/Note.js'; -import { id } from './util/id.js'; -import { MiUser } from './User.js'; -import { MiChannel } from './Channel.js'; -import { EventSchema } from './Event.js'; -import type { MiDriveFile } from './DriveFile.js'; - -type MinimumUser = { - id: MiUser['id']; - host: MiUser['host']; - username: MiUser['username']; - uri: MiUser['uri']; -}; - -export type MiScheduleNoteType = { - /** Date.toISOString() */ - createdAt: string; - visibility: 'public' | 'home' | 'followers' | 'specified'; - visibleUsers: MinimumUser[]; - channel?: MiChannel['id']; - poll: { - multiple: boolean; - choices: string[]; - /** Date.toISOString() */ - expiresAt: string | null - } | undefined; - renote?: MiNote['id']; - localOnly: boolean; - cw?: string | null; - reactionAcceptance: 'likeOnly' | 'likeOnlyForRemote' | 'nonSensitiveOnly' | 'nonSensitiveOnlyForLocalLikeOnlyForRemote' | null; - files: MiDriveFile['id'][]; - text?: string | null; - reply?: MiNote['id']; - event?: { - /** Date.toISOString() */ - start: string; - /** Date.toISOString() */ - end: string | null; - title: string; - metadata: EventSchema; - } | null; - disableRightClick: boolean, - apMentions?: MinimumUser[] | null; - apHashtags?: string[] | null; - apEmojis?: string[] | null; - deleteAt?: Date | null; - deliveryTargets?: { - mode: 'include' | 'exclude'; - hosts: string[]; - } | null; -}; - -@Entity('note_schedule') -export class MiNoteSchedule { - @PrimaryColumn(id()) - public id: string; - - @Column('jsonb') - public note: MiScheduleNoteType; - - @Index() - @Column('varchar', { - length: 260, - }) - public userId: MiUser['id']; - - @Column('timestamp with time zone') - public scheduledAt: Date; -} diff --git a/packages/backend/src/models/Notification.ts b/packages/backend/src/models/Notification.ts index bacabe96ad..0e943ba0eb 100644 --- a/packages/backend/src/models/Notification.ts +++ b/packages/backend/src/models/Notification.ts @@ -10,7 +10,9 @@ import { MiUserGroupInvitation } from './UserGroupInvitation.js'; import { MiAccessToken } from './AccessToken.js'; import { MiRole } from './Role.js'; import { MiDriveFile } from './DriveFile.js'; +import { MiNoteDraft } from './NoteDraft.js'; +// cherrypick-js の notificationTypes と同期すべし export type MiNotification = { type: 'note'; id: string; @@ -60,6 +62,16 @@ export type MiNotification = { createdAt: string; notifierId: MiUser['id']; noteId: MiNote['id']; +} | { + type: 'scheduledNotePosted'; + id: string; + createdAt: string; + noteId: MiNote['id']; +} | { + type: 'scheduledNotePostFailed'; + id: string; + createdAt: string; + noteDraftId: MiNoteDraft['id']; } | { type: 'receiveFollowRequest'; id: string; @@ -108,11 +120,6 @@ export type MiNotification = { type: 'createToken'; id: string; createdAt: string; -} | { - type: 'scheduleNote'; - id: string; - createdAt: string; - errorType: string; } | { type: 'app'; id: string; diff --git a/packages/backend/src/models/Page.ts b/packages/backend/src/models/Page.ts index 0b59e7a92c..d112a66c04 100644 --- a/packages/backend/src/models/Page.ts +++ b/packages/backend/src/models/Page.ts @@ -69,7 +69,7 @@ export class MiPage { public eyeCatchingImageId: MiDriveFile['id'] | null; @ManyToOne(type => MiDriveFile, { - onDelete: 'CASCADE', + onDelete: 'SET NULL', }) @JoinColumn() public eyeCatchingImage: MiDriveFile | null; diff --git a/packages/backend/src/models/RepositoryModule.ts b/packages/backend/src/models/RepositoryModule.ts index 7c3b62f9c9..75f241fccf 100644 --- a/packages/backend/src/models/RepositoryModule.ts +++ b/packages/backend/src/models/RepositoryModule.ts @@ -43,7 +43,6 @@ import { MiNote, MiNoteFavorite, MiNoteReaction, - MiNoteSchedule, MiNoteThreadMuting, MiNoteDraft, MiPage, @@ -90,6 +89,7 @@ import { MiChatRoomInvitation, MiChatApproval, } from './_.js'; +import { NoteHistory } from './NoteHistory.js'; import type { Provider } from '@nestjs/common'; import type { DataSource } from 'typeorm'; @@ -573,9 +573,9 @@ const $abuseReportResolversRepository: Provider = { inject: [DI.db], }; -const $noteScheduleRepository: Provider = { - provide: DI.noteScheduleRepository, - useFactory: (db: DataSource) => db.getRepository(MiNoteSchedule).extend(miRepository as MiRepository), +const $noteHistoryRepository: Provider = { + provide: DI.noteHistoryRepository, + useFactory: (db: DataSource) => db.getRepository(NoteHistory).extend(miRepository as MiRepository), inject: [DI.db], }; @@ -662,7 +662,7 @@ const $noteScheduleRepository: Provider = { $bubbleGameRecordsRepository, $reversiGamesRepository, $abuseReportResolversRepository, - $noteScheduleRepository, + $noteHistoryRepository, ], exports: [ $usersRepository, @@ -745,7 +745,7 @@ const $noteScheduleRepository: Provider = { $bubbleGameRecordsRepository, $reversiGamesRepository, $abuseReportResolversRepository, - $noteScheduleRepository, + $noteHistoryRepository, ], }) export class RepositoryModule { diff --git a/packages/backend/src/models/User.ts b/packages/backend/src/models/User.ts index e7b8031bb8..1170ac272d 100644 --- a/packages/backend/src/models/User.ts +++ b/packages/backend/src/models/User.ts @@ -120,7 +120,7 @@ export class MiUser { // avatarId が null になったとしてもこれが null でない可能性があるため、このフィールドを使うときは avatarId の non-null チェックをすること @Column('varchar', { - length: 512, nullable: true, + length: 1024, nullable: true, }) public avatarUrl: string | null; @@ -297,6 +297,23 @@ export class MiUser { }) public isSquareAvatars: boolean | null; + @Column('integer', { + nullable: true, + default: null, + }) + public autoDeleteNotesAfterDays!: number | null; + + @Column('boolean', { + default: true, + + }) + public autoDeleteKeepFavorites: boolean; + + @Column('boolean', { + nullable: true, + }) + public canChat: boolean | null; + constructor(data: Partial) { if (data == null) return; diff --git a/packages/backend/src/models/UserIp.ts b/packages/backend/src/models/UserIp.ts index 3e757fcf79..b017ed5904 100644 --- a/packages/backend/src/models/UserIp.ts +++ b/packages/backend/src/models/UserIp.ts @@ -25,4 +25,11 @@ export class MiUserIp { length: 128, }) public ip: string; + + @Column('varchar', { + length: 512, + array: true, + default: '{}', + }) + public dnsNames: string[]; } diff --git a/packages/backend/src/models/UserProfile.ts b/packages/backend/src/models/UserProfile.ts index e3f4d0f6bb..3b84aadc83 100644 --- a/packages/backend/src/models/UserProfile.ts +++ b/packages/backend/src/models/UserProfile.ts @@ -29,7 +29,7 @@ export class MiUserProfile { }) public location: string | null; - @Index() + // Note: There's index named IDX_de22cd2b445eee31ae51cdbe99 for SUBSTR("birthday", 6, 5) @Column('char', { length: 10, nullable: true, comment: 'The birthday (YYYY-MM-DD) of the User.', diff --git a/packages/backend/src/models/_.ts b/packages/backend/src/models/_.ts index f6a3187b60..6fe36921dc 100644 --- a/packages/backend/src/models/_.ts +++ b/packages/backend/src/models/_.ts @@ -60,7 +60,6 @@ import { MiNote } from '@/models/Note.js'; import { MiNoteDraft } from '@/models/NoteDraft.js'; import { MiNoteFavorite } from '@/models/NoteFavorite.js'; import { MiNoteReaction } from '@/models/NoteReaction.js'; -import { MiNoteSchedule } from '@/models/NoteSchedule.js'; import { MiNoteThreadMuting } from '@/models/NoteThreadMuting.js'; import { MiPage } from '@/models/Page.js'; import { MiPageLike } from '@/models/PageLike.js'; @@ -98,6 +97,7 @@ import { MiUserProfile } from '@/models/UserProfile.js'; import { MiUserPublickey } from '@/models/UserPublickey.js'; import { MiUserSecurityKey } from '@/models/UserSecurityKey.js'; import { MiWebhook } from '@/models/Webhook.js'; +import { NoteHistory } from '@/models/NoteHistory.js'; import type { QueryDeepPartialEntity } from 'typeorm/query-builder/QueryPartialEntity.js'; export interface MiRepository { @@ -200,7 +200,6 @@ export { MiNoteDraft, MiNoteFavorite, MiNoteReaction, - MiNoteSchedule, MiNoteThreadMuting, MiPage, MiPageLike, @@ -330,4 +329,5 @@ export type ChatRoomInvitationsRepository = Repository & M export type ChatApprovalsRepository = Repository & MiRepository; export type BubbleGameRecordsRepository = Repository & MiRepository; export type ReversiGamesRepository = Repository & MiRepository; -export type NoteScheduleRepository = Repository; +export type NoteHistoryRepository = Repository & MiRepository; + diff --git a/packages/backend/src/models/json-schema/ad.ts b/packages/backend/src/models/json-schema/ad.ts index b01b39a38b..d88ac23894 100644 --- a/packages/backend/src/models/json-schema/ad.ts +++ b/packages/backend/src/models/json-schema/ad.ts @@ -60,5 +60,10 @@ export const packedAdSchema = { optional: false, nullable: false, }, + isSensitive: { + type: 'boolean', + optional: false, + nullable: false, + }, }, } as const; diff --git a/packages/backend/src/models/json-schema/chat-message.ts b/packages/backend/src/models/json-schema/chat-message.ts index 3b5e85ab69..8502391ad1 100644 --- a/packages/backend/src/models/json-schema/chat-message.ts +++ b/packages/backend/src/models/json-schema/chat-message.ts @@ -78,6 +78,10 @@ export const packedChatMessageSchema = { }, }, }, + emojis: { + type: 'object', + optional: true, nullable: false, + }, }, } as const; @@ -142,6 +146,10 @@ export const packedChatMessageLiteSchema = { }, }, }, + emojis: { + type: 'object', + optional: true, nullable: false, + }, }, } as const; @@ -192,6 +200,10 @@ export const packedChatMessageLiteFor1on1Schema = { }, }, }, + emojis: { + type: 'object', + optional: true, nullable: false, + }, }, } as const; @@ -252,5 +264,9 @@ export const packedChatMessageLiteForRoomSchema = { }, }, }, + emojis: { + type: 'object', + optional: true, nullable: false, + }, }, } as const; diff --git a/packages/backend/src/models/json-schema/chat-room.ts b/packages/backend/src/models/json-schema/chat-room.ts index e97556e378..e628a9baa3 100644 --- a/packages/backend/src/models/json-schema/chat-room.ts +++ b/packages/backend/src/models/json-schema/chat-room.ts @@ -36,5 +36,9 @@ export const packedChatRoomSchema = { type: 'boolean', optional: true, nullable: false, }, + invitationExists: { + type: 'boolean', + optional: true, nullable: false, + }, }, } as const; diff --git a/packages/backend/src/models/json-schema/flash.ts b/packages/backend/src/models/json-schema/flash.ts index 42b2172409..d50200e6e9 100644 --- a/packages/backend/src/models/json-schema/flash.ts +++ b/packages/backend/src/models/json-schema/flash.ts @@ -51,7 +51,7 @@ export const packedFlashSchema = { }, likedCount: { type: 'number', - optional: false, nullable: true, + optional: false, nullable: false, }, isLiked: { type: 'boolean', diff --git a/packages/backend/src/models/json-schema/meta.ts b/packages/backend/src/models/json-schema/meta.ts index d91362072e..b6d97ccf97 100644 --- a/packages/backend/src/models/json-schema/meta.ts +++ b/packages/backend/src/models/json-schema/meta.ts @@ -75,6 +75,10 @@ export const packedMetaLiteSchema = { type: 'string', optional: false, nullable: true, }, + clientOptions: { + type: 'object', + optional: false, nullable: false, + }, disableRegistration: { type: 'boolean', optional: false, nullable: false, @@ -199,6 +203,10 @@ export const packedMetaLiteSchema = { type: 'integer', optional: false, nullable: false, }, + isSensitive: { + type: 'boolean', + optional: true, nullable: false, + }, }, }, }, diff --git a/packages/backend/src/models/json-schema/note-draft.ts b/packages/backend/src/models/json-schema/note-draft.ts index dd81c54e48..961631840f 100644 --- a/packages/backend/src/models/json-schema/note-draft.ts +++ b/packages/backend/src/models/json-schema/note-draft.ts @@ -23,7 +23,7 @@ export const packedNoteDraftSchema = { }, cw: { type: 'string', - optional: true, nullable: true, + optional: false, nullable: true, }, userId: { type: 'string', @@ -37,15 +37,13 @@ export const packedNoteDraftSchema = { }, replyId: { type: 'string', - optional: true, nullable: true, + optional: false, nullable: true, format: 'id', - example: 'xxxxxxxxxx', }, renoteId: { type: 'string', - optional: true, nullable: true, + optional: false, nullable: true, format: 'id', - example: 'xxxxxxxxxx', }, reply: { type: 'object', @@ -68,7 +66,7 @@ export const packedNoteDraftSchema = { }, visibleUserIds: { type: 'array', - optional: true, nullable: false, + optional: false, nullable: false, items: { type: 'string', optional: false, nullable: false, @@ -77,7 +75,7 @@ export const packedNoteDraftSchema = { }, fileIds: { type: 'array', - optional: true, nullable: false, + optional: false, nullable: false, items: { type: 'string', optional: false, nullable: false, @@ -95,11 +93,11 @@ export const packedNoteDraftSchema = { }, hashtag: { type: 'string', - optional: true, nullable: false, + optional: false, nullable: true, }, poll: { type: 'object', - optional: true, nullable: true, + optional: false, nullable: true, properties: { expiresAt: { type: 'string', @@ -130,9 +128,8 @@ export const packedNoteDraftSchema = { }, channelId: { type: 'string', - optional: true, nullable: true, + optional: false, nullable: true, format: 'id', - example: 'xxxxxxxxxx', }, channel: { type: 'object', @@ -166,17 +163,44 @@ export const packedNoteDraftSchema = { }, localOnly: { type: 'boolean', - optional: true, nullable: false, + optional: false, nullable: false, }, reactionAcceptance: { type: 'string', optional: false, nullable: true, enum: ['likeOnly', 'likeOnlyForRemote', 'nonSensitiveOnly', 'nonSensitiveOnlyForLocalLikeOnlyForRemote', null], }, + scheduledAt: { + type: 'number', + optional: false, nullable: true, + }, + isActuallyScheduled: { + type: 'boolean', + optional: false, nullable: false, + }, deleteAt: { type: 'string', optional: true, nullable: true, format: 'date-time', }, + deliveryTargets: { + type: 'object', + optional: true, nullable: true, + properties: { + mode: { + type: 'string', + optional: false, nullable: false, + enum: ['include', 'exclude'], + }, + hosts: { + type: 'array', + optional: true, nullable: true, + items: { + type: 'string', + optional: false, nullable: false, + }, + }, + }, + }, }, } as const; diff --git a/packages/backend/src/models/json-schema/note-history.ts b/packages/backend/src/models/json-schema/note-history.ts new file mode 100644 index 0000000000..c164f921aa --- /dev/null +++ b/packages/backend/src/models/json-schema/note-history.ts @@ -0,0 +1,125 @@ +/* + * SPDX-FileCopyrightText: noridev and cherrypick-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +export const packedNoteHistorySchema = { + type: 'object', + properties: { + id: { + type: 'string', + optional: false, nullable: false, + format: 'id', + example: 'xxxxxxxxxx', + }, + noteId: { + type: 'string', + optional: false, nullable: false, + }, + createdAt: { + type: 'string', + optional: false, nullable: false, + format: 'date-time', + }, + updatedAt: { + type: 'string', + optional: false, nullable: false, + format: 'date-time', + }, + userId: { + type: 'string', + optional: false, nullable: false, + format: 'id', + }, + text: { + type: 'string', + optional: false, nullable: true, + }, + cw: { + type: 'string', + optional: true, nullable: true, + }, + poll: { + type: 'object', + optional: true, nullable: true, + properties: { + choices: { + type: 'array', + items: { + type: 'string', + }, + }, + multiple: { + type: 'boolean', + }, + expiresAt: { + type: 'string', + format: 'date-time', + nullable: true, + }, + }, + }, + event: { + type: 'object', + optional: true, nullable: true, + properties: { + title: { + type: 'string', + }, + start: { + type: 'string', + format: 'date-time', + }, + end: { + type: 'string', + format: 'date-time', + nullable: true, + }, + metadata: { + type: 'object', + }, + }, + }, + fileIds: { + type: 'array', + optional: true, nullable: false, + items: { + type: 'string', + optional: false, nullable: false, + format: 'id', + }, + }, + files: { + type: 'array', + optional: true, nullable: false, + items: { + type: 'object', + optional: false, nullable: false, + ref: 'DriveFile', + }, + }, + visibility: { + type: 'string', + optional: false, nullable: false, + enum: ['public', 'home', 'followers', 'specified'], + }, + visibleUserIds: { + type: 'array', + optional: true, nullable: false, + items: { + type: 'string', + optional: false, nullable: false, + format: 'id', + }, + }, + emojis: { + type: 'object', + optional: true, nullable: false, + additionalProperties: { + anyOf: [{ + type: 'string', + }], + }, + }, + }, +} as const; diff --git a/packages/backend/src/models/json-schema/note-reaction.ts b/packages/backend/src/models/json-schema/note-reaction.ts index 95658ace1f..04c9f34232 100644 --- a/packages/backend/src/models/json-schema/note-reaction.ts +++ b/packages/backend/src/models/json-schema/note-reaction.ts @@ -10,7 +10,6 @@ export const packedNoteReactionSchema = { type: 'string', optional: false, nullable: false, format: 'id', - example: 'xxxxxxxxxx', }, createdAt: { type: 'string', @@ -28,3 +27,33 @@ export const packedNoteReactionSchema = { }, }, } as const; + +export const packedNoteReactionWithNoteSchema = { + type: 'object', + properties: { + id: { + type: 'string', + optional: false, nullable: false, + format: 'id', + }, + createdAt: { + type: 'string', + optional: false, nullable: false, + format: 'date-time', + }, + user: { + type: 'object', + optional: false, nullable: false, + ref: 'UserLite', + }, + type: { + type: 'string', + optional: false, nullable: false, + }, + note: { + type: 'object', + optional: false, nullable: false, + ref: 'Note', + }, + }, +} as const; diff --git a/packages/backend/src/models/json-schema/note.ts b/packages/backend/src/models/json-schema/note.ts index 031b87b27c..377baeb6a5 100644 --- a/packages/backend/src/models/json-schema/note.ts +++ b/packages/backend/src/models/json-schema/note.ts @@ -31,10 +31,6 @@ export const packedNoteSchema = { format: 'date-time', }, }, - noteEditHistory: { - type: 'array', - optional: true, nullable: false, - }, deletedAt: { type: 'string', optional: true, nullable: true, @@ -282,6 +278,11 @@ export const packedNoteSchema = { type: 'number', optional: true, nullable: false, }, + hasPoll: { + type: 'boolean', + optional: true, nullable: false, + }, + myReaction: { type: 'string', optional: true, nullable: true, diff --git a/packages/backend/src/models/json-schema/notification.ts b/packages/backend/src/models/json-schema/notification.ts index cbc18ae97b..077e14ccae 100644 --- a/packages/backend/src/models/json-schema/notification.ts +++ b/packages/backend/src/models/json-schema/notification.ts @@ -207,6 +207,36 @@ export const packedNotificationSchema = { optional: false, nullable: false, }, }, + }, { + type: 'object', + properties: { + ...baseSchema.properties, + type: { + type: 'string', + optional: false, nullable: false, + enum: ['scheduledNotePosted'], + }, + note: { + type: 'object', + ref: 'Note', + optional: false, nullable: false, + }, + }, + }, { + type: 'object', + properties: { + ...baseSchema.properties, + type: { + type: 'string', + optional: false, nullable: false, + enum: ['scheduledNotePostFailed'], + }, + noteDraft: { + type: 'object', + ref: 'NoteDraft', + optional: false, nullable: false, + }, + }, }, { type: 'object', properties: { @@ -358,20 +388,6 @@ export const packedNotificationSchema = { enum: ['createToken'], }, }, - }, { - type: 'object', - properties: { - ...baseSchema.properties, - type: { - type: 'string', - optional: false, nullable: false, - enum: ['scheduleNote'], - }, - errorType: { - type: 'string', - optional: false, nullable: false, - }, - }, }, { type: 'object', properties: { diff --git a/packages/backend/src/models/json-schema/queue.ts b/packages/backend/src/models/json-schema/queue.ts index 2ecf5c831f..dad0cf57f6 100644 --- a/packages/backend/src/models/json-schema/queue.ts +++ b/packages/backend/src/models/json-schema/queue.ts @@ -28,3 +28,110 @@ export const packedQueueCountSchema = { }, }, } as const; + +// Bull.Metrics +export const packedQueueMetricsSchema = { + type: 'object', + properties: { + meta: { + type: 'object', + optional: false, nullable: false, + properties: { + count: { + type: 'number', + optional: false, nullable: false, + }, + prevTS: { + type: 'number', + optional: false, nullable: false, + }, + prevCount: { + type: 'number', + optional: false, nullable: false, + }, + }, + }, + data: { + type: 'array', + optional: false, nullable: false, + items: { + type: 'number', + optional: false, nullable: false, + }, + }, + count: { + type: 'number', + optional: false, nullable: false, + }, + }, +} as const; + +export const packedQueueJobSchema = { + type: 'object', + properties: { + id: { + type: 'string', + optional: false, nullable: false, + }, + name: { + type: 'string', + optional: false, nullable: false, + }, + data: { + type: 'object', + optional: false, nullable: false, + }, + opts: { + type: 'object', + optional: false, nullable: false, + }, + timestamp: { + type: 'number', + optional: false, nullable: false, + }, + processedOn: { + type: 'number', + optional: true, nullable: false, + }, + processedBy: { + type: 'string', + optional: true, nullable: false, + }, + finishedOn: { + type: 'number', + optional: true, nullable: false, + }, + progress: { + type: 'object', + optional: false, nullable: false, + }, + attempts: { + type: 'number', + optional: false, nullable: false, + }, + delay: { + type: 'number', + optional: false, nullable: false, + }, + failedReason: { + type: 'string', + optional: false, nullable: false, + }, + stacktrace: { + type: 'array', + optional: false, nullable: false, + items: { + type: 'string', + optional: false, nullable: false, + }, + }, + returnValue: { + type: 'object', + optional: false, nullable: false, + }, + isFailed: { + type: 'boolean', + optional: false, nullable: false, + }, + }, +} as const; diff --git a/packages/backend/src/models/json-schema/role.ts b/packages/backend/src/models/json-schema/role.ts index 123b455b63..7461b874fe 100644 --- a/packages/backend/src/models/json-schema/role.ts +++ b/packages/backend/src/models/json-schema/role.ts @@ -248,6 +248,10 @@ export const packedRolePoliciesSchema = { type: 'boolean', optional: false, nullable: false, }, + canSearchUsers: { + type: 'boolean', + optional: false, nullable: false, + }, canUseTranslator: { type: 'boolean', optional: false, nullable: false, @@ -268,6 +272,14 @@ export const packedRolePoliciesSchema = { type: 'integer', optional: false, nullable: false, }, + uploadableFileTypes: { + type: 'array', + optional: false, nullable: false, + items: { + type: 'string', + optional: false, nullable: false, + }, + }, alwaysMarkNsfw: { type: 'boolean', optional: false, nullable: false, @@ -336,10 +348,6 @@ export const packedRolePoliciesSchema = { type: 'boolean', optional: false, nullable: false, }, - noteDraftLimit: { - type: 'integer', - optional: false, nullable: false, - }, canEditNote: { type: 'boolean', optional: false, nullable: false, @@ -370,6 +378,18 @@ export const packedRolePoliciesSchema = { optional: false, nullable: false, enum: ['available', 'readonly', 'unavailable'], }, + noteDraftLimit: { + type: 'integer', + optional: false, nullable: false, + }, + scheduledNoteLimit: { + type: 'integer', + optional: false, nullable: false, + }, + watermarkAvailable: { + type: 'boolean', + optional: false, nullable: false, + }, reactionAvailability: { type: 'string', diff --git a/packages/backend/src/models/json-schema/user-webhook.ts b/packages/backend/src/models/json-schema/user-webhook.ts new file mode 100644 index 0000000000..8ea0991716 --- /dev/null +++ b/packages/backend/src/models/json-schema/user-webhook.ts @@ -0,0 +1,55 @@ +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { webhookEventTypes } from '@/models/Webhook.js'; + +export const packedUserWebhookSchema = { + type: 'object', + properties: { + id: { + type: 'string', + format: 'id', + optional: false, nullable: false, + }, + userId: { + type: 'string', + format: 'id', + optional: false, nullable: false, + }, + name: { + type: 'string', + optional: false, nullable: false, + }, + on: { + type: 'array', + items: { + type: 'string', + optional: false, nullable: false, + enum: webhookEventTypes, + }, + }, + url: { + type: 'string', + optional: false, nullable: false, + }, + secret: { + type: 'string', + optional: false, nullable: false, + }, + active: { + type: 'boolean', + optional: false, nullable: false, + }, + latestSentAt: { + type: 'string', + format: 'date-time', + optional: false, nullable: true, + }, + latestStatus: { + type: 'integer', + optional: false, nullable: true, + }, + }, +} as const; diff --git a/packages/backend/src/models/json-schema/user.ts b/packages/backend/src/models/json-schema/user.ts index c787f33197..4cd36cae3c 100644 --- a/packages/backend/src/models/json-schema/user.ts +++ b/packages/backend/src/models/json-schema/user.ts @@ -65,7 +65,7 @@ export const packedUserLiteSchema = { avatarUrl: { type: 'string', format: 'url', - nullable: true, optional: false, + nullable: false, optional: false, }, avatarBlurhash: { type: 'string', @@ -485,11 +485,11 @@ export const packedMeDetailedOnlySchema = { }, isModerator: { type: 'boolean', - nullable: true, optional: false, + nullable: false, optional: false, }, isAdmin: { type: 'boolean', - nullable: true, optional: false, + nullable: false, optional: false, }, injectFeaturedNote: { type: 'boolean', @@ -611,7 +611,7 @@ export const packedMeDetailedOnlySchema = { }, mutedInstances: { type: 'array', - nullable: true, optional: false, + nullable: false, optional: false, items: { type: 'string', nullable: false, optional: false, @@ -629,6 +629,8 @@ export const packedMeDetailedOnlySchema = { quote: { optional: true, ...notificationRecieveConfig }, reaction: { optional: true, ...notificationRecieveConfig }, pollEnded: { optional: true, ...notificationRecieveConfig }, + scheduledNotePosted: { optional: true, ...notificationRecieveConfig }, + scheduledNotePostFailed: { optional: true, ...notificationRecieveConfig }, receiveFollowRequest: { optional: true, ...notificationRecieveConfig }, followRequestAccepted: { optional: true, ...notificationRecieveConfig }, groupInvited: { optional: true, ...notificationRecieveConfig }, @@ -713,6 +715,14 @@ export const packedMeDetailedOnlySchema = { }, }, //#endregion + autoDeleteNotesAfterDays: { + type: 'number', + nullable: true, optional: false, + }, + autoDeleteKeepFavorites: { + type: 'boolean', + nullable: false, optional: false, + }, }, } as const; diff --git a/packages/backend/src/postgres.ts b/packages/backend/src/postgres.ts index f76353453e..34836acfc7 100644 --- a/packages/backend/src/postgres.ts +++ b/packages/backend/src/postgres.ts @@ -92,7 +92,7 @@ import { MiBubbleGameRecord } from '@/models/BubbleGameRecord.js'; import { MiReversiGame } from '@/models/ReversiGame.js'; import { MiChatApproval } from '@/models/ChatApproval.js'; import { MiSystemAccount } from '@/models/SystemAccount.js'; -import { MiNoteSchedule } from '@/models/NoteSchedule.js'; +import { NoteHistory } from '@/models/NoteHistory.js'; pg.types.setTypeParser(20, Number); @@ -220,7 +220,6 @@ export const entities = [ MiNote, MiNoteFavorite, MiNoteReaction, - MiNoteSchedule, MiNoteThreadMuting, MiNoteDraft, MiPage, @@ -271,6 +270,7 @@ export const entities = [ MiChatApproval, MiBubbleGameRecord, MiReversiGame, + NoteHistory, ...charts, ]; diff --git a/packages/backend/src/queue/QueueProcessorModule.ts b/packages/backend/src/queue/QueueProcessorModule.ts index 02b9c5dd79..038bb67da7 100644 --- a/packages/backend/src/queue/QueueProcessorModule.ts +++ b/packages/backend/src/queue/QueueProcessorModule.ts @@ -6,11 +6,11 @@ import { Module } from '@nestjs/common'; import { CoreModule } from '@/core/CoreModule.js'; import { GlobalModule } from '@/GlobalModule.js'; -import { CheckModeratorsActivityProcessorService } from '@/queue/processors/CheckModeratorsActivityProcessorService.js'; import { QueueLoggerService } from './QueueLoggerService.js'; import { QueueProcessorService } from './QueueProcessorService.js'; import { DeliverProcessorService } from './processors/DeliverProcessorService.js'; import { EndedPollNotificationProcessorService } from './processors/EndedPollNotificationProcessorService.js'; +import { PostScheduledNoteProcessorService } from './processors/PostScheduledNoteProcessorService.js'; import { InboxProcessorService } from './processors/InboxProcessorService.js'; import { UserWebhookDeliverProcessorService } from './processors/UserWebhookDeliverProcessorService.js'; import { SystemWebhookDeliverProcessorService } from './processors/SystemWebhookDeliverProcessorService.js'; @@ -18,7 +18,10 @@ import { CheckExpiredMutingsProcessorService } from './processors/CheckExpiredMu import { BakeBufferedReactionsProcessorService } from './processors/BakeBufferedReactionsProcessorService.js'; import { CleanChartsProcessorService } from './processors/CleanChartsProcessorService.js'; import { CleanProcessorService } from './processors/CleanProcessorService.js'; +import { CheckModeratorsActivityProcessorService } from './processors/CheckModeratorsActivityProcessorService.js'; +import { CleanRemoteNotesProcessorService } from './processors/CleanRemoteNotesProcessorService.js'; import { CleanRemoteFilesProcessorService } from './processors/CleanRemoteFilesProcessorService.js'; +import { AutoDeleteNotesProcessorService } from './processors/AutoDeleteNotesProcessorService.js'; import { DeleteAccountProcessorService } from './processors/DeleteAccountProcessorService.js'; import { TruncateAccountProcessorService } from './processors/TruncateAccountProcessorService.js'; import { DeleteDriveFilesProcessorService } from './processors/DeleteDriveFilesProcessorService.js'; @@ -44,7 +47,6 @@ import { AggregateRetentionProcessorService } from './processors/AggregateRetent import { ExportFavoritesProcessorService } from './processors/ExportFavoritesProcessorService.js'; import { RelationshipProcessorService } from './processors/RelationshipProcessorService.js'; import { ScheduledNoteDeleteProcessorService } from './processors/ScheduledNoteDeleteProcessorService.js'; -import { ScheduleNotePostProcessorService } from './processors/ScheduleNotePostProcessorService.js'; @Module({ imports: [ @@ -84,14 +86,16 @@ import { ScheduleNotePostProcessorService } from './processors/ScheduleNotePostP UserWebhookDeliverProcessorService, SystemWebhookDeliverProcessorService, EndedPollNotificationProcessorService, + PostScheduledNoteProcessorService, DeliverProcessorService, InboxProcessorService, AggregateRetentionProcessorService, CheckExpiredMutingsProcessorService, CheckModeratorsActivityProcessorService, + CleanRemoteNotesProcessorService, + AutoDeleteNotesProcessorService, QueueProcessorService, ScheduledNoteDeleteProcessorService, - ScheduleNotePostProcessorService, ], exports: [ QueueProcessorService, diff --git a/packages/backend/src/queue/QueueProcessorService.ts b/packages/backend/src/queue/QueueProcessorService.ts index 12821b1e50..d802cfd4c0 100644 --- a/packages/backend/src/queue/QueueProcessorService.ts +++ b/packages/backend/src/queue/QueueProcessorService.ts @@ -15,6 +15,7 @@ import { CheckModeratorsActivityProcessorService } from '@/queue/processors/Chec import { UserWebhookDeliverProcessorService } from './processors/UserWebhookDeliverProcessorService.js'; import { SystemWebhookDeliverProcessorService } from './processors/SystemWebhookDeliverProcessorService.js'; import { EndedPollNotificationProcessorService } from './processors/EndedPollNotificationProcessorService.js'; +import { PostScheduledNoteProcessorService } from './processors/PostScheduledNoteProcessorService.js'; import { DeliverProcessorService } from './processors/DeliverProcessorService.js'; import { InboxProcessorService } from './processors/InboxProcessorService.js'; import { DeleteDriveFilesProcessorService } from './processors/DeleteDriveFilesProcessorService.js'; @@ -46,9 +47,10 @@ import { CheckExpiredMutingsProcessorService } from './processors/CheckExpiredMu import { BakeBufferedReactionsProcessorService } from './processors/BakeBufferedReactionsProcessorService.js'; import { CleanProcessorService } from './processors/CleanProcessorService.js'; import { AggregateRetentionProcessorService } from './processors/AggregateRetentionProcessorService.js'; +import { CleanRemoteNotesProcessorService } from './processors/CleanRemoteNotesProcessorService.js'; import { ScheduledNoteDeleteProcessorService } from './processors/ScheduledNoteDeleteProcessorService.js'; -import { ScheduleNotePostProcessorService } from './processors/ScheduleNotePostProcessorService.js'; import { QueueLoggerService } from './QueueLoggerService.js'; +import { AutoDeleteNotesProcessorService } from './processors/AutoDeleteNotesProcessorService.js'; import { QUEUE, baseWorkerOptions } from './const.js'; // ref. https://github.com/misskey-dev/misskey/pull/7635#issue-971097019 @@ -89,8 +91,8 @@ export class QueueProcessorService implements OnApplicationShutdown { private relationshipQueueWorker: Bull.Worker; private objectStorageQueueWorker: Bull.Worker; private endedPollNotificationQueueWorker: Bull.Worker; + private postScheduledNoteQueueWorker: Bull.Worker; private scheduledNoteDeleteQueueWorker: Bull.Worker; - private schedulerNotePostQueueWorker: Bull.Worker; constructor( @Inject(DI.config) @@ -103,6 +105,7 @@ export class QueueProcessorService implements OnApplicationShutdown { private userWebhookDeliverProcessorService: UserWebhookDeliverProcessorService, private systemWebhookDeliverProcessorService: SystemWebhookDeliverProcessorService, private endedPollNotificationProcessorService: EndedPollNotificationProcessorService, + private postScheduledNoteProcessorService: PostScheduledNoteProcessorService, private deliverProcessorService: DeliverProcessorService, private inboxProcessorService: InboxProcessorService, private deleteDriveFilesProcessorService: DeleteDriveFilesProcessorService, @@ -135,8 +138,9 @@ export class QueueProcessorService implements OnApplicationShutdown { private bakeBufferedReactionsProcessorService: BakeBufferedReactionsProcessorService, private checkModeratorsActivityProcessorService: CheckModeratorsActivityProcessorService, private cleanProcessorService: CleanProcessorService, + private autoDeleteNotesProcessorService: AutoDeleteNotesProcessorService, + private cleanRemoteNotesProcessorService: CleanRemoteNotesProcessorService, private scheduledNoteDeleteProcessorService: ScheduledNoteDeleteProcessorService, - private scheduleNotePostProcessorService: ScheduleNotePostProcessorService, ) { this.logger = this.queueLoggerService.logger; @@ -178,6 +182,8 @@ export class QueueProcessorService implements OnApplicationShutdown { case 'bakeBufferedReactions': return this.bakeBufferedReactionsProcessorService.process(); case 'checkModeratorsActivity': return this.checkModeratorsActivityProcessorService.process(); case 'clean': return this.cleanProcessorService.process(); + case 'cleanRemoteNotes': return this.cleanRemoteNotesProcessorService.process(job); + case 'autoDeleteNotes': return this.autoDeleteNotesProcessorService.process(job); default: throw new Error(`unrecognized job type ${job.name} for system`); } }; @@ -484,6 +490,7 @@ export class QueueProcessorService implements OnApplicationShutdown { switch (job.name) { case 'deleteFile': return this.deleteFileProcessorService.process(job); case 'cleanRemoteFiles': return this.cleanRemoteFilesProcessorService.process(job); + case 'autoDeleteNotes': return this.autoDeleteNotesProcessorService.process(job); default: throw new Error(`unrecognized job type ${job.name} for objectStorage`); } }; @@ -534,25 +541,31 @@ export class QueueProcessorService implements OnApplicationShutdown { } //#endregion - //#region scheduled note delete + //#region post scheduled note { - this.scheduledNoteDeleteQueueWorker = new Bull.Worker(QUEUE.SCHEDULED_NOTE_DELETE, (job) => { + this.postScheduledNoteQueueWorker = new Bull.Worker(QUEUE.POST_SCHEDULED_NOTE, async (job) => { if (this.config.sentryForBackend) { - return Sentry.startSpan({ name: 'Queue: ScheduledNoteDelete' }, () => this.scheduledNoteDeleteProcessorService.process(job)); + return Sentry.startSpan({ name: 'Queue: PostScheduledNote' }, () => this.postScheduledNoteProcessorService.process(job)); } else { - return this.scheduledNoteDeleteProcessorService.process(job); + return this.postScheduledNoteProcessorService.process(job); } }, { - ...baseWorkerOptions(this.config, QUEUE.SCHEDULED_NOTE_DELETE, this.redisForJobQueue), + ...baseWorkerOptions(this.config, QUEUE.POST_SCHEDULED_NOTE, this.redisForJobQueue), autorun: false, }); } //#endregion - //#region schedule note post + //#region scheduled note delete { - this.schedulerNotePostQueueWorker = new Bull.Worker(QUEUE.SCHEDULE_NOTE_POST, (job) => this.scheduleNotePostProcessorService.process(job), { - ...baseWorkerOptions(this.config, QUEUE.SCHEDULE_NOTE_POST, this.redisForJobQueue), + this.scheduledNoteDeleteQueueWorker = new Bull.Worker(QUEUE.SCHEDULED_NOTE_DELETE, (job) => { + if (this.config.sentryForBackend) { + return Sentry.startSpan({ name: 'Queue: ScheduledNoteDelete' }, () => this.scheduledNoteDeleteProcessorService.process(job)); + } else { + return this.scheduledNoteDeleteProcessorService.process(job); + } + }, { + ...baseWorkerOptions(this.config, QUEUE.SCHEDULED_NOTE_DELETE, this.redisForJobQueue), autorun: false, }); } @@ -571,8 +584,8 @@ export class QueueProcessorService implements OnApplicationShutdown { this.relationshipQueueWorker.run(), this.objectStorageQueueWorker.run(), this.endedPollNotificationQueueWorker.run(), + this.postScheduledNoteQueueWorker.run(), this.scheduledNoteDeleteQueueWorker.run(), - this.schedulerNotePostQueueWorker.run(), ]); } @@ -588,8 +601,8 @@ export class QueueProcessorService implements OnApplicationShutdown { this.relationshipQueueWorker.close(), this.objectStorageQueueWorker.close(), this.endedPollNotificationQueueWorker.close(), + this.postScheduledNoteQueueWorker.close(), this.scheduledNoteDeleteQueueWorker.close(), - this.schedulerNotePostQueueWorker.close(), ]); } diff --git a/packages/backend/src/queue/const.ts b/packages/backend/src/queue/const.ts index 3795394c37..8d8c74ef0e 100644 --- a/packages/backend/src/queue/const.ts +++ b/packages/backend/src/queue/const.ts @@ -13,13 +13,13 @@ export const QUEUE = { INBOX: 'inbox', SYSTEM: 'system', ENDED_POLL_NOTIFICATION: 'endedPollNotification', + POST_SCHEDULED_NOTE: 'postScheduledNote', DB: 'db', RELATIONSHIP: 'relationship', OBJECT_STORAGE: 'objectStorage', USER_WEBHOOK_DELIVER: 'userWebhookDeliver', SYSTEM_WEBHOOK_DELIVER: 'systemWebhookDeliver', SCHEDULED_NOTE_DELETE: 'scheduledNoteDelete', - SCHEDULE_NOTE_POST: 'scheduleNotePost', }; export function baseQueueOptions(config: Config, queueName: typeof QUEUE[keyof typeof QUEUE], redisConnection: Redis.Redis): Bull.QueueOptions { diff --git a/packages/backend/src/queue/processors/AutoDeleteNotesProcessorService.ts b/packages/backend/src/queue/processors/AutoDeleteNotesProcessorService.ts new file mode 100644 index 0000000000..8191f01db9 --- /dev/null +++ b/packages/backend/src/queue/processors/AutoDeleteNotesProcessorService.ts @@ -0,0 +1,105 @@ +/* + * SPDX-FileCopyrightText: noridev and cherrypick-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { Inject, Injectable } from '@nestjs/common'; +import { IsNull, LessThan, Not } from 'typeorm'; +import { DI } from '@/di-symbols.js'; +import type { NotesRepository, UsersRepository } from '@/models/_.js'; +import type Logger from '@/logger.js'; +import { bindThis } from '@/decorators.js'; +import { IdService } from '@/core/IdService.js'; +import { QueueLoggerService } from '../QueueLoggerService.js'; +import type * as Bull from 'bullmq'; + +@Injectable() +export class AutoDeleteNotesProcessorService { + private logger: Logger; + + constructor( + @Inject(DI.usersRepository) + private usersRepository: UsersRepository, + + @Inject(DI.notesRepository) + private notesRepository: NotesRepository, + + private idService: IdService, + private queueLoggerService: QueueLoggerService, + ) { + this.logger = this.queueLoggerService.logger.createSubLogger('auto-delete-notes'); + } + + @bindThis + public async process(job: Bull.Job>): Promise<{ + deletedCount: number; + processedUsers: number; + }> { + this.logger.info('Starting auto-delete notes process...'); + + const stats = { + deletedCount: 0, + processedUsers: 0, + }; + + // autoDeleteNotesAfterDays가 설정된 유저 찾기 + const usersWithAutoDelete = await this.usersRepository.findBy({ + autoDeleteNotesAfterDays: Not(IsNull()), + }); + + if (usersWithAutoDelete.length === 0) { + this.logger.info('No users with auto-delete settings found.'); + return stats; + } + + this.logger.info(`Found ${usersWithAutoDelete.length} users with auto-delete settings.`); + + // 각 유저별로 처리 + for (const user of usersWithAutoDelete) { + try { + const days = user.autoDeleteNotesAfterDays; + if (days === null || days <= 0) continue; + + // 삭제 기준 날짜 계산 + const deleteBeforeDate = new Date(Date.now() - (days * 24 * 60 * 60 * 1000)); + const deleteBeforeId = this.idService.gen(deleteBeforeDate.getTime()); + + this.logger.info(`Processing user ${user.id}: deleting notes older than ${days} days (before ${deleteBeforeDate.toISOString()})`); + + // 삭제할 노트 찾기 + const queryBuilder = this.notesRepository.createQueryBuilder('note') + .where('note.userId = :userId', { userId: user.id }) + .andWhere('note.id < :deleteBeforeId', { deleteBeforeId }); + + // 즐겨찾기 보호 설정이 켜져 있으면 즐겨찾기된 노트 제외 + if (user.autoDeleteKeepFavorites) { + queryBuilder.andWhere('NOT EXISTS (SELECT 1 FROM note_favorite WHERE "noteId" = note.id)'); + } + + const notesToDelete = await queryBuilder + .select('note.id') + .limit(1000) // 한 번에 최대 1000개씩 처리 + .getMany(); + + if (notesToDelete.length > 0) { + const noteIds = notesToDelete.map(note => note.id); + await this.notesRepository.delete(noteIds); + + stats.deletedCount += noteIds.length; + this.logger.info(`Deleted ${noteIds.length} notes for user ${user.id}`); + } else { + this.logger.info(`No notes to delete for user ${user.id}`); + } + + stats.processedUsers++; + } catch (error) { + this.logger.error(`Error processing user ${user.id}: ${error}`); + // 한 유저의 에러가 전체 프로세스를 막지 않도록 계속 진행 + } + } + + this.logger.succ(`Auto-delete notes process completed. Processed ${stats.processedUsers} users, deleted ${stats.deletedCount} notes.`); + + return stats; + } +} diff --git a/packages/backend/src/queue/processors/CleanRemoteFilesProcessorService.ts b/packages/backend/src/queue/processors/CleanRemoteFilesProcessorService.ts index 1c1739a7ba..0d74072f38 100644 --- a/packages/backend/src/queue/processors/CleanRemoteFilesProcessorService.ts +++ b/packages/backend/src/queue/processors/CleanRemoteFilesProcessorService.ts @@ -34,6 +34,11 @@ export class CleanRemoteFilesProcessorService { let deletedCount = 0; let cursor: MiDriveFile['id'] | null = null; + const total = await this.driveFilesRepository.countBy({ + userHost: Not(IsNull()), + isLink: false, + }); + while (true) { const files = await this.driveFilesRepository.find({ where: { @@ -58,12 +63,7 @@ export class CleanRemoteFilesProcessorService { deletedCount += 8; - const total = await this.driveFilesRepository.countBy({ - userHost: Not(IsNull()), - isLink: false, - }); - - job.updateProgress(100 / total * deletedCount); + job.updateProgress(deletedCount * total / 100); } this.logger.succ('All cached remote files has been deleted.'); diff --git a/packages/backend/src/queue/processors/CleanRemoteNotesProcessorService.ts b/packages/backend/src/queue/processors/CleanRemoteNotesProcessorService.ts new file mode 100644 index 0000000000..36c34c753c --- /dev/null +++ b/packages/backend/src/queue/processors/CleanRemoteNotesProcessorService.ts @@ -0,0 +1,289 @@ +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { setTimeout } from 'node:timers/promises'; +import { Inject, Injectable } from '@nestjs/common'; +import { DataSource, IsNull, LessThan, QueryFailedError, Not } from 'typeorm'; +import { DI } from '@/di-symbols.js'; +import type { MiMeta, MiNote, NotesRepository } from '@/models/_.js'; +import type Logger from '@/logger.js'; +import { bindThis } from '@/decorators.js'; +import { IdService } from '@/core/IdService.js'; +import { QueueLoggerService } from '../QueueLoggerService.js'; +import type * as Bull from 'bullmq'; + +@Injectable() +export class CleanRemoteNotesProcessorService { + private logger: Logger; + + constructor( + @Inject(DI.meta) + private meta: MiMeta, + + @Inject(DI.notesRepository) + private notesRepository: NotesRepository, + + @Inject(DI.db) + private db: DataSource, + + private idService: IdService, + private queueLoggerService: QueueLoggerService, + ) { + this.logger = this.queueLoggerService.logger.createSubLogger('clean-remote-notes'); + } + + @bindThis + private computeProgress(minId: string, maxId: string, cursorLeft: string) { + const minTs = this.idService.parse(minId).date.getTime(); + const maxTs = this.idService.parse(maxId).date.getTime(); + const cursorTs = this.idService.parse(cursorLeft).date.getTime(); + + return ((cursorTs - minTs) / (maxTs - minTs)) * 100; + } + + @bindThis + public async process(job: Bull.Job>): Promise<{ + deletedCount: number; + oldest: number | null; + newest: number | null; + skipped: boolean; + transientErrors: number; + }> { + if (!this.meta.enableRemoteNotesCleaning) { + this.logger.info('Remote notes cleaning is disabled, skipping...'); + return { + deletedCount: 0, + oldest: null, + newest: null, + skipped: true, + transientErrors: 0, + }; + } + + this.logger.info('cleaning remote notes...'); + + const maxDuration = this.meta.remoteNotesCleaningMaxProcessingDurationInMinutes * 60 * 1000; // Convert minutes to milliseconds + const startAt = Date.now(); + + //#region queries + // The date limit for the newest note to be considered for deletion. + // All notes newer than this limit will always be retained. + const newestLimit = this.idService.gen(Date.now() - (1000 * 60 * 60 * 24 * this.meta.remoteNotesCleaningExpiryDaysForEachNotes)); + + // The condition for removing the notes. + // The note must be: + // - old enough (older than the newestLimit) + // - a remote note (userHost is not null). + // - not have clipped + // - not have pinned on the user profile + // - not has been favorite by any user + const removalCriteria = [ + 'note."id" < :newestLimit', + 'note."clippedCount" = 0', + 'note."pageCount" = 0', + 'note."userHost" IS NOT NULL', + 'NOT EXISTS (SELECT 1 FROM user_note_pining WHERE "noteId" = note."id")', + 'NOT EXISTS (SELECT 1 FROM note_favorite WHERE "noteId" = note."id")', + 'NOT EXISTS (SELECT 1 FROM note_reaction INNER JOIN "user" ON note_reaction."userId" = "user".id WHERE note_reaction."noteId" = note."id" AND "user"."host" IS NULL)', + ].join(' AND '); + + const minId = (await this.notesRepository.createQueryBuilder('note') + .select('MIN(note.id)', 'minId') + .where({ + id: LessThan(newestLimit), + userHost: Not(IsNull()), + replyId: IsNull(), + renoteId: IsNull(), + }) + .getRawOne<{ minId?: MiNote['id'] }>())?.minId; + + if (!minId) { + this.logger.info('No notes can possibly be deleted, skipping...'); + return { + deletedCount: 0, + oldest: null, + newest: null, + skipped: false, + transientErrors: 0, + }; + } + + // start with a conservative limit and adjust it based on the query duration + const minimumLimit = 10; + let currentLimit = 100; + let cursorLeft = '0'; + + const candidateNotesCteName = 'candidate_notes'; + + // tree walk down all root notes, short-circuit when the first unremovable note is found + const candidateNotesQueryBase = this.notesRepository.createQueryBuilder('note') + .select('note."id"', 'id') + .addSelect('note."replyId"', 'replyId') + .addSelect('note."renoteId"', 'renoteId') + .addSelect('note."id"', 'rootId') + .addSelect('TRUE', 'isRemovable') + .addSelect('TRUE', 'isBase') + .where('note."id" > :cursorLeft') + .andWhere(removalCriteria) + .andWhere({ replyId: IsNull(), renoteId: IsNull() }); + + const candidateNotesQueryInductive = this.notesRepository.createQueryBuilder('note') + .select('note.id', 'id') + .addSelect('note."replyId"', 'replyId') + .addSelect('note."renoteId"', 'renoteId') + .addSelect('parent."rootId"', 'rootId') + .addSelect(removalCriteria, 'isRemovable') + .addSelect('FALSE', 'isBase') + .innerJoin(candidateNotesCteName, 'parent', 'parent."id" = note."replyId" OR parent."id" = note."renoteId"') + .where('parent."isRemovable" = TRUE'); + + // A note tree can be deleted if there are no unremovable rows with the same rootId. + // + // `candidate_notes` will have the following structure after recursive query (some columns omitted): + // After performing a LEFT JOIN with `candidate_notes` as `unremovable`, + // the note tree containing unremovable notes will be anti-joined. + // For removable rows, the `unremovable` columns will have `NULL` values. + // | id | rootId | isRemovable | + // |-----|--------|-------------| + // | aaa | aaa | TRUE | + // | bbb | aaa | FALSE | + // | ccc | aaa | FALSE | + // | ddd | ddd | TRUE | + // | eee | ddd | TRUE | + // | fff | fff | TRUE | + // | ggg | ggg | FALSE | + // + const candidateNotesQuery = this.db.createQueryBuilder() + .select(`"${candidateNotesCteName}"."id"`, 'id') + .addSelect('unremovable."id" IS NULL', 'isRemovable') + .addSelect(`BOOL_OR("${candidateNotesCteName}"."isBase")`, 'isBase') + .addCommonTableExpression( + `((SELECT "base".* FROM (${candidateNotesQueryBase.orderBy('note.id', 'ASC').limit(currentLimit).getQuery()}) AS "base") UNION ${candidateNotesQueryInductive.getQuery()})`, + candidateNotesCteName, + { recursive: true }, + ) + .from(candidateNotesCteName, candidateNotesCteName) + .leftJoin(candidateNotesCteName, 'unremovable', `unremovable."rootId" = "${candidateNotesCteName}"."rootId" AND unremovable."isRemovable" = FALSE`) + .groupBy(`"${candidateNotesCteName}"."id"`) + .addGroupBy('unremovable."id" IS NULL'); + + const stats = { + deletedCount: 0, + oldest: null as number | null, + newest: null as number | null, + }; + + let lowThroughputWarned = false; + let transientErrors = 0; + for (;;) { + //#region check time + const batchBeginAt = Date.now(); + + const elapsed = batchBeginAt - startAt; + + const progress = this.computeProgress(minId, newestLimit, cursorLeft > minId ? cursorLeft : minId); + + if (elapsed >= maxDuration) { + job.log(`Reached maximum duration of ${maxDuration}ms, stopping... (last cursor: ${cursorLeft}, final progress ${progress}%)`); + job.updateProgress(100); + break; + } + + const wallClockUsage = elapsed / maxDuration; + if (wallClockUsage > 0.5 && progress < 50 && !lowThroughputWarned) { + const msg = `Not projected to finish in time! (wall clock usage ${wallClockUsage * 100}% at ${progress}%, current limit ${currentLimit})`; + this.logger.warn(msg); + job.log(msg); + lowThroughputWarned = true; + } + job.updateProgress(progress); + //#endregion + + const queryBegin = performance.now(); + let noteIds = null; + + try { + noteIds = await candidateNotesQuery.setParameters( + { newestLimit, cursorLeft }, + ).getRawMany<{ id: MiNote['id'], isRemovable: boolean, isBase: boolean }>(); + } catch (e) { + if (currentLimit > minimumLimit && e instanceof QueryFailedError && e.driverError?.code === '57014') { + // Statement timeout (maybe suddenly hit a large note tree), reduce the limit and try again + // continuous failures will eventually converge to currentLimit == minimumLimit and then throw + currentLimit = Math.max(minimumLimit, Math.floor(currentLimit * 0.25)); + continue; + } + throw e; + } + + if (noteIds.length === 0) { + job.log('No more notes to clean.'); + break; + } + + const queryDuration = performance.now() - queryBegin; + // try to adjust such that each query takes about 1~5 seconds and reasonable NodeJS heap so the task stays responsive + // this should not oscillate.. + if (queryDuration > 5000 || noteIds.length > 5000) { + currentLimit = Math.floor(currentLimit * 0.5); + } else if (queryDuration < 1000 && noteIds.length < 1000) { + currentLimit = Math.floor(currentLimit * 1.5); + } + // clamp to a sane range + currentLimit = Math.min(Math.max(currentLimit, minimumLimit), 5000); + + const deletableNoteIds = noteIds.filter(result => result.isRemovable).map(result => result.id); + if (deletableNoteIds.length > 0) { + try { + await this.notesRepository.delete(deletableNoteIds); + + for (const id of deletableNoteIds) { + const t = this.idService.parse(id).date.getTime(); + if (stats.oldest === null || t < stats.oldest) { + stats.oldest = t; + } + if (stats.newest === null || t > stats.newest) { + stats.newest = t; + } + } + + stats.deletedCount += deletableNoteIds.length; + } catch (e) { + // check for integrity violation errors (class 23) that might have occurred between the check and the delete + // we can safely continue to the next batch + if (e instanceof QueryFailedError && e.driverError?.code?.startsWith('23')) { + transientErrors++; + job.log(`Error deleting notes: ${e} (transient race condition?)`); + } else { + throw e; + } + } + } + + cursorLeft = noteIds.filter(result => result.isBase).reduce((max, { id }) => id > max ? id : max, cursorLeft); + + job.log(`Deleted ${noteIds.length} notes; ${Date.now() - batchBeginAt}ms`); + + if (process.env.NODE_ENV !== 'test') { + await setTimeout(Math.min(1000 * 5, queryDuration)); // Wait a moment to avoid overwhelming the db + } + }; + + if (transientErrors > 0) { + const msg = `${transientErrors} transient errors occurred while cleaning remote notes. You may need a second pass to complete the cleaning.`; + this.logger.warn(msg); + job.log(msg); + } + this.logger.succ('cleaning of remote notes completed.'); + + return { + deletedCount: stats.deletedCount, + oldest: stats.oldest, + newest: stats.newest, + skipped: false, + transientErrors, + }; + } +} diff --git a/packages/backend/src/queue/processors/DeleteAccountProcessorService.ts b/packages/backend/src/queue/processors/DeleteAccountProcessorService.ts index eb607002dd..31c4ce9a28 100644 --- a/packages/backend/src/queue/processors/DeleteAccountProcessorService.ts +++ b/packages/backend/src/queue/processors/DeleteAccountProcessorService.ts @@ -6,7 +6,7 @@ import { Not, IsNull, MoreThan } from 'typeorm'; import { Inject, Injectable } from '@nestjs/common'; import { DI } from '@/di-symbols.js'; -import type { DriveFilesRepository, NotesRepository, FollowRequestsRepository, UserProfilesRepository, UsersRepository, FollowingsRepository, UserListMembershipsRepository } from '@/models/_.js'; +import type { DriveFilesRepository, NotesRepository, PagesRepository, FollowRequestsRepository, UserProfilesRepository, UsersRepository, FollowingsRepository, UserListMembershipsRepository } from '@/models/_.js'; import type Logger from '@/logger.js'; import { DriveService } from '@/core/DriveService.js'; import type { MiUser } from '@/models/User.js'; @@ -18,7 +18,9 @@ import { EmailService } from '@/core/EmailService.js'; import { RoleService } from '@/core/RoleService.js'; import { bindThis } from '@/decorators.js'; import { SearchService } from '@/core/SearchService.js'; +import { PageService } from '@/core/PageService.js'; import { UserEntityService } from '@/core/entities/UserEntityService.js'; +import { GlobalEventService } from '@/core/GlobalEventService.js'; import { QueueLoggerService } from '../QueueLoggerService.js'; import type * as Bull from 'bullmq'; import type { DbUserDeleteJobData } from '../types.js'; @@ -49,61 +51,22 @@ export class DeleteAccountProcessorService { @Inject(DI.userListMembershipsRepository) private userListMembershipsRepository: UserListMembershipsRepository, + @Inject(DI.pagesRepository) + private pagesRepository: PagesRepository, + private userEntityService: UserEntityService, private driveService: DriveService, + private pageService: PageService, private emailService: EmailService, private roleService: RoleService, private queueLoggerService: QueueLoggerService, private searchService: SearchService, + private globalEventService: GlobalEventService, private queueService: QueueService, ) { this.logger = this.queueLoggerService.logger.createSubLogger('delete-account'); } - private async deleteNotes(user: MiUser) { - while (true) { - const notes = await this.notesRepository.find({ - where: { - userId: user.id, - }, - take: 100, - }); - - if (notes.length === 0) { - break; - } - - await this.notesRepository.delete(notes.map(note => note.id)); - - for (const note of notes) { - await this.searchService.unindexNote(note); - } - } - - this.logger.succ('All of notes deleted'); - } - - private async deleteFiles(user: MiUser) { - while (true) { - const files = await this.driveFilesRepository.find({ - where: { - userId: user.id, - }, - take: 10, - }); - - if (files.length === 0) { - break; - } - - for (const file of files) { - await this.driveService.deleteFileSync(file); - } - } - - this.logger.succ('All of files deleted'); - } - @bindThis public async process(job: Bull.Job): Promise { this.logger.info(`Deleting account of ${job.data.user.id} ...`, { userDeleteJobData: job.data }); @@ -116,11 +79,93 @@ export class DeleteAccountProcessorService { ? await this.roleService.getUserPolicies(user.id) : { /*canDeleteContent: true,*/ canPurgeAccount: true }; - if (job.data.onlyFiles) { - //if (!canDeleteContent) return 'Permission denied'; + if (job.data.onlyFiles || !(!canPurgeAccount || job.data.soft)) { + { // Delete files + let cursor: MiDriveFile['id'] | null = null; + + while (true) { + const files = await this.driveFilesRepository.find({ + where: { + userId: user.id, + ...(cursor ? { id: MoreThan(cursor) } : {}), + }, + take: 10, + order: { + id: 1, + }, + }) as MiDriveFile[]; + + if (files.length === 0) { + break; + } + + cursor = files.at(-1)?.id ?? null; + + for (const file of files) { + await this.driveService.deleteFileSync(file, undefined, isRemote); + } + } - await this.deleteFiles(user); - return 'Files deleted'; + this.logger.succ(`All of files deleted: ${job.data.user.id}`); + + if (job.data.onlyFiles) { + return 'File Deleted.'; + } + } + } + if (!(!canPurgeAccount || job.data.soft)) { + { // Delete notes + let cursor: MiNote['id'] | null = null; + + while (true) { + const notes = await this.notesRepository.find({ + where: { + userId: user.id, + ...(cursor ? { id: MoreThan(cursor) } : {}), + }, + take: 100, + order: { + id: 1, + }, + }) as MiNote[]; + + if (notes.length === 0) { + break; + } + + cursor = notes.at(-1)?.id ?? null; + + await this.notesRepository.delete(notes.map(note => note.id)); + + for (const note of notes) { + await this.searchService.unindexNote(note); + } + } + + this.logger.succ(`All of notes deleted: ${job.data.user.id}`); + } + + { + // delete pages. Necessary for decrementing pageCount of notes. + while (true) { + const pages = await this.pagesRepository.find({ + where: { + userId: user.id, + }, + take: 100, + order: { + id: 1, + }, + }); + + if (pages.length === 0) { + break; + } + for (const page of pages) { + await this.pageService.delete(user, page.id); + } + } + } } { // Send email notification @@ -142,10 +187,13 @@ export class DeleteAccountProcessorService { //削除しない代わりにユーザーの痕跡をすべて解除する (async () => { //await this.unsubscribeList(user).catch(e => {}); - await this.unFollowAll(user).catch(e => {}); + await this.unFollowAll(user).catch(e => { }); })(); } else { await this.usersRepository.delete(job.data.user.id); + + // Trigger CacheService + this.globalEventService.publishInternalEvent('remoteUserUpdated', { id: job.data.user.id }); } return `[${job.data.user.id}] Account deleted`; diff --git a/packages/backend/src/queue/processors/DeleteDriveFilesProcessorService.ts b/packages/backend/src/queue/processors/DeleteDriveFilesProcessorService.ts index 1ca44b56e4..f27469a430 100644 --- a/packages/backend/src/queue/processors/DeleteDriveFilesProcessorService.ts +++ b/packages/backend/src/queue/processors/DeleteDriveFilesProcessorService.ts @@ -46,6 +46,10 @@ export class DeleteDriveFilesProcessorService { let deletedCount = 0; let cursor: MiDriveFile['id'] | null = null; + const total = await this.driveFilesRepository.countBy({ + userId: user.id, + }); + while (true) { const files = await this.driveFilesRepository.find({ where: { @@ -70,11 +74,7 @@ export class DeleteDriveFilesProcessorService { deletedCount++; } - const total = await this.driveFilesRepository.countBy({ - userId: user.id, - }); - - job.updateProgress(deletedCount / total); + job.updateProgress(deletedCount / total * 100); } this.logger.succ(`All drive files (${deletedCount}) of ${user.id} has been deleted.`); diff --git a/packages/backend/src/queue/processors/ExportAntennasProcessorService.ts b/packages/backend/src/queue/processors/ExportAntennasProcessorService.ts index b3111865ad..599a78d60f 100644 --- a/packages/backend/src/queue/processors/ExportAntennasProcessorService.ts +++ b/packages/backend/src/queue/processors/ExportAntennasProcessorService.ts @@ -15,6 +15,7 @@ import { bindThis } from '@/decorators.js'; import { createTemp } from '@/misc/create-temp.js'; import { UtilityService } from '@/core/UtilityService.js'; import { NotificationService } from '@/core/NotificationService.js'; +import { ExportedAntenna } from '@/queue/processors/ImportAntennasProcessorService.js'; import { QueueLoggerService } from '../QueueLoggerService.js'; import type { DBExportAntennasData } from '../types.js'; import type * as Bull from 'bullmq'; @@ -74,7 +75,7 @@ export class ExportAntennasProcessorService { } write(JSON.stringify({ name: antenna.name, - src: antenna.src, + src: antenna.src as any, keywords: antenna.keywords, excludeKeywords: antenna.excludeKeywords, users: antenna.users, @@ -86,7 +87,8 @@ export class ExportAntennasProcessorService { excludeBots: antenna.excludeBots, withReplies: antenna.withReplies, withFile: antenna.withFile, - })); + excludeNotesInSensitiveChannel: antenna.excludeNotesInSensitiveChannel, + } satisfies Required)); if (antennas.length - 1 !== index) { write(', '); } diff --git a/packages/backend/src/queue/processors/ExportBlockingProcessorService.ts b/packages/backend/src/queue/processors/ExportBlockingProcessorService.ts index ecc439db69..cca7cdf9da 100644 --- a/packages/backend/src/queue/processors/ExportBlockingProcessorService.ts +++ b/packages/backend/src/queue/processors/ExportBlockingProcessorService.ts @@ -58,6 +58,10 @@ export class ExportBlockingProcessorService { let exportedCount = 0; let cursor: MiBlocking['id'] | null = null; + const total = await this.blockingsRepository.countBy({ + blockerId: user.id, + }); + while (true) { const blockings = await this.blockingsRepository.find({ where: { @@ -97,11 +101,7 @@ export class ExportBlockingProcessorService { exportedCount++; } - const total = await this.blockingsRepository.countBy({ - blockerId: user.id, - }); - - job.updateProgress(exportedCount / total); + job.updateProgress(exportedCount / total * 100); } stream.end(); diff --git a/packages/backend/src/queue/processors/ExportClipsProcessorService.ts b/packages/backend/src/queue/processors/ExportClipsProcessorService.ts index 38b9f5b455..b2bed75bc0 100644 --- a/packages/backend/src/queue/processors/ExportClipsProcessorService.ts +++ b/packages/backend/src/queue/processors/ExportClipsProcessorService.ts @@ -93,6 +93,10 @@ export class ExportClipsProcessorService { let exportedClipsCount = 0; let cursor: MiClip['id'] | null = null; + const total = await this.clipsRepository.countBy({ + userId: user.id, + }); + while (true) { const clips = await this.clipsRepository.find({ where: { @@ -124,11 +128,7 @@ export class ExportClipsProcessorService { exportedClipsCount++; } - const total = await this.clipsRepository.countBy({ - userId: user.id, - }); - - job.updateProgress(exportedClipsCount / total); + job.updateProgress(exportedClipsCount / total * 100); } } diff --git a/packages/backend/src/queue/processors/ExportFavoritesProcessorService.ts b/packages/backend/src/queue/processors/ExportFavoritesProcessorService.ts index b81feece01..7918c8ccb5 100644 --- a/packages/backend/src/queue/processors/ExportFavoritesProcessorService.ts +++ b/packages/backend/src/queue/processors/ExportFavoritesProcessorService.ts @@ -78,6 +78,10 @@ export class ExportFavoritesProcessorService { let exportedFavoritesCount = 0; let cursor: MiNoteFavorite['id'] | null = null; + const total = await this.noteFavoritesRepository.countBy({ + userId: user.id, + }); + while (true) { const favorites = await this.noteFavoritesRepository.find({ where: { @@ -109,11 +113,7 @@ export class ExportFavoritesProcessorService { exportedFavoritesCount++; } - const total = await this.noteFavoritesRepository.countBy({ - userId: user.id, - }); - - job.updateProgress(exportedFavoritesCount / total); + job.updateProgress(exportedFavoritesCount / total * 100); } await write(']'); diff --git a/packages/backend/src/queue/processors/ExportFollowingProcessorService.ts b/packages/backend/src/queue/processors/ExportFollowingProcessorService.ts index 903f962515..91c39cb758 100644 --- a/packages/backend/src/queue/processors/ExportFollowingProcessorService.ts +++ b/packages/backend/src/queue/processors/ExportFollowingProcessorService.ts @@ -94,7 +94,8 @@ export class ExportFollowingProcessorService { continue; } - const content = this.utilityService.getFullApAccount(u.username, u.host); + const userAcct = this.utilityService.getFullApAccount(u.username, u.host); + const content = `${userAcct},withReplies=${following.withReplies}`; await new Promise((res, rej) => { stream.write(content + '\n', err => { if (err) { diff --git a/packages/backend/src/queue/processors/ExportMutingProcessorService.ts b/packages/backend/src/queue/processors/ExportMutingProcessorService.ts index f9867ade29..59448ccd34 100644 --- a/packages/backend/src/queue/processors/ExportMutingProcessorService.ts +++ b/packages/backend/src/queue/processors/ExportMutingProcessorService.ts @@ -58,6 +58,10 @@ export class ExportMutingProcessorService { let exportedCount = 0; let cursor: MiMuting['id'] | null = null; + const total = await this.mutingsRepository.countBy({ + muterId: user.id, + }); + while (true) { const mutes = await this.mutingsRepository.find({ where: { @@ -98,11 +102,7 @@ export class ExportMutingProcessorService { exportedCount++; } - const total = await this.mutingsRepository.countBy({ - muterId: user.id, - }); - - job.updateProgress(exportedCount / total); + job.updateProgress(exportedCount / total * 100); } stream.end(); diff --git a/packages/backend/src/queue/processors/ExportNotesProcessorService.ts b/packages/backend/src/queue/processors/ExportNotesProcessorService.ts index 8ca7a7cc3d..b5bb898bd9 100644 --- a/packages/backend/src/queue/processors/ExportNotesProcessorService.ts +++ b/packages/backend/src/queue/processors/ExportNotesProcessorService.ts @@ -37,6 +37,8 @@ class NoteStream extends ReadableStream> { let exportedNotesCount = 0; let cursor: MiNote['id'] | null = null; + const totalPromise = notesRepository.countBy({ userId }); + const serialize = ( note: MiNote, poll: MiPoll | null, @@ -48,7 +50,6 @@ class NoteStream extends ReadableStream> { createdAt: idService.parse(note.id).date.toISOString(), updatedAt: note.updatedAt?.toISOString(), updatedAtHistory: note.updatedAtHistory?.map(x => x.toISOString()), - noteEditHistory: note.noteEditHistory, fileIds: note.fileIds, files: files, replyId: note.replyId, @@ -92,8 +93,8 @@ class NoteStream extends ReadableStream> { exportedNotesCount++; } - const total = await notesRepository.countBy({ userId }); - job.updateProgress(exportedNotesCount / total); + const total = await totalPromise; + job.updateProgress(exportedNotesCount / total * 100); }, }); } diff --git a/packages/backend/src/queue/processors/ExportUserListsProcessorService.ts b/packages/backend/src/queue/processors/ExportUserListsProcessorService.ts index c483d79854..733e75f65f 100644 --- a/packages/backend/src/queue/processors/ExportUserListsProcessorService.ts +++ b/packages/backend/src/queue/processors/ExportUserListsProcessorService.ts @@ -67,10 +67,12 @@ export class ExportUserListsProcessorService { const users = await this.usersRepository.findBy({ id: In(memberships.map(j => j.userId)), }); + const usersWithReplies = new Set(memberships.filter(m => m.withReplies).map(m => m.userId)); for (const u of users) { const acct = this.utilityService.getFullApAccount(u.username, u.host); - const content = `${list.name},${acct}`; + // 3rd column and later will be key=value pairs + const content = `${list.name},${acct},withReplies=${usersWithReplies.has(u.id)}`; await new Promise((res, rej) => { stream.write(content + '\n', err => { if (err) { diff --git a/packages/backend/src/queue/processors/ImportAntennasProcessorService.ts b/packages/backend/src/queue/processors/ImportAntennasProcessorService.ts index 9c033b73e2..4c7f2d09bb 100644 --- a/packages/backend/src/queue/processors/ImportAntennasProcessorService.ts +++ b/packages/backend/src/queue/processors/ImportAntennasProcessorService.ts @@ -11,17 +11,18 @@ import Logger from '@/logger.js'; import type { AntennasRepository } from '@/models/_.js'; import { DI } from '@/di-symbols.js'; import { bindThis } from '@/decorators.js'; +import { Schema, SchemaType } from '@/misc/json-schema.js'; import { QueueLoggerService } from '../QueueLoggerService.js'; import { DBAntennaImportJobData } from '../types.js'; import type * as Bull from 'bullmq'; const Ajv = _Ajv.default; -const validate = new Ajv().compile({ +const exportedAntennaSchema = { type: 'object', properties: { name: { type: 'string', minLength: 1, maxLength: 100 }, - src: { type: 'string', enum: ['home', 'all', 'users', 'list'] }, + src: { type: 'string', enum: ['home', 'all', 'users', 'list', 'users_blacklist'] }, userListAccts: { type: 'array', items: { @@ -47,9 +48,14 @@ const validate = new Ajv().compile({ excludeBots: { type: 'boolean' }, withReplies: { type: 'boolean' }, withFile: { type: 'boolean' }, + excludeNotesInSensitiveChannel: { type: 'boolean' }, }, required: ['name', 'src', 'keywords', 'excludeKeywords', 'users', 'caseSensitive', 'withReplies', 'withFile'], -}); +} as const satisfies Schema; + +export type ExportedAntenna = SchemaType; + +const validate = new Ajv().compile(exportedAntennaSchema); @Injectable() export class ImportAntennasProcessorService { @@ -91,6 +97,7 @@ export class ImportAntennasProcessorService { excludeBots: antenna.excludeBots, withReplies: antenna.withReplies, withFile: antenna.withFile, + excludeNotesInSensitiveChannel: antenna.excludeNotesInSensitiveChannel, }); this.logger.succ('Antenna created: ' + result.id); this.globalEventService.publishInternalEvent('antennaCreated', result); diff --git a/packages/backend/src/queue/processors/ImportFollowingProcessorService.ts b/packages/backend/src/queue/processors/ImportFollowingProcessorService.ts index 70c9f3a096..03663d3b06 100644 --- a/packages/backend/src/queue/processors/ImportFollowingProcessorService.ts +++ b/packages/backend/src/queue/processors/ImportFollowingProcessorService.ts @@ -67,8 +67,19 @@ export class ImportFollowingProcessorService { const user = job.data.user; try { - const acct = line.split(',')[0].trim(); + const parts = line.split(','); + const acct = parts[0].trim(); const { username, host } = Acct.parse(acct); + let withReplies: boolean | null = null; + + for (const keyValue of parts.slice(2)) { + const [key, value] = keyValue.split('='); + switch (key) { + case 'withReplies': + withReplies = value === 'true'; + break; + } + } if (!host) return; @@ -95,7 +106,7 @@ export class ImportFollowingProcessorService { this.logger.info(`Follow ${target.id} ${job.data.withReplies ? 'with replies' : 'without replies'} ...`); - this.queueService.createFollowJob([{ from: user, to: { id: target.id }, silent: true, withReplies: job.data.withReplies }]); + await this.queueService.createFollowJob([{ from: user, to: { id: target.id }, silent: true, withReplies: withReplies ?? job.data.withReplies }]); } catch (e) { this.logger.warn(`Error: ${e}`); } diff --git a/packages/backend/src/queue/processors/ImportUserListsProcessorService.ts b/packages/backend/src/queue/processors/ImportUserListsProcessorService.ts index db9255b35d..bf061a1f78 100644 --- a/packages/backend/src/queue/processors/ImportUserListsProcessorService.ts +++ b/packages/backend/src/queue/processors/ImportUserListsProcessorService.ts @@ -70,8 +70,19 @@ export class ImportUserListsProcessorService { linenum++; try { - const listName = line.split(',')[0].trim(); - const { username, host } = Acct.parse(line.split(',')[1].trim()); + const parts = line.split(','); + const listName = parts[0].trim(); + const { username, host } = Acct.parse(parts[1].trim()); + let withReplies = false; + + for (const keyValue of parts.slice(2)) { + const [key, value] = keyValue.split('='); + switch (key) { + case 'withReplies': + withReplies = value === 'true'; + break; + } + } let list = await this.userListsRepository.findOneBy({ userId: user.id, @@ -100,7 +111,9 @@ export class ImportUserListsProcessorService { if (await this.userListMembershipsRepository.findOneBy({ userListId: list!.id, userId: target.id }) != null) continue; - this.userListService.addMember(target, list!, user); + await this.userListService.addMember(target, list, user, { + withReplies: withReplies, + }); } catch (e) { this.logger.warn(`Error in line:${linenum} ${e}`); } diff --git a/packages/backend/src/queue/processors/PostScheduledNoteProcessorService.ts b/packages/backend/src/queue/processors/PostScheduledNoteProcessorService.ts new file mode 100644 index 0000000000..aa034f5038 --- /dev/null +++ b/packages/backend/src/queue/processors/PostScheduledNoteProcessorService.ts @@ -0,0 +1,80 @@ +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { Inject, Injectable } from '@nestjs/common'; +import { DI } from '@/di-symbols.js'; +import type { NoteDraftsRepository } from '@/models/_.js'; +import type Logger from '@/logger.js'; +import { NotificationService } from '@/core/NotificationService.js'; +import { bindThis } from '@/decorators.js'; +import { NoteCreateService } from '@/core/NoteCreateService.js'; +import { QueueLoggerService } from '../QueueLoggerService.js'; +import type * as Bull from 'bullmq'; +import type { PostScheduledNoteJobData } from '../types.js'; + +@Injectable() +export class PostScheduledNoteProcessorService { + private logger: Logger; + + constructor( + @Inject(DI.noteDraftsRepository) + private noteDraftsRepository: NoteDraftsRepository, + + private noteCreateService: NoteCreateService, + private notificationService: NotificationService, + private queueLoggerService: QueueLoggerService, + ) { + this.logger = this.queueLoggerService.logger.createSubLogger('post-scheduled-note'); + } + + @bindThis + public async process(job: Bull.Job): Promise { + const draft = await this.noteDraftsRepository.findOne({ where: { id: job.data.noteDraftId }, relations: ['user'] }); + if (draft == null || draft.user == null || draft.scheduledAt == null || !draft.isActuallyScheduled) { + return; + } + + try { + const note = await this.noteCreateService.fetchAndCreate(draft.user, { + createdAt: new Date(), + fileIds: draft.fileIds, + poll: draft.hasPoll ? { + choices: draft.pollChoices, + multiple: draft.pollMultiple, + expiresAt: draft.pollExpiredAfter ? new Date(Date.now() + draft.pollExpiredAfter) : draft.pollExpiresAt ? new Date(draft.pollExpiresAt) : null, + } : null, + text: draft.text ?? null, + replyId: draft.replyId, + renoteId: draft.renoteId, + cw: draft.cw, + localOnly: draft.localOnly, + reactionAcceptance: draft.reactionAcceptance, + disableRightClick: draft.disableRightClick, + visibility: draft.visibility, + visibleUserIds: draft.visibleUserIds, + channelId: draft.channelId, + event: draft.hasEvent && draft.eventTitle && draft.eventStart ? { + title: draft.eventTitle, + start: new Date(draft.eventStart), + end: draft.eventEnd ? new Date(draft.eventEnd) : null, + metadata: draft.eventMetadata, + } : null, + deleteAt: draft.deleteAt ? new Date(draft.deleteAt) : null, + }); + + // await不要 + this.noteDraftsRepository.remove(draft); + + // await不要 + this.notificationService.createNotification(draft.userId, 'scheduledNotePosted', { + noteId: note.id, + }); + } catch (err) { + this.notificationService.createNotification(draft.userId, 'scheduledNotePostFailed', { + noteDraftId: draft.id, + }); + } + } +} diff --git a/packages/backend/src/queue/processors/ScheduleNotePostProcessorService.ts b/packages/backend/src/queue/processors/ScheduleNotePostProcessorService.ts deleted file mode 100644 index 5b0f428bdd..0000000000 --- a/packages/backend/src/queue/processors/ScheduleNotePostProcessorService.ts +++ /dev/null @@ -1,121 +0,0 @@ -/* - * SPDX-FileCopyrightText: syuilo and misskey-project - * SPDX-License-Identifier: AGPL-3.0-only - */ - -import { Inject, Injectable } from '@nestjs/common'; -import type Logger from '@/logger.js'; -import { bindThis } from '@/decorators.js'; -import { NoteCreateService } from '@/core/NoteCreateService.js'; -import type { ChannelsRepository, DriveFilesRepository, MiDriveFile, NoteScheduleRepository, NotesRepository, UsersRepository } from '@/models/_.js'; -import { DI } from '@/di-symbols.js'; -import { NotificationService } from '@/core/NotificationService.js'; -import { QueueLoggerService } from '../QueueLoggerService.js'; -import type * as Bull from 'bullmq'; -import type { ScheduleNotePostJobData } from '../types.js'; - -@Injectable() -export class ScheduleNotePostProcessorService { - private logger: Logger; - - constructor( - @Inject(DI.noteScheduleRepository) - private noteScheduleRepository: NoteScheduleRepository, - - @Inject(DI.usersRepository) - private usersRepository: UsersRepository, - @Inject(DI.driveFilesRepository) - private driveFilesRepository: DriveFilesRepository, - @Inject(DI.notesRepository) - private notesRepository: NotesRepository, - @Inject(DI.channelsRepository) - private channelsRepository: ChannelsRepository, - - private noteCreateService: NoteCreateService, - private queueLoggerService: QueueLoggerService, - private notificationService: NotificationService, - ) { - this.logger = this.queueLoggerService.logger.createSubLogger('schedule-note-post'); - } - - @bindThis - public async process(job: Bull.Job): Promise { - this.noteScheduleRepository.findOneBy({ id: job.data.scheduleNoteId }).then(async (data) => { - if (!data) { - this.logger.warn(`Schedule note ${job.data.scheduleNoteId} not found`); - } else { - const me = await this.usersRepository.findOneBy({ id: data.userId }); - const note = data.note; - - //idの形式でキューに積んであったのをDBから取り寄せる - const reply = note.reply ? await this.notesRepository.findOneBy({ id: note.reply }) : undefined; - const renote = note.reply ? await this.notesRepository.findOneBy({ id: note.renote }) : undefined; - const channel = note.channel ? await this.channelsRepository.findOneBy({ id: note.channel, isArchived: false }) : undefined; - let files: MiDriveFile[] = []; - const fileIds = note.files ?? null; - if (fileIds != null && fileIds.length > 0 && me) { - files = await this.driveFilesRepository.createQueryBuilder('file') - .where('file.userId = :userId AND file.id IN (:...fileIds)', { - userId: me.id, - fileIds, - }) - .orderBy('array_position(ARRAY[:...fileIds], "id"::text)') - .setParameters({ fileIds }) - .getMany(); - } - if ( - !data.userId || - !me || - (note.reply && !reply) || - (note.renote && !renote) || - (note.channel && !channel) || - (note.files.length !== files.length) - ) { - //キューに積んだときは有った物が消滅してたら予約投稿をキャンセルする - this.logger.warn('cancel schedule note'); - await this.noteScheduleRepository.remove(data); - - if (data.userId && me) { //ユーザーが特定できる場合に失敗を通知 - let errorType = 'unknown'; - if (note.renote && !renote) { - errorType = 'renoteTargetNotFound'; - } - if (note.reply && !reply) { - errorType = 'replyTargetNotFound'; - } - if (note.channel && !channel) { - errorType = 'channelTargetNotFound'; - } - if (note.files.length !== files.length) { - errorType = 'invalidFilesCount'; - } - this.notificationService.createNotification(data.userId, 'scheduleNote', { - errorType, - }); - } - return; - } - await this.noteCreateService.create(me, { - ...note, - createdAt: new Date(note.createdAt), //typeORMのjsonbで何故かstringにされるから戻す - files, - poll: note.poll ? { - choices: note.poll.choices, - multiple: note.poll.multiple, - expiresAt: note.poll.expiresAt ? new Date(note.poll.expiresAt) : null, - } : undefined, - event: note.event ? { - start: new Date(note.event.start), - end: note.event.end ? new Date(note.event.end) : null, - title: note.event.title, - metadata: note.event.metadata, - } : undefined, - reply, - renote, - channel, - }); - await this.noteScheduleRepository.remove(data); - } - }); - } -} diff --git a/packages/backend/src/queue/types.ts b/packages/backend/src/queue/types.ts index eae119a050..5d28c9ccdc 100644 --- a/packages/backend/src/queue/types.ts +++ b/packages/backend/src/queue/types.ts @@ -119,6 +119,10 @@ export type EndedPollNotificationJobData = { noteId: MiNote['id']; }; +export type PostScheduledNoteJobData = { + noteDraftId: string; +}; + export type SystemWebhookDeliverJobData = { type: T; content: SystemWebhookPayload; @@ -147,7 +151,3 @@ export type ThinUser = { export type ScheduledNoteDeleteJobData = { noteId: MiNote['id']; }; - -export type ScheduleNotePostJobData = { - scheduleNoteId: MiNote['id']; -}; diff --git a/packages/backend/src/server/ActivityPubServerService.ts b/packages/backend/src/server/ActivityPubServerService.ts index 3cfd24bdf7..5cf73aadbe 100644 --- a/packages/backend/src/server/ActivityPubServerService.ts +++ b/packages/backend/src/server/ActivityPubServerService.ts @@ -13,7 +13,7 @@ import accepts from 'accepts'; import vary from 'vary'; import secureJson from 'secure-json-parse'; import { DI } from '@/di-symbols.js'; -import type { FollowingsRepository, NotesRepository, EmojisRepository, NoteReactionsRepository, UserProfilesRepository, UserNotePiningsRepository, UsersRepository, FollowRequestsRepository, MiMeta } from '@/models/_.js'; +import type { FollowingsRepository, NotesRepository, EmojisRepository, NoteReactionsRepository, UserProfilesRepository, UserNotePiningsRepository, UsersRepository, FollowRequestsRepository, MiMeta, ChatMessagesRepository } from '@/models/_.js'; import * as url from '@/misc/prelude/url.js'; import type { Config } from '@/config.js'; import { ApRendererService } from '@/core/activitypub/ApRendererService.js'; @@ -71,6 +71,9 @@ export class ActivityPubServerService { @Inject(DI.followRequestsRepository) private followRequestsRepository: FollowRequestsRepository, + @Inject(DI.chatMessagesRepository) + private chatMessagesRepository: ChatMessagesRepository, + private utilityService: UtilityService, private userEntityService: UserEntityService, private apRendererService: ApRendererService, @@ -212,6 +215,10 @@ export class ActivityPubServerService { return; } + if (await this.applyAccessControl(request, reply)) { + return; + } + const userId = request.params.user; const cursor = request.query.cursor; @@ -313,6 +320,10 @@ export class ActivityPubServerService { return; } + if (await this.applyAccessControl(request, reply)) { + return; + } + const userId = request.params.user; const cursor = request.query.cursor; @@ -411,6 +422,10 @@ export class ActivityPubServerService { return; } + if (await this.applyAccessControl(request, reply)) { + return; + } + const userId = request.params.user; const user = await this.usersRepository.findOneBy({ @@ -464,6 +479,10 @@ export class ActivityPubServerService { return; } + if (await this.applyAccessControl(request, reply)) { + return; + } + const userId = request.params.user; const sinceId = request.query.since_id; @@ -512,15 +531,26 @@ export class ActivityPubServerService { useDbFallback: true, ignoreAuthorFromMute: true, excludePureRenotes: false, + withCats: true, noteFilter: (note) => { if (note.visibility !== 'home' && note.visibility !== 'public') return false; if (note.localOnly) return false; return true; }, dbFallback: async (untilId, sinceId, limit) => { - return await this.getUserNotesFromDb(sinceId, untilId, limit, user.id); + return await this.getUserNotesFromDb({ + untilId, + sinceId, + limit, + userId: user.id, + }); }, - }) : await this.getUserNotesFromDb(sinceId ?? null, untilId ?? null, limit, user.id); + }) : await this.getUserNotesFromDb({ + untilId: untilId ?? null, + sinceId: sinceId ?? null, + limit, + userId: user.id, + }); if (sinceId) notes.reverse(); @@ -559,16 +589,21 @@ export class ActivityPubServerService { } @bindThis - private async getUserNotesFromDb(untilId: string | null, sinceId: string | null, limit: number, userId: MiUser['id']) { - return await this.queryService.makePaginationQuery(this.notesRepository.createQueryBuilder('note'), sinceId, untilId) - .andWhere('note.userId = :userId', { userId }) + private async getUserNotesFromDb(ps: { + untilId: string | null, + sinceId: string | null, + limit: number, + userId: MiUser['id'], + }) { + return await this.queryService.makePaginationQuery(this.notesRepository.createQueryBuilder('note'), ps.sinceId, ps.untilId) + .andWhere('note.userId = :userId', { userId: ps.userId }) .andWhere(new Brackets(qb => { qb .where('note.visibility = \'public\'') .orWhere('note.visibility = \'home\''); })) .andWhere('note.localOnly = FALSE') - .limit(limit) + .limit(ps.limit) .getMany(); } @@ -735,6 +770,53 @@ export class ActivityPubServerService { return (this.apRendererService.addContext(await this.packActivity(note))); }); + // chat message + fastify.get<{ Params: { id: string; } }>('/chat/messages/:id', { constraints: { apOrHtml: 'ap' } }, async (request, reply) => { + vary(reply.raw, 'Accept'); + + if (this.meta.federation === 'none') { + reply.code(403); + return; + } + + const message = await this.chatMessagesRepository.findOneBy({ + id: request.params.id, + }); + + if (message == null) { + reply.code(404); + return; + } + + // Get fromUser + const fromUser = await this.usersRepository.findOneBy({ id: message.fromUserId }); + if (fromUser == null || fromUser.host !== null) { + reply.code(404); + return; + } + + // Get toUser(s) + let toUsers: MiUser[] = []; + if (message.toUserId) { + // 1:1 chat + const toUser = await this.usersRepository.findOneBy({ id: message.toUserId }); + if (toUser) toUsers = [toUser]; + } else if (message.toRoomId) { + // Group chat - not yet fully implemented for ActivityPub + reply.code(404); + return; + } + + if (toUsers.length === 0) { + reply.code(404); + return; + } + + reply.header('Cache-Control', 'public, max-age=180'); + this.setResponseType(request, reply); + return this.apRendererService.addContext(await this.apRendererService.renderChatMessage(message, fromUser, toUsers)); + }); + // outbox fastify.get<{ Params: { user: string; }; diff --git a/packages/backend/src/server/NodeinfoServerService.ts b/packages/backend/src/server/NodeinfoServerService.ts index 40493a43c2..099db3551a 100644 --- a/packages/backend/src/server/NodeinfoServerService.ts +++ b/packages/backend/src/server/NodeinfoServerService.ts @@ -47,7 +47,7 @@ export class NodeinfoServerService { @bindThis public createServer(fastify: FastifyInstance, options: FastifyPluginOptions, done: (err?: Error) => void) { - const nodeinfo2 = async (version: number) => { + const nodeinfo2 = async (version: number, userAgent?: string) => { const now = Date.now(); const notesChart = await this.notesChart.getChart('hour', 1, null); @@ -74,14 +74,21 @@ export class NodeinfoServerService { const basePolicies = { ...DEFAULT_POLICIES, ...meta.policies }; + // JoinMisskey APIからのリクエストかどうかを判定 + const isJoinMisskey = userAgent?.includes('JoinMisskey') ?? false; + // eslint-disable-next-line @typescript-eslint/no-explicit-any const document: any = { software: { /* * ソフトウェアの名前を変更すると、一部の独自機能が使用できなくなったり、CherryPickとして認識されないなどの不利益が発生する場合があります。 * フォーク開発者はこの点に注意して修正を行ってください。 + * + * CherryPickはMisskey互換性のため、JoinMisskey APIからのリクエストには"misskey"として応答します。 + * これにより、Misskey Hubのインスタンスリストに掲載されます。 + * それ以外のリクエストには"cherrypick"として応答します。 */ - name: 'cherrypick', + name: isJoinMisskey ? 'misskey' : 'cherrypick', version: this.config.version, basedMisskeyVersion: this.config.basedMisskeyVersion, homepage: nodeinfo_homepage, @@ -131,6 +138,13 @@ export class NodeinfoServerService { enableServiceWorker: meta.enableServiceWorker, proxyAccountName: proxyAccount.username, themeColor: meta.themeColor ?? '#ffbcdc', + features: [ + 'enable_wide_emoji', + 'enable_wide_emoji_reaction', + 'emoji_reaction', + 'quote', + 'emoji_keyword', + ], }, }; if (version >= 21) { @@ -140,10 +154,13 @@ export class NodeinfoServerService { return document; }; - const cache = new MemorySingleCache>>(1000 * 60 * 10); // 10m + // User-Agentによって異なる応答を返すため、キャッシュを使用しない + //const cache = new MemorySingleCache>>(1000 * 60 * 10); // 10m fastify.get(nodeinfo2_1path, async (request, reply) => { - const base = await cache.fetch(() => nodeinfo2(21)); + const userAgent = request.headers['user-agent']; + //const base = await cache.fetch(() => nodeinfo2(21)); + const base = await nodeinfo2(21, userAgent); reply .type( @@ -158,7 +175,9 @@ export class NodeinfoServerService { }); fastify.get(nodeinfo2_0path, async (request, reply) => { - const base = await cache.fetch(() => nodeinfo2(20)); + const userAgent = request.headers['user-agent']; + //const base = await cache.fetch(() => nodeinfo2(20)); + const base = await nodeinfo2(20, userAgent); delete (base as any).software.repository; diff --git a/packages/backend/src/server/ServerService.ts b/packages/backend/src/server/ServerService.ts index 69ccfa669b..b634b689d8 100644 --- a/packages/backend/src/server/ServerService.ts +++ b/packages/backend/src/server/ServerService.ts @@ -75,7 +75,7 @@ export class ServerService implements OnApplicationShutdown { @bindThis public async launch(): Promise { const fastify = Fastify({ - trustProxy: true, + trustProxy: this.config.trustProxy ?? true, logger: false, }); this.#fastify = fastify; @@ -108,7 +108,7 @@ export class ServerService implements OnApplicationShutdown { // this will break lookup that involve copying a URL from a third-party server, like trying to lookup http://charlie.example.com/@alice@alice.com // // this is not required by standard but protect us from peers that did not validate final URL. - if (this.config.disallowExternalApRedirect) { + if (!this.meta.allowExternalApRedirect) { const maybeApLookupRegex = /application\/activity\+json|application\/ld\+json.+activitystreams/i; fastify.addHook('onSend', (request, reply, _, done) => { const location = reply.getHeader('location'); @@ -238,30 +238,6 @@ export class ServerService implements OnApplicationShutdown { } }); - fastify.get<{ Params: { code: string } }>('/verify-email/:code', async (request, reply) => { - const profile = await this.userProfilesRepository.findOneBy({ - emailVerifyCode: request.params.code, - }); - - if (profile != null) { - await this.userProfilesRepository.update({ userId: profile.userId }, { - emailVerified: true, - emailVerifyCode: null, - }); - - this.globalEventService.publishMainStream(profile.userId, 'meUpdated', await this.userEntityService.pack(profile.userId, { id: profile.userId }, { - schema: 'MeDetailed', - includeSecrets: true, - })); - - reply.code(200).send('Verification succeeded! メールアドレスの認証に成功しました。'); - return; - } else { - reply.code(404).send('Verification failed. Please try again. メールアドレスの認証に失敗しました。もう一度お試しください'); - return; - } - }); - fastify.register(this.clientServerService.createServer); this.streamingApiServerService.attach(fastify.server); diff --git a/packages/backend/src/server/api/ApiCallService.ts b/packages/backend/src/server/api/ApiCallService.ts index e8597558da..1ea3f28300 100644 --- a/packages/backend/src/server/api/ApiCallService.ts +++ b/packages/backend/src/server/api/ApiCallService.ts @@ -6,6 +6,7 @@ import { randomUUID } from 'node:crypto'; import * as fs from 'node:fs'; import * as stream from 'node:stream/promises'; +import * as dns from 'node:dns'; import { Inject, Injectable } from '@nestjs/common'; import * as Sentry from '@sentry/node'; import { DI } from '@/di-symbols.js'; @@ -267,7 +268,7 @@ export class ApiCallService implements OnApplicationShutdown { } @bindThis - private logIp(request: FastifyRequest, user: MiLocalUser) { + private async logIp(request: FastifyRequest, user: MiLocalUser) { if (!this.meta.enableIpLogging) return; const ip = request.ip; const ips = this.userIpHistories.get(user.id); @@ -278,11 +279,22 @@ export class ApiCallService implements OnApplicationShutdown { ips.add(ip); } + let hostNames: string[] | undefined = undefined; + + try { + const names = await dns.promises.reverse(ip); + hostNames = names.map(x => + x.length < 512 ? x : x.substring(0, 512)); + } catch (e) { + console.log(e); + } + try { - this.userIpsRepository.createQueryBuilder().insert().values({ + await this.userIpsRepository.createQueryBuilder().insert().values({ createdAt: new Date(), userId: user.id, ip: ip, + dnsNames: hostNames, }).orIgnore(true).execute(); } catch { } @@ -328,19 +340,15 @@ export class ApiCallService implements OnApplicationShutdown { if (factor > 0) { // Rate limit - await this.rateLimiterService.limit(limit as IEndpointMeta['limit'] & { key: NonNullable }, limitActor, factor).catch(err => { - if ('info' in err) { - // errはLimiter.LimiterInfoであることが期待される - throw new ApiError({ - message: 'Rate limit exceeded. Please try again later.', - code: 'RATE_LIMIT_EXCEEDED', - id: 'd5826d14-3982-4d2e-8011-b9e9f02499ef', - httpStatusCode: 429, - }, err.info); - } else { - throw new TypeError('information must be a rate-limiter information.'); - } - }); + const rateLimit = await this.rateLimiterService.limit(limit as IEndpointMeta['limit'] & { key: NonNullable }, limitActor, factor); + if (rateLimit != null) { + throw new ApiError({ + message: 'Rate limit exceeded. Please try again later.', + code: 'RATE_LIMIT_EXCEEDED', + id: 'd5826d14-3982-4d2e-8011-b9e9f02499ef', + httpStatusCode: 429, + }, rateLimit.info); + } } } diff --git a/packages/backend/src/server/api/ApiServerService.ts b/packages/backend/src/server/api/ApiServerService.ts index 32818003ad..57d74ef2b1 100644 --- a/packages/backend/src/server/api/ApiServerService.ts +++ b/packages/backend/src/server/api/ApiServerService.ts @@ -176,6 +176,17 @@ export class ApiServerService { } }); + fastify.all('/clear-browser-cache', (request, reply) => { + if (['GET', 'POST'].includes(request.method)) { + reply.header('Clear-Site-Data', '"cache", "prefetchCache", "prerenderCache", "executionContexts"'); + reply.code(204); + reply.send(); + } else { + reply.code(405); + reply.send(); + } + }); + // Make sure any unknown path under /api returns HTTP 404 Not Found, // because otherwise ClientServerService will return the base client HTML // page with HTTP 200. diff --git a/packages/backend/src/server/api/GetterService.ts b/packages/backend/src/server/api/GetterService.ts index bbfa88bde3..ac7dcb9907 100644 --- a/packages/backend/src/server/api/GetterService.ts +++ b/packages/backend/src/server/api/GetterService.ts @@ -44,8 +44,8 @@ export class GetterService { } @bindThis - public async getNoteWithUser(noteId: MiNote['id']) { - const note = await this.notesRepository.findOne({ where: { id: noteId }, relations: ['user'] }); + public async getNoteWithRelations(noteId: MiNote['id']) { + const note = await this.notesRepository.findOne({ where: { id: noteId }, relations: ['user', 'reply', 'renote', 'reply.user', 'renote.user'] }); if (note == null) { throw new IdentifiableError('9725d0ce-ba28-4dde-95a7-2cbb2c15de24', 'No such note.'); diff --git a/packages/backend/src/server/api/RateLimiterService.ts b/packages/backend/src/server/api/RateLimiterService.ts index 52d73baa0a..a730d8c60e 100644 --- a/packages/backend/src/server/api/RateLimiterService.ts +++ b/packages/backend/src/server/api/RateLimiterService.ts @@ -12,6 +12,14 @@ import { LoggerService } from '@/core/LoggerService.js'; import { bindThis } from '@/decorators.js'; import type { IEndpointMeta } from './endpoints.js'; +type RateLimitInfo = { + code: 'BRIEF_REQUEST_INTERVAL', + info: Limiter.LimiterInfo, +} | { + code: 'RATE_LIMIT_EXCEEDED', + info: Limiter.LimiterInfo, +}; + @Injectable() export class RateLimiterService { private logger: Logger; @@ -31,77 +39,55 @@ export class RateLimiterService { } @bindThis - public limit(limitation: IEndpointMeta['limit'] & { key: NonNullable }, actor: string, factor = 1) { - { - if (this.disabled) { - return Promise.resolve(); - } - - // Short-term limit - const min = new Promise((ok, reject) => { - const minIntervalLimiter = new Limiter({ - id: `${actor}:${limitation.key}:min`, - duration: limitation.minInterval! * factor, - max: 1, - db: this.redisClient, - }); - - minIntervalLimiter.get((err, info) => { - if (err) { - return reject({ code: 'ERR', info }); - } + private checkLimiter(options: Limiter.LimiterOption): Promise { + return new Promise((resolve, reject) => { + new Limiter(options).get((err, info) => { + if (err) { + return reject(err); + } + resolve(info); + }); + }); + } - this.logger.debug(`${actor} ${limitation.key} min remaining: ${info.remaining}`); + @bindThis + public async limit(limitation: IEndpointMeta['limit'] & { key: NonNullable }, actor: string, factor = 1): Promise { + if (this.disabled) { + return null; + } - if (info.remaining === 0) { - return reject({ code: 'BRIEF_REQUEST_INTERVAL', info }); - } else { - if (hasLongTermLimit) { - return max.then(ok, reject); - } else { - return ok(); - } - } - }); + // Short-term limit + if (limitation.minInterval != null) { + const info = await this.checkLimiter({ + id: `${actor}:${limitation.key}:min`, + duration: limitation.minInterval * factor, + max: 1, + db: this.redisClient, }); - // Long term limit - const max = new Promise((ok, reject) => { - const limiter = new Limiter({ - id: `${actor}:${limitation.key}`, - duration: limitation.duration! * factor, - max: limitation.max! / factor, - db: this.redisClient, - }); - - limiter.get((err, info) => { - if (err) { - return reject({ code: 'ERR', info }); - } + this.logger.debug(`${actor} ${limitation.key} min remaining: ${info.remaining}`); - this.logger.debug(`${actor} ${limitation.key} max remaining: ${info.remaining}`); + if (info.remaining === 0) { + return { code: 'BRIEF_REQUEST_INTERVAL', info }; + } + } - if (info.remaining === 0) { - return reject({ code: 'RATE_LIMIT_EXCEEDED', info }); - } else { - return ok(); - } - }); + // Long term limit + if (limitation.duration != null && limitation.max != null) { + const info = await this.checkLimiter({ + id: `${actor}:${limitation.key}`, + duration: limitation.duration, + max: limitation.max / factor, + db: this.redisClient, }); - const hasShortTermLimit = typeof limitation.minInterval === 'number'; - - const hasLongTermLimit = - typeof limitation.duration === 'number' && - typeof limitation.max === 'number'; + this.logger.debug(`${actor} ${limitation.key} max remaining: ${info.remaining}`); - if (hasShortTermLimit) { - return min; - } else if (hasLongTermLimit) { - return max; - } else { - return Promise.resolve(); + if (info.remaining === 0) { + return { code: 'RATE_LIMIT_EXCEEDED', info }; } } + + return null; } } diff --git a/packages/backend/src/server/api/SigninApiService.ts b/packages/backend/src/server/api/SigninApiService.ts index 33bd0026aa..f39ea19e75 100644 --- a/packages/backend/src/server/api/SigninApiService.ts +++ b/packages/backend/src/server/api/SigninApiService.ts @@ -93,10 +93,9 @@ export class SigninApiService { return { error }; } - try { // not more than 1 attempt per second and not more than 10 attempts per hour - await this.rateLimiterService.limit({ key: 'signin', duration: 60 * 60 * 1000, max: 10, minInterval: 1000 }, getIpHash(request.ip)); - } catch (err) { + const rateLimit = await this.rateLimiterService.limit({ key: 'signin', duration: 60 * 60 * 1000, max: 10, minInterval: 1000 }, getIpHash(request.ip)); + if (rateLimit != null) { reply.code(429); return { error: { diff --git a/packages/backend/src/server/api/SignupApiService.ts b/packages/backend/src/server/api/SignupApiService.ts index 03bd005ae9..64f7236a1c 100644 --- a/packages/backend/src/server/api/SignupApiService.ts +++ b/packages/backend/src/server/api/SignupApiService.ts @@ -130,7 +130,8 @@ export class SignupApiService { let ticket: MiRegistrationTicket | null = null; - if (this.meta.disableRegistration) { + // テスト時はこの機構は障害となるため無効にする + if (process.env.NODE_ENV !== 'test' && this.meta.disableRegistration) { if (invitationCode == null || typeof invitationCode !== 'string') { reply.code(400); return; diff --git a/packages/backend/src/server/api/endpoint-list.ts b/packages/backend/src/server/api/endpoint-list.ts index 354aabf0a0..c42452aadb 100644 --- a/packages/backend/src/server/api/endpoint-list.ts +++ b/packages/backend/src/server/api/endpoint-list.ts @@ -46,7 +46,6 @@ export * as 'admin/drive/cleanup' from './endpoints/admin/drive/cleanup.js'; export * as 'admin/drive/files' from './endpoints/admin/drive/files.js'; export * as 'admin/drive/show-file' from './endpoints/admin/drive/show-file.js'; export * as 'admin/emoji/add' from './endpoints/admin/emoji/add.js'; -export * as 'admin/emoji/adds' from './endpoints/admin/emoji/adds.js'; export * as 'admin/emoji/add-aliases-bulk' from './endpoints/admin/emoji/add-aliases-bulk.js'; export * as 'admin/emoji/copy' from './endpoints/admin/emoji/copy.js'; export * as 'admin/emoji/delete' from './endpoints/admin/emoji/delete.js'; @@ -60,6 +59,8 @@ export * as 'admin/emoji/set-category-bulk' from './endpoints/admin/emoji/set-ca export * as 'admin/emoji/set-license-bulk' from './endpoints/admin/emoji/set-license-bulk.js'; export * as 'admin/emoji/steal' from './endpoints/admin/emoji/steal.js'; export * as 'admin/emoji/update' from './endpoints/admin/emoji/update.js'; +export * as 'i/auto-delete-settings' from './endpoints/i/auto-delete-settings.js'; +export * as 'i/update-auto-delete-settings' from './endpoints/i/update-auto-delete-settings.js'; export * as 'admin/federation/delete-all-files' from './endpoints/admin/federation/delete-all-files.js'; export * as 'admin/federation/refresh-remote-instance-metadata' from './endpoints/admin/federation/refresh-remote-instance-metadata.js'; export * as 'admin/federation/remove-all-following' from './endpoints/admin/federation/remove-all-following.js'; @@ -80,6 +81,7 @@ export * as 'admin/queue/inbox-delayed' from './endpoints/admin/queue/inbox-dela export * as 'admin/queue/retry-job' from './endpoints/admin/queue/retry-job.js'; export * as 'admin/queue/remove-job' from './endpoints/admin/queue/remove-job.js'; export * as 'admin/queue/show-job' from './endpoints/admin/queue/show-job.js'; +export * as 'admin/queue/show-job-logs' from './endpoints/admin/queue/show-job-logs.js'; export * as 'admin/queue/promote-jobs' from './endpoints/admin/queue/promote-jobs.js'; export * as 'admin/queue/jobs' from './endpoints/admin/queue/jobs.js'; export * as 'admin/queue/stats' from './endpoints/admin/queue/stats.js'; @@ -179,6 +181,7 @@ export * as 'clips/update' from './endpoints/clips/update.js'; export * as 'drive' from './endpoints/drive.js'; export * as 'drive/files' from './endpoints/drive/files.js'; export * as 'drive/files/attached-notes' from './endpoints/drive/files/attached-notes.js'; +export * as 'drive/files/attached-chat-messages' from './endpoints/drive/files/attached-chat-messages.js'; export * as 'drive/files/check-existence' from './endpoints/drive/files/check-existence.js'; export * as 'drive/files/create' from './endpoints/drive/files/create.js'; export * as 'drive/files/delete' from './endpoints/drive/files/delete.js'; @@ -186,6 +189,7 @@ export * as 'drive/files/find' from './endpoints/drive/files/find.js'; export * as 'drive/files/find-by-hash' from './endpoints/drive/files/find-by-hash.js'; export * as 'drive/files/show' from './endpoints/drive/files/show.js'; export * as 'drive/files/update' from './endpoints/drive/files/update.js'; +export * as 'drive/files/move-bulk' from './endpoints/drive/files/move-bulk.js'; export * as 'drive/files/upload-from-url' from './endpoints/drive/files/upload-from-url.js'; export * as 'drive/folders' from './endpoints/drive/folders.js'; export * as 'drive/folders/create' from './endpoints/drive/folders/create.js'; @@ -203,6 +207,7 @@ export * as 'export-custom-emojis' from './endpoints/export-custom-emojis.js'; export * as 'federation/followers' from './endpoints/federation/followers.js'; export * as 'federation/following' from './endpoints/federation/following.js'; export * as 'federation/instances' from './endpoints/federation/instances.js'; +export * as 'federation/remote-software' from './endpoints/federation/remote-software.js'; export * as 'federation/show-instance' from './endpoints/federation/show-instance.js'; export * as 'federation/stats' from './endpoints/federation/stats.js'; export * as 'federation/update-remote-user' from './endpoints/federation/update-remote-user.js'; @@ -219,6 +224,7 @@ export * as 'flash/my-likes' from './endpoints/flash/my-likes.js'; export * as 'flash/show' from './endpoints/flash/show.js'; export * as 'flash/unlike' from './endpoints/flash/unlike.js'; export * as 'flash/update' from './endpoints/flash/update.js'; +export * as 'flash/search' from './endpoints/flash/search.js'; export * as 'following/create' from './endpoints/following/create.js'; export * as 'following/delete' from './endpoints/following/delete.js'; export * as 'following/invalidate' from './endpoints/following/invalidate.js'; @@ -321,15 +327,17 @@ export * as 'notes/clips' from './endpoints/notes/clips.js'; export * as 'notes/conversation' from './endpoints/notes/conversation.js'; export * as 'notes/create' from './endpoints/notes/create.js'; export * as 'notes/delete' from './endpoints/notes/delete.js'; -export * as 'notes/drafts' from './endpoints/notes/drafts/list.js'; +export * as 'notes/drafts/list' from './endpoints/notes/drafts/list.js'; export * as 'notes/drafts/create' from './endpoints/notes/drafts/create.js'; export * as 'notes/drafts/delete' from './endpoints/notes/drafts/delete.js'; export * as 'notes/drafts/update' from './endpoints/notes/drafts/update.js'; +export * as 'notes/drafts/count' from './endpoints/notes/drafts/count.js'; export * as 'notes/events/search' from './endpoints/notes/events/search.js'; export * as 'notes/favorites/create' from './endpoints/notes/favorites/create.js'; export * as 'notes/favorites/delete' from './endpoints/notes/favorites/delete.js'; export * as 'notes/featured' from './endpoints/notes/featured.js'; export * as 'notes/global-timeline' from './endpoints/notes/global-timeline.js'; +export * as 'notes/history' from './endpoints/notes/history.js'; export * as 'notes/hybrid-timeline' from './endpoints/notes/hybrid-timeline.js'; export * as 'notes/local-timeline' from './endpoints/notes/local-timeline.js'; export * as 'notes/mentions' from './endpoints/notes/mentions.js'; @@ -341,12 +349,10 @@ export * as 'notes/reactions/create' from './endpoints/notes/reactions/create.js export * as 'notes/reactions/delete' from './endpoints/notes/reactions/delete.js'; export * as 'notes/renotes' from './endpoints/notes/renotes.js'; export * as 'notes/replies' from './endpoints/notes/replies.js'; -export * as 'notes/schedule/create' from './endpoints/notes/schedule/create.js'; -export * as 'notes/schedule/delete' from './endpoints/notes/schedule/delete.js'; -export * as 'notes/schedule/list' from './endpoints/notes/schedule/list.js'; export * as 'notes/search' from './endpoints/notes/search.js'; export * as 'notes/search-by-tag' from './endpoints/notes/search-by-tag.js'; export * as 'notes/show' from './endpoints/notes/show.js'; +export * as 'notes/show-partial-bulk' from './endpoints/notes/show-partial-bulk.js'; export * as 'notes/state' from './endpoints/notes/state.js'; export * as 'notes/thread-muting/create' from './endpoints/notes/thread-muting/create.js'; export * as 'notes/thread-muting/delete' from './endpoints/notes/thread-muting/delete.js'; @@ -405,6 +411,7 @@ export * as 'users/flashs' from './endpoints/users/flashs.js'; export * as 'users/followers' from './endpoints/users/followers.js'; export * as 'users/following' from './endpoints/users/following.js'; export * as 'users/friends-following' from './endpoints/users/friends-following.js'; +export * as 'users/friends-summary' from './endpoints/users/friends-summary.js'; export * as 'users/gallery/posts' from './endpoints/users/gallery/posts.js'; export * as 'users/get-frequently-replied-users' from './endpoints/users/get-frequently-replied-users.js'; export * as 'users/groups/create' from './endpoints/users/groups/create.js'; @@ -442,6 +449,7 @@ export * as 'users/search-by-username-and-host' from './endpoints/users/search-b export * as 'users/show' from './endpoints/users/show.js'; export * as 'users/stats' from './endpoints/users/stats.js'; export * as 'users/update-memo' from './endpoints/users/update-memo.js'; +export * as 'verify-email' from './endpoints/verify-email.js'; export * as 'chat/messages/create-to-user' from './endpoints/chat/messages/create-to-user.js'; export * as 'chat/messages/create-to-room' from './endpoints/chat/messages/create-to-room.js'; export * as 'chat/messages/delete' from './endpoints/chat/messages/delete.js'; @@ -462,10 +470,13 @@ export * as 'chat/rooms/joining' from './endpoints/chat/rooms/joining.js'; export * as 'chat/rooms/update' from './endpoints/chat/rooms/update.js'; export * as 'chat/rooms/members' from './endpoints/chat/rooms/members.js'; export * as 'chat/rooms/invitations/create' from './endpoints/chat/rooms/invitations/create.js'; +export * as 'chat/rooms/invitations/cancel' from './endpoints/chat/rooms/invitations/cancel.js'; export * as 'chat/rooms/invitations/ignore' from './endpoints/chat/rooms/invitations/ignore.js'; export * as 'chat/rooms/invitations/inbox' from './endpoints/chat/rooms/invitations/inbox.js'; export * as 'chat/rooms/invitations/outbox' from './endpoints/chat/rooms/invitations/outbox.js'; +export * as 'chat/rooms/invitations/reject' from './endpoints/chat/rooms/invitations/reject.js'; export * as 'chat/history' from './endpoints/chat/history.js'; +export * as 'chat/read-all' from './endpoints/chat/read-all.js'; export * as 'users/translate' from './endpoints/users/translate.js'; export * as 'v2/admin/emoji/list' from './endpoints/v2/admin/emoji/list.js'; export * as 'i/followers-servers' from './endpoints/i/followers-servers.js'; diff --git a/packages/backend/src/server/api/endpoints/admin/abuse-user-reports.ts b/packages/backend/src/server/api/endpoints/admin/abuse-user-reports.ts index 0dbfaae054..ff7133e73a 100644 --- a/packages/backend/src/server/api/endpoints/admin/abuse-user-reports.ts +++ b/packages/backend/src/server/api/endpoints/admin/abuse-user-reports.ts @@ -98,6 +98,8 @@ export const paramDef = { limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 }, sinceId: { type: 'string', format: 'misskey:id' }, untilId: { type: 'string', format: 'misskey:id' }, + sinceDate: { type: 'integer' }, + untilDate: { type: 'integer' }, state: { type: 'string', nullable: true, default: null }, reporterOrigin: { type: 'string', enum: ['combined', 'local', 'remote'], default: 'combined' }, targetUserOrigin: { type: 'string', enum: ['combined', 'local', 'remote'], default: 'combined' }, @@ -115,7 +117,7 @@ export default class extends Endpoint { // eslint- private queryService: QueryService, ) { super(meta, paramDef, async (ps, me) => { - const query = this.queryService.makePaginationQuery(this.abuseUserReportsRepository.createQueryBuilder('report'), ps.sinceId, ps.untilId); + const query = this.queryService.makePaginationQuery(this.abuseUserReportsRepository.createQueryBuilder('report'), ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate); switch (ps.state) { case 'resolved': query.andWhere('report.resolved = TRUE'); break; diff --git a/packages/backend/src/server/api/endpoints/admin/accounts/create.ts b/packages/backend/src/server/api/endpoints/admin/accounts/create.ts index 06047b58a6..8fe8f027c5 100644 --- a/packages/backend/src/server/api/endpoints/admin/accounts/create.ts +++ b/packages/backend/src/server/api/endpoints/admin/accounts/create.ts @@ -34,13 +34,22 @@ export const meta = { res: { type: 'object', optional: false, nullable: false, - ref: 'MeDetailed', - properties: { - token: { - type: 'string', + allOf: [ + { + type: 'object', + ref: 'MeDetailed', + }, + { + type: 'object', optional: false, nullable: false, + properties: { + token: { + type: 'string', + optional: false, nullable: false, + }, + }, }, - }, + ], }, } as const; diff --git a/packages/backend/src/server/api/endpoints/admin/ad/create.ts b/packages/backend/src/server/api/endpoints/admin/ad/create.ts index 955154f4fb..01697ae185 100644 --- a/packages/backend/src/server/api/endpoints/admin/ad/create.ts +++ b/packages/backend/src/server/api/endpoints/admin/ad/create.ts @@ -36,6 +36,7 @@ export const paramDef = { startsAt: { type: 'integer' }, imageUrl: { type: 'string', minLength: 1 }, dayOfWeek: { type: 'integer' }, + isSensitive: { type: 'boolean' }, }, required: ['url', 'memo', 'place', 'priority', 'ratio', 'expiresAt', 'startsAt', 'imageUrl', 'dayOfWeek'], } as const; @@ -55,6 +56,7 @@ export default class extends Endpoint { // eslint- expiresAt: new Date(ps.expiresAt), startsAt: new Date(ps.startsAt), dayOfWeek: ps.dayOfWeek, + isSensitive: ps.isSensitive, url: ps.url, imageUrl: ps.imageUrl, priority: ps.priority, @@ -73,6 +75,7 @@ export default class extends Endpoint { // eslint- expiresAt: ad.expiresAt.toISOString(), startsAt: ad.startsAt.toISOString(), dayOfWeek: ad.dayOfWeek, + isSensitive: ad.isSensitive, url: ad.url, imageUrl: ad.imageUrl, priority: ad.priority, diff --git a/packages/backend/src/server/api/endpoints/admin/ad/list.ts b/packages/backend/src/server/api/endpoints/admin/ad/list.ts index 6406709cda..f67cad5bd2 100644 --- a/packages/backend/src/server/api/endpoints/admin/ad/list.ts +++ b/packages/backend/src/server/api/endpoints/admin/ad/list.ts @@ -34,6 +34,8 @@ export const paramDef = { limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 }, sinceId: { type: 'string', format: 'misskey:id' }, untilId: { type: 'string', format: 'misskey:id' }, + sinceDate: { type: 'integer' }, + untilDate: { type: 'integer' }, publishing: { type: 'boolean', default: null, nullable: true }, }, required: [], @@ -48,7 +50,7 @@ export default class extends Endpoint { // eslint- private queryService: QueryService, ) { super(meta, paramDef, async (ps, me) => { - const query = this.queryService.makePaginationQuery(this.adsRepository.createQueryBuilder('ad'), ps.sinceId, ps.untilId); + const query = this.queryService.makePaginationQuery(this.adsRepository.createQueryBuilder('ad'), ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate); if (ps.publishing === true) { query.andWhere('ad.expiresAt > :now', { now: new Date() }).andWhere('ad.startsAt <= :now', { now: new Date() }); } else if (ps.publishing === false) { @@ -61,6 +63,7 @@ export default class extends Endpoint { // eslint- expiresAt: ad.expiresAt.toISOString(), startsAt: ad.startsAt.toISOString(), dayOfWeek: ad.dayOfWeek, + isSensitive: ad.isSensitive, url: ad.url, imageUrl: ad.imageUrl, memo: ad.memo, diff --git a/packages/backend/src/server/api/endpoints/admin/ad/update.ts b/packages/backend/src/server/api/endpoints/admin/ad/update.ts index 4e3d731aca..a3d9aaddc6 100644 --- a/packages/backend/src/server/api/endpoints/admin/ad/update.ts +++ b/packages/backend/src/server/api/endpoints/admin/ad/update.ts @@ -39,6 +39,7 @@ export const paramDef = { expiresAt: { type: 'integer' }, startsAt: { type: 'integer' }, dayOfWeek: { type: 'integer' }, + isSensitive: { type: 'boolean' }, }, required: ['id'], } as const; @@ -66,6 +67,7 @@ export default class extends Endpoint { // eslint- expiresAt: ps.expiresAt ? new Date(ps.expiresAt) : undefined, startsAt: ps.startsAt ? new Date(ps.startsAt) : undefined, dayOfWeek: ps.dayOfWeek, + isSensitive: ps.isSensitive, }); const updatedAd = await this.adsRepository.findOneByOrFail({ id: ad.id }); diff --git a/packages/backend/src/server/api/endpoints/admin/announcements/list.ts b/packages/backend/src/server/api/endpoints/admin/announcements/list.ts index 7596bf44e3..804bd5d9b9 100644 --- a/packages/backend/src/server/api/endpoints/admin/announcements/list.ts +++ b/packages/backend/src/server/api/endpoints/admin/announcements/list.ts @@ -49,6 +49,34 @@ export const meta = { type: 'string', optional: false, nullable: false, }, + icon: { + type: 'string', + optional: false, nullable: true, + }, + display: { + type: 'string', + optional: false, nullable: false, + }, + isActive: { + type: 'boolean', + optional: false, nullable: false, + }, + forExistingUsers: { + type: 'boolean', + optional: false, nullable: false, + }, + silence: { + type: 'boolean', + optional: false, nullable: false, + }, + needConfirmationToRead: { + type: 'boolean', + optional: false, nullable: false, + }, + userId: { + type: 'string', + optional: false, nullable: true, + }, imageUrl: { type: 'string', optional: false, nullable: true, @@ -68,6 +96,8 @@ export const paramDef = { limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 }, sinceId: { type: 'string', format: 'misskey:id' }, untilId: { type: 'string', format: 'misskey:id' }, + sinceDate: { type: 'integer' }, + untilDate: { type: 'integer' }, userId: { type: 'string', format: 'misskey:id', nullable: true }, status: { type: 'string', enum: ['all', 'active', 'archived'], default: 'active' }, }, @@ -87,7 +117,7 @@ export default class extends Endpoint { // eslint- private idService: IdService, ) { super(meta, paramDef, async (ps, me) => { - const query = this.queryService.makePaginationQuery(this.announcementsRepository.createQueryBuilder('announcement'), ps.sinceId, ps.untilId); + const query = this.queryService.makePaginationQuery(this.announcementsRepository.createQueryBuilder('announcement'), ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate); if (ps.status === 'archived') { query.andWhere('announcement.isActive = false'); diff --git a/packages/backend/src/server/api/endpoints/admin/avatar-decorations/list.ts b/packages/backend/src/server/api/endpoints/admin/avatar-decorations/list.ts index d4d9a7235b..765bfd6766 100644 --- a/packages/backend/src/server/api/endpoints/admin/avatar-decorations/list.ts +++ b/packages/backend/src/server/api/endpoints/admin/avatar-decorations/list.ts @@ -71,6 +71,8 @@ export const paramDef = { limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 }, sinceId: { type: 'string', format: 'misskey:id' }, untilId: { type: 'string', format: 'misskey:id' }, + sinceDate: { type: 'integer' }, + untilDate: { type: 'integer' }, userId: { type: 'string', format: 'misskey:id', nullable: true }, }, required: [], diff --git a/packages/backend/src/server/api/endpoints/admin/drive/files.ts b/packages/backend/src/server/api/endpoints/admin/drive/files.ts index 915d777e77..59b02482a2 100644 --- a/packages/backend/src/server/api/endpoints/admin/drive/files.ts +++ b/packages/backend/src/server/api/endpoints/admin/drive/files.ts @@ -34,6 +34,8 @@ export const paramDef = { limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 }, sinceId: { type: 'string', format: 'misskey:id' }, untilId: { type: 'string', format: 'misskey:id' }, + sinceDate: { type: 'integer' }, + untilDate: { type: 'integer' }, userId: { type: 'string', format: 'misskey:id', nullable: true }, type: { type: 'string', nullable: true, pattern: /^[a-zA-Z0-9\/\-*]+$/.toString().slice(1, -1) }, origin: { type: 'string', enum: ['combined', 'local', 'remote'], default: 'local' }, @@ -57,7 +59,7 @@ export default class extends Endpoint { // eslint- private queryService: QueryService, ) { super(meta, paramDef, async (ps, me) => { - const query = this.queryService.makePaginationQuery(this.driveFilesRepository.createQueryBuilder('file'), ps.sinceId, ps.untilId); + const query = this.queryService.makePaginationQuery(this.driveFilesRepository.createQueryBuilder('file'), ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate); if (ps.userId) { query.andWhere('file.userId = :userId', { userId: ps.userId }); diff --git a/packages/backend/src/server/api/endpoints/admin/drive/show-file.ts b/packages/backend/src/server/api/endpoints/admin/drive/show-file.ts index a7136d8c8c..e7a70d0762 100644 --- a/packages/backend/src/server/api/endpoints/admin/drive/show-file.ts +++ b/packages/backend/src/server/api/endpoints/admin/drive/show-file.ts @@ -157,19 +157,42 @@ export const meta = { type: 'boolean', optional: false, nullable: false, }, + maybeSensitive: { + type: 'boolean', + optional: false, nullable: false, + }, + maybePorn: { + type: 'boolean', + optional: false, nullable: false, + }, + requestIp: { + type: 'string', + optional: false, nullable: true, + }, + requestHeaders: { + type: 'object', + optional: false, nullable: true, + }, }, }, } as const; export const paramDef = { - type: 'object', - properties: { - fileId: { type: 'string', format: 'misskey:id' }, - url: { type: 'string' }, - }, anyOf: [ - { required: ['fileId'] }, - { required: ['url'] }, + { + type: 'object', + properties: { + fileId: { type: 'string', format: 'misskey:id' }, + }, + required: ['fileId'], + }, + { + type: 'object', + properties: { + url: { type: 'string' }, + }, + required: ['url'], + }, ], } as const; @@ -186,15 +209,11 @@ export default class extends Endpoint { // eslint- private idService: IdService, ) { super(meta, paramDef, async (ps, me) => { - const file = ps.fileId ? await this.driveFilesRepository.findOneBy({ id: ps.fileId }) : await this.driveFilesRepository.findOne({ - where: [{ - url: ps.url, - }, { - thumbnailUrl: ps.url, - }, { - webpublicUrl: ps.url, - }], - }); + const file = await this.driveFilesRepository.findOneBy( + 'fileId' in ps + ? { id: ps.fileId } + : [{ url: ps.url }, { thumbnailUrl: ps.url }, { webpublicUrl: ps.url }], + ); if (file == null) { throw new ApiError(meta.errors.noSuchFile); diff --git a/packages/backend/src/server/api/endpoints/admin/emoji/adds.ts b/packages/backend/src/server/api/endpoints/admin/emoji/adds.ts deleted file mode 100644 index 8c458c6b72..0000000000 --- a/packages/backend/src/server/api/endpoints/admin/emoji/adds.ts +++ /dev/null @@ -1,113 +0,0 @@ -/* - * SPDX-FileCopyrightText: syuilo and misskey-project & noridev and cherrypick-project - * SPDX-License-Identifier: AGPL-3.0-only - */ - -import { Inject, Injectable } from '@nestjs/common'; -import { Endpoint } from '@/server/api/endpoint-base.js'; -import type { DriveFilesRepository } from '@/models/_.js'; -import { DI } from '@/di-symbols.js'; -import { CustomEmojiService } from '@/core/CustomEmojiService.js'; -import { EmojiEntityService } from '@/core/entities/EmojiEntityService.js'; -import { secureRndstr } from '@/misc/secure-rndstr.js'; -import { FILE_TYPE_IMAGE } from '@/const.js'; -import { ApiError } from '../../../error.js'; - -export const meta = { - tags: ['admin'], - - requireCredential: true, - requiredRolePolicy: 'canManageCustomEmojis', - kind: 'write:admin:emoji', - - errors: { - noSuchFile: { - message: 'No such file.', - code: 'NO_SUCH_FILE', - id: 'fc46b5a4-6b92-4c33-ac66-b806659bb5cf', - }, - unsupportedFileType: { - message: 'Unsupported file type.', - code: 'UNSUPPORTED_FILE_TYPE', - id: 'f7599d96-8750-af68-1633-9575d625c1a7', - }, - duplicateName: { - message: 'Duplicate name.', - code: 'DUPLICATE_NAME', - id: 'f7a3462c-4e6e-4069-8421-b9bd4f4c3975', - }, - }, - - res: { - type: 'object', - ref: 'EmojiDetailed', - }, -} as const; - -export const paramDef = { - type: 'object', - properties: { - name: { type: 'string', pattern: '^[a-zA-Z0-9_]+$' }, - fileId: { type: 'string', format: 'misskey:id' }, - category: { - type: 'string', - nullable: true, - description: 'Use `null` to reset the category.', - }, - aliases: { - type: 'array', - items: { - type: 'string', - }, - }, - license: { type: 'string', nullable: true }, - isSensitive: { type: 'boolean' }, - localOnly: { type: 'boolean' }, - roleIdsThatCanBeUsedThisEmojiAsReaction: { - type: 'array', - items: { - type: 'string', - }, - }, - }, - required: ['fileId'], -} as const; - -// TODO: ロジックをサービスに切り出す - -@Injectable() -export default class extends Endpoint { // eslint-disable-line import/no-default-export - constructor( - @Inject(DI.driveFilesRepository) - private driveFilesRepository: DriveFilesRepository, - private customEmojiService: CustomEmojiService, - private emojiEntityService: EmojiEntityService, - ) { - super(meta, paramDef, async (ps, me) => { - const driveFile = await this.driveFilesRepository.findOneBy({ id: ps.fileId }); - if (driveFile == null) throw new ApiError(meta.errors.noSuchFile); - if (!FILE_TYPE_IMAGE.includes(driveFile.type)) throw new ApiError(meta.errors.unsupportedFileType); - - const name = driveFile.name.split('.')[0].match(/^[a-z0-9_]+$/) ? driveFile.name.split('.')[0] : `_${secureRndstr(8)}_`; - - const isDuplicate = await this.customEmojiService.checkDuplicate(name); - if (isDuplicate) throw new ApiError(meta.errors.duplicateName); - - const emoji = await this.customEmojiService.add({ - originalUrl: driveFile.url, - publicUrl: driveFile.webpublicUrl ?? driveFile.url, - fileType: driveFile.webpublicType ?? driveFile.type, - name, - category: ps.category ?? null, - aliases: ps.aliases ?? [], - host: null, - license: ps.license ?? null, - isSensitive: ps.isSensitive ?? false, - localOnly: ps.localOnly ?? false, - roleIdsThatCanBeUsedThisEmojiAsReaction: ps.roleIdsThatCanBeUsedThisEmojiAsReaction ?? [], - }, me); - - return this.emojiEntityService.packDetailed(emoji); - }); - } -} diff --git a/packages/backend/src/server/api/endpoints/admin/emoji/list-remote.ts b/packages/backend/src/server/api/endpoints/admin/emoji/list-remote.ts index b44007962d..660aa55bf8 100644 --- a/packages/backend/src/server/api/endpoints/admin/emoji/list-remote.ts +++ b/packages/backend/src/server/api/endpoints/admin/emoji/list-remote.ts @@ -74,6 +74,8 @@ export const paramDef = { limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 }, sinceId: { type: 'string', format: 'misskey:id' }, untilId: { type: 'string', format: 'misskey:id' }, + sinceDate: { type: 'integer' }, + untilDate: { type: 'integer' }, }, required: [], } as const; @@ -89,7 +91,7 @@ export default class extends Endpoint { // eslint- private emojiEntityService: EmojiEntityService, ) { super(meta, paramDef, async (ps, me) => { - const q = this.queryService.makePaginationQuery(this.emojisRepository.createQueryBuilder('emoji'), ps.sinceId, ps.untilId); + const q = this.queryService.makePaginationQuery(this.emojisRepository.createQueryBuilder('emoji'), ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate); if (ps.host == null) { q.andWhere('emoji.host IS NOT NULL'); diff --git a/packages/backend/src/server/api/endpoints/admin/emoji/list.ts b/packages/backend/src/server/api/endpoints/admin/emoji/list.ts index 4342e178cc..34d200455e 100644 --- a/packages/backend/src/server/api/endpoints/admin/emoji/list.ts +++ b/packages/backend/src/server/api/endpoints/admin/emoji/list.ts @@ -68,6 +68,8 @@ export const paramDef = { limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 }, sinceId: { type: 'string', format: 'misskey:id' }, untilId: { type: 'string', format: 'misskey:id' }, + sinceDate: { type: 'integer' }, + untilDate: { type: 'integer' }, }, required: [], } as const; @@ -82,7 +84,7 @@ export default class extends Endpoint { // eslint- private queryService: QueryService, ) { super(meta, paramDef, async (ps, me) => { - const q = this.queryService.makePaginationQuery(this.emojisRepository.createQueryBuilder('emoji'), ps.sinceId, ps.untilId) + const q = this.queryService.makePaginationQuery(this.emojisRepository.createQueryBuilder('emoji'), ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate) .andWhere('emoji.host IS NULL'); let emojis: MiEmoji[]; diff --git a/packages/backend/src/server/api/endpoints/admin/emoji/update.ts b/packages/backend/src/server/api/endpoints/admin/emoji/update.ts index 6834a6d213..7bde10af46 100644 --- a/packages/backend/src/server/api/endpoints/admin/emoji/update.ts +++ b/packages/backend/src/server/api/endpoints/admin/emoji/update.ts @@ -37,29 +37,45 @@ export const meta = { } as const; export const paramDef = { - type: 'object', - properties: { - id: { type: 'string', format: 'misskey:id' }, - name: { type: 'string', pattern: '^[a-zA-Z0-9_]+$' }, - fileId: { type: 'string', format: 'misskey:id' }, - category: { - type: 'string', - nullable: true, - description: 'Use `null` to reset the category.', + allOf: [ + { + anyOf: [ + { + type: 'object', + properties: { + id: { type: 'string', format: 'misskey:id' }, + }, + required: ['id'], + }, + { + type: 'object', + properties: { + name: { type: 'string', pattern: '^[a-zA-Z0-9_]+$' }, + }, + required: ['name'], + }, + ], + }, + { + type: 'object', + properties: { + fileId: { type: 'string', format: 'misskey:id' }, + category: { + type: 'string', + nullable: true, + description: 'Use `null` to reset the category.', + }, + aliases: { type: 'array', items: { + type: 'string', + } }, + license: { type: 'string', nullable: true }, + isSensitive: { type: 'boolean' }, + localOnly: { type: 'boolean' }, + roleIdsThatCanBeUsedThisEmojiAsReaction: { type: 'array', items: { + type: 'string', + } }, + }, }, - aliases: { type: 'array', items: { - type: 'string', - } }, - license: { type: 'string', nullable: true }, - isSensitive: { type: 'boolean' }, - localOnly: { type: 'boolean' }, - roleIdsThatCanBeUsedThisEmojiAsReaction: { type: 'array', items: { - type: 'string', - } }, - }, - anyOf: [ - { required: ['id'] }, - { required: ['name'] }, ], } as const; @@ -78,10 +94,9 @@ export default class extends Endpoint { // eslint- if (driveFile == null) throw new ApiError(meta.errors.noSuchFile); } - // JSON schemeのanyOfの型変換がうまくいっていないらしい - const required = { id: ps.id, name: ps.name } as - | { id: MiEmoji['id']; name?: string } - | { id?: MiEmoji['id']; name: string }; + const required = 'id' in ps + ? { id: ps.id, name: 'name' in ps ? ps.name as string : undefined } + : { name: ps.name }; const error = await this.customEmojiService.update({ ...required, diff --git a/packages/backend/src/server/api/endpoints/admin/get-user-ips.ts b/packages/backend/src/server/api/endpoints/admin/get-user-ips.ts index b7781b8c99..2f815c0274 100644 --- a/packages/backend/src/server/api/endpoints/admin/get-user-ips.ts +++ b/packages/backend/src/server/api/endpoints/admin/get-user-ips.ts @@ -25,6 +25,7 @@ export const meta = { nullable: false, properties: { ip: { type: 'string' }, + dnsNames: { type: 'array', items: { type: 'string' } }, createdAt: { type: 'string', optional: false, @@ -61,6 +62,7 @@ export default class extends Endpoint { // eslint- return ips.map(x => ({ ip: x.ip, + dnsNames: x.dnsNames, createdAt: x.createdAt.toISOString(), })); }); diff --git a/packages/backend/src/server/api/endpoints/admin/invite/create.ts b/packages/backend/src/server/api/endpoints/admin/invite/create.ts index 5ecae3161a..e52b177e2b 100644 --- a/packages/backend/src/server/api/endpoints/admin/invite/create.ts +++ b/packages/backend/src/server/api/endpoints/admin/invite/create.ts @@ -68,6 +68,8 @@ export default class extends Endpoint { // eslint- for (let i = 0; i < ps.count; i++) { ticketsPromises.push(this.registrationTicketsRepository.insertOne({ id: this.idService.gen(), + createdBy: me, + createdById: me.id, expiresAt: ps.expiresAt ? new Date(ps.expiresAt) : null, code: generateInviteCode(), })); diff --git a/packages/backend/src/server/api/endpoints/admin/meta.ts b/packages/backend/src/server/api/endpoints/admin/meta.ts index 9fd0ddc16f..36d6f2b32a 100644 --- a/packages/backend/src/server/api/endpoints/admin/meta.ts +++ b/packages/backend/src/server/api/endpoints/admin/meta.ts @@ -231,10 +231,12 @@ export const meta = { sensitiveMediaDetection: { type: 'string', optional: false, nullable: false, + enum: ['none', 'all', 'local', 'remote'], }, sensitiveMediaDetectionSensitivity: { type: 'string', optional: false, nullable: false, + enum: ['medium', 'low', 'high', 'veryLow', 'veryHigh'], }, setSensitiveFlagAutomatically: { type: 'boolean', @@ -473,6 +475,26 @@ export const meta = { type: 'boolean', optional: false, nullable: false, }, + ctav3SaKey: { + type: 'string', + optional: false, nullable: true, + }, + ctav3ProjectId: { + type: 'string', + optional: false, nullable: true, + }, + ctav3Location: { + type: 'string', + optional: false, nullable: true, + }, + ctav3Model: { + type: 'string', + optional: false, nullable: true, + }, + ctav3Glossary: { + type: 'string', + optional: false, nullable: true, + }, libreTranslateEndPoint: { type: 'string', optional: false, nullable: true, @@ -489,6 +511,10 @@ export const meta = { type: 'string', optional: false, nullable: true, }, + clientOptions: { + type: 'object', + optional: false, nullable: false, + }, description: { type: 'string', optional: false, nullable: true, @@ -537,6 +563,10 @@ export const meta = { type: 'string', optional: false, nullable: true, }, + feedbackUrl: { + type: 'string', + optional: false, nullable: true, + }, summalyProxy: { type: 'string', optional: false, nullable: true, @@ -563,6 +593,10 @@ export const meta = { type: 'boolean', optional: false, nullable: false, }, + urlPreviewAllowRedirect: { + type: 'boolean', + optional: false, nullable: false, + }, urlPreviewTimeout: { type: 'number', optional: false, nullable: false, @@ -596,6 +630,57 @@ export const meta = { optional: false, nullable: false, }, }, + deliverSuspendedSoftware: { + type: 'array', + optional: false, nullable: false, + items: { + type: 'object', + optional: false, nullable: false, + properties: { + software: { + type: 'string', + optional: false, nullable: false, + }, + versionRange: { + type: 'string', + optional: false, nullable: false, + }, + }, + }, + }, + singleUserMode: { + type: 'boolean', + optional: false, nullable: false, + }, + ugcVisibilityForVisitor: { + type: 'string', + enum: ['all', 'local', 'none'], + optional: false, nullable: false, + }, + proxyRemoteFiles: { + type: 'boolean', + optional: false, nullable: false, + }, + signToActivityPubGet: { + type: 'boolean', + optional: false, nullable: false, + }, + allowExternalApRedirect: { + type: 'boolean', + optional: false, nullable: false, + }, + enableRemoteNotesCleaning: { + type: 'boolean', + optional: false, nullable: false, + }, + remoteNotesCleaningExpiryDaysForEachNotes: { + type: 'number', + optional: false, nullable: false, + }, + remoteNotesCleaningMaxProcessingDurationInMinutes: { + type: 'number', + optional: false, nullable: false, + }, doNotSendNotificationEmailsForAbuseReport: { type: 'boolean', optional: false, nullable: false, @@ -749,6 +834,7 @@ export default class extends Endpoint { // eslint- logoImageUrl: instance.logoImageUrl, defaultLightTheme: instance.defaultLightTheme, defaultDarkTheme: instance.defaultDarkTheme, + clientOptions: instance.clientOptions, enableEmail: instance.enableEmail, enableServiceWorker: instance.enableServiceWorker, // translatorAvailable: instance.deeplAuthKey != null, @@ -843,6 +929,7 @@ export default class extends Endpoint { // eslint- notesPerOneAd: instance.notesPerOneAd, summalyProxy: instance.urlPreviewSummaryProxyUrl, urlPreviewEnabled: instance.urlPreviewEnabled, + urlPreviewAllowRedirect: instance.urlPreviewAllowRedirect, urlPreviewTimeout: instance.urlPreviewTimeout, urlPreviewMaximumContentLength: instance.urlPreviewMaximumContentLength, urlPreviewRequireContentLength: instance.urlPreviewRequireContentLength, @@ -851,6 +938,15 @@ export default class extends Endpoint { // eslint- federation: instance.federation, federationHosts: instance.federationHosts, deliverSuspendedSoftware: instance.deliverSuspendedSoftware, + singleUserMode: instance.singleUserMode, + ugcVisibilityForVisitor: instance.ugcVisibilityForVisitor, + proxyRemoteFiles: instance.proxyRemoteFiles, + signToActivityPubGet: instance.signToActivityPubGet, + allowExternalApRedirect: instance.allowExternalApRedirect, + enableRemoteNotesCleaning: instance.enableRemoteNotesCleaning, + remoteNotesCleaningExpiryDaysForEachNotes: instance.remoteNotesCleaningExpiryDaysForEachNotes, + remoteNotesCleaningMaxProcessingDurationInMinutes: instance.remoteNotesCleaningMaxProcessingDurationInMinutes, + showRoleBadgesOfRemoteUsers: instance.showRoleBadgesOfRemoteUsers, doNotSendNotificationEmailsForAbuseReport: instance.doNotSendNotificationEmailsForAbuseReport, emailToReceiveAbuseReport: instance.emailToReceiveAbuseReport, enableReceivePrerelease: instance.enableReceivePrerelease, diff --git a/packages/backend/src/server/api/endpoints/admin/queue/jobs.ts b/packages/backend/src/server/api/endpoints/admin/queue/jobs.ts index 79731c9786..a68e95bf3f 100644 --- a/packages/backend/src/server/api/endpoints/admin/queue/jobs.ts +++ b/packages/backend/src/server/api/endpoints/admin/queue/jobs.ts @@ -5,7 +5,6 @@ import { Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; -import { ModerationLogService } from '@/core/ModerationLogService.js'; import { QUEUE_TYPES, QueueService } from '@/core/QueueService.js'; export const meta = { @@ -14,13 +13,22 @@ export const meta = { requireCredential: true, requireModerator: true, kind: 'read:admin:queue', + + res: { + type: 'array', + optional: false, nullable: false, + items: { + optional: false, nullable: false, + ref: 'QueueJob', + }, + }, } as const; export const paramDef = { type: 'object', properties: { queue: { type: 'string', enum: QUEUE_TYPES }, - state: { type: 'array', items: { type: 'string', enum: ['active', 'wait', 'delayed', 'completed', 'failed'] } }, + state: { type: 'array', items: { type: 'string', enum: ['active', 'wait', 'delayed', 'completed', 'failed', 'paused'] } }, search: { type: 'string' }, }, required: ['queue', 'state'], diff --git a/packages/backend/src/server/api/endpoints/admin/queue/queue-stats.ts b/packages/backend/src/server/api/endpoints/admin/queue/queue-stats.ts index 10ce48332a..dd4391df38 100644 --- a/packages/backend/src/server/api/endpoints/admin/queue/queue-stats.ts +++ b/packages/backend/src/server/api/endpoints/admin/queue/queue-stats.ts @@ -5,7 +5,6 @@ import { Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; -import { ModerationLogService } from '@/core/ModerationLogService.js'; import { QUEUE_TYPES, QueueService } from '@/core/QueueService.js'; export const meta = { @@ -14,6 +13,118 @@ export const meta = { requireCredential: true, requireModerator: true, kind: 'read:admin:queue', + + res: { + type: 'object', + optional: false, nullable: false, + properties: { + name: { + type: 'string', + optional: false, nullable: false, + enum: QUEUE_TYPES, + }, + qualifiedName: { + type: 'string', + optional: false, nullable: false, + }, + counts: { + type: 'object', + optional: false, nullable: false, + additionalProperties: { + type: 'number', + }, + }, + isPaused: { + type: 'boolean', + optional: false, nullable: false, + }, + metrics: { + type: 'object', + optional: false, nullable: false, + properties: { + completed: { + optional: false, nullable: false, + ref: 'QueueMetrics', + }, + failed: { + optional: false, nullable: false, + ref: 'QueueMetrics', + }, + }, + }, + db: { + type: 'object', + optional: false, nullable: false, + properties: { + version: { + type: 'string', + optional: false, nullable: false, + }, + mode: { + type: 'string', + optional: false, nullable: false, + enum: ['cluster', 'standalone', 'sentinel'], + }, + runId: { + type: 'string', + optional: false, nullable: false, + }, + processId: { + type: 'string', + optional: false, nullable: false, + }, + port: { + type: 'number', + optional: false, nullable: false, + }, + os: { + type: 'string', + optional: false, nullable: false, + }, + uptime: { + type: 'number', + optional: false, nullable: false, + }, + memory: { + type: 'object', + optional: false, nullable: false, + properties: { + total: { + type: 'number', + optional: false, nullable: false, + }, + used: { + type: 'number', + optional: false, nullable: false, + }, + fragmentationRatio: { + type: 'number', + optional: false, nullable: false, + }, + peak: { + type: 'number', + optional: false, nullable: false, + }, + }, + }, + clients: { + type: 'object', + optional: false, nullable: false, + properties: { + blocked: { + type: 'number', + optional: false, nullable: false, + }, + connected: { + type: 'number', + optional: false, nullable: false, + }, + }, + }, + }, + }, + }, + }, } as const; export const paramDef = { diff --git a/packages/backend/src/server/api/endpoints/admin/queue/queues.ts b/packages/backend/src/server/api/endpoints/admin/queue/queues.ts index 3a38275f60..8d27e38c84 100644 --- a/packages/backend/src/server/api/endpoints/admin/queue/queues.ts +++ b/packages/backend/src/server/api/endpoints/admin/queue/queues.ts @@ -5,7 +5,6 @@ import { Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; -import { ModerationLogService } from '@/core/ModerationLogService.js'; import { QUEUE_TYPES, QueueService } from '@/core/QueueService.js'; export const meta = { @@ -14,6 +13,47 @@ export const meta = { requireCredential: true, requireModerator: true, kind: 'read:admin:queue', + + res: { + type: 'array', + optional: false, nullable: false, + items: { + type: 'object', + optional: false, nullable: false, + properties: { + name: { + type: 'string', + optional: false, nullable: false, + enum: QUEUE_TYPES, + }, + counts: { + type: 'object', + optional: false, nullable: false, + additionalProperties: { + type: 'number', + }, + }, + isPaused: { + type: 'boolean', + optional: false, nullable: false, + }, + metrics: { + type: 'object', + optional: false, nullable: false, + properties: { + completed: { + optional: false, nullable: false, + ref: 'QueueMetrics', + }, + failed: { + optional: false, nullable: false, + ref: 'QueueMetrics', + }, + }, + }, + }, + }, + }, } as const; export const paramDef = { diff --git a/packages/backend/src/server/api/endpoints/admin/queue/show-job-logs.ts b/packages/backend/src/server/api/endpoints/admin/queue/show-job-logs.ts new file mode 100644 index 0000000000..b9292ed12a --- /dev/null +++ b/packages/backend/src/server/api/endpoints/admin/queue/show-job-logs.ts @@ -0,0 +1,45 @@ +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { Injectable } from '@nestjs/common'; +import { Endpoint } from '@/server/api/endpoint-base.js'; +import { QUEUE_TYPES, QueueService } from '@/core/QueueService.js'; + +export const meta = { + tags: ['admin'], + + requireCredential: true, + requireModerator: true, + kind: 'read:admin:queue', + + res: { + type: 'array', + optional: false, nullable: false, + items: { + optional: false, nullable: false, + type: 'string', + }, + }, +} as const; + +export const paramDef = { + type: 'object', + properties: { + queue: { type: 'string', enum: QUEUE_TYPES }, + jobId: { type: 'string' }, + }, + required: ['queue', 'jobId'], +} as const; + +@Injectable() +export default class extends Endpoint { // eslint-disable-line import/no-default-export + constructor( + private queueService: QueueService, + ) { + super(meta, paramDef, async (ps, me) => { + return this.queueService.queueGetJobLogs(ps.queue, ps.jobId); + }); + } +} diff --git a/packages/backend/src/server/api/endpoints/admin/queue/show-job.ts b/packages/backend/src/server/api/endpoints/admin/queue/show-job.ts index 63747b5540..1735c22674 100644 --- a/packages/backend/src/server/api/endpoints/admin/queue/show-job.ts +++ b/packages/backend/src/server/api/endpoints/admin/queue/show-job.ts @@ -5,7 +5,6 @@ import { Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; -import { ModerationLogService } from '@/core/ModerationLogService.js'; import { QUEUE_TYPES, QueueService } from '@/core/QueueService.js'; export const meta = { @@ -14,6 +13,11 @@ export const meta = { requireCredential: true, requireModerator: true, kind: 'read:admin:queue', + + res: { + optional: false, nullable: false, + ref: 'QueueJob', + }, } as const; export const paramDef = { @@ -28,7 +32,6 @@ export const paramDef = { @Injectable() export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( - private moderationLogService: ModerationLogService, private queueService: QueueService, ) { super(meta, paramDef, async (ps, me) => { diff --git a/packages/backend/src/server/api/endpoints/admin/queue/stats.ts b/packages/backend/src/server/api/endpoints/admin/queue/stats.ts index e2bd38aac6..b69699c338 100644 --- a/packages/backend/src/server/api/endpoints/admin/queue/stats.ts +++ b/packages/backend/src/server/api/endpoints/admin/queue/stats.ts @@ -5,7 +5,7 @@ import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; -import type { DbQueue, DeliverQueue, EndedPollNotificationQueue, InboxQueue, ObjectStorageQueue, SystemQueue, UserWebhookDeliverQueue, SystemWebhookDeliverQueue, ScheduleNotePostQueue } from '@/core/QueueModule.js'; +import type { DbQueue, DeliverQueue, EndedPollNotificationQueue, PostScheduledNoteQueue, InboxQueue, ObjectStorageQueue, SystemQueue, UserWebhookDeliverQueue, SystemWebhookDeliverQueue } from '@/core/QueueModule.js'; export const meta = { tags: ['admin'], @@ -49,13 +49,13 @@ export default class extends Endpoint { // eslint- constructor( @Inject('queue:system') public systemQueue: SystemQueue, @Inject('queue:endedPollNotification') public endedPollNotificationQueue: EndedPollNotificationQueue, + @Inject('queue:postScheduledNote') public postScheduledNoteQueue: PostScheduledNoteQueue, @Inject('queue:deliver') public deliverQueue: DeliverQueue, @Inject('queue:inbox') public inboxQueue: InboxQueue, @Inject('queue:db') public dbQueue: DbQueue, @Inject('queue:objectStorage') public objectStorageQueue: ObjectStorageQueue, @Inject('queue:userWebhookDeliver') public userWebhookDeliverQueue: UserWebhookDeliverQueue, @Inject('queue:systemWebhookDeliver') public systemWebhookDeliverQueue: SystemWebhookDeliverQueue, - @Inject('queue:scheduleNotePost') public scheduleNotePostQueue: ScheduleNotePostQueue, ) { super(meta, paramDef, async (ps, me) => { const deliverJobCounts = await this.deliverQueue.getJobCounts(); diff --git a/packages/backend/src/server/api/endpoints/admin/roles/users.ts b/packages/backend/src/server/api/endpoints/admin/roles/users.ts index 198166bec2..63a8d513fd 100644 --- a/packages/backend/src/server/api/endpoints/admin/roles/users.ts +++ b/packages/backend/src/server/api/endpoints/admin/roles/users.ts @@ -49,6 +49,8 @@ export const paramDef = { roleId: { type: 'string', format: 'misskey:id' }, sinceId: { type: 'string', format: 'misskey:id' }, untilId: { type: 'string', format: 'misskey:id' }, + sinceDate: { type: 'integer' }, + untilDate: { type: 'integer' }, limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 }, }, required: ['roleId'], @@ -76,7 +78,7 @@ export default class extends Endpoint { // eslint- throw new ApiError(meta.errors.noSuchRole); } - const query = this.queryService.makePaginationQuery(this.roleAssignmentsRepository.createQueryBuilder('assign'), ps.sinceId, ps.untilId) + const query = this.queryService.makePaginationQuery(this.roleAssignmentsRepository.createQueryBuilder('assign'), ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate) .andWhere('assign.roleId = :roleId', { roleId: role.id }) .andWhere(new Brackets(qb => { qb diff --git a/packages/backend/src/server/api/endpoints/admin/show-moderation-logs.ts b/packages/backend/src/server/api/endpoints/admin/show-moderation-logs.ts index 58c5f1f60a..697fdf4210 100644 --- a/packages/backend/src/server/api/endpoints/admin/show-moderation-logs.ts +++ b/packages/backend/src/server/api/endpoints/admin/show-moderation-logs.ts @@ -9,6 +9,7 @@ import type { ModerationLogsRepository } from '@/models/_.js'; import { QueryService } from '@/core/QueryService.js'; import { DI } from '@/di-symbols.js'; import { ModerationLogEntityService } from '@/core/entities/ModerationLogEntityService.js'; +import { sqlLikeEscape } from '@/misc/sql-like-escape.js'; export const meta = { tags: ['admin'], @@ -63,8 +64,11 @@ export const paramDef = { limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 }, sinceId: { type: 'string', format: 'misskey:id' }, untilId: { type: 'string', format: 'misskey:id' }, + sinceDate: { type: 'integer' }, + untilDate: { type: 'integer' }, type: { type: 'string', nullable: true }, userId: { type: 'string', format: 'misskey:id', nullable: true }, + search: { type: 'string', nullable: true }, }, required: [], } as const; @@ -79,19 +83,24 @@ export default class extends Endpoint { // eslint- private queryService: QueryService, ) { super(meta, paramDef, async (ps, me) => { - const query = this.queryService.makePaginationQuery(this.moderationLogsRepository.createQueryBuilder('report'), ps.sinceId, ps.untilId); + const query = this.queryService.makePaginationQuery(this.moderationLogsRepository.createQueryBuilder('log'), ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate); if (ps.type != null) { - query.andWhere('report.type = :type', { type: ps.type }); + query.andWhere('log.type = :type', { type: ps.type }); } if (ps.userId != null) { - query.andWhere('report.userId = :userId', { userId: ps.userId }); + query.andWhere('log.userId = :userId', { userId: ps.userId }); } - const reports = await query.limit(ps.limit).getMany(); + if (ps.search != null) { + const escapedSearch = sqlLikeEscape(ps.search); + query.andWhere('log.info::text ILIKE :search', { search: `%${escapedSearch}%` }); + } + + const logs = await query.limit(ps.limit).getMany(); - return await this.moderationLogEntityService.packMany(reports); + return await this.moderationLogEntityService.packMany(logs); }); } } diff --git a/packages/backend/src/server/api/endpoints/admin/show-user.ts b/packages/backend/src/server/api/endpoints/admin/show-user.ts index 57821ac37d..ce673498dc 100644 --- a/packages/backend/src/server/api/endpoints/admin/show-user.ts +++ b/packages/backend/src/server/api/endpoints/admin/show-user.ts @@ -103,6 +103,8 @@ export const meta = { quote: { optional: true, ...notificationRecieveConfig }, reaction: { optional: true, ...notificationRecieveConfig }, pollEnded: { optional: true, ...notificationRecieveConfig }, + scheduledNotePosted: { optional: true, ...notificationRecieveConfig }, + scheduledNotePostFailed: { optional: true, ...notificationRecieveConfig }, receiveFollowRequest: { optional: true, ...notificationRecieveConfig }, followRequestAccepted: { optional: true, ...notificationRecieveConfig }, groupInvited: { optional: true, ...notificationRecieveConfig }, diff --git a/packages/backend/src/server/api/endpoints/admin/system-webhook/create.ts b/packages/backend/src/server/api/endpoints/admin/system-webhook/create.ts index 28071e7a33..93d293ed41 100644 --- a/packages/backend/src/server/api/endpoints/admin/system-webhook/create.ts +++ b/packages/backend/src/server/api/endpoints/admin/system-webhook/create.ts @@ -48,8 +48,8 @@ export const paramDef = { }, secret: { type: 'string', - minLength: 1, maxLength: 1024, + default: '', }, }, required: [ @@ -57,7 +57,6 @@ export const paramDef = { 'name', 'on', 'url', - 'secret', ], } as const; diff --git a/packages/backend/src/server/api/endpoints/admin/system-webhook/update.ts b/packages/backend/src/server/api/endpoints/admin/system-webhook/update.ts index 8d68bb8f87..e021806398 100644 --- a/packages/backend/src/server/api/endpoints/admin/system-webhook/update.ts +++ b/packages/backend/src/server/api/endpoints/admin/system-webhook/update.ts @@ -52,8 +52,8 @@ export const paramDef = { }, secret: { type: 'string', - minLength: 1, maxLength: 1024, + default: '', }, }, required: [ @@ -62,7 +62,6 @@ export const paramDef = { 'name', 'on', 'url', - 'secret', ], } as const; diff --git a/packages/backend/src/server/api/endpoints/admin/update-meta.ts b/packages/backend/src/server/api/endpoints/admin/update-meta.ts index ed3dd2ce14..53c137207d 100644 --- a/packages/backend/src/server/api/endpoints/admin/update-meta.ts +++ b/packages/backend/src/server/api/endpoints/admin/update-meta.ts @@ -70,6 +70,7 @@ export const paramDef = { description: { type: 'string', nullable: true }, defaultLightTheme: { type: 'string', nullable: true }, defaultDarkTheme: { type: 'string', nullable: true }, + clientOptions: { type: 'object', nullable: false }, cacheRemoteFiles: { type: 'boolean' }, cacheRemoteSensitiveFiles: { type: 'boolean' }, emailRequiredForSignup: { type: 'boolean' }, @@ -194,6 +195,7 @@ export const paramDef = { description: '[Deprecated] Use "urlPreviewSummaryProxyUrl" instead.', }, urlPreviewEnabled: { type: 'boolean' }, + urlPreviewAllowRedirect: { type: 'boolean' }, urlPreviewTimeout: { type: 'integer' }, urlPreviewMaximumContentLength: { type: 'integer' }, urlPreviewRequireContentLength: { type: 'boolean' }, @@ -220,6 +222,18 @@ export const paramDef = { required: ['software', 'versionRange'], }, }, + singleUserMode: { type: 'boolean' }, + ugcVisibilityForVisitor: { + type: 'string', + enum: ['all', 'local', 'none'], + }, + proxyRemoteFiles: { type: 'boolean' }, + signToActivityPubGet: { type: 'boolean' }, + allowExternalApRedirect: { type: 'boolean' }, + enableRemoteNotesCleaning: { type: 'boolean' }, + remoteNotesCleaningExpiryDaysForEachNotes: { type: 'number' }, + remoteNotesCleaningMaxProcessingDurationInMinutes: { type: 'number' }, + showRoleBadgesOfRemoteUsers: { type: 'boolean' }, doNotSendNotificationEmailsForAbuseReport: { type: 'boolean' }, emailToReceiveAbuseReport: { type: 'string', nullable: true }, enableReceivePrerelease: { type: 'boolean' }, @@ -369,6 +383,10 @@ export default class extends Endpoint { // eslint- set.defaultDarkTheme = ps.defaultDarkTheme; } + if (ps.clientOptions !== undefined) { + set.clientOptions = ps.clientOptions; + } + if (ps.cacheRemoteFiles !== undefined) { set.cacheRemoteFiles = ps.cacheRemoteFiles; } @@ -799,6 +817,10 @@ export default class extends Endpoint { // eslint- set.urlPreviewEnabled = ps.urlPreviewEnabled; } + if (ps.urlPreviewAllowRedirect !== undefined) { + set.urlPreviewAllowRedirect = ps.urlPreviewAllowRedirect; + } + if (ps.urlPreviewTimeout !== undefined) { set.urlPreviewTimeout = ps.urlPreviewTimeout; } @@ -833,6 +855,42 @@ export default class extends Endpoint { // eslint- set.federationHosts = ps.federationHosts.filter(Boolean).map(x => x.toLowerCase()); } + if (ps.singleUserMode !== undefined) { + set.singleUserMode = ps.singleUserMode; + } + + if (ps.ugcVisibilityForVisitor !== undefined) { + set.ugcVisibilityForVisitor = ps.ugcVisibilityForVisitor; + } + + if (ps.proxyRemoteFiles !== undefined) { + set.proxyRemoteFiles = ps.proxyRemoteFiles; + } + + if (ps.signToActivityPubGet !== undefined) { + set.signToActivityPubGet = ps.signToActivityPubGet; + } + + if (ps.allowExternalApRedirect !== undefined) { + set.allowExternalApRedirect = ps.allowExternalApRedirect; + } + + if (ps.enableRemoteNotesCleaning !== undefined) { + set.enableRemoteNotesCleaning = ps.enableRemoteNotesCleaning; + } + + if (ps.remoteNotesCleaningExpiryDaysForEachNotes !== undefined) { + set.remoteNotesCleaningExpiryDaysForEachNotes = ps.remoteNotesCleaningExpiryDaysForEachNotes; + } + + if (ps.remoteNotesCleaningMaxProcessingDurationInMinutes !== undefined) { + set.remoteNotesCleaningMaxProcessingDurationInMinutes = ps.remoteNotesCleaningMaxProcessingDurationInMinutes; + } + + if (ps.showRoleBadgesOfRemoteUsers !== undefined) { + set.showRoleBadgesOfRemoteUsers = ps.showRoleBadgesOfRemoteUsers; + } + if (ps.doNotSendNotificationEmailsForAbuseReport !== undefined) { set.doNotSendNotificationEmailsForAbuseReport = ps.doNotSendNotificationEmailsForAbuseReport; } diff --git a/packages/backend/src/server/api/endpoints/announcements.ts b/packages/backend/src/server/api/endpoints/announcements.ts index ff8dd73605..2ad1702f72 100644 --- a/packages/backend/src/server/api/endpoints/announcements.ts +++ b/packages/backend/src/server/api/endpoints/announcements.ts @@ -33,6 +33,8 @@ export const paramDef = { limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 }, sinceId: { type: 'string', format: 'misskey:id' }, untilId: { type: 'string', format: 'misskey:id' }, + sinceDate: { type: 'integer' }, + untilDate: { type: 'integer' }, isActive: { type: 'boolean', default: true }, }, required: [], @@ -48,7 +50,7 @@ export default class extends Endpoint { // eslint- private announcementEntityService: AnnouncementEntityService, ) { super(meta, paramDef, async (ps, me) => { - const query = this.queryService.makePaginationQuery(this.announcementsRepository.createQueryBuilder('announcement'), ps.sinceId, ps.untilId) + const query = this.queryService.makePaginationQuery(this.announcementsRepository.createQueryBuilder('announcement'), ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate) .andWhere('announcement.isActive = :isActive', { isActive: ps.isActive }) .andWhere(new Brackets(qb => { if (me) qb.orWhere('announcement.userId = :meId', { meId: me.id }); diff --git a/packages/backend/src/server/api/endpoints/antennas/notes.ts b/packages/backend/src/server/api/endpoints/antennas/notes.ts index f37cdc6658..b2d9cea03c 100644 --- a/packages/backend/src/server/api/endpoints/antennas/notes.ts +++ b/packages/backend/src/server/api/endpoints/antennas/notes.ts @@ -111,11 +111,8 @@ export default class extends Endpoint { // eslint- // NOTE: センシティブ除外の設定はこのエンドポイントでは無視する。 // https://github.com/misskey-dev/misskey/pull/15346#discussion_r1929950255 - this.queryService.generateBlockedHostQueryForNote(query); - this.queryService.generateSuspendedUserQueryForNote(query); this.queryService.generateVisibilityQuery(query, me); - this.queryService.generateMutedUserQueryForNotes(query, me); - this.queryService.generateBlockedUserQueryForNotes(query, me); + this.queryService.generateBaseNoteFilteringQuery(query, me); const notes = await query.getMany(); if (sinceId != null && untilId == null) { diff --git a/packages/backend/src/server/api/endpoints/blocking/list.ts b/packages/backend/src/server/api/endpoints/blocking/list.ts index 8431fa6b34..9885d32eda 100644 --- a/packages/backend/src/server/api/endpoints/blocking/list.ts +++ b/packages/backend/src/server/api/endpoints/blocking/list.ts @@ -34,6 +34,8 @@ export const paramDef = { limit: { type: 'integer', minimum: 1, maximum: 100, default: 30 }, sinceId: { type: 'string', format: 'misskey:id' }, untilId: { type: 'string', format: 'misskey:id' }, + sinceDate: { type: 'integer' }, + untilDate: { type: 'integer' }, }, required: [], } as const; @@ -48,7 +50,7 @@ export default class extends Endpoint { // eslint- private queryService: QueryService, ) { super(meta, paramDef, async (ps, me) => { - const query = this.queryService.makePaginationQuery(this.blockingsRepository.createQueryBuilder('blocking'), ps.sinceId, ps.untilId) + const query = this.queryService.makePaginationQuery(this.blockingsRepository.createQueryBuilder('blocking'), ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate) .andWhere('blocking.blockerId = :meId', { meId: me.id }); const blockings = await query diff --git a/packages/backend/src/server/api/endpoints/channels/followed.ts b/packages/backend/src/server/api/endpoints/channels/followed.ts index 294b5e4bc4..faceb03631 100644 --- a/packages/backend/src/server/api/endpoints/channels/followed.ts +++ b/packages/backend/src/server/api/endpoints/channels/followed.ts @@ -33,6 +33,8 @@ export const paramDef = { properties: { sinceId: { type: 'string', format: 'misskey:id' }, untilId: { type: 'string', format: 'misskey:id' }, + sinceDate: { type: 'integer' }, + untilDate: { type: 'integer' }, limit: { type: 'integer', minimum: 1, maximum: 100, default: 5 }, }, required: [], @@ -53,8 +55,8 @@ export default class extends Endpoint { // eslint- this.channelFollowingsRepository.createQueryBuilder(), ps.sinceId, ps.untilId, - null, - null, + ps.sinceDate, + ps.untilDate, 'followeeId', ) .andWhere({ followerId: me.id }); diff --git a/packages/backend/src/server/api/endpoints/channels/owned.ts b/packages/backend/src/server/api/endpoints/channels/owned.ts index daab685f1b..d22ac18b4b 100644 --- a/packages/backend/src/server/api/endpoints/channels/owned.ts +++ b/packages/backend/src/server/api/endpoints/channels/owned.ts @@ -33,6 +33,8 @@ export const paramDef = { properties: { sinceId: { type: 'string', format: 'misskey:id' }, untilId: { type: 'string', format: 'misskey:id' }, + sinceDate: { type: 'integer' }, + untilDate: { type: 'integer' }, limit: { type: 'integer', minimum: 1, maximum: 100, default: 5 }, }, required: [], @@ -48,7 +50,7 @@ export default class extends Endpoint { // eslint- private queryService: QueryService, ) { super(meta, paramDef, async (ps, me) => { - const query = this.queryService.makePaginationQuery(this.channelsRepository.createQueryBuilder('channel'), ps.sinceId, ps.untilId) + const query = this.queryService.makePaginationQuery(this.channelsRepository.createQueryBuilder('channel'), ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate) .andWhere('channel.isArchived = FALSE') .andWhere({ userId: me.id }); diff --git a/packages/backend/src/server/api/endpoints/channels/search.ts b/packages/backend/src/server/api/endpoints/channels/search.ts index ae32203603..7b6c4db91c 100644 --- a/packages/backend/src/server/api/endpoints/channels/search.ts +++ b/packages/backend/src/server/api/endpoints/channels/search.ts @@ -35,6 +35,8 @@ export const paramDef = { type: { type: 'string', enum: ['nameAndDescription', 'nameOnly'], default: 'nameAndDescription' }, sinceId: { type: 'string', format: 'misskey:id' }, untilId: { type: 'string', format: 'misskey:id' }, + sinceDate: { type: 'integer' }, + untilDate: { type: 'integer' }, limit: { type: 'integer', minimum: 1, maximum: 100, default: 5 }, }, required: ['query'], @@ -50,7 +52,7 @@ export default class extends Endpoint { // eslint- private queryService: QueryService, ) { super(meta, paramDef, async (ps, me) => { - const query = this.queryService.makePaginationQuery(this.channelsRepository.createQueryBuilder('channel'), ps.sinceId, ps.untilId) + const query = this.queryService.makePaginationQuery(this.channelsRepository.createQueryBuilder('channel'), ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate) .andWhere('channel.isArchived = FALSE'); if (ps.query !== '') { diff --git a/packages/backend/src/server/api/endpoints/channels/timeline.ts b/packages/backend/src/server/api/endpoints/channels/timeline.ts index 1d047f2360..7479257376 100644 --- a/packages/backend/src/server/api/endpoints/channels/timeline.ts +++ b/packages/backend/src/server/api/endpoints/channels/timeline.ts @@ -122,12 +122,7 @@ export default class extends Endpoint { // eslint- .leftJoinAndSelect('renote.user', 'renoteUser') .leftJoinAndSelect('note.channel', 'channel'); - this.queryService.generateBlockedHostQueryForNote(query); - this.queryService.generateSuspendedUserQueryForNote(query); - if (me) { - this.queryService.generateMutedUserQueryForNotes(query, me); - this.queryService.generateBlockedUserQueryForNotes(query, me); - } + this.queryService.generateBaseNoteFilteringQuery(query, me); //#endregion return await query.limit(ps.limit).getMany(); diff --git a/packages/backend/src/server/api/endpoints/chat/messages/room-timeline.ts b/packages/backend/src/server/api/endpoints/chat/messages/room-timeline.ts index c0e344b889..dd598b5628 100644 --- a/packages/backend/src/server/api/endpoints/chat/messages/room-timeline.ts +++ b/packages/backend/src/server/api/endpoints/chat/messages/room-timeline.ts @@ -9,6 +9,7 @@ import { DI } from '@/di-symbols.js'; import { ChatService } from '@/core/ChatService.js'; import { ChatEntityService } from '@/core/entities/ChatEntityService.js'; import { ApiError } from '@/server/api/error.js'; +import { IdService } from '@/core/IdService.js'; export const meta = { tags: ['chat'], @@ -42,6 +43,8 @@ export const paramDef = { limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 }, sinceId: { type: 'string', format: 'misskey:id' }, untilId: { type: 'string', format: 'misskey:id' }, + sinceDate: { type: 'integer' }, + untilDate: { type: 'integer' }, roomId: { type: 'string', format: 'misskey:id' }, }, required: ['roomId'], @@ -52,8 +55,12 @@ export default class extends Endpoint { // eslint- constructor( private chatEntityService: ChatEntityService, private chatService: ChatService, + private idService: IdService, ) { super(meta, paramDef, async (ps, me) => { + const untilId = ps.untilId ?? (ps.untilDate ? this.idService.gen(ps.untilDate!) : null); + const sinceId = ps.sinceId ?? (ps.sinceDate ? this.idService.gen(ps.sinceDate!) : null); + await this.chatService.checkChatAvailability(me.id, 'read'); const room = await this.chatService.findRoomById(ps.roomId); @@ -65,7 +72,7 @@ export default class extends Endpoint { // eslint- throw new ApiError(meta.errors.noSuchRoom); } - const messages = await this.chatService.roomTimeline(room.id, ps.limit, ps.sinceId, ps.untilId); + const messages = await this.chatService.roomTimeline(room.id, ps.limit, sinceId, untilId); this.chatService.readRoomChatMessage(me.id, room.id); diff --git a/packages/backend/src/server/api/endpoints/chat/messages/user-timeline.ts b/packages/backend/src/server/api/endpoints/chat/messages/user-timeline.ts index a057e2e088..52a13b2178 100644 --- a/packages/backend/src/server/api/endpoints/chat/messages/user-timeline.ts +++ b/packages/backend/src/server/api/endpoints/chat/messages/user-timeline.ts @@ -10,6 +10,7 @@ import { GetterService } from '@/server/api/GetterService.js'; import { ChatService } from '@/core/ChatService.js'; import { ChatEntityService } from '@/core/entities/ChatEntityService.js'; import { ApiError } from '@/server/api/error.js'; +import { IdService } from '@/core/IdService.js'; export const meta = { tags: ['chat'], @@ -43,6 +44,8 @@ export const paramDef = { limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 }, sinceId: { type: 'string', format: 'misskey:id' }, untilId: { type: 'string', format: 'misskey:id' }, + sinceDate: { type: 'integer' }, + untilDate: { type: 'integer' }, userId: { type: 'string', format: 'misskey:id' }, }, required: ['userId'], @@ -54,8 +57,12 @@ export default class extends Endpoint { // eslint- private chatEntityService: ChatEntityService, private chatService: ChatService, private getterService: GetterService, + private idService: IdService, ) { super(meta, paramDef, async (ps, me) => { + const untilId = ps.untilId ?? (ps.untilDate ? this.idService.gen(ps.untilDate!) : null); + const sinceId = ps.sinceId ?? (ps.sinceDate ? this.idService.gen(ps.sinceDate!) : null); + await this.chatService.checkChatAvailability(me.id, 'read'); const other = await this.getterService.getUser(ps.userId).catch(err => { @@ -63,7 +70,7 @@ export default class extends Endpoint { // eslint- throw err; }); - const messages = await this.chatService.userTimeline(me.id, other.id, ps.limit, ps.sinceId, ps.untilId); + const messages = await this.chatService.userTimeline(me.id, other.id, ps.limit, sinceId, untilId); this.chatService.readUserChatMessage(me.id, other.id); diff --git a/packages/backend/src/server/api/endpoints/chat/read-all.ts b/packages/backend/src/server/api/endpoints/chat/read-all.ts new file mode 100644 index 0000000000..e2d9601aa6 --- /dev/null +++ b/packages/backend/src/server/api/endpoints/chat/read-all.ts @@ -0,0 +1,40 @@ +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { Inject, Injectable } from '@nestjs/common'; +import { Endpoint } from '@/server/api/endpoint-base.js'; +import { DI } from '@/di-symbols.js'; +import { ChatService } from '@/core/ChatService.js'; +import { ApiError } from '@/server/api/error.js'; + +export const meta = { + tags: ['chat'], + + requireCredential: true, + + kind: 'write:chat', + + errors: { + }, +} as const; + +export const paramDef = { + type: 'object', + properties: { + }, +} as const; + +@Injectable() +export default class extends Endpoint { // eslint-disable-line import/no-default-export + constructor( + private chatService: ChatService, + ) { + super(meta, paramDef, async (ps, me) => { + await this.chatService.checkChatAvailability(me.id, 'read'); + + await this.chatService.readAllChatMessages(me.id); + }); + } +} diff --git a/packages/backend/src/server/api/endpoints/chat/rooms/invitations/cancel.ts b/packages/backend/src/server/api/endpoints/chat/rooms/invitations/cancel.ts new file mode 100644 index 0000000000..e9cd12ad7b --- /dev/null +++ b/packages/backend/src/server/api/endpoints/chat/rooms/invitations/cancel.ts @@ -0,0 +1,50 @@ +/* + * SPDX-FileCopyrightText: noridev and cherrypick-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { Inject, Injectable } from '@nestjs/common'; +import { Endpoint } from '@/server/api/endpoint-base.js'; +import { DI } from '@/di-symbols.js'; +import { ChatService } from '@/core/ChatService.js'; +import { ApiError } from '@/server/api/error.js'; + +export const meta = { + tags: ['chat'], + + requireCredential: true, + + kind: 'write:chat', + + errors: { + noSuchInvitation: { + message: 'No such invitation.', + code: 'NO_SUCH_INVITATION', + id: '8c8f38f0-3b7e-4f5e-9c6d-2e3f4a5b6c7d', + }, + }, +} as const; + +export const paramDef = { + type: 'object', + properties: { + invitationId: { type: 'string', format: 'misskey:id' }, + }, + required: ['invitationId'], +} as const; + +@Injectable() +export default class extends Endpoint { // eslint-disable-line import/no-default-export + constructor( + private chatService: ChatService, + ) { + super(meta, paramDef, async (ps, me) => { + await this.chatService.checkChatAvailability(me.id, 'write'); + + const result = await this.chatService.cancelRoomInvitation(me.id, ps.invitationId); + if (!result) { + throw new ApiError(meta.errors.noSuchInvitation); + } + }); + } +} diff --git a/packages/backend/src/server/api/endpoints/chat/rooms/invitations/inbox.ts b/packages/backend/src/server/api/endpoints/chat/rooms/invitations/inbox.ts index 8a02d1c704..f4f91a7d8f 100644 --- a/packages/backend/src/server/api/endpoints/chat/rooms/invitations/inbox.ts +++ b/packages/backend/src/server/api/endpoints/chat/rooms/invitations/inbox.ts @@ -9,6 +9,7 @@ import { DI } from '@/di-symbols.js'; import { ChatService } from '@/core/ChatService.js'; import { ChatEntityService } from '@/core/entities/ChatEntityService.js'; import { ApiError } from '@/server/api/error.js'; +import { IdService } from '@/core/IdService.js'; export const meta = { tags: ['chat'], @@ -37,6 +38,8 @@ export const paramDef = { limit: { type: 'integer', minimum: 1, maximum: 100, default: 30 }, sinceId: { type: 'string', format: 'misskey:id' }, untilId: { type: 'string', format: 'misskey:id' }, + sinceDate: { type: 'integer' }, + untilDate: { type: 'integer' }, }, } as const; @@ -45,11 +48,15 @@ export default class extends Endpoint { // eslint- constructor( private chatEntityService: ChatEntityService, private chatService: ChatService, + private idService: IdService, ) { super(meta, paramDef, async (ps, me) => { + const untilId = ps.untilId ?? (ps.untilDate ? this.idService.gen(ps.untilDate!) : null); + const sinceId = ps.sinceId ?? (ps.sinceDate ? this.idService.gen(ps.sinceDate!) : null); + await this.chatService.checkChatAvailability(me.id, 'read'); - const invitations = await this.chatService.getReceivedRoomInvitationsWithPagination(me.id, ps.limit, ps.sinceId, ps.untilId); + const invitations = await this.chatService.getReceivedRoomInvitationsWithPagination(me.id, ps.limit, sinceId, untilId); return this.chatEntityService.packRoomInvitations(invitations, me); }); } diff --git a/packages/backend/src/server/api/endpoints/chat/rooms/invitations/outbox.ts b/packages/backend/src/server/api/endpoints/chat/rooms/invitations/outbox.ts index 0702ba086c..827bef731c 100644 --- a/packages/backend/src/server/api/endpoints/chat/rooms/invitations/outbox.ts +++ b/packages/backend/src/server/api/endpoints/chat/rooms/invitations/outbox.ts @@ -10,6 +10,7 @@ import { DI } from '@/di-symbols.js'; import { ApiError } from '@/server/api/error.js'; import { ChatService } from '@/core/ChatService.js'; import { ChatEntityService } from '@/core/entities/ChatEntityService.js'; +import { IdService } from '@/core/IdService.js'; export const meta = { tags: ['chat'], @@ -44,6 +45,8 @@ export const paramDef = { limit: { type: 'integer', minimum: 1, maximum: 100, default: 30 }, sinceId: { type: 'string', format: 'misskey:id' }, untilId: { type: 'string', format: 'misskey:id' }, + sinceDate: { type: 'integer' }, + untilDate: { type: 'integer' }, }, required: ['roomId'], } as const; @@ -53,8 +56,12 @@ export default class extends Endpoint { // eslint- constructor( private chatService: ChatService, private chatEntityService: ChatEntityService, + private idService: IdService, ) { super(meta, paramDef, async (ps, me) => { + const untilId = ps.untilId ?? (ps.untilDate ? this.idService.gen(ps.untilDate!) : null); + const sinceId = ps.sinceId ?? (ps.sinceDate ? this.idService.gen(ps.sinceDate!) : null); + await this.chatService.checkChatAvailability(me.id, 'read'); const room = await this.chatService.findMyRoomById(me.id, ps.roomId); @@ -62,7 +69,7 @@ export default class extends Endpoint { // eslint- throw new ApiError(meta.errors.noSuchRoom); } - const invitations = await this.chatService.getSentRoomInvitationsWithPagination(ps.roomId, ps.limit, ps.sinceId, ps.untilId); + const invitations = await this.chatService.getSentRoomInvitationsWithPagination(ps.roomId, ps.limit, sinceId, untilId); return this.chatEntityService.packRoomInvitations(invitations, me); }); } diff --git a/packages/backend/src/server/api/endpoints/chat/rooms/invitations/reject.ts b/packages/backend/src/server/api/endpoints/chat/rooms/invitations/reject.ts new file mode 100644 index 0000000000..47fce05f39 --- /dev/null +++ b/packages/backend/src/server/api/endpoints/chat/rooms/invitations/reject.ts @@ -0,0 +1,47 @@ +/* + * SPDX-FileCopyrightText: noridev and cherrypick-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { Inject, Injectable } from '@nestjs/common'; +import { Endpoint } from '@/server/api/endpoint-base.js'; +import { DI } from '@/di-symbols.js'; +import { ChatService } from '@/core/ChatService.js'; +import { ApiError } from '@/server/api/error.js'; + +export const meta = { + tags: ['chat'], + + requireCredential: true, + + kind: 'write:chat', + + errors: { + noSuchRoom: { + message: 'No such room.', + code: 'NO_SUCH_ROOM', + id: '5130557e-5a11-4cfb-9cc5-fe60cda5de0d', + }, + }, +} as const; + +export const paramDef = { + type: 'object', + properties: { + roomId: { type: 'string', format: 'misskey:id' }, + }, + required: ['roomId'], +} as const; + +@Injectable() +export default class extends Endpoint { // eslint-disable-line import/no-default-export + constructor( + private chatService: ChatService, + ) { + super(meta, paramDef, async (ps, me) => { + await this.chatService.checkChatAvailability(me.id, 'write'); + + await this.chatService.rejectRoomInvitation(me.id, ps.roomId); + }); + } +} diff --git a/packages/backend/src/server/api/endpoints/chat/rooms/joining.ts b/packages/backend/src/server/api/endpoints/chat/rooms/joining.ts index ba9242c762..b061da6d9c 100644 --- a/packages/backend/src/server/api/endpoints/chat/rooms/joining.ts +++ b/packages/backend/src/server/api/endpoints/chat/rooms/joining.ts @@ -9,6 +9,7 @@ import { DI } from '@/di-symbols.js'; import { ChatService } from '@/core/ChatService.js'; import { ChatEntityService } from '@/core/entities/ChatEntityService.js'; import { ApiError } from '@/server/api/error.js'; +import { IdService } from '@/core/IdService.js'; export const meta = { tags: ['chat'], @@ -37,6 +38,8 @@ export const paramDef = { limit: { type: 'integer', minimum: 1, maximum: 100, default: 30 }, sinceId: { type: 'string', format: 'misskey:id' }, untilId: { type: 'string', format: 'misskey:id' }, + sinceDate: { type: 'integer' }, + untilDate: { type: 'integer' }, }, } as const; @@ -45,11 +48,15 @@ export default class extends Endpoint { // eslint- constructor( private chatService: ChatService, private chatEntityService: ChatEntityService, + private idService: IdService, ) { super(meta, paramDef, async (ps, me) => { + const untilId = ps.untilId ?? (ps.untilDate ? this.idService.gen(ps.untilDate!) : null); + const sinceId = ps.sinceId ?? (ps.sinceDate ? this.idService.gen(ps.sinceDate!) : null); + await this.chatService.checkChatAvailability(me.id, 'read'); - const memberships = await this.chatService.getMyMemberships(me.id, ps.limit, ps.sinceId, ps.untilId); + const memberships = await this.chatService.getMyMemberships(me.id, ps.limit, sinceId, untilId); return this.chatEntityService.packRoomMemberships(memberships, me, { populateUser: false, diff --git a/packages/backend/src/server/api/endpoints/chat/rooms/members.ts b/packages/backend/src/server/api/endpoints/chat/rooms/members.ts index f5ffa21d32..aa3fb5168d 100644 --- a/packages/backend/src/server/api/endpoints/chat/rooms/members.ts +++ b/packages/backend/src/server/api/endpoints/chat/rooms/members.ts @@ -9,6 +9,7 @@ import { DI } from '@/di-symbols.js'; import { ChatService } from '@/core/ChatService.js'; import { ApiError } from '@/server/api/error.js'; import { ChatEntityService } from '@/core/entities/ChatEntityService.js'; +import { IdService } from '@/core/IdService.js'; export const meta = { tags: ['chat'], @@ -43,6 +44,8 @@ export const paramDef = { limit: { type: 'integer', minimum: 1, maximum: 100, default: 30 }, sinceId: { type: 'string', format: 'misskey:id' }, untilId: { type: 'string', format: 'misskey:id' }, + sinceDate: { type: 'integer' }, + untilDate: { type: 'integer' }, }, required: ['roomId'], } as const; @@ -52,8 +55,12 @@ export default class extends Endpoint { // eslint- constructor( private chatService: ChatService, private chatEntityService: ChatEntityService, + private idService: IdService, ) { super(meta, paramDef, async (ps, me) => { + const untilId = ps.untilId ?? (ps.untilDate ? this.idService.gen(ps.untilDate!) : null); + const sinceId = ps.sinceId ?? (ps.sinceDate ? this.idService.gen(ps.sinceDate!) : null); + await this.chatService.checkChatAvailability(me.id, 'read'); const room = await this.chatService.findRoomById(ps.roomId); @@ -65,7 +72,7 @@ export default class extends Endpoint { // eslint- throw new ApiError(meta.errors.noSuchRoom); } - const memberships = await this.chatService.getRoomMembershipsWithPagination(room.id, ps.limit, ps.sinceId, ps.untilId); + const memberships = await this.chatService.getRoomMembershipsWithPagination(room.id, ps.limit, sinceId, untilId); return this.chatEntityService.packRoomMemberships(memberships, me, { populateUser: true, diff --git a/packages/backend/src/server/api/endpoints/chat/rooms/owned.ts b/packages/backend/src/server/api/endpoints/chat/rooms/owned.ts index accf7e1bee..40c954fcca 100644 --- a/packages/backend/src/server/api/endpoints/chat/rooms/owned.ts +++ b/packages/backend/src/server/api/endpoints/chat/rooms/owned.ts @@ -9,6 +9,7 @@ import { DI } from '@/di-symbols.js'; import { ChatService } from '@/core/ChatService.js'; import { ChatEntityService } from '@/core/entities/ChatEntityService.js'; import { ApiError } from '@/server/api/error.js'; +import { IdService } from '@/core/IdService.js'; export const meta = { tags: ['chat'], @@ -37,6 +38,8 @@ export const paramDef = { limit: { type: 'integer', minimum: 1, maximum: 100, default: 30 }, sinceId: { type: 'string', format: 'misskey:id' }, untilId: { type: 'string', format: 'misskey:id' }, + sinceDate: { type: 'integer' }, + untilDate: { type: 'integer' }, }, } as const; @@ -45,11 +48,15 @@ export default class extends Endpoint { // eslint- constructor( private chatEntityService: ChatEntityService, private chatService: ChatService, + private idService: IdService, ) { super(meta, paramDef, async (ps, me) => { + const untilId = ps.untilId ?? (ps.untilDate ? this.idService.gen(ps.untilDate!) : null); + const sinceId = ps.sinceId ?? (ps.sinceDate ? this.idService.gen(ps.sinceDate!) : null); + await this.chatService.checkChatAvailability(me.id, 'read'); - const rooms = await this.chatService.getOwnedRoomsWithPagination(me.id, ps.limit, ps.sinceId, ps.untilId); + const rooms = await this.chatService.getOwnedRoomsWithPagination(me.id, ps.limit, sinceId, untilId); return this.chatEntityService.packRooms(rooms, me); }); } diff --git a/packages/backend/src/server/api/endpoints/clips/list.ts b/packages/backend/src/server/api/endpoints/clips/list.ts index 2e4a3ff820..af20ea9f8d 100644 --- a/packages/backend/src/server/api/endpoints/clips/list.ts +++ b/packages/backend/src/server/api/endpoints/clips/list.ts @@ -5,6 +5,7 @@ import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; +import { QueryService } from '@/core/QueryService.js'; import type { ClipsRepository } from '@/models/_.js'; import { ClipEntityService } from '@/core/entities/ClipEntityService.js'; import { DI } from '@/di-symbols.js'; @@ -29,7 +30,13 @@ export const meta = { export const paramDef = { type: 'object', - properties: {}, + properties: { + limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 }, + sinceId: { type: 'string', format: 'misskey:id' }, + untilId: { type: 'string', format: 'misskey:id' }, + sinceDate: { type: 'integer' }, + untilDate: { type: 'integer' }, + }, required: [], } as const; @@ -39,12 +46,14 @@ export default class extends Endpoint { // eslint- @Inject(DI.clipsRepository) private clipsRepository: ClipsRepository, + private queryService: QueryService, private clipEntityService: ClipEntityService, ) { super(meta, paramDef, async (ps, me) => { - const clips = await this.clipsRepository.findBy({ - userId: me.id, - }); + const query = this.queryService.makePaginationQuery(this.clipsRepository.createQueryBuilder('clip'), ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate) + .andWhere('clip.userId = :userId', { userId: me.id }); + + const clips = await query.limit(ps.limit).getMany(); return await this.clipEntityService.packMany(clips, me); }); diff --git a/packages/backend/src/server/api/endpoints/clips/notes.ts b/packages/backend/src/server/api/endpoints/clips/notes.ts index 33f32d1d8a..c4260fd87c 100644 --- a/packages/backend/src/server/api/endpoints/clips/notes.ts +++ b/packages/backend/src/server/api/endpoints/clips/notes.ts @@ -4,11 +4,13 @@ */ import { Inject, Injectable } from '@nestjs/common'; +import { Brackets } from 'typeorm'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { NotesRepository, ClipsRepository, ClipNotesRepository } from '@/models/_.js'; import { QueryService } from '@/core/QueryService.js'; import { NoteEntityService } from '@/core/entities/NoteEntityService.js'; import { DI } from '@/di-symbols.js'; +import { sqlLikeEscape } from '@/misc/sql-like-escape.js'; import { ApiError } from '../../error.js'; export const meta = { @@ -44,6 +46,9 @@ export const paramDef = { limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 }, sinceId: { type: 'string', format: 'misskey:id' }, untilId: { type: 'string', format: 'misskey:id' }, + sinceDate: { type: 'integer' }, + untilDate: { type: 'integer' }, + search: { type: 'string', minLength: 1, maxLength: 100, nullable: true }, }, required: ['clipId'], } as const; @@ -76,7 +81,7 @@ export default class extends Endpoint { // eslint- throw new ApiError(meta.errors.noSuchClip); } - const query = this.queryService.makePaginationQuery(this.notesRepository.createQueryBuilder('note'), ps.sinceId, ps.untilId) + const query = this.queryService.makePaginationQuery(this.notesRepository.createQueryBuilder('note'), ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate) .innerJoin(this.clipNotesRepository.metadata.targetName, 'clipNote', 'clipNote.noteId = note.id') .innerJoinAndSelect('note.user', 'user') .leftJoinAndSelect('note.reply', 'reply') @@ -91,6 +96,17 @@ export default class extends Endpoint { // eslint- if (me) { this.queryService.generateMutedUserQueryForNotes(query, me); this.queryService.generateBlockedUserQueryForNotes(query, me); + this.queryService.generateMutedUserQueryForNotes(query, me, { noteColumn: 'renote' }); + this.queryService.generateBlockedUserQueryForNotes(query, me, { noteColumn: 'renote' }); + } + + if (ps.search != null) { + for (const word of ps.search.trim().split(' ')) { + query.andWhere(new Brackets(qb => { + qb.orWhere('note.text ILIKE :search', { search: `%${sqlLikeEscape(word)}%` }); + qb.orWhere('note.cw ILIKE :search', { search: `%${sqlLikeEscape(word)}%` }); + })); + } } const notes = await query diff --git a/packages/backend/src/server/api/endpoints/drive/files.ts b/packages/backend/src/server/api/endpoints/drive/files.ts index 10c521332d..303a4d4925 100644 --- a/packages/backend/src/server/api/endpoints/drive/files.ts +++ b/packages/backend/src/server/api/endpoints/drive/files.ts @@ -34,6 +34,8 @@ export const paramDef = { limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 }, sinceId: { type: 'string', format: 'misskey:id' }, untilId: { type: 'string', format: 'misskey:id' }, + sinceDate: { type: 'integer' }, + untilDate: { type: 'integer' }, folderId: { type: 'string', format: 'misskey:id', nullable: true, default: null }, type: { type: 'string', nullable: true, pattern: /^[a-zA-Z\/\-*]+$/.toString().slice(1, -1) }, sort: { type: 'string', nullable: true, enum: ['+createdAt', '-createdAt', '+name', '-name', '+size', '-size', null] }, @@ -51,7 +53,7 @@ export default class extends Endpoint { // eslint- private queryService: QueryService, ) { super(meta, paramDef, async (ps, me) => { - const query = this.queryService.makePaginationQuery(this.driveFilesRepository.createQueryBuilder('file'), ps.sinceId, ps.untilId) + const query = this.queryService.makePaginationQuery(this.driveFilesRepository.createQueryBuilder('file'), ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate) .andWhere('file.userId = :userId', { userId: me.id }); if (ps.folderId) { diff --git a/packages/backend/src/server/api/endpoints/drive/files/attached-chat-messages.ts b/packages/backend/src/server/api/endpoints/drive/files/attached-chat-messages.ts new file mode 100644 index 0000000000..b34ac4abd1 --- /dev/null +++ b/packages/backend/src/server/api/endpoints/drive/files/attached-chat-messages.ts @@ -0,0 +1,93 @@ +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { Inject, Injectable } from '@nestjs/common'; +import { Endpoint } from '@/server/api/endpoint-base.js'; +import type { DriveFilesRepository, ChatMessagesRepository } from '@/models/_.js'; +import { QueryService } from '@/core/QueryService.js'; +import { DI } from '@/di-symbols.js'; +import { RoleService } from '@/core/RoleService.js'; +import { ChatEntityService } from '@/core/entities/ChatEntityService.js'; +import { ChatService } from '@/core/ChatService.js'; +import { ApiError } from '../../../error.js'; + +export const meta = { + tags: ['drive', 'chat'], + + requireCredential: true, + + kind: 'read:drive', + + res: { + type: 'array', + optional: false, nullable: false, + items: { + type: 'object', + optional: false, nullable: false, + ref: 'ChatMessage', + }, + }, + + errors: { + noSuchFile: { + message: 'No such file.', + code: 'NO_SUCH_FILE', + id: '485ce26d-f5d2-4313-9783-e689d131eafb', + }, + }, +} as const; + +export const paramDef = { + type: 'object', + properties: { + sinceId: { type: 'string', format: 'misskey:id' }, + untilId: { type: 'string', format: 'misskey:id' }, + sinceDate: { type: 'integer' }, + untilDate: { type: 'integer' }, + limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 }, + fileId: { type: 'string', format: 'misskey:id' }, + }, + required: ['fileId'], +} as const; + +@Injectable() +export default class extends Endpoint { // eslint-disable-line import/no-default-export + constructor( + @Inject(DI.driveFilesRepository) + private driveFilesRepository: DriveFilesRepository, + + @Inject(DI.chatMessagesRepository) + private chatMessagesRepository: ChatMessagesRepository, + + private chatService: ChatService, + private chatEntityService: ChatEntityService, + private queryService: QueryService, + private roleService: RoleService, + ) { + super(meta, paramDef, async (ps, me) => { + const isModerator = await this.roleService.isModerator(me); + + if (!isModerator) { + await this.chatService.checkChatAvailability(me.id, 'read'); + } + + const file = await this.driveFilesRepository.findOneBy({ + id: ps.fileId, + userId: isModerator ? undefined : me.id, + }); + + if (file == null) { + throw new ApiError(meta.errors.noSuchFile); + } + + const query = this.queryService.makePaginationQuery(this.chatMessagesRepository.createQueryBuilder('message'), ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate); + query.andWhere('message.fileId = :fileId', { fileId: file.id }); + + const messages = await query.limit(ps.limit).getMany(); + + return await this.chatEntityService.packMessagesDetailed(messages, me); + }); + } +} diff --git a/packages/backend/src/server/api/endpoints/drive/files/attached-notes.ts b/packages/backend/src/server/api/endpoints/drive/files/attached-notes.ts index f58248e848..6bc8730a1e 100644 --- a/packages/backend/src/server/api/endpoints/drive/files/attached-notes.ts +++ b/packages/backend/src/server/api/endpoints/drive/files/attached-notes.ts @@ -45,6 +45,8 @@ export const paramDef = { properties: { sinceId: { type: 'string', format: 'misskey:id' }, untilId: { type: 'string', format: 'misskey:id' }, + sinceDate: { type: 'integer' }, + untilDate: { type: 'integer' }, limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 }, fileId: { type: 'string', format: 'misskey:id' }, }, @@ -75,7 +77,7 @@ export default class extends Endpoint { // eslint- throw new ApiError(meta.errors.noSuchFile); } - const query = this.queryService.makePaginationQuery(this.notesRepository.createQueryBuilder('note'), ps.sinceId, ps.untilId); + const query = this.queryService.makePaginationQuery(this.notesRepository.createQueryBuilder('note'), ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate); query.andWhere(':file <@ note.fileIds', { file: [file.id] }); const notes = await query.limit(ps.limit).getMany(); diff --git a/packages/backend/src/server/api/endpoints/drive/files/create.ts b/packages/backend/src/server/api/endpoints/drive/files/create.ts index 2301535a20..fb915b651e 100644 --- a/packages/backend/src/server/api/endpoints/drive/files/create.ts +++ b/packages/backend/src/server/api/endpoints/drive/files/create.ts @@ -63,6 +63,12 @@ export const meta = { id: 'b9d8c348-33f0-4673-b9a9-5d4da058977a', httpStatusCode: 413, }, + + unallowedFileType: { + message: 'Cannot upload the file because it is an unallowed file type.', + code: 'UNALLOWED_FILE_TYPE', + id: '4becd248-7f2c-48c4-a9f0-75edc4f9a1ea', + }, }, } as const; @@ -123,6 +129,7 @@ export default class extends Endpoint { // eslint- if (err.id === '282f77bf-5816-4f72-9264-aa14d8261a21') throw new ApiError(meta.errors.inappropriate); if (err.id === 'c6244ed2-a39a-4e1c-bf93-f0fbd7764fa6') throw new ApiError(meta.errors.noFreeSpace); if (err.id === 'f9e4e5f3-4df4-40b5-b400-f236945f7073') throw new ApiError(meta.errors.maxFileSizeExceeded); + if (err.id === 'bd71c601-f9b0-4808-9137-a330647ced9b') throw new ApiError(meta.errors.unallowedFileType); } throw new ApiError(); } finally { diff --git a/packages/backend/src/server/api/endpoints/drive/files/move-bulk.ts b/packages/backend/src/server/api/endpoints/drive/files/move-bulk.ts new file mode 100644 index 0000000000..c8500895eb --- /dev/null +++ b/packages/backend/src/server/api/endpoints/drive/files/move-bulk.ts @@ -0,0 +1,41 @@ +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { Inject, Injectable } from '@nestjs/common'; +import { Endpoint } from '@/server/api/endpoint-base.js'; +import { DI } from '@/di-symbols.js'; +import { DriveService } from '@/core/DriveService.js'; +import { ApiError } from '../../../error.js'; + +export const meta = { + tags: ['drive'], + + requireCredential: true, + + kind: 'write:drive', + + errors: { + }, +} as const; + +export const paramDef = { + type: 'object', + properties: { + fileIds: { type: 'array', uniqueItems: true, minItems: 1, maxItems: 100, items: { type: 'string', format: 'misskey:id' } }, + folderId: { type: 'string', format: 'misskey:id', nullable: true }, + }, + required: ['fileIds'], +} as const; + +@Injectable() +export default class extends Endpoint { // eslint-disable-line import/no-default-export + constructor( + private driveService: DriveService, + ) { + super(meta, paramDef, async (ps, me) => { + await this.driveService.moveFiles(ps.fileIds, ps.folderId ?? null, me.id); + }); + } +} diff --git a/packages/backend/src/server/api/endpoints/drive/files/show.ts b/packages/backend/src/server/api/endpoints/drive/files/show.ts index e8f4539d61..9a2e2c73e8 100644 --- a/packages/backend/src/server/api/endpoints/drive/files/show.ts +++ b/packages/backend/src/server/api/endpoints/drive/files/show.ts @@ -43,14 +43,21 @@ export const meta = { } as const; export const paramDef = { - type: 'object', - properties: { - fileId: { type: 'string', format: 'misskey:id' }, - url: { type: 'string' }, - }, anyOf: [ - { required: ['fileId'] }, - { required: ['url'] }, + { + type: 'object', + properties: { + fileId: { type: 'string', format: 'misskey:id' }, + }, + required: ['fileId'], + }, + { + type: 'object', + properties: { + url: { type: 'string' }, + }, + required: ['url'], + }, ], } as const; @@ -64,21 +71,11 @@ export default class extends Endpoint { // eslint- private roleService: RoleService, ) { super(meta, paramDef, async (ps, me) => { - let file: MiDriveFile | null = null; - - if (ps.fileId) { - file = await this.driveFilesRepository.findOneBy({ id: ps.fileId }); - } else if (ps.url) { - file = await this.driveFilesRepository.findOne({ - where: [{ - url: ps.url, - }, { - webpublicUrl: ps.url, - }, { - thumbnailUrl: ps.url, - }], - }); - } + const file = await this.driveFilesRepository.findOneBy( + 'fileId' in ps + ? { id: ps.fileId } + : [{ url: ps.url }, { webpublicUrl: ps.url }, { thumbnailUrl: ps.url }], + ); if (file == null) { throw new ApiError(meta.errors.noSuchFile); diff --git a/packages/backend/src/server/api/endpoints/drive/folders.ts b/packages/backend/src/server/api/endpoints/drive/folders.ts index 8c4848f8e1..23b3db60a8 100644 --- a/packages/backend/src/server/api/endpoints/drive/folders.ts +++ b/packages/backend/src/server/api/endpoints/drive/folders.ts @@ -34,6 +34,8 @@ export const paramDef = { limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 }, sinceId: { type: 'string', format: 'misskey:id' }, untilId: { type: 'string', format: 'misskey:id' }, + sinceDate: { type: 'integer' }, + untilDate: { type: 'integer' }, folderId: { type: 'string', format: 'misskey:id', nullable: true, default: null }, }, required: [], @@ -49,7 +51,7 @@ export default class extends Endpoint { // eslint- private queryService: QueryService, ) { super(meta, paramDef, async (ps, me) => { - const query = this.queryService.makePaginationQuery(this.driveFoldersRepository.createQueryBuilder('folder'), ps.sinceId, ps.untilId) + const query = this.queryService.makePaginationQuery(this.driveFoldersRepository.createQueryBuilder('folder'), ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate) .andWhere('folder.userId = :userId', { userId: me.id }); if (ps.folderId) { diff --git a/packages/backend/src/server/api/endpoints/drive/stream.ts b/packages/backend/src/server/api/endpoints/drive/stream.ts index f7c1ed39b5..8bf83a9653 100644 --- a/packages/backend/src/server/api/endpoints/drive/stream.ts +++ b/packages/backend/src/server/api/endpoints/drive/stream.ts @@ -34,6 +34,8 @@ export const paramDef = { limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 }, sinceId: { type: 'string', format: 'misskey:id' }, untilId: { type: 'string', format: 'misskey:id' }, + sinceDate: { type: 'integer' }, + untilDate: { type: 'integer' }, type: { type: 'string', pattern: /^[a-zA-Z\/\-*]+$/.toString().slice(1, -1) }, }, required: [], @@ -49,7 +51,7 @@ export default class extends Endpoint { // eslint- private queryService: QueryService, ) { super(meta, paramDef, async (ps, me) => { - const query = this.queryService.makePaginationQuery(this.driveFilesRepository.createQueryBuilder('file'), ps.sinceId, ps.untilId) + const query = this.queryService.makePaginationQuery(this.driveFilesRepository.createQueryBuilder('file'), ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate) .andWhere('file.userId = :userId', { userId: me.id }); if (ps.type) { diff --git a/packages/backend/src/server/api/endpoints/federation/followers.ts b/packages/backend/src/server/api/endpoints/federation/followers.ts index ce4dd13067..296bc7c5a8 100644 --- a/packages/backend/src/server/api/endpoints/federation/followers.ts +++ b/packages/backend/src/server/api/endpoints/federation/followers.ts @@ -32,6 +32,8 @@ export const paramDef = { host: { type: 'string' }, sinceId: { type: 'string', format: 'misskey:id' }, untilId: { type: 'string', format: 'misskey:id' }, + sinceDate: { type: 'integer' }, + untilDate: { type: 'integer' }, limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 }, }, required: ['host'], @@ -47,7 +49,7 @@ export default class extends Endpoint { // eslint- private queryService: QueryService, ) { super(meta, paramDef, async (ps, me) => { - const query = this.queryService.makePaginationQuery(this.followingsRepository.createQueryBuilder('following'), ps.sinceId, ps.untilId) + const query = this.queryService.makePaginationQuery(this.followingsRepository.createQueryBuilder('following'), ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate) .andWhere('following.followeeHost = :host', { host: ps.host }); const followings = await query diff --git a/packages/backend/src/server/api/endpoints/federation/following.ts b/packages/backend/src/server/api/endpoints/federation/following.ts index 1a793889c7..091bf442af 100644 --- a/packages/backend/src/server/api/endpoints/federation/following.ts +++ b/packages/backend/src/server/api/endpoints/federation/following.ts @@ -32,6 +32,8 @@ export const paramDef = { host: { type: 'string' }, sinceId: { type: 'string', format: 'misskey:id' }, untilId: { type: 'string', format: 'misskey:id' }, + sinceDate: { type: 'integer' }, + untilDate: { type: 'integer' }, limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 }, }, required: ['host'], @@ -47,7 +49,7 @@ export default class extends Endpoint { // eslint- private queryService: QueryService, ) { super(meta, paramDef, async (ps, me) => { - const query = this.queryService.makePaginationQuery(this.followingsRepository.createQueryBuilder('following'), ps.sinceId, ps.untilId) + const query = this.queryService.makePaginationQuery(this.followingsRepository.createQueryBuilder('following'), ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate) .andWhere('following.followerHost = :host', { host: ps.host }); const followings = await query diff --git a/packages/backend/src/server/api/endpoints/federation/remote-software.ts b/packages/backend/src/server/api/endpoints/federation/remote-software.ts new file mode 100644 index 0000000000..50dd6d8f9f --- /dev/null +++ b/packages/backend/src/server/api/endpoints/federation/remote-software.ts @@ -0,0 +1,163 @@ +/* + * SPDX-FileCopyrightText: noridev and cherrypick-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { Inject, Injectable } from '@nestjs/common'; +import type { InstancesRepository } from '@/models/_.js'; +import { Endpoint } from '@/server/api/endpoint-base.js'; +import { DI } from '@/di-symbols.js'; +import { MetaService } from '@/core/MetaService.js'; + +export const meta = { + tags: ['federation'], + + requireCredential: false, + + allowGet: true, + cacheSec: 60 * 60, + + res: { + type: 'array', + optional: false, + nullable: false, + items: { + type: 'object', + optional: false, + nullable: false, + properties: { + softwareName: { + type: 'string', + optional: false, + nullable: false, + }, + color: { + type: 'string', + optional: false, + nullable: true, + }, + count: { + type: 'integer', + optional: false, + nullable: false, + }, + }, + }, + }, +} as const; + +export const paramDef = { + type: 'object', + properties: { + blocked: { type: 'boolean', nullable: true }, + notResponding: { type: 'boolean', nullable: true }, + suspended: { type: 'boolean', nullable: true }, + silenced: { type: 'boolean', nullable: true }, + federating: { type: 'boolean', nullable: true }, + subscribing: { type: 'boolean', nullable: true }, + publishing: { type: 'boolean', nullable: true }, + quarantined: { type: 'boolean', nullable: true }, + }, + required: [], +} as const; + +@Injectable() +export default class extends Endpoint { // eslint-disable-line import/no-default-export + constructor( + @Inject(DI.instancesRepository) + private instancesRepository: InstancesRepository, + + private metaService: MetaService, + ) { + super(meta, paramDef, async (ps) => { + const query = this.instancesRepository + .createQueryBuilder('instance') + .select('"softwareName"'); + + if (typeof ps.blocked === 'boolean' || typeof ps.silenced === 'boolean') { + const meta = await this.metaService.fetch(true); + + if (typeof ps.blocked === 'boolean') { + if (meta.blockedHosts.length === 0) return []; + + query.andWhere(`instance.host ${ ps.blocked ? 'IN' : 'NOT IN'} (:...blocked)`, { + blocked: meta.blockedHosts, + }); + } + + if (typeof ps.silenced === 'boolean') { + if (meta.silencedHosts.length === 0) return []; + + query.andWhere(`instance.host ${ ps.silenced ? 'IN' : 'NOT IN'} (:...silences)`, { + silences: meta.silencedHosts, + }); + } + } + + if (typeof ps.federating === 'boolean') { + if (typeof ps.subscribing === 'boolean' && ps.subscribing !== ps.federating) return []; + if (typeof ps.publishing === 'boolean' && ps.publishing !== ps.federating) return []; + query.andWhere(ps.federating ? + '(("followingCount" > 0) OR ("followersCount" > 0))' : + '(("followingCount" = 0) AND ("followersCount" = 0))'); + } else { + if (typeof ps.subscribing === 'boolean') { + query.andWhere( ps.subscribing ? + 'instance.followersCount > 0' : 'instance.followersCount = 0'); + } + + if (typeof ps.publishing === 'boolean') { + query.andWhere( ps.subscribing ? + 'instance.followingCount > 0' : 'instance.followingCount = 0'); + } + } + + if (typeof ps.suspended === 'boolean') { + query.andWhere(`instance.suspensionState ${ ps.suspended ? '!=' : '='} 'none'`); + } + + if (typeof ps.quarantined === 'boolean') { + query.andWhere('instance.quarantineLimited = :quarantineLimited', { quarantineLimited: ps.quarantined }); + } + + if (typeof ps.notResponding === 'boolean') { + query.andWhere('instance.isNotResponding = :isNotResponding', { isNotResponding: ps.notResponding }); + } + + const queryResult = await query.getRawMany(); + const softwareName = [...new Set(queryResult.map( x => x.softwareName))]; + return softwareName.map(s => ({ + softwareName: s ?? 'null', + count: queryResult.filter(x => x.softwareName === s).length, + color: getColor(s), + })); + }); + } +} + +function getColor(name: string | null): string | null { + switch (name) { + case 'misskey': + return '#86b300'; + case 'sharkey': + return '#43BBE5'; + case 'cherrypick': + return '#ffa9c3'; + case 'yojo-art': + return '#ffbcdc'; + case 'mastodon': + return '#6364FF'; + case 'kmyblue': + return '#86AFE5'; + case 'fedibird': + return '#282c37'; + case 'pleroma': + return '#FAA459'; + case 'akkoma': + return '#462E7A'; + + // hollo, mitra, null + default: + return null; + } +} diff --git a/packages/backend/src/server/api/endpoints/federation/users.ts b/packages/backend/src/server/api/endpoints/federation/users.ts index 71b1aeb07b..c2d660f163 100644 --- a/packages/backend/src/server/api/endpoints/federation/users.ts +++ b/packages/backend/src/server/api/endpoints/federation/users.ts @@ -32,6 +32,8 @@ export const paramDef = { host: { type: 'string' }, sinceId: { type: 'string', format: 'misskey:id' }, untilId: { type: 'string', format: 'misskey:id' }, + sinceDate: { type: 'integer' }, + untilDate: { type: 'integer' }, limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 }, }, required: ['host'], @@ -47,7 +49,7 @@ export default class extends Endpoint { // eslint- private queryService: QueryService, ) { super(meta, paramDef, async (ps, me) => { - const query = this.queryService.makePaginationQuery(this.usersRepository.createQueryBuilder('user'), ps.sinceId, ps.untilId) + const query = this.queryService.makePaginationQuery(this.usersRepository.createQueryBuilder('user'), ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate) .andWhere('user.host = :host', { host: ps.host }); const users = await query diff --git a/packages/backend/src/server/api/endpoints/flash/my-likes.ts b/packages/backend/src/server/api/endpoints/flash/my-likes.ts index 755cc5acfc..ff9d6c3264 100644 --- a/packages/backend/src/server/api/endpoints/flash/my-likes.ts +++ b/packages/backend/src/server/api/endpoints/flash/my-likes.ts @@ -5,10 +5,9 @@ import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; -import type { FlashLikesRepository } from '@/models/_.js'; -import { QueryService } from '@/core/QueryService.js'; import { FlashLikeEntityService } from '@/core/entities/FlashLikeEntityService.js'; import { DI } from '@/di-symbols.js'; +import { FlashService } from '@/core/FlashService.js'; export const meta = { tags: ['account', 'flash'], @@ -44,6 +43,9 @@ export const paramDef = { limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 }, sinceId: { type: 'string', format: 'misskey:id' }, untilId: { type: 'string', format: 'misskey:id' }, + sinceDate: { type: 'integer' }, + untilDate: { type: 'integer' }, + search: { type: 'string', minLength: 1, maxLength: 100, nullable: true }, }, required: [], } as const; @@ -51,20 +53,18 @@ export const paramDef = { @Injectable() export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( - @Inject(DI.flashLikesRepository) - private flashLikesRepository: FlashLikesRepository, - private flashLikeEntityService: FlashLikeEntityService, - private queryService: QueryService, + private flashService: FlashService, ) { super(meta, paramDef, async (ps, me) => { - const query = this.queryService.makePaginationQuery(this.flashLikesRepository.createQueryBuilder('like'), ps.sinceId, ps.untilId) - .andWhere('like.userId = :meId', { meId: me.id }) - .leftJoinAndSelect('like.flash', 'flash'); - - const likes = await query - .limit(ps.limit) - .getMany(); + const likes = await this.flashService.myLikes(me.id, { + sinceId: ps.sinceId, + untilId: ps.untilId, + sinceDate: ps.sinceDate, + untilDate: ps.untilDate, + limit: ps.limit, + search: ps.search, + }); return this.flashLikeEntityService.packMany(likes, me); }); diff --git a/packages/backend/src/server/api/endpoints/flash/my.ts b/packages/backend/src/server/api/endpoints/flash/my.ts index 5746096232..6ec623b719 100644 --- a/packages/backend/src/server/api/endpoints/flash/my.ts +++ b/packages/backend/src/server/api/endpoints/flash/my.ts @@ -34,6 +34,8 @@ export const paramDef = { limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 }, sinceId: { type: 'string', format: 'misskey:id' }, untilId: { type: 'string', format: 'misskey:id' }, + sinceDate: { type: 'integer' }, + untilDate: { type: 'integer' }, }, required: [], } as const; @@ -48,7 +50,7 @@ export default class extends Endpoint { // eslint- private queryService: QueryService, ) { super(meta, paramDef, async (ps, me) => { - const query = this.queryService.makePaginationQuery(this.flashsRepository.createQueryBuilder('flash'), ps.sinceId, ps.untilId) + const query = this.queryService.makePaginationQuery(this.flashsRepository.createQueryBuilder('flash'), ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate) .andWhere('flash.userId = :meId', { meId: me.id }); const flashs = await query diff --git a/packages/backend/src/server/api/endpoints/flash/search.ts b/packages/backend/src/server/api/endpoints/flash/search.ts new file mode 100644 index 0000000000..36948bb7b4 --- /dev/null +++ b/packages/backend/src/server/api/endpoints/flash/search.ts @@ -0,0 +1,59 @@ +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { Inject, Injectable } from '@nestjs/common'; +import { Endpoint } from '@/server/api/endpoint-base.js'; +import { FlashEntityService } from '@/core/entities/FlashEntityService.js'; +import { DI } from '@/di-symbols.js'; +import { FlashService } from '@/core/FlashService.js'; + +export const meta = { + tags: ['flash'], + + requireCredential: false, + + res: { + type: 'array', + optional: false, nullable: false, + items: { + type: 'object', + optional: false, nullable: false, + ref: 'Flash', + }, + }, +} as const; + +export const paramDef = { + type: 'object', + properties: { + query: { type: 'string', minLength: 1, maxLength: 100 }, + sinceId: { type: 'string', format: 'misskey:id' }, + untilId: { type: 'string', format: 'misskey:id' }, + sinceDate: { type: 'integer' }, + untilDate: { type: 'integer' }, + limit: { type: 'integer', minimum: 1, maximum: 100, default: 5 }, + }, + required: ['query'], +} as const; + +@Injectable() +export default class extends Endpoint { // eslint-disable-line import/no-default-export + constructor( + private flashService: FlashService, + private flashEntityService: FlashEntityService, + ) { + super(meta, paramDef, async (ps, me) => { + const result = await this.flashService.search(ps.query, { + sinceId: ps.sinceId, + untilId: ps.untilId, + sinceDate: ps.sinceDate, + untilDate: ps.untilDate, + limit: ps.limit, + }); + + return await this.flashEntityService.packMany(result, me); + }); + } +} diff --git a/packages/backend/src/server/api/endpoints/following/requests/list.ts b/packages/backend/src/server/api/endpoints/following/requests/list.ts index fa59e38976..cf614e433d 100644 --- a/packages/backend/src/server/api/endpoints/following/requests/list.ts +++ b/packages/backend/src/server/api/endpoints/following/requests/list.ts @@ -49,6 +49,8 @@ export const paramDef = { properties: { sinceId: { type: 'string', format: 'misskey:id' }, untilId: { type: 'string', format: 'misskey:id' }, + sinceDate: { type: 'integer' }, + untilDate: { type: 'integer' }, limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 }, }, required: [], @@ -64,7 +66,7 @@ export default class extends Endpoint { // eslint- private queryService: QueryService, ) { super(meta, paramDef, async (ps, me) => { - const query = this.queryService.makePaginationQuery(this.followRequestsRepository.createQueryBuilder('request'), ps.sinceId, ps.untilId) + const query = this.queryService.makePaginationQuery(this.followRequestsRepository.createQueryBuilder('request'), ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate) .andWhere('request.followeeId = :meId', { meId: me.id }); const requests = await query diff --git a/packages/backend/src/server/api/endpoints/following/requests/sent.ts b/packages/backend/src/server/api/endpoints/following/requests/sent.ts index 6325f01bb8..2b3cc35f03 100644 --- a/packages/backend/src/server/api/endpoints/following/requests/sent.ts +++ b/packages/backend/src/server/api/endpoints/following/requests/sent.ts @@ -49,6 +49,8 @@ export const paramDef = { properties: { sinceId: { type: 'string', format: 'misskey:id' }, untilId: { type: 'string', format: 'misskey:id' }, + sinceDate: { type: 'integer' }, + untilDate: { type: 'integer' }, limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 }, }, required: [], @@ -64,7 +66,7 @@ export default class extends Endpoint { // eslint- private queryService: QueryService, ) { super(meta, paramDef, async (ps, me) => { - const query = this.queryService.makePaginationQuery(this.followRequestsRepository.createQueryBuilder('request'), ps.sinceId, ps.untilId) + const query = this.queryService.makePaginationQuery(this.followRequestsRepository.createQueryBuilder('request'), ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate) .andWhere('request.followerId = :meId', { meId: me.id }); const requests = await query diff --git a/packages/backend/src/server/api/endpoints/gallery/posts.ts b/packages/backend/src/server/api/endpoints/gallery/posts.ts index d398418ab4..846b903bdb 100644 --- a/packages/backend/src/server/api/endpoints/gallery/posts.ts +++ b/packages/backend/src/server/api/endpoints/gallery/posts.ts @@ -30,6 +30,8 @@ export const paramDef = { limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 }, sinceId: { type: 'string', format: 'misskey:id' }, untilId: { type: 'string', format: 'misskey:id' }, + sinceDate: { type: 'integer' }, + untilDate: { type: 'integer' }, }, required: [], } as const; @@ -44,7 +46,7 @@ export default class extends Endpoint { // eslint- private queryService: QueryService, ) { super(meta, paramDef, async (ps, me) => { - const query = this.queryService.makePaginationQuery(this.galleryPostsRepository.createQueryBuilder('post'), ps.sinceId, ps.untilId) + const query = this.queryService.makePaginationQuery(this.galleryPostsRepository.createQueryBuilder('post'), ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate) .innerJoinAndSelect('post.user', 'user'); const posts = await query.limit(ps.limit).getMany(); diff --git a/packages/backend/src/server/api/endpoints/i/apps.ts b/packages/backend/src/server/api/endpoints/i/apps.ts index 055b5cc061..523d81ac73 100644 --- a/packages/backend/src/server/api/endpoints/i/apps.ts +++ b/packages/backend/src/server/api/endpoints/i/apps.ts @@ -46,6 +46,14 @@ export const meta = { type: 'string', }, }, + iconUrl: { + type: 'string', + optional: true, nullable: true, + }, + description: { + type: 'string', + optional: true, nullable: true, + }, }, }, }, @@ -88,6 +96,8 @@ export default class extends Endpoint { // eslint- createdAt: this.idService.parse(token.id).date.toISOString(), lastUsedAt: token.lastUsedAt?.toISOString(), permission: token.app ? token.app.permission : token.permission, + iconUrl: token.iconUrl, + description: token.description ?? token.app?.description ?? null, }))); }); } diff --git a/packages/backend/src/server/api/endpoints/i/auto-delete-settings.ts b/packages/backend/src/server/api/endpoints/i/auto-delete-settings.ts new file mode 100644 index 0000000000..55ef0d7d52 --- /dev/null +++ b/packages/backend/src/server/api/endpoints/i/auto-delete-settings.ts @@ -0,0 +1,53 @@ +/* + * SPDX-FileCopyrightText: noridev and cherrypick-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { Inject, Injectable } from '@nestjs/common'; +import { Endpoint } from '@/server/api/endpoint-base.js'; +import type { UsersRepository } from '@/models/_.js'; +import { DI } from '@/di-symbols.js'; + +export const meta = { + tags: ['account'], + + requireCredential: true, + + kind: 'read:account', + + res: { + type: 'object', + properties: { + autoDeleteNotesAfterDays: { + type: 'number', + nullable: true, + }, + autoDeleteKeepFavorites: { + type: 'boolean', + }, + }, + }, +} as const; + +export const paramDef = { + type: 'object', + properties: {}, + required: [], +} as const; + +@Injectable() +export default class extends Endpoint { + constructor( + @Inject(DI.usersRepository) + private usersRepository: UsersRepository, + ) { + super(meta, paramDef, async (ps, me) => { + const user = await this.usersRepository.findOneByOrFail({ id: me.id }); + + return { + autoDeleteNotesAfterDays: user.autoDeleteNotesAfterDays, + autoDeleteKeepFavorites: user.autoDeleteKeepFavorites, + }; + }); + } +} diff --git a/packages/backend/src/server/api/endpoints/i/favorites.ts b/packages/backend/src/server/api/endpoints/i/favorites.ts index 3558035eca..00277282ba 100644 --- a/packages/backend/src/server/api/endpoints/i/favorites.ts +++ b/packages/backend/src/server/api/endpoints/i/favorites.ts @@ -34,6 +34,8 @@ export const paramDef = { limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 }, sinceId: { type: 'string', format: 'misskey:id' }, untilId: { type: 'string', format: 'misskey:id' }, + sinceDate: { type: 'integer' }, + untilDate: { type: 'integer' }, }, required: [], } as const; @@ -48,7 +50,7 @@ export default class extends Endpoint { // eslint- private queryService: QueryService, ) { super(meta, paramDef, async (ps, me) => { - const query = this.queryService.makePaginationQuery(this.noteFavoritesRepository.createQueryBuilder('favorite'), ps.sinceId, ps.untilId) + const query = this.queryService.makePaginationQuery(this.noteFavoritesRepository.createQueryBuilder('favorite'), ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate) .andWhere('favorite.userId = :meId', { meId: me.id }) .leftJoinAndSelect('favorite.note', 'note'); diff --git a/packages/backend/src/server/api/endpoints/i/followers-servers.ts b/packages/backend/src/server/api/endpoints/i/followers-servers.ts index 5460af49e4..075bf4a82d 100644 --- a/packages/backend/src/server/api/endpoints/i/followers-servers.ts +++ b/packages/backend/src/server/api/endpoints/i/followers-servers.ts @@ -1,11 +1,11 @@ /* - * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-FileCopyrightText: noridev and cherrypick-project * SPDX-License-Identifier: AGPL-3.0-only */ import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; -import type { FollowingsRepository } from '@/models/_.js'; +import type { FollowingsRepository, InstancesRepository } from '@/models/_.js'; import { DI } from '@/di-symbols.js'; export const meta = { @@ -25,6 +25,7 @@ export const meta = { optional: false, nullable: false, properties: { host: { type: 'string' }, + name: { type: 'string', nullable: true }, followersCount: { type: 'number' }, }, }, @@ -43,21 +44,28 @@ export default class extends Endpoint { // eslint- constructor( @Inject(DI.followingsRepository) private followingsRepository: FollowingsRepository, + + @Inject(DI.instancesRepository) + private instancesRepository: InstancesRepository, ) { super(meta, paramDef, async (ps, me) => { const serverStats = await this.followingsRepository .createQueryBuilder('following') .select('following.followerHost', 'host') .addSelect('COUNT(*)', 'followers_count') + .addSelect('instance.name', 'name') + .leftJoin('instance', 'instance', 'instance.host = following.followerHost') .where('following.followeeId = :userId', { userId: me.id }) .andWhere('following.followerHost IS NOT NULL') .groupBy('following.followerHost') + .addGroupBy('instance.name') .orderBy('followers_count', 'DESC') .getRawMany(); return { servers: serverStats.map(s => ({ host: s.host, + name: s.name, followersCount: Number(s.followers_count), })), }; diff --git a/packages/backend/src/server/api/endpoints/i/gallery/likes.ts b/packages/backend/src/server/api/endpoints/i/gallery/likes.ts index d492585ffa..9913ed7489 100644 --- a/packages/backend/src/server/api/endpoints/i/gallery/likes.ts +++ b/packages/backend/src/server/api/endpoints/i/gallery/likes.ts @@ -45,6 +45,8 @@ export const paramDef = { limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 }, sinceId: { type: 'string', format: 'misskey:id' }, untilId: { type: 'string', format: 'misskey:id' }, + sinceDate: { type: 'integer' }, + untilDate: { type: 'integer' }, }, required: [], } as const; @@ -59,7 +61,7 @@ export default class extends Endpoint { // eslint- private queryService: QueryService, ) { super(meta, paramDef, async (ps, me) => { - const query = this.queryService.makePaginationQuery(this.galleryLikesRepository.createQueryBuilder('like'), ps.sinceId, ps.untilId) + const query = this.queryService.makePaginationQuery(this.galleryLikesRepository.createQueryBuilder('like'), ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate) .andWhere('like.userId = :meId', { meId: me.id }) .leftJoinAndSelect('like.post', 'post'); diff --git a/packages/backend/src/server/api/endpoints/i/gallery/posts.ts b/packages/backend/src/server/api/endpoints/i/gallery/posts.ts index 73a6fcc98b..c9d17fc35c 100644 --- a/packages/backend/src/server/api/endpoints/i/gallery/posts.ts +++ b/packages/backend/src/server/api/endpoints/i/gallery/posts.ts @@ -34,6 +34,8 @@ export const paramDef = { limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 }, sinceId: { type: 'string', format: 'misskey:id' }, untilId: { type: 'string', format: 'misskey:id' }, + sinceDate: { type: 'integer' }, + untilDate: { type: 'integer' }, }, required: [], } as const; @@ -48,7 +50,7 @@ export default class extends Endpoint { // eslint- private queryService: QueryService, ) { super(meta, paramDef, async (ps, me) => { - const query = this.queryService.makePaginationQuery(this.galleryPostsRepository.createQueryBuilder('post'), ps.sinceId, ps.untilId) + const query = this.queryService.makePaginationQuery(this.galleryPostsRepository.createQueryBuilder('post'), ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate) .andWhere('post.userId = :meId', { meId: me.id }); const posts = await query diff --git a/packages/backend/src/server/api/endpoints/i/notifications-grouped.ts b/packages/backend/src/server/api/endpoints/i/notifications-grouped.ts index 6fc4011274..6ad72199b6 100644 --- a/packages/backend/src/server/api/endpoints/i/notifications-grouped.ts +++ b/packages/backend/src/server/api/endpoints/i/notifications-grouped.ts @@ -49,6 +49,8 @@ export const paramDef = { limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 }, sinceId: { type: 'string', format: 'misskey:id' }, untilId: { type: 'string', format: 'misskey:id' }, + sinceDate: { type: 'integer' }, + untilDate: { type: 'integer' }, markAsRead: { type: 'boolean', default: true }, // 後方互換のため、廃止された通知タイプも受け付ける includeTypes: { type: 'array', items: { @@ -64,15 +66,14 @@ export const paramDef = { @Injectable() export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( - @Inject(DI.redis) - private redisClient: Redis.Redis, - private idService: IdService, private notificationEntityService: NotificationEntityService, private notificationService: NotificationService, ) { super(meta, paramDef, async (ps, me) => { const EXTRA_LIMIT = 100; + const untilId = ps.untilId ?? (ps.untilDate ? this.idService.gen(ps.untilDate!) : undefined); + const sinceId = ps.sinceId ?? (ps.sinceDate ? this.idService.gen(ps.sinceDate!) : undefined); // includeTypes が空の場合はクエリしない if (ps.includeTypes && ps.includeTypes.length === 0) { @@ -87,8 +88,8 @@ export default class extends Endpoint { // eslint- const excludeTypes = ps.excludeTypes && ps.excludeTypes.filter(type => !(obsoleteNotificationTypes).includes(type as any)) as typeof groupedNotificationTypes[number][]; const notifications = await this.notificationService.getNotifications(me.id, { - sinceId: ps.sinceId, - untilId: ps.untilId, + sinceId: sinceId, + untilId: untilId, limit: ps.limit, includeTypes, excludeTypes, diff --git a/packages/backend/src/server/api/endpoints/i/notifications.ts b/packages/backend/src/server/api/endpoints/i/notifications.ts index f5a48b2f69..158cc9fd73 100644 --- a/packages/backend/src/server/api/endpoints/i/notifications.ts +++ b/packages/backend/src/server/api/endpoints/i/notifications.ts @@ -44,6 +44,8 @@ export const paramDef = { limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 }, sinceId: { type: 'string', format: 'misskey:id' }, untilId: { type: 'string', format: 'misskey:id' }, + sinceDate: { type: 'integer' }, + untilDate: { type: 'integer' }, markAsRead: { type: 'boolean', default: true }, // 後方互換のため、廃止された通知タイプも受け付ける includeTypes: { type: 'array', items: { @@ -59,17 +61,14 @@ export const paramDef = { @Injectable() export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( - @Inject(DI.redis) - private redisClient: Redis.Redis, - - @Inject(DI.notesRepository) - private notesRepository: NotesRepository, - private idService: IdService, private notificationEntityService: NotificationEntityService, private notificationService: NotificationService, ) { super(meta, paramDef, async (ps, me) => { + const untilId = ps.untilId ?? (ps.untilDate ? this.idService.gen(ps.untilDate!) : undefined); + const sinceId = ps.sinceId ?? (ps.sinceDate ? this.idService.gen(ps.sinceDate!) : undefined); + // includeTypes が空の場合はクエリしない if (ps.includeTypes && ps.includeTypes.length === 0) { return []; @@ -83,8 +82,8 @@ export default class extends Endpoint { // eslint- const excludeTypes = ps.excludeTypes && ps.excludeTypes.filter(type => !(obsoleteNotificationTypes).includes(type as any)) as typeof notificationTypes[number][]; const notifications = await this.notificationService.getNotifications(me.id, { - sinceId: ps.sinceId, - untilId: ps.untilId, + sinceId: sinceId, + untilId: untilId, limit: ps.limit, includeTypes, excludeTypes, diff --git a/packages/backend/src/server/api/endpoints/i/page-likes.ts b/packages/backend/src/server/api/endpoints/i/page-likes.ts index d4c09426a7..d62dd819f8 100644 --- a/packages/backend/src/server/api/endpoints/i/page-likes.ts +++ b/packages/backend/src/server/api/endpoints/i/page-likes.ts @@ -44,6 +44,8 @@ export const paramDef = { limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 }, sinceId: { type: 'string', format: 'misskey:id' }, untilId: { type: 'string', format: 'misskey:id' }, + sinceDate: { type: 'integer' }, + untilDate: { type: 'integer' }, }, required: [], } as const; @@ -58,7 +60,7 @@ export default class extends Endpoint { // eslint- private queryService: QueryService, ) { super(meta, paramDef, async (ps, me) => { - const query = this.queryService.makePaginationQuery(this.pageLikesRepository.createQueryBuilder('like'), ps.sinceId, ps.untilId) + const query = this.queryService.makePaginationQuery(this.pageLikesRepository.createQueryBuilder('like'), ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate) .andWhere('like.userId = :meId', { meId: me.id }) .leftJoinAndSelect('like.page', 'page'); diff --git a/packages/backend/src/server/api/endpoints/i/pages.ts b/packages/backend/src/server/api/endpoints/i/pages.ts index 1b6359a633..385842539e 100644 --- a/packages/backend/src/server/api/endpoints/i/pages.ts +++ b/packages/backend/src/server/api/endpoints/i/pages.ts @@ -34,6 +34,8 @@ export const paramDef = { limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 }, sinceId: { type: 'string', format: 'misskey:id' }, untilId: { type: 'string', format: 'misskey:id' }, + sinceDate: { type: 'integer' }, + untilDate: { type: 'integer' }, }, required: [], } as const; @@ -48,7 +50,7 @@ export default class extends Endpoint { // eslint- private queryService: QueryService, ) { super(meta, paramDef, async (ps, me) => { - const query = this.queryService.makePaginationQuery(this.pagesRepository.createQueryBuilder('page'), ps.sinceId, ps.untilId) + const query = this.queryService.makePaginationQuery(this.pagesRepository.createQueryBuilder('page'), ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate) .andWhere('page.userId = :meId', { meId: me.id }); const pages = await query diff --git a/packages/backend/src/server/api/endpoints/i/revoke-token.ts b/packages/backend/src/server/api/endpoints/i/revoke-token.ts index c05ee93c6f..08f5e3a7a1 100644 --- a/packages/backend/src/server/api/endpoints/i/revoke-token.ts +++ b/packages/backend/src/server/api/endpoints/i/revoke-token.ts @@ -15,14 +15,21 @@ export const meta = { } as const; export const paramDef = { - type: 'object', - properties: { - tokenId: { type: 'string', format: 'misskey:id' }, - token: { type: 'string', nullable: true }, - }, anyOf: [ - { required: ['tokenId'] }, - { required: ['token'] }, + { + type: 'object', + properties: { + tokenId: { type: 'string', format: 'misskey:id' }, + }, + required: ['tokenId'], + }, + { + type: 'object', + properties: { + token: { type: 'string', nullable: true }, + }, + required: ['token'], + }, ], } as const; @@ -33,7 +40,7 @@ export default class extends Endpoint { // eslint- private accessTokensRepository: AccessTokensRepository, ) { super(meta, paramDef, async (ps, me) => { - if (ps.tokenId) { + if ('tokenId' in ps) { const tokenExist = await this.accessTokensRepository.exists({ where: { id: ps.tokenId } }); if (tokenExist) { diff --git a/packages/backend/src/server/api/endpoints/i/signin-history.ts b/packages/backend/src/server/api/endpoints/i/signin-history.ts index 76ad0bbe21..c104dfdcdd 100644 --- a/packages/backend/src/server/api/endpoints/i/signin-history.ts +++ b/packages/backend/src/server/api/endpoints/i/signin-history.ts @@ -31,6 +31,8 @@ export const paramDef = { limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 }, sinceId: { type: 'string', format: 'misskey:id' }, untilId: { type: 'string', format: 'misskey:id' }, + sinceDate: { type: 'integer' }, + untilDate: { type: 'integer' }, }, required: [], } as const; @@ -45,7 +47,7 @@ export default class extends Endpoint { // eslint- private queryService: QueryService, ) { super(meta, paramDef, async (ps, me) => { - const query = this.queryService.makePaginationQuery(this.signinsRepository.createQueryBuilder('signin'), ps.sinceId, ps.untilId) + const query = this.queryService.makePaginationQuery(this.signinsRepository.createQueryBuilder('signin'), ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate) .andWhere('signin.userId = :meId', { meId: me.id }); const history = await query.limit(ps.limit).getMany(); diff --git a/packages/backend/src/server/api/endpoints/i/update-auto-delete-settings.ts b/packages/backend/src/server/api/endpoints/i/update-auto-delete-settings.ts new file mode 100644 index 0000000000..09ed063273 --- /dev/null +++ b/packages/backend/src/server/api/endpoints/i/update-auto-delete-settings.ts @@ -0,0 +1,65 @@ +/* + * SPDX-FileCopyrightText: noridev and cherrypick-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { Inject, Injectable } from '@nestjs/common'; +import { Endpoint } from '@/server/api/endpoint-base.js'; +import type { UsersRepository } from '@/models/_.js'; +import { DI } from '@/di-symbols.js'; + +export const meta = { + tags: ['account'], + + requireCredential: true, + + kind: 'write:account', + + errors: { + invalidValue: { + message: 'Invalid value.', + code: 'INVALID_VALUE', + id: 'a1b2c3d4-e5f6-7890-abcd-ef1234567890', + }, + }, +} as const; + +export const paramDef = { + type: 'object', + properties: { + autoDeleteNotesAfterDays: { + type: 'number', + nullable: true, + minimum: 1, + maximum: 3650, // 최대 10년 + }, + autoDeleteKeepFavorites: { + type: 'boolean', + }, + }, + required: [], +} as const; + +@Injectable() +export default class extends Endpoint { + constructor( + @Inject(DI.usersRepository) + private usersRepository: UsersRepository, + ) { + super(meta, paramDef, async (ps, me) => { + const updates: Record = {}; + + if (ps.autoDeleteNotesAfterDays !== undefined) { + updates.autoDeleteNotesAfterDays = ps.autoDeleteNotesAfterDays; + } + + if (ps.autoDeleteKeepFavorites !== undefined) { + updates.autoDeleteKeepFavorites = ps.autoDeleteKeepFavorites; + } + + await this.usersRepository.update(me.id, updates); + + return await this.usersRepository.findOneByOrFail({ id: me.id }); + }); + } +} diff --git a/packages/backend/src/server/api/endpoints/i/update.ts b/packages/backend/src/server/api/endpoints/i/update.ts index a50e1b0c9e..939d487a05 100644 --- a/packages/backend/src/server/api/endpoints/i/update.ts +++ b/packages/backend/src/server/api/endpoints/i/update.ts @@ -211,6 +211,8 @@ export const paramDef = { quote: notificationRecieveConfig, reaction: notificationRecieveConfig, pollEnded: notificationRecieveConfig, + scheduledNotePosted: notificationRecieveConfig, + scheduledNotePostFailed: notificationRecieveConfig, receiveFollowRequest: notificationRecieveConfig, followRequestAccepted: notificationRecieveConfig, groupInvited: notificationRecieveConfig, diff --git a/packages/backend/src/server/api/endpoints/i/webhooks/list.ts b/packages/backend/src/server/api/endpoints/i/webhooks/list.ts index 394c178f2a..8a3ba9e026 100644 --- a/packages/backend/src/server/api/endpoints/i/webhooks/list.ts +++ b/packages/backend/src/server/api/endpoints/i/webhooks/list.ts @@ -21,29 +21,7 @@ export const meta = { type: 'array', items: { type: 'object', - properties: { - id: { - type: 'string', - format: 'misskey:id', - }, - userId: { - type: 'string', - format: 'misskey:id', - }, - name: { type: 'string' }, - on: { - type: 'array', - items: { - type: 'string', - enum: webhookEventTypes, - }, - }, - url: { type: 'string' }, - secret: { type: 'string' }, - active: { type: 'boolean' }, - latestSentAt: { type: 'string', format: 'date-time', nullable: true }, - latestStatus: { type: 'integer', nullable: true }, - }, + ref: 'UserWebhook', }, }, } as const; @@ -65,19 +43,17 @@ export default class extends Endpoint { // eslint- userId: me.id, }); - return webhooks.map(webhook => ( - { - id: webhook.id, - userId: webhook.userId, - name: webhook.name, - on: webhook.on, - url: webhook.url, - secret: webhook.secret, - active: webhook.active, - latestSentAt: webhook.latestSentAt ? webhook.latestSentAt.toISOString() : null, - latestStatus: webhook.latestStatus, - } - )); + return webhooks.map(webhook => ({ + id: webhook.id, + userId: webhook.userId, + name: webhook.name, + on: webhook.on, + url: webhook.url, + secret: webhook.secret, + active: webhook.active, + latestSentAt: webhook.latestSentAt ? webhook.latestSentAt.toISOString() : null, + latestStatus: webhook.latestStatus, + })); }); } } diff --git a/packages/backend/src/server/api/endpoints/i/webhooks/show.ts b/packages/backend/src/server/api/endpoints/i/webhooks/show.ts index 4a0c09ff0c..1c19081c98 100644 --- a/packages/backend/src/server/api/endpoints/i/webhooks/show.ts +++ b/packages/backend/src/server/api/endpoints/i/webhooks/show.ts @@ -28,29 +28,7 @@ export const meta = { res: { type: 'object', - properties: { - id: { - type: 'string', - format: 'misskey:id', - }, - userId: { - type: 'string', - format: 'misskey:id', - }, - name: { type: 'string' }, - on: { - type: 'array', - items: { - type: 'string', - enum: webhookEventTypes, - }, - }, - url: { type: 'string' }, - secret: { type: 'string' }, - active: { type: 'boolean' }, - latestSentAt: { type: 'string', format: 'date-time', nullable: true }, - latestStatus: { type: 'integer', nullable: true }, - }, + ref: 'UserWebhook', }, } as const; diff --git a/packages/backend/src/server/api/endpoints/invite/list.ts b/packages/backend/src/server/api/endpoints/invite/list.ts index a99974a91e..71f8f579a5 100644 --- a/packages/backend/src/server/api/endpoints/invite/list.ts +++ b/packages/backend/src/server/api/endpoints/invite/list.ts @@ -34,6 +34,8 @@ export const paramDef = { limit: { type: 'integer', minimum: 1, maximum: 100, default: 30 }, sinceId: { type: 'string', format: 'misskey:id' }, untilId: { type: 'string', format: 'misskey:id' }, + sinceDate: { type: 'integer' }, + untilDate: { type: 'integer' }, }, required: [], } as const; @@ -48,7 +50,7 @@ export default class extends Endpoint { // eslint- private queryService: QueryService, ) { super(meta, paramDef, async (ps, me) => { - const query = this.queryService.makePaginationQuery(this.registrationTicketsRepository.createQueryBuilder('ticket'), ps.sinceId, ps.untilId) + const query = this.queryService.makePaginationQuery(this.registrationTicketsRepository.createQueryBuilder('ticket'), ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate) .andWhere('ticket.createdById = :meId', { meId: me.id }) .leftJoinAndSelect('ticket.createdBy', 'createdBy') .leftJoinAndSelect('ticket.usedBy', 'usedBy'); diff --git a/packages/backend/src/server/api/endpoints/mute/list.ts b/packages/backend/src/server/api/endpoints/mute/list.ts index 23204f2829..7762556bee 100644 --- a/packages/backend/src/server/api/endpoints/mute/list.ts +++ b/packages/backend/src/server/api/endpoints/mute/list.ts @@ -34,6 +34,8 @@ export const paramDef = { limit: { type: 'integer', minimum: 1, maximum: 100, default: 30 }, sinceId: { type: 'string', format: 'misskey:id' }, untilId: { type: 'string', format: 'misskey:id' }, + sinceDate: { type: 'integer' }, + untilDate: { type: 'integer' }, }, required: [], } as const; @@ -48,7 +50,7 @@ export default class extends Endpoint { // eslint- private queryService: QueryService, ) { super(meta, paramDef, async (ps, me) => { - const query = this.queryService.makePaginationQuery(this.mutingsRepository.createQueryBuilder('muting'), ps.sinceId, ps.untilId) + const query = this.queryService.makePaginationQuery(this.mutingsRepository.createQueryBuilder('muting'), ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate) .andWhere('muting.muterId = :meId', { meId: me.id }); const mutings = await query diff --git a/packages/backend/src/server/api/endpoints/notes.ts b/packages/backend/src/server/api/endpoints/notes.ts index d5ae17348c..29566bcdc9 100644 --- a/packages/backend/src/server/api/endpoints/notes.ts +++ b/packages/backend/src/server/api/endpoints/notes.ts @@ -36,6 +36,8 @@ export const paramDef = { limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 }, sinceId: { type: 'string', format: 'misskey:id' }, untilId: { type: 'string', format: 'misskey:id' }, + sinceDate: { type: 'integer' }, + untilDate: { type: 'integer' }, }, required: [], } as const; @@ -50,7 +52,7 @@ export default class extends Endpoint { // eslint- private queryService: QueryService, ) { super(meta, paramDef, async (ps, me) => { - const query = this.queryService.makePaginationQuery(this.notesRepository.createQueryBuilder('note'), ps.sinceId, ps.untilId) + const query = this.queryService.makePaginationQuery(this.notesRepository.createQueryBuilder('note'), ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate) .andWhere('note.visibility = \'public\'') .andWhere('note.localOnly = FALSE') .innerJoinAndSelect('note.user', 'user') diff --git a/packages/backend/src/server/api/endpoints/notes/bubble-timeline.ts b/packages/backend/src/server/api/endpoints/notes/bubble-timeline.ts index a9a215b52c..fdf5fa564f 100644 --- a/packages/backend/src/server/api/endpoints/notes/bubble-timeline.ts +++ b/packages/backend/src/server/api/endpoints/notes/bubble-timeline.ts @@ -92,13 +92,8 @@ export default class extends Endpoint { // eslint- .leftJoinAndSelect('reply.user', 'replyUser') .leftJoinAndSelect('renote.user', 'renoteUser'); - this.queryService.generateBlockedHostQueryForNote(query); - this.queryService.generateSuspendedUserQueryForNote(query); - if (me) { - this.queryService.generateMutedUserQueryForNotes(query, me); - this.queryService.generateBlockedUserQueryForNotes(query, me); - this.queryService.generateMutedUserRenotesQueryForNotes(query, me); - } + this.queryService.generateBaseNoteFilteringQuery(query, me); + if (me) this.queryService.generateMutedUserRenotesQueryForNotes(query, me); if (ps.withFiles) { query.andWhere('note.fileIds != \'{}\''); diff --git a/packages/backend/src/server/api/endpoints/notes/children.ts b/packages/backend/src/server/api/endpoints/notes/children.ts index 712a86eb13..e9d56e2892 100644 --- a/packages/backend/src/server/api/endpoints/notes/children.ts +++ b/packages/backend/src/server/api/endpoints/notes/children.ts @@ -34,6 +34,8 @@ export const paramDef = { limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 }, sinceId: { type: 'string', format: 'misskey:id' }, untilId: { type: 'string', format: 'misskey:id' }, + sinceDate: { type: 'integer' }, + untilDate: { type: 'integer' }, }, required: ['noteId'], } as const; @@ -48,7 +50,7 @@ export default class extends Endpoint { // eslint- private queryService: QueryService, ) { super(meta, paramDef, async (ps, me) => { - const query = this.queryService.makePaginationQuery(this.notesRepository.createQueryBuilder('note'), ps.sinceId, ps.untilId) + const query = this.queryService.makePaginationQuery(this.notesRepository.createQueryBuilder('note'), ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate) .andWhere(new Brackets(qb => { qb .where('note.replyId = :noteId', { noteId: ps.noteId }) @@ -70,12 +72,7 @@ export default class extends Endpoint { // eslint- .leftJoinAndSelect('renote.user', 'renoteUser'); this.queryService.generateVisibilityQuery(query, me); - this.queryService.generateBlockedHostQueryForNote(query); - this.queryService.generateSuspendedUserQueryForNote(query); - if (me) { - this.queryService.generateMutedUserQueryForNotes(query, me); - this.queryService.generateBlockedUserQueryForNotes(query, me); - } + this.queryService.generateBaseNoteFilteringQuery(query, me); const notes = await query.limit(ps.limit).getMany(); diff --git a/packages/backend/src/server/api/endpoints/notes/create.ts b/packages/backend/src/server/api/endpoints/notes/create.ts index 7d600b3b1c..e685f21efd 100644 --- a/packages/backend/src/server/api/endpoints/notes/create.ts +++ b/packages/backend/src/server/api/endpoints/notes/create.ts @@ -6,17 +6,10 @@ import ms from 'ms'; import { In } from 'typeorm'; import { Inject, Injectable } from '@nestjs/common'; -import type { MiUser } from '@/models/User.js'; -import type { UsersRepository, NotesRepository, BlockingsRepository, DriveFilesRepository, ChannelsRepository } from '@/models/_.js'; -import type { MiDriveFile } from '@/models/DriveFile.js'; -import type { MiNote } from '@/models/Note.js'; -import type { MiChannel } from '@/models/Channel.js'; import { MAX_NOTE_TEXT_LENGTH } from '@/const.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { NoteEntityService } from '@/core/entities/NoteEntityService.js'; import { NoteCreateService } from '@/core/NoteCreateService.js'; -import { DI } from '@/di-symbols.js'; -import { isQuote, isRenote } from '@/misc/is-renote.js'; import { IdentifiableError } from '@/misc/identifiable-error.js'; import { ApiError } from '../../error.js'; @@ -267,187 +260,35 @@ export const paramDef = { @Injectable() export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( - @Inject(DI.usersRepository) - private usersRepository: UsersRepository, - - @Inject(DI.notesRepository) - private notesRepository: NotesRepository, - - @Inject(DI.blockingsRepository) - private blockingsRepository: BlockingsRepository, - - @Inject(DI.driveFilesRepository) - private driveFilesRepository: DriveFilesRepository, - - @Inject(DI.channelsRepository) - private channelsRepository: ChannelsRepository, - private noteEntityService: NoteEntityService, private noteCreateService: NoteCreateService, ) { super(meta, paramDef, async (ps, me) => { - let visibleUsers: MiUser[] = []; - if (ps.visibleUserIds) { - visibleUsers = await this.usersRepository.findBy({ - id: In(ps.visibleUserIds), - }); - } - - let files: MiDriveFile[] = []; - const fileIds = ps.fileIds ?? ps.mediaIds ?? null; - if (fileIds != null) { - files = await this.driveFilesRepository.createQueryBuilder('file') - .where('file.userId = :userId AND file.id IN (:...fileIds)', { - userId: me.id, - fileIds, - }) - .orderBy('array_position(ARRAY[:...fileIds], "id"::text)') - .setParameters({ fileIds }) - .getMany(); - - if (files.length !== fileIds.length) { - throw new ApiError(meta.errors.noSuchFile); - } - } - - let renote: MiNote | null = null; - if (ps.renoteId != null) { - // Fetch renote to note - renote = await this.notesRepository.findOneBy({ id: ps.renoteId }); - - if (renote == null) { - throw new ApiError(meta.errors.noSuchRenoteTarget); - } else if (isRenote(renote) && !isQuote(renote)) { - throw new ApiError(meta.errors.cannotReRenote); - } - - // Check blocking - if (renote.userId !== me.id) { - const blockExist = await this.blockingsRepository.exists({ - where: { - blockerId: renote.userId, - blockeeId: me.id, - }, - }); - if (blockExist) { - throw new ApiError(meta.errors.youHaveBeenBlocked); - } - } - - if (renote.visibility === 'followers' && renote.userId !== me.id) { - // 他人のfollowers noteはreject - throw new ApiError(meta.errors.cannotRenoteDueToVisibility); - } else if (renote.visibility === 'specified') { - // specified / direct noteはreject - throw new ApiError(meta.errors.cannotRenoteDueToVisibility); - } - - if (renote.channelId && renote.channelId !== ps.channelId) { - // チャンネルのノートに対しリノート要求がきたとき、チャンネル外へのリノート可否をチェック - // リノートのユースケースのうち、チャンネル内→チャンネル外は少数だと考えられるため、JOINはせず必要な時に都度取得する - const renoteChannel = await this.channelsRepository.findOneBy({ id: renote.channelId }); - if (renoteChannel == null) { - // リノートしたいノートが書き込まれているチャンネルが無い - throw new ApiError(meta.errors.noSuchChannel); - } else if (!renoteChannel.allowRenoteToExternal) { - // リノート作成のリクエストだが、対象チャンネルがリノート禁止だった場合 - throw new ApiError(meta.errors.cannotRenoteOutsideOfChannel); - } - } - } - - let reply: MiNote | null = null; - if (ps.replyId != null) { - // Fetch reply - reply = await this.notesRepository.findOneBy({ id: ps.replyId }); - - if (reply == null) { - throw new ApiError(meta.errors.noSuchReplyTarget); - } else if (isRenote(reply) && !isQuote(reply)) { - throw new ApiError(meta.errors.cannotReplyToPureRenote); - } else if (!await this.noteEntityService.isVisibleForMe(reply, me.id)) { - throw new ApiError(meta.errors.cannotReplyToInvisibleNote); - } else if (reply.visibility === 'specified' && ps.visibility !== 'specified') { - throw new ApiError(meta.errors.cannotReplyToSpecifiedVisibilityNoteWithExtendedVisibility); - } - - // Check blocking - if (reply.userId !== me.id) { - const blockExist = await this.blockingsRepository.exists({ - where: { - blockerId: reply.userId, - blockeeId: me.id, - }, - }); - if (blockExist) { - throw new ApiError(meta.errors.youHaveBeenBlocked); - } - } - } - - if (ps.poll) { - if (typeof ps.poll.expiresAt === 'number') { - if (ps.poll.expiresAt < Date.now()) { - throw new ApiError(meta.errors.cannotCreateAlreadyExpiredPoll); - } - } else if (typeof ps.poll.expiredAfter === 'number') { - ps.poll.expiresAt = Date.now() + ps.poll.expiredAfter; - } - } - - if (ps.event) { - if (typeof ps.event.end === 'number') { - if (ps.event.end < Date.now()) { - throw new ApiError(meta.errors.cannotCreateAlreadyExpiredEvent); - } - } - } - - let channel: MiChannel | null = null; - if (ps.channelId != null) { - channel = await this.channelsRepository.findOneBy({ id: ps.channelId, isArchived: false }); - - if (channel == null) { - throw new ApiError(meta.errors.noSuchChannel); - } - } - - if (ps.scheduledDelete) { - if (typeof ps.scheduledDelete.deleteAt === 'number') { - if (ps.scheduledDelete.deleteAt < Date.now()) { - throw new ApiError(meta.errors.cannotScheduleDeleteEarlierThanNow); - } else if (typeof ps.scheduledDelete.deleteAfter === 'number') { - ps.scheduledDelete.deleteAt = Date.now() + ps.scheduledDelete.deleteAfter; - } - } - } - - // 投稿を作成 try { - const note = await this.noteCreateService.create(me, { + const note = await this.noteCreateService.fetchAndCreate(me, { createdAt: new Date(), - files: files, + fileIds: ps.fileIds ?? ps.mediaIds ?? [], poll: ps.poll ? { choices: ps.poll.choices, multiple: ps.poll.multiple ?? false, - expiresAt: ps.poll.expiresAt ? new Date(ps.poll.expiresAt) : null, - } : undefined, - text: ps.text ?? undefined, - reply, - renote, + expiresAt: ps.poll.expiredAfter ? new Date(Date.now() + ps.poll.expiredAfter) : ps.poll.expiresAt ? new Date(ps.poll.expiresAt) : null, + } : null, event: ps.event ? { start: new Date(ps.event.start!), end: ps.event.end ? new Date(ps.event.end) : null, title: ps.event.title!, metadata: ps.event.metadata ?? {}, - } : undefined, - cw: ps.cw, + } : null, + text: ps.text ?? null, + replyId: ps.replyId ?? null, + renoteId: ps.renoteId ?? null, + cw: ps.cw ?? null, localOnly: ps.localOnly, reactionAcceptance: ps.reactionAcceptance, disableRightClick: ps.disableRightClick, visibility: ps.visibility, - visibleUsers, - channel, + visibleUserIds: ps.visibleUserIds ?? [], + channelId: ps.channelId ?? null, apMentions: ps.noExtractMentions ? [] : undefined, apHashtags: ps.noExtractHashtags ? [] : undefined, apEmojis: ps.noExtractEmojis ? [] : undefined, @@ -458,16 +299,46 @@ export default class extends Endpoint { // eslint- return { createdNote: await this.noteEntityService.pack(note, me), }; - } catch (e) { + } catch (err) { // TODO: 他のErrorもここでキャッチしてエラーメッセージを当てるようにしたい - if (e instanceof IdentifiableError) { - if (e.id === '689ee33f-f97c-479a-ac49-1b9f8140af99') { + if (err instanceof IdentifiableError) { + if (err.id === '689ee33f-f97c-479a-ac49-1b9f8140af99') { throw new ApiError(meta.errors.containsProhibitedWords); - } else if (e.id === '9f466dab-c856-48cd-9e65-ff90ff750580') { + } else if (err.id === '9f466dab-c856-48cd-9e65-ff90ff750580') { throw new ApiError(meta.errors.containsTooManyMentions); + } else if (err.id === '801c046c-5bf5-4234-ad2b-e78fc20a2ac7') { + throw new ApiError(meta.errors.noSuchFile); + } else if (err.id === '53983c56-e163-45a6-942f-4ddc485d4290') { + throw new ApiError(meta.errors.noSuchRenoteTarget); + } else if (err.id === 'bde24c37-121f-4e7d-980d-cec52f599f02') { + throw new ApiError(meta.errors.cannotReRenote); + } else if (err.id === '2b4fe776-4414-4a2d-ae39-f3418b8fd4d3') { + throw new ApiError(meta.errors.youHaveBeenBlocked); + } else if (err.id === '90b9d6f0-893a-4fef-b0f1-e9a33989f71a') { + throw new ApiError(meta.errors.cannotRenoteDueToVisibility); + } else if (err.id === '48d7a997-da5c-4716-b3c3-92db3f37bf7d') { + throw new ApiError(meta.errors.cannotRenoteDueToVisibility); + } else if (err.id === 'b060f9a6-8909-4080-9e0b-94d9fa6f6a77') { + throw new ApiError(meta.errors.noSuchChannel); + } else if (err.id === '7e435f4a-780d-4cfc-a15a-42519bd6fb67') { + throw new ApiError(meta.errors.cannotRenoteOutsideOfChannel); + } else if (err.id === '60142edb-1519-408e-926d-4f108d27bee0') { + throw new ApiError(meta.errors.noSuchReplyTarget); + } else if (err.id === 'f089e4e2-c0e7-4f60-8a23-e5a6bf786b36') { + throw new ApiError(meta.errors.cannotReplyToPureRenote); + } else if (err.id === '11cd37b3-a411-4f77-8633-c580ce6a8dce') { + throw new ApiError(meta.errors.cannotReplyToInvisibleNote); + } else if (err.id === 'ced780a1-2012-4caf-bc7e-a95a291294cb') { + throw new ApiError(meta.errors.cannotReplyToSpecifiedVisibilityNoteWithExtendedVisibility); + } else if (err.id === 'b0df6025-f2e8-44b4-a26a-17ad99104612') { + throw new ApiError(meta.errors.youHaveBeenBlocked); + } else if (err.id === '0c11c11e-0c8d-48e7-822c-76ccef660068') { + throw new ApiError(meta.errors.cannotCreateAlreadyExpiredPoll); + } else if (err.id === 'bfa3905b-25f5-4894-b430-da331a490e4b') { + throw new ApiError(meta.errors.noSuchChannel); } } - throw e; + throw err; } }); } diff --git a/packages/backend/src/server/api/endpoints/notes/drafts/count.ts b/packages/backend/src/server/api/endpoints/notes/drafts/count.ts new file mode 100644 index 0000000000..002a545d32 --- /dev/null +++ b/packages/backend/src/server/api/endpoints/notes/drafts/count.ts @@ -0,0 +1,51 @@ +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { Inject, Injectable } from '@nestjs/common'; +import { Endpoint } from '@/server/api/endpoint-base.js'; +import type { NoteDraftsRepository } from '@/models/_.js'; +import { DI } from '@/di-symbols.js'; + +export const meta = { + tags: ['notes', 'drafts'], + + requireCredential: true, + + prohibitMoved: true, + + kind: 'read:account', + + res: { + type: 'number', + optional: false, nullable: false, + description: 'The number of drafts', + }, + + errors: { + }, +} as const; + +export const paramDef = { + type: 'object', + properties: { + }, + required: [], +} as const; + +@Injectable() +export default class extends Endpoint { // eslint-disable-line import/no-default-export + constructor( + @Inject(DI.noteDraftsRepository) + private noteDraftsRepository: NoteDraftsRepository, + ) { + super(meta, paramDef, async (ps, me) => { + const count = await this.noteDraftsRepository.createQueryBuilder('drafts') + .where('drafts.userId = :meId', { meId: me.id }) + .getCount(); + + return count; + }); + } +} diff --git a/packages/backend/src/server/api/endpoints/notes/drafts/create.ts b/packages/backend/src/server/api/endpoints/notes/drafts/create.ts index 15016712a7..29f6c90f80 100644 --- a/packages/backend/src/server/api/endpoints/notes/drafts/create.ts +++ b/packages/backend/src/server/api/endpoints/notes/drafts/create.ts @@ -3,18 +3,12 @@ * SPDX-License-Identifier: AGPL-3.0-only */ -import { Inject, Injectable } from '@nestjs/common'; +import { Injectable } from '@nestjs/common'; import ms from 'ms'; -import { In } from 'typeorm'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { NoteDraftService } from '@/core/NoteDraftService.js'; import { MAX_NOTE_TEXT_LENGTH } from '@/const.js'; -import type { MiNote, MiChannel, MiDriveFile, UsersRepository, NotesRepository, BlockingsRepository, DriveFilesRepository, ChannelsRepository } from '@/models/_.js'; -import { DI } from '@/di-symbols.js'; -import { MiUser } from '@/models/_.js'; import { ApiError } from '@/server/api/error.js'; -import { isQuote, isRenote } from '@/misc/is-renote.js'; -import { NoteEntityService } from '@/core/entities/NoteEntityService.js'; import { NoteDraftEntityService } from '@/core/entities/NoteDraftEntityService.js'; import { IdentifiableError } from '@/misc/identifiable-error.js'; @@ -136,6 +130,18 @@ export const meta = { id: '9ee33bbe-fde3-4c71-9b51-e50492c6b9c8', }, + tooManyScheduledNotes: { + message: 'You cannot create scheduled notes any more.', + code: 'TOO_MANY_SCHEDULED_NOTES', + id: '22ae69eb-09e3-4541-a850-773cfa45e693', + }, + + cannotRenoteToExternal: { + message: 'Cannot Renote to External.', + code: 'CANNOT_RENOTE_TO_EXTERNAL', + id: 'ed1952ac-2d26-4957-8b30-2deda76bedf7', + }, + cannotScheduleDeleteEarlierThanNow: { message: 'Cannot specify delete time earlier than now.', code: 'CANNOT_SCHEDULE_DELETE_EARLIER_THAN_NOW', @@ -175,7 +181,7 @@ export const paramDef = { fileIds: { type: 'array', uniqueItems: true, - minItems: 1, + minItems: 0, maxItems: 16, items: { type: 'string', format: 'misskey:id' }, }, @@ -206,6 +212,8 @@ export const paramDef = { metadata: { type: 'object' }, }, }, + scheduledAt: { type: 'integer', nullable: true }, + isActuallyScheduled: { type: 'boolean', default: false }, scheduledDelete: { type: 'object', nullable: true, @@ -214,6 +222,19 @@ export const paramDef = { deleteAfter: { type: 'integer', nullable: true, minimum: 1 }, }, }, + deliveryTargets: { + type: 'object', + nullable: true, + properties: { + mode: { type: 'string', enum: ['include', 'exclude'] }, + hosts: { + type: 'array', + items: { type: 'string' }, + uniqueItems: true, + }, + }, + required: ['mode', 'hosts'], + }, }, required: [], } as const; @@ -221,192 +242,71 @@ export const paramDef = { @Injectable() export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( - @Inject(DI.usersRepository) - private usersRepository: UsersRepository, - - @Inject(DI.notesRepository) - private notesRepository: NotesRepository, - - @Inject(DI.blockingsRepository) - private blockingsRepository: BlockingsRepository, - - @Inject(DI.driveFilesRepository) - private driveFilesRepository: DriveFilesRepository, - - @Inject(DI.channelsRepository) - private channelsRepository: ChannelsRepository, - - private noteEntityService: NoteEntityService, private noteDraftService: NoteDraftService, private noteDraftEntityService: NoteDraftEntityService, ) { super(meta, paramDef, async (ps, me) => { - // TODO: ノートendpointのバリデーションとServiceとして共通化 - let visibleUsers: MiUser[] = []; - if (ps.visibleUserIds) { - visibleUsers = await this.usersRepository.findBy({ - id: In(ps.visibleUserIds), - }); - } - - let files: MiDriveFile[] = []; - const fileIds = ps.fileIds ?? null; - if (fileIds != null) { - files = await this.driveFilesRepository.createQueryBuilder('file') - .where('file.userId = :userId AND file.id IN (:...fileIds)', { - userId: me.id, - fileIds, - }) - .orderBy('array_position(ARRAY[:...fileIds], "id"::text)') - .setParameters({ fileIds }) - .getMany(); - - if (files.length !== fileIds.length) { - throw new ApiError(meta.errors.noSuchFile); - } - } - - let renote: MiNote | null = null; - if (ps.renoteId != null) { - // Fetch renote to note - renote = await this.notesRepository.findOneBy({ id: ps.renoteId }); - - if (renote == null) { - throw new ApiError(meta.errors.noSuchRenoteTarget); - } else if (isRenote(renote) && !isQuote(renote)) { - throw new ApiError(meta.errors.cannotReRenote); - } - - // Check blocking - if (renote.userId !== me.id) { - const blockExist = await this.blockingsRepository.exists({ - where: { - blockerId: renote.userId, - blockeeId: me.id, - }, - }); - if (blockExist) { - throw new ApiError(meta.errors.youHaveBeenBlocked); - } - } - - if (renote.visibility === 'followers' && renote.userId !== me.id) { - // 他人のfollowers noteはreject - throw new ApiError(meta.errors.cannotRenoteDueToVisibility); - } else if (renote.visibility === 'specified') { - // specified / direct noteはreject - throw new ApiError(meta.errors.cannotRenoteDueToVisibility); - } - - if (renote.channelId && renote.channelId !== ps.channelId) { - // チャンネルのノートに対しリノート要求がきたとき、チャンネル外へのリノート可否をチェック - // リノートのユースケースのうち、チャンネル内→チャンネル外は少数だと考えられるため、JOINはせず必要な時に都度取得する - const renoteChannel = await this.channelsRepository.findOneBy({ id: renote.channelId }); - if (renoteChannel == null) { - // リノートしたいノートが書き込まれているチャンネルが無い - throw new ApiError(meta.errors.noSuchChannel); - } else if (!renoteChannel.allowRenoteToExternal) { - // リノート作成のリクエストだが、対象チャンネルがリノート禁止だった場合 - throw new ApiError(meta.errors.cannotRenoteOutsideOfChannel); - } - } - } - - let reply: MiNote | null = null; - if (ps.replyId != null) { - // Fetch reply - reply = await this.notesRepository.findOneBy({ id: ps.replyId }); - - if (reply == null) { - throw new ApiError(meta.errors.noSuchReplyTarget); - } else if (isRenote(reply) && !isQuote(reply)) { - throw new ApiError(meta.errors.cannotReplyToPureRenote); - } else if (!await this.noteEntityService.isVisibleForMe(reply, me.id)) { - throw new ApiError(meta.errors.cannotReplyToInvisibleNote); - } else if (reply.visibility === 'specified' && ps.visibility !== 'specified') { - throw new ApiError(meta.errors.cannotReplyToSpecifiedVisibilityNoteWithExtendedVisibility); - } - - // Check blocking - if (reply.userId !== me.id) { - const blockExist = await this.blockingsRepository.exists({ - where: { - blockerId: reply.userId, - blockeeId: me.id, - }, - }); - if (blockExist) { - throw new ApiError(meta.errors.youHaveBeenBlocked); - } - } - } - - if (ps.poll) { - if (typeof ps.poll.expiresAt === 'number') { - if (ps.poll.expiresAt < Date.now()) { - throw new ApiError(meta.errors.cannotCreateAlreadyExpiredPoll); - } - } else if (typeof ps.poll.expiredAfter === 'number') { - ps.poll.expiresAt = Date.now() + ps.poll.expiredAfter; - } - } - - if (ps.event) { - if (typeof ps.event.end === 'number') { - if (ps.event.end < Date.now()) { - throw new ApiError(meta.errors.cannotCreateAlreadyExpiredEvent); - } - } - } - - let channel: MiChannel | null = null; - if (ps.channelId != null) { - channel = await this.channelsRepository.findOneBy({ id: ps.channelId, isArchived: false }); - - if (channel == null) { - throw new ApiError(meta.errors.noSuchChannel); - } - } - - if (ps.scheduledDelete) { - if (typeof ps.scheduledDelete.deleteAt === 'number') { - if (ps.scheduledDelete.deleteAt < Date.now()) { - throw new ApiError(meta.errors.cannotScheduleDeleteEarlierThanNow); - } else if (typeof ps.scheduledDelete.deleteAfter === 'number') { - ps.scheduledDelete.deleteAt = Date.now() + ps.scheduledDelete.deleteAfter; - } - } - } - const draft = await this.noteDraftService.create(me, { - files: files, - poll: ps.poll ? { - choices: ps.poll.choices, - multiple: ps.poll.multiple ?? false, - expiresAt: ps.poll.expiresAt ? new Date(ps.poll.expiresAt) : null, - expiredAfter: ps.poll.expiredAfter ?? null, - } : undefined, + fileIds: ps.fileIds ?? [], + pollChoices: ps.poll?.choices ?? [], + pollMultiple: ps.poll?.multiple ?? false, + pollExpiresAt: ps.poll?.expiresAt ? new Date(ps.poll.expiresAt) : null, + pollExpiredAfter: ps.poll?.expiredAfter ?? null, + hasPoll: ps.poll != null, text: ps.text ?? null, - reply, - renote, - event: ps.event ? { - start: new Date(ps.event.start!), - end: ps.event.end ? new Date(ps.event.end) : null, - title: ps.event.title!, - metadata: ps.event.metadata ?? {}, - } : undefined, + replyId: ps.replyId ?? null, + renoteId: ps.renoteId ?? null, cw: ps.cw ?? null, - ...(ps.hashtag ? { hashtag: ps.hashtag } : {}), + hashtag: ps.hashtag ?? null, localOnly: ps.localOnly, reactionAcceptance: ps.reactionAcceptance, disableRightClick: ps.disableRightClick, visibility: ps.visibility, - visibleUsers, - channel, + visibleUserIds: ps.visibleUserIds ?? [], + channelId: ps.channelId ?? null, + scheduledAt: ps.scheduledAt ? new Date(ps.scheduledAt) : null, + isActuallyScheduled: ps.isActuallyScheduled, + hasEvent: ps.event != null, + eventStart: ps.event?.start ? new Date(ps.event.start) : null, + eventEnd: ps.event?.end ? new Date(ps.event.end) : null, + eventTitle: ps.event?.title ? ps.event.title! : null, + eventMetadata: ps.event?.metadata ? ps.event.metadata : null, deleteAt: ps.scheduledDelete?.deleteAt ? new Date(ps.scheduledDelete.deleteAt) : ps.scheduledDelete?.deleteAfter ? new Date(Date.now() + ps.scheduledDelete.deleteAfter) : null, + deliveryTargets: ps.deliveryTargets ?? null, }).catch((err) => { - if (err instanceof IdentifiableError && err.id === 'c9a2c1d8-d153-40be-9cac-9fc2eb56b581') { - throw new ApiError(meta.errors.tooManyDrafts); + if (err instanceof IdentifiableError) { + switch (err.id) { + case '9ee33bbe-fde3-4c71-9b51-e50492c6b9c8': + throw new ApiError(meta.errors.tooManyDrafts); + case '04da457d-b083-4055-9082-955525eda5a5': + throw new ApiError(meta.errors.cannotCreateAlreadyExpiredPoll); + case 'b6992544-63e7-67f0-fa7f-32444b1b5306': + throw new ApiError(meta.errors.noSuchFile); + case '64929870-2540-4d11-af41-3b484d78c956': + throw new ApiError(meta.errors.noSuchRenoteTarget); + case '76cc5583-5a14-4ad3-8717-0298507e32db': + throw new ApiError(meta.errors.cannotReRenote); + case '075ca298-e6e7-485a-b570-51a128bb5168': + throw new ApiError(meta.errors.youHaveBeenBlocked); + case '81eb8188-aea1-4e35-9a8f-3334a3be9855': + throw new ApiError(meta.errors.cannotRenoteDueToVisibility); + case '6815399a-6f13-4069-b60d-ed5156249d12': + throw new ApiError(meta.errors.noSuchChannel); + case 'ed1952ac-2d26-4957-8b30-2deda76bedf7': + throw new ApiError(meta.errors.cannotRenoteToExternal); + case 'c4721841-22fc-4bb7-ad3d-897ef1d375b5': + throw new ApiError(meta.errors.noSuchReplyTarget); + case 'e6c10b57-2c09-4da3-bd4d-eda05d51d140': + throw new ApiError(meta.errors.cannotReplyToPureRenote); + case '593c323c-6b6a-4501-a25c-2f36bd2a93d6': + throw new ApiError(meta.errors.cannotReplyToInvisibleNote); + case '215dbc76-336c-4d2a-9605-95766ba7dab0': + throw new ApiError(meta.errors.cannotReplyToSpecifiedVisibilityNoteWithExtendedVisibility); + case 'c3275f19-4558-4c59-83e1-4f684b5fab66': + throw new ApiError(meta.errors.tooManyScheduledNotes); + default: + throw err; + } } throw err; }); diff --git a/packages/backend/src/server/api/endpoints/notes/drafts/list.ts b/packages/backend/src/server/api/endpoints/notes/drafts/list.ts index 7594c14796..0774f09228 100644 --- a/packages/backend/src/server/api/endpoints/notes/drafts/list.ts +++ b/packages/backend/src/server/api/endpoints/notes/drafts/list.ts @@ -39,6 +39,9 @@ export const paramDef = { limit: { type: 'integer', minimum: 1, maximum: 100, default: 30 }, sinceId: { type: 'string', format: 'misskey:id' }, untilId: { type: 'string', format: 'misskey:id' }, + sinceDate: { type: 'integer' }, + untilDate: { type: 'integer' }, + scheduled: { type: 'boolean', nullable: true }, }, required: [], } as const; @@ -53,8 +56,14 @@ export default class extends Endpoint { // eslint- private noteDraftEntityService: NoteDraftEntityService, ) { super(meta, paramDef, async (ps, me) => { - const query = this.queryService.makePaginationQuery(this.noteDraftsRepository.createQueryBuilder('drafts'), ps.sinceId, ps.untilId) - .where('drafts.userId = :meId', { meId: me.id }); + const query = this.queryService.makePaginationQuery(this.noteDraftsRepository.createQueryBuilder('drafts'), ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate) + .andWhere('drafts.userId = :meId', { meId: me.id }); + + if (ps.scheduled === true) { + query.andWhere('drafts.isActuallyScheduled = true'); + } else if (ps.scheduled === false) { + query.andWhere('drafts.isActuallyScheduled = false'); + } const drafts = await query .limit(ps.limit) diff --git a/packages/backend/src/server/api/endpoints/notes/drafts/update.ts b/packages/backend/src/server/api/endpoints/notes/drafts/update.ts index 475e1d0348..3b7df9d6f9 100644 --- a/packages/backend/src/server/api/endpoints/notes/drafts/update.ts +++ b/packages/backend/src/server/api/endpoints/notes/drafts/update.ts @@ -5,17 +5,11 @@ import { Injectable } from '@nestjs/common'; import ms from 'ms'; -import { In } from 'typeorm'; -import { Inject } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { NoteDraftService } from '@/core/NoteDraftService.js'; import { MAX_NOTE_TEXT_LENGTH } from '@/const.js'; -import type { MiNote, MiChannel, MiDriveFile, UsersRepository, NotesRepository, BlockingsRepository, DriveFilesRepository, ChannelsRepository } from '@/models/_.js'; -import { isRenote, isQuote } from '@/misc/is-renote.js'; -import type { MiUser } from '@/models/User.js'; -import { DI } from '@/di-symbols.js'; -import { NoteEntityService } from '@/core/entities/NoteEntityService.js'; import { NoteDraftEntityService } from '@/core/entities/NoteDraftEntityService.js'; +import { IdentifiableError } from '@/misc/identifiable-error.js'; import { ApiError } from '../../../error.js'; export const meta = { @@ -76,9 +70,9 @@ export const meta = { id: '3ac74a84-8fd5-4bb0-870f-01804f82ce15', }, - cannotReplyToSpecifiedVisibilityNoteWithExtendedVisibility: { + cannotReplyToSpecifiedNoteWithExtendedVisibility: { message: 'You cannot reply to a specified visibility note with extended visibility.', - code: 'CANNOT_REPLY_TO_SPECIFIED_VISIBILITY_NOTE_WITH_EXTENDED_VISIBILITY', + code: 'CANNOT_REPLY_TO_SPECIFIED_NOTE_WITH_EXTENDED_VISIBILITY', id: 'ed940410-535c-4d5e-bfa3-af798671e93c', }, @@ -136,6 +130,42 @@ export const meta = { id: '56f35758-7dd5-468b-8439-5d6fb8ec9b8e', }, + noSuchRenote: { + message: 'No such renote.', + code: 'NO_SUCH_RENOTE', + id: '64929870-2540-4d11-af41-3b484d78c956', + }, + + cannotRenote: { + message: 'Cannot renote.', + code: 'CANNOT_RENOTE', + id: '76cc5583-5a14-4ad3-8717-0298507e32db', + }, + + cannotRenoteToExternal: { + message: 'Cannot Renote to External.', + code: 'CANNOT_RENOTE_TO_EXTERNAL', + id: 'ed1952ac-2d26-4957-8b30-2deda76bedf7', + }, + + noSuchReply: { + message: 'No such reply.', + code: 'NO_SUCH_REPLY', + id: 'c4721841-22fc-4bb7-ad3d-897ef1d375b5', + }, + + cannotReplyToSpecifiedVisibilityNoteWithExtendedVisibility: { + message: 'You cannot reply to a specified visibility note with extended visibility.', + code: 'CANNOT_REPLY_TO_SPECIFIED_VISIBILITY_NOTE_WITH_EXTENDED_VISIBILITY', + id: '215dbc76-336c-4d2a-9605-95766ba7dab0', + }, + + tooManyScheduledNotes: { + message: 'You cannot create scheduled notes any more.', + code: 'TOO_MANY_SCHEDULED_NOTES', + id: '02f5df79-08ae-4a33-8524-f1503c8f6212', + }, + cannotCreateAlreadyExpiredEvent: { message: 'Event is already expired.', code: 'CANNOT_CREATE_ALREADY_EXPIRED_EVENT', @@ -159,15 +189,15 @@ export const paramDef = { type: 'object', properties: { draftId: { type: 'string', nullable: false, format: 'misskey:id' }, - visibility: { type: 'string', enum: ['public', 'home', 'followers', 'specified'], default: 'public' }, + visibility: { type: 'string', enum: ['public', 'home', 'followers', 'specified'] }, visibleUserIds: { type: 'array', uniqueItems: true, items: { type: 'string', format: 'misskey:id', } }, cw: { type: 'string', nullable: true, minLength: 1, maxLength: 100 }, disableRightClick: { type: 'boolean', default: false }, hashtag: { type: 'string', nullable: true, maxLength: 200 }, - localOnly: { type: 'boolean', default: false }, - reactionAcceptance: { type: 'string', nullable: true, enum: [null, 'likeOnly', 'likeOnlyForRemote', 'nonSensitiveOnly', 'nonSensitiveOnlyForLocalLikeOnlyForRemote'], default: null }, + localOnly: { type: 'boolean' }, + reactionAcceptance: { type: 'string', nullable: true, enum: [null, 'likeOnly', 'likeOnlyForRemote', 'nonSensitiveOnly', 'nonSensitiveOnlyForLocalLikeOnlyForRemote'] }, replyId: { type: 'string', format: 'misskey:id', nullable: true }, renoteId: { type: 'string', format: 'misskey:id', nullable: true }, channelId: { type: 'string', format: 'misskey:id', nullable: true }, @@ -183,7 +213,7 @@ export const paramDef = { fileIds: { type: 'array', uniqueItems: true, - minItems: 1, + minItems: 0, maxItems: 16, items: { type: 'string', format: 'misskey:id' }, }, @@ -204,6 +234,8 @@ export const paramDef = { }, required: ['choices'], }, + scheduledAt: { type: 'integer', nullable: true }, + isActuallyScheduled: { type: 'boolean' }, event: { type: 'object', nullable: true, @@ -222,6 +254,19 @@ export const paramDef = { deleteAfter: { type: 'integer', nullable: true, minimum: 1 }, }, }, + deliveryTargets: { + type: 'object', + nullable: true, + properties: { + mode: { type: 'string', enum: ['include', 'exclude'] }, + hosts: { + type: 'array', + items: { type: 'string' }, + uniqueItems: true, + }, + }, + required: ['mode', 'hosts'], + }, }, required: ['draftId'], } as const; @@ -229,199 +274,83 @@ export const paramDef = { @Injectable() export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( - @Inject(DI.usersRepository) - private usersRepository: UsersRepository, - - @Inject(DI.notesRepository) - private notesRepository: NotesRepository, - - @Inject(DI.blockingsRepository) - private blockingsRepository: BlockingsRepository, - - @Inject(DI.driveFilesRepository) - private driveFilesRepository: DriveFilesRepository, - - @Inject(DI.channelsRepository) - private channelsRepository: ChannelsRepository, - - private noteEntityService: NoteEntityService, private noteDraftService: NoteDraftService, private noteDraftEntityService: NoteDraftEntityService, ) { super(meta, paramDef, async (ps, me) => { - const draft = await this.noteDraftService.get(me, ps.draftId); - - if (draft == null) { - throw new ApiError(meta.errors.noSuchNoteDraft); - } - - if (draft.userId !== me.id) { - throw new ApiError(meta.errors.accessDenied); - } - - // TODO: ノートendpointのバリデーションとServiceとして共通化 - let visibleUsers: MiUser[] = []; - if (ps.visibleUserIds) { - visibleUsers = await this.usersRepository.findBy({ - id: In(ps.visibleUserIds), - }); - } - - let files: MiDriveFile[] = []; - const fileIds = ps.fileIds ?? null; - if (fileIds != null) { - files = await this.driveFilesRepository.createQueryBuilder('file') - .where('file.userId = :userId AND file.id IN (:...fileIds)', { - userId: me.id, - fileIds, - }) - .orderBy('array_position(ARRAY[:...fileIds], "id"::text)') - .setParameters({ fileIds }) - .getMany(); - - if (files.length !== fileIds.length) { - throw new ApiError(meta.errors.noSuchFile); - } - } - - let renote: MiNote | null = null; - if (ps.renoteId != null) { - // Fetch renote to note - renote = await this.notesRepository.findOneBy({ id: ps.renoteId }); - - if (renote == null) { - throw new ApiError(meta.errors.noSuchRenoteTarget); - } else if (isRenote(renote) && !isQuote(renote)) { - throw new ApiError(meta.errors.cannotReRenote); - } - - // Check blocking - if (renote.userId !== me.id) { - const blockExist = await this.blockingsRepository.exists({ - where: { - blockerId: renote.userId, - blockeeId: me.id, - }, - }); - if (blockExist) { - throw new ApiError(meta.errors.youHaveBeenBlocked); - } - } - - if (renote.visibility === 'followers' && renote.userId !== me.id) { - // 他人のfollowers noteはreject - throw new ApiError(meta.errors.cannotRenoteDueToVisibility); - } else if (renote.visibility === 'specified') { - // specified / direct noteはreject - throw new ApiError(meta.errors.cannotRenoteDueToVisibility); - } - - if (renote.channelId && renote.channelId !== ps.channelId) { - // チャンネルのノートに対しリノート要求がきたとき、チャンネル外へのリノート可否をチェック - // リノートのユースケースのうち、チャンネル内→チャンネル外は少数だと考えられるため、JOINはせず必要な時に都度取得する - const renoteChannel = await this.channelsRepository.findOneBy({ id: renote.channelId }); - if (renoteChannel == null) { - // リノートしたいノートが書き込まれているチャンネルが無い - throw new ApiError(meta.errors.noSuchChannel); - } else if (!renoteChannel.allowRenoteToExternal) { - // リノート作成のリクエストだが、対象チャンネルがリノート禁止だった場合 - throw new ApiError(meta.errors.cannotRenoteOutsideOfChannel); - } - } - } - - let reply: MiNote | null = null; - if (ps.replyId != null) { - // Fetch reply - reply = await this.notesRepository.findOneBy({ id: ps.replyId }); - - if (reply == null) { - throw new ApiError(meta.errors.noSuchReplyTarget); - } else if (isRenote(reply) && !isQuote(reply)) { - throw new ApiError(meta.errors.cannotReplyToPureRenote); - } else if (!await this.noteEntityService.isVisibleForMe(reply, me.id)) { - throw new ApiError(meta.errors.cannotReplyToInvisibleNote); - } else if (reply.visibility === 'specified' && ps.visibility !== 'specified') { - throw new ApiError(meta.errors.cannotReplyToSpecifiedVisibilityNoteWithExtendedVisibility); - } - - // Check blocking - if (reply.userId !== me.id) { - const blockExist = await this.blockingsRepository.exists({ - where: { - blockerId: reply.userId, - blockeeId: me.id, - }, - }); - if (blockExist) { - throw new ApiError(meta.errors.youHaveBeenBlocked); - } - } - } - - if (ps.poll) { - if (typeof ps.poll.expiresAt === 'number') { - if (ps.poll.expiresAt < Date.now()) { - throw new ApiError(meta.errors.cannotCreateAlreadyExpiredPoll); - } - } else if (typeof ps.poll.expiredAfter === 'number') { - ps.poll.expiresAt = Date.now() + ps.poll.expiredAfter; - } - } - - if (ps.event) { - if (typeof ps.event.end === 'number') { - if (ps.event.end < Date.now()) { - throw new ApiError(meta.errors.cannotCreateAlreadyExpiredEvent); - } - } - } - - if (ps.scheduledDelete) { - if (typeof ps.scheduledDelete.deleteAt === 'number') { - if (ps.scheduledDelete.deleteAt < Date.now()) { - throw new ApiError(meta.errors.cannotScheduleDeleteEarlierThanNow); - } else if (typeof ps.scheduledDelete.deleteAfter === 'number') { - ps.scheduledDelete.deleteAt = Date.now() + ps.scheduledDelete.deleteAfter; - } - } - } - - let channel: MiChannel | null = null; - if (ps.channelId != null) { - channel = await this.channelsRepository.findOneBy({ id: ps.channelId, isArchived: false }); - - if (channel == null) { - throw new ApiError(meta.errors.noSuchChannel); - } - } - - await this.noteDraftService.update(me, draft.id, { - files: files, - poll: ps.poll ? { - choices: ps.poll.choices, - multiple: ps.poll.multiple ?? false, - expiresAt: ps.poll.expiresAt ? new Date(ps.poll.expiresAt) : null, - expiredAfter: ps.poll.expiredAfter ?? null, - } : undefined, - event: ps.event ? { - start: new Date(ps.event.start!), - end: ps.event.end ? new Date(ps.event.end) : null, - title: ps.event.title!, - metadata: ps.event.metadata ?? {}, - } : undefined, - text: ps.text ?? null, - reply, - renote, - cw: ps.cw ?? null, - ...(ps.hashtag ? { hashtag: ps.hashtag } : {}), + const draft = await this.noteDraftService.update(me, ps.draftId, { + fileIds: ps.fileIds, + pollChoices: ps.poll?.choices, + pollMultiple: ps.poll?.multiple, + pollExpiresAt: ps.poll?.expiresAt ? new Date(ps.poll.expiresAt) : null, + pollExpiredAfter: ps.poll?.expiredAfter, + text: ps.text, + replyId: ps.replyId, + renoteId: ps.renoteId, + cw: ps.cw, + hashtag: ps.hashtag, localOnly: ps.localOnly, reactionAcceptance: ps.reactionAcceptance, - visibility: ps.visibility, - visibleUsers, - channel, disableRightClick: ps.disableRightClick, + visibility: ps.visibility, + visibleUserIds: ps.visibleUserIds, + channelId: ps.channelId, + scheduledAt: ps.scheduledAt ? new Date(ps.scheduledAt) : null, + isActuallyScheduled: ps.isActuallyScheduled, + eventStart: ps.event?.start ? new Date(ps.event.start) : null, + eventEnd: ps.event?.end ? new Date(ps.event.end) : null, + eventTitle: ps.event?.title ? ps.event.title! : null, + eventMetadata: ps.event?.metadata ? ps.event.metadata : null, deleteAt: ps.scheduledDelete?.deleteAt ? new Date(ps.scheduledDelete.deleteAt) : ps.scheduledDelete?.deleteAfter ? new Date(Date.now() + ps.scheduledDelete.deleteAfter) : null, + deliveryTargets: ps.deliveryTargets, + }).catch((err) => { + if (err instanceof IdentifiableError) { + switch (err.id) { + case '49cd6b9d-848e-41ee-b0b9-adaca711a6b1': + throw new ApiError(meta.errors.noSuchNoteDraft); + case '04da457d-b083-4055-9082-955525eda5a5': + throw new ApiError(meta.errors.cannotCreateAlreadyExpiredPoll); + case 'b6992544-63e7-67f0-fa7f-32444b1b5306': + throw new ApiError(meta.errors.noSuchFile); + case '64929870-2540-4d11-af41-3b484d78c956': + throw new ApiError(meta.errors.noSuchRenote); + case '76cc5583-5a14-4ad3-8717-0298507e32db': + throw new ApiError(meta.errors.cannotRenote); + case '075ca298-e6e7-485a-b570-51a128bb5168': + throw new ApiError(meta.errors.youHaveBeenBlocked); + case '81eb8188-aea1-4e35-9a8f-3334a3be9855': + throw new ApiError(meta.errors.cannotRenoteDueToVisibility); + case '6815399a-6f13-4069-b60d-ed5156249d12': + throw new ApiError(meta.errors.noSuchChannel); + case 'ed1952ac-2d26-4957-8b30-2deda76bedf7': + throw new ApiError(meta.errors.cannotRenoteToExternal); + case 'c4721841-22fc-4bb7-ad3d-897ef1d375b5': + throw new ApiError(meta.errors.noSuchReply); + case 'e6c10b57-2c09-4da3-bd4d-eda05d51d140': + throw new ApiError(meta.errors.cannotReplyToPureRenote); + case '593c323c-6b6a-4501-a25c-2f36bd2a93d6': + throw new ApiError(meta.errors.cannotReplyToInvisibleNote); + case '215dbc76-336c-4d2a-9605-95766ba7dab0': + throw new ApiError(meta.errors.cannotReplyToSpecifiedNoteWithExtendedVisibility); + case 'b5c90186-4ab0-49c8-9bba-a1f76c282ba4': + throw new ApiError(meta.errors.noSuchRenoteTarget); + case 'fd4cc33e-2a37-48dd-99cc-9b806eb2031a': + throw new ApiError(meta.errors.cannotReRenote); + case '749ee0f6-d3da-459a-bf02-282e2da4292c': + throw new ApiError(meta.errors.noSuchReplyTarget); + case '33510210-8452-094c-6227-4a6c05d99f00': + throw new ApiError(meta.errors.cannotRenoteOutsideOfChannel); + case 'aa6e01d3-a85c-669d-758a-76aab43af334': + throw new ApiError(meta.errors.containsProhibitedWords); + case '4de0363a-3046-481b-9b0f-feff3e211025': + throw new ApiError(meta.errors.containsTooManyMentions); + case 'bacdf856-5c51-4159-b88a-804fa5103be5': + throw new ApiError(meta.errors.tooManyScheduledNotes); + default: + throw err; + } + } + throw err; }); const updatedDraft = await this.noteDraftEntityService.pack(draft, me); diff --git a/packages/backend/src/server/api/endpoints/notes/events/search.ts b/packages/backend/src/server/api/endpoints/notes/events/search.ts index 1ff4812a39..2cab7a9df0 100644 --- a/packages/backend/src/server/api/endpoints/notes/events/search.ts +++ b/packages/backend/src/server/api/endpoints/notes/events/search.ts @@ -112,7 +112,11 @@ export default class extends Endpoint { // eslint- query .innerJoinAndSelect(MiEvent, 'event', 'event.noteId = note.id') - .innerJoinAndSelect('note.user', 'user'); + .innerJoinAndSelect('note.user', 'user') + .leftJoinAndSelect('note.reply', 'reply') + .leftJoinAndSelect('note.renote', 'renote') + .leftJoinAndSelect('reply.user', 'replyUser') + .leftJoinAndSelect('renote.user', 'renoteUser'); if (ps.query && ps.query.trim() !== '') { query.andWhere(new Brackets((qb) => { @@ -161,10 +165,7 @@ export default class extends Endpoint { // eslint- } this.queryService.generateVisibilityQuery(query, me); - this.queryService.generateBlockedHostQueryForNote(query); - this.queryService.generateSuspendedUserQueryForNote(query); - if (me) this.queryService.generateMutedUserQueryForNotes(query, me); - if (me) this.queryService.generateBlockedUserQueryForNotes(query, me); + this.queryService.generateBaseNoteFilteringQuery(query, me); if (ps.offset) query.skip(ps.offset); diff --git a/packages/backend/src/server/api/endpoints/notes/global-timeline.ts b/packages/backend/src/server/api/endpoints/notes/global-timeline.ts index ffd9757268..d2964780cf 100644 --- a/packages/backend/src/server/api/endpoints/notes/global-timeline.ts +++ b/packages/backend/src/server/api/endpoints/notes/global-timeline.ts @@ -79,11 +79,8 @@ export default class extends Endpoint { // eslint- .leftJoinAndSelect('reply.user', 'replyUser') .leftJoinAndSelect('renote.user', 'renoteUser'); - if (me) { - this.queryService.generateMutedUserQueryForNotes(query, me); - this.queryService.generateBlockedUserQueryForNotes(query, me); - this.queryService.generateMutedUserRenotesQueryForNotes(query, me); - } + this.queryService.generateBaseNoteFilteringQuery(query, me); + if (me) this.queryService.generateMutedUserRenotesQueryForNotes(query, me); if (ps.withFiles) { query.andWhere('note.fileIds != \'{}\''); @@ -95,6 +92,7 @@ export default class extends Endpoint { // eslint- qb.orWhere(new Brackets(qb => { qb.where('note.text IS NOT NULL'); qb.orWhere('note.fileIds != \'{}\''); + qb.orWhere('0 < (SELECT COUNT(*) FROM poll WHERE poll."noteId" = note.id)'); })); })); } diff --git a/packages/backend/src/server/api/endpoints/notes/history.ts b/packages/backend/src/server/api/endpoints/notes/history.ts new file mode 100644 index 0000000000..7adc072902 --- /dev/null +++ b/packages/backend/src/server/api/endpoints/notes/history.ts @@ -0,0 +1,74 @@ +/* + * SPDX-FileCopyrightText: noridev and cherrypick-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import ms from 'ms'; +import { Inject, Injectable } from '@nestjs/common'; +import { Endpoint } from '@/server/api/endpoint-base.js'; +import { NoteEntityService } from '@/core/entities/NoteEntityService.js'; +import { NoteUpdateService } from '@/core/NoteUpdateService.js'; +import { DI } from '@/di-symbols.js'; +import { GetterService } from '@/server/api/GetterService.js'; +import { MAX_NOTE_TEXT_LENGTH } from '@/const.js'; +import type { DriveFilesRepository, MiDriveFile } from '@/models/_.js'; +import { NoteHistoryEntityService } from '@/core/entities/NoteHistoryEntityService.js'; +import { NoteHistorySerivce } from '@/core/NoteHistoryService.js'; +import { ApiError } from '../../error.js'; + +export const meta = { + tags: ['notes'], + + requireCredential: false, + + stability: 'experimental', + + errors: { + noSuchNote: { + message: 'No such note.', + code: 'NO_SUCH_NOTE', + id: '596e916b-c4d7-45f2-9d49-ecbbb99ac1c0', + }, + }, + res: { + type: 'array', + optional: false, nullable: false, + items: { + type: 'object', + optional: false, nullable: false, + ref: 'NoteHistory', + }, + }, +} as const; + +export const paramDef = { + type: 'object', + properties: { + noteId: { type: 'string', format: 'misskey:id' }, + limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 }, + sinceId: { type: 'string', format: 'misskey:id' }, + untilId: { type: 'string', format: 'misskey:id' }, + }, + required: ['noteId'], +} as const; + +@Injectable() +export default class extends Endpoint { // eslint-disable-line import/no-default-export + constructor( + private noteHistoryEntityService: NoteHistoryEntityService, + private noteHistoryService: NoteHistorySerivce, + private getterService: GetterService, + ) { + super(meta, paramDef, async (ps, me) => { + const note = await this.getterService.getNote(ps.noteId).catch(err => { + if (err.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError(meta.errors.noSuchNote); + throw err; + }); + const note_history = await this.noteHistoryService.getHistory(note.id, ps.limit, ps.sinceId, ps.untilId); + if (!note_history) { + return []; + } + return await this.noteHistoryEntityService.packMany(note_history, note.userHost, me); + }); + } +} diff --git a/packages/backend/src/server/api/endpoints/notes/hybrid-timeline.ts b/packages/backend/src/server/api/endpoints/notes/hybrid-timeline.ts index 59f13da63d..63f8059b40 100644 --- a/packages/backend/src/server/api/endpoints/notes/hybrid-timeline.ts +++ b/packages/backend/src/server/api/endpoints/notes/hybrid-timeline.ts @@ -248,10 +248,7 @@ export default class extends Endpoint { // eslint- } this.queryService.generateVisibilityQuery(query, me); - this.queryService.generateBlockedHostQueryForNote(query); - this.queryService.generateSuspendedUserQueryForNote(query); - this.queryService.generateMutedUserQueryForNotes(query, me); - this.queryService.generateBlockedUserQueryForNotes(query, me); + this.queryService.generateBaseNoteFilteringQuery(query, me); this.queryService.generateMutedUserRenotesQueryForNotes(query, me); if (ps.includeMyRenotes === false) { diff --git a/packages/backend/src/server/api/endpoints/notes/local-timeline.ts b/packages/backend/src/server/api/endpoints/notes/local-timeline.ts index 0c4c789ada..3a715d1c9f 100644 --- a/packages/backend/src/server/api/endpoints/notes/local-timeline.ts +++ b/packages/backend/src/server/api/endpoints/notes/local-timeline.ts @@ -161,10 +161,7 @@ export default class extends Endpoint { // eslint- .leftJoinAndSelect('renote.user', 'renoteUser'); this.queryService.generateVisibilityQuery(query, me); - this.queryService.generateBlockedHostQueryForNote(query); - this.queryService.generateSuspendedUserQueryForNote(query); - if (me) this.queryService.generateMutedUserQueryForNotes(query, me); - if (me) this.queryService.generateBlockedUserQueryForNotes(query, me); + this.queryService.generateBaseNoteFilteringQuery(query, me); if (me) this.queryService.generateMutedUserRenotesQueryForNotes(query, me); if (ps.withFiles) { diff --git a/packages/backend/src/server/api/endpoints/notes/mentions.ts b/packages/backend/src/server/api/endpoints/notes/mentions.ts index c3722b1b5a..e775bdb7fd 100644 --- a/packages/backend/src/server/api/endpoints/notes/mentions.ts +++ b/packages/backend/src/server/api/endpoints/notes/mentions.ts @@ -35,6 +35,8 @@ export const paramDef = { limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 }, sinceId: { type: 'string', format: 'misskey:id' }, untilId: { type: 'string', format: 'misskey:id' }, + sinceDate: { type: 'integer' }, + untilDate: { type: 'integer' }, visibility: { type: 'string' }, }, required: [], @@ -57,14 +59,14 @@ export default class extends Endpoint { // eslint- .select('following.followeeId') .where('following.followerId = :followerId', { followerId: me.id }); - const query = this.queryService.makePaginationQuery(this.notesRepository.createQueryBuilder('note'), ps.sinceId, ps.untilId) + const query = this.queryService.makePaginationQuery(this.notesRepository.createQueryBuilder('note'), ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate) .andWhere(new Brackets(qb => { qb // このmeIdAsListパラメータはqueryServiceのgenerateVisibilityQueryでセットされる .where(':meIdAsList <@ note.mentions') .orWhere(':meIdAsList <@ note.visibleUserIds'); })) // Avoid scanning primary key index - .orderBy('CONCAT(note.id)', 'DESC') + .orderBy('CONCAT(note.id)', (ps.sinceDate || ps.sinceId) ? 'ASC' : 'DESC') .innerJoinAndSelect('note.user', 'user') .leftJoinAndSelect('note.reply', 'reply') .leftJoinAndSelect('note.renote', 'renote') @@ -72,11 +74,8 @@ export default class extends Endpoint { // eslint- .leftJoinAndSelect('renote.user', 'renoteUser'); this.queryService.generateVisibilityQuery(query, me); - this.queryService.generateBlockedHostQueryForNote(query); - this.queryService.generateSuspendedUserQueryForNote(query); - this.queryService.generateMutedUserQueryForNotes(query, me); + this.queryService.generateBaseNoteFilteringQuery(query, me); this.queryService.generateMutedNoteThreadQuery(query, me); - this.queryService.generateBlockedUserQueryForNotes(query, me); if (ps.visibility) { query.andWhere('note.visibility = :visibility', { visibility: ps.visibility }); diff --git a/packages/backend/src/server/api/endpoints/notes/reactions.ts b/packages/backend/src/server/api/endpoints/notes/reactions.ts index 97b12ab7f7..e5e15fd4b3 100644 --- a/packages/backend/src/server/api/endpoints/notes/reactions.ts +++ b/packages/backend/src/server/api/endpoints/notes/reactions.ts @@ -47,6 +47,8 @@ export const paramDef = { limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 }, sinceId: { type: 'string', format: 'misskey:id' }, untilId: { type: 'string', format: 'misskey:id' }, + sinceDate: { type: 'integer' }, + untilDate: { type: 'integer' }, }, required: ['noteId'], } as const; @@ -61,7 +63,7 @@ export default class extends Endpoint { // eslint- private queryService: QueryService, ) { super(meta, paramDef, async (ps, me) => { - const query = this.queryService.makePaginationQuery(this.noteReactionsRepository.createQueryBuilder('reaction'), ps.sinceId, ps.untilId) + const query = this.queryService.makePaginationQuery(this.noteReactionsRepository.createQueryBuilder('reaction'), ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate) .andWhere('reaction.noteId = :noteId', { noteId: ps.noteId }) .leftJoinAndSelect('reaction.user', 'user') .leftJoinAndSelect('reaction.note', 'note'); diff --git a/packages/backend/src/server/api/endpoints/notes/renotes.ts b/packages/backend/src/server/api/endpoints/notes/renotes.ts index ce2435b8eb..b294794de6 100644 --- a/packages/backend/src/server/api/endpoints/notes/renotes.ts +++ b/packages/backend/src/server/api/endpoints/notes/renotes.ts @@ -43,6 +43,8 @@ export const paramDef = { limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 }, sinceId: { type: 'string', format: 'misskey:id' }, untilId: { type: 'string', format: 'misskey:id' }, + sinceDate: { type: 'integer' }, + untilDate: { type: 'integer' }, }, required: ['noteId'], } as const; @@ -63,7 +65,7 @@ export default class extends Endpoint { // eslint- throw err; }); - const query = this.queryService.makePaginationQuery(this.notesRepository.createQueryBuilder('note'), ps.sinceId, ps.untilId) + const query = this.queryService.makePaginationQuery(this.notesRepository.createQueryBuilder('note'), ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate) .andWhere('note.renoteId = :renoteId', { renoteId: note.id }) .innerJoinAndSelect('note.user', 'user') .leftJoinAndSelect('note.reply', 'reply') @@ -72,10 +74,7 @@ export default class extends Endpoint { // eslint- .leftJoinAndSelect('renote.user', 'renoteUser'); this.queryService.generateVisibilityQuery(query, me); - this.queryService.generateBlockedHostQueryForNote(query); - this.queryService.generateSuspendedUserQueryForNote(query); - if (me) this.queryService.generateMutedUserQueryForNotes(query, me); - if (me) this.queryService.generateBlockedUserQueryForNotes(query, me); + this.queryService.generateBaseNoteFilteringQuery(query, me); const renotes = await query.limit(ps.limit).getMany(); diff --git a/packages/backend/src/server/api/endpoints/notes/replies.ts b/packages/backend/src/server/api/endpoints/notes/replies.ts index f491cc38ab..d567d7c64a 100644 --- a/packages/backend/src/server/api/endpoints/notes/replies.ts +++ b/packages/backend/src/server/api/endpoints/notes/replies.ts @@ -32,6 +32,8 @@ export const paramDef = { noteId: { type: 'string', format: 'misskey:id' }, sinceId: { type: 'string', format: 'misskey:id' }, untilId: { type: 'string', format: 'misskey:id' }, + sinceDate: { type: 'integer' }, + untilDate: { type: 'integer' }, limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 }, }, required: ['noteId'], @@ -47,7 +49,7 @@ export default class extends Endpoint { // eslint- private queryService: QueryService, ) { super(meta, paramDef, async (ps, me) => { - const query = this.queryService.makePaginationQuery(this.notesRepository.createQueryBuilder('note'), ps.sinceId, ps.untilId) + const query = this.queryService.makePaginationQuery(this.notesRepository.createQueryBuilder('note'), ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate) .andWhere('note.replyId = :replyId', { replyId: ps.noteId }) .innerJoinAndSelect('note.user', 'user') .leftJoinAndSelect('note.reply', 'reply') @@ -56,10 +58,7 @@ export default class extends Endpoint { // eslint- .leftJoinAndSelect('renote.user', 'renoteUser'); this.queryService.generateVisibilityQuery(query, me); - this.queryService.generateBlockedHostQueryForNote(query); - this.queryService.generateSuspendedUserQueryForNote(query); - if (me) this.queryService.generateMutedUserQueryForNotes(query, me); - if (me) this.queryService.generateBlockedUserQueryForNotes(query, me); + this.queryService.generateBaseNoteFilteringQuery(query, me); const timeline = await query.limit(ps.limit).getMany(); diff --git a/packages/backend/src/server/api/endpoints/notes/schedule/create.ts b/packages/backend/src/server/api/endpoints/notes/schedule/create.ts deleted file mode 100644 index 41484869cb..0000000000 --- a/packages/backend/src/server/api/endpoints/notes/schedule/create.ts +++ /dev/null @@ -1,466 +0,0 @@ -/* - * SPDX-FileCopyrightText: syuilo and misskey-project - * SPDX-License-Identifier: AGPL-3.0-only - */ - -import ms from 'ms'; -import { In } from 'typeorm'; -import { Inject, Injectable } from '@nestjs/common'; -import { isPureRenote } from 'cherrypick-js/note.js'; -import type { MiUser } from '@/models/User.js'; -import type { - UsersRepository, - NotesRepository, - BlockingsRepository, - DriveFilesRepository, - ChannelsRepository, - NoteScheduleRepository, - MiChannel, -} from '@/models/_.js'; -import type { MiDriveFile } from '@/models/DriveFile.js'; -import type { MiNote } from '@/models/Note.js'; -import { MAX_NOTE_TEXT_LENGTH } from '@/const.js'; -import { Endpoint } from '@/server/api/endpoint-base.js'; -import { DI } from '@/di-symbols.js'; -import { QueueService } from '@/core/QueueService.js'; -import { IdService } from '@/core/IdService.js'; -import { MiScheduleNoteType } from '@/models/NoteSchedule.js'; -import { RoleService } from '@/core/RoleService.js'; -import { ApiError } from '../../../error.js'; - -export const meta = { - tags: ['notes'], - - requireCredential: true, - - prohibitMoved: true, - - limit: { - duration: ms('1hour'), - max: 300, - }, - - kind: 'write:notes-schedule', - - errors: { - scheduleNoteMax: { - message: 'Schedule note max.', - code: 'SCHEDULE_NOTE_MAX', - id: '168707c3-e7da-4031-989e-f42aa3a274b2', - }, - noSuchRenoteTarget: { - message: 'No such renote target.', - code: 'NO_SUCH_RENOTE_TARGET', - id: 'b5c90186-4ab0-49c8-9bba-a1f76c282ba4', - }, - - cannotReRenote: { - message: 'You can not Renote a pure Renote.', - code: 'CANNOT_RENOTE_TO_A_PURE_RENOTE', - id: 'fd4cc33e-2a37-48dd-99cc-9b806eb2031a', - }, - - cannotRenoteDueToVisibility: { - message: 'You can not Renote due to target visibility.', - code: 'CANNOT_RENOTE_DUE_TO_VISIBILITY', - id: 'be9529e9-fe72-4de0-ae43-0b363c4938af', - }, - - noSuchReplyTarget: { - message: 'No such reply target.', - code: 'NO_SUCH_REPLY_TARGET', - id: '749ee0f6-d3da-459a-bf02-282e2da4292c', - }, - - cannotReplyToPureRenote: { - message: 'You can not reply to a pure Renote.', - code: 'CANNOT_REPLY_TO_A_PURE_RENOTE', - id: '3ac74a84-8fd5-4bb0-870f-01804f82ce15', - }, - - cannotCreateAlreadyExpiredPoll: { - message: 'Poll is already expired.', - code: 'CANNOT_CREATE_ALREADY_EXPIRED_POLL', - id: '04da457d-b083-4055-9082-955525eda5a5', - }, - - cannotCreateAlreadyExpiredEvent: { - message: 'Event is already expired.', - code: 'CANNOT_CREATE_ALREADY_EXPIRED_EVENT', - id: 'a80c5545-5126-421e-969b-35c3eb2c3646', - }, - - cannotCreateAlreadyExpiredSchedule: { - message: 'Schedule is already expired.', - code: 'CANNOT_CREATE_ALREADY_EXPIRED_SCHEDULE', - id: '8a9bfb90-fc7e-4878-a3e8-d97faaf5fb07', - }, - - noSuchChannel: { - message: 'No such channel.', - code: 'NO_SUCH_CHANNEL', - id: 'b1653923-5453-4edc-b786-7c4f39bb0bbb', - }, - - noSuchSchedule: { - message: 'No such schedule.', - code: 'NO_SUCH_SCHEDULE', - id: '44dee229-8da1-4a61-856d-e3a4bbc12032', - }, - - cannotScheduleDeleteEarlierThanNow: { - message: 'Cannot specify delete time earlier than now.', - code: 'CANNOT_SCHEDULE_DELETE_EARLIER_THAN_NOW', - id: '9f04994a-3aa2-11ef-a495-177eea74788f', - }, - - youHaveBeenBlocked: { - message: 'You have been blocked by this user.', - code: 'YOU_HAVE_BEEN_BLOCKED', - id: 'b390d7e1-8a5e-46ed-b625-06271cafd3d3', - }, - - noSuchFile: { - message: 'Some files are not found.', - code: 'NO_SUCH_FILE', - id: 'b6992544-63e7-67f0-fa7f-32444b1b5306', - }, - - cannotRenoteOutsideOfChannel: { - message: 'Cannot renote outside of channel.', - code: 'CANNOT_RENOTE_OUTSIDE_OF_CHANNEL', - id: '33510210-8452-094c-6227-4a6c05d99f00', - }, - }, -} as const; - -export const paramDef = { - type: 'object', - properties: { - visibility: { type: 'string', enum: ['public', 'home', 'followers', 'specified'], default: 'public' }, - visibleUserIds: { type: 'array', uniqueItems: true, items: { - type: 'string', format: 'misskey:id', - } }, - cw: { type: 'string', nullable: true, minLength: 1, maxLength: 100 }, - reactionAcceptance: { type: 'string', nullable: true, enum: [null, 'likeOnly', 'likeOnlyForRemote', 'nonSensitiveOnly', 'nonSensitiveOnlyForLocalLikeOnlyForRemote'], default: null }, - disableRightClick: { type: 'boolean', default: false }, - noExtractMentions: { type: 'boolean', default: false }, - noExtractHashtags: { type: 'boolean', default: false }, - noExtractEmojis: { type: 'boolean', default: false }, - replyId: { type: 'string', format: 'misskey:id', nullable: true }, - renoteId: { type: 'string', format: 'misskey:id', nullable: true }, - channelId: { type: 'string', format: 'misskey:id', nullable: true }, - localOnly: { type: 'boolean', default: false }, - - // anyOf内にバリデーションを書いても最初の一つしかチェックされない - // See https://github.com/misskey-dev/misskey/pull/10082 - text: { - type: 'string', - minLength: 1, - maxLength: MAX_NOTE_TEXT_LENGTH, - nullable: true, - }, - fileIds: { - type: 'array', - uniqueItems: true, - minItems: 1, - maxItems: 16, - items: { type: 'string', format: 'misskey:id' }, - }, - mediaIds: { - type: 'array', - uniqueItems: true, - minItems: 1, - maxItems: 16, - items: { type: 'string', format: 'misskey:id' }, - }, - poll: { - type: 'object', - nullable: true, - properties: { - choices: { - type: 'array', - uniqueItems: true, - minItems: 2, - maxItems: 10, - items: { type: 'string', minLength: 1, maxLength: 50 }, - }, - multiple: { type: 'boolean' }, - expiresAt: { type: 'integer', nullable: true }, - expiredAfter: { type: 'integer', nullable: true, minimum: 1 }, - }, - required: ['choices'], - }, - event: { - type: 'object', - nullable: true, - properties: { - title: { type: 'string', minLength: 1, maxLength: 128, nullable: false }, - start: { type: 'integer', nullable: false }, - end: { type: 'integer', nullable: true }, - metadata: { type: 'object' }, - }, - }, - scheduleNote: { - type: 'object', - nullable: false, - properties: { - scheduledAt: { type: 'integer', nullable: false }, - }, - }, - scheduledDelete: { - type: 'object', - nullable: true, - properties: { - deleteAt: { type: 'integer', nullable: true }, - deleteAfter: { type: 'integer', nullable: true, minimum: 1 }, - }, - }, - deliveryTargets: { - type: 'object', - nullable: true, - properties: { - mode: { type: 'string', enum: ['include', 'exclude'] }, - hosts: { - type: 'array', - items: { type: 'string' }, - uniqueItems: true, - }, - }, - required: ['mode', 'hosts'], - }, - }, - // (re)note with text, files and poll are optional - anyOf: [ - { required: ['text'] }, - { required: ['renoteId'] }, - { required: ['fileIds'] }, - { required: ['mediaIds'] }, - { required: ['poll'] }, - ], - required: ['scheduleNote'], -} as const; - -@Injectable() -export default class extends Endpoint { // eslint-disable-line import/no-default-export - constructor( - @Inject(DI.usersRepository) - private usersRepository: UsersRepository, - - @Inject(DI.notesRepository) - private notesRepository: NotesRepository, - - @Inject(DI.noteScheduleRepository) - private noteScheduleRepository: NoteScheduleRepository, - - @Inject(DI.blockingsRepository) - private blockingsRepository: BlockingsRepository, - - @Inject(DI.driveFilesRepository) - private driveFilesRepository: DriveFilesRepository, - - @Inject(DI.channelsRepository) - private channelsRepository: ChannelsRepository, - - private queueService: QueueService, - private roleService: RoleService, - private idService: IdService, - ) { - super({ - ...meta, - }, paramDef, async (ps, me) => { - const scheduleNoteCount = await this.noteScheduleRepository.countBy({ userId: me.id }); - const scheduleNoteMax = (await this.roleService.getUserPolicies(me.id)).scheduleNoteMax; - if (scheduleNoteCount >= scheduleNoteMax) { - throw new ApiError(meta.errors.scheduleNoteMax); - } - let visibleUsers: MiUser[] = []; - if (ps.visibleUserIds) { - visibleUsers = await this.usersRepository.findBy({ - id: In(ps.visibleUserIds), - }); - } - - let files: MiDriveFile[] = []; - const fileIds = ps.fileIds ?? ps.mediaIds ?? null; - if (fileIds != null) { - files = await this.driveFilesRepository.createQueryBuilder('file') - .where('file.userId = :userId AND file.id IN (:...fileIds)', { - userId: me.id, - fileIds, - }) - .orderBy('array_position(ARRAY[:...fileIds], "id"::text)') - .setParameters({ fileIds }) - .getMany(); - - if (files.length !== fileIds.length) { - throw new ApiError(meta.errors.noSuchFile); - } - } - - let renote: MiNote | null = null; - if (ps.renoteId != null) { - // Fetch renote to note - renote = await this.notesRepository.findOneBy({ id: ps.renoteId }); - - if (renote == null) { - throw new ApiError(meta.errors.noSuchRenoteTarget); - } else if (isPureRenote(renote)) { - throw new ApiError(meta.errors.cannotReRenote); - } - - // Check blocking - if (renote.userId !== me.id) { - const blockExist = await this.blockingsRepository.exist({ - where: { - blockerId: renote.userId, - blockeeId: me.id, - }, - }); - if (blockExist) { - throw new ApiError(meta.errors.youHaveBeenBlocked); - } - } - - if (renote.visibility === 'followers' && renote.userId !== me.id) { - // 他人のfollowers noteはreject - throw new ApiError(meta.errors.cannotRenoteDueToVisibility); - } else if (renote.visibility === 'specified') { - // specified / direct noteはreject - throw new ApiError(meta.errors.cannotRenoteDueToVisibility); - } - } - - let reply: MiNote | null = null; - if (ps.replyId != null) { - // Fetch reply - reply = await this.notesRepository.findOneBy({ id: ps.replyId }); - - if (reply == null) { - throw new ApiError(meta.errors.noSuchReplyTarget); - } else if (isPureRenote(reply)) { - throw new ApiError(meta.errors.cannotReplyToPureRenote); - } - - // Check blocking - if (reply.userId !== me.id) { - const blockExist = await this.blockingsRepository.exist({ - where: { - blockerId: reply.userId, - blockeeId: me.id, - }, - }); - if (blockExist) { - throw new ApiError(meta.errors.youHaveBeenBlocked); - } - } - } - - if (ps.poll) { - let scheduleNote_scheduledAt = Date.now(); - if (typeof ps.scheduleNote.scheduledAt === 'number') { - scheduleNote_scheduledAt = ps.scheduleNote.scheduledAt; - } - if (typeof ps.poll.expiresAt === 'number') { - if (ps.poll.expiresAt < scheduleNote_scheduledAt) { - throw new ApiError(meta.errors.cannotCreateAlreadyExpiredPoll); - } - } else if (typeof ps.poll.expiredAfter === 'number') { - ps.poll.expiresAt = scheduleNote_scheduledAt + ps.poll.expiredAfter; - } - } - - if (ps.event) { - let scheduleNote_scheduledAt = Date.now(); - if (typeof ps.scheduleNote.scheduledAt === 'number') { - scheduleNote_scheduledAt = ps.scheduleNote.scheduledAt; - } - if (typeof ps.event.end === 'number') { - if (ps.event.end < Date.now() || ps.event.end < scheduleNote_scheduledAt) { - throw new ApiError(meta.errors.cannotCreateAlreadyExpiredEvent); - } - } - } - - let channel: MiChannel | null = null; - if (ps.channelId != null) { - channel = await this.channelsRepository.findOneBy({ id: ps.channelId, isArchived: false }); - - if (channel == null) { - throw new ApiError(meta.errors.noSuchChannel); - } - } - - if (typeof ps.scheduleNote.scheduledAt === 'number') { - if (ps.scheduleNote.scheduledAt < Date.now()) { - throw new ApiError(meta.errors.cannotCreateAlreadyExpiredSchedule); - } - } else { - throw new ApiError(meta.errors.cannotCreateAlreadyExpiredSchedule); - } - - if (ps.scheduledDelete) { - if (typeof ps.scheduledDelete.deleteAt === 'number') { - if (ps.scheduledDelete.deleteAt < Date.now()) { - throw new ApiError(meta.errors.cannotScheduleDeleteEarlierThanNow); - } else if (typeof ps.scheduledDelete.deleteAfter === 'number') { - ps.scheduledDelete.deleteAt = Date.now() + ps.scheduledDelete.deleteAfter; - } - } - } - - const note: MiScheduleNoteType = { - createdAt: new Date(ps.scheduleNote.scheduledAt!).toISOString(), - files: files.map(f => f.id), - poll: ps.poll ? { - choices: ps.poll.choices, - multiple: ps.poll.multiple ?? false, - expiresAt: ps.poll.expiresAt ? new Date(ps.poll.expiresAt).toISOString() : null, - } : undefined, - text: ps.text ?? undefined, - reply: reply?.id, - renote: renote?.id, - cw: ps.cw, - localOnly: ps.localOnly, - reactionAcceptance: ps.reactionAcceptance, - visibility: ps.visibility, - visibleUsers, - channel: channel?.id, - apMentions: ps.noExtractMentions ? [] : undefined, - apHashtags: ps.noExtractHashtags ? [] : undefined, - apEmojis: ps.noExtractEmojis ? [] : undefined, - event: ps.event ? { - start: new Date(ps.event.start!).toISOString(), - end: ps.event.end ? new Date(ps.event.end).toISOString() : null, - title: ps.event.title!, - metadata: ps.event.metadata ?? {}, - } : undefined, - disableRightClick: ps.disableRightClick, - deleteAt: ps.scheduledDelete?.deleteAt ? new Date(ps.scheduledDelete.deleteAt) : ps.scheduledDelete?.deleteAfter ? new Date(Date.now() + ps.scheduledDelete.deleteAfter) : null, - deliveryTargets: ps.deliveryTargets, - }; - - if (ps.scheduleNote.scheduledAt) { - me.token = null; - const noteId = this.idService.gen(new Date().getTime()); - await this.noteScheduleRepository.insert({ - id: noteId, - note: note, - userId: me.id, - scheduledAt: new Date(ps.scheduleNote.scheduledAt), - }); - - const delay = new Date(ps.scheduleNote.scheduledAt).getTime() - Date.now(); - await this.queueService.ScheduleNotePostQueue.add(String(delay), { - scheduleNoteId: noteId, - }, { - delay, - removeOnComplete: true, - jobId: noteId, - }); - } - - return ''; - }); - } -} diff --git a/packages/backend/src/server/api/endpoints/notes/schedule/delete.ts b/packages/backend/src/server/api/endpoints/notes/schedule/delete.ts deleted file mode 100644 index 7df0469af8..0000000000 --- a/packages/backend/src/server/api/endpoints/notes/schedule/delete.ts +++ /dev/null @@ -1,67 +0,0 @@ -/* - * SPDX-FileCopyrightText: syuilo and misskey-project - * SPDX-License-Identifier: AGPL-3.0-only - */ - -import ms from 'ms'; -import { Inject, Injectable } from '@nestjs/common'; -import type { NoteScheduleRepository } from '@/models/_.js'; -import { Endpoint } from '@/server/api/endpoint-base.js'; -import { DI } from '@/di-symbols.js'; -import { ApiError } from '@/server/api/error.js'; -import { QueueService } from '@/core/QueueService.js'; - -export const meta = { - tags: ['notes'], - - requireCredential: true, - kind: 'write:notes-schedule', - - limit: { - duration: ms('1hour'), - max: 300, - }, - - errors: { - noSuchNote: { - message: 'No such note.', - code: 'NO_SUCH_NOTE', - id: 'a58056ba-8ba1-4323-8ebf-e0b585bc244f', - }, - permissionDenied: { - message: 'Permission denied.', - code: 'PERMISSION_DENIED', - id: 'c0da2fed-8f61-4c47-a41d-431992607b5c', - httpStatusCode: 403, - }, - }, -} as const; - -export const paramDef = { - type: 'object', - properties: { - noteId: { type: 'string', format: 'misskey:id' }, - }, - required: ['noteId'], -} as const; - -@Injectable() -export default class extends Endpoint { // eslint-disable-line import/no-default-export - constructor( - @Inject(DI.noteScheduleRepository) - private noteScheduleRepository: NoteScheduleRepository, - private queueService: QueueService, - ) { - super(meta, paramDef, async (ps, me) => { - const note = await this.noteScheduleRepository.findOneBy({ id: ps.noteId }); - if (note === null) { - throw new ApiError(meta.errors.noSuchNote); - } - if (note.userId !== me.id) { - throw new ApiError(meta.errors.permissionDenied); - } - await this.noteScheduleRepository.delete({ id: ps.noteId }); - await this.queueService.ScheduleNotePostQueue.remove(ps.noteId); - }); - } -} diff --git a/packages/backend/src/server/api/endpoints/notes/schedule/list.ts b/packages/backend/src/server/api/endpoints/notes/schedule/list.ts deleted file mode 100644 index 68ed15c6ea..0000000000 --- a/packages/backend/src/server/api/endpoints/notes/schedule/list.ts +++ /dev/null @@ -1,128 +0,0 @@ -/* - * SPDX-FileCopyrightText: syuilo and misskey-project - * SPDX-License-Identifier: AGPL-3.0-only - */ - -import ms from 'ms'; -import { Inject, Injectable } from '@nestjs/common'; -import { Endpoint } from '@/server/api/endpoint-base.js'; -import { DI } from '@/di-symbols.js'; -import type { MiNote, MiNoteSchedule, NoteScheduleRepository } from '@/models/_.js'; -import { UserEntityService } from '@/core/entities/UserEntityService.js'; -import { QueryService } from '@/core/QueryService.js'; -import { Packed } from '@/misc/json-schema.js'; -import { noteVisibilities } from '@/types.js'; - -export const meta = { - tags: ['notes'], - - requireCredential: true, - kind: 'read:notes-schedule', - res: { - type: 'array', - optional: false, nullable: false, - items: { - type: 'object', - optional: false, nullable: false, - properties: { - id: { type: 'string', format: 'misskey:id', optional: false, nullable: false }, - note: { - type: 'object', - optional: false, nullable: false, - properties: { - createdAt: { type: 'string', optional: false, nullable: false }, - text: { type: 'string', optional: true, nullable: false }, - cw: { type: 'string', optional: true, nullable: true }, - fileIds: { type: 'array', optional: false, nullable: false, items: { type: 'string', format: 'misskey:id', optional: false, nullable: false } }, - visibility: { type: 'string', enum: ['public', 'home', 'followers', 'specified'], optional: false, nullable: false }, - visibleUsers: { - type: 'array', optional: false, nullable: false, items: { - type: 'object', - optional: false, nullable: false, - ref: 'UserLite', - }, - }, - user: { - type: 'object', - optional: false, nullable: false, - ref: 'User', - }, - reactionAcceptance: { type: 'string', nullable: true, enum: [null, 'likeOnly', 'likeOnlyForRemote', 'nonSensitiveOnly', 'nonSensitiveOnlyForLocalLikeOnlyForRemote'], default: null }, - isSchedule: { type: 'boolean', optional: false, nullable: false }, - }, - }, - userId: { type: 'string', optional: false, nullable: false }, - scheduledAt: { type: 'string', optional: false, nullable: false }, - }, - }, - }, - limit: { - duration: ms('1hour'), - max: 300, - }, - - errors: { - }, -} as const; - -export const paramDef = { - type: 'object', - properties: { - sinceId: { type: 'string', format: 'misskey:id' }, - untilId: { type: 'string', format: 'misskey:id' }, - limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 }, - }, -} as const; - -@Injectable() -export default class extends Endpoint { // eslint-disable-line import/no-default-export - constructor( - @Inject(DI.noteScheduleRepository) - private noteScheduleRepository: NoteScheduleRepository, - - private userEntityService: UserEntityService, - private queryService: QueryService, - ) { - super(meta, paramDef, async (ps, me) => { - const query = this.queryService.makePaginationQuery(this.noteScheduleRepository.createQueryBuilder('note'), ps.sinceId, ps.untilId) - .andWhere('note.userId = :userId', { userId: me.id }); - const scheduleNotes = await query.limit(ps.limit).getMany(); - const user = await this.userEntityService.pack(me, me); - const scheduleNotesPack: { - id: string; - note: { - text?: string; - cw?: string | null; - fileIds: string[]; - visibility: typeof noteVisibilities[number]; - visibleUsers: Packed<'UserLite'>[]; - reactionAcceptance: MiNote['reactionAcceptance']; - user: Packed<'User'>; - createdAt: string; - isSchedule: boolean; - }; - userId: string; - scheduledAt: string; - }[] = await Promise.all(scheduleNotes.map(async (item: MiNoteSchedule) => { - return { - ...item, - scheduledAt: item.scheduledAt.toISOString(), - note: { - ...item.note, - text: item.note.text ?? '', - user: user, - visibility: item.note.visibility ?? 'public', - reactionAcceptance: item.note.reactionAcceptance ?? null, - visibleUsers: item.note.visibleUsers ? await userEntityService.packMany(item.note.visibleUsers.map(u => u.id), me) : [], - fileIds: item.note.files ? item.note.files : [], - createdAt: item.scheduledAt.toISOString(), - isSchedule: true, - id: item.id, - }, - }; - })); - - return scheduleNotesPack; - }); - } -} diff --git a/packages/backend/src/server/api/endpoints/notes/search-by-tag.ts b/packages/backend/src/server/api/endpoints/notes/search-by-tag.ts index d0781bd8dd..2cd6610cf6 100644 --- a/packages/backend/src/server/api/endpoints/notes/search-by-tag.ts +++ b/packages/backend/src/server/api/endpoints/notes/search-by-tag.ts @@ -28,38 +28,55 @@ export const meta = { } as const; export const paramDef = { - type: 'object', - properties: { - reply: { type: 'boolean', nullable: true, default: null }, - renote: { type: 'boolean', nullable: true, default: null }, - withFiles: { - type: 'boolean', - default: false, - description: 'Only show notes that have attached files.', + allOf: [ + { + anyOf: [ + { + type: 'object', + properties: { + tag: { type: 'string', minLength: 1 }, + }, + required: ['tag'], + }, + { + type: 'object', + properties: { + query: { + type: 'array', + description: 'The outer arrays are chained with OR, the inner arrays are chained with AND.', + items: { + type: 'array', + items: { + type: 'string', + minLength: 1, + }, + minItems: 1, + }, + minItems: 1, + }, + }, + required: ['query'], + }, + ], }, - poll: { type: 'boolean', nullable: true, default: null }, - sinceId: { type: 'string', format: 'misskey:id' }, - untilId: { type: 'string', format: 'misskey:id' }, - limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 }, - - tag: { type: 'string', minLength: 1 }, - query: { - type: 'array', - description: 'The outer arrays are chained with OR, the inner arrays are chained with AND.', - items: { - type: 'array', - items: { - type: 'string', - minLength: 1, + { + type: 'object', + properties: { + reply: { type: 'boolean', nullable: true, default: null }, + renote: { type: 'boolean', nullable: true, default: null }, + withFiles: { + type: 'boolean', + default: false, + description: 'Only show notes that have attached files.', }, - minItems: 1, + poll: { type: 'boolean', nullable: true, default: null }, + sinceId: { type: 'string', format: 'misskey:id' }, + untilId: { type: 'string', format: 'misskey:id' }, + sinceDate: { type: 'integer' }, + untilDate: { type: 'integer' }, + limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 }, }, - minItems: 1, }, - }, - anyOf: [ - { required: ['tag'] }, - { required: ['query'] }, ], } as const; @@ -73,7 +90,7 @@ export default class extends Endpoint { // eslint- private queryService: QueryService, ) { super(meta, paramDef, async (ps, me) => { - const query = this.queryService.makePaginationQuery(this.notesRepository.createQueryBuilder('note'), ps.sinceId, ps.untilId) + const query = this.queryService.makePaginationQuery(this.notesRepository.createQueryBuilder('note'), ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate) .innerJoinAndSelect('note.user', 'user') .leftJoinAndSelect('note.reply', 'reply') .leftJoinAndSelect('note.renote', 'renote') @@ -81,18 +98,15 @@ export default class extends Endpoint { // eslint- .leftJoinAndSelect('renote.user', 'renoteUser'); this.queryService.generateVisibilityQuery(query, me); - this.queryService.generateBlockedHostQueryForNote(query); - this.queryService.generateSuspendedUserQueryForNote(query); - if (me) this.queryService.generateMutedUserQueryForNotes(query, me); - if (me) this.queryService.generateBlockedUserQueryForNotes(query, me); + this.queryService.generateBaseNoteFilteringQuery(query, me); try { - if (ps.tag) { + if ('tag' in ps) { if (!safeForSql(normalizeForSearch(ps.tag))) throw new Error('Injection'); query.andWhere(':tag <@ note.tags', { tag: [normalizeForSearch(ps.tag)] }); } else { query.andWhere(new Brackets(qb => { - for (const tags of ps.query!) { + for (const tags of ps.query) { qb.orWhere(new Brackets(qb => { for (const tag of tags) { if (!safeForSql(normalizeForSearch(tag))) throw new Error('Injection'); diff --git a/packages/backend/src/server/api/endpoints/notes/search.ts b/packages/backend/src/server/api/endpoints/notes/search.ts index 3fe19806e3..ab1bd934fb 100644 --- a/packages/backend/src/server/api/endpoints/notes/search.ts +++ b/packages/backend/src/server/api/endpoints/notes/search.ts @@ -8,6 +8,7 @@ import { Endpoint } from '@/server/api/endpoint-base.js'; import { SearchService } from '@/core/SearchService.js'; import { NoteEntityService } from '@/core/entities/NoteEntityService.js'; import { RoleService } from '@/core/RoleService.js'; +import { IdService } from '@/core/IdService.js'; import { ApiError } from '../../error.js'; export const meta = { @@ -40,6 +41,8 @@ export const paramDef = { query: { type: 'string' }, sinceId: { type: 'string', format: 'misskey:id' }, untilId: { type: 'string', format: 'misskey:id' }, + sinceDate: { type: 'integer' }, + untilDate: { type: 'integer' }, limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 }, offset: { type: 'integer', default: 0 }, host: { @@ -60,8 +63,12 @@ export default class extends Endpoint { // eslint- private noteEntityService: NoteEntityService, private searchService: SearchService, private roleService: RoleService, + private idService: IdService, ) { super(meta, paramDef, async (ps, me) => { + const untilId = ps.untilId ?? (ps.untilDate ? this.idService.gen(ps.untilDate!) : undefined); + const sinceId = ps.sinceId ?? (ps.sinceDate ? this.idService.gen(ps.sinceDate!) : undefined); + const policies = await this.roleService.getUserPolicies(me ? me.id : null); if (!policies.canSearchNotes) { throw new ApiError(meta.errors.unavailable); @@ -72,8 +79,8 @@ export default class extends Endpoint { // eslint- channelId: ps.channelId, host: ps.host, }, { - untilId: ps.untilId, - sinceId: ps.sinceId, + untilId: untilId, + sinceId: sinceId, limit: ps.limit, }); diff --git a/packages/backend/src/server/api/endpoints/notes/show-partial-bulk.ts b/packages/backend/src/server/api/endpoints/notes/show-partial-bulk.ts new file mode 100644 index 0000000000..e102bc1d4a --- /dev/null +++ b/packages/backend/src/server/api/endpoints/notes/show-partial-bulk.ts @@ -0,0 +1,66 @@ +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { Injectable } from '@nestjs/common'; +import { Endpoint } from '@/server/api/endpoint-base.js'; +import { NoteEntityService } from '@/core/entities/NoteEntityService.js'; +import { GetterService } from '@/server/api/GetterService.js'; +import { ApiError } from '../../error.js'; + +export const meta = { + tags: ['notes'], + + requireCredential: false, + + res: { + type: 'array', + optional: false, nullable: false, + items: { + type: 'object', + properties: { + id: { + type: 'string', + optional: false, nullable: false, + }, + reactions: { + type: 'object', + optional: false, nullable: false, + additionalProperties: { + type: 'number', + }, + }, + reactionEmojis: { + type: 'object', + optional: false, nullable: false, + additionalProperties: { + type: 'string', + }, + }, + }, + }, + }, + + errors: { + }, +} as const; + +export const paramDef = { + type: 'object', + properties: { + noteIds: { type: 'array', items: { type: 'string', format: 'misskey:id' }, maxItems: 100, minItems: 1 }, + }, + required: ['noteIds'], +} as const; + +@Injectable() +export default class extends Endpoint { // eslint-disable-line import/no-default-export + constructor( + private noteEntityService: NoteEntityService, + ) { + super(meta, paramDef, async (ps, me) => { + return await this.noteEntityService.fetchDiffs(ps.noteIds); + }); + } +} diff --git a/packages/backend/src/server/api/endpoints/notes/show.ts b/packages/backend/src/server/api/endpoints/notes/show.ts index 11839bce36..a41de25ddf 100644 --- a/packages/backend/src/server/api/endpoints/notes/show.ts +++ b/packages/backend/src/server/api/endpoints/notes/show.ts @@ -3,10 +3,12 @@ * SPDX-License-Identifier: AGPL-3.0-only */ -import { Injectable } from '@nestjs/common'; +import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { NoteEntityService } from '@/core/entities/NoteEntityService.js'; import { GetterService } from '@/server/api/GetterService.js'; +import { DI } from '@/di-symbols.js'; +import { MiMeta } from '@/models/Meta.js'; import { ApiError } from '../../error.js'; export const meta = { @@ -27,10 +29,16 @@ export const meta = { id: '24fcbfc6-2e37-42b6-8388-c29b3861a08d', }, - signinRequired: { - message: 'Signin required.', - code: 'SIGNIN_REQUIRED', - id: '8e75455b-738c-471d-9f80-62693f33372e', + contentRestrictedByUser: { + message: 'Content restricted by user. Please sign in to view.', + code: 'CONTENT_RESTRICTED_BY_USER', + id: 'fbcc002d-37d9-4944-a6b0-d9e29f2d33ab', + }, + + contentRestrictedByServer: { + message: 'Content restricted by server settings. Please sign in to view.', + code: 'CONTENT_RESTRICTED_BY_SERVER', + id: '145f88d2-b03d-4087-8143-a78928883c4b', }, }, } as const; @@ -46,17 +54,28 @@ export const paramDef = { @Injectable() export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( + @Inject(DI.meta) + private serverSettings: MiMeta, + private noteEntityService: NoteEntityService, private getterService: GetterService, ) { super(meta, paramDef, async (ps, me) => { - const note = await this.getterService.getNoteWithUser(ps.noteId).catch(err => { + const note = await this.getterService.getNoteWithRelations(ps.noteId).catch(err => { if (err.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError(meta.errors.noSuchNote); throw err; }); if (note.user!.requireSigninToViewContents && me == null) { - throw new ApiError(meta.errors.signinRequired); + throw new ApiError(meta.errors.contentRestrictedByUser); + } + + if (this.serverSettings.ugcVisibilityForVisitor === 'none' && me == null) { + throw new ApiError(meta.errors.contentRestrictedByServer); + } + + if (this.serverSettings.ugcVisibilityForVisitor === 'local' && note.userHost != null && me == null) { + throw new ApiError(meta.errors.contentRestrictedByServer); } return await this.noteEntityService.pack(note, me, { diff --git a/packages/backend/src/server/api/endpoints/notes/state.ts b/packages/backend/src/server/api/endpoints/notes/state.ts index 4c1eb86542..1cfed696ce 100644 --- a/packages/backend/src/server/api/endpoints/notes/state.ts +++ b/packages/backend/src/server/api/endpoints/notes/state.ts @@ -26,6 +26,10 @@ export const meta = { type: 'boolean', optional: false, nullable: false, }, + isRenoted: { + type: 'boolean', + optional: false, nullable: false, + }, }, }, } as const; @@ -53,7 +57,7 @@ export default class extends Endpoint { // eslint- super(meta, paramDef, async (ps, me) => { const note = await this.notesRepository.findOneByOrFail({ id: ps.noteId }); - const [favorite, threadMuting] = await Promise.all([ + const [favorite, threadMuting, renoted] = await Promise.all([ this.noteFavoritesRepository.count({ where: { userId: me.id, @@ -68,11 +72,19 @@ export default class extends Endpoint { // eslint- }, take: 1, }), + this.notesRepository.count({ + where: { + userId: me.id, + renoteId: note.id, + }, + take: 1, + }), ]); return { isFavorited: favorite !== 0, isMutedThread: threadMuting !== 0, + isRenoted: renoted !== 0, }; }); } diff --git a/packages/backend/src/server/api/endpoints/notes/timeline.ts b/packages/backend/src/server/api/endpoints/notes/timeline.ts index d5d8603333..3cd5916236 100644 --- a/packages/backend/src/server/api/endpoints/notes/timeline.ts +++ b/packages/backend/src/server/api/endpoints/notes/timeline.ts @@ -203,10 +203,7 @@ export default class extends Endpoint { // eslint- })); this.queryService.generateVisibilityQuery(query, me); - this.queryService.generateBlockedHostQueryForNote(query); - this.queryService.generateSuspendedUserQueryForNote(query); - this.queryService.generateMutedUserQueryForNotes(query, me); - this.queryService.generateBlockedUserQueryForNotes(query, me); + this.queryService.generateBaseNoteFilteringQuery(query, me); this.queryService.generateMutedUserRenotesQueryForNotes(query, me); if (ps.includeMyRenotes === false) { @@ -244,7 +241,14 @@ export default class extends Endpoint { // eslint- } if (ps.withRenotes === false) { - query.andWhere('note.renoteId IS NULL'); + query.andWhere(new Brackets(qb => { + qb.orWhere('note.renoteId IS NULL'); + qb.orWhere(new Brackets(qb => { + qb.orWhere('note.text IS NOT NULL'); + qb.orWhere('note.fileIds != \'{}\''); + qb.orWhere('0 < (SELECT COUNT(*) FROM poll WHERE poll."noteId" = note.id)'); + })); + })); } if (ps.withCats) { diff --git a/packages/backend/src/server/api/endpoints/notes/update.ts b/packages/backend/src/server/api/endpoints/notes/update.ts index 068fc60af8..ba4979e16b 100644 --- a/packages/backend/src/server/api/endpoints/notes/update.ts +++ b/packages/backend/src/server/api/endpoints/notes/update.ts @@ -195,20 +195,20 @@ export default class extends Endpoint { } const data = { - text: ps.text, files: files, - cw: ps.cw, poll: ps.poll ? { choices: ps.poll.choices, multiple: ps.poll.multiple ?? false, - expiresAt: ps.poll.expiresAt ? new Date(ps.poll.expiresAt) : null, - } : undefined, + expiresAt: ps.poll.expiredAfter ? new Date(Date.now() + ps.poll.expiredAfter) : ps.poll.expiresAt ? new Date(ps.poll.expiresAt) : null, + } : null, event: ps.event ? { start: new Date(ps.event.start!), end: ps.event.end ? new Date(ps.event.end) : null, title: ps.event.title!, metadata: ps.event.metadata ?? {}, - } : undefined, + } : null, + text: ps.text ?? null, + cw: ps.cw ?? null, disableRightClick: ps.disableRightClick, deleteAt: ps.scheduledDelete?.deleteAt ? new Date(ps.scheduledDelete.deleteAt) : ps.scheduledDelete?.deleteAfter ? new Date(Date.now() + ps.scheduledDelete.deleteAfter) : null, }; diff --git a/packages/backend/src/server/api/endpoints/notes/user-list-timeline.ts b/packages/backend/src/server/api/endpoints/notes/user-list-timeline.ts index f25d3befc2..91bb50f3b9 100644 --- a/packages/backend/src/server/api/endpoints/notes/user-list-timeline.ts +++ b/packages/backend/src/server/api/endpoints/notes/user-list-timeline.ts @@ -189,10 +189,7 @@ export default class extends Endpoint { // eslint- })); this.queryService.generateVisibilityQuery(query, me); - this.queryService.generateBlockedHostQueryForNote(query); - this.queryService.generateSuspendedUserQueryForNote(query); - this.queryService.generateMutedUserQueryForNotes(query, me); - this.queryService.generateBlockedUserQueryForNotes(query, me); + this.queryService.generateBaseNoteFilteringQuery(query, me); this.queryService.generateMutedUserRenotesQueryForNotes(query, me); if (ps.includeMyRenotes === false) { @@ -231,6 +228,7 @@ export default class extends Endpoint { // eslint- qb.orWhere(new Brackets(qb => { qb.orWhere('note.text IS NOT NULL'); qb.orWhere('note.fileIds != \'{}\''); + qb.orWhere('0 < (SELECT COUNT(*) FROM poll WHERE poll."noteId" = note.id)'); })); })); } diff --git a/packages/backend/src/server/api/endpoints/pages/create.ts b/packages/backend/src/server/api/endpoints/pages/create.ts index 6de5fe3d44..96bc2a953a 100644 --- a/packages/backend/src/server/api/endpoints/pages/create.ts +++ b/packages/backend/src/server/api/endpoints/pages/create.ts @@ -5,12 +5,13 @@ import ms from 'ms'; import { Inject, Injectable } from '@nestjs/common'; -import type { DriveFilesRepository, PagesRepository } from '@/models/_.js'; -import { IdService } from '@/core/IdService.js'; -import { MiPage, pageNameSchema } from '@/models/Page.js'; +import type { DriveFilesRepository, MiDriveFile, PagesRepository } from '@/models/_.js'; +import { pageNameSchema } from '@/models/Page.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { PageEntityService } from '@/core/entities/PageEntityService.js'; import { DI } from '@/di-symbols.js'; +import { PageService } from '@/core/PageService.js'; +import { IdentifiableError } from '@/misc/identifiable-error.js'; import { ApiError } from '../../error.js'; export const meta = { @@ -77,11 +78,11 @@ export default class extends Endpoint { // eslint- @Inject(DI.driveFilesRepository) private driveFilesRepository: DriveFilesRepository, + private pageService: PageService, private pageEntityService: PageEntityService, - private idService: IdService, ) { super(meta, paramDef, async (ps, me) => { - let eyeCatchingImage = null; + let eyeCatchingImage: MiDriveFile | null = null; if (ps.eyeCatchingImageId != null) { eyeCatchingImage = await this.driveFilesRepository.findOneBy({ id: ps.eyeCatchingImageId, @@ -102,24 +103,20 @@ export default class extends Endpoint { // eslint- } }); - const page = await this.pagesRepository.insertOne(new MiPage({ - id: this.idService.gen(), - updatedAt: new Date(), - title: ps.title, - name: ps.name, - summary: ps.summary, - content: ps.content, - variables: ps.variables, - script: ps.script, - eyeCatchingImageId: eyeCatchingImage ? eyeCatchingImage.id : null, - userId: me.id, - visibility: 'public', - alignCenter: ps.alignCenter, - hideTitleWhenPinned: ps.hideTitleWhenPinned, - font: ps.font, - })); + try { + const page = await this.pageService.create(me, { + ...ps, + eyeCatchingImage, + summary: ps.summary ?? null, + }); - return await this.pageEntityService.pack(page); + return await this.pageEntityService.pack(page); + } catch (err) { + if (err instanceof IdentifiableError && err.id === '1a79e38e-3d83-4423-845b-a9d83ff93b61') { + throw new ApiError(meta.errors.nameAlreadyExists); + } + throw err; + } }); } } diff --git a/packages/backend/src/server/api/endpoints/pages/delete.ts b/packages/backend/src/server/api/endpoints/pages/delete.ts index f2bc946788..7fda030deb 100644 --- a/packages/backend/src/server/api/endpoints/pages/delete.ts +++ b/packages/backend/src/server/api/endpoints/pages/delete.ts @@ -4,11 +4,13 @@ */ import { Inject, Injectable } from '@nestjs/common'; -import type { PagesRepository, UsersRepository } from '@/models/_.js'; +import type { MiDriveFile, PagesRepository, UsersRepository } from '@/models/_.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { DI } from '@/di-symbols.js'; import { ModerationLogService } from '@/core/ModerationLogService.js'; import { RoleService } from '@/core/RoleService.js'; +import { IdentifiableError } from '@/misc/identifiable-error.js'; +import { PageService } from '@/core/PageService.js'; import { ApiError } from '../../error.js'; export const meta = { @@ -44,36 +46,17 @@ export const paramDef = { @Injectable() export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( - @Inject(DI.pagesRepository) - private pagesRepository: PagesRepository, - - @Inject(DI.usersRepository) - private usersRepository: UsersRepository, - - private moderationLogService: ModerationLogService, - private roleService: RoleService, + private pageService: PageService, ) { super(meta, paramDef, async (ps, me) => { - const page = await this.pagesRepository.findOneBy({ id: ps.pageId }); - - if (page == null) { - throw new ApiError(meta.errors.noSuchPage); - } - - if (!await this.roleService.isModerator(me) && page.userId !== me.id) { - throw new ApiError(meta.errors.accessDenied); - } - - await this.pagesRepository.delete(page.id); - - if (page.userId !== me.id) { - const user = await this.usersRepository.findOneByOrFail({ id: page.userId }); - this.moderationLogService.log(me, 'deletePage', { - pageId: page.id, - pageUserId: page.userId, - pageUserUsername: user.username, - page, - }); + try { + await this.pageService.delete(me, ps.pageId); + } catch (err) { + if (err instanceof IdentifiableError) { + if (err.id === '66aefd3c-fdb2-4a71-85ae-cc18bea85d3f') throw new ApiError(meta.errors.noSuchPage); + if (err.id === 'd0017699-8256-46f1-aed4-bc03bed73616') throw new ApiError(meta.errors.accessDenied); + } + throw err; } }); } diff --git a/packages/backend/src/server/api/endpoints/pages/show.ts b/packages/backend/src/server/api/endpoints/pages/show.ts index e08b832a3f..8427bab2d5 100644 --- a/packages/backend/src/server/api/endpoints/pages/show.ts +++ b/packages/backend/src/server/api/endpoints/pages/show.ts @@ -33,15 +33,22 @@ export const meta = { } as const; export const paramDef = { - type: 'object', - properties: { - pageId: { type: 'string', format: 'misskey:id' }, - name: { type: 'string' }, - username: { type: 'string' }, - }, anyOf: [ - { required: ['pageId'] }, - { required: ['name', 'username'] }, + { + type: 'object', + properties: { + pageId: { type: 'string', format: 'misskey:id' }, + }, + required: ['pageId'], + }, + { + type: 'object', + properties: { + name: { type: 'string' }, + username: { type: 'string' }, + }, + required: ['name', 'username'], + }, ], } as const; @@ -59,9 +66,9 @@ export default class extends Endpoint { // eslint- super(meta, paramDef, async (ps, me) => { let page: MiPage | null = null; - if (ps.pageId) { + if ('pageId' in ps) { page = await this.pagesRepository.findOneBy({ id: ps.pageId }); - } else if (ps.name && ps.username) { + } else { const author = await this.usersRepository.findOneBy({ host: IsNull(), usernameLower: ps.username.toLowerCase(), diff --git a/packages/backend/src/server/api/endpoints/pages/update.ts b/packages/backend/src/server/api/endpoints/pages/update.ts index 995db6f486..f808bf7a3a 100644 --- a/packages/backend/src/server/api/endpoints/pages/update.ts +++ b/packages/backend/src/server/api/endpoints/pages/update.ts @@ -4,12 +4,13 @@ */ import ms from 'ms'; -import { Not } from 'typeorm'; import { Inject, Injectable } from '@nestjs/common'; -import type { PagesRepository, DriveFilesRepository } from '@/models/_.js'; +import type { DriveFilesRepository, MiDriveFile } from '@/models/_.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { DI } from '@/di-symbols.js'; import { pageNameSchema } from '@/models/Page.js'; +import { IdentifiableError } from '@/misc/identifiable-error.js'; +import { PageService } from '@/core/PageService.js'; import { ApiError } from '../../error.js'; export const meta = { @@ -75,57 +76,37 @@ export const paramDef = { @Injectable() export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( - @Inject(DI.pagesRepository) - private pagesRepository: PagesRepository, - @Inject(DI.driveFilesRepository) private driveFilesRepository: DriveFilesRepository, + + private pageService: PageService, ) { super(meta, paramDef, async (ps, me) => { - const page = await this.pagesRepository.findOneBy({ id: ps.pageId }); - if (page == null) { - throw new ApiError(meta.errors.noSuchPage); - } - if (page.userId !== me.id) { - throw new ApiError(meta.errors.accessDenied); - } - - if (ps.eyeCatchingImageId != null) { - const eyeCatchingImage = await this.driveFilesRepository.findOneBy({ - id: ps.eyeCatchingImageId, - userId: me.id, - }); + try { + let eyeCatchingImage: MiDriveFile | null | undefined | string = ps.eyeCatchingImageId; + if (eyeCatchingImage != null) { + eyeCatchingImage = await this.driveFilesRepository.findOneBy({ + id: eyeCatchingImage, + userId: me.id, + }); - if (eyeCatchingImage == null) { - throw new ApiError(meta.errors.noSuchFile); + if (eyeCatchingImage == null) { + throw new ApiError(meta.errors.noSuchFile); + } } - } - if (ps.name != null) { - await this.pagesRepository.findBy({ - id: Not(ps.pageId), - userId: me.id, - name: ps.name, - }).then(result => { - if (result.length > 0) { - throw new ApiError(meta.errors.nameAlreadyExists); - } + await this.pageService.update(me, ps.pageId, { + ...ps, + eyeCatchingImage, }); + } catch (err) { + if (err instanceof IdentifiableError) { + if (err.id === '66aefd3c-fdb2-4a71-85ae-cc18bea85d3f') throw new ApiError(meta.errors.noSuchPage); + if (err.id === 'd0017699-8256-46f1-aed4-bc03bed73616') throw new ApiError(meta.errors.accessDenied); + if (err.id === 'd05bfe24-24b6-4ea2-a3ec-87cc9bf4daa4') throw new ApiError(meta.errors.nameAlreadyExists); + } + throw err; } - - await this.pagesRepository.update(page.id, { - updatedAt: new Date(), - title: ps.title, - name: ps.name, - summary: ps.summary === undefined ? page.summary : ps.summary, - content: ps.content, - variables: ps.variables, - script: ps.script, - alignCenter: ps.alignCenter, - hideTitleWhenPinned: ps.hideTitleWhenPinned, - font: ps.font, - eyeCatchingImageId: ps.eyeCatchingImageId, - }); }); } } diff --git a/packages/backend/src/server/api/endpoints/renote-mute/list.ts b/packages/backend/src/server/api/endpoints/renote-mute/list.ts index 3be01f989a..adf5aa76bf 100644 --- a/packages/backend/src/server/api/endpoints/renote-mute/list.ts +++ b/packages/backend/src/server/api/endpoints/renote-mute/list.ts @@ -34,6 +34,8 @@ export const paramDef = { limit: { type: 'integer', minimum: 1, maximum: 100, default: 30 }, sinceId: { type: 'string', format: 'misskey:id' }, untilId: { type: 'string', format: 'misskey:id' }, + sinceDate: { type: 'integer' }, + untilDate: { type: 'integer' }, }, required: [], } as const; @@ -48,7 +50,7 @@ export default class extends Endpoint { // eslint- private queryService: QueryService, ) { super(meta, paramDef, async (ps, me) => { - const query = this.queryService.makePaginationQuery(this.renoteMutingsRepository.createQueryBuilder('muting'), ps.sinceId, ps.untilId) + const query = this.queryService.makePaginationQuery(this.renoteMutingsRepository.createQueryBuilder('muting'), ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate) .andWhere('muting.muterId = :meId', { meId: me.id }); const mutings = await query diff --git a/packages/backend/src/server/api/endpoints/reversi/games.ts b/packages/backend/src/server/api/endpoints/reversi/games.ts index 6b06068727..22f3a0617b 100644 --- a/packages/backend/src/server/api/endpoints/reversi/games.ts +++ b/packages/backend/src/server/api/endpoints/reversi/games.ts @@ -27,6 +27,8 @@ export const paramDef = { limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 }, sinceId: { type: 'string', format: 'misskey:id' }, untilId: { type: 'string', format: 'misskey:id' }, + sinceDate: { type: 'integer' }, + untilDate: { type: 'integer' }, my: { type: 'boolean', default: false }, }, required: [], @@ -42,7 +44,7 @@ export default class extends Endpoint { // eslint- private queryService: QueryService, ) { super(meta, paramDef, async (ps, me) => { - const query = this.queryService.makePaginationQuery(this.reversiGamesRepository.createQueryBuilder('game'), ps.sinceId, ps.untilId) + const query = this.queryService.makePaginationQuery(this.reversiGamesRepository.createQueryBuilder('game'), ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate) .innerJoinAndSelect('game.user1', 'user1') .innerJoinAndSelect('game.user2', 'user2'); diff --git a/packages/backend/src/server/api/endpoints/roles/notes.ts b/packages/backend/src/server/api/endpoints/roles/notes.ts index 16b0783a01..e8a760e9f8 100644 --- a/packages/backend/src/server/api/endpoints/roles/notes.ts +++ b/packages/backend/src/server/api/endpoints/roles/notes.ts @@ -102,10 +102,7 @@ export default class extends Endpoint { // eslint- .leftJoinAndSelect('renote.user', 'renoteUser'); this.queryService.generateVisibilityQuery(query, me); - this.queryService.generateBlockedHostQueryForNote(query); - this.queryService.generateSuspendedUserQueryForNote(query); - this.queryService.generateMutedUserQueryForNotes(query, me); - this.queryService.generateBlockedUserQueryForNotes(query, me); + this.queryService.generateBaseNoteFilteringQuery(query, me); const notes = await query.getMany(); notes.sort((a, b) => a.id > b.id ? -1 : 1); diff --git a/packages/backend/src/server/api/endpoints/roles/users.ts b/packages/backend/src/server/api/endpoints/roles/users.ts index 71d5030b66..e4cc059688 100644 --- a/packages/backend/src/server/api/endpoints/roles/users.ts +++ b/packages/backend/src/server/api/endpoints/roles/users.ts @@ -51,6 +51,8 @@ export const paramDef = { roleId: { type: 'string', format: 'misskey:id' }, sinceId: { type: 'string', format: 'misskey:id' }, untilId: { type: 'string', format: 'misskey:id' }, + sinceDate: { type: 'integer' }, + untilDate: { type: 'integer' }, limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 }, }, required: ['roleId'], @@ -79,7 +81,7 @@ export default class extends Endpoint { // eslint- throw new ApiError(meta.errors.noSuchRole); } - let query = this.queryService.makePaginationQuery(this.roleAssignmentsRepository.createQueryBuilder('assign'), ps.sinceId, ps.untilId) + const query = this.queryService.makePaginationQuery(this.roleAssignmentsRepository.createQueryBuilder('assign'), ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate) .andWhere('assign.roleId = :roleId', { roleId: role.id }) .andWhere(new Brackets(qb => { qb diff --git a/packages/backend/src/server/api/endpoints/users/clips.ts b/packages/backend/src/server/api/endpoints/users/clips.ts index 7f7d2ea8cc..fb5a2391f2 100644 --- a/packages/backend/src/server/api/endpoints/users/clips.ts +++ b/packages/backend/src/server/api/endpoints/users/clips.ts @@ -33,6 +33,8 @@ export const paramDef = { limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 }, sinceId: { type: 'string', format: 'misskey:id' }, untilId: { type: 'string', format: 'misskey:id' }, + sinceDate: { type: 'integer' }, + untilDate: { type: 'integer' }, }, required: ['userId'], } as const; @@ -47,7 +49,7 @@ export default class extends Endpoint { // eslint- private queryService: QueryService, ) { super(meta, paramDef, async (ps, me) => { - const query = this.queryService.makePaginationQuery(this.clipsRepository.createQueryBuilder('clip'), ps.sinceId, ps.untilId) + const query = this.queryService.makePaginationQuery(this.clipsRepository.createQueryBuilder('clip'), ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate) .andWhere('clip.userId = :userId', { userId: ps.userId }) .andWhere('clip.isPublic = true'); diff --git a/packages/backend/src/server/api/endpoints/users/flashs.ts b/packages/backend/src/server/api/endpoints/users/flashs.ts index c02835a3ee..be435d1577 100644 --- a/packages/backend/src/server/api/endpoints/users/flashs.ts +++ b/packages/backend/src/server/api/endpoints/users/flashs.ts @@ -33,6 +33,8 @@ export const paramDef = { limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 }, sinceId: { type: 'string', format: 'misskey:id' }, untilId: { type: 'string', format: 'misskey:id' }, + sinceDate: { type: 'integer' }, + untilDate: { type: 'integer' }, }, required: ['userId'], } as const; @@ -47,7 +49,7 @@ export default class extends Endpoint { private queryService: QueryService, ) { super(meta, paramDef, async (ps, me) => { - const query = this.queryService.makePaginationQuery(this.flashsRepository.createQueryBuilder('flash'), ps.sinceId, ps.untilId) + const query = this.queryService.makePaginationQuery(this.flashsRepository.createQueryBuilder('flash'), ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate) .andWhere('flash.userId = :userId', { userId: ps.userId }) .andWhere('flash.visibility = \'public\''); diff --git a/packages/backend/src/server/api/endpoints/users/followers.ts b/packages/backend/src/server/api/endpoints/users/followers.ts index a8b4319a61..84c4c80d01 100644 --- a/packages/backend/src/server/api/endpoints/users/followers.ts +++ b/packages/backend/src/server/api/endpoints/users/followers.ts @@ -47,23 +47,40 @@ export const meta = { } as const; export const paramDef = { - type: 'object', - properties: { - sinceId: { type: 'string', format: 'misskey:id' }, - untilId: { type: 'string', format: 'misskey:id' }, - limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 }, - - userId: { type: 'string', format: 'misskey:id' }, - username: { type: 'string' }, - host: { - type: 'string', - nullable: true, - description: 'The local host is represented with `null`.', + allOf: [ + { + anyOf: [ + { + type: 'object', + properties: { + userId: { type: 'string', format: 'misskey:id' }, + }, + required: ['userId'], + }, + { + type: 'object', + properties: { + username: { type: 'string' }, + host: { + type: 'string', + nullable: true, + description: 'The local host is represented with `null`.', + }, + }, + required: ['username', 'host'], + }, + ], + }, + { + type: 'object', + properties: { + sinceId: { type: 'string', format: 'misskey:id' }, + untilId: { type: 'string', format: 'misskey:id' }, + sinceDate: { type: 'integer' }, + untilDate: { type: 'integer' }, + limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 }, + }, }, - }, - anyOf: [ - { required: ['userId'] }, - { required: ['username', 'host'] }, ], } as const; @@ -85,9 +102,9 @@ export default class extends Endpoint { // eslint- private roleService: RoleService, ) { super(meta, paramDef, async (ps, me) => { - const user = await this.usersRepository.findOneBy(ps.userId != null + const user = await this.usersRepository.findOneBy('userId' in ps ? { id: ps.userId } - : { usernameLower: ps.username!.toLowerCase(), host: this.utilityService.toPunyNullable(ps.host) ?? IsNull() }); + : { usernameLower: ps.username.toLowerCase(), host: this.utilityService.toPunyNullable(ps.host) ?? IsNull() }); if (user == null) { throw new ApiError(meta.errors.noSuchUser); @@ -117,7 +134,7 @@ export default class extends Endpoint { // eslint- } } - const query = this.queryService.makePaginationQuery(this.followingsRepository.createQueryBuilder('following'), ps.sinceId, ps.untilId) + const query = this.queryService.makePaginationQuery(this.followingsRepository.createQueryBuilder('following'), ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate) .andWhere('following.followeeId = :userId', { userId: user.id }) .innerJoinAndSelect('following.follower', 'follower'); diff --git a/packages/backend/src/server/api/endpoints/users/following.ts b/packages/backend/src/server/api/endpoints/users/following.ts index feda5bb353..047f9a053b 100644 --- a/packages/backend/src/server/api/endpoints/users/following.ts +++ b/packages/backend/src/server/api/endpoints/users/following.ts @@ -54,25 +54,41 @@ export const meta = { } as const; export const paramDef = { - type: 'object', - properties: { - sinceId: { type: 'string', format: 'misskey:id' }, - untilId: { type: 'string', format: 'misskey:id' }, - limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 }, - - userId: { type: 'string', format: 'misskey:id' }, - username: { type: 'string' }, - host: { - type: 'string', - nullable: true, - description: 'The local host is represented with `null`.', + allOf: [ + { + anyOf: [ + { + type: 'object', + properties: { + userId: { type: 'string', format: 'misskey:id' }, + }, + required: ['userId'], + }, + { + type: 'object', + properties: { + username: { type: 'string' }, + host: { + type: 'string', + nullable: true, + description: 'The local host is represented with `null`.', + }, + }, + required: ['username', 'host'], + }, + ], + }, + { + type: 'object', + properties: { + sinceId: { type: 'string', format: 'misskey:id' }, + untilId: { type: 'string', format: 'misskey:id' }, + sinceDate: { type: 'integer' }, + untilDate: { type: 'integer' }, + limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 }, + birthday: { ...birthdaySchema, nullable: true }, + }, }, - - birthday: { ...birthdaySchema, nullable: true }, - }, - anyOf: [ - { required: ['userId'] }, - { required: ['username', 'host'] }, ], } as const; @@ -94,9 +110,9 @@ export default class extends Endpoint { // eslint- private roleService: RoleService, ) { super(meta, paramDef, async (ps, me) => { - const user = await this.usersRepository.findOneBy(ps.userId != null + const user = await this.usersRepository.findOneBy('userId' in ps ? { id: ps.userId } - : { usernameLower: ps.username!.toLowerCase(), host: this.utilityService.toPunyNullable(ps.host) ?? IsNull() }); + : { usernameLower: ps.username.toLowerCase(), host: this.utilityService.toPunyNullable(ps.host) ?? IsNull() }); if (user == null) { throw new ApiError(meta.errors.noSuchUser); @@ -126,7 +142,7 @@ export default class extends Endpoint { // eslint- } } - const query = this.queryService.makePaginationQuery(this.followingsRepository.createQueryBuilder('following'), ps.sinceId, ps.untilId) + const query = this.queryService.makePaginationQuery(this.followingsRepository.createQueryBuilder('following'), ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate) .andWhere('following.followerId = :userId', { userId: user.id }) .innerJoinAndSelect('following.followee', 'followee'); diff --git a/packages/backend/src/server/api/endpoints/users/friends-following.ts b/packages/backend/src/server/api/endpoints/users/friends-following.ts index 61bb27c2b8..830cead8cc 100644 --- a/packages/backend/src/server/api/endpoints/users/friends-following.ts +++ b/packages/backend/src/server/api/endpoints/users/friends-following.ts @@ -6,6 +6,7 @@ import { IsNull } from 'typeorm'; import { Inject, Injectable } from '@nestjs/common'; import type { UsersRepository, FollowingsRepository, UserProfilesRepository } from '@/models/_.js'; +import { birthdaySchema } from '@/models/User.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { QueryService } from '@/core/QueryService.js'; import { FollowingEntityService } from '@/core/entities/FollowingEntityService.js'; @@ -22,22 +23,12 @@ export const meta = { description: 'Show everyone that this user is following.', res: { - type: 'object', + type: 'array', optional: false, nullable: false, - properties: { - userCount: { - type: 'integer', - optional: false, nullable: true, - }, - users: { - type: 'array', - optional: false, nullable: true, - items: { - type: 'object', - optional: false, nullable: false, - ref: 'Following', - }, - }, + items: { + type: 'object', + optional: false, nullable: false, + ref: 'Following', }, }, @@ -53,27 +44,51 @@ export const meta = { code: 'FORBIDDEN', id: 'f6cdb0df-c19f-ec5c-7dbb-0ba84a1f92ba', }, + + birthdayInvalid: { + message: 'Birthday date format is invalid.', + code: 'BIRTHDAY_DATE_FORMAT_INVALID', + id: 'a2b007b9-4782-4eba-abd3-93b05ed4130d', + }, }, } as const; export const paramDef = { - type: 'object', - properties: { - sinceId: { type: 'string', format: 'misskey:id' }, - untilId: { type: 'string', format: 'misskey:id' }, - limit: { type: 'integer', minimum: 1, maximum: 50, default: 10 }, - - userId: { type: 'string', format: 'misskey:id' }, - username: { type: 'string' }, - host: { - type: 'string', - nullable: true, - description: 'The local host is represented with `null`.', + allOf: [ + { + anyOf: [ + { + type: 'object', + properties: { + userId: { type: 'string', format: 'misskey:id' }, + }, + required: ['userId'], + }, + { + type: 'object', + properties: { + username: { type: 'string' }, + host: { + type: 'string', + nullable: true, + description: 'The local host is represented with `null`.', + }, + }, + required: ['username', 'host'], + }, + ], + }, + { + type: 'object', + properties: { + sinceId: { type: 'string', format: 'misskey:id' }, + untilId: { type: 'string', format: 'misskey:id' }, + sinceDate: { type: 'integer' }, + untilDate: { type: 'integer' }, + limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 }, + birthday: { ...birthdaySchema, nullable: true }, + }, }, - }, - anyOf: [ - { required: ['userId'] }, - { required: ['username', 'host'] }, ], } as const; @@ -113,9 +128,7 @@ export default class extends Endpoint { // eslint- if (profile.followersVisibility !== 'public' && !await this.roleService.isModerator(me)) { if (profile.followersVisibility === 'private') { if (me == null || (me.id !== user.id)) { - return { - userCount: null, users: null, - }; + return null; } } else if (profile.followersVisibility === 'followers') { if (me == null) { @@ -128,14 +141,12 @@ export default class extends Endpoint { // eslint- }, }); if (!isFollowing) { - return { - userCount: null, users: null, - }; + return null; } } } } - const query = this.followingsRepository.createQueryBuilder('following') + const query = this.queryService.makePaginationQuery(this.followingsRepository.createQueryBuilder('following'), ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate) .andWhere('following.followeeId = :userId', { userId: user.id }) .innerJoinAndSelect('following.follower', 'follower') .andWhere(qb => { @@ -146,15 +157,24 @@ export default class extends Endpoint { // eslint- }) .setParameters({ meId: me.id }); - const count = await query.getCount(); + if (ps.birthday) { + try { + const birthday = ps.birthday.substring(5, 10); + const birthdayUserQuery = this.userProfilesRepository.createQueryBuilder('user_profile'); + birthdayUserQuery.select('user_profile.userId') + .where(`SUBSTR(user_profile.birthday, 6, 5) = '${birthday}'`); + + query.andWhere(`following.followeeId IN (${ birthdayUserQuery.getQuery() })`); + } catch (err) { + throw new ApiError(meta.errors.birthdayInvalid); + } + } + const followings = await query .limit(ps.limit) .getMany(); - return { - userCount: count, - users: await this.followingEntityService.packMany(followings, me, { populateFollower: true }), - }; + return await this.followingEntityService.packMany(followings, me, { populateFollower: true }); }); } } diff --git a/packages/backend/src/server/api/endpoints/users/friends-summary.ts b/packages/backend/src/server/api/endpoints/users/friends-summary.ts new file mode 100644 index 0000000000..61bb27c2b8 --- /dev/null +++ b/packages/backend/src/server/api/endpoints/users/friends-summary.ts @@ -0,0 +1,160 @@ +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { IsNull } from 'typeorm'; +import { Inject, Injectable } from '@nestjs/common'; +import type { UsersRepository, FollowingsRepository, UserProfilesRepository } from '@/models/_.js'; +import { Endpoint } from '@/server/api/endpoint-base.js'; +import { QueryService } from '@/core/QueryService.js'; +import { FollowingEntityService } from '@/core/entities/FollowingEntityService.js'; +import { UtilityService } from '@/core/UtilityService.js'; +import { DI } from '@/di-symbols.js'; +import { RoleService } from '@/core/RoleService.js'; +import { ApiError } from '../../error.js'; + +export const meta = { + tags: ['users'], + + requireCredential: false, + + description: 'Show everyone that this user is following.', + + res: { + type: 'object', + optional: false, nullable: false, + properties: { + userCount: { + type: 'integer', + optional: false, nullable: true, + }, + users: { + type: 'array', + optional: false, nullable: true, + items: { + type: 'object', + optional: false, nullable: false, + ref: 'Following', + }, + }, + }, + }, + + errors: { + noSuchUser: { + message: 'No such user.', + code: 'NO_SUCH_USER', + id: '63e4aba4-4156-4e53-be25-c9559e42d71b', + }, + + forbidden: { + message: 'Forbidden.', + code: 'FORBIDDEN', + id: 'f6cdb0df-c19f-ec5c-7dbb-0ba84a1f92ba', + }, + }, +} as const; + +export const paramDef = { + type: 'object', + properties: { + sinceId: { type: 'string', format: 'misskey:id' }, + untilId: { type: 'string', format: 'misskey:id' }, + limit: { type: 'integer', minimum: 1, maximum: 50, default: 10 }, + + userId: { type: 'string', format: 'misskey:id' }, + username: { type: 'string' }, + host: { + type: 'string', + nullable: true, + description: 'The local host is represented with `null`.', + }, + }, + anyOf: [ + { required: ['userId'] }, + { required: ['username', 'host'] }, + ], +} as const; + +@Injectable() +export default class extends Endpoint { // eslint-disable-line import/no-default-export + constructor( + @Inject(DI.usersRepository) + private usersRepository: UsersRepository, + + @Inject(DI.userProfilesRepository) + private userProfilesRepository: UserProfilesRepository, + + @Inject(DI.followingsRepository) + private followingsRepository: FollowingsRepository, + + private utilityService: UtilityService, + private followingEntityService: FollowingEntityService, + private queryService: QueryService, + private roleService: RoleService, + ) { + super(meta, paramDef, async (ps, me) => { + const user = await this.usersRepository.findOneBy(ps.userId != null + ? { id: ps.userId } + : { usernameLower: ps.username!.toLowerCase(), host: this.utilityService.toPunyNullable(ps.host) ?? IsNull() }); + + if (user == null) { + throw new ApiError(meta.errors.noSuchUser); + } + if (me == null) { + return { + userCount: null, users: null, + }; + } + + const profile = await this.userProfilesRepository.findOneByOrFail({ userId: user.id }); + + if (profile.followersVisibility !== 'public' && !await this.roleService.isModerator(me)) { + if (profile.followersVisibility === 'private') { + if (me == null || (me.id !== user.id)) { + return { + userCount: null, users: null, + }; + } + } else if (profile.followersVisibility === 'followers') { + if (me == null) { + throw new ApiError(meta.errors.forbidden); + } else if (me.id !== user.id) { + const isFollowing = await this.followingsRepository.exists({ + where: { + followeeId: user.id, + followerId: me.id, + }, + }); + if (!isFollowing) { + return { + userCount: null, users: null, + }; + } + } + } + } + const query = this.followingsRepository.createQueryBuilder('following') + .andWhere('following.followeeId = :userId', { userId: user.id }) + .innerJoinAndSelect('following.follower', 'follower') + .andWhere(qb => { + const subQuery = this.followingsRepository.createQueryBuilder('myFollowing') + .select('myFollowing.followeeId') + .where('myFollowing.followerId = :meId', { meId: me.id }); + return `follower.id IN (${subQuery.getQuery()})`; + }) + .setParameters({ meId: me.id }); + + const count = await query.getCount(); + const followings = await query + .limit(ps.limit) + .getMany(); + + return { + userCount: count, + users: await this.followingEntityService.packMany(followings, me, { populateFollower: true }), + }; + }); + } +} diff --git a/packages/backend/src/server/api/endpoints/users/gallery/posts.ts b/packages/backend/src/server/api/endpoints/users/gallery/posts.ts index 553886374c..55e885e3c3 100644 --- a/packages/backend/src/server/api/endpoints/users/gallery/posts.ts +++ b/packages/backend/src/server/api/endpoints/users/gallery/posts.ts @@ -33,6 +33,8 @@ export const paramDef = { limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 }, sinceId: { type: 'string', format: 'misskey:id' }, untilId: { type: 'string', format: 'misskey:id' }, + sinceDate: { type: 'integer' }, + untilDate: { type: 'integer' }, }, required: ['userId'], } as const; @@ -47,7 +49,7 @@ export default class extends Endpoint { // eslint- private queryService: QueryService, ) { super(meta, paramDef, async (ps, me) => { - const query = this.queryService.makePaginationQuery(this.galleryPostsRepository.createQueryBuilder('post'), ps.sinceId, ps.untilId) + const query = this.queryService.makePaginationQuery(this.galleryPostsRepository.createQueryBuilder('post'), ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate) .andWhere('post.userId = :userId', { userId: ps.userId }); const posts = await query diff --git a/packages/backend/src/server/api/endpoints/users/lists/get-memberships.ts b/packages/backend/src/server/api/endpoints/users/lists/get-memberships.ts index 6d6e8d34ea..a841c4b94d 100644 --- a/packages/backend/src/server/api/endpoints/users/lists/get-memberships.ts +++ b/packages/backend/src/server/api/endpoints/users/lists/get-memberships.ts @@ -64,6 +64,8 @@ export const paramDef = { limit: { type: 'integer', minimum: 1, maximum: 100, default: 30 }, sinceId: { type: 'string', format: 'misskey:id' }, untilId: { type: 'string', format: 'misskey:id' }, + sinceDate: { type: 'integer' }, + untilDate: { type: 'integer' }, }, required: ['listId'], } as const; @@ -94,7 +96,7 @@ export default class extends Endpoint { throw new ApiError(meta.errors.noSuchList); } - const query = this.queryService.makePaginationQuery(this.userListMembershipsRepository.createQueryBuilder('membership'), ps.sinceId, ps.untilId) + const query = this.queryService.makePaginationQuery(this.userListMembershipsRepository.createQueryBuilder('membership'), ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate) .andWhere('membership.userListId = :userListId', { userListId: userList.id }) .innerJoinAndSelect('membership.user', 'user'); diff --git a/packages/backend/src/server/api/endpoints/users/lists/show.ts b/packages/backend/src/server/api/endpoints/users/lists/show.ts index 8756801fe4..c6d477a92f 100644 --- a/packages/backend/src/server/api/endpoints/users/lists/show.ts +++ b/packages/backend/src/server/api/endpoints/users/lists/show.ts @@ -22,7 +22,26 @@ export const meta = { res: { type: 'object', optional: false, nullable: false, - ref: 'UserList', + allOf: [ + { + type: 'object', + ref: 'UserList', + }, + { + type: 'object', + optional: false, nullable: false, + properties: { + likedCount: { + type: 'number', + optional: true, nullable: false, + }, + isLiked: { + type: 'boolean', + optional: true, nullable: false, + }, + }, + }, + ], }, errors: { diff --git a/packages/backend/src/server/api/endpoints/users/notes.ts b/packages/backend/src/server/api/endpoints/users/notes.ts index 9fc05ce81a..293cdb4ca2 100644 --- a/packages/backend/src/server/api/endpoints/users/notes.ts +++ b/packages/backend/src/server/api/endpoints/users/notes.ts @@ -191,12 +191,10 @@ export default class extends Endpoint { // eslint- } this.queryService.generateVisibilityQuery(query, me); - this.queryService.generateBlockedHostQueryForNote(query, true); - this.queryService.generateSuspendedUserQueryForNote(query, true); - if (me) { - this.queryService.generateMutedUserQueryForNotes(query, me, { id: ps.userId }); - this.queryService.generateBlockedUserQueryForNotes(query, me); - } + this.queryService.generateBaseNoteFilteringQuery(query, me, { + excludeAuthor: true, + excludeUserFromMute: ps.userId, + }); if (ps.withFiles) { query.andWhere('note.fileIds != \'{}\''); diff --git a/packages/backend/src/server/api/endpoints/users/pages.ts b/packages/backend/src/server/api/endpoints/users/pages.ts index bb7de0e0b5..1d7499d4be 100644 --- a/packages/backend/src/server/api/endpoints/users/pages.ts +++ b/packages/backend/src/server/api/endpoints/users/pages.ts @@ -33,6 +33,8 @@ export const paramDef = { limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 }, sinceId: { type: 'string', format: 'misskey:id' }, untilId: { type: 'string', format: 'misskey:id' }, + sinceDate: { type: 'integer' }, + untilDate: { type: 'integer' }, }, required: ['userId'], } as const; @@ -47,7 +49,7 @@ export default class extends Endpoint { // eslint- private queryService: QueryService, ) { super(meta, paramDef, async (ps, me) => { - const query = this.queryService.makePaginationQuery(this.pagesRepository.createQueryBuilder('page'), ps.sinceId, ps.untilId) + const query = this.queryService.makePaginationQuery(this.pagesRepository.createQueryBuilder('page'), ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate) .andWhere('page.userId = :userId', { userId: ps.userId }) .andWhere('page.visibility = \'public\''); diff --git a/packages/backend/src/server/api/endpoints/users/reactions.ts b/packages/backend/src/server/api/endpoints/users/reactions.ts index d6f1ecd8ed..d84a191f7a 100644 --- a/packages/backend/src/server/api/endpoints/users/reactions.ts +++ b/packages/backend/src/server/api/endpoints/users/reactions.ts @@ -28,7 +28,7 @@ export const meta = { items: { type: 'object', optional: false, nullable: false, - ref: 'NoteReaction', + ref: 'NoteReactionWithNote', }, }, @@ -120,7 +120,7 @@ export default class extends Endpoint { // eslint- return true; }); - return await this.noteReactionEntityService.packMany(reactions, me, { withNote: true }); + return await this.noteReactionEntityService.packManyWithNote(reactions, me); }); } } diff --git a/packages/backend/src/server/api/endpoints/users/recommendation.ts b/packages/backend/src/server/api/endpoints/users/recommendation.ts index 5b1c6b514b..769a72d7a1 100644 --- a/packages/backend/src/server/api/endpoints/users/recommendation.ts +++ b/packages/backend/src/server/api/endpoints/users/recommendation.ts @@ -64,6 +64,7 @@ export default class extends Endpoint { // eslint- this.queryService.generateMutedUserQueryForUsers(query, me); this.queryService.generateBlockQueryForUsers(query, me); this.queryService.generateBlockedUserQueryForNotes(query, me); + this.queryService.generateBlockedUserQueryForNotes(query, me, { noteColumn: 'renote' }); const followingQuery = this.followingsRepository.createQueryBuilder('following') .select('following.followeeId') diff --git a/packages/backend/src/server/api/endpoints/users/relation.ts b/packages/backend/src/server/api/endpoints/users/relation.ts index 1d75437b81..f146095cf1 100644 --- a/packages/backend/src/server/api/endpoints/users/relation.ts +++ b/packages/backend/src/server/api/endpoints/users/relation.ts @@ -114,7 +114,7 @@ export const paramDef = { type: 'object', properties: { userId: { - anyOf: [ + oneOf: [ { type: 'string', format: 'misskey:id' }, { type: 'array', diff --git a/packages/backend/src/server/api/endpoints/users/search-by-username-and-host.ts b/packages/backend/src/server/api/endpoints/users/search-by-username-and-host.ts index 134f1a8e87..d1d6354d53 100644 --- a/packages/backend/src/server/api/endpoints/users/search-by-username-and-host.ts +++ b/packages/backend/src/server/api/endpoints/users/search-by-username-and-host.ts @@ -26,17 +26,32 @@ export const meta = { } as const; export const paramDef = { - type: 'object', - properties: { - limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 }, - detail: { type: 'boolean', default: true }, - - username: { type: 'string', nullable: true }, - host: { type: 'string', nullable: true }, - }, - anyOf: [ - { required: ['username'] }, - { required: ['host'] }, + allOf: [ + { + anyOf: [ + { + type: 'object', + properties: { + username: { type: 'string', nullable: true }, + }, + required: ['username'], + }, + { + type: 'object', + properties: { + host: { type: 'string', nullable: true }, + }, + required: ['host'], + }, + ], + }, + { + type: 'object', + properties: { + limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 }, + detail: { type: 'boolean', default: true }, + }, + }, ], } as const; @@ -47,8 +62,8 @@ export default class extends Endpoint { // eslint- ) { super(meta, paramDef, (ps, me) => { return this.userSearchService.searchByUsernameAndHost({ - username: ps.username, - host: ps.host, + username: 'username' in ps ? ps.username : undefined, + host: 'host' in ps ? ps.host : undefined, }, { limit: ps.limit, detail: ps.detail, diff --git a/packages/backend/src/server/api/endpoints/users/search.ts b/packages/backend/src/server/api/endpoints/users/search.ts index 5d36847e03..c422286152 100644 --- a/packages/backend/src/server/api/endpoints/users/search.ts +++ b/packages/backend/src/server/api/endpoints/users/search.ts @@ -13,6 +13,7 @@ export const meta = { tags: ['users'], requireCredential: false, + requiredRolePolicy: 'canSearchUsers', description: 'Search for users.', diff --git a/packages/backend/src/server/api/endpoints/users/show.test.ts b/packages/backend/src/server/api/endpoints/users/show.test.ts new file mode 100644 index 0000000000..c67e15b205 --- /dev/null +++ b/packages/backend/src/server/api/endpoints/users/show.test.ts @@ -0,0 +1,23 @@ +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +process.env.NODE_ENV = 'test'; + +import { getValidator } from '../../../../../test/prelude/get-api-validator.js'; +import { paramDef } from './show.js'; + +const VALID = true; +const INVALID = false; + +describe('api:users/show', () => { + describe('validation', () => { + const v = getValidator(paramDef); + + test('Reject empty', () => expect(v({})).toBe(INVALID)); + test('Reject host only', () => expect(v({ host: 'cherrypick.test' })).toBe(INVALID)); + test('Accept userId only', () => expect(v({ userId: '1' })).toBe(VALID)); + test('Accept username and host', () => expect(v({ username: 'alice', host: 'cherrypick.test' })).toBe(VALID)); + }); +}); diff --git a/packages/backend/src/server/api/endpoints/users/show.ts b/packages/backend/src/server/api/endpoints/users/show.ts index 07a62c46fa..c30e9854bd 100644 --- a/packages/backend/src/server/api/endpoints/users/show.ts +++ b/packages/backend/src/server/api/endpoints/users/show.ts @@ -5,7 +5,7 @@ import { In, IsNull } from 'typeorm'; import { Inject, Injectable } from '@nestjs/common'; -import type { UsersRepository } from '@/models/_.js'; +import type { MiMeta, UsersRepository } from '@/models/_.js'; import type { MiUser } from '@/models/User.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { UserEntityService } from '@/core/entities/UserEntityService.js'; @@ -59,29 +59,53 @@ export const meta = { } as const; export const paramDef = { - type: 'object', - properties: { - userId: { type: 'string', format: 'misskey:id' }, - userIds: { type: 'array', uniqueItems: true, items: { - type: 'string', format: 'misskey:id', - } }, - username: { type: 'string' }, - host: { - type: 'string', - nullable: true, - description: 'The local host is represented with `null`.', + allOf: [ + { + anyOf: [ + { + type: 'object', + properties: { + userId: { type: 'string', format: 'misskey:id' }, + }, + required: ['userId'], + }, + { + type: 'object', + properties: { + userIds: { type: 'array', uniqueItems: true, items: { + type: 'string', format: 'misskey:id', + } }, + }, + required: ['userIds'], + }, + { + type: 'object', + properties: { + username: { type: 'string' }, + }, + required: ['username'], + }, + ], + }, + { + type: 'object', + properties: { + host: { + type: 'string', + nullable: true, + description: 'The local host is represented with `null`.', + }, + }, }, - }, - anyOf: [ - { required: ['userId'] }, - { required: ['userIds'] }, - { required: ['username'] }, ], } as const; @Injectable() export default class extends Endpoint { // eslint-disable-line import/no-default-export constructor( + @Inject(DI.meta) + private serverSettings: MiMeta, + @Inject(DI.usersRepository) private usersRepository: UsersRepository, @@ -92,12 +116,19 @@ export default class extends Endpoint { // eslint- private apiLoggerService: ApiLoggerService, ) { super(meta, paramDef, async (ps, me, _1, _2, _3, _4, ip) => { + // ログイン時にusers/showできなくなってしまう + //if (this.serverSettings.ugcVisibilityForVisitor === 'none' && me == null) { + // throw new ApiError(meta.errors.noSuchUser); + //} + let user; const isModerator = await this.roleService.isModerator(me); - ps.username = ps.username?.trim(); + if ('username' in ps) { + ps.username = ps.username.trim(); + } - if (ps.userIds) { + if ('userIds' in ps) { if (ps.userIds.length === 0) { return []; } @@ -122,13 +153,17 @@ export default class extends Endpoint { // eslint- return _users.map(u => _userMap.get(u.id)!); } else { // Lookup user - if (typeof ps.host === 'string' && typeof ps.username === 'string') { + if (typeof ps.host === 'string' && 'username' in ps) { + if (this.serverSettings.ugcVisibilityForVisitor === 'local' && me == null) { + throw new ApiError(meta.errors.noSuchUser); + } + user = await this.remoteUserResolveService.resolveUser(ps.username, ps.host).catch(err => { this.apiLoggerService.logger.warn(`failed to resolve remote user: ${err}`); throw new ApiError(meta.errors.failedToResolveRemoteUser); }); } else { - const q: FindOptionsWhere = ps.userId != null + const q: FindOptionsWhere = 'userId' in ps ? { id: ps.userId } : { usernameLower: ps.username!.toLowerCase(), host: IsNull() }; @@ -139,6 +174,10 @@ export default class extends Endpoint { // eslint- throw new ApiError(meta.errors.noSuchUser); } + if (this.serverSettings.ugcVisibilityForVisitor === 'local' && user.host != null && me == null) { + throw new ApiError(meta.errors.noSuchUser); + } + if (user.host == null) { if (me == null && ip != null) { this.perUserPvChart.commitByVisitor(user, ip); diff --git a/packages/backend/src/server/api/endpoints/v2/admin/emoji/list.ts b/packages/backend/src/server/api/endpoints/v2/admin/emoji/list.ts index 7139715293..c07d100a99 100644 --- a/packages/backend/src/server/api/endpoints/v2/admin/emoji/list.ts +++ b/packages/backend/src/server/api/endpoints/v2/admin/emoji/list.ts @@ -7,6 +7,7 @@ import { Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { EmojiEntityService } from '@/core/entities/EmojiEntityService.js'; import { CustomEmojiService, fetchEmojisHostTypes, fetchEmojisSortKeys } from '@/core/CustomEmojiService.js'; +import { IdService } from '@/core/IdService.js'; export const meta = { tags: ['admin'], @@ -65,6 +66,8 @@ export const paramDef = { }, sinceId: { type: 'string', format: 'misskey:id' }, untilId: { type: 'string', format: 'misskey:id' }, + sinceDate: { type: 'integer' }, + untilDate: { type: 'integer' }, limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 }, page: { type: 'integer' }, sortKeys: { @@ -84,8 +87,12 @@ export default class extends Endpoint { // eslint- constructor( private customEmojiService: CustomEmojiService, private emojiEntityService: EmojiEntityService, + private idService: IdService, ) { super(meta, paramDef, async (ps, me) => { + const untilId = ps.untilId ?? (ps.untilDate ? this.idService.gen(ps.untilDate!) : undefined); + const sinceId = ps.sinceId ?? (ps.sinceDate ? this.idService.gen(ps.sinceDate!) : undefined); + const q = ps.query; const result = await this.customEmojiService.fetchEmojis( { @@ -105,8 +112,8 @@ export default class extends Endpoint { // eslint- hostType: q?.hostType, roleIds: q?.roleIds, }, - sinceId: ps.sinceId, - untilId: ps.untilId, + sinceId: sinceId, + untilId: untilId, }, { limit: ps.limit, diff --git a/packages/backend/src/server/api/endpoints/verify-email.ts b/packages/backend/src/server/api/endpoints/verify-email.ts new file mode 100644 index 0000000000..e069ed59f2 --- /dev/null +++ b/packages/backend/src/server/api/endpoints/verify-email.ts @@ -0,0 +1,66 @@ +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { Inject, Injectable } from '@nestjs/common'; +import { Endpoint } from '@/server/api/endpoint-base.js'; +import type { UserProfilesRepository } from '@/models/_.js'; +import { UserEntityService } from '@/core/entities/UserEntityService.js'; +import { DI } from '@/di-symbols.js'; +import { GlobalEventService } from '@/core/GlobalEventService.js'; +import { ApiError } from '../error.js'; + +export const meta = { + requireCredential: false, + + tags: ['account'], + + errors: { + noSuchCode: { + message: 'No such code.', + code: 'NO_SUCH_CODE', + id: '97c1f576-e4b8-4b8a-a6dc-9cb65e7f6f85', + }, + }, +} as const; + +export const paramDef = { + type: 'object', + properties: { + code: { type: 'string' }, + }, + required: ['code'], +} as const; + +@Injectable() +export default class extends Endpoint { // eslint-disable-line import/no-default-export + constructor( + @Inject(DI.userProfilesRepository) + private userProfilesRepository: UserProfilesRepository, + + private userEntityService: UserEntityService, + private globalEventService: GlobalEventService, + ) { + super(meta, paramDef, async (ps) => { + const profile = await this.userProfilesRepository.findOneBy({ + emailVerifyCode: ps.code, + }); + + if (profile == null) { + throw new ApiError(meta.errors.noSuchCode); + } + + await this.userProfilesRepository.update({ userId: profile.userId }, { + emailVerified: true, + emailVerifyCode: null, + }); + + this.globalEventService.publishMainStream(profile.userId, 'meUpdated', await this.userEntityService.pack(profile.userId, { id: profile.userId }, { + schema: 'MeDetailed', + includeSecrets: true, + })); + }); + } +} + diff --git a/packages/backend/src/server/api/openapi/gen-spec.ts b/packages/backend/src/server/api/openapi/gen-spec.ts index 882cb18a7e..86c24fe9f4 100644 --- a/packages/backend/src/server/api/openapi/gen-spec.ts +++ b/packages/backend/src/server/api/openapi/gen-spec.ts @@ -89,7 +89,8 @@ export function genOpenapiSpec(config: Config, includeSelfRef = false) { schema.required = undefined; } - const hasBody = (schema.type === 'object' && schema.properties && Object.keys(schema.properties).length >= 1); + const hasBody = (schema.type === 'object' && schema.properties && Object.keys(schema.properties).length >= 1) + || ['allOf', 'oneOf', 'anyOf'].some(o => (Array.isArray(schema[o]) && schema[o].length >= 0)); const info = { operationId: endpoint.name.replaceAll('/', '___'), // NOTE: スラッシュは使えない diff --git a/packages/backend/src/server/api/openapi/schemas.ts b/packages/backend/src/server/api/openapi/schemas.ts index c80dda8d96..1cdcbebd1a 100644 --- a/packages/backend/src/server/api/openapi/schemas.ts +++ b/packages/backend/src/server/api/openapi/schemas.ts @@ -38,14 +38,13 @@ export function convertSchemaToOpenApiSchema(schema: Schema, type: 'param' | 're if (type === 'res' && schema.ref && (!schema.selfRef || includeSelfRef)) { const $ref = `#/components/schemas/${schema.ref}`; - if (schema.nullable || schema.optional) { - res.allOf = [{ $ref }]; + if (schema.nullable) { + res.oneOf = [{ $ref }, { type: 'null' }]; } else { res.$ref = $ref; } - } - - if (schema.nullable) { + delete res.type; + } else if (schema.nullable) { if (Array.isArray(schema.type) && !schema.type.includes('null')) { res.type.push('null'); } else if (typeof schema.type === 'string') { diff --git a/packages/backend/src/server/api/stream/Connection.ts b/packages/backend/src/server/api/stream/Connection.ts index c9801d8314..8e28ab263b 100644 --- a/packages/backend/src/server/api/stream/Connection.ts +++ b/packages/backend/src/server/api/stream/Connection.ts @@ -32,7 +32,6 @@ export default class Connection { public subscriber: StreamEventEmitter; private channels: Channel[] = []; private subscribingNotes: Partial> = {}; - private cachedNotes: Packed<'Note'>[] = []; public userProfile: MiUserProfile | null = null; public following: Record | undefined> = {}; public followingChannels: Set = new Set(); @@ -132,26 +131,6 @@ export default class Connection { this.sendMessageToWs(data.type, data.body); } - @bindThis - public cacheNote(note: Packed<'Note'>) { - const add = (note: Packed<'Note'>) => { - const existIndex = this.cachedNotes.findIndex(n => n.id === note.id); - if (existIndex > -1) { - this.cachedNotes[existIndex] = note; - return; - } - - this.cachedNotes.unshift(note); - if (this.cachedNotes.length > 32) { - this.cachedNotes.splice(32); - } - }; - - add(note); - if (note.reply) add(note.reply); - if (note.renote) add(note.renote); - } - @bindThis private onReadNotification(payload: JsonValue | undefined) { this.notificationService.readAllNotification(this.user!.id); diff --git a/packages/backend/src/server/api/stream/channels/antenna.ts b/packages/backend/src/server/api/stream/channels/antenna.ts index 53dc7f18b6..e08562fdf9 100644 --- a/packages/backend/src/server/api/stream/channels/antenna.ts +++ b/packages/backend/src/server/api/stream/channels/antenna.ts @@ -43,8 +43,6 @@ class AntennaChannel extends Channel { if (this.isNoteMutedOrBlocked(note)) return; - this.connection.cacheNote(note); - this.send('note', note); } else { this.send(data.type, data.body); diff --git a/packages/backend/src/server/api/stream/channels/bubble-timeline.ts b/packages/backend/src/server/api/stream/channels/bubble-timeline.ts index c5c3a89e4e..9cde868e49 100644 --- a/packages/backend/src/server/api/stream/channels/bubble-timeline.ts +++ b/packages/backend/src/server/api/stream/channels/bubble-timeline.ts @@ -74,9 +74,7 @@ class BubbleTimelineChannel extends Channel { note.renote.myReaction = myRenoteReaction; } } - - this.connection.cacheNote(note); - + this.send('note', note); } diff --git a/packages/backend/src/server/api/stream/channels/channel.ts b/packages/backend/src/server/api/stream/channels/channel.ts index 7108e0cd6e..ac79c31854 100644 --- a/packages/backend/src/server/api/stream/channels/channel.ts +++ b/packages/backend/src/server/api/stream/channels/channel.ts @@ -49,8 +49,6 @@ class ChannelChannel extends Channel { } } - this.connection.cacheNote(note); - this.send('note', note); } diff --git a/packages/backend/src/server/api/stream/channels/global-timeline.ts b/packages/backend/src/server/api/stream/channels/global-timeline.ts index 0d8b084a7d..4a743341d2 100644 --- a/packages/backend/src/server/api/stream/channels/global-timeline.ts +++ b/packages/backend/src/server/api/stream/channels/global-timeline.ts @@ -68,8 +68,6 @@ class GlobalTimelineChannel extends Channel { } } - this.connection.cacheNote(note); - this.send('note', note); } diff --git a/packages/backend/src/server/api/stream/channels/hashtag.ts b/packages/backend/src/server/api/stream/channels/hashtag.ts index 8105f15cb1..c911d63642 100644 --- a/packages/backend/src/server/api/stream/channels/hashtag.ts +++ b/packages/backend/src/server/api/stream/channels/hashtag.ts @@ -53,8 +53,6 @@ class HashtagChannel extends Channel { } } - this.connection.cacheNote(note); - this.send('note', note); } diff --git a/packages/backend/src/server/api/stream/channels/home-timeline.ts b/packages/backend/src/server/api/stream/channels/home-timeline.ts index 0c6f4f3a1b..55fbbc0f1d 100644 --- a/packages/backend/src/server/api/stream/channels/home-timeline.ts +++ b/packages/backend/src/server/api/stream/channels/home-timeline.ts @@ -89,8 +89,6 @@ class HomeTimelineChannel extends Channel { } } - this.connection.cacheNote(note); - this.send('note', note); } diff --git a/packages/backend/src/server/api/stream/channels/hybrid-timeline.ts b/packages/backend/src/server/api/stream/channels/hybrid-timeline.ts index 9d01efcb7f..ef1f6992da 100644 --- a/packages/backend/src/server/api/stream/channels/hybrid-timeline.ts +++ b/packages/backend/src/server/api/stream/channels/hybrid-timeline.ts @@ -103,8 +103,6 @@ class HybridTimelineChannel extends Channel { } } - this.connection.cacheNote(note); - this.send('note', note); } diff --git a/packages/backend/src/server/api/stream/channels/local-timeline.ts b/packages/backend/src/server/api/stream/channels/local-timeline.ts index a8f85c54e9..cdada3650d 100644 --- a/packages/backend/src/server/api/stream/channels/local-timeline.ts +++ b/packages/backend/src/server/api/stream/channels/local-timeline.ts @@ -78,8 +78,6 @@ class LocalTimelineChannel extends Channel { } } - this.connection.cacheNote(note); - this.send('note', note); } diff --git a/packages/backend/src/server/api/stream/channels/main.ts b/packages/backend/src/server/api/stream/channels/main.ts index 863d7f4c4e..525f24c105 100644 --- a/packages/backend/src/server/api/stream/channels/main.ts +++ b/packages/backend/src/server/api/stream/channels/main.ts @@ -39,7 +39,6 @@ class MainChannel extends Channel { const note = await this.noteEntityService.pack(data.body.note.id, this.user, { detail: true, }); - this.connection.cacheNote(note); data.body.note = note; } break; @@ -52,7 +51,6 @@ class MainChannel extends Channel { const note = await this.noteEntityService.pack(data.body.id, this.user, { detail: true, }); - this.connection.cacheNote(note); data.body = note; } break; diff --git a/packages/backend/src/server/api/stream/channels/user-list.ts b/packages/backend/src/server/api/stream/channels/user-list.ts index 4f38351e94..5bfd8fa68c 100644 --- a/packages/backend/src/server/api/stream/channels/user-list.ts +++ b/packages/backend/src/server/api/stream/channels/user-list.ts @@ -118,8 +118,6 @@ class UserListChannel extends Channel { } } - this.connection.cacheNote(note); - this.send('note', note); } diff --git a/packages/backend/src/server/oauth/OAuth2ProviderService.ts b/packages/backend/src/server/oauth/OAuth2ProviderService.ts index 93b8646468..bb35b72631 100644 --- a/packages/backend/src/server/oauth/OAuth2ProviderService.ts +++ b/packages/backend/src/server/oauth/OAuth2ProviderService.ts @@ -130,11 +130,11 @@ async function discoverClientInformation(logger: Logger, httpRequestService: Htt const microformats = mf2(text, { baseUrl: res.url }); const correspondingProperties = microformats.items.find(item => item.type?.includes('h-app') && item.properties.url.includes(id)); if (correspondingProperties) { - const nameProperty = correspondingProperties.properties.name[0]; + const nameProperty = correspondingProperties.properties.name?.[0]; if (typeof nameProperty === 'string') { name = nameProperty; } - const logoProperty = correspondingProperties.properties.logo[0]; + const logoProperty = correspondingProperties.properties.logo?.[0]; if (typeof logoProperty === 'string') { logo = logoProperty; } diff --git a/packages/backend/src/server/web/ClientServerService.ts b/packages/backend/src/server/web/ClientServerService.ts index cf3a283f34..2f381621b7 100644 --- a/packages/backend/src/server/web/ClientServerService.ts +++ b/packages/backend/src/server/web/ClientServerService.ts @@ -20,19 +20,6 @@ import type { Config } from '@/config.js'; import { getNoteSummary } from '@/misc/get-note-summary.js'; import { DI } from '@/di-symbols.js'; import * as Acct from '@/misc/acct.js'; -import type { - DbQueue, - DeliverQueue, - EndedPollNotificationQueue, - InboxQueue, - ObjectStorageQueue, - RelationshipQueue, - SystemQueue, - UserWebhookDeliverQueue, - SystemWebhookDeliverQueue, - ScheduledNoteDeleteQueue, - ScheduleNotePostQueue, -} from '@/core/QueueModule.js'; import { UserEntityService } from '@/core/entities/UserEntityService.js'; import { NoteEntityService } from '@/core/entities/NoteEntityService.js'; import { PageEntityService } from '@/core/entities/PageEntityService.js'; @@ -131,18 +118,6 @@ export class ClientServerService { private feedService: FeedService, private roleService: RoleService, private clientLoggerService: ClientLoggerService, - - @Inject('queue:system') public systemQueue: SystemQueue, - @Inject('queue:endedPollNotification') public endedPollNotificationQueue: EndedPollNotificationQueue, - @Inject('queue:deliver') public deliverQueue: DeliverQueue, - @Inject('queue:inbox') public inboxQueue: InboxQueue, - @Inject('queue:db') public dbQueue: DbQueue, - @Inject('queue:relationship') public relationshipQueue: RelationshipQueue, - @Inject('queue:objectStorage') public objectStorageQueue: ObjectStorageQueue, - @Inject('queue:userWebhookDeliver') public userWebhookDeliverQueue: UserWebhookDeliverQueue, - @Inject('queue:systemWebhookDeliver') public systemWebhookDeliverQueue: SystemWebhookDeliverQueue, - @Inject('queue:scheduledNoteDelete') public scheduledNoteDeleteQueue: ScheduledNoteDeleteQueue, - @Inject('queue:scheduleNotePost') public scheduleNotePostQueue: ScheduleNotePostQueue, ) { //this.createServer = this.createServer.bind(this); } @@ -192,6 +167,10 @@ export class ClientServerService { 'url': 'url', }, }, + 'shortcuts': [{ + 'name': 'Safemode', + 'url': '/?safemode=true', + }], }; manifest = { @@ -217,12 +196,15 @@ export class ClientServerService { instanceUrl: this.config.url, metaJson: htmlSafeJsonStringify(await this.metaEntityService.packDetailed(meta)), now: Date.now(), + federationEnabled: this.meta.federation !== 'none', customSplashText: meta.customSplashText[Math.floor(Math.random() * meta.customSplashText.length)], }; } @bindThis public createServer(fastify: FastifyInstance, options: FastifyPluginOptions, done: (err?: Error) => void) { + const configUrl = new URL(this.config.url); + fastify.register(fastifyView, { root: _dirname + '/views', engine: { @@ -262,7 +244,6 @@ export class ClientServerService { done(); }); } else { - const configUrl = new URL(this.config.url); const urlOriginWithoutPort = configUrl.origin.replace(/:\d+$/, ''); const port = (process.env.VITE_PORT ?? '5173'); @@ -528,7 +509,12 @@ export class ClientServerService { vary(reply.raw, 'Accept'); - if (user != null) { + if ( + user != null && ( + this.meta.ugcVisibilityForVisitor === 'all' || + (this.meta.ugcVisibilityForVisitor === 'local' && user.host == null) + ) + ) { const profile = await this.userProfilesRepository.findOneByOrFail({ userId: user.id }); const me = profile.fields ? profile.fields @@ -589,10 +575,16 @@ export class ClientServerService { id: request.params.note, visibility: In(['public', 'home']), }, - relations: ['user'], + relations: ['user', 'reply', 'renote'], }); - if (note && !note.user!.requireSigninToViewContents) { + if ( + note && + !note.user!.requireSigninToViewContents && + (this.meta.ugcVisibilityForVisitor === 'all' || + (this.meta.ugcVisibilityForVisitor === 'local' && note.userHost == null) + ) + ) { const _note = await this.noteEntityService.pack(note); const profile = await this.userProfilesRepository.findOneByOrFail({ userId: note.userId }); reply.header('Cache-Control', 'public, max-age=15'); @@ -824,8 +816,11 @@ export class ClientServerService { fastify.get<{ Params: { note: string; } }>('/embed/notes/:note', async (request, reply) => { reply.removeHeader('X-Frame-Options'); - const note = await this.notesRepository.findOneBy({ - id: request.params.note, + const note = await this.notesRepository.findOne({ + where: { + id: request.params.note, + }, + relations: ['user', 'reply', 'renote'], }); if (note == null) return; @@ -907,6 +902,22 @@ export class ClientServerService { [, ...target.split('/').filter(x => x), ...source.split('/').filter(x => x).splice(depth)].join('/'); fastify.get('/flush', async (request, reply) => { + let sendHeader = true; + + if (request.headers['origin']) { + const originURL = new URL(request.headers['origin']); + if (originURL.protocol !== 'https:') { // Clear-Site-Data only supports https + sendHeader = false; + } + if (originURL.host !== configUrl.host) { + sendHeader = false; + } + } + + if (sendHeader) { + reply.header('Clear-Site-Data', '"*"'); + } + reply.header('Set-Cookie', 'http-flush-failed=1; Path=/flush; Max-Age=60'); return await reply.view('flush'); }); diff --git a/packages/backend/src/server/web/UrlPreviewService.ts b/packages/backend/src/server/web/UrlPreviewService.ts index 531d085315..b9a4015031 100644 --- a/packages/backend/src/server/web/UrlPreviewService.ts +++ b/packages/backend/src/server/web/UrlPreviewService.ts @@ -94,8 +94,8 @@ export class UrlPreviewService { summary.icon = this.wrap(summary.icon); summary.thumbnail = this.wrap(summary.thumbnail); - // Cache 7days - reply.header('Cache-Control', 'max-age=604800, immutable'); + // Cache 1day + reply.header('Cache-Control', 'max-age=86400, immutable'); return summary; } catch (err) { @@ -122,7 +122,7 @@ export class UrlPreviewService { : undefined; return summaly(url, { - followRedirects: false, + followRedirects: this.meta.urlPreviewAllowRedirect, lang: lang ?? 'ja-JP', agent: agent, userAgent: meta.urlPreviewUserAgent ?? undefined, @@ -137,6 +137,7 @@ export class UrlPreviewService { const queryStr = query({ url: url, lang: lang ?? 'ja-JP', + followRedirects: this.meta.urlPreviewAllowRedirect, userAgent: meta.urlPreviewUserAgent ?? undefined, operationTimeout: meta.urlPreviewTimeout, contentLengthLimit: meta.urlPreviewMaximumContentLength, diff --git a/packages/backend/src/server/web/boot.embed.js b/packages/backend/src/server/web/boot.embed.js index 301cb952eb..e3e7e7d6fd 100644 --- a/packages/backend/src/server/web/boot.embed.js +++ b/packages/backend/src/server/web/boot.embed.js @@ -32,67 +32,30 @@ } //#region Detect language & fetch translations - if (!localStorage.hasOwnProperty('locale')) { - const supportedLangs = LANGS; - let lang = localStorage.getItem('lang'); - if (lang == null || !supportedLangs.includes(lang)) { - if (supportedLangs.includes(navigator.language)) { - lang = navigator.language; - } else { - lang = supportedLangs.find(x => x.split('-')[0] === navigator.language); - - // Fallback - if (lang == null) lang = 'en-US'; - } - } - - const metaRes = await window.fetch('/api/meta', { - method: 'POST', - body: JSON.stringify({}), - credentials: 'omit', - cache: 'no-cache', - headers: { - 'Content-Type': 'application/json', - }, - }); - if (metaRes.status !== 200) { - renderError('META_FETCH'); - return; - } - const meta = await metaRes.json(); - const v = meta.version; - const basedMisskeyVersion = meta.basedMisskeyVersion; - if (v == null) { - renderError('META_FETCH_V'); - return; - } - - if (basedMisskeyVersion == null) { - renderError('META_FETCH_BASEDMISSKEY_V'); - return; - } + const supportedLangs = LANGS; + /** @type { string } */ + let lang = localStorage.getItem('lang'); + if (lang == null || !supportedLangs.includes(lang)) { + if (supportedLangs.includes(navigator.language)) { + lang = navigator.language; + } else { + lang = supportedLangs.find(x => x.split('-')[0] === navigator.language); - // for https://github.com/misskey-dev/misskey/issues/10202 - if (lang == null || lang.toString == null || lang.toString() === 'null') { - console.error('invalid lang value detected!!!', typeof lang, lang); - lang = 'en-US'; + // Fallback + if (lang == null) lang = 'en-US'; } + } - const localRes = await window.fetch(`/assets/locales/${lang}.${v}.json`); - if (localRes.status === 200) { - localStorage.setItem('lang', lang); - localStorage.setItem('locale', await localRes.text()); - localStorage.setItem('localeVersion', v); - } else { - renderError('LOCALE_FETCH'); - return; - } + // for https://github.com/misskey-dev/misskey/issues/10202 + if (lang == null || lang.toString == null || lang.toString() === 'null') { + console.error('invalid lang value detected!!!', typeof lang, lang); + lang = 'en-US'; } //#endregion //#region Script async function importAppScript() { - await import(`/embed_vite/${CLIENT_ENTRY}`) + await import(CLIENT_ENTRY ? `/embed_vite/${CLIENT_ENTRY.replace('scripts', lang)}` : '/embed_vite/src/_boot_.ts') .catch(async e => { console.error(e); renderError('APP_IMPORT'); @@ -121,10 +84,26 @@ await new Promise(resolve => window.addEventListener('DOMContentLoaded', resolve)); } - const locale = JSON.parse(localStorage.getItem('locale') || '{}'); + let messages = null; + const bootloaderLocales = localStorage.getItem('bootloaderLocales'); + if (bootloaderLocales) { + messages = JSON.parse(bootloaderLocales); + } + if (!messages) { + // older version of cherrypick does not store bootloaderLocales, stores locale as a whole + const legacyLocale = localStorage.getItem('locale'); + if (legacyLocale) { + const parsed = JSON.parse(legacyLocale); + messages = { + ...(parsed._bootErrors ?? {}), + reload: parsed.reload, + }; + } + } + if (!messages) messages = {}; - const title = locale?._bootErrors?.title || 'Failed to initialize CherryPick'; - const reload = locale?.reload || 'Reload'; + const title = messages?.title || 'Failed to initialize CherryPick'; + const reload = messages?.reload || 'Reload'; document.body.innerHTML = `

${title}
diff --git a/packages/backend/src/server/web/boot.js b/packages/backend/src/server/web/boot.js index cc79a26f36..190574235a 100644 --- a/packages/backend/src/server/web/boot.js +++ b/packages/backend/src/server/web/boot.js @@ -13,7 +13,7 @@ }; window.onunhandledrejection = (e) => { console.error(e); - renderError('SOMETHING_HAPPENED_IN_PROMISE', e); + renderError('SOMETHING_HAPPENED_IN_PROMISE', e.reason || e); }; let forceError = localStorage.getItem('forceError'); @@ -22,67 +22,31 @@ return; } - //#region Detect language & fetch translations - if (!localStorage.hasOwnProperty('locale')) { - const supportedLangs = LANGS; - let lang = localStorage.getItem('lang'); - if (lang == null || !supportedLangs.includes(lang)) { - if (supportedLangs.includes(navigator.language)) { - lang = navigator.language; - } else { - lang = supportedLangs.find(x => x.split('-')[0] === navigator.language); - - // Fallback - if (lang == null) lang = 'en-US'; - } - } - - const metaRes = await window.fetch('/api/meta', { - method: 'POST', - body: JSON.stringify({}), - credentials: 'omit', - cache: 'no-cache', - headers: { - 'Content-Type': 'application/json', - }, - }); - if (metaRes.status !== 200) { - renderError('META_FETCH'); - return; - } - const meta = await metaRes.json(); - const v = meta.version; - const basedMisskeyVersion = meta.basedMisskeyVersion; - if (v == null) { - renderError('META_FETCH_V'); - return; - } - if (basedMisskeyVersion == null) { - renderError('META_FETCH_BASEDMISSKEY_V'); - return; - } + //#region Detect language + const supportedLangs = LANGS; + /** @type { string } */ + let lang = localStorage.getItem('lang'); + if (lang == null || !supportedLangs.includes(lang)) { + if (supportedLangs.includes(navigator.language)) { + lang = navigator.language; + } else { + lang = supportedLangs.find(x => x.split('-')[0] === navigator.language); - // for https://github.com/misskey-dev/misskey/issues/10202 - if (lang == null || lang.toString == null || lang.toString() === 'null') { - console.error('invalid lang value detected!!!', typeof lang, lang); - lang = 'en-US'; + // Fallback + if (lang == null) lang = 'en-US'; } + } - const localRes = await window.fetch(`/assets/locales/${lang}.${v}.json`); - if (localRes.status === 200) { - localStorage.setItem('lang', lang); - localStorage.setItem('locale', await localRes.text()); - localStorage.setItem('localeVersion', v); - } else { - renderError('LOCALE_FETCH'); - return; - } + // for https://github.com/misskey-dev/misskey/issues/10202 + if (lang == null || lang.toString == null || lang.toString() === 'null') { + console.error('invalid lang value detected!!!', typeof lang, lang); + lang = 'en-US'; } //#endregion //#region Script async function importAppScript() { - await import(`/vite/${CLIENT_ENTRY}`) + await import(CLIENT_ENTRY ? `/vite/${CLIENT_ENTRY.replace('scripts', lang)}` : '/vite/src/_boot_.ts') .catch(async e => { console.error(e); renderError('APP_IMPORT', e); @@ -99,23 +63,37 @@ } //#endregion + let isSafeMode = (localStorage.getItem('isSafeMode') === 'true'); + + if (!isSafeMode) { + const urlParams = new URLSearchParams(window.location.search); + + if (urlParams.has('safemode') && urlParams.get('safemode') === 'true') { + localStorage.setItem('isSafeMode', 'true'); + isSafeMode = true; + } + } + //#region Theme - const theme = localStorage.getItem('theme'); - if (theme) { - for (const [k, v] of Object.entries(JSON.parse(theme))) { - document.documentElement.style.setProperty(`--MI_THEME-${k}`, v.toString()); - - // HTMLの theme-color 適用 - if (k === 'htmlThemeColor') { - for (const tag of document.head.children) { - if (tag.tagName === 'META' && tag.getAttribute('name') === 'theme-color') { - tag.setAttribute('content', v); - break; + if (!isSafeMode) { + const theme = localStorage.getItem('theme'); + if (theme) { + for (const [k, v] of Object.entries(JSON.parse(theme))) { + document.documentElement.style.setProperty(`--MI_THEME-${k}`, v.toString()); + + // HTMLの theme-color 適用 + if (k === 'htmlThemeColor') { + for (const tag of document.head.children) { + if (tag.tagName === 'META' && tag.getAttribute('name') === 'theme-color') { + tag.setAttribute('content', v); + break; + } } } } } } + const colorScheme = localStorage.getItem('colorScheme'); if (colorScheme) { document.documentElement.style.setProperty('color-scheme', colorScheme); @@ -137,11 +115,13 @@ document.documentElement.classList.add('useSystemFont'); } - const customCss = localStorage.getItem('customCss'); - if (customCss && customCss.length > 0) { - const style = document.createElement('style'); - style.innerHTML = customCss; - document.head.appendChild(style); + if (!isSafeMode) { + const customCss = localStorage.getItem('customCss'); + if (customCss && customCss.length > 0) { + const style = document.createElement('style'); + style.innerHTML = customCss; + document.head.appendChild(style); + } } async function addStyle(styleText) { @@ -156,9 +136,25 @@ await new Promise(resolve => window.addEventListener('DOMContentLoaded', resolve)); } - const locale = JSON.parse(localStorage.getItem('locale') || '{}'); + let messages = null; + const bootloaderLocales = localStorage.getItem('bootloaderLocales'); + if (bootloaderLocales) { + messages = JSON.parse(bootloaderLocales); + } + if (!messages) { + // older version of cherrypick does not store bootloaderLocales, stores locale as a whole + const legacyLocale = localStorage.getItem('locale'); + if (legacyLocale) { + const parsed = JSON.parse(legacyLocale); + messages = { + ...(parsed._bootErrors ?? {}), + reload: parsed.reload, + }; + } + } + if (!messages) messages = {}; - const messages = Object.assign({ + messages = Object.assign({ title: 'Failed to initialize CherryPick', solution: 'The following actions may solve the problem.', solution1: 'Update your os and browser', @@ -169,8 +165,12 @@ otherOption1: 'Clear preferences and cache', otherOption2: 'Start the simple client', otherOption3: 'Start the repair tool', - }, locale?._bootErrors || {}); - const reload = locale?.reload || 'Reload'; + otherOption4: 'Start CherryPick in safe mode', + reload: 'Reload', + }, messages); + + const safeModeUrl = new URL(window.location.href); + safeModeUrl.searchParams.set('safemode', 'true'); let errorsElement = document.getElementById('errors'); @@ -183,7 +183,7 @@

${messages.title}

${messages.solution}

${messages.solution1}

@@ -192,6 +192,12 @@

${messages.solution4}

${messages.otherOption} + + + +
-
@@ -47,7 +47,7 @@ SPDX-License-Identifier: AGPL-3.0-only - +
+ + + + - + + + + + - + {{ i18n.ts.notSpecifiedMentionWarning }} -
{{ maxCwTextLength - cwTextLength }}
+
+
@@ -19,7 +19,7 @@ SPDX-License-Identifier: AGPL-3.0-only import { ref, watch } from 'vue'; import { useWidgetPropsManager } from './widget.js'; import type { WidgetComponentEmits, WidgetComponentExpose, WidgetComponentProps } from './widget.js'; -import type { GetFormResultType } from '@/utility/form.js'; +import type { FormWithDefault, GetFormResultType } from '@/utility/form.js'; import MkContainer from '@/components/MkContainer.vue'; import { store } from '@/store.js'; import { i18n } from '@/i18n.js'; @@ -28,14 +28,14 @@ const name = 'memo'; const widgetPropsDef = { showHeader: { - type: 'boolean' as const, + type: 'boolean', default: true, }, height: { - type: 'number' as const, + type: 'number', default: 100, }, -}; +} satisfies FormWithDefault; type WidgetProps = GetFormResultType; diff --git a/packages/frontend/src/widgets/WidgetNotifications.vue b/packages/frontend/src/widgets/WidgetNotifications.vue index 7db8adc57f..0c64b04004 100644 --- a/packages/frontend/src/widgets/WidgetNotifications.vue +++ b/packages/frontend/src/widgets/WidgetNotifications.vue @@ -8,12 +8,12 @@ SPDX-License-Identifier: AGPL-3.0-only
- +
@@ -21,10 +21,11 @@ SPDX-License-Identifier: AGPL-3.0-only `; + return `${messages.title}
${messages.header}
v${_VERSION_}
${_BASEDMISSKEYVERSION_}
`; } globalThis.addEventListener('fetch', ev => { @@ -126,6 +126,9 @@ globalThis.addEventListener('notificationclick', (ev: ServiceWorkerGlobalScopeEv case 'groupInvited': await swos.api('users/groups/invitations/accept', loginId, { invitationId: data.body.invitation.id }); break; + case 'chatRoomInvitationReceived': + await swos.api('chat/rooms/join', loginId, { roomId: data.body.invitation.roomId }); + break; } break; case 'reject': @@ -136,6 +139,16 @@ globalThis.addEventListener('notificationclick', (ev: ServiceWorkerGlobalScopeEv case 'groupInvited': await swos.api('users/groups/invitations/reject', loginId, { invitationId: data.body.invitation.id }); break; + case 'chatRoomInvitationReceived': + await swos.api('chat/rooms/invitations/reject', loginId, { roomId: data.body.invitation.roomId }); + break; + } + break; + case 'ignore': + switch (data.body.type) { + case 'chatRoomInvitationReceived': + await swos.api('chat/rooms/invitations/ignore', loginId, { roomId: data.body.invitation.roomId }); + break; } break; case 'showFollowRequests': @@ -152,6 +165,9 @@ globalThis.addEventListener('notificationclick', (ev: ServiceWorkerGlobalScopeEv case 'reaction': client = await swos.openNote(data.body.note.id, loginId); break; + case 'chatRoomInvitationReceived': + client = await swos.openClient('push', '/chat', loginId); + break; default: if ('note' in data.body) { client = await swos.openNote(data.body.note.id, loginId); diff --git a/patches/.gitkeep b/patches/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 83e01a5cd2..daeeab4a78 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -14,78 +14,78 @@ importers: .: dependencies: cssnano: - specifier: 7.0.6 - version: 7.0.6(postcss@8.5.3) + specifier: 7.1.1 + version: 7.1.1(postcss@8.5.6) esbuild: - specifier: 0.25.3 - version: 0.25.3 + specifier: 0.25.10 + version: 0.25.10 execa: - specifier: 9.5.2 - version: 9.5.2 + specifier: 9.6.0 + version: 9.6.0 fast-glob: specifier: 3.3.3 version: 3.3.3 glob: - specifier: 11.0.2 - version: 11.0.2 + specifier: 11.0.3 + version: 11.0.3 ignore-walk: - specifier: 7.0.0 - version: 7.0.0 + specifier: 8.0.0 + version: 8.0.0 js-yaml: specifier: 4.1.0 version: 4.1.0 postcss: - specifier: 8.5.3 - version: 8.5.3 + specifier: 8.5.6 + version: 8.5.6 tar: - specifier: 7.4.3 - version: 7.4.3 + specifier: 7.5.1 + version: 7.5.1 terser: - specifier: 5.39.0 - version: 5.39.0 + specifier: 5.44.0 + version: 5.44.0 typescript: - specifier: 5.8.3 - version: 5.8.3 - vite: - specifier: ^5.4.19 - version: 5.4.19(@types/node@22.15.2)(sass@1.87.0)(terser@5.39.0) + specifier: 5.9.3 + version: 5.9.3 devDependencies: '@biomejs/biome': - specifier: 1.9.4 - version: 1.9.4 + specifier: 2.3.1 + version: 2.3.1 '@misskey-dev/eslint-plugin': specifier: 2.1.0 - version: 2.1.0(@eslint/compat@1.3.0(eslint@9.25.1))(@stylistic/eslint-plugin@4.4.1(eslint@9.25.1)(typescript@5.8.3))(@typescript-eslint/eslint-plugin@8.31.0(@typescript-eslint/parser@8.31.0(eslint@9.25.1)(typescript@5.8.3))(eslint@9.25.1)(typescript@5.8.3))(@typescript-eslint/parser@8.31.0(eslint@9.25.1)(typescript@5.8.3))(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.31.0(eslint@9.25.1)(typescript@5.8.3))(eslint@9.25.1))(eslint@9.25.1)(globals@16.0.0) + version: 2.1.0(@eslint/compat@1.1.1)(@stylistic/eslint-plugin@3.1.0(eslint@9.37.0)(typescript@5.9.3))(@typescript-eslint/eslint-plugin@8.46.1(@typescript-eslint/parser@8.46.1(eslint@9.37.0)(typescript@5.9.3))(eslint@9.37.0)(typescript@5.9.3))(@typescript-eslint/parser@8.46.1(eslint@9.37.0)(typescript@5.9.3))(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.46.1(eslint@9.37.0)(typescript@5.9.3))(eslint@9.37.0))(eslint@9.37.0)(globals@16.4.0) + '@types/js-yaml': + specifier: 4.0.9 + version: 4.0.9 '@types/node': - specifier: 22.15.2 - version: 22.15.2 + specifier: 24.9.1 + version: 24.9.1 '@typescript-eslint/eslint-plugin': - specifier: 8.31.0 - version: 8.31.0(@typescript-eslint/parser@8.31.0(eslint@9.25.1)(typescript@5.8.3))(eslint@9.25.1)(typescript@5.8.3) + specifier: 8.46.1 + version: 8.46.1(@typescript-eslint/parser@8.46.1(eslint@9.37.0)(typescript@5.9.3))(eslint@9.37.0)(typescript@5.9.3) '@typescript-eslint/parser': - specifier: 8.31.0 - version: 8.31.0(eslint@9.25.1)(typescript@5.8.3) + specifier: 8.46.1 + version: 8.46.1(eslint@9.37.0)(typescript@5.9.3) cross-env: - specifier: 7.0.3 - version: 7.0.3 + specifier: 10.1.0 + version: 10.1.0 cypress: - specifier: 14.3.2 - version: 14.3.2 + specifier: 15.4.0 + version: 15.4.0 eslint: - specifier: 9.25.1 - version: 9.25.1 + specifier: 9.37.0 + version: 9.37.0 globals: - specifier: 16.0.0 - version: 16.0.0 + specifier: 16.4.0 + version: 16.4.0 ncp: specifier: 2.0.0 version: 2.0.0 pnpm: - specifier: 10.10.0 - version: 10.10.0 + specifier: 10.18.2 + version: 10.18.2 start-server-and-test: - specifier: 2.0.11 - version: 2.0.11 + specifier: 2.1.2 + version: 2.1.2 optionalDependencies: '@tensorflow/tfjs-core': specifier: 4.22.0 @@ -94,17 +94,17 @@ importers: packages/backend: dependencies: '@aws-sdk/client-s3': - specifier: 3.797.0 - version: 3.797.0 + specifier: 3.908.0 + version: 3.908.0 '@aws-sdk/lib-storage': - specifier: 3.797.0 - version: 3.797.0(@aws-sdk/client-s3@3.797.0) + specifier: 3.908.0 + version: 3.908.0(@aws-sdk/client-s3@3.908.0) '@discordapp/twemoji': - specifier: 15.1.0 - version: 15.1.0 + specifier: 16.0.1 + version: 16.0.1 '@fastify/accepts': - specifier: 5.0.2 - version: 5.0.2 + specifier: 5.0.3 + version: 5.0.3 '@fastify/cookie': specifier: 11.0.2 version: 11.0.2 @@ -118,11 +118,11 @@ importers: specifier: 10.0.2 version: 10.0.2(bufferutil@4.0.9)(utf-8-validate@6.0.5) '@fastify/multipart': - specifier: 9.0.3 - version: 9.0.3 + specifier: 9.2.1 + version: 9.2.1 '@fastify/static': - specifier: 8.1.1 - version: 8.1.1 + specifier: 8.2.0 + version: 8.2.0 '@fastify/view': specifier: 10.0.2 version: 10.0.2 @@ -131,34 +131,34 @@ importers: version: 10.5.0(encoding@0.1.13) '@google-cloud/translate': specifier: ^7.2.1 - version: 7.2.2(encoding@0.1.13) + version: 7.2.1(encoding@0.1.13) '@misskey-dev/sharp-read-bmp': specifier: 1.2.0 version: 1.2.0 '@misskey-dev/summaly': - specifier: 5.2.1 - version: 5.2.1 + specifier: 5.2.4 + version: 5.2.4 '@napi-rs/canvas': - specifier: 0.1.69 - version: 0.1.69 + specifier: 0.1.80 + version: 0.1.80 '@nestjs/common': - specifier: 11.1.0 - version: 11.1.0(reflect-metadata@0.2.2)(rxjs@7.8.2) + specifier: 11.1.6 + version: 11.1.6(reflect-metadata@0.2.2)(rxjs@7.8.2) '@nestjs/core': - specifier: 11.1.0 - version: 11.1.0(@nestjs/common@11.1.0(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@10.4.17)(reflect-metadata@0.2.2)(rxjs@7.8.2) + specifier: 11.1.6 + version: 11.1.6(@nestjs/common@11.1.6(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@10.4.20)(reflect-metadata@0.2.2)(rxjs@7.8.2) '@nestjs/testing': - specifier: 11.1.0 - version: 11.1.0(@nestjs/common@11.1.0(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.0)(@nestjs/platform-express@10.4.17) + specifier: 11.1.6 + version: 11.1.6(@nestjs/common@11.1.6(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.6)(@nestjs/platform-express@10.4.20) '@peertube/http-signature': specifier: 1.7.0 version: 1.7.0 '@sentry/node': - specifier: 8.55.0 - version: 8.55.0 + specifier: 10.20.0 + version: 10.20.0 '@sentry/profiling-node': - specifier: 8.55.0 - version: 8.55.0 + specifier: 10.20.0 + version: 10.20.0 '@simplewebauthn/server': specifier: 12.0.0 version: 12.0.0(encoding@0.1.13) @@ -169,14 +169,14 @@ importers: specifier: 2.5.0 version: 2.5.0 '@swc/cli': - specifier: 0.7.3 - version: 0.7.3(@swc/core@1.11.22)(chokidar@4.0.3) + specifier: 0.7.8 + version: 0.7.8(@swc/core@1.13.5)(chokidar@4.0.3) '@swc/core': - specifier: 1.11.22 - version: 1.11.22 + specifier: 1.13.5 + version: 1.13.5 '@twemoji/parser': - specifier: 15.1.1 - version: 15.1.1 + specifier: 16.0.0 + version: 16.0.0 '@types/redis-info': specifier: 3.0.3 version: 3.0.3 @@ -208,8 +208,8 @@ importers: specifier: 1.20.3 version: 1.20.3 bullmq: - specifier: 5.51.1 - version: 5.51.1 + specifier: 5.61.0 + version: 5.61.0 cacheable-lookup: specifier: 7.0.0 version: 7.0.0 @@ -217,11 +217,11 @@ importers: specifier: 9.0.2 version: 9.0.2 chalk: - specifier: 5.4.1 - version: 5.4.1 + specifier: 5.6.2 + version: 5.6.2 chalk-template: - specifier: 1.1.0 - version: 1.1.0 + specifier: 1.1.2 + version: 1.1.2 cherrypick-js: specifier: workspace:* version: link:../cherrypick-js @@ -244,8 +244,8 @@ importers: specifier: 0.1.21 version: 0.1.21 fastify: - specifier: 5.3.2 - version: 5.3.2 + specifier: 5.6.1 + version: 5.6.1 fastify-raw-body: specifier: 5.0.0 version: 5.0.0 @@ -253,20 +253,20 @@ importers: specifier: 4.2.2 version: 4.2.2 file-type: - specifier: 19.6.0 - version: 19.6.0 + specifier: 21.0.0 + version: 21.0.0 fluent-ffmpeg: specifier: 2.1.3 version: 2.1.3 form-data: - specifier: 4.0.2 - version: 4.0.2 + specifier: 4.0.4 + version: 4.0.4 got: - specifier: 14.4.7 - version: 14.4.7 + specifier: 14.5.0 + version: 14.5.0 happy-dom: - specifier: 16.8.1 - version: 16.8.1 + specifier: 20.0.7 + version: 20.0.7 hpagent: specifier: 1.2.0 version: 1.2.0 @@ -277,8 +277,8 @@ importers: specifier: 1.1.3 version: 1.1.3 ioredis: - specifier: 5.6.1 - version: 5.6.1 + specifier: 5.8.1 + version: 5.8.1 ip-cidr: specifier: 4.0.2 version: 4.0.2 @@ -299,22 +299,22 @@ importers: version: 2.2.3 jsonld: specifier: 8.3.3 - version: 8.3.3(web-streams-polyfill@3.3.3) + version: 8.3.3(web-streams-polyfill@3.2.1) jsrsasign: specifier: 11.1.0 version: 11.1.0 juice: - specifier: 11.0.1 - version: 11.0.1 + specifier: 11.0.3 + version: 11.0.3 meilisearch: - specifier: 0.50.0 - version: 0.50.0 + specifier: 0.53.0 + version: 0.53.0 mfc-js: - specifier: 0.24.0-cherrypick.9 - version: 0.24.0-cherrypick.9 + specifier: 0.1.0 + version: 0.1.0 microformats-parser: - specifier: 2.0.2 - version: 2.0.2 + specifier: 2.0.4 + version: 2.0.4 mime-types: specifier: 2.1.35 version: 2.1.35 @@ -322,11 +322,11 @@ importers: specifier: workspace:* version: link:../misskey-reversi ms: - specifier: 3.0.0-canary.1 - version: 3.0.0-canary.1 + specifier: 3.0.0-canary.202508261828 + version: 3.0.0-canary.202508261828 nanoid: - specifier: 5.1.5 - version: 5.1.5 + specifier: 5.1.6 + version: 5.1.6 nested-property: specifier: 4.0.0 version: 4.0.0 @@ -334,8 +334,8 @@ importers: specifier: 3.3.2 version: 3.3.2 nodemailer: - specifier: 6.10.1 - version: 6.10.1 + specifier: 7.0.9 + version: 7.0.9 nsfwjs: specifier: 4.2.0 version: 4.2.0(@tensorflow/tfjs@4.22.0(encoding@0.1.13)(seedrandom@3.0.5))(buffer@6.0.3) @@ -352,14 +352,14 @@ importers: specifier: 0.0.14 version: 0.0.14 otpauth: - specifier: 9.4.0 - version: 9.4.0 + specifier: 9.4.1 + version: 9.4.1 parse5: specifier: 7.3.0 version: 7.3.0 pg: - specifier: 8.15.6 - version: 8.15.6 + specifier: 8.16.3 + version: 8.16.3 pkce-challenge: specifier: 4.1.0 version: 4.1.0 @@ -382,8 +382,8 @@ importers: specifier: 3.4.1 version: 3.4.1 re2: - specifier: 1.21.4 - version: 1.21.4 + specifier: 1.22.1 + version: 1.22.1 redis-info: specifier: 3.1.0 version: 3.1.0 @@ -403,14 +403,14 @@ importers: specifier: 7.8.2 version: 7.8.2 sanitize-html: - specifier: 2.16.0 - version: 2.16.0 + specifier: 2.17.0 + version: 2.17.0 secure-json-parse: specifier: 3.0.2 version: 3.0.2 semver: - specifier: 7.7.1 - version: 7.7.1 + specifier: 7.7.3 + version: 7.7.3 sharp: specifier: 0.33.5 version: 0.33.5 @@ -427,26 +427,26 @@ importers: specifier: ^7.1.0 version: 7.1.0 systeminformation: - specifier: 5.25.11 - version: 5.25.11 + specifier: 5.27.11 + version: 5.27.11 tinycolor2: specifier: 1.6.0 version: 1.6.0 tmp: - specifier: 0.2.3 - version: 0.2.3 + specifier: 0.2.5 + version: 0.2.5 tsc-alias: - specifier: 1.8.15 - version: 1.8.15 + specifier: 1.8.16 + version: 1.8.16 tsconfig-paths: specifier: 4.2.0 version: 4.2.0 typeorm: - specifier: 0.3.22 - version: 0.3.22(ioredis@5.6.1)(pg@8.15.6)(reflect-metadata@0.2.2) + specifier: 0.3.27 + version: 0.3.27(ioredis@5.8.1)(pg@8.16.3)(reflect-metadata@0.2.2) typescript: - specifier: 5.8.3 - version: 5.8.3 + specifier: 5.9.3 + version: 5.9.3 ulid: specifier: 2.4.0 version: 2.4.0 @@ -457,30 +457,30 @@ importers: specifier: 3.6.7 version: 3.6.7 ws: - specifier: 8.18.1 - version: 8.18.1(bufferutil@4.0.9)(utf-8-validate@6.0.5) + specifier: 8.18.3 + version: 8.18.3(bufferutil@4.0.9)(utf-8-validate@6.0.5) xev: specifier: 3.0.2 version: 3.0.2 devDependencies: '@biomejs/biome': - specifier: 1.9.4 - version: 1.9.4 + specifier: 2.3.1 + version: 2.3.1 '@jest/globals': specifier: 29.7.0 version: 29.7.0 '@nestjs/platform-express': - specifier: 10.4.17 - version: 10.4.17(@nestjs/common@11.1.0(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.0) + specifier: 10.4.20 + version: 10.4.20(@nestjs/common@11.1.6(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.6) '@sentry/vue': - specifier: 9.14.0 - version: 9.14.0(vue@3.5.13(typescript@5.8.3)) + specifier: 10.20.0 + version: 10.20.0(vue@3.5.22(typescript@5.9.3)) '@simplewebauthn/types': specifier: 12.0.0 version: 12.0.0 '@swc/jest': - specifier: 0.2.38 - version: 0.2.38(@swc/core@1.11.22) + specifier: 0.2.39 + version: 0.2.39(@swc/core@1.13.5) '@types/accepts': specifier: 1.3.7 version: 1.3.7 @@ -491,14 +491,14 @@ importers: specifier: 2.4.6 version: 2.4.6 '@types/body-parser': - specifier: 1.19.5 - version: 1.19.5 + specifier: 1.19.6 + version: 1.19.6 '@types/color-convert': specifier: 2.0.4 version: 2.0.4 '@types/content-disposition': - specifier: 0.5.8 - version: 0.5.8 + specifier: 0.5.9 + version: 0.5.9 '@types/fluent-ffmpeg': specifier: 2.1.27 version: 2.1.27 @@ -530,11 +530,11 @@ importers: specifier: 0.7.34 version: 0.7.34 '@types/node': - specifier: 22.15.2 - version: 22.15.2 + specifier: 24.9.1 + version: 24.9.1 '@types/nodemailer': - specifier: 6.4.17 - version: 6.4.17 + specifier: 6.4.20 + version: 6.4.20 '@types/oauth': specifier: 0.9.6 version: 0.9.6 @@ -545,8 +545,8 @@ importers: specifier: 0.1.2 version: 0.1.2 '@types/pg': - specifier: 8.11.14 - version: 8.11.14 + specifier: 8.15.5 + version: 8.15.5 '@types/pug': specifier: 2.0.10 version: 2.0.10 @@ -563,11 +563,11 @@ importers: specifier: 1.0.7 version: 1.0.7 '@types/sanitize-html': - specifier: 2.15.0 - version: 2.15.0 + specifier: 2.16.0 + version: 2.16.0 '@types/semver': - specifier: 7.7.0 - version: 7.7.0 + specifier: 7.7.1 + version: 7.7.1 '@types/simple-oauth2': specifier: 5.0.7 version: 5.0.7 @@ -593,11 +593,11 @@ importers: specifier: 8.18.1 version: 8.18.1 '@typescript-eslint/eslint-plugin': - specifier: 8.31.0 - version: 8.31.0(@typescript-eslint/parser@8.31.0(eslint@9.25.1)(typescript@5.8.3))(eslint@9.25.1)(typescript@5.8.3) + specifier: 8.46.1 + version: 8.46.1(@typescript-eslint/parser@8.46.1(eslint@9.37.0)(typescript@5.9.3))(eslint@9.37.0)(typescript@5.9.3) '@typescript-eslint/parser': - specifier: 8.31.0 - version: 8.31.0(eslint@9.25.1)(typescript@5.8.3) + specifier: 8.46.1 + version: 8.46.1(eslint@9.37.0)(typescript@5.9.3) aws-sdk-client-mock: specifier: 4.1.0 version: 4.1.0 @@ -605,8 +605,8 @@ importers: specifier: 7.0.3 version: 7.0.3 eslint-plugin-import: - specifier: 2.31.0 - version: 2.31.0(@typescript-eslint/parser@8.31.0(eslint@9.25.1)(typescript@5.8.3))(eslint@9.25.1) + specifier: 2.32.0 + version: 2.32.0(@typescript-eslint/parser@8.46.1(eslint@9.37.0)(typescript@5.9.3))(eslint@9.37.0) execa: specifier: 8.0.1 version: 8.0.1 @@ -615,7 +615,7 @@ importers: version: 9.0.0 jest: specifier: 29.7.0 - version: 29.7.0(@types/node@22.15.2) + version: 29.7.0(@types/node@24.9.1) jest-mock: specifier: 29.7.0 version: 29.7.0 @@ -629,45 +629,45 @@ importers: specifier: 5.1.0 version: 5.1.0 supertest: - specifier: 7.1.0 - version: 7.1.0 + specifier: 7.1.4 + version: 7.1.4 optionalDependencies: '@swc/core-android-arm64': specifier: 1.3.11 version: 1.3.11 '@swc/core-darwin-arm64': - specifier: 1.11.22 - version: 1.11.22 + specifier: 1.13.20 + version: 1.13.20 '@swc/core-darwin-x64': - specifier: 1.11.22 - version: 1.11.22 + specifier: 1.13.20 + version: 1.13.20 '@swc/core-freebsd-x64': specifier: 1.3.11 version: 1.3.11 '@swc/core-linux-arm-gnueabihf': - specifier: 1.11.22 - version: 1.11.22 + specifier: 1.13.20 + version: 1.13.20 '@swc/core-linux-arm64-gnu': - specifier: 1.11.22 - version: 1.11.22 + specifier: 1.13.20 + version: 1.13.20 '@swc/core-linux-arm64-musl': - specifier: 1.11.22 - version: 1.11.22 + specifier: 1.13.20 + version: 1.13.20 '@swc/core-linux-x64-gnu': - specifier: 1.11.22 - version: 1.11.22 + specifier: 1.13.20 + version: 1.13.20 '@swc/core-linux-x64-musl': - specifier: 1.11.22 - version: 1.11.22 + specifier: 1.13.20 + version: 1.13.20 '@swc/core-win32-arm64-msvc': - specifier: 1.11.22 - version: 1.11.22 + specifier: 1.13.20 + version: 1.13.20 '@swc/core-win32-ia32-msvc': - specifier: 1.11.22 - version: 1.11.22 + specifier: 1.13.20 + version: 1.13.20 '@swc/core-win32-x64-msvc': - specifier: 1.11.22 - version: 1.11.22 + specifier: 1.13.20 + version: 1.13.20 '@tensorflow/tfjs': specifier: 4.22.0 version: 4.22.0(encoding@0.1.13)(seedrandom@3.0.5) @@ -733,47 +733,32 @@ importers: version: 4.4.0 devDependencies: '@biomejs/biome': - specifier: 1.9.4 - version: 1.9.4 + specifier: 2.3.1 + version: 2.3.1 '@microsoft/api-extractor': - specifier: 7.52.5 - version: 7.52.5(@types/node@22.15.2) - '@swc/jest': - specifier: 0.2.38 - version: 0.2.38(@swc/core@1.11.22) - '@types/jest': - specifier: 29.5.14 - version: 29.5.14 + specifier: 7.53.1 + version: 7.53.1(@types/node@24.9.1) '@types/node': - specifier: 22.15.2 - version: 22.15.2 + specifier: 24.9.1 + version: 24.9.1 '@typescript-eslint/eslint-plugin': - specifier: 8.31.0 - version: 8.31.0(@typescript-eslint/parser@8.31.0(eslint@9.25.1)(typescript@5.8.3))(eslint@9.25.1)(typescript@5.8.3) + specifier: 8.46.1 + version: 8.46.1(@typescript-eslint/parser@8.46.1(eslint@9.37.0)(typescript@5.9.3))(eslint@9.37.0)(typescript@5.9.3) '@typescript-eslint/parser': - specifier: 8.31.0 - version: 8.31.0(eslint@9.25.1)(typescript@5.8.3) + specifier: 8.46.1 + version: 8.46.1(eslint@9.37.0)(typescript@5.9.3) + '@vitest/coverage-v8': + specifier: 3.2.4 + version: 3.2.4(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.9.1)(happy-dom@20.0.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)) esbuild: - specifier: 0.25.3 - version: 0.25.3 + specifier: 0.25.10 + version: 0.25.10 execa: - specifier: 8.0.1 - version: 8.0.1 + specifier: 9.6.0 + version: 9.6.0 glob: - specifier: 11.0.2 - version: 11.0.2 - jest: - specifier: 29.7.0 - version: 29.7.0(@types/node@22.15.2) - jest-fetch-mock: - specifier: 3.0.3 - version: 3.0.3(encoding@0.1.13) - jest-websocket-mock: - specifier: 2.5.0 - version: 2.5.0 - mock-socket: - specifier: 9.3.1 - version: 9.3.1 + specifier: 11.0.3 + version: 11.0.3 ncp: specifier: 2.0.0 version: 2.0.0 @@ -781,41 +766,47 @@ importers: specifier: 3.1.10 version: 3.1.10 tsd: - specifier: 0.32.0 - version: 0.32.0 + specifier: 0.33.0 + version: 0.33.0 typescript: - specifier: 5.8.3 - version: 5.8.3 + specifier: 5.9.3 + version: 5.9.3 + vitest: + specifier: 3.2.4 + version: 3.2.4(@types/debug@4.1.12)(@types/node@24.9.1)(happy-dom@20.0.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6) + vitest-websocket-mock: + specifier: 0.5.0 + version: 0.5.0(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.9.1)(happy-dom@20.0.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)) packages/cherrypick-js/generator: devDependencies: '@readme/openapi-parser': - specifier: 2.7.0 - version: 2.7.0(openapi-types@12.1.3) + specifier: 5.0.2 + version: 5.0.2(openapi-types@12.1.3) '@types/node': - specifier: 22.15.2 - version: 22.15.2 + specifier: 24.9.1 + version: 24.9.1 '@typescript-eslint/eslint-plugin': - specifier: 8.31.0 - version: 8.31.0(@typescript-eslint/parser@8.31.0(eslint@9.25.1)(typescript@5.8.3))(eslint@9.25.1)(typescript@5.8.3) + specifier: 8.46.1 + version: 8.46.1(@typescript-eslint/parser@8.46.1(eslint@9.37.0)(typescript@5.9.3))(eslint@9.37.0)(typescript@5.9.3) '@typescript-eslint/parser': - specifier: 8.31.0 - version: 8.31.0(eslint@9.25.1)(typescript@5.8.3) + specifier: 8.46.1 + version: 8.46.1(eslint@9.37.0)(typescript@5.9.3) openapi-types: specifier: 12.1.3 version: 12.1.3 openapi-typescript: - specifier: 6.7.6 - version: 6.7.6 + specifier: 7.9.1 + version: 7.9.1(typescript@5.9.3) ts-case-convert: specifier: 2.1.0 version: 2.1.0 tsx: - specifier: 4.19.3 - version: 4.19.3 + specifier: 4.20.6 + version: 4.20.6 typescript: - specifier: 5.8.3 - version: 5.8.3 + specifier: 5.9.3 + version: 5.9.3 packages/frontend: dependencies: @@ -824,10 +815,10 @@ importers: version: 1.1.0 '@dice-roller/rpg-dice-roller': specifier: ^5.5.0 - version: 5.5.1 + version: 5.5.0 '@discordapp/twemoji': - specifier: 15.1.0 - version: 15.1.0 + specifier: 16.0.1 + version: 16.0.1 '@github/webauthn-json': specifier: 2.1.1 version: 2.1.1 @@ -839,37 +830,37 @@ importers: version: 2024.1.0 '@rollup/plugin-json': specifier: 6.1.0 - version: 6.1.0(rollup@4.40.0) + version: 6.1.0(rollup@4.52.4) '@rollup/plugin-replace': specifier: 6.0.2 - version: 6.0.2(rollup@4.40.0) + version: 6.0.2(rollup@4.52.4) '@rollup/pluginutils': - specifier: 5.1.4 - version: 5.1.4(rollup@4.40.0) + specifier: 5.3.0 + version: 5.3.0(rollup@4.52.4) '@sentry/vue': - specifier: 9.14.0 - version: 9.14.0(vue@3.5.13(typescript@5.8.3)) + specifier: 10.20.0 + version: 10.20.0(vue@3.5.22(typescript@5.9.3)) '@syuilo/aiscript': - specifier: 0.19.0 - version: 0.19.0 - '@tabler/icons-webfont': - specifier: 3.31.0 - version: 3.31.0 + specifier: 1.1.2 + version: 1.1.2 + '@syuilo/aiscript-0-19-0': + specifier: npm:@syuilo/aiscript@^0.19.0 + version: '@syuilo/aiscript@0.19.0' '@twemoji/parser': - specifier: 15.1.1 - version: 15.1.1 + specifier: 16.0.0 + version: 16.0.0 '@vitejs/plugin-vue': - specifier: 5.2.3 - version: 5.2.3(vite@6.3.4(@types/node@22.15.2)(sass@1.87.0)(terser@5.39.0)(tsx@4.19.3))(vue@3.5.13(typescript@5.8.3)) + specifier: 6.0.1 + version: 6.0.1(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6))(vue@3.5.22(typescript@5.9.3)) '@vue/compiler-sfc': - specifier: 3.5.13 - version: 3.5.13 + specifier: 3.5.22 + version: 3.5.22 aiscript-vscode: specifier: github:aiscript-dev/aiscript-vscode#v0.1.15 version: https://codeload.github.com/aiscript-dev/aiscript-vscode/tar.gz/c3cde89e79a41d93540cf8a48cd619c3f2dcb1b7 analytics: - specifier: 0.8.16 - version: 0.8.16(@types/dlv@1.1.5) + specifier: 0.8.19 + version: 0.8.19(@types/dlv@1.1.5) astring: specifier: 1.9.0 version: 1.9.0 @@ -886,32 +877,32 @@ importers: specifier: 1.9.3 version: 1.9.3 chart.js: - specifier: 4.4.9 - version: 4.4.9 + specifier: 4.5.1 + version: 4.5.1 chartjs-adapter-date-fns: specifier: 3.0.0 - version: 3.0.0(chart.js@4.4.9)(date-fns@4.1.0) + version: 3.0.0(chart.js@4.5.1)(date-fns@4.1.0) chartjs-chart-matrix: - specifier: 2.1.1 - version: 2.1.1(chart.js@4.4.9) + specifier: 3.0.0 + version: 3.0.0(chart.js@4.5.1) chartjs-plugin-gradient: specifier: 0.6.1 - version: 0.6.1(chart.js@4.4.9) + version: 0.6.1(chart.js@4.5.1) chartjs-plugin-zoom: specifier: 2.2.0 - version: 2.2.0(chart.js@4.4.9) + version: 2.2.0(chart.js@4.5.1) cherrypick-js: specifier: workspace:* version: link:../cherrypick-js chromatic: - specifier: 11.28.2 - version: 11.28.2 + specifier: 13.3.0 + version: 13.3.0 compare-versions: specifier: 6.1.1 version: 6.1.1 cropperjs: - specifier: 2.0.0 - version: 2.0.0 + specifier: 2.0.1 + version: 2.0.1 date-fns: specifier: 4.1.0 version: 4.1.0 @@ -921,15 +912,24 @@ importers: eventemitter3: specifier: 5.0.1 version: 5.0.1 + execa: + specifier: 9.6.0 + version: 9.6.0 frontend-shared: specifier: workspace:* version: link:../frontend-shared + icons-subsetter: + specifier: workspace:* + version: link:../icons-subsetter idb-keyval: - specifier: 6.2.1 - version: 6.2.1 + specifier: 6.2.2 + version: 6.2.2 insert-text-at-cursor: specifier: 0.3.0 version: 0.3.0 + ios-haptics: + specifier: 0.1.4 + version: 0.1.4 is-file-animated: specifier: 1.0.2 version: 1.0.2 @@ -937,14 +937,17 @@ importers: specifier: 2.2.3 version: 2.2.3 magic-string: - specifier: 0.30.17 - version: 0.30.17 + specifier: 0.30.19 + version: 0.30.19 matter-js: specifier: 0.20.0 version: 0.20.0 + mediabunny: + specifier: 1.23.0 + version: 1.23.0 mfc-js: - specifier: 0.24.0-cherrypick.9 - version: 0.24.0-cherrypick.9 + specifier: 0.1.0 + version: 0.1.0 misskey-bubble-game: specifier: workspace:* version: link:../misskey-bubble-game @@ -958,41 +961,44 @@ importers: specifier: 5.4.4 version: 5.4.4 prismjs: - specifier: 1.29.0 - version: 1.29.0 + specifier: 1.30.0 + version: 1.30.0 punycode.js: specifier: 2.3.1 version: 2.3.1 + qr-code-styling: + specifier: 1.9.2 + version: 1.9.2 + qr-scanner: + specifier: 1.4.2 + version: 1.4.2 qrcode: specifier: ^1.5.4 version: 1.5.4 - qrcode-vue3: - specifier: ^1.7.1 - version: 1.7.1 rollup: - specifier: 4.40.0 - version: 4.40.0 + specifier: 4.52.4 + version: 4.52.4 sanitize-html: - specifier: 2.16.0 - version: 2.16.0 + specifier: 2.17.0 + version: 2.17.0 sass: - specifier: 1.87.0 - version: 1.87.0 + specifier: 1.93.2 + version: 1.93.2 shiki: - specifier: 3.3.0 - version: 3.3.0 + specifier: 3.13.0 + version: 3.13.0 strict-event-emitter-types: specifier: 2.0.0 version: 2.0.0 temml: - specifier: 0.11.06 - version: 0.11.6 + specifier: 0.11.11 + version: 0.11.11 textarea-caret: specifier: 3.1.0 version: 3.1.0 three: - specifier: 0.176.0 - version: 0.176.0 + specifier: 0.180.0 + version: 0.180.0 throttle-debounce: specifier: 5.0.2 version: 5.0.2 @@ -1003,119 +1009,116 @@ importers: specifier: ^1.3.4 version: 1.3.4 tsc-alias: - specifier: 1.8.15 - version: 1.8.15 + specifier: 1.8.16 + version: 1.8.16 tsconfig-paths: specifier: 4.2.0 version: 4.2.0 typescript: - specifier: 5.8.3 - version: 5.8.3 - uuid: - specifier: 11.1.0 - version: 11.1.0 + specifier: 5.9.3 + version: 5.9.3 v-code-diff: specifier: 1.13.1 - version: 1.13.1(vue@3.5.13(typescript@5.8.3)) + version: 1.13.1(vue@3.5.22(typescript@5.9.3)) vite: - specifier: 6.3.4 - version: 6.3.4(@types/node@22.15.2)(sass@1.87.0)(terser@5.39.0)(tsx@4.19.3) + specifier: 7.1.9 + version: 7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6) vue: - specifier: 3.5.13 - version: 3.5.13(typescript@5.8.3) + specifier: 3.5.22 + version: 3.5.22(typescript@5.9.3) vue-prism-editor: specifier: 2.0.0-alpha.2 - version: 2.0.0-alpha.2(vue@3.5.13(typescript@5.8.3)) + version: 2.0.0-alpha.2(vue@3.5.22(typescript@5.9.3)) vuedraggable: specifier: next - version: 4.1.0(vue@3.5.13(typescript@5.8.3)) + version: 4.1.0(vue@3.5.22(typescript@5.9.3)) wanakana: specifier: 5.3.1 version: 5.3.1 devDependencies: '@biomejs/biome': - specifier: 1.9.4 - version: 1.9.4 + specifier: 2.3.1 + version: 2.3.1 '@misskey-dev/summaly': - specifier: 5.2.1 - version: 5.2.1 - '@storybook/addon-actions': - specifier: 8.6.12 - version: 8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5)) + specifier: 5.2.4 + version: 5.2.4 '@storybook/addon-essentials': - specifier: 8.6.12 - version: 8.6.12(@types/react@19.1.8)(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5)) + specifier: 8.6.14 + version: 8.6.14(@types/react@18.0.28)(storybook@9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6))) '@storybook/addon-interactions': - specifier: 8.6.12 - version: 8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5)) + specifier: 8.6.14 + version: 8.6.14(storybook@9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6))) '@storybook/addon-links': - specifier: 8.6.12 - version: 8.6.12(react@19.1.0)(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5)) + specifier: 9.1.10 + version: 9.1.10(react@19.2.0)(storybook@9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6))) '@storybook/addon-mdx-gfm': - specifier: 8.6.12 - version: 8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5)) + specifier: 8.6.14 + version: 8.6.14(storybook@9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6))) '@storybook/addon-storysource': - specifier: 8.6.12 - version: 8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5)) + specifier: 8.6.14 + version: 8.6.14(storybook@9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6))) '@storybook/blocks': - specifier: 8.6.12 - version: 8.6.12(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5)) + specifier: 8.6.14 + version: 8.6.14(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(storybook@9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6))) '@storybook/components': - specifier: 8.6.12 - version: 8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5)) + specifier: 8.6.14 + version: 8.6.14(storybook@9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6))) '@storybook/core-events': - specifier: 8.6.12 - version: 8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5)) + specifier: 8.6.14 + version: 8.6.14(storybook@9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6))) '@storybook/manager-api': - specifier: 8.6.12 - version: 8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5)) + specifier: 8.6.14 + version: 8.6.14(storybook@9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6))) '@storybook/preview-api': - specifier: 8.6.12 - version: 8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5)) + specifier: 8.6.14 + version: 8.6.14(storybook@9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6))) '@storybook/react': - specifier: 8.6.12 - version: 8.6.12(@storybook/test@8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5)))(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5))(typescript@5.8.3) + specifier: 9.1.10 + version: 9.1.10(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(storybook@9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)))(typescript@5.9.3) '@storybook/react-vite': - specifier: 8.6.12 - version: 8.6.12(@storybook/test@8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5)))(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(rollup@4.40.0)(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5))(typescript@5.8.3)(vite@6.3.4(@types/node@22.15.2)(sass@1.87.0)(terser@5.39.0)(tsx@4.19.3)) + specifier: 9.1.10 + version: 9.1.10(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(rollup@4.52.4)(storybook@9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)))(typescript@5.9.3)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)) '@storybook/test': - specifier: 8.6.12 - version: 8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5)) + specifier: 8.6.14 + version: 8.6.14(storybook@9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6))) '@storybook/theming': - specifier: 8.6.12 - version: 8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5)) + specifier: 8.6.14 + version: 8.6.14(storybook@9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6))) '@storybook/types': - specifier: 8.6.12 - version: 8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5)) + specifier: 8.6.14 + version: 8.6.14(storybook@9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6))) '@storybook/vue3': - specifier: 8.6.12 - version: 8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5))(vue@3.5.13(typescript@5.8.3)) + specifier: 9.1.10 + version: 9.1.10(storybook@9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)))(vue@3.5.22(typescript@5.9.3)) '@storybook/vue3-vite': - specifier: 8.6.12 - version: 8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5))(vite@6.3.4(@types/node@22.15.2)(sass@1.87.0)(terser@5.39.0)(tsx@4.19.3))(vue@3.5.13(typescript@5.8.3)) + specifier: 9.1.10 + version: 9.1.10(storybook@9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)))(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6))(vue@3.5.22(typescript@5.9.3)) + '@tabler/icons-webfont': + specifier: 3.35.0 + version: 3.35.0 '@testing-library/vue': specifier: 8.1.0 - version: 8.1.0(@vue/compiler-sfc@3.5.13)(vue@3.5.13(typescript@5.8.3)) + version: 8.1.0(@vue/compiler-sfc@3.5.22)(@vue/server-renderer@3.5.22(vue@3.5.22(typescript@5.9.3)))(vue@3.5.22(typescript@5.9.3)) '@types/autosize': specifier: ^4.0.1 - version: 4.0.3 + version: 4.0.1 '@types/canvas-confetti': specifier: 1.9.0 version: 1.9.0 '@types/estree': - specifier: 1.0.7 - version: 1.0.7 + specifier: 1.0.8 + version: 1.0.8 '@types/matter-js': - specifier: 0.19.8 - version: 0.19.8 + specifier: 0.20.2 + version: 0.20.2 '@types/micromatch': specifier: 4.0.9 version: 4.0.9 '@types/node': - specifier: 22.15.2 - version: 22.15.2 + specifier: 24.9.1 + version: 24.9.1 '@types/prismjs': - specifier: ^1.26.0 + specifier: 1.26.5 version: 1.26.5 '@types/punycode.js': specifier: npm:@types/punycode@2.1.4 @@ -1124,8 +1127,8 @@ importers: specifier: ^1.5.5 version: 1.5.5 '@types/sanitize-html': - specifier: 2.15.0 - version: 2.15.0 + specifier: 2.16.0 + version: 2.16.0 '@types/seedrandom': specifier: 3.0.8 version: 3.0.8 @@ -1139,44 +1142,44 @@ importers: specifier: 8.18.1 version: 8.18.1 '@typescript-eslint/eslint-plugin': - specifier: 8.31.0 - version: 8.31.0(@typescript-eslint/parser@8.31.0(eslint@9.25.1)(typescript@5.8.3))(eslint@9.25.1)(typescript@5.8.3) + specifier: 8.46.1 + version: 8.46.1(@typescript-eslint/parser@8.46.1(eslint@9.37.0)(typescript@5.9.3))(eslint@9.37.0)(typescript@5.9.3) '@typescript-eslint/parser': - specifier: 8.31.0 - version: 8.31.0(eslint@9.25.1)(typescript@5.8.3) + specifier: 8.46.1 + version: 8.46.1(eslint@9.37.0)(typescript@5.9.3) '@vitest/coverage-v8': - specifier: 3.1.2 - version: 3.1.2(vitest@3.1.2(@types/debug@4.1.12)(@types/node@22.15.2)(happy-dom@17.4.4)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(msw@2.7.5(@types/node@22.15.2)(typescript@5.8.3))(sass@1.87.0)(terser@5.39.0)(tsx@4.19.3)) + specifier: 3.2.4 + version: 3.2.4(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.9.1)(happy-dom@20.0.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)) '@vue/compiler-core': - specifier: 3.5.13 - version: 3.5.13 + specifier: 3.5.22 + version: 3.5.22 '@vue/runtime-core': - specifier: 3.5.13 - version: 3.5.13 + specifier: 3.5.22 + version: 3.5.22 acorn: - specifier: 8.14.1 - version: 8.14.1 + specifier: 8.15.0 + version: 8.15.0 cross-env: - specifier: 7.0.3 - version: 7.0.3 + specifier: 10.1.0 + version: 10.1.0 cypress: - specifier: 14.3.2 - version: 14.3.2 + specifier: 15.4.0 + version: 15.4.0 eslint-plugin-import: - specifier: 2.31.0 - version: 2.31.0(@typescript-eslint/parser@8.31.0(eslint@9.25.1)(typescript@5.8.3))(eslint@9.25.1) + specifier: 2.32.0 + version: 2.32.0(@typescript-eslint/parser@8.46.1(eslint@9.37.0)(typescript@5.9.3))(eslint@9.37.0) eslint-plugin-storybook: specifier: ^0.6.13 - version: 0.6.15(eslint@9.25.1)(typescript@5.8.3) + version: 0.6.13(eslint@9.37.0)(typescript@5.9.3) eslint-plugin-vue: - specifier: 10.0.0 - version: 10.0.0(eslint@9.25.1)(vue-eslint-parser@10.1.3(eslint@9.25.1)) + specifier: 10.5.0 + version: 10.5.0(@stylistic/eslint-plugin@3.1.0(eslint@9.37.0)(typescript@5.9.3))(@typescript-eslint/parser@8.46.1(eslint@9.37.0)(typescript@5.9.3))(eslint@9.37.0)(vue-eslint-parser@10.2.0(eslint@9.37.0)) fast-glob: specifier: 3.3.3 version: 3.3.3 happy-dom: - specifier: 17.4.4 - version: 17.4.4 + specifier: 20.0.7 + version: 20.0.7 intersection-observer: specifier: 0.12.2 version: 0.12.2 @@ -1184,83 +1187,117 @@ importers: specifier: 4.0.8 version: 4.0.8 minimatch: - specifier: 10.0.1 - version: 10.0.1 + specifier: 10.0.3 + version: 10.0.3 msw: - specifier: 2.7.5 - version: 2.7.5(@types/node@22.15.2)(typescript@5.8.3) + specifier: 2.11.5 + version: 2.11.5(@types/node@24.9.1)(typescript@5.9.3) msw-storybook-addon: - specifier: 2.0.4 - version: 2.0.4(msw@2.7.5(@types/node@22.15.2)(typescript@5.8.3)) + specifier: 2.0.6 + version: 2.0.6(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3)) nodemon: specifier: 3.1.10 version: 3.1.10 prettier: - specifier: 3.5.3 - version: 3.5.3 + specifier: 3.6.2 + version: 3.6.2 react: - specifier: 19.1.0 - version: 19.1.0 + specifier: 19.2.0 + version: 19.2.0 react-dom: - specifier: 19.1.0 - version: 19.1.0(react@19.1.0) + specifier: 19.2.0 + version: 19.2.0(react@19.2.0) seedrandom: specifier: 3.0.5 version: 3.0.5 start-server-and-test: - specifier: 2.0.11 - version: 2.0.11 + specifier: 2.1.2 + version: 2.1.2 storybook: - specifier: 8.6.12 - version: 8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5) + specifier: 9.1.10 + version: 9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)) storybook-addon-misskey-theme: specifier: github:misskey-dev/storybook-addon-misskey-theme - version: https://codeload.github.com/misskey-dev/storybook-addon-misskey-theme/tar.gz/cf583db098365b2ccc81a82f63ca9c93bc32b640(@storybook/blocks@8.6.12(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5)))(@storybook/components@8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5)))(@storybook/core-events@8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5)))(@storybook/manager-api@8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5)))(@storybook/preview-api@8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5)))(@storybook/theming@8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5)))(@storybook/types@8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5)))(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + version: https://codeload.github.com/misskey-dev/storybook-addon-misskey-theme/tar.gz/cf583db098365b2ccc81a82f63ca9c93bc32b640(8592f997fbe36bffac29bb2d9605c63c) + tsx: + specifier: 4.20.6 + version: 4.20.6 + vite-plugin-glsl: + specifier: 1.5.4 + version: 1.5.4(@rollup/pluginutils@5.3.0(rollup@4.52.4))(esbuild@0.25.10)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)) vite-plugin-turbosnap: specifier: 1.0.3 version: 1.0.3 vitest: - specifier: 3.1.2 - version: 3.1.2(@types/debug@4.1.12)(@types/node@22.15.2)(happy-dom@17.4.4)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(msw@2.7.5(@types/node@22.15.2)(typescript@5.8.3))(sass@1.87.0)(terser@5.39.0)(tsx@4.19.3) + specifier: 3.2.4 + version: 3.2.4(@types/debug@4.1.12)(@types/node@24.9.1)(happy-dom@20.0.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6) vitest-fetch-mock: specifier: 0.4.5 - version: 0.4.5(vitest@3.1.2(@types/debug@4.1.12)(@types/node@22.15.2)(happy-dom@17.4.4)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(msw@2.7.5(@types/node@22.15.2)(typescript@5.8.3))(sass@1.87.0)(terser@5.39.0)(tsx@4.19.3)) + version: 0.4.5(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.9.1)(happy-dom@20.0.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)) vue-component-type-helpers: - specifier: 2.2.10 - version: 2.2.10 + specifier: 3.1.1 + version: 3.1.1 vue-eslint-parser: - specifier: 10.1.3 - version: 10.1.3(eslint@9.25.1) + specifier: 10.2.0 + version: 10.2.0(eslint@9.37.0) vue-tsc: - specifier: 2.2.10 - version: 2.2.10(typescript@5.8.3) + specifier: 3.1.1 + version: 3.1.1(typescript@5.9.3) + + packages/frontend-builder: + dependencies: + estree-walker: + specifier: 3.0.3 + version: 3.0.3 + magic-string: + specifier: 0.30.19 + version: 0.30.19 + vite: + specifier: 7.1.9 + version: 7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6) + devDependencies: + '@types/estree': + specifier: 1.0.8 + version: 1.0.8 + '@types/node': + specifier: 24.9.1 + version: 24.9.1 + '@typescript-eslint/eslint-plugin': + specifier: 8.46.1 + version: 8.46.1(@typescript-eslint/parser@8.46.1(eslint@9.37.0)(typescript@5.9.3))(eslint@9.37.0)(typescript@5.9.3) + '@typescript-eslint/parser': + specifier: 8.46.1 + version: 8.46.1(eslint@9.37.0)(typescript@5.9.3) + rollup: + specifier: 4.52.4 + version: 4.52.4 + typescript: + specifier: 5.9.3 + version: 5.9.3 packages/frontend-embed: dependencies: '@discordapp/twemoji': - specifier: 15.1.0 - version: 15.1.0 + specifier: 16.0.1 + version: 16.0.1 '@rollup/plugin-json': specifier: 6.1.0 - version: 6.1.0(rollup@4.40.0) + version: 6.1.0(rollup@4.52.4) '@rollup/plugin-replace': specifier: 6.0.2 - version: 6.0.2(rollup@4.40.0) + version: 6.0.2(rollup@4.52.4) '@rollup/pluginutils': - specifier: 5.1.4 - version: 5.1.4(rollup@4.40.0) - '@tabler/icons-webfont': - specifier: 3.31.0 - version: 3.31.0 + specifier: 5.3.0 + version: 5.3.0(rollup@4.52.4) '@twemoji/parser': - specifier: 15.1.1 - version: 15.1.1 + specifier: 16.0.0 + version: 16.0.0 '@vitejs/plugin-vue': - specifier: 5.2.3 - version: 5.2.3(vite@6.3.4(@types/node@22.15.2)(sass@1.87.0)(terser@5.39.0)(tsx@4.19.3))(vue@3.5.13(typescript@5.8.3)) + specifier: 6.0.1 + version: 6.0.1(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6))(vue@3.5.22(typescript@5.9.3)) '@vue/compiler-sfc': - specifier: 3.5.13 - version: 3.5.13 + specifier: 3.5.22 + version: 3.5.22 astring: specifier: 1.9.0 version: 1.9.0 @@ -1276,67 +1313,73 @@ importers: frontend-shared: specifier: workspace:* version: link:../frontend-shared + icons-subsetter: + specifier: workspace:* + version: link:../icons-subsetter json5: specifier: 2.2.3 version: 2.2.3 mfc-js: - specifier: 0.24.0-cherrypick.9 - version: 0.24.0-cherrypick.9 + specifier: 0.1.0 + version: 0.1.0 punycode.js: specifier: 2.3.1 version: 2.3.1 rollup: - specifier: 4.40.0 - version: 4.40.0 + specifier: 4.52.4 + version: 4.52.4 sass: - specifier: 1.87.0 - version: 1.87.0 + specifier: 1.93.2 + version: 1.93.2 shiki: - specifier: 3.3.0 - version: 3.3.0 + specifier: 3.13.0 + version: 3.13.0 temml: - specifier: 0.11.06 - version: 0.11.6 + specifier: 0.11.11 + version: 0.11.11 tinycolor2: specifier: 1.6.0 version: 1.6.0 tsc-alias: - specifier: 1.8.15 - version: 1.8.15 + specifier: 1.8.16 + version: 1.8.16 tsconfig-paths: specifier: 4.2.0 version: 4.2.0 typescript: - specifier: 5.8.3 - version: 5.8.3 + specifier: 5.9.3 + version: 5.9.3 uuid: - specifier: 11.1.0 - version: 11.1.0 + specifier: 13.0.0 + version: 13.0.0 vite: - specifier: 6.3.4 - version: 6.3.4(@types/node@22.15.2)(sass@1.87.0)(terser@5.39.0)(tsx@4.19.3) + specifier: 7.1.9 + version: 7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6) vue: - specifier: 3.5.13 - version: 3.5.13(typescript@5.8.3) + specifier: 3.5.22 + version: 3.5.22(typescript@5.9.3) devDependencies: '@biomejs/biome': - specifier: 1.9.4 - version: 1.9.4 + specifier: 2.3.1 + version: 2.3.1 '@misskey-dev/summaly': - specifier: 5.2.1 - version: 5.2.1 + specifier: 5.2.4 + version: 5.2.4 + '@tabler/icons-webfont': + specifier: 3.35.0 + version: 3.35.0 '@testing-library/vue': specifier: 8.1.0 - version: 8.1.0(@vue/compiler-sfc@3.5.13)(vue@3.5.13(typescript@5.8.3)) + version: 8.1.0(@vue/compiler-sfc@3.5.22)(@vue/server-renderer@3.5.22(vue@3.5.22(typescript@5.9.3)))(vue@3.5.22(typescript@5.9.3)) '@types/estree': - specifier: 1.0.7 - version: 1.0.7 + specifier: 1.0.8 + version: 1.0.8 '@types/micromatch': specifier: 4.0.9 version: 4.0.9 '@types/node': - specifier: 22.15.2 - version: 22.15.2 + specifier: 24.9.1 + version: 24.9.1 '@types/punycode.js': specifier: npm:@types/punycode@2.1.4 version: '@types/punycode@2.1.4' @@ -1347,35 +1390,35 @@ importers: specifier: 8.18.1 version: 8.18.1 '@typescript-eslint/eslint-plugin': - specifier: 8.31.0 - version: 8.31.0(@typescript-eslint/parser@8.31.0(eslint@9.25.1)(typescript@5.8.3))(eslint@9.25.1)(typescript@5.8.3) + specifier: 8.46.1 + version: 8.46.1(@typescript-eslint/parser@8.46.1(eslint@9.37.0)(typescript@5.9.3))(eslint@9.37.0)(typescript@5.9.3) '@typescript-eslint/parser': - specifier: 8.31.0 - version: 8.31.0(eslint@9.25.1)(typescript@5.8.3) + specifier: 8.46.1 + version: 8.46.1(eslint@9.37.0)(typescript@5.9.3) '@vitest/coverage-v8': - specifier: 3.1.2 - version: 3.1.2(vitest@3.1.2(@types/debug@4.1.12)(@types/node@22.15.2)(happy-dom@17.4.4)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(msw@2.7.5(@types/node@22.15.2)(typescript@5.8.3))(sass@1.87.0)(terser@5.39.0)(tsx@4.19.3)) + specifier: 3.2.4 + version: 3.2.4(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.9.1)(happy-dom@20.0.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)) '@vue/runtime-core': - specifier: 3.5.13 - version: 3.5.13 + specifier: 3.5.22 + version: 3.5.22 acorn: - specifier: 8.14.1 - version: 8.14.1 + specifier: 8.15.0 + version: 8.15.0 cross-env: - specifier: 7.0.3 - version: 7.0.3 + specifier: 10.1.0 + version: 10.1.0 eslint-plugin-import: - specifier: 2.31.0 - version: 2.31.0(@typescript-eslint/parser@8.31.0(eslint@9.25.1)(typescript@5.8.3))(eslint@9.25.1) + specifier: 2.32.0 + version: 2.32.0(@typescript-eslint/parser@8.46.1(eslint@9.37.0)(typescript@5.9.3))(eslint@9.37.0) eslint-plugin-vue: - specifier: 10.0.0 - version: 10.0.0(eslint@9.25.1)(vue-eslint-parser@10.1.3(eslint@9.25.1)) + specifier: 10.5.0 + version: 10.5.0(@stylistic/eslint-plugin@3.1.0(eslint@9.37.0)(typescript@5.9.3))(@typescript-eslint/parser@8.46.1(eslint@9.37.0)(typescript@5.9.3))(eslint@9.37.0)(vue-eslint-parser@10.2.0(eslint@9.37.0)) fast-glob: specifier: 3.3.3 version: 3.3.3 happy-dom: - specifier: 17.4.4 - version: 17.4.4 + specifier: 20.0.7 + version: 20.0.7 intersection-observer: specifier: 0.12.2 version: 0.12.2 @@ -1383,29 +1426,32 @@ importers: specifier: 4.0.8 version: 4.0.8 msw: - specifier: 2.7.5 - version: 2.7.5(@types/node@22.15.2)(typescript@5.8.3) + specifier: 2.11.5 + version: 2.11.5(@types/node@24.9.1)(typescript@5.9.3) nodemon: specifier: 3.1.10 version: 3.1.10 prettier: - specifier: 3.5.3 - version: 3.5.3 + specifier: 3.6.2 + version: 3.6.2 start-server-and-test: - specifier: 2.0.11 - version: 2.0.11 + specifier: 2.1.2 + version: 2.1.2 + tsx: + specifier: 4.20.6 + version: 4.20.6 vite-plugin-turbosnap: specifier: 1.0.3 version: 1.0.3 vue-component-type-helpers: - specifier: 2.2.10 - version: 2.2.10 + specifier: 3.1.1 + version: 3.1.1 vue-eslint-parser: - specifier: 10.1.3 - version: 10.1.3(eslint@9.25.1) + specifier: 10.2.0 + version: 10.2.0(eslint@9.37.0) vue-tsc: - specifier: 2.2.10 - version: 2.2.10(typescript@5.8.3) + specifier: 3.1.1 + version: 3.1.1(typescript@5.9.3) packages/frontend-shared: dependencies: @@ -1413,36 +1459,70 @@ importers: specifier: workspace:* version: link:../cherrypick-js vue: - specifier: 3.5.13 - version: 3.5.13(typescript@5.8.3) + specifier: 3.5.22 + version: 3.5.22(typescript@5.9.3) devDependencies: '@biomejs/biome': - specifier: 1.9.4 - version: 1.9.4 + specifier: 2.3.1 + version: 2.3.1 '@types/node': - specifier: 22.15.2 - version: 22.15.2 + specifier: 24.9.1 + version: 24.9.1 '@typescript-eslint/eslint-plugin': - specifier: 8.31.0 - version: 8.31.0(@typescript-eslint/parser@8.31.0(eslint@9.25.1)(typescript@5.8.3))(eslint@9.25.1)(typescript@5.8.3) + specifier: 8.46.1 + version: 8.46.1(@typescript-eslint/parser@8.46.1(eslint@9.37.0)(typescript@5.9.3))(eslint@9.37.0)(typescript@5.9.3) '@typescript-eslint/parser': - specifier: 8.31.0 - version: 8.31.0(eslint@9.25.1)(typescript@5.8.3) + specifier: 8.46.1 + version: 8.46.1(eslint@9.37.0)(typescript@5.9.3) esbuild: - specifier: 0.25.3 - version: 0.25.3 + specifier: 0.25.10 + version: 0.25.10 eslint-plugin-vue: - specifier: 10.0.0 - version: 10.0.0(eslint@9.25.1)(vue-eslint-parser@10.1.3(eslint@9.25.1)) + specifier: 10.5.0 + version: 10.5.0(@stylistic/eslint-plugin@3.1.0(eslint@9.37.0)(typescript@5.9.3))(@typescript-eslint/parser@8.46.1(eslint@9.37.0)(typescript@5.9.3))(eslint@9.37.0)(vue-eslint-parser@10.2.0(eslint@9.37.0)) nodemon: specifier: 3.1.10 version: 3.1.10 typescript: - specifier: 5.8.3 - version: 5.8.3 + specifier: 5.9.3 + version: 5.9.3 vue-eslint-parser: - specifier: 10.1.3 - version: 10.1.3(eslint@9.25.1) + specifier: 10.2.0 + version: 10.2.0(eslint@9.37.0) + + packages/icons-subsetter: + dependencies: + '@tabler/icons-webfont': + specifier: 3.35.0 + version: 3.35.0 + harfbuzzjs: + specifier: 0.4.13 + version: 0.4.13 + tiny-glob: + specifier: 0.2.9 + version: 0.2.9 + tsx: + specifier: 4.20.6 + version: 4.20.6 + typescript: + specifier: 5.9.3 + version: 5.9.3 + wawoff2: + specifier: 2.0.1 + version: 2.0.1 + devDependencies: + '@types/node': + specifier: 24.9.1 + version: 24.9.1 + '@types/wawoff2': + specifier: 1.0.2 + version: 1.0.2 + '@typescript-eslint/eslint-plugin': + specifier: 8.46.1 + version: 8.46.1(@typescript-eslint/parser@8.46.1(eslint@9.37.0)(typescript@5.9.3))(eslint@9.37.0)(typescript@5.9.3) + '@typescript-eslint/parser': + specifier: 8.46.1 + version: 8.46.1(eslint@9.37.0)(typescript@5.9.3) packages/misskey-bubble-game: dependencies: @@ -1457,38 +1537,38 @@ importers: version: 3.0.5 devDependencies: '@biomejs/biome': - specifier: 1.9.4 - version: 1.9.4 + specifier: 2.3.1 + version: 2.3.1 '@types/matter-js': - specifier: 0.19.8 - version: 0.19.8 + specifier: 0.20.2 + version: 0.20.2 '@types/node': - specifier: 22.15.2 - version: 22.15.2 + specifier: 24.9.1 + version: 24.9.1 '@types/seedrandom': specifier: 3.0.8 version: 3.0.8 '@typescript-eslint/eslint-plugin': - specifier: 8.31.0 - version: 8.31.0(@typescript-eslint/parser@8.31.0(eslint@9.25.1)(typescript@5.8.3))(eslint@9.25.1)(typescript@5.8.3) + specifier: 8.46.1 + version: 8.46.1(@typescript-eslint/parser@8.46.1(eslint@9.37.0)(typescript@5.9.3))(eslint@9.37.0)(typescript@5.9.3) '@typescript-eslint/parser': - specifier: 8.31.0 - version: 8.31.0(eslint@9.25.1)(typescript@5.8.3) + specifier: 8.46.1 + version: 8.46.1(eslint@9.37.0)(typescript@5.9.3) esbuild: - specifier: 0.25.3 - version: 0.25.3 + specifier: 0.25.10 + version: 0.25.10 execa: - specifier: 9.5.2 - version: 9.5.2 + specifier: 9.6.0 + version: 9.6.0 glob: - specifier: 11.0.2 - version: 11.0.2 + specifier: 11.0.3 + version: 11.0.3 nodemon: specifier: 3.1.10 version: 3.1.10 typescript: - specifier: 5.8.3 - version: 5.8.3 + specifier: 5.9.3 + version: 5.9.3 packages/misskey-reversi: dependencies: @@ -1497,32 +1577,32 @@ importers: version: 1.2.2 devDependencies: '@biomejs/biome': - specifier: 1.9.4 - version: 1.9.4 + specifier: 2.3.1 + version: 2.3.1 '@types/node': - specifier: 22.15.2 - version: 22.15.2 + specifier: 24.9.1 + version: 24.9.1 '@typescript-eslint/eslint-plugin': - specifier: 8.31.0 - version: 8.31.0(@typescript-eslint/parser@8.31.0(eslint@9.25.1)(typescript@5.8.3))(eslint@9.25.1)(typescript@5.8.3) + specifier: 8.46.1 + version: 8.46.1(@typescript-eslint/parser@8.46.1(eslint@9.37.0)(typescript@5.9.3))(eslint@9.37.0)(typescript@5.9.3) '@typescript-eslint/parser': - specifier: 8.31.0 - version: 8.31.0(eslint@9.25.1)(typescript@5.8.3) + specifier: 8.46.1 + version: 8.46.1(eslint@9.37.0)(typescript@5.9.3) esbuild: - specifier: 0.25.3 - version: 0.25.3 + specifier: 0.25.10 + version: 0.25.10 execa: - specifier: 9.5.2 - version: 9.5.2 + specifier: 9.6.0 + version: 9.6.0 glob: - specifier: 11.0.2 - version: 11.0.2 + specifier: 11.0.3 + version: 11.0.3 nodemon: specifier: 3.1.10 version: 3.1.10 typescript: - specifier: 5.8.3 - version: 5.8.3 + specifier: 5.9.3 + version: 5.9.3 packages/sw: dependencies: @@ -1530,69 +1610,82 @@ importers: specifier: workspace:* version: link:../cherrypick-js esbuild: - specifier: 0.25.3 - version: 0.25.3 + specifier: 0.25.10 + version: 0.25.10 idb-keyval: - specifier: 6.2.1 - version: 6.2.1 + specifier: 6.2.2 + version: 6.2.2 devDependencies: '@biomejs/biome': - specifier: 1.9.4 - version: 1.9.4 + specifier: 2.3.1 + version: 2.3.1 '@typescript-eslint/parser': - specifier: 8.31.0 - version: 8.31.0(eslint@9.25.1)(typescript@5.8.3) + specifier: 8.46.1 + version: 8.46.1(eslint@9.37.0)(typescript@5.9.3) '@typescript/lib-webworker': specifier: npm:@types/serviceworker@0.0.74 version: '@types/serviceworker@0.0.74' eslint-plugin-import: - specifier: 2.31.0 - version: 2.31.0(@typescript-eslint/parser@8.31.0(eslint@9.25.1)(typescript@5.8.3))(eslint@9.25.1) + specifier: 2.32.0 + version: 2.32.0(@typescript-eslint/parser@8.46.1(eslint@9.37.0)(typescript@5.9.3))(eslint@9.37.0) nodemon: specifier: 3.1.10 version: 3.1.10 typescript: - specifier: 5.8.3 - version: 5.8.3 + specifier: 5.9.3 + version: 5.9.3 packages: - '@adobe/css-tools@4.4.3': - resolution: {integrity: sha512-VQKMkwriZbaOgVCby1UDY/LDk5fIjhQicCvVPFqfe+69fWaPWydbWJ3wRt59/YzIwda1I81loas3oCoHxnqvdA==} + '@aashutoshrathi/word-wrap@1.2.6': + resolution: {integrity: sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==} + engines: {node: '>=0.10.0'} + + '@adobe/css-tools@4.4.0': + resolution: {integrity: sha512-Ff9+ksdQQB3rMncgqDK78uLznstjyfIf2Arnh22pW8kBpLs6rpKDwgnZT46hin5Hl1WzazzK64DOrhSwYpS7bQ==} '@ampproject/remapping@2.3.0': resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} engines: {node: '>=6.0.0'} - '@analytics/cookie-utils@0.2.12': - resolution: {integrity: sha512-2h/yuIu3kmu+ZJlKmlT6GoRvUEY2k1BbQBezEv5kGhnn9KpmzPz715Y3GmM2i+m7Y0QmBdVUoA260dQZkofs2A==} + '@analytics/cookie-utils@0.2.14': + resolution: {integrity: sha512-x51x2cLqvP5Fb1ydgNvTCX+SVv0ALK/yTNwp/53++yk4kLhxb850krWtQ4aASN0612oXrIGotwfmdJIttnLiPQ==} - '@analytics/core@0.12.17': - resolution: {integrity: sha512-GMxRm5Dp3Wam/w5NNvqNKMO6zWecozbVv21Kn4WhftCx6OjJI7zMlVtiLpjGjxa0RRZfVG80YhupF0Qh9XL2gw==} + '@analytics/core@0.13.2': + resolution: {integrity: sha512-ejvfoPP8TEh2hA2szMEq9c4TdeX8FAeY1j/7MxJVZjzDaq8BDHOyaAAQzTFiLMHvV0WcU2YC0smJ5Ids5Ll5ng==} - '@analytics/global-storage-utils@0.1.7': - resolution: {integrity: sha512-V+spzGLZYm4biZT4uefaylm80SrLXf8WOTv9hCgA46cLcyxx3LD4GCpssp1lj+RcWLl/uXJQBRO4Mnn/o1x6Gw==} + '@analytics/global-storage-utils@0.1.9': + resolution: {integrity: sha512-+xm6CDnWsVOQIKkqbPRPRdYDXKk3PNgr/bCZWSI+7tEDT5PCDgI0QSBZe+FqCVkCRtTkgOrjFOY7wOM8Gq+ndA==} '@analytics/google-analytics@1.1.0': resolution: {integrity: sha512-i8uGyELMtwEUAf3GNWNLNBzhRvReDn1RUxvMdMhjUA7+GNGxPOM4kkzFfv3giQXKNxTEjfsh75kqNcscbJsuaA==} - '@analytics/localstorage-utils@0.1.10': - resolution: {integrity: sha512-uJS+Jp1yLG5VFCgA5T82ZODYBS0xuDQx0NtAZrgbqt9j51BX3TcgmOez5LVkrUNu/lpbxjCLq35I4TKj78VmOQ==} + '@analytics/localstorage-utils@0.1.12': + resolution: {integrity: sha512-BL3vuZUwWgMqdkQsE0GKsED5SPLC6daI4K4LE0a/BkKv+4Cae5JLLqpO5gju2HUGOjJxIvw8U/G5EcglNY5+1w==} + + '@analytics/session-storage-utils@0.0.9': + resolution: {integrity: sha512-fhP9QCpyq45rZKsXaAxyz+VTmOUWljIW08CWSkFzpwOHkDM4Xy5tymc1YcWqSBBaLjHldo3HlY4qfqEIS4Aj1A==} - '@analytics/session-storage-utils@0.0.7': - resolution: {integrity: sha512-PSv40UxG96HVcjY15e3zOqU2n8IqXnH8XvTkg1X43uXNTKVSebiI2kUjA3Q7ESFbw5DPwcLbJhV7GforpuBLDw==} + '@analytics/storage-utils@0.4.4': + resolution: {integrity: sha512-873P4wDIunbOnBqADc2AhTVsLbluUv1dP6k9UrK8FIeV8WXv5+fG12HdwwaniUIxq6QLgZJfKEaCwtWSKrrV0g==} - '@analytics/storage-utils@0.4.2': - resolution: {integrity: sha512-AXObwyVQw9h2uJh1t2hUgabtVxzYpW+7uKVbdHQK80vr3Td5rrmCxrCxarh7HUuAgSDZ0bZWqmYxVgmwKceaLg==} + '@analytics/type-utils@0.6.4': + resolution: {integrity: sha512-Ou1gQxFakOWLcPnbFVsrPb8g1wLLUZYYJXDPjHkG07+5mustGs5yqACx42UAu4A6NszNN6Z5gGxhyH45zPWRxw==} - '@analytics/type-utils@0.6.2': - resolution: {integrity: sha512-TD+xbmsBLyYy/IxFimW/YL/9L2IEnM7/EoV9Aeh56U64Ify8o27HJcKjo38XY9Tcn0uOq1AX3thkKgvtWvwFQg==} + '@apidevtools/json-schema-ref-parser@14.2.1': + resolution: {integrity: sha512-HmdFw9CDYqM6B25pqGBpNeLCKvGPlIx1EbLrVL0zPvj50CJQUHyBNBw45Muk0kEIkogo1VZvOKHajdMuAzSxRg==} + engines: {node: '>= 20'} + peerDependencies: + '@types/json-schema': ^7.0.15 - '@apidevtools/swagger-methods@3.0.2': - resolution: {integrity: sha512-QAkD5kK2b1WfjDS/UQn/qQkbwF31uqRjPTrsCs5ZG9BQGAkjwvqGFjjPqAuzac/IYzpPtRzjCP1WrTuAIjMrXg==} + '@apm-js-collab/code-transformer@0.8.2': + resolution: {integrity: sha512-YRjJjNq5KFSjDUoqu5pFUWrrsvGOxl6c3bu+uMFc9HNNptZ2rNU/TI2nLw4jnhQNtka972Ee2m3uqbvDQtPeCA==} - '@asamuzakjp/css-color@3.2.0': - resolution: {integrity: sha512-K1A6z8tS3XsmCMM86xoWdn7Fkdn9m6RSVtocUrJYIwZnFVkng/PvkEoWtOWmP+Scc6saYWHWZYbndEEXxl24jw==} + '@apm-js-collab/tracing-hooks@0.3.1': + resolution: {integrity: sha512-Vu1CbmPURlN5fTboVuKMoJjbO5qcq9fA5YXpskx3dXe/zTBvjODFoerw+69rVBlRLrJpwPqSDqEuJDEKIrTldw==} + + '@asamuzakjp/css-color@2.8.3': + resolution: {integrity: sha512-GIc76d9UI1hCvOATjZPyHFmE5qhRccp3/zGfMPapK3jBi+yocEzp6BBB0UnfRYP9NP4FANqUZYb0hnfs3TM3hw==} '@aws-crypto/crc32@5.2.0': resolution: {integrity: sha512-nLbCWqQNgUiwwtFsen1AdzAtvuLRsQS8rYgMuxCrdKf9kOssamGLuPwyTY9wyYblNr9+1XM8v6zoDTPPSIeANg==} @@ -1617,129 +1710,133 @@ packages: '@aws-crypto/util@5.2.0': resolution: {integrity: sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==} - '@aws-sdk/client-s3@3.797.0': - resolution: {integrity: sha512-N7pB94mXi4fCt+rYmR9TzfbbwZsWs6Mnk/jDNX9sAZyWkZQnS3AZ/nRtnUmdCimdnOPOMNVjmAoZ4mW3Ff8LDw==} + '@aws-sdk/client-s3@3.908.0': + resolution: {integrity: sha512-c/89iG3of8UEiWbRK014DoHLy8PLLTJtM9IvYLPsvrf83kpV2P/K9WrdbjW4h6e5qt9XPgfNTZ8U607mt7pdmA==} engines: {node: '>=18.0.0'} - '@aws-sdk/client-sso@3.797.0': - resolution: {integrity: sha512-9xuR918p7tShR67ZL+AOSbydpJxSHAOdXcQswxxWR/hKCF7tULX7tyL3gNo3l/ETp0CDcStvorOdH/nCbzEOjw==} + '@aws-sdk/client-ses@3.908.0': + resolution: {integrity: sha512-e4bglczZvoDLmMeAgr0lou5QKCIOGfdCnfXp9jkEhkL6JLKNYvkmrRZpCrQiBwm/4j4H88oRPgLYk+sGQKFPlw==} engines: {node: '>=18.0.0'} - '@aws-sdk/core@3.796.0': - resolution: {integrity: sha512-tH8Sp7lCxISVoLnkyv4AouuXs2CDlMhTuesWa0lq2NX1f+DXsMwSBtN37ttZdpFMw3F8mWdsJt27X9h2Oq868A==} + '@aws-sdk/client-sso@3.908.0': + resolution: {integrity: sha512-PseFMWvtac+Q+zaY9DMISE+2+glNh0ROJ1yR4gMzeafNHSwkdYu4qcgxLWIOnIodGydBv/tQ6nzHPzExXnUUgw==} engines: {node: '>=18.0.0'} - '@aws-sdk/credential-provider-env@3.796.0': - resolution: {integrity: sha512-kQzGKm4IOYYO6vUrai2JocNwhJm4Aml2BsAV+tBhFhhkutE7khf9PUucoVjB78b0J48nF+kdSacqzY+gB81/Uw==} + '@aws-sdk/core@3.908.0': + resolution: {integrity: sha512-okl6FC2cQT1Oidvmnmvyp/IEvqENBagKO0ww4YV5UtBkf0VlhAymCWkZqhovtklsqgq0otag2VRPAgnrMt6nVQ==} engines: {node: '>=18.0.0'} - '@aws-sdk/credential-provider-http@3.796.0': - resolution: {integrity: sha512-wWOT6VAHIKOuHdKFGm1iyKvx7f6+Kc/YTzFWJPuT+l+CPlXR6ylP1UMIDsHHLKpMzsrh3CH77QDsjkhQrnKkfg==} + '@aws-sdk/credential-provider-env@3.908.0': + resolution: {integrity: sha512-FK2YuxoI5CxUflPOIMbVAwDbi6Xvu+2sXopXLmrHc2PfI39M3vmjEoQwYCP8WuQSRb+TbAP3xAkxHjFSBFR35w==} engines: {node: '>=18.0.0'} - '@aws-sdk/credential-provider-ini@3.797.0': - resolution: {integrity: sha512-Zpj6pJ2hnebrhLDr+x61ArMUkjHG6mfJRfamHxeVTgZkhLcwHjC5aM4u9pWTVugIaPY+VBtgkKPbi3TRbHlt2g==} + '@aws-sdk/credential-provider-http@3.908.0': + resolution: {integrity: sha512-eLbz0geVW9EykujQNnYfR35Of8MreI6pau5K6XDFDUSWO9GF8wqH7CQwbXpXHBlCTHtq4QSLxzorD8U5CROhUw==} engines: {node: '>=18.0.0'} - '@aws-sdk/credential-provider-node@3.797.0': - resolution: {integrity: sha512-xJSWvvnmzEfHbqbpN4F3E3mI9+zJ/VWLGiKOjzX1Inbspa5WqNn2GoMamolZR2TvvZS4F3Hp73TD1WoBzkIjuw==} + '@aws-sdk/credential-provider-ini@3.908.0': + resolution: {integrity: sha512-7Cgnv5wabgFtsgr+Uc/76EfPNGyxmbG8aICn3g3D3iJlcO4uuOZI8a77i0afoDdchZrTC6TG6UusS/NAW6zEoQ==} engines: {node: '>=18.0.0'} - '@aws-sdk/credential-provider-process@3.796.0': - resolution: {integrity: sha512-r4e8/4AdKn/qQbRVocW7oXkpoiuXdTv0qty8AASNLnbQnT1vjD1bvmP6kp4fbHPWgwY8I9h0Dqjp49uy9Bqyuw==} + '@aws-sdk/credential-provider-node@3.908.0': + resolution: {integrity: sha512-8OKbykpGw5bdfF/pLTf8YfUi1Kl8o1CTjBqWQTsLOkE3Ho3hsp1eQx8Cz4ttrpv0919kb+lox62DgmAOEmTr1w==} engines: {node: '>=18.0.0'} - '@aws-sdk/credential-provider-sso@3.797.0': - resolution: {integrity: sha512-VlyWnjTsTnBXqXcEW0nw3S7nj00n9fYwF6uU6HPO9t860yIySG01lNPAWTvAt3DfVL5SRS0GANriCZF6ohcMcQ==} + '@aws-sdk/credential-provider-process@3.908.0': + resolution: {integrity: sha512-sWnbkGjDPBi6sODUzrAh5BCDpnPw0wpK8UC/hWI13Q8KGfyatAmCBfr+9OeO3+xBHa8N5AskMncr7C4qS846yQ==} engines: {node: '>=18.0.0'} - '@aws-sdk/credential-provider-web-identity@3.797.0': - resolution: {integrity: sha512-DIb05FEmdOX7bNsqSVEAB3UkaDgrYHonQ2+gcBLqZ7LoDNnovHIlvC5jii93usgEStxITZstnzw+49keNEgVWw==} + '@aws-sdk/credential-provider-sso@3.908.0': + resolution: {integrity: sha512-WV/aOzuS6ZZhrkPty6TJ3ZG24iS8NXP0m3GuTVuZ5tKi9Guss31/PJ1CrKPRCYGm15CsIjf+mrUxVnNYv9ap5g==} engines: {node: '>=18.0.0'} - '@aws-sdk/lib-storage@3.797.0': - resolution: {integrity: sha512-hGacJXiFBnhkDhDuirptViR0ZfpvE6ENt+xJFV76F5OX8RvO7UhEkq9wdq/GzlSwrPB2XBfoYQgdtHJpjHs2zA==} + '@aws-sdk/credential-provider-web-identity@3.908.0': + resolution: {integrity: sha512-9xWrFn6nWlF5KlV4XYW+7E6F33S3wUUEGRZ/+pgDhkIZd527ycT2nPG2dZ3fWUZMlRmzijP20QIJDqEbbGWe1Q==} engines: {node: '>=18.0.0'} - peerDependencies: - '@aws-sdk/client-s3': ^3.797.0 - '@aws-sdk/middleware-bucket-endpoint@3.775.0': - resolution: {integrity: sha512-qogMIpVChDYr4xiUNC19/RDSw/sKoHkAhouS6Skxiy6s27HBhow1L3Z1qVYXuBmOZGSWPU0xiyZCvOyWrv9s+Q==} + '@aws-sdk/lib-storage@3.908.0': + resolution: {integrity: sha512-tWYvGPAImOHSGYyau5rrVQA3OS0MV8ZCgf5ywtRIAmMEV4CSctDBP8WR2FrO7shAPKMRkjgdul5f0pZAjOYd2Q==} engines: {node: '>=18.0.0'} + peerDependencies: + '@aws-sdk/client-s3': ^3.908.0 - '@aws-sdk/middleware-expect-continue@3.775.0': - resolution: {integrity: sha512-Apd3owkIeUW5dnk3au9np2IdW2N0zc9NjTjHiH+Mx3zqwSrc+m+ANgJVgk9mnQjMzU/vb7VuxJ0eqdEbp5gYsg==} + '@aws-sdk/middleware-bucket-endpoint@3.901.0': + resolution: {integrity: sha512-mPF3N6eZlVs9G8aBSzvtoxR1RZqMo1aIwR+X8BAZSkhfj55fVF2no4IfPXfdFO3I66N+zEQ8nKoB0uTATWrogQ==} engines: {node: '>=18.0.0'} - '@aws-sdk/middleware-flexible-checksums@3.796.0': - resolution: {integrity: sha512-JTqnyzGlbvXDcEnBtd5LFNrCFKUHnGyp/V9+BkvzNP02WXABLWzYvj1TCaf5pQySwK/b4kVn5lvbpTi0rXqjZw==} + '@aws-sdk/middleware-expect-continue@3.901.0': + resolution: {integrity: sha512-bwq9nj6MH38hlJwOY9QXIDwa6lI48UsaZpaXbdD71BljEIRlxDzfB4JaYb+ZNNK7RIAdzsP/K05mJty6KJAQHw==} engines: {node: '>=18.0.0'} - '@aws-sdk/middleware-host-header@3.775.0': - resolution: {integrity: sha512-tkSegM0Z6WMXpLB8oPys/d+umYIocvO298mGvcMCncpRl77L9XkvSLJIFzaHes+o7djAgIduYw8wKIMStFss2w==} + '@aws-sdk/middleware-flexible-checksums@3.908.0': + resolution: {integrity: sha512-hYGhNBvdfnxhhywYRkesdxIZD8rvhsp2CBci5kCqrR2o5VvEkn5+waUQtkREtkciEpC4ent4fadg7N9XfTKvgQ==} engines: {node: '>=18.0.0'} - '@aws-sdk/middleware-location-constraint@3.775.0': - resolution: {integrity: sha512-8TMXEHZXZTFTckQLyBT5aEI8fX11HZcwZseRifvBKKpj0RZDk4F0EEYGxeNSPpUQ7n+PRWyfAEnnZNRdAj/1NQ==} + '@aws-sdk/middleware-host-header@3.901.0': + resolution: {integrity: sha512-yWX7GvRmqBtbNnUW7qbre3GvZmyYwU0WHefpZzDTYDoNgatuYq6LgUIQ+z5C04/kCRoFkAFrHag8a3BXqFzq5A==} engines: {node: '>=18.0.0'} - '@aws-sdk/middleware-logger@3.775.0': - resolution: {integrity: sha512-FaxO1xom4MAoUJsldmR92nT1G6uZxTdNYOFYtdHfd6N2wcNaTuxgjIvqzg5y7QIH9kn58XX/dzf1iTjgqUStZw==} + '@aws-sdk/middleware-location-constraint@3.901.0': + resolution: {integrity: sha512-MuCS5R2ngNoYifkVt05CTULvYVWX0dvRT0/Md4jE3a0u0yMygYy31C1zorwfE/SUgAQXyLmUx8ATmPp9PppImQ==} engines: {node: '>=18.0.0'} - '@aws-sdk/middleware-recursion-detection@3.775.0': - resolution: {integrity: sha512-GLCzC8D0A0YDG5u3F5U03Vb9j5tcOEFhr8oc6PDk0k0vm5VwtZOE6LvK7hcCSoAB4HXyOUM0sQuXrbaAh9OwXA==} + '@aws-sdk/middleware-logger@3.901.0': + resolution: {integrity: sha512-UoHebjE7el/tfRo8/CQTj91oNUm+5Heus5/a4ECdmWaSCHCS/hXTsU3PTTHAY67oAQR8wBLFPfp3mMvXjB+L2A==} engines: {node: '>=18.0.0'} - '@aws-sdk/middleware-sdk-s3@3.796.0': - resolution: {integrity: sha512-5o78oE79sGOtYkL7Up02h2nmr9UhGQZJgxE29EBdTw4dZ1EaA46L+C8oA+fBCmAB5xPQsjQqvhRrsr4Lcp+jZQ==} + '@aws-sdk/middleware-recursion-detection@3.901.0': + resolution: {integrity: sha512-Wd2t8qa/4OL0v/oDpCHHYkgsXJr8/ttCxrvCKAt0H1zZe2LlRhY9gpDVKqdertfHrHDj786fOvEQA28G1L75Dg==} engines: {node: '>=18.0.0'} - '@aws-sdk/middleware-ssec@3.775.0': - resolution: {integrity: sha512-Iw1RHD8vfAWWPzBBIKaojO4GAvQkHOYIpKdAfis/EUSUmSa79QsnXnRqsdcE0mCB0Ylj23yi+ah4/0wh9FsekA==} + '@aws-sdk/middleware-sdk-s3@3.908.0': + resolution: {integrity: sha512-23MbAOHsGaD0kTVMVLumaIM1f9vtDImIn2lSvPullbjFHKS4XxfrKuPumtKDzl8gzcux+98XnmfDRKH0fzkOUA==} engines: {node: '>=18.0.0'} - '@aws-sdk/middleware-user-agent@3.796.0': - resolution: {integrity: sha512-IeNg+3jNWT37J45opi5Jx89hGF0lOnZjiNwlMp3rKq7PlOqy8kWq5J1Gxk0W3tIkPpuf68CtBs/QFrRXWOjsZw==} + '@aws-sdk/middleware-ssec@3.901.0': + resolution: {integrity: sha512-YiLLJmA3RvjL38mFLuu8fhTTGWtp2qT24VqpucgfoyziYcTgIQkJJmKi90Xp6R6/3VcArqilyRgM1+x8i/em+Q==} engines: {node: '>=18.0.0'} - '@aws-sdk/nested-clients@3.797.0': - resolution: {integrity: sha512-xCsRKdsv0GAg9E28fvYBdC3JR2xdtZ2o41MVknOs+pSFtMsZm3SsgxObN35p1OTMk/o/V0LORGVLnFQMlc5QiA==} + '@aws-sdk/middleware-user-agent@3.908.0': + resolution: {integrity: sha512-R0ePEOku72EvyJWy/D0Z5f/Ifpfxa0U9gySO3stpNhOox87XhsILpcIsCHPy0OHz1a7cMoZsF6rMKSzDeCnogQ==} engines: {node: '>=18.0.0'} - '@aws-sdk/region-config-resolver@3.775.0': - resolution: {integrity: sha512-40iH3LJjrQS3LKUJAl7Wj0bln7RFPEvUYKFxtP8a+oKFDO0F65F52xZxIJbPn6sHkxWDAnZlGgdjZXM3p2g5wQ==} + '@aws-sdk/nested-clients@3.908.0': + resolution: {integrity: sha512-ZxDYrfxOKXNFHLyvJtT96TJ0p4brZOhwRE4csRXrezEVUN+pNgxuem95YvMALPVhlVqON2CTzr8BX+CcBKvX9Q==} engines: {node: '>=18.0.0'} - '@aws-sdk/signature-v4-multi-region@3.796.0': - resolution: {integrity: sha512-JAOLdvazTc9HlTFslSrIOrKRMuOruuM3FeGw0hyfLP/RIbjd9bqe/xLIzDSJr3wpCpJs0sXoofwJgXtgTipvjA==} + '@aws-sdk/region-config-resolver@3.901.0': + resolution: {integrity: sha512-7F0N888qVLHo4CSQOsnkZ4QAp8uHLKJ4v3u09Ly5k4AEStrSlFpckTPyUx6elwGL+fxGjNE2aakK8vEgzzCV0A==} engines: {node: '>=18.0.0'} - '@aws-sdk/token-providers@3.797.0': - resolution: {integrity: sha512-TLFkP4BBdkH2zCXhG3JjaYrRft25MMZ+6/YDz1C/ikq2Zk8krUbVoSmhtYMVz10JtxAPiQ++w0vI/qbz2JSDXg==} + '@aws-sdk/signature-v4-multi-region@3.908.0': + resolution: {integrity: sha512-8OodflIzZM2GVuCGiGK6hqwsbfHRDl4kQcEYzHRg9p91H4h5Y876DPvLRkwM7pSC7LKUL0XkKWWVVjwJbp6/Ig==} engines: {node: '>=18.0.0'} - '@aws-sdk/types@3.775.0': - resolution: {integrity: sha512-ZoGKwa4C9fC9Av6bdfqcW6Ix5ot05F/S4VxWR2nHuMv7hzfmAjTOcUiWT7UR4hM/U0whf84VhDtXN/DWAk52KA==} + '@aws-sdk/token-providers@3.908.0': + resolution: {integrity: sha512-4SosHWRQ8hj1X2yDenCYHParcCjHcd7S+Mdb/lelwF0JBFCNC+dNCI9ws3cP/dFdZO/AIhJQGUBzEQtieloixw==} engines: {node: '>=18.0.0'} - '@aws-sdk/util-arn-parser@3.723.0': - resolution: {integrity: sha512-ZhEfvUwNliOQROcAk34WJWVYTlTa4694kSVhDSjW6lE1bMataPnIN8A0ycukEzBXmd8ZSoBcQLn6lKGl7XIJ5w==} + '@aws-sdk/types@3.901.0': + resolution: {integrity: sha512-FfEM25hLEs4LoXsLXQ/q6X6L4JmKkKkbVFpKD4mwfVHtRVQG6QxJiCPcrkcPISquiy6esbwK2eh64TWbiD60cg==} engines: {node: '>=18.0.0'} - '@aws-sdk/util-endpoints@3.787.0': - resolution: {integrity: sha512-fd3zkiOkwnbdbN0Xp9TsP5SWrmv0SpT70YEdbb8wAj2DWQwiCmFszaSs+YCvhoCdmlR3Wl9Spu0pGpSAGKeYvQ==} + '@aws-sdk/util-arn-parser@3.893.0': + resolution: {integrity: sha512-u8H4f2Zsi19DGnwj5FSZzDMhytYF/bCh37vAtBsn3cNDL3YG578X5oc+wSX54pM3tOxS+NY7tvOAo52SW7koUA==} engines: {node: '>=18.0.0'} - '@aws-sdk/util-locate-window@3.804.0': - resolution: {integrity: sha512-zVoRfpmBVPodYlnMjgVjfGoEZagyRF5IPn3Uo6ZvOZp24chnW/FRstH7ESDHDDRga4z3V+ElUQHKpFDXWyBW5A==} + '@aws-sdk/util-endpoints@3.901.0': + resolution: {integrity: sha512-5nZP3hGA8FHEtKvEQf4Aww5QZOkjLW1Z+NixSd+0XKfHvA39Ah5sZboScjLx0C9kti/K3OGW1RCx5K9Zc3bZqg==} engines: {node: '>=18.0.0'} - '@aws-sdk/util-user-agent-browser@3.775.0': - resolution: {integrity: sha512-txw2wkiJmZKVdDbscK7VBK+u+TJnRtlUjRTLei+elZg2ADhpQxfVAQl436FUeIv6AhB/oRHW6/K/EAGXUSWi0A==} + '@aws-sdk/util-locate-window@3.208.0': + resolution: {integrity: sha512-iua1A2+P7JJEDHVgvXrRJSvsnzG7stYSGQnBVphIUlemwl6nN5D+QrgbjECtrbxRz8asYFHSzhdhECqN+tFiBg==} + engines: {node: '>=14.0.0'} + + '@aws-sdk/util-user-agent-browser@3.907.0': + resolution: {integrity: sha512-Hus/2YCQmtCEfr4Ls88d07Q99Ex59uvtktiPTV963Q7w7LHuIT/JBjrbwNxtSm2KlJR9PHNdqxwN+fSuNsMGMQ==} - '@aws-sdk/util-user-agent-node@3.796.0': - resolution: {integrity: sha512-9fQpNcHgVFitf1tbTT8V1xGRoRHSmOAWjrhevo6Tc0WoINMAKz+4JNqfVGWRE5Tmtpq0oHKo1RmvxXQQtJYciA==} + '@aws-sdk/util-user-agent-node@3.908.0': + resolution: {integrity: sha512-l6AEaKUAYarcEy8T8NZ+dNZ00VGLs3fW2Cqu1AuPENaSad0/ahEU+VU7MpXS8FhMRGPgplxKVgCTLyTY0Lbssw==} engines: {node: '>=18.0.0'} peerDependencies: aws-crt: '>=1.0.0' @@ -1747,62 +1844,125 @@ packages: aws-crt: optional: true - '@aws-sdk/xml-builder@3.775.0': - resolution: {integrity: sha512-b9NGO6FKJeLGYnV7Z1yvcP1TNU4dkD5jNsLWOF1/sygZoASaQhNOlaiJ/1OH331YQ1R1oWk38nBb0frsYkDsOQ==} + '@aws-sdk/xml-builder@3.901.0': + resolution: {integrity: sha512-pxFCkuAP7Q94wMTNPAwi6hEtNrp/BdFf+HOrIEeFQsk4EoOmpKY3I6S+u6A9Wg295J80Kh74LqDWM22ux3z6Aw==} + engines: {node: '>=18.0.0'} + + '@aws/lambda-invoke-store@0.0.1': + resolution: {integrity: sha512-ORHRQ2tmvnBXc8t/X9Z8IcSbBA4xTLKuN873FopzklHMeqBst7YG0d+AX97inkvDX+NChYtSr+qGfcqGFaI8Zw==} engines: {node: '>=18.0.0'} + '@babel/code-frame@7.24.7': + resolution: {integrity: sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==} + engines: {node: '>=6.9.0'} + '@babel/code-frame@7.27.1': resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==} engines: {node: '>=6.9.0'} - '@babel/compat-data@7.27.5': - resolution: {integrity: sha512-KiRAp/VoJaWkkte84TvUd9qjdbZAdiqyvMxrGl1N6vzFogKmaLgoM3L1kgtLicp2HP5fBJS8JrZKLVIZGVJAVg==} + '@babel/compat-data@7.25.0': + resolution: {integrity: sha512-P4fwKI2mjEb3ZU5cnMJzvRsRKGBUcs8jvxIoRmr6ufAY9Xk2Bz7JubRTTivkw55c7WQJfTECeqYVa+HZ0FzREg==} + engines: {node: '>=6.9.0'} + + '@babel/compat-data@7.28.4': + resolution: {integrity: sha512-YsmSKC29MJwf0gF8Rjjrg5LQCmyh+j/nD8/eP7f+BeoQTKYqs9RoWbjGOdy0+1Ekr68RJZMUOPVQaQisnIo4Rw==} + engines: {node: '>=6.9.0'} + + '@babel/core@7.24.9': + resolution: {integrity: sha512-5e3FI4Q3M3Pbr21+5xJwCv6ZT6KmGkI0vw3Tozy5ODAQFTIWe37iT8Cr7Ice2Ntb+M3iSKCEWMB1MBgKrW3whg==} + engines: {node: '>=6.9.0'} + + '@babel/core@7.28.4': + resolution: {integrity: sha512-2BCOP7TN8M+gVDj7/ht3hsaO/B/n5oDbiAyyvnRlNOs+u1o+JWNYTQrmpuNp1/Wq2gcFrI01JAW+paEKDMx/CA==} + engines: {node: '>=6.9.0'} + + '@babel/generator@7.25.0': + resolution: {integrity: sha512-3LEEcj3PVW8pW2R1SR1M89g/qrYk/m/mB/tLqn7dn4sbBUQyTqnlod+II2U4dqiGtUmkcnAmkMDralTFZttRiw==} engines: {node: '>=6.9.0'} - '@babel/core@7.27.4': - resolution: {integrity: sha512-bXYxrXFubeYdvB0NhD/NBB3Qi6aZeV20GOWVI47t2dkecCEoneR4NPVcb7abpXDEvejgrUfFtG6vG/zxAKmg+g==} + '@babel/generator@7.28.3': + resolution: {integrity: sha512-3lSpxGgvnmZznmBkCRnVREPUFJv2wrv9iAoFDvADJc0ypmdOxdUtcLeBgBJ6zE0PMeTKnxeQzyk0xTBq4Ep7zw==} engines: {node: '>=6.9.0'} - '@babel/generator@7.27.5': - resolution: {integrity: sha512-ZGhA37l0e/g2s1Cnzdix0O3aLYm66eF8aufiVteOgnwxgnRP8GoyMj7VWsgWnQbVKXyge7hqrFh2K2TQM6t1Hw==} + '@babel/helper-compilation-targets@7.24.8': + resolution: {integrity: sha512-oU+UoqCHdp+nWVDkpldqIQL/i/bvAv53tRqLG/s+cOXxe66zOYLU7ar/Xs3LdmBihrUMEUhwu6dMZwbNOYDwvw==} engines: {node: '>=6.9.0'} '@babel/helper-compilation-targets@7.27.2': resolution: {integrity: sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==} engines: {node: '>=6.9.0'} + '@babel/helper-globals@7.28.0': + resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-imports@7.24.7': + resolution: {integrity: sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==} + engines: {node: '>=6.9.0'} + '@babel/helper-module-imports@7.27.1': resolution: {integrity: sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==} engines: {node: '>=6.9.0'} - '@babel/helper-module-transforms@7.27.3': - resolution: {integrity: sha512-dSOvYwvyLsWBeIRyOeHXp5vPj5l1I011r52FM1+r1jCERv+aFXYk4whgQccYEGYxK2H3ZAIA8nuPkQ0HaUo3qg==} + '@babel/helper-module-transforms@7.25.0': + resolution: {integrity: sha512-bIkOa2ZJYn7FHnepzr5iX9Kmz8FjIz4UKzJ9zhX3dnYuVW0xul9RuR3skBfoLu+FPTQw90EHW9rJsSZhyLQ3fQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-module-transforms@7.28.3': + resolution: {integrity: sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/helper-plugin-utils@7.27.1': - resolution: {integrity: sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==} + '@babel/helper-plugin-utils@7.22.5': + resolution: {integrity: sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-simple-access@7.24.7': + resolution: {integrity: sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==} engines: {node: '>=6.9.0'} '@babel/helper-string-parser@7.27.1': resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} engines: {node: '>=6.9.0'} + '@babel/helper-validator-identifier@7.24.7': + resolution: {integrity: sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==} + engines: {node: '>=6.9.0'} + '@babel/helper-validator-identifier@7.27.1': resolution: {integrity: sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==} engines: {node: '>=6.9.0'} + '@babel/helper-validator-option@7.24.8': + resolution: {integrity: sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==} + engines: {node: '>=6.9.0'} + '@babel/helper-validator-option@7.27.1': resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} engines: {node: '>=6.9.0'} - '@babel/helpers@7.27.6': - resolution: {integrity: sha512-muE8Tt8M22638HU31A3CgfSUciwz1fhATfoVai05aPXGor//CdWDCbnlY1yvBPo07njuVOCNGCSp/GTt12lIug==} + '@babel/helpers@7.25.0': + resolution: {integrity: sha512-MjgLZ42aCm0oGjJj8CtSM3DB8NOOf8h2l7DCTePJs29u+v7yO/RBX9nShlKMgFnRks/Q4tBAe7Hxnov9VkGwLw==} + engines: {node: '>=6.9.0'} + + '@babel/helpers@7.28.4': + resolution: {integrity: sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==} + engines: {node: '>=6.9.0'} + + '@babel/highlight@7.24.7': + resolution: {integrity: sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==} engines: {node: '>=6.9.0'} - '@babel/parser@7.27.5': - resolution: {integrity: sha512-OsQd175SxWkGlzbny8J3K8TnnDD0N3lrIUtB92xwyRpzaenGZhxDvxN/JgU00U3CDZNj9tPuDJ5H0WS4Nt3vKg==} + '@babel/parser@7.25.6': + resolution: {integrity: sha512-trGdfBdbD0l1ZPmcJ83eNxB9rbEax4ALFTF7fN386TMYbeCQbyme5cOEXQhbGXKebwGaB/J52w1mrklMcbgy6Q==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/parser@7.28.4': + resolution: {integrity: sha512-yZbBqeM6TkpP9du/I2pUZnJsRMGGvOuIrhjzC1AwHwW+6he4mni6Bp/m8ijn0iOuZuPI2BfkCoSRunpyjnrQKg==} engines: {node: '>=6.0.0'} hasBin: true @@ -1821,18 +1981,6 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-syntax-class-static-block@7.14.5': - resolution: {integrity: sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==} - 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==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - '@babel/plugin-syntax-import-meta@7.10.4': resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} peerDependencies: @@ -1843,8 +1991,8 @@ packages: 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.23.3': + resolution: {integrity: sha512-EB2MELswq55OHUoRZLGg/zC7QWUKfNLpE57m/S2yr1uEneIgsTgrSzXP3NXEsMkVn76OlaVVnzN+ugObuYGwhg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1879,42 +2027,52 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-syntax-private-property-in-object@7.14.5': - resolution: {integrity: sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - '@babel/plugin-syntax-top-level-await@7.14.5': resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} 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.23.3': + resolution: {integrity: sha512-9EiNjVJOMwCO+43TqoTrgQ8jMwcAd0sWyXi9RPfIsLTj4R2MADDDQXELhffaUx/uJv2AYcxBgPwH6j4TIA4ytQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/runtime@7.21.0': + resolution: {integrity: sha512-xwII0//EObnq89Ji5AKYQaRYiW/nZ3llSv29d49IuxPhKbtJoLP+9QUUZ4nVragQVtaVGeZrpB+ZtG/Pdy/POw==} + engines: {node: '>=6.9.0'} + + '@babel/runtime@7.23.4': + resolution: {integrity: sha512-2Yv65nlWnWlSpe3fXEyX5i7fx5kIKo4Qbcj+hMO0odwaneFjfXw5fdum+4yL20O0QiaHpia0cYQ9xpNMqrBwHg==} + engines: {node: '>=6.9.0'} + '@babel/runtime@7.27.0': resolution: {integrity: sha512-VtPOkrdPHZsKc/clNqyi9WUA8TINkZ4cGk63UUE3u4pmB2k+ZMQRDuIOagv8UVd6j7k0T3+RRIb7beKTebNbcw==} engines: {node: '>=6.9.0'} - '@babel/runtime@7.27.6': - resolution: {integrity: sha512-vbavdySgbTTrmFE+EsiqUTzlOr5bzlnJtUv9PynGCAKvfQqjIXbvFdumPM/GxMDfyuGMJaJAU6TO4zc1Jf1i8Q==} + '@babel/template@7.25.0': + resolution: {integrity: sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==} engines: {node: '>=6.9.0'} '@babel/template@7.27.2': resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==} engines: {node: '>=6.9.0'} - '@babel/traverse@7.27.4': - resolution: {integrity: sha512-oNcu2QbHqts9BtOWJosOVJapWjBDSxGCpFvikNR5TGDYDQf3JwpIoMzIKrvfoti93cLfPJEG4tH9SPVeyCGgdA==} + '@babel/traverse@7.25.0': + resolution: {integrity: sha512-ubALThHQy4GCf6mbb+5ZRNmLLCI7bJ3f8Q6LHBSRlSKSWj5a7dSUzJBLv3VuIhFrFPgjF4IzPF567YG/HSCdZA==} engines: {node: '>=6.9.0'} - '@babel/types@7.27.6': - resolution: {integrity: sha512-ETyHEk2VHHvl9b9jZP5IHPavHYk57EhanlRRuae9XCpb/j5bDCbPPMOBfCWhnl/7EDJz0jEMCi/RhccCE8r1+Q==} + '@babel/traverse@7.28.4': + resolution: {integrity: sha512-YEzuboP2qvQavAcjgQNVgsvHIDv6ZpwXvcvjmyySP2DIMuByS/6ioU5G9pYrWHM6T2YDfc7xga9iNzYOs12CFQ==} + engines: {node: '>=6.9.0'} + + '@babel/types@7.25.6': + resolution: {integrity: sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw==} + engines: {node: '>=6.9.0'} + + '@babel/types@7.28.4': + resolution: {integrity: sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q==} engines: {node: '>=6.9.0'} '@bcoe/v8-coverage@0.2.3': @@ -1924,450 +2082,314 @@ packages: resolution: {integrity: sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==} engines: {node: '>=18'} - '@biomejs/biome@1.9.4': - resolution: {integrity: sha512-1rkd7G70+o9KkTn5KLmDYXihGoTaIGO9PIIN2ZB7UJxFrWw04CZHPYiMRjYsaDvVV7hP1dYNRLxSANLaBFGpog==} + '@biomejs/biome@2.3.1': + resolution: {integrity: sha512-A29evf1R72V5bo4o2EPxYMm5mtyGvzp2g+biZvRFx29nWebGyyeOSsDWGx3tuNNMFRepGwxmA9ZQ15mzfabK2w==} engines: {node: '>=14.21.3'} hasBin: true - '@biomejs/cli-darwin-arm64@1.9.4': - resolution: {integrity: sha512-bFBsPWrNvkdKrNCYeAp+xo2HecOGPAy9WyNyB/jKnnedgzl4W4Hb9ZMzYNbf8dMCGmUdSavlYHiR01QaYR58cw==} + '@biomejs/cli-darwin-arm64@2.3.1': + resolution: {integrity: sha512-ombSf3MnTUueiYGN1SeI9tBCsDUhpWzOwS63Dove42osNh0PfE1cUtHFx6eZ1+MYCCLwXzlFlYFdrJ+U7h6LcA==} engines: {node: '>=14.21.3'} cpu: [arm64] os: [darwin] - '@biomejs/cli-darwin-x64@1.9.4': - resolution: {integrity: sha512-ngYBh/+bEedqkSevPVhLP4QfVPCpb+4BBe2p7Xs32dBgs7rh9nY2AIYUL6BgLw1JVXV8GlpKmb/hNiuIxfPfZg==} + '@biomejs/cli-darwin-x64@2.3.1': + resolution: {integrity: sha512-pcOfwyoQkrkbGvXxRvZNe5qgD797IowpJPovPX5biPk2FwMEV+INZqfCaz4G5bVq9hYnjwhRMamg11U4QsRXrQ==} engines: {node: '>=14.21.3'} cpu: [x64] os: [darwin] - '@biomejs/cli-linux-arm64-musl@1.9.4': - resolution: {integrity: sha512-v665Ct9WCRjGa8+kTr0CzApU0+XXtRgwmzIf1SeKSGAv+2scAlW6JR5PMFo6FzqqZ64Po79cKODKf3/AAmECqA==} + '@biomejs/cli-linux-arm64-musl@2.3.1': + resolution: {integrity: sha512-+DZYv8l7FlUtTrWs1Tdt1KcNCAmRO87PyOnxKGunbWm5HKg1oZBSbIIPkjrCtDZaeqSG1DiGx7qF+CPsquQRcg==} engines: {node: '>=14.21.3'} cpu: [arm64] os: [linux] - '@biomejs/cli-linux-arm64@1.9.4': - resolution: {integrity: sha512-fJIW0+LYujdjUgJJuwesP4EjIBl/N/TcOX3IvIHJQNsAqvV2CHIogsmA94BPG6jZATS4Hi+xv4SkBBQSt1N4/g==} + '@biomejs/cli-linux-arm64@2.3.1': + resolution: {integrity: sha512-td5O8pFIgLs8H1sAZsD6v+5quODihyEw4nv2R8z7swUfIK1FKk+15e4eiYVLcAE4jUqngvh4j3JCNgg0Y4o4IQ==} engines: {node: '>=14.21.3'} cpu: [arm64] os: [linux] - '@biomejs/cli-linux-x64-musl@1.9.4': - resolution: {integrity: sha512-gEhi/jSBhZ2m6wjV530Yy8+fNqG8PAinM3oV7CyO+6c3CEh16Eizm21uHVsyVBEB6RIM8JHIl6AGYCv6Q6Q9Tg==} + '@biomejs/cli-linux-x64-musl@2.3.1': + resolution: {integrity: sha512-Y3Ob4nqgv38Mh+6EGHltuN+Cq8aj/gyMTJYzkFZV2AEj+9XzoXB9VNljz9pjfFNHUxvLEV4b55VWyxozQTBaUQ==} engines: {node: '>=14.21.3'} cpu: [x64] os: [linux] - '@biomejs/cli-linux-x64@1.9.4': - resolution: {integrity: sha512-lRCJv/Vi3Vlwmbd6K+oQ0KhLHMAysN8lXoCI7XeHlxaajk06u7G+UsFSO01NAs5iYuWKmVZjmiOzJ0OJmGsMwg==} + '@biomejs/cli-linux-x64@2.3.1': + resolution: {integrity: sha512-PYWgEO7up7XYwSAArOpzsVCiqxBCXy53gsReAb1kKYIyXaoAlhBaBMvxR/k2Rm9aTuZ662locXUmPk/Aj+Xu+Q==} engines: {node: '>=14.21.3'} cpu: [x64] os: [linux] - '@biomejs/cli-win32-arm64@1.9.4': - resolution: {integrity: sha512-tlbhLk+WXZmgwoIKwHIHEBZUwxml7bRJgk0X2sPyNR3S93cdRq6XulAZRQJ17FYGGzWne0fgrXBKpl7l4M87Hg==} + '@biomejs/cli-win32-arm64@2.3.1': + resolution: {integrity: sha512-RHIG/zgo+69idUqVvV3n8+j58dKYABRpMyDmfWu2TITC+jwGPiEaT0Q3RKD+kQHiS80mpBrST0iUGeEXT0bU9A==} engines: {node: '>=14.21.3'} cpu: [arm64] os: [win32] - '@biomejs/cli-win32-x64@1.9.4': - resolution: {integrity: sha512-8Y5wMhVIPaWe6jw2H+KlEm4wP/f7EW3810ZLmDlrEEy5KvBsb9ECEfu/kMWD484ijfQ8+nIi0giMgu9g1UAuuA==} + '@biomejs/cli-win32-x64@2.3.1': + resolution: {integrity: sha512-izl30JJ5Dp10mi90Eko47zhxE6pYyWPcnX1NQxKpL/yMhXxf95oLTzfpu4q+MDBh/gemNqyJEwjBpe0MT5iWPA==} engines: {node: '>=14.21.3'} cpu: [x64] os: [win32] - '@bundled-es-modules/cookie@2.0.1': - resolution: {integrity: sha512-8o+5fRPLNbjbdGRRmJj3h6Hh1AQJf2dk3qQ/5ZFb+PXkRNiSoMGGUKlsgLfrxneb72axVJyIYji64E2+nNfYyw==} - - '@bundled-es-modules/statuses@1.0.1': - resolution: {integrity: sha512-yn7BklA5acgcBr+7w064fGV+SGIFySjCKpqjcWgBAIfrAkY+4GQTJJHQMeT3V/sgz23VTEVV8TtOmkvJAhFVfg==} - - '@bundled-es-modules/tough-cookie@0.1.6': - resolution: {integrity: sha512-dvMHbL464C0zI+Yqxbz6kZ5TOEp7GLW+pry/RWndAR8MJQAXZ2rPmIs8tziTZjeIyhSNZgZbCePtfSbdWqStJw==} - '@canvas/image-data@1.0.0': resolution: {integrity: sha512-BxOqI5LgsIQP1odU5KMwV9yoijleOPzHL18/YvNqF9KFSGF2K/DLlYAbDQsWqd/1nbaFuSkYD/191dpMtNh4vw==} '@chainsafe/is-ip@2.1.0': resolution: {integrity: sha512-KIjt+6IfysQ4GCv66xihEitBjvhU/bixbbbFxdJ1sqCp4uJ0wuZiYBPhksZoy4lfaF0k9cwNzY5upEW/VWdw3w==} - '@colors/colors@1.5.0': - resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==} - engines: {node: '>=0.1.90'} - - '@cropper/element-canvas@2.0.0': - resolution: {integrity: sha512-GPtGJgSm92crJhhhwUsaMw3rz2KfJWWSz7kRAlufFEV/EHTP5+6r6/Z1BCGRna830i+Avqbm435XLOtA7PVJwA==} + '@cropper/element-canvas@2.0.1': + resolution: {integrity: sha512-OKxq/O0HL9W2JegOsc2zh1NRpERZcLM5+M8aQ/eXdmMcfi1lzosPftag3Irp6pTsVpwV6B6ypIxKESzJ4ci9Fw==} - '@cropper/element-crosshair@2.0.0': - resolution: {integrity: sha512-KfPfyrdeFvUC31Ws7ATtcalWWSaMtrC6bMoCipZhqbUOE7wZoL4ecDSL6BUOZxPa74awZUqfzirCDjHvheBfyw==} + '@cropper/element-crosshair@2.0.1': + resolution: {integrity: sha512-bS5msU9cTU/jf1/kDw+QJmEM9/rw8IgOdpolR85iMVUCR8sRcLa0wgom42MBHcpBYB6hvL5YfiOeXZ7lHIYMpw==} - '@cropper/element-grid@2.0.0': - resolution: {integrity: sha512-i78SQ0IJTLFveKX6P7svkfMYVdgHrQ8ZmmEw8keFy9n1ZVbK+SK0UHK5FNMRNI/gtVhKJOGEnK/zeyjUdj4Iyw==} + '@cropper/element-grid@2.0.1': + resolution: {integrity: sha512-ayqCvYQJ+GVT31HhFpttzHabW1T/LsIwLJY5PLTMG0cEZLw/E8ihg8mxctjZbo852D7oEePbz6/2SeuCb1018Q==} - '@cropper/element-handle@2.0.0': - resolution: {integrity: sha512-ZJvW+0MkK9E8xYymGdoruaQn2kwjSHFpNSWinjyq6csuVQiCPxlX5ovAEDldmZ9MWePPtWEi3vLKQOo2Yb0T8g==} + '@cropper/element-handle@2.0.1': + resolution: {integrity: sha512-fdifyyPIaR9S2eQ7qPHuM8fX8uToAfBsi8vQlR9EM+oJkDNil0uO4rWyArLWEtlr0/q7U0OvsufcuJ7ffqfmpg==} - '@cropper/element-image@2.0.0': - resolution: {integrity: sha512-9BxiTS/aHRmrjopaFQb9mQQXmx4ruhYHGkDZMVz24AXpMFjUY6OpqrWse/WjzD9tfhMFvEdu17b3VAekcAgpeg==} + '@cropper/element-image@2.0.1': + resolution: {integrity: sha512-gPj5Sl2T8Cno198Cz3F3TDfcYoALW3yJ3fV6PHXmhMnX8sBkL7J441do7Vwkg0mEd2CogCtTLAf+p7ljdV0kgA==} - '@cropper/element-selection@2.0.0': - resolution: {integrity: sha512-ensNnbIfJsJ8bhbJTH/RXtk2URFvTOO4TvfRk461n2FPEC588D7rwBmUJxQg74IiTi4y1JbCI+6j+4LyzYBLCQ==} + '@cropper/element-selection@2.0.1': + resolution: {integrity: sha512-atv+Aeq2N2eWawelIRPGh1kYFdNrpb0QkUPPheGxz1ImfxpLdcHO9gb9T5noQijizUW2G0pNvts4ZaITQ0I71Q==} - '@cropper/element-shade@2.0.0': - resolution: {integrity: sha512-jv/2bbNZnhU4W+T4G0c8ADocLIZvQFTXgCf2RFDNhI5UVxurzWBnDdb8Mx8LnVplnkTqO+xUmHZYve0CwgWo+Q==} + '@cropper/element-shade@2.0.1': + resolution: {integrity: sha512-YIYgJ690NdFQ6wJLRFh/EySNVxGFKArncQ4FrsJ3yHU+ShgtOKz4FpjFLpqJRJB9swoVbD3WKTimGyzXrwjZrQ==} - '@cropper/element-viewer@2.0.0': - resolution: {integrity: sha512-zY+3VRN5TvpM8twlphYtXw0tzJL2VgzeK7ufhL1BixVqOdRxwP13TprYIhqwGt9EW/SyJZUiaIu396T89kRX8A==} + '@cropper/element-viewer@2.0.1': + resolution: {integrity: sha512-HDj25l08pWi/AO6El/OqfQHBpBC4Lh5NEnQN1SOldsmxEwt27Ubv6ndDsF8LkTK7XPwjjZRpyQPyfig4w8L2JQ==} - '@cropper/element@2.0.0': - resolution: {integrity: sha512-lsthn0nQq73GExUE7Mg/ss6Q3RXADGDv055hxoLFwvl/wGHgy6ZkYlfLZ/VmgBHC6jDK5IgPBFnqrPqlXWSGBA==} + '@cropper/element@2.0.1': + resolution: {integrity: sha512-Jn1hR7XWzWQM/QfXRGMGzdkJ2gG/UcLdQPZQ7OKs0JiFfRzKpzu4u/nYrXHeH3MM2iOslLqh2kqYju6mjZLMJQ==} - '@cropper/elements@2.0.0': - resolution: {integrity: sha512-PQkPo1nUjxLFUQuHYu+6atfHxpX9B41Xribao6wpvmvmNIFML6LQdNqqWYb6LyM7ujsu71CZdBiMT5oetjJVoQ==} + '@cropper/elements@2.0.1': + resolution: {integrity: sha512-paFbBLXTKXNngn1yDi2ZIf+FO1pIEQXyBntmqOjuxqtG73KuEKv633wsJPFpj958bgcfSakgBbF80j+3nHbPug==} - '@cropper/utils@2.0.0': - resolution: {integrity: sha512-cprLYr+7kK3faGgoOsTW9gIn5sefDr2KwOmgyjzIXk+8PLpW8FgFKEg5FoWfRD5zMAmkCBuX6rGKDK3VdUEGrg==} + '@cropper/utils@2.0.1': + resolution: {integrity: sha512-A9RnAFmgNF5aZk5q2VZnFnHtXWu1kPyEN0LVsX8wJ2LBRu2nyETKwz+ZXVsVWliktToCaYojHKrS+6/HODyEZA==} - '@csstools/color-helpers@5.0.2': - resolution: {integrity: sha512-JqWH1vsgdGcw2RR6VliXXdA0/59LttzlU8UlRT/iUUsEeWfYq8I+K0yhihEUTTHLRm1EXvpsCx3083EU15ecsA==} + '@csstools/color-helpers@5.0.1': + resolution: {integrity: sha512-MKtmkA0BX87PKaO1NFRTFH+UnkgnmySQOvNxJubsadusqPEC2aJ9MOQiMceZJJ6oitUl/i0L6u0M1IrmAOmgBA==} engines: {node: '>=18'} - '@csstools/css-calc@2.1.4': - resolution: {integrity: sha512-3N8oaj+0juUw/1H3YwmDDJXCgTB1gKU6Hc/bB502u9zR0q2vd786XJH9QfrKIEgFlZmhZiq6epXl4rHqhzsIgQ==} + '@csstools/css-calc@2.1.1': + resolution: {integrity: sha512-rL7kaUnTkL9K+Cvo2pnCieqNpTKgQzy5f+N+5Iuko9HAoasP+xgprVh7KN/MaJVvVL1l0EzQq2MoqBHKSrDrag==} engines: {node: '>=18'} peerDependencies: - '@csstools/css-parser-algorithms': ^3.0.5 - '@csstools/css-tokenizer': ^3.0.4 + '@csstools/css-parser-algorithms': ^3.0.4 + '@csstools/css-tokenizer': ^3.0.3 - '@csstools/css-color-parser@3.0.10': - resolution: {integrity: sha512-TiJ5Ajr6WRd1r8HSiwJvZBiJOqtH86aHpUjq5aEKWHiII2Qfjqd/HCWKPOW8EP4vcspXbHnXrwIDlu5savQipg==} + '@csstools/css-color-parser@3.0.7': + resolution: {integrity: sha512-nkMp2mTICw32uE5NN+EsJ4f5N+IGFeCFu4bGpiKgb2Pq/7J/MpyLBeQ5ry4KKtRFZaYs6sTmcMYrSRIyj5DFKA==} engines: {node: '>=18'} peerDependencies: - '@csstools/css-parser-algorithms': ^3.0.5 - '@csstools/css-tokenizer': ^3.0.4 + '@csstools/css-parser-algorithms': ^3.0.4 + '@csstools/css-tokenizer': ^3.0.3 - '@csstools/css-parser-algorithms@3.0.5': - resolution: {integrity: sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==} + '@csstools/css-parser-algorithms@3.0.4': + resolution: {integrity: sha512-Up7rBoV77rv29d3uKHUIVubz1BTcgyUK72IvCQAbfbMv584xHcGKCKbWh7i8hPrRJ7qU4Y8IO3IY9m+iTB7P3A==} engines: {node: '>=18'} peerDependencies: - '@csstools/css-tokenizer': ^3.0.4 + '@csstools/css-tokenizer': ^3.0.3 - '@csstools/css-tokenizer@3.0.4': - resolution: {integrity: sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==} + '@csstools/css-tokenizer@3.0.3': + resolution: {integrity: sha512-UJnjoFsmxfKUdNYdWgOB0mWUypuLvAfQPH1+pyvRJs6euowbFkFC6P13w1l8mJyi3vxYMxc9kld5jZEGRQs6bw==} engines: {node: '>=18'} - '@cypress/request@3.0.8': - resolution: {integrity: sha512-h0NFgh1mJmm1nr4jCwkGHwKneVYKghUyWe6TMNrk0B9zsjAJxpg8C4/+BAcmLgCPa1vj1V8rNUaILl+zYRUWBQ==} + '@cypress/request@3.0.9': + resolution: {integrity: sha512-I3l7FdGRXluAS44/0NguwWlO83J18p0vlr2FYHrJkWdNYhgVoiYo61IXPqaOsL+vNxU1ZqMACzItGK3/KKDsdw==} engines: {node: '>= 6'} '@cypress/xvfb@1.2.4': resolution: {integrity: sha512-skbBzPggOVYCbnGgV+0dmBdW/s77ZkAOXIC1knS8NagwDjBrNC1LuXtQJeiN6l+m7lzmHtaoUw/ctJKdqkG57Q==} - '@dice-roller/rpg-dice-roller@5.5.1': - resolution: {integrity: sha512-De5/UTjihpv639XJDBOCfwuOlzIInLqCeal5rpIY9C8Qh8oaNL2/5e0wa/0lcVZyy8m+BCn5zT4eZamCnguIXQ==} + '@dice-roller/rpg-dice-roller@5.5.0': + resolution: {integrity: sha512-ip318MKhfRvqzpXNQaMyqJkOWbeOlaiIopfyluantEVF706fRP4Jy0WsTZrnKhRvhJTZTJa5dTTWqcoPmt1Xww==} engines: {node: '>=18.0'} '@digitalbazaar/http-client@3.4.1': resolution: {integrity: sha512-Ahk1N+s7urkgj7WvvUND5f8GiWEPfUw0D41hdElaqLgu8wZScI8gdI0q+qWw5N1d35x7GCRH2uk9mi+Uzo9M3g==} engines: {node: '>=14.0'} - '@discordapp/twemoji@15.1.0': - resolution: {integrity: sha512-QdpV4ifTONAXvDjRrMohausZeGrQ1ac/Ox6togUh6Xl3XKJ/KAaMMuAEi0qsb0wDwoVTSZBll5Y6+N3hB2ktBw==} + '@discordapp/twemoji@16.0.1': + resolution: {integrity: sha512-figLiBWzjS5cyrAjLaGjM8AAaowO3qvK8rg5bA2dElB4qsaPMvBVlFDMO2d3x+nC1igt7kgWH4dvNmvvUHUF8w==} - '@emnapi/runtime@1.4.3': - resolution: {integrity: sha512-pBPWdu6MLKROBX05wSNKcNb++m5Er+KQ9QkB+WVM+pW2Kx9hoSrVTnu3BdkI5eBLZoKu/J6mW/B6i6bJB2ytXQ==} + '@emnapi/runtime@1.2.0': + resolution: {integrity: sha512-bV21/9LQmcQeCPEg3BDFtvwL6cwiTMksYNWQQ4KOxCZikEGalWtenoZ0wCiukJINlGCIi2KXx01g4FoH/LxpzQ==} - '@esbuild/aix-ppc64@0.21.5': - resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} - engines: {node: '>=12'} - cpu: [ppc64] - os: [aix] + '@epic-web/invariant@1.0.0': + resolution: {integrity: sha512-lrTPqgvfFQtR/eY/qkIzp98OGdNJu0m5ji3q/nJI8v3SXkRKEnWiOxMmbvcSoAIzv/cGiuvRy57k4suKQSAdwA==} - '@esbuild/aix-ppc64@0.25.3': - resolution: {integrity: sha512-W8bFfPA8DowP8l//sxjJLSLkD8iEjMc7cBVyP+u4cEv9sM7mdUCkgsj+t0n/BWPFtv7WWCN5Yzj0N6FJNUUqBQ==} + '@esbuild/aix-ppc64@0.25.10': + resolution: {integrity: sha512-0NFWnA+7l41irNuaSVlLfgNT12caWJVLzp5eAVhZ0z1qpxbockccEt3s+149rE64VUI3Ml2zt8Nv5JVc4QXTsw==} engines: {node: '>=18'} cpu: [ppc64] os: [aix] - '@esbuild/android-arm64@0.21.5': - resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} - engines: {node: '>=12'} - cpu: [arm64] - os: [android] - - '@esbuild/android-arm64@0.25.3': - resolution: {integrity: sha512-XelR6MzjlZuBM4f5z2IQHK6LkK34Cvv6Rj2EntER3lwCBFdg6h2lKbtRjpTTsdEjD/WSe1q8UyPBXP1x3i/wYQ==} + '@esbuild/android-arm64@0.25.10': + resolution: {integrity: sha512-LSQa7eDahypv/VO6WKohZGPSJDq5OVOo3UoFR1E4t4Gj1W7zEQMUhI+lo81H+DtB+kP+tDgBp+M4oNCwp6kffg==} engines: {node: '>=18'} cpu: [arm64] os: [android] - '@esbuild/android-arm@0.21.5': - resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} - engines: {node: '>=12'} - cpu: [arm] - os: [android] - - '@esbuild/android-arm@0.25.3': - resolution: {integrity: sha512-PuwVXbnP87Tcff5I9ngV0lmiSu40xw1At6i3GsU77U7cjDDB4s0X2cyFuBiDa1SBk9DnvWwnGvVaGBqoFWPb7A==} + '@esbuild/android-arm@0.25.10': + resolution: {integrity: sha512-dQAxF1dW1C3zpeCDc5KqIYuZ1tgAdRXNoZP7vkBIRtKZPYe2xVr/d3SkirklCHudW1B45tGiUlz2pUWDfbDD4w==} engines: {node: '>=18'} cpu: [arm] os: [android] - '@esbuild/android-x64@0.21.5': - resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} - engines: {node: '>=12'} - cpu: [x64] - os: [android] - - '@esbuild/android-x64@0.25.3': - resolution: {integrity: sha512-ogtTpYHT/g1GWS/zKM0cc/tIebFjm1F9Aw1boQ2Y0eUQ+J89d0jFY//s9ei9jVIlkYi8AfOjiixcLJSGNSOAdQ==} + '@esbuild/android-x64@0.25.10': + resolution: {integrity: sha512-MiC9CWdPrfhibcXwr39p9ha1x0lZJ9KaVfvzA0Wxwz9ETX4v5CHfF09bx935nHlhi+MxhA63dKRRQLiVgSUtEg==} engines: {node: '>=18'} cpu: [x64] os: [android] - '@esbuild/darwin-arm64@0.21.5': - resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} - engines: {node: '>=12'} - cpu: [arm64] - os: [darwin] - - '@esbuild/darwin-arm64@0.25.3': - resolution: {integrity: sha512-eESK5yfPNTqpAmDfFWNsOhmIOaQA59tAcF/EfYvo5/QWQCzXn5iUSOnqt3ra3UdzBv073ykTtmeLJZGt3HhA+w==} + '@esbuild/darwin-arm64@0.25.10': + resolution: {integrity: sha512-JC74bdXcQEpW9KkV326WpZZjLguSZ3DfS8wrrvPMHgQOIEIG/sPXEN/V8IssoJhbefLRcRqw6RQH2NnpdprtMA==} engines: {node: '>=18'} cpu: [arm64] os: [darwin] - '@esbuild/darwin-x64@0.21.5': - resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} - engines: {node: '>=12'} - cpu: [x64] - os: [darwin] - - '@esbuild/darwin-x64@0.25.3': - resolution: {integrity: sha512-Kd8glo7sIZtwOLcPbW0yLpKmBNWMANZhrC1r6K++uDR2zyzb6AeOYtI6udbtabmQpFaxJ8uduXMAo1gs5ozz8A==} + '@esbuild/darwin-x64@0.25.10': + resolution: {integrity: sha512-tguWg1olF6DGqzws97pKZ8G2L7Ig1vjDmGTwcTuYHbuU6TTjJe5FXbgs5C1BBzHbJ2bo1m3WkQDbWO2PvamRcg==} engines: {node: '>=18'} cpu: [x64] os: [darwin] - '@esbuild/freebsd-arm64@0.21.5': - resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} - engines: {node: '>=12'} - cpu: [arm64] - os: [freebsd] - - '@esbuild/freebsd-arm64@0.25.3': - resolution: {integrity: sha512-EJiyS70BYybOBpJth3M0KLOus0n+RRMKTYzhYhFeMwp7e/RaajXvP+BWlmEXNk6uk+KAu46j/kaQzr6au+JcIw==} + '@esbuild/freebsd-arm64@0.25.10': + resolution: {integrity: sha512-3ZioSQSg1HT2N05YxeJWYR+Libe3bREVSdWhEEgExWaDtyFbbXWb49QgPvFH8u03vUPX10JhJPcz7s9t9+boWg==} engines: {node: '>=18'} cpu: [arm64] os: [freebsd] - '@esbuild/freebsd-x64@0.21.5': - resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [freebsd] - - '@esbuild/freebsd-x64@0.25.3': - resolution: {integrity: sha512-Q+wSjaLpGxYf7zC0kL0nDlhsfuFkoN+EXrx2KSB33RhinWzejOd6AvgmP5JbkgXKmjhmpfgKZq24pneodYqE8Q==} + '@esbuild/freebsd-x64@0.25.10': + resolution: {integrity: sha512-LLgJfHJk014Aa4anGDbh8bmI5Lk+QidDmGzuC2D+vP7mv/GeSN+H39zOf7pN5N8p059FcOfs2bVlrRr4SK9WxA==} engines: {node: '>=18'} cpu: [x64] os: [freebsd] - '@esbuild/linux-arm64@0.21.5': - resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} - engines: {node: '>=12'} - cpu: [arm64] - os: [linux] - - '@esbuild/linux-arm64@0.25.3': - resolution: {integrity: sha512-xCUgnNYhRD5bb1C1nqrDV1PfkwgbswTTBRbAd8aH5PhYzikdf/ddtsYyMXFfGSsb/6t6QaPSzxtbfAZr9uox4A==} + '@esbuild/linux-arm64@0.25.10': + resolution: {integrity: sha512-5luJWN6YKBsawd5f9i4+c+geYiVEw20FVW5x0v1kEMWNq8UctFjDiMATBxLvmmHA4bf7F6hTRaJgtghFr9iziQ==} engines: {node: '>=18'} cpu: [arm64] os: [linux] - '@esbuild/linux-arm@0.21.5': - resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} - engines: {node: '>=12'} - cpu: [arm] - os: [linux] - - '@esbuild/linux-arm@0.25.3': - resolution: {integrity: sha512-dUOVmAUzuHy2ZOKIHIKHCm58HKzFqd+puLaS424h6I85GlSDRZIA5ycBixb3mFgM0Jdh+ZOSB6KptX30DD8YOQ==} + '@esbuild/linux-arm@0.25.10': + resolution: {integrity: sha512-oR31GtBTFYCqEBALI9r6WxoU/ZofZl962pouZRTEYECvNF/dtXKku8YXcJkhgK/beU+zedXfIzHijSRapJY3vg==} engines: {node: '>=18'} cpu: [arm] os: [linux] - '@esbuild/linux-ia32@0.21.5': - resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} - engines: {node: '>=12'} - cpu: [ia32] - os: [linux] - - '@esbuild/linux-ia32@0.25.3': - resolution: {integrity: sha512-yplPOpczHOO4jTYKmuYuANI3WhvIPSVANGcNUeMlxH4twz/TeXuzEP41tGKNGWJjuMhotpGabeFYGAOU2ummBw==} + '@esbuild/linux-ia32@0.25.10': + resolution: {integrity: sha512-NrSCx2Kim3EnnWgS4Txn0QGt0Xipoumb6z6sUtl5bOEZIVKhzfyp/Lyw4C1DIYvzeW/5mWYPBFJU3a/8Yr75DQ==} engines: {node: '>=18'} cpu: [ia32] os: [linux] - '@esbuild/linux-loong64@0.21.5': - resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} - engines: {node: '>=12'} - cpu: [loong64] - os: [linux] - - '@esbuild/linux-loong64@0.25.3': - resolution: {integrity: sha512-P4BLP5/fjyihmXCELRGrLd793q/lBtKMQl8ARGpDxgzgIKJDRJ/u4r1A/HgpBpKpKZelGct2PGI4T+axcedf6g==} + '@esbuild/linux-loong64@0.25.10': + resolution: {integrity: sha512-xoSphrd4AZda8+rUDDfD9J6FUMjrkTz8itpTITM4/xgerAZZcFW7Dv+sun7333IfKxGG8gAq+3NbfEMJfiY+Eg==} engines: {node: '>=18'} cpu: [loong64] os: [linux] - '@esbuild/linux-mips64el@0.21.5': - resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} - engines: {node: '>=12'} - cpu: [mips64el] - os: [linux] - - '@esbuild/linux-mips64el@0.25.3': - resolution: {integrity: sha512-eRAOV2ODpu6P5divMEMa26RRqb2yUoYsuQQOuFUexUoQndm4MdpXXDBbUoKIc0iPa4aCO7gIhtnYomkn2x+bag==} + '@esbuild/linux-mips64el@0.25.10': + resolution: {integrity: sha512-ab6eiuCwoMmYDyTnyptoKkVS3k8fy/1Uvq7Dj5czXI6DF2GqD2ToInBI0SHOp5/X1BdZ26RKc5+qjQNGRBelRA==} engines: {node: '>=18'} cpu: [mips64el] os: [linux] - '@esbuild/linux-ppc64@0.21.5': - resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} - engines: {node: '>=12'} - cpu: [ppc64] - os: [linux] - - '@esbuild/linux-ppc64@0.25.3': - resolution: {integrity: sha512-ZC4jV2p7VbzTlnl8nZKLcBkfzIf4Yad1SJM4ZMKYnJqZFD4rTI+pBG65u8ev4jk3/MPwY9DvGn50wi3uhdaghg==} + '@esbuild/linux-ppc64@0.25.10': + resolution: {integrity: sha512-NLinzzOgZQsGpsTkEbdJTCanwA5/wozN9dSgEl12haXJBzMTpssebuXR42bthOF3z7zXFWH1AmvWunUCkBE4EA==} engines: {node: '>=18'} cpu: [ppc64] os: [linux] - '@esbuild/linux-riscv64@0.21.5': - resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} - engines: {node: '>=12'} - cpu: [riscv64] - os: [linux] - - '@esbuild/linux-riscv64@0.25.3': - resolution: {integrity: sha512-LDDODcFzNtECTrUUbVCs6j9/bDVqy7DDRsuIXJg6so+mFksgwG7ZVnTruYi5V+z3eE5y+BJZw7VvUadkbfg7QA==} + '@esbuild/linux-riscv64@0.25.10': + resolution: {integrity: sha512-FE557XdZDrtX8NMIeA8LBJX3dC2M8VGXwfrQWU7LB5SLOajfJIxmSdyL/gU1m64Zs9CBKvm4UAuBp5aJ8OgnrA==} engines: {node: '>=18'} cpu: [riscv64] os: [linux] - '@esbuild/linux-s390x@0.21.5': - resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} - engines: {node: '>=12'} - cpu: [s390x] - os: [linux] - - '@esbuild/linux-s390x@0.25.3': - resolution: {integrity: sha512-s+w/NOY2k0yC2p9SLen+ymflgcpRkvwwa02fqmAwhBRI3SC12uiS10edHHXlVWwfAagYSY5UpmT/zISXPMW3tQ==} + '@esbuild/linux-s390x@0.25.10': + resolution: {integrity: sha512-3BBSbgzuB9ajLoVZk0mGu+EHlBwkusRmeNYdqmznmMc9zGASFjSsxgkNsqmXugpPk00gJ0JNKh/97nxmjctdew==} engines: {node: '>=18'} cpu: [s390x] os: [linux] - '@esbuild/linux-x64@0.21.5': - resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [linux] - - '@esbuild/linux-x64@0.25.3': - resolution: {integrity: sha512-nQHDz4pXjSDC6UfOE1Fw9Q8d6GCAd9KdvMZpfVGWSJztYCarRgSDfOVBY5xwhQXseiyxapkiSJi/5/ja8mRFFA==} + '@esbuild/linux-x64@0.25.10': + resolution: {integrity: sha512-QSX81KhFoZGwenVyPoberggdW1nrQZSvfVDAIUXr3WqLRZGZqWk/P4T8p2SP+de2Sr5HPcvjhcJzEiulKgnxtA==} engines: {node: '>=18'} cpu: [x64] os: [linux] - '@esbuild/netbsd-arm64@0.25.3': - resolution: {integrity: sha512-1QaLtOWq0mzK6tzzp0jRN3eccmN3hezey7mhLnzC6oNlJoUJz4nym5ZD7mDnS/LZQgkrhEbEiTn515lPeLpgWA==} + '@esbuild/netbsd-arm64@0.25.10': + resolution: {integrity: sha512-AKQM3gfYfSW8XRk8DdMCzaLUFB15dTrZfnX8WXQoOUpUBQ+NaAFCP1kPS/ykbbGYz7rxn0WS48/81l9hFl3u4A==} engines: {node: '>=18'} cpu: [arm64] os: [netbsd] - '@esbuild/netbsd-x64@0.21.5': - resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} - engines: {node: '>=12'} - cpu: [x64] - os: [netbsd] - - '@esbuild/netbsd-x64@0.25.3': - resolution: {integrity: sha512-i5Hm68HXHdgv8wkrt+10Bc50zM0/eonPb/a/OFVfB6Qvpiirco5gBA5bz7S2SHuU+Y4LWn/zehzNX14Sp4r27g==} + '@esbuild/netbsd-x64@0.25.10': + resolution: {integrity: sha512-7RTytDPGU6fek/hWuN9qQpeGPBZFfB4zZgcz2VK2Z5VpdUxEI8JKYsg3JfO0n/Z1E/6l05n0unDCNc4HnhQGig==} engines: {node: '>=18'} cpu: [x64] os: [netbsd] - '@esbuild/openbsd-arm64@0.25.3': - resolution: {integrity: sha512-zGAVApJEYTbOC6H/3QBr2mq3upG/LBEXr85/pTtKiv2IXcgKV0RT0QA/hSXZqSvLEpXeIxah7LczB4lkiYhTAQ==} + '@esbuild/openbsd-arm64@0.25.10': + resolution: {integrity: sha512-5Se0VM9Wtq797YFn+dLimf2Zx6McttsH2olUBsDml+lm0GOCRVebRWUvDtkY4BWYv/3NgzS8b/UM3jQNh5hYyw==} engines: {node: '>=18'} cpu: [arm64] os: [openbsd] - '@esbuild/openbsd-x64@0.21.5': - resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} - engines: {node: '>=12'} - cpu: [x64] - os: [openbsd] - - '@esbuild/openbsd-x64@0.25.3': - resolution: {integrity: sha512-fpqctI45NnCIDKBH5AXQBsD0NDPbEFczK98hk/aa6HJxbl+UtLkJV2+Bvy5hLSLk3LHmqt0NTkKNso1A9y1a4w==} + '@esbuild/openbsd-x64@0.25.10': + resolution: {integrity: sha512-XkA4frq1TLj4bEMB+2HnI0+4RnjbuGZfet2gs/LNs5Hc7D89ZQBHQ0gL2ND6Lzu1+QVkjp3x1gIcPKzRNP8bXw==} engines: {node: '>=18'} cpu: [x64] os: [openbsd] - '@esbuild/sunos-x64@0.21.5': - resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} - engines: {node: '>=12'} - cpu: [x64] - os: [sunos] + '@esbuild/openharmony-arm64@0.25.10': + resolution: {integrity: sha512-AVTSBhTX8Y/Fz6OmIVBip9tJzZEUcY8WLh7I59+upa5/GPhh2/aM6bvOMQySspnCCHvFi79kMtdJS1w0DXAeag==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] - '@esbuild/sunos-x64@0.25.3': - resolution: {integrity: sha512-ROJhm7d8bk9dMCUZjkS8fgzsPAZEjtRJqCAmVgB0gMrvG7hfmPmz9k1rwO4jSiblFjYmNvbECL9uhaPzONMfgA==} + '@esbuild/sunos-x64@0.25.10': + resolution: {integrity: sha512-fswk3XT0Uf2pGJmOpDB7yknqhVkJQkAQOcW/ccVOtfx05LkbWOaRAtn5SaqXypeKQra1QaEa841PgrSL9ubSPQ==} engines: {node: '>=18'} cpu: [x64] os: [sunos] - '@esbuild/win32-arm64@0.21.5': - resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} - engines: {node: '>=12'} - cpu: [arm64] - os: [win32] - - '@esbuild/win32-arm64@0.25.3': - resolution: {integrity: sha512-YWcow8peiHpNBiIXHwaswPnAXLsLVygFwCB3A7Bh5jRkIBFWHGmNQ48AlX4xDvQNoMZlPYzjVOQDYEzWCqufMQ==} + '@esbuild/win32-arm64@0.25.10': + resolution: {integrity: sha512-ah+9b59KDTSfpaCg6VdJoOQvKjI33nTaQr4UluQwW7aEwZQsbMCfTmfEO4VyewOxx4RaDT/xCy9ra2GPWmO7Kw==} engines: {node: '>=18'} cpu: [arm64] os: [win32] - '@esbuild/win32-ia32@0.21.5': - resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} - engines: {node: '>=12'} - cpu: [ia32] - os: [win32] - - '@esbuild/win32-ia32@0.25.3': - resolution: {integrity: sha512-qspTZOIGoXVS4DpNqUYUs9UxVb04khS1Degaw/MnfMe7goQ3lTfQ13Vw4qY/Nj0979BGvMRpAYbs/BAxEvU8ew==} + '@esbuild/win32-ia32@0.25.10': + resolution: {integrity: sha512-QHPDbKkrGO8/cz9LKVnJU22HOi4pxZnZhhA2HYHez5Pz4JeffhDjf85E57Oyco163GnzNCVkZK0b/n4Y0UHcSw==} engines: {node: '>=18'} cpu: [ia32] os: [win32] - '@esbuild/win32-x64@0.21.5': - resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} - engines: {node: '>=12'} - cpu: [x64] - os: [win32] - - '@esbuild/win32-x64@0.25.3': - resolution: {integrity: sha512-ICgUR+kPimx0vvRzf+N/7L7tVSQeE3BYY+NhHRHXS1kBuPO7z2+7ea2HbhDyZdTephgvNvKrlDDKUexuCVBVvg==} + '@esbuild/win32-x64@0.25.10': + resolution: {integrity: sha512-9KpxSVFCu0iK1owoez6aC/s/EdUQLDN3adTxGCqxMVhrPDj6bt5dbrHDXUuq+Bs2vATFBBrQS5vdQ/Ed2P+nbw==} engines: {node: '>=18'} cpu: [x64] os: [win32] - '@eslint-community/eslint-utils@4.7.0': - resolution: {integrity: sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==} + '@eslint-community/eslint-utils@4.4.0': + resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + + '@eslint-community/eslint-utils@4.9.0': + resolution: {integrity: sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 @@ -2376,58 +2398,53 @@ packages: resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - '@eslint/compat@1.3.0': - resolution: {integrity: sha512-ZBygRBqpDYiIHsN+d1WyHn3TYgzgpzLEcgJUxTATyiInQbKZz6wZb6+ljwdg8xeeOe4v03z6Uh6lELiw0/mVhQ==} + '@eslint/compat@1.1.1': + resolution: {integrity: sha512-lpHyRyplhGPL5mGEh6M9O5nnKk0Gz4bFI+Zu6tKlPpDUN7XshWvH9C/px4UVm87IAANE0W81CEsNGbS1KlzXpA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: ^9.10.0 - peerDependenciesMeta: - eslint: - optional: true - '@eslint/config-array@0.20.1': - resolution: {integrity: sha512-OL0RJzC/CBzli0DrrR31qzj6d6i6Mm3HByuhflhl4LOBiWxN+3i6/t/ZQQNii4tjksXi8r2CRW1wMpWA2ULUEw==} + '@eslint/config-array@0.21.0': + resolution: {integrity: sha512-ENIdc4iLu0d93HeYirvKmrzshzofPw6VkZRKQGe9Nv46ZnWUzcF1xV01dcvEg/1wXUR61OmmlSfyeyO7EvjLxQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/config-helpers@0.2.3': - resolution: {integrity: sha512-u180qk2Um1le4yf0ruXH3PYFeEZeYC3p/4wCTKrr2U1CmGdzGi3KtY0nuPDH48UJxlKCC5RDzbcbh4X0XlqgHg==} + '@eslint/config-helpers@0.4.1': + resolution: {integrity: sha512-csZAzkNhsgwb0I/UAV6/RGFTbiakPCf0ZrGmrIxQpYvGZ00PhTkSnyKNolphgIvmnJeGw6rcGVEXfTzUnFuEvw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/core@0.13.0': - resolution: {integrity: sha512-yfkgDw1KR66rkT5A8ci4irzDysN7FRpq3ttJolR88OqQikAWqwA8j5VZyas+vjyBNFIJ7MfybJ9plMILI2UrCw==} + '@eslint/core@0.16.0': + resolution: {integrity: sha512-nmC8/totwobIiFcGkDza3GIKfAw1+hLiYVrh3I1nIomQ8PEr5cxg34jnkmGawul/ep52wGRAcyeDCNtWKSOj4Q==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@eslint/eslintrc@3.3.1': resolution: {integrity: sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/js@9.25.1': - resolution: {integrity: sha512-dEIwmjntEx8u3Uvv+kr3PDeeArL8Hw07H9kyYxCjnM9pBjfEhk6uLXSchxxzgiwtRhhzVzqmUSDFBOi1TuZ7qg==} + '@eslint/js@9.37.0': + resolution: {integrity: sha512-jaS+NJ+hximswBG6pjNX0uEJZkrT0zwpVi3BA3vX22aFGjJjmgSTSmPpZCRKmoBL5VY/M6p0xsSJx7rk7sy5gg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@eslint/object-schema@2.1.6': resolution: {integrity: sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/plugin-kit@0.2.8': - resolution: {integrity: sha512-ZAoA40rNMPwSm+AeHpCq8STiNAwzWLJuP8Xv4CHIc9wv/PSuExjMrmjfYNj682vW0OOiZ1HKxzvjQr9XZIisQA==} + '@eslint/plugin-kit@0.4.0': + resolution: {integrity: sha512-sB5uyeq+dwCWyPi31B2gQlVlo+j5brPlWx4yZBrEaRo/nhdDE8Xke1gsGgtiBdaBTxuTkceLVuVt/pclrasb0A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@fastify/accept-negotiator@2.0.1': - resolution: {integrity: sha512-/c/TW2bO/v9JeEgoD/g1G5GxGeCF1Hafdf79WPmUlgYiBXummY0oX3VVq4yFkKKVBKDNlaDUYoab7g38RpPqCQ==} + '@fastify/accept-negotiator@2.0.0': + resolution: {integrity: sha512-/Sce/kBzuTxIq5tJh85nVNOq9wKD8s+viIgX0fFMDBdw95gnpf53qmF1oBgJym3cPFliWUuSloVg/1w/rH0FcQ==} - '@fastify/accepts@5.0.2': - resolution: {integrity: sha512-pX0OrioMz3C2cuYFOGRCNMdP3sR6daTFjeSNFrWlZVutawpPIGI5opK5h4Qa6x6C9oavdDkAjA16orneE2jAFQ==} + '@fastify/accepts@5.0.3': + resolution: {integrity: sha512-JQE0PVW7V5aIvWNQvBvlz3K92Q4OnDcC8ERcJnFd9a11/IVi/eV6SCutOUh9K2CAeQUMkJJyRog3Gltn7uAF6g==} - '@fastify/ajv-compiler@4.0.2': - resolution: {integrity: sha512-Rkiu/8wIjpsf46Rr+Fitd3HRP+VsxUFDDeag0hs9L0ksfnwx2g7SPQQTFL0E8Qv+rfXzQOxBJnjUB9ITUDjfWQ==} + '@fastify/ajv-compiler@4.0.1': + resolution: {integrity: sha512-DxrBdgsjNLP0YM6W5Hd6/Fmj43S8zMKiFJYgi+Ri3htTGAowPVG/tG1wpnWLMjufEnehRivUCKZ1pLDIoZdTuw==} - '@fastify/busboy@2.1.1': - resolution: {integrity: sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==} + '@fastify/busboy@2.1.0': + resolution: {integrity: sha512-+KpH+QxZU7O4675t3mnkQKcZZg56u+K/Ct2K+N2AZYNVK8kyeo/bI18tI8aPm3tvNNRyTWfj6s5tnGNlcbQRsA==} engines: {node: '>=14'} - '@fastify/busboy@3.1.1': - resolution: {integrity: sha512-5DGmA8FTdB2XbDeEwc/5ZXBl6UbBAyBOOLlPuBnZ/N1SwdH9Ii+cOX3tBROlDgcTXxjOYnLMVoKk9+FXAw0CJw==} + '@fastify/busboy@3.0.0': + resolution: {integrity: sha512-83rnH2nCvclWaPQQKvkJ2pdOjG4TZyEVuFDnlOF6KP08lDaaceVyw/W63mDuafQT+MKHCvXIPpE5uYWeM0rT4w==} '@fastify/cookie@11.0.2': resolution: {integrity: sha512-GWdwdGlgJxyvNv+QcKiGNevSspMQXncjMZ1J8IvuDQk0jvkzgWWZFNC2En3s+nHndZBGV8IbLwOI/sxCZw/mzA==} @@ -2435,17 +2452,17 @@ packages: '@fastify/cors@10.1.0': resolution: {integrity: sha512-MZyBCBJtII60CU9Xme/iE4aEy8G7QpzGR8zkdXZkDFt7ElEMachbE61tfhAG/bvSaULlqlf0huMT12T7iqEmdQ==} - '@fastify/deepmerge@2.0.2': - resolution: {integrity: sha512-3wuLdX5iiiYeZWP6bQrjqhrcvBIf0NHbQH1Ur1WbHvoiuTYUEItgygea3zs8aHpiitn0lOB8gX20u1qO+FDm7Q==} + '@fastify/deepmerge@3.1.0': + resolution: {integrity: sha512-lCVONBQINyNhM6LLezB6+2afusgEYR4G8xenMsfe+AT+iZ7Ca6upM5Ha8UkZuYSnuMw3GWl/BiPXnLMi/gSxuQ==} - '@fastify/error@4.2.0': - resolution: {integrity: sha512-RSo3sVDXfHskiBZKBPRgnQTtIqpi/7zhJOEmAxCiBcM7d0uwdGdxLlsCaLzGs8v8NnxIRlfG0N51p5yFaOentQ==} + '@fastify/error@4.0.0': + resolution: {integrity: sha512-OO/SA8As24JtT1usTUTKgGH7uLvhfwZPwlptRi2Dp5P4KKmJI3gvsZ8MIHnNwDs4sLf/aai5LzTyl66xr7qMxA==} '@fastify/express@4.0.2': resolution: {integrity: sha512-lzu9MLdjlsK4Q2RiqEAwTgwQPrWQVP0kmbgAi/w9rIUqtnacjKvj3EHVTR6PIvXDs6Ut1jnTHiGbuNxHTsZwHQ==} - '@fastify/fast-json-stringify-compiler@5.0.3': - resolution: {integrity: sha512-uik7yYHkLr6fxd8hJSZ8c+xF4WafPK+XzneQDPU+D10r5X19GW8lJcom2YijX2+qtFF1ENJlHXKFM9ouXNJYgQ==} + '@fastify/fast-json-stringify-compiler@5.0.1': + resolution: {integrity: sha512-f2d3JExJgFE3UbdFcpPwqNUEoHWmt8pAKf8f+9YuLESdefA0WgqxeT6DrGL4Yrf/9ihXNSKOqpjEmurV405meA==} '@fastify/forwarded@3.0.0': resolution: {integrity: sha512-kJExsp4JCms7ipzg7SJ3y8DwmePaELHxKYtg+tZow+k0znUTf3cb+npgyqm8+ATZOdmfgfydIebPDWM172wfyA==} @@ -2453,23 +2470,23 @@ packages: '@fastify/http-proxy@10.0.2': resolution: {integrity: sha512-3IlTjOu9xtX5UPd/ZxY3ebYb6caINuBlr7iyVxYmh3zZLV0K5ted8yfU9UCNXVNs33RwbXD2RhDucc3z5BNgEA==} - '@fastify/merge-json-schemas@0.2.1': - resolution: {integrity: sha512-OA3KGBCy6KtIvLf8DINC5880o5iBlDX4SxzLQS8HorJAbqluzLRn80UXU0bxZn7UOFhFgpRJDasfwn9nG4FG4A==} + '@fastify/merge-json-schemas@0.1.1': + resolution: {integrity: sha512-fERDVz7topgNjtXsJTTW1JKLy0rhuLRcquYqNR9rF7OcVpCa2OVW49ZPDIhaRRCaUuvVxI+N416xUoF76HNSXA==} - '@fastify/multipart@9.0.3': - resolution: {integrity: sha512-pJogxQCrT12/6I5Fh6jr3narwcymA0pv4B0jbC7c6Bl9wnrxomEUnV0d26w6gUls7gSXmhG8JGRMmHFIPsxt1g==} + '@fastify/multipart@9.2.1': + resolution: {integrity: sha512-U4221XDMfzCUtfzsyV1/PkR4MNgKI0158vUUyn/oF2Tl6RxMc+N7XYLr5fZXQiEC+Fmw5zFaTjxsTGTgtDtK+g==} '@fastify/proxy-addr@5.0.0': resolution: {integrity: sha512-37qVVA1qZ5sgH7KpHkkC4z9SK6StIsIcOmpjvMPXNb3vx2GQxhZocogVYbr2PbbeLCQxYIPDok307xEvRZOzGA==} - '@fastify/reply-from@11.0.2': - resolution: {integrity: sha512-VcHhe01PsHuVX2eVrkoskCs+pwNPgVfOOpwQJnSo3AwIKtISm0VCFB7bycQjHfxAuPYgkrI6ZvYoovdHx4sVMA==} + '@fastify/reply-from@11.0.1': + resolution: {integrity: sha512-F2Qk88gcqIIiug9V+4I6WeeV1faj1Wu798JyOnwbJcjQhm4LYrHdkpFSVwJE0g1cVjYCFFmH3OVh1HHaninttQ==} - '@fastify/send@3.3.1': - resolution: {integrity: sha512-6pofeVwaHN+E/MAofCwDqkWUliE3i++jlD0VH/LOfU8TJlCkMUSgKvA9bawDdVXxjve7XrdYMyDmkiYaoGWEtA==} + '@fastify/send@4.1.0': + resolution: {integrity: sha512-TMYeQLCBSy2TOFmV95hQWkiTYgC/SEx7vMdV+wnZVX4tt8VBLKzmH8vV9OzJehV0+XBfg+WxPMt5wp+JBUKsVw==} - '@fastify/static@8.1.1': - resolution: {integrity: sha512-TW9eyVHJLytZNpBlSIqd0bl1giJkEaRaPZG+5AT3L/OBKq9U8D7g/OYmc2NPQZnzPURGhMt3IAWuyVkvd2nOkQ==} + '@fastify/static@8.2.0': + resolution: {integrity: sha512-PejC/DtT7p1yo3p+W7LiUtLMsV8fEvxAK15sozHy9t8kwo5r0uLYmhV/inURmGz1SkHZFz/8CNtHLPyhKcx4SQ==} '@fastify/view@10.0.2': resolution: {integrity: sha512-tGjXFyDUMj5a+E8BBrQ2wpsVnpOfMq3cqy4WD8pnjWPE/HGNItBASUPoPUcX/QjPhxfuZZTYv2XdCmKXdcMZPw==} @@ -2498,39 +2515,59 @@ packages: resolution: {integrity: sha512-z1CjRjtQyBOYL+5Qr9DdYIfrdLBe746jRTYfaYU6MeXkqp7UfYs/jX16lFFVzZ7PGEJvqZNqYUEtb1mvDww4pA==} engines: {node: '>=12'} - '@google-cloud/translate@7.2.2': - resolution: {integrity: sha512-IAJhPKotLH/OF/NzWml/byLDN+OILbs1P4k+7HNUJK618NsShFelRKzh3pRUUQA4DX0je3HaEZw9nR+5uJ6ZEg==} + '@google-cloud/translate@7.2.1': + resolution: {integrity: sha512-VXmEvMF8qa4c7p5drjUZ06B8v0DxoUfFPyjhFp/wbgoe0GWaD1y1gGk6rUZxGKD/pB19kFU+0LMMSCgBW+a0iA==} engines: {node: '>=12.0.0'} - '@grpc/grpc-js@1.8.22': - resolution: {integrity: sha512-oAjDdN7fzbUi+4hZjKG96MR6KTEubAeMpQEb+77qy+3r0Ua5xTFuie6JOLr4ZZgl5g+W5/uRTS2M1V8mVAFPuA==} + '@grpc/grpc-js@1.8.16': + resolution: {integrity: sha512-Nvlq4V7XQmdRVDGgecR8ZPPCeY+uH1LhzbC+QxklwAahpQlq8YLsiOQgfkub9FiakRiohaDy361xqlTLkq9EHw==} engines: {node: ^8.13.0 || >=10.10.0} - '@grpc/proto-loader@0.7.15': - resolution: {integrity: sha512-tMXdRCfYVixjuFK+Hk0Q1s38gV9zDiDJfWL3h1rv4Qc39oILCu1TRTDt7+fGUI8K4G1Fj125Hx/ru3azECWTyQ==} + '@grpc/proto-loader@0.7.7': + resolution: {integrity: sha512-1TIeXOi8TuSCQprPItwoMymZXxWT0CPxUhkrkeCUH+D8U7QDwQ6b7SUz2MaLuWM2llT+J/TVFLmQI5KtML3BhQ==} engines: {node: '>=6'} hasBin: true + '@hapi/address@5.1.1': + resolution: {integrity: sha512-A+po2d/dVoY7cYajycYI43ZbYMXukuopIsqCjh5QzsBCipDtdofHntljDlpccMjIfTy6UOkg+5KPriwYch2bXA==} + engines: {node: '>=14.0.0'} + '@hapi/boom@10.0.1': resolution: {integrity: sha512-ERcCZaEjdH3OgSJlyjVk8pHIFeus91CjKP3v+MpgBNp5IvGzP2l/bRiD78nqYcKPaZdbKkK5vDBVPd2ohHBlsA==} '@hapi/bourne@3.0.0': resolution: {integrity: sha512-Waj1cwPXJDucOib4a3bAISsKJVb15MKi9IvmTI/7ssVEm6sywXGjVJDhl6/umt1pK1ZS7PacXU3A1PmFKHEZ2w==} + '@hapi/formula@3.0.2': + resolution: {integrity: sha512-hY5YPNXzw1He7s0iqkRQi+uMGh383CGdyyIGYtB+W5N3KHPXoqychklvHhKCC9M3Xtv0OCs/IHw+r4dcHtBYWw==} + + '@hapi/hoek@11.0.4': + resolution: {integrity: sha512-PnsP5d4q7289pS2T2EgGz147BFJ2Jpb4yrEdkpz2IhgEUzos1S7HTl7ezWh1yfYzYlj89KzLdCRkqsP6SIryeQ==} + '@hapi/hoek@11.0.7': resolution: {integrity: sha512-HV5undWkKzcB4RZUusqOpcgxOaq6VOAH7zhhIr2g3G8NF/MlFO75SjOr2NfuSx0Mh40+1FqCkagKLJRykUWoFQ==} '@hapi/hoek@9.3.0': resolution: {integrity: sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==} + '@hapi/pinpoint@2.0.1': + resolution: {integrity: sha512-EKQmr16tM8s16vTT3cA5L0kZZcTMU5DUOZTuvpnY738m+jyP3JIUj+Mm1xc1rsLkGBQ/gVnfKYPwOmPg1tUR4Q==} + + '@hapi/tlds@1.1.3': + resolution: {integrity: sha512-QIvUMB5VZ8HMLZF9A2oWr3AFM430QC8oGd0L35y2jHpuW6bIIca6x/xL7zUf4J7L9WJ3qjz+iJII8ncaeMbpSg==} + engines: {node: '>=14.0.0'} + '@hapi/topo@5.1.0': resolution: {integrity: sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==} - '@hapi/wreck@18.1.0': - resolution: {integrity: sha512-0z6ZRCmFEfV/MQqkQomJ7sl/hyxvcZM7LtuVqN3vdAO4vM9eBbowl0kaqQj9EJJQab+3Uuh1GxbGIBFy4NfJ4w==} + '@hapi/topo@6.0.2': + resolution: {integrity: sha512-KR3rD5inZbGMrHmgPxsJ9dbi6zEK+C3ZwUwTa+eMwWLz7oijWUTWD2pMSNNYJAU6Qq+65NkxXjqHr/7LM2Xkqg==} - '@hexagon/base64@1.1.28': - resolution: {integrity: sha512-lhqDEAvWixy3bZ+UOYbPwUbBkwBq5C1LAJ/xPC8Oi+lL54oyakv/npbA0aU2hgCsx/1NUd4IBvV03+aUBWxerw==} + '@hapi/wreck@18.0.1': + resolution: {integrity: sha512-OLHER70+rZxvDl75xq3xXOfd3e8XIvz8fWY0dqg92UvhZ29zo24vQgfqgHSYhB5ZiuFpSLeriOisAlxAo/1jWg==} + + '@hexagon/base64@1.1.27': + resolution: {integrity: sha512-PdUmzpvcUM3Rh39kvz9RdbPVYhMjBjdV7Suw7ZduP7urRLsZR8l5tzgSWKm7TExwBYDFwTnYrZbnE0rQ3N5NLQ==} '@humanfs/core@0.19.1': resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} @@ -2548,12 +2585,12 @@ packages: resolution: {integrity: sha512-RE815I4arJFtt+FVeU1Tgp9/Xvecacji8w/V6XtXsWWH/wz/eNkNbhb+ny/+PlVZjV0rxQpRSQKNKE3lcktHEA==} engines: {node: '>=10.10.0'} - '@humanwhocodes/retry@0.3.1': - resolution: {integrity: sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==} + '@humanwhocodes/retry@0.3.0': + resolution: {integrity: sha512-d2CGZR2o7fS6sWB7DG/3a95bGKQyHMACZ5aW8qGkkqQpUoZV6C0X7Pc7l4ZNMZkfNBf4VWNe9E1jRsf0G146Ew==} engines: {node: '>=18.18'} - '@humanwhocodes/retry@0.4.3': - resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} + '@humanwhocodes/retry@0.4.2': + resolution: {integrity: sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ==} engines: {node: '>=18.18'} '@img/sharp-darwin-arm64@0.33.5': @@ -2661,39 +2698,36 @@ packages: cpu: [x64] os: [win32] - '@inquirer/confirm@5.1.12': - resolution: {integrity: sha512-dpq+ielV9/bqgXRUbNH//KsY6WEw9DrGPmipkpmgC1Y46cwuBTNx7PXFWTjc3MQ+urcc0QxoVHcMI0FW4Ok0hg==} + '@inquirer/confirm@5.0.2': + resolution: {integrity: sha512-KJLUHOaKnNCYzwVbryj3TNBxyZIrr56fR5N45v6K9IPrbT6B7DcudBMfylkV1A8PUdJE15mybkEQyp2/ZUpxUA==} engines: {node: '>=18'} peerDependencies: '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - '@inquirer/core@10.1.13': - resolution: {integrity: sha512-1viSxebkYN2nJULlzCxES6G9/stgHSepZ9LqqfdIGPHj5OHhiBUXVS0a6R0bEC2A+VL4D9w6QB66ebCr6HGllA==} + '@inquirer/core@10.1.0': + resolution: {integrity: sha512-I+ETk2AL+yAVbvuKx5AJpQmoaWhpiTFOg/UJb7ZkMAK4blmtG8ATh5ct+T/8xNld0CZG/2UhtkdMwpgvld92XQ==} engines: {node: '>=18'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - '@inquirer/figures@1.0.12': - resolution: {integrity: sha512-MJttijd8rMFcKJC8NYmprWr6hD3r9Gd9qUC0XwPNwoEPWSMVJwA2MlXxF+nhZZNMY+HXsWa+o7KY2emWYIn0jQ==} + '@inquirer/figures@1.0.8': + resolution: {integrity: sha512-tKd+jsmhq21AP1LhexC0pPwsCxEhGgAkg28byjJAd+xhmIs8LUX8JbUc3vBf3PhLxWiB5EvyBE5X7JSPAqMAqg==} engines: {node: '>=18'} - '@inquirer/type@3.0.7': - resolution: {integrity: sha512-PfunHQcjwnju84L+ycmcMKB/pTPIngjUJvfnRhKY6FKPuYXlM4aQCb/nIdTFR6BEhMjFvngzvng/vBAJMZpLSA==} + '@inquirer/type@3.0.1': + resolution: {integrity: sha512-+ksJMIy92sOAiAccGpcKZUc3bYO07cADnscIxHBknEm3uNts3movSmBofc1908BNy5edKscxYeAdaX1NXkHS6A==} engines: {node: '>=18'} peerDependencies: '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - '@ioredis/commands@1.2.0': - resolution: {integrity: sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg==} + '@ioredis/commands@1.4.0': + resolution: {integrity: sha512-aFT2yemJJo+TZCmieA7qnYGQooOS7QfNmYrzGtsYd3g9j5iDP8AimYYAesf79ohjbLG12XxC4nG5DyEnC88AsQ==} + + '@isaacs/balanced-match@4.0.1': + resolution: {integrity: sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==} + engines: {node: 20 || >=22} + + '@isaacs/brace-expansion@5.0.0': + resolution: {integrity: sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==} + engines: {node: 20 || >=22} '@isaacs/cliui@8.0.2': resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} @@ -2724,9 +2758,9 @@ packages: node-notifier: optional: true - '@jest/create-cache-key-function@29.7.0': - resolution: {integrity: sha512-4QqS3LY5PBmTRHj9sAg1HLoPzqAI0uOX6wI/TRqHIcOxlFidy6YEmCQJk6FSZjNLGCeubDMfmkWL+qaLKhSGQA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/create-cache-key-function@30.2.0': + resolution: {integrity: sha512-44F4l4Enf+MirJN8X/NhdGkl71k5rBYiwdVlo4HxOwbu0sHV8QKrGEedb1VUU4K3W7fBKE0HGfbn7eZm0Ti3zg==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} '@jest/environment@29.7.0': resolution: {integrity: sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==} @@ -2748,6 +2782,10 @@ packages: resolution: {integrity: sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/pattern@30.0.1': + resolution: {integrity: sha512-gWp7NfQW27LaBQz3TITS8L7ZCQ0TLvtmI//4OwlQRx4rnWxcPNIYjxZpDcN4+UlGxgm3jS5QPz8IPTCkb59wZA==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + '@jest/reporters@29.7.0': resolution: {integrity: sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -2761,6 +2799,10 @@ packages: resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/schemas@30.0.5': + resolution: {integrity: sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + '@jest/source-map@29.6.3': resolution: {integrity: sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -2781,51 +2823,64 @@ packages: resolution: {integrity: sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - '@joshwooding/vite-plugin-react-docgen-typescript@0.5.0': - resolution: {integrity: sha512-qYDdL7fPwLRI+bJNurVcis+tNgJmvWjH4YTBGXTA8xMuxFrnAz6E5o35iyzyKbq5J5Lr8mJGfrR5GXl+WGwhgQ==} + '@jest/types@30.2.0': + resolution: {integrity: sha512-H9xg1/sfVvyfU7o3zMfBEjQ1gcsdeTMgqHoYdN79tuLqfTtuu7WckRA1R5whDwOzxaZAeMKTYWqP+WCAi0CHsg==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + + '@joshwooding/vite-plugin-react-docgen-typescript@0.6.1': + resolution: {integrity: sha512-J4BaTocTOYFkMHIra1JDWrMWpNmBl4EkplIwHEsV8aeUOtdWjwSnln9U7twjMFTAEB7mptNtSKyVi1Y2W9sDJw==} peerDependencies: typescript: '>= 4.3.x' - vite: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 + vite: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 peerDependenciesMeta: typescript: optional: true - '@jridgewell/gen-mapping@0.3.8': - resolution: {integrity: sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==} + '@jridgewell/gen-mapping@0.3.13': + resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} + + '@jridgewell/gen-mapping@0.3.5': + resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} engines: {node: '>=6.0.0'} - '@jridgewell/resolve-uri@3.1.2': - resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + '@jridgewell/remapping@2.3.5': + resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} + + '@jridgewell/resolve-uri@3.1.0': + resolution: {integrity: sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==} engines: {node: '>=6.0.0'} '@jridgewell/set-array@1.2.1': resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} engines: {node: '>=6.0.0'} - '@jridgewell/source-map@0.3.6': - resolution: {integrity: sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==} + '@jridgewell/source-map@0.3.5': + resolution: {integrity: sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==} - '@jridgewell/sourcemap-codec@1.5.0': - resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} + '@jridgewell/sourcemap-codec@1.5.5': + resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} '@jridgewell/trace-mapping@0.3.25': resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} - '@jsdevtools/ono@7.1.3': - resolution: {integrity: sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==} + '@jridgewell/trace-mapping@0.3.31': + resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} - '@jsdoc/salty@0.2.9': - resolution: {integrity: sha512-yYxMVH7Dqw6nO0d5NIV8OQWnitU8k6vXH8NtgqAfIa/IUqRMxRv/NUJJ08VEKbAakwxlgBl5PJdrU0dMPStsnw==} + '@jsdoc/salty@0.2.5': + resolution: {integrity: sha512-TfRP53RqunNe2HBobVBJ0VLhK1HbfvBYeTC1ahnN64PWvyYyGebmMiPkuwvD9fpw2ZbkoPb8Q7mwy0aR8Z9rvw==} engines: {node: '>=v12.0.0'} - '@kurkle/color@0.3.4': - resolution: {integrity: sha512-M5UknZPHRu3DEDWoipU6sE8PdkZ6Z/S+v4dD+Ke8IaNlpdSQah50lz1KtcFBa2vsdOnwbbnxJwVM4wty6udA5w==} + '@keyv/serialize@1.1.1': + resolution: {integrity: sha512-dXn3FZhPv0US+7dtJsIi2R+c7qWYiReoEh5zUntWCf4oSpMNib8FDhSoed6m3QyZdx5hK7iLFkYk3rNxwt8vTA==} + + '@kurkle/color@0.3.2': + resolution: {integrity: sha512-fuscdXJ9G1qb7W8VdHi+IwRqij3lBkosAm4ydQtEmbY58OzHXqQhvlxqEkoz0yssNVn38bcpRWgA9PP+OGoisw==} - '@levischuck/tiny-cbor@0.2.11': - resolution: {integrity: sha512-llBRm4dT4Z89aRsm6u2oEZ8tfwL/2l6BwpZ7JcyieouniDECM5AqNgr/y08zalEIvW3RSK4upYyybDcmjXqAow==} + '@levischuck/tiny-cbor@0.2.2': + resolution: {integrity: sha512-f5CnPw997Y2GQ8FAvtuVVC19FX8mwNNC+1XJcIi16n/LTJifKO6QBgGLgN3YEmqtGMk17SKSuoWES3imJVxAVw==} - '@lukeed/csprng@1.1.0': - resolution: {integrity: sha512-Z7C/xXCiGWsg0KuKsHTKJxbWhpI3Vs5GwLfOean7MGyVFGqdRgBbAjOCh6u4bbjPc/8MJ2pZmK/0DLdCbivLDA==} + '@lukeed/csprng@1.0.1': + resolution: {integrity: sha512-uSvJdwQU5nK+Vdf6zxcWAY2A8r7uqe+gePwLWzJ+fsQehq18pc0I2hJKwypZ2aLM90+Er9u1xn4iLJPZ+xlL4g==} engines: {node: '>=8'} '@lukeed/ms@2.0.2': @@ -2842,17 +2897,17 @@ packages: '@mcaptcha/vanilla-glue@0.1.0-alpha-3': resolution: {integrity: sha512-GT6TJBgmViGXcXiT5VOr+h/6iOnThSlZuCoOWncubyTZU9R3cgU5vWPkF7G6Ob6ee2CBe3yqBxxk24CFVGTVXw==} - '@mdx-js/react@3.1.0': - resolution: {integrity: sha512-QjHtSaoameoalGnKDT3FoIl4+9RwyTmo9ZJGBdLOks/YOiWHoRDI3PUwEzOE7kEmGcV3AFcp9K6dYu9rEuKLAQ==} + '@mdx-js/react@3.0.1': + resolution: {integrity: sha512-9ZrPIU4MGf6et1m1ov3zKf+q9+deetI51zprKB1D/z3NOb+rUxxtEl3mCjW5wTGh6VhRdwPueh1oRzi6ezkA8A==} peerDependencies: '@types/react': '>=16' react: '>=16' - '@microsoft/api-extractor-model@7.30.5': - resolution: {integrity: sha512-0ic4rcbcDZHz833RaTZWTGu+NpNgrxVNjVaor0ZDUymfDFzjA/Uuk8hYziIUIOEOSTfmIQqyzVwlzxZxPe7tOA==} + '@microsoft/api-extractor-model@7.31.1': + resolution: {integrity: sha512-Dhnip5OFKbl85rq/ICHBFGhV4RA5UQSl8AC/P/zoGvs+CBudPkatt5kIhMGiYgVPnUWmfR6fcp38+1AFLYNtUw==} - '@microsoft/api-extractor@7.52.5': - resolution: {integrity: sha512-6WWgjjg6FkoDWpF/O3sjB05OkszpI5wtKJqd8fUIR/JJUv8IqNCGr1lJUZJnc1HegcT9gAvyf98KfH0wFncU0w==} + '@microsoft/api-extractor@7.53.1': + resolution: {integrity: sha512-bul5eTNxijLdDBqLye74u9494sRmf+9QULtec9Od0uHnifahGeNt8CC4/xCdn7mVyEBrXIQyQ5+sc4Uc0QfBSA==} hasBin: true '@microsoft/tsdoc-config@0.17.1': @@ -2878,212 +2933,112 @@ packages: '@misskey-dev/sharp-read-bmp@1.2.0': resolution: {integrity: sha512-er4pRakXzHYfEgOFAFfQagqDouG+wLm+kwNq1I30oSdIHDa0wM3KjFpfIGQ25Fks4GcmOl1s7Zh6xoQu5dNjTw==} - '@misskey-dev/summaly@5.2.1': - resolution: {integrity: sha512-fcFd7ssHAghRntewRROOpRxv+VH18uz85Kzg6pZK1EFyqPOXxf39ErRA9HnJSzPYQT6KJTqBWuKHbCGoFlceXg==} + '@misskey-dev/summaly@5.2.4': + resolution: {integrity: sha512-GDil+9w2DPsbwNYatB6cLRCPEqSY9k/f39rN8LrzUKYCrATzj5FLCFIbFvZQg55zgUnM599GJzNLka5LlFlA/g==} - '@msgpackr-extract/msgpackr-extract-darwin-arm64@3.0.3': - resolution: {integrity: sha512-QZHtlVgbAdy2zAqNA9Gu1UpIuI8Xvsd1v8ic6B2pZmeFnFcMWiPLfWXh7TVw4eGEZ/C9TH281KwhVoeQUKbyjw==} + '@msgpackr-extract/msgpackr-extract-darwin-arm64@3.0.2': + resolution: {integrity: sha512-9bfjwDxIDWmmOKusUcqdS4Rw+SETlp9Dy39Xui9BEGEk19dDwH0jhipwFzEff/pFg95NKymc6TOTbRKcWeRqyQ==} cpu: [arm64] os: [darwin] - '@msgpackr-extract/msgpackr-extract-darwin-x64@3.0.3': - resolution: {integrity: sha512-mdzd3AVzYKuUmiWOQ8GNhl64/IoFGol569zNRdkLReh6LRLHOXxU4U8eq0JwaD8iFHdVGqSy4IjFL4reoWCDFw==} + '@msgpackr-extract/msgpackr-extract-darwin-x64@3.0.2': + resolution: {integrity: sha512-lwriRAHm1Yg4iDf23Oxm9n/t5Zpw1lVnxYU3HnJPTi2lJRkKTrps1KVgvL6m7WvmhYVt/FIsssWay+k45QHeuw==} cpu: [x64] os: [darwin] - '@msgpackr-extract/msgpackr-extract-linux-arm64@3.0.3': - resolution: {integrity: sha512-YxQL+ax0XqBJDZiKimS2XQaf+2wDGVa1enVRGzEvLLVFeqa5kx2bWbtcSXgsxjQB7nRqqIGFIcLteF/sHeVtQg==} + '@msgpackr-extract/msgpackr-extract-linux-arm64@3.0.2': + resolution: {integrity: sha512-FU20Bo66/f7He9Fp9sP2zaJ1Q8L9uLPZQDub/WlUip78JlPeMbVL8546HbZfcW9LNciEXc8d+tThSJjSC+tmsg==} cpu: [arm64] os: [linux] - '@msgpackr-extract/msgpackr-extract-linux-arm@3.0.3': - resolution: {integrity: sha512-fg0uy/dG/nZEXfYilKoRe7yALaNmHoYeIoJuJ7KJ+YyU2bvY8vPv27f7UKhGRpY6euFYqEVhxCFZgAUNQBM3nw==} + '@msgpackr-extract/msgpackr-extract-linux-arm@3.0.2': + resolution: {integrity: sha512-MOI9Dlfrpi2Cuc7i5dXdxPbFIgbDBGgKR5F2yWEa6FVEtSWncfVNKW5AKjImAQ6CZlBK9tympdsZJ2xThBiWWA==} cpu: [arm] os: [linux] - '@msgpackr-extract/msgpackr-extract-linux-x64@3.0.3': - resolution: {integrity: sha512-cvwNfbP07pKUfq1uH+S6KJ7dT9K8WOE4ZiAcsrSes+UY55E/0jLYc+vq+DO7jlmqRb5zAggExKm0H7O/CBaesg==} + '@msgpackr-extract/msgpackr-extract-linux-x64@3.0.2': + resolution: {integrity: sha512-gsWNDCklNy7Ajk0vBBf9jEx04RUxuDQfBse918Ww+Qb9HCPoGzS+XJTLe96iN3BVK7grnLiYghP/M4L8VsaHeA==} cpu: [x64] os: [linux] - '@msgpackr-extract/msgpackr-extract-win32-x64@3.0.3': - resolution: {integrity: sha512-x0fWaQtYp4E6sktbsdAqnehxDgEc/VwM7uLsRCYWaiGu0ykYdZPiS8zCWdnjHwyiumousxfBm4SO31eXqwEZhQ==} + '@msgpackr-extract/msgpackr-extract-win32-x64@3.0.2': + resolution: {integrity: sha512-O+6Gs8UeDbyFpbSh2CPEz/UOrrdWPTBYNblZK5CxxLisYt4kGX3Sc+czffFonyjiGSq3jWLwJS/CCJc7tBr4sQ==} cpu: [x64] os: [win32] - '@mswjs/interceptors@0.37.6': - resolution: {integrity: sha512-wK+5pLK5XFmgtH3aQ2YVvA3HohS3xqV/OxuVOdNx9Wpnz7VE/fnC+e1A7ln6LFYeck7gOJ/dsZV6OLplOtAJ2w==} + '@mswjs/interceptors@0.39.7': + resolution: {integrity: sha512-sURvQbbKsq5f8INV54YJgJEdk8oxBanqkTiXXd33rKmofFCwZLhLRszPduMZ9TA9b8/1CHc/IJmOlBHJk2Q5AQ==} engines: {node: '>=18'} - '@napi-rs/canvas-android-arm64@0.1.69': - resolution: {integrity: sha512-4icWTByY8zPvM9SelfQKf3I6kwXw0aI5drBOVrwfER5kjwXJd78FPSDSZkxDHjvIo9Q86ljl18Yr963ehA4sHQ==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [android] - - '@napi-rs/canvas-darwin-arm64@0.1.69': - resolution: {integrity: sha512-HOanhhYlHdukA+unjelT4Dg3ta7e820x87/AG2dKUMsUzH19jaeZs9bcYjzEy2vYi/dFWKz7cSv2yaIOudB8Yg==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [darwin] - - '@napi-rs/canvas-darwin-x64@0.1.69': - resolution: {integrity: sha512-SIp7WfhxAPnSVK9bkFfJp+84rbATCIq9jMUzDwpCLhQ+v+OqtXe4pggX1oeV+62/HK6BT1t18qRmJfyqwJ9f3g==} - engines: {node: '>= 10'} - cpu: [x64] - os: [darwin] - - '@napi-rs/canvas-linux-arm-gnueabihf@0.1.69': - resolution: {integrity: sha512-Ls+KujCp6TGpkuMVFvrlx+CxtL+casdkrprFjqIuOAnB30Mct6bCEr+I83Tu29s3nNq4EzIGjdmA3fFAZG/Dtw==} - engines: {node: '>= 10'} - cpu: [arm] - os: [linux] - - '@napi-rs/canvas-linux-arm64-gnu@0.1.69': - resolution: {integrity: sha512-m8VcGmeSBNRbHZBd1srvdM1aq/ScS2y8KqGqmCCEgJlytYK4jdULzAo2K/BPKE1v3xvn8oUPZDLI/NBJbJkEoA==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [linux] - - '@napi-rs/canvas-linux-arm64-musl@0.1.69': - resolution: {integrity: sha512-a3xjNRIeK2m2ZORGv2moBvv3vbkaFZG1QKMeiEv/BKij+rkztuEhTJGMar+buICFgS0fLgphXXsKNkUSJb7eRQ==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [linux] - - '@napi-rs/canvas-linux-riscv64-gnu@0.1.69': - resolution: {integrity: sha512-pClUoJF5wdC9AvD0mc15G9JffL1Q85nuH1rLSQPRkGmGmQOtRjw5E9xNbanz7oFUiPbjH7xcAXUjVAcf7tdgPQ==} - engines: {node: '>= 10'} - cpu: [riscv64] - os: [linux] - - '@napi-rs/canvas-linux-x64-gnu@0.1.69': - resolution: {integrity: sha512-96X3bFAmzemfw84Ts6Jg/omL86uuynvK06MWGR/mp3JYNumY9RXofA14eF/kJIYelbYFWXcwpbcBR71lJ6G/YQ==} - engines: {node: '>= 10'} - cpu: [x64] - os: [linux] - - '@napi-rs/canvas-linux-x64-musl@0.1.69': - resolution: {integrity: sha512-2QTsEFO72Kwkj53W9hc5y1FAUvdGx0V+pjJB+9oQF6Ys9+y989GyPIl5wZDzeh8nIJW6koZZ1eFa8pD+pA5BFQ==} - engines: {node: '>= 10'} - cpu: [x64] - os: [linux] - - '@napi-rs/canvas-win32-x64-msvc@0.1.69': - resolution: {integrity: sha512-Q4YA8kVnKarApBVLu7F8icGlIfSll5Glswo5hY6gPS4Is2dCI8+ig9OeDM8RlwYevUIxKq8lZBypN8Q1iLAQ7w==} - engines: {node: '>= 10'} - cpu: [x64] - os: [win32] - - '@napi-rs/canvas@0.1.69': - resolution: {integrity: sha512-ydvNeJMRm+l3T14yCoUKqjYQiEdXDq1isznI93LEBGYssXKfSaLNLHOkeM4z9Fnw9Pkt2EKOCAtW9cS4b00Zcg==} - engines: {node: '>= 10'} - - '@napi-rs/nice-android-arm-eabi@1.0.1': - resolution: {integrity: sha512-5qpvOu5IGwDo7MEKVqqyAxF90I6aLj4n07OzpARdgDRfz8UbBztTByBp0RC59r3J1Ij8uzYi6jI7r5Lws7nn6w==} - engines: {node: '>= 10'} - cpu: [arm] - os: [android] - - '@napi-rs/nice-android-arm64@1.0.1': - resolution: {integrity: sha512-GqvXL0P8fZ+mQqG1g0o4AO9hJjQaeYG84FRfZaYjyJtZZZcMjXW5TwkL8Y8UApheJgyE13TQ4YNUssQaTgTyvA==} + '@napi-rs/canvas-android-arm64@0.1.80': + resolution: {integrity: sha512-sk7xhN/MoXeuExlggf91pNziBxLPVUqF2CAVnB57KLG/pz7+U5TKG8eXdc3pm0d7Od0WreB6ZKLj37sX9muGOQ==} engines: {node: '>= 10'} cpu: [arm64] os: [android] - '@napi-rs/nice-darwin-arm64@1.0.1': - resolution: {integrity: sha512-91k3HEqUl2fsrz/sKkuEkscj6EAj3/eZNCLqzD2AA0TtVbkQi8nqxZCZDMkfklULmxLkMxuUdKe7RvG/T6s2AA==} + '@napi-rs/canvas-darwin-arm64@0.1.80': + resolution: {integrity: sha512-O64APRTXRUiAz0P8gErkfEr3lipLJgM6pjATwavZ22ebhjYl/SUbpgM0xcWPQBNMP1n29afAC/Us5PX1vg+JNQ==} engines: {node: '>= 10'} cpu: [arm64] os: [darwin] - '@napi-rs/nice-darwin-x64@1.0.1': - resolution: {integrity: sha512-jXnMleYSIR/+TAN/p5u+NkCA7yidgswx5ftqzXdD5wgy/hNR92oerTXHc0jrlBisbd7DpzoaGY4cFD7Sm5GlgQ==} + '@napi-rs/canvas-darwin-x64@0.1.80': + resolution: {integrity: sha512-FqqSU7qFce0Cp3pwnTjVkKjjOtxMqRe6lmINxpIZYaZNnVI0H5FtsaraZJ36SiTHNjZlUB69/HhxNDT1Aaa9vA==} engines: {node: '>= 10'} cpu: [x64] os: [darwin] - '@napi-rs/nice-freebsd-x64@1.0.1': - resolution: {integrity: sha512-j+iJ/ezONXRQsVIB/FJfwjeQXX7A2tf3gEXs4WUGFrJjpe/z2KB7sOv6zpkm08PofF36C9S7wTNuzHZ/Iiccfw==} - engines: {node: '>= 10'} - cpu: [x64] - os: [freebsd] - - '@napi-rs/nice-linux-arm-gnueabihf@1.0.1': - resolution: {integrity: sha512-G8RgJ8FYXYkkSGQwywAUh84m946UTn6l03/vmEXBYNJxQJcD+I3B3k5jmjFG/OPiU8DfvxutOP8bi+F89MCV7Q==} + '@napi-rs/canvas-linux-arm-gnueabihf@0.1.80': + resolution: {integrity: sha512-eyWz0ddBDQc7/JbAtY4OtZ5SpK8tR4JsCYEZjCE3dI8pqoWUC8oMwYSBGCYfsx2w47cQgQCgMVRVTFiiO38hHQ==} engines: {node: '>= 10'} cpu: [arm] os: [linux] - '@napi-rs/nice-linux-arm64-gnu@1.0.1': - resolution: {integrity: sha512-IMDak59/W5JSab1oZvmNbrms3mHqcreaCeClUjwlwDr0m3BoR09ZiN8cKFBzuSlXgRdZ4PNqCYNeGQv7YMTjuA==} + '@napi-rs/canvas-linux-arm64-gnu@0.1.80': + resolution: {integrity: sha512-qwA63t8A86bnxhuA/GwOkK3jvb+XTQaTiVML0vAWoHyoZYTjNs7BzoOONDgTnNtr8/yHrq64XXzUoLqDzU+Uuw==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] - '@napi-rs/nice-linux-arm64-musl@1.0.1': - resolution: {integrity: sha512-wG8fa2VKuWM4CfjOjjRX9YLIbysSVV1S3Kgm2Fnc67ap/soHBeYZa6AGMeR5BJAylYRjnoVOzV19Cmkco3QEPw==} + '@napi-rs/canvas-linux-arm64-musl@0.1.80': + resolution: {integrity: sha512-1XbCOz/ymhj24lFaIXtWnwv/6eFHXDrjP0jYkc6iHQ9q8oXKzUX1Lc6bu+wuGiLhGh2GS/2JlfORC5ZcXimRcg==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] - '@napi-rs/nice-linux-ppc64-gnu@1.0.1': - resolution: {integrity: sha512-lxQ9WrBf0IlNTCA9oS2jg/iAjQyTI6JHzABV664LLrLA/SIdD+I1i3Mjf7TsnoUbgopBcCuDztVLfJ0q9ubf6Q==} - engines: {node: '>= 10'} - cpu: [ppc64] - os: [linux] - - '@napi-rs/nice-linux-riscv64-gnu@1.0.1': - resolution: {integrity: sha512-3xs69dO8WSWBb13KBVex+yvxmUeEsdWexxibqskzoKaWx9AIqkMbWmE2npkazJoopPKX2ULKd8Fm9veEn0g4Ig==} + '@napi-rs/canvas-linux-riscv64-gnu@0.1.80': + resolution: {integrity: sha512-XTzR125w5ZMs0lJcxRlS1K3P5RaZ9RmUsPtd1uGt+EfDyYMu4c6SEROYsxyatbbu/2+lPe7MPHOO/0a0x7L/gw==} engines: {node: '>= 10'} cpu: [riscv64] os: [linux] - '@napi-rs/nice-linux-s390x-gnu@1.0.1': - resolution: {integrity: sha512-lMFI3i9rlW7hgToyAzTaEybQYGbQHDrpRkg+1gJWEpH0PLAQoZ8jiY0IzakLfNWnVda1eTYYlxxFYzW8Rqczkg==} - engines: {node: '>= 10'} - cpu: [s390x] - os: [linux] - - '@napi-rs/nice-linux-x64-gnu@1.0.1': - resolution: {integrity: sha512-XQAJs7DRN2GpLN6Fb+ZdGFeYZDdGl2Fn3TmFlqEL5JorgWKrQGRUrpGKbgZ25UeZPILuTKJ+OowG2avN8mThBA==} + '@napi-rs/canvas-linux-x64-gnu@0.1.80': + resolution: {integrity: sha512-BeXAmhKg1kX3UCrJsYbdQd3hIMDH/K6HnP/pG2LuITaXhXBiNdh//TVVVVCBbJzVQaV5gK/4ZOCMrQW9mvuTqA==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - '@napi-rs/nice-linux-x64-musl@1.0.1': - resolution: {integrity: sha512-/rodHpRSgiI9o1faq9SZOp/o2QkKQg7T+DK0R5AkbnI/YxvAIEHf2cngjYzLMQSQgUhxym+LFr+UGZx4vK4QdQ==} + '@napi-rs/canvas-linux-x64-musl@0.1.80': + resolution: {integrity: sha512-x0XvZWdHbkgdgucJsRxprX/4o4sEed7qo9rCQA9ugiS9qE2QvP0RIiEugtZhfLH3cyI+jIRFJHV4Fuz+1BHHMg==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - '@napi-rs/nice-win32-arm64-msvc@1.0.1': - resolution: {integrity: sha512-rEcz9vZymaCB3OqEXoHnp9YViLct8ugF+6uO5McifTedjq4QMQs3DHz35xBEGhH3gJWEsXMUbzazkz5KNM5YUg==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [win32] - - '@napi-rs/nice-win32-ia32-msvc@1.0.1': - resolution: {integrity: sha512-t7eBAyPUrWL8su3gDxw9xxxqNwZzAqKo0Szv3IjVQd1GpXXVkb6vBBQUuxfIYaXMzZLwlxRQ7uzM2vdUE9ULGw==} - engines: {node: '>= 10'} - cpu: [ia32] - os: [win32] - - '@napi-rs/nice-win32-x64-msvc@1.0.1': - resolution: {integrity: sha512-JlF+uDcatt3St2ntBG8H02F1mM45i5SF9W+bIKiReVE6wiy3o16oBP/yxt+RZ+N6LbCImJXJ6bXNO2kn9AXicg==} + '@napi-rs/canvas-win32-x64-msvc@0.1.80': + resolution: {integrity: sha512-Z8jPsM6df5V8B1HrCHB05+bDiCxjE9QA//3YrkKIdVDEwn5RKaqOxCJDRJkl48cJbylcrJbW4HxZbTte8juuPg==} engines: {node: '>= 10'} cpu: [x64] os: [win32] - '@napi-rs/nice@1.0.1': - resolution: {integrity: sha512-zM0mVWSXE0a0h9aKACLwKmD6nHcRiKrPpCfvaKqG1CqDEyjEawId0ocXxVzPMCAm6kkWr2P025msfxXEnt8UGQ==} + '@napi-rs/canvas@0.1.80': + resolution: {integrity: sha512-DxuT1ClnIPts1kQx8FBmkk4BQDTfI5kIzywAaMjQSXfNnra5UFU9PwurXrl+Je3bJ6BGsp/zmshVVFbCmyI+ww==} engines: {node: '>= 10'} - '@nestjs/common@11.1.0': - resolution: {integrity: sha512-8MrajltjtIN6eW9cTpv+1IZogqz2Zsrc8YDt0LwQPUq8cSq0j50DETdQpPsNMeib+p9avkV41+NrzGk1z2o5Wg==} + '@nestjs/common@11.1.6': + resolution: {integrity: sha512-krKwLLcFmeuKDqngG2N/RuZHCs2ycsKcxWIDgcm7i1lf3sQ0iG03ci+DsP/r3FcT/eJDFsIHnKtNta2LIi7PzQ==} peerDependencies: - class-transformer: '*' - class-validator: '*' + class-transformer: '>=0.4.1' + class-validator: '>=0.13.2' reflect-metadata: ^0.1.12 || ^0.2.0 rxjs: ^7.1.0 peerDependenciesMeta: @@ -3092,8 +3047,8 @@ packages: class-validator: optional: true - '@nestjs/core@11.1.0': - resolution: {integrity: sha512-IeXbTRPrr6xAVbETlDE+miSkNmYf/cPhCa9GU9gFtPO6pVNuAeG/dNrjLVc23mJtUlT/ibdsoW35TlSyHLkzEA==} + '@nestjs/core@11.1.6': + resolution: {integrity: sha512-siWX7UDgErisW18VTeJA+x+/tpNZrJewjTBsRPF3JVxuWRuAB1kRoiJcxHgln8Lb5UY9NdvklITR84DUEXD0Cg==} engines: {node: '>= 20'} peerDependencies: '@nestjs/common': ^11.0.0 @@ -3110,14 +3065,14 @@ packages: '@nestjs/websockets': optional: true - '@nestjs/platform-express@10.4.17': - resolution: {integrity: sha512-ovn4Wxney3QGBrqNPv0QLcCuH5QoAi6pb/GNWAz6B/NmBjZbs9/zl4a2beGDA2SaYre9w43YbfmHTm17PneP9w==} + '@nestjs/platform-express@10.4.20': + resolution: {integrity: sha512-rh97mX3rimyf4xLMLHuTOBKe6UD8LOJ14VlJ1F/PTd6C6ZK9Ak6EHuJvdaGcSFQhd3ZMBh3I6CuujKGW9pNdIg==} peerDependencies: '@nestjs/common': ^10.0.0 '@nestjs/core': ^10.0.0 - '@nestjs/testing@11.1.0': - resolution: {integrity: sha512-gQ+NGshkHbNrDNXMVaPiwduqZ8YHpXrnsQqhSsnyNYOcDNPdBbB+0FDq7XiiklluXqjdLAN8i+bS7MbGlZIhKw==} + '@nestjs/testing@11.1.6': + resolution: {integrity: sha512-srYzzDNxGvVCe1j0SpTS9/ix75PKt6Sn6iMaH1rpJ6nj2g8vwNrhK0CoJJXvpCYgrnI+2WES2pprYnq8rAMYHA==} peerDependencies: '@nestjs/common': ^11.0.0 '@nestjs/core': ^11.0.0 @@ -3149,13 +3104,13 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} - '@npmcli/agent@2.2.2': - resolution: {integrity: sha512-OrcNPXdpSl9UX7qPVRWbmWMCSXrcDa2M9DvrbOTj7ao1S4PlqVFYv9/yLKMkrJKZ/V5A/kDBC690or307i26Og==} - engines: {node: ^16.14.0 || >=18.0.0} + '@npmcli/agent@3.0.0': + resolution: {integrity: sha512-S79NdEgDQd/NGCay6TCoVzXSj74skRZIKJcpJjC5lOq34SZzyI6MqtiiWoiVWoVrTcGjNeC4ipbh1VIHlpfF5Q==} + engines: {node: ^18.17.0 || >=20.5.0} - '@npmcli/fs@3.1.1': - resolution: {integrity: sha512-q9CRWjpHCMIh5sVyefoD1cA7PkvILqCZsnSOEUUivORLjxCO/Irmue2DprETiNgEqktDBZaM1Bi+jrarx1XdCg==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + '@npmcli/fs@4.0.0': + resolution: {integrity: sha512-/xGlezI6xfGO9NwuJlnwz/K14qD1kCSAGtacBHnGzeAIuJGazcp45KP5NuyARXoKb7cwulAGWVsbeSxdG/cb0Q==} + engines: {node: ^18.17.0 || >=20.5.0} '@nuxt/opencollective@0.4.1': resolution: {integrity: sha512-GXD3wy50qYbxCJ652bDrDzgMr3NFEkIS374+IgFQKkCvk9yiYcLvX2XDYr7UyQxf4wK0e+yqDYRubZ0DtOxnmQ==} @@ -3174,17 +3129,13 @@ packages: '@open-draft/until@2.1.0': resolution: {integrity: sha512-U69T3ItWHvLwGg5eJ0n3I62nWuE6ilHlmz7zM0npLBRvPRd7e6NYmg54vvRtP5mZG7kZqZCFVdsTWo7BPtBujg==} - '@openmeteo/sdk@1.20.1': - resolution: {integrity: sha512-o5tw3+N617Ms8nDm649PWwWt6PDz8NHWBLjOOFB8bx/EJpvsvKEeHMMoapxQ71bjHzQM+4h39eCe6/nM+nBuwg==} + '@openmeteo/sdk@1.18.6': + resolution: {integrity: sha512-oeRClpD1V4u+iNVtjUQFjYncc2ZCTA7OXk+yVIVdf3SHDfWk3IuXpJPCkXTOUaahbcBiER0acJndx9oRHY6u2A==} engines: {node: '>=12.0'} - '@opentelemetry/api-logs@0.53.0': - resolution: {integrity: sha512-8HArjKx+RaAI8uEIgcORbZIPklyh1YLjPSBus8hjRmvLi6DeFzgOcdZ7KwPabKj8mXF8dX0hyfAyGfycz0DbFw==} - engines: {node: '>=14'} - - '@opentelemetry/api-logs@0.57.1': - resolution: {integrity: sha512-I4PHczeujhQAQv6ZBzqHYEUiggZL4IdSMixtVD3EYqbdrjujE7kRfI5QohjlPoJm8BvenoW5YaTMWRrbpot6tg==} - engines: {node: '>=14'} + '@opentelemetry/api-logs@0.204.0': + resolution: {integrity: sha512-DqxY8yoAaiBPivoJD4UtgrMS8gEmzZ5lnaxzPojzLVHBGqPxgWm4zcuvcUHZiqQ6kRX2Klel2r9y8cA2HAtqpw==} + engines: {node: '>=8.0.0'} '@opentelemetry/api-logs@0.57.2': resolution: {integrity: sha512-uIX52NnTM0iBh84MShlpouI7UKqkZ7MrUszTmaypHBu4r7NofznSnQRfJ+uUeDtQDj6w8eFGg5KBLDAwAPz1+A==} @@ -3194,171 +3145,159 @@ packages: resolution: {integrity: sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==} engines: {node: '>=8.0.0'} - '@opentelemetry/context-async-hooks@1.30.1': - resolution: {integrity: sha512-s5vvxXPVdjqS3kTLKMeBMvop9hbWkwzBpu+mUO2M7sZtlkyDJGwFe33wRKnbaYDo8ExRVBIIdwIGrqpxHuKttA==} - engines: {node: '>=14'} + '@opentelemetry/context-async-hooks@2.2.0': + resolution: {integrity: sha512-qRkLWiUEZNAmYapZ7KGS5C4OmBLcP/H2foXeOEaowYCR0wi89fHejrfYfbuLVCMLp/dWZXKvQusdbUEZjERfwQ==} + engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': '>=1.0.0 <1.10.0' - '@opentelemetry/core@1.30.1': - resolution: {integrity: sha512-OOCM2C/QIURhJMuKaekP3TRBxBKxG/TWWA0TL2J6nXUtDnuCtccy49LUJF8xPFXMX+0LMcxFpCo8M9cGY1W6rQ==} - engines: {node: '>=14'} + '@opentelemetry/core@2.1.0': + resolution: {integrity: sha512-RMEtHsxJs/GiHHxYT58IY57UXAQTuUnZVco6ymDEqTNlJKTimM4qPUPVe8InNFyBjhHBEAx4k3Q8LtNayBsbUQ==} + engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': '>=1.0.0 <1.10.0' - '@opentelemetry/instrumentation-amqplib@0.46.1': - resolution: {integrity: sha512-AyXVnlCf/xV3K/rNumzKxZqsULyITJH6OVLiW6730JPRqWA7Zc9bvYoVNpN6iOpTU8CasH34SU/ksVJmObFibQ==} - engines: {node: '>=14'} + '@opentelemetry/core@2.2.0': + resolution: {integrity: sha512-FuabnnUm8LflnieVxs6eP7Z383hgQU4W1e3KJS6aOG3RxWxcHyBxH8fDMHNgu/gFx/M2jvTOW/4/PHhLz6bjWw==} + engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: - '@opentelemetry/api': ^1.3.0 + '@opentelemetry/api': '>=1.0.0 <1.10.0' - '@opentelemetry/instrumentation-connect@0.43.0': - resolution: {integrity: sha512-Q57JGpH6T4dkYHo9tKXONgLtxzsh1ZEW5M9A/OwKrZFyEpLqWgjhcZ3hIuVvDlhb426iDF1f9FPToV/mi5rpeA==} - engines: {node: '>=14'} + '@opentelemetry/instrumentation-amqplib@0.51.0': + resolution: {integrity: sha512-XGmjYwjVRktD4agFnWBWQXo9SiYHKBxR6Ag3MLXwtLE4R99N3a08kGKM5SC1qOFKIELcQDGFEFT9ydXMH00Luw==} + engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/instrumentation-dataloader@0.16.0': - resolution: {integrity: sha512-88+qCHZC02up8PwKHk0UQKLLqGGURzS3hFQBZC7PnGwReuoKjHXS1o29H58S+QkXJpkTr2GACbx8j6mUoGjNPA==} - engines: {node: '>=14'} + '@opentelemetry/instrumentation-connect@0.48.0': + resolution: {integrity: sha512-OMjc3SFL4pC16PeK+tDhwP7MRvDPalYCGSvGqUhX5rASkI2H0RuxZHOWElYeXkV0WP+70Gw6JHWac/2Zqwmhdw==} + engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/instrumentation-express@0.47.0': - resolution: {integrity: sha512-XFWVx6k0XlU8lu6cBlCa29ONtVt6ADEjmxtyAyeF2+rifk8uBJbk1La0yIVfI0DoKURGbaEDTNelaXG9l/lNNQ==} - engines: {node: '>=14'} + '@opentelemetry/instrumentation-dataloader@0.22.0': + resolution: {integrity: sha512-bXnTcwtngQsI1CvodFkTemrrRSQjAjZxqHVc+CJZTDnidT0T6wt3jkKhnsjU/Kkkc0lacr6VdRpCu2CUWa0OKw==} + engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/instrumentation-fastify@0.44.1': - resolution: {integrity: sha512-RoVeMGKcNttNfXMSl6W4fsYoCAYP1vi6ZAWIGhBY+o7R9Y0afA7f9JJL0j8LHbyb0P0QhSYk+6O56OwI2k4iRQ==} - engines: {node: '>=14'} + '@opentelemetry/instrumentation-express@0.53.0': + resolution: {integrity: sha512-r/PBafQmFYRjuxLYEHJ3ze1iBnP2GDA1nXOSS6E02KnYNZAVjj6WcDA1MSthtdAUUK0XnotHvvWM8/qz7DMO5A==} + engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/instrumentation-fs@0.19.0': - resolution: {integrity: sha512-JGwmHhBkRT2G/BYNV1aGI+bBjJu4fJUD/5/Jat0EWZa2ftrLV3YE8z84Fiij/wK32oMZ88eS8DI4ecLGZhpqsQ==} - engines: {node: '>=14'} + '@opentelemetry/instrumentation-fs@0.24.0': + resolution: {integrity: sha512-HjIxJ6CBRD770KNVaTdMXIv29Sjz4C1kPCCK5x1Ujpc6SNnLGPqUVyJYZ3LUhhnHAqdbrl83ogVWjCgeT4Q0yw==} + engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/instrumentation-generic-pool@0.43.0': - resolution: {integrity: sha512-at8GceTtNxD1NfFKGAuwtqM41ot/TpcLh+YsGe4dhf7gvv1HW/ZWdq6nfRtS6UjIvZJOokViqLPJ3GVtZItAnQ==} - engines: {node: '>=14'} + '@opentelemetry/instrumentation-generic-pool@0.48.0': + resolution: {integrity: sha512-TLv/On8pufynNR+pUbpkyvuESVASZZKMlqCm4bBImTpXKTpqXaJJ3o/MUDeMlM91rpen+PEv2SeyOKcHCSlgag==} + engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/instrumentation-graphql@0.47.0': - resolution: {integrity: sha512-Cc8SMf+nLqp0fi8oAnooNEfwZWFnzMiBHCGmDFYqmgjPylyLmi83b+NiTns/rKGwlErpW0AGPt0sMpkbNlzn8w==} - engines: {node: '>=14'} + '@opentelemetry/instrumentation-graphql@0.52.0': + resolution: {integrity: sha512-3fEJ8jOOMwopvldY16KuzHbRhPk8wSsOTSF0v2psmOCGewh6ad+ZbkTx/xyUK9rUdUMWAxRVU0tFpj4Wx1vkPA==} + engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/instrumentation-hapi@0.45.1': - resolution: {integrity: sha512-VH6mU3YqAKTePPfUPwfq4/xr049774qWtfTuJqVHoVspCLiT3bW+fCQ1toZxt6cxRPYASoYaBsMA3CWo8B8rcw==} - engines: {node: '>=14'} + '@opentelemetry/instrumentation-hapi@0.51.0': + resolution: {integrity: sha512-qyf27DaFNL1Qhbo/da+04MSCw982B02FhuOS5/UF+PMhM61CcOiu7fPuXj8TvbqyReQuJFljXE6UirlvoT/62g==} + engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/instrumentation-http@0.57.1': - resolution: {integrity: sha512-ThLmzAQDs7b/tdKI3BV2+yawuF09jF111OFsovqT1Qj3D8vjwKBwhi/rDE5xethwn4tSXtZcJ9hBsVAlWFQZ7g==} - engines: {node: '>=14'} + '@opentelemetry/instrumentation-http@0.204.0': + resolution: {integrity: sha512-1afJYyGRA4OmHTv0FfNTrTAzoEjPQUYgd+8ih/lX0LlZBnGio/O80vxA0lN3knsJPS7FiDrsDrWq25K7oAzbkw==} + engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/instrumentation-ioredis@0.47.0': - resolution: {integrity: sha512-4HqP9IBC8e7pW9p90P3q4ox0XlbLGme65YTrA3UTLvqvo4Z6b0puqZQP203YFu8m9rE/luLfaG7/xrwwqMUpJw==} - engines: {node: '>=14'} + '@opentelemetry/instrumentation-ioredis@0.52.0': + resolution: {integrity: sha512-rUvlyZwI90HRQPYicxpDGhT8setMrlHKokCtBtZgYxQWRF5RBbG4q0pGtbZvd7kyseuHbFpA3I/5z7M8b/5ywg==} + engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/instrumentation-kafkajs@0.7.0': - resolution: {integrity: sha512-LB+3xiNzc034zHfCtgs4ITWhq6Xvdo8bsq7amR058jZlf2aXXDrN9SV4si4z2ya9QX4tz6r4eZJwDkXOp14/AQ==} - engines: {node: '>=14'} + '@opentelemetry/instrumentation-kafkajs@0.14.0': + resolution: {integrity: sha512-kbB5yXS47dTIdO/lfbbXlzhvHFturbux4EpP0+6H78Lk0Bn4QXiZQW7rmZY1xBCY16mNcCb8Yt0mhz85hTnSVA==} + engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/instrumentation-knex@0.44.0': - resolution: {integrity: sha512-SlT0+bLA0Lg3VthGje+bSZatlGHw/vwgQywx0R/5u9QC59FddTQSPJeWNw29M6f8ScORMeUOOTwihlQAn4GkJQ==} - engines: {node: '>=14'} + '@opentelemetry/instrumentation-knex@0.49.0': + resolution: {integrity: sha512-NKsRRT27fbIYL4Ix+BjjP8h4YveyKc+2gD6DMZbr5R5rUeDqfC8+DTfIt3c3ex3BIc5Vvek4rqHnN7q34ZetLQ==} + engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/instrumentation-koa@0.47.0': - resolution: {integrity: sha512-HFdvqf2+w8sWOuwtEXayGzdZ2vWpCKEQv5F7+2DSA74Te/Cv4rvb2E5So5/lh+ok4/RAIPuvCbCb/SHQFzMmbw==} - engines: {node: '>=14'} + '@opentelemetry/instrumentation-koa@0.52.0': + resolution: {integrity: sha512-JJSBYLDx/mNSy8Ibi/uQixu2rH0bZODJa8/cz04hEhRaiZQoeJ5UrOhO/mS87IdgVsHrnBOsZ6vDu09znupyuA==} + engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/instrumentation-lru-memoizer@0.44.0': - resolution: {integrity: sha512-Tn7emHAlvYDFik3vGU0mdwvWJDwtITtkJ+5eT2cUquct6nIs+H8M47sqMJkCpyPe5QIBJoTOHxmc6mj9lz6zDw==} - engines: {node: '>=14'} + '@opentelemetry/instrumentation-lru-memoizer@0.49.0': + resolution: {integrity: sha512-ctXu+O/1HSadAxtjoEg2w307Z5iPyLOMM8IRNwjaKrIpNAthYGSOanChbk1kqY6zU5CrpkPHGdAT6jk8dXiMqw==} + engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/instrumentation-mongodb@0.51.0': - resolution: {integrity: sha512-cMKASxCX4aFxesoj3WK8uoQ0YUrRvnfxaO72QWI2xLu5ZtgX/QvdGBlU3Ehdond5eb74c2s1cqRQUIptBnKz1g==} - engines: {node: '>=14'} + '@opentelemetry/instrumentation-mongodb@0.57.0': + resolution: {integrity: sha512-KD6Rg0KSHWDkik+qjIOWoksi1xqSpix8TSPfquIK1DTmd9OTFb5PHmMkzJe16TAPVEuElUW8gvgP59cacFcrMQ==} + engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/instrumentation-mongoose@0.46.0': - resolution: {integrity: sha512-mtVv6UeaaSaWTeZtLo4cx4P5/ING2obSqfWGItIFSunQBrYROfhuVe7wdIrFUs2RH1tn2YYpAJyMaRe/bnTTIQ==} - engines: {node: '>=14'} + '@opentelemetry/instrumentation-mongoose@0.51.0': + resolution: {integrity: sha512-gwWaAlhhV2By7XcbyU3DOLMvzsgeaymwP/jktDC+/uPkCmgB61zurwqOQdeiRq9KAf22Y2dtE5ZLXxytJRbEVA==} + engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/instrumentation-mysql2@0.45.0': - resolution: {integrity: sha512-qLslv/EPuLj0IXFvcE3b0EqhWI8LKmrgRPIa4gUd8DllbBpqJAvLNJSv3cC6vWwovpbSI3bagNO/3Q2SuXv2xA==} - engines: {node: '>=14'} + '@opentelemetry/instrumentation-mysql2@0.51.0': + resolution: {integrity: sha512-zT2Wg22Xn43RyfU3NOUmnFtb5zlDI0fKcijCj9AcK9zuLZ4ModgtLXOyBJSSfO+hsOCZSC1v/Fxwj+nZJFdzLQ==} + engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/instrumentation-mysql@0.45.0': - resolution: {integrity: sha512-tWWyymgwYcTwZ4t8/rLDfPYbOTF3oYB8SxnYMtIQ1zEf5uDm90Ku3i6U/vhaMyfHNlIHvDhvJh+qx5Nc4Z3Acg==} - engines: {node: '>=14'} + '@opentelemetry/instrumentation-mysql@0.50.0': + resolution: {integrity: sha512-duKAvMRI3vq6u9JwzIipY9zHfikN20bX05sL7GjDeLKr2qV0LQ4ADtKST7KStdGcQ+MTN5wghWbbVdLgNcB3rA==} + engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/instrumentation-nestjs-core@0.44.0': - resolution: {integrity: sha512-t16pQ7A4WYu1yyQJZhRKIfUNvl5PAaF2pEteLvgJb/BWdd1oNuU1rOYt4S825kMy+0q4ngiX281Ss9qiwHfxFQ==} - engines: {node: '>=14'} + '@opentelemetry/instrumentation-pg@0.57.0': + resolution: {integrity: sha512-dWLGE+r5lBgm2A8SaaSYDE3OKJ/kwwy5WLyGyzor8PLhUL9VnJRiY6qhp4njwhnljiLtzeffRtG2Mf/YyWLeTw==} + engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/instrumentation-pg@0.50.0': - resolution: {integrity: sha512-TtLxDdYZmBhFswm8UIsrDjh/HFBeDXd4BLmE8h2MxirNHewLJ0VS9UUddKKEverb5Sm2qFVjqRjcU+8Iw4FJ3w==} - engines: {node: '>=14'} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-redis-4@0.46.0': - resolution: {integrity: sha512-aTUWbzbFMFeRODn3720TZO0tsh/49T8H3h8vVnVKJ+yE36AeW38Uj/8zykQ/9nO8Vrtjr5yKuX3uMiG/W8FKNw==} - engines: {node: '>=14'} + '@opentelemetry/instrumentation-redis@0.53.0': + resolution: {integrity: sha512-WUHV8fr+8yo5RmzyU7D5BIE1zwiaNQcTyZPwtxlfr7px6NYYx7IIpSihJK7WA60npWynfxxK1T67RAVF0Gdfjg==} + engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/instrumentation-tedious@0.18.0': - resolution: {integrity: sha512-9zhjDpUDOtD+coeADnYEJQ0IeLVCj7w/hqzIutdp5NqS1VqTAanaEfsEcSypyvYv5DX3YOsTUoF+nr2wDXPETA==} - engines: {node: '>=14'} + '@opentelemetry/instrumentation-tedious@0.23.0': + resolution: {integrity: sha512-3TMTk/9VtlRonVTaU4tCzbg4YqW+Iq/l5VnN2e5whP6JgEg/PKfrGbqQ+CxQWNLfLaQYIUgEZqAn5gk/inh1uQ==} + engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/instrumentation-undici@0.10.0': - resolution: {integrity: sha512-vm+V255NGw9gaSsPD6CP0oGo8L55BffBc8KnxqsMuc6XiAD1L8SFNzsW0RHhxJFqy9CJaJh+YiJ5EHXuZ5rZBw==} - engines: {node: '>=14'} + '@opentelemetry/instrumentation-undici@0.15.0': + resolution: {integrity: sha512-sNFGA/iCDlVkNjzTzPRcudmI11vT/WAfAguRdZY9IspCw02N4WSC72zTuQhSMheh2a1gdeM9my1imnKRvEEvEg==} + engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.7.0 - '@opentelemetry/instrumentation@0.53.0': - resolution: {integrity: sha512-DMwg0hy4wzf7K73JJtl95m/e0boSoWhH07rfvHvYzQtBD3Bmv0Wc1x733vyZBqmFm8OjJD0/pfiUg1W3JjFX0A==} - engines: {node: '>=14'} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation@0.57.1': - resolution: {integrity: sha512-SgHEKXoVxOjc20ZYusPG3Fh+RLIZTSa4x8QtD3NfgAUDyqdFFS9W1F2ZVbZkqDCdyMcQG02Ok4duUGLHJXHgbA==} - engines: {node: '>=14'} + '@opentelemetry/instrumentation@0.204.0': + resolution: {integrity: sha512-vV5+WSxktzoMP8JoYWKeopChy6G3HKk4UQ2hESCRDUUTZqQ3+nM3u8noVG0LmNfRWwcFBnbZ71GKC7vaYYdJ1g==} + engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 @@ -3368,37 +3307,29 @@ packages: peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/redis-common@0.36.2': - resolution: {integrity: sha512-faYX1N0gpLhej/6nyp6bgRjzAKXn5GOEMYY7YhciSfCoITAktLUtQ36d24QEWNA1/WA1y6qQunCe0OhHRkVl9g==} - engines: {node: '>=14'} + '@opentelemetry/redis-common@0.38.2': + resolution: {integrity: sha512-1BCcU93iwSRZvDAgwUxC/DV4T/406SkMfxGqu5ojc3AvNI+I9GhV7v0J1HljsczuuhcnFLYqD5VmwVXfCGHzxA==} + engines: {node: ^18.19.0 || >=20.6.0} - '@opentelemetry/resources@1.30.1': - resolution: {integrity: sha512-5UxZqiAgLYGFjS4s9qm5mBVo433u+dSPUFWVWXmLAD4wB65oMCoXaJP1KJa9DIYYMeHu3z4BZcStG3LC593cWA==} - engines: {node: '>=14'} + '@opentelemetry/resources@2.2.0': + resolution: {integrity: sha512-1pNQf/JazQTMA0BiO5NINUzH0cbLbbl7mntLa4aJNmCCXSj0q03T5ZXXL0zw4G55TjdL9Tz32cznGClf+8zr5A==} + engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: - '@opentelemetry/api': '>=1.0.0 <1.10.0' + '@opentelemetry/api': '>=1.3.0 <1.10.0' - '@opentelemetry/sdk-trace-base@1.30.1': - resolution: {integrity: sha512-jVPgBbH1gCy2Lb7X0AVQ8XAfgg0pJ4nvl8/IiQA6nxOsPvS+0zMJaFSs2ltXe0J6C8dqjcnpyqINDJmU30+uOg==} - engines: {node: '>=14'} + '@opentelemetry/sdk-trace-base@2.2.0': + resolution: {integrity: sha512-xWQgL0Bmctsalg6PaXExmzdedSp3gyKV8mQBwK/j9VGdCDu2fmXIb2gAehBKbkXCpJ4HPkgv3QfoJWRT4dHWbw==} + engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: - '@opentelemetry/api': '>=1.0.0 <1.10.0' - - '@opentelemetry/semantic-conventions@1.27.0': - resolution: {integrity: sha512-sAay1RrB+ONOem0OZanAR1ZI/k7yDpnOQSQmTMuGImUQb2y8EbSaCJ94FQluM74xoU03vlb2d2U90hZluL6nQg==} - engines: {node: '>=14'} + '@opentelemetry/api': '>=1.3.0 <1.10.0' - '@opentelemetry/semantic-conventions@1.28.0': - resolution: {integrity: sha512-lp4qAiMTD4sNWW4DbKLBkfiMZ4jbAboJIGOQr5DvciMRI494OapieI9qiODpOt0XBr1LjIDy1xAGAnVs5supTA==} + '@opentelemetry/semantic-conventions@1.37.0': + resolution: {integrity: sha512-JD6DerIKdJGmRp4jQyX5FlrQjA4tjOw1cvfsPAZXfOOEErMUHjPcPSICS+6WnM0nB0efSFARh0KAZss+bvExOA==} engines: {node: '>=14'} - '@opentelemetry/semantic-conventions@1.34.0': - resolution: {integrity: sha512-aKcOkyrorBGlajjRdVoJWHTxfxO1vCNHLJVlSDaRHDIdjU+pX8IYQPvPDkYiujKLbRnWU+1TBwEt0QRgSm4SGA==} - engines: {node: '>=14'} - - '@opentelemetry/sql-common@0.40.1': - resolution: {integrity: sha512-nSDlnHSqzC3pXn/wZEZVLuAuJ1MYMXPBwtv2qAbCa3847SaHItdE7SzUq/Jtb0KZmh1zfAbNi3AAMjztTT4Ugg==} - engines: {node: '>=14'} + '@opentelemetry/sql-common@0.41.2': + resolution: {integrity: sha512-4mhWm3Z8z+i508zQJ7r6Xi7y4mmoJpdvH0fZPFRkWrdp5fq7hhZ2HhYokEOLkfqSMgPR4Z9EyB3DBkbKGOqZiQ==} + engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.1.0 @@ -3487,20 +3418,20 @@ packages: resolution: {integrity: sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==} engines: {node: '>= 10.0.0'} - '@peculiar/asn1-android@2.3.16': - resolution: {integrity: sha512-a1viIv3bIahXNssrOIkXZIlI2ePpZaNmR30d4aBL99mu2rO+mT9D6zBsp7H6eROWGtmwv0Ionp5olJurIo09dw==} + '@peculiar/asn1-android@2.3.10': + resolution: {integrity: sha512-z9Rx9cFJv7UUablZISe7uksNbFJCq13hO0yEAOoIpAymALTLlvUOSLnGiQS7okPaM5dP42oTLhezH6XDXRXjGw==} - '@peculiar/asn1-ecc@2.3.15': - resolution: {integrity: sha512-/HtR91dvgog7z/WhCVdxZJ/jitJuIu8iTqiyWVgRE9Ac5imt2sT/E4obqIVGKQw7PIy+X6i8lVBoT6wC73XUgA==} + '@peculiar/asn1-ecc@2.3.8': + resolution: {integrity: sha512-Ah/Q15y3A/CtxbPibiLM/LKcMbnLTdUdLHUgdpB5f60sSvGkXzxJCu5ezGTFHogZXWNX3KSmYqilCrfdmBc6pQ==} - '@peculiar/asn1-rsa@2.3.15': - resolution: {integrity: sha512-p6hsanvPhexRtYSOHihLvUUgrJ8y0FtOM97N5UEpC+VifFYyZa0iZ5cXjTkZoDwxJ/TTJ1IJo3HVTB2JJTpXvg==} + '@peculiar/asn1-rsa@2.3.8': + resolution: {integrity: sha512-ES/RVEHu8VMYXgrg3gjb1m/XG0KJWnV4qyZZ7mAg7rrF3VTmRbLxO8mk+uy0Hme7geSMebp+Wvi2U6RLLEs12Q==} - '@peculiar/asn1-schema@2.3.15': - resolution: {integrity: sha512-QPeD8UA8axQREpgR5UTAfu2mqQmm97oUqahDtNdBcfj3qAnoXzFdQW+aNf/tD2WVXF8Fhmftxoj0eMIT++gX2w==} + '@peculiar/asn1-schema@2.3.8': + resolution: {integrity: sha512-ULB1XqHKx1WBU/tTFIA+uARuRoBVZ4pNdOA878RDrRbBfBGcSzi5HBkdScC6ZbHn8z7L8gmKCgPC1LHRrP46tA==} - '@peculiar/asn1-x509@2.3.15': - resolution: {integrity: sha512-0dK5xqTqSLaxv1FHXIcd4Q/BZNuopg+u1l23hT9rOmQ1g4dNtw0g/RnEi+TboB0gOwGtrWn269v27cMgchFIIg==} + '@peculiar/asn1-x509@2.3.8': + resolution: {integrity: sha512-voKxGfDU1c6r9mKiN5ZUsZWh3Dy1BABvTM3cimf0tztNwyMJPhiXY94eRTgsMQe6ViLfT6EoXxkWVzcm3mFAFw==} '@peertube/http-signature@1.7.0': resolution: {integrity: sha512-aGQIwo6/sWtyyqhVK4e1MtxYz4N1X8CNt6SOtCc+Wnczs5S5ONaLHDDR8LYaGn0MgOwvGgXyuZ5sJIfd7iyoUw==} @@ -3514,8 +3445,10 @@ packages: resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} - '@prisma/instrumentation@5.22.0': - resolution: {integrity: sha512-LxccF392NN37ISGxIurUljZSh1YWnphO34V5a0+T7FVQG2u9bhAXRTJpgmQ3483woVhkraQZFF7cbRrpbw/F4Q==} + '@prisma/instrumentation@6.15.0': + resolution: {integrity: sha512-6TXaH6OmDkMOQvOxwLZ8XS51hU2v4A3vmE2pSijCIiGRJYyNeMcL6nMHQMyYdZRD8wl7LF3Wzc+AMPMV/9Oo7A==} + peerDependencies: + '@opentelemetry/api': ^1.8 '@protobufjs/aspromise@1.1.2': resolution: {integrity: sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==} @@ -3553,13 +3486,9 @@ packages: peerDependencies: ajv: 4.11.8 - 8 - '@readme/json-schema-ref-parser@1.2.0': - resolution: {integrity: sha512-Bt3QVovFSua4QmHa65EHUmh2xS0XJ3rgTEUPH998f4OW4VVJke3BuS16f+kM0ZLOGdvIrzrPRqwihuv5BAjtrA==} - deprecated: This package is no longer maintained. Please use `@apidevtools/json-schema-ref-parser` instead. - - '@readme/openapi-parser@2.7.0': - resolution: {integrity: sha512-P8WSr8WTOxilnT89tcCRKWYsG/II4sAwt1a/DIWub8xTtkrG9cCBBy/IUcvc5X8oGWN82MwcTA3uEkDrXZd/7A==} - engines: {node: '>=18'} + '@readme/openapi-parser@5.0.2': + resolution: {integrity: sha512-EDecF1OPz28PFHDrFXS2pu+VeBE1Skta0AgdgvODr3uWBU1sFDffo+zRHDQWswIpQVdfhveSyPg/gXZR37QCPQ==} + engines: {node: '>=20'} peerDependencies: openapi-types: '>=7' @@ -3567,6 +3496,19 @@ packages: resolution: {integrity: sha512-9FC/6ho8uFa8fV50+FPy/ngWN53jaUu4GRXlAjcxIRrzhltJnpKkBG2Tp0IDraFJeWrOpk84RJ9EMEEYzaI1Bw==} engines: {node: '>=18'} + '@redocly/ajv@8.11.3': + resolution: {integrity: sha512-4P3iZse91TkBiY+Dx5DUgxQ9GXkVJf++cmI0MOyLDxV9b5MUBI4II6ES8zA5JCbO72nKAJxWrw4PUPW+YP3ZDQ==} + + '@redocly/config@0.22.2': + resolution: {integrity: sha512-roRDai8/zr2S9YfmzUfNhKjOF0NdcOIqF7bhf4MVC5UxpjIysDjyudvlAiVbpPHp3eDRWbdzUgtkK1a7YiDNyQ==} + + '@redocly/openapi-core@1.34.5': + resolution: {integrity: sha512-0EbE8LRbkogtcCXU7liAyC00n9uNG9hJ+eMyHFdUsy9lB/WGqnEBgwjA9q2cyzAVcdTkQqTBBU1XePNnN3OijA==} + engines: {node: '>=18.17.0', npm: '>=9.5.0'} + + '@rolldown/pluginutils@1.0.0-beta.29': + resolution: {integrity: sha512-NIJgOsMjbxAXvoGq/X0gD7VPMQ8j9g0BiDaNjVNVjvl+iKXxL3Jre0v31RmBYeLEmkbj2s02v8vFTbUXi5XS2Q==} + '@rollup/plugin-json@6.1.0': resolution: {integrity: sha512-EGI2te5ENk1coGeADSIwZ7G2Q8CJS2sF120T7jLw4xFw9n7wIOXHo+kIYRAoVpJAN+kmqZSoO3Fp4JtoNF4ReA==} engines: {node: '>=14.0.0'} @@ -3585,8 +3527,8 @@ packages: rollup: optional: true - '@rollup/pluginutils@5.1.4': - resolution: {integrity: sha512-USm05zrsFxYLPdWWq+K3STlWiT/3ELn3RcV5hJMghpeAIhxfsUIg6mt12CBJBInWMV4VneoV7SfGv8xIwo2qNQ==} + '@rollup/pluginutils@5.3.0': + resolution: {integrity: sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==} engines: {node: '>=14.0.0'} peerDependencies: rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 @@ -3594,184 +3536,213 @@ packages: rollup: optional: true - '@rollup/rollup-android-arm-eabi@4.40.0': - resolution: {integrity: sha512-+Fbls/diZ0RDerhE8kyC6hjADCXA1K4yVNlH0EYfd2XjyH0UGgzaQ8MlT0pCXAThfxv3QUAczHaL+qSv1E4/Cg==} + '@rollup/rollup-android-arm-eabi@4.52.4': + resolution: {integrity: sha512-BTm2qKNnWIQ5auf4deoetINJm2JzvihvGb9R6K/ETwKLql/Bb3Eg2H1FBp1gUb4YGbydMA3jcmQTR73q7J+GAA==} cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.40.0': - resolution: {integrity: sha512-PPA6aEEsTPRz+/4xxAmaoWDqh67N7wFbgFUJGMnanCFs0TV99M0M8QhhaSCks+n6EbQoFvLQgYOGXxlMGQe/6w==} + '@rollup/rollup-android-arm64@4.52.4': + resolution: {integrity: sha512-P9LDQiC5vpgGFgz7GSM6dKPCiqR3XYN1WwJKA4/BUVDjHpYsf3iBEmVz62uyq20NGYbiGPR5cNHI7T1HqxNs2w==} cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.40.0': - resolution: {integrity: sha512-GwYOcOakYHdfnjjKwqpTGgn5a6cUX7+Ra2HeNj/GdXvO2VJOOXCiYYlRFU4CubFM67EhbmzLOmACKEfvp3J1kQ==} + '@rollup/rollup-darwin-arm64@4.52.4': + resolution: {integrity: sha512-QRWSW+bVccAvZF6cbNZBJwAehmvG9NwfWHwMy4GbWi/BQIA/laTIktebT2ipVjNncqE6GLPxOok5hsECgAxGZg==} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.40.0': - resolution: {integrity: sha512-CoLEGJ+2eheqD9KBSxmma6ld01czS52Iw0e2qMZNpPDlf7Z9mj8xmMemxEucinev4LgHalDPczMyxzbq+Q+EtA==} + '@rollup/rollup-darwin-x64@4.52.4': + resolution: {integrity: sha512-hZgP05pResAkRJxL1b+7yxCnXPGsXU0fG9Yfd6dUaoGk+FhdPKCJ5L1Sumyxn8kvw8Qi5PvQ8ulenUbRjzeCTw==} cpu: [x64] os: [darwin] - '@rollup/rollup-freebsd-arm64@4.40.0': - resolution: {integrity: sha512-r7yGiS4HN/kibvESzmrOB/PxKMhPTlz+FcGvoUIKYoTyGd5toHp48g1uZy1o1xQvybwwpqpe010JrcGG2s5nkg==} + '@rollup/rollup-freebsd-arm64@4.52.4': + resolution: {integrity: sha512-xmc30VshuBNUd58Xk4TKAEcRZHaXlV+tCxIXELiE9sQuK3kG8ZFgSPi57UBJt8/ogfhAF5Oz4ZSUBN77weM+mQ==} cpu: [arm64] os: [freebsd] - '@rollup/rollup-freebsd-x64@4.40.0': - resolution: {integrity: sha512-mVDxzlf0oLzV3oZOr0SMJ0lSDd3xC4CmnWJ8Val8isp9jRGl5Dq//LLDSPFrasS7pSm6m5xAcKaw3sHXhBjoRw==} + '@rollup/rollup-freebsd-x64@4.52.4': + resolution: {integrity: sha512-WdSLpZFjOEqNZGmHflxyifolwAiZmDQzuOzIq9L27ButpCVpD7KzTRtEG1I0wMPFyiyUdOO+4t8GvrnBLQSwpw==} cpu: [x64] os: [freebsd] - '@rollup/rollup-linux-arm-gnueabihf@4.40.0': - resolution: {integrity: sha512-y/qUMOpJxBMy8xCXD++jeu8t7kzjlOCkoxxajL58G62PJGBZVl/Gwpm7JK9+YvlB701rcQTzjUZ1JgUoPTnoQA==} + '@rollup/rollup-linux-arm-gnueabihf@4.52.4': + resolution: {integrity: sha512-xRiOu9Of1FZ4SxVbB0iEDXc4ddIcjCv2aj03dmW8UrZIW7aIQ9jVJdLBIhxBI+MaTnGAKyvMwPwQnoOEvP7FgQ==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm-musleabihf@4.40.0': - resolution: {integrity: sha512-GoCsPibtVdJFPv/BOIvBKO/XmwZLwaNWdyD8TKlXuqp0veo2sHE+A/vpMQ5iSArRUz/uaoj4h5S6Pn0+PdhRjg==} + '@rollup/rollup-linux-arm-musleabihf@4.52.4': + resolution: {integrity: sha512-FbhM2p9TJAmEIEhIgzR4soUcsW49e9veAQCziwbR+XWB2zqJ12b4i/+hel9yLiD8pLncDH4fKIPIbt5238341Q==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm64-gnu@4.40.0': - resolution: {integrity: sha512-L5ZLphTjjAD9leJzSLI7rr8fNqJMlGDKlazW2tX4IUF9P7R5TMQPElpH82Q7eNIDQnQlAyiNVfRPfP2vM5Avvg==} + '@rollup/rollup-linux-arm64-gnu@4.52.4': + resolution: {integrity: sha512-4n4gVwhPHR9q/g8lKCyz0yuaD0MvDf7dV4f9tHt0C73Mp8h38UCtSCSE6R9iBlTbXlmA8CjpsZoujhszefqueg==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-arm64-musl@4.40.0': - resolution: {integrity: sha512-ATZvCRGCDtv1Y4gpDIXsS+wfFeFuLwVxyUBSLawjgXK2tRE6fnsQEkE4csQQYWlBlsFztRzCnBvWVfcae/1qxQ==} + '@rollup/rollup-linux-arm64-musl@4.52.4': + resolution: {integrity: sha512-u0n17nGA0nvi/11gcZKsjkLj1QIpAuPFQbR48Subo7SmZJnGxDpspyw2kbpuoQnyK+9pwf3pAoEXerJs/8Mi9g==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-loongarch64-gnu@4.40.0': - resolution: {integrity: sha512-wG9e2XtIhd++QugU5MD9i7OnpaVb08ji3P1y/hNbxrQ3sYEelKJOq1UJ5dXczeo6Hj2rfDEL5GdtkMSVLa/AOg==} + '@rollup/rollup-linux-loong64-gnu@4.52.4': + resolution: {integrity: sha512-0G2c2lpYtbTuXo8KEJkDkClE/+/2AFPdPAbmaHoE870foRFs4pBrDehilMcrSScrN/fB/1HTaWO4bqw+ewBzMQ==} cpu: [loong64] os: [linux] - '@rollup/rollup-linux-powerpc64le-gnu@4.40.0': - resolution: {integrity: sha512-vgXfWmj0f3jAUvC7TZSU/m/cOE558ILWDzS7jBhiCAFpY2WEBn5jqgbqvmzlMjtp8KlLcBlXVD2mkTSEQE6Ixw==} + '@rollup/rollup-linux-ppc64-gnu@4.52.4': + resolution: {integrity: sha512-teSACug1GyZHmPDv14VNbvZFX779UqWTsd7KtTM9JIZRDI5NUwYSIS30kzI8m06gOPB//jtpqlhmraQ68b5X2g==} cpu: [ppc64] os: [linux] - '@rollup/rollup-linux-riscv64-gnu@4.40.0': - resolution: {integrity: sha512-uJkYTugqtPZBS3Z136arevt/FsKTF/J9dEMTX/cwR7lsAW4bShzI2R0pJVw+hcBTWF4dxVckYh72Hk3/hWNKvA==} + '@rollup/rollup-linux-riscv64-gnu@4.52.4': + resolution: {integrity: sha512-/MOEW3aHjjs1p4Pw1Xk4+3egRevx8Ji9N6HUIA1Ifh8Q+cg9dremvFCUbOX2Zebz80BwJIgCBUemjqhU5XI5Eg==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-riscv64-musl@4.40.0': - resolution: {integrity: sha512-rKmSj6EXQRnhSkE22+WvrqOqRtk733x3p5sWpZilhmjnkHkpeCgWsFFo0dGnUGeA+OZjRl3+VYq+HyCOEuwcxQ==} + '@rollup/rollup-linux-riscv64-musl@4.52.4': + resolution: {integrity: sha512-1HHmsRyh845QDpEWzOFtMCph5Ts+9+yllCrREuBR/vg2RogAQGGBRC8lDPrPOMnrdOJ+mt1WLMOC2Kao/UwcvA==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-s390x-gnu@4.40.0': - resolution: {integrity: sha512-SpnYlAfKPOoVsQqmTFJ0usx0z84bzGOS9anAC0AZ3rdSo3snecihbhFTlJZ8XMwzqAcodjFU4+/SM311dqE5Sw==} + '@rollup/rollup-linux-s390x-gnu@4.52.4': + resolution: {integrity: sha512-seoeZp4L/6D1MUyjWkOMRU6/iLmCU2EjbMTyAG4oIOs1/I82Y5lTeaxW0KBfkUdHAWN7j25bpkt0rjnOgAcQcA==} cpu: [s390x] os: [linux] - '@rollup/rollup-linux-x64-gnu@4.40.0': - resolution: {integrity: sha512-RcDGMtqF9EFN8i2RYN2W+64CdHruJ5rPqrlYw+cgM3uOVPSsnAQps7cpjXe9be/yDp8UC7VLoCoKC8J3Kn2FkQ==} + '@rollup/rollup-linux-x64-gnu@4.52.4': + resolution: {integrity: sha512-Wi6AXf0k0L7E2gteNsNHUs7UMwCIhsCTs6+tqQ5GPwVRWMaflqGec4Sd8n6+FNFDw9vGcReqk2KzBDhCa1DLYg==} cpu: [x64] os: [linux] - '@rollup/rollup-linux-x64-musl@4.40.0': - resolution: {integrity: sha512-HZvjpiUmSNx5zFgwtQAV1GaGazT2RWvqeDi0hV+AtC8unqqDSsaFjPxfsO6qPtKRRg25SisACWnJ37Yio8ttaw==} + '@rollup/rollup-linux-x64-musl@4.52.4': + resolution: {integrity: sha512-dtBZYjDmCQ9hW+WgEkaffvRRCKm767wWhxsFW3Lw86VXz/uJRuD438/XvbZT//B96Vs8oTA8Q4A0AfHbrxP9zw==} cpu: [x64] os: [linux] - '@rollup/rollup-win32-arm64-msvc@4.40.0': - resolution: {integrity: sha512-UtZQQI5k/b8d7d3i9AZmA/t+Q4tk3hOC0tMOMSq2GlMYOfxbesxG4mJSeDp0EHs30N9bsfwUvs3zF4v/RzOeTQ==} + '@rollup/rollup-openharmony-arm64@4.52.4': + resolution: {integrity: sha512-1ox+GqgRWqaB1RnyZXL8PD6E5f7YyRUJYnCqKpNzxzP0TkaUh112NDrR9Tt+C8rJ4x5G9Mk8PQR3o7Ku2RKqKA==} + cpu: [arm64] + os: [openharmony] + + '@rollup/rollup-win32-arm64-msvc@4.52.4': + resolution: {integrity: sha512-8GKr640PdFNXwzIE0IrkMWUNUomILLkfeHjXBi/nUvFlpZP+FA8BKGKpacjW6OUUHaNI6sUURxR2U2g78FOHWQ==} cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.40.0': - resolution: {integrity: sha512-+m03kvI2f5syIqHXCZLPVYplP8pQch9JHyXKZ3AGMKlg8dCyr2PKHjwRLiW53LTrN/Nc3EqHOKxUxzoSPdKddA==} + '@rollup/rollup-win32-ia32-msvc@4.52.4': + resolution: {integrity: sha512-AIy/jdJ7WtJ/F6EcfOb2GjR9UweO0n43jNObQMb6oGxkYTfLcnN7vYYpG+CN3lLxrQkzWnMOoNSHTW54pgbVxw==} cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.40.0': - resolution: {integrity: sha512-lpPE1cLfP5oPzVjKMx10pgBmKELQnFJXHgvtHCtuJWOv8MxqdEIMNtgHgBFf7Ea2/7EuVwa9fodWUfXAlXZLZQ==} + '@rollup/rollup-win32-x64-gnu@4.52.4': + resolution: {integrity: sha512-UF9KfsH9yEam0UjTwAgdK0anlQ7c8/pWPU2yVjyWcF1I1thABt6WXE47cI71pGiZ8wGvxohBoLnxM04L/wj8mQ==} + cpu: [x64] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.52.4': + resolution: {integrity: sha512-bf9PtUa0u8IXDVxzRToFQKsNCRz9qLYfR/MpECxl4mRoWYjAeFjgxj1XdZr2M/GNVpT05p+LgQOHopYDlUu6/w==} cpu: [x64] os: [win32] '@rtsao/scc@1.1.0': resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==} - '@rushstack/node-core-library@5.13.0': - resolution: {integrity: sha512-IGVhy+JgUacAdCGXKUrRhwHMTzqhWwZUI+qEPcdzsb80heOw0QPbhhoVsoiMF7Klp8eYsp7hzpScMXmOa3Uhfg==} + '@rushstack/node-core-library@5.17.0': + resolution: {integrity: sha512-24vt1GbHN6kyIglRMTVpyEiNRRRJK8uZHc1XoGAhmnTDKnrWet8OmOpImMswJIe6gM78eV8cMg1HXwuUHkSSgg==} + peerDependencies: + '@types/node': '*' + peerDependenciesMeta: + '@types/node': + optional: true + + '@rushstack/problem-matcher@0.1.1': + resolution: {integrity: sha512-Fm5XtS7+G8HLcJHCWpES5VmeMyjAKaWeyZU5qPzZC+22mPlJzAsOxymHiWIfuirtPckX3aptWws+K2d0BzniJA==} peerDependencies: '@types/node': '*' peerDependenciesMeta: '@types/node': optional: true - '@rushstack/rig-package@0.5.3': - resolution: {integrity: sha512-olzSSjYrvCNxUFZowevC3uz8gvKr3WTpHQ7BkpjtRpA3wK+T0ybep/SRUMfr195gBzJm5gaXw0ZMgjIyHqJUow==} + '@rushstack/rig-package@0.6.0': + resolution: {integrity: sha512-ZQmfzsLE2+Y91GF15c65L/slMRVhF6Hycq04D4TwtdGaUAbIXXg9c5pKA5KFU7M4QMaihoobp9JJYpYcaY3zOw==} - '@rushstack/terminal@0.15.2': - resolution: {integrity: sha512-7Hmc0ysK5077R/IkLS9hYu0QuNafm+TbZbtYVzCMbeOdMjaRboLKrhryjwZSRJGJzu+TV1ON7qZHeqf58XfLpA==} + '@rushstack/terminal@0.19.1': + resolution: {integrity: sha512-jsBuSad67IDVMO2yp0hDfs0OdE4z3mDIjIL2pclDT3aEJboeZXE85e1HjuD0F6JoW3XgHvDwoX+WOV+AVTDQeA==} peerDependencies: '@types/node': '*' peerDependenciesMeta: '@types/node': optional: true - '@rushstack/ts-command-line@5.0.0': - resolution: {integrity: sha512-SW6nqZVxH26Rxz25+lJQRlnXI/YCrNH7NfDEWPPm9i0rwkSE6Rgtmzw96cuZgQjacOh0sw77d6V4SvgarAfr8g==} + '@rushstack/ts-command-line@5.1.1': + resolution: {integrity: sha512-HPzFsUcr+wZ3oQI08Ec/E6cuiAVHKzrXZGHhwiwIGygAFiqN5QzX+ff30n70NU2WyE26CykgMwBZZSSyHCJrzA==} '@sec-ant/readable-stream@0.4.1': resolution: {integrity: sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==} - '@sentry-internal/browser-utils@9.14.0': - resolution: {integrity: sha512-pDk9XUu9zf7lcT9QX0nTObPNp/y0xQyy1Dj+5/8TSB3vAfe0LQcooKGl/D1h7EoIXVHUozZk5JC/dH+gz6BXRg==} + '@sentry-internal/browser-utils@10.20.0': + resolution: {integrity: sha512-9+NybrYs+dEM2iW5uRAYEhKkNK0XhDea5jovtDUXEvdSCMJFcdR88uztkftnCur45/hpvbgSULsGPUdHPb5ITw==} engines: {node: '>=18'} - '@sentry-internal/feedback@9.14.0': - resolution: {integrity: sha512-D+PiEUWbDT0vqmaTiOs6OzXwVRVFgf7BCkFs48qsN9sAPwUgT+5zh2oo/rU2r0NrmMcvJVtSY+ezwPMk8BgGsg==} + '@sentry-internal/feedback@10.20.0': + resolution: {integrity: sha512-R/eGLKl7WDccLKBorEbyTsy5b99w/k4v80SntE8HL2rsO7DCDXma8TGmtHd+iZnw8dUci+EVrw7LbeGSgf3QzA==} engines: {node: '>=18'} - '@sentry-internal/replay-canvas@9.14.0': - resolution: {integrity: sha512-GhCSqc0oNzRiLhQsi9LCXgUmIwdHdvzVIsX4fihoFYWfgWSSj5YLqeEkb3CMM8htM6vheSFzIbPLlRS8fjCrPQ==} + '@sentry-internal/node-cpu-profiler@2.2.0': + resolution: {integrity: sha512-oLHVYurqZfADPh5hvmQYS5qx8t0UZzT2u6+/68VXsFruQEOnYJTODKgU3BVLmemRs3WE6kCJjPeFdHVYOQGSzQ==} engines: {node: '>=18'} - '@sentry-internal/replay@9.14.0': - resolution: {integrity: sha512-wgt397/PtpfVQ9t779a0L+hGH3JN9doXv3+9Wj98MLWwhymvJBjpjCFUBLScO5iP6imewTbRqQHbq7XS7I+x1A==} + '@sentry-internal/replay-canvas@10.20.0': + resolution: {integrity: sha512-8DBawFi4F4e2Cu2ToiitCnYsK8idrDOv66Vq+N6c8e3qFitTTuoPQwOihb2+HY4CB06ABPW3WvfZntJJmsf91w==} engines: {node: '>=18'} - '@sentry/browser@9.14.0': - resolution: {integrity: sha512-acxFbFEei3hzKr/IW3OmkzHlwohRaRBG0872nIhLYV2f/BgZmR6eV5zrUoELMmt2cgoLmDYyfp1734OoplfDbw==} + '@sentry-internal/replay@10.20.0': + resolution: {integrity: sha512-+XPYp0CuJnf+c36/c+hHrY6wAPHCdnqllZeyU7+9LAiKsdhN8Oo4eF1v5zd097qDZBg1NrKhU44ScJIzz+vygw==} engines: {node: '>=18'} - '@sentry/core@8.55.0': - resolution: {integrity: sha512-6g7jpbefjHYs821Z+EBJ8r4Z7LT5h80YSWRJaylGS4nW5W5Z2KXzpdnyFarv37O7QjauzVC2E+PABmpkw5/JGA==} - engines: {node: '>=14.18'} + '@sentry/browser@10.20.0': + resolution: {integrity: sha512-zcf8HwFiRbzjZL9KbLev44eEOf+yl+3svQbs2BlR2KAYGaB10swV5abij0UTTGO7ClnqUZdcGpwiyyfPS6mjHg==} + engines: {node: '>=18'} - '@sentry/core@9.14.0': - resolution: {integrity: sha512-OLfucnP3LAL5bxVNWc2RVOHCX7fk9Er5bWPCS+O5cPjqNUUz0HQHhVh2Vhei5C0kYZZM4vy4BQit5T9LrlOaNA==} + '@sentry/core@10.20.0': + resolution: {integrity: sha512-S291KihnOIB8i7mVJIJBVHBMcCfIoY/KDJBHEfBoHY9M56g2An4FVhM9+/xR85+IoMkTySdXN08k9LEyQz4FpQ==} engines: {node: '>=18'} - '@sentry/node@8.55.0': - resolution: {integrity: sha512-h10LJLDTRAzYgay60Oy7moMookqqSZSviCWkkmHZyaDn+4WURnPp5SKhhfrzPRQcXKrweiOwDSHBgn1tweDssg==} - engines: {node: '>=14.18'} + '@sentry/node-core@10.20.0': + resolution: {integrity: sha512-9BelcS9722jionzuyUNff4Bqx6fMFlYlK+5gMZYxAzOdS1AYZeFiYNVV2GlCGXfDLSHTnE1rOGH6QOsUdgCdbg==} + engines: {node: '>=18'} + peerDependencies: + '@opentelemetry/api': ^1.9.0 + '@opentelemetry/context-async-hooks': ^1.30.1 || ^2.1.0 + '@opentelemetry/core': ^1.30.1 || ^2.1.0 + '@opentelemetry/instrumentation': '>=0.57.1 <1' + '@opentelemetry/resources': ^1.30.1 || ^2.1.0 + '@opentelemetry/sdk-trace-base': ^1.30.1 || ^2.1.0 + '@opentelemetry/semantic-conventions': ^1.37.0 + + '@sentry/node@10.20.0': + resolution: {integrity: sha512-Hv6cxQ2ilL54lF6+WwvvrvJEkt0fwUAAQZNwfAR0CfuP4Zg8FPQvxDeLhryd2Qr0nwPMNi3eYjypORjD3dcMLg==} + engines: {node: '>=18'} - '@sentry/opentelemetry@8.55.0': - resolution: {integrity: sha512-UvatdmSr3Xf+4PLBzJNLZ2JjG1yAPWGe/VrJlJAqyTJ2gKeTzgXJJw8rp4pbvNZO8NaTGEYhhO+scLUj0UtLAQ==} - engines: {node: '>=14.18'} + '@sentry/opentelemetry@10.20.0': + resolution: {integrity: sha512-91hr3RbMSUWgZb1BpW0gjlPsFaPtx0oNY2HYoC12T//1E0RMV183McBKbghBdT9swjhw112jeTFEERMJCaJyNw==} + engines: {node: '>=18'} peerDependencies: '@opentelemetry/api': ^1.9.0 - '@opentelemetry/context-async-hooks': ^1.30.1 - '@opentelemetry/core': ^1.30.1 - '@opentelemetry/instrumentation': ^0.57.1 - '@opentelemetry/sdk-trace-base': ^1.30.1 - '@opentelemetry/semantic-conventions': ^1.28.0 - - '@sentry/profiling-node@8.55.0': - resolution: {integrity: sha512-rYrlxbMlfQLHhkBUEC7bviuja1rojCb4+TtXi4NGnB4PppZeveGeuVTdJDWt3Ed6IBd20EEYoXv4+0aETbEnpw==} - engines: {node: '>=14.18'} + '@opentelemetry/context-async-hooks': ^1.30.1 || ^2.1.0 + '@opentelemetry/core': ^1.30.1 || ^2.1.0 + '@opentelemetry/sdk-trace-base': ^1.30.1 || ^2.1.0 + '@opentelemetry/semantic-conventions': ^1.37.0 + + '@sentry/profiling-node@10.20.0': + resolution: {integrity: sha512-Ov+GmBSGlv+OWEaMps31M952/hGKLaqjKeF3KiIAVzo6SnzAhbylaItcCiQyk5ZFyTrVWBKGp2VbaN0/79yZ3A==} + engines: {node: '>=18'} hasBin: true - '@sentry/vue@9.14.0': - resolution: {integrity: sha512-FJ6SBsDXCHpKlFpXcniFZ+5x9FUJ+WtxetU3rEelFrvYRV24lodRXY+IUbkxPiH0NvwhIo7B36DBQIhxeOWQew==} + '@sentry/vue@10.20.0': + resolution: {integrity: sha512-3mWc81mLs1CpXrihuTQNXwt0HfOIy7BAZMvtYgaTuIDvooYtBbsZ+7yGDkcwsWBtfAvE7/yP2h95M4HRIw5KyQ==} engines: {node: '>=18'} peerDependencies: pinia: 2.x || 3.x @@ -3780,29 +3751,29 @@ packages: pinia: optional: true - '@shikijs/core@3.3.0': - resolution: {integrity: sha512-CovkFL2WVaHk6PCrwv6ctlmD4SS1qtIfN8yEyDXDYWh4ONvomdM9MaFw20qHuqJOcb8/xrkqoWQRJ//X10phOQ==} + '@shikijs/core@3.13.0': + resolution: {integrity: sha512-3P8rGsg2Eh2qIHekwuQjzWhKI4jV97PhvYjYUzGqjvJfqdQPz+nMlfWahU24GZAyW1FxFI1sYjyhfh5CoLmIUA==} - '@shikijs/engine-javascript@3.3.0': - resolution: {integrity: sha512-XlhnFGv0glq7pfsoN0KyBCz9FJU678LZdQ2LqlIdAj6JKsg5xpYKay3DkazXWExp3DTJJK9rMOuGzU2911pg7Q==} + '@shikijs/engine-javascript@3.13.0': + resolution: {integrity: sha512-Ty7xv32XCp8u0eQt8rItpMs6rU9Ki6LJ1dQOW3V/56PKDcpvfHPnYFbsx5FFUP2Yim34m/UkazidamMNVR4vKg==} - '@shikijs/engine-oniguruma@3.3.0': - resolution: {integrity: sha512-l0vIw+GxeNU7uGnsu6B+Crpeqf+WTQ2Va71cHb5ZYWEVEPdfYwY5kXwYqRJwHrxz9WH+pjSpXQz+TJgAsrkA5A==} + '@shikijs/engine-oniguruma@3.13.0': + resolution: {integrity: sha512-O42rBGr4UDSlhT2ZFMxqM7QzIU+IcpoTMzb3W7AlziI1ZF7R8eS2M0yt5Ry35nnnTX/LTLXFPUjRFCIW+Operg==} - '@shikijs/langs@3.3.0': - resolution: {integrity: sha512-zt6Kf/7XpBQKSI9eqku+arLkAcDQ3NHJO6zFjiChI8w0Oz6Jjjay7pToottjQGjSDCFk++R85643WbyINcuL+g==} + '@shikijs/langs@3.13.0': + resolution: {integrity: sha512-672c3WAETDYHwrRP0yLy3W1QYB89Hbpj+pO4KhxK6FzIrDI2FoEXNiNCut6BQmEApYLfuYfpgOZaqbY+E9b8wQ==} - '@shikijs/themes@3.3.0': - resolution: {integrity: sha512-tXeCvLXBnqq34B0YZUEaAD1lD4lmN6TOHAhnHacj4Owh7Ptb/rf5XCDeROZt2rEOk5yuka3OOW2zLqClV7/SOg==} + '@shikijs/themes@3.13.0': + resolution: {integrity: sha512-Vxw1Nm1/Od8jyA7QuAenaV78BG2nSr3/gCGdBkLpfLscddCkzkL36Q5b67SrLLfvAJTOUzW39x4FHVCFriPVgg==} - '@shikijs/types@3.3.0': - resolution: {integrity: sha512-KPCGnHG6k06QG/2pnYGbFtFvpVJmC3uIpXrAiPrawETifujPBv0Se2oUxm5qYgjCvGJS9InKvjytOdN+bGuX+Q==} + '@shikijs/types@3.13.0': + resolution: {integrity: sha512-oM9P+NCFri/mmQ8LoFGVfVyemm5Hi27330zuOBp0annwJdKH1kOLndw3zCtAVDehPLg9fKqoEx3Ht/wNZxolfw==} '@shikijs/vscode-textmate@10.0.2': resolution: {integrity: sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==} - '@sideway/address@4.1.5': - resolution: {integrity: sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==} + '@sideway/address@4.1.4': + resolution: {integrity: sha512-7vwq+rOHVWjyXxVlR76Agnvhy8I9rpzjosTESvmhNeXOXdZZB15Fl+TI9x1SiHZH5Jv2wTGduSxFDIaq0m3DUw==} '@sideway/formula@3.0.1': resolution: {integrity: sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==} @@ -3820,18 +3791,27 @@ packages: '@sinclair/typebox@0.27.8': resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} - '@sindresorhus/is@5.6.0': - resolution: {integrity: sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g==} + '@sinclair/typebox@0.34.41': + resolution: {integrity: sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g==} + + '@sindresorhus/is@5.3.0': + resolution: {integrity: sha512-CX6t4SYQ37lzxicAqsBtxA3OseeoVrh9cSJ5PFYam0GksYlupRfy1A+Q4aYD3zvcfECLc0zO2u+ZnR2UYKvCrw==} engines: {node: '>=14.16'} - '@sindresorhus/is@7.0.2': - resolution: {integrity: sha512-d9xRovfKNz1SKieM0qJdO+PQonjnnIfSNWfHYnBSJ9hkjm0ZPw6HlxscDXYstp3z+7V2GOFHc+J0CYrYTjqCJw==} + '@sindresorhus/is@7.0.1': + resolution: {integrity: sha512-QWLl2P+rsCJeofkDNIT3WFmb6NrRud1SUYW8dIhXK/46XFV8Q/g7Bsvib0Askb0reRLe+WYPeeE+l5cH7SlkuQ==} engines: {node: '>=18'} '@sindresorhus/merge-streams@4.0.0': resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==} engines: {node: '>=18'} + '@sinonjs/commons@2.0.0': + resolution: {integrity: sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==} + + '@sinonjs/commons@3.0.0': + resolution: {integrity: sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==} + '@sinonjs/commons@3.0.1': resolution: {integrity: sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==} @@ -3847,8 +3827,8 @@ packages: '@sinonjs/fake-timers@13.0.5': resolution: {integrity: sha512-36/hTbH2uaWuGVERyC6da9YwGWnzUZXuPro/F2LfsdOsLnCojz/iSH8MxUt/FD2S5XBSVPhmArFUXcpCQ2Hkiw==} - '@sinonjs/samsam@8.0.2': - resolution: {integrity: sha512-v46t/fwnhejRSFTGqbpn9u+LQ9xJDse10gNnPgAcxgdoCDMXj/G2asWAC/8Qs+BAZDicX+MNZouXT1A7c83kVw==} + '@sinonjs/samsam@8.0.0': + resolution: {integrity: sha512-Bp8KUVlLp8ibJZrnvq2foVhP0IVX2CIprMJPK0vqGqgrDa0OHVKeZyBykqskkrdxV6yKBPmGasO8LVjAKR3Gew==} '@sinonjs/text-encoding@0.7.3': resolution: {integrity: sha512-DE427ROAphMQzU4ENbliGYrBSYPXF+TtLg9S8vzeA+OF4ZKzoDdzfL8sxuMUGS/lgRhM6j1URSk9ghf7Xo1tyA==} @@ -3857,355 +3837,359 @@ packages: resolution: {integrity: sha512-wRlta7GuLWpTqtFfGo+nZyOO1vEvewdNR1R4rTxpC8XU6vG/NDyrFBhwLZsqg1NUoR1noVaXJPC/7ZK47QCySw==} engines: {node: '>=14.0.0'} - '@smithy/abort-controller@4.0.4': - resolution: {integrity: sha512-gJnEjZMvigPDQWHrW3oPrFhQtkrgqBkyjj3pCIdF3A5M6vsZODG93KNlfJprv6bp4245bdT32fsHK4kkH3KYDA==} + '@smithy/abort-controller@4.2.0': + resolution: {integrity: sha512-PLUYa+SUKOEZtXFURBu/CNxlsxfaFGxSBPcStL13KpVeVWIfdezWyDqkz7iDLmwnxojXD0s5KzuB5HGHvt4Aeg==} engines: {node: '>=18.0.0'} - '@smithy/chunked-blob-reader-native@4.0.0': - resolution: {integrity: sha512-R9wM2yPmfEMsUmlMlIgSzOyICs0x9uu7UTHoccMyt7BWw8shcGM8HqB355+BZCPBcySvbTYMs62EgEQkNxz2ig==} + '@smithy/chunked-blob-reader-native@4.2.1': + resolution: {integrity: sha512-lX9Ay+6LisTfpLid2zZtIhSEjHMZoAR5hHCR4H7tBz/Zkfr5ea8RcQ7Tk4mi0P76p4cN+Btz16Ffno7YHpKXnQ==} engines: {node: '>=18.0.0'} - '@smithy/chunked-blob-reader@5.0.0': - resolution: {integrity: sha512-+sKqDBQqb036hh4NPaUiEkYFkTUGYzRsn3EuFhyfQfMy6oGHEUJDurLP9Ufb5dasr/XiAmPNMr6wa9afjQB+Gw==} + '@smithy/chunked-blob-reader@5.2.0': + resolution: {integrity: sha512-WmU0TnhEAJLWvfSeMxBNe5xtbselEO8+4wG0NtZeL8oR21WgH1xiO37El+/Y+H/Ie4SCwBy3MxYWmOYaGgZueA==} engines: {node: '>=18.0.0'} - '@smithy/config-resolver@4.1.4': - resolution: {integrity: sha512-prmU+rDddxHOH0oNcwemL+SwnzcG65sBF2yXRO7aeXIn/xTlq2pX7JLVbkBnVLowHLg4/OL4+jBmv9hVrVGS+w==} + '@smithy/config-resolver@4.3.0': + resolution: {integrity: sha512-9oH+n8AVNiLPK/iK/agOsoWfrKZ3FGP3502tkksd6SRsKMYiu7AFX0YXo6YBADdsAj7C+G/aLKdsafIJHxuCkQ==} engines: {node: '>=18.0.0'} - '@smithy/core@3.5.3': - resolution: {integrity: sha512-xa5byV9fEguZNofCclv6v9ra0FYh5FATQW/da7FQUVTic94DfrN/NvmKZjrMyzbpqfot9ZjBaO8U1UeTbmSLuA==} + '@smithy/core@3.15.0': + resolution: {integrity: sha512-VJWncXgt+ExNn0U2+Y7UywuATtRYaodGQKFo9mDyh70q+fJGedfrqi2XuKU1BhiLeXgg6RZrW7VEKfeqFhHAJA==} engines: {node: '>=18.0.0'} - '@smithy/credential-provider-imds@4.0.6': - resolution: {integrity: sha512-hKMWcANhUiNbCJouYkZ9V3+/Qf9pteR1dnwgdyzR09R4ODEYx8BbUysHwRSyex4rZ9zapddZhLFTnT4ZijR4pw==} + '@smithy/credential-provider-imds@4.2.0': + resolution: {integrity: sha512-SOhFVvFH4D5HJZytb0bLKxCrSnwcqPiNlrw+S4ZXjMnsC+o9JcUQzbZOEQcA8yv9wJFNhfsUiIUKiEnYL68Big==} engines: {node: '>=18.0.0'} - '@smithy/eventstream-codec@4.0.4': - resolution: {integrity: sha512-7XoWfZqWb/QoR/rAU4VSi0mWnO2vu9/ltS6JZ5ZSZv0eovLVfDfu0/AX4ub33RsJTOth3TiFWSHS5YdztvFnig==} + '@smithy/eventstream-codec@4.2.0': + resolution: {integrity: sha512-XE7CtKfyxYiNZ5vz7OvyTf1osrdbJfmUy+rbh+NLQmZumMGvY0mT0Cq1qKSfhrvLtRYzMsOBuRpi10dyI0EBPg==} engines: {node: '>=18.0.0'} - '@smithy/eventstream-serde-browser@4.0.4': - resolution: {integrity: sha512-3fb/9SYaYqbpy/z/H3yIi0bYKyAa89y6xPmIqwr2vQiUT2St+avRt8UKwsWt9fEdEasc5d/V+QjrviRaX1JRFA==} + '@smithy/eventstream-serde-browser@4.2.0': + resolution: {integrity: sha512-U53p7fcrk27k8irLhOwUu+UYnBqsXNLKl1XevOpsxK3y1Lndk8R7CSiZV6FN3fYFuTPuJy5pP6qa/bjDzEkRvA==} engines: {node: '>=18.0.0'} - '@smithy/eventstream-serde-config-resolver@4.1.2': - resolution: {integrity: sha512-JGtambizrWP50xHgbzZI04IWU7LdI0nh/wGbqH3sJesYToMi2j/DcoElqyOcqEIG/D4tNyxgRuaqBXWE3zOFhQ==} + '@smithy/eventstream-serde-config-resolver@4.3.0': + resolution: {integrity: sha512-uwx54t8W2Yo9Jr3nVF5cNnkAAnMCJ8Wrm+wDlQY6rY/IrEgZS3OqagtCu/9ceIcZFQ1zVW/zbN9dxb5esuojfA==} engines: {node: '>=18.0.0'} - '@smithy/eventstream-serde-node@4.0.4': - resolution: {integrity: sha512-RD6UwNZ5zISpOWPuhVgRz60GkSIp0dy1fuZmj4RYmqLVRtejFqQ16WmfYDdoSoAjlp1LX+FnZo+/hkdmyyGZ1w==} + '@smithy/eventstream-serde-node@4.2.0': + resolution: {integrity: sha512-yjM2L6QGmWgJjVu/IgYd6hMzwm/tf4VFX0lm8/SvGbGBwc+aFl3hOzvO/e9IJ2XI+22Tx1Zg3vRpFRs04SWFcg==} engines: {node: '>=18.0.0'} - '@smithy/eventstream-serde-universal@4.0.4': - resolution: {integrity: sha512-UeJpOmLGhq1SLox79QWw/0n2PFX+oPRE1ZyRMxPIaFEfCqWaqpB7BU9C8kpPOGEhLF7AwEqfFbtwNxGy4ReENA==} + '@smithy/eventstream-serde-universal@4.2.0': + resolution: {integrity: sha512-C3jxz6GeRzNyGKhU7oV656ZbuHY93mrfkT12rmjDdZch142ykjn8do+VOkeRNjSGKw01p4g+hdalPYPhmMwk1g==} engines: {node: '>=18.0.0'} - '@smithy/fetch-http-handler@5.0.4': - resolution: {integrity: sha512-AMtBR5pHppYMVD7z7G+OlHHAcgAN7v0kVKEpHuTO4Gb199Gowh0taYi9oDStFeUhetkeP55JLSVlTW1n9rFtUw==} + '@smithy/fetch-http-handler@5.3.1': + resolution: {integrity: sha512-3AvYYbB+Dv5EPLqnJIAgYw/9+WzeBiUYS8B+rU0pHq5NMQMvrZmevUROS4V2GAt0jEOn9viBzPLrZE+riTNd5Q==} engines: {node: '>=18.0.0'} - '@smithy/hash-blob-browser@4.0.4': - resolution: {integrity: sha512-WszRiACJiQV3QG6XMV44i5YWlkrlsM5Yxgz4jvsksuu7LDXA6wAtypfPajtNTadzpJy3KyJPoWehYpmZGKUFIQ==} + '@smithy/hash-blob-browser@4.2.1': + resolution: {integrity: sha512-Os9cg1fTXMwuqbvjemELlf+HB5oEeVyZmYsTbAtDQBmjGyibjmbeeqcaw7xOJLIHrkH/u0wAYabNcN6FRTqMRg==} engines: {node: '>=18.0.0'} - '@smithy/hash-node@4.0.4': - resolution: {integrity: sha512-qnbTPUhCVnCgBp4z4BUJUhOEkVwxiEi1cyFM+Zj6o+aY8OFGxUQleKWq8ltgp3dujuhXojIvJWdoqpm6dVO3lQ==} + '@smithy/hash-node@4.2.0': + resolution: {integrity: sha512-ugv93gOhZGysTctZh9qdgng8B+xO0cj+zN0qAZ+Sgh7qTQGPOJbMdIuyP89KNfUyfAqFSNh5tMvC+h2uCpmTtA==} engines: {node: '>=18.0.0'} - '@smithy/hash-stream-node@4.0.4': - resolution: {integrity: sha512-wHo0d8GXyVmpmMh/qOR0R7Y46/G1y6OR8U+bSTB4ppEzRxd1xVAQ9xOE9hOc0bSjhz0ujCPAbfNLkLrpa6cevg==} + '@smithy/hash-stream-node@4.2.0': + resolution: {integrity: sha512-8dELAuGv+UEjtzrpMeNBZc1sJhO8GxFVV/Yh21wE35oX4lOE697+lsMHBoUIFAUuYkTMIeu0EuJSEsH7/8Y+UQ==} engines: {node: '>=18.0.0'} - '@smithy/invalid-dependency@4.0.4': - resolution: {integrity: sha512-bNYMi7WKTJHu0gn26wg8OscncTt1t2b8KcsZxvOv56XA6cyXtOAAAaNP7+m45xfppXfOatXF3Sb1MNsLUgVLTw==} + '@smithy/invalid-dependency@4.2.0': + resolution: {integrity: sha512-ZmK5X5fUPAbtvRcUPtk28aqIClVhbfcmfoS4M7UQBTnDdrNxhsrxYVv0ZEl5NaPSyExsPWqL4GsPlRvtlwg+2A==} engines: {node: '>=18.0.0'} '@smithy/is-array-buffer@2.2.0': resolution: {integrity: sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==} engines: {node: '>=14.0.0'} - '@smithy/is-array-buffer@4.0.0': - resolution: {integrity: sha512-saYhF8ZZNoJDTvJBEWgeBccCg+yvp1CX+ed12yORU3NilJScfc6gfch2oVb4QgxZrGUx3/ZJlb+c/dJbyupxlw==} + '@smithy/is-array-buffer@4.2.0': + resolution: {integrity: sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ==} engines: {node: '>=18.0.0'} - '@smithy/md5-js@4.0.4': - resolution: {integrity: sha512-uGLBVqcOwrLvGh/v/jw423yWHq/ofUGK1W31M2TNspLQbUV1Va0F5kTxtirkoHawODAZcjXTSGi7JwbnPcDPJg==} + '@smithy/md5-js@4.2.0': + resolution: {integrity: sha512-LFEPniXGKRQArFmDQ3MgArXlClFJMsXDteuQQY8WG1/zzv6gVSo96+qpkuu1oJp4MZsKrwchY0cuAoPKzEbaNA==} engines: {node: '>=18.0.0'} - '@smithy/middleware-content-length@4.0.4': - resolution: {integrity: sha512-F7gDyfI2BB1Kc+4M6rpuOLne5LOcEknH1n6UQB69qv+HucXBR1rkzXBnQTB2q46sFy1PM/zuSJOB532yc8bg3w==} + '@smithy/middleware-content-length@4.2.0': + resolution: {integrity: sha512-6ZAnwrXFecrA4kIDOcz6aLBhU5ih2is2NdcZtobBDSdSHtE9a+MThB5uqyK4XXesdOCvOcbCm2IGB95birTSOQ==} engines: {node: '>=18.0.0'} - '@smithy/middleware-endpoint@4.1.11': - resolution: {integrity: sha512-zDogwtRLzKl58lVS8wPcARevFZNBOOqnmzWWxVe9XiaXU2CADFjvJ9XfNibgkOWs08sxLuSr81NrpY4mgp9OwQ==} + '@smithy/middleware-endpoint@4.3.1': + resolution: {integrity: sha512-JtM4SjEgImLEJVXdsbvWHYiJ9dtuKE8bqLlvkvGi96LbejDL6qnVpVxEFUximFodoQbg0Gnkyff9EKUhFhVJFw==} engines: {node: '>=18.0.0'} - '@smithy/middleware-retry@4.1.12': - resolution: {integrity: sha512-wvIH70c4e91NtRxdaLZF+mbLZ/HcC6yg7ySKUiufL6ESp6zJUSnJucZ309AvG9nqCFHSRB5I6T3Ez1Q9wCh0Ww==} + '@smithy/middleware-retry@4.4.1': + resolution: {integrity: sha512-wXxS4ex8cJJteL0PPQmWYkNi9QKDWZIpsndr0wZI2EL+pSSvA/qqxXU60gBOJoIc2YgtZSWY/PE86qhKCCKP1w==} engines: {node: '>=18.0.0'} - '@smithy/middleware-serde@4.0.8': - resolution: {integrity: sha512-iSSl7HJoJaGyMIoNn2B7czghOVwJ9nD7TMvLhMWeSB5vt0TnEYyRRqPJu/TqW76WScaNvYYB8nRoiBHR9S1Ddw==} + '@smithy/middleware-serde@4.2.0': + resolution: {integrity: sha512-rpTQ7D65/EAbC6VydXlxjvbifTf4IH+sADKg6JmAvhkflJO2NvDeyU9qsWUNBelJiQFcXKejUHWRSdmpJmEmiw==} engines: {node: '>=18.0.0'} - '@smithy/middleware-stack@4.0.4': - resolution: {integrity: sha512-kagK5ggDrBUCCzI93ft6DjteNSfY8Ulr83UtySog/h09lTIOAJ/xUSObutanlPT0nhoHAkpmW9V5K8oPyLh+QA==} + '@smithy/middleware-stack@4.2.0': + resolution: {integrity: sha512-G5CJ//eqRd9OARrQu9MK1H8fNm2sMtqFh6j8/rPozhEL+Dokpvi1Og+aCixTuwDAGZUkJPk6hJT5jchbk/WCyg==} engines: {node: '>=18.0.0'} - '@smithy/node-config-provider@4.1.3': - resolution: {integrity: sha512-HGHQr2s59qaU1lrVH6MbLlmOBxadtzTsoO4c+bF5asdgVik3I8o7JIOzoeqWc5MjVa+vD36/LWE0iXKpNqooRw==} + '@smithy/node-config-provider@4.3.0': + resolution: {integrity: sha512-5QgHNuWdT9j9GwMPPJCKxy2KDxZ3E5l4M3/5TatSZrqYVoEiqQrDfAq8I6KWZw7RZOHtVtCzEPdYz7rHZixwcA==} engines: {node: '>=18.0.0'} '@smithy/node-http-handler@2.5.0': resolution: {integrity: sha512-mVGyPBzkkGQsPoxQUbxlEfRjrj6FPyA3u3u2VXGr9hT8wilsoQdZdvKpMBFMB8Crfhv5dNkKHIW0Yyuc7eABqA==} engines: {node: '>=14.0.0'} - '@smithy/node-http-handler@4.0.6': - resolution: {integrity: sha512-NqbmSz7AW2rvw4kXhKGrYTiJVDHnMsFnX4i+/FzcZAfbOBauPYs2ekuECkSbtqaxETLLTu9Rl/ex6+I2BKErPA==} + '@smithy/node-http-handler@4.3.0': + resolution: {integrity: sha512-RHZ/uWCmSNZ8cneoWEVsVwMZBKy/8123hEpm57vgGXA3Irf/Ja4v9TVshHK2ML5/IqzAZn0WhINHOP9xl+Qy6Q==} engines: {node: '>=18.0.0'} - '@smithy/property-provider@4.0.4': - resolution: {integrity: sha512-qHJ2sSgu4FqF4U/5UUp4DhXNmdTrgmoAai6oQiM+c5RZ/sbDwJ12qxB1M6FnP+Tn/ggkPZf9ccn4jqKSINaquw==} + '@smithy/property-provider@4.2.0': + resolution: {integrity: sha512-rV6wFre0BU6n/tx2Ztn5LdvEdNZ2FasQbPQmDOPfV9QQyDmsCkOAB0osQjotRCQg+nSKFmINhyda0D3AnjSBJw==} engines: {node: '>=18.0.0'} '@smithy/protocol-http@3.3.0': resolution: {integrity: sha512-Xy5XK1AFWW2nlY/biWZXu6/krgbaf2dg0q492D8M5qthsnU2H+UgFeZLbM76FnH7s6RO/xhQRkj+T6KBO3JzgQ==} engines: {node: '>=14.0.0'} - '@smithy/protocol-http@5.1.2': - resolution: {integrity: sha512-rOG5cNLBXovxIrICSBm95dLqzfvxjEmuZx4KK3hWwPFHGdW3lxY0fZNXfv2zebfRO7sJZ5pKJYHScsqopeIWtQ==} + '@smithy/protocol-http@5.3.0': + resolution: {integrity: sha512-6POSYlmDnsLKb7r1D3SVm7RaYW6H1vcNcTWGWrF7s9+2noNYvUsm7E4tz5ZQ9HXPmKn6Hb67pBDRIjrT4w/d7Q==} engines: {node: '>=18.0.0'} '@smithy/querystring-builder@2.2.0': resolution: {integrity: sha512-L1kSeviUWL+emq3CUVSgdogoM/D9QMFaqxL/dd0X7PCNWmPXqt+ExtrBjqT0V7HLN03Vs9SuiLrG3zy3JGnE5A==} engines: {node: '>=14.0.0'} - '@smithy/querystring-builder@4.0.4': - resolution: {integrity: sha512-SwREZcDnEYoh9tLNgMbpop+UTGq44Hl9tdj3rf+yeLcfH7+J8OXEBaMc2kDxtyRHu8BhSg9ADEx0gFHvpJgU8w==} + '@smithy/querystring-builder@4.2.0': + resolution: {integrity: sha512-Q4oFD0ZmI8yJkiPPeGUITZj++4HHYCW3pYBYfIobUCkYpI6mbkzmG1MAQQ3lJYYWj3iNqfzOenUZu+jqdPQ16A==} engines: {node: '>=18.0.0'} - '@smithy/querystring-parser@4.0.4': - resolution: {integrity: sha512-6yZf53i/qB8gRHH/l2ZwUG5xgkPgQF15/KxH0DdXMDHjesA9MeZje/853ifkSY0x4m5S+dfDZ+c4x439PF0M2w==} + '@smithy/querystring-parser@4.2.0': + resolution: {integrity: sha512-BjATSNNyvVbQxOOlKse0b0pSezTWGMvA87SvoFoFlkRsKXVsN3bEtjCxvsNXJXfnAzlWFPaT9DmhWy1vn0sNEA==} engines: {node: '>=18.0.0'} - '@smithy/service-error-classification@4.0.5': - resolution: {integrity: sha512-LvcfhrnCBvCmTee81pRlh1F39yTS/+kYleVeLCwNtkY8wtGg8V/ca9rbZZvYIl8OjlMtL6KIjaiL/lgVqHD2nA==} + '@smithy/service-error-classification@4.2.0': + resolution: {integrity: sha512-Ylv1ttUeKatpR0wEOMnHf1hXMktPUMObDClSWl2TpCVT4DwtJhCeighLzSLbgH3jr5pBNM0LDXT5yYxUvZ9WpA==} engines: {node: '>=18.0.0'} - '@smithy/shared-ini-file-loader@4.0.4': - resolution: {integrity: sha512-63X0260LoFBjrHifPDs+nM9tV0VMkOTl4JRMYNuKh/f5PauSjowTfvF3LogfkWdcPoxsA9UjqEOgjeYIbhb7Nw==} + '@smithy/shared-ini-file-loader@4.3.0': + resolution: {integrity: sha512-VCUPPtNs+rKWlqqntX0CbVvWyjhmX30JCtzO+s5dlzzxrvSfRh5SY0yxnkirvc1c80vdKQttahL71a9EsdolSQ==} engines: {node: '>=18.0.0'} - '@smithy/signature-v4@5.1.2': - resolution: {integrity: sha512-d3+U/VpX7a60seHziWnVZOHuEgJlclufjkS6zhXvxcJgkJq4UWdH5eOBLzHRMx6gXjsdT9h6lfpmLzbrdupHgQ==} + '@smithy/signature-v4@5.3.0': + resolution: {integrity: sha512-MKNyhXEs99xAZaFhm88h+3/V+tCRDQ+PrDzRqL0xdDpq4gjxcMmf5rBA3YXgqZqMZ/XwemZEurCBQMfxZOWq/g==} engines: {node: '>=18.0.0'} - '@smithy/smithy-client@4.4.3': - resolution: {integrity: sha512-xxzNYgA0HD6ETCe5QJubsxP0hQH3QK3kbpJz3QrosBCuIWyEXLR/CO5hFb2OeawEKUxMNhz3a1nuJNN2np2RMA==} + '@smithy/smithy-client@4.7.1': + resolution: {integrity: sha512-WXVbiyNf/WOS/RHUoFMkJ6leEVpln5ojCjNBnzoZeMsnCg3A0BRhLK3WYc4V7PmYcYPZh9IYzzAg9XcNSzYxYQ==} engines: {node: '>=18.0.0'} '@smithy/types@2.12.0': resolution: {integrity: sha512-QwYgloJ0sVNBeBuBs65cIkTbfzV/Q6ZNPCJ99EICFEdJYG50nGIY/uYXp+TbsdJReIuPr0a0kXmCvren3MbRRw==} engines: {node: '>=14.0.0'} - '@smithy/types@4.3.1': - resolution: {integrity: sha512-UqKOQBL2x6+HWl3P+3QqFD4ncKq0I8Nuz9QItGv5WuKuMHuuwlhvqcZCoXGfc+P1QmfJE7VieykoYYmrOoFJxA==} + '@smithy/types@4.6.0': + resolution: {integrity: sha512-4lI9C8NzRPOv66FaY1LL1O/0v0aLVrq/mXP/keUa9mJOApEeae43LsLd2kZRUJw91gxOQfLIrV3OvqPgWz1YsA==} engines: {node: '>=18.0.0'} - '@smithy/url-parser@4.0.4': - resolution: {integrity: sha512-eMkc144MuN7B0TDA4U2fKs+BqczVbk3W+qIvcoCY6D1JY3hnAdCuhCZODC+GAeaxj0p6Jroz4+XMUn3PCxQQeQ==} + '@smithy/url-parser@4.2.0': + resolution: {integrity: sha512-AlBmD6Idav2ugmoAL6UtR6ItS7jU5h5RNqLMZC7QrLCoITA9NzIN3nx9GWi8g4z1pfWh2r9r96SX/jHiNwPJ9A==} engines: {node: '>=18.0.0'} - '@smithy/util-base64@4.0.0': - resolution: {integrity: sha512-CvHfCmO2mchox9kjrtzoHkWHxjHZzaFojLc8quxXY7WAAMAg43nuxwv95tATVgQFNDwd4M9S1qFzj40Ul41Kmg==} + '@smithy/util-base64@4.3.0': + resolution: {integrity: sha512-GkXZ59JfyxsIwNTWFnjmFEI8kZpRNIBfxKjv09+nkAWPt/4aGaEWMM04m4sxgNVWkbt2MdSvE3KF/PfX4nFedQ==} engines: {node: '>=18.0.0'} - '@smithy/util-body-length-browser@4.0.0': - resolution: {integrity: sha512-sNi3DL0/k64/LO3A256M+m3CDdG6V7WKWHdAiBBMUN8S3hK3aMPhwnPik2A/a2ONN+9doY9UxaLfgqsIRg69QA==} + '@smithy/util-body-length-browser@4.2.0': + resolution: {integrity: sha512-Fkoh/I76szMKJnBXWPdFkQJl2r9SjPt3cMzLdOB6eJ4Pnpas8hVoWPYemX/peO0yrrvldgCUVJqOAjUrOLjbxg==} engines: {node: '>=18.0.0'} - '@smithy/util-body-length-node@4.0.0': - resolution: {integrity: sha512-q0iDP3VsZzqJyje8xJWEJCNIu3lktUGVoSy1KB0UWym2CL1siV3artm+u1DFYTLejpsrdGyCSWBdGNjJzfDPjg==} + '@smithy/util-body-length-node@4.2.1': + resolution: {integrity: sha512-h53dz/pISVrVrfxV1iqXlx5pRg3V2YWFcSQyPyXZRrZoZj4R4DeWRDo1a7dd3CPTcFi3kE+98tuNyD2axyZReA==} engines: {node: '>=18.0.0'} '@smithy/util-buffer-from@2.2.0': resolution: {integrity: sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==} engines: {node: '>=14.0.0'} - '@smithy/util-buffer-from@4.0.0': - resolution: {integrity: sha512-9TOQ7781sZvddgO8nxueKi3+yGvkY35kotA0Y6BWRajAv8jjmigQ1sBwz0UX47pQMYXJPahSKEKYFgt+rXdcug==} + '@smithy/util-buffer-from@4.2.0': + resolution: {integrity: sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew==} engines: {node: '>=18.0.0'} - '@smithy/util-config-provider@4.0.0': - resolution: {integrity: sha512-L1RBVzLyfE8OXH+1hsJ8p+acNUSirQnWQ6/EgpchV88G6zGBTDPdXiiExei6Z1wR2RxYvxY/XLw6AMNCCt8H3w==} + '@smithy/util-config-provider@4.2.0': + resolution: {integrity: sha512-YEjpl6XJ36FTKmD+kRJJWYvrHeUvm5ykaUS5xK+6oXffQPHeEM4/nXlZPe+Wu0lsgRUcNZiliYNh/y7q9c2y6Q==} engines: {node: '>=18.0.0'} - '@smithy/util-defaults-mode-browser@4.0.19': - resolution: {integrity: sha512-mvLMh87xSmQrV5XqnUYEPoiFFeEGYeAKIDDKdhE2ahqitm8OHM3aSvhqL6rrK6wm1brIk90JhxDf5lf2hbrLbQ==} + '@smithy/util-defaults-mode-browser@4.3.0': + resolution: {integrity: sha512-H4MAj8j8Yp19Mr7vVtGgi7noJjvjJbsKQJkvNnLlrIFduRFT5jq5Eri1k838YW7rN2g5FTnXpz5ktKVr1KVgPQ==} engines: {node: '>=18.0.0'} - '@smithy/util-defaults-mode-node@4.0.19': - resolution: {integrity: sha512-8tYnx+LUfj6m+zkUUIrIQJxPM1xVxfRBvoGHua7R/i6qAxOMjqR6CpEpDwKoIs1o0+hOjGvkKE23CafKL0vJ9w==} + '@smithy/util-defaults-mode-node@4.2.1': + resolution: {integrity: sha512-PuDcgx7/qKEMzV1QFHJ7E4/MMeEjaA7+zS5UNcHCLPvvn59AeZQ0DSDGMpqC2xecfa/1cNGm4l8Ec/VxCuY7Ug==} engines: {node: '>=18.0.0'} - '@smithy/util-endpoints@3.0.6': - resolution: {integrity: sha512-YARl3tFL3WgPuLzljRUnrS2ngLiUtkwhQtj8PAL13XZSyUiNLQxwG3fBBq3QXFqGFUXepIN73pINp3y8c2nBmA==} + '@smithy/util-endpoints@3.2.0': + resolution: {integrity: sha512-TXeCn22D56vvWr/5xPqALc9oO+LN+QpFjrSM7peG/ckqEPoI3zaKZFp+bFwfmiHhn5MGWPaLCqDOJPPIixk9Wg==} engines: {node: '>=18.0.0'} - '@smithy/util-hex-encoding@4.0.0': - resolution: {integrity: sha512-Yk5mLhHtfIgW2W2WQZWSg5kuMZCVbvhFmC7rV4IO2QqnZdbEFPmQnCcGMAX2z/8Qj3B9hYYNjZOhWym+RwhePw==} + '@smithy/util-hex-encoding@4.2.0': + resolution: {integrity: sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw==} engines: {node: '>=18.0.0'} - '@smithy/util-middleware@4.0.4': - resolution: {integrity: sha512-9MLKmkBmf4PRb0ONJikCbCwORACcil6gUWojwARCClT7RmLzF04hUR4WdRprIXal7XVyrddadYNfp2eF3nrvtQ==} + '@smithy/util-middleware@4.2.0': + resolution: {integrity: sha512-u9OOfDa43MjagtJZ8AapJcmimP+K2Z7szXn8xbty4aza+7P1wjFmy2ewjSbhEiYQoW1unTlOAIV165weYAaowA==} engines: {node: '>=18.0.0'} - '@smithy/util-retry@4.0.5': - resolution: {integrity: sha512-V7MSjVDTlEt/plmOFBn1762Dyu5uqMrV2Pl2X0dYk4XvWfdWJNe9Bs5Bzb56wkCuiWjSfClVMGcsuKrGj7S/yg==} + '@smithy/util-retry@4.2.0': + resolution: {integrity: sha512-BWSiuGbwRnEE2SFfaAZEX0TqaxtvtSYPM/J73PFVm+A29Fg1HTPiYFb8TmX1DXp4hgcdyJcNQmprfd5foeORsg==} engines: {node: '>=18.0.0'} - '@smithy/util-stream@4.2.2': - resolution: {integrity: sha512-aI+GLi7MJoVxg24/3J1ipwLoYzgkB4kUfogZfnslcYlynj3xsQ0e7vk4TnTro9hhsS5PvX1mwmkRqqHQjwcU7w==} + '@smithy/util-stream@4.5.0': + resolution: {integrity: sha512-0TD5M5HCGu5diEvZ/O/WquSjhJPasqv7trjoqHyWjNh/FBeBl7a0ztl9uFMOsauYtRfd8jvpzIAQhDHbx+nvZw==} engines: {node: '>=18.0.0'} '@smithy/util-uri-escape@2.2.0': resolution: {integrity: sha512-jtmJMyt1xMD/d8OtbVJ2gFZOSKc+ueYJZPW20ULW1GOp/q/YIM0wNh+u8ZFao9UaIGz4WoPW8hC64qlWLIfoDA==} engines: {node: '>=14.0.0'} - '@smithy/util-uri-escape@4.0.0': - resolution: {integrity: sha512-77yfbCbQMtgtTylO9itEAdpPXSog3ZxMe09AEhm0dU0NLTalV70ghDZFR+Nfi1C60jnJoh/Re4090/DuZh2Omg==} + '@smithy/util-uri-escape@4.2.0': + resolution: {integrity: sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA==} engines: {node: '>=18.0.0'} '@smithy/util-utf8@2.3.0': resolution: {integrity: sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==} engines: {node: '>=14.0.0'} - '@smithy/util-utf8@4.0.0': - resolution: {integrity: sha512-b+zebfKCfRdgNJDknHCob3O7FpeYQN6ZG6YLExMcasDHsCXlsXCEuiPZeLnJLpwa5dvPetGlnGCiMHuLwGvFow==} + '@smithy/util-utf8@4.2.0': + resolution: {integrity: sha512-zBPfuzoI8xyBtR2P6WQj63Rz8i3AmfAaJLuNG8dWsfvPe8lO4aCPYLn879mEgHndZH1zQ2oXmG8O1GGzzaoZiw==} engines: {node: '>=18.0.0'} - '@smithy/util-waiter@4.0.5': - resolution: {integrity: sha512-4QvC49HTteI1gfemu0I1syWovJgPvGn7CVUoN9ZFkdvr/cCFkrEL7qNCdx/2eICqDWEGnnr68oMdSIPCLAriSQ==} + '@smithy/util-waiter@4.2.0': + resolution: {integrity: sha512-0Z+nxUU4/4T+SL8BCNN4ztKdQjToNvUYmkF1kXO5T7Yz3Gafzh0HeIG6mrkN8Fz3gn9hSyxuAT+6h4vM+iQSBQ==} + engines: {node: '>=18.0.0'} + + '@smithy/uuid@1.1.0': + resolution: {integrity: sha512-4aUIteuyxtBUhVdiQqcDhKFitwfd9hqoSDYY2KRXiWtgoWJ9Bmise+KfEPDiVHWeJepvF8xJO9/9+WDIciMFFw==} engines: {node: '>=18.0.0'} '@sqltools/formatter@1.2.5': resolution: {integrity: sha512-Uy0+khmZqUrUGm5dmMqVlnvufZRSK0FbYzVgp0UMstm+F5+W2/jnEEQyc9vo1ZR/E5ZI/B1WjjoTqBqwJL6Krw==} - '@storybook/addon-actions@8.6.12': - resolution: {integrity: sha512-B5kfiRvi35oJ0NIo53CGH66H471A3XTzrfaa6SxXEJsgxxSeKScG5YeXcCvLiZfvANRQ7QDsmzPUgg0o3hdMXw==} + '@standard-schema/spec@1.0.0': + resolution: {integrity: sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==} + + '@storybook/addon-actions@8.6.14': + resolution: {integrity: sha512-mDQxylxGGCQSK7tJPkD144J8jWh9IU9ziJMHfB84PKpI/V5ZgqMDnpr2bssTrUaGDqU5e1/z8KcRF+Melhs9pQ==} peerDependencies: - storybook: ^8.6.12 + storybook: ^8.6.14 - '@storybook/addon-backgrounds@8.6.12': - resolution: {integrity: sha512-lmIAma9BiiCTbJ8YfdZkXjpnAIrOUcgboLkt1f6XJ78vNEMnLNzD9gnh7Tssz1qrqvm34v9daDjIb+ggdiKp3Q==} + '@storybook/addon-backgrounds@8.6.14': + resolution: {integrity: sha512-l9xS8qWe5n4tvMwth09QxH2PmJbCctEvBAc1tjjRasAfrd69f7/uFK4WhwJAstzBTNgTc8VXI4w8ZR97i1sFbg==} peerDependencies: - storybook: ^8.6.12 + storybook: ^8.6.14 - '@storybook/addon-controls@8.6.12': - resolution: {integrity: sha512-9VSRPJWQVb9wLp21uvpxDGNctYptyUX0gbvxIWOHMH3R2DslSoq41lsC/oQ4l4zSHVdL+nq8sCTkhBxIsjKqdQ==} + '@storybook/addon-controls@8.6.14': + resolution: {integrity: sha512-IiQpkNJdiRyA4Mq9mzjZlvQugL/aE7hNgVxBBGPiIZG6wb6Ht9hNnBYpap5ZXXFKV9p2qVI0FZK445ONmAa+Cw==} peerDependencies: - storybook: ^8.6.12 + storybook: ^8.6.14 - '@storybook/addon-docs@8.6.12': - resolution: {integrity: sha512-kEezQjAf/p3SpDzLABgg4fbT48B6dkT2LiZCKTRmCrJVtuReaAr4R9MMM6Jsph6XjbIj/SvOWf3CMeOPXOs9sg==} + '@storybook/addon-docs@8.6.14': + resolution: {integrity: sha512-Obpd0OhAF99JyU5pp5ci17YmpcQtMNgqW2pTXV8jAiiipWpwO++hNDeQmLmlSXB399XjtRDOcDVkoc7rc6JzdQ==} peerDependencies: - storybook: ^8.6.12 + storybook: ^8.6.14 - '@storybook/addon-essentials@8.6.12': - resolution: {integrity: sha512-Y/7e8KFlttaNfv7q2zoHMPdX6hPXHdsuQMAjYl5NG9HOAJREu4XBy4KZpbcozRe4ApZ78rYsN/MO1EuA+bNMIA==} + '@storybook/addon-essentials@8.6.14': + resolution: {integrity: sha512-5ZZSHNaW9mXMOFkoPyc3QkoNGdJHETZydI62/OASR0lmPlJ1065TNigEo5dJddmZNn0/3bkE8eKMAzLnO5eIdA==} peerDependencies: - storybook: ^8.6.12 + storybook: ^8.6.14 - '@storybook/addon-highlight@8.6.12': - resolution: {integrity: sha512-9FITVxdoycZ+eXuAZL9ElWyML/0fPPn9UgnnAkrU7zkMi+Segq/Tx7y+WWanC5zfWZrXAuG6WTOYEXeWQdm//w==} + '@storybook/addon-highlight@8.6.14': + resolution: {integrity: sha512-4H19OJlapkofiE9tM6K/vsepf4ir9jMm9T+zw5L85blJZxhKZIbJ6FO0TCG9PDc4iPt3L6+aq5B0X29s9zicNQ==} peerDependencies: - storybook: ^8.6.12 + storybook: ^8.6.14 - '@storybook/addon-interactions@8.6.12': - resolution: {integrity: sha512-cTAJlTq6uVZBEbtwdXkXoPQ4jHOAGKQnYSezBT4pfNkdjn/FnEeaQhMBDzf14h2wr5OgBnJa6Lmd8LD9ficz4A==} + '@storybook/addon-interactions@8.6.14': + resolution: {integrity: sha512-8VmElhm2XOjh22l/dO4UmXxNOolGhNiSpBcls2pqWSraVh4a670EyYBZsHpkXqfNHo2YgKyZN3C91+9zfH79qQ==} peerDependencies: - storybook: ^8.6.12 + storybook: ^8.6.14 - '@storybook/addon-links@8.6.12': - resolution: {integrity: sha512-AfKujFHoAxhxq4yu+6NwylltS9lf5MPs1eLLXvOlwo3l7Y/c68OdxJ7j68vLQhs9H173WVYjKyjbjFxJWf/YYg==} + '@storybook/addon-links@9.1.10': + resolution: {integrity: sha512-MG0vktKX/qH+hSRnX2/TfEtSpO87G++H5D95PaBtPYwV+JqgZI5Qpq+ikC+s0wvCxlRgm3qy+NkeoHGze29T0g==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta - storybook: ^8.6.12 + storybook: ^9.1.10 peerDependenciesMeta: react: optional: true - '@storybook/addon-mdx-gfm@8.6.12': - resolution: {integrity: sha512-OKI5+O8xyK8axGPFwkl38NGJ6Rjf7kyhiBPxw5NuHOjOnU/FL4Pw3QmY47TT96TVws27vP3gF5+FX8lj3Dd3rQ==} + '@storybook/addon-mdx-gfm@8.6.14': + resolution: {integrity: sha512-ClfngOSwFrhc3x2dXSzfBSSbzz4VHzUs0XOg9V8fj1bgQhmPoMz9OD3vIjbnJOC33wORbC0ZpfcQPt3RGILYrA==} peerDependencies: - storybook: ^8.6.12 + storybook: ^8.6.14 - '@storybook/addon-measure@8.6.12': - resolution: {integrity: sha512-tACmwqqOvutaQSduw8SMb62wICaT1rWaHtMN3vtWXuxgDPSdJQxLP+wdVyRYMAgpxhLyIO7YRf++Hfha9RHgFg==} + '@storybook/addon-measure@8.6.14': + resolution: {integrity: sha512-1Tlyb72NX8aAqm6I6OICsUuGOP6hgnXcuFlXucyhKomPa6j3Eu2vKu561t/f0oGtAK2nO93Z70kVaEh5X+vaGw==} peerDependencies: - storybook: ^8.6.12 + storybook: ^8.6.14 - '@storybook/addon-outline@8.6.12': - resolution: {integrity: sha512-1ylwm+n1s40S91No0v9T4tCjZORu3GbnjINlyjYTDLLhQHyBQd3nWR1Y1eewU4xH4cW9SnSLcMQFS/82xHqU6A==} + '@storybook/addon-outline@8.6.14': + resolution: {integrity: sha512-CW857JvN6OxGWElqjlzJO2S69DHf+xO3WsEfT5mT3ZtIjmsvRDukdWfDU9bIYUFyA2lFvYjncBGjbK+I91XR7w==} peerDependencies: - storybook: ^8.6.12 + storybook: ^8.6.14 - '@storybook/addon-storysource@8.6.12': - resolution: {integrity: sha512-EAvf7DubbIw8OnTCp/blmgDaO4hzL8rROR+SpNMx6t3NwFgfJTP4VosiNOFIrtdGOaUeG0I815XSUphjNQ14lw==} + '@storybook/addon-storysource@8.6.14': + resolution: {integrity: sha512-/eDCNUHPdsVDF53B+Ebi9gHSNcRrA3puo1UCDio8wMN+jBMoWh6E5wSjXDsxWaOyp0Zwuq8XUx8AdgTlg/rcrw==} peerDependencies: - storybook: ^8.6.12 + storybook: ^8.6.14 - '@storybook/addon-toolbars@8.6.12': - resolution: {integrity: sha512-HEcSzo1DyFtIu5/ikVOmh5h85C1IvK9iFKSzBR6ice33zBOaehVJK+Z5f487MOXxPsZ63uvWUytwPyViGInj+g==} + '@storybook/addon-toolbars@8.6.14': + resolution: {integrity: sha512-W/wEXT8h3VyZTVfWK/84BAcjAxTdtRiAkT2KAN0nbSHxxB5KEM1MjKpKu2upyzzMa3EywITqbfy4dP6lpkVTwQ==} peerDependencies: - storybook: ^8.6.12 + storybook: ^8.6.14 - '@storybook/addon-viewport@8.6.12': - resolution: {integrity: sha512-EXK2LArAnABsPP0leJKy78L/lbMWow+EIJfytEP5fHaW4EhMR6h7Hzaqzre6U0IMMr/jVFa1ci+m0PJ0eQc2bw==} + '@storybook/addon-viewport@8.6.14': + resolution: {integrity: sha512-gNzVQbMqRC+/4uQTPI2ZrWuRHGquTMZpdgB9DrD88VTEjNudP+J6r8myLfr2VvGksBbUMHkGHMXHuIhrBEnXYA==} peerDependencies: - storybook: ^8.6.12 + storybook: ^8.6.14 - '@storybook/blocks@8.6.12': - resolution: {integrity: sha512-DohlTq6HM1jDbHYiXL4ZvZ00VkhpUp5uftzj/CZDLY1fYHRjqtaTwWm2/OpceivMA8zDitLcq5atEZN+f+siTg==} + '@storybook/blocks@8.6.14': + resolution: {integrity: sha512-rBMHAfA39AGHgkrDze4RmsnQTMw1ND5fGWobr9pDcJdnDKWQWNRD7Nrlxj0gFlN3n4D9lEZhWGdFrCbku7FVAQ==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - storybook: ^8.6.12 + storybook: ^8.6.14 peerDependenciesMeta: react: optional: true react-dom: optional: true - '@storybook/builder-vite@8.6.12': - resolution: {integrity: sha512-Gju21ud/3Qw4v2vLNaa5SuJECsI9ICNRr2G0UyCCzRvCHg8jpA9lDReu2NqhLDyFIuDG+ZYT38gcaHEUoNQ8KQ==} + '@storybook/builder-vite@9.1.10': + resolution: {integrity: sha512-0ogI+toZJYaFptcFpRcRPOZ9/NrFUYhiaI09ggeEB1FF9ygHMVsobp4eaj4HjZI6V3x7cQwkd2ZmxAMQDBQuMA==} peerDependencies: - storybook: ^8.6.12 - vite: ^4.0.0 || ^5.0.0 || ^6.0.0 + storybook: ^9.1.10 + vite: ^5.0.0 || ^6.0.0 || ^7.0.0 - '@storybook/components@8.6.12': - resolution: {integrity: sha512-FiaE8xvCdvKC2arYusgtlDNZ77b8ysr8njAYQZwwaIHjy27TbR2tEpLDCmUwSbANNmivtc/xGEiDDwcNppMWlQ==} + '@storybook/components@8.6.14': + resolution: {integrity: sha512-HNR2mC5I4Z5ek8kTrVZlIY/B8gJGs5b3XdZPBPBopTIN6U/YHXiDyOjY3JlaS4fSG1fVhp/Qp1TpMn1w/9m1pw==} peerDependencies: storybook: ^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0 - '@storybook/core-events@8.6.12': - resolution: {integrity: sha512-j2MUlSfYOhTsjlruRWTqSVwYreJGFIsWeqHFAhCdtmXe3qpFBM/LuxTKuaM1uWvs6vEAyGEzDw8+DXwuO6uISg==} + '@storybook/core-events@8.6.14': + resolution: {integrity: sha512-RrJ95u3HuIE4Nk8VmZP0tc/u0vYoE2v9fYlMw6K2GUSExzKDITs3voy6WMIY7Q3qbQun8XUXVlmqkuFzTEy/pA==} peerDependencies: storybook: ^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0 - '@storybook/core@8.6.12': - resolution: {integrity: sha512-t+ZuDzAlsXKa6tLxNZT81gEAt4GNwsKP/Id2wluhmUWD/lwYW0uum1JiPUuanw8xD6TdakCW/7ULZc7aQUBLCQ==} + '@storybook/csf-plugin@8.6.14': + resolution: {integrity: sha512-dErtc9teAuN+eelN8FojzFE635xlq9cNGGGEu0WEmMUQ4iJ8pingvBO1N8X3scz4Ry7KnxX++NNf3J3gpxS8qQ==} peerDependencies: - prettier: ^2 || ^3 - peerDependenciesMeta: - prettier: - optional: true + storybook: ^8.6.14 - '@storybook/csf-plugin@8.6.12': - resolution: {integrity: sha512-6s8CnP1aoKPb3XtC0jRLUp8M5vTA8RhGAwQDKUsFpCC7g89JR9CaKs9FY2ZSzsNbjR15uASi7b3K8BzeYumYQg==} + '@storybook/csf-plugin@9.1.10': + resolution: {integrity: sha512-247F/JU0Naxm/RIUnQYpqXeCL0wG8UNJkZe+/GkLjdqzsyML0lb+8OwBsWFfG8zfj6fkjmRU2mF44TnNkzoQcg==} peerDependencies: - storybook: ^8.6.12 + storybook: ^9.1.10 '@storybook/csf@0.0.1': resolution: {integrity: sha512-USTLkZze5gkel8MYCujSRBVIrUQ3YPBrLOx7GNk/0wttvVtlzWXAq9eLbQ4p/NicGxP+3T7KPEMVV//g+yubpw==} @@ -4213,105 +4197,105 @@ packages: '@storybook/global@5.0.0': resolution: {integrity: sha512-FcOqPAXACP0I3oJ/ws6/rrPT9WGhu915Cg8D02a9YxLo0DE9zI+a9A5gRGvmQ09fiWPukqI8ZAEoQEdWUKMQdQ==} - '@storybook/icons@1.4.0': - resolution: {integrity: sha512-Td73IeJxOyalzvjQL+JXx72jlIYHgs+REaHiREOqfpo3A2AYYG71AUbcv+lg7mEDIweKVCxsMQ0UKo634c8XeA==} + '@storybook/icons@1.2.12': + resolution: {integrity: sha512-UxgyK5W3/UV4VrI3dl6ajGfHM4aOqMAkFLWe2KibeQudLf6NJpDrDMSHwZj+3iKC4jFU7dkKbbtH2h/al4sW3Q==} engines: {node: '>=14.0.0'} peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta - react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 - '@storybook/instrumenter@8.6.12': - resolution: {integrity: sha512-VK5fYAF8jMwWP/u3YsmSwKGh+FeSY8WZn78flzRUwirp2Eg1WWjsqPRubAk7yTpcqcC/km9YMF3KbqfzRv2s/A==} + '@storybook/instrumenter@8.6.14': + resolution: {integrity: sha512-iG4MlWCcz1L7Yu8AwgsnfVAmMbvyRSk700Mfy2g4c8y5O+Cv1ejshE1LBBsCwHgkuqU0H4R0qu4g23+6UnUemQ==} peerDependencies: - storybook: ^8.6.12 + storybook: ^8.6.14 - '@storybook/manager-api@8.6.12': - resolution: {integrity: sha512-O0SpISeJLNTQvhSBOsWzzkCgs8vCjOq1578rwqHlC6jWWm4QmtfdyXqnv7rR1Hk08kQ+Dzqh0uhwHx0nfwy4nQ==} + '@storybook/manager-api@8.6.14': + resolution: {integrity: sha512-ez0Zihuy17udLbfHZQXkGqwtep0mSGgHcNzGN7iZrMP1m+VmNo+7aGCJJdvXi7+iU3yq8weXSQFWg5DqWgLS7g==} peerDependencies: storybook: ^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0 - '@storybook/preview-api@8.6.12': - resolution: {integrity: sha512-84FE3Hrs0AYKHqpDZOwx1S/ffOfxBdL65lhCoeI8GoWwCkzwa9zEP3kvXBo/BnEDO7nAfxvMhjASTZXbKRJh5Q==} + '@storybook/preview-api@8.6.14': + resolution: {integrity: sha512-2GhcCd4dNMrnD7eooEfvbfL4I83qAqEyO0CO7JQAmIO6Rxb9BsOLLI/GD5HkvQB73ArTJ+PT50rfaO820IExOQ==} peerDependencies: storybook: ^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0 - '@storybook/react-dom-shim@8.6.12': - resolution: {integrity: sha512-51QvoimkBzYs8s3rCYnY5h0cFqLz/Mh0vRcughwYaXckWzDBV8l67WBO5Xf5nBsukCbWyqBVPpEQLww8s7mrLA==} + '@storybook/react-dom-shim@8.6.14': + resolution: {integrity: sha512-0hixr3dOy3f3M+HBofp3jtMQMS+sqzjKNgl7Arfuj3fvjmyXOks/yGjDImySR4imPtEllvPZfhiQNlejheaInw==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta - storybook: ^8.6.12 + storybook: ^8.6.14 - '@storybook/react-vite@8.6.12': - resolution: {integrity: sha512-UA2Kule99oyFgHdhcuhrRwCKyWu/yMbqbl9U7NwowFHNwWWFjVMMir/AmfShb/H1C1DQ3LqOad6/QwJyPLjP8g==} - engines: {node: '>=18.0.0'} + '@storybook/react-dom-shim@9.1.10': + resolution: {integrity: sha512-cxy8GTj73RMJIFPrgqdnMXePGX5iFohM5pDCZ63Te5m5GtzKqsILRXtBBLO6Ouexm/ZYRVznkKiwNKX/Fu24fQ==} peerDependencies: - '@storybook/test': 8.6.12 react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta - storybook: ^8.6.12 - vite: ^4.0.0 || ^5.0.0 || ^6.0.0 - peerDependenciesMeta: - '@storybook/test': - optional: true + storybook: ^9.1.10 - '@storybook/react@8.6.12': - resolution: {integrity: sha512-NzxlHLA5DkDgZM/dMwTYinuzRs6rsUPmlqP+NIv6YaciQ4NGnTYyOC7R/SqI6HHFm8ZZ5eMYvpfiFmhZ9rU+rQ==} - engines: {node: '>=18.0.0'} + '@storybook/react-vite@9.1.10': + resolution: {integrity: sha512-k0wWlfoWakoHL3NZ1+38oxRH3WYyprFFX+WUb/4W8axrvpKogvdnxKCul/YB1HH5FcTagIfguamsPjKwB1ZkJg==} + engines: {node: '>=20.0.0'} peerDependencies: - '@storybook/test': 8.6.12 react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta - storybook: ^8.6.12 - typescript: '>= 4.2.x' + storybook: ^9.1.10 + vite: ^5.0.0 || ^6.0.0 || ^7.0.0 + + '@storybook/react@9.1.10': + resolution: {integrity: sha512-flG3Gn3EHZnxn92C7vrA2U4aGqpOKdf85fL43+J/2k9HF5AIyOFGlcv4LGVyKZ3LOAow/nGBVSXL9961h+ICRA==} + engines: {node: '>=20.0.0'} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta + storybook: ^9.1.10 + typescript: '>= 4.9.x' peerDependenciesMeta: - '@storybook/test': - optional: true typescript: optional: true - '@storybook/source-loader@8.6.12': - resolution: {integrity: sha512-Yfq54Vh1RnsUXqda6yd79gUoqjOfvig9t6a2eZDkLSBlFiYIUqHYCfMBFXxQTJN2pn0BlZccZs5ho85q3ULWWQ==} + '@storybook/source-loader@8.6.14': + resolution: {integrity: sha512-aFUqrkWh4XSXDmkrK0Nm8q4K94bfgnixFMmql8lBAFuEllFek9Rd3i2RwGOhLUtwzpM89f74nzEgR1kd/ijJ+g==} peerDependencies: - storybook: ^8.6.12 + storybook: ^8.6.14 - '@storybook/test@8.6.12': - resolution: {integrity: sha512-0BK1Eg+VD0lNMB1BtxqHE3tP9FdkUmohtvWG7cq6lWvMrbCmAmh3VWai3RMCCDOukPFpjabOr8BBRLVvhNpv2w==} + '@storybook/test@8.6.14': + resolution: {integrity: sha512-GkPNBbbZmz+XRdrhMtkxPotCLOQ1BaGNp/gFZYdGDk2KmUWBKmvc5JxxOhtoXM2703IzNFlQHSSNnhrDZYuLlw==} peerDependencies: - storybook: ^8.6.12 + storybook: ^8.6.14 - '@storybook/theming@8.6.12': - resolution: {integrity: sha512-6VjZg8HJ2Op7+KV7ihJpYrDnFtd9D1jrQnUS8LckcpuBXrIEbaut5+34ObY8ssQnSqkk2GwIZBBBQYQBCVvkOw==} + '@storybook/theming@8.6.14': + resolution: {integrity: sha512-r4y+LsiB37V5hzpQo+BM10PaCsp7YlZ0YcZzQP1OCkPlYXmUAFy2VvDKaFRpD8IeNPKug2u4iFm/laDEbs03dg==} peerDependencies: storybook: ^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0 - '@storybook/types@8.6.12': - resolution: {integrity: sha512-G/nR+js7KV1qKH3nAcOfwceERBic5e03dpkeA6PDmqBiQ8XeM9B6N4NTMhXi/2gM5ZAGJ+NxJMaW6zLnc32DjA==} + '@storybook/types@8.6.14': + resolution: {integrity: sha512-33kzHZa7h6/EygeLZDcm1PNRTlybokz8dzAh2JYjpETf77pG8jhPmEfrI2oHSAdgNeK7A3OMcGA/EwEN7EJdzw==} peerDependencies: storybook: ^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0 - '@storybook/vue3-vite@8.6.12': - resolution: {integrity: sha512-ihYH2TiV14B8V1mrCVVrbjuf+F6+V/78oWofVkvnUQnpwH4CnAySGf6bz6c6/Y6qEr9r30ECUe6/sS0TMt1ZAQ==} - engines: {node: '>=18.0.0'} + '@storybook/vue3-vite@9.1.10': + resolution: {integrity: sha512-6TiXT2dh7FR2AFNhT5TwbP/hMVzjmLgCGlP5KhKMtZe2xPkSzTd/z+z6RsK49vp0CaNcFus/3uPm0GIFDeeTCQ==} + engines: {node: '>=20.0.0'} peerDependencies: - storybook: ^8.6.12 - vite: ^4.0.0 || ^5.0.0 || ^6.0.0 + storybook: ^9.1.10 + vite: ^5.0.0 || ^6.0.0 || ^7.0.0 - '@storybook/vue3@8.6.12': - resolution: {integrity: sha512-mgGRMrFghDW5nHCDbdbhC4YUrOs7mCzwEuLZtdcvpB8TUPP62lTSnv3Gvcz8r12HjyIK6Jow9WgjTtdownGzkA==} - engines: {node: '>=18.0.0'} + '@storybook/vue3@9.1.10': + resolution: {integrity: sha512-tJl5ElDl5DNK4d/SSTuibKGPK8VqweDLjlcW8uamsDJEZ+a/qg2JmxhU3AlXTbB/BkJU8gfc6kN4HYN6JSMiwA==} + engines: {node: '>=20.0.0'} peerDependencies: - storybook: ^8.6.12 + storybook: ^9.1.10 vue: ^3.0.0 - '@stylistic/eslint-plugin@4.4.1': - resolution: {integrity: sha512-CEigAk7eOLyHvdgmpZsKFwtiqS2wFwI1fn4j09IU9GmD4euFM4jEBAViWeCqaNLlbX2k2+A/Fq9cje4HQBXuJQ==} + '@stylistic/eslint-plugin@3.1.0': + resolution: {integrity: sha512-pA6VOrOqk0+S8toJYhQGv2MWpQQR0QpeUo9AhNkC49Y26nxBQ/nH1rta9bUU1rPw2fJ1zZEMV5oCX5AazT7J2g==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - eslint: '>=9.0.0' + eslint: '>=8.40.0' - '@swc/cli@0.7.3': - resolution: {integrity: sha512-rnVXNnlURjdOuPaBIwZ3TmBA44BF/eP0j154LanlgPEYfau74ige7cpKlKkZr1IBqMOG99lAnYNxQipDWA3hdg==} + '@swc/cli@0.7.8': + resolution: {integrity: sha512-27Ov4rm0s2C6LLX+NDXfDVB69LGs8K94sXtFhgeUyQ4DBywZuCgTBu2loCNHRr8JhT9DeQvJM5j9FAu/THbo4w==} engines: {node: '>= 16.14.0'} hasBin: true peerDependencies: @@ -4327,14 +4311,26 @@ packages: cpu: [arm64] os: [android] - '@swc/core-darwin-arm64@1.11.22': - resolution: {integrity: sha512-upSiFQfo1TE2QM3+KpBcp5SrOdKKjoc+oUoD1mmBDU2Wv4Bjjv16Z2I5ADvIqMV+b87AhYW+4Qu6iVrQD7j96Q==} + '@swc/core-darwin-arm64@1.13.20': + resolution: {integrity: sha512-k/nqRwm6G3tw1BbCDxc3KmAMGsuDYA5Uh4MjYm23e+UziLyHz0z7W0zja3el+yGBIZXKlgSzWVFLsFDFzVqtgg==} + engines: {node: '>=10'} + cpu: [arm64] + os: [darwin] + + '@swc/core-darwin-arm64@1.13.5': + resolution: {integrity: sha512-lKNv7SujeXvKn16gvQqUQI5DdyY8v7xcoO3k06/FJbHJS90zEwZdQiMNRiqpYw/orU543tPaWgz7cIYWhbopiQ==} engines: {node: '>=10'} cpu: [arm64] os: [darwin] - '@swc/core-darwin-x64@1.11.22': - resolution: {integrity: sha512-8PEuF/gxIMJVK21DjuCOtzdqstn2DqnxVhpAYfXEtm3WmMqLIOIZBypF/xafAozyaHws4aB/5xmz8/7rPsjavw==} + '@swc/core-darwin-x64@1.13.20': + resolution: {integrity: sha512-7xr+ACdUMNyrN87oEF1GvJIZJBAhGolfQVB0EYP08JEy8VSh//FEwfdlUz8gweaZyjOl1nuPS6ncXlKgZuZU8A==} + engines: {node: '>=10'} + cpu: [x64] + os: [darwin] + + '@swc/core-darwin-x64@1.13.5': + resolution: {integrity: sha512-ILd38Fg/w23vHb0yVjlWvQBoE37ZJTdlLHa8LRCFDdX4WKfnVBiblsCU9ar4QTMNdeTBEX9iUF4IrbNWhaF1Ng==} engines: {node: '>=10'} cpu: [x64] os: [darwin] @@ -4345,58 +4341,105 @@ packages: cpu: [x64] os: [freebsd] - '@swc/core-linux-arm-gnueabihf@1.11.22': - resolution: {integrity: sha512-NIPTXvqtn9e7oQHgdaxM9Z/anHoXC3Fg4ZAgw5rSGa1OlnKKupt5sdfJamNggSi+eAtyoFcyfkgqHnfe2u63HA==} + '@swc/core-linux-arm-gnueabihf@1.13.20': + resolution: {integrity: sha512-IaOLxU1U/oGV3lZ2T8tD5nB/5O60UFPqj5ZxYzDpCBVB73tDQDIxiDcro1X81nHbwJHjuHmbIrhoflS7LQN6+A==} + engines: {node: '>=10'} + cpu: [arm] + os: [linux] + + '@swc/core-linux-arm-gnueabihf@1.13.5': + resolution: {integrity: sha512-Q6eS3Pt8GLkXxqz9TAw+AUk9HpVJt8Uzm54MvPsqp2yuGmY0/sNaPPNVqctCX9fu/Nu8eaWUen0si6iEiCsazQ==} engines: {node: '>=10'} cpu: [arm] os: [linux] - '@swc/core-linux-arm64-gnu@1.11.22': - resolution: {integrity: sha512-xZ+bgS60c5r8kAeYsLNjJJhhQNkXdidQ277pUabSlu5GjR0CkQUPQ+L9hFeHf8DITEqpPBPRiAiiJsWq5eqMBg==} + '@swc/core-linux-arm64-gnu@1.13.20': + resolution: {integrity: sha512-Lg6FyotDydXGnNnlw+u7vCZzR2+fX3Q2HiULBTYl2dey3TvRyzAfEhdgMjUc4beRzf26U9rzMuTroJ6KMBCBjA==} engines: {node: '>=10'} cpu: [arm64] os: [linux] - '@swc/core-linux-arm64-musl@1.11.22': - resolution: {integrity: sha512-JhrP/q5VqQl2eJR0xKYIkKTPjgf8CRsAmRnjJA2PtZhfQ543YbYvUqxyXSRyBOxdyX8JwzuAxIPEAlKlT7PPuQ==} + '@swc/core-linux-arm64-gnu@1.13.5': + resolution: {integrity: sha512-aNDfeN+9af+y+M2MYfxCzCy/VDq7Z5YIbMqRI739o8Ganz6ST+27kjQFd8Y/57JN/hcnUEa9xqdS3XY7WaVtSw==} engines: {node: '>=10'} cpu: [arm64] os: [linux] - '@swc/core-linux-x64-gnu@1.11.22': - resolution: {integrity: sha512-htmAVL+U01gk9GyziVUP0UWYaUQBgrsiP7Ytf6uDffrySyn/FclUS3MDPocNydqYsOpj3OpNKPxkaHK+F+X5fg==} + '@swc/core-linux-arm64-musl@1.13.20': + resolution: {integrity: sha512-d1SvxmFykS0Ep8nPbduV1UwCvFjZ3ESzFKQdTbkr72bge8AseILBI9TbLTmoeWndDaTesiiTKRD5Y1iAvF1wvA==} + engines: {node: '>=10'} + cpu: [arm64] + os: [linux] + + '@swc/core-linux-arm64-musl@1.13.5': + resolution: {integrity: sha512-9+ZxFN5GJag4CnYnq6apKTnnezpfJhCumyz0504/JbHLo+Ue+ZtJnf3RhyA9W9TINtLE0bC4hKpWi8ZKoETyOQ==} + engines: {node: '>=10'} + cpu: [arm64] + os: [linux] + + '@swc/core-linux-x64-gnu@1.13.20': + resolution: {integrity: sha512-Bwmng57EuMod58Q8GDJA8rmUgFl20taK8w8MqeeDMiCnZY2+rJrNERbIX3sXZbwsf/kCIELZ7q4ZXiwdyB4zoQ==} + engines: {node: '>=10'} + cpu: [x64] + os: [linux] + + '@swc/core-linux-x64-gnu@1.13.5': + resolution: {integrity: sha512-WD530qvHrki8Ywt/PloKUjaRKgstQqNGvmZl54g06kA+hqtSE2FTG9gngXr3UJxYu/cNAjJYiBifm7+w4nbHbA==} + engines: {node: '>=10'} + cpu: [x64] + os: [linux] + + '@swc/core-linux-x64-musl@1.13.20': + resolution: {integrity: sha512-osCm3VEKL/OIKInyhy75S5B+R+QGBdpR1B5vwTYqG/1RB4vFM3O5SDtRZabd6NV9Cxc9dcLztWyZjhs2qp63SQ==} engines: {node: '>=10'} cpu: [x64] os: [linux] - '@swc/core-linux-x64-musl@1.11.22': - resolution: {integrity: sha512-PL0VHbduWPX+ANoyOzr58jBiL2VnD0xGSFwPy7NRZ1Pr6SNWm4jw3x2u6RjLArGhS5EcWp64BSk9ZxqmTV3FEg==} + '@swc/core-linux-x64-musl@1.13.5': + resolution: {integrity: sha512-Luj8y4OFYx4DHNQTWjdIuKTq2f5k6uSXICqx+FSabnXptaOBAbJHNbHT/06JZh6NRUouaf0mYXN0mcsqvkhd7Q==} engines: {node: '>=10'} cpu: [x64] os: [linux] - '@swc/core-win32-arm64-msvc@1.11.22': - resolution: {integrity: sha512-moJvFhhTVGoMeEThtdF7hQog80Q00CS06v5uB+32VRuv+I31+4WPRyGlTWHO+oY4rReNcXut/mlDHPH7p0LdFg==} + '@swc/core-win32-arm64-msvc@1.13.20': + resolution: {integrity: sha512-svbQNirwEa6zwaAJPrEmQnMVZsOz8Jpr4nakFLkYIQwwJ73sBUkUJvH9ouIWmIu5bvgQrbQlRpxWTIY3e0Utlg==} engines: {node: '>=10'} cpu: [arm64] os: [win32] - '@swc/core-win32-ia32-msvc@1.11.22': - resolution: {integrity: sha512-/jnsPJJz89F1aKHIb5ScHkwyzBciz2AjEq2m9tDvQdIdVufdJ4SpEDEN9FqsRNRLcBHjtbLs6bnboA+B+pRFXw==} + '@swc/core-win32-arm64-msvc@1.13.5': + resolution: {integrity: sha512-cZ6UpumhF9SDJvv4DA2fo9WIzlNFuKSkZpZmPG1c+4PFSEMy5DFOjBSllCvnqihCabzXzpn6ykCwBmHpy31vQw==} + engines: {node: '>=10'} + cpu: [arm64] + os: [win32] + + '@swc/core-win32-ia32-msvc@1.13.20': + resolution: {integrity: sha512-uVjjwGXJltUQK0v1qQSNGeMS6osLJuwgeTti5N7kxQ6mOfa1irxq+TX0YdIVQwIONMjzI+TP7lhqPeA9VdUjRg==} engines: {node: '>=10'} cpu: [ia32] os: [win32] - '@swc/core-win32-x64-msvc@1.11.22': - resolution: {integrity: sha512-lc93Y8Mku7LCFGqIxJ91coXZp2HeoDcFZSHCL90Wttg5xhk5xVM9uUCP+OdQsSsEixLF34h5DbT9ObzP8rAdRw==} + '@swc/core-win32-ia32-msvc@1.13.5': + resolution: {integrity: sha512-C5Yi/xIikrFUzZcyGj9L3RpKljFvKiDMtyDzPKzlsDrKIw2EYY+bF88gB6oGY5RGmv4DAX8dbnpRAqgFD0FMEw==} + engines: {node: '>=10'} + cpu: [ia32] + os: [win32] + + '@swc/core-win32-x64-msvc@1.13.20': + resolution: {integrity: sha512-Xm1JAew/P0TgsPSXyo60IH865fAmt9b2Mzd0FBJ77Q1xA1o/Oi9teCeGChyFq3+6JFao6uT0N4mcI3BJ4WBfkA==} + engines: {node: '>=10'} + cpu: [x64] + os: [win32] + + '@swc/core-win32-x64-msvc@1.13.5': + resolution: {integrity: sha512-YrKdMVxbYmlfybCSbRtrilc6UA8GF5aPmGKBdPvjrarvsmf4i7ZHGCEnLtfOMd3Lwbs2WUZq3WdMbozYeLU93Q==} engines: {node: '>=10'} cpu: [x64] os: [win32] - '@swc/core@1.11.22': - resolution: {integrity: sha512-mjPYbqq8XjwqSE0hEPT9CzaJDyxql97LgK4iyvYlwVSQhdN1uK0DBG4eP9PxYzCS2MUGAXB34WFLegdUj5HGpg==} + '@swc/core@1.13.5': + resolution: {integrity: sha512-WezcBo8a0Dg2rnR82zhwoR6aRNxeTGfK5QCD6TQ+kg3xx/zNT02s/0o+81h/3zhvFSB24NtqEr8FTw88O5W/JQ==} engines: {node: '>=10'} - deprecated: It has a bug. See https://github.com/swc-project/swc/issues/10413 peerDependencies: '@swc/helpers': '>=0.5.17' peerDependenciesMeta: @@ -4406,14 +4449,14 @@ packages: '@swc/counter@0.1.3': resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} - '@swc/jest@0.2.38': - resolution: {integrity: sha512-HMoZgXWMqChJwffdDjvplH53g9G2ALQes3HKXDEdliB/b85OQ0CTSbxG8VSeCwiAn7cOaDVEt4mwmZvbHcS52w==} + '@swc/jest@0.2.39': + resolution: {integrity: sha512-eyokjOwYd0Q8RnMHri+8/FS1HIrIUKK/sRrFp8c1dThUOfNeCWbLmBP1P5VsKdvmkd25JaH+OKYwEYiAYg9YAA==} engines: {npm: '>= 7.0.0'} peerDependencies: '@swc/core': '*' - '@swc/types@0.1.23': - resolution: {integrity: sha512-u1iIVZV9Q0jxY+yM2vw/hZGDNudsN85bBpTqzAQ9rzkxW9D+e3aEM4Han+ow518gSewkXgjmEK0BD79ZcNVgPw==} + '@swc/types@0.1.25': + resolution: {integrity: sha512-iAoY/qRhNH8a/hBvm3zKj9qQ4oc2+3w1unPJa2XvTK3XjeLXtzcCingVPw/9e5mn1+0yPqxcBGp9Jf0pkfMb1g==} '@swc/wasm@1.2.130': resolution: {integrity: sha512-rNcJsBxS70+pv8YUWwf5fRlWX6JoY/HJc25HD/F8m6Kv7XhJdqPPMhyX6TKkUBPAG7TWlZYoxa+rHAjPy4Cj3Q==} @@ -4421,15 +4464,18 @@ packages: '@syuilo/aiscript@0.19.0': resolution: {integrity: sha512-ZWG4s1m6RrFjE7NeIMaxFz769YO1jW5ReTrOROrEO4IHheOrjxxJ/Ffe2TUNqX9/XxDloMwfWplKhfSzx8LGMA==} + '@syuilo/aiscript@1.1.2': + resolution: {integrity: sha512-cijsHTiMjeECocElyjRIcWMPGDhZIX3YfCOyzI6AZM8ajxRQ2hSqJwEh9pDr4mVTml9kLMHWDHmgfHkTHRJ1sg==} + '@szmarczak/http-timer@5.0.1': resolution: {integrity: sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==} engines: {node: '>=14.16'} - '@tabler/icons-webfont@3.31.0': - resolution: {integrity: sha512-0a3Uhj9nKU5kYz6/MUIGuX7kRbbrnOvVL3LGnbIcW/fmEQMgVRN0lkXdeIVkIL6/JKDzI2zSm3X5I+hLIpzLog==} + '@tabler/icons-webfont@3.35.0': + resolution: {integrity: sha512-PRnv+lgj2Va6S1nTVcZoYDWZPXUaVNromQ9uxn0B1CbBOjqKXAzC/8yLc8XOXD2fH2DWT2XNw1XaNtlNpc0/Tw==} - '@tabler/icons@3.31.0': - resolution: {integrity: sha512-dblAdeKY3+GA1U+Q9eziZ0ooVlZMHsE8dqP0RkwvRtEsAULoKOYaCUOcJ4oW1DjWegdxk++UAt2SlQVnmeHv+g==} + '@tabler/icons@3.35.0': + resolution: {integrity: sha512-yYXe+gJ56xlZFiXwV9zVoe3FWCGuZ/D7/G4ZIlDtGxSx5CGQK110wrnT29gUj52kEZoxqF7oURTk97GQxELOFQ==} '@tensorflow/tfjs-backend-cpu@4.22.0': resolution: {integrity: sha512-1u0FmuLGuRAi8D2c3cocHTASGXOmHc/4OvoVDENJayjYkS119fcTcQf4iHrtLthWyDIPy3JiPhRrZQC9EwnhLw==} @@ -4483,12 +4529,22 @@ packages: resolution: {integrity: sha512-xGGHpBXYSHUUr6XsKBfs85TWlYKpTc37cSBBVrXcib2MkHLboWlkClhWF37JKlDb9KEq3dHs+f2xR7XJEWGBxA==} engines: {node: '>=14', npm: '>=6', yarn: '>=1'} + '@testing-library/jest-dom@6.9.1': + resolution: {integrity: sha512-zIcONa+hVtVSSep9UT3jZ5rizo2BsxgyDYU7WFD5eICBE7no3881HGeb/QkGfsJs6JTkY1aQhT7rIPC7e+0nnA==} + engines: {node: '>=14', npm: '>=6', yarn: '>=1'} + '@testing-library/user-event@14.5.2': resolution: {integrity: sha512-YAh82Wh4TIrxYLmfGcixwD18oIjyC1pFQC2Y01F2lzV2HTMiYrI0nze0FD0ocB//CKS/7jIUgae+adPqxK5yCQ==} engines: {node: '>=12', npm: '>=6'} peerDependencies: '@testing-library/dom': '>=7.21.4' + '@testing-library/user-event@14.6.1': + resolution: {integrity: sha512-vq7fv0rnt+QTXgPxr5Hjc210p6YKq2kmdziLgnsZGgLJ9e6VAShx1pACLuRjd/AS/sr7phAR58OIIpf0LlmQNw==} + engines: {node: '>=12', npm: '>=6'} + peerDependencies: + '@testing-library/dom': '>=7.21.4' + '@testing-library/vue@8.1.0': resolution: {integrity: sha512-ls4RiHO1ta4mxqqajWRh8158uFObVrrtAPoxk7cIp4HrnQUj/ScKzqz53HxYpG3X6Zb7H2v+0eTGLSoy8HQ2nA==} engines: {node: '>=14'} @@ -4510,22 +4566,15 @@ packages: resolution: {integrity: sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==} engines: {node: '>= 10'} - '@trysound/sax@0.2.0': - resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==} - engines: {node: '>=10.13.0'} - - '@tsd/typescript@5.8.3': - resolution: {integrity: sha512-oKarNCN1QUhG148M88mtZdOlBZWWGcInquef+U8QL7gwJkRuNo5WS45Fjsd+3hM9cDJWGpqSZ4Oo097KDx4IWA==} + '@tsd/typescript@5.9.3': + resolution: {integrity: sha512-JSSdNiS0wgd8GHhBwnMAI18Y8XPhLVN+dNelPfZCXFhy9Lb3NbnFyp9JKxxr54jSUkEJPk3cidvCoHducSaRMQ==} engines: {node: '>=14.17'} - '@twemoji/parser@15.0.0': - resolution: {integrity: sha512-lh9515BNsvKSNvyUqbj5yFu83iIDQ77SwVcsN/SnEGawczhsKU6qWuogewN1GweTi5Imo5ToQ9s+nNTf97IXvg==} + '@twemoji/parser@16.0.0': + resolution: {integrity: sha512-jmuIjkp3OIaEemwMy3sArBwZSuZkRqmueGwRe2Zk4cFzbUJISFBJSZLDUUBNIgq3c+nY49ideYN2OiII6JUqwA==} - '@twemoji/parser@15.1.0': - resolution: {integrity: sha512-3HTiSxPvkWUJ4kZeCvwyKlIwkpTUfBOk6igpBBRQni58ceQMv5YK4smkc8vX/eqOlMMNER/9qobv+Q6Q8LVrqA==} - - '@twemoji/parser@15.1.1': - resolution: {integrity: sha512-CChRzIu6ngkCJOmURBlYEdX5DZSu+bBTtqR60XjBkFrmvplKW7OQsea+i8XwF4bLVlUXBO7ZmHhRPDzfQyLwwg==} + '@twemoji/parser@17.0.0': + resolution: {integrity: sha512-UsFCnivUCUq/UHJhfM3bd3L35VerCi76jYwT5nFNHUnESDKefNav0z2l0jdoFVbcq72n3llr6AQrOlcrStPE1Q==} '@types/accepts@1.3.7': resolution: {integrity: sha512-Pay9fq2lM2wXPWbteBsRAGiWH2hig4ZE2asK+mm7kUzlxRTfL961rj89I6zV/E3PcIkDqyuBEcMxFT7rccugeQ==} @@ -4536,41 +4585,47 @@ packages: '@types/argparse@1.0.38': resolution: {integrity: sha512-ebDJ9b0e702Yr7pWgB0jzm+CX4Srzz8RcXtLJDJB+BSccqMa36uyH/zUsSYao5+BD1ytv3k3rPYCq4mAE1hsXA==} - '@types/aria-query@5.0.4': - resolution: {integrity: sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==} + '@types/aria-query@5.0.1': + resolution: {integrity: sha512-XTIieEY+gvJ39ChLcB4If5zHtPxt3Syj5rgZR+e1ctpmK8NjPf0zFqsz4JpLJT0xla9GFDKjy8Cpu331nrmE1Q==} + + '@types/autosize@4.0.1': + resolution: {integrity: sha512-iPJT/FCaSO79G6j+9n6gmFc5nhxZ1gDrA2UAvb5FslJ6FJQZnDfbBU0qp5vpp0Cbjj7+gOyjuWZ7RrXvRuETaA==} - '@types/autosize@4.0.3': - resolution: {integrity: sha512-o0ZyU3ePp3+KRbhHsY4ogjc+ZQWgVN5h6j8BHW5RII4cFKi6PEKK9QPAcphJVkD0dGpyFnD3VRR0WMvHVjCv9w==} + '@types/babel__core@7.20.0': + resolution: {integrity: sha512-+n8dL/9GWblDO0iU6eZAwEIJVr5DWigtle+Q6HLOrh/pdbXOhOtqzq8VPPE2zvNJzSKY4vH/z3iT3tn0A3ypiQ==} '@types/babel__core@7.20.5': resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} - '@types/babel__generator@7.27.0': - resolution: {integrity: sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==} + '@types/babel__generator@7.6.4': + resolution: {integrity: sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==} - '@types/babel__template@7.4.4': - resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} + '@types/babel__template@7.4.1': + resolution: {integrity: sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==} - '@types/babel__traverse@7.20.7': - resolution: {integrity: sha512-dkO5fhS7+/oos4ciWxyEyjWe48zmG6wbCheo/G2ZnHx4fs3EU6YC6UM8rk56gAjNJ9P3MTH2jo5jb92/K6wbng==} + '@types/babel__traverse@7.28.0': + resolution: {integrity: sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==} '@types/bcryptjs@2.4.6': resolution: {integrity: sha512-9xlo6R2qDs5uixm0bcIqCeMCE6HiQsIyel9KQySStiyqNl2tnj2mP3DX1Nf56MD6KMenNNlBBsy3LJ7gUEQPXQ==} - '@types/body-parser@1.19.5': - resolution: {integrity: sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==} + '@types/body-parser@1.19.6': + resolution: {integrity: sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==} - '@types/braces@3.0.5': - resolution: {integrity: sha512-SQFof9H+LXeWNz8wDe7oN5zu7ket0qwMu5vZubW4GCJ8Kkeh6nBWUz87+KTz/G3Kqsrp0j/W253XJb3KMEeg3w==} + '@types/braces@3.0.1': + resolution: {integrity: sha512-+euflG6ygo4bn0JHtn4pYqcXwRtLvElQ7/nnjDu7iYG56H0+OhCd7d6Ug0IE3WcFpZozBKW2+80FUbv5QGk5AQ==} '@types/canvas-confetti@1.9.0': resolution: {integrity: sha512-aBGj/dULrimR1XDZLtG9JwxX1b4HPRF6CX9Yfwh3NvstZEm1ZL7RBnel4keCPSqs1ANRu1u2Aoz9R+VmtjYuTg==} + '@types/chai@5.2.2': + resolution: {integrity: sha512-8kB30R7Hwqf40JPiKhVzodJs2Qc1ZJ5zuT3uzw5Hq/dhNCl3G3l83jfpdI1e20BP348+fV7VIL/+FxaXkqBmWg==} + '@types/color-convert@2.0.4': resolution: {integrity: sha512-Ub1MmDdyZ7mX//g25uBAoH/mWGd9swVbt8BseymnaE18SU4po/PjmCrHxqIIRjBo3hV/vh1KGr0eMxUhp+t+dQ==} - '@types/color-name@1.1.5': - resolution: {integrity: sha512-j2K5UJqGTxeesj6oQuGpMgifpT5k9HprgQd8D1Y0lOFqKHl3PJu5GMeS4Y5EgjS55AE6OQxf8mPED9uaGbf4Cg==} + '@types/color-name@1.1.1': + resolution: {integrity: sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==} '@types/connect@3.4.36': resolution: {integrity: sha512-P63Zd/JUGq+PdrM1lv0Wv5SBYeA2+CORvbrXbngriYY0jzLUWfQMQQxOhjONEz/wlHOAxOdY7CY65rgQdTjq2w==} @@ -4578,11 +4633,8 @@ packages: '@types/connect@3.4.38': resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} - '@types/content-disposition@0.5.8': - resolution: {integrity: sha512-QVSSvno3dE0MgO76pJhmv4Qyi/j0Yk9pBp0Y7TJ2Tlj+KCgJWY6qX7nnxCOLkZ3VYRSIk1WTxCvwUSdx6CCLdg==} - - '@types/cookie@0.6.0': - resolution: {integrity: sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==} + '@types/content-disposition@0.5.9': + resolution: {integrity: sha512-8uYXI3Gw35MhiVYhG3s295oihrxRyytcRHjSjqnqZVDDy/xcGBRny7+Xj1Wgfhv5QzRtN2hB2dVRBUX9XW3UcQ==} '@types/cookiejar@2.1.5': resolution: {integrity: sha512-he+DHOWReW0nghN24E1WUqM0efK4kI9oTqDm6XmK8ZPe2djZ90BSNdGnIyCLzCPw7/pogPlGbzI2wHGGmi4O/Q==} @@ -4590,8 +4642,11 @@ packages: '@types/debug@4.1.12': resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==} - '@types/disposable-email-domains@1.0.6': - resolution: {integrity: sha512-+jHw0Q4ERuVYIChlUaoSm/VEuuNFeW7JgUU8Rwa9V1ym6q+gkGmBK5sGTDKqlfmsSdI5bFMHKlEatirPFvd8Xw==} + '@types/deep-eql@4.0.2': + resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} + + '@types/disposable-email-domains@1.0.2': + resolution: {integrity: sha512-SDKwyYTjk3y5aZBxxc38yRecpJPjsqn57STz1bNxYYlv4k11bBe7QB8w4llXDTmQXKT1mFvgGmJv+8Zdu3YmJw==} '@types/dlv@1.1.5': resolution: {integrity: sha512-JHOWNfiWepAhfwlSw17kiWrWrk6od2dEQgHltJw9AS0JPFoLZJBge5+Dnil2NfdjAvJ/+vGSX60/BRW20PpUXw==} @@ -4599,17 +4654,23 @@ packages: '@types/doctrine@0.0.9': resolution: {integrity: sha512-eOIHzCUSH7SMfonMG1LsC2f8vxBFtho6NGBznK41R84YzPuvSBzrhEps33IsQiOW9+VL6NQ9DbjQJznk/S4uRA==} + '@types/dom-mediacapture-transform@0.1.11': + resolution: {integrity: sha512-Y2p+nGf1bF2XMttBnsVPHUWzRRZzqUoJAKmiP10b5umnO6DDrWI0BrGDJy1pOHoOULVmGSfFNkQrAlC5dcj6nQ==} + + '@types/dom-webcodecs@0.1.13': + resolution: {integrity: sha512-O5hkiFIcjjszPIYyUSyvScyvrBoV3NOEEZx/pMlsu44TKzWNkLVBBxnxJz42in5n3QIolYOcBYFCPZZ0h8SkwQ==} + '@types/eslint@7.29.0': resolution: {integrity: sha512-VNcvioYDH8/FxaeTKkM4/TiTwt6pBV9E3OfGmvaw8tPl0rrHCJ4Ll15HRT+pMiFAf/MLQvAzC+6RzUMEL9Ceng==} - '@types/estree@1.0.7': - resolution: {integrity: sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==} + '@types/estree@1.0.8': + resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} - '@types/express-serve-static-core@5.0.6': - resolution: {integrity: sha512-3xhRnjJPkULekpSzgtoNYYcTWgEZkp4myc+Saevii5JPnHNvHMRlBSHDbs7Bh1iPPoVTERHEZXyhyLbMEsExsA==} + '@types/express-serve-static-core@4.17.33': + resolution: {integrity: sha512-TPBqmR/HRYI3eC2E5hmiivIzv+bidAfXofM+sbonAGvyDhySGw9/PQZFt2BLOrjUUR++4eJVpx6KnLQK1Fk9tA==} - '@types/express@5.0.3': - resolution: {integrity: sha512-wGA0NX93b19/dZC1J18tKWVIYWyyF2ZjT9vin/NRu0qzzvfVzWjs04iq2rQ3H65vCTQYlRqs3YHfY7zjdV+9Kw==} + '@types/express@4.17.17': + resolution: {integrity: sha512-Q4FmmuLGBG58btUnfS1c1r/NQdlp3DMfGDGig8WhfpA2YRUtEkxAjkZb0yvplJGYdF1fsQ81iMDcH24sSCNC/Q==} '@types/fluent-ffmpeg@2.1.27': resolution: {integrity: sha512-QiDWjihpUhriISNoBi2hJBRUUmoj/BMTYcfz+F+ZM9hHWBYABFAE6hjP/TbCZC0GWwlpa3FzvHH9RzFeRusZ7A==} @@ -4617,8 +4678,8 @@ packages: '@types/glob@8.1.0': resolution: {integrity: sha512-IO+MJPVhoqz+28h1qLAcBEH2+xHMK6MTyHJc7MTnnYb6wsoLR29POVGJ7LycmVXIqyy/4/2ShP5sUwTXuOwb/w==} - '@types/graceful-fs@4.1.9': - resolution: {integrity: sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==} + '@types/graceful-fs@4.1.6': + resolution: {integrity: sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw==} '@types/hammerjs@2.0.46': resolution: {integrity: sha512-ynRvcq6wvqexJ9brDMS4BnBLzmr0e14d6ZJTEShTBWKymQiHwlAyGu0ZPEFI2Fh1U53F7tN9ufClWM5KvqkKOw==} @@ -4635,17 +4696,20 @@ packages: '@types/http-errors@1.8.2': resolution: {integrity: sha512-EqX+YQxINb+MeXaIqYDASb6U6FCHbWjkj4a1CKDBks3d/QiB2+PqBLyO72vLDgAO1wUI4O+9gweRcQK11bTL/w==} - '@types/http-errors@2.0.5': - resolution: {integrity: sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==} - '@types/http-link-header@1.0.7': resolution: {integrity: sha512-snm5oLckop0K3cTDAiBnZDy6ncx9DJ3mCRDvs42C884MbVYPP74Tiq2hFsSDRTyjK6RyDYDIulPiW23ge+g5Lw==} + '@types/istanbul-lib-coverage@2.0.4': + resolution: {integrity: sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==} + '@types/istanbul-lib-coverage@2.0.6': resolution: {integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==} - '@types/istanbul-lib-report@3.0.3': - resolution: {integrity: sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==} + '@types/istanbul-lib-report@3.0.0': + resolution: {integrity: sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==} + + '@types/istanbul-reports@3.0.1': + resolution: {integrity: sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==} '@types/istanbul-reports@3.0.4': resolution: {integrity: sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==} @@ -4671,26 +4735,26 @@ packages: '@types/jsrsasign@10.5.15': resolution: {integrity: sha512-3stUTaSRtN09PPzVWR6aySD9gNnuymz+WviNHoTb85dKu+BjaV4uBbWWGykBBJkfwPtcNZVfTn2lbX00U+yhpQ==} - '@types/linkify-it@5.0.0': - resolution: {integrity: sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==} + '@types/linkify-it@3.0.2': + resolution: {integrity: sha512-HZQYqbiFVWufzCwexrvh694SOim8z2d+xJl5UNamcvQFejLY/2YUtzXHYi3cHdI7PMlS8ejH2slRAOJQ32aNbA==} '@types/long@4.0.2': resolution: {integrity: sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==} - '@types/markdown-it@14.1.2': - resolution: {integrity: sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==} + '@types/markdown-it@12.2.3': + resolution: {integrity: sha512-GKMHFfv3458yYy+v/N8gjufHO6MSZKCOXpZc5GXIWWy8uldwfmPn98vp81gZ5f9SVw8YYBctgfJ22a2d7AOMeQ==} - '@types/matter-js@0.19.8': - resolution: {integrity: sha512-W2ZWG58Lijv/4v768NgpeyFqqiOyslmAU7qqM1Lhz4XBoUgGtZtPz4CjcOKYtqHIak14dvPldslQhltqLTWwsw==} + '@types/matter-js@0.20.2': + resolution: {integrity: sha512-3PPKy3QxvZ89h9+wdBV2488I1JLVs7DEpIkPvgO8JC1mUdiVSO37ZIvVctOTD7hIq8OAL2gJ3ugGSuUip6DhCw==} - '@types/mdast@4.0.4': - resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} + '@types/mdast@4.0.3': + resolution: {integrity: sha512-LsjtqsyF+d2/yFOYaN22dHZI1Cpwkrj+g06G8+qtUKlhovPW89YhqSnfKtMbkgmEtYpH2gydRNULd6y8mciAFg==} - '@types/mdurl@2.0.0': - resolution: {integrity: sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==} + '@types/mdurl@1.0.2': + resolution: {integrity: sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA==} - '@types/mdx@2.0.13': - resolution: {integrity: sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==} + '@types/mdx@2.0.3': + resolution: {integrity: sha512-IgHxcT3RC8LzFLhKwP3gbMPeaK7BM9eBH46OdapPA7yvuIUJ8H6zHZV53J8hGZcTSnt95jANt+rTBNUUc22ACQ==} '@types/methods@1.1.4': resolution: {integrity: sha512-ymXWVrDiCxTBE3+RIrrP533E70eA+9qu7zdWoHuOmGujkYtzf4HQF96b8nwHLqhuf4ykX61IGRIB38CC6/sImQ==} @@ -4701,32 +4765,35 @@ packages: '@types/mime-types@2.1.4': resolution: {integrity: sha512-lfU4b34HOri+kAY5UheuFMWPDOI+OPceBSHZKp69gEyTL/mmJ4cnU6Y/rlme3UL3GyOn6Y42hyIEw0/q8sWx5w==} - '@types/mime@1.3.5': - resolution: {integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==} + '@types/mime@3.0.1': + resolution: {integrity: sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==} '@types/minimatch@5.1.2': resolution: {integrity: sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==} - '@types/minimist@1.2.5': - resolution: {integrity: sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==} + '@types/minimist@1.2.2': + resolution: {integrity: sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==} '@types/ms@0.7.34': resolution: {integrity: sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==} - '@types/mysql@2.15.26': - resolution: {integrity: sha512-DSLCOXhkvfS5WNNPbfn2KdICAmk8lLc+/PNvnPnF7gOdMZCxopXduqv0OQ13y/yA/zXTSikZZqVgybUxOEg6YQ==} + '@types/mysql@2.15.27': + resolution: {integrity: sha512-YfWiV16IY0OeBfBCk8+hXKmdTKrKlwKN1MNKAPBu5JYxLwBEZl7QzeEpGnlZb3VMGJrrGmB84gXiH+ofs/TezA==} + + '@types/node-fetch@2.6.2': + resolution: {integrity: sha512-DHqhlq5jeESLy19TYhLakJ07kNumXWjcDdxXsLUMJZ6ue8VZJj4kLPQVE/2mdHh3xZziNF1xppu5lwmS53HR+A==} - '@types/node-fetch@2.6.12': - resolution: {integrity: sha512-8nneRWKCg3rMtF69nLQJnOYUcbafYeFSjqkw3jCRLsqkWFlHaoQrr5mXmofFGOx3DKn7UfmBMyov8ySvLRVldA==} + '@types/node@20.19.20': + resolution: {integrity: sha512-2Q7WS25j4pS1cS8yw3d6buNCVJukOTeQ39bAnwR6sOJbaxvyCGebzTMypDFN82CxBLnl+lSWVdCCWbRY6y9yZQ==} - '@types/node@22.15.2': - resolution: {integrity: sha512-uKXqKN9beGoMdBfcaTY1ecwz6ctxuJAcUlwE55938g0ZJ8lRxwAZqRz2AJ4pzpt5dHdTPMB863UZ0ESiFUcP7A==} + '@types/node@24.9.1': + resolution: {integrity: sha512-QoiaXANRkSXK6p0Duvt56W208du4P9Uye9hWLWgGMDTEoKPhuenzNcC4vGUmrNkiOKTlIrBoyNQYNpSwfEZXSg==} - '@types/nodemailer@6.4.17': - resolution: {integrity: sha512-I9CCaIp6DTldEg7vyUTZi8+9Vo0hi1/T8gv3C89yk1rSAAzoKQ8H8ki/jBYJSFoH/BisgLP8tkZMlQ91CIquww==} + '@types/nodemailer@6.4.20': + resolution: {integrity: sha512-uj83z0GqwqMUE6RI4EKptPlav0FYE6vpIlqJAnxzu+/sSezRdbH69rSBCMsdW6DdsCAzoFQZ52c2UIlhRVQYDA==} - '@types/normalize-package-data@2.4.4': - resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} + '@types/normalize-package-data@2.4.1': + resolution: {integrity: sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==} '@types/oauth2orize-pkce@0.1.2': resolution: {integrity: sha512-g5rDzqQTTUIJJpY7UWxb0EU1WyURIwOj3TndKC2krEEEmaKrnZXgoEBkR72QY2kp4cJ6N9cF2AqTPJ0Qyg+caA==} @@ -4740,21 +4807,21 @@ packages: '@types/offscreencanvas@2019.3.0': resolution: {integrity: sha512-esIJx9bQg+QYF0ra8GnvfianIY8qWB0GBx54PK5Eps6m+xTj86KLavHv6qDhzKcu5UUOgNfJ2pWaIIV7TRUd9Q==} - '@types/offscreencanvas@2019.7.3': - resolution: {integrity: sha512-ieXiYmgSRXUDeOntE1InxjWyvEelZGP63M+cGuquuRLuIKKT1osnkXjxev9B7d1nXSug5vpunx+gNlbVxMlC9A==} + '@types/offscreencanvas@2019.7.0': + resolution: {integrity: sha512-PGcyveRIpL1XIqK8eBsmRBt76eFgtzuPiSTyKHZxnGemp2yzGzWpjYKAfK3wIMiU7eH+851yEpiuP8JZerTmWg==} '@types/pg-pool@2.0.6': resolution: {integrity: sha512-TaAUE5rq2VQYxab5Ts7WZhKNmuN78Q6PiFonTDdpbx8a1H0M1vhy3rhiMjl+e2iHmogyMw7jZF4FrE6eJUy5HQ==} - '@types/pg@8.11.14': - resolution: {integrity: sha512-qyD11E5R3u0eJmd1lB0WnWKXJGA7s015nyARWljfz5DcX83TKAIlY+QrmvzQTsbIe+hkiFtkyL2gHC6qwF6Fbg==} - - '@types/pg@8.6.1': - resolution: {integrity: sha512-1Kc4oAGzAl7uqUStZCDvaLFqZrW9qWSjXOmBfdgyBP5La7Us6Mg4GBvRlSoaZMhQF/zSj1C8CtKMBkoiT8eL8w==} + '@types/pg@8.15.5': + resolution: {integrity: sha512-LF7lF6zWEKxuT3/OR8wAZGzkg4ENGXFNyiV/JeOt9z5B+0ZVwbql9McqX5c/WStFq1GaGso7H1AzP/qSzmlCKQ==} '@types/prismjs@1.26.5': resolution: {integrity: sha512-AUZTa7hQ2KY5L7AmtSiqxlhWxb4ina0yd8hNbl4TWuqnv/pFP0nDMb3YrfSBf4hJVGLh2YEIBfKaBW/9UEl6IQ==} + '@types/prop-types@15.7.5': + resolution: {integrity: sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==} + '@types/pug@2.0.10': resolution: {integrity: sha512-Sk/uYFOBAB7mb74XcpizmH0KOR2Pv3D2Hmrh1Dmy5BmK3MpdSa5kqZcg6EKBdklU0bFXX9gCfzvpnyUehrPIuA==} @@ -4764,23 +4831,23 @@ packages: '@types/qrcode@1.5.5': resolution: {integrity: sha512-CdfBi/e3Qk+3Z/fXYShipBT13OJ2fDO2Q2w5CIP5anLTLIndQG9z6P1cnm+8zCWSpm5dnxMFd/uREtb0EXuQzg==} - '@types/qs@6.14.0': - resolution: {integrity: sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==} + '@types/qs@6.9.7': + resolution: {integrity: sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==} '@types/random-seed@0.3.5': resolution: {integrity: sha512-CftxcDPAHgs0SLHU2dt+ZlDPJfGqLW3sZlC/ATr5vJDSe5tRLeOne7HMvCOJnFyF8e1U41wqzs3h6AMC613xtA==} - '@types/range-parser@1.2.7': - resolution: {integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==} + '@types/range-parser@1.2.4': + resolution: {integrity: sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==} '@types/ratelimiter@3.4.6': resolution: {integrity: sha512-Bv6WLSXPGLVsBjkizXtn+ef78R92e36/DFQo2wXPTHtp1cYXF6rCULMqf9WcZPAtyMZMvQAtIPeYMA1xAyxghw==} - '@types/react@19.1.8': - resolution: {integrity: sha512-AwAfQ2Wa5bCx9WP8nZL2uMZWod7J7/JSplxbTmBQ5ms6QpqNYm672H0Vu9ZVKVngQ+ii4R/byguVEUZQyeg44g==} + '@types/react@18.0.28': + resolution: {integrity: sha512-RD0ivG1kEztNBdoAK7lekI9M+azSnitIn85h4iOiaLjaTrMjzslhaqCGaI4IyCJ1RljWiLCEu4jyrLLgqxBTew==} - '@types/readdir-glob@1.1.5': - resolution: {integrity: sha512-raiuEPUYqXu+nvtY2Pe8s8FEmZ3x5yAH4VkLdihcPdalvsHltomrRC9BzuStrJ9yk06470hS0Crw0f1pXqD+Hg==} + '@types/readdir-glob@1.1.1': + resolution: {integrity: sha512-ImM6TmoF8bgOwvehGviEj3tRdRBbQujr1N+0ypaln/GWjaerOB26jb93vsRHmdMtvVQZQebOlqt2HROark87mQ==} '@types/redis-info@3.0.3': resolution: {integrity: sha512-VIkNy6JbYI/RLdbPHdm9JQvv6RVld2uE2/6Hdid38Qdq+zvDli2FTpImI8pC5zwp8xS8qVqfzlfyAub8xZEd5g==} @@ -4788,29 +4855,29 @@ packages: '@types/rename@1.0.7': resolution: {integrity: sha512-E9qapfghUGfBMi3jNhsmCKPIp3f2zvNKpaX1BDGLGJNjzpgsZ/RTx7NaNksFjGoJ+r9NvWF1NSM5vVecnNjVmw==} - '@types/resolve@1.20.6': - resolution: {integrity: sha512-A4STmOXPhMUtHH+S6ymgE2GiBSMqf4oTvcQZMcHzokuTLVYzXTB8ttjcgxOVaAp2lGwEdzZ0J+cRbbeevQj1UQ==} + '@types/resolve@1.20.3': + resolution: {integrity: sha512-NH5oErHOtHZYcjCtg69t26aXEk4BN2zLWqf7wnDZ+dpe0iR7Rds1SPGEItl3fca21oOe0n3OCnZ4W7jBxu7FOw==} '@types/rimraf@3.0.2': resolution: {integrity: sha512-F3OznnSLAUxFrCEu/L5PY8+ny8DtcFRjx7fZZ9bycvXRi3KPTRS9HOitGZwvPg0juRhXFWIeKX58cnX5YqLohQ==} - '@types/sanitize-html@2.15.0': - resolution: {integrity: sha512-71Z6PbYsVKfp4i6Jvr37s5ql6if1Q/iJQT80NbaSi7uGaG8CqBMXP0pk/EsURAOuGdk5IJCd/vnzKrR7S3Txsw==} + '@types/sanitize-html@2.16.0': + resolution: {integrity: sha512-l6rX1MUXje5ztPT0cAFtUayXF06DqPhRyfVXareEN5gGCFaP/iwsxIyKODr9XDhfxPpN6vXUFNfo5kZMXCxBtw==} + + '@types/scheduler@0.16.2': + resolution: {integrity: sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==} - '@types/seedrandom@2.4.34': - resolution: {integrity: sha512-ytDiArvrn/3Xk6/vtylys5tlY6eo7Ane0hvcx++TKo6RxQXuVfW0AF/oeWqAj9dN29SyhtawuXstgmPlwNcv/A==} + '@types/seedrandom@2.4.30': + resolution: {integrity: sha512-AnxLHewubLVzoF/A4qdxBGHCKifw8cY32iro3DQX9TPcetE95zBeVt3jnsvtvAUf1vwzMfwzp4t/L2yqPlnjkQ==} '@types/seedrandom@3.0.8': resolution: {integrity: sha512-TY1eezMU2zH2ozQoAFAQFOPpvP15g+ZgSfTZt31AUUH/Rxtnz3H+A/Sv1Snw2/amp//omibc+AEkTaA8KUeOLQ==} - '@types/semver@7.7.0': - resolution: {integrity: sha512-k107IF4+Xr7UHjwDc7Cfd6PRQfbdkiRabXGRjo07b4WyPahFBZCZ1sE+BNxYIJPPg73UkfOsVOLwqVc/6ETrIA==} + '@types/semver@7.7.1': + resolution: {integrity: sha512-FmgJfu+MOcQ370SD0ev7EI8TlCAfKYU+B4m5T3yXc1CiRN94g/SZPtsCkk506aUDtlMnFZvasDwHHUcZUEaYuA==} - '@types/send@0.17.5': - resolution: {integrity: sha512-z6F2D3cOStZvuk2SaP6YrwkNO65iTZcwA2ZkSABegdkAh/lf+Aa/YQndZVfmEXT5vgAp6zv06VQ3ejSVjAny4w==} - - '@types/serve-static@1.15.8': - resolution: {integrity: sha512-roei0UY3LhpOJvjbIP6ZZFngyLKl5dskOtDhxY5THRSpO+ZI+nzJ+m5yUMzGrp89YRa7lvknKkMYjqQFGwA7Sg==} + '@types/serve-static@1.15.1': + resolution: {integrity: sha512-NUo5XNiAdULrJENtJXZZ3fHtfMolzZwczzBbnAeBbqBwG+LaG6YaJtuwzwGSQZ2wsCrxjEhNNjAkKigy3n8teQ==} '@types/serviceworker@0.0.74': resolution: {integrity: sha512-HNt7NJHrjGtCmI3h1+rsb1g/ZY0iy5KaeenfEV7zAWPSaCs49hEUvgH++V1BHNwlLfB3sbjPh3pSiNixfYjb1w==} @@ -4821,8 +4888,8 @@ packages: '@types/simple-oauth2@5.0.7': resolution: {integrity: sha512-8JbWVJbiTSBQP/7eiyGKyXWAqp3dKQZpaA+pdW16FCi32ujkzRMG8JfjoAzdWt6W8U591ZNdHcPtP2D7ILTKuA==} - '@types/sinon@17.0.4': - resolution: {integrity: sha512-RHnIrhfPO3+tJT0s7cFaXGZvsL4bbR3/k7z3P312qMS4JaS2Tk+KiwiLx1S0rQ56ERj00u1/BtdyVd0FY+Pdew==} + '@types/sinon@17.0.3': + resolution: {integrity: sha512-j3uovdn8ewky9kRBG19bOwaZbexJu/XjtkHyjvUgt4xfPFz18dcORIMqnYh66Fx3Powhcr85NT5+er3+oViapw==} '@types/sinonjs__fake-timers@8.1.1': resolution: {integrity: sha512-0kSuKjAS0TrGLJ0M/+8MaFkGsQhZpB6pxOmvS3K8FYI72K//YmdfoW9X2qPsAKh1mkwxGD5zib9s1FIFed6E8g==} @@ -4830,14 +4897,14 @@ packages: '@types/sinonjs__fake-timers@8.1.5': resolution: {integrity: sha512-mQkU2jY8jJEF7YHjHvsQO8+3ughTL1mcnn96igfhONmR+fUPSKIkefQYpSe8bsly2Ep7oQbn/6VG5/9/0qcArQ==} - '@types/sizzle@2.3.9': - resolution: {integrity: sha512-xzLEyKB50yqCUPUJkIsrVvoWNfFUbIZI+RspLWt8u+tIW/BetMBZtgV2LY/2o+tYH8dRvQ+eoPf3NdhQCcLE2w==} + '@types/sizzle@2.3.3': + resolution: {integrity: sha512-JYM8x9EGF163bEyhdJBpR2QX1R5naCJHC8ucJylJ3w9/CVBaskdQ8WqBf8MmQrd1kRvp/a4TS8HJ+bxzR7ZJYQ==} - '@types/stack-utils@2.0.3': - resolution: {integrity: sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==} + '@types/stack-utils@2.0.1': + resolution: {integrity: sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==} - '@types/statuses@2.0.6': - resolution: {integrity: sha512-xMAgYwceFhRA2zY+XbEA7mxYbA093wdiW8Vu6gZPGWy9cmOyU9XesH1tNcEWsKFd5Vzrqx5T3D38PWx1FIIXkA==} + '@types/statuses@2.0.4': + resolution: {integrity: sha512-eqNDvZsCNY49OAXB0Firg/Sc2BgoWsntsLUdybGFOhAfCD6QJ2n9HXUIHGqt5qjrxmMv4wS8WLAw43ZkKcJ8Pw==} '@types/superagent@8.1.9': resolution: {integrity: sha512-pTVjI73witn+9ILmoJdajHGW2jkSaOzhiFYF1Rd3EQ94kymLqB9PjD9ISg7WaALC7+dCHT0FGe9T2LktLq/3GQ==} @@ -4857,11 +4924,11 @@ packages: '@types/tmp@0.2.6': resolution: {integrity: sha512-chhaNf2oKHlRkDGt+tiKE2Z5aJ6qalm7Z9rlLdBwmOiAAf09YQvvoLXjWK4HWPF1xU/fqvMgfNfpVoBscA/tKA==} - '@types/tough-cookie@4.0.5': - resolution: {integrity: sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==} + '@types/tough-cookie@4.0.2': + resolution: {integrity: sha512-Q5vtl1W5ue16D+nIaW8JWebSSraJVlK+EthKn7e7UcD4KWsaSJ8BqGPXNaPghgtcn/fhvrN17Tv8ksUsQpiplw==} - '@types/unist@3.0.3': - resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} + '@types/unist@3.0.2': + resolution: {integrity: sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==} '@types/uuid@9.0.8': resolution: {integrity: sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==} @@ -4869,77 +4936,78 @@ packages: '@types/vary@1.1.3': resolution: {integrity: sha512-XJT8/ZQCL7NUut9QDLf6l24JfAEl7bnNdgxfj50cHIpEPRJLHHDDFOAq6i+GsEmeFfH7NamhBE4c4Thtb2egWg==} + '@types/wawoff2@1.0.2': + resolution: {integrity: sha512-UVq4NxMuBywz5gklafg1HcENrK02trh/q+ifyvO6xktflGXRtf11GYsia3/l5nxg2edFQRlnUT6ivnk898WDiw==} + '@types/web-push@3.6.4': resolution: {integrity: sha512-GnJmSr40H3RAnj0s34FNTcJi1hmWFV5KXugE0mYWnYhgTAHLJ/dJKAwDmvPJYMke0RplY2XE9LnM4hqSqKIjhQ==} + '@types/whatwg-mimetype@3.0.2': + resolution: {integrity: sha512-c2AKvDT8ToxLIOUlN51gTiHXflsfIFisS4pO7pDPoKouJCESkhZnEy623gwP9laCy5lnLDAw1vAzu2vM2YLOrA==} + '@types/ws@8.18.1': resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==} - '@types/yargs-parser@21.0.3': - resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==} + '@types/yargs-parser@21.0.0': + resolution: {integrity: sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==} + + '@types/yargs@17.0.19': + resolution: {integrity: sha512-cAx3qamwaYX9R0fzOIZAlFpo4A+1uBVCxqpKz9D26uTF4srRXaGTTsikQmaotCtNdbhzyUH7ft6p9ktz9s6UNQ==} '@types/yargs@17.0.33': resolution: {integrity: sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==} - '@types/yauzl@2.10.3': - resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==} + '@types/yauzl@2.10.0': + resolution: {integrity: sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw==} - '@typescript-eslint/eslint-plugin@8.31.0': - resolution: {integrity: sha512-evaQJZ/J/S4wisevDvC1KFZkPzRetH8kYZbkgcTRyql3mcKsf+ZFDV1BVWUGTCAW5pQHoqn5gK5b8kn7ou9aFQ==} + '@typescript-eslint/eslint-plugin@8.46.1': + resolution: {integrity: sha512-rUsLh8PXmBjdiPY+Emjz9NX2yHvhS11v0SR6xNJkm5GM1MO9ea/1GoDKlHHZGrOJclL/cZ2i/vRUYVtjRhrHVQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - '@typescript-eslint/parser': ^8.0.0 || ^8.0.0-alpha.0 + '@typescript-eslint/parser': ^8.46.1 eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <5.9.0' + typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/parser@8.31.0': - resolution: {integrity: sha512-67kYYShjBR0jNI5vsf/c3WG4u+zDnCTHTPqVMQguffaWWFs7artgwKmfwdifl+r6XyM5LYLas/dInj2T0SgJyw==} + '@typescript-eslint/parser@8.46.1': + resolution: {integrity: sha512-6JSSaBZmsKvEkbRUkf7Zj7dru/8ZCrJxAqArcLaVMee5907JdtEbKGsZ7zNiIm/UAkpGUkaSMZEXShnN2D1HZA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <5.9.0' + typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/project-service@8.34.0': - resolution: {integrity: sha512-iEgDALRf970/B2YExmtPMPF54NenZUf4xpL3wsCRx/lgjz6ul/l13R81ozP/ZNuXfnLCS+oPmG7JIxfdNYKELw==} + '@typescript-eslint/project-service@8.46.1': + resolution: {integrity: sha512-FOIaFVMHzRskXr5J4Jp8lFVV0gz5ngv3RHmn+E4HYxSJ3DgDzU7fVI1/M7Ijh1zf6S7HIoaIOtln1H5y8V+9Zg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - typescript: '>=4.8.4 <5.9.0' + typescript: '>=4.8.4 <6.0.0' '@typescript-eslint/scope-manager@5.62.0': resolution: {integrity: sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - '@typescript-eslint/scope-manager@8.31.0': - resolution: {integrity: sha512-knO8UyF78Nt8O/B64i7TlGXod69ko7z6vJD9uhSlm0qkAbGeRUSudcm0+K/4CrRjrpiHfBCjMWlc08Vav1xwcw==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@typescript-eslint/scope-manager@8.34.0': - resolution: {integrity: sha512-9Ac0X8WiLykl0aj1oYQNcLZjHgBojT6cW68yAgZ19letYu+Hxd0rE0veI1XznSSst1X5lwnxhPbVdwjDRIomRw==} + '@typescript-eslint/scope-manager@8.46.1': + resolution: {integrity: sha512-weL9Gg3/5F0pVQKiF8eOXFZp8emqWzZsOJuWRUNtHT+UNV2xSJegmpCNQHy37aEQIbToTq7RHKhWvOsmbM680A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/tsconfig-utils@8.34.0': - resolution: {integrity: sha512-+W9VYHKFIzA5cBeooqQxqNriAP0QeQ7xTiDuIOr71hzgffm3EL2hxwWBIIj4GuofIbKxGNarpKqIq6Q6YrShOA==} + '@typescript-eslint/tsconfig-utils@8.46.1': + resolution: {integrity: sha512-X88+J/CwFvlJB+mK09VFqx5FE4H5cXD+H/Bdza2aEWkSb8hnWIQorNcscRl4IEo1Cz9VI/+/r/jnGWkbWPx54g==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - typescript: '>=4.8.4 <5.9.0' + typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/type-utils@8.31.0': - resolution: {integrity: sha512-DJ1N1GdjI7IS7uRlzJuEDCgDQix3ZVYVtgeWEyhyn4iaoitpMBX6Ndd488mXSx0xah/cONAkEaYyylDyAeHMHg==} + '@typescript-eslint/type-utils@8.46.1': + resolution: {integrity: sha512-+BlmiHIiqufBxkVnOtFwjah/vrkF4MtKKvpXrKSPLCkCtAp8H01/VV43sfqA98Od7nJpDcFnkwgyfQbOG0AMvw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <5.9.0' + typescript: '>=4.8.4 <6.0.0' '@typescript-eslint/types@5.62.0': resolution: {integrity: sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - '@typescript-eslint/types@8.31.0': - resolution: {integrity: sha512-Ch8oSjVyYyJxPQk8pMiP2FFGYatqXQfQIaMp+TpuuLlDachRWpUAeEu1u9B/v/8LToehUIWyiKcA/w5hUFRKuQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@typescript-eslint/types@8.34.0': - resolution: {integrity: sha512-9V24k/paICYPniajHfJ4cuAWETnt7Ssy+R0Rbcqo5sSFr3QEZ/8TSoUi9XeXVBGXCaLtwTOKSLGcInCAvyZeMA==} + '@typescript-eslint/types@8.46.1': + resolution: {integrity: sha512-C+soprGBHwWBdkDpbaRC4paGBrkIXxVlNohadL5o0kfhsXqOC6GYH2S/Obmig+I0HTDl8wMaRySwrfrXVP8/pQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@typescript-eslint/typescript-estree@5.62.0': @@ -4951,17 +5019,11 @@ packages: typescript: optional: true - '@typescript-eslint/typescript-estree@8.31.0': - resolution: {integrity: sha512-xLmgn4Yl46xi6aDSZ9KkyfhhtnYI15/CvHbpOy/eR5NWhK/BK8wc709KKwhAR0m4ZKRP7h07bm4BWUYOCuRpQQ==} + '@typescript-eslint/typescript-estree@8.46.1': + resolution: {integrity: sha512-uIifjT4s8cQKFQ8ZBXXyoUODtRoAd7F7+G8MKmtzj17+1UbdzFl52AzRyZRyKqPHhgzvXunnSckVu36flGy8cg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - typescript: '>=4.8.4 <5.9.0' - - '@typescript-eslint/typescript-estree@8.34.0': - resolution: {integrity: sha512-rOi4KZxI7E0+BMqG7emPSK1bB4RICCpF7QD3KCLXn9ZvWoESsOMlHyZPAHyG04ujVplPaHbmEvs34m+wjgtVtg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - typescript: '>=4.8.4 <5.9.0' + typescript: '>=4.8.4 <6.0.0' '@typescript-eslint/utils@5.62.0': resolution: {integrity: sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==} @@ -4969,51 +5031,40 @@ packages: peerDependencies: eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - '@typescript-eslint/utils@8.31.0': - resolution: {integrity: sha512-qi6uPLt9cjTFxAb1zGNgTob4x9ur7xC6mHQJ8GwEzGMGE9tYniublmJaowOJ9V2jUzxrltTPfdG2nKlWsq0+Ww==} + '@typescript-eslint/utils@8.46.1': + resolution: {integrity: sha512-vkYUy6LdZS7q1v/Gxb2Zs7zziuXN0wxqsetJdeZdRe/f5dwJFglmuvZBfTUivCtjH725C1jWCDfpadadD95EDQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <5.9.0' - - '@typescript-eslint/utils@8.34.0': - resolution: {integrity: sha512-8L4tWatGchV9A1cKbjaavS6mwYwp39jql8xUmIIKJdm+qiaeHy5KMKlBrf30akXAWBzn2SqKsNOtSENWUwg7XQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <5.9.0' + typescript: '>=4.8.4 <6.0.0' '@typescript-eslint/visitor-keys@5.62.0': resolution: {integrity: sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - '@typescript-eslint/visitor-keys@8.31.0': - resolution: {integrity: sha512-QcGHmlRHWOl93o64ZUMNewCdwKGU6WItOU52H0djgNmn1EOrhVudrDzXz4OycCRSCPwFCDrE2iIt5vmuUdHxuQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@typescript-eslint/visitor-keys@8.34.0': - resolution: {integrity: sha512-qHV7pW7E85A0x6qyrFn+O+q1k1p3tQCsqIZ1KZ5ESLXY57aTvUd3/a4rdPTeXisvhXn2VQG0VSKUqs8KHF2zcA==} + '@typescript-eslint/visitor-keys@8.46.1': + resolution: {integrity: sha512-ptkmIf2iDkNUjdeu2bQqhFPV1m6qTnFFjg7PPDjxKWaMaP0Z6I9l30Jr3g5QqbZGdw8YdYvLp+XnqnWWZOg/NA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@ungap/structured-clone@1.3.0': - resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==} + '@ungap/structured-clone@1.2.0': + resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} '@vitalets/google-translate-api@9.2.1': resolution: {integrity: sha512-zlwQWSjXUZhbZQ6qwtIQ7GdYXFQmJ4wYqzcrYJUxtvzQQwUP+uKUb/SRJaBOQuBntjBjzcdcJoLFrpCKUbIkOg==} engines: {node: '>=14'} - '@vitejs/plugin-vue@5.2.3': - resolution: {integrity: sha512-IYSLEQj4LgZZuoVpdSUCw3dIynTWQgPlaRP6iAvMle4My0HdYwr5g5wQAfwOeHQBmYwEkqF70nRpSilr6PoUDg==} - engines: {node: ^18.0.0 || >=20.0.0} + '@vitejs/plugin-vue@6.0.1': + resolution: {integrity: sha512-+MaE752hU0wfPFJEUAIxqw18+20euHHdxVtMvbFcOEpjEyfqXH/5DCoTHiVJ0J29EhTJdoTkjEv5YBKU9dnoTw==} + engines: {node: ^20.19.0 || >=22.12.0} peerDependencies: - vite: ^5.0.0 || ^6.0.0 + vite: ^5.0.0 || ^6.0.0 || ^7.0.0 vue: ^3.2.25 - '@vitest/coverage-v8@3.1.2': - resolution: {integrity: sha512-XDdaDOeaTMAMYW7N63AqoK32sYUWbXnTkC6tEbVcu3RlU1bB9of32T+PGf8KZvxqLNqeXhafDFqCkwpf2+dyaQ==} + '@vitest/coverage-v8@3.2.4': + resolution: {integrity: sha512-EyF9SXU6kS5Ku/U82E259WSnvg6c8KTjppUncuNdm5QHpe17mwREHnjDzozC8x9MZ0xfBUFSaLkRv4TMA75ALQ==} peerDependencies: - '@vitest/browser': 3.1.2 - vitest: 3.1.2 + '@vitest/browser': 3.2.4 + vitest: 3.2.4 peerDependenciesMeta: '@vitest/browser': optional: true @@ -5021,14 +5072,14 @@ packages: '@vitest/expect@2.0.5': resolution: {integrity: sha512-yHZtwuP7JZivj65Gxoi8upUN2OzHTi3zVfjwdpu2WrvCZPLwsJ2Ey5ILIPccoW23dd/zQBlJ4/dhi7DWNyXCpA==} - '@vitest/expect@3.1.2': - resolution: {integrity: sha512-O8hJgr+zREopCAqWl3uCVaOdqJwZ9qaDwUP7vy3Xigad0phZe9APxKhPcDNqYYi0rX5oMvwJMSCAXY2afqeTSA==} + '@vitest/expect@3.2.4': + resolution: {integrity: sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig==} - '@vitest/mocker@3.1.2': - resolution: {integrity: sha512-kOtd6K2lc7SQ0mBqYv/wdGedlqPdM/B38paPY+OwJ1XiNi44w3Fpog82UfOibmHaV9Wod18A09I9SCKLyDMqgw==} + '@vitest/mocker@3.2.4': + resolution: {integrity: sha512-46ryTE9RZO/rfDd7pEqFl7etuyzekzEhUbTW3BvmeO/BcCMEgq59BKhek3dXDWgAj4oMK6OZi+vRr1wPW6qjEQ==} peerDependencies: msw: ^2.4.9 - vite: ^5.0.0 || ^6.0.0 + vite: ^5.0.0 || ^6.0.0 || ^7.0.0-0 peerDependenciesMeta: msw: optional: true @@ -5038,96 +5089,110 @@ packages: '@vitest/pretty-format@2.0.5': resolution: {integrity: sha512-h8k+1oWHfwTkyTkb9egzwNMfJAEx4veaPSnMeKbVSjp4euqGSbQlm5+6VHwTr7u4FJslVVsUG5nopCaAYdOmSQ==} - '@vitest/pretty-format@2.1.9': - resolution: {integrity: sha512-KhRIdGV2U9HOUzxfiHmY8IFHTdqtOhIzCpd8WRdJiE7D/HUcZVD0EgQCVjm+Q9gkUXWgBvMmTtZgIG48wq7sOQ==} + '@vitest/pretty-format@2.1.1': + resolution: {integrity: sha512-SjxPFOtuINDUW8/UkElJYQSFtnWX7tMksSGW0vfjxMneFqxVr8YJ979QpMbDW7g+BIiq88RAGDjf7en6rvLPPQ==} '@vitest/pretty-format@3.1.2': resolution: {integrity: sha512-R0xAiHuWeDjTSB3kQ3OQpT8Rx3yhdOAIm/JM4axXxnG7Q/fS8XUwggv/A4xzbQA+drYRjzkMnpYnOGAc4oeq8w==} - '@vitest/pretty-format@3.2.3': - resolution: {integrity: sha512-yFglXGkr9hW/yEXngO+IKMhP0jxyFw2/qys/CK4fFUZnSltD+MU7dVYGrH8rvPcK/O6feXQA+EU33gjaBBbAng==} + '@vitest/pretty-format@3.2.4': + resolution: {integrity: sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA==} - '@vitest/runner@3.1.2': - resolution: {integrity: sha512-bhLib9l4xb4sUMPXnThbnhX2Yi8OutBMA8Yahxa7yavQsFDtwY/jrUZwpKp2XH9DhRFJIeytlyGpXCqZ65nR+g==} + '@vitest/runner@3.2.4': + resolution: {integrity: sha512-oukfKT9Mk41LreEW09vt45f8wx7DordoWUZMYdY/cyAk7w5TWkTRCNZYF7sX7n2wB7jyGAl74OxgwhPgKaqDMQ==} - '@vitest/snapshot@3.1.2': - resolution: {integrity: sha512-Q1qkpazSF/p4ApZg1vfZSQ5Yw6OCQxVMVrLjslbLFA1hMDrT2uxtqMaw8Tc/jy5DLka1sNs1Y7rBcftMiaSH/Q==} + '@vitest/snapshot@3.2.4': + resolution: {integrity: sha512-dEYtS7qQP2CjU27QBC5oUOxLE/v5eLkGqPE0ZKEIDGMs4vKWe7IjgLOeauHsR0D5YuuycGRO5oSRXnwnmA78fQ==} '@vitest/spy@2.0.5': resolution: {integrity: sha512-c/jdthAhvJdpfVuaexSrnawxZz6pywlTPe84LUB2m/4t3rl2fTo9NFGBG4oWgaD+FTgDDV8hJ/nibT7IfH3JfA==} - '@vitest/spy@3.1.2': - resolution: {integrity: sha512-OEc5fSXMws6sHVe4kOFyDSj/+4MSwst0ib4un0DlcYgQvRuYQ0+M2HyqGaauUMnjq87tmUaMNDxKQx7wNfVqPA==} + '@vitest/spy@3.2.4': + resolution: {integrity: sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw==} '@vitest/utils@2.0.5': resolution: {integrity: sha512-d8HKbqIcya+GR67mkZbrzhS5kKhtp8dQLcmRZLGTscGVg7yImT82cIrhtn2L8+VujWcy6KZweApgNmPsTAO/UQ==} - '@vitest/utils@2.1.9': - resolution: {integrity: sha512-v0psaMSkNJ3A2NMrUEHFRzJtDPFn+/VWZ5WxImB21T9fjucJRmS7xCS3ppEnARb9y11OAzaD+P2Ps+b+BGX5iQ==} + '@vitest/utils@2.1.1': + resolution: {integrity: sha512-Y6Q9TsI+qJ2CC0ZKj6VBb+T8UPz593N113nnUykqwANqhgf3QkZeHFlusgKLTqrnVHbj/XDKZcDHol+dxVT+rQ==} '@vitest/utils@3.1.2': resolution: {integrity: sha512-5GGd0ytZ7BH3H6JTj9Kw7Prn1Nbg0wZVrIvou+UWxm54d+WoXXgAgjFJ8wn3LdagWLFSEfpPeyYrByZaGEZHLg==} - '@volar/language-core@2.4.14': - resolution: {integrity: sha512-X6beusV0DvuVseaOEy7GoagS4rYHgDHnTrdOj5jeUb49fW5ceQyP9Ej5rBhqgz2wJggl+2fDbbojq1XKaxDi6w==} + '@vitest/utils@3.2.4': + resolution: {integrity: sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==} + + '@volar/language-core@2.2.4': + resolution: {integrity: sha512-7As47GndxGxsqqYnbreLrfB5NDUeQioPM2LJKUuB4/34c0NpEJ2byVl3c9KYdjIdiEstWZ9JLtLKNTaPWb5jtA==} + + '@volar/language-core@2.4.23': + resolution: {integrity: sha512-hEEd5ET/oSmBC6pi1j6NaNYRWoAiDhINbT8rmwtINugR39loROSlufGdYMF9TaKGfz+ViGs1Idi3mAhnuPcoGQ==} - '@volar/source-map@2.4.14': - resolution: {integrity: sha512-5TeKKMh7Sfxo8021cJfmBzcjfY1SsXsPMMjMvjY7ivesdnybqqS+GxGAoXHAOUawQTwtdUxgP65Im+dEmvWtYQ==} + '@volar/source-map@2.2.4': + resolution: {integrity: sha512-m92FLpR9vB1YEZfiZ+bfgpLrToL/DNkOrorWVep3pffHrwwI4Tx2oIQN+sqHJfKkiT5N3J1owC+8crhAEinfjg==} - '@volar/typescript@2.4.14': - resolution: {integrity: sha512-p8Z6f/bZM3/HyCdRNFZOEEzts51uV8WHeN8Tnfnm2EBv6FDB2TQLzfVx7aJvnl8ofKAOnS64B2O8bImBFaauRw==} + '@volar/source-map@2.4.23': + resolution: {integrity: sha512-Z1Uc8IB57Lm6k7q6KIDu/p+JWtf3xsXJqAX/5r18hYOTpJyBn0KXUR8oTJ4WFYOcDzWC9n3IflGgHowx6U6z9Q==} - '@vue/compiler-core@3.5.13': - resolution: {integrity: sha512-oOdAkwqUfW1WqpwSYJce06wvt6HljgY3fGeM9NcVA1HaYOij3mZG9Rkysn0OHuyUAGMbEbARIpsG+LPVlBJ5/Q==} + '@volar/typescript@2.2.4': + resolution: {integrity: sha512-uAQC53tgEbHO62G8NXMfmBrJAlP2QJ9WxVEEQqqK3I6VSy8frL5LbH3hAWODxiwMWixv74wJLWlKbWXOgdIoRQ==} - '@vue/compiler-core@3.5.16': - resolution: {integrity: sha512-AOQS2eaQOaaZQoL1u+2rCJIKDruNXVBZSiUD3chnUrsoX5ZTQMaCvXlWNIfxBJuU15r1o7+mpo5223KVtIhAgQ==} + '@volar/typescript@2.4.23': + resolution: {integrity: sha512-lAB5zJghWxVPqfcStmAP1ZqQacMpe90UrP5RJ3arDyrhy4aCUQqmxPPLB2PWDKugvylmO41ljK7vZ+t6INMTag==} - '@vue/compiler-dom@3.5.13': - resolution: {integrity: sha512-ZOJ46sMOKUjO3e94wPdCzQ6P1Lx/vhp2RSvfaab88Ajexs0AHeV0uasYhi99WPaogmBlRHNRuly8xV75cNTMDA==} + '@vue/compiler-core@3.5.22': + resolution: {integrity: sha512-jQ0pFPmZwTEiRNSb+i9Ow/I/cHv2tXYqsnHKKyCQ08irI2kdF5qmYedmF8si8mA7zepUFmJ2hqzS8CQmNOWOkQ==} - '@vue/compiler-dom@3.5.16': - resolution: {integrity: sha512-SSJIhBr/teipXiXjmWOVWLnxjNGo65Oj/8wTEQz0nqwQeP75jWZ0n4sF24Zxoht1cuJoWopwj0J0exYwCJ0dCQ==} + '@vue/compiler-dom@3.5.22': + resolution: {integrity: sha512-W8RknzUM1BLkypvdz10OVsGxnMAuSIZs9Wdx1vzA3mL5fNMN15rhrSCLiTm6blWeACwUwizzPVqGJgOGBEN/hA==} - '@vue/compiler-sfc@3.5.13': - resolution: {integrity: sha512-6VdaljMpD82w6c2749Zhf5T9u5uLBWKnVue6XWxprDobftnletJ8+oel7sexFfM3qIxNmVE7LSFGTpv6obNyaQ==} + '@vue/compiler-sfc@3.5.22': + resolution: {integrity: sha512-tbTR1zKGce4Lj+JLzFXDq36K4vcSZbJ1RBu8FxcDv1IGRz//Dh2EBqksyGVypz3kXpshIfWKGOCcqpSbyGWRJQ==} - '@vue/compiler-ssr@3.5.13': - resolution: {integrity: sha512-wMH6vrYHxQl/IybKJagqbquvxpWCuVYpoUJfCqFZwa/JY1GdATAQ+TgVtgrwwMZ0D07QhA99rs/EAAWfvG6KpA==} + '@vue/compiler-ssr@3.5.22': + resolution: {integrity: sha512-GdgyLvg4R+7T8Nk2Mlighx7XGxq/fJf9jaVofc3IL0EPesTE86cP/8DD1lT3h1JeZr2ySBvyqKQJgbS54IX1Ww==} - '@vue/compiler-vue2@2.7.16': - resolution: {integrity: sha512-qYC3Psj9S/mfu9uVi5WvNZIzq+xnXMhOwbTFKKDD7b1lhpnn71jXSFdTQ+WsIEk0ONCd7VV2IMm7ONl6tbQ86A==} + '@vue/language-core@2.0.19': + resolution: {integrity: sha512-A9EGOnvb51jOvnCYoRLnMP+CcoPlbZVxI9gZXE/y2GksRWM6j/PrLEIC++pnosWTN08tFpJgxhSS//E9v/Sg+Q==} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true - '@vue/language-core@2.2.10': - resolution: {integrity: sha512-+yNoYx6XIKuAO8Mqh1vGytu8jkFEOH5C8iOv3i8Z/65A7x9iAOXA97Q+PqZ3nlm2lxf5rOJuIGI/wDtx/riNYw==} + '@vue/language-core@3.1.1': + resolution: {integrity: sha512-qjMY3Q+hUCjdH+jLrQapqgpsJ0rd/2mAY02lZoHG3VFJZZZKLjAlV+Oo9QmWIT4jh8+Rx8RUGUi++d7T9Wb6Mw==} peerDependencies: typescript: '*' peerDependenciesMeta: typescript: optional: true - '@vue/reactivity@3.5.13': - resolution: {integrity: sha512-NaCwtw8o48B9I6L1zl2p41OHo/2Z4wqYGGIK1Khu5T7yxrn+ATOixn/Udn2m+6kZKB/J7cuT9DbWWhRxqixACg==} + '@vue/reactivity@3.5.22': + resolution: {integrity: sha512-f2Wux4v/Z2pqc9+4SmgZC1p73Z53fyD90NFWXiX9AKVnVBEvLFOWCEgJD3GdGnlxPZt01PSlfmLqbLYzY/Fw4A==} - '@vue/runtime-core@3.5.13': - resolution: {integrity: sha512-Fj4YRQ3Az0WTZw1sFe+QDb0aXCerigEpw418pw1HBUKFtnQHWzwojaukAs2X/c9DQz4MQ4bsXTGlcpGxU/RCIw==} + '@vue/runtime-core@3.5.22': + resolution: {integrity: sha512-EHo4W/eiYeAzRTN5PCextDUZ0dMs9I8mQ2Fy+OkzvRPUYQEyK9yAjbasrMCXbLNhF7P0OUyivLjIy0yc6VrLJQ==} - '@vue/runtime-dom@3.5.13': - resolution: {integrity: sha512-dLaj94s93NYLqjLiyFzVs9X6dWhTdAlEAciC3Moq7gzAc13VJUdCnjjRurNM6uTLFATRHexHCTu/Xp3eW6yoog==} + '@vue/runtime-dom@3.5.22': + resolution: {integrity: sha512-Av60jsryAkI023PlN7LsqrfPvwfxOd2yAwtReCjeuugTJTkgrksYJJstg1e12qle0NarkfhfFu1ox2D+cQotww==} - '@vue/server-renderer@3.5.13': - resolution: {integrity: sha512-wAi4IRJV/2SAW3htkTlB+dHeRmpTiVIK1OGLWV1yeStVSebSQQOwGwIq0D3ZIoBj2C2qpgz5+vX9iEBkTdk5YA==} + '@vue/server-renderer@3.5.22': + resolution: {integrity: sha512-gXjo+ao0oHYTSswF+a3KRHZ1WszxIqO7u6XwNHqcqb9JfyIL/pbWrrh/xLv7jeDqla9u+LK7yfZKHih1e1RKAQ==} peerDependencies: - vue: 3.5.13 - - '@vue/shared@3.5.13': - resolution: {integrity: sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ==} + vue: 3.5.22 - '@vue/shared@3.5.16': - resolution: {integrity: sha512-c/0fWy3Jw6Z8L9FmTyYfkpM5zklnqqa9+a6dz3DvONRKW2NEbh46BP0FHuLFSWi2TnQEtp91Z6zOWNrU6QiyPg==} + '@vue/shared@3.5.22': + resolution: {integrity: sha512-F4yc6palwq3TT0u+FYf0Ns4Tfl9GRFURDN2gWG7L1ecIaS/4fCIuFOjMTnCyjsu/OK6vaDKLCrGAa+KvvH+h4w==} - '@vue/test-utils@2.4.6': - resolution: {integrity: sha512-FMxEjOpYNYiFe0GkaHsnJPXFHxQ6m4t8vI/ElPGpMWxZKpmRvQ33OIrvRXemy6yha03RxhOlQuy+gZMC3CQSow==} + '@vue/test-utils@2.4.1': + resolution: {integrity: sha512-VO8nragneNzUZUah6kOjiFmD/gwRjUauG9DROh6oaOeFwX1cZRUNHhdeogE8635cISigXFTtGLUQWx5KCb0xeg==} + peerDependencies: + '@vue/server-renderer': ^3.0.1 + vue: ^3.0.1 + peerDependenciesMeta: + '@vue/server-renderer': + optional: true '@webgpu/types@0.1.38': resolution: {integrity: sha512-7LrhVKz2PRh+DD7+S+PVaFd5HxaWQvoMqBbsV9fNJO1pjUs1P8bM2vQVNfk+3URTqbuTI7gkXi0rfsN0IadoBA==} @@ -5175,9 +5240,9 @@ packages: abbrev@1.1.1: resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==} - abbrev@2.0.0: - resolution: {integrity: sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + abbrev@3.0.1: + resolution: {integrity: sha512-AO2ac6pjRB3SJmGJo+v5/aK6Omggp6fsLrs6wN9bd35ulu4cCwaAU9+7ZhXjeqHVkaHThLuzH0nZr0YpCDhygg==} + engines: {node: ^18.17.0 || >=20.5.0} abort-controller@3.0.0: resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} @@ -5205,19 +5270,14 @@ packages: engines: {node: '>=0.4.0'} hasBin: true - acorn@8.14.1: - resolution: {integrity: sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==} - engines: {node: '>=0.4.0'} - hasBin: true - acorn@8.15.0: resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==} engines: {node: '>=0.4.0'} hasBin: true - adm-zip@0.5.16: - resolution: {integrity: sha512-TGw5yVi4saajsSEgz25grObGHEUaDrniwvA2qwSC060KfqGPdglhvPMA2lPIoxs3PQIItj2iag35fONcQqgUaQ==} - engines: {node: '>=12.0'} + adm-zip@0.5.10: + resolution: {integrity: sha512-x0HvcHqVJNTPk/Bw8JbLWlWoo6Wwnsug0fnYYro1HBrjxZ3G7/AZk7Ahv8JwDe1uIcz8eBqvu86FuF1POiG7vQ==} + engines: {node: '>=6.0'} agent-base@4.3.0: resolution: {integrity: sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==} @@ -5227,6 +5287,10 @@ packages: resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} engines: {node: '>= 6.0.0'} + agent-base@7.1.0: + resolution: {integrity: sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==} + engines: {node: '>= 14'} + agent-base@7.1.3: resolution: {integrity: sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==} engines: {node: '>= 14'} @@ -5272,16 +5336,16 @@ packages: ajv@8.17.1: resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==} - alien-signals@1.0.13: - resolution: {integrity: sha512-OGj9yyTnJEttvzhTUWuscOvtqxq5vrhF7vL9oS0xJ2mK0ItPYP1/y+vCFebfxoEyAz0++1AIwJ5CMr+Fk3nDmg==} + alien-signals@3.0.1: + resolution: {integrity: sha512-ec02Wv5iOg7yG979PH9ykv5KN/KHznOxMlKy/Jr8lnBo3T94d4MUGo7FVdM8B2fM0e94twzEcWCyWzfIyeV19g==} - analytics-utils@1.0.14: - resolution: {integrity: sha512-9v0kPd8v0GuBvfQcg5BO48AElaEAr9IXMAfJWXYMAhrD3QprgozEIUgMp/de0vS136PUOBB+10XQH9eBgBmfMw==} + analytics-utils@1.1.1: + resolution: {integrity: sha512-nRybjTpRAcHVhWb1cvYaOLJaI3R79r8XjMbu5c0wd2jKmANNqSrYwybiU0X3mp+CQQdm4YiAggTXb2cIA8XhUg==} peerDependencies: '@types/dlv': ^1.0.0 - analytics@0.8.16: - resolution: {integrity: sha512-LEFQ47G9V1zVp9WIh2xhnbmSFEJq+WEzSv6voJ5uba88lefiIIYeG2nq87gFu83ocz1qtb9u7XgeaKKVBbbgWA==} + analytics@0.8.19: + resolution: {integrity: sha512-JFgasxpWFiAoqm5UHaGQv9j9OGz+f1KAeQkABYr3Z7YGhiqhQrBpPhIVAIEyttBRJZmew1QwMhN9/bOGGBnpJA==} ansi-colors@4.1.3: resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} @@ -5295,10 +5359,14 @@ packages: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} - ansi-regex@6.1.0: - resolution: {integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==} + ansi-regex@6.0.1: + resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} engines: {node: '>=12'} + ansi-styles@3.2.1: + resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} + engines: {node: '>=4'} + ansi-styles@4.3.0: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} engines: {node: '>=8'} @@ -5370,8 +5438,8 @@ packages: aria-query@5.3.0: resolution: {integrity: sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==} - aria-query@5.3.2: - resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==} + array-buffer-byte-length@1.0.1: + resolution: {integrity: sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==} engines: {node: '>= 0.4'} array-buffer-byte-length@1.0.2: @@ -5401,6 +5469,10 @@ packages: resolution: {integrity: sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==} engines: {node: '>= 0.4'} + arraybuffer.prototype.slice@1.0.3: + resolution: {integrity: sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==} + engines: {node: '>= 0.4'} + arraybuffer.prototype.slice@1.0.4: resolution: {integrity: sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==} engines: {node: '>= 0.4'} @@ -5422,12 +5494,12 @@ packages: asn1@0.2.6: resolution: {integrity: sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==} - asn1js@3.0.6: - resolution: {integrity: sha512-UOCGPYbl0tv8+006qks/dTgV9ajs97X2p0FAbyS2iyCRrmLSRolDaHdp+v/CLgnzHc3fVB+CwYiUmei7ndFcgA==} + asn1js@3.0.5: + resolution: {integrity: sha512-FVnvrKJwpt9LP2lAMl8qZswRNm3T4q9CON+bxldk2iwk3FFpuwhx2FfinyitizWHsVYyaY+y5JzDR0rCMV5yTQ==} engines: {node: '>=12.0.0'} - assert-never@1.4.0: - resolution: {integrity: sha512-5oJg84os6NMQNl27T9LnZkvvqzvAnHu03ShCnoj6bsJwS7L8AO4lf+C/XjK/nvzEqQB744moC6V128RucQd1jA==} + assert-never@1.2.1: + resolution: {integrity: sha512-TaTivMB6pYI1kXwrFlEhLeGfOqoDNdTxjCdwRfFFkEA30Eu+k48W34nlok2EYWJfFFzqaEmichdNM7th6M5HNw==} assert-plus@1.0.0: resolution: {integrity: sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==} @@ -5441,6 +5513,9 @@ packages: resolution: {integrity: sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg==} engines: {node: '>=4'} + ast-v8-to-istanbul@0.3.5: + resolution: {integrity: sha512-9SdXjNheSiE8bALAQCQQuT6fgQaoxJh7IRYrRGZ8/9nv8WhJeC1aXAwN8TbaOssGOukUvyvnkgD9+Yuykvl1aA==} + astral-regex@2.0.0: resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==} engines: {node: '>=8'} @@ -5459,8 +5534,8 @@ packages: async@0.2.10: resolution: {integrity: sha512-eAkdoKxU6/LkKDBzLpT+t6Ff5EtfSF4wx1WfJiPEEV7WNLnDaRXk0oVysiEPm262roaachGexwUv94WhSgN5TQ==} - async@3.2.6: - resolution: {integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==} + async@3.2.4: + resolution: {integrity: sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==} asynckit@0.4.0: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} @@ -5480,8 +5555,8 @@ packages: resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} engines: {node: '>= 0.4'} - avvio@9.1.0: - resolution: {integrity: sha512-fYASnYi600CsH/j9EQov7lECAniYiBFiiAtBNuZYLA2leLe9qOvZzqYHFjtIj6gD2VMoMLP14834LFWvr4IfDw==} + avvio@9.0.0: + resolution: {integrity: sha512-UbYrOXgE/I+knFG+3kJr9AgC7uNo8DG+FGGODpH9Bj1O1kL/QDjBXnTem9leD3VdQKtaHjV3O85DQ7hHh4IIHw==} aws-sdk-client-mock@4.1.0: resolution: {integrity: sha512-h/tOYTkXEsAcV3//6C1/7U4ifSpKyJvb6auveAepqqNJl6TdZaPFEtKjBQNf8UxQdDP850knB2i/whq4zlsxJw==} @@ -5489,17 +5564,17 @@ packages: aws-sign2@0.7.0: resolution: {integrity: sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==} - aws4@1.13.2: - resolution: {integrity: sha512-lHe62zvbTB5eEABUVi/AwVh0ZKY9rMMDhmm+eeyuuUQbQ3+J+fONVQOZyj+DdrvD4BY33uYniyRJ4UJIaSKAfw==} + aws4@1.12.0: + resolution: {integrity: sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==} axios@0.24.0: resolution: {integrity: sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA==} - axios@1.10.0: - resolution: {integrity: sha512-/1xYAC4MP/HEG+3duIhFr4ZQXR4sQXOIe+o6sdqzeykGLx6Upp/1p8MHqhINOvGeP7xyNHe7tsiJByc4SSVUxw==} + axios@1.12.2: + resolution: {integrity: sha512-vMJzPewAlRyOgxV2dU0Cuz2O8zzzx9VYtbJOaBgXFeLc4IV/Eg50n4LowmehOOR61S8ZMpc2K5Sa7g6A4jfkUw==} - b4a@1.6.7: - resolution: {integrity: sha512-OnAYlL5b7LEkALw87fUVafQw5rVR9RjwGd4KUwNQ6DrrNmaVaUCgLipfVlzrPQ4tWOR9P0IXGNOx50jYCCdSJg==} + b4a@1.6.4: + resolution: {integrity: sha512-fpWrvyVHEKyeEvbKZTVOeZF3VSKKWtJxFIxX/jaVPf+cLbGUSitjb49pHLqPV2BUNNZ0LcoeEGfE/YCpyDYHIw==} babel-jest@29.7.0: resolution: {integrity: sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==} @@ -5515,8 +5590,8 @@ packages: resolution: {integrity: sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - babel-preset-current-node-syntax@1.1.0: - resolution: {integrity: sha512-ldYss8SbBlWva1bs28q78Ju5Zq1F+8BrqBZZ0VFhLBvhh6lCpC2o3gDJi/5DRLs9FgYZCnmPYIVFU4lRXCkyUw==} + babel-preset-current-node-syntax@1.0.1: + resolution: {integrity: sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==} peerDependencies: '@babel/core': ^7.0.0 @@ -5536,12 +5611,13 @@ packages: balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - bare-events@2.5.4: - resolution: {integrity: sha512-+gFfDkR8pj4/TrWCGUGWmJIkBwuxPS5F+a5yWjOHQt2hHvNZd5YLzadjmDUtFmMM4y429bnKLa8bYBMHcYdnQA==} - base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + baseline-browser-mapping@2.8.16: + resolution: {integrity: sha512-OMu3BGQ4E7P1ErFsIPpbJh0qvDudM/UuJeHgkAvfWe+0HFJCXh+t/l8L6fVLR55RI/UbKrVLnAXZSVwd9ysWYw==} + hasBin: true + bcrypt-pbkdf@1.0.2: resolution: {integrity: sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==} @@ -5552,8 +5628,8 @@ packages: resolution: {integrity: sha512-aVNobHnJqLiUelTaHat9DZ1qM2w0C0Eym4LPI/3JxOnSokGVdsl1T1kN7TFvsEAD8G47A6VKQ0TVHqbBnYMJlQ==} engines: {node: '>=12.0.0'} - bignumber.js@9.3.0: - resolution: {integrity: sha512-EM7aMFTXbptt/wZdMlBv2t8IViwQL+h6SLHosp8Yf0dqJMTnY6iL32opnAB6kAdL0SZPuvcAzFr31o0c/R3/RA==} + bignumber.js@9.1.1: + resolution: {integrity: sha512-pHm4LsMJ6lzgNGVfZHjMoO8sdoRhOzOH4MLmY65Jg70bpxCKu5iOHNJyfF6OyvYw7t8Fpf35RuzUyqnQsj8Vig==} bin-version-check@5.1.0: resolution: {integrity: sha512-bYsvMqJ8yNGILLz1KP9zKLzQ6YpljV3ln1gqhuLkUtyfGi3qXKGuK2p+U4NAvjVFzDFiBBtOpCOSFNuYYEGZ5g==} @@ -5572,8 +5648,8 @@ packages: blurhash@2.0.5: resolution: {integrity: sha512-cRygWd7kGBQO3VEhPiTgq4Wc43ctsM+o46urrmPOiuAe+07fzlSB9OJVdpgDL0jPqXUVQ9ht7aq7kxOeJHRK+w==} - bn.js@4.12.2: - resolution: {integrity: sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==} + bn.js@4.12.0: + resolution: {integrity: sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==} body-parser@1.20.3: resolution: {integrity: sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==} @@ -5585,11 +5661,11 @@ packages: bowser@2.11.0: resolution: {integrity: sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA==} - brace-expansion@1.1.12: - resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==} + brace-expansion@1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} - brace-expansion@2.0.2: - resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==} + brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} braces@3.0.3: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} @@ -5598,11 +5674,13 @@ packages: broadcast-channel@7.1.0: resolution: {integrity: sha512-InJljddsYWbEL8LBnopnCg+qMQp9KcowvYWOt4YWrjD5HmxzDYKdVbDS1w/ji5rFZdRD58V5UxJPtBdpEbEJYw==} - browser-assert@1.2.1: - resolution: {integrity: sha512-nfulgvOR6S4gt9UKCeGJOuSGBPGiFT6oQ/2UBnvTY/5aQ1PnksW72fhZkM30DzoRRv2WpwZf1vHHEr3mtuXIWQ==} + browserslist@4.24.4: + resolution: {integrity: sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true - browserslist@4.25.0: - resolution: {integrity: sha512-PJ8gYKeS5e/whHBh8xrwYK+dAvEj7JXtz6uTucnMRB8OiGTsKccFekoRrjajPBHV8oOY+2tI4uxeceSimKwMFA==} + browserslist@4.26.3: + resolution: {integrity: sha512-lAUU+02RFBuCKQPj/P6NgjlbCnLBMp4UtgTx7vNHd3XSIJF87s9a5rA3aH2yw3GS9DqZAUbOtZdCCiZeVRqt0w==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true @@ -5635,8 +5713,8 @@ packages: resolution: {integrity: sha512-WDtdLmJvAuNNPzByAYpRo2rF1Mmradw6gvWsQKf63476DDXmomT9zUiGypLcG4ibIM67vhAj8jJRdbmEws2Aqw==} engines: {node: '>=6.14.2'} - bullmq@5.51.1: - resolution: {integrity: sha512-JEZokH5Sb6p66HRjbfQjPNYuSilDRcB8UREmJzOBqTTaJFza8I92vsBF3J/zmtzd7KVv3dxhZyH9CYSLOJALRA==} + bullmq@5.61.0: + resolution: {integrity: sha512-khaTjc1JnzaYFl4FrUtsSsqugAW/urRrcZ9Q0ZE+REAw8W+gkHFqxbGlutOu6q7j7n91wibVaaNlOUMdiEvoSQ==} buraha@0.0.1: resolution: {integrity: sha512-G563A0mTbzknm2jDaNxfZuNKIdeArs8T+XQN6t+KbmgnOoevXSXhKDkyf8Md/36Jrx99ikwbCag37VGe3myExQ==} @@ -5653,9 +5731,9 @@ packages: resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} engines: {node: '>=8'} - cacache@18.0.4: - resolution: {integrity: sha512-B+L5iIa9mgcjLbliir2th36yEwPftrzteHYujzsx3dFP/31GCHcIeS8f5MGd80odLOjaOvSpU3EEAmRQptkxLQ==} - engines: {node: ^16.14.0 || >=18.0.0} + cacache@19.0.1: + resolution: {integrity: sha512-hdsUxulXCi5STId78vRVYEtDAjq99ICAUktLTeTYsLoTE6Z8dS0c8pWNCxwdrk9YfJeobDZc2Y186hD/5ZQgFQ==} + engines: {node: ^18.17.0 || >=20.5.0} cacheable-lookup@7.0.0: resolution: {integrity: sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==} @@ -5665,18 +5743,22 @@ packages: resolution: {integrity: sha512-zkDT5WAF4hSSoUgyfg5tFIxz8XQK+25W/TLVojJTMKBaxevLBBtLxgqguAuVQB8PVW79FVjHcU+GJ9tVbDZ9mQ==} engines: {node: '>=14.16'} - cacheable-request@12.0.1: - resolution: {integrity: sha512-Yo9wGIQUaAfIbk+qY0X4cDQgCosecfBe3V9NSyeY4qPC2SAkbCS4Xj79VP8WOzitpJUZKc/wsRCYF5ariDIwkg==} + cacheable-request@13.0.12: + resolution: {integrity: sha512-qqK/etGeI/9DV5yRkO50ApDTjip9UXPml1NHYJksUAw15yMLOf8VUO1/8bu4P8birOCqR+hYQ/nh1Lezc8sZrA==} engines: {node: '>=18'} - cachedir@2.4.0: - resolution: {integrity: sha512-9EtFOZR8g22CL7BWjJ9BUx1+A/djkofnyW3aOXZORNW2kxoUpx2h+uN2cOqwPmFhnpVmxg+KW2OjOSgChTEvsQ==} + cachedir@2.3.0: + resolution: {integrity: sha512-A+Fezp4zxnit6FanDmv9EqXNAi3vt9DWp51/71UEhXukb7QUuvtv9344h91dyAxuTLoSYJFU299qzR3tzwPAhw==} engines: {node: '>=6'} call-bind-apply-helpers@1.0.2: resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} engines: {node: '>= 0.4'} + call-bind@1.0.7: + resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==} + engines: {node: '>= 0.4'} + call-bind@1.0.8: resolution: {integrity: sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==} engines: {node: '>= 0.4'} @@ -5685,9 +5767,6 @@ packages: resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} engines: {node: '>= 0.4'} - call-me-maybe@1.0.2: - resolution: {integrity: sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ==} - callsites@3.1.0: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} @@ -5707,8 +5786,11 @@ packages: caniuse-api@3.0.0: resolution: {integrity: sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==} - caniuse-lite@1.0.30001723: - resolution: {integrity: sha512-1R/elMjtehrFejxwmexeXAtae5UO9iSyFn6G/I806CYC/BLyyBk1EPhrKBkWhy6wM6Xnm47dSJQec+tLJ39WHw==} + caniuse-lite@1.0.30001699: + resolution: {integrity: sha512-b+uH5BakXZ9Do9iK+CkDmctUSEqZl+SP056vc5usa0PL+ev5OHw003rZXcnjNDv3L8P5j6rwT6C0BPKSikW08w==} + + caniuse-lite@1.0.30001749: + resolution: {integrity: sha512-0rw2fJOmLfnzCRbkm8EyHL8SvI2Apu5UbnQuTsJ0ClgrH8hcwFooJ1s5R0EP8o8aVrFu8++ae29Kt9/gZAZp/Q==} canonicalize@1.0.8: resolution: {integrity: sha512-0CNTVCLZggSh7bc5VkX5WWPWO+cyZbNd07IHIsSXLia/eAq+r836hgk+8BKoEh7949Mda87VUOitx5OddVj64A==} @@ -5734,10 +5816,14 @@ packages: resolution: {integrity: sha512-mCuXncKXk5iCLhfhwTc0izo0gtEmpz5CtG2y8GiOINBlMVS6v8TMRc5TaLWKS6692m9+dVVfzgeVxR5UxWHTYw==} engines: {node: '>=12'} - chalk-template@1.1.0: - resolution: {integrity: sha512-T2VJbcDuZQ0Tb2EWwSotMPJjgpy1/tGee1BTpUNsGZ/qgNjV2t7Mvu+d4600U564nbLesN1x2dPL+xii174Ekg==} + chalk-template@1.1.2: + resolution: {integrity: sha512-2bxTP2yUH7AJj/VAXfcA+4IcWGdQ87HwBANLt5XxGTeomo8yG0y95N1um9i5StvhT/Bl0/2cARA5v1PpPXUxUA==} engines: {node: '>=14.16'} + chalk@2.4.2: + resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} + engines: {node: '>=4'} + chalk@3.0.0: resolution: {integrity: sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==} engines: {node: '>=8'} @@ -5746,10 +5832,13 @@ packages: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} - chalk@5.4.1: - resolution: {integrity: sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==} + chalk@5.6.2: + resolution: {integrity: sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==} engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + change-case@5.4.4: + resolution: {integrity: sha512-HRQyTk2/YPEkt9TnUPbOpr64Uw3KOicFWPVBb+xiHvd6eBx/qPr9xqfBFDT8P2vWsvvz4jbEkfDe71W3VyNu2w==} + char-regex@1.0.2: resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==} engines: {node: '>=10'} @@ -5766,8 +5855,8 @@ packages: character-parser@2.2.0: resolution: {integrity: sha512-+UqJQjFEFaTAs3bNsF2j2kEN1baG/zghZbdqoYEDxGZtJo9LBzl1A+m0D4n3qKx8N2FNv8/Xp6yV9mQmBuptaw==} - chart.js@4.4.9: - resolution: {integrity: sha512-EyZ9wWKgpAU0fLJ43YAEIF8sr5F2W3LqbS40ZJyHIner2lY14ufqv2VMp69MAiZ2rpwxEUxEhIH/0U3xyRynxg==} + chart.js@4.5.1: + resolution: {integrity: sha512-GIjfiT9dbmHRiYi6Nl2yFCq7kkwdkp1W/lp2J99rX0yo9tgJGn3lKQATztIjb5tVtevcBtIdICNWqlq5+E8/Pw==} engines: {pnpm: '>=8'} chartjs-adapter-date-fns@3.0.0: @@ -5776,8 +5865,8 @@ packages: chart.js: '>=2.8.0' date-fns: '>=2.0.0' - chartjs-chart-matrix@2.1.1: - resolution: {integrity: sha512-hJ5NKGYqfM37mnkr3XXIJDn9Eij4G7mbNsNxY1zEmtoVLu/k6HO9yL8sL8vFgVnJbhWqAJdlrb+dlTOFKh8xfA==} + chartjs-chart-matrix@3.0.0: + resolution: {integrity: sha512-lUWC1UaWkxGdG02dBJ5r1ppbSYB/uWmwAh11VEs7V3ZQItNCk4am+rmacwkgeb+SQeEj2hP9Qq4oGsUmPl/1lQ==} peerDependencies: chart.js: '>=3.0.0' @@ -5806,9 +5895,9 @@ packages: resolution: {integrity: sha512-quS9HgjQpdaXOvsZz82Oz7uxtXiy6UIsIQcpBj7HRw2M63Skasm9qlDocAM7jNuaxdhpPU7c4kJN+gA5MCu4ww==} engines: {node: '>=18.17'} - cheerio@1.1.0: - resolution: {integrity: sha512-+0hMx9eYhJvWbgpKV9hN7jg0JcwydpopZE4hgi+KvQtByZXPp04NiCWU0LzcAbP63abZckIHkTQaXVF52mX3xQ==} - engines: {node: '>=18.17'} + cheerio@1.1.2: + resolution: {integrity: sha512-IkxPpb5rS/d1IiLbHMgfPuS0FgiWTtFIm/Nj+2woXDLTZ7fOT2eqzgYbdMlLweqlHbsZjxEChoVK+7iph7jyQg==} + engines: {node: '>=20.18.1'} chokidar@4.0.3: resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} @@ -5822,8 +5911,8 @@ packages: resolution: {integrity: sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==} engines: {node: '>=18'} - chromatic@11.28.2: - resolution: {integrity: sha512-aCmUPcZUs4/p9zRZdMreOoO/5JqO2DiJC3md1/vRx8dlMRcmR/YI5ZbgXZcai2absVR+6hsXZ5XiPxV2sboTuQ==} + chromatic@13.3.0: + resolution: {integrity: sha512-OtXVKSFqGS1x6E6xYzmYX2iImSknbvo5CfTxP3ztFvXQhIAwhJzJuA3XpnIewER9gtWUNnV2DDi8/f9JyZJSfg==} hasBin: true peerDependencies: '@chromatic-com/cypress': ^0.*.* || ^1.0.0 @@ -5834,16 +5923,16 @@ packages: '@chromatic-com/playwright': optional: true - ci-info@3.9.0: - resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} + ci-info@3.7.1: + resolution: {integrity: sha512-4jYS4MOAaCIStSRwiuxc4B8MYhIe676yO1sYGzARnjXkWpmzZMMYxY6zu8WYWDhSuth5zhrQ1rhNSibyyvv4/w==} engines: {node: '>=8'} - ci-info@4.2.0: - resolution: {integrity: sha512-cYY9mypksY8NRqgDB1XD1RiJL338v/551niynFTGkZOO2LHuB2OmOYxDIe/ttN9AHwrqdum1360G3ald0W9kCg==} + ci-info@4.1.0: + resolution: {integrity: sha512-HutrvTNsF48wnxkzERIXOe5/mlcfFcbfCmwcg6CJnizbSue78AbDt+1cgl26zwn61WFxhcPykPfZrbqjGmBb4A==} engines: {node: '>=8'} - cjs-module-lexer@1.4.3: - resolution: {integrity: sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==} + cjs-module-lexer@1.2.2: + resolution: {integrity: sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==} clean-stack@2.2.0: resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} @@ -5862,8 +5951,8 @@ packages: engines: {node: '>=8.0.0', npm: '>=5.0.0'} hasBin: true - cli-table3@0.6.5: - resolution: {integrity: sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==} + cli-table3@0.6.1: + resolution: {integrity: sha512-w0q/enDHhPLq44ovMGdQeeDLvwxwavsJX7oQGYt/LrBlYsyaxyDnp6z3QzFut/6kLLKnlcUVJLrpB7KBfgG/RA==} engines: {node: 10.* || >= 12.*} cli-truncate@2.1.0: @@ -5892,13 +5981,19 @@ packages: resolution: {integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==} engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'} - collect-v8-coverage@1.0.2: - resolution: {integrity: sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==} + collect-v8-coverage@1.0.1: + resolution: {integrity: sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==} + + color-convert@1.9.3: + resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} color-convert@2.0.1: resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} engines: {node: '>=7.0.0'} + color-name@1.1.3: + resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} + color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} @@ -5916,8 +6011,15 @@ packages: colord@2.9.3: resolution: {integrity: sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==} - colorette@2.0.20: - resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} + colorette@1.4.0: + resolution: {integrity: sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g==} + + colorette@2.0.19: + resolution: {integrity: sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==} + + colors@1.4.0: + resolution: {integrity: sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==} + engines: {node: '>=0.1.90'} combined-stream@1.0.8: resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} @@ -5930,6 +6032,10 @@ packages: resolution: {integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==} engines: {node: '>=14'} + commander@11.1.0: + resolution: {integrity: sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==} + engines: {node: '>=16'} + commander@12.1.0: resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==} engines: {node: '>=18'} @@ -5941,10 +6047,6 @@ packages: resolution: {integrity: sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==} engines: {node: '>= 6'} - commander@7.2.0: - resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==} - engines: {node: '>= 10'} - commander@8.3.0: resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==} engines: {node: '>= 12'} @@ -5960,8 +6062,8 @@ packages: compare-versions@6.1.1: resolution: {integrity: sha512-4hm4VPpIecmlg59CHXnRDnqGplJFrbLG4aFEl5vl6cK1u76ws3LLvX7ikFnTDl5vo39sjWD6AaDPYodJp/NNHg==} - complex.js@2.4.2: - resolution: {integrity: sha512-qtx7HRhPGSCBtGiST4/WGHuW+zeaND/6Ld+db6PbrulIB1i2Ev/2UPiqcmpQNPSyfBKraC0EOvOKCB5dGZKt3g==} + complex.js@2.1.1: + resolution: {integrity: sha512-8njCHOTtFFLtegk6zQo0kkVX1rngygb/KQI6z1qZxlFI3scluC+LVTCFbrkWjBv4vvLlbQ9t88IPMC6k95VTTg==} component-emitter@1.3.1: resolution: {integrity: sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==} @@ -5970,18 +6072,21 @@ packages: resolution: {integrity: sha512-6FqVXeETqWPoGcfzrXb37E50NP0LXT8kAMu5ooZayhWWdgEY4lBEEcbQNXtkuKQsGduxiIcI4gOTsxTmuq/bSg==} engines: {node: '>= 14'} + computeds@0.0.1: + resolution: {integrity: sha512-7CEBgcMjVmitjYo5q8JTJVra6X5mQ20uTThdK+0kR7UEaDrAWEQcRiBtWJzga4eRpP6afNwwLsX2SET2JhVB1Q==} + concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} - concat-stream@1.6.2: - resolution: {integrity: sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==} - engines: {'0': node >= 0.8} + concat-stream@2.0.0: + resolution: {integrity: sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==} + engines: {'0': node >= 6.0} config-chain@1.1.13: resolution: {integrity: sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==} - consola@3.4.2: - resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==} + consola@3.4.0: + resolution: {integrity: sha512-EiPU8G6dQG0GFHNR8ljnZFki/8a+cQwEQ+7wpxdChl02Q8HXlwEZWD5lqAF8vC2sEC3Tehr8hy7vErz88LHyUA==} engines: {node: ^14.18.0 || >=16.10.0} console-control-strings@1.1.0: @@ -5998,19 +6103,26 @@ packages: resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} engines: {node: '>= 0.6'} + convert-source-map@1.9.0: + resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} + convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} cookie-signature@1.0.6: resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==} + cookie@0.6.0: + resolution: {integrity: sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==} + engines: {node: '>= 0.6'} + cookie@0.7.1: resolution: {integrity: sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==} engines: {node: '>= 0.6'} - cookie@0.7.2: - resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} - engines: {node: '>= 0.6'} + cookie@1.0.1: + resolution: {integrity: sha512-Xd8lFX4LM9QEEwxQpF9J9NTUh8pmdJO0cyRJhFiDoLTk2eH8FXlRv2IFGYVadZpqI3j8fhNrSdKCeYPxiAhLXw==} + engines: {node: '>=18'} cookie@1.0.2: resolution: {integrity: sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==} @@ -6050,19 +6162,25 @@ packages: resolution: {integrity: sha512-p0SaNjrHOnQeR8/VnfGbmg9te2kfyYSQ7Sc/j/6DtPL3JQvKxmjO9TSjNFpujqV3vEYYBvNNvXSxzyksBWAx1Q==} engines: {node: '>=12.0.0'} - cropperjs@2.0.0: - resolution: {integrity: sha512-TO2j0Qre01kPHbow4FuTrbdEB4jTmGRySxW49jyEIqlJZuEBfrvCTT0vC3eRB2WBXudDfKi1Onako6DKWKxeAQ==} + cropperjs@2.0.1: + resolution: {integrity: sha512-hiJwk2SCPZqxMA7aR3byzLpYUqOrQo+ihMk8k/WRm/xe/LX8wNzAIzMwEB/NEGJYA6sbewxW9TUlrRUYi/2Ipg==} + + cross-env@10.1.0: + resolution: {integrity: sha512-GsYosgnACZTADcmEyJctkJIoqAhHjttw7RsFrVoJNXbsWWqaq6Ym+7kZjq6mS45O0jij6vtiReppKQEtqWy6Dw==} + engines: {node: '>=20'} + hasBin: true cross-env@7.0.3: resolution: {integrity: sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==} engines: {node: '>=10.14', npm: '>=6', yarn: '>=1'} hasBin: true - cross-fetch@3.2.0: - resolution: {integrity: sha512-Q+xVJLoGOeIMXZmbUK4HYk+69cQH6LudR0Vu/pRm2YlU/hDV9CiS0gKUMaWY5f2NeUH9C1nV3bsTlCo0FsTV1Q==} + cross-fetch@4.0.0: + resolution: {integrity: sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==} - cross-fetch@4.1.0: - resolution: {integrity: sha512-uKm5PU+MHTootlWEY+mZ4vvXoCn4fLQxT9dSc1sXVMSFkINTJVN8cAQROpwcKm8bJ/c7rgZVIBWzH5T78sNZZw==} + cross-spawn@7.0.3: + resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} + engines: {node: '>= 8'} cross-spawn@7.0.6: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} @@ -6081,8 +6199,8 @@ packages: resolution: {integrity: sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==} engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'} - css-tree@2.3.1: - resolution: {integrity: sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==} + css-tree@3.1.0: + resolution: {integrity: sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w==} engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} css-what@6.1.0: @@ -6097,8 +6215,8 @@ packages: engines: {node: '>=4'} hasBin: true - cssnano-preset-default@7.0.7: - resolution: {integrity: sha512-jW6CG/7PNB6MufOrlovs1TvBTEVmhY45yz+bd0h6nw3h6d+1e+/TX+0fflZ+LzvZombbT5f+KC063w9VoHeHow==} + cssnano-preset-default@7.0.9: + resolution: {integrity: sha512-tCD6AAFgYBOVpMBX41KjbvRh9c2uUjLXRyV7KHSIrwHiq5Z9o0TFfUCoM3TwVrRsRteN3sVXGNvjVNxYzkpTsA==} engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} peerDependencies: postcss: ^8.4.32 @@ -6109,48 +6227,60 @@ packages: peerDependencies: postcss: ^8.4.32 - cssnano@7.0.6: - resolution: {integrity: sha512-54woqx8SCbp8HwvNZYn68ZFAepuouZW4lTwiMVnBErM3VkO7/Sd4oTOt3Zz3bPx3kxQ36aISppyXj2Md4lg8bw==} + cssnano@7.1.1: + resolution: {integrity: sha512-fm4D8ti0dQmFPeF8DXSAA//btEmqCOgAc/9Oa3C1LW94h5usNrJEfrON7b4FkPZgnDEn6OUs5NdxiJZmAtGOpQ==} engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} peerDependencies: - postcss: ^8.4.31 + postcss: ^8.4.32 csso@5.0.5: resolution: {integrity: sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==} engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'} - cssstyle@4.4.0: - resolution: {integrity: sha512-W0Y2HOXlPkb2yaKrCVRjinYKciu/qSLEmK0K9mcfDei3zwlnHFEHAs/Du3cIRwPqY+J4JsiBzUjoHyc8RsJ03A==} + cssstyle@4.2.1: + resolution: {integrity: sha512-9+vem03dMXG7gDmZ62uqmRiMRNtinIZ9ZyuF6BdxzfOD+FdN5hretzynkn0ReS2DO2GSw76RWHs0UmJPI2zUjw==} engines: {node: '>=18'} csstype@3.1.3: resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} - cypress@14.3.2: - resolution: {integrity: sha512-n+yGD2ZFFKgy7I3YtVpZ7BcFYrrDMcKj713eOZdtxPttpBjCyw/R8dLlFSsJPouneGN7A/HOSRyPJ5+3/gKDoA==} - engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} + cypress@15.4.0: + resolution: {integrity: sha512-+GC/Y/LXAcaMCzfuM7vRx5okRmonceZbr0ORUAoOrZt/5n2eGK8yh04bok1bWSjZ32wRHrZESqkswQ6biArN5w==} + engines: {node: ^20.1.0 || ^22.0.0 || >=24.0.0} hasBin: true dashdash@1.14.1: resolution: {integrity: sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==} engines: {node: '>=0.10'} - data-uri-to-buffer@4.0.1: - resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==} + data-uri-to-buffer@4.0.0: + resolution: {integrity: sha512-Vr3mLBA8qWmcuschSLAOogKgQ/Jwxulv3RNE4FXnYWRGujzrRWQI4m12fQqRkwX06C0KanhLr4hK+GydchZsaA==} engines: {node: '>= 12'} data-urls@5.0.0: resolution: {integrity: sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==} engines: {node: '>=18'} + data-view-buffer@1.0.1: + resolution: {integrity: sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==} + engines: {node: '>= 0.4'} + data-view-buffer@1.0.2: resolution: {integrity: sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==} engines: {node: '>= 0.4'} + data-view-byte-length@1.0.1: + resolution: {integrity: sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==} + engines: {node: '>= 0.4'} + data-view-byte-length@1.0.2: resolution: {integrity: sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==} engines: {node: '>= 0.4'} + data-view-byte-offset@1.0.0: + resolution: {integrity: sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==} + engines: {node: '>= 0.4'} + data-view-byte-offset@1.0.1: resolution: {integrity: sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==} engines: {node: '>= 0.4'} @@ -6184,6 +6314,15 @@ packages: supports-color: optional: true + debug@4.3.5: + resolution: {integrity: sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + debug@4.4.0: resolution: {integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==} engines: {node: '>=6.0'} @@ -6193,8 +6332,8 @@ packages: supports-color: optional: true - debug@4.4.1: - resolution: {integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==} + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} engines: {node: '>=6.0'} peerDependencies: supports-color: '*' @@ -6210,6 +6349,9 @@ packages: resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==} engines: {node: '>=0.10.0'} + decimal.js@10.4.3: + resolution: {integrity: sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==} + decimal.js@10.5.0: resolution: {integrity: sha512-8vDa8Qxvr/+d94hSh5P3IJwI5t8/c0KsMp+g8bNw9cY2icONa5aPfvKeieW1WlG0WQYwwhJ7mjui2xtiePQSXw==} @@ -6221,15 +6363,23 @@ packages: resolution: {integrity: sha512-69NZfbKIzux1vBOd31al3XnMnH+2mqDhEgLdpygErm4d60N+UwA5Sq5WFjmEDQzumgB9fElojGwWG0vybVfFmA==} engines: {node: '>=8.6'} - decode-named-character-reference@1.2.0: - resolution: {integrity: sha512-c6fcElNV6ShtZXmsgNgFFV5tVX2PaV4g+MOAkb8eXHvn6sryJBrZa9r0zV6+dtTyoCKxtDy5tyQ5ZwQuidtd+Q==} + decode-named-character-reference@1.0.2: + resolution: {integrity: sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==} decompress-response@6.0.0: resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} engines: {node: '>=10'} - dedent@1.6.0: - resolution: {integrity: sha512-F1Z+5UCFpmQUzJa11agbyPVMbpgT/qA3/SKyJ1jyBgm7dUcUEa8v9JwDkerSQXfakBwFljIxhOJqGkjUwZ9FSA==} + dedent@1.5.1: + resolution: {integrity: sha512-+LxW+KLWxu3HW3M2w2ympwtqPrqYRzU8fqi6Fhd18fBALe15blJPI/I4+UHveMVG6lJqB4JNd4UG0S5cnVHwIg==} + peerDependencies: + babel-plugin-macros: ^3.1.0 + peerDependenciesMeta: + babel-plugin-macros: + optional: true + + dedent@1.7.0: + resolution: {integrity: sha512-HGFtf8yhuhGhqO07SV79tRp+br4MnbdjeVxotpn1QBl30pcLLCQjX5b2295ll0fv8RKDKsmWYrl05usHM9CewQ==} peerDependencies: babel-plugin-macros: ^3.1.0 peerDependenciesMeta: @@ -6243,15 +6393,14 @@ packages: resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} engines: {node: '>=6'} - deep-equal@2.2.3: - resolution: {integrity: sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==} - engines: {node: '>= 0.4'} + deep-equal@2.2.0: + resolution: {integrity: sha512-RdpzE0Hv4lhowpIUKKMJfeH6C1pXdtT1/it80ubgWqwI3qpuxUBpC1S4hnHg+zjnuOoDkzUtUCEEkG+XG5l3Mw==} deep-is@0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} - deepmerge@4.3.1: - resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} + deepmerge@4.2.2: + resolution: {integrity: sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==} engines: {node: '>=0.10.0'} defaults@3.0.0: @@ -6302,8 +6451,8 @@ packages: engines: {node: '>=0.10'} hasBin: true - detect-libc@2.0.4: - resolution: {integrity: sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==} + detect-libc@2.0.3: + resolution: {integrity: sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==} engines: {node: '>=8'} detect-newline@3.1.0: @@ -6327,8 +6476,8 @@ packages: resolution: {integrity: sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==} engines: {node: '>=0.3.1'} - dijkstrajs@1.0.3: - resolution: {integrity: sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA==} + dijkstrajs@1.0.2: + resolution: {integrity: sha512-QV6PMaHTCNmKSeP6QoXhVTw9snc9VD8MulTT0Bd99Pacp4SS1cjcrYPgBPmibqKVtMJJfqC6XvOXgPMEEPH/fg==} dir-glob@3.0.1: resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} @@ -6381,6 +6530,9 @@ packages: domutils@2.8.0: resolution: {integrity: sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==} + domutils@3.1.0: + resolution: {integrity: sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==} + domutils@3.2.2: resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==} @@ -6399,8 +6551,8 @@ packages: duplexer@0.1.2: resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==} - duplexify@4.1.3: - resolution: {integrity: sha512-M3BmBhwJRZsSx38lZyhE53Csddgzl5R7xGJNk7CVddZD6CcmwMCH8J+7AprIrQKH7TonKxaCjcv27Qmf+sQ+oA==} + duplexify@4.1.2: + resolution: {integrity: sha512-fz3OjcNCHmRP12MJoZMPglx8m4rrFP8rovnk4vT8Fs+aonZoCwGg10dSsQsfP/E62eZcPTMSMP6686fu9Qlqtw==} eastasianwidth@0.2.0: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} @@ -6419,8 +6571,11 @@ packages: ee-first@1.1.1: resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} - electron-to-chromium@1.5.167: - resolution: {integrity: sha512-LxcRvnYO5ez2bMOFpbuuVuAI5QNeY1ncVytE/KXaL6ZNfzX1yPlAO0nSOyIHx2fVAuUprMqPs/TdVhUFZy7SIQ==} + electron-to-chromium@1.5.101: + resolution: {integrity: sha512-L0ISiQrP/56Acgu4/i/kfPwWSgrzYZUnQrC0+QPFuhqlLP1Ir7qzPPDVS9BcKIyWTRU8+o6CC8dKw38tSWhYIA==} + + electron-to-chromium@1.5.234: + resolution: {integrity: sha512-RXfEp2x+VRYn8jbKfQlRImzoJU01kyDvVPBmG39eU2iuRVhuS6vQNocB8J0/8GrIMLnPzgz4eW6WiRnJkTuNWg==} emittery@0.13.1: resolution: {integrity: sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==} @@ -6440,6 +6595,9 @@ packages: resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} engines: {node: '>= 0.8'} + encoding-sniffer@0.2.0: + resolution: {integrity: sha512-ju7Wq1kg04I3HtiYIOrUrdfdDvkyO9s5XM8QAj/bN61Yo/Vb4vgJxy5vi4Yxk01gWHbrofpPtpxM8bKger9jhg==} + encoding-sniffer@0.2.1: resolution: {integrity: sha512-5gvq20T6vfpekVtqrYQsSCFZ1wEg5+wW0/QaZMWkFr6BqD3NfKs0rLCx4rrVlSWJeZb5NBJgVLswK/w2MWU+Gw==} @@ -6449,13 +6607,15 @@ packages: end-of-stream@1.4.4: resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} - enquirer@2.4.1: - resolution: {integrity: sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==} + enquirer@2.3.6: + resolution: {integrity: sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==} engines: {node: '>=8.6'} - ent@2.2.2: - resolution: {integrity: sha512-kKvD1tO6BM+oK9HzCPpUdRb4vKFQY/FPTFmurMvh6LlN68VMrdj77w8yp51/kDbpkFOS9J8w5W6zIzgM2H8/hw==} - engines: {node: '>= 0.4'} + ent@2.2.0: + resolution: {integrity: sha512-GHrMyVZQWvTIdDtpiEXdHZnFQKzeO09apj8Cbl4pKWy4i0Oprcq17usfDt5aO63swf0JOeMWjWQE/LzgSRuWpA==} + + entities@2.1.0: + resolution: {integrity: sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==} entities@2.2.0: resolution: {integrity: sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==} @@ -6464,8 +6624,12 @@ packages: resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} engines: {node: '>=0.12'} - entities@6.0.1: - resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==} + entities@6.0.0: + resolution: {integrity: sha512-aKstq2TDOndCn4diEyp9Uq/Flu2i1GlLkc6XIDQSDMuaFE3OPW5OphLCyQ5SpSJZTb4reN+kTcYru5yIfXoRPw==} + engines: {node: '>=0.12'} + + entities@7.0.0: + resolution: {integrity: sha512-FDWG5cmEYf2Z00IkYRhbFrwIwvdFKH07uV8dvNy0omp/Qb1xcyCWp2UDtcwJF4QZZvk0sLudP6/hAu42TaqVhQ==} engines: {node: '>=0.12'} env-paths@2.2.1: @@ -6478,6 +6642,10 @@ packages: error-ex@1.3.2: resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} + es-abstract@1.23.3: + resolution: {integrity: sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==} + engines: {node: '>= 0.4'} + es-abstract@1.24.0: resolution: {integrity: sha512-WSzPgsdLtTcQwm4CROfS5ju2Wa1QQcVeT37jFjYzdFz1r9ahadC8B8/a4qxJxM+09F18iumCdRmlr96ZYkQvEg==} engines: {node: '>= 0.4'} @@ -6504,16 +6672,23 @@ packages: resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} engines: {node: '>= 0.4'} + es-shim-unscopables@1.0.2: + resolution: {integrity: sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==} + es-shim-unscopables@1.1.0: resolution: {integrity: sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==} engines: {node: '>= 0.4'} + es-to-primitive@1.2.1: + resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==} + engines: {node: '>= 0.4'} + es-to-primitive@1.3.0: resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==} engines: {node: '>= 0.4'} - es-toolkit@1.39.3: - resolution: {integrity: sha512-Qb/TCFCldgOy8lZ5uC7nLGdqJwSabkQiYQShmw4jyiPk1pZzaYWTwaYKYP7EgLccWYgZocMrtItrwh683voaww==} + es-toolkit@1.27.0: + resolution: {integrity: sha512-ETSFA+ZJArcuSCpzD2TjAy6UHpx4E4uqFsoDg9F/nTLogrLmVVZQ+zNxco5h7cWnA1nNak07IXsLcaSMih+ZPQ==} es6-promise@4.2.8: resolution: {integrity: sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==} @@ -6521,21 +6696,20 @@ packages: es6-promisify@5.0.0: resolution: {integrity: sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ==} - esbuild-register@3.6.0: - resolution: {integrity: sha512-H2/S7Pm8a9CL1uhp9OvjwrBh5Pvx0H8qVOxNu8Wed9Y7qv56MPtq+GGM8RJpq6glYJn9Wspr8uw7l55uyinNeg==} + esbuild-register@3.5.0: + resolution: {integrity: sha512-+4G/XmakeBAsvJuDugJvtyF1x+XJT4FMocynNpxrvEBViirpfUn2PgNpCHedfWhF4WokNsO/OvMKrmJOIJsI5A==} peerDependencies: esbuild: '>=0.12 <1' - esbuild@0.21.5: - resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} - engines: {node: '>=12'} - hasBin: true - - esbuild@0.25.3: - resolution: {integrity: sha512-qKA6Pvai73+M2FtftpNKRxJ78GIjmFXFxd/1DVBqGo/qNhLSfv+G12n9pNoWdytJC8U00TrViOwpjT0zgqQS8Q==} + esbuild@0.25.10: + resolution: {integrity: sha512-9RiGKvCwaqxO2owP61uQ4BgNborAQskMR6QusfWzQqv7AZOg5oGehdY2pRJMTKuwxd1IDBP4rSbI5lHzU7SMsQ==} engines: {node: '>=18'} hasBin: true + escalade@3.1.1: + resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} + engines: {node: '>=6'} + escalade@3.2.0: resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} engines: {node: '>=6'} @@ -6581,8 +6755,8 @@ packages: eslint-import-resolver-node@0.3.9: resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==} - eslint-module-utils@2.12.0: - resolution: {integrity: sha512-wALZ0HFoytlyh/1+4wuZ9FJCD/leWHQzzrxJ8+rebyReSLk7LApMyd3WJaLVoN+D5+WIdJyDK1c6JnE65V4Zyg==} + eslint-module-utils@2.12.1: + resolution: {integrity: sha512-L8jSWTze7K2mTg0vos/RuLRS5soomksDPoJLXIslC7c8Wmut3bx7CPpJijDcBZtxQ5lrbUdM+s0OlNbz0DCDNw==} engines: {node: '>=4'} peerDependencies: '@typescript-eslint/parser': '*' @@ -6602,8 +6776,8 @@ packages: eslint-import-resolver-webpack: optional: true - eslint-plugin-import@2.31.0: - resolution: {integrity: sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A==} + eslint-plugin-import@2.32.0: + resolution: {integrity: sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==} engines: {node: '>=4'} peerDependencies: '@typescript-eslint/parser': '*' @@ -6612,18 +6786,25 @@ packages: '@typescript-eslint/parser': optional: true - eslint-plugin-storybook@0.6.15: - resolution: {integrity: sha512-lAGqVAJGob47Griu29KXYowI4G7KwMoJDOkEip8ujikuDLxU+oWJ1l0WL6F2oDO4QiyUFXvtDkEkISMOPzo+7w==} + eslint-plugin-storybook@0.6.13: + resolution: {integrity: sha512-smd+CS0WH1jBqUEJ3znGS7DU4ayBE9z6lkQAK2yrSUv1+rq8BT/tiI5C/rKE7rmiqiAfojtNYZRhzo5HrulccQ==} engines: {node: 12.x || 14.x || >= 16} peerDependencies: eslint: '>=6' - eslint-plugin-vue@10.0.0: - resolution: {integrity: sha512-XKckedtajqwmaX6u1VnECmZ6xJt+YvlmMzBPZd+/sI3ub2lpYZyFnsyWo7c3nMOQKJQudeyk1lw/JxdgeKT64w==} + eslint-plugin-vue@10.5.0: + resolution: {integrity: sha512-7BZHsG3kC2vei8F2W8hnfDi9RK+cv5eKPMvzBdrl8Vuc0hR5odGQRli8VVzUkrmUHkxFEm4Iio1r5HOKslO0Aw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: + '@stylistic/eslint-plugin': ^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0 + '@typescript-eslint/parser': ^7.0.0 || ^8.0.0 eslint: ^8.57.0 || ^9.0.0 vue-eslint-parser: ^10.0.0 + peerDependenciesMeta: + '@stylistic/eslint-plugin': + optional: true + '@typescript-eslint/parser': + optional: true eslint-rule-docs@1.1.235: resolution: {integrity: sha512-+TQ+x4JdTnDoFEXXb3fDvfGOwnyNV7duH8fXWTPD1ieaBmB8omj7Gw/pMBBu4uI2uJCCU8APDaQJzWuXnTsH4A==} @@ -6632,6 +6813,10 @@ packages: resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} engines: {node: '>=8.0.0'} + eslint-scope@8.3.0: + resolution: {integrity: sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + eslint-scope@8.4.0: resolution: {integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -6640,12 +6825,16 @@ packages: resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + eslint-visitor-keys@4.2.0: + resolution: {integrity: sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + eslint-visitor-keys@4.2.1: resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - eslint@9.25.1: - resolution: {integrity: sha512-E6Mtz9oGQWDCpV12319d59n4tx9zOTXSTmc8BLVxBx+G/0RdM5MvEEJLU9c0+aleoePYYgVTOsRblx433qmhWQ==} + eslint@9.37.0: + resolution: {integrity: sha512-XyLmROnACWqSxiGYArdef1fItQd47weqB7iwtfr9JHwRrqIXZdcFMvvEcL9xHCmL0SNsOvF0c42lWyM1U5dgig==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} hasBin: true peerDependencies: @@ -6654,8 +6843,12 @@ packages: jiti: optional: true - esm-resolve@1.0.11: - resolution: {integrity: sha512-LxF0wfUQm3ldUDHkkV2MIbvvY0TgzIpJ420jHSV1Dm+IlplBEWiJTKWM61GtxUfvjV6iD4OtTYFGAGM2uuIUWg==} + esm-resolve@1.0.9: + resolution: {integrity: sha512-qVENG+4e2s5HO/TMV9LvjpOVNW4HlaZn98q7h0y9R524M1chXNAwrn2bKx+wQs9Qryb22qX8P0rQ5N3e3Udq/w==} + + espree@10.3.0: + resolution: {integrity: sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} espree@10.4.0: resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==} @@ -6740,8 +6933,8 @@ packages: resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} engines: {node: '>=16.17'} - execa@9.5.2: - resolution: {integrity: sha512-EHlpxMCpHWSAh1dgS6bVeoLAXGnJNdR93aabr4QCGbzOM73o5XmRfM/e5FUqsw3aagP8S8XEWUWFAxnRBnAF0Q==} + execa@9.6.0: + resolution: {integrity: sha512-jpWzZ1ZhwUmeWRhS7Qv3mhpOhLfwI+uAX4e5fOcXqwMR7EcJ0pj2kV1CVzHVMX/LphnKWD3LObjZCoJ71lKpHw==} engines: {node: ^18.19.0 || >=20.5.0} executable@4.1.1: @@ -6760,8 +6953,12 @@ packages: resolution: {integrity: sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - exponential-backoff@3.1.2: - resolution: {integrity: sha512-8QxYTVXUkuy7fIIoitQkPwGonB8F3Zj8eEO8Sqg9Zv/bkI7RJAzowee4gr81Hak/dUTpA2Z7VfQgoijjPNlUZA==} + exponential-backoff@3.1.1: + resolution: {integrity: sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw==} + + express@4.21.1: + resolution: {integrity: sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==} + engines: {node: '>= 0.10.0'} express@4.21.2: resolution: {integrity: sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==} @@ -6787,8 +6984,8 @@ packages: resolution: {integrity: sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==} engines: {'0': node >=0.6.0} - fast-content-type-parse@2.0.1: - resolution: {integrity: sha512-nGqtvLrj5w0naR6tDPfB4cUmYCqouzyQiz6C5y/LtcDllJdrcc6WaWW6iXyIIOErTa/XRybj28aasdn4LkVk6Q==} + fast-content-type-parse@2.0.0: + resolution: {integrity: sha512-fCqg/6Sps8tqk8p+kqyKqYfOF0VjPNYrqpLiqNl0RBKmD80B080AJWVV6EkSkscjToNExcXg1+Mfzftrx6+iSA==} fast-decode-uri-component@1.0.1: resolution: {integrity: sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg==} @@ -6796,8 +6993,8 @@ packages: fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} - fast-fifo@1.3.2: - resolution: {integrity: sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==} + fast-fifo@1.3.0: + resolution: {integrity: sha512-IgfweLvEpwyA4WgiQe9Nx6VV2QkML2NkvZnk1oKnIzXgXdWxuhF7zw4DvLTPZJn6PIUneiAXPF24QmoEqHTjyw==} fast-glob@3.3.3: resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} @@ -6806,8 +7003,8 @@ packages: fast-json-stable-stringify@2.1.0: resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} - fast-json-stringify@6.0.1: - resolution: {integrity: sha512-s7SJE83QKBZwg54dIbD5rCtzOBVD43V1ReWXXYqBgwCwHLYAAT0RQc/FmrQglXqWPpz6omtryJQOau5jI4Nrvg==} + fast-json-stringify@6.0.0: + resolution: {integrity: sha512-FGMKZwniMTgZh7zQp9b6XnBVxUmKVahQLQeRQHqwYmPDqDhcEKZ3BaQsxelFFI5PY7nN71OEeiL47/zUWcYe1A==} fast-levenshtein@2.0.6: resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} @@ -6815,8 +7012,8 @@ packages: fast-querystring@1.1.2: resolution: {integrity: sha512-g6KuKWmFXc0fID8WWH0jit4g0AGBoJhCkJMb1RmbsSEUNvQ+ZC8D6CUZ+GtF8nMzSPXnhiePyyqqipzNNEnHjg==} - fast-redact@3.5.0: - resolution: {integrity: sha512-dwsoQlS7h9hMeYUq1W++23NDcBLV4KqONnITDV9DjfS3q1SgDGVrBdvvTLUotWtPSD7asWDV9/CmsZPy8Hf70A==} + fast-redact@3.1.2: + resolution: {integrity: sha512-+0em+Iya9fKGfEQGcd62Yv6onjBmmhV1uh86XVfOU8VwAe6kaFdQCWI9s0/Nnugx5Vd9tdbZ7e6gE2tR9dzXdw==} engines: {node: '>=6'} fast-safe-stringify@2.1.1: @@ -6825,17 +7022,23 @@ packages: fast-text-encoding@1.0.6: resolution: {integrity: sha512-VhXlQgj9ioXCqGstD37E/HBeqEGV/qOD/kmbVG8h5xKBYvM1L3lR1Zn4555cQ8GkYbJa8aJSipLPndE1k6zK2w==} - fast-uri@3.0.6: - resolution: {integrity: sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==} + fast-uri@2.4.0: + resolution: {integrity: sha512-ypuAmmMKInk5q7XcepxlnUWDLWv4GFtaJqAzWKqn62IpQ3pejtr5dTVbt3vwqVaMKmkNR55sTT+CqUKIaT21BA==} - fast-xml-parser@4.4.1: - resolution: {integrity: sha512-xkjOecfnKGkSsOwtZ5Pz7Us/T6mrbPQrq0nh+aCO5V9nk5NLWmasAHumTKjiPJPWANe+kAZ84Jc8ooJkzZ88Sw==} + fast-uri@3.0.1: + resolution: {integrity: sha512-MWipKbbYiYI0UC7cl8m/i/IWTqfC8YXsqjzybjddLsFjStroQzsHXkc73JutMvBiXmOvapk+axIl79ig5t55Bw==} + + fast-xml-parser@4.5.0: + resolution: {integrity: sha512-/PlTQCI96+fZMAOLMZK4CWG1ItCbfZ/0jx7UIJFChPNrx7tcEgerUgWbeieCM9MfHInUDyK8DWYZ+YrywDJuTg==} hasBin: true - fast-xml-parser@4.5.3: - resolution: {integrity: sha512-RKihhV+SHsIUGXObeVy9AXiBbFwkVk7Syp8XgwN5U3JV416+Gwp/GO9i0JYKmikykgz/UHRrrV4ROuZEo/T0ig==} + fast-xml-parser@5.2.5: + resolution: {integrity: sha512-pfX9uG9Ki0yekDHx2SiuRIyFdyAr1kMIMitPvb0YBo8SUfKvia7w7FIyd/l6av85pFYRhZscS75MwMnbvY+hcQ==} hasBin: true + fastify-plugin@4.5.1: + resolution: {integrity: sha512-stRHYGeuqpEZTL1Ef0Ovr2ltazUT9g844X5z/zEBFLG8RYlpDiOCIG+ATvYEp+/zmc7sN29mcIMp8gvYplYPIQ==} + fastify-plugin@5.0.1: resolution: {integrity: sha512-HCxs+YnRaWzCl+cWRYFnHmeRFyR5GVnJTAaCJQiYzQSDwK9MgJdyAsuL3nh0EWRCYMgQ5MeziymvmAhUHYHDUQ==} @@ -6843,11 +7046,11 @@ packages: resolution: {integrity: sha512-2qfoaQ3BQDhZ1gtbkKZd6n0kKxJISJGM6u/skD9ljdWItAscjXrtZ1lnjr7PavmXX9j4EyCPmBDiIsLn07d5vA==} engines: {node: '>= 10'} - fastify@5.3.2: - resolution: {integrity: sha512-AIPqBgtqBAwkOkrnwesEE+dOyU30dQ4kh7udxeGVR05CRGwubZx+p2H8P0C4cRnQT0+EPK4VGea2DTL2RtWttg==} + fastify@5.6.1: + resolution: {integrity: sha512-WjjlOciBF0K8pDUPZoGPhqhKrQJ02I8DKaDIfO51EL0kbSMwQFl85cRwhOvmSDWoukNOdTo27gLN549pLCcH7Q==} - fastq@1.19.1: - resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==} + fastq@1.17.1: + resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} fb-watchman@2.0.2: resolution: {integrity: sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==} @@ -6855,8 +7058,17 @@ packages: fd-slicer@1.1.0: resolution: {integrity: sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==} - fdir@6.4.6: - resolution: {integrity: sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==} + fdir@6.4.4: + resolution: {integrity: sha512-1NZP+GK4GfuAv3PqKvxQRDMjdSRZjnkq7KfhlNrCNNlZ0ygQFpebfrnfnq/W7fpUnAv9aGWmY1zKx7FYL3gwhg==} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + + fdir@6.5.0: + resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} + engines: {node: '>=12.0.0'} peerDependencies: picomatch: ^3 || ^4 peerDependenciesMeta: @@ -6890,9 +7102,9 @@ packages: resolution: {integrity: sha512-VZR5I7k5wkD0HgFnMsq5hOsSc710MJMu5Nc5QYsbe38NN5iPV/XTObYLc/cpttRTf6lX538+5uO1ZQRhYibiZQ==} engines: {node: '>=18'} - file-type@20.4.1: - resolution: {integrity: sha512-hw9gNZXUfZ02Jo0uafWLaFVPter5/k2rfcrjFJJHX/77xtSDOfJuEFb6oKlFV86FLP1SuyHMW1PSk0U9M5tKkQ==} - engines: {node: '>=18'} + file-type@21.0.0: + resolution: {integrity: sha512-ek5xNX2YBYlXhiUXui3D/BXa3LdqPmoLJ7rqEx2bKJ7EAUEfmXgW0Das7Dc6Nr9MvqaOnIqiPV0mZk/r/UpNAg==} + engines: {node: '>=20'} filename-reserved-regex@3.0.0: resolution: {integrity: sha512-hn4cQfU6GOT/7cFHXBqeBg2TbrMBgdD0kcjLhvSQYYwm3s4B6cjvBfb7nBALJLAXqmU5xajSa7X2NnUud/VCdw==} @@ -6910,9 +7122,9 @@ packages: resolution: {integrity: sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==} engines: {node: '>= 0.8'} - find-my-way@9.3.0: - resolution: {integrity: sha512-eRoFWQw+Yv2tuYlK2pjFS2jGXSxSppAs3hSQjfxVKxM5amECzIgYYc1FEI8ZmhSh/Ig+FrKEz43NLRKJjYCZVg==} - engines: {node: '>=20'} + find-my-way@9.0.1: + resolution: {integrity: sha512-/5NN/R0pFWuff16TMajeKt2JyiW+/OE8nOO8vo1DwZTxLaIURb7lcBYPIgRPh61yCNh9l8voeKwcrkUzmB00vw==} + engines: {node: '>=14'} find-package-json@1.2.0: resolution: {integrity: sha512-+SOGcLGYDJHtyqHd87ysBhmaeQ95oWspDKnMXBrnQ9Eq4OkLNqejgoaD8xVWu6GPa0B6roa6KinCMEMcVeqONw==} @@ -6925,6 +7137,10 @@ packages: resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} engines: {node: '>=10'} + find-up@7.0.0: + resolution: {integrity: sha512-YyZM99iHrqLKjmt4LJDj58KI+fYyufRLBSYcqycxf//KpBk9FoewoGX0450m9nB44qrZnovzC2oeP5hUibxc/g==} + engines: {node: '>=18'} + find-versions@5.1.0: resolution: {integrity: sha512-+iwzCJ7C5v5KgcBuueqVoNiHVoQpwiUK5XFLjf0affFTep+Wcw93tPvmb8tqujDNmzhBDPddnWV/qgWSXgq+Hg==} engines: {node: '>=12'} @@ -6940,16 +7156,21 @@ packages: flatbuffers@24.12.23: resolution: {integrity: sha512-dLVCAISd5mhls514keQzmEG6QHmUUsNuWsb4tFafIUwvvgDjXhtfAYSKOzt5SWOy+qByV5pbsDZ+Vb7HUOBEdA==} - flatbuffers@25.2.10: - resolution: {integrity: sha512-7JlN9ZvLDG1McO3kbX0k4v+SUAg48L1rIwEvN6ZQl/eCtgJz9UylTMzE9wrmYrcorgxm3CX/3T/w5VAub99UUw==} - - flatted@3.3.3: - resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} + flatted@3.3.1: + resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==} fluent-ffmpeg@2.1.3: resolution: {integrity: sha512-Be3narBNt2s6bsaqP6Jzq91heDgOEaDCJAXcE3qcma/EJBSy5FB4cvO31XBInuAuKBx8Kptf8dkhjK0IOru39Q==} engines: {node: '>=18'} - deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. + + follow-redirects@1.15.2: + resolution: {integrity: sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true follow-redirects@1.15.9: resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==} @@ -6960,10 +7181,17 @@ packages: debug: optional: true + for-each@0.3.3: + resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} + for-each@0.3.5: resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} engines: {node: '>= 0.4'} + foreground-child@3.1.1: + resolution: {integrity: sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==} + engines: {node: '>=14'} + foreground-child@3.3.1: resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} engines: {node: '>=14'} @@ -6975,12 +7203,16 @@ packages: resolution: {integrity: sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==} engines: {node: '>= 14.17'} - form-data-encoder@4.1.0: - resolution: {integrity: sha512-G6NsmEW15s0Uw9XnCg+33H3ViYRyiM0hMrMhhqQOR8NFc5GhYrI+6I3u7OTw7b91J2g8rtvMBZJDbcGb2YUniw==} + form-data-encoder@4.0.2: + resolution: {integrity: sha512-KQVhvhK8ZkWzxKxOr56CPulAhH3dobtuQ4+hNQ+HekH/Wp5gSOafqRAeTphQUJAIk0GBvHZgJ2ZGRWd5kphMuw==} engines: {node: '>= 18'} - form-data@4.0.2: - resolution: {integrity: sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==} + form-data@3.0.1: + resolution: {integrity: sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==} + engines: {node: '>= 6'} + + form-data@4.0.4: + resolution: {integrity: sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==} engines: {node: '>= 6'} formdata-polyfill@4.0.10: @@ -6998,9 +7230,8 @@ packages: resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} engines: {node: '>= 0.6'} - fraction.js@5.2.2: - resolution: {integrity: sha512-uXBDv5knpYmv/2gLzWQ5mBHGBRk9wcKTeWu6GLTUEQfjCxO09uM/mHDrojlL+Q1mVGIIFo149Gba7od1XPgSzQ==} - engines: {node: '>= 12'} + fraction.js@4.3.4: + resolution: {integrity: sha512-pwiTgt0Q7t+GHZA4yaLjObx4vXmmdcS0iSJ19o8d/goUGgItX9UZWKWNnLHehxviD8wU2IWRsnR8cD5+yOJP2Q==} fresh@0.5.2: resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} @@ -7025,8 +7256,8 @@ packages: resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==} engines: {node: '>= 8'} - fs-minipass@3.0.3: - resolution: {integrity: sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==} + fs-minipass@3.0.2: + resolution: {integrity: sha512-2GAfyfoaCDRrM6jaOS3UsBts8yJ55VioXdWcOL7dK9zdAuKT71+WBA4ifnNYqVjYv+4SsPxjK0JT4yIIn4cA/g==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} fs.realpath@1.0.0: @@ -7040,6 +7271,10 @@ packages: function-bind@1.1.2: resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + function.prototype.name@1.1.6: + resolution: {integrity: sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==} + engines: {node: '>= 0.4'} + function.prototype.name@1.1.8: resolution: {integrity: sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==} engines: {node: '>= 0.4'} @@ -7056,16 +7291,16 @@ packages: resolution: {integrity: sha512-gSaYYIO1Y3wUtdfHmjDUZ8LWaxJQpiavzbF5Kq53akSzvmVg0RfyOcFDbO1KJ/KCGRFz2qG+lS81F0nkr7cRJA==} engines: {node: '>=10'} - gaxios@5.1.3: - resolution: {integrity: sha512-95hVgBRgEIRQQQHIbnxBXeHbW4TqFk4ZDJW7wmVtvYar72FdhRIo1UGOLS2eRAKCPEdPBWu+M7+A33D9CdX9rA==} + gaxios@5.1.2: + resolution: {integrity: sha512-mPyw3qQq6qoHWTe27CrzhSj7XYKVStTGrpP92a91FfogBWOd9BMW8GT5yS5WhEYGw02AgB1fVQVSAO+JKiQP0w==} engines: {node: '>=12'} gcp-metadata@4.3.1: resolution: {integrity: sha512-x850LS5N7V1F3UcV7PoupzGsyD6iVwTVvsh3tbXfkctZnBnjW5yu5z1/3k3SehF7TyoTIe78rJs02GMMy+LF+A==} engines: {node: '>=10'} - gcp-metadata@5.3.0: - resolution: {integrity: sha512-FNTkdNEnBdlqF2oatizolQqNANMrcqJt6AAYt99B3y1aLLC8Hc5IOBb+ZnnzllodEEf6xMBp6wRcBbc16fa65w==} + gcp-metadata@5.2.0: + resolution: {integrity: sha512-aFhhvvNycky2QyhG+dcfEdHBF0FRbYcf39s6WNHUDysKSrbJ5vuFbjydxBcmewtXeV248GP8dWT3ByPNxsyHCw==} engines: {node: '>=12'} gensync@1.0.0-beta.2: @@ -7076,6 +7311,10 @@ packages: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} + get-intrinsic@1.2.7: + resolution: {integrity: sha512-VW6Pxhsrk0KAOqs3WEd0klDiF/+V7gQOpAvY1jVU/LHmaD/kQO4523aiJuikX/QAKYiW6x8Jh+RJej1almdtCA==} + engines: {node: '>= 0.4'} + get-intrinsic@1.3.0: resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} engines: {node: '>= 0.4'} @@ -7104,15 +7343,16 @@ packages: resolution: {integrity: sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==} engines: {node: '>=18'} + get-symbol-description@1.0.2: + resolution: {integrity: sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==} + engines: {node: '>= 0.4'} + get-symbol-description@1.1.0: resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==} engines: {node: '>= 0.4'} - get-tsconfig@4.10.1: - resolution: {integrity: sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ==} - - getos@3.2.1: - resolution: {integrity: sha512-U56CfOK17OKgTVqozZjUKNdkfEv6jk5WISBJ8SHoagjE6L69zOwl3Z+O8myjY9MEW3i2HPWQBt/LTbCgcC973Q==} + get-tsconfig@4.10.0: + resolution: {integrity: sha512-kGzZ3LWWQcGIAmg6iWvXn0ei6WDtV26wzHRMwDSzmAbcXrTEXxHy6IehI6/4eT6VRKyMP1eF1VqwrVUmE/LR7A==} getpass@0.1.7: resolution: {integrity: sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==} @@ -7129,8 +7369,8 @@ packages: resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} hasBin: true - glob@11.0.2: - resolution: {integrity: sha512-YT7U7Vye+t5fZ/QMkBFrTJ7ZQxInIUjwyAjVj84CYXqgBdv30MFUPGnBR6sQaVq6Is15wYJUsnzTuWaGRBhBAQ==} + glob@11.0.3: + resolution: {integrity: sha512-2Nim7dha1KVkaiF4q6Dj+ngPPMdfvLJEOpZk/jKiUAkqKebpGAWQXAq9z1xu9HKu5lWfqw/FASuccEjyznjPaA==} engines: {node: 20 || >=22} hasBin: true @@ -7155,35 +7395,44 @@ packages: resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} engines: {node: '>=18'} - globals@16.0.0: - resolution: {integrity: sha512-iInW14XItCXET01CQFqudPOWP2jYMl7T+QRQT+UNcR/iQncN/F0UNpgd76iFkBPgNQb4+X3LV9tLJYzwh+Gl3A==} + globals@16.4.0: + resolution: {integrity: sha512-ob/2LcVVaVGCYN+r14cnwnoDPUufjiYgSqRhiFD0Q1iI4Odora5RE8Iv1D24hAz5oMophRGkGz+yuvQmmUMnMw==} engines: {node: '>=18'} + globalthis@1.0.3: + resolution: {integrity: sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==} + engines: {node: '>= 0.4'} + globalthis@1.0.4: resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} engines: {node: '>= 0.4'} + globalyzer@0.1.0: + resolution: {integrity: sha512-40oNTM9UfG6aBmuKxk/giHn5nQ8RVz/SS4Ir6zgzOv9/qC3kKZ9v4etGTcJbEl/NyVQH7FGU7d+X1egr57Md2Q==} + globby@11.1.0: resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} engines: {node: '>=10'} - google-auth-library@8.9.0: - resolution: {integrity: sha512-f7aQCJODJFmYWN6PeNKzgvy9LI2tYmXnzpNDHEjG5sDNPgGb2FXQyTBnXeSH+PAtpKESFD+LmHw3Ox3mN7e1Fg==} + globrex@0.1.2: + resolution: {integrity: sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==} + + google-auth-library@8.8.0: + resolution: {integrity: sha512-0iJn7IDqObDG5Tu9Tn2WemmJ31ksEa96IyK0J0OZCpTh6CrC6FrattwKX87h3qKVuprCJpdOGKc1Xi8V0kMh8Q==} engines: {node: '>=12'} - google-gax@3.6.1: - resolution: {integrity: sha512-g/lcUjGcB6DSw2HxgEmCDOrI/CByOwqRvsuUvNalHUK2iPPPlmAIpbMbl62u0YufGMr8zgE3JL7th6dCb1Ry+w==} + google-gax@3.6.0: + resolution: {integrity: sha512-2fyb61vWxUonHiArRNJQmE4tx5oY1ni8VPo08fzII409vDSCWG7apDX4qNOQ2GXXT82gLBn3d3P1Dydh7pWjyw==} engines: {node: '>=12'} hasBin: true google-p12-pem@4.0.1: resolution: {integrity: sha512-WPkN4yGtz05WZ5EhtlxNDWPhC4JIic6G8ePitwUWy4l+XPVYec+a0j0Ts47PDtW59y3RwAhUd9/h9ZZ63px6RQ==} engines: {node: '>=12.0.0'} - deprecated: Package is no longer maintained hasBin: true - google-protobuf@3.21.4: - resolution: {integrity: sha512-MnG7N936zcKTco4Jd2PX2U96Kf9PxygAPKBug+74LHzmHXmceN16MmRcdgZv+DGef/S9YvQAfRsNCn4cjf9yyQ==} + google-protobuf@3.21.2: + resolution: {integrity: sha512-3MSOYFO5U9mPGikIYCzK0SaThypfGgS6bHqrUGXG3DPHCrb+txNqeEcns1W0lkGfk0rCyNXm7xB9rMxnCiZOoA==} gopd@1.2.0: resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} @@ -7193,8 +7442,8 @@ packages: resolution: {integrity: sha512-XfBk1CxOOScDcMr9O1yKkNaQyy865NbYs+F7dr4H0LZMVgCj2Le59k6PqbNHoL5ToeaEQUYh6c6yMfVcc6SJxA==} engines: {node: '>=16'} - got@14.4.7: - resolution: {integrity: sha512-DI8zV1231tqiGzOiOzQWDhsBmncFW7oQDH6Zgy6pDPrqJuVZMtoSgPLLsBZQj8Jg4JFfwoOsDA8NGtLQLnIx2g==} + got@14.5.0: + resolution: {integrity: sha512-rZ8+ZMYz9yeTFmFtOiwf/Trcli8gdqgqAz0kmkEOWcT7C3BFG3Z+dLQu0y8je7RogG7Wp1obnu5GerwCaccftw==} engines: {node: '>=20'} graceful-fs@4.2.11: @@ -7203,8 +7452,8 @@ packages: graphemer@1.4.0: resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} - graphql@16.11.0: - resolution: {integrity: sha512-mS1lbMsxgQj6hge1XZ6p7GPhbrtFwUFYi3wRzXAC/FmYnyXMTvvI3td3rjmQ2u8ewXueaSvRPWaEcgVVOT9Jnw==} + graphql@16.8.1: + resolution: {integrity: sha512-59LZHPdGZVh695Ud9lRzPBVTtlX9ZCV150Er2W43ro37wVof0ctenSaskPPjN7lVTIN8mSZt8PHUNKZuNQUuxw==} engines: {node: ^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0} gtoken@6.1.2: @@ -7215,21 +7464,19 @@ packages: resolution: {integrity: sha512-tSQXBXS/MWQOn/RKckawJ61vvsDpCom87JgxiYdGwHdOa0ht0vzUWDlfioofFCRU0L+6NGDt6XzbgoJvZkMeRQ==} engines: {node: '>=0.8.0'} - happy-dom@16.8.1: - resolution: {integrity: sha512-n0QrmT9lD81rbpKsyhnlz3DgnMZlaOkJPpgi746doA+HvaMC79bdWkwjrNnGJRvDrWTI8iOcJiVTJ5CdT/AZRw==} - engines: {node: '>=18.0.0'} - - happy-dom@17.4.4: - resolution: {integrity: sha512-/Pb0ctk3HTZ5xEL3BZ0hK1AqDSAUuRQitOmROPHhfUYEWpmTImwfD8vFDGADmMAX0JYgbcgxWoLFKtsWhcpuVA==} - engines: {node: '>=18.0.0'} + happy-dom@20.0.7: + resolution: {integrity: sha512-CywLfzmYxP5OYpuAG0usFY0CpxJtwYR+w8Mms5J8W29Y2Pzf6rbfQS2M523tRZTb0oLA+URopPtnAQX2fupHZQ==} + engines: {node: '>=20.0.0'} hard-rejection@2.1.0: resolution: {integrity: sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==} engines: {node: '>=6'} - has-bigints@1.1.0: - resolution: {integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==} - engines: {node: '>= 0.4'} + harfbuzzjs@0.4.13: + resolution: {integrity: sha512-EC0q1K9Axs2IhgzDcTlYSv0m/Xo3VU36BQXtRoUS/4eMpy0rsMHePHwIjHKdhaouVO5O03sfUOwHP6ZzZ3HwFA==} + + has-bigints@1.0.2: + resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==} has-flag@3.0.0: resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} @@ -7242,6 +7489,10 @@ packages: has-property-descriptors@1.0.2: resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + has-proto@1.0.3: + resolution: {integrity: sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==} + engines: {node: '>= 0.4'} + has-proto@1.2.0: resolution: {integrity: sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==} engines: {node: '>= 0.4'} @@ -7260,6 +7511,10 @@ packages: hash-sum@2.0.0: resolution: {integrity: sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg==} + hasha@5.2.2: + resolution: {integrity: sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==} + engines: {node: '>=8'} + hasown@2.0.2: resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} engines: {node: '>= 0.4'} @@ -7274,14 +7529,14 @@ packages: resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} hasBin: true - headers-polyfill@4.0.3: - resolution: {integrity: sha512-IScLbePpkvO846sIwOtOTDjutRMWdXdJmXdMvk6gCBHxFO8d+QKOQedyZSxFTTFYRSmlgSTDtXqqq4pcenBXLQ==} + headers-polyfill@4.0.2: + resolution: {integrity: sha512-EWGTfnTqAO2L/j5HZgoM/3z82L7necsJ0pO9Tp0X1wil3PDLrkypTBRgVO2ExehEEvUycejZD3FuRaXpZZc3kw==} highlight.js@10.7.3: resolution: {integrity: sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==} - highlight.js@11.11.1: - resolution: {integrity: sha512-Xwwo44whKBVCYoliBQwaPvtd/2tYFkRQtXDWj1nackaV2JPXx3L0+Jvd8/qCJ2p+ML0/XVkJ2q+Mr+UVdpJK5w==} + highlight.js@11.10.0: + resolution: {integrity: sha512-SYVnVFswQER+zu1laSya563s+F8VDGt7o35d4utbamowvUNLLMovFqwCLSocpZTz3MgaSRA1IbqRWZv97dtErQ==} engines: {node: '>=12.0.0'} hosted-git-info@2.8.9: @@ -7299,14 +7554,14 @@ packages: resolution: {integrity: sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==} engines: {node: '>=18'} - html-entities@2.5.2: - resolution: {integrity: sha512-K//PSRMQk4FZ78Kyau+mZurHn3FH0Vwr+H36eE0rPbeYkRRi9YxceYPhuN60UwWorxyKHhqoAJl2OFKa4BVtaA==} + html-entities@2.6.0: + resolution: {integrity: sha512-kig+rMn/QOVRvr7c86gQ8lWXq+Hkv6CbAH1hLu+RG338StTpE8Z0b44SDVaqVu7HGKf27frdmUYEs9hTUX/cLQ==} html-escaper@2.0.2: resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} - html-tags@3.3.1: - resolution: {integrity: sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==} + html-tags@3.2.0: + resolution: {integrity: sha512-vy7ClnArOZwCnqZgvv+ddgHgJiAFXe3Ge9ML5/mBctVJoUoYPCdxVucOywjDARn6CVoh3dRSFdPHy2sX80L0Wg==} engines: {node: '>=8'} html-void-elements@3.0.0: @@ -7322,12 +7577,15 @@ packages: htmlparser2@5.0.1: resolution: {integrity: sha512-vKZZra6CSe9qsJzh0BjBGXo8dvzNsq/oGvsjfRdOrrryfeD9UOBEEQdeoqCRmKZchF5h2zOBMQ6YuQ0uRUmdbQ==} - htmlparser2@8.0.2: - resolution: {integrity: sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==} + htmlparser2@8.0.1: + resolution: {integrity: sha512-4lVbmc1diZC7GUJQtRQ5yBAeUCL1exyMwmForWkRLnwyzWBFxN633SALPMGYaWZvKe9j1pRZJpauvmxENSp/EA==} htmlparser2@9.1.0: resolution: {integrity: sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==} + http-cache-semantics@4.1.1: + resolution: {integrity: sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==} + http-cache-semantics@4.2.0: resolution: {integrity: sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==} @@ -7367,6 +7625,10 @@ packages: resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} engines: {node: '>= 6'} + https-proxy-agent@7.0.2: + resolution: {integrity: sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA==} + engines: {node: '>= 14'} + https-proxy-agent@7.0.6: resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} engines: {node: '>= 14'} @@ -7399,8 +7661,12 @@ packages: resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} engines: {node: '>=0.10.0'} - idb-keyval@6.2.1: - resolution: {integrity: sha512-8Sb3veuYCyrZL+VBt9LJfZjLUPWVvqn8tG28VqYNFCo43KHcKuq+b4EiXGeuaLAQWL2YmyDgMp2aSpH9JHsEQg==} + iconv-lite@0.7.0: + resolution: {integrity: sha512-cf6L2Ds3h57VVmkZe+Pn+5APsT7FpqJtEhhieDCvrE2MK5Qk9MyffgQyuxQTm6BChfeZNtcOLHp9IcWRVcIcBQ==} + engines: {node: '>=0.10.0'} + + idb-keyval@6.2.2: + resolution: {integrity: sha512-yjD9nARJ/jb1g+CvD0tlhUHOrJ9Sy0P8T9MF3YaLlHnSRpwPfpTX0XIvpmw3gAJUmEu3FiICLBDPXVwyEvrleg==} ieee754@1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} @@ -7408,30 +7674,34 @@ packages: ignore-by-default@1.0.1: resolution: {integrity: sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==} - ignore-walk@7.0.0: - resolution: {integrity: sha512-T4gbf83A4NH95zvhVYZc+qWocBBGlpzUXLPGurJggw/WIOwicfXJChLDP/iBZnN5WqROSu5Bm3hhle4z8a8YGQ==} - engines: {node: ^18.17.0 || >=20.5.0} + ignore-walk@8.0.0: + resolution: {integrity: sha512-FCeMZT4NiRQGh+YkeKMtWrOmBgWjHjMJ26WQWrRQyoyzqevdaGSakUaJW5xQYmjLlUVk2qUnCjYVBax9EKKg8A==} + engines: {node: ^20.17.0 || >=22.9.0} + + ignore@5.3.1: + resolution: {integrity: sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==} + engines: {node: '>= 4'} - ignore@5.3.2: - resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + ignore@7.0.5: + resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==} engines: {node: '>= 4'} - immutable@5.1.3: - resolution: {integrity: sha512-+chQdDfvscSF1SJqv2gn4SRO2ZyS3xL3r7IW/wWEEzrzLisnOlKiQu5ytC/BVNcS15C39WT2Hg/bjKjDMcu+zg==} + immutable@5.0.3: + resolution: {integrity: sha512-P8IdPQHq3lA1xVeBRi5VPqUm5HDgKnx0Ru51wZz5mjxHr5n3RWhjIpOFU7ybkUxfB+5IToy+OLaHYDBIWsv+uw==} - import-fresh@3.3.1: - resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} + import-fresh@3.3.0: + resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} engines: {node: '>=6'} - import-in-the-middle@1.14.2: - resolution: {integrity: sha512-5tCuY9BV8ujfOpwtAGgsTx9CGUapcFMEEyByLv1B+v2+6DhAcw+Zr0nhQT7uwaZ7DiourxFEscghOR8e1aPLQw==} + import-in-the-middle@1.15.0: + resolution: {integrity: sha512-bpQy+CrsRmYmoPMAE/0G33iwRqwW4ouqdRg8jgbH3aKuCtOc8lxgmYXg2dMM92CRiGP660EtBcymH/eVUpCSaA==} import-lazy@4.0.0: resolution: {integrity: sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==} engines: {node: '>=8'} - import-local@3.2.0: - resolution: {integrity: sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==} + import-local@3.1.0: + resolution: {integrity: sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==} engines: {node: '>=8'} hasBin: true @@ -7447,9 +7717,12 @@ packages: resolution: {integrity: sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==} engines: {node: '>=12'} + index-to-position@1.2.0: + resolution: {integrity: sha512-Yg7+ztRkqslMAS2iFaU+Oa4KTSidr63OsFGlOrJoW981kIYO3CGCS3wA95P1mUi/IVSJkn0D479KTJpVpvFNuw==} + engines: {node: '>=18'} + inflight@1.0.6: 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.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} @@ -7471,6 +7744,10 @@ packages: resolution: {integrity: sha512-+y6WywKZREw5rq7U2jvr2nmZpT7cbWbQQ0N/qfcseYnzHFz2cZz1Et52oY+XttYuYeTkI8Y+R2JNWj68MpQFSg==} hasBin: true + internal-slot@1.0.7: + resolution: {integrity: sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==} + engines: {node: '>= 0.4'} + internal-slot@1.1.0: resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==} engines: {node: '>= 0.4'} @@ -7478,10 +7755,17 @@ packages: intersection-observer@0.12.2: resolution: {integrity: sha512-7m1vEcPCxXYI8HqnL8CKI6siDyD+eIWSwgB3DZA+ZTogxk9I4CDnj4wilt9x/+/QbHI4YG5YZNmC6458/e9Ktg==} - ioredis@5.6.1: - resolution: {integrity: sha512-UxC0Yv1Y4WRJiGQxQkP0hfdL0/5/6YvdfOOClRgJ0qppSarkhneSa6UvkMkms0AkdGimSH3Ikqm+6mkMmX7vGA==} + ioredis@5.8.1: + resolution: {integrity: sha512-Qho8TgIamqEPdgiMadJwzRMW3TudIg6vpg4YONokGDudy4eqRIJtDbVX72pfLBcWxvbn3qm/40TyGUObdW4tLQ==} engines: {node: '>=12.22.0'} + ios-haptics@0.1.4: + resolution: {integrity: sha512-94FJcSuvmhe4mHTX4Uauj+/2yhs56m4BLkRScy1vNvkv7H1cSjsvfT+olc1sYOUqWlPhtVttAFBHex0cY9CE7Q==} + + ip-address@10.0.1: + resolution: {integrity: sha512-NWv9YLW4PoW2B7xtzaS3NCot75m6nK7Icdv0o3lfMceJVRfSoQwqD4wEH5rLwoKJwUiZ/rfpiVBhnaF0FK4HoA==} + engines: {node: '>= 12'} + ip-address@9.0.5: resolution: {integrity: sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==} engines: {node: '>= 12'} @@ -7506,8 +7790,15 @@ packages: resolution: {integrity: sha512-1ANGLZ+Nkv1ptFb2pa8oG8Lem4krflKuX/gINiHJHjJUKaJHk/SXk5x6K3J+39/p0h1RQ2saROclJJ+QLvETCQ==} engines: {node: '>=8'} - is-arguments@1.2.0: - resolution: {integrity: sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==} + is-arguments@1.1.1: + resolution: {integrity: sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==} + engines: {node: '>= 0.4'} + + is-array-buffer@3.0.2: + resolution: {integrity: sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==} + + is-array-buffer@3.0.4: + resolution: {integrity: sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==} engines: {node: '>= 0.4'} is-array-buffer@3.0.5: @@ -7524,10 +7815,17 @@ packages: resolution: {integrity: sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==} engines: {node: '>= 0.4'} + is-bigint@1.0.4: + resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==} + is-bigint@1.1.0: resolution: {integrity: sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==} engines: {node: '>= 0.4'} + is-boolean-object@1.1.2: + resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==} + engines: {node: '>= 0.4'} + is-boolean-object@1.2.2: resolution: {integrity: sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==} engines: {node: '>= 0.4'} @@ -7536,14 +7834,26 @@ packages: resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} engines: {node: '>= 0.4'} + is-core-module@2.15.1: + resolution: {integrity: sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==} + engines: {node: '>= 0.4'} + is-core-module@2.16.1: resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} engines: {node: '>= 0.4'} + is-data-view@1.0.1: + resolution: {integrity: sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==} + engines: {node: '>= 0.4'} + is-data-view@1.0.2: resolution: {integrity: sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==} engines: {node: '>= 0.4'} + is-date-object@1.0.5: + resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==} + engines: {node: '>= 0.4'} + is-date-object@1.1.0: resolution: {integrity: sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==} engines: {node: '>= 0.4'} @@ -7575,8 +7885,8 @@ packages: resolution: {integrity: sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==} engines: {node: '>=6'} - is-generator-function@1.1.0: - resolution: {integrity: sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==} + is-generator-function@1.0.10: + resolution: {integrity: sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==} engines: {node: '>= 0.4'} is-glob@4.0.3: @@ -7591,8 +7901,8 @@ packages: resolution: {integrity: sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==} engines: {node: '>=10'} - is-lambda@1.0.1: - resolution: {integrity: sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==} + is-map@2.0.2: + resolution: {integrity: sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==} is-map@2.0.3: resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} @@ -7605,6 +7915,10 @@ packages: is-node-process@1.2.0: resolution: {integrity: sha512-Vg4o6/fqPxIjtxgUH5QLJhwZ7gW5diGCVlXpuUfELC62CuxM1iHcRe51f2W1FDy04Ai4KJkagKjx3XaqyfRKXw==} + is-number-object@1.0.7: + resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==} + engines: {node: '>= 0.4'} + is-number-object@1.1.1: resolution: {integrity: sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==} engines: {node: '>= 0.4'} @@ -7639,14 +7953,28 @@ packages: is-promise@2.2.2: resolution: {integrity: sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==} + is-regex@1.1.4: + resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} + engines: {node: '>= 0.4'} + is-regex@1.2.1: resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==} engines: {node: '>= 0.4'} + is-set@2.0.2: + resolution: {integrity: sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g==} + is-set@2.0.3: resolution: {integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==} engines: {node: '>= 0.4'} + is-shared-array-buffer@1.0.2: + resolution: {integrity: sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==} + + is-shared-array-buffer@1.0.3: + resolution: {integrity: sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==} + engines: {node: '>= 0.4'} + is-shared-array-buffer@1.0.4: resolution: {integrity: sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==} engines: {node: '>= 0.4'} @@ -7666,6 +7994,10 @@ packages: resolution: {integrity: sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==} engines: {node: '>=18'} + is-string@1.0.7: + resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} + engines: {node: '>= 0.4'} + is-string@1.1.1: resolution: {integrity: sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==} engines: {node: '>= 0.4'} @@ -7674,10 +8006,18 @@ packages: resolution: {integrity: sha512-uVg5yifaTxHoefNf5Jcx+i9RZe2OBYd/UStp1umx+EERa4xGRa3LLGXjoEph43qUORC0qkafUgrXZ6zzK89yGA==} engines: {node: '>=14.16'} + is-symbol@1.0.4: + resolution: {integrity: sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==} + engines: {node: '>= 0.4'} + is-symbol@1.1.1: resolution: {integrity: sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==} engines: {node: '>= 0.4'} + is-typed-array@1.1.13: + resolution: {integrity: sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==} + engines: {node: '>= 0.4'} + is-typed-array@1.1.15: resolution: {integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==} engines: {node: '>= 0.4'} @@ -7693,14 +8033,23 @@ packages: resolution: {integrity: sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==} engines: {node: '>=18'} + is-weakmap@2.0.1: + resolution: {integrity: sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA==} + is-weakmap@2.0.2: resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==} engines: {node: '>= 0.4'} + is-weakref@1.0.2: + resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} + is-weakref@1.1.1: resolution: {integrity: sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==} engines: {node: '>= 0.4'} + is-weakset@2.0.2: + resolution: {integrity: sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg==} + is-weakset@2.0.4: resolution: {integrity: sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==} engines: {node: '>= 0.4'} @@ -7733,8 +8082,8 @@ packages: resolution: {integrity: sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==} engines: {node: '>=8'} - istanbul-lib-instrument@6.0.3: - resolution: {integrity: sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==} + istanbul-lib-instrument@6.0.0: + resolution: {integrity: sha512-x58orMzEVfzPUKqlbLd1hXCnySCxKdDKa6Rjg97CwuLLRI4g3FHTdnExu1OqffVFay6zeMW+T6/DowFLndWnIw==} engines: {node: '>=10'} istanbul-lib-report@3.0.1: @@ -7813,9 +8162,6 @@ packages: resolution: {integrity: sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - jest-fetch-mock@3.0.3: - resolution: {integrity: sha512-Ux1nWprtLrdrH4XwE7O7InRY6psIi3GOsqNESJgMJ+M5cv4A8Lh7SN9d2V2kKRZ8ebAfcd1LNyZguAOb6JiDqw==} - jest-get-type@29.6.3: resolution: {integrity: sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -7853,6 +8199,10 @@ packages: resolution: {integrity: sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-regex-util@30.0.1: + resolution: {integrity: sha512-jHEQgBXAgc+Gh4g0p3bCevgRCVRkB4VB70zhoAE48gxeSr1hfUOsM/C2WoJgVL7Eyg//hudYENbm3Ne+/dRVVA==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + jest-resolve-dependencies@29.7.0: resolution: {integrity: sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -7885,9 +8235,6 @@ packages: resolution: {integrity: sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - jest-websocket-mock@2.5.0: - resolution: {integrity: sha512-a+UJGfowNIWvtIKIQBHoEWIUqRxxQHFx4CXT+R5KxxKBtEQ5rS3pPOV/5299sHzqbmeCzxxY5qE4+yfXePePig==} - jest-worker@29.7.0: resolution: {integrity: sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -7905,17 +8252,21 @@ packages: jju@1.4.0: resolution: {integrity: sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==} - joi@17.13.3: - resolution: {integrity: sha512-otDA4ldcIx+ZXsKHWmp0YizCweVRZG96J10b0FevjfuncLO1oX59THoAmHkNubYJ+9gWsYsp5k8v4ib6oDv1fA==} + joi@17.11.0: + resolution: {integrity: sha512-NgB+lZLNoqISVy1rZocE9PZI36bL/77ie924Ri43yEvi9GUUMPeyVIr8KdFTMUlby1p0PBYMk9spIxEUQYqrJQ==} - js-beautify@1.15.4: - resolution: {integrity: sha512-9/KXeZUKKJwqCXUdBxFJ3vPh467OCckSBmYDwSK/EtV090K+iMJ7zx2S3HLVDIWFQdqMIsZWbnaGiba18aWhaA==} - engines: {node: '>=14'} + joi@18.0.1: + resolution: {integrity: sha512-IiQpRyypSnLisQf3PwuN2eIHAsAIGZIrLZkd4zdvIar2bDyhM91ubRjy8a3eYablXsh9BeI/c7dmPYHca5qtoA==} + engines: {node: '>= 20'} + + js-beautify@1.14.9: + resolution: {integrity: sha512-coM7xq1syLcMyuVGyToxcj2AlzhkDjmfklL8r0JgJ7A76wyGMpJ1oA35mr4APdYNO/o/4YY8H54NQIJzhMbhBg==} + engines: {node: '>=12'} hasBin: true - js-cookie@3.0.5: - resolution: {integrity: sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==} - engines: {node: '>=14'} + js-levenshtein@1.1.6: + resolution: {integrity: sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==} + engines: {node: '>=0.10.0'} js-stringify@1.0.2: resolution: {integrity: sha512-rtS5ATOo2Q5k1G+DADISilDA6lv79zIiwFd6CcjuIxGKLFm5C+RLImRscVap9k55i+MOZwgliw+NejvkLuGD5g==} @@ -7923,6 +8274,9 @@ packages: js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + js-tokens@9.0.1: + resolution: {integrity: sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==} + js-yaml@3.14.1: resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} hasBin: true @@ -7944,12 +8298,8 @@ packages: resolution: {integrity: sha512-/kmVISmrwVwtyYU40iQUOp3SUPk2dhNCMsZBQX0R1/jZ8maaXJ/oZIzUOiyOqcgtLnETFKYChbJ5iDC/eWmFHg==} engines: {node: '>=0.1.90'} - jsdoc-type-pratt-parser@4.1.0: - resolution: {integrity: sha512-Hicd6JK5Njt2QB6XYFS7ok9e37O8AYk3jTcppG4YVQnYjOemymvTcmc7OWsmq/Qqj5TdRFO5/x/tIPmBeRtGHg==} - engines: {node: '>=12.0.0'} - - jsdoc@4.0.4: - resolution: {integrity: sha512-zeFezwyXeG4syyYHbvh1A967IAqq/67yXtXvuL5wnqCkFZe8I0vKfm+EO+YEvLguo6w9CDUbrAXVtJSHh2E8rw==} + jsdoc@4.0.2: + resolution: {integrity: sha512-e8cIg2z62InH7azBBi3EsSEqrKx+nUtAS5bBcYTSpZFA+vhNPyhv8PTFZ0WsjOPDj04/dOLlm08EDcQJDqaGQg==} engines: {node: '>=12.0.0'} hasBin: true @@ -7962,6 +8312,11 @@ packages: canvas: optional: true + jsesc@2.5.2: + resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} + engines: {node: '>=4'} + hasBin: true + jsesc@3.1.0: resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} engines: {node: '>=6'} @@ -7976,8 +8331,8 @@ packages: json-parse-even-better-errors@2.3.1: resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} - json-schema-ref-resolver@2.0.1: - resolution: {integrity: sha512-HG0SIB9X4J8bwbxCbnd5FfPEbcXAJYTi1pBJeP/QPON+w8ovSME8iRG+ElHNxZNX2Qh6eYn1GdzJFS4cDFfx0Q==} + json-schema-ref-resolver@1.0.1: + resolution: {integrity: sha512-EJAj1pgHc1hxF6vo2Z3s69fMjO1INq6eGHXZ8Z6wCQeldCuwxGK9Sxf4/cScGn3FZubCVUehfWtcDM/PLteCQw==} json-schema-traverse@0.4.1: resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} @@ -8003,8 +8358,8 @@ packages: engines: {node: '>=6'} hasBin: true - jsonc-parser@3.3.1: - resolution: {integrity: sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==} + jsonc-parser@3.2.0: + resolution: {integrity: sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==} jsonfile@4.0.0: resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} @@ -8037,16 +8392,16 @@ packages: jstransformer@1.0.0: resolution: {integrity: sha512-C9YK3Rf8q6VAPDCCU9fnqo3mAfOH6vUGnMcP4AQAYIEpWtfGLpwOTmZ+igtdK5y+VvI2n3CyYSzy4Qh34eq24A==} - juice@11.0.1: - resolution: {integrity: sha512-R3KLud4l/sN9AMmFZs0QY7cugGSiKvPhGyIsufCV5nJ0MjSlngUE7k80TmFeK9I62wOXrjWBtYA1knVs2OkF8w==} + juice@11.0.3: + resolution: {integrity: sha512-VYjPg4WylyWyLPnSiUsJ9tnnGhRZF0vn0YD8WWwaI8FhP9+1UdRMyRDbvqPOH/nBotmLKOc+FI+Oma6FwVWfSw==} engines: {node: '>=18.17'} hasBin: true just-extend@6.2.0: resolution: {integrity: sha512-cYofQu2Xpom82S6qD778jBDpwvvy39s1l/hrYij2u9AMdQcGRpaBu6kY4mVhuno5kJVi1DAz4aiphA2WI1/OAw==} - jwa@2.0.1: - resolution: {integrity: sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==} + jwa@2.0.0: + resolution: {integrity: sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==} jws@4.0.0: resolution: {integrity: sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==} @@ -8054,6 +8409,9 @@ packages: keyv@4.5.4: resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + keyv@5.5.3: + resolution: {integrity: sha512-h0Un1ieD+HUrzBH6dJXhod3ifSghk5Hw/2Y4/KHBziPlZecrFyE9YOTPU6eOs0V9pYl8gOs86fkr/KN8lUX39A==} + kind-of@6.0.3: resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} engines: {node: '>=0.10.0'} @@ -8099,8 +8457,8 @@ packages: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} - light-my-request@6.6.0: - resolution: {integrity: sha512-CHYbu8RtboSIoVsHZ6Ye4cj4Aw/yg2oAFimlF7mNvfDV192LR7nDiKtSIfCuLT7KokPSTn/9kfVLm5OGN0A28A==} + light-my-request@6.0.0: + resolution: {integrity: sha512-kFkFXrmKCL0EEeOmJybMH5amWFd+AFvlvMlvFTRxCUwbhfapZqDmeLMPoWihntnYY6JpoQDE9k+vOzObF1fDqg==} lilconfig@3.1.3: resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==} @@ -8109,8 +8467,8 @@ packages: lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} - linkify-it@5.0.0: - resolution: {integrity: sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==} + linkify-it@3.0.3: + resolution: {integrity: sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==} listr2@3.14.0: resolution: {integrity: sha512-TyWI8G99GX9GjE54cJ+RrNMcIFBfwMPxc3XTFiAYGN4s10hWROGtOg7+O6u6LE3mNkyld7RSLE6nrKBvTfcs3g==} @@ -8133,6 +8491,10 @@ packages: resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} engines: {node: '>=10'} + locate-path@7.2.0: + resolution: {integrity: sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + lodash.camelcase@4.3.0: resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==} @@ -8172,8 +8534,8 @@ packages: long@4.0.0: resolution: {integrity: sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==} - long@5.3.2: - resolution: {integrity: sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==} + long@5.2.3: + resolution: {integrity: sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==} longest-streak@3.1.0: resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==} @@ -8181,6 +8543,9 @@ packages: loupe@3.1.3: resolution: {integrity: sha512-kkIp7XSkP78ZxJEsSxW3712C6teJVoeHHwgo9zJ380de7IYyJ2ISlxojcH2pC5OFLewESmnRi/+XCDIEEVyoug==} + loupe@3.2.1: + resolution: {integrity: sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==} + lowercase-keys@3.0.0: resolution: {integrity: sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -8188,8 +8553,8 @@ packages: lru-cache@10.4.3: resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} - lru-cache@11.1.0: - resolution: {integrity: sha512-QIXZUBJUx+2zHUdQujWejBkcD9+cs94tLn0+YL8UrCh+D5sCXZ4c7LaEH48pNwRY3MLDgqUFyhlCyjJPf1WP0A==} + lru-cache@11.0.0: + resolution: {integrity: sha512-Qv32eSV1RSCfhY3fpPE2GNZ8jgM9X7rdAfemLWqTUxwiyIC4jJ6Sy0fZ8H+oLWevO6i4/bizg7c8d8i6bxrzbA==} engines: {node: 20 || >=22} lru-cache@5.1.1: @@ -8199,24 +8564,20 @@ packages: resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} engines: {node: '>=10'} - lru-cache@8.0.5: - resolution: {integrity: sha512-MhWWlVnuab1RG5/zMRRcVGXZLCXrZTgfwMikgzCegsPnG62yDQo5JnqKkrK4jO5iKqDAZGItAqN5CtKBCBWRUA==} + lru-cache@8.0.4: + resolution: {integrity: sha512-E9FF6+Oc/uFLqZCuZwRKUzgFt5Raih6LfxknOSAVTjNkrCZkBf7DQCwJxZQgd9l4eHjIJDGR+E+1QKD1RhThPw==} engines: {node: '>=16.14'} - luxon@3.6.1: - resolution: {integrity: sha512-tJLxrKJhO2ukZ5z0gyjY1zPh3Rh88Ej9P7jNrZiHMUXHae1yvI2imgOZtL1TO8TW6biMMKfTtAOoEJANgtWBMQ==} + luxon@3.3.0: + resolution: {integrity: sha512-An0UCfG/rSiqtAIiBPO0Y9/zAnHUZxAMiCpTd5h2smgsj7GGmcenvrvww2cqNA8/4A5ZrD1gJpHN2mIHZQF+Mg==} engines: {node: '>=12'} lz-string@1.5.0: resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} hasBin: true - magic-string@0.27.0: - resolution: {integrity: sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==} - engines: {node: '>=12'} - - magic-string@0.30.17: - resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==} + magic-string@0.30.19: + resolution: {integrity: sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw==} magicast@0.3.5: resolution: {integrity: sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ==} @@ -8232,9 +8593,9 @@ packages: resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} engines: {node: '>=10'} - make-fetch-happen@13.0.1: - resolution: {integrity: sha512-cKTUFc/rbKUd/9meOvgrpJ2WrNzymt6jfRDdwg5UCnVzv9dTpEj9JS5m3wtziXVCjluIXyL8pcaukYqezIzZQA==} - engines: {node: ^16.14.0 || >=18.0.0} + make-fetch-happen@14.0.3: + resolution: {integrity: sha512-QMjGbFTP0blj97EeidG5hk/QhKQ3T4ICckQGLgz38QF7Vgbk6e6FTARN8KhKxyBbWn8R0HU+bnw8aSoFPD4qtQ==} + engines: {node: ^18.17.0 || >=20.5.0} makeerror@1.0.12: resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==} @@ -8259,12 +8620,12 @@ packages: '@types/markdown-it': '*' markdown-it: '*' - markdown-it@14.1.0: - resolution: {integrity: sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==} + markdown-it@12.3.2: + resolution: {integrity: sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==} hasBin: true - markdown-table@3.0.4: - resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==} + markdown-table@3.0.3: + resolution: {integrity: sha512-Z1NL3Tb1M9wH4XESsCDEksWoKTdlUafKc4pt0GRwjUyXaCFZ+dc3g2erqB6zm3szA2IUSi7VnPI+o/9jnxh9hw==} marked@4.3.0: resolution: {integrity: sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==} @@ -8275,25 +8636,25 @@ packages: resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} engines: {node: '>= 0.4'} - mathjs@14.5.2: - resolution: {integrity: sha512-51U6hp7j4M4Rj+l+q2KbmXAV9EhQVQzUdw1wE67RnUkKKq5ibxdrl9Ky2YkSUEIc2+VU8/IsThZNu6QSHUoyTA==} - engines: {node: '>= 18'} + mathjs@11.12.0: + resolution: {integrity: sha512-UGhVw8rS1AyedyI55DGz9q1qZ0p98kyKPyc9vherBkoueLntPfKtPBh14x+V4cdUWK0NZV2TBwqRFlvadscSuw==} + engines: {node: '>= 14'} hasBin: true matter-js@0.20.0: resolution: {integrity: sha512-iC9fYR7zVT3HppNnsFsp9XOoQdQN2tUyfaKg4CHLH8bN+j6GT4Gw7IH2rP0tflAebrHFw730RR3DkVSZRX8hwA==} - mdast-util-find-and-replace@3.0.2: - resolution: {integrity: sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==} + mdast-util-find-and-replace@3.0.1: + resolution: {integrity: sha512-SG21kZHGC3XRTSUhtofZkBzZTJNM5ecCi0SK2IMKmSXR8vO3peL+kb1O0z7Zl83jKtutG4k5Wv/W7V3/YHvzPA==} - mdast-util-from-markdown@2.0.2: - resolution: {integrity: sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==} + mdast-util-from-markdown@2.0.0: + resolution: {integrity: sha512-n7MTOr/z+8NAX/wmhhDji8O3bRvPTV/U0oTCaZJkjhPSKTPhS3xufVhKGF8s1pJ7Ox4QgoIU7KHseh09S+9rTA==} - mdast-util-gfm-autolink-literal@2.0.1: - resolution: {integrity: sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==} + mdast-util-gfm-autolink-literal@2.0.0: + resolution: {integrity: sha512-FyzMsduZZHSc3i0Px3PQcBT4WJY/X/RCtEJKuybiC6sjPqLv7h1yqAkmILZtuxMSsUyaLUWNp71+vQH2zqp5cg==} - mdast-util-gfm-footnote@2.1.0: - resolution: {integrity: sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==} + mdast-util-gfm-footnote@2.0.0: + resolution: {integrity: sha512-5jOT2boTSVkMnQ7LTrd6n/18kqwjmuYqo7JUPe+tRCY6O7dAuTFMtTPauYYrMPpox9hlN0uOx/FL8XvEfG9/mQ==} mdast-util-gfm-strikethrough@2.0.0: resolution: {integrity: sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==} @@ -8304,8 +8665,8 @@ packages: mdast-util-gfm-task-list-item@2.0.0: resolution: {integrity: sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==} - mdast-util-gfm@3.1.0: - resolution: {integrity: sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==} + mdast-util-gfm@3.0.0: + resolution: {integrity: sha512-dgQEX5Amaq+DuUqf26jJqSK9qgixgd6rYDHAv4aTBuA92cTknZlKpPfa86Z/s8Dj8xsAQpFfBmPUHWJBWqS4Bw==} mdast-util-phrasing@4.1.0: resolution: {integrity: sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==} @@ -8313,8 +8674,8 @@ packages: mdast-util-to-hast@13.2.0: resolution: {integrity: sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==} - mdast-util-to-markdown@2.1.2: - resolution: {integrity: sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==} + mdast-util-to-markdown@2.1.0: + resolution: {integrity: sha512-SR2VnIEdVNCJbP6y7kVTJgPLifdr8WEU440fQec7qHoHOUz/oJ2jmNRqdDQ3rbiStOXb2mCDGTuwsK5OPUgYlQ==} mdast-util-to-string@4.0.0: resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==} @@ -8322,18 +8683,21 @@ packages: mdn-data@2.0.28: resolution: {integrity: sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==} - mdn-data@2.0.30: - resolution: {integrity: sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==} + mdn-data@2.12.2: + resolution: {integrity: sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==} - mdurl@2.0.0: - resolution: {integrity: sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==} + mdurl@1.0.1: + resolution: {integrity: sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==} media-typer@0.3.0: resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} engines: {node: '>= 0.6'} - meilisearch@0.50.0: - resolution: {integrity: sha512-9IzIkobvnuS18Eg4dq/eJB9W+eXqeLZjNRgq/kKMswSmVYYSQsXqGgSuCA0JkF+o5RwJlwIsieQee6rh313VhA==} + mediabunny@1.23.0: + resolution: {integrity: sha512-mWdhhdRquePfTgZ+18DLCFWmqwO6oGP/YudmRU8Puh+whMUJ3VSb9KMAHPl2utim66ixKdZw+DbmdqBfBxRp0A==} + + meilisearch@0.53.0: + resolution: {integrity: sha512-nG4VXbEOSzUmtbfsgOo+t6yX1ECEgXaT4hC0ap9MBpQGK5xwT+NWYDENYsKWR75cVaWaAqva+ok4zHlgtdXlLw==} memoizerific@1.11.3: resolution: {integrity: sha512-/EuHYwAPdLtXwAwSZkh/Gutery6pD2KYd44oQLhAvQp/50mpyduZh8Q7PYHXTCJ+wuXxt7oij2LXyIJOOYFPog==} @@ -8359,96 +8723,96 @@ packages: resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} engines: {node: '>= 0.6'} - mfc-js@0.24.0-cherrypick.9: - resolution: {integrity: sha512-U2WH3z25CGqJljgumkjhZxgocAIET/x/oVCmFtkatyU3iHdTVO35iXx7Dey/1alZ0b5EPNno5rGtRQhqz5vISA==} + mfc-js@0.1.0: + resolution: {integrity: sha512-ibcX5cJfObLB6fcKHQuX8fbBArZJCzMXTZN5NJ3dkf2UZSy1mEtosPRI61P+4KHEGISyqBQg4lsK1W7LeVRaNQ==} - microformats-parser@2.0.2: - resolution: {integrity: sha512-tUf9DmN4Jq/tGyp1YH2V6D/Cud+9Uc0WhjjUFirqVeHTRkkfLDacv6BQFT7h7HFsD0Z8wja5eKkRgzZU8bv0Fw==} + microformats-parser@2.0.4: + resolution: {integrity: sha512-DA2yt3uz2JjupBGoNvaG9ngBP5vSTI1ky2yhxBai/RnQrlzo+gEzuCdvwIIjj2nh3uVPDybTP5u7uua7pOa6LA==} engines: {node: '>=18'} - micromark-core-commonmark@2.0.3: - resolution: {integrity: sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==} + micromark-core-commonmark@2.0.0: + resolution: {integrity: sha512-jThOz/pVmAYUtkroV3D5c1osFXAMv9e0ypGDOIZuCeAe91/sD6BoE2Sjzt30yuXtwOYUmySOhMas/PVyh02itA==} - micromark-extension-gfm-autolink-literal@2.1.0: - resolution: {integrity: sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==} + micromark-extension-gfm-autolink-literal@2.0.0: + resolution: {integrity: sha512-rTHfnpt/Q7dEAK1Y5ii0W8bhfJlVJFnJMHIPisfPK3gpVNuOP0VnRl96+YJ3RYWV/P4gFeQoGKNlT3RhuvpqAg==} - micromark-extension-gfm-footnote@2.1.0: - resolution: {integrity: sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==} + micromark-extension-gfm-footnote@2.0.0: + resolution: {integrity: sha512-6Rzu0CYRKDv3BfLAUnZsSlzx3ak6HAoI85KTiijuKIz5UxZxbUI+pD6oHgw+6UtQuiRwnGRhzMmPRv4smcz0fg==} - micromark-extension-gfm-strikethrough@2.1.0: - resolution: {integrity: sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==} + micromark-extension-gfm-strikethrough@2.0.0: + resolution: {integrity: sha512-c3BR1ClMp5fxxmwP6AoOY2fXO9U8uFMKs4ADD66ahLTNcwzSCyRVU4k7LPV5Nxo/VJiR4TdzxRQY2v3qIUceCw==} - micromark-extension-gfm-table@2.1.1: - resolution: {integrity: sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==} + micromark-extension-gfm-table@2.0.0: + resolution: {integrity: sha512-PoHlhypg1ItIucOaHmKE8fbin3vTLpDOUg8KAr8gRCF1MOZI9Nquq2i/44wFvviM4WuxJzc3demT8Y3dkfvYrw==} micromark-extension-gfm-tagfilter@2.0.0: resolution: {integrity: sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==} - micromark-extension-gfm-task-list-item@2.1.0: - resolution: {integrity: sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==} + micromark-extension-gfm-task-list-item@2.0.1: + resolution: {integrity: sha512-cY5PzGcnULaN5O7T+cOzfMoHjBW7j+T9D2sucA5d/KbsBTPcYdebm9zUd9zzdgJGCwahV+/W78Z3nbulBYVbTw==} micromark-extension-gfm@3.0.0: resolution: {integrity: sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==} - micromark-factory-destination@2.0.1: - resolution: {integrity: sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==} + micromark-factory-destination@2.0.0: + resolution: {integrity: sha512-j9DGrQLm/Uhl2tCzcbLhy5kXsgkHUrjJHg4fFAeoMRwJmJerT9aw4FEhIbZStWN8A3qMwOp1uzHr4UL8AInxtA==} - micromark-factory-label@2.0.1: - resolution: {integrity: sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==} + micromark-factory-label@2.0.0: + resolution: {integrity: sha512-RR3i96ohZGde//4WSe/dJsxOX6vxIg9TimLAS3i4EhBAFx8Sm5SmqVfR8E87DPSR31nEAjZfbt91OMZWcNgdZw==} - micromark-factory-space@2.0.1: - resolution: {integrity: sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==} + micromark-factory-space@2.0.0: + resolution: {integrity: sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==} - micromark-factory-title@2.0.1: - resolution: {integrity: sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==} + micromark-factory-title@2.0.0: + resolution: {integrity: sha512-jY8CSxmpWLOxS+t8W+FG3Xigc0RDQA9bKMY/EwILvsesiRniiVMejYTE4wumNc2f4UbAa4WsHqe3J1QS1sli+A==} - micromark-factory-whitespace@2.0.1: - resolution: {integrity: sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==} + micromark-factory-whitespace@2.0.0: + resolution: {integrity: sha512-28kbwaBjc5yAI1XadbdPYHX/eDnqaUFVikLwrO7FDnKG7lpgxnvk/XGRhX/PN0mOZ+dBSZ+LgunHS+6tYQAzhA==} - micromark-util-character@2.1.1: - resolution: {integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==} + micromark-util-character@2.1.0: + resolution: {integrity: sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==} - micromark-util-chunked@2.0.1: - resolution: {integrity: sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==} + micromark-util-chunked@2.0.0: + resolution: {integrity: sha512-anK8SWmNphkXdaKgz5hJvGa7l00qmcaUQoMYsBwDlSKFKjc6gjGXPDw3FNL3Nbwq5L8gE+RCbGqTw49FK5Qyvg==} - micromark-util-classify-character@2.0.1: - resolution: {integrity: sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==} + micromark-util-classify-character@2.0.0: + resolution: {integrity: sha512-S0ze2R9GH+fu41FA7pbSqNWObo/kzwf8rN/+IGlW/4tC6oACOs8B++bh+i9bVyNnwCcuksbFwsBme5OCKXCwIw==} - micromark-util-combine-extensions@2.0.1: - resolution: {integrity: sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==} + micromark-util-combine-extensions@2.0.0: + resolution: {integrity: sha512-vZZio48k7ON0fVS3CUgFatWHoKbbLTK/rT7pzpJ4Bjp5JjkZeasRfrS9wsBdDJK2cJLHMckXZdzPSSr1B8a4oQ==} - micromark-util-decode-numeric-character-reference@2.0.2: - resolution: {integrity: sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==} + micromark-util-decode-numeric-character-reference@2.0.1: + resolution: {integrity: sha512-bmkNc7z8Wn6kgjZmVHOX3SowGmVdhYS7yBpMnuMnPzDq/6xwVA604DuOXMZTO1lvq01g+Adfa0pE2UKGlxL1XQ==} - micromark-util-decode-string@2.0.1: - resolution: {integrity: sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==} + micromark-util-decode-string@2.0.0: + resolution: {integrity: sha512-r4Sc6leeUTn3P6gk20aFMj2ntPwn6qpDZqWvYmAG6NgvFTIlj4WtrAudLi65qYoaGdXYViXYw2pkmn7QnIFasA==} - micromark-util-encode@2.0.1: - resolution: {integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==} + micromark-util-encode@2.0.0: + resolution: {integrity: sha512-pS+ROfCXAGLWCOc8egcBvT0kf27GoWMqtdarNfDcjb6YLuV5cM3ioG45Ys2qOVqeqSbjaKg72vU+Wby3eddPsA==} - micromark-util-html-tag-name@2.0.1: - resolution: {integrity: sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==} + micromark-util-html-tag-name@2.0.0: + resolution: {integrity: sha512-xNn4Pqkj2puRhKdKTm8t1YHC/BAjx6CEwRFXntTaRf/x16aqka6ouVoutm+QdkISTlT7e2zU7U4ZdlDLJd2Mcw==} - micromark-util-normalize-identifier@2.0.1: - resolution: {integrity: sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==} + micromark-util-normalize-identifier@2.0.0: + resolution: {integrity: sha512-2xhYT0sfo85FMrUPtHcPo2rrp1lwbDEEzpx7jiH2xXJLqBuy4H0GgXk5ToU8IEwoROtXuL8ND0ttVa4rNqYK3w==} - micromark-util-resolve-all@2.0.1: - resolution: {integrity: sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==} + micromark-util-resolve-all@2.0.0: + resolution: {integrity: sha512-6KU6qO7DZ7GJkaCgwBNtplXCvGkJToU86ybBAUdavvgsCiG8lSSvYxr9MhwmQ+udpzywHsl4RpGJsYWG1pDOcA==} - micromark-util-sanitize-uri@2.0.1: - resolution: {integrity: sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==} + micromark-util-sanitize-uri@2.0.0: + resolution: {integrity: sha512-WhYv5UEcZrbAtlsnPuChHUAsu/iBPOVaEVsntLBIdpibO0ddy8OzavZz3iL2xVvBZOpolujSliP65Kq0/7KIYw==} - micromark-util-subtokenize@2.1.0: - resolution: {integrity: sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==} + micromark-util-subtokenize@2.0.0: + resolution: {integrity: sha512-vc93L1t+gpR3p8jxeVdaYlbV2jTYteDje19rNSS/H5dlhxUYll5Fy6vJ2cDwP8RnsXi818yGty1ayP55y3W6fg==} - micromark-util-symbol@2.0.1: - resolution: {integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==} + micromark-util-symbol@2.0.0: + resolution: {integrity: sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==} - micromark-util-types@2.0.2: - resolution: {integrity: sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==} + micromark-util-types@2.0.0: + resolution: {integrity: sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w==} - micromark@4.0.2: - resolution: {integrity: sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==} + micromark@4.0.0: + resolution: {integrity: sha512-o/sd0nMof8kYff+TqcDx3VSrgBTcZpSvYcAHIfHhv5VAuNmisCxjhx6YmxS8PFEpb9z5WKWKPdzf0jM23ro3RQ==} micromatch@4.0.8: resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} @@ -8458,10 +8822,6 @@ packages: resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} engines: {node: '>= 0.6'} - mime-db@1.54.0: - resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==} - engines: {node: '>= 0.6'} - mime-types@2.1.35: resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} engines: {node: '>= 0.6'} @@ -8504,32 +8864,32 @@ packages: minimalistic-assert@1.0.1: resolution: {integrity: sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==} - minimatch@10.0.1: - resolution: {integrity: sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==} + minimatch@10.0.3: + resolution: {integrity: sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw==} engines: {node: 20 || >=22} - minimatch@3.0.8: - resolution: {integrity: sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==} - minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} - minimatch@5.1.6: - resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} + minimatch@5.1.2: + resolution: {integrity: sha512-bNH9mmM9qsJ2X4r2Nat1B//1dJVcn3+iBLa3IgqJ7EbGaDNepL9QSHOxN4ng33s52VMMhhIfgCYDk3C4ZmlDAg==} engines: {node: '>=10'} minimatch@9.0.1: resolution: {integrity: sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==} engines: {node: '>=16 || 14 >=14.17'} - minimatch@9.0.5: - resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} + minimatch@9.0.4: + resolution: {integrity: sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==} engines: {node: '>=16 || 14 >=14.17'} minimist-options@4.1.0: resolution: {integrity: sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==} engines: {node: '>= 6'} + minimist@1.2.7: + resolution: {integrity: sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==} + minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} @@ -8537,9 +8897,9 @@ packages: resolution: {integrity: sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw==} engines: {node: '>=16 || 14 >=14.17'} - minipass-fetch@3.0.5: - resolution: {integrity: sha512-2N8elDQAtSnFV0Dk7gt15KHsS0Fyz6CbYZ360h0WTYV1Ty46li3rAXVOQj1THMNLdmrD9Vt5pBPtWtVkpwGBqg==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + minipass-fetch@4.0.1: + resolution: {integrity: sha512-j7U11C5HXigVuutxebFadoYBbd7VSdZWggSe64NVdvWNBqGAiXPL2QVCehjmw7lY1oF9gOllYbORh+hiNgfPgQ==} + engines: {node: ^18.17.0 || >=20.5.0} minipass-flush@1.0.5: resolution: {integrity: sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==} @@ -8569,8 +8929,12 @@ packages: resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==} engines: {node: '>= 8'} - minizlib@3.0.2: - resolution: {integrity: sha512-oG62iEk+CYt5Xj2YqI5Xi9xWUeZhDI8jjQmC5oThVH5JGCTgIjr7ciJDzC7MBzYd//WvR1OTmP5Q38Q8ShQtVA==} + minizlib@3.0.1: + resolution: {integrity: sha512-umcy022ILvb5/3Djuu8LWeqUa8D68JaBzlttKeMWen48SjabqS3iY5w/vzeMzMUNhLDifyhbOwKDSznB1vvrwg==} + engines: {node: '>= 18'} + + minizlib@3.1.0: + resolution: {integrity: sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==} engines: {node: '>= 18'} mkdirp@0.5.6: @@ -8582,11 +8946,6 @@ packages: engines: {node: '>=10'} hasBin: true - mkdirp@3.0.1: - resolution: {integrity: sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==} - engines: {node: '>=10'} - hasBin: true - mnemonist@0.40.0: resolution: {integrity: sha512-kdd8AFNig2AD5Rkih7EPCXhu/iMvwevQFX/uEiGhZyPZi7fHqOoF4V4kHLpCfysxXMgQ4B52kdPMCwARshKvEg==} @@ -8594,33 +8953,39 @@ packages: resolution: {integrity: sha512-qxBgB7Qa2sEQgHFjj0dSigq7fX4k6Saisd5Nelwp2q8mlbAFh5dHV9JTTlF8viYJLSSWgMCZFUom8PJcMNBoJw==} engines: {node: '>= 8'} + module-details-from-path@1.0.3: + resolution: {integrity: sha512-ySViT69/76t8VhE1xXHK6Ch4NcDd26gx0MzKXLO+F7NOtnqH68d9zF94nT8ZWSxXh8ELOERsnJO/sWt1xZYw5A==} + module-details-from-path@1.0.4: resolution: {integrity: sha512-EGWKgxALGMgzvxYF1UyGTy0HXX/2vHLkw6+NvDKW2jypWbHpjQuj4UMcqQWXHERJhVGKikolT06G3bcKe4fi7w==} ms@2.0.0: resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} + ms@2.1.2: + resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - ms@3.0.0-canary.1: - resolution: {integrity: sha512-kh8ARjh8rMN7Du2igDRO9QJnqCb2xYTJxyQYK7vJJS4TvLLmsbyhiKpSW+t+y26gyOyMd0riphX0GeWKU3ky5g==} - engines: {node: '>=12.13'} + ms@3.0.0-canary.202508261828: + resolution: {integrity: sha512-NotsCoUCIUkojWCzQff4ttdCfIPoA1UGZsyQbi7KmqkNRfKCrvga8JJi2PknHymHOuor0cJSn/ylj52Cbt2IrQ==} + engines: {node: '>=18'} - msgpackr-extract@3.0.3: - resolution: {integrity: sha512-P0efT1C9jIdVRefqjzOQ9Xml57zpOXnIuS+csaB4MdZbTdmGDLo8XhzBG1N7aO11gKDDkJvBLULeFTo46wwreA==} + msgpackr-extract@3.0.2: + resolution: {integrity: sha512-SdzXp4kD/Qf8agZ9+iTu6eql0m3kWm1A2y1hkpTeVNENutaB0BwHlSvAIaMxwntmRUAUjon2V4L8Z/njd0Ct8A==} hasBin: true - msgpackr@1.11.4: - resolution: {integrity: sha512-uaff7RG9VIC4jacFW9xzL3jc0iM32DNHe4jYVycBcjUePT/Klnfj7pqtWJt9khvDFizmjN2TlYniYmSS2LIaZg==} + msgpackr@1.11.2: + resolution: {integrity: sha512-F9UngXRlPyWCDEASDpTf6c9uNhGPTqnTeLVt7bN+bU1eajoR/8V9ys2BRaV5C/e5ihE6sJ9uPIKaYt6bFuO32g==} - msw-storybook-addon@2.0.4: - resolution: {integrity: sha512-rstO8+r01sRMg6PPP7OxM8LG5/6r4+wmp2uapHeHvm9TQQRHvpPXOU/Y9/Somysz8Oi4Ea1aummXH3JlnP2LIA==} + msw-storybook-addon@2.0.6: + resolution: {integrity: sha512-ExCwDbcJoM2V3iQU+fZNp+axVfNc7DWMRh4lyTXebDO8IbpUNYKGFUrA8UqaeWiRGKVuS7+fU+KXEa9b0OP6uA==} peerDependencies: msw: ^2.0.0 - msw@2.7.5: - resolution: {integrity: sha512-00MyTlY3TJutBa5kiU+jWiz2z5pNJDYHn2TgPkGkh92kMmNH43RqvMXd8y/7HxNn8RjzUbvZWYZjcS36fdb6sw==} + msw@2.11.5: + resolution: {integrity: sha512-atFI4GjKSJComxcigz273honh8h4j5zzpk5kwG4tGm0TPcYne6bqmVrufeRll6auBeouIkXqZYXxVbWSWxM3RA==} engines: {node: '>=18'} hasBin: true peerDependencies: @@ -8632,10 +8997,9 @@ packages: muggle-string@0.4.1: resolution: {integrity: sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==} - multer@1.4.4-lts.1: - resolution: {integrity: sha512-WeSGziVj6+Z2/MwQo3GvqzgR+9Uc+qt8SwHKh3gvNPiISKfsMfG4SvCOFYlxxgkXt7yIV2i1yczehm0EOKIxIg==} - engines: {node: '>= 6.0.0'} - deprecated: Multer 1.x is impacted by a number of vulnerabilities, which have been patched in 2.x. You should upgrade to the latest 2.x version. + multer@2.0.2: + resolution: {integrity: sha512-u7f2xaZ/UG8oLXHvtF/oWTRvT44p9ecwBBqTwgJVq0+4BW1g8OW01TyMEGWBHbyMOYVHXslaut7qEQ1meATXgw==} + engines: {node: '>= 10.16.0'} mute-stream@2.0.0: resolution: {integrity: sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==} @@ -8648,16 +9012,16 @@ packages: mz@2.7.0: resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} - nan@2.22.2: - resolution: {integrity: sha512-DANghxFkS1plDdRsX0X9pm0Z6SJNN6gBdtXfanwoZ8hooC5gosGFSBGRYHUVPz1asKA/kMRqDRdHrluZ61SpBQ==} + nan@2.23.0: + resolution: {integrity: sha512-1UxuyYGdoQHcGg87Lkqm3FzefucTa0NAiOcuRsDmysep3c1LVCRK2krrUDafMWtjSG04htvAmvg96+SDknOmgQ==} nanoid@3.3.11: resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true - nanoid@5.1.5: - resolution: {integrity: sha512-Ir/+ZpE9fDsNH0hQ3C68uyThDXzYcim2EqcZ8zn8Chtt1iylPT9xXJB0kPCnqzgcEGikO9RxSrh63MsmVCU7Fw==} + nanoid@5.1.6: + resolution: {integrity: sha512-c7+7RQ+dMB5dPwwCp4ee1/iV/q2P6aK1mTZcfr1BTuVlyW9hJYiMPybJCcnBlQtuSmTIWNeazm/zqNoZSSElBg==} engines: {node: ^18 || >=20} hasBin: true @@ -8677,8 +9041,8 @@ packages: resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} engines: {node: '>= 0.6'} - negotiator@0.6.4: - resolution: {integrity: sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==} + negotiator@1.0.0: + resolution: {integrity: sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==} engines: {node: '>= 0.6'} nested-property@4.0.0: @@ -8688,30 +9052,36 @@ packages: resolution: {integrity: sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==} engines: {node: '>= 0.4.0'} + nice-napi@1.0.2: + resolution: {integrity: sha512-px/KnJAJZf5RuBGcfD+Sp2pAKq0ytz8j+1NehvgIGFkvtvFrDM3T8E4x/JJODXK9WZow8RRGrbA9QQ3hs+pDhA==} + os: ['!win32'] + nise@6.1.1: resolution: {integrity: sha512-aMSAzLVY7LyeM60gvBS423nBmIPP+Wy7St7hsb+8/fc1HmeoHJfLO8CKse4u3BtOZvQLJghYPI2i/1WZrEj5/g==} - node-abi@3.75.0: - resolution: {integrity: sha512-OhYaY5sDsIka7H7AtijtI9jwGYLyl29eQn/W623DiN/MIv5sUqc4g7BIDThX+gb7di9f6xK02nkp8sdfFWZLTg==} + node-abi@3.78.0: + resolution: {integrity: sha512-E2wEyrgX/CqvicaQYU3Ze1PFGjc4QYPGsjUrlYkqAE0WjHEZwgOsGMPMzkMse4LjJbDmaEuDX3CM036j5K2DSQ==} engines: {node: '>=10'} node-abort-controller@3.1.1: resolution: {integrity: sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==} + node-addon-api@3.2.1: + resolution: {integrity: sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==} + node-addon-api@7.1.1: resolution: {integrity: sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==} - node-addon-api@8.4.0: - resolution: {integrity: sha512-D9DI/gXHvVmjHS08SVch0Em8G5S1P+QWtU31appcKT/8wFSPRcdHadIFSAntdMMVM5zz+/DL+bL/gz3UDppqtg==} + node-addon-api@8.2.0: + resolution: {integrity: sha512-qnyuI2ROiCkye42n9Tj5aX1ns7rzj6n7zW1XReSnLSL9v/vbLeR6fJq6PU27YU/ICfYw6W7Ouk/N7cysWu/hlw==} engines: {node: ^18 || ^20 || >= 21} node-domexception@1.0.0: resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} engines: {node: '>=10.5.0'} - deprecated: Use your platform's native DOMException instead - node-fetch@2.6.13: - resolution: {integrity: sha512-StxNAxh15zr77QvvkmveSQ8uCQ4+v5FkvNTj0OESmiHu+VRi/gXArXtkWMElOsOUNLtUEvI4yS+rdtOHZTwlQA==} + node-fetch@2.6.11: + resolution: {integrity: sha512-4I6pdBY1EthSqDmJkiNk3JIT8cswwR9nfeW/cPdUagJYEQG7R95WRH74wpz7ma8Gh/9dI9FP+OU+0E4FvtA55w==} engines: {node: 4.x || >=6.0.0} peerDependencies: encoding: ^0.1.0 @@ -8736,17 +9106,17 @@ packages: resolution: {integrity: sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==} engines: {node: '>= 6.13.0'} - node-gyp-build-optional-packages@5.2.2: - resolution: {integrity: sha512-s+w+rBWnpTMwSFbaE0UXsRlg7hU4FjekKU4eyAih5T8nJuNZT1nNsskXpxmeqSK9UzkBl6UgRlnKc8hz8IEqOw==} + node-gyp-build-optional-packages@5.0.7: + resolution: {integrity: sha512-YlCCc6Wffkx0kHkmam79GKvDQ6x+QZkMjFGrIMxgFNILFvGSbCp2fCBC55pGTT9gVaz8Na5CLmxt/urtzRv36w==} hasBin: true - node-gyp-build@4.8.4: - resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==} + node-gyp-build@4.8.2: + resolution: {integrity: sha512-IRUxE4BVsHWXkV/SFOut4qTlagw2aM8T5/vnTsmrHJvVoKueJHRc/JaFND7QDDc61kLYUJ6qlZM3sqTSyx2dTw==} hasBin: true - node-gyp@10.3.1: - resolution: {integrity: sha512-Pp3nFHBThHzVtNY7U6JfPjvT/DTE8+o/4xKsLQtBoU+j2HLsGlhcfzflAoUreaJbNmYnX+LlLi0qjV8kpyO6xQ==} - engines: {node: ^16.14.0 || >=18.0.0} + node-gyp@11.4.2: + resolution: {integrity: sha512-3gD+6zsrLQH7DyYOUIutaauuXrcyxeTPyQuZQCQoNPZMHMMS5m4y0xclNpvYzoK3VNzuyxT6eF4mkIL4WSZ1eQ==} + engines: {node: ^18.17.0 || >=20.5.0} hasBin: true node-int64@0.4.0: @@ -8755,8 +9125,11 @@ packages: node-releases@2.0.19: resolution: {integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==} - nodemailer@6.10.1: - resolution: {integrity: sha512-Z+iLaBGVaSjbIzQ4pX6XV41HrooLsQ10ZWPUehGmuantvzWoDVBnmsdUcOIDM1t+yPor5pDhVlDESgOMEGxhHA==} + node-releases@2.0.23: + resolution: {integrity: sha512-cCmFDMSm26S6tQSDpBCg/NR8NENrVPhAJSf+XbxBG4rPFaaonlEoE9wHQmun+cls499TQGSb7ZyPBRlzgKfpeg==} + + nodemailer@7.0.9: + resolution: {integrity: sha512-9/Qm0qXIByEP8lEV2qOqcAW7bRpL8CR9jcTwk3NBnHJNmP9fIJ86g2fgmIXqHY+nj55ZEMwWqYAT2QTDpRUYiQ==} engines: {node: '>=6.0.0'} nodemon@3.1.10: @@ -8768,14 +9141,23 @@ packages: resolution: {integrity: sha512-l2NNj07e9afPnhAhvgVrCD/oy2Ai1yfLpuo3EpiO1jFTsB4sFz6oIfAfSZyQzVpkZQ9xS8ZS5g1jCBgq4Hwo0g==} engines: {node: '>=12.19'} + nopt@1.0.10: + resolution: {integrity: sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==} + hasBin: true + nopt@5.0.0: resolution: {integrity: sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==} engines: {node: '>=6'} hasBin: true - nopt@7.2.1: - resolution: {integrity: sha512-taM24ViiimT/XntxbPyJQzCG+p4EKOpgD3mxFwW38mGjVUrfERQOeY4EDHjdnptttfHuHQXFx+lTP08Q+mLa/w==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + nopt@6.0.0: + resolution: {integrity: sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + hasBin: true + + nopt@8.1.0: + resolution: {integrity: sha512-ieGu42u/Qsa4TFktmaKEwM6MQH0pOWnaB3htzh0JRtx84+Mebc0cbZYN5bC+6WTZ4+77xrL9Pn5m7CV6VIkV7A==} + engines: {node: ^18.17.0 || >=20.5.0} hasBin: true normalize-package-data@2.5.0: @@ -8789,8 +9171,12 @@ packages: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} - normalize-url@8.0.2: - resolution: {integrity: sha512-Ee/R3SyN4BuynXcnTaekmaVdbDAEiNrHqjQIA37mHU8G9pf7aaAD4ZX3XjBLo6rsdcxA/gtkcNYZLt30ACgynw==} + normalize-url@8.0.1: + resolution: {integrity: sha512-IO9QvjUMWxPQQhs60oOu10CRkWCiZzSUkzbXGGV9pviYl1fXYcvkzQ5jV9z8Y6un8ARoVRl4EtC6v6jNqbaJ/w==} + engines: {node: '>=14.16'} + + normalize-url@8.1.0: + resolution: {integrity: sha512-X06Mfd/5aKsRHc0O0J5CUedwnPmnDtLF2+nq+KN9KSDlJHkPuh0JUviWjEWMe0SW/9TDdSLVPuk7L5gGTIA1/w==} engines: {node: '>=14.16'} npm-run-path@4.0.1: @@ -8818,8 +9204,8 @@ packages: nth-check@2.1.1: resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} - nwsapi@2.2.20: - resolution: {integrity: sha512-/ieB+mDe4MrrKMT8z+mQL8klXydZWGR5Dowt4RAGKbJ3kIGEx3X4ljUo+6V73IXtUPWgfOlU5B9MlGxFO5T+cA==} + nwsapi@2.2.16: + resolution: {integrity: sha512-F1I/bimDpj3ncaNDhfyMWuFqmQDBwDB0Fogc2qpL3BWvkQteFD/8BzWuIRl83rq0DXfm8SGt/HFhLXZyljTXcQ==} oauth2orize-pkce@0.1.2: resolution: {integrity: sha512-grto2UYhXHi9GLE3IBgBBbV87xci55+bCyjpVuxKyzol6I5Rg0K1MiTuXE+JZk54R86SG2wqXODMiZYHraPpxw==} @@ -8839,18 +9225,30 @@ packages: resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==} engines: {node: '>= 6'} + object-inspect@1.13.2: + resolution: {integrity: sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==} + engines: {node: '>= 0.4'} + object-inspect@1.13.4: resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} engines: {node: '>= 0.4'} - object-is@1.1.6: - resolution: {integrity: sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==} + object-is@1.1.5: + resolution: {integrity: sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==} engines: {node: '>= 0.4'} object-keys@1.1.1: resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} engines: {node: '>= 0.4'} + object.assign@4.1.4: + resolution: {integrity: sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==} + engines: {node: '>= 0.4'} + + object.assign@4.1.5: + resolution: {integrity: sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==} + engines: {node: '>= 0.4'} + object.assign@4.1.7: resolution: {integrity: sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==} engines: {node: '>= 0.4'} @@ -8867,19 +9265,15 @@ packages: resolution: {integrity: sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==} engines: {node: '>= 0.4'} - obliterator@2.0.5: - resolution: {integrity: sha512-42CPE9AhahZRsMNslczq0ctAEtqk8Eka26QofnqC346BZdHDySk3LWka23LI7ULIw11NmltpiLagIq8gBozxTw==} + obliterator@2.0.4: + resolution: {integrity: sha512-lgHwxlxV1qIg1Eap7LgIeoBWIMFibOjbrYPIPJZcI1mmGAI2m3lNYpK12Y+GBdPQ0U1hRwSord7GIaawz962qQ==} oblivious-set@1.4.0: resolution: {integrity: sha512-szyd0ou0T8nsAqHtprRcP3WidfsN1TnAR5yWXf2mFCEr5ek3LEOkT6EZ/92Xfs74HIdyhG5WkGxIssMU0jBaeg==} engines: {node: '>=16'} - obuf@1.1.2: - resolution: {integrity: sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==} - - on-exit-leak-free@2.1.2: - resolution: {integrity: sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==} - engines: {node: '>=14.0.0'} + on-exit-leak-free@2.1.0: + resolution: {integrity: sha512-VuCaZZAjReZ3vUwgOB8LxAosIurDiAW0s13rI1YwmaP++jvcxP77AWoQvenZebpCA2m8WC1/EosPYPMjnRAp/w==} on-finished@2.4.1: resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} @@ -8909,9 +9303,11 @@ packages: openapi-types@12.1.3: resolution: {integrity: sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw==} - openapi-typescript@6.7.6: - resolution: {integrity: sha512-c/hfooPx+RBIOPM09GSxABOZhYPblDoyaGhqBkD/59vtpN21jEuWKDlM0KYTvqJVlSYjKs0tBcIdeXKChlSPtw==} + openapi-typescript@7.9.1: + resolution: {integrity: sha512-9gJtoY04mk6iPMbToPjPxEAtfXZ0dTsMZtsgUI8YZta0btPPig9DJFP4jlerQD/7QOwYgb0tl+zLUpDf7vb7VA==} hasBin: true + peerDependencies: + typescript: ^5.x openmeteo@1.1.4: resolution: {integrity: sha512-TalTDl0M7JJoeRTf+rWiFZ9SLvoxm7KkFLOQqcSjCiYs+bVMhax1qtryJqeZ1RF4W4Xfsgcl9x+VC1z39ULCxA==} @@ -8921,8 +9317,8 @@ packages: resolution: {integrity: sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==} engines: {node: '>= 0.8.0'} - optionator@0.9.4: - resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} + optionator@0.9.3: + resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==} engines: {node: '>= 0.8.0'} os-utils@0.0.14: @@ -8931,8 +9327,8 @@ packages: ospath@1.2.2: resolution: {integrity: sha512-o6E5qJV5zkAbIDNhGSIlyOhScKXgQrSRMilfph0clDfM0nEnBOlKlH4sWDmG95BW/CvwNz0vmm7dJVtU2KlMiA==} - otpauth@9.4.0: - resolution: {integrity: sha512-fHIfzIG5RqCkK9cmV8WU+dPQr9/ebR5QOwGZn2JAr1RQF+lmAuLL2YdtdqvmBjNmgJlYk3KZ4a0XokaEhg1Jsw==} + otpauth@9.4.1: + resolution: {integrity: sha512-+iVvys36CFsyXEqfNftQm1II7SW23W1wx9RwNk0Cd97lbvorqAhBDksb/0bYry087QMxjiuBS0wokdoZ0iUeAw==} outvariant@1.4.3: resolution: {integrity: sha512-+Sl2UErvtsoajRDKCE5/dBz4DIvHXQQnAxtQTF04OJxY0+DyZXSo5P5Bb7XYWOh81syohlYL24hbDwxedPUJCA==} @@ -8961,6 +9357,10 @@ packages: resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} engines: {node: '>=10'} + p-limit@4.0.0: + resolution: {integrity: sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + p-locate@4.1.0: resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} engines: {node: '>=8'} @@ -8969,10 +9369,18 @@ packages: resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} engines: {node: '>=10'} + p-locate@6.0.0: + resolution: {integrity: sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + p-map@4.0.0: resolution: {integrity: sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==} engines: {node: '>=10'} + p-map@7.0.3: + resolution: {integrity: sha512-VkndIv2fIB99swvQoA65bm+fsmt6UNdGeIB0oxBs+WhAhdh08QA04JXpI7rbB9r08/nkbysKoya9rtDERYOYMA==} + engines: {node: '>=18'} + p-queue@6.6.2: resolution: {integrity: sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ==} engines: {node: '>=8'} @@ -8985,8 +9393,8 @@ packages: resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} engines: {node: '>=6'} - package-json-from-dist@1.0.1: - resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} + package-json-from-dist@1.0.0: + resolution: {integrity: sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==} parent-module@1.0.1: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} @@ -8996,6 +9404,10 @@ packages: resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} engines: {node: '>=8'} + parse-json@8.3.0: + resolution: {integrity: sha512-ybiGyvspI+fAoRQbIPRddCcSTV9/LsJbf0e/S85VLowVGzRmokfneg2kwVW/KU5rOXrPSbF1qAKPMgNTqqROQQ==} + engines: {node: '>=18'} + parse-ms@4.0.0: resolution: {integrity: sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==} engines: {node: '>=18'} @@ -9032,6 +9444,10 @@ packages: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} engines: {node: '>=8'} + path-exists@5.0.0: + resolution: {integrity: sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + path-is-absolute@1.0.1: resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} engines: {node: '>=0.10.0'} @@ -9055,6 +9471,9 @@ packages: resolution: {integrity: sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==} engines: {node: 20 || >=22} + path-to-regexp@0.1.10: + resolution: {integrity: sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==} + path-to-regexp@0.1.12: resolution: {integrity: sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==} @@ -9079,49 +9498,48 @@ packages: pause-stream@0.0.11: resolution: {integrity: sha512-e3FBlXLmN/D1S+zHzanP4E/4Z60oFAa3O051qt1pxa7DEJWKAyil6upYVXCWadEnuoqa4Pkc9oUx9zsxYeRv8A==} - peek-readable@5.4.2: - resolution: {integrity: sha512-peBp3qZyuS6cNIJ2akRNG1uo1WJ1d0wTxg/fxMdZ0BqCVhx242bSFHM9eNqflfJVS9SsgkzgT/1UgnsurBOTMg==} + peek-readable@5.3.1: + resolution: {integrity: sha512-GVlENSDW6KHaXcd9zkZltB7tCLosKB/4Hg0fqBJkAoBgYG2Tn1xtMgXtSUuMU9AK/gCm/tTdT8mgAeF4YNeeqw==} engines: {node: '>=14.16'} + peek-readable@7.0.0: + resolution: {integrity: sha512-nri2TO5JE3/mRryik9LlHFT53cgHfRK0Lt0BAZQXku/AW3E6XLt2GaY8siWi7dvW/m1z0ecn+J+bpDa9ZN3IsQ==} + engines: {node: '>=18'} + pend@1.2.0: resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==} performance-now@2.1.0: resolution: {integrity: sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==} - pg-cloudflare@1.2.5: - resolution: {integrity: sha512-OOX22Vt0vOSRrdoUPKJ8Wi2OpE/o/h9T8X1s4qSkCedbNah9ei2W2765be8iMVxQUsvgT7zIAT2eIa9fs5+vtg==} + pg-cloudflare@1.2.7: + resolution: {integrity: sha512-YgCtzMH0ptvZJslLM1ffsY4EuGaU0cx4XSdXLRFae8bPP4dS5xL1tNB3k2o/N64cHJpwU7dxKli/nZ2lUa5fLg==} - pg-connection-string@2.9.0: - resolution: {integrity: sha512-P2DEBKuvh5RClafLngkAuGe9OUlFV7ebu8w1kmaaOgPcpJd1RIFh7otETfI6hAR8YupOLFTY7nuvvIn7PLciUQ==} + pg-connection-string@2.9.1: + resolution: {integrity: sha512-nkc6NpDcvPVpZXxrreI/FOtX3XemeLl8E0qFr6F2Lrm/I8WOnaWNhIPK2Z7OHpw7gh5XJThi6j6ppgNoaT1w4w==} pg-int8@1.0.1: resolution: {integrity: sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==} engines: {node: '>=4.0.0'} - pg-numeric@1.0.2: - resolution: {integrity: sha512-BM/Thnrw5jm2kKLE5uJkXqqExRUY/toLHda65XgFTBTFYZyopbKjBe29Ii3RbkvlsMoFwD+tHeGaCjjv0gHlyw==} - engines: {node: '>=4'} - - pg-pool@3.10.0: - resolution: {integrity: sha512-DzZ26On4sQ0KmqnO34muPcmKbhrjmyiO4lCCR0VwEd7MjmiKf5NTg/6+apUEu0NF7ESa37CGzFxH513CoUmWnA==} + pg-pool@3.10.1: + resolution: {integrity: sha512-Tu8jMlcX+9d8+QVzKIvM/uJtp07PKr82IUOYEphaWcoBhIYkoHpLXN3qO59nAI11ripznDsEzEv8nUxBVWajGg==} peerDependencies: pg: '>=8.0' - pg-protocol@1.10.0: - resolution: {integrity: sha512-IpdytjudNuLv8nhlHs/UrVBhU0e78J0oIS/0AVdTbWxSOkFUVdsHC/NrorO6nXsQNDTT1kzDSOMJubBQviX18Q==} + pg-protocol@1.10.3: + resolution: {integrity: sha512-6DIBgBQaTKDJyxnXaLiLR8wBpQQcGWuAESkRBX/t6OwA8YsqP+iVSiond2EDy6Y/dsGk8rh/jtax3js5NeV7JQ==} + + pg-protocol@1.9.5: + resolution: {integrity: sha512-DYTWtWpfd5FOro3UnAfwvhD8jh59r2ig8bPtc9H8Ds7MscE/9NYruUQWFAOuraRl29jwcT2kyMFQ3MxeaVjUhg==} pg-types@2.2.0: resolution: {integrity: sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==} engines: {node: '>=4'} - pg-types@4.0.2: - resolution: {integrity: sha512-cRL3JpS3lKMGsKaWndugWQoLOCoP+Cic8oseVcbr0qhPzYD5DWXK+RZ9LY9wxRf7RQia4SCwQlXk0q6FCPrVng==} - engines: {node: '>=10'} - - pg@8.15.6: - resolution: {integrity: sha512-yvao7YI3GdmmrslNVsZgx9PfntfWrnXwtR+K/DjI0I/sTKif4Z623um+sjVZ1hk5670B+ODjvHDAckKdjmPTsg==} - engines: {node: '>= 8.0.0'} + pg@8.16.3: + resolution: {integrity: sha512-enxc1h0jA/aq5oSDMvqyW3q89ra6XIIDZgCX9vkMrnz5DFTw/Ny3Li2lFQ+pt3L6MCgm/5o2o8HW9hiJji+xvw==} + engines: {node: '>= 16.0.0'} peerDependencies: pg-native: '>=3.0.1' peerDependenciesMeta: @@ -9146,6 +9564,10 @@ packages: resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==} engines: {node: '>=12'} + picomatch@4.0.3: + resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} + engines: {node: '>=12'} + pid-port@1.0.2: resolution: {integrity: sha512-Khqp07zX8IJpmIg56bHrLxS3M0iSL4cq6wnMq8YE7r/hSw3Kn4QxYS6QJg8Bs22Z7CSVj7eSsxFuigYVIFWmjg==} engines: {node: '>=18'} @@ -9154,22 +9576,22 @@ packages: resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==} engines: {node: '>=0.10.0'} - pino-abstract-transport@2.0.0: - resolution: {integrity: sha512-F63x5tizV6WCh4R6RHyi2Ml+M70DNRXt/+HANowMflpgGFMAym/VKm6G7ZOQRjqN7XbGxK1Lg9t6ZrtzOaivMw==} + pino-abstract-transport@1.2.0: + resolution: {integrity: sha512-Guhh8EZfPCfH+PMXAb6rKOjGQEoy0xlAIn+irODG5kgfYV+BQ0rGYYWTIel3P5mmyXqkYkPmdIkywsn6QKUR1Q==} pino-std-serializers@7.0.0: resolution: {integrity: sha512-e906FRY0+tV27iq4juKzSYPbUj2do2X2JX4EzSca1631EB2QJQUqGbDuERal7LCtOpxl6x3+nvo9NPZcmjkiFA==} - pino@9.7.0: - resolution: {integrity: sha512-vnMCM6xZTb1WDmLvtG2lE/2p+t9hDEIvTWJsu6FejkE62vB7gDhvzrpFR4Cw2to+9JNQxVnkAKVPA1KPB98vWg==} + pino@9.3.2: + resolution: {integrity: sha512-WtARBjgZ7LNEkrGWxMBN/jvlFiE17LTbBoH0konmBU684Kd0uIiDwBXlcTCW7iJnA6HfIKwUssS/2AC6cDEanw==} hasBin: true - pirates@4.0.7: - resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==} + pirates@4.0.5: + resolution: {integrity: sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==} engines: {node: '>= 6'} - piscina@4.9.2: - resolution: {integrity: sha512-Fq0FERJWFEUpB4eSY59wSNwXD4RYqR+nR/WiEVcZW8IWfVBxJJafcgTEZDQo8k3w0sUarJ8RyVbbUF4GQ2LGbQ==} + piscina@4.4.0: + resolution: {integrity: sha512-+AQduEJefrOApE4bV7KRmp3N2JnnyErlVqq4P/jmko4FPz9Z877BCccl/iB3FdrWSUkvbGV9Kan/KllJgat3Vg==} pkce-challenge@4.1.0: resolution: {integrity: sha512-ZBmhE1C9LcPoH9XZSdwiPtbPHZROwAnMy+kIFQVrnMCxY4Cudlz3gBOpzilgc0jOgRaiT3sIWfpMomW2ar2orQ==} @@ -9179,29 +9601,32 @@ packages: resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} engines: {node: '>=8'} - plimit-lit@1.6.1: - resolution: {integrity: sha512-B7+VDyb8Tl6oMJT9oSO2CW8XC/T4UcJGrwOVoNGwOQsQYhlpfajmrMj5xeejqaASq3V/EqThyOeATEOMuSEXiA==} - engines: {node: '>=12'} + plimit-lit@1.5.0: + resolution: {integrity: sha512-Eb/MqCb1Iv/ok4m1FqIXqvUKPISufcjZ605hl3KM/n8GaX8zfhtgdLwZU3vKjuHGh2O9Rjog/bHTq8ofIShdng==} plur@4.0.0: resolution: {integrity: sha512-4UGewrYgqDFw9vV6zNV+ADmPAUAfJPKtGvb/VdpQAx25X5f3xXdGdyOEVFwkl8Hl/tl7+xbeHqSEM+D5/TirUg==} engines: {node: '>=10'} + pluralize@8.0.0: + resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} + engines: {node: '>=4'} + pngjs@5.0.0: resolution: {integrity: sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==} engines: {node: '>=10.13.0'} - pnpm@10.10.0: - resolution: {integrity: sha512-1hXbJG/nDyXc/qbY1z3ueCziPiJF48T2+Igkn7VoFJMYY33Kc8LFyO8qTKDVZX+5VnGIv6tH9WbR7mzph4FcOQ==} + pnpm@10.18.2: + resolution: {integrity: sha512-n7lp+nSbOt5gNeDxCfC4pgtdCKGof99y4zfakNzJMzbiKAyk5E8jWKZJuDwXlZ6Zk+d3wggIefOAHm8NmZrT3Q==} engines: {node: '>=18.12'} hasBin: true - polished@4.3.1: - resolution: {integrity: sha512-OBatVyC/N7SCW/FaDHrSd+vn0o5cS855TOmYi4OkdWUMSJCET/xip//ch8xGUvtr3i44X9LVyWwQlRMTN3pwSA==} + polished@4.2.2: + resolution: {integrity: sha512-Sz2Lkdxz6F2Pgnpi9U5Ng/WdWAUZxmHrNPoVlm3aAemxoy2Qy7LGjQg4uf8qKelDAUW94F4np3iH2YPf2qefcQ==} engines: {node: '>=10'} - possible-typed-array-names@1.1.0: - resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} + possible-typed-array-names@1.0.0: + resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==} engines: {node: '>= 0.4'} postcss-calc@10.1.1: @@ -9210,14 +9635,14 @@ packages: peerDependencies: postcss: ^8.4.38 - postcss-colormin@7.0.3: - resolution: {integrity: sha512-xZxQcSyIVZbSsl1vjoqZAcMYYdnJsIyG8OvqShuuqf12S88qQboxxEy0ohNCOLwVPXTU+hFHvJPACRL2B5ohTA==} + postcss-colormin@7.0.4: + resolution: {integrity: sha512-ziQuVzQZBROpKpfeDwmrG+Vvlr0YWmY/ZAk99XD+mGEBuEojoFekL41NCsdhyNUtZI7DPOoIWIR7vQQK9xwluw==} engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} peerDependencies: postcss: ^8.4.32 - postcss-convert-values@7.0.5: - resolution: {integrity: sha512-0VFhH8nElpIs3uXKnVtotDJJNX0OGYSZmdt4XfSfvOMrFw1jKfpwpZxfC4iN73CTM/MWakDEmsHQXkISYj4BXw==} + postcss-convert-values@7.0.7: + resolution: {integrity: sha512-HR9DZLN04Xbe6xugRH6lS4ZQH2zm/bFh/ZyRkpedZozhvh+awAfbA0P36InO4fZfDhvYfNJeNvlTf1sjwGbw/A==} engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} peerDependencies: postcss: ^8.4.32 @@ -9252,8 +9677,8 @@ packages: peerDependencies: postcss: ^8.4.32 - postcss-merge-rules@7.0.5: - resolution: {integrity: sha512-ZonhuSwEaWA3+xYbOdJoEReKIBs5eDiBVLAGpYZpNFPzXZcEE5VKR7/qBEQvTZpiwjqhhqEQ+ax5O3VShBj9Wg==} + postcss-merge-rules@7.0.6: + resolution: {integrity: sha512-2jIPT4Tzs8K87tvgCpSukRQ2jjd+hH6Bb8rEEOUDmmhOeTcqDg5fEFK8uKIu+Pvc3//sm3Uu6FRqfyv7YF7+BQ==} engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} peerDependencies: postcss: ^8.4.32 @@ -9270,8 +9695,8 @@ packages: peerDependencies: postcss: ^8.4.32 - postcss-minify-params@7.0.3: - resolution: {integrity: sha512-vUKV2+f5mtjewYieanLX0xemxIp1t0W0H/D11u+kQV/MWdygOO7xPMkbK+r9P6Lhms8MgzKARF/g5OPXhb8tgg==} + postcss-minify-params@7.0.4: + resolution: {integrity: sha512-3OqqUddfH8c2e7M35W6zIwv7jssM/3miF9cbCSb1iJiWvtguQjlxZGIHK9JRmc8XAKmE2PFGtHSM7g/VcW97sw==} engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} peerDependencies: postcss: ^8.4.32 @@ -9318,8 +9743,8 @@ packages: peerDependencies: postcss: ^8.4.32 - postcss-normalize-unicode@7.0.3: - resolution: {integrity: sha512-EcoA29LvG3F+EpOh03iqu+tJY3uYYKzArqKJHxDhUYLa2u58aqGq16K6/AOsXD9yqLN8O6y9mmePKN5cx6krOw==} + postcss-normalize-unicode@7.0.4: + resolution: {integrity: sha512-LvIURTi1sQoZqj8mEIE8R15yvM+OhbR1avynMtI9bUzj5gGKR/gfZFd8O7VMj0QgJaIFzxDwxGl/ASMYAkqO8g==} engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} peerDependencies: postcss: ^8.4.32 @@ -9342,8 +9767,8 @@ packages: peerDependencies: postcss: ^8.4.32 - postcss-reduce-initial@7.0.3: - resolution: {integrity: sha512-RFvkZaqiWtGMlVjlUHpaxGqEL27lgt+Q2Ixjf83CRAzqdo+TsDyGPtJUbPx2MuYIJ+sCQc2TrOvRnhcXQfgIVA==} + postcss-reduce-initial@7.0.4: + resolution: {integrity: sha512-rdIC9IlMBn7zJo6puim58Xd++0HdbvHeHaPgXsimMfG1ijC5A9ULvNLSE0rUKVJOvNMcwewW4Ga21ngyJjY/+Q==} engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} peerDependencies: postcss: ^8.4.32 @@ -9362,8 +9787,8 @@ packages: resolution: {integrity: sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==} engines: {node: '>=4'} - postcss-svgo@7.0.2: - resolution: {integrity: sha512-5Dzy66JlnRM6pkdOTF8+cGsB1fnERTE8Nc+Eed++fOWo1hdsBptCsbG8UuJkgtZt75bRtMJIrPeZmtfANixdFA==} + postcss-svgo@7.1.0: + resolution: {integrity: sha512-KnAlfmhtoLz6IuU3Sij2ycusNs4jPW+QoFE5kuuUOK8awR6tMxZQrs5Ey3BUz7nFCzT3eqyFgqkyrHiaU2xx3w==} engines: {node: ^18.12.0 || ^20.9.0 || >= 18} peerDependencies: postcss: ^8.4.32 @@ -9377,45 +9802,26 @@ packages: postcss-value-parser@4.2.0: resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} - postcss@8.5.3: - resolution: {integrity: sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==} + postcss@8.5.6: + resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} engines: {node: ^10 || ^12 || >=14} postgres-array@2.0.0: resolution: {integrity: sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==} engines: {node: '>=4'} - postgres-array@3.0.4: - resolution: {integrity: sha512-nAUSGfSDGOaOAEGwqsRY27GPOea7CNipJPOA7lPbdEpx5Kg3qzdP0AaWC5MlhTWV9s4hFX39nomVZ+C4tnGOJQ==} - engines: {node: '>=12'} - postgres-bytea@1.0.0: resolution: {integrity: sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==} engines: {node: '>=0.10.0'} - postgres-bytea@3.0.0: - resolution: {integrity: sha512-CNd4jim9RFPkObHSjVHlVrxoVQXz7quwNFpz7RY1okNNme49+sVyiTvTRobiLV548Hx/hb1BG+iE7h9493WzFw==} - engines: {node: '>= 6'} - postgres-date@1.0.7: resolution: {integrity: sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==} engines: {node: '>=0.10.0'} - postgres-date@2.1.0: - resolution: {integrity: sha512-K7Juri8gtgXVcDfZttFKVmhglp7epKb1K4pgrkLxehjqkrgPhfG6OO8LHLkfaqkbpjNRnra018XwAr1yQFWGcA==} - engines: {node: '>=12'} - postgres-interval@1.2.0: resolution: {integrity: sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==} engines: {node: '>=0.10.0'} - postgres-interval@3.0.0: - resolution: {integrity: sha512-BSNDnbyZCXSxgA+1f5UU2GmwhoI0aU5yMxRGO8CdFEcY2BQF9xm/7MqKnYoM1nJDk8nONNWDk9WeSmePFhQdlw==} - engines: {node: '>=12'} - - postgres-range@1.1.4: - resolution: {integrity: sha512-i/hbxIE9803Alj/6ytL7UHQxRvZkI9O4Sy+J3HGc4F4oo/2eQAjTSNJ0bfxyse3bH0nuVesCk+3IRLaMtG3H6w==} - prelude-ls@1.1.2: resolution: {integrity: sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==} engines: {node: '>= 0.8.0'} @@ -9424,8 +9830,8 @@ packages: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} - prettier@3.5.3: - resolution: {integrity: sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==} + prettier@3.6.2: + resolution: {integrity: sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==} engines: {node: '>=14'} hasBin: true @@ -9445,8 +9851,8 @@ packages: resolution: {integrity: sha512-4yf0QO/sllf/1zbZWYnvWw3NxCQwLXKzIj0G849LSufP15BXKM0rbD2Z3wVnkMfjdn/CB0Dpp444gYAACdsplg==} engines: {node: '>=18'} - prismjs@1.29.0: - resolution: {integrity: sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==} + prismjs@1.30.0: + resolution: {integrity: sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==} engines: {node: '>=6'} private-ip@3.0.2: @@ -9456,9 +9862,9 @@ packages: probe-image-size@7.2.3: resolution: {integrity: sha512-HubhG4Rb2UH8YtV4ba0Vp5bQ7L78RTONYu/ujmCu5nBI8wGv24s4E9xSKBi0N1MowRpxk76pFCpJtW0KPzOK0w==} - proc-log@4.2.0: - resolution: {integrity: sha512-g8+OnU/L2v+wyiVK+D5fA34J7EH8jZ8DDlvwhRCMxmMj7UCBvxiO1mGeN+36JXIKF4zevU4kRBd8lVgG9vLelA==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + proc-log@5.0.0: + resolution: {integrity: sha512-Azwzvl90HaF0aCz1JrDdXQykFakSSNPaPoiZ9fm5qJIMHioDZEi7OAdRwSm6rSoPtY3Qutnm3L7ogmg3dc+wbQ==} + engines: {node: ^18.17.0 || >=20.5.0} process-exists@5.0.0: resolution: {integrity: sha512-6QPRh5fyHD8MaXr4GYML8K/YY0Sq5dKHGIOrAKS3cYpHQdmygFCcijIu1dVoNKAZ0TWAMoeh8KDK9dF8auBkJA==} @@ -9467,8 +9873,8 @@ packages: process-nextick-args@2.0.1: resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} - process-warning@4.0.1: - resolution: {integrity: sha512-3c2LzQ3rY9d0hc1emcsHhfT9Jwz0cChib/QN89oME2R451w5fy3f0afAhERFZAwrbDU43wk12d0ORBpDVME50Q==} + process-warning@4.0.0: + resolution: {integrity: sha512-/MyYDxttz7DfGMMHiysAsFE4qF+pQYAA8ziO/3NcRVrQ5fSk+Mns4QZA/oRPFzvcqNoVJXQNWNAsdwBXLUkQKw==} process-warning@5.0.0: resolution: {integrity: sha512-a39t9ApHNx2L4+HBnQKqxxHNs1r7KF+Intd8Q/g1bUh6q0WIp9voPXJ/x0j+ZL45KF1pJd9+q2jLIRMfvEshkA==} @@ -9484,9 +9890,6 @@ packages: promise-limit@2.7.0: resolution: {integrity: sha512-7nJ6v5lnJsXwGprnGXga4wx6d1POjvi5Qmf1ivTRxTjH4Z/9Czja/UCMLVmB9N93GeWOU93XaFaEt6jbuoagNw==} - promise-polyfill@8.3.0: - resolution: {integrity: sha512-H5oELycFml5yto/atYqmjyigJoAo3+OXwolYiH7OfQuYlAqhxNvTfiNMbV9hsC6Yp83yE5r2KTVmtrG6R9i6Pg==} - promise-retry@2.0.1: resolution: {integrity: sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==} engines: {node: '>=10'} @@ -9498,8 +9901,8 @@ packages: resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} engines: {node: '>= 6'} - property-information@7.1.0: - resolution: {integrity: sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==} + property-information@7.0.0: + resolution: {integrity: sha512-7D/qOz/+Y4X/rzSB6jKxKUsQnphO046ei8qxG59mtM3RG3DHgTK81HrxrmoDVINJb8NKT5ZsRbwHvQ6B68Iyhg==} proto-list@1.2.4: resolution: {integrity: sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==} @@ -9515,12 +9918,8 @@ packages: peerDependencies: protobufjs: ^7.0.0 - protobufjs@7.2.4: - resolution: {integrity: sha512-AT+RJgD2sH8phPmCf7OUZR8xGdcJRga4+1cOaXJ64hvcSkVhNcRHOwIxUatPH15+nj59WAGTDv3LSGZPEQbJaQ==} - engines: {node: '>=12.0.0'} - - protobufjs@7.5.3: - resolution: {integrity: sha512-sildjKwVqOI2kmFDiXQ6aEB0fjYTafpEvIBs8tOR8qI4spuL9OPROLVu2qZqi/xgCfsHIwVqlaF8JBjWFHnKbw==} + protobufjs@7.2.3: + resolution: {integrity: sha512-TtpvOqwB5Gdz/PQmOjgsrGH1nHjAQVCN7JG4A6r1sXRWESL5rNMAiRcBQlCAdKxZcAbstExQePYG8xof/JVRgg==} engines: {node: '>=12.0.0'} proxy-addr@2.0.7: @@ -9542,9 +9941,6 @@ packages: engines: {node: '>= 0.10'} hasBin: true - psl@1.15.0: - resolution: {integrity: sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==} - pstree.remy@1.1.8: resolution: {integrity: sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==} @@ -9554,6 +9950,9 @@ packages: pug-code-gen@3.0.3: resolution: {integrity: sha512-cYQg0JW0w32Ux+XTeZnBEeuWrAY7/HNE6TWnhiHGnnRYlCgyAUPoyh9KzCMa9WhcJlJ1AtQqpEYHc+vbCzA+Aw==} + pug-error@2.0.0: + resolution: {integrity: sha512-sjiUsi9M4RAGHktC1drQfCr5C5eriu24Lfbt4s+7SykztEOwVZtbFk1RRq0tzLxcMxMYTBR+zMQaG07J/btayQ==} + pug-error@2.1.0: resolution: {integrity: sha512-lv7sU9e5Jk8IeUheHata6/UThZ7RK2jnaaNztxfPYUY+VxZyk/ePVaNZ/vwmH8WqGvDz3LrNYt/+gA55NDg6Pg==} @@ -9584,8 +9983,8 @@ packages: pug@3.0.3: resolution: {integrity: sha512-uBi6kmc9f3SZ3PXxqcHiUZLmIXgfgWooKWXcwSGwQd2Zi5Rb0bT14+8CJjJgI8AB+nndLaNgHGrcc6bPIB665g==} - pump@3.0.2: - resolution: {integrity: sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==} + pump@3.0.0: + resolution: {integrity: sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==} pumpify@2.0.1: resolution: {integrity: sha512-m7KOje7jZxrmutanlkS1daj1dS6z6BgslzOXmcSEpIlCxM3VJH7lG5QLeck/6hgF6F4crFf01UtQmNsJfweTAw==} @@ -9594,28 +9993,29 @@ packages: resolution: {integrity: sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==} engines: {node: '>=6'} - punycode@1.4.1: - resolution: {integrity: sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==} - punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} - pure-rand@6.1.0: - resolution: {integrity: sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==} + pure-rand@6.0.0: + resolution: {integrity: sha512-rLSBxJjP+4DQOgcJAx6RZHT2he2pkhQdSnofG5VWyVl6GRq/K02ISOuOLcsMOrtKDIJb8JN2zm3FFzWNbezdPw==} - pvtsutils@1.3.6: - resolution: {integrity: sha512-PLgQXQ6H2FWCaeRak8vvk1GW462lMxB5s3Jm673N82zI4vqtVUPuZdffdZbPDFRoU8kAhItWFtPCWiPpp4/EDg==} + pvtsutils@1.3.5: + resolution: {integrity: sha512-ARvb14YB9Nm2Xi6nBq1ZX6dAM0FsJnuk+31aUp4TrcZEdKUlSqOqsxJHUPJDNE3qiIp+iUPEIeR6Je/tgV7zsA==} pvutils@1.1.3: resolution: {integrity: sha512-pMpnA0qRdFp32b1sJl1wOJNxZLQ2cbQx+k6tjNtZ8CpvVhNqEPRgivZ2WOUev2YMajecdH7ctUPDvEe87nariQ==} engines: {node: '>=6.0.0'} - qrcode-generator@1.5.0: - resolution: {integrity: sha512-sqo7otiDq5rA4djRkFI7IjLQqxRrLpIou0d3rqr03JJLUGf5raPh91xCio+lFFbQf0SlcVckStz0EmDEX3EeZA==} + qr-code-styling@1.9.2: + resolution: {integrity: sha512-RgJaZJ1/RrXJ6N0j7a+pdw3zMBmzZU4VN2dtAZf8ZggCfRB5stEQ3IoDNGaNhYY3nnZKYlYSLl5YkfWN5dPutg==} + engines: {node: '>=18.18.0'} + + qr-scanner@1.4.2: + resolution: {integrity: sha512-kV1yQUe2FENvn59tMZW6mOVfpq9mGxGf8l6+EGaXUOd4RBOLg7tRC83OrirM5AtDvZRpdjdlXURsHreAOSPOUw==} - qrcode-vue3@1.7.1: - resolution: {integrity: sha512-Xa82NslFJUqsnQbLtc1qO+xPEOeFaTRxktg3ugRd2Pk116kta1X+7GLSEPQj9gor8jWVyfmLmhYZHuANnRZoLQ==} + qrcode-generator@1.4.4: + resolution: {integrity: sha512-HM7yY8O2ilqhmULxGMpcHSF1EhJJ9yBj8gvDEuZ6M+KGJ0YY2hKpnXvRD+hZPLrDVck3ExIGhmPtSdcjC+guuw==} qrcode@1.5.4: resolution: {integrity: sha512-1ca71Zgiu6ORjHqFBDpnSMTR2ReToX4l1Au1VFLyVeBTFavzQnv5JxMFr3ukHVKpSrSA2MCk0lNJSykjUfz7Zg==} @@ -9630,16 +10030,15 @@ packages: resolution: {integrity: sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==} engines: {node: '>=0.6'} - querystringify@2.2.0: - resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==} - - queue-lit@1.5.2: - resolution: {integrity: sha512-tLc36IOPeMAubu8BkW8YDBV+WyIgKlYU7zUNs0J5Vk9skSZ4JfGlPOqplP0aHdfv7HL0B2Pg6nwiq60Qc6M2Hw==} - engines: {node: '>=12'} + queue-lit@1.5.0: + resolution: {integrity: sha512-IslToJ4eiCEE9xwMzq3viOO5nH8sUWUCwoElrhNMozzr9IIt2qqvB4I+uHu/zJTQVqc9R5DFwok4ijNK1pU3fA==} queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + queue-tick@1.0.1: + resolution: {integrity: sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==} + quick-format-unescaped@4.0.4: resolution: {integrity: sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==} @@ -9677,31 +10076,31 @@ packages: resolution: {integrity: sha512-fUeWjrkOO0t1rg7B2fdyDTvngj+9RlUyL92vOdiB7c0FPguWVsniIMjEtHH+meLBO9rzkUlUzBVXgWrjI8P9LA==} engines: {node: '>=12'} - re2@1.21.4: - resolution: {integrity: sha512-MVIfXWJmsP28mRsSt8HeL750ifb8H5+oF2UDIxGaiJCr8fkMqhLZ7kcX9ADRk2dC8qeGKedB7UVYRfBVpEiLfA==} + re2@1.22.1: + resolution: {integrity: sha512-E4J0EtgyNLdIr0wTg0dQPefuiqNY29KaLacytiUAYYRzxCG+zOkWoUygt1rI+TA1LrhN49/njrfSO1DHtVC5Vw==} - react-docgen-typescript@2.4.0: - resolution: {integrity: sha512-ZtAp5XTO5HRzQctjPU0ybY0RRCQO19X/8fxn3w7y2VVTUbGHDKULPTL4ky3vB05euSgG5NpALhEhDPvQ56wvXg==} + react-docgen-typescript@2.2.2: + resolution: {integrity: sha512-tvg2ZtOpOi6QDwsb3GZhOjDkkX0h8Z2gipvTg6OVMUyoYoURhEiRNePT8NZItTVCDh39JJHnLdfCOkzoLbFnTg==} peerDependencies: typescript: '>= 4.3.x' - react-docgen@7.1.1: - resolution: {integrity: sha512-hlSJDQ2synMPKFZOsKo9Hi8WWZTC7POR8EmWvTSjow+VDgKzkmjQvFm2fk0tmRw+f0vTOIYKlarR0iL4996pdg==} - engines: {node: '>=16.14.0'} + react-docgen@8.0.2: + resolution: {integrity: sha512-+NRMYs2DyTP4/tqWz371Oo50JqmWltR1h2gcdgUMAWZJIAvrd0/SqlCfx7tpzpl/s36rzw6qH2MjoNrxtRNYhA==} + engines: {node: ^20.9.0 || >=22} - react-dom@19.1.0: - resolution: {integrity: sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==} + react-dom@19.2.0: + resolution: {integrity: sha512-UlbRu4cAiGaIewkPyiRGJk0imDN2T3JjieT6spoL2UeSf5od4n5LB/mQ4ejmxhCFT1tYe8IvaFulzynWovsEFQ==} peerDependencies: - react: ^19.1.0 + react: ^19.2.0 react-is@17.0.2: resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} - react-is@18.3.1: - resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} + react-is@18.2.0: + resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==} - react@19.1.0: - resolution: {integrity: sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==} + react@19.2.0: + resolution: {integrity: sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ==} engines: {node: '>=0.10.0'} read-pkg-up@7.0.1: @@ -9712,19 +10111,19 @@ packages: resolution: {integrity: sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==} engines: {node: '>=8'} - readable-stream@2.3.8: - resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} + readable-stream@2.3.7: + resolution: {integrity: sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==} - readable-stream@3.6.2: - resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} + readable-stream@3.6.0: + resolution: {integrity: sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==} engines: {node: '>= 6'} - readable-stream@4.7.0: - resolution: {integrity: sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==} + readable-stream@4.3.0: + resolution: {integrity: sha512-MuEnA0lbSi7JS8XM+WNJlWZkHAAdm7gETHdFK//Q/mChGyj2akEFtdLZh32jSdkWGbRwCW9pn6g3LWDdDeZnBQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - readdir-glob@1.1.3: - resolution: {integrity: sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==} + readdir-glob@1.1.2: + resolution: {integrity: sha512-6RLVvwJtVwEDfPdn6X6Ille4/lxGl0ATOY4FN/B9nxQcgOazvvI0nodiD19ScKq0PvA/29VpaOQML36o5IzZWA==} readdirp@4.1.2: resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} @@ -9734,8 +10133,8 @@ packages: resolution: {integrity: sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==} engines: {node: '>= 12.13.0'} - recast@0.23.11: - resolution: {integrity: sha512-YTUo+Flmw4ZXiWfQKGcwwc11KnoRAYgzAE2E7mXKCjSviTKShtxBsN6YUUBB2gtaBzKzeKunxhUwNHQuRryhWA==} + recast@0.23.7: + resolution: {integrity: sha512-MpQlLZVpqbbxYcqEjwpRWo88sGvjOYoXptySz710RuddNMHx+wPkoNX6YyLZJlXAh5VZr1qmPrTwcTuFMh0Lag==} engines: {node: '>= 4'} reconnecting-websocket@4.4.0: @@ -9770,8 +10169,8 @@ packages: regenerator-runtime@0.13.11: resolution: {integrity: sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==} - regenerator-runtime@0.14.1: - resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} + regenerator-runtime@0.14.0: + resolution: {integrity: sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==} regex-recursion@6.0.2: resolution: {integrity: sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==} @@ -9782,12 +10181,20 @@ packages: regex@6.0.1: resolution: {integrity: sha512-uorlqlzAKjKQZ5P+kTJr3eeJGSVroLKoHmquUj4zHWuR+hEyNqlXsSKlYYF5F4NI6nl7tWCs0apKJ0lmfsXAPA==} + regexp.prototype.flags@1.5.0: + resolution: {integrity: sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA==} + engines: {node: '>= 0.4'} + + regexp.prototype.flags@1.5.2: + resolution: {integrity: sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==} + engines: {node: '>= 0.4'} + regexp.prototype.flags@1.5.4: resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==} engines: {node: '>= 0.4'} - remark-gfm@4.0.1: - resolution: {integrity: sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==} + remark-gfm@4.0.0: + resolution: {integrity: sha512-U92vJgBPkbw4Zfu/IiW2oTZLSL3Zpv+uI7My2eq8JxKgqraFdU8YUGicEJCEgSbeaG+QDFqIcwwfMTOEelPxuA==} remark-parse@11.0.0: resolution: {integrity: sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==} @@ -9809,8 +10216,8 @@ packages: resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} engines: {node: '>=0.10.0'} - require-in-the-middle@7.5.2: - resolution: {integrity: sha512-gAZ+kLqBdHarXB64XpAe2VCjB7rIRv+mU8tfRWziHRJ5umKsIHN2tLLv6EtMw7WCdP19S0ERVMldNvxYCHnhSQ==} + require-in-the-middle@7.3.0: + resolution: {integrity: sha512-nQFEv9gRw6SJAwWD2LrL0NmQvAcO7FBwJbwmr2ttPAacfy0xuiOjE5zt+zM4xDyuyvUaxBi/9gb2SoCyNEVJcw==} engines: {node: '>=8.6.0'} require-main-filename@2.0.0: @@ -9820,9 +10227,6 @@ packages: resolution: {integrity: sha512-L9jEkOi3ASd9PYit2cwRfyppc9NoABujTP8/5gFcbERmo5jUoAKovIC3fsF17pkTnGsrByysqX+Kxd2OTNI1ww==} engines: {node: '>=0.10.5'} - requires-port@1.0.0: - resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} - requizzle@0.2.4: resolution: {integrity: sha512-JRrFk1D4OQ4SqovXOgdav+K8EAhSB/LJZqCz8tbX0KObcdeM15Ss59ozWMBWmmINMagCwmqn4ZNryUGpBsl6Jw==} @@ -9844,19 +10248,22 @@ packages: resolve-pkg-maps@1.0.0: resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} - resolve.exports@2.0.3: - resolution: {integrity: sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A==} + resolve.exports@2.0.0: + resolution: {integrity: sha512-6K/gDlqgQscOlg9fSRpWstA8sYe8rbELsSTNpx+3kTrsVCzvSl0zIvRErM7fdl9ERWDsKnrLnwB+Ne89918XOg==} engines: {node: '>=10'} - resolve@1.22.10: - resolution: {integrity: sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==} - engines: {node: '>= 0.4'} + resolve@1.22.8: + resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} hasBin: true responselike@3.0.0: resolution: {integrity: sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==} engines: {node: '>=14.16'} + responselike@4.0.2: + resolution: {integrity: sha512-cGk8IbWEAnaCpdAt1BHzJ3Ahz5ewDJa0KseTsE3qIRMJ3C698W8psM7byCeWVpd/Ha7FUYzuRVzXoKoM6nRUbA==} + engines: {node: '>=20'} + restore-cursor@3.1.0: resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==} engines: {node: '>=8'} @@ -9873,8 +10280,11 @@ packages: resolution: {integrity: sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==} engines: {node: '>= 4'} - reusify@1.1.0: - resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} + rettime@0.7.0: + resolution: {integrity: sha512-LPRKoHnLKd/r3dVxcwO7vhCW+orkOGj9ViueosEBK6ie89CijnfRlhaDhHq/3Hxu4CkWQtxwlBG0mzTQY6uQjw==} + + reusify@1.0.4: + resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} rfdc@1.4.1: @@ -9890,8 +10300,12 @@ packages: deprecated: Rimraf versions prior to v4 are no longer supported hasBin: true - rollup@4.40.0: - resolution: {integrity: sha512-Noe455xmA96nnqH5piFtLobsGbCij7Tu+tb3c1vYjNbTkfzGqXqQXG3wJaYXkRZuQ0vEYN4bhwg7QnIrqB5B+w==} + rimraf@5.0.10: + resolution: {integrity: sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==} + hasBin: true + + rollup@4.52.4: + resolution: {integrity: sha512-CLEVl+MnPAiKh5pl4dEWSyMTpuflgNQiLGhMv8ezD5W/qP8AKvmYpCOKRRNOh7oRKnauBZ4SyeYkMS+1VSyKwQ==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true @@ -9907,6 +10321,10 @@ packages: rxjs@7.8.2: resolution: {integrity: sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==} + safe-array-concat@1.1.2: + resolution: {integrity: sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==} + engines: {node: '>=0.4'} + safe-array-concat@1.1.3: resolution: {integrity: sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==} engines: {node: '>=0.4'} @@ -9921,28 +10339,35 @@ packages: resolution: {integrity: sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==} engines: {node: '>= 0.4'} + safe-regex-test@1.0.3: + resolution: {integrity: sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==} + engines: {node: '>= 0.4'} + safe-regex-test@1.1.0: resolution: {integrity: sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==} engines: {node: '>= 0.4'} - safe-regex2@5.0.0: - resolution: {integrity: sha512-YwJwe5a51WlK7KbOJREPdjNrpViQBI3p4T50lfwPuDhZnE3XGVTlGvi+aolc5+RvxDD6bnUmjVsU9n1eboLUYw==} + safe-regex2@4.0.0: + resolution: {integrity: sha512-Hvjfv25jPDVr3U+4LDzBuZPPOymELG3PYcSk5hcevooo1yxxamQL/bHs/GrEPGmMoMEwRrHVGiCA1pXi97B8Ew==} - safe-stable-stringify@2.5.0: - resolution: {integrity: sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==} + safe-stable-stringify@2.4.2: + resolution: {integrity: sha512-gMxvPJYhP0O9n2pvcfYfIuYgbledAOJFcqRThtPRmjscaipiwcwPPKLytpVzMkG2HAN87Qmo2d4PtGiri1dSLA==} engines: {node: '>=10'} safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - sanitize-html@2.16.0: - resolution: {integrity: sha512-0s4caLuHHaZFVxFTG74oW91+j6vW7gKbGD6CD2+miP73CE6z6YtOBN0ArtLd2UGyi4IC7K47v3ENUbQX4jV3Mg==} + sanitize-html@2.17.0: + resolution: {integrity: sha512-dLAADUSS8rBwhaevT12yCezvioCA+bmUTPH/u57xKPT8d++voeYE6HeluA/bPbQ15TwDBG2ii+QZIEmYx8VdxA==} - sass@1.87.0: - resolution: {integrity: sha512-d0NoFH4v6SjEK7BoX810Jsrhj7IQSYHAHLi/iSpgqKc7LaIDshFRlSg5LOymf9FqQhxEHs2W5ZQXlvy0KD45Uw==} + sass@1.93.2: + resolution: {integrity: sha512-t+YPtOQHpGW1QWsh1CHQ5cPIr9lbbGZLZnbihP/D/qZj/yuV68m8qarcV17nvkOX81BCrvzAlq2klCQFZghyTg==} engines: {node: '>=14.0.0'} hasBin: true + sax@1.2.4: + resolution: {integrity: sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==} + sax@1.4.1: resolution: {integrity: sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==} @@ -9950,8 +10375,8 @@ packages: resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==} engines: {node: '>=v12.22.7'} - scheduler@0.26.0: - resolution: {integrity: sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==} + scheduler@0.27.0: + resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==} secure-json-parse@2.7.0: resolution: {integrity: sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==} @@ -9977,8 +10402,8 @@ packages: resolution: {integrity: sha512-LJWA9kSvMolR51oDE6PN3kALBNaUdkxzAGcexw8gjMA8xr5zUqK0JiR3CgARSqanYF3Z1YHvsErb1KDgh+v7Rg==} engines: {node: '>=12'} - semver@5.7.2: - resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} + semver@5.7.1: + resolution: {integrity: sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==} hasBin: true semver@6.3.1: @@ -9990,8 +10415,8 @@ packages: engines: {node: '>=10'} hasBin: true - semver@7.7.1: - resolution: {integrity: sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==} + semver@7.7.3: + resolution: {integrity: sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==} engines: {node: '>=10'} hasBin: true @@ -10006,8 +10431,8 @@ packages: set-blocking@2.0.0: resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} - set-cookie-parser@2.7.1: - resolution: {integrity: sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==} + set-cookie-parser@2.6.0: + resolution: {integrity: sha512-RVnVQxTXuerk653XfuliOxBP81Sf0+qfQE73LIYKcyMYHG94AuH0kgrQpRDuTZnSmjpysHmzxJXKNfa6PjFhyQ==} set-function-length@1.2.2: resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} @@ -10027,8 +10452,9 @@ packages: setprototypeof@1.2.0: resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} - sha.js@2.4.11: - resolution: {integrity: sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==} + sha.js@2.4.12: + resolution: {integrity: sha512-8LzC5+bvI45BjpfXU8V5fdU2mfeKiQe1D1gIMn7XUlF3OTUrpdJpPPH4EMAnF0DsHHdSZqCdSss5qCmJKuiO3w==} + engines: {node: '>= 0.10'} hasBin: true sharp@0.33.5: @@ -10043,8 +10469,8 @@ packages: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} - shiki@3.3.0: - resolution: {integrity: sha512-j0Z1tG5vlOFGW8JVj0Cpuatzvshes7VJy5ncDmmMaYcmnGW0Js1N81TOW98ivTFNZfKRn9uwEg/aIm638o368g==} + shiki@3.13.0: + resolution: {integrity: sha512-aZW4l8Og16CokuCLf8CF8kq+KK2yOygapU5m3+hoGw0Mdosc6fPitjM+ujYarppj5ZIKGyPDPP1vqmQhr+5/0g==} shimmer@1.2.1: resolution: {integrity: sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==} @@ -10061,6 +10487,13 @@ packages: resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} engines: {node: '>= 0.4'} + side-channel@1.0.4: + resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==} + + side-channel@1.0.6: + resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==} + engines: {node: '>= 0.4'} + side-channel@1.1.0: resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} engines: {node: '>= 0.4'} @@ -10195,12 +10628,12 @@ packages: resolution: {integrity: sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==} engines: {node: '>= 14'} - socks@2.8.5: - resolution: {integrity: sha512-iF+tNDQla22geJdTyJB1wM/qrX9DMRwWrciEPwWLPRWAUEM8sQiyxgckLxWT1f7+9VabJS0jTGGr4QgBuvi6Ww==} + socks@2.8.7: + resolution: {integrity: sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A==} engines: {node: '>= 10.0.0', npm: '>= 3.0.0'} - sonic-boom@4.2.0: - resolution: {integrity: sha512-INb7TM37/mAcsGmc9hyyI6+QR3rR1zVRu36B0NeGXKnOOLiZOfER5SA+N7X7k3yUYRzLWafduTDvJAfDswwEww==} + sonic-boom@4.0.1: + resolution: {integrity: sha512-hTSD/6JMLyT4r9zeof6UtuBDpjJ9sO08/nmS5djaA9eozT9oOlNdpXSnzcgj4FTqpk3nkLrs61l4gip9r1HCrQ==} sort-keys-length@1.0.1: resolution: {integrity: sha512-GRbEOUqCxemTAk/b32F2xa8wDTs+Z1QHOkbhJDQTvv/6G3ZkbJ+frYWsTcc7cBB3Fu4wy4XlLCuNtJuMn7Gsvw==} @@ -10234,20 +10667,20 @@ packages: space-separated-tokens@2.0.2: resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} - spdx-correct@3.2.0: - resolution: {integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==} + spdx-correct@3.1.1: + resolution: {integrity: sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==} - spdx-exceptions@2.5.0: - resolution: {integrity: sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==} + spdx-exceptions@2.3.0: + resolution: {integrity: sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==} spdx-expression-parse@3.0.1: resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==} - spdx-license-ids@3.0.21: - resolution: {integrity: sha512-Bvg/8F5XephndSK3JffaRqdT+gyhfqIPwDHpX80tJrF8QQRYMo8sNMeaZ2Dp5+jhwKnUmIOyFFQfHRkjJm5nXg==} + spdx-license-ids@3.0.12: + resolution: {integrity: sha512-rr+VVSXtRhO4OHbXUiAF7xW3Bo9DuuF6C5jH+q/x15j2jniycgKbxU09Hr0WqlSLUs4i4ltHGXqTe7VHclYWyA==} - split2@4.2.0: - resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} + split2@4.1.0: + resolution: {integrity: sha512-VBiJxFkxiXRlUIeyMQi8s4hgvKCSjtknJv/LVYbrgALPwf5zSKmEwV9Lst25AkvMDnvxODugjdl6KZgwKM1WYQ==} engines: {node: '>= 10.x'} split@0.3.3: @@ -10259,18 +10692,23 @@ packages: sprintf-js@1.1.3: resolution: {integrity: sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==} - sql-highlight@6.1.0: - resolution: {integrity: sha512-ed7OK4e9ywpE7pgRMkMQmZDPKSVdm0oX5IEtZiKnFucSF0zu6c80GZBe38UqHuVhTWJ9xsKgSMjCG2bml86KvA==} + sql-highlight@6.0.0: + resolution: {integrity: sha512-+fLpbAbWkQ+d0JEchJT/NrRRXbYRNbG15gFpANx73EwxQB1PRjj+k/OI0GTU0J63g8ikGkJECQp9z8XEJZvPRw==} engines: {node: '>=14'} + sshpk@1.17.0: + resolution: {integrity: sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==} + engines: {node: '>=0.10.0'} + hasBin: true + sshpk@1.18.0: resolution: {integrity: sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==} engines: {node: '>=0.10.0'} hasBin: true - ssri@10.0.6: - resolution: {integrity: sha512-MGrFH9Z4NP9Iyhqn16sDtBpRRNJ0Y2hNa6D65h736fVSaPCHr4DM4sWUNvVaSuC+0OBGhwsrydQwmgfg5LncqQ==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + ssri@12.0.0: + resolution: {integrity: sha512-S7iGNosepx9RadX82oimUkvr0Ct7IjJbEbs4mJcTxst8um95J3sDYU1RBEOvdu6oL1Wek2ODI5i4MAw+dZ6cAQ==} + engines: {node: ^18.17.0 || >=20.5.0} stack-utils@2.0.6: resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} @@ -10282,8 +10720,8 @@ packages: standard-as-callback@2.1.0: resolution: {integrity: sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==} - start-server-and-test@2.0.11: - resolution: {integrity: sha512-TN39gLzPhHAflxyOkE/oMfQGj+pj3JgF6qVicFH/JrXt7xXktidKXwqfRga+ve7lVA8+RgPZVc25VrEPRScaDw==} + start-server-and-test@2.1.2: + resolution: {integrity: sha512-OIjfo3G6QV9Sh6IlMqj58oZwVhPVuU/l6uVACG7YNE9kAfDvcYoPThtb0NNT3tZMMC3wOYbXnC15yiCSNFkdRg==} engines: {node: '>=16'} hasBin: true @@ -10298,6 +10736,10 @@ packages: std-env@3.9.0: resolution: {integrity: sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==} + stop-iteration-iterator@1.0.0: + resolution: {integrity: sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ==} + engines: {node: '>= 0.4'} + stop-iteration-iterator@1.1.0: resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==} engines: {node: '>= 0.4'} @@ -10321,8 +10763,8 @@ packages: react-dom: optional: true - storybook@8.6.12: - resolution: {integrity: sha512-Z/nWYEHBTLK1ZBtAWdhxC0l5zf7ioJ7G4+zYqtTdYeb67gTnxNj80gehf8o8QY9L2zA2+eyMRGLC2V5fI7Z3Tw==} + storybook@9.1.10: + resolution: {integrity: sha512-4+U7gF9hMpGilQmdVJwQaVZZEkD7XwC4ZDmBa51mobaPYelELEMoMfNM2hLyvB2x12gk1IJui1DnwOE4t+MXhw==} hasBin: true peerDependencies: prettier: ^2 || ^3 @@ -10342,15 +10784,15 @@ packages: stream-parser@0.3.1: resolution: {integrity: sha512-bJ/HgKq41nlKvlhccD5kaCr/P+Hu0wPNKPJOH7en+YrJu/9EgqUF+88w5Jb6KNcjOFMhfX4B2asfeAtIGuHObQ==} - stream-shift@1.0.3: - resolution: {integrity: sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==} + stream-shift@1.0.1: + resolution: {integrity: sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==} streamsearch@1.1.0: resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} engines: {node: '>=10.0.0'} - streamx@2.22.1: - resolution: {integrity: sha512-znKXEBxfatz2GBNK02kRnCXjV+AA4kjZIUxeWSr3UGirZMJfTE9uiwKHobnbgxWyL/JWro8tTq+vOqAK1/qbSA==} + streamx@2.15.0: + resolution: {integrity: sha512-HcxY6ncGjjklGs1xsP1aR71INYcsXFJet5CU1CHqihQ2J5nOsbd4OjgjHO42w/4QNv9gZb3BueV+Vxok5pLEXg==} strict-event-emitter-types@2.0.0: resolution: {integrity: sha512-Nk/brWYpD85WlOgzw5h173aci0Teyv8YdIAEtV+N88nDB0dLlazZyJMIsN6eo1/AR61l+p6CJTG1JIyFaoNEEA==} @@ -10358,8 +10800,8 @@ packages: strict-event-emitter@0.5.1: resolution: {integrity: sha512-vMgjE/GGEPEFnhFub6pa4FmJBRBVOLpIII2hvCZ8Kzb7K0hlHo7mQv6xYrBvCL2LtAIBwFUK8wvuJgTVSQ5MFQ==} - string-argv@0.3.2: - resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==} + string-argv@0.3.1: + resolution: {integrity: sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==} engines: {node: '>=0.6.19'} string-length@4.0.2: @@ -10378,6 +10820,10 @@ packages: resolution: {integrity: sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==} engines: {node: '>= 0.4'} + string.prototype.trim@1.2.9: + resolution: {integrity: sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==} + engines: {node: '>= 0.4'} + string.prototype.trimend@1.0.9: resolution: {integrity: sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==} engines: {node: '>= 0.4'} @@ -10441,34 +10887,44 @@ packages: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} - strnum@1.1.2: - resolution: {integrity: sha512-vrN+B7DBIoTTZjnPNewwhx6cBA/H+IS7rfW68n7XxC1y7uoiGQBxaKzqucGUgavX15dJgiGztLJ8vxuEzwqBdA==} + strip-literal@3.1.0: + resolution: {integrity: sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg==} + + strnum@1.0.5: + resolution: {integrity: sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==} - strtok3@10.3.1: - resolution: {integrity: sha512-3JWEZM6mfix/GCJBBUrkA8p2Id2pBkyTkVCJKto55w080QBKZ+8R171fGrbiSp+yMO/u6F8/yUh7K4V9K+YCnw==} + strnum@2.1.1: + resolution: {integrity: sha512-7ZvoFTiCnGxBtDqJ//Cu6fWtZtc7Y3x+QOirG15wztbdngGSkht27o2pyGWrVy0b4WAy3jbKmnoK6g5VlVNUUw==} + + strtok3@10.2.2: + resolution: {integrity: sha512-Xt18+h4s7Z8xyZ0tmBoRmzxcop97R4BAh+dXouUDCYn+Em+1P3qpkUfI5ueWLT8ynC5hZ+q4iPEmGG1urvQGBg==} engines: {node: '>=18'} - strtok3@9.1.1: - resolution: {integrity: sha512-FhwotcEqjr241ZbjFzjlIYg6c5/L/s4yBGWSMvJ9UoExiSqL+FnFA/CaeZx17WGaZMS/4SOZp8wH18jSS4R4lw==} + strtok3@9.0.1: + resolution: {integrity: sha512-ERPW+XkvX9W2A+ov07iy+ZFJpVdik04GhDA4eVogiG9hpC97Kem2iucyzhFxbFRvQ5o2UckFtKZdp1hkGvnrEw==} engines: {node: '>=16'} stubs@3.0.0: resolution: {integrity: sha512-PdHt7hHUJKxvTCgbKX9C1V/ftOcjJQgz8BZwNfV5c4B6dcGqlpelTbJ999jBGZ2jYiPAwcX5dP6oBwVlBlUbxw==} - stylehacks@7.0.5: - resolution: {integrity: sha512-5kNb7V37BNf0Q3w+1pxfa+oiNPS++/b4Jil9e/kPDgrk1zjEd6uR7SZeJiYaLYH6RRSC1XX2/37OTeU/4FvuIA==} + stylehacks@7.0.6: + resolution: {integrity: sha512-iitguKivmsueOmTO0wmxURXBP8uqOO+zikLGZ7Mm9e/94R4w5T999Js2taS/KBOnQ/wdC3jN3vNSrkGDrlnqQg==} engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} peerDependencies: postcss: ^8.4.32 - superagent@9.0.2: - resolution: {integrity: sha512-xuW7dzkUpcJq7QnhOsnNUgtYp3xRwpt2F7abdRYIpCsAt0hhUqia0EdxyXZQQpNmGtsCzYHryaKSV3q3GJnq7w==} + superagent@10.2.3: + resolution: {integrity: sha512-y/hkYGeXAj7wUMjxRbB21g/l6aAEituGXM9Rwl4o20+SX3e8YOSV6BxFXl+dL3Uk0mjSL3kCbNkwURm8/gEDig==} engines: {node: '>=14.18.0'} - supertest@7.1.0: - resolution: {integrity: sha512-5QeSO8hSrKghtcWEoPiO036fxH0Ii2wVQfFZSP0oqQhmjk8bOLhDFXr4JrvaFmPuEWUoq4znY3uSi8UzLKxGqw==} + supertest@7.1.4: + resolution: {integrity: sha512-tjLPs7dVyqgItVFirHYqe2T+MfWc2VOBQ8QFKKbWTA3PU7liZR8zoSpAi/C1k1ilm9RsXIKYf197oap9wXGVYg==} engines: {node: '>=14.18.0'} + supports-color@10.2.2: + resolution: {integrity: sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g==} + engines: {node: '>=18'} + supports-color@5.5.0: resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} engines: {node: '>=4'} @@ -10481,10 +10937,6 @@ packages: resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} engines: {node: '>=10'} - supports-color@9.4.0: - resolution: {integrity: sha512-VL+lNrEoIXww1coLPOmiEmK/0sGigko5COxI09KzHc2VJXJsQ37UaQ+8quuxjDeA7+KnLGTWRyOXSLLR2Wb4jw==} - engines: {node: '>=12'} - supports-hyperlinks@2.3.0: resolution: {integrity: sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==} engines: {node: '>=8'} @@ -10493,20 +10945,29 @@ packages: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} - svgo@3.3.2: - resolution: {integrity: sha512-OoohrmuUlBs8B8o6MB2Aevn+pRIH9zDALSR+6hhqVfa6fRwG/Qw9VUMSMW9VNg2CFc/MTIfabtdOVl9ODIJjpw==} - engines: {node: '>=14.0.0'} + svgo@4.0.0: + resolution: {integrity: sha512-VvrHQ+9uniE+Mvx3+C9IEe/lWasXCU0nXMY2kZeLrHNICuRiC8uMPyM14UEaMOFA5mhyQqEkB02VoQ16n3DLaw==} + engines: {node: '>=16'} hasBin: true symbol-tree@3.2.4: resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} - systeminformation@5.25.11: - resolution: {integrity: sha512-jI01fn/t47rrLTQB0FTlMCC+5dYx8o0RRF+R4BPiUNsvg5OdY0s9DKMFmJGrx5SwMZQ4cag0Gl6v8oycso9b/g==} + systeminformation@5.27.11: + resolution: {integrity: sha512-K3Lto/2m3K2twmKHdgx5B+0in9qhXK4YnoT9rIlgwN/4v7OV5c8IjbeAUkuky/6VzCQC7iKCAqi8rZathCdjHg==} + engines: {node: '>=8.0.0'} + os: [darwin, linux, win32, freebsd, openbsd, netbsd, sunos, android] + hasBin: true + + systeminformation@5.27.7: + resolution: {integrity: sha512-saaqOoVEEFaux4v0K8Q7caiauRwjXC4XbD2eH60dxHXbpKxQ8kH9Rf7Jh+nryKpOUSEFxtCdBlSUx0/lO6rwRg==} engines: {node: '>=8.0.0'} os: [darwin, linux, win32, freebsd, openbsd, netbsd, sunos, android] hasBin: true + tar-stream@3.1.6: + resolution: {integrity: sha512-B/UyjYwPpMBv+PaFSWAmtYjwdrlEaZQEhMIBFNC5oEG8lpiW8XjcSdmEaClj28ArfKScKHs2nshz3k2le6crsg==} + tar-stream@3.1.7: resolution: {integrity: sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==} @@ -10514,8 +10975,8 @@ packages: resolution: {integrity: sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==} engines: {node: '>=10'} - tar@7.4.3: - resolution: {integrity: sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==} + tar@7.5.1: + resolution: {integrity: sha512-nlGpxf+hv0v7GkWBK2V9spgactGOp0qvfWRxUMjqHyzrt3SgwE48DIv/FhqPHJYLHpgW1opq3nERbz5Anq7n1g==} engines: {node: '>=18'} taskkill@5.0.0: @@ -10526,12 +10987,12 @@ packages: resolution: {integrity: sha512-jJZpA5He2y52yUhA7pyAGZlgQpcB+xLjcN0eUFxr9c8hP/H7uOXbBNVo/O0C/xVfJLJs680jvkFgVJEEvk9+ww==} engines: {node: '>=12'} - temml@0.11.6: - resolution: {integrity: sha512-XGgTdyP2tLse1IuCaGcHvbNja/yA7M6cNzOXB+slW1tnTuKReNx3egFUi25z9Rdg2wmhjZXDRLv1UV5BsaKjcw==} + temml@0.11.11: + resolution: {integrity: sha512-Z/Ihgwad+ges0ez6+KmKWZ3o4BYbP6aZ/cU94cVtN+DwxwqxjHgcF4Z6cb9jLkKN+aU7uni165HsIxLHs5/TqA==} engines: {node: '>=18.13.0'} - terser@5.39.0: - resolution: {integrity: sha512-LBAhFyLho16harJoWMg/nZsQYgTrg5jXOn2nCYjRUcZZEdE3qa2zb8QEDRUGVZBW4rlazf2fxkg8tztybTaqWw==} + terser@5.44.0: + resolution: {integrity: sha512-nIVck8DK+GM/0Frwd+nIhZ84pR/BX7rmXMfYwyg+Sri5oGVE99/E3KvXqpC2xHFxyqXyGHTKBSioxxplrO4I4w==} engines: {node: '>=10'} hasBin: true @@ -10543,9 +11004,6 @@ packages: resolution: {integrity: sha512-pFYqmTw68LXVjeWJMST4+borgQP2AyMNbg1BpZh9LbyhUeNkeaPF9gzfPGUAnSMV3qPYdWUwDIjjCLiSDOl7vg==} engines: {node: '>=18'} - text-decoder@1.2.3: - resolution: {integrity: sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA==} - textarea-caret@3.1.0: resolution: {integrity: sha512-cXAvzO9pP5CGa6NKx0WYHl+8CHKZs8byMkt3PCJBCmq2a34YA9pO1NrQET5pzeqnBjBdToF5No4rrmkDUgQC2Q==} @@ -10559,15 +11017,15 @@ packages: thread-stream@3.1.0: resolution: {integrity: sha512-OqyPZ9u96VohAyMfJykzmivOrY2wfMSf3C5TtFJVgN+Hm6aj+voFhlK+kZEIv2FBh1X6Xp3DlnCOfEQ3B2J86A==} - three@0.176.0: - resolution: {integrity: sha512-PWRKYWQo23ojf9oZSlRGH8K09q7nRSWx6LY/HF/UUrMdYgN9i1e2OwJYHoQjwc6HF/4lvvYLC5YC1X8UJL2ZpA==} + three@0.180.0: + resolution: {integrity: sha512-o+qycAMZrh+TsE01GqWUxUIKR1AL0S8pq7zDkYOQw8GqfX8b8VoCKYUoHbhiX5j+7hr8XsuHDVU6+gkQJQKg9w==} throttle-debounce@5.0.2: resolution: {integrity: sha512-B71/4oyj61iNH0KeCamLuE2rmKuTO5byTOSVwECM5FA7TiAiAW+UqTKZ9ERueC4qvgSttUhdmq1mXC3kJqGX7A==} engines: {node: '>=12.22'} - throttleit@1.0.1: - resolution: {integrity: sha512-vDZpf9Chs9mAdfY046mcPt8fg5QSZr37hEH4TXYBnDF+izxgrbRGUAAaBvIk/fJm9aOFCGFd1EsNg5AZCbnQCQ==} + throttleit@1.0.0: + resolution: {integrity: sha512-rkTVqu6IjfQ/6+uNuuc3sZek4CEYxTJom3IktzgdSxcZqdARuebbA/f4QmAxMQIxqq9ZLEUkSYqvuk1I6VKq4g==} through@2.3.8: resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} @@ -10575,6 +11033,9 @@ packages: tiny-emitter@2.1.0: resolution: {integrity: sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==} + tiny-glob@0.2.9: + resolution: {integrity: sha512-g/55ssRPUjShh+xkfx9UPDXqhckHEsHr4Vd9zX55oSdGZc/MD0m3sferOkwWtp98bv+kcVfEHtRJgBVJzelrzg==} + tiny-invariant@1.3.3: resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==} @@ -10587,8 +11048,12 @@ packages: tinyexec@0.3.2: resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} - tinyglobby@0.2.14: - resolution: {integrity: sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==} + tinyglobby@0.2.13: + resolution: {integrity: sha512-mEwzpUgrLySlveBwEVDMKk5B57bhLPYovRfPAXD5gA/98Opn0rCDj3GtLwFvCvH5RK9uPCExUROW5NjDwvqkxw==} + engines: {node: '>=12.0.0'} + + tinyglobby@0.2.15: + resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} engines: {node: '>=12.0.0'} tinyld@1.3.4: @@ -10596,8 +11061,8 @@ packages: engines: {node: '>= 12.10.0', npm: '>= 6.12.0', yarn: '>= 1.20.0'} hasBin: true - tinypool@1.1.0: - resolution: {integrity: sha512-7CotroY9a8DKsKprEy/a14aCCm8jYVmR7aFy4fpkZM8sdpNJbKkixuNjgM50yCmip2ezc8z4N7k3oe2+rfRJCQ==} + tinypool@1.1.1: + resolution: {integrity: sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==} engines: {node: ^18.0.0 || >=20.0.0} tinyrainbow@1.2.0: @@ -10612,23 +11077,42 @@ packages: resolution: {integrity: sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==} engines: {node: '>=14.0.0'} - tldts-core@6.1.86: - resolution: {integrity: sha512-Je6p7pkk+KMzMv2XXKmAE3McmolOQFdxkKw0R8EYNr7sELW46JqnNeTX8ybPiQgvg1ymCoF8LXs5fzFaZvJPTA==} + tinyspy@4.0.4: + resolution: {integrity: sha512-azl+t0z7pw/z958Gy9svOTuzqIk6xq+NSheJzn5MMWtWTFywIacg2wUlzKFGtt3cthx0r2SxMK0yzJOR0IES7Q==} + engines: {node: '>=14.0.0'} + + tldts-core@6.1.61: + resolution: {integrity: sha512-In7VffkDWUPgwa+c9picLUxvb0RltVwTkSgMNFgvlGSWveCzGBemBqTsgJCL4EDFWZ6WH0fKTsot6yNhzy3ZzQ==} - tldts@6.1.86: - resolution: {integrity: sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ==} + tldts-core@7.0.17: + resolution: {integrity: sha512-DieYoGrP78PWKsrXr8MZwtQ7GLCUeLxihtjC1jZsW1DnvSMdKPitJSe8OSYDM2u5H6g3kWJZpePqkp43TfLh0g==} + + tldts@6.1.61: + resolution: {integrity: sha512-rv8LUyez4Ygkopqn+M6OLItAOT9FF3REpPQDkdMx5ix8w4qkuE7Vo2o/vw1nxKQYmJDV8JpAMJQr1b+lTKf0FA==} + hasBin: true + + tldts@7.0.17: + resolution: {integrity: sha512-Y1KQBgDd/NUc+LfOtKS6mNsC9CCaH+m2P1RoIZy7RAPo3C3/t8X45+zgut31cRZtZ3xKPjfn3TkGTrctC2TQIQ==} hasBin: true - tmp@0.2.3: - resolution: {integrity: sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==} + tmp@0.2.5: + resolution: {integrity: sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==} engines: {node: '>=14.14'} tmpl@1.0.5: resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==} + to-buffer@1.2.2: + resolution: {integrity: sha512-db0E3UJjcFhpDhAF4tLo03oli3pwl3dbnzXOUIlRKrp+ldk/VUxzpWYZENsw2SZiuBjHAk7DfB0VU7NKdpb6sw==} + engines: {node: '>= 0.4'} + to-data-view@1.1.0: resolution: {integrity: sha512-1eAdufMg6mwgmlojAx3QeMnzB/BTVp7Tbndi3U7ftcT2zCZadjxkkmLmd97zmaxWi+sgGcgWrokmpEoy0Dn0vQ==} + to-fast-properties@2.0.0: + resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} + engines: {node: '>=4'} + to-regex-range@5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} @@ -10648,23 +11132,23 @@ packages: resolution: {integrity: sha512-lbDrTLVsHhOMljPscd0yitpozq7Ga2M5Cvez5AjGg8GASBjtt6iERCAJ93yommPmz62fb45oFIXHEZ3u9bfJEA==} engines: {node: '>=14.16'} - touch@3.1.1: - resolution: {integrity: sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==} + touch@3.1.0: + resolution: {integrity: sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==} hasBin: true - tough-cookie@4.1.4: - resolution: {integrity: sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==} - engines: {node: '>=6'} - tough-cookie@5.1.2: resolution: {integrity: sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A==} engines: {node: '>=16'} + tough-cookie@6.0.0: + resolution: {integrity: sha512-kXuRi1mtaKMrsLUxz3sQYvVl37B0Ns6MzfrtV5DvJceE9bPyspOqk9xxv7XbZWcfLWbFmm997vl83qUWVJA64w==} + engines: {node: '>=16'} + tr46@0.0.3: resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} - tr46@5.1.1: - resolution: {integrity: sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==} + tr46@5.0.0: + resolution: {integrity: sha512-tk2G5R2KRwBd+ZN0zaEXpmzdKyOYksXwywulIX95MBODjSzMIuQnQ3m8JxgbhnL1LeVo7lqQKsYa1O3Htl7K5g==} engines: {node: '>=18'} tree-kill@1.2.2: @@ -10697,8 +11181,8 @@ packages: ts-map@1.0.3: resolution: {integrity: sha512-vDWbsl26LIcPGmDpoVzjEP6+hvHZkBkLW7JpvwbCv/5IYPJlsbzCVXY3wsCeAxAUeTclNOUZxnLdGh3VBD/J6w==} - tsc-alias@1.8.15: - resolution: {integrity: sha512-yKLVx8ddUurRwhVcS6JFF2ZjksOX2ZWDRIdgt+PQhJBDegIdAdilptiHsuAbx9UFxa16GFrxeKQ2kTcGvR6fkQ==} + tsc-alias@1.8.16: + resolution: {integrity: sha512-QjCyu55NFyRSBAl6+MTFwplpFcnm2Pq01rR/uxfqJoLMm6X3O14KEGtaSDZpJYaE1bJBGDjD0eSuiIWPe2T58g==} engines: {node: '>=16.20.2'} hasBin: true @@ -10709,14 +11193,20 @@ packages: resolution: {integrity: sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==} engines: {node: '>=6'} - tsd@0.32.0: - resolution: {integrity: sha512-R5lBZCbxGBowOcW0gpQaiIjGYrG5NmU+PfFDKcc3zbtzWjML1o/zAwzdDnS2ZheSlPu9GW51azpFqEPUBq9DoQ==} + tsd@0.33.0: + resolution: {integrity: sha512-/PQtykJFVw90QICG7zyPDMIyueOXKL7jOJVoX5pILnb3Ux+7QqynOxfVvarE+K+yi7BZyOSY4r+OZNWSWRiEwQ==} engines: {node: '>=14.16'} hasBin: true tslib@1.14.1: resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} + tslib@2.6.2: + resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} + + tslib@2.7.0: + resolution: {integrity: sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==} + tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} @@ -10726,8 +11216,8 @@ packages: peerDependencies: typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta' - tsx@4.19.3: - resolution: {integrity: sha512-4H8vUNGNjQ4V2EOoGw005+c+dGuPSnhpPBPHBtsZdGZBk/iJb4kguGlPWaZTZ3q5nMtFOEsY0nRDlh9PJyd6SQ==} + tsx@4.20.6: + resolution: {integrity: sha512-ytQKuwgmrrkDTFP4LjR0ToE2nqgy886GpvRSpU0JAnrdBYppuY5rLkRUYPU1yCryb24SsKBTL/hlDQAEFVwtZg==} engines: {node: '>=18.0.0'} hasBin: true @@ -10749,10 +11239,6 @@ packages: resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} engines: {node: '>=4'} - type-detect@4.1.0: - resolution: {integrity: sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==} - engines: {node: '>=4'} - type-fest@0.18.1: resolution: {integrity: sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==} engines: {node: '>=10'} @@ -10781,18 +11267,34 @@ packages: resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} engines: {node: '>= 0.6'} + typed-array-buffer@1.0.2: + resolution: {integrity: sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==} + engines: {node: '>= 0.4'} + typed-array-buffer@1.0.3: resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==} engines: {node: '>= 0.4'} + typed-array-byte-length@1.0.1: + resolution: {integrity: sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==} + engines: {node: '>= 0.4'} + typed-array-byte-length@1.0.3: resolution: {integrity: sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==} engines: {node: '>= 0.4'} + typed-array-byte-offset@1.0.2: + resolution: {integrity: sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==} + engines: {node: '>= 0.4'} + typed-array-byte-offset@1.0.4: resolution: {integrity: sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==} engines: {node: '>= 0.4'} + typed-array-length@1.0.6: + resolution: {integrity: sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==} + engines: {node: '>= 0.4'} + typed-array-length@1.0.7: resolution: {integrity: sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==} engines: {node: '>= 0.4'} @@ -10804,15 +11306,14 @@ packages: typedarray@0.0.6: resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==} - typeorm@0.3.22: - resolution: {integrity: sha512-P/Tsz3UpJ9+K0oryC0twK5PO27zejLYYwMsE8SISfZc1lVHX+ajigiOyWsKbuXpEFMjD9z7UjLzY3+ElVOMMDA==} + typeorm@0.3.27: + resolution: {integrity: sha512-pNV1bn+1n8qEe8tUNsNdD8ejuPcMAg47u2lUGnbsajiNUr3p2Js1XLKQjBMH0yMRMDfdX8T+fIRejFmIwy9x4A==} engines: {node: '>=16.13.0'} hasBin: true peerDependencies: '@google-cloud/spanner': ^5.18.0 || ^6.0.0 || ^7.0.0 - '@sap/hana-client': ^2.12.25 - better-sqlite3: ^8.0.0 || ^9.0.0 || ^10.0.0 || ^11.0.0 - hdb-pool: ^0.1.6 + '@sap/hana-client': ^2.14.22 + better-sqlite3: ^8.0.0 || ^9.0.0 || ^10.0.0 || ^11.0.0 || ^12.0.0 ioredis: ^5.0.4 mongodb: ^5.8.0 || ^6.0.0 mssql: ^9.1.1 || ^10.0.1 || ^11.0.1 @@ -10821,7 +11322,7 @@ packages: pg: ^8.5.1 pg-native: ^3.0.0 pg-query-stream: ^4.0.0 - redis: ^3.1.1 || ^4.0.0 + redis: ^3.1.1 || ^4.0.0 || ^5.0.14 reflect-metadata: ^0.1.14 || ^0.2.0 sql.js: ^1.4.0 sqlite3: ^5.0.3 @@ -10834,8 +11335,6 @@ packages: optional: true better-sqlite3: optional: true - hdb-pool: - optional: true ioredis: optional: true mongodb: @@ -10868,16 +11367,16 @@ packages: engines: {node: '>=14.17'} hasBin: true - typescript@5.8.3: - resolution: {integrity: sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==} + typescript@5.9.3: + resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} engines: {node: '>=14.17'} hasBin: true - uc.micro@2.1.0: - resolution: {integrity: sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==} + uc.micro@1.0.6: + resolution: {integrity: sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==} - uglify-js@3.19.3: - resolution: {integrity: sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==} + uglify-js@3.17.4: + resolution: {integrity: sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==} engines: {node: '>=0.8.0'} hasBin: true @@ -10896,6 +11395,9 @@ packages: resolution: {integrity: sha512-fIRiVTJNcSRmXKPZtGzFQv9WRrZ3M9eoptl/teFJvjOzmpU+/K/JH6HZ8deBfb5vMEpicJcLn7JmvdknlMq7Zg==} hasBin: true + unbox-primitive@1.0.2: + resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} + unbox-primitive@1.1.0: resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} engines: {node: '>= 0.4'} @@ -10906,38 +11408,45 @@ packages: undefsafe@2.0.5: resolution: {integrity: sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==} - underscore@1.13.7: - resolution: {integrity: sha512-GMXzWtsc57XAtguZgaQViUOzs0KTkk8ojr3/xAxXLITqf/3EMwxC0inyETfDFjH/Krbhuep0HNbbjI9i/q3F3g==} + underscore@1.13.6: + resolution: {integrity: sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==} undici-types@6.21.0: resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} - undici@5.29.0: - resolution: {integrity: sha512-raqeBD6NQK4SkWhQzeYKd1KmIG6dllBOTt55Rmkt4HtI9mwdWtJljnrXjAFUBLTSN67HWrOIZ3EPF4kjUw80Bg==} + undici-types@7.16.0: + resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==} + + undici@5.28.5: + resolution: {integrity: sha512-zICwjrDrcrUE0pyyJc1I2QzBkLM8FINsgOrt6WjA+BgajVq9Nxu2PbFFXUrAggLfDXlZGZBVZYw7WNV5KiBiBA==} engines: {node: '>=14.0'} - undici@6.21.3: - resolution: {integrity: sha512-gBLkYIlEnSp8pFbT64yFgGE6UIB9tAkhukC23PmMDCe5Nd+cRqKxSjw5y54MK2AZMgZfJWMaNE4nYUHgi1XEOw==} + undici@6.19.8: + resolution: {integrity: sha512-U8uCCl2x9TK3WANvmBavymRzxbfFYG+tAu+fgx3zxQy3qdagQqBLwJVrdyO1TBfUXvfKveMKJZhpvUYoOjM+4g==} engines: {node: '>=18.17'} - undici@7.10.0: - resolution: {integrity: sha512-u5otvFBOBZvmdjWLVW+5DAc9Nkq8f24g0O9oY7qw2JVIF1VocIFoyz9JFkuVOS2j41AufeO0xnlweJ2RLT8nGw==} + undici@7.16.0: + resolution: {integrity: sha512-QEg3HPMll0o3t2ourKwOeUAZ159Kn9mx5pnzHRQO8+Wixmh88YdZRiIwat0iNzNNXn0yoEtXJqFpyW7eM8BV7g==} engines: {node: '>=20.18.1'} + unicorn-magic@0.1.0: + resolution: {integrity: sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==} + engines: {node: '>=18'} + unicorn-magic@0.3.0: resolution: {integrity: sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==} engines: {node: '>=18'} - unified@11.0.5: - resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==} + unified@11.0.4: + resolution: {integrity: sha512-apMPnyLjAX+ty4OrNap7yumyVAMlKx5IWU2wlzzUdYJO9A8f1p9m/gywF/GM2ZDFcjQPrx59Mc90KwmxsoklxQ==} - unique-filename@3.0.0: - resolution: {integrity: sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + unique-filename@4.0.0: + resolution: {integrity: sha512-XSnEewXmQ+veP7xX2dS5Q4yZAvO40cBN2MWkJ7D/6sW4Dg6wYBNwM1Vrnz1FhH5AdeLIlUXRI9e28z1YZi71NQ==} + engines: {node: ^18.17.0 || >=20.5.0} - unique-slug@4.0.0: - resolution: {integrity: sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + unique-slug@5.0.0: + resolution: {integrity: sha512-9OdaqO5kwqR+1kVgHAhsp5vPNU0hnxRa26rBFNfNgM7M6pNtgzeBn3s/xbyCQL3dcjzOatcef6UUHpB/6MaETg==} + engines: {node: ^18.17.0 || >=20.5.0} unist-util-is@6.0.0: resolution: {integrity: sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==} @@ -10958,12 +11467,8 @@ packages: resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} engines: {node: '>= 4.0.0'} - universalify@0.2.0: - resolution: {integrity: sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==} - engines: {node: '>= 4.0.0'} - - universalify@2.0.1: - resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} + universalify@2.0.0: + resolution: {integrity: sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==} engines: {node: '>= 10.0.0'} unload@2.4.1: @@ -10973,26 +11478,34 @@ packages: resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} engines: {node: '>= 0.8'} - unplugin@1.16.1: - resolution: {integrity: sha512-4/u/j4FrCKdi17jaxuJA0jClGxB1AvU2hw/IuayPc4ay1XGaJs/rbb4v5WKwAjNifjmXK9PIFyuPiaK8azyR9w==} - engines: {node: '>=14.0.0'} + unplugin@1.5.1: + resolution: {integrity: sha512-0QkvG13z6RD+1L1FoibQqnvTwVBXvS4XSPwAyinVgoOCl2jAgwzdUKmEj05o4Lt8xwQI85Hb6mSyYkcAGwZPew==} + + until-async@3.0.2: + resolution: {integrity: sha512-IiSk4HlzAMqTUseHHe3VhIGyuFmN90zMTpD3Z3y8jeQbzLIq500MVM7Jq2vUAnTKAFPJrqwkzr6PoTcPhGcOiw==} untildify@4.0.0: resolution: {integrity: sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==} engines: {node: '>=8'} + update-browserslist-db@1.1.2: + resolution: {integrity: sha512-PPypAm5qvlD7XMZC3BujecnaOxwhrtoFR+Dqkk5Aa/6DssiH0ibKoketaj9w8LP7Bont1rYeoV5plxD7RTEPRg==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + update-browserslist-db@1.1.3: resolution: {integrity: sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==} hasBin: true peerDependencies: browserslist: '>= 4.21.0' + uri-js-replace@1.0.1: + resolution: {integrity: sha512-W+C9NWNLFOoBI2QWDp4UT9pv65r2w5Cx+3sTYFvtMdDBxkKt1syCqsUdSFAChbEe1uK5TfS04wt/nGwmaeIQ0g==} + uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} - url-parse@1.5.10: - resolution: {integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==} - utf-8-validate@6.0.5: resolution: {integrity: sha512-EYZR+OpIXp9Y1eG1iueg8KRsY8TuT8VNgnanZ0uA3STqhHQTLwbl+WX76/9X5OY12yQubymBpaBSmMPkSTQcKA==} engines: {node: '>=6.14.2'} @@ -11000,9 +11513,6 @@ packages: util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} - util@0.12.5: - resolution: {integrity: sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==} - utils-merge@1.0.1: resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} engines: {node: '>= 0.4.0'} @@ -11011,10 +11521,18 @@ packages: resolution: {integrity: sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==} hasBin: true + uuid@13.0.0: + resolution: {integrity: sha512-XQegIaBTVUjSHliKqcnFqYypAd4S+WCYt5NIeRs6w/UAry7z8Y9j5ZwRRL4kzq9U3sD6v+85er9FvkEaBpji2w==} + hasBin: true + uuid@8.3.2: resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} hasBin: true + uuid@9.0.0: + resolution: {integrity: sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==} + hasBin: true + uuid@9.0.1: resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} hasBin: true @@ -11028,8 +11546,8 @@ packages: '@vue/composition-api': optional: true - v8-to-istanbul@9.3.0: - resolution: {integrity: sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==} + v8-to-istanbul@9.1.0: + resolution: {integrity: sha512-6z3GW9x8G1gd+JIIgQQQxXuiJtCXeAjp6RaPEPLv62mH3iPHPxV6W3robxtCzNErRo6ZwTmzWhsbNvjyEBKzKA==} engines: {node: '>=10.12.0'} valid-data-url@3.0.1: @@ -11050,33 +11568,51 @@ packages: vfile-message@4.0.2: resolution: {integrity: sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==} - vfile@6.0.3: - resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} + vfile@6.0.1: + resolution: {integrity: sha512-1bYqc7pt6NIADBJ98UiG0Bn/CHIVOoZ/IyEkqIruLg0mE1BKzkOXY2D6CSqQIcKqgadppE5lrxgWXJmXd7zZJw==} - vite-node@3.1.2: - resolution: {integrity: sha512-/8iMryv46J3aK13iUXsei5G/A3CUlW4665THCPS+K8xAaqrVWiGB4RfXMQXCLjpK9P2eK//BczrVkn5JLAk6DA==} + vite-node@3.2.4: + resolution: {integrity: sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==} engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} hasBin: true + vite-plugin-glsl@1.5.4: + resolution: {integrity: sha512-EUmwL+IDK+dGDAlaKm89++k8aJ4qmHjLQxrngww3GLOOAQ4aZ48o9YR1ie7XPe08iDWlG+9Uh5V7oiZcXTUbyA==} + engines: {node: '>= 20.17.0', npm: '>= 10.8.3'} + peerDependencies: + '@rollup/pluginutils': ^5.x + esbuild: '>= 0.25' + vite: '>= 3.x' + peerDependenciesMeta: + '@rollup/pluginutils': + optional: true + esbuild: + optional: true + vite-plugin-turbosnap@1.0.3: resolution: {integrity: sha512-p4D8CFVhZS412SyQX125qxyzOgIFouwOcvjZWk6bQbNPR1wtaEzFT6jZxAjf1dejlGqa6fqHcuCvQea6EWUkUA==} - vite@5.4.19: - resolution: {integrity: sha512-qO3aKv3HoQC8QKiNSTuUM1l9o/XX3+c+VTgLHbJWHZGeTPVAg2XwazI9UWzoxjIJCGCV2zU60uqMzjeLZuULqA==} - engines: {node: ^18.0.0 || >=20.0.0} + vite@7.1.7: + resolution: {integrity: sha512-VbA8ScMvAISJNJVbRDTJdCwqQoAareR/wutevKanhR2/1EkoXVZVkkORaYm/tNVCjP/UDTKtcw3bAkwOUdedmA==} + engines: {node: ^20.19.0 || >=22.12.0} hasBin: true peerDependencies: - '@types/node': ^18.0.0 || >=20.0.0 - less: '*' + '@types/node': ^20.19.0 || >=22.12.0 + jiti: '>=1.21.0' + less: ^4.0.0 lightningcss: ^1.21.0 - sass: '*' - sass-embedded: '*' - stylus: '*' - sugarss: '*' - terser: ^5.4.0 + sass: ^1.70.0 + sass-embedded: ^1.70.0 + stylus: '>=0.54.8' + sugarss: ^5.0.0 + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 peerDependenciesMeta: '@types/node': optional: true + jiti: + optional: true less: optional: true lightningcss: @@ -11091,20 +11627,24 @@ packages: optional: true terser: optional: true + tsx: + optional: true + yaml: + optional: true - vite@6.3.4: - resolution: {integrity: sha512-BiReIiMS2fyFqbqNT/Qqt4CVITDU9M9vE+DKcVAsB+ZV0wvTKd+3hMbkpxz1b+NmEDMegpVbisKiAZOnvO92Sw==} - engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} + vite@7.1.9: + resolution: {integrity: sha512-4nVGliEpxmhCL8DslSAUdxlB6+SMrhB0a1v5ijlh1xB1nEPuy1mxaHxysVucLHuWryAxLWg6a5ei+U4TLn/rFg==} + engines: {node: ^20.19.0 || >=22.12.0} hasBin: true peerDependencies: - '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 + '@types/node': ^20.19.0 || >=22.12.0 jiti: '>=1.21.0' - less: '*' + less: ^4.0.0 lightningcss: ^1.21.0 - sass: '*' - sass-embedded: '*' - stylus: '*' - sugarss: '*' + sass: ^1.70.0 + sass-embedded: ^1.70.0 + stylus: '>=0.54.8' + sugarss: ^5.0.0 terser: ^5.16.0 tsx: ^4.8.1 yaml: ^2.4.2 @@ -11138,16 +11678,21 @@ packages: peerDependencies: vitest: '>=2.0.0' - vitest@3.1.2: - resolution: {integrity: sha512-WaxpJe092ID1C0mr+LH9MmNrhfzi8I65EX/NRU/Ld016KqQNRgxSOlGNP1hHN+a/F8L15Mh8klwaF77zR3GeDQ==} + vitest-websocket-mock@0.5.0: + resolution: {integrity: sha512-vzBWeuF/kD/OCOFzB7WAclb7PxfI105qPkZtdOkPMwZdilBskQjJL4l319JtPtmeovDU7ZVhO3hTfGPjM4txQQ==} + peerDependencies: + vitest: '>=3' + + vitest@3.2.4: + resolution: {integrity: sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==} engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} hasBin: true peerDependencies: '@edge-runtime/vm': '*' '@types/debug': ^4.1.12 '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 - '@vitest/browser': 3.1.2 - '@vitest/ui': 3.1.2 + '@vitest/browser': 3.2.4 + '@vitest/ui': 3.2.4 happy-dom: '*' jsdom: '*' peerDependenciesMeta: @@ -11184,22 +11729,31 @@ packages: vscode-languageserver-types@3.17.5: resolution: {integrity: sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==} - vscode-uri@3.1.0: - resolution: {integrity: sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==} + vscode-uri@3.0.8: + resolution: {integrity: sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw==} - vue-component-meta@2.2.10: - resolution: {integrity: sha512-awylfiFFx/RFJKnu424R+btiGBEJgHa1RdJqb7SrbF5OKNYrL4VWkq49Fgvs/YbCsGSwVOjSl4em/mwOlrQ8/Q==} + vue-component-meta@2.0.19: + resolution: {integrity: sha512-Iv6VWXnlkUyJZvgadxYLcZajb58qUuIrQUePGbm0yZQEKMTb2T09UK57hz35TU4lb7zobierICDKvzInEpOGpg==} peerDependencies: typescript: '*' peerDependenciesMeta: typescript: optional: true - vue-component-type-helpers@2.2.10: - resolution: {integrity: sha512-iDUO7uQK+Sab2tYuiP9D1oLujCWlhHELHMgV/cB13cuGbG4qwkLHvtfWb6FzvxrIOPDnU0oHsz2MlQjhYDeaHA==} + vue-component-type-helpers@1.8.4: + resolution: {integrity: sha512-6bnLkn8O0JJyiFSIF0EfCogzeqNXpnjJ0vW/SZzNHfe6sPx30lTtTXlE5TFs2qhJlAtDFybStVNpL73cPe3OMQ==} + + vue-component-type-helpers@2.0.19: + resolution: {integrity: sha512-cN3f1aTxxKo4lzNeQAkVopswuImUrb5Iurll9Gaw5cqpnbTAxtEMM1mgi6ou4X79OCyqYv1U1mzBHJkzmiK82w==} + + vue-component-type-helpers@3.1.1: + resolution: {integrity: sha512-B0kHv7qX6E7+kdc5nsaqjdGZ1KwNKSUQDWGy7XkTYT7wFsOpkEyaJ1Vq79TjwrrtuLRgizrTV7PPuC4rRQo+vw==} + + vue-component-type-helpers@3.1.3: + resolution: {integrity: sha512-V1dOD8XYfstOKCnXbWyEJIrhTBMwSyNjv271L1Jlx9ExpNlCSuqOs3OdWrGJ0V544zXufKbcYabi/o+gK8lyfQ==} - vue-demi@0.14.10: - resolution: {integrity: sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==} + vue-demi@0.14.7: + resolution: {integrity: sha512-EOG8KXDQNwkJILkx/gPcoL/7vH+hORoBaKgGe+6W7VFMvCYJfmF2dGbvgDroVnI8LU7/kTu8mbjRZGBU1z9NTA==} engines: {node: '>=12'} hasBin: true peerDependencies: @@ -11209,13 +11763,13 @@ packages: '@vue/composition-api': optional: true - vue-docgen-api@4.79.2: - resolution: {integrity: sha512-n9ENAcs+40awPZMsas7STqjkZiVlIjxIKgiJr5rSohDP0/JCrD9VtlzNojafsA1MChm/hz2h3PDtUedx3lbgfA==} + vue-docgen-api@4.76.0: + resolution: {integrity: sha512-Nykmg/Net1BhoS1tENGqcevDdgha4us0x2Xnin7n5SxxAH6+s10FXTWtg7E9+jhC3GWEE83lcFHMS/Ml4C1dog==} peerDependencies: vue: '>=2' - vue-eslint-parser@10.1.3: - resolution: {integrity: sha512-dbCBnd2e02dYWsXoqX5yKUZlOt+ExIpq7hmHKPb5ZqKcjf++Eo0hMseFTZMLKThrUk61m+Uv6A2YSBve6ZvuDQ==} + vue-eslint-parser@10.2.0: + resolution: {integrity: sha512-CydUvFOQKD928UzZhTp4pr2vWz1L+H99t7Pkln2QSPdvmURT0MoC4wUccfCnuEaihNsu9aYYyk+bep8rlfkUXw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 @@ -11231,14 +11785,17 @@ packages: peerDependencies: vue: ^3.0.0 - vue-tsc@2.2.10: - resolution: {integrity: sha512-jWZ1xSaNbabEV3whpIDMbjVSVawjAyW+x1n3JeGQo7S0uv2n9F/JMgWW90tGWNFRKya4YwKMZgCtr0vRAM7DeQ==} + vue-template-compiler@2.7.14: + resolution: {integrity: sha512-zyA5Y3ArvVG0NacJDkkzJuPQDF8RFeRlzV2vLeSnhSpieO6LK2OVbdLPi5MPPs09Ii+gMO8nY4S3iKQxBxDmWQ==} + + vue-tsc@3.1.1: + resolution: {integrity: sha512-fyixKxFniOVgn+L/4+g8zCG6dflLLt01Agz9jl3TO45Bgk87NZJRmJVPsiK+ouq3LB91jJCbOV+pDkzYTxbI7A==} hasBin: true peerDependencies: typescript: '>=5.0.0' - vue@3.5.13: - resolution: {integrity: sha512-wmeiSMxkZCSc+PM2w2VRsOYAZC8GdipNFRTsLSfodVqI9mbejKeXEGr8SckuLnrQPGe3oJN5c3K0vpoU9q/wCQ==} + vue@3.5.22: + resolution: {integrity: sha512-toaZjQ3a/G/mYaLSbV+QsQhIdMo9x5rrqIpYRObsJ6T/J+RyCSFwN2LHNVH9v8uIcljDNa3QzPVdv3Y6b9hAJQ==} peerDependencies: typescript: '*' peerDependenciesMeta: @@ -11254,8 +11811,8 @@ packages: resolution: {integrity: sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==} engines: {node: '>=18'} - wait-on@8.0.3: - resolution: {integrity: sha512-nQFqAFzZDeRxsu7S3C7LbuxslHhk+gnJZHyethuGKAn2IVleIbTB9I3vJSQiSR+DifUqmdzfPMoMPJfLqMF2vw==} + wait-on@8.0.5: + resolution: {integrity: sha512-J3WlS0txVHkhLRb2FsmRg3dkMTCV1+M6Xra3Ho7HzZDHpE7DCOnoSoCJsZotrmW3uRMhvIJGSKUKrh/MeF4iag==} engines: {node: '>=12.0.0'} hasBin: true @@ -11266,6 +11823,10 @@ packages: resolution: {integrity: sha512-OSDqupzTlzl2LGyqTdhcXcl6ezMiFhcUwLBP8YKaBIbMYW1wAwDvupw2T9G9oVaKT9RmaSpyTXjxddFPUcFFIw==} engines: {node: '>=12'} + wawoff2@2.0.1: + resolution: {integrity: sha512-r0CEmvpH63r4T15ebFqeOjGqU4+EgTx4I510NtK35EMciSdcTxCw3Byy3JnBonz7iyIFZ0AbVo0bbFpEVuhCYA==} + hasBin: true + web-push@3.6.7: resolution: {integrity: sha512-OpiIUe8cuGjrj3mMBFWY+e4MMIkW3SVT+7vEIjvD9kejGUypv8GPDf84JdPWskK8zMRIJ6xYGm+Kxr8YkPyA0A==} engines: {node: '>= 16'} @@ -11275,8 +11836,8 @@ packages: resolution: {integrity: sha512-NlfnGF8MY9ZUwFjyq3vOUBx7KwF8bmE+ywR781SB0nWB6MoMxN4BA8gtgP1KGTZo/O/AyWJz7HZpR704eaj4mg==} engines: {node: '>=10.0.0'} - web-streams-polyfill@3.3.3: - resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==} + web-streams-polyfill@3.2.1: + resolution: {integrity: sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==} engines: {node: '>= 8'} webidl-conversions@3.0.1: @@ -11286,8 +11847,12 @@ packages: resolution: {integrity: sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==} engines: {node: '>=12'} - webpack-virtual-modules@0.6.2: - resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==} + webpack-sources@3.2.3: + resolution: {integrity: sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==} + engines: {node: '>=10.13.0'} + + webpack-virtual-modules@0.6.0: + resolution: {integrity: sha512-KnaMTE6EItz/f2q4Gwg5/rmeKVi79OR58NoYnwDJqCk9ywMtTGbBnBcfoBtN4QbYu0lWXvyMoH2Owxuhe4qI6Q==} whatwg-encoding@3.1.1: resolution: {integrity: sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==} @@ -11301,13 +11866,16 @@ packages: resolution: {integrity: sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==} engines: {node: '>=18'} - whatwg-url@14.2.0: - resolution: {integrity: sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==} + whatwg-url@14.1.1: + resolution: {integrity: sha512-mDGf9diDad/giZ/Sm9Xi2YcyzaFpbdLpJPr+E9fSkyQ7KpQD4SdFcugkRQYzhmfI4KeV4Qpnn2sKPdo+kmsgRQ==} engines: {node: '>=18'} whatwg-url@5.0.0: resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + which-boxed-primitive@1.0.2: + resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} + which-boxed-primitive@1.1.1: resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==} engines: {node: '>= 0.4'} @@ -11316,12 +11884,19 @@ packages: resolution: {integrity: sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==} engines: {node: '>= 0.4'} + which-collection@1.0.1: + resolution: {integrity: sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A==} + which-collection@1.0.2: resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} engines: {node: '>= 0.4'} - which-module@2.0.1: - resolution: {integrity: sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==} + which-module@2.0.0: + resolution: {integrity: sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==} + + which-typed-array@1.1.15: + resolution: {integrity: sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==} + engines: {node: '>= 0.4'} which-typed-array@1.1.19: resolution: {integrity: sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==} @@ -11336,9 +11911,9 @@ packages: engines: {node: '>= 8'} hasBin: true - which@4.0.0: - resolution: {integrity: sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==} - engines: {node: ^16.13.0 || >=18.0.0} + which@5.0.0: + resolution: {integrity: sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==} + engines: {node: ^18.17.0 || >=20.5.0} hasBin: true why-is-node-running@2.3.0: @@ -11353,8 +11928,8 @@ packages: resolution: {integrity: sha512-RNGKj82nUPg3g5ygxkQl0R937xLyho1J24ItRCBTr/m1YnZkzJy1hUiHUJrc/VlsDQzsCnInEGSg3bci0Lmd4w==} engines: {node: '>= 10.0.0'} - word-wrap@1.2.5: - resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} + word-wrap@1.2.3: + resolution: {integrity: sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==} engines: {node: '>=0.10.0'} wrap-ansi@6.2.0: @@ -11376,8 +11951,8 @@ packages: resolution: {integrity: sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} - ws@8.18.1: - resolution: {integrity: sha512-RKW2aJZMXeMxVpnZ6bck+RswznaxmzdULiBr6KY7XkTnW8uvt0iT9H5DkHUChXrc+uurzwa0rVI16n/Xzjdz1w==} + ws@8.18.3: + resolution: {integrity: sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==} engines: {node: '>=10.0.0'} peerDependencies: bufferutil: ^4.0.1 @@ -11438,6 +12013,9 @@ packages: resolution: {integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==} engines: {node: '>=18'} + yaml-ast-parser@0.0.43: + resolution: {integrity: sha512-2PTINUwsRqSd+s8XxKaJWQlUuEMHJQyEuh2edBbW8KNJz0SJPwUSD2zRWqezFEdN7IzAgeuYHFUCF7o8zRdZ0A==} + yargs-parser@18.1.3: resolution: {integrity: sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==} engines: {node: '>=6'} @@ -11473,6 +12051,10 @@ packages: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} + yocto-queue@1.2.1: + resolution: {integrity: sha512-AyeEbWOu/TAXdxlV9wmGcR0+yh2j3vYPGOECcIj2S7MkrLyC7ne+oye2BKTItt0ii2PHk4cDy+95+LshzbXnGg==} + engines: {node: '>=12.20'} + yoctocolors-cjs@2.1.2: resolution: {integrity: sha512-cYVsTjKl8b+FrnidjibDWskAv7UKOfcwaVZdp/it9n1s9fU3IkgDbhdIRKCW4JDsAlECJY0ytoVPT3sK6kideA==} engines: {node: '>=18'} @@ -11490,77 +12072,92 @@ packages: snapshots: - '@adobe/css-tools@4.4.3': {} + '@aashutoshrathi/word-wrap@1.2.6': {} + + '@adobe/css-tools@4.4.0': {} '@ampproject/remapping@2.3.0': dependencies: - '@jridgewell/gen-mapping': 0.3.8 - '@jridgewell/trace-mapping': 0.3.25 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 - '@analytics/cookie-utils@0.2.12': + '@analytics/cookie-utils@0.2.14': dependencies: - '@analytics/global-storage-utils': 0.1.7 + '@analytics/global-storage-utils': 0.1.9 - '@analytics/core@0.12.17(@types/dlv@1.1.5)': + '@analytics/core@0.13.2(@types/dlv@1.1.5)': dependencies: - '@analytics/global-storage-utils': 0.1.7 - '@analytics/type-utils': 0.6.2 - analytics-utils: 1.0.14(@types/dlv@1.1.5) + '@analytics/global-storage-utils': 0.1.9 + '@analytics/type-utils': 0.6.4 + analytics-utils: 1.1.1(@types/dlv@1.1.5) transitivePeerDependencies: - '@types/dlv' - '@analytics/global-storage-utils@0.1.7': + '@analytics/global-storage-utils@0.1.9': dependencies: - '@analytics/type-utils': 0.6.2 + '@analytics/type-utils': 0.6.4 '@analytics/google-analytics@1.1.0': {} - '@analytics/localstorage-utils@0.1.10': + '@analytics/localstorage-utils@0.1.12': + dependencies: + '@analytics/global-storage-utils': 0.1.9 + + '@analytics/session-storage-utils@0.0.9': dependencies: - '@analytics/global-storage-utils': 0.1.7 + '@analytics/global-storage-utils': 0.1.9 - '@analytics/session-storage-utils@0.0.7': + '@analytics/storage-utils@0.4.4': dependencies: - '@analytics/global-storage-utils': 0.1.7 + '@analytics/cookie-utils': 0.2.14 + '@analytics/global-storage-utils': 0.1.9 + '@analytics/localstorage-utils': 0.1.12 + '@analytics/session-storage-utils': 0.0.9 + '@analytics/type-utils': 0.6.4 + + '@analytics/type-utils@0.6.4': {} - '@analytics/storage-utils@0.4.2': + '@apidevtools/json-schema-ref-parser@14.2.1(@types/json-schema@7.0.15)': dependencies: - '@analytics/cookie-utils': 0.2.12 - '@analytics/global-storage-utils': 0.1.7 - '@analytics/localstorage-utils': 0.1.10 - '@analytics/session-storage-utils': 0.0.7 - '@analytics/type-utils': 0.6.2 + '@types/json-schema': 7.0.15 + js-yaml: 4.1.0 - '@analytics/type-utils@0.6.2': {} + '@apm-js-collab/code-transformer@0.8.2': {} - '@apidevtools/swagger-methods@3.0.2': {} + '@apm-js-collab/tracing-hooks@0.3.1': + dependencies: + '@apm-js-collab/code-transformer': 0.8.2 + debug: 4.4.3(supports-color@8.1.1) + module-details-from-path: 1.0.4 + transitivePeerDependencies: + - supports-color - '@asamuzakjp/css-color@3.2.0': + '@asamuzakjp/css-color@2.8.3': 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-color-parser': 3.0.10(@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/css-calc': 2.1.1(@csstools/css-parser-algorithms@3.0.4(@csstools/css-tokenizer@3.0.3))(@csstools/css-tokenizer@3.0.3) + '@csstools/css-color-parser': 3.0.7(@csstools/css-parser-algorithms@3.0.4(@csstools/css-tokenizer@3.0.3))(@csstools/css-tokenizer@3.0.3) + '@csstools/css-parser-algorithms': 3.0.4(@csstools/css-tokenizer@3.0.3) + '@csstools/css-tokenizer': 3.0.3 lru-cache: 10.4.3 '@aws-crypto/crc32@5.2.0': dependencies: '@aws-crypto/util': 5.2.0 - '@aws-sdk/types': 3.775.0 + '@aws-sdk/types': 3.901.0 tslib: 2.8.1 '@aws-crypto/crc32c@5.2.0': dependencies: '@aws-crypto/util': 5.2.0 - '@aws-sdk/types': 3.775.0 + '@aws-sdk/types': 3.901.0 tslib: 2.8.1 '@aws-crypto/sha1-browser@5.2.0': dependencies: '@aws-crypto/supports-web-crypto': 5.2.0 '@aws-crypto/util': 5.2.0 - '@aws-sdk/types': 3.775.0 - '@aws-sdk/util-locate-window': 3.804.0 + '@aws-sdk/types': 3.901.0 + '@aws-sdk/util-locate-window': 3.208.0 '@smithy/util-utf8': 2.3.0 tslib: 2.8.1 @@ -11569,15 +12166,15 @@ snapshots: '@aws-crypto/sha256-js': 5.2.0 '@aws-crypto/supports-web-crypto': 5.2.0 '@aws-crypto/util': 5.2.0 - '@aws-sdk/types': 3.775.0 - '@aws-sdk/util-locate-window': 3.804.0 + '@aws-sdk/types': 3.901.0 + '@aws-sdk/util-locate-window': 3.208.0 '@smithy/util-utf8': 2.3.0 tslib: 2.8.1 '@aws-crypto/sha256-js@5.2.0': dependencies: '@aws-crypto/util': 5.2.0 - '@aws-sdk/types': 3.775.0 + '@aws-sdk/types': 3.901.0 tslib: 2.8.1 '@aws-crypto/supports-web-crypto@5.2.0': @@ -11586,619 +12183,837 @@ snapshots: '@aws-crypto/util@5.2.0': dependencies: - '@aws-sdk/types': 3.775.0 + '@aws-sdk/types': 3.901.0 '@smithy/util-utf8': 2.3.0 tslib: 2.8.1 - '@aws-sdk/client-s3@3.797.0': + '@aws-sdk/client-s3@3.908.0': dependencies: '@aws-crypto/sha1-browser': 5.2.0 '@aws-crypto/sha256-browser': 5.2.0 '@aws-crypto/sha256-js': 5.2.0 - '@aws-sdk/core': 3.796.0 - '@aws-sdk/credential-provider-node': 3.797.0 - '@aws-sdk/middleware-bucket-endpoint': 3.775.0 - '@aws-sdk/middleware-expect-continue': 3.775.0 - '@aws-sdk/middleware-flexible-checksums': 3.796.0 - '@aws-sdk/middleware-host-header': 3.775.0 - '@aws-sdk/middleware-location-constraint': 3.775.0 - '@aws-sdk/middleware-logger': 3.775.0 - '@aws-sdk/middleware-recursion-detection': 3.775.0 - '@aws-sdk/middleware-sdk-s3': 3.796.0 - '@aws-sdk/middleware-ssec': 3.775.0 - '@aws-sdk/middleware-user-agent': 3.796.0 - '@aws-sdk/region-config-resolver': 3.775.0 - '@aws-sdk/signature-v4-multi-region': 3.796.0 - '@aws-sdk/types': 3.775.0 - '@aws-sdk/util-endpoints': 3.787.0 - '@aws-sdk/util-user-agent-browser': 3.775.0 - '@aws-sdk/util-user-agent-node': 3.796.0 - '@aws-sdk/xml-builder': 3.775.0 - '@smithy/config-resolver': 4.1.4 - '@smithy/core': 3.5.3 - '@smithy/eventstream-serde-browser': 4.0.4 - '@smithy/eventstream-serde-config-resolver': 4.1.2 - '@smithy/eventstream-serde-node': 4.0.4 - '@smithy/fetch-http-handler': 5.0.4 - '@smithy/hash-blob-browser': 4.0.4 - '@smithy/hash-node': 4.0.4 - '@smithy/hash-stream-node': 4.0.4 - '@smithy/invalid-dependency': 4.0.4 - '@smithy/md5-js': 4.0.4 - '@smithy/middleware-content-length': 4.0.4 - '@smithy/middleware-endpoint': 4.1.11 - '@smithy/middleware-retry': 4.1.12 - '@smithy/middleware-serde': 4.0.8 - '@smithy/middleware-stack': 4.0.4 - '@smithy/node-config-provider': 4.1.3 - '@smithy/node-http-handler': 4.0.6 - '@smithy/protocol-http': 5.1.2 - '@smithy/smithy-client': 4.4.3 - '@smithy/types': 4.3.1 - '@smithy/url-parser': 4.0.4 - '@smithy/util-base64': 4.0.0 - '@smithy/util-body-length-browser': 4.0.0 - '@smithy/util-body-length-node': 4.0.0 - '@smithy/util-defaults-mode-browser': 4.0.19 - '@smithy/util-defaults-mode-node': 4.0.19 - '@smithy/util-endpoints': 3.0.6 - '@smithy/util-middleware': 4.0.4 - '@smithy/util-retry': 4.0.5 - '@smithy/util-stream': 4.2.2 - '@smithy/util-utf8': 4.0.0 - '@smithy/util-waiter': 4.0.5 + '@aws-sdk/core': 3.908.0 + '@aws-sdk/credential-provider-node': 3.908.0 + '@aws-sdk/middleware-bucket-endpoint': 3.901.0 + '@aws-sdk/middleware-expect-continue': 3.901.0 + '@aws-sdk/middleware-flexible-checksums': 3.908.0 + '@aws-sdk/middleware-host-header': 3.901.0 + '@aws-sdk/middleware-location-constraint': 3.901.0 + '@aws-sdk/middleware-logger': 3.901.0 + '@aws-sdk/middleware-recursion-detection': 3.901.0 + '@aws-sdk/middleware-sdk-s3': 3.908.0 + '@aws-sdk/middleware-ssec': 3.901.0 + '@aws-sdk/middleware-user-agent': 3.908.0 + '@aws-sdk/region-config-resolver': 3.901.0 + '@aws-sdk/signature-v4-multi-region': 3.908.0 + '@aws-sdk/types': 3.901.0 + '@aws-sdk/util-endpoints': 3.901.0 + '@aws-sdk/util-user-agent-browser': 3.907.0 + '@aws-sdk/util-user-agent-node': 3.908.0 + '@aws-sdk/xml-builder': 3.901.0 + '@smithy/config-resolver': 4.3.0 + '@smithy/core': 3.15.0 + '@smithy/eventstream-serde-browser': 4.2.0 + '@smithy/eventstream-serde-config-resolver': 4.3.0 + '@smithy/eventstream-serde-node': 4.2.0 + '@smithy/fetch-http-handler': 5.3.1 + '@smithy/hash-blob-browser': 4.2.1 + '@smithy/hash-node': 4.2.0 + '@smithy/hash-stream-node': 4.2.0 + '@smithy/invalid-dependency': 4.2.0 + '@smithy/md5-js': 4.2.0 + '@smithy/middleware-content-length': 4.2.0 + '@smithy/middleware-endpoint': 4.3.1 + '@smithy/middleware-retry': 4.4.1 + '@smithy/middleware-serde': 4.2.0 + '@smithy/middleware-stack': 4.2.0 + '@smithy/node-config-provider': 4.3.0 + '@smithy/node-http-handler': 4.3.0 + '@smithy/protocol-http': 5.3.0 + '@smithy/smithy-client': 4.7.1 + '@smithy/types': 4.6.0 + '@smithy/url-parser': 4.2.0 + '@smithy/util-base64': 4.3.0 + '@smithy/util-body-length-browser': 4.2.0 + '@smithy/util-body-length-node': 4.2.1 + '@smithy/util-defaults-mode-browser': 4.3.0 + '@smithy/util-defaults-mode-node': 4.2.1 + '@smithy/util-endpoints': 3.2.0 + '@smithy/util-middleware': 4.2.0 + '@smithy/util-retry': 4.2.0 + '@smithy/util-stream': 4.5.0 + '@smithy/util-utf8': 4.2.0 + '@smithy/util-waiter': 4.2.0 + '@smithy/uuid': 1.1.0 + tslib: 2.8.1 + transitivePeerDependencies: + - aws-crt + + '@aws-sdk/client-ses@3.908.0': + dependencies: + '@aws-crypto/sha256-browser': 5.2.0 + '@aws-crypto/sha256-js': 5.2.0 + '@aws-sdk/core': 3.908.0 + '@aws-sdk/credential-provider-node': 3.908.0 + '@aws-sdk/middleware-host-header': 3.901.0 + '@aws-sdk/middleware-logger': 3.901.0 + '@aws-sdk/middleware-recursion-detection': 3.901.0 + '@aws-sdk/middleware-user-agent': 3.908.0 + '@aws-sdk/region-config-resolver': 3.901.0 + '@aws-sdk/types': 3.901.0 + '@aws-sdk/util-endpoints': 3.901.0 + '@aws-sdk/util-user-agent-browser': 3.907.0 + '@aws-sdk/util-user-agent-node': 3.908.0 + '@smithy/config-resolver': 4.3.0 + '@smithy/core': 3.15.0 + '@smithy/fetch-http-handler': 5.3.1 + '@smithy/hash-node': 4.2.0 + '@smithy/invalid-dependency': 4.2.0 + '@smithy/middleware-content-length': 4.2.0 + '@smithy/middleware-endpoint': 4.3.1 + '@smithy/middleware-retry': 4.4.1 + '@smithy/middleware-serde': 4.2.0 + '@smithy/middleware-stack': 4.2.0 + '@smithy/node-config-provider': 4.3.0 + '@smithy/node-http-handler': 4.3.0 + '@smithy/protocol-http': 5.3.0 + '@smithy/smithy-client': 4.7.1 + '@smithy/types': 4.6.0 + '@smithy/url-parser': 4.2.0 + '@smithy/util-base64': 4.3.0 + '@smithy/util-body-length-browser': 4.2.0 + '@smithy/util-body-length-node': 4.2.1 + '@smithy/util-defaults-mode-browser': 4.3.0 + '@smithy/util-defaults-mode-node': 4.2.1 + '@smithy/util-endpoints': 3.2.0 + '@smithy/util-middleware': 4.2.0 + '@smithy/util-retry': 4.2.0 + '@smithy/util-utf8': 4.2.0 + '@smithy/util-waiter': 4.2.0 tslib: 2.8.1 transitivePeerDependencies: - aws-crt - '@aws-sdk/client-sso@3.797.0': + '@aws-sdk/client-sso@3.908.0': dependencies: '@aws-crypto/sha256-browser': 5.2.0 '@aws-crypto/sha256-js': 5.2.0 - '@aws-sdk/core': 3.796.0 - '@aws-sdk/middleware-host-header': 3.775.0 - '@aws-sdk/middleware-logger': 3.775.0 - '@aws-sdk/middleware-recursion-detection': 3.775.0 - '@aws-sdk/middleware-user-agent': 3.796.0 - '@aws-sdk/region-config-resolver': 3.775.0 - '@aws-sdk/types': 3.775.0 - '@aws-sdk/util-endpoints': 3.787.0 - '@aws-sdk/util-user-agent-browser': 3.775.0 - '@aws-sdk/util-user-agent-node': 3.796.0 - '@smithy/config-resolver': 4.1.4 - '@smithy/core': 3.5.3 - '@smithy/fetch-http-handler': 5.0.4 - '@smithy/hash-node': 4.0.4 - '@smithy/invalid-dependency': 4.0.4 - '@smithy/middleware-content-length': 4.0.4 - '@smithy/middleware-endpoint': 4.1.11 - '@smithy/middleware-retry': 4.1.12 - '@smithy/middleware-serde': 4.0.8 - '@smithy/middleware-stack': 4.0.4 - '@smithy/node-config-provider': 4.1.3 - '@smithy/node-http-handler': 4.0.6 - '@smithy/protocol-http': 5.1.2 - '@smithy/smithy-client': 4.4.3 - '@smithy/types': 4.3.1 - '@smithy/url-parser': 4.0.4 - '@smithy/util-base64': 4.0.0 - '@smithy/util-body-length-browser': 4.0.0 - '@smithy/util-body-length-node': 4.0.0 - '@smithy/util-defaults-mode-browser': 4.0.19 - '@smithy/util-defaults-mode-node': 4.0.19 - '@smithy/util-endpoints': 3.0.6 - '@smithy/util-middleware': 4.0.4 - '@smithy/util-retry': 4.0.5 - '@smithy/util-utf8': 4.0.0 + '@aws-sdk/core': 3.908.0 + '@aws-sdk/middleware-host-header': 3.901.0 + '@aws-sdk/middleware-logger': 3.901.0 + '@aws-sdk/middleware-recursion-detection': 3.901.0 + '@aws-sdk/middleware-user-agent': 3.908.0 + '@aws-sdk/region-config-resolver': 3.901.0 + '@aws-sdk/types': 3.901.0 + '@aws-sdk/util-endpoints': 3.901.0 + '@aws-sdk/util-user-agent-browser': 3.907.0 + '@aws-sdk/util-user-agent-node': 3.908.0 + '@smithy/config-resolver': 4.3.0 + '@smithy/core': 3.15.0 + '@smithy/fetch-http-handler': 5.3.1 + '@smithy/hash-node': 4.2.0 + '@smithy/invalid-dependency': 4.2.0 + '@smithy/middleware-content-length': 4.2.0 + '@smithy/middleware-endpoint': 4.3.1 + '@smithy/middleware-retry': 4.4.1 + '@smithy/middleware-serde': 4.2.0 + '@smithy/middleware-stack': 4.2.0 + '@smithy/node-config-provider': 4.3.0 + '@smithy/node-http-handler': 4.3.0 + '@smithy/protocol-http': 5.3.0 + '@smithy/smithy-client': 4.7.1 + '@smithy/types': 4.6.0 + '@smithy/url-parser': 4.2.0 + '@smithy/util-base64': 4.3.0 + '@smithy/util-body-length-browser': 4.2.0 + '@smithy/util-body-length-node': 4.2.1 + '@smithy/util-defaults-mode-browser': 4.3.0 + '@smithy/util-defaults-mode-node': 4.2.1 + '@smithy/util-endpoints': 3.2.0 + '@smithy/util-middleware': 4.2.0 + '@smithy/util-retry': 4.2.0 + '@smithy/util-utf8': 4.2.0 tslib: 2.8.1 transitivePeerDependencies: - aws-crt - '@aws-sdk/core@3.796.0': - dependencies: - '@aws-sdk/types': 3.775.0 - '@smithy/core': 3.5.3 - '@smithy/node-config-provider': 4.1.3 - '@smithy/property-provider': 4.0.4 - '@smithy/protocol-http': 5.1.2 - '@smithy/signature-v4': 5.1.2 - '@smithy/smithy-client': 4.4.3 - '@smithy/types': 4.3.1 - '@smithy/util-middleware': 4.0.4 - fast-xml-parser: 4.4.1 + '@aws-sdk/core@3.908.0': + dependencies: + '@aws-sdk/types': 3.901.0 + '@aws-sdk/xml-builder': 3.901.0 + '@smithy/core': 3.15.0 + '@smithy/node-config-provider': 4.3.0 + '@smithy/property-provider': 4.2.0 + '@smithy/protocol-http': 5.3.0 + '@smithy/signature-v4': 5.3.0 + '@smithy/smithy-client': 4.7.1 + '@smithy/types': 4.6.0 + '@smithy/util-base64': 4.3.0 + '@smithy/util-middleware': 4.2.0 + '@smithy/util-utf8': 4.2.0 tslib: 2.8.1 - '@aws-sdk/credential-provider-env@3.796.0': + '@aws-sdk/credential-provider-env@3.908.0': dependencies: - '@aws-sdk/core': 3.796.0 - '@aws-sdk/types': 3.775.0 - '@smithy/property-provider': 4.0.4 - '@smithy/types': 4.3.1 + '@aws-sdk/core': 3.908.0 + '@aws-sdk/types': 3.901.0 + '@smithy/property-provider': 4.2.0 + '@smithy/types': 4.6.0 tslib: 2.8.1 - '@aws-sdk/credential-provider-http@3.796.0': - dependencies: - '@aws-sdk/core': 3.796.0 - '@aws-sdk/types': 3.775.0 - '@smithy/fetch-http-handler': 5.0.4 - '@smithy/node-http-handler': 4.0.6 - '@smithy/property-provider': 4.0.4 - '@smithy/protocol-http': 5.1.2 - '@smithy/smithy-client': 4.4.3 - '@smithy/types': 4.3.1 - '@smithy/util-stream': 4.2.2 + '@aws-sdk/credential-provider-http@3.908.0': + dependencies: + '@aws-sdk/core': 3.908.0 + '@aws-sdk/types': 3.901.0 + '@smithy/fetch-http-handler': 5.3.1 + '@smithy/node-http-handler': 4.3.0 + '@smithy/property-provider': 4.2.0 + '@smithy/protocol-http': 5.3.0 + '@smithy/smithy-client': 4.7.1 + '@smithy/types': 4.6.0 + '@smithy/util-stream': 4.5.0 tslib: 2.8.1 - '@aws-sdk/credential-provider-ini@3.797.0': - dependencies: - '@aws-sdk/core': 3.796.0 - '@aws-sdk/credential-provider-env': 3.796.0 - '@aws-sdk/credential-provider-http': 3.796.0 - '@aws-sdk/credential-provider-process': 3.796.0 - '@aws-sdk/credential-provider-sso': 3.797.0 - '@aws-sdk/credential-provider-web-identity': 3.797.0 - '@aws-sdk/nested-clients': 3.797.0 - '@aws-sdk/types': 3.775.0 - '@smithy/credential-provider-imds': 4.0.6 - '@smithy/property-provider': 4.0.4 - '@smithy/shared-ini-file-loader': 4.0.4 - '@smithy/types': 4.3.1 + '@aws-sdk/credential-provider-ini@3.908.0': + dependencies: + '@aws-sdk/core': 3.908.0 + '@aws-sdk/credential-provider-env': 3.908.0 + '@aws-sdk/credential-provider-http': 3.908.0 + '@aws-sdk/credential-provider-process': 3.908.0 + '@aws-sdk/credential-provider-sso': 3.908.0 + '@aws-sdk/credential-provider-web-identity': 3.908.0 + '@aws-sdk/nested-clients': 3.908.0 + '@aws-sdk/types': 3.901.0 + '@smithy/credential-provider-imds': 4.2.0 + '@smithy/property-provider': 4.2.0 + '@smithy/shared-ini-file-loader': 4.3.0 + '@smithy/types': 4.6.0 tslib: 2.8.1 transitivePeerDependencies: - aws-crt - '@aws-sdk/credential-provider-node@3.797.0': - dependencies: - '@aws-sdk/credential-provider-env': 3.796.0 - '@aws-sdk/credential-provider-http': 3.796.0 - '@aws-sdk/credential-provider-ini': 3.797.0 - '@aws-sdk/credential-provider-process': 3.796.0 - '@aws-sdk/credential-provider-sso': 3.797.0 - '@aws-sdk/credential-provider-web-identity': 3.797.0 - '@aws-sdk/types': 3.775.0 - '@smithy/credential-provider-imds': 4.0.6 - '@smithy/property-provider': 4.0.4 - '@smithy/shared-ini-file-loader': 4.0.4 - '@smithy/types': 4.3.1 + '@aws-sdk/credential-provider-node@3.908.0': + dependencies: + '@aws-sdk/credential-provider-env': 3.908.0 + '@aws-sdk/credential-provider-http': 3.908.0 + '@aws-sdk/credential-provider-ini': 3.908.0 + '@aws-sdk/credential-provider-process': 3.908.0 + '@aws-sdk/credential-provider-sso': 3.908.0 + '@aws-sdk/credential-provider-web-identity': 3.908.0 + '@aws-sdk/types': 3.901.0 + '@smithy/credential-provider-imds': 4.2.0 + '@smithy/property-provider': 4.2.0 + '@smithy/shared-ini-file-loader': 4.3.0 + '@smithy/types': 4.6.0 tslib: 2.8.1 transitivePeerDependencies: - aws-crt - '@aws-sdk/credential-provider-process@3.796.0': + '@aws-sdk/credential-provider-process@3.908.0': dependencies: - '@aws-sdk/core': 3.796.0 - '@aws-sdk/types': 3.775.0 - '@smithy/property-provider': 4.0.4 - '@smithy/shared-ini-file-loader': 4.0.4 - '@smithy/types': 4.3.1 + '@aws-sdk/core': 3.908.0 + '@aws-sdk/types': 3.901.0 + '@smithy/property-provider': 4.2.0 + '@smithy/shared-ini-file-loader': 4.3.0 + '@smithy/types': 4.6.0 tslib: 2.8.1 - '@aws-sdk/credential-provider-sso@3.797.0': + '@aws-sdk/credential-provider-sso@3.908.0': dependencies: - '@aws-sdk/client-sso': 3.797.0 - '@aws-sdk/core': 3.796.0 - '@aws-sdk/token-providers': 3.797.0 - '@aws-sdk/types': 3.775.0 - '@smithy/property-provider': 4.0.4 - '@smithy/shared-ini-file-loader': 4.0.4 - '@smithy/types': 4.3.1 + '@aws-sdk/client-sso': 3.908.0 + '@aws-sdk/core': 3.908.0 + '@aws-sdk/token-providers': 3.908.0 + '@aws-sdk/types': 3.901.0 + '@smithy/property-provider': 4.2.0 + '@smithy/shared-ini-file-loader': 4.3.0 + '@smithy/types': 4.6.0 tslib: 2.8.1 transitivePeerDependencies: - aws-crt - '@aws-sdk/credential-provider-web-identity@3.797.0': + '@aws-sdk/credential-provider-web-identity@3.908.0': dependencies: - '@aws-sdk/core': 3.796.0 - '@aws-sdk/nested-clients': 3.797.0 - '@aws-sdk/types': 3.775.0 - '@smithy/property-provider': 4.0.4 - '@smithy/types': 4.3.1 + '@aws-sdk/core': 3.908.0 + '@aws-sdk/nested-clients': 3.908.0 + '@aws-sdk/types': 3.901.0 + '@smithy/property-provider': 4.2.0 + '@smithy/shared-ini-file-loader': 4.3.0 + '@smithy/types': 4.6.0 tslib: 2.8.1 transitivePeerDependencies: - aws-crt - '@aws-sdk/lib-storage@3.797.0(@aws-sdk/client-s3@3.797.0)': + '@aws-sdk/lib-storage@3.908.0(@aws-sdk/client-s3@3.908.0)': dependencies: - '@aws-sdk/client-s3': 3.797.0 - '@smithy/abort-controller': 4.0.4 - '@smithy/middleware-endpoint': 4.1.11 - '@smithy/smithy-client': 4.4.3 + '@aws-sdk/client-s3': 3.908.0 + '@smithy/abort-controller': 4.2.0 + '@smithy/middleware-endpoint': 4.3.1 + '@smithy/smithy-client': 4.7.1 buffer: 5.6.0 events: 3.3.0 stream-browserify: 3.0.0 tslib: 2.8.1 - '@aws-sdk/middleware-bucket-endpoint@3.775.0': + '@aws-sdk/middleware-bucket-endpoint@3.901.0': dependencies: - '@aws-sdk/types': 3.775.0 - '@aws-sdk/util-arn-parser': 3.723.0 - '@smithy/node-config-provider': 4.1.3 - '@smithy/protocol-http': 5.1.2 - '@smithy/types': 4.3.1 - '@smithy/util-config-provider': 4.0.0 + '@aws-sdk/types': 3.901.0 + '@aws-sdk/util-arn-parser': 3.893.0 + '@smithy/node-config-provider': 4.3.0 + '@smithy/protocol-http': 5.3.0 + '@smithy/types': 4.6.0 + '@smithy/util-config-provider': 4.2.0 tslib: 2.8.1 - '@aws-sdk/middleware-expect-continue@3.775.0': + '@aws-sdk/middleware-expect-continue@3.901.0': dependencies: - '@aws-sdk/types': 3.775.0 - '@smithy/protocol-http': 5.1.2 - '@smithy/types': 4.3.1 + '@aws-sdk/types': 3.901.0 + '@smithy/protocol-http': 5.3.0 + '@smithy/types': 4.6.0 tslib: 2.8.1 - '@aws-sdk/middleware-flexible-checksums@3.796.0': + '@aws-sdk/middleware-flexible-checksums@3.908.0': dependencies: '@aws-crypto/crc32': 5.2.0 '@aws-crypto/crc32c': 5.2.0 '@aws-crypto/util': 5.2.0 - '@aws-sdk/core': 3.796.0 - '@aws-sdk/types': 3.775.0 - '@smithy/is-array-buffer': 4.0.0 - '@smithy/node-config-provider': 4.1.3 - '@smithy/protocol-http': 5.1.2 - '@smithy/types': 4.3.1 - '@smithy/util-middleware': 4.0.4 - '@smithy/util-stream': 4.2.2 - '@smithy/util-utf8': 4.0.0 + '@aws-sdk/core': 3.908.0 + '@aws-sdk/types': 3.901.0 + '@smithy/is-array-buffer': 4.2.0 + '@smithy/node-config-provider': 4.3.0 + '@smithy/protocol-http': 5.3.0 + '@smithy/types': 4.6.0 + '@smithy/util-middleware': 4.2.0 + '@smithy/util-stream': 4.5.0 + '@smithy/util-utf8': 4.2.0 tslib: 2.8.1 - '@aws-sdk/middleware-host-header@3.775.0': + '@aws-sdk/middleware-host-header@3.901.0': dependencies: - '@aws-sdk/types': 3.775.0 - '@smithy/protocol-http': 5.1.2 - '@smithy/types': 4.3.1 + '@aws-sdk/types': 3.901.0 + '@smithy/protocol-http': 5.3.0 + '@smithy/types': 4.6.0 tslib: 2.8.1 - '@aws-sdk/middleware-location-constraint@3.775.0': + '@aws-sdk/middleware-location-constraint@3.901.0': dependencies: - '@aws-sdk/types': 3.775.0 - '@smithy/types': 4.3.1 + '@aws-sdk/types': 3.901.0 + '@smithy/types': 4.6.0 tslib: 2.8.1 - '@aws-sdk/middleware-logger@3.775.0': + '@aws-sdk/middleware-logger@3.901.0': dependencies: - '@aws-sdk/types': 3.775.0 - '@smithy/types': 4.3.1 + '@aws-sdk/types': 3.901.0 + '@smithy/types': 4.6.0 tslib: 2.8.1 - '@aws-sdk/middleware-recursion-detection@3.775.0': + '@aws-sdk/middleware-recursion-detection@3.901.0': dependencies: - '@aws-sdk/types': 3.775.0 - '@smithy/protocol-http': 5.1.2 - '@smithy/types': 4.3.1 + '@aws-sdk/types': 3.901.0 + '@aws/lambda-invoke-store': 0.0.1 + '@smithy/protocol-http': 5.3.0 + '@smithy/types': 4.6.0 tslib: 2.8.1 - '@aws-sdk/middleware-sdk-s3@3.796.0': - dependencies: - '@aws-sdk/core': 3.796.0 - '@aws-sdk/types': 3.775.0 - '@aws-sdk/util-arn-parser': 3.723.0 - '@smithy/core': 3.5.3 - '@smithy/node-config-provider': 4.1.3 - '@smithy/protocol-http': 5.1.2 - '@smithy/signature-v4': 5.1.2 - '@smithy/smithy-client': 4.4.3 - '@smithy/types': 4.3.1 - '@smithy/util-config-provider': 4.0.0 - '@smithy/util-middleware': 4.0.4 - '@smithy/util-stream': 4.2.2 - '@smithy/util-utf8': 4.0.0 + '@aws-sdk/middleware-sdk-s3@3.908.0': + dependencies: + '@aws-sdk/core': 3.908.0 + '@aws-sdk/types': 3.901.0 + '@aws-sdk/util-arn-parser': 3.893.0 + '@smithy/core': 3.15.0 + '@smithy/node-config-provider': 4.3.0 + '@smithy/protocol-http': 5.3.0 + '@smithy/signature-v4': 5.3.0 + '@smithy/smithy-client': 4.7.1 + '@smithy/types': 4.6.0 + '@smithy/util-config-provider': 4.2.0 + '@smithy/util-middleware': 4.2.0 + '@smithy/util-stream': 4.5.0 + '@smithy/util-utf8': 4.2.0 tslib: 2.8.1 - '@aws-sdk/middleware-ssec@3.775.0': + '@aws-sdk/middleware-ssec@3.901.0': dependencies: - '@aws-sdk/types': 3.775.0 - '@smithy/types': 4.3.1 + '@aws-sdk/types': 3.901.0 + '@smithy/types': 4.6.0 tslib: 2.8.1 - '@aws-sdk/middleware-user-agent@3.796.0': + '@aws-sdk/middleware-user-agent@3.908.0': dependencies: - '@aws-sdk/core': 3.796.0 - '@aws-sdk/types': 3.775.0 - '@aws-sdk/util-endpoints': 3.787.0 - '@smithy/core': 3.5.3 - '@smithy/protocol-http': 5.1.2 - '@smithy/types': 4.3.1 + '@aws-sdk/core': 3.908.0 + '@aws-sdk/types': 3.901.0 + '@aws-sdk/util-endpoints': 3.901.0 + '@smithy/core': 3.15.0 + '@smithy/protocol-http': 5.3.0 + '@smithy/types': 4.6.0 tslib: 2.8.1 - '@aws-sdk/nested-clients@3.797.0': + '@aws-sdk/nested-clients@3.908.0': dependencies: '@aws-crypto/sha256-browser': 5.2.0 '@aws-crypto/sha256-js': 5.2.0 - '@aws-sdk/core': 3.796.0 - '@aws-sdk/middleware-host-header': 3.775.0 - '@aws-sdk/middleware-logger': 3.775.0 - '@aws-sdk/middleware-recursion-detection': 3.775.0 - '@aws-sdk/middleware-user-agent': 3.796.0 - '@aws-sdk/region-config-resolver': 3.775.0 - '@aws-sdk/types': 3.775.0 - '@aws-sdk/util-endpoints': 3.787.0 - '@aws-sdk/util-user-agent-browser': 3.775.0 - '@aws-sdk/util-user-agent-node': 3.796.0 - '@smithy/config-resolver': 4.1.4 - '@smithy/core': 3.5.3 - '@smithy/fetch-http-handler': 5.0.4 - '@smithy/hash-node': 4.0.4 - '@smithy/invalid-dependency': 4.0.4 - '@smithy/middleware-content-length': 4.0.4 - '@smithy/middleware-endpoint': 4.1.11 - '@smithy/middleware-retry': 4.1.12 - '@smithy/middleware-serde': 4.0.8 - '@smithy/middleware-stack': 4.0.4 - '@smithy/node-config-provider': 4.1.3 - '@smithy/node-http-handler': 4.0.6 - '@smithy/protocol-http': 5.1.2 - '@smithy/smithy-client': 4.4.3 - '@smithy/types': 4.3.1 - '@smithy/url-parser': 4.0.4 - '@smithy/util-base64': 4.0.0 - '@smithy/util-body-length-browser': 4.0.0 - '@smithy/util-body-length-node': 4.0.0 - '@smithy/util-defaults-mode-browser': 4.0.19 - '@smithy/util-defaults-mode-node': 4.0.19 - '@smithy/util-endpoints': 3.0.6 - '@smithy/util-middleware': 4.0.4 - '@smithy/util-retry': 4.0.5 - '@smithy/util-utf8': 4.0.0 + '@aws-sdk/core': 3.908.0 + '@aws-sdk/middleware-host-header': 3.901.0 + '@aws-sdk/middleware-logger': 3.901.0 + '@aws-sdk/middleware-recursion-detection': 3.901.0 + '@aws-sdk/middleware-user-agent': 3.908.0 + '@aws-sdk/region-config-resolver': 3.901.0 + '@aws-sdk/types': 3.901.0 + '@aws-sdk/util-endpoints': 3.901.0 + '@aws-sdk/util-user-agent-browser': 3.907.0 + '@aws-sdk/util-user-agent-node': 3.908.0 + '@smithy/config-resolver': 4.3.0 + '@smithy/core': 3.15.0 + '@smithy/fetch-http-handler': 5.3.1 + '@smithy/hash-node': 4.2.0 + '@smithy/invalid-dependency': 4.2.0 + '@smithy/middleware-content-length': 4.2.0 + '@smithy/middleware-endpoint': 4.3.1 + '@smithy/middleware-retry': 4.4.1 + '@smithy/middleware-serde': 4.2.0 + '@smithy/middleware-stack': 4.2.0 + '@smithy/node-config-provider': 4.3.0 + '@smithy/node-http-handler': 4.3.0 + '@smithy/protocol-http': 5.3.0 + '@smithy/smithy-client': 4.7.1 + '@smithy/types': 4.6.0 + '@smithy/url-parser': 4.2.0 + '@smithy/util-base64': 4.3.0 + '@smithy/util-body-length-browser': 4.2.0 + '@smithy/util-body-length-node': 4.2.1 + '@smithy/util-defaults-mode-browser': 4.3.0 + '@smithy/util-defaults-mode-node': 4.2.1 + '@smithy/util-endpoints': 3.2.0 + '@smithy/util-middleware': 4.2.0 + '@smithy/util-retry': 4.2.0 + '@smithy/util-utf8': 4.2.0 tslib: 2.8.1 transitivePeerDependencies: - aws-crt - '@aws-sdk/region-config-resolver@3.775.0': + '@aws-sdk/region-config-resolver@3.901.0': dependencies: - '@aws-sdk/types': 3.775.0 - '@smithy/node-config-provider': 4.1.3 - '@smithy/types': 4.3.1 - '@smithy/util-config-provider': 4.0.0 - '@smithy/util-middleware': 4.0.4 + '@aws-sdk/types': 3.901.0 + '@smithy/node-config-provider': 4.3.0 + '@smithy/types': 4.6.0 + '@smithy/util-config-provider': 4.2.0 + '@smithy/util-middleware': 4.2.0 tslib: 2.8.1 - '@aws-sdk/signature-v4-multi-region@3.796.0': + '@aws-sdk/signature-v4-multi-region@3.908.0': dependencies: - '@aws-sdk/middleware-sdk-s3': 3.796.0 - '@aws-sdk/types': 3.775.0 - '@smithy/protocol-http': 5.1.2 - '@smithy/signature-v4': 5.1.2 - '@smithy/types': 4.3.1 + '@aws-sdk/middleware-sdk-s3': 3.908.0 + '@aws-sdk/types': 3.901.0 + '@smithy/protocol-http': 5.3.0 + '@smithy/signature-v4': 5.3.0 + '@smithy/types': 4.6.0 tslib: 2.8.1 - '@aws-sdk/token-providers@3.797.0': + '@aws-sdk/token-providers@3.908.0': dependencies: - '@aws-sdk/nested-clients': 3.797.0 - '@aws-sdk/types': 3.775.0 - '@smithy/property-provider': 4.0.4 - '@smithy/shared-ini-file-loader': 4.0.4 - '@smithy/types': 4.3.1 + '@aws-sdk/core': 3.908.0 + '@aws-sdk/nested-clients': 3.908.0 + '@aws-sdk/types': 3.901.0 + '@smithy/property-provider': 4.2.0 + '@smithy/shared-ini-file-loader': 4.3.0 + '@smithy/types': 4.6.0 tslib: 2.8.1 transitivePeerDependencies: - aws-crt - '@aws-sdk/types@3.775.0': + '@aws-sdk/types@3.901.0': dependencies: - '@smithy/types': 4.3.1 + '@smithy/types': 4.6.0 tslib: 2.8.1 - '@aws-sdk/util-arn-parser@3.723.0': + '@aws-sdk/util-arn-parser@3.893.0': dependencies: tslib: 2.8.1 - '@aws-sdk/util-endpoints@3.787.0': + '@aws-sdk/util-endpoints@3.901.0': dependencies: - '@aws-sdk/types': 3.775.0 - '@smithy/types': 4.3.1 - '@smithy/util-endpoints': 3.0.6 + '@aws-sdk/types': 3.901.0 + '@smithy/types': 4.6.0 + '@smithy/url-parser': 4.2.0 + '@smithy/util-endpoints': 3.2.0 tslib: 2.8.1 - '@aws-sdk/util-locate-window@3.804.0': + '@aws-sdk/util-locate-window@3.208.0': dependencies: tslib: 2.8.1 - '@aws-sdk/util-user-agent-browser@3.775.0': + '@aws-sdk/util-user-agent-browser@3.907.0': dependencies: - '@aws-sdk/types': 3.775.0 - '@smithy/types': 4.3.1 + '@aws-sdk/types': 3.901.0 + '@smithy/types': 4.6.0 bowser: 2.11.0 tslib: 2.8.1 - '@aws-sdk/util-user-agent-node@3.796.0': + '@aws-sdk/util-user-agent-node@3.908.0': dependencies: - '@aws-sdk/middleware-user-agent': 3.796.0 - '@aws-sdk/types': 3.775.0 - '@smithy/node-config-provider': 4.1.3 - '@smithy/types': 4.3.1 + '@aws-sdk/middleware-user-agent': 3.908.0 + '@aws-sdk/types': 3.901.0 + '@smithy/node-config-provider': 4.3.0 + '@smithy/types': 4.6.0 tslib: 2.8.1 - '@aws-sdk/xml-builder@3.775.0': + '@aws-sdk/xml-builder@3.901.0': dependencies: - '@smithy/types': 4.3.1 + '@smithy/types': 4.6.0 + fast-xml-parser: 5.2.5 tslib: 2.8.1 + '@aws/lambda-invoke-store@0.0.1': {} + + '@babel/code-frame@7.24.7': + dependencies: + '@babel/highlight': 7.24.7 + picocolors: 1.1.1 + '@babel/code-frame@7.27.1': dependencies: '@babel/helper-validator-identifier': 7.27.1 js-tokens: 4.0.0 picocolors: 1.1.1 - '@babel/compat-data@7.27.5': {} + '@babel/compat-data@7.25.0': {} + + '@babel/compat-data@7.28.4': {} - '@babel/core@7.27.4': + '@babel/core@7.24.9': dependencies: '@ampproject/remapping': 2.3.0 + '@babel/code-frame': 7.24.7 + '@babel/generator': 7.25.0 + '@babel/helper-compilation-targets': 7.24.8 + '@babel/helper-module-transforms': 7.25.0(@babel/core@7.24.9) + '@babel/helpers': 7.25.0 + '@babel/parser': 7.25.6 + '@babel/template': 7.25.0 + '@babel/traverse': 7.25.0 + '@babel/types': 7.25.6 + convert-source-map: 2.0.0 + debug: 4.4.3(supports-color@8.1.1) + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/core@7.28.4': + dependencies: '@babel/code-frame': 7.27.1 - '@babel/generator': 7.27.5 + '@babel/generator': 7.28.3 '@babel/helper-compilation-targets': 7.27.2 - '@babel/helper-module-transforms': 7.27.3(@babel/core@7.27.4) - '@babel/helpers': 7.27.6 - '@babel/parser': 7.27.5 + '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.4) + '@babel/helpers': 7.28.4 + '@babel/parser': 7.28.4 '@babel/template': 7.27.2 - '@babel/traverse': 7.27.4 - '@babel/types': 7.27.6 + '@babel/traverse': 7.28.4 + '@babel/types': 7.28.4 + '@jridgewell/remapping': 2.3.5 convert-source-map: 2.0.0 - debug: 4.4.1(supports-color@5.5.0) + debug: 4.4.3(supports-color@8.1.1) gensync: 1.0.0-beta.2 json5: 2.2.3 semver: 6.3.1 transitivePeerDependencies: - supports-color - '@babel/generator@7.27.5': + '@babel/generator@7.25.0': dependencies: - '@babel/parser': 7.27.5 - '@babel/types': 7.27.6 - '@jridgewell/gen-mapping': 0.3.8 + '@babel/types': 7.28.4 + '@jridgewell/gen-mapping': 0.3.5 '@jridgewell/trace-mapping': 0.3.25 + jsesc: 2.5.2 + + '@babel/generator@7.28.3': + dependencies: + '@babel/parser': 7.28.4 + '@babel/types': 7.28.4 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 jsesc: 3.1.0 + '@babel/helper-compilation-targets@7.24.8': + dependencies: + '@babel/compat-data': 7.25.0 + '@babel/helper-validator-option': 7.24.8 + browserslist: 4.24.4 + lru-cache: 5.1.1 + semver: 6.3.1 + '@babel/helper-compilation-targets@7.27.2': dependencies: - '@babel/compat-data': 7.27.5 + '@babel/compat-data': 7.28.4 '@babel/helper-validator-option': 7.27.1 - browserslist: 4.25.0 + browserslist: 4.26.3 lru-cache: 5.1.1 semver: 6.3.1 + '@babel/helper-globals@7.28.0': {} + + '@babel/helper-module-imports@7.24.7': + dependencies: + '@babel/traverse': 7.28.4 + '@babel/types': 7.28.4 + transitivePeerDependencies: + - supports-color + '@babel/helper-module-imports@7.27.1': dependencies: - '@babel/traverse': 7.27.4 - '@babel/types': 7.27.6 + '@babel/traverse': 7.28.4 + '@babel/types': 7.28.4 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-transforms@7.25.0(@babel/core@7.24.9)': + dependencies: + '@babel/core': 7.24.9 + '@babel/helper-module-imports': 7.24.7 + '@babel/helper-simple-access': 7.24.7 + '@babel/helper-validator-identifier': 7.27.1 + '@babel/traverse': 7.28.4 transitivePeerDependencies: - supports-color - '@babel/helper-module-transforms@7.27.3(@babel/core@7.27.4)': + '@babel/helper-module-transforms@7.28.3(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.27.4 + '@babel/core': 7.28.4 '@babel/helper-module-imports': 7.27.1 '@babel/helper-validator-identifier': 7.27.1 - '@babel/traverse': 7.27.4 + '@babel/traverse': 7.28.4 transitivePeerDependencies: - supports-color - '@babel/helper-plugin-utils@7.27.1': {} + '@babel/helper-plugin-utils@7.22.5': {} + + '@babel/helper-simple-access@7.24.7': + dependencies: + '@babel/traverse': 7.28.4 + '@babel/types': 7.28.4 + transitivePeerDependencies: + - supports-color '@babel/helper-string-parser@7.27.1': {} + '@babel/helper-validator-identifier@7.24.7': {} + '@babel/helper-validator-identifier@7.27.1': {} + '@babel/helper-validator-option@7.24.8': {} + '@babel/helper-validator-option@7.27.1': {} - '@babel/helpers@7.27.6': + '@babel/helpers@7.25.0': + dependencies: + '@babel/template': 7.27.2 + '@babel/types': 7.28.4 + + '@babel/helpers@7.28.4': dependencies: '@babel/template': 7.27.2 - '@babel/types': 7.27.6 + '@babel/types': 7.28.4 + + '@babel/highlight@7.24.7': + dependencies: + '@babel/helper-validator-identifier': 7.24.7 + chalk: 2.4.2 + js-tokens: 4.0.0 + picocolors: 1.1.1 + + '@babel/parser@7.25.6': + dependencies: + '@babel/types': 7.28.4 + + '@babel/parser@7.28.4': + dependencies: + '@babel/types': 7.28.4 + + '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.24.9)': + dependencies: + '@babel/core': 7.24.9 + '@babel/helper-plugin-utils': 7.22.5 + + '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.28.4)': + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-plugin-utils': 7.22.5 + + '@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.24.9)': + dependencies: + '@babel/core': 7.24.9 + '@babel/helper-plugin-utils': 7.22.5 + + '@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.28.4)': + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-plugin-utils': 7.22.5 + + '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.24.9)': + dependencies: + '@babel/core': 7.24.9 + '@babel/helper-plugin-utils': 7.22.5 + + '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.28.4)': + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-plugin-utils': 7.22.5 + + '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.24.9)': + dependencies: + '@babel/core': 7.24.9 + '@babel/helper-plugin-utils': 7.22.5 + + '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.28.4)': + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-plugin-utils': 7.22.5 + + '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.24.9)': + dependencies: + '@babel/core': 7.24.9 + '@babel/helper-plugin-utils': 7.22.5 + + '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.28.4)': + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-plugin-utils': 7.22.5 - '@babel/parser@7.27.5': + '@babel/plugin-syntax-jsx@7.23.3(@babel/core@7.28.4)': dependencies: - '@babel/types': 7.27.6 + '@babel/core': 7.28.4 + '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.27.4)': + '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.24.9)': dependencies: - '@babel/core': 7.27.4 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.24.9 + '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.27.4)': + '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.27.4 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.28.4 + '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.27.4)': + '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.24.9)': dependencies: - '@babel/core': 7.27.4 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.24.9 + '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.27.4)': + '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.27.4 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.28.4 + '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-import-attributes@7.27.1(@babel/core@7.27.4)': + '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.24.9)': dependencies: - '@babel/core': 7.27.4 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.24.9 + '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.27.4)': + '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.27.4 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.28.4 + '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.27.4)': + '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.24.9)': dependencies: - '@babel/core': 7.27.4 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.24.9 + '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.27.4)': + '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.27.4 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.28.4 + '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.27.4)': + '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.24.9)': dependencies: - '@babel/core': 7.27.4 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.24.9 + '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.27.4)': + '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.27.4 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.28.4 + '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.27.4)': + '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.24.9)': dependencies: - '@babel/core': 7.27.4 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.24.9 + '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.27.4)': + '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.27.4 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.28.4 + '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.27.4)': + '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.24.9)': dependencies: - '@babel/core': 7.27.4 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.24.9 + '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.27.4)': + '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.27.4 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.28.4 + '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.27.4)': + '@babel/plugin-syntax-typescript@7.23.3(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.27.4 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/core': 7.28.4 + '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.27.4)': + '@babel/runtime@7.21.0': dependencies: - '@babel/core': 7.27.4 - '@babel/helper-plugin-utils': 7.27.1 + regenerator-runtime: 0.13.11 - '@babel/plugin-syntax-typescript@7.27.1(@babel/core@7.27.4)': + '@babel/runtime@7.23.4': dependencies: - '@babel/core': 7.27.4 - '@babel/helper-plugin-utils': 7.27.1 + regenerator-runtime: 0.14.0 '@babel/runtime@7.27.0': dependencies: - regenerator-runtime: 0.14.1 + regenerator-runtime: 0.14.0 - '@babel/runtime@7.27.6': {} + '@babel/template@7.25.0': + dependencies: + '@babel/code-frame': 7.27.1 + '@babel/parser': 7.28.4 + '@babel/types': 7.28.4 '@babel/template@7.27.2': dependencies: '@babel/code-frame': 7.27.1 - '@babel/parser': 7.27.5 - '@babel/types': 7.27.6 + '@babel/parser': 7.28.4 + '@babel/types': 7.28.4 - '@babel/traverse@7.27.4': + '@babel/traverse@7.25.0': dependencies: '@babel/code-frame': 7.27.1 - '@babel/generator': 7.27.5 - '@babel/parser': 7.27.5 + '@babel/generator': 7.28.3 + '@babel/parser': 7.28.4 '@babel/template': 7.27.2 - '@babel/types': 7.27.6 - debug: 4.4.1(supports-color@5.5.0) + '@babel/types': 7.28.4 + debug: 4.4.3(supports-color@8.1.1) globals: 11.12.0 transitivePeerDependencies: - supports-color - '@babel/types@7.27.6': + '@babel/traverse@7.28.4': + dependencies: + '@babel/code-frame': 7.27.1 + '@babel/generator': 7.28.3 + '@babel/helper-globals': 7.28.0 + '@babel/parser': 7.28.4 + '@babel/template': 7.27.2 + '@babel/types': 7.28.4 + debug: 4.4.3(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + + '@babel/types@7.25.6': + dependencies: + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.27.1 + to-fast-properties: 2.0.0 + + '@babel/types@7.28.4': dependencies: '@babel/helper-string-parser': 7.27.1 '@babel/helper-validator-identifier': 7.27.1 @@ -12207,156 +13022,140 @@ snapshots: '@bcoe/v8-coverage@1.0.2': {} - '@biomejs/biome@1.9.4': + '@biomejs/biome@2.3.1': optionalDependencies: - '@biomejs/cli-darwin-arm64': 1.9.4 - '@biomejs/cli-darwin-x64': 1.9.4 - '@biomejs/cli-linux-arm64': 1.9.4 - '@biomejs/cli-linux-arm64-musl': 1.9.4 - '@biomejs/cli-linux-x64': 1.9.4 - '@biomejs/cli-linux-x64-musl': 1.9.4 - '@biomejs/cli-win32-arm64': 1.9.4 - '@biomejs/cli-win32-x64': 1.9.4 - - '@biomejs/cli-darwin-arm64@1.9.4': + '@biomejs/cli-darwin-arm64': 2.3.1 + '@biomejs/cli-darwin-x64': 2.3.1 + '@biomejs/cli-linux-arm64': 2.3.1 + '@biomejs/cli-linux-arm64-musl': 2.3.1 + '@biomejs/cli-linux-x64': 2.3.1 + '@biomejs/cli-linux-x64-musl': 2.3.1 + '@biomejs/cli-win32-arm64': 2.3.1 + '@biomejs/cli-win32-x64': 2.3.1 + + '@biomejs/cli-darwin-arm64@2.3.1': optional: true - '@biomejs/cli-darwin-x64@1.9.4': + '@biomejs/cli-darwin-x64@2.3.1': optional: true - '@biomejs/cli-linux-arm64-musl@1.9.4': + '@biomejs/cli-linux-arm64-musl@2.3.1': optional: true - '@biomejs/cli-linux-arm64@1.9.4': + '@biomejs/cli-linux-arm64@2.3.1': optional: true - '@biomejs/cli-linux-x64-musl@1.9.4': + '@biomejs/cli-linux-x64-musl@2.3.1': optional: true - '@biomejs/cli-linux-x64@1.9.4': + '@biomejs/cli-linux-x64@2.3.1': optional: true - '@biomejs/cli-win32-arm64@1.9.4': + '@biomejs/cli-win32-arm64@2.3.1': optional: true - '@biomejs/cli-win32-x64@1.9.4': + '@biomejs/cli-win32-x64@2.3.1': optional: true - '@bundled-es-modules/cookie@2.0.1': - dependencies: - cookie: 0.7.2 - - '@bundled-es-modules/statuses@1.0.1': - dependencies: - statuses: 2.0.2 - - '@bundled-es-modules/tough-cookie@0.1.6': - dependencies: - '@types/tough-cookie': 4.0.5 - tough-cookie: 4.1.4 - '@canvas/image-data@1.0.0': {} '@chainsafe/is-ip@2.1.0': {} - '@colors/colors@1.5.0': - optional: true - - '@cropper/element-canvas@2.0.0': + '@cropper/element-canvas@2.0.1': dependencies: - '@cropper/element': 2.0.0 - '@cropper/utils': 2.0.0 + '@cropper/element': 2.0.1 + '@cropper/utils': 2.0.1 - '@cropper/element-crosshair@2.0.0': + '@cropper/element-crosshair@2.0.1': dependencies: - '@cropper/element': 2.0.0 - '@cropper/utils': 2.0.0 + '@cropper/element': 2.0.1 + '@cropper/utils': 2.0.1 - '@cropper/element-grid@2.0.0': + '@cropper/element-grid@2.0.1': dependencies: - '@cropper/element': 2.0.0 - '@cropper/utils': 2.0.0 + '@cropper/element': 2.0.1 + '@cropper/utils': 2.0.1 - '@cropper/element-handle@2.0.0': + '@cropper/element-handle@2.0.1': dependencies: - '@cropper/element': 2.0.0 - '@cropper/utils': 2.0.0 + '@cropper/element': 2.0.1 + '@cropper/utils': 2.0.1 - '@cropper/element-image@2.0.0': + '@cropper/element-image@2.0.1': dependencies: - '@cropper/element': 2.0.0 - '@cropper/element-canvas': 2.0.0 - '@cropper/utils': 2.0.0 + '@cropper/element': 2.0.1 + '@cropper/element-canvas': 2.0.1 + '@cropper/utils': 2.0.1 - '@cropper/element-selection@2.0.0': + '@cropper/element-selection@2.0.1': dependencies: - '@cropper/element': 2.0.0 - '@cropper/element-canvas': 2.0.0 - '@cropper/element-image': 2.0.0 - '@cropper/utils': 2.0.0 + '@cropper/element': 2.0.1 + '@cropper/element-canvas': 2.0.1 + '@cropper/element-image': 2.0.1 + '@cropper/utils': 2.0.1 - '@cropper/element-shade@2.0.0': + '@cropper/element-shade@2.0.1': dependencies: - '@cropper/element': 2.0.0 - '@cropper/element-canvas': 2.0.0 - '@cropper/element-selection': 2.0.0 - '@cropper/utils': 2.0.0 + '@cropper/element': 2.0.1 + '@cropper/element-canvas': 2.0.1 + '@cropper/element-selection': 2.0.1 + '@cropper/utils': 2.0.1 - '@cropper/element-viewer@2.0.0': + '@cropper/element-viewer@2.0.1': dependencies: - '@cropper/element': 2.0.0 - '@cropper/element-canvas': 2.0.0 - '@cropper/element-image': 2.0.0 - '@cropper/element-selection': 2.0.0 - '@cropper/utils': 2.0.0 + '@cropper/element': 2.0.1 + '@cropper/element-canvas': 2.0.1 + '@cropper/element-image': 2.0.1 + '@cropper/element-selection': 2.0.1 + '@cropper/utils': 2.0.1 - '@cropper/element@2.0.0': + '@cropper/element@2.0.1': dependencies: - '@cropper/utils': 2.0.0 + '@cropper/utils': 2.0.1 - '@cropper/elements@2.0.0': + '@cropper/elements@2.0.1': dependencies: - '@cropper/element': 2.0.0 - '@cropper/element-canvas': 2.0.0 - '@cropper/element-crosshair': 2.0.0 - '@cropper/element-grid': 2.0.0 - '@cropper/element-handle': 2.0.0 - '@cropper/element-image': 2.0.0 - '@cropper/element-selection': 2.0.0 - '@cropper/element-shade': 2.0.0 - '@cropper/element-viewer': 2.0.0 + '@cropper/element': 2.0.1 + '@cropper/element-canvas': 2.0.1 + '@cropper/element-crosshair': 2.0.1 + '@cropper/element-grid': 2.0.1 + '@cropper/element-handle': 2.0.1 + '@cropper/element-image': 2.0.1 + '@cropper/element-selection': 2.0.1 + '@cropper/element-shade': 2.0.1 + '@cropper/element-viewer': 2.0.1 - '@cropper/utils@2.0.0': {} + '@cropper/utils@2.0.1': {} - '@csstools/color-helpers@5.0.2': {} + '@csstools/color-helpers@5.0.1': {} - '@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-calc@2.1.1(@csstools/css-parser-algorithms@3.0.4(@csstools/css-tokenizer@3.0.3))(@csstools/css-tokenizer@3.0.3)': dependencies: - '@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.4(@csstools/css-tokenizer@3.0.3) + '@csstools/css-tokenizer': 3.0.3 - '@csstools/css-color-parser@3.0.10(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)': + '@csstools/css-color-parser@3.0.7(@csstools/css-parser-algorithms@3.0.4(@csstools/css-tokenizer@3.0.3))(@csstools/css-tokenizer@3.0.3)': dependencies: - '@csstools/color-helpers': 5.0.2 - '@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/color-helpers': 5.0.1 + '@csstools/css-calc': 2.1.1(@csstools/css-parser-algorithms@3.0.4(@csstools/css-tokenizer@3.0.3))(@csstools/css-tokenizer@3.0.3) + '@csstools/css-parser-algorithms': 3.0.4(@csstools/css-tokenizer@3.0.3) + '@csstools/css-tokenizer': 3.0.3 - '@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4)': + '@csstools/css-parser-algorithms@3.0.4(@csstools/css-tokenizer@3.0.3)': dependencies: - '@csstools/css-tokenizer': 3.0.4 + '@csstools/css-tokenizer': 3.0.3 - '@csstools/css-tokenizer@3.0.4': {} + '@csstools/css-tokenizer@3.0.3': {} - '@cypress/request@3.0.8': + '@cypress/request@3.0.9': dependencies: aws-sign2: 0.7.0 - aws4: 1.13.2 + aws4: 1.12.0 caseless: 0.12.0 combined-stream: 1.0.8 extend: 3.0.2 forever-agent: 0.6.1 - form-data: 4.0.2 + form-data: 4.0.4 http-signature: 1.4.0 is-typedarray: 1.0.0 isstream: 0.1.2 @@ -12371,248 +13170,189 @@ snapshots: '@cypress/xvfb@1.2.4(supports-color@8.1.1)': dependencies: - debug: 3.2.7(supports-color@8.1.1) - lodash.once: 4.1.1 - transitivePeerDependencies: - - supports-color - - '@dice-roller/rpg-dice-roller@5.5.1': - dependencies: - mathjs: 14.5.2 - random-js: 2.1.0 - - '@digitalbazaar/http-client@3.4.1(web-streams-polyfill@3.3.3)': - dependencies: - ky: 0.33.3 - ky-universal: 0.11.0(ky@0.33.3)(web-streams-polyfill@3.3.3) - undici: 5.29.0 - transitivePeerDependencies: - - web-streams-polyfill - - '@discordapp/twemoji@15.1.0': - dependencies: - '@twemoji/parser': 15.1.0 - fs-extra: 8.1.0 - jsonfile: 5.0.0 - universalify: 0.1.2 - - '@emnapi/runtime@1.4.3': - dependencies: - tslib: 2.8.1 - optional: true - - '@esbuild/aix-ppc64@0.21.5': - optional: true - - '@esbuild/aix-ppc64@0.25.3': - optional: true - - '@esbuild/android-arm64@0.21.5': - optional: true - - '@esbuild/android-arm64@0.25.3': - optional: true - - '@esbuild/android-arm@0.21.5': - optional: true - - '@esbuild/android-arm@0.25.3': - optional: true - - '@esbuild/android-x64@0.21.5': - optional: true - - '@esbuild/android-x64@0.25.3': - optional: true - - '@esbuild/darwin-arm64@0.21.5': - optional: true - - '@esbuild/darwin-arm64@0.25.3': - optional: true - - '@esbuild/darwin-x64@0.21.5': - optional: true - - '@esbuild/darwin-x64@0.25.3': - optional: true - - '@esbuild/freebsd-arm64@0.21.5': - optional: true - - '@esbuild/freebsd-arm64@0.25.3': - optional: true - - '@esbuild/freebsd-x64@0.21.5': - optional: true - - '@esbuild/freebsd-x64@0.25.3': - optional: true + debug: 3.2.7(supports-color@8.1.1) + lodash.once: 4.1.1 + transitivePeerDependencies: + - supports-color - '@esbuild/linux-arm64@0.21.5': - optional: true + '@dice-roller/rpg-dice-roller@5.5.0': + dependencies: + mathjs: 11.12.0 + random-js: 2.1.0 - '@esbuild/linux-arm64@0.25.3': - optional: true + '@digitalbazaar/http-client@3.4.1(web-streams-polyfill@3.2.1)': + dependencies: + ky: 0.33.3 + ky-universal: 0.11.0(ky@0.33.3)(web-streams-polyfill@3.2.1) + undici: 5.28.5 + transitivePeerDependencies: + - web-streams-polyfill - '@esbuild/linux-arm@0.21.5': - optional: true + '@discordapp/twemoji@16.0.1': + dependencies: + '@twemoji/parser': 16.0.0 + fs-extra: 8.1.0 + jsonfile: 5.0.0 + universalify: 0.1.2 - '@esbuild/linux-arm@0.25.3': + '@emnapi/runtime@1.2.0': + dependencies: + tslib: 2.8.1 optional: true - '@esbuild/linux-ia32@0.21.5': - optional: true + '@epic-web/invariant@1.0.0': {} - '@esbuild/linux-ia32@0.25.3': + '@esbuild/aix-ppc64@0.25.10': optional: true - '@esbuild/linux-loong64@0.21.5': + '@esbuild/android-arm64@0.25.10': optional: true - '@esbuild/linux-loong64@0.25.3': + '@esbuild/android-arm@0.25.10': optional: true - '@esbuild/linux-mips64el@0.21.5': + '@esbuild/android-x64@0.25.10': optional: true - '@esbuild/linux-mips64el@0.25.3': + '@esbuild/darwin-arm64@0.25.10': optional: true - '@esbuild/linux-ppc64@0.21.5': + '@esbuild/darwin-x64@0.25.10': optional: true - '@esbuild/linux-ppc64@0.25.3': + '@esbuild/freebsd-arm64@0.25.10': optional: true - '@esbuild/linux-riscv64@0.21.5': + '@esbuild/freebsd-x64@0.25.10': optional: true - '@esbuild/linux-riscv64@0.25.3': + '@esbuild/linux-arm64@0.25.10': optional: true - '@esbuild/linux-s390x@0.21.5': + '@esbuild/linux-arm@0.25.10': optional: true - '@esbuild/linux-s390x@0.25.3': + '@esbuild/linux-ia32@0.25.10': optional: true - '@esbuild/linux-x64@0.21.5': + '@esbuild/linux-loong64@0.25.10': optional: true - '@esbuild/linux-x64@0.25.3': + '@esbuild/linux-mips64el@0.25.10': optional: true - '@esbuild/netbsd-arm64@0.25.3': + '@esbuild/linux-ppc64@0.25.10': optional: true - '@esbuild/netbsd-x64@0.21.5': + '@esbuild/linux-riscv64@0.25.10': optional: true - '@esbuild/netbsd-x64@0.25.3': + '@esbuild/linux-s390x@0.25.10': optional: true - '@esbuild/openbsd-arm64@0.25.3': + '@esbuild/linux-x64@0.25.10': optional: true - '@esbuild/openbsd-x64@0.21.5': + '@esbuild/netbsd-arm64@0.25.10': optional: true - '@esbuild/openbsd-x64@0.25.3': + '@esbuild/netbsd-x64@0.25.10': optional: true - '@esbuild/sunos-x64@0.21.5': + '@esbuild/openbsd-arm64@0.25.10': optional: true - '@esbuild/sunos-x64@0.25.3': + '@esbuild/openbsd-x64@0.25.10': optional: true - '@esbuild/win32-arm64@0.21.5': + '@esbuild/openharmony-arm64@0.25.10': optional: true - '@esbuild/win32-arm64@0.25.3': + '@esbuild/sunos-x64@0.25.10': optional: true - '@esbuild/win32-ia32@0.21.5': + '@esbuild/win32-arm64@0.25.10': optional: true - '@esbuild/win32-ia32@0.25.3': + '@esbuild/win32-ia32@0.25.10': optional: true - '@esbuild/win32-x64@0.21.5': + '@esbuild/win32-x64@0.25.10': optional: true - '@esbuild/win32-x64@0.25.3': - optional: true + '@eslint-community/eslint-utils@4.4.0(eslint@9.37.0)': + dependencies: + eslint: 9.37.0 + eslint-visitor-keys: 3.4.3 - '@eslint-community/eslint-utils@4.7.0(eslint@9.25.1)': + '@eslint-community/eslint-utils@4.9.0(eslint@9.37.0)': dependencies: - eslint: 9.25.1 + eslint: 9.37.0 eslint-visitor-keys: 3.4.3 '@eslint-community/regexpp@4.12.1': {} - '@eslint/compat@1.3.0(eslint@9.25.1)': - optionalDependencies: - eslint: 9.25.1 + '@eslint/compat@1.1.1': {} - '@eslint/config-array@0.20.1': + '@eslint/config-array@0.21.0': dependencies: '@eslint/object-schema': 2.1.6 - debug: 4.4.1(supports-color@5.5.0) + debug: 4.4.3(supports-color@8.1.1) minimatch: 3.1.2 transitivePeerDependencies: - supports-color - '@eslint/config-helpers@0.2.3': {} + '@eslint/config-helpers@0.4.1': + dependencies: + '@eslint/core': 0.16.0 - '@eslint/core@0.13.0': + '@eslint/core@0.16.0': dependencies: '@types/json-schema': 7.0.15 '@eslint/eslintrc@3.3.1': dependencies: ajv: 6.12.6 - debug: 4.4.1(supports-color@5.5.0) + debug: 4.4.3(supports-color@8.1.1) espree: 10.4.0 globals: 14.0.0 - ignore: 5.3.2 - import-fresh: 3.3.1 + ignore: 5.3.1 + import-fresh: 3.3.0 js-yaml: 4.1.0 minimatch: 3.1.2 strip-json-comments: 3.1.1 transitivePeerDependencies: - supports-color - '@eslint/js@9.25.1': {} + '@eslint/js@9.37.0': {} '@eslint/object-schema@2.1.6': {} - '@eslint/plugin-kit@0.2.8': + '@eslint/plugin-kit@0.4.0': dependencies: - '@eslint/core': 0.13.0 + '@eslint/core': 0.16.0 levn: 0.4.1 - '@fastify/accept-negotiator@2.0.1': {} + '@fastify/accept-negotiator@2.0.0': {} - '@fastify/accepts@5.0.2': + '@fastify/accepts@5.0.3': dependencies: accepts: 1.3.8 fastify-plugin: 5.0.1 - '@fastify/ajv-compiler@4.0.2': + '@fastify/ajv-compiler@4.0.1': dependencies: ajv: 8.17.1 ajv-formats: 3.0.1(ajv@8.17.1) - fast-uri: 3.0.6 + fast-uri: 3.0.1 - '@fastify/busboy@2.1.1': {} + '@fastify/busboy@2.1.0': {} - '@fastify/busboy@3.1.1': {} + '@fastify/busboy@3.0.0': {} '@fastify/cookie@11.0.2': dependencies: - cookie: 1.0.2 + cookie: 1.0.1 fastify-plugin: 5.0.1 '@fastify/cors@10.1.0': @@ -12620,61 +13360,61 @@ snapshots: fastify-plugin: 5.0.1 mnemonist: 0.40.0 - '@fastify/deepmerge@2.0.2': {} + '@fastify/deepmerge@3.1.0': {} - '@fastify/error@4.2.0': {} + '@fastify/error@4.0.0': {} '@fastify/express@4.0.2': dependencies: - express: 4.21.2 + express: 4.21.1 fastify-plugin: 5.0.1 transitivePeerDependencies: - supports-color - '@fastify/fast-json-stringify-compiler@5.0.3': + '@fastify/fast-json-stringify-compiler@5.0.1': dependencies: - fast-json-stringify: 6.0.1 + fast-json-stringify: 6.0.0 '@fastify/forwarded@3.0.0': {} '@fastify/http-proxy@10.0.2(bufferutil@4.0.9)(utf-8-validate@6.0.5)': dependencies: - '@fastify/reply-from': 11.0.2 + '@fastify/reply-from': 11.0.1 fast-querystring: 1.1.2 fastify-plugin: 5.0.1 - ws: 8.18.1(bufferutil@4.0.9)(utf-8-validate@6.0.5) + ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@6.0.5) transitivePeerDependencies: - bufferutil - utf-8-validate - '@fastify/merge-json-schemas@0.2.1': + '@fastify/merge-json-schemas@0.1.1': dependencies: - dequal: 2.0.3 + fast-deep-equal: 3.1.3 - '@fastify/multipart@9.0.3': + '@fastify/multipart@9.2.1': dependencies: - '@fastify/busboy': 3.1.1 - '@fastify/deepmerge': 2.0.2 - '@fastify/error': 4.2.0 + '@fastify/busboy': 3.0.0 + '@fastify/deepmerge': 3.1.0 + '@fastify/error': 4.0.0 fastify-plugin: 5.0.1 - secure-json-parse: 3.0.2 + secure-json-parse: 4.0.0 '@fastify/proxy-addr@5.0.0': dependencies: '@fastify/forwarded': 3.0.0 ipaddr.js: 2.2.0 - '@fastify/reply-from@11.0.2': + '@fastify/reply-from@11.0.1': dependencies: - '@fastify/error': 4.2.0 + '@fastify/error': 4.0.0 end-of-stream: 1.4.4 - fast-content-type-parse: 2.0.1 + fast-content-type-parse: 2.0.0 fast-querystring: 1.1.2 - fastify-plugin: 5.0.1 + fastify-plugin: 4.5.1 toad-cache: 3.7.0 - undici: 6.21.3 + undici: 6.19.8 - '@fastify/send@3.3.1': + '@fastify/send@4.1.0': dependencies: '@lukeed/ms': 2.0.2 escape-html: 1.0.3 @@ -12682,14 +13422,14 @@ snapshots: http-errors: 2.0.0 mime: 3.0.0 - '@fastify/static@8.1.1': + '@fastify/static@8.2.0': dependencies: - '@fastify/accept-negotiator': 2.0.1 - '@fastify/send': 3.3.1 + '@fastify/accept-negotiator': 2.0.0 + '@fastify/send': 4.1.0 content-disposition: 0.5.4 fastify-plugin: 5.0.1 - fastq: 1.19.1 - glob: 11.0.2 + fastq: 1.17.1 + glob: 11.0.3 '@fastify/view@10.0.2': dependencies: @@ -12703,10 +13443,10 @@ snapshots: '@google-cloud/projectify': 3.0.0 '@google-cloud/promisify': 3.0.1 arrify: 2.0.1 - duplexify: 4.1.3 - ent: 2.2.2 + duplexify: 4.1.2 + ent: 2.2.0 extend: 3.0.2 - google-auth-library: 8.9.0(encoding@0.1.13) + google-auth-library: 8.8.0(encoding@0.1.13) retry-request: 5.0.2 teeny-request: 8.0.3(encoding@0.1.13) transitivePeerDependencies: @@ -12724,12 +13464,12 @@ snapshots: eventid: 2.0.1 extend: 3.0.2 gcp-metadata: 4.3.1(encoding@0.1.13) - google-auth-library: 8.9.0(encoding@0.1.13) - google-gax: 3.6.1(encoding@0.1.13) + google-auth-library: 8.8.0(encoding@0.1.13) + google-gax: 3.6.0(encoding@0.1.13) on-finished: 2.4.1 pumpify: 2.0.1 stream-events: 1.0.5 - uuid: 9.0.1 + uuid: 9.0.0 transitivePeerDependencies: - encoding - supports-color @@ -12743,66 +13483,83 @@ snapshots: '@google-cloud/promisify@3.0.1': {} - '@google-cloud/translate@7.2.2(encoding@0.1.13)': + '@google-cloud/translate@7.2.1(encoding@0.1.13)': dependencies: '@google-cloud/common': 4.0.3(encoding@0.1.13) '@google-cloud/promisify': 3.0.1 arrify: 2.0.1 extend: 3.0.2 - google-gax: 3.6.1(encoding@0.1.13) + google-gax: 3.6.0(encoding@0.1.13) is-html: 2.0.0 transitivePeerDependencies: - encoding - supports-color - '@grpc/grpc-js@1.8.22': + '@grpc/grpc-js@1.8.16': dependencies: - '@grpc/proto-loader': 0.7.15 - '@types/node': 22.15.2 + '@grpc/proto-loader': 0.7.7 + '@types/node': 24.9.1 - '@grpc/proto-loader@0.7.15': + '@grpc/proto-loader@0.7.7': dependencies: + '@types/long': 4.0.2 lodash.camelcase: 4.3.0 - long: 5.3.2 - protobufjs: 7.5.3 + long: 4.0.0 + protobufjs: 7.2.3 yargs: 17.7.2 - '@hapi/boom@10.0.1': + '@hapi/address@5.1.1': dependencies: '@hapi/hoek': 11.0.7 + '@hapi/boom@10.0.1': + dependencies: + '@hapi/hoek': 11.0.4 + '@hapi/bourne@3.0.0': {} + '@hapi/formula@3.0.2': {} + + '@hapi/hoek@11.0.4': {} + '@hapi/hoek@11.0.7': {} '@hapi/hoek@9.3.0': {} + '@hapi/pinpoint@2.0.1': {} + + '@hapi/tlds@1.1.3': {} + '@hapi/topo@5.1.0': dependencies: '@hapi/hoek': 9.3.0 - '@hapi/wreck@18.1.0': + '@hapi/topo@6.0.2': + dependencies: + '@hapi/hoek': 11.0.7 + + '@hapi/wreck@18.0.1': dependencies: '@hapi/boom': 10.0.1 '@hapi/bourne': 3.0.0 - '@hapi/hoek': 11.0.7 + '@hapi/hoek': 11.0.4 - '@hexagon/base64@1.1.28': {} + '@hexagon/base64@1.1.27': {} '@humanfs/core@0.19.1': {} '@humanfs/node@0.16.6': dependencies: '@humanfs/core': 0.19.1 - '@humanwhocodes/retry': 0.3.1 + '@humanwhocodes/retry': 0.3.0 '@humanwhocodes/module-importer@1.0.1': {} '@humanwhocodes/momoa@2.0.4': {} - '@humanwhocodes/retry@0.3.1': {} + '@humanwhocodes/retry@0.3.0': {} - '@humanwhocodes/retry@0.4.3': {} + '@humanwhocodes/retry@0.4.2': {} '@img/sharp-darwin-arm64@0.33.5': optionalDependencies: @@ -12870,7 +13627,7 @@ snapshots: '@img/sharp-wasm32@0.33.5': dependencies: - '@emnapi/runtime': 1.4.3 + '@emnapi/runtime': 1.2.0 optional: true '@img/sharp-win32-ia32@0.33.5': @@ -12879,33 +13636,39 @@ snapshots: '@img/sharp-win32-x64@0.33.5': optional: true - '@inquirer/confirm@5.1.12(@types/node@22.15.2)': + '@inquirer/confirm@5.0.2(@types/node@24.9.1)': dependencies: - '@inquirer/core': 10.1.13(@types/node@22.15.2) - '@inquirer/type': 3.0.7(@types/node@22.15.2) - optionalDependencies: - '@types/node': 22.15.2 + '@inquirer/core': 10.1.0(@types/node@24.9.1) + '@inquirer/type': 3.0.1(@types/node@24.9.1) + '@types/node': 24.9.1 - '@inquirer/core@10.1.13(@types/node@22.15.2)': + '@inquirer/core@10.1.0(@types/node@24.9.1)': dependencies: - '@inquirer/figures': 1.0.12 - '@inquirer/type': 3.0.7(@types/node@22.15.2) + '@inquirer/figures': 1.0.8 + '@inquirer/type': 3.0.1(@types/node@24.9.1) ansi-escapes: 4.3.2 cli-width: 4.1.0 mute-stream: 2.0.0 signal-exit: 4.1.0 + strip-ansi: 6.0.1 wrap-ansi: 6.2.0 yoctocolors-cjs: 2.1.2 - optionalDependencies: - '@types/node': 22.15.2 + transitivePeerDependencies: + - '@types/node' - '@inquirer/figures@1.0.12': {} + '@inquirer/figures@1.0.8': {} - '@inquirer/type@3.0.7(@types/node@22.15.2)': - optionalDependencies: - '@types/node': 22.15.2 + '@inquirer/type@3.0.1(@types/node@24.9.1)': + dependencies: + '@types/node': 24.9.1 + + '@ioredis/commands@1.4.0': {} - '@ioredis/commands@1.2.0': {} + '@isaacs/balanced-match@4.0.1': {} + + '@isaacs/brace-expansion@5.0.0': + dependencies: + '@isaacs/balanced-match': 4.0.1 '@isaacs/cliui@8.0.2': dependencies: @@ -12933,7 +13696,7 @@ snapshots: '@jest/console@29.7.0': dependencies: '@jest/types': 29.6.3 - '@types/node': 22.15.2 + '@types/node': 24.9.1 chalk: 4.1.2 jest-message-util: 29.7.0 jest-util: 29.7.0 @@ -12946,14 +13709,14 @@ snapshots: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 22.15.2 + '@types/node': 24.9.1 ansi-escapes: 4.3.2 chalk: 4.1.2 - ci-info: 3.9.0 + ci-info: 3.7.1 exit: 0.1.2 graceful-fs: 4.2.11 jest-changed-files: 29.7.0 - jest-config: 29.7.0(@types/node@22.15.2) + jest-config: 29.7.0(@types/node@24.9.1) jest-haste-map: 29.7.0 jest-message-util: 29.7.0 jest-regex-util: 29.6.3 @@ -12974,15 +13737,15 @@ snapshots: - supports-color - ts-node - '@jest/create-cache-key-function@29.7.0': + '@jest/create-cache-key-function@30.2.0': dependencies: - '@jest/types': 29.6.3 + '@jest/types': 30.2.0 '@jest/environment@29.7.0': dependencies: '@jest/fake-timers': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 22.15.2 + '@types/node': 24.9.1 jest-mock: 29.7.0 '@jest/expect-utils@29.7.0': @@ -13000,7 +13763,7 @@ snapshots: dependencies: '@jest/types': 29.6.3 '@sinonjs/fake-timers': 10.3.0 - '@types/node': 22.15.2 + '@types/node': 24.9.1 jest-message-util: 29.7.0 jest-mock: 29.7.0 jest-util: 29.7.0 @@ -13014,6 +13777,11 @@ snapshots: transitivePeerDependencies: - supports-color + '@jest/pattern@30.0.1': + dependencies: + '@types/node': 24.9.1 + jest-regex-util: 30.0.1 + '@jest/reporters@29.7.0': dependencies: '@bcoe/v8-coverage': 0.2.3 @@ -13021,15 +13789,15 @@ snapshots: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@jridgewell/trace-mapping': 0.3.25 - '@types/node': 22.15.2 + '@jridgewell/trace-mapping': 0.3.31 + '@types/node': 24.9.1 chalk: 4.1.2 - collect-v8-coverage: 1.0.2 + collect-v8-coverage: 1.0.1 exit: 0.1.2 glob: 7.2.3 graceful-fs: 4.2.11 istanbul-lib-coverage: 3.2.2 - istanbul-lib-instrument: 6.0.3 + istanbul-lib-instrument: 6.0.0 istanbul-lib-report: 3.0.1 istanbul-lib-source-maps: 4.0.1 istanbul-reports: 3.1.7 @@ -13039,7 +13807,7 @@ snapshots: slash: 3.0.0 string-length: 4.0.2 strip-ansi: 6.0.1 - v8-to-istanbul: 9.3.0 + v8-to-istanbul: 9.1.0 transitivePeerDependencies: - supports-color @@ -13047,9 +13815,13 @@ snapshots: dependencies: '@sinclair/typebox': 0.27.8 + '@jest/schemas@30.0.5': + dependencies: + '@sinclair/typebox': 0.34.41 + '@jest/source-map@29.6.3': dependencies: - '@jridgewell/trace-mapping': 0.3.25 + '@jridgewell/trace-mapping': 0.3.31 callsites: 3.1.0 graceful-fs: 4.2.11 @@ -13057,8 +13829,8 @@ snapshots: dependencies: '@jest/console': 29.7.0 '@jest/types': 29.6.3 - '@types/istanbul-lib-coverage': 2.0.6 - collect-v8-coverage: 1.0.2 + '@types/istanbul-lib-coverage': 2.0.4 + collect-v8-coverage: 1.0.1 '@jest/test-sequencer@29.7.0': dependencies: @@ -13069,9 +13841,9 @@ snapshots: '@jest/transform@29.7.0': dependencies: - '@babel/core': 7.27.4 + '@babel/core': 7.28.4 '@jest/types': 29.6.3 - '@jridgewell/trace-mapping': 0.3.25 + '@jridgewell/trace-mapping': 0.3.31 babel-plugin-istanbul: 6.1.1 chalk: 4.1.2 convert-source-map: 2.0.0 @@ -13081,7 +13853,7 @@ snapshots: jest-regex-util: 29.6.3 jest-util: 29.7.0 micromatch: 4.0.8 - pirates: 4.0.7 + pirates: 4.0.5 slash: 3.0.0 write-file-atomic: 4.0.2 transitivePeerDependencies: @@ -13090,67 +13862,92 @@ snapshots: '@jest/types@29.6.3': dependencies: '@jest/schemas': 29.6.3 + '@types/istanbul-lib-coverage': 2.0.4 + '@types/istanbul-reports': 3.0.1 + '@types/node': 24.9.1 + '@types/yargs': 17.0.19 + chalk: 4.1.2 + + '@jest/types@30.2.0': + dependencies: + '@jest/pattern': 30.0.1 + '@jest/schemas': 30.0.5 '@types/istanbul-lib-coverage': 2.0.6 '@types/istanbul-reports': 3.0.4 - '@types/node': 22.15.2 + '@types/node': 24.9.1 '@types/yargs': 17.0.33 chalk: 4.1.2 - '@joshwooding/vite-plugin-react-docgen-typescript@0.5.0(typescript@5.8.3)(vite@6.3.4(@types/node@22.15.2)(sass@1.87.0)(terser@5.39.0)(tsx@4.19.3))': + '@joshwooding/vite-plugin-react-docgen-typescript@0.6.1(typescript@5.9.3)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6))': dependencies: glob: 10.4.5 - magic-string: 0.27.0 - react-docgen-typescript: 2.4.0(typescript@5.8.3) - vite: 6.3.4(@types/node@22.15.2)(sass@1.87.0)(terser@5.39.0)(tsx@4.19.3) + magic-string: 0.30.19 + react-docgen-typescript: 2.2.2(typescript@5.9.3) + vite: 7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6) optionalDependencies: - typescript: 5.8.3 + typescript: 5.9.3 - '@jridgewell/gen-mapping@0.3.8': + '@jridgewell/gen-mapping@0.3.13': + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/gen-mapping@0.3.5': dependencies: '@jridgewell/set-array': 1.2.1 - '@jridgewell/sourcemap-codec': 1.5.0 - '@jridgewell/trace-mapping': 0.3.25 + '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/remapping@2.3.5': + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 - '@jridgewell/resolve-uri@3.1.2': {} + '@jridgewell/resolve-uri@3.1.0': {} '@jridgewell/set-array@1.2.1': {} - '@jridgewell/source-map@0.3.6': + '@jridgewell/source-map@0.3.5': dependencies: - '@jridgewell/gen-mapping': 0.3.8 - '@jridgewell/trace-mapping': 0.3.25 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 - '@jridgewell/sourcemap-codec@1.5.0': {} + '@jridgewell/sourcemap-codec@1.5.5': {} '@jridgewell/trace-mapping@0.3.25': dependencies: - '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/resolve-uri': 3.1.0 + '@jridgewell/sourcemap-codec': 1.5.5 - '@jsdevtools/ono@7.1.3': {} + '@jridgewell/trace-mapping@0.3.31': + dependencies: + '@jridgewell/resolve-uri': 3.1.0 + '@jridgewell/sourcemap-codec': 1.5.5 - '@jsdoc/salty@0.2.9': + '@jsdoc/salty@0.2.5': dependencies: lodash: 4.17.21 - '@kurkle/color@0.3.4': {} + '@keyv/serialize@1.1.1': {} + + '@kurkle/color@0.3.2': {} - '@levischuck/tiny-cbor@0.2.11': {} + '@levischuck/tiny-cbor@0.2.2': {} - '@lukeed/csprng@1.1.0': {} + '@lukeed/csprng@1.0.1': {} '@lukeed/ms@2.0.2': {} '@mapbox/node-pre-gyp@1.0.9(encoding@0.1.13)': dependencies: - detect-libc: 2.0.4 + detect-libc: 2.0.3 https-proxy-agent: 5.0.1 make-dir: 3.1.0 node-fetch: 2.7.0(encoding@0.1.13) nopt: 5.0.0 npmlog: 5.0.1 rimraf: 3.0.2 - semver: 7.7.1 + semver: 7.7.3 tar: 6.2.1 transitivePeerDependencies: - encoding @@ -13163,32 +13960,32 @@ snapshots: dependencies: '@mcaptcha/core-glue': 0.1.0-alpha-5 - '@mdx-js/react@3.1.0(@types/react@19.1.8)(react@19.1.0)': + '@mdx-js/react@3.0.1(@types/react@18.0.28)(react@19.2.0)': dependencies: - '@types/mdx': 2.0.13 - '@types/react': 19.1.8 - react: 19.1.0 + '@types/mdx': 2.0.3 + '@types/react': 18.0.28 + react: 19.2.0 - '@microsoft/api-extractor-model@7.30.5(@types/node@22.15.2)': + '@microsoft/api-extractor-model@7.31.1(@types/node@24.9.1)': dependencies: '@microsoft/tsdoc': 0.15.1 '@microsoft/tsdoc-config': 0.17.1 - '@rushstack/node-core-library': 5.13.0(@types/node@22.15.2) + '@rushstack/node-core-library': 5.17.0(@types/node@24.9.1) transitivePeerDependencies: - '@types/node' - '@microsoft/api-extractor@7.52.5(@types/node@22.15.2)': + '@microsoft/api-extractor@7.53.1(@types/node@24.9.1)': dependencies: - '@microsoft/api-extractor-model': 7.30.5(@types/node@22.15.2) + '@microsoft/api-extractor-model': 7.31.1(@types/node@24.9.1) '@microsoft/tsdoc': 0.15.1 '@microsoft/tsdoc-config': 0.17.1 - '@rushstack/node-core-library': 5.13.0(@types/node@22.15.2) - '@rushstack/rig-package': 0.5.3 - '@rushstack/terminal': 0.15.2(@types/node@22.15.2) - '@rushstack/ts-command-line': 5.0.0(@types/node@22.15.2) + '@rushstack/node-core-library': 5.17.0(@types/node@24.9.1) + '@rushstack/rig-package': 0.6.0 + '@rushstack/terminal': 0.19.1(@types/node@24.9.1) + '@rushstack/ts-command-line': 5.1.1(@types/node@24.9.1) lodash: 4.17.21 - minimatch: 3.0.8 - resolve: 1.22.10 + minimatch: 10.0.3 + resolve: 1.22.8 semver: 7.5.4 source-map: 0.6.1 typescript: 5.8.2 @@ -13200,21 +13997,21 @@ snapshots: '@microsoft/tsdoc': 0.15.1 ajv: 8.12.0 jju: 1.4.0 - resolve: 1.22.10 + resolve: 1.22.8 '@microsoft/tsdoc@0.15.1': {} '@misskey-dev/browser-image-resizer@2024.1.0': {} - '@misskey-dev/eslint-plugin@2.1.0(@eslint/compat@1.3.0(eslint@9.25.1))(@stylistic/eslint-plugin@4.4.1(eslint@9.25.1)(typescript@5.8.3))(@typescript-eslint/eslint-plugin@8.31.0(@typescript-eslint/parser@8.31.0(eslint@9.25.1)(typescript@5.8.3))(eslint@9.25.1)(typescript@5.8.3))(@typescript-eslint/parser@8.31.0(eslint@9.25.1)(typescript@5.8.3))(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.31.0(eslint@9.25.1)(typescript@5.8.3))(eslint@9.25.1))(eslint@9.25.1)(globals@16.0.0)': + '@misskey-dev/eslint-plugin@2.1.0(@eslint/compat@1.1.1)(@stylistic/eslint-plugin@3.1.0(eslint@9.37.0)(typescript@5.9.3))(@typescript-eslint/eslint-plugin@8.46.1(@typescript-eslint/parser@8.46.1(eslint@9.37.0)(typescript@5.9.3))(eslint@9.37.0)(typescript@5.9.3))(@typescript-eslint/parser@8.46.1(eslint@9.37.0)(typescript@5.9.3))(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.46.1(eslint@9.37.0)(typescript@5.9.3))(eslint@9.37.0))(eslint@9.37.0)(globals@16.4.0)': dependencies: - '@eslint/compat': 1.3.0(eslint@9.25.1) - '@stylistic/eslint-plugin': 4.4.1(eslint@9.25.1)(typescript@5.8.3) - '@typescript-eslint/eslint-plugin': 8.31.0(@typescript-eslint/parser@8.31.0(eslint@9.25.1)(typescript@5.8.3))(eslint@9.25.1)(typescript@5.8.3) - '@typescript-eslint/parser': 8.31.0(eslint@9.25.1)(typescript@5.8.3) - eslint: 9.25.1 - eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.31.0(eslint@9.25.1)(typescript@5.8.3))(eslint@9.25.1) - globals: 16.0.0 + '@eslint/compat': 1.1.1 + '@stylistic/eslint-plugin': 3.1.0(eslint@9.37.0)(typescript@5.9.3) + '@typescript-eslint/eslint-plugin': 8.46.1(@typescript-eslint/parser@8.46.1(eslint@9.37.0)(typescript@5.9.3))(eslint@9.37.0)(typescript@5.9.3) + '@typescript-eslint/parser': 8.46.1(eslint@9.37.0)(typescript@5.9.3) + eslint: 9.37.0 + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.46.1(eslint@9.37.0)(typescript@5.9.3))(eslint@9.37.0) + globals: 16.4.0 '@misskey-dev/sharp-read-bmp@1.2.0': dependencies: @@ -13222,35 +14019,35 @@ snapshots: decode-ico: 0.4.1 sharp: 0.33.5 - '@misskey-dev/summaly@5.2.1': + '@misskey-dev/summaly@5.2.4': dependencies: - cheerio: 1.0.0 + cheerio: 1.1.2 escape-regexp: 0.0.1 - got: 14.4.7 - html-entities: 2.5.2 - iconv-lite: 0.6.3 + got: 14.5.0 + html-entities: 2.6.0 + iconv-lite: 0.7.0 jschardet: 3.1.4 private-ip: 3.0.2 - '@msgpackr-extract/msgpackr-extract-darwin-arm64@3.0.3': + '@msgpackr-extract/msgpackr-extract-darwin-arm64@3.0.2': optional: true - '@msgpackr-extract/msgpackr-extract-darwin-x64@3.0.3': + '@msgpackr-extract/msgpackr-extract-darwin-x64@3.0.2': optional: true - '@msgpackr-extract/msgpackr-extract-linux-arm64@3.0.3': + '@msgpackr-extract/msgpackr-extract-linux-arm64@3.0.2': optional: true - '@msgpackr-extract/msgpackr-extract-linux-arm@3.0.3': + '@msgpackr-extract/msgpackr-extract-linux-arm@3.0.2': optional: true - '@msgpackr-extract/msgpackr-extract-linux-x64@3.0.3': + '@msgpackr-extract/msgpackr-extract-linux-x64@3.0.2': optional: true - '@msgpackr-extract/msgpackr-extract-win32-x64@3.0.3': + '@msgpackr-extract/msgpackr-extract-win32-x64@3.0.2': optional: true - '@mswjs/interceptors@0.37.6': + '@mswjs/interceptors@0.39.7': dependencies: '@open-draft/deferred-promise': 2.2.0 '@open-draft/logger': 0.3.0 @@ -13259,120 +14056,52 @@ snapshots: outvariant: 1.4.3 strict-event-emitter: 0.5.1 - '@napi-rs/canvas-android-arm64@0.1.69': - optional: true - - '@napi-rs/canvas-darwin-arm64@0.1.69': - optional: true - - '@napi-rs/canvas-darwin-x64@0.1.69': - optional: true - - '@napi-rs/canvas-linux-arm-gnueabihf@0.1.69': - optional: true - - '@napi-rs/canvas-linux-arm64-gnu@0.1.69': - optional: true - - '@napi-rs/canvas-linux-arm64-musl@0.1.69': - optional: true - - '@napi-rs/canvas-linux-riscv64-gnu@0.1.69': - optional: true - - '@napi-rs/canvas-linux-x64-gnu@0.1.69': - optional: true - - '@napi-rs/canvas-linux-x64-musl@0.1.69': - optional: true - - '@napi-rs/canvas-win32-x64-msvc@0.1.69': + '@napi-rs/canvas-android-arm64@0.1.80': optional: true - '@napi-rs/canvas@0.1.69': - optionalDependencies: - '@napi-rs/canvas-android-arm64': 0.1.69 - '@napi-rs/canvas-darwin-arm64': 0.1.69 - '@napi-rs/canvas-darwin-x64': 0.1.69 - '@napi-rs/canvas-linux-arm-gnueabihf': 0.1.69 - '@napi-rs/canvas-linux-arm64-gnu': 0.1.69 - '@napi-rs/canvas-linux-arm64-musl': 0.1.69 - '@napi-rs/canvas-linux-riscv64-gnu': 0.1.69 - '@napi-rs/canvas-linux-x64-gnu': 0.1.69 - '@napi-rs/canvas-linux-x64-musl': 0.1.69 - '@napi-rs/canvas-win32-x64-msvc': 0.1.69 - - '@napi-rs/nice-android-arm-eabi@1.0.1': - optional: true - - '@napi-rs/nice-android-arm64@1.0.1': - optional: true - - '@napi-rs/nice-darwin-arm64@1.0.1': - optional: true - - '@napi-rs/nice-darwin-x64@1.0.1': - optional: true - - '@napi-rs/nice-freebsd-x64@1.0.1': - optional: true - - '@napi-rs/nice-linux-arm-gnueabihf@1.0.1': - optional: true - - '@napi-rs/nice-linux-arm64-gnu@1.0.1': - optional: true - - '@napi-rs/nice-linux-arm64-musl@1.0.1': + '@napi-rs/canvas-darwin-arm64@0.1.80': optional: true - '@napi-rs/nice-linux-ppc64-gnu@1.0.1': + '@napi-rs/canvas-darwin-x64@0.1.80': optional: true - '@napi-rs/nice-linux-riscv64-gnu@1.0.1': + '@napi-rs/canvas-linux-arm-gnueabihf@0.1.80': optional: true - '@napi-rs/nice-linux-s390x-gnu@1.0.1': + '@napi-rs/canvas-linux-arm64-gnu@0.1.80': optional: true - '@napi-rs/nice-linux-x64-gnu@1.0.1': + '@napi-rs/canvas-linux-arm64-musl@0.1.80': optional: true - '@napi-rs/nice-linux-x64-musl@1.0.1': + '@napi-rs/canvas-linux-riscv64-gnu@0.1.80': optional: true - '@napi-rs/nice-win32-arm64-msvc@1.0.1': + '@napi-rs/canvas-linux-x64-gnu@0.1.80': optional: true - '@napi-rs/nice-win32-ia32-msvc@1.0.1': + '@napi-rs/canvas-linux-x64-musl@0.1.80': optional: true - '@napi-rs/nice-win32-x64-msvc@1.0.1': + '@napi-rs/canvas-win32-x64-msvc@0.1.80': optional: true - '@napi-rs/nice@1.0.1': + '@napi-rs/canvas@0.1.80': optionalDependencies: - '@napi-rs/nice-android-arm-eabi': 1.0.1 - '@napi-rs/nice-android-arm64': 1.0.1 - '@napi-rs/nice-darwin-arm64': 1.0.1 - '@napi-rs/nice-darwin-x64': 1.0.1 - '@napi-rs/nice-freebsd-x64': 1.0.1 - '@napi-rs/nice-linux-arm-gnueabihf': 1.0.1 - '@napi-rs/nice-linux-arm64-gnu': 1.0.1 - '@napi-rs/nice-linux-arm64-musl': 1.0.1 - '@napi-rs/nice-linux-ppc64-gnu': 1.0.1 - '@napi-rs/nice-linux-riscv64-gnu': 1.0.1 - '@napi-rs/nice-linux-s390x-gnu': 1.0.1 - '@napi-rs/nice-linux-x64-gnu': 1.0.1 - '@napi-rs/nice-linux-x64-musl': 1.0.1 - '@napi-rs/nice-win32-arm64-msvc': 1.0.1 - '@napi-rs/nice-win32-ia32-msvc': 1.0.1 - '@napi-rs/nice-win32-x64-msvc': 1.0.1 - optional: true - - '@nestjs/common@11.1.0(reflect-metadata@0.2.2)(rxjs@7.8.2)': - dependencies: - file-type: 20.4.1 + '@napi-rs/canvas-android-arm64': 0.1.80 + '@napi-rs/canvas-darwin-arm64': 0.1.80 + '@napi-rs/canvas-darwin-x64': 0.1.80 + '@napi-rs/canvas-linux-arm-gnueabihf': 0.1.80 + '@napi-rs/canvas-linux-arm64-gnu': 0.1.80 + '@napi-rs/canvas-linux-arm64-musl': 0.1.80 + '@napi-rs/canvas-linux-riscv64-gnu': 0.1.80 + '@napi-rs/canvas-linux-x64-gnu': 0.1.80 + '@napi-rs/canvas-linux-x64-musl': 0.1.80 + '@napi-rs/canvas-win32-x64-msvc': 0.1.80 + + '@nestjs/common@11.1.6(reflect-metadata@0.2.2)(rxjs@7.8.2)': + dependencies: + file-type: 21.0.0 iterare: 1.2.1 load-esm: 1.0.2 reflect-metadata: 0.2.2 @@ -13382,9 +14111,9 @@ snapshots: transitivePeerDependencies: - supports-color - '@nestjs/core@11.1.0(@nestjs/common@11.1.0(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@10.4.17)(reflect-metadata@0.2.2)(rxjs@7.8.2)': + '@nestjs/core@11.1.6(@nestjs/common@11.1.6(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@10.4.20)(reflect-metadata@0.2.2)(rxjs@7.8.2)': dependencies: - '@nestjs/common': 11.1.0(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.6(reflect-metadata@0.2.2)(rxjs@7.8.2) '@nuxt/opencollective': 0.4.1 fast-safe-stringify: 2.1.1 iterare: 1.2.1 @@ -13394,27 +14123,27 @@ snapshots: tslib: 2.8.1 uid: 2.0.2 optionalDependencies: - '@nestjs/platform-express': 10.4.17(@nestjs/common@11.1.0(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.0) + '@nestjs/platform-express': 10.4.20(@nestjs/common@11.1.6(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.6) - '@nestjs/platform-express@10.4.17(@nestjs/common@11.1.0(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.0)': + '@nestjs/platform-express@10.4.20(@nestjs/common@11.1.6(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.6)': dependencies: - '@nestjs/common': 11.1.0(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.0(@nestjs/common@11.1.0(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@10.4.17)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.6(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.6(@nestjs/common@11.1.6(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@10.4.20)(reflect-metadata@0.2.2)(rxjs@7.8.2) body-parser: 1.20.3 cors: 2.8.5 express: 4.21.2 - multer: 1.4.4-lts.1 + multer: 2.0.2 tslib: 2.8.1 transitivePeerDependencies: - supports-color - '@nestjs/testing@11.1.0(@nestjs/common@11.1.0(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.0)(@nestjs/platform-express@10.4.17)': + '@nestjs/testing@11.1.6(@nestjs/common@11.1.6(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.6)(@nestjs/platform-express@10.4.20)': dependencies: - '@nestjs/common': 11.1.0(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.0(@nestjs/common@11.1.0(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@10.4.17)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.6(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.6(@nestjs/common@11.1.6(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@10.4.20)(reflect-metadata@0.2.2)(rxjs@7.8.2) tslib: 2.8.1 optionalDependencies: - '@nestjs/platform-express': 10.4.17(@nestjs/common@11.1.0(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.0) + '@nestjs/platform-express': 10.4.20(@nestjs/common@11.1.6(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.6) '@noble/hashes@1.7.1': {} @@ -13430,9 +14159,9 @@ snapshots: '@nodelib/fs.walk@1.2.8': dependencies: '@nodelib/fs.scandir': 2.1.5 - fastq: 1.19.1 + fastq: 1.17.1 - '@npmcli/agent@2.2.2': + '@npmcli/agent@3.0.0': dependencies: agent-base: 7.1.3 http-proxy-agent: 7.0.2 @@ -13442,13 +14171,13 @@ snapshots: transitivePeerDependencies: - supports-color - '@npmcli/fs@3.1.1': + '@npmcli/fs@4.0.0': dependencies: - semver: 7.7.1 + semver: 7.7.3 '@nuxt/opencollective@0.4.1': dependencies: - consola: 3.4.2 + consola: 3.4.0 '@one-ini/wasm@0.1.1': {} @@ -13461,15 +14190,11 @@ snapshots: '@open-draft/until@2.1.0': {} - '@openmeteo/sdk@1.20.1': - dependencies: - flatbuffers: 25.2.10 - - '@opentelemetry/api-logs@0.53.0': + '@openmeteo/sdk@1.18.6': dependencies: - '@opentelemetry/api': 1.9.0 + flatbuffers: 24.12.23 - '@opentelemetry/api-logs@0.57.1': + '@opentelemetry/api-logs@0.204.0': dependencies: '@opentelemetry/api': 1.9.0 @@ -13479,244 +14204,216 @@ snapshots: '@opentelemetry/api@1.9.0': {} - '@opentelemetry/context-async-hooks@1.30.1(@opentelemetry/api@1.9.0)': + '@opentelemetry/context-async-hooks@2.2.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/core@1.30.1(@opentelemetry/api@1.9.0)': + '@opentelemetry/core@2.1.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/semantic-conventions': 1.28.0 + '@opentelemetry/semantic-conventions': 1.37.0 - '@opentelemetry/instrumentation-amqplib@0.46.1(@opentelemetry/api@1.9.0)': + '@opentelemetry/core@2.2.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 1.30.1(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation': 0.57.2(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.34.0 - transitivePeerDependencies: - - supports-color + '@opentelemetry/semantic-conventions': 1.37.0 - '@opentelemetry/instrumentation-connect@0.43.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/instrumentation-amqplib@0.51.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 1.30.1(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation': 0.57.2(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.34.0 - '@types/connect': 3.4.36 + '@opentelemetry/core': 2.2.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.204.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.37.0 transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation-dataloader@0.16.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/instrumentation-connect@0.48.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/instrumentation': 0.57.2(@opentelemetry/api@1.9.0) + '@opentelemetry/core': 2.2.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.204.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.37.0 + '@types/connect': 3.4.38 transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation-express@0.47.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/instrumentation-dataloader@0.22.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 1.30.1(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation': 0.57.2(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.34.0 + '@opentelemetry/instrumentation': 0.204.0(@opentelemetry/api@1.9.0) transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation-fastify@0.44.1(@opentelemetry/api@1.9.0)': + '@opentelemetry/instrumentation-express@0.53.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 1.30.1(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation': 0.57.2(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.34.0 + '@opentelemetry/core': 2.2.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.204.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.37.0 transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation-fs@0.19.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/instrumentation-fs@0.24.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 1.30.1(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation': 0.57.2(@opentelemetry/api@1.9.0) + '@opentelemetry/core': 2.2.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.204.0(@opentelemetry/api@1.9.0) transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation-generic-pool@0.43.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/instrumentation-generic-pool@0.48.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/instrumentation': 0.57.2(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.204.0(@opentelemetry/api@1.9.0) transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation-graphql@0.47.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/instrumentation-graphql@0.52.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/instrumentation': 0.57.2(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.204.0(@opentelemetry/api@1.9.0) transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation-hapi@0.45.1(@opentelemetry/api@1.9.0)': + '@opentelemetry/instrumentation-hapi@0.51.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 1.30.1(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation': 0.57.2(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.34.0 + '@opentelemetry/core': 2.2.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.204.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.37.0 transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation-http@0.57.1(@opentelemetry/api@1.9.0)': + '@opentelemetry/instrumentation-http@0.204.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 1.30.1(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation': 0.57.1(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.28.0 + '@opentelemetry/core': 2.1.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.204.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.37.0 forwarded-parse: 2.1.2 - semver: 7.7.1 - transitivePeerDependencies: - - supports-color - - '@opentelemetry/instrumentation-ioredis@0.47.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/instrumentation': 0.57.2(@opentelemetry/api@1.9.0) - '@opentelemetry/redis-common': 0.36.2 - '@opentelemetry/semantic-conventions': 1.34.0 transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation-kafkajs@0.7.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/instrumentation-ioredis@0.52.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/instrumentation': 0.57.2(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.34.0 + '@opentelemetry/instrumentation': 0.204.0(@opentelemetry/api@1.9.0) + '@opentelemetry/redis-common': 0.38.2 + '@opentelemetry/semantic-conventions': 1.37.0 transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation-knex@0.44.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/instrumentation-kafkajs@0.14.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/instrumentation': 0.57.2(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.34.0 + '@opentelemetry/instrumentation': 0.204.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.37.0 transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation-koa@0.47.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/instrumentation-knex@0.49.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 1.30.1(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation': 0.57.2(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.34.0 + '@opentelemetry/instrumentation': 0.204.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.37.0 transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation-lru-memoizer@0.44.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/instrumentation-koa@0.52.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/instrumentation': 0.57.2(@opentelemetry/api@1.9.0) + '@opentelemetry/core': 2.2.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.204.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.37.0 transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation-mongodb@0.51.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/instrumentation-lru-memoizer@0.49.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/instrumentation': 0.57.2(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.34.0 + '@opentelemetry/instrumentation': 0.204.0(@opentelemetry/api@1.9.0) transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation-mongoose@0.46.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/instrumentation-mongodb@0.57.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 1.30.1(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation': 0.57.2(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.34.0 + '@opentelemetry/instrumentation': 0.204.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.37.0 transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation-mysql2@0.45.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/instrumentation-mongoose@0.51.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/instrumentation': 0.57.2(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.34.0 - '@opentelemetry/sql-common': 0.40.1(@opentelemetry/api@1.9.0) + '@opentelemetry/core': 2.2.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.204.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.37.0 transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation-mysql@0.45.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/instrumentation-mysql2@0.51.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/instrumentation': 0.57.2(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.34.0 - '@types/mysql': 2.15.26 + '@opentelemetry/instrumentation': 0.204.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.37.0 + '@opentelemetry/sql-common': 0.41.2(@opentelemetry/api@1.9.0) transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation-nestjs-core@0.44.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/instrumentation-mysql@0.50.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/instrumentation': 0.57.2(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.34.0 + '@opentelemetry/instrumentation': 0.204.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.37.0 + '@types/mysql': 2.15.27 transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation-pg@0.50.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/instrumentation-pg@0.57.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 1.30.1(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation': 0.57.2(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.27.0 - '@opentelemetry/sql-common': 0.40.1(@opentelemetry/api@1.9.0) - '@types/pg': 8.6.1 + '@opentelemetry/core': 2.2.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.204.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.37.0 + '@opentelemetry/sql-common': 0.41.2(@opentelemetry/api@1.9.0) + '@types/pg': 8.15.5 '@types/pg-pool': 2.0.6 transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation-redis-4@0.46.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/instrumentation-redis@0.53.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/instrumentation': 0.57.2(@opentelemetry/api@1.9.0) - '@opentelemetry/redis-common': 0.36.2 - '@opentelemetry/semantic-conventions': 1.34.0 + '@opentelemetry/instrumentation': 0.204.0(@opentelemetry/api@1.9.0) + '@opentelemetry/redis-common': 0.38.2 + '@opentelemetry/semantic-conventions': 1.37.0 transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation-tedious@0.18.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/instrumentation-tedious@0.23.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/instrumentation': 0.57.2(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.34.0 + '@opentelemetry/instrumentation': 0.204.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.37.0 '@types/tedious': 4.0.14 transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation-undici@0.10.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 1.30.1(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation': 0.57.2(@opentelemetry/api@1.9.0) - transitivePeerDependencies: - - supports-color - - '@opentelemetry/instrumentation@0.53.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/instrumentation-undici@0.15.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/api-logs': 0.53.0 - '@types/shimmer': 1.2.0 - import-in-the-middle: 1.14.2 - require-in-the-middle: 7.5.2 - semver: 7.7.1 - shimmer: 1.2.1 + '@opentelemetry/core': 2.2.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.204.0(@opentelemetry/api@1.9.0) transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation@0.57.1(@opentelemetry/api@1.9.0)': + '@opentelemetry/instrumentation@0.204.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/api-logs': 0.57.1 - '@types/shimmer': 1.2.0 - import-in-the-middle: 1.14.2 - require-in-the-middle: 7.5.2 - semver: 7.7.1 - shimmer: 1.2.1 + '@opentelemetry/api-logs': 0.204.0 + import-in-the-middle: 1.15.0 + require-in-the-middle: 7.3.0 transitivePeerDependencies: - supports-color @@ -13725,42 +14422,38 @@ snapshots: '@opentelemetry/api': 1.9.0 '@opentelemetry/api-logs': 0.57.2 '@types/shimmer': 1.2.0 - import-in-the-middle: 1.14.2 - require-in-the-middle: 7.5.2 - semver: 7.7.1 + import-in-the-middle: 1.15.0 + require-in-the-middle: 7.3.0 + semver: 7.7.3 shimmer: 1.2.1 transitivePeerDependencies: - supports-color - '@opentelemetry/redis-common@0.36.2': {} + '@opentelemetry/redis-common@0.38.2': {} - '@opentelemetry/resources@1.30.1(@opentelemetry/api@1.9.0)': + '@opentelemetry/resources@2.2.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 1.30.1(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.28.0 + '@opentelemetry/core': 2.2.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.37.0 - '@opentelemetry/sdk-trace-base@1.30.1(@opentelemetry/api@1.9.0)': + '@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 1.30.1(@opentelemetry/api@1.9.0) - '@opentelemetry/resources': 1.30.1(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.28.0 - - '@opentelemetry/semantic-conventions@1.27.0': {} + '@opentelemetry/core': 2.2.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.2.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.37.0 - '@opentelemetry/semantic-conventions@1.28.0': {} + '@opentelemetry/semantic-conventions@1.37.0': {} - '@opentelemetry/semantic-conventions@1.34.0': {} - - '@opentelemetry/sql-common@0.40.1(@opentelemetry/api@1.9.0)': + '@opentelemetry/sql-common@0.41.2(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 1.30.1(@opentelemetry/api@1.9.0) + '@opentelemetry/core': 2.2.0(@opentelemetry/api@1.9.0) '@paralleldrive/cuid2@2.2.2': dependencies: - '@noble/hashes': 1.8.0 + '@noble/hashes': 1.7.1 '@parcel/watcher-android-arm64@2.5.1': optional: true @@ -13823,55 +14516,55 @@ snapshots: '@parcel/watcher-win32-x64': 2.5.1 optional: true - '@peculiar/asn1-android@2.3.16': + '@peculiar/asn1-android@2.3.10': dependencies: - '@peculiar/asn1-schema': 2.3.15 - asn1js: 3.0.6 + '@peculiar/asn1-schema': 2.3.8 + asn1js: 3.0.5 tslib: 2.8.1 - '@peculiar/asn1-ecc@2.3.15': + '@peculiar/asn1-ecc@2.3.8': dependencies: - '@peculiar/asn1-schema': 2.3.15 - '@peculiar/asn1-x509': 2.3.15 - asn1js: 3.0.6 + '@peculiar/asn1-schema': 2.3.8 + '@peculiar/asn1-x509': 2.3.8 + asn1js: 3.0.5 tslib: 2.8.1 - '@peculiar/asn1-rsa@2.3.15': + '@peculiar/asn1-rsa@2.3.8': dependencies: - '@peculiar/asn1-schema': 2.3.15 - '@peculiar/asn1-x509': 2.3.15 - asn1js: 3.0.6 + '@peculiar/asn1-schema': 2.3.8 + '@peculiar/asn1-x509': 2.3.8 + asn1js: 3.0.5 tslib: 2.8.1 - '@peculiar/asn1-schema@2.3.15': + '@peculiar/asn1-schema@2.3.8': dependencies: - asn1js: 3.0.6 - pvtsutils: 1.3.6 + asn1js: 3.0.5 + pvtsutils: 1.3.5 tslib: 2.8.1 - '@peculiar/asn1-x509@2.3.15': + '@peculiar/asn1-x509@2.3.8': dependencies: - '@peculiar/asn1-schema': 2.3.15 - asn1js: 3.0.6 - pvtsutils: 1.3.6 + '@peculiar/asn1-schema': 2.3.8 + asn1js: 3.0.5 + ipaddr.js: 2.2.0 + pvtsutils: 1.3.5 tslib: 2.8.1 '@peertube/http-signature@1.7.0': dependencies: assert-plus: 1.0.0 jsprim: 1.4.2 - sshpk: 1.18.0 + sshpk: 1.17.0 '@phc/format@1.0.0': {} '@pkgjs/parseargs@0.11.0': optional: true - '@prisma/instrumentation@5.22.0': + '@prisma/instrumentation@6.15.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/instrumentation': 0.53.0(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-trace-base': 1.30.1(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.57.2(@opentelemetry/api@1.9.0) transitivePeerDependencies: - supports-color @@ -13901,118 +14594,140 @@ snapshots: '@readme/better-ajv-errors@2.3.2(ajv@8.17.1)': dependencies: '@babel/code-frame': 7.27.1 - '@babel/runtime': 7.27.6 + '@babel/runtime': 7.27.0 '@humanwhocodes/momoa': 2.0.4 ajv: 8.17.1 jsonpointer: 5.0.1 leven: 3.1.0 picocolors: 1.1.1 - '@readme/json-schema-ref-parser@1.2.0': - dependencies: - '@jsdevtools/ono': 7.1.3 - '@types/json-schema': 7.0.15 - call-me-maybe: 1.0.2 - js-yaml: 4.1.0 - - '@readme/openapi-parser@2.7.0(openapi-types@12.1.3)': + '@readme/openapi-parser@5.0.2(openapi-types@12.1.3)': dependencies: - '@apidevtools/swagger-methods': 3.0.2 - '@jsdevtools/ono': 7.1.3 + '@apidevtools/json-schema-ref-parser': 14.2.1(@types/json-schema@7.0.15) '@readme/better-ajv-errors': 2.3.2(ajv@8.17.1) - '@readme/json-schema-ref-parser': 1.2.0 '@readme/openapi-schemas': 3.1.0 + '@types/json-schema': 7.0.15 ajv: 8.17.1 ajv-draft-04: 1.0.0(ajv@8.17.1) - call-me-maybe: 1.0.2 openapi-types: 12.1.3 '@readme/openapi-schemas@3.1.0': {} - '@rollup/plugin-json@6.1.0(rollup@4.40.0)': + '@redocly/ajv@8.11.3': + dependencies: + fast-deep-equal: 3.1.3 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + uri-js-replace: 1.0.1 + + '@redocly/config@0.22.2': {} + + '@redocly/openapi-core@1.34.5(supports-color@10.2.2)': + dependencies: + '@redocly/ajv': 8.11.3 + '@redocly/config': 0.22.2 + colorette: 1.4.0 + https-proxy-agent: 7.0.6(supports-color@10.2.2) + js-levenshtein: 1.1.6 + js-yaml: 4.1.0 + minimatch: 5.1.2 + pluralize: 8.0.0 + yaml-ast-parser: 0.0.43 + transitivePeerDependencies: + - supports-color + + '@rolldown/pluginutils@1.0.0-beta.29': {} + + '@rollup/plugin-json@6.1.0(rollup@4.52.4)': dependencies: - '@rollup/pluginutils': 5.1.4(rollup@4.40.0) + '@rollup/pluginutils': 5.3.0(rollup@4.52.4) optionalDependencies: - rollup: 4.40.0 + rollup: 4.52.4 - '@rollup/plugin-replace@6.0.2(rollup@4.40.0)': + '@rollup/plugin-replace@6.0.2(rollup@4.52.4)': dependencies: - '@rollup/pluginutils': 5.1.4(rollup@4.40.0) - magic-string: 0.30.17 + '@rollup/pluginutils': 5.3.0(rollup@4.52.4) + magic-string: 0.30.19 optionalDependencies: - rollup: 4.40.0 + rollup: 4.52.4 - '@rollup/pluginutils@5.1.4(rollup@4.40.0)': + '@rollup/pluginutils@5.3.0(rollup@4.52.4)': dependencies: - '@types/estree': 1.0.7 + '@types/estree': 1.0.8 estree-walker: 2.0.2 picomatch: 4.0.2 optionalDependencies: - rollup: 4.40.0 + rollup: 4.52.4 - '@rollup/rollup-android-arm-eabi@4.40.0': + '@rollup/rollup-android-arm-eabi@4.52.4': optional: true - '@rollup/rollup-android-arm64@4.40.0': + '@rollup/rollup-android-arm64@4.52.4': optional: true - '@rollup/rollup-darwin-arm64@4.40.0': + '@rollup/rollup-darwin-arm64@4.52.4': optional: true - '@rollup/rollup-darwin-x64@4.40.0': + '@rollup/rollup-darwin-x64@4.52.4': optional: true - '@rollup/rollup-freebsd-arm64@4.40.0': + '@rollup/rollup-freebsd-arm64@4.52.4': optional: true - '@rollup/rollup-freebsd-x64@4.40.0': + '@rollup/rollup-freebsd-x64@4.52.4': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.40.0': + '@rollup/rollup-linux-arm-gnueabihf@4.52.4': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.40.0': + '@rollup/rollup-linux-arm-musleabihf@4.52.4': optional: true - '@rollup/rollup-linux-arm64-gnu@4.40.0': + '@rollup/rollup-linux-arm64-gnu@4.52.4': optional: true - '@rollup/rollup-linux-arm64-musl@4.40.0': + '@rollup/rollup-linux-arm64-musl@4.52.4': optional: true - '@rollup/rollup-linux-loongarch64-gnu@4.40.0': + '@rollup/rollup-linux-loong64-gnu@4.52.4': optional: true - '@rollup/rollup-linux-powerpc64le-gnu@4.40.0': + '@rollup/rollup-linux-ppc64-gnu@4.52.4': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.40.0': + '@rollup/rollup-linux-riscv64-gnu@4.52.4': optional: true - '@rollup/rollup-linux-riscv64-musl@4.40.0': + '@rollup/rollup-linux-riscv64-musl@4.52.4': optional: true - '@rollup/rollup-linux-s390x-gnu@4.40.0': + '@rollup/rollup-linux-s390x-gnu@4.52.4': optional: true - '@rollup/rollup-linux-x64-gnu@4.40.0': + '@rollup/rollup-linux-x64-gnu@4.52.4': optional: true - '@rollup/rollup-linux-x64-musl@4.40.0': + '@rollup/rollup-linux-x64-musl@4.52.4': optional: true - '@rollup/rollup-win32-arm64-msvc@4.40.0': + '@rollup/rollup-openharmony-arm64@4.52.4': optional: true - '@rollup/rollup-win32-ia32-msvc@4.40.0': + '@rollup/rollup-win32-arm64-msvc@4.52.4': optional: true - '@rollup/rollup-win32-x64-msvc@4.40.0': + '@rollup/rollup-win32-ia32-msvc@4.52.4': + optional: true + + '@rollup/rollup-win32-x64-gnu@4.52.4': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.52.4': optional: true '@rtsao/scc@1.1.0': {} - '@rushstack/node-core-library@5.13.0(@types/node@22.15.2)': + '@rushstack/node-core-library@5.17.0(@types/node@24.9.1)': dependencies: ajv: 8.13.0 ajv-draft-04: 1.0.0(ajv@8.13.0) @@ -14020,163 +14735,185 @@ snapshots: fs-extra: 11.3.0 import-lazy: 4.0.0 jju: 1.4.0 - resolve: 1.22.10 + resolve: 1.22.8 semver: 7.5.4 optionalDependencies: - '@types/node': 22.15.2 + '@types/node': 24.9.1 - '@rushstack/rig-package@0.5.3': + '@rushstack/problem-matcher@0.1.1(@types/node@24.9.1)': + optionalDependencies: + '@types/node': 24.9.1 + + '@rushstack/rig-package@0.6.0': dependencies: - resolve: 1.22.10 + resolve: 1.22.8 strip-json-comments: 3.1.1 - '@rushstack/terminal@0.15.2(@types/node@22.15.2)': + '@rushstack/terminal@0.19.1(@types/node@24.9.1)': dependencies: - '@rushstack/node-core-library': 5.13.0(@types/node@22.15.2) + '@rushstack/node-core-library': 5.17.0(@types/node@24.9.1) + '@rushstack/problem-matcher': 0.1.1(@types/node@24.9.1) supports-color: 8.1.1 optionalDependencies: - '@types/node': 22.15.2 + '@types/node': 24.9.1 - '@rushstack/ts-command-line@5.0.0(@types/node@22.15.2)': + '@rushstack/ts-command-line@5.1.1(@types/node@24.9.1)': dependencies: - '@rushstack/terminal': 0.15.2(@types/node@22.15.2) + '@rushstack/terminal': 0.19.1(@types/node@24.9.1) '@types/argparse': 1.0.38 argparse: 1.0.10 - string-argv: 0.3.2 + string-argv: 0.3.1 transitivePeerDependencies: - '@types/node' '@sec-ant/readable-stream@0.4.1': {} - '@sentry-internal/browser-utils@9.14.0': + '@sentry-internal/browser-utils@10.20.0': dependencies: - '@sentry/core': 9.14.0 + '@sentry/core': 10.20.0 - '@sentry-internal/feedback@9.14.0': + '@sentry-internal/feedback@10.20.0': dependencies: - '@sentry/core': 9.14.0 + '@sentry/core': 10.20.0 - '@sentry-internal/replay-canvas@9.14.0': + '@sentry-internal/node-cpu-profiler@2.2.0': dependencies: - '@sentry-internal/replay': 9.14.0 - '@sentry/core': 9.14.0 + detect-libc: 2.0.3 + node-abi: 3.78.0 - '@sentry-internal/replay@9.14.0': + '@sentry-internal/replay-canvas@10.20.0': dependencies: - '@sentry-internal/browser-utils': 9.14.0 - '@sentry/core': 9.14.0 + '@sentry-internal/replay': 10.20.0 + '@sentry/core': 10.20.0 - '@sentry/browser@9.14.0': + '@sentry-internal/replay@10.20.0': dependencies: - '@sentry-internal/browser-utils': 9.14.0 - '@sentry-internal/feedback': 9.14.0 - '@sentry-internal/replay': 9.14.0 - '@sentry-internal/replay-canvas': 9.14.0 - '@sentry/core': 9.14.0 + '@sentry-internal/browser-utils': 10.20.0 + '@sentry/core': 10.20.0 - '@sentry/core@8.55.0': {} + '@sentry/browser@10.20.0': + dependencies: + '@sentry-internal/browser-utils': 10.20.0 + '@sentry-internal/feedback': 10.20.0 + '@sentry-internal/replay': 10.20.0 + '@sentry-internal/replay-canvas': 10.20.0 + '@sentry/core': 10.20.0 - '@sentry/core@9.14.0': {} + '@sentry/core@10.20.0': {} - '@sentry/node@8.55.0': + '@sentry/node-core@10.20.0(@opentelemetry/api@1.9.0)(@opentelemetry/context-async-hooks@2.2.0(@opentelemetry/api@1.9.0))(@opentelemetry/core@2.2.0(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.204.0(@opentelemetry/api@1.9.0))(@opentelemetry/resources@2.2.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.37.0)': dependencies: + '@apm-js-collab/tracing-hooks': 0.3.1 '@opentelemetry/api': 1.9.0 - '@opentelemetry/context-async-hooks': 1.30.1(@opentelemetry/api@1.9.0) - '@opentelemetry/core': 1.30.1(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation': 0.57.2(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-amqplib': 0.46.1(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-connect': 0.43.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-dataloader': 0.16.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-express': 0.47.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-fastify': 0.44.1(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-fs': 0.19.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-generic-pool': 0.43.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-graphql': 0.47.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-hapi': 0.45.1(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-http': 0.57.1(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-ioredis': 0.47.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-kafkajs': 0.7.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-knex': 0.44.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-koa': 0.47.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-lru-memoizer': 0.44.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-mongodb': 0.51.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-mongoose': 0.46.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-mysql': 0.45.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-mysql2': 0.45.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-nestjs-core': 0.44.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-pg': 0.50.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-redis-4': 0.46.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-tedious': 0.18.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-undici': 0.10.0(@opentelemetry/api@1.9.0) - '@opentelemetry/resources': 1.30.1(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-trace-base': 1.30.1(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.34.0 - '@prisma/instrumentation': 5.22.0 - '@sentry/core': 8.55.0 - '@sentry/opentelemetry': 8.55.0(@opentelemetry/api@1.9.0)(@opentelemetry/context-async-hooks@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/core@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.57.2(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.34.0) - import-in-the-middle: 1.14.2 + '@opentelemetry/context-async-hooks': 2.2.0(@opentelemetry/api@1.9.0) + '@opentelemetry/core': 2.2.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.204.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.2.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace-base': 2.2.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.37.0 + '@sentry/core': 10.20.0 + '@sentry/opentelemetry': 10.20.0(@opentelemetry/api@1.9.0)(@opentelemetry/context-async-hooks@2.2.0(@opentelemetry/api@1.9.0))(@opentelemetry/core@2.2.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.37.0) + import-in-the-middle: 1.15.0 transitivePeerDependencies: - supports-color - '@sentry/opentelemetry@8.55.0(@opentelemetry/api@1.9.0)(@opentelemetry/context-async-hooks@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/core@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.57.2(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.34.0)': + '@sentry/node@10.20.0': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/context-async-hooks': 1.30.1(@opentelemetry/api@1.9.0) - '@opentelemetry/core': 1.30.1(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation': 0.57.2(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-trace-base': 1.30.1(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.34.0 - '@sentry/core': 8.55.0 + '@opentelemetry/context-async-hooks': 2.2.0(@opentelemetry/api@1.9.0) + '@opentelemetry/core': 2.2.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.204.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-amqplib': 0.51.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-connect': 0.48.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-dataloader': 0.22.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-express': 0.53.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-fs': 0.24.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-generic-pool': 0.48.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-graphql': 0.52.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-hapi': 0.51.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-http': 0.204.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-ioredis': 0.52.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-kafkajs': 0.14.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-knex': 0.49.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-koa': 0.52.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-lru-memoizer': 0.49.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-mongodb': 0.57.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-mongoose': 0.51.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-mysql': 0.50.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-mysql2': 0.51.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-pg': 0.57.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-redis': 0.53.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-tedious': 0.23.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-undici': 0.15.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.2.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace-base': 2.2.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.37.0 + '@prisma/instrumentation': 6.15.0(@opentelemetry/api@1.9.0) + '@sentry/core': 10.20.0 + '@sentry/node-core': 10.20.0(@opentelemetry/api@1.9.0)(@opentelemetry/context-async-hooks@2.2.0(@opentelemetry/api@1.9.0))(@opentelemetry/core@2.2.0(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.204.0(@opentelemetry/api@1.9.0))(@opentelemetry/resources@2.2.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.37.0) + '@sentry/opentelemetry': 10.20.0(@opentelemetry/api@1.9.0)(@opentelemetry/context-async-hooks@2.2.0(@opentelemetry/api@1.9.0))(@opentelemetry/core@2.2.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.37.0) + import-in-the-middle: 1.15.0 + minimatch: 9.0.4 + transitivePeerDependencies: + - supports-color + + '@sentry/opentelemetry@10.20.0(@opentelemetry/api@1.9.0)(@opentelemetry/context-async-hooks@2.2.0(@opentelemetry/api@1.9.0))(@opentelemetry/core@2.2.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.37.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/context-async-hooks': 2.2.0(@opentelemetry/api@1.9.0) + '@opentelemetry/core': 2.2.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace-base': 2.2.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.37.0 + '@sentry/core': 10.20.0 - '@sentry/profiling-node@8.55.0': + '@sentry/profiling-node@10.20.0': dependencies: - '@sentry/core': 8.55.0 - '@sentry/node': 8.55.0 - detect-libc: 2.0.4 - node-abi: 3.75.0 + '@sentry-internal/node-cpu-profiler': 2.2.0 + '@sentry/core': 10.20.0 + '@sentry/node': 10.20.0 transitivePeerDependencies: - supports-color - '@sentry/vue@9.14.0(vue@3.5.13(typescript@5.8.3))': + '@sentry/vue@10.20.0(vue@3.5.22(typescript@5.9.3))': dependencies: - '@sentry/browser': 9.14.0 - '@sentry/core': 9.14.0 - vue: 3.5.13(typescript@5.8.3) + '@sentry/browser': 10.20.0 + '@sentry/core': 10.20.0 + vue: 3.5.22(typescript@5.9.3) - '@shikijs/core@3.3.0': + '@shikijs/core@3.13.0': dependencies: - '@shikijs/types': 3.3.0 + '@shikijs/types': 3.13.0 '@shikijs/vscode-textmate': 10.0.2 '@types/hast': 3.0.4 hast-util-to-html: 9.0.5 - '@shikijs/engine-javascript@3.3.0': + '@shikijs/engine-javascript@3.13.0': dependencies: - '@shikijs/types': 3.3.0 + '@shikijs/types': 3.13.0 '@shikijs/vscode-textmate': 10.0.2 oniguruma-to-es: 4.3.3 - '@shikijs/engine-oniguruma@3.3.0': + '@shikijs/engine-oniguruma@3.13.0': dependencies: - '@shikijs/types': 3.3.0 + '@shikijs/types': 3.13.0 '@shikijs/vscode-textmate': 10.0.2 - '@shikijs/langs@3.3.0': + '@shikijs/langs@3.13.0': dependencies: - '@shikijs/types': 3.3.0 + '@shikijs/types': 3.13.0 - '@shikijs/themes@3.3.0': + '@shikijs/themes@3.13.0': dependencies: - '@shikijs/types': 3.3.0 + '@shikijs/types': 3.13.0 - '@shikijs/types@3.3.0': + '@shikijs/types@3.13.0': dependencies: '@shikijs/vscode-textmate': 10.0.2 '@types/hast': 3.0.4 '@shikijs/vscode-textmate@10.0.2': {} - '@sideway/address@4.1.5': + '@sideway/address@4.1.4': dependencies: '@hapi/hoek': 9.3.0 @@ -14186,15 +14923,15 @@ snapshots: '@simplewebauthn/server@12.0.0(encoding@0.1.13)': dependencies: - '@hexagon/base64': 1.1.28 - '@levischuck/tiny-cbor': 0.2.11 - '@peculiar/asn1-android': 2.3.16 - '@peculiar/asn1-ecc': 2.3.15 - '@peculiar/asn1-rsa': 2.3.15 - '@peculiar/asn1-schema': 2.3.15 - '@peculiar/asn1-x509': 2.3.15 + '@hexagon/base64': 1.1.27 + '@levischuck/tiny-cbor': 0.2.2 + '@peculiar/asn1-android': 2.3.10 + '@peculiar/asn1-ecc': 2.3.8 + '@peculiar/asn1-rsa': 2.3.8 + '@peculiar/asn1-schema': 2.3.8 + '@peculiar/asn1-x509': 2.3.8 '@simplewebauthn/types': 12.0.0 - cross-fetch: 4.1.0(encoding@0.1.13) + cross-fetch: 4.0.0(encoding@0.1.13) transitivePeerDependencies: - encoding @@ -14202,19 +14939,29 @@ snapshots: '@sinclair/typebox@0.27.8': {} - '@sindresorhus/is@5.6.0': {} + '@sinclair/typebox@0.34.41': {} - '@sindresorhus/is@7.0.2': {} + '@sindresorhus/is@5.3.0': {} + + '@sindresorhus/is@7.0.1': {} '@sindresorhus/merge-streams@4.0.0': {} + '@sinonjs/commons@2.0.0': + dependencies: + type-detect: 4.0.8 + + '@sinonjs/commons@3.0.0': + dependencies: + type-detect: 4.0.8 + '@sinonjs/commons@3.0.1': dependencies: type-detect: 4.0.8 '@sinonjs/fake-timers@10.3.0': dependencies: - '@sinonjs/commons': 3.0.1 + '@sinonjs/commons': 3.0.0 '@sinonjs/fake-timers@11.2.2': dependencies: @@ -14228,11 +14975,11 @@ snapshots: dependencies: '@sinonjs/commons': 3.0.1 - '@sinonjs/samsam@8.0.2': + '@sinonjs/samsam@8.0.0': dependencies: - '@sinonjs/commons': 3.0.1 + '@sinonjs/commons': 2.0.0 lodash.get: 4.4.2 - type-detect: 4.1.0 + type-detect: 4.0.8 '@sinonjs/text-encoding@0.7.3': {} @@ -14241,170 +14988,171 @@ snapshots: '@smithy/types': 2.12.0 tslib: 2.8.1 - '@smithy/abort-controller@4.0.4': + '@smithy/abort-controller@4.2.0': dependencies: - '@smithy/types': 4.3.1 + '@smithy/types': 4.6.0 tslib: 2.8.1 - '@smithy/chunked-blob-reader-native@4.0.0': + '@smithy/chunked-blob-reader-native@4.2.1': dependencies: - '@smithy/util-base64': 4.0.0 + '@smithy/util-base64': 4.3.0 tslib: 2.8.1 - '@smithy/chunked-blob-reader@5.0.0': + '@smithy/chunked-blob-reader@5.2.0': dependencies: tslib: 2.8.1 - '@smithy/config-resolver@4.1.4': + '@smithy/config-resolver@4.3.0': dependencies: - '@smithy/node-config-provider': 4.1.3 - '@smithy/types': 4.3.1 - '@smithy/util-config-provider': 4.0.0 - '@smithy/util-middleware': 4.0.4 + '@smithy/node-config-provider': 4.3.0 + '@smithy/types': 4.6.0 + '@smithy/util-config-provider': 4.2.0 + '@smithy/util-middleware': 4.2.0 tslib: 2.8.1 - '@smithy/core@3.5.3': - dependencies: - '@smithy/middleware-serde': 4.0.8 - '@smithy/protocol-http': 5.1.2 - '@smithy/types': 4.3.1 - '@smithy/util-base64': 4.0.0 - '@smithy/util-body-length-browser': 4.0.0 - '@smithy/util-middleware': 4.0.4 - '@smithy/util-stream': 4.2.2 - '@smithy/util-utf8': 4.0.0 + '@smithy/core@3.15.0': + dependencies: + '@smithy/middleware-serde': 4.2.0 + '@smithy/protocol-http': 5.3.0 + '@smithy/types': 4.6.0 + '@smithy/util-base64': 4.3.0 + '@smithy/util-body-length-browser': 4.2.0 + '@smithy/util-middleware': 4.2.0 + '@smithy/util-stream': 4.5.0 + '@smithy/util-utf8': 4.2.0 + '@smithy/uuid': 1.1.0 tslib: 2.8.1 - '@smithy/credential-provider-imds@4.0.6': + '@smithy/credential-provider-imds@4.2.0': dependencies: - '@smithy/node-config-provider': 4.1.3 - '@smithy/property-provider': 4.0.4 - '@smithy/types': 4.3.1 - '@smithy/url-parser': 4.0.4 + '@smithy/node-config-provider': 4.3.0 + '@smithy/property-provider': 4.2.0 + '@smithy/types': 4.6.0 + '@smithy/url-parser': 4.2.0 tslib: 2.8.1 - '@smithy/eventstream-codec@4.0.4': + '@smithy/eventstream-codec@4.2.0': dependencies: '@aws-crypto/crc32': 5.2.0 - '@smithy/types': 4.3.1 - '@smithy/util-hex-encoding': 4.0.0 + '@smithy/types': 4.6.0 + '@smithy/util-hex-encoding': 4.2.0 tslib: 2.8.1 - '@smithy/eventstream-serde-browser@4.0.4': + '@smithy/eventstream-serde-browser@4.2.0': dependencies: - '@smithy/eventstream-serde-universal': 4.0.4 - '@smithy/types': 4.3.1 + '@smithy/eventstream-serde-universal': 4.2.0 + '@smithy/types': 4.6.0 tslib: 2.8.1 - '@smithy/eventstream-serde-config-resolver@4.1.2': + '@smithy/eventstream-serde-config-resolver@4.3.0': dependencies: - '@smithy/types': 4.3.1 + '@smithy/types': 4.6.0 tslib: 2.8.1 - '@smithy/eventstream-serde-node@4.0.4': + '@smithy/eventstream-serde-node@4.2.0': dependencies: - '@smithy/eventstream-serde-universal': 4.0.4 - '@smithy/types': 4.3.1 + '@smithy/eventstream-serde-universal': 4.2.0 + '@smithy/types': 4.6.0 tslib: 2.8.1 - '@smithy/eventstream-serde-universal@4.0.4': + '@smithy/eventstream-serde-universal@4.2.0': dependencies: - '@smithy/eventstream-codec': 4.0.4 - '@smithy/types': 4.3.1 + '@smithy/eventstream-codec': 4.2.0 + '@smithy/types': 4.6.0 tslib: 2.8.1 - '@smithy/fetch-http-handler@5.0.4': + '@smithy/fetch-http-handler@5.3.1': dependencies: - '@smithy/protocol-http': 5.1.2 - '@smithy/querystring-builder': 4.0.4 - '@smithy/types': 4.3.1 - '@smithy/util-base64': 4.0.0 + '@smithy/protocol-http': 5.3.0 + '@smithy/querystring-builder': 4.2.0 + '@smithy/types': 4.6.0 + '@smithy/util-base64': 4.3.0 tslib: 2.8.1 - '@smithy/hash-blob-browser@4.0.4': + '@smithy/hash-blob-browser@4.2.1': dependencies: - '@smithy/chunked-blob-reader': 5.0.0 - '@smithy/chunked-blob-reader-native': 4.0.0 - '@smithy/types': 4.3.1 + '@smithy/chunked-blob-reader': 5.2.0 + '@smithy/chunked-blob-reader-native': 4.2.1 + '@smithy/types': 4.6.0 tslib: 2.8.1 - '@smithy/hash-node@4.0.4': + '@smithy/hash-node@4.2.0': dependencies: - '@smithy/types': 4.3.1 - '@smithy/util-buffer-from': 4.0.0 - '@smithy/util-utf8': 4.0.0 + '@smithy/types': 4.6.0 + '@smithy/util-buffer-from': 4.2.0 + '@smithy/util-utf8': 4.2.0 tslib: 2.8.1 - '@smithy/hash-stream-node@4.0.4': + '@smithy/hash-stream-node@4.2.0': dependencies: - '@smithy/types': 4.3.1 - '@smithy/util-utf8': 4.0.0 + '@smithy/types': 4.6.0 + '@smithy/util-utf8': 4.2.0 tslib: 2.8.1 - '@smithy/invalid-dependency@4.0.4': + '@smithy/invalid-dependency@4.2.0': dependencies: - '@smithy/types': 4.3.1 + '@smithy/types': 4.6.0 tslib: 2.8.1 '@smithy/is-array-buffer@2.2.0': dependencies: tslib: 2.8.1 - '@smithy/is-array-buffer@4.0.0': + '@smithy/is-array-buffer@4.2.0': dependencies: tslib: 2.8.1 - '@smithy/md5-js@4.0.4': + '@smithy/md5-js@4.2.0': dependencies: - '@smithy/types': 4.3.1 - '@smithy/util-utf8': 4.0.0 + '@smithy/types': 4.6.0 + '@smithy/util-utf8': 4.2.0 tslib: 2.8.1 - '@smithy/middleware-content-length@4.0.4': + '@smithy/middleware-content-length@4.2.0': dependencies: - '@smithy/protocol-http': 5.1.2 - '@smithy/types': 4.3.1 + '@smithy/protocol-http': 5.3.0 + '@smithy/types': 4.6.0 tslib: 2.8.1 - '@smithy/middleware-endpoint@4.1.11': + '@smithy/middleware-endpoint@4.3.1': dependencies: - '@smithy/core': 3.5.3 - '@smithy/middleware-serde': 4.0.8 - '@smithy/node-config-provider': 4.1.3 - '@smithy/shared-ini-file-loader': 4.0.4 - '@smithy/types': 4.3.1 - '@smithy/url-parser': 4.0.4 - '@smithy/util-middleware': 4.0.4 + '@smithy/core': 3.15.0 + '@smithy/middleware-serde': 4.2.0 + '@smithy/node-config-provider': 4.3.0 + '@smithy/shared-ini-file-loader': 4.3.0 + '@smithy/types': 4.6.0 + '@smithy/url-parser': 4.2.0 + '@smithy/util-middleware': 4.2.0 tslib: 2.8.1 - '@smithy/middleware-retry@4.1.12': + '@smithy/middleware-retry@4.4.1': dependencies: - '@smithy/node-config-provider': 4.1.3 - '@smithy/protocol-http': 5.1.2 - '@smithy/service-error-classification': 4.0.5 - '@smithy/smithy-client': 4.4.3 - '@smithy/types': 4.3.1 - '@smithy/util-middleware': 4.0.4 - '@smithy/util-retry': 4.0.5 + '@smithy/node-config-provider': 4.3.0 + '@smithy/protocol-http': 5.3.0 + '@smithy/service-error-classification': 4.2.0 + '@smithy/smithy-client': 4.7.1 + '@smithy/types': 4.6.0 + '@smithy/util-middleware': 4.2.0 + '@smithy/util-retry': 4.2.0 + '@smithy/uuid': 1.1.0 tslib: 2.8.1 - uuid: 9.0.1 - '@smithy/middleware-serde@4.0.8': + '@smithy/middleware-serde@4.2.0': dependencies: - '@smithy/protocol-http': 5.1.2 - '@smithy/types': 4.3.1 + '@smithy/protocol-http': 5.3.0 + '@smithy/types': 4.6.0 tslib: 2.8.1 - '@smithy/middleware-stack@4.0.4': + '@smithy/middleware-stack@4.2.0': dependencies: - '@smithy/types': 4.3.1 + '@smithy/types': 4.6.0 tslib: 2.8.1 - '@smithy/node-config-provider@4.1.3': + '@smithy/node-config-provider@4.3.0': dependencies: - '@smithy/property-provider': 4.0.4 - '@smithy/shared-ini-file-loader': 4.0.4 - '@smithy/types': 4.3.1 + '@smithy/property-provider': 4.2.0 + '@smithy/shared-ini-file-loader': 4.3.0 + '@smithy/types': 4.6.0 tslib: 2.8.1 '@smithy/node-http-handler@2.5.0': @@ -14413,19 +15161,19 @@ snapshots: '@smithy/protocol-http': 3.3.0 '@smithy/querystring-builder': 2.2.0 '@smithy/types': 2.12.0 - tslib: 2.8.1 + tslib: 2.6.2 - '@smithy/node-http-handler@4.0.6': + '@smithy/node-http-handler@4.3.0': dependencies: - '@smithy/abort-controller': 4.0.4 - '@smithy/protocol-http': 5.1.2 - '@smithy/querystring-builder': 4.0.4 - '@smithy/types': 4.3.1 + '@smithy/abort-controller': 4.2.0 + '@smithy/protocol-http': 5.3.0 + '@smithy/querystring-builder': 4.2.0 + '@smithy/types': 4.6.0 tslib: 2.8.1 - '@smithy/property-provider@4.0.4': + '@smithy/property-provider@4.2.0': dependencies: - '@smithy/types': 4.3.1 + '@smithy/types': 4.6.0 tslib: 2.8.1 '@smithy/protocol-http@3.3.0': @@ -14433,9 +15181,9 @@ snapshots: '@smithy/types': 2.12.0 tslib: 2.8.1 - '@smithy/protocol-http@5.1.2': + '@smithy/protocol-http@5.3.0': dependencies: - '@smithy/types': 4.3.1 + '@smithy/types': 4.6.0 tslib: 2.8.1 '@smithy/querystring-builder@2.2.0': @@ -14444,72 +15192,72 @@ snapshots: '@smithy/util-uri-escape': 2.2.0 tslib: 2.8.1 - '@smithy/querystring-builder@4.0.4': + '@smithy/querystring-builder@4.2.0': dependencies: - '@smithy/types': 4.3.1 - '@smithy/util-uri-escape': 4.0.0 + '@smithy/types': 4.6.0 + '@smithy/util-uri-escape': 4.2.0 tslib: 2.8.1 - '@smithy/querystring-parser@4.0.4': + '@smithy/querystring-parser@4.2.0': dependencies: - '@smithy/types': 4.3.1 + '@smithy/types': 4.6.0 tslib: 2.8.1 - '@smithy/service-error-classification@4.0.5': + '@smithy/service-error-classification@4.2.0': dependencies: - '@smithy/types': 4.3.1 + '@smithy/types': 4.6.0 - '@smithy/shared-ini-file-loader@4.0.4': + '@smithy/shared-ini-file-loader@4.3.0': dependencies: - '@smithy/types': 4.3.1 + '@smithy/types': 4.6.0 tslib: 2.8.1 - '@smithy/signature-v4@5.1.2': + '@smithy/signature-v4@5.3.0': dependencies: - '@smithy/is-array-buffer': 4.0.0 - '@smithy/protocol-http': 5.1.2 - '@smithy/types': 4.3.1 - '@smithy/util-hex-encoding': 4.0.0 - '@smithy/util-middleware': 4.0.4 - '@smithy/util-uri-escape': 4.0.0 - '@smithy/util-utf8': 4.0.0 + '@smithy/is-array-buffer': 4.2.0 + '@smithy/protocol-http': 5.3.0 + '@smithy/types': 4.6.0 + '@smithy/util-hex-encoding': 4.2.0 + '@smithy/util-middleware': 4.2.0 + '@smithy/util-uri-escape': 4.2.0 + '@smithy/util-utf8': 4.2.0 tslib: 2.8.1 - '@smithy/smithy-client@4.4.3': + '@smithy/smithy-client@4.7.1': dependencies: - '@smithy/core': 3.5.3 - '@smithy/middleware-endpoint': 4.1.11 - '@smithy/middleware-stack': 4.0.4 - '@smithy/protocol-http': 5.1.2 - '@smithy/types': 4.3.1 - '@smithy/util-stream': 4.2.2 + '@smithy/core': 3.15.0 + '@smithy/middleware-endpoint': 4.3.1 + '@smithy/middleware-stack': 4.2.0 + '@smithy/protocol-http': 5.3.0 + '@smithy/types': 4.6.0 + '@smithy/util-stream': 4.5.0 tslib: 2.8.1 '@smithy/types@2.12.0': dependencies: tslib: 2.8.1 - '@smithy/types@4.3.1': + '@smithy/types@4.6.0': dependencies: tslib: 2.8.1 - '@smithy/url-parser@4.0.4': + '@smithy/url-parser@4.2.0': dependencies: - '@smithy/querystring-parser': 4.0.4 - '@smithy/types': 4.3.1 + '@smithy/querystring-parser': 4.2.0 + '@smithy/types': 4.6.0 tslib: 2.8.1 - '@smithy/util-base64@4.0.0': + '@smithy/util-base64@4.3.0': dependencies: - '@smithy/util-buffer-from': 4.0.0 - '@smithy/util-utf8': 4.0.0 + '@smithy/util-buffer-from': 4.2.0 + '@smithy/util-utf8': 4.2.0 tslib: 2.8.1 - '@smithy/util-body-length-browser@4.0.0': + '@smithy/util-body-length-browser@4.2.0': dependencies: tslib: 2.8.1 - '@smithy/util-body-length-node@4.0.0': + '@smithy/util-body-length-node@4.2.1': dependencies: tslib: 2.8.1 @@ -14518,70 +15266,69 @@ snapshots: '@smithy/is-array-buffer': 2.2.0 tslib: 2.8.1 - '@smithy/util-buffer-from@4.0.0': + '@smithy/util-buffer-from@4.2.0': dependencies: - '@smithy/is-array-buffer': 4.0.0 + '@smithy/is-array-buffer': 4.2.0 tslib: 2.8.1 - '@smithy/util-config-provider@4.0.0': + '@smithy/util-config-provider@4.2.0': dependencies: tslib: 2.8.1 - '@smithy/util-defaults-mode-browser@4.0.19': + '@smithy/util-defaults-mode-browser@4.3.0': dependencies: - '@smithy/property-provider': 4.0.4 - '@smithy/smithy-client': 4.4.3 - '@smithy/types': 4.3.1 - bowser: 2.11.0 + '@smithy/property-provider': 4.2.0 + '@smithy/smithy-client': 4.7.1 + '@smithy/types': 4.6.0 tslib: 2.8.1 - '@smithy/util-defaults-mode-node@4.0.19': + '@smithy/util-defaults-mode-node@4.2.1': dependencies: - '@smithy/config-resolver': 4.1.4 - '@smithy/credential-provider-imds': 4.0.6 - '@smithy/node-config-provider': 4.1.3 - '@smithy/property-provider': 4.0.4 - '@smithy/smithy-client': 4.4.3 - '@smithy/types': 4.3.1 + '@smithy/config-resolver': 4.3.0 + '@smithy/credential-provider-imds': 4.2.0 + '@smithy/node-config-provider': 4.3.0 + '@smithy/property-provider': 4.2.0 + '@smithy/smithy-client': 4.7.1 + '@smithy/types': 4.6.0 tslib: 2.8.1 - '@smithy/util-endpoints@3.0.6': + '@smithy/util-endpoints@3.2.0': dependencies: - '@smithy/node-config-provider': 4.1.3 - '@smithy/types': 4.3.1 + '@smithy/node-config-provider': 4.3.0 + '@smithy/types': 4.6.0 tslib: 2.8.1 - '@smithy/util-hex-encoding@4.0.0': + '@smithy/util-hex-encoding@4.2.0': dependencies: tslib: 2.8.1 - '@smithy/util-middleware@4.0.4': + '@smithy/util-middleware@4.2.0': dependencies: - '@smithy/types': 4.3.1 + '@smithy/types': 4.6.0 tslib: 2.8.1 - '@smithy/util-retry@4.0.5': + '@smithy/util-retry@4.2.0': dependencies: - '@smithy/service-error-classification': 4.0.5 - '@smithy/types': 4.3.1 + '@smithy/service-error-classification': 4.2.0 + '@smithy/types': 4.6.0 tslib: 2.8.1 - '@smithy/util-stream@4.2.2': + '@smithy/util-stream@4.5.0': dependencies: - '@smithy/fetch-http-handler': 5.0.4 - '@smithy/node-http-handler': 4.0.6 - '@smithy/types': 4.3.1 - '@smithy/util-base64': 4.0.0 - '@smithy/util-buffer-from': 4.0.0 - '@smithy/util-hex-encoding': 4.0.0 - '@smithy/util-utf8': 4.0.0 + '@smithy/fetch-http-handler': 5.3.1 + '@smithy/node-http-handler': 4.3.0 + '@smithy/types': 4.6.0 + '@smithy/util-base64': 4.3.0 + '@smithy/util-buffer-from': 4.2.0 + '@smithy/util-hex-encoding': 4.2.0 + '@smithy/util-utf8': 4.2.0 tslib: 2.8.1 '@smithy/util-uri-escape@2.2.0': dependencies: tslib: 2.8.1 - '@smithy/util-uri-escape@4.0.0': + '@smithy/util-uri-escape@4.2.0': dependencies: tslib: 2.8.1 @@ -14590,179 +15337,167 @@ snapshots: '@smithy/util-buffer-from': 2.2.0 tslib: 2.8.1 - '@smithy/util-utf8@4.0.0': + '@smithy/util-utf8@4.2.0': dependencies: - '@smithy/util-buffer-from': 4.0.0 + '@smithy/util-buffer-from': 4.2.0 tslib: 2.8.1 - '@smithy/util-waiter@4.0.5': + '@smithy/util-waiter@4.2.0': + dependencies: + '@smithy/abort-controller': 4.2.0 + '@smithy/types': 4.6.0 + tslib: 2.8.1 + + '@smithy/uuid@1.1.0': dependencies: - '@smithy/abort-controller': 4.0.4 - '@smithy/types': 4.3.1 tslib: 2.8.1 '@sqltools/formatter@1.2.5': {} - '@storybook/addon-actions@8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5))': + '@standard-schema/spec@1.0.0': {} + + '@storybook/addon-actions@8.6.14(storybook@9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)))': dependencies: '@storybook/global': 5.0.0 '@types/uuid': 9.0.8 dequal: 2.0.3 - polished: 4.3.1 - storybook: 8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5) + polished: 4.2.2 + storybook: 9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)) uuid: 9.0.1 - '@storybook/addon-backgrounds@8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5))': + '@storybook/addon-backgrounds@8.6.14(storybook@9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)))': dependencies: '@storybook/global': 5.0.0 memoizerific: 1.11.3 - storybook: 8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5) + storybook: 9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)) ts-dedent: 2.2.0 - '@storybook/addon-controls@8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5))': + '@storybook/addon-controls@8.6.14(storybook@9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)))': dependencies: '@storybook/global': 5.0.0 dequal: 2.0.3 - storybook: 8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5) + storybook: 9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)) ts-dedent: 2.2.0 - '@storybook/addon-docs@8.6.12(@types/react@19.1.8)(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5))': + '@storybook/addon-docs@8.6.14(@types/react@18.0.28)(storybook@9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)))': dependencies: - '@mdx-js/react': 3.1.0(@types/react@19.1.8)(react@19.1.0) - '@storybook/blocks': 8.6.12(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5)) - '@storybook/csf-plugin': 8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5)) - '@storybook/react-dom-shim': 8.6.12(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5)) - react: 19.1.0 - react-dom: 19.1.0(react@19.1.0) - storybook: 8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5) + '@mdx-js/react': 3.0.1(@types/react@18.0.28)(react@19.2.0) + '@storybook/blocks': 8.6.14(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(storybook@9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6))) + '@storybook/csf-plugin': 8.6.14(storybook@9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6))) + '@storybook/react-dom-shim': 8.6.14(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(storybook@9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6))) + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) + storybook: 9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)) ts-dedent: 2.2.0 transitivePeerDependencies: - '@types/react' - '@storybook/addon-essentials@8.6.12(@types/react@19.1.8)(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5))': - dependencies: - '@storybook/addon-actions': 8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5)) - '@storybook/addon-backgrounds': 8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5)) - '@storybook/addon-controls': 8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5)) - '@storybook/addon-docs': 8.6.12(@types/react@19.1.8)(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5)) - '@storybook/addon-highlight': 8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5)) - '@storybook/addon-measure': 8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5)) - '@storybook/addon-outline': 8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5)) - '@storybook/addon-toolbars': 8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5)) - '@storybook/addon-viewport': 8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5)) - storybook: 8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5) + '@storybook/addon-essentials@8.6.14(@types/react@18.0.28)(storybook@9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)))': + dependencies: + '@storybook/addon-actions': 8.6.14(storybook@9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6))) + '@storybook/addon-backgrounds': 8.6.14(storybook@9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6))) + '@storybook/addon-controls': 8.6.14(storybook@9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6))) + '@storybook/addon-docs': 8.6.14(@types/react@18.0.28)(storybook@9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6))) + '@storybook/addon-highlight': 8.6.14(storybook@9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6))) + '@storybook/addon-measure': 8.6.14(storybook@9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6))) + '@storybook/addon-outline': 8.6.14(storybook@9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6))) + '@storybook/addon-toolbars': 8.6.14(storybook@9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6))) + '@storybook/addon-viewport': 8.6.14(storybook@9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6))) + storybook: 9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)) ts-dedent: 2.2.0 transitivePeerDependencies: - '@types/react' - '@storybook/addon-highlight@8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5))': + '@storybook/addon-highlight@8.6.14(storybook@9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)))': dependencies: '@storybook/global': 5.0.0 - storybook: 8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5) + storybook: 9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)) - '@storybook/addon-interactions@8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5))': + '@storybook/addon-interactions@8.6.14(storybook@9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)))': dependencies: '@storybook/global': 5.0.0 - '@storybook/instrumenter': 8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5)) - '@storybook/test': 8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5)) - polished: 4.3.1 - storybook: 8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5) + '@storybook/instrumenter': 8.6.14(storybook@9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6))) + '@storybook/test': 8.6.14(storybook@9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6))) + polished: 4.2.2 + storybook: 9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)) ts-dedent: 2.2.0 - '@storybook/addon-links@8.6.12(react@19.1.0)(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5))': + '@storybook/addon-links@9.1.10(react@19.2.0)(storybook@9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)))': dependencies: '@storybook/global': 5.0.0 - storybook: 8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5) - ts-dedent: 2.2.0 + storybook: 9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)) optionalDependencies: - react: 19.1.0 + react: 19.2.0 - '@storybook/addon-mdx-gfm@8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5))': + '@storybook/addon-mdx-gfm@8.6.14(storybook@9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)))': dependencies: - remark-gfm: 4.0.1 - storybook: 8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5) + remark-gfm: 4.0.0 + storybook: 9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)) ts-dedent: 2.2.0 transitivePeerDependencies: - supports-color - '@storybook/addon-measure@8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5))': + '@storybook/addon-measure@8.6.14(storybook@9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)))': dependencies: '@storybook/global': 5.0.0 - storybook: 8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5) + storybook: 9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)) tiny-invariant: 1.3.3 - '@storybook/addon-outline@8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5))': + '@storybook/addon-outline@8.6.14(storybook@9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)))': dependencies: '@storybook/global': 5.0.0 - storybook: 8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5) + storybook: 9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)) ts-dedent: 2.2.0 - '@storybook/addon-storysource@8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5))': + '@storybook/addon-storysource@8.6.14(storybook@9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)))': dependencies: - '@storybook/source-loader': 8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5)) + '@storybook/source-loader': 8.6.14(storybook@9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6))) estraverse: 5.3.0 - storybook: 8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5) + storybook: 9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)) tiny-invariant: 1.3.3 - '@storybook/addon-toolbars@8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5))': + '@storybook/addon-toolbars@8.6.14(storybook@9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)))': dependencies: - storybook: 8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5) + storybook: 9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)) - '@storybook/addon-viewport@8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5))': + '@storybook/addon-viewport@8.6.14(storybook@9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)))': dependencies: memoizerific: 1.11.3 - storybook: 8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5) + storybook: 9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)) - '@storybook/blocks@8.6.12(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5))': + '@storybook/blocks@8.6.14(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(storybook@9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)))': dependencies: - '@storybook/icons': 1.4.0(react-dom@19.1.0(react@19.1.0))(react@19.1.0) - storybook: 8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5) + '@storybook/icons': 1.2.12(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + storybook: 9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)) ts-dedent: 2.2.0 optionalDependencies: - react: 19.1.0 - react-dom: 19.1.0(react@19.1.0) + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) - '@storybook/builder-vite@8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5))(vite@6.3.4(@types/node@22.15.2)(sass@1.87.0)(terser@5.39.0)(tsx@4.19.3))': + '@storybook/builder-vite@9.1.10(storybook@9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)))(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6))': dependencies: - '@storybook/csf-plugin': 8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5)) - browser-assert: 1.2.1 - storybook: 8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5) + '@storybook/csf-plugin': 9.1.10(storybook@9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6))) + storybook: 9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)) ts-dedent: 2.2.0 - vite: 6.3.4(@types/node@22.15.2)(sass@1.87.0)(terser@5.39.0)(tsx@4.19.3) + vite: 7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6) - '@storybook/components@8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5))': + '@storybook/components@8.6.14(storybook@9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)))': dependencies: - storybook: 8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5) + storybook: 9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)) - '@storybook/core-events@8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5))': + '@storybook/core-events@8.6.14(storybook@9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)))': dependencies: - storybook: 8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5) + storybook: 9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)) - '@storybook/core@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5))(utf-8-validate@6.0.5)': + '@storybook/csf-plugin@8.6.14(storybook@9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)))': dependencies: - '@storybook/theming': 8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5)) - better-opn: 3.0.2 - browser-assert: 1.2.1 - esbuild: 0.25.3 - esbuild-register: 3.6.0(esbuild@0.25.3) - jsdoc-type-pratt-parser: 4.1.0 - process: 0.11.10 - recast: 0.23.11 - semver: 7.7.1 - util: 0.12.5 - ws: 8.18.1(bufferutil@4.0.9)(utf-8-validate@6.0.5) - optionalDependencies: - prettier: 3.5.3 - transitivePeerDependencies: - - bufferutil - - storybook - - supports-color - - utf-8-validate + storybook: 9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)) + unplugin: 1.5.1 - '@storybook/csf-plugin@8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5))': + '@storybook/csf-plugin@9.1.10(storybook@9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)))': dependencies: - storybook: 8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5) - unplugin: 1.16.1 + storybook: 9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)) + unplugin: 1.5.1 '@storybook/csf@0.0.1': dependencies: @@ -14770,146 +15505,139 @@ snapshots: '@storybook/global@5.0.0': {} - '@storybook/icons@1.4.0(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + '@storybook/icons@1.2.12(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': dependencies: - react: 19.1.0 - react-dom: 19.1.0(react@19.1.0) + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) - '@storybook/instrumenter@8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5))': + '@storybook/instrumenter@8.6.14(storybook@9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)))': dependencies: '@storybook/global': 5.0.0 - '@vitest/utils': 2.1.9 - storybook: 8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5) + '@vitest/utils': 2.1.1 + storybook: 9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)) - '@storybook/manager-api@8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5))': + '@storybook/manager-api@8.6.14(storybook@9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)))': dependencies: - storybook: 8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5) + storybook: 9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)) - '@storybook/preview-api@8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5))': + '@storybook/preview-api@8.6.14(storybook@9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)))': dependencies: - storybook: 8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5) + storybook: 9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)) - '@storybook/react-dom-shim@8.6.12(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5))': + '@storybook/react-dom-shim@8.6.14(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(storybook@9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)))': dependencies: - react: 19.1.0 - react-dom: 19.1.0(react@19.1.0) - storybook: 8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5) + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) + storybook: 9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)) - '@storybook/react-vite@8.6.12(@storybook/test@8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5)))(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(rollup@4.40.0)(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5))(typescript@5.8.3)(vite@6.3.4(@types/node@22.15.2)(sass@1.87.0)(terser@5.39.0)(tsx@4.19.3))': + '@storybook/react-dom-shim@9.1.10(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(storybook@9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)))': dependencies: - '@joshwooding/vite-plugin-react-docgen-typescript': 0.5.0(typescript@5.8.3)(vite@6.3.4(@types/node@22.15.2)(sass@1.87.0)(terser@5.39.0)(tsx@4.19.3)) - '@rollup/pluginutils': 5.1.4(rollup@4.40.0) - '@storybook/builder-vite': 8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5))(vite@6.3.4(@types/node@22.15.2)(sass@1.87.0)(terser@5.39.0)(tsx@4.19.3)) - '@storybook/react': 8.6.12(@storybook/test@8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5)))(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5))(typescript@5.8.3) - find-up: 5.0.0 - magic-string: 0.30.17 - react: 19.1.0 - react-docgen: 7.1.1 - react-dom: 19.1.0(react@19.1.0) - resolve: 1.22.10 - storybook: 8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5) + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) + storybook: 9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)) + + '@storybook/react-vite@9.1.10(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(rollup@4.52.4)(storybook@9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)))(typescript@5.9.3)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6))': + dependencies: + '@joshwooding/vite-plugin-react-docgen-typescript': 0.6.1(typescript@5.9.3)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)) + '@rollup/pluginutils': 5.3.0(rollup@4.52.4) + '@storybook/builder-vite': 9.1.10(storybook@9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)))(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)) + '@storybook/react': 9.1.10(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(storybook@9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)))(typescript@5.9.3) + find-up: 7.0.0 + magic-string: 0.30.19 + react: 19.2.0 + react-docgen: 8.0.2 + react-dom: 19.2.0(react@19.2.0) + resolve: 1.22.8 + storybook: 9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)) tsconfig-paths: 4.2.0 - vite: 6.3.4(@types/node@22.15.2)(sass@1.87.0)(terser@5.39.0)(tsx@4.19.3) - optionalDependencies: - '@storybook/test': 8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5)) + vite: 7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6) transitivePeerDependencies: - rollup - supports-color - typescript - '@storybook/react@8.6.12(@storybook/test@8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5)))(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5))(typescript@5.8.3)': + '@storybook/react@9.1.10(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(storybook@9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)))(typescript@5.9.3)': dependencies: - '@storybook/components': 8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5)) '@storybook/global': 5.0.0 - '@storybook/manager-api': 8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5)) - '@storybook/preview-api': 8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5)) - '@storybook/react-dom-shim': 8.6.12(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5)) - '@storybook/theming': 8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5)) - react: 19.1.0 - react-dom: 19.1.0(react@19.1.0) - storybook: 8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5) + '@storybook/react-dom-shim': 9.1.10(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(storybook@9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6))) + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) + storybook: 9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)) optionalDependencies: - '@storybook/test': 8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5)) - typescript: 5.8.3 + typescript: 5.9.3 - '@storybook/source-loader@8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5))': + '@storybook/source-loader@8.6.14(storybook@9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)))': dependencies: - es-toolkit: 1.39.3 + es-toolkit: 1.27.0 estraverse: 5.3.0 - prettier: 3.5.3 - storybook: 8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5) + prettier: 3.6.2 + storybook: 9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)) - '@storybook/test@8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5))': + '@storybook/test@8.6.14(storybook@9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)))': dependencies: '@storybook/global': 5.0.0 - '@storybook/instrumenter': 8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5)) + '@storybook/instrumenter': 8.6.14(storybook@9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6))) '@testing-library/dom': 10.4.0 '@testing-library/jest-dom': 6.5.0 '@testing-library/user-event': 14.5.2(@testing-library/dom@10.4.0) '@vitest/expect': 2.0.5 '@vitest/spy': 2.0.5 - storybook: 8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5) + storybook: 9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)) - '@storybook/theming@8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5))': + '@storybook/theming@8.6.14(storybook@9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)))': dependencies: - storybook: 8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5) + storybook: 9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)) - '@storybook/types@8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5))': + '@storybook/types@8.6.14(storybook@9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)))': dependencies: - storybook: 8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5) + storybook: 9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)) - '@storybook/vue3-vite@8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5))(vite@6.3.4(@types/node@22.15.2)(sass@1.87.0)(terser@5.39.0)(tsx@4.19.3))(vue@3.5.13(typescript@5.8.3))': + '@storybook/vue3-vite@9.1.10(storybook@9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)))(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6))(vue@3.5.22(typescript@5.9.3))': dependencies: - '@storybook/builder-vite': 8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5))(vite@6.3.4(@types/node@22.15.2)(sass@1.87.0)(terser@5.39.0)(tsx@4.19.3)) - '@storybook/vue3': 8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5))(vue@3.5.13(typescript@5.8.3)) + '@storybook/builder-vite': 9.1.10(storybook@9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)))(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)) + '@storybook/vue3': 9.1.10(storybook@9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)))(vue@3.5.22(typescript@5.9.3)) find-package-json: 1.2.0 - magic-string: 0.30.17 - storybook: 8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5) - typescript: 5.8.3 - vite: 6.3.4(@types/node@22.15.2)(sass@1.87.0)(terser@5.39.0)(tsx@4.19.3) - vue-component-meta: 2.2.10(typescript@5.8.3) - vue-docgen-api: 4.79.2(vue@3.5.13(typescript@5.8.3)) + magic-string: 0.30.19 + storybook: 9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)) + typescript: 5.9.3 + vite: 7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6) + vue-component-meta: 2.0.19(typescript@5.9.3) + vue-docgen-api: 4.76.0(vue@3.5.22(typescript@5.9.3)) transitivePeerDependencies: - vue - '@storybook/vue3@8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5))(vue@3.5.13(typescript@5.8.3))': + '@storybook/vue3@9.1.10(storybook@9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)))(vue@3.5.22(typescript@5.9.3))': dependencies: - '@storybook/components': 8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5)) '@storybook/global': 5.0.0 - '@storybook/manager-api': 8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5)) - '@storybook/preview-api': 8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5)) - '@storybook/theming': 8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5)) - '@vue/compiler-core': 3.5.13 - storybook: 8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5) - ts-dedent: 2.2.0 + storybook: 9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)) type-fest: 2.19.0 - vue: 3.5.13(typescript@5.8.3) - vue-component-type-helpers: 2.2.10 + vue: 3.5.22(typescript@5.9.3) + vue-component-type-helpers: 3.1.3 - '@stylistic/eslint-plugin@4.4.1(eslint@9.25.1)(typescript@5.8.3)': + '@stylistic/eslint-plugin@3.1.0(eslint@9.37.0)(typescript@5.9.3)': dependencies: - '@typescript-eslint/utils': 8.34.0(eslint@9.25.1)(typescript@5.8.3) - eslint: 9.25.1 + '@typescript-eslint/utils': 8.46.1(eslint@9.37.0)(typescript@5.9.3) + eslint: 9.37.0 eslint-visitor-keys: 4.2.1 espree: 10.4.0 estraverse: 5.3.0 - picomatch: 4.0.2 + picomatch: 4.0.3 transitivePeerDependencies: - supports-color - typescript - '@swc/cli@0.7.3(@swc/core@1.11.22)(chokidar@4.0.3)': + '@swc/cli@0.7.8(@swc/core@1.13.5)(chokidar@4.0.3)': dependencies: - '@swc/core': 1.11.22 + '@swc/core': 1.13.5 '@swc/counter': 0.1.3 '@xhmikosr/bin-wrapper': 13.0.5 commander: 8.3.0 - fast-glob: 3.3.3 - minimatch: 9.0.5 - piscina: 4.9.2 - semver: 7.7.1 + minimatch: 9.0.4 + piscina: 4.4.0 + semver: 7.7.3 slash: 3.0.0 source-map: 0.7.4 + tinyglobby: 0.2.13 optionalDependencies: chokidar: 4.0.3 @@ -14918,10 +15646,16 @@ snapshots: '@swc/wasm': 1.2.130 optional: true - '@swc/core-darwin-arm64@1.11.22': + '@swc/core-darwin-arm64@1.13.20': + optional: true + + '@swc/core-darwin-arm64@1.13.5': + optional: true + + '@swc/core-darwin-x64@1.13.20': optional: true - '@swc/core-darwin-x64@1.11.22': + '@swc/core-darwin-x64@1.13.5': optional: true '@swc/core-freebsd-x64@1.3.11': @@ -14929,82 +15663,113 @@ snapshots: '@swc/wasm': 1.2.130 optional: true - '@swc/core-linux-arm-gnueabihf@1.11.22': + '@swc/core-linux-arm-gnueabihf@1.13.20': + optional: true + + '@swc/core-linux-arm-gnueabihf@1.13.5': + optional: true + + '@swc/core-linux-arm64-gnu@1.13.20': + optional: true + + '@swc/core-linux-arm64-gnu@1.13.5': + optional: true + + '@swc/core-linux-arm64-musl@1.13.20': + optional: true + + '@swc/core-linux-arm64-musl@1.13.5': + optional: true + + '@swc/core-linux-x64-gnu@1.13.20': + optional: true + + '@swc/core-linux-x64-gnu@1.13.5': + optional: true + + '@swc/core-linux-x64-musl@1.13.20': optional: true - '@swc/core-linux-arm64-gnu@1.11.22': + '@swc/core-linux-x64-musl@1.13.5': optional: true - '@swc/core-linux-arm64-musl@1.11.22': + '@swc/core-win32-arm64-msvc@1.13.20': optional: true - '@swc/core-linux-x64-gnu@1.11.22': + '@swc/core-win32-arm64-msvc@1.13.5': optional: true - '@swc/core-linux-x64-musl@1.11.22': + '@swc/core-win32-ia32-msvc@1.13.20': optional: true - '@swc/core-win32-arm64-msvc@1.11.22': + '@swc/core-win32-ia32-msvc@1.13.5': optional: true - '@swc/core-win32-ia32-msvc@1.11.22': + '@swc/core-win32-x64-msvc@1.13.20': optional: true - '@swc/core-win32-x64-msvc@1.11.22': + '@swc/core-win32-x64-msvc@1.13.5': optional: true - '@swc/core@1.11.22': + '@swc/core@1.13.5': dependencies: '@swc/counter': 0.1.3 - '@swc/types': 0.1.23 + '@swc/types': 0.1.25 optionalDependencies: - '@swc/core-darwin-arm64': 1.11.22 - '@swc/core-darwin-x64': 1.11.22 - '@swc/core-linux-arm-gnueabihf': 1.11.22 - '@swc/core-linux-arm64-gnu': 1.11.22 - '@swc/core-linux-arm64-musl': 1.11.22 - '@swc/core-linux-x64-gnu': 1.11.22 - '@swc/core-linux-x64-musl': 1.11.22 - '@swc/core-win32-arm64-msvc': 1.11.22 - '@swc/core-win32-ia32-msvc': 1.11.22 - '@swc/core-win32-x64-msvc': 1.11.22 + '@swc/core-darwin-arm64': 1.13.5 + '@swc/core-darwin-x64': 1.13.5 + '@swc/core-linux-arm-gnueabihf': 1.13.5 + '@swc/core-linux-arm64-gnu': 1.13.5 + '@swc/core-linux-arm64-musl': 1.13.5 + '@swc/core-linux-x64-gnu': 1.13.5 + '@swc/core-linux-x64-musl': 1.13.5 + '@swc/core-win32-arm64-msvc': 1.13.5 + '@swc/core-win32-ia32-msvc': 1.13.5 + '@swc/core-win32-x64-msvc': 1.13.5 '@swc/counter@0.1.3': {} - '@swc/jest@0.2.38(@swc/core@1.11.22)': + '@swc/jest@0.2.39(@swc/core@1.13.5)': dependencies: - '@jest/create-cache-key-function': 29.7.0 - '@swc/core': 1.11.22 + '@jest/create-cache-key-function': 30.2.0 + '@swc/core': 1.13.5 '@swc/counter': 0.1.3 - jsonc-parser: 3.3.1 + jsonc-parser: 3.2.0 - '@swc/types@0.1.23': + '@swc/types@0.1.25': dependencies: '@swc/counter': 0.1.3 '@swc/wasm@1.2.130': optional: true - '@syuilo/aiscript@0.19.0': + '@syuilo/aiscript@0.19.0': + dependencies: + seedrandom: 3.0.5 + stringz: 2.1.0 + uuid: 9.0.1 + + '@syuilo/aiscript@1.1.2': dependencies: seedrandom: 3.0.5 stringz: 2.1.0 - uuid: 9.0.1 + uuid: 11.1.0 '@szmarczak/http-timer@5.0.1': dependencies: defer-to-connect: 2.0.1 - '@tabler/icons-webfont@3.31.0': + '@tabler/icons-webfont@3.35.0': dependencies: - '@tabler/icons': 3.31.0 + '@tabler/icons': 3.35.0 + sharp: 0.33.5 - '@tabler/icons@3.31.0': {} + '@tabler/icons@3.35.0': {} '@tensorflow/tfjs-backend-cpu@4.22.0(@tensorflow/tfjs-core@4.22.0(encoding@0.1.13))': dependencies: '@tensorflow/tfjs-core': 4.22.0(encoding@0.1.13) - '@types/seedrandom': 2.4.34 + '@types/seedrandom': 2.4.30 seedrandom: 3.0.5 '@tensorflow/tfjs-backend-webgl@4.22.0(@tensorflow/tfjs-core@4.22.0(encoding@0.1.13))': @@ -15012,7 +15777,7 @@ snapshots: '@tensorflow/tfjs-backend-cpu': 4.22.0(@tensorflow/tfjs-core@4.22.0(encoding@0.1.13)) '@tensorflow/tfjs-core': 4.22.0(encoding@0.1.13) '@types/offscreencanvas': 2019.3.0 - '@types/seedrandom': 2.4.34 + '@types/seedrandom': 2.4.30 seedrandom: 3.0.5 '@tensorflow/tfjs-converter@4.22.0(@tensorflow/tfjs-core@4.22.0(encoding@0.1.13))': @@ -15022,11 +15787,11 @@ snapshots: '@tensorflow/tfjs-core@4.22.0(encoding@0.1.13)': dependencies: '@types/long': 4.0.2 - '@types/offscreencanvas': 2019.7.3 - '@types/seedrandom': 2.4.34 + '@types/offscreencanvas': 2019.7.0 + '@types/seedrandom': 2.4.30 '@webgpu/types': 0.1.38 long: 4.0.0 - node-fetch: 2.6.13(encoding@0.1.13) + node-fetch: 2.6.11(encoding@0.1.13) seedrandom: 3.0.5 transitivePeerDependencies: - encoding @@ -15034,8 +15799,8 @@ snapshots: '@tensorflow/tfjs-data@4.22.0(@tensorflow/tfjs-core@4.22.0(encoding@0.1.13))(encoding@0.1.13)(seedrandom@3.0.5)': dependencies: '@tensorflow/tfjs-core': 4.22.0(encoding@0.1.13) - '@types/node-fetch': 2.6.12 - node-fetch: 2.6.13(encoding@0.1.13) + '@types/node-fetch': 2.6.2 + node-fetch: 2.6.11(encoding@0.1.13) seedrandom: 3.0.5 string_decoder: 1.3.0 transitivePeerDependencies: @@ -15049,8 +15814,8 @@ snapshots: dependencies: '@mapbox/node-pre-gyp': 1.0.9(encoding@0.1.13) '@tensorflow/tfjs': 4.22.0(encoding@0.1.13)(seedrandom@3.0.5) - adm-zip: 0.5.16 - google-protobuf: 3.21.4 + adm-zip: 0.5.10 + google-protobuf: 3.21.2 https-proxy-agent: 2.2.4 progress: 2.0.3 rimraf: 2.7.1 @@ -15080,9 +15845,9 @@ snapshots: '@testing-library/dom@10.4.0': dependencies: - '@babel/code-frame': 7.27.1 - '@babel/runtime': 7.27.6 - '@types/aria-query': 5.0.4 + '@babel/code-frame': 7.24.7 + '@babel/runtime': 7.27.0 + '@types/aria-query': 5.0.1 aria-query: 5.3.0 chalk: 4.1.2 dom-accessibility-api: 0.5.16 @@ -15091,9 +15856,9 @@ snapshots: '@testing-library/dom@9.3.4': dependencies: - '@babel/code-frame': 7.27.1 - '@babel/runtime': 7.27.6 - '@types/aria-query': 5.0.4 + '@babel/code-frame': 7.24.7 + '@babel/runtime': 7.23.4 + '@types/aria-query': 5.0.1 aria-query: 5.1.3 chalk: 4.1.2 dom-accessibility-api: 0.5.16 @@ -15102,30 +15867,45 @@ snapshots: '@testing-library/jest-dom@6.5.0': dependencies: - '@adobe/css-tools': 4.4.3 - aria-query: 5.3.2 + '@adobe/css-tools': 4.4.0 + aria-query: 5.3.0 chalk: 3.0.0 css.escape: 1.5.1 dom-accessibility-api: 0.6.3 lodash: 4.17.21 redent: 3.0.0 + '@testing-library/jest-dom@6.9.1': + dependencies: + '@adobe/css-tools': 4.4.0 + aria-query: 5.3.0 + css.escape: 1.5.1 + dom-accessibility-api: 0.6.3 + picocolors: 1.1.1 + redent: 3.0.0 + '@testing-library/user-event@14.5.2(@testing-library/dom@10.4.0)': dependencies: '@testing-library/dom': 10.4.0 - '@testing-library/vue@8.1.0(@vue/compiler-sfc@3.5.13)(vue@3.5.13(typescript@5.8.3))': + '@testing-library/user-event@14.6.1(@testing-library/dom@10.4.0)': dependencies: - '@babel/runtime': 7.27.6 + '@testing-library/dom': 10.4.0 + + '@testing-library/vue@8.1.0(@vue/compiler-sfc@3.5.22)(@vue/server-renderer@3.5.22(vue@3.5.22(typescript@5.9.3)))(vue@3.5.22(typescript@5.9.3))': + dependencies: + '@babel/runtime': 7.23.4 '@testing-library/dom': 9.3.4 - '@vue/test-utils': 2.4.6 - vue: 3.5.13(typescript@5.8.3) + '@vue/test-utils': 2.4.1(@vue/server-renderer@3.5.22(vue@3.5.22(typescript@5.9.3)))(vue@3.5.22(typescript@5.9.3)) + vue: 3.5.22(typescript@5.9.3) optionalDependencies: - '@vue/compiler-sfc': 3.5.13 + '@vue/compiler-sfc': 3.5.22 + transitivePeerDependencies: + - '@vue/server-renderer' '@tokenizer/inflate@0.2.7': dependencies: - debug: 4.4.1(supports-color@5.5.0) + debug: 4.4.3(supports-color@8.1.1) fflate: 0.8.2 token-types: 6.0.0 transitivePeerDependencies: @@ -15135,79 +15915,85 @@ snapshots: '@tootallnate/once@2.0.0': {} - '@trysound/sax@0.2.0': {} + '@tsd/typescript@5.9.3': {} - '@tsd/typescript@5.8.3': {} + '@twemoji/parser@16.0.0': {} - '@twemoji/parser@15.0.0': {} - - '@twemoji/parser@15.1.0': {} - - '@twemoji/parser@15.1.1': {} + '@twemoji/parser@17.0.0': {} '@types/accepts@1.3.7': dependencies: - '@types/node': 22.15.2 + '@types/node': 24.9.1 '@types/archiver@6.0.3': dependencies: - '@types/readdir-glob': 1.1.5 + '@types/readdir-glob': 1.1.1 '@types/argparse@1.0.38': {} - '@types/aria-query@5.0.4': {} + '@types/aria-query@5.0.1': {} - '@types/autosize@4.0.3': {} + '@types/autosize@4.0.1': {} + + '@types/babel__core@7.20.0': + dependencies: + '@babel/parser': 7.28.4 + '@babel/types': 7.28.4 + '@types/babel__generator': 7.6.4 + '@types/babel__template': 7.4.1 + '@types/babel__traverse': 7.28.0 '@types/babel__core@7.20.5': dependencies: - '@babel/parser': 7.27.5 - '@babel/types': 7.27.6 - '@types/babel__generator': 7.27.0 - '@types/babel__template': 7.4.4 - '@types/babel__traverse': 7.20.7 + '@babel/parser': 7.28.4 + '@babel/types': 7.28.4 + '@types/babel__generator': 7.6.4 + '@types/babel__template': 7.4.1 + '@types/babel__traverse': 7.28.0 - '@types/babel__generator@7.27.0': + '@types/babel__generator@7.6.4': dependencies: - '@babel/types': 7.27.6 + '@babel/types': 7.28.4 - '@types/babel__template@7.4.4': + '@types/babel__template@7.4.1': dependencies: - '@babel/parser': 7.27.5 - '@babel/types': 7.27.6 + '@babel/parser': 7.28.4 + '@babel/types': 7.28.4 - '@types/babel__traverse@7.20.7': + '@types/babel__traverse@7.28.0': dependencies: - '@babel/types': 7.27.6 + '@babel/types': 7.28.4 '@types/bcryptjs@2.4.6': {} - '@types/body-parser@1.19.5': + '@types/body-parser@1.19.6': dependencies: - '@types/connect': 3.4.38 - '@types/node': 22.15.2 + '@types/connect': 3.4.36 + '@types/node': 24.9.1 - '@types/braces@3.0.5': {} + '@types/braces@3.0.1': {} '@types/canvas-confetti@1.9.0': {} + '@types/chai@5.2.2': + dependencies: + '@types/deep-eql': 4.0.2 + '@types/color-convert@2.0.4': dependencies: - '@types/color-name': 1.1.5 + '@types/color-name': 1.1.1 - '@types/color-name@1.1.5': {} + '@types/color-name@1.1.1': {} '@types/connect@3.4.36': dependencies: - '@types/node': 22.15.2 + '@types/node': 24.9.1 '@types/connect@3.4.38': dependencies: - '@types/node': 22.15.2 + '@types/node': 24.9.1 - '@types/content-disposition@0.5.8': {} - - '@types/cookie@0.6.0': {} + '@types/content-disposition@0.5.9': {} '@types/cookiejar@2.1.5': {} @@ -15215,50 +16001,58 @@ snapshots: dependencies: '@types/ms': 0.7.34 - '@types/disposable-email-domains@1.0.6': {} + '@types/deep-eql@4.0.2': {} + + '@types/disposable-email-domains@1.0.2': {} '@types/dlv@1.1.5': {} '@types/doctrine@0.0.9': {} + '@types/dom-mediacapture-transform@0.1.11': + dependencies: + '@types/dom-webcodecs': 0.1.13 + + '@types/dom-webcodecs@0.1.13': {} + '@types/eslint@7.29.0': dependencies: - '@types/estree': 1.0.7 + '@types/estree': 1.0.8 '@types/json-schema': 7.0.15 - '@types/estree@1.0.7': {} + '@types/estree@1.0.8': {} - '@types/express-serve-static-core@5.0.6': + '@types/express-serve-static-core@4.17.33': dependencies: - '@types/node': 22.15.2 - '@types/qs': 6.14.0 - '@types/range-parser': 1.2.7 - '@types/send': 0.17.5 + '@types/node': 24.9.1 + '@types/qs': 6.9.7 + '@types/range-parser': 1.2.4 - '@types/express@5.0.3': + '@types/express@4.17.17': dependencies: - '@types/body-parser': 1.19.5 - '@types/express-serve-static-core': 5.0.6 - '@types/serve-static': 1.15.8 + '@types/body-parser': 1.19.6 + '@types/express-serve-static-core': 4.17.33 + '@types/qs': 6.9.7 + '@types/serve-static': 1.15.1 '@types/fluent-ffmpeg@2.1.27': dependencies: - '@types/node': 22.15.2 + '@types/node': 24.9.1 '@types/glob@8.1.0': dependencies: '@types/minimatch': 5.1.2 - '@types/node': 22.15.2 + '@types/node': 24.9.1 - '@types/graceful-fs@4.1.9': + '@types/graceful-fs@4.1.6': dependencies: - '@types/node': 22.15.2 + '@types/node': 24.9.1 '@types/hammerjs@2.0.46': {} '@types/hast@3.0.4': dependencies: - '@types/unist': 3.0.3 + '@types/unist': 3.0.2 '@types/htmlescape@1.1.3': {} @@ -15266,21 +16060,25 @@ snapshots: '@types/http-errors@1.8.2': {} - '@types/http-errors@2.0.5': {} - '@types/http-link-header@1.0.7': dependencies: - '@types/node': 22.15.2 + '@types/node': 24.9.1 + + '@types/istanbul-lib-coverage@2.0.4': {} '@types/istanbul-lib-coverage@2.0.6': {} - '@types/istanbul-lib-report@3.0.3': + '@types/istanbul-lib-report@3.0.0': dependencies: - '@types/istanbul-lib-coverage': 2.0.6 + '@types/istanbul-lib-coverage': 2.0.4 + + '@types/istanbul-reports@3.0.1': + dependencies: + '@types/istanbul-lib-report': 3.0.0 '@types/istanbul-reports@3.0.4': dependencies: - '@types/istanbul-lib-report': 3.0.3 + '@types/istanbul-lib-report': 3.0.0 '@types/jest@29.5.14': dependencies: @@ -15291,8 +16089,8 @@ snapshots: '@types/jsdom@21.1.7': dependencies: - '@types/node': 22.15.2 - '@types/tough-cookie': 4.0.5 + '@types/node': 24.9.1 + '@types/tough-cookie': 4.0.2 parse5: 7.3.0 '@types/json-schema@7.0.15': {} @@ -15303,59 +16101,66 @@ snapshots: '@types/jsrsasign@10.5.15': {} - '@types/linkify-it@5.0.0': {} + '@types/linkify-it@3.0.2': {} '@types/long@4.0.2': {} - '@types/markdown-it@14.1.2': + '@types/markdown-it@12.2.3': dependencies: - '@types/linkify-it': 5.0.0 - '@types/mdurl': 2.0.0 + '@types/linkify-it': 3.0.2 + '@types/mdurl': 1.0.2 - '@types/matter-js@0.19.8': {} + '@types/matter-js@0.20.2': {} - '@types/mdast@4.0.4': + '@types/mdast@4.0.3': dependencies: - '@types/unist': 3.0.3 + '@types/unist': 3.0.2 - '@types/mdurl@2.0.0': {} + '@types/mdurl@1.0.2': {} - '@types/mdx@2.0.13': {} + '@types/mdx@2.0.3': {} '@types/methods@1.1.4': {} '@types/micromatch@4.0.9': dependencies: - '@types/braces': 3.0.5 + '@types/braces': 3.0.1 '@types/mime-types@2.1.4': {} - '@types/mime@1.3.5': {} + '@types/mime@3.0.1': {} '@types/minimatch@5.1.2': {} - '@types/minimist@1.2.5': {} + '@types/minimist@1.2.2': {} '@types/ms@0.7.34': {} - '@types/mysql@2.15.26': + '@types/mysql@2.15.27': dependencies: - '@types/node': 22.15.2 + '@types/node': 24.9.1 - '@types/node-fetch@2.6.12': + '@types/node-fetch@2.6.2': dependencies: - '@types/node': 22.15.2 - form-data: 4.0.2 + '@types/node': 24.9.1 + form-data: 3.0.1 - '@types/node@22.15.2': + '@types/node@20.19.20': dependencies: undici-types: 6.21.0 - '@types/nodemailer@6.4.17': + '@types/node@24.9.1': + dependencies: + undici-types: 7.16.0 + + '@types/nodemailer@6.4.20': dependencies: - '@types/node': 22.15.2 + '@aws-sdk/client-ses': 3.908.0 + '@types/node': 24.9.1 + transitivePeerDependencies: + - aws-crt - '@types/normalize-package-data@2.4.4': {} + '@types/normalize-package-data@2.4.1': {} '@types/oauth2orize-pkce@0.1.2': dependencies: @@ -15363,90 +16168,84 @@ snapshots: '@types/oauth2orize@1.11.5': dependencies: - '@types/express': 5.0.3 - '@types/node': 22.15.2 + '@types/express': 4.17.17 + '@types/node': 24.9.1 '@types/oauth@0.9.6': dependencies: - '@types/node': 22.15.2 + '@types/node': 24.9.1 '@types/offscreencanvas@2019.3.0': {} - '@types/offscreencanvas@2019.7.3': {} + '@types/offscreencanvas@2019.7.0': {} '@types/pg-pool@2.0.6': dependencies: - '@types/pg': 8.11.14 - - '@types/pg@8.11.14': - dependencies: - '@types/node': 22.15.2 - pg-protocol: 1.10.0 - pg-types: 4.0.2 + '@types/pg': 8.15.5 - '@types/pg@8.6.1': + '@types/pg@8.15.5': dependencies: - '@types/node': 22.15.2 - pg-protocol: 1.10.0 + '@types/node': 24.9.1 + pg-protocol: 1.9.5 pg-types: 2.2.0 '@types/prismjs@1.26.5': {} + '@types/prop-types@15.7.5': {} + '@types/pug@2.0.10': {} '@types/punycode@2.1.4': {} '@types/qrcode@1.5.5': dependencies: - '@types/node': 22.15.2 + '@types/node': 24.9.1 - '@types/qs@6.14.0': {} + '@types/qs@6.9.7': {} '@types/random-seed@0.3.5': {} - '@types/range-parser@1.2.7': {} + '@types/range-parser@1.2.4': {} '@types/ratelimiter@3.4.6': {} - '@types/react@19.1.8': + '@types/react@18.0.28': dependencies: + '@types/prop-types': 15.7.5 + '@types/scheduler': 0.16.2 csstype: 3.1.3 - '@types/readdir-glob@1.1.5': + '@types/readdir-glob@1.1.1': dependencies: - '@types/node': 22.15.2 + '@types/node': 24.9.1 '@types/redis-info@3.0.3': {} '@types/rename@1.0.7': {} - '@types/resolve@1.20.6': {} + '@types/resolve@1.20.3': {} '@types/rimraf@3.0.2': dependencies: '@types/glob': 8.1.0 - '@types/node': 22.15.2 + '@types/node': 24.9.1 - '@types/sanitize-html@2.15.0': + '@types/sanitize-html@2.16.0': dependencies: - htmlparser2: 8.0.2 + htmlparser2: 8.0.1 - '@types/seedrandom@2.4.34': {} + '@types/scheduler@0.16.2': {} - '@types/seedrandom@3.0.8': {} + '@types/seedrandom@2.4.30': {} - '@types/semver@7.7.0': {} + '@types/seedrandom@3.0.8': {} - '@types/send@0.17.5': - dependencies: - '@types/mime': 1.3.5 - '@types/node': 22.15.2 + '@types/semver@7.7.1': {} - '@types/serve-static@1.15.8': + '@types/serve-static@1.15.1': dependencies: - '@types/http-errors': 2.0.5 - '@types/node': 22.15.2 - '@types/send': 0.17.5 + '@types/mime': 3.0.1 + '@types/node': 24.9.1 '@types/serviceworker@0.0.74': {} @@ -15454,7 +16253,7 @@ snapshots: '@types/simple-oauth2@5.0.7': {} - '@types/sinon@17.0.4': + '@types/sinon@17.0.3': dependencies: '@types/sinonjs__fake-timers': 8.1.5 @@ -15462,18 +16261,18 @@ snapshots: '@types/sinonjs__fake-timers@8.1.5': {} - '@types/sizzle@2.3.9': {} + '@types/sizzle@2.3.3': {} - '@types/stack-utils@2.0.3': {} + '@types/stack-utils@2.0.1': {} - '@types/statuses@2.0.6': {} + '@types/statuses@2.0.4': {} '@types/superagent@8.1.9': dependencies: '@types/cookiejar': 2.1.5 '@types/methods': 1.1.4 - '@types/node': 22.15.2 - form-data: 4.0.2 + '@types/node': 24.9.1 + form-data: 4.0.4 '@types/supertest@6.0.3': dependencies: @@ -15482,7 +16281,7 @@ snapshots: '@types/tedious@4.0.14': dependencies: - '@types/node': 22.15.2 + '@types/node': 24.9.1 '@types/throttle-debounce@5.0.2': {} @@ -15490,70 +16289,80 @@ snapshots: '@types/tmp@0.2.6': {} - '@types/tough-cookie@4.0.5': {} + '@types/tough-cookie@4.0.2': {} - '@types/unist@3.0.3': {} + '@types/unist@3.0.2': {} '@types/uuid@9.0.8': {} '@types/vary@1.1.3': dependencies: - '@types/node': 22.15.2 + '@types/node': 24.9.1 + + '@types/wawoff2@1.0.2': + dependencies: + '@types/node': 24.9.1 '@types/web-push@3.6.4': dependencies: - '@types/node': 22.15.2 + '@types/node': 24.9.1 + + '@types/whatwg-mimetype@3.0.2': {} '@types/ws@8.18.1': dependencies: - '@types/node': 22.15.2 + '@types/node': 24.9.1 + + '@types/yargs-parser@21.0.0': {} - '@types/yargs-parser@21.0.3': {} + '@types/yargs@17.0.19': + dependencies: + '@types/yargs-parser': 21.0.0 '@types/yargs@17.0.33': dependencies: - '@types/yargs-parser': 21.0.3 + '@types/yargs-parser': 21.0.0 - '@types/yauzl@2.10.3': + '@types/yauzl@2.10.0': dependencies: - '@types/node': 22.15.2 + '@types/node': 24.9.1 optional: true - '@typescript-eslint/eslint-plugin@8.31.0(@typescript-eslint/parser@8.31.0(eslint@9.25.1)(typescript@5.8.3))(eslint@9.25.1)(typescript@5.8.3)': + '@typescript-eslint/eslint-plugin@8.46.1(@typescript-eslint/parser@8.46.1(eslint@9.37.0)(typescript@5.9.3))(eslint@9.37.0)(typescript@5.9.3)': dependencies: '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 8.31.0(eslint@9.25.1)(typescript@5.8.3) - '@typescript-eslint/scope-manager': 8.31.0 - '@typescript-eslint/type-utils': 8.31.0(eslint@9.25.1)(typescript@5.8.3) - '@typescript-eslint/utils': 8.31.0(eslint@9.25.1)(typescript@5.8.3) - '@typescript-eslint/visitor-keys': 8.31.0 - eslint: 9.25.1 + '@typescript-eslint/parser': 8.46.1(eslint@9.37.0)(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.46.1 + '@typescript-eslint/type-utils': 8.46.1(eslint@9.37.0)(typescript@5.9.3) + '@typescript-eslint/utils': 8.46.1(eslint@9.37.0)(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.46.1 + eslint: 9.37.0 graphemer: 1.4.0 - ignore: 5.3.2 + ignore: 7.0.5 natural-compare: 1.4.0 - ts-api-utils: 2.1.0(typescript@5.8.3) - typescript: 5.8.3 + ts-api-utils: 2.1.0(typescript@5.9.3) + typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.31.0(eslint@9.25.1)(typescript@5.8.3)': + '@typescript-eslint/parser@8.46.1(eslint@9.37.0)(typescript@5.9.3)': dependencies: - '@typescript-eslint/scope-manager': 8.31.0 - '@typescript-eslint/types': 8.31.0 - '@typescript-eslint/typescript-estree': 8.31.0(typescript@5.8.3) - '@typescript-eslint/visitor-keys': 8.31.0 - debug: 4.4.1(supports-color@5.5.0) - eslint: 9.25.1 - typescript: 5.8.3 + '@typescript-eslint/scope-manager': 8.46.1 + '@typescript-eslint/types': 8.46.1 + '@typescript-eslint/typescript-estree': 8.46.1(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.46.1 + debug: 4.4.3(supports-color@8.1.1) + eslint: 9.37.0 + typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/project-service@8.34.0(typescript@5.8.3)': + '@typescript-eslint/project-service@8.46.1(typescript@5.9.3)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.34.0(typescript@5.8.3) - '@typescript-eslint/types': 8.34.0 - debug: 4.4.1(supports-color@5.5.0) - typescript: 5.8.3 + '@typescript-eslint/tsconfig-utils': 8.46.1(typescript@5.9.3) + '@typescript-eslint/types': 8.46.1 + debug: 4.4.3(supports-color@8.1.1) + typescript: 5.9.3 transitivePeerDependencies: - supports-color @@ -15562,115 +16371,84 @@ snapshots: '@typescript-eslint/types': 5.62.0 '@typescript-eslint/visitor-keys': 5.62.0 - '@typescript-eslint/scope-manager@8.31.0': - dependencies: - '@typescript-eslint/types': 8.31.0 - '@typescript-eslint/visitor-keys': 8.31.0 - - '@typescript-eslint/scope-manager@8.34.0': + '@typescript-eslint/scope-manager@8.46.1': dependencies: - '@typescript-eslint/types': 8.34.0 - '@typescript-eslint/visitor-keys': 8.34.0 + '@typescript-eslint/types': 8.46.1 + '@typescript-eslint/visitor-keys': 8.46.1 - '@typescript-eslint/tsconfig-utils@8.34.0(typescript@5.8.3)': + '@typescript-eslint/tsconfig-utils@8.46.1(typescript@5.9.3)': dependencies: - typescript: 5.8.3 + typescript: 5.9.3 - '@typescript-eslint/type-utils@8.31.0(eslint@9.25.1)(typescript@5.8.3)': + '@typescript-eslint/type-utils@8.46.1(eslint@9.37.0)(typescript@5.9.3)': dependencies: - '@typescript-eslint/typescript-estree': 8.31.0(typescript@5.8.3) - '@typescript-eslint/utils': 8.31.0(eslint@9.25.1)(typescript@5.8.3) - debug: 4.4.1(supports-color@5.5.0) - eslint: 9.25.1 - ts-api-utils: 2.1.0(typescript@5.8.3) - typescript: 5.8.3 + '@typescript-eslint/types': 8.46.1 + '@typescript-eslint/typescript-estree': 8.46.1(typescript@5.9.3) + '@typescript-eslint/utils': 8.46.1(eslint@9.37.0)(typescript@5.9.3) + debug: 4.4.3(supports-color@8.1.1) + eslint: 9.37.0 + ts-api-utils: 2.1.0(typescript@5.9.3) + typescript: 5.9.3 transitivePeerDependencies: - supports-color '@typescript-eslint/types@5.62.0': {} - '@typescript-eslint/types@8.31.0': {} - - '@typescript-eslint/types@8.34.0': {} + '@typescript-eslint/types@8.46.1': {} - '@typescript-eslint/typescript-estree@5.62.0(typescript@5.8.3)': + '@typescript-eslint/typescript-estree@5.62.0(typescript@5.9.3)': dependencies: '@typescript-eslint/types': 5.62.0 '@typescript-eslint/visitor-keys': 5.62.0 - debug: 4.4.1(supports-color@5.5.0) + debug: 4.4.3(supports-color@8.1.1) globby: 11.1.0 is-glob: 4.0.3 - semver: 7.7.1 - tsutils: 3.21.0(typescript@5.8.3) + semver: 7.7.3 + tsutils: 3.21.0(typescript@5.9.3) optionalDependencies: - typescript: 5.8.3 + typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/typescript-estree@8.31.0(typescript@5.8.3)': + '@typescript-eslint/typescript-estree@8.46.1(typescript@5.9.3)': dependencies: - '@typescript-eslint/types': 8.31.0 - '@typescript-eslint/visitor-keys': 8.31.0 - debug: 4.4.1(supports-color@5.5.0) + '@typescript-eslint/project-service': 8.46.1(typescript@5.9.3) + '@typescript-eslint/tsconfig-utils': 8.46.1(typescript@5.9.3) + '@typescript-eslint/types': 8.46.1 + '@typescript-eslint/visitor-keys': 8.46.1 + debug: 4.4.3(supports-color@8.1.1) fast-glob: 3.3.3 is-glob: 4.0.3 - minimatch: 9.0.5 - semver: 7.7.1 - ts-api-utils: 2.1.0(typescript@5.8.3) - typescript: 5.8.3 + minimatch: 9.0.4 + semver: 7.7.3 + ts-api-utils: 2.1.0(typescript@5.9.3) + typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/typescript-estree@8.34.0(typescript@5.8.3)': + '@typescript-eslint/utils@5.62.0(eslint@9.37.0)(typescript@5.9.3)': dependencies: - '@typescript-eslint/project-service': 8.34.0(typescript@5.8.3) - '@typescript-eslint/tsconfig-utils': 8.34.0(typescript@5.8.3) - '@typescript-eslint/types': 8.34.0 - '@typescript-eslint/visitor-keys': 8.34.0 - debug: 4.4.1(supports-color@5.5.0) - fast-glob: 3.3.3 - is-glob: 4.0.3 - minimatch: 9.0.5 - semver: 7.7.1 - ts-api-utils: 2.1.0(typescript@5.8.3) - typescript: 5.8.3 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/utils@5.62.0(eslint@9.25.1)(typescript@5.8.3)': - dependencies: - '@eslint-community/eslint-utils': 4.7.0(eslint@9.25.1) + '@eslint-community/eslint-utils': 4.9.0(eslint@9.37.0) '@types/json-schema': 7.0.15 - '@types/semver': 7.7.0 + '@types/semver': 7.7.1 '@typescript-eslint/scope-manager': 5.62.0 '@typescript-eslint/types': 5.62.0 - '@typescript-eslint/typescript-estree': 5.62.0(typescript@5.8.3) - eslint: 9.25.1 + '@typescript-eslint/typescript-estree': 5.62.0(typescript@5.9.3) + eslint: 9.37.0 eslint-scope: 5.1.1 - semver: 7.7.1 + semver: 7.7.3 transitivePeerDependencies: - supports-color - typescript - '@typescript-eslint/utils@8.31.0(eslint@9.25.1)(typescript@5.8.3)': - dependencies: - '@eslint-community/eslint-utils': 4.7.0(eslint@9.25.1) - '@typescript-eslint/scope-manager': 8.31.0 - '@typescript-eslint/types': 8.31.0 - '@typescript-eslint/typescript-estree': 8.31.0(typescript@5.8.3) - eslint: 9.25.1 - typescript: 5.8.3 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/utils@8.34.0(eslint@9.25.1)(typescript@5.8.3)': + '@typescript-eslint/utils@8.46.1(eslint@9.37.0)(typescript@5.9.3)': dependencies: - '@eslint-community/eslint-utils': 4.7.0(eslint@9.25.1) - '@typescript-eslint/scope-manager': 8.34.0 - '@typescript-eslint/types': 8.34.0 - '@typescript-eslint/typescript-estree': 8.34.0(typescript@5.8.3) - eslint: 9.25.1 - typescript: 5.8.3 + '@eslint-community/eslint-utils': 4.9.0(eslint@9.37.0) + '@typescript-eslint/scope-manager': 8.46.1 + '@typescript-eslint/types': 8.46.1 + '@typescript-eslint/typescript-estree': 8.46.1(typescript@5.9.3) + eslint: 9.37.0 + typescript: 5.9.3 transitivePeerDependencies: - supports-color @@ -15679,17 +16457,12 @@ snapshots: '@typescript-eslint/types': 5.62.0 eslint-visitor-keys: 3.4.3 - '@typescript-eslint/visitor-keys@8.31.0': - dependencies: - '@typescript-eslint/types': 8.31.0 - eslint-visitor-keys: 4.2.1 - - '@typescript-eslint/visitor-keys@8.34.0': + '@typescript-eslint/visitor-keys@8.46.1': dependencies: - '@typescript-eslint/types': 8.34.0 + '@typescript-eslint/types': 8.46.1 eslint-visitor-keys: 4.2.1 - '@ungap/structured-clone@1.3.0': {} + '@ungap/structured-clone@1.2.0': {} '@vitalets/google-translate-api@9.2.1(encoding@0.1.13)': dependencies: @@ -15699,26 +16472,28 @@ snapshots: transitivePeerDependencies: - encoding - '@vitejs/plugin-vue@5.2.3(vite@6.3.4(@types/node@22.15.2)(sass@1.87.0)(terser@5.39.0)(tsx@4.19.3))(vue@3.5.13(typescript@5.8.3))': + '@vitejs/plugin-vue@6.0.1(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6))(vue@3.5.22(typescript@5.9.3))': dependencies: - vite: 6.3.4(@types/node@22.15.2)(sass@1.87.0)(terser@5.39.0)(tsx@4.19.3) - vue: 3.5.13(typescript@5.8.3) + '@rolldown/pluginutils': 1.0.0-beta.29 + vite: 7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6) + vue: 3.5.22(typescript@5.9.3) - '@vitest/coverage-v8@3.1.2(vitest@3.1.2(@types/debug@4.1.12)(@types/node@22.15.2)(happy-dom@17.4.4)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(msw@2.7.5(@types/node@22.15.2)(typescript@5.8.3))(sass@1.87.0)(terser@5.39.0)(tsx@4.19.3))': + '@vitest/coverage-v8@3.2.4(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.9.1)(happy-dom@20.0.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6))': dependencies: '@ampproject/remapping': 2.3.0 '@bcoe/v8-coverage': 1.0.2 - debug: 4.4.1(supports-color@5.5.0) + ast-v8-to-istanbul: 0.3.5 + debug: 4.4.3(supports-color@8.1.1) istanbul-lib-coverage: 3.2.2 istanbul-lib-report: 3.0.1 istanbul-lib-source-maps: 5.0.6 istanbul-reports: 3.1.7 - magic-string: 0.30.17 + magic-string: 0.30.19 magicast: 0.3.5 std-env: 3.9.0 test-exclude: 7.0.1 tinyrainbow: 2.0.0 - vitest: 3.1.2(@types/debug@4.1.12)(@types/node@22.15.2)(happy-dom@17.4.4)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(msw@2.7.5(@types/node@22.15.2)(typescript@5.8.3))(sass@1.87.0)(terser@5.39.0)(tsx@4.19.3) + vitest: 3.2.4(@types/debug@4.1.12)(@types/node@24.9.1)(happy-dom@20.0.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6) transitivePeerDependencies: - supports-color @@ -15729,27 +16504,37 @@ snapshots: chai: 5.2.0 tinyrainbow: 1.2.0 - '@vitest/expect@3.1.2': + '@vitest/expect@3.2.4': dependencies: - '@vitest/spy': 3.1.2 - '@vitest/utils': 3.1.2 + '@types/chai': 5.2.2 + '@vitest/spy': 3.2.4 + '@vitest/utils': 3.2.4 chai: 5.2.0 tinyrainbow: 2.0.0 - '@vitest/mocker@3.1.2(msw@2.7.5(@types/node@22.15.2)(typescript@5.8.3))(vite@6.3.4(@types/node@22.15.2)(sass@1.87.0)(terser@5.39.0)(tsx@4.19.3))': + '@vitest/mocker@3.2.4(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(vite@7.1.7(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6))': + dependencies: + '@vitest/spy': 3.2.4 + estree-walker: 3.0.3 + magic-string: 0.30.19 + optionalDependencies: + msw: 2.11.5(@types/node@24.9.1)(typescript@5.9.3) + vite: 7.1.7(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6) + + '@vitest/mocker@3.2.4(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6))': dependencies: - '@vitest/spy': 3.1.2 + '@vitest/spy': 3.2.4 estree-walker: 3.0.3 - magic-string: 0.30.17 + magic-string: 0.30.19 optionalDependencies: - msw: 2.7.5(@types/node@22.15.2)(typescript@5.8.3) - vite: 6.3.4(@types/node@22.15.2)(sass@1.87.0)(terser@5.39.0)(tsx@4.19.3) + msw: 2.11.5(@types/node@24.9.1)(typescript@5.9.3) + vite: 7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6) '@vitest/pretty-format@2.0.5': dependencies: tinyrainbow: 1.2.0 - '@vitest/pretty-format@2.1.9': + '@vitest/pretty-format@2.1.1': dependencies: tinyrainbow: 1.2.0 @@ -15757,28 +16542,29 @@ snapshots: dependencies: tinyrainbow: 2.0.0 - '@vitest/pretty-format@3.2.3': + '@vitest/pretty-format@3.2.4': dependencies: tinyrainbow: 2.0.0 - '@vitest/runner@3.1.2': + '@vitest/runner@3.2.4': dependencies: - '@vitest/utils': 3.1.2 + '@vitest/utils': 3.2.4 pathe: 2.0.3 + strip-literal: 3.1.0 - '@vitest/snapshot@3.1.2': + '@vitest/snapshot@3.2.4': dependencies: - '@vitest/pretty-format': 3.1.2 - magic-string: 0.30.17 + '@vitest/pretty-format': 3.2.4 + magic-string: 0.30.19 pathe: 2.0.3 '@vitest/spy@2.0.5': dependencies: tinyspy: 3.0.2 - '@vitest/spy@3.1.2': + '@vitest/spy@3.2.4': dependencies: - tinyspy: 3.0.2 + tinyspy: 4.0.4 '@vitest/utils@2.0.5': dependencies: @@ -15787,9 +16573,9 @@ snapshots: loupe: 3.1.3 tinyrainbow: 1.2.0 - '@vitest/utils@2.1.9': + '@vitest/utils@2.1.1': dependencies: - '@vitest/pretty-format': 2.1.9 + '@vitest/pretty-format': 2.1.1 loupe: 3.1.3 tinyrainbow: 1.2.0 @@ -15799,109 +16585,122 @@ snapshots: loupe: 3.1.3 tinyrainbow: 2.0.0 - '@volar/language-core@2.4.14': + '@vitest/utils@3.2.4': + dependencies: + '@vitest/pretty-format': 3.2.4 + loupe: 3.2.1 + tinyrainbow: 2.0.0 + + '@volar/language-core@2.2.4': dependencies: - '@volar/source-map': 2.4.14 + '@volar/source-map': 2.2.4 - '@volar/source-map@2.4.14': {} + '@volar/language-core@2.4.23': + dependencies: + '@volar/source-map': 2.4.23 + + '@volar/source-map@2.2.4': + dependencies: + muggle-string: 0.4.1 - '@volar/typescript@2.4.14': + '@volar/source-map@2.4.23': {} + + '@volar/typescript@2.2.4': dependencies: - '@volar/language-core': 2.4.14 + '@volar/language-core': 2.2.4 path-browserify: 1.0.1 - vscode-uri: 3.1.0 - '@vue/compiler-core@3.5.13': + '@volar/typescript@2.4.23': dependencies: - '@babel/parser': 7.27.5 - '@vue/shared': 3.5.13 - entities: 4.5.0 - estree-walker: 2.0.2 - source-map-js: 1.2.1 + '@volar/language-core': 2.4.23 + path-browserify: 1.0.1 + vscode-uri: 3.0.8 - '@vue/compiler-core@3.5.16': + '@vue/compiler-core@3.5.22': dependencies: - '@babel/parser': 7.27.5 - '@vue/shared': 3.5.16 + '@babel/parser': 7.28.4 + '@vue/shared': 3.5.22 entities: 4.5.0 estree-walker: 2.0.2 source-map-js: 1.2.1 - '@vue/compiler-dom@3.5.13': - dependencies: - '@vue/compiler-core': 3.5.13 - '@vue/shared': 3.5.13 - - '@vue/compiler-dom@3.5.16': + '@vue/compiler-dom@3.5.22': dependencies: - '@vue/compiler-core': 3.5.16 - '@vue/shared': 3.5.16 + '@vue/compiler-core': 3.5.22 + '@vue/shared': 3.5.22 - '@vue/compiler-sfc@3.5.13': + '@vue/compiler-sfc@3.5.22': dependencies: - '@babel/parser': 7.27.5 - '@vue/compiler-core': 3.5.13 - '@vue/compiler-dom': 3.5.13 - '@vue/compiler-ssr': 3.5.13 - '@vue/shared': 3.5.13 + '@babel/parser': 7.28.4 + '@vue/compiler-core': 3.5.22 + '@vue/compiler-dom': 3.5.22 + '@vue/compiler-ssr': 3.5.22 + '@vue/shared': 3.5.22 estree-walker: 2.0.2 - magic-string: 0.30.17 - postcss: 8.5.3 + magic-string: 0.30.19 + postcss: 8.5.6 source-map-js: 1.2.1 - '@vue/compiler-ssr@3.5.13': + '@vue/compiler-ssr@3.5.22': dependencies: - '@vue/compiler-dom': 3.5.13 - '@vue/shared': 3.5.13 + '@vue/compiler-dom': 3.5.22 + '@vue/shared': 3.5.22 - '@vue/compiler-vue2@2.7.16': + '@vue/language-core@2.0.19(typescript@5.9.3)': dependencies: - de-indent: 1.0.2 - he: 1.2.0 + '@volar/language-core': 2.2.4 + '@vue/compiler-dom': 3.5.22 + '@vue/shared': 3.5.22 + computeds: 0.0.1 + minimatch: 9.0.4 + path-browserify: 1.0.1 + vue-template-compiler: 2.7.14 + optionalDependencies: + typescript: 5.9.3 - '@vue/language-core@2.2.10(typescript@5.8.3)': + '@vue/language-core@3.1.1(typescript@5.9.3)': dependencies: - '@volar/language-core': 2.4.14 - '@vue/compiler-dom': 3.5.16 - '@vue/compiler-vue2': 2.7.16 - '@vue/shared': 3.5.16 - alien-signals: 1.0.13 - minimatch: 9.0.5 + '@volar/language-core': 2.4.23 + '@vue/compiler-dom': 3.5.22 + '@vue/shared': 3.5.22 + alien-signals: 3.0.1 muggle-string: 0.4.1 path-browserify: 1.0.1 + picomatch: 4.0.3 optionalDependencies: - typescript: 5.8.3 + typescript: 5.9.3 - '@vue/reactivity@3.5.13': + '@vue/reactivity@3.5.22': dependencies: - '@vue/shared': 3.5.13 + '@vue/shared': 3.5.22 - '@vue/runtime-core@3.5.13': + '@vue/runtime-core@3.5.22': dependencies: - '@vue/reactivity': 3.5.13 - '@vue/shared': 3.5.13 + '@vue/reactivity': 3.5.22 + '@vue/shared': 3.5.22 - '@vue/runtime-dom@3.5.13': + '@vue/runtime-dom@3.5.22': dependencies: - '@vue/reactivity': 3.5.13 - '@vue/runtime-core': 3.5.13 - '@vue/shared': 3.5.13 + '@vue/reactivity': 3.5.22 + '@vue/runtime-core': 3.5.22 + '@vue/shared': 3.5.22 csstype: 3.1.3 - '@vue/server-renderer@3.5.13(vue@3.5.13(typescript@5.8.3))': + '@vue/server-renderer@3.5.22(vue@3.5.22(typescript@5.9.3))': dependencies: - '@vue/compiler-ssr': 3.5.13 - '@vue/shared': 3.5.13 - vue: 3.5.13(typescript@5.8.3) - - '@vue/shared@3.5.13': {} + '@vue/compiler-ssr': 3.5.22 + '@vue/shared': 3.5.22 + vue: 3.5.22(typescript@5.9.3) - '@vue/shared@3.5.16': {} + '@vue/shared@3.5.22': {} - '@vue/test-utils@2.4.6': + '@vue/test-utils@2.4.1(@vue/server-renderer@3.5.22(vue@3.5.22(typescript@5.9.3)))(vue@3.5.22(typescript@5.9.3))': dependencies: - js-beautify: 1.15.4 - vue-component-type-helpers: 2.2.10 + js-beautify: 1.14.9 + vue: 3.5.22(typescript@5.9.3) + vue-component-type-helpers: 1.8.4 + optionalDependencies: + '@vue/server-renderer': 3.5.22(vue@3.5.22(typescript@5.9.3)) '@webgpu/types@0.1.38': {} @@ -15973,10 +16772,9 @@ snapshots: dependencies: arch: 3.0.0 - abbrev@1.1.1: - optional: true + abbrev@1.1.1: {} - abbrev@2.0.0: {} + abbrev@3.0.1: {} abort-controller@3.0.0: dependencies: @@ -15989,13 +16787,9 @@ snapshots: mime-types: 2.1.35 negotiator: 0.6.3 - acorn-import-attributes@1.9.5(acorn@8.14.1): - dependencies: - acorn: 8.14.1 - - acorn-jsx@5.3.2(acorn@8.14.1): + acorn-import-attributes@1.9.5(acorn@8.15.0): dependencies: - acorn: 8.14.1 + acorn: 8.15.0 acorn-jsx@5.3.2(acorn@8.15.0): dependencies: @@ -16003,11 +16797,9 @@ snapshots: acorn@7.4.1: {} - acorn@8.14.1: {} - acorn@8.15.0: {} - adm-zip@0.5.16: + adm-zip@0.5.10: optional: true agent-base@4.3.0: @@ -16017,7 +16809,13 @@ snapshots: agent-base@6.0.2: dependencies: - debug: 4.4.1(supports-color@5.5.0) + debug: 4.4.3(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + + agent-base@7.1.0: + dependencies: + debug: 4.4.0(supports-color@5.5.0) transitivePeerDependencies: - supports-color @@ -16077,22 +16875,22 @@ snapshots: ajv@8.17.1: dependencies: fast-deep-equal: 3.1.3 - fast-uri: 3.0.6 + fast-uri: 3.0.1 json-schema-traverse: 1.0.0 require-from-string: 2.0.2 - alien-signals@1.0.13: {} + alien-signals@3.0.1: {} - analytics-utils@1.0.14(@types/dlv@1.1.5): + analytics-utils@1.1.1(@types/dlv@1.1.5): dependencies: - '@analytics/type-utils': 0.6.2 + '@analytics/type-utils': 0.6.4 '@types/dlv': 1.1.5 dlv: 1.1.3 - analytics@0.8.16(@types/dlv@1.1.5): + analytics@0.8.19(@types/dlv@1.1.5): dependencies: - '@analytics/core': 0.12.17(@types/dlv@1.1.5) - '@analytics/storage-utils': 0.4.2 + '@analytics/core': 0.13.2(@types/dlv@1.1.5) + '@analytics/storage-utils': 0.4.4 transitivePeerDependencies: - '@types/dlv' @@ -16104,7 +16902,11 @@ snapshots: ansi-regex@5.0.1: {} - ansi-regex@6.1.0: {} + ansi-regex@6.0.1: {} + + ansi-styles@3.2.1: + dependencies: + color-convert: 1.9.3 ansi-styles@4.3.0: dependencies: @@ -16142,22 +16944,22 @@ snapshots: lazystream: 1.0.1 lodash: 4.17.21 normalize-path: 3.0.0 - readable-stream: 4.7.0 + readable-stream: 4.3.0 archiver@7.0.1: dependencies: archiver-utils: 5.0.2 - async: 3.2.6 + async: 3.2.4 buffer-crc32: 1.0.0 - readable-stream: 4.7.0 - readdir-glob: 1.1.3 - tar-stream: 3.1.7 + readable-stream: 4.3.0 + readdir-glob: 1.1.2 + tar-stream: 3.1.6 zip-stream: 6.0.1 are-we-there-yet@2.0.0: dependencies: delegates: 1.0.0 - readable-stream: 3.6.2 + readable-stream: 3.6.0 optional: true arg@5.0.2: {} @@ -16165,8 +16967,8 @@ snapshots: argon2@0.40.3: dependencies: '@phc/format': 1.0.0 - node-addon-api: 8.4.0 - node-gyp-build: 4.8.4 + node-addon-api: 8.2.0 + node-gyp-build: 4.8.2 argparse@1.0.10: dependencies: @@ -16176,13 +16978,16 @@ snapshots: aria-query@5.1.3: dependencies: - deep-equal: 2.2.3 + deep-equal: 2.2.0 aria-query@5.3.0: dependencies: dequal: 2.0.3 - aria-query@5.3.2: {} + array-buffer-byte-length@1.0.1: + dependencies: + call-bind: 1.0.7 + is-array-buffer: 3.0.4 array-buffer-byte-length@1.0.2: dependencies: @@ -16219,14 +17024,25 @@ snapshots: call-bind: 1.0.8 define-properties: 1.2.1 es-abstract: 1.24.0 - es-shim-unscopables: 1.1.0 + es-shim-unscopables: 1.0.2 array.prototype.flatmap@1.3.3: dependencies: call-bind: 1.0.8 define-properties: 1.2.1 es-abstract: 1.24.0 - es-shim-unscopables: 1.1.0 + es-shim-unscopables: 1.0.2 + + arraybuffer.prototype.slice@1.0.3: + dependencies: + array-buffer-byte-length: 1.0.1 + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + is-array-buffer: 3.0.4 + is-shared-array-buffer: 1.0.3 arraybuffer.prototype.slice@1.0.4: dependencies: @@ -16246,7 +17062,7 @@ snapshots: asn1.js@5.4.1: dependencies: - bn.js: 4.12.2 + bn.js: 4.12.0 inherits: 2.0.4 minimalistic-assert: 1.0.1 safer-buffer: 2.1.2 @@ -16255,13 +17071,13 @@ snapshots: dependencies: safer-buffer: 2.1.2 - asn1js@3.0.6: + asn1js@3.0.5: dependencies: - pvtsutils: 1.3.6 + pvtsutils: 1.3.5 pvutils: 1.1.3 tslib: 2.8.1 - assert-never@1.4.0: {} + assert-never@1.2.1: {} assert-plus@1.0.0: {} @@ -16271,6 +17087,12 @@ snapshots: dependencies: tslib: 2.8.1 + ast-v8-to-istanbul@0.3.5: + dependencies: + '@jridgewell/trace-mapping': 0.3.31 + estree-walker: 3.0.3 + js-tokens: 9.0.1 + astral-regex@2.0.0: {} astring@1.9.0: {} @@ -16279,11 +17101,11 @@ snapshots: async-mutex@0.5.0: dependencies: - tslib: 2.8.1 + tslib: 2.6.2 async@0.2.10: {} - async@3.2.6: {} + async@3.2.4: {} asynckit@0.4.0: {} @@ -16295,46 +17117,46 @@ snapshots: available-typed-arrays@1.0.7: dependencies: - possible-typed-array-names: 1.1.0 + possible-typed-array-names: 1.0.0 - avvio@9.1.0: + avvio@9.0.0: dependencies: - '@fastify/error': 4.2.0 - fastq: 1.19.1 + '@fastify/error': 4.0.0 + fastq: 1.17.1 aws-sdk-client-mock@4.1.0: dependencies: - '@types/sinon': 17.0.4 + '@types/sinon': 17.0.3 sinon: 18.0.1 - tslib: 2.8.1 + tslib: 2.7.0 aws-sign2@0.7.0: {} - aws4@1.13.2: {} + aws4@1.12.0: {} axios@0.24.0: dependencies: - follow-redirects: 1.15.9(debug@4.4.0) + follow-redirects: 1.15.2 transitivePeerDependencies: - debug - axios@1.10.0(debug@4.4.0): + axios@1.12.2(debug@4.4.3): dependencies: - follow-redirects: 1.15.9(debug@4.4.0) - form-data: 4.0.2 + follow-redirects: 1.15.9(debug@4.4.3) + form-data: 4.0.4 proxy-from-env: 1.1.0 transitivePeerDependencies: - debug - b4a@1.6.7: {} + b4a@1.6.4: {} - babel-jest@29.7.0(@babel/core@7.27.4): + babel-jest@29.7.0(@babel/core@7.24.9): dependencies: - '@babel/core': 7.27.4 + '@babel/core': 7.24.9 '@jest/transform': 29.7.0 - '@types/babel__core': 7.20.5 + '@types/babel__core': 7.20.0 babel-plugin-istanbul: 6.1.1 - babel-preset-jest: 29.6.3(@babel/core@7.27.4) + babel-preset-jest: 29.6.3(@babel/core@7.24.9) chalk: 4.1.2 graceful-fs: 4.2.11 slash: 3.0.0 @@ -16343,7 +17165,7 @@ snapshots: babel-plugin-istanbul@6.1.1: dependencies: - '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-plugin-utils': 7.22.5 '@istanbuljs/load-nyc-config': 1.1.0 '@istanbuljs/schema': 0.1.3 istanbul-lib-instrument: 5.2.1 @@ -16354,48 +17176,60 @@ snapshots: babel-plugin-jest-hoist@29.6.3: dependencies: '@babel/template': 7.27.2 - '@babel/types': 7.27.6 + '@babel/types': 7.28.4 '@types/babel__core': 7.20.5 - '@types/babel__traverse': 7.20.7 - - babel-preset-current-node-syntax@1.1.0(@babel/core@7.27.4): - dependencies: - '@babel/core': 7.27.4 - '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.27.4) - '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.27.4) - '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.27.4) - '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.27.4) - '@babel/plugin-syntax-import-attributes': 7.27.1(@babel/core@7.27.4) - '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.27.4) - '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.27.4) - '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.27.4) - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.27.4) - '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.27.4) - '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.27.4) - '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.27.4) - '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.27.4) - '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.27.4) - '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.27.4) - - babel-preset-jest@29.6.3(@babel/core@7.27.4): - dependencies: - '@babel/core': 7.27.4 + '@types/babel__traverse': 7.28.0 + + babel-preset-current-node-syntax@1.0.1(@babel/core@7.24.9): + dependencies: + '@babel/core': 7.24.9 + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.24.9) + '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.24.9) + '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.24.9) + '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.24.9) + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.24.9) + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.24.9) + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.24.9) + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.24.9) + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.24.9) + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.24.9) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.24.9) + '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.24.9) + + babel-preset-current-node-syntax@1.0.1(@babel/core@7.28.4): + dependencies: + '@babel/core': 7.28.4 + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.28.4) + '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.28.4) + '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.28.4) + '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.28.4) + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.28.4) + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.28.4) + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.28.4) + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.28.4) + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.28.4) + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.28.4) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.28.4) + '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.28.4) + + babel-preset-jest@29.6.3(@babel/core@7.24.9): + dependencies: + '@babel/core': 7.24.9 babel-plugin-jest-hoist: 29.6.3 - babel-preset-current-node-syntax: 1.1.0(@babel/core@7.27.4) + babel-preset-current-node-syntax: 1.0.1(@babel/core@7.24.9) babel-walk@3.0.0-canary-5: dependencies: - '@babel/types': 7.27.6 + '@babel/types': 7.28.4 bail@2.0.2: {} balanced-match@1.0.2: {} - bare-events@2.5.4: - optional: true - base64-js@1.5.1: {} + baseline-browser-mapping@2.8.16: {} + bcrypt-pbkdf@1.0.2: dependencies: tweetnacl: 0.14.5 @@ -16406,12 +17240,12 @@ snapshots: dependencies: open: 8.4.2 - bignumber.js@9.3.0: {} + bignumber.js@9.1.1: {} bin-version-check@5.1.0: dependencies: bin-version: 6.0.0 - semver: 7.7.1 + semver: 7.7.3 semver-truncate: 3.0.0 bin-version@6.0.0: @@ -16425,7 +17259,7 @@ snapshots: blurhash@2.0.5: {} - bn.js@4.12.2: {} + bn.js@4.12.0: {} body-parser@1.20.3: dependencies: @@ -16448,12 +17282,12 @@ snapshots: bowser@2.11.0: {} - brace-expansion@1.1.12: + brace-expansion@1.1.11: dependencies: balanced-match: 1.0.2 concat-map: 0.0.1 - brace-expansion@2.0.2: + brace-expansion@2.0.1: dependencies: balanced-match: 1.0.2 @@ -16468,14 +17302,20 @@ snapshots: p-queue: 6.6.2 unload: 2.4.1 - browser-assert@1.2.1: {} - - browserslist@4.25.0: + browserslist@4.24.4: dependencies: - caniuse-lite: 1.0.30001723 - electron-to-chromium: 1.5.167 + caniuse-lite: 1.0.30001699 + electron-to-chromium: 1.5.101 node-releases: 2.0.19 - update-browserslist-db: 1.1.3(browserslist@4.25.0) + update-browserslist-db: 1.1.2(browserslist@4.24.4) + + browserslist@4.26.3: + dependencies: + baseline-browser-mapping: 2.8.16 + caniuse-lite: 1.0.30001749 + electron-to-chromium: 1.5.234 + node-releases: 2.0.23 + update-browserslist-db: 1.1.3(browserslist@4.26.3) bser@2.1.1: dependencies: @@ -16506,18 +17346,18 @@ snapshots: bufferutil@4.0.9: dependencies: - node-gyp-build: 4.8.4 + node-gyp-build: 4.8.2 optional: true - bullmq@5.51.1: + bullmq@5.61.0: dependencies: cron-parser: 4.9.0 - ioredis: 5.6.1 - msgpackr: 1.11.4 + ioredis: 5.8.1 + msgpackr: 1.11.2 node-abort-controller: 3.1.1 - semver: 7.7.1 + semver: 7.7.3 tslib: 2.8.1 - uuid: 9.0.1 + uuid: 11.1.0 transitivePeerDependencies: - supports-color @@ -16531,20 +17371,20 @@ snapshots: cac@6.7.14: {} - cacache@18.0.4: + cacache@19.0.1: dependencies: - '@npmcli/fs': 3.1.1 - fs-minipass: 3.0.3 + '@npmcli/fs': 4.0.0 + fs-minipass: 3.0.2 glob: 10.4.5 lru-cache: 10.4.3 minipass: 7.1.2 minipass-collect: 2.0.1 minipass-flush: 1.0.5 minipass-pipeline: 1.2.4 - p-map: 4.0.0 - ssri: 10.0.6 - tar: 6.2.1 - unique-filename: 3.0.0 + p-map: 7.0.3 + ssri: 12.0.0 + tar: 7.5.1 + unique-filename: 4.0.0 cacheable-lookup@7.0.0: {} @@ -16552,29 +17392,37 @@ snapshots: dependencies: '@types/http-cache-semantics': 4.0.4 get-stream: 6.0.1 - http-cache-semantics: 4.2.0 + http-cache-semantics: 4.1.1 keyv: 4.5.4 mimic-response: 4.0.0 - normalize-url: 8.0.2 + normalize-url: 8.0.1 responselike: 3.0.0 - cacheable-request@12.0.1: + cacheable-request@13.0.12: dependencies: '@types/http-cache-semantics': 4.0.4 get-stream: 9.0.1 http-cache-semantics: 4.2.0 - keyv: 4.5.4 + keyv: 5.5.3 mimic-response: 4.0.0 - normalize-url: 8.0.2 + normalize-url: 8.1.0 responselike: 3.0.0 - cachedir@2.4.0: {} + cachedir@2.3.0: {} call-bind-apply-helpers@1.0.2: dependencies: es-errors: 1.3.0 function-bind: 1.1.2 + call-bind@1.0.7: + dependencies: + es-define-property: 1.0.1 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.3.0 + set-function-length: 1.2.2 + call-bind@1.0.8: dependencies: call-bind-apply-helpers: 1.0.2 @@ -16587,8 +17435,6 @@ snapshots: call-bind-apply-helpers: 1.0.2 get-intrinsic: 1.3.0 - call-me-maybe@1.0.2: {} - callsites@3.1.0: {} camelcase-keys@6.2.2: @@ -16603,12 +17449,14 @@ snapshots: caniuse-api@3.0.0: dependencies: - browserslist: 4.25.0 - caniuse-lite: 1.0.30001723 + browserslist: 4.26.3 + caniuse-lite: 1.0.30001699 lodash.memoize: 4.1.2 lodash.uniq: 4.5.0 - caniuse-lite@1.0.30001723: {} + caniuse-lite@1.0.30001699: {} + + caniuse-lite@1.0.30001749: {} canonicalize@1.0.8: {} @@ -16634,9 +17482,15 @@ snapshots: loupe: 3.1.3 pathval: 2.0.0 - chalk-template@1.1.0: + chalk-template@1.1.2: + dependencies: + chalk: 5.6.2 + + chalk@2.4.2: dependencies: - chalk: 5.4.1 + ansi-styles: 3.2.1 + escape-string-regexp: 1.0.5 + supports-color: 5.5.0 chalk@3.0.0: dependencies: @@ -16648,7 +17502,9 @@ snapshots: ansi-styles: 4.3.0 supports-color: 7.2.0 - chalk@5.4.1: {} + chalk@5.6.2: {} + + change-case@5.4.4: {} char-regex@1.0.2: {} @@ -16660,29 +17516,29 @@ snapshots: character-parser@2.2.0: dependencies: - is-regex: 1.2.1 + is-regex: 1.1.4 - chart.js@4.4.9: + chart.js@4.5.1: dependencies: - '@kurkle/color': 0.3.4 + '@kurkle/color': 0.3.2 - chartjs-adapter-date-fns@3.0.0(chart.js@4.4.9)(date-fns@4.1.0): + chartjs-adapter-date-fns@3.0.0(chart.js@4.5.1)(date-fns@4.1.0): dependencies: - chart.js: 4.4.9 + chart.js: 4.5.1 date-fns: 4.1.0 - chartjs-chart-matrix@2.1.1(chart.js@4.4.9): + chartjs-chart-matrix@3.0.0(chart.js@4.5.1): dependencies: - chart.js: 4.4.9 + chart.js: 4.5.1 - chartjs-plugin-gradient@0.6.1(chart.js@4.4.9): + chartjs-plugin-gradient@0.6.1(chart.js@4.5.1): dependencies: - chart.js: 4.4.9 + chart.js: 4.5.1 - chartjs-plugin-zoom@2.2.0(chart.js@4.4.9): + chartjs-plugin-zoom@2.2.0(chart.js@4.5.1): dependencies: '@types/hammerjs': 2.0.46 - chart.js: 4.4.9 + chart.js: 4.5.1 hammerjs: 2.0.8 check-error@2.1.1: {} @@ -16704,15 +17560,15 @@ snapshots: dom-serializer: 2.0.0 domhandler: 5.0.3 domutils: 3.2.2 - encoding-sniffer: 0.2.1 + encoding-sniffer: 0.2.0 htmlparser2: 9.1.0 parse5: 7.3.0 parse5-htmlparser2-tree-adapter: 7.1.0 parse5-parser-stream: 7.1.2 - undici: 6.21.3 + undici: 6.19.8 whatwg-mimetype: 4.0.0 - cheerio@1.1.0: + cheerio@1.1.2: dependencies: cheerio-select: 2.1.0 dom-serializer: 2.0.0 @@ -16723,24 +17579,25 @@ snapshots: parse5: 7.3.0 parse5-htmlparser2-tree-adapter: 7.1.0 parse5-parser-stream: 7.1.2 - undici: 7.10.0 + undici: 7.16.0 whatwg-mimetype: 4.0.0 chokidar@4.0.3: dependencies: readdirp: 4.1.2 - chownr@2.0.0: {} + chownr@2.0.0: + optional: true chownr@3.0.0: {} - chromatic@11.28.2: {} + chromatic@13.3.0: {} - ci-info@3.9.0: {} + ci-info@3.7.1: {} - ci-info@4.2.0: {} + ci-info@4.1.0: {} - cjs-module-lexer@1.4.3: {} + cjs-module-lexer@1.2.2: {} clean-stack@2.2.0: {} @@ -16761,11 +17618,11 @@ snapshots: parse5-htmlparser2-tree-adapter: 6.0.1 yargs: 16.2.0 - cli-table3@0.6.5: + cli-table3@0.6.1: dependencies: string-width: 4.2.3 optionalDependencies: - '@colors/colors': 1.5.0 + colors: 1.4.0 cli-truncate@2.1.0: dependencies: @@ -16796,12 +17653,18 @@ snapshots: co@4.6.0: {} - collect-v8-coverage@1.0.2: {} + collect-v8-coverage@1.0.1: {} + + color-convert@1.9.3: + dependencies: + color-name: 1.1.3 color-convert@2.0.1: dependencies: color-name: 1.1.4 + color-name@1.1.3: {} + color-name@1.1.4: {} color-string@1.9.1: @@ -16819,7 +17682,12 @@ snapshots: colord@2.9.3: {} - colorette@2.0.20: {} + colorette@1.4.0: {} + + colorette@2.0.19: {} + + colors@1.4.0: + optional: true combined-stream@1.0.8: dependencies: @@ -16829,14 +17697,14 @@ snapshots: commander@10.0.1: {} + commander@11.1.0: {} + commander@12.1.0: {} commander@2.20.3: {} commander@6.2.1: {} - commander@7.2.0: {} - commander@8.3.0: {} commander@9.5.0: {} @@ -16845,7 +17713,7 @@ snapshots: compare-versions@6.1.1: {} - complex.js@2.4.2: {} + complex.js@2.1.1: {} component-emitter@1.3.1: {} @@ -16855,15 +17723,17 @@ snapshots: crc32-stream: 6.0.0 is-stream: 2.0.1 normalize-path: 3.0.0 - readable-stream: 4.7.0 + readable-stream: 4.3.0 + + computeds@0.0.1: {} concat-map@0.0.1: {} - concat-stream@1.6.2: + concat-stream@2.0.0: dependencies: buffer-from: 1.1.2 inherits: 2.0.4 - readable-stream: 2.3.8 + readable-stream: 3.6.0 typedarray: 0.0.6 config-chain@1.1.13: @@ -16871,15 +17741,15 @@ snapshots: ini: 1.3.8 proto-list: 1.2.4 - consola@3.4.2: {} + consola@3.4.0: {} console-control-strings@1.1.0: optional: true constantinople@4.0.1: dependencies: - '@babel/parser': 7.27.5 - '@babel/types': 7.27.6 + '@babel/parser': 7.28.4 + '@babel/types': 7.28.4 content-disposition@0.5.4: dependencies: @@ -16887,13 +17757,17 @@ snapshots: content-type@1.0.5: {} + convert-source-map@1.9.0: {} + convert-source-map@2.0.0: {} cookie-signature@1.0.6: {} + cookie@0.6.0: {} + cookie@0.7.1: {} - cookie@0.7.2: {} + cookie@1.0.1: {} cookie@1.0.2: {} @@ -16915,15 +17789,15 @@ snapshots: crc32-stream@6.0.0: dependencies: crc-32: 1.2.2 - readable-stream: 4.7.0 + readable-stream: 4.3.0 - create-jest@29.7.0(@types/node@22.15.2): + create-jest@29.7.0(@types/node@24.9.1): dependencies: '@jest/types': 29.6.3 chalk: 4.1.2 exit: 0.1.2 graceful-fs: 4.2.11 - jest-config: 29.7.0(@types/node@22.15.2) + jest-config: 29.7.0(@types/node@24.9.1) jest-util: 29.7.0 prompts: 2.4.2 transitivePeerDependencies: @@ -16934,38 +17808,43 @@ snapshots: cron-parser@4.9.0: dependencies: - luxon: 3.6.1 + luxon: 3.3.0 - cropperjs@2.0.0: + cropperjs@2.0.1: dependencies: - '@cropper/elements': 2.0.0 - '@cropper/utils': 2.0.0 + '@cropper/elements': 2.0.1 + '@cropper/utils': 2.0.1 - cross-env@7.0.3: + cross-env@10.1.0: dependencies: + '@epic-web/invariant': 1.0.0 cross-spawn: 7.0.6 - cross-fetch@3.2.0(encoding@0.1.13): + cross-env@7.0.3: dependencies: - node-fetch: 2.7.0(encoding@0.1.13) - transitivePeerDependencies: - - encoding + cross-spawn: 7.0.3 - cross-fetch@4.1.0(encoding@0.1.13): + cross-fetch@4.0.0(encoding@0.1.13): dependencies: node-fetch: 2.7.0(encoding@0.1.13) transitivePeerDependencies: - encoding + cross-spawn@7.0.3: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + cross-spawn@7.0.6: dependencies: path-key: 3.1.1 shebang-command: 2.0.0 which: 2.0.2 - css-declaration-sorter@7.2.0(postcss@8.5.3): + css-declaration-sorter@7.2.0(postcss@8.5.6): dependencies: - postcss: 8.5.3 + postcss: 8.5.6 css-select@5.1.0: dependencies: @@ -16980,9 +17859,9 @@ snapshots: mdn-data: 2.0.28 source-map-js: 1.2.1 - css-tree@2.3.1: + css-tree@3.1.0: dependencies: - mdn-data: 2.0.30 + mdn-data: 2.12.2 source-map-js: 1.2.1 css-what@6.1.0: {} @@ -16991,92 +17870,91 @@ snapshots: cssesc@3.0.0: {} - cssnano-preset-default@7.0.7(postcss@8.5.3): - dependencies: - browserslist: 4.25.0 - css-declaration-sorter: 7.2.0(postcss@8.5.3) - cssnano-utils: 5.0.1(postcss@8.5.3) - postcss: 8.5.3 - postcss-calc: 10.1.1(postcss@8.5.3) - postcss-colormin: 7.0.3(postcss@8.5.3) - postcss-convert-values: 7.0.5(postcss@8.5.3) - postcss-discard-comments: 7.0.4(postcss@8.5.3) - postcss-discard-duplicates: 7.0.2(postcss@8.5.3) - postcss-discard-empty: 7.0.1(postcss@8.5.3) - postcss-discard-overridden: 7.0.1(postcss@8.5.3) - postcss-merge-longhand: 7.0.5(postcss@8.5.3) - postcss-merge-rules: 7.0.5(postcss@8.5.3) - postcss-minify-font-values: 7.0.1(postcss@8.5.3) - postcss-minify-gradients: 7.0.1(postcss@8.5.3) - postcss-minify-params: 7.0.3(postcss@8.5.3) - postcss-minify-selectors: 7.0.5(postcss@8.5.3) - postcss-normalize-charset: 7.0.1(postcss@8.5.3) - postcss-normalize-display-values: 7.0.1(postcss@8.5.3) - postcss-normalize-positions: 7.0.1(postcss@8.5.3) - postcss-normalize-repeat-style: 7.0.1(postcss@8.5.3) - postcss-normalize-string: 7.0.1(postcss@8.5.3) - postcss-normalize-timing-functions: 7.0.1(postcss@8.5.3) - postcss-normalize-unicode: 7.0.3(postcss@8.5.3) - postcss-normalize-url: 7.0.1(postcss@8.5.3) - postcss-normalize-whitespace: 7.0.1(postcss@8.5.3) - postcss-ordered-values: 7.0.2(postcss@8.5.3) - postcss-reduce-initial: 7.0.3(postcss@8.5.3) - postcss-reduce-transforms: 7.0.1(postcss@8.5.3) - postcss-svgo: 7.0.2(postcss@8.5.3) - postcss-unique-selectors: 7.0.4(postcss@8.5.3) - - cssnano-utils@5.0.1(postcss@8.5.3): - dependencies: - postcss: 8.5.3 - - cssnano@7.0.6(postcss@8.5.3): - dependencies: - cssnano-preset-default: 7.0.7(postcss@8.5.3) + cssnano-preset-default@7.0.9(postcss@8.5.6): + dependencies: + browserslist: 4.26.3 + css-declaration-sorter: 7.2.0(postcss@8.5.6) + cssnano-utils: 5.0.1(postcss@8.5.6) + postcss: 8.5.6 + postcss-calc: 10.1.1(postcss@8.5.6) + postcss-colormin: 7.0.4(postcss@8.5.6) + postcss-convert-values: 7.0.7(postcss@8.5.6) + postcss-discard-comments: 7.0.4(postcss@8.5.6) + postcss-discard-duplicates: 7.0.2(postcss@8.5.6) + postcss-discard-empty: 7.0.1(postcss@8.5.6) + postcss-discard-overridden: 7.0.1(postcss@8.5.6) + postcss-merge-longhand: 7.0.5(postcss@8.5.6) + postcss-merge-rules: 7.0.6(postcss@8.5.6) + postcss-minify-font-values: 7.0.1(postcss@8.5.6) + postcss-minify-gradients: 7.0.1(postcss@8.5.6) + postcss-minify-params: 7.0.4(postcss@8.5.6) + postcss-minify-selectors: 7.0.5(postcss@8.5.6) + postcss-normalize-charset: 7.0.1(postcss@8.5.6) + postcss-normalize-display-values: 7.0.1(postcss@8.5.6) + postcss-normalize-positions: 7.0.1(postcss@8.5.6) + postcss-normalize-repeat-style: 7.0.1(postcss@8.5.6) + postcss-normalize-string: 7.0.1(postcss@8.5.6) + postcss-normalize-timing-functions: 7.0.1(postcss@8.5.6) + postcss-normalize-unicode: 7.0.4(postcss@8.5.6) + postcss-normalize-url: 7.0.1(postcss@8.5.6) + postcss-normalize-whitespace: 7.0.1(postcss@8.5.6) + postcss-ordered-values: 7.0.2(postcss@8.5.6) + postcss-reduce-initial: 7.0.4(postcss@8.5.6) + postcss-reduce-transforms: 7.0.1(postcss@8.5.6) + postcss-svgo: 7.1.0(postcss@8.5.6) + postcss-unique-selectors: 7.0.4(postcss@8.5.6) + + cssnano-utils@5.0.1(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + + cssnano@7.1.1(postcss@8.5.6): + dependencies: + cssnano-preset-default: 7.0.9(postcss@8.5.6) lilconfig: 3.1.3 - postcss: 8.5.3 + postcss: 8.5.6 csso@5.0.5: dependencies: css-tree: 2.2.1 - cssstyle@4.4.0: + cssstyle@4.2.1: dependencies: - '@asamuzakjp/css-color': 3.2.0 + '@asamuzakjp/css-color': 2.8.3 rrweb-cssom: 0.8.0 csstype@3.1.3: {} - cypress@14.3.2: + cypress@15.4.0: dependencies: - '@cypress/request': 3.0.8 + '@cypress/request': 3.0.9 '@cypress/xvfb': 1.2.4(supports-color@8.1.1) '@types/sinonjs__fake-timers': 8.1.1 - '@types/sizzle': 2.3.9 + '@types/sizzle': 2.3.3 + '@types/tmp': 0.2.6 arch: 2.2.0 blob-util: 2.0.2 bluebird: 3.7.2 buffer: 5.7.1 - cachedir: 2.4.0 + cachedir: 2.3.0 chalk: 4.1.2 - check-more-types: 2.24.0 - ci-info: 4.2.0 + ci-info: 4.1.0 cli-cursor: 3.1.0 - cli-table3: 0.6.5 + cli-table3: 0.6.1 commander: 6.2.1 common-tags: 1.8.2 dayjs: 1.11.13 - debug: 4.4.1(supports-color@8.1.1) - enquirer: 2.4.1 + debug: 4.4.3(supports-color@8.1.1) + enquirer: 2.3.6 eventemitter2: 6.4.7 execa: 4.1.0 executable: 4.1.1 extract-zip: 2.0.1(supports-color@8.1.1) figures: 3.2.0 fs-extra: 9.1.0 - getos: 3.2.1 + hasha: 5.2.2 is-installed-globally: 0.4.0 - lazy-ass: 1.6.0 - listr2: 3.14.0(enquirer@2.4.1) + listr2: 3.14.0(enquirer@2.3.6) lodash: 4.17.21 log-symbols: 4.1.0 minimist: 1.2.8 @@ -17085,9 +17963,10 @@ snapshots: process: 0.11.10 proxy-from-env: 1.0.0 request-progress: 3.0.0 - semver: 7.7.1 + semver: 7.7.3 supports-color: 8.1.1 - tmp: 0.2.3 + systeminformation: 5.27.7 + tmp: 0.2.5 tree-kill: 1.2.2 untildify: 4.0.0 yauzl: 2.10.0 @@ -17096,12 +17975,18 @@ snapshots: dependencies: assert-plus: 1.0.0 - data-uri-to-buffer@4.0.1: {} + data-uri-to-buffer@4.0.0: {} data-urls@5.0.0: dependencies: whatwg-mimetype: 4.0.0 - whatwg-url: 14.2.0 + whatwg-url: 14.1.1 + + data-view-buffer@1.0.1: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-data-view: 1.0.1 data-view-buffer@1.0.2: dependencies: @@ -17109,12 +17994,24 @@ snapshots: es-errors: 1.3.0 is-data-view: 1.0.2 + data-view-byte-length@1.0.1: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-data-view: 1.0.1 + data-view-byte-length@1.0.2: dependencies: call-bound: 1.0.4 es-errors: 1.3.0 is-data-view: 1.0.2 + data-view-byte-offset@1.0.0: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-data-view: 1.0.1 + data-view-byte-offset@1.0.1: dependencies: call-bound: 1.0.4 @@ -17123,7 +18020,7 @@ snapshots: date-fns@2.30.0: dependencies: - '@babel/runtime': 7.27.6 + '@babel/runtime': 7.21.0 date-fns@4.1.0: {} @@ -17141,17 +18038,23 @@ snapshots: optionalDependencies: supports-color: 8.1.1 - debug@4.4.0: + debug@4.3.5: dependencies: - ms: 2.1.3 + ms: 2.1.2 - debug@4.4.1(supports-color@5.5.0): + debug@4.4.0(supports-color@5.5.0): dependencies: ms: 2.1.3 optionalDependencies: supports-color: 5.5.0 - debug@4.4.1(supports-color@8.1.1): + debug@4.4.3(supports-color@10.2.2): + dependencies: + ms: 2.1.3 + optionalDependencies: + supports-color: 10.2.2 + + debug@4.4.3(supports-color@8.1.1): dependencies: ms: 2.1.3 optionalDependencies: @@ -17164,6 +18067,8 @@ snapshots: decamelize@1.2.0: {} + decimal.js@10.4.3: {} + decimal.js@10.5.0: {} decode-bmp@0.2.1: @@ -17177,7 +18082,7 @@ snapshots: decode-bmp: 0.2.1 to-data-view: 1.1.0 - decode-named-character-reference@1.2.0: + decode-named-character-reference@1.0.2: dependencies: character-entities: 2.0.2 @@ -17185,11 +18090,13 @@ snapshots: dependencies: mimic-response: 3.1.0 - dedent@1.6.0: {} + dedent@1.5.1: {} + + dedent@1.7.0: {} deep-email-validator@0.1.21: dependencies: - '@types/disposable-email-domains': 1.0.6 + '@types/disposable-email-domains': 1.0.2 axios: 0.24.0 disposable-email-domains: 1.0.62 mailcheck: 1.1.1 @@ -17198,30 +18105,29 @@ snapshots: deep-eql@5.0.2: {} - deep-equal@2.2.3: + deep-equal@2.2.0: dependencies: - array-buffer-byte-length: 1.0.2 - call-bind: 1.0.8 + call-bind: 1.0.7 es-get-iterator: 1.1.3 - get-intrinsic: 1.3.0 - is-arguments: 1.2.0 - is-array-buffer: 3.0.5 - is-date-object: 1.1.0 - is-regex: 1.2.1 - is-shared-array-buffer: 1.0.4 + get-intrinsic: 1.2.7 + is-arguments: 1.1.1 + is-array-buffer: 3.0.2 + is-date-object: 1.0.5 + is-regex: 1.1.4 + is-shared-array-buffer: 1.0.2 isarray: 2.0.5 - object-is: 1.1.6 + object-is: 1.1.5 object-keys: 1.1.1 - object.assign: 4.1.7 - regexp.prototype.flags: 1.5.4 - side-channel: 1.1.0 - which-boxed-primitive: 1.1.1 - which-collection: 1.0.2 - which-typed-array: 1.1.19 + object.assign: 4.1.4 + regexp.prototype.flags: 1.5.0 + side-channel: 1.0.4 + which-boxed-primitive: 1.0.2 + which-collection: 1.0.1 + which-typed-array: 1.1.15 deep-is@0.1.4: {} - deepmerge@4.3.1: {} + deepmerge@4.2.2: {} defaults@3.0.0: {} @@ -17257,7 +18163,7 @@ snapshots: detect-libc@1.0.3: optional: true - detect-libc@2.0.4: {} + detect-libc@2.0.3: {} detect-newline@3.1.0: {} @@ -17276,7 +18182,7 @@ snapshots: diff@5.2.0: {} - dijkstrajs@1.0.3: {} + dijkstrajs@1.0.2: {} dir-glob@3.0.1: dependencies: @@ -17332,6 +18238,12 @@ snapshots: domelementtype: 2.3.0 domhandler: 4.3.1 + domutils@3.1.0: + dependencies: + dom-serializer: 2.0.0 + domelementtype: 2.3.0 + domhandler: 5.0.3 + domutils@3.2.2: dependencies: dom-serializer: 2.0.0 @@ -17352,12 +18264,12 @@ snapshots: duplexer@0.1.2: {} - duplexify@4.1.3: + duplexify@4.1.2: dependencies: end-of-stream: 1.4.4 inherits: 2.0.4 - readable-stream: 3.6.2 - stream-shift: 1.0.3 + readable-stream: 3.6.0 + stream-shift: 1.0.1 eastasianwidth@0.2.0: {} @@ -17375,11 +18287,13 @@ snapshots: '@one-ini/wasm': 0.1.1 commander: 10.0.1 minimatch: 9.0.1 - semver: 7.7.1 + semver: 7.7.3 ee-first@1.1.1: {} - electron-to-chromium@1.5.167: {} + electron-to-chromium@1.5.101: {} + + electron-to-chromium@1.5.234: {} emittery@0.13.1: {} @@ -17391,6 +18305,11 @@ snapshots: encodeurl@2.0.0: {} + encoding-sniffer@0.2.0: + dependencies: + iconv-lite: 0.6.3 + whatwg-encoding: 3.1.1 + encoding-sniffer@0.2.1: dependencies: iconv-lite: 0.6.3 @@ -17405,23 +18324,21 @@ snapshots: dependencies: once: 1.4.0 - enquirer@2.4.1: + enquirer@2.3.6: dependencies: ansi-colors: 4.1.3 - strip-ansi: 6.0.1 - ent@2.2.2: - dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - punycode: 1.4.1 - safe-regex-test: 1.1.0 + ent@2.2.0: {} + + entities@2.1.0: {} entities@2.2.0: {} entities@4.5.0: {} - entities@6.0.1: {} + entities@6.0.0: {} + + entities@7.0.0: {} env-paths@2.2.1: {} @@ -17431,6 +18348,55 @@ snapshots: dependencies: is-arrayish: 0.2.1 + es-abstract@1.23.3: + dependencies: + array-buffer-byte-length: 1.0.1 + arraybuffer.prototype.slice: 1.0.3 + available-typed-arrays: 1.0.7 + call-bind: 1.0.7 + data-view-buffer: 1.0.1 + data-view-byte-length: 1.0.1 + data-view-byte-offset: 1.0.0 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + es-set-tostringtag: 2.1.0 + es-to-primitive: 1.2.1 + function.prototype.name: 1.1.6 + get-intrinsic: 1.3.0 + get-symbol-description: 1.0.2 + globalthis: 1.0.3 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + has-proto: 1.0.3 + has-symbols: 1.1.0 + hasown: 2.0.2 + internal-slot: 1.0.7 + is-array-buffer: 3.0.4 + is-callable: 1.2.7 + is-data-view: 1.0.1 + is-negative-zero: 2.0.3 + is-regex: 1.1.4 + is-shared-array-buffer: 1.0.3 + is-string: 1.0.7 + is-typed-array: 1.1.13 + is-weakref: 1.0.2 + object-inspect: 1.13.4 + object-keys: 1.1.1 + object.assign: 4.1.5 + regexp.prototype.flags: 1.5.2 + safe-array-concat: 1.1.2 + safe-regex-test: 1.0.3 + string.prototype.trim: 1.2.9 + string.prototype.trimend: 1.0.9 + string.prototype.trimstart: 1.0.8 + typed-array-buffer: 1.0.2 + typed-array-byte-length: 1.0.1 + typed-array-byte-offset: 1.0.2 + typed-array-length: 1.0.6 + unbox-primitive: 1.0.2 + which-typed-array: 1.1.15 + es-abstract@1.24.0: dependencies: array-buffer-byte-length: 1.0.2 @@ -17494,15 +18460,15 @@ snapshots: es-get-iterator@1.1.3: dependencies: - call-bind: 1.0.8 + call-bind: 1.0.7 get-intrinsic: 1.3.0 has-symbols: 1.1.0 - is-arguments: 1.2.0 - is-map: 2.0.3 - is-set: 2.0.3 - is-string: 1.1.1 + is-arguments: 1.1.1 + is-map: 2.0.2 + is-set: 2.0.2 + is-string: 1.0.7 isarray: 2.0.5 - stop-iteration-iterator: 1.1.0 + stop-iteration-iterator: 1.0.0 es-module-lexer@1.7.0: {} @@ -17517,17 +18483,27 @@ snapshots: has-tostringtag: 1.0.2 hasown: 2.0.2 + es-shim-unscopables@1.0.2: + dependencies: + hasown: 2.0.2 + es-shim-unscopables@1.1.0: dependencies: hasown: 2.0.2 + es-to-primitive@1.2.1: + dependencies: + is-callable: 1.2.7 + is-date-object: 1.0.5 + is-symbol: 1.0.4 + es-to-primitive@1.3.0: dependencies: is-callable: 1.2.7 - is-date-object: 1.1.0 - is-symbol: 1.1.1 + is-date-object: 1.0.5 + is-symbol: 1.0.4 - es-toolkit@1.39.3: {} + es-toolkit@1.27.0: {} es6-promise@4.2.8: optional: true @@ -17537,66 +18513,43 @@ snapshots: es6-promise: 4.2.8 optional: true - esbuild-register@3.6.0(esbuild@0.25.3): + esbuild-register@3.5.0(esbuild@0.25.10): dependencies: - debug: 4.4.1(supports-color@5.5.0) - esbuild: 0.25.3 + debug: 4.4.3(supports-color@8.1.1) + esbuild: 0.25.10 transitivePeerDependencies: - supports-color - esbuild@0.21.5: - optionalDependencies: - '@esbuild/aix-ppc64': 0.21.5 - '@esbuild/android-arm': 0.21.5 - '@esbuild/android-arm64': 0.21.5 - '@esbuild/android-x64': 0.21.5 - '@esbuild/darwin-arm64': 0.21.5 - '@esbuild/darwin-x64': 0.21.5 - '@esbuild/freebsd-arm64': 0.21.5 - '@esbuild/freebsd-x64': 0.21.5 - '@esbuild/linux-arm': 0.21.5 - '@esbuild/linux-arm64': 0.21.5 - '@esbuild/linux-ia32': 0.21.5 - '@esbuild/linux-loong64': 0.21.5 - '@esbuild/linux-mips64el': 0.21.5 - '@esbuild/linux-ppc64': 0.21.5 - '@esbuild/linux-riscv64': 0.21.5 - '@esbuild/linux-s390x': 0.21.5 - '@esbuild/linux-x64': 0.21.5 - '@esbuild/netbsd-x64': 0.21.5 - '@esbuild/openbsd-x64': 0.21.5 - '@esbuild/sunos-x64': 0.21.5 - '@esbuild/win32-arm64': 0.21.5 - '@esbuild/win32-ia32': 0.21.5 - '@esbuild/win32-x64': 0.21.5 - - esbuild@0.25.3: + esbuild@0.25.10: optionalDependencies: - '@esbuild/aix-ppc64': 0.25.3 - '@esbuild/android-arm': 0.25.3 - '@esbuild/android-arm64': 0.25.3 - '@esbuild/android-x64': 0.25.3 - '@esbuild/darwin-arm64': 0.25.3 - '@esbuild/darwin-x64': 0.25.3 - '@esbuild/freebsd-arm64': 0.25.3 - '@esbuild/freebsd-x64': 0.25.3 - '@esbuild/linux-arm': 0.25.3 - '@esbuild/linux-arm64': 0.25.3 - '@esbuild/linux-ia32': 0.25.3 - '@esbuild/linux-loong64': 0.25.3 - '@esbuild/linux-mips64el': 0.25.3 - '@esbuild/linux-ppc64': 0.25.3 - '@esbuild/linux-riscv64': 0.25.3 - '@esbuild/linux-s390x': 0.25.3 - '@esbuild/linux-x64': 0.25.3 - '@esbuild/netbsd-arm64': 0.25.3 - '@esbuild/netbsd-x64': 0.25.3 - '@esbuild/openbsd-arm64': 0.25.3 - '@esbuild/openbsd-x64': 0.25.3 - '@esbuild/sunos-x64': 0.25.3 - '@esbuild/win32-arm64': 0.25.3 - '@esbuild/win32-ia32': 0.25.3 - '@esbuild/win32-x64': 0.25.3 + '@esbuild/aix-ppc64': 0.25.10 + '@esbuild/android-arm': 0.25.10 + '@esbuild/android-arm64': 0.25.10 + '@esbuild/android-x64': 0.25.10 + '@esbuild/darwin-arm64': 0.25.10 + '@esbuild/darwin-x64': 0.25.10 + '@esbuild/freebsd-arm64': 0.25.10 + '@esbuild/freebsd-x64': 0.25.10 + '@esbuild/linux-arm': 0.25.10 + '@esbuild/linux-arm64': 0.25.10 + '@esbuild/linux-ia32': 0.25.10 + '@esbuild/linux-loong64': 0.25.10 + '@esbuild/linux-mips64el': 0.25.10 + '@esbuild/linux-ppc64': 0.25.10 + '@esbuild/linux-riscv64': 0.25.10 + '@esbuild/linux-s390x': 0.25.10 + '@esbuild/linux-x64': 0.25.10 + '@esbuild/netbsd-arm64': 0.25.10 + '@esbuild/netbsd-x64': 0.25.10 + '@esbuild/openbsd-arm64': 0.25.10 + '@esbuild/openbsd-x64': 0.25.10 + '@esbuild/openharmony-arm64': 0.25.10 + '@esbuild/sunos-x64': 0.25.10 + '@esbuild/win32-arm64': 0.25.10 + '@esbuild/win32-ia32': 0.25.10 + '@esbuild/win32-x64': 0.25.10 + + escalade@3.1.1: {} escalade@3.2.0: {} @@ -17640,21 +18593,21 @@ snapshots: dependencies: debug: 3.2.7(supports-color@8.1.1) is-core-module: 2.16.1 - resolve: 1.22.10 + resolve: 1.22.8 transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.0(@typescript-eslint/parser@8.31.0(eslint@9.25.1)(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint@9.25.1): + eslint-module-utils@2.12.1(@typescript-eslint/parser@8.46.1(eslint@9.37.0)(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint@9.37.0): dependencies: debug: 3.2.7(supports-color@8.1.1) optionalDependencies: - '@typescript-eslint/parser': 8.31.0(eslint@9.25.1)(typescript@5.8.3) - eslint: 9.25.1 + '@typescript-eslint/parser': 8.46.1(eslint@9.37.0)(typescript@5.9.3) + eslint: 9.37.0 eslint-import-resolver-node: 0.3.9 transitivePeerDependencies: - supports-color - eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.31.0(eslint@9.25.1)(typescript@5.8.3))(eslint@9.25.1): + eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.46.1(eslint@9.37.0)(typescript@5.9.3))(eslint@9.37.0): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.9 @@ -17663,9 +18616,9 @@ snapshots: array.prototype.flatmap: 1.3.3 debug: 3.2.7(supports-color@8.1.1) doctrine: 2.1.0 - eslint: 9.25.1 + eslint: 9.37.0 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.31.0(eslint@9.25.1)(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint@9.25.1) + eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.46.1(eslint@9.37.0)(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint@9.37.0) hasown: 2.0.2 is-core-module: 2.16.1 is-glob: 4.0.3 @@ -17677,33 +18630,36 @@ snapshots: string.prototype.trimend: 1.0.9 tsconfig-paths: 3.15.0 optionalDependencies: - '@typescript-eslint/parser': 8.31.0(eslint@9.25.1)(typescript@5.8.3) + '@typescript-eslint/parser': 8.46.1(eslint@9.37.0)(typescript@5.9.3) transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack - supports-color - eslint-plugin-storybook@0.6.15(eslint@9.25.1)(typescript@5.8.3): + eslint-plugin-storybook@0.6.13(eslint@9.37.0)(typescript@5.9.3): dependencies: '@storybook/csf': 0.0.1 - '@typescript-eslint/utils': 5.62.0(eslint@9.25.1)(typescript@5.8.3) - eslint: 9.25.1 + '@typescript-eslint/utils': 5.62.0(eslint@9.37.0)(typescript@5.9.3) + eslint: 9.37.0 requireindex: 1.2.0 ts-dedent: 2.2.0 transitivePeerDependencies: - supports-color - typescript - eslint-plugin-vue@10.0.0(eslint@9.25.1)(vue-eslint-parser@10.1.3(eslint@9.25.1)): + eslint-plugin-vue@10.5.0(@stylistic/eslint-plugin@3.1.0(eslint@9.37.0)(typescript@5.9.3))(@typescript-eslint/parser@8.46.1(eslint@9.37.0)(typescript@5.9.3))(eslint@9.37.0)(vue-eslint-parser@10.2.0(eslint@9.37.0)): dependencies: - '@eslint-community/eslint-utils': 4.7.0(eslint@9.25.1) - eslint: 9.25.1 + '@eslint-community/eslint-utils': 4.4.0(eslint@9.37.0) + eslint: 9.37.0 natural-compare: 1.4.0 nth-check: 2.1.1 postcss-selector-parser: 6.1.2 - semver: 7.7.1 - vue-eslint-parser: 10.1.3(eslint@9.25.1) + semver: 7.7.3 + vue-eslint-parser: 10.2.0(eslint@9.37.0) xml-name-validator: 4.0.0 + optionalDependencies: + '@stylistic/eslint-plugin': 3.1.0(eslint@9.37.0)(typescript@5.9.3) + '@typescript-eslint/parser': 8.46.1(eslint@9.37.0)(typescript@5.9.3) eslint-rule-docs@1.1.235: {} @@ -17712,6 +18668,11 @@ snapshots: esrecurse: 4.3.0 estraverse: 4.3.0 + eslint-scope@8.3.0: + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + eslint-scope@8.4.0: dependencies: esrecurse: 4.3.0 @@ -17719,27 +18680,29 @@ snapshots: eslint-visitor-keys@3.4.3: {} + eslint-visitor-keys@4.2.0: {} + eslint-visitor-keys@4.2.1: {} - eslint@9.25.1: + eslint@9.37.0: dependencies: - '@eslint-community/eslint-utils': 4.7.0(eslint@9.25.1) + '@eslint-community/eslint-utils': 4.9.0(eslint@9.37.0) '@eslint-community/regexpp': 4.12.1 - '@eslint/config-array': 0.20.1 - '@eslint/config-helpers': 0.2.3 - '@eslint/core': 0.13.0 + '@eslint/config-array': 0.21.0 + '@eslint/config-helpers': 0.4.1 + '@eslint/core': 0.16.0 '@eslint/eslintrc': 3.3.1 - '@eslint/js': 9.25.1 - '@eslint/plugin-kit': 0.2.8 + '@eslint/js': 9.37.0 + '@eslint/plugin-kit': 0.4.0 '@humanfs/node': 0.16.6 '@humanwhocodes/module-importer': 1.0.1 - '@humanwhocodes/retry': 0.4.3 - '@types/estree': 1.0.7 + '@humanwhocodes/retry': 0.4.2 + '@types/estree': 1.0.8 '@types/json-schema': 7.0.15 ajv: 6.12.6 chalk: 4.1.2 cross-spawn: 7.0.6 - debug: 4.4.1(supports-color@5.5.0) + debug: 4.4.3(supports-color@8.1.1) escape-string-regexp: 4.0.0 eslint-scope: 8.4.0 eslint-visitor-keys: 4.2.1 @@ -17750,18 +18713,24 @@ snapshots: file-entry-cache: 8.0.0 find-up: 5.0.0 glob-parent: 6.0.2 - ignore: 5.3.2 + ignore: 5.3.1 imurmurhash: 0.1.4 is-glob: 4.0.3 json-stable-stringify-without-jsonify: 1.0.1 lodash.merge: 4.6.2 minimatch: 3.1.2 natural-compare: 1.4.0 - optionator: 0.9.4 + optionator: 0.9.3 transitivePeerDependencies: - supports-color - esm-resolve@1.0.11: {} + esm-resolve@1.0.9: {} + + espree@10.3.0: + dependencies: + acorn: 8.15.0 + acorn-jsx: 5.3.2(acorn@8.15.0) + eslint-visitor-keys: 4.2.1 espree@10.4.0: dependencies: @@ -17771,8 +18740,8 @@ snapshots: espree@9.6.1: dependencies: - acorn: 8.14.1 - acorn-jsx: 5.3.2(acorn@8.14.1) + acorn: 8.15.0 + acorn-jsx: 5.3.2(acorn@8.15.0) eslint-visitor-keys: 3.4.3 esprima@4.0.1: {} @@ -17793,7 +18762,7 @@ snapshots: estree-walker@3.0.3: dependencies: - '@types/estree': 1.0.7 + '@types/estree': 1.0.8 esutils@2.0.3: {} @@ -17861,7 +18830,7 @@ snapshots: execa@8.0.1: dependencies: - cross-spawn: 7.0.6 + cross-spawn: 7.0.3 get-stream: 8.0.1 human-signals: 5.0.0 is-stream: 3.0.0 @@ -17871,7 +18840,7 @@ snapshots: signal-exit: 4.1.0 strip-final-newline: 3.0.0 - execa@9.5.2: + execa@9.6.0: dependencies: '@sindresorhus/merge-streams': 4.0.0 cross-spawn: 7.0.6 @@ -17902,7 +18871,43 @@ snapshots: jest-message-util: 29.7.0 jest-util: 29.7.0 - exponential-backoff@3.1.2: {} + exponential-backoff@3.1.1: {} + + express@4.21.1: + dependencies: + accepts: 1.3.8 + array-flatten: 1.1.1 + body-parser: 1.20.3 + content-disposition: 0.5.4 + content-type: 1.0.5 + cookie: 0.7.1 + cookie-signature: 1.0.6 + debug: 2.6.9 + depd: 2.0.0 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + finalhandler: 1.3.1 + fresh: 0.5.2 + http-errors: 2.0.0 + merge-descriptors: 1.0.3 + methods: 1.1.2 + on-finished: 2.4.1 + parseurl: 1.3.3 + path-to-regexp: 0.1.10 + proxy-addr: 2.0.7 + qs: 6.13.0 + range-parser: 1.2.1 + safe-buffer: 5.2.1 + send: 0.19.0 + serve-static: 1.16.2 + setprototypeof: 1.2.0 + statuses: 2.0.1 + type-is: 1.6.18 + utils-merge: 1.0.1 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color express@4.21.2: dependencies: @@ -17942,7 +18947,7 @@ snapshots: ext-list@2.2.2: dependencies: - mime-db: 1.54.0 + mime-db: 1.52.0 ext-name@5.0.0: dependencies: @@ -17953,23 +18958,23 @@ snapshots: extract-zip@2.0.1(supports-color@8.1.1): dependencies: - debug: 4.4.1(supports-color@8.1.1) + debug: 4.4.3(supports-color@8.1.1) get-stream: 5.2.0 yauzl: 2.10.0 optionalDependencies: - '@types/yauzl': 2.10.3 + '@types/yauzl': 2.10.0 transitivePeerDependencies: - supports-color extsprintf@1.3.0: {} - fast-content-type-parse@2.0.1: {} + fast-content-type-parse@2.0.0: {} fast-decode-uri-component@1.0.1: {} fast-deep-equal@3.1.3: {} - fast-fifo@1.3.2: {} + fast-fifo@1.3.0: {} fast-glob@3.3.3: dependencies: @@ -17981,13 +18986,14 @@ snapshots: fast-json-stable-stringify@2.1.0: {} - fast-json-stringify@6.0.1: + fast-json-stringify@6.0.0: dependencies: - '@fastify/merge-json-schemas': 0.2.1 + '@fastify/merge-json-schemas': 0.1.1 ajv: 8.17.1 ajv-formats: 3.0.1(ajv@8.17.1) - fast-uri: 3.0.6 - json-schema-ref-resolver: 2.0.1 + fast-deep-equal: 3.1.3 + fast-uri: 2.4.0 + json-schema-ref-resolver: 1.0.1 rfdc: 1.4.1 fast-levenshtein@2.0.6: {} @@ -17996,21 +19002,25 @@ snapshots: dependencies: fast-decode-uri-component: 1.0.1 - fast-redact@3.5.0: {} + fast-redact@3.1.2: {} fast-safe-stringify@2.1.1: {} fast-text-encoding@1.0.6: {} - fast-uri@3.0.6: {} + fast-uri@2.4.0: {} - fast-xml-parser@4.4.1: + fast-uri@3.0.1: {} + + fast-xml-parser@4.5.0: dependencies: - strnum: 1.1.2 + strnum: 1.0.5 - fast-xml-parser@4.5.3: + fast-xml-parser@5.2.5: dependencies: - strnum: 1.1.2 + strnum: 2.1.1 + + fastify-plugin@4.5.1: {} fastify-plugin@5.0.1: {} @@ -18020,27 +19030,27 @@ snapshots: raw-body: 3.0.0 secure-json-parse: 2.7.0 - fastify@5.3.2: + fastify@5.6.1: dependencies: - '@fastify/ajv-compiler': 4.0.2 - '@fastify/error': 4.2.0 - '@fastify/fast-json-stringify-compiler': 5.0.3 + '@fastify/ajv-compiler': 4.0.1 + '@fastify/error': 4.0.0 + '@fastify/fast-json-stringify-compiler': 5.0.1 '@fastify/proxy-addr': 5.0.0 abstract-logging: 2.0.1 - avvio: 9.1.0 - fast-json-stringify: 6.0.1 - find-my-way: 9.3.0 - light-my-request: 6.6.0 - pino: 9.7.0 + avvio: 9.0.0 + fast-json-stringify: 6.0.0 + find-my-way: 9.0.1 + light-my-request: 6.0.0 + pino: 9.3.2 process-warning: 5.0.0 rfdc: 1.4.1 secure-json-parse: 4.0.0 - semver: 7.7.1 + semver: 7.7.3 toad-cache: 3.7.0 - fastq@1.19.1: + fastq@1.17.1: dependencies: - reusify: 1.1.0 + reusify: 1.0.4 fb-watchman@2.0.2: dependencies: @@ -18050,10 +19060,14 @@ snapshots: dependencies: pend: 1.2.0 - fdir@6.4.6(picomatch@4.0.2): + fdir@6.4.4(picomatch@4.0.2): optionalDependencies: picomatch: 4.0.2 + fdir@6.5.0(picomatch@4.0.3): + optionalDependencies: + picomatch: 4.0.3 + feed@4.2.2: dependencies: xml-js: 1.6.11 @@ -18061,7 +19075,7 @@ snapshots: fetch-blob@3.2.0: dependencies: node-domexception: 1.0.0 - web-streams-polyfill: 3.3.3 + web-streams-polyfill: 3.2.1 fflate@0.8.2: {} @@ -18080,14 +19094,14 @@ snapshots: file-type@19.6.0: dependencies: get-stream: 9.0.1 - strtok3: 9.1.1 + strtok3: 9.0.1 token-types: 6.0.0 uint8array-extras: 1.4.0 - file-type@20.4.1: + file-type@21.0.0: dependencies: '@tokenizer/inflate': 0.2.7 - strtok3: 10.3.1 + strtok3: 10.2.2 token-types: 6.0.0 uint8array-extras: 1.4.0 transitivePeerDependencies: @@ -18115,11 +19129,11 @@ snapshots: transitivePeerDependencies: - supports-color - find-my-way@9.3.0: + find-my-way@9.0.1: dependencies: fast-deep-equal: 3.1.3 fast-querystring: 1.1.2 - safe-regex2: 5.0.0 + safe-regex2: 4.0.0 find-package-json@1.2.0: {} @@ -18133,6 +19147,12 @@ snapshots: locate-path: 6.0.0 path-exists: 4.0.0 + find-up@7.0.0: + dependencies: + locate-path: 7.2.0 + path-exists: 5.0.0 + unicorn-magic: 0.1.0 + find-versions@5.1.0: dependencies: semver-regex: 4.0.5 @@ -18148,28 +19168,37 @@ snapshots: flat-cache@4.0.1: dependencies: - flatted: 3.3.3 + flatted: 3.3.1 keyv: 4.5.4 flatbuffers@24.12.23: {} - flatbuffers@25.2.10: {} - - flatted@3.3.3: {} + flatted@3.3.1: {} fluent-ffmpeg@2.1.3: dependencies: async: 0.2.10 which: 1.3.1 - follow-redirects@1.15.9(debug@4.4.0): + follow-redirects@1.15.2: {} + + follow-redirects@1.15.9(debug@4.4.3): optionalDependencies: - debug: 4.4.0 + debug: 4.4.3(supports-color@8.1.1) + + for-each@0.3.3: + dependencies: + is-callable: 1.2.7 for-each@0.3.5: dependencies: is-callable: 1.2.7 + foreground-child@3.1.1: + dependencies: + cross-spawn: 7.0.6 + signal-exit: 4.1.0 + foreground-child@3.3.1: dependencies: cross-spawn: 7.0.6 @@ -18179,13 +19208,20 @@ snapshots: form-data-encoder@2.1.4: {} - form-data-encoder@4.1.0: {} + form-data-encoder@4.0.2: {} + + form-data@3.0.1: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 - form-data@4.0.2: + form-data@4.0.4: dependencies: asynckit: 0.4.0 combined-stream: 1.0.8 es-set-tostringtag: 2.1.0 + hasown: 2.0.2 mime-types: 2.1.35 formdata-polyfill@4.0.10: @@ -18202,7 +19238,7 @@ snapshots: forwarded@0.2.0: {} - fraction.js@5.2.2: {} + fraction.js@4.3.4: {} fresh@0.5.2: {} @@ -18212,7 +19248,7 @@ snapshots: dependencies: graceful-fs: 4.2.11 jsonfile: 6.1.0 - universalify: 2.0.1 + universalify: 2.0.0 fs-extra@8.1.0: dependencies: @@ -18225,15 +19261,16 @@ snapshots: at-least-node: 1.0.0 graceful-fs: 4.2.11 jsonfile: 6.1.0 - universalify: 2.0.1 + universalify: 2.0.0 fs-minipass@2.1.0: dependencies: minipass: 3.3.6 + optional: true - fs-minipass@3.0.3: + fs-minipass@3.0.2: dependencies: - minipass: 7.1.2 + minipass: 5.0.0 fs.realpath@1.0.0: {} @@ -18242,6 +19279,13 @@ snapshots: function-bind@1.1.2: {} + function.prototype.name@1.1.6: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + functions-have-names: 1.2.3 + function.prototype.name@1.1.8: dependencies: call-bind: 1.0.8 @@ -18277,7 +19321,7 @@ snapshots: - encoding - supports-color - gaxios@5.1.3(encoding@0.1.13): + gaxios@5.1.2(encoding@0.1.13): dependencies: extend: 3.0.2 https-proxy-agent: 5.0.1 @@ -18295,9 +19339,9 @@ snapshots: - encoding - supports-color - gcp-metadata@5.3.0(encoding@0.1.13): + gcp-metadata@5.2.0(encoding@0.1.13): dependencies: - gaxios: 5.1.3(encoding@0.1.13) + gaxios: 5.1.2(encoding@0.1.13) json-bigint: 1.0.0 transitivePeerDependencies: - encoding @@ -18307,6 +19351,19 @@ snapshots: get-caller-file@2.0.5: {} + get-intrinsic@1.2.7: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + function-bind: 1.1.2 + get-proto: 1.0.1 + gopd: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.2 + math-intrinsics: 1.1.0 + get-intrinsic@1.3.0: dependencies: call-bind-apply-helpers: 1.0.2 @@ -18329,7 +19386,7 @@ snapshots: get-stream@5.2.0: dependencies: - pump: 3.0.2 + pump: 3.0.0 get-stream@6.0.1: {} @@ -18340,20 +19397,22 @@ snapshots: '@sec-ant/readable-stream': 0.4.1 is-stream: 4.0.1 + get-symbol-description@1.0.2: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + get-symbol-description@1.1.0: dependencies: call-bound: 1.0.4 es-errors: 1.3.0 get-intrinsic: 1.3.0 - get-tsconfig@4.10.1: + get-tsconfig@4.10.0: dependencies: resolve-pkg-maps: 1.0.0 - getos@3.2.1: - dependencies: - async: 3.2.6 - getpass@0.1.7: dependencies: assert-plus: 1.0.0 @@ -18368,20 +19427,20 @@ snapshots: glob@10.4.5: dependencies: - foreground-child: 3.3.1 + foreground-child: 3.1.1 jackspeak: 3.4.3 - minimatch: 9.0.5 + minimatch: 9.0.4 minipass: 7.1.2 - package-json-from-dist: 1.0.1 + package-json-from-dist: 1.0.0 path-scurry: 1.11.1 - glob@11.0.2: + glob@11.0.3: dependencies: foreground-child: 3.3.1 jackspeak: 4.1.1 - minimatch: 10.0.1 + minimatch: 10.0.3 minipass: 7.1.2 - package-json-from-dist: 1.0.1 + package-json-from-dist: 1.0.0 path-scurry: 2.0.0 glob@7.2.3: @@ -18398,7 +19457,7 @@ snapshots: fs.realpath: 1.0.0 inflight: 1.0.6 inherits: 2.0.4 - minimatch: 5.1.6 + minimatch: 5.1.2 once: 1.4.0 global-dirs@3.0.1: @@ -18409,30 +19468,38 @@ snapshots: globals@14.0.0: {} - globals@16.0.0: {} + globals@16.4.0: {} + + globalthis@1.0.3: + dependencies: + define-properties: 1.2.1 globalthis@1.0.4: dependencies: define-properties: 1.2.1 gopd: 1.2.0 + globalyzer@0.1.0: {} + globby@11.1.0: dependencies: array-union: 2.1.0 dir-glob: 3.0.1 fast-glob: 3.3.3 - ignore: 5.3.2 + ignore: 5.3.1 merge2: 1.4.1 slash: 3.0.0 - google-auth-library@8.9.0(encoding@0.1.13): + globrex@0.1.2: {} + + google-auth-library@8.8.0(encoding@0.1.13): dependencies: arrify: 2.0.1 base64-js: 1.5.1 ecdsa-sig-formatter: 1.0.11 fast-text-encoding: 1.0.6 - gaxios: 5.1.3(encoding@0.1.13) - gcp-metadata: 5.3.0(encoding@0.1.13) + gaxios: 5.1.2(encoding@0.1.13) + gcp-metadata: 5.2.0(encoding@0.1.13) gtoken: 6.1.2(encoding@0.1.13) jws: 4.0.0 lru-cache: 6.0.0 @@ -18440,22 +19507,22 @@ snapshots: - encoding - supports-color - google-gax@3.6.1(encoding@0.1.13): + google-gax@3.6.0(encoding@0.1.13): dependencies: - '@grpc/grpc-js': 1.8.22 - '@grpc/proto-loader': 0.7.15 + '@grpc/grpc-js': 1.8.16 + '@grpc/proto-loader': 0.7.7 '@types/long': 4.0.2 '@types/rimraf': 3.0.2 abort-controller: 3.0.0 - duplexify: 4.1.3 + duplexify: 4.1.2 fast-text-encoding: 1.0.6 - google-auth-library: 8.9.0(encoding@0.1.13) + google-auth-library: 8.8.0(encoding@0.1.13) is-stream-ended: 0.1.4 node-fetch: 2.7.0(encoding@0.1.13) object-hash: 3.0.0 proto3-json-serializer: 1.1.1 - protobufjs: 7.2.4 - protobufjs-cli: 1.1.1(protobufjs@7.2.4) + protobufjs: 7.2.3 + protobufjs-cli: 1.1.1(protobufjs@7.2.3) retry-request: 5.0.2 transitivePeerDependencies: - encoding @@ -18465,14 +19532,14 @@ snapshots: dependencies: node-forge: 1.3.1 - google-protobuf@3.21.4: + google-protobuf@3.21.2: optional: true gopd@1.2.0: {} got@13.0.0: dependencies: - '@sindresorhus/is': 5.6.0 + '@sindresorhus/is': 5.3.0 '@szmarczak/http-timer': 5.0.1 cacheable-lookup: 7.0.0 cacheable-request: 10.2.14 @@ -18484,29 +19551,30 @@ snapshots: p-cancelable: 3.0.0 responselike: 3.0.0 - got@14.4.7: + got@14.5.0: dependencies: - '@sindresorhus/is': 7.0.2 + '@sindresorhus/is': 7.0.1 '@szmarczak/http-timer': 5.0.1 cacheable-lookup: 7.0.0 - cacheable-request: 12.0.1 + cacheable-request: 13.0.12 decompress-response: 6.0.0 - form-data-encoder: 4.1.0 + form-data-encoder: 4.0.2 http2-wrapper: 2.2.1 + keyv: 5.5.3 lowercase-keys: 3.0.0 p-cancelable: 4.0.1 - responselike: 3.0.0 + responselike: 4.0.2 type-fest: 4.41.0 graceful-fs@4.2.11: {} graphemer@1.4.0: {} - graphql@16.11.0: {} + graphql@16.8.1: {} gtoken@6.1.2(encoding@0.1.13): dependencies: - gaxios: 5.1.3(encoding@0.1.13) + gaxios: 5.1.2(encoding@0.1.13) google-p12-pem: 4.0.1 jws: 4.0.0 transitivePeerDependencies: @@ -18515,19 +19583,17 @@ snapshots: hammerjs@2.0.8: {} - happy-dom@16.8.1: - dependencies: - webidl-conversions: 7.0.0 - whatwg-mimetype: 3.0.0 - - happy-dom@17.4.4: + happy-dom@20.0.7: dependencies: - webidl-conversions: 7.0.0 + '@types/node': 20.19.20 + '@types/whatwg-mimetype': 3.0.2 whatwg-mimetype: 3.0.0 hard-rejection@2.1.0: {} - has-bigints@1.1.0: {} + harfbuzzjs@0.4.13: {} + + has-bigints@1.0.2: {} has-flag@3.0.0: {} @@ -18537,6 +19603,8 @@ snapshots: dependencies: es-define-property: 1.0.1 + has-proto@1.0.3: {} + has-proto@1.2.0: dependencies: dunder-proto: 1.0.1 @@ -18552,6 +19620,11 @@ snapshots: hash-sum@2.0.0: {} + hasha@5.2.2: + dependencies: + is-stream: 2.0.1 + type-fest: 0.8.1 + hasown@2.0.2: dependencies: function-bind: 1.1.2 @@ -18559,13 +19632,13 @@ snapshots: hast-util-to-html@9.0.5: dependencies: '@types/hast': 3.0.4 - '@types/unist': 3.0.3 + '@types/unist': 3.0.2 ccount: 2.0.1 comma-separated-tokens: 2.0.3 hast-util-whitespace: 3.0.0 html-void-elements: 3.0.0 mdast-util-to-hast: 13.2.0 - property-information: 7.1.0 + property-information: 7.0.0 space-separated-tokens: 2.0.2 stringify-entities: 4.0.4 zwitch: 2.0.4 @@ -18576,11 +19649,11 @@ snapshots: he@1.2.0: {} - headers-polyfill@4.0.3: {} + headers-polyfill@4.0.2: {} highlight.js@10.7.3: {} - highlight.js@11.11.1: {} + highlight.js@11.10.0: {} hosted-git-info@2.8.9: {} @@ -18594,11 +19667,11 @@ snapshots: dependencies: whatwg-encoding: 3.1.1 - html-entities@2.5.2: {} + html-entities@2.6.0: {} html-escaper@2.0.2: {} - html-tags@3.3.1: {} + html-tags@3.2.0: {} html-void-elements@3.0.0: {} @@ -18609,7 +19682,7 @@ snapshots: domelementtype: 2.3.0 domhandler: 5.0.3 domutils: 3.2.2 - entities: 6.0.1 + entities: 6.0.0 htmlparser2@5.0.1: dependencies: @@ -18618,11 +19691,11 @@ snapshots: domutils: 2.8.0 entities: 2.2.0 - htmlparser2@8.0.2: + htmlparser2@8.0.1: dependencies: domelementtype: 2.3.0 domhandler: 5.0.3 - domutils: 3.2.2 + domutils: 3.1.0 entities: 4.5.0 htmlparser2@9.1.0: @@ -18632,6 +19705,8 @@ snapshots: domutils: 3.2.2 entities: 4.5.0 + http-cache-semantics@4.1.1: {} + http-cache-semantics@4.2.0: {} http-errors@2.0.0: @@ -18648,14 +19723,14 @@ snapshots: dependencies: '@tootallnate/once': 2.0.0 agent-base: 6.0.2 - debug: 4.4.1(supports-color@5.5.0) + debug: 4.4.3(supports-color@8.1.1) transitivePeerDependencies: - supports-color http-proxy-agent@7.0.2: dependencies: agent-base: 7.1.3 - debug: 4.4.1(supports-color@5.5.0) + debug: 4.4.3(supports-color@8.1.1) transitivePeerDependencies: - supports-color @@ -18683,14 +19758,28 @@ snapshots: https-proxy-agent@5.0.1: dependencies: agent-base: 6.0.2 - debug: 4.4.1(supports-color@5.5.0) + debug: 4.4.3(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + + https-proxy-agent@7.0.2: + dependencies: + agent-base: 7.1.0 + debug: 4.4.0(supports-color@5.5.0) transitivePeerDependencies: - supports-color https-proxy-agent@7.0.6: dependencies: agent-base: 7.1.3 - debug: 4.4.1(supports-color@5.5.0) + debug: 4.4.3(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + + https-proxy-agent@7.0.6(supports-color@10.2.2): + dependencies: + agent-base: 7.1.3 + debug: 4.4.3(supports-color@10.2.2) transitivePeerDependencies: - supports-color @@ -18712,35 +19801,41 @@ snapshots: dependencies: safer-buffer: 2.1.2 - idb-keyval@6.2.1: {} + iconv-lite@0.7.0: + dependencies: + safer-buffer: 2.1.2 + + idb-keyval@6.2.2: {} ieee754@1.2.1: {} ignore-by-default@1.0.1: {} - ignore-walk@7.0.0: + ignore-walk@8.0.0: dependencies: - minimatch: 9.0.5 + minimatch: 10.0.3 - ignore@5.3.2: {} + ignore@5.3.1: {} - immutable@5.1.3: {} + ignore@7.0.5: {} - import-fresh@3.3.1: + immutable@5.0.3: {} + + import-fresh@3.3.0: dependencies: parent-module: 1.0.1 resolve-from: 4.0.0 - import-in-the-middle@1.14.2: + import-in-the-middle@1.15.0: dependencies: - acorn: 8.14.1 - acorn-import-attributes: 1.9.5(acorn@8.14.1) - cjs-module-lexer: 1.4.3 - module-details-from-path: 1.0.4 + acorn: 8.15.0 + acorn-import-attributes: 1.9.5(acorn@8.15.0) + cjs-module-lexer: 1.2.2 + module-details-from-path: 1.0.3 import-lazy@4.0.0: {} - import-local@3.2.0: + import-local@3.1.0: dependencies: pkg-dir: 4.2.0 resolve-cwd: 3.0.0 @@ -18751,6 +19846,8 @@ snapshots: indent-string@5.0.0: {} + index-to-position@1.2.0: {} + inflight@1.0.6: dependencies: once: 1.4.0 @@ -18770,6 +19867,12 @@ snapshots: install-artifact-from-github@1.4.0: {} + internal-slot@1.0.7: + dependencies: + es-errors: 1.3.0 + hasown: 2.0.2 + side-channel: 1.1.0 + internal-slot@1.1.0: dependencies: es-errors: 1.3.0 @@ -18778,11 +19881,11 @@ snapshots: intersection-observer@0.12.2: {} - ioredis@5.6.1: + ioredis@5.8.1: dependencies: - '@ioredis/commands': 1.2.0 + '@ioredis/commands': 1.4.0 cluster-key-slot: 1.1.2 - debug: 4.4.1(supports-color@5.5.0) + debug: 4.4.3(supports-color@8.1.1) denque: 2.1.0 lodash.defaults: 4.2.0 lodash.isarguments: 3.1.0 @@ -18792,6 +19895,10 @@ snapshots: transitivePeerDependencies: - supports-color + ios-haptics@0.1.4: {} + + ip-address@10.0.1: {} + ip-address@9.0.5: dependencies: jsbn: 1.1.0 @@ -18809,11 +19916,22 @@ snapshots: irregular-plurals@3.5.0: {} - is-arguments@1.2.0: + is-arguments@1.1.1: dependencies: - call-bound: 1.0.4 + call-bind: 1.0.7 has-tostringtag: 1.0.2 + is-array-buffer@3.0.2: + dependencies: + call-bind: 1.0.7 + get-intrinsic: 1.3.0 + is-typed-array: 1.1.13 + + is-array-buffer@3.0.4: + dependencies: + call-bind: 1.0.7 + get-intrinsic: 1.3.0 + is-array-buffer@3.0.5: dependencies: call-bind: 1.0.8 @@ -18832,9 +19950,18 @@ snapshots: has-tostringtag: 1.0.2 safe-regex-test: 1.1.0 + is-bigint@1.0.4: + dependencies: + has-bigints: 1.0.2 + is-bigint@1.1.0: dependencies: - has-bigints: 1.1.0 + has-bigints: 1.0.2 + + is-boolean-object@1.1.2: + dependencies: + call-bind: 1.0.7 + has-tostringtag: 1.0.2 is-boolean-object@1.2.2: dependencies: @@ -18843,16 +19970,28 @@ snapshots: is-callable@1.2.7: {} + is-core-module@2.15.1: + dependencies: + hasown: 2.0.2 + is-core-module@2.16.1: dependencies: hasown: 2.0.2 + is-data-view@1.0.1: + dependencies: + is-typed-array: 1.1.13 + is-data-view@1.0.2: dependencies: call-bound: 1.0.4 get-intrinsic: 1.3.0 is-typed-array: 1.1.15 + is-date-object@1.0.5: + dependencies: + has-tostringtag: 1.0.2 + is-date-object@1.1.0: dependencies: call-bound: 1.0.4 @@ -18877,12 +20016,9 @@ snapshots: is-generator-fn@2.1.0: {} - is-generator-function@1.1.0: + is-generator-function@1.0.10: dependencies: - call-bound: 1.0.4 - get-proto: 1.0.1 has-tostringtag: 1.0.2 - safe-regex-test: 1.1.0 is-glob@4.0.3: dependencies: @@ -18890,14 +20026,14 @@ snapshots: is-html@2.0.0: dependencies: - html-tags: 3.3.1 + html-tags: 3.2.0 is-installed-globally@0.4.0: dependencies: global-dirs: 3.0.1 is-path-inside: 3.0.3 - is-lambda@1.0.1: {} + is-map@2.0.2: {} is-map@2.0.3: {} @@ -18905,6 +20041,10 @@ snapshots: is-node-process@1.2.0: {} + is-number-object@1.0.7: + dependencies: + has-tostringtag: 1.0.2 + is-number-object@1.1.1: dependencies: call-bound: 1.0.4 @@ -18926,6 +20066,11 @@ snapshots: is-promise@2.2.2: {} + is-regex@1.1.4: + dependencies: + call-bind: 1.0.7 + has-tostringtag: 1.0.2 + is-regex@1.2.1: dependencies: call-bound: 1.0.4 @@ -18933,8 +20078,18 @@ snapshots: has-tostringtag: 1.0.2 hasown: 2.0.2 + is-set@2.0.2: {} + is-set@2.0.3: {} + is-shared-array-buffer@1.0.2: + dependencies: + call-bind: 1.0.7 + + is-shared-array-buffer@1.0.3: + dependencies: + call-bind: 1.0.7 + is-shared-array-buffer@1.0.4: dependencies: call-bound: 1.0.4 @@ -18947,6 +20102,10 @@ snapshots: is-stream@4.0.1: {} + is-string@1.0.7: + dependencies: + has-tostringtag: 1.0.2 + is-string@1.1.1: dependencies: call-bound: 1.0.4 @@ -18954,7 +20113,11 @@ snapshots: is-svg@5.1.0: dependencies: - fast-xml-parser: 4.5.3 + fast-xml-parser: 4.5.0 + + is-symbol@1.0.4: + dependencies: + has-symbols: 1.1.0 is-symbol@1.1.1: dependencies: @@ -18962,6 +20125,10 @@ snapshots: has-symbols: 1.1.0 safe-regex-test: 1.1.0 + is-typed-array@1.1.13: + dependencies: + which-typed-array: 1.1.15 + is-typed-array@1.1.15: dependencies: which-typed-array: 1.1.19 @@ -18972,12 +20139,23 @@ snapshots: is-unicode-supported@2.1.0: {} + is-weakmap@2.0.1: {} + is-weakmap@2.0.2: {} + is-weakref@1.0.2: + dependencies: + call-bind: 1.0.7 + is-weakref@1.1.1: dependencies: call-bound: 1.0.4 + is-weakset@2.0.2: + dependencies: + call-bind: 1.0.7 + get-intrinsic: 1.3.0 + is-weakset@2.0.4: dependencies: call-bound: 1.0.4 @@ -19001,21 +20179,21 @@ snapshots: istanbul-lib-instrument@5.2.1: dependencies: - '@babel/core': 7.27.4 - '@babel/parser': 7.27.5 + '@babel/core': 7.28.4 + '@babel/parser': 7.28.4 '@istanbuljs/schema': 0.1.3 istanbul-lib-coverage: 3.2.2 semver: 6.3.1 transitivePeerDependencies: - supports-color - istanbul-lib-instrument@6.0.3: + istanbul-lib-instrument@6.0.0: dependencies: - '@babel/core': 7.27.4 - '@babel/parser': 7.27.5 + '@babel/core': 7.28.4 + '@babel/parser': 7.28.4 '@istanbuljs/schema': 0.1.3 istanbul-lib-coverage: 3.2.2 - semver: 7.7.1 + semver: 7.7.3 transitivePeerDependencies: - supports-color @@ -19027,7 +20205,7 @@ snapshots: istanbul-lib-source-maps@4.0.1: dependencies: - debug: 4.4.1(supports-color@5.5.0) + debug: 4.4.3(supports-color@8.1.1) istanbul-lib-coverage: 3.2.2 source-map: 0.6.1 transitivePeerDependencies: @@ -19035,8 +20213,8 @@ snapshots: istanbul-lib-source-maps@5.0.6: dependencies: - '@jridgewell/trace-mapping': 0.3.25 - debug: 4.4.1(supports-color@5.5.0) + '@jridgewell/trace-mapping': 0.3.31 + debug: 4.4.3(supports-color@8.1.1) istanbul-lib-coverage: 3.2.2 transitivePeerDependencies: - supports-color @@ -19072,10 +20250,10 @@ snapshots: '@jest/expect': 29.7.0 '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 22.15.2 + '@types/node': 24.9.1 chalk: 4.1.2 co: 4.6.0 - dedent: 1.6.0 + dedent: 1.5.1 is-generator-fn: 2.1.0 jest-each: 29.7.0 jest-matcher-utils: 29.7.0 @@ -19085,23 +20263,23 @@ snapshots: jest-util: 29.7.0 p-limit: 3.1.0 pretty-format: 29.7.0 - pure-rand: 6.1.0 + pure-rand: 6.0.0 slash: 3.0.0 stack-utils: 2.0.6 transitivePeerDependencies: - babel-plugin-macros - supports-color - jest-cli@29.7.0(@types/node@22.15.2): + jest-cli@29.7.0(@types/node@24.9.1): dependencies: '@jest/core': 29.7.0 '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 chalk: 4.1.2 - create-jest: 29.7.0(@types/node@22.15.2) + create-jest: 29.7.0(@types/node@24.9.1) exit: 0.1.2 - import-local: 3.2.0 - jest-config: 29.7.0(@types/node@22.15.2) + import-local: 3.1.0 + jest-config: 29.7.0(@types/node@24.9.1) jest-util: 29.7.0 jest-validate: 29.7.0 yargs: 17.7.2 @@ -19111,15 +20289,15 @@ snapshots: - supports-color - ts-node - jest-config@29.7.0(@types/node@22.15.2): + jest-config@29.7.0(@types/node@24.9.1): dependencies: - '@babel/core': 7.27.4 + '@babel/core': 7.24.9 '@jest/test-sequencer': 29.7.0 '@jest/types': 29.6.3 - babel-jest: 29.7.0(@babel/core@7.27.4) + babel-jest: 29.7.0(@babel/core@7.24.9) chalk: 4.1.2 - ci-info: 3.9.0 - deepmerge: 4.3.1 + ci-info: 3.7.1 + deepmerge: 4.2.2 glob: 7.2.3 graceful-fs: 4.2.11 jest-circus: 29.7.0 @@ -19136,7 +20314,7 @@ snapshots: slash: 3.0.0 strip-json-comments: 3.1.1 optionalDependencies: - '@types/node': 22.15.2 + '@types/node': 24.9.1 transitivePeerDependencies: - babel-plugin-macros - supports-color @@ -19165,24 +20343,17 @@ snapshots: '@jest/environment': 29.7.0 '@jest/fake-timers': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 22.15.2 + '@types/node': 24.9.1 jest-mock: 29.7.0 jest-util: 29.7.0 - jest-fetch-mock@3.0.3(encoding@0.1.13): - dependencies: - cross-fetch: 3.2.0(encoding@0.1.13) - promise-polyfill: 8.3.0 - transitivePeerDependencies: - - encoding - jest-get-type@29.6.3: {} jest-haste-map@29.7.0: dependencies: '@jest/types': 29.6.3 - '@types/graceful-fs': 4.1.9 - '@types/node': 22.15.2 + '@types/graceful-fs': 4.1.6 + '@types/node': 24.9.1 anymatch: 3.1.3 fb-watchman: 2.0.2 graceful-fs: 4.2.11 @@ -19208,9 +20379,9 @@ snapshots: jest-message-util@29.7.0: dependencies: - '@babel/code-frame': 7.27.1 + '@babel/code-frame': 7.24.7 '@jest/types': 29.6.3 - '@types/stack-utils': 2.0.3 + '@types/stack-utils': 2.0.1 chalk: 4.1.2 graceful-fs: 4.2.11 micromatch: 4.0.8 @@ -19221,7 +20392,7 @@ snapshots: jest-mock@29.7.0: dependencies: '@jest/types': 29.6.3 - '@types/node': 22.15.2 + '@types/node': 24.9.1 jest-util: 29.7.0 jest-pnp-resolver@1.2.3(jest-resolve@29.7.0): @@ -19230,6 +20401,8 @@ snapshots: jest-regex-util@29.6.3: {} + jest-regex-util@30.0.1: {} + jest-resolve-dependencies@29.7.0: dependencies: jest-regex-util: 29.6.3 @@ -19245,8 +20418,8 @@ snapshots: jest-pnp-resolver: 1.2.3(jest-resolve@29.7.0) jest-util: 29.7.0 jest-validate: 29.7.0 - resolve: 1.22.10 - resolve.exports: 2.0.3 + resolve: 1.22.8 + resolve.exports: 2.0.0 slash: 3.0.0 jest-runner@29.7.0: @@ -19256,7 +20429,7 @@ snapshots: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 22.15.2 + '@types/node': 24.9.1 chalk: 4.1.2 emittery: 0.13.1 graceful-fs: 4.2.11 @@ -19284,10 +20457,10 @@ snapshots: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 22.15.2 + '@types/node': 24.9.1 chalk: 4.1.2 - cjs-module-lexer: 1.4.3 - collect-v8-coverage: 1.0.2 + cjs-module-lexer: 1.2.2 + collect-v8-coverage: 1.0.1 glob: 7.2.3 graceful-fs: 4.2.11 jest-haste-map: 29.7.0 @@ -19304,15 +20477,15 @@ snapshots: jest-snapshot@29.7.0: dependencies: - '@babel/core': 7.27.4 - '@babel/generator': 7.27.5 - '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.27.4) - '@babel/plugin-syntax-typescript': 7.27.1(@babel/core@7.27.4) - '@babel/types': 7.27.6 + '@babel/core': 7.28.4 + '@babel/generator': 7.28.3 + '@babel/plugin-syntax-jsx': 7.23.3(@babel/core@7.28.4) + '@babel/plugin-syntax-typescript': 7.23.3(@babel/core@7.28.4) + '@babel/types': 7.28.4 '@jest/expect-utils': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - babel-preset-current-node-syntax: 1.1.0(@babel/core@7.27.4) + babel-preset-current-node-syntax: 1.0.1(@babel/core@7.28.4) chalk: 4.1.2 expect: 29.7.0 graceful-fs: 4.2.11 @@ -19323,16 +20496,16 @@ snapshots: jest-util: 29.7.0 natural-compare: 1.4.0 pretty-format: 29.7.0 - semver: 7.7.1 + semver: 7.7.3 transitivePeerDependencies: - supports-color jest-util@29.7.0: dependencies: '@jest/types': 29.6.3 - '@types/node': 22.15.2 + '@types/node': 24.9.1 chalk: 4.1.2 - ci-info: 3.9.0 + ci-info: 3.7.1 graceful-fs: 4.2.11 picomatch: 2.3.1 @@ -19349,31 +20522,26 @@ snapshots: dependencies: '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 22.15.2 + '@types/node': 24.9.1 ansi-escapes: 4.3.2 chalk: 4.1.2 emittery: 0.13.1 jest-util: 29.7.0 string-length: 4.0.2 - jest-websocket-mock@2.5.0: - dependencies: - jest-diff: 29.7.0 - mock-socket: 9.3.1 - jest-worker@29.7.0: dependencies: - '@types/node': 22.15.2 + '@types/node': 24.9.1 jest-util: 29.7.0 merge-stream: 2.0.0 supports-color: 8.1.1 - jest@29.7.0(@types/node@22.15.2): + jest@29.7.0(@types/node@24.9.1): dependencies: '@jest/core': 29.7.0 '@jest/types': 29.6.3 - import-local: 3.2.0 - jest-cli: 29.7.0(@types/node@22.15.2) + import-local: 3.1.0 + jest-cli: 29.7.0(@types/node@24.9.1) transitivePeerDependencies: - '@types/node' - babel-plugin-macros @@ -19382,28 +20550,39 @@ snapshots: jju@1.4.0: {} - joi@17.13.3: + joi@17.11.0: dependencies: '@hapi/hoek': 9.3.0 '@hapi/topo': 5.1.0 - '@sideway/address': 4.1.5 + '@sideway/address': 4.1.4 '@sideway/formula': 3.0.1 '@sideway/pinpoint': 2.0.0 - js-beautify@1.15.4: + joi@18.0.1: + dependencies: + '@hapi/address': 5.1.1 + '@hapi/formula': 3.0.2 + '@hapi/hoek': 11.0.7 + '@hapi/pinpoint': 2.0.1 + '@hapi/tlds': 1.1.3 + '@hapi/topo': 6.0.2 + '@standard-schema/spec': 1.0.0 + + js-beautify@1.14.9: dependencies: config-chain: 1.1.13 editorconfig: 1.0.4 - glob: 10.4.5 - js-cookie: 3.0.5 - nopt: 7.2.1 + glob: 8.1.0 + nopt: 6.0.0 - js-cookie@3.0.5: {} + js-levenshtein@1.1.6: {} js-stringify@1.0.2: {} js-tokens@4.0.0: {} + js-tokens@9.0.1: {} + js-yaml@3.14.1: dependencies: argparse: 1.0.10 @@ -19423,36 +20602,34 @@ snapshots: jschardet@3.1.4: {} - jsdoc-type-pratt-parser@4.1.0: {} - - jsdoc@4.0.4: + jsdoc@4.0.2: dependencies: - '@babel/parser': 7.27.5 - '@jsdoc/salty': 0.2.9 - '@types/markdown-it': 14.1.2 + '@babel/parser': 7.28.4 + '@jsdoc/salty': 0.2.5 + '@types/markdown-it': 12.2.3 bluebird: 3.7.2 catharsis: 0.9.0 escape-string-regexp: 2.0.0 js2xmlparser: 4.0.2 klaw: 3.0.0 - markdown-it: 14.1.0 - markdown-it-anchor: 8.6.7(@types/markdown-it@14.1.2)(markdown-it@14.1.0) + markdown-it: 12.3.2 + markdown-it-anchor: 8.6.7(@types/markdown-it@12.2.3)(markdown-it@12.3.2) marked: 4.3.0 mkdirp: 1.0.4 requizzle: 0.2.4 strip-json-comments: 3.1.1 - underscore: 1.13.7 + underscore: 1.13.6 jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5): dependencies: - cssstyle: 4.4.0 + cssstyle: 4.2.1 data-urls: 5.0.0 decimal.js: 10.5.0 html-encoding-sniffer: 4.0.0 http-proxy-agent: 7.0.2 https-proxy-agent: 7.0.6 is-potential-custom-element-name: 1.0.1 - nwsapi: 2.2.20 + nwsapi: 2.2.16 parse5: 7.3.0 rrweb-cssom: 0.8.0 saxes: 6.0.0 @@ -19462,27 +20639,29 @@ snapshots: webidl-conversions: 7.0.0 whatwg-encoding: 3.1.1 whatwg-mimetype: 4.0.0 - whatwg-url: 14.2.0 - ws: 8.18.1(bufferutil@4.0.9)(utf-8-validate@6.0.5) + whatwg-url: 14.1.1 + ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@6.0.5) xml-name-validator: 5.0.0 transitivePeerDependencies: - bufferutil - supports-color - utf-8-validate + jsesc@2.5.2: {} + jsesc@3.1.0: {} json-bigint@1.0.0: dependencies: - bignumber.js: 9.3.0 + bignumber.js: 9.1.1 json-buffer@3.0.1: {} json-parse-even-better-errors@2.3.1: {} - json-schema-ref-resolver@2.0.1: + json-schema-ref-resolver@1.0.1: dependencies: - dequal: 2.0.3 + fast-deep-equal: 3.1.3 json-schema-traverse@0.4.1: {} @@ -19500,7 +20679,7 @@ snapshots: json5@2.2.3: {} - jsonc-parser@3.3.1: {} + jsonc-parser@3.2.0: {} jsonfile@4.0.0: optionalDependencies: @@ -19514,13 +20693,13 @@ snapshots: jsonfile@6.1.0: dependencies: - universalify: 2.0.1 + universalify: 2.0.0 optionalDependencies: graceful-fs: 4.2.11 - jsonld@8.3.3(web-streams-polyfill@3.3.3): + jsonld@8.3.3(web-streams-polyfill@3.2.1): dependencies: - '@digitalbazaar/http-client': 3.4.1(web-streams-polyfill@3.3.3) + '@digitalbazaar/http-client': 3.4.1(web-streams-polyfill@3.2.1) canonicalize: 1.0.8 lru-cache: 6.0.0 rdf-canonize: 3.4.0 @@ -19550,18 +20729,18 @@ snapshots: is-promise: 2.2.2 promise: 7.3.1 - juice@11.0.1: + juice@11.0.3: dependencies: - cheerio: 1.1.0 + cheerio: 1.0.0 commander: 12.1.0 - entities: 4.5.0 + entities: 7.0.0 mensch: 0.3.4 slick: 1.12.2 web-resource-inliner: 7.0.0 just-extend@6.2.0: {} - jwa@2.0.1: + jwa@2.0.0: dependencies: buffer-equal-constant-time: 1.0.1 ecdsa-sig-formatter: 1.0.11 @@ -19569,13 +20748,17 @@ snapshots: jws@4.0.0: dependencies: - jwa: 2.0.1 + jwa: 2.0.0 safe-buffer: 5.2.1 keyv@4.5.4: dependencies: json-buffer: 3.0.1 + keyv@5.5.3: + dependencies: + '@keyv/serialize': 1.1.1 + kind-of@6.0.3: {} klaw@3.0.0: @@ -19584,13 +20767,13 @@ snapshots: kleur@3.0.3: {} - ky-universal@0.11.0(ky@0.33.3)(web-streams-polyfill@3.3.3): + ky-universal@0.11.0(ky@0.33.3)(web-streams-polyfill@3.2.1): dependencies: abort-controller: 3.0.0 ky: 0.33.3 node-fetch: 3.3.2 optionalDependencies: - web-streams-polyfill: 3.3.3 + web-streams-polyfill: 3.2.1 ky@0.33.3: {} @@ -19598,7 +20781,7 @@ snapshots: lazystream@1.0.1: dependencies: - readable-stream: 2.3.8 + readable-stream: 2.3.7 leven@3.1.0: {} @@ -19612,24 +20795,24 @@ snapshots: prelude-ls: 1.2.1 type-check: 0.4.0 - light-my-request@6.6.0: + light-my-request@6.0.0: dependencies: - cookie: 1.0.2 - process-warning: 4.0.1 - set-cookie-parser: 2.7.1 + cookie: 0.6.0 + process-warning: 4.0.0 + set-cookie-parser: 2.6.0 lilconfig@3.1.3: {} lines-and-columns@1.2.4: {} - linkify-it@5.0.0: + linkify-it@3.0.3: dependencies: - uc.micro: 2.1.0 + uc.micro: 1.0.6 - listr2@3.14.0(enquirer@2.4.1): + listr2@3.14.0(enquirer@2.3.6): dependencies: cli-truncate: 2.1.0 - colorette: 2.0.20 + colorette: 2.0.19 log-update: 4.0.0 p-map: 4.0.0 rfdc: 1.4.1 @@ -19637,7 +20820,7 @@ snapshots: through: 2.3.8 wrap-ansi: 7.0.0 optionalDependencies: - enquirer: 2.4.1 + enquirer: 2.3.6 load-esm@1.0.2: {} @@ -19649,6 +20832,10 @@ snapshots: dependencies: p-locate: 5.0.0 + locate-path@7.2.0: + dependencies: + p-locate: 6.0.0 + lodash.camelcase@4.3.0: {} lodash.defaults@4.2.0: {} @@ -19681,17 +20868,19 @@ snapshots: long@4.0.0: {} - long@5.3.2: {} + long@5.2.3: {} longest-streak@3.1.0: {} loupe@3.1.3: {} + loupe@3.2.1: {} + lowercase-keys@3.0.0: {} lru-cache@10.4.3: {} - lru-cache@11.1.0: {} + lru-cache@11.0.0: {} lru-cache@5.1.1: dependencies: @@ -19701,24 +20890,20 @@ snapshots: dependencies: yallist: 4.0.0 - lru-cache@8.0.5: {} + lru-cache@8.0.4: {} - luxon@3.6.1: {} + luxon@3.3.0: {} lz-string@1.5.0: {} - magic-string@0.27.0: + magic-string@0.30.19: dependencies: - '@jridgewell/sourcemap-codec': 1.5.0 - - magic-string@0.30.17: - dependencies: - '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/sourcemap-codec': 1.5.5 magicast@0.3.5: dependencies: - '@babel/parser': 7.27.5 - '@babel/types': 7.27.6 + '@babel/parser': 7.28.4 + '@babel/types': 7.28.4 source-map-js: 1.2.1 mailcheck@1.1.1: {} @@ -19730,22 +20915,21 @@ snapshots: make-dir@4.0.0: dependencies: - semver: 7.7.1 + semver: 7.7.3 - make-fetch-happen@13.0.1: + make-fetch-happen@14.0.3: dependencies: - '@npmcli/agent': 2.2.2 - cacache: 18.0.4 - http-cache-semantics: 4.2.0 - is-lambda: 1.0.1 + '@npmcli/agent': 3.0.0 + cacache: 19.0.1 + http-cache-semantics: 4.1.1 minipass: 7.1.2 - minipass-fetch: 3.0.5 + minipass-fetch: 4.0.1 minipass-flush: 1.0.5 minipass-pipeline: 1.2.4 - negotiator: 0.6.4 - proc-log: 4.2.0 + negotiator: 1.0.0 + proc-log: 5.0.0 promise-retry: 2.0.1 - ssri: 10.0.6 + ssri: 12.0.0 transitivePeerDependencies: - supports-color @@ -19761,33 +20945,32 @@ snapshots: map-stream@0.1.0: {} - markdown-it-anchor@8.6.7(@types/markdown-it@14.1.2)(markdown-it@14.1.0): + markdown-it-anchor@8.6.7(@types/markdown-it@12.2.3)(markdown-it@12.3.2): dependencies: - '@types/markdown-it': 14.1.2 - markdown-it: 14.1.0 + '@types/markdown-it': 12.2.3 + markdown-it: 12.3.2 - markdown-it@14.1.0: + markdown-it@12.3.2: dependencies: argparse: 2.0.1 - entities: 4.5.0 - linkify-it: 5.0.0 - mdurl: 2.0.0 - punycode.js: 2.3.1 - uc.micro: 2.1.0 + entities: 2.1.0 + linkify-it: 3.0.3 + mdurl: 1.0.1 + uc.micro: 1.0.6 - markdown-table@3.0.4: {} + markdown-table@3.0.3: {} marked@4.3.0: {} math-intrinsics@1.1.0: {} - mathjs@14.5.2: + mathjs@11.12.0: dependencies: - '@babel/runtime': 7.27.6 - complex.js: 2.4.2 - decimal.js: 10.5.0 + '@babel/runtime': 7.23.4 + complex.js: 2.1.1 + decimal.js: 10.4.3 escape-latex: 1.2.0 - fraction.js: 5.2.2 + fraction.js: 4.3.4 javascript-natural-sort: 0.7.1 seedrandom: 3.0.5 tiny-emitter: 2.1.0 @@ -19795,129 +20978,133 @@ snapshots: matter-js@0.20.0: {} - mdast-util-find-and-replace@3.0.2: + mdast-util-find-and-replace@3.0.1: dependencies: - '@types/mdast': 4.0.4 + '@types/mdast': 4.0.3 escape-string-regexp: 5.0.0 unist-util-is: 6.0.0 unist-util-visit-parents: 6.0.1 - mdast-util-from-markdown@2.0.2: + mdast-util-from-markdown@2.0.0: dependencies: - '@types/mdast': 4.0.4 - '@types/unist': 3.0.3 - decode-named-character-reference: 1.2.0 + '@types/mdast': 4.0.3 + '@types/unist': 3.0.2 + decode-named-character-reference: 1.0.2 devlop: 1.1.0 mdast-util-to-string: 4.0.0 - micromark: 4.0.2 - micromark-util-decode-numeric-character-reference: 2.0.2 - micromark-util-decode-string: 2.0.1 - micromark-util-normalize-identifier: 2.0.1 - micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 + micromark: 4.0.0 + micromark-util-decode-numeric-character-reference: 2.0.1 + micromark-util-decode-string: 2.0.0 + micromark-util-normalize-identifier: 2.0.0 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 unist-util-stringify-position: 4.0.0 transitivePeerDependencies: - supports-color - mdast-util-gfm-autolink-literal@2.0.1: + mdast-util-gfm-autolink-literal@2.0.0: dependencies: - '@types/mdast': 4.0.4 + '@types/mdast': 4.0.3 ccount: 2.0.1 devlop: 1.1.0 - mdast-util-find-and-replace: 3.0.2 - micromark-util-character: 2.1.1 + mdast-util-find-and-replace: 3.0.1 + micromark-util-character: 2.1.0 - mdast-util-gfm-footnote@2.1.0: + mdast-util-gfm-footnote@2.0.0: dependencies: - '@types/mdast': 4.0.4 + '@types/mdast': 4.0.3 devlop: 1.1.0 - mdast-util-from-markdown: 2.0.2 - mdast-util-to-markdown: 2.1.2 - micromark-util-normalize-identifier: 2.0.1 + mdast-util-from-markdown: 2.0.0 + mdast-util-to-markdown: 2.1.0 + micromark-util-normalize-identifier: 2.0.0 transitivePeerDependencies: - supports-color mdast-util-gfm-strikethrough@2.0.0: dependencies: - '@types/mdast': 4.0.4 - mdast-util-from-markdown: 2.0.2 - mdast-util-to-markdown: 2.1.2 + '@types/mdast': 4.0.3 + mdast-util-from-markdown: 2.0.0 + mdast-util-to-markdown: 2.1.0 transitivePeerDependencies: - supports-color mdast-util-gfm-table@2.0.0: dependencies: - '@types/mdast': 4.0.4 + '@types/mdast': 4.0.3 devlop: 1.1.0 - markdown-table: 3.0.4 - mdast-util-from-markdown: 2.0.2 - mdast-util-to-markdown: 2.1.2 + markdown-table: 3.0.3 + mdast-util-from-markdown: 2.0.0 + mdast-util-to-markdown: 2.1.0 transitivePeerDependencies: - supports-color mdast-util-gfm-task-list-item@2.0.0: dependencies: - '@types/mdast': 4.0.4 + '@types/mdast': 4.0.3 devlop: 1.1.0 - mdast-util-from-markdown: 2.0.2 - mdast-util-to-markdown: 2.1.2 + mdast-util-from-markdown: 2.0.0 + mdast-util-to-markdown: 2.1.0 transitivePeerDependencies: - supports-color - mdast-util-gfm@3.1.0: + mdast-util-gfm@3.0.0: dependencies: - mdast-util-from-markdown: 2.0.2 - mdast-util-gfm-autolink-literal: 2.0.1 - mdast-util-gfm-footnote: 2.1.0 + mdast-util-from-markdown: 2.0.0 + mdast-util-gfm-autolink-literal: 2.0.0 + mdast-util-gfm-footnote: 2.0.0 mdast-util-gfm-strikethrough: 2.0.0 mdast-util-gfm-table: 2.0.0 mdast-util-gfm-task-list-item: 2.0.0 - mdast-util-to-markdown: 2.1.2 + mdast-util-to-markdown: 2.1.0 transitivePeerDependencies: - supports-color mdast-util-phrasing@4.1.0: dependencies: - '@types/mdast': 4.0.4 + '@types/mdast': 4.0.3 unist-util-is: 6.0.0 mdast-util-to-hast@13.2.0: dependencies: '@types/hast': 3.0.4 - '@types/mdast': 4.0.4 - '@ungap/structured-clone': 1.3.0 + '@types/mdast': 4.0.3 + '@ungap/structured-clone': 1.2.0 devlop: 1.1.0 - micromark-util-sanitize-uri: 2.0.1 + micromark-util-sanitize-uri: 2.0.0 trim-lines: 3.0.1 unist-util-position: 5.0.0 unist-util-visit: 5.0.0 - vfile: 6.0.3 + vfile: 6.0.1 - mdast-util-to-markdown@2.1.2: + mdast-util-to-markdown@2.1.0: dependencies: - '@types/mdast': 4.0.4 - '@types/unist': 3.0.3 + '@types/mdast': 4.0.3 + '@types/unist': 3.0.2 longest-streak: 3.1.0 mdast-util-phrasing: 4.1.0 mdast-util-to-string: 4.0.0 - micromark-util-classify-character: 2.0.1 - micromark-util-decode-string: 2.0.1 + micromark-util-decode-string: 2.0.0 unist-util-visit: 5.0.0 zwitch: 2.0.4 mdast-util-to-string@4.0.0: dependencies: - '@types/mdast': 4.0.4 + '@types/mdast': 4.0.3 mdn-data@2.0.28: {} - mdn-data@2.0.30: {} + mdn-data@2.12.2: {} - mdurl@2.0.0: {} + mdurl@1.0.1: {} media-typer@0.3.0: {} - meilisearch@0.50.0: {} + mediabunny@1.23.0: + dependencies: + '@types/dom-mediacapture-transform': 0.1.11 + '@types/dom-webcodecs': 0.1.13 + + meilisearch@0.53.0: {} memoizerific@1.11.3: dependencies: @@ -19927,7 +21114,7 @@ snapshots: meow@9.0.0: dependencies: - '@types/minimist': 1.2.5 + '@types/minimist': 1.2.2 camelcase-keys: 6.2.2 decamelize: 1.2.0 decamelize-keys: 1.1.1 @@ -19948,202 +21135,202 @@ snapshots: methods@1.1.2: {} - mfc-js@0.24.0-cherrypick.9: + mfc-js@0.1.0: dependencies: - '@twemoji/parser': 15.0.0 + '@twemoji/parser': 17.0.0 - microformats-parser@2.0.2: + microformats-parser@2.0.4: dependencies: parse5: 7.3.0 - micromark-core-commonmark@2.0.3: + micromark-core-commonmark@2.0.0: dependencies: - decode-named-character-reference: 1.2.0 + decode-named-character-reference: 1.0.2 devlop: 1.1.0 - micromark-factory-destination: 2.0.1 - micromark-factory-label: 2.0.1 - micromark-factory-space: 2.0.1 - micromark-factory-title: 2.0.1 - micromark-factory-whitespace: 2.0.1 - micromark-util-character: 2.1.1 - micromark-util-chunked: 2.0.1 - micromark-util-classify-character: 2.0.1 - micromark-util-html-tag-name: 2.0.1 - micromark-util-normalize-identifier: 2.0.1 - micromark-util-resolve-all: 2.0.1 - micromark-util-subtokenize: 2.1.0 - micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 - - micromark-extension-gfm-autolink-literal@2.1.0: - dependencies: - micromark-util-character: 2.1.1 - micromark-util-sanitize-uri: 2.0.1 - micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 - - micromark-extension-gfm-footnote@2.1.0: + micromark-factory-destination: 2.0.0 + micromark-factory-label: 2.0.0 + micromark-factory-space: 2.0.0 + micromark-factory-title: 2.0.0 + micromark-factory-whitespace: 2.0.0 + micromark-util-character: 2.1.0 + micromark-util-chunked: 2.0.0 + micromark-util-classify-character: 2.0.0 + micromark-util-html-tag-name: 2.0.0 + micromark-util-normalize-identifier: 2.0.0 + micromark-util-resolve-all: 2.0.0 + micromark-util-subtokenize: 2.0.0 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + + micromark-extension-gfm-autolink-literal@2.0.0: + dependencies: + micromark-util-character: 2.1.0 + micromark-util-sanitize-uri: 2.0.0 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + + micromark-extension-gfm-footnote@2.0.0: dependencies: devlop: 1.1.0 - micromark-core-commonmark: 2.0.3 - micromark-factory-space: 2.0.1 - micromark-util-character: 2.1.1 - micromark-util-normalize-identifier: 2.0.1 - micromark-util-sanitize-uri: 2.0.1 - micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 + micromark-core-commonmark: 2.0.0 + micromark-factory-space: 2.0.0 + micromark-util-character: 2.1.0 + micromark-util-normalize-identifier: 2.0.0 + micromark-util-sanitize-uri: 2.0.0 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 - micromark-extension-gfm-strikethrough@2.1.0: + micromark-extension-gfm-strikethrough@2.0.0: dependencies: devlop: 1.1.0 - micromark-util-chunked: 2.0.1 - micromark-util-classify-character: 2.0.1 - micromark-util-resolve-all: 2.0.1 - micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 + micromark-util-chunked: 2.0.0 + micromark-util-classify-character: 2.0.0 + micromark-util-resolve-all: 2.0.0 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 - micromark-extension-gfm-table@2.1.1: + micromark-extension-gfm-table@2.0.0: dependencies: devlop: 1.1.0 - micromark-factory-space: 2.0.1 - micromark-util-character: 2.1.1 - micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 + micromark-factory-space: 2.0.0 + micromark-util-character: 2.1.0 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 micromark-extension-gfm-tagfilter@2.0.0: dependencies: - micromark-util-types: 2.0.2 + micromark-util-types: 2.0.0 - micromark-extension-gfm-task-list-item@2.1.0: + micromark-extension-gfm-task-list-item@2.0.1: dependencies: devlop: 1.1.0 - micromark-factory-space: 2.0.1 - micromark-util-character: 2.1.1 - micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 + micromark-factory-space: 2.0.0 + micromark-util-character: 2.1.0 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 micromark-extension-gfm@3.0.0: dependencies: - micromark-extension-gfm-autolink-literal: 2.1.0 - micromark-extension-gfm-footnote: 2.1.0 - micromark-extension-gfm-strikethrough: 2.1.0 - micromark-extension-gfm-table: 2.1.1 + micromark-extension-gfm-autolink-literal: 2.0.0 + micromark-extension-gfm-footnote: 2.0.0 + micromark-extension-gfm-strikethrough: 2.0.0 + micromark-extension-gfm-table: 2.0.0 micromark-extension-gfm-tagfilter: 2.0.0 - micromark-extension-gfm-task-list-item: 2.1.0 - micromark-util-combine-extensions: 2.0.1 - micromark-util-types: 2.0.2 + micromark-extension-gfm-task-list-item: 2.0.1 + micromark-util-combine-extensions: 2.0.0 + micromark-util-types: 2.0.0 - micromark-factory-destination@2.0.1: + micromark-factory-destination@2.0.0: dependencies: - micromark-util-character: 2.1.1 - micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 + micromark-util-character: 2.1.0 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 - micromark-factory-label@2.0.1: + micromark-factory-label@2.0.0: dependencies: devlop: 1.1.0 - micromark-util-character: 2.1.1 - micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 + micromark-util-character: 2.1.0 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 - micromark-factory-space@2.0.1: + micromark-factory-space@2.0.0: dependencies: - micromark-util-character: 2.1.1 - micromark-util-types: 2.0.2 + micromark-util-character: 2.1.0 + micromark-util-types: 2.0.0 - micromark-factory-title@2.0.1: + micromark-factory-title@2.0.0: dependencies: - micromark-factory-space: 2.0.1 - micromark-util-character: 2.1.1 - micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 + micromark-factory-space: 2.0.0 + micromark-util-character: 2.1.0 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 - micromark-factory-whitespace@2.0.1: + micromark-factory-whitespace@2.0.0: dependencies: - micromark-factory-space: 2.0.1 - micromark-util-character: 2.1.1 - micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 + micromark-factory-space: 2.0.0 + micromark-util-character: 2.1.0 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 - micromark-util-character@2.1.1: + micromark-util-character@2.1.0: dependencies: - micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 - micromark-util-chunked@2.0.1: + micromark-util-chunked@2.0.0: dependencies: - micromark-util-symbol: 2.0.1 + micromark-util-symbol: 2.0.0 - micromark-util-classify-character@2.0.1: + micromark-util-classify-character@2.0.0: dependencies: - micromark-util-character: 2.1.1 - micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 + micromark-util-character: 2.1.0 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 - micromark-util-combine-extensions@2.0.1: + micromark-util-combine-extensions@2.0.0: dependencies: - micromark-util-chunked: 2.0.1 - micromark-util-types: 2.0.2 + micromark-util-chunked: 2.0.0 + micromark-util-types: 2.0.0 - micromark-util-decode-numeric-character-reference@2.0.2: + micromark-util-decode-numeric-character-reference@2.0.1: dependencies: - micromark-util-symbol: 2.0.1 + micromark-util-symbol: 2.0.0 - micromark-util-decode-string@2.0.1: + micromark-util-decode-string@2.0.0: dependencies: - decode-named-character-reference: 1.2.0 - micromark-util-character: 2.1.1 - micromark-util-decode-numeric-character-reference: 2.0.2 - micromark-util-symbol: 2.0.1 + decode-named-character-reference: 1.0.2 + micromark-util-character: 2.1.0 + micromark-util-decode-numeric-character-reference: 2.0.1 + micromark-util-symbol: 2.0.0 - micromark-util-encode@2.0.1: {} + micromark-util-encode@2.0.0: {} - micromark-util-html-tag-name@2.0.1: {} + micromark-util-html-tag-name@2.0.0: {} - micromark-util-normalize-identifier@2.0.1: + micromark-util-normalize-identifier@2.0.0: dependencies: - micromark-util-symbol: 2.0.1 + micromark-util-symbol: 2.0.0 - micromark-util-resolve-all@2.0.1: + micromark-util-resolve-all@2.0.0: dependencies: - micromark-util-types: 2.0.2 + micromark-util-types: 2.0.0 - micromark-util-sanitize-uri@2.0.1: + micromark-util-sanitize-uri@2.0.0: dependencies: - micromark-util-character: 2.1.1 - micromark-util-encode: 2.0.1 - micromark-util-symbol: 2.0.1 + micromark-util-character: 2.1.0 + micromark-util-encode: 2.0.0 + micromark-util-symbol: 2.0.0 - micromark-util-subtokenize@2.1.0: + micromark-util-subtokenize@2.0.0: dependencies: devlop: 1.1.0 - micromark-util-chunked: 2.0.1 - micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 + micromark-util-chunked: 2.0.0 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 - micromark-util-symbol@2.0.1: {} + micromark-util-symbol@2.0.0: {} - micromark-util-types@2.0.2: {} + micromark-util-types@2.0.0: {} - micromark@4.0.2: + micromark@4.0.0: dependencies: '@types/debug': 4.1.12 - debug: 4.4.1(supports-color@5.5.0) - decode-named-character-reference: 1.2.0 + debug: 4.4.3(supports-color@8.1.1) + decode-named-character-reference: 1.0.2 devlop: 1.1.0 - micromark-core-commonmark: 2.0.3 - micromark-factory-space: 2.0.1 - micromark-util-character: 2.1.1 - micromark-util-chunked: 2.0.1 - micromark-util-combine-extensions: 2.0.1 - micromark-util-decode-numeric-character-reference: 2.0.2 - micromark-util-encode: 2.0.1 - micromark-util-normalize-identifier: 2.0.1 - micromark-util-resolve-all: 2.0.1 - micromark-util-sanitize-uri: 2.0.1 - micromark-util-subtokenize: 2.1.0 - micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 + micromark-core-commonmark: 2.0.0 + micromark-factory-space: 2.0.0 + micromark-util-character: 2.1.0 + micromark-util-chunked: 2.0.0 + micromark-util-combine-extensions: 2.0.0 + micromark-util-decode-numeric-character-reference: 2.0.1 + micromark-util-encode: 2.0.0 + micromark-util-normalize-identifier: 2.0.0 + micromark-util-resolve-all: 2.0.0 + micromark-util-sanitize-uri: 2.0.0 + micromark-util-subtokenize: 2.0.0 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 transitivePeerDependencies: - supports-color @@ -20154,8 +21341,6 @@ snapshots: mime-db@1.52.0: {} - mime-db@1.54.0: {} - mime-types@2.1.35: dependencies: mime-db: 1.52.0 @@ -20178,29 +21363,25 @@ snapshots: minimalistic-assert@1.0.1: {} - minimatch@10.0.1: + minimatch@10.0.3: dependencies: - brace-expansion: 2.0.2 - - minimatch@3.0.8: - dependencies: - brace-expansion: 1.1.12 + '@isaacs/brace-expansion': 5.0.0 minimatch@3.1.2: dependencies: - brace-expansion: 1.1.12 + brace-expansion: 1.1.11 - minimatch@5.1.6: + minimatch@5.1.2: dependencies: - brace-expansion: 2.0.2 + brace-expansion: 2.0.1 minimatch@9.0.1: dependencies: - brace-expansion: 2.0.2 + brace-expansion: 2.0.1 - minimatch@9.0.5: + minimatch@9.0.4: dependencies: - brace-expansion: 2.0.2 + brace-expansion: 2.0.1 minimist-options@4.1.0: dependencies: @@ -20208,17 +21389,19 @@ snapshots: is-plain-obj: 1.1.0 kind-of: 6.0.3 + minimist@1.2.7: {} + minimist@1.2.8: {} minipass-collect@2.0.1: dependencies: minipass: 7.1.2 - minipass-fetch@3.0.5: + minipass-fetch@4.0.1: dependencies: minipass: 7.1.2 minipass-sized: 1.0.3 - minizlib: 2.1.2 + minizlib: 3.0.1 optionalDependencies: encoding: 0.1.13 @@ -20246,8 +21429,14 @@ snapshots: dependencies: minipass: 3.3.6 yallist: 4.0.0 + optional: true + + minizlib@3.0.1: + dependencies: + minipass: 7.1.2 + rimraf: 5.0.10 - minizlib@3.0.2: + minizlib@3.1.0: dependencies: minipass: 7.1.2 @@ -20257,75 +21446,77 @@ snapshots: mkdirp@1.0.4: {} - mkdirp@3.0.1: {} - mnemonist@0.40.0: dependencies: - obliterator: 2.0.5 + obliterator: 2.0.4 mock-socket@9.3.1: {} + module-details-from-path@1.0.3: {} + module-details-from-path@1.0.4: {} ms@2.0.0: {} + ms@2.1.2: {} + ms@2.1.3: {} - ms@3.0.0-canary.1: {} + ms@3.0.0-canary.202508261828: {} - msgpackr-extract@3.0.3: + msgpackr-extract@3.0.2: dependencies: - node-gyp-build-optional-packages: 5.2.2 + node-gyp-build-optional-packages: 5.0.7 optionalDependencies: - '@msgpackr-extract/msgpackr-extract-darwin-arm64': 3.0.3 - '@msgpackr-extract/msgpackr-extract-darwin-x64': 3.0.3 - '@msgpackr-extract/msgpackr-extract-linux-arm': 3.0.3 - '@msgpackr-extract/msgpackr-extract-linux-arm64': 3.0.3 - '@msgpackr-extract/msgpackr-extract-linux-x64': 3.0.3 - '@msgpackr-extract/msgpackr-extract-win32-x64': 3.0.3 + '@msgpackr-extract/msgpackr-extract-darwin-arm64': 3.0.2 + '@msgpackr-extract/msgpackr-extract-darwin-x64': 3.0.2 + '@msgpackr-extract/msgpackr-extract-linux-arm': 3.0.2 + '@msgpackr-extract/msgpackr-extract-linux-arm64': 3.0.2 + '@msgpackr-extract/msgpackr-extract-linux-x64': 3.0.2 + '@msgpackr-extract/msgpackr-extract-win32-x64': 3.0.2 optional: true - msgpackr@1.11.4: + msgpackr@1.11.2: optionalDependencies: - msgpackr-extract: 3.0.3 + msgpackr-extract: 3.0.2 - msw-storybook-addon@2.0.4(msw@2.7.5(@types/node@22.15.2)(typescript@5.8.3)): + msw-storybook-addon@2.0.6(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3)): dependencies: is-node-process: 1.2.0 - msw: 2.7.5(@types/node@22.15.2)(typescript@5.8.3) + msw: 2.11.5(@types/node@24.9.1)(typescript@5.9.3) - msw@2.7.5(@types/node@22.15.2)(typescript@5.8.3): + msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3): dependencies: - '@bundled-es-modules/cookie': 2.0.1 - '@bundled-es-modules/statuses': 1.0.1 - '@bundled-es-modules/tough-cookie': 0.1.6 - '@inquirer/confirm': 5.1.12(@types/node@22.15.2) - '@mswjs/interceptors': 0.37.6 + '@inquirer/confirm': 5.0.2(@types/node@24.9.1) + '@mswjs/interceptors': 0.39.7 '@open-draft/deferred-promise': 2.2.0 - '@open-draft/until': 2.1.0 - '@types/cookie': 0.6.0 - '@types/statuses': 2.0.6 - graphql: 16.11.0 - headers-polyfill: 4.0.3 + '@types/statuses': 2.0.4 + cookie: 1.0.2 + graphql: 16.8.1 + headers-polyfill: 4.0.2 is-node-process: 1.2.0 outvariant: 1.4.3 path-to-regexp: 6.3.0 picocolors: 1.1.1 + rettime: 0.7.0 + statuses: 2.0.2 strict-event-emitter: 0.5.1 + tough-cookie: 6.0.0 type-fest: 4.41.0 + until-async: 3.0.2 yargs: 17.7.2 optionalDependencies: - typescript: 5.8.3 + typescript: 5.9.3 transitivePeerDependencies: - '@types/node' muggle-string@0.4.1: {} - multer@1.4.4-lts.1: + multer@2.0.2: dependencies: append-field: 1.0.0 busboy: 1.6.0 - concat-stream: 1.6.2 + concat-stream: 2.0.0 mkdirp: 0.5.6 object-assign: 4.1.1 type-is: 1.6.18 @@ -20341,11 +21532,11 @@ snapshots: object-assign: 4.1.1 thenify-all: 1.6.0 - nan@2.22.2: {} + nan@2.23.0: {} nanoid@3.3.11: {} - nanoid@5.1.5: {} + nanoid@5.1.6: {} natural-compare@1.4.0: {} @@ -20355,18 +21546,24 @@ snapshots: dependencies: debug: 3.2.7(supports-color@8.1.1) iconv-lite: 0.4.24 - sax: 1.4.1 + sax: 1.2.4 transitivePeerDependencies: - supports-color negotiator@0.6.3: {} - negotiator@0.6.4: {} + negotiator@1.0.0: {} nested-property@4.0.0: {} netmask@2.0.2: {} + nice-napi@1.0.2: + dependencies: + node-addon-api: 3.2.1 + node-gyp-build: 4.8.2 + optional: true + nise@6.1.1: dependencies: '@sinonjs/commons': 3.0.1 @@ -20375,20 +21572,23 @@ snapshots: just-extend: 6.2.0 path-to-regexp: 8.2.0 - node-abi@3.75.0: + node-abi@3.78.0: dependencies: - semver: 7.7.1 + semver: 7.7.3 node-abort-controller@3.1.1: {} + node-addon-api@3.2.1: + optional: true + node-addon-api@7.1.1: optional: true - node-addon-api@8.4.0: {} + node-addon-api@8.2.0: {} node-domexception@1.0.0: {} - node-fetch@2.6.13(encoding@0.1.13): + node-fetch@2.6.11(encoding@0.1.13): dependencies: whatwg-url: 5.0.0 optionalDependencies: @@ -20402,31 +21602,29 @@ snapshots: node-fetch@3.3.2: dependencies: - data-uri-to-buffer: 4.0.1 + data-uri-to-buffer: 4.0.0 fetch-blob: 3.2.0 formdata-polyfill: 4.0.10 node-forge@1.3.1: {} - node-gyp-build-optional-packages@5.2.2: - dependencies: - detect-libc: 2.0.4 + node-gyp-build-optional-packages@5.0.7: optional: true - node-gyp-build@4.8.4: {} + node-gyp-build@4.8.2: {} - node-gyp@10.3.1: + node-gyp@11.4.2: dependencies: env-paths: 2.2.1 - exponential-backoff: 3.1.2 - glob: 10.4.5 + exponential-backoff: 3.1.1 graceful-fs: 4.2.11 - make-fetch-happen: 13.0.1 - nopt: 7.2.1 - proc-log: 4.2.0 - semver: 7.7.1 - tar: 6.2.1 - which: 4.0.0 + make-fetch-happen: 14.0.3 + nopt: 8.1.0 + proc-log: 5.0.0 + semver: 7.7.3 + tar: 7.5.1 + tinyglobby: 0.2.13 + which: 5.0.0 transitivePeerDependencies: - supports-color @@ -20434,49 +21632,61 @@ snapshots: node-releases@2.0.19: {} - nodemailer@6.10.1: {} + node-releases@2.0.23: {} + + nodemailer@7.0.9: {} nodemon@3.1.10: dependencies: chokidar: 4.0.3 - debug: 4.4.1(supports-color@5.5.0) + debug: 4.4.0(supports-color@5.5.0) ignore-by-default: 1.0.1 minimatch: 3.1.2 pstree.remy: 1.1.8 - semver: 7.7.1 + semver: 7.7.3 simple-update-notifier: 2.0.0 supports-color: 5.5.0 - touch: 3.1.1 + touch: 3.1.0 undefsafe: 2.0.5 nofilter@3.1.0: {} - nopt@5.0.0: + nopt@1.0.10: + dependencies: + abbrev: 1.1.1 + + nopt@5.0.0: + dependencies: + abbrev: 1.1.1 + optional: true + + nopt@6.0.0: dependencies: abbrev: 1.1.1 - optional: true - nopt@7.2.1: + nopt@8.1.0: dependencies: - abbrev: 2.0.0 + abbrev: 3.0.1 normalize-package-data@2.5.0: dependencies: hosted-git-info: 2.8.9 - resolve: 1.22.10 - semver: 5.7.2 + resolve: 1.22.8 + semver: 5.7.1 validate-npm-package-license: 3.0.4 normalize-package-data@3.0.3: dependencies: hosted-git-info: 4.1.0 - is-core-module: 2.16.1 - semver: 7.7.1 + is-core-module: 2.15.1 + semver: 7.7.3 validate-npm-package-license: 3.0.4 normalize-path@3.0.0: {} - normalize-url@8.0.2: {} + normalize-url@8.0.1: {} + + normalize-url@8.1.0: {} npm-run-path@4.0.1: dependencies: @@ -20508,7 +21718,7 @@ snapshots: dependencies: boolbase: 1.0.0 - nwsapi@2.2.20: {} + nwsapi@2.2.16: {} oauth2orize-pkce@0.1.2: {} @@ -20526,15 +21736,31 @@ snapshots: object-hash@3.0.0: {} + object-inspect@1.13.2: {} + object-inspect@1.13.4: {} - object-is@1.1.6: + object-is@1.1.5: dependencies: - call-bind: 1.0.8 + call-bind: 1.0.7 define-properties: 1.2.1 object-keys@1.1.1: {} + object.assign@4.1.4: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + has-symbols: 1.1.0 + object-keys: 1.1.1 + + object.assign@4.1.5: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + has-symbols: 1.1.0 + object-keys: 1.1.1 + object.assign@4.1.7: dependencies: call-bind: 1.0.8 @@ -20546,16 +21772,16 @@ snapshots: object.fromentries@2.0.8: dependencies: - call-bind: 1.0.8 + call-bind: 1.0.7 define-properties: 1.2.1 - es-abstract: 1.24.0 + es-abstract: 1.23.3 es-object-atoms: 1.1.1 object.groupby@1.0.3: dependencies: - call-bind: 1.0.8 + call-bind: 1.0.7 define-properties: 1.2.1 - es-abstract: 1.24.0 + es-abstract: 1.23.3 object.values@1.2.1: dependencies: @@ -20564,13 +21790,11 @@ snapshots: define-properties: 1.2.1 es-object-atoms: 1.1.1 - obliterator@2.0.5: {} + obliterator@2.0.4: {} oblivious-set@1.4.0: {} - obuf@1.1.2: {} - - on-exit-leak-free@2.1.2: {} + on-exit-leak-free@2.1.0: {} on-finished@2.4.1: dependencies: @@ -20604,18 +21828,19 @@ snapshots: openapi-types@12.1.3: {} - openapi-typescript@6.7.6: + openapi-typescript@7.9.1(typescript@5.9.3): dependencies: + '@redocly/openapi-core': 1.34.5(supports-color@10.2.2) ansi-colors: 4.1.3 - fast-glob: 3.3.3 - js-yaml: 4.1.0 - supports-color: 9.4.0 - undici: 5.29.0 + change-case: 5.4.4 + parse-json: 8.3.0 + supports-color: 10.2.2 + typescript: 5.9.3 yargs-parser: 21.1.1 openmeteo@1.1.4: dependencies: - '@openmeteo/sdk': 1.20.1 + '@openmeteo/sdk': 1.18.6 flatbuffers: 24.12.23 optionator@0.8.3: @@ -20625,24 +21850,24 @@ snapshots: levn: 0.3.0 prelude-ls: 1.1.2 type-check: 0.3.2 - word-wrap: 1.2.5 + word-wrap: 1.2.3 - optionator@0.9.4: + optionator@0.9.3: dependencies: + '@aashutoshrathi/word-wrap': 1.2.6 deep-is: 0.1.4 fast-levenshtein: 2.0.6 levn: 0.4.1 prelude-ls: 1.2.1 type-check: 0.4.0 - word-wrap: 1.2.5 os-utils@0.0.14: {} ospath@1.2.2: {} - otpauth@9.4.0: + otpauth@9.4.1: dependencies: - '@noble/hashes': 1.7.1 + '@noble/hashes': 1.8.0 outvariant@1.4.3: {} @@ -20666,6 +21891,10 @@ snapshots: dependencies: yocto-queue: 0.1.0 + p-limit@4.0.0: + dependencies: + yocto-queue: 1.2.1 + p-locate@4.1.0: dependencies: p-limit: 2.3.0 @@ -20674,10 +21903,16 @@ snapshots: dependencies: p-limit: 3.1.0 + p-locate@6.0.0: + dependencies: + p-limit: 4.0.0 + p-map@4.0.0: dependencies: aggregate-error: 3.1.0 + p-map@7.0.3: {} + p-queue@6.6.2: dependencies: eventemitter3: 4.0.7 @@ -20689,7 +21924,7 @@ snapshots: p-try@2.2.0: {} - package-json-from-dist@1.0.1: {} + package-json-from-dist@1.0.0: {} parent-module@1.0.1: dependencies: @@ -20697,11 +21932,17 @@ snapshots: parse-json@5.2.0: dependencies: - '@babel/code-frame': 7.27.1 + '@babel/code-frame': 7.24.7 error-ex: 1.3.2 json-parse-even-better-errors: 2.3.1 lines-and-columns: 1.2.4 + parse-json@8.3.0: + dependencies: + '@babel/code-frame': 7.27.1 + index-to-position: 1.2.0 + type-fest: 4.41.0 + parse-ms@4.0.0: {} parse-srcset@1.0.2: {} @@ -20725,7 +21966,7 @@ snapshots: parse5@7.3.0: dependencies: - entities: 6.0.1 + entities: 6.0.0 parseurl@1.3.3: {} @@ -20733,6 +21974,8 @@ snapshots: path-exists@4.0.0: {} + path-exists@5.0.0: {} + path-is-absolute@1.0.1: {} path-key@3.1.1: {} @@ -20748,9 +21991,11 @@ snapshots: path-scurry@2.0.0: dependencies: - lru-cache: 11.1.0 + lru-cache: 11.0.0 minipass: 7.1.2 + path-to-regexp@0.1.10: {} + path-to-regexp@0.1.12: {} path-to-regexp@6.3.0: {} @@ -20767,26 +22012,28 @@ snapshots: dependencies: through: 2.3.8 - peek-readable@5.4.2: {} + peek-readable@5.3.1: {} + + peek-readable@7.0.0: {} pend@1.2.0: {} performance-now@2.1.0: {} - pg-cloudflare@1.2.5: + pg-cloudflare@1.2.7: optional: true - pg-connection-string@2.9.0: {} + pg-connection-string@2.9.1: {} pg-int8@1.0.1: {} - pg-numeric@1.0.2: {} - - pg-pool@3.10.0(pg@8.15.6): + pg-pool@3.10.1(pg@8.16.3): dependencies: - pg: 8.15.6 + pg: 8.16.3 + + pg-protocol@1.10.3: {} - pg-protocol@1.10.0: {} + pg-protocol@1.9.5: {} pg-types@2.2.0: dependencies: @@ -20796,29 +22043,19 @@ snapshots: postgres-date: 1.0.7 postgres-interval: 1.2.0 - pg-types@4.0.2: + pg@8.16.3: dependencies: - pg-int8: 1.0.1 - pg-numeric: 1.0.2 - postgres-array: 3.0.4 - postgres-bytea: 3.0.0 - postgres-date: 2.1.0 - postgres-interval: 3.0.0 - postgres-range: 1.1.4 - - pg@8.15.6: - dependencies: - pg-connection-string: 2.9.0 - pg-pool: 3.10.0(pg@8.15.6) - pg-protocol: 1.10.0 + pg-connection-string: 2.9.1 + pg-pool: 3.10.1(pg@8.16.3) + pg-protocol: 1.10.3 pg-types: 2.2.0 pgpass: 1.0.5 optionalDependencies: - pg-cloudflare: 1.2.5 + pg-cloudflare: 1.2.7 pgpass@1.0.5: dependencies: - split2: 4.2.0 + split2: 4.1.0 photoswipe@5.4.4: {} @@ -20828,37 +22065,40 @@ snapshots: picomatch@4.0.2: {} + picomatch@4.0.3: {} + pid-port@1.0.2: dependencies: execa: 8.0.1 pify@2.3.0: {} - pino-abstract-transport@2.0.0: + pino-abstract-transport@1.2.0: dependencies: - split2: 4.2.0 + readable-stream: 4.3.0 + split2: 4.1.0 pino-std-serializers@7.0.0: {} - pino@9.7.0: + pino@9.3.2: dependencies: atomic-sleep: 1.0.0 - fast-redact: 3.5.0 - on-exit-leak-free: 2.1.2 - pino-abstract-transport: 2.0.0 + fast-redact: 3.1.2 + on-exit-leak-free: 2.1.0 + pino-abstract-transport: 1.2.0 pino-std-serializers: 7.0.0 - process-warning: 5.0.0 + process-warning: 4.0.0 quick-format-unescaped: 4.0.4 real-require: 0.2.0 - safe-stable-stringify: 2.5.0 - sonic-boom: 4.2.0 + safe-stable-stringify: 2.4.2 + sonic-boom: 4.0.1 thread-stream: 3.1.0 - pirates@4.0.7: {} + pirates@4.0.5: {} - piscina@4.9.2: + piscina@4.4.0: optionalDependencies: - '@napi-rs/nice': 1.0.1 + nice-napi: 1.0.2 pkce-challenge@4.1.0: {} @@ -20866,160 +22106,162 @@ snapshots: dependencies: find-up: 4.1.0 - plimit-lit@1.6.1: + plimit-lit@1.5.0: dependencies: - queue-lit: 1.5.2 + queue-lit: 1.5.0 plur@4.0.0: dependencies: irregular-plurals: 3.5.0 + pluralize@8.0.0: {} + pngjs@5.0.0: {} - pnpm@10.10.0: {} + pnpm@10.18.2: {} - polished@4.3.1: + polished@4.2.2: dependencies: - '@babel/runtime': 7.27.6 + '@babel/runtime': 7.27.0 - possible-typed-array-names@1.1.0: {} + possible-typed-array-names@1.0.0: {} - postcss-calc@10.1.1(postcss@8.5.3): + postcss-calc@10.1.1(postcss@8.5.6): dependencies: - postcss: 8.5.3 + postcss: 8.5.6 postcss-selector-parser: 7.1.0 postcss-value-parser: 4.2.0 - postcss-colormin@7.0.3(postcss@8.5.3): + postcss-colormin@7.0.4(postcss@8.5.6): dependencies: - browserslist: 4.25.0 + browserslist: 4.26.3 caniuse-api: 3.0.0 colord: 2.9.3 - postcss: 8.5.3 + postcss: 8.5.6 postcss-value-parser: 4.2.0 - postcss-convert-values@7.0.5(postcss@8.5.3): + postcss-convert-values@7.0.7(postcss@8.5.6): dependencies: - browserslist: 4.25.0 - postcss: 8.5.3 + browserslist: 4.26.3 + postcss: 8.5.6 postcss-value-parser: 4.2.0 - postcss-discard-comments@7.0.4(postcss@8.5.3): + postcss-discard-comments@7.0.4(postcss@8.5.6): dependencies: - postcss: 8.5.3 + postcss: 8.5.6 postcss-selector-parser: 7.1.0 - postcss-discard-duplicates@7.0.2(postcss@8.5.3): + postcss-discard-duplicates@7.0.2(postcss@8.5.6): dependencies: - postcss: 8.5.3 + postcss: 8.5.6 - postcss-discard-empty@7.0.1(postcss@8.5.3): + postcss-discard-empty@7.0.1(postcss@8.5.6): dependencies: - postcss: 8.5.3 + postcss: 8.5.6 - postcss-discard-overridden@7.0.1(postcss@8.5.3): + postcss-discard-overridden@7.0.1(postcss@8.5.6): dependencies: - postcss: 8.5.3 + postcss: 8.5.6 - postcss-merge-longhand@7.0.5(postcss@8.5.3): + postcss-merge-longhand@7.0.5(postcss@8.5.6): dependencies: - postcss: 8.5.3 + postcss: 8.5.6 postcss-value-parser: 4.2.0 - stylehacks: 7.0.5(postcss@8.5.3) + stylehacks: 7.0.6(postcss@8.5.6) - postcss-merge-rules@7.0.5(postcss@8.5.3): + postcss-merge-rules@7.0.6(postcss@8.5.6): dependencies: - browserslist: 4.25.0 + browserslist: 4.26.3 caniuse-api: 3.0.0 - cssnano-utils: 5.0.1(postcss@8.5.3) - postcss: 8.5.3 + cssnano-utils: 5.0.1(postcss@8.5.6) + postcss: 8.5.6 postcss-selector-parser: 7.1.0 - postcss-minify-font-values@7.0.1(postcss@8.5.3): + postcss-minify-font-values@7.0.1(postcss@8.5.6): dependencies: - postcss: 8.5.3 + postcss: 8.5.6 postcss-value-parser: 4.2.0 - postcss-minify-gradients@7.0.1(postcss@8.5.3): + postcss-minify-gradients@7.0.1(postcss@8.5.6): dependencies: colord: 2.9.3 - cssnano-utils: 5.0.1(postcss@8.5.3) - postcss: 8.5.3 + cssnano-utils: 5.0.1(postcss@8.5.6) + postcss: 8.5.6 postcss-value-parser: 4.2.0 - postcss-minify-params@7.0.3(postcss@8.5.3): + postcss-minify-params@7.0.4(postcss@8.5.6): dependencies: - browserslist: 4.25.0 - cssnano-utils: 5.0.1(postcss@8.5.3) - postcss: 8.5.3 + browserslist: 4.26.3 + cssnano-utils: 5.0.1(postcss@8.5.6) + postcss: 8.5.6 postcss-value-parser: 4.2.0 - postcss-minify-selectors@7.0.5(postcss@8.5.3): + postcss-minify-selectors@7.0.5(postcss@8.5.6): dependencies: cssesc: 3.0.0 - postcss: 8.5.3 + postcss: 8.5.6 postcss-selector-parser: 7.1.0 - postcss-normalize-charset@7.0.1(postcss@8.5.3): + postcss-normalize-charset@7.0.1(postcss@8.5.6): dependencies: - postcss: 8.5.3 + postcss: 8.5.6 - postcss-normalize-display-values@7.0.1(postcss@8.5.3): + postcss-normalize-display-values@7.0.1(postcss@8.5.6): dependencies: - postcss: 8.5.3 + postcss: 8.5.6 postcss-value-parser: 4.2.0 - postcss-normalize-positions@7.0.1(postcss@8.5.3): + postcss-normalize-positions@7.0.1(postcss@8.5.6): dependencies: - postcss: 8.5.3 + postcss: 8.5.6 postcss-value-parser: 4.2.0 - postcss-normalize-repeat-style@7.0.1(postcss@8.5.3): + postcss-normalize-repeat-style@7.0.1(postcss@8.5.6): dependencies: - postcss: 8.5.3 + postcss: 8.5.6 postcss-value-parser: 4.2.0 - postcss-normalize-string@7.0.1(postcss@8.5.3): + postcss-normalize-string@7.0.1(postcss@8.5.6): dependencies: - postcss: 8.5.3 + postcss: 8.5.6 postcss-value-parser: 4.2.0 - postcss-normalize-timing-functions@7.0.1(postcss@8.5.3): + postcss-normalize-timing-functions@7.0.1(postcss@8.5.6): dependencies: - postcss: 8.5.3 + postcss: 8.5.6 postcss-value-parser: 4.2.0 - postcss-normalize-unicode@7.0.3(postcss@8.5.3): + postcss-normalize-unicode@7.0.4(postcss@8.5.6): dependencies: - browserslist: 4.25.0 - postcss: 8.5.3 + browserslist: 4.26.3 + postcss: 8.5.6 postcss-value-parser: 4.2.0 - postcss-normalize-url@7.0.1(postcss@8.5.3): + postcss-normalize-url@7.0.1(postcss@8.5.6): dependencies: - postcss: 8.5.3 + postcss: 8.5.6 postcss-value-parser: 4.2.0 - postcss-normalize-whitespace@7.0.1(postcss@8.5.3): + postcss-normalize-whitespace@7.0.1(postcss@8.5.6): dependencies: - postcss: 8.5.3 + postcss: 8.5.6 postcss-value-parser: 4.2.0 - postcss-ordered-values@7.0.2(postcss@8.5.3): + postcss-ordered-values@7.0.2(postcss@8.5.6): dependencies: - cssnano-utils: 5.0.1(postcss@8.5.3) - postcss: 8.5.3 + cssnano-utils: 5.0.1(postcss@8.5.6) + postcss: 8.5.6 postcss-value-parser: 4.2.0 - postcss-reduce-initial@7.0.3(postcss@8.5.3): + postcss-reduce-initial@7.0.4(postcss@8.5.6): dependencies: - browserslist: 4.25.0 + browserslist: 4.26.3 caniuse-api: 3.0.0 - postcss: 8.5.3 + postcss: 8.5.6 - postcss-reduce-transforms@7.0.1(postcss@8.5.3): + postcss-reduce-transforms@7.0.1(postcss@8.5.6): dependencies: - postcss: 8.5.3 + postcss: 8.5.6 postcss-value-parser: 4.2.0 postcss-selector-parser@6.1.2: @@ -21032,20 +22274,20 @@ snapshots: cssesc: 3.0.0 util-deprecate: 1.0.2 - postcss-svgo@7.0.2(postcss@8.5.3): + postcss-svgo@7.1.0(postcss@8.5.6): dependencies: - postcss: 8.5.3 + postcss: 8.5.6 postcss-value-parser: 4.2.0 - svgo: 3.3.2 + svgo: 4.0.0 - postcss-unique-selectors@7.0.4(postcss@8.5.3): + postcss-unique-selectors@7.0.4(postcss@8.5.6): dependencies: - postcss: 8.5.3 + postcss: 8.5.6 postcss-selector-parser: 7.1.0 postcss-value-parser@4.2.0: {} - postcss@8.5.3: + postcss@8.5.6: dependencies: nanoid: 3.3.11 picocolors: 1.1.1 @@ -21053,31 +22295,19 @@ snapshots: postgres-array@2.0.0: {} - postgres-array@3.0.4: {} - postgres-bytea@1.0.0: {} - postgres-bytea@3.0.0: - dependencies: - obuf: 1.1.2 - postgres-date@1.0.7: {} - postgres-date@2.1.0: {} - postgres-interval@1.2.0: dependencies: xtend: 4.0.2 - postgres-interval@3.0.0: {} - - postgres-range@1.1.4: {} - prelude-ls@1.1.2: {} prelude-ls@1.2.1: {} - prettier@3.5.3: {} + prettier@3.6.2: {} pretty-bytes@5.6.0: {} @@ -21091,13 +22321,13 @@ snapshots: dependencies: '@jest/schemas': 29.6.3 ansi-styles: 5.2.0 - react-is: 18.3.1 + react-is: 18.2.0 pretty-ms@9.2.0: dependencies: parse-ms: 4.0.0 - prismjs@1.29.0: {} + prismjs@1.30.0: {} private-ip@3.0.2: dependencies: @@ -21114,7 +22344,7 @@ snapshots: transitivePeerDependencies: - supports-color - proc-log@4.2.0: {} + proc-log@5.0.0: {} process-exists@5.0.0: dependencies: @@ -21122,7 +22352,7 @@ snapshots: process-nextick-args@2.0.1: {} - process-warning@4.0.1: {} + process-warning@4.0.0: {} process-warning@5.0.0: {} @@ -21133,8 +22363,6 @@ snapshots: promise-limit@2.7.0: {} - promise-polyfill@8.3.0: {} - promise-retry@2.0.1: dependencies: err-code: 2.0.3 @@ -21149,44 +22377,29 @@ snapshots: kleur: 3.0.3 sisteransi: 1.0.5 - property-information@7.1.0: {} + property-information@7.0.0: {} proto-list@1.2.4: {} proto3-json-serializer@1.1.1: dependencies: - protobufjs: 7.2.4 + protobufjs: 7.2.3 - protobufjs-cli@1.1.1(protobufjs@7.2.4): + protobufjs-cli@1.1.1(protobufjs@7.2.3): dependencies: chalk: 4.1.2 escodegen: 1.14.3 espree: 9.6.1 estraverse: 5.3.0 glob: 8.1.0 - jsdoc: 4.0.4 + jsdoc: 4.0.2 minimist: 1.2.8 - protobufjs: 7.2.4 - semver: 7.7.1 - tmp: 0.2.3 - uglify-js: 3.19.3 - - protobufjs@7.2.4: - 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': 22.15.2 - long: 5.3.2 + protobufjs: 7.2.3 + semver: 7.7.3 + tmp: 0.2.5 + uglify-js: 3.17.4 - protobufjs@7.5.3: + protobufjs@7.2.3: dependencies: '@protobufjs/aspromise': 1.1.2 '@protobufjs/base64': 1.1.2 @@ -21198,8 +22411,8 @@ snapshots: '@protobufjs/path': 1.1.2 '@protobufjs/pool': 1.1.0 '@protobufjs/utf8': 1.1.0 - '@types/node': 22.15.2 - long: 5.3.2 + '@types/node': 24.9.1 + long: 5.2.3 proxy-addr@2.0.7: dependencies: @@ -21216,10 +22429,6 @@ snapshots: dependencies: event-stream: 3.3.4 - psl@1.15.0: - dependencies: - punycode: 2.3.1 - pstree.remy@1.1.8: {} pug-attrs@3.0.0: @@ -21239,25 +22448,27 @@ snapshots: void-elements: 3.1.0 with: 7.0.2 + pug-error@2.0.0: {} + pug-error@2.1.0: {} pug-filters@4.0.0: dependencies: constantinople: 4.0.1 jstransformer: 1.0.0 - pug-error: 2.1.0 + pug-error: 2.0.0 pug-walk: 2.0.0 - resolve: 1.22.10 + resolve: 1.22.8 pug-lexer@5.0.1: dependencies: character-parser: 2.2.0 is-expression: 4.0.0 - pug-error: 2.1.0 + pug-error: 2.0.0 pug-linker@4.0.0: dependencies: - pug-error: 2.1.0 + pug-error: 2.0.0 pug-walk: 2.0.0 pug-load@3.0.0: @@ -21267,14 +22478,14 @@ snapshots: pug-parser@6.0.0: dependencies: - pug-error: 2.1.0 + pug-error: 2.0.0 token-stream: 1.0.0 pug-runtime@3.0.1: {} pug-strip-comments@2.0.0: dependencies: - pug-error: 2.1.0 + pug-error: 2.0.0 pug-walk@2.0.0: {} @@ -21289,57 +22500,59 @@ snapshots: pug-runtime: 3.0.1 pug-strip-comments: 2.0.0 - pump@3.0.2: + pump@3.0.0: dependencies: end-of-stream: 1.4.4 once: 1.4.0 pumpify@2.0.1: dependencies: - duplexify: 4.1.3 + duplexify: 4.1.2 inherits: 2.0.4 - pump: 3.0.2 + pump: 3.0.0 punycode.js@2.3.1: {} - punycode@1.4.1: {} - punycode@2.3.1: {} - pure-rand@6.1.0: {} + pure-rand@6.0.0: {} - pvtsutils@1.3.6: + pvtsutils@1.3.5: dependencies: tslib: 2.8.1 pvutils@1.1.3: {} - qrcode-generator@1.5.0: {} + qr-code-styling@1.9.2: + dependencies: + qrcode-generator: 1.4.4 - qrcode-vue3@1.7.1: + qr-scanner@1.4.2: dependencies: - qrcode-generator: 1.5.0 + '@types/offscreencanvas': 2019.7.0 + + qrcode-generator@1.4.4: {} qrcode@1.5.4: dependencies: - dijkstrajs: 1.0.3 + dijkstrajs: 1.0.2 pngjs: 5.0.0 yargs: 15.4.1 qs@6.13.0: dependencies: - side-channel: 1.1.0 + side-channel: 1.0.6 qs@6.14.0: dependencies: side-channel: 1.1.0 - querystringify@2.2.0: {} - - queue-lit@1.5.2: {} + queue-lit@1.5.0: {} queue-microtask@1.2.3: {} + queue-tick@1.0.1: {} + quick-format-unescaped@4.0.4: {} quick-lru@4.0.1: {} @@ -21374,43 +22587,43 @@ snapshots: dependencies: setimmediate: 1.0.5 - re2@1.21.4: + re2@1.22.1: dependencies: install-artifact-from-github: 1.4.0 - nan: 2.22.2 - node-gyp: 10.3.1 + nan: 2.23.0 + node-gyp: 11.4.2 transitivePeerDependencies: - supports-color - react-docgen-typescript@2.4.0(typescript@5.8.3): + react-docgen-typescript@2.2.2(typescript@5.9.3): dependencies: - typescript: 5.8.3 + typescript: 5.9.3 - react-docgen@7.1.1: + react-docgen@8.0.2: dependencies: - '@babel/core': 7.27.4 - '@babel/traverse': 7.27.4 - '@babel/types': 7.27.6 + '@babel/core': 7.28.4 + '@babel/traverse': 7.28.4 + '@babel/types': 7.28.4 '@types/babel__core': 7.20.5 - '@types/babel__traverse': 7.20.7 + '@types/babel__traverse': 7.28.0 '@types/doctrine': 0.0.9 - '@types/resolve': 1.20.6 + '@types/resolve': 1.20.3 doctrine: 3.0.0 - resolve: 1.22.10 + resolve: 1.22.8 strip-indent: 4.0.0 transitivePeerDependencies: - supports-color - react-dom@19.1.0(react@19.1.0): + react-dom@19.2.0(react@19.2.0): dependencies: - react: 19.1.0 - scheduler: 0.26.0 + react: 19.2.0 + scheduler: 0.27.0 react-is@17.0.2: {} - react-is@18.3.1: {} + react-is@18.2.0: {} - react@19.1.0: {} + react@19.2.0: {} read-pkg-up@7.0.1: dependencies: @@ -21420,12 +22633,12 @@ snapshots: read-pkg@5.2.0: dependencies: - '@types/normalize-package-data': 2.4.4 + '@types/normalize-package-data': 2.4.1 normalize-package-data: 2.5.0 parse-json: 5.2.0 type-fest: 0.6.0 - readable-stream@2.3.8: + readable-stream@2.3.7: dependencies: core-util-is: 1.0.3 inherits: 2.0.4 @@ -21435,29 +22648,28 @@ snapshots: string_decoder: 1.1.1 util-deprecate: 1.0.2 - readable-stream@3.6.2: + readable-stream@3.6.0: dependencies: inherits: 2.0.4 string_decoder: 1.3.0 util-deprecate: 1.0.2 - readable-stream@4.7.0: + readable-stream@4.3.0: dependencies: abort-controller: 3.0.0 buffer: 6.0.3 events: 3.3.0 process: 0.11.10 - string_decoder: 1.3.0 - readdir-glob@1.1.3: + readdir-glob@1.1.2: dependencies: - minimatch: 5.1.6 + minimatch: 5.1.2 readdirp@4.1.2: {} real-require@0.2.0: {} - recast@0.23.11: + recast@0.23.7: dependencies: ast-types: 0.16.1 esprima: 4.0.1 @@ -21499,7 +22711,7 @@ snapshots: regenerator-runtime@0.13.11: {} - regenerator-runtime@0.14.1: {} + regenerator-runtime@0.14.0: {} regex-recursion@6.0.2: dependencies: @@ -21511,6 +22723,19 @@ snapshots: dependencies: regex-utilities: 2.3.0 + regexp.prototype.flags@1.5.0: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + functions-have-names: 1.2.3 + + regexp.prototype.flags@1.5.2: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-errors: 1.3.0 + set-function-name: 2.0.2 + regexp.prototype.flags@1.5.4: dependencies: call-bind: 1.0.8 @@ -21520,31 +22745,31 @@ snapshots: gopd: 1.2.0 set-function-name: 2.0.2 - remark-gfm@4.0.1: + remark-gfm@4.0.0: dependencies: - '@types/mdast': 4.0.4 - mdast-util-gfm: 3.1.0 + '@types/mdast': 4.0.3 + mdast-util-gfm: 3.0.0 micromark-extension-gfm: 3.0.0 remark-parse: 11.0.0 remark-stringify: 11.0.0 - unified: 11.0.5 + unified: 11.0.4 transitivePeerDependencies: - supports-color remark-parse@11.0.0: dependencies: - '@types/mdast': 4.0.4 - mdast-util-from-markdown: 2.0.2 - micromark-util-types: 2.0.2 - unified: 11.0.5 + '@types/mdast': 4.0.3 + mdast-util-from-markdown: 2.0.0 + micromark-util-types: 2.0.0 + unified: 11.0.4 transitivePeerDependencies: - supports-color remark-stringify@11.0.0: dependencies: - '@types/mdast': 4.0.4 - mdast-util-to-markdown: 2.1.2 - unified: 11.0.5 + '@types/mdast': 4.0.3 + mdast-util-to-markdown: 2.1.0 + unified: 11.0.4 rename@1.0.4: dependencies: @@ -21554,17 +22779,17 @@ snapshots: request-progress@3.0.0: dependencies: - throttleit: 1.0.1 + throttleit: 1.0.0 require-directory@2.1.1: {} require-from-string@2.0.2: {} - require-in-the-middle@7.5.2: + require-in-the-middle@7.3.0: dependencies: - debug: 4.4.1(supports-color@5.5.0) - module-details-from-path: 1.0.4 - resolve: 1.22.10 + debug: 4.4.3(supports-color@8.1.1) + module-details-from-path: 1.0.3 + resolve: 1.22.8 transitivePeerDependencies: - supports-color @@ -21572,8 +22797,6 @@ snapshots: requireindex@1.2.0: {} - requires-port@1.0.0: {} - requizzle@0.2.4: dependencies: lodash: 4.17.21 @@ -21590,11 +22813,11 @@ snapshots: resolve-pkg-maps@1.0.0: {} - resolve.exports@2.0.3: {} + resolve.exports@2.0.0: {} - resolve@1.22.10: + resolve@1.22.8: dependencies: - is-core-module: 2.16.1 + is-core-module: 2.15.1 path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 @@ -21602,6 +22825,10 @@ snapshots: dependencies: lowercase-keys: 3.0.0 + responselike@4.0.2: + dependencies: + lowercase-keys: 3.0.0 + restore-cursor@3.1.0: dependencies: onetime: 5.1.2 @@ -21611,14 +22838,16 @@ snapshots: retry-request@5.0.2: dependencies: - debug: 4.4.1(supports-color@5.5.0) + debug: 4.4.3(supports-color@8.1.1) extend: 3.0.2 transitivePeerDependencies: - supports-color retry@0.12.0: {} - reusify@1.1.0: {} + rettime@0.7.0: {} + + reusify@1.0.4: {} rfdc@1.4.1: {} @@ -21632,30 +22861,36 @@ snapshots: glob: 7.2.3 optional: true - rollup@4.40.0: + rimraf@5.0.10: dependencies: - '@types/estree': 1.0.7 + glob: 10.4.5 + + rollup@4.52.4: + dependencies: + '@types/estree': 1.0.8 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.40.0 - '@rollup/rollup-android-arm64': 4.40.0 - '@rollup/rollup-darwin-arm64': 4.40.0 - '@rollup/rollup-darwin-x64': 4.40.0 - '@rollup/rollup-freebsd-arm64': 4.40.0 - '@rollup/rollup-freebsd-x64': 4.40.0 - '@rollup/rollup-linux-arm-gnueabihf': 4.40.0 - '@rollup/rollup-linux-arm-musleabihf': 4.40.0 - '@rollup/rollup-linux-arm64-gnu': 4.40.0 - '@rollup/rollup-linux-arm64-musl': 4.40.0 - '@rollup/rollup-linux-loongarch64-gnu': 4.40.0 - '@rollup/rollup-linux-powerpc64le-gnu': 4.40.0 - '@rollup/rollup-linux-riscv64-gnu': 4.40.0 - '@rollup/rollup-linux-riscv64-musl': 4.40.0 - '@rollup/rollup-linux-s390x-gnu': 4.40.0 - '@rollup/rollup-linux-x64-gnu': 4.40.0 - '@rollup/rollup-linux-x64-musl': 4.40.0 - '@rollup/rollup-win32-arm64-msvc': 4.40.0 - '@rollup/rollup-win32-ia32-msvc': 4.40.0 - '@rollup/rollup-win32-x64-msvc': 4.40.0 + '@rollup/rollup-android-arm-eabi': 4.52.4 + '@rollup/rollup-android-arm64': 4.52.4 + '@rollup/rollup-darwin-arm64': 4.52.4 + '@rollup/rollup-darwin-x64': 4.52.4 + '@rollup/rollup-freebsd-arm64': 4.52.4 + '@rollup/rollup-freebsd-x64': 4.52.4 + '@rollup/rollup-linux-arm-gnueabihf': 4.52.4 + '@rollup/rollup-linux-arm-musleabihf': 4.52.4 + '@rollup/rollup-linux-arm64-gnu': 4.52.4 + '@rollup/rollup-linux-arm64-musl': 4.52.4 + '@rollup/rollup-linux-loong64-gnu': 4.52.4 + '@rollup/rollup-linux-ppc64-gnu': 4.52.4 + '@rollup/rollup-linux-riscv64-gnu': 4.52.4 + '@rollup/rollup-linux-riscv64-musl': 4.52.4 + '@rollup/rollup-linux-s390x-gnu': 4.52.4 + '@rollup/rollup-linux-x64-gnu': 4.52.4 + '@rollup/rollup-linux-x64-musl': 4.52.4 + '@rollup/rollup-openharmony-arm64': 4.52.4 + '@rollup/rollup-win32-arm64-msvc': 4.52.4 + '@rollup/rollup-win32-ia32-msvc': 4.52.4 + '@rollup/rollup-win32-x64-gnu': 4.52.4 + '@rollup/rollup-win32-x64-msvc': 4.52.4 fsevents: 2.3.3 rrweb-cssom@0.8.0: {} @@ -21673,6 +22908,13 @@ snapshots: dependencies: tslib: 2.8.1 + safe-array-concat@1.1.2: + dependencies: + call-bind: 1.0.7 + get-intrinsic: 1.3.0 + has-symbols: 1.1.0 + isarray: 2.0.5 + safe-array-concat@1.1.3: dependencies: call-bind: 1.0.8 @@ -21690,44 +22932,52 @@ snapshots: es-errors: 1.3.0 isarray: 2.0.5 + safe-regex-test@1.0.3: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-regex: 1.1.4 + safe-regex-test@1.1.0: dependencies: call-bound: 1.0.4 es-errors: 1.3.0 is-regex: 1.2.1 - safe-regex2@5.0.0: + safe-regex2@4.0.0: dependencies: ret: 0.5.0 - safe-stable-stringify@2.5.0: {} + safe-stable-stringify@2.4.2: {} safer-buffer@2.1.2: {} - sanitize-html@2.16.0: + sanitize-html@2.17.0: dependencies: - deepmerge: 4.3.1 + deepmerge: 4.2.2 escape-string-regexp: 4.0.0 - htmlparser2: 8.0.2 + htmlparser2: 8.0.1 is-plain-object: 5.0.0 parse-srcset: 1.0.2 - postcss: 8.5.3 + postcss: 8.5.6 - sass@1.87.0: + sass@1.93.2: dependencies: chokidar: 4.0.3 - immutable: 5.1.3 + immutable: 5.0.3 source-map-js: 1.2.1 optionalDependencies: '@parcel/watcher': 2.5.1 + sax@1.2.4: {} + sax@1.4.1: {} saxes@6.0.0: dependencies: xmlchars: 2.2.0 - scheduler@0.26.0: {} + scheduler@0.27.0: {} secure-json-parse@2.7.0: {} @@ -21745,9 +22995,9 @@ snapshots: semver-truncate@3.0.0: dependencies: - semver: 7.7.1 + semver: 7.7.3 - semver@5.7.2: {} + semver@5.7.1: {} semver@6.3.1: {} @@ -21755,7 +23005,7 @@ snapshots: dependencies: lru-cache: 6.0.0 - semver@7.7.1: {} + semver@7.7.3: {} send@0.19.0: dependencies: @@ -21786,7 +23036,7 @@ snapshots: set-blocking@2.0.0: {} - set-cookie-parser@2.7.1: {} + set-cookie-parser@2.6.0: {} set-function-length@1.2.2: dependencies: @@ -21814,16 +23064,17 @@ snapshots: setprototypeof@1.2.0: {} - sha.js@2.4.11: + sha.js@2.4.12: dependencies: inherits: 2.0.4 safe-buffer: 5.2.1 + to-buffer: 1.2.2 sharp@0.33.5: dependencies: color: 4.2.3 - detect-libc: 2.0.4 - semver: 7.7.1 + detect-libc: 2.0.3 + semver: 7.7.3 optionalDependencies: '@img/sharp-darwin-arm64': 0.33.5 '@img/sharp-darwin-x64': 0.33.5 @@ -21851,14 +23102,14 @@ snapshots: shebang-regex@3.0.0: {} - shiki@3.3.0: + shiki@3.13.0: dependencies: - '@shikijs/core': 3.3.0 - '@shikijs/engine-javascript': 3.3.0 - '@shikijs/engine-oniguruma': 3.3.0 - '@shikijs/langs': 3.3.0 - '@shikijs/themes': 3.3.0 - '@shikijs/types': 3.3.0 + '@shikijs/core': 3.13.0 + '@shikijs/engine-javascript': 3.13.0 + '@shikijs/engine-oniguruma': 3.13.0 + '@shikijs/langs': 3.13.0 + '@shikijs/themes': 3.13.0 + '@shikijs/types': 3.13.0 '@shikijs/vscode-textmate': 10.0.2 '@types/hast': 3.0.4 @@ -21884,6 +23135,19 @@ snapshots: object-inspect: 1.13.4 side-channel-map: 1.0.1 + side-channel@1.0.4: + dependencies: + call-bind: 1.0.7 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + + side-channel@1.0.6: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + get-intrinsic: 1.2.7 + object-inspect: 1.13.2 + side-channel@1.1.0: dependencies: es-errors: 1.3.0 @@ -21900,10 +23164,10 @@ snapshots: simple-oauth2@5.1.0: dependencies: - '@hapi/hoek': 11.0.7 - '@hapi/wreck': 18.1.0 - debug: 4.4.1(supports-color@5.5.0) - joi: 17.13.3 + '@hapi/hoek': 11.0.4 + '@hapi/wreck': 18.0.1 + debug: 4.3.5 + joi: 17.11.0 transitivePeerDependencies: - supports-color @@ -21913,13 +23177,13 @@ snapshots: simple-update-notifier@2.0.0: dependencies: - semver: 7.7.1 + semver: 7.7.3 sinon@18.0.1: dependencies: '@sinonjs/commons': 3.0.1 '@sinonjs/fake-timers': 11.2.2 - '@sinonjs/samsam': 8.0.2 + '@sinonjs/samsam': 8.0.0 diff: 5.2.0 nise: 6.1.1 supports-color: 7.2.0 @@ -22002,17 +23266,17 @@ snapshots: socks-proxy-agent@8.0.5: dependencies: agent-base: 7.1.3 - debug: 4.4.1(supports-color@5.5.0) - socks: 2.8.5 + debug: 4.4.3(supports-color@8.1.1) + socks: 2.8.7 transitivePeerDependencies: - supports-color - socks@2.8.5: + socks@2.8.7: dependencies: - ip-address: 9.0.5 + ip-address: 10.0.1 smart-buffer: 4.2.0 - sonic-boom@4.2.0: + sonic-boom@4.0.1: dependencies: atomic-sleep: 1.0.0 @@ -22044,21 +23308,21 @@ snapshots: space-separated-tokens@2.0.2: {} - spdx-correct@3.2.0: + spdx-correct@3.1.1: dependencies: spdx-expression-parse: 3.0.1 - spdx-license-ids: 3.0.21 + spdx-license-ids: 3.0.12 - spdx-exceptions@2.5.0: {} + spdx-exceptions@2.3.0: {} spdx-expression-parse@3.0.1: dependencies: - spdx-exceptions: 2.5.0 - spdx-license-ids: 3.0.21 + spdx-exceptions: 2.3.0 + spdx-license-ids: 3.0.12 - spdx-license-ids@3.0.21: {} + spdx-license-ids@3.0.12: {} - split2@4.2.0: {} + split2@4.1.0: {} split@0.3.3: dependencies: @@ -22068,7 +23332,19 @@ snapshots: sprintf-js@1.1.3: {} - sql-highlight@6.1.0: {} + sql-highlight@6.0.0: {} + + sshpk@1.17.0: + dependencies: + asn1: 0.2.6 + assert-plus: 1.0.0 + bcrypt-pbkdf: 1.0.2 + dashdash: 1.14.1 + ecc-jsbn: 0.1.2 + getpass: 0.1.7 + jsbn: 0.1.1 + safer-buffer: 2.1.2 + tweetnacl: 0.14.5 sshpk@1.18.0: dependencies: @@ -22082,7 +23358,7 @@ snapshots: safer-buffer: 2.1.2 tweetnacl: 0.14.5 - ssri@10.0.6: + ssri@12.0.0: dependencies: minipass: 7.1.2 @@ -22094,16 +23370,16 @@ snapshots: standard-as-callback@2.1.0: {} - start-server-and-test@2.0.11: + start-server-and-test@2.1.2: dependencies: arg: 5.0.2 bluebird: 3.7.2 check-more-types: 2.24.0 - debug: 4.4.0 + debug: 4.4.3(supports-color@8.1.1) execa: 5.1.1 lazy-ass: 1.6.0 ps-tree: 1.2.0 - wait-on: 8.0.3(debug@4.4.0) + wait-on: 8.0.5(debug@4.4.3) transitivePeerDependencies: - supports-color @@ -22113,38 +23389,56 @@ snapshots: std-env@3.9.0: {} + stop-iteration-iterator@1.0.0: + dependencies: + internal-slot: 1.0.7 + stop-iteration-iterator@1.1.0: dependencies: es-errors: 1.3.0 internal-slot: 1.1.0 - storybook-addon-misskey-theme@https://codeload.github.com/misskey-dev/storybook-addon-misskey-theme/tar.gz/cf583db098365b2ccc81a82f63ca9c93bc32b640(@storybook/blocks@8.6.12(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5)))(@storybook/components@8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5)))(@storybook/core-events@8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5)))(@storybook/manager-api@8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5)))(@storybook/preview-api@8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5)))(@storybook/theming@8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5)))(@storybook/types@8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5)))(react-dom@19.1.0(react@19.1.0))(react@19.1.0): + storybook-addon-misskey-theme@https://codeload.github.com/misskey-dev/storybook-addon-misskey-theme/tar.gz/cf583db098365b2ccc81a82f63ca9c93bc32b640(8592f997fbe36bffac29bb2d9605c63c): dependencies: - '@storybook/blocks': 8.6.12(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5)) - '@storybook/components': 8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5)) - '@storybook/core-events': 8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5)) - '@storybook/manager-api': 8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5)) - '@storybook/preview-api': 8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5)) - '@storybook/theming': 8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5)) - '@storybook/types': 8.6.12(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5)) + '@storybook/blocks': 8.6.14(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(storybook@9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6))) + '@storybook/components': 8.6.14(storybook@9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6))) + '@storybook/core-events': 8.6.14(storybook@9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6))) + '@storybook/manager-api': 8.6.14(storybook@9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6))) + '@storybook/preview-api': 8.6.14(storybook@9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6))) + '@storybook/theming': 8.6.14(storybook@9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6))) + '@storybook/types': 8.6.14(storybook@9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6))) optionalDependencies: - react: 19.1.0 - react-dom: 19.1.0(react@19.1.0) + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) - storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5): + storybook@9.1.10(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(prettier@3.6.2)(utf-8-validate@6.0.5)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)): dependencies: - '@storybook/core': 8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(storybook@8.6.12(bufferutil@4.0.9)(prettier@3.5.3)(utf-8-validate@6.0.5))(utf-8-validate@6.0.5) + '@storybook/global': 5.0.0 + '@testing-library/jest-dom': 6.9.1 + '@testing-library/user-event': 14.6.1(@testing-library/dom@10.4.0) + '@vitest/expect': 3.2.4 + '@vitest/mocker': 3.2.4(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)) + '@vitest/spy': 3.2.4 + better-opn: 3.0.2 + esbuild: 0.25.10 + esbuild-register: 3.5.0(esbuild@0.25.10) + recast: 0.23.7 + semver: 7.7.3 + ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@6.0.5) optionalDependencies: - prettier: 3.5.3 + prettier: 3.6.2 transitivePeerDependencies: + - '@testing-library/dom' - bufferutil + - msw - supports-color - utf-8-validate + - vite stream-browserify@3.0.0: dependencies: inherits: 2.0.4 - readable-stream: 3.6.2 + readable-stream: 3.6.0 stream-combiner@0.0.4: dependencies: @@ -22160,22 +23454,20 @@ snapshots: transitivePeerDependencies: - supports-color - stream-shift@1.0.3: {} + stream-shift@1.0.1: {} streamsearch@1.1.0: {} - streamx@2.22.1: + streamx@2.15.0: dependencies: - fast-fifo: 1.3.2 - text-decoder: 1.2.3 - optionalDependencies: - bare-events: 2.5.4 + fast-fifo: 1.3.0 + queue-tick: 1.0.1 strict-event-emitter-types@2.0.0: {} strict-event-emitter@0.5.1: {} - string-argv@0.3.2: {} + string-argv@0.3.1: {} string-length@4.0.2: dependencies: @@ -22204,6 +23496,13 @@ snapshots: es-object-atoms: 1.1.1 has-property-descriptors: 1.0.2 + string.prototype.trim@1.2.9: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-object-atoms: 1.1.1 + string.prototype.trimend@1.0.9: dependencies: call-bind: 1.0.8 @@ -22240,7 +23539,7 @@ snapshots: strip-ansi@7.1.0: dependencies: - ansi-regex: 6.1.0 + ansi-regex: 6.0.1 strip-bom@3.0.0: {} @@ -22267,32 +23566,39 @@ snapshots: strip-json-comments@3.1.1: {} - strnum@1.1.2: {} + strip-literal@3.1.0: + dependencies: + js-tokens: 9.0.1 + + strnum@1.0.5: {} - strtok3@10.3.1: + strnum@2.1.1: {} + + strtok3@10.2.2: dependencies: '@tokenizer/token': 0.3.0 + peek-readable: 7.0.0 - strtok3@9.1.1: + strtok3@9.0.1: dependencies: '@tokenizer/token': 0.3.0 - peek-readable: 5.4.2 + peek-readable: 5.3.1 stubs@3.0.0: {} - stylehacks@7.0.5(postcss@8.5.3): + stylehacks@7.0.6(postcss@8.5.6): dependencies: - browserslist: 4.25.0 - postcss: 8.5.3 + browserslist: 4.26.3 + postcss: 8.5.6 postcss-selector-parser: 7.1.0 - superagent@9.0.2: + superagent@10.2.3: dependencies: component-emitter: 1.3.1 cookiejar: 2.1.4 - debug: 4.4.1(supports-color@5.5.0) + debug: 4.4.0(supports-color@5.5.0) fast-safe-stringify: 2.1.1 - form-data: 4.0.2 + form-data: 4.0.4 formidable: 3.5.4 methods: 1.1.2 mime: 2.6.0 @@ -22300,13 +23606,15 @@ snapshots: transitivePeerDependencies: - supports-color - supertest@7.1.0: + supertest@7.1.4: dependencies: methods: 1.1.2 - superagent: 9.0.2 + superagent: 10.2.3 transitivePeerDependencies: - supports-color + supports-color@10.2.2: {} + supports-color@5.5.0: dependencies: has-flag: 3.0.0 @@ -22319,8 +23627,6 @@ snapshots: dependencies: has-flag: 4.0.0 - supports-color@9.4.0: {} - supports-hyperlinks@2.3.0: dependencies: has-flag: 4.0.0 @@ -22328,25 +23634,33 @@ snapshots: supports-preserve-symlinks-flag@1.0.0: {} - svgo@3.3.2: + svgo@4.0.0: dependencies: - '@trysound/sax': 0.2.0 - commander: 7.2.0 + commander: 11.1.0 css-select: 5.1.0 - css-tree: 2.3.1 + css-tree: 3.1.0 css-what: 6.1.0 csso: 5.0.5 picocolors: 1.1.1 + sax: 1.4.1 symbol-tree@3.2.4: {} - systeminformation@5.25.11: {} + systeminformation@5.27.11: {} + + systeminformation@5.27.7: {} + + tar-stream@3.1.6: + dependencies: + b4a: 1.6.4 + fast-fifo: 1.3.0 + streamx: 2.15.0 tar-stream@3.1.7: dependencies: - b4a: 1.6.7 - fast-fifo: 1.3.2 - streamx: 2.22.1 + b4a: 1.6.4 + fast-fifo: 1.3.0 + streamx: 2.15.0 tar@6.2.1: dependencies: @@ -22356,14 +23670,14 @@ snapshots: minizlib: 2.1.2 mkdirp: 1.0.4 yallist: 4.0.0 + optional: true - tar@7.4.3: + tar@7.5.1: dependencies: '@isaacs/fs-minipass': 4.0.1 chownr: 3.0.0 minipass: 7.1.2 - minizlib: 3.0.2 - mkdirp: 3.0.1 + minizlib: 3.1.0 yallist: 5.0.0 taskkill@5.0.0: @@ -22381,12 +23695,12 @@ snapshots: - encoding - supports-color - temml@0.11.6: {} + temml@0.11.11: {} - terser@5.39.0: + terser@5.44.0: dependencies: - '@jridgewell/source-map': 0.3.6 - acorn: 8.14.1 + '@jridgewell/source-map': 0.3.5 + acorn: 8.15.0 commander: 2.20.3 source-map-support: 0.5.21 @@ -22400,11 +23714,7 @@ snapshots: dependencies: '@istanbuljs/schema': 0.1.3 glob: 10.4.5 - minimatch: 9.0.5 - - text-decoder@1.2.3: - dependencies: - b4a: 1.6.7 + minimatch: 9.0.4 textarea-caret@3.1.0: {} @@ -22420,16 +23730,21 @@ snapshots: dependencies: real-require: 0.2.0 - three@0.176.0: {} + three@0.180.0: {} throttle-debounce@5.0.2: {} - throttleit@1.0.1: {} + throttleit@1.0.0: {} through@2.3.8: {} tiny-emitter@2.1.0: {} + tiny-glob@0.2.9: + dependencies: + globalyzer: 0.1.0 + globrex: 0.1.2 + tiny-invariant@1.3.3: {} tinybench@2.9.0: {} @@ -22438,14 +23753,19 @@ snapshots: tinyexec@0.3.2: {} - tinyglobby@0.2.14: + tinyglobby@0.2.13: dependencies: - fdir: 6.4.6(picomatch@4.0.2) + fdir: 6.4.4(picomatch@4.0.2) picomatch: 4.0.2 + tinyglobby@0.2.15: + dependencies: + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + tinyld@1.3.4: {} - tinypool@1.1.0: {} + tinypool@1.1.1: {} tinyrainbow@1.2.0: {} @@ -22453,18 +23773,34 @@ snapshots: tinyspy@3.0.2: {} - tldts-core@6.1.86: {} + tinyspy@4.0.4: {} + + tldts-core@6.1.61: {} - tldts@6.1.86: + tldts-core@7.0.17: {} + + tldts@6.1.61: + dependencies: + tldts-core: 6.1.61 + + tldts@7.0.17: dependencies: - tldts-core: 6.1.86 + tldts-core: 7.0.17 - tmp@0.2.3: {} + tmp@0.2.5: {} tmpl@1.0.5: {} + to-buffer@1.2.2: + dependencies: + isarray: 2.0.5 + safe-buffer: 5.2.1 + typed-array-buffer: 1.0.3 + to-data-view@1.1.0: {} + to-fast-properties@2.0.0: {} + to-regex-range@5.0.1: dependencies: is-number: 7.0.0 @@ -22480,22 +23816,21 @@ snapshots: '@tokenizer/token': 0.3.0 ieee754: 1.2.1 - touch@3.1.1: {} - - tough-cookie@4.1.4: + touch@3.1.0: dependencies: - psl: 1.15.0 - punycode: 2.3.1 - universalify: 0.2.0 - url-parse: 1.5.10 + nopt: 1.0.10 tough-cookie@5.1.2: dependencies: - tldts: 6.1.86 + tldts: 6.1.61 + + tough-cookie@6.0.0: + dependencies: + tldts: 7.0.17 tr46@0.0.3: {} - tr46@5.1.1: + tr46@5.0.0: dependencies: punycode: 2.3.1 @@ -22507,9 +23842,9 @@ snapshots: trough@2.2.0: {} - ts-api-utils@2.1.0(typescript@5.8.3): + ts-api-utils@2.1.0(typescript@5.9.3): dependencies: - typescript: 5.8.3 + typescript: 5.9.3 ts-case-convert@2.1.0: {} @@ -22517,15 +23852,15 @@ snapshots: ts-map@1.0.3: {} - tsc-alias@1.8.15: + tsc-alias@1.8.16: dependencies: chokidar: 4.0.3 commander: 9.5.0 - get-tsconfig: 4.10.1 + get-tsconfig: 4.10.0 globby: 11.1.0 mylas: 2.1.13 normalize-path: 3.0.0 - plimit-lit: 1.6.1 + plimit-lit: 1.5.0 tsconfig-paths@3.15.0: dependencies: @@ -22537,12 +23872,12 @@ snapshots: tsconfig-paths@4.2.0: dependencies: json5: 2.2.3 - minimist: 1.2.8 + minimist: 1.2.7 strip-bom: 3.0.0 - tsd@0.32.0: + tsd@0.33.0: dependencies: - '@tsd/typescript': 5.8.3 + '@tsd/typescript': 5.9.3 eslint-formatter-pretty: 4.1.0 globby: 11.1.0 jest-diff: 29.7.0 @@ -22552,17 +23887,21 @@ snapshots: tslib@1.14.1: {} + tslib@2.6.2: {} + + tslib@2.7.0: {} + tslib@2.8.1: {} - tsutils@3.21.0(typescript@5.8.3): + tsutils@3.21.0(typescript@5.9.3): dependencies: tslib: 1.14.1 - typescript: 5.8.3 + typescript: 5.9.3 - tsx@4.19.3: + tsx@4.20.6: dependencies: - esbuild: 0.25.3 - get-tsconfig: 4.10.1 + esbuild: 0.25.10 + get-tsconfig: 4.10.0 optionalDependencies: fsevents: 2.3.3 @@ -22582,8 +23921,6 @@ snapshots: type-detect@4.0.8: {} - type-detect@4.1.0: {} - type-fest@0.18.1: {} type-fest@0.21.3: {} @@ -22601,87 +23938,128 @@ snapshots: media-typer: 0.3.0 mime-types: 2.1.35 + typed-array-buffer@1.0.2: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-typed-array: 1.1.13 + typed-array-buffer@1.0.3: dependencies: call-bound: 1.0.4 es-errors: 1.3.0 is-typed-array: 1.1.15 + typed-array-byte-length@1.0.1: + dependencies: + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.2.0 + has-proto: 1.0.3 + is-typed-array: 1.1.13 + typed-array-byte-length@1.0.3: dependencies: call-bind: 1.0.8 - for-each: 0.3.5 + for-each: 0.3.3 gopd: 1.2.0 has-proto: 1.2.0 is-typed-array: 1.1.15 + typed-array-byte-offset@1.0.2: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.2.0 + has-proto: 1.0.3 + is-typed-array: 1.1.13 + typed-array-byte-offset@1.0.4: dependencies: available-typed-arrays: 1.0.7 call-bind: 1.0.8 - for-each: 0.3.5 + for-each: 0.3.3 gopd: 1.2.0 has-proto: 1.2.0 is-typed-array: 1.1.15 reflect.getprototypeof: 1.0.10 + typed-array-length@1.0.6: + dependencies: + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.2.0 + has-proto: 1.0.3 + is-typed-array: 1.1.13 + possible-typed-array-names: 1.0.0 + typed-array-length@1.0.7: dependencies: call-bind: 1.0.8 - for-each: 0.3.5 + for-each: 0.3.3 gopd: 1.2.0 is-typed-array: 1.1.15 - possible-typed-array-names: 1.1.0 + possible-typed-array-names: 1.0.0 reflect.getprototypeof: 1.0.10 typed-function@4.2.1: {} typedarray@0.0.6: {} - typeorm@0.3.22(ioredis@5.6.1)(pg@8.15.6)(reflect-metadata@0.2.2): + typeorm@0.3.27(ioredis@5.8.1)(pg@8.16.3)(reflect-metadata@0.2.2): dependencies: '@sqltools/formatter': 1.2.5 ansis: 3.17.0 app-root-path: 3.1.0 buffer: 6.0.3 dayjs: 1.11.13 - debug: 4.4.1(supports-color@5.5.0) + debug: 4.4.0(supports-color@5.5.0) + dedent: 1.7.0 dotenv: 16.5.0 glob: 10.4.5 reflect-metadata: 0.2.2 - sha.js: 2.4.11 - sql-highlight: 6.1.0 + sha.js: 2.4.12 + sql-highlight: 6.0.0 tslib: 2.8.1 uuid: 11.1.0 yargs: 17.7.2 optionalDependencies: - ioredis: 5.6.1 - pg: 8.15.6 + ioredis: 5.8.1 + pg: 8.16.3 transitivePeerDependencies: + - babel-plugin-macros - supports-color typescript@5.8.2: {} - typescript@5.8.3: {} + typescript@5.9.3: {} - uc.micro@2.1.0: {} + uc.micro@1.0.6: {} - uglify-js@3.19.3: {} + uglify-js@3.17.4: {} uid2@0.0.4: {} uid@2.0.2: dependencies: - '@lukeed/csprng': 1.1.0 + '@lukeed/csprng': 1.0.1 uint8array-extras@1.4.0: {} ulid@2.4.0: {} + unbox-primitive@1.0.2: + dependencies: + call-bind: 1.0.7 + has-bigints: 1.0.2 + has-symbols: 1.1.0 + which-boxed-primitive: 1.0.2 + unbox-primitive@1.1.0: dependencies: call-bound: 1.0.4 - has-bigints: 1.1.0 + has-bigints: 1.0.2 has-symbols: 1.1.0 which-boxed-primitive: 1.1.1 @@ -22692,135 +24070,140 @@ snapshots: undefsafe@2.0.5: {} - underscore@1.13.7: {} + underscore@1.13.6: {} undici-types@6.21.0: {} - undici@5.29.0: + undici-types@7.16.0: {} + + undici@5.28.5: dependencies: - '@fastify/busboy': 2.1.1 + '@fastify/busboy': 2.1.0 - undici@6.21.3: {} + undici@6.19.8: {} - undici@7.10.0: {} + undici@7.16.0: {} + + unicorn-magic@0.1.0: {} unicorn-magic@0.3.0: {} - unified@11.0.5: + unified@11.0.4: dependencies: - '@types/unist': 3.0.3 + '@types/unist': 3.0.2 bail: 2.0.2 devlop: 1.1.0 extend: 3.0.2 is-plain-obj: 4.1.0 trough: 2.2.0 - vfile: 6.0.3 + vfile: 6.0.1 - unique-filename@3.0.0: + unique-filename@4.0.0: dependencies: - unique-slug: 4.0.0 + unique-slug: 5.0.0 - unique-slug@4.0.0: + unique-slug@5.0.0: dependencies: imurmurhash: 0.1.4 unist-util-is@6.0.0: dependencies: - '@types/unist': 3.0.3 + '@types/unist': 3.0.2 unist-util-position@5.0.0: dependencies: - '@types/unist': 3.0.3 + '@types/unist': 3.0.2 unist-util-stringify-position@4.0.0: dependencies: - '@types/unist': 3.0.3 + '@types/unist': 3.0.2 unist-util-visit-parents@6.0.1: dependencies: - '@types/unist': 3.0.3 + '@types/unist': 3.0.2 unist-util-is: 6.0.0 unist-util-visit@5.0.0: dependencies: - '@types/unist': 3.0.3 + '@types/unist': 3.0.2 unist-util-is: 6.0.0 unist-util-visit-parents: 6.0.1 universalify@0.1.2: {} - universalify@0.2.0: {} - - universalify@2.0.1: {} + universalify@2.0.0: {} unload@2.4.1: {} unpipe@1.0.0: {} - unplugin@1.16.1: + unplugin@1.5.1: dependencies: - acorn: 8.14.1 - webpack-virtual-modules: 0.6.2 + acorn: 8.15.0 + chokidar: 4.0.3 + webpack-sources: 3.2.3 + webpack-virtual-modules: 0.6.0 + + until-async@3.0.2: {} untildify@4.0.0: {} - update-browserslist-db@1.1.3(browserslist@4.25.0): + update-browserslist-db@1.1.2(browserslist@4.24.4): dependencies: - browserslist: 4.25.0 + browserslist: 4.24.4 escalade: 3.2.0 picocolors: 1.1.1 - uri-js@4.4.1: + update-browserslist-db@1.1.3(browserslist@4.26.3): dependencies: - punycode: 2.3.1 + browserslist: 4.26.3 + escalade: 3.2.0 + picocolors: 1.1.1 + + uri-js-replace@1.0.1: {} - url-parse@1.5.10: + uri-js@4.4.1: dependencies: - querystringify: 2.2.0 - requires-port: 1.0.0 + punycode: 2.3.1 utf-8-validate@6.0.5: dependencies: - node-gyp-build: 4.8.4 + node-gyp-build: 4.8.2 optional: true util-deprecate@1.0.2: {} - util@0.12.5: - dependencies: - inherits: 2.0.4 - is-arguments: 1.2.0 - is-generator-function: 1.1.0 - is-typed-array: 1.1.15 - which-typed-array: 1.1.19 - utils-merge@1.0.1: {} uuid@11.1.0: {} + uuid@13.0.0: {} + uuid@8.3.2: {} + uuid@9.0.0: {} + uuid@9.0.1: {} - v-code-diff@1.13.1(vue@3.5.13(typescript@5.8.3)): + v-code-diff@1.13.1(vue@3.5.22(typescript@5.9.3)): dependencies: diff: 5.2.0 diff-match-patch: 1.0.5 - highlight.js: 11.11.1 - vue: 3.5.13(typescript@5.8.3) - vue-demi: 0.14.10(vue@3.5.13(typescript@5.8.3)) + highlight.js: 11.10.0 + vue: 3.5.22(typescript@5.9.3) + vue-demi: 0.14.7(vue@3.5.22(typescript@5.9.3)) - v8-to-istanbul@9.3.0: + v8-to-istanbul@9.1.0: dependencies: - '@jridgewell/trace-mapping': 0.3.25 - '@types/istanbul-lib-coverage': 2.0.6 - convert-source-map: 2.0.0 + '@jridgewell/trace-mapping': 0.3.31 + '@types/istanbul-lib-coverage': 2.0.4 + convert-source-map: 1.9.0 valid-data-url@3.0.1: {} validate-npm-package-license@3.0.4: dependencies: - spdx-correct: 3.2.0 + spdx-correct: 3.1.1 spdx-expression-parse: 3.0.1 vary@1.1.2: {} @@ -22833,21 +24216,22 @@ snapshots: vfile-message@4.0.2: dependencies: - '@types/unist': 3.0.3 + '@types/unist': 3.0.2 unist-util-stringify-position: 4.0.0 - vfile@6.0.3: + vfile@6.0.1: dependencies: - '@types/unist': 3.0.3 + '@types/unist': 3.0.2 + unist-util-stringify-position: 4.0.0 vfile-message: 4.0.2 - vite-node@3.1.2(@types/node@22.15.2)(sass@1.87.0)(terser@5.39.0)(tsx@4.19.3): + vite-node@3.2.4(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6): dependencies: cac: 6.7.14 - debug: 4.4.1(supports-color@5.5.0) + debug: 4.4.3(supports-color@8.1.1) es-module-lexer: 1.7.0 pathe: 2.0.3 - vite: 6.3.4(@types/node@22.15.2)(sass@1.87.0)(terser@5.39.0)(tsx@4.19.3) + vite: 7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6) transitivePeerDependencies: - '@types/node' - jiti @@ -22862,65 +24246,84 @@ snapshots: - tsx - yaml + vite-plugin-glsl@1.5.4(@rollup/pluginutils@5.3.0(rollup@4.52.4))(esbuild@0.25.10)(vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)): + dependencies: + vite: 7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6) + optionalDependencies: + '@rollup/pluginutils': 5.3.0(rollup@4.52.4) + esbuild: 0.25.10 + vite-plugin-turbosnap@1.0.3: {} - vite@5.4.19(@types/node@22.15.2)(sass@1.87.0)(terser@5.39.0): + vite@7.1.7(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6): dependencies: - esbuild: 0.21.5 - postcss: 8.5.3 - rollup: 4.40.0 + esbuild: 0.25.10 + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + postcss: 8.5.6 + rollup: 4.52.4 + tinyglobby: 0.2.15 optionalDependencies: - '@types/node': 22.15.2 + '@types/node': 24.9.1 fsevents: 2.3.3 - sass: 1.87.0 - terser: 5.39.0 - - vite@6.3.4(@types/node@22.15.2)(sass@1.87.0)(terser@5.39.0)(tsx@4.19.3): - dependencies: - esbuild: 0.25.3 - fdir: 6.4.6(picomatch@4.0.2) - picomatch: 4.0.2 - postcss: 8.5.3 - rollup: 4.40.0 - tinyglobby: 0.2.14 + sass: 1.93.2 + terser: 5.44.0 + tsx: 4.20.6 + + vite@7.1.9(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6): + dependencies: + esbuild: 0.25.10 + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + postcss: 8.5.6 + rollup: 4.52.4 + tinyglobby: 0.2.15 optionalDependencies: - '@types/node': 22.15.2 + '@types/node': 24.9.1 fsevents: 2.3.3 - sass: 1.87.0 - terser: 5.39.0 - tsx: 4.19.3 + sass: 1.93.2 + terser: 5.44.0 + tsx: 4.20.6 - vitest-fetch-mock@0.4.5(vitest@3.1.2(@types/debug@4.1.12)(@types/node@22.15.2)(happy-dom@17.4.4)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(msw@2.7.5(@types/node@22.15.2)(typescript@5.8.3))(sass@1.87.0)(terser@5.39.0)(tsx@4.19.3)): + vitest-fetch-mock@0.4.5(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.9.1)(happy-dom@20.0.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)): dependencies: - vitest: 3.1.2(@types/debug@4.1.12)(@types/node@22.15.2)(happy-dom@17.4.4)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(msw@2.7.5(@types/node@22.15.2)(typescript@5.8.3))(sass@1.87.0)(terser@5.39.0)(tsx@4.19.3) + vitest: 3.2.4(@types/debug@4.1.12)(@types/node@24.9.1)(happy-dom@20.0.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6) - vitest@3.1.2(@types/debug@4.1.12)(@types/node@22.15.2)(happy-dom@17.4.4)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(msw@2.7.5(@types/node@22.15.2)(typescript@5.8.3))(sass@1.87.0)(terser@5.39.0)(tsx@4.19.3): + vitest-websocket-mock@0.5.0(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.9.1)(happy-dom@20.0.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)): dependencies: - '@vitest/expect': 3.1.2 - '@vitest/mocker': 3.1.2(msw@2.7.5(@types/node@22.15.2)(typescript@5.8.3))(vite@6.3.4(@types/node@22.15.2)(sass@1.87.0)(terser@5.39.0)(tsx@4.19.3)) - '@vitest/pretty-format': 3.2.3 - '@vitest/runner': 3.1.2 - '@vitest/snapshot': 3.1.2 - '@vitest/spy': 3.1.2 '@vitest/utils': 3.1.2 + mock-socket: 9.3.1 + vitest: 3.2.4(@types/debug@4.1.12)(@types/node@24.9.1)(happy-dom@20.0.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6) + + vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.9.1)(happy-dom@20.0.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6): + dependencies: + '@types/chai': 5.2.2 + '@vitest/expect': 3.2.4 + '@vitest/mocker': 3.2.4(msw@2.11.5(@types/node@24.9.1)(typescript@5.9.3))(vite@7.1.7(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)) + '@vitest/pretty-format': 3.2.4 + '@vitest/runner': 3.2.4 + '@vitest/snapshot': 3.2.4 + '@vitest/spy': 3.2.4 + '@vitest/utils': 3.2.4 chai: 5.2.0 - debug: 4.4.1(supports-color@5.5.0) + debug: 4.4.3(supports-color@8.1.1) expect-type: 1.2.1 - magic-string: 0.30.17 + magic-string: 0.30.19 pathe: 2.0.3 + picomatch: 4.0.2 std-env: 3.9.0 tinybench: 2.9.0 tinyexec: 0.3.2 - tinyglobby: 0.2.14 - tinypool: 1.1.0 + tinyglobby: 0.2.15 + tinypool: 1.1.1 tinyrainbow: 2.0.0 - vite: 6.3.4(@types/node@22.15.2)(sass@1.87.0)(terser@5.39.0)(tsx@4.19.3) - vite-node: 3.1.2(@types/node@22.15.2)(sass@1.87.0)(terser@5.39.0)(tsx@4.19.3) + vite: 7.1.7(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6) + vite-node: 3.2.4(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6) why-is-node-running: 2.3.0 optionalDependencies: '@types/debug': 4.1.12 - '@types/node': 22.15.2 - happy-dom: 17.4.4 + '@types/node': 24.9.1 + happy-dom: 20.0.7 jsdom: 26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5) transitivePeerDependencies: - jiti @@ -22942,8 +24345,8 @@ snapshots: vscode-languageclient@9.0.1: dependencies: - minimatch: 5.1.6 - semver: 7.7.1 + minimatch: 5.1.2 + semver: 7.7.3 vscode-languageserver-protocol: 3.17.5 vscode-languageserver-protocol@3.17.5: @@ -22953,89 +24356,99 @@ snapshots: vscode-languageserver-types@3.17.5: {} - vscode-uri@3.1.0: {} + vscode-uri@3.0.8: {} - vue-component-meta@2.2.10(typescript@5.8.3): + vue-component-meta@2.0.19(typescript@5.9.3): dependencies: - '@volar/typescript': 2.4.14 - '@vue/language-core': 2.2.10(typescript@5.8.3) + '@volar/typescript': 2.2.4 + '@vue/language-core': 2.0.19(typescript@5.9.3) path-browserify: 1.0.1 - vue-component-type-helpers: 2.2.10 + vue-component-type-helpers: 2.0.19 optionalDependencies: - typescript: 5.8.3 + typescript: 5.9.3 + + vue-component-type-helpers@1.8.4: {} + + vue-component-type-helpers@2.0.19: {} + + vue-component-type-helpers@3.1.1: {} - vue-component-type-helpers@2.2.10: {} + vue-component-type-helpers@3.1.3: {} - vue-demi@0.14.10(vue@3.5.13(typescript@5.8.3)): + vue-demi@0.14.7(vue@3.5.22(typescript@5.9.3)): dependencies: - vue: 3.5.13(typescript@5.8.3) + vue: 3.5.22(typescript@5.9.3) - vue-docgen-api@4.79.2(vue@3.5.13(typescript@5.8.3)): + vue-docgen-api@4.76.0(vue@3.5.22(typescript@5.9.3)): dependencies: - '@babel/parser': 7.27.5 - '@babel/types': 7.27.6 - '@vue/compiler-dom': 3.5.16 - '@vue/compiler-sfc': 3.5.13 + '@babel/parser': 7.28.4 + '@babel/types': 7.28.4 + '@vue/compiler-dom': 3.5.22 + '@vue/compiler-sfc': 3.5.22 ast-types: 0.16.1 - esm-resolve: 1.0.11 + esm-resolve: 1.0.9 hash-sum: 2.0.0 - lru-cache: 8.0.5 + lru-cache: 8.0.4 pug: 3.0.3 - recast: 0.23.11 + recast: 0.23.7 ts-map: 1.0.3 - vue: 3.5.13(typescript@5.8.3) - vue-inbrowser-compiler-independent-utils: 4.71.1(vue@3.5.13(typescript@5.8.3)) + vue: 3.5.22(typescript@5.9.3) + vue-inbrowser-compiler-independent-utils: 4.71.1(vue@3.5.22(typescript@5.9.3)) - vue-eslint-parser@10.1.3(eslint@9.25.1): + vue-eslint-parser@10.2.0(eslint@9.37.0): dependencies: - debug: 4.4.1(supports-color@5.5.0) - eslint: 9.25.1 - eslint-scope: 8.4.0 - eslint-visitor-keys: 4.2.1 - espree: 10.4.0 + debug: 4.4.0(supports-color@5.5.0) + eslint: 9.37.0 + eslint-scope: 8.3.0 + eslint-visitor-keys: 4.2.0 + espree: 10.3.0 esquery: 1.6.0 - lodash: 4.17.21 - semver: 7.7.1 + semver: 7.7.3 transitivePeerDependencies: - supports-color - vue-inbrowser-compiler-independent-utils@4.71.1(vue@3.5.13(typescript@5.8.3)): + vue-inbrowser-compiler-independent-utils@4.71.1(vue@3.5.22(typescript@5.9.3)): dependencies: - vue: 3.5.13(typescript@5.8.3) + vue: 3.5.22(typescript@5.9.3) - vue-prism-editor@2.0.0-alpha.2(vue@3.5.13(typescript@5.8.3)): + vue-prism-editor@2.0.0-alpha.2(vue@3.5.22(typescript@5.9.3)): dependencies: - vue: 3.5.13(typescript@5.8.3) + vue: 3.5.22(typescript@5.9.3) - vue-tsc@2.2.10(typescript@5.8.3): + vue-template-compiler@2.7.14: dependencies: - '@volar/typescript': 2.4.14 - '@vue/language-core': 2.2.10(typescript@5.8.3) - typescript: 5.8.3 + de-indent: 1.0.2 + he: 1.2.0 + + vue-tsc@3.1.1(typescript@5.9.3): + dependencies: + '@volar/typescript': 2.4.23 + '@vue/language-core': 3.1.1(typescript@5.9.3) + typescript: 5.9.3 - vue@3.5.13(typescript@5.8.3): + vue@3.5.22(typescript@5.9.3): dependencies: - '@vue/compiler-dom': 3.5.13 - '@vue/compiler-sfc': 3.5.13 - '@vue/runtime-dom': 3.5.13 - '@vue/server-renderer': 3.5.13(vue@3.5.13(typescript@5.8.3)) - '@vue/shared': 3.5.13 + '@vue/compiler-dom': 3.5.22 + '@vue/compiler-sfc': 3.5.22 + '@vue/runtime-dom': 3.5.22 + '@vue/server-renderer': 3.5.22(vue@3.5.22(typescript@5.9.3)) + '@vue/shared': 3.5.22 optionalDependencies: - typescript: 5.8.3 + typescript: 5.9.3 - vuedraggable@4.1.0(vue@3.5.13(typescript@5.8.3)): + vuedraggable@4.1.0(vue@3.5.22(typescript@5.9.3)): dependencies: sortablejs: 1.14.0 - vue: 3.5.13(typescript@5.8.3) + vue: 3.5.22(typescript@5.9.3) w3c-xmlserializer@5.0.0: dependencies: xml-name-validator: 5.0.0 - wait-on@8.0.3(debug@4.4.0): + wait-on@8.0.5(debug@4.4.3): dependencies: - axios: 1.10.0(debug@4.4.0) - joi: 17.13.3 + axios: 1.12.2(debug@4.4.3) + joi: 18.0.1 lodash: 4.17.21 minimist: 1.2.8 rxjs: 7.8.2 @@ -23048,11 +24461,15 @@ snapshots: wanakana@5.3.1: {} + wawoff2@2.0.1: + dependencies: + argparse: 2.0.1 + web-push@3.6.7: dependencies: asn1.js: 5.4.1 http_ece: 1.2.0 - https-proxy-agent: 7.0.6 + https-proxy-agent: 7.0.2 jws: 4.0.0 minimist: 1.2.8 transitivePeerDependencies: @@ -23066,13 +24483,15 @@ snapshots: mime: 2.6.0 valid-data-url: 3.0.1 - web-streams-polyfill@3.3.3: {} + web-streams-polyfill@3.2.1: {} webidl-conversions@3.0.1: {} webidl-conversions@7.0.0: {} - webpack-virtual-modules@0.6.2: {} + webpack-sources@3.2.3: {} + + webpack-virtual-modules@0.6.0: {} whatwg-encoding@3.1.1: dependencies: @@ -23082,9 +24501,9 @@ snapshots: whatwg-mimetype@4.0.0: {} - whatwg-url@14.2.0: + whatwg-url@14.1.1: dependencies: - tr46: 5.1.1 + tr46: 5.0.0 webidl-conversions: 7.0.0 whatwg-url@5.0.0: @@ -23092,6 +24511,14 @@ snapshots: tr46: 0.0.3 webidl-conversions: 3.0.1 + which-boxed-primitive@1.0.2: + dependencies: + is-bigint: 1.0.4 + is-boolean-object: 1.1.2 + is-number-object: 1.0.7 + is-string: 1.0.7 + is-symbol: 1.0.4 + which-boxed-primitive@1.1.1: dependencies: is-bigint: 1.1.0 @@ -23108,7 +24535,7 @@ snapshots: is-async-function: 2.1.1 is-date-object: 1.1.0 is-finalizationregistry: 1.1.1 - is-generator-function: 1.1.0 + is-generator-function: 1.0.10 is-regex: 1.2.1 is-weakref: 1.1.1 isarray: 2.0.5 @@ -23116,6 +24543,13 @@ snapshots: which-collection: 1.0.2 which-typed-array: 1.1.19 + which-collection@1.0.1: + dependencies: + is-map: 2.0.2 + is-set: 2.0.2 + is-weakmap: 2.0.1 + is-weakset: 2.0.2 + which-collection@1.0.2: dependencies: is-map: 2.0.3 @@ -23123,7 +24557,15 @@ snapshots: is-weakmap: 2.0.2 is-weakset: 2.0.4 - which-module@2.0.1: {} + which-module@2.0.0: {} + + which-typed-array@1.1.15: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.2.0 + has-tostringtag: 1.0.2 which-typed-array@1.1.19: dependencies: @@ -23143,7 +24585,7 @@ snapshots: dependencies: isexe: 2.0.0 - which@4.0.0: + which@5.0.0: dependencies: isexe: 3.1.1 @@ -23159,12 +24601,12 @@ snapshots: with@7.0.2: dependencies: - '@babel/parser': 7.27.5 - '@babel/types': 7.27.6 - assert-never: 1.4.0 + '@babel/parser': 7.28.4 + '@babel/types': 7.28.4 + assert-never: 1.2.1 babel-walk: 3.0.0-canary-5 - word-wrap@1.2.5: {} + word-wrap@1.2.3: {} wrap-ansi@6.2.0: dependencies: @@ -23191,7 +24633,7 @@ snapshots: imurmurhash: 0.1.4 signal-exit: 3.0.7 - ws@8.18.1(bufferutil@4.0.9)(utf-8-validate@6.0.5): + ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@6.0.5): optionalDependencies: bufferutil: 4.0.9 utf-8-validate: 6.0.5 @@ -23200,7 +24642,7 @@ snapshots: xml-js@1.6.11: dependencies: - sax: 1.4.1 + sax: 1.2.4 xml-name-validator@4.0.0: {} @@ -23208,7 +24650,7 @@ snapshots: xml2js@0.5.0: dependencies: - sax: 1.4.1 + sax: 1.2.4 xmlbuilder: 11.0.1 xmlbuilder@11.0.1: {} @@ -23229,6 +24671,8 @@ snapshots: yallist@5.0.0: {} + yaml-ast-parser@0.0.43: {} + yargs-parser@18.1.3: dependencies: camelcase: 5.3.1 @@ -23248,14 +24692,14 @@ snapshots: require-main-filename: 2.0.0 set-blocking: 2.0.0 string-width: 4.2.3 - which-module: 2.0.1 + which-module: 2.0.0 y18n: 4.0.3 yargs-parser: 18.1.3 yargs@16.2.0: dependencies: cliui: 7.0.4 - escalade: 3.2.0 + escalade: 3.1.1 get-caller-file: 2.0.5 require-directory: 2.1.1 string-width: 4.2.3 @@ -23265,7 +24709,7 @@ snapshots: yargs@17.7.2: dependencies: cliui: 8.0.1 - escalade: 3.2.0 + escalade: 3.1.1 get-caller-file: 2.0.5 require-directory: 2.1.1 string-width: 4.2.3 @@ -23284,6 +24728,8 @@ snapshots: yocto-queue@0.1.0: {} + yocto-queue@1.2.1: {} + yoctocolors-cjs@2.1.2: {} yoctocolors@2.1.1: {} @@ -23292,6 +24738,6 @@ snapshots: dependencies: archiver-utils: 5.0.2 compress-commons: 6.0.2 - readable-stream: 4.7.0 + readable-stream: 4.3.0 zwitch@2.0.4: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 65d129d0db..38a281c53e 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -2,7 +2,9 @@ packages: - packages/backend - packages/frontend-shared - packages/frontend + - packages/frontend-builder - packages/frontend-embed + - packages/icons-subsetter - packages/sw - packages/cherrypick-js - packages/cherrypick-js/generator @@ -31,3 +33,6 @@ onlyBuiltDependencies: - v-code-diff - vue-demi ignorePatchFailures: false +minimumReleaseAge: 10080 # delay 7days to mitigate supply-chain attack +minimumReleaseAgeExclude: + - happy-dom # セキュリティ修正のため一時的に。そのうち消すこと diff --git a/renovate.json5 b/renovate.json5 index 9ea4b893d9..401c9d1278 100644 --- a/renovate.json5 +++ b/renovate.json5 @@ -15,6 +15,7 @@ dependencyDashboardAutoclose: true, osvVulnerabilityAlerts: true, dependencyDashboardOSVVulnerabilitySummary: 'unresolved', + minimumReleaseAge: '7 days', ignoreDeps: [ // https://github.com/misskey-dev/misskey/pull/15489#issuecomment-2660717458 '@typescript/lib-webworker', @@ -22,7 +23,8 @@ 'nsfwjs', // https://github.com/misskey-dev/misskey/issues/15920 'sharp', - '@misskey-dev/sharp-read-bmp' + '@misskey-dev/sharp-read-bmp', + '@syuilo/aiscript-0-19-0', ], packageRules: [ { @@ -37,9 +39,11 @@ 'packages/frontend/**/package.json', 'packages/frontend-embed/**/package.json', 'packages/frontend-shared/**/package.json', + 'packages/frontend-builder/**/package.json', 'packages/misskey-bubble-game/**/package.json', 'packages/misskey-reversi/**/package.json', 'packages/sw/**/package.json', + 'packages/icons-subsetter/**/package.json', ], // prevent wastage of Chromatic snapshots rebaseWhen: 'never', @@ -74,6 +78,18 @@ '.node-version', ], }, + { + groupName: '[Node.js] Update dependencies', + matchManagers: ['custom.regex'], + matchPackageNames: ['node'], + }, + { + groupName: '[Node.js] Update dependencies', + matchDepNames: ['ghcr.io/devcontainers/features/node:1'], + matchFileNames: [ + '.devcontainer/**', + ], + }, { groupName: '[Docker] Update dependencies', matchFileNames: [ @@ -85,9 +101,20 @@ }, { groupName: '[devcontainer] Update dependencies', + matchDepNames: ['!ghcr.io/devcontainers/features/node:1'], matchFileNames: [ '.devcontainer/**', ], }, ], + customManagers: [ + { + customType: 'regex', + managerFilePatterns: ['/^Dockerfile$/'], + matchStrings: ['ARG NODE_VERSION=(?.*?)\\n'], + datasourceTemplate: 'docker', + depNameTemplate: 'node', + versioningTemplate: 'docker', + }, + ], } diff --git a/scripts/build-assets.mjs b/scripts/build-assets.mjs index a2057703ca..c32870e69b 100644 --- a/scripts/build-assets.mjs +++ b/scripts/build-assets.mjs @@ -33,10 +33,6 @@ async function copyFrontendFonts() { await fs.cp('./packages/frontend/node_modules/three/examples/fonts', './built/_frontend_dist_/fonts', { dereference: true, recursive: true }); } -async function copyFrontendTablerIcons() { - await fs.cp('./packages/frontend/node_modules/@tabler/icons-webfont/dist', `./built/_frontend_dist_/tabler-icons.${meta.version}`, { dereference: true, recursive: true }); -} - async function copyFrontendLocales() { generateDTS(); @@ -89,7 +85,6 @@ async function buildBackendStyle() { async function build() { await Promise.all([ copyFrontendFonts(), - copyFrontendTablerIcons(), copyFrontendLocales(), copyBackendViews(), buildBackendScript(), diff --git a/scripts/changelog-checker/package-lock.json b/scripts/changelog-checker/package-lock.json index 0fbb803a05..2074fa45da 100644 --- a/scripts/changelog-checker/package-lock.json +++ b/scripts/changelog-checker/package-lock.json @@ -9,16 +9,16 @@ "version": "1.0.0", "devDependencies": { "@types/mdast": "4.0.4", - "@types/node": "22.15.2", - "@vitest/coverage-v8": "3.1.2", + "@types/node": "24.9.1", + "@vitest/coverage-v8": "3.2.4", "mdast-util-to-string": "4.0.0", "remark": "15.0.1", "remark-parse": "11.0.0", - "typescript": "5.8.3", + "typescript": "5.9.3", "unified": "11.0.5", - "vite": "6.3.4", - "vite-node": "3.1.2", - "vitest": "3.1.2" + "vite": "6.4.1", + "vite-node": "3.2.4", + "vitest": "3.2.4" } }, "node_modules/@ampproject/remapping": { @@ -890,6 +890,16 @@ "win32" ] }, + "node_modules/@types/chai": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.2.tgz", + "integrity": "sha512-8kB30R7Hwqf40JPiKhVzodJs2Qc1ZJ5zuT3uzw5Hq/dhNCl3G3l83jfpdI1e20BP348+fV7VIL/+FxaXkqBmWg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/deep-eql": "*" + } + }, "node_modules/@types/debug": { "version": "4.1.12", "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", @@ -899,6 +909,13 @@ "@types/ms": "*" } }, + "node_modules/@types/deep-eql": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", + "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/estree": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz", @@ -923,13 +940,14 @@ "dev": true }, "node_modules/@types/node": { - "version": "22.15.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.2.tgz", - "integrity": "sha512-uKXqKN9beGoMdBfcaTY1ecwz6ctxuJAcUlwE55938g0ZJ8lRxwAZqRz2AJ4pzpt5dHdTPMB863UZ0ESiFUcP7A==", + "version": "24.9.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.9.1.tgz", + "integrity": "sha512-QoiaXANRkSXK6p0Duvt56W208du4P9Uye9hWLWgGMDTEoKPhuenzNcC4vGUmrNkiOKTlIrBoyNQYNpSwfEZXSg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { - "undici-types": "~6.21.0" + "undici-types": "~7.16.0" } }, "node_modules/@types/unist": { @@ -939,15 +957,16 @@ "dev": true }, "node_modules/@vitest/coverage-v8": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-3.1.2.tgz", - "integrity": "sha512-XDdaDOeaTMAMYW7N63AqoK32sYUWbXnTkC6tEbVcu3RlU1bB9of32T+PGf8KZvxqLNqeXhafDFqCkwpf2+dyaQ==", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-3.2.4.tgz", + "integrity": "sha512-EyF9SXU6kS5Ku/U82E259WSnvg6c8KTjppUncuNdm5QHpe17mwREHnjDzozC8x9MZ0xfBUFSaLkRv4TMA75ALQ==", "dev": true, "license": "MIT", "dependencies": { "@ampproject/remapping": "^2.3.0", "@bcoe/v8-coverage": "^1.0.2", - "debug": "^4.4.0", + "ast-v8-to-istanbul": "^0.3.3", + "debug": "^4.4.1", "istanbul-lib-coverage": "^3.2.2", "istanbul-lib-report": "^3.0.1", "istanbul-lib-source-maps": "^5.0.6", @@ -962,8 +981,8 @@ "url": "https://opencollective.com/vitest" }, "peerDependencies": { - "@vitest/browser": "3.1.2", - "vitest": "3.1.2" + "@vitest/browser": "3.2.4", + "vitest": "3.2.4" }, "peerDependenciesMeta": { "@vitest/browser": { @@ -972,14 +991,15 @@ } }, "node_modules/@vitest/expect": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.1.2.tgz", - "integrity": "sha512-O8hJgr+zREopCAqWl3uCVaOdqJwZ9qaDwUP7vy3Xigad0phZe9APxKhPcDNqYYi0rX5oMvwJMSCAXY2afqeTSA==", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.2.4.tgz", + "integrity": "sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/spy": "3.1.2", - "@vitest/utils": "3.1.2", + "@types/chai": "^5.2.2", + "@vitest/spy": "3.2.4", + "@vitest/utils": "3.2.4", "chai": "^5.2.0", "tinyrainbow": "^2.0.0" }, @@ -988,13 +1008,13 @@ } }, "node_modules/@vitest/mocker": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.1.2.tgz", - "integrity": "sha512-kOtd6K2lc7SQ0mBqYv/wdGedlqPdM/B38paPY+OwJ1XiNi44w3Fpog82UfOibmHaV9Wod18A09I9SCKLyDMqgw==", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.2.4.tgz", + "integrity": "sha512-46ryTE9RZO/rfDd7pEqFl7etuyzekzEhUbTW3BvmeO/BcCMEgq59BKhek3dXDWgAj4oMK6OZi+vRr1wPW6qjEQ==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/spy": "3.1.2", + "@vitest/spy": "3.2.4", "estree-walker": "^3.0.3", "magic-string": "^0.30.17" }, @@ -1003,7 +1023,7 @@ }, "peerDependencies": { "msw": "^2.4.9", - "vite": "^5.0.0 || ^6.0.0" + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" }, "peerDependenciesMeta": { "msw": { @@ -1015,9 +1035,9 @@ } }, "node_modules/@vitest/pretty-format": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.1.2.tgz", - "integrity": "sha512-R0xAiHuWeDjTSB3kQ3OQpT8Rx3yhdOAIm/JM4axXxnG7Q/fS8XUwggv/A4xzbQA+drYRjzkMnpYnOGAc4oeq8w==", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.2.4.tgz", + "integrity": "sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA==", "dev": true, "license": "MIT", "dependencies": { @@ -1028,27 +1048,28 @@ } }, "node_modules/@vitest/runner": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.1.2.tgz", - "integrity": "sha512-bhLib9l4xb4sUMPXnThbnhX2Yi8OutBMA8Yahxa7yavQsFDtwY/jrUZwpKp2XH9DhRFJIeytlyGpXCqZ65nR+g==", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.2.4.tgz", + "integrity": "sha512-oukfKT9Mk41LreEW09vt45f8wx7DordoWUZMYdY/cyAk7w5TWkTRCNZYF7sX7n2wB7jyGAl74OxgwhPgKaqDMQ==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/utils": "3.1.2", - "pathe": "^2.0.3" + "@vitest/utils": "3.2.4", + "pathe": "^2.0.3", + "strip-literal": "^3.0.0" }, "funding": { "url": "https://opencollective.com/vitest" } }, "node_modules/@vitest/snapshot": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.1.2.tgz", - "integrity": "sha512-Q1qkpazSF/p4ApZg1vfZSQ5Yw6OCQxVMVrLjslbLFA1hMDrT2uxtqMaw8Tc/jy5DLka1sNs1Y7rBcftMiaSH/Q==", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.2.4.tgz", + "integrity": "sha512-dEYtS7qQP2CjU27QBC5oUOxLE/v5eLkGqPE0ZKEIDGMs4vKWe7IjgLOeauHsR0D5YuuycGRO5oSRXnwnmA78fQ==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "3.1.2", + "@vitest/pretty-format": "3.2.4", "magic-string": "^0.30.17", "pathe": "^2.0.3" }, @@ -1057,27 +1078,27 @@ } }, "node_modules/@vitest/spy": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.1.2.tgz", - "integrity": "sha512-OEc5fSXMws6sHVe4kOFyDSj/+4MSwst0ib4un0DlcYgQvRuYQ0+M2HyqGaauUMnjq87tmUaMNDxKQx7wNfVqPA==", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.2.4.tgz", + "integrity": "sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw==", "dev": true, "license": "MIT", "dependencies": { - "tinyspy": "^3.0.2" + "tinyspy": "^4.0.3" }, "funding": { "url": "https://opencollective.com/vitest" } }, "node_modules/@vitest/utils": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.1.2.tgz", - "integrity": "sha512-5GGd0ytZ7BH3H6JTj9Kw7Prn1Nbg0wZVrIvou+UWxm54d+WoXXgAgjFJ8wn3LdagWLFSEfpPeyYrByZaGEZHLg==", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.2.4.tgz", + "integrity": "sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "3.1.2", - "loupe": "^3.1.3", + "@vitest/pretty-format": "3.2.4", + "loupe": "^3.1.4", "tinyrainbow": "^2.0.0" }, "funding": { @@ -1120,6 +1141,18 @@ "node": ">=12" } }, + "node_modules/ast-v8-to-istanbul": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/ast-v8-to-istanbul/-/ast-v8-to-istanbul-0.3.3.tgz", + "integrity": "sha512-MuXMrSLVVoA6sYN/6Hke18vMzrT4TZNbZIj/hvh0fnYFpO+/kFXcLIaiPwXXWaQUPg4yJD8fj+lfJ7/1EBconw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.25", + "estree-walker": "^3.0.3", + "js-tokens": "^9.0.1" + } + }, "node_modules/bail": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", @@ -1138,9 +1171,9 @@ "license": "MIT" }, "node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", "dev": true, "license": "MIT", "dependencies": { @@ -1214,10 +1247,11 @@ "license": "MIT" }, "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, + "license": "MIT", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -1228,9 +1262,9 @@ } }, "node_modules/debug": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", - "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", + "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", "dev": true, "license": "MIT", "dependencies": { @@ -1305,9 +1339,9 @@ "license": "MIT" }, "node_modules/es-module-lexer": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.6.0.tgz", - "integrity": "sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", + "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", "dev": true, "license": "MIT" }, @@ -1557,6 +1591,13 @@ "@pkgjs/parseargs": "^0.11.0" } }, + "node_modules/js-tokens": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.1.tgz", + "integrity": "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==", + "dev": true, + "license": "MIT" + }, "node_modules/longest-streak": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", @@ -1568,9 +1609,9 @@ } }, "node_modules/loupe": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.3.tgz", - "integrity": "sha512-kkIp7XSkP78ZxJEsSxW3712C6teJVoeHHwgo9zJ380de7IYyJ2ISlxojcH2pC5OFLewESmnRi/+XCDIEEVyoug==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.2.0.tgz", + "integrity": "sha512-2NCfZcT5VGVNX9mSZIxLRkEAegDGBpuQZBy13desuHeVORmBDyAET4TkJr4SjqQy3A8JDofMN6LpkK8Xcm/dlw==", "dev": true, "license": "MIT" }, @@ -2258,6 +2299,7 @@ "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=12" }, @@ -2561,6 +2603,19 @@ "node": ">=8" } }, + "node_modules/strip-literal": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-3.0.0.tgz", + "integrity": "sha512-TcccoMhJOM3OebGhSBEmp3UZ2SfDMZUEBdRA/9ynfLi8yYajyWX3JiXArcJt4Umh4vISpspkQIY8ZZoCqjbviA==", + "dev": true, + "license": "MIT", + "dependencies": { + "js-tokens": "^9.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, "node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -2603,9 +2658,9 @@ "license": "MIT" }, "node_modules/tinyglobby": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.13.tgz", - "integrity": "sha512-mEwzpUgrLySlveBwEVDMKk5B57bhLPYovRfPAXD5gA/98Opn0rCDj3GtLwFvCvH5RK9uPCExUROW5NjDwvqkxw==", + "version": "0.2.14", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.14.tgz", + "integrity": "sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==", "dev": true, "license": "MIT", "dependencies": { @@ -2620,9 +2675,9 @@ } }, "node_modules/tinypool": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.0.2.tgz", - "integrity": "sha512-al6n+QEANGFOMf/dmUMsuS5/r9B06uwlyNjZZql/zv8J7ybHCgoihBNORZCY2mzUuAnomQa2JdhyHKzZxPCrFA==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.1.1.tgz", + "integrity": "sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==", "dev": true, "license": "MIT", "engines": { @@ -2640,9 +2695,9 @@ } }, "node_modules/tinyspy": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-3.0.2.tgz", - "integrity": "sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-4.0.3.tgz", + "integrity": "sha512-t2T/WLB2WRgZ9EpE4jgPJ9w+i66UZfDc8wHh0xrwiRNN+UwH98GIJkTeZqX9rg0i0ptwzqW+uYeIF0T4F8LR7A==", "dev": true, "license": "MIT", "engines": { @@ -2660,9 +2715,9 @@ } }, "node_modules/typescript": { - "version": "5.8.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", - "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "dev": true, "license": "Apache-2.0", "bin": { @@ -2674,9 +2729,9 @@ } }, "node_modules/undici-types": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", - "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", + "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", "dev": true, "license": "MIT" }, @@ -2785,11 +2840,12 @@ } }, "node_modules/vite": { - "version": "6.3.4", - "resolved": "https://registry.npmjs.org/vite/-/vite-6.3.4.tgz", - "integrity": "sha512-BiReIiMS2fyFqbqNT/Qqt4CVITDU9M9vE+DKcVAsB+ZV0wvTKd+3hMbkpxz1b+NmEDMegpVbisKiAZOnvO92Sw==", + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.4.1.tgz", + "integrity": "sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.4.4", @@ -2860,17 +2916,17 @@ } }, "node_modules/vite-node": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.1.2.tgz", - "integrity": "sha512-/8iMryv46J3aK13iUXsei5G/A3CUlW4665THCPS+K8xAaqrVWiGB4RfXMQXCLjpK9P2eK//BczrVkn5JLAk6DA==", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.2.4.tgz", + "integrity": "sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==", "dev": true, "license": "MIT", "dependencies": { "cac": "^6.7.14", - "debug": "^4.4.0", - "es-module-lexer": "^1.6.0", + "debug": "^4.4.1", + "es-module-lexer": "^1.7.0", "pathe": "^2.0.3", - "vite": "^5.0.0 || ^6.0.0" + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" }, "bin": { "vite-node": "vite-node.mjs" @@ -2883,32 +2939,35 @@ } }, "node_modules/vitest": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.1.2.tgz", - "integrity": "sha512-WaxpJe092ID1C0mr+LH9MmNrhfzi8I65EX/NRU/Ld016KqQNRgxSOlGNP1hHN+a/F8L15Mh8klwaF77zR3GeDQ==", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.2.4.tgz", + "integrity": "sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { - "@vitest/expect": "3.1.2", - "@vitest/mocker": "3.1.2", - "@vitest/pretty-format": "^3.1.2", - "@vitest/runner": "3.1.2", - "@vitest/snapshot": "3.1.2", - "@vitest/spy": "3.1.2", - "@vitest/utils": "3.1.2", + "@types/chai": "^5.2.2", + "@vitest/expect": "3.2.4", + "@vitest/mocker": "3.2.4", + "@vitest/pretty-format": "^3.2.4", + "@vitest/runner": "3.2.4", + "@vitest/snapshot": "3.2.4", + "@vitest/spy": "3.2.4", + "@vitest/utils": "3.2.4", "chai": "^5.2.0", - "debug": "^4.4.0", + "debug": "^4.4.1", "expect-type": "^1.2.1", "magic-string": "^0.30.17", "pathe": "^2.0.3", + "picomatch": "^4.0.2", "std-env": "^3.9.0", "tinybench": "^2.9.0", "tinyexec": "^0.3.2", - "tinyglobby": "^0.2.13", - "tinypool": "^1.0.2", + "tinyglobby": "^0.2.14", + "tinypool": "^1.1.1", "tinyrainbow": "^2.0.0", - "vite": "^5.0.0 || ^6.0.0", - "vite-node": "3.1.2", + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0", + "vite-node": "3.2.4", "why-is-node-running": "^2.3.0" }, "bin": { @@ -2924,8 +2983,8 @@ "@edge-runtime/vm": "*", "@types/debug": "^4.1.12", "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", - "@vitest/browser": "3.1.2", - "@vitest/ui": "3.1.2", + "@vitest/browser": "3.2.4", + "@vitest/ui": "3.2.4", "happy-dom": "*", "jsdom": "*" }, diff --git a/scripts/changelog-checker/package.json b/scripts/changelog-checker/package.json index e702d8f9ad..9f45f1599a 100644 --- a/scripts/changelog-checker/package.json +++ b/scripts/changelog-checker/package.json @@ -10,15 +10,15 @@ }, "devDependencies": { "@types/mdast": "4.0.4", - "@types/node": "22.15.2", - "@vitest/coverage-v8": "3.1.2", + "@types/node": "24.9.1", + "@vitest/coverage-v8": "3.2.4", "mdast-util-to-string": "4.0.0", "remark": "15.0.1", "remark-parse": "11.0.0", - "typescript": "5.8.3", + "typescript": "5.9.3", "unified": "11.0.5", - "vite": "6.3.4", - "vite-node": "3.1.2", - "vitest": "3.1.2" + "vite": "6.4.1", + "vite-node": "3.2.4", + "vitest": "3.2.4" } } diff --git a/scripts/changelog-checker/src/index.ts b/scripts/changelog-checker/src/index.ts index 0e2c5ce057..24777188b0 100644 --- a/scripts/changelog-checker/src/index.ts +++ b/scripts/changelog-checker/src/index.ts @@ -17,13 +17,13 @@ function abort(message?: string) { } function main() { - if (!fs.existsSync('./CHANGELOG-base.md') || !fs.existsSync('./CHANGELOG-head.md')) { - console.error('CHANGELOG-base.md or CHANGELOG-head.md is missing.'); + if (!fs.existsSync('./CHANGELOG_CHERRYPICK-base.md') || !fs.existsSync('./CHANGELOG_CHERRYPICK-head.md')) { + console.error('CHANGELOG_CHERRYPICK-base.md or CHANGELOG_CHERRYPICK-head.md is missing.'); return; } - const base = parseChangeLog('./CHANGELOG-base.md'); - const head = parseChangeLog('./CHANGELOG-head.md'); + const base = parseChangeLog('./CHANGELOG_CHERRYPICK-base.md'); + const head = parseChangeLog('./CHANGELOG_CHERRYPICK-head.md'); const result = (base.length < head.length) ? checkNewRelease(base, head) diff --git a/scripts/clean-all.js b/scripts/clean-all.js index 875d522dbd..5a6c837a11 100644 --- a/scripts/clean-all.js +++ b/scripts/clean-all.js @@ -13,6 +13,8 @@ const fs = require('fs'); fs.rmSync(__dirname + '/../packages/frontend-shared/built', { recursive: true, force: true }); fs.rmSync(__dirname + '/../packages/frontend-shared/node_modules', { recursive: true, force: true }); + fs.rmSync(__dirname + '/../packages/frontend-builder/node_modules', { recursive: true, force: true }); + fs.rmSync(__dirname + '/../packages/frontend/built', { recursive: true, force: true }); fs.rmSync(__dirname + '/../packages/frontend/node_modules', { recursive: true, force: true }); diff --git a/scripts/clean.js b/scripts/clean.js index e6506e9dce..589ecb7216 100644 --- a/scripts/clean.js +++ b/scripts/clean.js @@ -10,6 +10,7 @@ const fs = require('fs'); fs.rmSync(__dirname + '/../packages/frontend-shared/built', { recursive: true, force: true }); fs.rmSync(__dirname + '/../packages/frontend/built', { recursive: true, force: true }); fs.rmSync(__dirname + '/../packages/frontend-embed/built', { recursive: true, force: true }); + fs.rmSync(__dirname + '/../packages/icons-subsetter/built', { recursive: true, force: true }); fs.rmSync(__dirname + '/../packages/sw/built', { recursive: true, force: true }); fs.rmSync(__dirname + '/../packages/cherrypick-js/built', { recursive: true, force: true }); fs.rmSync(__dirname + '/../packages/misskey-reversi/built', { recursive: true, force: true }); diff --git a/scripts/dev.mjs b/scripts/dev.mjs index eaa8c12b35..74543aea03 100644 --- a/scripts/dev.mjs +++ b/scripts/dev.mjs @@ -32,6 +32,12 @@ await Promise.all([ stdout: process.stdout, stderr: process.stderr, }), + // icons-subsetterは開発段階では使用されないが、型エラーを抑制するためにはじめの一度だけビルドする + execa('pnpm', ['--filter', 'icons-subsetter', 'build'], { + cwd: _dirname + '/../', + stdout: process.stdout, + stderr: process.stderr, + }), ]); execa('pnpm', ['build-pre', '--watch'], {