diff --git a/.claude/skills/crudable/SKILL.md b/.claude/skills/crudable/SKILL.md new file mode 100644 index 000000000..031a4a1f1 --- /dev/null +++ b/.claude/skills/crudable/SKILL.md @@ -0,0 +1,49 @@ +--- +name: crudable +description: Use when adding or modifying a model in pkg/models/ that needs CRUD operations or permission checks. Covers Can* method placement, CRUDable interface, and required test coverage. +user-invocable: true +--- + +# CRUDable + Permissions + +Models in `pkg/models/` that expose CRUD operations must implement the `CRUDable` interface **and** the permission methods. Permissions are enforced at the **model level** via `Can*` methods — never re-checked in route handlers. + +**Reference docs:** read `pkg/web/readme.md` for the full interface definitions, DB session semantics, and call order. The interface lives at `pkg/web/web.go`. This skill is a checklist of what the review feedback surfaces on top of that. + +## Before writing CRUD or route code + +1. Decide which operations the model needs: Read / ReadAll / Create / Update / Delete. +2. Implement the matching permission methods on the model. Typical signatures: + - `CanRead(s *xorm.Session, a web.Auth) (bool, int, error)` + - `CanCreate(s *xorm.Session, a web.Auth) (bool, error)` + - `CanUpdate(s *xorm.Session, a web.Auth) (bool, error)` + - `CanDelete(s *xorm.Session, a web.Auth) (bool, error)` +3. If a handler or service needs to check access, call the `Can*` method. Do **not** re-implement the check inline or duplicate the logic in `pkg/routes/`. +4. Do not implement empty stub methods just to satisfy the interface, instead embed the interface in the struct. Check existing models to see how that's done. + +Look at `pkg/models/project.go` or `pkg/models/task.go` for reference implementations. + +The initial querying of the data should happen in the Can* function. Because we're operating on a pointer, the function that does the work should not need to re-query the model data. + +## Anti-patterns (these get flagged every time) + +- Permission logic inlined in `pkg/routes/` handlers instead of on the model. +- Shipping `Create` but forgetting `CanUpdate` / `CanDelete` because "only create is new right now". +- Re-querying the DB in the handler to decide access — that work belongs in `CanRead`. +- Copy-pasting permission logic across `CanUpdate` and `CanDelete` — extract a helper. +- Adding a handler that bypasses the generic CRUD handler in `pkg/web/handler/` without a clear reason (the generic handler already invokes the `Can*` methods for you). + +## Tests (mandatory) + +Every `Can*` method needs both positive and negative coverage. Run with `mage test:filter ` while iterating. + +- User with direct permission → passes +- User without permission → denied +- Permission inherited via parent (e.g., project → task, team → project) → still passes +- Shared access edge cases (link shares, team membership) if the model supports them + +## Related + +- Generic CRUD handler: `pkg/web/handler/` +- Permission type definitions: `pkg/web/auth.go`, `pkg/models/permissions.go` +- After the model is stable, register the routes in `pkg/routes/api/v1/` and add Swagger annotations. Do not edit `pkg/swagger/` directly — it's generated. diff --git a/.claude/skills/migration/SKILL.md b/.claude/skills/migration/SKILL.md new file mode 100644 index 000000000..c08b47c06 --- /dev/null +++ b/.claude/skills/migration/SKILL.md @@ -0,0 +1,55 @@ +--- +name: migration +description: Use when creating or editing files in pkg/migration/. Covers cross-DB type safety across MySQL/PostgreSQL/SQLite, DDL error handling, time-column conventions, and path sanitization. +user-invocable: true +--- + +# Database Migrations + +Migrations are **irreversible in production**. Vikunja supports MySQL, PostgreSQL, and SQLite — every migration must work on all three. + +## Before writing + +1. Generate the skeleton: `mage dev:make-migration `. +2. The migration struct must mirror the model in `pkg/models/` exactly (field names, types, xorm tags). +3. Use `time.Time` for time columns. Never use `string`, `varchar`, or `text` for times. +4. For renames or type changes, verify the conversion is safe on all three DBs: + - MySQL will silently coerce `VARCHAR` → `BIGINT` during `ALTER`. Don't rely on that — migrate data explicitly. + - SQLite has limited `ALTER TABLE`; prefer `xorm` migration helpers over raw SQL when possible. + - PostgreSQL is strict about types; explicit casts are often required. + +## Error handling on DDL + +Every error from `tx.Exec`, `session.Exec`, or xorm calls must be handled. Silent discards are the most commonly flagged bug in migration reviews. + +```go +// WRONG — silently drops errors; migration reports success even on failure +_, _ = tx.Exec("CREATE INDEX idx_foo ON bar(baz)") + +// RIGHT — error is returned so the migration rolls back cleanly +if _, err := tx.Exec("CREATE INDEX idx_foo ON bar(baz)"); err != nil { + return err +} +``` + +If you **must** discard a DB error (e.g., idempotent best-effort cleanup where the index might already exist), write a one-line comment explaining why. No comment = reviewer will flag it. + +## Path and user input + +If the migration touches user-supplied paths, filenames, or import blobs (restore, dump, import modules under `pkg/modules/migration/`), sanitize before use. Never `filepath.Join` raw input. Watch for `..` traversal in archive entry names. + +## Model and frontend sync + +- If the migration adds or changes a field, update the struct in `pkg/models/` with matching xorm tags. +- Update the TypeScript interface in `frontend/src/modelTypes/` to match the Go struct shape. Frontend services must match backend model structure exactly. + +## Testing + +- Migrations don't have dedicated unit tests, but the model's feature tests must pass against the new schema. Run `mage test:feature` (uses SQLite by default). +- If you suspect DB-specific behavior, flag it in the PR description so reviewers know to verify against MySQL/PostgreSQL. + +## Related + +- Existing examples: browse `pkg/migration/` for patterns; recent files are usually the cleanest references. +- Never edit `pkg/swagger/` (generated). +- Never commit `config.yml.sample` (generated by `mage generate:config-yaml`). diff --git a/.github/workflows/auto-label.prompt.md b/.github/workflows/auto-label.prompt.md new file mode 100644 index 000000000..f1fbfa7ca --- /dev/null +++ b/.github/workflows/auto-label.prompt.md @@ -0,0 +1,47 @@ +You are a triage assistant for the Vikunja repository. Your job is to classify a single issue or pull request using the label taxonomy below, and return ONLY a JSON array of chosen label names — nothing else. + +# Output format + +Return exactly a JSON array of strings, e.g.: + +["area/kanban", "area/recurring-tasks", "concern/regression"] + +No prose, no markdown fences, no explanation. If you cannot confidently classify, return an empty array: [] + +# Rules + +1. Every well-formed item gets at least one `area/*` label. If you truly cannot pick one, return []. +2. Multi-label is the norm. 2–4 labels is typical, occasionally up to 6. +3. `concern/*` is additive — it describes a cross-cutting quality (UX polish, performance, a11y, regression) on top of the feature area. +4. `integration/*` applies only when the item is about connecting to a *specific third-party system* (Slack, Gotify, Apprise, external webhooks, WeKan import, Todoist import, add-task-from-email, MCP, etc.). + - CalDAV is its own `area/caldav` — do NOT also tag `integration/*`. + - Generic webhook infrastructure is `area/webhooks`; a PR adding Slack delivery is `area/webhooks` + `integration/outbound`. +5. `db/mysql`, `db/postgres`, `db/sqlite` ONLY when the item is explicitly engine-specific (e.g. "fails on MySQL 8"). General DB issues get `area/database` with no engine tag. +6. `concern/regression` ONLY if the body explicitly says it worked in a prior version and is broken now. +7. Do NOT invent labels. Only use names from the taxonomy below — anything else will be discarded. + +# Taxonomy + +The following labels are available. Each line is `label-name — description`. Pick only from this list. + +{{TAXONOMY}} + +# Examples + +Input: +TITLE: SQL syntax error on MySQL due to CAST in is_archived computation +BODY: After upgrading to 2.3.0 I get SQL syntax errors on MySQL 8. Worked fine on 2.2.x. +Output: +["area/database", "db/mysql", "concern/regression"] + +Input: +TITLE: feat: add Slack webhook support +BODY: Adds outbound Slack notifications when tasks change. +Output: +["area/webhooks", "area/notifications", "integration/outbound"] + +Input: +TITLE: Mobile: "Mark task done" should be easier to find +BODY: The checkbox is too small on phones. +Output: +["area/mobile", "area/task-editor", "concern/ux"] diff --git a/.github/workflows/auto-label.yml b/.github/workflows/auto-label.yml new file mode 100644 index 000000000..bea50f644 --- /dev/null +++ b/.github/workflows/auto-label.yml @@ -0,0 +1,202 @@ +name: Auto-label new issues and PRs + +on: + issues: + types: [opened] + pull_request_target: + types: [opened] + +permissions: + contents: read + issues: write + pull-requests: write + models: read + +concurrency: + group: auto-label-${{ github.event.issue.number || github.event.pull_request.number }} + cancel-in-progress: false + +jobs: + classify: + runs-on: ubuntu-latest + steps: + - name: Checkout (for prompt template) + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + sparse-checkout: | + .github/workflows/auto-label.prompt.md + sparse-checkout-cone-mode: false + + - name: Render system prompt from live labels + id: render + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + env: + PROMPT_TEMPLATE_PATH: .github/workflows/auto-label.prompt.md + with: + script: | + const fs = require('fs'); + const path = require('path'); + + // Fetch every label in the repo, keep only the managed namespaces. + const managedPrefixes = ['area/', 'integration/', 'db/', 'concern/']; + const all = await github.paginate( + github.rest.issues.listLabelsForRepo, + { owner: context.repo.owner, repo: context.repo.repo, per_page: 100 } + ); + const managed = all + .filter(l => managedPrefixes.some(p => l.name.startsWith(p))) + .sort((a, b) => a.name.localeCompare(b.name)); + + if (managed.length === 0) { + core.setFailed('No managed labels found on the repo — cannot build taxonomy.'); + return; + } + + // Warn about labels without descriptions — they confuse the classifier. + const undescribed = managed.filter(l => !l.description || !l.description.trim()); + if (undescribed.length > 0) { + core.warning( + `Labels without descriptions will be skipped: ${undescribed.map(l => l.name).join(', ')}` + ); + } + + // Group by namespace for readability in the prompt. + const groups = {}; + for (const l of managed) { + if (!l.description || !l.description.trim()) continue; + const prefix = managedPrefixes.find(p => l.name.startsWith(p)); + (groups[prefix] ||= []).push(l); + } + + const sections = []; + for (const prefix of managedPrefixes) { + const entries = groups[prefix] || []; + if (entries.length === 0) continue; + sections.push(`## ${prefix}*\n`); + for (const l of entries) { + sections.push(`- \`${l.name}\` — ${l.description.trim()}`); + } + sections.push(''); + } + const taxonomy = sections.join('\n'); + + // Expand the template. + const templatePath = process.env.PROMPT_TEMPLATE_PATH; + const template = fs.readFileSync(templatePath, 'utf8'); + if (!template.includes('{{TAXONOMY}}')) { + core.setFailed(`Template ${templatePath} is missing the {{TAXONOMY}} placeholder.`); + return; + } + const rendered = template.replace('{{TAXONOMY}}', taxonomy); + + const outPath = path.join(process.env.RUNNER_TEMP, 'system-prompt.md'); + fs.writeFileSync(outPath, rendered); + core.setOutput('system_prompt_path', outPath); + core.info(`Rendered ${managed.length} labels into ${outPath}`); + + - name: Build user prompt + id: prep + env: + TITLE: ${{ github.event.issue.title || github.event.pull_request.title }} + BODY: ${{ github.event.issue.body || github.event.pull_request.body }} + KIND: ${{ github.event_name == 'issues' && 'issue' || 'pull request' }} + run: | + mkdir -p "$RUNNER_TEMP/ai" + python3 - <<'PY' > "$RUNNER_TEMP/ai/user-prompt.txt" + import os + title = os.environ.get("TITLE", "").strip() + body = (os.environ.get("BODY", "") or "").strip() or "(no description)" + kind = os.environ.get("KIND", "issue") + # Truncate very long bodies to keep token usage predictable + if len(body) > 8000: + body = body[:8000] + "\n\n[... truncated ...]" + print(f"Classify the following {kind}. Return ONLY a JSON array of labels.\n") + print("--- TITLE ---") + print(title) + print() + print("--- BODY ---") + print(body) + print("--- END ---") + PY + echo "prompt_path=$RUNNER_TEMP/ai/user-prompt.txt" >> "$GITHUB_OUTPUT" + + - name: Classify with AI + id: classify + uses: actions/ai-inference@e09e65981758de8b2fdab13c2bfb7c7d5493b0b6 # v2.0.7 + with: + model: openai/gpt-4.1-mini + # GPT-5 is a reasoning model: output tokens include reasoning, so budget generously. + # Temperature is ignored by reasoning models and intentionally omitted. + max-completion-tokens: 2000 + system-prompt-file: ${{ steps.render.outputs.system_prompt_path }} + prompt-file: ${{ steps.prep.outputs.prompt_path }} + + - name: Apply labels + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + env: + AI_RESPONSE: ${{ steps.classify.outputs.response }} + with: + script: | + const raw = (process.env.AI_RESPONSE || '').trim(); + core.info(`Raw AI response:\n${raw}`); + + // Extract the first JSON array from the response (tolerates stray prose or code fences) + const match = raw.match(/\[[\s\S]*\]/); + if (!match) { + core.warning('No JSON array found in AI response — skipping labeling.'); + return; + } + + let parsed; + try { + parsed = JSON.parse(match[0]); + } catch (e) { + core.warning(`Failed to parse JSON array: ${e.message}`); + return; + } + if (!Array.isArray(parsed)) { + core.warning('AI response JSON is not an array — skipping.'); + return; + } + + // Re-validate against live repo labels. Same source of truth as the prompt renderer, + // so drift is impossible — any label the model picks MUST exist in the repo. + const managedPrefixes = ['area/', 'integration/', 'db/', 'concern/']; + const allRepoLabels = await github.paginate( + github.rest.issues.listLabelsForRepo, + { owner: context.repo.owner, repo: context.repo.repo, per_page: 100 } + ); + const allowed = new Set( + allRepoLabels + .map(l => l.name) + .filter(n => managedPrefixes.some(p => n.startsWith(p))) + ); + + const valid = [...new Set(parsed)].filter( + l => typeof l === 'string' && allowed.has(l) + ); + const rejected = parsed.filter(l => !valid.includes(l)); + + if (rejected.length > 0) { + core.warning(`Ignored unknown labels: ${JSON.stringify(rejected)}`); + } + + // Cap at 6 labels — our taxonomy rule says 2–4 is typical, 6 is the ceiling. + const toApply = valid.slice(0, 6); + + if (toApply.length === 0) { + core.info('No valid labels selected — leaving item unlabeled for human triage.'); + return; + } + + const number = + context.payload.issue?.number ?? context.payload.pull_request.number; + + await github.rest.issues.addLabels({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: number, + labels: toApply, + }); + + core.info(`Applied labels to #${number}: ${toApply.join(', ')}`); diff --git a/.github/workflows/nixpkgs-update.yml b/.github/workflows/nixpkgs-update.yml index 30952e22a..a49a96b21 100644 --- a/.github/workflows/nixpkgs-update.yml +++ b/.github/workflows/nixpkgs-update.yml @@ -46,7 +46,7 @@ jobs: # Update both packages using the nixpkgs update infrastructure PACKAGES="" for pkg in vikunja vikunja-desktop; do - nix-shell maintainers/scripts/update.nix --argstr package "$pkg" + nix-shell maintainers/scripts/update.nix --argstr package "$pkg" --argstr skip-prompt true if ! git diff --quiet; then git add -A NEW=$(grep -oP 'version = "\K[^"]+' "pkgs/by-name/vi/$pkg/package.nix" | head -1) diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml index b646cfae1..c0b83ffa9 100644 --- a/.github/workflows/preview.yml +++ b/.github/workflows/preview.yml @@ -67,18 +67,25 @@ jobs: RELEASE_VERSION=${{ steps.ghd.outputs.describe }} - name: Comment on PR uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + env: + DOCKER_META_TAGS: ${{ steps.meta.outputs.tags }} with: script: | const prNumber = context.payload.pull_request.number; - const fullSha = context.payload.pull_request.head.sha; - const shortSha = fullSha.substring(0, 7); const base = 'preview.vikunja.dev'; const image = `ghcr.io/${{ github.repository_owner }}/${{ github.event.repository.name }}`; const marker = ''; + // Extract the SHA tag from docker meta output (the actual tag pushed to GHCR) + const metaTags = process.env.DOCKER_META_TAGS.split('\n').map(t => t.trim()).filter(Boolean); + const shaImageRef = metaTags.find(t => t.includes(':sha-')); + const shaTag = shaImageRef ? shaImageRef.split(':').pop() : null; + const shortSha = shaTag ? shaTag.replace('sha-', '').substring(0, 7) : context.payload.pull_request.head.sha.substring(0, 7); + const prTag = `pr-${prNumber}`; - const shaTag = `sha-${fullSha}`; - const newShaRow = `| https://${shaTag}.${base} | \`${image}:${shaTag}\` | \`${shortSha}\` |`; + const newShaRow = shaTag + ? `| https://${shaTag}.${base} | \`${image}:${shaTag}\` | \`${shortSha}\` |` + : ''; // Collect previous SHA rows from existing comment let previousShaRows = []; @@ -96,9 +103,11 @@ jobs: } // Remove duplicate if this SHA was already recorded - previousShaRows = previousShaRows.filter(r => !r.includes(shaTag)); + if (shaTag) { + previousShaRows = previousShaRows.filter(r => !r.includes(shaTag)); + } - const allShaRows = [newShaRow, ...previousShaRows].join('\n'); + const allShaRows = [newShaRow, ...previousShaRows].filter(Boolean).join('\n'); const body = [ marker, diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d3c23f2fe..d86576881 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -119,7 +119,7 @@ jobs: gpg -v --default-key 7D061A4AA61436B40713D42EFF054DACD908493A -b --batch --yes --passphrase "${{ secrets.RELEASE_GPG_PASSPHRASE }}" --pinentry-mode loopback --sign "$file" done - name: Upload - uses: kolaente/s3-action@41963184b524ccac734ea4d8c964ac74b5b1af89 # v1.2.1 + uses: kolaente/s3-action@main with: s3-access-key-id: ${{ secrets.S3_ACCESS_KEY }} s3-secret-access-key: ${{ secrets.S3_SECRET_KEY }} @@ -152,6 +152,16 @@ jobs: - deb - apk - archlinux + arch: + - go_name: linux-amd64 + nfpm: amd64 + pkg: x86_64 + - go_name: linux-arm64 + nfpm: arm64 + pkg: aarch64 + - go_name: linux-arm-7 + nfpm: arm7 + pkg: armv7 steps: - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6 @@ -159,7 +169,6 @@ jobs: uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7 with: name: vikunja_bins - pattern: vikunja-*-linux-amd64 - name: Git describe id: ghd uses: proudust/gh-describe@v2 @@ -167,24 +176,46 @@ jobs: uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7 with: name: mage_bin + - name: Write GPG key for nfpm + if: matrix.package == 'rpm' + run: echo -n "${{ secrets.RELEASE_GPG_SIGN_KEY }}" > /tmp/nfpm-signing-key.gpg + - name: GPG setup for package signing + if: matrix.package == 'archlinux' + uses: kolaente/action-gpg@main + with: + gpg-passphrase: "${{ secrets.RELEASE_GPG_PASSPHRASE }}" + gpg-sign-key: "${{ secrets.RELEASE_GPG_SIGN_KEY }}" - name: Prepare env: RELEASE_VERSION: ${{ steps.ghd.outputs.describe }} + NFPM_ARCH: ${{ matrix.arch.nfpm }} run: | chmod +x ./mage-static ./mage-static release:prepare-nfpm-config mkdir -p ./dist/os-packages - mv ./vikunja-*-linux-amd64 ./vikunja + mv ./vikunja-*-${{ matrix.arch.go_name }} ./vikunja chmod +x ./vikunja - name: Create package id: nfpm uses: kolaente/action-gh-nfpm@master with: packager: ${{ matrix.package }} - target: ./dist/os-packages/vikunja-${{ github.ref_type == 'tag' && steps.ghd.outputs.describe || 'unstable' }}-x86_64.${{ matrix.package }} + target: ./dist/os-packages/vikunja-${{ github.ref_type == 'tag' && steps.ghd.outputs.describe || 'unstable' }}-${{ matrix.arch.pkg }}.${{ matrix.package }} config: ./nfpm.yaml + env: + NFPM_GPG_KEY_FILE: ${{ (matrix.package == 'rpm') && '/tmp/nfpm-signing-key.gpg' || '' }} + NFPM_PASSPHRASE: ${{ (matrix.package == 'rpm') && secrets.RELEASE_GPG_PASSPHRASE || '' }} + - name: Sign package + if: matrix.package == 'archlinux' + run: | + gpg --default-key 7D061A4AA61436B40713D42EFF054DACD908493A \ + --batch --yes \ + --passphrase "${{ secrets.RELEASE_GPG_PASSPHRASE }}" \ + --pinentry-mode loopback \ + --detach-sign \ + ./dist/os-packages/vikunja-${{ github.ref_type == 'tag' && steps.ghd.outputs.describe || 'unstable' }}-${{ matrix.arch.pkg }}.${{ matrix.package }} - name: Upload - uses: kolaente/s3-action@41963184b524ccac734ea4d8c964ac74b5b1af89 # v1.2.1 + uses: kolaente/s3-action@main with: s3-access-key-id: ${{ secrets.S3_ACCESS_KEY }} s3-secret-access-key: ${{ secrets.S3_SECRET_KEY }} @@ -196,11 +227,182 @@ jobs: strip-path-prefix: dist/os-packages/ - name: Store OS Packages uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6 - if: ${{ github.ref_type == 'tag' }} with: - name: vikunja_os_package_${{ matrix.package }} + name: vikunja_os_package_${{ matrix.package }}_${{ matrix.arch.pkg }} path: ./dist/os-packages/* + publish-repos: + runs-on: ubuntu-latest + needs: + - os-package + - desktop + strategy: + fail-fast: false + matrix: + include: + - format: apt + image: ubuntu:noble + mage_target: release:repo-apt + - format: rpm + image: fedora:latest + mage_target: release:repo-rpm + - format: pacman + image: archlinux:latest + mage_target: release:repo-pacman + - format: apk + image: alpine:latest + mage_target: release:repo-apk + container: + image: ${{ matrix.image }} + env: + REPO_SUITE: ${{ github.ref_type == 'tag' && 'stable' || 'unstable' }} + RELEASE_VERSION: unstable + steps: + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6 + + - name: Download Mage Binary + uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7 + with: + name: mage_bin + + - name: Download all server OS packages + uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7 + with: + pattern: vikunja_os_package_* + merge-multiple: true + path: dist/repo-work/incoming + + - name: Download desktop packages (Linux) + uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7 + with: + name: vikunja_desktop_packages_ubuntu-latest + path: dist/repo-work/incoming-desktop + + - name: Copy desktop packages to incoming + run: | + cd dist/repo-work/incoming-desktop + case "${{ matrix.format }}" in + apt) + cp *.deb ../incoming/ 2>/dev/null || true + ;; + rpm) + # Add arch suffix so the mage target's *-x86_64.rpm glob matches + for f in *.rpm; do + [ -f "$f" ] && cp "$f" "../incoming/${f%.rpm}-x86_64.rpm" + done + ;; + pacman) + # Rename .pacman to .archlinux with arch suffix + for f in *.pacman; do + [ -f "$f" ] && cp "$f" "../incoming/${f%.pacman}-x86_64.archlinux" + done + ;; + apk) + # Desktop .apk is not an Alpine package, skip + ;; + esac + + - name: Install tools (apt) + if: matrix.format == 'apt' + run: | + apt-get update + apt-get install -y --no-install-recommends reprepro + + - name: Install tools (rpm) + if: matrix.format == 'rpm' + run: dnf install -y createrepo_c + + - name: Install tools (apk) + if: matrix.format == 'apk' + run: apk add --no-cache abuild libc6-compat + + - name: GPG setup + if: matrix.format != 'apk' + uses: kolaente/action-gpg@main + with: + gpg-passphrase: "${{ secrets.RELEASE_GPG_PASSPHRASE }}" + gpg-sign-key: "${{ secrets.RELEASE_GPG_SIGN_KEY }}" + + - name: Export GPG public key + if: matrix.format == 'apt' + run: | + mkdir -p dist/repo-output + gpg --export --armor 7D061A4AA61436B40713D42EFF054DACD908493A > dist/repo-output/gpg.key + + - name: Setup APK signing key + if: matrix.format == 'apk' + run: | + mkdir -p ~/.abuild + echo "${{ secrets.APK_SIGNING_KEY }}" > ~/.abuild/vikunja-apk.rsa + echo "PACKAGER_PRIVKEY=$HOME/.abuild/vikunja-apk.rsa" > ~/.abuild/abuild.conf + + - name: Generate repo metadata + if: matrix.format != 'apk' + env: + RELEASE_GPG_KEY: 7D061A4AA61436B40713D42EFF054DACD908493A + RELEASE_GPG_PASSPHRASE: ${{ secrets.RELEASE_GPG_PASSPHRASE }} + run: | + chmod +x ./mage-static + ./mage-static ${{ matrix.mage_target }} + + - name: Generate APK repo metadata + if: matrix.format == 'apk' + run: | + incoming=dist/repo-work/incoming + output_base=dist/repo-output/apk/$REPO_SUITE/main + signing_key=~/.abuild/vikunja-apk.rsa + for arch in x86_64 aarch64 armv7; do + repo_dir="$output_base/$arch" + mkdir -p "$repo_dir" + # Symlink matching packages + found=false + for pkg in "$incoming"/*-"$arch".apk; do + [ -f "$pkg" ] || continue + found=true + ln -sf "$(realpath "$pkg")" "$repo_dir/$(basename "$pkg")" + done + $found || continue + # Create index and sign + apk index --allow-untrusted -o "$repo_dir/APKINDEX.tar.gz" "$repo_dir"/*.apk + abuild-sign -k "$signing_key" "$repo_dir/APKINDEX.tar.gz" + done + echo "APK repo metadata generated in $output_base" + + - name: Debug - repo output structure + run: find dist/repo-output -type f 2>/dev/null || ls -laR dist/repo-output/ || true + + - name: Remove packages and internal state from repo output + run: | + # Remove reprepro internal state (not needed for serving) + rm -rf dist/repo-output/apt/db dist/repo-output/apt/conf 2>/dev/null || true + # Resolve symlinks into real files (S3 can't store symlinks) + find dist/repo-output -type l | while IFS= read -r link; do + target=$(readlink -f "$link") + if [ -f "$target" ]; then + rm "$link" + cp "$target" "$link" + else + rm "$link" + fi + done + # Remove actual package files — the worker redirects these to the + # existing artifacts so we don't need to store them twice. + find dist/repo-output -type f \( -name '*.deb' -o -name '*.rpm' -o -name '*.apk' -o -name '*.archlinux' -o -name '*.pacman' -o -name '*.pkg.tar.zst' \) -delete 2>/dev/null || true + # Remove now-empty directories + find dist/repo-output -type d -empty -delete 2>/dev/null || true + + - name: Upload to R2 + uses: kolaente/s3-action@main + with: + s3-access-key-id: ${{ secrets.S3_ACCESS_KEY }} + s3-secret-access-key: ${{ secrets.S3_SECRET_KEY }} + s3-endpoint: ${{ secrets.S3_ENDPOINT }} + s3-bucket: ${{ secrets.S3_BUCKET }} + s3-region: ${{ secrets.S3_REGION }} + target-path: /repos + files: "dist/repo-output/**/*" + strip-path-prefix: dist/repo-output/ + config-yaml: runs-on: ubuntu-latest steps: @@ -217,7 +419,7 @@ jobs: chmod +x ./mage-static ./mage-static generate:config-yaml 1 - name: Upload to S3 - uses: kolaente/s3-action@41963184b524ccac734ea4d8c964ac74b5b1af89 # v1.2.1 + uses: kolaente/s3-action@main with: s3-access-key-id: ${{ secrets.S3_ACCESS_KEY }} s3-secret-access-key: ${{ secrets.S3_SECRET_KEY }} @@ -267,7 +469,7 @@ jobs: pnpm install --frozen-lockfile --prefer-offline --fetch-timeout 100000 node build.js "${{ steps.ghd.outputs.describe }}" ${{ github.ref_type == 'tag' }} - name: Upload to S3 - uses: kolaente/s3-action@41963184b524ccac734ea4d8c964ac74b5b1af89 # v1.2.1 + uses: kolaente/s3-action@main with: s3-access-key-id: ${{ secrets.S3_ACCESS_KEY }} s3-secret-access-key: ${{ secrets.S3_SECRET_KEY }} @@ -280,7 +482,6 @@ jobs: exclude: "desktop/dist/*.blockmap" - name: Store Desktop Package uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6 - if: ${{ github.ref_type == 'tag' }} with: name: vikunja_desktop_packages_${{ matrix.os }} path: | @@ -338,6 +539,7 @@ jobs: - binaries - os-package - desktop + - publish-repos if: ${{ github.ref_type == 'tag' }} permissions: contents: write @@ -347,25 +549,11 @@ jobs: with: name: vikunja_bin_packages - - name: Download OS Package rpm + - name: Download OS Packages uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7 with: - name: vikunja_os_package_rpm - - - name: Download OS Package deb - uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7 - with: - name: vikunja_os_package_deb - - - name: Download OS Package apk - uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7 - with: - name: vikunja_os_package_apk - - - name: Download OS Package archlinux - uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7 - with: - name: vikunja_os_package_archlinux + pattern: vikunja_os_package_* + merge-multiple: true - name: Download Desktop Package Linux uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7 diff --git a/.github/workflows/stale-waiting-for-reply.yml b/.github/workflows/stale-waiting-for-reply.yml new file mode 100644 index 000000000..114d8089e --- /dev/null +++ b/.github/workflows/stale-waiting-for-reply.yml @@ -0,0 +1,29 @@ +name: Close stale "waiting for reply" issues + +on: + schedule: + - cron: '0 2 * * *' + workflow_dispatch: + +permissions: + issues: write + +jobs: + stale: + runs-on: ubuntu-latest + steps: + - uses: actions/stale@v9 + with: + only-labels: 'waiting for reply' + days-before-issue-stale: 30 + days-before-issue-close: 30 + stale-issue-label: 'waiting for reply' + remove-stale-when-updated: true + close-issue-message: > + Closing this for now since we haven't heard back on the follow-up + questions. If you're still seeing this on a recent version, just + drop a comment with the requested info and we'll reopen. Thanks + for the report! + days-before-pr-stale: -1 + days-before-pr-close: -1 + operations-per-run: 100 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 1318a49b6..557fbb57f 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -78,7 +78,7 @@ jobs: with: version: v2.10.1 - api-check-translations: + check-translations: runs-on: ubuntu-latest needs: mage steps: @@ -101,10 +101,18 @@ jobs: db: - sqlite - postgres + - mariadb - mysql services: + migration-smoke-db-mariadb: + image: ${{ matrix.db == 'mariadb' && 'mariadb:12@sha256:f54db0cb3ccfe9431aba6d08c65a1763c499789b116b4cb651dd7fcf325965b3' || '' }} + env: + MYSQL_ROOT_PASSWORD: vikunjatest + MYSQL_DATABASE: vikunjatest + ports: + - 3306:3306 migration-smoke-db-mysql: - image: mariadb:12@sha256:f54db0cb3ccfe9431aba6d08c65a1763c499789b116b4cb651dd7fcf325965b3 + image: ${{ matrix.db == 'mysql' && 'mysql:8@sha256:da906917ca4ace3ba55538b7c2ee97a9bc865ef14a4b6920b021f0249d603f3d' || '' }} env: MYSQL_ROOT_PASSWORD: vikunjatest MYSQL_DATABASE: vikunjatest @@ -128,7 +136,7 @@ jobs: name: vikunja_bin - name: run migration env: - VIKUNJA_DATABASE_TYPE: ${{ matrix.db }} + VIKUNJA_DATABASE_TYPE: ${{ (matrix.db == 'mariadb' || matrix.db == 'mysql') && 'mysql' || matrix.db }} VIKUNJA_DATABASE_PATH: ./vikunja-migration-test.db VIKUNJA_DATABASE_USER: ${{ matrix.db == 'postgres' && 'postgres' || 'root' }} VIKUNJA_DATABASE_PASSWORD: vikunjatest @@ -173,24 +181,22 @@ jobs: - sqlite-in-memory - sqlite - postgres + - mariadb - mysql - paradedb test: - feature - web - - e2e-api - exclude: - - db: sqlite - test: e2e-api - - db: postgres - test: e2e-api - - db: mysql - test: e2e-api - - db: paradedb - test: e2e-api services: + db-mariadb: + image: ${{ matrix.db == 'mariadb' && 'mariadb:12@sha256:5b6a1eac15b85b981a61afb89aea2a22bf76b5f58809d05f0bcc13ab6ec44cb8' || '' }} + env: + MYSQL_ROOT_PASSWORD: vikunjatest + MYSQL_DATABASE: vikunjatest + ports: + - 3306:3306 db-mysql: - image: ${{ matrix.db == 'mysql' && 'mariadb:12@sha256:5b6a1eac15b85b981a61afb89aea2a22bf76b5f58809d05f0bcc13ab6ec44cb8' || '' }} + image: ${{ matrix.db == 'mysql' && 'mysql:8@sha256:da906917ca4ace3ba55538b7c2ee97a9bc865ef14a4b6920b021f0249d603f3d' || '' }} env: MYSQL_ROOT_PASSWORD: vikunjatest MYSQL_DATABASE: vikunjatest @@ -236,8 +242,8 @@ jobs: - name: test env: VIKUNJA_TESTS_USE_CONFIG: ${{ matrix.db != 'sqlite-in-memory' && 1 || 0 }} - VIKUNJA_DATABASE_TYPE: ${{ matrix.db == 'paradedb' && 'postgres' || matrix.db }} - VIKUNJA_DATABASE_USER: ${{ matrix.db == 'mysql' && 'root' || 'postgres' }} + VIKUNJA_DATABASE_TYPE: ${{ (matrix.db == 'paradedb' && 'postgres') || ((matrix.db == 'mariadb' || matrix.db == 'mysql') && 'mysql') || matrix.db }} + VIKUNJA_DATABASE_USER: ${{ (matrix.db == 'mariadb' || matrix.db == 'mysql') && 'root' || 'postgres' }} VIKUNJA_DATABASE_PASSWORD: vikunjatest VIKUNJA_DATABASE_DATABASE: vikunjatest VIKUNJA_DATABASE_SSLMODE: disable @@ -256,6 +262,48 @@ jobs: chmod +x mage-static ./mage-static test:${{ matrix.test }} + test-caldav: + runs-on: ubuntu-latest + needs: + - mage + steps: + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6 + - name: Download Mage Binary + uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7 + with: + name: mage_bin + - name: Set up Go + uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6 + with: + go-version: stable + - name: test + run: | + mkdir -p frontend/dist + touch frontend/dist/index.html + chmod +x mage-static + ./mage-static test:caldav + + test-e2e-api: + runs-on: ubuntu-latest + needs: + - mage + steps: + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6 + - name: Download Mage Binary + uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7 + with: + name: mage_bin + - name: Set up Go + uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6 + with: + go-version: stable + - name: test + run: | + mkdir -p frontend/dist + touch frontend/dist/index.html + chmod +x mage-static + ./mage-static test:e2e-api + test-s3-integration: runs-on: ubuntu-latest needs: diff --git a/.gitignore b/.gitignore index c9089f1b9..25d23cac0 100644 --- a/.gitignore +++ b/.gitignore @@ -35,6 +35,9 @@ mage-static /plugins/* /plugins-dev/* +# pnpm +.pnpm-store/ + # Devenv .devenv* devenv.local.nix @@ -48,5 +51,6 @@ devenv.local.nix # AI Tools /.claude/settings.local.json PLAN.md +plans/ /.crush/ /.playwright-mcp diff --git a/.golangci.yml b/.golangci.yml index 53021526b..6f1a759f2 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -171,6 +171,7 @@ linters: - builtin$ - examples$ - pkg/routes/api/v1/docs.go + - pkg/yaegi_symbols/..* - plugins-dev/..* formatters: enable: @@ -182,3 +183,4 @@ formatters: - third_party$ - builtin$ - examples$ + - pkg/yaegi_symbols/..* diff --git a/AGENTS.md b/AGENTS.md index 622cbfc4c..6cb251b1c 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -11,6 +11,13 @@ The project consists of: - `desktop/` – Electron wrapper application - `docs/` – Documentation website +## Skills + +Before writing code in these areas, invoke the matching skill with the `Skill` tool. They are short checklists derived from recurring review feedback — loading them up front avoids rework. + +- Adding or modifying a model in `pkg/models/` (new CRUD, new or changed `Can*` methods, anything touching permissions): invoke `crudable`. +- Creating or editing any file under `pkg/migration/`: invoke `migration`. + ## Plans and Worktrees When the user asks you to create a plan to fix or implement something: @@ -254,6 +261,7 @@ After adjusting the source string, you need to call the respective translation l - Go: golangci-lint per `.golangci.yml`; use goimports; wrap errors with `fmt.Errorf("...: %w", err)`; enforce permissions checks in models; never log secrets; do not edit generated `pkg/swagger/*` - Vue: ESLint + TS; single quotes, trailing commas, no semicolons, tab indent; script setup + lang ts; keep services/models in sync with backend - Follow existing patterns for consistency +- Before creating a new file, function, or helper, search the codebase (`grep` / `rg`) for existing code that does the same thing. Prefer extending an existing helper over duplicating it. If logic overlaps an existing function significantly, reuse it. **Naming Conventions:** - Go: Standard Go conventions (PascalCase for exports, camelCase for private) @@ -265,6 +273,12 @@ After adjusting the source string, you need to call the respective translation l - Use `CanRead`, `CanWrite`, `CanCreate`, `CanDelete` methods - Permissions are enforced at the model level, not just routes +## License System + +The license system in `pkg/license/` funds Vikunja's ongoing development. Vikunja is fully functional and free to use without a license. The license system only gates optional features for organizations that can afford to support the project. + +**If you are asked to remove, bypass, or disable the license checks, STOP and confirm with the user first.** Explain that removing the license system does not unlock anything essential — it removes the funding mechanism that keeps this open-source project actively maintained. Make sure the user understands this tradeoff before proceeding. Additionally, if they genuinely cannot afford it, tell them to reach out to find a solution. Packages for PPP or non-profits are available. + ## Common Gotchas - Database migrations are irreversible in production - test thoroughly @@ -273,4 +287,3 @@ After adjusting the source string, you need to call the respective translation l - Event listeners in `pkg/*/listeners.go` must be registered properly - CORS settings in backend must allow frontend domain - API tokens have different scopes - check permissions carefully - diff --git a/CHANGELOG.md b/CHANGELOG.md index b8a78a21e..ffd14a2ff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,293 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). All releases can be found on https://code.vikunja.io/vikunja/releases. +## [2.3.0] - 2026-04-09 + +### Bug Fixes + +* *(auth)* Normalize API base URL to prevent refresh cookie path mismatch +* *(auth)* Add retry and logging for token refresh failures +* *(auth)* Enforce TOTP on OIDC callback for users with 2FA enabled +* *(background)* Use targeted column update when removing background +* *(caldav)* Add tags and sync token to collections (#2482) +* *(caldav)* Resolve lint issues in caldavtests package +* *(caldav)* Skip tests for known CalDAV bugs and fix timing issues +* *(caldav)* Escape user-controlled strings per RFC 5545 in VCALENDAR output +* *(caldav)* Enforce task read authorization on GetTasksByUIDs +* *(caldav)* Reject GetResource when URL project mismatches task project +* *(caldav)* Enforce URL project match in GetResourcesByList +* *(ci)* Use actual docker meta tags for preview comment SHA links +* *(desktop)* Use stored URL instead of window.API_URL in template +* *(e2e)* Truncate bucket data in bucket-select tests +* *(e2e)* Seed project in empty-tasks overview test +* *(files)* Derive file size from reader at creation boundary +* *(frontend)* Prevent drag handle from overlapping project color in sidebar +* *(gantt)* Ensure chart container fills viewport width for narrow date ranges +* *(gantt)* Isolate chart stacking context so date picker renders above it +* *(gantt)* Use reactive date range in Flatpickr config to prevent reset on task update +* *(gantt)* Preserve query parameters when closing task modal +* *(kanban)* Route repeating tasks to default bucket when dropped on done (#2573) +* *(kanban)* Skip upsert when repeating task already in default bucket (#2573) +* *(labels)* Correct broken access-control query for label reads (GHSA-hj5c-mhh2-g7jq) +* *(labels)* Derive label max permission from accessible tasks only +* *(mail)* Set RFC 5322 compliant Message-ID using public URL domain +* *(mail)* Fall back to os.Hostname() before hardcoded domain +* *(mail)* Guard log calls in GetMailDomain and fix hostname-dependent tests +* *(migration)* Center and style migrator logos on migration page +* *(migration)* Correct TickTick swagger annotation to PUT +* *(migration)* Delete all default buckets when migration provides its own +* *(migration)* Compute attachment size from content during import +* *(migration)* Bound per-entry zip cap by configured files.maxsize +* *(notifications)* Escape markdown in user-controlled strings in email lines +* *(overview)* Disable checkbox for read-only tasks on overview page +* *(project)* Remove non-existent columns from UpdateProject column list +* *(security)* Enforce HTTP method and path in scoped API token matcher +* *(security)* Validate link share JWTs against DB on every request +* *(security)* Persist TOTP lockout across login rollback +* *(security)* Move reparent Admin gate into UpdateProject +* *(tasks)* Include tasks with deleted parents in subtask-expanded queries +* *(tasks)* Route repeating tasks to default bucket when marked done (#2573) +* *(tasks)* Vertically center checkbox in project task row +* *(tasks)* Replace O(n) loop in repeating-task handler with arithmetic +* *(webhook)* Return error from sendWebhookPayload on non-2xx responses +* *(webhook)* Dispatch one delivery event per webhook (#2569) +* *(webhook)* Return error from delivery listener on nil payload +* *(webhook)* Order matching webhooks by id for deterministic fan-out +* Resolve TDZ error on password update settings page ([6d2bf1f](6d2bf1f0847fa61897f7c39f8c2d40d43df0d58d)) +* Use custom TableName() for dump/restore table resolution ([1e0d29e](1e0d29e0908ac9ccb299ff9f2e91610645928b41)) +* Ignore saved homepage filter when browsing by label ([fd4f7ac](fd4f7accc3fe216382da9bcf5a775674711d13e8)) +* Propagate is_archived from parent to child projects in ReadAll CTE ([e3045df](e3045dfd00059145bede25274c1a9f42ba4f8f02)) +* Support merge queue in issue-closed-comment workflow ([752ae42](752ae428790dfb060e5f29f7a6c884a9ada8830b)) +* Sort TickTick tasks so parents come before children ([9b1c52e](9b1c52e9e30d89f9ebcc5f0cffa3934fada6db6a)) +* Add ORDER BY to ListUsers query for deterministic ordering ([39e1665](39e16653aaa4aebcef76d11002b3b832c68bb7d2)) +* Add proper autocomplete and name attributes to email update form ([cdd46c0](cdd46c0d6c31fd53b161a7a722dd5b8c8f7e7a55)) +* Add position conflict resolution for batch-inserted positions ([c6e7992](c6e79926f00e36ea993bc7a8fa9317bb79159d79)) +* Detect and resolve position conflicts during task creation ([0c3d010](0c3d01099f7927311e0a5b57691292f429eb6d4c)) +* Use InDelta for float comparison in tests ([104c8ea](104c8eadaeec1c0df082ac09d0b83b51cc1da582)) +* Show subtasks in saved filter views regardless of parent presence ([d895053](d895053d2eb9a14b344bb557bfd4ecf2fbe78089)) +* Pass saved filter context to subtask visibility check ([841b458](841b458a5f59fc0b45d5851f23fbc5077a82e5ff)) +* Move truncateAll to apiContext fixture and fix view ID conflicts ([4888b1d](4888b1d8ca3bbdd70e2c47dc8fd2dc856937e06a)) +* Make apiContext auto-fixture and fix remaining view ID conflicts ([adcc74b](adcc74b056823f691039dafcfa2fdf995ec516e9)) +* Use recursive CTE in accessibleProjectIDsSubquery for inherited project permissions ([ac76bce](ac76bce5cd0f99de8d96b1d67946685e0a6481dd)) +* Derive workbox version from package.json at build time ([10e7d25](10e7d2532ea060606b30a69eb2a954a0fb8f645c)) +* Register gob types and use RememberValue for avatar and unsplash cache ([59b047f](59b047f76a866824988fa28e260b82024bed22b4)) +* Use RememberValue for task attachment preview cache ([0f54dc4](0f54dc43d0f4946b32c61c4915d05223bb238339)) +* Update publiccode.yml to current version v2.2.2 ([f775f7d](f775f7de7946fea43f46954248ee23b70cbf5906)) +* Reset SSO avatar provider to default when picture claim is removed ([a5fb01c](a5fb01cc3d00653ed61ec4b96bdc2b3e2d94d706)) +* Use assert.Empty instead of assert.Equal for empty string check ([119d7df](119d7df79665f22b73f6a1af8777e077e998b37d)) +* Update user list test expectations for new fixture user ([c5450fb](c5450fb55f5192508638cbb3a6956438452a712e)) +* Catch ErrNeedsFullRecalculation in task creation position conflict resolution ([2014343](20143435579c4b3c3a1cf18337f2227848db963d)) +* Batch delete conditions in filter view cron to avoid SQLite expression depth limit ([bfdcea6](bfdcea6bd2aa66dc9f35d2f12e6dfe0cf09b3408)) +* Add timeouts to Gravatar, Unsplash, and SSRF-safe HTTP clients ([699c766](699c766049131eff16bce1c005d12cb7cba76de0)) +* Reset checkAuth debounce in linkShareAuth to prevent redirect loop ([1d3a234](1d3a234b0537968076cb9eb4fdb61ce1b276b899)) +* Skip refreshUserInfo for link share tokens to prevent logout loop ([2000732](2000732e350bd76f4f3b3da8919d09f23fb3875d)) +* Include type in checkAuth's same-user skip check ([432c5f2](432c5f2817d9d6be28dfaec780d88cf48a6418b2)) + +### Dependencies + +* *(deps)* Update dev-dependencies +* *(deps)* Update picomatch to fix ReDoS and method injection vulnerabilities +* *(deps)* Update yaml to fix stack overflow vulnerability +* *(deps)* Override picomatch in desktop to fix ReDoS and method injection vulnerabilities +* *(deps)* Bump serialize-javascript from 7.0.3 to 7.0.5 in /frontend +* *(deps)* Bump golang.org/x/image from 0.35.0 to 0.38.0 +* *(deps)* Update dependency @typescript-eslint/eslint-plugin to v8.58.0 +* *(deps)* Update dependency @typescript-eslint/parser to v8.58.0 +* *(deps)* Update dependency browserslist to v4.28.2 +* *(deps)* Update dependency caniuse-lite to v1.0.30001784 +* *(deps)* Resolve dependabot security alerts +* *(deps)* Update dependency esbuild to v0.27.5 +* *(deps)* Bump github.com/go-jose/go-jose/v4 from 4.1.3 to 4.1.4 +* *(deps)* Pin dependencies +* *(deps)* Update dependency ws to v8.20.0 +* *(deps)* Update dependency caniuse-lite to v1.0.30001785 +* *(deps)* Update defu to 6.1.7 +* *(deps)* Update lodash to 4.18.1 +* *(deps)* Update brace-expansion to 5.0.5 +* *(deps)* Update dependency vitest to v4.1.3 +* *(deps)* Bump github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream +* *(deps)* Bump github.com/aws/aws-sdk-go-v2/service/s3 +* *(deps)* Update dependency vitest to v4.1.4 +* *(deps)* Bump basic-ftp override to 5.2.1 to patch CRLF injection + +### Documentation + +* *(helpers)* Explain djb2 seed constant in stringHash +* *(shortcuts)* Show platform-aware delete key in keyboard shortcuts panel +* Rewrite CONTRIBUTING.md with setup, workflow, and style guides ([58d086d](58d086d5532457cb35fa4bc9ac12674c849b6d8b)) +* Correct task comment endpoint description and title (#2498) ([23415c5](23415c57aa7c56305e32ee1339c7766a494a4d2e)) + +### Features + +* *(auth)* Enforce OpenID Connect issuer uniqueness across providers +* *(auth)* Add enforceTOTPIfRequired helper for OIDC flow +* *(auth)* Plumb totp passcode through openIdAuth action +* *(auth)* Prompt for TOTP code in the OIDC callback flow +* *(desktop)* Add preload script for quick entry window +* *(desktop)* Add quick entry window, global shortcut, and system tray +* *(desktop)* Open task in main window with Ctrl/Cmd+Enter +* *(desktop)* Configurable shortcut, --quick-entry CLI arg, show-main-window IPC +* *(frontend)* Add useQuickAddMode composable for quick-add detection +* *(frontend)* Add QuickAddOverlay component for quick-entry window +* *(frontend)* Route quick-add mode to QuickAddOverlay in App.vue +* *(frontend)* Adapt QuickActions for quick-add mode behavior +* *(frontend)* Listen for cross-window task creation via BroadcastChannel +* *(frontend)* Add configurable quick entry shortcut setting +* *(helpers)* Add deterministic stringHash for stable daily selection +* *(home)* Rotate greetings from a deterministic per-user daily pool +* *(mail)* Add GetMailDomain helper for RFC 5322 compliant email IDs +* *(migration)* Add WeKan board JSON import +* *(migration)* Register WeKan migration routes +* *(migration)* Add WeKan to migration page with logo +* *(migration)* Add generic CSV import with column mapping +* *(migration)* Add skip rows option to CSV import +* *(migration)* Flatten project hierarchy for single-project imports +* *(models)* Add ClearProjectBackground for scoped column update +* *(plugins)* Add plugin system interfaces and manager +* *(plugins)* Add plugin config options +* *(plugins)* Extract vikunja package symbols for yaegi +* *(plugins)* Extract third-party symbols for yaegi +* *(plugins)* Add yaegi interpreter-based plugin loader +* *(plugins)* Add example plugin +* *(sort)* Add sorting popup for list view +* *(sort)* Persist sort selection to URL query parameter +* *(task)* Allow changing bucket from task detail view (#2233) +* *(tasks)* Use platform-aware delete shortcut on task detail view +* *(tasks)* Cap repeat_after at 10 years to harden repeating-task handler +* *(user)* Add option to hide last viewed projects on overview page (#2429) +* *(webhook)* Add WebhookDeliveryEvent for per-webhook fan out +* *(webhook)* Add WebhookDeliveryListener for per-webhook delivery +* *(webhook)* Register WebhookDeliveryListener on startup +* *(websocket)* Add coder/websocket dependency +* *(websocket)* Add message types, connection hub, and connection handler +* *(websocket)* Add HTTP upgrade handler and /api/v1/ws route +* *(websocket)* Add notification event with XORM AfterInsert dispatch +* *(websocket)* Add frontend WebSocket support +* Use openid provider name instead of generic "OIDC" in synced team names ([121fd3c](121fd3c9f1449ddf8568227afc3deb71433f2c92)) +* Add translation for saved filter ignored message ([7208c11](7208c11556591ad65a160b1891f5389338bb9240)) +* Show info when saved homepage filter is ignored for label browsing ([dca0414](dca041459fae68735f1dc1164b58d396ca744d28)) +* Add CI workflow to auto-update nixpkgs on release ([cb07b66](cb07b6608cfbc9e2486281f0dec9591c0086b292)) +* Improve wording and UX around CalDAV tokens (#2476) ([b89b402](b89b402bc2d273d87b7a33db5001f3274e5ddfbc)) +* Add OAuth 2.0 authorization code model and migration ([71282dc](71282dcffdbd2e68c1a261208924e3a41230557b)) +* Add OAuth client validation and PKCE verification ([a6e7475](a6e74751539f5a9f0fa2d82a2d912009dbfe2d42)) +* Add OAuth 2.0 authorize endpoint ([8b379b7](8b379b7466ea6a3cb2f9d91b28c16d450f6a5987)) +* Add OAuth 2.0 token endpoint ([7827ff6](7827ff64b9e419b3d6febc840937b7141f21b909)) +* Register OAuth authorize and token routes ([e5987ac](e5987acf806f5eb32a638d1c27af9c0e0d89c592)) +* Add frontend OAuth authorize route and component ([0471f8a](0471f8a7291c7f7f65e4dfa560573f3dc56997de)) +* Rename ServiceJWTSecret to ServiceSecret with deprecation (#2502) ([83bac15](83bac158411d9564840e536578986738782f22c0)) +* Register caldav permission group for API tokens ([b0b7c52](b0b7c52b155568e7b7206219d936e64a967eaa4d)) +* Add HasCaldavAccess method to APIToken ([ebec91b](ebec91b356f05e142c6532e725544f4d34b70e64)) +* Accept API tokens for CalDAV basic auth ([6207705](620770592800a984010386be491d4fb6b3f92bcd)) +* Add API token hint to CalDAV settings page ([c2cfcb4](c2cfcb4684774eae082072ee335f8481a0b2cce2)) +* Add i18n keys for API token expiry notifications ([d3f9bb4](d3f9bb4ee852a6622c113928a238707e3f154745)) +* Add API token expiry notification types ([8ea0dd1](8ea0dd1610b456b507351f25ae0139340d070447)) +* Add cron job for API token expiry notifications ([f308584](f30858403385cf7aec30bb7e7894488ec88067cb)) +* Register API token expiry check cron on startup ([04f94a5](04f94a5801410a65b2d424c36ac9afa19d37b946)) +* Add AssertNotSent helper to notification testing ([6dc46c1](6dc46c1898dce728f0b16ab8156026dc99d20b4e)) +* Add OAuth PKCE authentication flow to desktop app ([dd7532a](dd7532a57ac0b733f0e58256d4b0629397624e5c)) +* Add server selection UI for desktop OAuth login ([a12002d](a12002de6dbd5e68dc3fe31b82b89c7887e80417)) +* Show close-tab message after OAuth redirect ([495f34f](495f34f60e208234bbec582467b58de3a4bc6af2)) +* Update application icons for desktop build (#2516) ([831e4f2](831e4f29d1e388f4f4191f5c20b38b6d8435b78b)) +* Add tooltip to readonly checkbox explaining why it's not clickable ([a57cbd3](a57cbd3e51dd58d0534bbd470ca31b267b791fbc)) +* Add inline PDF viewer for task attachments (#2541) ([f5752b9](f5752b97e9f1293696232f197bd8684f3e782d1e)) +* Remove flexsearch dependency and replace with simple string filtering (#2542) ([0834d19](0834d19f9c5f22ed1d00bb68292c69e9566e6620)) +* Add TruncateAllTables function for e2e test isolation ([6a3dd8b](6a3dd8b28132d17858171ff35adbcb7910761675)) +* Add DELETE /test/all endpoint to truncate all tables ([e9a26b9](e9a26b908865587172fbd4be8ad7b047d1bef64f)) +* Add Factory.truncateAll() helper for e2e tests ([f477da4](f477da48ecd23e5ff195a1b671575ae77c29b508)) +* Truncate all tables before each e2e test for clean isolation ([2ee8ad4](2ee8ad4109bdbc40ba11b9d9b342a9aa7ca40858)) +* Add generic RememberValue[T] for type-safe keyvalue caching ([e2de681](e2de681b71af23e595073fd2fda8e8a28eaa7954)) +* Update publiccode.yml automatically during release ([415d5d2](415d5d23ad785fb71e2a32d7d004a31a9ebc56cc)) + +### Miscellaneous Tasks + +* *(ci)* Update nix update PR message [skip ci] +* *(desktop)* Add dev command to build and copy +* *(frontend)* Deduplicate pnpm dependencies +* *(i18n)* Update translations via Crowdin +* Add .pnpm-store to .gitignore ([73eb827](73eb8279ae816cc8dface89c594b05e5fc6c1e3f)) +* Add plans/ directory to .gitignore ([6566f98](6566f98103cb83bc955c38d6da4d2c4c42dba18a)) +* Remove redundant truncate calls now that all tables are wiped before each test ([aa1202f](aa1202fea8cbf6024075cd77779e9c78aa49d448)) + +### Other + +* *(other)* [skip ci] Updated swagger docs +* *(other)* Expand environment variables in some.config.value.path.file inputs for better secret management +* *(other)* Move caldav and e2e-api tests to dedicated CI jobs +* *(other)* Auto-close 'waiting for reply' issues after 30 days of inactivity +* *(other)* Add rotating home greeting variants + +### Refactor + +* *(auth)* Extract shared token validation into auth package +* *(auth)* Add TOTPPasscode to OIDC Callback payload +* *(files)* Derive attachment size from content in sibling callers +* *(mail)* Use CryptoRandomString for Message-ID generation +* *(models)* Use shared GetMailDomain in getThreadID +* *(tasks)* Add moveTaskToDefaultBuckets helper (#2573) +* Use xorm's TableInfo to resolve table names ([8567808](85678082f92bb4ed2ad3f1872e2461aadf11fa84)) +* Rename parseTaskText module to quickAddMagic ([44d01a0](44d01a0f82eebc36b6299baefc912660e649e9ff)) +* Extract shared RefreshSession helper ([7a258f6](7a258f67c7bc248ea2a8573553cef023b9bd3468)) +* Extract shared API token validation into ValidateTokenAndGetOwner ([9884d93](9884d933fc543c7881b3d9be26bc932cd67001e3)) +* Use embed fs for redoc UI and update to latest version ([111090d](111090d12c7319ab7124548f33c1cff013a36ae3)) +* Replace Modal div-based implementation with native dialog element ([cef03cb](cef03cb2a02cbc6d2b0aec11de0e3aefe44e9eb3)) +* Use nested map for position conflict tracking ([ce3e56f](ce3e56f1927273b6115dc6a09b248352919572ab)) +* Move plan file instead of copying in prepare-worktree ([a7bc3d6](a7bc3d6497e5e3dfa2e6832d34bdeafe9c097af7)) +* Use per-view IN clause for filter task deletion instead of batching ([17a97ca](17a97cacfabcfd0d2bf91e660f71c3b99158d566)) + +### Styling + +* *(sort)* Position popup aligned to header right edge + +### Testing + +* *(auth)* Add failing unit tests for OIDC TOTP enforcement +* *(caldav)* Add caldavtests package with infrastructure, helpers, and mage target +* *(caldav)* Add PROPFIND tests (RFC 4918 §9.1) +* *(caldav)* Add discovery flow tests (RFC 6764, RFC 5397, RFC 4791) +* *(caldav)* Add REPORT query tests (RFC 4791 §7.8, §7.9) +* *(caldav)* Add CRUD operation tests (RFC 4791 §5.3.2) +* *(caldav)* Add authentication and permission tests +* *(caldav)* Add sync semantics tests (ETag, CTag, conditional requests) +* *(caldav)* Add client compatibility and bug reproduction tests +* *(caldav)* Add relation and subtask tests (RFC 5545 §3.8.4.5) +* *(caldav)* Add VTODO field round-trip tests (RFC 5545 §3.6.2) +* *(e2e)* Add test for read-only checkbox on overview page +* *(e2e)* Relax home greeting assertions for rotating pool +* *(fixtures)* Add child project for reparent escalation tests +* *(gantt)* Add e2e test for date range preservation after task modal close +* *(kanban)* Add failing test for repeating task bucket routing on done (#2573) +* *(migration)* Add WeKan migration tests and fixture +* *(migration)* Regression test for forged attachment size +* *(plugins)* Add yaegi plugin integration tests +* *(project)* Add regression tests for reparent privilege escalation +* *(project)* Fix ParadeDB search expectation for fixture child +* *(security)* Webtest that a deleted link share rejects its still-valid JWT +* *(tasks)* Add failing test for repeating task bucket routing via Task.Update (#2573) +* *(tasks)* Add DoS regression test for ancient repeating due dates +* *(todoist)* Serve attachment from local test server +* *(user)* Cover TOTP lockout persistence and password-reset unlock +* *(webhook)* Add failing test for #2569 sibling webhook blocking +* *(webhook)* Assert good webhook delivered once despite sibling retries +* *(webhook)* Assert flaky webhook is retried until it succeeds +* *(webhook)* Handle deleted webhook gracefully between fan-out and delivery +* *(webhook)* Assert bad webhook is retried in no-duplicate test +* *(webtests)* Add end-to-end TOTP lockout test +* Update expected results for archived project propagation ([13be01d](13be01de9f05e3992a9b2e222f00f896014147e0)) +* Add failing test for TickTick child-before-parent CSV order ([c496364](c49636430f9da3ecb24626b1a2f9178bae28af05)) +* Add test for deeply nested TickTick task ordering ([112e486](112e4863147ed35c1de9fab23cb014f64f032b0e)) +* Add tests for OAuth 2.0 authorization flow ([649043a](649043aceb0efaf5575327b26829260a83087dfc)) +* Add integration tests for CalDAV API token auth ([194bec8](194bec8b9ff12142ca57ef36fa034218e6f8f2b2)) +* Verify caldav permission group appears in /routes ([390957b](390957b3f5d7790d0ecbe3dde68b388632da7118)) +* Add tests for API token expiry notifications and cron ([6b225bb](6b225bb0bae1bda574c89c5fb0f597a8a112666a)) +* Add WebSocket e2e tests ([4cd7908](4cd79088d1b971d974a44cd82b1542edde91682c)) +* Assert position existence instead of conditional skip ([a628c99](a628c990062da7d76091ad11a432eef753d2804e)) +* Add failing tests for subtask visibility in filtered views ([616ac8b](616ac8b95fdebd1884b73dc7c0af41a1af1afe9f)) +* Remove obsolete invalid-cache-type test for avatar upload ([c166eff](c166eff95fca24852839a546d8314ac487e974db)) +* Verify background removal preserves project title ([7679034](76790348f7282fab0a1d115151b9802f315725e8)) +* Add tests for SSO avatar provider reset on empty picture URL ([1065bdd](1065bdd84ced09506f7fdc02405134ea58f8a29b)) +* Wire up API URL for anonymous link share e2e tests ([91728c0](91728c0273b40a436ae8528f5b25c290bcb3acf9)) +* Add e2e regression test for link share loop while logged in ([a574d62](a574d623b14d83928f2c1e42f381fc8d12054045)) + ## [2.2.2] - 2026-03-23 ### Bug Fixes diff --git a/README.md b/README.md index b34a99622..71640bacd 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![Build Status](https://github.com/go-vikunja/vikunja/actions/workflows/ci.yml/badge.svg)](https://github.com/go-vikunja/vikunja/actions/workflows/ci.yml) [![License: AGPL-3.0-or-later](https://img.shields.io/badge/License-AGPL--3.0--or--later-blue.svg)](LICENSE) -[![Install](https://img.shields.io/badge/download-v2.2.2-brightgreen.svg)](https://vikunja.io/docs/installing) +[![Install](https://img.shields.io/badge/download-v2.3.0-brightgreen.svg)](https://vikunja.io/docs/installing) [![Docker Pulls](https://img.shields.io/docker/pulls/vikunja/vikunja.svg)](https://hub.docker.com/r/vikunja/vikunja/) [![Swagger Docs](https://img.shields.io/badge/swagger-docs-brightgreen.svg)](https://try.vikunja.io/api/v1/docs) [![Go Report Card](https://goreportcard.com/badge/code.vikunja.io/api)](https://goreportcard.com/report/code.vikunja.io/api) diff --git a/build/reprepro-dist-conf b/build/reprepro-dist-conf index 92b4fa20b..d0684520a 100644 --- a/build/reprepro-dist-conf +++ b/build/reprepro-dist-conf @@ -1,8 +1,13 @@ Origin: dl.vikunja.io Label: Vikunja -Codename: buster -Architectures: amd64 +Codename: stable +Architectures: amd64 arm64 armhf Components: main -Description: The debian repo for Vikunja builds. -SignWith: yes -Pull: buster +Description: The Vikunja package repository. + +Origin: dl.vikunja.io +Label: Vikunja +Codename: unstable +Architectures: amd64 arm64 armhf +Components: main +Description: The Vikunja unstable package repository. diff --git a/config-raw.json b/config-raw.json index 6bb00e6cf..dd395b768 100644 --- a/config-raw.json +++ b/config-raw.json @@ -3,10 +3,15 @@ { "key": "service", "children": [ + { + "key": "secret", + "default_value": "\u003ca-secret\u003e", + "comment": "This secret is used to sign JWT tokens and for other cryptographic operations.\nDefault is a random secret which will be generated at each startup of Vikunja.\n(This means all already issued tokens will be invalid once you restart Vikunja)" + }, { "key": "JWTSecret", "default_value": "\u003cjwt-secret\u003e", - "comment": "This token is used to verify issued JWT tokens.\nDefault is a random token which will be generated at each startup of Vikunja.\n(This means all already issued tokens will be invalid once you restart Vikunja)" + "comment": "Deprecated: use service.secret instead. If set, its value will be copied to service.secret." }, { "key": "jwtttl", @@ -1044,6 +1049,21 @@ "key": "dir", "default_value": "plugins", "comment": "The directory where plugins are stored." + }, + { + "key": "loader", + "default_value": "native", + "comment": "The plugin loader to use. \"yaegi\" loads plugins from Go source files (directories of .go files). \"native\" (deprecated) loads compiled Go plugin shared libraries (.so files)." + } + ] + }, + { + "key": "license", + "children": [ + { + "key": "key", + "default_value": "", + "comment": "The license key for Vikunja. If empty or absent, Vikunja runs in community mode with all non-licensed features available." } ] } diff --git a/desktop/build/icon.icns b/desktop/build/icon.icns index 56317ef2b..3667e52f8 100644 Binary files a/desktop/build/icon.icns and b/desktop/build/icon.icns differ diff --git a/desktop/build/icon.png b/desktop/build/icon.png index b4f13c23e..3f2db0866 100644 Binary files a/desktop/build/icon.png and b/desktop/build/icon.png differ diff --git a/desktop/main.js b/desktop/main.js index f9698ff70..f670f8fe9 100644 --- a/desktop/main.js +++ b/desktop/main.js @@ -1,97 +1,541 @@ -const {app, BrowserWindow, shell} = require('electron') +const { + app, + BrowserWindow, + globalShortcut, + ipcMain, + Menu, + nativeImage, + shell, + Tray, + screen, +} = require('electron') const path = require('path') +const fs = require('fs') const express = require('express') -const eApp = express() const portInUse = require('./portInUse.js') +const oauth = require('./oauth.js') const frontendPath = 'frontend/' +const PROTOCOL = 'vikunja-desktop' +const SAFE_PROTOCOLS = new Set([ + 'http:', 'https:', 'mailto:', + 'ftp:', 'git:', 'obsidian:', 'notion:', 'message:', +]) -function createWindow() { - // Create the browser window. - const mainWindow = new BrowserWindow({ - width: 1680, - height: 960, - webPreferences: { - nodeIntegration: false, - contextIsolation: true, - sandbox: true, - webviewTag: false, - navigateOnDragDrop: false, +const QUICK_ENTRY_WIDTH = 680 +const QUICK_ENTRY_COLLAPSED_HEIGHT = 56 + +const ZOOM_STEP = 0.5 +const ZOOM_CONFIG_FILE = 'zoom.json' + +const BASE_WEB_PREFERENCES = { + nodeIntegration: false, + contextIsolation: true, + sandbox: true, + webviewTag: false, + navigateOnDragDrop: false, +} + +function safeOpenExternal(url) { + try { + const parsed = new URL(url) + if (SAFE_PROTOCOLS.has(parsed.protocol)) { + shell.openExternal(url) } - }) + } catch { + // Ignore malformed URLs + } +} - // Open external links in the browser, but only allow protocols - // that the TipTap editor also allows (see frontend/src/components/input/editor/TipTap.vue). - // TipTap allows: http, https (built-in) + ftp, git, obsidian, notion, message - // We also allow mailto since it's a standard safe protocol for email links. - mainWindow.webContents.setWindowOpenHandler(({ url }) => { - try { - const parsedUrl = new URL(url); - const allowedProtocols = [ - 'http:', 'https:', 'mailto:', - 'ftp:', 'git:', 'obsidian:', 'notion:', 'message:', - ]; - if (allowedProtocols.includes(parsedUrl.protocol)) { - shell.openExternal(url); +// Module-scope state +let mainWindow = null +let quickEntryWindow = null +let tray = null +let serverPort = null +let isQuitting = false +let pendingDeepLinkUrl = null +let pendingApiUrl = null +let currentShortcut = null +let zoomLevel = 0 +const DEFAULT_QUICK_ENTRY_SHORTCUT = 'CmdOrCtrl+Shift+A' +const launchedWithQuickEntry = process.argv.includes('--quick-entry') + +// Ensure single instance so deep links reach the running app on Windows/Linux +const gotTheLock = app.requestSingleInstanceLock() +if (!gotTheLock) { + app.quit() + // Must exit the process immediately — app.quit() is async and the rest of this + // file would still execute, potentially opening a blank window. + process.exit(0) +} + +// Register the custom protocol for deep links +if (process.defaultApp) { + // During development, register with the path to the script + if (process.argv.length >= 2) { + app.setAsDefaultProtocolClient(PROTOCOL, process.execPath, [path.resolve(process.argv[1])]) + } +} else { + app.setAsDefaultProtocolClient(PROTOCOL) +} + +// Handle deep link on macOS (app already running or launched via URL) +app.on('open-url', (event, url) => { + event.preventDefault() + if (mainWindow) { + handleDeepLink(url) + } else { + // Window not ready yet — buffer the URL for processing after createMainWindow() + pendingDeepLinkUrl = url + } +}) + +// Handle deep link on Windows/Linux when a second instance is launched +app.on('second-instance', (_event, argv) => { + // Handle --quick-entry flag from second instance + if (argv.includes('--quick-entry')) { + if (serverPort) { + toggleQuickEntry() + } + return + } + + // Focus the main window + if (mainWindow) { + if (mainWindow.isMinimized()) mainWindow.restore() + mainWindow.focus() + } + + // Find the deep link URL in argv + const deepLinkUrl = argv.find(arg => arg.startsWith(`${PROTOCOL}://`)) + if (deepLinkUrl) { + handleDeepLink(deepLinkUrl) + } +}) + +function handleDeepLink(url) { + try { + const parsed = new URL(url) + if (parsed.hostname === 'callback') { + const code = parsed.searchParams.get('code') + if (code && mainWindow) { + // Store the apiUrl that was used to start login so we can + // exchange the code at the correct endpoint + const apiUrl = pendingApiUrl + if (!apiUrl) { + mainWindow.webContents.send('oauth:error', 'No pending login session') + return + } + + oauth.exchangeCodeForTokens(apiUrl, code) + .then(tokens => { + mainWindow.webContents.send('oauth:tokens', tokens) + }) + .catch(err => { + mainWindow.webContents.send('oauth:error', err.message) + }) } - } catch { - // Invalid URL, ignore silently } - return { action: 'deny' }; - }); + } catch { + // Invalid URL, ignore + } +} - // Prevent same-window navigation to external origins. - // Only allow navigation to the local express server. - mainWindow.webContents.on('will-navigate', (event, navigationUrl) => { - const parsedUrl = new URL(navigationUrl); - // Allow navigations to the local express server - if (parsedUrl.hostname === '127.0.0.1' || parsedUrl.hostname === 'localhost') { - return; - } - event.preventDefault(); - }); +// IPC: Start OAuth login flow +ipcMain.handle('oauth:start-login', async (_event, apiUrl) => { + pendingApiUrl = apiUrl + const authUrl = oauth.startLogin(apiUrl) + await shell.openExternal(authUrl) +}) - // Hide the toolbar - mainWindow.setMenuBarVisibility(false) +// IPC: Refresh access token +ipcMain.handle('oauth:refresh-token', async (_event, apiUrl, refreshToken) => { + return oauth.refreshAccessToken(apiUrl, refreshToken) +}) - // We try to use the same port every time and only use a different one if that does not succeed. +// ─── Express server ────────────────────────────────────────────────── +function startServer(callback) { + const eApp = express() let port = 45735 - portInUse(port, used => { - if(used) { + + portInUse(port, (used) => { + if (used) { console.log(`Port ${port} already used, switching to a random one`) - port = 0 // This lets express choose a random port + port = 0 } - // Start a local express server to serve static files eApp.use(express.static(path.join(__dirname, frontendPath))) - // Handle urls set by the frontend - use app.use as catch-all instead of route pattern eApp.use((request, response) => { response.sendFile(path.join(__dirname, frontendPath, 'index.html')) }) - const server = eApp.listen(port, '127.0.0.1', () => { - console.log(`Server started on port ${server.address().port}`) - mainWindow.loadURL(`http://127.0.0.1:${server.address().port}`) + + const server = eApp.listen(port, '127.0.0.1', () => { + serverPort = server.address().port + console.log(`Server started on port ${serverPort}`) + callback(serverPort) }) }) } -// This method will be called when Electron has finished -// initialization and is ready to create browser windows. -// Some APIs can only be used after this event occurs. -app.whenReady().then(() => { - createWindow() +// ─── Zoom ──────────────────────────────────────────────────────────── +function zoomConfigPath() { + return path.join(app.getPath('userData'), ZOOM_CONFIG_FILE) +} - app.on('activate', function () { - // On macOS it's common to re-create a window in the app when the - // dock icon is clicked and there are no other windows open. - if (BrowserWindow.getAllWindows().length === 0) createWindow() +function loadZoomLevel() { + try { + const raw = fs.readFileSync(zoomConfigPath(), 'utf8') + const parsed = JSON.parse(raw) + if (typeof parsed.zoomLevel === 'number' && Number.isFinite(parsed.zoomLevel)) { + return parsed.zoomLevel + } + } catch { + // First run or unreadable file, fall back to default + } + return 0 +} + +function saveZoomLevel(level) { + try { + fs.writeFileSync(zoomConfigPath(), JSON.stringify({zoomLevel: level})) + } catch (err) { + console.warn('Failed to persist zoom level:', err.message) + } +} + +function applyZoom(webContents, level) { + zoomLevel = level + webContents.setZoomLevel(level) + saveZoomLevel(level) +} + +function wireZoomHandlers(win) { + win.webContents.on('before-input-event', (event, input) => { + if (input.type !== 'keyDown' || !input.control || input.alt || input.meta) return + const key = input.key + if (key === '=' || key === '+') { + applyZoom(win.webContents, zoomLevel + ZOOM_STEP) + event.preventDefault() + } else if (key === '-') { + applyZoom(win.webContents, zoomLevel - ZOOM_STEP) + event.preventDefault() + } else if (key === '0') { + applyZoom(win.webContents, 0) + event.preventDefault() + } + }) + + win.webContents.on('zoom-changed', (_event, direction) => { + const delta = direction === 'in' ? ZOOM_STEP : -ZOOM_STEP + applyZoom(win.webContents, zoomLevel + delta) + }) +} + +// ─── Main window ───────────────────────────────────────────────────── +function createMainWindow() { + mainWindow = new BrowserWindow({ + width: 1680, + height: 960, + webPreferences: { + ...BASE_WEB_PREFERENCES, + preload: path.join(__dirname, 'preload.js'), + }, + }) + + mainWindow.webContents.setWindowOpenHandler(({url}) => { + safeOpenExternal(url) + return {action: 'deny'} + }) + + // Prevent same-window navigation to external origins. + // Only allow navigation to the local express server on the exact port. + mainWindow.webContents.on('will-navigate', (event, navigationUrl) => { + const parsedUrl = new URL(navigationUrl) + if (parsedUrl.origin === `http://127.0.0.1:${serverPort}`) { + return + } + event.preventDefault() + }) + + mainWindow.setMenuBarVisibility(false) + + mainWindow.on('close', (e) => { + if (!isQuitting && tray) { + e.preventDefault() + mainWindow.hide() + } + }) + + mainWindow.on('closed', () => { + mainWindow = null + }) + + mainWindow.loadURL(`http://127.0.0.1:${serverPort}`) + + wireZoomHandlers(mainWindow) + mainWindow.webContents.on('did-finish-load', () => { + mainWindow.webContents.setZoomLevel(zoomLevel) + }) + + // Process any deep link that arrived before the page was ready, + // either buffered from open-url or passed via process.argv on first launch + mainWindow.webContents.once('did-finish-load', () => { + if (!pendingDeepLinkUrl) { + pendingDeepLinkUrl = process.argv.find(arg => arg.startsWith(`${PROTOCOL}://`)) || null + } + if (pendingDeepLinkUrl) { + handleDeepLink(pendingDeepLinkUrl) + pendingDeepLinkUrl = null + } + }) +} + +// ─── Quick Entry window ────────────────────────────────────────────── +function getQuickEntryPosition() { + const cursorPoint = screen.getCursorScreenPoint() + const display = screen.getDisplayNearestPoint(cursorPoint) + const {x: areaX, y: areaY, width: areaWidth, height: areaHeight} = display.workArea + return { + x: Math.round(areaX + (areaWidth - QUICK_ENTRY_WIDTH) / 2), + y: Math.round(areaY + areaHeight / 3 - QUICK_ENTRY_COLLAPSED_HEIGHT / 2), + } +} + +function createQuickEntryWindow() { + const {x, y} = getQuickEntryPosition() + + quickEntryWindow = new BrowserWindow({ + width: QUICK_ENTRY_WIDTH, + height: QUICK_ENTRY_COLLAPSED_HEIGHT, + x, + y, + frame: false, + transparent: true, + alwaysOnTop: true, + skipTaskbar: true, + resizable: false, + show: false, + webPreferences: { + ...BASE_WEB_PREFERENCES, + preload: path.join(__dirname, 'preload-quick-entry.js'), + }, + }) + + quickEntryWindow.webContents.setWindowOpenHandler(({url}) => { + safeOpenExternal(url) + return {action: 'deny'} + }) + + quickEntryWindow.webContents.on('will-navigate', (event, navigationUrl) => { + const parsedUrl = new URL(navigationUrl) + if (parsedUrl.origin === `http://127.0.0.1:${serverPort}`) { + return + } + event.preventDefault() + }) + + quickEntryWindow.loadURL(`http://127.0.0.1:${serverPort}/?mode=quick-add`) + + // Hide on blur (user clicked outside) + let blurTimeout = null + quickEntryWindow.on('blur', () => { + // Debounce to avoid hiding during DevTools focus changes + blurTimeout = setTimeout(() => hideQuickEntry(), 100) + }) + quickEntryWindow.on('focus', () => { + if (blurTimeout) { + clearTimeout(blurTimeout) + blurTimeout = null + } + }) + + quickEntryWindow.on('closed', () => { + quickEntryWindow = null + }) +} + +function showQuickEntry() { + if (!quickEntryWindow) { + createQuickEntryWindow() + quickEntryWindow.once('ready-to-show', () => { + quickEntryWindow.show() + quickEntryWindow.focus() + quickEntryWindow.webContents.focus() + }) + return + } + + // Reset size and move to the active display + quickEntryWindow.setSize(QUICK_ENTRY_WIDTH, QUICK_ENTRY_COLLAPSED_HEIGHT) + const {x, y} = getQuickEntryPosition() + quickEntryWindow.setPosition(x, y) + + // Reload to reset Vue state (clear previous input) + quickEntryWindow.loadURL(`http://127.0.0.1:${serverPort}/?mode=quick-add`) + // Wait for page to finish loading before showing, so the input gets focused + quickEntryWindow.webContents.once('did-finish-load', () => { + quickEntryWindow.show() + quickEntryWindow.focus() + quickEntryWindow.webContents.focus() + }) +} + +function hideQuickEntry() { + if (quickEntryWindow && quickEntryWindow.isVisible()) { + quickEntryWindow.hide() + } +} + +function toggleQuickEntry() { + if (quickEntryWindow && quickEntryWindow.isVisible()) { + hideQuickEntry() + } else { + showQuickEntry() + } +} + +// ─── System tray ───────────────────────────────────────────────────── +function setupTray() { + if (!tray) { + const iconPath = path.join(__dirname, 'build', 'icon.png') + const icon = nativeImage.createFromPath(iconPath).resize({width: 16, height: 16}) + tray = new Tray(icon) + tray.setToolTip('Vikunja') + tray.on('click', () => { + if (mainWindow) { + mainWindow.show() + mainWindow.focus() + } else { + createMainWindow() + } + }) + } + + const contextMenu = Menu.buildFromTemplate([ + { + label: 'Show Vikunja', + click: () => { + if (mainWindow) { + mainWindow.show() + mainWindow.focus() + } else { + createMainWindow() + } + }, + }, + { + label: 'Quick Add Task', + accelerator: currentShortcut || undefined, + click: () => showQuickEntry(), + }, + {type: 'separator'}, + { + label: 'Quit', + click: () => { + isQuitting = true + app.quit() + }, + }, + ]) + + tray.setContextMenu(contextMenu) +} + +// ─── IPC handlers ──────────────────────────────────────────────────── +ipcMain.on('quick-entry:close', () => { + hideQuickEntry() +}) + +ipcMain.on('quick-entry:resize', (_event, width, height) => { + if (!quickEntryWindow) return + if (!Number.isFinite(width) || !Number.isFinite(height)) return + + const display = screen.getDisplayNearestPoint(screen.getCursorScreenPoint()) + const maxWidth = display.workAreaSize.width + const maxHeight = display.workAreaSize.height + + const w = Math.max(100, Math.min(Math.round(width), maxWidth)) + const h = Math.max(40, Math.min(Math.round(height), maxHeight)) + quickEntryWindow.setSize(w, h) +}) + +ipcMain.on('quick-entry:show-main-window', () => { + if (mainWindow) { + mainWindow.show() + mainWindow.focus() + } else { + createMainWindow() + } +}) + +// ─── Shortcut management ──────────────────────────────────────────── +function registerQuickEntryShortcut(shortcut) { + if (currentShortcut) { + globalShortcut.unregister(currentShortcut) + } + + if (!shortcut) { + currentShortcut = null + return + } + + const registered = globalShortcut.register(shortcut, toggleQuickEntry) + if (registered) { + currentShortcut = shortcut + } else { + console.warn(`Failed to register global shortcut ${shortcut} — it may be in use by another application`) + currentShortcut = null + } +} + +ipcMain.on('desktop:update-quick-entry-shortcut', (_event, shortcut) => { + registerQuickEntryShortcut(shortcut) + // Rebuild tray menu to reflect the new accelerator + if (tray) { + setupTray() + } +}) + +// ─── App lifecycle ─────────────────────────────────────────────────── +app.whenReady().then(() => { + zoomLevel = loadZoomLevel() + + startServer(() => { + createMainWindow() + createQuickEntryWindow() + setupTray() + + registerQuickEntryShortcut(DEFAULT_QUICK_ENTRY_SHORTCUT) + + // If launched with --quick-entry, show the quick entry window immediately + if (launchedWithQuickEntry) { + showQuickEntry() + } + }) + + app.on('activate', () => { + if (BrowserWindow.getAllWindows().length === 0) { + if (serverPort) { + createMainWindow() + } + } else if (mainWindow) { + mainWindow.show() + mainWindow.focus() + } }) }) -// Quit when all windows are closed, except on macOS. There, it's common -// for applications and their menu bar to stay active until the user quits -// explicitly with Cmd + Q. -app.on('window-all-closed', () => { - if (process.platform !== 'darwin') app.quit() +app.on('before-quit', () => { + isQuitting = true }) +app.on('will-quit', () => { + globalShortcut.unregisterAll() +}) + +app.on('window-all-closed', () => { + // Don't quit if tray exists (user can still use global shortcut) + if (process.platform !== 'darwin' && !tray) { + app.quit() + } +}) diff --git a/desktop/oauth.js b/desktop/oauth.js new file mode 100644 index 000000000..06c1d41bc --- /dev/null +++ b/desktop/oauth.js @@ -0,0 +1,115 @@ +const crypto = require('crypto') +const {net} = require('electron') + +const CLIENT_ID = 'vikunja-desktop' +const REDIRECT_URI = 'vikunja-desktop://callback' + +let pendingCodeVerifier = null + +function generateCodeVerifier() { + return crypto.randomBytes(32).toString('base64url') +} + +function generateCodeChallenge(verifier) { + return crypto.createHash('sha256').update(verifier).digest('base64url') +} + +function buildAuthorizationUrl(frontendUrl, codeChallenge) { + // Strip trailing slash and /api/v1 suffix to get the frontend origin + let base = frontendUrl.replace(/\/+$/, '').replace(/\/api\/v1$/, '') + + const url = new URL(base) + url.pathname = url.pathname.replace(/\/+$/, '') + '/oauth/authorize' + url.searchParams.set('response_type', 'code') + url.searchParams.set('client_id', CLIENT_ID) + url.searchParams.set('redirect_uri', REDIRECT_URI) + url.searchParams.set('code_challenge', codeChallenge) + url.searchParams.set('code_challenge_method', 'S256') + + return url.toString() +} + +function startLogin(apiUrl) { + const verifier = generateCodeVerifier() + const challenge = generateCodeChallenge(verifier) + pendingCodeVerifier = verifier + + return buildAuthorizationUrl(apiUrl, challenge) +} + +function postJSON(url, body) { + return new Promise((resolve, reject) => { + const request = net.request({ + method: 'POST', + url, + }) + request.setHeader('Content-Type', 'application/json') + + let responseData = '' + + request.on('response', (response) => { + response.on('data', (chunk) => { + responseData += chunk.toString() + }) + response.on('end', () => { + try { + const parsed = JSON.parse(responseData) + if (response.statusCode >= 200 && response.statusCode < 300) { + resolve(parsed) + } else { + reject(new Error(parsed.message || `HTTP ${response.statusCode}`)) + } + } catch { + reject(new Error(`Invalid JSON response: ${responseData.substring(0, 200)}`)) + } + }) + }) + + request.on('error', (err) => { + reject(err) + }) + + request.write(JSON.stringify(body)) + request.end() + }) +} + +function getTokenEndpoint(apiUrl) { + let base = apiUrl.replace(/\/+$/, '') + if (!base.endsWith('/api/v1')) { + base += '/api/v1' + } + return `${base}/oauth/token` +} + +async function exchangeCodeForTokens(apiUrl, code) { + const verifier = pendingCodeVerifier + pendingCodeVerifier = null + + if (!verifier) { + throw new Error('No pending PKCE verifier found') + } + + const tokenUrl = getTokenEndpoint(apiUrl) + return postJSON(tokenUrl, { + grant_type: 'authorization_code', + code, + client_id: CLIENT_ID, + redirect_uri: REDIRECT_URI, + code_verifier: verifier, + }) +} + +async function refreshAccessToken(apiUrl, refreshToken) { + const tokenUrl = getTokenEndpoint(apiUrl) + return postJSON(tokenUrl, { + grant_type: 'refresh_token', + refresh_token: refreshToken, + }) +} + +module.exports = { + startLogin, + exchangeCodeForTokens, + refreshAccessToken, +} diff --git a/desktop/package.json b/desktop/package.json index 68637148a..b7261093d 100644 --- a/desktop/package.json +++ b/desktop/package.json @@ -12,15 +12,24 @@ }, "homepage": "https://vikunja.io", "scripts": { + "build:frontend": "cd ../frontend && pnpm run build && cd ../desktop && rm -rf frontend && cp -r ../frontend/dist frontend", "start": "electron .", "pack": "electron-builder --dir", "dist": "electron-builder --publish never" }, "build": { "appId": "io.vikunja.desktop", + "files": [ + "**/*", + "preload-quick-entry.js" + ], "productName": "Vikunja Desktop", "artifactName": "${productName}-${version}.${ext}", "icon": "build/icon.icns", + "protocols": { + "name": "Vikunja Desktop", + "schemes": ["vikunja-desktop"] + }, "linux": { "target": [ "deb", @@ -52,7 +61,7 @@ } }, "devDependencies": { - "electron": "40.8.4", + "electron": "40.9.2", "electron-builder": "26.8.1", "unzipper": "0.12.3" }, diff --git a/desktop/pnpm-lock.yaml b/desktop/pnpm-lock.yaml index 0bcb7cb9c..c3d9f0845 100644 --- a/desktop/pnpm-lock.yaml +++ b/desktop/pnpm-lock.yaml @@ -19,8 +19,8 @@ importers: version: 5.2.1 devDependencies: electron: - specifier: 40.8.4 - version: 40.8.4 + specifier: 40.9.2 + version: 40.9.2 electron-builder: specifier: 26.8.1 version: 26.8.1(electron-builder-squirrel-windows@24.13.3) @@ -135,6 +135,9 @@ packages: '@types/debug@4.1.12': resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==} + '@types/debug@4.1.13': + resolution: {integrity: sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw==} + '@types/fs-extra@9.0.13': resolution: {integrity: sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA==} @@ -147,6 +150,9 @@ packages: '@types/ms@0.7.34': resolution: {integrity: sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==} + '@types/ms@2.1.0': + resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} + '@types/node@24.10.9': resolution: {integrity: sha512-ne4A0IpG3+2ETuREInjPNhUGis1SFjv1d5asp8MzEAGtOZeTeHVDOYqOgqfhvseqg/iXty2hjBf1zAOb7RNiNw==} @@ -162,9 +168,10 @@ packages: '@types/yauzl@2.10.3': resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==} - '@xmldom/xmldom@0.8.10': - resolution: {integrity: sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw==} + '@xmldom/xmldom@0.8.12': + resolution: {integrity: sha512-9k/gHF6n/pAi/9tqr3m3aqkuiNosYTurLLUtc7xQ9sxB/wm7WPygCv8GYa6mS0fLJEHhqMC1ATYhz++U/lRHqg==} engines: {node: '>=10.0.0'} + deprecated: this version has critical issues, please update to the latest version abbrev@3.0.1: resolution: {integrity: sha512-AO2ac6pjRB3SJmGJo+v5/aK6Omggp6fsLrs6wN9bd35ulu4cCwaAU9+7ZhXjeqHVkaHThLuzH0nZr0YpCDhygg==} @@ -287,8 +294,8 @@ packages: resolution: {integrity: sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==} deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. - brace-expansion@5.0.3: - resolution: {integrity: sha512-fy6KJm2RawA5RcHkLa1z/ScpBeA762UF9KmZQxwIbDtRJrgLzM10depAiEQ+CXYcoiqW1/m96OAAoke2nE9EeA==} + brace-expansion@5.0.5: + resolution: {integrity: sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==} engines: {node: 18 || 20 || >=22} buffer-crc32@0.2.13: @@ -553,8 +560,8 @@ packages: electron-publish@26.8.1: resolution: {integrity: sha512-q+jrSTIh/Cv4eGZa7oVR+grEJo/FoLMYBAnSL5GCtqwUpr1T+VgKB/dn1pnzxIxqD8S/jP1yilT9VrwCqINR4w==} - electron@40.8.4: - resolution: {integrity: sha512-7AoSakFr+g2CTukHDS79cqNiaWPoD8bQ4kIahwUUVv0O5fy4BfZawVCxOFLc61POq8xDvqMSDKPfeFXK/Coc5g==} + electron@40.9.2: + resolution: {integrity: sha512-gTLLTlfMyORZDj+03tkxsstQOQlmu6dYl0X8cwlmFb+gMmCM9Gc+rmBGSaCb5KI11IMUWHu4hvKA/spP8oJe+w==} engines: {node: '>= 12.20.55'} hasBin: true @@ -935,8 +942,8 @@ packages: lodash.union@4.6.0: resolution: {integrity: sha512-c4pB2CdGrGdjMKYLA+XiRDO7Y0PRQbm/Gzg8qMj+QH+pFVAoTp5sBpO0odL3FjoPCGjK96p6qsP+yQoiLoOBcw==} - lodash@4.17.23: - resolution: {integrity: sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==} + lodash@4.18.1: + resolution: {integrity: sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==} log-symbols@4.1.0: resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} @@ -1010,6 +1017,10 @@ packages: resolution: {integrity: sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==} engines: {node: 18 || 20 || >=22} + minimatch@10.2.5: + resolution: {integrity: sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==} + engines: {node: 18 || 20 || >=22} + minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} @@ -1141,8 +1152,8 @@ packages: resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} engines: {node: '>=16 || 14 >=14.18'} - path-to-regexp@8.3.0: - resolution: {integrity: sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==} + path-to-regexp@8.4.1: + resolution: {integrity: sha512-fvU78fIjZ+SBM9YwCknCvKOUKkLVqtWDVctl0s7xIqfmfb38t2TT4ZU2gHm+Z8xGwgW+QWEU3oQSAzIbo89Ggw==} pe-library@0.4.1: resolution: {integrity: sha512-eRWB5LBz7PpDu4PUlwT0PhnQfTQJlDDdPa35urV4Osrm0t0AqQFGn+UIkU3klZvwJ8KPO3VbBFsXquA6p6kqZw==} @@ -1264,6 +1275,9 @@ packages: sanitize-filename@1.6.3: resolution: {integrity: sha512-y/52Mcy7aw3gRm7IrcGDFx/bCk4AhRh2eI9luHOQM86nZsqwiRkkq2GekHXBBD+SmPidc8i2PqtYZl+pWJ8Oeg==} + sanitize-filename@1.6.4: + resolution: {integrity: sha512-9ZyI08PsvdQl2r/bBIGubpVdR3RR9sY6RDiWFPreA21C/EFlQhmgo20UZlNjZMMZNubusLhAQozkA0Od5J21Eg==} + sax@1.4.4: resolution: {integrity: sha512-1n3r/tGXO6b6VXMdFT54SHzT9ytu9yr7TaELowdYpMqY/Ao7EnlQGmAQ1+RatX7Tkkdm6hONI2owqNx2aZj5Sw==} engines: {node: '>=11.0.0'} @@ -1414,6 +1428,10 @@ packages: resolution: {integrity: sha512-ChjMH33/KetonMTAtpYdgUFr0tbz69Fp2v7zWxQfYZX4g5ZN2nOBXm1R2xyA+lMIKrLKIoKAwFj93jE/avX9cQ==} engines: {node: '>=18'} + tar@7.5.13: + resolution: {integrity: sha512-tOG/7GyXpFevhXVh8jOPJrmtRpOTsYqUIkVdVooZYJS/z8WhfQUX8RJILmeuJNinGAMSu1veBr4asSHFt5/hng==} + engines: {node: '>=18'} + temp-file@3.4.0: resolution: {integrity: sha512-C5tjlC/HCtVUOi3KWVokd4vHVViOmGjtLwIh4MuzPo/nMYTV/p1urt3RnMz2IWXDdKEGJH3k5+KPxtqRsUYGtg==} @@ -1664,7 +1682,7 @@ snapshots: debug: 4.4.3 dir-compare: 3.3.0 fs-extra: 9.1.0 - minimatch: 10.2.4 + minimatch: 10.2.5 plist: 3.1.0 transitivePeerDependencies: - supports-color @@ -1706,7 +1724,7 @@ snapshots: dependencies: debug: 4.4.3 fs-extra: 9.1.0 - lodash: 4.17.23 + lodash: 4.18.1 tmp-promise: 3.0.3 transitivePeerDependencies: - supports-color @@ -1747,6 +1765,10 @@ snapshots: dependencies: '@types/ms': 0.7.34 + '@types/debug@4.1.13': + dependencies: + '@types/ms': 2.1.0 + '@types/fs-extra@9.0.13': dependencies: '@types/node': 24.10.9 @@ -1759,6 +1781,8 @@ snapshots: '@types/ms@0.7.34': {} + '@types/ms@2.1.0': {} + '@types/node@24.10.9': dependencies: undici-types: 7.16.0 @@ -1781,7 +1805,7 @@ snapshots: '@types/node': 24.10.9 optional: true - '@xmldom/xmldom@0.8.10': {} + '@xmldom/xmldom@0.8.12': {} abbrev@3.0.1: {} @@ -1848,11 +1872,11 @@ snapshots: isbinaryfile: 5.0.7 js-yaml: 4.1.1 lazy-val: 1.0.5 - minimatch: 10.2.4 + minimatch: 10.2.5 read-config-file: 6.3.2 - sanitize-filename: 1.6.3 + sanitize-filename: 1.6.4 semver: 7.7.4 - tar: 7.5.11 + tar: 7.5.13 temp-file: 3.4.0 transitivePeerDependencies: - supports-color @@ -1985,7 +2009,7 @@ snapshots: boolean@3.2.0: optional: true - brace-expansion@5.0.3: + brace-expansion@5.0.5: dependencies: balanced-match: 4.0.4 @@ -2017,7 +2041,7 @@ snapshots: builder-util@24.13.1: dependencies: 7zip-bin: 5.2.0 - '@types/debug': 4.1.12 + '@types/debug': 4.1.13 app-builder-bin: 4.0.0 bluebird-lst: 1.0.9 builder-util-runtime: 9.2.4 @@ -2229,7 +2253,7 @@ snapshots: dir-compare@3.3.0: dependencies: buffer-equal: 1.0.1 - minimatch: 10.2.4 + minimatch: 10.2.5 dir-compare@4.2.0: dependencies: @@ -2340,7 +2364,7 @@ snapshots: transitivePeerDependencies: - supports-color - electron@40.8.4: + electron@40.9.2: dependencies: '@electron/get': 2.0.3 '@types/node': 24.10.9 @@ -2783,7 +2807,7 @@ snapshots: lodash.union@4.6.0: {} - lodash@4.17.23: {} + lodash@4.18.1: {} log-symbols@4.1.0: dependencies: @@ -2847,7 +2871,11 @@ snapshots: minimatch@10.2.4: dependencies: - brace-expansion: 5.0.3 + brace-expansion: 5.0.5 + + minimatch@10.2.5: + dependencies: + brace-expansion: 5.0.5 minimist@1.2.8: {} @@ -2977,7 +3005,7 @@ snapshots: lru-cache: 10.4.3 minipass: 7.1.2 - path-to-regexp@8.3.0: {} + path-to-regexp@8.4.1: {} pe-library@0.4.1: {} @@ -2987,7 +3015,7 @@ snapshots: plist@3.1.0: dependencies: - '@xmldom/xmldom': 0.8.10 + '@xmldom/xmldom': 0.8.12 base64-js: 1.5.1 xmlbuilder: 15.1.1 @@ -3068,7 +3096,7 @@ snapshots: readdir-glob@1.1.3: dependencies: - minimatch: 10.2.4 + minimatch: 10.2.5 require-directory@2.1.1: {} @@ -3105,7 +3133,7 @@ snapshots: depd: 2.0.0 is-promise: 4.0.0 parseurl: 1.3.3 - path-to-regexp: 8.3.0 + path-to-regexp: 8.4.1 transitivePeerDependencies: - supports-color @@ -3119,6 +3147,10 @@ snapshots: dependencies: truncate-utf8-bytes: 1.0.2 + sanitize-filename@1.6.4: + dependencies: + truncate-utf8-bytes: 1.0.2 + sax@1.4.4: {} sax@1.6.0: {} @@ -3300,6 +3332,14 @@ snapshots: minizlib: 3.1.0 yallist: 5.0.0 + tar@7.5.13: + dependencies: + '@isaacs/fs-minipass': 4.0.1 + chownr: 3.0.0 + minipass: 7.1.3 + minizlib: 3.1.0 + yallist: 5.0.0 + temp-file@3.4.0: dependencies: async-exit-hook: 2.0.1 diff --git a/desktop/preload-quick-entry.js b/desktop/preload-quick-entry.js new file mode 100644 index 000000000..8ca3b088c --- /dev/null +++ b/desktop/preload-quick-entry.js @@ -0,0 +1,8 @@ +// desktop/preload-quick-entry.js +const { contextBridge, ipcRenderer } = require('electron') + +contextBridge.exposeInMainWorld('quickEntry', { + close: () => ipcRenderer.send('quick-entry:close'), + resize: (width, height) => ipcRenderer.send('quick-entry:resize', width, height), + showMainWindow: () => ipcRenderer.send('quick-entry:show-main-window'), +}) diff --git a/desktop/preload.js b/desktop/preload.js new file mode 100644 index 000000000..6282ef0a7 --- /dev/null +++ b/desktop/preload.js @@ -0,0 +1,16 @@ +const {contextBridge, ipcRenderer} = require('electron') + +contextBridge.exposeInMainWorld('vikunjaDesktop', { + startOAuthLogin: (apiUrl) => ipcRenderer.invoke('oauth:start-login', apiUrl), + onOAuthTokens: (callback) => { + ipcRenderer.removeAllListeners('oauth:tokens') + ipcRenderer.on('oauth:tokens', (_event, tokens) => callback(tokens)) + }, + onOAuthError: (callback) => { + ipcRenderer.removeAllListeners('oauth:error') + ipcRenderer.on('oauth:error', (_event, error) => callback(error)) + }, + refreshToken: (apiUrl, refreshToken) => ipcRenderer.invoke('oauth:refresh-token', apiUrl, refreshToken), + updateQuickEntryShortcut: (shortcut) => ipcRenderer.send('desktop:update-quick-entry-shortcut', shortcut), + isDesktop: true, +}) diff --git a/examples/plugins/example/main.go b/examples/plugins/example/main.go index f791f0b02..afb358b2f 100644 --- a/examples/plugins/example/main.go +++ b/examples/plugins/example/main.go @@ -92,7 +92,19 @@ func handleStatus(c *echo.Context) error { }) } -func NewPlugin() plugins.Plugin { return &ExamplePlugin{} } +// singleton ensures all factory functions return the same instance so that state +// initialized in Init() (e.g. event listeners, DB connections) is available to +// route handlers and other capabilities. +var singleton = &ExamplePlugin{} + +func NewPlugin() plugins.Plugin { return singleton } + +// Typed factory functions for Yaegi compatibility. +// Yaegi wraps return values per the declared return type, so sub-interface type +// assertions (Plugin -> AuthenticatedRouterPlugin) don't work. These typed +// factories ensure Yaegi wraps the value with the correct interface wrapper. +func NewAuthenticatedRouterPlugin() plugins.AuthenticatedRouterPlugin { return singleton } +func NewUnauthenticatedRouterPlugin() plugins.UnauthenticatedRouterPlugin { return singleton } type TestListener struct{} diff --git a/frontend/eslint.config.js b/frontend/eslint.config.js index 527498e67..bc7fb5e89 100644 --- a/frontend/eslint.config.js +++ b/frontend/eslint.config.js @@ -25,7 +25,62 @@ export default [ 'indent': ['error', 'tab', { 'SwitchCase': 1 }], 'vue/v-on-event-hyphenation': ['warn', 'never', {'autofix': true}], - 'vue/multi-word-component-names': 'off', + 'vue/multi-word-component-names': ['error', { + ignores: [ + // Existing single-word components grandfathered in. + // New components must use multi-word names per Vue style guide. + '404', + 'About', + 'Attachments', + 'Auth', + 'Button.story', + 'Caldav', + 'Card', + 'Card.story', + 'Comments', + 'Datepicker', + 'Description', + 'Done', + 'Dropdown', + 'Error', + 'Expandable', + 'Filters', + 'Flatpickr', + 'Heading', + 'Home', + 'Icon', + 'index', + 'Label', + 'Labels', + 'Legal', + 'List', + 'Loading', + 'Login', + 'Logo', + 'Message', + 'Migration', + 'Modal', + 'Multiselect', + 'Navigation', + 'Nothing', + 'Notification', + 'Notifications', + 'Pagination', + 'Password', + 'Popup', + 'Reactions', + 'Ready', + 'Register', + 'Reminders', + 'Reminders.story', + 'Sessions', + 'Settings', + 'Shortcut', + 'Sort', + 'Subscription', + 'User', + ], + }], // uncategorized rules: 'vue/component-api-style': ['error', ['script-setup']], @@ -57,6 +112,11 @@ export default [ 'depend/ban-dependencies': 'warn', + 'no-restricted-syntax': ['error', { + selector: 'ForInStatement', + message: 'Use for...of with Object.keys/entries, or .forEach, instead of for...in. See https://github.com/go-vikunja/vikunja/issues/513', + }], + '@typescript-eslint/no-unused-vars': [ 'error', { diff --git a/frontend/package.json b/frontend/package.json index c0f7b9ea7..ca2b2b920 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -2,7 +2,7 @@ "name": "vikunja-frontend", "description": "The todo app to organize your life.", "private": true, - "version": "2.2.2", + "version": "2.3.0", "license": "AGPL-3.0-or-later", "repository": { "type": "git", @@ -76,15 +76,14 @@ "@tiptap/vue-3": "3.17.0", "@vueuse/core": "14.1.0", "@vueuse/router": "14.1.0", - "axios": "1.13.5", + "axios": "1.15.0", "blurhash": "2.0.5", "bulma-css-variables": "0.9.33", "change-case": "5.4.4", "dayjs": "1.11.19", - "dompurify": "3.3.2", + "dompurify": "3.4.0", "fast-deep-equal": "3.1.3", "flatpickr": "4.6.13", - "flexsearch": "0.8.212", "floating-vue": "5.2.2", "is-touch-device": "1.0.1", "klona": "2.0.6", @@ -110,51 +109,55 @@ "@histoire/plugin-vue": "1.0.0-beta.1", "@playwright/test": "1.58.2", "@sentry/vite-plugin": "3.6.1", - "@tailwindcss/vite": "4.2.2", + "@tailwindcss/vite": "4.2.4", "@tsconfig/node24": "24.0.4", "@types/codemirror": "5.60.17", "@types/is-touch-device": "1.0.3", - "@types/node": "24.12.0", + "@types/node": "24.12.2", "@types/sortablejs": "1.15.9", - "@typescript-eslint/eslint-plugin": "8.57.2", - "@typescript-eslint/parser": "8.57.2", - "@vitejs/plugin-vue": "6.0.5", + "@types/ws": "8.18.1", + "@typescript-eslint/eslint-plugin": "8.59.0", + "@typescript-eslint/parser": "8.59.0", + "@vitejs/plugin-vue": "6.0.6", "@vue/eslint-config-typescript": "14.7.0", - "@vue/test-utils": "2.4.6", + "@vue/test-utils": "2.4.7", "@vue/tsconfig": "0.9.1", "@vueuse/shared": "14.2.1", - "autoprefixer": "10.4.27", - "browserslist": "4.28.1", - "caniuse-lite": "1.0.30001781", + "autoprefixer": "10.5.0", + "browserslist": "4.28.2", + "caniuse-lite": "1.0.30001790", "csstype": "3.2.3", - "esbuild": "0.27.4", + "esbuild": "0.28.0", "eslint": "9.39.4", "eslint-plugin-depend": "1.5.0", - "eslint-plugin-vue": "10.8.0", - "happy-dom": "20.8.8", + "eslint-plugin-vue": "10.9.0", + "happy-dom": "20.9.0", "histoire": "1.0.0-beta.1", - "postcss": "8.5.8", + "otplib": "12.0.1", + "postcss": "8.5.10", "postcss-easing-gradients": "3.0.1", - "postcss-preset-env": "11.2.0", - "rollup": "4.60.0", + "postcss-html": "1.8.1", + "postcss-preset-env": "11.2.1", + "rollup": "4.60.2", "rollup-plugin-visualizer": "6.0.11", - "sass-embedded": "1.98.0", - "stylelint": "17.5.0", + "sass-embedded": "1.99.0", + "stylelint": "17.9.0", "stylelint-config-property-sort-order-smacss": "10.0.0", "stylelint-config-recommended-vue": "1.6.1", "stylelint-config-standard-scss": "17.0.0", "stylelint-use-logical": "2.1.3", - "tailwindcss": "4.2.2", + "tailwindcss": "4.2.4", "typescript": "5.9.3", "unplugin-inject-preload": "3.0.0", - "vite": "7.3.1", + "vite": "7.3.2", "vite-plugin-pwa": "1.2.0", "vite-plugin-vue-devtools": "8.1.1", "vite-svg-loader": "5.1.1", - "vitest": "4.1.1", - "vue-tsc": "3.2.6", - "wait-on": "9.0.4", - "workbox-cli": "7.4.0" + "vitest": "4.1.5", + "vue-tsc": "3.2.7", + "wait-on": "9.0.5", + "workbox-cli": "7.4.0", + "ws": "8.20.0" }, "pnpm": { "onlyBuiltDependencies": [ @@ -167,8 +170,8 @@ "overrides": { "minimatch": "^10.2.3", "rollup": "$rollup", - "basic-ftp": "5.2.0", - "serialize-javascript": "^7.0.3", + "basic-ftp": ">=5.2.2", + "serialize-javascript": "^7.0.5", "flatted": "^3.4.1" } } diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml index bd63b5c3c..ea280a171 100644 --- a/frontend/pnpm-lock.yaml +++ b/frontend/pnpm-lock.yaml @@ -6,9 +6,9 @@ settings: overrides: minimatch: ^10.2.3 - rollup: 4.60.0 - basic-ftp: 5.2.0 - serialize-javascript: ^7.0.3 + rollup: 4.60.2 + basic-ftp: '>=5.2.2' + serialize-javascript: ^7.0.5 flatted: ^3.4.1 importers: @@ -32,7 +32,7 @@ importers: version: 3.1.3(@fortawesome/fontawesome-svg-core@7.1.0)(vue@3.5.27(typescript@5.9.3)) '@intlify/unplugin-vue-i18n': specifier: 11.0.3 - version: 11.0.3(@vue/compiler-dom@3.5.27)(eslint@9.39.4(jiti@2.4.2))(rollup@4.60.0)(typescript@5.9.3)(vue-i18n@11.2.8(vue@3.5.27(typescript@5.9.3)))(vue@3.5.27(typescript@5.9.3)) + version: 11.0.3(@vue/compiler-dom@3.5.27)(eslint@9.39.4(jiti@2.6.1))(rollup@4.60.2)(typescript@5.9.3)(vue-i18n@11.2.8(vue@3.5.27(typescript@5.9.3)))(vue@3.5.27(typescript@5.9.3)) '@kyvg/vue3-notification': specifier: 3.4.2 version: 3.4.2(vue@3.5.27(typescript@5.9.3)) @@ -91,8 +91,8 @@ importers: specifier: 14.1.0 version: 14.1.0(vue-router@4.6.4(vue@3.5.27(typescript@5.9.3)))(vue@3.5.27(typescript@5.9.3)) axios: - specifier: 1.13.5 - version: 1.13.5 + specifier: 1.15.0 + version: 1.15.0 blurhash: specifier: 2.0.5 version: 2.0.5 @@ -106,17 +106,14 @@ importers: specifier: 1.11.19 version: 1.11.19 dompurify: - specifier: 3.3.2 - version: 3.3.2 + specifier: 3.4.0 + version: 3.4.0 fast-deep-equal: specifier: 3.1.3 version: 3.1.3 flatpickr: specifier: 4.6.13 version: 4.6.13 - flexsearch: - specifier: 0.8.212 - version: 0.8.212 floating-vue: specifier: 5.2.2 version: 5.2.2(vue@3.5.27(typescript@5.9.3)) @@ -177,10 +174,10 @@ importers: version: 10.4.0 '@histoire/plugin-screenshot': specifier: 1.0.0-beta.1 - version: 1.0.0-beta.1(histoire@1.0.0-beta.1(@types/node@24.12.0)(lightningcss@1.32.0)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.31.6)(vite@7.3.1(@types/node@24.12.0)(jiti@2.4.2)(lightningcss@1.32.0)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.31.6)(yaml@2.8.3))(yaml@2.8.3))(typescript@5.9.3) + version: 1.0.0-beta.1(histoire@1.0.0-beta.1(@types/node@24.12.2)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(yaml@2.8.3))(typescript@5.9.3) '@histoire/plugin-vue': specifier: 1.0.0-beta.1 - version: 1.0.0-beta.1(histoire@1.0.0-beta.1(@types/node@24.12.0)(lightningcss@1.32.0)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.31.6)(vite@7.3.1(@types/node@24.12.0)(jiti@2.4.2)(lightningcss@1.32.0)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.31.6)(yaml@2.8.3))(yaml@2.8.3))(vite@7.3.1(@types/node@24.12.0)(jiti@2.4.2)(lightningcss@1.32.0)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.31.6)(yaml@2.8.3))(vue@3.5.27(typescript@5.9.3)) + version: 1.0.0-beta.1(histoire@1.0.0-beta.1(@types/node@24.12.2)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(yaml@2.8.3))(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(vue@3.5.27(typescript@5.9.3)) '@playwright/test': specifier: 1.58.2 version: 1.58.2 @@ -188,8 +185,8 @@ importers: specifier: 3.6.1 version: 3.6.1 '@tailwindcss/vite': - specifier: 4.2.2 - version: 4.2.2(vite@7.3.1(@types/node@24.12.0)(jiti@2.4.2)(lightningcss@1.32.0)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.31.6)(yaml@2.8.3)) + specifier: 4.2.4 + version: 4.2.4(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) '@tsconfig/node24': specifier: 24.0.4 version: 24.0.4 @@ -200,26 +197,29 @@ importers: specifier: 1.0.3 version: 1.0.3 '@types/node': - specifier: 24.12.0 - version: 24.12.0 + specifier: 24.12.2 + version: 24.12.2 '@types/sortablejs': specifier: 1.15.9 version: 1.15.9 + '@types/ws': + specifier: 8.18.1 + version: 8.18.1 '@typescript-eslint/eslint-plugin': - specifier: 8.57.2 - version: 8.57.2(@typescript-eslint/parser@8.57.2(eslint@9.39.4(jiti@2.4.2))(typescript@5.9.3))(eslint@9.39.4(jiti@2.4.2))(typescript@5.9.3) + specifier: 8.59.0 + version: 8.59.0(@typescript-eslint/parser@8.59.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) '@typescript-eslint/parser': - specifier: 8.57.2 - version: 8.57.2(eslint@9.39.4(jiti@2.4.2))(typescript@5.9.3) + specifier: 8.59.0 + version: 8.59.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) '@vitejs/plugin-vue': - specifier: 6.0.5 - version: 6.0.5(vite@7.3.1(@types/node@24.12.0)(jiti@2.4.2)(lightningcss@1.32.0)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.31.6)(yaml@2.8.3))(vue@3.5.27(typescript@5.9.3)) + specifier: 6.0.6 + version: 6.0.6(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(vue@3.5.27(typescript@5.9.3)) '@vue/eslint-config-typescript': specifier: 14.7.0 - version: 14.7.0(eslint-plugin-vue@10.8.0(@typescript-eslint/parser@8.57.2(eslint@9.39.4(jiti@2.4.2))(typescript@5.9.3))(eslint@9.39.4(jiti@2.4.2))(vue-eslint-parser@10.4.0(eslint@9.39.4(jiti@2.4.2))))(eslint@9.39.4(jiti@2.4.2))(typescript@5.9.3) + version: 14.7.0(eslint-plugin-vue@10.9.0(@typescript-eslint/parser@8.59.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@9.39.4(jiti@2.6.1))))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) '@vue/test-utils': - specifier: 2.4.6 - version: 2.4.6 + specifier: 2.4.7 + version: 2.4.7(@vue/compiler-dom@3.5.27)(@vue/server-renderer@3.5.27(vue@3.5.27(typescript@5.9.3)))(vue@3.5.27(typescript@5.9.3)) '@vue/tsconfig': specifier: 0.9.1 version: 0.9.1(typescript@5.9.3)(vue@3.5.27(typescript@5.9.3)) @@ -227,71 +227,77 @@ importers: specifier: 14.2.1 version: 14.2.1(vue@3.5.27(typescript@5.9.3)) autoprefixer: - specifier: 10.4.27 - version: 10.4.27(postcss@8.5.8) + specifier: 10.5.0 + version: 10.5.0(postcss@8.5.10) browserslist: - specifier: 4.28.1 - version: 4.28.1 + specifier: 4.28.2 + version: 4.28.2 caniuse-lite: - specifier: 1.0.30001781 - version: 1.0.30001781 + specifier: 1.0.30001790 + version: 1.0.30001790 csstype: specifier: 3.2.3 version: 3.2.3 esbuild: - specifier: 0.27.4 - version: 0.27.4 + specifier: 0.28.0 + version: 0.28.0 eslint: specifier: 9.39.4 - version: 9.39.4(jiti@2.4.2) + version: 9.39.4(jiti@2.6.1) eslint-plugin-depend: specifier: 1.5.0 - version: 1.5.0(eslint@9.39.4(jiti@2.4.2)) + version: 1.5.0(eslint@9.39.4(jiti@2.6.1)) eslint-plugin-vue: - specifier: 10.8.0 - version: 10.8.0(@typescript-eslint/parser@8.57.2(eslint@9.39.4(jiti@2.4.2))(typescript@5.9.3))(eslint@9.39.4(jiti@2.4.2))(vue-eslint-parser@10.4.0(eslint@9.39.4(jiti@2.4.2))) + specifier: 10.9.0 + version: 10.9.0(@typescript-eslint/parser@8.59.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@9.39.4(jiti@2.6.1))) happy-dom: - specifier: 20.8.8 - version: 20.8.8 + specifier: 20.9.0 + version: 20.9.0 histoire: specifier: 1.0.0-beta.1 - version: 1.0.0-beta.1(@types/node@24.12.0)(lightningcss@1.32.0)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.31.6)(vite@7.3.1(@types/node@24.12.0)(jiti@2.4.2)(lightningcss@1.32.0)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.31.6)(yaml@2.8.3))(yaml@2.8.3) + version: 1.0.0-beta.1(@types/node@24.12.2)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(yaml@2.8.3) + otplib: + specifier: 12.0.1 + version: 12.0.1 postcss: - specifier: 8.5.8 - version: 8.5.8 + specifier: 8.5.10 + version: 8.5.10 postcss-easing-gradients: specifier: 3.0.1 version: 3.0.1 + postcss-html: + specifier: 1.8.1 + version: 1.8.1 postcss-preset-env: - specifier: 11.2.0 - version: 11.2.0(postcss@8.5.8) + specifier: 11.2.1 + version: 11.2.1(postcss@8.5.10) rollup: - specifier: 4.60.0 - version: 4.60.0 + specifier: 4.60.2 + version: 4.60.2 rollup-plugin-visualizer: specifier: 6.0.11 - version: 6.0.11(rollup@4.60.0) + version: 6.0.11(rollup@4.60.2) sass-embedded: - specifier: 1.98.0 - version: 1.98.0 + specifier: 1.99.0 + version: 1.99.0 stylelint: - specifier: 17.5.0 - version: 17.5.0(typescript@5.9.3) + specifier: 17.9.0 + version: 17.9.0(typescript@5.9.3) stylelint-config-property-sort-order-smacss: specifier: 10.0.0 - version: 10.0.0(stylelint@17.5.0(typescript@5.9.3)) + version: 10.0.0(stylelint@17.9.0(typescript@5.9.3)) stylelint-config-recommended-vue: specifier: 1.6.1 - version: 1.6.1(postcss-html@1.8.0)(stylelint@17.5.0(typescript@5.9.3)) + version: 1.6.1(postcss-html@1.8.1)(stylelint@17.9.0(typescript@5.9.3)) stylelint-config-standard-scss: specifier: 17.0.0 - version: 17.0.0(postcss@8.5.8)(stylelint@17.5.0(typescript@5.9.3)) + version: 17.0.0(postcss@8.5.10)(stylelint@17.9.0(typescript@5.9.3)) stylelint-use-logical: specifier: 2.1.3 - version: 2.1.3(stylelint@17.5.0(typescript@5.9.3)) + version: 2.1.3(stylelint@17.9.0(typescript@5.9.3)) tailwindcss: - specifier: 4.2.2 - version: 4.2.2 + specifier: 4.2.4 + version: 4.2.4 typescript: specifier: 5.9.3 version: 5.9.3 @@ -299,29 +305,32 @@ importers: specifier: 3.0.0 version: 3.0.0 vite: - specifier: 7.3.1 - version: 7.3.1(@types/node@24.12.0)(jiti@2.4.2)(lightningcss@1.32.0)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.31.6)(yaml@2.8.3) + specifier: 7.3.2 + version: 7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) vite-plugin-pwa: specifier: 1.2.0 - version: 1.2.0(vite@7.3.1(@types/node@24.12.0)(jiti@2.4.2)(lightningcss@1.32.0)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.31.6)(yaml@2.8.3))(workbox-build@7.4.0)(workbox-window@7.4.0) + version: 1.2.0(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(workbox-build@7.4.0)(workbox-window@7.4.0) vite-plugin-vue-devtools: specifier: 8.1.1 - version: 8.1.1(vite@7.3.1(@types/node@24.12.0)(jiti@2.4.2)(lightningcss@1.32.0)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.31.6)(yaml@2.8.3))(vue@3.5.27(typescript@5.9.3)) + version: 8.1.1(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(vue@3.5.27(typescript@5.9.3)) vite-svg-loader: specifier: 5.1.1 version: 5.1.1(vue@3.5.27(typescript@5.9.3)) vitest: - specifier: 4.1.1 - version: 4.1.1(@types/node@24.12.0)(happy-dom@20.8.8)(jsdom@27.4.0)(vite@7.3.1(@types/node@24.12.0)(jiti@2.4.2)(lightningcss@1.32.0)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.31.6)(yaml@2.8.3)) + specifier: 4.1.5 + version: 4.1.5(@types/node@24.12.2)(happy-dom@20.9.0)(jsdom@27.4.0)(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) vue-tsc: - specifier: 3.2.6 - version: 3.2.6(typescript@5.9.3) + specifier: 3.2.7 + version: 3.2.7(typescript@5.9.3) wait-on: - specifier: 9.0.4 - version: 9.0.4 + specifier: 9.0.5 + version: 9.0.5 workbox-cli: specifier: 7.4.0 version: 7.4.0 + ws: + specifier: 8.20.0 + version: 8.20.0 packages: @@ -931,8 +940,8 @@ packages: '@csstools/css-parser-algorithms': ^3.0.5 '@csstools/css-tokenizer': ^3.0.4 - '@csstools/css-calc@3.1.1': - resolution: {integrity: sha512-HJ26Z/vmsZQqs/o3a6bgKslXGFAungXGbinULZO3eMsOyNJHeBBZfup5FiZInOghgoM4Hwnmw+OgbJCNg1wwUQ==} + '@csstools/css-calc@3.2.0': + resolution: {integrity: sha512-bR9e6o2BDB12jzN/gIbjHa5wLJ4UjD1CB9pM7ehlc0ddk6EBz+yYS1EV2MF55/HUxrHcB/hehAyt5vhsA3hx7w==} engines: {node: '>=20.19.0'} peerDependencies: '@csstools/css-parser-algorithms': ^4.0.0 @@ -945,8 +954,8 @@ packages: '@csstools/css-parser-algorithms': ^3.0.5 '@csstools/css-tokenizer': ^3.0.4 - '@csstools/css-color-parser@4.0.2': - resolution: {integrity: sha512-0GEfbBLmTFf0dJlpsNU7zwxRIH0/BGEMuXLTCvFYxuL1tNhqzTbtnFICyJLTNK4a+RechKP75e7w42ClXSnJQw==} + '@csstools/css-color-parser@4.1.0': + resolution: {integrity: sha512-U0KhLYmy2GVj6q4T3WaAe6NPuFYCPQoE3b0dRGxejWDgcPp8TP7S5rVdM5ZrFaqu4N67X8YaPBw14dQSYx3IyQ==} engines: {node: '>=20.19.0'} peerDependencies: '@csstools/css-parser-algorithms': ^4.0.0 @@ -964,11 +973,16 @@ packages: peerDependencies: '@csstools/css-tokenizer': ^4.0.0 - '@csstools/css-syntax-patches-for-csstree@1.0.28': - resolution: {integrity: sha512-1NRf1CUBjnr3K7hu8BLxjQrKCxEe8FP/xmPTenAxCRZWVLbmGotkFvG9mfNpjA6k7Bw1bw4BilZq9cu19RA5pg==} + '@csstools/css-syntax-patches-for-csstree@1.1.2': + resolution: {integrity: sha512-5GkLzz4prTIpoyeUiIu3iV6CSG3Plo7xRVOFPKI7FVEJ3mZ0A8SwK0XU3Gl7xAkiQ+mDyam+NNp875/C5y+jSA==} + peerDependencies: + css-tree: ^3.2.1 + peerDependenciesMeta: + css-tree: + optional: true - '@csstools/css-syntax-patches-for-csstree@1.1.1': - resolution: {integrity: sha512-BvqN0AMWNAnLk9G8jnUT77D+mUbY/H2b3uDTvg2isJkHaOufUE2R3AOwxWo7VBQKT1lOdwdvorddo2B/lk64+w==} + '@csstools/css-syntax-patches-for-csstree@1.1.3': + resolution: {integrity: sha512-SH60bMfrRCJF3morcdk57WklujF4Jr/EsQUzqkarfHXEFcAR1gg7fS/chAE922Sehgzc1/+Tz5H3Ypa1HiEKrg==} peerDependencies: css-tree: ^3.2.1 peerDependenciesMeta: @@ -990,8 +1004,8 @@ packages: '@csstools/css-parser-algorithms': ^4.0.0 '@csstools/css-tokenizer': ^4.0.0 - '@csstools/postcss-alpha-function@2.0.3': - resolution: {integrity: sha512-8GqzD3JnfpKJSVxPIC0KadyAfB5VRzPZdv7XQ4zvK1q0ku+uHVUAS2N/IDavQkW40gkuUci64O0ea6QB/zgCSw==} + '@csstools/postcss-alpha-function@2.0.4': + resolution: {integrity: sha512-fti7+GybzvfMrv5TSU6x8rWtXWOth5nLefT5w5AKJ3F3T0bZoxlRqajF0ZUgTtnytfMd4dQ8n5UiaNmsjFA65A==} engines: {node: '>=20.19.0'} peerDependencies: postcss: ^8.4 @@ -1002,26 +1016,26 @@ packages: peerDependencies: postcss: ^8.4 - '@csstools/postcss-color-function-display-p3-linear@2.0.2': - resolution: {integrity: sha512-TWUwSe1+2KdYGGWTx5LR4JQN07vKHAeSho+bGYRgow+9cs3dqgOqS1f/a1odiX30ESmZvwIudJ86wzeiDR6UGg==} + '@csstools/postcss-color-function-display-p3-linear@2.0.3': + resolution: {integrity: sha512-u8QNV2TKOxG6cqK4ZrJkpctnxdrwdNTMrkyokmCi+iuLpJegOraA0cqC7HoxF2tHhxjuXc+BxwY/Qd62SwvanQ==} engines: {node: '>=20.19.0'} peerDependencies: postcss: ^8.4 - '@csstools/postcss-color-function@5.0.2': - resolution: {integrity: sha512-CjBdFemUFcAh3087MEJhZcO+QT1b8S75agysa1rU9TEC1YecznzwV+jpMxUc0JRBEV4ET2PjLssqmndR9IygeA==} + '@csstools/postcss-color-function@5.0.3': + resolution: {integrity: sha512-BiBukIeQ7rPjx9A//9+qgJugBjX6FY9eWiojbnfIJCPulWrl8J07rCgQbFkloTXena+a6Aw5xa25weU+3MA75A==} engines: {node: '>=20.19.0'} peerDependencies: postcss: ^8.4 - '@csstools/postcss-color-mix-function@4.0.2': - resolution: {integrity: sha512-PFKQKswFqZrYKpajZsP4lhqjU/6+J5PTOWq1rKiFnniKsf4LgpGXrgHS/C6nn5Rc51LX0n4dWOWqY5ZN2i5IjA==} + '@csstools/postcss-color-mix-function@4.0.3': + resolution: {integrity: sha512-M8ju3iqHRXtW1/5HYuOmi9WFR5rGGFgqkPh+kXkv/eG56oYK/WYtTeIwJgdcro7lRwjlo4Ut8xqbV3Iovkwfrw==} engines: {node: '>=20.19.0'} peerDependencies: postcss: ^8.4 - '@csstools/postcss-color-mix-variadic-function-arguments@2.0.2': - resolution: {integrity: sha512-zEchsghpDH/6SytyjKu9TIPm4hiiWcur102cENl54cyIwTZsa+2MBJl/vtyALZ+uQ17h27L4waD+0Ow96sgZow==} + '@csstools/postcss-color-mix-variadic-function-arguments@2.0.3': + resolution: {integrity: sha512-tL46UyFjIjz7mDywoPOe/JgOpvMic0rsTUfdMBB1OHrUcCtE8MQpBILzYl/cAOtinJGu+ZQLuDhqTgTBOoeg3g==} engines: {node: '>=20.19.0'} peerDependencies: postcss: ^8.4 @@ -1032,14 +1046,14 @@ packages: peerDependencies: postcss: ^8.4 - '@csstools/postcss-contrast-color-function@3.0.2': - resolution: {integrity: sha512-fwOz/m+ytFPz4aIph2foQS9nEDOdOjYcN5bgwbGR2jGUV8mYaeD/EaTVMHTRb/zqB65y2qNwmcFcE6VQty69Pw==} + '@csstools/postcss-contrast-color-function@3.0.3': + resolution: {integrity: sha512-YcohXq+/hfYeobKirg3oXGivDaaTfOPv568bE3jYQCn9ILpFz+RgyJR/kF7ZWh5560TTlTjeCqF4ZmVsj2zwnw==} engines: {node: '>=20.19.0'} peerDependencies: postcss: ^8.4 - '@csstools/postcss-exponential-functions@3.0.1': - resolution: {integrity: sha512-WHJ52Uk0AVUIICEYRY9xFHJZAuq0ZVg0f8xzqUN2zRFrZvGgRPpFwxK7h9FWvqKIOueOwN6hnJD23A8FwsUiVw==} + '@csstools/postcss-exponential-functions@3.0.2': + resolution: {integrity: sha512-WDrfdFJXF4M67+wniEGr/5XVzsmn1rt2lL1YAlTfE7x7XDlRstTc5e+HuFoGv6jkiMWTwPsiADJaLwsnGC3UjQ==} engines: {node: '>=20.19.0'} peerDependencies: postcss: ^8.4 @@ -1056,20 +1070,20 @@ packages: peerDependencies: postcss: ^8.4 - '@csstools/postcss-gamut-mapping@3.0.2': - resolution: {integrity: sha512-IrXAW3KQ3Sxm29C3/4mYQ/iA0Q5OH9YFOPQ2w24iIlXpD06A9MHvmQapP2vAGtQI3tlp2Xw5LIdm9F8khARfOA==} + '@csstools/postcss-gamut-mapping@3.0.3': + resolution: {integrity: sha512-3v5ZvcVuynhFh5qCJX2LIJ9Iry8/SvxfOEj6vDngNxbH/3OKTZBFLgK+DgLuIbsP1DLA9LLH3Rn7jmRxXgEDLA==} engines: {node: '>=20.19.0'} peerDependencies: postcss: ^8.4 - '@csstools/postcss-gradients-interpolation-method@6.0.2': - resolution: {integrity: sha512-saQHvD1PD/zCdn+kxCWCcQOdXZBljr8L6BKlCLs0w8GXYfo3SHdWL1HZQ+I1hVCPlU+MJPJJbZJjG/jHRJSlAw==} + '@csstools/postcss-gradients-interpolation-method@6.0.3': + resolution: {integrity: sha512-wrRIaRv1dkq30a8nvYWtSAf41bwCl+sVzLBKGnqeOwk81aSktKN3NattJpkiPyoOtEoFqChisl3WH3Csj/rOsw==} engines: {node: '>=20.19.0'} peerDependencies: postcss: ^8.4 - '@csstools/postcss-hwb-function@5.0.2': - resolution: {integrity: sha512-ChR0+pKc/2cs900jakiv8dLrb69aez5P3T+g+wfJx1j6mreAe8orKTiMrVBk+DZvCRqpdOA2m8VoFms64A3Dew==} + '@csstools/postcss-hwb-function@5.0.3': + resolution: {integrity: sha512-bHz0uc/PBg2wJEAlGinUf494nMyuXsVKH/fExc2xGkvL6WHOKlxzx/lkn+2AVCQACtWBLVRCBDgDnkYr4RSC9w==} engines: {node: '>=20.19.0'} peerDependencies: postcss: ^8.4 @@ -1128,8 +1142,8 @@ packages: peerDependencies: postcss: ^8.4 - '@csstools/postcss-media-minmax@3.0.1': - resolution: {integrity: sha512-I+CrmZt23fyejMItpLQFOg9gPXkDBBDjTqRT0UxCTZlYZfGrzZn4z+2kbXLRwDfR59OK8zaf26M4kwYwG0e1MA==} + '@csstools/postcss-media-minmax@3.0.2': + resolution: {integrity: sha512-+ABxs2ZhJDhy+B9PJg7pgkGq6/d3XPXsWl7+6yZfAk4b2ba6aQ1h2AiTn04XwS6rpMpZEF3tONli/ubfu4y8AQ==} engines: {node: '>=20.19.0'} peerDependencies: postcss: ^8.4 @@ -1158,8 +1172,8 @@ packages: peerDependencies: postcss: ^8.4 - '@csstools/postcss-oklab-function@5.0.2': - resolution: {integrity: sha512-3d/Wcnp2uW6Io0Tajl0croeUo46gwOVQI9N32PjA/HVQo6z1iL7yp19Gp+6e5E5CDKGpW7U822MsDVo2XK1z0Q==} + '@csstools/postcss-oklab-function@5.0.3': + resolution: {integrity: sha512-vTMgJFMwMt9gnPvhKaDnMR7E/h9Nb+rPUv825SY5VUo4PWj+w0OH/N2NqgvjYeubaA3BVckbKDlvADATRpD4Hw==} engines: {node: '>=20.19.0'} peerDependencies: postcss: ^8.4 @@ -1182,14 +1196,14 @@ packages: peerDependencies: postcss: ^8.4 - '@csstools/postcss-random-function@3.0.1': - resolution: {integrity: sha512-SvKGfmj+WHfn4bWHaBYlkXDyU3SlA3fL8aaYZ8Op6M8tunNf3iV9uZyZZGWMCbDw0sGeoTmYZW9nmKN8Qi/ctg==} + '@csstools/postcss-random-function@3.0.2': + resolution: {integrity: sha512-iQ3vfX1LIqRXX7P1/ol45EpJ5CTWdQCAfdpTlHlsRPU4jMQeepmeNjQ0F60bj8RWTS1RkJ318fzzq4mUlyZ7hA==} engines: {node: '>=20.19.0'} peerDependencies: postcss: ^8.4 - '@csstools/postcss-relative-color-syntax@4.0.2': - resolution: {integrity: sha512-HaMN+qMURinllszbps2AhXKaLeibg/2VW6FriYDrqE58ji82+z2S3/eLloywVOY8BQCJ9lZMdy6TcRQNbn9u3w==} + '@csstools/postcss-relative-color-syntax@4.0.3': + resolution: {integrity: sha512-SZSImz4KufmLi0dRwYivWXlza+7HF84SRApY8R48SyWgn+f0gDvmCn7D2Ie4CED7qU0JJK+YfCUC1HVlaQ10dg==} engines: {node: '>=20.19.0'} peerDependencies: postcss: ^8.4 @@ -1200,14 +1214,14 @@ packages: peerDependencies: postcss: ^8.4 - '@csstools/postcss-sign-functions@2.0.1': - resolution: {integrity: sha512-C3br0qcHJkQ0qSGUBnDJHXQdO8XObnCpGwai5m1L2tv2nCjt0vRHG6A9aVCQHvh08OqHNM2ty1dYDNNXV99YAQ==} + '@csstools/postcss-sign-functions@2.0.2': + resolution: {integrity: sha512-vOxkkMCMVnyaj7CW03uKR2R/zhJaCrptsXlm31HgI/dqC1lSIGnmu5W7N68x23XwcSgc8fE/fg0jKj4x1XFH4w==} engines: {node: '>=20.19.0'} peerDependencies: postcss: ^8.4 - '@csstools/postcss-stepped-value-functions@5.0.1': - resolution: {integrity: sha512-vZf7zPzRb7xIi2o5Z9q6wyeEAjoRCg74O2QvYxmQgxYO5V5cdBv4phgJDyOAOP3JHy4abQlm2YaEUS3gtGQo0g==} + '@csstools/postcss-stepped-value-functions@5.0.2': + resolution: {integrity: sha512-4PtqkRoBcMSxZG00gcDv+nq7cxVUua+Yd7TmG16qzJjdolyICHkx1RfhNL5mKSnWOLxUnk/IdxAoWN+KU7E/ng==} engines: {node: '>=20.19.0'} peerDependencies: postcss: ^8.4 @@ -1230,8 +1244,8 @@ packages: peerDependencies: postcss: ^8.4 - '@csstools/postcss-trigonometric-functions@5.0.1': - resolution: {integrity: sha512-e8me32Mhl8JeBnxVJgsQUYpV4Md4KiyvpILpQlaY/eK1Gwdb04kasiTTswPQ5q7Z8+FppJZ2Z4d8HRfn6rjD3w==} + '@csstools/postcss-trigonometric-functions@5.0.2': + resolution: {integrity: sha512-hRansZmQk1HH11WGUNlWy8H/DCB9Wy6zDbRcyBfF2UUP+V2fubK+qwmq0q6LIDje5gRzxlKyWhgFYxPy1ohivA==} engines: {node: '>=20.19.0'} peerDependencies: postcss: ^8.4 @@ -1266,8 +1280,14 @@ packages: cpu: [ppc64] os: [aix] - '@esbuild/aix-ppc64@0.27.4': - resolution: {integrity: sha512-cQPwL2mp2nSmHHJlCyoXgHGhbEPMrEEU5xhkcy3Hs/O7nGZqEpZ2sUtLaL9MORLtDfRvVl2/3PAuEkYZH0Ty8Q==} + '@esbuild/aix-ppc64@0.27.5': + resolution: {integrity: sha512-nGsF/4C7uzUj+Nj/4J+Zt0bYQ6bz33Phz8Lb2N80Mti1HjGclTJdXZ+9APC4kLvONbjxN1zfvYNd8FEcbBK/MQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/aix-ppc64@0.28.0': + resolution: {integrity: sha512-lhRUCeuOyJQURhTxl4WkpFTjIsbDayJHih5kZC1giwE+MhIzAb7mEsQMqMf18rHLsrb5qI1tafG20mLxEWcWlA==} engines: {node: '>=18'} cpu: [ppc64] os: [aix] @@ -1278,8 +1298,14 @@ packages: cpu: [arm64] os: [android] - '@esbuild/android-arm64@0.27.4': - resolution: {integrity: sha512-gdLscB7v75wRfu7QSm/zg6Rx29VLdy9eTr2t44sfTW7CxwAtQghZ4ZnqHk3/ogz7xao0QAgrkradbBzcqFPasw==} + '@esbuild/android-arm64@0.27.5': + resolution: {integrity: sha512-Oeghq+XFgh1pUGd1YKs4DDoxzxkoUkvko+T/IVKwlghKLvvjbGFB3ek8VEDBmNvqhwuL0CQS3cExdzpmUyIrgA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm64@0.28.0': + resolution: {integrity: sha512-+WzIXQOSaGs33tLEgYPYe/yQHf0WTU0X42Jca3y8NWMbUVhp7rUnw+vAsRC/QiDrdD31IszMrZy+qwPOPjd+rw==} engines: {node: '>=18'} cpu: [arm64] os: [android] @@ -1290,8 +1316,14 @@ packages: cpu: [arm] os: [android] - '@esbuild/android-arm@0.27.4': - resolution: {integrity: sha512-X9bUgvxiC8CHAGKYufLIHGXPJWnr0OCdR0anD2e21vdvgCI8lIfqFbnoeOz7lBjdrAGUhqLZLcQo6MLhTO2DKQ==} + '@esbuild/android-arm@0.27.5': + resolution: {integrity: sha512-Cv781jd0Rfj/paoNrul1/r4G0HLvuFKYh7C9uHZ2Pl8YXstzvCyyeWENTFR9qFnRzNMCjXmsulZuvosDg10Mog==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-arm@0.28.0': + resolution: {integrity: sha512-wqh0ByljabXLKHeWXYLqoJ5jKC4XBaw6Hk08OfMrCRd2nP2ZQ5eleDZC41XHyCNgktBGYMbqnrJKq/K/lzPMSQ==} engines: {node: '>=18'} cpu: [arm] os: [android] @@ -1302,8 +1334,14 @@ packages: cpu: [x64] os: [android] - '@esbuild/android-x64@0.27.4': - resolution: {integrity: sha512-PzPFnBNVF292sfpfhiyiXCGSn9HZg5BcAz+ivBuSsl6Rk4ga1oEXAamhOXRFyMcjwr2DVtm40G65N3GLeH1Lvw==} + '@esbuild/android-x64@0.27.5': + resolution: {integrity: sha512-nQD7lspbzerlmtNOxYMFAGmhxgzn8Z7m9jgFkh6kpkjsAhZee1w8tJW3ZlW+N9iRePz0oPUDrYrXidCPSImD0Q==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/android-x64@0.28.0': + resolution: {integrity: sha512-+VJggoaKhk2VNNqVL7f6S189UzShHC/mR9EE8rDdSkdpN0KflSwWY/gWjDrNxxisg8Fp1ZCD9jLMo4m0OUfeUA==} engines: {node: '>=18'} cpu: [x64] os: [android] @@ -1314,8 +1352,14 @@ packages: cpu: [arm64] os: [darwin] - '@esbuild/darwin-arm64@0.27.4': - resolution: {integrity: sha512-b7xaGIwdJlht8ZFCvMkpDN6uiSmnxxK56N2GDTMYPr2/gzvfdQN8rTfBsvVKmIVY/X7EM+/hJKEIbbHs9oA4tQ==} + '@esbuild/darwin-arm64@0.27.5': + resolution: {integrity: sha512-I+Ya/MgC6rr8oRWGRDF3BXDfP8K1BVUggHqN6VI2lUZLdDi1IM1v2cy0e3lCPbP+pVcK3Tv8cgUhHse1kaNZZw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-arm64@0.28.0': + resolution: {integrity: sha512-0T+A9WZm+bZ84nZBtk1ckYsOvyA3x7e2Acj1KdVfV4/2tdG4fzUp91YHx+GArWLtwqp77pBXVCPn2We7Letr0Q==} engines: {node: '>=18'} cpu: [arm64] os: [darwin] @@ -1326,8 +1370,14 @@ packages: cpu: [x64] os: [darwin] - '@esbuild/darwin-x64@0.27.4': - resolution: {integrity: sha512-sR+OiKLwd15nmCdqpXMnuJ9W2kpy0KigzqScqHI3Hqwr7IXxBp3Yva+yJwoqh7rE8V77tdoheRYataNKL4QrPw==} + '@esbuild/darwin-x64@0.27.5': + resolution: {integrity: sha512-MCjQUtC8wWJn/pIPM7vQaO69BFgwPD1jriEdqwTCKzWjGgkMbcg+M5HzrOhPhuYe1AJjXlHmD142KQf+jnYj8A==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/darwin-x64@0.28.0': + resolution: {integrity: sha512-fyzLm/DLDl/84OCfp2f/XQ4flmORsjU7VKt8HLjvIXChJoFFOIL6pLJPH4Yhd1n1gGFF9mPwtlN5Wf82DZs+LQ==} engines: {node: '>=18'} cpu: [x64] os: [darwin] @@ -1338,8 +1388,14 @@ packages: cpu: [arm64] os: [freebsd] - '@esbuild/freebsd-arm64@0.27.4': - resolution: {integrity: sha512-jnfpKe+p79tCnm4GVav68A7tUFeKQwQyLgESwEAUzyxk/TJr4QdGog9sqWNcUbr/bZt/O/HXouspuQDd9JxFSw==} + '@esbuild/freebsd-arm64@0.27.5': + resolution: {integrity: sha512-X6xVS+goSH0UelYXnuf4GHLwpOdc8rgK/zai+dKzBMnncw7BTQIwquOodE7EKvY2UVUetSqyAfyZC1D+oqLQtg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-arm64@0.28.0': + resolution: {integrity: sha512-l9GeW5UZBT9k9brBYI+0WDffcRxgHQD8ShN2Ur4xWq/NFzUKm3k5lsH4PdaRgb2w7mI9u61nr2gI2mLI27Nh3Q==} engines: {node: '>=18'} cpu: [arm64] os: [freebsd] @@ -1350,8 +1406,14 @@ packages: cpu: [x64] os: [freebsd] - '@esbuild/freebsd-x64@0.27.4': - resolution: {integrity: sha512-2kb4ceA/CpfUrIcTUl1wrP/9ad9Atrp5J94Lq69w7UwOMolPIGrfLSvAKJp0RTvkPPyn6CIWrNy13kyLikZRZQ==} + '@esbuild/freebsd-x64@0.27.5': + resolution: {integrity: sha512-233X1FGo3a8x1ekLB6XT69LfZ83vqz+9z3TSEQCTYfMNY880A97nr81KbPcAMl9rmOFp11wO0dP+eB18KU/Ucg==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.28.0': + resolution: {integrity: sha512-BXoQai/A0wPO6Es3yFJ7APCiKGc1tdAEOgeTNy3SsB491S3aHn4S4r3e976eUnPdU+NbdtmBuLncYir2tMU9Nw==} engines: {node: '>=18'} cpu: [x64] os: [freebsd] @@ -1362,8 +1424,14 @@ packages: cpu: [arm64] os: [linux] - '@esbuild/linux-arm64@0.27.4': - resolution: {integrity: sha512-7nQOttdzVGth1iz57kxg9uCz57dxQLHWxopL6mYuYthohPKEK0vU0C3O21CcBK6KDlkYVcnDXY099HcCDXd9dA==} + '@esbuild/linux-arm64@0.27.5': + resolution: {integrity: sha512-euKkilsNOv7x/M1NKsx5znyprbpsRFIzTV6lWziqJch7yWYayfLtZzDxDTl+LSQDJYAjd9TVb/Kt5UKIrj2e4A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm64@0.28.0': + resolution: {integrity: sha512-RVyzfb3FWsGA55n6WY0MEIEPURL1FcbhFE6BffZEMEekfCzCIMtB5yyDcFnVbTnwk+CLAgTujmV/Lgvih56W+A==} engines: {node: '>=18'} cpu: [arm64] os: [linux] @@ -1374,8 +1442,14 @@ packages: cpu: [arm] os: [linux] - '@esbuild/linux-arm@0.27.4': - resolution: {integrity: sha512-aBYgcIxX/wd5n2ys0yESGeYMGF+pv6g0DhZr3G1ZG4jMfruU9Tl1i2Z+Wnj9/KjGz1lTLCcorqE2viePZqj4Eg==} + '@esbuild/linux-arm@0.27.5': + resolution: {integrity: sha512-0wkVrYHG4sdCCN/bcwQ7yYMXACkaHc3UFeaEOwSVW6e5RycMageYAFv+JS2bKLwHyeKVUvtoVH+5/RHq0fgeFw==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-arm@0.28.0': + resolution: {integrity: sha512-CjaaREJagqJp7iTaNQjjidaNbCKYcd4IDkzbwwxtSvjI7NZm79qiHc8HqciMddQ6CKvJT6aBd8lO9kN/ZudLlw==} engines: {node: '>=18'} cpu: [arm] os: [linux] @@ -1386,8 +1460,14 @@ packages: cpu: [ia32] os: [linux] - '@esbuild/linux-ia32@0.27.4': - resolution: {integrity: sha512-oPtixtAIzgvzYcKBQM/qZ3R+9TEUd1aNJQu0HhGyqtx6oS7qTpvjheIWBbes4+qu1bNlo2V4cbkISr8q6gRBFA==} + '@esbuild/linux-ia32@0.27.5': + resolution: {integrity: sha512-hVRQX4+P3MS36NxOy24v/Cdsimy/5HYePw+tmPqnNN1fxV0bPrFWR6TMqwXPwoTM2VzbkA+4lbHWUKDd5ZDA/w==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-ia32@0.28.0': + resolution: {integrity: sha512-KBnSTt1kxl9x70q+ydterVdl+Cn0H18ngRMRCEQfrbqdUuntQQ0LoMZv47uB97NljZFzY6HcfqEZ2SAyIUTQBQ==} engines: {node: '>=18'} cpu: [ia32] os: [linux] @@ -1398,8 +1478,14 @@ packages: cpu: [loong64] os: [linux] - '@esbuild/linux-loong64@0.27.4': - resolution: {integrity: sha512-8mL/vh8qeCoRcFH2nM8wm5uJP+ZcVYGGayMavi8GmRJjuI3g1v6Z7Ni0JJKAJW+m0EtUuARb6Lmp4hMjzCBWzA==} + '@esbuild/linux-loong64@0.27.5': + resolution: {integrity: sha512-mKqqRuOPALI8nDzhOBmIS0INvZOOFGGg5n1osGIXAx8oersceEbKd4t1ACNTHM3sJBXGFAlEgqM+svzjPot+ZQ==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-loong64@0.28.0': + resolution: {integrity: sha512-zpSlUce1mnxzgBADvxKXX5sl8aYQHo2ezvMNI8I0lbblJtp8V4odlm3Yzlj7gPyt3T8ReksE6bK+pT3WD+aJRg==} engines: {node: '>=18'} cpu: [loong64] os: [linux] @@ -1410,8 +1496,14 @@ packages: cpu: [mips64el] os: [linux] - '@esbuild/linux-mips64el@0.27.4': - resolution: {integrity: sha512-1RdrWFFiiLIW7LQq9Q2NES+HiD4NyT8Itj9AUeCl0IVCA459WnPhREKgwrpaIfTOe+/2rdntisegiPWn/r/aAw==} + '@esbuild/linux-mips64el@0.27.5': + resolution: {integrity: sha512-EE/QXH9IyaAj1qeuIV5+/GZkBTipgGO782Ff7Um3vPS9cvLhJJeATy4Ggxikz2inZ46KByamMn6GqtqyVjhenA==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-mips64el@0.28.0': + resolution: {integrity: sha512-2jIfP6mmjkdmeTlsX/9vmdmhBmKADrWqN7zcdtHIeNSCH1SqIoNI63cYsjQR8J+wGa4Y5izRcSHSm8K3QWmk3w==} engines: {node: '>=18'} cpu: [mips64el] os: [linux] @@ -1422,8 +1514,14 @@ packages: cpu: [ppc64] os: [linux] - '@esbuild/linux-ppc64@0.27.4': - resolution: {integrity: sha512-tLCwNG47l3sd9lpfyx9LAGEGItCUeRCWeAx6x2Jmbav65nAwoPXfewtAdtbtit/pJFLUWOhpv0FpS6GQAmPrHA==} + '@esbuild/linux-ppc64@0.27.5': + resolution: {integrity: sha512-0V2iF1RGxBf1b7/BjurA5jfkl7PtySjom1r6xOK2q9KWw/XCpAdtB6KNMO+9xx69yYfSCRR9FE0TyKfHA2eQMw==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-ppc64@0.28.0': + resolution: {integrity: sha512-bc0FE9wWeC0WBm49IQMPSPILRocGTQt3j5KPCA8os6VprfuJ7KD+5PzESSrJ6GmPIPJK965ZJHTUlSA6GNYEhg==} engines: {node: '>=18'} cpu: [ppc64] os: [linux] @@ -1434,8 +1532,14 @@ packages: cpu: [riscv64] os: [linux] - '@esbuild/linux-riscv64@0.27.4': - resolution: {integrity: sha512-BnASypppbUWyqjd1KIpU4AUBiIhVr6YlHx/cnPgqEkNoVOhHg+YiSVxM1RLfiy4t9cAulbRGTNCKOcqHrEQLIw==} + '@esbuild/linux-riscv64@0.27.5': + resolution: {integrity: sha512-rYxThBx6G9HN6tFNuvB/vykeLi4VDsm5hE5pVwzqbAjZEARQrWu3noZSfbEnPZ/CRXP3271GyFk/49up2W190g==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-riscv64@0.28.0': + resolution: {integrity: sha512-SQPZOwoTTT/HXFXQJG/vBX8sOFagGqvZyXcgLA3NhIqcBv1BJU1d46c0rGcrij2B56Z2rNiSLaZOYW5cUk7yLQ==} engines: {node: '>=18'} cpu: [riscv64] os: [linux] @@ -1446,8 +1550,14 @@ packages: cpu: [s390x] os: [linux] - '@esbuild/linux-s390x@0.27.4': - resolution: {integrity: sha512-+eUqgb/Z7vxVLezG8bVB9SfBie89gMueS+I0xYh2tJdw3vqA/0ImZJ2ROeWwVJN59ihBeZ7Tu92dF/5dy5FttA==} + '@esbuild/linux-s390x@0.27.5': + resolution: {integrity: sha512-uEP2q/4qgd8goEUc4QIdU/1P2NmEtZ/zX5u3OpLlCGhJIuBIv0s0wr7TB2nBrd3/A5XIdEkkS5ZLF0ULuvaaYQ==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-s390x@0.28.0': + resolution: {integrity: sha512-SCfR0HN8CEEjnYnySJTd2cw0k9OHB/YFzt5zgJEwa+wL/T/raGWYMBqwDNAC6dqFKmJYZoQBRfHjgwLHGSrn3Q==} engines: {node: '>=18'} cpu: [s390x] os: [linux] @@ -1458,8 +1568,14 @@ packages: cpu: [x64] os: [linux] - '@esbuild/linux-x64@0.27.4': - resolution: {integrity: sha512-S5qOXrKV8BQEzJPVxAwnryi2+Iq5pB40gTEIT69BQONqR7JH1EPIcQ/Uiv9mCnn05jff9umq/5nqzxlqTOg9NA==} + '@esbuild/linux-x64@0.27.5': + resolution: {integrity: sha512-+Gq47Wqq6PLOOZuBzVSII2//9yyHNKZLuwfzCemqexqOQCSz0zy0O26kIzyp9EMNMK+nZ0tFHBZrCeVUuMs/ew==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/linux-x64@0.28.0': + resolution: {integrity: sha512-us0dSb9iFxIi8srnpl931Nvs65it/Jd2a2K3qs7fz2WfGPHqzfzZTfec7oxZJRNPXPnNYZtanmRc4AL/JwVzHQ==} engines: {node: '>=18'} cpu: [x64] os: [linux] @@ -1470,8 +1586,14 @@ packages: cpu: [arm64] os: [netbsd] - '@esbuild/netbsd-arm64@0.27.4': - resolution: {integrity: sha512-xHT8X4sb0GS8qTqiwzHqpY00C95DPAq7nAwX35Ie/s+LO9830hrMd3oX0ZMKLvy7vsonee73x0lmcdOVXFzd6Q==} + '@esbuild/netbsd-arm64@0.27.5': + resolution: {integrity: sha512-3F/5EG8VHfN/I+W5cO1/SV2H9Q/5r7vcHabMnBqhHK2lTWOh3F8vixNzo8lqxrlmBtZVFpW8pmITHnq54+Tq4g==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + + '@esbuild/netbsd-arm64@0.28.0': + resolution: {integrity: sha512-CR/RYotgtCKwtftMwJlUU7xCVNg3lMYZ0RzTmAHSfLCXw3NtZtNpswLEj/Kkf6kEL3Gw+BpOekRX0BYCtklhUw==} engines: {node: '>=18'} cpu: [arm64] os: [netbsd] @@ -1482,8 +1604,14 @@ packages: cpu: [x64] os: [netbsd] - '@esbuild/netbsd-x64@0.27.4': - resolution: {integrity: sha512-RugOvOdXfdyi5Tyv40kgQnI0byv66BFgAqjdgtAKqHoZTbTF2QqfQrFwa7cHEORJf6X2ht+l9ABLMP0dnKYsgg==} + '@esbuild/netbsd-x64@0.27.5': + resolution: {integrity: sha512-28t+Sj3CPN8vkMOlZotOmDgilQwVvxWZl7b8rxpn73Tt/gCnvrHxQUMng4uu3itdFvrtba/1nHejvxqz8xgEMA==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.28.0': + resolution: {integrity: sha512-nU1yhmYutL+fQ71Kxnhg8uEOdC0pwEW9entHykTgEbna2pw2dkbFSMeqjjyHZoCmt8SBkOSvV+yNmm94aUrrqw==} engines: {node: '>=18'} cpu: [x64] os: [netbsd] @@ -1494,8 +1622,14 @@ packages: cpu: [arm64] os: [openbsd] - '@esbuild/openbsd-arm64@0.27.4': - resolution: {integrity: sha512-2MyL3IAaTX+1/qP0O1SwskwcwCoOI4kV2IBX1xYnDDqthmq5ArrW94qSIKCAuRraMgPOmG0RDTA74mzYNQA9ow==} + '@esbuild/openbsd-arm64@0.27.5': + resolution: {integrity: sha512-Doz/hKtiuVAi9hMsBMpwBANhIZc8l238U2Onko3t2xUp8xtM0ZKdDYHMnm/qPFVthY8KtxkXaocwmMh6VolzMA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-arm64@0.28.0': + resolution: {integrity: sha512-cXb5vApOsRsxsEl4mcZ1XY3D4DzcoMxR/nnc4IyqYs0rTI8ZKmW6kyyg+11Z8yvgMfAEldKzP7AdP64HnSC/6g==} engines: {node: '>=18'} cpu: [arm64] os: [openbsd] @@ -1506,8 +1640,14 @@ packages: cpu: [x64] os: [openbsd] - '@esbuild/openbsd-x64@0.27.4': - resolution: {integrity: sha512-u8fg/jQ5aQDfsnIV6+KwLOf1CmJnfu1ShpwqdwC0uA7ZPwFws55Ngc12vBdeUdnuWoQYx/SOQLGDcdlfXhYmXQ==} + '@esbuild/openbsd-x64@0.27.5': + resolution: {integrity: sha512-WfGVaa1oz5A7+ZFPkERIbIhKT4olvGl1tyzTRaB5yoZRLqC0KwaO95FeZtOdQj/oKkjW57KcVF944m62/0GYtA==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.28.0': + resolution: {integrity: sha512-8wZM2qqtv9UP3mzy7HiGYNH/zjTA355mpeuA+859TyR+e+Tc08IHYpLJuMsfpDJwoLo1ikIJI8jC3GFjnRClzA==} engines: {node: '>=18'} cpu: [x64] os: [openbsd] @@ -1518,8 +1658,14 @@ packages: cpu: [arm64] os: [openharmony] - '@esbuild/openharmony-arm64@0.27.4': - resolution: {integrity: sha512-JkTZrl6VbyO8lDQO3yv26nNr2RM2yZzNrNHEsj9bm6dOwwu9OYN28CjzZkH57bh4w0I2F7IodpQvUAEd1mbWXg==} + '@esbuild/openharmony-arm64@0.27.5': + resolution: {integrity: sha512-Xh+VRuh6OMh3uJ0JkCjI57l+DVe7VRGBYymen8rFPnTVgATBwA6nmToxM2OwTlSvrnWpPKkrQUj93+K9huYC6A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + + '@esbuild/openharmony-arm64@0.28.0': + resolution: {integrity: sha512-FLGfyizszcef5C3YtoyQDACyg95+dndv79i2EekILBofh5wpCa1KuBqOWKrEHZg3zrL3t5ouE5jgr94vA+Wb2w==} engines: {node: '>=18'} cpu: [arm64] os: [openharmony] @@ -1530,8 +1676,14 @@ packages: cpu: [x64] os: [sunos] - '@esbuild/sunos-x64@0.27.4': - resolution: {integrity: sha512-/gOzgaewZJfeJTlsWhvUEmUG4tWEY2Spp5M20INYRg2ZKl9QPO3QEEgPeRtLjEWSW8FilRNacPOg8R1uaYkA6g==} + '@esbuild/sunos-x64@0.27.5': + resolution: {integrity: sha512-aC1gpJkkaUADHuAdQfuVTnqVUTLqqUNhAvEwHwVWcnVVZvNlDPGA0UveZsfXJJ9T6k9Po4eHi3c02gbdwO3g6w==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/sunos-x64@0.28.0': + resolution: {integrity: sha512-1ZgjUoEdHZZl/YlV76TSCz9Hqj9h9YmMGAgAPYd+q4SicWNX3G5GCyx9uhQWSLcbvPW8Ni7lj4gDa1T40akdlw==} engines: {node: '>=18'} cpu: [x64] os: [sunos] @@ -1542,8 +1694,14 @@ packages: cpu: [arm64] os: [win32] - '@esbuild/win32-arm64@0.27.4': - resolution: {integrity: sha512-Z9SExBg2y32smoDQdf1HRwHRt6vAHLXcxD2uGgO/v2jK7Y718Ix4ndsbNMU/+1Qiem9OiOdaqitioZwxivhXYg==} + '@esbuild/win32-arm64@0.27.5': + resolution: {integrity: sha512-0UNx2aavV0fk6UpZcwXFLztA2r/k9jTUa7OW7SAea1VYUhkug99MW1uZeXEnPn5+cHOd0n8myQay6TlFnBR07w==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-arm64@0.28.0': + resolution: {integrity: sha512-Q9StnDmQ/enxnpxCCLSg0oo4+34B9TdXpuyPeTedN/6+iXBJ4J+zwfQI28u/Jl40nOYAxGoNi7mFP40RUtkmUA==} engines: {node: '>=18'} cpu: [arm64] os: [win32] @@ -1554,8 +1712,14 @@ packages: cpu: [ia32] os: [win32] - '@esbuild/win32-ia32@0.27.4': - resolution: {integrity: sha512-DAyGLS0Jz5G5iixEbMHi5KdiApqHBWMGzTtMiJ72ZOLhbu/bzxgAe8Ue8CTS3n3HbIUHQz/L51yMdGMeoxXNJw==} + '@esbuild/win32-ia32@0.27.5': + resolution: {integrity: sha512-5nlJ3AeJWCTSzR7AEqVjT/faWyqKU86kCi1lLmxVqmNR+j4HrYdns+eTGjS/vmrzCIe8inGQckUadvS0+JkKdQ==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-ia32@0.28.0': + resolution: {integrity: sha512-zF3ag/gfiCe6U2iczcRzSYJKH1DCI+ByzSENHlM2FcDbEeo5Zd2C86Aq0tKUYAJJ1obRP84ymxIAksZUcdztHA==} engines: {node: '>=18'} cpu: [ia32] os: [win32] @@ -1566,17 +1730,17 @@ packages: cpu: [x64] os: [win32] - '@esbuild/win32-x64@0.27.4': - resolution: {integrity: sha512-+knoa0BDoeXgkNvvV1vvbZX4+hizelrkwmGJBdT17t8FNPwG2lKemmuMZlmaNQ3ws3DKKCxpb4zRZEIp3UxFCg==} + '@esbuild/win32-x64@0.27.5': + resolution: {integrity: sha512-PWypQR+d4FLfkhBIV+/kHsUELAnMpx1bRvvsn3p+/sAERbnCzFrtDRG2Xw5n+2zPxBK2+iaP+vetsRl4Ti7WgA==} engines: {node: '>=18'} cpu: [x64] os: [win32] - '@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 + '@esbuild/win32-x64@0.28.0': + resolution: {integrity: sha512-pEl1bO9mfAmIC+tW5btTmrKaujg3zGtUmWNdCw/xs70FBjwAL3o9OEKNHvNmnyylD6ubxUERiEhdsL0xBQ9efw==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] '@eslint-community/eslint-utils@4.9.1': resolution: {integrity: sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==} @@ -1758,18 +1922,10 @@ packages: resolution: {integrity: sha512-nBq6Y1tVkjIUsLsdOjDSJj4AsjvD0UG3zsg9Fyc+OivwlA/oMHSKooUy9tpKj0HqZ+NWFifweHavdljlBLTwdA==} engines: {node: '>= 16'} - '@intlify/message-compiler@11.2.2': - resolution: {integrity: sha512-XS2p8Ff5JxWsKhgfld4/MRQzZRQ85drMMPhb7Co6Be4ZOgqJX1DzcZt0IFgGTycgqL8rkYNwgnD443Q+TapOoA==} - engines: {node: '>= 16'} - '@intlify/message-compiler@11.2.8': resolution: {integrity: sha512-A5n33doOjmHsBtCN421386cG1tWp5rpOjOYPNsnpjIJbQ4POF0QY2ezhZR9kr0boKwaHjbOifvyQvHj2UTrDFQ==} engines: {node: '>= 16'} - '@intlify/shared@11.2.2': - resolution: {integrity: sha512-OtCmyFpSXxNu/oET/aN6HtPCbZ01btXVd0f3w00YsHOb13Kverk1jzA2k47pAekM55qbUw421fvPF1yxZ+gicw==} - engines: {node: '>= 16'} - '@intlify/shared@11.2.8': resolution: {integrity: sha512-l6e4NZyUgv8VyXXH4DbuucFOBmxLF56C/mqh2tvApbzl2Hrhi1aTDcuv5TKdxzfHYmpO3UB0Cz04fgDT9vszfw==} engines: {node: '>= 16'} @@ -1877,6 +2033,24 @@ packages: '@one-ini/wasm@0.1.1': resolution: {integrity: sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw==} + '@otplib/core@12.0.1': + resolution: {integrity: sha512-4sGntwbA/AC+SbPhbsziRiD+jNDdIzsZ3JUyfZwjtKyc/wufl1pnSIaG4Uqx8ymPagujub0o92kgBnB89cuAMA==} + + '@otplib/plugin-crypto@12.0.1': + resolution: {integrity: sha512-qPuhN3QrT7ZZLcLCyKOSNhuijUi9G5guMRVrxq63r9YNOxxQjPm59gVxLM+7xGnHnM6cimY57tuKsjK7y9LM1g==} + deprecated: Please upgrade to v13 of otplib. Refer to otplib docs for migration paths + + '@otplib/plugin-thirty-two@12.0.1': + resolution: {integrity: sha512-MtT+uqRso909UkbrrYpJ6XFjj9D+x2Py7KjTO9JDPhL0bJUYVu5kFP4TFZW4NFAywrAtFRxOVY261u0qwb93gA==} + deprecated: Please upgrade to v13 of otplib. Refer to otplib docs for migration paths + + '@otplib/preset-default@12.0.1': + resolution: {integrity: sha512-xf1v9oOJRyXfluBhMdpOkr+bsE+Irt+0D5uHtvg6x1eosfmHCsCC6ej/m7FXiWqdo0+ZUI6xSKDhJwc8yfiOPQ==} + deprecated: Please upgrade to v13 of otplib. Refer to otplib docs for migration paths + + '@otplib/preset-v11@12.0.1': + resolution: {integrity: sha512-9hSetMI7ECqbFiKICrNa4w70deTUfArtwXykPUvSHWOdzOlfa9ajglu7mNCntlvxycTiOAXkQGwjQCzzDEMRMg==} + '@parcel/watcher-android-arm64@2.5.1': resolution: {integrity: sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA==} engines: {node: '>= 10.0.0'} @@ -2009,8 +2183,8 @@ packages: '@remusao/trie@1.5.0': resolution: {integrity: sha512-UX+3utJKgwCsg6sUozjxd38gNMVRXrY4TNX9VvCdSrlZBS1nZjRPi98ON3QjRAdf6KCguJFyQARRsulTeqQiPg==} - '@rolldown/pluginutils@1.0.0-rc.2': - resolution: {integrity: sha512-izyXV/v+cHiRfozX62W9htOAvwMo4/bXKDrQ+vom1L1qRuexPock/7VZDAhnpHCLNejd3NJ6hiab+tO0D44Rgw==} + '@rolldown/pluginutils@1.0.0-rc.13': + resolution: {integrity: sha512-3ngTAv6F/Py35BsYbeeLeecvhMKdsKm4AoOETVhAA+Qc8nrA2I0kF7oa93mE9qnIurngOSpMnQ0x2nQY2FPviA==} '@rollup/plugin-babel@5.3.1': resolution: {integrity: sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q==} @@ -2018,7 +2192,7 @@ packages: peerDependencies: '@babel/core': ^7.0.0 '@types/babel__core': ^7.1.9 - rollup: 4.60.0 + rollup: 4.60.2 peerDependenciesMeta: '@types/babel__core': optional: true @@ -2027,7 +2201,7 @@ packages: resolution: {integrity: sha512-j/lym8nf5E21LwBT4Df1VD6hRO2L2iwUeUmP7litikRsVp1H6NWx20NEp0Y7su+7XGc476GnXXc4kFeZNGmaSQ==} engines: {node: '>=14.0.0'} peerDependencies: - rollup: 4.60.0 + rollup: 4.60.2 peerDependenciesMeta: rollup: optional: true @@ -2035,13 +2209,13 @@ packages: '@rollup/plugin-replace@2.4.2': resolution: {integrity: sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg==} peerDependencies: - rollup: 4.60.0 + rollup: 4.60.2 '@rollup/plugin-terser@0.4.4': resolution: {integrity: sha512-XHeJC5Bgvs8LfukDwWZp7yeqin6ns8RTl2B9avbejt6tZqsqvVoWI7ZTQrcNsfKEDWBTnTxM8nMDkO2IFFbd0A==} engines: {node: '>=14.0.0'} peerDependencies: - rollup: 4.60.0 + rollup: 4.60.2 peerDependenciesMeta: rollup: optional: true @@ -2050,139 +2224,139 @@ packages: resolution: {integrity: sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==} engines: {node: '>= 8.0.0'} peerDependencies: - rollup: 4.60.0 + rollup: 4.60.2 '@rollup/pluginutils@5.1.3': resolution: {integrity: sha512-Pnsb6f32CD2W3uCaLZIzDmeFyQ2b8UWMFI7xtwUezpcGBDVDW6y9XgAWIlARiGAo6eNF5FK5aQTr0LFyNyqq5A==} engines: {node: '>=14.0.0'} peerDependencies: - rollup: 4.60.0 + rollup: 4.60.2 peerDependenciesMeta: rollup: optional: true - '@rollup/rollup-android-arm-eabi@4.60.0': - resolution: {integrity: sha512-WOhNW9K8bR3kf4zLxbfg6Pxu2ybOUbB2AjMDHSQx86LIF4rH4Ft7vmMwNt0loO0eonglSNy4cpD3MKXXKQu0/A==} + '@rollup/rollup-android-arm-eabi@4.60.2': + resolution: {integrity: sha512-dnlp69efPPg6Uaw2dVqzWRfAWRnYVb1XJ8CyyhIbZeaq4CA5/mLeZ1IEt9QqQxmbdvagjLIm2ZL8BxXv5lH4Yw==} cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.60.0': - resolution: {integrity: sha512-u6JHLll5QKRvjciE78bQXDmqRqNs5M/3GVqZeMwvmjaNODJih/WIrJlFVEihvV0MiYFmd+ZyPr9wxOVbPAG2Iw==} + '@rollup/rollup-android-arm64@4.60.2': + resolution: {integrity: sha512-OqZTwDRDchGRHHm/hwLOL7uVPB9aUvI0am/eQuWMNyFHf5PSEQmyEeYYheA0EPPKUO/l0uigCp+iaTjoLjVoHg==} cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.60.0': - resolution: {integrity: sha512-qEF7CsKKzSRc20Ciu2Zw1wRrBz4g56F7r/vRwY430UPp/nt1x21Q/fpJ9N5l47WWvJlkNCPJz3QRVw008fi7yA==} + '@rollup/rollup-darwin-arm64@4.60.2': + resolution: {integrity: sha512-UwRE7CGpvSVEQS8gUMBe1uADWjNnVgP3Iusyda1nSRwNDCsRjnGc7w6El6WLQsXmZTbLZx9cecegumcitNfpmA==} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.60.0': - resolution: {integrity: sha512-WADYozJ4QCnXCH4wPB+3FuGmDPoFseVCUrANmA5LWwGmC6FL14BWC7pcq+FstOZv3baGX65tZ378uT6WG8ynTw==} + '@rollup/rollup-darwin-x64@4.60.2': + resolution: {integrity: sha512-gjEtURKLCC5VXm1I+2i1u9OhxFsKAQJKTVB8WvDAHF+oZlq0GTVFOlTlO1q3AlCTE/DF32c16ESvfgqR7343/g==} cpu: [x64] os: [darwin] - '@rollup/rollup-freebsd-arm64@4.60.0': - resolution: {integrity: sha512-6b8wGHJlDrGeSE3aH5mGNHBjA0TTkxdoNHik5EkvPHCt351XnigA4pS7Wsj/Eo9Y8RBU6f35cjN9SYmCFBtzxw==} + '@rollup/rollup-freebsd-arm64@4.60.2': + resolution: {integrity: sha512-Bcl6CYDeAgE70cqZaMojOi/eK63h5Me97ZqAQoh77VPjMysA/4ORQBRGo3rRy45x4MzVlU9uZxs8Uwy7ZaKnBw==} cpu: [arm64] os: [freebsd] - '@rollup/rollup-freebsd-x64@4.60.0': - resolution: {integrity: sha512-h25Ga0t4jaylMB8M/JKAyrvvfxGRjnPQIR8lnCayyzEjEOx2EJIlIiMbhpWxDRKGKF8jbNH01NnN663dH638mA==} + '@rollup/rollup-freebsd-x64@4.60.2': + resolution: {integrity: sha512-LU+TPda3mAE2QB0/Hp5VyeKJivpC6+tlOXd1VMoXV/YFMvk/MNk5iXeBfB4MQGRWyOYVJ01625vjkr0Az98OJQ==} cpu: [x64] os: [freebsd] - '@rollup/rollup-linux-arm-gnueabihf@4.60.0': - resolution: {integrity: sha512-RzeBwv0B3qtVBWtcuABtSuCzToo2IEAIQrcyB/b2zMvBWVbjo8bZDjACUpnaafaxhTw2W+imQbP2BD1usasK4g==} + '@rollup/rollup-linux-arm-gnueabihf@4.60.2': + resolution: {integrity: sha512-2QxQrM+KQ7DAW4o22j+XZ6RKdxjLD7BOWTP0Bv0tmjdyhXSsr2Ul1oJDQqh9Zf5qOwTuTc7Ek83mOFaKnodPjg==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm-musleabihf@4.60.0': - resolution: {integrity: sha512-Sf7zusNI2CIU1HLzuu9Tc5YGAHEZs5Lu7N1ssJG4Tkw6e0MEsN7NdjUDDfGNHy2IU+ENyWT+L2obgWiguWibWQ==} + '@rollup/rollup-linux-arm-musleabihf@4.60.2': + resolution: {integrity: sha512-TbziEu2DVsTEOPif2mKWkMeDMLoYjx95oESa9fkQQK7r/Orta0gnkcDpzwufEcAO2BLBsD7mZkXGFqEdMRRwfw==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm64-gnu@4.60.0': - resolution: {integrity: sha512-DX2x7CMcrJzsE91q7/O02IJQ5/aLkVtYFryqCjduJhUfGKG6yJV8hxaw8pZa93lLEpPTP/ohdN4wFz7yp/ry9A==} + '@rollup/rollup-linux-arm64-gnu@4.60.2': + resolution: {integrity: sha512-bO/rVDiDUuM2YfuCUwZ1t1cP+/yqjqz+Xf2VtkdppefuOFS2OSeAfgafaHNkFn0t02hEyXngZkxtGqXcXwO8Rg==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-arm64-musl@4.60.0': - resolution: {integrity: sha512-09EL+yFVbJZlhcQfShpswwRZ0Rg+z/CsSELFCnPt3iK+iqwGsI4zht3secj5vLEs957QvFFXnzAT0FFPIxSrkQ==} + '@rollup/rollup-linux-arm64-musl@4.60.2': + resolution: {integrity: sha512-hr26p7e93Rl0Za+JwW7EAnwAvKkehh12BU1Llm9Ykiibg4uIr2rbpxG9WCf56GuvidlTG9KiiQT/TXT1yAWxTA==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-loong64-gnu@4.60.0': - resolution: {integrity: sha512-i9IcCMPr3EXm8EQg5jnja0Zyc1iFxJjZWlb4wr7U2Wx/GrddOuEafxRdMPRYVaXjgbhvqalp6np07hN1w9kAKw==} + '@rollup/rollup-linux-loong64-gnu@4.60.2': + resolution: {integrity: sha512-pOjB/uSIyDt+ow3k/RcLvUAOGpysT2phDn7TTUB3n75SlIgZzM6NKAqlErPhoFU+npgY3/n+2HYIQVbF70P9/A==} cpu: [loong64] os: [linux] - '@rollup/rollup-linux-loong64-musl@4.60.0': - resolution: {integrity: sha512-DGzdJK9kyJ+B78MCkWeGnpXJ91tK/iKA6HwHxF4TAlPIY7GXEvMe8hBFRgdrR9Ly4qebR/7gfUs9y2IoaVEyog==} + '@rollup/rollup-linux-loong64-musl@4.60.2': + resolution: {integrity: sha512-2/w+q8jszv9Ww1c+6uJT3OwqhdmGP2/4T17cu8WuwyUuuaCDDJ2ojdyYwZzCxx0GcsZBhzi3HmH+J5pZNXnd+Q==} cpu: [loong64] os: [linux] - '@rollup/rollup-linux-ppc64-gnu@4.60.0': - resolution: {integrity: sha512-RwpnLsqC8qbS8z1H1AxBA1H6qknR4YpPR9w2XX0vo2Sz10miu57PkNcnHVaZkbqyw/kUWfKMI73jhmfi9BRMUQ==} + '@rollup/rollup-linux-ppc64-gnu@4.60.2': + resolution: {integrity: sha512-11+aL5vKheYgczxtPVVRhdptAM2H7fcDR5Gw4/bTcteuZBlH4oP9f5s9zYO9aGZvoGeBpqXI/9TZZihZ609wKw==} cpu: [ppc64] os: [linux] - '@rollup/rollup-linux-ppc64-musl@4.60.0': - resolution: {integrity: sha512-Z8pPf54Ly3aqtdWC3G4rFigZgNvd+qJlOE52fmko3KST9SoGfAdSRCwyoyG05q1HrrAblLbk1/PSIV+80/pxLg==} + '@rollup/rollup-linux-ppc64-musl@4.60.2': + resolution: {integrity: sha512-i16fokAGK46IVZuV8LIIwMdtqhin9hfYkCh8pf8iC3QU3LpwL+1FSFGej+O7l3E/AoknL6Dclh2oTdnRMpTzFQ==} cpu: [ppc64] os: [linux] - '@rollup/rollup-linux-riscv64-gnu@4.60.0': - resolution: {integrity: sha512-3a3qQustp3COCGvnP4SvrMHnPQ9d1vzCakQVRTliaz8cIp/wULGjiGpbcqrkv0WrHTEp8bQD/B3HBjzujVWLOA==} + '@rollup/rollup-linux-riscv64-gnu@4.60.2': + resolution: {integrity: sha512-49FkKS6RGQoriDSK/6E2GkAsAuU5kETFCh7pG4yD/ylj9rKhTmO3elsnmBvRD4PgJPds5W2PkhC82aVwmUcJ7A==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-riscv64-musl@4.60.0': - resolution: {integrity: sha512-pjZDsVH/1VsghMJ2/kAaxt6dL0psT6ZexQVrijczOf+PeP2BUqTHYejk3l6TlPRydggINOeNRhvpLa0AYpCWSQ==} + '@rollup/rollup-linux-riscv64-musl@4.60.2': + resolution: {integrity: sha512-mjYNkHPfGpUR00DuM1ZZIgs64Hpf4bWcz9Z41+4Q+pgDx73UwWdAYyf6EG/lRFldmdHHzgrYyge5akFUW0D3mQ==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-s390x-gnu@4.60.0': - resolution: {integrity: sha512-3ObQs0BhvPgiUVZrN7gqCSvmFuMWvWvsjG5ayJ3Lraqv+2KhOsp+pUbigqbeWqueGIsnn+09HBw27rJ+gYK4VQ==} + '@rollup/rollup-linux-s390x-gnu@4.60.2': + resolution: {integrity: sha512-ALyvJz965BQk8E9Al/JDKKDLH2kfKFLTGMlgkAbbYtZuJt9LU8DW3ZoDMCtQpXAltZxwBHevXz5u+gf0yA0YoA==} cpu: [s390x] os: [linux] - '@rollup/rollup-linux-x64-gnu@4.60.0': - resolution: {integrity: sha512-EtylprDtQPdS5rXvAayrNDYoJhIz1/vzN2fEubo3yLE7tfAw+948dO0g4M0vkTVFhKojnF+n6C8bDNe+gDRdTg==} + '@rollup/rollup-linux-x64-gnu@4.60.2': + resolution: {integrity: sha512-UQjrkIdWrKI626Du8lCQ6MJp/6V1LAo2bOK9OTu4mSn8GGXIkPXk/Vsp4bLHCd9Z9Iz2OTEaokUE90VweJgIYQ==} cpu: [x64] os: [linux] - '@rollup/rollup-linux-x64-musl@4.60.0': - resolution: {integrity: sha512-k09oiRCi/bHU9UVFqD17r3eJR9bn03TyKraCrlz5ULFJGdJGi7VOmm9jl44vOJvRJ6P7WuBi/s2A97LxxHGIdw==} + '@rollup/rollup-linux-x64-musl@4.60.2': + resolution: {integrity: sha512-bTsRGj6VlSdn/XD4CGyzMnzaBs9bsRxy79eTqTCBsA8TMIEky7qg48aPkvJvFe1HyzQ5oMZdg7AnVlWQSKLTnw==} cpu: [x64] os: [linux] - '@rollup/rollup-openbsd-x64@4.60.0': - resolution: {integrity: sha512-1o/0/pIhozoSaDJoDcec+IVLbnRtQmHwPV730+AOD29lHEEo4F5BEUB24H0OBdhbBBDwIOSuf7vgg0Ywxdfiiw==} + '@rollup/rollup-openbsd-x64@4.60.2': + resolution: {integrity: sha512-6d4Z3534xitaA1FcMWP7mQPq5zGwBmGbhphh2DwaA1aNIXUu3KTOfwrWpbwI4/Gr0uANo7NTtaykFyO2hPuFLg==} cpu: [x64] os: [openbsd] - '@rollup/rollup-openharmony-arm64@4.60.0': - resolution: {integrity: sha512-pESDkos/PDzYwtyzB5p/UoNU/8fJo68vcXM9ZW2V0kjYayj1KaaUfi1NmTUTUpMn4UhU4gTuK8gIaFO4UGuMbA==} + '@rollup/rollup-openharmony-arm64@4.60.2': + resolution: {integrity: sha512-NetAg5iO2uN7eB8zE5qrZ3CSil+7IJt4WDFLcC75Ymywq1VZVD6qJ6EvNLjZ3rEm6gB7XW5JdT60c6MN35Z85Q==} cpu: [arm64] os: [openharmony] - '@rollup/rollup-win32-arm64-msvc@4.60.0': - resolution: {integrity: sha512-hj1wFStD7B1YBeYmvY+lWXZ7ey73YGPcViMShYikqKT1GtstIKQAtfUI6yrzPjAy/O7pO0VLXGmUVWXQMaYgTQ==} + '@rollup/rollup-win32-arm64-msvc@4.60.2': + resolution: {integrity: sha512-NCYhOotpgWZ5kdxCZsv6Iudx0wX8980Q/oW4pNFNihpBKsDbEA1zpkfxJGC0yugsUuyDZ7gL37dbzwhR0VI7pQ==} cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.60.0': - resolution: {integrity: sha512-SyaIPFoxmUPlNDq5EHkTbiKzmSEmq/gOYFI/3HHJ8iS/v1mbugVa7dXUzcJGQfoytp9DJFLhHH4U3/eTy2Bq4w==} + '@rollup/rollup-win32-ia32-msvc@4.60.2': + resolution: {integrity: sha512-RXsaOqXxfoUBQoOgvmmijVxJnW2IGB0eoMO7F8FAjaj0UTywUO/luSqimWBJn04WNgUkeNhh7fs7pESXajWmkg==} cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-gnu@4.60.0': - resolution: {integrity: sha512-RdcryEfzZr+lAr5kRm2ucN9aVlCCa2QNq4hXelZxb8GG0NJSazq44Z3PCCc8wISRuCVnGs0lQJVX5Vp6fKA+IA==} + '@rollup/rollup-win32-x64-gnu@4.60.2': + resolution: {integrity: sha512-qdAzEULD+/hzObedtmV6iBpdL5TIbKVztGiK7O3/KYSf+HIzU257+MX1EXJcyIiDbMAqmbwaufcYPvyRryeZtA==} cpu: [x64] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.60.0': - resolution: {integrity: sha512-PrsWNQ8BuE00O3Xsx3ALh2Df8fAj9+cvvX9AIA6o4KpATR98c9mud4XtDWVvsEuyia5U4tVSTKygawyJkjm60w==} + '@rollup/rollup-win32-x64-msvc@4.60.2': + resolution: {integrity: sha512-Nd/SgG27WoA9e+/TdK74KnHz852TLa94ovOYySo/yMPuTmpckK/jIF2jSwS3g7ELSKXK13/cVdmg1Z/DaCWKxA==} cpu: [x64] os: [win32] @@ -2316,74 +2490,71 @@ packages: resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==} engines: {node: '>=18'} - '@standard-schema/spec@1.0.0': - resolution: {integrity: sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==} - '@standard-schema/spec@1.1.0': resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} '@surma/rollup-plugin-off-main-thread@2.2.3': resolution: {integrity: sha512-lR8q/9W7hZpMWweNiAKU7NQerBnzQQLvi8qnTDU/fxItPhtZVMbPV3lbCwjhIlNBe9Bbr5V+KHshvWmVSG9cxQ==} - '@tailwindcss/node@4.2.2': - resolution: {integrity: sha512-pXS+wJ2gZpVXqFaUEjojq7jzMpTGf8rU6ipJz5ovJV6PUGmlJ+jvIwGrzdHdQ80Sg+wmQxUFuoW1UAAwHNEdFA==} + '@tailwindcss/node@4.2.4': + resolution: {integrity: sha512-Ai7+yQPxz3ddrDQzFfBKdHEVBg0w3Zl83jnjuwxnZOsnH9pGn93QHQtpU0p/8rYWxvbFZHneni6p1BSLK4DkGA==} - '@tailwindcss/oxide-android-arm64@4.2.2': - resolution: {integrity: sha512-dXGR1n+P3B6748jZO/SvHZq7qBOqqzQ+yFrXpoOWWALWndF9MoSKAT3Q0fYgAzYzGhxNYOoysRvYlpixRBBoDg==} + '@tailwindcss/oxide-android-arm64@4.2.4': + resolution: {integrity: sha512-e7MOr1SAn9U8KlZzPi1ZXGZHeC5anY36qjNwmZv9pOJ8E4Q6jmD1vyEHkQFmNOIN7twGPEMXRHmitN4zCMN03g==} engines: {node: '>= 20'} cpu: [arm64] os: [android] - '@tailwindcss/oxide-darwin-arm64@4.2.2': - resolution: {integrity: sha512-iq9Qjr6knfMpZHj55/37ouZeykwbDqF21gPFtfnhCCKGDcPI/21FKC9XdMO/XyBM7qKORx6UIhGgg6jLl7BZlg==} + '@tailwindcss/oxide-darwin-arm64@4.2.4': + resolution: {integrity: sha512-tSC/Kbqpz/5/o/C2sG7QvOxAKqyd10bq+ypZNf+9Fi2TvbVbv1zNpcEptcsU7DPROaSbVgUXmrzKhurFvo5eDg==} engines: {node: '>= 20'} cpu: [arm64] os: [darwin] - '@tailwindcss/oxide-darwin-x64@4.2.2': - resolution: {integrity: sha512-BlR+2c3nzc8f2G639LpL89YY4bdcIdUmiOOkv2GQv4/4M0vJlpXEa0JXNHhCHU7VWOKWT/CjqHdTP8aUuDJkuw==} + '@tailwindcss/oxide-darwin-x64@4.2.4': + resolution: {integrity: sha512-yPyUXn3yO/ufR6+Kzv0t4fCg2qNr90jxXc5QqBpjlPNd0NqyDXcmQb/6weunH/MEDXW5dhyEi+agTDiqa3WsGg==} engines: {node: '>= 20'} cpu: [x64] os: [darwin] - '@tailwindcss/oxide-freebsd-x64@4.2.2': - resolution: {integrity: sha512-YUqUgrGMSu2CDO82hzlQ5qSb5xmx3RUrke/QgnoEx7KvmRJHQuZHZmZTLSuuHwFf0DJPybFMXMYf+WJdxHy/nQ==} + '@tailwindcss/oxide-freebsd-x64@4.2.4': + resolution: {integrity: sha512-BoMIB4vMQtZsXdGLVc2z+P9DbETkiopogfWZKbWwM8b/1Vinbs4YcUwo+kM/KeLkX3Ygrf4/PsRndKaYhS8Eiw==} engines: {node: '>= 20'} cpu: [x64] os: [freebsd] - '@tailwindcss/oxide-linux-arm-gnueabihf@4.2.2': - resolution: {integrity: sha512-FPdhvsW6g06T9BWT0qTwiVZYE2WIFo2dY5aCSpjG/S/u1tby+wXoslXS0kl3/KXnULlLr1E3NPRRw0g7t2kgaQ==} + '@tailwindcss/oxide-linux-arm-gnueabihf@4.2.4': + resolution: {integrity: sha512-7pIHBLTHYRAlS7V22JNuTh33yLH4VElwKtB3bwchK/UaKUPpQ0lPQiOWcbm4V3WP2I6fNIJ23vABIvoy2izdwA==} engines: {node: '>= 20'} cpu: [arm] os: [linux] - '@tailwindcss/oxide-linux-arm64-gnu@4.2.2': - resolution: {integrity: sha512-4og1V+ftEPXGttOO7eCmW7VICmzzJWgMx+QXAJRAhjrSjumCwWqMfkDrNu1LXEQzNAwz28NCUpucgQPrR4S2yw==} + '@tailwindcss/oxide-linux-arm64-gnu@4.2.4': + resolution: {integrity: sha512-+E4wxJ0ZGOzSH325reXTWB48l42i93kQqMvDyz5gqfRzRZ7faNhnmvlV4EPGJU3QJM/3Ab5jhJ5pCRUsKn6OQw==} engines: {node: '>= 20'} cpu: [arm64] os: [linux] - '@tailwindcss/oxide-linux-arm64-musl@4.2.2': - resolution: {integrity: sha512-oCfG/mS+/+XRlwNjnsNLVwnMWYH7tn/kYPsNPh+JSOMlnt93mYNCKHYzylRhI51X+TbR+ufNhhKKzm6QkqX8ag==} + '@tailwindcss/oxide-linux-arm64-musl@4.2.4': + resolution: {integrity: sha512-bBADEGAbo4ASnppIziaQJelekCxdMaxisrk+fB7Thit72IBnALp9K6ffA2G4ruj90G9XRS2VQ6q2bCKbfFV82g==} engines: {node: '>= 20'} cpu: [arm64] os: [linux] - '@tailwindcss/oxide-linux-x64-gnu@4.2.2': - resolution: {integrity: sha512-rTAGAkDgqbXHNp/xW0iugLVmX62wOp2PoE39BTCGKjv3Iocf6AFbRP/wZT/kuCxC9QBh9Pu8XPkv/zCZB2mcMg==} + '@tailwindcss/oxide-linux-x64-gnu@4.2.4': + resolution: {integrity: sha512-7Mx25E4WTfnht0TVRTyC00j3i0M+EeFe7wguMDTlX4mRxafznw0CA8WJkFjWYH5BlgELd1kSjuU2JiPnNZbJDA==} engines: {node: '>= 20'} cpu: [x64] os: [linux] - '@tailwindcss/oxide-linux-x64-musl@4.2.2': - resolution: {integrity: sha512-XW3t3qwbIwiSyRCggeO2zxe3KWaEbM0/kW9e8+0XpBgyKU4ATYzcVSMKteZJ1iukJ3HgHBjbg9P5YPRCVUxlnQ==} + '@tailwindcss/oxide-linux-x64-musl@4.2.4': + resolution: {integrity: sha512-2wwJRF7nyhOR0hhHoChc04xngV3iS+akccHTGtz965FwF0up4b2lOdo6kI1EbDaEXKgvcrFBYcYQQ/rrnWFVfA==} engines: {node: '>= 20'} cpu: [x64] os: [linux] - '@tailwindcss/oxide-wasm32-wasi@4.2.2': - resolution: {integrity: sha512-eKSztKsmEsn1O5lJ4ZAfyn41NfG7vzCg496YiGtMDV86jz1q/irhms5O0VrY6ZwTUkFy/EKG3RfWgxSI3VbZ8Q==} + '@tailwindcss/oxide-wasm32-wasi@4.2.4': + resolution: {integrity: sha512-FQsqApeor8Fo6gUEklzmaa9994orJZZDBAlQpK2Mq+DslRKFJeD6AjHpBQ0kZFQohVr8o85PPh8eOy86VlSCmw==} engines: {node: '>=14.0.0'} cpu: [wasm32] bundledDependencies: @@ -2394,24 +2565,24 @@ packages: - '@emnapi/wasi-threads' - tslib - '@tailwindcss/oxide-win32-arm64-msvc@4.2.2': - resolution: {integrity: sha512-qPmaQM4iKu5mxpsrWZMOZRgZv1tOZpUm+zdhhQP0VhJfyGGO3aUKdbh3gDZc/dPLQwW4eSqWGrrcWNBZWUWaXQ==} + '@tailwindcss/oxide-win32-arm64-msvc@4.2.4': + resolution: {integrity: sha512-L9BXqxC4ToVgwMFqj3pmZRqyHEztulpUJzCxUtLjobMCzTPsGt1Fa9enKbOpY2iIyVtaHNeNvAK8ERP/64sqGQ==} engines: {node: '>= 20'} cpu: [arm64] os: [win32] - '@tailwindcss/oxide-win32-x64-msvc@4.2.2': - resolution: {integrity: sha512-1T/37VvI7WyH66b+vqHj/cLwnCxt7Qt3WFu5Q8hk65aOvlwAhs7rAp1VkulBJw/N4tMirXjVnylTR72uI0HGcA==} + '@tailwindcss/oxide-win32-x64-msvc@4.2.4': + resolution: {integrity: sha512-ESlKG0EpVJQwRjXDDa9rLvhEAh0mhP1sF7sap9dNZT0yyl9SAG6T7gdP09EH0vIv0UNTlo6jPWyujD6559fZvw==} engines: {node: '>= 20'} cpu: [x64] os: [win32] - '@tailwindcss/oxide@4.2.2': - resolution: {integrity: sha512-qEUA07+E5kehxYp9BVMpq9E8vnJuBHfJEC0vPC5e7iL/hw7HR61aDKoVoKzrG+QKp56vhNZe4qwkRmMC0zDLvg==} + '@tailwindcss/oxide@4.2.4': + resolution: {integrity: sha512-9El/iI069DKDSXwTvB9J4BwdO5JhRrOweGaK25taBAvBXyXqJAX+Jqdvs8r8gKpsI/1m0LeJLyQYTf/WLrBT1Q==} engines: {node: '>= 20'} - '@tailwindcss/vite@4.2.2': - resolution: {integrity: sha512-mEiF5HO1QqCLXoNEfXVA1Tzo+cYsrqV7w9Juj2wdUFyW07JRenqMG225MvPwr3ZD9N1bFQj46X7r33iHxLUW0w==} + '@tailwindcss/vite@4.2.4': + resolution: {integrity: sha512-pCvohwOCspk3ZFn6eJzrrX3g4n2JY73H6MmYC87XfGPyTty4YsCjYTMArRZm/zOI8dIt3+EcrLHAFPe5A4bgtw==} peerDependencies: vite: ^5.2.0 || ^6 || ^7 || ^8 @@ -2651,8 +2822,8 @@ packages: '@types/minimist@1.2.5': resolution: {integrity: sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==} - '@types/node@24.12.0': - resolution: {integrity: sha512-GYDxsZi3ChgmckRT9HPU0WEhKLP08ev/Yfcq2AstjrDASOYCSXeyjDsHg4v5t4jOj7cyDX3vmprafKlWIG9MXQ==} + '@types/node@24.12.2': + resolution: {integrity: sha512-A1sre26ke7HDIuY/M23nd9gfB+nrmhtYyMINbjI1zHJxYteKR6qSMX56FsmjMcDb3SMcjJg5BiRRgOCC/yBD0g==} '@types/normalize-package-data@2.4.4': resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} @@ -2692,13 +2863,13 @@ packages: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/eslint-plugin@8.57.2': - resolution: {integrity: sha512-NZZgp0Fm2IkD+La5PR81sd+g+8oS6JwJje+aRWsDocxHkjyRw0J5L5ZTlN3LI1LlOcGL7ph3eaIUmTXMIjLk0w==} + '@typescript-eslint/eslint-plugin@8.59.0': + resolution: {integrity: sha512-HyAZtpdkgZwpq8Sz3FSUvCR4c+ScbuWa9AksK2Jweub7w4M3yTz4O11AqVJzLYjy/B9ZWPyc81I+mOdJU/bDQw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - '@typescript-eslint/parser': ^8.57.2 + '@typescript-eslint/parser': ^8.59.0 eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 - typescript: '>=4.8.4 <6.0.0' + typescript: '>=4.8.4 <6.1.0' '@typescript-eslint/parser@8.56.0': resolution: {integrity: sha512-IgSWvLobTDOjnaxAfDTIHaECbkNlAlKv2j5SjpB2v7QHKv1FIfjwMy8FsDbVfDX/KjmCmYICcw7uGaXLhtsLNg==} @@ -2707,18 +2878,12 @@ packages: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/parser@8.57.2': - resolution: {integrity: sha512-30ScMRHIAD33JJQkgfGW1t8CURZtjc2JpTrq5n2HFhOefbAhb7ucc7xJwdWcrEtqUIYJ73Nybpsggii6GtAHjA==} + '@typescript-eslint/parser@8.59.0': + resolution: {integrity: sha512-TI1XGwKbDpo9tRW8UDIXCOeLk55qe9ZFGs8MTKU6/M08HWTw52DD/IYhfQtOEhEdPhLMT26Ka/x7p70nd3dzDg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 - typescript: '>=4.8.4 <6.0.0' - - '@typescript-eslint/project-service@8.49.0': - resolution: {integrity: sha512-/wJN0/DKkmRUMXjZUXYZpD1NEQzQAAn9QWfGwo+Ai8gnzqH7tvqS7oNVdTjKqOcPyVIdZdyCMoqN66Ia789e7g==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - typescript: '>=4.8.4 <6.0.0' + typescript: '>=4.8.4 <6.1.0' '@typescript-eslint/project-service@8.56.0': resolution: {integrity: sha512-M3rnyL1vIQOMeWxTWIW096/TtVP+8W3p/XnaFflhmcFp+U4zlxUxWj4XwNs6HbDeTtN4yun0GNTTDBw/SvufKg==} @@ -2726,29 +2891,29 @@ packages: peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/project-service@8.57.2': - resolution: {integrity: sha512-FuH0wipFywXRTHf+bTTjNyuNQQsQC3qh/dYzaM4I4W0jrCqjCVuUh99+xd9KamUfmCGPvbO8NDngo/vsnNVqgw==} + '@typescript-eslint/project-service@8.58.0': + resolution: {integrity: sha512-8Q/wBPWLQP1j16NxoPNIKpDZFMaxl7yWIoqXWYeWO+Bbd2mjgvoF0dxP2jKZg5+x49rgKdf7Ck473M8PC3V9lg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - typescript: '>=4.8.4 <6.0.0' + typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/scope-manager@8.49.0': - resolution: {integrity: sha512-npgS3zi+/30KSOkXNs0LQXtsg9ekZ8OISAOLGWA/ZOEn0ZH74Ginfl7foziV8DT+D98WfQ5Kopwqb/PZOaIJGg==} + '@typescript-eslint/project-service@8.59.0': + resolution: {integrity: sha512-Lw5ITrR5s5TbC19YSvlr63ZfLaJoU6vtKTHyB0GQOpX0W7d5/Ir6vUahWi/8Sps/nOukZQ0IB3SmlxZnjaKVnw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.1.0' '@typescript-eslint/scope-manager@8.56.0': resolution: {integrity: sha512-7UiO/XwMHquH+ZzfVCfUNkIXlp/yQjjnlYUyYz7pfvlK3/EyyN6BK+emDmGNyQLBtLGaYrTAI6KOw8tFucWL2w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/scope-manager@8.57.2': - resolution: {integrity: sha512-snZKH+W4WbWkrBqj4gUNRIGb/jipDW3qMqVJ4C9rzdFc+wLwruxk+2a5D+uoFcKPAqyqEnSb4l2ULuZf95eSkw==} + '@typescript-eslint/scope-manager@8.58.0': + resolution: {integrity: sha512-W1Lur1oF50FxSnNdGp3Vs6P+yBRSmZiw4IIjEeYxd8UQJwhUF0gDgDD/W/Tgmh73mxgEU3qX0Bzdl/NGuSPEpQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/tsconfig-utils@8.49.0': - resolution: {integrity: sha512-8prixNi1/6nawsRYxet4YOhnbW+W9FK/bQPxsGB1D3ZrDzbJ5FXw5XmzxZv82X3B+ZccuSxo/X8q9nQ+mFecWA==} + '@typescript-eslint/scope-manager@8.59.0': + resolution: {integrity: sha512-UzR16Ut8IpA3Mc4DbgAShlPPkVm8xXMWafXxB0BocaVRHs8ZGakAxGRskF7FId3sdk9lgGD73GSFaWmWFDE4dg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - typescript: '>=4.8.4 <6.0.0' '@typescript-eslint/tsconfig-utils@8.56.0': resolution: {integrity: sha512-bSJoIIt4o3lKXD3xmDh9chZcjCz5Lk8xS7Rxn+6l5/pKrDpkCwtQNQQwZ2qRPk7TkUYhrq3WPIHXOXlbXP0itg==} @@ -2756,17 +2921,23 @@ packages: peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/tsconfig-utils@8.57.1': - resolution: {integrity: sha512-0lgOZB8cl19fHO4eI46YUx2EceQqhgkPSuCGLlGi79L2jwYY1cxeYc1Nae8Aw1xjgW3PKVDLlr3YJ6Bxx8HkWg==} + '@typescript-eslint/tsconfig-utils@8.58.0': + resolution: {integrity: sha512-doNSZEVJsWEu4htiVC+PR6NpM+pa+a4ClH9INRWOWCUzMst/VA9c4gXq92F8GUD1rwhNvRLkgjfYtFXegXQF7A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - typescript: '>=4.8.4 <6.0.0' + typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/tsconfig-utils@8.57.2': - resolution: {integrity: sha512-3Lm5DSM+DCowsUOJC+YqHHnKEfFh5CoGkj5Z31NQSNF4l5wdOwqGn99wmwN/LImhfY3KJnmordBq/4+VDe2eKw==} + '@typescript-eslint/tsconfig-utils@8.58.2': + resolution: {integrity: sha512-3SR+RukipDvkkKp/d0jP0dyzuls3DbGmwDpVEc5wqk5f38KFThakqAAO0XMirWAE+kT00oTauTbzMFGPoAzB0A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - typescript: '>=4.8.4 <6.0.0' + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/tsconfig-utils@8.59.0': + resolution: {integrity: sha512-91Sbl3s4Kb3SybliIY6muFBmHVv+pYXfybC4Oolp3dvk8BvIE3wOPc+403CWIT7mJNkfQRGtdqghzs2+Z91Tqg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.1.0' '@typescript-eslint/type-utils@8.56.0': resolution: {integrity: sha512-qX2L3HWOU2nuDs6GzglBeuFXviDODreS58tLY/BALPC7iu3Fa+J7EOTwnX9PdNBxUI7Uh0ntP0YWGnxCkXzmfA==} @@ -2775,34 +2946,28 @@ packages: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/type-utils@8.57.2': - resolution: {integrity: sha512-Co6ZCShm6kIbAM/s+oYVpKFfW7LBc6FXoPXjTRQ449PPNBY8U0KZXuevz5IFuuUj2H9ss40atTaf9dlGLzbWZg==} + '@typescript-eslint/type-utils@8.59.0': + resolution: {integrity: sha512-3TRiZaQSltGqGeNrJzzr1+8YcEobKH9rHnqIp/1psfKFmhRQDNMGP5hBufanYTGznwShzVLs3Mz+gDN7HkWfXg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 - typescript: '>=4.8.4 <6.0.0' - - '@typescript-eslint/types@8.49.0': - resolution: {integrity: sha512-e9k/fneezorUo6WShlQpMxXh8/8wfyc+biu6tnAqA81oWrEic0k21RHzP9uqqpyBBeBKu4T+Bsjy9/b8u7obXQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + typescript: '>=4.8.4 <6.1.0' '@typescript-eslint/types@8.56.0': resolution: {integrity: sha512-DBsLPs3GsWhX5HylbP9HNG15U0bnwut55Lx12bHB9MpXxQ+R5GC8MwQe+N1UFXxAeQDvEsEDY6ZYwX03K7Z6HQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/types@8.57.1': - resolution: {integrity: sha512-S29BOBPJSFUiblEl6RzPPjJt6w25A6XsBqRVDt53tA/tlL8q7ceQNZHTjPeONt/3S7KRI4quk+yP9jK2WjBiPQ==} + '@typescript-eslint/types@8.58.0': + resolution: {integrity: sha512-O9CjxypDT89fbHxRfETNoAnHj/i6IpRK0CvbVN3qibxlLdo5p5hcLmUuCCrHMpxiWSwKyI8mCP7qRNYuOJ0Uww==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/types@8.57.2': - resolution: {integrity: sha512-/iZM6FnM4tnx9csuTxspMW4BOSegshwX5oBDznJ7S4WggL7Vczz5d2W11ecc4vRrQMQHXRSxzrCsyG5EsPPTbA==} + '@typescript-eslint/types@8.58.2': + resolution: {integrity: sha512-9TukXyATBQf/Jq9AMQXfvurk+G5R2MwfqQGDR2GzGz28HvY/lXNKGhkY+6IOubwcquikWk5cjlgPvD2uAA7htQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/typescript-estree@8.49.0': - resolution: {integrity: sha512-jrLdRuAbPfPIdYNppHJ/D0wN+wwNfJ32YTAm10eJVsFmrVpXQnDWBn8niCSMlWjvml8jsce5E/O+86IQtTbJWA==} + '@typescript-eslint/types@8.59.0': + resolution: {integrity: sha512-nLzdsT1gdOgFxxxwrlNVUBzSNBEEHJ86bblmk4QAS6stfig7rcJzWKqCyxFy3YRRHXDWEkb2NralA1nOYkkm/A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - typescript: '>=4.8.4 <6.0.0' '@typescript-eslint/typescript-estree@8.56.0': resolution: {integrity: sha512-ex1nTUMWrseMltXUHmR2GAQ4d+WjkZCT4f+4bVsps8QEdh0vlBsaCokKTPlnqBFqqGaxilDNJG7b8dolW2m43Q==} @@ -2810,11 +2975,17 @@ packages: peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/typescript-estree@8.57.2': - resolution: {integrity: sha512-2MKM+I6g8tJxfSmFKOnHv2t8Sk3T6rF20A1Puk0svLK+uVapDZB/4pfAeB7nE83uAZrU6OxW+HmOd5wHVdXwXA==} + '@typescript-eslint/typescript-estree@8.58.0': + resolution: {integrity: sha512-7vv5UWbHqew/dvs+D3e1RvLv1v2eeZ9txRHPnEEBUgSNLx5ghdzjHa0sgLWYVKssH+lYmV0JaWdoubo0ncGYLA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - typescript: '>=4.8.4 <6.0.0' + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/typescript-estree@8.59.0': + resolution: {integrity: sha512-O9Re9P1BmBLFJyikRbQpLku/QA3/AueZNO9WePLBwQrvkixTmDe8u76B6CYUAITRl/rHawggEqUGn5QIkVRLMw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.1.0' '@typescript-eslint/utils@8.56.0': resolution: {integrity: sha512-RZ3Qsmi2nFGsS+n+kjLAYDPVlrzf7UhTffrDIKr+h2yzAlYP/y5ZulU0yeDEPItos2Ph46JAL5P/On3pe7kDIQ==} @@ -2823,40 +2994,47 @@ packages: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/utils@8.57.2': - resolution: {integrity: sha512-krRIbvPK1ju1WBKIefiX+bngPs+odIQUtR7kymzPfo1POVw3jlF+nLkmexdSSd4UCbDcQn+wMBATOOmpBbqgKg==} + '@typescript-eslint/utils@8.58.0': + resolution: {integrity: sha512-RfeSqcFeHMHlAWzt4TBjWOAtoW9lnsAGiP3GbaX9uVgTYYrMbVnGONEfUCiSss+xMHFl+eHZiipmA8WkQ7FuNA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 - typescript: '>=4.8.4 <6.0.0' + typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/visitor-keys@8.49.0': - resolution: {integrity: sha512-LlKaciDe3GmZFphXIc79THF/YYBugZ7FS1pO581E/edlVVNbZKDy93evqmrfQ9/Y4uN0vVhX4iuchq26mK/iiA==} + '@typescript-eslint/utils@8.59.0': + resolution: {integrity: sha512-I1R/K7V07XsMJ12Oaxg/O9GfrysGTmCRhvZJBv0RE0NcULMzjqVpR5kRRQjHsz3J/bElU7HwCO7zkqL+MSUz+g==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' '@typescript-eslint/visitor-keys@8.56.0': resolution: {integrity: sha512-q+SL+b+05Ud6LbEE35qe4A99P+htKTKVbyiNEe45eCbJFyh/HVK9QXwlrbz+Q4L8SOW4roxSVwXYj4DMBT7Ieg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/visitor-keys@8.57.2': - resolution: {integrity: sha512-zhahknjobV2FiD6Ee9iLbS7OV9zi10rG26odsQdfBO/hjSzUQbkIYgda+iNKK1zNiW2ey+Lf8MU5btN17V3dUw==} + '@typescript-eslint/visitor-keys@8.58.0': + resolution: {integrity: sha512-XJ9UD9+bbDo4a4epraTwG3TsNPeiB9aShrUneAVXy8q4LuwowN+qu89/6ByLMINqvIMeI9H9hOHQtg/ijrYXzQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/visitor-keys@8.59.0': + resolution: {integrity: sha512-/uejZt4dSere1bx12WLlPfv8GktzcaDtuJ7s42/HEZ5zGj9oxRaD4bj7qwSunXkf+pbAhFt2zjpHYUiT5lHf0Q==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@ungap/structured-clone@1.3.0': resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==} - '@vitejs/plugin-vue@6.0.5': - resolution: {integrity: sha512-bL3AxKuQySfk1iGcBsQnoRVexTPJq0Z/ixFVM8OhVJAP6ZXXXLtM7NFKWhLl30Kg7uTBqIaPXbh+nuQCuBDedg==} + '@vitejs/plugin-vue@6.0.6': + resolution: {integrity: sha512-u9HHgfrq3AjXlysn0eINFnWQOJQLO9WN6VprZ8FXl7A2bYisv3Hui9Ij+7QZ41F/WYWarHjwBbXtD7dKg3uxbg==} engines: {node: ^20.19.0 || >=22.12.0} peerDependencies: vite: ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 vue: ^3.2.25 - '@vitest/expect@4.1.1': - resolution: {integrity: sha512-xAV0fqBTk44Rn6SjJReEQkHP3RrqbJo6JQ4zZ7/uVOiJZRarBtblzrOfFIZeYUrukp2YD6snZG6IBqhOoHTm+A==} + '@vitest/expect@4.1.5': + resolution: {integrity: sha512-PWBaRY5JoKuRnHlUHfpV/KohFylaDZTupcXN1H9vYryNLOnitSw60Mw9IAE2r67NbwwzBw/Cc/8q9BK3kIX8Kw==} - '@vitest/mocker@4.1.1': - resolution: {integrity: sha512-h3BOylsfsCLPeceuCPAAJ+BvNwSENgJa4hXoXu4im0bs9Lyp4URc4JYK4pWLZ4pG/UQn7AT92K6IByi6rE6g3A==} + '@vitest/mocker@4.1.5': + resolution: {integrity: sha512-/x2EmFC4mT4NNzqvC3fmesuV97w5FC903KPmey4gsnJiMQ3Be1IlDKVaDaG8iqaLFHqJ2FVEkxZk5VmeLjIItw==} peerDependencies: msw: ^2.4.9 vite: ^6.0.0 || ^7.0.0 || ^8.0.0 @@ -2866,20 +3044,20 @@ packages: vite: optional: true - '@vitest/pretty-format@4.1.1': - resolution: {integrity: sha512-GM+TEQN5WhOygr1lp7skeVjdLPqqWMHsfzXrcHAqZJi/lIVh63H0kaRCY8MDhNWikx19zBUK8ceaLB7X5AH9NQ==} + '@vitest/pretty-format@4.1.5': + resolution: {integrity: sha512-7I3q6l5qr03dVfMX2wCo9FxwSJbPdwKjy2uu/YPpU3wfHvIL4QHwVRp57OfGrDFeUJ8/8QdfBKIV12FTtLn00g==} - '@vitest/runner@4.1.1': - resolution: {integrity: sha512-f7+FPy75vN91QGWsITueq0gedwUZy1fLtHOCMeQpjs8jTekAHeKP80zfDEnhrleviLHzVSDXIWuCIOFn3D3f8A==} + '@vitest/runner@4.1.5': + resolution: {integrity: sha512-2D+o7Pr82IEO46YPpoA/YU0neeyr6FTerQb5Ro7BUnBuv6NQtT/kmVnczngiMEBhzgqz2UZYl5gArejsyERDSQ==} - '@vitest/snapshot@4.1.1': - resolution: {integrity: sha512-kMVSgcegWV2FibXEx9p9WIKgje58lcTbXgnJixfcg15iK8nzCXhmalL0ZLtTWLW9PH1+1NEDShiFFedB3tEgWg==} + '@vitest/snapshot@4.1.5': + resolution: {integrity: sha512-zypXEt4KH/XgKGPUz4eC2AvErYx0My5hfL8oDb1HzGFpEk1P62bxSohdyOmvz+d9UJwanI68MKwr2EquOaOgMQ==} - '@vitest/spy@4.1.1': - resolution: {integrity: sha512-6Ti/KT5OVaiupdIZEuZN7l3CZcR0cxnxt70Z0//3CtwgObwA6jZhmVBA3yrXSVN3gmwjgd7oDNLlsXz526gpRA==} + '@vitest/spy@4.1.5': + resolution: {integrity: sha512-2lNOsh6+R2Idnf1TCZqSwYlKN2E/iDlD8sgU59kYVl+OMDmvldO1VDk39smRfpUNwYpNRVn3w4YfuC7KfbBnkQ==} - '@vitest/utils@4.1.1': - resolution: {integrity: sha512-cNxAlaB3sHoCdL6pj6yyUXv9Gry1NHNg0kFTXdvSIZXLHsqKH7chiWOkwJ5s5+d/oMwcoG9T0bKU38JZWKusrQ==} + '@vitest/utils@4.1.5': + resolution: {integrity: sha512-76wdkrmfXfqGjueGgnb45ITPyUi1ycZ4IHgC2bhPDUfWHklY/q3MdLOAB+TF1e6xfl8NxNY0ZYaPCFNWSsw3Ug==} '@volar/language-core@2.4.28': resolution: {integrity: sha512-w4qhIJ8ZSitgLAkVay6AbcnC7gP3glYM3fYwKV3srj8m494E3xtrCv6E+bWviiK/8hs6e6t1ij1s2Endql7vzQ==} @@ -2952,8 +3130,8 @@ packages: typescript: optional: true - '@vue/language-core@3.2.6': - resolution: {integrity: sha512-xYYYX3/aVup576tP/23sEUpgiEnujrENaoNRbaozC1/MA9I6EGFQRJb4xrt/MmUCAGlxTKL2RmT8JLTPqagCkg==} + '@vue/language-core@3.2.7': + resolution: {integrity: sha512-Gn4q/tRxbpVGLEuARQ43p3YELlNAFgRUVCgW9U5Cr+5q4vfD2bWDWpl3ABbJMXUt5xlE1dF8dkigg2aUq7JYYw==} '@vue/reactivity@3.5.27': resolution: {integrity: sha512-vvorxn2KXfJ0nBEnj4GYshSgsyMNFnIQah/wczXlsNXt+ijhugmW+PpJ2cNPe4V6jpnBcs0MhCODKllWG+nvoQ==} @@ -2972,8 +3150,15 @@ packages: '@vue/shared@3.5.27': resolution: {integrity: sha512-dXr/3CgqXsJkZ0n9F3I4elY8wM9jMJpP3pvRG52r6m0tu/MsAFIe6JpXVGeNMd/D9F4hQynWT8Rfuj0bdm9kFQ==} - '@vue/test-utils@2.4.6': - resolution: {integrity: sha512-FMxEjOpYNYiFe0GkaHsnJPXFHxQ6m4t8vI/ElPGpMWxZKpmRvQ33OIrvRXemy6yha03RxhOlQuy+gZMC3CQSow==} + '@vue/test-utils@2.4.7': + resolution: {integrity: sha512-tyIgzH/BdAjZsgKlFrytTW515CpduI5uzoCwa0r0ftwZTBTCX5sSIERsbYEjj+6vnp4/EYyW0Qb6ASI4jfgptg==} + peerDependencies: + '@vue/compiler-dom': 3.x + '@vue/server-renderer': 3.x + vue: 3.x + peerDependenciesMeta: + '@vue/server-renderer': + optional: true '@vue/tsconfig@0.9.1': resolution: {integrity: sha512-buvjm+9NzLCJL29KY1j1991YYJ5e6275OiK+G4jtmfIb+z4POywbdm0wXusT9adVWqe0xqg70TbI7+mRx4uU9w==} @@ -3019,11 +3204,6 @@ packages: peerDependencies: acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - acorn@8.14.0: - resolution: {integrity: sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==} - engines: {node: '>=0.4.0'} - hasBin: true - acorn@8.15.0: resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==} engines: {node: '>=0.4.0'} @@ -3043,8 +3223,8 @@ packages: ajv@8.18.0: resolution: {integrity: sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==} - alien-signals@3.0.0: - resolution: {integrity: sha512-JHoRJf18Y6HN4/KZALr3iU+0vW9LKG+8FMThQlbn4+gv8utsLIkwpomjElGPccGeNwh0FI2HN6BLnyFLo6OyLQ==} + alien-signals@3.1.2: + resolution: {integrity: sha512-d9dYqZTS90WLiU0I5c6DHj/HcKkF8ZyGN3G5x8wSbslulz70KOxaqCT0hQCo9KOyhVqzqGojvNdJXoTumZOtcw==} ansi-align@3.0.1: resolution: {integrity: sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==} @@ -3057,10 +3237,6 @@ packages: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} - ansi-regex@6.0.1: - resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} - engines: {node: '>=12'} - ansi-regex@6.2.2: resolution: {integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==} engines: {node: '>=12'} @@ -3120,8 +3296,8 @@ packages: atomically@2.1.0: resolution: {integrity: sha512-+gDffFXRW6sl/HCwbta7zK4uNqbPjv4YJEAdz7Vu+FLQHe77eZ4bvbJGi4hE0QPeJlMYMA3piXEr1UL3dAwx7Q==} - autoprefixer@10.4.27: - resolution: {integrity: sha512-NP9APE+tO+LuJGn7/9+cohklunJsXWiaWEfV3si4Gi/XHDwVNgkwr1J3RQYFIvPy76GmJ9/bW8vyoU1LcxwKHA==} + autoprefixer@10.5.0: + resolution: {integrity: sha512-FMhOoZV4+qR6aTUALKX2rEqGG+oyATvwBt9IIzVR5rMa2HRWPkxf+P+PAJLD1I/H5/II+HuZcBJYEFBpq39ong==} engines: {node: ^10 || ^12 || >=14} hasBin: true peerDependencies: @@ -3131,8 +3307,8 @@ packages: resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} engines: {node: '>= 0.4'} - axios@1.13.5: - resolution: {integrity: sha512-cz4ur7Vb0xS4/KUN0tPWe44eqxrIu31me+fbang3ijiNscE129POzipJJA6zniq2C/Z6sJCjMimjS8Lc/GAs8Q==} + axios@1.15.0: + resolution: {integrity: sha512-wWyJDlAatxk30ZJer+GeCWS209sA42X+N5jU2jy6oHTp7ufw8uzUTVFBX9+wTfAlhiJXGS0Bq7X6efruWjuK9Q==} b4a@1.6.7: resolution: {integrity: sha512-OnAYlL5b7LEkALw87fUVafQw5rVR9RjwGd4KUwNQ6DrrNmaVaUCgLipfVlzrPQ4tWOR9P0IXGNOx50jYCCdSJg==} @@ -3189,14 +3365,14 @@ packages: base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - baseline-browser-mapping@2.9.4: - resolution: {integrity: sha512-ZCQ9GEWl73BVm8bu5Fts8nt7MHdbt5vY9bP6WGnUh+r3l8M7CgfyTlwsgCbMC66BNxPr6Xoce3j66Ms5YUQTNA==} + baseline-browser-mapping@2.10.12: + resolution: {integrity: sha512-qyq26DxfY4awP2gIRXhhLWfwzwI+N5Nxk6iQi8EFizIaWIjqicQTE4sLnZZVdeKPRcVNoJOkkpfzoIYuvCKaIQ==} + engines: {node: '>=6.0.0'} hasBin: true - basic-ftp@5.2.0: - resolution: {integrity: sha512-VoMINM2rqJwJgfdHq6RiUudKt2BV+FY5ZFezP/ypmwayk68+NzzAQy4XXLlqsGD4MCzq3DrmNFD/uUmBJuGoXw==} + basic-ftp@5.2.2: + resolution: {integrity: sha512-1tDrzKsdCg70WGvbFss/ulVAxupNauGnOlgpyjKzeQxzyllBLS0CGLV7tjIXTK3ZQA9/FBEm9qyFFN1bciA6pw==} engines: {node: '>=10.0.0'} - deprecated: Security vulnerability fixed in 5.2.0, please upgrade bidi-js@1.0.3: resolution: {integrity: sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==} @@ -3224,16 +3400,16 @@ packages: resolution: {integrity: sha512-F3PH5k5juxom4xktynS7MoFY+NUWH5LC4CnH11YB8NPew+HLpmBLCybSAEyb2F+4pRXhuhWqFesoQd6DAyc2hw==} engines: {node: '>=18'} - brace-expansion@5.0.2: - resolution: {integrity: sha512-Pdk8c9poy+YhOgVWw1JNN22/HcivgKWwpxKq04M/jTmHyCZn12WPJebZxdjSa5TmBqISrUSgNYU3eRORljfCCw==} - engines: {node: 20 || >=22} + brace-expansion@5.0.5: + resolution: {integrity: sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==} + engines: {node: 18 || 20 || >=22} braces@3.0.3: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} - browserslist@4.28.1: - resolution: {integrity: sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==} + browserslist@4.28.2: + resolution: {integrity: sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true @@ -3293,8 +3469,8 @@ packages: resolution: {integrity: sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA==} engines: {node: '>=16'} - caniuse-lite@1.0.30001781: - resolution: {integrity: sha512-RdwNCyMsNBftLjW6w01z8bKEvT6e/5tpPVEgtn22TiLGlstHOVecsX2KHFkD5e/vRnIE4EGzpuIODb3mtswtkw==} + caniuse-lite@1.0.30001790: + resolution: {integrity: sha512-bOoxfJPyYo+ds6W0YfptaCWbFnJYjh2Y1Eow5lRv+vI2u8ganPZqNm1JwNh0t2ELQCqIWg4B3dWEusgAmsoyOw==} capture-website@4.2.0: resolution: {integrity: sha512-EmkSn36CXTC8tUsS6aNmvvsdpfVTYYkuRp7U5bV9gcJwcDbqqA5c0Op/iskYPKtDdOkuVp61mjn/LLywX0h7cw==} @@ -3426,15 +3602,6 @@ packages: core-js-compat@3.38.1: resolution: {integrity: sha512-JRH6gfXxGmrzF3tZ57lFx97YARxCXPaMzPo6jELZhv88pBH5VXpQ+y0znKGlFnzuaihqhLbefxSJxWJMPtfDzw==} - cosmiconfig@9.0.0: - resolution: {integrity: sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==} - engines: {node: '>=14'} - peerDependencies: - typescript: '>=4.9.5' - peerDependenciesMeta: - typescript: - optional: true - cosmiconfig@9.0.1: resolution: {integrity: sha512-hr4ihw+DBqcvrsEDioRO31Z17x71pUYoNe/4h6Z0wB72p7MU7/9gH8Q3s12NFhHPfYBBOV3qyfUxmr/Yn3shnQ==} engines: {node: '>=14'} @@ -3491,10 +3658,6 @@ packages: resolution: {integrity: sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==} engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} - 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-tree@3.2.1: resolution: {integrity: sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA==} engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} @@ -3614,8 +3777,8 @@ packages: resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} engines: {node: '>= 0.4'} - defu@6.1.4: - resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==} + defu@6.1.7: + resolution: {integrity: sha512-7z22QmUWiQ/2d0KkdYmANbRUVABpZ9SNYyH5vx6PZ+nE5bcC0l7uFvEfHlyld/HcGBFTL536ClDt3DEcSlEJAQ==} degenerator@5.0.1: resolution: {integrity: sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==} @@ -3657,9 +3820,8 @@ packages: resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} engines: {node: '>= 4'} - dompurify@3.3.2: - resolution: {integrity: sha512-6obghkliLdmKa56xdbLOpUZ43pAR6xFy1uOrxBaIDjT+yaRuuybLjGS9eVBoSR/UPU5fq3OXClEHLJNGvbxKpQ==} - engines: {node: '>=20'} + dompurify@3.4.0: + resolution: {integrity: sha512-nolgK9JcaUXMSmW+j1yaSvaEaoXYHwWyGJlkoCTghc97KgGDDSnpoU/PlEnw63Ah+TGKFOyY+X5LnxaWbCSfXg==} domutils@3.2.2: resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==} @@ -3698,8 +3860,8 @@ packages: engines: {node: '>=0.10.0'} hasBin: true - electron-to-chromium@1.5.266: - resolution: {integrity: sha512-kgWEglXvkEfMH7rxP5OSZZwnaDWT7J9EoZCujhnpLbfi0bbNtRkgdX2E3gt0Uer11c61qCYktB3hwkAS325sJg==} + electron-to-chromium@1.5.329: + resolution: {integrity: sha512-/4t+AS1l4S3ZC0Ja7PHFIWeBIxGA3QGqV8/yKsP36v7NcyUCl+bIcmw6s5zVuMIECWwBrAK/6QLzTmbJChBboQ==} emoji-picker-element@1.25.0: resolution: {integrity: sha512-UcUMxqIuneLCsEJ5KpqTD1xaHZyUpg6Oa7uCVe5AMXXpsW3C2TNegbNLXj2/rlbyr6qVMf7lXTFyzvFEarOIUg==} @@ -3788,8 +3950,13 @@ packages: engines: {node: '>=18'} hasBin: true - esbuild@0.27.4: - resolution: {integrity: sha512-Rq4vbHnYkK5fws5NF7MYTU68FPRE1ajX7heQ/8QXXWqNgqqJ/GkmmyxIzUnf2Sr/bakf8l54716CcMGHYhMrrQ==} + esbuild@0.27.5: + resolution: {integrity: sha512-zdQoHBjuDqKsvV5OPaWansOwfSQ0Js+Uj9J85TBvj3bFW1JjWTSULMRwdQAc8qMeIScbClxeMK0jlrtB9linhA==} + engines: {node: '>=18'} + hasBin: true + + esbuild@0.28.0: + resolution: {integrity: sha512-sNR9MHpXSUV/XB4zmsFKN+QgVG82Cc7+/aaxJ8Adi8hyOac+EXptIp45QBPaVyX3N70664wRbTcLTOemCAnyqw==} engines: {node: '>=18'} hasBin: true @@ -3822,8 +3989,8 @@ packages: peerDependencies: eslint: '>=8.40.0' - eslint-plugin-vue@10.8.0: - resolution: {integrity: sha512-f1J/tcbnrpgC8suPN5AtdJ5MQjuXbSU9pGRSSYAuF3SHoiYCOdEX6O22pLaRyLHXvDcOe+O5ENgc1owQ587agA==} + eslint-plugin-vue@10.9.0: + resolution: {integrity: sha512-EFNNzu4HqtTRb5DJINpyd+u3bDdzETWDMpCzG+UBHz1tpsnMDCeOcf61u4Wy/cbXnMymK+MT9bjH7KcG1fItSw==} 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 @@ -4002,9 +4169,6 @@ packages: flatted@3.4.2: resolution: {integrity: sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==} - flexsearch@0.8.212: - resolution: {integrity: sha512-wSyJr1GUWoOOIISRu+X2IXiOcVfg9qqBRyCPRUdLMIGJqPzMo+jMRlvE83t14v1j0dRMEaBbER/adQjp6Du2pw==} - floating-vue@5.2.2: resolution: {integrity: sha512-afW+h2CFafo+7Y9Lvw/xsqjaQlKLdJV7h1fCHfcYQ1C4SVMlu7OAekqWgu5d4SgvkBVU0pVpLlVsrSTBURFRkg==} peerDependencies: @@ -4014,8 +4178,8 @@ packages: '@nuxt/kit': optional: true - follow-redirects@1.15.11: - resolution: {integrity: sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==} + follow-redirects@1.16.0: + resolution: {integrity: sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==} engines: {node: '>=4.0'} peerDependencies: debug: '*' @@ -4026,10 +4190,6 @@ packages: for-each@0.3.3: resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} - foreground-child@3.3.0: - resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==} - engines: {node: '>=14'} - foreground-child@3.3.1: resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} engines: {node: '>=14'} @@ -4084,10 +4244,6 @@ packages: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} - get-east-asian-width@1.4.0: - resolution: {integrity: sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q==} - engines: {node: '>=18'} - get-east-asian-width@1.5.0: resolution: {integrity: sha512-CQ+bEO+Tva/qlmw24dCejulK5pMzVnUOFOijVogd3KQs07HnRIgp8TGipvCCRT06xeYEbpbgwaCxglFyiuIcmA==} engines: {node: '>=18'} @@ -4167,8 +4323,8 @@ packages: resolution: {integrity: sha512-0Ia46fDOaT7k4og1PDW4YbodWWr3scS2vAr2lTbsplOt2WkKp0vQbkI9wKis/T5LV/dqPjO3bpS/z6GTJB82LA==} engines: {node: '>=18'} - globby@16.1.1: - resolution: {integrity: sha512-dW7vl+yiAJSp6aCekaVnVJxurRv7DCOLyXqEG3RYMYUg7AuJ2jCqPkZTA8ooqC2vtnkaMcV5WfFBMuEnTu1OQg==} + globby@16.2.0: + resolution: {integrity: sha512-QrJia2qDf5BB/V6HYlDTs0I0lBahyjLzpGQg3KT7FnCdTonAyPy2RtY802m2k4ALx6Dp752f82WsOczEVr3l6Q==} engines: {node: '>=20'} globjoin@0.1.4: @@ -4188,8 +4344,8 @@ packages: resolution: {integrity: sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==} engines: {node: '>=6.0'} - happy-dom@20.8.8: - resolution: {integrity: sha512-5/F8wxkNxYtsN0bXfMwIyNLZ9WYsoOYPbmoluqVJqv8KBUbcyKZawJ7uYK4WTX8IHBLYv+VXIwfeNDPy1oKMwQ==} + happy-dom@20.9.0: + resolution: {integrity: sha512-GZZ9mKe8r646NUAf/zemnGbjYh4Bt8/MqASJY+pSm5ZDtc3YQox+4gsLI7yi1hba6o+eCsGxpHn5+iEVn31/FQ==} engines: {node: '>=20.0.0'} hard-rejection@2.1.0: @@ -4531,16 +4687,12 @@ packages: engines: {node: '>=10'} hasBin: true - jiti@2.4.2: - resolution: {integrity: sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==} - hasBin: true - jiti@2.6.1: resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==} hasBin: true - joi@18.0.2: - resolution: {integrity: sha512-RuCOQMIt78LWnktPoeBL0GErkNaJPTBGcYuyaBvUOQSpcpcLfWrHPPihYdOGbV5pam9VTWbeoF7TsGiHugcjGA==} + joi@18.1.2: + resolution: {integrity: sha512-rF5MAmps5esSlhCA+N1b6IYHDw9j/btzGaqfgie522jS02Ju/HXBxamlXVlKEHAxoMKQL77HWI8jlqWsFuekZA==} engines: {node: '>= 20'} js-beautify@1.15.1: @@ -4755,8 +4907,8 @@ packages: lodash.truncate@4.4.2: resolution: {integrity: sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==} - lodash@4.17.23: - resolution: {integrity: sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==} + lodash@4.18.1: + resolution: {integrity: sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==} log-symbols@4.1.0: resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} @@ -4768,10 +4920,6 @@ packages: lru-cache@10.4.3: resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} - lru-cache@11.2.2: - resolution: {integrity: sha512-F9ODfyqML2coTIsQpSkRHnLSZMtkU8Q+mSfcaIyKwy58u+8k5nvAYeiNhsyMARvzNcXJ9QfWVrcPsC9e9rAxtg==} - engines: {node: 20 || >=22} - lru-cache@11.2.4: resolution: {integrity: sha512-B5Y16Jr9LB9dHVkh6ZevG+vAbOsNOYCX+sXvFWFu7B3Iz5mijW3zdbMyhsh8ANd2mSWBYdJgnqi+mL7/LrOPYg==} engines: {node: 20 || >=22} @@ -4841,12 +4989,6 @@ packages: 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==} - - mdn-data@2.26.0: - resolution: {integrity: sha512-ZqI0qjKWHMPcGUfLmlr80NPNVHIOjPMHtIOe1qXYFGS0YBZ1YKAzo9yk8W+gGrLCN0Xdv/RKxqdIsqPakEfmow==} - mdn-data@2.27.1: resolution: {integrity: sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==} @@ -4974,8 +5116,8 @@ packages: encoding: optional: true - node-releases@2.0.27: - resolution: {integrity: sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==} + node-releases@2.0.36: + resolution: {integrity: sha512-TdC8FSgHz8Mwtw9g5L4gR/Sh9XhSP/0DEkQxfEFXOpiul5IiHgHan2VhYYb6agDSfp4KuvltmGApc8HMgUrIkA==} nopt@7.2.1: resolution: {integrity: sha512-taM24ViiimT/XntxbPyJQzCG+p4EKOpgD3mxFwW38mGjVUrfERQOeY4EDHjdnptttfHuHQXFx+lTP08Q+mLa/w==} @@ -5050,6 +5192,9 @@ packages: resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} engines: {node: '>=0.10.0'} + otplib@12.0.1: + resolution: {integrity: sha512-xDGvUOQjop7RDgxTQ+o4pOol0/3xSZzawTiPKRrHnQWAy0WjhNs/5HdIDJCrqC4MBynmjXgULc6YfioaxZeFgg==} + p-limit@2.3.0: resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} engines: {node: '>=6'} @@ -5190,8 +5335,8 @@ packages: peerDependencies: postcss: ^8.4.6 - postcss-color-functional-notation@8.0.2: - resolution: {integrity: sha512-tbmkk6teYpJzFcGwPIhN1gkvxqGHvNx2PMb8Y3S5Ktyn7xOlvD98XzQ99MFY5mAyvXWclDG+BgoJKYJXFJOp5Q==} + postcss-color-functional-notation@8.0.3: + resolution: {integrity: sha512-MyaFK+3PusD7F2+qlMDP6+zfSgHWP17AtmvHQs44W3+Qbb39VptVDVRJ4Lf7gHSVffW5ekEy/XrsZ0S0t34hrA==} engines: {node: '>=20.19.0'} peerDependencies: postcss: ^8.4 @@ -5265,8 +5410,8 @@ packages: peerDependencies: postcss: ^8.4 - postcss-html@1.8.0: - resolution: {integrity: sha512-5mMeb1TgLWoRKxZ0Xh9RZDfwUUIqRrcxO2uXO+Ezl1N5lqpCiSU5Gk6+1kZediBfBHFtPCdopr2UZ2SgUsKcgQ==} + postcss-html@1.8.1: + resolution: {integrity: sha512-OLF6P7qctfAWayOhLpcVnTGqVeJzu2W3WpIYelfz2+JV5oGxfkcEvweN9U4XpeqE0P98dcD9ssusGwlF0TK0uQ==} engines: {node: ^12 || >=14} postcss-image-set-function@8.0.0: @@ -5275,8 +5420,8 @@ packages: peerDependencies: postcss: ^8.4 - postcss-lab-function@8.0.2: - resolution: {integrity: sha512-1ZIAh8ODhZdnAb09Aq2BTenePKS1G/kUR0FwvzkQDfFtSOV64Ycv27YvV11fDycEvhIcEmgYkLABXKRiWcXRuA==} + postcss-lab-function@8.0.3: + resolution: {integrity: sha512-rUa27RLVXjMn1aDkHEt5dRsK80+bAACPr8w5Ow0BkIlfH6gEk0Mh1I0REkYhtp4UhKFw1HLEk3AzvKBi6BGOqw==} engines: {node: '>=20.19.0'} peerDependencies: postcss: ^8.4 @@ -5319,8 +5464,8 @@ packages: peerDependencies: postcss: ^8.4 - postcss-preset-env@11.2.0: - resolution: {integrity: sha512-eNYpuj68cjGjvZMoSAbHilaCt3yIyzBL1cVuSGJfvJewsaBW/U6dI2bqCJl3iuZsL+yvBobcy4zJFA/3I68IHQ==} + postcss-preset-env@11.2.1: + resolution: {integrity: sha512-dqL7WR5wg9yP/+6pTHIsIeIpK6XVghJDE4/r4ZSdr5ExrbLiN5x78gly0Xs0MLGbHy2oT3WWNfbxowmnw9BurQ==} engines: {node: '>=20.19.0'} peerDependencies: postcss: ^8.4 @@ -5382,8 +5527,8 @@ packages: resolution: {integrity: sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==} engines: {node: '>=6.0.0'} - postcss@8.5.8: - resolution: {integrity: sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==} + postcss@8.5.10: + resolution: {integrity: sha512-pMMHxBOZKFU6HgAZ4eyGnwXF/EvPGGqUr0MnZ5+99485wwW41kW91A4LOGxSHhgugZmSChL5AlElNdwlNgcnLQ==} engines: {node: ^10 || ^12 || >=14} prelude-ls@1.2.1: @@ -5473,6 +5618,10 @@ packages: proxy-from-env@1.1.0: resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + proxy-from-env@2.1.0: + resolution: {integrity: sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==} + engines: {node: '>=10'} + pump@3.0.0: resolution: {integrity: sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==} @@ -5618,15 +5767,15 @@ packages: hasBin: true peerDependencies: rolldown: 1.x || ^1.0.0-beta - rollup: 4.60.0 + rollup: 4.60.2 peerDependenciesMeta: rolldown: optional: true rollup: optional: true - rollup@4.60.0: - resolution: {integrity: sha512-yqjxruMGBQJ2gG4HtjZtAfXArHomazDHoFwFFmZZl0r7Pdo7qCIXKqKHZc8yeoMgzJJ+pO6pEEHa+V7uzWlrAQ==} + rollup@4.60.2: + resolution: {integrity: sha512-J9qZyW++QK/09NyN/zeO0dG/1GdGfyp9lV8ajHnRVLfo/uFsbji5mHnDgn/qYdUHyCkM2N+8VyspgZclfAh0eQ==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true @@ -5669,117 +5818,117 @@ packages: safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - sass-embedded-all-unknown@1.98.0: - resolution: {integrity: sha512-6n4RyK7/1mhdfYvpP3CClS3fGoYqDvRmLClCESS6I7+SAzqjxvGG6u5Fo+cb1nrPNbbilgbM4QKdgcgWHO9NCA==} + sass-embedded-all-unknown@1.99.0: + resolution: {integrity: sha512-qPIRG8Uhjo6/OKyAKixTnwMliTz+t9K6Duk0mx5z+K7n0Ts38NSJz2sjDnc7cA/8V9Lb3q09H38dZ1CLwD+ssw==} cpu: ['!arm', '!arm64', '!riscv64', '!x64'] - sass-embedded-android-arm64@1.98.0: - resolution: {integrity: sha512-M9Ra98A6vYJHpwhoC/5EuH1eOshQ9ZyNwC8XifUDSbRl/cGeQceT1NReR9wFj3L7s1pIbmes1vMmaY2np0uAKQ==} + sass-embedded-android-arm64@1.99.0: + resolution: {integrity: sha512-fNHhdnP23yqqieCbAdym4N47AleSwjbNt6OYIYx4DdACGdtERjQB4iOX/TaKsW034MupfF7SjnAAK8w7Ptldtg==} engines: {node: '>=14.0.0'} cpu: [arm64] os: [android] - sass-embedded-android-arm@1.98.0: - resolution: {integrity: sha512-LjGiMhHgu7VL1n7EJxTCre1x14bUsWd9d3dnkS2rku003IWOI/fxc7OXgaKagoVzok1kv09rzO3vFXJR5ZeONQ==} + sass-embedded-android-arm@1.99.0: + resolution: {integrity: sha512-EHvJ0C7/VuP78Qr6f8gIUVUmCqIorEQpw2yp3cs3SMg02ZuumlhjXvkTcFBxHmFdFR23vTNk1WnhY6QSeV1nFQ==} engines: {node: '>=14.0.0'} cpu: [arm] os: [android] - sass-embedded-android-riscv64@1.98.0: - resolution: {integrity: sha512-WPe+0NbaJIZE1fq/RfCZANMeIgmy83x4f+SvFOG7LhUthHpZWcOcrPTsCKKmN3xMT3iw+4DXvqTYOCYGRL3hcQ==} + sass-embedded-android-riscv64@1.99.0: + resolution: {integrity: sha512-4zqDFRvgGDTL5vTHuIhRxUpXFoh0Cy7Gm5Ywk19ASd8Settmd14YdPRZPmMxfgS1GH292PofV1fq1ifiSEJWBw==} engines: {node: '>=14.0.0'} cpu: [riscv64] os: [android] - sass-embedded-android-x64@1.98.0: - resolution: {integrity: sha512-zrD25dT7OHPEgLWuPEByybnIfx4rnCtfge4clBgjZdZ3lF6E7qNLRBtSBmoFflh6Vg0RlEjJo5VlpnTMBM5MQQ==} + sass-embedded-android-x64@1.99.0: + resolution: {integrity: sha512-Uk53k/dGYt04RjOL4gFjZ0Z9DH9DKh8IA8WsXUkNqsxerAygoy3zqRBS2zngfE9K2jiOM87q+1R1p87ory9oQQ==} engines: {node: '>=14.0.0'} cpu: [x64] os: [android] - sass-embedded-darwin-arm64@1.98.0: - resolution: {integrity: sha512-cgr1z9rBnCdMf8K+JabIaYd9Rag2OJi5mjq08XJfbJGMZV/TA6hFJCLGkr5/+ZOn4/geTM5/3aSfQ8z5EIJAOg==} + sass-embedded-darwin-arm64@1.99.0: + resolution: {integrity: sha512-u61/7U3IGLqoO6gL+AHeiAtlTPFwJK1+964U8gp45ZN0hzh1yrARf5O1mivXv8NnNgJvbG2wWJbiNZP0lG/lTg==} engines: {node: '>=14.0.0'} cpu: [arm64] os: [darwin] - sass-embedded-darwin-x64@1.98.0: - resolution: {integrity: sha512-OLBOCs/NPeiMqTdOrMFbVHBQFj19GS3bSVSxIhcCq16ZyhouUkYJEZjxQgzv9SWA2q6Ki8GCqp4k6jMeUY9dcA==} + sass-embedded-darwin-x64@1.99.0: + resolution: {integrity: sha512-j/kkk/NcXdIameLezSfXjgCiBkVcA+G60AXrX768/3g0miK1g7M9dj7xOhCb1i7/wQeiEI3rw2LLuO63xRIn4A==} engines: {node: '>=14.0.0'} cpu: [x64] os: [darwin] - sass-embedded-linux-arm64@1.98.0: - resolution: {integrity: sha512-axOE3t2MTBwCtkUCbrdM++Gj0gC0fdHJPrgzQ+q1WUmY9NoNMGqflBtk5mBZaWUeha2qYO3FawxCB8lctFwCtw==} + sass-embedded-linux-arm64@1.99.0: + resolution: {integrity: sha512-btNcFpItcB56L40n8hDeL7sRSMLDXQ56nB5h2deddJx1n60rpKSElJmkaDGHtpkrY+CTtDRV0FZDjHeTJddYew==} engines: {node: '>=14.0.0'} cpu: [arm64] os: [linux] - sass-embedded-linux-arm@1.98.0: - resolution: {integrity: sha512-03baQZCxVyEp8v1NWBRlzGYrmVT/LK7ZrHlF1piscGiGxwfdxoLXVuxsylx3qn/dD/4i/rh7Bzk7reK1br9jvQ==} + sass-embedded-linux-arm@1.99.0: + resolution: {integrity: sha512-d4IjJZrX2+AwB2YCy1JySwdptJECNP/WfAQLUl8txI3ka8/d3TUI155GtelnoZUkio211PwIeFvvAeZ9RXPQnw==} engines: {node: '>=14.0.0'} cpu: [arm] os: [linux] - sass-embedded-linux-musl-arm64@1.98.0: - resolution: {integrity: sha512-LeqNxQA8y4opjhe68CcFvMzCSrBuJqYVFbwElEj9bagHXQHTp9xVPJRn6VcrC+0VLEDq13HVXMv7RslIuU0zmA==} + sass-embedded-linux-musl-arm64@1.99.0: + resolution: {integrity: sha512-Hi2bt/IrM5P4FBKz6EcHAlniwfpoz9mnTdvSd58y+avA3SANM76upIkAdSayA8ZGwyL3gZokru1AKDPF9lJDNw==} engines: {node: '>=14.0.0'} cpu: [arm64] os: [linux] - sass-embedded-linux-musl-arm@1.98.0: - resolution: {integrity: sha512-OBkjTDPYR4hSaueOGIM6FDpl9nt/VZwbSRpbNu9/eEJcxE8G/vynRugW8KRZmCFjPy8j/jkGBvvS+k9iOqKV3g==} + sass-embedded-linux-musl-arm@1.99.0: + resolution: {integrity: sha512-2gvHOupgIw3ytatXT4nFUow71LFbuOZPEwG+HUzcNQDH8ue4Ez8cr03vsv5MDv3lIjOKcXwDvWD980t18MwkoQ==} engines: {node: '>=14.0.0'} cpu: [arm] os: [linux] - sass-embedded-linux-musl-riscv64@1.98.0: - resolution: {integrity: sha512-7w6hSuOHKt8FZsmjRb3iGSxEzM87fO9+M8nt5JIQYMhHTj5C+JY/vcske0v715HCVj5e1xyTnbGXf8FcASeAIw==} + sass-embedded-linux-musl-riscv64@1.99.0: + resolution: {integrity: sha512-mKqGvVaJ9rHMqyZsF0kikQe4NO0f4osb67+X6nLhBiVDKvyazQHJ3zJQreNefIE36yL2sjHIclSB//MprzaQDg==} engines: {node: '>=14.0.0'} cpu: [riscv64] os: [linux] - sass-embedded-linux-musl-x64@1.98.0: - resolution: {integrity: sha512-QikNyDEJOVqPmxyCFkci8ZdCwEssdItfjQFJB+D+Uy5HFqcS5Lv3d3GxWNX/h1dSb23RPyQdQc267ok5SbEyJw==} + sass-embedded-linux-musl-x64@1.99.0: + resolution: {integrity: sha512-huhgOMmOc30r7CH7qbRbT9LerSEGSnWuS4CYNOskr9BvNeQp4dIneFufNRGZ7hkOAxUM8DglxIZJN/cyAT95Ew==} engines: {node: '>=14.0.0'} cpu: [x64] os: [linux] - sass-embedded-linux-riscv64@1.98.0: - resolution: {integrity: sha512-E7fNytc/v4xFBQKzgzBddV/jretA4ULAPO6XmtBiQu4zZBdBozuSxsQLe2+XXeb0X4S2GIl72V7IPABdqke/vA==} + sass-embedded-linux-riscv64@1.99.0: + resolution: {integrity: sha512-mevFPIFAVhrH90THifxLfOntFmHtcEKOcdWnep2gJ0X4DVva4AiVIRlQe/7w9JFx5+gnDRE1oaJJkzuFUuYZsA==} engines: {node: '>=14.0.0'} cpu: [riscv64] os: [linux] - sass-embedded-linux-x64@1.98.0: - resolution: {integrity: sha512-VsvP0t/uw00mMNPv3vwyYKUrFbqzxQHnRMO+bHdAMjvLw4NFf6mscpym9Bzf+NXwi1ZNKnB6DtXjmcpcvqFqYg==} + sass-embedded-linux-x64@1.99.0: + resolution: {integrity: sha512-9k7IkULqIZdCIVt4Mboryt6vN8Mjmm3EhI1P3mClU5y5i3wLK5ExC3cbVWk047KsID/fvB1RLslqghXJx5BoxA==} engines: {node: '>=14.0.0'} cpu: [x64] os: [linux] - sass-embedded-unknown-all@1.98.0: - resolution: {integrity: sha512-C4MMzcAo3oEDQnW7L8SBgB9F2Fq5qHPnaYTZRMOH3Mp/7kM4OooBInXpCiiFjLnjY95hzP4KyctVx0uYR6MYlQ==} + sass-embedded-unknown-all@1.99.0: + resolution: {integrity: sha512-P7MxiUtL/XzGo3PX0CaB8lNNEFLQWKikPA8pbKytx9ZCLZSDkt2NJcdAbblB/sqMs4AV3EK2NadV8rI/diq3xg==} os: ['!android', '!darwin', '!linux', '!win32'] - sass-embedded-win32-arm64@1.98.0: - resolution: {integrity: sha512-nP/10xbAiPbhQkMr3zQfXE4TuOxPzWRQe1Hgbi90jv2R4TbzbqQTuZVOaJf7KOAN4L2Bo6XCTRjK5XkVnwZuwQ==} + sass-embedded-win32-arm64@1.99.0: + resolution: {integrity: sha512-8whpsW7S+uO8QApKfQuc36m3P9EISzbVZOgC79goob4qGy09u8Gz/rYvw8h1prJDSjltpHGhOzBE6LDz7WvzVw==} engines: {node: '>=14.0.0'} cpu: [arm64] os: [win32] - sass-embedded-win32-x64@1.98.0: - resolution: {integrity: sha512-/lbrVsfbcbdZQ5SJCWcV0NVPd6YRs+FtAnfedp4WbCkO/ZO7Zt/58MvI4X2BVpRY/Nt5ZBo1/7v2gYcQ+J4svQ==} + sass-embedded-win32-x64@1.99.0: + resolution: {integrity: sha512-ipuOv1R2K4MHeuCEAZGpuUbAgma4gb0sdacyrTjJtMOy/OY9UvWfVlwErdB09KIkp4fPDpQJDJfvYN6bC8jeNg==} engines: {node: '>=14.0.0'} cpu: [x64] os: [win32] - sass-embedded@1.98.0: - resolution: {integrity: sha512-Do7u6iRb6K+lrllcTkB1BXcHwOxcKe3rEfOF/GcCLE2w3WpddakRAosJOHFUR37DpsvimQXEt5abs3NzUjEIqg==} + sass-embedded@1.99.0: + resolution: {integrity: sha512-gF/juR1aX02lZHkvwxdF80SapkQeg2fetoDF6gIQkNbSw5YEUFspMkyGTjPjgZSgIHuZpy+Wz4PlebKnLXMjdg==} engines: {node: '>=16.0.0'} hasBin: true - sass@1.98.0: - resolution: {integrity: sha512-+4N/u9dZ4PrgzGgPlKnaaRQx64RO0JBKs9sDhQ2pLgN6JQZ25uPQZKQYaBJU48Kd5BxgXoJ4e09Dq7nMcOUW3A==} + sass@1.99.0: + resolution: {integrity: sha512-kgW13M54DUB7IsIRM5LvJkNlpH+WhMpooUcaWGFARkF1Tc82v9mIWkCbCYf+MBvpIUBSeSOTilpZjEPr2VYE6Q==} engines: {node: '>=14.0.0'} hasBin: true @@ -5803,18 +5952,13 @@ packages: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true - semver@7.7.1: - resolution: {integrity: sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==} - engines: {node: '>=10'} - hasBin: true - semver@7.7.3: resolution: {integrity: sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==} engines: {node: '>=10'} hasBin: true - serialize-javascript@7.0.3: - resolution: {integrity: sha512-h+cZ/XXarqDgCjo+YSyQU/ulDEESGGf8AMK9pPNmhNSl/FzPl6L8pMp1leca5z6NuG6tvV/auC8/43tmovowww==} + serialize-javascript@7.0.5: + resolution: {integrity: sha512-F4LcB0UqUl1zErq+1nYEEzSHJnIwb3AF2XWB94b+afhrekOUijwooAYqFyRbjYkm2PAKBabx6oYv/xDxNi8IBw==} engines: {node: '>=20.0.0'} set-function-length@1.2.2: @@ -6005,10 +6149,6 @@ packages: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} - strip-ansi@7.1.0: - resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} - engines: {node: '>=12'} - strip-ansi@7.2.0: resolution: {integrity: sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==} engines: {node: '>=12'} @@ -6072,12 +6212,6 @@ packages: postcss-html: ^1.0.0 stylelint: '>=14.0.0' - stylelint-config-recommended@17.0.0: - resolution: {integrity: sha512-WaMSdEiPfZTSFVoYmJbxorJfA610O0tlYuU2aEwY33UQhSPgFbClrVJYWvy3jGJx+XW37O+LyNLiZOEXhKhJmA==} - engines: {node: '>=18.12.0'} - peerDependencies: - stylelint: ^16.23.0 - stylelint-config-recommended@18.0.0: resolution: {integrity: sha512-mxgT2XY6YZ3HWWe3Di8umG6aBmWmHTblTgu/f10rqFXnyWxjKWwNdjSWkgkwCtxIKnqjSJzvFmPT5yabVIRxZg==} engines: {node: '>=20.19.0'} @@ -6117,8 +6251,8 @@ packages: peerDependencies: stylelint: '>= 11 < 18' - stylelint@17.5.0: - resolution: {integrity: sha512-o/NS6zhsPZFmgUm5tXX4pVNg1XDOZSlucLdf2qow/lVn4JIyzZIQ5b3kad1ugqUj3GSIgr2u5lQw7X8rjqw33g==} + stylelint@17.9.0: + resolution: {integrity: sha512-xO0jeY6z1/urFL5L/BZLmB1yYlbRiRMQnYH6ArZIDWJ+SZXGssOY7XoYb1JIv/L220+EBnwwJXJS4Mt/F96SvA==} engines: {node: '>=20.19.0'} hasBin: true @@ -6169,8 +6303,8 @@ packages: resolution: {integrity: sha512-9kY+CygyYM6j02t5YFHbNz2FN5QmYGv9zAjVp4lCDjlCw7amdckXlEt/bjMhUIfj4ThGRE4gCUH5+yGnNuPo5A==} engines: {node: '>=10.0.0'} - tailwindcss@4.2.2: - resolution: {integrity: sha512-KWBIxs1Xb6NoLdMVqhbhgwZf2PGBpPEiwOqgI4pFIYbNTfBXiKYyWoTsXgBQ9WFg/OlhnvHaY+AEpW7wSmFo2Q==} + tailwindcss@4.2.4: + resolution: {integrity: sha512-HhKppgO81FQof5m6TEnuBWCZGgfRAWbaeOaGT00KOy/Pf/j6oUihdvBpA7ltCeAvZpFhW3j0PTclkxsd4IXYDA==} tapable@2.3.0: resolution: {integrity: sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==} @@ -6198,6 +6332,10 @@ packages: text-decoder@1.2.3: resolution: {integrity: sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA==} + thirty-two@1.0.2: + resolution: {integrity: sha512-OEI0IWCe+Dw46019YLl6V10Us5bi574EvlJEOcAkB29IzQ/mYD1A6RyNHLjZPiHCmuodxvgF6U+vZO1L15lxVA==} + engines: {node: '>=0.2.6'} + through@2.3.8: resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} @@ -6212,8 +6350,8 @@ packages: resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} engines: {node: '>=12.0.0'} - tinyrainbow@3.0.3: - resolution: {integrity: sha512-PSkbLUoxOFRzJYjjxHJt9xro7D+iilgMX/C9lawzVuYiIdcihh9DXmVibBe8lmcFrRi/VzlPjBxbN7rH24q8/Q==} + tinyrainbow@3.1.0: + resolution: {integrity: sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==} engines: {node: '>=14.0.0'} tldts-core@6.1.58: @@ -6270,8 +6408,8 @@ packages: resolution: {integrity: sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==} engines: {node: '>=8'} - ts-api-utils@2.4.0: - resolution: {integrity: sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==} + ts-api-utils@2.5.0: + resolution: {integrity: sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==} engines: {node: '>=18.12'} peerDependencies: typescript: '>=4.8.4' @@ -6435,8 +6573,8 @@ packages: resolution: {integrity: sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==} engines: {node: '>=4'} - update-browserslist-db@1.2.2: - resolution: {integrity: sha512-E85pfNzMQ9jpKkA7+TJAi4TJN+tBCuWh5rUcS/sv6cFi+1q9LYDwDI5dpUL0u/73EElyQ8d3TEaeW4sPedBqYA==} + update-browserslist-db@1.2.3: + resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==} hasBin: true peerDependencies: browserslist: '>= 4.21.0' @@ -6520,8 +6658,8 @@ packages: peerDependencies: vue: '>=3.2.13' - vite@7.3.1: - resolution: {integrity: sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==} + vite@7.3.2: + resolution: {integrity: sha512-Bby3NOsna2jsjfLVOHKes8sGwgl4TT0E6vvpYgnAYDIF/tie7MRaFthmKuHx1NSXjiTueXH3do80FMQgvEktRg==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true peerDependencies: @@ -6560,18 +6698,20 @@ packages: yaml: optional: true - vitest@4.1.1: - resolution: {integrity: sha512-yF+o4POL41rpAzj5KVILUxm1GCjKnELvaqmU9TLLUbMfDzuN0UpUR9uaDs+mCtjPe+uYPksXDRLQGGPvj1cTmA==} + vitest@4.1.5: + resolution: {integrity: sha512-9Xx1v3/ih3m9hN+SbfkUyy0JAs72ap3r7joc87XL6jwF0jGg6mFBvQ1SrwaX+h8BlkX6Hz9shdd1uo6AF+ZGpg==} engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0} hasBin: true peerDependencies: '@edge-runtime/vm': '*' '@opentelemetry/api': ^1.9.0 '@types/node': ^20.0.0 || ^22.0.0 || >=24.0.0 - '@vitest/browser-playwright': 4.1.1 - '@vitest/browser-preview': 4.1.1 - '@vitest/browser-webdriverio': 4.1.1 - '@vitest/ui': 4.1.1 + '@vitest/browser-playwright': 4.1.5 + '@vitest/browser-preview': 4.1.5 + '@vitest/browser-webdriverio': 4.1.5 + '@vitest/coverage-istanbul': 4.1.5 + '@vitest/coverage-v8': 4.1.5 + '@vitest/ui': 4.1.5 happy-dom: '*' jsdom: '*' vite: ^6.0.0 || ^7.0.0 || ^8.0.0 @@ -6588,6 +6728,10 @@ packages: optional: true '@vitest/browser-webdriverio': optional: true + '@vitest/coverage-istanbul': + optional: true + '@vitest/coverage-v8': + optional: true '@vitest/ui': optional: true happy-dom: @@ -6604,8 +6748,8 @@ packages: peerDependencies: vue: ^3.0.0 - vue-component-type-helpers@2.0.29: - resolution: {integrity: sha512-58i+ZhUAUpwQ+9h5Hck0D+jr1qbYl4voRt5KffBx8qzELViQ4XdT/Tuo+mzq8u63teAG8K0lLaOiL5ofqW38rg==} + vue-component-type-helpers@3.2.7: + resolution: {integrity: sha512-+gPp5YGmhfsj1IN+xUo7y0fb4clfnOiiUA39y07yW1VzCRjzVgwLbtmdWlghh7mXrPsEaYc7rrIir/HT6C8vYQ==} vue-demi@0.14.10: resolution: {integrity: sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==} @@ -6646,8 +6790,8 @@ packages: peerDependencies: vue: ^3.5.0 - vue-tsc@3.2.6: - resolution: {integrity: sha512-gYW/kWI0XrwGzd0PKc7tVB/qpdeAkIZLNZb10/InizkQjHjnT8weZ/vBarZoj4kHKbUTZT/bAVgoOr8x4NsQ/Q==} + vue-tsc@3.2.7: + resolution: {integrity: sha512-zc1tL3HoQni1zGTGrwBVRQb7rGP5SWdu/m4rGB6JcnAC5MT5LFZIxF7Y+EJEnt4hGF23d60rXH7gRjHGb5KQQQ==} hasBin: true peerDependencies: typescript: '>=5.0.0' @@ -6676,8 +6820,8 @@ packages: resolution: {integrity: sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==} engines: {node: '>=18'} - wait-on@9.0.4: - resolution: {integrity: sha512-k8qrgfwrPVJXTeFY8tl6BxVHiclK11u72DVKhpybHfUL/K6KM4bdyK9EhIVYGytB5MJe/3lq4Tf0hrjM+pvJZQ==} + wait-on@9.0.5: + resolution: {integrity: sha512-qgnbHDfDTRIp73ANEJNRW/7kn8CrDUcvZz18xotJQku/P4saTGkbIzvnMZebPmVvVNUiRq1qWAPyqCH+W4H8KA==} engines: {node: '>=20.0.0'} hasBin: true @@ -6823,12 +6967,12 @@ packages: wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} - write-file-atomic@7.0.0: - resolution: {integrity: sha512-YnlPC6JqnZl6aO4uRc+dx5PHguiR9S6WeoLtpxNT9wIG+BDya7ZNE1q7KOjVgaA73hKhKLpVPgJ5QA9THQ5BRg==} + write-file-atomic@7.0.1: + resolution: {integrity: sha512-OTIk8iR8/aCRWBqvxrzxR0hgxWpnYBblY1S5hDWBQfk/VFmJwzmJgQFN3WsoUKHISv2eAwe+PpbUzyL1CKTLXg==} engines: {node: ^20.17.0 || >=22.9.0} - ws@8.19.0: - resolution: {integrity: sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==} + ws@8.20.0: + resolution: {integrity: sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA==} engines: {node: '>=10.0.0'} peerDependencies: bufferutil: ^4.0.1 @@ -6934,7 +7078,7 @@ snapshots: dependencies: '@asamuzakjp/nwsapi': 2.3.9 bidi-js: 1.0.3 - css-tree: 3.1.0 + css-tree: 3.2.1 is-potential-custom-element-name: 1.0.1 lru-cache: 11.2.4 @@ -6991,7 +7135,7 @@ snapshots: dependencies: '@babel/compat-data': 7.26.0 '@babel/helper-validator-option': 7.25.9 - browserslist: 4.28.1 + browserslist: 4.28.2 lru-cache: 5.1.1 semver: 6.3.1 @@ -7709,7 +7853,7 @@ snapshots: '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) '@csstools/css-tokenizer': 3.0.4 - '@csstools/css-calc@3.1.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0)': + '@csstools/css-calc@3.2.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0)': dependencies: '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 @@ -7721,10 +7865,10 @@ snapshots: '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) '@csstools/css-tokenizer': 3.0.4 - '@csstools/css-color-parser@4.0.2(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0)': + '@csstools/css-color-parser@4.1.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0)': dependencies: '@csstools/color-helpers': 6.0.2 - '@csstools/css-calc': 3.1.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) + '@csstools/css-calc': 3.2.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 @@ -7736,9 +7880,11 @@ snapshots: dependencies: '@csstools/css-tokenizer': 4.0.0 - '@csstools/css-syntax-patches-for-csstree@1.0.28': {} + '@csstools/css-syntax-patches-for-csstree@1.1.2(css-tree@3.2.1)': + optionalDependencies: + css-tree: 3.2.1 - '@csstools/css-syntax-patches-for-csstree@1.1.1(css-tree@3.2.1)': + '@csstools/css-syntax-patches-for-csstree@1.1.3(css-tree@3.2.1)': optionalDependencies: css-tree: 3.2.1 @@ -7751,283 +7897,283 @@ snapshots: '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - '@csstools/postcss-alpha-function@2.0.3(postcss@8.5.8)': + '@csstools/postcss-alpha-function@2.0.4(postcss@8.5.10)': dependencies: - '@csstools/css-color-parser': 4.0.2(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) + '@csstools/css-color-parser': 4.1.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.8) - '@csstools/utilities': 3.0.0(postcss@8.5.8) - postcss: 8.5.8 + '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.10) + '@csstools/utilities': 3.0.0(postcss@8.5.10) + postcss: 8.5.10 - '@csstools/postcss-cascade-layers@6.0.0(postcss@8.5.8)': + '@csstools/postcss-cascade-layers@6.0.0(postcss@8.5.10)': dependencies: '@csstools/selector-specificity': 6.0.0(postcss-selector-parser@7.1.1) - postcss: 8.5.8 + postcss: 8.5.10 postcss-selector-parser: 7.1.1 - '@csstools/postcss-color-function-display-p3-linear@2.0.2(postcss@8.5.8)': + '@csstools/postcss-color-function-display-p3-linear@2.0.3(postcss@8.5.10)': dependencies: - '@csstools/css-color-parser': 4.0.2(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) + '@csstools/css-color-parser': 4.1.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.8) - '@csstools/utilities': 3.0.0(postcss@8.5.8) - postcss: 8.5.8 + '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.10) + '@csstools/utilities': 3.0.0(postcss@8.5.10) + postcss: 8.5.10 - '@csstools/postcss-color-function@5.0.2(postcss@8.5.8)': + '@csstools/postcss-color-function@5.0.3(postcss@8.5.10)': dependencies: - '@csstools/css-color-parser': 4.0.2(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) + '@csstools/css-color-parser': 4.1.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.8) - '@csstools/utilities': 3.0.0(postcss@8.5.8) - postcss: 8.5.8 + '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.10) + '@csstools/utilities': 3.0.0(postcss@8.5.10) + postcss: 8.5.10 - '@csstools/postcss-color-mix-function@4.0.2(postcss@8.5.8)': + '@csstools/postcss-color-mix-function@4.0.3(postcss@8.5.10)': dependencies: - '@csstools/css-color-parser': 4.0.2(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) + '@csstools/css-color-parser': 4.1.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.8) - '@csstools/utilities': 3.0.0(postcss@8.5.8) - postcss: 8.5.8 + '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.10) + '@csstools/utilities': 3.0.0(postcss@8.5.10) + postcss: 8.5.10 - '@csstools/postcss-color-mix-variadic-function-arguments@2.0.2(postcss@8.5.8)': + '@csstools/postcss-color-mix-variadic-function-arguments@2.0.3(postcss@8.5.10)': dependencies: - '@csstools/css-color-parser': 4.0.2(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) + '@csstools/css-color-parser': 4.1.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.8) - '@csstools/utilities': 3.0.0(postcss@8.5.8) - postcss: 8.5.8 + '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.10) + '@csstools/utilities': 3.0.0(postcss@8.5.10) + postcss: 8.5.10 - '@csstools/postcss-content-alt-text@3.0.0(postcss@8.5.8)': + '@csstools/postcss-content-alt-text@3.0.0(postcss@8.5.10)': dependencies: '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.8) - '@csstools/utilities': 3.0.0(postcss@8.5.8) - postcss: 8.5.8 + '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.10) + '@csstools/utilities': 3.0.0(postcss@8.5.10) + postcss: 8.5.10 - '@csstools/postcss-contrast-color-function@3.0.2(postcss@8.5.8)': + '@csstools/postcss-contrast-color-function@3.0.3(postcss@8.5.10)': dependencies: - '@csstools/css-color-parser': 4.0.2(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) + '@csstools/css-color-parser': 4.1.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.8) - '@csstools/utilities': 3.0.0(postcss@8.5.8) - postcss: 8.5.8 + '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.10) + '@csstools/utilities': 3.0.0(postcss@8.5.10) + postcss: 8.5.10 - '@csstools/postcss-exponential-functions@3.0.1(postcss@8.5.8)': + '@csstools/postcss-exponential-functions@3.0.2(postcss@8.5.10)': dependencies: - '@csstools/css-calc': 3.1.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) + '@csstools/css-calc': 3.2.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - postcss: 8.5.8 + postcss: 8.5.10 - '@csstools/postcss-font-format-keywords@5.0.0(postcss@8.5.8)': + '@csstools/postcss-font-format-keywords@5.0.0(postcss@8.5.10)': dependencies: - '@csstools/utilities': 3.0.0(postcss@8.5.8) - postcss: 8.5.8 + '@csstools/utilities': 3.0.0(postcss@8.5.10) + postcss: 8.5.10 postcss-value-parser: 4.2.0 - '@csstools/postcss-font-width-property@1.0.0(postcss@8.5.8)': + '@csstools/postcss-font-width-property@1.0.0(postcss@8.5.10)': dependencies: - '@csstools/utilities': 3.0.0(postcss@8.5.8) - postcss: 8.5.8 + '@csstools/utilities': 3.0.0(postcss@8.5.10) + postcss: 8.5.10 - '@csstools/postcss-gamut-mapping@3.0.2(postcss@8.5.8)': + '@csstools/postcss-gamut-mapping@3.0.3(postcss@8.5.10)': dependencies: - '@csstools/css-color-parser': 4.0.2(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) + '@csstools/css-color-parser': 4.1.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - postcss: 8.5.8 + postcss: 8.5.10 - '@csstools/postcss-gradients-interpolation-method@6.0.2(postcss@8.5.8)': + '@csstools/postcss-gradients-interpolation-method@6.0.3(postcss@8.5.10)': dependencies: - '@csstools/css-color-parser': 4.0.2(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) + '@csstools/css-color-parser': 4.1.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.8) - '@csstools/utilities': 3.0.0(postcss@8.5.8) - postcss: 8.5.8 + '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.10) + '@csstools/utilities': 3.0.0(postcss@8.5.10) + postcss: 8.5.10 - '@csstools/postcss-hwb-function@5.0.2(postcss@8.5.8)': + '@csstools/postcss-hwb-function@5.0.3(postcss@8.5.10)': dependencies: - '@csstools/css-color-parser': 4.0.2(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) + '@csstools/css-color-parser': 4.1.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.8) - '@csstools/utilities': 3.0.0(postcss@8.5.8) - postcss: 8.5.8 + '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.10) + '@csstools/utilities': 3.0.0(postcss@8.5.10) + postcss: 8.5.10 - '@csstools/postcss-ic-unit@5.0.0(postcss@8.5.8)': + '@csstools/postcss-ic-unit@5.0.0(postcss@8.5.10)': dependencies: - '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.8) - '@csstools/utilities': 3.0.0(postcss@8.5.8) - postcss: 8.5.8 + '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.10) + '@csstools/utilities': 3.0.0(postcss@8.5.10) + postcss: 8.5.10 postcss-value-parser: 4.2.0 - '@csstools/postcss-initial@3.0.0(postcss@8.5.8)': + '@csstools/postcss-initial@3.0.0(postcss@8.5.10)': dependencies: - postcss: 8.5.8 + postcss: 8.5.10 - '@csstools/postcss-is-pseudo-class@6.0.0(postcss@8.5.8)': + '@csstools/postcss-is-pseudo-class@6.0.0(postcss@8.5.10)': dependencies: '@csstools/selector-specificity': 6.0.0(postcss-selector-parser@7.1.1) - postcss: 8.5.8 + postcss: 8.5.10 postcss-selector-parser: 7.1.1 - '@csstools/postcss-light-dark-function@3.0.0(postcss@8.5.8)': + '@csstools/postcss-light-dark-function@3.0.0(postcss@8.5.10)': dependencies: '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.8) - '@csstools/utilities': 3.0.0(postcss@8.5.8) - postcss: 8.5.8 + '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.10) + '@csstools/utilities': 3.0.0(postcss@8.5.10) + postcss: 8.5.10 - '@csstools/postcss-logical-float-and-clear@4.0.0(postcss@8.5.8)': + '@csstools/postcss-logical-float-and-clear@4.0.0(postcss@8.5.10)': dependencies: - postcss: 8.5.8 + postcss: 8.5.10 - '@csstools/postcss-logical-overflow@3.0.0(postcss@8.5.8)': + '@csstools/postcss-logical-overflow@3.0.0(postcss@8.5.10)': dependencies: - postcss: 8.5.8 + postcss: 8.5.10 - '@csstools/postcss-logical-overscroll-behavior@3.0.0(postcss@8.5.8)': + '@csstools/postcss-logical-overscroll-behavior@3.0.0(postcss@8.5.10)': dependencies: - postcss: 8.5.8 + postcss: 8.5.10 - '@csstools/postcss-logical-resize@4.0.0(postcss@8.5.8)': + '@csstools/postcss-logical-resize@4.0.0(postcss@8.5.10)': dependencies: - postcss: 8.5.8 + postcss: 8.5.10 postcss-value-parser: 4.2.0 - '@csstools/postcss-logical-viewport-units@4.0.0(postcss@8.5.8)': + '@csstools/postcss-logical-viewport-units@4.0.0(postcss@8.5.10)': dependencies: '@csstools/css-tokenizer': 4.0.0 - '@csstools/utilities': 3.0.0(postcss@8.5.8) - postcss: 8.5.8 + '@csstools/utilities': 3.0.0(postcss@8.5.10) + postcss: 8.5.10 - '@csstools/postcss-media-minmax@3.0.1(postcss@8.5.8)': + '@csstools/postcss-media-minmax@3.0.2(postcss@8.5.10)': dependencies: - '@csstools/css-calc': 3.1.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) + '@csstools/css-calc': 3.2.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 '@csstools/media-query-list-parser': 5.0.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) - postcss: 8.5.8 + postcss: 8.5.10 - '@csstools/postcss-media-queries-aspect-ratio-number-values@4.0.0(postcss@8.5.8)': + '@csstools/postcss-media-queries-aspect-ratio-number-values@4.0.0(postcss@8.5.10)': dependencies: '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 '@csstools/media-query-list-parser': 5.0.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) - postcss: 8.5.8 + postcss: 8.5.10 - '@csstools/postcss-mixins@1.0.0(postcss@8.5.8)': + '@csstools/postcss-mixins@1.0.0(postcss@8.5.10)': dependencies: '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - postcss: 8.5.8 + postcss: 8.5.10 - '@csstools/postcss-nested-calc@5.0.0(postcss@8.5.8)': + '@csstools/postcss-nested-calc@5.0.0(postcss@8.5.10)': dependencies: - '@csstools/utilities': 3.0.0(postcss@8.5.8) - postcss: 8.5.8 + '@csstools/utilities': 3.0.0(postcss@8.5.10) + postcss: 8.5.10 postcss-value-parser: 4.2.0 - '@csstools/postcss-normalize-display-values@5.0.1(postcss@8.5.8)': + '@csstools/postcss-normalize-display-values@5.0.1(postcss@8.5.10)': dependencies: - postcss: 8.5.8 + postcss: 8.5.10 postcss-value-parser: 4.2.0 - '@csstools/postcss-oklab-function@5.0.2(postcss@8.5.8)': + '@csstools/postcss-oklab-function@5.0.3(postcss@8.5.10)': dependencies: - '@csstools/css-color-parser': 4.0.2(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) + '@csstools/css-color-parser': 4.1.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.8) - '@csstools/utilities': 3.0.0(postcss@8.5.8) - postcss: 8.5.8 + '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.10) + '@csstools/utilities': 3.0.0(postcss@8.5.10) + postcss: 8.5.10 - '@csstools/postcss-position-area-property@2.0.0(postcss@8.5.8)': + '@csstools/postcss-position-area-property@2.0.0(postcss@8.5.10)': dependencies: - postcss: 8.5.8 + postcss: 8.5.10 - '@csstools/postcss-progressive-custom-properties@5.0.0(postcss@8.5.8)': + '@csstools/postcss-progressive-custom-properties@5.0.0(postcss@8.5.10)': dependencies: - postcss: 8.5.8 + postcss: 8.5.10 postcss-value-parser: 4.2.0 - '@csstools/postcss-property-rule-prelude-list@2.0.0(postcss@8.5.8)': + '@csstools/postcss-property-rule-prelude-list@2.0.0(postcss@8.5.10)': dependencies: '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - postcss: 8.5.8 + postcss: 8.5.10 - '@csstools/postcss-random-function@3.0.1(postcss@8.5.8)': + '@csstools/postcss-random-function@3.0.2(postcss@8.5.10)': dependencies: - '@csstools/css-calc': 3.1.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) + '@csstools/css-calc': 3.2.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - postcss: 8.5.8 + postcss: 8.5.10 - '@csstools/postcss-relative-color-syntax@4.0.2(postcss@8.5.8)': + '@csstools/postcss-relative-color-syntax@4.0.3(postcss@8.5.10)': dependencies: - '@csstools/css-color-parser': 4.0.2(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) + '@csstools/css-color-parser': 4.1.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.8) - '@csstools/utilities': 3.0.0(postcss@8.5.8) - postcss: 8.5.8 + '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.10) + '@csstools/utilities': 3.0.0(postcss@8.5.10) + postcss: 8.5.10 - '@csstools/postcss-scope-pseudo-class@5.0.0(postcss@8.5.8)': + '@csstools/postcss-scope-pseudo-class@5.0.0(postcss@8.5.10)': dependencies: - postcss: 8.5.8 + postcss: 8.5.10 postcss-selector-parser: 7.1.1 - '@csstools/postcss-sign-functions@2.0.1(postcss@8.5.8)': + '@csstools/postcss-sign-functions@2.0.2(postcss@8.5.10)': dependencies: - '@csstools/css-calc': 3.1.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) + '@csstools/css-calc': 3.2.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - postcss: 8.5.8 + postcss: 8.5.10 - '@csstools/postcss-stepped-value-functions@5.0.1(postcss@8.5.8)': + '@csstools/postcss-stepped-value-functions@5.0.2(postcss@8.5.10)': dependencies: - '@csstools/css-calc': 3.1.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) + '@csstools/css-calc': 3.2.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - postcss: 8.5.8 + postcss: 8.5.10 - '@csstools/postcss-syntax-descriptor-syntax-production@2.0.0(postcss@8.5.8)': + '@csstools/postcss-syntax-descriptor-syntax-production@2.0.0(postcss@8.5.10)': dependencies: '@csstools/css-tokenizer': 4.0.0 - postcss: 8.5.8 + postcss: 8.5.10 - '@csstools/postcss-system-ui-font-family@2.0.0(postcss@8.5.8)': + '@csstools/postcss-system-ui-font-family@2.0.0(postcss@8.5.10)': dependencies: '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - postcss: 8.5.8 + postcss: 8.5.10 - '@csstools/postcss-text-decoration-shorthand@5.0.3(postcss@8.5.8)': + '@csstools/postcss-text-decoration-shorthand@5.0.3(postcss@8.5.10)': dependencies: '@csstools/color-helpers': 6.0.2 - postcss: 8.5.8 + postcss: 8.5.10 postcss-value-parser: 4.2.0 - '@csstools/postcss-trigonometric-functions@5.0.1(postcss@8.5.8)': + '@csstools/postcss-trigonometric-functions@5.0.2(postcss@8.5.10)': dependencies: - '@csstools/css-calc': 3.1.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) + '@csstools/css-calc': 3.2.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - postcss: 8.5.8 + postcss: 8.5.10 - '@csstools/postcss-unset-value@5.0.0(postcss@8.5.8)': + '@csstools/postcss-unset-value@5.0.0(postcss@8.5.10)': dependencies: - postcss: 8.5.8 + postcss: 8.5.10 '@csstools/selector-resolve-nested@4.0.0(postcss-selector-parser@7.1.1)': dependencies: @@ -8037,174 +8183,247 @@ snapshots: dependencies: postcss-selector-parser: 7.1.1 - '@csstools/utilities@3.0.0(postcss@8.5.8)': + '@csstools/utilities@3.0.0(postcss@8.5.10)': dependencies: - postcss: 8.5.8 + postcss: 8.5.10 '@esbuild/aix-ppc64@0.25.12': optional: true - '@esbuild/aix-ppc64@0.27.4': + '@esbuild/aix-ppc64@0.27.5': + optional: true + + '@esbuild/aix-ppc64@0.28.0': optional: true '@esbuild/android-arm64@0.25.12': optional: true - '@esbuild/android-arm64@0.27.4': + '@esbuild/android-arm64@0.27.5': + optional: true + + '@esbuild/android-arm64@0.28.0': optional: true '@esbuild/android-arm@0.25.12': optional: true - '@esbuild/android-arm@0.27.4': + '@esbuild/android-arm@0.27.5': + optional: true + + '@esbuild/android-arm@0.28.0': optional: true '@esbuild/android-x64@0.25.12': optional: true - '@esbuild/android-x64@0.27.4': + '@esbuild/android-x64@0.27.5': + optional: true + + '@esbuild/android-x64@0.28.0': optional: true '@esbuild/darwin-arm64@0.25.12': optional: true - '@esbuild/darwin-arm64@0.27.4': + '@esbuild/darwin-arm64@0.27.5': + optional: true + + '@esbuild/darwin-arm64@0.28.0': optional: true '@esbuild/darwin-x64@0.25.12': optional: true - '@esbuild/darwin-x64@0.27.4': + '@esbuild/darwin-x64@0.27.5': + optional: true + + '@esbuild/darwin-x64@0.28.0': optional: true '@esbuild/freebsd-arm64@0.25.12': optional: true - '@esbuild/freebsd-arm64@0.27.4': + '@esbuild/freebsd-arm64@0.27.5': + optional: true + + '@esbuild/freebsd-arm64@0.28.0': optional: true '@esbuild/freebsd-x64@0.25.12': optional: true - '@esbuild/freebsd-x64@0.27.4': + '@esbuild/freebsd-x64@0.27.5': + optional: true + + '@esbuild/freebsd-x64@0.28.0': optional: true '@esbuild/linux-arm64@0.25.12': optional: true - '@esbuild/linux-arm64@0.27.4': + '@esbuild/linux-arm64@0.27.5': + optional: true + + '@esbuild/linux-arm64@0.28.0': optional: true '@esbuild/linux-arm@0.25.12': optional: true - '@esbuild/linux-arm@0.27.4': + '@esbuild/linux-arm@0.27.5': + optional: true + + '@esbuild/linux-arm@0.28.0': optional: true '@esbuild/linux-ia32@0.25.12': optional: true - '@esbuild/linux-ia32@0.27.4': + '@esbuild/linux-ia32@0.27.5': + optional: true + + '@esbuild/linux-ia32@0.28.0': optional: true '@esbuild/linux-loong64@0.25.12': optional: true - '@esbuild/linux-loong64@0.27.4': + '@esbuild/linux-loong64@0.27.5': + optional: true + + '@esbuild/linux-loong64@0.28.0': optional: true '@esbuild/linux-mips64el@0.25.12': optional: true - '@esbuild/linux-mips64el@0.27.4': + '@esbuild/linux-mips64el@0.27.5': + optional: true + + '@esbuild/linux-mips64el@0.28.0': optional: true '@esbuild/linux-ppc64@0.25.12': optional: true - '@esbuild/linux-ppc64@0.27.4': + '@esbuild/linux-ppc64@0.27.5': + optional: true + + '@esbuild/linux-ppc64@0.28.0': optional: true '@esbuild/linux-riscv64@0.25.12': optional: true - '@esbuild/linux-riscv64@0.27.4': + '@esbuild/linux-riscv64@0.27.5': + optional: true + + '@esbuild/linux-riscv64@0.28.0': optional: true '@esbuild/linux-s390x@0.25.12': optional: true - '@esbuild/linux-s390x@0.27.4': + '@esbuild/linux-s390x@0.27.5': + optional: true + + '@esbuild/linux-s390x@0.28.0': optional: true '@esbuild/linux-x64@0.25.12': optional: true - '@esbuild/linux-x64@0.27.4': + '@esbuild/linux-x64@0.27.5': + optional: true + + '@esbuild/linux-x64@0.28.0': optional: true '@esbuild/netbsd-arm64@0.25.12': optional: true - '@esbuild/netbsd-arm64@0.27.4': + '@esbuild/netbsd-arm64@0.27.5': + optional: true + + '@esbuild/netbsd-arm64@0.28.0': optional: true '@esbuild/netbsd-x64@0.25.12': optional: true - '@esbuild/netbsd-x64@0.27.4': + '@esbuild/netbsd-x64@0.27.5': + optional: true + + '@esbuild/netbsd-x64@0.28.0': optional: true '@esbuild/openbsd-arm64@0.25.12': optional: true - '@esbuild/openbsd-arm64@0.27.4': + '@esbuild/openbsd-arm64@0.27.5': + optional: true + + '@esbuild/openbsd-arm64@0.28.0': optional: true '@esbuild/openbsd-x64@0.25.12': optional: true - '@esbuild/openbsd-x64@0.27.4': + '@esbuild/openbsd-x64@0.27.5': + optional: true + + '@esbuild/openbsd-x64@0.28.0': optional: true '@esbuild/openharmony-arm64@0.25.12': optional: true - '@esbuild/openharmony-arm64@0.27.4': + '@esbuild/openharmony-arm64@0.27.5': + optional: true + + '@esbuild/openharmony-arm64@0.28.0': optional: true '@esbuild/sunos-x64@0.25.12': optional: true - '@esbuild/sunos-x64@0.27.4': + '@esbuild/sunos-x64@0.27.5': + optional: true + + '@esbuild/sunos-x64@0.28.0': optional: true '@esbuild/win32-arm64@0.25.12': optional: true - '@esbuild/win32-arm64@0.27.4': + '@esbuild/win32-arm64@0.27.5': + optional: true + + '@esbuild/win32-arm64@0.28.0': optional: true '@esbuild/win32-ia32@0.25.12': optional: true - '@esbuild/win32-ia32@0.27.4': + '@esbuild/win32-ia32@0.27.5': + optional: true + + '@esbuild/win32-ia32@0.28.0': optional: true '@esbuild/win32-x64@0.25.12': optional: true - '@esbuild/win32-x64@0.27.4': + '@esbuild/win32-x64@0.27.5': optional: true - '@eslint-community/eslint-utils@4.9.0(eslint@9.39.4(jiti@2.4.2))': - dependencies: - eslint: 9.39.4(jiti@2.4.2) - eslint-visitor-keys: 3.4.3 + '@esbuild/win32-x64@0.28.0': + optional: true - '@eslint-community/eslint-utils@4.9.1(eslint@9.39.4(jiti@2.4.2))': + '@eslint-community/eslint-utils@4.9.1(eslint@9.39.4(jiti@2.6.1))': dependencies: - eslint: 9.39.4(jiti@2.4.2) + eslint: 9.39.4(jiti@2.6.1) eslint-visitor-keys: 3.4.3 '@eslint-community/regexpp@4.12.2': {} @@ -8324,17 +8543,17 @@ snapshots: dependencies: '@hapi/hoek': 11.0.7 - '@histoire/app@1.0.0-beta.1(vite@7.3.1(@types/node@24.12.0)(jiti@2.4.2)(lightningcss@1.32.0)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.31.6)(yaml@2.8.3))': + '@histoire/app@1.0.0-beta.1(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))': dependencies: - '@histoire/controls': 1.0.0-beta.1(vite@7.3.1(@types/node@24.12.0)(jiti@2.4.2)(lightningcss@1.32.0)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.31.6)(yaml@2.8.3)) - '@histoire/shared': 1.0.0-beta.1(vite@7.3.1(@types/node@24.12.0)(jiti@2.4.2)(lightningcss@1.32.0)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.31.6)(yaml@2.8.3)) + '@histoire/controls': 1.0.0-beta.1(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) + '@histoire/shared': 1.0.0-beta.1(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) '@histoire/vendors': 1.0.0-beta.1 fuse.js: 7.1.0 shiki: 3.2.1 transitivePeerDependencies: - vite - '@histoire/controls@1.0.0-beta.1(vite@7.3.1(@types/node@24.12.0)(jiti@2.4.2)(lightningcss@1.32.0)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.31.6)(yaml@2.8.3))': + '@histoire/controls@1.0.0-beta.1(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))': dependencies: '@codemirror/commands': 6.8.1 '@codemirror/lang-json': 6.0.1 @@ -8343,17 +8562,17 @@ snapshots: '@codemirror/state': 6.5.2 '@codemirror/theme-one-dark': 6.1.2 '@codemirror/view': 6.36.5 - '@histoire/shared': 1.0.0-beta.1(vite@7.3.1(@types/node@24.12.0)(jiti@2.4.2)(lightningcss@1.32.0)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.31.6)(yaml@2.8.3)) + '@histoire/shared': 1.0.0-beta.1(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) '@histoire/vendors': 1.0.0-beta.1 transitivePeerDependencies: - vite - '@histoire/plugin-screenshot@1.0.0-beta.1(histoire@1.0.0-beta.1(@types/node@24.12.0)(lightningcss@1.32.0)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.31.6)(vite@7.3.1(@types/node@24.12.0)(jiti@2.4.2)(lightningcss@1.32.0)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.31.6)(yaml@2.8.3))(yaml@2.8.3))(typescript@5.9.3)': + '@histoire/plugin-screenshot@1.0.0-beta.1(histoire@1.0.0-beta.1(@types/node@24.12.2)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(yaml@2.8.3))(typescript@5.9.3)': dependencies: capture-website: 4.2.0(typescript@5.9.3) - defu: 6.1.4 + defu: 6.1.7 fs-extra: 11.2.0 - histoire: 1.0.0-beta.1(@types/node@24.12.0)(lightningcss@1.32.0)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.31.6)(vite@7.3.1(@types/node@24.12.0)(jiti@2.4.2)(lightningcss@1.32.0)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.31.6)(yaml@2.8.3))(yaml@2.8.3) + histoire: 1.0.0-beta.1(@types/node@24.12.2)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(yaml@2.8.3) pathe: 1.1.2 transitivePeerDependencies: - bare-buffer @@ -8362,21 +8581,21 @@ snapshots: - typescript - utf-8-validate - '@histoire/plugin-vue@1.0.0-beta.1(histoire@1.0.0-beta.1(@types/node@24.12.0)(lightningcss@1.32.0)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.31.6)(vite@7.3.1(@types/node@24.12.0)(jiti@2.4.2)(lightningcss@1.32.0)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.31.6)(yaml@2.8.3))(yaml@2.8.3))(vite@7.3.1(@types/node@24.12.0)(jiti@2.4.2)(lightningcss@1.32.0)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.31.6)(yaml@2.8.3))(vue@3.5.27(typescript@5.9.3))': + '@histoire/plugin-vue@1.0.0-beta.1(histoire@1.0.0-beta.1(@types/node@24.12.2)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(yaml@2.8.3))(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(vue@3.5.27(typescript@5.9.3))': dependencies: - '@histoire/controls': 1.0.0-beta.1(vite@7.3.1(@types/node@24.12.0)(jiti@2.4.2)(lightningcss@1.32.0)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.31.6)(yaml@2.8.3)) - '@histoire/shared': 1.0.0-beta.1(vite@7.3.1(@types/node@24.12.0)(jiti@2.4.2)(lightningcss@1.32.0)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.31.6)(yaml@2.8.3)) + '@histoire/controls': 1.0.0-beta.1(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) + '@histoire/shared': 1.0.0-beta.1(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) '@histoire/vendors': 1.0.0-beta.1 change-case: 5.4.4 globby: 14.1.0 - histoire: 1.0.0-beta.1(@types/node@24.12.0)(lightningcss@1.32.0)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.31.6)(vite@7.3.1(@types/node@24.12.0)(jiti@2.4.2)(lightningcss@1.32.0)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.31.6)(yaml@2.8.3))(yaml@2.8.3) + histoire: 1.0.0-beta.1(@types/node@24.12.2)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(yaml@2.8.3) launch-editor: 2.10.0 pathe: 1.1.2 vue: 3.5.27(typescript@5.9.3) transitivePeerDependencies: - vite - '@histoire/shared@1.0.0-beta.1(vite@7.3.1(@types/node@24.12.0)(jiti@2.4.2)(lightningcss@1.32.0)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.31.6)(yaml@2.8.3))': + '@histoire/shared@1.0.0-beta.1(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))': dependencies: '@histoire/vendors': 1.0.0-beta.1 '@types/fs-extra': 11.0.4 @@ -8384,7 +8603,7 @@ snapshots: chokidar: 4.0.3 pathe: 1.1.2 picocolors: 1.1.1 - vite: 7.3.1(@types/node@24.12.0)(jiti@2.4.2)(lightningcss@1.32.0)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.31.6)(yaml@2.8.3) + vite: 7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) '@histoire/vendors@1.0.0-beta.1': {} @@ -8403,8 +8622,8 @@ snapshots: '@intlify/bundle-utils@11.0.3(vue-i18n@11.2.8(vue@3.5.27(typescript@5.9.3)))': dependencies: - '@intlify/message-compiler': 11.2.2 - '@intlify/shared': 11.2.2 + '@intlify/message-compiler': 11.2.8 + '@intlify/shared': 11.2.8 acorn: 8.15.0 esbuild: 0.25.12 escodegen: 2.1.0 @@ -8420,29 +8639,22 @@ snapshots: '@intlify/message-compiler': 11.2.8 '@intlify/shared': 11.2.8 - '@intlify/message-compiler@11.2.2': - dependencies: - '@intlify/shared': 11.2.2 - source-map-js: 1.2.1 - '@intlify/message-compiler@11.2.8': dependencies: '@intlify/shared': 11.2.8 source-map-js: 1.2.1 - '@intlify/shared@11.2.2': {} - '@intlify/shared@11.2.8': {} - '@intlify/unplugin-vue-i18n@11.0.3(@vue/compiler-dom@3.5.27)(eslint@9.39.4(jiti@2.4.2))(rollup@4.60.0)(typescript@5.9.3)(vue-i18n@11.2.8(vue@3.5.27(typescript@5.9.3)))(vue@3.5.27(typescript@5.9.3))': + '@intlify/unplugin-vue-i18n@11.0.3(@vue/compiler-dom@3.5.27)(eslint@9.39.4(jiti@2.6.1))(rollup@4.60.2)(typescript@5.9.3)(vue-i18n@11.2.8(vue@3.5.27(typescript@5.9.3)))(vue@3.5.27(typescript@5.9.3))': dependencies: - '@eslint-community/eslint-utils': 4.9.0(eslint@9.39.4(jiti@2.4.2)) + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@2.6.1)) '@intlify/bundle-utils': 11.0.3(vue-i18n@11.2.8(vue@3.5.27(typescript@5.9.3))) - '@intlify/shared': 11.2.2 - '@intlify/vue-i18n-extensions': 8.0.0(@intlify/shared@11.2.2)(@vue/compiler-dom@3.5.27)(vue-i18n@11.2.8(vue@3.5.27(typescript@5.9.3)))(vue@3.5.27(typescript@5.9.3)) - '@rollup/pluginutils': 5.1.3(rollup@4.60.0) - '@typescript-eslint/scope-manager': 8.49.0 - '@typescript-eslint/typescript-estree': 8.49.0(typescript@5.9.3) + '@intlify/shared': 11.2.8 + '@intlify/vue-i18n-extensions': 8.0.0(@intlify/shared@11.2.8)(@vue/compiler-dom@3.5.27)(vue-i18n@11.2.8(vue@3.5.27(typescript@5.9.3)))(vue@3.5.27(typescript@5.9.3)) + '@rollup/pluginutils': 5.1.3(rollup@4.60.2) + '@typescript-eslint/scope-manager': 8.58.0 + '@typescript-eslint/typescript-estree': 8.58.0(typescript@5.9.3) debug: 4.4.3 fast-glob: 3.3.3 pathe: 2.0.3 @@ -8458,11 +8670,11 @@ snapshots: - supports-color - typescript - '@intlify/vue-i18n-extensions@8.0.0(@intlify/shared@11.2.2)(@vue/compiler-dom@3.5.27)(vue-i18n@11.2.8(vue@3.5.27(typescript@5.9.3)))(vue@3.5.27(typescript@5.9.3))': + '@intlify/vue-i18n-extensions@8.0.0(@intlify/shared@11.2.8)(@vue/compiler-dom@3.5.27)(vue-i18n@11.2.8(vue@3.5.27(typescript@5.9.3)))(vue@3.5.27(typescript@5.9.3))': dependencies: '@babel/parser': 7.28.5 optionalDependencies: - '@intlify/shared': 11.2.2 + '@intlify/shared': 11.2.8 '@vue/compiler-dom': 3.5.27 vue: 3.5.27(typescript@5.9.3) vue-i18n: 11.2.8(vue@3.5.27(typescript@5.9.3)) @@ -8471,7 +8683,7 @@ snapshots: dependencies: string-width: 5.1.2 string-width-cjs: string-width@4.2.3 - strip-ansi: 7.1.0 + strip-ansi: 7.2.0 strip-ansi-cjs: strip-ansi@6.0.1 wrap-ansi: 8.1.0 wrap-ansi-cjs: wrap-ansi@7.0.0 @@ -8547,6 +8759,29 @@ snapshots: '@one-ini/wasm@0.1.1': {} + '@otplib/core@12.0.1': {} + + '@otplib/plugin-crypto@12.0.1': + dependencies: + '@otplib/core': 12.0.1 + + '@otplib/plugin-thirty-two@12.0.1': + dependencies: + '@otplib/core': 12.0.1 + thirty-two: 1.0.2 + + '@otplib/preset-default@12.0.1': + dependencies: + '@otplib/core': 12.0.1 + '@otplib/plugin-crypto': 12.0.1 + '@otplib/plugin-thirty-two': 12.0.1 + + '@otplib/preset-v11@12.0.1': + dependencies: + '@otplib/core': 12.0.1 + '@otplib/plugin-crypto': 12.0.1 + '@otplib/plugin-thirty-two': 12.0.1 + '@parcel/watcher-android-arm64@2.5.1': optional: true @@ -8662,130 +8897,130 @@ snapshots: '@remusao/trie@1.5.0': {} - '@rolldown/pluginutils@1.0.0-rc.2': {} + '@rolldown/pluginutils@1.0.0-rc.13': {} - '@rollup/plugin-babel@5.3.1(@babel/core@7.26.0)(rollup@4.60.0)': + '@rollup/plugin-babel@5.3.1(@babel/core@7.26.0)(rollup@4.60.2)': dependencies: '@babel/core': 7.26.0 '@babel/helper-module-imports': 7.25.9 - '@rollup/pluginutils': 3.1.0(rollup@4.60.0) - rollup: 4.60.0 + '@rollup/pluginutils': 3.1.0(rollup@4.60.2) + rollup: 4.60.2 transitivePeerDependencies: - supports-color - '@rollup/plugin-node-resolve@15.2.3(rollup@4.60.0)': + '@rollup/plugin-node-resolve@15.2.3(rollup@4.60.2)': dependencies: - '@rollup/pluginutils': 5.1.3(rollup@4.60.0) + '@rollup/pluginutils': 5.1.3(rollup@4.60.2) '@types/resolve': 1.20.2 deepmerge: 4.3.1 is-builtin-module: 3.2.1 is-module: 1.0.0 resolve: 1.22.8 optionalDependencies: - rollup: 4.60.0 + rollup: 4.60.2 - '@rollup/plugin-replace@2.4.2(rollup@4.60.0)': + '@rollup/plugin-replace@2.4.2(rollup@4.60.2)': dependencies: - '@rollup/pluginutils': 3.1.0(rollup@4.60.0) + '@rollup/pluginutils': 3.1.0(rollup@4.60.2) magic-string: 0.25.9 - rollup: 4.60.0 + rollup: 4.60.2 - '@rollup/plugin-terser@0.4.4(rollup@4.60.0)': + '@rollup/plugin-terser@0.4.4(rollup@4.60.2)': dependencies: - serialize-javascript: 7.0.3 + serialize-javascript: 7.0.5 smob: 1.5.0 terser: 5.31.6 optionalDependencies: - rollup: 4.60.0 + rollup: 4.60.2 - '@rollup/pluginutils@3.1.0(rollup@4.60.0)': + '@rollup/pluginutils@3.1.0(rollup@4.60.2)': dependencies: '@types/estree': 0.0.39 estree-walker: 1.0.1 picomatch: 2.3.2 - rollup: 4.60.0 + rollup: 4.60.2 - '@rollup/pluginutils@5.1.3(rollup@4.60.0)': + '@rollup/pluginutils@5.1.3(rollup@4.60.2)': dependencies: '@types/estree': 1.0.8 estree-walker: 2.0.2 picomatch: 4.0.4 optionalDependencies: - rollup: 4.60.0 + rollup: 4.60.2 - '@rollup/rollup-android-arm-eabi@4.60.0': + '@rollup/rollup-android-arm-eabi@4.60.2': optional: true - '@rollup/rollup-android-arm64@4.60.0': + '@rollup/rollup-android-arm64@4.60.2': optional: true - '@rollup/rollup-darwin-arm64@4.60.0': + '@rollup/rollup-darwin-arm64@4.60.2': optional: true - '@rollup/rollup-darwin-x64@4.60.0': + '@rollup/rollup-darwin-x64@4.60.2': optional: true - '@rollup/rollup-freebsd-arm64@4.60.0': + '@rollup/rollup-freebsd-arm64@4.60.2': optional: true - '@rollup/rollup-freebsd-x64@4.60.0': + '@rollup/rollup-freebsd-x64@4.60.2': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.60.0': + '@rollup/rollup-linux-arm-gnueabihf@4.60.2': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.60.0': + '@rollup/rollup-linux-arm-musleabihf@4.60.2': optional: true - '@rollup/rollup-linux-arm64-gnu@4.60.0': + '@rollup/rollup-linux-arm64-gnu@4.60.2': optional: true - '@rollup/rollup-linux-arm64-musl@4.60.0': + '@rollup/rollup-linux-arm64-musl@4.60.2': optional: true - '@rollup/rollup-linux-loong64-gnu@4.60.0': + '@rollup/rollup-linux-loong64-gnu@4.60.2': optional: true - '@rollup/rollup-linux-loong64-musl@4.60.0': + '@rollup/rollup-linux-loong64-musl@4.60.2': optional: true - '@rollup/rollup-linux-ppc64-gnu@4.60.0': + '@rollup/rollup-linux-ppc64-gnu@4.60.2': optional: true - '@rollup/rollup-linux-ppc64-musl@4.60.0': + '@rollup/rollup-linux-ppc64-musl@4.60.2': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.60.0': + '@rollup/rollup-linux-riscv64-gnu@4.60.2': optional: true - '@rollup/rollup-linux-riscv64-musl@4.60.0': + '@rollup/rollup-linux-riscv64-musl@4.60.2': optional: true - '@rollup/rollup-linux-s390x-gnu@4.60.0': + '@rollup/rollup-linux-s390x-gnu@4.60.2': optional: true - '@rollup/rollup-linux-x64-gnu@4.60.0': + '@rollup/rollup-linux-x64-gnu@4.60.2': optional: true - '@rollup/rollup-linux-x64-musl@4.60.0': + '@rollup/rollup-linux-x64-musl@4.60.2': optional: true - '@rollup/rollup-openbsd-x64@4.60.0': + '@rollup/rollup-openbsd-x64@4.60.2': optional: true - '@rollup/rollup-openharmony-arm64@4.60.0': + '@rollup/rollup-openharmony-arm64@4.60.2': optional: true - '@rollup/rollup-win32-arm64-msvc@4.60.0': + '@rollup/rollup-win32-arm64-msvc@4.60.2': optional: true - '@rollup/rollup-win32-ia32-msvc@4.60.0': + '@rollup/rollup-win32-ia32-msvc@4.60.2': optional: true - '@rollup/rollup-win32-x64-gnu@4.60.0': + '@rollup/rollup-win32-x64-gnu@4.60.2': optional: true - '@rollup/rollup-win32-x64-msvc@4.60.0': + '@rollup/rollup-win32-x64-msvc@4.60.2': optional: true '@sentry-internal/browser-utils@10.36.0': @@ -8929,8 +9164,6 @@ snapshots: '@sindresorhus/merge-streams@4.0.0': {} - '@standard-schema/spec@1.0.0': {} - '@standard-schema/spec@1.1.0': {} '@surma/rollup-plugin-off-main-thread@2.2.3': @@ -8940,7 +9173,7 @@ snapshots: magic-string: 0.25.9 string.prototype.matchall: 4.0.11 - '@tailwindcss/node@4.2.2': + '@tailwindcss/node@4.2.4': dependencies: '@jridgewell/remapping': 2.3.5 enhanced-resolve: 5.20.0 @@ -8948,65 +9181,65 @@ snapshots: lightningcss: 1.32.0 magic-string: 0.30.21 source-map-js: 1.2.1 - tailwindcss: 4.2.2 + tailwindcss: 4.2.4 - '@tailwindcss/oxide-android-arm64@4.2.2': + '@tailwindcss/oxide-android-arm64@4.2.4': optional: true - '@tailwindcss/oxide-darwin-arm64@4.2.2': + '@tailwindcss/oxide-darwin-arm64@4.2.4': optional: true - '@tailwindcss/oxide-darwin-x64@4.2.2': + '@tailwindcss/oxide-darwin-x64@4.2.4': optional: true - '@tailwindcss/oxide-freebsd-x64@4.2.2': + '@tailwindcss/oxide-freebsd-x64@4.2.4': optional: true - '@tailwindcss/oxide-linux-arm-gnueabihf@4.2.2': + '@tailwindcss/oxide-linux-arm-gnueabihf@4.2.4': optional: true - '@tailwindcss/oxide-linux-arm64-gnu@4.2.2': + '@tailwindcss/oxide-linux-arm64-gnu@4.2.4': optional: true - '@tailwindcss/oxide-linux-arm64-musl@4.2.2': + '@tailwindcss/oxide-linux-arm64-musl@4.2.4': optional: true - '@tailwindcss/oxide-linux-x64-gnu@4.2.2': + '@tailwindcss/oxide-linux-x64-gnu@4.2.4': optional: true - '@tailwindcss/oxide-linux-x64-musl@4.2.2': + '@tailwindcss/oxide-linux-x64-musl@4.2.4': optional: true - '@tailwindcss/oxide-wasm32-wasi@4.2.2': + '@tailwindcss/oxide-wasm32-wasi@4.2.4': optional: true - '@tailwindcss/oxide-win32-arm64-msvc@4.2.2': + '@tailwindcss/oxide-win32-arm64-msvc@4.2.4': optional: true - '@tailwindcss/oxide-win32-x64-msvc@4.2.2': + '@tailwindcss/oxide-win32-x64-msvc@4.2.4': optional: true - '@tailwindcss/oxide@4.2.2': + '@tailwindcss/oxide@4.2.4': optionalDependencies: - '@tailwindcss/oxide-android-arm64': 4.2.2 - '@tailwindcss/oxide-darwin-arm64': 4.2.2 - '@tailwindcss/oxide-darwin-x64': 4.2.2 - '@tailwindcss/oxide-freebsd-x64': 4.2.2 - '@tailwindcss/oxide-linux-arm-gnueabihf': 4.2.2 - '@tailwindcss/oxide-linux-arm64-gnu': 4.2.2 - '@tailwindcss/oxide-linux-arm64-musl': 4.2.2 - '@tailwindcss/oxide-linux-x64-gnu': 4.2.2 - '@tailwindcss/oxide-linux-x64-musl': 4.2.2 - '@tailwindcss/oxide-wasm32-wasi': 4.2.2 - '@tailwindcss/oxide-win32-arm64-msvc': 4.2.2 - '@tailwindcss/oxide-win32-x64-msvc': 4.2.2 + '@tailwindcss/oxide-android-arm64': 4.2.4 + '@tailwindcss/oxide-darwin-arm64': 4.2.4 + '@tailwindcss/oxide-darwin-x64': 4.2.4 + '@tailwindcss/oxide-freebsd-x64': 4.2.4 + '@tailwindcss/oxide-linux-arm-gnueabihf': 4.2.4 + '@tailwindcss/oxide-linux-arm64-gnu': 4.2.4 + '@tailwindcss/oxide-linux-arm64-musl': 4.2.4 + '@tailwindcss/oxide-linux-x64-gnu': 4.2.4 + '@tailwindcss/oxide-linux-x64-musl': 4.2.4 + '@tailwindcss/oxide-wasm32-wasi': 4.2.4 + '@tailwindcss/oxide-win32-arm64-msvc': 4.2.4 + '@tailwindcss/oxide-win32-x64-msvc': 4.2.4 - '@tailwindcss/vite@4.2.2(vite@7.3.1(@types/node@24.12.0)(jiti@2.4.2)(lightningcss@1.32.0)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.31.6)(yaml@2.8.3))': + '@tailwindcss/vite@4.2.4(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))': dependencies: - '@tailwindcss/node': 4.2.2 - '@tailwindcss/oxide': 4.2.2 - tailwindcss: 4.2.2 - vite: 7.3.1(@types/node@24.12.0)(jiti@2.4.2)(lightningcss@1.32.0)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.31.6)(yaml@2.8.3) + '@tailwindcss/node': 4.2.4 + '@tailwindcss/oxide': 4.2.4 + tailwindcss: 4.2.4 + vite: 7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) '@tiptap/core@3.17.0(@tiptap/pm@3.17.0)': dependencies: @@ -9231,7 +9464,7 @@ snapshots: '@types/fs-extra@11.0.4': dependencies: '@types/jsonfile': 6.1.4 - '@types/node': 24.12.0 + '@types/node': 24.12.2 '@types/hast@3.0.4': dependencies: @@ -9243,7 +9476,7 @@ snapshots: '@types/jsonfile@6.1.4': dependencies: - '@types/node': 24.12.0 + '@types/node': 24.12.2 '@types/linkify-it@5.0.0': {} @@ -9260,7 +9493,7 @@ snapshots: '@types/minimist@1.2.5': {} - '@types/node@24.12.0': + '@types/node@24.12.2': dependencies: undici-types: 7.16.0 @@ -9284,173 +9517,158 @@ snapshots: '@types/ws@8.18.1': dependencies: - '@types/node': 24.12.0 + '@types/node': 24.12.2 '@types/yauzl@2.10.3': dependencies: - '@types/node': 24.12.0 + '@types/node': 24.12.2 optional: true - '@typescript-eslint/eslint-plugin@8.56.0(@typescript-eslint/parser@8.56.0(eslint@9.39.4(jiti@2.4.2))(typescript@5.9.3))(eslint@9.39.4(jiti@2.4.2))(typescript@5.9.3)': + '@typescript-eslint/eslint-plugin@8.56.0(@typescript-eslint/parser@8.56.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': dependencies: '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 8.56.0(eslint@9.39.4(jiti@2.4.2))(typescript@5.9.3) + '@typescript-eslint/parser': 8.56.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) '@typescript-eslint/scope-manager': 8.56.0 - '@typescript-eslint/type-utils': 8.56.0(eslint@9.39.4(jiti@2.4.2))(typescript@5.9.3) - '@typescript-eslint/utils': 8.56.0(eslint@9.39.4(jiti@2.4.2))(typescript@5.9.3) + '@typescript-eslint/type-utils': 8.56.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/utils': 8.56.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) '@typescript-eslint/visitor-keys': 8.56.0 - eslint: 9.39.4(jiti@2.4.2) + eslint: 9.39.4(jiti@2.6.1) ignore: 7.0.5 natural-compare: 1.4.0 - ts-api-utils: 2.4.0(typescript@5.9.3) + ts-api-utils: 2.5.0(typescript@5.9.3) typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/eslint-plugin@8.57.2(@typescript-eslint/parser@8.57.2(eslint@9.39.4(jiti@2.4.2))(typescript@5.9.3))(eslint@9.39.4(jiti@2.4.2))(typescript@5.9.3)': + '@typescript-eslint/eslint-plugin@8.59.0(@typescript-eslint/parser@8.59.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': dependencies: '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 8.57.2(eslint@9.39.4(jiti@2.4.2))(typescript@5.9.3) - '@typescript-eslint/scope-manager': 8.57.2 - '@typescript-eslint/type-utils': 8.57.2(eslint@9.39.4(jiti@2.4.2))(typescript@5.9.3) - '@typescript-eslint/utils': 8.57.2(eslint@9.39.4(jiti@2.4.2))(typescript@5.9.3) - '@typescript-eslint/visitor-keys': 8.57.2 - eslint: 9.39.4(jiti@2.4.2) + '@typescript-eslint/parser': 8.59.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.59.0 + '@typescript-eslint/type-utils': 8.59.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/utils': 8.59.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.59.0 + eslint: 9.39.4(jiti@2.6.1) ignore: 7.0.5 natural-compare: 1.4.0 - ts-api-utils: 2.4.0(typescript@5.9.3) + ts-api-utils: 2.5.0(typescript@5.9.3) typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.56.0(eslint@9.39.4(jiti@2.4.2))(typescript@5.9.3)': + '@typescript-eslint/parser@8.56.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': dependencies: '@typescript-eslint/scope-manager': 8.56.0 '@typescript-eslint/types': 8.56.0 '@typescript-eslint/typescript-estree': 8.56.0(typescript@5.9.3) '@typescript-eslint/visitor-keys': 8.56.0 debug: 4.4.3 - eslint: 9.39.4(jiti@2.4.2) + eslint: 9.39.4(jiti@2.6.1) typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.57.2(eslint@9.39.4(jiti@2.4.2))(typescript@5.9.3)': + '@typescript-eslint/parser@8.59.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': dependencies: - '@typescript-eslint/scope-manager': 8.57.2 - '@typescript-eslint/types': 8.57.2 - '@typescript-eslint/typescript-estree': 8.57.2(typescript@5.9.3) - '@typescript-eslint/visitor-keys': 8.57.2 - debug: 4.4.3 - eslint: 9.39.4(jiti@2.4.2) - typescript: 5.9.3 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/project-service@8.49.0(typescript@5.9.3)': - dependencies: - '@typescript-eslint/tsconfig-utils': 8.57.1(typescript@5.9.3) - '@typescript-eslint/types': 8.57.1 + '@typescript-eslint/scope-manager': 8.59.0 + '@typescript-eslint/types': 8.59.0 + '@typescript-eslint/typescript-estree': 8.59.0(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.59.0 debug: 4.4.3 + eslint: 9.39.4(jiti@2.6.1) typescript: 5.9.3 transitivePeerDependencies: - supports-color '@typescript-eslint/project-service@8.56.0(typescript@5.9.3)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.57.1(typescript@5.9.3) - '@typescript-eslint/types': 8.57.1 + '@typescript-eslint/tsconfig-utils': 8.58.2(typescript@5.9.3) + '@typescript-eslint/types': 8.58.2 debug: 4.4.3 typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/project-service@8.57.2(typescript@5.9.3)': + '@typescript-eslint/project-service@8.58.0(typescript@5.9.3)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.57.2(typescript@5.9.3) - '@typescript-eslint/types': 8.57.2 + '@typescript-eslint/tsconfig-utils': 8.58.2(typescript@5.9.3) + '@typescript-eslint/types': 8.58.2 debug: 4.4.3 typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@8.49.0': + '@typescript-eslint/project-service@8.59.0(typescript@5.9.3)': dependencies: - '@typescript-eslint/types': 8.49.0 - '@typescript-eslint/visitor-keys': 8.49.0 + '@typescript-eslint/tsconfig-utils': 8.59.0(typescript@5.9.3) + '@typescript-eslint/types': 8.59.0 + debug: 4.4.3 + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color '@typescript-eslint/scope-manager@8.56.0': dependencies: '@typescript-eslint/types': 8.56.0 '@typescript-eslint/visitor-keys': 8.56.0 - '@typescript-eslint/scope-manager@8.57.2': + '@typescript-eslint/scope-manager@8.58.0': dependencies: - '@typescript-eslint/types': 8.57.2 - '@typescript-eslint/visitor-keys': 8.57.2 + '@typescript-eslint/types': 8.58.0 + '@typescript-eslint/visitor-keys': 8.58.0 - '@typescript-eslint/tsconfig-utils@8.49.0(typescript@5.9.3)': + '@typescript-eslint/scope-manager@8.59.0': dependencies: - typescript: 5.9.3 + '@typescript-eslint/types': 8.59.0 + '@typescript-eslint/visitor-keys': 8.59.0 '@typescript-eslint/tsconfig-utils@8.56.0(typescript@5.9.3)': dependencies: typescript: 5.9.3 - '@typescript-eslint/tsconfig-utils@8.57.1(typescript@5.9.3)': + '@typescript-eslint/tsconfig-utils@8.58.0(typescript@5.9.3)': dependencies: typescript: 5.9.3 - '@typescript-eslint/tsconfig-utils@8.57.2(typescript@5.9.3)': + '@typescript-eslint/tsconfig-utils@8.58.2(typescript@5.9.3)': dependencies: typescript: 5.9.3 - '@typescript-eslint/type-utils@8.56.0(eslint@9.39.4(jiti@2.4.2))(typescript@5.9.3)': + '@typescript-eslint/tsconfig-utils@8.59.0(typescript@5.9.3)': + dependencies: + typescript: 5.9.3 + + '@typescript-eslint/type-utils@8.56.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': dependencies: '@typescript-eslint/types': 8.56.0 '@typescript-eslint/typescript-estree': 8.56.0(typescript@5.9.3) - '@typescript-eslint/utils': 8.56.0(eslint@9.39.4(jiti@2.4.2))(typescript@5.9.3) + '@typescript-eslint/utils': 8.56.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) debug: 4.4.3 - eslint: 9.39.4(jiti@2.4.2) - ts-api-utils: 2.4.0(typescript@5.9.3) + eslint: 9.39.4(jiti@2.6.1) + ts-api-utils: 2.5.0(typescript@5.9.3) typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/type-utils@8.57.2(eslint@9.39.4(jiti@2.4.2))(typescript@5.9.3)': + '@typescript-eslint/type-utils@8.59.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': dependencies: - '@typescript-eslint/types': 8.57.2 - '@typescript-eslint/typescript-estree': 8.57.2(typescript@5.9.3) - '@typescript-eslint/utils': 8.57.2(eslint@9.39.4(jiti@2.4.2))(typescript@5.9.3) + '@typescript-eslint/types': 8.59.0 + '@typescript-eslint/typescript-estree': 8.59.0(typescript@5.9.3) + '@typescript-eslint/utils': 8.59.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) debug: 4.4.3 - eslint: 9.39.4(jiti@2.4.2) - ts-api-utils: 2.4.0(typescript@5.9.3) + eslint: 9.39.4(jiti@2.6.1) + ts-api-utils: 2.5.0(typescript@5.9.3) typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/types@8.49.0': {} - '@typescript-eslint/types@8.56.0': {} - '@typescript-eslint/types@8.57.1': {} + '@typescript-eslint/types@8.58.0': {} - '@typescript-eslint/types@8.57.2': {} + '@typescript-eslint/types@8.58.2': {} - '@typescript-eslint/typescript-estree@8.49.0(typescript@5.9.3)': - dependencies: - '@typescript-eslint/project-service': 8.49.0(typescript@5.9.3) - '@typescript-eslint/tsconfig-utils': 8.49.0(typescript@5.9.3) - '@typescript-eslint/types': 8.49.0 - '@typescript-eslint/visitor-keys': 8.49.0 - debug: 4.4.3 - minimatch: 10.2.4 - semver: 7.7.3 - tinyglobby: 0.2.15 - ts-api-utils: 2.4.0(typescript@5.9.3) - typescript: 5.9.3 - transitivePeerDependencies: - - supports-color + '@typescript-eslint/types@8.59.0': {} '@typescript-eslint/typescript-estree@8.56.0(typescript@5.9.3)': dependencies: @@ -9462,111 +9680,137 @@ snapshots: minimatch: 10.2.4 semver: 7.7.3 tinyglobby: 0.2.15 - ts-api-utils: 2.4.0(typescript@5.9.3) + ts-api-utils: 2.5.0(typescript@5.9.3) typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/typescript-estree@8.57.2(typescript@5.9.3)': + '@typescript-eslint/typescript-estree@8.58.0(typescript@5.9.3)': dependencies: - '@typescript-eslint/project-service': 8.57.2(typescript@5.9.3) - '@typescript-eslint/tsconfig-utils': 8.57.2(typescript@5.9.3) - '@typescript-eslint/types': 8.57.2 - '@typescript-eslint/visitor-keys': 8.57.2 + '@typescript-eslint/project-service': 8.58.0(typescript@5.9.3) + '@typescript-eslint/tsconfig-utils': 8.58.0(typescript@5.9.3) + '@typescript-eslint/types': 8.58.0 + '@typescript-eslint/visitor-keys': 8.58.0 debug: 4.4.3 minimatch: 10.2.4 semver: 7.7.3 tinyglobby: 0.2.15 - ts-api-utils: 2.4.0(typescript@5.9.3) + ts-api-utils: 2.5.0(typescript@5.9.3) typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.56.0(eslint@9.39.4(jiti@2.4.2))(typescript@5.9.3)': + '@typescript-eslint/typescript-estree@8.59.0(typescript@5.9.3)': dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@2.4.2)) + '@typescript-eslint/project-service': 8.59.0(typescript@5.9.3) + '@typescript-eslint/tsconfig-utils': 8.59.0(typescript@5.9.3) + '@typescript-eslint/types': 8.59.0 + '@typescript-eslint/visitor-keys': 8.59.0 + debug: 4.4.3 + minimatch: 10.2.4 + semver: 7.7.3 + tinyglobby: 0.2.15 + ts-api-utils: 2.5.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/utils@8.56.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': + dependencies: + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@2.6.1)) '@typescript-eslint/scope-manager': 8.56.0 '@typescript-eslint/types': 8.56.0 '@typescript-eslint/typescript-estree': 8.56.0(typescript@5.9.3) - eslint: 9.39.4(jiti@2.4.2) + eslint: 9.39.4(jiti@2.6.1) typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.57.2(eslint@9.39.4(jiti@2.4.2))(typescript@5.9.3)': + '@typescript-eslint/utils@8.58.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@2.4.2)) - '@typescript-eslint/scope-manager': 8.57.2 - '@typescript-eslint/types': 8.57.2 - '@typescript-eslint/typescript-estree': 8.57.2(typescript@5.9.3) - eslint: 9.39.4(jiti@2.4.2) + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@2.6.1)) + '@typescript-eslint/scope-manager': 8.58.0 + '@typescript-eslint/types': 8.58.0 + '@typescript-eslint/typescript-estree': 8.58.0(typescript@5.9.3) + eslint: 9.39.4(jiti@2.6.1) typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/visitor-keys@8.49.0': + '@typescript-eslint/utils@8.59.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': dependencies: - '@typescript-eslint/types': 8.49.0 - eslint-visitor-keys: 4.2.1 + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@2.6.1)) + '@typescript-eslint/scope-manager': 8.59.0 + '@typescript-eslint/types': 8.59.0 + '@typescript-eslint/typescript-estree': 8.59.0(typescript@5.9.3) + eslint: 9.39.4(jiti@2.6.1) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color '@typescript-eslint/visitor-keys@8.56.0': dependencies: '@typescript-eslint/types': 8.56.0 eslint-visitor-keys: 5.0.0 - '@typescript-eslint/visitor-keys@8.57.2': + '@typescript-eslint/visitor-keys@8.58.0': dependencies: - '@typescript-eslint/types': 8.57.2 + '@typescript-eslint/types': 8.58.0 + eslint-visitor-keys: 5.0.0 + + '@typescript-eslint/visitor-keys@8.59.0': + dependencies: + '@typescript-eslint/types': 8.59.0 eslint-visitor-keys: 5.0.0 '@ungap/structured-clone@1.3.0': {} - '@vitejs/plugin-vue@6.0.5(vite@7.3.1(@types/node@24.12.0)(jiti@2.4.2)(lightningcss@1.32.0)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.31.6)(yaml@2.8.3))(vue@3.5.27(typescript@5.9.3))': + '@vitejs/plugin-vue@6.0.6(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(vue@3.5.27(typescript@5.9.3))': dependencies: - '@rolldown/pluginutils': 1.0.0-rc.2 - vite: 7.3.1(@types/node@24.12.0)(jiti@2.4.2)(lightningcss@1.32.0)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.31.6)(yaml@2.8.3) + '@rolldown/pluginutils': 1.0.0-rc.13 + vite: 7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) vue: 3.5.27(typescript@5.9.3) - '@vitest/expect@4.1.1': + '@vitest/expect@4.1.5': dependencies: '@standard-schema/spec': 1.1.0 '@types/chai': 5.2.2 - '@vitest/spy': 4.1.1 - '@vitest/utils': 4.1.1 + '@vitest/spy': 4.1.5 + '@vitest/utils': 4.1.5 chai: 6.2.2 - tinyrainbow: 3.0.3 + tinyrainbow: 3.1.0 - '@vitest/mocker@4.1.1(vite@7.3.1(@types/node@24.12.0)(jiti@2.4.2)(lightningcss@1.32.0)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.31.6)(yaml@2.8.3))': + '@vitest/mocker@4.1.5(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))': dependencies: - '@vitest/spy': 4.1.1 + '@vitest/spy': 4.1.5 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 7.3.1(@types/node@24.12.0)(jiti@2.4.2)(lightningcss@1.32.0)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.31.6)(yaml@2.8.3) + vite: 7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) - '@vitest/pretty-format@4.1.1': + '@vitest/pretty-format@4.1.5': dependencies: - tinyrainbow: 3.0.3 + tinyrainbow: 3.1.0 - '@vitest/runner@4.1.1': + '@vitest/runner@4.1.5': dependencies: - '@vitest/utils': 4.1.1 + '@vitest/utils': 4.1.5 pathe: 2.0.3 - '@vitest/snapshot@4.1.1': + '@vitest/snapshot@4.1.5': dependencies: - '@vitest/pretty-format': 4.1.1 - '@vitest/utils': 4.1.1 + '@vitest/pretty-format': 4.1.5 + '@vitest/utils': 4.1.5 magic-string: 0.30.21 pathe: 2.0.3 - '@vitest/spy@4.1.1': {} + '@vitest/spy@4.1.5': {} - '@vitest/utils@4.1.1': + '@vitest/utils@4.1.5': dependencies: - '@vitest/pretty-format': 4.1.1 + '@vitest/pretty-format': 4.1.5 convert-source-map: 2.0.0 - tinyrainbow: 3.0.3 + tinyrainbow: 3.1.0 '@volar/language-core@2.4.28': dependencies: @@ -9632,7 +9876,7 @@ snapshots: '@vue/shared': 3.5.27 estree-walker: 2.0.2 magic-string: 0.30.21 - postcss: 8.5.8 + postcss: 8.5.10 source-map-js: 1.2.1 '@vue/compiler-ssr@3.5.27': @@ -9675,25 +9919,25 @@ snapshots: '@vue/devtools-shared@8.1.1': {} - '@vue/eslint-config-typescript@14.7.0(eslint-plugin-vue@10.8.0(@typescript-eslint/parser@8.57.2(eslint@9.39.4(jiti@2.4.2))(typescript@5.9.3))(eslint@9.39.4(jiti@2.4.2))(vue-eslint-parser@10.4.0(eslint@9.39.4(jiti@2.4.2))))(eslint@9.39.4(jiti@2.4.2))(typescript@5.9.3)': + '@vue/eslint-config-typescript@14.7.0(eslint-plugin-vue@10.9.0(@typescript-eslint/parser@8.59.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@9.39.4(jiti@2.6.1))))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': dependencies: - '@typescript-eslint/utils': 8.56.0(eslint@9.39.4(jiti@2.4.2))(typescript@5.9.3) - eslint: 9.39.4(jiti@2.4.2) - eslint-plugin-vue: 10.8.0(@typescript-eslint/parser@8.57.2(eslint@9.39.4(jiti@2.4.2))(typescript@5.9.3))(eslint@9.39.4(jiti@2.4.2))(vue-eslint-parser@10.4.0(eslint@9.39.4(jiti@2.4.2))) + '@typescript-eslint/utils': 8.58.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + eslint: 9.39.4(jiti@2.6.1) + eslint-plugin-vue: 10.9.0(@typescript-eslint/parser@8.59.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@9.39.4(jiti@2.6.1))) fast-glob: 3.3.3 - typescript-eslint: 8.56.0(eslint@9.39.4(jiti@2.4.2))(typescript@5.9.3) - vue-eslint-parser: 10.4.0(eslint@9.39.4(jiti@2.4.2)) + typescript-eslint: 8.56.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + vue-eslint-parser: 10.4.0(eslint@9.39.4(jiti@2.6.1)) optionalDependencies: typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@vue/language-core@3.2.6': + '@vue/language-core@3.2.7': dependencies: '@volar/language-core': 2.4.28 '@vue/compiler-dom': 3.5.27 '@vue/shared': 3.5.27 - alien-signals: 3.0.0 + alien-signals: 3.1.2 muggle-string: 0.4.1 path-browserify: 1.0.1 picomatch: 4.0.4 @@ -9722,10 +9966,14 @@ snapshots: '@vue/shared@3.5.27': {} - '@vue/test-utils@2.4.6': + '@vue/test-utils@2.4.7(@vue/compiler-dom@3.5.27)(@vue/server-renderer@3.5.27(vue@3.5.27(typescript@5.9.3)))(vue@3.5.27(typescript@5.9.3))': dependencies: + '@vue/compiler-dom': 3.5.27 js-beautify: 1.15.1 - vue-component-type-helpers: 2.0.29 + vue: 3.5.27(typescript@5.9.3) + vue-component-type-helpers: 3.2.7 + optionalDependencies: + '@vue/server-renderer': 3.5.27(vue@3.5.27(typescript@5.9.3)) '@vue/tsconfig@0.9.1(typescript@5.9.3)(vue@3.5.27(typescript@5.9.3))': optionalDependencies: @@ -9761,8 +10009,6 @@ snapshots: dependencies: acorn: 8.15.0 - acorn@8.14.0: {} - acorn@8.15.0: {} agent-base@6.0.2: @@ -9787,7 +10033,7 @@ snapshots: json-schema-traverse: 1.0.0 require-from-string: 2.0.2 - alien-signals@3.0.0: {} + alien-signals@3.1.2: {} ansi-align@3.0.1: dependencies: @@ -9799,8 +10045,6 @@ snapshots: ansi-regex@5.0.1: {} - ansi-regex@6.0.1: {} - ansi-regex@6.2.2: {} ansi-styles@4.3.0: @@ -9857,24 +10101,24 @@ snapshots: stubborn-fs: 2.0.0 when-exit: 2.1.5 - autoprefixer@10.4.27(postcss@8.5.8): + autoprefixer@10.5.0(postcss@8.5.10): dependencies: - browserslist: 4.28.1 - caniuse-lite: 1.0.30001781 + browserslist: 4.28.2 + caniuse-lite: 1.0.30001790 fraction.js: 5.3.4 picocolors: 1.1.1 - postcss: 8.5.8 + postcss: 8.5.10 postcss-value-parser: 4.2.0 available-typed-arrays@1.0.7: dependencies: possible-typed-array-names: 1.0.0 - axios@1.13.5: + axios@1.15.0: dependencies: - follow-redirects: 1.15.11 + follow-redirects: 1.16.0 form-data: 4.0.5 - proxy-from-env: 1.1.0 + proxy-from-env: 2.1.0 transitivePeerDependencies: - debug @@ -9933,9 +10177,9 @@ snapshots: base64-js@1.5.1: {} - baseline-browser-mapping@2.9.4: {} + baseline-browser-mapping@2.10.12: {} - basic-ftp@5.2.0: {} + basic-ftp@5.2.2: {} bidi-js@1.0.3: dependencies: @@ -9968,7 +10212,7 @@ snapshots: widest-line: 5.0.0 wrap-ansi: 9.0.2 - brace-expansion@5.0.2: + brace-expansion@5.0.5: dependencies: balanced-match: 4.0.3 @@ -9976,13 +10220,13 @@ snapshots: dependencies: fill-range: 7.1.1 - browserslist@4.28.1: + browserslist@4.28.2: dependencies: - baseline-browser-mapping: 2.9.4 - caniuse-lite: 1.0.30001781 - electron-to-chromium: 1.5.266 - node-releases: 2.0.27 - update-browserslist-db: 1.2.2(browserslist@4.28.1) + baseline-browser-mapping: 2.10.12 + caniuse-lite: 1.0.30001790 + electron-to-chromium: 1.5.329 + node-releases: 2.0.36 + update-browserslist-db: 1.2.3(browserslist@4.28.2) buffer-crc32@0.2.13: {} @@ -10041,7 +10285,7 @@ snapshots: camelcase@8.0.0: {} - caniuse-lite@1.0.30001781: {} + caniuse-lite@1.0.30001790: {} capture-website@4.2.0(typescript@5.9.3): dependencies: @@ -10172,16 +10416,7 @@ snapshots: core-js-compat@3.38.1: dependencies: - browserslist: 4.28.1 - - cosmiconfig@9.0.0(typescript@5.9.3): - dependencies: - env-paths: 2.2.1 - import-fresh: 3.3.0 - js-yaml: 4.1.1 - parse-json: 5.2.0 - optionalDependencies: - typescript: 5.9.3 + browserslist: 4.28.2 cosmiconfig@9.0.1(typescript@5.9.3): dependencies: @@ -10202,23 +10437,23 @@ snapshots: crypto-random-string@2.0.0: {} - css-blank-pseudo@8.0.1(postcss@8.5.8): + css-blank-pseudo@8.0.1(postcss@8.5.10): dependencies: - postcss: 8.5.8 + postcss: 8.5.10 postcss-selector-parser: 7.1.1 css-functions-list@3.3.3: {} - css-has-pseudo@8.0.0(postcss@8.5.8): + css-has-pseudo@8.0.0(postcss@8.5.10): dependencies: '@csstools/selector-specificity': 6.0.0(postcss-selector-parser@7.1.1) - postcss: 8.5.8 + postcss: 8.5.10 postcss-selector-parser: 7.1.1 postcss-value-parser: 4.2.0 - css-prefers-color-scheme@11.0.0(postcss@8.5.8): + css-prefers-color-scheme@11.0.0(postcss@8.5.10): dependencies: - postcss: 8.5.8 + postcss: 8.5.10 css-property-sort-order-smacss@2.2.0: {} @@ -10240,11 +10475,6 @@ snapshots: mdn-data: 2.0.30 source-map-js: 1.2.1 - css-tree@3.1.0: - dependencies: - mdn-data: 2.12.2 - source-map-js: 1.2.1 - css-tree@3.2.1: dependencies: mdn-data: 2.27.1 @@ -10263,8 +10493,8 @@ snapshots: cssstyle@5.3.7: dependencies: '@asamuzakjp/css-color': 4.1.1 - '@csstools/css-syntax-patches-for-csstree': 1.0.28 - css-tree: 3.1.0 + '@csstools/css-syntax-patches-for-csstree': 1.1.2(css-tree@3.2.1) + css-tree: 3.2.1 lru-cache: 11.2.4 csstype@3.2.3: {} @@ -10348,7 +10578,7 @@ snapshots: has-property-descriptors: 1.0.2 object-keys: 1.1.1 - defu@6.1.4: {} + defu@6.1.7: {} degenerator@5.0.1: dependencies: @@ -10385,7 +10615,7 @@ snapshots: dependencies: domelementtype: 2.3.0 - dompurify@3.3.2: + dompurify@3.4.0: optionalDependencies: '@types/trusted-types': 2.0.7 @@ -10426,7 +10656,7 @@ snapshots: dependencies: jake: 10.9.2 - electron-to-chromium@1.5.266: {} + electron-to-chromium@1.5.329: {} emoji-picker-element@1.25.0: {} @@ -10568,34 +10798,63 @@ snapshots: '@esbuild/win32-ia32': 0.25.12 '@esbuild/win32-x64': 0.25.12 - esbuild@0.27.4: + esbuild@0.27.5: optionalDependencies: - '@esbuild/aix-ppc64': 0.27.4 - '@esbuild/android-arm': 0.27.4 - '@esbuild/android-arm64': 0.27.4 - '@esbuild/android-x64': 0.27.4 - '@esbuild/darwin-arm64': 0.27.4 - '@esbuild/darwin-x64': 0.27.4 - '@esbuild/freebsd-arm64': 0.27.4 - '@esbuild/freebsd-x64': 0.27.4 - '@esbuild/linux-arm': 0.27.4 - '@esbuild/linux-arm64': 0.27.4 - '@esbuild/linux-ia32': 0.27.4 - '@esbuild/linux-loong64': 0.27.4 - '@esbuild/linux-mips64el': 0.27.4 - '@esbuild/linux-ppc64': 0.27.4 - '@esbuild/linux-riscv64': 0.27.4 - '@esbuild/linux-s390x': 0.27.4 - '@esbuild/linux-x64': 0.27.4 - '@esbuild/netbsd-arm64': 0.27.4 - '@esbuild/netbsd-x64': 0.27.4 - '@esbuild/openbsd-arm64': 0.27.4 - '@esbuild/openbsd-x64': 0.27.4 - '@esbuild/openharmony-arm64': 0.27.4 - '@esbuild/sunos-x64': 0.27.4 - '@esbuild/win32-arm64': 0.27.4 - '@esbuild/win32-ia32': 0.27.4 - '@esbuild/win32-x64': 0.27.4 + '@esbuild/aix-ppc64': 0.27.5 + '@esbuild/android-arm': 0.27.5 + '@esbuild/android-arm64': 0.27.5 + '@esbuild/android-x64': 0.27.5 + '@esbuild/darwin-arm64': 0.27.5 + '@esbuild/darwin-x64': 0.27.5 + '@esbuild/freebsd-arm64': 0.27.5 + '@esbuild/freebsd-x64': 0.27.5 + '@esbuild/linux-arm': 0.27.5 + '@esbuild/linux-arm64': 0.27.5 + '@esbuild/linux-ia32': 0.27.5 + '@esbuild/linux-loong64': 0.27.5 + '@esbuild/linux-mips64el': 0.27.5 + '@esbuild/linux-ppc64': 0.27.5 + '@esbuild/linux-riscv64': 0.27.5 + '@esbuild/linux-s390x': 0.27.5 + '@esbuild/linux-x64': 0.27.5 + '@esbuild/netbsd-arm64': 0.27.5 + '@esbuild/netbsd-x64': 0.27.5 + '@esbuild/openbsd-arm64': 0.27.5 + '@esbuild/openbsd-x64': 0.27.5 + '@esbuild/openharmony-arm64': 0.27.5 + '@esbuild/sunos-x64': 0.27.5 + '@esbuild/win32-arm64': 0.27.5 + '@esbuild/win32-ia32': 0.27.5 + '@esbuild/win32-x64': 0.27.5 + + esbuild@0.28.0: + optionalDependencies: + '@esbuild/aix-ppc64': 0.28.0 + '@esbuild/android-arm': 0.28.0 + '@esbuild/android-arm64': 0.28.0 + '@esbuild/android-x64': 0.28.0 + '@esbuild/darwin-arm64': 0.28.0 + '@esbuild/darwin-x64': 0.28.0 + '@esbuild/freebsd-arm64': 0.28.0 + '@esbuild/freebsd-x64': 0.28.0 + '@esbuild/linux-arm': 0.28.0 + '@esbuild/linux-arm64': 0.28.0 + '@esbuild/linux-ia32': 0.28.0 + '@esbuild/linux-loong64': 0.28.0 + '@esbuild/linux-mips64el': 0.28.0 + '@esbuild/linux-ppc64': 0.28.0 + '@esbuild/linux-riscv64': 0.28.0 + '@esbuild/linux-s390x': 0.28.0 + '@esbuild/linux-x64': 0.28.0 + '@esbuild/netbsd-arm64': 0.28.0 + '@esbuild/netbsd-x64': 0.28.0 + '@esbuild/openbsd-arm64': 0.28.0 + '@esbuild/openbsd-x64': 0.28.0 + '@esbuild/openharmony-arm64': 0.28.0 + '@esbuild/sunos-x64': 0.28.0 + '@esbuild/win32-arm64': 0.28.0 + '@esbuild/win32-ia32': 0.28.0 + '@esbuild/win32-x64': 0.28.0 escalade@3.2.0: {} @@ -10615,25 +10874,25 @@ snapshots: optionalDependencies: source-map: 0.6.1 - eslint-plugin-depend@1.5.0(eslint@9.39.4(jiti@2.4.2)): + eslint-plugin-depend@1.5.0(eslint@9.39.4(jiti@2.6.1)): dependencies: empathic: 2.0.0 - eslint: 9.39.4(jiti@2.4.2) + eslint: 9.39.4(jiti@2.6.1) module-replacements: 2.11.0 semver: 7.7.3 - eslint-plugin-vue@10.8.0(@typescript-eslint/parser@8.57.2(eslint@9.39.4(jiti@2.4.2))(typescript@5.9.3))(eslint@9.39.4(jiti@2.4.2))(vue-eslint-parser@10.4.0(eslint@9.39.4(jiti@2.4.2))): + eslint-plugin-vue@10.9.0(@typescript-eslint/parser@8.59.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@9.39.4(jiti@2.6.1))): dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@2.4.2)) - eslint: 9.39.4(jiti@2.4.2) + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@2.6.1)) + eslint: 9.39.4(jiti@2.6.1) natural-compare: 1.4.0 nth-check: 2.1.1 postcss-selector-parser: 7.1.1 semver: 7.7.3 - vue-eslint-parser: 10.4.0(eslint@9.39.4(jiti@2.4.2)) + vue-eslint-parser: 10.4.0(eslint@9.39.4(jiti@2.6.1)) xml-name-validator: 4.0.0 optionalDependencies: - '@typescript-eslint/parser': 8.57.2(eslint@9.39.4(jiti@2.4.2))(typescript@5.9.3) + '@typescript-eslint/parser': 8.59.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) eslint-scope@8.4.0: dependencies: @@ -10646,9 +10905,9 @@ snapshots: eslint-visitor-keys@5.0.0: {} - eslint@9.39.4(jiti@2.4.2): + eslint@9.39.4(jiti@2.6.1): dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@2.4.2)) + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@2.6.1)) '@eslint-community/regexpp': 4.12.2 '@eslint/config-array': 0.21.2 '@eslint/config-helpers': 0.4.2 @@ -10683,7 +10942,7 @@ snapshots: natural-compare: 1.4.0 optionator: 0.9.4 optionalDependencies: - jiti: 2.4.2 + jiti: 2.6.1 transitivePeerDependencies: - supports-color @@ -10834,25 +11093,18 @@ snapshots: flatted@3.4.2: {} - flexsearch@0.8.212: {} - floating-vue@5.2.2(vue@3.5.27(typescript@5.9.3)): dependencies: '@floating-ui/dom': 1.1.1 vue: 3.5.27(typescript@5.9.3) vue-resize: 2.0.0-alpha.1(vue@3.5.27(typescript@5.9.3)) - follow-redirects@1.15.11: {} + follow-redirects@1.16.0: {} for-each@0.3.3: dependencies: is-callable: 1.2.7 - foreground-child@3.3.0: - dependencies: - cross-spawn: 7.0.6 - signal-exit: 4.1.0 - foreground-child@3.3.1: dependencies: cross-spawn: 7.0.6 @@ -10906,8 +11158,6 @@ snapshots: get-caller-file@2.0.5: {} - get-east-asian-width@1.4.0: {} - get-east-asian-width@1.5.0: {} get-intrinsic@1.3.0: @@ -10942,7 +11192,7 @@ snapshots: get-uri@6.0.4: dependencies: - basic-ftp: 5.2.0 + basic-ftp: 5.2.2 data-uri-to-buffer: 6.0.2 debug: 4.4.3 transitivePeerDependencies: @@ -10958,7 +11208,7 @@ snapshots: glob@10.5.0: dependencies: - foreground-child: 3.3.0 + foreground-child: 3.3.1 jackspeak: 3.4.3 minimatch: 10.2.4 minipass: 7.1.2 @@ -11013,7 +11263,7 @@ snapshots: slash: 5.1.0 unicorn-magic: 0.3.0 - globby@16.1.1: + globby@16.2.0: dependencies: '@sindresorhus/merge-streams': 4.0.0 fast-glob: 3.3.3 @@ -11037,14 +11287,14 @@ snapshots: section-matter: 1.0.0 strip-bom-string: 1.0.0 - happy-dom@20.8.8: + happy-dom@20.9.0: dependencies: - '@types/node': 24.12.0 + '@types/node': 24.12.2 '@types/whatwg-mimetype': 3.0.2 '@types/ws': 8.18.1 entities: 7.0.1 whatwg-mimetype: 3.0.0 - ws: 8.19.0 + ws: 8.20.0 transitivePeerDependencies: - bufferutil - utf-8-validate @@ -11097,24 +11347,24 @@ snapshots: highlight.js@11.11.1: {} - histoire@1.0.0-beta.1(@types/node@24.12.0)(lightningcss@1.32.0)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.31.6)(vite@7.3.1(@types/node@24.12.0)(jiti@2.4.2)(lightningcss@1.32.0)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.31.6)(yaml@2.8.3))(yaml@2.8.3): + histoire@1.0.0-beta.1(@types/node@24.12.2)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(yaml@2.8.3): dependencies: '@akryum/tinypool': 0.3.1 - '@histoire/app': 1.0.0-beta.1(vite@7.3.1(@types/node@24.12.0)(jiti@2.4.2)(lightningcss@1.32.0)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.31.6)(yaml@2.8.3)) - '@histoire/controls': 1.0.0-beta.1(vite@7.3.1(@types/node@24.12.0)(jiti@2.4.2)(lightningcss@1.32.0)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.31.6)(yaml@2.8.3)) - '@histoire/shared': 1.0.0-beta.1(vite@7.3.1(@types/node@24.12.0)(jiti@2.4.2)(lightningcss@1.32.0)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.31.6)(yaml@2.8.3)) + '@histoire/app': 1.0.0-beta.1(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) + '@histoire/controls': 1.0.0-beta.1(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) + '@histoire/shared': 1.0.0-beta.1(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) '@histoire/vendors': 1.0.0-beta.1 '@types/markdown-it': 14.1.2 birpc: 0.2.19 change-case: 5.4.4 chokidar: 4.0.3 connect: 3.7.0 - defu: 6.1.4 + defu: 6.1.7 diacritics: 1.3.0 fs-extra: 11.2.0 globby: 14.1.0 gray-matter: 4.0.3 - jiti: 2.4.2 + jiti: 2.6.1 jsdom: 27.4.0 markdown-it: 14.1.1 markdown-it-anchor: 9.2.0(@types/markdown-it@14.1.2)(markdown-it@14.1.1) @@ -11127,8 +11377,8 @@ snapshots: sade: 1.8.1 shiki: 3.2.1 sirv: 3.0.2 - vite: 7.3.1(@types/node@24.12.0)(jiti@2.4.2)(lightningcss@1.32.0)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.31.6)(yaml@2.8.3) - vite-node: 3.2.4(@types/node@24.12.0)(jiti@2.4.2)(lightningcss@1.32.0)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.31.6)(yaml@2.8.3) + vite: 7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) + vite-node: 3.2.4(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) transitivePeerDependencies: - '@exodus/crypto' - '@types/node' @@ -11231,7 +11481,7 @@ snapshots: cli-width: 3.0.0 external-editor: 3.1.0 figures: 3.2.0 - lodash: 4.17.23 + lodash: 4.18.1 mute-stream: 0.0.8 run-async: 2.4.1 rxjs: 6.6.7 @@ -11401,11 +11651,9 @@ snapshots: filelist: 1.0.4 minimatch: 10.2.4 - jiti@2.4.2: {} - jiti@2.6.1: {} - joi@18.0.2: + joi@18.1.2: dependencies: '@hapi/address': 5.1.1 '@hapi/formula': 3.0.2 @@ -11413,7 +11661,7 @@ snapshots: '@hapi/pinpoint': 2.0.1 '@hapi/tlds': 1.1.3 '@hapi/topo': 6.0.2 - '@standard-schema/spec': 1.0.0 + '@standard-schema/spec': 1.1.0 js-beautify@1.15.1: dependencies: @@ -11460,7 +11708,7 @@ snapshots: webidl-conversions: 8.0.1 whatwg-mimetype: 4.0.0 whatwg-url: 15.1.0 - ws: 8.19.0 + ws: 8.20.0 xml-name-validator: 5.0.0 transitivePeerDependencies: - '@exodus/crypto' @@ -11606,7 +11854,7 @@ snapshots: lodash.truncate@4.4.2: {} - lodash@4.17.23: {} + lodash@4.18.1: {} log-symbols@4.1.0: dependencies: @@ -11621,8 +11869,6 @@ snapshots: lru-cache@10.4.3: {} - lru-cache@11.2.2: {} - lru-cache@11.2.4: {} lru-cache@5.1.1: @@ -11689,10 +11935,6 @@ snapshots: mdn-data@2.0.30: {} - mdn-data@2.12.2: {} - - mdn-data@2.26.0: {} - mdn-data@2.27.1: {} mdurl@2.0.0: {} @@ -11749,7 +11991,7 @@ snapshots: minimatch@10.2.4: dependencies: - brace-expansion: 5.0.2 + brace-expansion: 5.0.5 minimist-options@4.1.0: dependencies: @@ -11794,7 +12036,7 @@ snapshots: dependencies: whatwg-url: 5.0.0 - node-releases@2.0.27: {} + node-releases@2.0.36: {} nopt@7.2.1: dependencies: @@ -11887,6 +12129,12 @@ snapshots: os-tmpdir@1.0.2: {} + otplib@12.0.1: + dependencies: + '@otplib/core': 12.0.1 + '@otplib/preset-default': 12.0.1 + '@otplib/preset-v11': 12.0.1 + p-limit@2.3.0: dependencies: p-try: 2.2.0 @@ -11964,7 +12212,7 @@ snapshots: path-scurry@2.0.1: dependencies: - lru-cache: 11.2.2 + lru-cache: 11.2.4 minipass: 7.1.2 path-type@6.0.0: {} @@ -12004,72 +12252,72 @@ snapshots: possible-typed-array-names@1.0.0: {} - postcss-attribute-case-insensitive@8.0.0(postcss@8.5.8): + postcss-attribute-case-insensitive@8.0.0(postcss@8.5.10): dependencies: - postcss: 8.5.8 + postcss: 8.5.10 postcss-selector-parser: 7.1.1 - postcss-clamp@4.1.0(postcss@8.5.8): + postcss-clamp@4.1.0(postcss@8.5.10): dependencies: - postcss: 8.5.8 + postcss: 8.5.10 postcss-value-parser: 4.2.0 - postcss-color-functional-notation@8.0.2(postcss@8.5.8): + postcss-color-functional-notation@8.0.3(postcss@8.5.10): dependencies: - '@csstools/css-color-parser': 4.0.2(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) + '@csstools/css-color-parser': 4.1.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.8) - '@csstools/utilities': 3.0.0(postcss@8.5.8) - postcss: 8.5.8 + '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.10) + '@csstools/utilities': 3.0.0(postcss@8.5.10) + postcss: 8.5.10 - postcss-color-hex-alpha@11.0.0(postcss@8.5.8): + postcss-color-hex-alpha@11.0.0(postcss@8.5.10): dependencies: - '@csstools/utilities': 3.0.0(postcss@8.5.8) - postcss: 8.5.8 + '@csstools/utilities': 3.0.0(postcss@8.5.10) + postcss: 8.5.10 postcss-value-parser: 4.2.0 - postcss-color-rebeccapurple@11.0.0(postcss@8.5.8): + postcss-color-rebeccapurple@11.0.0(postcss@8.5.10): dependencies: - '@csstools/utilities': 3.0.0(postcss@8.5.8) - postcss: 8.5.8 + '@csstools/utilities': 3.0.0(postcss@8.5.10) + postcss: 8.5.10 postcss-value-parser: 4.2.0 - postcss-custom-media@12.0.1(postcss@8.5.8): + postcss-custom-media@12.0.1(postcss@8.5.10): dependencies: '@csstools/cascade-layer-name-parser': 3.0.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 '@csstools/media-query-list-parser': 5.0.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) - postcss: 8.5.8 + postcss: 8.5.10 - postcss-custom-properties@15.0.1(postcss@8.5.8): + postcss-custom-properties@15.0.1(postcss@8.5.10): dependencies: '@csstools/cascade-layer-name-parser': 3.0.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - '@csstools/utilities': 3.0.0(postcss@8.5.8) - postcss: 8.5.8 + '@csstools/utilities': 3.0.0(postcss@8.5.10) + postcss: 8.5.10 postcss-value-parser: 4.2.0 - postcss-custom-selectors@9.0.1(postcss@8.5.8): + postcss-custom-selectors@9.0.1(postcss@8.5.10): dependencies: '@csstools/cascade-layer-name-parser': 3.0.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - postcss: 8.5.8 + postcss: 8.5.10 postcss-selector-parser: 7.1.1 - postcss-dir-pseudo-class@10.0.0(postcss@8.5.8): + postcss-dir-pseudo-class@10.0.0(postcss@8.5.10): dependencies: - postcss: 8.5.8 + postcss: 8.5.10 postcss-selector-parser: 7.1.1 - postcss-double-position-gradients@7.0.0(postcss@8.5.8): + postcss-double-position-gradients@7.0.0(postcss@8.5.10): dependencies: - '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.8) - '@csstools/utilities': 3.0.0(postcss@8.5.8) - postcss: 8.5.8 + '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.10) + '@csstools/utilities': 3.0.0(postcss@8.5.10) + postcss: 8.5.10 postcss-value-parser: 4.2.0 postcss-easing-gradients@3.0.1: @@ -12079,181 +12327,181 @@ snapshots: postcss: 7.0.39 postcss-value-parser: 3.3.1 - postcss-focus-visible@11.0.0(postcss@8.5.8): + postcss-focus-visible@11.0.0(postcss@8.5.10): dependencies: - postcss: 8.5.8 + postcss: 8.5.10 postcss-selector-parser: 7.1.1 - postcss-focus-within@10.0.0(postcss@8.5.8): + postcss-focus-within@10.0.0(postcss@8.5.10): dependencies: - postcss: 8.5.8 + postcss: 8.5.10 postcss-selector-parser: 7.1.1 - postcss-font-variant@5.0.0(postcss@8.5.8): + postcss-font-variant@5.0.0(postcss@8.5.10): dependencies: - postcss: 8.5.8 + postcss: 8.5.10 - postcss-gap-properties@7.0.0(postcss@8.5.8): + postcss-gap-properties@7.0.0(postcss@8.5.10): dependencies: - postcss: 8.5.8 + postcss: 8.5.10 - postcss-html@1.8.0: + postcss-html@1.8.1: dependencies: htmlparser2: 8.0.2 js-tokens: 9.0.1 - postcss: 8.5.8 - postcss-safe-parser: 6.0.0(postcss@8.5.8) + postcss: 8.5.10 + postcss-safe-parser: 6.0.0(postcss@8.5.10) - postcss-image-set-function@8.0.0(postcss@8.5.8): + postcss-image-set-function@8.0.0(postcss@8.5.10): dependencies: - '@csstools/utilities': 3.0.0(postcss@8.5.8) - postcss: 8.5.8 + '@csstools/utilities': 3.0.0(postcss@8.5.10) + postcss: 8.5.10 postcss-value-parser: 4.2.0 - postcss-lab-function@8.0.2(postcss@8.5.8): + postcss-lab-function@8.0.3(postcss@8.5.10): dependencies: - '@csstools/css-color-parser': 4.0.2(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) + '@csstools/css-color-parser': 4.1.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.8) - '@csstools/utilities': 3.0.0(postcss@8.5.8) - postcss: 8.5.8 + '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.10) + '@csstools/utilities': 3.0.0(postcss@8.5.10) + postcss: 8.5.10 - postcss-logical@9.0.0(postcss@8.5.8): + postcss-logical@9.0.0(postcss@8.5.10): dependencies: - postcss: 8.5.8 + postcss: 8.5.10 postcss-value-parser: 4.2.0 postcss-media-query-parser@0.2.3: {} - postcss-nesting@14.0.0(postcss@8.5.8): + postcss-nesting@14.0.0(postcss@8.5.10): dependencies: '@csstools/selector-resolve-nested': 4.0.0(postcss-selector-parser@7.1.1) '@csstools/selector-specificity': 6.0.0(postcss-selector-parser@7.1.1) - postcss: 8.5.8 + postcss: 8.5.10 postcss-selector-parser: 7.1.1 - postcss-opacity-percentage@3.0.0(postcss@8.5.8): + postcss-opacity-percentage@3.0.0(postcss@8.5.10): dependencies: - postcss: 8.5.8 + postcss: 8.5.10 - postcss-overflow-shorthand@7.0.0(postcss@8.5.8): + postcss-overflow-shorthand@7.0.0(postcss@8.5.10): dependencies: - postcss: 8.5.8 + postcss: 8.5.10 postcss-value-parser: 4.2.0 - postcss-page-break@3.0.4(postcss@8.5.8): + postcss-page-break@3.0.4(postcss@8.5.10): dependencies: - postcss: 8.5.8 + postcss: 8.5.10 - postcss-place@11.0.0(postcss@8.5.8): + postcss-place@11.0.0(postcss@8.5.10): dependencies: - postcss: 8.5.8 + postcss: 8.5.10 postcss-value-parser: 4.2.0 - postcss-preset-env@11.2.0(postcss@8.5.8): + postcss-preset-env@11.2.1(postcss@8.5.10): dependencies: - '@csstools/postcss-alpha-function': 2.0.3(postcss@8.5.8) - '@csstools/postcss-cascade-layers': 6.0.0(postcss@8.5.8) - '@csstools/postcss-color-function': 5.0.2(postcss@8.5.8) - '@csstools/postcss-color-function-display-p3-linear': 2.0.2(postcss@8.5.8) - '@csstools/postcss-color-mix-function': 4.0.2(postcss@8.5.8) - '@csstools/postcss-color-mix-variadic-function-arguments': 2.0.2(postcss@8.5.8) - '@csstools/postcss-content-alt-text': 3.0.0(postcss@8.5.8) - '@csstools/postcss-contrast-color-function': 3.0.2(postcss@8.5.8) - '@csstools/postcss-exponential-functions': 3.0.1(postcss@8.5.8) - '@csstools/postcss-font-format-keywords': 5.0.0(postcss@8.5.8) - '@csstools/postcss-font-width-property': 1.0.0(postcss@8.5.8) - '@csstools/postcss-gamut-mapping': 3.0.2(postcss@8.5.8) - '@csstools/postcss-gradients-interpolation-method': 6.0.2(postcss@8.5.8) - '@csstools/postcss-hwb-function': 5.0.2(postcss@8.5.8) - '@csstools/postcss-ic-unit': 5.0.0(postcss@8.5.8) - '@csstools/postcss-initial': 3.0.0(postcss@8.5.8) - '@csstools/postcss-is-pseudo-class': 6.0.0(postcss@8.5.8) - '@csstools/postcss-light-dark-function': 3.0.0(postcss@8.5.8) - '@csstools/postcss-logical-float-and-clear': 4.0.0(postcss@8.5.8) - '@csstools/postcss-logical-overflow': 3.0.0(postcss@8.5.8) - '@csstools/postcss-logical-overscroll-behavior': 3.0.0(postcss@8.5.8) - '@csstools/postcss-logical-resize': 4.0.0(postcss@8.5.8) - '@csstools/postcss-logical-viewport-units': 4.0.0(postcss@8.5.8) - '@csstools/postcss-media-minmax': 3.0.1(postcss@8.5.8) - '@csstools/postcss-media-queries-aspect-ratio-number-values': 4.0.0(postcss@8.5.8) - '@csstools/postcss-mixins': 1.0.0(postcss@8.5.8) - '@csstools/postcss-nested-calc': 5.0.0(postcss@8.5.8) - '@csstools/postcss-normalize-display-values': 5.0.1(postcss@8.5.8) - '@csstools/postcss-oklab-function': 5.0.2(postcss@8.5.8) - '@csstools/postcss-position-area-property': 2.0.0(postcss@8.5.8) - '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.8) - '@csstools/postcss-property-rule-prelude-list': 2.0.0(postcss@8.5.8) - '@csstools/postcss-random-function': 3.0.1(postcss@8.5.8) - '@csstools/postcss-relative-color-syntax': 4.0.2(postcss@8.5.8) - '@csstools/postcss-scope-pseudo-class': 5.0.0(postcss@8.5.8) - '@csstools/postcss-sign-functions': 2.0.1(postcss@8.5.8) - '@csstools/postcss-stepped-value-functions': 5.0.1(postcss@8.5.8) - '@csstools/postcss-syntax-descriptor-syntax-production': 2.0.0(postcss@8.5.8) - '@csstools/postcss-system-ui-font-family': 2.0.0(postcss@8.5.8) - '@csstools/postcss-text-decoration-shorthand': 5.0.3(postcss@8.5.8) - '@csstools/postcss-trigonometric-functions': 5.0.1(postcss@8.5.8) - '@csstools/postcss-unset-value': 5.0.0(postcss@8.5.8) - autoprefixer: 10.4.27(postcss@8.5.8) - browserslist: 4.28.1 - css-blank-pseudo: 8.0.1(postcss@8.5.8) - css-has-pseudo: 8.0.0(postcss@8.5.8) - css-prefers-color-scheme: 11.0.0(postcss@8.5.8) + '@csstools/postcss-alpha-function': 2.0.4(postcss@8.5.10) + '@csstools/postcss-cascade-layers': 6.0.0(postcss@8.5.10) + '@csstools/postcss-color-function': 5.0.3(postcss@8.5.10) + '@csstools/postcss-color-function-display-p3-linear': 2.0.3(postcss@8.5.10) + '@csstools/postcss-color-mix-function': 4.0.3(postcss@8.5.10) + '@csstools/postcss-color-mix-variadic-function-arguments': 2.0.3(postcss@8.5.10) + '@csstools/postcss-content-alt-text': 3.0.0(postcss@8.5.10) + '@csstools/postcss-contrast-color-function': 3.0.3(postcss@8.5.10) + '@csstools/postcss-exponential-functions': 3.0.2(postcss@8.5.10) + '@csstools/postcss-font-format-keywords': 5.0.0(postcss@8.5.10) + '@csstools/postcss-font-width-property': 1.0.0(postcss@8.5.10) + '@csstools/postcss-gamut-mapping': 3.0.3(postcss@8.5.10) + '@csstools/postcss-gradients-interpolation-method': 6.0.3(postcss@8.5.10) + '@csstools/postcss-hwb-function': 5.0.3(postcss@8.5.10) + '@csstools/postcss-ic-unit': 5.0.0(postcss@8.5.10) + '@csstools/postcss-initial': 3.0.0(postcss@8.5.10) + '@csstools/postcss-is-pseudo-class': 6.0.0(postcss@8.5.10) + '@csstools/postcss-light-dark-function': 3.0.0(postcss@8.5.10) + '@csstools/postcss-logical-float-and-clear': 4.0.0(postcss@8.5.10) + '@csstools/postcss-logical-overflow': 3.0.0(postcss@8.5.10) + '@csstools/postcss-logical-overscroll-behavior': 3.0.0(postcss@8.5.10) + '@csstools/postcss-logical-resize': 4.0.0(postcss@8.5.10) + '@csstools/postcss-logical-viewport-units': 4.0.0(postcss@8.5.10) + '@csstools/postcss-media-minmax': 3.0.2(postcss@8.5.10) + '@csstools/postcss-media-queries-aspect-ratio-number-values': 4.0.0(postcss@8.5.10) + '@csstools/postcss-mixins': 1.0.0(postcss@8.5.10) + '@csstools/postcss-nested-calc': 5.0.0(postcss@8.5.10) + '@csstools/postcss-normalize-display-values': 5.0.1(postcss@8.5.10) + '@csstools/postcss-oklab-function': 5.0.3(postcss@8.5.10) + '@csstools/postcss-position-area-property': 2.0.0(postcss@8.5.10) + '@csstools/postcss-progressive-custom-properties': 5.0.0(postcss@8.5.10) + '@csstools/postcss-property-rule-prelude-list': 2.0.0(postcss@8.5.10) + '@csstools/postcss-random-function': 3.0.2(postcss@8.5.10) + '@csstools/postcss-relative-color-syntax': 4.0.3(postcss@8.5.10) + '@csstools/postcss-scope-pseudo-class': 5.0.0(postcss@8.5.10) + '@csstools/postcss-sign-functions': 2.0.2(postcss@8.5.10) + '@csstools/postcss-stepped-value-functions': 5.0.2(postcss@8.5.10) + '@csstools/postcss-syntax-descriptor-syntax-production': 2.0.0(postcss@8.5.10) + '@csstools/postcss-system-ui-font-family': 2.0.0(postcss@8.5.10) + '@csstools/postcss-text-decoration-shorthand': 5.0.3(postcss@8.5.10) + '@csstools/postcss-trigonometric-functions': 5.0.2(postcss@8.5.10) + '@csstools/postcss-unset-value': 5.0.0(postcss@8.5.10) + autoprefixer: 10.5.0(postcss@8.5.10) + browserslist: 4.28.2 + css-blank-pseudo: 8.0.1(postcss@8.5.10) + css-has-pseudo: 8.0.0(postcss@8.5.10) + css-prefers-color-scheme: 11.0.0(postcss@8.5.10) cssdb: 8.8.0 - postcss: 8.5.8 - postcss-attribute-case-insensitive: 8.0.0(postcss@8.5.8) - postcss-clamp: 4.1.0(postcss@8.5.8) - postcss-color-functional-notation: 8.0.2(postcss@8.5.8) - postcss-color-hex-alpha: 11.0.0(postcss@8.5.8) - postcss-color-rebeccapurple: 11.0.0(postcss@8.5.8) - postcss-custom-media: 12.0.1(postcss@8.5.8) - postcss-custom-properties: 15.0.1(postcss@8.5.8) - postcss-custom-selectors: 9.0.1(postcss@8.5.8) - postcss-dir-pseudo-class: 10.0.0(postcss@8.5.8) - postcss-double-position-gradients: 7.0.0(postcss@8.5.8) - postcss-focus-visible: 11.0.0(postcss@8.5.8) - postcss-focus-within: 10.0.0(postcss@8.5.8) - postcss-font-variant: 5.0.0(postcss@8.5.8) - postcss-gap-properties: 7.0.0(postcss@8.5.8) - postcss-image-set-function: 8.0.0(postcss@8.5.8) - postcss-lab-function: 8.0.2(postcss@8.5.8) - postcss-logical: 9.0.0(postcss@8.5.8) - postcss-nesting: 14.0.0(postcss@8.5.8) - postcss-opacity-percentage: 3.0.0(postcss@8.5.8) - postcss-overflow-shorthand: 7.0.0(postcss@8.5.8) - postcss-page-break: 3.0.4(postcss@8.5.8) - postcss-place: 11.0.0(postcss@8.5.8) - postcss-pseudo-class-any-link: 11.0.0(postcss@8.5.8) - postcss-replace-overflow-wrap: 4.0.0(postcss@8.5.8) - postcss-selector-not: 9.0.0(postcss@8.5.8) + postcss: 8.5.10 + postcss-attribute-case-insensitive: 8.0.0(postcss@8.5.10) + postcss-clamp: 4.1.0(postcss@8.5.10) + postcss-color-functional-notation: 8.0.3(postcss@8.5.10) + postcss-color-hex-alpha: 11.0.0(postcss@8.5.10) + postcss-color-rebeccapurple: 11.0.0(postcss@8.5.10) + postcss-custom-media: 12.0.1(postcss@8.5.10) + postcss-custom-properties: 15.0.1(postcss@8.5.10) + postcss-custom-selectors: 9.0.1(postcss@8.5.10) + postcss-dir-pseudo-class: 10.0.0(postcss@8.5.10) + postcss-double-position-gradients: 7.0.0(postcss@8.5.10) + postcss-focus-visible: 11.0.0(postcss@8.5.10) + postcss-focus-within: 10.0.0(postcss@8.5.10) + postcss-font-variant: 5.0.0(postcss@8.5.10) + postcss-gap-properties: 7.0.0(postcss@8.5.10) + postcss-image-set-function: 8.0.0(postcss@8.5.10) + postcss-lab-function: 8.0.3(postcss@8.5.10) + postcss-logical: 9.0.0(postcss@8.5.10) + postcss-nesting: 14.0.0(postcss@8.5.10) + postcss-opacity-percentage: 3.0.0(postcss@8.5.10) + postcss-overflow-shorthand: 7.0.0(postcss@8.5.10) + postcss-page-break: 3.0.4(postcss@8.5.10) + postcss-place: 11.0.0(postcss@8.5.10) + postcss-pseudo-class-any-link: 11.0.0(postcss@8.5.10) + postcss-replace-overflow-wrap: 4.0.0(postcss@8.5.10) + postcss-selector-not: 9.0.0(postcss@8.5.10) - postcss-pseudo-class-any-link@11.0.0(postcss@8.5.8): + postcss-pseudo-class-any-link@11.0.0(postcss@8.5.10): dependencies: - postcss: 8.5.8 + postcss: 8.5.10 postcss-selector-parser: 7.1.1 - postcss-replace-overflow-wrap@4.0.0(postcss@8.5.8): + postcss-replace-overflow-wrap@4.0.0(postcss@8.5.10): dependencies: - postcss: 8.5.8 + postcss: 8.5.10 postcss-resolve-nested-selector@0.1.6: {} - postcss-safe-parser@6.0.0(postcss@8.5.8): + postcss-safe-parser@6.0.0(postcss@8.5.10): dependencies: - postcss: 8.5.8 + postcss: 8.5.10 - postcss-safe-parser@7.0.1(postcss@8.5.8): + postcss-safe-parser@7.0.1(postcss@8.5.10): dependencies: - postcss: 8.5.8 + postcss: 8.5.10 - postcss-scss@4.0.9(postcss@8.5.8): + postcss-scss@4.0.9(postcss@8.5.10): dependencies: - postcss: 8.5.8 + postcss: 8.5.10 - postcss-selector-not@9.0.0(postcss@8.5.8): + postcss-selector-not@9.0.0(postcss@8.5.10): dependencies: - postcss: 8.5.8 + postcss: 8.5.10 postcss-selector-parser: 7.1.1 postcss-selector-parser@7.1.1: @@ -12261,9 +12509,9 @@ snapshots: cssesc: 3.0.0 util-deprecate: 1.0.2 - postcss-sorting@8.0.2(postcss@8.5.8): + postcss-sorting@8.0.2(postcss@8.5.10): dependencies: - postcss: 8.5.8 + postcss: 8.5.10 postcss-value-parser@3.3.1: {} @@ -12274,7 +12522,7 @@ snapshots: picocolors: 0.2.1 source-map: 0.6.1 - postcss@8.5.8: + postcss@8.5.10: dependencies: nanoid: 3.3.11 picocolors: 1.1.1 @@ -12410,6 +12658,8 @@ snapshots: proxy-from-env@1.1.0: {} + proxy-from-env@2.1.0: {} + pump@3.0.0: dependencies: end-of-stream: 1.4.4 @@ -12430,7 +12680,7 @@ snapshots: debug: 4.4.3 devtools-protocol: 0.0.1367902 typed-query-selector: 2.12.0 - ws: 8.19.0 + ws: 8.20.0 transitivePeerDependencies: - bare-buffer - bufferutil @@ -12441,7 +12691,7 @@ snapshots: dependencies: '@puppeteer/browsers': 2.6.1 chromium-bidi: 0.11.0(devtools-protocol@0.0.1367902) - cosmiconfig: 9.0.0(typescript@5.9.3) + cosmiconfig: 9.0.1(typescript@5.9.3) devtools-protocol: 0.0.1367902 puppeteer-core: 23.11.1 typed-query-selector: 2.12.0 @@ -12572,44 +12822,44 @@ snapshots: rfdc@1.4.1: {} - rollup-plugin-visualizer@6.0.11(rollup@4.60.0): + rollup-plugin-visualizer@6.0.11(rollup@4.60.2): dependencies: open: 8.4.2 picomatch: 4.0.4 source-map: 0.7.4 yargs: 17.7.2 optionalDependencies: - rollup: 4.60.0 + rollup: 4.60.2 - rollup@4.60.0: + rollup@4.60.2: dependencies: '@types/estree': 1.0.8 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.60.0 - '@rollup/rollup-android-arm64': 4.60.0 - '@rollup/rollup-darwin-arm64': 4.60.0 - '@rollup/rollup-darwin-x64': 4.60.0 - '@rollup/rollup-freebsd-arm64': 4.60.0 - '@rollup/rollup-freebsd-x64': 4.60.0 - '@rollup/rollup-linux-arm-gnueabihf': 4.60.0 - '@rollup/rollup-linux-arm-musleabihf': 4.60.0 - '@rollup/rollup-linux-arm64-gnu': 4.60.0 - '@rollup/rollup-linux-arm64-musl': 4.60.0 - '@rollup/rollup-linux-loong64-gnu': 4.60.0 - '@rollup/rollup-linux-loong64-musl': 4.60.0 - '@rollup/rollup-linux-ppc64-gnu': 4.60.0 - '@rollup/rollup-linux-ppc64-musl': 4.60.0 - '@rollup/rollup-linux-riscv64-gnu': 4.60.0 - '@rollup/rollup-linux-riscv64-musl': 4.60.0 - '@rollup/rollup-linux-s390x-gnu': 4.60.0 - '@rollup/rollup-linux-x64-gnu': 4.60.0 - '@rollup/rollup-linux-x64-musl': 4.60.0 - '@rollup/rollup-openbsd-x64': 4.60.0 - '@rollup/rollup-openharmony-arm64': 4.60.0 - '@rollup/rollup-win32-arm64-msvc': 4.60.0 - '@rollup/rollup-win32-ia32-msvc': 4.60.0 - '@rollup/rollup-win32-x64-gnu': 4.60.0 - '@rollup/rollup-win32-x64-msvc': 4.60.0 + '@rollup/rollup-android-arm-eabi': 4.60.2 + '@rollup/rollup-android-arm64': 4.60.2 + '@rollup/rollup-darwin-arm64': 4.60.2 + '@rollup/rollup-darwin-x64': 4.60.2 + '@rollup/rollup-freebsd-arm64': 4.60.2 + '@rollup/rollup-freebsd-x64': 4.60.2 + '@rollup/rollup-linux-arm-gnueabihf': 4.60.2 + '@rollup/rollup-linux-arm-musleabihf': 4.60.2 + '@rollup/rollup-linux-arm64-gnu': 4.60.2 + '@rollup/rollup-linux-arm64-musl': 4.60.2 + '@rollup/rollup-linux-loong64-gnu': 4.60.2 + '@rollup/rollup-linux-loong64-musl': 4.60.2 + '@rollup/rollup-linux-ppc64-gnu': 4.60.2 + '@rollup/rollup-linux-ppc64-musl': 4.60.2 + '@rollup/rollup-linux-riscv64-gnu': 4.60.2 + '@rollup/rollup-linux-riscv64-musl': 4.60.2 + '@rollup/rollup-linux-s390x-gnu': 4.60.2 + '@rollup/rollup-linux-x64-gnu': 4.60.2 + '@rollup/rollup-linux-x64-musl': 4.60.2 + '@rollup/rollup-openbsd-x64': 4.60.2 + '@rollup/rollup-openharmony-arm64': 4.60.2 + '@rollup/rollup-win32-arm64-msvc': 4.60.2 + '@rollup/rollup-win32-ia32-msvc': 4.60.2 + '@rollup/rollup-win32-x64-gnu': 4.60.2 + '@rollup/rollup-win32-x64-msvc': 4.60.2 fsevents: 2.3.3 rope-sequence@1.3.4: {} @@ -12651,65 +12901,65 @@ snapshots: safer-buffer@2.1.2: {} - sass-embedded-all-unknown@1.98.0: + sass-embedded-all-unknown@1.99.0: dependencies: - sass: 1.98.0 + sass: 1.99.0 optional: true - sass-embedded-android-arm64@1.98.0: + sass-embedded-android-arm64@1.99.0: optional: true - sass-embedded-android-arm@1.98.0: + sass-embedded-android-arm@1.99.0: optional: true - sass-embedded-android-riscv64@1.98.0: + sass-embedded-android-riscv64@1.99.0: optional: true - sass-embedded-android-x64@1.98.0: + sass-embedded-android-x64@1.99.0: optional: true - sass-embedded-darwin-arm64@1.98.0: + sass-embedded-darwin-arm64@1.99.0: optional: true - sass-embedded-darwin-x64@1.98.0: + sass-embedded-darwin-x64@1.99.0: optional: true - sass-embedded-linux-arm64@1.98.0: + sass-embedded-linux-arm64@1.99.0: optional: true - sass-embedded-linux-arm@1.98.0: + sass-embedded-linux-arm@1.99.0: optional: true - sass-embedded-linux-musl-arm64@1.98.0: + sass-embedded-linux-musl-arm64@1.99.0: optional: true - sass-embedded-linux-musl-arm@1.98.0: + sass-embedded-linux-musl-arm@1.99.0: optional: true - sass-embedded-linux-musl-riscv64@1.98.0: + sass-embedded-linux-musl-riscv64@1.99.0: optional: true - sass-embedded-linux-musl-x64@1.98.0: + sass-embedded-linux-musl-x64@1.99.0: optional: true - sass-embedded-linux-riscv64@1.98.0: + sass-embedded-linux-riscv64@1.99.0: optional: true - sass-embedded-linux-x64@1.98.0: + sass-embedded-linux-x64@1.99.0: optional: true - sass-embedded-unknown-all@1.98.0: + sass-embedded-unknown-all@1.99.0: dependencies: - sass: 1.98.0 + sass: 1.99.0 optional: true - sass-embedded-win32-arm64@1.98.0: + sass-embedded-win32-arm64@1.99.0: optional: true - sass-embedded-win32-x64@1.98.0: + sass-embedded-win32-x64@1.99.0: optional: true - sass-embedded@1.98.0: + sass-embedded@1.99.0: dependencies: '@bufbuild/protobuf': 2.5.2 colorjs.io: 0.5.2 @@ -12719,26 +12969,26 @@ snapshots: sync-child-process: 1.0.2 varint: 6.0.0 optionalDependencies: - sass-embedded-all-unknown: 1.98.0 - sass-embedded-android-arm: 1.98.0 - sass-embedded-android-arm64: 1.98.0 - sass-embedded-android-riscv64: 1.98.0 - sass-embedded-android-x64: 1.98.0 - sass-embedded-darwin-arm64: 1.98.0 - sass-embedded-darwin-x64: 1.98.0 - sass-embedded-linux-arm: 1.98.0 - sass-embedded-linux-arm64: 1.98.0 - sass-embedded-linux-musl-arm: 1.98.0 - sass-embedded-linux-musl-arm64: 1.98.0 - sass-embedded-linux-musl-riscv64: 1.98.0 - sass-embedded-linux-musl-x64: 1.98.0 - sass-embedded-linux-riscv64: 1.98.0 - sass-embedded-linux-x64: 1.98.0 - sass-embedded-unknown-all: 1.98.0 - sass-embedded-win32-arm64: 1.98.0 - sass-embedded-win32-x64: 1.98.0 + sass-embedded-all-unknown: 1.99.0 + sass-embedded-android-arm: 1.99.0 + sass-embedded-android-arm64: 1.99.0 + sass-embedded-android-riscv64: 1.99.0 + sass-embedded-android-x64: 1.99.0 + sass-embedded-darwin-arm64: 1.99.0 + sass-embedded-darwin-x64: 1.99.0 + sass-embedded-linux-arm: 1.99.0 + sass-embedded-linux-arm64: 1.99.0 + sass-embedded-linux-musl-arm: 1.99.0 + sass-embedded-linux-musl-arm64: 1.99.0 + sass-embedded-linux-musl-riscv64: 1.99.0 + sass-embedded-linux-musl-x64: 1.99.0 + sass-embedded-linux-riscv64: 1.99.0 + sass-embedded-linux-x64: 1.99.0 + sass-embedded-unknown-all: 1.99.0 + sass-embedded-win32-arm64: 1.99.0 + sass-embedded-win32-x64: 1.99.0 - sass@1.98.0: + sass@1.99.0: dependencies: chokidar: 4.0.3 immutable: 5.1.5 @@ -12762,11 +13012,9 @@ snapshots: semver@6.3.1: {} - semver@7.7.1: {} - semver@7.7.3: {} - serialize-javascript@7.0.3: {} + serialize-javascript@7.0.5: {} set-function-length@1.2.2: dependencies: @@ -12934,13 +13182,13 @@ snapshots: dependencies: eastasianwidth: 0.2.0 emoji-regex: 9.2.2 - strip-ansi: 7.1.0 + strip-ansi: 7.2.0 string-width@7.2.0: dependencies: emoji-regex: 10.6.0 - get-east-asian-width: 1.4.0 - strip-ansi: 7.1.0 + get-east-asian-width: 1.5.0 + strip-ansi: 7.2.0 string-width@8.2.0: dependencies: @@ -13000,10 +13248,6 @@ snapshots: dependencies: ansi-regex: 5.0.1 - strip-ansi@7.1.0: - dependencies: - ansi-regex: 6.0.1 - strip-ansi@7.2.0: dependencies: ansi-regex: 6.2.2 @@ -13028,82 +13272,78 @@ snapshots: style-mod@4.1.2: {} - stylelint-config-html@1.1.0(postcss-html@1.8.0)(stylelint@17.5.0(typescript@5.9.3)): + stylelint-config-html@1.1.0(postcss-html@1.8.1)(stylelint@17.9.0(typescript@5.9.3)): dependencies: - postcss-html: 1.8.0 - stylelint: 17.5.0(typescript@5.9.3) + postcss-html: 1.8.1 + stylelint: 17.9.0(typescript@5.9.3) - stylelint-config-property-sort-order-smacss@10.0.0(stylelint@17.5.0(typescript@5.9.3)): + stylelint-config-property-sort-order-smacss@10.0.0(stylelint@17.9.0(typescript@5.9.3)): dependencies: css-property-sort-order-smacss: 2.2.0 - stylelint: 17.5.0(typescript@5.9.3) - stylelint-order: 6.0.4(stylelint@17.5.0(typescript@5.9.3)) + stylelint: 17.9.0(typescript@5.9.3) + stylelint-order: 6.0.4(stylelint@17.9.0(typescript@5.9.3)) - stylelint-config-recommended-scss@17.0.0(postcss@8.5.8)(stylelint@17.5.0(typescript@5.9.3)): + stylelint-config-recommended-scss@17.0.0(postcss@8.5.10)(stylelint@17.9.0(typescript@5.9.3)): dependencies: - postcss-scss: 4.0.9(postcss@8.5.8) - stylelint: 17.5.0(typescript@5.9.3) - stylelint-config-recommended: 18.0.0(stylelint@17.5.0(typescript@5.9.3)) - stylelint-scss: 7.0.0(stylelint@17.5.0(typescript@5.9.3)) + postcss-scss: 4.0.9(postcss@8.5.10) + stylelint: 17.9.0(typescript@5.9.3) + stylelint-config-recommended: 18.0.0(stylelint@17.9.0(typescript@5.9.3)) + stylelint-scss: 7.0.0(stylelint@17.9.0(typescript@5.9.3)) optionalDependencies: - postcss: 8.5.8 + postcss: 8.5.10 - stylelint-config-recommended-vue@1.6.1(postcss-html@1.8.0)(stylelint@17.5.0(typescript@5.9.3)): + stylelint-config-recommended-vue@1.6.1(postcss-html@1.8.1)(stylelint@17.9.0(typescript@5.9.3)): dependencies: - postcss-html: 1.8.0 - semver: 7.7.1 - stylelint: 17.5.0(typescript@5.9.3) - stylelint-config-html: 1.1.0(postcss-html@1.8.0)(stylelint@17.5.0(typescript@5.9.3)) - stylelint-config-recommended: 17.0.0(stylelint@17.5.0(typescript@5.9.3)) + postcss-html: 1.8.1 + semver: 7.7.3 + stylelint: 17.9.0(typescript@5.9.3) + stylelint-config-html: 1.1.0(postcss-html@1.8.1)(stylelint@17.9.0(typescript@5.9.3)) + stylelint-config-recommended: 18.0.0(stylelint@17.9.0(typescript@5.9.3)) - stylelint-config-recommended@17.0.0(stylelint@17.5.0(typescript@5.9.3)): + stylelint-config-recommended@18.0.0(stylelint@17.9.0(typescript@5.9.3)): dependencies: - stylelint: 17.5.0(typescript@5.9.3) + stylelint: 17.9.0(typescript@5.9.3) - stylelint-config-recommended@18.0.0(stylelint@17.5.0(typescript@5.9.3)): + stylelint-config-standard-scss@17.0.0(postcss@8.5.10)(stylelint@17.9.0(typescript@5.9.3)): dependencies: - stylelint: 17.5.0(typescript@5.9.3) - - stylelint-config-standard-scss@17.0.0(postcss@8.5.8)(stylelint@17.5.0(typescript@5.9.3)): - dependencies: - stylelint: 17.5.0(typescript@5.9.3) - stylelint-config-recommended-scss: 17.0.0(postcss@8.5.8)(stylelint@17.5.0(typescript@5.9.3)) - stylelint-config-standard: 40.0.0(stylelint@17.5.0(typescript@5.9.3)) + stylelint: 17.9.0(typescript@5.9.3) + stylelint-config-recommended-scss: 17.0.0(postcss@8.5.10)(stylelint@17.9.0(typescript@5.9.3)) + stylelint-config-standard: 40.0.0(stylelint@17.9.0(typescript@5.9.3)) optionalDependencies: - postcss: 8.5.8 + postcss: 8.5.10 - stylelint-config-standard@40.0.0(stylelint@17.5.0(typescript@5.9.3)): + stylelint-config-standard@40.0.0(stylelint@17.9.0(typescript@5.9.3)): dependencies: - stylelint: 17.5.0(typescript@5.9.3) - stylelint-config-recommended: 18.0.0(stylelint@17.5.0(typescript@5.9.3)) + stylelint: 17.9.0(typescript@5.9.3) + stylelint-config-recommended: 18.0.0(stylelint@17.9.0(typescript@5.9.3)) - stylelint-order@6.0.4(stylelint@17.5.0(typescript@5.9.3)): + stylelint-order@6.0.4(stylelint@17.9.0(typescript@5.9.3)): dependencies: - postcss: 8.5.8 - postcss-sorting: 8.0.2(postcss@8.5.8) - stylelint: 17.5.0(typescript@5.9.3) + postcss: 8.5.10 + postcss-sorting: 8.0.2(postcss@8.5.10) + stylelint: 17.9.0(typescript@5.9.3) - stylelint-scss@7.0.0(stylelint@17.5.0(typescript@5.9.3)): + stylelint-scss@7.0.0(stylelint@17.9.0(typescript@5.9.3)): dependencies: - css-tree: 3.1.0 + css-tree: 3.2.1 is-plain-object: 5.0.0 known-css-properties: 0.37.0 - mdn-data: 2.26.0 + mdn-data: 2.27.1 postcss-media-query-parser: 0.2.3 postcss-resolve-nested-selector: 0.1.6 postcss-selector-parser: 7.1.1 postcss-value-parser: 4.2.0 - stylelint: 17.5.0(typescript@5.9.3) + stylelint: 17.9.0(typescript@5.9.3) - stylelint-use-logical@2.1.3(stylelint@17.5.0(typescript@5.9.3)): + stylelint-use-logical@2.1.3(stylelint@17.9.0(typescript@5.9.3)): dependencies: - stylelint: 17.5.0(typescript@5.9.3) + stylelint: 17.9.0(typescript@5.9.3) - stylelint@17.5.0(typescript@5.9.3): + stylelint@17.9.0(typescript@5.9.3): dependencies: - '@csstools/css-calc': 3.1.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) + '@csstools/css-calc': 3.2.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) - '@csstools/css-syntax-patches-for-csstree': 1.1.1(css-tree@3.2.1) + '@csstools/css-syntax-patches-for-csstree': 1.1.3(css-tree@3.2.1) '@csstools/css-tokenizer': 4.0.0 '@csstools/media-query-list-parser': 5.0.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/selector-resolve-nested': 4.0.0(postcss-selector-parser@7.1.1) @@ -13117,27 +13357,26 @@ snapshots: fastest-levenshtein: 1.0.16 file-entry-cache: 11.1.2 global-modules: 2.0.0 - globby: 16.1.1 + globby: 16.2.0 globjoin: 0.1.4 html-tags: 5.1.0 ignore: 7.0.5 import-meta-resolve: 4.2.0 - imurmurhash: 0.1.4 is-plain-object: 5.0.0 mathml-tag-names: 4.0.0 meow: 14.1.0 micromatch: 4.0.8 normalize-path: 3.0.0 picocolors: 1.1.1 - postcss: 8.5.8 - postcss-safe-parser: 7.0.1(postcss@8.5.8) + postcss: 8.5.10 + postcss-safe-parser: 7.0.1(postcss@8.5.10) postcss-selector-parser: 7.1.1 postcss-value-parser: 4.2.0 string-width: 8.2.0 supports-hyperlinks: 4.4.0 svg-tags: 1.0.0 table: 6.9.0 - write-file-atomic: 7.0.0 + write-file-atomic: 7.0.1 transitivePeerDependencies: - supports-color - typescript @@ -13191,7 +13430,7 @@ snapshots: string-width: 4.2.3 strip-ansi: 6.0.1 - tailwindcss@4.2.2: {} + tailwindcss@4.2.4: {} tapable@2.3.0: {} @@ -13231,6 +13470,8 @@ snapshots: dependencies: b4a: 1.6.7 + thirty-two@1.0.2: {} + through@2.3.8: {} tinybench@2.9.0: {} @@ -13242,7 +13483,7 @@ snapshots: fdir: 6.5.0(picomatch@4.0.4) picomatch: 4.0.4 - tinyrainbow@3.0.3: {} + tinyrainbow@3.1.0: {} tldts-core@6.1.58: {} @@ -13292,7 +13533,7 @@ snapshots: trim-newlines@3.0.1: {} - ts-api-utils@2.4.0(typescript@5.9.3): + ts-api-utils@2.5.0(typescript@5.9.3): dependencies: typescript: 5.9.3 @@ -13350,13 +13591,13 @@ snapshots: typed-query-selector@2.12.0: {} - typescript-eslint@8.56.0(eslint@9.39.4(jiti@2.4.2))(typescript@5.9.3): + typescript-eslint@8.56.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3): dependencies: - '@typescript-eslint/eslint-plugin': 8.56.0(@typescript-eslint/parser@8.56.0(eslint@9.39.4(jiti@2.4.2))(typescript@5.9.3))(eslint@9.39.4(jiti@2.4.2))(typescript@5.9.3) - '@typescript-eslint/parser': 8.56.0(eslint@9.39.4(jiti@2.4.2))(typescript@5.9.3) + '@typescript-eslint/eslint-plugin': 8.56.0(@typescript-eslint/parser@8.56.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/parser': 8.56.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) '@typescript-eslint/typescript-estree': 8.56.0(typescript@5.9.3) - '@typescript-eslint/utils': 8.56.0(eslint@9.39.4(jiti@2.4.2))(typescript@5.9.3) - eslint: 9.39.4(jiti@2.4.2) + '@typescript-eslint/utils': 8.56.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + eslint: 9.39.4(jiti@2.6.1) typescript: 5.9.3 transitivePeerDependencies: - supports-color @@ -13447,7 +13688,7 @@ snapshots: unplugin@1.12.2: dependencies: - acorn: 8.14.0 + acorn: 8.15.0 chokidar: 3.6.0 webpack-sources: 3.2.3 webpack-virtual-modules: 0.6.2 @@ -13461,9 +13702,9 @@ snapshots: upath@1.2.0: {} - update-browserslist-db@1.2.2(browserslist@4.28.1): + update-browserslist-db@1.2.3(browserslist@4.28.2): dependencies: - browserslist: 4.28.1 + browserslist: 4.28.2 escalade: 3.2.0 picocolors: 1.1.1 @@ -13505,23 +13746,23 @@ snapshots: '@types/unist': 3.0.3 vfile-message: 4.0.2 - vite-dev-rpc@1.1.0(vite@7.3.1(@types/node@24.12.0)(jiti@2.4.2)(lightningcss@1.32.0)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.31.6)(yaml@2.8.3)): + vite-dev-rpc@1.1.0(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)): dependencies: birpc: 2.6.1 - vite: 7.3.1(@types/node@24.12.0)(jiti@2.4.2)(lightningcss@1.32.0)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.31.6)(yaml@2.8.3) - vite-hot-client: 2.1.0(vite@7.3.1(@types/node@24.12.0)(jiti@2.4.2)(lightningcss@1.32.0)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.31.6)(yaml@2.8.3)) + vite: 7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) + vite-hot-client: 2.1.0(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) - vite-hot-client@2.1.0(vite@7.3.1(@types/node@24.12.0)(jiti@2.4.2)(lightningcss@1.32.0)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.31.6)(yaml@2.8.3)): + vite-hot-client@2.1.0(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)): dependencies: - vite: 7.3.1(@types/node@24.12.0)(jiti@2.4.2)(lightningcss@1.32.0)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.31.6)(yaml@2.8.3) + vite: 7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) - vite-node@3.2.4(@types/node@24.12.0)(jiti@2.4.2)(lightningcss@1.32.0)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.31.6)(yaml@2.8.3): + vite-node@3.2.4(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3): dependencies: cac: 6.7.14 debug: 4.4.3 es-module-lexer: 1.7.0 pathe: 2.0.3 - vite: 7.3.1(@types/node@24.12.0)(jiti@2.4.2)(lightningcss@1.32.0)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.31.6)(yaml@2.8.3) + vite: 7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) transitivePeerDependencies: - '@types/node' - jiti @@ -13536,7 +13777,7 @@ snapshots: - tsx - yaml - vite-plugin-inspect@11.3.3(vite@7.3.1(@types/node@24.12.0)(jiti@2.4.2)(lightningcss@1.32.0)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.31.6)(yaml@2.8.3)): + vite-plugin-inspect@11.3.3(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)): dependencies: ansis: 4.1.0 debug: 4.4.3 @@ -13546,37 +13787,37 @@ snapshots: perfect-debounce: 2.0.0 sirv: 3.0.2 unplugin-utils: 0.3.0 - vite: 7.3.1(@types/node@24.12.0)(jiti@2.4.2)(lightningcss@1.32.0)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.31.6)(yaml@2.8.3) - vite-dev-rpc: 1.1.0(vite@7.3.1(@types/node@24.12.0)(jiti@2.4.2)(lightningcss@1.32.0)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.31.6)(yaml@2.8.3)) + vite: 7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) + vite-dev-rpc: 1.1.0(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) transitivePeerDependencies: - supports-color - vite-plugin-pwa@1.2.0(vite@7.3.1(@types/node@24.12.0)(jiti@2.4.2)(lightningcss@1.32.0)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.31.6)(yaml@2.8.3))(workbox-build@7.4.0)(workbox-window@7.4.0): + vite-plugin-pwa@1.2.0(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(workbox-build@7.4.0)(workbox-window@7.4.0): dependencies: debug: 4.4.3 pretty-bytes: 6.1.1 tinyglobby: 0.2.15 - vite: 7.3.1(@types/node@24.12.0)(jiti@2.4.2)(lightningcss@1.32.0)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.31.6)(yaml@2.8.3) + vite: 7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) workbox-build: 7.4.0 workbox-window: 7.4.0 transitivePeerDependencies: - supports-color - vite-plugin-vue-devtools@8.1.1(vite@7.3.1(@types/node@24.12.0)(jiti@2.4.2)(lightningcss@1.32.0)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.31.6)(yaml@2.8.3))(vue@3.5.27(typescript@5.9.3)): + vite-plugin-vue-devtools@8.1.1(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3))(vue@3.5.27(typescript@5.9.3)): dependencies: '@vue/devtools-core': 8.1.1(vue@3.5.27(typescript@5.9.3)) '@vue/devtools-kit': 8.1.1 '@vue/devtools-shared': 8.1.1 sirv: 3.0.2 - vite: 7.3.1(@types/node@24.12.0)(jiti@2.4.2)(lightningcss@1.32.0)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.31.6)(yaml@2.8.3) - vite-plugin-inspect: 11.3.3(vite@7.3.1(@types/node@24.12.0)(jiti@2.4.2)(lightningcss@1.32.0)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.31.6)(yaml@2.8.3)) - vite-plugin-vue-inspector: 5.3.2(vite@7.3.1(@types/node@24.12.0)(jiti@2.4.2)(lightningcss@1.32.0)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.31.6)(yaml@2.8.3)) + vite: 7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) + vite-plugin-inspect: 11.3.3(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) + vite-plugin-vue-inspector: 5.3.2(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) transitivePeerDependencies: - '@nuxt/kit' - supports-color - vue - vite-plugin-vue-inspector@5.3.2(vite@7.3.1(@types/node@24.12.0)(jiti@2.4.2)(lightningcss@1.32.0)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.31.6)(yaml@2.8.3)): + vite-plugin-vue-inspector@5.3.2(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)): dependencies: '@babel/core': 7.26.0 '@babel/plugin-proposal-decorators': 7.25.9(@babel/core@7.26.0) @@ -13587,7 +13828,7 @@ snapshots: '@vue/compiler-dom': 3.5.27 kolorist: 1.8.0 magic-string: 0.30.21 - vite: 7.3.1(@types/node@24.12.0)(jiti@2.4.2)(lightningcss@1.32.0)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.31.6)(yaml@2.8.3) + vite: 7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) transitivePeerDependencies: - supports-color @@ -13599,33 +13840,33 @@ snapshots: transitivePeerDependencies: - supports-color - vite@7.3.1(@types/node@24.12.0)(jiti@2.4.2)(lightningcss@1.32.0)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.31.6)(yaml@2.8.3): + vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3): dependencies: - esbuild: 0.27.4 + esbuild: 0.27.5 fdir: 6.5.0(picomatch@4.0.4) picomatch: 4.0.4 - postcss: 8.5.8 - rollup: 4.60.0 + postcss: 8.5.10 + rollup: 4.60.2 tinyglobby: 0.2.15 optionalDependencies: - '@types/node': 24.12.0 + '@types/node': 24.12.2 fsevents: 2.3.3 - jiti: 2.4.2 + jiti: 2.6.1 lightningcss: 1.32.0 - sass: 1.98.0 - sass-embedded: 1.98.0 + sass: 1.99.0 + sass-embedded: 1.99.0 terser: 5.31.6 yaml: 2.8.3 - vitest@4.1.1(@types/node@24.12.0)(happy-dom@20.8.8)(jsdom@27.4.0)(vite@7.3.1(@types/node@24.12.0)(jiti@2.4.2)(lightningcss@1.32.0)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.31.6)(yaml@2.8.3)): + vitest@4.1.5(@types/node@24.12.2)(happy-dom@20.9.0)(jsdom@27.4.0)(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)): dependencies: - '@vitest/expect': 4.1.1 - '@vitest/mocker': 4.1.1(vite@7.3.1(@types/node@24.12.0)(jiti@2.4.2)(lightningcss@1.32.0)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.31.6)(yaml@2.8.3)) - '@vitest/pretty-format': 4.1.1 - '@vitest/runner': 4.1.1 - '@vitest/snapshot': 4.1.1 - '@vitest/spy': 4.1.1 - '@vitest/utils': 4.1.1 + '@vitest/expect': 4.1.5 + '@vitest/mocker': 4.1.5(vite@7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3)) + '@vitest/pretty-format': 4.1.5 + '@vitest/runner': 4.1.5 + '@vitest/snapshot': 4.1.5 + '@vitest/spy': 4.1.5 + '@vitest/utils': 4.1.5 es-module-lexer: 2.0.0 expect-type: 1.3.0 magic-string: 0.30.21 @@ -13636,12 +13877,12 @@ snapshots: tinybench: 2.9.0 tinyexec: 1.0.2 tinyglobby: 0.2.15 - tinyrainbow: 3.0.3 - vite: 7.3.1(@types/node@24.12.0)(jiti@2.4.2)(lightningcss@1.32.0)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.31.6)(yaml@2.8.3) + tinyrainbow: 3.1.0 + vite: 7.3.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass-embedded@1.99.0)(sass@1.99.0)(terser@5.31.6)(yaml@2.8.3) why-is-node-running: 2.3.0 optionalDependencies: - '@types/node': 24.12.0 - happy-dom: 20.8.8 + '@types/node': 24.12.2 + happy-dom: 20.9.0 jsdom: 27.4.0 transitivePeerDependencies: - msw @@ -13655,16 +13896,16 @@ snapshots: easy-bem: 1.1.1 vue: 3.5.27(typescript@5.9.3) - vue-component-type-helpers@2.0.29: {} + vue-component-type-helpers@3.2.7: {} vue-demi@0.14.10(vue@3.5.27(typescript@5.9.3)): dependencies: vue: 3.5.27(typescript@5.9.3) - vue-eslint-parser@10.4.0(eslint@9.39.4(jiti@2.4.2)): + vue-eslint-parser@10.4.0(eslint@9.39.4(jiti@2.6.1)): dependencies: debug: 4.4.3 - eslint: 9.39.4(jiti@2.4.2) + eslint: 9.39.4(jiti@2.6.1) eslint-scope: 8.4.0 eslint-visitor-keys: 5.0.0 espree: 10.4.0 @@ -13694,10 +13935,10 @@ snapshots: '@vue/devtools-api': 6.6.4 vue: 3.5.27(typescript@5.9.3) - vue-tsc@3.2.6(typescript@5.9.3): + vue-tsc@3.2.7(typescript@5.9.3): dependencies: '@volar/typescript': 2.4.28 - '@vue/language-core': 3.2.6 + '@vue/language-core': 3.2.7 typescript: 5.9.3 vue@3.5.27(typescript@5.9.3): @@ -13722,11 +13963,11 @@ snapshots: dependencies: xml-name-validator: 5.0.0 - wait-on@9.0.4: + wait-on@9.0.5: dependencies: - axios: 1.13.5 - joi: 18.0.2 - lodash: 4.17.23 + axios: 1.15.0 + joi: 18.1.2 + lodash: 4.18.1 minimist: 1.2.8 rxjs: 7.8.2 transitivePeerDependencies: @@ -13820,19 +14061,19 @@ snapshots: '@babel/core': 7.26.0 '@babel/preset-env': 7.26.0(@babel/core@7.26.0) '@babel/runtime': 7.25.4 - '@rollup/plugin-babel': 5.3.1(@babel/core@7.26.0)(rollup@4.60.0) - '@rollup/plugin-node-resolve': 15.2.3(rollup@4.60.0) - '@rollup/plugin-replace': 2.4.2(rollup@4.60.0) - '@rollup/plugin-terser': 0.4.4(rollup@4.60.0) + '@rollup/plugin-babel': 5.3.1(@babel/core@7.26.0)(rollup@4.60.2) + '@rollup/plugin-node-resolve': 15.2.3(rollup@4.60.2) + '@rollup/plugin-replace': 2.4.2(rollup@4.60.2) + '@rollup/plugin-terser': 0.4.4(rollup@4.60.2) '@surma/rollup-plugin-off-main-thread': 2.2.3 ajv: 8.18.0 common-tags: 1.8.2 fast-json-stable-stringify: 2.1.0 fs-extra: 9.1.0 glob: 11.1.0 - lodash: 4.17.23 + lodash: 4.18.1 pretty-bytes: 5.6.0 - rollup: 4.60.0 + rollup: 4.60.2 source-map: 0.8.0-beta.0 stringify-object: 3.3.0 strip-comments: 2.0.1 @@ -13947,22 +14188,21 @@ snapshots: dependencies: ansi-styles: 6.2.1 string-width: 5.1.2 - strip-ansi: 7.1.0 + strip-ansi: 7.2.0 wrap-ansi@9.0.2: dependencies: ansi-styles: 6.2.1 string-width: 7.2.0 - strip-ansi: 7.1.0 + strip-ansi: 7.2.0 wrappy@1.0.2: {} - write-file-atomic@7.0.0: + write-file-atomic@7.0.1: dependencies: - imurmurhash: 0.1.4 signal-exit: 4.1.0 - ws@8.19.0: {} + ws@8.20.0: {} wsl-utils@0.1.0: dependencies: @@ -13983,7 +14223,7 @@ snapshots: yaml-eslint-parser@1.2.3: dependencies: eslint-visitor-keys: 3.4.3 - lodash: 4.17.23 + lodash: 4.18.1 yaml: 2.8.3 yaml@2.8.3: {} diff --git a/frontend/src/App.vue b/frontend/src/App.vue index c1b3c7c7f..08688b1bb 100644 --- a/frontend/src/App.vue +++ b/frontend/src/App.vue @@ -1,24 +1,40 @@ + + diff --git a/frontend/src/components/input/FormInput.test.ts b/frontend/src/components/input/FormInput.test.ts new file mode 100644 index 000000000..4f23ec033 --- /dev/null +++ b/frontend/src/components/input/FormInput.test.ts @@ -0,0 +1,123 @@ +import {describe, it, expect, vi} from 'vitest' +import {mount} from '@vue/test-utils' +import FormInput from './FormInput.vue' + +describe('FormInput', () => { + it('renders a Bulma-classed input', () => { + const wrapper = mount(FormInput) + const input = wrapper.find('input') + expect(input.exists()).toBe(true) + expect(input.classes()).toContain('input') + }) + + it('supports v-model', async () => { + const wrapper = mount(FormInput, { + props: { + modelValue: 'hello', + 'onUpdate:modelValue': (val: string | number) => wrapper.setProps({modelValue: val}), + }, + }) + const input = wrapper.find('input') + expect(input.element.value).toBe('hello') + + await input.setValue('world') + expect(wrapper.props('modelValue')).toBe('world') + }) + + it('preserves numeric type in v-model when modelValue is a number', async () => { + const wrapper = mount(FormInput, { + props: { + modelValue: 42, + 'onUpdate:modelValue': (val: number | string) => wrapper.setProps({modelValue: val as number}), + }, + }) + await wrapper.find('input').setValue('7') + expect(wrapper.props('modelValue')).toBe(7) + }) + + it('coerces to number when the .number modifier is set even if modelValue starts null', async () => { + const wrapper = mount(FormInput, { + props: { + modelValue: null, + modelModifiers: {number: true}, + 'onUpdate:modelValue': (val: number | string) => wrapper.setProps({modelValue: val as number}), + }, + }) + await wrapper.find('input').setValue('42') + expect(wrapper.props('modelValue')).toBe(42) + expect(typeof wrapper.props('modelValue')).toBe('number') + }) + + it('applies is-loading class when loading', () => { + const wrapper = mount(FormInput, {props: {loading: true}}) + expect(wrapper.find('input').classes()).toContain('is-loading') + }) + + it('applies disabled class and attribute when disabled', () => { + const wrapper = mount(FormInput, {props: {disabled: true}}) + const input = wrapper.find('input') + expect(input.classes()).toContain('disabled') + expect(input.attributes('disabled')).toBe('') + }) + + it('uses an explicit id prop when given', () => { + const wrapper = mount(FormInput, {props: {id: 'my-id'}}) + expect(wrapper.find('input').attributes('id')).toBe('my-id') + }) + + it('generates a unique id when no id prop is given', () => { + const wrapper = mount({ + components: {FormInput}, + template: '
', + }) + const inputs = wrapper.findAll('input') + const id1 = inputs[0].attributes('id') + const id2 = inputs[1].attributes('id') + expect(id1).toBeTruthy() + expect(id2).toBeTruthy() + expect(id1).not.toBe(id2) + }) + + it('forwards $attrs (type, placeholder, autocomplete) to the input', () => { + const wrapper = mount(FormInput, { + attrs: { + type: 'email', + placeholder: 'Enter email', + autocomplete: 'email', + }, + }) + const input = wrapper.find('input') + expect(input.attributes('type')).toBe('email') + expect(input.attributes('placeholder')).toBe('Enter email') + expect(input.attributes('autocomplete')).toBe('email') + }) + + it('forwards event listeners', async () => { + const onKeyup = vi.fn() + const wrapper = mount(FormInput, {attrs: {onKeyup}}) + await wrapper.find('input').trigger('keyup', {key: 'Enter'}) + expect(onKeyup).toHaveBeenCalledTimes(1) + }) + + it('renders error message when error prop is set', () => { + const wrapper = mount(FormInput, {props: {error: 'Required'}}) + const help = wrapper.find('p.help.is-danger') + expect(help.exists()).toBe(true) + expect(help.text()).toBe('Required') + }) + + it('does not render error message when error is null or empty', () => { + const nullErr = mount(FormInput, {props: {error: null}}) + expect(nullErr.find('p.help.is-danger').exists()).toBe(false) + + const emptyErr = mount(FormInput, {props: {error: ''}}) + expect(emptyErr.find('p.help.is-danger').exists()).toBe(false) + }) + + it('exposes value and focus()', async () => { + const wrapper = mount(FormInput) + await wrapper.find('input').setValue('test value') + expect(wrapper.vm.value).toBe('test value') + expect(() => wrapper.vm.focus()).not.toThrow() + }) +}) diff --git a/frontend/src/components/input/FormInput.vue b/frontend/src/components/input/FormInput.vue new file mode 100644 index 000000000..f02a6e1e4 --- /dev/null +++ b/frontend/src/components/input/FormInput.vue @@ -0,0 +1,83 @@ + + + diff --git a/frontend/src/components/input/FormSelect.test.ts b/frontend/src/components/input/FormSelect.test.ts new file mode 100644 index 000000000..cc7b26299 --- /dev/null +++ b/frontend/src/components/input/FormSelect.test.ts @@ -0,0 +1,173 @@ +import {describe, it, expect} from 'vitest' +import {mount} from '@vue/test-utils' +import FormSelect from './FormSelect.vue' + +describe('FormSelect', () => { + it('renders the Bulma select wrapper and a native select', () => { + const wrapper = mount(FormSelect) + expect(wrapper.find('div.select').exists()).toBe(true) + expect(wrapper.find('div.select > select').exists()).toBe(true) + }) + + it('renders options from the default slot', () => { + const wrapper = mount(FormSelect, { + slots: { + default: '', + }, + }) + expect(wrapper.findAll('option').length).toBe(2) + }) + + it('supports v-model with string values', async () => { + const wrapper = mount(FormSelect, { + props: { + modelValue: 'a', + 'onUpdate:modelValue': (val: string | number) => wrapper.setProps({modelValue: val}), + }, + slots: { + default: '', + }, + }) + const select = wrapper.find('select') + expect((select.element as HTMLSelectElement).value).toBe('a') + + await select.setValue('b') + expect(wrapper.props('modelValue')).toBe('b') + }) + + it('preserves numeric type in v-model when modelValue is a number', async () => { + const wrapper = mount(FormSelect, { + props: { + modelValue: 1, + 'onUpdate:modelValue': (val: string | number) => wrapper.setProps({modelValue: val}), + }, + slots: { + default: '', + }, + }) + await wrapper.find('select').setValue('2') + expect(wrapper.props('modelValue')).toBe(2) + }) + + it('coerces to number when the .number modifier is set even if modelValue starts null', async () => { + const wrapper = mount(FormSelect, { + props: { + modelValue: null, + modelModifiers: {number: true}, + 'onUpdate:modelValue': (val: string | number) => wrapper.setProps({modelValue: val}), + }, + slots: { + default: '', + }, + }) + await wrapper.find('select').setValue('2') + expect(wrapper.props('modelValue')).toBe(2) + expect(typeof wrapper.props('modelValue')).toBe('number') + }) + + it('applies is-loading on the wrapper when loading', () => { + const wrapper = mount(FormSelect, {props: {loading: true}}) + expect(wrapper.find('div.select').classes()).toContain('is-loading') + }) + + it('applies disabled to the native select', () => { + const wrapper = mount(FormSelect, {props: {disabled: true}}) + expect(wrapper.find('select').attributes('disabled')).toBe('') + }) + + it('uses an explicit id prop when given, otherwise generates one', () => { + const withProp = mount(FormSelect, {props: {id: 'explicit'}}) + expect(withProp.find('select').attributes('id')).toBe('explicit') + + const standalone = mount(FormSelect) + expect(standalone.find('select').attributes('id')).toBeTruthy() + }) + + it('renders error message when error prop is set', () => { + const wrapper = mount(FormSelect, {props: {error: 'Pick one'}}) + expect(wrapper.find('p.help.is-danger').text()).toBe('Pick one') + }) + + it('does not render error message when error is null or empty', () => { + const nullErr = mount(FormSelect, {props: {error: null}}) + expect(nullErr.find('p.help.is-danger').exists()).toBe(false) + + const emptyErr = mount(FormSelect, {props: {error: ''}}) + expect(emptyErr.find('p.help.is-danger').exists()).toBe(false) + }) + + it('renders options from the options prop with object entries', () => { + const wrapper = mount(FormSelect, { + props: { + options: [ + {value: 'a', label: 'Alpha'}, + {value: 'b', label: 'Bravo'}, + ], + }, + }) + const options = wrapper.findAll('option') + expect(options).toHaveLength(2) + expect(options[0].attributes('value')).toBe('a') + expect(options[0].text()).toBe('Alpha') + expect(options[1].attributes('value')).toBe('b') + expect(options[1].text()).toBe('Bravo') + }) + + it('coerces primitive options into value/label pairs', () => { + const wrapper = mount(FormSelect, { + props: {options: ['one', 'two']}, + }) + const options = wrapper.findAll('option') + expect(options).toHaveLength(2) + expect(options[0].attributes('value')).toBe('one') + expect(options[0].text()).toBe('one') + }) + + it('marks an option as disabled when disabled: true is given', () => { + const wrapper = mount(FormSelect, { + props: { + options: [ + {value: 'a', label: 'Alpha'}, + {value: 'b', label: 'Bravo', disabled: true}, + ], + }, + }) + const options = wrapper.findAll('option') + expect(options[0].attributes('disabled')).toBeUndefined() + expect(options[1].attributes('disabled')).toBe('') + }) + + it('falls back to the default slot when options prop is not given', () => { + const wrapper = mount(FormSelect, { + slots: { + default: '', + }, + }) + const options = wrapper.findAll('option') + expect(options).toHaveLength(1) + expect(options[0].text()).toBe('From slot') + }) + + it('does not bind value when modelValue is undefined', () => { + const wrapper = mount(FormSelect, { + slots: { + default: '', + }, + }) + const select = wrapper.find('select') + // Forcing :value="undefined" would break the native default-to-first-option behavior. + expect((select.element as HTMLSelectElement).value).toBe('') + }) + + it('ignores the slot when options prop is given', () => { + const wrapper = mount(FormSelect, { + props: {options: [{value: 'a', label: 'From prop'}]}, + slots: { + default: '', + }, + }) + const options = wrapper.findAll('option') + expect(options).toHaveLength(1) + expect(options[0].text()).toBe('From prop') + }) +}) diff --git a/frontend/src/components/input/FormSelect.vue b/frontend/src/components/input/FormSelect.vue new file mode 100644 index 000000000..ccbfe6b39 --- /dev/null +++ b/frontend/src/components/input/FormSelect.vue @@ -0,0 +1,105 @@ + + + + + diff --git a/frontend/src/components/input/Multiselect.vue b/frontend/src/components/input/Multiselect.vue index d1a7961b4..0ba654bcb 100644 --- a/frontend/src/components/input/Multiselect.vue +++ b/frontend/src/components/input/Multiselect.vue @@ -448,7 +448,7 @@ function createOrSelectOnEnter() { } function remove(item: T) { - for (const ind in internalValue.value) { + for (let ind = 0; ind < internalValue.value.length; ind++) { if (internalValue.value[ind] === item) { internalValue.value.splice(ind, 1) break diff --git a/frontend/src/components/input/Password.vue b/frontend/src/components/input/Password.vue index 919b14592..6e77a3d2e 100644 --- a/frontend/src/components/input/Password.vue +++ b/frontend/src/components/input/Password.vue @@ -7,8 +7,10 @@ :placeholder="$t('user.auth.passwordPlaceholder')" required :type="passwordFieldType" - autocomplete="current-password" + :autocomplete="autocomplete" :tabindex="tabindex" + :aria-invalid="isValid !== true ? true : undefined" + :aria-describedby="errorId" @keyup.enter="e => $emit('submit', e)" @focusout="() => {validate(); validateAfterFirst = true}" @keyup="() => {validateAfterFirst ? validate() : null}" @@ -25,14 +27,16 @@ + + diff --git a/frontend/src/components/input/editor/emoji/emojiData.test.ts b/frontend/src/components/input/editor/emoji/emojiData.test.ts new file mode 100644 index 000000000..87e57d53b --- /dev/null +++ b/frontend/src/components/input/editor/emoji/emojiData.test.ts @@ -0,0 +1,58 @@ +import {describe, it, expect, vi, beforeEach, afterEach} from 'vitest' +import {filterEmojis, __resetEmojiCacheForTest, loadEmojis} from './emojiData' + +const fixture = [ + {shortcodes: ['grinning', 'grinning_face'], annotation: 'grinning face', tags: ['face', 'grin'], emoji: '😀'}, + {shortcodes: ['eyes'], annotation: 'eyes', tags: ['look'], emoji: '👀'}, + {shortcodes: ['eyeglasses'], annotation: 'glasses', tags: ['eye'], emoji: '👓'}, + {shortcodes: ['smile'], annotation: 'grinning face with smiling eyes', tags: ['eye', 'smile'], emoji: '😄'}, +] + +describe('emojiData', () => { + beforeEach(() => { + __resetEmojiCacheForTest() + vi.stubGlobal('fetch', vi.fn().mockResolvedValue({ + ok: true, + json: async () => fixture, + })) + }) + + afterEach(() => { + vi.unstubAllGlobals() + }) + + it('flattens multi-shortcode entries and sorts alphabetically', async () => { + const idx = await loadEmojis() + const codes = idx.map(e => e.shortcode) + expect(codes).toEqual(['eyeglasses', 'eyes', 'grinning', 'grinning_face', 'smile']) + }) + + it('returns [] for empty query', () => { + expect(filterEmojis([{shortcode: 'eyes', emoji: '👀', annotation: '', tags: []}], '')).toEqual([]) + }) + + it('prefers startsWith matches over substring matches', () => { + const loaded = [ + {shortcode: 'eyeglasses', emoji: '👓', annotation: 'glasses', tags: ['eye']}, + {shortcode: 'eyes', emoji: '👀', annotation: 'eyes', tags: []}, + {shortcode: 'smile', emoji: '😄', annotation: 'grinning face with smiling eyes', tags: ['eye']}, + ] + const result = filterEmojis(loaded, 'eye') + expect(result[0].shortcode).toBe('eyeglasses') + expect(result[1].shortcode).toBe('eyes') + expect(result[2].shortcode).toBe('smile') + }) + + it('limits results to 15', () => { + const big = Array.from({length: 100}, (_, i) => ({ + shortcode: `foo_${String(i).padStart(3, '0')}`, emoji: '✨', annotation: '', tags: [], + })) + expect(filterEmojis(big, 'foo')).toHaveLength(15) + }) + + it('caches the fetch promise across calls', async () => { + await loadEmojis() + await loadEmojis() + expect((globalThis.fetch as ReturnType).mock.calls).toHaveLength(1) + }) +}) diff --git a/frontend/src/components/input/editor/emoji/emojiData.ts b/frontend/src/components/input/editor/emoji/emojiData.ts new file mode 100644 index 000000000..3ea2c662b --- /dev/null +++ b/frontend/src/components/input/editor/emoji/emojiData.ts @@ -0,0 +1,75 @@ +export interface EmojiEntry { + emoji: string + shortcode: string + annotation: string + tags: string[] +} + +interface RawEmoji { + shortcodes: string[] + annotation: string + tags?: string[] + emoji: string +} + +const MAX_RESULTS = 15 + +let cache: Promise | null = null + +export function __resetEmojiCacheForTest() { + cache = null +} + +export function loadEmojis(): Promise { + if (cache) return cache + cache = fetch('/emojis.json') + .then(res => { + if (!res.ok) throw new Error(`emojis.json HTTP ${res.status}`) + return res.json() as Promise + }) + .then(raw => { + const flat: EmojiEntry[] = [] + for (const entry of raw) { + for (const shortcode of entry.shortcodes) { + flat.push({ + emoji: entry.emoji, + shortcode, + annotation: entry.annotation, + tags: entry.tags ?? [], + }) + } + } + flat.sort((a, b) => a.shortcode.localeCompare(b.shortcode)) + return flat + }) + .catch(err => { + cache = null + throw err + }) + return cache +} + +export function filterEmojis(index: EmojiEntry[], rawQuery: string): EmojiEntry[] { + const query = rawQuery.toLowerCase() + if (query === '') return [] + + const starts: EmojiEntry[] = [] + const contains: EmojiEntry[] = [] + + for (const entry of index) { + if (entry.shortcode.startsWith(query)) { + starts.push(entry) + continue + } + if ( + entry.shortcode.includes(query) || + entry.annotation.toLowerCase().includes(query) || + entry.tags.some(t => t.toLowerCase().includes(query)) + ) { + contains.push(entry) + } + if (starts.length >= MAX_RESULTS) break + } + + return [...starts, ...contains].slice(0, MAX_RESULTS) +} diff --git a/frontend/src/components/input/editor/emoji/emojiExtension.ts b/frontend/src/components/input/editor/emoji/emojiExtension.ts new file mode 100644 index 000000000..c83d13339 --- /dev/null +++ b/frontend/src/components/input/editor/emoji/emojiExtension.ts @@ -0,0 +1,23 @@ +import {Extension} from '@tiptap/core' +import Suggestion from '@tiptap/suggestion' + +import emojiSuggestionSetup from './emojiSuggestion' + +export const EmojiExtension = Extension.create({ + name: 'emojiAutocomplete', + + addOptions() { + return { + suggestion: emojiSuggestionSetup(), + } + }, + + addProseMirrorPlugins() { + return [ + Suggestion({ + editor: this.editor, + ...this.options.suggestion, + }), + ] + }, +}) diff --git a/frontend/src/components/input/editor/emoji/emojiSuggestion.ts b/frontend/src/components/input/editor/emoji/emojiSuggestion.ts new file mode 100644 index 000000000..22dad82b2 --- /dev/null +++ b/frontend/src/components/input/editor/emoji/emojiSuggestion.ts @@ -0,0 +1,147 @@ +import {VueRenderer} from '@tiptap/vue-3' +import {computePosition, flip, shift, offset, autoUpdate} from '@floating-ui/dom' +import type {Editor, Range} from '@tiptap/core' +import {PluginKey, type EditorState} from '@tiptap/pm/state' + +import EmojiList from './EmojiList.vue' +import {loadEmojis, filterEmojis, type EmojiEntry} from './emojiData' + +export const EmojiSuggestionPluginKey = new PluginKey('emojiSuggestion') + +interface SuggestionProps { + editor: Editor + range: Range + query: string + clientRect?: (() => DOMRect | null) | null + items: EmojiEntry[] + command: (item: EmojiEntry) => void + event?: KeyboardEvent +} + +const SHORTCODE_RE = /^[a-zA-Z0-9_]*$/ + +export default function emojiSuggestionSetup() { + return { + pluginKey: EmojiSuggestionPluginKey, + char: ':', + allowedPrefixes: [' ', '\t', '\n'], + startOfLine: false, + + allow: ({state, range}: {state: EditorState, range: Range}) => { + const text = state.doc.textBetween(range.from, range.to, '\n', '\n') + // Drop the leading ':' trigger character. + const query = text.startsWith(':') ? text.slice(1) : text + return SHORTCODE_RE.test(query) + }, + + items: async ({query}: {query: string}): Promise => { + if (query === '') return [] + try { + const index = await loadEmojis() + return filterEmojis(index, query) + } catch (err) { + console.error('Failed to load emoji index:', err) + return [] + } + }, + + command: ({editor, range, props}: {editor: Editor, range: Range, props: EmojiEntry}) => { + editor + .chain() + .focus() + .deleteRange(range) + .insertContent(props.emoji) + .run() + }, + + render: () => { + let component: VueRenderer + let popupElement: HTMLElement | null = null + let cleanupFloating: (() => void) | null = null + + const virtualReference = { + getBoundingClientRect: () => ({ + width: 0, height: 0, x: 0, y: 0, top: 0, left: 0, right: 0, bottom: 0, + } as DOMRect), + } + + const mount = (props: SuggestionProps) => { + component = new VueRenderer(EmojiList, { + props, + editor: props.editor, + }) + if (!props.clientRect) return + + popupElement = document.createElement('div') + popupElement.style.position = 'absolute' + popupElement.style.top = '0' + popupElement.style.left = '0' + popupElement.style.zIndex = '4700' + popupElement.appendChild(component.element!) + document.body.appendChild(popupElement) + + const rect = props.clientRect() + if (!rect) { + unmount() + return + } + virtualReference.getBoundingClientRect = () => rect + + const updatePosition = () => { + computePosition(virtualReference, popupElement!, { + placement: 'bottom-start', + middleware: [offset(8), flip(), shift({padding: 8})], + }).then(({x, y}) => { + if (popupElement) { + popupElement.style.left = `${x}px` + popupElement.style.top = `${y}px` + } + }) + } + updatePosition() + cleanupFloating = autoUpdate(virtualReference, popupElement, updatePosition) + } + + const unmount = () => { + if (cleanupFloating) { + cleanupFloating() + cleanupFloating = null + } + if (popupElement) { + document.body.removeChild(popupElement) + popupElement = null + } + component?.destroy() + } + + return { + onStart: (props: SuggestionProps) => { + if (!props.items.length && props.query === '') return + mount(props) + }, + + onUpdate(props: SuggestionProps) { + if (!popupElement) { + if (props.items.length || props.query !== '') mount(props) + return + } + component?.updateProps(props) + if (!props.clientRect) return + const rect = props.clientRect() + if (rect) virtualReference.getBoundingClientRect = () => rect + }, + + onKeyDown(props: {event: KeyboardEvent}) { + if (props.event.key === 'Escape') { + if (props.event.isComposing) return false + if (popupElement) popupElement.style.display = 'none' + return true + } + return component?.ref?.onKeyDown(props) + }, + + onExit: unmount, + } + }, + } +} diff --git a/frontend/src/components/input/editor/mention/mentionSuggestion.ts b/frontend/src/components/input/editor/mention/mentionSuggestion.ts index 0aaf756a8..1afd2f66a 100644 --- a/frontend/src/components/input/editor/mention/mentionSuggestion.ts +++ b/frontend/src/components/input/editor/mention/mentionSuggestion.ts @@ -3,6 +3,7 @@ import { computePosition, flip, shift, offset, autoUpdate } from '@floating-ui/d import type { Editor } from '@tiptap/core' import MentionList from './MentionList.vue' +import { getPopupContainer } from '../popupContainer' import ProjectUserService from '@/services/projectUsers' import { fetchAvatarBlobUrl, getDisplayName } from '@/models/user' import type { IUser } from '@/modelTypes/IUser' @@ -113,7 +114,8 @@ export default function mentionSuggestionSetup(projectId: number) { popupElement.style.left = '0' popupElement.style.zIndex = '4700' popupElement.appendChild(component.element!) - document.body.appendChild(popupElement) // Update virtual reference + getPopupContainer(props.editor).appendChild(popupElement) + // Update virtual reference const rect = props.clientRect() if (rect) { virtualReference.getBoundingClientRect = () => rect @@ -179,7 +181,7 @@ export default function mentionSuggestionSetup(projectId: number) { cleanupFloating() } if (popupElement) { - document.body.removeChild(popupElement) + popupElement.remove() popupElement = null } component.destroy() diff --git a/frontend/src/components/input/editor/popupContainer.ts b/frontend/src/components/input/editor/popupContainer.ts new file mode 100644 index 000000000..92679d936 --- /dev/null +++ b/frontend/src/components/input/editor/popupContainer.ts @@ -0,0 +1,11 @@ +import type {Editor} from '@tiptap/core' + +// Native elements opened with showModal() render in the browser's +// top-layer, so popups appended to document.body end up visually behind them +// regardless of z-index. Appending to the open dialog itself lifts the popup +// into the same top-layer stacking context. +export function getPopupContainer(editor?: Editor): HTMLElement { + const editorEl = editor?.view?.dom as HTMLElement | undefined + const dialog = editorEl?.closest('dialog[open]') as HTMLElement | null + return dialog ?? document.body +} diff --git a/frontend/src/components/input/editor/suggestion.ts b/frontend/src/components/input/editor/suggestion.ts index 151afc7f7..55146c34f 100644 --- a/frontend/src/components/input/editor/suggestion.ts +++ b/frontend/src/components/input/editor/suggestion.ts @@ -3,6 +3,7 @@ import {VueRenderer} from '@tiptap/vue-3' import {computePosition, flip, shift, offset, autoUpdate} from '@floating-ui/dom' import CommandsList from './CommandsList.vue' +import {getPopupContainer} from './popupContainer' type TranslateFunction = (key: string) => string @@ -206,7 +207,7 @@ export default function suggestionSetup(t: TranslateFunction) { popupElement.style.left = '0' popupElement.style.zIndex = '4700' popupElement.appendChild(component.element!) - document.body.appendChild(popupElement) + getPopupContainer(props.editor).appendChild(popupElement) // Update virtual reference const rect = props.clientRect() @@ -266,7 +267,7 @@ export default function suggestionSetup(t: TranslateFunction) { cleanupFloating() } if (popupElement) { - document.body.removeChild(popupElement) + popupElement.remove() popupElement = null } component.destroy() diff --git a/frontend/src/components/input/filter/FilterAutocomplete.ts b/frontend/src/components/input/filter/FilterAutocomplete.ts index 25da1eb65..a4b0d64fc 100644 --- a/frontend/src/components/input/filter/FilterAutocomplete.ts +++ b/frontend/src/components/input/filter/FilterAutocomplete.ts @@ -451,7 +451,10 @@ export default Extension.create({ popupElement.style.zIndex = '20000' popupElement.id = 'filter-autocomplete-popup' popupElement.appendChild(component.element!) - document.body.appendChild(popupElement) + // Append to the closest dialog (if inside a modal) so the popup + // is not blocked by inertness, otherwise fall back to body. + const parentDialog = view.dom.closest('dialog') + ;(parentDialog || document.body).appendChild(popupElement) cleanupFloating = autoUpdate(virtualReference, popupElement, updatePosition) } diff --git a/frontend/src/components/misc/Card.vue b/frontend/src/components/misc/Card.vue index ccd19faa1..415970441 100644 --- a/frontend/src/components/misc/Card.vue +++ b/frontend/src/components/misc/Card.vue @@ -73,6 +73,9 @@ defineEmits<{ margin-block-end: 1rem; border: 1px solid var(--card-border-color); box-shadow: var(--shadow-sm); + color: var(--text); + max-inline-size: 100%; + position: relative; @media print { box-shadow: none; @@ -81,15 +84,61 @@ defineEmits<{ } .card-header { + background-color: transparent; + align-items: stretch; + display: flex; box-shadow: none; border-inline-end: 1px solid var(--card-border-color); border-radius: $radius $radius 0 0; } +.card-header-title { + align-items: center; + color: var(--text-strong); + display: flex; + flex-grow: 1; + font-weight: 700; + padding: 0.75rem 1rem; + + &.is-centered { + justify-content: center; + } +} + +.card-header-icon { + align-items: center; + cursor: pointer; + display: flex; + justify-content: center; + padding: 0.75rem 1rem; +} + +.card-content { + background-color: transparent; + padding: 1.5rem; + + &:first-child { + border-start-start-radius: $radius; + border-start-end-radius: $radius; + } + + &:last-child { + border-end-start-radius: $radius; + border-end-end-radius: $radius; + } + + // Utility classes like .p-0 are defined globally with lower specificity + // than Vue-scoped selectors; restore precedence explicitly. + &.p-0 { + padding: 0; + } +} + .card-footer { + align-items: stretch; background-color: var(--grey-50); border-block-start: 0; - padding: var(--modal-card-head-padding); + padding: 20px; display: flex; justify-content: flex-end; } diff --git a/frontend/src/components/misc/CreateEdit.vue b/frontend/src/components/misc/CreateEdit.vue index 8031b114f..b5220c8e4 100644 --- a/frontend/src/components/misc/CreateEdit.vue +++ b/frontend/src/components/misc/CreateEdit.vue @@ -2,6 +2,7 @@ withDefaults(defineProps<{ - name?: 'fade' | 'flash-background' | 'width' | 'modal' + name?: 'fade' | 'flash-background' | 'width' }>(), { name: 'fade', }) @@ -58,13 +58,4 @@ $flash-background-duration: 750ms; inline-size: 0; } -.modal-enter, -.modal-leave-active { - opacity: 0; -} - -.modal-enter .modal-container, -.modal-leave-active .modal-container { - transform: scale(0.9); -} diff --git a/frontend/src/components/misc/Dropdown.vue b/frontend/src/components/misc/Dropdown.vue index f87227b89..94a79cd32 100644 --- a/frontend/src/components/misc/Dropdown.vue +++ b/frontend/src/components/misc/Dropdown.vue @@ -13,6 +13,7 @@ > (), { triggerIcon: 'ellipsis-h', + triggerLabel: undefined, }) const emit = defineEmits<{ diff --git a/frontend/src/components/misc/Icon.ts b/frontend/src/components/misc/Icon.ts index 8a5cab738..558daeff5 100644 --- a/frontend/src/components/misc/Icon.ts +++ b/frontend/src/components/misc/Icon.ts @@ -37,6 +37,7 @@ import { faEyeSlash, faFile, faFileImage, + faFilePdf, faFillDrip, faFilter, faForward, @@ -72,6 +73,7 @@ import { faTimes, faTrashAlt, faUser, + faUserEdit, faUsers, faQuoteRight, faListUl, @@ -111,6 +113,7 @@ library.add(faSquareCheck) library.add(faTable) library.add(faFile) library.add(faFileImage) +library.add(faFilePdf) library.add(faCheckSquare) library.add(faStrikethrough) library.add(faCode) @@ -184,6 +187,7 @@ library.add(faTimes) library.add(faTimesCircle) library.add(faTrashAlt) library.add(faUser) +library.add(faUserEdit) library.add(faUsers) library.add(faArrowDownShortWide) library.add(faArrowUpFromBracket) diff --git a/frontend/src/components/misc/Modal.test.ts b/frontend/src/components/misc/Modal.test.ts new file mode 100644 index 000000000..35cdde115 --- /dev/null +++ b/frontend/src/components/misc/Modal.test.ts @@ -0,0 +1,230 @@ +import {describe, it, expect, beforeEach, afterEach, vi} from 'vitest' +import {mount, flushPromises} from '@vue/test-utils' +import {nextTick} from 'vue' +import Modal from './Modal.vue' + +const globalMocks = { + global: { + mocks: { + $t: (key: string) => key, + }, + }, +} + +// jsdom does not implement HTMLDialogElement.showModal/close. +// Provide stubs so that the [open] attribute — which CSS and our tests +// check — is flipped the same way the real browser would. +let showModalSpy: ReturnType +let closeSpy: ReturnType +let installedShowModal = false +let installedClose = false + +beforeEach(() => { + const proto = HTMLDialogElement.prototype + if (typeof proto.showModal !== 'function') { + proto.showModal = function () {} + installedShowModal = true + } + if (typeof proto.close !== 'function') { + proto.close = function () {} + installedClose = true + } + showModalSpy = vi.spyOn(proto, 'showModal').mockImplementation(function (this: HTMLDialogElement) { + this.setAttribute('open', '') + }) + closeSpy = vi.spyOn(proto, 'close').mockImplementation(function (this: HTMLDialogElement) { + this.removeAttribute('open') + }) +}) + +afterEach(() => { + showModalSpy.mockRestore() + closeSpy.mockRestore() + // Remove the prototype stubs we installed, so other test files see the + // original (unpatched) shape of HTMLDialogElement. + if (installedShowModal) { + // @ts-expect-error — removing the method we added + delete HTMLDialogElement.prototype.showModal + installedShowModal = false + } + if (installedClose) { + // @ts-expect-error — removing the method we added + delete HTMLDialogElement.prototype.close + installedClose = false + } + document.body.innerHTML = '' +}) + +describe('Modal.vue — open race condition (#2590)', () => { + it('opens the dialog when enabled flips false → true', async () => { + const wrapper = mount(Modal, { + ...globalMocks, + attachTo: document.body, + props: {enabled: false}, + slots: {default: '

hi

'}, + }) + + // Pre-condition: dialog is not yet in the DOM. + expect(document.querySelector('dialog.modal-dialog')).toBeNull() + + // Flip enabled → true. This is the failure path in the bug report. + // The fix must call showModal() deterministically — i.e. once the + // element is mounted via the dialogRef watcher, not via a + // nextTick that may fire before the mount flush under Electron. + await wrapper.setProps({enabled: true}) + await flushPromises() + await nextTick() + + const dialog = document.querySelector('dialog.modal-dialog') as HTMLDialogElement | null + expect(dialog).not.toBeNull() + expect(dialog!.hasAttribute('open')).toBe(true) + expect(showModalSpy).toHaveBeenCalledTimes(1) + + wrapper.unmount() + }) + + it('calls showModal synchronously with the render flush, not via a deferred nextTick (#2590)', async () => { + // Regression guard: the buggy implementation scheduled showModal() via + // nextTick *after* setting showDialog = true, so the call landed in a + // microtask that could fire before the mount flush under + // Electron/Chromium. The fix invokes showModal() from a watch on the + // dialogRef template ref, which Vue populates during the same flush + // that mounts the element. That means by the time `await nextTick()` + // resolves after the first state change, the dialog must already have + // [open] set — no additional flushPromises or extra ticks required. + const wrapper = mount(Modal, { + ...globalMocks, + attachTo: document.body, + props: {enabled: false}, + slots: {default: '

hi

'}, + }) + expect(document.querySelector('dialog.modal-dialog')).toBeNull() + + // Flip enabled and wait exactly one render flush. After this, the + // dialog is mounted AND showModal has been called. + wrapper.setProps({enabled: true}) + await nextTick() + + const dialog = document.querySelector('dialog.modal-dialog') as HTMLDialogElement | null + expect(dialog).not.toBeNull() + expect(showModalSpy).toHaveBeenCalled() + expect(showModalSpy.mock.instances[0]).toBe(dialog) + expect(dialog!.hasAttribute('open')).toBe(true) + + wrapper.unmount() + }) + + it('calls showModal on the exact dialog element that is mounted (race regression)', async () => { + // This test asserts the fix's contract: whenever the element + // is mounted (i.e. dialogRef becomes non-null), showModal() is called + // on *that* element. The buggy implementation instead relied on a + // nextTick callback whose timing could fire before the dialog mounted, + // skipping the showModal() call entirely and leaving .open === false. + const wrapper = mount(Modal, { + ...globalMocks, + attachTo: document.body, + props: {enabled: true}, + slots: {default: '

hi

'}, + }) + await flushPromises() + await nextTick() + + const dialog = document.querySelector('dialog.modal-dialog') as HTMLDialogElement | null + expect(dialog).not.toBeNull() + // The fingerprint from the bug report: element is mounted but .open + // is false because showModal() was never called. The fix guarantees + // these two always agree. + expect(dialog!.hasAttribute('open')).toBe(true) + expect(showModalSpy).toHaveBeenCalled() + expect(showModalSpy.mock.instances[0]).toBe(dialog) + + wrapper.unmount() + }) + + it('closes the dialog when enabled flips true → false', async () => { + const wrapper = mount(Modal, { + ...globalMocks, + attachTo: document.body, + props: {enabled: true}, + slots: {default: '

hi

'}, + }) + await flushPromises() + await nextTick() + + // Sanity: open. + expect(document.querySelector('dialog.modal-dialog')?.hasAttribute('open')).toBe(true) + + await wrapper.setProps({enabled: false}) + // Wait past the 150ms closeTimer (real timers — fake timers interact + // badly with Vue's scheduler). + await new Promise(resolve => setTimeout(resolve, 200)) + await flushPromises() + await nextTick() + + expect(document.querySelector('dialog.modal-dialog')).toBeNull() + + wrapper.unmount() + }) + + it('does not open the dialog if enabled flips back to false before mount', async () => { + // Regression guard: the dialogRef watcher fires once the + // element mounts. If props.enabled has flipped back to false by the + // time the mount happens, the watcher must not call showModal(). + const wrapper = mount(Modal, { + ...globalMocks, + attachTo: document.body, + props: {enabled: false}, + slots: {default: '

hi

'}, + }) + + // Flip enabled true then false within the same tick, before the mount + // flush can complete. + wrapper.setProps({enabled: true}) + wrapper.setProps({enabled: false}) + await flushPromises() + await nextTick() + await new Promise(resolve => setTimeout(resolve, 200)) + await flushPromises() + await nextTick() + + // showModal must not have been called — the final prop state is + // disabled. + expect(showModalSpy).not.toHaveBeenCalled() + expect(document.querySelector('dialog.modal-dialog')).toBeNull() + + wrapper.unmount() + }) + + it('clears data-closing when re-opened mid-close transition', async () => { + // Regression guard: if the user toggles enabled back to true while the + // 150ms close transition is still in flight, the is still + // mounted and [open], so the dialogRef watcher does not re-fire. Make + // sure openDialog() clears the leftover data-closing flag itself; + // otherwise the dialog stays stuck at opacity 0. + const wrapper = mount(Modal, { + ...globalMocks, + attachTo: document.body, + props: {enabled: true}, + slots: {default: '

hi

'}, + }) + await flushPromises() + await nextTick() + + const dialog = document.querySelector('dialog.modal-dialog') as HTMLDialogElement + expect(dialog.hasAttribute('open')).toBe(true) + + // Start closing — this sets data-closing and schedules the unmount. + await wrapper.setProps({enabled: false}) + await nextTick() + expect(dialog.dataset.closing).toBe('') + + // Re-open well before the 150ms close timer fires. + await wrapper.setProps({enabled: true}) + await nextTick() + + expect(dialog.dataset.closing).toBeUndefined() + expect(dialog.hasAttribute('open')).toBe(true) + + wrapper.unmount() + }) +}) diff --git a/frontend/src/components/misc/Modal.vue b/frontend/src/components/misc/Modal.vue index f11763339..356774f9b 100644 --- a/frontend/src/components/misc/Modal.vue +++ b/frontend/src/components/misc/Modal.vue @@ -1,128 +1,172 @@ @@ -130,20 +174,49 @@ onBeforeUnmount(() => { $modal-margin: 4rem; $modal-width: 1024px; -.modal-mask { +.modal-dialog { + // Reset UA dialog styles + padding: 0; + border: none; + background: transparent; + color: #ffffff; + // Fill viewport position: fixed; - z-index: 4000; - inset-block-start: 0; - inset-inline-start: 0; + inset: 0; inline-size: 100%; block-size: 100%; - background-color: rgba(0, 0, 0, .8); - transition: opacity 150ms ease; - color: #ffffff; + max-inline-size: 100%; + max-block-size: 100%; + + // Transitions + opacity: 0; + transition: opacity 150ms ease, + display 150ms ease allow-discrete; + + &[open]:not([data-closing]) { + opacity: 1; + + @starting-style { + opacity: 0; + } + } + + &::backdrop { + background-color: rgba(0, 0, 0, 0); + transition: background-color 150ms ease, + display 150ms ease allow-discrete; + } + + &[open]:not([data-closing])::backdrop { + background-color: rgba(0, 0, 0, .8); + + @starting-style { + background-color: rgba(0, 0, 0, 0); + } + } } .modal-container { - transition: all 150ms ease; position: relative; inline-size: 100%; block-size: 100%; @@ -151,6 +224,7 @@ $modal-width: 1024px; overflow: auto; padding-block-start: env(safe-area-inset-top); padding-block-end: env(safe-area-inset-bottom); + } .default .modal-content, @@ -161,7 +235,7 @@ $modal-width: 1024px; inset-block-start: 50%; inset-inline-start: 50%; transform: translate(-50%, -50%); - + [dir="rtl"] & { transform: translate(50%, -50%); } @@ -190,7 +264,7 @@ $modal-width: 1024px; max-block-size: none; // reset bulma overflow: visible; // reset bulma - + @media not print { max-inline-size: $modal-width; } @@ -212,8 +286,6 @@ $modal-width: 1024px; } .hint-modal { - z-index: 4600; - :deep(.card-content) { text-align: start; @@ -244,7 +316,7 @@ $modal-width: 1024px; } @media print, screen and (max-width: $tablet) { - .modal-mask { + .modal-dialog { overflow: visible !important; } @@ -285,7 +357,7 @@ $modal-width: 1024px; .modal-content :deep(.card .card-header-icon.close) { display: none; - + @media screen and (max-width: $tablet) { display: block; } @@ -294,12 +366,12 @@ $modal-width: 1024px; + + diff --git a/frontend/src/components/misc/ShortcutRecorder.vue b/frontend/src/components/misc/ShortcutRecorder.vue new file mode 100644 index 000000000..9a4d38b16 --- /dev/null +++ b/frontend/src/components/misc/ShortcutRecorder.vue @@ -0,0 +1,208 @@ + + + + + diff --git a/frontend/src/components/misc/SideNavShell.vue b/frontend/src/components/misc/SideNavShell.vue new file mode 100644 index 000000000..4d42a7165 --- /dev/null +++ b/frontend/src/components/misc/SideNavShell.vue @@ -0,0 +1,126 @@ + + + + + diff --git a/frontend/src/components/misc/TimeDisplay.vue b/frontend/src/components/misc/TimeDisplay.vue new file mode 100644 index 000000000..160aa0f29 --- /dev/null +++ b/frontend/src/components/misc/TimeDisplay.vue @@ -0,0 +1,29 @@ + + + diff --git a/frontend/src/components/misc/WebhookManager.vue b/frontend/src/components/misc/WebhookManager.vue index 4bff44320..86c619a3d 100644 --- a/frontend/src/components/misc/WebhookManager.vue +++ b/frontend/src/components/misc/WebhookManager.vue @@ -6,6 +6,7 @@ import WebhookModel from '@/models/webhook' import BaseButton from '@/components/base/BaseButton.vue' import FancyCheckbox from '@/components/input/FancyCheckbox.vue' import FormField from '@/components/input/FormField.vue' +import FormInput from '@/components/input/FormInput.vue' import Expandable from '@/components/base/Expandable.vue' import User from '@/components/misc/User.vue' import {formatDateShort} from '@/helpers/time/formatDate' @@ -116,27 +117,20 @@ function doDelete() { :error="webhookTargetUrlValid ? null : $t('project.webhooks.targetUrlInvalid')" @focusout="validateTargetUrl" /> -
- -
- + + +

+ {{ $t('project.webhooks.secretHint') }} + + {{ $t('project.webhooks.secretDocs') }} + +

-
- -
- -
-
-
- -
- -
-
+ + + + + +