From 23be25d84ab35cf9fc661ddfb20be95c1a35c862 Mon Sep 17 00:00:00 2001 From: Dmitry Verkhoturov Date: Sat, 22 Aug 2026 18:34:24 +0100 Subject: [PATCH] Fix seven widget defects, including the cookies the separate-domain setup needs (#2197) * Drop the frontend workspace root and re-resolve the lockfile `frontend/` carried a `package.json`, a `pnpm-workspace.yaml` and the lockfile for a workspace of exactly one package. Two manifests meant two places to declare a version, and the app pin was the one that did not win: `preact` and `@babel/core` were each written twice, and a bump to the app manifest alone would have been a silent no-op, since `pnpm.overrides` decides and it lived at the root. Everything pnpm reads now lives in `frontend/apps/remark42`: dependencies, `packageManager`, `engines` and the overrides. `frontend/` keeps `.nvmrc`, `.husky` and `CLAUDE.md`, none of which pnpm reads. The directory nesting stays: every path in the repository points at `frontend/apps/remark42`, including the published contributing docs, so moving the package up would have rewritten 14 files to no benefit. Moving the manifest kept the old resolutions verbatim, which left optional peer subtrees the tree no longer reaches: `ts-node` under jest, `@swc/core` under webpack, `vitest` under `@testing-library/jest-dom`, `tslib` under `webpack-dev-server`. None is referenced by any config or source file here. Re-resolving drops 137 packages and moves 59 to versions already permitted by the ranges in the manifest, 1446 to 1308, with no direct dependency changing version: the five that look changed differ only in their peer suffix. Every file `pnpm build` produces is identical in size before and after. The frontend-deps stage of the Dockerfile sets `CI=true` so the `prepare` script skips husky, which has no git repository to install hooks into there. * Stop markdown-only changes triggering heavy workflows, and check the documented versions `ci-backend.yml`, `ci-build.yml` and `ci-frontend.yml` all end their path filters with `!**.md`. The e2e workflow did not, so a change to any markdown file under `frontend/` or `backend/` matched its `frontend/**` and `backend/**` entries and started a docker build and the whole browser suite. The release filter had the same hole and two of its own: it names `README.md` and `LICENSE` on purpose, since `.goreleaser.yml` packages both, so it now excludes markdown under `backend/` and `frontend/` only. `CLAUDE.md` and the installation page were listed as well, and neither is packaged. `ci-site.yml` goes on matching markdown, which is right, since the site is built from it. It excludes `CLAUDE.md`, so a future `site/CLAUDE.md` cannot start a site build, and `site/README.md`, which documents how to build the site rather than being part of it. The installation page tells a reader that a source build needs Go 1.25, Node 24+ and PNPM 10. Nothing kept those in step with `backend/go.mod`, `engines.node`, `packageManager` and `.nvmrc`, and the drift is silent: a wrong version in the docs builds and tests exactly as well as a right one. `.nvmrc` is the pin with form here, having sat at 16 through the whole node 20 migration because nothing red ever pointed at it. The check compares each stated version against its source and holds `.nvmrc` to `engines.node`, and it fails when the page states no version at all, so removing the claims cannot turn it into a check that passes by comparing nothing. Its own workflow rather than a step in an existing one, since the inputs span the backend module, the frontend manifest and the site. * Fix the cookie fallback page, asset path, message senders, auth teardown and cookies Two defects with the same origin: 5825a55b, the January 2021 frontend rewrite, first released in v1.7.0. It removed the build entry for comments.html while leaving both the template and the link to it in place, so the page the auth panel offers when third-party cookies are blocked has been a 404 ever since, for exactly the reader who has no other way in. The template needed no changes; it is built again, and an e2e case now opens it on a thread carrying a comment and waits for that comment, so the page being served, its inline script running and it asking for the thread named in its own query string are all covered. Against an image built without the plugin entry that case fails on the 404, which is the regression it exists for. It also fixed the public path to the domain root, so an instance mounted under a prefix, which manuals/separate-domain documents, asked for /web/google.svg when its own icons live under that prefix. Fifteen provider icons in remark.mjs and one in last-comments.mjs. The path is now derived from the url the bundle was loaded from, which is correct for both arrangements, and the file loader no longer overrides it. The host page also accepted postMessage from any window: every frame on a page can reach window.parent, and the handler resizes the widget, scrolls the page and opens the profile overlay. It now ignores anything that did not come from a frame this module created. A fourth, in the same family: the OAuth flow never tore its polling down. `subscribed` was declared, checked and cleared but never set, so the guard against a second subscription was dead code and every provider click attached another listener pair. The five minute deadline then rejected without unsubscribing, leaving those listeners and a retry that reschedules itself for as long as getUser returns null. Cross-domain is where getUser never stops returning null, so a reader on the arrangement manuals/separate-domain documents was left polling /auth/user once a minute for the life of the page, against a route capped at 2 req/s. It also rejected with no argument, and the caller stores that as the error state, so the interface had undefined to render. The deadline now tears the subscription down and rejects with an error. The message check had a second half. Hardening the parent left the widget document trusting any sender, and it acts on signout and theme, so anything holding a reference to the frame could sign a reader out. `auth.hooks` already checked `event.source !== window.parent`; that check is now a shared `isFromParent` and the three listeners that lacked it use it too. The origin cannot stand in for it, since the host page is whatever site embeds the widget and `ALLOWED_HOSTS` is enforced server side through `frame-ancestors`. And createInstance stacked its listeners. It reuses the marked iframe instead of building one, but installed three listeners plus a title observer on every call, while destroy could only reach the newest closure, so a second call without a destroy stranded a set for good. The listeners of the current instance are now detached before the next set goes on. Reuse and the ignored config are unchanged: that contract is open in the backlog note and not settled here. The auth cookies the embedded case needs were not being delivered, in both halves of the client's own writer. The name was decorated: setAuthCookie prefixed with __Host- whenever the page was https, so a real deployment wrote __Host-JWT and __Host-XSRF-TOKEN while the backend looks for JWT and the fetcher reads XSRF-TOKEN, and nothing anywhere reads a prefixed name. Nothing caught it because the prefix is applied from the page protocol and every test and the dev server run on http; there is now a second suite pinned to an https page, which is the only condition that shows it. And the attributes could not be delivered: both were SameSite=Strict, judged against the top-level site and not the request's own origin, so a Strict cookie is never sent from a third-party frame, which is the entire configuration this code exists for. They now follow the embedding, Strict while the widget shares its page origin and None with Secure and Partitioned once it does not, since that is the only third-party form browsers still accept. Over http in a third-party frame no combination works, and the strict form is written instead of one the browser would reject outright. That leaves the client half of #1877 working, whose reporter wanted AUTH_SEND_JWT_HEADER for exactly this arrangement, and whose first half merged as #1929. The server's own cookies still carry no Partitioned; that is upstream work in go-pkgz/auth. Two plan changes. A review pass corrected its central Path B premise, which said the first document render is anonymous permanently, in every configuration: it is anonymous in the configuration remark42 ships, go-pkgz/auth exposing XSRFIgnoreMethods and remark42 leaving it unset. The door is not shut, it is closed by a setting, and opening it is scoped security work and not a flag flip, because GET /deleteme deletes every comment a user has written and is a GET so the emailed link works. And the separate-domain arrangement is promoted from a constraint bullet to a named requirement with acceptance criteria, since a test that signs in and posts without reloading passes while persistence is entirely broken. Review found a seventh, and it was reachable only because of the first: comments.ejs built its title with innerHTML from the url query parameter, so restoring the build entry made a reflected XSS live on the instance origin, where the page is a top-level document, frame-ancestors does not apply and the /web CSP allows unsafe-inline. The anchor is now built through the DOM with textContent, and only http and https reach href, since escaping alone leaves a javascript: url working. Two e2e subtests pin both halves, and mutation testing separates them: restoring innerHTML fails four assertions, while keeping the escaping and dropping only the scheme guard fails the href one alone. Review also found the poll teardown test did not exercise the poll. handleWindowVisibilityChange is reachable only from the two listeners and from the retry it schedules itself, and the test dispatched neither, so no request was ever made and the assertion compared zero to zero; it passed with the teardown reverted. It now dispatches focus, asserts requests are being made and keep coming, and only then that they stop. And the teardown could not cancel an in-flight getUser: a null resolving after the deadline ran the code past the await and scheduled a fresh retry with nothing left to clear it. A closure-local flag checked after the await stops that, chosen over a second guard at the top of the handler because only one of the two is detectable by mutation and this is the one that prevents the stray timer rather than neutering it. The inline handler in the iframe template accepted messages from any window while acting on them through location.replace and document.title. It now takes only the parent, the same check the host page side makes. --- .github/workflows/ci-docs-versions.yml | 37 + .github/workflows/ci-frontend.yml | 16 +- .github/workflows/ci-site.yml | 4 + .github/workflows/e2e-tests.yml | 2 + .github/workflows/release.yml | 12 +- CLAUDE.md | 6 +- Dockerfile | 8 +- .../public-widget-contract-docs-and-types.md | 58 + .../2026-08-19-frontend-simplification.md | 561 +++++ e2e/widgets_test.go | 81 + frontend/CLAUDE.md | 20 +- .../remark42/app/common/cookies.https.test.ts | 90 + .../apps/remark42/app/common/cookies.test.ts | 137 + frontend/apps/remark42/app/common/cookies.ts | 66 +- .../app/components/auth/auth.api.spec.ts | 118 + .../remark42/app/components/auth/auth.api.ts | 24 +- .../app/components/dropdown/dropdown.tsx | 6 +- .../remark42/app/components/root/root.tsx | 6 +- frontend/apps/remark42/app/embed.test.ts | 78 + frontend/apps/remark42/app/embed.ts | 30 +- frontend/apps/remark42/app/profile.ts | 7 + frontend/apps/remark42/app/remark.tsx | 6 +- .../remark42/app/utils/post-message.test.ts | 26 + .../apps/remark42/app/utils/post-message.ts | 16 + frontend/apps/remark42/package.json | 77 +- frontend/{ => apps/remark42}/pnpm-lock.yaml | 2215 +++-------------- frontend/apps/remark42/templates/comments.ejs | 12 +- frontend/apps/remark42/templates/iframe.ejs | 4 + frontend/apps/remark42/webpack.config.js | 16 +- frontend/package.json | 95 - frontend/pnpm-workspace.yaml | 2 - scripts/check-documented-versions.sh | 67 + scripts/prepare-release-assets.sh | 6 +- .../docs/contributing/frontend/index.md | 10 +- .../docs/contributing/translations/index.md | 2 +- 35 files changed, 1952 insertions(+), 1969 deletions(-) create mode 100644 .github/workflows/ci-docs-versions.yml create mode 100644 docs/backlog/public-widget-contract-docs-and-types.md create mode 100644 docs/plans/2026-08-19-frontend-simplification.md create mode 100644 frontend/apps/remark42/app/common/cookies.https.test.ts create mode 100644 frontend/apps/remark42/app/common/cookies.test.ts create mode 100644 frontend/apps/remark42/app/components/auth/auth.api.spec.ts create mode 100644 frontend/apps/remark42/app/utils/post-message.test.ts rename frontend/{ => apps/remark42}/pnpm-lock.yaml (86%) delete mode 100644 frontend/package.json delete mode 100644 frontend/pnpm-workspace.yaml create mode 100755 scripts/check-documented-versions.sh diff --git a/.github/workflows/ci-docs-versions.yml b/.github/workflows/ci-docs-versions.yml new file mode 100644 index 00000000..54b3b021 --- /dev/null +++ b/.github/workflows/ci-docs-versions.yml @@ -0,0 +1,37 @@ +name: docs versions + +on: + push: + branches: + - master + paths: + - ".github/workflows/ci-docs-versions.yml" + - "scripts/check-documented-versions.sh" + - "site/content/docs/getting-started/installation/index.md" + - "backend/go.mod" + - "frontend/apps/remark42/package.json" + - "frontend/.nvmrc" + pull_request: + paths: + - ".github/workflows/ci-docs-versions.yml" + - "scripts/check-documented-versions.sh" + - "site/content/docs/getting-started/installation/index.md" + - "backend/go.mod" + - "frontend/apps/remark42/package.json" + - "frontend/.nvmrc" + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + check: + name: Documented versions + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v7 + with: + persist-credentials: false + + - name: Check documented versions against the repository + run: ./scripts/check-documented-versions.sh diff --git a/.github/workflows/ci-frontend.yml b/.github/workflows/ci-frontend.yml index 86940565..0a6888fd 100644 --- a/.github/workflows/ci-frontend.yml +++ b/.github/workflows/ci-frontend.yml @@ -41,11 +41,11 @@ jobs: with: node-version: ${{ matrix.node }} cache: "pnpm" - cache-dependency-path: frontend/pnpm-lock.yaml + cache-dependency-path: frontend/apps/remark42/pnpm-lock.yaml - name: Install dependencies run: pnpm install --frozen-lockfile - working-directory: ./frontend + working-directory: ./frontend/apps/remark42 - name: Translations check run: pnpm translation-check @@ -77,11 +77,11 @@ jobs: with: node-version: ${{ matrix.node }} cache: "pnpm" - cache-dependency-path: frontend/pnpm-lock.yaml + cache-dependency-path: frontend/apps/remark42/pnpm-lock.yaml - name: Install dependencies run: pnpm install --frozen-lockfile - working-directory: ./frontend + working-directory: ./frontend/apps/remark42 - name: Run type check run: pnpm type-check @@ -113,11 +113,11 @@ jobs: with: node-version: ${{ matrix.node }} cache: "pnpm" - cache-dependency-path: frontend/pnpm-lock.yaml + cache-dependency-path: frontend/apps/remark42/pnpm-lock.yaml - name: Install dependencies run: pnpm install --frozen-lockfile - working-directory: ./frontend + working-directory: ./frontend/apps/remark42 - name: Run linters run: pnpm lint @@ -177,11 +177,11 @@ jobs: with: node-version: ${{ matrix.node }} cache: "pnpm" - cache-dependency-path: frontend/pnpm-lock.yaml + cache-dependency-path: frontend/apps/remark42/pnpm-lock.yaml - name: Install dependencies run: pnpm install --frozen-lockfile - working-directory: ./frontend + working-directory: ./frontend/apps/remark42 - name: Test & Coverage run: pnpm coverage diff --git a/.github/workflows/ci-site.yml b/.github/workflows/ci-site.yml index 361be584..9f887f40 100644 --- a/.github/workflows/ci-site.yml +++ b/.github/workflows/ci-site.yml @@ -9,10 +9,14 @@ on: paths: - ".github/workflows/ci-site.yml" - "site/**" + - "!**/CLAUDE.md" + - "!site/README.md" pull_request: paths: - ".github/workflows/ci-site.yml" - "site/**" + - "!**/CLAUDE.md" + - "!site/README.md" concurrency: group: ${{ github.workflow }}-${{ github.ref }} diff --git a/.github/workflows/e2e-tests.yml b/.github/workflows/e2e-tests.yml index d977a08e..224a3fe5 100644 --- a/.github/workflows/e2e-tests.yml +++ b/.github/workflows/e2e-tests.yml @@ -10,6 +10,7 @@ on: - "e2e/**" - "compose-e2e-test.yml" - "Dockerfile" + - "!**.md" pull_request: branches: [master] @@ -20,6 +21,7 @@ on: - "e2e/**" - "compose-e2e-test.yml" - "Dockerfile" + - "!**.md" concurrency: group: ${{ github.workflow }}-${{ github.ref }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index bd7a7908..b7ed4194 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -12,10 +12,10 @@ on: - "scripts/**" - "backend/**" - "frontend/**" + - "!backend/**.md" + - "!frontend/**.md" - "README.md" - "LICENSE" - - "CLAUDE.md" - - "site/content/docs/getting-started/installation/index.md" permissions: contents: read @@ -47,7 +47,7 @@ jobs: with: node-version: 24 cache: "pnpm" - cache-dependency-path: frontend/pnpm-lock.yaml + cache-dependency-path: frontend/apps/remark42/pnpm-lock.yaml - name: test and build backend run: | @@ -67,7 +67,7 @@ jobs: - name: install frontend dependencies run: pnpm install --frozen-lockfile - working-directory: frontend + working-directory: frontend/apps/remark42 env: CI: "true" @@ -123,11 +123,11 @@ jobs: with: node-version: 24 cache: "pnpm" - cache-dependency-path: frontend/pnpm-lock.yaml + cache-dependency-path: frontend/apps/remark42/pnpm-lock.yaml - name: install frontend dependencies run: pnpm install --frozen-lockfile - working-directory: frontend + working-directory: frontend/apps/remark42 env: CI: "true" diff --git a/CLAUDE.md b/CLAUDE.md index 08abb1f7..a0c754ed 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -10,13 +10,13 @@ - Run single test: `cd backend/app && go test -run TestName ./path/to/package` - **IMPORTANT**: Run example tests: `cd backend/_example/memory_store && go test -race ./... && go build -race ./...` - **Frontend**: - - Development: `cd frontend && pnpm dev:app` - - Tests: `cd frontend && pnpm test` + - Development: `cd frontend/apps/remark42 && pnpm dev` + - Tests: `cd frontend/apps/remark42 && pnpm test` - **End-to-end**: `make e2e` drives the widget in a real browser; see `e2e/README.md`. Build-tagged, so `go test ./...` never runs it. - **Lint**: - Backend: `cd backend && golangci-lint run` - **IMPORTANT**: Example lint: `cd backend/_example/memory_store && golangci-lint run --config ../../.golangci.yml` - - Frontend: `cd frontend && pnpm lint` + - Frontend: `cd frontend/apps/remark42 && pnpm lint` - **Before committing**: Always run tests and linter on both main backend AND examples - **Go module changes**: - **Any** change to `backend/go.mod` or `backend/go.sum` requires `go mod tidy` in `backend/_example/memory_store` in the same commit. That covers dependency bumps, adding or removing a dependency, and changing the `go` directive, not only version updates. diff --git a/Dockerfile b/Dockerfile index 0215ba03..6d338f85 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,11 +2,13 @@ FROM --platform=$BUILDPLATFORM node:24-alpine AS frontend-deps ARG SKIP_FRONTEND_TEST ARG SKIP_FRONTEND_BUILD +# the manifest's prepare script installs husky hooks, which needs a git repository the build +# context does not have. husky itself skips on CI, and this is the same flag the build stage sets +ENV CI=true -WORKDIR /srv/frontend/ +WORKDIR /srv/frontend/apps/remark42/ -COPY ./frontend/package.json ./frontend/pnpm-lock.yaml ./frontend/pnpm-workspace.yaml /srv/frontend/ -COPY ./frontend/apps/remark42/package.json /srv/frontend/apps/remark42/ +COPY ./frontend/apps/remark42/package.json ./frontend/apps/remark42/pnpm-lock.yaml /srv/frontend/apps/remark42/ RUN \ if [[ -z "$SKIP_FRONTEND_BUILD" || -z "$SKIP_FRONTEND_TEST" ]]; then \ diff --git a/docs/backlog/public-widget-contract-docs-and-types.md b/docs/backlog/public-widget-contract-docs-and-types.md new file mode 100644 index 00000000..39df3b8c --- /dev/null +++ b/docs/backlog/public-widget-contract-docs-and-types.md @@ -0,0 +1,58 @@ +--- +worth: yes +where: site/content/docs/configuration/frontend/_index.md, frontend/apps/remark42/app/typings/global.d.ts +added: 2026-08-21 +--- +# The public embed contract has no reference page and no shippable type declaration + +Discussion #1714 asked for a description of `window.REMARK42` and TypeScript types, in December 2023. +The contract was written out in a reply on 2026-08-20, but a discussion comment is not documentation, +and the two halves of the request are still open. + +## The docs half + +The pieces exist and are scattered. `configuration/frontend/_index.md:81` documents `changeTheme` only, +in a section about theming. `configuration/frontend/spa.md` shows `createInstance`, `destroy` and the +`REMARK42::ready` event, but as a single-page-app recipe rather than as a reference. The Astro and +Gatsby manuals repeat fragments again. There is no page that states the surface once. + +Three behaviours are documented nowhere and will bite anyone building against it, all in `app/embed.ts`: + +- `createInstance` throws rather than returning an error in three cases: no element with id `remark42`, + `window.remark_config` undefined, or `site_id` unset +- those checks read the **global** `window.remark_config`, while the rest of the function reads the + object passed as the argument, so passing a config does not remove the need for a valid global +- `createInstance` reuses a direct-child iframe carrying `data-remark42-iframe` rather than creating one, + and the config passed to that second call is ignored, so calling it again without a `destroy` silently + does nothing. The reuse also leaves the first instance's `message`, `hashchange` and `click` listeners + installed, so each call adds another set + +Also undocumented: the embed script creates an instance *before* dispatching `REMARK42::ready`, so the +event means the global is safe to touch rather than that nothing is mounted; and `__colors__` reaches +the iframe through `window.name` (`templates/iframe.ejs:42-44`) rather than the URL, so it is read once +at boot and is not a runtime API. + +## The types half, and the open decision + +`app/typings/global.d.ts` is internal: it imports `jest-fetch-mock` and `common/types`, so it cannot be +shipped as-is. A public declaration would be a standalone file with `Theme`, `RemarkConfig` and the +`window.REMARK42` surface and no internal imports. That part is easy. + +**How it reaches a consumer is not decided.** `tsc` picks up types from `node_modules`, and npm is the +direction we have just moved away from: #1715 declined packaging the widgets and #2172 removed +`@remark42/api`. Options, in the order I would rank them: + +1. Publish the file on the site as a copy-paste block, with no package. Zero infrastructure, works + today, and consumers paste it into their own `global.d.ts`. This is what the Astro and Gatsby + manuals need, since both currently declare `REMARK42: any` and `remark_config: any` + (`integration-with-astro/index.md:150`, `integration-with-gatsby/index.md:109`), which is our own + documentation admitting the gap. +2. A types-only npm package. Note this does not contradict #1715: that was declined because shipping + *widget code* through npm puts the widget in the host origin and breaks OAuth. A package containing + no runtime code has none of that problem. It does add a publish step and a version to keep in sync. + +Option 1 clears the reported need. Option 2 only pays off if we want `npm i -D` ergonomics, which is a +separate call. + +Whatever is chosen, fixing the two integration manuals to stop using `any` is the visible win, and +#1714 should get the pull request linked when it lands, as promised there. diff --git a/docs/plans/2026-08-19-frontend-simplification.md b/docs/plans/2026-08-19-frontend-simplification.md new file mode 100644 index 00000000..eee4258b --- /dev/null +++ b/docs/plans/2026-08-19-frontend-simplification.md @@ -0,0 +1,561 @@ +# Frontend direction: two viable paths, and what has to be true for either + +Written 2026-08-19, revised 2026-08-22. Every file reference below was re-checked against master +`a82dc8d3` plus #2196, #2197 and #2198, which are treated here as landed: they change the e2e net, +the manifest layout, the fallback page, the asset path and the instance URL, and costing either +direction against the state before them would be costing a world that no longer exists. + +## Overview + +- The widget's measured cost was the **toolchain and the React compatibility alias**, not Preact + itself. The alias is now gone, so what remains is the toolchain +- Two paths are genuinely viable: **incremental simplification** (keep Preact, finish collapsing the + toolchain) or the **server-rendered rewrite** of #825. This document sets out to cost both rather + than to recommend against one, and it half succeeds: Path A is costed, Path B is not, because two + of its inputs are still open. What language the retained client code is written in, and whether a + scoped XSRF exemption can make the document render authenticated, both change the figure + materially. The "months" estimate below is therefore a placeholder rather than a finding, and + should not be quoted as though the comparison had been made +- Server rendering is not architecturally blocked. Authenticated *fragments* work; the initial + *document* render is anonymous in every configuration, and that is forced rather than chosen +- Whichever path is taken, two standing requirements constrain it, and three pieces of work are + worth doing first regardless. One of those three is now done + +## Standing requirements + +Not tasks. Tests any proposal has to pass. + +### R1: Remark42 must be hostable on a domain other than the site embedding it + +This is a product requirement rather than a constraint to respect in passing, and it is the one +users report against most. The target arrangement is remark42 serving from its own name, say +`remark42.example.com`, with comments appearing on a different site entirely, say `food.com`. It is +documented in `site/content/docs/manuals/separate-domain/index.md`, so operators follow it and then +find that authentication behaves differently from the same-domain case. + +**Acceptance criteria.** A reader on `food.com` can sign in with any configured provider, post, +reload the page, and still be signed in, on a browser that blocks unpartitioned third-party cookies. +Nothing short of the reload proves it: the widget holds a token in memory for the life of a page, so +a test that signs in and posts without reloading passes while the persistence is entirely broken. + +**Where that stands.** The e2e suite covers the rendering half through +`TestCrossOrigin_WidgetRendersOnAnotherOrigin`, which proves the document loads on another origin +and reports itself through postMessage across the boundary, and `ALLOWED_HOSTS` refusal through +`TestCrossOrigin_DisallowedHostNeverReportsInited`. The authentication half is not covered and +cannot be until the e2e stack speaks https, because an embedded cookie needs `SameSite=None`, which +browsers accept only with `Secure`. + +`ALLOWED_HOSTS` sets the CSP `frame-ancestors` and `AUTH_SAME_SITE=none` lets auth cookies be set +from any embedding domain. OAuth is what visibly fails off-domain (discussion #1139). Telegram, +email and anonymous work where third-party cookies are still permitted, and stop working where they +are not: the server's cookies carry no `Partitioned`, and the header fallback is off by default, so +nothing saves them once the browser blocks unpartitioned third-party cookies. + +There is a second mechanism aimed squarely at this, `AUTH_SEND_JWT_HEADER`, which returns the token +in a response header so the client can present it without relying on an ambient cookie. #1877 was +opened by an operator who wanted exactly this for exactly this reason, and #1929 was merged as its +first half. Its persistence never worked on https: the client wrote its copy under a `__Host-` +prefix that neither the backend nor the widget's own reader ever asks for, and marked it +`SameSite=Strict`, which is never sent from a third-party frame. Both are corrected here, and the +frontend now marks its cookies `SameSite=None; Secure; Partitioned` when it detects a third-party +context. The server-set cookies still need the same treatment, and that is upstream work in +`go-pkgz/auth`. + +Constraints on any frontend design: + +- nothing may assume the widget and host page share an origin. Note `BASE_URL` comes from + `remark_config.host`, read into `BASE_URL` in `app/common/constants.config.ts`, so the iframe is + cross-site only when that host differs from the page host; both configurations exist in the wild +- treat third-party cookie loss as the direction of travel. Safari blocks third-party cookies + outright and honours only cookies explicitly marked `Partitioned`; its CHIPS support has been + switched on, off and on again across releases, so pin the current state before relying on a + version number. A design depending on `SameSite=None` surviving has an expiry date +- the endpoint is CHIPS (`SameSite=None; Secure; Partitioned`) or a token not relying on ambient + cookies. Neither is a flag flip, and the first cost is upstream rather than here: + `go-pkgz/auth/v2@v2.2.0` cannot emit `Partitioned` at all. Both cookies are hand-built in + `Service.Set` with only `HttpOnly`, `Path`, `Domain`, `MaxAge`, `Secure` and `SameSite`, and + `AUTH_SAME_SITE` in `cmd/server.go` offers `default`/`none`/`lax`/`strict` with no partitioned + axis, since `Partitioned` is a separate attribute. That is a PR to the library before anything in + this repo changes +- the popup-to-iframe handoff cannot be done in JS. The JWT cookie is `HttpOnly: true`, set in + `Service.Set`, so the top-level popup cannot read it to hand over, and the receiving end would not + work either: `setAuthCookie` in `cookies.ts` writes `SameSite: 'Strict'` under a `__Host-` prefix + with no `Partitioned`, and Strict is never sent from a third-party frame. The handoff has to be + server-mediated, a one-time code redeemed for a `Set-Cookie … Partitioned` issued from the + embedded context. Email and anonymous authenticate over XHR from inside the iframe, which keeps + them working while third-party cookies are permitted, but XHR does not create a partition by + itself, so they need `Partitioned` for the same reason OAuth does +- the failure mode is silent rather than an error, which is why #1139 reads as a hang. OAuth + completion is detected by polling: `oauthSignin` in `auth/auth.api.ts` opens the popup and, on + `visibilitychange` once `authWindow.closed`, calls `getUser()`, with nothing posted back from the + popup. When the cookie is not readable from the embedded context, `getUser()` returns null and the + flow re-polls every minute until the 5 minute deadline gives up, showing a waiting state + throughout. Until #2197 that deadline rejected without tearing the subscription down, so the retry + outlived it and polled for the life of the page; the reason it lasted is that the arrangement it + breaks in is the one nobody runs locally +- the documented escape hatch is the fallback page. When the widget detects a third-party context + with storage unavailable it offers a link to `${origin}/web/comments.html` (`auth-panel.tsx`, the + `IS_THIRD_PARTY` and `IS_STORAGE_AVAILABLE` checks in `app/common/constants.ts`). That page went + unbuilt from the January 2021 rewrite until #2197 restored the entry, so it 404'd for four years + in exactly R1's configuration. Any redesign has to keep emitting it, and nothing pins that yet: + the `documentedWebPaths` table in `e2e/webfiles_test.go` still has no entry for it, which is the + same absence that let it break in the first place +- fixing #1139 must not get harder + +### R2: The language must be selectable per page, and may stay fixed after load + +24 catalogs in `app/locales/`. Locale is read once from `remark_config.locale` (the `locale` export +in `app/common/settings.ts`) and resolved to one chunk by `loadLocale`. There is **no runtime +switcher** and no locale entry in the postMessage contract, so language cannot change during an +instance's life. + +That makes this a comfortable requirement: a site with three language versions embeds each page with +its own locale. Server-generated per-locale output satisfies it as well as the current client +catalog. + +Must survive: + +- `remark_config.locale` keeps selecting the language per instance +- all 24 languages keep working. Adding one is not catalog-only today: the language goes into + `tasks/supportedLocales.json`, and generation then rewrites `app/utils/loadLocale.ts` from it. + Preserve that registry-plus-generation shape or replace it deliberately +- the translation completeness check in `ci-frontend.yml` survives in some form +- `formatDate`/`formatTime` (`Comment` in `comment.tsx`, implemented over `Intl.DateTimeFormat` in + `common/intl.tsx`) keep resolving in the viewer's **timezone**. The locale is not the viewer's: + the provider gets the configured `locale` (`remark.tsx`, from `remark_config.locale` via the + `locale` export in `settings.ts`), which the server knows too. Only the timezone is genuinely + client-side, so the carve-out is timezone-local time rendering rather than a whole date-formatting + layer + +## Server rendering is not blocked, but the document render is anonymous by force + +SSR is sometimes assumed to be impossible here, on the grounds that the widget document is +cross-site and the auth cookie defaults to Lax. That reasoning does not hold: + +- **htmx fragments are XHR, not document navigations.** They are same-origin to the widget document, + so the server-set auth cookie rides along exactly as it does for today's API calls. What + `htmx:configRequest` has to attach is the `X-XSRF-TOKEN` header read from the JS-readable XSRF + cookie, attached by `request()` in `fetcher.ts`, and on **every** authenticated request rather + than only state-changing ones: `request()` attaches it unconditionally for get, put, post and + delete alike. There is no JS-held JWT to attach under default configuration: `activeJwtToken` in + `fetcher.ts` is filled only from an `X-JWT` response header, which the server sends only in + `SEND_JWT_HEADER` mode +- **`AUTH_SEND_JWT_HEADER` defaults to false** (`backend/app/cmd/server.go`). Auth is cookie-based + by default, so the header was never what made it work +- **The cross-domain auth limitation already exists**, is documented, and is #1139's subject. SSR + does not introduce it and does not make it worse +- **The `/web/` cache and rate limit are not a general blocker.** They apply to the current static + route, where `addFileServer` applies `rateLimiter` and `cacheControl`; dynamic HTML served from a + new route avoids that pair, and `/api/v1` open routes already run through `NoCache`. The open + routes do carry their own limiter, `rateLimiter(s.openRouteLimiter)`, so a new route escapes the + static cache, not rate limiting in general. Price which bucket it lands in: open routes allow 10 + req/s per IP (`openRouteLimiter` in `rest.go`) against 20/s for static `/web/`, applied by + `addFileServer`, and a fragment UI multiplies requests per interaction against the tighter one. + Under R1, with readers behind shared egress, that is the operative ceiling +- **`AUTH_SAME_SITE=none` already exists** and would let cookies accompany iframe navigations on + browsers that still allow third-party cookies. It is inert for the document render, though, for + the reason below: the cookie arrives and is then discarded + +The real constraint is not about cookie delivery at all. + +**The first document render is anonymous in the configuration remark42 ships, and changing that is a +security decision rather than a flag flip.** The auth library rejects any cookie-borne token whose +`X-XSRF-TOKEN` header does not match the JWT's `jti`, in `Service.Get` of `go-pkgz/auth/v2@v2.2.0`. +A document navigation, which is what an iframe `src` is, cannot carry a custom header, so the widget +document arrives anonymous even with `AUTH_SAME_SITE=none`, even with third-party cookies fully +permitted, and even with a perfectly delivered partitioned cookie. `authMiddleware.Trace` swallows +the error, which is why it is silent. + +What makes it the current behaviour rather than a law is `XSRFIgnoreMethods`, an option the library +exposes on `Opts` and threads into the JWT service. remark42 leaves it unset, so the default empty +list applies and the short circuit in `Service.Get` never fires for any method. Setting it would +make an authenticated document render possible. + +Do not reach for it globally, though. `GET /deleteme` deletes every comment a user has written, and +is a GET deliberately, so that the link in the confirmation email works when clicked. Exempting GET +from XSRF wholesale removes that protection from a destructive endpoint. Anything built on this has +to scope the exemption to the document route alone, and that route has to be provably side-effect +free. Cost that work rather than assuming either that the door is shut or that it is open. + +There is also a query-parameter path, and it is worse than the constraint: `Service.Get` accepts the +token from a query parameter, `?jwt=` rather than the library default `?token=` because remark42 +overrides `JWTQuery` in `cmd/server.go`, and because `fromCookie` stays false the XSRF check is +skipped entirely. That would put a live JWT into `Referer`, into history, and into the access log if +the route is one that logs bodies. It is unreachable in any case, since the JWT cookie is `HttpOnly: +true`, set in `Service.Set`, and no JS can read it to build the URL. + +So anonymous-first is what the current configuration gives, and the honest Path B position is that +making the document authenticated is a scoped piece of security work with its own cost. Until that +is costed, budget for anonymous-first: render anonymous, then hydrate the user state over XHR, which +does carry the header. Anonymous-first is also what a shared cache wants, though see the hydration +item in Path B for how much that is worth. + +## Verified facts + +Checked against the code at `a82dc8d3` and by independent reviewers. + +- 9 runtime dependencies against 61 devDependencies, and **68** override entries, all in the single + `frontend/apps/remark42/package.json` since #2197 removed the workspace root. Before this effort + started it was 15 against 83 across two manifests +- `pnpm audit` reports **no known vulnerabilities** as of 2026-08-20, after the override work. The + 23 it reported before that were all build or test tooling and none shipped, so the toolchain's + security cost is recurring maintenance rather than a standing exposure, and it is a weak argument + for Path B +- Frontend churn 67 commits in 24 months against 119 on the backend, merges excluded on both sides +- Preact appears in 53 non-test files, 57 counting typings and stubs, and not only for `h` and JSX + types: `Fragment` in 11, `Component` in 7, `render` in 1, `createRef` in 3, `createContext` in 2, + and `preact/hooks` in 19. **No file imports `preact/compat` any more**, no `react` or `react-dom` + entries remain in `package.json`, and the only `paths` entries in `tsconfig.json` point at preact + itself. `frontend/CLAUDE.md` carries a "Don't import preact/compat" section recording why +- Composer plus auth is **~2,400 non-test lines** (`comment-form/` 1,540, `auth/` 867), the most + stateful code in the repo, plus two custom-element packages and the polyfill they need +- The e2e suite is Go and playwright-go since #2180, and passed 60 tests while this was being + written, up from 7. Treat the exact figure as stale on sight; it is the only coverage that + survives a rewrite +- The unit suite is 46 files, 25 `*.test.*` plus 21 `*.spec.*`, and **426 cases**, as jest + enumerates them. Counting only `*.test.*` understates it by twenty files, which is the trap +- `en.json` is 180 keys with no ICU plural or select forms +- 136 non-test source files under `app/` excluding typings, mocks and stubs, 8,498 lines; 152 files + and 8,715 lines counting them +- `profile.ts` (139 lines) is only the iframe host; the view is `profile.tsx` (235) reusing + `Comment` (638) in `view="user"` mode +- `last-comments` renders into the **host page**, not an iframe, and side-loads its own stylesheet + (`last-comments.tsx`) +- `/find` already supports server pagination via `limit` and `offset_id` in `findCommentsCtrl`; only + the widget ignores them +- Client-only state: collapse persisted via `remark.tsx` and `store/thread/utils.ts`; hidden users + localStorage-only (`store/user/actions.ts`); votes optimistic via component state, with the store + patched only on success and errors merely clearing `loadingState` (`comment-votes.tsx`) +- Emoji rendering and the image proxy already run server-side in `CommentFormatter`, wired in + `cmd/server.go`, so neither is a Path B cost +- 8 `window.confirm` call sites gate delete, pin, verify, block and hide (six in `comment.tsx`, two + in `settings.tsx`). The iframe carries no `sandbox` attribute, so `allow-modals` is not the issue, + but cross-origin iframe dialogs have been targeted for removal once already (Chrome 92, rolled + back after breakage). #2024 proposes an inline replacement. Either path inherits all 8, and R1 is + exactly the configuration where it bites +- `CommentFormatter` in `formatter.go` runs chroma with `html.WithClasses(true)`, so highlight CSS + lives in the bundle; `Comment.Text` is pre-sanitised while `Orig` is explicitly unsafe, as + `store.Comment` documents +- `getLocalIdent` in `webpack.config.js` emits order-dependent ids via `incstr`, **in production + only**; development builds use readable `[name]__[local]_[hash:5]`, since `getLocalIdent` is + production-only. They are stable for an identical module order and churn on any add or reorder, so + no embedder has a CSS override surface that survives an upgrade + +## What the bundler still does + +The concrete "what is left" list, and what any no-npm proposal has to answer for. + +- transpiles TS and JSX for 136 to 152 source files, typed by `tsconfig.json`, compiled by the + preset list in `.babelrc.js` +- CSS modules for 29 `*.module.css` files, 2,219 lines, including 177 nested `&`, 4 `composes` and + 10 `:global` occurrences across 6 files, all handled by the CSS-modules rule in + `webpack.config.js`. One of the `composes` crosses a file boundary (`auth.module.css` composes + `input` from `components/input/input.module.css`), which has no plain-CSS equivalent and has to be + flattened rather than translated +- code-splits the 24 locale JSON catalogs (`app/utils/loadLocale.ts`, itself generated) and + `node-emoji` (the lazy import in `comment-form/text-expander.tsx`) +- runs postcss-preset-env against `defaults, not IE 11, not samsung 12` +- builds six `.ejs` templates through `HtmlWebpackPlugin`, the sixth being `comments.ejs`, the R1 + fallback page above +- resolves images through `file-loader`. The public path is derived at runtime from the URL the + bundle was loaded from since #2197; before that it was fixed to `/web/`, so a sub-path install of + the kind `site/content/docs/manuals/subdomain/index.md` documents fetched its provider icons from + the domain root. A build with no bundler has to derive every asset URL from `BASE_URL` itself, and + inherits that requirement rather than the fix +- strips `data-testid` through a local babel plugin, which nothing else replicates +- minifies JS and CSS +- supplies `REMARK_NODE`, `REMARK_URL` and `NODE_ENV` through `DefinePlugin`, read by `NODE_ID` and + `BASE_URL` in `constants.config.ts`, and by `last-comments.tsx`. `REMARK_URL` is the one that had + teeth: it was baked in as `{% REMARK_URL %}` and substituted by the release script, which left + every published binary serving a widget pointed at loopback. #2198 moved the substitution to serve + time in the Go file server, so a no-bundler build inherits a working mechanism rather than a + broken one + +Five CI jobs depend on npm and each needs a replacement or an accepted loss: `translations-check`, +`type-check`, `lint`, `size-limit` and `test`, all in `ci-frontend.yml`. + +### What is already out + +The widget build is the last npm consumer in the repository, which is worth stating because it was +not true a week ago. + +- **`site/`** has no `package.json` at all since #2179 moved it from eleventy to hugo. It is now a + Go static generator against `hugo.toml`, `layouts/` and `content/`, and is no longer a separate + npm decision deferred to later +- **`e2e/`** is a Go module since #2180. Note the caveat: `playwright-go` downloads a node runtime + and the playwright npm package as its browser driver at test time (`e2e-tests.yml` caches both). + That is a fetched runtime rather than a tracked dependency, so it survives whatever happens here +- **`@remark42/api`** and `frontend/packages/` are gone with #2172 +- **Three static assets** moved into `backend/app/webassets/assets` in #2181 and are embedded in the + Go binary, which is the working proof that the no-build serving path carries real files + +Since #2197 removed the workspace root there is one manifest and one lockfile, +`frontend/apps/remark42/package.json` and its `pnpm-lock.yaml`. `release.yml` still runs pnpm to +build the widget, and that step goes when the widget build does. + +## Do first, regardless of path + +### Task 1: Document and type the public contract + +Answers discussion #1714. It is a discussion rather than an issue, so no PR closes it; the same is +true of #1715 and #1383. Every third-party integration found in the wild uses `remark_config` plus +`window.REMARK42.createInstance()`, and none of it is documented. + +The contract was written out in a reply on #1714 on 2026-08-20, and +`docs/backlog/public-widget-contract-docs-and-types.md` records the remaining work. One decision is +open and belongs here rather than in the backlog note: **how a public `.d.ts` reaches a consumer** +now that npm is the direction being left. Publishing it on the site as a copy-paste block needs no +infrastructure; a types-only package does not contradict #1715, whose objection was that shipping +widget *code* through npm breaks OAuth, but it adds a publish step and a version to keep in sync. + +- [ ] Document `createInstance`, `destroy`, `changeTheme`, the `REMARK42::ready` event and every + `remark_config` field, including the two behaviours that bite: `createInstance` throws rather than + returning an error, and its guard clauses read the **global** config while the rest of the + function reads the argument, so passing a config does not remove the need for a valid global. A + second call also reuses the iframe and ignores the config passed to it. #2197 stopped that call + stacking a second listener set, but left the reuse itself alone, so what the contract should be is + still open: replace the instance atomically, or return the existing one and require `destroy` + before a configuration change +- [ ] Ship a `.d.ts`, after deciding how it is delivered +- [ ] Move the REST reference out of `site/content/docs/contributing/api` into the integration docs; + #1383 states the API is the supported path for custom frontends +- [ ] Document `__colors__` from `window.name` (`templates/iframe.ejs`), which works today and is + undocumented +- [ ] Fix the Astro and Gatsby manuals, which declare `REMARK42: any` and `remark_config: any` + +### Task 2: Extend the e2e suite + +**Done.** #2180 moved the suite to Go and playwright-go and took it from 7 tests to 22; #2196 took +it to 48. Every item this task originally listed is covered: vote and its failure path +(`vote_test.go`), edit inside and outside the deadline, delete and reply (`comment_test.go`), sort +change and collapse persistence (`thread_test.go`), anonymous and email auth (`auth_test.go`), the +profile iframe and last-comments (`widgets_test.go`). + +What remains uncovered is a different list, and it is the contract surface rather than the +behaviour: a cross-origin host page (every host page in the suite is served from the widget origin, +so R1 has no coverage at all), the `comments.html` fallback, `remark_config` fields (`url`, +`page_title`, hash deep links, `max_shown_comments`, the three `show_*_subscription` flags, +`__colors__`), the listener leak on a repeated `createInstance`, timezone-local date rendering, the +unknown-locale fallback, and the composer. + +### Task 3: Stable class names and a documented override stylesheet + +Closes #5, open since 2018. Server-rendered markup needs stable names anyway, and the current ids +churn per build so there is nothing to preserve, only something to start honouring. + +- [ ] Replace the `getLocalIdent` output with stable semantic names on the public surface +- [ ] Document the override point + +The surface that exists today is accidental rather than designed, but it is not small, and that +changes what Task 3 is. `auth.tsx` alone emits sixteen global names (`auth`, `auth-error`, +`auth-dropdown`, `auth-form`, `auth-form-title`, `auth-row`, `auth-tabs`, `auth-tabs-item`, +`auth-divider`, `auth-close-button`, `auth-token-textarea`, `auth-submit`, `auth-button`, +`auth-back-button`, `auth-input-username`, `auth-input-email`). Add `select`, `select_focused`, +`select_`, `select-arrow` and `select-element` (`select.tsx`), `sort-picker` +(`sort-picker.tsx`), `oauth-icon` (the `OAuth` component in `oauth.tsx`), bare `.dark`/`.light` on +the root wrapper, and `comment_highlighting`, applied imperatively in `root.tsx`. Six module files +reach these through `:global()`. + +So the first step is an inventory rather than a design: integrators may already be relying on any of +these, and they have to be treated as a contract to preserve rather than a blank sheet. Note also +that the hashed names are deterministic for an identical module order, so they churn on a reorder +rather than on every build; the problem is that nothing tells an integrator which of the two kinds +of name they are looking at. + +Two things make this more urgent than its age suggests. Production and development emit different +names, so a developer never sees what an integrator sees. And unit tests run through +`identity-obj-proxy`, mapped in `jest.config.mjs`, so no test observes a real class name and nothing +would catch a naming regression. + +`app/styles/custom-properties.css` is the one stylesheet already in the right shape for this: 80 +plain custom properties, no module scoping, nothing for the bundler to rename. + +**Ordering caution.** #2128 is rewriting this same CSS layer on the assumption that hashed class +names stay. Settling the direction here first avoids redoing that work. + +## Path A: incremental simplification + +Keep Preact. Remove what makes it expensive. + +- [x] Replace `react-redux`. Done in #2175: `app/store/context.tsx` is a small binding over preact + context, and the store's own logic was already plain `redux` plus `redux-thunk` +- [x] Replace `react-intl`. Done in #2176: `app/common/intl.tsx` is a 253-line binding over preact + context with 25 importers. Note what it does **not** implement, because it constrains R2: `{name}` + interpolation and paired `` rich text only, with no ICU plural, select, typed arguments or + apostrophe quoting. All 24 catalogs stay within that today +- [x] Delete the `react`/`react-dom` aliases, `@preact/compat` and the `paths` entries in + `tsconfig.json`. Done in #2176 +- [x] Collapse the compiler pipelines to one. Done in #2178: `ts-loader`, `@swc/jest`, `@swc/core` + and enzyme are gone, `babel-loader` is the only compiler, and `jest.config.mjs` hands the same + `.babelrc.js` to `babel-jest`. The same PR dropped the module/nomodule dual build, so output is + `[name].mjs` only and `.js` is a server-side alias (the alias comment in + `backend/app/rest/api/webfiles.go`) +- [ ] Evaluate **preact + htm over native ESM**, and treat the answer as likely no. It is not the + cheap item it looks: dropping the JSX transpile drops type-checked markup, since the `jsx: + react-jsx` and `jsxImportSource: preact` options in `tsconfig.json` is what types templates today + and `htm` tagged literals are opaque to `tsc`. Rewriting every `.tsx` with a type-safety + regression is the same objection the Rejected section uses against a vanilla rewrite. Unbundling + 136 or more source files plus 24 locale chunks into individually fetched modules also multiplies a + cold load's request count against the 20/s `/web/` bucket that `addFileServer` applies, and + because `cacheControl` sends `max-age=3600, no-cache` with an ETag even a warm cache revalidates + each one. It additionally collides with the legacy `.js` contract, which promises module-free + bytes + +**What actually happened**: the first four items landed within two days of this document being +written, on 21 August. Only the htm evaluation is open, which retires the original framing that this +path "spends the expensive `react-intl` card on the option that does not remove npm". That card is +already played, and it cost less than estimated. + +**The revised objection**: the devDependency target did not materialise. This document predicted a +fall from 82 to roughly 20; the figure after the collapse is 59. What survives is not compilation +but **gates and machinery**: eslint, stylelint, prettier, size-limit, `@formatjs/cli` and the +webpack plugin set. That reframes both paths. The remaining question is no longer how the code is +compiled, it is what verifies it. + +## Path B: server-rendered, #825 + +- [ ] Serve dynamic HTML from a **new route**, and not just outside `/web/`. It must also sit + outside `/api/v1`, because `apiCSPMiddleware` replaces the CSP on everything mounted there with + `default-src 'none'; sandbox; frame-ancestors 'none'`, from `rest/image_headers.go`, which would + sandbox the widget document and forbid framing it at all. The global `securityHeadersMiddleware` + is what supplies `frame-ancestors` from `ALLOWED_HOSTS`, so it is also R1's enforcement point. + Note its `form-action 'none'`: htmx uses XHR and is unaffected, but a progressive-enhancement + design built on real form submissions is blocked by the existing policy +- [ ] Render anonymous-first, then hydrate. Budget this as a **second full render of the tree**, not + a patch: user identity threads through every node. `prepVotes` in `store/service/service.go` sets + each comment's `Vote` from the requester and strips the voter map, `alterCommentCached` blanks + `User.IP` for non-admins, and on top sit the edit window, own-comment delete, admin controls and + hidden users. The backend already shows the shape: `/find` keys its cache on `URLKeyWithUser` + (`URLKeyWithUser`, used by `findCommentsCtrl`), one entry per user with a separate `admin!!` key. + An HTML cache fragments the same way, so the shared-cache benefit only pays for logged-out readers +- [ ] Attach the existing auth via `htmx:configRequest` on fragment requests +- [ ] Keep client-side: embed script, auth popups, composer, collapse and hidden-user state, + optimistic votes, and the **three subscription flows**. Email, Telegram and RSS + (`comment-form/__subscribe-by-email/`, `__subscribe-by-telegram/`, `__subscribe-by-rss/`) are each + multi-step and stateful (send code, enter code, confirm; QR plus poll), backing seven private + endpoints in `routes()` plus the `GET /qr/telegram` route +- [ ] Keep the height shim on every swap. The iframe has no intrinsic height; the parent sizes it + from `postMessage({height})` (`updateIframeHeight` in `utils/post-message.ts`, consumed in + `embed.ts`). The ResizeObserver that feeds it already exists (the `ResizeObserver` in `root.tsx`, + plus the dropdown one in `auth.hooks.ts`), so this is code to carry forward rather than write +- [ ] Serve the `?selfClose` stub from the new route. OAuth builds its return URL from the widget + document's own path (`oauth.tsx` builds `origin + pathname + '?selfClose'`) and `iframe.ejs` + closes the popup on arrival. Move the document and the return URL moves with it, so the new route + inherits the self-closing stub and must not cache that response +- [ ] Thread `?site=` through every fragment URL. `matchSiteID` rejects an empty `site` param on + every private and admin request, so a fragment that omits it gets a 403 rather than a 401 +- [ ] Join the public response cache's flush scopes. Comment and info responses are cached keyed by + `Scopes(siteID, URL)` and flushed on writes (`findCommentsCtrl` and `infoCtrl`); a dynamic HTML + route outside those scopes serves stale comments after every post +- [ ] Move i18n server-side except timezone-local `formatDate`/`formatTime`. This is a from-zero + build: `backend/app/templates` holds five templates today, four email plus one error page, and no + catalog machinery. Go's `text/template` has no plural support either, so the current no-ICU + position has to be stated as a rule or implemented on both sides +- [ ] Decide what happens to the two host-DOM scripts, `last-comments` (`last-comments.tsx`) and + `counter` (`counter.ts`), which write into the host page rather than into the iframe. Cross-origin + server rendering is available to them through CORS fragments (the backend runs `corsMiddleware()` + unless `ProxyCORS` is set, in `routes()`) or through an iframe, so this is a design choice, not a + blocker + +**Cost**: months to an opt-in parallel UI reads as a floor derived from the optimistic architecture, +and the optimistic architecture does not hold. Anonymous-first is forced rather than chosen, so the +fragment layer reproduces the entire authenticated tree rather than a delta; add the three +subscription flows and, if R1 is to be honoured, the upstream `Partitioned` work in `go-pkgz/auth`. +On one contributor the realistic figure is long enough that the plan's own warning applies to the +schedule and not only to the design. Deletes the entire npm toolchain. **Against it**: 2,400 lines +of the most stateful code get rewritten; a second HTML-fragment API surface becomes permanent +alongside the JSON one; and no comparable project does this (isso, utterances, waline and cusdis are +all client-rendered, giscus does SSR in JS, and comentario, the closest Go analogue, ships a +framework-free TS web component). + +The net that rewrite would run against is materially better than when this was written: sixty-odd +tests rather than seven, and still growing. It is still not a substitute for the 426 unit cases, +which is a separate item below. + +**The unresolved tension**: "deletes the entire npm toolchain" and "keep the composer, auth, votes, +collapse and the embed script client-side" pull against each other. That kept code is 2,400 lines of +TSX today and the composer leans on two custom-element packages and a polyfill. Without npm it +becomes hand-authored vanilla or htm modules, which is the same "unowned in-house framework" risk +the Rejected section uses to rule out a full vanilla rewrite, now applied to the most stateful code +in the repo. Path B is not costed until it says what the kept client code is written in. + +## What neither path has answered yet + +Missing from both costings, and each one can move the verdict. + +- **A definition of done for "no npm".** Which files and jobs actually go: the node stages in + `Dockerfile`, the five `ci-frontend.yml` jobs, the pnpm steps in `release.yml`, husky and + lint-staged. And what replaces each gate, or which loss is accepted +- **A browser-support floor.** the browserslist query in `.babelrc.js` targets `defaults, not IE 11, + not samsung 12` today. Without a transpiler that becomes the literal floor and source syntax ships + as written, which matters for native CSS nesting and JSON import attributes +- **A runtime-dependency inventory.** For each of `preact`, `redux`, `redux-thunk`, `clsx`, + `lodash-es/isEqual`, `node-emoji` and the three custom elements: is there a usable ESM build, what + is the licence, and is it vendored into `backend/app/webassets/assets` or dropped. The two the + plan itself proposes, `htm` for Path A and `htmx` for Path B, belong in the same inventory with + the same columns, plus what each costs the CSP. "Vendor the custom elements" understates them: + `markdown-toolbar` mutates textarea selections and `text-expander` emits its own events and lazily + loads the emoji data, so the tags rendering is not the same as the behaviour working +- **A security section.** Messages are still posted with `'*'` in both directions + (`postMessageToParent` and `postMessageToIframe` in `post-message.ts`), so both ends check the + sender rather than the target: #2197 made the parent ignore anything that did not come from a + frame it created, and the child side checks `isFromParent`. The child cannot do better, because + the host page is whatever site embeds the widget and `ALLOWED_HOSTS` is what constrains that, + server side through `frame-ancestors`. The parent can: it builds the iframe URL from `BASE_URL`, + so it knows the widget origin and could both pass that as `targetOrigin` instead of `'*'` and + compare `event.origin` alongside `event.source`. That hardening is available and not done. Beyond + the channel, `dangerouslySetInnerHTML` on comment text and preview (`comment.tsx` and + `comment-form.tsx`) relies entirely on server-side sanitisation in `store.Comment`, and any new + route needs its CSP decided +- **The integrator compatibility contract beyond the JS API.** The documented `/web` URLs pinned by + `documentedWebPaths` in `e2e/webfiles_test.go`, the `remark_config.components` loader, and the + legacy `.js` names, which must stay module-free. `/web` is also an overlay rather than one + directory: a `--web-root` file wins and only a missing name falls through to the embedded assets + (`webFileSystem` in `webfiles.go`, mounted by `addFileServer`), so moving a page between the two + sources silently changes whether an operator can override it +- **Translation tooling after node.** Only `@formatjs/cli` is genuinely npm-bound; the downstream + `tasks/*.js` scripts are dependency-free node over `extracted-messages/messages.json`. Note the + failure mode: extraction matches the identifiers `defineMessages`, `FormattedMessage` and + `intl.formatMessage` rather than an import source, so moving strings into Go templates extracts + zero keys with a zero exit code, after which `generateDictionary.js` deletes them from all 24 + catalogs +- **A replacement strategy for the 426 unit cases**, naming what e2e cannot reach: the store, the + fetcher, cookie handling and the intl parser. Two whole flows sit here rather than in the e2e net: + Telegram auth and subscription have no browser route at all, which the e2e suite's own backlog + note records, and RSS subscription is covered only for whether its control renders. Path B keeps + all three subscription flows, so it inherits all three gaps +- **Whether dependency-free node scripts are allowed to stay.** The goal bans the installed + dependency tree and the build and test machinery, but `tasks/checkTranslation.js` and its siblings + need only node built-ins. Nothing in the goal as stated decides whether they survive as scripts or + have to be ported to Go, and the answer changes the size of the i18n item +- **A build-output acceptance matrix.** Each generated HTML page, the dynamic catalogue and emoji + payloads, the copied images, the stripped `data-testid` attributes and the compressed size budgets + are today the emergent result of separate webpack rules and plugins rather than one replaceable + step. Without a statement of what the output must contain, a replacement cannot be checked against + anything +- **Size budgets and the dev loop.** `.size-limit.js` and `webpack-dev-server` both disappear with + npm; a Go test over the embedded FS covers the first, `make rundev` plus `--web-root` the second +- **Storage partitioning semantics.** Collapse, hidden users, sort, draft and email all live in + widget-origin `localStorage`, so on a multi-site install "persists across reload" becomes per top + site +- **Sequencing against #2128**, which rewrites the CSS layer on the assumption that hashed class + names stay. It is the one piece of work in flight that Task 3 collides with, and settling the + class-name direction first is what stops that work being redone + +## If Path B is chosen + +Ship it as an opt-in parallel UI (`remark_config.ui: 'v2'` on a separate endpoint), time-boxed, with +a stated date at which one of the two is deleted. With one active frontend contributor the realistic +failure is not picking the wrong stack, it is carrying two half-finished ones. + +## Rejected + +- **Full vanilla rewrite**: the render layer becomes an unowned in-house framework +- **lit / alpine / solid / petite-vue**: none removes more tooling than Path A, each trades a known + 3 kB library for a less-known one +- **Packaging widgets for npm (#1715)**: the widget must run in an iframe on the remark42 origin for + OAuth popups; importing it into a host bundle breaks auth. A types-only package is a separate + question and is not covered by that objection +- **`@remark42/api`**: removed in #2172. It had no OAuth method and no consumers. + `frontend/packages/` is gone with it, and #2197 removed the workspace root outright, leaving a + single manifest and lockfile under `frontend/apps/remark42` diff --git a/e2e/widgets_test.go b/e2e/widgets_test.go index f03edd4b..90f59352 100644 --- a/e2e/widgets_test.go +++ b/e2e/widgets_test.go @@ -6,6 +6,7 @@ import ( "encoding/json" "fmt" "net/http" + neturl "net/url" "os" "path/filepath" "strconv" @@ -326,3 +327,83 @@ func TestWidgets_SimpleViewHidesTheEditingFurniture(t *testing.T) { }) } } + +// TestWidgets_CommentsPageOpensAThreadOnItsOwnOrigin covers /web/comments.html, which is where the +// widget sends a reader whose browser blocks third-party storage: the auth panel links it, and the +// page mounts the widget on the instance's own origin, where the storage is first-party. +// +// The page is built from templates/comments.ejs by HtmlWebpackPlugin, and the build stopped +// emitting it while the link went on pointing at it, so readers who followed it reached a 404. +// Nothing noticed, because it is the one page no other test opens. +func TestWidgets_CommentsPageOpensAThreadOnItsOwnOrigin(t *testing.T) { + thread := threadURL(t) + text := "cookie fallback " + runID + + poster := newPage(t) + posted := openURL(t, poster, thread) + signInAnon(t, poster, posted, "fallbackposter") + postComment(t, posted, text) + + page := newPage(t) + pauseForAuthLimit() + resp, err := page.Goto(fmt.Sprintf("%s/web/comments.html?site_id=remark&url=%s", + baseURL, neturl.QueryEscape(thread))) + require.NoError(t, err) + require.NotNil(t, resp) + require.Equal(t, 200, resp.Status(), + "the page the auth panel links to when third-party storage is blocked is not served") + + // it reads the thread out of its own query string and mounts the widget itself, so reaching + // the comment proves the page was served, its inline script ran, and it asked for the right + // thread. a 200 alone would be satisfied by any page the server happened to return + frame := widget(t, page) + waitVisible(t, comment(frame, text)) +} + +// TestWidgets_CommentsPageRefusesInjectedMarkup covers the reflected injection the fallback page +// carried. It puts the url from its own query string into the title, and building that with +// innerHTML let a crafted url run script in a top-level document on the instance's own origin, +// which is where the reader's session lives; inside the widget frame the same payload would be +// far less use. The hole and the page arrived together, since it is only reachable at all now +// that the build emits it again +func TestWidgets_CommentsPageRefusesInjectedMarkup(t *testing.T) { + for _, tc := range []struct { + name, url string + }{ + {"markup", `">`}, + {"javascript scheme", "javascript:window.__xss=1"}, + } { + t.Run(tc.name, func(t *testing.T) { + page := newPage(t) + + pauseForAuthLimit() + // %20 and not +, which is what a browser produces and what the page's own parser + // reads back: it decodes with decodeURIComponent, which leaves a + as a plus + escaped := strings.ReplaceAll(neturl.QueryEscape(tc.url), "+", "%20") + _, err := page.Goto(fmt.Sprintf("%s/web/comments.html?site_id=remark&url=%s", baseURL, escaped)) + require.NoError(t, err) + waitVisible(t, page.Locator("#title")) + + // nothing the url asked for became an element + imgs, err := page.Locator("#title img").Count() + require.NoError(t, err) + assert.Zero(t, imgs, "the url reached the page as markup, so a crafted one runs script "+ + "on the instance's own origin") + + ran, err := page.Evaluate(`() => Boolean(window.__xss)`) + require.NoError(t, err) + assert.Equal(t, false, ran, "the injected script ran") + + // and the title still shows what it was given, so what changed is the escaping and + // not the feature + txt, err := page.Locator("#title").InnerText() + require.NoError(t, err) + assert.Contains(t, txt, tc.url, "the title should carry the url as text") + + // only http(s) reaches href, or the anchor itself becomes the payload + href, err := page.Locator("#title a").First().GetAttribute("href") + require.NoError(t, err) + assert.Empty(t, href, "a url the page will not navigate to should not become a link") + }) + } +} diff --git a/frontend/CLAUDE.md b/frontend/CLAUDE.md index 365977c3..1b570561 100644 --- a/frontend/CLAUDE.md +++ b/frontend/CLAUDE.md @@ -8,7 +8,7 @@ CI staying green does **not** mean every pin is consistent — `.nvmrc` in parti - `Dockerfile` (production image) — `FROM node:X-alpine` and `npm i -g pnpm@X.Y.Z` - `frontend/.nvmrc` — not read by CI at all; only matters to a human running `nvm use` locally. This is the one that drifted unnoticed: it sat at `16` through the whole node-20 migration because nothing red ever pointed at it. -- Every `package.json`'s `packageManager` field (`frontend/package.json`, `frontend/apps/remark42/package.json`) and `frontend/apps/remark42/package.json`'s `engines` block +- `frontend/apps/remark42/package.json`, both its `packageManager` field and its `engines` block - `pnpm/action-setup@vN` blocks in `.github/workflows/ci-frontend.yml` (5) and `release.yml` (2) — pin `version:` to the **exact** patch (e.g. `10.10.0`), matching `packageManager`, not just the major. A floating major here is silent in CI (it just resolves to whatever the latest patch is at run time) but breaks the "Dockerfile and CI use the same pnpm" guarantee. - `node:` matrices in `.github/workflows/ci-frontend.yml` (every entry, not just the first) and the `node-version:` values in `release.yml` @@ -16,6 +16,16 @@ When bumping pnpm/node, also re-check `frontend/apps/remark42/package.json`'s `e `engines.node` states the major we support, currently `>=24`, which is the active LTS; 22 has dropped to maintenance. `@babel/core` 8 wants `^22.18 || >=24.11` and `size-limit` 13 wants `^22.18 || ^24 || >=26`, so 22 was the floor rather than the target. Individual dev dependencies can be stricter within that major (`undici` wants `>=20.18.1`); do not chase those patch floors into `engines` or the docs, or every lockfile refresh becomes a documentation change. +## One manifest, at `frontend/apps/remark42` + +`frontend/` holds no `package.json`, no lockfile and no `pnpm-workspace.yaml`. Everything pnpm reads +lives in `frontend/apps/remark42`: the dependencies, `packageManager`, `engines` and the +`pnpm.overrides` block. Install and run from there, not from `frontend/`. + +The directory nesting is kept because every path in the repository points at it, from the Dockerfile +and the workflows to the published contributing docs. `frontend/` still carries `.nvmrc`, `.husky` +and this file, none of which pnpm reads. + ## pnpm 10's stricter `node-linker` layout needs explicit pins One dep is pinned specifically because of pnpm 10's hoisting changes, not because of the dep itself: @@ -74,11 +84,11 @@ Keep both in step. If babel were left on the classic `pragma: 'h'` transform, a without `import { h }` would type-check and lint clean, then throw at runtime, because `eslint-config-preact` sets `react/react-in-jsx-scope` to 0 and the local config turns `no-undef` off. -## `@babel/core` is pinned to 8 for the whole workspace +## `@babel/core` is pinned to 8 for the whole dependency tree `@jest/transform` and `istanbul-lib-instrument` depend on `@babel/core` 7 outright, and a babel 8 preset loaded into a babel 7 core fails on the first `enum` it meets. The `pnpm.overrides` entry in -`frontend/package.json` is what stops that. `eslint-config-preact` is the one consumer that cannot +`frontend/apps/remark42/package.json` is what stops that. `eslint-config-preact` is the one consumer that cannot take it: its `@babel/eslint-parser` loads babel 7 syntax plugins that babel 8 rejects, so a second scoped override, `eslint-config-preact>@babel/core`, holds that subtree on 7. @@ -103,8 +113,8 @@ directory second, matching the backend's order, so links to them resolve on the `eslint.config.mjs` lives in `apps/remark42`, and eslint loads the config next to the directory it is *run from* rather than the one nearest the file being linted. Anything that invokes eslint has -to have `apps/remark42` as its working directory: the workspace-root `lint` script filters to the -app, `.husky/pre-commit` cd's into it, and an IDE integration needs +to have `apps/remark42` as its working directory: it is where every script runs, `.husky/pre-commit` +cd's into it, and an IDE integration needs `"eslint.workingDirectories": ["frontend/apps/remark42"]`. Rules that only exist under a plugin's flat-config export are spread in explicitly; the block that diff --git a/frontend/apps/remark42/app/common/cookies.https.test.ts b/frontend/apps/remark42/app/common/cookies.https.test.ts new file mode 100644 index 00000000..07f72b24 --- /dev/null +++ b/frontend/apps/remark42/app/common/cookies.https.test.ts @@ -0,0 +1,90 @@ +/** + * @jest-environment jsdom + * @jest-environment-options {"url": "https://remark42.example.com/web/iframe.html"} + */ + +/** + * The naming bug this guards against only appeared on https, because the prefix was applied from + * `window.location.protocol`. Every other suite here runs on the jsdom default of http, so the + * decoration never showed up and the defect reached production untouched. This file exists to run + * the same code on an https page, which is the only condition that reveals it. + */ + +function captureRaw() { + const written: string[] = []; + const original = Object.getOwnPropertyDescriptor(Document.prototype, 'cookie'); + + Object.defineProperty(document, 'cookie', { + configurable: true, + get: () => '', + set: (v: string) => { + written.push(v); + }, + }); + + return { + written, + restore() { + delete (document as unknown as Record).cookie; + if (original) Object.defineProperty(Document.prototype, 'cookie', original); + }, + }; +} + +async function loadCookies(thirdParty: boolean) { + jest.resetModules(); + jest.doMock('./constants', () => ({ IS_THIRD_PARTY: thirdParty })); + + return import('./cookies'); +} + +afterEach(() => { + jest.dontMock('./constants'); +}); + +describe('auth cookies on an https page', () => { + it('writes the undecorated name the backend and the fetcher read', async () => { + const raw = captureRaw(); + const { setAuthCookie } = await loadCookies(false); + + setAuthCookie('JWT', 'token'); + setAuthCookie('XSRF-TOKEN', 'jti'); + + // the backend looks for JWT and `fetcher` reads XSRF-TOKEN. A __Host- prefix stores both + // under names neither of them asks for, and only here, on https + expect(raw.written[0]).toMatch(/^JWT=token/); + expect(raw.written[1]).toMatch(/^XSRF-TOKEN=jti/); + expect(raw.written.join('\n')).not.toContain('__Host-'); + + raw.restore(); + }); + + it('marks the cookie for third-party delivery when the page is on another origin', async () => { + const raw = captureRaw(); + const { setAuthCookie } = await loadCookies(true); + + setAuthCookie('JWT', 'token'); + + expect(raw.written[0]).toContain('sameSite=None'); + expect(raw.written[0]).toContain('secure'); + expect(raw.written[0]).toContain('partitioned'); + + raw.restore(); + }); + + it('clears under the same attributes, so the browser matches the cookie it set', async () => { + const raw = captureRaw(); + const { clearAuthCookie } = await loadCookies(true); + + clearAuthCookie('JWT'); + + expect(raw.written[0]).toMatch(/^JWT=;/); + expect(raw.written[0]).not.toContain('__Host-'); + expect(raw.written[0]).toContain('sameSite=None'); + expect(raw.written[0]).toContain('partitioned'); + + raw.restore(); + }); +}); + +export {}; diff --git a/frontend/apps/remark42/app/common/cookies.test.ts b/frontend/apps/remark42/app/common/cookies.test.ts new file mode 100644 index 00000000..bf3fd2bb --- /dev/null +++ b/frontend/apps/remark42/app/common/cookies.test.ts @@ -0,0 +1,137 @@ +/** + * These cookies exist to be read by someone else: the JWT by the backend, which looks for `JWT`, + * and the XSRF value by `fetcher`, which reads `XSRF-TOKEN`. So the name written and the + * attributes that decide delivery are the whole contract. + * + * `window.location` is not redefinable under jsdom, so the protocol-dependent half is covered by + * calling `authCookieOptions` directly rather than by faking an https page. + */ + +/** captures the strings assigned to document.cookie, which is where the attributes live */ +function captureCookieWrites() { + const written: string[] = []; + const original = Object.getOwnPropertyDescriptor(Document.prototype, 'cookie'); + + Object.defineProperty(document, 'cookie', { + configurable: true, + get: () => written.join('; '), + set: (v: string) => { + written.push(v.split(';')[0]); + }, + }); + + return { + written, + restore() { + delete (document as unknown as Record).cookie; + if (original) Object.defineProperty(Document.prototype, 'cookie', original); + }, + }; +} + +/** raw assignments, attributes included, which the capture above deliberately strips for reads */ +function captureRaw() { + const written: string[] = []; + const original = Object.getOwnPropertyDescriptor(Document.prototype, 'cookie'); + + Object.defineProperty(document, 'cookie', { + configurable: true, + get: () => '', + set: (v: string) => { + written.push(v); + }, + }); + + return { + written, + restore() { + delete (document as unknown as Record).cookie; + if (original) Object.defineProperty(Document.prototype, 'cookie', original); + }, + }; +} + +async function loadCookies(thirdParty: boolean) { + jest.resetModules(); + jest.doMock('./constants', () => ({ IS_THIRD_PARTY: thirdParty })); + + return import('./cookies'); +} + +afterEach(() => { + jest.dontMock('./constants'); +}); + +describe('authCookieOptions', () => { + it('keeps the cookie off cross-site requests when the widget shares its page origin', async () => { + const { authCookieOptions } = await loadCookies(false); + + expect(authCookieOptions(true)).toEqual({ path: '/', sameSite: 'Strict', secure: true }); + }); + + it('asks for delivery in a third-party frame when the page is on another origin', async () => { + const { authCookieOptions } = await loadCookies(true); + + // Strict is never sent from a third-party frame: SameSite is judged against the top-level + // site, not the request's own origin. None needs Secure, and Partitioned is what survives + // third-party cookie blocking + expect(authCookieOptions(true)).toEqual({ + path: '/', + sameSite: 'None', + secure: true, + partitioned: true, + }); + }); + + it('does not claim attributes it cannot honour over http', async () => { + const { authCookieOptions } = await loadCookies(true); + + // SameSite=None without Secure is rejected outright, which loses the cookie altogether + expect(authCookieOptions(false)).toEqual({ path: '/', sameSite: 'Strict', secure: false }); + }); +}); + +describe('setAuthCookie', () => { + it('writes the name it was given, undecorated', async () => { + const raw = captureRaw(); + const { setAuthCookie } = await loadCookies(false); + + setAuthCookie('XSRF-TOKEN', 'jti-value'); + + // a __Host- prefix stores the value under a name neither the backend nor the fetcher asks + // for, and only on https, so it is invisible until deployment + expect(raw.written[0]).toMatch(/^XSRF-TOKEN=jti-value/); + expect(raw.written[0]).not.toContain('__Host-'); + + raw.restore(); + }); + + it('round-trips through the reader that consumes it', async () => { + const capture = captureCookieWrites(); + const { setAuthCookie, getCookie } = await loadCookies(false); + + setAuthCookie('XSRF-TOKEN', 'jti-value'); + + expect(getCookie('XSRF-TOKEN')).toBe('jti-value'); + + capture.restore(); + }); +}); + +describe('clearAuthCookie', () => { + it('expires the cookie under the attributes it was set with', async () => { + const raw = captureRaw(); + const { clearAuthCookie } = await loadCookies(true); + + clearAuthCookie('JWT'); + + // a mismatched SameSite or Partitioned makes this a different cookie, and the original stays + expect(raw.written[0]).toMatch(/^JWT=;/); + expect(raw.written[0]).toContain('Thu, 01 Jan 1970'); + expect(raw.written[0]).toContain('sameSite=Strict'); + + raw.restore(); + }); +}); + +export {}; diff --git a/frontend/apps/remark42/app/common/cookies.ts b/frontend/apps/remark42/app/common/cookies.ts index 7ac4590b..23aa6608 100644 --- a/frontend/apps/remark42/app/common/cookies.ts +++ b/frontend/apps/remark42/app/common/cookies.ts @@ -1,3 +1,5 @@ +import { IS_THIRD_PARTY } from './constants'; + interface CookieOptions { /** * Either time in seconds, @@ -9,6 +11,12 @@ interface CookieOptions { domain?: string; secure?: boolean; sameSite?: 'Strict' | 'Lax' | 'None'; + /** + * CHIPS. Keys the cookie to the embedding top-level site as well as its own, which is the only + * form of third-party cookie browsers still accept. Requires Secure, and is meaningless without + * `sameSite: 'None'`. + */ + partitioned?: boolean; } export function setCookie(name: string, value: string, options: CookieOptions = {}) { @@ -39,48 +47,56 @@ export function setCookie(name: string, value: string, options: CookieOptions = } /** - * Sets a cookie with enhanced security options for authentication + * Attributes an auth cookie has to carry to be delivered in the context the widget is running in. + * + * The name is never decorated. These cookies exist to be read by someone else: the JWT by the + * backend, which looks for `JWT`, and the XSRF value by `fetcher`, which reads `XSRF-TOKEN`. A + * `__Host-` prefix would satisfy neither, and the security it buys is worth nothing on a cookie + * that no longer reaches its reader. + * + * `SameSite` follows the embedding. Strict is right when the widget and the page share an origin + * and keeps the cookie off cross-site requests entirely. It is fatal once they do not: a Strict + * cookie is never sent from a third-party frame, because `SameSite` is judged against the + * top-level site rather than the request's own origin. The separate-domain arrangement therefore + * needs `None`, which browsers only honour with `Secure`, plus `Partitioned` to survive + * third-party cookie blocking. + * + * Over http in a third-party frame there is no combination that works, and this returns the + * strict form rather than an unusable one. + */ +export function authCookieOptions(isSecure: boolean): CookieOptions { + if (IS_THIRD_PARTY && isSecure) { + return { path: '/', sameSite: 'None', secure: true, partitioned: true }; + } + + return { path: '/', sameSite: 'Strict', secure: isSecure }; +} + +/** + * Sets a cookie with the attributes its delivery context requires * @param name The name of the cookie * @param value The value to set * @param options Additional cookie options */ export function setAuthCookie(name: string, value: string, options: CookieOptions = {}) { const isSecure = window.location.protocol === 'https:'; - const cookiePrefix = isSecure ? '__Host-' : ''; - // Default options for auth cookies with strong security - const authOptions: CookieOptions = { - path: '/', - sameSite: 'Strict', - secure: isSecure, - ...options, - }; - - setCookie(`${cookiePrefix}${name}`, value, authOptions); + setCookie(name, value, { ...authCookieOptions(isSecure), ...options }); } /** - * Clears an authentication cookie by setting its expiration to the past + * Clears an authentication cookie by setting its expiration to the past. + * The attributes have to match the ones it was set with, or the browser treats it as a different + * cookie and leaves the original in place. * @param name The name of the cookie to clear */ export function clearAuthCookie(name: string) { const isSecure = window.location.protocol === 'https:'; - const cookiePrefix = isSecure ? '__Host-' : ''; - setCookie(`${cookiePrefix}${name}`, '', { - path: '/', - secure: isSecure, + setCookie(name, '', { + ...authCookieOptions(isSecure), expires: new Date(0), // Set to epoch time to expire immediately }); - - // Also try to clear the non-prefixed version to be thorough - if (cookiePrefix) { - setCookie(name, '', { - path: '/', - secure: isSecure, - expires: new Date(0), - }); - } } export function getCookie(name: string) { diff --git a/frontend/apps/remark42/app/components/auth/auth.api.spec.ts b/frontend/apps/remark42/app/components/auth/auth.api.spec.ts new file mode 100644 index 00000000..70f22d50 --- /dev/null +++ b/frontend/apps/remark42/app/components/auth/auth.api.spec.ts @@ -0,0 +1,118 @@ +import { oauthSignin } from './auth.api'; + +/** + * The OAuth flow has no message from the popup to listen for: the popup closes itself and the + * opener notices, so completion is detected by polling `getUser` whenever the document regains + * focus. That polling is what these tests are about. Cross-domain embedding is the case where + * the cookie never becomes readable and `getUser` therefore never stops returning null, so the + * retry has to be bounded by something other than success. + */ +describe('oauthSignin', () => { + const openedWindow = { closed: true } as Window; + + beforeEach(() => { + jest.useFakeTimers(); + jest.spyOn(window, 'open').mockReturnValue(openedWindow); + // the poll only fires while the document is focused and visible + jest.spyOn(document, 'hasFocus').mockReturnValue(true); + Object.defineProperty(document, 'hidden', { value: false, configurable: true }); + fetchMock.resetMocks(); + }); + + afterEach(() => { + jest.runOnlyPendingTimers(); + jest.useRealTimers(); + jest.restoreAllMocks(); + }); + + /** how many listeners the flow has attached and not removed */ + function listenerCount() { + return ( + (document.addEventListener as jest.Mock).mock.calls.length - + (document.removeEventListener as jest.Mock).mock.calls.length + ); + } + + it('stops polling once it gives up', async () => { + // an unauthenticated response is what a cross-domain embed gets indefinitely + fetchMock.mockResponse('', { status: 401 }); + const pending = oauthSignin('/auth/github/login'); + const rejected = expect(pending).rejects.toThrow(/authorization window/); + + // the poll is reachable only from the two listeners and from the retry it schedules itself, + // so without dispatching one of them no request is ever made and this test asserts nothing + window.dispatchEvent(new Event('focus')); + await jest.advanceTimersByTimeAsync(0); + expect(fetchMock.mock.calls.length).toBeGreaterThan(0); + + // it keeps retrying while getUser returns null + await jest.advanceTimersByTimeAsync(60 * 1000); + const whileRunning = fetchMock.mock.calls.length; + expect(whileRunning).toBeGreaterThan(1); + + await jest.advanceTimersByTimeAsync(5 * 60 * 1000); + await rejected; + + const afterGivingUp = fetchMock.mock.calls.length; + // without the teardown the one-minute retry keeps rescheduling itself for the life of the + // page, against a route capped at 2 req/s + await jest.advanceTimersByTimeAsync(10 * 60 * 1000); + expect(fetchMock.mock.calls.length).toBe(afterGivingUp); + }); + + it('does not reschedule when getUser resolves after the deadline', async () => { + // the deadline can pass while a request is in flight. that resolution still runs the code + // after the await, and without a guard it schedules a fresh retry with nothing left to clear + let release: (v: Response) => void = () => undefined; + fetchMock.mockImplementation( + () => + new Promise((r) => { + release = r as (v: Response) => void; + }) + ); + + const pending = oauthSignin('/auth/github/login'); + const rejected = expect(pending).rejects.toThrow(/authorization window/); + + window.dispatchEvent(new Event('focus')); + await jest.advanceTimersByTimeAsync(0); + expect(fetchMock.mock.calls.length).toBe(1); + + await jest.advanceTimersByTimeAsync(5 * 60 * 1000); + await rejected; + + // the in-flight request now comes back unauthenticated, after the flow already gave up + release(new Response('', { status: 401 })); + await jest.advanceTimersByTimeAsync(0); + + const afterGivingUp = fetchMock.mock.calls.length; + await jest.advanceTimersByTimeAsync(10 * 60 * 1000); + expect(fetchMock.mock.calls.length).toBe(afterGivingUp); + }); + + it('detaches its listeners once it gives up', async () => { + jest.spyOn(document, 'addEventListener'); + jest.spyOn(document, 'removeEventListener'); + fetchMock.mockResponse('', { status: 401 }); + + const pending = oauthSignin('/auth/github/login'); + const rejected = expect(pending).rejects.toThrow(); + expect(listenerCount()).toBeGreaterThan(0); + + await jest.advanceTimersByTimeAsync(5 * 60 * 1000); + await rejected; + + expect(listenerCount()).toBe(0); + }); + + it('rejects with an error rather than undefined', async () => { + fetchMock.mockResponse('', { status: 401 }); + const pending = oauthSignin('/auth/github/login'); + // the caller stores whatever this rejects with as the error state, so rejecting with no + // argument puts undefined on screen + const assertion = expect(pending).rejects.toBeInstanceOf(Error); + + await jest.advanceTimersByTimeAsync(5 * 60 * 1000); + await assertion; + }); +}); diff --git a/frontend/apps/remark42/app/components/auth/auth.api.ts b/frontend/apps/remark42/app/components/auth/auth.api.ts index e53e1783..03f3f6ed 100644 --- a/frontend/apps/remark42/app/components/auth/auth.api.ts +++ b/frontend/apps/remark42/app/components/auth/auth.api.ts @@ -42,12 +42,20 @@ export function oauthSignin(url: string): Promise { return Promise.resolve(null); } + subscribed = true; + return new Promise((resolve, reject) => { + // closure-local rather than the module-level `subscribed`, because a second oauthSignin can + // start while this one's getUser is still resolving and would clear a flag it does not own + let stopped = false; + function unsubscribe() { + stopped = true; document.removeEventListener('visibilitychange', handleWindowVisibilityChange); window.removeEventListener('focus', handleWindowVisibilityChange); subscribed = false; clearTimeout(timeout); + clearTimeout(giveUp); } async function handleWindowVisibilityChange() { @@ -57,6 +65,12 @@ export function oauthSignin(url: string): Promise { const user = await getUser(); + // the request was in flight when the deadline passed, so there is nothing left to clear the + // retry this would otherwise schedule + if (stopped) { + return; + } + clearTimeout(timeout); if (user === null) { @@ -72,9 +86,15 @@ export function oauthSignin(url: string): Promise { unsubscribe(); } - setTimeout( + // giving up has to tear the subscription down as well. the retry above reschedules itself + // for as long as getUser keeps returning null, which is the permanent state whenever the + // widget is embedded cross-domain and the cookie never becomes readable, so leaving the + // listeners attached leaves a poll of /auth/user running for the life of the page against + // a route limited to 2 req/s + const giveUp = setTimeout( () => { - reject(); + unsubscribe(); + reject(new Error('Timed out waiting for the authorization window')); }, 5 * 60 * 1000 ); diff --git a/frontend/apps/remark42/app/components/dropdown/dropdown.tsx b/frontend/apps/remark42/app/components/dropdown/dropdown.tsx index 1ca37537..f4a000cd 100644 --- a/frontend/apps/remark42/app/components/dropdown/dropdown.tsx +++ b/frontend/apps/remark42/app/components/dropdown/dropdown.tsx @@ -5,7 +5,7 @@ import clsx from 'clsx'; import type { Theme } from 'common/types'; import { sleep } from 'utils/sleep'; import { Button } from 'components/button'; -import { parseMessage } from 'utils/post-message'; +import { parseMessage, isFromParent } from 'utils/post-message'; import styles from './dropdown.module.css'; @@ -136,6 +136,10 @@ export class Dropdown extends Component { } receiveMessage(evt: MessageEvent) { + if (!isFromParent(evt)) { + return; + } + const data = parseMessage(evt); if (!data.clickOutside || !this.state.isActive) { diff --git a/frontend/apps/remark42/app/components/root/root.tsx b/frontend/apps/remark42/app/components/root/root.tsx index bab2bd83..43b88af8 100644 --- a/frontend/apps/remark42/app/components/root/root.tsx +++ b/frontend/apps/remark42/app/components/root/root.tsx @@ -34,7 +34,7 @@ import { ConnectedComment as Comment } from 'components/comment/connected-commen import { uploadImage, getPreview } from 'common/api'; import { isUserAnonymous } from 'utils/isUserAnonymous'; import { bindActions } from 'utils/actionBinder'; -import { postMessageToParent, parseMessage, updateIframeHeight } from 'utils/post-message'; +import { postMessageToParent, parseMessage, isFromParent, updateIframeHeight } from 'utils/post-message'; import { useActions } from 'hooks/useAction'; import { setCollapse } from 'store/thread/actions'; @@ -185,6 +185,10 @@ export class Root extends Component { }; onMessage = (event: MessageEvent) => { + if (!isFromParent(event)) { + return; + } + const data = parseMessage(event); if (data.signout === true) { diff --git a/frontend/apps/remark42/app/embed.test.ts b/frontend/apps/remark42/app/embed.test.ts index d7375d11..ff73e6d3 100644 --- a/frontend/apps/remark42/app/embed.test.ts +++ b/frontend/apps/remark42/app/embed.test.ts @@ -50,4 +50,82 @@ describe('embed', () => { expect(root.querySelectorAll('iframe')).toHaveLength(1); expect(root.querySelector(MARKED)).toBe(first); }); + + it('does not stack listeners when createInstance is called again', async () => { + const root = await mount(); + const iframe = root.querySelector(MARKED)!; + + // the second call reuses the iframe rather than building one, so without a teardown the first + // call's handlers stay attached and both react to every message + window.REMARK42.createInstance(window.remark_config); + window.REMARK42.createInstance(window.remark_config); + + let resizes = 0; + Object.defineProperty(iframe.style, 'height', { + set() { + resizes += 1; + }, + get: () => '', + configurable: true, + }); + + window.dispatchEvent(new MessageEvent('message', { data: { height: 500 }, source: iframe.contentWindow })); + + expect(resizes).toBe(1); + }); + + it('detaches every listener on destroy, however many instances were created', async () => { + const root = await mount(); + const iframe = root.querySelector(MARKED)!; + + window.REMARK42.createInstance(window.remark_config); + window.REMARK42.destroy!(); + + let resized = false; + Object.defineProperty(iframe.style, 'height', { + set() { + resized = true; + }, + get: () => '', + configurable: true, + }); + + window.dispatchEvent(new MessageEvent('message', { data: { height: 500 }, source: iframe.contentWindow })); + + expect(resized).toBe(false); + }); + + it('resizes for its own iframe', async () => { + const root = await mount(); + const iframe = root.querySelector(MARKED)!; + + window.dispatchEvent(new MessageEvent('message', { data: { height: 500 }, source: iframe.contentWindow })); + + expect(iframe.style.height).toBe('500px'); + }); + + it('ignores a message from a frame it does not own', async () => { + const root = await mount(); + const iframe = root.querySelector(MARKED)!; + iframe.style.height = '100px'; + + // every frame on a page can reach window.parent, an advertisement among them, and the handler + // resizes the widget, scrolls the page and opens the profile overlay + const foreign = document.createElement('iframe'); + document.body.appendChild(foreign); + const scrollTo = jest.spyOn(window, 'scrollTo').mockImplementation(() => undefined); + + window.dispatchEvent( + new MessageEvent('message', { + data: { height: 9000, scrollTo: 5000, profile: { id: 'anyone' } }, + source: foreign.contentWindow, + }) + ); + + expect(iframe.style.height).toBe('100px'); + expect(scrollTo).not.toHaveBeenCalled(); + expect(document.querySelectorAll('iframe')).toHaveLength(2); + + scrollTo.mockRestore(); + }); }); diff --git a/frontend/apps/remark42/app/embed.ts b/frontend/apps/remark42/app/embed.ts index 3fa5f8b5..3d229d0d 100644 --- a/frontend/apps/remark42/app/embed.ts +++ b/frontend/apps/remark42/app/embed.ts @@ -2,12 +2,18 @@ import { NODE_ID, COMMENT_NODE_CLASSNAME_PREFIX } from 'common/constants.config' import { parseMessage, postMessageToIframe } from 'utils/post-message'; import { createIframe } from 'utils/create-iframe'; import type { Theme } from 'common/types'; -import { closeProfile, openProfile } from 'profile'; +import { closeProfile, openProfile, ownsWindow } from 'profile'; // marks the iframe this module owns, so a second createInstance reuses it instead of adopting // whatever the integrator left in the root as a loading placeholder const IFRAME_MARKER = 'data-remark42-iframe'; +// detaches the listeners of whichever instance is current. every createInstance installs three of +// them plus a title observer, all closing over that call's iframe, while the call reuses an +// existing iframe rather than building one. Without this a second call leaves the first set +// attached for good, since destroy() can only reach the newest closure +let detachCurrentInstance: (() => void) | null = null; + if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); } else { @@ -45,6 +51,10 @@ function createInstance(config: typeof window.remark_config) { root.appendChild(iframe); + // after the throwing validation above, so a rejected call leaves a working instance alone + detachCurrentInstance?.(); + detachCurrentInstance = detach; + window.addEventListener('message', handleReceiveMessage); window.addEventListener('hashchange', handleHashChange); document.addEventListener('click', postClickOutsideToIframe); @@ -61,6 +71,13 @@ function createInstance(config: typeof window.remark_config) { } function handleReceiveMessage(event: MessageEvent): void { + // only the frames this module created. window.parent is reachable by every frame on the page, + // an advertisement among them, and the handler below resizes the widget, scrolls the page and + // opens the profile overlay, so an unchecked sender can drive all three + if (event.source !== iframe.contentWindow && !ownsWindow(event.source)) { + return; + } + const data = parseMessage(event); if (typeof data.height === 'number') { @@ -125,7 +142,7 @@ function createInstance(config: typeof window.remark_config) { postMessageToIframe(iframe, { theme }); } - function destroy() { + function detach() { window.removeEventListener('message', handleReceiveMessage); window.removeEventListener('hashchange', handleHashChange); document.removeEventListener('click', postClickOutsideToIframe); @@ -136,6 +153,15 @@ function createInstance(config: typeof window.remark_config) { // to prevent attempts to send messages to detached frame titleObserver = null; } + } + + function destroy() { + detach(); + + // a later createInstance must not detach an instance that is already gone + if (detachCurrentInstance === detach) { + detachCurrentInstance = null; + } iframe.remove(); } diff --git a/frontend/apps/remark42/app/profile.ts b/frontend/apps/remark42/app/profile.ts index 3a96d104..1e251490 100644 --- a/frontend/apps/remark42/app/profile.ts +++ b/frontend/apps/remark42/app/profile.ts @@ -87,6 +87,13 @@ export function openProfile(params: Profile & Record) window.addEventListener('keydown', handleKeydown); } +// ownsWindow reports whether the message came from the profile frame this module created. The +// host page's listener has no other way to tell it apart: any frame on the page can post to the +// parent, and nothing about the message itself says where it came from +export function ownsWindow(source: MessageEventSource | null): boolean { + return source !== null && iframe !== null && source === iframe.contentWindow; +} + export function closeProfile() { window.removeEventListener('keydown', handleKeydown); animateDisappear().then(() => { diff --git a/frontend/apps/remark42/app/remark.tsx b/frontend/apps/remark42/app/remark.tsx index 3d4128d2..fbb7c025 100644 --- a/frontend/apps/remark42/app/remark.tsx +++ b/frontend/apps/remark42/app/remark.tsx @@ -4,7 +4,7 @@ import { Provider } from 'store/context'; import { IntlProvider } from 'common/intl'; import { loadLocale } from 'utils/loadLocale'; -import { parseMessage } from 'utils/post-message'; +import { parseMessage, isFromParent } from 'utils/post-message'; import { ConnectedRoot } from 'components/root'; import { Profile } from 'components/profile'; import { store } from 'store'; @@ -36,6 +36,10 @@ async function init(): Promise { node.innerHTML = ''; window.addEventListener('message', (evt) => { + if (!isFromParent(evt)) { + return; + } + const data = parseMessage(evt); if (data.theme === 'light') { diff --git a/frontend/apps/remark42/app/utils/post-message.test.ts b/frontend/apps/remark42/app/utils/post-message.test.ts new file mode 100644 index 00000000..c4029fbc --- /dev/null +++ b/frontend/apps/remark42/app/utils/post-message.test.ts @@ -0,0 +1,26 @@ +import { isFromParent } from './post-message'; + +/** + * The widget document acts on `signout` and `theme` straight out of a message, so the sender has to + * be the page embedding it. The origin cannot stand in for that check: the host is whatever site + * embeds the widget, and `ALLOWED_HOSTS` is enforced server side through `frame-ancestors`. + */ +describe('isFromParent', () => { + it('accepts the embedding page', () => { + expect(isFromParent(new MessageEvent('message', { source: window.parent }))).toBe(true); + }); + + it('rejects another frame on the page', () => { + const foreign = document.createElement('iframe'); + document.body.appendChild(foreign); + + expect(isFromParent(new MessageEvent('message', { source: foreign.contentWindow }))).toBe(false); + + foreign.remove(); + }); + + it('rejects a message carrying no sender', () => { + // an extension posting into the frame is the common case + expect(isFromParent(new MessageEvent('message', { data: { signout: true } }))).toBe(false); + }); +}); diff --git a/frontend/apps/remark42/app/utils/post-message.ts b/frontend/apps/remark42/app/utils/post-message.ts index bee61e21..a14099f9 100644 --- a/frontend/apps/remark42/app/utils/post-message.ts +++ b/frontend/apps/remark42/app/utils/post-message.ts @@ -49,6 +49,22 @@ export function postMessageToIframe(target: HTMLIFrameElement, data: ChildMessag return true; } +/** + * Whether a message reaching the widget document came from the page embedding it. + * + * The embed script is the only legitimate sender, and it always posts from the parent. Browser + * extensions post their own messages into the frame, and so can any window holding a reference to + * it, which matters because the child acts on `signout` and `theme`. The origin cannot be checked + * instead: the host page is whatever site embeds the widget, so there is no fixed value to compare + * against, and `ALLOWED_HOSTS` is enforced server side through `frame-ancestors` rather than here. + * + * A widget opened directly rather than embedded has `window.parent === window`, so its own messages + * still pass, which is what the counter and last-comments pages rely on. + */ +export function isFromParent(evt: MessageEvent): boolean { + return evt.source === window.parent; +} + /** * Parses data from post message that was received in iframe * diff --git a/frontend/apps/remark42/package.json b/frontend/apps/remark42/package.json index 7a3e7603..3247c4dc 100644 --- a/frontend/apps/remark42/package.json +++ b/frontend/apps/remark42/package.json @@ -19,7 +19,8 @@ "translation-check": "run-s translation:extract translation:check", "translation:extract": "formatjs extract --out-file=./extracted-messages/messages.json \"**/*.{ts,tsx}\" --ignore=\"**/*.d.ts\" --ignore=\"**/*.{test,spec}.{ts,tsx}\" --ignore=\"app/tests/**\" --ignore=\"app/__mocks__/**\" --ignore=\"app/__stubs__/**\"", "translation:generate": "node ./tasks/generateDictionary.js", - "translation:check": "node ./tasks/checkTranslation.js" + "translation:check": "node ./tasks/checkTranslation.js", + "prepare": "if [ -z \"$CI\" ]; then cd ../../.. && husky install frontend/.husky; else echo \"Skip Husky Hooks\"; fi" }, "engines": { "node": ">=24", @@ -71,12 +72,14 @@ "file-loader": "^6.2.0", "fork-ts-checker-webpack-plugin": "^9.1.0", "html-webpack-plugin": "^5.6.8", + "husky": "^8.0.1", "identity-obj-proxy": "^3.0.0", "incstr": "^1.2.3", "jest": "^30.4.2", "jest-environment-jsdom": "^30.4.1", "jest-fetch-mock": "^4.2.0", "jest-localstorage-mock": "^2.4.26", + "lint-staged": "^13.0.3", "mini-css-extract-plugin": "^2.10.2", "npm-run-all": "^4.1.5", "postcss": "^8.5.26", @@ -97,5 +100,77 @@ "webpack-bundle-analyzer": "^5.3.1", "webpack-cli": "^7.2.2", "webpack-dev-server": "^5.2.5" + }, + "pnpm": { + "overrides": { + "decode-uri-component@<0.2.1": ">=0.2.1", + "loader-utils@>=2.0.0 <2.0.3": ">=2.0.3 <3.0.0", + "loader-utils@>=2.0.0 <2.0.4": ">=2.0.4 <3.0.0", + "json5@<1.0.2": ">=1.0.2", + "json5@>=2.0.0 <2.2.2": ">=2.2.2", + "tough-cookie@<4.1.3": ">=4.1.3", + "micromatch@<4.0.8": ">=4.0.8", + "esbuild@<=0.24.2": ">=0.25.0", + "word-wrap@<1.2.4": ">=1.2.4", + "cookie@<0.7.0": ">=0.7.0", + "@babel/runtime-corejs3@<7.26.10": ">=7.26.10 <8.0.0", + "@babel/runtime@<7.26.10": ">=7.26.10 <8.0.0", + "@babel/helpers@<7.26.10": ">=7.26.10 <8.0.0", + "cross-spawn@<6.0.6": ">=6.0.6", + "cross-spawn@>=7.0.0 <7.0.5": ">=7.0.5", + "tmp@<=0.2.3": ">=0.2.4", + "form-data@>=4.0.0 <4.0.4": ">=4.0.4", + "nanoid@>=4.0.0 <5.0.9": ">=5.0.9", + "glob@>=10.2.0 <10.5.0": ">=10.5.0 <11.0.0", + "diff@>=4.0.0 <4.0.4": ">=4.0.4", + "semver@>=2.0.0-alpha <5.7.2": ">=5.7.2", + "semver@>=7.0.0 <7.5.2": ">=7.5.2", + "semver@>=6.0.0 <6.3.1": ">=6.3.1", + "serialize-javascript@<=7.0.2": ">=7.0.3", + "flatted@<3.4.0": ">=3.4.0", + "flatted@<=3.4.1": ">=3.4.2", + "lodash-es@>=4.0.0 <=4.17.23": ">=4.18.0", + "lodash@>=4.0.0 <=4.17.23": ">=4.18.0", + "lodash-es@<=4.17.23": ">=4.18.0", + "lodash@<=4.17.23": ">=4.18.0", + "serialize-javascript@>=6.0.0 <6.0.2": ">=6.0.2", + "@xmldom/xmldom@<0.8.12": ">=0.8.12", + "@babel/traverse@<7.23.2": ">=7.23.2 <8.0.0", + "@xmldom/xmldom@<0.8.13": ">=0.8.13", + "@tootallnate/once@<2.0.1": ">=2.0.1", + "serialize-javascript@>=5.0.0 <7.0.5": ">=7.0.5", + "uuid@<11.1.1": ">=11.1.1", + "@babel/plugin-transform-modules-systemjs@>=7.12.0 <=7.29.3": ">=7.29.4 <8.0.0", + "lodash@>=4.0.0 <=4.17.22": ">=4.17.23", + "shell-quote@>=1.1.0 <=1.8.3": ">=1.8.4", + "tmp@<0.2.6": ">=0.2.6", + "form-data@>=4.0.0 <4.0.6": ">=4.0.6", + "launch-editor@<=2.14.0": ">=2.14.1", + "@babel/core@<=7.29.0": ">=7.29.6 <8.0.0", + "webpack-dev-server@<5.2.6": ">=5.2.6 <6.0.0", + "http-proxy-middleware@>=0.16.0 <2.0.10": ">=2.0.10 <3.0.0", + "yaml@>=1.0.0 <2.0.0": ">=1.10.3 <2.0.0", + "yaml@>=2.0.0 <3.0.0": ">=2.9.0 <3.0.0", + "js-yaml@>=3.0.0 <4.0.0": ">=3.15.1 <4.0.0", + "js-yaml@>=4.0.0 <5.0.0": ">=5.2.2 <6.0.0", + "minimatch@>=3.0.0 <4.0.0": ">=3.1.3 <4.0.0", + "minimatch@>=9.0.0 <10.0.0": ">=9.0.7 <10.0.0", + "ajv@>=8.0.0 <9.0.0": ">=8.18.0 <9.0.0", + "ws@>=7.0.0 <8.0.0": ">=7.5.11 <8.0.0", + "ws@>=8.0.0 <9.0.0": ">=8.21.0 <9.0.0", + "brace-expansion@>=1.0.0 <2.0.0": ">=1.1.18 <2.0.0", + "brace-expansion@>=2.0.0 <3.0.0": ">=2.0.2 <3.0.0", + "brace-expansion@>=4.0.0 <6.0.0": ">=5.0.9 <6.0.0", + "fast-uri": ">=4.1.2 <5.0.0", + "nanoid@>=3.0.0 <4.0.0": ">=3.3.18 <4.0.0", + "postcss@<8.5.23": ">=8.5.23 <9.0.0", + "svgo": ">=4.0.2 <5.0.0", + "undici@>=7.0.0 <8.0.0": ">=7.29.0 <8.0.0", + "body-parser@<1.20.6": ">=1.20.6 <2.0.0", + "preact": "10.29.8", + "@types/minimatch": "5.1.2", + "@babel/core": "^8.0.1", + "eslint-config-preact>@babel/core": "^7.29.7" + } } } diff --git a/frontend/pnpm-lock.yaml b/frontend/apps/remark42/pnpm-lock.yaml similarity index 86% rename from frontend/pnpm-lock.yaml rename to frontend/apps/remark42/pnpm-lock.yaml index 8908f4a2..a28ddbc1 100644 --- a/frontend/pnpm-lock.yaml +++ b/frontend/apps/remark42/pnpm-lock.yaml @@ -77,15 +77,6 @@ overrides: importers: .: - devDependencies: - husky: - specifier: ^8.0.1 - version: 8.0.3 - lint-staged: - specifier: ^13.0.3 - version: 13.3.0 - - apps/remark42: dependencies: '@github/markdown-toolbar-element': specifier: ^2.2.3 @@ -135,7 +126,7 @@ importers: version: 13.0.3(size-limit@13.0.3) '@testing-library/jest-dom': specifier: ^7.0.1 - version: 7.0.1(@testing-library/dom@8.20.1)(vitest@4.1.9) + version: 7.0.1(@testing-library/dom@8.20.1) '@testing-library/preact': specifier: 3.2.4 version: 3.2.4(preact@10.29.8) @@ -204,7 +195,7 @@ importers: version: 6.10.2(eslint@9.39.5(jiti@2.7.0)) eslint-plugin-prettier: specifier: ^5.5.6 - version: 5.5.6(@types/eslint@8.56.12)(eslint-config-prettier@10.1.8(eslint@9.39.5(jiti@2.7.0)))(eslint@9.39.5(jiti@2.7.0))(prettier@3.9.6) + version: 5.5.6(eslint-config-prettier@10.1.8(eslint@9.39.5(jiti@2.7.0)))(eslint@9.39.5(jiti@2.7.0))(prettier@3.9.6) file-loader: specifier: ^6.2.0 version: 6.2.0(webpack@5.109.2) @@ -214,6 +205,9 @@ importers: html-webpack-plugin: specifier: ^5.6.8 version: 5.6.8(webpack@5.109.2) + husky: + specifier: ^8.0.1 + version: 8.0.3 identity-obj-proxy: specifier: ^3.0.0 version: 3.0.0 @@ -222,7 +216,7 @@ importers: version: 1.2.3 jest: specifier: ^30.4.2 - version: 30.4.2(@types/node@26.2.0)(ts-node@10.9.2(@swc/core@1.16.1)(@types/node@26.2.0)(typescript@5.9.3)) + version: 30.4.2(@types/node@26.2.0) jest-environment-jsdom: specifier: ^30.4.1 version: 30.4.1 @@ -232,6 +226,9 @@ importers: jest-localstorage-mock: specifier: ^2.4.26 version: 2.4.26 + lint-staged: + specifier: ^13.0.3 + version: 13.3.0 mini-css-extract-plugin: specifier: ^2.10.2 version: 2.10.2(webpack@5.109.2) @@ -282,7 +279,7 @@ importers: version: 5.9.3 webpack: specifier: ^5.109.2 - version: 5.109.2(@swc/core@1.16.1)(postcss@8.5.26)(webpack-cli@7.2.2) + version: 5.109.2(postcss@8.5.26)(webpack-cli@7.2.2) webpack-bundle-analyzer: specifier: ^5.3.1 version: 5.3.1 @@ -291,7 +288,7 @@ importers: version: 7.2.2(js-yaml@5.3.0)(json5@2.2.3)(webpack-bundle-analyzer@5.3.1)(webpack-dev-server@5.2.6)(webpack@5.109.2) webpack-dev-server: specifier: '>=5.2.6 <6.0.0' - version: 5.2.6(tslib@2.8.1)(webpack-cli@7.2.2)(webpack@5.109.2) + version: 5.2.6(webpack-cli@7.2.2)(webpack@5.109.2) packages: @@ -332,10 +329,6 @@ packages: '@babel/core': ^8.0.1 eslint: ^7.5.0 || ^8.0.0 || ^9.0.0 - '@babel/generator@7.29.7': - resolution: {integrity: sha512-DkXD5OJQaAQIdZ1bt3UZdEnHAn9Imd3IVBdX03UFe+ony9Ojw5pzr9YVKGDY1jt+Gcn/FnGkNf8r+Vj5NOJWtQ==} - engines: {node: '>=6.9.0'} - '@babel/generator@7.29.8': resolution: {integrity: sha512-gZbepsdh3WDtgZKWL+vTPh71LSBrm/Y4/QDZBVCcYfmeTEEuoOYwlSy+G1StfJg+/Zy550u/3TATbm7qDbbMtg==} engines: {node: '>=6.9.0'} @@ -472,11 +465,6 @@ packages: resolution: {integrity: sha512-wfbi91pM3py96oIiJEz7qIpyXDytgr9zQC1HEWwlGNVRAEmItuU/0a41ZUKu1sJGyhhOIpc4t5vk4PYzt8wpsg==} engines: {node: ^22.18.0 || >=24.11.0} - '@babel/parser@7.29.7': - resolution: {integrity: sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg==} - engines: {node: '>=6.0.0'} - hasBin: true - '@babel/parser@7.29.8': resolution: {integrity: sha512-E8lTAYNB1KW+FH+VGJuZM1ioAx2E6oVlvQFRrf5P8ZZmsiJXYAD9vTFV7yyEURNzgh1dFqMZuO6tUwcARbqFCA==} engines: {node: '>=6.0.0'} @@ -1005,10 +993,6 @@ packages: resolution: {integrity: sha512-bZnmqzGG8UZneG1lLxBoWIH0G6Gr1D846Yu4/3XnY6FhCndMR49u26nTY08u/dAxWmLWF9vGQOuC+84FfIUoeg==} engines: {node: ^22.18.0 || >=24.11.0} - '@babel/types@7.29.7': - resolution: {integrity: sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==} - engines: {node: '>=6.9.0'} - '@babel/types@7.29.8': resolution: {integrity: sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==} engines: {node: '>=6.9.0'} @@ -1020,22 +1004,14 @@ packages: '@bcoe/v8-coverage@0.2.3': resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} - '@bcoe/v8-coverage@1.0.2': - resolution: {integrity: sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==} - engines: {node: '>=18'} - '@cacheable/memory@2.2.0': resolution: {integrity: sha512-CTLKqLItRCEixEAewD3/j9DB3/o96gpTPD4eJ1v+DGOlxZRZncRQkGYqqnAGCscYd6RNeXfGeiuCphsPtqyIfQ==} '@cacheable/utils@2.5.0': resolution: {integrity: sha512-buipgOVDkkPXNR5+xBpDw7Zk2n1EvU7qBJCNUcL7rhQ//kfpOXPAvQ511Os0vpLYJ1pZnvudNytkQt2hst3wqA==} - '@colordx/core@5.5.0': - resolution: {integrity: sha512-3PxTH8itZzltK0U9jTwVVnjLXvnDYuq3m+QXsHkENxWiPRh4WaoLcs1SQjqgZ55kS+QyirpH5BVwzP2gMVG6EQ==} - - '@cspotcode/source-map-support@0.8.1': - resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} - engines: {node: '>=12'} + '@colordx/core@5.6.0': + resolution: {integrity: sha512-EDlcg/Hmlj1WuFh/Os9YhA+A2aasB2XlgwFfGePUDuW7fVHC07HBi5AFIMx0Ct1eM8kHM9NRyOtZ0MuVYa8xvg==} '@csstools/color-helpers@5.1.0': resolution: {integrity: sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA==} @@ -1048,8 +1024,8 @@ packages: '@csstools/css-parser-algorithms': ^3.0.5 '@csstools/css-tokenizer': ^3.0.4 - '@csstools/css-calc@3.2.1': - resolution: {integrity: sha512-DtdHlgXh5ZkA43cwBcAm+huzgJiwx3ZTWVjBs94kwz2xKqSimDA3lBgCjphYgwgVUMWatSM0pDd8TILB1yrVVg==} + '@csstools/css-calc@3.3.0': + resolution: {integrity: sha512-c5ihYsPkdG6JCkU2zTMm4+k6r7RXuGxtWYhu5DHMIiF1FHzrfmHL5so11AoFpUv/tu61xfcmT4AmKoFfMPoqdQ==} engines: {node: '>=20.19.0'} peerDependencies: '@csstools/css-parser-algorithms': ^4.0.0 @@ -1074,8 +1050,8 @@ packages: peerDependencies: '@csstools/css-tokenizer': ^4.0.0 - '@csstools/css-syntax-patches-for-csstree@1.1.6': - resolution: {integrity: sha512-TcJCWFbXLPpJYq6z7bfOyjWYJDiDg2/I4gyUC9pqPNqHFRIey0EB0q0L5cSnQDfWJg8Jd6VadakxdIez/3zkqQ==} + '@csstools/css-syntax-patches-for-csstree@1.1.8': + resolution: {integrity: sha512-CpMLjAvwQg3BL5S0IeqsZNMH7EQrEWi0kLKOC13ZBF0ZwERiLWlibNPJr8G1kdU3Ms/r2KiNrF81pUh2HwAHdg==} peerDependencies: css-tree: ^3.2.1 peerDependenciesMeta: @@ -1210,26 +1186,17 @@ packages: '@emnapi/core@1.10.0': resolution: {integrity: sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==} - '@emnapi/core@1.11.1': - resolution: {integrity: sha512-RSvbQmHzdKzNsLYa/wHrbc3KN4sYLKAdPZxqiM2HATqv/SBk2/ENSHpvXGaLOMcsAyz0poEGqkmmKYG3OWiJEQ==} - '@emnapi/runtime@1.10.0': resolution: {integrity: sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==} - '@emnapi/runtime@1.11.1': - resolution: {integrity: sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw==} - '@emnapi/wasi-threads@1.2.1': resolution: {integrity: sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==} - '@emnapi/wasi-threads@1.2.2': - resolution: {integrity: sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA==} - '@epic-web/invariant@1.0.0': resolution: {integrity: sha512-lrTPqgvfFQtR/eY/qkIzp98OGdNJu0m5ji3q/nJI8v3SXkRKEnWiOxMmbvcSoAIzv/cGiuvRy57k4suKQSAdwA==} - '@eslint-community/eslint-utils@4.9.1': - resolution: {integrity: sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==} + '@eslint-community/eslint-utils@4.10.1': + resolution: {integrity: sha512-cuadcxVFE8sDK6iWJbs8Sn0av2Nrh2QSGQhVlBW9AaAHqHwjWsZHT8LJ4hFGPh7ASBV2deFdM7H/DPjulmh8rg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 @@ -1305,41 +1272,6 @@ packages: resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} engines: {node: '>=18.18'} - '@inquirer/ansi@2.0.7': - resolution: {integrity: sha512-3eTuUO1vH2cZm2ZKHeQxnOqlTi9EfZDGgIe3BL3I4u+rJHocr9Fz86M4fjYABPvFnQG/gGK551HqDiIcETwU6Q==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} - - '@inquirer/confirm@6.1.1': - resolution: {integrity: sha512-eb8DBZcz/2qHWQda4rk2JiQk5h9QV/cVHi1yjt0f69WFZMRFn0sJTye3EAP8icut8UDMjQPsaH5KbcOogefrFQ==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - - '@inquirer/core@11.2.1': - resolution: {integrity: sha512-Qd6GJT1yVyrZZCfN8W2qKF5ApmqryXRhRKCuip8h01x2w/esJQ2XIYc6f9abMIHgKQdBfFTSOdbHRLAhuM09UA==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - - '@inquirer/figures@2.0.7': - resolution: {integrity: sha512-aJ8TBPOGB6f/2qziPfElISTCEd5XOYTFckA2SGjhNmiKzfK/u4ot3v0DUzGVdUnKjN10EqnnEPck36BkyfLnJw==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} - - '@inquirer/type@4.0.7': - resolution: {integrity: sha512-t28inv14nMQ1PhKpsJPY+kEs/c00qzeCOS2gTNRyTjG5d6qsVA2fItxW4hkvGZ5lvanGLdtCzVIx5dwdRpN1+g==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - '@isaacs/cliui@8.0.2': resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} @@ -1463,9 +1395,6 @@ packages: '@jridgewell/trace-mapping@0.3.31': resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} - '@jridgewell/trace-mapping@0.3.9': - resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} - '@jsonjoy.com/base64@1.1.2': resolution: {integrity: sha512-q6XAnWQDIMA3+FTiOYajoYqySkO+JSat0ytXGSuRdq9uXE7o92gzuQwQM14xaCRlBLGq3v5miDGC4vkVTn54xA==} engines: {node: '>=10.0'} @@ -1502,50 +1431,50 @@ packages: peerDependencies: tslib: '2' - '@jsonjoy.com/fs-core@4.57.8': - resolution: {integrity: sha512-YzVbwggV9452VCeHgo0bjsTaUt1O7JE0XpEsPar93nn/+RAwXk0mb1Y+f5EDJ3TRtRCFe+Ck5RuojdfB4jeHVw==} + '@jsonjoy.com/fs-core@4.68.1': + resolution: {integrity: sha512-V5oZ4Gt9WJKyQef0n9cAd0N9qjSkIBm3E4MYsgNIWBk5aINCDPKxMPo1i29rBxqiT4Ixf1epklqV9VJMKIxwlw==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' - '@jsonjoy.com/fs-fsa@4.57.8': - resolution: {integrity: sha512-vmClyvCQMxgqz7uamDiGtRfp4MjzOznk3pcQjCxlIwJcw7TWeyr+bF30hI0x8NxdtNOGMg1pHM74VDIXOeyjuw==} + '@jsonjoy.com/fs-fsa@4.68.1': + resolution: {integrity: sha512-HCG72UioncuO7Gw09XNVG+S85e3cq2hrUC/mexBrsWsa3mI7eePkkqWie3uVYbtsb64OR9YGQs5SqaufDRYBcg==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' - '@jsonjoy.com/fs-node-builtins@4.57.8': - resolution: {integrity: sha512-mxXSXw8zZwRVakcjLqR2I/psy4gURFSASZS10kKJ2kJw05GC2nXGroGrWVHxwgkxXgQLsFQnB74QaLzsxzdL/w==} + '@jsonjoy.com/fs-node-builtins@4.68.1': + resolution: {integrity: sha512-HK1BTksysokNZxNspqDH0yPaqN9YgR/AYIlYiIaU2Ys4BOk5CdybI7r6BgiZuiiPiV8n4sK/kZdice7Znpy2Kw==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' - '@jsonjoy.com/fs-node-to-fsa@4.57.8': - resolution: {integrity: sha512-AWZcT/4+H+iDl4XCukbXrarvwEgOrf/prFI5/7eg4ix9FxqVsZysIDJd1Kjd+AjlCeHKHJOaRqjLd5HiGSCJEw==} + '@jsonjoy.com/fs-node-to-fsa@4.68.1': + resolution: {integrity: sha512-lpKmU4X9e/oh8GIuAI7EXaS5QiLNM3KD15CkdhfS6PYmrGvoJqKQcyEfnLgnnaGslh/PFUMYSIZBCf2ejJGw8g==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' - '@jsonjoy.com/fs-node-utils@4.57.8': - resolution: {integrity: sha512-E/bJ7sQAb4pu9nbeJhbULU3WnqWrswte4N9Js/oHt7aHB746S8/XBqKlcbrqIgnD3095XluovNEZuu5ONT230g==} + '@jsonjoy.com/fs-node-utils@4.68.1': + resolution: {integrity: sha512-/GxfW1DWm9SCdkfbvqevLO/P5duobQfmKkHXxdMIDbcZMQeAgooAstIfZhkXpATzq9QbCQsnoWFM/dGHdZfndw==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' - '@jsonjoy.com/fs-node@4.57.8': - resolution: {integrity: sha512-IPEOlDYSnTDYpjQlQg2F8h+eqxKQN3sdbroI0WrteRiQZ462HzVpBo9ZZX485njz4nAacoe3fd4iDiIhk+k5Hg==} + '@jsonjoy.com/fs-node@4.68.1': + resolution: {integrity: sha512-R5D9mWtqdURzcOWj1vdXr3APCwX0xchtFT+kmW7fXLNDifWdDrnh26jSID8pdnUfFBxTyfHtFtTL/NWKzIH7kQ==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' - '@jsonjoy.com/fs-print@4.57.8': - resolution: {integrity: sha512-DfzhOBpmvNu5P/KSe4NNQaOnvNliTdcf0qrh/4EReErF/XUQXYkd0vZl/OiJCm/qjEEo8DWRstliw2/JNS84dA==} + '@jsonjoy.com/fs-print@4.68.1': + resolution: {integrity: sha512-oGeZOGPYKK9v1CgeVeEDsLomH1lCnslSpqUN5GmPzrmAVGQlsmsdcXNA2O4lV8Y4xkuSuynx2ITBkUHJVaTbow==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' - '@jsonjoy.com/fs-snapshot@4.57.8': - resolution: {integrity: sha512-L+eqKaWOHLDaiMv1dh/EWQ4hA+o6xAhWSumTo3Teg7OM18jU/KE13/e8Mfal+eAZ/pSl4wIhKHcDiwapJzC8Wg==} + '@jsonjoy.com/fs-snapshot@4.68.1': + resolution: {integrity: sha512-XZfP0FDZN32bbc4t2bZN2qRrYHg5AktJnzk22HRoKGK4BprrbNRH2k5ceSNS/kupKYcofCs+O841+xaAbjnxwQ==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' @@ -1604,15 +1533,12 @@ packages: '@mdn/browser-compat-data@6.1.5': resolution: {integrity: sha512-PzdZZzRhcXvKB0begee28n5lvwAcinGKYuLZOVxHAZm+n7y01ddEGfdS1ZXRuVcV+ndG6mSEAE8vgudom5UjYg==} - '@mswjs/interceptors@0.41.9': - resolution: {integrity: sha512-VVPPgHyQ6ShqnrmDWuxjmUIsO9gWyOZFmuOfLd9LfBGQJwZfy0gvv9pbHSJuoFNIYC7ZDX9aoFwowjcdSC4E8w==} - engines: {node: '>=18'} - - '@napi-rs/wasm-runtime@1.1.6': - resolution: {integrity: sha512-ZLv/JdUfkvOy9eCnnBaGfiO+XimbjebAeO+MRQqD/B+FR1tnRN0tpKSJHRbE8sFfS6aqsXZ67TQjfwfsxULVbg==} + '@napi-rs/wasm-runtime@1.2.3': + resolution: {integrity: sha512-UMduMbqO5s5zF2NkNacMT/yK5Y5QiKvWr2+50bzIIxFDwVJ2h49b+oyjaCGPhJxd2/gC2x39EHv/gHVuu36x2Q==} + engines: {node: ^20.19.0 || ^22.13.0 || >=23.5.0} peerDependencies: - '@emnapi/core': ^1.7.1 - '@emnapi/runtime': ^1.7.1 + '@emnapi/core': ^1.7.1 || ^2.0.0-alpha.4 + '@emnapi/runtime': ^1.7.1 || ^2.0.0-alpha.4 '@nicolo-ribaudo/eslint-scope-5-internals@5.1.1-v1': resolution: {integrity: sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg==} @@ -1633,50 +1559,45 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} - '@open-draft/deferred-promise@2.2.0': - resolution: {integrity: sha512-CecwLWx3rhxVQF6V4bAgPS5t+So2sTbPgAzafKkVizyi7tlwpcFpdFqq+wqF2OwNBmqFuu6tOyouTuxgpMfzmA==} + '@peculiar/asn1-cms@2.9.4': + resolution: {integrity: sha512-cben7oxmQsUGZqotus7yt0srYdncOT6RNWcTQ77T2RFOXejYVYkXadrfePdRcrVpO9K95IRLKKglG2k38jKXuw==} + engines: {node: '>=14'} - '@open-draft/deferred-promise@3.0.0': - resolution: {integrity: sha512-XW375UK8/9SqUVNVa6M0yEy8+iTi4QN5VZ7aZuRFQmy76LRwI9wy5F4YIBU6T+eTe2/DNDo8tqu8RHlwLHM6RA==} + '@peculiar/asn1-csr@2.9.4': + resolution: {integrity: sha512-xd4YN4vpRjkDAQWVfZZkeu12IEND7DOpkqaHSIHxZl1uggUNa9Ju0QxY2jHvDAS9pP0zhRBytg8ifsnGo3V0jw==} + engines: {node: '>=14'} - '@open-draft/logger@0.3.0': - resolution: {integrity: sha512-X2g45fzhxH238HKO4xbSr7+wBS8Fvw6ixhTDuvLd5mqh6bJJCFAPwU9mPDxbcrRtfxv4u5IHCEH77BmxvXmmxQ==} + '@peculiar/asn1-ecc@2.9.4': + resolution: {integrity: sha512-JJXefFshRAuVAjWQo/39bkg1ywc1VaiO44S8RRC+Ykvf/u2KDmYffoDb0ZBPCR5uJy4AGKQhl8mX+Q8ShcWaXQ==} + engines: {node: '>=14'} - '@open-draft/until@2.1.0': - resolution: {integrity: sha512-U69T3ItWHvLwGg5eJ0n3I62nWuE6ilHlmz7zM0npLBRvPRd7e6NYmg54vvRtP5mZG7kZqZCFVdsTWo7BPtBujg==} + '@peculiar/asn1-pfx@2.9.4': + resolution: {integrity: sha512-khuGzHTzNzk4GDlIBEILyIs6Lce0yn0ZBdoI9v93kmNncfZRhD+AQ5ODFqdhvoE8cMJF/JMTQ8yA+t1D14kqCw==} + engines: {node: '>=14'} - '@oxc-project/types@0.137.0': - resolution: {integrity: sha512-WT+Gb24i8hmvo85AIv2oEYouEXkRlKAlT9WaCa3TfLgNCN+GhrJOGZuIlMouAh38Qe4QOx26eUOVsq70qXrywA==} + '@peculiar/asn1-pkcs8@2.9.4': + resolution: {integrity: sha512-duRdotlUx9eDZe6QrQpQKl61RbWykCHBCkKayP8V8XdEFwlKHZ8qGGDMyS6Pye7OX7nLFttTTpRkJeet78ckwQ==} + engines: {node: '>=14'} - '@peculiar/asn1-cms@2.8.0': - resolution: {integrity: sha512-NgekZOrSJFSBFLFoLfwePguAWAx7z1+f2TEsWFUMyiqqfntZ4+S/S5hzqME3q4pCA0iOsFKdwiQ35dwY24eVqA==} + '@peculiar/asn1-pkcs9@2.9.4': + resolution: {integrity: sha512-kaL4cNxBpdQE2dKlyZBqz4ygCrwffO+8wfoxTEqM1Z8RadvCeELBRzcv0dzM8aY9azHMwODO5nxU65zXmhToOQ==} + engines: {node: '>=14'} - '@peculiar/asn1-csr@2.8.0': - resolution: {integrity: sha512-akbF8+uvleHs8sejNPQxwmVFuInAg6FMNHOwMILXfP518YfFJwdR3jr6oNUPOaEJfuEhn/vkNOCIT6ASUd4mbg==} + '@peculiar/asn1-rsa@2.9.4': + resolution: {integrity: sha512-pZ96eD1PptovcWQ/GSmuNFXd/7EQJNlKfDaNCyE2rx3W0v6QFelkzquVqRSRyyDXXCYD69ZXJDzZ8GhIiQzKoA==} + engines: {node: '>=14'} - '@peculiar/asn1-ecc@2.8.0': - resolution: {integrity: sha512-ohwlk+u9Rv2NOAY1c6MfHj45ATVF8R1DUN/WCgABiRtLi2ZftlZWZX7KvpAbU8v9xPcmoILfELeEABj/rn18AQ==} + '@peculiar/asn1-schema@2.9.4': + resolution: {integrity: sha512-GjzePcT9Iw8NzeOPf73iNS9xM+TBhd/FilAfP+RQGkTMQJTVWtytN3JHJACCjf/ABNau5S7mS3g+DcuxmRgYEg==} + engines: {node: '>=14'} - '@peculiar/asn1-pfx@2.8.0': - resolution: {integrity: sha512-5yof1ytoB++RQtaFbqSUJ8pxDJtZT6vbVqZ8XoJ61ph7UjNVvfFwAilnCodqkNsAodpy13gDhoxZXw00pghnyg==} + '@peculiar/asn1-x509-attr@2.9.4': + resolution: {integrity: sha512-ehQXbpQaQYycgu8OrvigwSPTFfVRcu0ECNYCWw+yzBp02Lw5paRqzzhUpfOgO2K38+WfFZuEz/0RPtam5g0OMg==} + engines: {node: '>=14'} - '@peculiar/asn1-pkcs8@2.8.0': - resolution: {integrity: sha512-qAKXtLpBEw9LqhKpjw3ajZSXlBur+ipW+y2ivVBQAG6F6qRx94yO+1ZR4mvw+YaCfKSaOzLeYEzsPaBp4SJELA==} - - '@peculiar/asn1-pkcs9@2.8.0': - resolution: {integrity: sha512-b5nDWCnkV60+cQ141D6sVVwK9nz64R5n3zSVnklGd+ECdkW2Ol3U1a6yYFlalpSOaD557yuJB64A+q42jG7lUQ==} - - '@peculiar/asn1-rsa@2.8.0': - resolution: {integrity: sha512-zHEUlCqB2mk7x2lxDwHHJy7hWZOPdGHVlsmITWKB5/PbQo61atbu9PJ/0r9dQNMwFzbKPXZ8uK8/91eUhRznSg==} - - '@peculiar/asn1-schema@2.8.0': - resolution: {integrity: sha512-7YT0U/ze0tF2QOBbE15gKZwy5tvgGyLRiRHLzhlbOpf7BT032oBSd0haZqXn5W6l26WLlu3dyxzjM+2638/z2Q==} - - '@peculiar/asn1-x509-attr@2.8.0': - resolution: {integrity: sha512-tHjkfS/qhMnmrlB2J9NhflQlQ7In3khO3CfmVrriOlpTeErY9ZIKOso1hQ5JQiyrJ7ShvqVPk7E5fQmbclkSKA==} - - '@peculiar/asn1-x509@2.8.0': - resolution: {integrity: sha512-N0CMuhWUzsWEVq6F1q9X6+VKUnWzSW+cSVg+aPaGGwDdbFoFWTYgin5MHwXgpWd6y9COMBxnfy/Qc+Xc7F0Zwg==} + '@peculiar/asn1-x509@2.9.4': + resolution: {integrity: sha512-CxhBo/RdEbMMob7T31ZdQjGuoyRFLVwrDzTn25bihzBasRg9kRm/0IxIPvhgQtcK/9dNcO1XQL2fuPugwELL0Q==} + engines: {node: '>=14'} '@peculiar/utils@2.0.3': resolution: {integrity: sha512-+oL3HPFRIZ1St2K50lWCXiioIgSoxzz7R1J3uF6neO2yl1sgmpgY6XXJH4BdpoDkMWznQTeYF6oWNDZLCdQ4eQ==} @@ -1696,103 +1617,11 @@ packages: '@polka/url@1.0.0-next.29': resolution: {integrity: sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==} - '@rolldown/binding-android-arm64@1.1.3': - resolution: {integrity: sha512-DT6Z3PhvioeHMvxo+xHc3KtqggrI7CCTXCmC2h/5zUlp5jVitv7XEy+9q5/7v8IolhlioawpMo8Kg0EEBy7J0g==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [android] - - '@rolldown/binding-darwin-arm64@1.1.3': - resolution: {integrity: sha512-0NwgwsjM7LrsuVnXMK3koTpagBNOhloc/BNjKqZjv4V5zI5r13qx69uVhRx+o5Z0yy4Hzq+lpy7TAgUG/ocvrw==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [darwin] - - '@rolldown/binding-darwin-x64@1.1.3': - resolution: {integrity: sha512-YtiBp4disu6V560loT6PjMdiRaWmVvDNrUunAalbiFx2ggeJwxdAsgZMcoGP17uyAsTwAj5V1niksxlHnVQ1Sw==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [darwin] - - '@rolldown/binding-freebsd-x64@1.1.3': - resolution: {integrity: sha512-yD3EkEdXk2LypPxnf/kSZHirarsI8gcPzc62SukhR9VJTyvV+F9Q/GxWNuCojc7sXyuVC4DxRGhdDK4X8VSsbw==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [freebsd] - - '@rolldown/binding-linux-arm-gnueabihf@1.1.3': - resolution: {integrity: sha512-c+8vieQbsD7HNAHKIA34w0GJ9FedFFuJGD+7E6vz7Q3uqAIugL5p45fhlsj4UaAsHpcmlqugBWMhA0/j7o0sIg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm] - os: [linux] - - '@rolldown/binding-linux-arm64-gnu@1.1.3': - resolution: {integrity: sha512-50jD0uUwLvur7Zz9LHz17kaAdTPjn5wN93hEgjvmYFRZwiR7ZJYovTd5ipyWJDAnXKvZ+wgc+/Ika6dwSF5OcA==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [linux] - - '@rolldown/binding-linux-arm64-musl@1.1.3': - resolution: {integrity: sha512-BO9+oPL8K9poZJBfYPsXNtYjPE5uM3qeehT3aFcW4LITOl+iSqhp0abzjR2nWBUNjIZeKXjAEWBZ64WjNoHd6w==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [linux] - - '@rolldown/binding-linux-ppc64-gnu@1.1.3': - resolution: {integrity: sha512-f3VpLB1vQ0Eo6ecr/6cekLnvYMFF4YBFoVGkfkvPLq1bAkbAwHYQPZKoAmG6OJyTcxxoC+AvezGx/S1obNC0Mw==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [ppc64] - os: [linux] - - '@rolldown/binding-linux-s390x-gnu@1.1.3': - resolution: {integrity: sha512-AmurZ26Pqx/RI9N1gzEOCklkKXl927yjfXWUUS0O7Puh8ARM/Ob8qfrD3qnWksScdw6cSrW5PSHE9DyLu7+PtA==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [s390x] - os: [linux] - - '@rolldown/binding-linux-x64-gnu@1.1.3': - resolution: {integrity: sha512-JJpqs8bRGITDOdbkNKnlojzBabbOHrqjSvDr0IVsZObE1lBcPjxItUEY9eWIDbxaJ3cGrXPWGfGkIxFijg/URg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [linux] - - '@rolldown/binding-linux-x64-musl@1.1.3': - resolution: {integrity: sha512-rSJcdjPxzA/by/6/rYs+v+bXU7UjvnbUWz8MJb6kh6+knqB1dCrtHg0uu7C/4haqJvqdkYHQ5IGn+tCH9GLW/g==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [linux] - - '@rolldown/binding-openharmony-arm64@1.1.3': - resolution: {integrity: sha512-hQ3/PYkDJICgevvyNcVrihVeqq7k1Pp3VZ9lY+dauAYUJKO+auqApvANhvR1An9BhmqYKvW2Mu1F9u4DXSMLxQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [openharmony] - - '@rolldown/binding-wasm32-wasi@1.1.3': - resolution: {integrity: sha512-Elcv/BtML9lXrV6JuKITc/grN2kYV9gjsQpW8Jfw4ioK0TOkjBjye0nnyqQNy9STNaI20lXNaQBRrD5gSgR0Yg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [wasm32] - - '@rolldown/binding-win32-arm64-msvc@1.1.3': - resolution: {integrity: sha512-2DrEfhluH9yhiaFApmsjsjwrSYbNcY1oFTzYSP1a535jDbV98zCFanA/96TBUd0iDFcxGmw9QRExwGCXz3U+/g==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [win32] - - '@rolldown/binding-win32-x64-msvc@1.1.3': - resolution: {integrity: sha512-OL4OMk7UPXOeVGGd3qo5zJyPIljf4AFgk5QAkPPS+OoLuOOozhuaQGC18MxVTnw/06q93gShAJzlwnSCY9YtqA==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [win32] - - '@rolldown/pluginutils@1.0.1': - resolution: {integrity: sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==} - '@rtsao/scc@1.1.0': resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==} - '@sinclair/typebox@0.34.49': - resolution: {integrity: sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==} + '@sinclair/typebox@0.34.52': + resolution: {integrity: sha512-XiMQh7qqVlxZzcVD+kkGMNGMzcTrDMLWI7S4x7z1MkCkbDPrekpZXEUK0eZqZFMuHQg2a2DZOcDIh9o5v3Gonw==} '@sindresorhus/merge-streams@4.0.0': resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==} @@ -1810,96 +1639,6 @@ packages: peerDependencies: size-limit: 13.0.3 - '@standard-schema/spec@1.1.0': - resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} - - '@swc/core-darwin-arm64@1.16.1': - resolution: {integrity: sha512-zlJblJ8ncErD43lKdxjbUaUskJQf+LxiPXYcWXD8/8ZMV+7uuAT+CwjciLXpyZBd5Pq/S726bMpeeAwSeL1hhg==} - engines: {node: '>=10'} - cpu: [arm64] - os: [darwin] - - '@swc/core-darwin-x64@1.16.1': - resolution: {integrity: sha512-IN0BmPWb0YAh/17mmlWB/HDBtTw2MfuW4hulf/tQAgTQBRH17l+z499bNJLK6LizSjqs0P7V+jU38Zj+vJC1DA==} - engines: {node: '>=10'} - cpu: [x64] - os: [darwin] - - '@swc/core-linux-arm-gnueabihf@1.16.1': - resolution: {integrity: sha512-EYgrx2YOCQ2Twz2S793kqNjPkpvYVUPzzR95bIb7by+VQcyaai4lZZ2iz/tZvcFVKSNcN3/JTKwx+aBn2ZL52A==} - engines: {node: '>=10'} - cpu: [arm] - os: [linux] - - '@swc/core-linux-arm64-gnu@1.16.1': - resolution: {integrity: sha512-moyKm0YZlHdHohzm1YwgAyesqnE853rO0REMfJLFAova51wF9BNi+3ZW2PeS7Vqvn6HeJuepLpAHbBdZctxpHA==} - engines: {node: '>=10'} - cpu: [arm64] - os: [linux] - - '@swc/core-linux-arm64-musl@1.16.1': - resolution: {integrity: sha512-kKGBO9wdapiSzuf5ZzZ2fYtlu1BNSYtIIUxvH1ir/gcelTOREEHGDCLTDFx/2Knf878nU11A40z7LxwasEFxqA==} - engines: {node: '>=10'} - cpu: [arm64] - os: [linux] - - '@swc/core-linux-ppc64-gnu@1.16.1': - resolution: {integrity: sha512-nZ6qahtLxC3PM54cWOQZHxt4lTCF/3J4LIoWWzz6v7A+rLs8Dx54anYQf7mH3eIi8KlNpgKci/ie8ZSqFN8O7A==} - engines: {node: '>=10'} - cpu: [ppc64] - os: [linux] - - '@swc/core-linux-s390x-gnu@1.16.1': - resolution: {integrity: sha512-4ji5PNzhYq193Z4/4xUaSoNJza6iCkDJSzhetrbB6KOYxsr+kxtQr8ePWhMJUiMt6JUWtXaZ1PYT8FhtED+nGA==} - engines: {node: '>=10'} - cpu: [s390x] - os: [linux] - - '@swc/core-linux-x64-gnu@1.16.1': - resolution: {integrity: sha512-VJQxqrisHV+B394IgrOu8YsIIXZgffnf5tO+yc9Z/hoUpuZEvuQTjWwlnpZdpyD+0nx6LTD1/3k646JYm43yJA==} - engines: {node: '>=10'} - cpu: [x64] - os: [linux] - - '@swc/core-linux-x64-musl@1.16.1': - resolution: {integrity: sha512-r9oV1mwxxsIGcLV1IQ/tw76MW3doatKze1QFWuC+a7QqJUkhY/bKTSVk6NpKKUGm2LDsE33Va8VqSClfA7vSiQ==} - engines: {node: '>=10'} - cpu: [x64] - os: [linux] - - '@swc/core-win32-arm64-msvc@1.16.1': - resolution: {integrity: sha512-6huNRessoBLxWEqBm5zJXyCQ27TO7anvkdiuQ5MDO4CJni0nOXEqKtV9RllQ2TdyENKKsUMXVnIfW2hIXx/R5Q==} - engines: {node: '>=10'} - cpu: [arm64] - os: [win32] - - '@swc/core-win32-ia32-msvc@1.16.1': - resolution: {integrity: sha512-OVKJFUzphrGmsh+BGtcZDesx0YryV7/Yvy5XGgTqnrZfjnyfcr5uaqYQugCckdIlupc5Vs3XtDjRAj12z4ZPlw==} - engines: {node: '>=10'} - cpu: [ia32] - os: [win32] - - '@swc/core-win32-x64-msvc@1.16.1': - resolution: {integrity: sha512-Bt+VIhWYCGk4urklnkkteLUOeLv1VxigwTCeB/xC6rBZxY6IIKdDwCJf6on3E3SUGsIqmQS6QqtuJQc1VxF4Aw==} - engines: {node: '>=10'} - cpu: [x64] - os: [win32] - - '@swc/core@1.16.1': - resolution: {integrity: sha512-nUaeu91O5QZKrQdaDCHd402ogUIoNOOjpkZNq0UomWK0G6gDaGmLhvddF1/3BXf5O8aLyo6ZPY/aMDWvaJQ/hg==} - engines: {node: '>=10'} - peerDependencies: - '@swc/helpers': '>=0.5.17' - peerDependenciesMeta: - '@swc/helpers': - optional: true - - '@swc/counter@0.1.3': - resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} - - '@swc/types@0.1.28': - resolution: {integrity: sha512-V6Mnml8v09QALx6K0elJ7o9K/MkVDtW3t6L+7Ou/JcWtb3xwId2AH4FeOceySd2JaO87IMw4+6vSZxLm34LPbw==} - '@testing-library/dom@8.20.1': resolution: {integrity: sha512-/DiOQ5xBxgdYRC8LNk7U+RWat0S3qRLeIw3ZIkMQ9kkVlRmwD/Eg8k8CqIpD6GW7u20JIUOfMKbxtiLutpjQ4g==} engines: {node: '>=12'} @@ -1920,18 +1659,6 @@ packages: peerDependencies: preact: 10.29.8 - '@tsconfig/node10@1.0.12': - resolution: {integrity: sha512-UCYBaeFvM11aU2y3YPZ//O5Rhj+xKyzy7mvcIoAjASbigy8mHMryP5cK7dgjlz2hWxh1g5pLw084E0a/wlUSFQ==} - - '@tsconfig/node12@1.0.11': - resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} - - '@tsconfig/node14@1.0.3': - resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} - - '@tsconfig/node16@1.0.4': - resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} - '@tybys/wasm-util@0.10.3': resolution: {integrity: sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg==} @@ -1956,36 +1683,21 @@ packages: '@types/bonjour@3.5.13': resolution: {integrity: sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==} - '@types/chai@5.2.3': - resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==} - '@types/connect-history-api-fallback@1.5.4': resolution: {integrity: sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==} '@types/connect@3.4.38': resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} - '@types/deep-eql@4.0.2': - resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} - - '@types/eslint@8.56.12': - resolution: {integrity: sha512-03ruubjWyOHlmljCVoxSuNDdmfZDzsrrz0P2LeJsOXr+ZwFQ+0yQIwNCwt/GYhV7Z31fgtXJTAEs+FYlEL851g==} - '@types/estree@1.0.9': resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==} '@types/express-serve-static-core@4.19.9': resolution: {integrity: sha512-QP2ESEe/ImWY0HDwNAnK9PvEffUyhLTnWkk7KXzHfyeWAnlrDe1fN77bXl6ia8KT3wPlmA7t9/VPRpnf4Ex9sg==} - '@types/express-serve-static-core@5.1.3': - resolution: {integrity: sha512-dPfW8NFiOF4wOHc7+N/QSxlY9cfSsenewGbAz8C8U/MULPd/YZ27LvJUIlzaXie7e6Ove9YunJGgC9tbHD2cKw==} - '@types/express@4.17.25': resolution: {integrity: sha512-dVd04UKsfpINUnK0yBoYHDF3xu7xVH4BuDotC/xGuycx4CgbP48X/KF/586bcObxT0HENHXEU8Nqtu6NR+eKhw==} - '@types/express@5.0.6': - resolution: {integrity: sha512-sKYVuV7Sv9fbPIt/442koC7+IIwK5olP1KWeD88e/idgoJqDm3JV/YUiPwkoKK92ylff2MGxSz1CSjsXelx0YA==} - '@types/gensync@1.0.5': resolution: {integrity: sha512-MbsRCT7mTikHwKZ0X+LVUTLRrZZRLipTuXEO9qOYO+zmjMVk81axyClMROf6uoPD9MRVu46bx8zoR0Ad9q3NAg==} @@ -2028,8 +1740,8 @@ packages: '@types/lodash-es@4.17.12': resolution: {integrity: sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==} - '@types/lodash@4.17.24': - resolution: {integrity: sha512-gIW7lQLZbue7lRSWEFql49QJJWThrTFFeIMJdp3eH4tKoxm1OvEPg02rm4wCCSHS0cL3/Fizimb35b7k8atwsQ==} + '@types/lodash@4.17.25': + resolution: {integrity: sha512-+K1NIO8I+F9/wNulfVvu23QYd0Pe9/OCqRrim4NoYIf1VoEDL90Ve4ClzpyqBLc7NpGGWRvYNCKZ1BE/Jpf8dQ==} '@types/mime@1.3.5': resolution: {integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==} @@ -2067,21 +1779,12 @@ packages: '@types/serve-static@1.15.10': resolution: {integrity: sha512-tRs1dB+g8Itk72rlSI2ZrW6vZg0YrLI81iQSTkMmOqnqCaNr/8Ek4VwWcN5vZgCYWbg/JJSGBlUaYGAOP73qBw==} - '@types/serve-static@2.2.0': - resolution: {integrity: sha512-8mam4H1NHLtu7nmtalF7eyBH14QyOASmcxHhSfEoRyr0nP/YdoesEtU+uSRvMe96TW/HPTtkoKqQLl53N7UXMQ==} - - '@types/set-cookie-parser@2.4.10': - resolution: {integrity: sha512-GGmQVGpQWUe5qglJozEjZV/5dyxbOOZ0LHe/lqyWssB88Y4svNfst0uqBVscdDeIKl5Jy5+aPSvy7mI9tYRguw==} - '@types/sockjs@0.3.36': resolution: {integrity: sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==} '@types/stack-utils@2.0.3': resolution: {integrity: sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==} - '@types/statuses@2.0.6': - resolution: {integrity: sha512-xMAgYwceFhRA2zY+XbEA7mxYbA093wdiW8Vu6gZPGWy9cmOyU9XesH1tNcEWsKFd5Vzrqx5T3D38PWx1FIIXkA==} - '@types/tough-cookie@4.0.5': resolution: {integrity: sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==} @@ -2159,8 +1862,8 @@ packages: '@ungap/custom-elements@1.3.0': resolution: {integrity: sha512-f4q/s76+8nOy+fhrNHyetuoPDR01lmlZB5czfCG+OOnBw/Wf+x48DcCDPmMQY7oL8xYFL8qfenMoiS8DUkKBUw==} - '@ungap/structured-clone@1.3.2': - resolution: {integrity: sha512-5jsZFwgR5rTdKwidH9Qmat75RKwqfpKlWWB1frDkljN127mwqBu8K0PYo7/hFpF03IEJpfVPpCQDY/eDx3iHvA==} + '@ungap/structured-clone@1.3.3': + resolution: {integrity: sha512-60YRaenCQcVjYEKOcG824+DRGGIQ3VKErcBoAEDJZz5bKIs2ZG+X/H9Nk+Q6EVkwJk5QNApxbrc5QtBSwtrXAg==} '@unrs/resolver-binding-android-arm-eabi@1.12.2': resolution: {integrity: sha512-g5T90pqg1bo/7mytQx6F4iBNC0Wsh9cu+z9veDbFjc7HjpesJFWD7QMS0NGStXM075+7dJPPVvBbpZlnrdpi/w==} @@ -2272,44 +1975,6 @@ packages: cpu: [x64] os: [win32] - '@vitest/coverage-v8@4.1.9': - resolution: {integrity: sha512-G9/lgqibheLVBDRuya45EbsEXTYcWoSG+TLg7i2axuzx0Eq62eXn+aWXyaVdV5vKvFSWd6ywcX8hA7la9Pvu8g==} - peerDependencies: - '@vitest/browser': 4.1.9 - vitest: 4.1.9 - peerDependenciesMeta: - '@vitest/browser': - optional: true - - '@vitest/expect@4.1.9': - resolution: {integrity: sha512-vl/rYsUKcBr3SnQn166+XR5ZQcgMx3DQhFWdfli/cWpLnLUmbxZvyrJZotLFUryib+LtArYMSTJ5RbQ57ZqrlA==} - - '@vitest/mocker@4.1.9': - resolution: {integrity: sha512-EVkXzBjrPGM+cK8/ANWgBrkUCfJfb38/EfTSO8h7pWvKkyPkpWxvR7BkD2MyItMF62C97zAEoqdpUixwR/e+Rw==} - peerDependencies: - msw: ^2.4.9 - vite: ^6.0.0 || ^7.0.0 || ^8.0.0 - peerDependenciesMeta: - msw: - optional: true - vite: - optional: true - - '@vitest/pretty-format@4.1.9': - resolution: {integrity: sha512-s0iufns3iIFitdgm+YR7g1whCAaGtXz459VS9/PqyKDEEFgYIhsHOQmXgIgDuYCt7DeQmiZT0Qe2OA2p4ZPu5A==} - - '@vitest/runner@4.1.9': - resolution: {integrity: sha512-KXLMDtc7oe70+3mJfGrPUWPesswH+3sTxAMAMl8DG7I8IUQT4XW718dY5ID3vPUcmlu27CcKfY4P3h3I29SLJg==} - - '@vitest/snapshot@4.1.9': - resolution: {integrity: sha512-Jc7RKGNBo8Z28WYIm0Niej4xdSPByRf6mU58VpHQkd6Zh05rlnA+twjbK5HyeIGHxrzsc3mJgS43uM0CZKzaIA==} - - '@vitest/spy@4.1.9': - resolution: {integrity: sha512-fHpsS6mIi+PiEW+vcRVOMkX1oSaPKne3VOclSFICPcGOmfKgXPU5iAah+wcNcj2xPrCCmfq99IDGf+EojhhvhA==} - - '@vitest/utils@4.1.9': - resolution: {integrity: sha512-A51o8ymO5PpqlWNnBP9ZHPXDIpuMtTLlGSjN7la4US+LJzoUMyhwjA5QXlm39JexgwHKW4Xjs8Z2d3dLCXOeuA==} - '@webassemblyjs/ast@1.14.1': resolution: {integrity: sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==} @@ -2374,8 +2039,8 @@ packages: resolution: {integrity: sha512-HEHNfbars9v4pgpW6SO1KSPkfoS0xVOM/9UzkJltjlsHZmJasxg8aXkuZa7SMf8vKGIBhpUsPluQSqhJFCqebw==} engines: {node: '>=0.4.0'} - acorn@8.17.0: - resolution: {integrity: sha512-xRQbDb9BnwDafYNn6Vwl839DYVjqXYb1XVGtWAZ1kcDc6iwAL4hg3B1dZlRiuENFeO2H53gFG3in621AdERVAg==} + acorn@8.18.0: + resolution: {integrity: sha512-lGq+9yr1/GuAWaVYIHRjvvySG5/4VfKIvC8EWxStPdcDh/Ka7FG3twP6v4d5BkravUilhIAsG4Qj83t02LWUPQ==} engines: {node: '>=0.4.0'} hasBin: true @@ -2424,8 +2089,8 @@ packages: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} - ansi-regex@6.2.2: - resolution: {integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==} + ansi-regex@6.3.0: + resolution: {integrity: sha512-WpDfL7NO6j7tH88IDBNVdUJxDh9nmCteAVW9dsep846XdwF4naCBK+/tGLX3KJgcpgMRXCFlTM2hKGoK9FsdrQ==} engines: {node: '>=12'} ansi-styles@3.2.1: @@ -2448,9 +2113,6 @@ packages: resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} engines: {node: '>= 8'} - arg@4.1.3: - resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} - argparse@1.0.10: resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} @@ -2511,19 +2173,12 @@ packages: resolution: {integrity: sha512-S2s3aOytiKdFRdulw2qPE51MzjzVOisppcVv7jVFR+Kw0kxwvFrDcYA0h7Ndqbmj0HkMIXYWaoj7fli8kgx1eg==} engines: {node: '>=12.0.0'} - assertion-error@2.0.1: - resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} - engines: {node: '>=12'} - ast-metadata-inferer@0.8.1: resolution: {integrity: sha512-ht3Dm6Zr7SXv6t1Ra6gFo0+kLDglHGrEbYihTkcycrbHw7WCcuhBzPlJYHEsIpycaUwzsJHje+vUcxXUX4ztTA==} ast-types-flow@0.0.8: resolution: {integrity: sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==} - ast-v8-to-istanbul@1.0.4: - resolution: {integrity: sha512-0bC0/4bTSrnwdhU3IsZDwEdojvuPrSg59OYZfKsLRtJZ0u8VBx9DebfqqG8bRdCC0I7vjgxmPi41P0lpkhJHtA==} - astral-regex@2.0.0: resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==} engines: {node: '>=8'} @@ -2532,8 +2187,8 @@ packages: resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==} engines: {node: '>= 0.4'} - autoprefixer@10.5.2: - resolution: {integrity: sha512-rD5t5DwOjJdmSORcTq64j8MawTC+tbQ+HHqjR4NDumamy/ambn1UJrlKL+KdwujWxMkFjPM3pPHOEA9tl4767Q==} + autoprefixer@10.5.4: + resolution: {integrity: sha512-MaU0U/za7N3r6brxD4YB/l4NSrFzLPlANv6wEuQVaIPlD3L4W9rFcQPbL/EilY9BHhHvhfcz3gInDLrEtWT4EA==} engines: {node: ^10 || ^12 || >=14} hasBin: true peerDependencies: @@ -2543,8 +2198,8 @@ packages: resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} engines: {node: '>= 0.4'} - axe-core@4.12.1: - resolution: {integrity: sha512-s7iGf5GaVMxEG0ENN9x+xTr7GFZCb1ZP/1uATUpCEK2X78nDB3RwbtFCo9pGAf9ru+VwoQ464DkaLEeRM08wJA==} + axe-core@4.13.0: + resolution: {integrity: sha512-UzGt8zg7Ny8djbYMhxl2zuEevVa7r2gJjYY5Lwr1xM7+XU2nd6CkIWFTVcCIbAP63vSz71NaVyyuSk9lHKcy0A==} engines: {node: '>=4'} axobject-query@4.1.0: @@ -2602,8 +2257,8 @@ packages: resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} engines: {node: 18 || 20 || >=22} - baseline-browser-mapping@2.10.40: - resolution: {integrity: sha512-BSSLZ9/Cjjv7Gtj5B68ZzXcXUg8iOf3fme+FCuh8rC/Go+Kmh8cox7M3A8dolou16s64QjLPOSdngh7GxXvkSw==} + baseline-browser-mapping@2.11.17: + resolution: {integrity: sha512-KAUDn1OSS0fmPlGO+NOUMRcOQ/b/shUBH3OgkG73mPgdf+JD/BQ6fHboGxNOxnUmlwcq+lLq3dTkayRPuSfXwg==} engines: {node: '>=6.0.0'} hasBin: true @@ -2621,8 +2276,8 @@ packages: resolution: {integrity: sha512-p5tAzS57i5MV9fZFDj9LeIiTZEufbSe2eDozP+ElheSUq1m74CRq1jI4mYNDdVs9vQztXFLuk/Gd6BWTdwRJ5g==} engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} - bonjour-service@1.4.2: - resolution: {integrity: sha512-lMskhnsW70yWHr4PhPeh2rvaIkLSaDpp+nmtbXBZaNKTXwxL73QOkW6HhbzqTImXjevn9TreGT4GACGBCGP9nQ==} + bonjour-service@1.4.4: + resolution: {integrity: sha512-jCZcVv7eoc4QesRscwEZtSROBen+6LpKAmBIsQYQrsAeVHLyMXWX/t6eIV5KiRZYNUBl8eVqImEEMQ8L5+c/Kw==} boolbase@1.0.0: resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} @@ -2641,8 +2296,8 @@ packages: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} - browserslist@4.28.4: - resolution: {integrity: sha512-MTc8i/x9jBQd1iMw2CFGS+rwMa07eYjLR0CCTLDACl9xhxy+nIs3KeML/biicXtk9JrZ6dnnTatmc7ErPXIxqw==} + browserslist@4.28.8: + resolution: {integrity: sha512-V2NpofLblG64mfOtSgDhOJESZEGogzDMBv/q+W6oc4LXWP/q75eOXoOaaOu1EOadB9U4Bwx/e0yzbvwKH8zalA==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true @@ -2701,12 +2356,8 @@ packages: caniuse-api@3.0.0: resolution: {integrity: sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==} - caniuse-lite@1.0.30001800: - resolution: {integrity: sha512-MMHtuAz9Ys840zAY5F4k6fV5GaivZ9sPk+nz0mY+GYVzRBnYkN0mpqkSR92oWRQ19yQWo4HvBV/FnC16AJX8MA==} - - chai@6.2.2: - resolution: {integrity: sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==} - engines: {node: '>=18'} + caniuse-lite@1.0.30001809: + resolution: {integrity: sha512-xxWVywk6a6Arlk+hymeycyn/VgqEfLDxupvhH/xiY5SJ/18kmi9o6MiO320DCUzypORHLtvh0I4i04tUhCNHNQ==} chalk@2.4.2: resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} @@ -2761,10 +2412,6 @@ packages: resolution: {integrity: sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - cli-width@4.1.0: - resolution: {integrity: sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==} - engines: {node: '>= 12'} - cliui@8.0.1: resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} engines: {node: '>=12'} @@ -2797,8 +2444,8 @@ packages: color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - colord@2.9.3: - resolution: {integrity: sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==} + colord@2.10.0: + resolution: {integrity: sha512-AidJptpBJmjTclAp9BkLwJi0T93fo5epJnbaZslpg6QVzpHjAiveF55mE9AcUJiGMqRHgMDY8soMsQtuNYMHfw==} colorette@2.0.20: resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} @@ -2858,12 +2505,9 @@ packages: resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} engines: {node: '>= 0.6'} - cookie@1.1.1: - resolution: {integrity: sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==} - engines: {node: '>=18'} - - core-js-compat@3.49.0: - resolution: {integrity: sha512-VQXt1jr9cBz03b331DFDCCP90b3fanciLkgiOoy8SBHy06gNf+vQ1A3WFLqG7I8TipYIKeYK9wxd0tUrvHcOZA==} + core-js-compat@3.50.0: + resolution: {integrity: sha512-XGpFGbMLHwSt74YLTKho7Ib242qi6O8MSX+sRokV4oz7iKXvQWGYZthjIhjRGMxjzVkAubBO512dKGYcefmX3Q==} + engines: {node: '>=6.4.0'} core-util-is@1.0.3: resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} @@ -2886,9 +2530,6 @@ packages: typescript: optional: true - create-require@1.1.1: - resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} - cross-env@10.1.0: resolution: {integrity: sha512-GsYosgnACZTADcmEyJctkJIoqAhHjttw7RsFrVoJNXbsWWqaq6Ym+7kZjq6mS45O0jij6vtiReppKQEtqWy6Dw==} engines: {node: '>=20'} @@ -2897,10 +2538,6 @@ packages: cross-fetch@3.2.0: resolution: {integrity: sha512-Q+xVJLoGOeIMXZmbUK4HYk+69cQH6LudR0Vu/pRm2YlU/hDV9CiS0gKUMaWY5f2NeUH9C1nV3bsTlCo0FsTV1Q==} - cross-spawn@6.0.6: - resolution: {integrity: sha512-VqCUuhcd1iB+dsv8gxPttb5iZh/D0iubSP21g36KXdEuf6I5JiioesUVjpCdHV9MZRUfVFlvwtIUyPfxo5trtw==} - engines: {node: '>=4.8'} - cross-spawn@7.0.6: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} @@ -3107,8 +2744,8 @@ packages: resolution: {integrity: sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q==} engines: {node: '>=18'} - default-browser@5.5.0: - resolution: {integrity: sha512-H9LMLr5zwIbSxrmvikGuI/5KGhZ8E2zH3stkMgM5LpOWDutGM2JZaj460Udnf1a+946zc7YBgrqEWwbk7zHvGw==} + default-browser@5.5.1: + resolution: {integrity: sha512-m1pAzaJgZ/gssEqlOhJkPJp8Xly7QyW6xcrkUa2KKcDeDSEMP7X8xipU3snUcfisTQx0w1AGae+9UtJSfVnXGw==} engines: {node: '>=18'} define-data-property@1.1.4: @@ -3139,10 +2776,6 @@ packages: resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} - detect-libc@2.1.2: - resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} - engines: {node: '>=8'} - detect-newline@3.1.0: resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==} engines: {node: '>=8'} @@ -3150,10 +2783,6 @@ packages: detect-node@2.1.0: resolution: {integrity: sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==} - diff@4.0.4: - resolution: {integrity: sha512-X07nttJQkwkfKfvTPG/KSnE2OMdcUCao6+eXF3wmnIQRn2aPAHH3VxDbDOdegkd6JbPsXqShpvEOHfAT+nCNwQ==} - engines: {node: '>=0.3.1'} - dns-packet@5.6.1: resolution: {integrity: sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==} engines: {node: '>=6'} @@ -3214,8 +2843,8 @@ packages: ee-first@1.1.1: resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} - electron-to-chromium@1.5.382: - resolution: {integrity: sha512-8ETaWbV6SZOrno+G93Ffd9ENsMtetqdnqj4nlfxFW90Sm5GgnuV28Kf62hqQVD6VUgzm7qFQKsTsAPmeUiU3Ug==} + electron-to-chromium@1.5.412: + resolution: {integrity: sha512-z4rMe3esBzlzovKHj4gxJnsCGZRK5l4baUvm+gCGJBPE+gsyUMKsuU9tnEUtI1dOebXz1ytAPGjvXhmQ7rIPwA==} emittery@0.13.1: resolution: {integrity: sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==} @@ -3239,10 +2868,6 @@ packages: resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} engines: {node: '>= 0.8'} - enhanced-resolve@5.24.1: - resolution: {integrity: sha512-7DdUaTjmNwMcH2gLr1qycesKII3BK4RLy/mdAb7x10Lq7bR4aNKHt1BR1ZALSv0rPM/hF5wYF0PhGop/rJm8vw==} - engines: {node: '>=10.13.0'} - enhanced-resolve@5.24.5: resolution: {integrity: sha512-L1l8TNvomm6UVW5B253AGxQagSQr+vGwhMlrrfRS2qmhx46AMpMVJKQYLvWYbysTMY8VoicOvzHzoHMbyzB+4A==} engines: {node: '>=10.13.0'} @@ -3289,12 +2914,12 @@ packages: es-get-iterator@1.1.3: resolution: {integrity: sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==} - es-iterator-helpers@1.3.3: - resolution: {integrity: sha512-0PuBxFi+4uPanB97iDxCLWuHeYud2FALrw5HFZGtAF38UpJDbDC8frwp2cnDyae692CQ0dou60UwWfhgsa4U/g==} + es-iterator-helpers@1.4.0: + resolution: {integrity: sha512-c/A0P0oxkACDc+cKWw8evLXK83oBKgn0qPOqCYT4x9uolpCIJAcYvJC9QYKNDRPsTeGyCrQ326jrvgZWdCdK5Q==} engines: {node: '>= 0.4'} - es-module-lexer@2.2.0: - resolution: {integrity: sha512-3lGxdTXCLfe1MYfTz1y2ksAAUM4NAOP6rPEjxGJVKO7TZ5+tvHCaQWGpC4Y3IXvW3ece0Cz1cIP4FWBxOnGCTQ==} + es-module-lexer@2.3.2: + resolution: {integrity: sha512-poHGpORABojJJucnV9KbOavETW8lBVnphkW77ER5/BQ5Fz7oXSoCNek7IH3vR5nRjdsEz926ibFYX8KtLQmdyw==} es-object-atoms@1.1.2: resolution: {integrity: sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==} @@ -3349,8 +2974,8 @@ packages: eslint-import-resolver-node@0.3.10: resolution: {integrity: sha512-tRrKqFyCaKict5hOd244sL6EQFNycnMQnBe+j8uqGNXYzsImGbGUU4ibtoaBmv5FLwJwcFJNeg1GeVjQfbMrDQ==} - eslint-module-utils@2.13.0: - resolution: {integrity: sha512-bLohSkT6469rRs8czj0tLTD8vaeIS/whvPRJVjDr7IuoTT1k5DYDERlNycjDj/HkOlvQdYurmfZ/g3fG5bgeLQ==} + eslint-module-utils@2.14.0: + resolution: {integrity: sha512-W2WCRZ9Dqntd+2u8jJcVMV2PKulc6RdLgUUoh/yQr3uB6lo/ZOeGx11sv60/8S4QFFKNslAlWhr9u0Ef7ZW6Ig==} engines: {node: '>=4'} peerDependencies: '@typescript-eslint/parser': '*' @@ -3445,6 +3070,7 @@ packages: eslint@9.39.5: resolution: {integrity: sha512-DgZS62aPLXKlnxILS/AYCoRvHaZeXceIzlXPkkGGzJWSow1aEk0lbTlxUSlyjC8jcaKxAdOnTDz+o1JFSBsyjw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + deprecated: This version is no longer supported. Please see https://eslint.org/version-support for other options. hasBin: true peerDependencies: jiti: '*' @@ -3477,9 +3103,6 @@ packages: resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} engines: {node: '>=4.0'} - estree-walker@3.0.3: - resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} - esutils@2.0.3: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} engines: {node: '>=0.10.0'} @@ -3510,10 +3133,6 @@ packages: resolution: {integrity: sha512-+I6B/IkJc1o/2tiURyz/ivu/O0nKNEArIUB5O7zBrlDVJr22SCLH3xTeEry428LvFhRzIA1g8izguxJ/gbNcVQ==} engines: {node: '>= 0.8.0'} - expect-type@1.4.0: - resolution: {integrity: sha512-KfYbmpRm0VbLjEvVa9yGwCi9GI34xvi7A/HXYWQO65CSD2u3MczUJSuwXKFIxlGsgBQizV9q5J9NHj4VG0n+pA==} - engines: {node: '>=12.0.0'} - expect@30.4.1: resolution: {integrity: sha512-PMARsyh/JtqC20HoGqlFcIlQAyqUtW4PlI1rup1uhYJtKuwAjbvWi3GQMAn+STdHum/dk8xrKfUM1+5SAwpolA==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} @@ -3538,18 +3157,9 @@ packages: fast-levenshtein@2.0.6: resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} - fast-string-truncated-width@3.0.3: - resolution: {integrity: sha512-0jjjIEL6+0jag3l2XWWizO64/aZVtpiGE3t0Zgqxv0DPuxiMjvB3M24fCyhZUO4KomJQPj3LTSUnDP3GpdwC0g==} - - fast-string-width@3.0.2: - resolution: {integrity: sha512-gX8LrtNEI5hq8DVUfRQMbr5lpaS4nMIWV+7XEbXk2b8kiQIizgnlr12B4dA3ZEx3308ze0O4Q1R+cHts8kyUJg==} - fast-uri@4.1.2: resolution: {integrity: sha512-TyGmBcbDTZXcb2cj5MV89DrF42DKvb3y5DDUNh95iO+IMeAzMkVSxK1PZRrRIpc9yg8U2GhGdbofNa0LS/a4Bw==} - fast-wrap-ansi@0.2.2: - resolution: {integrity: sha512-7F2Fl+TjRSenLqlU3UjSH0iyqopqoZIu7eZVpEirP2g1GtWa2G/ecEmBdgz31+Mxr+ELclgg6sokpSFIQiZ02Q==} - fastest-levenshtein@1.0.16: resolution: {integrity: sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==} engines: {node: '>= 4.9.1'} @@ -3613,8 +3223,8 @@ packages: resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==} hasBin: true - flatted@3.4.2: - resolution: {integrity: sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==} + flatted@3.4.4: + resolution: {integrity: sha512-5+ybhBZANEJxaH3X5evAFatUxLfEHSr7n6kYJ+1Qd0mUqr4eu9gIf6GDbWHf8RJijHrjjO8G+la14SlL2SeS1Q==} follow-redirects@1.16.0: resolution: {integrity: sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==} @@ -3777,10 +3387,6 @@ packages: graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} - graphql@16.14.2: - resolution: {integrity: sha512-Chq1s4CY7jmh8gO2qvLIJyfCDIN+EHLFW/9iShnp1z8FjBQMoodWP1kDC36VAMXXIvAjj4ARa7ntfAV2BrjsbA==} - engines: {node: ^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0} - handle-thing@2.0.1: resolution: {integrity: sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==} @@ -3830,9 +3436,6 @@ packages: resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} hasBin: true - headers-polyfill@5.0.1: - resolution: {integrity: sha512-1TJ6Fih/b8h5TIcv+1+Hw0PDQWJTKDKzFZzcKOiW1wJza3XoAQlkCuXLbymPYB8+ZQyw8mHvdw560e8zVFIWyA==} - hookified@1.15.1: resolution: {integrity: sha512-MvG/clsADq1GPM2KGo2nyfaWVyn9naPiXrqIe4jYjXNZQt238kWyOGrsyc/DmRAQ+Re6yeo6yX/yoNCG5KAEVg==} @@ -3956,8 +3559,8 @@ packages: resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} engines: {node: '>= 4'} - ignore@7.0.5: - resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==} + ignore@7.0.6: + resolution: {integrity: sha512-BAg6QkE8W+TuQLrrw0Ugr7HegXduRuuj8/ti2kSOc+jz1dmx8/WNcjr6XGnq5YpDWxFwwaavqD0+jIUOKelTsw==} engines: {node: '>= 4'} import-fresh@3.3.1: @@ -4005,8 +3608,8 @@ packages: resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} engines: {node: '>= 0.10'} - ipaddr.js@2.4.0: - resolution: {integrity: sha512-9VGk3HGanVE6JoZXHiCpnGy5X0jYDnN4EA4lntFPj+1vIWlFhIylq2CrrCOJH9EAhc5CYhq18F2Av2tgoAPsYQ==} + ipaddr.js@2.5.0: + resolution: {integrity: sha512-aq+t5NAc+cS6rZQQVWC2x98CPqGtKKTMDd4Gaodv0wShnItdKg/51djkGJ1hqH+Oy0ivDftCbSLCQob8zso01w==} engines: {node: '>= 10'} is-arguments@1.2.0: @@ -4106,9 +3709,6 @@ packages: resolution: {integrity: sha512-PhBY86zaxNZUuWP6h13Vu5oFe0XY6/UlKzQnYFELzGVHygP3MxmvTfYSG7GN3aIab/iWudSMgjSnG9Dq+nHrgA==} engines: {node: '>=16'} - is-node-process@1.2.0: - resolution: {integrity: sha512-Vg4o6/fqPxIjtxgUH5QLJhwZ7gW5diGCVlXpuUfELC62CuxM1iHcRe51f2W1FDy04Ai4KJkagKjx3XaqyfRKXw==} - is-number-object@1.1.1: resolution: {integrity: sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==} engines: {node: '>= 0.4'} @@ -4478,76 +4078,6 @@ packages: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} - lightningcss-android-arm64@1.32.0: - resolution: {integrity: sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==} - engines: {node: '>= 12.0.0'} - cpu: [arm64] - os: [android] - - lightningcss-darwin-arm64@1.32.0: - resolution: {integrity: sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==} - engines: {node: '>= 12.0.0'} - cpu: [arm64] - os: [darwin] - - lightningcss-darwin-x64@1.32.0: - resolution: {integrity: sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==} - engines: {node: '>= 12.0.0'} - cpu: [x64] - os: [darwin] - - lightningcss-freebsd-x64@1.32.0: - resolution: {integrity: sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==} - engines: {node: '>= 12.0.0'} - cpu: [x64] - os: [freebsd] - - lightningcss-linux-arm-gnueabihf@1.32.0: - resolution: {integrity: sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==} - engines: {node: '>= 12.0.0'} - cpu: [arm] - os: [linux] - - lightningcss-linux-arm64-gnu@1.32.0: - resolution: {integrity: sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==} - engines: {node: '>= 12.0.0'} - cpu: [arm64] - os: [linux] - - lightningcss-linux-arm64-musl@1.32.0: - resolution: {integrity: sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==} - engines: {node: '>= 12.0.0'} - cpu: [arm64] - os: [linux] - - lightningcss-linux-x64-gnu@1.32.0: - resolution: {integrity: sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==} - engines: {node: '>= 12.0.0'} - cpu: [x64] - os: [linux] - - lightningcss-linux-x64-musl@1.32.0: - resolution: {integrity: sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==} - engines: {node: '>= 12.0.0'} - cpu: [x64] - os: [linux] - - lightningcss-win32-arm64-msvc@1.32.0: - resolution: {integrity: sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==} - engines: {node: '>= 12.0.0'} - cpu: [arm64] - os: [win32] - - lightningcss-win32-x64-msvc@1.32.0: - resolution: {integrity: sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==} - engines: {node: '>= 12.0.0'} - cpu: [x64] - os: [win32] - - lightningcss@1.32.0: - resolution: {integrity: sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==} - engines: {node: '>= 12.0.0'} - lilconfig@2.1.0: resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==} engines: {node: '>=10'} @@ -4627,8 +4157,8 @@ packages: lru-cache@10.4.3: resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} - lru-cache@11.5.1: - resolution: {integrity: sha512-RPimw/7aMdv2oqRrxKwvZXcPfwBrn/JZ2xYcY9Hus/6LaS3VOAKVWKWgNLCFSiOm1ESXinjsDlidVU7JlnCN2A==} + lru-cache@11.5.2: + resolution: {integrity: sha512-4pfM1Ff0x50o0tQwb5ucw/RzNyD0/YJME6IVcStalZuMWxdt3sR3huStTtxz4PUmvZfRguvDejasvQ2kifR11g==} engines: {node: 20 || >=22} lru-cache@5.1.1: @@ -4638,19 +4168,10 @@ packages: resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} hasBin: true - magic-string@0.30.21: - resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} - - magicast@0.5.3: - resolution: {integrity: sha512-pVKE4UdSQ7DvHzivsCIFx2BJn1mHG6KsyrFcaxFx6tONdneEuThrDx0Cj3AMg58KyN4pzYT+LHOotxDQDjNvkw==} - make-dir@4.0.0: resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} engines: {node: '>=10'} - make-error@1.3.6: - resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} - makeerror@1.0.12: resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==} @@ -4675,10 +4196,8 @@ packages: resolution: {integrity: sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==} engines: {node: '>= 4.0.0'} - memfs@4.57.8: - resolution: {integrity: sha512-bApYhn8BLpFAnAQmFfEl/NPN+8qx5Ar3V4Qt3ek23mVwBEElzV7c6XoPkb/PCG8ZFpowCEpHcPwMFTwHS7tSMA==} - peerDependencies: - tslib: '2' + memfs@4.68.1: + resolution: {integrity: sha512-OD+IDRUvIxu3QHL+nFm9gdyugInD27FDJ+sl4B5QgomPHXMlbw+GP918P8VNKu2FkNlVeqBkpzkwROpamVifRw==} memorystream@0.3.1: resolution: {integrity: sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==} @@ -4748,8 +4267,8 @@ packages: minimalistic-assert@1.0.1: resolution: {integrity: sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==} - minimatch@10.2.5: - resolution: {integrity: sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==} + minimatch@10.2.6: + resolution: {integrity: sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A==} engines: {node: 18 || 20 || >=22} minimatch@3.1.5: @@ -4822,24 +4341,10 @@ packages: ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - msw@2.14.6: - resolution: {integrity: sha512-ALe+N10S72cyx94cMcy3Zs4HhXCj35sgeAL4c+WTvKi0zWnbd8/h0lcFqv0mb2P+aSgAdD7p9HzvA0DiUPxsyg==} - engines: {node: '>=18'} - hasBin: true - peerDependencies: - typescript: '>= 4.8.x' - peerDependenciesMeta: - typescript: - optional: true - multicast-dns@7.2.5: resolution: {integrity: sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==} hasBin: true - mute-stream@3.0.0: - resolution: {integrity: sha512-dkEJPVvun4FryqBmZ5KhDo0K9iDXAwn08tMLDinNdRBNPcYEDiWYysLcc6k3mjTMlbP9KyylvRpd4wFtwrT9rw==} - engines: {node: ^20.17.0 || >=22.9.0} - nanoid@3.3.18: resolution: {integrity: sha512-DTg4MJbGMWkfi6VZFdNt2/caMbQy4Ou+Op/hJQvGEWcnVfoA1QA+xzRKAzw9jD6+GVOOeYr/mIcuDSdug6F6+w==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} @@ -4867,9 +4372,6 @@ packages: neo-async@2.6.2: resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} - nice-try@1.0.5: - resolution: {integrity: sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==} - no-case@3.0.4: resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==} @@ -4895,8 +4397,8 @@ packages: node-int64@0.4.0: resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} - node-releases@2.0.50: - resolution: {integrity: sha512-J6l92tKHX6w8Jy5nO1Vuc01NoIiRGi/d6qBKVxh+IQ8Cr3b6HbVNfKiF8ZpFKufTwpwxMmce2W3iQZ861ZRyTg==} + node-releases@2.0.53: + resolution: {integrity: sha512-D9UOmYG3UH1V+ENW56t5QXBwJw1YEY18ruVeus89Rw+SyIgjPkCO84bRzO3uNIYosJbNwiabWVn48o3uJLjxFQ==} engines: {node: '>=18'} normalize-package-data@2.5.0: @@ -4964,8 +4466,8 @@ packages: obuf@1.1.2: resolution: {integrity: sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==} - obug@2.1.3: - resolution: {integrity: sha512-9miFgM2OFba7hB+pRgvtV84pYTBaoTHohvmIgiRt6dRIzbwEOIaNaP+dIlGs2fNFoB0SeISs0Jz5WFVRid6Xyg==} + obug@2.1.4: + resolution: {integrity: sha512-4a+OsYv9UktOJKE+l1A4OufDgdRF9PifWj+tJnHURo/P+WOxpG4GzUFL9qCalmWauao6ogiG+QvnCovwPoyAWA==} engines: {node: '>=12.20.0'} on-finished@2.4.1: @@ -4999,11 +4501,8 @@ packages: resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} engines: {node: '>= 0.8.0'} - outvariant@1.4.3: - resolution: {integrity: sha512-+Sl2UErvtsoajRDKCE5/dBz4DIvHXQQnAxtQTF04OJxY0+DyZXSo5P5Bb7XYWOh81syohlYL24hbDwxedPUJCA==} - - own-keys@1.0.1: - resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==} + own-keys@1.0.2: + resolution: {integrity: sha512-19YVAg7T+WTrxggPukVq7DjTv6+PJ867TmhCvBsYwmbFCsZd344rq2Ld1p0wo8f8Qrrhgp82c6FJRqdXWtSEhg==} engines: {node: '>= 0.4'} p-limit@2.3.0: @@ -5073,10 +4572,6 @@ packages: path-is-inside@1.0.2: resolution: {integrity: sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==} - path-key@2.0.1: - resolution: {integrity: sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==} - engines: {node: '>=4'} - path-key@3.1.1: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} @@ -5095,9 +4590,6 @@ packages: path-to-regexp@0.1.13: resolution: {integrity: sha512-A/AGNMFN3c8bOlvV9RreMdrv7jsmF9XIfDeCd87+I8RNg6s78BhJxMu69NEMHBSJFxKidViTEdruRwEk/WIKqA==} - path-to-regexp@6.3.0: - resolution: {integrity: sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==} - path-type@3.0.0: resolution: {integrity: sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==} engines: {node: '>=4'} @@ -5106,9 +4598,6 @@ packages: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} - pathe@2.0.3: - resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} - picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} @@ -5116,8 +4605,8 @@ packages: resolution: {integrity: sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==} engines: {node: '>=8.6'} - picomatch@4.0.4: - resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==} + picomatch@4.0.5: + resolution: {integrity: sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==} engines: {node: '>=12'} pidtree@0.3.1: @@ -5543,8 +5032,8 @@ packages: resolution: {integrity: sha512-bIoJLOmjCO1S9XdY/DcnR5hJxvrDir1PbGChrzXG3vw0/FOliy/fA3dmdhQ441kah4gKv+TwckGzex6wNS5cnQ==} engines: {node: '>=4'} - postcss-selector-parser@7.1.4: - resolution: {integrity: sha512-HeP7D2wyhkR+XaK6v4W8oRF62Dsz4flyuczALJp61GckGm42u1saSSJ/0auvcBqxs3jMRFEcPK34At/0JBKdOg==} + postcss-selector-parser@7.1.5: + resolution: {integrity: sha512-KvvtD7SrlBP7dlgkBghEE3r84CABm5SmV2aNcG4oCA+qDnJ/tvKonFVvwWAyyWUEwxuNawdfEAZKP9zM3oZ2Uw==} engines: {node: '>=4'} postcss-svgo@7.1.3: @@ -5618,8 +5107,8 @@ packages: pvtsutils@1.3.6: resolution: {integrity: sha512-PLgQXQ6H2FWCaeRak8vvk1GW462lMxB5s3Jm673N82zI4vqtVUPuZdffdZbPDFRoU8kAhItWFtPCWiPpp4/EDg==} - pvutils@1.1.5: - resolution: {integrity: sha512-KTqnxsgGiQ6ZAzZCVlJH5eOjSnvlyEgx1m8bkRJfOhmGRqfo5KLvmAlACQkrjEtOQ4B7wF9TdSLIs9O90MX9xA==} + pvutils@1.2.0: + resolution: {integrity: sha512-BbubeCEyTuQjVMakvJQ/Sxbc93F2pwmbsxONT/ZRrwU7Ua38d8unYTwXpTVLAKJ4BDuH9IGztCjQcd/N/39Dvg==} engines: {node: '>=16.0.0'} qified@0.10.1: @@ -5774,9 +5263,6 @@ packages: resolution: {integrity: sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==} engines: {node: '>= 4'} - rettime@0.11.11: - resolution: {integrity: sha512-ILJRqVWBCTlg9r42fFgwVZx1gnFAcQF8mRoMkbgQfIrjEDf9nbBFDFx00oloOa+Q869FUtaYDXZvEfnecQSCoQ==} - reusify@1.1.0: resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} @@ -5789,11 +5275,6 @@ packages: deprecated: Rimraf versions prior to v4 are no longer supported hasBin: true - rolldown@1.1.3: - resolution: {integrity: sha512-1F1eEtUBtFvcGm1HQ9TiUIUHPQG7mSAODrhIzjxoUEFuo8OcbrGLiVLkevNgj84TE4lnHvnumwFjhJO5Eu135g==} - engines: {node: ^20.19.0 || >=22.12.0} - hasBin: true - rrweb-cssom@0.8.0: resolution: {integrity: sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==} @@ -5825,8 +5306,8 @@ packages: safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - sax@1.6.0: - resolution: {integrity: sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA==} + sax@1.6.1: + resolution: {integrity: sha512-42tBVwLWnaQvW5zc4HbZrTuWccECCZfBi92FDuwtqxasH+JbPB3/FOKb1m222K42R4WxuxzzMsTswfzgtSu64Q==} engines: {node: '>=11.0.0'} saxes@6.0.0: @@ -5848,10 +5329,6 @@ packages: resolution: {integrity: sha512-ftnu3TW4+3eBfLRFnDEkzGxSF/10BJBkaLJuBHZX0kiPS7bRdlpZGu6YGt4KngMkdTwJE6MbjavFpqHvqVt+Ew==} engines: {node: '>=18'} - semver@5.7.2: - resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} - hasBin: true - semver@6.3.1: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true @@ -5877,9 +5354,6 @@ packages: resolution: {integrity: sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA==} engines: {node: '>= 0.8.0'} - set-cookie-parser@3.1.1: - resolution: {integrity: sha512-vM9SUhjsUYs6UeJUmygc5Ofm5eQGe85riob5ju6XCgFGJI5PLV4nrDAQpQjd+LkFBpAkADn5BQQpZ9EUNkyLuA==} - set-function-length@1.2.2: resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} engines: {node: '>= 0.4'} @@ -5899,24 +5373,16 @@ packages: resolution: {integrity: sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==} engines: {node: '>=8'} - shebang-command@1.2.0: - resolution: {integrity: sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==} - engines: {node: '>=0.10.0'} - shebang-command@2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} engines: {node: '>=8'} - shebang-regex@1.0.0: - resolution: {integrity: sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==} - engines: {node: '>=0.10.0'} - shebang-regex@3.0.0: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} - shell-quote@1.9.0: - resolution: {integrity: sha512-Iov+JwFv/2HcTpcwNMKd8+IWNb8tboQJNQTkAY/LLVK7gGH9jy+LGkVqPxfekHl+yMmiqXszdGWXgkfml7hjqA==} + shell-quote@1.10.0: + resolution: {integrity: sha512-w1aiOKwKuRgtwAReIIj89puqg+I7GvX4IbLrvmhXbzQsj1+Zwi4VO3+fa6ZF91TWSjIxoEkKnMeHcLEODK5ZXA==} engines: {node: '>= 0.4'} side-channel-list@1.0.1: @@ -5935,9 +5401,6 @@ packages: resolution: {integrity: sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==} engines: {node: '>= 0.4'} - siginfo@2.0.0: - resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} - signal-exit@3.0.7: resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} @@ -6013,9 +5476,6 @@ packages: resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} engines: {node: '>=10'} - stackback@0.0.2: - resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} - statuses@1.5.0: resolution: {integrity: sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==} engines: {node: '>= 0.6'} @@ -6024,16 +5484,10 @@ packages: resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} engines: {node: '>= 0.8'} - std-env@4.1.0: - resolution: {integrity: sha512-Rq7ybcX2RuC55r9oaPVEW7/xu3tj8u4GeBYHBWCychFtzMIr86A7e3PPEBPT37sHStKX3+TiX/Fr/ACmJLVlLQ==} - stop-iteration-iterator@1.1.0: resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==} engines: {node: '>= 0.4'} - strict-event-emitter@0.5.1: - resolution: {integrity: sha512-vMgjE/GGEPEFnhFub6pa4FmJBRBVOLpIII2hvCZ8Kzb7K0hlHo7mQv6xYrBvCL2LtAIBwFUK8wvuJgTVSQ5MFQ==} - string-argv@0.3.2: resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==} engines: {node: '>=0.6.19'} @@ -6203,16 +5657,12 @@ packages: resolution: {integrity: sha512-9kY+CygyYM6j02t5YFHbNz2FN5QmYGv9zAjVp4lCDjlCw7amdckXlEt/bjMhUIfj4ThGRE4gCUH5+yGnNuPo5A==} engines: {node: '>=10.0.0'} - tagged-tag@1.0.0: - resolution: {integrity: sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng==} - engines: {node: '>=20'} - tapable@2.3.3: resolution: {integrity: sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==} engines: {node: '>=6'} - terser@5.48.0: - resolution: {integrity: sha512-J/9An6vs9Us6wKRriSFXBWdRZapREHqFzdNUKk0pmu804EMR6dr6winwo7e5JDxN4xahxQsuysyYFwlwj4XN/Q==} + terser@5.50.0: + resolution: {integrity: sha512-CN9BVxWhgS/hRxtUMjtC2uRWSTcSfQFHMDWma6sKKfIivCD91sM+FOPfvwoaRMqCSrUpe1nv3jDamd9eEQ4y+w==} engines: {node: '>=10'} hasBin: true @@ -6220,8 +5670,8 @@ packages: resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==} engines: {node: '>=8'} - thingies@2.6.0: - resolution: {integrity: sha512-rMHRjmlFLM1R96UYPvpmnc3LYtdFrT33JIB7L9hetGue1qAPfn1N2LJeEjxUSidu1Iku+haLZXDuEXUHNGO/lg==} + thingies@2.6.1: + resolution: {integrity: sha512-cV/CMGTK3M4MlnJ/0At6ismOw/A0EEniDNScajjz/Br3c1sqE72YD01rGpPTKwd27wAxI5Pr+6+0w8yofzFRYw==} engines: {node: '>=10.18'} peerDependencies: tslib: ^2 @@ -6229,35 +5679,17 @@ packages: thunky@1.1.0: resolution: {integrity: sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==} - tinybench@2.9.0: - resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} - - tinyexec@1.2.4: - resolution: {integrity: sha512-SHf/r48b7vOrjve9PxJo3MN5v5yuyjHvdUcrQffT3WXMUfnGmHDVbC4k3sHJaJTgZCwpUplIaAo5ANtMyp3YHg==} - engines: {node: '>=18'} - tinyglobby@0.2.17: resolution: {integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==} engines: {node: '>=12.0.0'} - tinyrainbow@3.1.0: - resolution: {integrity: sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==} - engines: {node: '>=14.0.0'} - tldts-core@6.1.86: resolution: {integrity: sha512-Je6p7pkk+KMzMv2XXKmAE3McmolOQFdxkKw0R8EYNr7sELW46JqnNeTX8ybPiQgvg1ymCoF8LXs5fzFaZvJPTA==} - tldts-core@7.4.5: - resolution: {integrity: sha512-pGrwzZDvPwKe+7NNUqAunb6rqTfynr0VOUhCMdqbu5xlvNiszsAJygRzwvpVycdzejlbpY+SWJOn+s75Og7FEA==} - tldts@6.1.86: resolution: {integrity: sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ==} hasBin: true - tldts@7.4.5: - resolution: {integrity: sha512-RfEzKWcq5fHUOFq7J3rl3Oz6ylKGtcHqUznzj4EcXsxLSIjJcvpbXAQtWGeJQ0xKnimR5e0Cn+cn9TssfMzm+g==} - hasBin: true - tmpl@1.0.5: resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==} @@ -6277,10 +5709,6 @@ packages: resolution: {integrity: sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A==} engines: {node: '>=16'} - tough-cookie@6.0.1: - resolution: {integrity: sha512-LktZQb3IeoUWB9lqR5EWTHgW/VTITCXg4D21M+lvybRVdylLrRMnqaIONLVb5mav8vM19m44HIcGq4qASeu2Qw==} - engines: {node: '>=16'} - tr46@0.0.3: resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} @@ -6300,20 +5728,6 @@ packages: peerDependencies: typescript: '>=4.8.4' - ts-node@10.9.2: - resolution: {integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==} - hasBin: true - peerDependencies: - '@swc/core': '>=1.2.50' - '@swc/wasm': '>=1.2.50' - '@types/node': '*' - typescript: '>=2.7' - peerDependenciesMeta: - '@swc/core': - optional: true - '@swc/wasm': - optional: true - tsconfig-paths-webpack-plugin@4.2.0: resolution: {integrity: sha512-zbem3rfRS8BgeNK50Zz5SIQgXzLafiHjOwUAvk/38/o1jHn/V5QAgVUcz884or7WYcPaH3N2CIfUc2u0ul7UcA==} engines: {node: '>=10.13.0'} @@ -6351,10 +5765,6 @@ packages: resolution: {integrity: sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==} engines: {node: '>=10'} - type-fest@5.7.0: - resolution: {integrity: sha512-1URUxUqfHFM1c+zfSPsa3gnkO7Aq21qyH75SIduNYz4SzY964rn1X2vCMQaHSHhktiw+0kPa2iyb6PUpXqB6Vg==} - engines: {node: '>=20'} - type-is@1.6.18: resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} engines: {node: '>= 0.6'} @@ -6418,11 +5828,8 @@ packages: unrs-resolver@1.12.2: resolution: {integrity: sha512-dmlRxBJJayXjqTwC+JtF1HhJmgf3ftQ3YejFcZrf4+KKtJv0qDsK1pjqaaVjG7wJ5NJ6UVP1OqRMQ71Z4C3rxQ==} - until-async@3.0.2: - resolution: {integrity: sha512-IiSk4HlzAMqTUseHHe3VhIGyuFmN90zMTpD3Z3y8jeQbzLIq500MVM7Jq2vUAnTKAFPJrqwkzr6PoTcPhGcOiw==} - - update-browserslist-db@1.2.3: - resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==} + update-browserslist-db@1.3.1: + resolution: {integrity: sha512-ZZ61DsRsOnakl74HAmp3oSN4aXUmEWXf+i/yv0h7tIBfICc3VdrFErQKUUKPgu3AMsTUMbcongALEN4l6GSUrQ==} hasBin: true peerDependencies: browserslist: '>= 4.21.0' @@ -6444,9 +5851,6 @@ packages: resolution: {integrity: sha512-xZe/16rV4aa+HGSOCiY2YeLT1OybRLrrkL/Rqaq7p7GMVXjFh+6wN4oMYgjFmnSnhY8t6Xpdl2l9qmnHYuMHwQ==} hasBin: true - v8-compile-cache-lib@3.0.1: - resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} - v8-to-istanbul@9.3.0: resolution: {integrity: sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==} engines: {node: '>=10.12.0'} @@ -6458,90 +5862,6 @@ packages: resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} engines: {node: '>= 0.8'} - vite@8.1.2: - resolution: {integrity: sha512-6YYPbRXTxx6bRXmOn7XdnQAy5DQNHhDgtjhDHI13oe4pY93kkcdGJWxpGwOm++/Wh0QpQhDrpIoVMrmrsI5AGQ==} - engines: {node: ^20.19.0 || >=22.12.0} - hasBin: true - peerDependencies: - '@types/node': ^20.19.0 || >=22.12.0 - '@vitejs/devtools': ^0.3.0 - esbuild: ^0.27.0 || ^0.28.0 - jiti: '>=1.21.0' - less: ^4.0.0 - sass: ^1.70.0 - sass-embedded: ^1.70.0 - stylus: '>=0.54.8' - sugarss: ^5.0.0 - terser: ^5.16.0 - tsx: ^4.8.1 - yaml: '>=2.9.0 <3.0.0' - peerDependenciesMeta: - '@types/node': - optional: true - '@vitejs/devtools': - optional: true - esbuild: - optional: true - jiti: - optional: true - less: - optional: true - sass: - optional: true - sass-embedded: - optional: true - stylus: - optional: true - sugarss: - optional: true - terser: - optional: true - tsx: - optional: true - yaml: - optional: true - - vitest@4.1.9: - resolution: {integrity: sha512-nE3/LEyc0z87uHYLZebqCUOaJr2hdtuPp7BQ4BosVFnfltxgAvMG08NyrSGlPpOUWvR27c5flSmYFTNr78L9GQ==} - 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.9 - '@vitest/browser-preview': 4.1.9 - '@vitest/browser-webdriverio': 4.1.9 - '@vitest/coverage-istanbul': 4.1.9 - '@vitest/coverage-v8': 4.1.9 - '@vitest/ui': 4.1.9 - happy-dom: '*' - jsdom: '*' - vite: ^6.0.0 || ^7.0.0 || ^8.0.0 - peerDependenciesMeta: - '@edge-runtime/vm': - optional: true - '@opentelemetry/api': - optional: true - '@types/node': - optional: true - '@vitest/browser-playwright': - optional: true - '@vitest/browser-preview': - optional: true - '@vitest/browser-webdriverio': - optional: true - '@vitest/coverage-istanbul': - optional: true - '@vitest/coverage-v8': - optional: true - '@vitest/ui': - optional: true - happy-dom: - optional: true - jsdom: - optional: true - w3c-xmlserializer@5.0.0: resolution: {integrity: sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==} engines: {node: '>=18'} @@ -6680,11 +6000,6 @@ packages: engines: {node: '>= 8'} hasBin: true - why-is-node-running@2.3.0: - resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} - engines: {node: '>=8'} - hasBin: true - wildcard@2.0.1: resolution: {integrity: sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==} @@ -6711,8 +6026,8 @@ packages: resolution: {integrity: sha512-OTIk8iR8/aCRWBqvxrzxR0hgxWpnYBblY1S5hDWBQfk/VFmJwzmJgQFN3WsoUKHISv2eAwe+PpbUzyL1CKTLXg==} engines: {node: ^20.17.0 || >=22.9.0} - ws@8.21.0: - resolution: {integrity: sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==} + ws@8.21.3: + resolution: {integrity: sha512-201TZ/kPWxoPr/OKWjquZR1SWKXcvxdH+e1xrx89b3YbmzLMFCLfnaG1HFIgWzJOEWZ7MvpK++odZufgYR50Rw==} engines: {node: '>=10.0.0'} peerDependencies: bufferutil: ^4.0.1 @@ -6754,10 +6069,6 @@ packages: resolution: {integrity: sha512-GZtjxm/J/4TSxuL3FNYjCmLktBTnIw/rVmKSIyKeYAZpmJB2ig9VauCC5xsa82GNKVKDAqpOn3KVzNt0zmrU0g==} engines: {node: '>=12'} - yn@3.1.1: - resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} - engines: {node: '>=6'} - yocto-queue@0.1.0: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} @@ -6792,7 +6103,7 @@ snapshots: '@babel/core@7.29.7': dependencies: '@babel/code-frame': 7.29.7 - '@babel/generator': 7.29.7 + '@babel/generator': 7.29.8 '@babel/helper-compilation-targets': 7.29.7 '@babel/helper-module-transforms': 7.29.7(@babel/core@7.29.7) '@babel/helpers': 7.29.7 @@ -6825,7 +6136,7 @@ snapshots: gensync: 1.0.0-beta.2 import-meta-resolve: 4.2.0 json5: 2.2.3 - obug: 2.1.3 + obug: 2.1.4 semver: 7.8.5 '@babel/eslint-parser@7.29.7(@babel/core@7.29.7)(eslint@9.39.5(jiti@2.7.0))': @@ -6836,14 +6147,6 @@ snapshots: eslint-visitor-keys: 2.1.0 semver: 6.3.1 - '@babel/generator@7.29.7': - dependencies: - '@babel/parser': 7.29.7 - '@babel/types': 7.29.7 - '@jridgewell/gen-mapping': 0.3.13 - '@jridgewell/trace-mapping': 0.3.31 - jsesc: 3.1.0 - '@babel/generator@7.29.8': dependencies: '@babel/parser': 7.29.8 @@ -6869,7 +6172,7 @@ snapshots: dependencies: '@babel/compat-data': 7.29.7 '@babel/helper-validator-option': 7.29.7 - browserslist: 4.28.4 + browserslist: 4.28.8 lru-cache: 5.1.1 semver: 6.3.1 @@ -6877,8 +6180,8 @@ snapshots: dependencies: '@babel/compat-data': 8.0.0 '@babel/helper-validator-option': 8.0.0 - browserslist: 4.28.4 - lru-cache: 11.5.1 + browserslist: 4.28.8 + lru-cache: 11.5.2 semver: 7.8.5 '@babel/helper-create-class-features-plugin@8.0.1(@babel/core@8.0.1)': @@ -7000,10 +6303,6 @@ snapshots: '@babel/template': 8.0.0 '@babel/types': 8.0.4 - '@babel/parser@7.29.7': - dependencies: - '@babel/types': 7.29.7 - '@babel/parser@7.29.8': dependencies: '@babel/types': 7.29.8 @@ -7540,7 +6839,7 @@ snapshots: '@babel/plugin-transform-unicode-sets-regex': 8.0.1(@babel/core@8.0.1) '@babel/preset-modules': 0.2.0(@babel/core@8.0.1) babel-plugin-polyfill-corejs3: 1.0.0(@babel/core@8.0.1) - core-js-compat: 3.49.0 + core-js-compat: 3.50.0 semver: 7.8.5 '@babel/preset-modules@0.2.0(@babel/core@8.0.1)': @@ -7604,12 +6903,7 @@ snapshots: '@babel/parser': 8.0.4 '@babel/template': 8.0.0 '@babel/types': 8.0.4 - obug: 2.1.3 - - '@babel/types@7.29.7': - dependencies: - '@babel/helper-string-parser': 7.29.7 - '@babel/helper-validator-identifier': 7.29.7 + obug: 2.1.4 '@babel/types@7.29.8': dependencies: @@ -7623,9 +6917,6 @@ snapshots: '@bcoe/v8-coverage@0.2.3': {} - '@bcoe/v8-coverage@1.0.2': - optional: true - '@cacheable/memory@2.2.0': dependencies: '@cacheable/utils': 2.5.0 @@ -7638,12 +6929,7 @@ snapshots: hashery: 1.5.1 keyv: 5.6.0 - '@colordx/core@5.5.0': {} - - '@cspotcode/source-map-support@0.8.1': - dependencies: - '@jridgewell/trace-mapping': 0.3.9 - optional: true + '@colordx/core@5.6.0': {} '@csstools/color-helpers@5.1.0': {} @@ -7652,7 +6938,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.2.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0)': + '@csstools/css-calc@3.3.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 @@ -7672,7 +6958,7 @@ snapshots: dependencies: '@csstools/css-tokenizer': 4.0.0 - '@csstools/css-syntax-patches-for-csstree@1.1.6(css-tree@3.2.1)': + '@csstools/css-syntax-patches-for-csstree@1.1.8(css-tree@3.2.1)': optionalDependencies: css-tree: 3.2.1 @@ -7759,17 +7045,17 @@ snapshots: dependencies: postcss: 8.5.26 - '@csstools/selector-resolve-nested@4.0.1(postcss-selector-parser@7.1.4)': + '@csstools/selector-resolve-nested@4.0.1(postcss-selector-parser@7.1.5)': dependencies: - postcss-selector-parser: 7.1.4 + postcss-selector-parser: 7.1.5 '@csstools/selector-specificity@2.2.0(postcss-selector-parser@6.1.4)': dependencies: postcss-selector-parser: 6.1.4 - '@csstools/selector-specificity@6.0.0(postcss-selector-parser@7.1.4)': + '@csstools/selector-specificity@6.0.0(postcss-selector-parser@7.1.5)': dependencies: - postcss-selector-parser: 7.1.4 + postcss-selector-parser: 7.1.5 '@discoveryjs/json-ext@0.6.3': {} @@ -7781,35 +7067,19 @@ snapshots: tslib: 2.8.1 optional: true - '@emnapi/core@1.11.1': - dependencies: - '@emnapi/wasi-threads': 1.2.2 - tslib: 2.8.1 - optional: true - '@emnapi/runtime@1.10.0': dependencies: tslib: 2.8.1 optional: true - '@emnapi/runtime@1.11.1': - dependencies: - tslib: 2.8.1 - optional: true - '@emnapi/wasi-threads@1.2.1': dependencies: tslib: 2.8.1 optional: true - '@emnapi/wasi-threads@1.2.2': - dependencies: - tslib: 2.8.1 - optional: true - '@epic-web/invariant@1.0.0': {} - '@eslint-community/eslint-utils@4.9.1(eslint@9.39.5(jiti@2.7.0))': + '@eslint-community/eslint-utils@4.10.1(eslint@9.39.5(jiti@2.7.0))': dependencies: eslint: 9.39.5(jiti@2.7.0) eslint-visitor-keys: 3.4.3 @@ -7882,38 +7152,6 @@ snapshots: '@humanwhocodes/retry@0.4.3': {} - '@inquirer/ansi@2.0.7': - optional: true - - '@inquirer/confirm@6.1.1(@types/node@26.2.0)': - dependencies: - '@inquirer/core': 11.2.1(@types/node@26.2.0) - '@inquirer/type': 4.0.7(@types/node@26.2.0) - optionalDependencies: - '@types/node': 26.2.0 - optional: true - - '@inquirer/core@11.2.1(@types/node@26.2.0)': - dependencies: - '@inquirer/ansi': 2.0.7 - '@inquirer/figures': 2.0.7 - '@inquirer/type': 4.0.7(@types/node@26.2.0) - cli-width: 4.1.0 - fast-wrap-ansi: 0.2.2 - mute-stream: 3.0.0 - signal-exit: 4.1.0 - optionalDependencies: - '@types/node': 26.2.0 - optional: true - - '@inquirer/figures@2.0.7': - optional: true - - '@inquirer/type@4.0.7(@types/node@26.2.0)': - optionalDependencies: - '@types/node': 26.2.0 - optional: true - '@isaacs/cliui@8.0.2': dependencies: string-width: 5.1.2 @@ -7942,7 +7180,7 @@ snapshots: jest-util: 30.4.1 slash: 3.0.0 - '@jest/core@30.4.2(ts-node@10.9.2(@swc/core@1.16.1)(@types/node@26.2.0)(typescript@5.9.3))': + '@jest/core@30.4.2': dependencies: '@jest/console': 30.4.1 '@jest/pattern': 30.4.0 @@ -7958,7 +7196,7 @@ snapshots: fast-json-stable-stringify: 2.1.0 graceful-fs: 4.2.11 jest-changed-files: 30.4.1 - jest-config: 30.4.2(@types/node@26.2.0)(ts-node@10.9.2(@swc/core@1.16.1)(@types/node@26.2.0)(typescript@5.9.3)) + jest-config: 30.4.2(@types/node@26.2.0) jest-haste-map: 30.4.1 jest-message-util: 30.4.1 jest-regex-util: 30.4.0 @@ -8060,7 +7298,7 @@ snapshots: '@jest/schemas@30.4.1': dependencies: - '@sinclair/typebox': 0.34.49 + '@sinclair/typebox': 0.34.52 '@jest/snapshot-utils@30.4.1': dependencies: @@ -8140,12 +7378,6 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.5 - '@jridgewell/trace-mapping@0.3.9': - dependencies: - '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.5 - optional: true - '@jsonjoy.com/base64@1.1.2(tslib@2.8.1)': dependencies: tslib: 2.8.1 @@ -8170,58 +7402,59 @@ snapshots: dependencies: tslib: 2.8.1 - '@jsonjoy.com/fs-core@4.57.8(tslib@2.8.1)': + '@jsonjoy.com/fs-core@4.68.1(tslib@2.8.1)': dependencies: - '@jsonjoy.com/fs-node-builtins': 4.57.8(tslib@2.8.1) - '@jsonjoy.com/fs-node-utils': 4.57.8(tslib@2.8.1) - thingies: 2.6.0(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.68.1(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.68.1(tslib@2.8.1) + thingies: 2.6.1(tslib@2.8.1) tslib: 2.8.1 - '@jsonjoy.com/fs-fsa@4.57.8(tslib@2.8.1)': + '@jsonjoy.com/fs-fsa@4.68.1(tslib@2.8.1)': dependencies: - '@jsonjoy.com/fs-core': 4.57.8(tslib@2.8.1) - '@jsonjoy.com/fs-node-builtins': 4.57.8(tslib@2.8.1) - '@jsonjoy.com/fs-node-utils': 4.57.8(tslib@2.8.1) - thingies: 2.6.0(tslib@2.8.1) + '@jsonjoy.com/fs-core': 4.68.1(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.68.1(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.68.1(tslib@2.8.1) + thingies: 2.6.1(tslib@2.8.1) tslib: 2.8.1 - '@jsonjoy.com/fs-node-builtins@4.57.8(tslib@2.8.1)': + '@jsonjoy.com/fs-node-builtins@4.68.1(tslib@2.8.1)': dependencies: tslib: 2.8.1 - '@jsonjoy.com/fs-node-to-fsa@4.57.8(tslib@2.8.1)': + '@jsonjoy.com/fs-node-to-fsa@4.68.1(tslib@2.8.1)': dependencies: - '@jsonjoy.com/fs-fsa': 4.57.8(tslib@2.8.1) - '@jsonjoy.com/fs-node-builtins': 4.57.8(tslib@2.8.1) - '@jsonjoy.com/fs-node-utils': 4.57.8(tslib@2.8.1) + '@jsonjoy.com/fs-fsa': 4.68.1(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.68.1(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.68.1(tslib@2.8.1) tslib: 2.8.1 - '@jsonjoy.com/fs-node-utils@4.57.8(tslib@2.8.1)': + '@jsonjoy.com/fs-node-utils@4.68.1(tslib@2.8.1)': dependencies: - '@jsonjoy.com/fs-node-builtins': 4.57.8(tslib@2.8.1) - tslib: 2.8.1 - - '@jsonjoy.com/fs-node@4.57.8(tslib@2.8.1)': - dependencies: - '@jsonjoy.com/fs-core': 4.57.8(tslib@2.8.1) - '@jsonjoy.com/fs-node-builtins': 4.57.8(tslib@2.8.1) - '@jsonjoy.com/fs-node-utils': 4.57.8(tslib@2.8.1) - '@jsonjoy.com/fs-print': 4.57.8(tslib@2.8.1) - '@jsonjoy.com/fs-snapshot': 4.57.8(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.68.1(tslib@2.8.1) glob-to-regex.js: 1.2.0(tslib@2.8.1) - thingies: 2.6.0(tslib@2.8.1) tslib: 2.8.1 - '@jsonjoy.com/fs-print@4.57.8(tslib@2.8.1)': + '@jsonjoy.com/fs-node@4.68.1(tslib@2.8.1)': dependencies: - '@jsonjoy.com/fs-node-utils': 4.57.8(tslib@2.8.1) + '@jsonjoy.com/fs-core': 4.68.1(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.68.1(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.68.1(tslib@2.8.1) + '@jsonjoy.com/fs-print': 4.68.1(tslib@2.8.1) + '@jsonjoy.com/fs-snapshot': 4.68.1(tslib@2.8.1) + glob-to-regex.js: 1.2.0(tslib@2.8.1) + thingies: 2.6.1(tslib@2.8.1) + tslib: 2.8.1 + + '@jsonjoy.com/fs-print@4.68.1(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/fs-node-utils': 4.68.1(tslib@2.8.1) tree-dump: 1.1.0(tslib@2.8.1) tslib: 2.8.1 - '@jsonjoy.com/fs-snapshot@4.57.8(tslib@2.8.1)': + '@jsonjoy.com/fs-snapshot@4.68.1(tslib@2.8.1)': dependencies: '@jsonjoy.com/buffers': 17.67.0(tslib@2.8.1) - '@jsonjoy.com/fs-node-utils': 4.57.8(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.68.1(tslib@2.8.1) '@jsonjoy.com/json-pack': 17.67.0(tslib@2.8.1) '@jsonjoy.com/util': 17.67.0(tslib@2.8.1) tslib: 2.8.1 @@ -8234,7 +7467,7 @@ snapshots: '@jsonjoy.com/json-pointer': 1.0.2(tslib@2.8.1) '@jsonjoy.com/util': 1.9.0(tslib@2.8.1) hyperdyperid: 1.2.0 - thingies: 2.6.0(tslib@2.8.1) + thingies: 2.6.1(tslib@2.8.1) tree-dump: 1.1.0(tslib@2.8.1) tslib: 2.8.1 @@ -8246,7 +7479,7 @@ snapshots: '@jsonjoy.com/json-pointer': 17.67.0(tslib@2.8.1) '@jsonjoy.com/util': 17.67.0(tslib@2.8.1) hyperdyperid: 1.2.0 - thingies: 2.6.0(tslib@2.8.1) + thingies: 2.6.1(tslib@2.8.1) tree-dump: 1.1.0(tslib@2.8.1) tslib: 2.8.1 @@ -8287,30 +7520,13 @@ snapshots: '@mdn/browser-compat-data@6.1.5': {} - '@mswjs/interceptors@0.41.9': - dependencies: - '@open-draft/deferred-promise': 2.2.0 - '@open-draft/logger': 0.3.0 - '@open-draft/until': 2.1.0 - is-node-process: 1.2.0 - outvariant: 1.4.3 - strict-event-emitter: 0.5.1 - optional: true - - '@napi-rs/wasm-runtime@1.1.6(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)': + '@napi-rs/wasm-runtime@1.2.3(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)': dependencies: '@emnapi/core': 1.10.0 '@emnapi/runtime': 1.10.0 '@tybys/wasm-util': 0.10.3 optional: true - '@napi-rs/wasm-runtime@1.1.6(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)': - dependencies: - '@emnapi/core': 1.11.1 - '@emnapi/runtime': 1.11.1 - '@tybys/wasm-util': 0.10.3 - optional: true - '@nicolo-ribaudo/eslint-scope-5-internals@5.1.1-v1': dependencies: eslint-scope: 5.1.1 @@ -8329,96 +7545,78 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.20.1 - '@open-draft/deferred-promise@2.2.0': - optional: true - - '@open-draft/deferred-promise@3.0.0': - optional: true - - '@open-draft/logger@0.3.0': + '@peculiar/asn1-cms@2.9.4': dependencies: - is-node-process: 1.2.0 - outvariant: 1.4.3 - optional: true - - '@open-draft/until@2.1.0': - optional: true - - '@oxc-project/types@0.137.0': - optional: true - - '@peculiar/asn1-cms@2.8.0': - dependencies: - '@peculiar/asn1-schema': 2.8.0 - '@peculiar/asn1-x509': 2.8.0 - '@peculiar/asn1-x509-attr': 2.8.0 + '@peculiar/asn1-schema': 2.9.4 + '@peculiar/asn1-x509': 2.9.4 + '@peculiar/asn1-x509-attr': 2.9.4 asn1js: 3.0.10 tslib: 2.8.1 - '@peculiar/asn1-csr@2.8.0': + '@peculiar/asn1-csr@2.9.4': dependencies: - '@peculiar/asn1-schema': 2.8.0 - '@peculiar/asn1-x509': 2.8.0 + '@peculiar/asn1-schema': 2.9.4 + '@peculiar/asn1-x509': 2.9.4 asn1js: 3.0.10 tslib: 2.8.1 - '@peculiar/asn1-ecc@2.8.0': + '@peculiar/asn1-ecc@2.9.4': dependencies: - '@peculiar/asn1-schema': 2.8.0 - '@peculiar/asn1-x509': 2.8.0 + '@peculiar/asn1-schema': 2.9.4 + '@peculiar/asn1-x509': 2.9.4 asn1js: 3.0.10 tslib: 2.8.1 - '@peculiar/asn1-pfx@2.8.0': + '@peculiar/asn1-pfx@2.9.4': dependencies: - '@peculiar/asn1-cms': 2.8.0 - '@peculiar/asn1-pkcs8': 2.8.0 - '@peculiar/asn1-rsa': 2.8.0 - '@peculiar/asn1-schema': 2.8.0 + '@peculiar/asn1-cms': 2.9.4 + '@peculiar/asn1-pkcs8': 2.9.4 + '@peculiar/asn1-rsa': 2.9.4 + '@peculiar/asn1-schema': 2.9.4 asn1js: 3.0.10 tslib: 2.8.1 - '@peculiar/asn1-pkcs8@2.8.0': + '@peculiar/asn1-pkcs8@2.9.4': dependencies: - '@peculiar/asn1-schema': 2.8.0 - '@peculiar/asn1-x509': 2.8.0 + '@peculiar/asn1-schema': 2.9.4 + '@peculiar/asn1-x509': 2.9.4 asn1js: 3.0.10 tslib: 2.8.1 - '@peculiar/asn1-pkcs9@2.8.0': + '@peculiar/asn1-pkcs9@2.9.4': dependencies: - '@peculiar/asn1-cms': 2.8.0 - '@peculiar/asn1-pfx': 2.8.0 - '@peculiar/asn1-pkcs8': 2.8.0 - '@peculiar/asn1-schema': 2.8.0 - '@peculiar/asn1-x509': 2.8.0 - '@peculiar/asn1-x509-attr': 2.8.0 + '@peculiar/asn1-cms': 2.9.4 + '@peculiar/asn1-pfx': 2.9.4 + '@peculiar/asn1-pkcs8': 2.9.4 + '@peculiar/asn1-schema': 2.9.4 + '@peculiar/asn1-x509': 2.9.4 + '@peculiar/asn1-x509-attr': 2.9.4 asn1js: 3.0.10 tslib: 2.8.1 - '@peculiar/asn1-rsa@2.8.0': + '@peculiar/asn1-rsa@2.9.4': dependencies: - '@peculiar/asn1-schema': 2.8.0 - '@peculiar/asn1-x509': 2.8.0 + '@peculiar/asn1-schema': 2.9.4 + '@peculiar/asn1-x509': 2.9.4 asn1js: 3.0.10 tslib: 2.8.1 - '@peculiar/asn1-schema@2.8.0': + '@peculiar/asn1-schema@2.9.4': dependencies: '@peculiar/utils': 2.0.3 asn1js: 3.0.10 tslib: 2.8.1 - '@peculiar/asn1-x509-attr@2.8.0': + '@peculiar/asn1-x509-attr@2.9.4': dependencies: - '@peculiar/asn1-schema': 2.8.0 - '@peculiar/asn1-x509': 2.8.0 + '@peculiar/asn1-schema': 2.9.4 + '@peculiar/asn1-x509': 2.9.4 asn1js: 3.0.10 tslib: 2.8.1 - '@peculiar/asn1-x509@2.8.0': + '@peculiar/asn1-x509@2.9.4': dependencies: - '@peculiar/asn1-schema': 2.8.0 + '@peculiar/asn1-schema': 2.9.4 '@peculiar/utils': 2.0.3 asn1js: 3.0.10 tslib: 2.8.1 @@ -8429,13 +7627,13 @@ snapshots: '@peculiar/x509@1.14.3': dependencies: - '@peculiar/asn1-cms': 2.8.0 - '@peculiar/asn1-csr': 2.8.0 - '@peculiar/asn1-ecc': 2.8.0 - '@peculiar/asn1-pkcs9': 2.8.0 - '@peculiar/asn1-rsa': 2.8.0 - '@peculiar/asn1-schema': 2.8.0 - '@peculiar/asn1-x509': 2.8.0 + '@peculiar/asn1-cms': 2.9.4 + '@peculiar/asn1-csr': 2.9.4 + '@peculiar/asn1-ecc': 2.9.4 + '@peculiar/asn1-pkcs9': 2.9.4 + '@peculiar/asn1-rsa': 2.9.4 + '@peculiar/asn1-schema': 2.9.4 + '@peculiar/asn1-x509': 2.9.4 pvtsutils: 1.3.6 reflect-metadata: 0.2.2 tslib: 2.8.1 @@ -8448,61 +7646,9 @@ snapshots: '@polka/url@1.0.0-next.29': {} - '@rolldown/binding-android-arm64@1.1.3': - optional: true - - '@rolldown/binding-darwin-arm64@1.1.3': - optional: true - - '@rolldown/binding-darwin-x64@1.1.3': - optional: true - - '@rolldown/binding-freebsd-x64@1.1.3': - optional: true - - '@rolldown/binding-linux-arm-gnueabihf@1.1.3': - optional: true - - '@rolldown/binding-linux-arm64-gnu@1.1.3': - optional: true - - '@rolldown/binding-linux-arm64-musl@1.1.3': - optional: true - - '@rolldown/binding-linux-ppc64-gnu@1.1.3': - optional: true - - '@rolldown/binding-linux-s390x-gnu@1.1.3': - optional: true - - '@rolldown/binding-linux-x64-gnu@1.1.3': - optional: true - - '@rolldown/binding-linux-x64-musl@1.1.3': - optional: true - - '@rolldown/binding-openharmony-arm64@1.1.3': - optional: true - - '@rolldown/binding-wasm32-wasi@1.1.3': - dependencies: - '@emnapi/core': 1.11.1 - '@emnapi/runtime': 1.11.1 - '@napi-rs/wasm-runtime': 1.1.6(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1) - optional: true - - '@rolldown/binding-win32-arm64-msvc@1.1.3': - optional: true - - '@rolldown/binding-win32-x64-msvc@1.1.3': - optional: true - - '@rolldown/pluginutils@1.0.1': - optional: true - '@rtsao/scc@1.1.0': {} - '@sinclair/typebox@0.34.49': {} + '@sinclair/typebox@0.34.52': {} '@sindresorhus/merge-streams@4.0.0': {} @@ -8518,72 +7664,6 @@ snapshots: dependencies: size-limit: 13.0.3 - '@standard-schema/spec@1.1.0': - optional: true - - '@swc/core-darwin-arm64@1.16.1': - optional: true - - '@swc/core-darwin-x64@1.16.1': - optional: true - - '@swc/core-linux-arm-gnueabihf@1.16.1': - optional: true - - '@swc/core-linux-arm64-gnu@1.16.1': - optional: true - - '@swc/core-linux-arm64-musl@1.16.1': - optional: true - - '@swc/core-linux-ppc64-gnu@1.16.1': - optional: true - - '@swc/core-linux-s390x-gnu@1.16.1': - optional: true - - '@swc/core-linux-x64-gnu@1.16.1': - optional: true - - '@swc/core-linux-x64-musl@1.16.1': - optional: true - - '@swc/core-win32-arm64-msvc@1.16.1': - optional: true - - '@swc/core-win32-ia32-msvc@1.16.1': - optional: true - - '@swc/core-win32-x64-msvc@1.16.1': - optional: true - - '@swc/core@1.16.1': - dependencies: - '@swc/counter': 0.1.3 - '@swc/types': 0.1.28 - optionalDependencies: - '@swc/core-darwin-arm64': 1.16.1 - '@swc/core-darwin-x64': 1.16.1 - '@swc/core-linux-arm-gnueabihf': 1.16.1 - '@swc/core-linux-arm64-gnu': 1.16.1 - '@swc/core-linux-arm64-musl': 1.16.1 - '@swc/core-linux-ppc64-gnu': 1.16.1 - '@swc/core-linux-s390x-gnu': 1.16.1 - '@swc/core-linux-x64-gnu': 1.16.1 - '@swc/core-linux-x64-musl': 1.16.1 - '@swc/core-win32-arm64-msvc': 1.16.1 - '@swc/core-win32-ia32-msvc': 1.16.1 - '@swc/core-win32-x64-msvc': 1.16.1 - optional: true - - '@swc/counter@0.1.3': - optional: true - - '@swc/types@0.1.28': - dependencies: - '@swc/counter': 0.1.3 - optional: true - '@testing-library/dom@8.20.1': dependencies: '@babel/code-frame': 7.29.7 @@ -8595,7 +7675,7 @@ snapshots: lz-string: 1.5.0 pretty-format: 27.5.1 - '@testing-library/jest-dom@7.0.1(@testing-library/dom@8.20.1)(vitest@4.1.9)': + '@testing-library/jest-dom@7.0.1(@testing-library/dom@8.20.1)': dependencies: '@adobe/css-tools': 4.5.0 '@testing-library/dom': 8.20.1 @@ -8604,26 +7684,12 @@ snapshots: dom-accessibility-api: 0.6.3 picocolors: 1.1.1 redent: 3.0.0 - optionalDependencies: - vitest: 4.1.9(@types/node@26.2.0)(@vitest/coverage-v8@4.1.9)(jsdom@26.1.0)(msw@2.14.6(@types/node@26.2.0)(typescript@5.9.3))(vite@8.1.2(@types/node@26.2.0)(jiti@2.7.0)(terser@5.48.0)(yaml@2.9.0)) '@testing-library/preact@3.2.4(preact@10.29.8)': dependencies: '@testing-library/dom': 8.20.1 preact: 10.29.8 - '@tsconfig/node10@1.0.12': - optional: true - - '@tsconfig/node12@1.0.11': - optional: true - - '@tsconfig/node14@1.0.3': - optional: true - - '@tsconfig/node16@1.0.4': - optional: true - '@tybys/wasm-util@0.10.3': dependencies: tslib: 2.8.1 @@ -8633,24 +7699,24 @@ snapshots: '@types/babel__core@7.20.5': dependencies: - '@babel/parser': 7.29.7 - '@babel/types': 7.29.7 + '@babel/parser': 7.29.8 + '@babel/types': 7.29.8 '@types/babel__generator': 7.27.0 '@types/babel__template': 7.4.4 '@types/babel__traverse': 7.28.0 '@types/babel__generator@7.27.0': dependencies: - '@babel/types': 7.29.7 + '@babel/types': 7.29.8 '@types/babel__template@7.4.4': dependencies: - '@babel/parser': 7.29.7 - '@babel/types': 7.29.7 + '@babel/parser': 7.29.8 + '@babel/types': 7.29.8 '@types/babel__traverse@7.28.0': dependencies: - '@babel/types': 7.29.7 + '@babel/types': 7.29.8 '@types/body-parser@1.19.6': dependencies: @@ -8661,30 +7727,15 @@ snapshots: dependencies: '@types/node': 26.2.0 - '@types/chai@5.2.3': - dependencies: - '@types/deep-eql': 4.0.2 - assertion-error: 2.0.1 - optional: true - '@types/connect-history-api-fallback@1.5.4': dependencies: - '@types/express-serve-static-core': 5.1.3 + '@types/express-serve-static-core': 4.19.9 '@types/node': 26.2.0 '@types/connect@3.4.38': dependencies: '@types/node': 26.2.0 - '@types/deep-eql@4.0.2': - optional: true - - '@types/eslint@8.56.12': - dependencies: - '@types/estree': 1.0.9 - '@types/json-schema': 7.0.15 - optional: true - '@types/estree@1.0.9': {} '@types/express-serve-static-core@4.19.9': @@ -8694,13 +7745,6 @@ snapshots: '@types/range-parser': 1.2.7 '@types/send': 1.2.1 - '@types/express-serve-static-core@5.1.3': - dependencies: - '@types/node': 26.2.0 - '@types/qs': 6.15.1 - '@types/range-parser': 1.2.7 - '@types/send': 1.2.1 - '@types/express@4.17.25': dependencies: '@types/body-parser': 1.19.6 @@ -8708,12 +7752,6 @@ snapshots: '@types/qs': 6.15.1 '@types/serve-static': 1.15.10 - '@types/express@5.0.6': - dependencies: - '@types/body-parser': 1.19.6 - '@types/express-serve-static-core': 5.1.3 - '@types/serve-static': 2.2.0 - '@types/gensync@1.0.5': {} '@types/glob@7.2.0': @@ -8758,9 +7796,9 @@ snapshots: '@types/lodash-es@4.17.12': dependencies: - '@types/lodash': 4.17.24 + '@types/lodash': 4.17.25 - '@types/lodash@4.17.24': {} + '@types/lodash@4.17.25': {} '@types/mime@1.3.5': {} @@ -8793,7 +7831,7 @@ snapshots: '@types/serve-index@1.9.4': dependencies: - '@types/express': 5.0.6 + '@types/express': 4.17.25 '@types/serve-static@1.15.10': dependencies: @@ -8801,25 +7839,12 @@ snapshots: '@types/node': 26.2.0 '@types/send': 0.17.6 - '@types/serve-static@2.2.0': - dependencies: - '@types/http-errors': 2.0.5 - '@types/node': 26.2.0 - - '@types/set-cookie-parser@2.4.10': - dependencies: - '@types/node': 26.2.0 - optional: true - '@types/sockjs@0.3.36': dependencies: '@types/node': 26.2.0 '@types/stack-utils@2.0.3': {} - '@types/statuses@2.0.6': - optional: true - '@types/tough-cookie@4.0.5': {} '@types/webpack-env@1.18.8': {} @@ -8843,7 +7868,7 @@ snapshots: '@typescript-eslint/utils': 8.67.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3) '@typescript-eslint/visitor-keys': 8.67.0 eslint: 9.39.5(jiti@2.7.0) - ignore: 7.0.5 + ignore: 7.0.6 natural-compare: 1.4.0 ts-api-utils: 2.5.0(typescript@5.9.3) typescript: 5.9.3 @@ -8901,7 +7926,7 @@ snapshots: '@typescript-eslint/types': 8.67.0 '@typescript-eslint/visitor-keys': 8.67.0 debug: 4.4.3 - minimatch: 10.2.5 + minimatch: 10.2.6 semver: 7.8.5 tinyglobby: 0.2.17 ts-api-utils: 2.5.0(typescript@5.9.3) @@ -8911,7 +7936,7 @@ snapshots: '@typescript-eslint/utils@8.67.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3)': dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.5(jiti@2.7.0)) + '@eslint-community/eslint-utils': 4.10.1(eslint@9.39.5(jiti@2.7.0)) '@typescript-eslint/scope-manager': 8.67.0 '@typescript-eslint/types': 8.67.0 '@typescript-eslint/typescript-estree': 8.67.0(typescript@5.9.3) @@ -8927,7 +7952,7 @@ snapshots: '@ungap/custom-elements@1.3.0': {} - '@ungap/structured-clone@1.3.2': {} + '@ungap/structured-clone@1.3.3': {} '@unrs/resolver-binding-android-arm-eabi@1.12.2': optional: true @@ -8987,7 +8012,7 @@ snapshots: dependencies: '@emnapi/core': 1.10.0 '@emnapi/runtime': 1.10.0 - '@napi-rs/wasm-runtime': 1.1.6(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) + '@napi-rs/wasm-runtime': 1.2.3(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) optional: true '@unrs/resolver-binding-win32-arm64-msvc@1.12.2': @@ -8999,70 +8024,6 @@ snapshots: '@unrs/resolver-binding-win32-x64-msvc@1.12.2': optional: true - '@vitest/coverage-v8@4.1.9(vitest@4.1.9)': - dependencies: - '@bcoe/v8-coverage': 1.0.2 - '@vitest/utils': 4.1.9 - ast-v8-to-istanbul: 1.0.4 - istanbul-lib-coverage: 3.2.2 - istanbul-lib-report: 3.0.1 - istanbul-reports: 3.2.0 - magicast: 0.5.3 - obug: 2.1.3 - std-env: 4.1.0 - tinyrainbow: 3.1.0 - vitest: 4.1.9(@types/node@26.2.0)(@vitest/coverage-v8@4.1.9)(jsdom@26.1.0)(msw@2.14.6(@types/node@26.2.0)(typescript@5.9.3))(vite@8.1.2(@types/node@26.2.0)(jiti@2.7.0)(terser@5.48.0)(yaml@2.9.0)) - optional: true - - '@vitest/expect@4.1.9': - dependencies: - '@standard-schema/spec': 1.1.0 - '@types/chai': 5.2.3 - '@vitest/spy': 4.1.9 - '@vitest/utils': 4.1.9 - chai: 6.2.2 - tinyrainbow: 3.1.0 - optional: true - - '@vitest/mocker@4.1.9(msw@2.14.6(@types/node@26.2.0)(typescript@5.9.3))(vite@8.1.2(@types/node@26.2.0)(jiti@2.7.0)(terser@5.48.0)(yaml@2.9.0))': - dependencies: - '@vitest/spy': 4.1.9 - estree-walker: 3.0.3 - magic-string: 0.30.21 - optionalDependencies: - msw: 2.14.6(@types/node@26.2.0)(typescript@5.9.3) - vite: 8.1.2(@types/node@26.2.0)(jiti@2.7.0)(terser@5.48.0)(yaml@2.9.0) - optional: true - - '@vitest/pretty-format@4.1.9': - dependencies: - tinyrainbow: 3.1.0 - optional: true - - '@vitest/runner@4.1.9': - dependencies: - '@vitest/utils': 4.1.9 - pathe: 2.0.3 - optional: true - - '@vitest/snapshot@4.1.9': - dependencies: - '@vitest/pretty-format': 4.1.9 - '@vitest/utils': 4.1.9 - magic-string: 0.30.21 - pathe: 2.0.3 - optional: true - - '@vitest/spy@4.1.9': - optional: true - - '@vitest/utils@4.1.9': - dependencies: - '@vitest/pretty-format': 4.1.9 - convert-source-map: 2.0.0 - tinyrainbow: 3.1.0 - optional: true - '@webassemblyjs/ast@1.14.1': dependencies: '@webassemblyjs/helper-numbers': 1.13.2 @@ -9148,15 +8109,15 @@ snapshots: mime-types: 2.1.35 negotiator: 0.6.3 - acorn-jsx@5.3.2(acorn@8.17.0): + acorn-jsx@5.3.2(acorn@8.18.0): dependencies: - acorn: 8.17.0 + acorn: 8.18.0 acorn-walk@8.3.5: dependencies: - acorn: 8.17.0 + acorn: 8.18.0 - acorn@8.17.0: {} + acorn@8.18.0: {} agent-base@7.1.4: {} @@ -9199,7 +8160,7 @@ snapshots: ansi-regex@5.0.1: {} - ansi-regex@6.2.2: {} + ansi-regex@6.3.0: {} ansi-styles@3.2.1: dependencies: @@ -9218,9 +8179,6 @@ snapshots: normalize-path: 3.0.0 picomatch: 2.3.2 - arg@4.1.3: - optional: true - argparse@1.0.10: dependencies: sprintf-js: 1.0.3 @@ -9311,33 +8269,23 @@ snapshots: asn1js@3.0.10: dependencies: pvtsutils: 1.3.6 - pvutils: 1.1.5 + pvutils: 1.2.0 tslib: 2.8.1 - assertion-error@2.0.1: - optional: true - ast-metadata-inferer@0.8.1: dependencies: '@mdn/browser-compat-data': 5.7.6 ast-types-flow@0.0.8: {} - ast-v8-to-istanbul@1.0.4: - dependencies: - '@jridgewell/trace-mapping': 0.3.31 - estree-walker: 3.0.3 - js-tokens: 10.0.0 - optional: true - astral-regex@2.0.0: {} async-function@1.0.0: {} - autoprefixer@10.5.2(postcss@8.5.26): + autoprefixer@10.5.4(postcss@8.5.26): dependencies: - browserslist: 4.28.4 - caniuse-lite: 1.0.30001800 + browserslist: 4.28.8 + caniuse-lite: 1.0.30001809 fraction.js: 5.3.4 picocolors: 1.1.1 postcss: 8.5.26 @@ -9347,7 +8295,7 @@ snapshots: dependencies: possible-typed-array-names: 1.1.0 - axe-core@4.12.1: {} + axe-core@4.13.0: {} axobject-query@4.1.0: {} @@ -9367,7 +8315,7 @@ snapshots: '@babel/core': 8.0.1 find-up: 5.0.0 optionalDependencies: - webpack: 5.109.2(@swc/core@1.16.1)(postcss@8.5.26)(webpack-cli@7.2.2) + webpack: 5.109.2(postcss@8.5.26)(webpack-cli@7.2.2) babel-plugin-istanbul@7.0.1: dependencies: @@ -9385,7 +8333,7 @@ snapshots: dependencies: '@babel/core': 8.0.1 '@babel/helper-define-polyfill-provider': 1.0.0(@babel/core@8.0.1) - core-js-compat: 3.49.0 + core-js-compat: 3.50.0 babel-preset-current-node-syntax@1.2.0(@babel/core@8.0.1): dependencies: @@ -9416,7 +8364,7 @@ snapshots: balanced-match@4.0.4: {} - baseline-browser-mapping@2.10.40: {} + baseline-browser-mapping@2.11.17: {} batch@0.6.1: {} @@ -9441,7 +8389,7 @@ snapshots: transitivePeerDependencies: - supports-color - bonjour-service@1.4.2: + bonjour-service@1.4.4: dependencies: fast-deep-equal: 3.1.3 multicast-dns: 7.2.5 @@ -9465,13 +8413,13 @@ snapshots: dependencies: fill-range: 7.1.1 - browserslist@4.28.4: + browserslist@4.28.8: dependencies: - baseline-browser-mapping: 2.10.40 - caniuse-lite: 1.0.30001800 - electron-to-chromium: 1.5.382 - node-releases: 2.0.50 - update-browserslist-db: 1.2.3(browserslist@4.28.4) + baseline-browser-mapping: 2.11.17 + caniuse-lite: 1.0.30001809 + electron-to-chromium: 1.5.412 + node-releases: 2.0.53 + update-browserslist-db: 1.3.1(browserslist@4.28.8) bser@2.1.1: dependencies: @@ -9527,15 +8475,12 @@ snapshots: caniuse-api@3.0.0: dependencies: - browserslist: 4.28.4 - caniuse-lite: 1.0.30001800 + browserslist: 4.28.8 + caniuse-lite: 1.0.30001809 lodash.memoize: 4.1.2 lodash.uniq: 4.5.0 - caniuse-lite@1.0.30001800: {} - - chai@6.2.2: - optional: true + caniuse-lite@1.0.30001809: {} chalk@2.4.2: dependencies: @@ -9581,7 +8526,7 @@ snapshots: clean-webpack-plugin@4.0.0(webpack@5.109.2): dependencies: del: 4.1.1 - webpack: 5.109.2(@swc/core@1.16.1)(postcss@8.5.26)(webpack-cli@7.2.2) + webpack: 5.109.2(postcss@8.5.26)(webpack-cli@7.2.2) cli-cursor@4.0.0: dependencies: @@ -9592,9 +8537,6 @@ snapshots: slice-ansi: 5.0.0 string-width: 5.1.2 - cli-width@4.1.0: - optional: true - cliui@8.0.1: dependencies: string-width: 4.2.3 @@ -9625,7 +8567,7 @@ snapshots: color-name@1.1.4: {} - colord@2.9.3: {} + colord@2.10.0: {} colorette@2.0.20: {} @@ -9673,12 +8615,9 @@ snapshots: cookie@0.7.2: {} - cookie@1.1.1: - optional: true - - core-js-compat@3.49.0: + core-js-compat@3.50.0: dependencies: - browserslist: 4.28.4 + browserslist: 4.28.8 core-util-is@1.0.3: {} @@ -9700,9 +8639,6 @@ snapshots: optionalDependencies: typescript: 5.9.3 - create-require@1.1.1: - optional: true - cross-env@10.1.0: dependencies: '@epic-web/invariant': 1.0.0 @@ -9714,14 +8650,6 @@ snapshots: transitivePeerDependencies: - encoding - cross-spawn@6.0.6: - dependencies: - nice-try: 1.0.5 - path-key: 2.0.1 - semver: 5.7.2 - shebang-command: 1.2.0 - which: 1.3.1 - cross-spawn@7.0.6: dependencies: path-key: 3.1.1 @@ -9755,7 +8683,7 @@ snapshots: postcss-value-parser: 4.2.0 semver: 7.8.5 optionalDependencies: - webpack: 5.109.2(@swc/core@1.16.1)(postcss@8.5.26)(webpack-cli@7.2.2) + webpack: 5.109.2(postcss@8.5.26)(webpack-cli@7.2.2) css-minimizer-webpack-plugin@8.0.0(webpack@5.109.2): dependencies: @@ -9765,7 +8693,7 @@ snapshots: postcss: 8.5.26 schema-utils: 4.3.3 serialize-javascript: 7.1.0 - webpack: 5.109.2(@swc/core@1.16.1)(postcss@8.5.26)(webpack-cli@7.2.2) + webpack: 5.109.2(postcss@8.5.26)(webpack-cli@7.2.2) css-prefers-color-scheme@6.0.3(postcss@8.5.26): dependencies: @@ -9807,7 +8735,7 @@ snapshots: cssnano-preset-default@7.0.17(postcss@8.5.26): dependencies: - browserslist: 4.28.4 + browserslist: 4.28.8 css-declaration-sorter: 7.4.0(postcss@8.5.26) cssnano-utils: 5.0.3(postcss@8.5.26) postcss: 8.5.26 @@ -9930,7 +8858,7 @@ snapshots: default-browser-id@5.0.1: {} - default-browser@5.5.0: + default-browser@5.5.1: dependencies: bundle-name: 4.1.0 default-browser-id: 5.0.1 @@ -9965,16 +8893,10 @@ snapshots: destroy@1.2.0: {} - detect-libc@2.1.2: - optional: true - detect-newline@3.1.0: {} detect-node@2.1.0: {} - diff@4.0.4: - optional: true - dns-packet@5.6.1: dependencies: '@leichtgewicht/ip-codec': 2.0.5 @@ -10044,7 +8966,7 @@ snapshots: ee-first@1.1.1: {} - electron-to-chromium@1.5.382: {} + electron-to-chromium@1.5.412: {} emittery@0.13.1: {} @@ -10058,11 +8980,6 @@ snapshots: encodeurl@2.0.0: {} - enhanced-resolve@5.24.1: - dependencies: - graceful-fs: 4.2.11 - tapable: 2.3.3 - enhanced-resolve@5.24.5: dependencies: graceful-fs: 4.2.11 @@ -10129,7 +9046,7 @@ snapshots: object-inspect: 1.13.4 object-keys: 1.1.1 object.assign: 4.1.7 - own-keys: 1.0.1 + own-keys: 1.0.2 regexp.prototype.flags: 1.5.4 safe-array-concat: 1.1.4 safe-push-apply: 1.0.0 @@ -10162,7 +9079,7 @@ snapshots: isarray: 2.0.5 stop-iteration-iterator: 1.1.0 - es-iterator-helpers@1.3.3: + es-iterator-helpers@1.4.0: dependencies: call-bind: 1.0.9 call-bound: 1.0.4 @@ -10181,7 +9098,7 @@ snapshots: iterator.prototype: 1.1.5 math-intrinsics: 1.1.0 - es-module-lexer@2.2.0: {} + es-module-lexer@2.3.2: {} es-object-atoms@1.1.2: dependencies: @@ -10246,7 +9163,7 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.13.0(@typescript-eslint/parser@8.67.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3))(eslint-import-resolver-node@0.3.10)(eslint@9.39.5(jiti@2.7.0)): + eslint-module-utils@2.14.0(@typescript-eslint/parser@8.67.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3))(eslint-import-resolver-node@0.3.10)(eslint@9.39.5(jiti@2.7.0)): dependencies: debug: 3.2.7 optionalDependencies: @@ -10260,7 +9177,7 @@ snapshots: dependencies: '@mdn/browser-compat-data': 6.1.5 ast-metadata-inferer: 0.8.1 - browserslist: 4.28.4 + browserslist: 4.28.8 eslint: 9.39.5(jiti@2.7.0) find-up: 5.0.0 globals: 15.15.0 @@ -10278,7 +9195,7 @@ snapshots: doctrine: 2.1.0 eslint: 9.39.5(jiti@2.7.0) eslint-import-resolver-node: 0.3.10 - eslint-module-utils: 2.13.0(@typescript-eslint/parser@8.67.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3))(eslint-import-resolver-node@0.3.10)(eslint@9.39.5(jiti@2.7.0)) + eslint-module-utils: 2.14.0(@typescript-eslint/parser@8.67.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3))(eslint-import-resolver-node@0.3.10)(eslint@9.39.5(jiti@2.7.0)) hasown: 2.0.4 is-core-module: 2.16.2 is-glob: 4.0.3 @@ -10302,7 +9219,7 @@ snapshots: array-includes: 3.1.9 array.prototype.flatmap: 1.3.3 ast-types-flow: 0.0.8 - axe-core: 4.12.1 + axe-core: 4.13.0 axobject-query: 4.1.0 damerau-levenshtein: 1.0.8 emoji-regex: 9.2.2 @@ -10315,14 +9232,13 @@ snapshots: safe-regex-test: 1.1.0 string.prototype.includes: 2.0.1 - eslint-plugin-prettier@5.5.6(@types/eslint@8.56.12)(eslint-config-prettier@10.1.8(eslint@9.39.5(jiti@2.7.0)))(eslint@9.39.5(jiti@2.7.0))(prettier@3.9.6): + eslint-plugin-prettier@5.5.6(eslint-config-prettier@10.1.8(eslint@9.39.5(jiti@2.7.0)))(eslint@9.39.5(jiti@2.7.0))(prettier@3.9.6): dependencies: eslint: 9.39.5(jiti@2.7.0) prettier: 3.9.6 prettier-linter-helpers: 1.0.1 synckit: 0.11.13 optionalDependencies: - '@types/eslint': 8.56.12 eslint-config-prettier: 10.1.8(eslint@9.39.5(jiti@2.7.0)) eslint-plugin-react-hooks@5.2.0(eslint@9.39.5(jiti@2.7.0)): @@ -10336,7 +9252,7 @@ snapshots: array.prototype.flatmap: 1.3.3 array.prototype.tosorted: 1.1.4 doctrine: 2.1.0 - es-iterator-helpers: 1.3.3 + es-iterator-helpers: 1.4.0 eslint: 9.39.5(jiti@2.7.0) estraverse: 5.3.0 hasown: 2.0.4 @@ -10371,7 +9287,7 @@ snapshots: eslint@9.39.5(jiti@2.7.0): dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.5(jiti@2.7.0)) + '@eslint-community/eslint-utils': 4.10.1(eslint@9.39.5(jiti@2.7.0)) '@eslint-community/regexpp': 4.12.2 '@eslint/config-array': 0.21.2 '@eslint/config-helpers': 0.4.2 @@ -10412,8 +9328,8 @@ snapshots: espree@10.4.0: dependencies: - acorn: 8.17.0 - acorn-jsx: 5.3.2(acorn@8.17.0) + acorn: 8.18.0 + acorn-jsx: 5.3.2(acorn@8.18.0) eslint-visitor-keys: 4.2.1 esprima@4.0.1: {} @@ -10430,11 +9346,6 @@ snapshots: estraverse@5.3.0: {} - estree-walker@3.0.3: - dependencies: - '@types/estree': 1.0.9 - optional: true - esutils@2.0.3: {} etag@1.8.1: {} @@ -10471,9 +9382,6 @@ snapshots: exit-x@0.2.2: {} - expect-type@1.4.0: - optional: true - expect@30.4.1: dependencies: '@jest/expect-utils': 30.4.1 @@ -10535,21 +9443,8 @@ snapshots: fast-levenshtein@2.0.6: {} - fast-string-truncated-width@3.0.3: - optional: true - - fast-string-width@3.0.2: - dependencies: - fast-string-truncated-width: 3.0.3 - optional: true - fast-uri@4.1.2: {} - fast-wrap-ansi@0.2.2: - dependencies: - fast-string-width: 3.0.2 - optional: true - fastest-levenshtein@1.0.16: {} fastq@1.20.1: @@ -10564,9 +9459,9 @@ snapshots: dependencies: bser: 2.1.1 - fdir@6.5.0(picomatch@4.0.4): + fdir@6.5.0(picomatch@4.0.5): optionalDependencies: - picomatch: 4.0.4 + picomatch: 4.0.5 file-entry-cache@11.1.5: dependencies: @@ -10580,7 +9475,7 @@ snapshots: dependencies: loader-utils: 2.0.4 schema-utils: 3.3.0 - webpack: 5.109.2(@swc/core@1.16.1)(postcss@8.5.26)(webpack-cli@7.2.2) + webpack: 5.109.2(postcss@8.5.26)(webpack-cli@7.2.2) fill-range@7.1.1: dependencies: @@ -10610,18 +9505,18 @@ snapshots: flat-cache@4.0.1: dependencies: - flatted: 3.4.2 + flatted: 3.4.4 keyv: 4.5.4 flat-cache@6.1.23: dependencies: cacheable: 2.5.0 - flatted: 3.4.2 + flatted: 3.4.4 hookified: 1.15.1 flat@5.0.2: {} - flatted@3.4.2: {} + flatted@3.4.4: {} follow-redirects@1.16.0: {} @@ -10649,7 +9544,7 @@ snapshots: semver: 7.8.5 tapable: 2.3.3 typescript: 5.9.3 - webpack: 5.109.2(@swc/core@1.16.1)(postcss@8.5.26)(webpack-cli@7.2.2) + webpack: 5.109.2(postcss@8.5.26)(webpack-cli@7.2.2) forwarded@0.2.0: {} @@ -10777,7 +9672,7 @@ snapshots: dependencies: '@sindresorhus/merge-streams': 4.0.0 fast-glob: 3.3.3 - ignore: 7.0.5 + ignore: 7.0.6 is-path-inside: 4.0.0 micromatch: 4.0.8 slash: 5.1.0 @@ -10797,9 +9692,6 @@ snapshots: graceful-fs@4.2.11: {} - graphql@16.14.2: - optional: true - handle-thing@2.0.1: {} harmony-reflect@1.6.2: {} @@ -10836,12 +9728,6 @@ snapshots: he@1.2.0: {} - headers-polyfill@5.0.1: - dependencies: - '@types/set-cookie-parser': 2.4.10 - set-cookie-parser: 3.1.1 - optional: true - hookified@1.15.1: {} hookified@2.2.0: {} @@ -10871,7 +9757,7 @@ snapshots: he: 1.2.0 param-case: 3.0.4 relateurl: 0.2.7 - terser: 5.48.0 + terser: 5.50.0 html-tags@5.1.0: {} @@ -10883,7 +9769,7 @@ snapshots: pretty-error: 4.0.0 tapable: 2.3.3 optionalDependencies: - webpack: 5.109.2(@swc/core@1.16.1)(postcss@8.5.26)(webpack-cli@7.2.2) + webpack: 5.109.2(postcss@8.5.26)(webpack-cli@7.2.2) htmlparser2@6.1.0: dependencies: @@ -10979,7 +9865,7 @@ snapshots: ignore@5.3.2: {} - ignore@7.0.5: {} + ignore@7.0.6: {} import-fresh@3.3.1: dependencies: @@ -11018,7 +9904,7 @@ snapshots: ipaddr.js@1.9.1: {} - ipaddr.js@2.4.0: {} + ipaddr.js@2.5.0: {} is-arguments@1.2.0: dependencies: @@ -11111,9 +9997,6 @@ snapshots: is-network-error@1.3.2: {} - is-node-process@1.2.0: - optional: true - is-number-object@1.1.1: dependencies: call-bound: 1.0.4 @@ -11201,7 +10084,7 @@ snapshots: istanbul-lib-instrument@6.0.3: dependencies: '@babel/core': 8.0.1 - '@babel/parser': 7.29.7 + '@babel/parser': 7.29.8 '@istanbuljs/schema': 0.1.6 istanbul-lib-coverage: 3.2.2 semver: 7.8.5 @@ -11271,15 +10154,15 @@ snapshots: transitivePeerDependencies: - babel-plugin-macros - jest-cli@30.4.2(@types/node@26.2.0)(ts-node@10.9.2(@swc/core@1.16.1)(@types/node@26.2.0)(typescript@5.9.3)): + jest-cli@30.4.2(@types/node@26.2.0): dependencies: - '@jest/core': 30.4.2(ts-node@10.9.2(@swc/core@1.16.1)(@types/node@26.2.0)(typescript@5.9.3)) + '@jest/core': 30.4.2 '@jest/test-result': 30.4.1 '@jest/types': 30.4.1 chalk: 4.1.2 exit-x: 0.2.2 import-local: 3.2.0 - jest-config: 30.4.2(@types/node@26.2.0)(ts-node@10.9.2(@swc/core@1.16.1)(@types/node@26.2.0)(typescript@5.9.3)) + jest-config: 30.4.2(@types/node@26.2.0) jest-util: 30.4.1 jest-validate: 30.4.1 yargs: 17.7.3 @@ -11290,7 +10173,7 @@ snapshots: - supports-color - ts-node - jest-config@30.4.2(@types/node@26.2.0)(ts-node@10.9.2(@swc/core@1.16.1)(@types/node@26.2.0)(typescript@5.9.3)): + jest-config@30.4.2(@types/node@26.2.0): dependencies: '@babel/core': 8.0.1 '@jest/get-type': 30.1.0 @@ -11317,7 +10200,6 @@ snapshots: strip-json-comments: 3.1.1 optionalDependencies: '@types/node': 26.2.0 - ts-node: 10.9.2(@swc/core@1.16.1)(@types/node@26.2.0)(typescript@5.9.3) transitivePeerDependencies: - babel-plugin-macros @@ -11376,7 +10258,7 @@ snapshots: jest-regex-util: 30.4.0 jest-util: 30.4.1 jest-worker: 30.4.1 - picomatch: 4.0.4 + picomatch: 4.0.5 walker: 1.0.8 optionalDependencies: fsevents: 2.3.3 @@ -11403,7 +10285,7 @@ snapshots: chalk: 4.1.2 graceful-fs: 4.2.11 jest-util: 30.4.1 - picomatch: 4.0.4 + picomatch: 4.0.5 pretty-format: 30.4.1 slash: 3.0.0 stack-utils: 2.0.6 @@ -11489,10 +10371,10 @@ snapshots: jest-snapshot@30.4.1: dependencies: '@babel/core': 8.0.1 - '@babel/generator': 7.29.7 + '@babel/generator': 7.29.8 '@babel/plugin-syntax-jsx': 7.29.7(@babel/core@8.0.1) '@babel/plugin-syntax-typescript': 7.29.7(@babel/core@8.0.1) - '@babel/types': 7.29.7 + '@babel/types': 7.29.8 '@jest/expect-utils': 30.4.1 '@jest/get-type': 30.1.0 '@jest/snapshot-utils': 30.4.1 @@ -11517,7 +10399,7 @@ snapshots: chalk: 4.1.2 ci-info: 4.4.0 graceful-fs: 4.2.11 - picomatch: 4.0.4 + picomatch: 4.0.5 jest-validate@30.4.1: dependencies: @@ -11548,17 +10430,17 @@ snapshots: jest-worker@30.4.1: dependencies: '@types/node': 26.2.0 - '@ungap/structured-clone': 1.3.2 + '@ungap/structured-clone': 1.3.3 jest-util: 30.4.1 merge-stream: 2.0.0 supports-color: 8.1.1 - jest@30.4.2(@types/node@26.2.0)(ts-node@10.9.2(@swc/core@1.16.1)(@types/node@26.2.0)(typescript@5.9.3)): + jest@30.4.2(@types/node@26.2.0): dependencies: - '@jest/core': 30.4.2(ts-node@10.9.2(@swc/core@1.16.1)(@types/node@26.2.0)(typescript@5.9.3)) + '@jest/core': 30.4.2 '@jest/types': 30.4.1 import-local: 3.2.0 - jest-cli: 30.4.2(@types/node@26.2.0)(ts-node@10.9.2(@swc/core@1.16.1)(@types/node@26.2.0)(typescript@5.9.3)) + jest-cli: 30.4.2(@types/node@26.2.0) transitivePeerDependencies: - '@types/node' - babel-plugin-macros @@ -11603,7 +10485,7 @@ snapshots: whatwg-encoding: 3.1.1 whatwg-mimetype: 4.0.0 whatwg-url: 14.2.0 - ws: 8.21.0 + ws: 8.21.3 xml-name-validator: 5.0.0 transitivePeerDependencies: - bufferutil @@ -11662,7 +10544,7 @@ snapshots: launch-editor@2.14.1: dependencies: picocolors: 1.1.1 - shell-quote: 1.9.0 + shell-quote: 1.10.0 leven@3.1.0: {} @@ -11671,56 +10553,6 @@ snapshots: prelude-ls: 1.2.1 type-check: 0.4.0 - lightningcss-android-arm64@1.32.0: - optional: true - - lightningcss-darwin-arm64@1.32.0: - optional: true - - lightningcss-darwin-x64@1.32.0: - optional: true - - lightningcss-freebsd-x64@1.32.0: - optional: true - - lightningcss-linux-arm-gnueabihf@1.32.0: - optional: true - - lightningcss-linux-arm64-gnu@1.32.0: - optional: true - - lightningcss-linux-arm64-musl@1.32.0: - optional: true - - lightningcss-linux-x64-gnu@1.32.0: - optional: true - - lightningcss-linux-x64-musl@1.32.0: - optional: true - - lightningcss-win32-arm64-msvc@1.32.0: - optional: true - - lightningcss-win32-x64-msvc@1.32.0: - optional: true - - lightningcss@1.32.0: - dependencies: - detect-libc: 2.1.2 - optionalDependencies: - lightningcss-android-arm64: 1.32.0 - lightningcss-darwin-arm64: 1.32.0 - lightningcss-darwin-x64: 1.32.0 - lightningcss-freebsd-x64: 1.32.0 - lightningcss-linux-arm-gnueabihf: 1.32.0 - lightningcss-linux-arm64-gnu: 1.32.0 - lightningcss-linux-arm64-musl: 1.32.0 - lightningcss-linux-x64-gnu: 1.32.0 - lightningcss-linux-x64-musl: 1.32.0 - lightningcss-win32-arm64-msvc: 1.32.0 - lightningcss-win32-x64-msvc: 1.32.0 - optional: true - lilconfig@2.1.0: {} lilconfig@3.1.3: {} @@ -11807,7 +10639,7 @@ snapshots: lru-cache@10.4.3: {} - lru-cache@11.5.1: {} + lru-cache@11.5.2: {} lru-cache@5.1.1: dependencies: @@ -11815,25 +10647,10 @@ snapshots: lz-string@1.5.0: {} - magic-string@0.30.21: - dependencies: - '@jridgewell/sourcemap-codec': 1.5.5 - optional: true - - magicast@0.5.3: - dependencies: - '@babel/parser': 7.29.8 - '@babel/types': 7.29.8 - source-map-js: 1.2.1 - optional: true - make-dir@4.0.0: dependencies: semver: 7.8.5 - make-error@1.3.6: - optional: true - makeerror@1.0.12: dependencies: tmpl: 1.0.5 @@ -11852,20 +10669,20 @@ snapshots: dependencies: fs-monkey: 1.1.0 - memfs@4.57.8(tslib@2.8.1): + memfs@4.68.1: dependencies: - '@jsonjoy.com/fs-core': 4.57.8(tslib@2.8.1) - '@jsonjoy.com/fs-fsa': 4.57.8(tslib@2.8.1) - '@jsonjoy.com/fs-node': 4.57.8(tslib@2.8.1) - '@jsonjoy.com/fs-node-builtins': 4.57.8(tslib@2.8.1) - '@jsonjoy.com/fs-node-to-fsa': 4.57.8(tslib@2.8.1) - '@jsonjoy.com/fs-node-utils': 4.57.8(tslib@2.8.1) - '@jsonjoy.com/fs-print': 4.57.8(tslib@2.8.1) - '@jsonjoy.com/fs-snapshot': 4.57.8(tslib@2.8.1) + '@jsonjoy.com/fs-core': 4.68.1(tslib@2.8.1) + '@jsonjoy.com/fs-fsa': 4.68.1(tslib@2.8.1) + '@jsonjoy.com/fs-node': 4.68.1(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.68.1(tslib@2.8.1) + '@jsonjoy.com/fs-node-to-fsa': 4.68.1(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.68.1(tslib@2.8.1) + '@jsonjoy.com/fs-print': 4.68.1(tslib@2.8.1) + '@jsonjoy.com/fs-snapshot': 4.68.1(tslib@2.8.1) '@jsonjoy.com/json-pack': 1.21.0(tslib@2.8.1) '@jsonjoy.com/util': 1.9.0(tslib@2.8.1) glob-to-regex.js: 1.2.0(tslib@2.8.1) - thingies: 2.6.0(tslib@2.8.1) + thingies: 2.6.1(tslib@2.8.1) tree-dump: 1.1.0(tslib@2.8.1) tslib: 2.8.1 @@ -11910,11 +10727,11 @@ snapshots: dependencies: schema-utils: 4.3.3 tapable: 2.3.3 - webpack: 5.109.2(@swc/core@1.16.1)(postcss@8.5.26)(webpack-cli@7.2.2) + webpack: 5.109.2(postcss@8.5.26)(webpack-cli@7.2.2) minimalistic-assert@1.0.1: {} - minimatch@10.2.5: + minimatch@10.2.6: dependencies: brace-expansion: 5.0.9 @@ -11928,15 +10745,14 @@ snapshots: minimist@1.2.8: {} - minimizer-webpack-plugin@5.6.1(@swc/core@1.16.1)(postcss@8.5.26)(webpack@5.109.2): + minimizer-webpack-plugin@5.6.1(postcss@8.5.26)(webpack@5.109.2): dependencies: '@jridgewell/trace-mapping': 0.3.31 jest-worker: 27.5.1 schema-utils: 4.3.3 - terser: 5.48.0 - webpack: 5.109.2(@swc/core@1.16.1)(postcss@8.5.26)(webpack-cli@7.2.2) + terser: 5.50.0 + webpack: 5.109.2(postcss@8.5.26)(webpack-cli@7.2.2) optionalDependencies: - '@swc/core': 1.16.1 postcss: 8.5.26 minipass@7.1.3: {} @@ -11949,40 +10765,11 @@ snapshots: ms@2.1.3: {} - msw@2.14.6(@types/node@26.2.0)(typescript@5.9.3): - dependencies: - '@inquirer/confirm': 6.1.1(@types/node@26.2.0) - '@mswjs/interceptors': 0.41.9 - '@open-draft/deferred-promise': 3.0.0 - '@types/statuses': 2.0.6 - cookie: 1.1.1 - graphql: 16.14.2 - headers-polyfill: 5.0.1 - is-node-process: 1.2.0 - outvariant: 1.4.3 - path-to-regexp: 6.3.0 - picocolors: 1.1.1 - rettime: 0.11.11 - statuses: 2.0.2 - strict-event-emitter: 0.5.1 - tough-cookie: 6.0.1 - type-fest: 5.7.0 - until-async: 3.0.2 - yargs: 17.7.3 - optionalDependencies: - typescript: 5.9.3 - transitivePeerDependencies: - - '@types/node' - optional: true - multicast-dns@7.2.5: dependencies: dns-packet: 5.6.1 thunky: 1.1.0 - mute-stream@3.0.0: - optional: true - nanoid@3.3.18: {} nanospinner@1.2.2: @@ -11999,8 +10786,6 @@ snapshots: neo-async@2.6.2: {} - nice-try@1.0.5: {} - no-case@3.0.4: dependencies: lower-case: 2.0.2 @@ -12025,13 +10810,13 @@ snapshots: node-int64@0.4.0: {} - node-releases@2.0.50: {} + node-releases@2.0.53: {} normalize-package-data@2.5.0: dependencies: hosted-git-info: 2.8.9 resolve: 1.22.12 - semver: 5.7.2 + semver: 7.8.5 validate-npm-package-license: 3.0.4 normalize-path@3.0.0: {} @@ -12040,12 +10825,12 @@ snapshots: dependencies: ansi-styles: 3.2.1 chalk: 2.4.2 - cross-spawn: 6.0.6 + cross-spawn: 7.0.6 memorystream: 0.3.1 minimatch: 3.1.5 pidtree: 0.3.1 read-pkg: 3.0.0 - shell-quote: 1.9.0 + shell-quote: 1.10.0 string.prototype.padend: 3.1.6 npm-run-path@4.0.1: @@ -12111,7 +10896,7 @@ snapshots: obuf@1.1.2: {} - obug@2.1.3: {} + obug@2.1.4: {} on-finished@2.4.1: dependencies: @@ -12133,7 +10918,7 @@ snapshots: open@10.2.0: dependencies: - default-browser: 5.5.0 + default-browser: 5.5.1 define-lazy-prop: 3.0.0 is-inside-container: 1.0.0 wsl-utils: 0.1.0 @@ -12149,11 +10934,9 @@ snapshots: type-check: 0.4.0 word-wrap: 1.2.5 - outvariant@1.4.3: - optional: true - - own-keys@1.0.1: + own-keys@1.0.2: dependencies: + call-bound: 1.0.4 get-intrinsic: 1.3.0 object-keys: 1.1.1 safe-push-apply: 1.0.0 @@ -12224,8 +11007,6 @@ snapshots: path-is-inside@1.0.2: {} - path-key@2.0.1: {} - path-key@3.1.1: {} path-key@4.0.0: {} @@ -12239,23 +11020,17 @@ snapshots: path-to-regexp@0.1.13: {} - path-to-regexp@6.3.0: - optional: true - path-type@3.0.0: dependencies: pify: 3.0.0 path-type@4.0.0: {} - pathe@2.0.3: - optional: true - picocolors@1.1.1: {} picomatch@2.3.2: {} - picomatch@4.0.4: {} + picomatch@4.0.5: {} pidtree@0.3.1: {} @@ -12285,7 +11060,7 @@ snapshots: asn1js: 3.0.10 bytestreamjs: 2.0.1 pvtsutils: 1.3.6 - pvutils: 1.1.5 + pvutils: 1.2.0 tslib: 2.8.1 possible-typed-array-names@1.1.0: {} @@ -12298,7 +11073,7 @@ snapshots: postcss-calc@10.1.1(postcss@8.5.26): dependencies: postcss: 8.5.26 - postcss-selector-parser: 7.1.4 + postcss-selector-parser: 7.1.5 postcss-value-parser: 4.2.0 postcss-clamp@4.1.0(postcss@8.5.26): @@ -12323,15 +11098,15 @@ snapshots: postcss-colormin@7.0.10(postcss@8.5.26): dependencies: - '@colordx/core': 5.5.0 - browserslist: 4.28.4 + '@colordx/core': 5.6.0 + browserslist: 4.28.8 caniuse-api: 3.0.0 postcss: 8.5.26 postcss-value-parser: 4.2.0 postcss-convert-values@7.0.12(postcss@8.5.26): dependencies: - browserslist: 4.28.4 + browserslist: 4.28.8 postcss: 8.5.26 postcss-value-parser: 4.2.0 @@ -12358,7 +11133,7 @@ snapshots: postcss-discard-comments@7.0.8(postcss@8.5.26): dependencies: postcss: 8.5.26 - postcss-selector-parser: 7.1.4 + postcss-selector-parser: 7.1.5 postcss-discard-duplicates@7.0.4(postcss@8.5.26): dependencies: @@ -12430,7 +11205,7 @@ snapshots: postcss: 8.5.26 semver: 7.8.5 optionalDependencies: - webpack: 5.109.2(@swc/core@1.16.1)(postcss@8.5.26)(webpack-cli@7.2.2) + webpack: 5.109.2(postcss@8.5.26)(webpack-cli@7.2.2) transitivePeerDependencies: - typescript @@ -12450,11 +11225,11 @@ snapshots: postcss-merge-rules@7.0.11(postcss@8.5.26): dependencies: - browserslist: 4.28.4 + browserslist: 4.28.8 caniuse-api: 3.0.0 cssnano-utils: 5.0.3(postcss@8.5.26) postcss: 8.5.26 - postcss-selector-parser: 7.1.4 + postcss-selector-parser: 7.1.5 postcss-minify-font-values@7.0.3(postcss@8.5.26): dependencies: @@ -12463,25 +11238,25 @@ snapshots: postcss-minify-gradients@7.0.5(postcss@8.5.26): dependencies: - '@colordx/core': 5.5.0 + '@colordx/core': 5.6.0 cssnano-utils: 5.0.3(postcss@8.5.26) postcss: 8.5.26 postcss-value-parser: 4.2.0 postcss-minify-params@7.0.9(postcss@8.5.26): dependencies: - browserslist: 4.28.4 + browserslist: 4.28.8 cssnano-utils: 5.0.3(postcss@8.5.26) postcss: 8.5.26 postcss-value-parser: 4.2.0 postcss-minify-selectors@7.1.2(postcss@8.5.26): dependencies: - browserslist: 4.28.4 + browserslist: 4.28.8 caniuse-api: 3.0.0 cssesc: 3.0.0 postcss: 8.5.26 - postcss-selector-parser: 7.1.4 + postcss-selector-parser: 7.1.5 postcss-modules-extract-imports@3.1.0(postcss@8.5.26): dependencies: @@ -12491,13 +11266,13 @@ snapshots: dependencies: icss-utils: 5.1.0(postcss@8.5.26) postcss: 8.5.26 - postcss-selector-parser: 7.1.4 + postcss-selector-parser: 7.1.5 postcss-value-parser: 4.2.0 postcss-modules-scope@3.2.1(postcss@8.5.26): dependencies: postcss: 8.5.26 - postcss-selector-parser: 7.1.4 + postcss-selector-parser: 7.1.5 postcss-modules-values@4.0.0(postcss@8.5.26): dependencies: @@ -12541,7 +11316,7 @@ snapshots: postcss-normalize-unicode@7.0.9(postcss@8.5.26): dependencies: - browserslist: 4.28.4 + browserslist: 4.28.8 postcss: 8.5.26 postcss-value-parser: 4.2.0 @@ -12595,8 +11370,8 @@ snapshots: '@csstools/postcss-text-decoration-shorthand': 1.0.0(postcss@8.5.26) '@csstools/postcss-trigonometric-functions': 1.0.2(postcss@8.5.26) '@csstools/postcss-unset-value': 1.0.2(postcss@8.5.26) - autoprefixer: 10.5.2(postcss@8.5.26) - browserslist: 4.28.4 + autoprefixer: 10.5.4(postcss@8.5.26) + browserslist: 4.28.8 css-blank-pseudo: 3.0.3(postcss@8.5.26) css-has-pseudo: 3.0.4(postcss@8.5.26) css-prefers-color-scheme: 6.0.3(postcss@8.5.26) @@ -12639,7 +11414,7 @@ snapshots: postcss-reduce-initial@7.0.9(postcss@8.5.26): dependencies: - browserslist: 4.28.4 + browserslist: 4.28.8 caniuse-api: 3.0.0 postcss: 8.5.26 @@ -12670,7 +11445,7 @@ snapshots: cssesc: 3.0.0 util-deprecate: 1.0.2 - postcss-selector-parser@7.1.4: + postcss-selector-parser@7.1.5: dependencies: cssesc: 3.0.0 util-deprecate: 1.0.2 @@ -12684,7 +11459,7 @@ snapshots: postcss-unique-selectors@7.0.7(postcss@8.5.26): dependencies: postcss: 8.5.26 - postcss-selector-parser: 7.1.4 + postcss-selector-parser: 7.1.5 postcss-value-parser@4.2.0: {} @@ -12743,7 +11518,7 @@ snapshots: dependencies: tslib: 2.8.1 - pvutils@1.1.5: {} + pvutils@1.2.0: {} qified@0.10.1: dependencies: @@ -12915,9 +11690,6 @@ snapshots: retry@0.13.1: {} - rettime@0.11.11: - optional: true - reusify@1.1.0: {} rfdc@1.4.1: {} @@ -12926,28 +11698,6 @@ snapshots: dependencies: glob: 7.2.3 - rolldown@1.1.3: - dependencies: - '@oxc-project/types': 0.137.0 - '@rolldown/pluginutils': 1.0.1 - optionalDependencies: - '@rolldown/binding-android-arm64': 1.1.3 - '@rolldown/binding-darwin-arm64': 1.1.3 - '@rolldown/binding-darwin-x64': 1.1.3 - '@rolldown/binding-freebsd-x64': 1.1.3 - '@rolldown/binding-linux-arm-gnueabihf': 1.1.3 - '@rolldown/binding-linux-arm64-gnu': 1.1.3 - '@rolldown/binding-linux-arm64-musl': 1.1.3 - '@rolldown/binding-linux-ppc64-gnu': 1.1.3 - '@rolldown/binding-linux-s390x-gnu': 1.1.3 - '@rolldown/binding-linux-x64-gnu': 1.1.3 - '@rolldown/binding-linux-x64-musl': 1.1.3 - '@rolldown/binding-openharmony-arm64': 1.1.3 - '@rolldown/binding-wasm32-wasi': 1.1.3 - '@rolldown/binding-win32-arm64-msvc': 1.1.3 - '@rolldown/binding-win32-x64-msvc': 1.1.3 - optional: true - rrweb-cssom@0.8.0: {} run-applescript@7.1.0: {} @@ -12981,7 +11731,7 @@ snapshots: safer-buffer@2.1.2: {} - sax@1.6.0: {} + sax@1.6.1: {} saxes@6.0.0: dependencies: @@ -13007,8 +11757,6 @@ snapshots: '@peculiar/x509': 1.14.3 pkijs: 3.4.0 - semver@5.7.2: {} - semver@6.3.1: {} semver@7.8.5: {} @@ -13054,9 +11802,6 @@ snapshots: transitivePeerDependencies: - supports-color - set-cookie-parser@3.1.1: - optional: true - set-function-length@1.2.2: dependencies: define-data-property: 1.1.4 @@ -13085,19 +11830,13 @@ snapshots: dependencies: kind-of: 6.0.3 - shebang-command@1.2.0: - dependencies: - shebang-regex: 1.0.0 - shebang-command@2.0.0: dependencies: shebang-regex: 3.0.0 - shebang-regex@1.0.0: {} - shebang-regex@3.0.0: {} - shell-quote@1.9.0: {} + shell-quote@1.10.0: {} side-channel-list@1.0.1: dependencies: @@ -13127,9 +11866,6 @@ snapshots: side-channel-map: 1.0.1 side-channel-weakmap: 1.0.2 - siginfo@2.0.0: - optional: true - signal-exit@3.0.7: {} signal-exit@4.1.0: {} @@ -13222,24 +11958,15 @@ snapshots: dependencies: escape-string-regexp: 2.0.0 - stackback@0.0.2: - optional: true - statuses@1.5.0: {} statuses@2.0.2: {} - std-env@4.1.0: - optional: true - stop-iteration-iterator@1.1.0: dependencies: es-errors: 1.3.0 internal-slot: 1.1.0 - strict-event-emitter@0.5.1: - optional: true - string-argv@0.3.2: {} string-length@4.0.2: @@ -13336,7 +12063,7 @@ snapshots: strip-ansi@7.2.0: dependencies: - ansi-regex: 6.2.2 + ansi-regex: 6.3.0 strip-bom@3.0.0: {} @@ -13354,13 +12081,13 @@ snapshots: style-loader@4.0.0(webpack@5.109.2): dependencies: - webpack: 5.109.2(@swc/core@1.16.1)(postcss@8.5.26)(webpack-cli@7.2.2) + webpack: 5.109.2(postcss@8.5.26)(webpack-cli@7.2.2) stylehacks@7.0.11(postcss@8.5.26): dependencies: - browserslist: 4.28.4 + browserslist: 4.28.8 postcss: 8.5.26 - postcss-selector-parser: 7.1.4 + postcss-selector-parser: 7.1.5 stylelint-config-recommended@18.0.0(stylelint@17.14.1(typescript@5.9.3)): dependencies: @@ -13383,14 +12110,14 @@ snapshots: stylelint@17.14.1(typescript@5.9.3): dependencies: - '@csstools/css-calc': 3.2.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) + '@csstools/css-calc': 3.3.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.6(css-tree@3.2.1) + '@csstools/css-syntax-patches-for-csstree': 1.1.8(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.1(postcss-selector-parser@7.1.4) - '@csstools/selector-specificity': 6.0.0(postcss-selector-parser@7.1.4) - colord: 2.9.3 + '@csstools/selector-resolve-nested': 4.0.1(postcss-selector-parser@7.1.5) + '@csstools/selector-specificity': 6.0.0(postcss-selector-parser@7.1.5) + colord: 2.10.0 cosmiconfig: 9.0.2(typescript@5.9.3) css-functions-list: 3.3.3 css-tree: 3.2.1 @@ -13402,7 +12129,7 @@ snapshots: globby: 16.2.4 globjoin: 0.1.4 html-tags: 5.1.0 - ignore: 7.0.5 + ignore: 7.0.6 import-meta-resolve: 4.2.0 mathml-tag-names: 4.0.0 meow: 14.1.0 @@ -13411,7 +12138,7 @@ snapshots: picocolors: 1.1.1 postcss: 8.5.26 postcss-safe-parser: 7.0.1(postcss@8.5.26) - postcss-selector-parser: 7.1.4 + postcss-selector-parser: 7.1.5 postcss-value-parser: 4.2.0 string-width: 8.2.2 supports-hyperlinks: 4.5.0 @@ -13453,7 +12180,7 @@ snapshots: css-what: 6.2.2 csso: 5.0.5 picocolors: 1.1.1 - sax: 1.6.0 + sax: 1.6.1 symbol-tree@3.2.4: {} @@ -13469,15 +12196,12 @@ snapshots: string-width: 4.2.3 strip-ansi: 6.0.1 - tagged-tag@1.0.0: - optional: true - tapable@2.3.3: {} - terser@5.48.0: + terser@5.50.0: dependencies: '@jridgewell/source-map': 0.3.11 - acorn: 8.17.0 + acorn: 8.18.0 commander: 2.20.3 source-map-support: 0.5.21 @@ -13487,40 +12211,23 @@ snapshots: glob: 7.2.3 minimatch: 3.1.5 - thingies@2.6.0(tslib@2.8.1): + thingies@2.6.1(tslib@2.8.1): dependencies: tslib: 2.8.1 thunky@1.1.0: {} - tinybench@2.9.0: - optional: true - - tinyexec@1.2.4: - optional: true - tinyglobby@0.2.17: dependencies: - fdir: 6.5.0(picomatch@4.0.4) - picomatch: 4.0.4 - - tinyrainbow@3.1.0: - optional: true + fdir: 6.5.0(picomatch@4.0.5) + picomatch: 4.0.5 tldts-core@6.1.86: {} - tldts-core@7.4.5: - optional: true - tldts@6.1.86: dependencies: tldts-core: 6.1.86 - tldts@7.4.5: - dependencies: - tldts-core: 7.4.5 - optional: true - tmpl@1.0.5: {} to-regex-range@5.0.1: @@ -13535,11 +12242,6 @@ snapshots: dependencies: tldts: 6.1.86 - tough-cookie@6.0.1: - dependencies: - tldts: 7.4.5 - optional: true - tr46@0.0.3: {} tr46@5.1.1: @@ -13554,31 +12256,10 @@ snapshots: dependencies: typescript: 5.9.3 - ts-node@10.9.2(@swc/core@1.16.1)(@types/node@26.2.0)(typescript@5.9.3): - dependencies: - '@cspotcode/source-map-support': 0.8.1 - '@tsconfig/node10': 1.0.12 - '@tsconfig/node12': 1.0.11 - '@tsconfig/node14': 1.0.3 - '@tsconfig/node16': 1.0.4 - '@types/node': 26.2.0 - acorn: 8.17.0 - acorn-walk: 8.3.5 - arg: 4.1.3 - create-require: 1.1.1 - diff: 4.0.4 - make-error: 1.3.6 - typescript: 5.9.3 - v8-compile-cache-lib: 3.0.1 - yn: 3.1.1 - optionalDependencies: - '@swc/core': 1.16.1 - optional: true - tsconfig-paths-webpack-plugin@4.2.0: dependencies: chalk: 4.1.2 - enhanced-resolve: 5.24.1 + enhanced-resolve: 5.24.5 tapable: 2.3.3 tsconfig-paths: 4.2.0 @@ -13613,11 +12294,6 @@ snapshots: type-fest@1.4.0: {} - type-fest@5.7.0: - dependencies: - tagged-tag: 1.0.0 - optional: true - type-is@1.6.18: dependencies: media-typer: 0.3.0 @@ -13711,12 +12387,9 @@ snapshots: '@unrs/resolver-binding-win32-ia32-msvc': 1.12.2 '@unrs/resolver-binding-win32-x64-msvc': 1.12.2 - until-async@3.0.2: - optional: true - - update-browserslist-db@1.2.3(browserslist@4.28.4): + update-browserslist-db@1.3.1(browserslist@4.28.8): dependencies: - browserslist: 4.28.4 + browserslist: 4.28.8 escalade: 3.2.0 picocolors: 1.1.1 @@ -13732,9 +12405,6 @@ snapshots: uuid@14.0.2: {} - v8-compile-cache-lib@3.0.1: - optional: true - v8-to-istanbul@9.3.0: dependencies: '@jridgewell/trace-mapping': 0.3.31 @@ -13748,51 +12418,6 @@ snapshots: vary@1.1.2: {} - vite@8.1.2(@types/node@26.2.0)(jiti@2.7.0)(terser@5.48.0)(yaml@2.9.0): - dependencies: - lightningcss: 1.32.0 - picomatch: 4.0.4 - postcss: 8.5.26 - rolldown: 1.1.3 - tinyglobby: 0.2.17 - optionalDependencies: - '@types/node': 26.2.0 - fsevents: 2.3.3 - jiti: 2.7.0 - terser: 5.48.0 - yaml: 2.9.0 - optional: true - - vitest@4.1.9(@types/node@26.2.0)(@vitest/coverage-v8@4.1.9)(jsdom@26.1.0)(msw@2.14.6(@types/node@26.2.0)(typescript@5.9.3))(vite@8.1.2(@types/node@26.2.0)(jiti@2.7.0)(terser@5.48.0)(yaml@2.9.0)): - dependencies: - '@vitest/expect': 4.1.9 - '@vitest/mocker': 4.1.9(msw@2.14.6(@types/node@26.2.0)(typescript@5.9.3))(vite@8.1.2(@types/node@26.2.0)(jiti@2.7.0)(terser@5.48.0)(yaml@2.9.0)) - '@vitest/pretty-format': 4.1.9 - '@vitest/runner': 4.1.9 - '@vitest/snapshot': 4.1.9 - '@vitest/spy': 4.1.9 - '@vitest/utils': 4.1.9 - es-module-lexer: 2.2.0 - expect-type: 1.4.0 - magic-string: 0.30.21 - obug: 2.1.3 - pathe: 2.0.3 - picomatch: 4.0.4 - std-env: 4.1.0 - tinybench: 2.9.0 - tinyexec: 1.2.4 - tinyglobby: 0.2.17 - tinyrainbow: 3.1.0 - vite: 8.1.2(@types/node@26.2.0)(jiti@2.7.0)(terser@5.48.0)(yaml@2.9.0) - why-is-node-running: 2.3.0 - optionalDependencies: - '@types/node': 26.2.0 - '@vitest/coverage-v8': 4.1.9(vitest@4.1.9) - jsdom: 26.1.0 - transitivePeerDependencies: - - msw - optional: true - w3c-xmlserializer@5.0.0: dependencies: xml-name-validator: 5.0.0 @@ -13816,7 +12441,7 @@ snapshots: webpack-bundle-analyzer@5.3.1: dependencies: '@discoveryjs/json-ext': 0.6.3 - acorn: 8.17.0 + acorn: 8.18.0 acorn-walk: 8.3.5 commander: 14.0.3 escape-string-regexp: 5.0.0 @@ -13824,7 +12449,7 @@ snapshots: opener: 1.5.2 picocolors: 1.1.1 sirv: 3.0.2 - ws: 8.21.0 + ws: 8.21.3 transitivePeerDependencies: - bufferutil - utf-8-validate @@ -13838,28 +12463,26 @@ snapshots: import-local: 3.2.0 interpret: 3.1.1 rechoir: 0.8.0 - webpack: 5.109.2(@swc/core@1.16.1)(postcss@8.5.26)(webpack-cli@7.2.2) + webpack: 5.109.2(postcss@8.5.26)(webpack-cli@7.2.2) webpack-merge: 6.0.1 optionalDependencies: js-yaml: 5.3.0 json5: 2.2.3 webpack-bundle-analyzer: 5.3.1 - webpack-dev-server: 5.2.6(tslib@2.8.1)(webpack-cli@7.2.2)(webpack@5.109.2) + webpack-dev-server: 5.2.6(webpack-cli@7.2.2)(webpack@5.109.2) - webpack-dev-middleware@7.4.5(tslib@2.8.1)(webpack@5.109.2): + webpack-dev-middleware@7.4.5(webpack@5.109.2): dependencies: colorette: 2.0.20 - memfs: 4.57.8(tslib@2.8.1) + memfs: 4.68.1 mime-types: 3.0.2 on-finished: 2.4.1 range-parser: 1.3.0 schema-utils: 4.3.3 optionalDependencies: - webpack: 5.109.2(@swc/core@1.16.1)(postcss@8.5.26)(webpack-cli@7.2.2) - transitivePeerDependencies: - - tslib + webpack: 5.109.2(postcss@8.5.26)(webpack-cli@7.2.2) - webpack-dev-server@5.2.6(tslib@2.8.1)(webpack-cli@7.2.2)(webpack@5.109.2): + webpack-dev-server@5.2.6(webpack-cli@7.2.2)(webpack@5.109.2): dependencies: '@types/bonjour': 3.5.13 '@types/connect-history-api-fallback': 1.5.4 @@ -13870,7 +12493,7 @@ snapshots: '@types/sockjs': 0.3.36 '@types/ws': 8.18.1 ansi-html-community: 0.0.8 - bonjour-service: 1.4.2 + bonjour-service: 1.4.4 chokidar: 3.6.0 colorette: 2.0.20 compression: 1.8.1 @@ -13878,7 +12501,7 @@ snapshots: express: 4.22.2 graceful-fs: 4.2.11 http-proxy-middleware: 2.0.10(@types/express@4.17.25) - ipaddr.js: 2.4.0 + ipaddr.js: 2.5.0 launch-editor: 2.14.1 open: 10.2.0 p-retry: 6.2.1 @@ -13887,16 +12510,15 @@ snapshots: serve-index: 1.9.2 sockjs: 0.3.24 spdy: 4.0.2 - webpack-dev-middleware: 7.4.5(tslib@2.8.1)(webpack@5.109.2) - ws: 8.21.0 + webpack-dev-middleware: 7.4.5(webpack@5.109.2) + ws: 8.21.3 optionalDependencies: - webpack: 5.109.2(@swc/core@1.16.1)(postcss@8.5.26)(webpack-cli@7.2.2) + webpack: 5.109.2(postcss@8.5.26)(webpack-cli@7.2.2) webpack-cli: 7.2.2(js-yaml@5.3.0)(json5@2.2.3)(webpack-bundle-analyzer@5.3.1)(webpack-dev-server@5.2.6)(webpack@5.109.2) transitivePeerDependencies: - bufferutil - debug - supports-color - - tslib - utf-8-validate webpack-merge@6.0.1: @@ -13907,23 +12529,23 @@ snapshots: webpack-sources@3.5.1: {} - webpack@5.109.2(@swc/core@1.16.1)(postcss@8.5.26)(webpack-cli@7.2.2): + webpack@5.109.2(postcss@8.5.26)(webpack-cli@7.2.2): dependencies: '@types/estree': 1.0.9 '@types/json-schema': 7.0.15 '@webassemblyjs/ast': 1.14.1 '@webassemblyjs/wasm-edit': 1.14.1 '@webassemblyjs/wasm-parser': 1.14.1 - acorn: 8.17.0 - browserslist: 4.28.4 + acorn: 8.18.0 + browserslist: 4.28.8 chrome-trace-event: 1.0.4 enhanced-resolve: 5.24.5 - es-module-lexer: 2.2.0 + es-module-lexer: 2.3.2 eslint-scope: 5.1.1 events: 3.3.0 graceful-fs: 4.2.11 mime-db: 1.54.0 - minimizer-webpack-plugin: 5.6.1(@swc/core@1.16.1)(postcss@8.5.26)(webpack@5.109.2) + minimizer-webpack-plugin: 5.6.1(postcss@8.5.26)(webpack@5.109.2) neo-async: 2.6.2 schema-utils: 4.3.3 tapable: 2.3.3 @@ -14018,12 +12640,6 @@ snapshots: dependencies: isexe: 2.0.0 - why-is-node-running@2.3.0: - dependencies: - siginfo: 2.0.0 - stackback: 0.0.2 - optional: true - wildcard@2.0.1: {} word-wrap@1.2.5: {} @@ -14051,7 +12667,7 @@ snapshots: dependencies: signal-exit: 4.1.0 - ws@8.21.0: {} + ws@8.21.3: {} wsl-utils@0.1.0: dependencies: @@ -14079,7 +12695,4 @@ snapshots: y18n: 5.0.8 yargs-parser: 21.1.1 - yn@3.1.1: - optional: true - yocto-queue@0.1.0: {} diff --git a/frontend/apps/remark42/templates/comments.ejs b/frontend/apps/remark42/templates/comments.ejs index 2de9a26f..1efcdc6a 100644 --- a/frontend/apps/remark42/templates/comments.ejs +++ b/frontend/apps/remark42/templates/comments.ejs @@ -63,7 +63,17 @@ })(); if (query.site_id && query.url) { var titleElement = document.getElementById('title'); - titleElement.innerHTML = 'Comments for ' + query.url + ''; + // built through the DOM rather than innerHTML: query.url is attacker-controlled and this + // page is a top-level document on the instance origin, so an injected script would run + // there rather than inside the sandboxed widget frame + var link = document.createElement('a'); + link.textContent = query.url; + // and only http(s) reaches href, or a javascript: url survives the escaping + if (/^https?:\/\//i.test(query.url)) { + link.href = query.url; + } + titleElement.textContent = 'Comments for '; + titleElement.appendChild(link); var remark_config = { site_id: query.site_id, host: '<%= htmlWebpackPlugin.options.REMARK_URL %>', diff --git a/frontend/apps/remark42/templates/iframe.ejs b/frontend/apps/remark42/templates/iframe.ejs index 17c3e159..abf61bad 100644 --- a/frontend/apps/remark42/templates/iframe.ejs +++ b/frontend/apps/remark42/templates/iframe.ejs @@ -75,6 +75,10 @@