diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 42645aa492d5..63f79fa100e6 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -50,7 +50,7 @@ If you open a pull request for a new feature, we're likely to close it not becau ## Coding standards -Our code formatting rules are defined in the `"prettier"` section of [package.json](https://github.com/tailwindcss/tailwindcss/blob/main/package.json). You can check your code against these standards by running: +Our code formatting rules are defined in the `"prettier"` section of [package.json](https://github.com/tailwindlabs/tailwindcss/blob/main/package.json). You can check your code against these standards by running: ```sh pnpm run lint @@ -76,7 +76,7 @@ To run the integration tests, use: pnpm build && pnpm test:integrations ``` -Additionally, some features require testing in browsers (i.e to ensure CSS variable resolution works as expected). These can be run via: +Additionally, some features require testing in browsers (i.e. to ensure CSS variable resolution works as expected). These can be run via: ```sh pnpm build && pnpm test:ui diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index ee9d3f9abcc0..aa0793aa39f8 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -8,7 +8,7 @@ It's never a fun experience to have your pull request declined after investing a For more info, check out the contributing guide: -https://github.com/tailwindcss/tailwindcss/blob/main/.github/CONTRIBUTING.md +https://github.com/tailwindlabs/tailwindcss/blob/main/.github/CONTRIBUTING.md --> diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d8c099873b64..fca477c08bec 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,6 +11,10 @@ permissions: env: NODE_VERSION: 24 +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: tests: strategy: @@ -106,9 +110,13 @@ jobs: - name: Run Playwright tests run: npm run test:ui + notify: + if: ${{ always() && github.ref == 'refs/heads/main' && needs.tests.result == 'failure' }} + needs: tests + runs-on: ubuntu-latest + steps: - name: Notify Discord - if: failure() && github.ref == 'refs/heads/main' uses: discord-actions/message@v2 with: webhookUrl: ${{ secrets.DISCORD_WEBHOOK_URL }} - message: 'The [most recent build](<${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}>) on the `main` branch has failed.' + message: 'The [most recent ${{ github.workflow }} workflow](<${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}>) on the `main` branch has failed.' diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index e36f5b3abc47..3b2cf8f1b80a 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -11,6 +11,10 @@ permissions: env: NODE_VERSION: 24 +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: tests: strategy: @@ -109,9 +113,13 @@ jobs: env: GITHUB_WORKSPACE: ${{ github.workspace }} + notify: + if: ${{ always() && github.ref == 'refs/heads/main' && needs.tests.result == 'failure' }} + needs: tests + runs-on: ubuntu-latest + steps: - name: Notify Discord - if: failure() && github.ref == 'refs/heads/main' uses: discord-actions/message@v2 with: webhookUrl: ${{ secrets.DISCORD_WEBHOOK_URL }} - message: 'The [most recent build](<${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}>) on the `main` branch has failed.' + message: 'The [most recent ${{ github.workflow }} workflow](<${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}>) on the `main` branch has failed.' diff --git a/.github/workflows/prepare-release.yml b/.github/workflows/prepare-release.yml index e506ab187b7a..d5ad798be455 100644 --- a/.github/workflows/prepare-release.yml +++ b/.github/workflows/prepare-release.yml @@ -14,6 +14,10 @@ env: permissions: contents: read +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: build: strategy: @@ -262,7 +266,7 @@ jobs: run: pnpm --filter=!./playgrounds/* install - name: Download artifacts - uses: actions/download-artifact@v6 + uses: actions/download-artifact@v7 with: path: ${{ env.OXIDE_LOCATION }} diff --git a/.github/workflows/release-insiders.yml b/.github/workflows/release-insiders.yml index f7792244f520..4852cce7b7a9 100644 --- a/.github/workflows/release-insiders.yml +++ b/.github/workflows/release-insiders.yml @@ -13,6 +13,10 @@ env: OXIDE_LOCATION: ./crates/node RELEASE_CHANNEL: insiders +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: build: strategy: @@ -259,7 +263,7 @@ jobs: run: pnpm --filter=!./playgrounds/* install - name: Download artifacts - uses: actions/download-artifact@v6 + uses: actions/download-artifact@v7 with: path: ${{ env.OXIDE_LOCATION }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 3b0aeab20049..a872900ff9e2 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -254,7 +254,7 @@ jobs: run: pnpm --filter=!./playgrounds/* install - name: Download artifacts - uses: actions/download-artifact@v6 + uses: actions/download-artifact@v7 with: path: ${{ env.OXIDE_LOCATION }} diff --git a/.prettierignore b/.prettierignore index 3de4530ddcf2..4f50b932fbca 100644 --- a/.prettierignore +++ b/.prettierignore @@ -4,5 +4,6 @@ pnpm-lock.yaml target/ crates/node/index.d.ts crates/node/index.js +crates/ignore/ .next .fingerprint diff --git a/CHANGELOG.md b/CHANGELOG.md index b66ebaea00dd..dd549036ed0f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,18 +7,51 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Added + +- _Experimental_: Add `@container-size` utility ([#18901](https://github.com/tailwindlabs/tailwindcss/pull/18901)) + +### Fixed + +- Allow trailing dash in functional utility names for backwards compatibility ([#19696](https://github.com/tailwindlabs/tailwindcss/pull/19696)) +- Fix missing extracted classes in mdx files containing `.` ([#19711](https://github.com/tailwindlabs/tailwindcss/pull/19711)) + +## [4.2.0] - 2026-02-18 + +### Added + +- Add mauve, olive, mist, and taupe color palettes to the default theme ([#19627](https://github.com/tailwindlabs/tailwindcss/pull/19627)) +- Add `@tailwindcss/webpack` package to run Tailwind CSS as a webpack plugin ([#19610](https://github.com/tailwindlabs/tailwindcss/pull/19610)) +- Add `pbs-*` and `pbe-*` utilities for `padding-block-start` and `padding-block-end` ([#19601](https://github.com/tailwindlabs/tailwindcss/pull/19601)) +- Add `mbs-*` and `mbe-*` utilities for `margin-block-start` and `margin-block-end` ([#19601](https://github.com/tailwindlabs/tailwindcss/pull/19601)) +- Add `scroll-pbs-*` and `scroll-pbe-*` utilities for `scroll-padding-block-start` and `scroll-padding-block-end` ([#19601](https://github.com/tailwindlabs/tailwindcss/pull/19601)) +- Add `scroll-mbs-*` and `scroll-mbe-*` utilities for `scroll-margin-block-start` and `scroll-margin-block-end` ([#19601](https://github.com/tailwindlabs/tailwindcss/pull/19601)) +- Add `border-bs-*` and `border-be-*` utilities for `border-block-start` and `border-block-end` ([#19601](https://github.com/tailwindlabs/tailwindcss/pull/19601)) +- Add `inline-*`, `min-inline-*`, `max-inline-*` utilities for `inline-size`, `min-inline-size`, and `max-inline-size` ([#19612](https://github.com/tailwindlabs/tailwindcss/pull/19612)) +- Add `block-*`, `min-block-*`, `max-block-*` utilities for `block-size`, `min-block-size`, and `max-block-size` ([#19612](https://github.com/tailwindlabs/tailwindcss/pull/19612)) +- Add `inset-s-*`, `inset-e-*`, `inset-bs-*`, `inset-be-*` utilities for `inset-inline-start`, `inset-inline-end`, `inset-block-start`, and `inset-block-end` ([#19613](https://github.com/tailwindlabs/tailwindcss/pull/19613)) +- Add `font-features-*` utility for `font-feature-settings` ([#19623](https://github.com/tailwindlabs/tailwindcss/pull/19615)) + ### Fixed -- Do not wrap `color-mix` in a `@supports` rule if one already exists ([#19450](https://github.com/tailwindlabs/tailwindcss/pull/19450)) +- Prevent double `@supports` wrapper for `color-mix` values ([#19450](https://github.com/tailwindlabs/tailwindcss/pull/19450)) - Allow whitespace around `@source inline()` argument ([#19461](https://github.com/tailwindlabs/tailwindcss/pull/19461)) -- CLI: Emit comment when source maps are saved to files ([#19447](https://github.com/tailwindlabs/tailwindcss/pull/19447)) -- Detect utilities when containing capital letters followed by numbers ([#19465](https://github.com/tailwindlabs/tailwindcss/pull/19465)) +- Emit comment when source maps are saved to files when using `@tailwindcss/cli` ([#19447](https://github.com/tailwindlabs/tailwindcss/pull/19447)) +- Detect utilities containing capital letters followed by numbers ([#19465](https://github.com/tailwindlabs/tailwindcss/pull/19465)) - Fix class extraction for Rails' strict locals ([#19525](https://github.com/tailwindlabs/tailwindcss/pull/19525)) - Align `@utility` name validation with Oxide scanner rules ([#19524](https://github.com/tailwindlabs/tailwindcss/pull/19524)) +- Fix infinite loop when using `@variant` inside `@custom-variant` ([#19633](https://github.com/tailwindlabs/tailwindcss/pull/19633)) +- Allow multiples of `.25` in `aspect-*` fractions (e.g. `aspect-8.5/11`) ([#19688](https://github.com/tailwindlabs/tailwindcss/pull/19688)) +- Ensure changes to external files listed via `@source` trigger a full page reload when using `@tailwindcss/vite` ([#19670](https://github.com/tailwindlabs/tailwindcss/pull/19670)) +- Improve performance of Oxide scanner in bigger projects by reducing file system walks ([#19632](https://github.com/tailwindlabs/tailwindcss/pull/19632)) +- Ensure import aliases in Astro v5 work without crashing when using `@tailwindcss/vite` ([#19677](https://github.com/tailwindlabs/tailwindcss/issues/19677)) +- Allow escape characters in `@utility` names to improve support with formatters such as Biome ([#19626](https://github.com/tailwindlabs/tailwindcss/pull/19626)) +- Fix incorrect canonicalization results when canonicalizing multiple times ([#19675](https://github.com/tailwindlabs/tailwindcss/pull/19675)) +- Add `.jj` to default ignored content directories ([#19687](https://github.com/tailwindlabs/tailwindcss/pull/19687)) -### Added +### Deprecated -- _Experimental_: Add `@container-size` utility ([#18901](https://github.com/tailwindlabs/tailwindcss/pull/18901)) +- Deprecate `start-*` and `end-*` utilities in favor of `inset-s-*` and `inset-e-*` utilities ([#19613](https://github.com/tailwindlabs/tailwindcss/pull/19613)) ## [4.1.18] - 2025-12-11 @@ -3913,7 +3946,8 @@ No release notes - Everything! -[unreleased]: https://github.com/tailwindlabs/tailwindcss/compare/v4.1.18...HEAD +[unreleased]: https://github.com/tailwindlabs/tailwindcss/compare/v4.2.0...HEAD +[4.2.0]: https://github.com/tailwindlabs/tailwindcss/compare/v4.1.18...v4.2.0 [4.1.18]: https://github.com/tailwindlabs/tailwindcss/compare/v4.1.17...v4.1.18 [3.4.19]: https://github.com/tailwindlabs/tailwindcss/compare/v3.4.18...v3.4.19 [4.1.17]: https://github.com/tailwindlabs/tailwindcss/compare/v4.1.16...v4.1.17 diff --git a/README.md b/README.md index 7d21bd88385a..5f532607d00a 100644 --- a/README.md +++ b/README.md @@ -13,10 +13,10 @@

- Build Status + Build Status Total Downloads - Latest Release - License + Latest Release + License

--- @@ -29,8 +29,8 @@ For full documentation, visit [tailwindcss.com](https://tailwindcss.com). For help, discussion about best practices, or feature ideas: -[Discuss Tailwind CSS on GitHub](https://github.com/tailwindcss/tailwindcss/discussions) +[Discuss Tailwind CSS on GitHub](https://github.com/tailwindlabs/tailwindcss/discussions) ## Contributing -If you're interested in contributing to Tailwind CSS, please read our [contributing docs](https://github.com/tailwindcss/tailwindcss/blob/next/.github/CONTRIBUTING.md) **before submitting a pull request**. +If you're interested in contributing to Tailwind CSS, please read our [contributing docs](https://github.com/tailwindlabs/tailwindcss/blob/main/.github/CONTRIBUTING.md) **before submitting a pull request**. diff --git a/crates/node/npm/android-arm-eabi/package.json b/crates/node/npm/android-arm-eabi/package.json index 47df39f4ec30..cba6fedce0b2 100644 --- a/crates/node/npm/android-arm-eabi/package.json +++ b/crates/node/npm/android-arm-eabi/package.json @@ -1,6 +1,6 @@ { "name": "@tailwindcss/oxide-android-arm-eabi", - "version": "4.1.18", + "version": "4.2.0", "repository": { "type": "git", "url": "git+https://github.com/tailwindlabs/tailwindcss.git", diff --git a/crates/node/npm/android-arm64/package.json b/crates/node/npm/android-arm64/package.json index a2d8231abb28..0950b7a03e95 100644 --- a/crates/node/npm/android-arm64/package.json +++ b/crates/node/npm/android-arm64/package.json @@ -1,6 +1,6 @@ { "name": "@tailwindcss/oxide-android-arm64", - "version": "4.1.18", + "version": "4.2.0", "repository": { "type": "git", "url": "git+https://github.com/tailwindlabs/tailwindcss.git", diff --git a/crates/node/npm/darwin-arm64/package.json b/crates/node/npm/darwin-arm64/package.json index 153b2306fe9c..423333d61dcf 100644 --- a/crates/node/npm/darwin-arm64/package.json +++ b/crates/node/npm/darwin-arm64/package.json @@ -1,6 +1,6 @@ { "name": "@tailwindcss/oxide-darwin-arm64", - "version": "4.1.18", + "version": "4.2.0", "repository": { "type": "git", "url": "git+https://github.com/tailwindlabs/tailwindcss.git", diff --git a/crates/node/npm/darwin-x64/package.json b/crates/node/npm/darwin-x64/package.json index fd4fba92b312..81007674ee5c 100644 --- a/crates/node/npm/darwin-x64/package.json +++ b/crates/node/npm/darwin-x64/package.json @@ -1,6 +1,6 @@ { "name": "@tailwindcss/oxide-darwin-x64", - "version": "4.1.18", + "version": "4.2.0", "repository": { "type": "git", "url": "git+https://github.com/tailwindlabs/tailwindcss.git", diff --git a/crates/node/npm/freebsd-x64/package.json b/crates/node/npm/freebsd-x64/package.json index 89f126ba19fd..8c25927edc39 100644 --- a/crates/node/npm/freebsd-x64/package.json +++ b/crates/node/npm/freebsd-x64/package.json @@ -1,6 +1,6 @@ { "name": "@tailwindcss/oxide-freebsd-x64", - "version": "4.1.18", + "version": "4.2.0", "repository": { "type": "git", "url": "git+https://github.com/tailwindlabs/tailwindcss.git", diff --git a/crates/node/npm/linux-arm-gnueabihf/package.json b/crates/node/npm/linux-arm-gnueabihf/package.json index e0939b03718c..b2a4c0281127 100644 --- a/crates/node/npm/linux-arm-gnueabihf/package.json +++ b/crates/node/npm/linux-arm-gnueabihf/package.json @@ -1,6 +1,6 @@ { "name": "@tailwindcss/oxide-linux-arm-gnueabihf", - "version": "4.1.18", + "version": "4.2.0", "repository": { "type": "git", "url": "git+https://github.com/tailwindlabs/tailwindcss.git", diff --git a/crates/node/npm/linux-arm64-gnu/package.json b/crates/node/npm/linux-arm64-gnu/package.json index ec4d07081c52..e1855f2894c3 100644 --- a/crates/node/npm/linux-arm64-gnu/package.json +++ b/crates/node/npm/linux-arm64-gnu/package.json @@ -1,6 +1,6 @@ { "name": "@tailwindcss/oxide-linux-arm64-gnu", - "version": "4.1.18", + "version": "4.2.0", "repository": { "type": "git", "url": "git+https://github.com/tailwindlabs/tailwindcss.git", diff --git a/crates/node/npm/linux-arm64-musl/package.json b/crates/node/npm/linux-arm64-musl/package.json index 1ff8c8917ebe..c6b96ab8ab14 100644 --- a/crates/node/npm/linux-arm64-musl/package.json +++ b/crates/node/npm/linux-arm64-musl/package.json @@ -1,6 +1,6 @@ { "name": "@tailwindcss/oxide-linux-arm64-musl", - "version": "4.1.18", + "version": "4.2.0", "repository": { "type": "git", "url": "git+https://github.com/tailwindlabs/tailwindcss.git", diff --git a/crates/node/npm/linux-x64-gnu/package.json b/crates/node/npm/linux-x64-gnu/package.json index b27ebb4f169b..2d4fa6fe3c84 100644 --- a/crates/node/npm/linux-x64-gnu/package.json +++ b/crates/node/npm/linux-x64-gnu/package.json @@ -1,6 +1,6 @@ { "name": "@tailwindcss/oxide-linux-x64-gnu", - "version": "4.1.18", + "version": "4.2.0", "repository": { "type": "git", "url": "git+https://github.com/tailwindlabs/tailwindcss.git", diff --git a/crates/node/npm/linux-x64-musl/package.json b/crates/node/npm/linux-x64-musl/package.json index b38fe0792485..5855b5d6a331 100644 --- a/crates/node/npm/linux-x64-musl/package.json +++ b/crates/node/npm/linux-x64-musl/package.json @@ -1,6 +1,6 @@ { "name": "@tailwindcss/oxide-linux-x64-musl", - "version": "4.1.18", + "version": "4.2.0", "repository": { "type": "git", "url": "git+https://github.com/tailwindlabs/tailwindcss.git", diff --git a/crates/node/npm/wasm32-wasi/package.json b/crates/node/npm/wasm32-wasi/package.json index ea06f944dd16..0c1defca3a43 100644 --- a/crates/node/npm/wasm32-wasi/package.json +++ b/crates/node/npm/wasm32-wasi/package.json @@ -1,6 +1,6 @@ { "name": "@tailwindcss/oxide-wasm32-wasi", - "version": "4.1.18", + "version": "4.2.0", "cpu": [ "wasm32" ], @@ -28,11 +28,11 @@ "browser": "tailwindcss-oxide.wasi-browser.js", "dependencies": { "@napi-rs/wasm-runtime": "^1.1.1", - "@emnapi/core": "^1.7.1", - "@emnapi/runtime": "^1.7.1", + "@emnapi/core": "^1.8.1", + "@emnapi/runtime": "^1.8.1", "@tybys/wasm-util": "^0.10.1", "@emnapi/wasi-threads": "^1.1.0", - "tslib": "^2.4.0" + "tslib": "^2.8.1" }, "bundledDependencies": [ "@napi-rs/wasm-runtime", diff --git a/crates/node/npm/win32-arm64-msvc/package.json b/crates/node/npm/win32-arm64-msvc/package.json index f1ef4133a570..633a4d12eb9c 100644 --- a/crates/node/npm/win32-arm64-msvc/package.json +++ b/crates/node/npm/win32-arm64-msvc/package.json @@ -1,6 +1,6 @@ { "name": "@tailwindcss/oxide-win32-arm64-msvc", - "version": "4.1.18", + "version": "4.2.0", "repository": { "type": "git", "url": "git+https://github.com/tailwindlabs/tailwindcss.git", diff --git a/crates/node/npm/win32-x64-msvc/package.json b/crates/node/npm/win32-x64-msvc/package.json index 4049d272da2b..99dca35d18c4 100644 --- a/crates/node/npm/win32-x64-msvc/package.json +++ b/crates/node/npm/win32-x64-msvc/package.json @@ -1,6 +1,6 @@ { "name": "@tailwindcss/oxide-win32-x64-msvc", - "version": "4.1.18", + "version": "4.2.0", "repository": { "type": "git", "url": "git+https://github.com/tailwindlabs/tailwindcss.git", diff --git a/crates/node/package.json b/crates/node/package.json index 00557993d8f3..6da669ced184 100644 --- a/crates/node/package.json +++ b/crates/node/package.json @@ -1,6 +1,6 @@ { "name": "@tailwindcss/oxide", - "version": "4.1.18", + "version": "4.2.0", "repository": { "type": "git", "url": "git+https://github.com/tailwindlabs/tailwindcss.git", @@ -35,7 +35,7 @@ "devDependencies": { "@napi-rs/cli": "3.4.1", "@napi-rs/wasm-runtime": "^1.1.1", - "emnapi": "1.7.1" + "emnapi": "1.8.1" }, "engines": { "node": ">= 20" diff --git a/crates/oxide/src/cursor.rs b/crates/oxide/src/cursor.rs index 818a0ef1b450..71cdccdf6aeb 100644 --- a/crates/oxide/src/cursor.rs +++ b/crates/oxide/src/cursor.rs @@ -1,44 +1,49 @@ use std::{ascii::escape_default, fmt::Display}; -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Copy)] pub struct Cursor<'a> { // The input we're scanning pub input: &'a [u8], // The location of the cursor in the input pub pos: usize, - - /// Is the cursor at the start of the input - pub at_start: bool, - - /// Is the cursor at the end of the input - pub at_end: bool, - - /// The previously consumed character - /// If `at_start` is true, this will be NUL - pub prev: u8, - - /// The current character - pub curr: u8, - - /// The upcoming character (if any) - /// If `at_end` is true, this will be NUL - pub next: u8, } impl<'a> Cursor<'a> { + #[inline(always)] pub fn new(input: &'a [u8]) -> Self { - let mut cursor = Self { - input, - pos: 0, - at_start: true, - at_end: false, - prev: 0x00, - curr: 0x00, - next: 0x00, - }; - cursor.move_to(0); - cursor + Self { input, pos: 0 } + } + + /// The current byte at `pos`, or 0x00 if past the end. + #[inline(always)] + pub fn curr(&self) -> u8 { + if self.pos < self.input.len() { + unsafe { *self.input.get_unchecked(self.pos) } + } else { + 0x00 + } + } + + /// The next byte at `pos + 1`, or 0x00 if past the end. + #[inline(always)] + pub fn next(&self) -> u8 { + let next_pos = self.pos + 1; + if next_pos < self.input.len() { + unsafe { *self.input.get_unchecked(next_pos) } + } else { + 0x00 + } + } + + /// The previous byte at `pos - 1`, or 0x00 if at the start. + #[inline(always)] + pub fn prev(&self) -> u8 { + if self.pos > 0 { + unsafe { *self.input.get_unchecked(self.pos - 1) } + } else { + 0x00 + } } pub fn advance_by(&mut self, amount: usize) { @@ -48,38 +53,15 @@ impl<'a> Cursor<'a> { #[inline(always)] pub fn advance(&mut self) { self.pos += 1; - - self.prev = self.curr; - self.curr = self.next; - self.next = *self - .input - .get(self.pos.saturating_add(1)) - .unwrap_or(&0x00u8); } #[inline(always)] pub fn advance_twice(&mut self) { self.pos += 2; - - self.prev = self.next; - self.curr = *self.input.get(self.pos).unwrap_or(&0x00u8); - self.next = *self - .input - .get(self.pos.saturating_add(1)) - .unwrap_or(&0x00u8); } pub fn move_to(&mut self, pos: usize) { - let len = self.input.len(); - let pos = pos.clamp(0, len); - - self.pos = pos; - self.at_start = pos == 0; - self.at_end = pos + 1 >= len; - - self.prev = *self.input.get(pos.wrapping_sub(1)).unwrap_or(&0x00u8); - self.curr = *self.input.get(pos).unwrap_or(&0x00u8); - self.next = *self.input.get(pos.saturating_add(1)).unwrap_or(&0x00u8); + self.pos = pos.min(self.input.len()); } } @@ -90,9 +72,9 @@ impl Display for Cursor<'_> { let pos = format!("{: >len_count$}", self.pos, len_count = len.len()); write!(f, "{}/{} ", pos, len)?; - if self.at_start { + if self.pos == 0 { write!(f, "S ")?; - } else if self.at_end { + } else if self.pos + 1 >= self.input.len() { write!(f, "E ")?; } else { write!(f, "M ")?; @@ -109,9 +91,9 @@ impl Display for Cursor<'_> { write!( f, "[{} {} {}]", - to_str(self.prev), - to_str(self.curr), - to_str(self.next) + to_str(self.prev()), + to_str(self.curr()), + to_str(self.next()) ) } } @@ -125,36 +107,28 @@ mod test { fn test_cursor() { let mut cursor = Cursor::new(b"hello world"); assert_eq!(cursor.pos, 0); - assert!(cursor.at_start); - assert!(!cursor.at_end); - assert_eq!(cursor.prev, 0x00); - assert_eq!(cursor.curr, b'h'); - assert_eq!(cursor.next, b'e'); + assert_eq!(cursor.prev(), 0x00); + assert_eq!(cursor.curr(), b'h'); + assert_eq!(cursor.next(), b'e'); cursor.advance_by(1); assert_eq!(cursor.pos, 1); - assert!(!cursor.at_start); - assert!(!cursor.at_end); - assert_eq!(cursor.prev, b'h'); - assert_eq!(cursor.curr, b'e'); - assert_eq!(cursor.next, b'l'); + assert_eq!(cursor.prev(), b'h'); + assert_eq!(cursor.curr(), b'e'); + assert_eq!(cursor.next(), b'l'); // Advancing too far should stop at the end cursor.advance_by(10); assert_eq!(cursor.pos, 11); - assert!(!cursor.at_start); - assert!(cursor.at_end); - assert_eq!(cursor.prev, b'd'); - assert_eq!(cursor.curr, 0x00); - assert_eq!(cursor.next, 0x00); + assert_eq!(cursor.prev(), b'd'); + assert_eq!(cursor.curr(), 0x00); + assert_eq!(cursor.next(), 0x00); // Can't advance past the end cursor.advance_by(1); assert_eq!(cursor.pos, 11); - assert!(!cursor.at_start); - assert!(cursor.at_end); - assert_eq!(cursor.prev, b'd'); - assert_eq!(cursor.curr, 0x00); - assert_eq!(cursor.next, 0x00); + assert_eq!(cursor.prev(), b'd'); + assert_eq!(cursor.curr(), 0x00); + assert_eq!(cursor.next(), 0x00); } } diff --git a/crates/oxide/src/extractor/arbitrary_property_machine.rs b/crates/oxide/src/extractor/arbitrary_property_machine.rs index 8fd13e39405f..a4325333925c 100644 --- a/crates/oxide/src/extractor/arbitrary_property_machine.rs +++ b/crates/oxide/src/extractor/arbitrary_property_machine.rs @@ -74,7 +74,7 @@ impl Machine for ArbitraryPropertyMachine { #[inline] fn next(&mut self, cursor: &mut cursor::Cursor<'_>) -> MachineState { - match cursor.curr.into() { + match cursor.curr().into() { // Start of an arbitrary property Class::OpenBracket => { self.start_pos = cursor.pos; @@ -97,8 +97,8 @@ impl Machine for ArbitraryPropertyMachine { let len = cursor.input.len(); while cursor.pos < len { - match cursor.curr.into() { - Class::Dash => match cursor.next.into() { + match cursor.curr().into() { + Class::Dash => match cursor.next().into() { // Start of a CSS variable // // E.g.: `[--my-color:red]` @@ -137,7 +137,7 @@ impl ArbitraryPropertyMachine { fn parse_property_variable(&mut self, cursor: &mut cursor::Cursor<'_>) -> MachineState { match self.css_variable_machine.next(cursor) { MachineState::Idle => self.restart(), - MachineState::Done(_) => match cursor.next.into() { + MachineState::Done(_) => match cursor.next().into() { // End of the CSS variable, must be followed by a `:` // // E.g.: `[--my-color:red]` @@ -165,8 +165,8 @@ impl Machine for ArbitraryPropertyMachine { let len = cursor.input.len(); let start_of_value_pos = cursor.pos; while cursor.pos < len { - match cursor.curr.into() { - Class::Escape => match cursor.next.into() { + match cursor.curr().into() { + Class::Escape => match cursor.next().into() { // An escaped whitespace character is not allowed // // E.g.: `[color:var(--my-\ color)]` @@ -181,7 +181,7 @@ impl Machine for ArbitraryPropertyMachine { }, Class::OpenParen | Class::OpenBracket | Class::OpenCurly => { - if !self.bracket_stack.push(cursor.curr) { + if !self.bracket_stack.push(cursor.curr()) { return self.restart(); } cursor.advance(); @@ -190,7 +190,7 @@ impl Machine for ArbitraryPropertyMachine { Class::CloseParen | Class::CloseBracket | Class::CloseCurly if !self.bracket_stack.is_empty() => { - if !self.bracket_stack.pop(cursor.curr) { + if !self.bracket_stack.pop(cursor.curr()) { return self.restart(); } cursor.advance(); @@ -227,7 +227,7 @@ impl Machine for ArbitraryPropertyMachine { Class::Slash if start_of_value_pos == cursor.pos => return self.restart(), // String interpolation-like syntax is not allowed. E.g.: `[${x}]` - Class::Dollar if matches!(cursor.next.into(), Class::OpenCurly) => { + Class::Dollar if matches!(cursor.next().into(), Class::OpenCurly) => { return self.restart() } diff --git a/crates/oxide/src/extractor/arbitrary_value_machine.rs b/crates/oxide/src/extractor/arbitrary_value_machine.rs index f5a612df13f2..cbef62c42681 100644 --- a/crates/oxide/src/extractor/arbitrary_value_machine.rs +++ b/crates/oxide/src/extractor/arbitrary_value_machine.rs @@ -32,7 +32,7 @@ impl Machine for ArbitraryValueMachine { #[inline] fn next(&mut self, cursor: &mut cursor::Cursor<'_>) -> MachineState { // An arbitrary value must start with an open bracket - if Class::OpenBracket != cursor.curr.into() { + if Class::OpenBracket != cursor.curr().into() { return MachineState::Idle; } @@ -42,8 +42,8 @@ impl Machine for ArbitraryValueMachine { let len = cursor.input.len(); while cursor.pos < len { - match cursor.curr.into() { - Class::Escape => match cursor.next.into() { + match cursor.curr().into() { + Class::Escape => match cursor.next().into() { // An escaped whitespace character is not allowed // // E.g.: `[color:var(--my-\ color)]` @@ -61,7 +61,7 @@ impl Machine for ArbitraryValueMachine { }, Class::OpenParen | Class::OpenBracket | Class::OpenCurly => { - if !self.bracket_stack.push(cursor.curr) { + if !self.bracket_stack.push(cursor.curr()) { return self.restart(); } cursor.advance(); @@ -70,7 +70,7 @@ impl Machine for ArbitraryValueMachine { Class::CloseParen | Class::CloseBracket | Class::CloseCurly if !self.bracket_stack.is_empty() => { - if !self.bracket_stack.pop(cursor.curr) { + if !self.bracket_stack.pop(cursor.curr()) { return self.restart(); } cursor.advance(); @@ -96,7 +96,7 @@ impl Machine for ArbitraryValueMachine { Class::Whitespace => return self.restart(), // String interpolation-like syntax is not allowed. E.g.: `[${x}]` - Class::Dollar if matches!(cursor.next.into(), Class::OpenCurly) => { + Class::Dollar if matches!(cursor.next().into(), Class::OpenCurly) => { return self.restart() } diff --git a/crates/oxide/src/extractor/arbitrary_variable_machine.rs b/crates/oxide/src/extractor/arbitrary_variable_machine.rs index 6990e110b087..e8d4755571c7 100644 --- a/crates/oxide/src/extractor/arbitrary_variable_machine.rs +++ b/crates/oxide/src/extractor/arbitrary_variable_machine.rs @@ -80,13 +80,13 @@ impl Machine for ArbitraryVariableMachine { #[inline(always)] fn next(&mut self, cursor: &mut cursor::Cursor<'_>) -> MachineState { - match cursor.curr.into() { + match cursor.curr().into() { // Arbitrary variables start with `(` followed by a CSS variable // // E.g.: `(--my-variable)` // ^^ // - Class::OpenParen => match cursor.next.into() { + Class::OpenParen => match cursor.next().into() { Class::Dash => { self.start_pos = cursor.pos; cursor.advance(); @@ -117,7 +117,7 @@ impl Machine for ArbitraryVariableMachine { fn next(&mut self, cursor: &mut cursor::Cursor<'_>) -> MachineState { match self.css_variable_machine.next(cursor) { MachineState::Idle => self.restart(), - MachineState::Done(_) => match cursor.next.into() { + MachineState::Done(_) => match cursor.next().into() { // A CSS variable followed by a `,` means that there is a fallback // // E.g.: `(--my-color,red)` @@ -134,7 +134,7 @@ impl Machine for ArbitraryVariableMachine { _ => { cursor.advance(); - match cursor.curr.into() { + match cursor.curr().into() { // End of an arbitrary variable, must be followed by `)` Class::CloseParen => self.done(self.start_pos, cursor), @@ -156,7 +156,7 @@ impl Machine for ArbitraryVariableMachine { let len = cursor.input.len(); while cursor.pos < len { - match cursor.curr.into() { + match cursor.curr().into() { // Valid data type characters // // E.g.: `(length:--my-length)` @@ -169,7 +169,7 @@ impl Machine for ArbitraryVariableMachine { // // E.g.: `(length:--my-length)` // ^ - Class::Colon => match cursor.next.into() { + Class::Colon => match cursor.next().into() { Class::Dash => { cursor.advance(); return self.transition::().next(cursor); @@ -196,8 +196,8 @@ impl Machine for ArbitraryVariableMachine { fn next(&mut self, cursor: &mut cursor::Cursor<'_>) -> MachineState { let len = cursor.input.len(); while cursor.pos < len { - match cursor.curr.into() { - Class::Escape => match cursor.next.into() { + match cursor.curr().into() { + Class::Escape => match cursor.next().into() { // An escaped whitespace character is not allowed // // E.g.: `(--my-\ color)` @@ -212,7 +212,7 @@ impl Machine for ArbitraryVariableMachine { }, Class::OpenParen | Class::OpenBracket | Class::OpenCurly => { - if !self.bracket_stack.push(cursor.curr) { + if !self.bracket_stack.push(cursor.curr()) { return self.restart(); } cursor.advance(); @@ -221,7 +221,7 @@ impl Machine for ArbitraryVariableMachine { Class::CloseParen | Class::CloseBracket | Class::CloseCurly if !self.bracket_stack.is_empty() => { - if !self.bracket_stack.pop(cursor.curr) { + if !self.bracket_stack.pop(cursor.curr()) { return self.restart(); } cursor.advance(); @@ -253,7 +253,7 @@ impl Machine for ArbitraryVariableMachine { Class::Whitespace => return self.restart(), // String interpolation-like syntax is not allowed. E.g.: `[${x}]` - Class::Dollar if matches!(cursor.next.into(), Class::OpenCurly) => { + Class::Dollar if matches!(cursor.next().into(), Class::OpenCurly) => { return self.restart() } diff --git a/crates/oxide/src/extractor/candidate_machine.rs b/crates/oxide/src/extractor/candidate_machine.rs index c82cc3707993..a755cf02a2b5 100644 --- a/crates/oxide/src/extractor/candidate_machine.rs +++ b/crates/oxide/src/extractor/candidate_machine.rs @@ -32,14 +32,14 @@ impl Machine for CandidateMachine { while cursor.pos < len { // Skip ahead for known characters that will never be part of a candidate. No need to // run any sub-machines. - if cursor.curr.is_ascii_whitespace() { + if cursor.curr().is_ascii_whitespace() { self.reset(); cursor.advance(); continue; } // Candidates don't start with these characters, so we can skip ahead. - if matches!(cursor.curr, b':' | b'"' | b'\'' | b'`') { + if matches!(cursor.curr(), b':' | b'"' | b'\'' | b'`') { self.reset(); cursor.advance(); continue; @@ -56,7 +56,7 @@ impl Machine for CandidateMachine { // E.g.: `Some Class` // ^ ^ Invalid, we can jump ahead to the next boundary // - if matches!(cursor.curr, b'<' | b'A'..=b'Z') { + if matches!(cursor.curr(), b'<' | b'A'..=b'Z') { if let Some(offset) = cursor.input[cursor.pos..] .iter() .position(|&c| is_valid_before_boundary(&c)) diff --git a/crates/oxide/src/extractor/css_variable_machine.rs b/crates/oxide/src/extractor/css_variable_machine.rs index 4e19c7111f5d..7beb827ee84b 100644 --- a/crates/oxide/src/extractor/css_variable_machine.rs +++ b/crates/oxide/src/extractor/css_variable_machine.rs @@ -20,7 +20,7 @@ impl Machine for CssVariableMachine { #[inline] fn next(&mut self, cursor: &mut cursor::Cursor<'_>) -> MachineState { // CSS Variables must start with `--` - if Class::Dash != cursor.curr.into() || Class::Dash != cursor.next.into() { + if Class::Dash != cursor.curr().into() || Class::Dash != cursor.next().into() { return MachineState::Idle; } @@ -30,11 +30,11 @@ impl Machine for CssVariableMachine { cursor.advance_twice(); while cursor.pos < len { - match cursor.curr.into() { + match cursor.curr().into() { // https://drafts.csswg.org/css-syntax-3/#ident-token-diagram // Class::AllowedCharacter | Class::Dash => { - match cursor.next.into() { + match cursor.next().into() { // Valid character followed by a valid character or an escape character // // E.g.: `--my-variable` @@ -58,7 +58,7 @@ impl Machine for CssVariableMachine { } } - Class::Escape => match cursor.next.into() { + Class::Escape => match cursor.next().into() { // An escaped whitespace character is not allowed // // In CSS it is allowed, but in the context of a class it's not because then we diff --git a/crates/oxide/src/extractor/mod.rs b/crates/oxide/src/extractor/mod.rs index add0de4acaca..a37d6a0a49b3 100644 --- a/crates/oxide/src/extractor/mod.rs +++ b/crates/oxide/src/extractor/mod.rs @@ -86,7 +86,7 @@ impl<'a> Extractor<'a> { { let cursor = &mut self.cursor.clone(); while cursor.pos < len { - if cursor.curr.is_ascii_whitespace() { + if cursor.curr().is_ascii_whitespace() { cursor.advance(); continue; } @@ -104,7 +104,7 @@ impl<'a> Extractor<'a> { let cursor = &mut self.cursor.clone(); while cursor.pos < len { - if cursor.curr.is_ascii_whitespace() { + if cursor.curr().is_ascii_whitespace() { cursor.advance(); continue; } @@ -147,7 +147,7 @@ impl<'a> Extractor<'a> { let cursor = &mut self.cursor.clone(); while cursor.pos < len { - if cursor.curr.is_ascii_whitespace() { + if cursor.curr().is_ascii_whitespace() { cursor.advance(); continue; } @@ -238,7 +238,7 @@ mod tests { use std::hint::black_box; fn pre_process_input(input: &str, extension: &str) -> String { - let input = crate::scanner::pre_process_input(input.as_bytes(), extension); + let input = crate::scanner::pre_process_input(input.as_bytes().to_vec(), extension); String::from_utf8(input).unwrap() } diff --git a/crates/oxide/src/extractor/modifier_machine.rs b/crates/oxide/src/extractor/modifier_machine.rs index 22668a828749..811bc9ded9e0 100644 --- a/crates/oxide/src/extractor/modifier_machine.rs +++ b/crates/oxide/src/extractor/modifier_machine.rs @@ -31,14 +31,14 @@ impl Machine for ModifierMachine { #[inline] fn next(&mut self, cursor: &mut cursor::Cursor<'_>) -> MachineState { // A modifier must start with a `/`, everything else is not a valid start of a modifier - if Class::Slash != cursor.curr.into() { + if Class::Slash != cursor.curr().into() { return MachineState::Idle; } let start_pos = cursor.pos; cursor.advance(); - match cursor.curr.into() { + match cursor.curr().into() { // Start of an arbitrary value: // // ``` @@ -70,9 +70,9 @@ impl Machine for ModifierMachine { Class::ValidStart => { let len = cursor.input.len(); while cursor.pos < len { - match cursor.curr.into() { + match cursor.curr().into() { Class::ValidStart | Class::ValidInside => { - match cursor.next.into() { + match cursor.next().into() { // Only valid characters are allowed, if followed by another valid character Class::ValidStart | Class::ValidInside => cursor.advance(), diff --git a/crates/oxide/src/extractor/named_utility_machine.rs b/crates/oxide/src/extractor/named_utility_machine.rs index d218dbeb7a9b..24dc027b2d69 100644 --- a/crates/oxide/src/extractor/named_utility_machine.rs +++ b/crates/oxide/src/extractor/named_utility_machine.rs @@ -52,8 +52,8 @@ impl Machine for NamedUtilityMachine { #[inline] fn next(&mut self, cursor: &mut cursor::Cursor<'_>) -> MachineState { - match cursor.curr.into() { - Class::AlphaLower => match cursor.next.into() { + match cursor.curr().into() { + Class::AlphaLower => match cursor.next().into() { // Valid single character utility in between quotes // // E.g.: `
` @@ -90,7 +90,7 @@ impl Machine for NamedUtilityMachine { // // E.g.: `-mx-2.5` // ^^ - Class::Dash => match cursor.next.into() { + Class::Dash => match cursor.next().into() { Class::AlphaLower => { self.start_pos = cursor.pos; cursor.advance(); @@ -118,7 +118,7 @@ impl Machine for NamedUtilityMachine { let len = cursor.input.len(); while cursor.pos < len { - match cursor.curr.into() { + match cursor.curr().into() { // Followed by a boundary character, we are at the end of the utility. // // E.g.: `'flex'` @@ -132,14 +132,14 @@ impl Machine for NamedUtilityMachine { // E.g.: `:div="{ flex: true }"` (JavaScript object syntax) // ^ Class::AlphaLower | Class::AlphaUpper => { - if is_valid_after_boundary(&cursor.next) || { + if is_valid_after_boundary(&cursor.next()) || { // Or any of these characters // // - `:`, because of JS object keys // - `/`, because of modifiers // - `!`, because of important matches!( - cursor.next.into(), + cursor.next().into(), Class::Colon | Class::Slash | Class::Exclamation ) } { @@ -150,7 +150,7 @@ impl Machine for NamedUtilityMachine { cursor.advance() } - Class::Dash => match cursor.next.into() { + Class::Dash => match cursor.next().into() { // Start of an arbitrary value // // E.g.: `bg-[#0088cc]` @@ -196,7 +196,7 @@ impl Machine for NamedUtilityMachine { _ => return self.restart(), }, - Class::Underscore => match cursor.next.into() { + Class::Underscore => match cursor.next().into() { // Valid characters _if_ followed by another valid character. These characters are // only valid inside of the utility but not at the end of the utility. // @@ -225,14 +225,14 @@ impl Machine for NamedUtilityMachine { // ^ // E.g.: `:div="{ flex: true }"` (JavaScript object syntax) // ^ - _ if is_valid_after_boundary(&cursor.next) || { + _ if is_valid_after_boundary(&cursor.next()) || { // Or any of these characters // // - `:`, because of JS object keys // - `/`, because of modifiers // - `!`, because of important matches!( - cursor.next.into(), + cursor.next().into(), Class::Colon | Class::Slash | Class::Exclamation ) } => @@ -249,11 +249,11 @@ impl Machine for NamedUtilityMachine { // E.g.: `px-2.5` // ^^^ Class::Dot => { - if !matches!(cursor.prev.into(), Class::Number) { + if !matches!(cursor.prev().into(), Class::Number) { return self.restart(); } - if !matches!(cursor.next.into(), Class::Number) { + if !matches!(cursor.next().into(), Class::Number) { return self.restart(); } @@ -278,7 +278,7 @@ impl Machine for NamedUtilityMachine { // Class::Number => { if !matches!( - cursor.prev.into(), + cursor.prev().into(), Class::Dash | Class::Underscore | Class::Dot @@ -290,7 +290,7 @@ impl Machine for NamedUtilityMachine { } if !matches!( - cursor.next.into(), + cursor.next().into(), Class::Dot | Class::Number | Class::AlphaLower @@ -314,7 +314,7 @@ impl Machine for NamedUtilityMachine { // ^^ // ``` Class::Percent => { - if !matches!(cursor.prev.into(), Class::Number) { + if !matches!(cursor.prev().into(), Class::Number) { return self.restart(); } diff --git a/crates/oxide/src/extractor/named_variant_machine.rs b/crates/oxide/src/extractor/named_variant_machine.rs index b6de8220b4cb..285fe6ab51a6 100644 --- a/crates/oxide/src/extractor/named_variant_machine.rs +++ b/crates/oxide/src/extractor/named_variant_machine.rs @@ -81,8 +81,8 @@ impl Machine for NamedVariantMachine { #[inline(always)] fn next(&mut self, cursor: &mut cursor::Cursor<'_>) -> MachineState { - match cursor.curr.into() { - Class::AlphaLower | Class::Star => match cursor.next.into() { + match cursor.curr().into() { + Class::AlphaLower | Class::Star => match cursor.next().into() { // Valid single character variant, must be followed by a `:` // // E.g.: `
` @@ -134,8 +134,8 @@ impl Machine for NamedVariantMachine { let len = cursor.input.len(); while cursor.pos < len { - match cursor.curr.into() { - Class::Dash => match cursor.next.into() { + match cursor.curr().into() { + Class::Dash => match cursor.next().into() { // Start of an arbitrary value // // E.g.: `data-[state=pending]:`. @@ -192,7 +192,7 @@ impl Machine for NamedVariantMachine { }; } - Class::Underscore => match cursor.next.into() { + Class::Underscore => match cursor.next().into() { // Valid characters _if_ followed by another valid character. These characters are // only valid inside of the variant but not at the end of the variant. // @@ -240,11 +240,11 @@ impl Machine for NamedVariantMachine { // E.g.: `2.5xl:flex` // ^^^ Class::Dot => { - if !matches!(cursor.prev.into(), Class::Number) { + if !matches!(cursor.prev().into(), Class::Number) { return self.restart(); } - if !matches!(cursor.next.into(), Class::Number) { + if !matches!(cursor.next().into(), Class::Number) { return self.restart(); } @@ -263,7 +263,7 @@ impl Machine for NamedVariantMachine { impl NamedVariantMachine { #[inline(always)] fn parse_arbitrary_end(&mut self, cursor: &mut cursor::Cursor<'_>) -> MachineState { - match cursor.next.into() { + match cursor.next().into() { Class::Slash => { cursor.advance(); self.transition::().next(cursor) @@ -285,7 +285,7 @@ impl Machine for NamedVariantMachine { fn next(&mut self, cursor: &mut cursor::Cursor<'_>) -> MachineState { match self.modifier_machine.next(cursor) { MachineState::Idle => self.restart(), - MachineState::Done(_) => match cursor.next.into() { + MachineState::Done(_) => match cursor.next().into() { // Modifier must be followed by a `:` // // E.g.: `group-hover/name:` @@ -308,7 +308,7 @@ impl Machine for NamedVariantMachine { #[inline(always)] fn next(&mut self, cursor: &mut cursor::Cursor<'_>) -> MachineState { - match cursor.curr.into() { + match cursor.curr().into() { // The end of a variant must be the `:` // // E.g.: `hover:` diff --git a/crates/oxide/src/extractor/pre_processors/clojure.rs b/crates/oxide/src/extractor/pre_processors/clojure.rs index ecf02b4ff634..3fb4ce601cd6 100644 --- a/crates/oxide/src/extractor/pre_processors/clojure.rs +++ b/crates/oxide/src/extractor/pre_processors/clojure.rs @@ -32,14 +32,14 @@ impl PreProcessor for Clojure { let mut cursor = cursor::Cursor::new(&content); while cursor.pos < len { - match cursor.curr { + match cursor.curr() { // Consume strings as-is b'"' => { result[cursor.pos] = b' '; cursor.advance(); while cursor.pos < len { - match cursor.curr { + match cursor.curr() { // Escaped character, skip ahead to the next character b'\\' => cursor.advance_twice(), @@ -57,8 +57,8 @@ impl PreProcessor for Clojure { // Discard line comments until the end of the line. // Comments start with `;;` - b';' if matches!(cursor.next, b';') => { - while cursor.pos < len && cursor.curr != b'\n' { + b';' if matches!(cursor.next(), b';') => { + while cursor.pos < len && cursor.curr() != b'\n' { result[cursor.pos] = b' '; cursor.advance(); } @@ -70,7 +70,7 @@ impl PreProcessor for Clojure { cursor.advance(); while cursor.pos < len { - match cursor.curr { + match cursor.curr() { // A `.` surrounded by digits is a decimal number, so we don't want to replace it. // // E.g.: @@ -78,8 +78,8 @@ impl PreProcessor for Clojure { // gap-1.5 // ^ // ``` - b'.' if cursor.prev.is_ascii_digit() - && cursor.next.is_ascii_digit() => + b'.' if cursor.prev().is_ascii_digit() + && cursor.next().is_ascii_digit() => { // Keep the `.` as-is } @@ -95,7 +95,7 @@ impl PreProcessor for Clojure { result[cursor.pos] = b' '; } // End of keyword. - _ if !is_keyword_character(cursor.curr) => { + _ if !is_keyword_character(cursor.curr()) => { result[cursor.pos] = b' '; break; } @@ -110,11 +110,11 @@ impl PreProcessor for Clojure { // Handle quote with a list, e.g.: `'(…)` // and with a vector, e.g.: `'[…]` - b'\'' if matches!(cursor.next, b'[' | b'(') => { + b'\'' if matches!(cursor.next(), b'[' | b'(') => { result[cursor.pos] = b' '; cursor.advance(); result[cursor.pos] = b' '; - let end = match cursor.curr { + let end = match cursor.curr() { b'[' => b']', b'(' => b')', _ => unreachable!(), @@ -122,7 +122,7 @@ impl PreProcessor for Clojure { // Consume until the closing `]` while cursor.pos < len { - match cursor.curr { + match cursor.curr() { x if x == end => { result[cursor.pos] = b' '; break; @@ -134,7 +134,7 @@ impl PreProcessor for Clojure { cursor.advance(); while cursor.pos < len { - match cursor.curr { + match cursor.curr() { // Escaped character, skip ahead to the next character b'\\' => cursor.advance_twice(), @@ -157,14 +157,14 @@ impl PreProcessor for Clojure { } // Handle quote with a keyword, e.g.: `'bg-white` - b'\'' if !cursor.next.is_ascii_whitespace() => { + b'\'' if !cursor.next().is_ascii_whitespace() => { result[cursor.pos] = b' '; cursor.advance(); while cursor.pos < len { - match cursor.curr { + match cursor.curr() { // End of keyword. - _ if !is_keyword_character(cursor.curr) => { + _ if !is_keyword_character(cursor.curr()) => { result[cursor.pos] = b' '; break; } diff --git a/crates/oxide/src/extractor/pre_processors/elixir.rs b/crates/oxide/src/extractor/pre_processors/elixir.rs index 87b89a2a9dda..7737a6b2d1ae 100644 --- a/crates/oxide/src/extractor/pre_processors/elixir.rs +++ b/crates/oxide/src/extractor/pre_processors/elixir.rs @@ -13,13 +13,13 @@ impl PreProcessor for Elixir { while cursor.pos < content.len() { // Look for a sigil marker - if cursor.curr != b'~' { + if cursor.curr() != b'~' { cursor.advance(); continue; } // Scan charlists, strings, and wordlists - if !matches!(cursor.next, b'c' | b'C' | b's' | b'S' | b'w' | b'W') { + if !matches!(cursor.next(), b'c' | b'C' | b's' | b'S' | b'w' | b'W') { cursor.advance(); continue; } @@ -27,7 +27,7 @@ impl PreProcessor for Elixir { cursor.advance_twice(); // Match the opening for a sigil - if !matches!(cursor.curr, b'(' | b'[' | b'{') { + if !matches!(cursor.curr(), b'(' | b'[' | b'{') { continue; } @@ -35,19 +35,19 @@ impl PreProcessor for Elixir { result[cursor.pos] = b' '; // Scan until we find a balanced closing one and replace it too - bracket_stack.push(cursor.curr); + bracket_stack.push(cursor.curr()); while cursor.pos < content.len() { cursor.advance(); - match cursor.curr { + match cursor.curr() { // Escaped character, skip ahead to the next character b'\\' => cursor.advance_twice(), b'(' | b'[' | b'{' => { - bracket_stack.push(cursor.curr); + bracket_stack.push(cursor.curr()); } b')' | b']' | b'}' if !bracket_stack.is_empty() => { - bracket_stack.pop(cursor.curr); + bracket_stack.pop(cursor.curr()); if bracket_stack.is_empty() { // Replace the closing bracket with a space diff --git a/crates/oxide/src/extractor/pre_processors/haml.rs b/crates/oxide/src/extractor/pre_processors/haml.rs index a131618abe66..99b7bd052302 100644 --- a/crates/oxide/src/extractor/pre_processors/haml.rs +++ b/crates/oxide/src/extractor/pre_processors/haml.rs @@ -101,7 +101,7 @@ impl PreProcessor for Haml { let mut last_newline_position = 0; while cursor.pos < len { - match cursor.curr { + match cursor.curr() { // Escape the next character b'\\' => { cursor.advance_twice(); @@ -119,7 +119,7 @@ impl PreProcessor for Haml { b'-' if cursor.input[last_newline_position..cursor.pos] .iter() .all(u8::is_ascii_whitespace) - && matches!(cursor.next, b'#') => + && matches!(cursor.next(), b'#') => { // Just consume the comment let updated_last_newline_position = @@ -159,7 +159,7 @@ impl PreProcessor for Haml { // Override the last known newline position last_newline_position = end; - let replaced = pre_process_input(ruby_code, "rb"); + let replaced = pre_process_input(ruby_code.to_vec(), "rb"); result.replace_range(start..end, replaced); } @@ -190,7 +190,7 @@ impl PreProcessor for Haml { // digit. // E.g.: `bg-red-500.2xl:flex` // ^^^ - if cursor.prev.is_ascii_digit() && cursor.next.is_ascii_digit() { + if cursor.prev().is_ascii_digit() && cursor.next().is_ascii_digit() { let mut next_cursor = cursor.clone(); next_cursor.advance(); @@ -213,11 +213,11 @@ impl PreProcessor for Haml { if bracket_stack.is_empty() { result[cursor.pos] = b' '; } - bracket_stack.push(cursor.curr); + bracket_stack.push(cursor.curr()); } b')' | b']' | b'}' if !bracket_stack.is_empty() => { - bracket_stack.pop(cursor.curr); + bracket_stack.pop(cursor.curr()); // Replace closing bracket with a space if bracket_stack.is_empty() { @@ -257,7 +257,7 @@ impl Haml { // :url => { :action => "add", :id => product.id }, // :update => { :success => "cart", :failure => "error" } // ``` - let evaluation_type = cursor.curr; + let evaluation_type = cursor.curr(); let block_indentation_level = cursor .pos @@ -267,17 +267,17 @@ impl Haml { let mut last_newline_position = last_known_newline_position; // Consume until the end of the line first - while cursor.pos < len && cursor.curr != b'\n' { + while cursor.pos < len && cursor.curr() != b'\n' { cursor.advance(); } // Block is already done, aka just a line - if evaluation_type == b'=' && cursor.prev != b',' { + if evaluation_type == b'=' && cursor.prev() != b',' { return cursor.pos; } 'outer: while cursor.pos < len { - match cursor.curr { + match cursor.curr() { // Escape the next character b'\\' => { cursor.advance_twice(); @@ -289,7 +289,7 @@ impl Haml { last_newline_position = cursor.pos; // We are done with this block - if evaluation_type == b'=' && cursor.prev != b',' { + if evaluation_type == b'=' && cursor.prev() != b',' { break; } @@ -300,11 +300,11 @@ impl Haml { // Skip whitespace and compute the indentation level x if x.is_ascii_whitespace() => { // Find first non-whitespace character - while cursor.pos < len && cursor.curr.is_ascii_whitespace() { - if cursor.curr == b'\n' { + while cursor.pos < len && cursor.curr().is_ascii_whitespace() { + if cursor.curr() == b'\n' { last_newline_position = cursor.pos; - if evaluation_type == b'=' && cursor.prev != b',' { + if evaluation_type == b'=' && cursor.prev() != b',' { // We are done with this block break 'outer; } diff --git a/crates/oxide/src/extractor/pre_processors/json.rs b/crates/oxide/src/extractor/pre_processors/json.rs index 809eb501e679..cd457050c5fc 100644 --- a/crates/oxide/src/extractor/pre_processors/json.rs +++ b/crates/oxide/src/extractor/pre_processors/json.rs @@ -11,13 +11,13 @@ impl PreProcessor for Json { let mut cursor = cursor::Cursor::new(content); while cursor.pos < len { - match cursor.curr { + match cursor.curr() { // Consume strings as-is b'"' => { cursor.advance(); while cursor.pos < len { - match cursor.curr { + match cursor.curr() { // Escaped character, skip ahead to the next character b'\\' => cursor.advance_twice(), diff --git a/crates/oxide/src/extractor/pre_processors/markdown.rs b/crates/oxide/src/extractor/pre_processors/markdown.rs index 63dc37d1eb4b..488614ee57bd 100644 --- a/crates/oxide/src/extractor/pre_processors/markdown.rs +++ b/crates/oxide/src/extractor/pre_processors/markdown.rs @@ -9,20 +9,27 @@ impl PreProcessor for Markdown { let len = content.len(); let mut result = content.to_vec(); let mut cursor = cursor::Cursor::new(content); + let mut bracket_stack = vec![]; let mut in_directive = false; while cursor.pos < len { - match (in_directive, cursor.curr) { + match (in_directive, cursor.curr()) { (false, b'{') => { result[cursor.pos] = b' '; in_directive = true; } + (true, b'(' | b'[' | b'{' | b'<') => { + bracket_stack.push(cursor.curr()); + } + (true, b')' | b']' | b'}' | b'>') if !bracket_stack.is_empty() => { + bracket_stack.pop(); + } (true, b'}') => { result[cursor.pos] = b' '; in_directive = false; } - (true, b'.') => { + (true, b'.') if bracket_stack.is_empty() => { result[cursor.pos] = b' '; } _ => {} @@ -60,4 +67,17 @@ mod tests { Markdown::test(input, expected); } } + + #[test] + fn test_nested_classes_keep_the_dots() { + for (input, expected) in [ + ( + r#"{
}"#, + r#"
"#, + ), + (r#"{content-['example.js']}"#, r#" content-['example.js'] "#), + ] { + Markdown::test(input, expected); + } + } } diff --git a/crates/oxide/src/extractor/pre_processors/pug.rs b/crates/oxide/src/extractor/pre_processors/pug.rs index 7b44fcf5be04..70dfe5683197 100644 --- a/crates/oxide/src/extractor/pre_processors/pug.rs +++ b/crates/oxide/src/extractor/pre_processors/pug.rs @@ -15,7 +15,7 @@ impl PreProcessor for Pug { let mut bracket_stack = BracketStack::default(); while cursor.pos < len { - match cursor.curr { + match cursor.curr() { // Only replace `.` with a space if it's not surrounded by numbers. E.g.: // // ```diff @@ -43,7 +43,7 @@ impl PreProcessor for Pug { // digit. // E.g.: `bg-red-500.2xl:flex` // ^^^ - if cursor.prev.is_ascii_digit() && cursor.next.is_ascii_digit() { + if cursor.prev().is_ascii_digit() && cursor.next().is_ascii_digit() { let mut next_cursor = cursor.clone(); next_cursor.advance(); @@ -68,17 +68,17 @@ impl PreProcessor for Pug { // // However, we also need to make sure that we keep the parens that are part of the // utility class. E.g.: `bg-(--my-color)`. - b'(' if bracket_stack.is_empty() && !matches!(cursor.prev, b'-' | b'/') => { + b'(' if bracket_stack.is_empty() && !matches!(cursor.prev(), b'-' | b'/') => { result[cursor.pos] = b' '; - bracket_stack.push(cursor.curr); + bracket_stack.push(cursor.curr()); } b'(' | b'[' | b'{' => { - bracket_stack.push(cursor.curr); + bracket_stack.push(cursor.curr()); } b')' | b']' | b'}' if !bracket_stack.is_empty() => { - bracket_stack.pop(cursor.curr); + bracket_stack.pop(cursor.curr()); } // Consume everything else diff --git a/crates/oxide/src/extractor/pre_processors/ruby.rs b/crates/oxide/src/extractor/pre_processors/ruby.rs index 89ac1ee7b1c6..1f2221414ff4 100644 --- a/crates/oxide/src/extractor/pre_processors/ruby.rs +++ b/crates/oxide/src/extractor/pre_processors/ruby.rs @@ -68,7 +68,8 @@ impl PreProcessor for Ruby { } let body = &content_as_str[body_start..body_end]; - let replaced = pre_process_input(body.as_bytes(), &lang.to_ascii_lowercase()); + let replaced = + pre_process_input(body.as_bytes().to_vec(), &lang.to_ascii_lowercase()); result.replace_range(body_start..body_end, replaced); break; @@ -77,12 +78,12 @@ impl PreProcessor for Ruby { // Ruby extraction while cursor.pos < len { - match cursor.curr { + match cursor.curr() { b'"' => { cursor.advance(); while cursor.pos < len { - match cursor.curr { + match cursor.curr() { // Escaped character, skip ahead to the next character b'\\' => cursor.advance_twice(), @@ -102,7 +103,7 @@ impl PreProcessor for Ruby { cursor.advance(); while cursor.pos < len { - match cursor.curr { + match cursor.curr() { // Escaped character, skip ahead to the next character b'\\' => cursor.advance_twice(), @@ -123,12 +124,12 @@ impl PreProcessor for Ruby { // Except for strict locals, these are defined in a `<%# locals: … %>`. Checking if // the comment is preceded by a `%` should be enough without having to perform more // parsing logic. Worst case we _do_ scan a few comments. - b'#' if !matches!(cursor.prev, b'%') => { + b'#' if !matches!(cursor.prev(), b'%') => { result[cursor.pos] = b' '; cursor.advance(); while cursor.pos < len { - match cursor.curr { + match cursor.curr() { // End of the comment b'\n' => break, @@ -148,7 +149,7 @@ impl PreProcessor for Ruby { } // Looking for `%w`, `%W`, or `%p` - if cursor.curr != b'%' || !matches!(cursor.next, b'w' | b'W' | b'p') { + if cursor.curr() != b'%' || !matches!(cursor.next(), b'w' | b'W' | b'p') { cursor.advance(); continue; } @@ -156,7 +157,7 @@ impl PreProcessor for Ruby { cursor.advance_twice(); // Boundary character - let boundary = match cursor.curr { + let boundary = match cursor.curr() { b'[' => b']', b'(' => b')', b'{' => b'}', @@ -177,11 +178,11 @@ impl PreProcessor for Ruby { cursor.advance(); while cursor.pos < len { - match cursor.curr { + match cursor.curr() { // Skip escaped characters b'\\' => { // Use backslash to embed spaces in the strings. - if cursor.next == b' ' { + if cursor.next() == b' ' { result[cursor.pos] = b' '; } @@ -190,19 +191,19 @@ impl PreProcessor for Ruby { // Start of a nested bracket b'[' | b'(' | b'{' => { - bracket_stack.push(cursor.curr); + bracket_stack.push(cursor.curr()); } // End of a nested bracket b']' | b')' | b'}' if !bracket_stack.is_empty() => { - if !bracket_stack.pop(cursor.curr) { + if !bracket_stack.pop(cursor.curr()) { // Unbalanced cursor.advance(); } } // End of the pattern, replace the boundary character with a space - _ if cursor.curr == boundary => { + _ if cursor.curr() == boundary => { if boundary != b'\n' { result[cursor.pos] = b' '; } diff --git a/crates/oxide/src/extractor/pre_processors/rust.rs b/crates/oxide/src/extractor/pre_processors/rust.rs index 6404fffb5e29..34c9e0c916b7 100644 --- a/crates/oxide/src/extractor/pre_processors/rust.rs +++ b/crates/oxide/src/extractor/pre_processors/rust.rs @@ -33,7 +33,7 @@ impl Rust { let mut bracket_stack = bracket_stack::BracketStack::default(); while cursor.pos < len { - match cursor.curr { + match cursor.curr() { // Escaped character, skip ahead to the next character b'\\' => { cursor.advance_twice(); @@ -46,7 +46,7 @@ impl Rust { cursor.advance(); while cursor.pos < len { - match cursor.curr { + match cursor.curr() { // Escaped character, skip ahead to the next character b'\\' => cursor.advance_twice(), @@ -89,7 +89,7 @@ impl Rust { // digit. // E.g.: `bg-red-500.2xl:flex` // ^^^ - if cursor.prev.is_ascii_digit() && cursor.next.is_ascii_digit() { + if cursor.prev().is_ascii_digit() && cursor.next().is_ascii_digit() { let mut next_cursor = cursor.clone(); next_cursor.advance(); @@ -103,11 +103,11 @@ impl Rust { } b'[' => { - bracket_stack.push(cursor.curr); + bracket_stack.push(cursor.curr()); } b']' if !bracket_stack.is_empty() => { - bracket_stack.pop(cursor.curr); + bracket_stack.pop(cursor.curr()); } // Consume everything else diff --git a/crates/oxide/src/extractor/pre_processors/slim.rs b/crates/oxide/src/extractor/pre_processors/slim.rs index 6d41e5a09b72..eacfb55eedfd 100644 --- a/crates/oxide/src/extractor/pre_processors/slim.rs +++ b/crates/oxide/src/extractor/pre_processors/slim.rs @@ -15,7 +15,7 @@ impl PreProcessor for Slim { let mut bracket_stack = BracketStack::default(); while cursor.pos < len { - match cursor.curr { + match cursor.curr() { // Only replace `.` with a space if it's not surrounded by numbers. E.g.: // // ```diff @@ -43,7 +43,7 @@ impl PreProcessor for Slim { // digit. // E.g.: `bg-red-500.2xl:flex` // ^^^ - if cursor.prev.is_ascii_digit() && cursor.next.is_ascii_digit() { + if cursor.prev().is_ascii_digit() && cursor.next().is_ascii_digit() { let mut next_cursor = cursor.clone(); next_cursor.advance(); @@ -65,7 +65,7 @@ impl PreProcessor for Slim { // class=%w[bg-blue-500 w-10 h-10] // ] // ``` - b'%' if matches!(cursor.next, b'w' | b'W') + b'%' if matches!(cursor.next(), b'w' | b'W') && matches!(cursor.input.get(cursor.pos + 2), Some(b'[' | b'(' | b'{')) => { result[cursor.pos] = b' '; // Replace `%` @@ -73,7 +73,7 @@ impl PreProcessor for Slim { result[cursor.pos] = b' '; // Replace `w` cursor.advance(); result[cursor.pos] = b' '; // Replace `[` or `(` or `{` - bracket_stack.push(cursor.curr); + bracket_stack.push(cursor.curr()); cursor.advance(); // Move past the bracket continue; } @@ -96,10 +96,10 @@ impl PreProcessor for Slim { // Instead of listing all boundary characters, let's list the characters we know // will be invalid instead. b'[' if bracket_stack.is_empty() - && matches!(cursor.prev, b'a'..=b'z' | b'A'..=b'Z' | b'0'..=b'9') => + && matches!(cursor.prev(), b'a'..=b'z' | b'A'..=b'Z' | b'0'..=b'9') => { result[cursor.pos] = b' '; - bracket_stack.push(cursor.curr); + bracket_stack.push(cursor.curr()); } // In Slim the class name shorthand can be followed by a parenthesis. E.g.: @@ -114,17 +114,17 @@ impl PreProcessor for Slim { // // However, we also need to make sure that we keep the parens that are part of the // utility class. E.g.: `bg-(--my-color)`. - b'(' if bracket_stack.is_empty() && !matches!(cursor.prev, b'-' | b'/') => { + b'(' if bracket_stack.is_empty() && !matches!(cursor.prev(), b'-' | b'/') => { result[cursor.pos] = b' '; - bracket_stack.push(cursor.curr); + bracket_stack.push(cursor.curr()); } b'(' | b'[' | b'{' => { - bracket_stack.push(cursor.curr); + bracket_stack.push(cursor.curr()); } b')' | b']' | b'}' if !bracket_stack.is_empty() => { - bracket_stack.pop(cursor.curr); + bracket_stack.pop(cursor.curr()); } // Consume everything else diff --git a/crates/oxide/src/extractor/pre_processors/vue.rs b/crates/oxide/src/extractor/pre_processors/vue.rs index 119e2a3d2079..1b9bf1668cb4 100644 --- a/crates/oxide/src/extractor/pre_processors/vue.rs +++ b/crates/oxide/src/extractor/pre_processors/vue.rs @@ -14,13 +14,12 @@ pub struct Vue; impl PreProcessor for Vue { fn process(&self, content: &[u8]) -> Vec { let mut result = content.to_vec(); - let content_as_str = std::str::from_utf8(content).unwrap(); for (_, [lang, body]) in TEMPLATE_REGEX .captures_iter(content_as_str) .map(|c| c.extract()) { - let replaced = pre_process_input(body.as_bytes(), lang); + let replaced = pre_process_input(body.as_bytes().to_vec(), lang); result = result.replace(body, replaced); } diff --git a/crates/oxide/src/extractor/string_machine.rs b/crates/oxide/src/extractor/string_machine.rs index 9148a1fbf619..4fad49faae19 100644 --- a/crates/oxide/src/extractor/string_machine.rs +++ b/crates/oxide/src/extractor/string_machine.rs @@ -30,20 +30,20 @@ impl Machine for StringMachine { #[inline] fn next(&mut self, cursor: &mut cursor::Cursor<'_>) -> MachineState { - if Class::Quote != cursor.curr.into() { + if Class::Quote != cursor.curr().into() { return MachineState::Idle; } // Start of a string let len = cursor.input.len(); let start_pos = cursor.pos; - let end_char = cursor.curr; + let end_char = cursor.curr(); cursor.advance(); while cursor.pos < len { - match cursor.curr.into() { - Class::Escape => match cursor.next.into() { + match cursor.curr().into() { + Class::Escape => match cursor.next().into() { // An escaped whitespace character is not allowed Class::Whitespace => return MachineState::Idle, @@ -52,7 +52,7 @@ impl Machine for StringMachine { }, // End of the string - Class::Quote if cursor.curr == end_char => return self.done(start_pos, cursor), + Class::Quote if cursor.curr() == end_char => return self.done(start_pos, cursor), // Any kind of whitespace is not allowed Class::Whitespace => return MachineState::Idle, diff --git a/crates/oxide/src/extractor/utility_machine.rs b/crates/oxide/src/extractor/utility_machine.rs index b9b1038cdb3a..c116ec4e4226 100644 --- a/crates/oxide/src/extractor/utility_machine.rs +++ b/crates/oxide/src/extractor/utility_machine.rs @@ -27,12 +27,12 @@ impl Machine for UtilityMachine { #[inline] fn next(&mut self, cursor: &mut cursor::Cursor<'_>) -> MachineState { - match cursor.curr.into() { + match cursor.curr().into() { // LEGACY: Important marker Class::Exclamation => { self.legacy_important = true; - match cursor.next.into() { + match cursor.next().into() { // Start of an arbitrary property // // E.g.: `![color:red]` @@ -78,7 +78,7 @@ impl UtilityMachine { fn parse_arbitrary_property(&mut self, cursor: &mut cursor::Cursor<'_>) -> MachineState { match self.arbitrary_property_machine.next(cursor) { MachineState::Idle => self.restart(), - MachineState::Done(_) => match cursor.next.into() { + MachineState::Done(_) => match cursor.next().into() { // End of arbitrary property, but there is a potential modifier. // // E.g.: `[color:#0088cc]/` @@ -109,7 +109,7 @@ impl UtilityMachine { fn parse_named_utility(&mut self, cursor: &mut cursor::Cursor<'_>) -> MachineState { match self.named_utility_machine.next(cursor) { MachineState::Idle => self.restart(), - MachineState::Done(_) => match cursor.next.into() { + MachineState::Done(_) => match cursor.next().into() { // End of a named utility, but there is a potential modifier. // // E.g.: `bg-red-500/` @@ -140,7 +140,7 @@ impl UtilityMachine { fn parse_modifier(&mut self, cursor: &mut cursor::Cursor<'_>) -> MachineState { match self.modifier_machine.next(cursor) { MachineState::Idle => self.restart(), - MachineState::Done(_) => match cursor.next.into() { + MachineState::Done(_) => match cursor.next().into() { // A modifier followed by a modifier is invalid Class::Slash => self.restart(), diff --git a/crates/oxide/src/extractor/variant_machine.rs b/crates/oxide/src/extractor/variant_machine.rs index 23aa61798643..9ec2adc0922a 100644 --- a/crates/oxide/src/extractor/variant_machine.rs +++ b/crates/oxide/src/extractor/variant_machine.rs @@ -16,7 +16,7 @@ impl Machine for VariantMachine { #[inline] fn next(&mut self, cursor: &mut cursor::Cursor<'_>) -> MachineState { - match cursor.curr.into() { + match cursor.curr().into() { // Start of an arbitrary variant // // E.g.: `[&:hover]:` @@ -48,7 +48,7 @@ impl VariantMachine { start_pos: usize, cursor: &mut cursor::Cursor<'_>, ) -> MachineState { - match cursor.next.into() { + match cursor.next().into() { // End of an arbitrary value, must be followed by a `:` // // E.g.: `[&:hover]:` diff --git a/crates/oxide/src/fast_skip.rs b/crates/oxide/src/fast_skip.rs index 488e61bd68da..54930548c620 100644 --- a/crates/oxide/src/fast_skip.rs +++ b/crates/oxide/src/fast_skip.rs @@ -10,7 +10,7 @@ pub fn fast_skip(cursor: &Cursor) -> Option { return None; } - if !cursor.curr.is_ascii_whitespace() { + if !cursor.curr().is_ascii_whitespace() { return None; } diff --git a/crates/oxide/src/scanner/detect_sources.rs b/crates/oxide/src/scanner/detect_sources.rs index 9dc340fbaf47..c519cd00d788 100644 --- a/crates/oxide/src/scanner/detect_sources.rs +++ b/crates/oxide/src/scanner/detect_sources.rs @@ -30,11 +30,9 @@ fn sort_by_dir_and_name(a: &DirEntry, z: &DirEntry) -> Ordering { pub fn resolve_globs( base: PathBuf, - dirs: &[PathBuf], + dirs: &FxHashSet, extensions: &FxHashSet, ) -> Vec { - let allowed_paths: FxHashSet = FxHashSet::from_iter(dirs.iter().cloned()); - // A list of known extensions + a list of extensions we found in the project. let mut found_extensions: FxHashSet = FxHashSet::from_iter(KNOWN_EXTENSIONS.iter().map(|x| x.to_string())); @@ -72,7 +70,7 @@ pub fn resolve_globs( continue; } - if !allowed_paths.contains(path) { + if !dirs.contains(path) { let mut path = path; while let Some(parent) = path.parent() { if parent == base { @@ -113,7 +111,7 @@ pub fn resolve_globs( continue; } - if !allowed_paths.contains(path) { + if !dirs.contains(path) { continue; } diff --git a/crates/oxide/src/scanner/fixtures/ignored-content-dirs.txt b/crates/oxide/src/scanner/fixtures/ignored-content-dirs.txt index 0921d2ff8c8e..79f01ecc117a 100644 --- a/crates/oxide/src/scanner/fixtures/ignored-content-dirs.txt +++ b/crates/oxide/src/scanner/fixtures/ignored-content-dirs.txt @@ -1,14 +1,15 @@ .git .hg -.svn -node_modules -.yarn -.venv -venv +.jj .next -.turbo .parcel-cache -__pycache__ -.svelte-kit .pnpm-store +.svelte-kit +.svn +.turbo +.venv .vercel +.yarn +__pycache__ +node_modules +venv diff --git a/crates/oxide/src/scanner/init_tracing.rs b/crates/oxide/src/scanner/init_tracing.rs new file mode 100644 index 000000000000..2a570ff20188 --- /dev/null +++ b/crates/oxide/src/scanner/init_tracing.rs @@ -0,0 +1,70 @@ +use std::fs::OpenOptions; +use std::io::{self, Write}; +use std::path::Path; +use std::sync::{self, Arc, Mutex}; +use tracing_subscriber::fmt::writer::BoxMakeWriter; + +pub static SHOULD_TRACE: sync::LazyLock = sync::LazyLock::new( + || matches!(std::env::var("DEBUG"), Ok(value) if value.eq("*") || (value.contains("tailwindcss:oxide") && !value.contains("-tailwindcss:oxide"))), +); + +fn dim(input: &str) -> String { + format!("\u{001b}[2m{input}\u{001b}[22m") +} + +fn blue(input: &str) -> String { + format!("\u{001b}[34m{input}\u{001b}[39m") +} + +fn highlight(input: &str) -> String { + format!("{}{}{}", dim(&blue("`")), blue(input), dim(&blue("`"))) +} + +struct MutexWriter(Arc>); + +impl Write for MutexWriter { + fn write(&mut self, buf: &[u8]) -> io::Result { + self.0.lock().unwrap().write(buf) + } + + fn flush(&mut self) -> io::Result<()> { + self.0.lock().unwrap().flush() + } +} + +pub fn init_tracing() { + if !*SHOULD_TRACE { + return; + } + + let file_path = format!("tailwindcss-{}.log", std::process::id()); + let file = OpenOptions::new() + .create(true) + .append(true) + .open(&file_path) + .unwrap_or_else(|_| panic!("Failed to open {file_path}")); + + let file_path = Path::new(&file_path); + let absolute_file_path = dunce::canonicalize(file_path) + .unwrap_or_else(|_| panic!("Failed to canonicalize {file_path:?}")); + eprintln!( + "{} Writing debug info to: {}\n", + dim("[DEBUG]"), + highlight(absolute_file_path.as_path().to_str().unwrap()) + ); + + let file = Arc::new(Mutex::new(file)); + + let writer: BoxMakeWriter = BoxMakeWriter::new({ + let file = file.clone(); + move || Box::new(MutexWriter(file.clone())) as Box + }); + + _ = tracing_subscriber::fmt() + .with_max_level(tracing::Level::INFO) + .with_span_events(tracing_subscriber::fmt::format::FmtSpan::ACTIVE) + .with_writer(writer) + .with_ansi(false) + .compact() + .try_init(); +} diff --git a/crates/oxide/src/scanner/mod.rs b/crates/oxide/src/scanner/mod.rs index ec6aea642481..6d6cabc2aa80 100644 --- a/crates/oxide/src/scanner/mod.rs +++ b/crates/oxide/src/scanner/mod.rs @@ -1,5 +1,6 @@ pub mod auto_source_detection; pub mod detect_sources; +pub mod init_tracing; pub mod sources; use crate::extractor::{Extracted, Extractor}; @@ -14,15 +15,13 @@ use bstr::ByteSlice; use fast_glob::glob_match; use fxhash::{FxHashMap, FxHashSet}; use ignore::{gitignore::GitignoreBuilder, WalkBuilder}; +use init_tracing::{init_tracing, SHOULD_TRACE}; use rayon::prelude::*; use std::collections::{BTreeMap, BTreeSet}; -use std::fs::OpenOptions; -use std::io::{self, Write}; use std::path::{Path, PathBuf}; -use std::sync::{self, Arc, Mutex}; +use std::sync::{Arc, Mutex}; use std::time::SystemTime; use tracing::event; -use tracing_subscriber::fmt::writer::BoxMakeWriter; // @source "some/folder"; // This is auto source detection // @source "some/folder/**/*"; // This is auto source detection @@ -34,70 +33,6 @@ use tracing_subscriber::fmt::writer::BoxMakeWriter; // // @source "do-include-me.bin"; // `.bin` is typically ignored, but now it's explicit so should be included // @source "git-ignored.html"; // A git ignored file that is listed explicitly, should be scanned -static SHOULD_TRACE: sync::LazyLock = sync::LazyLock::new( - || matches!(std::env::var("DEBUG"), Ok(value) if value.eq("*") || (value.contains("tailwindcss:oxide") && !value.contains("-tailwindcss:oxide"))), -); - -fn dim(input: &str) -> String { - format!("\u{001b}[2m{input}\u{001b}[22m") -} - -fn blue(input: &str) -> String { - format!("\u{001b}[34m{input}\u{001b}[39m") -} - -fn highlight(input: &str) -> String { - format!("{}{}{}", dim(&blue("`")), blue(input), dim(&blue("`"))) -} - -fn init_tracing() { - if !*SHOULD_TRACE { - return; - } - - let file_path = format!("tailwindcss-{}.log", std::process::id()); - let file = OpenOptions::new() - .create(true) - .append(true) - .open(&file_path) - .unwrap_or_else(|_| panic!("Failed to open {file_path}")); - - let file_path = Path::new(&file_path); - let absolute_file_path = dunce::canonicalize(file_path) - .unwrap_or_else(|_| panic!("Failed to canonicalize {file_path:?}")); - eprintln!( - "{} Writing debug info to: {}\n", - dim("[DEBUG]"), - highlight(absolute_file_path.as_path().to_str().unwrap()) - ); - - let file = Arc::new(Mutex::new(file)); - - let writer: BoxMakeWriter = BoxMakeWriter::new({ - let file = file.clone(); - move || Box::new(MutexWriter(file.clone())) as Box - }); - - _ = tracing_subscriber::fmt() - .with_max_level(tracing::Level::INFO) - .with_span_events(tracing_subscriber::fmt::format::FmtSpan::ACTIVE) - .with_writer(writer) - .with_ansi(false) - .compact() - .try_init(); -} - -struct MutexWriter(Arc>); - -impl Write for MutexWriter { - fn write(&mut self, buf: &[u8]) -> io::Result { - self.0.lock().unwrap().write(buf) - } - - fn flush(&mut self) -> io::Result<()> { - self.0.lock().unwrap().flush() - } -} #[derive(Debug, Clone)] pub enum ChangedContent { @@ -129,26 +64,32 @@ pub struct Scanner { /// The walker to detect all files that we have to scan walker: Option, - /// All changed content that we have to parse - changed_content: Vec, - /// All found extensions extensions: FxHashSet, - /// All CSS files we want to scan for CSS variable usage - css_files: Vec, - /// All files that we have to scan - files: Vec, + files: FxHashSet, /// All directories, sub-directories, etc… we saw during source detection - dirs: Vec, + dirs: FxHashSet, /// All generated globs, used for setting up watchers globs: Option>, /// Track unique set of candidates candidates: FxHashSet, + + /// Track mtimes for files so re-scans can skip unchanged files. + /// Only populated after the first scan completes (to avoid unnecessary + /// metadata calls on initial build). + mtimes: FxHashMap, + + /// Whether we've completed at least one full scan. When false, we skip + /// mtime tracking entirely so the initial build stays fast. + has_scanned_once: bool, + + /// Whether sources have been scanned since the last `scan()` call + sources_scanned: bool, } impl Scanner { @@ -163,7 +104,6 @@ impl Scanner { } let sources = Sources::new(public_source_entries_to_private_source_entries(sources)); - if *SHOULD_TRACE { event!(tracing::Level::INFO, "Optimized sources:"); for source in sources.iter() { @@ -171,29 +111,26 @@ impl Scanner { } } + let walker = create_walker(&sources); + Self { - sources: sources.clone(), - walker: create_walker(sources), + sources, + walker, ..Default::default() } } pub fn scan(&mut self) -> Vec { - self.scan_sources(); + self.sources_scanned = false; - // TODO: performance improvement, bail early if we don't have any changed content - // if self.changed_content.is_empty() { - // return vec![]; - // } + let (scanned_blobs, css_files) = self.discover_sources(); - let _new_candidates = self.extract_candidates(); + self.extract_candidates(scanned_blobs, css_files); - // Make sure we have a sorted list of candidates - let mut candidates = self.candidates.iter().cloned().collect::<_>>(); - candidates.par_sort_unstable(); - - // Return all candidates instead of only the new ones - candidates + // Return all candidates sorted + let mut result = self.candidates.iter().cloned().collect::<_>>(); + result.par_sort_unstable(); + result } #[tracing::instrument(skip_all)] @@ -208,7 +145,7 @@ impl Scanner { // Raw content can be parsed directly, no need to verify if the file exists and is allowed // to be scanned. - self.changed_content.extend(changed_contents); + let mut content_to_scan: Vec = changed_contents; // Fully resolve all files let changed_files = changed_files @@ -232,7 +169,7 @@ impl Scanner { }); // All known files are allowed to be scanned - self.changed_content.extend(known_files); + content_to_scan.extend(known_files); // Figure out if the new unknown files are allowed to be scanned if !new_unknown_files.is_empty() { @@ -252,8 +189,8 @@ impl Scanner { // When the file is found on disk it means that all the rules pass. We can // extract the current file and remove it from the list of passed in files. if file == path { - self.files.push(path.to_path_buf()); // Track for future use - self.changed_content.push(changed_file.clone()); // Track for parsing + self.files.insert(path.to_path_buf()); // Track for future use + content_to_scan.push(changed_file.clone()); // Track for parsing drop_file_indexes.push(idx); } } @@ -274,18 +211,17 @@ impl Scanner { } } - self.extract_candidates() + // Read all content into blobs for extraction + let blobs = read_all_files(content_to_scan); + self.extract_candidates(blobs, vec![]) } #[tracing::instrument(skip_all)] - fn extract_candidates(&mut self) -> Vec { - let changed_content = self.changed_content.drain(..).collect::<_>>(); - - // Extract all candidates from the changed content - let mut new_candidates = parse_all_blobs(read_all_files(changed_content)); + fn extract_candidates(&mut self, blobs: Vec>, css_files: Vec) -> Vec { + // Extract all candidates from the pre-read blobs + let mut new_candidates = parse_all_blobs(blobs); // Extract all CSS variables from the CSS files - let css_files = self.css_files.drain(..).collect::<_>>(); if !css_files.is_empty() { let css_variables = extract_css_variables(read_all_files( css_files @@ -297,63 +233,23 @@ impl Scanner { new_candidates.extend(css_variables); } - // Only compute the new candidates and ignore the ones we already have. This is for - // subsequent calls to prevent serializing the entire set of candidates every time. - let mut new_candidates = new_candidates - .into_par_iter() - .filter(|candidate| !self.candidates.contains(candidate)) - .collect::<_>>(); - - new_candidates.par_sort_unstable(); + // Only keep candidates we haven't seen before + for existing in self.candidates.iter() { + new_candidates.remove(existing); + } // Track new candidates for subsequent calls - self.candidates.par_extend(new_candidates.clone()); - - new_candidates - } - - #[tracing::instrument(skip_all)] - fn scan_sources(&mut self) { - let Some(walker) = &mut self.walker else { - return; - }; + self.candidates.extend(new_candidates.iter().cloned()); - for entry in walker.build().filter_map(Result::ok) { - let path = entry.into_path(); - let Ok(metadata) = path.metadata() else { - continue; - }; - if metadata.is_dir() { - self.dirs.push(path); - } else if metadata.is_file() { - let extension = path - .extension() - .and_then(|x| x.to_str()) - .unwrap_or_default(); // In case the file has no extension + let mut result: Vec = new_candidates.into_iter().collect(); + result.par_sort_unstable(); - match extension { - // Special handing for CSS files, we don't want to extract candidates from - // these files, but we do want to extract used CSS variables. - "css" => { - self.css_files.push(path.clone()); - } - _ => { - self.changed_content.push(ChangedContent::File( - path.to_path_buf(), - extension.to_owned(), - )); - } - } - - self.extensions.insert(extension.to_owned()); - self.files.push(path); - } - } + result } #[tracing::instrument(skip_all)] pub fn get_files(&mut self) -> Vec { - self.scan_sources(); + let _ = self.discover_sources(); self.files .par_iter() @@ -367,7 +263,7 @@ impl Scanner { return globs.clone(); } - self.scan_sources(); + let _ = self.discover_sources(); let mut globs = vec![]; for source in self.sources.iter() { @@ -456,6 +352,99 @@ impl Scanner { }) .collect() } + + #[tracing::instrument(skip_all)] + fn discover_sources(&mut self) -> (Vec>, Vec) { + if self.sources_scanned { + return (vec![], vec![]); + } + self.sources_scanned = true; + + let Some(walker) = &mut self.walker else { + return (vec![], vec![]); + }; + + // Use synchronous walk for the initial build (lower overhead) and parallel + // walk for subsequent calls (watch mode) where the overhead is amortised. + let all_entries = if self.has_scanned_once { + walk_parallel(walker) + } else { + walk_synchronous(walker) + }; + + let mut css_files: Vec = vec![]; + let mut content_paths: Vec<(PathBuf, String)> = Vec::new(); + let mut seen_files: FxHashSet = FxHashSet::default(); + + for (path, is_dir, extension) in all_entries { + if is_dir { + self.dirs.insert(path); + } else { + // Deduplicate: parallel walk can visit the same file from multiple threads + if !seen_files.insert(path.clone()) { + continue; + } + + // On re-scans, check mtime to skip unchanged files. + // On the first scan we skip this entirely to avoid extra + // metadata syscalls. + let changed = if self.has_scanned_once { + let current_mtime = std::fs::metadata(&path) + .ok() + .and_then(|m| m.modified().ok()); + + match current_mtime { + Some(mtime) => { + let prev = self.mtimes.insert(path.clone(), mtime); + prev.is_none_or(|prev| prev != mtime) + } + None => true, + } + } else { + true + }; + + match extension.as_str() { + // Special handing for CSS files, we don't want to extract candidates from + // these files, but we do want to extract used CSS variables. + "css" => { + if changed { + css_files.push(path.clone()); + } + } + _ => { + if changed { + content_paths.push((path.clone(), extension.clone())); + } + } + } + + self.extensions.insert(extension); + self.files.insert(path); + } + } + + // Read + preprocess all discovered files in parallel + let scanned_blobs: Vec> = content_paths + .into_par_iter() + .filter_map(|(path, ext)| { + let content = std::fs::read(&path).ok()?; + event!(tracing::Level::INFO, "Reading {:?}", path); + let processed = pre_process_input(content, &ext); + if processed.is_empty() { + None + } else { + Some(processed) + } + }) + .collect(); + + if !self.has_scanned_once { + self.has_scanned_once = true; + } + + (scanned_blobs, css_files) + } } fn read_changed_content(c: ChangedContent) -> Option> { @@ -474,26 +463,26 @@ fn read_changed_content(c: ChangedContent) -> Option> { ChangedContent::Content(contents, extension) => (contents.into_bytes(), extension), }; - Some(pre_process_input(&content, &extension)) + Some(pre_process_input(content, &extension)) } -pub fn pre_process_input(content: &[u8], extension: &str) -> Vec { +pub fn pre_process_input(content: Vec, extension: &str) -> Vec { use crate::extractor::pre_processors::*; match extension { - "clj" | "cljs" | "cljc" => Clojure.process(content), - "heex" | "eex" | "ex" | "exs" => Elixir.process(content), - "cshtml" | "razor" => Razor.process(content), - "haml" => Haml.process(content), - "json" => Json.process(content), - "md" | "mdx" => Markdown.process(content), - "pug" => Pug.process(content), - "rb" | "erb" => Ruby.process(content), - "slim" | "slang" => Slim.process(content), - "svelte" => Svelte.process(content), - "rs" => Rust.process(content), - "vue" => Vue.process(content), - _ => content.to_vec(), + "clj" | "cljs" | "cljc" => Clojure.process(&content), + "heex" | "eex" | "ex" | "exs" => Elixir.process(&content), + "cshtml" | "razor" => Razor.process(&content), + "haml" => Haml.process(&content), + "json" => Json.process(&content), + "md" | "mdx" => Markdown.process(&content), + "pug" => Pug.process(&content), + "rb" | "erb" => Ruby.process(&content), + "slim" | "slang" => Slim.process(&content), + "svelte" => Svelte.process(&content), + "rs" => Rust.process(&content), + "vue" => Vue.process(&content), + _ => content, } } @@ -512,23 +501,23 @@ fn read_all_files(changed_content: Vec) -> Vec> { } #[tracing::instrument(skip_all)] -fn extract_css_variables(blobs: Vec>) -> Vec { +fn extract_css_variables(blobs: Vec>) -> FxHashSet { extract(blobs, |mut extractor| { extractor.extract_variables_from_css() }) } #[tracing::instrument(skip_all)] -fn parse_all_blobs(blobs: Vec>) -> Vec { +fn parse_all_blobs(blobs: Vec>) -> FxHashSet { extract(blobs, |mut extractor| extractor.extract()) } #[tracing::instrument(skip_all)] -fn extract(blobs: Vec>, handle: H) -> Vec +fn extract(blobs: Vec>, handle: H) -> FxHashSet where H: Fn(Extractor) -> Vec + std::marker::Sync, { - let mut result: Vec<_> = blobs + blobs .par_iter() .flat_map(|blob| blob.par_split(|x| *x == b'\n')) .filter_map(|blob| { @@ -554,22 +543,97 @@ where }) .into_iter() .map(|s| unsafe { String::from_utf8_unchecked(s.to_vec()) }) - .collect(); + .collect() +} + +type WalkEntry = (PathBuf, bool, String); - // SAFETY: Unstable sort is faster and in this scenario it's also safe because we are - // guaranteed to have unique candidates. - result.par_sort_unstable(); +/// Walk the file system synchronously. Used for the initial build where the overhead of spawning +/// parallel walker threads is not worth it. +#[tracing::instrument(skip_all)] +fn walk_synchronous(walker: &mut WalkBuilder) -> Vec { + let mut entries = Vec::new(); + + for entry in walker.build().filter_map(Result::ok) { + let is_dir = entry.file_type().map(|ft| ft.is_dir()).unwrap_or(false); + let path = entry.into_path(); + + if is_dir { + entries.push((path, true, String::new())); + } else { + let ext = path + .extension() + .and_then(|x| x.to_str()) + .unwrap_or_default() + .to_owned(); + entries.push((path, false, ext)); + } + } - result + entries } -/// Create a walker for the given sources to detect all the files that we have to scan. +/// Walk the file system in parallel. Used in watch mode where the parallel walker overhead is +/// amortised across many rebuilds and subsequent calls are much faster. +#[tracing::instrument(skip_all)] +fn walk_parallel(walker: &mut WalkBuilder) -> Vec { + struct FlushOnDrop { + local: Vec, + shared: Arc>>, + } + + impl Drop for FlushOnDrop { + fn drop(&mut self) { + if !self.local.is_empty() { + self.shared.lock().unwrap().append(&mut self.local); + } + } + } + + let collected: Arc>> = Arc::new(Mutex::new(Vec::new())); + + walker.build_parallel().run(|| { + let mut buf = FlushOnDrop { + local: Vec::with_capacity(256), + shared: collected.clone(), + }; + + Box::new(move |entry| { + let Ok(entry) = entry else { + return ignore::WalkState::Continue; + }; + + let is_dir = entry.file_type().map(|ft| ft.is_dir()).unwrap_or(false); + let path = entry.into_path(); + + if is_dir { + buf.local.push((path, true, String::new())); + } else { + let ext = path + .extension() + .and_then(|x| x.to_str()) + .unwrap_or_default() + .to_owned(); + buf.local.push((path, false, ext)); + } + + if buf.local.len() >= 256 { + buf.shared.lock().unwrap().append(&mut buf.local); + } + + ignore::WalkState::Continue + }) + }); + + // All threads have finished and flushed their buffers via FlushOnDrop::drop + Arc::try_unwrap(collected).unwrap().into_inner().unwrap() +} + +/// Sets up a WalkBuilder with all source roots, gitignore rules, and source pattern matching. /// -/// The `mtimes` map is used to keep track of the last modified time of each file. This is used to -/// determine if a file or folder has changed since the last scan and we can skip folders that -/// haven't changed. -fn create_walker(sources: Sources) -> Option { - let mtimes: Arc>> = Default::default(); +/// This is the common setup shared between the full walker (with mtime tracking for re-scans) +/// and the parallel walker (without mtime tracking for the initial scan). +fn create_walker(sources: &Sources) -> Option { let mut other_roots: FxHashSet<&PathBuf> = FxHashSet::default(); let mut first_root: Option<&PathBuf> = None; let mut ignores: BTreeMap<&PathBuf, BTreeSet> = Default::default(); @@ -717,75 +781,68 @@ fn create_walker(sources: Sources) -> Option { builder.add_gitignore(ignore); } - builder.filter_entry({ - move |entry| { - let path = entry.path(); - - // Ensure the entries are matching any of the provided source patterns (this is - // necessary for manual-patterns that can filter the file extension) - if path.is_file() { - let mut matches = false; - for source in sources.iter() { - match source { - SourceEntry::Auto { base } | SourceEntry::External { base } => { - if path.starts_with(base) { - matches = true; - break; - } - } - SourceEntry::Pattern { base, pattern } => { - let mut pattern = pattern.to_string(); - // Ensure that the pattern is pinned to the base path. - if !pattern.starts_with("/") { - pattern = format!("/{pattern}"); - } - - // Check if path starts with base, if so, remove the prefix and check the remainder against the pattern - let remainder = path.strip_prefix(base); - if remainder.is_ok_and(|remainder| { - let mut path_str = remainder.to_string_lossy().to_string(); - if !path_str.starts_with("/") { - path_str = format!("/{path_str}"); - } - glob_match(pattern, path_str.as_bytes()) - }) { - matches = true; - break; - } - } - _ => {} - } - } + // Pre-compute source matching data to avoid allocations in the hot filter_entry path + let auto_bases: Vec = sources + .iter() + .filter_map(|source| match source { + SourceEntry::Auto { base } | SourceEntry::External { base } => Some(base.clone()), + _ => None, + }) + .collect(); - if !matches { - return false; - } + let pattern_sources: Vec<(PathBuf, String)> = sources + .iter() + .filter_map(|source| match source { + SourceEntry::Pattern { base, pattern } => { + let normalized = if pattern.starts_with("/") { + pattern.to_string() + } else { + format!("/{pattern}") + }; + Some((base.clone(), normalized)) } + _ => None, + }) + .collect(); - let mut mtimes = mtimes.lock().unwrap(); - let current_time = match entry.metadata() { - Ok(metadata) if metadata.is_file() => { - if let Ok(time) = metadata.modified() { - Some(time) - } else { - None - } - } - _ => None, - }; + // Source pattern matching filter (lock-free, safe for parallel walking) + builder.filter_entry(move |entry| { + let path = entry.path(); - let previous_time = - current_time.and_then(|time| mtimes.insert(entry.clone().into_path(), time)); + // Ensure the entries are matching any of the provided source patterns (this is + // necessary for manual-patterns that can filter the file extension) + if path.is_file() { + let mut matches = false; - match (current_time, previous_time) { - (Some(current), Some(prev)) if prev == current => false, - _ => { - event!(tracing::Level::INFO, "Discovering {:?}", path); + for base in &auto_bases { + if path.starts_with(base) { + matches = true; + break; + } + } - true + if !matches { + for (base, pattern) in &pattern_sources { + let remainder = path.strip_prefix(base); + if remainder.is_ok_and(|remainder| { + let mut path_str = remainder.to_string_lossy().to_string(); + if !path_str.starts_with("/") { + path_str = format!("/{path_str}"); + } + glob_match(pattern, path_str.as_bytes()) + }) { + matches = true; + break; + } } } + + if !matches { + return false; + } } + + true }); Some(builder) diff --git a/integrations/utils.ts b/integrations/utils.ts index a2fc0d58af9a..c5d3306c4677 100644 --- a/integrations/utils.ts +++ b/integrations/utils.ts @@ -498,6 +498,7 @@ async function overwriteVersionsInPackageJson(content: string): Promise json.pnpm.overrides['@tailwindcss/cli>tailwindcss'] = resolveVersion(pkg) json.pnpm.overrides['@tailwindcss/postcss>tailwindcss'] = resolveVersion(pkg) json.pnpm.overrides['@tailwindcss/vite>tailwindcss'] = resolveVersion(pkg) + json.pnpm.overrides['@tailwindcss/webpack>tailwindcss'] = resolveVersion(pkg) } else { json.pnpm.overrides[pkg] = resolveVersion(pkg) } diff --git a/integrations/vite/astro.test.ts b/integrations/vite/astro.test.ts index 43406624c316..f828b5071b60 100644 --- a/integrations/vite/astro.test.ts +++ b/integrations/vite/astro.test.ts @@ -1,4 +1,4 @@ -import { candidate, fetchStyles, html, js, json, retryAssertion, test, ts } from '../utils' +import { candidate, css, fetchStyles, html, js, json, retryAssertion, test, ts } from '../utils' test( 'dev mode', @@ -129,3 +129,73 @@ test( await fs.expectFileToContain(files[0][0], [candidate`underline`, candidate`overline`]) }, ) + +// https://github.com/tailwindlabs/tailwindcss/issues/19677 +test( + 'import aliases should work in + + +

Astro

+ + + `, + 'src/styles/global.css': css`@import 'tailwindcss';`, + }, + }, + async ({ fs, exec, expect }) => { + await exec('pnpm astro build') + + let files = await fs.glob('dist/**/*.css') + expect(files).toHaveLength(1) + + await fs.expectFileToContain(files[0][0], [candidate`underline`]) + }, +) diff --git a/integrations/vite/index.test.ts b/integrations/vite/index.test.ts index b8b2ad6e39df..81236579d378 100644 --- a/integrations/vite/index.test.ts +++ b/integrations/vite/index.test.ts @@ -7,6 +7,7 @@ import { html, js, json, + jsx, retryAssertion, test, ts, @@ -472,6 +473,117 @@ describe.each(['postcss', 'lightningcss'])('%s', (transformer) => { }, ) + describe.sequential.each([['^6'], ['7.0.8'], ['7.1.12'], ['7.3.1']])( + 'Using Vite %s', + (version) => { + test( + 'external source file changes trigger a full reload', + { + fs: { + 'package.json': json`{}`, + 'pnpm-workspace.yaml': yaml` + # + packages: + - project-a + `, + 'project-a/package.json': json` + { + "type": "module", + "dependencies": { + "@tailwindcss/vite": "workspace:^", + "tailwindcss": "workspace:^" + }, + "devDependencies": { + ${transformer === 'lightningcss' ? `"lightningcss": "^1",` : ''} + "vite": "${version}" + } + } + `, + 'project-a/vite.config.ts': ts` + import fs from 'node:fs' + import path from 'node:path' + import tailwindcss from '@tailwindcss/vite' + import { defineConfig } from 'vite' + + export default defineConfig({ + css: ${transformer === 'postcss' ? '{}' : "{ transformer: 'lightningcss' }"}, + build: { cssMinify: false }, + plugins: [tailwindcss()], + logLevel: 'info', + }) + `, + 'project-a/index.html': html` + + + + + +
+ + + + `, + 'project-a/src/main.ts': jsx`import { classes } from './app'`, + 'project-a/src/app.ts': jsx`export let classes = "content-['project-a/src/app.ts']"`, + 'project-a/src/index.css': css` + @import 'tailwindcss'; + @source '../../project-b/**/*.php'; + `, + 'project-b/src/index.php': html` +
+ `, + }, + }, + async ({ root, spawn, fs, expect }) => { + let process = await spawn('pnpm vite dev --debug hmr', { + cwd: path.join(root, 'project-a'), + }) + await process.onStdout((m) => m.includes('ready in')) + + let url = '' + await process.onStdout((m) => { + let match = /Local:\s*(http.*)\//.exec(m) + if (match) url = match[1] + return Boolean(url) + }) + + await retryAssertion(async () => { + let styles = await fetchStyles(url, '/index.html') + expect(styles).toContain(candidate`content-['project-b/src/index.php']`) + }) + + // Flush all messages so that we can be sure the next messages are from + // the file changes we're about to make + process.flush() + + // Changing an external .php file should trigger a full reload + { + await fs.write( + 'project-b/src/index.php', + txt`
`, + ) + + // Ensure the page reloaded + if (version === '^6' || version === '7.0.8') { + await process.onStdout((m) => m.includes('page reload') && m.includes('index.php')) + } else { + await process.onStderr( + (m) => m.includes('vite:hmr (client)') && m.includes('index.php'), + ) + } + await process.onStderr((m) => m.includes('vite:hmr (ssr)') && m.includes('index.php')) + + // Ensure the styles were regenerated with the new content + let styles = await fetchStyles(url, '/index.html') + expect(styles).toContain(candidate`content-['updated:project-b/src/index.php']`) + } + }, + ) + }, + ) + test( `source(none) disables looking at the module graph`, { diff --git a/integrations/webpack/loader.test.ts b/integrations/webpack/loader.test.ts new file mode 100644 index 000000000000..3a3782c0d7a3 --- /dev/null +++ b/integrations/webpack/loader.test.ts @@ -0,0 +1,420 @@ +import { css, html, js, json, test } from '../utils' + +test( + '@tailwindcss/webpack loader (build)', + { + fs: { + 'package.json': json` + { + "main": "./src/index.js", + "browser": "./src/index.js", + "dependencies": { + "css-loader": "^6", + "webpack": "^5", + "webpack-cli": "^5", + "mini-css-extract-plugin": "^2", + "tailwindcss": "workspace:^", + "@tailwindcss/webpack": "workspace:^" + } + } + `, + 'webpack.config.js': js` + let MiniCssExtractPlugin = require('mini-css-extract-plugin') + + module.exports = { + output: { + clean: true, + }, + plugins: [new MiniCssExtractPlugin()], + module: { + rules: [ + { + test: /.css$/i, + use: [MiniCssExtractPlugin.loader, 'css-loader', '@tailwindcss/webpack'], + }, + ], + }, + } + `, + 'src/index.js': js`import './index.css'`, + 'src/index.html': html` +
+ `, + 'src/index.css': css` + @import 'tailwindcss/theme'; + @import 'tailwindcss/utilities'; + `, + }, + }, + async ({ fs, exec, expect }) => { + await exec('pnpm webpack --mode=development') + + expect(await fs.dumpFiles('./dist/*.css')).toMatchInlineSnapshot(` + " + --- ./dist/main.css --- + .flex { + display: flex; + } + " + `) + }, +) + +test( + '@tailwindcss/webpack loader (watch)', + { + fs: { + 'package.json': json` + { + "main": "./src/index.js", + "browser": "./src/index.js", + "dependencies": { + "css-loader": "^6", + "webpack": "^5", + "webpack-cli": "^5", + "mini-css-extract-plugin": "^2", + "tailwindcss": "workspace:^", + "@tailwindcss/webpack": "workspace:^" + } + } + `, + 'webpack.config.js': js` + let MiniCssExtractPlugin = require('mini-css-extract-plugin') + + module.exports = { + output: { + clean: true, + }, + plugins: [new MiniCssExtractPlugin()], + module: { + rules: [ + { + test: /.css$/i, + use: [MiniCssExtractPlugin.loader, 'css-loader', '@tailwindcss/webpack'], + }, + ], + }, + } + `, + 'src/index.js': js`import './index.css'`, + 'src/index.html': html` +
+ `, + 'src/index.css': css` + @import 'tailwindcss/theme'; + @import 'tailwindcss/utilities'; + `, + }, + }, + async ({ fs, spawn, exec, expect }) => { + // Generate the initial build so output CSS files exist on disk + await exec('pnpm webpack --mode=development') + + let process = await spawn('pnpm webpack --mode=development --watch') + await process.onStdout((m) => m.includes('compiled successfully in')) + + expect(await fs.dumpFiles('./dist/*.css')).toMatchInlineSnapshot(` + " + --- ./dist/main.css --- + .flex { + display: flex; + } + " + `) + + // Add a new Tailwind class to the HTML file + await fs.write('src/index.html', html` +
+ `) + await process.onStdout((m) => m.includes('compiled successfully in')) + + expect(await fs.dumpFiles('./dist/*.css')).toMatchInlineSnapshot(` + " + --- ./dist/main.css --- + .flex { + display: flex; + } + .underline { + text-decoration-line: underline; + } + " + `) + }, +) + +test( + '@tailwindcss/webpack loader with @apply', + { + fs: { + 'package.json': json` + { + "main": "./src/index.js", + "browser": "./src/index.js", + "dependencies": { + "css-loader": "^6", + "webpack": "^5", + "webpack-cli": "^5", + "mini-css-extract-plugin": "^2", + "tailwindcss": "workspace:^", + "@tailwindcss/webpack": "workspace:^" + } + } + `, + 'webpack.config.js': js` + let MiniCssExtractPlugin = require('mini-css-extract-plugin') + + module.exports = { + output: { + clean: true, + }, + plugins: [new MiniCssExtractPlugin()], + module: { + rules: [ + { + test: /.css$/i, + use: [MiniCssExtractPlugin.loader, 'css-loader', '@tailwindcss/webpack'], + }, + ], + }, + } + `, + 'src/index.js': js`import './index.css'`, + 'src/index.css': css` + @import 'tailwindcss/theme'; + + .btn { + @apply flex items-center px-4 py-2 rounded-md; + } + `, + }, + }, + async ({ fs, exec, expect }) => { + await exec('pnpm webpack --mode=development') + + expect(await fs.dumpFiles('./dist/*.css')).toMatchInlineSnapshot(` + " + --- ./dist/main.css --- + :root, :host { + --spacing: 0.25rem; + --radius-md: 0.375rem; + } + .btn { + display: flex; + align-items: center; + border-radius: var(--radius-md); + padding-inline: calc(var(--spacing) * 4); + padding-block: calc(var(--spacing) * 2); + } + " + `) + }, +) + +test( + '@tailwindcss/webpack loader with optimization', + { + fs: { + 'package.json': json` + { + "main": "./src/index.js", + "browser": "./src/index.js", + "dependencies": { + "css-loader": "^6", + "webpack": "^5", + "webpack-cli": "^5", + "mini-css-extract-plugin": "^2", + "tailwindcss": "workspace:^", + "@tailwindcss/webpack": "workspace:^" + } + } + `, + 'webpack.config.js': js` + let MiniCssExtractPlugin = require('mini-css-extract-plugin') + + module.exports = { + output: { + clean: true, + }, + plugins: [new MiniCssExtractPlugin()], + module: { + rules: [ + { + test: /.css$/i, + use: [ + MiniCssExtractPlugin.loader, + 'css-loader', + { + loader: '@tailwindcss/webpack', + options: { + optimize: true, + }, + }, + ], + }, + ], + }, + } + `, + 'src/index.js': js`import './index.css'`, + 'src/index.html': html` +
+ `, + 'src/index.css': css` + @import 'tailwindcss/theme'; + @import 'tailwindcss/utilities'; + `, + }, + }, + async ({ fs, exec, expect }) => { + await exec('pnpm webpack --mode=development') + + expect(await fs.dumpFiles('./dist/*.css')).toMatchInlineSnapshot(` + " + --- ./dist/main.css --- + .flex{display:flex} + " + `) + }, +) + +test( + '@tailwindcss/webpack loader with CSS @import', + { + fs: { + 'package.json': json` + { + "main": "./src/index.js", + "browser": "./src/index.js", + "dependencies": { + "css-loader": "^6", + "webpack": "^5", + "webpack-cli": "^5", + "mini-css-extract-plugin": "^2", + "tailwindcss": "workspace:^", + "@tailwindcss/webpack": "workspace:^" + } + } + `, + 'webpack.config.js': js` + let MiniCssExtractPlugin = require('mini-css-extract-plugin') + + module.exports = { + output: { + clean: true, + }, + plugins: [new MiniCssExtractPlugin()], + module: { + rules: [ + { + test: /.css$/i, + use: [MiniCssExtractPlugin.loader, 'css-loader', '@tailwindcss/webpack'], + }, + ], + }, + } + `, + 'src/index.js': js`import './index.css'`, + 'src/index.html': html` +
+ `, + 'src/index.css': css` + @import './custom.css'; + @import 'tailwindcss/theme'; + @import 'tailwindcss/utilities'; + `, + 'src/custom.css': css` + /**/ + @utility custom-util { + color: var(--color-red-500); + } + `, + }, + }, + async ({ fs, exec, expect }) => { + await exec('pnpm webpack --mode=development') + + expect(await fs.dumpFiles('./dist/*.css')).toMatchInlineSnapshot(` + " + --- ./dist/main.css --- + :root, :host { + --color-red-500: oklch(63.7% 0.237 25.331); + } + .flex { + display: flex; + } + .custom-util { + color: var(--color-red-500); + } + " + `) + }, +) + +test( + '@tailwindcss/webpack loader with @plugin', + { + fs: { + 'package.json': json` + { + "main": "./src/index.js", + "browser": "./src/index.js", + "dependencies": { + "css-loader": "^6", + "webpack": "^5", + "webpack-cli": "^5", + "mini-css-extract-plugin": "^2", + "tailwindcss": "workspace:^", + "@tailwindcss/webpack": "workspace:^" + } + } + `, + 'webpack.config.js': js` + let MiniCssExtractPlugin = require('mini-css-extract-plugin') + + module.exports = { + output: { + clean: true, + }, + plugins: [new MiniCssExtractPlugin()], + module: { + rules: [ + { + test: /.css$/i, + use: [MiniCssExtractPlugin.loader, 'css-loader', '@tailwindcss/webpack'], + }, + ], + }, + } + `, + 'src/index.js': js`import './index.css'`, + 'src/index.html': html` +
+ `, + 'src/index.css': css` + @import 'tailwindcss/utilities'; + @plugin './plugin.js'; + `, + 'src/plugin.js': js` + export default function ({ addUtilities }) { + addUtilities({ + '.custom-underline': { + 'border-bottom': '1px solid green', + }, + }) + } + `, + }, + }, + async ({ fs, exec, expect }) => { + await exec('pnpm webpack --mode=development') + + expect(await fs.dumpFiles('./dist/*.css')).toMatchInlineSnapshot(` + " + --- ./dist/main.css --- + .custom-underline { + border-bottom: 1px solid green; + } + " + `) + }, +) diff --git a/package.json b/package.json index 1b5a50a82d97..e1e310c69d52 100644 --- a/package.json +++ b/package.json @@ -48,7 +48,7 @@ }, "license": "MIT", "devDependencies": { - "@playwright/test": "^1.57.0", + "@playwright/test": "^1.58.0", "@types/node": "catalog:", "postcss": "8.5.6", "postcss-import": "^16.1.1", @@ -56,14 +56,14 @@ "prettier-plugin-embed": "^0.5.1", "prettier-plugin-organize-imports": "^4.3.0", "tsup": "^8.5.1", - "turbo": "^2.7.2", + "turbo": "^2.7.6", "typescript": "^5.5.4", - "vitest": "^4.0.3" + "vitest": "^4.0.18" }, "packageManager": "pnpm@9.6.0", "pnpm": { "patchedDependencies": { - "lightningcss@1.30.2": "patches/lightningcss@1.30.2.patch", + "lightningcss@1.31.1": "patches/lightningcss@1.31.1.patch", "@parcel/watcher@2.5.1": "patches/@parcel__watcher@2.5.1.patch" } } diff --git a/packages/@tailwindcss-browser/README.md b/packages/@tailwindcss-browser/README.md index 7d21bd88385a..5f532607d00a 100644 --- a/packages/@tailwindcss-browser/README.md +++ b/packages/@tailwindcss-browser/README.md @@ -13,10 +13,10 @@

- Build Status + Build Status Total Downloads - Latest Release - License + Latest Release + License

--- @@ -29,8 +29,8 @@ For full documentation, visit [tailwindcss.com](https://tailwindcss.com). For help, discussion about best practices, or feature ideas: -[Discuss Tailwind CSS on GitHub](https://github.com/tailwindcss/tailwindcss/discussions) +[Discuss Tailwind CSS on GitHub](https://github.com/tailwindlabs/tailwindcss/discussions) ## Contributing -If you're interested in contributing to Tailwind CSS, please read our [contributing docs](https://github.com/tailwindcss/tailwindcss/blob/next/.github/CONTRIBUTING.md) **before submitting a pull request**. +If you're interested in contributing to Tailwind CSS, please read our [contributing docs](https://github.com/tailwindlabs/tailwindcss/blob/main/.github/CONTRIBUTING.md) **before submitting a pull request**. diff --git a/packages/@tailwindcss-browser/package.json b/packages/@tailwindcss-browser/package.json index 6bda85f75c78..8075cfb3fc0c 100644 --- a/packages/@tailwindcss-browser/package.json +++ b/packages/@tailwindcss-browser/package.json @@ -1,6 +1,6 @@ { "name": "@tailwindcss/browser", - "version": "4.1.18", + "version": "4.2.0", "description": "A utility-first CSS framework for rapidly building custom user interfaces.", "license": "MIT", "main": "./dist/index.global.js", @@ -30,7 +30,7 @@ "access": "public" }, "devDependencies": { - "h3": "^1.15.4", + "h3": "^1.15.5", "listhen": "^1.9.0", "tailwindcss": "workspace:*" } diff --git a/packages/@tailwindcss-cli/README.md b/packages/@tailwindcss-cli/README.md index 7d21bd88385a..5f532607d00a 100644 --- a/packages/@tailwindcss-cli/README.md +++ b/packages/@tailwindcss-cli/README.md @@ -13,10 +13,10 @@

- Build Status + Build Status Total Downloads - Latest Release - License + Latest Release + License

--- @@ -29,8 +29,8 @@ For full documentation, visit [tailwindcss.com](https://tailwindcss.com). For help, discussion about best practices, or feature ideas: -[Discuss Tailwind CSS on GitHub](https://github.com/tailwindcss/tailwindcss/discussions) +[Discuss Tailwind CSS on GitHub](https://github.com/tailwindlabs/tailwindcss/discussions) ## Contributing -If you're interested in contributing to Tailwind CSS, please read our [contributing docs](https://github.com/tailwindcss/tailwindcss/blob/next/.github/CONTRIBUTING.md) **before submitting a pull request**. +If you're interested in contributing to Tailwind CSS, please read our [contributing docs](https://github.com/tailwindlabs/tailwindcss/blob/main/.github/CONTRIBUTING.md) **before submitting a pull request**. diff --git a/packages/@tailwindcss-cli/package.json b/packages/@tailwindcss-cli/package.json index 346d244ec3bf..af488a701caa 100644 --- a/packages/@tailwindcss-cli/package.json +++ b/packages/@tailwindcss-cli/package.json @@ -1,6 +1,6 @@ { "name": "@tailwindcss/cli", - "version": "4.1.18", + "version": "4.2.0", "description": "A utility-first CSS framework for rapidly building custom user interfaces.", "license": "MIT", "repository": { @@ -32,7 +32,7 @@ "@parcel/watcher": "^2.5.1", "@tailwindcss/node": "workspace:*", "@tailwindcss/oxide": "workspace:*", - "enhanced-resolve": "^5.18.4", + "enhanced-resolve": "^5.19.0", "mri": "^1.2.0", "picocolors": "^1.1.1", "tailwindcss": "workspace:*" diff --git a/packages/@tailwindcss-node/README.md b/packages/@tailwindcss-node/README.md index 7d21bd88385a..5f532607d00a 100644 --- a/packages/@tailwindcss-node/README.md +++ b/packages/@tailwindcss-node/README.md @@ -13,10 +13,10 @@

- Build Status + Build Status Total Downloads - Latest Release - License + Latest Release + License

--- @@ -29,8 +29,8 @@ For full documentation, visit [tailwindcss.com](https://tailwindcss.com). For help, discussion about best practices, or feature ideas: -[Discuss Tailwind CSS on GitHub](https://github.com/tailwindcss/tailwindcss/discussions) +[Discuss Tailwind CSS on GitHub](https://github.com/tailwindlabs/tailwindcss/discussions) ## Contributing -If you're interested in contributing to Tailwind CSS, please read our [contributing docs](https://github.com/tailwindcss/tailwindcss/blob/next/.github/CONTRIBUTING.md) **before submitting a pull request**. +If you're interested in contributing to Tailwind CSS, please read our [contributing docs](https://github.com/tailwindlabs/tailwindcss/blob/main/.github/CONTRIBUTING.md) **before submitting a pull request**. diff --git a/packages/@tailwindcss-node/package.json b/packages/@tailwindcss-node/package.json index 257b440aea3a..064b53f802a7 100644 --- a/packages/@tailwindcss-node/package.json +++ b/packages/@tailwindcss-node/package.json @@ -1,6 +1,6 @@ { "name": "@tailwindcss/node", - "version": "4.1.18", + "version": "4.2.0", "description": "A utility-first CSS framework for rapidly building custom user interfaces.", "license": "MIT", "repository": { @@ -37,8 +37,8 @@ } }, "dependencies": { - "@jridgewell/remapping": "^2.3.4", - "enhanced-resolve": "^5.18.4", + "@jridgewell/remapping": "^2.3.5", + "enhanced-resolve": "^5.19.0", "jiti": "^2.6.1", "lightningcss": "catalog:", "magic-string": "^0.30.21", diff --git a/packages/@tailwindcss-postcss/README.md b/packages/@tailwindcss-postcss/README.md index db2a6b9a007d..6aec3fe253de 100644 --- a/packages/@tailwindcss-postcss/README.md +++ b/packages/@tailwindcss-postcss/README.md @@ -13,10 +13,10 @@

- Build Status + Build Status Total Downloads - Latest Release - License + Latest Release + License

--- @@ -29,11 +29,11 @@ For full documentation, visit [tailwindcss.com](https://tailwindcss.com). For help, discussion about best practices, or feature ideas: -[Discuss Tailwind CSS on GitHub](https://github.com/tailwindcss/tailwindcss/discussions) +[Discuss Tailwind CSS on GitHub](https://github.com/tailwindlabs/tailwindcss/discussions) ## Contributing -If you're interested in contributing to Tailwind CSS, please read our [contributing docs](https://github.com/tailwindcss/tailwindcss/blob/next/.github/CONTRIBUTING.md) **before submitting a pull request**. +If you're interested in contributing to Tailwind CSS, please read our [contributing docs](https://github.com/tailwindlabs/tailwindcss/blob/main/.github/CONTRIBUTING.md) **before submitting a pull request**. --- @@ -44,14 +44,14 @@ If you're interested in contributing to Tailwind CSS, please read our [contribut You can use the `base` option (defaults to the current working directory) to change the directory in which the plugin searches for source files: ```js -import tailwindcss from "@tailwindcss/postcss" +import tailwindcss from '@tailwindcss/postcss' export default { - plugins: [ - tailwindcss({ - base: path.resolve(__dirname, "./path") - }) - ] + plugins: [ + tailwindcss({ + base: path.resolve(__dirname, './path'), + }), + ], } ``` diff --git a/packages/@tailwindcss-postcss/package.json b/packages/@tailwindcss-postcss/package.json index 22e775d728ae..5180133e8f27 100644 --- a/packages/@tailwindcss-postcss/package.json +++ b/packages/@tailwindcss-postcss/package.json @@ -1,6 +1,6 @@ { "name": "@tailwindcss/postcss", - "version": "4.1.18", + "version": "4.2.0", "description": "PostCSS plugin for Tailwind CSS, a utility-first CSS framework for rapidly building custom user interfaces", "license": "MIT", "repository": { @@ -33,7 +33,7 @@ "@alloc/quick-lru": "^5.2.0", "@tailwindcss/node": "workspace:*", "@tailwindcss/oxide": "workspace:*", - "postcss": "^8.4.41", + "postcss": "^8.5.6", "tailwindcss": "workspace:*" }, "devDependencies": { diff --git a/packages/@tailwindcss-postcss/src/__snapshots__/index.test.ts.snap b/packages/@tailwindcss-postcss/src/__snapshots__/index.test.ts.snap index 8fdc0dbf740f..fd6db912cf4a 100644 --- a/packages/@tailwindcss-postcss/src/__snapshots__/index.test.ts.snap +++ b/packages/@tailwindcss-postcss/src/__snapshots__/index.test.ts.snap @@ -11,8 +11,10 @@ exports[`\`@import 'tailwindcss'\` is replaced with the generated CSS 1`] = ` @layer theme { :root, :host { - --font-sans: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; - --font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; + --font-sans: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", + "Noto Color Emoji"; + --font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", + monospace; --color-black: #000; --text-2xl: 1.5rem; --text-2xl--line-height: calc(2 / 1.5); diff --git a/packages/@tailwindcss-standalone/package.json b/packages/@tailwindcss-standalone/package.json index cfe124563789..50039f29a459 100644 --- a/packages/@tailwindcss-standalone/package.json +++ b/packages/@tailwindcss-standalone/package.json @@ -1,6 +1,6 @@ { "name": "@tailwindcss/standalone", - "version": "4.1.18", + "version": "4.2.0", "private": true, "description": "Standalone CLI for Tailwind CSS", "license": "MIT", @@ -30,20 +30,20 @@ "@tailwindcss/forms": "^0.5.11", "@tailwindcss/typography": "^0.5.19", "detect-libc": "1.0.3", - "enhanced-resolve": "^5.18.4", + "enhanced-resolve": "^5.19.0", "tailwindcss": "workspace:*" }, "__notes": "These binary packages must be included so Bun can build the CLI for all supported platforms. We also rely on Lightning CSS and Parcel being patched so Bun can statically analyze the executables.", "devDependencies": { - "@parcel/watcher-darwin-arm64": "^2.5.1", - "@parcel/watcher-darwin-x64": "^2.5.1", - "@parcel/watcher-linux-arm64-glibc": "^2.5.1", - "@parcel/watcher-linux-arm64-musl": "^2.5.1", - "@parcel/watcher-linux-x64-glibc": "^2.5.1", - "@parcel/watcher-linux-x64-musl": "^2.5.1", - "@parcel/watcher-win32-x64": "^2.5.1", - "@types/bun": "^1.3.5", - "bun": "^1.3.5", + "@parcel/watcher-darwin-arm64": "^2.5.6", + "@parcel/watcher-darwin-x64": "^2.5.6", + "@parcel/watcher-linux-arm64-glibc": "^2.5.6", + "@parcel/watcher-linux-arm64-musl": "^2.5.6", + "@parcel/watcher-linux-x64-glibc": "^2.5.6", + "@parcel/watcher-linux-x64-musl": "^2.5.6", + "@parcel/watcher-win32-x64": "^2.5.6", + "@types/bun": "^1.3.9", + "bun": "^1.3.9", "lightningcss-darwin-arm64": "catalog:", "lightningcss-darwin-x64": "catalog:", "lightningcss-linux-arm64-gnu": "catalog:", diff --git a/packages/@tailwindcss-standalone/src/index.ts b/packages/@tailwindcss-standalone/src/index.ts index ce6ba84d11fe..23a928f8b68b 100644 --- a/packages/@tailwindcss-standalone/src/index.ts +++ b/packages/@tailwindcss-standalone/src/index.ts @@ -75,12 +75,10 @@ Bun.plugin({ 'tailwindcss/plugin': await import('tailwindcss/plugin'), 'tailwindcss/plugin.js': await import('tailwindcss/plugin'), 'tailwindcss/package.json': await import('tailwindcss/package.json'), - 'tailwindcss/lib/util/flattenColorPalette': await import( - 'tailwindcss/lib/util/flattenColorPalette' - ), - 'tailwindcss/lib/util/flattenColorPalette.js': await import( - 'tailwindcss/lib/util/flattenColorPalette' - ), + 'tailwindcss/lib/util/flattenColorPalette': + await import('tailwindcss/lib/util/flattenColorPalette'), + 'tailwindcss/lib/util/flattenColorPalette.js': + await import('tailwindcss/lib/util/flattenColorPalette'), 'tailwindcss/defaultTheme': await import('tailwindcss/defaultTheme'), 'tailwindcss/defaultTheme.js': await import('tailwindcss/defaultTheme'), } diff --git a/packages/@tailwindcss-upgrade/README.md b/packages/@tailwindcss-upgrade/README.md index 7d21bd88385a..5f532607d00a 100644 --- a/packages/@tailwindcss-upgrade/README.md +++ b/packages/@tailwindcss-upgrade/README.md @@ -13,10 +13,10 @@

- Build Status + Build Status Total Downloads - Latest Release - License + Latest Release + License

--- @@ -29,8 +29,8 @@ For full documentation, visit [tailwindcss.com](https://tailwindcss.com). For help, discussion about best practices, or feature ideas: -[Discuss Tailwind CSS on GitHub](https://github.com/tailwindcss/tailwindcss/discussions) +[Discuss Tailwind CSS on GitHub](https://github.com/tailwindlabs/tailwindcss/discussions) ## Contributing -If you're interested in contributing to Tailwind CSS, please read our [contributing docs](https://github.com/tailwindcss/tailwindcss/blob/next/.github/CONTRIBUTING.md) **before submitting a pull request**. +If you're interested in contributing to Tailwind CSS, please read our [contributing docs](https://github.com/tailwindlabs/tailwindcss/blob/main/.github/CONTRIBUTING.md) **before submitting a pull request**. diff --git a/packages/@tailwindcss-upgrade/package.json b/packages/@tailwindcss-upgrade/package.json index e41e40b22fcc..b8191e23c58e 100644 --- a/packages/@tailwindcss-upgrade/package.json +++ b/packages/@tailwindcss-upgrade/package.json @@ -1,6 +1,6 @@ { "name": "@tailwindcss/upgrade", - "version": "4.1.18", + "version": "4.2.0", "description": "A utility-first CSS framework for rapidly building custom user interfaces.", "license": "MIT", "repository": { @@ -31,16 +31,16 @@ "@tailwindcss/oxide": "workspace:*", "braces": "^3.0.3", "dedent": "1.7.1", - "enhanced-resolve": "^5.18.4", + "enhanced-resolve": "^5.19.0", "globby": "^15.0.0", "jiti": "^2.0.0-beta.3", "mri": "^1.2.0", "picocolors": "^1.1.1", - "postcss": "^8.4.41", + "postcss": "^8.5.6", "postcss-import": "^16.1.1", "postcss-selector-parser": "^7.1.1", "prettier": "catalog:", - "semver": "^7.7.3", + "semver": "^7.7.4", "tailwindcss": "workspace:*", "tree-sitter": "^0.22.4", "tree-sitter-typescript": "^0.23.2" diff --git a/packages/@tailwindcss-vite/README.md b/packages/@tailwindcss-vite/README.md index 53e03ab47e89..1a5d25c73652 100644 --- a/packages/@tailwindcss-vite/README.md +++ b/packages/@tailwindcss-vite/README.md @@ -13,10 +13,10 @@

- Build Status + Build Status Total Downloads - Latest Release - License + Latest Release + License

--- @@ -29,11 +29,11 @@ For full documentation, visit [tailwindcss.com](https://tailwindcss.com). For help, discussion about best practices, or feature ideas: -[Discuss Tailwind CSS on GitHub](https://github.com/tailwindcss/tailwindcss/discussions) +[Discuss Tailwind CSS on GitHub](https://github.com/tailwindlabs/tailwindcss/discussions) ## Contributing -If you're interested in contributing to Tailwind CSS, please read our [contributing docs](https://github.com/tailwindcss/tailwindcss/blob/next/.github/CONTRIBUTING.md) **before submitting a pull request**. +If you're interested in contributing to Tailwind CSS, please read our [contributing docs](https://github.com/tailwindlabs/tailwindcss/blob/main/.github/CONTRIBUTING.md) **before submitting a pull request**. --- diff --git a/packages/@tailwindcss-vite/package.json b/packages/@tailwindcss-vite/package.json index bdf5518e289f..db0297fc215a 100644 --- a/packages/@tailwindcss-vite/package.json +++ b/packages/@tailwindcss-vite/package.json @@ -1,6 +1,6 @@ { "name": "@tailwindcss/vite", - "version": "4.1.18", + "version": "4.2.0", "description": "A utility-first CSS framework for rapidly building custom user interfaces.", "license": "MIT", "repository": { diff --git a/packages/@tailwindcss-vite/src/index.ts b/packages/@tailwindcss-vite/src/index.ts index 341c662b164e..3ab7c3a0f2f8 100644 --- a/packages/@tailwindcss-vite/src/index.ts +++ b/packages/@tailwindcss-vite/src/index.ts @@ -9,9 +9,16 @@ import { } from '@tailwindcss/node' import { clearRequireCache } from '@tailwindcss/node/require-cache' import { Scanner } from '@tailwindcss/oxide' +import { realpathSync } from 'node:fs' import fs from 'node:fs/promises' import path from 'node:path' -import type { Environment, Plugin, ResolvedConfig, ViteDevServer } from 'vite' +import type { + Environment, + InternalResolveOptions, + Plugin, + ResolvedConfig, + ViteDevServer, +} from 'vite' import * as vite from 'vite' const DEBUG = env.DEBUG @@ -58,8 +65,36 @@ export default function tailwindcss(opts: PluginOptions = {}): Plugin[] { customCssResolver = (id: string, base: string) => cssResolver(id, base, true, isSSR) customJsResolver = (id: string, base: string) => jsResolver(id, base, true, isSSR) } else { + type ResolveIdFn = ( + environment: Environment, + id: string, + importer?: string, + aliasOnly?: boolean, + ) => Promise + + // There are cases where Environment API is available, + // but `createResolver` is still overriden (for example astro v5) + // + // Copied as-is from vite, because this function is not a part of public API + // + // TODO: Remove this function and pre-environment code when Vite < 7 is no longer supported + function createBackCompatIdResolver( + config: ResolvedConfig, + options?: Partial, + ): ResolveIdFn { + const compatResolve = config.createResolver(options) + let resolve: ResolveIdFn + return async (environment, id, importer, aliasOnly) => { + if (environment.name === 'client' || environment.name === 'ssr') { + return compatResolve(id, importer, aliasOnly, environment.name === 'ssr') + } + resolve ??= vite.createIdResolver(config, options) + return resolve(environment, id, importer, aliasOnly) + } + } + // Newer Vite versions - let cssResolver = vite.createIdResolver(env.config, { + let cssResolver = createBackCompatIdResolver(env.config, { ...env.config.resolve, extensions: ['.css'], mainFields: ['style'], @@ -68,7 +103,7 @@ export default function tailwindcss(opts: PluginOptions = {}): Plugin[] { preferRelative: true, }) - let jsResolver = vite.createIdResolver(env.config, env.config.resolve) + let jsResolver = createBackCompatIdResolver(env.config, env.config.resolve) customCssResolver = (id: string, base: string) => cssResolver(env, id, base, true) customJsResolver = (id: string, base: string) => jsResolver(env, id, base, true) @@ -151,6 +186,64 @@ export default function tailwindcss(opts: PluginOptions = {}): Plugin[] { return result }, }, + + hotUpdate({ file, modules, timestamp, server }) { + // Ensure full-reloads are triggered for files that are being watched by + // Tailwind but aren't part of the module graph (like PHP or HTML + // files). If we don't do this, then changes to those files won't + // trigger a reload at all since Vite doesn't know about them. + { + // It's a little bit confusing, because due to the `addWatchFile` + // calls, it _is_ part of the module graph but nothing is really + // handling those files. These modules typically have an id of + // undefined and/or have a type of 'asset'. + // + // If we call `addWatchFile` on a file that is part of the actual + // module graph, then we will see a module for it with a type of `js` + // and a type of `asset`. We are only interested if _all_ of them are + // missing an id and/or have a type of 'asset', which is a strong + // signal that the changed file is not being handled by Vite or any of + // the plugins. + // + // Note: in Vite v7.0.6 the modules here will have a type of `js`, not + // 'asset'. But it will also have a `HARD_INVALIDATED` state and will + // do a full page reload already. + let isExternalFile = modules.every((mod) => mod.type === 'asset' || mod.id === undefined) + if (!isExternalFile) return + + for (let env of new Set([this.environment.name, 'client'])) { + let roots = rootsByEnv.get(env) + if (roots.size === 0) continue + + // If the file is not being watched by any of the roots, then we can + // skip the reload since it's not relevant to Tailwind CSS. + if (!isScannedFile(file, modules, roots)) { + continue + } + + // https://vite.dev/changes/hotupdate-hook#migration-guide + let invalidatedModules = new Set() + for (let mod of modules) { + this.environment.moduleGraph.invalidateModule( + mod, + invalidatedModules, + timestamp, + true, + ) + } + + if (env === this.environment.name) { + this.environment.hot.send({ type: 'full-reload' }) + } else if (server.hot.send) { + server.hot.send({ type: 'full-reload' }) + } else if (server.ws.send) { + server.ws.send({ type: 'full-reload' }) + } + + return [] + } + } + }, }, { @@ -271,6 +364,10 @@ class Root { private customJsResolver: (id: string, base: string) => Promise, ) {} + get scannedFiles() { + return this.scanner?.files ?? [] + } + // Generate the CSS for the root file. This can return false if the file is // not considered a Tailwind root. When this happened, the root can be GCed. public async generate( @@ -375,6 +472,7 @@ class Root { } if (this.compiler.features & Features.Utilities) { + DEBUG && I.start('Register dependency messages') // Watch individual files found via custom `@source` paths for (let file of this.scanner.files) { addWatchFile(file) @@ -411,6 +509,7 @@ class Root { } } } + DEBUG && I.end('Register dependency messages') } DEBUG && I.start('Build CSS') @@ -450,3 +549,54 @@ class Root { return false } } + +function isScannedFile( + file: string, + modules: vite.EnvironmentModuleNode[], + roots: Map, +) { + let seen = new Set() + let q = [...modules] + let checks = { + file, + get realpath() { + try { + let realpath = realpathSync(file) + Object.defineProperty(checks, 'realpath', { value: realpath }) + return realpath + } catch { + return null + } + }, + } + + while (q.length > 0) { + let module = q.shift()! + if (seen.has(module)) continue + seen.add(module) + + if (module.id) { + let root = roots.get(module.id) + + if (root) { + // If the file is part of the scanned files for this root, then we know + // for sure that it's being watched by any of the Tailwind CSS roots. It + // doesn't matter which root it is since it's only used to know whether + // we should trigger a full reload or not. + if ( + root.scannedFiles.includes(checks.file) || + (checks.realpath && root.scannedFiles.includes(checks.realpath)) + ) { + return true + } + } + } + + // Keep walking up the tree until we find a root. + for (let importer of module.importers) { + q.push(importer) + } + } + + return false +} diff --git a/packages/@tailwindcss-webpack/README.md b/packages/@tailwindcss-webpack/README.md new file mode 100644 index 000000000000..56484ed7f0f6 --- /dev/null +++ b/packages/@tailwindcss-webpack/README.md @@ -0,0 +1,102 @@ +

+ + + + + Tailwind CSS + + +

+ +

+ A utility-first CSS framework for rapidly building custom user interfaces. +

+ +

+ Build Status + Total Downloads + Latest Release + License +

+ +--- + +## Documentation + +For full documentation, visit [tailwindcss.com](https://tailwindcss.com). + +## Community + +For help, discussion about best practices, or feature ideas: + +[Discuss Tailwind CSS on GitHub](https://github.com/tailwindlabs/tailwindcss/discussions) + +## Contributing + +If you're interested in contributing to Tailwind CSS, please read our [contributing docs](https://github.com/tailwindlabs/tailwindcss/blob/main/.github/CONTRIBUTING.md) **before submitting a pull request**. + +--- + +## @tailwindcss/webpack + +A webpack loader for Tailwind CSS v4. + +## Installation + +```sh +npm install @tailwindcss/webpack +``` + +### Usage + +```javascript +// webpack.config.js +const MiniCssExtractPlugin = require('mini-css-extract-plugin') + +module.exports = { + plugins: [new MiniCssExtractPlugin()], + module: { + rules: [ + { + test: /\.css$/i, + use: [MiniCssExtractPlugin.loader, 'css-loader', '@tailwindcss/webpack'], + }, + ], + }, +} +``` + +Then create a CSS file that imports Tailwind: + +```css +/* src/index.css */ +@import 'tailwindcss'; +``` + +### Options + +#### `base` + +The base directory to scan for class candidates. Defaults to the current working directory. + +```javascript +{ + loader: '@tailwindcss/webpack', + options: { + base: process.cwd(), + }, +} +``` + +#### `optimize` + +Whether to optimize and minify the output CSS. Defaults to `true` in production mode. + +```javascript +{ + loader: '@tailwindcss/webpack', + options: { + optimize: true, // or { minify: true } + }, +} +``` diff --git a/packages/@tailwindcss-webpack/package.json b/packages/@tailwindcss-webpack/package.json new file mode 100644 index 000000000000..0fcf0d3f7b0c --- /dev/null +++ b/packages/@tailwindcss-webpack/package.json @@ -0,0 +1,46 @@ +{ + "name": "@tailwindcss/webpack", + "version": "4.2.0", + "description": "A webpack loader for Tailwind CSS v4.", + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/tailwindlabs/tailwindcss.git", + "directory": "packages/@tailwindcss-webpack" + }, + "bugs": "https://github.com/tailwindlabs/tailwindcss/issues", + "homepage": "https://tailwindcss.com", + "scripts": { + "build": "tsup-node", + "dev": "pnpm run build -- --watch" + }, + "files": [ + "dist/" + ], + "publishConfig": { + "provenance": true, + "access": "public" + }, + "exports": { + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/index.mjs", + "require": "./dist/index.js" + } + }, + "main": "./dist/index.js", + "types": "./dist/index.d.ts", + "dependencies": { + "@alloc/quick-lru": "^5.2.0", + "@tailwindcss/node": "workspace:*", + "@tailwindcss/oxide": "workspace:*", + "tailwindcss": "workspace:*" + }, + "devDependencies": { + "@types/node": "catalog:", + "webpack": "catalog:" + }, + "peerDependencies": { + "webpack": "^5" + } +} diff --git a/packages/@tailwindcss-webpack/src/index.cts b/packages/@tailwindcss-webpack/src/index.cts new file mode 100644 index 000000000000..dbdded748a92 --- /dev/null +++ b/packages/@tailwindcss-webpack/src/index.cts @@ -0,0 +1,5 @@ +import tailwindLoader from './index.ts' + +// CommonJS export for webpack loaders - must be the function directly +// @ts-ignore +export = tailwindLoader diff --git a/packages/@tailwindcss-webpack/src/index.ts b/packages/@tailwindcss-webpack/src/index.ts new file mode 100644 index 000000000000..2c78a552b9e7 --- /dev/null +++ b/packages/@tailwindcss-webpack/src/index.ts @@ -0,0 +1,282 @@ +import QuickLRU from '@alloc/quick-lru' +import { + compile, + env, + Features, + Instrumentation, + normalizePath, + optimize, + Polyfills, +} from '@tailwindcss/node' +import { clearRequireCache } from '@tailwindcss/node/require-cache' +import { Scanner } from '@tailwindcss/oxide' +import fs from 'node:fs' +import path from 'node:path' +import type { LoaderContext } from 'webpack' + +const DEBUG = env.DEBUG + +export interface LoaderOptions { + /** + * The base directory to scan for class candidates. + * + * Defaults to the current working directory. + */ + base?: string + + /** + * Optimize and minify the output CSS. + */ + optimize?: boolean | { minify?: boolean } +} + +interface CacheEntry { + mtimes: Map + compiler: null | Awaited> + scanner: null | Scanner + candidates: Set + fullRebuildPaths: string[] +} + +const cache = new QuickLRU({ maxSize: 50 }) + +function getContextFromCache(inputFile: string, opts: LoaderOptions): CacheEntry { + let key = `${inputFile}:${opts.base ?? ''}:${JSON.stringify(opts.optimize)}` + if (cache.has(key)) return cache.get(key)! + let entry: CacheEntry = { + mtimes: new Map(), + compiler: null, + scanner: null, + candidates: new Set(), + fullRebuildPaths: [], + } + cache.set(key, entry) + return entry +} + +export default async function tailwindLoader( + this: LoaderContext, + source: string, +): Promise { + let callback = this.async() + let options = this.getOptions() ?? {} + let inputFile = this.resourcePath + let base = options.base ?? process.cwd() + let shouldOptimize = options.optimize ?? process.env.NODE_ENV === 'production' + let isCSSModuleFile = inputFile.endsWith('.module.css') + + using I = new Instrumentation() + + DEBUG && I.start(`[@tailwindcss/webpack] ${path.relative(base, inputFile)}`) + + // Bail out early if this is guaranteed to be a non-Tailwind CSS file. + { + DEBUG && I.start('Quick bail check') + let canBail = !/@(import|reference|theme|variant|config|plugin|apply|tailwind)\b/.test(source) + if (canBail) { + DEBUG && I.end('Quick bail check') + DEBUG && I.end(`[@tailwindcss/webpack] ${path.relative(base, inputFile)}`) + callback(null, source) + return + } + DEBUG && I.end('Quick bail check') + } + + try { + let context = getContextFromCache(inputFile, options) + let inputBasePath = path.dirname(path.resolve(inputFile)) + + // Whether this is the first build or not + let isInitialBuild = context.compiler === null + + async function createCompiler() { + DEBUG && I.start('Setup compiler') + if (context.fullRebuildPaths.length > 0 && !isInitialBuild) { + clearRequireCache(context.fullRebuildPaths) + } + + context.fullRebuildPaths = [] + + DEBUG && I.start('Create compiler') + let compiler = await compile(source, { + from: inputFile, + base: inputBasePath, + shouldRewriteUrls: true, + onDependency: (depPath) => context.fullRebuildPaths.push(depPath), + // In CSS Module files, we have to disable the `@property` polyfill since these will + // emit global `*` rules which are considered to be non-pure and will cause builds + // to fail. + polyfills: isCSSModuleFile ? Polyfills.All ^ Polyfills.AtProperty : Polyfills.All, + }) + DEBUG && I.end('Create compiler') + + DEBUG && I.end('Setup compiler') + return compiler + } + + // Setup the compiler if it doesn't exist yet + context.compiler ??= await createCompiler() + + // Early exit if no Tailwind features are used + if (context.compiler.features === Features.None) { + DEBUG && I.end(`[@tailwindcss/webpack] ${path.relative(base, inputFile)}`) + callback(null, source) + return + } + + let rebuildStrategy: 'full' | 'incremental' = 'incremental' + + // Track file modification times to CSS files + DEBUG && I.start('Register full rebuild paths') + { + // Report dependencies for config files, plugins, etc. + for (let file of context.fullRebuildPaths) { + this.addDependency(path.resolve(file)) + } + + let files = [...context.fullRebuildPaths, inputFile] + + for (let file of files) { + let changedTime: number | null = null + try { + changedTime = fs.statSync(file)?.mtimeMs ?? null + } catch { + // File might not exist + } + + if (changedTime === null) { + if (file === inputFile) { + rebuildStrategy = 'full' + } + continue + } + + let prevTime = context.mtimes.get(file) + if (prevTime === changedTime) continue + + rebuildStrategy = 'full' + context.mtimes.set(file, changedTime) + } + } + DEBUG && I.end('Register full rebuild paths') + + if (rebuildStrategy === 'full' && !isInitialBuild) { + context.compiler = await createCompiler() + } + + let compiler = context.compiler + + // Check if we need to process this file at all + if ( + !( + compiler.features & + (Features.AtApply | Features.JsPluginCompat | Features.ThemeFunction | Features.Utilities) + ) + ) { + DEBUG && I.end(`[@tailwindcss/webpack] ${path.relative(base, inputFile)}`) + callback(null, source) + return + } + + // Setup or update scanner if needed + if (context.scanner === null || rebuildStrategy === 'full') { + DEBUG && I.start('Setup scanner') + let sources = (() => { + // Disable auto source detection + if (compiler.root === 'none') { + return [] + } + + // No root specified, use the base directory + if (compiler.root === null) { + return [{ base, pattern: '**/*', negated: false }] + } + + // Use the specified root + return [{ ...compiler.root, negated: false }] + })().concat(compiler.sources) + + context.scanner = new Scanner({ sources }) + DEBUG && I.end('Setup scanner') + } + + // Scan for candidates if utilities are used + if (compiler.features & Features.Utilities) { + DEBUG && I.start('Scan for candidates') + for (let candidate of context.scanner.scan()) { + context.candidates.add(candidate) + } + DEBUG && I.end('Scan for candidates') + + DEBUG && I.start('Register dependency messages') + // Add all found files as direct dependencies + let resolvedInputFile = path.resolve(base, inputFile) + for (let file of context.scanner.files) { + let absolutePath = path.resolve(file) + // The CSS file cannot be a dependency of itself + if (absolutePath === resolvedInputFile) { + continue + } + this.addDependency(absolutePath) + } + + // Register context dependencies for glob patterns + for (let glob of context.scanner.globs) { + // Skip negated patterns + if (glob.pattern[0] === '!') continue + + // Avoid adding a dependency on the base directory itself + if (glob.pattern === '*' && base === glob.base) { + continue + } + + this.addContextDependency(path.resolve(glob.base)) + } + + // Validate that source(...) paths are directories + let root = compiler.root + if (root !== 'none' && root !== null) { + let basePath = normalizePath(path.resolve(root.base, root.pattern)) + try { + let stats = fs.statSync(basePath) + if (!stats.isDirectory()) { + throw new Error( + `The path given to \`source(…)\` must be a directory but got \`source(${basePath})\` instead.`, + ) + } + } catch (err) { + if ((err as NodeJS.ErrnoException).code !== 'ENOENT') { + throw err + } + // Directory doesn't exist yet, which is fine + } + } + DEBUG && I.end('Register dependency messages') + } + + DEBUG && I.start('Build utilities') + let css = compiler.build([...context.candidates]) + DEBUG && I.end('Build utilities') + + // Optionally optimize the output + let result = css + if (shouldOptimize) { + DEBUG && I.start('Optimization') + let optimized = optimize(css, { + minify: typeof shouldOptimize === 'object' ? shouldOptimize.minify : true, + }) + result = optimized.code + DEBUG && I.end('Optimization') + } + + DEBUG && I.end(`[@tailwindcss/webpack] ${path.relative(base, inputFile)}`) + callback(null, result) + } catch (error) { + // Clear the cache entry on error to force a full rebuild next time + let key = `${inputFile}:${options.base ?? ''}:${JSON.stringify(options.optimize)}` + cache.delete(key) + + DEBUG && I.end(`[@tailwindcss/webpack] ${path.relative(base, inputFile)}`) + callback(error as Error) + } +} diff --git a/packages/@tailwindcss-webpack/tsconfig.json b/packages/@tailwindcss-webpack/tsconfig.json new file mode 100644 index 000000000000..6ae022f65bf0 --- /dev/null +++ b/packages/@tailwindcss-webpack/tsconfig.json @@ -0,0 +1,3 @@ +{ + "extends": "../tsconfig.base.json", +} diff --git a/packages/@tailwindcss-webpack/tsup.config.ts b/packages/@tailwindcss-webpack/tsup.config.ts new file mode 100644 index 000000000000..998eebe4fe0d --- /dev/null +++ b/packages/@tailwindcss-webpack/tsup.config.ts @@ -0,0 +1,19 @@ +import { defineConfig } from 'tsup' + +export default defineConfig([ + { + format: ['esm'], + clean: true, + minify: true, + cjsInterop: true, + dts: true, + entry: ['src/index.ts'], + }, + { + format: ['cjs'], + minify: true, + cjsInterop: true, + dts: true, + entry: ['src/index.cts'], + }, +]) diff --git a/packages/tailwindcss/README.md b/packages/tailwindcss/README.md index 7d21bd88385a..5f532607d00a 100644 --- a/packages/tailwindcss/README.md +++ b/packages/tailwindcss/README.md @@ -13,10 +13,10 @@

- Build Status + Build Status Total Downloads - Latest Release - License + Latest Release + License

--- @@ -29,8 +29,8 @@ For full documentation, visit [tailwindcss.com](https://tailwindcss.com). For help, discussion about best practices, or feature ideas: -[Discuss Tailwind CSS on GitHub](https://github.com/tailwindcss/tailwindcss/discussions) +[Discuss Tailwind CSS on GitHub](https://github.com/tailwindlabs/tailwindcss/discussions) ## Contributing -If you're interested in contributing to Tailwind CSS, please read our [contributing docs](https://github.com/tailwindcss/tailwindcss/blob/next/.github/CONTRIBUTING.md) **before submitting a pull request**. +If you're interested in contributing to Tailwind CSS, please read our [contributing docs](https://github.com/tailwindlabs/tailwindcss/blob/main/.github/CONTRIBUTING.md) **before submitting a pull request**. diff --git a/packages/tailwindcss/package.json b/packages/tailwindcss/package.json index a453c9a1461f..abe6da365387 100644 --- a/packages/tailwindcss/package.json +++ b/packages/tailwindcss/package.json @@ -1,6 +1,6 @@ { "name": "tailwindcss", - "version": "4.1.18", + "version": "4.2.0", "description": "A utility-first CSS framework for rapidly building custom user interfaces.", "license": "MIT", "repository": { @@ -127,7 +127,7 @@ "utilities.css" ], "devDependencies": { - "@jridgewell/remapping": "^2.3.4", + "@jridgewell/remapping": "^2.3.5", "@tailwindcss/oxide": "workspace:^", "@types/node": "catalog:", "dedent": "1.7.1", diff --git a/packages/tailwindcss/src/__snapshots__/index.test.ts.snap b/packages/tailwindcss/src/__snapshots__/index.test.ts.snap index 70060e1e1797..88365b1ce156 100644 --- a/packages/tailwindcss/src/__snapshots__/index.test.ts.snap +++ b/packages/tailwindcss/src/__snapshots__/index.test.ts.snap @@ -129,8 +129,10 @@ exports[`compiling CSS > \`@tailwind utilities\` is replaced by utilities using exports[`compiling CSS > prefix all CSS variables inside preflight 1`] = ` "@layer theme { :root, :host { - --tw-font-sans: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; - --tw-font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; + --tw-font-sans: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", + "Noto Color Emoji"; + --tw-font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", + monospace; --tw-default-font-family: var(--tw-font-sans); --tw-default-mono-font-family: var(--tw-font-mono); } diff --git a/packages/tailwindcss/src/__snapshots__/intellisense.test.ts.snap b/packages/tailwindcss/src/__snapshots__/intellisense.test.ts.snap index 690b1cb1f0eb..3bf7905409b2 100644 --- a/packages/tailwindcss/src/__snapshots__/intellisense.test.ts.snap +++ b/packages/tailwindcss/src/__snapshots__/intellisense.test.ts.snap @@ -306,66 +306,6 @@ exports[`getClassList 1`] = ` "-col-start-11", "-col-start-12", "-col-start-13", - "-end-0", - "-end-0.5", - "-end-1", - "-end-1.5", - "-end-2", - "-end-2.5", - "-end-3", - "-end-3.5", - "-end-4", - "-end-5", - "-end-6", - "-end-7", - "-end-8", - "-end-9", - "-end-10", - "-end-11", - "-end-12", - "-end-14", - "-end-16", - "-end-20", - "-end-24", - "-end-28", - "-end-32", - "-end-36", - "-end-40", - "-end-44", - "-end-48", - "-end-52", - "-end-56", - "-end-60", - "-end-64", - "-end-72", - "-end-80", - "-end-96", - "-end-1/2", - "-end-1/3", - "-end-1/4", - "-end-1/5", - "-end-1/6", - "-end-1/12", - "-end-2/3", - "-end-2/4", - "-end-2/5", - "-end-2/6", - "-end-2/12", - "-end-3/4", - "-end-3/5", - "-end-3/6", - "-end-3/12", - "-end-4/5", - "-end-4/6", - "-end-4/12", - "-end-5/6", - "-end-5/12", - "-end-6/12", - "-end-7/12", - "-end-8/12", - "-end-9/12", - "-end-10/12", - "-end-11/12", "-end-full", "-end-px", "-indent-0", @@ -463,8 +403,256 @@ exports[`getClassList 1`] = ` "-inset-9/12", "-inset-10/12", "-inset-11/12", + "-inset-be-0", + "-inset-be-0.5", + "-inset-be-1", + "-inset-be-1.5", + "-inset-be-2", + "-inset-be-2.5", + "-inset-be-3", + "-inset-be-3.5", + "-inset-be-4", + "-inset-be-5", + "-inset-be-6", + "-inset-be-7", + "-inset-be-8", + "-inset-be-9", + "-inset-be-10", + "-inset-be-11", + "-inset-be-12", + "-inset-be-14", + "-inset-be-16", + "-inset-be-20", + "-inset-be-24", + "-inset-be-28", + "-inset-be-32", + "-inset-be-36", + "-inset-be-40", + "-inset-be-44", + "-inset-be-48", + "-inset-be-52", + "-inset-be-56", + "-inset-be-60", + "-inset-be-64", + "-inset-be-72", + "-inset-be-80", + "-inset-be-96", + "-inset-be-1/2", + "-inset-be-1/3", + "-inset-be-1/4", + "-inset-be-1/5", + "-inset-be-1/6", + "-inset-be-1/12", + "-inset-be-2/3", + "-inset-be-2/4", + "-inset-be-2/5", + "-inset-be-2/6", + "-inset-be-2/12", + "-inset-be-3/4", + "-inset-be-3/5", + "-inset-be-3/6", + "-inset-be-3/12", + "-inset-be-4/5", + "-inset-be-4/6", + "-inset-be-4/12", + "-inset-be-5/6", + "-inset-be-5/12", + "-inset-be-6/12", + "-inset-be-7/12", + "-inset-be-8/12", + "-inset-be-9/12", + "-inset-be-10/12", + "-inset-be-11/12", + "-inset-be-full", + "-inset-be-px", + "-inset-bs-0", + "-inset-bs-0.5", + "-inset-bs-1", + "-inset-bs-1.5", + "-inset-bs-2", + "-inset-bs-2.5", + "-inset-bs-3", + "-inset-bs-3.5", + "-inset-bs-4", + "-inset-bs-5", + "-inset-bs-6", + "-inset-bs-7", + "-inset-bs-8", + "-inset-bs-9", + "-inset-bs-10", + "-inset-bs-11", + "-inset-bs-12", + "-inset-bs-14", + "-inset-bs-16", + "-inset-bs-20", + "-inset-bs-24", + "-inset-bs-28", + "-inset-bs-32", + "-inset-bs-36", + "-inset-bs-40", + "-inset-bs-44", + "-inset-bs-48", + "-inset-bs-52", + "-inset-bs-56", + "-inset-bs-60", + "-inset-bs-64", + "-inset-bs-72", + "-inset-bs-80", + "-inset-bs-96", + "-inset-bs-1/2", + "-inset-bs-1/3", + "-inset-bs-1/4", + "-inset-bs-1/5", + "-inset-bs-1/6", + "-inset-bs-1/12", + "-inset-bs-2/3", + "-inset-bs-2/4", + "-inset-bs-2/5", + "-inset-bs-2/6", + "-inset-bs-2/12", + "-inset-bs-3/4", + "-inset-bs-3/5", + "-inset-bs-3/6", + "-inset-bs-3/12", + "-inset-bs-4/5", + "-inset-bs-4/6", + "-inset-bs-4/12", + "-inset-bs-5/6", + "-inset-bs-5/12", + "-inset-bs-6/12", + "-inset-bs-7/12", + "-inset-bs-8/12", + "-inset-bs-9/12", + "-inset-bs-10/12", + "-inset-bs-11/12", + "-inset-bs-full", + "-inset-bs-px", + "-inset-e-0", + "-inset-e-0.5", + "-inset-e-1", + "-inset-e-1.5", + "-inset-e-2", + "-inset-e-2.5", + "-inset-e-3", + "-inset-e-3.5", + "-inset-e-4", + "-inset-e-5", + "-inset-e-6", + "-inset-e-7", + "-inset-e-8", + "-inset-e-9", + "-inset-e-10", + "-inset-e-11", + "-inset-e-12", + "-inset-e-14", + "-inset-e-16", + "-inset-e-20", + "-inset-e-24", + "-inset-e-28", + "-inset-e-32", + "-inset-e-36", + "-inset-e-40", + "-inset-e-44", + "-inset-e-48", + "-inset-e-52", + "-inset-e-56", + "-inset-e-60", + "-inset-e-64", + "-inset-e-72", + "-inset-e-80", + "-inset-e-96", + "-inset-e-1/2", + "-inset-e-1/3", + "-inset-e-1/4", + "-inset-e-1/5", + "-inset-e-1/6", + "-inset-e-1/12", + "-inset-e-2/3", + "-inset-e-2/4", + "-inset-e-2/5", + "-inset-e-2/6", + "-inset-e-2/12", + "-inset-e-3/4", + "-inset-e-3/5", + "-inset-e-3/6", + "-inset-e-3/12", + "-inset-e-4/5", + "-inset-e-4/6", + "-inset-e-4/12", + "-inset-e-5/6", + "-inset-e-5/12", + "-inset-e-6/12", + "-inset-e-7/12", + "-inset-e-8/12", + "-inset-e-9/12", + "-inset-e-10/12", + "-inset-e-11/12", + "-inset-e-full", + "-inset-e-px", "-inset-full", "-inset-px", + "-inset-s-0", + "-inset-s-0.5", + "-inset-s-1", + "-inset-s-1.5", + "-inset-s-2", + "-inset-s-2.5", + "-inset-s-3", + "-inset-s-3.5", + "-inset-s-4", + "-inset-s-5", + "-inset-s-6", + "-inset-s-7", + "-inset-s-8", + "-inset-s-9", + "-inset-s-10", + "-inset-s-11", + "-inset-s-12", + "-inset-s-14", + "-inset-s-16", + "-inset-s-20", + "-inset-s-24", + "-inset-s-28", + "-inset-s-32", + "-inset-s-36", + "-inset-s-40", + "-inset-s-44", + "-inset-s-48", + "-inset-s-52", + "-inset-s-56", + "-inset-s-60", + "-inset-s-64", + "-inset-s-72", + "-inset-s-80", + "-inset-s-96", + "-inset-s-1/2", + "-inset-s-1/3", + "-inset-s-1/4", + "-inset-s-1/5", + "-inset-s-1/6", + "-inset-s-1/12", + "-inset-s-2/3", + "-inset-s-2/4", + "-inset-s-2/5", + "-inset-s-2/6", + "-inset-s-2/12", + "-inset-s-3/4", + "-inset-s-3/5", + "-inset-s-3/6", + "-inset-s-3/12", + "-inset-s-4/5", + "-inset-s-4/6", + "-inset-s-4/12", + "-inset-s-5/6", + "-inset-s-5/12", + "-inset-s-6/12", + "-inset-s-7/12", + "-inset-s-8/12", + "-inset-s-9/12", + "-inset-s-10/12", + "-inset-s-11/12", + "-inset-s-full", + "-inset-s-px", "-inset-x-0", "-inset-x-0.5", "-inset-x-1", @@ -739,6 +927,76 @@ exports[`getClassList 1`] = ` "-mb-80", "-mb-96", "-mb-px", + "-mbe-0", + "-mbe-0.5", + "-mbe-1", + "-mbe-1.5", + "-mbe-2", + "-mbe-2.5", + "-mbe-3", + "-mbe-3.5", + "-mbe-4", + "-mbe-5", + "-mbe-6", + "-mbe-7", + "-mbe-8", + "-mbe-9", + "-mbe-10", + "-mbe-11", + "-mbe-12", + "-mbe-14", + "-mbe-16", + "-mbe-20", + "-mbe-24", + "-mbe-28", + "-mbe-32", + "-mbe-36", + "-mbe-40", + "-mbe-44", + "-mbe-48", + "-mbe-52", + "-mbe-56", + "-mbe-60", + "-mbe-64", + "-mbe-72", + "-mbe-80", + "-mbe-96", + "-mbe-px", + "-mbs-0", + "-mbs-0.5", + "-mbs-1", + "-mbs-1.5", + "-mbs-2", + "-mbs-2.5", + "-mbs-3", + "-mbs-3.5", + "-mbs-4", + "-mbs-5", + "-mbs-6", + "-mbs-7", + "-mbs-8", + "-mbs-9", + "-mbs-10", + "-mbs-11", + "-mbs-12", + "-mbs-14", + "-mbs-16", + "-mbs-20", + "-mbs-24", + "-mbs-28", + "-mbs-32", + "-mbs-36", + "-mbs-40", + "-mbs-44", + "-mbs-48", + "-mbs-52", + "-mbs-56", + "-mbs-60", + "-mbs-64", + "-mbs-72", + "-mbs-80", + "-mbs-96", + "-mbs-px", "-me-0", "-me-0.5", "-me-1", @@ -1239,6 +1497,76 @@ exports[`getClassList 1`] = ` "-scroll-mb-80", "-scroll-mb-96", "-scroll-mb-px", + "-scroll-mbe-0", + "-scroll-mbe-0.5", + "-scroll-mbe-1", + "-scroll-mbe-1.5", + "-scroll-mbe-2", + "-scroll-mbe-2.5", + "-scroll-mbe-3", + "-scroll-mbe-3.5", + "-scroll-mbe-4", + "-scroll-mbe-5", + "-scroll-mbe-6", + "-scroll-mbe-7", + "-scroll-mbe-8", + "-scroll-mbe-9", + "-scroll-mbe-10", + "-scroll-mbe-11", + "-scroll-mbe-12", + "-scroll-mbe-14", + "-scroll-mbe-16", + "-scroll-mbe-20", + "-scroll-mbe-24", + "-scroll-mbe-28", + "-scroll-mbe-32", + "-scroll-mbe-36", + "-scroll-mbe-40", + "-scroll-mbe-44", + "-scroll-mbe-48", + "-scroll-mbe-52", + "-scroll-mbe-56", + "-scroll-mbe-60", + "-scroll-mbe-64", + "-scroll-mbe-72", + "-scroll-mbe-80", + "-scroll-mbe-96", + "-scroll-mbe-px", + "-scroll-mbs-0", + "-scroll-mbs-0.5", + "-scroll-mbs-1", + "-scroll-mbs-1.5", + "-scroll-mbs-2", + "-scroll-mbs-2.5", + "-scroll-mbs-3", + "-scroll-mbs-3.5", + "-scroll-mbs-4", + "-scroll-mbs-5", + "-scroll-mbs-6", + "-scroll-mbs-7", + "-scroll-mbs-8", + "-scroll-mbs-9", + "-scroll-mbs-10", + "-scroll-mbs-11", + "-scroll-mbs-12", + "-scroll-mbs-14", + "-scroll-mbs-16", + "-scroll-mbs-20", + "-scroll-mbs-24", + "-scroll-mbs-28", + "-scroll-mbs-32", + "-scroll-mbs-36", + "-scroll-mbs-40", + "-scroll-mbs-44", + "-scroll-mbs-48", + "-scroll-mbs-52", + "-scroll-mbs-56", + "-scroll-mbs-60", + "-scroll-mbs-64", + "-scroll-mbs-72", + "-scroll-mbs-80", + "-scroll-mbs-96", + "-scroll-mbs-px", "-scroll-me-0", "-scroll-me-0.5", "-scroll-me-1", @@ -1572,66 +1900,6 @@ exports[`getClassList 1`] = ` "-space-y-80", "-space-y-96", "-space-y-px", - "-start-0", - "-start-0.5", - "-start-1", - "-start-1.5", - "-start-2", - "-start-2.5", - "-start-3", - "-start-3.5", - "-start-4", - "-start-5", - "-start-6", - "-start-7", - "-start-8", - "-start-9", - "-start-10", - "-start-11", - "-start-12", - "-start-14", - "-start-16", - "-start-20", - "-start-24", - "-start-28", - "-start-32", - "-start-36", - "-start-40", - "-start-44", - "-start-48", - "-start-52", - "-start-56", - "-start-60", - "-start-64", - "-start-72", - "-start-80", - "-start-96", - "-start-1/2", - "-start-1/3", - "-start-1/4", - "-start-1/5", - "-start-1/6", - "-start-1/12", - "-start-2/3", - "-start-2/4", - "-start-2/5", - "-start-2/6", - "-start-2/12", - "-start-3/4", - "-start-3/5", - "-start-3/6", - "-start-3/12", - "-start-4/5", - "-start-4/6", - "-start-4/12", - "-start-5/6", - "-start-5/12", - "-start-6/12", - "-start-7/12", - "-start-8/12", - "-start-9/12", - "-start-10/12", - "-start-11/12", "-start-full", "-start-px", "-top-0", @@ -2574,6 +2842,77 @@ exports[`getClassList 1`] = ` "bg-transparent/95", "bg-transparent/100", "block", + "block-0", + "block-0.5", + "block-1", + "block-1.5", + "block-2", + "block-2.5", + "block-3", + "block-3.5", + "block-4", + "block-5", + "block-6", + "block-7", + "block-8", + "block-9", + "block-10", + "block-11", + "block-12", + "block-14", + "block-16", + "block-20", + "block-24", + "block-28", + "block-32", + "block-36", + "block-40", + "block-44", + "block-48", + "block-52", + "block-56", + "block-60", + "block-64", + "block-72", + "block-80", + "block-96", + "block-1/2", + "block-1/3", + "block-1/4", + "block-1/5", + "block-1/6", + "block-1/12", + "block-2/3", + "block-2/4", + "block-2/5", + "block-2/6", + "block-2/12", + "block-3/4", + "block-3/5", + "block-3/6", + "block-3/12", + "block-4/5", + "block-4/6", + "block-4/12", + "block-5/6", + "block-5/12", + "block-6/12", + "block-7/12", + "block-8/12", + "block-9/12", + "block-10/12", + "block-11/12", + "block-auto", + "block-dvh", + "block-fit", + "block-full", + "block-lh", + "block-lvh", + "block-max", + "block-min", + "block-px", + "block-screen", + "block-svh", "blur-none", "border", "border/0", @@ -2693,6 +3032,190 @@ exports[`getClassList 1`] = ` "border-b-transparent/90", "border-b-transparent/95", "border-b-transparent/100", + "border-be", + "border-be/0", + "border-be/5", + "border-be/10", + "border-be/15", + "border-be/20", + "border-be/25", + "border-be/30", + "border-be/35", + "border-be/40", + "border-be/45", + "border-be/50", + "border-be/55", + "border-be/60", + "border-be/65", + "border-be/70", + "border-be/75", + "border-be/80", + "border-be/85", + "border-be/90", + "border-be/95", + "border-be/100", + "border-be-0", + "border-be-2", + "border-be-4", + "border-be-8", + "border-be-current", + "border-be-current/0", + "border-be-current/5", + "border-be-current/10", + "border-be-current/15", + "border-be-current/20", + "border-be-current/25", + "border-be-current/30", + "border-be-current/35", + "border-be-current/40", + "border-be-current/45", + "border-be-current/50", + "border-be-current/55", + "border-be-current/60", + "border-be-current/65", + "border-be-current/70", + "border-be-current/75", + "border-be-current/80", + "border-be-current/85", + "border-be-current/90", + "border-be-current/95", + "border-be-current/100", + "border-be-inherit", + "border-be-inherit/0", + "border-be-inherit/5", + "border-be-inherit/10", + "border-be-inherit/15", + "border-be-inherit/20", + "border-be-inherit/25", + "border-be-inherit/30", + "border-be-inherit/35", + "border-be-inherit/40", + "border-be-inherit/45", + "border-be-inherit/50", + "border-be-inherit/55", + "border-be-inherit/60", + "border-be-inherit/65", + "border-be-inherit/70", + "border-be-inherit/75", + "border-be-inherit/80", + "border-be-inherit/85", + "border-be-inherit/90", + "border-be-inherit/95", + "border-be-inherit/100", + "border-be-transparent", + "border-be-transparent/0", + "border-be-transparent/5", + "border-be-transparent/10", + "border-be-transparent/15", + "border-be-transparent/20", + "border-be-transparent/25", + "border-be-transparent/30", + "border-be-transparent/35", + "border-be-transparent/40", + "border-be-transparent/45", + "border-be-transparent/50", + "border-be-transparent/55", + "border-be-transparent/60", + "border-be-transparent/65", + "border-be-transparent/70", + "border-be-transparent/75", + "border-be-transparent/80", + "border-be-transparent/85", + "border-be-transparent/90", + "border-be-transparent/95", + "border-be-transparent/100", + "border-bs", + "border-bs/0", + "border-bs/5", + "border-bs/10", + "border-bs/15", + "border-bs/20", + "border-bs/25", + "border-bs/30", + "border-bs/35", + "border-bs/40", + "border-bs/45", + "border-bs/50", + "border-bs/55", + "border-bs/60", + "border-bs/65", + "border-bs/70", + "border-bs/75", + "border-bs/80", + "border-bs/85", + "border-bs/90", + "border-bs/95", + "border-bs/100", + "border-bs-0", + "border-bs-2", + "border-bs-4", + "border-bs-8", + "border-bs-current", + "border-bs-current/0", + "border-bs-current/5", + "border-bs-current/10", + "border-bs-current/15", + "border-bs-current/20", + "border-bs-current/25", + "border-bs-current/30", + "border-bs-current/35", + "border-bs-current/40", + "border-bs-current/45", + "border-bs-current/50", + "border-bs-current/55", + "border-bs-current/60", + "border-bs-current/65", + "border-bs-current/70", + "border-bs-current/75", + "border-bs-current/80", + "border-bs-current/85", + "border-bs-current/90", + "border-bs-current/95", + "border-bs-current/100", + "border-bs-inherit", + "border-bs-inherit/0", + "border-bs-inherit/5", + "border-bs-inherit/10", + "border-bs-inherit/15", + "border-bs-inherit/20", + "border-bs-inherit/25", + "border-bs-inherit/30", + "border-bs-inherit/35", + "border-bs-inherit/40", + "border-bs-inherit/45", + "border-bs-inherit/50", + "border-bs-inherit/55", + "border-bs-inherit/60", + "border-bs-inherit/65", + "border-bs-inherit/70", + "border-bs-inherit/75", + "border-bs-inherit/80", + "border-bs-inherit/85", + "border-bs-inherit/90", + "border-bs-inherit/95", + "border-bs-inherit/100", + "border-bs-transparent", + "border-bs-transparent/0", + "border-bs-transparent/5", + "border-bs-transparent/10", + "border-bs-transparent/15", + "border-bs-transparent/20", + "border-bs-transparent/25", + "border-bs-transparent/30", + "border-bs-transparent/35", + "border-bs-transparent/40", + "border-bs-transparent/45", + "border-bs-transparent/50", + "border-bs-transparent/55", + "border-bs-transparent/60", + "border-bs-transparent/65", + "border-bs-transparent/70", + "border-bs-transparent/75", + "border-bs-transparent/80", + "border-bs-transparent/85", + "border-bs-transparent/90", + "border-bs-transparent/95", + "border-bs-transparent/100", "border-collapse", "border-current", "border-current/0", @@ -4062,66 +4585,6 @@ exports[`getClassList 1`] = ` "duration-initial", "ease-initial", "ease-linear", - "end-0", - "end-0.5", - "end-1", - "end-1.5", - "end-2", - "end-2.5", - "end-3", - "end-3.5", - "end-4", - "end-5", - "end-6", - "end-7", - "end-8", - "end-9", - "end-10", - "end-11", - "end-12", - "end-14", - "end-16", - "end-20", - "end-24", - "end-28", - "end-32", - "end-36", - "end-40", - "end-44", - "end-48", - "end-52", - "end-56", - "end-60", - "end-64", - "end-72", - "end-80", - "end-96", - "end-1/2", - "end-1/3", - "end-1/4", - "end-1/5", - "end-1/6", - "end-1/12", - "end-2/3", - "end-2/4", - "end-2/5", - "end-2/6", - "end-2/12", - "end-3/4", - "end-3/5", - "end-3/6", - "end-3/12", - "end-4/5", - "end-4/6", - "end-4/12", - "end-5/6", - "end-5/12", - "end-6/12", - "end-7/12", - "end-8/12", - "end-9/12", - "end-10/12", - "end-11/12", "end-auto", "end-full", "end-px", @@ -4628,9 +5091,81 @@ exports[`getClassList 1`] = ` "indent-96", "indent-px", "inline", + "inline-0", + "inline-0.5", + "inline-1", + "inline-1.5", + "inline-2", + "inline-2.5", + "inline-3", + "inline-3.5", + "inline-4", + "inline-5", + "inline-6", + "inline-7", + "inline-8", + "inline-9", + "inline-10", + "inline-11", + "inline-12", + "inline-14", + "inline-16", + "inline-20", + "inline-24", + "inline-28", + "inline-32", + "inline-36", + "inline-40", + "inline-44", + "inline-48", + "inline-52", + "inline-56", + "inline-60", + "inline-64", + "inline-72", + "inline-80", + "inline-96", + "inline-auto", "inline-block", + "inline-dvw", + "inline-fit", "inline-flex", + "inline-full", "inline-grid", + "inline-lg", + "inline-lvw", + "inline-max", + "inline-md", + "inline-1/2", + "inline-1/3", + "inline-1/4", + "inline-1/5", + "inline-1/6", + "inline-1/12", + "inline-2/3", + "inline-2/4", + "inline-2/5", + "inline-2/6", + "inline-2/12", + "inline-3/4", + "inline-3/5", + "inline-3/6", + "inline-3/12", + "inline-4/5", + "inline-4/6", + "inline-4/12", + "inline-5/6", + "inline-5/12", + "inline-6/12", + "inline-7/12", + "inline-8/12", + "inline-9/12", + "inline-10/12", + "inline-11/12", + "inline-min", + "inline-px", + "inline-screen", + "inline-svw", "inline-table", "inset-0", "inset-0.5", @@ -4693,6 +5228,195 @@ exports[`getClassList 1`] = ` "inset-10/12", "inset-11/12", "inset-auto", + "inset-be-0", + "inset-be-0.5", + "inset-be-1", + "inset-be-1.5", + "inset-be-2", + "inset-be-2.5", + "inset-be-3", + "inset-be-3.5", + "inset-be-4", + "inset-be-5", + "inset-be-6", + "inset-be-7", + "inset-be-8", + "inset-be-9", + "inset-be-10", + "inset-be-11", + "inset-be-12", + "inset-be-14", + "inset-be-16", + "inset-be-20", + "inset-be-24", + "inset-be-28", + "inset-be-32", + "inset-be-36", + "inset-be-40", + "inset-be-44", + "inset-be-48", + "inset-be-52", + "inset-be-56", + "inset-be-60", + "inset-be-64", + "inset-be-72", + "inset-be-80", + "inset-be-96", + "inset-be-1/2", + "inset-be-1/3", + "inset-be-1/4", + "inset-be-1/5", + "inset-be-1/6", + "inset-be-1/12", + "inset-be-2/3", + "inset-be-2/4", + "inset-be-2/5", + "inset-be-2/6", + "inset-be-2/12", + "inset-be-3/4", + "inset-be-3/5", + "inset-be-3/6", + "inset-be-3/12", + "inset-be-4/5", + "inset-be-4/6", + "inset-be-4/12", + "inset-be-5/6", + "inset-be-5/12", + "inset-be-6/12", + "inset-be-7/12", + "inset-be-8/12", + "inset-be-9/12", + "inset-be-10/12", + "inset-be-11/12", + "inset-be-auto", + "inset-be-full", + "inset-be-px", + "inset-bs-0", + "inset-bs-0.5", + "inset-bs-1", + "inset-bs-1.5", + "inset-bs-2", + "inset-bs-2.5", + "inset-bs-3", + "inset-bs-3.5", + "inset-bs-4", + "inset-bs-5", + "inset-bs-6", + "inset-bs-7", + "inset-bs-8", + "inset-bs-9", + "inset-bs-10", + "inset-bs-11", + "inset-bs-12", + "inset-bs-14", + "inset-bs-16", + "inset-bs-20", + "inset-bs-24", + "inset-bs-28", + "inset-bs-32", + "inset-bs-36", + "inset-bs-40", + "inset-bs-44", + "inset-bs-48", + "inset-bs-52", + "inset-bs-56", + "inset-bs-60", + "inset-bs-64", + "inset-bs-72", + "inset-bs-80", + "inset-bs-96", + "inset-bs-1/2", + "inset-bs-1/3", + "inset-bs-1/4", + "inset-bs-1/5", + "inset-bs-1/6", + "inset-bs-1/12", + "inset-bs-2/3", + "inset-bs-2/4", + "inset-bs-2/5", + "inset-bs-2/6", + "inset-bs-2/12", + "inset-bs-3/4", + "inset-bs-3/5", + "inset-bs-3/6", + "inset-bs-3/12", + "inset-bs-4/5", + "inset-bs-4/6", + "inset-bs-4/12", + "inset-bs-5/6", + "inset-bs-5/12", + "inset-bs-6/12", + "inset-bs-7/12", + "inset-bs-8/12", + "inset-bs-9/12", + "inset-bs-10/12", + "inset-bs-11/12", + "inset-bs-auto", + "inset-bs-full", + "inset-bs-px", + "inset-e-0", + "inset-e-0.5", + "inset-e-1", + "inset-e-1.5", + "inset-e-2", + "inset-e-2.5", + "inset-e-3", + "inset-e-3.5", + "inset-e-4", + "inset-e-5", + "inset-e-6", + "inset-e-7", + "inset-e-8", + "inset-e-9", + "inset-e-10", + "inset-e-11", + "inset-e-12", + "inset-e-14", + "inset-e-16", + "inset-e-20", + "inset-e-24", + "inset-e-28", + "inset-e-32", + "inset-e-36", + "inset-e-40", + "inset-e-44", + "inset-e-48", + "inset-e-52", + "inset-e-56", + "inset-e-60", + "inset-e-64", + "inset-e-72", + "inset-e-80", + "inset-e-96", + "inset-e-1/2", + "inset-e-1/3", + "inset-e-1/4", + "inset-e-1/5", + "inset-e-1/6", + "inset-e-1/12", + "inset-e-2/3", + "inset-e-2/4", + "inset-e-2/5", + "inset-e-2/6", + "inset-e-2/12", + "inset-e-3/4", + "inset-e-3/5", + "inset-e-3/6", + "inset-e-3/12", + "inset-e-4/5", + "inset-e-4/6", + "inset-e-4/12", + "inset-e-5/6", + "inset-e-5/12", + "inset-e-6/12", + "inset-e-7/12", + "inset-e-8/12", + "inset-e-9/12", + "inset-e-10/12", + "inset-e-11/12", + "inset-e-auto", + "inset-e-full", + "inset-e-px", "inset-full", "inset-px", "inset-ring", @@ -4767,6 +5491,69 @@ exports[`getClassList 1`] = ` "inset-ring-transparent/90", "inset-ring-transparent/95", "inset-ring-transparent/100", + "inset-s-0", + "inset-s-0.5", + "inset-s-1", + "inset-s-1.5", + "inset-s-2", + "inset-s-2.5", + "inset-s-3", + "inset-s-3.5", + "inset-s-4", + "inset-s-5", + "inset-s-6", + "inset-s-7", + "inset-s-8", + "inset-s-9", + "inset-s-10", + "inset-s-11", + "inset-s-12", + "inset-s-14", + "inset-s-16", + "inset-s-20", + "inset-s-24", + "inset-s-28", + "inset-s-32", + "inset-s-36", + "inset-s-40", + "inset-s-44", + "inset-s-48", + "inset-s-52", + "inset-s-56", + "inset-s-60", + "inset-s-64", + "inset-s-72", + "inset-s-80", + "inset-s-96", + "inset-s-1/2", + "inset-s-1/3", + "inset-s-1/4", + "inset-s-1/5", + "inset-s-1/6", + "inset-s-1/12", + "inset-s-2/3", + "inset-s-2/4", + "inset-s-2/5", + "inset-s-2/6", + "inset-s-2/12", + "inset-s-3/4", + "inset-s-3/5", + "inset-s-3/6", + "inset-s-3/12", + "inset-s-4/5", + "inset-s-4/6", + "inset-s-4/12", + "inset-s-5/6", + "inset-s-5/12", + "inset-s-6/12", + "inset-s-7/12", + "inset-s-8/12", + "inset-s-9/12", + "inset-s-10/12", + "inset-s-11/12", + "inset-s-auto", + "inset-s-full", + "inset-s-px", "inset-shadow-current", "inset-shadow-current/0", "inset-shadow-current/5", @@ -7430,6 +8217,77 @@ exports[`getClassList 1`] = ` "mask-y-to-transparent/90", "mask-y-to-transparent/95", "mask-y-to-transparent/100", + "max-block-0", + "max-block-0.5", + "max-block-1", + "max-block-1.5", + "max-block-2", + "max-block-2.5", + "max-block-3", + "max-block-3.5", + "max-block-4", + "max-block-5", + "max-block-6", + "max-block-7", + "max-block-8", + "max-block-9", + "max-block-10", + "max-block-11", + "max-block-12", + "max-block-14", + "max-block-16", + "max-block-20", + "max-block-24", + "max-block-28", + "max-block-32", + "max-block-36", + "max-block-40", + "max-block-44", + "max-block-48", + "max-block-52", + "max-block-56", + "max-block-60", + "max-block-64", + "max-block-72", + "max-block-80", + "max-block-96", + "max-block-1/2", + "max-block-1/3", + "max-block-1/4", + "max-block-1/5", + "max-block-1/6", + "max-block-1/12", + "max-block-2/3", + "max-block-2/4", + "max-block-2/5", + "max-block-2/6", + "max-block-2/12", + "max-block-3/4", + "max-block-3/5", + "max-block-3/6", + "max-block-3/12", + "max-block-4/5", + "max-block-4/6", + "max-block-4/12", + "max-block-5/6", + "max-block-5/12", + "max-block-6/12", + "max-block-7/12", + "max-block-8/12", + "max-block-9/12", + "max-block-10/12", + "max-block-11/12", + "max-block-dvh", + "max-block-fit", + "max-block-full", + "max-block-lh", + "max-block-lvh", + "max-block-max", + "max-block-min", + "max-block-none", + "max-block-px", + "max-block-screen", + "max-block-svh", "max-h-0", "max-h-0.5", "max-h-1", @@ -7504,6 +8362,78 @@ exports[`getClassList 1`] = ` "max-h-screen", "max-h-svh", "max-h-svw", + "max-inline-0", + "max-inline-0.5", + "max-inline-1", + "max-inline-1.5", + "max-inline-2", + "max-inline-2.5", + "max-inline-3", + "max-inline-3.5", + "max-inline-4", + "max-inline-5", + "max-inline-6", + "max-inline-7", + "max-inline-8", + "max-inline-9", + "max-inline-10", + "max-inline-11", + "max-inline-12", + "max-inline-14", + "max-inline-16", + "max-inline-20", + "max-inline-24", + "max-inline-28", + "max-inline-32", + "max-inline-36", + "max-inline-40", + "max-inline-44", + "max-inline-48", + "max-inline-52", + "max-inline-56", + "max-inline-60", + "max-inline-64", + "max-inline-72", + "max-inline-80", + "max-inline-96", + "max-inline-dvw", + "max-inline-fit", + "max-inline-full", + "max-inline-lg", + "max-inline-lvw", + "max-inline-max", + "max-inline-md", + "max-inline-1/2", + "max-inline-1/3", + "max-inline-1/4", + "max-inline-1/5", + "max-inline-1/6", + "max-inline-1/12", + "max-inline-2/3", + "max-inline-2/4", + "max-inline-2/5", + "max-inline-2/6", + "max-inline-2/12", + "max-inline-3/4", + "max-inline-3/5", + "max-inline-3/6", + "max-inline-3/12", + "max-inline-4/5", + "max-inline-4/6", + "max-inline-4/12", + "max-inline-5/6", + "max-inline-5/12", + "max-inline-6/12", + "max-inline-7/12", + "max-inline-8/12", + "max-inline-9/12", + "max-inline-10/12", + "max-inline-11/12", + "max-inline-min", + "max-inline-none", + "max-inline-px", + "max-inline-screen", + "max-inline-svw", "max-w-0", "max-w-0.5", "max-w-1", @@ -7614,6 +8544,78 @@ exports[`getClassList 1`] = ` "mb-96", "mb-auto", "mb-px", + "mbe-0", + "mbe-0.5", + "mbe-1", + "mbe-1.5", + "mbe-2", + "mbe-2.5", + "mbe-3", + "mbe-3.5", + "mbe-4", + "mbe-5", + "mbe-6", + "mbe-7", + "mbe-8", + "mbe-9", + "mbe-10", + "mbe-11", + "mbe-12", + "mbe-14", + "mbe-16", + "mbe-20", + "mbe-24", + "mbe-28", + "mbe-32", + "mbe-36", + "mbe-40", + "mbe-44", + "mbe-48", + "mbe-52", + "mbe-56", + "mbe-60", + "mbe-64", + "mbe-72", + "mbe-80", + "mbe-96", + "mbe-auto", + "mbe-px", + "mbs-0", + "mbs-0.5", + "mbs-1", + "mbs-1.5", + "mbs-2", + "mbs-2.5", + "mbs-3", + "mbs-3.5", + "mbs-4", + "mbs-5", + "mbs-6", + "mbs-7", + "mbs-8", + "mbs-9", + "mbs-10", + "mbs-11", + "mbs-12", + "mbs-14", + "mbs-16", + "mbs-20", + "mbs-24", + "mbs-28", + "mbs-32", + "mbs-36", + "mbs-40", + "mbs-44", + "mbs-48", + "mbs-52", + "mbs-56", + "mbs-60", + "mbs-64", + "mbs-72", + "mbs-80", + "mbs-96", + "mbs-auto", + "mbs-px", "me-0", "me-0.5", "me-1", @@ -7650,6 +8652,77 @@ exports[`getClassList 1`] = ` "me-96", "me-auto", "me-px", + "min-block-0", + "min-block-0.5", + "min-block-1", + "min-block-1.5", + "min-block-2", + "min-block-2.5", + "min-block-3", + "min-block-3.5", + "min-block-4", + "min-block-5", + "min-block-6", + "min-block-7", + "min-block-8", + "min-block-9", + "min-block-10", + "min-block-11", + "min-block-12", + "min-block-14", + "min-block-16", + "min-block-20", + "min-block-24", + "min-block-28", + "min-block-32", + "min-block-36", + "min-block-40", + "min-block-44", + "min-block-48", + "min-block-52", + "min-block-56", + "min-block-60", + "min-block-64", + "min-block-72", + "min-block-80", + "min-block-96", + "min-block-1/2", + "min-block-1/3", + "min-block-1/4", + "min-block-1/5", + "min-block-1/6", + "min-block-1/12", + "min-block-2/3", + "min-block-2/4", + "min-block-2/5", + "min-block-2/6", + "min-block-2/12", + "min-block-3/4", + "min-block-3/5", + "min-block-3/6", + "min-block-3/12", + "min-block-4/5", + "min-block-4/6", + "min-block-4/12", + "min-block-5/6", + "min-block-5/12", + "min-block-6/12", + "min-block-7/12", + "min-block-8/12", + "min-block-9/12", + "min-block-10/12", + "min-block-11/12", + "min-block-auto", + "min-block-dvh", + "min-block-fit", + "min-block-full", + "min-block-lh", + "min-block-lvh", + "min-block-max", + "min-block-min", + "min-block-px", + "min-block-screen", + "min-block-svh", "min-h-0", "min-h-0.5", "min-h-1", @@ -7724,6 +8797,78 @@ exports[`getClassList 1`] = ` "min-h-screen", "min-h-svh", "min-h-svw", + "min-inline-0", + "min-inline-0.5", + "min-inline-1", + "min-inline-1.5", + "min-inline-2", + "min-inline-2.5", + "min-inline-3", + "min-inline-3.5", + "min-inline-4", + "min-inline-5", + "min-inline-6", + "min-inline-7", + "min-inline-8", + "min-inline-9", + "min-inline-10", + "min-inline-11", + "min-inline-12", + "min-inline-14", + "min-inline-16", + "min-inline-20", + "min-inline-24", + "min-inline-28", + "min-inline-32", + "min-inline-36", + "min-inline-40", + "min-inline-44", + "min-inline-48", + "min-inline-52", + "min-inline-56", + "min-inline-60", + "min-inline-64", + "min-inline-72", + "min-inline-80", + "min-inline-96", + "min-inline-auto", + "min-inline-dvw", + "min-inline-fit", + "min-inline-full", + "min-inline-lg", + "min-inline-lvw", + "min-inline-max", + "min-inline-md", + "min-inline-1/2", + "min-inline-1/3", + "min-inline-1/4", + "min-inline-1/5", + "min-inline-1/6", + "min-inline-1/12", + "min-inline-2/3", + "min-inline-2/4", + "min-inline-2/5", + "min-inline-2/6", + "min-inline-2/12", + "min-inline-3/4", + "min-inline-3/5", + "min-inline-3/6", + "min-inline-3/12", + "min-inline-4/5", + "min-inline-4/6", + "min-inline-4/12", + "min-inline-5/6", + "min-inline-5/12", + "min-inline-6/12", + "min-inline-7/12", + "min-inline-8/12", + "min-inline-9/12", + "min-inline-10/12", + "min-inline-11/12", + "min-inline-min", + "min-inline-px", + "min-inline-screen", + "min-inline-svw", "min-w-0", "min-w-0.5", "min-w-1", @@ -8298,6 +9443,76 @@ exports[`getClassList 1`] = ` "pb-80", "pb-96", "pb-px", + "pbe-0", + "pbe-0.5", + "pbe-1", + "pbe-1.5", + "pbe-2", + "pbe-2.5", + "pbe-3", + "pbe-3.5", + "pbe-4", + "pbe-5", + "pbe-6", + "pbe-7", + "pbe-8", + "pbe-9", + "pbe-10", + "pbe-11", + "pbe-12", + "pbe-14", + "pbe-16", + "pbe-20", + "pbe-24", + "pbe-28", + "pbe-32", + "pbe-36", + "pbe-40", + "pbe-44", + "pbe-48", + "pbe-52", + "pbe-56", + "pbe-60", + "pbe-64", + "pbe-72", + "pbe-80", + "pbe-96", + "pbe-px", + "pbs-0", + "pbs-0.5", + "pbs-1", + "pbs-1.5", + "pbs-2", + "pbs-2.5", + "pbs-3", + "pbs-3.5", + "pbs-4", + "pbs-5", + "pbs-6", + "pbs-7", + "pbs-8", + "pbs-9", + "pbs-10", + "pbs-11", + "pbs-12", + "pbs-14", + "pbs-16", + "pbs-20", + "pbs-24", + "pbs-28", + "pbs-32", + "pbs-36", + "pbs-40", + "pbs-44", + "pbs-48", + "pbs-52", + "pbs-56", + "pbs-60", + "pbs-64", + "pbs-72", + "pbs-80", + "pbs-96", + "pbs-px", "pe-0", "pe-0.5", "pe-1", @@ -9097,6 +10312,76 @@ exports[`getClassList 1`] = ` "scroll-mb-80", "scroll-mb-96", "scroll-mb-px", + "scroll-mbe-0", + "scroll-mbe-0.5", + "scroll-mbe-1", + "scroll-mbe-1.5", + "scroll-mbe-2", + "scroll-mbe-2.5", + "scroll-mbe-3", + "scroll-mbe-3.5", + "scroll-mbe-4", + "scroll-mbe-5", + "scroll-mbe-6", + "scroll-mbe-7", + "scroll-mbe-8", + "scroll-mbe-9", + "scroll-mbe-10", + "scroll-mbe-11", + "scroll-mbe-12", + "scroll-mbe-14", + "scroll-mbe-16", + "scroll-mbe-20", + "scroll-mbe-24", + "scroll-mbe-28", + "scroll-mbe-32", + "scroll-mbe-36", + "scroll-mbe-40", + "scroll-mbe-44", + "scroll-mbe-48", + "scroll-mbe-52", + "scroll-mbe-56", + "scroll-mbe-60", + "scroll-mbe-64", + "scroll-mbe-72", + "scroll-mbe-80", + "scroll-mbe-96", + "scroll-mbe-px", + "scroll-mbs-0", + "scroll-mbs-0.5", + "scroll-mbs-1", + "scroll-mbs-1.5", + "scroll-mbs-2", + "scroll-mbs-2.5", + "scroll-mbs-3", + "scroll-mbs-3.5", + "scroll-mbs-4", + "scroll-mbs-5", + "scroll-mbs-6", + "scroll-mbs-7", + "scroll-mbs-8", + "scroll-mbs-9", + "scroll-mbs-10", + "scroll-mbs-11", + "scroll-mbs-12", + "scroll-mbs-14", + "scroll-mbs-16", + "scroll-mbs-20", + "scroll-mbs-24", + "scroll-mbs-28", + "scroll-mbs-32", + "scroll-mbs-36", + "scroll-mbs-40", + "scroll-mbs-44", + "scroll-mbs-48", + "scroll-mbs-52", + "scroll-mbs-56", + "scroll-mbs-60", + "scroll-mbs-64", + "scroll-mbs-72", + "scroll-mbs-80", + "scroll-mbs-96", + "scroll-mbs-px", "scroll-me-0", "scroll-me-0.5", "scroll-me-1", @@ -9412,6 +10697,76 @@ exports[`getClassList 1`] = ` "scroll-pb-80", "scroll-pb-96", "scroll-pb-px", + "scroll-pbe-0", + "scroll-pbe-0.5", + "scroll-pbe-1", + "scroll-pbe-1.5", + "scroll-pbe-2", + "scroll-pbe-2.5", + "scroll-pbe-3", + "scroll-pbe-3.5", + "scroll-pbe-4", + "scroll-pbe-5", + "scroll-pbe-6", + "scroll-pbe-7", + "scroll-pbe-8", + "scroll-pbe-9", + "scroll-pbe-10", + "scroll-pbe-11", + "scroll-pbe-12", + "scroll-pbe-14", + "scroll-pbe-16", + "scroll-pbe-20", + "scroll-pbe-24", + "scroll-pbe-28", + "scroll-pbe-32", + "scroll-pbe-36", + "scroll-pbe-40", + "scroll-pbe-44", + "scroll-pbe-48", + "scroll-pbe-52", + "scroll-pbe-56", + "scroll-pbe-60", + "scroll-pbe-64", + "scroll-pbe-72", + "scroll-pbe-80", + "scroll-pbe-96", + "scroll-pbe-px", + "scroll-pbs-0", + "scroll-pbs-0.5", + "scroll-pbs-1", + "scroll-pbs-1.5", + "scroll-pbs-2", + "scroll-pbs-2.5", + "scroll-pbs-3", + "scroll-pbs-3.5", + "scroll-pbs-4", + "scroll-pbs-5", + "scroll-pbs-6", + "scroll-pbs-7", + "scroll-pbs-8", + "scroll-pbs-9", + "scroll-pbs-10", + "scroll-pbs-11", + "scroll-pbs-12", + "scroll-pbs-14", + "scroll-pbs-16", + "scroll-pbs-20", + "scroll-pbs-24", + "scroll-pbs-28", + "scroll-pbs-32", + "scroll-pbs-36", + "scroll-pbs-40", + "scroll-pbs-44", + "scroll-pbs-48", + "scroll-pbs-52", + "scroll-pbs-56", + "scroll-pbs-60", + "scroll-pbs-64", + "scroll-pbs-72", + "scroll-pbs-80", + "scroll-pbs-96", + "scroll-pbs-px", "scroll-pe-0", "scroll-pe-0.5", "scroll-pe-1", @@ -9922,66 +11277,6 @@ exports[`getClassList 1`] = ` "space-y-reverse", "sr-only", "stacked-fractions", - "start-0", - "start-0.5", - "start-1", - "start-1.5", - "start-2", - "start-2.5", - "start-3", - "start-3.5", - "start-4", - "start-5", - "start-6", - "start-7", - "start-8", - "start-9", - "start-10", - "start-11", - "start-12", - "start-14", - "start-16", - "start-20", - "start-24", - "start-28", - "start-32", - "start-36", - "start-40", - "start-44", - "start-48", - "start-52", - "start-56", - "start-60", - "start-64", - "start-72", - "start-80", - "start-96", - "start-1/2", - "start-1/3", - "start-1/4", - "start-1/5", - "start-1/6", - "start-1/12", - "start-2/3", - "start-2/4", - "start-2/5", - "start-2/6", - "start-2/12", - "start-3/4", - "start-3/5", - "start-3/6", - "start-3/12", - "start-4/5", - "start-4/6", - "start-4/12", - "start-5/6", - "start-5/12", - "start-6/12", - "start-7/12", - "start-8/12", - "start-9/12", - "start-10/12", - "start-11/12", "start-auto", "start-full", "start-px", diff --git a/packages/tailwindcss/src/__snapshots__/utilities.test.ts.snap b/packages/tailwindcss/src/__snapshots__/utilities.test.ts.snap index 6adc96113d46..12bf1312a0cd 100644 --- a/packages/tailwindcss/src/__snapshots__/utilities.test.ts.snap +++ b/packages/tailwindcss/src/__snapshots__/utilities.test.ts.snap @@ -370,6 +370,376 @@ exports[`border-b-* 1`] = ` }" `; +exports[`border-be-* 1`] = ` +"@layer properties { + @supports (((-webkit-hyphens: none)) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color: rgb(from red r g b)))) { + *, :before, :after, ::backdrop { + --tw-border-style: solid; + } + } +} + +:root, :host { + --color-red-500: #ef4444; + --border-color-blue-500: #3b82f6; +} + +.border-be { + border-block-end-style: var(--tw-border-style); + border-block-end-width: 1px; +} + +.border-be-0 { + border-block-end-style: var(--tw-border-style); + border-block-end-width: 0; +} + +.border-be-2 { + border-block-end-style: var(--tw-border-style); + border-block-end-width: 2px; +} + +.border-be-4 { + border-block-end-style: var(--tw-border-style); + border-block-end-width: 4px; +} + +.border-be-123 { + border-block-end-style: var(--tw-border-style); + border-block-end-width: 123px; +} + +.border-be-\\[0_1\\] { + border-block-end-style: var(--tw-border-style); + border-block-end-width: 0 1; +} + +.border-be-\\[0_2px_0_2px\\] { + border-block-end-style: var(--tw-border-style); + border-block-end-width: 0 2px 0 2px; +} + +.border-be-\\[12px\\] { + border-block-end-style: var(--tw-border-style); + border-block-end-width: 12px; +} + +.border-be-\\[12px_8px\\] { + border-block-end-style: var(--tw-border-style); + border-block-end-width: 12px 8px; +} + +.border-be-\\[length\\:var\\(--my-width\\)\\], .border-be-\\[line-width\\:var\\(--my-width\\)\\] { + border-block-end-style: var(--tw-border-style); + border-block-end-width: var(--my-width); +} + +.border-be-\\[medium\\] { + border-block-end-style: var(--tw-border-style); + border-block-end-width: medium; +} + +.border-be-\\[thick\\] { + border-block-end-style: var(--tw-border-style); + border-block-end-width: thick; +} + +.border-be-\\[thin\\] { + border-block-end-style: var(--tw-border-style); + border-block-end-width: thin; +} + +.border-be-\\[thin_2px\\] { + border-block-end-style: var(--tw-border-style); + border-block-end-width: thin 2px; +} + +.border-be-\\[\\#0088cc\\] { + border-block-end-color: #08c; +} + +.border-be-\\[\\#0088cc\\]\\/50 { + border-block-end-color: oklab(59.9824% -.067 -.124 / .5); +} + +.border-be-\\[color\\:var\\(--my-color\\)\\], .border-be-\\[color\\:var\\(--my-color\\)\\]\\/50 { + border-block-end-color: var(--my-color); +} + +@supports (color: color-mix(in lab, red, red)) { + .border-be-\\[color\\:var\\(--my-color\\)\\]\\/50 { + border-block-end-color: color-mix(in oklab, var(--my-color) 50%, transparent); + } +} + +.border-be-\\[var\\(--my-color\\)\\], .border-be-\\[var\\(--my-color\\)\\]\\/50 { + border-block-end-color: var(--my-color); +} + +@supports (color: color-mix(in lab, red, red)) { + .border-be-\\[var\\(--my-color\\)\\]\\/50 { + border-block-end-color: color-mix(in oklab, var(--my-color) 50%, transparent); + } +} + +.border-be-blue-500 { + border-block-end-color: var(--border-color-blue-500); +} + +.border-be-current, .border-be-current\\/50 { + border-block-end-color: currentColor; +} + +@supports (color: color-mix(in lab, red, red)) { + .border-be-current\\/50 { + border-block-end-color: color-mix(in oklab, currentcolor 50%, transparent); + } +} + +.border-be-inherit { + border-block-end-color: inherit; +} + +.border-be-red-500 { + border-block-end-color: var(--color-red-500); +} + +.border-be-red-500\\/2\\.5 { + border-block-end-color: #ef444406; +} + +@supports (color: color-mix(in lab, red, red)) { + .border-be-red-500\\/2\\.5 { + border-block-end-color: color-mix(in oklab, var(--color-red-500) 2.5%, transparent); + } +} + +.border-be-red-500\\/2\\.25 { + border-block-end-color: #ef444406; +} + +@supports (color: color-mix(in lab, red, red)) { + .border-be-red-500\\/2\\.25 { + border-block-end-color: color-mix(in oklab, var(--color-red-500) 2.25%, transparent); + } +} + +.border-be-red-500\\/2\\.75 { + border-block-end-color: #ef444407; +} + +@supports (color: color-mix(in lab, red, red)) { + .border-be-red-500\\/2\\.75 { + border-block-end-color: color-mix(in oklab, var(--color-red-500) 2.75%, transparent); + } +} + +.border-be-red-500\\/50 { + border-block-end-color: #ef444480; +} + +@supports (color: color-mix(in lab, red, red)) { + .border-be-red-500\\/50 { + border-block-end-color: color-mix(in oklab, var(--color-red-500) 50%, transparent); + } +} + +.border-be-transparent { + border-block-end-color: #0000; +} + +@property --tw-border-style { + syntax: "*"; + inherits: false; + initial-value: solid; +}" +`; + +exports[`border-bs-* 1`] = ` +"@layer properties { + @supports (((-webkit-hyphens: none)) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color: rgb(from red r g b)))) { + *, :before, :after, ::backdrop { + --tw-border-style: solid; + } + } +} + +:root, :host { + --color-red-500: #ef4444; + --border-color-blue-500: #3b82f6; +} + +.border-bs { + border-block-start-style: var(--tw-border-style); + border-block-start-width: 1px; +} + +.border-bs-0 { + border-block-start-style: var(--tw-border-style); + border-block-start-width: 0; +} + +.border-bs-2 { + border-block-start-style: var(--tw-border-style); + border-block-start-width: 2px; +} + +.border-bs-4 { + border-block-start-style: var(--tw-border-style); + border-block-start-width: 4px; +} + +.border-bs-123 { + border-block-start-style: var(--tw-border-style); + border-block-start-width: 123px; +} + +.border-bs-\\[0_1\\] { + border-block-start-style: var(--tw-border-style); + border-block-start-width: 0 1; +} + +.border-bs-\\[0_2px_0_2px\\] { + border-block-start-style: var(--tw-border-style); + border-block-start-width: 0 2px 0 2px; +} + +.border-bs-\\[12px\\] { + border-block-start-style: var(--tw-border-style); + border-block-start-width: 12px; +} + +.border-bs-\\[12px_8px\\] { + border-block-start-style: var(--tw-border-style); + border-block-start-width: 12px 8px; +} + +.border-bs-\\[length\\:var\\(--my-width\\)\\], .border-bs-\\[line-width\\:var\\(--my-width\\)\\] { + border-block-start-style: var(--tw-border-style); + border-block-start-width: var(--my-width); +} + +.border-bs-\\[medium\\] { + border-block-start-style: var(--tw-border-style); + border-block-start-width: medium; +} + +.border-bs-\\[thick\\] { + border-block-start-style: var(--tw-border-style); + border-block-start-width: thick; +} + +.border-bs-\\[thin\\] { + border-block-start-style: var(--tw-border-style); + border-block-start-width: thin; +} + +.border-bs-\\[thin_2px\\] { + border-block-start-style: var(--tw-border-style); + border-block-start-width: thin 2px; +} + +.border-bs-\\[\\#0088cc\\] { + border-block-start-color: #08c; +} + +.border-bs-\\[\\#0088cc\\]\\/50 { + border-block-start-color: oklab(59.9824% -.067 -.124 / .5); +} + +.border-bs-\\[color\\:var\\(--my-color\\)\\], .border-bs-\\[color\\:var\\(--my-color\\)\\]\\/50 { + border-block-start-color: var(--my-color); +} + +@supports (color: color-mix(in lab, red, red)) { + .border-bs-\\[color\\:var\\(--my-color\\)\\]\\/50 { + border-block-start-color: color-mix(in oklab, var(--my-color) 50%, transparent); + } +} + +.border-bs-\\[var\\(--my-color\\)\\], .border-bs-\\[var\\(--my-color\\)\\]\\/50 { + border-block-start-color: var(--my-color); +} + +@supports (color: color-mix(in lab, red, red)) { + .border-bs-\\[var\\(--my-color\\)\\]\\/50 { + border-block-start-color: color-mix(in oklab, var(--my-color) 50%, transparent); + } +} + +.border-bs-blue-500 { + border-block-start-color: var(--border-color-blue-500); +} + +.border-bs-current, .border-bs-current\\/50 { + border-block-start-color: currentColor; +} + +@supports (color: color-mix(in lab, red, red)) { + .border-bs-current\\/50 { + border-block-start-color: color-mix(in oklab, currentcolor 50%, transparent); + } +} + +.border-bs-inherit { + border-block-start-color: inherit; +} + +.border-bs-red-500 { + border-block-start-color: var(--color-red-500); +} + +.border-bs-red-500\\/2\\.5 { + border-block-start-color: #ef444406; +} + +@supports (color: color-mix(in lab, red, red)) { + .border-bs-red-500\\/2\\.5 { + border-block-start-color: color-mix(in oklab, var(--color-red-500) 2.5%, transparent); + } +} + +.border-bs-red-500\\/2\\.25 { + border-block-start-color: #ef444406; +} + +@supports (color: color-mix(in lab, red, red)) { + .border-bs-red-500\\/2\\.25 { + border-block-start-color: color-mix(in oklab, var(--color-red-500) 2.25%, transparent); + } +} + +.border-bs-red-500\\/2\\.75 { + border-block-start-color: #ef444407; +} + +@supports (color: color-mix(in lab, red, red)) { + .border-bs-red-500\\/2\\.75 { + border-block-start-color: color-mix(in oklab, var(--color-red-500) 2.75%, transparent); + } +} + +.border-bs-red-500\\/50 { + border-block-start-color: #ef444480; +} + +@supports (color: color-mix(in lab, red, red)) { + .border-bs-red-500\\/50 { + border-block-start-color: color-mix(in oklab, var(--color-red-500) 50%, transparent); + } +} + +.border-bs-transparent { + border-block-start-color: #0000; +} + +@property --tw-border-style { + syntax: "*"; + inherits: false; + initial-value: solid; +}" +`; + exports[`border-e-* 1`] = ` "@layer properties { @supports (((-webkit-hyphens: none)) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color: rgb(from red r g b)))) { diff --git a/packages/tailwindcss/src/canonicalize-candidates.test.ts b/packages/tailwindcss/src/canonicalize-candidates.test.ts index b8ca59d67880..fae944cde362 100644 --- a/packages/tailwindcss/src/canonicalize-candidates.test.ts +++ b/packages/tailwindcss/src/canonicalize-candidates.test.ts @@ -1163,3 +1163,46 @@ describe('options', () => { expect(designSystem.canonicalizeCandidates(['m-[16px]'])).toEqual(['m-[16px]']) // Ensure options don't influence shared state }) }) + +// https://github.com/schoero/eslint-plugin-better-tailwindcss/issues/321 +test('a subset of classes should be canonicalizable', { timeout }, async () => { + let designSystem = await designSystems.get(__dirname).get(css` + @import 'tailwindcss'; + `) + + let options: CanonicalizeOptions = { + collapse: true, + logicalToPhysical: true, + rem: 16, + } + + expect( + designSystem.canonicalizeCandidates(['underline', 'h-4', 'w-4', 'text-sm'], options), + ).toEqual(['underline', 'text-sm', 'size-4']) +}) + +test('collapse canonicalization is not affected by previous calls', { timeout }, async () => { + let designSystem = await designSystems.get(__dirname).get(css` + @import 'tailwindcss'; + `) + + let options: CanonicalizeOptions = { + collapse: true, + logicalToPhysical: true, + rem: 16, + } + + let target = ['underline', 'h-4', 'w-4'] + + expect(designSystem.canonicalizeCandidates(target, options)).toEqual(['underline', 'size-4']) + + designSystem.canonicalizeCandidates(['mb-4', 'text-sm'], options) + designSystem.canonicalizeCandidates(['underline', 'mb-4'], options) + + expect(designSystem.canonicalizeCandidates(target, options)).toEqual(['underline', 'size-4']) + expect(designSystem.canonicalizeCandidates(target.concat('text-sm'), options)).toEqual([ + 'underline', + 'text-sm', + 'size-4', + ]) +}) diff --git a/packages/tailwindcss/src/canonicalize-candidates.ts b/packages/tailwindcss/src/canonicalize-candidates.ts index 61212998545d..64fa2d8b16cf 100644 --- a/packages/tailwindcss/src/canonicalize-candidates.ts +++ b/packages/tailwindcss/src/canonicalize-candidates.ts @@ -267,6 +267,8 @@ function collapseCandidates(options: InternalCanonicalizeOptions, candidates: st let interestingLineHeights = new Set() let seenLineHeights = new Set() for (let pairs of candidatePropertiesValues) { + if (!pairs.has('line-height')) continue + for (let lineHeight of pairs.get('line-height')) { if (seenLineHeights.has(lineHeight)) continue seenLineHeights.add(lineHeight) @@ -292,6 +294,8 @@ function collapseCandidates(options: InternalCanonicalizeOptions, candidates: st let seenFontSizes = new Set() for (let pairs of candidatePropertiesValues) { + if (!pairs.has('font-size')) continue + for (let fontSize of pairs.get('font-size')) { if (seenFontSizes.has(fontSize)) continue seenFontSizes.add(fontSize) diff --git a/packages/tailwindcss/src/compat/colors.ts b/packages/tailwindcss/src/compat/colors.ts index 2f443b4b65e1..a1d162c54b06 100644 --- a/packages/tailwindcss/src/compat/colors.ts +++ b/packages/tailwindcss/src/compat/colors.ts @@ -69,6 +69,58 @@ export default { '900': 'oklch(21.6% 0.006 56.043)', '950': 'oklch(14.7% 0.004 49.25)', }, + mauve: { + '50': 'oklch(98.5% 0 0)', + '100': 'oklch(96% 0.003 325.6)', + '200': 'oklch(92.2% 0.005 325.62)', + '300': 'oklch(86.5% 0.012 325.68)', + '400': 'oklch(71.1% 0.019 323.02)', + '500': 'oklch(54.2% 0.034 322.5)', + '600': 'oklch(43.5% 0.029 321.78)', + '700': 'oklch(36.4% 0.029 323.89)', + '800': 'oklch(26.3% 0.024 320.12)', + '900': 'oklch(21.2% 0.019 322.12)', + '950': 'oklch(14.5% 0.008 326)', + }, + olive: { + '50': 'oklch(98.8% 0.003 106.5)', + '100': 'oklch(96.6% 0.005 106.5)', + '200': 'oklch(93% 0.007 106.5)', + '300': 'oklch(88% 0.011 106.6)', + '400': 'oklch(73.7% 0.021 106.9)', + '500': 'oklch(58% 0.031 107.3)', + '600': 'oklch(46.6% 0.025 107.3)', + '700': 'oklch(39.4% 0.023 107.4)', + '800': 'oklch(28.6% 0.016 107.4)', + '900': 'oklch(22.8% 0.013 107.4)', + '950': 'oklch(15.3% 0.006 107.1)', + }, + mist: { + '50': 'oklch(98.7% 0.002 197.1)', + '100': 'oklch(96.3% 0.002 197.1)', + '200': 'oklch(92.5% 0.005 214.3)', + '300': 'oklch(87.2% 0.007 219.6)', + '400': 'oklch(72.3% 0.014 214.4)', + '500': 'oklch(56% 0.021 213.5)', + '600': 'oklch(45% 0.017 213.2)', + '700': 'oklch(37.8% 0.015 216)', + '800': 'oklch(27.5% 0.011 216.9)', + '900': 'oklch(21.8% 0.008 223.9)', + '950': 'oklch(14.8% 0.004 228.8)', + }, + taupe: { + '50': 'oklch(98.6% 0.002 67.8)', + '100': 'oklch(96% 0.002 17.2)', + '200': 'oklch(92.2% 0.005 34.3)', + '300': 'oklch(86.8% 0.007 39.5)', + '400': 'oklch(71.4% 0.014 41.2)', + '500': 'oklch(54.7% 0.021 43.1)', + '600': 'oklch(43.8% 0.017 39.3)', + '700': 'oklch(36.7% 0.016 35.7)', + '800': 'oklch(26.8% 0.011 36.5)', + '900': 'oklch(21.4% 0.009 43.1)', + '950': 'oklch(14.7% 0.004 49.3)', + }, red: { '50': 'oklch(97.1% 0.013 17.38)', '100': 'oklch(93.6% 0.032 17.717)', diff --git a/packages/tailwindcss/src/compat/legacy-utilities.test.ts b/packages/tailwindcss/src/compat/legacy-utilities.test.ts index 9a828d673b78..24222f882f75 100644 --- a/packages/tailwindcss/src/compat/legacy-utilities.test.ts +++ b/packages/tailwindcss/src/compat/legacy-utilities.test.ts @@ -211,3 +211,177 @@ test('flex-shrink', async () => { ]), ).toEqual('') }) + +test('start', async () => { + expect( + await compileCss( + css` + @theme { + --spacing-4: 1rem; + --inset-shadowned: 1940px; + } + @tailwind utilities; + `, + [ + 'start-shadowned', + 'start-auto', + '-start-full', + 'start-full', + 'start-3/4', + 'start-4', + '-start-4', + 'start-[4px]', + ], + ), + ).toMatchInlineSnapshot(` + ":root, :host { + --spacing-4: 1rem; + --inset-shadowned: 1940px; + } + + .-start-4 { + inset-inline-start: calc(var(--spacing-4) * -1); + } + + .-start-full { + inset-inline-start: -100%; + } + + .start-3\\/4 { + inset-inline-start: 75%; + } + + .start-4 { + inset-inline-start: var(--spacing-4); + } + + .start-\\[4px\\] { + inset-inline-start: 4px; + } + + .start-auto { + inset-inline-start: auto; + } + + .start-full { + inset-inline-start: 100%; + } + + .start-shadowned { + inset-inline-start: var(--inset-shadowned); + }" + `) + expect( + await compileCss( + css` + @theme reference { + --spacing-4: 1rem; + --inset-shadow-sm: inset 0 1px 1px rgb(0 0 0 / 0.05); + } + @tailwind utilities; + `, + [ + 'start-shadow-sm', + 'start', + 'start--1', + 'start--1/2', + 'start--1/-2', + 'start-1/-2', + 'start-auto/foo', + '-start-full/foo', + 'start-full/foo', + 'start-3/4/foo', + 'start-4/foo', + '-start-4/foo', + 'start-[4px]/foo', + ], + ), + ).toEqual('') +}) + +test('end', async () => { + expect( + await compileCss( + css` + @theme { + --spacing-4: 1rem; + --inset-shadowned: 1940px; + } + @tailwind utilities; + `, + [ + 'end-shadowned', + 'end-auto', + '-end-full', + 'end-full', + 'end-3/4', + 'end-4', + '-end-4', + 'end-[4px]', + ], + ), + ).toMatchInlineSnapshot(` + ":root, :host { + --spacing-4: 1rem; + --inset-shadowned: 1940px; + } + + .-end-4 { + inset-inline-end: calc(var(--spacing-4) * -1); + } + + .-end-full { + inset-inline-end: -100%; + } + + .end-3\\/4 { + inset-inline-end: 75%; + } + + .end-4 { + inset-inline-end: var(--spacing-4); + } + + .end-\\[4px\\] { + inset-inline-end: 4px; + } + + .end-auto { + inset-inline-end: auto; + } + + .end-full { + inset-inline-end: 100%; + } + + .end-shadowned { + inset-inline-end: var(--inset-shadowned); + }" + `) + expect( + await compileCss( + css` + @theme reference { + --spacing-4: 1rem; + --inset-shadow-sm: inset 0 1px 1px rgb(0 0 0 / 0.05); + } + @tailwind utilities; + `, + [ + 'end-shadow-sm', + 'end', + 'end--1', + 'end--1/2', + 'end--1/-2', + 'end-1/-2', + 'end-auto/foo', + '-end-full/foo', + 'end-full/foo', + 'end-3/4/foo', + 'end-4/foo', + '-end-4/foo', + 'end-[4px]/foo', + ], + ), + ).toEqual('') +}) diff --git a/packages/tailwindcss/src/compat/legacy-utilities.ts b/packages/tailwindcss/src/compat/legacy-utilities.ts index ffefca940e35..dc53e42179c8 100644 --- a/packages/tailwindcss/src/compat/legacy-utilities.ts +++ b/packages/tailwindcss/src/compat/legacy-utilities.ts @@ -1,6 +1,7 @@ import { decl } from '../ast' import type { DesignSystem } from '../design-system' -import { isPositiveInteger } from '../utils/infer-data-type' +import { isPositiveInteger, isValidSpacingMultiplier } from '../utils/infer-data-type' +import { segment } from '../utils/segment' export function registerLegacyUtilities(designSystem: DesignSystem) { for (let [value, direction] of [ @@ -111,4 +112,68 @@ export function registerLegacyUtilities(designSystem: DesignSystem) { designSystem.utilities.suggest('break-words', () => []) designSystem.utilities.static('break-words', () => [decl('overflow-wrap', 'break-word')]) + + // Legacy `start` and `end` inset utilities, replaced by `inset-s` and `inset-e` + for (let [name, property] of [ + ['start', 'inset-inline-start'], + ['end', 'inset-inline-end'], + ] as const) { + designSystem.utilities.static(`${name}-auto`, () => [decl(property, 'auto')]) + designSystem.utilities.static(`${name}-full`, () => [decl(property, '100%')]) + designSystem.utilities.static(`-${name}-full`, () => [decl(property, '-100%')]) + designSystem.utilities.static(`${name}-px`, () => [decl(property, '1px')]) + designSystem.utilities.static(`-${name}-px`, () => [decl(property, '-1px')]) + + function handleInset({ negative }: { negative: boolean }) { + return (candidate: Extract) => { + if (!candidate.value) { + if (candidate.modifier) return + let value = designSystem.theme.resolve(null, ['--inset', '--spacing']) + if (value === null) return + return [decl(property, negative ? `calc(${value} * -1)` : value)] + } + + if (candidate.value.kind === 'arbitrary') { + if (candidate.modifier) return + let value = candidate.value.value + return [decl(property, negative ? `calc(${value} * -1)` : value)] + } + + let value = designSystem.theme.resolve(candidate.value.fraction ?? candidate.value.value, [ + '--inset', + '--spacing', + ]) + + // Handle fractions like `start-1/2` + if (value === null && candidate.value.fraction) { + let [lhs, rhs] = segment(candidate.value.fraction, '/') + if (!isPositiveInteger(lhs) || !isPositiveInteger(rhs)) return + value = `calc(${candidate.value.fraction} * 100%)` + } + + // Handle bare spacing multiplier values like `start-4` + if (value === null && negative) { + let multiplier = designSystem.theme.resolve(null, ['--spacing']) + if (multiplier && isValidSpacingMultiplier(candidate.value.value)) { + value = `calc(${multiplier} * -${candidate.value.value})` + if (value !== null) return [decl(property, value)] + } + } + + if (value === null) { + let multiplier = designSystem.theme.resolve(null, ['--spacing']) + if (multiplier && isValidSpacingMultiplier(candidate.value.value)) { + value = `calc(${multiplier} * ${candidate.value.value})` + } + } + + if (value === null) return + + return [decl(property, negative ? `calc(${value} * -1)` : value)] + } + } + + designSystem.utilities.functional(`-${name}`, handleInset({ negative: true })) + designSystem.utilities.functional(name, handleInset({ negative: false })) + } } diff --git a/packages/tailwindcss/src/css-functions.test.ts b/packages/tailwindcss/src/css-functions.test.ts index 464f058641e0..3e880dd8b0d7 100644 --- a/packages/tailwindcss/src/css-functions.test.ts +++ b/packages/tailwindcss/src/css-functions.test.ts @@ -313,7 +313,8 @@ describe('--theme(…)', () => { ), ).toMatchInlineSnapshot(` ":root, :host { - --tw-font-sans: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; + --tw-font-sans: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", + "Segoe UI Symbol", "Noto Color Emoji"; --tw-default-font-family: var(--tw-font-sans); } @@ -1360,7 +1361,7 @@ test('resolves paths ending with a 1', async () => { `) }) -test('upgrades to a full JS compat theme lookup if a value can not be mapped to a CSS variable', async () => { +test('upgrades to a full JS compat theme lookup if a value cannot be mapped to a CSS variable', async () => { expect( await compileCss( css` diff --git a/packages/tailwindcss/src/index.test.ts b/packages/tailwindcss/src/index.test.ts index 94b17714ed25..5eb7407d81dd 100644 --- a/packages/tailwindcss/src/index.test.ts +++ b/packages/tailwindcss/src/index.test.ts @@ -1561,7 +1561,8 @@ describe('Parsing theme values from CSS', () => { ), ).toMatchInlineSnapshot(` ":root, :host { - --animate-very-long-animation-name: very-long-animation-name var(--very-long-animation-name-configuration, 2.5s ease-in-out 0s infinite normal none running); + --animate-very-long-animation-name: very-long-animation-name + var(--very-long-animation-name-configuration, 2.5s ease-in-out 0s infinite normal none running); } .animate-very-long-animation-name { @@ -3097,7 +3098,7 @@ describe('plugins', () => { ).rejects.toThrowErrorMatchingInlineSnapshot(`[Error: \`@plugin\` must have a path.]`) }) - test('@plugin can not have an empty path', () => { + test('@plugin cannot have an empty path', () => { return expect( compile( css` @@ -4558,6 +4559,97 @@ describe('@custom-variant', () => { `) }) + // https://github.com/tailwindlabs/tailwindcss/issues/19618 + test('@custom-variant can use a @variant that eventually uses another @custom-variant', async () => { + expect( + await compileCss( + css` + @custom-variant a { + @slot; + } + + @custom-variant b { + @variant a { + @slot; + } + } + + @tailwind utilities; + `, + ['a:flex', 'b:flex', 'a:b:flex', 'b:a:flex'], + ), + ).toMatchInlineSnapshot(` + ".a\\:flex, .b\\:flex, .a\\:b\\:flex, .b\\:a\\:flex { + display: flex; + }" + `) + }) + + test('@custom-variant can use a @variant that eventually uses another @custom-variant (2)', async () => { + expect( + await compileCss( + css` + @custom-variant a { + .a { + @slot; + } + } + + @custom-variant b { + .b { + @variant a { + .a-inside-b { + @slot; + } + } + } + } + + @tailwind utilities; + `, + ['a:flex', 'b:flex', 'a:b:flex', 'b:a:flex'], + ), + ).toMatchInlineSnapshot(` + ".a\\:flex .a, .b\\:flex .b .a .a-inside-b, .a\\:b\\:flex .a .b .a .a-inside-b, .b\\:a\\:flex .b .a .a-inside-b .a { + display: flex; + }" + `) + }) + + // https://github.com/tailwindlabs/tailwindcss/issues/19618#issuecomment-3830775912 + test('@custom-variant can use existing @slot @variants', async () => { + expect( + await compileCss( + css` + @custom-variant hocus { + @variant hover { + @variant focus { + @slot; + } + } + } + + @custom-variant hover { + &:hover { + @slot; + } + + &[data-hover] { + @slot; + } + } + + @tailwind utilities; + `, + ['hocus:flex'], + ), + ).toMatchInlineSnapshot(` + ".hocus\\:flex:hover:focus, .hocus\\:flex[data-hover]:focus { + display: flex; + }" + `) + }) + test('@custom-variant setup that results in a circular dependency error can be solved', async () => { expect( await compileCss( @@ -4637,6 +4729,31 @@ describe('@utility', () => { ) }) + test('@utility can handle escape sequences correctly', async () => { + let { build } = await compile(css` + @layer utilities { + @tailwind utilities; + } + + @utility push-1\/2 { + right: 50%; + } + + @utility push-50\% { + right: 50%; + } + `) + let compiled = build(['push-1/2', 'push-50%']) + + expect(optimizeCss(compiled).trim()).toMatchInlineSnapshot(` + "@layer utilities { + .push-1\\/2, .push-50\\% { + right: 50%; + } + }" + `) + }) + test('A functional @utility must end in -*', () => { return expect( compileCss(css` @@ -5559,7 +5676,7 @@ describe('`color-mix(…)` polyfill', () => { @supports (color: color-mix(in lab, red, red)) { .text-red-500\\/50 { - color: color-mix(in oklab, var(--color-red-500) 50%, transparent); + color: color-mix(in oklab,var(--color-red-500)50%,transparent); } }" `) diff --git a/packages/tailwindcss/src/property-order.ts b/packages/tailwindcss/src/property-order.ts index f024f69771a0..e92bc374479c 100644 --- a/packages/tailwindcss/src/property-order.ts +++ b/packages/tailwindcss/src/property-order.ts @@ -11,6 +11,8 @@ export default [ 'inset-block', 'inset-inline-start', 'inset-inline-end', + 'inset-block-start', + 'inset-block-end', 'top', 'right', 'bottom', @@ -39,6 +41,8 @@ export default [ 'margin-block', 'margin-inline-start', 'margin-inline-end', + 'margin-block-start', + 'margin-block-end', 'margin-top', 'margin-right', 'margin-bottom', @@ -108,6 +112,8 @@ export default [ 'scroll-margin-block', 'scroll-margin-inline-start', 'scroll-margin-inline-end', + 'scroll-margin-block-start', + 'scroll-margin-block-end', 'scroll-margin-top', 'scroll-margin-right', 'scroll-margin-bottom', @@ -118,6 +124,8 @@ export default [ 'scroll-padding-block', 'scroll-padding-inline-start', 'scroll-padding-inline-end', + 'scroll-padding-block-start', + 'scroll-padding-block-end', 'scroll-padding-top', 'scroll-padding-right', 'scroll-padding-bottom', @@ -196,6 +204,8 @@ export default [ 'border-block-width', 'border-inline-start-width', 'border-inline-end-width', + 'border-block-start-width', + 'border-block-end-width', 'border-top-width', 'border-right-width', 'border-bottom-width', @@ -206,6 +216,8 @@ export default [ 'border-block-style', 'border-inline-start-style', 'border-inline-end-style', + 'border-block-start-style', + 'border-block-end-style', 'border-top-style', 'border-right-style', 'border-bottom-style', @@ -216,6 +228,8 @@ export default [ 'border-block-color', 'border-inline-start-color', 'border-inline-end-color', + 'border-block-start-color', + 'border-block-end-color', 'border-top-color', 'border-right-color', 'border-bottom-color', @@ -317,6 +331,8 @@ export default [ 'padding-block', 'padding-inline-start', 'padding-inline-end', + 'padding-block-start', + 'padding-block-end', 'padding-top', 'padding-right', 'padding-bottom', @@ -327,6 +343,7 @@ export default [ 'vertical-align', 'font-family', + 'font-feature-settings', 'font-size', 'line-height', 'font-weight', diff --git a/packages/tailwindcss/src/source-maps/source-map.test.ts b/packages/tailwindcss/src/source-maps/source-map.test.ts index 8433e8aa031a..02d8a434acb4 100644 --- a/packages/tailwindcss/src/source-maps/source-map.test.ts +++ b/packages/tailwindcss/src/source-maps/source-map.test.ts @@ -178,8 +178,8 @@ test('source maps trace back to @import location', async ({ expect }) => { 'theme.css: 5:22 <- 4:22', 'theme.css: 6:4 <- 6:2-8:0', 'theme.css: 7:13 <- 8:13', - 'theme.css: 8:4-43 <- 446:2-54', - 'theme.css: 9:4-48 <- 449:2-59', + 'theme.css: 8:4-43 <- 494:2-54', + 'theme.css: 9:4-48 <- 497:2-59', 'index.css: 12:0-12 <- 4:0-37', 'preflight.css: 13:2-59 <- 7:0-11:23', 'preflight.css: 14:4-26 <- 12:2-24', diff --git a/packages/tailwindcss/src/utilities.test.ts b/packages/tailwindcss/src/utilities.test.ts index cff2284f45c9..360acd9e29a6 100644 --- a/packages/tailwindcss/src/utilities.test.ts +++ b/packages/tailwindcss/src/utilities.test.ts @@ -480,7 +480,7 @@ test('inset-y', async () => { ).toEqual('') }) -test('start', async () => { +test('inset-s', async () => { expect( await compileCss( css` @@ -491,14 +491,14 @@ test('start', async () => { @tailwind utilities; `, [ - 'start-shadowned', - 'start-auto', - '-start-full', - 'start-full', - 'start-3/4', - 'start-4', - '-start-4', - 'start-[4px]', + 'inset-s-shadowned', + 'inset-s-auto', + '-inset-s-full', + 'inset-s-full', + 'inset-s-3/4', + 'inset-s-4', + '-inset-s-4', + 'inset-s-[4px]', ], ), ).toMatchInlineSnapshot(` @@ -507,35 +507,35 @@ test('start', async () => { --inset-shadowned: 1940px; } - .-start-4 { + .-inset-s-4 { inset-inline-start: calc(var(--spacing-4) * -1); } - .-start-full { + .-inset-s-full { inset-inline-start: -100%; } - .start-3\\/4 { + .inset-s-3\\/4 { inset-inline-start: 75%; } - .start-4 { + .inset-s-4 { inset-inline-start: var(--spacing-4); } - .start-\\[4px\\] { + .inset-s-\\[4px\\] { inset-inline-start: 4px; } - .start-auto { + .inset-s-auto { inset-inline-start: auto; } - .start-full { + .inset-s-full { inset-inline-start: 100%; } - .start-shadowned { + .inset-s-shadowned { inset-inline-start: var(--inset-shadowned); }" `) @@ -549,25 +549,25 @@ test('start', async () => { @tailwind utilities; `, [ - 'start-shadow-sm', - 'start', - 'start--1', - 'start--1/2', - 'start--1/-2', - 'start-1/-2', - 'start-auto/foo', - '-start-full/foo', - 'start-full/foo', - 'start-3/4/foo', - 'start-4/foo', - '-start-4/foo', - 'start-[4px]/foo', + 'inset-s-shadow-sm', + 'inset-s', + 'inset-s--1', + 'inset-s--1/2', + 'inset-s--1/-2', + 'inset-s-1/-2', + 'inset-s-auto/foo', + '-inset-s-full/foo', + 'inset-s-full/foo', + 'inset-s-3/4/foo', + 'inset-s-4/foo', + '-inset-s-4/foo', + 'inset-s-[4px]/foo', ], ), ).toEqual('') }) -test('end', async () => { +test('inset-e', async () => { expect( await compileCss( css` @@ -578,14 +578,14 @@ test('end', async () => { @tailwind utilities; `, [ - 'end-shadowned', - 'end-auto', - '-end-full', - 'end-full', - 'end-3/4', - 'end-4', - '-end-4', - 'end-[4px]', + 'inset-e-shadowned', + 'inset-e-auto', + '-inset-e-full', + 'inset-e-full', + 'inset-e-3/4', + 'inset-e-4', + '-inset-e-4', + 'inset-e-[4px]', ], ), ).toMatchInlineSnapshot(` @@ -594,35 +594,35 @@ test('end', async () => { --inset-shadowned: 1940px; } - .-end-4 { + .-inset-e-4 { inset-inline-end: calc(var(--spacing-4) * -1); } - .-end-full { + .-inset-e-full { inset-inline-end: -100%; } - .end-3\\/4 { + .inset-e-3\\/4 { inset-inline-end: 75%; } - .end-4 { + .inset-e-4 { inset-inline-end: var(--spacing-4); } - .end-\\[4px\\] { + .inset-e-\\[4px\\] { inset-inline-end: 4px; } - .end-auto { + .inset-e-auto { inset-inline-end: auto; } - .end-full { + .inset-e-full { inset-inline-end: 100%; } - .end-shadowned { + .inset-e-shadowned { inset-inline-end: var(--inset-shadowned); }" `) @@ -636,19 +636,193 @@ test('end', async () => { @tailwind utilities; `, [ - 'end-shadow-sm', - 'end', - 'end--1', - 'end--1/2', - 'end--1/-2', - 'end-1/-2', - 'end-auto/foo', - '-end-full/foo', - 'end-full/foo', - 'end-3/4/foo', - 'end-4/foo', - '-end-4/foo', - 'end-[4px]/foo', + 'inset-e-shadow-sm', + 'inset-e', + 'inset-e--1', + 'inset-e--1/2', + 'inset-e--1/-2', + 'inset-e-1/-2', + 'inset-e-auto/foo', + '-inset-e-full/foo', + 'inset-e-full/foo', + 'inset-e-3/4/foo', + 'inset-e-4/foo', + '-inset-e-4/foo', + 'inset-e-[4px]/foo', + ], + ), + ).toEqual('') +}) + +test('inset-bs', async () => { + expect( + await compileCss( + css` + @theme { + --spacing-4: 1rem; + --inset-shadowned: 1940px; + } + @tailwind utilities; + `, + [ + 'inset-bs-shadowned', + 'inset-bs-auto', + '-inset-bs-full', + 'inset-bs-full', + 'inset-bs-3/4', + 'inset-bs-4', + '-inset-bs-4', + 'inset-bs-[4px]', + ], + ), + ).toMatchInlineSnapshot(` + ":root, :host { + --spacing-4: 1rem; + --inset-shadowned: 1940px; + } + + .-inset-bs-4 { + inset-block-start: calc(var(--spacing-4) * -1); + } + + .-inset-bs-full { + inset-block-start: -100%; + } + + .inset-bs-3\\/4 { + inset-block-start: 75%; + } + + .inset-bs-4 { + inset-block-start: var(--spacing-4); + } + + .inset-bs-\\[4px\\] { + inset-block-start: 4px; + } + + .inset-bs-auto { + inset-block-start: auto; + } + + .inset-bs-full { + inset-block-start: 100%; + } + + .inset-bs-shadowned { + inset-block-start: var(--inset-shadowned); + }" + `) + expect( + await compileCss( + css` + @theme reference { + --spacing-4: 1rem; + --inset-shadow-sm: inset 0 1px 1px rgb(0 0 0 / 0.05); + } + @tailwind utilities; + `, + [ + 'inset-bs-shadow-sm', + 'inset-bs', + 'inset-bs--1', + 'inset-bs--1/2', + 'inset-bs--1/-2', + 'inset-bs-1/-2', + 'inset-bs-auto/foo', + '-inset-bs-full/foo', + 'inset-bs-full/foo', + 'inset-bs-3/4/foo', + 'inset-bs-4/foo', + '-inset-bs-4/foo', + 'inset-bs-[4px]/foo', + ], + ), + ).toEqual('') +}) + +test('inset-be', async () => { + expect( + await compileCss( + css` + @theme { + --spacing-4: 1rem; + --inset-shadowned: 1940px; + } + @tailwind utilities; + `, + [ + 'inset-be-shadowned', + 'inset-be-auto', + '-inset-be-full', + 'inset-be-full', + 'inset-be-3/4', + 'inset-be-4', + '-inset-be-4', + 'inset-be-[4px]', + ], + ), + ).toMatchInlineSnapshot(` + ":root, :host { + --spacing-4: 1rem; + --inset-shadowned: 1940px; + } + + .-inset-be-4 { + inset-block-end: calc(var(--spacing-4) * -1); + } + + .-inset-be-full { + inset-block-end: -100%; + } + + .inset-be-3\\/4 { + inset-block-end: 75%; + } + + .inset-be-4 { + inset-block-end: var(--spacing-4); + } + + .inset-be-\\[4px\\] { + inset-block-end: 4px; + } + + .inset-be-auto { + inset-block-end: auto; + } + + .inset-be-full { + inset-block-end: 100%; + } + + .inset-be-shadowned { + inset-block-end: var(--inset-shadowned); + }" + `) + expect( + await compileCss( + css` + @theme reference { + --spacing-4: 1rem; + --inset-shadow-sm: inset 0 1px 1px rgb(0 0 0 / 0.05); + } + @tailwind utilities; + `, + [ + 'inset-be-shadow-sm', + 'inset-be', + 'inset-be--1', + 'inset-be--1/2', + 'inset-be--1/-2', + 'inset-be-1/-2', + 'inset-be-auto/foo', + '-inset-be-full/foo', + 'inset-be-full/foo', + 'inset-be-3/4/foo', + 'inset-be-4/foo', + '-inset-be-4/foo', + 'inset-be-[4px]/foo', ], ), ).toEqual('') @@ -2216,6 +2390,178 @@ test('me', async () => { ).toEqual('') }) +test('mbs', async () => { + expect( + await compileCss( + css` + @theme { + --spacing: 0.25rem; + --spacing-big: 100rem; + } + @tailwind utilities; + `, + [ + 'mbs-1', + 'mbs-99', + 'mbs-2.5', + 'mbs-big', + 'mbs-[4px]', + '-mbs-4', + '-mbs-2.5', + '-mbs-big', + '-mbs-[4px]', + 'mbs-[var(--my-var)]', + '-mbs-[var(--my-var)]', + ], + ), + ).toMatchInlineSnapshot(` + ":root, :host { + --spacing: .25rem; + --spacing-big: 100rem; + } + + .-mbs-2\\.5 { + margin-block-start: calc(var(--spacing) * -2.5); + } + + .-mbs-4 { + margin-block-start: calc(var(--spacing) * -4); + } + + .-mbs-\\[4px\\] { + margin-block-start: -4px; + } + + .-mbs-\\[var\\(--my-var\\)\\] { + margin-block-start: calc(var(--my-var) * -1); + } + + .-mbs-big { + margin-block-start: calc(var(--spacing-big) * -1); + } + + .mbs-1 { + margin-block-start: calc(var(--spacing) * 1); + } + + .mbs-2\\.5 { + margin-block-start: calc(var(--spacing) * 2.5); + } + + .mbs-99 { + margin-block-start: calc(var(--spacing) * 99); + } + + .mbs-\\[4px\\] { + margin-block-start: 4px; + } + + .mbs-\\[var\\(--my-var\\)\\] { + margin-block-start: var(--my-var); + } + + .mbs-big { + margin-block-start: var(--spacing-big); + }" + `) + expect( + await run([ + 'mbs', + 'mbs-auto/foo', + 'mbs-4/foo', + 'mbs-[4px]/foo', + '-mbs-4/foo', + '-mbs-[var(--value)]/foo', + ]), + ).toEqual('') +}) + +test('mbe', async () => { + expect( + await compileCss( + css` + @theme { + --spacing: 0.25rem; + --spacing-big: 100rem; + } + @tailwind utilities; + `, + [ + 'mbe-1', + 'mbe-99', + 'mbe-2.5', + 'mbe-big', + 'mbe-[4px]', + '-mbe-4', + '-mbe-2.5', + '-mbe-big', + '-mbe-[4px]', + 'mbe-[var(--my-var)]', + '-mbe-[var(--my-var)]', + ], + ), + ).toMatchInlineSnapshot(` + ":root, :host { + --spacing: .25rem; + --spacing-big: 100rem; + } + + .-mbe-2\\.5 { + margin-block-end: calc(var(--spacing) * -2.5); + } + + .-mbe-4 { + margin-block-end: calc(var(--spacing) * -4); + } + + .-mbe-\\[4px\\] { + margin-block-end: -4px; + } + + .-mbe-\\[var\\(--my-var\\)\\] { + margin-block-end: calc(var(--my-var) * -1); + } + + .-mbe-big { + margin-block-end: calc(var(--spacing-big) * -1); + } + + .mbe-1 { + margin-block-end: calc(var(--spacing) * 1); + } + + .mbe-2\\.5 { + margin-block-end: calc(var(--spacing) * 2.5); + } + + .mbe-99 { + margin-block-end: calc(var(--spacing) * 99); + } + + .mbe-\\[4px\\] { + margin-block-end: 4px; + } + + .mbe-\\[var\\(--my-var\\)\\] { + margin-block-end: var(--my-var); + } + + .mbe-big { + margin-block-end: var(--spacing-big); + }" + `) + expect( + await run([ + 'mbe', + 'mbe-auto/foo', + 'mbe-4/foo', + 'mbe-[4px]/foo', + '-mbe-4/foo', + '-mbe-[var(--value)]/foo', + ]), + ).toEqual('') +}) + test('mr', async () => { expect( await compileCss( @@ -2810,7 +3156,7 @@ test('aspect-ratio', async () => { } @tailwind utilities; `, - ['aspect-video', 'aspect-[10/9]', 'aspect-4/3'], + ['aspect-video', 'aspect-[10/9]', 'aspect-4/3', 'aspect-8.5/11'], ), ).toMatchInlineSnapshot(` ":root, :host { @@ -2821,6 +3167,10 @@ test('aspect-ratio', async () => { aspect-ratio: 4 / 3; } + .aspect-8\\.5\\/11 { + aspect-ratio: 8.5 / 11; + } + .aspect-\\[10\\/9\\] { aspect-ratio: 10 / 9; } @@ -2842,6 +3192,7 @@ test('aspect-ratio', async () => { 'aspect--4/3', 'aspect--4/-3', 'aspect-4/-3', + 'aspect-1.23/4.56', ]), ).toEqual('') }) @@ -3391,7 +3742,570 @@ test('min-height', async () => { ).toEqual('') }) -test('max-height', async () => { +test('max-height', async () => { + expect( + await compileCss( + css` + @theme { + --spacing-4: 1rem; + } + @tailwind utilities; + `, + [ + 'max-h-none', + 'max-h-full', + 'max-h-screen', + 'max-h-svh', + 'max-h-lvh', + 'max-h-dvh', + 'max-h-lh', + 'max-h-min', + 'max-h-max', + 'max-h-fit', + 'max-h-4', + 'max-h-[4px]', + ], + ), + ).toMatchInlineSnapshot(` + ":root, :host { + --spacing-4: 1rem; + } + + .max-h-4 { + max-height: var(--spacing-4); + } + + .max-h-\\[4px\\] { + max-height: 4px; + } + + .max-h-dvh { + max-height: 100dvh; + } + + .max-h-fit { + max-height: fit-content; + } + + .max-h-full { + max-height: 100%; + } + + .max-h-lh { + max-height: 1lh; + } + + .max-h-lvh { + max-height: 100lvh; + } + + .max-h-max { + max-height: max-content; + } + + .max-h-min { + max-height: min-content; + } + + .max-h-none { + max-height: none; + } + + .max-h-screen { + max-height: 100vh; + } + + .max-h-svh { + max-height: 100svh; + }" + `) + expect( + await run([ + 'max-h', + 'max-h-auto', + '-max-h-4', + '-max-h-[4px]', + 'max-h-none/foo', + 'max-h-full/foo', + 'max-h-screen/foo', + 'max-h-svh/foo', + 'max-h-lvh/foo', + 'max-h-dvh/foo', + 'max-h-lh/foo', + 'max-h-min/foo', + 'max-h-max/foo', + 'max-h-fit/foo', + 'max-h-4/foo', + 'max-h-[4px]/foo', + ]), + ).toEqual('') +}) + +test('inline-size', async () => { + expect( + await compileCss( + css` + @theme { + --spacing-4: 1rem; + --container-xl: 36rem; + } + @tailwind utilities; + `, + [ + 'inline-full', + 'inline-auto', + 'inline-screen', + 'inline-svw', + 'inline-lvw', + 'inline-dvw', + 'inline-min', + 'inline-max', + 'inline-fit', + 'inline-4', + 'inline-xl', + 'inline-1/2', + 'inline-[4px]', + ], + ), + ).toMatchInlineSnapshot(` + ":root, :host { + --spacing-4: 1rem; + --container-xl: 36rem; + } + + .inline-1\\/2 { + inline-size: 50%; + } + + .inline-4 { + inline-size: var(--spacing-4); + } + + .inline-\\[4px\\] { + inline-size: 4px; + } + + .inline-auto { + inline-size: auto; + } + + .inline-dvw { + inline-size: 100dvw; + } + + .inline-fit { + inline-size: fit-content; + } + + .inline-full { + inline-size: 100%; + } + + .inline-lvw { + inline-size: 100lvw; + } + + .inline-max { + inline-size: max-content; + } + + .inline-min { + inline-size: min-content; + } + + .inline-screen { + inline-size: 100vw; + } + + .inline-svw { + inline-size: 100svw; + } + + .inline-xl { + inline-size: var(--container-xl); + }" + `) + expect( + await run([ + 'inline--1', + 'inline--1/2', + 'inline--1/-2', + 'inline-1/-2', + '-inline-4', + '-inline-1/2', + '-inline-[4px]', + 'inline-full/foo', + 'inline-auto/foo', + 'inline-screen/foo', + 'inline-svw/foo', + 'inline-lvw/foo', + 'inline-dvw/foo', + 'inline-min/foo', + 'inline-max/foo', + 'inline-fit/foo', + 'inline-4/foo', + 'inline-xl/foo', + 'inline-1/2/foo', + 'inline-[4px]/foo', + ]), + ).toEqual('') +}) + +test('min-inline-size', async () => { + expect( + await compileCss( + css` + @theme { + --spacing-4: 1rem; + --container-xl: 36rem; + } + @tailwind utilities; + `, + [ + 'min-inline-full', + 'min-inline-auto', + 'min-inline-min', + 'min-inline-max', + 'min-inline-fit', + 'min-inline-4', + 'min-inline-xl', + 'min-inline-[4px]', + ], + ), + ).toMatchInlineSnapshot(` + ":root, :host { + --spacing-4: 1rem; + --container-xl: 36rem; + } + + .min-inline-4 { + min-inline-size: var(--spacing-4); + } + + .min-inline-\\[4px\\] { + min-inline-size: 4px; + } + + .min-inline-auto { + min-inline-size: auto; + } + + .min-inline-fit { + min-inline-size: fit-content; + } + + .min-inline-full { + min-inline-size: 100%; + } + + .min-inline-max { + min-inline-size: max-content; + } + + .min-inline-min { + min-inline-size: min-content; + } + + .min-inline-xl { + min-inline-size: var(--container-xl); + }" + `) + expect( + await run([ + 'min-inline', + '-min-inline-4', + '-min-inline-[4px]', + 'min-inline-auto/foo', + 'min-inline-full/foo', + 'min-inline-min/foo', + 'min-inline-max/foo', + 'min-inline-fit/foo', + 'min-inline-4/foo', + 'min-inline-xl/foo', + 'min-inline-[4px]/foo', + ]), + ).toEqual('') +}) + +test('max-inline-size', async () => { + expect( + await compileCss( + css` + @theme { + --spacing-4: 1rem; + --container-xl: 36rem; + } + @tailwind utilities; + `, + [ + 'max-inline-none', + 'max-inline-full', + 'max-inline-max', + 'max-inline-fit', + 'max-inline-4', + 'max-inline-xl', + 'max-inline-[4px]', + ], + ), + ).toMatchInlineSnapshot(` + ":root, :host { + --spacing-4: 1rem; + --container-xl: 36rem; + } + + .max-inline-4 { + max-inline-size: var(--spacing-4); + } + + .max-inline-\\[4px\\] { + max-inline-size: 4px; + } + + .max-inline-fit { + max-inline-size: fit-content; + } + + .max-inline-full { + max-inline-size: 100%; + } + + .max-inline-max { + max-inline-size: max-content; + } + + .max-inline-none { + max-inline-size: none; + } + + .max-inline-xl { + max-inline-size: var(--container-xl); + }" + `) + expect( + await run([ + 'max-inline', + 'max-inline-auto', + '-max-inline-4', + '-max-inline-[4px]', + 'max-inline-none/foo', + 'max-inline-full/foo', + 'max-inline-max/foo', + 'max-inline-max/foo', + 'max-inline-fit/foo', + 'max-inline-4/foo', + 'max-inline-xl/foo', + 'max-inline-[4px]/foo', + ]), + ).toEqual('') +}) + +test('block-size', async () => { + expect( + await compileCss( + css` + @theme { + --spacing-4: 1rem; + } + @tailwind utilities; + `, + [ + 'block-full', + 'block-auto', + 'block-screen', + 'block-svh', + 'block-lvh', + 'block-dvh', + 'block-min', + 'block-lh', + 'block-max', + 'block-fit', + 'block-4', + 'block-1/2', + 'block-[4px]', + ], + ), + ).toMatchInlineSnapshot(` + ":root, :host { + --spacing-4: 1rem; + } + + .block-1\\/2 { + block-size: 50%; + } + + .block-4 { + block-size: var(--spacing-4); + } + + .block-\\[4px\\] { + block-size: 4px; + } + + .block-auto { + block-size: auto; + } + + .block-dvh { + block-size: 100dvh; + } + + .block-fit { + block-size: fit-content; + } + + .block-full { + block-size: 100%; + } + + .block-lh { + block-size: 1lh; + } + + .block-lvh { + block-size: 100lvh; + } + + .block-max { + block-size: max-content; + } + + .block-min { + block-size: min-content; + } + + .block-screen { + block-size: 100vh; + } + + .block-svh { + block-size: 100svh; + }" + `) + expect( + await run([ + '-block-4', + 'block--1', + 'block--1/2', + 'block--1/-2', + 'block-1/-2', + '-block-1/2', + '-block-[4px]', + 'block-full/foo', + 'block-auto/foo', + 'block-screen/foo', + 'block-svh/foo', + 'block-lvh/foo', + 'block-dvh/foo', + 'block-lh/foo', + 'block-min/foo', + 'block-max/foo', + 'block-fit/foo', + 'block-4/foo', + 'block-1/2/foo', + 'block-[4px]/foo', + ]), + ).toEqual('') +}) + +test('min-block-size', async () => { + expect( + await compileCss( + css` + @theme { + --spacing-4: 1rem; + } + @tailwind utilities; + `, + [ + 'min-block-full', + 'min-block-auto', + 'min-block-screen', + 'min-block-svh', + 'min-block-lvh', + 'min-block-dvh', + 'min-block-min', + 'min-block-lh', + 'min-block-max', + 'min-block-fit', + 'min-block-4', + 'min-block-[4px]', + ], + ), + ).toMatchInlineSnapshot(` + ":root, :host { + --spacing-4: 1rem; + } + + .min-block-4 { + min-block-size: var(--spacing-4); + } + + .min-block-\\[4px\\] { + min-block-size: 4px; + } + + .min-block-auto { + min-block-size: auto; + } + + .min-block-dvh { + min-block-size: 100dvh; + } + + .min-block-fit { + min-block-size: fit-content; + } + + .min-block-full { + min-block-size: 100%; + } + + .min-block-lh { + min-block-size: 1lh; + } + + .min-block-lvh { + min-block-size: 100lvh; + } + + .min-block-max { + min-block-size: max-content; + } + + .min-block-min { + min-block-size: min-content; + } + + .min-block-screen { + min-block-size: 100vh; + } + + .min-block-svh { + min-block-size: 100svh; + }" + `) + expect( + await run([ + 'min-block', + '-min-block-4', + '-min-block-[4px]', + 'min-block-auto/foo', + 'min-block-full/foo', + 'min-block-screen/foo', + 'min-block-svh/foo', + 'min-block-lvh/foo', + 'min-block-dvh/foo', + 'min-block-lh/foo', + 'min-block-min/foo', + 'min-block-max/foo', + 'min-block-fit/foo', + 'min-block-4/foo', + 'min-block-[4px]/foo', + ]), + ).toEqual('') +}) + +test('max-block-size', async () => { expect( await compileCss( css` @@ -3401,18 +4315,18 @@ test('max-height', async () => { @tailwind utilities; `, [ - 'max-h-none', - 'max-h-full', - 'max-h-screen', - 'max-h-svh', - 'max-h-lvh', - 'max-h-dvh', - 'max-h-lh', - 'max-h-min', - 'max-h-max', - 'max-h-fit', - 'max-h-4', - 'max-h-[4px]', + 'max-block-none', + 'max-block-full', + 'max-block-screen', + 'max-block-svh', + 'max-block-lvh', + 'max-block-dvh', + 'max-block-lh', + 'max-block-min', + 'max-block-max', + 'max-block-fit', + 'max-block-4', + 'max-block-[4px]', ], ), ).toMatchInlineSnapshot(` @@ -3420,72 +4334,72 @@ test('max-height', async () => { --spacing-4: 1rem; } - .max-h-4 { - max-height: var(--spacing-4); + .max-block-4 { + max-block-size: var(--spacing-4); } - .max-h-\\[4px\\] { - max-height: 4px; + .max-block-\\[4px\\] { + max-block-size: 4px; } - .max-h-dvh { - max-height: 100dvh; + .max-block-dvh { + max-block-size: 100dvh; } - .max-h-fit { - max-height: fit-content; + .max-block-fit { + max-block-size: fit-content; } - .max-h-full { - max-height: 100%; + .max-block-full { + max-block-size: 100%; } - .max-h-lh { - max-height: 1lh; + .max-block-lh { + max-block-size: 1lh; } - .max-h-lvh { - max-height: 100lvh; + .max-block-lvh { + max-block-size: 100lvh; } - .max-h-max { - max-height: max-content; + .max-block-max { + max-block-size: max-content; } - .max-h-min { - max-height: min-content; + .max-block-min { + max-block-size: min-content; } - .max-h-none { - max-height: none; + .max-block-none { + max-block-size: none; } - .max-h-screen { - max-height: 100vh; + .max-block-screen { + max-block-size: 100vh; } - .max-h-svh { - max-height: 100svh; + .max-block-svh { + max-block-size: 100svh; }" `) expect( await run([ - 'max-h', - 'max-h-auto', - '-max-h-4', - '-max-h-[4px]', - 'max-h-none/foo', - 'max-h-full/foo', - 'max-h-screen/foo', - 'max-h-svh/foo', - 'max-h-lvh/foo', - 'max-h-dvh/foo', - 'max-h-lh/foo', - 'max-h-min/foo', - 'max-h-max/foo', - 'max-h-fit/foo', - 'max-h-4/foo', - 'max-h-[4px]/foo', + 'max-block', + 'max-block-auto', + '-max-block-4', + '-max-block-[4px]', + 'max-block-none/foo', + 'max-block-full/foo', + 'max-block-screen/foo', + 'max-block-svh/foo', + 'max-block-lvh/foo', + 'max-block-dvh/foo', + 'max-block-lh/foo', + 'max-block-min/foo', + 'max-block-max/foo', + 'max-block-fit/foo', + 'max-block-4/foo', + 'max-block-[4px]/foo', ]), ).toEqual('') }) @@ -4855,27 +5769,27 @@ test('rotate-x', async () => { .-rotate-x-\\(--var\\) { --tw-rotate-x: rotateX(calc(var(--var) * -1)); - transform: var(--tw-rotate-x, ) var(--tw-rotate-y, ) var(--tw-rotate-z, ) var(--tw-skew-x, ) var(--tw-skew-y, ); + transform: var(--tw-rotate-x, ) var(--tw-rotate-y, ) var(--tw-rotate-z, ) var(--tw-skew-x, ) var(--tw-skew-y, ); } .-rotate-x-45 { --tw-rotate-x: rotateX(calc(45deg * -1)); - transform: var(--tw-rotate-x, ) var(--tw-rotate-y, ) var(--tw-rotate-z, ) var(--tw-skew-x, ) var(--tw-skew-y, ); + transform: var(--tw-rotate-x, ) var(--tw-rotate-y, ) var(--tw-rotate-z, ) var(--tw-skew-x, ) var(--tw-skew-y, ); } .rotate-x-\\(--var\\) { --tw-rotate-x: rotateX(var(--var)); - transform: var(--tw-rotate-x, ) var(--tw-rotate-y, ) var(--tw-rotate-z, ) var(--tw-skew-x, ) var(--tw-skew-y, ); + transform: var(--tw-rotate-x, ) var(--tw-rotate-y, ) var(--tw-rotate-z, ) var(--tw-skew-x, ) var(--tw-skew-y, ); } .rotate-x-45 { --tw-rotate-x: rotateX(45deg); - transform: var(--tw-rotate-x, ) var(--tw-rotate-y, ) var(--tw-rotate-z, ) var(--tw-skew-x, ) var(--tw-skew-y, ); + transform: var(--tw-rotate-x, ) var(--tw-rotate-y, ) var(--tw-rotate-z, ) var(--tw-skew-x, ) var(--tw-skew-y, ); } .rotate-x-\\[123deg\\] { --tw-rotate-x: rotateX(123deg); - transform: var(--tw-rotate-x, ) var(--tw-rotate-y, ) var(--tw-rotate-z, ) var(--tw-skew-x, ) var(--tw-skew-y, ); + transform: var(--tw-rotate-x, ) var(--tw-rotate-y, ) var(--tw-rotate-z, ) var(--tw-skew-x, ) var(--tw-skew-y, ); } @property --tw-rotate-x { @@ -4941,32 +5855,32 @@ test('rotate-y', async () => { .-rotate-y-\\(--var\\) { --tw-rotate-y: rotateY(calc(var(--var) * -1)); - transform: var(--tw-rotate-x, ) var(--tw-rotate-y, ) var(--tw-rotate-z, ) var(--tw-skew-x, ) var(--tw-skew-y, ); + transform: var(--tw-rotate-x, ) var(--tw-rotate-y, ) var(--tw-rotate-z, ) var(--tw-skew-x, ) var(--tw-skew-y, ); } .-rotate-y-45 { --tw-rotate-y: rotateY(calc(45deg * -1)); - transform: var(--tw-rotate-x, ) var(--tw-rotate-y, ) var(--tw-rotate-z, ) var(--tw-skew-x, ) var(--tw-skew-y, ); + transform: var(--tw-rotate-x, ) var(--tw-rotate-y, ) var(--tw-rotate-z, ) var(--tw-skew-x, ) var(--tw-skew-y, ); } .-rotate-y-\\[123deg\\] { --tw-rotate-y: rotateY(calc(123deg * -1)); - transform: var(--tw-rotate-x, ) var(--tw-rotate-y, ) var(--tw-rotate-z, ) var(--tw-skew-x, ) var(--tw-skew-y, ); + transform: var(--tw-rotate-x, ) var(--tw-rotate-y, ) var(--tw-rotate-z, ) var(--tw-skew-x, ) var(--tw-skew-y, ); } .rotate-y-\\(--var\\) { --tw-rotate-y: rotateY(var(--var)); - transform: var(--tw-rotate-x, ) var(--tw-rotate-y, ) var(--tw-rotate-z, ) var(--tw-skew-x, ) var(--tw-skew-y, ); + transform: var(--tw-rotate-x, ) var(--tw-rotate-y, ) var(--tw-rotate-z, ) var(--tw-skew-x, ) var(--tw-skew-y, ); } .rotate-y-45 { --tw-rotate-y: rotateY(45deg); - transform: var(--tw-rotate-x, ) var(--tw-rotate-y, ) var(--tw-rotate-z, ) var(--tw-skew-x, ) var(--tw-skew-y, ); + transform: var(--tw-rotate-x, ) var(--tw-rotate-y, ) var(--tw-rotate-z, ) var(--tw-skew-x, ) var(--tw-skew-y, ); } .rotate-y-\\[123deg\\] { --tw-rotate-y: rotateY(123deg); - transform: var(--tw-rotate-x, ) var(--tw-rotate-y, ) var(--tw-rotate-z, ) var(--tw-skew-x, ) var(--tw-skew-y, ); + transform: var(--tw-rotate-x, ) var(--tw-rotate-y, ) var(--tw-rotate-z, ) var(--tw-skew-x, ) var(--tw-skew-y, ); } @property --tw-rotate-x { @@ -5032,32 +5946,32 @@ test('rotate-z', async () => { .-rotate-z-\\(--var\\) { --tw-rotate-z: rotateZ(calc(var(--var) * -1)); - transform: var(--tw-rotate-x, ) var(--tw-rotate-y, ) var(--tw-rotate-z, ) var(--tw-skew-x, ) var(--tw-skew-y, ); + transform: var(--tw-rotate-x, ) var(--tw-rotate-y, ) var(--tw-rotate-z, ) var(--tw-skew-x, ) var(--tw-skew-y, ); } .-rotate-z-45 { --tw-rotate-z: rotateZ(calc(45deg * -1)); - transform: var(--tw-rotate-x, ) var(--tw-rotate-y, ) var(--tw-rotate-z, ) var(--tw-skew-x, ) var(--tw-skew-y, ); + transform: var(--tw-rotate-x, ) var(--tw-rotate-y, ) var(--tw-rotate-z, ) var(--tw-skew-x, ) var(--tw-skew-y, ); } .-rotate-z-\\[123deg\\] { --tw-rotate-z: rotateZ(calc(123deg * -1)); - transform: var(--tw-rotate-x, ) var(--tw-rotate-y, ) var(--tw-rotate-z, ) var(--tw-skew-x, ) var(--tw-skew-y, ); + transform: var(--tw-rotate-x, ) var(--tw-rotate-y, ) var(--tw-rotate-z, ) var(--tw-skew-x, ) var(--tw-skew-y, ); } .rotate-z-\\(--var\\) { --tw-rotate-z: rotateZ(var(--var)); - transform: var(--tw-rotate-x, ) var(--tw-rotate-y, ) var(--tw-rotate-z, ) var(--tw-skew-x, ) var(--tw-skew-y, ); + transform: var(--tw-rotate-x, ) var(--tw-rotate-y, ) var(--tw-rotate-z, ) var(--tw-skew-x, ) var(--tw-skew-y, ); } .rotate-z-45 { --tw-rotate-z: rotateZ(45deg); - transform: var(--tw-rotate-x, ) var(--tw-rotate-y, ) var(--tw-rotate-z, ) var(--tw-skew-x, ) var(--tw-skew-y, ); + transform: var(--tw-rotate-x, ) var(--tw-rotate-y, ) var(--tw-rotate-z, ) var(--tw-skew-x, ) var(--tw-skew-y, ); } .rotate-z-\\[123deg\\] { --tw-rotate-z: rotateZ(123deg); - transform: var(--tw-rotate-x, ) var(--tw-rotate-y, ) var(--tw-rotate-z, ) var(--tw-skew-x, ) var(--tw-skew-y, ); + transform: var(--tw-rotate-x, ) var(--tw-rotate-y, ) var(--tw-rotate-z, ) var(--tw-skew-x, ) var(--tw-skew-y, ); } @property --tw-rotate-x { @@ -5115,19 +6029,19 @@ test('skew', async () => { .-skew-6 { --tw-skew-x: skewX(calc(6deg * -1)); --tw-skew-y: skewY(calc(6deg * -1)); - transform: var(--tw-rotate-x, ) var(--tw-rotate-y, ) var(--tw-rotate-z, ) var(--tw-skew-x, ) var(--tw-skew-y, ); + transform: var(--tw-rotate-x, ) var(--tw-rotate-y, ) var(--tw-rotate-z, ) var(--tw-skew-x, ) var(--tw-skew-y, ); } .skew-6 { --tw-skew-x: skewX(6deg); --tw-skew-y: skewY(6deg); - transform: var(--tw-rotate-x, ) var(--tw-rotate-y, ) var(--tw-rotate-z, ) var(--tw-skew-x, ) var(--tw-skew-y, ); + transform: var(--tw-rotate-x, ) var(--tw-rotate-y, ) var(--tw-rotate-z, ) var(--tw-skew-x, ) var(--tw-skew-y, ); } .skew-\\[123deg\\] { --tw-skew-x: skewX(123deg); --tw-skew-y: skewY(123deg); - transform: var(--tw-rotate-x, ) var(--tw-rotate-y, ) var(--tw-rotate-z, ) var(--tw-skew-x, ) var(--tw-skew-y, ); + transform: var(--tw-rotate-x, ) var(--tw-rotate-y, ) var(--tw-rotate-z, ) var(--tw-skew-x, ) var(--tw-skew-y, ); } @property --tw-rotate-x { @@ -5183,17 +6097,17 @@ test('skew-x', async () => { .-skew-x-6 { --tw-skew-x: skewX(calc(6deg * -1)); - transform: var(--tw-rotate-x, ) var(--tw-rotate-y, ) var(--tw-rotate-z, ) var(--tw-skew-x, ) var(--tw-skew-y, ); + transform: var(--tw-rotate-x, ) var(--tw-rotate-y, ) var(--tw-rotate-z, ) var(--tw-skew-x, ) var(--tw-skew-y, ); } .skew-x-6 { --tw-skew-x: skewX(6deg); - transform: var(--tw-rotate-x, ) var(--tw-rotate-y, ) var(--tw-rotate-z, ) var(--tw-skew-x, ) var(--tw-skew-y, ); + transform: var(--tw-rotate-x, ) var(--tw-rotate-y, ) var(--tw-rotate-z, ) var(--tw-skew-x, ) var(--tw-skew-y, ); } .skew-x-\\[123deg\\] { --tw-skew-x: skewX(123deg); - transform: var(--tw-rotate-x, ) var(--tw-rotate-y, ) var(--tw-rotate-z, ) var(--tw-skew-x, ) var(--tw-skew-y, ); + transform: var(--tw-rotate-x, ) var(--tw-rotate-y, ) var(--tw-rotate-z, ) var(--tw-skew-x, ) var(--tw-skew-y, ); } @property --tw-rotate-x { @@ -5249,17 +6163,17 @@ test('skew-y', async () => { .-skew-y-6 { --tw-skew-y: skewY(calc(6deg * -1)); - transform: var(--tw-rotate-x, ) var(--tw-rotate-y, ) var(--tw-rotate-z, ) var(--tw-skew-x, ) var(--tw-skew-y, ); + transform: var(--tw-rotate-x, ) var(--tw-rotate-y, ) var(--tw-rotate-z, ) var(--tw-skew-x, ) var(--tw-skew-y, ); } .skew-y-6 { --tw-skew-y: skewY(6deg); - transform: var(--tw-rotate-x, ) var(--tw-rotate-y, ) var(--tw-rotate-z, ) var(--tw-skew-x, ) var(--tw-skew-y, ); + transform: var(--tw-rotate-x, ) var(--tw-rotate-y, ) var(--tw-rotate-z, ) var(--tw-skew-x, ) var(--tw-skew-y, ); } .skew-y-\\[123deg\\] { --tw-skew-y: skewY(123deg); - transform: var(--tw-rotate-x, ) var(--tw-rotate-y, ) var(--tw-rotate-z, ) var(--tw-skew-x, ) var(--tw-skew-y, ); + transform: var(--tw-rotate-x, ) var(--tw-rotate-y, ) var(--tw-rotate-z, ) var(--tw-skew-x, ) var(--tw-skew-y, ); } @property --tw-rotate-x { @@ -5642,7 +6556,7 @@ test('transform', async () => { } .transform { - transform: var(--tw-rotate-x, ) var(--tw-rotate-y, ) var(--tw-rotate-z, ) var(--tw-skew-x, ) var(--tw-skew-y, ); + transform: var(--tw-rotate-x, ) var(--tw-rotate-y, ) var(--tw-rotate-z, ) var(--tw-skew-x, ) var(--tw-skew-y, ); } .transform-\\[scaleZ\\(2\\)_rotateY\\(45deg\\)\\] { @@ -5650,11 +6564,11 @@ test('transform', async () => { } .transform-cpu { - transform: var(--tw-rotate-x, ) var(--tw-rotate-y, ) var(--tw-rotate-z, ) var(--tw-skew-x, ) var(--tw-skew-y, ); + transform: var(--tw-rotate-x, ) var(--tw-rotate-y, ) var(--tw-rotate-z, ) var(--tw-skew-x, ) var(--tw-skew-y, ); } .transform-gpu { - transform: translateZ(0) var(--tw-rotate-x, ) var(--tw-rotate-y, ) var(--tw-rotate-z, ) var(--tw-skew-x, ) var(--tw-skew-y, ); + transform: translateZ(0) var(--tw-rotate-x, ) var(--tw-rotate-y, ) var(--tw-rotate-z, ) var(--tw-skew-x, ) var(--tw-skew-y, ); } .transform-none { @@ -6166,32 +7080,32 @@ test('touch-pan', async () => { .touch-pan-left { --tw-pan-x: pan-left; - touch-action: var(--tw-pan-x, ) var(--tw-pan-y, ) var(--tw-pinch-zoom, ); + touch-action: var(--tw-pan-x, ) var(--tw-pan-y, ) var(--tw-pinch-zoom, ); } .touch-pan-right { --tw-pan-x: pan-right; - touch-action: var(--tw-pan-x, ) var(--tw-pan-y, ) var(--tw-pinch-zoom, ); + touch-action: var(--tw-pan-x, ) var(--tw-pan-y, ) var(--tw-pinch-zoom, ); } .touch-pan-x { --tw-pan-x: pan-x; - touch-action: var(--tw-pan-x, ) var(--tw-pan-y, ) var(--tw-pinch-zoom, ); + touch-action: var(--tw-pan-x, ) var(--tw-pan-y, ) var(--tw-pinch-zoom, ); } .touch-pan-down { --tw-pan-y: pan-down; - touch-action: var(--tw-pan-x, ) var(--tw-pan-y, ) var(--tw-pinch-zoom, ); + touch-action: var(--tw-pan-x, ) var(--tw-pan-y, ) var(--tw-pinch-zoom, ); } .touch-pan-up { --tw-pan-y: pan-up; - touch-action: var(--tw-pan-x, ) var(--tw-pan-y, ) var(--tw-pinch-zoom, ); + touch-action: var(--tw-pan-x, ) var(--tw-pan-y, ) var(--tw-pinch-zoom, ); } .touch-pan-y { --tw-pan-y: pan-y; - touch-action: var(--tw-pan-x, ) var(--tw-pan-y, ) var(--tw-pinch-zoom, ); + touch-action: var(--tw-pan-x, ) var(--tw-pan-y, ) var(--tw-pinch-zoom, ); } @property --tw-pan-x { @@ -6241,7 +7155,7 @@ test('touch-pinch-zoom', async () => { .touch-pinch-zoom { --tw-pinch-zoom: pinch-zoom; - touch-action: var(--tw-pan-x, ) var(--tw-pan-y, ) var(--tw-pinch-zoom, ); + touch-action: var(--tw-pan-x, ) var(--tw-pan-y, ) var(--tw-pinch-zoom, ); } @property --tw-pan-x { @@ -6669,6 +7583,92 @@ test('scroll-me', async () => { ).toEqual('') }) +test('scroll-mbs', async () => { + expect( + await compileCss( + css` + @theme { + --spacing-4: 1rem; + } + @tailwind utilities; + `, + ['scroll-mbs-4', 'scroll-mbs-[4px]', '-scroll-mbs-4', '-scroll-mbs-[var(--value)]'], + ), + ).toMatchInlineSnapshot(` + ":root, :host { + --spacing-4: 1rem; + } + + .-scroll-mbs-4 { + scroll-margin-block-start: calc(var(--spacing-4) * -1); + } + + .-scroll-mbs-\\[var\\(--value\\)\\] { + scroll-margin-block-start: calc(var(--value) * -1); + } + + .scroll-mbs-4 { + scroll-margin-block-start: var(--spacing-4); + } + + .scroll-mbs-\\[4px\\] { + scroll-margin-block-start: 4px; + }" + `) + expect( + await run([ + 'scroll-mbs', + 'scroll-mbs-4/foo', + 'scroll-mbs-[4px]/foo', + '-scroll-mbs-4/foo', + '-scroll-mbs-[var(--value)]/foo', + ]), + ).toEqual('') +}) + +test('scroll-mbe', async () => { + expect( + await compileCss( + css` + @theme { + --spacing-4: 1rem; + } + @tailwind utilities; + `, + ['scroll-mbe-4', 'scroll-mbe-[4px]', '-scroll-mbe-4', '-scroll-mbe-[var(--value)]'], + ), + ).toMatchInlineSnapshot(` + ":root, :host { + --spacing-4: 1rem; + } + + .-scroll-mbe-4 { + scroll-margin-block-end: calc(var(--spacing-4) * -1); + } + + .-scroll-mbe-\\[var\\(--value\\)\\] { + scroll-margin-block-end: calc(var(--value) * -1); + } + + .scroll-mbe-4 { + scroll-margin-block-end: var(--spacing-4); + } + + .scroll-mbe-\\[4px\\] { + scroll-margin-block-end: 4px; + }" + `) + expect( + await run([ + 'scroll-mbe', + 'scroll-mbe-4/foo', + 'scroll-mbe-[4px]/foo', + '-scroll-mbe-4/foo', + '-scroll-mbe-[var(--value)]/foo', + ]), + ).toEqual('') +}) + test('scroll-mt', async () => { expect( await compileCss( @@ -7016,6 +8016,76 @@ test('scroll-pe', async () => { ).toEqual('') }) +test('scroll-pbs', async () => { + expect( + await compileCss( + css` + @theme { + --spacing-4: 1rem; + } + @tailwind utilities; + `, + ['scroll-pbs-4', 'scroll-pbs-[4px]'], + ), + ).toMatchInlineSnapshot(` + ":root, :host { + --spacing-4: 1rem; + } + + .scroll-pbs-4 { + scroll-padding-block-start: var(--spacing-4); + } + + .scroll-pbs-\\[4px\\] { + scroll-padding-block-start: 4px; + }" + `) + expect( + await run([ + 'scroll-pbs', + 'scroll-pbs-4/foo', + 'scroll-pbs-[4px]/foo', + '-scroll-pbs-4', + '-scroll-pbs-[var(--value)]', + ]), + ).toEqual('') +}) + +test('scroll-pbe', async () => { + expect( + await compileCss( + css` + @theme { + --spacing-4: 1rem; + } + @tailwind utilities; + `, + ['scroll-pbe-4', 'scroll-pbe-[4px]'], + ), + ).toMatchInlineSnapshot(` + ":root, :host { + --spacing-4: 1rem; + } + + .scroll-pbe-4 { + scroll-padding-block-end: var(--spacing-4); + } + + .scroll-pbe-\\[4px\\] { + scroll-padding-block-end: 4px; + }" + `) + expect( + await run([ + 'scroll-pbe', + 'scroll-pbe-4/foo', + 'scroll-pbe-[4px]/foo', + '-scroll-pbe-4', + '-scroll-pbe-[var(--value)]', + ]), + ).toEqual('') +}) + test('scroll-pt', async () => { expect( await compileCss( @@ -11119,6 +12189,8 @@ const prefixes = [ 'border-y', 'border-s', 'border-e', + 'border-bs', + 'border-be', 'border-t', 'border-r', 'border-b', @@ -20693,6 +21765,88 @@ test('pe', async () => { expect(await run(['pe', '-pe-4', '-pe-[4px]', 'pe-4/foo', 'pe-[4px]/foo'])).toEqual('') }) +test('pbs', async () => { + expect( + await compileCss( + css` + @theme { + --spacing: 0.25rem; + --spacing-big: 100rem; + } + @tailwind utilities; + `, + ['pbs-1', 'pbs-4', 'pbs-99', 'pbs-big', 'pbs-[4px]'], + ), + ).toMatchInlineSnapshot(` + ":root, :host { + --spacing: .25rem; + --spacing-big: 100rem; + } + + .pbs-1 { + padding-block-start: calc(var(--spacing) * 1); + } + + .pbs-4 { + padding-block-start: calc(var(--spacing) * 4); + } + + .pbs-99 { + padding-block-start: calc(var(--spacing) * 99); + } + + .pbs-\\[4px\\] { + padding-block-start: 4px; + } + + .pbs-big { + padding-block-start: var(--spacing-big); + }" + `) + expect(await run(['pbs', '-pbs-4', '-pbs-[4px]', 'pbs-4/foo', 'pbs-[4px]/foo'])).toEqual('') +}) + +test('pbe', async () => { + expect( + await compileCss( + css` + @theme { + --spacing: 0.25rem; + --spacing-big: 100rem; + } + @tailwind utilities; + `, + ['pbe-1', 'pbe-4', 'pbe-99', 'pbe-big', 'pbe-[4px]'], + ), + ).toMatchInlineSnapshot(` + ":root, :host { + --spacing: .25rem; + --spacing-big: 100rem; + } + + .pbe-1 { + padding-block-end: calc(var(--spacing) * 1); + } + + .pbe-4 { + padding-block-end: calc(var(--spacing) * 4); + } + + .pbe-99 { + padding-block-end: calc(var(--spacing) * 99); + } + + .pbe-\\[4px\\] { + padding-block-end: 4px; + } + + .pbe-big { + padding-block-end: var(--spacing-big); + }" + `) + expect(await run(['pbe', '-pbe-4', '-pbe-[4px]', 'pbe-4/foo', 'pbe-[4px]/foo'])).toEqual('') +}) + test('pr', async () => { expect( await compileCss( @@ -20990,7 +22144,8 @@ test('font', async () => { } :root, :host { - --font-sans: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; + --font-sans: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", + "Segoe UI Symbol", "Noto Color Emoji"; --font-weight-bold: 650; } @@ -21069,6 +22224,41 @@ test('font', async () => { ).toEqual('') }) +test('font-features', async () => { + expect( + await run([ + 'font-features-["smcp"]', + 'font-features-["c2sc","smcp"]', + 'font-features-[var(--my-features)]', + 'font-features-(--my-features)', + ]), + ).toMatchInlineSnapshot(` + ".font-features-\\(--my-features\\) { + font-feature-settings: var(--my-features); + } + + .font-features-\\[\\"c2sc\\"\\,\\"smcp\\"\\] { + font-feature-settings: "c2sc","smcp"; + } + + .font-features-\\[\\"smcp\\"\\] { + font-feature-settings: "smcp"; + } + + .font-features-\\[var\\(--my-features\\)\\] { + font-feature-settings: var(--my-features); + }" + `) + expect( + await run([ + 'font-features', + '-font-features-["smcp"]', + 'font-features-smcp', + 'font-features-["smcp"]/foo', + ]), + ).toEqual('') +}) + test('text-transform', async () => { expect(await run(['uppercase', 'lowercase', 'capitalize', 'normal-case'])).toMatchInlineSnapshot(` ".capitalize { @@ -21853,73 +23043,73 @@ test('filter', async () => { .blur-\\[4px\\] { --tw-blur: blur(4px); - filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, ); + filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, ); } .blur-none { - --tw-blur: ; - filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, ); + --tw-blur: ; + filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, ); } .blur-xl { --tw-blur: blur(var(--blur-xl)); - filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, ); + filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, ); } .brightness-50 { --tw-brightness: brightness(50%); - filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, ); + filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, ); } .brightness-\\[1\\.23\\] { --tw-brightness: brightness(1.23); - filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, ); + filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, ); } .contrast-50 { --tw-contrast: contrast(50%); - filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, ); + filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, ); } .contrast-\\[1\\.23\\] { --tw-contrast: contrast(1.23); - filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, ); + filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, ); } .drop-shadow\\/25 { --tw-drop-shadow-alpha: 25%; --tw-drop-shadow-size: drop-shadow(0 1px 1px var(--tw-drop-shadow-color, oklab(0% 0 0 / .25))); --tw-drop-shadow: drop-shadow(var(--drop-shadow)); - filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, ); + filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, ); } .drop-shadow { --tw-drop-shadow-size: drop-shadow(0 1px 1px var(--tw-drop-shadow-color, #0000000d)); --tw-drop-shadow: drop-shadow(var(--drop-shadow)); - filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, ); + filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, ); } .drop-shadow-\\[0_0_red\\] { --tw-drop-shadow-size: drop-shadow(0 0 var(--tw-drop-shadow-color, red)); --tw-drop-shadow: var(--tw-drop-shadow-size); - filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, ); + filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, ); } .drop-shadow-multi { --tw-drop-shadow-size: drop-shadow(0 1px 1px var(--tw-drop-shadow-color, #0000000d)) drop-shadow(0 9px 7px var(--tw-drop-shadow-color, #0000001a)); --tw-drop-shadow: drop-shadow(0 1px 1px #0000000d) drop-shadow(0 9px 7px #0000001a); - filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, ); + filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, ); } .drop-shadow-xl { --tw-drop-shadow-size: drop-shadow(0 9px 7px var(--tw-drop-shadow-color, #0000001a)); --tw-drop-shadow: drop-shadow(var(--drop-shadow-xl)); - filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, ); + filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, ); } .drop-shadow-none { - --tw-drop-shadow: ; - filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, ); + --tw-drop-shadow: ; + filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, ); } .drop-shadow-inherit { @@ -21957,91 +23147,91 @@ test('filter', async () => { .grayscale { --tw-grayscale: grayscale(100%); - filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, ); + filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, ); } .grayscale-0 { --tw-grayscale: grayscale(0%); - filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, ); + filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, ); } .grayscale-\\[var\\(--value\\)\\] { --tw-grayscale: grayscale(var(--value)); - filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, ); + filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, ); } .-hue-rotate-15 { --tw-hue-rotate: hue-rotate(calc(15deg * -1)); - filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, ); + filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, ); } .-hue-rotate-\\[45deg\\] { --tw-hue-rotate: hue-rotate(calc(45deg * -1)); - filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, ); + filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, ); } .hue-rotate-15 { --tw-hue-rotate: hue-rotate(15deg); - filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, ); + filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, ); } .hue-rotate-\\[45deg\\] { --tw-hue-rotate: hue-rotate(45deg); - filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, ); + filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, ); } .invert { --tw-invert: invert(100%); - filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, ); + filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, ); } .invert-0 { --tw-invert: invert(0%); - filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, ); + filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, ); } .invert-\\[var\\(--value\\)\\] { --tw-invert: invert(var(--value)); - filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, ); + filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, ); } .saturate-0 { --tw-saturate: saturate(0%); - filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, ); + filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, ); } .saturate-\\[1\\.75\\] { --tw-saturate: saturate(1.75); - filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, ); + filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, ); } .saturate-\\[var\\(--value\\)\\] { --tw-saturate: saturate(var(--value)); - filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, ); + filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, ); } .sepia { --tw-sepia: sepia(100%); - filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, ); + filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, ); } .sepia-0 { --tw-sepia: sepia(0%); - filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, ); + filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, ); } .sepia-\\[50\\%\\] { --tw-sepia: sepia(50%); - filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, ); + filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, ); } .sepia-\\[var\\(--value\\)\\] { --tw-sepia: sepia(var(--value)); - filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, ); + filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, ); } .filter { - filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, ); + filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, ); } .filter-\\[var\\(--value\\)\\] { @@ -22234,7 +23424,7 @@ test('filter', async () => { .blur-none { --tw-blur: blur(var(--blur-none)); - filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, ); + filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, ); } @property --tw-blur { @@ -22373,187 +23563,187 @@ test('backdrop-filter', async () => { .backdrop-blur-\\[4px\\] { --tw-backdrop-blur: blur(4px); - -webkit-backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); - backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); + -webkit-backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); + backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); } .backdrop-blur-none { - --tw-backdrop-blur: ; - -webkit-backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); - backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); + --tw-backdrop-blur: ; + -webkit-backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); + backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); } .backdrop-blur-xl { --tw-backdrop-blur: blur(var(--blur-xl)); - -webkit-backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); - backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); + -webkit-backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); + backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); } .backdrop-brightness-50 { --tw-backdrop-brightness: brightness(50%); - -webkit-backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); - backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); + -webkit-backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); + backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); } .backdrop-brightness-\\[1\\.23\\] { --tw-backdrop-brightness: brightness(1.23); - -webkit-backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); - backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); + -webkit-backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); + backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); } .backdrop-contrast-50 { --tw-backdrop-contrast: contrast(50%); - -webkit-backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); - backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); + -webkit-backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); + backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); } .backdrop-contrast-\\[1\\.23\\] { --tw-backdrop-contrast: contrast(1.23); - -webkit-backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); - backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); + -webkit-backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); + backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); } .backdrop-grayscale { --tw-backdrop-grayscale: grayscale(100%); - -webkit-backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); - backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); + -webkit-backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); + backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); } .backdrop-grayscale-0 { --tw-backdrop-grayscale: grayscale(0%); - -webkit-backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); - backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); + -webkit-backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); + backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); } .backdrop-grayscale-\\[var\\(--value\\)\\] { --tw-backdrop-grayscale: grayscale(var(--value)); - -webkit-backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); - backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); + -webkit-backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); + backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); } .-backdrop-hue-rotate-15 { --tw-backdrop-hue-rotate: hue-rotate(calc(15deg * -1)); - -webkit-backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); - backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); + -webkit-backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); + backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); } .-backdrop-hue-rotate-\\[45deg\\] { --tw-backdrop-hue-rotate: hue-rotate(calc(45deg * -1)); - -webkit-backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); - backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); + -webkit-backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); + backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); } .backdrop-hue-rotate-15 { --tw-backdrop-hue-rotate: hue-rotate(15deg); - -webkit-backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); - backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); + -webkit-backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); + backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); } .backdrop-hue-rotate-\\[45deg\\] { --tw-backdrop-hue-rotate: hue-rotate(45deg); - -webkit-backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); - backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); + -webkit-backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); + backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); } .backdrop-invert { --tw-backdrop-invert: invert(100%); - -webkit-backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); - backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); + -webkit-backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); + backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); } .backdrop-invert-0 { --tw-backdrop-invert: invert(0%); - -webkit-backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); - backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); + -webkit-backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); + backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); } .backdrop-invert-\\[var\\(--value\\)\\] { --tw-backdrop-invert: invert(var(--value)); - -webkit-backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); - backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); + -webkit-backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); + backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); } .backdrop-opacity-1\\.25 { --tw-backdrop-opacity: opacity(1.25%); - -webkit-backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); - backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); + -webkit-backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); + backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); } .backdrop-opacity-2\\.5 { --tw-backdrop-opacity: opacity(2.5%); - -webkit-backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); - backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); + -webkit-backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); + backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); } .backdrop-opacity-3\\.75 { --tw-backdrop-opacity: opacity(3.75%); - -webkit-backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); - backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); + -webkit-backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); + backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); } .backdrop-opacity-50 { --tw-backdrop-opacity: opacity(50%); - -webkit-backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); - backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); + -webkit-backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); + backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); } .backdrop-opacity-71 { --tw-backdrop-opacity: opacity(71%); - -webkit-backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); - backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); + -webkit-backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); + backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); } .backdrop-opacity-\\[0\\.5\\] { --tw-backdrop-opacity: opacity(.5); - -webkit-backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); - backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); + -webkit-backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); + backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); } .backdrop-saturate-0 { --tw-backdrop-saturate: saturate(0%); - -webkit-backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); - backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); + -webkit-backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); + backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); } .backdrop-saturate-\\[1\\.75\\] { --tw-backdrop-saturate: saturate(1.75); - -webkit-backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); - backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); + -webkit-backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); + backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); } .backdrop-saturate-\\[var\\(--value\\)\\] { --tw-backdrop-saturate: saturate(var(--value)); - -webkit-backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); - backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); + -webkit-backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); + backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); } .backdrop-sepia { --tw-backdrop-sepia: sepia(100%); - -webkit-backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); - backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); + -webkit-backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); + backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); } .backdrop-sepia-0 { --tw-backdrop-sepia: sepia(0%); - -webkit-backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); - backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); + -webkit-backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); + backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); } .backdrop-sepia-\\[50\\%\\] { --tw-backdrop-sepia: sepia(50%); - -webkit-backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); - backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); + -webkit-backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); + backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); } .backdrop-sepia-\\[var\\(--value\\)\\] { --tw-backdrop-sepia: sepia(var(--value)); - -webkit-backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); - backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); + -webkit-backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); + backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); } .backdrop-filter { - -webkit-backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); - backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); + -webkit-backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); + backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); } .backdrop-filter-\\[var\\(--value\\)\\] { @@ -22717,8 +23907,8 @@ test('backdrop-filter', async () => { .backdrop-blur-none { --tw-backdrop-blur: blur(var(--backdrop-blur-none)); - -webkit-backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); - backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); + -webkit-backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); + backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, ); } @property --tw-backdrop-blur { @@ -23185,27 +24375,27 @@ test('contain', async () => { .contain-inline-size { --tw-contain-size: inline-size; - contain: var(--tw-contain-size, ) var(--tw-contain-layout, ) var(--tw-contain-paint, ) var(--tw-contain-style, ); + contain: var(--tw-contain-size, ) var(--tw-contain-layout, ) var(--tw-contain-paint, ) var(--tw-contain-style, ); } .contain-layout { --tw-contain-layout: layout; - contain: var(--tw-contain-size, ) var(--tw-contain-layout, ) var(--tw-contain-paint, ) var(--tw-contain-style, ); + contain: var(--tw-contain-size, ) var(--tw-contain-layout, ) var(--tw-contain-paint, ) var(--tw-contain-style, ); } .contain-paint { --tw-contain-paint: paint; - contain: var(--tw-contain-size, ) var(--tw-contain-layout, ) var(--tw-contain-paint, ) var(--tw-contain-style, ); + contain: var(--tw-contain-size, ) var(--tw-contain-layout, ) var(--tw-contain-paint, ) var(--tw-contain-style, ); } .contain-size { --tw-contain-size: size; - contain: var(--tw-contain-size, ) var(--tw-contain-layout, ) var(--tw-contain-paint, ) var(--tw-contain-style, ); + contain: var(--tw-contain-size, ) var(--tw-contain-layout, ) var(--tw-contain-paint, ) var(--tw-contain-style, ); } .contain-style { --tw-contain-style: style; - contain: var(--tw-contain-size, ) var(--tw-contain-layout, ) var(--tw-contain-paint, ) var(--tw-contain-style, ); + contain: var(--tw-contain-size, ) var(--tw-contain-layout, ) var(--tw-contain-paint, ) var(--tw-contain-style, ); } .contain-\\[unset\\] { @@ -23533,42 +24723,42 @@ test('font-variant-numeric', async () => { .diagonal-fractions { --tw-numeric-fraction: diagonal-fractions; - font-variant-numeric: var(--tw-ordinal, ) var(--tw-slashed-zero, ) var(--tw-numeric-figure, ) var(--tw-numeric-spacing, ) var(--tw-numeric-fraction, ); + font-variant-numeric: var(--tw-ordinal, ) var(--tw-slashed-zero, ) var(--tw-numeric-figure, ) var(--tw-numeric-spacing, ) var(--tw-numeric-fraction, ); } .lining-nums { --tw-numeric-figure: lining-nums; - font-variant-numeric: var(--tw-ordinal, ) var(--tw-slashed-zero, ) var(--tw-numeric-figure, ) var(--tw-numeric-spacing, ) var(--tw-numeric-fraction, ); + font-variant-numeric: var(--tw-ordinal, ) var(--tw-slashed-zero, ) var(--tw-numeric-figure, ) var(--tw-numeric-spacing, ) var(--tw-numeric-fraction, ); } .oldstyle-nums { --tw-numeric-figure: oldstyle-nums; - font-variant-numeric: var(--tw-ordinal, ) var(--tw-slashed-zero, ) var(--tw-numeric-figure, ) var(--tw-numeric-spacing, ) var(--tw-numeric-fraction, ); + font-variant-numeric: var(--tw-ordinal, ) var(--tw-slashed-zero, ) var(--tw-numeric-figure, ) var(--tw-numeric-spacing, ) var(--tw-numeric-fraction, ); } .ordinal { --tw-ordinal: ordinal; - font-variant-numeric: var(--tw-ordinal, ) var(--tw-slashed-zero, ) var(--tw-numeric-figure, ) var(--tw-numeric-spacing, ) var(--tw-numeric-fraction, ); + font-variant-numeric: var(--tw-ordinal, ) var(--tw-slashed-zero, ) var(--tw-numeric-figure, ) var(--tw-numeric-spacing, ) var(--tw-numeric-fraction, ); } .proportional-nums { --tw-numeric-spacing: proportional-nums; - font-variant-numeric: var(--tw-ordinal, ) var(--tw-slashed-zero, ) var(--tw-numeric-figure, ) var(--tw-numeric-spacing, ) var(--tw-numeric-fraction, ); + font-variant-numeric: var(--tw-ordinal, ) var(--tw-slashed-zero, ) var(--tw-numeric-figure, ) var(--tw-numeric-spacing, ) var(--tw-numeric-fraction, ); } .slashed-zero { --tw-slashed-zero: slashed-zero; - font-variant-numeric: var(--tw-ordinal, ) var(--tw-slashed-zero, ) var(--tw-numeric-figure, ) var(--tw-numeric-spacing, ) var(--tw-numeric-fraction, ); + font-variant-numeric: var(--tw-ordinal, ) var(--tw-slashed-zero, ) var(--tw-numeric-figure, ) var(--tw-numeric-spacing, ) var(--tw-numeric-fraction, ); } .stacked-fractions { --tw-numeric-fraction: stacked-fractions; - font-variant-numeric: var(--tw-ordinal, ) var(--tw-slashed-zero, ) var(--tw-numeric-figure, ) var(--tw-numeric-spacing, ) var(--tw-numeric-fraction, ); + font-variant-numeric: var(--tw-ordinal, ) var(--tw-slashed-zero, ) var(--tw-numeric-figure, ) var(--tw-numeric-spacing, ) var(--tw-numeric-fraction, ); } .tabular-nums { --tw-numeric-spacing: tabular-nums; - font-variant-numeric: var(--tw-ordinal, ) var(--tw-slashed-zero, ) var(--tw-numeric-figure, ) var(--tw-numeric-spacing, ) var(--tw-numeric-fraction, ); + font-variant-numeric: var(--tw-ordinal, ) var(--tw-slashed-zero, ) var(--tw-numeric-figure, ) var(--tw-numeric-spacing, ) var(--tw-numeric-fraction, ); } .normal-nums { @@ -25940,37 +27130,37 @@ test('ring', async () => { } .ring { - --tw-ring-shadow: var(--tw-ring-inset, ) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor); + --tw-ring-shadow: var(--tw-ring-inset, ) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor); box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); } .ring-0 { - --tw-ring-shadow: var(--tw-ring-inset, ) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor); + --tw-ring-shadow: var(--tw-ring-inset, ) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor); box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); } .ring-1 { - --tw-ring-shadow: var(--tw-ring-inset, ) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor); + --tw-ring-shadow: var(--tw-ring-inset, ) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor); box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); } .ring-2 { - --tw-ring-shadow: var(--tw-ring-inset, ) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor); + --tw-ring-shadow: var(--tw-ring-inset, ) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor); box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); } .ring-4 { - --tw-ring-shadow: var(--tw-ring-inset, ) 0 0 0 calc(4px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor); + --tw-ring-shadow: var(--tw-ring-inset, ) 0 0 0 calc(4px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor); box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); } .ring-\\[12px\\] { - --tw-ring-shadow: var(--tw-ring-inset, ) 0 0 0 calc(12px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor); + --tw-ring-shadow: var(--tw-ring-inset, ) 0 0 0 calc(12px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor); box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); } .ring-\\[length\\:var\\(--my-width\\)\\] { - --tw-ring-shadow: var(--tw-ring-inset, ) 0 0 0 calc(var(--my-width) + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor); + --tw-ring-shadow: var(--tw-ring-inset, ) 0 0 0 calc(var(--my-width) + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor); box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); } @@ -26264,7 +27454,7 @@ test('ring', async () => { } .ring { - --tw-ring-shadow: var(--tw-ring-inset, ) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor); + --tw-ring-shadow: var(--tw-ring-inset, ) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor); box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); } @@ -26834,32 +28024,32 @@ test('ring-offset', async () => { .ring-offset-0 { --tw-ring-offset-width: 0px; - --tw-ring-offset-shadow: var(--tw-ring-inset, ) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-offset-shadow: var(--tw-ring-inset, ) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); } .ring-offset-1 { --tw-ring-offset-width: 1px; - --tw-ring-offset-shadow: var(--tw-ring-inset, ) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-offset-shadow: var(--tw-ring-inset, ) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); } .ring-offset-2 { --tw-ring-offset-width: 2px; - --tw-ring-offset-shadow: var(--tw-ring-inset, ) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-offset-shadow: var(--tw-ring-inset, ) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); } .ring-offset-4 { --tw-ring-offset-width: 4px; - --tw-ring-offset-shadow: var(--tw-ring-inset, ) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-offset-shadow: var(--tw-ring-inset, ) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); } .ring-offset-\\[12px\\] { --tw-ring-offset-width: 12px; - --tw-ring-offset-shadow: var(--tw-ring-inset, ) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-offset-shadow: var(--tw-ring-inset, ) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); } .ring-offset-\\[length\\:var\\(--my-width\\)\\] { --tw-ring-offset-width: var(--my-width); - --tw-ring-offset-shadow: var(--tw-ring-inset, ) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-offset-shadow: var(--tw-ring-inset, ) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); } .ring-offset-\\[\\#0088cc\\] { @@ -27238,7 +28428,7 @@ describe('custom utilities', () => { test.each([ ['foo', false], // Simple name, missing '-*' suffix ['foo-*', true], // Simple name - ['foo--*', false], // Root should not end in `-` + ['foo--*', true], // Root ending in `-` is valid (e.g. `border--*`) ['-foo-*', true], // Simple name (negative) ['foo-bar-*', true], // With dashes ['foo_bar-*', true], // With underscores @@ -27415,7 +28605,7 @@ describe('custom utilities', () => { .text-sm { font-size: var(--text-sm, .8755rem); line-height: var(--text-sm--line-height, 1.255rem); - text-rendering: optimizeLegibility; + text-rendering: optimizelegibility; font-size: var(--text-sm, .875rem); line-height: var(--tw-leading, var(--text-sm--line-height, 1.25rem)); } @@ -27710,6 +28900,38 @@ describe('custom utilities', () => { expect(await compileCss(input, ['tab-3', 'tab-gitlab'])).toEqual('') }) + test('functional utility with double-dash separator', async () => { + let input = css` + @theme reference { + --color-border-0: #e5e7eb; + --color-border-1: #d1d5db; + --color-border-2: #9ca3af; + } + + @utility border--* { + border-color: --value(--color-border-*, [color]); + } + + @tailwind utilities; + ` + + expect(await compileCss(input, ['border--0', 'border--1', 'border--2'])) + .toMatchInlineSnapshot(` + ".border--0 { + border-color: var(--color-border-0, #e5e7eb); + } + + .border--1 { + border-color: var(--color-border-1, #d1d5db); + } + + .border--2 { + border-color: var(--color-border-2, #9ca3af); + }" + `) + expect(await compileCss(input, ['border--3'])).toEqual('') + }) + test('resolving values from `@theme`, with `--tab-size-*` syntax', async () => { let input = // Explicitly not using the css tagged template literal so that @@ -28398,7 +29620,7 @@ describe('custom utilities', () => { } .example-\\[7\\/9\\] { - --value: 7 / 9; + --value: 7/9; } .example-video { diff --git a/packages/tailwindcss/src/utilities.ts b/packages/tailwindcss/src/utilities.ts index e1c84ce00890..aa2187887405 100644 --- a/packages/tailwindcss/src/utilities.ts +++ b/packages/tailwindcss/src/utilities.ts @@ -16,6 +16,7 @@ import { enableContainerSizeUtility } from './feature-flags' import type { Theme, ThemeKey } from './theme' import { compareBreakpoints } from './utils/compare-breakpoints' import { DefaultMap } from './utils/default-map' +import { unescape } from './utils/escape' import { inferDataType, isPositiveInteger, @@ -421,7 +422,7 @@ export function createUtilities(theme: Theme) { if (value === null && desc.supportsFractions && candidate.value.fraction) { let [lhs, rhs] = segment(candidate.value.fraction, '/') if (!isPositiveInteger(lhs) || !isPositiveInteger(rhs)) return - value = `calc(${candidate.value.fraction} * 100%)` + value = `calc(${lhs} / ${rhs} * 100%)` } // If there is still no value but the utility supports bare values, @@ -624,8 +625,10 @@ export function createUtilities(theme: Theme) { ['inset', 'inset'], ['inset-x', 'inset-inline'], ['inset-y', 'inset-block'], - ['start', 'inset-inline-start'], - ['end', 'inset-inline-end'], + ['inset-s', 'inset-inline-start'], + ['inset-e', 'inset-inline-end'], + ['inset-bs', 'inset-block-start'], + ['inset-be', 'inset-block-end'], ['top', 'top'], ['right', 'right'], ['bottom', 'bottom'], @@ -888,6 +891,8 @@ export function createUtilities(theme: Theme) { ['my', 'margin-block'], ['ms', 'margin-inline-start'], ['me', 'margin-inline-end'], + ['mbs', 'margin-block-start'], + ['mbe', 'margin-block-end'], ['mt', 'margin-top'], ['mr', 'margin-right'], ['mb', 'margin-bottom'], @@ -977,7 +982,7 @@ export function createUtilities(theme: Theme) { handleBareValue: ({ fraction }) => { if (fraction === null) return null let [lhs, rhs] = segment(fraction, '/') - if (!isPositiveInteger(lhs) || !isPositiveInteger(rhs)) return null + if (!isValidSpacingMultiplier(lhs) || !isValidSpacingMultiplier(rhs)) return null return fraction }, handle: (value) => [decl('aspect-ratio', value)], @@ -1067,6 +1072,82 @@ export function createUtilities(theme: Theme) { }) } + /** + * @css `inline-size` + * @css `min-inline-size` + * @css `max-inline-size` + * @css `block-size` + * @css `min-block-size` + * @css `max-block-size` + */ + for (let [key, value] of [ + ['full', '100%'], + ['min', 'min-content'], + ['max', 'max-content'], + ['fit', 'fit-content'], + ]) { + staticUtility(`inline-${key}`, [['inline-size', value]]) + staticUtility(`block-${key}`, [['block-size', value]]) + staticUtility(`min-inline-${key}`, [['min-inline-size', value]]) + staticUtility(`min-block-${key}`, [['min-block-size', value]]) + staticUtility(`max-inline-${key}`, [['max-inline-size', value]]) + staticUtility(`max-block-${key}`, [['max-block-size', value]]) + } + + // inline-size viewport units (like width) + for (let [key, value] of [ + ['svw', '100svw'], + ['lvw', '100lvw'], + ['dvw', '100dvw'], + ]) { + staticUtility(`inline-${key}`, [['inline-size', value]]) + staticUtility(`min-inline-${key}`, [['min-inline-size', value]]) + staticUtility(`max-inline-${key}`, [['max-inline-size', value]]) + } + + // block-size viewport units (like height) + for (let [key, value] of [ + ['svh', '100svh'], + ['lvh', '100lvh'], + ['dvh', '100dvh'], + ]) { + staticUtility(`block-${key}`, [['block-size', value]]) + staticUtility(`min-block-${key}`, [['min-block-size', value]]) + staticUtility(`max-block-${key}`, [['max-block-size', value]]) + } + + staticUtility(`inline-auto`, [['inline-size', 'auto']]) + staticUtility(`block-auto`, [['block-size', 'auto']]) + staticUtility(`min-inline-auto`, [['min-inline-size', 'auto']]) + staticUtility(`min-block-auto`, [['min-block-size', 'auto']]) + + staticUtility(`block-lh`, [['block-size', '1lh']]) + staticUtility(`min-block-lh`, [['min-block-size', '1lh']]) + staticUtility(`max-block-lh`, [['max-block-size', '1lh']]) + + staticUtility(`inline-screen`, [['inline-size', '100vw']]) + staticUtility(`min-inline-screen`, [['min-inline-size', '100vw']]) + staticUtility(`max-inline-screen`, [['max-inline-size', '100vw']]) + staticUtility(`block-screen`, [['block-size', '100vh']]) + staticUtility(`min-block-screen`, [['min-block-size', '100vh']]) + staticUtility(`max-block-screen`, [['max-block-size', '100vh']]) + + staticUtility(`max-inline-none`, [['max-inline-size', 'none']]) + staticUtility(`max-block-none`, [['max-block-size', 'none']]) + + for (let [name, namespaces, property] of [ + ['inline', ['--spacing', '--container'], 'inline-size'], + ['min-inline', ['--spacing', '--container'], 'min-inline-size'], + ['max-inline', ['--spacing', '--container'], 'max-inline-size'], + ['block', ['--spacing'], 'block-size'], + ['min-block', ['--spacing'], 'min-block-size'], + ['max-block', ['--spacing'], 'max-block-size'], + ] as [string, ThemeKey[], string][]) { + spacingUtility(name, namespaces, (value) => [decl(property, value)], { + supportsFractions: true, + }) + } + utilities.static('container', () => { let breakpoints = [...theme.namespace('--breakpoint').values()] breakpoints.sort((a, z) => compareBreakpoints(a, z, 'asc')) @@ -1774,6 +1855,8 @@ export function createUtilities(theme: Theme) { ['scroll-my', 'scroll-margin-block'], ['scroll-ms', 'scroll-margin-inline-start'], ['scroll-me', 'scroll-margin-inline-end'], + ['scroll-mbs', 'scroll-margin-block-start'], + ['scroll-mbe', 'scroll-margin-block-end'], ['scroll-mt', 'scroll-margin-top'], ['scroll-mr', 'scroll-margin-right'], ['scroll-mb', 'scroll-margin-bottom'], @@ -1798,6 +1881,8 @@ export function createUtilities(theme: Theme) { ['scroll-py', 'scroll-padding-block'], ['scroll-ps', 'scroll-padding-inline-start'], ['scroll-pe', 'scroll-padding-inline-end'], + ['scroll-pbs', 'scroll-padding-block-start'], + ['scroll-pbe', 'scroll-padding-block-end'], ['scroll-pt', 'scroll-padding-top'], ['scroll-pr', 'scroll-padding-right'], ['scroll-pb', 'scroll-padding-bottom'], @@ -2344,6 +2429,22 @@ export function createUtilities(theme: Theme) { color: (value) => [decl('border-inline-end-color', value)], }) + borderSideUtility('border-bs', { + width: (value) => [ + decl('border-block-start-style', 'var(--tw-border-style)'), + decl('border-block-start-width', value), + ], + color: (value) => [decl('border-block-start-color', value)], + }) + + borderSideUtility('border-be', { + width: (value) => [ + decl('border-block-end-style', 'var(--tw-border-style)'), + decl('border-block-end-width', value), + ], + color: (value) => [decl('border-block-end-color', value)], + }) + borderSideUtility('border-t', { width: (value) => [ decl('border-top-style', 'var(--tw-border-style)'), @@ -3706,6 +3807,8 @@ export function createUtilities(theme: Theme) { ['py', 'padding-block'], ['ps', 'padding-inline-start'], ['pe', 'padding-inline-end'], + ['pbs', 'padding-block-start'], + ['pbe', 'padding-block-end'], ['pt', 'padding-top'], ['pr', 'padding-right'], ['pb', 'padding-bottom'], @@ -3807,6 +3910,14 @@ export function createUtilities(theme: Theme) { }, ]) + /** + * @css `font-feature-settings` + */ + functionalUtility('font-features', { + themeKeys: [], + handle: (value) => [decl('font-feature-settings', value)], + }) + staticUtility('uppercase', [['text-transform', 'uppercase']]) staticUtility('lowercase', [['text-transform', 'lowercase']]) staticUtility('capitalize', [['text-transform', 'capitalize']]) @@ -5497,7 +5608,7 @@ export function createUtilities(theme: Theme) { value, alpha, (color) => `var(--tw-inset-shadow-color, ${color})`, - 'inset ', + 'inset', ), decl('box-shadow', cssBoxShadowValue), ] @@ -5829,7 +5940,11 @@ export const BARE_VALUE_DATA_TYPES = [ ] export function createCssUtility(node: AtRule) { - let name = node.params + // Allow escaped characters in the name for compatibility with formatters and + // other parsers, to ensure valid CSS syntax. E.g.: `@utility foo-1\/2`. + // + // Note: the actual utility will be `foo-1/2` + let name = unescape(node.params) // Functional utilities. E.g.: `tab-size-*` if (isValidFunctionalUtilityName(name)) { @@ -6267,7 +6382,7 @@ function resolveValueFunction( // Ratio must be a valid fraction, e.g.: / if (type === 'ratio') { - let [lhs, rhs] = segment(resolved, '/') + let [lhs, rhs] = segment(resolved, '/').map(Number) if (!isPositiveInteger(lhs) || !isPositiveInteger(rhs)) continue } @@ -6282,7 +6397,12 @@ function resolveValueFunction( continue } - return { nodes: ValueParser.parse(resolved), ratio: type === 'ratio' } + if (type === 'ratio') { + let [lhs, rhs] = segment(resolved, '/') + return { nodes: ValueParser.parse(`${lhs.trim()} / ${rhs.trim()}`), ratio: true } + } + + return { nodes: ValueParser.parse(resolved), ratio: false } } // Arbitrary value, e.g.: `--value([integer])` @@ -6361,8 +6481,8 @@ function alphaReplacedShadowProperties( function applyPrefix(x: string) { if (!prefix) return x return segment(x, ',') - .map((value) => prefix + value) - .join(',') + .map((value) => prefix.trim() + ' ' + value.trim()) + .join(', ') } if (requiresFallback) { @@ -6539,22 +6659,21 @@ export function isValidFunctionalUtilityName(name: string): boolean { let root = match[0] let value = name.slice(root.length) - // Root should not end in `-` if there is no value - // - // `tab-size--*` - // --------- Root - // -- Suffix - // - // Because with default values, this could match `tab-size-` which is invalid. - if (value.length === 0 && root.endsWith('-')) { - return false - } - // No remaining value is valid // // `tab-size-*` // -------- Root // -- Suffix + // + // Backwards compatibility: a root ending in `-` was valid and correctly + // scanned by Oxide. This means that custom utilities can result in candidates + // such as `foo--bar`. + // + // We might want to revisit this for Tailwind CSS v5, but for now we have to + // make it backwards compatible. + // + // PR: https://github.com/tailwindlabs/tailwindcss/pull/19696 + // if (value.length === 0) { return true } diff --git a/packages/tailwindcss/src/variants.ts b/packages/tailwindcss/src/variants.ts index 82a2b8592cfe..0b4bcb0c578c 100644 --- a/packages/tailwindcss/src/variants.ts +++ b/packages/tailwindcss/src/variants.ts @@ -1196,7 +1196,7 @@ export function substituteAtSlot(ast: AstNode[], nodes: AstNode[]) { walk(ast, (node) => { // Replace `@slot` with rule nodes if (node.kind === 'at-rule' && node.name === '@slot') { - return WalkAction.Replace(nodes) + return WalkAction.ReplaceSkip(nodes) } // Wrap `@keyframes` and `@property` in `AtRoot` nodes diff --git a/packages/tailwindcss/src/walk.ts b/packages/tailwindcss/src/walk.ts index ccb384256c3f..97c30db90be1 100644 --- a/packages/tailwindcss/src/walk.ts +++ b/packages/tailwindcss/src/walk.ts @@ -52,42 +52,53 @@ export function walk( else walkImplementation(ast, hooks.enter, hooks.exit) } +interface Stack { + value: T + prev: Stack | null +} + function walkImplementation( ast: T[], enter: (node: T, ctx: VisitContext) => EnterResult | void = () => WalkAction.Continue, exit: (node: T, ctx: VisitContext) => ExitResult | void = () => WalkAction.Continue, ) { - let stack: [nodes: T[], offset: number, parent: Parent | null][] = [[ast, 0, null]] + type StackFrame = [nodes: T[], offset: number, parent: Parent | null] + let stack: Stack | null = { value: [ast, 0, null], prev: null } + let ctx: VisitContext = { parent: null, depth: 0, path() { let path: T[] = [] - for (let i = 1; i < stack.length; i++) { - let parent = stack[i][2] + let frames: Stack | null = stack + + while (frames) { + let parent = frames.value[2] if (parent) path.push(parent) + frames = frames.prev } + path.reverse() + return path }, } - while (stack.length > 0) { - let depth = stack.length - 1 - let frame = stack[depth] + while (stack !== null) { + let frame = stack.value let nodes = frame[0] let offset = frame[1] let parent = frame[2] // Done with this level if (offset >= nodes.length) { - stack.pop() + stack = stack.prev + ctx.depth -= 1 continue } ctx.parent = parent - ctx.depth = depth // Enter phase (offsets are positive) if (offset >= 0) { @@ -97,7 +108,11 @@ function walkImplementation( switch (result.kind) { case WalkKind.Continue: { if (node.nodes && node.nodes.length > 0) { - stack.push([node.nodes, 0, node as Parent]) + ctx.depth += 1 + stack = { + value: [node.nodes, 0, node as Parent], + prev: stack, + } } frame[1] = ~offset // Prepare for exit phase, same offset diff --git a/packages/tailwindcss/tests/ui.spec.ts b/packages/tailwindcss/tests/ui.spec.ts index 0c3534efd748..889848c5cb68 100644 --- a/packages/tailwindcss/tests/ui.spec.ts +++ b/packages/tailwindcss/tests/ui.spec.ts @@ -1911,7 +1911,7 @@ test('outline style is optional', async ({ page }) => { html`
`, ) - expect(await getPropertyValue('#x', 'outline')).toEqual('rgb(255, 255, 255) solid 2px') + expect(await getPropertyValue('#x', 'outline')).toEqual('2px solid rgb(255, 255, 255)') }) test('outline style is preserved when changing outline width', async ({ page }) => { @@ -1922,11 +1922,11 @@ test('outline style is preserved when changing outline width', async ({ page }) `, ) - expect(await getPropertyValue('#x', 'outline')).toEqual('rgb(255, 255, 255) dotted 2px') + expect(await getPropertyValue('#x', 'outline')).toEqual('2px dotted rgb(255, 255, 255)') await page.locator('#x').hover() - expect(await getPropertyValue('#x', 'outline')).toEqual('rgb(255, 255, 255) dotted 4px') + expect(await getPropertyValue('#x', 'outline')).toEqual('4px dotted rgb(255, 255, 255)') }) test('borders can be added without a border-style utility', async ({ page }) => { @@ -2249,7 +2249,7 @@ async function getPropertyValue( selector: [string, string | undefined], property: string, ) { - return page.evaluate( + let value = await page.evaluate( ([[selector, pseudo], property]) => { return window .getComputedStyle(document.querySelector(selector)!, pseudo) @@ -2257,4 +2257,16 @@ async function getPropertyValue( }, [selector, property] as const, ) + + switch (property) { + case 'outline': + // Order in webkit vs chromium is different. Sort to normalize. + return segment(value, ' ') + .map((part) => part.trim()) + .sort((a, z) => a.length - z.length) + .join(' ') + + default: + return value + } } diff --git a/packages/tailwindcss/theme.css b/packages/tailwindcss/theme.css index 52d447f7ffa0..502f5c752293 100644 --- a/packages/tailwindcss/theme.css +++ b/packages/tailwindcss/theme.css @@ -271,6 +271,54 @@ --color-stone-900: oklch(21.6% 0.006 56.043); --color-stone-950: oklch(14.7% 0.004 49.25); + --color-mauve-50: oklch(98.5% 0 0); + --color-mauve-100: oklch(96% 0.003 325.6); + --color-mauve-200: oklch(92.2% 0.005 325.62); + --color-mauve-300: oklch(86.5% 0.012 325.68); + --color-mauve-400: oklch(71.1% 0.019 323.02); + --color-mauve-500: oklch(54.2% 0.034 322.5); + --color-mauve-600: oklch(43.5% 0.029 321.78); + --color-mauve-700: oklch(36.4% 0.029 323.89); + --color-mauve-800: oklch(26.3% 0.024 320.12); + --color-mauve-900: oklch(21.2% 0.019 322.12); + --color-mauve-950: oklch(14.5% 0.008 326); + + --color-olive-50: oklch(98.8% 0.003 106.5); + --color-olive-100: oklch(96.6% 0.005 106.5); + --color-olive-200: oklch(93% 0.007 106.5); + --color-olive-300: oklch(88% 0.011 106.6); + --color-olive-400: oklch(73.7% 0.021 106.9); + --color-olive-500: oklch(58% 0.031 107.3); + --color-olive-600: oklch(46.6% 0.025 107.3); + --color-olive-700: oklch(39.4% 0.023 107.4); + --color-olive-800: oklch(28.6% 0.016 107.4); + --color-olive-900: oklch(22.8% 0.013 107.4); + --color-olive-950: oklch(15.3% 0.006 107.1); + + --color-mist-50: oklch(98.7% 0.002 197.1); + --color-mist-100: oklch(96.3% 0.002 197.1); + --color-mist-200: oklch(92.5% 0.005 214.3); + --color-mist-300: oklch(87.2% 0.007 219.6); + --color-mist-400: oklch(72.3% 0.014 214.4); + --color-mist-500: oklch(56% 0.021 213.5); + --color-mist-600: oklch(45% 0.017 213.2); + --color-mist-700: oklch(37.8% 0.015 216); + --color-mist-800: oklch(27.5% 0.011 216.9); + --color-mist-900: oklch(21.8% 0.008 223.9); + --color-mist-950: oklch(14.8% 0.004 228.8); + + --color-taupe-50: oklch(98.6% 0.002 67.8); + --color-taupe-100: oklch(96% 0.002 17.2); + --color-taupe-200: oklch(92.2% 0.005 34.3); + --color-taupe-300: oklch(86.8% 0.007 39.5); + --color-taupe-400: oklch(71.4% 0.014 41.2); + --color-taupe-500: oklch(54.7% 0.021 43.1); + --color-taupe-600: oklch(43.8% 0.017 39.3); + --color-taupe-700: oklch(36.7% 0.016 35.7); + --color-taupe-800: oklch(26.8% 0.011 36.5); + --color-taupe-900: oklch(21.4% 0.009 43.1); + --color-taupe-950: oklch(14.7% 0.004 49.3); + --color-black: #000; --color-white: #fff; diff --git a/patches/lightningcss@1.30.2.patch b/patches/lightningcss@1.31.1.patch similarity index 100% rename from patches/lightningcss@1.30.2.patch rename to patches/lightningcss@1.31.1.patch diff --git a/playgrounds/nextjs/package.json b/playgrounds/nextjs/package.json index 8dc97a047be5..4e56fd3092e1 100644 --- a/playgrounds/nextjs/package.json +++ b/playgrounds/nextjs/package.json @@ -11,17 +11,17 @@ "dependencies": { "@tailwindcss/postcss": "workspace:^", "fast-glob": "^3.3.3", - "next": "^16.1.0", - "react": "^19.2.3", - "react-dom": "^19.2.3", + "next": "^16.1.6", + "react": "^19.2.4", + "react-dom": "^19.2.4", "tailwindcss": "workspace:^" }, "devDependencies": { "@types/node": "catalog:", - "@types/react": "^19.2.7", + "@types/react": "^19.2.14", "@types/react-dom": "^19.2.3", "eslint": "^9.39.2", - "eslint-config-next": "^16.1.0", - "typescript": "^5.5.4" + "eslint-config-next": "^16.1.6", + "typescript": "^5.9.3" } } diff --git a/playgrounds/v3/package.json b/playgrounds/v3/package.json index c03663b698b8..15449f6405bd 100644 --- a/playgrounds/v3/package.json +++ b/playgrounds/v3/package.json @@ -9,18 +9,18 @@ "upgrade": "node scripts/upgrade.mjs" }, "dependencies": { - "next": "^16.1.0", - "react": "^19.2.3", - "react-dom": "^19.2.3", + "next": "^16.1.6", + "react": "^19.2.4", + "react-dom": "^19.2.4", "tailwindcss": "^3" }, "devDependencies": { - "@types/node": "^20.14.8", - "@types/react": "^19.2.7", + "@types/node": "catalog:", + "@types/react": "^19.2.14", "@types/react-dom": "^19.2.3", - "autoprefixer": "^10.4.23", + "autoprefixer": "^10.4.24", "eslint": "^9.39.2", - "eslint-config-next": "^16.1.0", - "typescript": "^5.5.4" + "eslint-config-next": "^16.1.6", + "typescript": "^5.9.3" } } diff --git a/playgrounds/vite/package.json b/playgrounds/vite/package.json index e158445cb765..1a7c0b74573e 100644 --- a/playgrounds/vite/package.json +++ b/playgrounds/vite/package.json @@ -10,15 +10,15 @@ }, "dependencies": { "@tailwindcss/vite": "workspace:^", - "@vitejs/plugin-react": "^5.1.2", - "react": "^19.2.3", - "react-dom": "^19.2.3", + "@vitejs/plugin-react": "^5.1.3", + "react": "^19.2.4", + "react-dom": "^19.2.4", "tailwindcss": "workspace:^" }, "devDependencies": { - "@types/react": "^19.2.7", + "@types/react": "^19.2.14", "@types/react-dom": "^19.2.3", - "bun": "^1.3.5", + "bun": "^1.3.9", "vite": "catalog:" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d32bc3c6495f..4ce5acce01ed 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -10,51 +10,54 @@ catalogs: specifier: ^20.19.0 version: 20.19.1 lightningcss: - specifier: 1.30.2 - version: 1.30.2 + specifier: 1.31.1 + version: 1.31.1 lightningcss-darwin-arm64: - specifier: 1.30.2 - version: 1.30.2 + specifier: 1.31.1 + version: 1.31.1 lightningcss-darwin-x64: - specifier: 1.30.2 - version: 1.30.2 + specifier: 1.31.1 + version: 1.31.1 lightningcss-linux-arm64-gnu: - specifier: 1.30.2 - version: 1.30.2 + specifier: 1.31.1 + version: 1.31.1 lightningcss-linux-arm64-musl: - specifier: 1.30.2 - version: 1.30.2 + specifier: 1.31.1 + version: 1.31.1 lightningcss-linux-x64-gnu: - specifier: 1.30.2 - version: 1.30.2 + specifier: 1.31.1 + version: 1.31.1 lightningcss-linux-x64-musl: - specifier: 1.30.2 - version: 1.30.2 + specifier: 1.31.1 + version: 1.31.1 lightningcss-win32-x64-msvc: - specifier: 1.30.2 - version: 1.30.2 + specifier: 1.31.1 + version: 1.31.1 prettier: - specifier: 3.6.2 - version: 3.6.2 + specifier: 3.8.1 + version: 3.8.1 vite: - specifier: ^7.0.0 - version: 7.0.0 + specifier: ^7.3.1 + version: 7.3.1 + webpack: + specifier: ^5 + version: 5.104.1 patchedDependencies: '@parcel/watcher@2.5.1': hash: zs2vvlrje3h42xp5ed2v44fep4 path: patches/@parcel__watcher@2.5.1.patch - lightningcss@1.30.2: + lightningcss@1.31.1: hash: tzyxy3asfxcqc7ihrooumyi5fm - path: patches/lightningcss@1.30.2.patch + path: patches/lightningcss@1.31.1.patch importers: .: devDependencies: '@playwright/test': - specifier: ^1.57.0 - version: 1.57.0 + specifier: ^1.58.0 + version: 1.58.0 '@types/node': specifier: 'catalog:' version: 20.19.1 @@ -66,25 +69,25 @@ importers: version: 16.1.1(postcss@8.5.6) prettier: specifier: 'catalog:' - version: 3.6.2 + version: 3.8.1 prettier-plugin-embed: specifier: ^0.5.1 version: 0.5.1 prettier-plugin-organize-imports: specifier: ^4.3.0 - version: 4.3.0(prettier@3.6.2)(typescript@5.5.4) + version: 4.3.0(prettier@3.8.1)(typescript@5.5.4) tsup: specifier: ^8.5.1 version: 8.5.1(jiti@2.6.1)(postcss@8.5.6)(tsx@4.19.1)(typescript@5.5.4)(yaml@2.6.0) turbo: - specifier: ^2.7.2 - version: 2.7.2 + specifier: ^2.7.6 + version: 2.7.6 typescript: specifier: ^5.5.4 version: 5.5.4 vitest: - specifier: ^4.0.3 - version: 4.0.12(@types/node@20.19.1)(jiti@2.6.1)(lightningcss@1.30.2(patch_hash=tzyxy3asfxcqc7ihrooumyi5fm))(terser@5.31.6)(tsx@4.19.1)(yaml@2.6.0) + specifier: ^4.0.18 + version: 4.0.18(@types/node@20.19.1)(jiti@2.6.1)(lightningcss@1.31.1(patch_hash=tzyxy3asfxcqc7ihrooumyi5fm))(terser@5.31.6)(tsx@4.19.1)(yaml@2.6.0) crates/node: optionalDependencies: @@ -127,13 +130,13 @@ importers: devDependencies: '@napi-rs/cli': specifier: 3.4.1 - version: 3.4.1(@emnapi/runtime@1.7.1)(@types/node@20.19.1)(node-addon-api@8.3.0) + version: 3.4.1(@emnapi/runtime@1.8.1)(@types/node@20.19.1)(node-addon-api@8.3.0) '@napi-rs/wasm-runtime': specifier: ^1.1.1 version: 1.1.1 emnapi: - specifier: 1.7.1 - version: 1.7.1(node-addon-api@8.3.0) + specifier: 1.8.1 + version: 1.8.1(node-addon-api@8.3.0) crates/node/npm/android-arm-eabi: {} @@ -158,11 +161,11 @@ importers: crates/node/npm/wasm32-wasi: dependencies: '@emnapi/core': - specifier: ^1.7.1 - version: 1.7.1 + specifier: ^1.8.1 + version: 1.8.1 '@emnapi/runtime': - specifier: ^1.7.1 - version: 1.7.1 + specifier: ^1.8.1 + version: 1.8.1 '@emnapi/wasi-threads': specifier: ^1.1.0 version: 1.1.0 @@ -173,7 +176,7 @@ importers: specifier: ^0.10.1 version: 0.10.1 tslib: - specifier: ^2.4.0 + specifier: ^2.8.1 version: 2.8.1 crates/node/npm/win32-arm64-msvc: {} @@ -195,8 +198,8 @@ importers: packages/@tailwindcss-browser: devDependencies: h3: - specifier: ^1.15.4 - version: 1.15.4 + specifier: ^1.15.5 + version: 1.15.5 listhen: specifier: ^1.9.0 version: 1.9.0 @@ -216,8 +219,8 @@ importers: specifier: workspace:* version: link:../../crates/node enhanced-resolve: - specifier: ^5.18.4 - version: 5.18.4 + specifier: ^5.19.0 + version: 5.19.0 mri: specifier: ^1.2.0 version: 1.2.0 @@ -231,17 +234,17 @@ importers: packages/@tailwindcss-node: dependencies: '@jridgewell/remapping': - specifier: ^2.3.4 + specifier: ^2.3.5 version: 2.3.5 enhanced-resolve: - specifier: ^5.18.4 - version: 5.18.4 + specifier: ^5.19.0 + version: 5.19.0 jiti: specifier: ^2.6.1 version: 2.6.1 lightningcss: specifier: 'catalog:' - version: 1.30.2(patch_hash=tzyxy3asfxcqc7ihrooumyi5fm) + version: 1.31.1(patch_hash=tzyxy3asfxcqc7ihrooumyi5fm) magic-string: specifier: ^0.30.21 version: 0.30.21 @@ -264,8 +267,8 @@ importers: specifier: workspace:* version: link:../../crates/node postcss: - specifier: ^8.4.41 - version: 8.4.41 + specifier: ^8.5.6 + version: 8.5.6 tailwindcss: specifier: workspace:* version: link:../tailwindcss @@ -284,7 +287,7 @@ importers: version: link:../internal-example-plugin postcss-import: specifier: ^16.1.1 - version: 16.1.1(postcss@8.4.41) + version: 16.1.1(postcss@8.5.6) packages/@tailwindcss-standalone: dependencies: @@ -304,60 +307,60 @@ importers: specifier: 1.0.3 version: 1.0.3 enhanced-resolve: - specifier: ^5.18.4 - version: 5.18.4 + specifier: ^5.19.0 + version: 5.19.0 tailwindcss: specifier: workspace:* version: link:../tailwindcss devDependencies: '@parcel/watcher-darwin-arm64': - specifier: ^2.5.1 - version: 2.5.1 + specifier: ^2.5.6 + version: 2.5.6 '@parcel/watcher-darwin-x64': - specifier: ^2.5.1 - version: 2.5.1 + specifier: ^2.5.6 + version: 2.5.6 '@parcel/watcher-linux-arm64-glibc': - specifier: ^2.5.1 - version: 2.5.1 + specifier: ^2.5.6 + version: 2.5.6 '@parcel/watcher-linux-arm64-musl': - specifier: ^2.5.1 - version: 2.5.1 + specifier: ^2.5.6 + version: 2.5.6 '@parcel/watcher-linux-x64-glibc': - specifier: ^2.5.1 - version: 2.5.1 + specifier: ^2.5.6 + version: 2.5.6 '@parcel/watcher-linux-x64-musl': - specifier: ^2.5.1 - version: 2.5.1 + specifier: ^2.5.6 + version: 2.5.6 '@parcel/watcher-win32-x64': - specifier: ^2.5.1 - version: 2.5.1 + specifier: ^2.5.6 + version: 2.5.6 '@types/bun': - specifier: ^1.3.5 - version: 1.3.5 + specifier: ^1.3.9 + version: 1.3.9 bun: - specifier: ^1.3.5 - version: 1.3.5 + specifier: ^1.3.9 + version: 1.3.9 lightningcss-darwin-arm64: specifier: 'catalog:' - version: 1.30.2 + version: 1.31.1 lightningcss-darwin-x64: specifier: 'catalog:' - version: 1.30.2 + version: 1.31.1 lightningcss-linux-arm64-gnu: specifier: 'catalog:' - version: 1.30.2 + version: 1.31.1 lightningcss-linux-arm64-musl: specifier: 'catalog:' - version: 1.30.2 + version: 1.31.1 lightningcss-linux-x64-gnu: specifier: 'catalog:' - version: 1.30.2 + version: 1.31.1 lightningcss-linux-x64-musl: specifier: 'catalog:' - version: 1.30.2 + version: 1.31.1 lightningcss-win32-x64-msvc: specifier: 'catalog:' - version: 1.30.2 + version: 1.31.1 packages/@tailwindcss-upgrade: dependencies: @@ -374,8 +377,8 @@ importers: specifier: 1.7.1 version: 1.7.1 enhanced-resolve: - specifier: ^5.18.4 - version: 5.18.4 + specifier: ^5.19.0 + version: 5.19.0 globby: specifier: ^15.0.0 version: 15.0.0 @@ -389,20 +392,20 @@ importers: specifier: ^1.1.1 version: 1.1.1 postcss: - specifier: ^8.4.41 - version: 8.4.41 + specifier: ^8.5.6 + version: 8.5.6 postcss-import: specifier: ^16.1.1 - version: 16.1.1(postcss@8.4.41) + version: 16.1.1(postcss@8.5.6) postcss-selector-parser: specifier: ^7.1.1 version: 7.1.1 prettier: specifier: 'catalog:' - version: 3.6.2 + version: 3.8.1 semver: - specifier: ^7.7.3 - version: 7.7.3 + specifier: ^7.7.4 + version: 7.7.4 tailwindcss: specifier: workspace:* version: link:../tailwindcss @@ -443,14 +446,36 @@ importers: version: 20.19.1 vite: specifier: 'catalog:' - version: 7.0.0(@types/node@20.19.1)(jiti@2.6.1)(lightningcss@1.30.2(patch_hash=tzyxy3asfxcqc7ihrooumyi5fm))(terser@5.31.6)(tsx@4.19.1)(yaml@2.6.0) + version: 7.3.1(@types/node@20.19.1)(jiti@2.6.1)(lightningcss@1.31.1(patch_hash=tzyxy3asfxcqc7ihrooumyi5fm))(terser@5.31.6)(tsx@4.19.1)(yaml@2.6.0) + + packages/@tailwindcss-webpack: + dependencies: + '@alloc/quick-lru': + specifier: ^5.2.0 + version: 5.2.0 + '@tailwindcss/node': + specifier: workspace:* + version: link:../@tailwindcss-node + '@tailwindcss/oxide': + specifier: workspace:* + version: link:../../crates/node + tailwindcss: + specifier: workspace:* + version: link:../tailwindcss + devDependencies: + '@types/node': + specifier: 'catalog:' + version: 20.19.1 + webpack: + specifier: 'catalog:' + version: 5.104.1(esbuild@0.27.0) packages/internal-example-plugin: {} packages/tailwindcss: devDependencies: '@jridgewell/remapping': - specifier: ^2.3.4 + specifier: ^2.3.5 version: 2.3.5 '@tailwindcss/oxide': specifier: workspace:^ @@ -463,7 +488,7 @@ importers: version: 1.7.1 lightningcss: specifier: 'catalog:' - version: 1.30.2(patch_hash=tzyxy3asfxcqc7ihrooumyi5fm) + version: 1.31.1(patch_hash=tzyxy3asfxcqc7ihrooumyi5fm) magic-string: specifier: ^0.30.21 version: 0.30.21 @@ -480,14 +505,14 @@ importers: specifier: ^3.3.3 version: 3.3.3 next: - specifier: ^16.1.0 - version: 16.1.0(@playwright/test@1.57.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + specifier: ^16.1.6 + version: 16.1.6(@babel/core@7.28.5)(@playwright/test@1.58.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) react: - specifier: ^19.2.3 - version: 19.2.3 + specifier: ^19.2.4 + version: 19.2.4 react-dom: - specifier: ^19.2.3 - version: 19.2.3(react@19.2.3) + specifier: ^19.2.4 + version: 19.2.4(react@19.2.4) tailwindcss: specifier: workspace:^ version: link:../../packages/tailwindcss @@ -496,57 +521,57 @@ importers: specifier: 'catalog:' version: 20.19.1 '@types/react': - specifier: ^19.2.7 - version: 19.2.7 + specifier: ^19.2.14 + version: 19.2.14 '@types/react-dom': specifier: ^19.2.3 - version: 19.2.3(@types/react@19.2.7) + version: 19.2.3(@types/react@19.2.14) eslint: specifier: ^9.39.2 version: 9.39.2(jiti@2.6.1) eslint-config-next: - specifier: ^16.1.0 - version: 16.1.0(@typescript-eslint/parser@8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.5.4))(eslint@9.39.2(jiti@2.6.1))(typescript@5.5.4) + specifier: ^16.1.6 + version: 16.1.6(@typescript-eslint/parser@8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) typescript: - specifier: ^5.5.4 - version: 5.5.4 + specifier: ^5.9.3 + version: 5.9.3 playgrounds/v3: dependencies: next: - specifier: ^16.1.0 - version: 16.1.0(@playwright/test@1.57.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + specifier: ^16.1.6 + version: 16.1.6(@babel/core@7.28.5)(@playwright/test@1.58.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) react: - specifier: ^19.2.3 - version: 19.2.3 + specifier: ^19.2.4 + version: 19.2.4 react-dom: - specifier: ^19.2.3 - version: 19.2.3(react@19.2.3) + specifier: ^19.2.4 + version: 19.2.4(react@19.2.4) tailwindcss: specifier: ^3 version: 3.4.14 devDependencies: '@types/node': - specifier: ^20.14.8 - version: 20.14.13 + specifier: 'catalog:' + version: 20.19.1 '@types/react': - specifier: ^19.2.7 - version: 19.2.7 + specifier: ^19.2.14 + version: 19.2.14 '@types/react-dom': specifier: ^19.2.3 - version: 19.2.3(@types/react@19.2.7) + version: 19.2.3(@types/react@19.2.14) autoprefixer: - specifier: ^10.4.23 - version: 10.4.23(postcss@8.4.47) + specifier: ^10.4.24 + version: 10.4.24(postcss@8.5.6) eslint: specifier: ^9.39.2 version: 9.39.2(jiti@2.6.1) eslint-config-next: - specifier: ^16.1.0 - version: 16.1.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.6.3) + specifier: ^16.1.6 + version: 16.1.6(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) typescript: - specifier: ^5.5.4 - version: 5.6.3 + specifier: ^5.9.3 + version: 5.9.3 playgrounds/vite: dependencies: @@ -554,30 +579,30 @@ importers: specifier: workspace:^ version: link:../../packages/@tailwindcss-vite '@vitejs/plugin-react': - specifier: ^5.1.2 - version: 5.1.2(vite@7.0.0(@types/node@20.19.1)(jiti@2.6.1)(lightningcss@1.30.2(patch_hash=tzyxy3asfxcqc7ihrooumyi5fm))(terser@5.31.6)(tsx@4.19.1)(yaml@2.6.0)) + specifier: ^5.1.3 + version: 5.1.3(vite@7.3.1(@types/node@20.19.1)(jiti@2.6.1)(lightningcss@1.31.1(patch_hash=tzyxy3asfxcqc7ihrooumyi5fm))(terser@5.31.6)(tsx@4.19.1)(yaml@2.6.0)) react: - specifier: ^19.2.3 - version: 19.2.3 + specifier: ^19.2.4 + version: 19.2.4 react-dom: - specifier: ^19.2.3 - version: 19.2.3(react@19.2.3) + specifier: ^19.2.4 + version: 19.2.4(react@19.2.4) tailwindcss: specifier: workspace:^ version: link:../../packages/tailwindcss devDependencies: '@types/react': - specifier: ^19.2.7 - version: 19.2.7 + specifier: ^19.2.14 + version: 19.2.14 '@types/react-dom': specifier: ^19.2.3 - version: 19.2.3(@types/react@19.2.7) + version: 19.2.3(@types/react@19.2.14) bun: - specifier: ^1.3.5 - version: 1.3.5 + specifier: ^1.3.9 + version: 1.3.9 vite: specifier: 'catalog:' - version: 7.0.0(@types/node@20.19.1)(jiti@2.6.1)(lightningcss@1.30.2(patch_hash=tzyxy3asfxcqc7ihrooumyi5fm))(terser@5.31.6)(tsx@4.19.1)(yaml@2.6.0) + version: 7.3.1(@types/node@20.19.1)(jiti@2.6.1)(lightningcss@1.31.1(patch_hash=tzyxy3asfxcqc7ihrooumyi5fm))(terser@5.31.6)(tsx@4.19.1)(yaml@2.6.0) packages: @@ -589,22 +614,42 @@ packages: resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==} engines: {node: '>=6.9.0'} + '@babel/code-frame@7.29.0': + resolution: {integrity: sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==} + engines: {node: '>=6.9.0'} + '@babel/compat-data@7.27.5': resolution: {integrity: sha512-KiRAp/VoJaWkkte84TvUd9qjdbZAdiqyvMxrGl1N6vzFogKmaLgoM3L1kgtLicp2HP5fBJS8JrZKLVIZGVJAVg==} engines: {node: '>=6.9.0'} + '@babel/compat-data@7.29.0': + resolution: {integrity: sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==} + engines: {node: '>=6.9.0'} + '@babel/core@7.28.5': resolution: {integrity: sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==} engines: {node: '>=6.9.0'} + '@babel/core@7.29.0': + resolution: {integrity: sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==} + engines: {node: '>=6.9.0'} + '@babel/generator@7.28.5': resolution: {integrity: sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==} engines: {node: '>=6.9.0'} + '@babel/generator@7.29.1': + resolution: {integrity: sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==} + engines: {node: '>=6.9.0'} + '@babel/helper-compilation-targets@7.27.2': resolution: {integrity: sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==} engines: {node: '>=6.9.0'} + '@babel/helper-compilation-targets@7.28.6': + resolution: {integrity: sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==} + engines: {node: '>=6.9.0'} + '@babel/helper-globals@7.28.0': resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==} engines: {node: '>=6.9.0'} @@ -613,12 +658,22 @@ packages: resolution: {integrity: sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==} engines: {node: '>=6.9.0'} + '@babel/helper-module-imports@7.28.6': + resolution: {integrity: sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==} + engines: {node: '>=6.9.0'} + '@babel/helper-module-transforms@7.28.3': resolution: {integrity: sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 + '@babel/helper-module-transforms@7.28.6': + resolution: {integrity: sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + '@babel/helper-plugin-utils@7.27.1': resolution: {integrity: sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==} engines: {node: '>=6.9.0'} @@ -639,11 +694,20 @@ packages: resolution: {integrity: sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==} engines: {node: '>=6.9.0'} + '@babel/helpers@7.28.6': + resolution: {integrity: sha512-xOBvwq86HHdB7WUDTfKfT/Vuxh7gElQ+Sfti2Cy6yIWNW05P8iUslOVcZ4/sKbE+/jQaukQAdz/gf3724kYdqw==} + engines: {node: '>=6.9.0'} + '@babel/parser@7.28.5': resolution: {integrity: sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==} engines: {node: '>=6.0.0'} hasBin: true + '@babel/parser@7.29.0': + resolution: {integrity: sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==} + engines: {node: '>=6.0.0'} + hasBin: true + '@babel/plugin-transform-react-jsx-self@7.27.1': resolution: {integrity: sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==} engines: {node: '>=6.9.0'} @@ -660,20 +724,38 @@ packages: resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==} engines: {node: '>=6.9.0'} + '@babel/template@7.28.6': + resolution: {integrity: sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==} + engines: {node: '>=6.9.0'} + '@babel/traverse@7.28.5': resolution: {integrity: sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==} engines: {node: '>=6.9.0'} + '@babel/traverse@7.29.0': + resolution: {integrity: sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==} + engines: {node: '>=6.9.0'} + '@babel/types@7.28.5': resolution: {integrity: sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==} engines: {node: '>=6.9.0'} + '@babel/types@7.29.0': + resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==} + engines: {node: '>=6.9.0'} + '@emnapi/core@1.7.1': resolution: {integrity: sha512-o1uhUASyo921r2XtHYOHy7gdkGLge8ghBEQHMWmyJFoXlpU58kIrhhN3w26lpQb6dspetweapMn2CSNwQ8I4wg==} + '@emnapi/core@1.8.1': + resolution: {integrity: sha512-AvT9QFpxK0Zd8J0jopedNm+w/2fIzvtPKPjqyw9jwvBaReTTqPBk9Hixaz7KbjimP+QNz605/XnjFcDAL2pqBg==} + '@emnapi/runtime@1.7.1': resolution: {integrity: sha512-PVtJr5CmLwYAU9PZDMITZoR5iAOShYREoR45EyyLrbntV50mdePTgUn4AmOw90Ifcj+x2kRjdzr1HP3RrNiHGA==} + '@emnapi/runtime@1.8.1': + resolution: {integrity: sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg==} + '@emnapi/wasi-threads@1.1.0': resolution: {integrity: sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==} @@ -1481,9 +1563,6 @@ packages: '@jridgewell/source-map@0.3.6': resolution: {integrity: sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==} - '@jridgewell/sourcemap-codec@1.5.0': - resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} - '@jridgewell/sourcemap-codec@1.5.5': resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} @@ -1826,56 +1905,56 @@ packages: resolution: {integrity: sha512-enkZYyuCdo+9jneCPE/0fjIta4wWnvVN9hBo2HuiMpRF0q3lzv1J6b/cl7i0mxZUKhBrV3aCKDBQnCOhwKbPmQ==} engines: {node: '>= 10'} - '@next/env@16.1.0': - resolution: {integrity: sha512-Dd23XQeFHmhf3KBW76leYVkejHlCdB7erakC2At2apL1N08Bm+dLYNP+nNHh0tzUXfPQcNcXiQyacw0PG4Fcpw==} + '@next/env@16.1.6': + resolution: {integrity: sha512-N1ySLuZjnAtN3kFnwhAwPvZah8RJxKasD7x1f8shFqhncnWZn4JMfg37diLNuoHsLAlrDfM3g4mawVdtAG8XLQ==} - '@next/eslint-plugin-next@16.1.0': - resolution: {integrity: sha512-sooC/k0LCF4/jLXYHpgfzJot04lZQqsttn8XJpTguP8N3GhqXN3wSkh68no2OcZzS/qeGwKDFTqhZ8WofdXmmQ==} + '@next/eslint-plugin-next@16.1.6': + resolution: {integrity: sha512-/Qq3PTagA6+nYVfryAtQ7/9FEr/6YVyvOtl6rZnGsbReGLf0jZU6gkpr1FuChAQpvV46a78p4cmHOVP8mbfSMQ==} - '@next/swc-darwin-arm64@16.1.0': - resolution: {integrity: sha512-onHq8dl8KjDb8taANQdzs3XmIqQWV3fYdslkGENuvVInFQzZnuBYYOG2HGHqqtvgmEU7xWzhgndXXxnhk4Z3fQ==} + '@next/swc-darwin-arm64@16.1.6': + resolution: {integrity: sha512-wTzYulosJr/6nFnqGW7FrG3jfUUlEf8UjGA0/pyypJl42ExdVgC6xJgcXQ+V8QFn6niSG2Pb8+MIG1mZr2vczw==} engines: {node: '>= 10'} cpu: [arm64] os: [darwin] - '@next/swc-darwin-x64@16.1.0': - resolution: {integrity: sha512-Am6VJTp8KhLuAH13tPrAoVIXzuComlZlMwGr++o2KDjWiKPe3VwpxYhgV6I4gKls2EnsIMggL4y7GdXyDdJcFA==} + '@next/swc-darwin-x64@16.1.6': + resolution: {integrity: sha512-BLFPYPDO+MNJsiDWbeVzqvYd4NyuRrEYVB5k2N3JfWncuHAy2IVwMAOlVQDFjj+krkWzhY2apvmekMkfQR0CUQ==} engines: {node: '>= 10'} cpu: [x64] os: [darwin] - '@next/swc-linux-arm64-gnu@16.1.0': - resolution: {integrity: sha512-fVicfaJT6QfghNyg8JErZ+EMNQ812IS0lmKfbmC01LF1nFBcKfcs4Q75Yy8IqnsCqH/hZwGhqzj3IGVfWV6vpA==} + '@next/swc-linux-arm64-gnu@16.1.6': + resolution: {integrity: sha512-OJYkCd5pj/QloBvoEcJ2XiMnlJkRv9idWA/j0ugSuA34gMT6f5b7vOiCQHVRpvStoZUknhl6/UxOXL4OwtdaBw==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] - '@next/swc-linux-arm64-musl@16.1.0': - resolution: {integrity: sha512-TojQnDRoX7wJWXEEwdfuJtakMDW64Q7NrxQPviUnfYJvAx5/5wcGE+1vZzQ9F17m+SdpFeeXuOr6v3jbyusYMQ==} + '@next/swc-linux-arm64-musl@16.1.6': + resolution: {integrity: sha512-S4J2v+8tT3NIO9u2q+S0G5KdvNDjXfAv06OhfOzNDaBn5rw84DGXWndOEB7d5/x852A20sW1M56vhC/tRVbccQ==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] - '@next/swc-linux-x64-gnu@16.1.0': - resolution: {integrity: sha512-quhNFVySW4QwXiZkZ34SbfzNBm27vLrxZ2HwTfFFO1BBP0OY1+pI0nbyewKeq1FriqU+LZrob/cm26lwsiAi8Q==} + '@next/swc-linux-x64-gnu@16.1.6': + resolution: {integrity: sha512-2eEBDkFlMMNQnkTyPBhQOAyn2qMxyG2eE7GPH2WIDGEpEILcBPI/jdSv4t6xupSP+ot/jkfrCShLAa7+ZUPcJQ==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - '@next/swc-linux-x64-musl@16.1.0': - resolution: {integrity: sha512-6JW0z2FZUK5iOVhUIWqE4RblAhUj1EwhZ/MwteGb//SpFTOHydnhbp3868gxalwea+mbOLWO6xgxj9wA9wNvNw==} + '@next/swc-linux-x64-musl@16.1.6': + resolution: {integrity: sha512-oicJwRlyOoZXVlxmIMaTq7f8pN9QNbdes0q2FXfRsPhfCi8n8JmOZJm5oo1pwDaFbnnD421rVU409M3evFbIqg==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - '@next/swc-win32-arm64-msvc@16.1.0': - resolution: {integrity: sha512-+DK/akkAvvXn5RdYN84IOmLkSy87SCmpofJPdB8vbLmf01BzntPBSYXnMvnEEv/Vcf3HYJwt24QZ/s6sWAwOMQ==} + '@next/swc-win32-arm64-msvc@16.1.6': + resolution: {integrity: sha512-gQmm8izDTPgs+DCWH22kcDmuUp7NyiJgEl18bcr8irXA5N2m2O+JQIr6f3ct42GOs9c0h8QF3L5SzIxcYAAXXw==} engines: {node: '>= 10'} cpu: [arm64] os: [win32] - '@next/swc-win32-x64-msvc@16.1.0': - resolution: {integrity: sha512-Tr0j94MphimCCks+1rtYPzQFK+faJuhHWCegU9S9gDlgyOk8Y3kPmO64UcjyzZAlligeBtYZ/2bEyrKq0d2wqQ==} + '@next/swc-win32-x64-msvc@16.1.6': + resolution: {integrity: sha512-NRfO39AIrzBnixKbjuo2YiYhB6o9d8v/ymU9m/Xk8cyVk+k7XylniXkHwjs4s70wedVffc6bQNbufk5v0xEm0A==} engines: {node: '>= 10'} cpu: [x64] os: [win32] @@ -1948,58 +2027,58 @@ packages: '@octokit/types@16.0.0': resolution: {integrity: sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg==} - '@oven/bun-darwin-aarch64@1.3.5': - resolution: {integrity: sha512-8GvNtMo0NINM7Emk9cNAviCG3teEgr3BUX9be0+GD029zIagx2Sf54jMui1Eu1IpFm7nWHODuLEefGOQNaJ0gQ==} + '@oven/bun-darwin-aarch64@1.3.9': + resolution: {integrity: sha512-df7smckMWSUfaT5mzwN9Lfpd3ZGkOqo+vmQ8VV2a32gl14v6uZ/qeeo+1RlANXn8M0uzXPWWCkrKZIWSZUR0qw==} cpu: [arm64] os: [darwin] - '@oven/bun-darwin-x64-baseline@1.3.5': - resolution: {integrity: sha512-p5q3rJk48qhLuLBOFehVc+kqCE03YrswTc6NCxbwsxiwfySXwcAvpF2KWKF/ZZObvvR8hCCvqe1F81b2p5r2dg==} + '@oven/bun-darwin-x64-baseline@1.3.9': + resolution: {integrity: sha512-XbhsA2XAFzvFr0vPSV6SNqGxab4xHKdPmVTLqoSHAx9tffrSq/012BDptOskulwnD+YNsrJUx2D2Ve1xvfgGcg==} cpu: [x64] os: [darwin] - '@oven/bun-darwin-x64@1.3.5': - resolution: {integrity: sha512-r33eHQOHAwkuiBJIwmkXIyqONQOQMnd1GMTpDzaxx9vf9+svby80LZO9Hcm1ns6KT/TBRFyODC/0loA7FAaffg==} + '@oven/bun-darwin-x64@1.3.9': + resolution: {integrity: sha512-YiLxfsPzQqaVvT2a+nxH9do0YfUjrlxF3tKP0b1DDgvfgCcVKGsrQH3Wa82qHgL4dnT8h2bqi94JxXESEuPmcA==} cpu: [x64] os: [darwin] - '@oven/bun-linux-aarch64-musl@1.3.5': - resolution: {integrity: sha512-HKBeUlJdNduRkzJKZ5DXM+pPqntfC50/Hu2X65jVX0Y7hu/6IC8RaUTqpr8FtCZqqmc9wDK0OTL+Mbi9UQIKYQ==} + '@oven/bun-linux-aarch64-musl@1.3.9': + resolution: {integrity: sha512-t8uimCVBTw5f9K2QTZE5wN6UOrFETNrh/Xr7qtXT9nAOzaOnIFvYA+HcHbGfi31fRlCVfTxqm/EiCwJ1gEw9YQ==} cpu: [arm64] os: [linux] - '@oven/bun-linux-aarch64@1.3.5': - resolution: {integrity: sha512-zkcHPI23QxJ1TdqafhgkXt1NOEN8o5C460sVeNnrhfJ43LwZgtfcvcQE39x/pBedu67fatY8CU0iY00nOh46ZQ==} + '@oven/bun-linux-aarch64@1.3.9': + resolution: {integrity: sha512-VaNQTu0Up4gnwZLQ6/Hmho6jAlLxTQ1PwxEth8EsXHf82FOXXPV5OCQ6KC9mmmocjKlmWFaIGebThrOy8DUo4g==} cpu: [arm64] os: [linux] - '@oven/bun-linux-x64-baseline@1.3.5': - resolution: {integrity: sha512-FeCQyBU62DMuB0nn01vPnf3McXrKOsrK9p7sHaBFYycw0mmoU8kCq/WkBkGMnLuvQljJSyen8QBTx+fXdNupWg==} + '@oven/bun-linux-x64-baseline@1.3.9': + resolution: {integrity: sha512-nZ12g22cy7pEOBwAxz2tp0wVqekaCn9QRKuGTHqOdLlyAqR4SCdErDvDhUWd51bIyHTQoCmj72TegGTgG0WNPw==} cpu: [x64] os: [linux] - '@oven/bun-linux-x64-musl-baseline@1.3.5': - resolution: {integrity: sha512-TJiYC7KCr0XxFTsxgwQOeE7dncrEL/RSyL0EzSL3xRkrxJMWBCvCSjQn7LV1i6T7hFst0+3KoN3VWvD5BinqHA==} + '@oven/bun-linux-x64-musl-baseline@1.3.9': + resolution: {integrity: sha512-3FXQgtYFsT0YOmAdMcJn56pLM5kzSl6y942rJJIl5l2KummB9Ea3J/vMJMzQk7NCAGhleZGWU/pJSS/uXKGa7w==} cpu: [x64] os: [linux] - '@oven/bun-linux-x64-musl@1.3.5': - resolution: {integrity: sha512-XkCCHkByYn8BIDvoxnny898znju4xnW2kvFE8FT5+0Y62cWdcBGMZ9RdsEUTeRz16k8hHtJpaSfLcEmNTFIwRQ==} + '@oven/bun-linux-x64-musl@1.3.9': + resolution: {integrity: sha512-4ZjIUgCxEyKwcKXideB5sX0KJpnHTZtu778w73VNq2uNH2fNpMZv98+DBgJyQ9OfFoRhmKn1bmLmSefvnHzI9w==} cpu: [x64] os: [linux] - '@oven/bun-linux-x64@1.3.5': - resolution: {integrity: sha512-n7zhKTSDZS0yOYg5Rq8easZu5Y/o47sv0c7yGr2ciFdcie9uYV55fZ7QMqhWMGK33ezCSikh5EDkUMCIvfWpjA==} + '@oven/bun-linux-x64@1.3.9': + resolution: {integrity: sha512-oQyAW3+ugulvXTZ+XYeUMmNPR94sJeMokfHQoKwPvVwhVkgRuMhcLGV2ZesHCADVu30Oz2MFXbgdC8x4/o9dRg==} cpu: [x64] os: [linux] - '@oven/bun-windows-x64-baseline@1.3.5': - resolution: {integrity: sha512-rtVQB9/1XK8FWJgFtsOthbPifRMYypgJwxu+pK3NHx8WvFKmq7HcPDqNr8xLzGULjQEO7eAo2aOZfONOwYz+5g==} + '@oven/bun-windows-x64-baseline@1.3.9': + resolution: {integrity: sha512-a/+hSrrDpMD7THyXvE2KJy1skxzAD0cnW4K1WjuI/91VqsphjNzvf5t/ZgxEVL4wb6f+hKrSJ5J3aH47zPr61g==} cpu: [x64] os: [win32] - '@oven/bun-windows-x64@1.3.5': - resolution: {integrity: sha512-T3xkODItb/0ftQPFsZDc7EAX2D6A4TEazQ2YZyofZToO8Q7y8YT8ooWdhd0BQiTCd66uEvgE1DCZetynwg2IoA==} + '@oven/bun-windows-x64@1.3.9': + resolution: {integrity: sha512-/d6vAmgKvkoYlsGPsRPlPmOK1slPis/F40UG02pYwypTH0wmY0smgzdFqR4YmryxFh17XrW1kITv+U99Oajk9Q==} cpu: [x64] os: [win32] @@ -2024,6 +2103,13 @@ packages: '@parcel/watcher-darwin-arm64@2.5.1': resolution: {integrity: sha512-eAzPv5osDmZyBhou8PoF4i6RQXAfeKL9tjb3QzYuccXFMQU0ruIc/POh30ePnaOyD1UXdlKguHBmsTs53tVoPw==} engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [darwin] + + '@parcel/watcher-darwin-arm64@2.5.6': + resolution: {integrity: sha512-Z2ZdrnwyXvvvdtRHLmM4knydIdU9adO3D4n/0cVipF3rRiwP+3/sfzpAwA/qKFL6i1ModaabkU7IbpeMBgiVEA==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] os: [darwin] '@parcel/watcher-darwin-x64@2.5.0': @@ -2035,6 +2121,13 @@ packages: '@parcel/watcher-darwin-x64@2.5.1': resolution: {integrity: sha512-1ZXDthrnNmwv10A0/3AJNZ9JGlzrF82i3gNQcWOzd7nJ8aj+ILyW1MTxVk35Db0u91oD5Nlk9MBiujMlwmeXZg==} engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [darwin] + + '@parcel/watcher-darwin-x64@2.5.6': + resolution: {integrity: sha512-HgvOf3W9dhithcwOWX9uDZyn1lW9R+7tPZ4sug+NGrGIo4Rk1hAXLEbcH1TQSqxts0NYXXlOWqVpvS1SFS4fRg==} + engines: {node: '>= 10.0.0'} + cpu: [x64] os: [darwin] '@parcel/watcher-freebsd-x64@2.5.0': @@ -2082,6 +2175,13 @@ packages: '@parcel/watcher-linux-arm64-glibc@2.5.1': resolution: {integrity: sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==} engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [linux] + + '@parcel/watcher-linux-arm64-glibc@2.5.6': + resolution: {integrity: sha512-f2g/DT3NhGPdBmMWYoxixqYr3v/UXcmLOYy16Bx0TM20Tchduwr4EaCbmxh1321TABqPGDpS8D/ggOTaljijOA==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] os: [linux] '@parcel/watcher-linux-arm64-musl@2.5.0': @@ -2093,6 +2193,13 @@ packages: '@parcel/watcher-linux-arm64-musl@2.5.1': resolution: {integrity: sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg==} engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [linux] + + '@parcel/watcher-linux-arm64-musl@2.5.6': + resolution: {integrity: sha512-qb6naMDGlbCwdhLj6hgoVKJl2odL34z2sqkC7Z6kzir8b5W65WYDpLB6R06KabvZdgoHI/zxke4b3zR0wAbDTA==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] os: [linux] '@parcel/watcher-linux-x64-glibc@2.5.0': @@ -2104,6 +2211,13 @@ packages: '@parcel/watcher-linux-x64-glibc@2.5.1': resolution: {integrity: sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A==} engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [linux] + + '@parcel/watcher-linux-x64-glibc@2.5.6': + resolution: {integrity: sha512-kbT5wvNQlx7NaGjzPFu8nVIW1rWqV780O7ZtkjuWaPUgpv2NMFpjYERVi0UYj1msZNyCzGlaCWEtzc+exjMGbQ==} + engines: {node: '>= 10.0.0'} + cpu: [x64] os: [linux] '@parcel/watcher-linux-x64-musl@2.5.0': @@ -2115,6 +2229,13 @@ packages: '@parcel/watcher-linux-x64-musl@2.5.1': resolution: {integrity: sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg==} engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [linux] + + '@parcel/watcher-linux-x64-musl@2.5.6': + resolution: {integrity: sha512-1JRFeC+h7RdXwldHzTsmdtYR/Ku8SylLgTU/reMuqdVD7CtLwf0VR1FqeprZ0eHQkO0vqsbvFLXUmYm/uNKJBg==} + engines: {node: '>= 10.0.0'} + cpu: [x64] os: [linux] '@parcel/watcher-wasm@2.5.0': @@ -2156,6 +2277,13 @@ packages: '@parcel/watcher-win32-x64@2.5.1': resolution: {integrity: sha512-9lHBdJITeNR++EvSQVUcaZoWupyHfXe1jZvGZ06O/5MflPcuPLtEphScIBL+AiCWBO46tDSHzWyD0uDmmZqsgA==} engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [win32] + + '@parcel/watcher-win32-x64@2.5.6': + resolution: {integrity: sha512-hbQlYcCq5dlAX9Qx+kFb0FHue6vbjlf0FrNzSKdYK2APUf7tGfGxQCk2ihEREmbR6ZMc0MVAD5RIX/41gpUzTw==} + engines: {node: '>= 10.0.0'} + cpu: [x64] os: [win32] '@parcel/watcher@2.5.0': @@ -2170,13 +2298,13 @@ packages: resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} - '@playwright/test@1.57.0': - resolution: {integrity: sha512-6TyEnHgd6SArQO8UO2OMTxshln3QMWBtPGrOCgs3wVEmQmwyuNtB10IZMfmYDE0riwNR1cu4q+pPcxMVtaG3TA==} + '@playwright/test@1.58.0': + resolution: {integrity: sha512-fWza+Lpbj6SkQKCrU6si4iu+fD2dD3gxNHFhUPxsfXBPhnv3rRSQVd0NtBUT9Z/RhF/boCBcuUaMUSTRTopjZg==} engines: {node: '>=18'} hasBin: true - '@rolldown/pluginutils@1.0.0-beta.53': - resolution: {integrity: sha512-vENRlFU4YbrwVqNDZ7fLvy+JR1CRkyr01jhSiDpE1u6py3OMzQfztQU2jxykW3ALNxO4kSlqIDeYyD0Y9RcQeQ==} + '@rolldown/pluginutils@1.0.0-rc.2': + resolution: {integrity: sha512-izyXV/v+cHiRfozX62W9htOAvwMo4/bXKDrQ+vom1L1qRuexPock/7VZDAhnpHCLNejd3NJ6hiab+tO0D44Rgw==} '@rollup/rollup-android-arm-eabi@4.44.0': resolution: {integrity: sha512-xEiEE5oDW6tK4jXCAyliuntGR+amEMO7HLtdSshVuhFnKTYoeYMyXQK7pLouAJJj5KHdwdn87bfHAR2nSdNAUA==} @@ -2324,8 +2452,8 @@ packages: '@types/braces@3.0.5': resolution: {integrity: sha512-SQFof9H+LXeWNz8wDe7oN5zu7ket0qwMu5vZubW4GCJ8Kkeh6nBWUz87+KTz/G3Kqsrp0j/W253XJb3KMEeg3w==} - '@types/bun@1.3.5': - resolution: {integrity: sha512-RnygCqNrd3srIPEWBd5LFeUYG7plCoH2Yw9WaZGyNmdTEei+gWaHqydbaIRkIkcbXwhBT94q78QljxN0Sk838w==} + '@types/bun@1.3.9': + resolution: {integrity: sha512-KQ571yULOdWJiMH+RIWIOZ7B2RXQGpL1YQrBtLIV3FqDcCu6FsbFUBwhdKUlCKUpS3PJDsHlJ1QKlpxoVR+xtw==} '@types/chai@5.2.3': resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==} @@ -2333,6 +2461,12 @@ packages: '@types/deep-eql@4.0.2': resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} + '@types/eslint-scope@3.7.7': + resolution: {integrity: sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==} + + '@types/eslint@9.6.1': + resolution: {integrity: sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==} + '@types/estree@1.0.8': resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} @@ -2342,9 +2476,6 @@ packages: '@types/json5@0.0.29': resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} - '@types/node@20.14.13': - resolution: {integrity: sha512-+bHoGiZb8UiQ0+WEtmph2IWQCjIqg8MDZMAV+ppRRhUZnquF5mQkP/9vpSwJClEiSM/C7fZZExPzfU0vJTyp8w==} - '@types/node@20.19.1': resolution: {integrity: sha512-jJD50LtlD2dodAEO653i3YF04NWak6jN3ky+Ri3Em3mGR39/glWiboM/IePaRbgwSfqM1TpGXfAg8ohn/4dTgA==} @@ -2356,8 +2487,8 @@ packages: peerDependencies: '@types/react': ^19.2.0 - '@types/react@19.2.7': - resolution: {integrity: sha512-MWtvHrGZLFttgeEj28VXHxpmwYbor/ATPYbBfSFZEIRK0ecCFLl2Qo55z52Hss+UV9CRN7trSeq1zbgx7YDWWg==} + '@types/react@19.2.14': + resolution: {integrity: sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==} '@types/semver@7.7.1': resolution: {integrity: sha512-FmgJfu+MOcQ370SD0ev7EI8TlCAfKYU+B4m5T3yXc1CiRN94g/SZPtsCkk506aUDtlMnFZvasDwHHUcZUEaYuA==} @@ -2421,17 +2552,17 @@ packages: resolution: {integrity: sha512-SIV3/6eftCy1bNzCQoPmbWsRLujS8t5iDIZ4spZOBHqrM+yfX2ogg8Tt3PDTAVKw3sSCiUgg30uOAvK2r9zGjQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@vitejs/plugin-react@5.1.2': - resolution: {integrity: sha512-EcA07pHJouywpzsoTUqNh5NwGayl2PPVEJKUSinGGSxFGYn+shYbqMGBg6FXDqgXum9Ou/ecb+411ssw8HImJQ==} + '@vitejs/plugin-react@5.1.3': + resolution: {integrity: sha512-NVUnA6gQCl8jfoYqKqQU5Clv0aPw14KkZYCsX6T9Lfu9slI0LOU10OTwFHS/WmptsMMpshNd/1tuWsHQ2Uk+cg==} engines: {node: ^20.19.0 || >=22.12.0} peerDependencies: vite: ^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 - '@vitest/expect@4.0.12': - resolution: {integrity: sha512-is+g0w8V3/ZhRNrRizrJNr8PFQKwYmctWlU4qg8zy5r9aIV5w8IxXLlfbbxJCwSpsVl2PXPTm2/zruqTqz3QSg==} + '@vitest/expect@4.0.18': + resolution: {integrity: sha512-8sCWUyckXXYvx4opfzVY03EOiYVxyNrHS5QxX3DAIi5dpJAAkyJezHCP77VMX4HKA2LDT/Jpfo8i2r5BE3GnQQ==} - '@vitest/mocker@4.0.12': - resolution: {integrity: sha512-GsmA/tD5Ht3RUFoz41mZsMU1AXch3lhmgbTnoSPTdH231g7S3ytNN1aU0bZDSyxWs8WA7KDyMPD5L4q6V6vj9w==} + '@vitest/mocker@4.0.18': + resolution: {integrity: sha512-HhVd0MDnzzsgevnOWCBj5Otnzobjy5wLBe4EdeeFGv8luMsGcYqDuFRMcttKWZA5vVO8RFjexVovXvAM4JoJDQ==} peerDependencies: msw: ^2.4.9 vite: ^6.0.0 || ^7.0.0-0 @@ -2441,20 +2572,77 @@ packages: vite: optional: true - '@vitest/pretty-format@4.0.12': - resolution: {integrity: sha512-R7nMAcnienG17MvRN8TPMJiCG8rrZJblV9mhT7oMFdBXvS0x+QD6S1G4DxFusR2E0QIS73f7DqSR1n87rrmE+g==} + '@vitest/pretty-format@4.0.18': + resolution: {integrity: sha512-P24GK3GulZWC5tz87ux0m8OADrQIUVDPIjjj65vBXYG17ZeU3qD7r+MNZ1RNv4l8CGU2vtTRqixrOi9fYk/yKw==} + + '@vitest/runner@4.0.18': + resolution: {integrity: sha512-rpk9y12PGa22Jg6g5M3UVVnTS7+zycIGk9ZNGN+m6tZHKQb7jrP7/77WfZy13Y/EUDd52NDsLRQhYKtv7XfPQw==} + + '@vitest/snapshot@4.0.18': + resolution: {integrity: sha512-PCiV0rcl7jKQjbgYqjtakly6T1uwv/5BQ9SwBLekVg/EaYeQFPiXcgrC2Y7vDMA8dM1SUEAEV82kgSQIlXNMvA==} + + '@vitest/spy@4.0.18': + resolution: {integrity: sha512-cbQt3PTSD7P2OARdVW3qWER5EGq7PHlvE+QfzSC0lbwO+xnt7+XH06ZzFjFRgzUX//JmpxrCu92VdwvEPlWSNw==} + + '@vitest/utils@4.0.18': + resolution: {integrity: sha512-msMRKLMVLWygpK3u2Hybgi4MNjcYJvwTb0Ru09+fOyCXIgT5raYP041DRRdiJiI3k/2U6SEbAETB3YtBrUkCFA==} + + '@webassemblyjs/ast@1.14.1': + resolution: {integrity: sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==} + + '@webassemblyjs/floating-point-hex-parser@1.13.2': + resolution: {integrity: sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==} + + '@webassemblyjs/helper-api-error@1.13.2': + resolution: {integrity: sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==} + + '@webassemblyjs/helper-buffer@1.14.1': + resolution: {integrity: sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==} + + '@webassemblyjs/helper-numbers@1.13.2': + resolution: {integrity: sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==} + + '@webassemblyjs/helper-wasm-bytecode@1.13.2': + resolution: {integrity: sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==} + + '@webassemblyjs/helper-wasm-section@1.14.1': + resolution: {integrity: sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==} + + '@webassemblyjs/ieee754@1.13.2': + resolution: {integrity: sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==} + + '@webassemblyjs/leb128@1.13.2': + resolution: {integrity: sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==} + + '@webassemblyjs/utf8@1.13.2': + resolution: {integrity: sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==} + + '@webassemblyjs/wasm-edit@1.14.1': + resolution: {integrity: sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==} + + '@webassemblyjs/wasm-gen@1.14.1': + resolution: {integrity: sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==} - '@vitest/runner@4.0.12': - resolution: {integrity: sha512-hDlCIJWuwlcLumfukPsNfPDOJokTv79hnOlf11V+n7E14rHNPz0Sp/BO6h8sh9qw4/UjZiKyYpVxK2ZNi+3ceQ==} + '@webassemblyjs/wasm-opt@1.14.1': + resolution: {integrity: sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==} - '@vitest/snapshot@4.0.12': - resolution: {integrity: sha512-2jz9zAuBDUSbnfyixnyOd1S2YDBrZO23rt1bicAb6MA/ya5rHdKFRikPIDpBj/Dwvh6cbImDmudegnDAkHvmRQ==} + '@webassemblyjs/wasm-parser@1.14.1': + resolution: {integrity: sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==} - '@vitest/spy@4.0.12': - resolution: {integrity: sha512-GZjI9PPhiOYNX8Nsyqdw7JQB+u0BptL5fSnXiottAUBHlcMzgADV58A7SLTXXQwcN1yZ6gfd1DH+2bqjuUlCzw==} + '@webassemblyjs/wast-printer@1.14.1': + resolution: {integrity: sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==} - '@vitest/utils@4.0.12': - resolution: {integrity: sha512-DVS/TLkLdvGvj1avRy0LSmKfrcI9MNFvNGN6ECjTUHWJdlcgPDOXhjMis5Dh7rBH62nAmSXnkPbE+DZ5YD75Rw==} + '@xtuc/ieee754@1.2.0': + resolution: {integrity: sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==} + + '@xtuc/long@4.2.2': + resolution: {integrity: sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==} + + acorn-import-phases@1.0.4: + resolution: {integrity: sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==} + engines: {node: '>=10.13.0'} + peerDependencies: + acorn: ^8.14.0 acorn-jsx@5.3.2: resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} @@ -2471,9 +2659,25 @@ packages: engines: {node: '>=0.4.0'} hasBin: true + ajv-formats@2.1.1: + resolution: {integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==} + peerDependencies: + ajv: ^8.0.0 + peerDependenciesMeta: + ajv: + optional: true + + ajv-keywords@5.1.0: + resolution: {integrity: sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==} + peerDependencies: + ajv: ^8.8.2 + ajv@6.12.6: resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + ajv@8.17.1: + resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==} + ansi-regex@5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} @@ -2546,8 +2750,8 @@ packages: ast-types-flow@0.0.8: resolution: {integrity: sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==} - autoprefixer@10.4.23: - resolution: {integrity: sha512-YYTXSFulfwytnjAPlw8QHncHJmlvFKtczb8InXaAx9Q0LbfDnfEYDE55omerIJKihhmU61Ft+cAOSzQVaBUmeA==} + autoprefixer@10.4.24: + resolution: {integrity: sha512-uHZg7N9ULTVbutaIsDRoUkoS8/h3bdsmVJYZ5l3wv8Cp/6UIIoRDm90hZ+BwxUj/hGBEzLxdHNSKuFpn8WOyZw==} engines: {node: ^10 || ^12 || >=14} hasBin: true peerDependencies: @@ -2606,11 +2810,12 @@ packages: buffer-from@1.1.2: resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} - bun-types@1.3.5: - resolution: {integrity: sha512-inmAYe2PFLs0SUbFOWSVD24sg1jFlMPxOjOSSCYqUgn4Hsc3rDc7dFvfVYjFPNHtov6kgUeulV4SxbuIV/stPw==} + bun-types@1.3.9: + resolution: {integrity: sha512-+UBWWOakIP4Tswh0Bt0QD0alpTY8cb5hvgiYeWCMet9YukHbzuruIEeXC2D7nMJPB12kbh8C7XJykSexEqGKJg==} - bun@1.3.5: - resolution: {integrity: sha512-c1YHIGUfgvYPJmLug5QiLzNWlX2Dg7X/67JWu1Va+AmMXNXzC/KQn2lgQ7rD+n1u1UqDpJMowVGGxTNpbPydNw==} + bun@1.3.9: + resolution: {integrity: sha512-v5hkh1us7sMNjfimWE70flYbD5I1/qWQaqmJ45q2qk5H/7muQVa478LSVRSFyGTBUBog2LsPQnfIRdjyWJRY+A==} + cpu: [arm64, x64] os: [darwin, linux, win32] hasBin: true @@ -2644,12 +2849,12 @@ packages: resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==} engines: {node: '>= 6'} - caniuse-lite@1.0.30001755: - resolution: {integrity: sha512-44V+Jm6ctPj7R52Na4TLi3Zri4dWUljJd+RDm+j8LtNCc/ihLCT+X1TzoOAkRETEWqjuLnh9581Tl80FvK7jVA==} - caniuse-lite@1.0.30001761: resolution: {integrity: sha512-JF9ptu1vP2coz98+5051jZ4PwQgd2ni8A+gYSN7EA7dPKIMf0pDlSUxhdmVOaV3/fYK5uWBkgSXJaRLr4+3A6g==} + caniuse-lite@1.0.30001769: + resolution: {integrity: sha512-BCfFL1sHijQlBGWBMuJyhZUhzo7wer5sVj9hqekB/7xn0Ypy+pER/edCYQm4exbXj4WiySGp40P8UuTh6w1srg==} + chai@6.2.1: resolution: {integrity: sha512-p4Z49OGG5W/WBCPSS/dH3jQ73kD6tiMmUM+bckNK6Jr5JHMG3k9bg/BvKR8lKmtVBKmOiuVaV2ws8s9oSbwysg==} engines: {node: '>=18'} @@ -2669,6 +2874,10 @@ packages: resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} engines: {node: '>= 14.16.0'} + chrome-trace-event@1.0.4: + resolution: {integrity: sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==} + engines: {node: '>=6.0'} + citty@0.1.6: resolution: {integrity: sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ==} @@ -2805,10 +3014,6 @@ packages: engines: {node: '>=0.10'} hasBin: true - detect-libc@2.0.4: - resolution: {integrity: sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==} - engines: {node: '>=8'} - detect-libc@2.1.2: resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} engines: {node: '>=8'} @@ -2836,8 +3041,8 @@ packages: electron-to-chromium@1.5.267: resolution: {integrity: sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw==} - emnapi@1.7.1: - resolution: {integrity: sha512-wlLK2xFq+T+rCBlY6+lPlFVDEyE93b7hSn9dMrfWBIcPf4ArwUvymvvMnN9M5WWuiryYQe9M+UJrkqw4trdyRA==} + emnapi@1.8.1: + resolution: {integrity: sha512-34i2BbgHx1LnEO4JCGQYo6h6s4e4KrdWtdTHfllBNLbXSHPmdIHplxKejfabsRK+ukNciqVdalB+fxMibqHdaQ==} peerDependencies: node-addon-api: '>= 6.1.0' peerDependenciesMeta: @@ -2850,8 +3055,8 @@ packages: emoji-regex@9.2.2: resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} - enhanced-resolve@5.18.4: - resolution: {integrity: sha512-LgQMM4WXU3QI+SYgEc2liRgznaD5ojbmY3sb8LxyguVkIg5FxdpTkvk72te2R38/TGKxH634oLxXRGY6d7AP+Q==} + enhanced-resolve@5.19.0: + resolution: {integrity: sha512-phv3E1Xl4tQOShqSte26C7Fl84EwUdZsyOuSSk9qtAGyyQs2s3jJzComh+Abf4g187lUUAvH+H26omrqia2aGg==} engines: {node: '>=10.13.0'} es-abstract@1.24.0: @@ -2873,6 +3078,9 @@ packages: es-module-lexer@1.7.0: resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==} + es-module-lexer@2.0.0: + resolution: {integrity: sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw==} + es-object-atoms@1.1.1: resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} engines: {node: '>= 0.4'} @@ -2915,8 +3123,8 @@ packages: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} engines: {node: '>=10'} - eslint-config-next@16.1.0: - resolution: {integrity: sha512-RlPb8E2uO/Ix/w3kizxz6+6ogw99WqtNzTG0ArRZ5NEkIYcsfRb8U0j7aTG7NjRvcrsak5QtUSuxGNN2UcA58g==} + eslint-config-next@16.1.6: + resolution: {integrity: sha512-vKq40io2B0XtkkNDYyleATwblNt8xuh3FWp8SpSz3pt7P01OkBFlKsJZ2mWt5WsCySlDQLckb1zMY9yE9Qy0LA==} peerDependencies: eslint: '>=9.0.0' typescript: '>=3.3.1' @@ -2989,6 +3197,10 @@ packages: peerDependencies: eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7 + eslint-scope@5.1.1: + resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} + engines: {node: '>=8.0.0'} + eslint-scope@8.4.0: resolution: {integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -3023,6 +3235,10 @@ packages: resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} engines: {node: '>=4.0'} + estraverse@4.3.0: + resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==} + engines: {node: '>=4.0'} + estraverse@5.3.0: resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} engines: {node: '>=4.0'} @@ -3034,6 +3250,10 @@ packages: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} engines: {node: '>=0.10.0'} + events@3.3.0: + resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} + engines: {node: '>=0.8.x'} + execa@8.0.1: resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} engines: {node: '>=16.17'} @@ -3069,6 +3289,9 @@ packages: fast-stringify@4.0.0: resolution: {integrity: sha512-lE2DIivBaLysf6hK5WH/VfMgqRbvBVHcpGVVTmA5Zi8oWIjq9YxIt6lYGdUgP1HNSXxTIat7HEIDnrSvXSeKQw==} + fast-uri@3.1.0: + resolution: {integrity: sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==} + fastq@1.17.1: resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} @@ -3180,8 +3403,12 @@ packages: resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} engines: {node: '>=10.13.0'} + glob-to-regexp@0.4.1: + resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} + glob@10.4.5: resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me hasBin: true globals@14.0.0: @@ -3210,8 +3437,8 @@ packages: graphemer@1.4.0: resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} - h3@1.15.4: - resolution: {integrity: sha512-z5cFQWDffyOe4vQ9xIqNfCZdV4p//vy6fBnr8Q1AWnVZ0teurKMG66rLj++TKwKPUP3u7iMUvrvKaEUiQw2QWQ==} + h3@1.15.5: + resolution: {integrity: sha512-xEyq3rSl+dhGX2Lm0+eFQIAzlDN6Fs0EcC4f7BNUmzaRX/PTzeuM+Tr2lHB8FoXggsQIeXLj8EDVgs5ywxyxmg==} has-bigints@1.0.2: resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==} @@ -3430,6 +3657,10 @@ packages: jackspeak@3.4.3: resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} + jest-worker@27.5.1: + resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==} + engines: {node: '>= 10.13.0'} + jiti@1.21.6: resolution: {integrity: sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==} hasBin: true @@ -3461,9 +3692,15 @@ packages: json-buffer@3.0.1: resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + json-parse-even-better-errors@2.3.1: + resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + json-schema-traverse@0.4.1: resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + json-schema-traverse@1.0.0: + resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + json-stable-stringify-without-jsonify@1.0.1: resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} @@ -3494,67 +3731,74 @@ packages: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} - lightningcss-android-arm64@1.30.2: - resolution: {integrity: sha512-BH9sEdOCahSgmkVhBLeU7Hc9DWeZ1Eb6wNS6Da8igvUwAe0sqROHddIlvU06q3WyXVEOYDZ6ykBZQnjTbmo4+A==} + lightningcss-android-arm64@1.31.1: + resolution: {integrity: sha512-HXJF3x8w9nQ4jbXRiNppBCqeZPIAfUo8zE/kOEGbW5NZvGc/K7nMxbhIr+YlFlHW5mpbg/YFPdbnCh1wAXCKFg==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [android] - lightningcss-darwin-arm64@1.30.2: - resolution: {integrity: sha512-ylTcDJBN3Hp21TdhRT5zBOIi73P6/W0qwvlFEk22fkdXchtNTOU4Qc37SkzV+EKYxLouZ6M4LG9NfZ1qkhhBWA==} + lightningcss-darwin-arm64@1.31.1: + resolution: {integrity: sha512-02uTEqf3vIfNMq3h/z2cJfcOXnQ0GRwQrkmPafhueLb2h7mqEidiCzkE4gBMEH65abHRiQvhdcQ+aP0D0g67sg==} engines: {node: '>= 12.0.0'} + cpu: [arm64] os: [darwin] - lightningcss-darwin-x64@1.30.2: - resolution: {integrity: sha512-oBZgKchomuDYxr7ilwLcyms6BCyLn0z8J0+ZZmfpjwg9fRVZIR5/GMXd7r9RH94iDhld3UmSjBM6nXWM2TfZTQ==} + lightningcss-darwin-x64@1.31.1: + resolution: {integrity: sha512-1ObhyoCY+tGxtsz1lSx5NXCj3nirk0Y0kB/g8B8DT+sSx4G9djitg9ejFnjb3gJNWo7qXH4DIy2SUHvpoFwfTA==} engines: {node: '>= 12.0.0'} + cpu: [x64] os: [darwin] - lightningcss-freebsd-x64@1.30.2: - resolution: {integrity: sha512-c2bH6xTrf4BDpK8MoGG4Bd6zAMZDAXS569UxCAGcA7IKbHNMlhGQ89eRmvpIUGfKWNVdbhSbkQaWhEoMGmGslA==} + lightningcss-freebsd-x64@1.31.1: + resolution: {integrity: sha512-1RINmQKAItO6ISxYgPwszQE1BrsVU5aB45ho6O42mu96UiZBxEXsuQ7cJW4zs4CEodPUioj/QrXW1r9pLUM74A==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [freebsd] - lightningcss-linux-arm-gnueabihf@1.30.2: - resolution: {integrity: sha512-eVdpxh4wYcm0PofJIZVuYuLiqBIakQ9uFZmipf6LF/HRj5Bgm0eb3qL/mr1smyXIS1twwOxNWndd8z0E374hiA==} + lightningcss-linux-arm-gnueabihf@1.31.1: + resolution: {integrity: sha512-OOCm2//MZJ87CdDK62rZIu+aw9gBv4azMJuA8/KB74wmfS3lnC4yoPHm0uXZ/dvNNHmnZnB8XLAZzObeG0nS1g==} engines: {node: '>= 12.0.0'} cpu: [arm] os: [linux] - lightningcss-linux-arm64-gnu@1.30.2: - resolution: {integrity: sha512-UK65WJAbwIJbiBFXpxrbTNArtfuznvxAJw4Q2ZGlU8kPeDIWEX1dg3rn2veBVUylA2Ezg89ktszWbaQnxD/e3A==} + lightningcss-linux-arm64-gnu@1.31.1: + resolution: {integrity: sha512-WKyLWztD71rTnou4xAD5kQT+982wvca7E6QoLpoawZ1gP9JM0GJj4Tp5jMUh9B3AitHbRZ2/H3W5xQmdEOUlLg==} engines: {node: '>= 12.0.0'} + cpu: [arm64] os: [linux] - lightningcss-linux-arm64-musl@1.30.2: - resolution: {integrity: sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA==} + lightningcss-linux-arm64-musl@1.31.1: + resolution: {integrity: sha512-mVZ7Pg2zIbe3XlNbZJdjs86YViQFoJSpc41CbVmKBPiGmC4YrfeOyz65ms2qpAobVd7WQsbW4PdsSJEMymyIMg==} engines: {node: '>= 12.0.0'} + cpu: [arm64] os: [linux] - lightningcss-linux-x64-gnu@1.30.2: - resolution: {integrity: sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w==} + lightningcss-linux-x64-gnu@1.31.1: + resolution: {integrity: sha512-xGlFWRMl+0KvUhgySdIaReQdB4FNudfUTARn7q0hh/V67PVGCs3ADFjw+6++kG1RNd0zdGRlEKa+T13/tQjPMA==} engines: {node: '>= 12.0.0'} + cpu: [x64] os: [linux] - lightningcss-linux-x64-musl@1.30.2: - resolution: {integrity: sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA==} + lightningcss-linux-x64-musl@1.31.1: + resolution: {integrity: sha512-eowF8PrKHw9LpoZii5tdZwnBcYDxRw2rRCyvAXLi34iyeYfqCQNA9rmUM0ce62NlPhCvof1+9ivRaTY6pSKDaA==} engines: {node: '>= 12.0.0'} + cpu: [x64] os: [linux] - lightningcss-win32-arm64-msvc@1.30.2: - resolution: {integrity: sha512-FZn+vaj7zLv//D/192WFFVA0RgHawIcHqLX9xuWiQt7P0PtdFEVaxgF9rjM/IRYHQXNnk61/H/gb2Ei+kUQ4xQ==} + lightningcss-win32-arm64-msvc@1.31.1: + resolution: {integrity: sha512-aJReEbSEQzx1uBlQizAOBSjcmr9dCdL3XuC/6HLXAxmtErsj2ICo5yYggg1qOODQMtnjNQv2UHb9NpOuFtYe4w==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [win32] - lightningcss-win32-x64-msvc@1.30.2: - resolution: {integrity: sha512-5g1yc73p+iAkid5phb4oVFMB45417DkRevRbt/El/gKXJk4jid+vPFF/AXbxn05Aky8PapwzZrdJShv5C0avjw==} + lightningcss-win32-x64-msvc@1.31.1: + resolution: {integrity: sha512-I9aiFrbd7oYHwlnQDqr1Roz+fTz61oDDJX7n9tYF9FJymH1cIN1DtKw3iYt6b8WZgEjoNwVSncwF4wx/ZedMhw==} engines: {node: '>= 12.0.0'} + cpu: [x64] os: [win32] - lightningcss@1.30.2: - resolution: {integrity: sha512-utfs7Pr5uJyyvDETitgsaqSyjCb2qNRAtuqUeWIAKztsOYdcACf2KtARYXg2pSvhkt+9NfoaNY7fxjl6nuMjIQ==} + lightningcss@1.31.1: + resolution: {integrity: sha512-l51N2r93WmGUye3WuFoN5k10zyvrVs0qfKBhyC5ogUQ6Ew6JUSswh78mbSO+IU3nTWsyOArqPCcShdQSadghBQ==} engines: {node: '>= 12.0.0'} lilconfig@2.1.0: @@ -3576,6 +3820,10 @@ packages: resolution: {integrity: sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + loader-runner@4.3.1: + resolution: {integrity: sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q==} + engines: {node: '>=6.11.5'} + locate-path@6.0.0: resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} engines: {node: '>=10'} @@ -3618,6 +3866,14 @@ packages: resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} engines: {node: '>=8.6'} + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + mimic-fn@4.0.0: resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} engines: {node: '>=12'} @@ -3665,16 +3921,14 @@ packages: engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true - nanoid@3.3.7: - resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} - engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} - hasBin: true - natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} - next@16.1.0: - resolution: {integrity: sha512-Y+KbmDbefYtHDDQKLNrmzE/YYzG2msqo2VXhzh5yrJ54tx/6TmGdkR5+kP9ma7i7LwZpZMfoY3m/AoPPPKxtVw==} + neo-async@2.6.2: + resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} + + next@16.1.6: + resolution: {integrity: sha512-hkyRkcu5x/41KoqnROkfTm2pZVbKxvbZRuNvKXLRXxs3VfyO0WhY50TQS40EuKO9SW3rBj/sF3WbVwDACeMZyw==} engines: {node: '>=20.9.0'} hasBin: true peerDependencies: @@ -3717,8 +3971,8 @@ packages: resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==} hasBin: true - node-mock-http@1.0.2: - resolution: {integrity: sha512-zWaamgDUdo9SSLw47we78+zYw/bDr5gH8pH7oRRs8V3KmBtu8GLgGIbV2p/gRPd3LWpEOpjQj7X1FOU3VFMJ8g==} + node-mock-http@1.0.4: + resolution: {integrity: sha512-8DY+kFsDkNXy1sJglUfuODx1/opAGJGyrTuFqEoN90oRc2Vk0ZbD4K2qmKXBBEhZQzdKHIVfEJpDU8Ak2NJEvQ==} node-releases@2.0.27: resolution: {integrity: sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==} @@ -3767,6 +4021,9 @@ packages: resolution: {integrity: sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==} engines: {node: '>= 0.4'} + obug@2.1.1: + resolution: {integrity: sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==} + onetime@6.0.0: resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} engines: {node: '>=12'} @@ -3853,13 +4110,13 @@ packages: pkg-types@1.3.0: resolution: {integrity: sha512-kS7yWjVFCkIw9hqdJBoMxDdzEngmkr5FXeWZZfQ6GoYacjVnsW6l2CcYW/0ThD0vF4LPJgVYnrg4d0uuhwYQbg==} - playwright-core@1.57.0: - resolution: {integrity: sha512-agTcKlMw/mjBWOnD6kFZttAAGHgi/Nw0CZ2o6JqWSbMlI219lAFLZZCyqByTsvVAJq5XA5H8cA6PrvBRpBWEuQ==} + playwright-core@1.58.0: + resolution: {integrity: sha512-aaoB1RWrdNi3//rOeKuMiS65UCcgOVljU46At6eFcOFPFHWtd2weHRRow6z/n+Lec0Lvu0k9ZPKJSjPugikirw==} engines: {node: '>=18'} hasBin: true - playwright@1.57.0: - resolution: {integrity: sha512-ilYQj1s8sr2ppEJ2YVadYBN0Mb3mdo9J0wQ+UuDhzYqURwSoW4n1Xs5vs7ORwgDGmyEh33tRMeS8KhdkMoLXQw==} + playwright@1.58.0: + resolution: {integrity: sha512-2SVA0sbPktiIY/MCOPX8e86ehA/e+tDNq+e5Y8qjKYti2Z/JG7xnronT/TXTIkKbYGWlCbuucZ6dziEgkoEjQQ==} engines: {node: '>=18'} hasBin: true @@ -3940,14 +4197,6 @@ packages: resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==} engines: {node: ^10 || ^12 || >=14} - postcss@8.4.41: - resolution: {integrity: sha512-TesUflQ0WKZqAvg52PWL6kHgLKP6xB6heTOdoYM0Wt2UHyxNa4K25EZZMgKns3BH1RLVbZCREPpLY0rhnNoHVQ==} - engines: {node: ^10 || ^12 || >=14} - - postcss@8.4.47: - resolution: {integrity: sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==} - engines: {node: ^10 || ^12 || >=14} - postcss@8.5.6: resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} engines: {node: ^10 || ^12 || >=14} @@ -3969,8 +4218,8 @@ packages: vue-tsc: optional: true - prettier@3.6.2: - resolution: {integrity: sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==} + prettier@3.8.1: + resolution: {integrity: sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==} engines: {node: '>=14'} hasBin: true @@ -3987,10 +4236,13 @@ packages: radix3@1.1.2: resolution: {integrity: sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA==} - react-dom@19.2.3: - resolution: {integrity: sha512-yELu4WmLPw5Mr/lmeEpox5rw3RETacE++JgHqQzd2dg+YbJuat3jH4ingc+WPZhxaoFzdv9y33G+F7Nl5O0GBg==} + randombytes@2.1.0: + resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} + + react-dom@19.2.4: + resolution: {integrity: sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==} peerDependencies: - react: ^19.2.3 + react: ^19.2.4 react-is@16.13.1: resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} @@ -3999,8 +4251,8 @@ packages: resolution: {integrity: sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw==} engines: {node: '>=0.10.0'} - react@19.2.3: - resolution: {integrity: sha512-Ku/hhYbVjOQnXDZFv2+RibmLFGwFdeeKHFcOTlrt7xplBnya5OGn/hIRDsqDiSUcfORsDC7MPxwork8jBwsIWA==} + react@19.2.4: + resolution: {integrity: sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==} engines: {node: '>=0.10.0'} read-cache@1.0.0: @@ -4022,6 +4274,10 @@ packages: resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==} engines: {node: '>= 0.4'} + require-from-string@2.0.2: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + engines: {node: '>=0.10.0'} + resolve-from@4.0.0: resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} engines: {node: '>=4'} @@ -4057,6 +4313,9 @@ packages: resolution: {integrity: sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==} engines: {node: '>=0.4'} + safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + safe-push-apply@1.0.0: resolution: {integrity: sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==} engines: {node: '>= 0.4'} @@ -4071,6 +4330,10 @@ packages: scheduler@0.27.0: resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==} + schema-utils@4.3.3: + resolution: {integrity: sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==} + engines: {node: '>= 10.13.0'} + semver@6.3.1: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true @@ -4080,6 +4343,14 @@ packages: engines: {node: '>=10'} hasBin: true + semver@7.7.4: + resolution: {integrity: sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==} + engines: {node: '>=10'} + hasBin: true + + serialize-javascript@6.0.2: + resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==} + set-function-length@1.2.2: resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} engines: {node: '>= 0.4'} @@ -4232,6 +4503,10 @@ packages: resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} engines: {node: '>=8'} + supports-color@8.1.1: + resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} + engines: {node: '>=10'} + supports-preserve-symlinks-flag@1.0.0: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} @@ -4249,10 +4524,26 @@ packages: engines: {node: '>=14.0.0'} hasBin: true - tapable@2.2.1: - resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} + tapable@2.3.0: + resolution: {integrity: sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==} engines: {node: '>=6'} + terser-webpack-plugin@5.3.16: + resolution: {integrity: sha512-h9oBFCWrq78NyWWVcSwZarJkZ01c2AyGrzs1crmHZO3QUg9D61Wu4NPjBy69n7JqylFF5y+CsUZYmYEIZ3mR+Q==} + engines: {node: '>= 10.13.0'} + peerDependencies: + '@swc/core': '*' + esbuild: '*' + uglify-js: '*' + webpack: ^5.1.0 + peerDependenciesMeta: + '@swc/core': + optional: true + esbuild: + optional: true + uglify-js: + optional: true + terser@5.31.6: resolution: {integrity: sha512-PQ4DAriWzKj+qgehQ7LK5bQqCFNMmlhjR2PFFLuqGCpuCAauxemVBWwWOxo3UIwWQx8+Pr61Df++r76wDmkQBg==} engines: {node: '>=10'} @@ -4274,6 +4565,10 @@ packages: tinyexec@0.3.2: resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} + tinyexec@1.0.2: + resolution: {integrity: sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==} + engines: {node: '>=18'} + tinyglobby@0.2.14: resolution: {integrity: sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==} engines: {node: '>=12.0.0'} @@ -4352,38 +4647,38 @@ packages: engines: {node: '>=18.0.0'} hasBin: true - turbo-darwin-64@2.7.2: - resolution: {integrity: sha512-dxY3X6ezcT5vm3coK6VGixbrhplbQMwgNsCsvZamS/+/6JiebqW9DKt4NwpgYXhDY2HdH00I7FWs3wkVuan4rA==} + turbo-darwin-64@2.7.6: + resolution: {integrity: sha512-bYu0qnWju2Ha3EbIkPCk1SMLT3sltKh1P/Jy5FER6BmH++H5z+T5MHh3W1Xoers9rk4N1VdKvog9FO1pxQyjhw==} cpu: [x64] os: [darwin] - turbo-darwin-arm64@2.7.2: - resolution: {integrity: sha512-1bXmuwPLqNFt3mzrtYcVx1sdJ8UYb124Bf48nIgcpMCGZy3kDhgxNv1503kmuK/37OGOZbsWSQFU4I08feIuSg==} + turbo-darwin-arm64@2.7.6: + resolution: {integrity: sha512-KCxTf3Y1hgNLYIWRLw8bwH8Zie9RyCGoxAlXYsCBI/YNqBSR+ZZK9KYzFxAqDaVaNvTwLFv3rJRGsXOFWg4+Uw==} cpu: [arm64] os: [darwin] - turbo-linux-64@2.7.2: - resolution: {integrity: sha512-kP+TiiMaiPugbRlv57VGLfcjFNsFbo8H64wMBCPV2270Or2TpDCBULMzZrvEsvWFjT3pBFvToYbdp8/Kw0jAQg==} + turbo-linux-64@2.7.6: + resolution: {integrity: sha512-vjoU8zIfNgvJR3cMitgw7inEoi6bmuVuFawDl5yKtxjAEhDktFdRBpGS3WojD4l3BklBbIK689ssXcGf21LxRA==} cpu: [x64] os: [linux] - turbo-linux-arm64@2.7.2: - resolution: {integrity: sha512-VDJwQ0+8zjAfbyY6boNaWfP6RIez4ypKHxwkuB6SrWbOSk+vxTyW5/hEjytTwK8w/TsbKVcMDyvpora8tEsRFw==} + turbo-linux-arm64@2.7.6: + resolution: {integrity: sha512-TcMpBvTqZf+1DptrVYLbZls7WY1UVNDTGaf0bo7/GCgWYv5eZHCVo4Td7kCJeDU4glbXg67REX0md0S0V6ghMg==} cpu: [arm64] os: [linux] - turbo-windows-64@2.7.2: - resolution: {integrity: sha512-rPjqQXVnI6A6oxgzNEE8DNb6Vdj2Wwyhfv3oDc+YM3U9P7CAcBIlKv/868mKl4vsBtz4ouWpTQNXG8vljgJO+w==} + turbo-windows-64@2.7.6: + resolution: {integrity: sha512-1/MhkYldiihjneY8QnnDMbAkHXn/udTWSVYS94EMlkE9AShozsLTTOT1gDOpX06EfEW5njP09suhMvxbvwuwpQ==} cpu: [x64] os: [win32] - turbo-windows-arm64@2.7.2: - resolution: {integrity: sha512-tcnHvBhO515OheIFWdxA+qUvZzNqqcHbLVFc1+n+TJ1rrp8prYicQtbtmsiKgMvr/54jb9jOabU62URAobnB7g==} + turbo-windows-arm64@2.7.6: + resolution: {integrity: sha512-0wDVnUJLFAWm4ZzOQFDkbyyUqaszorTGf3Rdc22IRIyJTTLd6ajqdb+cWD89UZ1RKr953+PZR1gqgWQY4PDuhA==} cpu: [arm64] os: [win32] - turbo@2.7.2: - resolution: {integrity: sha512-5JIA5aYBAJSAhrhbyag1ZuMSgUZnHtI+Sq3H8D3an4fL8PeF+L1yYvbEJg47akP1PFfATMf5ehkqFnxfkmuwZQ==} + turbo@2.7.6: + resolution: {integrity: sha512-PO9AvJLEsNLO+EYhF4zB+v10hOjsJe5kJW+S6tTbRv+TW7gf1Qer4mfjP9h3/y9h8ZiPvOrenxnEgDtFgaM5zw==} hasBin: true typanion@3.14.0: @@ -4425,8 +4720,8 @@ packages: engines: {node: '>=14.17'} hasBin: true - typescript@5.6.3: - resolution: {integrity: sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==} + typescript@5.9.3: + resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} engines: {node: '>=14.17'} hasBin: true @@ -4436,6 +4731,9 @@ packages: ufo@1.6.1: resolution: {integrity: sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==} + ufo@1.6.3: + resolution: {integrity: sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q==} + unbox-primitive@1.1.0: resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} engines: {node: '>= 0.4'} @@ -4443,9 +4741,6 @@ packages: uncrypto@0.1.3: resolution: {integrity: sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==} - undici-types@5.26.5: - resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} - undici-types@6.21.0: resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} @@ -4521,19 +4816,58 @@ packages: yaml: optional: true - vitest@4.0.12: - resolution: {integrity: sha512-pmW4GCKQ8t5Ko1jYjC3SqOr7TUKN7uHOHB/XGsAIb69eYu6d1ionGSsb5H9chmPf+WeXt0VE7jTXsB1IvWoNbw==} + vite@7.3.1: + resolution: {integrity: sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + peerDependencies: + '@types/node': ^20.19.0 || >=22.12.0 + jiti: '>=1.21.0' + less: ^4.0.0 + lightningcss: ^1.21.0 + sass: ^1.70.0 + sass-embedded: ^1.70.0 + stylus: '>=0.54.8' + sugarss: ^5.0.0 + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + '@types/node': + optional: true + jiti: + optional: true + less: + optional: true + lightningcss: + 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.0.18: + resolution: {integrity: sha512-hOQuK7h0FGKgBAas7v0mSAsnvrIgAvWmRFjmzpJ7SwFHH3g1k2u37JtYwOwmEKhK6ZO3v9ggDBBm0La1LCK4uQ==} engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0} hasBin: true peerDependencies: '@edge-runtime/vm': '*' '@opentelemetry/api': ^1.9.0 - '@types/debug': ^4.1.12 '@types/node': ^20.0.0 || ^22.0.0 || >=24.0.0 - '@vitest/browser-playwright': 4.0.12 - '@vitest/browser-preview': 4.0.12 - '@vitest/browser-webdriverio': 4.0.12 - '@vitest/ui': 4.0.12 + '@vitest/browser-playwright': 4.0.18 + '@vitest/browser-preview': 4.0.18 + '@vitest/browser-webdriverio': 4.0.18 + '@vitest/ui': 4.0.18 happy-dom: '*' jsdom: '*' peerDependenciesMeta: @@ -4541,8 +4875,6 @@ packages: optional: true '@opentelemetry/api': optional: true - '@types/debug': - optional: true '@types/node': optional: true '@vitest/browser-playwright': @@ -4558,6 +4890,24 @@ packages: jsdom: optional: true + watchpack@2.5.1: + resolution: {integrity: sha512-Zn5uXdcFNIA1+1Ei5McRd+iRzfhENPCe7LeABkJtNulSxjma+l7ltNx55BWZkRlwRnpOgHqxnjyaDgJnNXnqzg==} + engines: {node: '>=10.13.0'} + + webpack-sources@3.3.3: + resolution: {integrity: sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg==} + engines: {node: '>=10.13.0'} + + webpack@5.104.1: + resolution: {integrity: sha512-Qphch25abbMNtekmEGJmeRUhLDbe+QfiWTiqpKYkpCOWY64v9eyl+KRRLmqOFA2AvKPpc9DC6+u2n76tQLBoaA==} + engines: {node: '>=10.13.0'} + hasBin: true + peerDependencies: + webpack-cli: '*' + peerDependenciesMeta: + webpack-cli: + optional: true + which-boxed-primitive@1.1.1: resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==} engines: {node: '>= 0.4'} @@ -4635,8 +4985,16 @@ snapshots: js-tokens: 4.0.0 picocolors: 1.1.1 + '@babel/code-frame@7.29.0': + dependencies: + '@babel/helper-validator-identifier': 7.28.5 + js-tokens: 4.0.0 + picocolors: 1.1.1 + '@babel/compat-data@7.27.5': {} + '@babel/compat-data@7.29.0': {} + '@babel/core@7.28.5': dependencies: '@babel/code-frame': 7.27.1 @@ -4657,11 +5015,39 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/generator@7.28.5': - dependencies: - '@babel/parser': 7.28.5 - '@babel/types': 7.28.5 - '@jridgewell/gen-mapping': 0.3.12 + '@babel/core@7.29.0': + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/generator': 7.29.1 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) + '@babel/helpers': 7.28.6 + '@babel/parser': 7.29.0 + '@babel/template': 7.28.6 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + '@jridgewell/remapping': 2.3.5 + convert-source-map: 2.0.0 + debug: 4.4.3 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/generator@7.28.5': + dependencies: + '@babel/parser': 7.28.5 + '@babel/types': 7.28.5 + '@jridgewell/gen-mapping': 0.3.12 + '@jridgewell/trace-mapping': 0.3.29 + jsesc: 3.1.0 + + '@babel/generator@7.29.1': + dependencies: + '@babel/parser': 7.29.0 + '@babel/types': 7.29.0 + '@jridgewell/gen-mapping': 0.3.12 '@jridgewell/trace-mapping': 0.3.29 jsesc: 3.1.0 @@ -4673,6 +5059,14 @@ snapshots: lru-cache: 5.1.1 semver: 6.3.1 + '@babel/helper-compilation-targets@7.28.6': + dependencies: + '@babel/compat-data': 7.29.0 + '@babel/helper-validator-option': 7.27.1 + browserslist: 4.28.1 + lru-cache: 5.1.1 + semver: 6.3.1 + '@babel/helper-globals@7.28.0': {} '@babel/helper-module-imports@7.27.1': @@ -4682,6 +5076,13 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/helper-module-imports@7.28.6': + dependencies: + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + transitivePeerDependencies: + - supports-color + '@babel/helper-module-transforms@7.28.3(@babel/core@7.28.5)': dependencies: '@babel/core': 7.28.5 @@ -4691,6 +5092,15 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/helper-module-transforms@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-module-imports': 7.28.6 + '@babel/helper-validator-identifier': 7.28.5 + '@babel/traverse': 7.29.0 + transitivePeerDependencies: + - supports-color + '@babel/helper-plugin-utils@7.27.1': {} '@babel/helper-string-parser@7.27.1': {} @@ -4704,18 +5114,27 @@ snapshots: '@babel/template': 7.27.2 '@babel/types': 7.28.5 + '@babel/helpers@7.28.6': + dependencies: + '@babel/template': 7.28.6 + '@babel/types': 7.29.0 + '@babel/parser@7.28.5': dependencies: '@babel/types': 7.28.5 - '@babel/plugin-transform-react-jsx-self@7.27.1(@babel/core@7.28.5)': + '@babel/parser@7.29.0': dependencies: - '@babel/core': 7.28.5 + '@babel/types': 7.29.0 + + '@babel/plugin-transform-react-jsx-self@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-react-jsx-source@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-react-jsx-source@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.27.1 '@babel/template@7.27.2': @@ -4724,6 +5143,12 @@ snapshots: '@babel/parser': 7.28.5 '@babel/types': 7.28.5 + '@babel/template@7.28.6': + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/parser': 7.29.0 + '@babel/types': 7.29.0 + '@babel/traverse@7.28.5': dependencies: '@babel/code-frame': 7.27.1 @@ -4736,20 +5161,46 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/traverse@7.29.0': + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/generator': 7.29.1 + '@babel/helper-globals': 7.28.0 + '@babel/parser': 7.29.0 + '@babel/template': 7.28.6 + '@babel/types': 7.29.0 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + '@babel/types@7.28.5': dependencies: '@babel/helper-string-parser': 7.27.1 '@babel/helper-validator-identifier': 7.28.5 + '@babel/types@7.29.0': + dependencies: + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.28.5 + '@emnapi/core@1.7.1': dependencies: '@emnapi/wasi-threads': 1.1.0 tslib: 2.8.1 + '@emnapi/core@1.8.1': + dependencies: + '@emnapi/wasi-threads': 1.1.0 + tslib: 2.8.1 + '@emnapi/runtime@1.7.1': dependencies: tslib: 2.8.1 + '@emnapi/runtime@1.8.1': + dependencies: + tslib: 2.8.1 + '@emnapi/wasi-threads@1.1.0': dependencies: tslib: 2.8.1 @@ -5123,7 +5574,7 @@ snapshots: '@img/sharp-wasm32@0.34.5': dependencies: - '@emnapi/runtime': 1.7.1 + '@emnapi/runtime': 1.8.1 optional: true '@img/sharp-win32-arm64@0.34.5': @@ -5271,7 +5722,7 @@ snapshots: '@jridgewell/gen-mapping@0.3.12': dependencies: - '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/sourcemap-codec': 1.5.5 '@jridgewell/trace-mapping': 0.3.29 '@jridgewell/gen-mapping@0.3.5': @@ -5293,9 +5744,6 @@ snapshots: dependencies: '@jridgewell/gen-mapping': 0.3.12 '@jridgewell/trace-mapping': 0.3.29 - optional: true - - '@jridgewell/sourcemap-codec@1.5.0': {} '@jridgewell/sourcemap-codec@1.5.5': {} @@ -5307,9 +5755,9 @@ snapshots: '@jridgewell/trace-mapping@0.3.29': dependencies: '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/sourcemap-codec': 1.5.5 - '@napi-rs/cli@3.4.1(@emnapi/runtime@1.7.1)(@types/node@20.19.1)(node-addon-api@8.3.0)': + '@napi-rs/cli@3.4.1(@emnapi/runtime@1.8.1)(@types/node@20.19.1)(node-addon-api@8.3.0)': dependencies: '@inquirer/prompts': 7.10.1(@types/node@20.19.1) '@napi-rs/cross-toolchain': 1.0.3 @@ -5318,13 +5766,13 @@ snapshots: clipanion: 4.0.0-rc.4(typanion@3.14.0) colorette: 2.0.20 debug: 4.4.3 - emnapi: 1.7.1(node-addon-api@8.3.0) + emnapi: 1.8.1(node-addon-api@8.3.0) es-toolkit: 1.43.0 js-yaml: 4.1.0 semver: 7.7.3 typanion: 3.14.0 optionalDependencies: - '@emnapi/runtime': 1.7.1 + '@emnapi/runtime': 1.8.1 transitivePeerDependencies: - '@napi-rs/cross-toolchain-arm64-target-aarch64' - '@napi-rs/cross-toolchain-arm64-target-armv7' @@ -5553,34 +6001,34 @@ snapshots: '@napi-rs/wasm-tools-win32-ia32-msvc': 1.0.1 '@napi-rs/wasm-tools-win32-x64-msvc': 1.0.1 - '@next/env@16.1.0': {} + '@next/env@16.1.6': {} - '@next/eslint-plugin-next@16.1.0': + '@next/eslint-plugin-next@16.1.6': dependencies: fast-glob: 3.3.1 - '@next/swc-darwin-arm64@16.1.0': + '@next/swc-darwin-arm64@16.1.6': optional: true - '@next/swc-darwin-x64@16.1.0': + '@next/swc-darwin-x64@16.1.6': optional: true - '@next/swc-linux-arm64-gnu@16.1.0': + '@next/swc-linux-arm64-gnu@16.1.6': optional: true - '@next/swc-linux-arm64-musl@16.1.0': + '@next/swc-linux-arm64-musl@16.1.6': optional: true - '@next/swc-linux-x64-gnu@16.1.0': + '@next/swc-linux-x64-gnu@16.1.6': optional: true - '@next/swc-linux-x64-musl@16.1.0': + '@next/swc-linux-x64-musl@16.1.6': optional: true - '@next/swc-win32-arm64-msvc@16.1.0': + '@next/swc-win32-arm64-msvc@16.1.6': optional: true - '@next/swc-win32-x64-msvc@16.1.0': + '@next/swc-win32-x64-msvc@16.1.6': optional: true '@nodelib/fs.scandir@2.1.5': @@ -5659,37 +6107,37 @@ snapshots: dependencies: '@octokit/openapi-types': 27.0.0 - '@oven/bun-darwin-aarch64@1.3.5': + '@oven/bun-darwin-aarch64@1.3.9': optional: true - '@oven/bun-darwin-x64-baseline@1.3.5': + '@oven/bun-darwin-x64-baseline@1.3.9': optional: true - '@oven/bun-darwin-x64@1.3.5': + '@oven/bun-darwin-x64@1.3.9': optional: true - '@oven/bun-linux-aarch64-musl@1.3.5': + '@oven/bun-linux-aarch64-musl@1.3.9': optional: true - '@oven/bun-linux-aarch64@1.3.5': + '@oven/bun-linux-aarch64@1.3.9': optional: true - '@oven/bun-linux-x64-baseline@1.3.5': + '@oven/bun-linux-x64-baseline@1.3.9': optional: true - '@oven/bun-linux-x64-musl-baseline@1.3.5': + '@oven/bun-linux-x64-musl-baseline@1.3.9': optional: true - '@oven/bun-linux-x64-musl@1.3.5': + '@oven/bun-linux-x64-musl@1.3.9': optional: true - '@oven/bun-linux-x64@1.3.5': + '@oven/bun-linux-x64@1.3.9': optional: true - '@oven/bun-windows-x64-baseline@1.3.5': + '@oven/bun-windows-x64-baseline@1.3.9': optional: true - '@oven/bun-windows-x64@1.3.5': + '@oven/bun-windows-x64@1.3.9': optional: true '@parcel/watcher-android-arm64@2.5.0': @@ -5701,12 +6149,18 @@ snapshots: '@parcel/watcher-darwin-arm64@2.5.0': optional: true - '@parcel/watcher-darwin-arm64@2.5.1': {} + '@parcel/watcher-darwin-arm64@2.5.1': + optional: true + + '@parcel/watcher-darwin-arm64@2.5.6': {} '@parcel/watcher-darwin-x64@2.5.0': optional: true - '@parcel/watcher-darwin-x64@2.5.1': {} + '@parcel/watcher-darwin-x64@2.5.1': + optional: true + + '@parcel/watcher-darwin-x64@2.5.6': {} '@parcel/watcher-freebsd-x64@2.5.0': optional: true @@ -5729,22 +6183,34 @@ snapshots: '@parcel/watcher-linux-arm64-glibc@2.5.0': optional: true - '@parcel/watcher-linux-arm64-glibc@2.5.1': {} + '@parcel/watcher-linux-arm64-glibc@2.5.1': + optional: true + + '@parcel/watcher-linux-arm64-glibc@2.5.6': {} '@parcel/watcher-linux-arm64-musl@2.5.0': optional: true - '@parcel/watcher-linux-arm64-musl@2.5.1': {} + '@parcel/watcher-linux-arm64-musl@2.5.1': + optional: true + + '@parcel/watcher-linux-arm64-musl@2.5.6': {} '@parcel/watcher-linux-x64-glibc@2.5.0': optional: true - '@parcel/watcher-linux-x64-glibc@2.5.1': {} + '@parcel/watcher-linux-x64-glibc@2.5.1': + optional: true + + '@parcel/watcher-linux-x64-glibc@2.5.6': {} '@parcel/watcher-linux-x64-musl@2.5.0': optional: true - '@parcel/watcher-linux-x64-musl@2.5.1': {} + '@parcel/watcher-linux-x64-musl@2.5.1': + optional: true + + '@parcel/watcher-linux-x64-musl@2.5.6': {} '@parcel/watcher-wasm@2.5.0': dependencies: @@ -5766,7 +6232,10 @@ snapshots: '@parcel/watcher-win32-x64@2.5.0': optional: true - '@parcel/watcher-win32-x64@2.5.1': {} + '@parcel/watcher-win32-x64@2.5.1': + optional: true + + '@parcel/watcher-win32-x64@2.5.6': {} '@parcel/watcher@2.5.0': dependencies: @@ -5813,11 +6282,11 @@ snapshots: '@pkgjs/parseargs@0.11.0': optional: true - '@playwright/test@1.57.0': + '@playwright/test@1.58.0': dependencies: - playwright: 1.57.0 + playwright: 1.58.0 - '@rolldown/pluginutils@1.0.0-beta.53': {} + '@rolldown/pluginutils@1.0.0-rc.2': {} '@rollup/rollup-android-arm-eabi@4.44.0': optional: true @@ -5909,30 +6378,30 @@ snapshots: '@types/babel__core@7.20.5': dependencies: - '@babel/parser': 7.28.5 - '@babel/types': 7.28.5 + '@babel/parser': 7.29.0 + '@babel/types': 7.29.0 '@types/babel__generator': 7.6.8 '@types/babel__template': 7.4.4 '@types/babel__traverse': 7.20.6 '@types/babel__generator@7.6.8': dependencies: - '@babel/types': 7.28.5 + '@babel/types': 7.29.0 '@types/babel__template@7.4.4': dependencies: - '@babel/parser': 7.28.5 - '@babel/types': 7.28.5 + '@babel/parser': 7.29.0 + '@babel/types': 7.29.0 '@types/babel__traverse@7.20.6': dependencies: - '@babel/types': 7.28.5 + '@babel/types': 7.29.0 '@types/braces@3.0.5': {} - '@types/bun@1.3.5': + '@types/bun@1.3.9': dependencies: - bun-types: 1.3.5 + bun-types: 1.3.9 '@types/chai@5.2.3': dependencies: @@ -5941,107 +6410,75 @@ snapshots: '@types/deep-eql@4.0.2': {} + '@types/eslint-scope@3.7.7': + dependencies: + '@types/eslint': 9.6.1 + '@types/estree': 1.0.8 + + '@types/eslint@9.6.1': + dependencies: + '@types/estree': 1.0.8 + '@types/json-schema': 7.0.15 + '@types/estree@1.0.8': {} '@types/json-schema@7.0.15': {} '@types/json5@0.0.29': {} - '@types/node@20.14.13': - dependencies: - undici-types: 5.26.5 - '@types/node@20.19.1': dependencies: undici-types: 6.21.0 '@types/postcss-import@14.0.3': dependencies: - postcss: 8.4.41 + postcss: 8.5.6 - '@types/react-dom@19.2.3(@types/react@19.2.7)': + '@types/react-dom@19.2.3(@types/react@19.2.14)': dependencies: - '@types/react': 19.2.7 + '@types/react': 19.2.14 - '@types/react@19.2.7': + '@types/react@19.2.14': dependencies: csstype: 3.2.3 '@types/semver@7.7.1': {} - '@typescript-eslint/eslint-plugin@8.47.0(@typescript-eslint/parser@8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.5.4))(eslint@9.39.2(jiti@2.6.1))(typescript@5.5.4)': - dependencies: - '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.5.4) - '@typescript-eslint/scope-manager': 8.47.0 - '@typescript-eslint/type-utils': 8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.5.4) - '@typescript-eslint/utils': 8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.5.4) - '@typescript-eslint/visitor-keys': 8.47.0 - eslint: 9.39.2(jiti@2.6.1) - graphemer: 1.4.0 - ignore: 7.0.5 - natural-compare: 1.4.0 - ts-api-utils: 2.1.0(typescript@5.5.4) - typescript: 5.5.4 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/eslint-plugin@8.47.0(@typescript-eslint/parser@8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.6.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.6.3)': + '@typescript-eslint/eslint-plugin@8.47.0(@typescript-eslint/parser@8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)': dependencies: '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.6.3) + '@typescript-eslint/parser': 8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) '@typescript-eslint/scope-manager': 8.47.0 - '@typescript-eslint/type-utils': 8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.6.3) - '@typescript-eslint/utils': 8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.6.3) + '@typescript-eslint/type-utils': 8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/utils': 8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) '@typescript-eslint/visitor-keys': 8.47.0 eslint: 9.39.2(jiti@2.6.1) graphemer: 1.4.0 ignore: 7.0.5 natural-compare: 1.4.0 - ts-api-utils: 2.1.0(typescript@5.6.3) - typescript: 5.6.3 + ts-api-utils: 2.1.0(typescript@5.9.3) + typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.5.4)': + '@typescript-eslint/parser@8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)': dependencies: '@typescript-eslint/scope-manager': 8.47.0 '@typescript-eslint/types': 8.47.0 - '@typescript-eslint/typescript-estree': 8.47.0(typescript@5.5.4) + '@typescript-eslint/typescript-estree': 8.47.0(typescript@5.9.3) '@typescript-eslint/visitor-keys': 8.47.0 debug: 4.4.3 eslint: 9.39.2(jiti@2.6.1) - typescript: 5.5.4 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/parser@8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.6.3)': - dependencies: - '@typescript-eslint/scope-manager': 8.47.0 - '@typescript-eslint/types': 8.47.0 - '@typescript-eslint/typescript-estree': 8.47.0(typescript@5.6.3) - '@typescript-eslint/visitor-keys': 8.47.0 - debug: 4.4.3 - eslint: 9.39.2(jiti@2.6.1) - typescript: 5.6.3 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/project-service@8.47.0(typescript@5.5.4)': - dependencies: - '@typescript-eslint/tsconfig-utils': 8.47.0(typescript@5.5.4) - '@typescript-eslint/types': 8.47.0 - debug: 4.4.3 - typescript: 5.5.4 + typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/project-service@8.47.0(typescript@5.6.3)': + '@typescript-eslint/project-service@8.47.0(typescript@5.9.3)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.47.0(typescript@5.6.3) + '@typescript-eslint/tsconfig-utils': 8.47.0(typescript@5.9.3) '@typescript-eslint/types': 8.47.0 debug: 4.4.3 - typescript: 5.6.3 + typescript: 5.9.3 transitivePeerDependencies: - supports-color @@ -6050,91 +6487,48 @@ snapshots: '@typescript-eslint/types': 8.47.0 '@typescript-eslint/visitor-keys': 8.47.0 - '@typescript-eslint/tsconfig-utils@8.47.0(typescript@5.5.4)': + '@typescript-eslint/tsconfig-utils@8.47.0(typescript@5.9.3)': dependencies: - typescript: 5.5.4 + typescript: 5.9.3 - '@typescript-eslint/tsconfig-utils@8.47.0(typescript@5.6.3)': - dependencies: - typescript: 5.6.3 - - '@typescript-eslint/type-utils@8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.5.4)': + '@typescript-eslint/type-utils@8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)': dependencies: '@typescript-eslint/types': 8.47.0 - '@typescript-eslint/typescript-estree': 8.47.0(typescript@5.5.4) - '@typescript-eslint/utils': 8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.5.4) + '@typescript-eslint/typescript-estree': 8.47.0(typescript@5.9.3) + '@typescript-eslint/utils': 8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) debug: 4.4.3 eslint: 9.39.2(jiti@2.6.1) - ts-api-utils: 2.1.0(typescript@5.5.4) - typescript: 5.5.4 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/type-utils@8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.6.3)': - dependencies: - '@typescript-eslint/types': 8.47.0 - '@typescript-eslint/typescript-estree': 8.47.0(typescript@5.6.3) - '@typescript-eslint/utils': 8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.6.3) - debug: 4.4.3 - eslint: 9.39.2(jiti@2.6.1) - ts-api-utils: 2.1.0(typescript@5.6.3) - typescript: 5.6.3 + ts-api-utils: 2.1.0(typescript@5.9.3) + typescript: 5.9.3 transitivePeerDependencies: - supports-color '@typescript-eslint/types@8.47.0': {} - '@typescript-eslint/typescript-estree@8.47.0(typescript@5.5.4)': - dependencies: - '@typescript-eslint/project-service': 8.47.0(typescript@5.5.4) - '@typescript-eslint/tsconfig-utils': 8.47.0(typescript@5.5.4) - '@typescript-eslint/types': 8.47.0 - '@typescript-eslint/visitor-keys': 8.47.0 - debug: 4.4.3 - fast-glob: 3.3.3 - is-glob: 4.0.3 - minimatch: 9.0.5 - semver: 7.7.3 - ts-api-utils: 2.1.0(typescript@5.5.4) - typescript: 5.5.4 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/typescript-estree@8.47.0(typescript@5.6.3)': + '@typescript-eslint/typescript-estree@8.47.0(typescript@5.9.3)': dependencies: - '@typescript-eslint/project-service': 8.47.0(typescript@5.6.3) - '@typescript-eslint/tsconfig-utils': 8.47.0(typescript@5.6.3) + '@typescript-eslint/project-service': 8.47.0(typescript@5.9.3) + '@typescript-eslint/tsconfig-utils': 8.47.0(typescript@5.9.3) '@typescript-eslint/types': 8.47.0 '@typescript-eslint/visitor-keys': 8.47.0 debug: 4.4.3 fast-glob: 3.3.3 is-glob: 4.0.3 minimatch: 9.0.5 - semver: 7.7.3 - ts-api-utils: 2.1.0(typescript@5.6.3) - typescript: 5.6.3 + semver: 7.7.4 + ts-api-utils: 2.1.0(typescript@5.9.3) + typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.5.4)': + '@typescript-eslint/utils@8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)': dependencies: '@eslint-community/eslint-utils': 4.9.0(eslint@9.39.2(jiti@2.6.1)) '@typescript-eslint/scope-manager': 8.47.0 '@typescript-eslint/types': 8.47.0 - '@typescript-eslint/typescript-estree': 8.47.0(typescript@5.5.4) + '@typescript-eslint/typescript-estree': 8.47.0(typescript@5.9.3) eslint: 9.39.2(jiti@2.6.1) - typescript: 5.5.4 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/utils@8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.6.3)': - dependencies: - '@eslint-community/eslint-utils': 4.9.0(eslint@9.39.2(jiti@2.6.1)) - '@typescript-eslint/scope-manager': 8.47.0 - '@typescript-eslint/types': 8.47.0 - '@typescript-eslint/typescript-estree': 8.47.0(typescript@5.6.3) - eslint: 9.39.2(jiti@2.6.1) - typescript: 5.6.3 + typescript: 5.9.3 transitivePeerDependencies: - supports-color @@ -6143,57 +6537,141 @@ snapshots: '@typescript-eslint/types': 8.47.0 eslint-visitor-keys: 4.2.1 - '@vitejs/plugin-react@5.1.2(vite@7.0.0(@types/node@20.19.1)(jiti@2.6.1)(lightningcss@1.30.2(patch_hash=tzyxy3asfxcqc7ihrooumyi5fm))(terser@5.31.6)(tsx@4.19.1)(yaml@2.6.0))': + '@vitejs/plugin-react@5.1.3(vite@7.3.1(@types/node@20.19.1)(jiti@2.6.1)(lightningcss@1.31.1(patch_hash=tzyxy3asfxcqc7ihrooumyi5fm))(terser@5.31.6)(tsx@4.19.1)(yaml@2.6.0))': dependencies: - '@babel/core': 7.28.5 - '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-react-jsx-source': 7.27.1(@babel/core@7.28.5) - '@rolldown/pluginutils': 1.0.0-beta.53 + '@babel/core': 7.29.0 + '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-react-jsx-source': 7.27.1(@babel/core@7.29.0) + '@rolldown/pluginutils': 1.0.0-rc.2 '@types/babel__core': 7.20.5 react-refresh: 0.18.0 - vite: 7.0.0(@types/node@20.19.1)(jiti@2.6.1)(lightningcss@1.30.2(patch_hash=tzyxy3asfxcqc7ihrooumyi5fm))(terser@5.31.6)(tsx@4.19.1)(yaml@2.6.0) + vite: 7.3.1(@types/node@20.19.1)(jiti@2.6.1)(lightningcss@1.31.1(patch_hash=tzyxy3asfxcqc7ihrooumyi5fm))(terser@5.31.6)(tsx@4.19.1)(yaml@2.6.0) transitivePeerDependencies: - supports-color - '@vitest/expect@4.0.12': + '@vitest/expect@4.0.18': dependencies: '@standard-schema/spec': 1.0.0 '@types/chai': 5.2.3 - '@vitest/spy': 4.0.12 - '@vitest/utils': 4.0.12 + '@vitest/spy': 4.0.18 + '@vitest/utils': 4.0.18 chai: 6.2.1 tinyrainbow: 3.0.3 - '@vitest/mocker@4.0.12(vite@7.0.0(@types/node@20.19.1)(jiti@2.6.1)(lightningcss@1.30.2(patch_hash=tzyxy3asfxcqc7ihrooumyi5fm))(terser@5.31.6)(tsx@4.19.1)(yaml@2.6.0))': + '@vitest/mocker@4.0.18(vite@7.0.0(@types/node@20.19.1)(jiti@2.6.1)(lightningcss@1.31.1(patch_hash=tzyxy3asfxcqc7ihrooumyi5fm))(terser@5.31.6)(tsx@4.19.1)(yaml@2.6.0))': dependencies: - '@vitest/spy': 4.0.12 + '@vitest/spy': 4.0.18 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 7.0.0(@types/node@20.19.1)(jiti@2.6.1)(lightningcss@1.30.2(patch_hash=tzyxy3asfxcqc7ihrooumyi5fm))(terser@5.31.6)(tsx@4.19.1)(yaml@2.6.0) + vite: 7.0.0(@types/node@20.19.1)(jiti@2.6.1)(lightningcss@1.31.1(patch_hash=tzyxy3asfxcqc7ihrooumyi5fm))(terser@5.31.6)(tsx@4.19.1)(yaml@2.6.0) - '@vitest/pretty-format@4.0.12': + '@vitest/pretty-format@4.0.18': dependencies: tinyrainbow: 3.0.3 - '@vitest/runner@4.0.12': + '@vitest/runner@4.0.18': dependencies: - '@vitest/utils': 4.0.12 + '@vitest/utils': 4.0.18 pathe: 2.0.3 - '@vitest/snapshot@4.0.12': + '@vitest/snapshot@4.0.18': dependencies: - '@vitest/pretty-format': 4.0.12 + '@vitest/pretty-format': 4.0.18 magic-string: 0.30.21 pathe: 2.0.3 - '@vitest/spy@4.0.12': {} + '@vitest/spy@4.0.18': {} - '@vitest/utils@4.0.12': + '@vitest/utils@4.0.18': dependencies: - '@vitest/pretty-format': 4.0.12 + '@vitest/pretty-format': 4.0.18 tinyrainbow: 3.0.3 + '@webassemblyjs/ast@1.14.1': + dependencies: + '@webassemblyjs/helper-numbers': 1.13.2 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + + '@webassemblyjs/floating-point-hex-parser@1.13.2': {} + + '@webassemblyjs/helper-api-error@1.13.2': {} + + '@webassemblyjs/helper-buffer@1.14.1': {} + + '@webassemblyjs/helper-numbers@1.13.2': + dependencies: + '@webassemblyjs/floating-point-hex-parser': 1.13.2 + '@webassemblyjs/helper-api-error': 1.13.2 + '@xtuc/long': 4.2.2 + + '@webassemblyjs/helper-wasm-bytecode@1.13.2': {} + + '@webassemblyjs/helper-wasm-section@1.14.1': + dependencies: + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-buffer': 1.14.1 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + '@webassemblyjs/wasm-gen': 1.14.1 + + '@webassemblyjs/ieee754@1.13.2': + dependencies: + '@xtuc/ieee754': 1.2.0 + + '@webassemblyjs/leb128@1.13.2': + dependencies: + '@xtuc/long': 4.2.2 + + '@webassemblyjs/utf8@1.13.2': {} + + '@webassemblyjs/wasm-edit@1.14.1': + dependencies: + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-buffer': 1.14.1 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + '@webassemblyjs/helper-wasm-section': 1.14.1 + '@webassemblyjs/wasm-gen': 1.14.1 + '@webassemblyjs/wasm-opt': 1.14.1 + '@webassemblyjs/wasm-parser': 1.14.1 + '@webassemblyjs/wast-printer': 1.14.1 + + '@webassemblyjs/wasm-gen@1.14.1': + dependencies: + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + '@webassemblyjs/ieee754': 1.13.2 + '@webassemblyjs/leb128': 1.13.2 + '@webassemblyjs/utf8': 1.13.2 + + '@webassemblyjs/wasm-opt@1.14.1': + dependencies: + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-buffer': 1.14.1 + '@webassemblyjs/wasm-gen': 1.14.1 + '@webassemblyjs/wasm-parser': 1.14.1 + + '@webassemblyjs/wasm-parser@1.14.1': + dependencies: + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-api-error': 1.13.2 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + '@webassemblyjs/ieee754': 1.13.2 + '@webassemblyjs/leb128': 1.13.2 + '@webassemblyjs/utf8': 1.13.2 + + '@webassemblyjs/wast-printer@1.14.1': + dependencies: + '@webassemblyjs/ast': 1.14.1 + '@xtuc/long': 4.2.2 + + '@xtuc/ieee754@1.2.0': {} + + '@xtuc/long@4.2.2': {} + + acorn-import-phases@1.0.4(acorn@8.15.0): + dependencies: + acorn: 8.15.0 + acorn-jsx@5.3.2(acorn@8.15.0): dependencies: acorn: 8.15.0 @@ -6202,6 +6680,15 @@ snapshots: acorn@8.15.0: {} + ajv-formats@2.1.1(ajv@8.17.1): + optionalDependencies: + ajv: 8.17.1 + + ajv-keywords@5.1.0(ajv@8.17.1): + dependencies: + ajv: 8.17.1 + fast-deep-equal: 3.1.3 + ajv@6.12.6: dependencies: fast-deep-equal: 3.1.3 @@ -6209,6 +6696,13 @@ snapshots: json-schema-traverse: 0.4.1 uri-js: 4.4.1 + ajv@8.17.1: + dependencies: + fast-deep-equal: 3.1.3 + fast-uri: 3.1.0 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + ansi-regex@5.0.1: {} ansi-regex@6.0.1: {} @@ -6303,13 +6797,13 @@ snapshots: ast-types-flow@0.0.8: {} - autoprefixer@10.4.23(postcss@8.4.47): + autoprefixer@10.4.24(postcss@8.5.6): dependencies: browserslist: 4.28.1 - caniuse-lite: 1.0.30001761 + caniuse-lite: 1.0.30001769 fraction.js: 5.3.4 picocolors: 1.1.1 - postcss: 8.4.47 + postcss: 8.5.6 postcss-value-parser: 4.2.0 available-typed-arrays@1.0.7: @@ -6346,7 +6840,7 @@ snapshots: browserslist@4.28.0: dependencies: baseline-browser-mapping: 2.8.29 - caniuse-lite: 1.0.30001761 + caniuse-lite: 1.0.30001769 electron-to-chromium: 1.5.255 node-releases: 2.0.27 update-browserslist-db: 1.1.4(browserslist@4.28.0) @@ -6359,26 +6853,25 @@ snapshots: node-releases: 2.0.27 update-browserslist-db: 1.2.3(browserslist@4.28.1) - buffer-from@1.1.2: - optional: true + buffer-from@1.1.2: {} - bun-types@1.3.5: + bun-types@1.3.9: dependencies: '@types/node': 20.19.1 - bun@1.3.5: + bun@1.3.9: optionalDependencies: - '@oven/bun-darwin-aarch64': 1.3.5 - '@oven/bun-darwin-x64': 1.3.5 - '@oven/bun-darwin-x64-baseline': 1.3.5 - '@oven/bun-linux-aarch64': 1.3.5 - '@oven/bun-linux-aarch64-musl': 1.3.5 - '@oven/bun-linux-x64': 1.3.5 - '@oven/bun-linux-x64-baseline': 1.3.5 - '@oven/bun-linux-x64-musl': 1.3.5 - '@oven/bun-linux-x64-musl-baseline': 1.3.5 - '@oven/bun-windows-x64': 1.3.5 - '@oven/bun-windows-x64-baseline': 1.3.5 + '@oven/bun-darwin-aarch64': 1.3.9 + '@oven/bun-darwin-x64': 1.3.9 + '@oven/bun-darwin-x64-baseline': 1.3.9 + '@oven/bun-linux-aarch64': 1.3.9 + '@oven/bun-linux-aarch64-musl': 1.3.9 + '@oven/bun-linux-x64': 1.3.9 + '@oven/bun-linux-x64-baseline': 1.3.9 + '@oven/bun-linux-x64-musl': 1.3.9 + '@oven/bun-linux-x64-musl-baseline': 1.3.9 + '@oven/bun-windows-x64': 1.3.9 + '@oven/bun-windows-x64-baseline': 1.3.9 bundle-require@5.1.0(esbuild@0.27.0): dependencies: @@ -6408,10 +6901,10 @@ snapshots: camelcase-css@2.0.1: {} - caniuse-lite@1.0.30001755: {} - caniuse-lite@1.0.30001761: {} + caniuse-lite@1.0.30001769: {} + chai@6.2.1: {} chalk@4.1.2: @@ -6437,6 +6930,8 @@ snapshots: dependencies: readdirp: 4.1.1 + chrome-trace-event@1.0.4: {} + citty@0.1.6: dependencies: consola: 3.2.3 @@ -6463,8 +6958,7 @@ snapshots: colorette@2.0.20: {} - commander@2.20.3: - optional: true + commander@2.20.3: {} commander@4.1.1: {} @@ -6548,10 +7042,7 @@ snapshots: detect-libc@1.0.3: {} - detect-libc@2.0.4: {} - - detect-libc@2.1.2: - optional: true + detect-libc@2.1.2: {} didyoumean@1.2.2: {} @@ -6573,7 +7064,7 @@ snapshots: electron-to-chromium@1.5.267: {} - emnapi@1.7.1(node-addon-api@8.3.0): + emnapi@1.8.1(node-addon-api@8.3.0): optionalDependencies: node-addon-api: 8.3.0 @@ -6581,10 +7072,10 @@ snapshots: emoji-regex@9.2.2: {} - enhanced-resolve@5.18.4: + enhanced-resolve@5.19.0: dependencies: graceful-fs: 4.2.11 - tapable: 2.2.1 + tapable: 2.3.0 es-abstract@1.24.0: dependencies: @@ -6666,6 +7157,8 @@ snapshots: es-module-lexer@1.7.0: {} + es-module-lexer@2.0.0: {} + es-object-atoms@1.1.1: dependencies: es-errors: 1.3.0 @@ -6778,29 +7271,29 @@ snapshots: escape-string-regexp@4.0.0: {} - eslint-config-next@16.1.0(@typescript-eslint/parser@8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.5.4))(eslint@9.39.2(jiti@2.6.1))(typescript@5.5.4): + eslint-config-next@16.1.6(@typescript-eslint/parser@8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3): dependencies: - '@next/eslint-plugin-next': 16.1.0 + '@next/eslint-plugin-next': 16.1.6 eslint: 9.39.2(jiti@2.6.1) eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.5.4))(eslint@9.39.2(jiti@2.6.1)))(eslint@9.39.2(jiti@2.6.1)) - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.5.4))(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.5.4))(eslint@9.39.2(jiti@2.6.1)))(eslint@9.39.2(jiti@2.6.1)))(eslint@9.39.2(jiti@2.6.1)) + eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1)))(eslint@9.39.2(jiti@2.6.1)) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@3.6.3)(eslint@9.39.2(jiti@2.6.1)) eslint-plugin-jsx-a11y: 6.10.1(eslint@9.39.2(jiti@2.6.1)) eslint-plugin-react: 7.37.2(eslint@9.39.2(jiti@2.6.1)) eslint-plugin-react-hooks: 7.0.1(eslint@9.39.2(jiti@2.6.1)) globals: 16.4.0 - typescript-eslint: 8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.5.4) + typescript-eslint: 8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) optionalDependencies: - typescript: 5.5.4 + typescript: 5.9.3 transitivePeerDependencies: - '@typescript-eslint/parser' - eslint-import-resolver-webpack - eslint-plugin-import-x - supports-color - eslint-config-next@16.1.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.6.3): + eslint-config-next@16.1.6(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3): dependencies: - '@next/eslint-plugin-next': 16.1.0 + '@next/eslint-plugin-next': 16.1.6 eslint: 9.39.2(jiti@2.6.1) eslint-import-resolver-node: 0.3.9 eslint-import-resolver-typescript: 3.6.3(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.32.0)(eslint@9.39.2(jiti@2.6.1)) @@ -6809,9 +7302,9 @@ snapshots: eslint-plugin-react: 7.37.2(eslint@9.39.2(jiti@2.6.1)) eslint-plugin-react-hooks: 7.0.1(eslint@9.39.2(jiti@2.6.1)) globals: 16.4.0 - typescript-eslint: 8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.6.3) + typescript-eslint: 8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) optionalDependencies: - typescript: 5.6.3 + typescript: 5.9.3 transitivePeerDependencies: - '@typescript-eslint/parser' - eslint-import-resolver-webpack @@ -6826,19 +7319,19 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.5.4))(eslint@9.39.2(jiti@2.6.1)))(eslint@9.39.2(jiti@2.6.1)): + eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1)))(eslint@9.39.2(jiti@2.6.1)): dependencies: '@nolyfill/is-core-module': 1.0.39 debug: 4.4.3 - enhanced-resolve: 5.18.4 + enhanced-resolve: 5.19.0 eslint: 9.39.2(jiti@2.6.1) - eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.5.4))(eslint@9.39.2(jiti@2.6.1)))(eslint@9.39.2(jiti@2.6.1)))(eslint@9.39.2(jiti@2.6.1)) + eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1)))(eslint@9.39.2(jiti@2.6.1)))(eslint@9.39.2(jiti@2.6.1)) fast-glob: 3.3.3 get-tsconfig: 4.10.0 is-bun-module: 1.2.1 is-glob: 4.0.3 optionalDependencies: - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.5.4))(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.5.4))(eslint@9.39.2(jiti@2.6.1)))(eslint@9.39.2(jiti@2.6.1)))(eslint@9.39.2(jiti@2.6.1)) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@3.6.3)(eslint@9.39.2(jiti@2.6.1)) transitivePeerDependencies: - '@typescript-eslint/parser' - eslint-import-resolver-node @@ -6849,7 +7342,7 @@ snapshots: dependencies: '@nolyfill/is-core-module': 1.0.39 debug: 4.4.3 - enhanced-resolve: 5.18.4 + enhanced-resolve: 5.19.0 eslint: 9.39.2(jiti@2.6.1) eslint-module-utils: 2.12.1(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.32.0)(eslint@9.39.2(jiti@2.6.1)))(eslint@9.39.2(jiti@2.6.1)) fast-glob: 3.3.3 @@ -6864,14 +7357,14 @@ snapshots: - eslint-import-resolver-webpack - supports-color - eslint-module-utils@2.12.1(@typescript-eslint/parser@8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.5.4))(eslint@9.39.2(jiti@2.6.1)))(eslint@9.39.2(jiti@2.6.1)))(eslint@9.39.2(jiti@2.6.1)): + eslint-module-utils@2.12.1(@typescript-eslint/parser@8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1)))(eslint@9.39.2(jiti@2.6.1)))(eslint@9.39.2(jiti@2.6.1)): dependencies: debug: 3.2.7 optionalDependencies: - '@typescript-eslint/parser': 8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.5.4) + '@typescript-eslint/parser': 8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) eslint: 9.39.2(jiti@2.6.1) eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.5.4))(eslint@9.39.2(jiti@2.6.1)))(eslint@9.39.2(jiti@2.6.1)) + eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1)))(eslint@9.39.2(jiti@2.6.1)) transitivePeerDependencies: - supports-color @@ -6885,7 +7378,7 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.5.4))(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.5.4))(eslint@9.39.2(jiti@2.6.1)))(eslint@9.39.2(jiti@2.6.1)))(eslint@9.39.2(jiti@2.6.1)): + eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@3.6.3)(eslint@9.39.2(jiti@2.6.1)): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.9 @@ -6896,7 +7389,7 @@ snapshots: doctrine: 2.1.0 eslint: 9.39.2(jiti@2.6.1) eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.5.4))(eslint@9.39.2(jiti@2.6.1)))(eslint@9.39.2(jiti@2.6.1)))(eslint@9.39.2(jiti@2.6.1)) + eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1)))(eslint@9.39.2(jiti@2.6.1)))(eslint@9.39.2(jiti@2.6.1)) hasown: 2.0.2 is-core-module: 2.16.1 is-glob: 4.0.3 @@ -6908,7 +7401,7 @@ snapshots: string.prototype.trimend: 1.0.9 tsconfig-paths: 3.15.0 optionalDependencies: - '@typescript-eslint/parser': 8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.5.4) + '@typescript-eslint/parser': 8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack @@ -6994,6 +7487,11 @@ snapshots: string.prototype.matchall: 4.0.11 string.prototype.repeat: 1.0.0 + eslint-scope@5.1.1: + dependencies: + esrecurse: 4.3.0 + estraverse: 4.3.0 + eslint-scope@8.4.0: dependencies: esrecurse: 4.3.0 @@ -7058,6 +7556,8 @@ snapshots: dependencies: estraverse: 5.3.0 + estraverse@4.3.0: {} + estraverse@5.3.0: {} estree-walker@3.0.3: @@ -7066,6 +7566,8 @@ snapshots: esutils@2.0.3: {} + events@3.3.0: {} + execa@8.0.1: dependencies: cross-spawn: 7.0.6 @@ -7108,6 +7610,8 @@ snapshots: fast-stringify@4.0.0: {} + fast-uri@3.1.0: {} + fastq@1.17.1: dependencies: reusify: 1.0.4 @@ -7220,6 +7724,8 @@ snapshots: dependencies: is-glob: 4.0.3 + glob-to-regexp@0.4.1: {} + glob@10.4.5: dependencies: foreground-child: 3.3.0 @@ -7253,16 +7759,16 @@ snapshots: graphemer@1.4.0: {} - h3@1.15.4: + h3@1.15.5: dependencies: cookie-es: 1.2.2 crossws: 0.3.5 defu: 6.1.4 destr: 2.0.5 iron-webcrypto: 1.2.1 - node-mock-http: 1.0.2 + node-mock-http: 1.0.4 radix3: 1.1.2 - ufo: 1.6.1 + ufo: 1.6.3 uncrypto: 0.1.3 has-bigints@1.0.2: {} @@ -7345,7 +7851,7 @@ snapshots: is-bun-module@1.2.1: dependencies: - semver: 7.7.3 + semver: 7.7.4 is-callable@1.2.7: {} @@ -7468,6 +7974,12 @@ snapshots: optionalDependencies: '@pkgjs/parseargs': 0.11.0 + jest-worker@27.5.1: + dependencies: + '@types/node': 20.19.1 + merge-stream: 2.0.0 + supports-color: 8.1.1 + jiti@1.21.6: {} jiti@2.4.2: {} @@ -7486,8 +7998,12 @@ snapshots: json-buffer@3.0.1: {} + json-parse-even-better-errors@2.3.1: {} + json-schema-traverse@0.4.1: {} + json-schema-traverse@1.0.0: {} + json-stable-stringify-without-jsonify@1.0.1: {} json5@1.0.2: @@ -7518,47 +8034,47 @@ snapshots: prelude-ls: 1.2.1 type-check: 0.4.0 - lightningcss-android-arm64@1.30.2: + lightningcss-android-arm64@1.31.1: optional: true - lightningcss-darwin-arm64@1.30.2: {} + lightningcss-darwin-arm64@1.31.1: {} - lightningcss-darwin-x64@1.30.2: {} + lightningcss-darwin-x64@1.31.1: {} - lightningcss-freebsd-x64@1.30.2: + lightningcss-freebsd-x64@1.31.1: optional: true - lightningcss-linux-arm-gnueabihf@1.30.2: + lightningcss-linux-arm-gnueabihf@1.31.1: optional: true - lightningcss-linux-arm64-gnu@1.30.2: {} + lightningcss-linux-arm64-gnu@1.31.1: {} - lightningcss-linux-arm64-musl@1.30.2: {} + lightningcss-linux-arm64-musl@1.31.1: {} - lightningcss-linux-x64-gnu@1.30.2: {} + lightningcss-linux-x64-gnu@1.31.1: {} - lightningcss-linux-x64-musl@1.30.2: {} + lightningcss-linux-x64-musl@1.31.1: {} - lightningcss-win32-arm64-msvc@1.30.2: + lightningcss-win32-arm64-msvc@1.31.1: optional: true - lightningcss-win32-x64-msvc@1.30.2: {} + lightningcss-win32-x64-msvc@1.31.1: {} - lightningcss@1.30.2(patch_hash=tzyxy3asfxcqc7ihrooumyi5fm): + lightningcss@1.31.1(patch_hash=tzyxy3asfxcqc7ihrooumyi5fm): dependencies: - detect-libc: 2.0.4 + detect-libc: 2.1.2 optionalDependencies: - lightningcss-android-arm64: 1.30.2 - lightningcss-darwin-arm64: 1.30.2 - lightningcss-darwin-x64: 1.30.2 - lightningcss-freebsd-x64: 1.30.2 - lightningcss-linux-arm-gnueabihf: 1.30.2 - lightningcss-linux-arm64-gnu: 1.30.2 - lightningcss-linux-arm64-musl: 1.30.2 - lightningcss-linux-x64-gnu: 1.30.2 - lightningcss-linux-x64-musl: 1.30.2 - lightningcss-win32-arm64-msvc: 1.30.2 - lightningcss-win32-x64-msvc: 1.30.2 + lightningcss-android-arm64: 1.31.1 + lightningcss-darwin-arm64: 1.31.1 + lightningcss-darwin-x64: 1.31.1 + lightningcss-freebsd-x64: 1.31.1 + lightningcss-linux-arm-gnueabihf: 1.31.1 + lightningcss-linux-arm64-gnu: 1.31.1 + lightningcss-linux-arm64-musl: 1.31.1 + lightningcss-linux-x64-gnu: 1.31.1 + lightningcss-linux-x64-musl: 1.31.1 + lightningcss-win32-arm64-msvc: 1.31.1 + lightningcss-win32-x64-msvc: 1.31.1 lilconfig@2.1.0: {} @@ -7576,7 +8092,7 @@ snapshots: crossws: 0.3.1 defu: 6.1.4 get-port-please: 3.1.2 - h3: 1.15.4 + h3: 1.15.5 http-shutdown: 1.2.2 jiti: 2.4.2 mlly: 1.7.3 @@ -7589,6 +8105,8 @@ snapshots: load-tsconfig@0.2.5: {} + loader-runner@4.3.1: {} + locate-path@6.0.0: dependencies: p-locate: 5.0.0 @@ -7630,6 +8148,12 @@ snapshots: braces: 3.0.3 picomatch: 2.3.1 + mime-db@1.52.0: {} + + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + mimic-fn@4.0.0: {} mini-svg-data-uri@1.4.4: {} @@ -7674,30 +8198,30 @@ snapshots: nanoid@3.3.11: {} - nanoid@3.3.7: {} - natural-compare@1.4.0: {} - next@16.1.0(@playwright/test@1.57.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3): + neo-async@2.6.2: {} + + next@16.1.6(@babel/core@7.28.5)(@playwright/test@1.58.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4): dependencies: - '@next/env': 16.1.0 + '@next/env': 16.1.6 '@swc/helpers': 0.5.15 - baseline-browser-mapping: 2.8.29 - caniuse-lite: 1.0.30001755 + baseline-browser-mapping: 2.9.11 + caniuse-lite: 1.0.30001761 postcss: 8.4.31 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - styled-jsx: 5.1.6(react@19.2.3) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + styled-jsx: 5.1.6(@babel/core@7.28.5)(react@19.2.4) optionalDependencies: - '@next/swc-darwin-arm64': 16.1.0 - '@next/swc-darwin-x64': 16.1.0 - '@next/swc-linux-arm64-gnu': 16.1.0 - '@next/swc-linux-arm64-musl': 16.1.0 - '@next/swc-linux-x64-gnu': 16.1.0 - '@next/swc-linux-x64-musl': 16.1.0 - '@next/swc-win32-arm64-msvc': 16.1.0 - '@next/swc-win32-x64-msvc': 16.1.0 - '@playwright/test': 1.57.0 + '@next/swc-darwin-arm64': 16.1.6 + '@next/swc-darwin-x64': 16.1.6 + '@next/swc-linux-arm64-gnu': 16.1.6 + '@next/swc-linux-arm64-musl': 16.1.6 + '@next/swc-linux-x64-gnu': 16.1.6 + '@next/swc-linux-x64-musl': 16.1.6 + '@next/swc-win32-arm64-msvc': 16.1.6 + '@next/swc-win32-x64-msvc': 16.1.6 + '@playwright/test': 1.58.0 sharp: 0.34.5 transitivePeerDependencies: - '@babel/core' @@ -7715,7 +8239,7 @@ snapshots: node-gyp-build@4.8.4: {} - node-mock-http@1.0.2: {} + node-mock-http@1.0.4: {} node-releases@2.0.27: {} @@ -7768,6 +8292,8 @@ snapshots: define-properties: 1.2.1 es-object-atoms: 1.1.1 + obug@2.1.1: {} + onetime@6.0.0: dependencies: mimic-fn: 4.0.0 @@ -7842,26 +8368,19 @@ snapshots: mlly: 1.7.3 pathe: 1.1.2 - playwright-core@1.57.0: {} + playwright-core@1.58.0: {} - playwright@1.57.0: + playwright@1.58.0: dependencies: - playwright-core: 1.57.0 + playwright-core: 1.58.0 optionalDependencies: fsevents: 2.3.2 possible-typed-array-names@1.0.0: {} - postcss-import@15.1.0(postcss@8.4.47): - dependencies: - postcss: 8.4.47 - postcss-value-parser: 4.2.0 - read-cache: 1.0.0 - resolve: 1.22.8 - - postcss-import@16.1.1(postcss@8.4.41): + postcss-import@15.1.0(postcss@8.5.6): dependencies: - postcss: 8.4.41 + postcss: 8.5.6 postcss-value-parser: 4.2.0 read-cache: 1.0.0 resolve: 1.22.8 @@ -7873,17 +8392,17 @@ snapshots: read-cache: 1.0.0 resolve: 1.22.8 - postcss-js@4.0.1(postcss@8.4.47): + postcss-js@4.0.1(postcss@8.5.6): dependencies: camelcase-css: 2.0.1 - postcss: 8.4.47 + postcss: 8.5.6 - postcss-load-config@4.0.2(postcss@8.4.47): + postcss-load-config@4.0.2(postcss@8.5.6): dependencies: lilconfig: 3.1.2 yaml: 2.6.0 optionalDependencies: - postcss: 8.4.47 + postcss: 8.5.6 postcss-load-config@6.0.1(jiti@2.6.1)(postcss@8.5.6)(tsx@4.19.1)(yaml@2.6.0): dependencies: @@ -7894,9 +8413,9 @@ snapshots: tsx: 4.19.1 yaml: 2.6.0 - postcss-nested@6.2.0(postcss@8.4.47): + postcss-nested@6.2.0(postcss@8.5.6): dependencies: - postcss: 8.4.47 + postcss: 8.5.6 postcss-selector-parser: 6.1.2 postcss-selector-parser@6.0.10: @@ -7922,18 +8441,6 @@ snapshots: picocolors: 1.1.1 source-map-js: 1.2.1 - postcss@8.4.41: - dependencies: - nanoid: 3.3.7 - picocolors: 1.1.1 - source-map-js: 1.2.1 - - postcss@8.4.47: - dependencies: - nanoid: 3.3.7 - picocolors: 1.1.1 - source-map-js: 1.2.1 - postcss@8.5.6: dependencies: nanoid: 3.3.11 @@ -7953,12 +8460,12 @@ snapshots: transitivePeerDependencies: - babel-plugin-macros - prettier-plugin-organize-imports@4.3.0(prettier@3.6.2)(typescript@5.5.4): + prettier-plugin-organize-imports@4.3.0(prettier@3.8.1)(typescript@5.5.4): dependencies: - prettier: 3.6.2 + prettier: 3.8.1 typescript: 5.5.4 - prettier@3.6.2: {} + prettier@3.8.1: {} prop-types@15.8.1: dependencies: @@ -7972,16 +8479,20 @@ snapshots: radix3@1.1.2: {} - react-dom@19.2.3(react@19.2.3): + randombytes@2.1.0: + dependencies: + safe-buffer: 5.2.1 + + react-dom@19.2.4(react@19.2.4): dependencies: - react: 19.2.3 + react: 19.2.4 scheduler: 0.27.0 react-is@16.13.1: {} react-refresh@0.18.0: {} - react@19.2.3: {} + react@19.2.4: {} read-cache@1.0.0: dependencies: @@ -8013,6 +8524,8 @@ snapshots: gopd: 1.2.0 set-function-name: 2.0.2 + require-from-string@2.0.2: {} + resolve-from@4.0.0: {} resolve-from@5.0.0: {} @@ -8071,6 +8584,8 @@ snapshots: has-symbols: 1.1.0 isarray: 2.0.5 + safe-buffer@5.2.1: {} + safe-push-apply@1.0.0: dependencies: es-errors: 1.3.0 @@ -8086,10 +8601,23 @@ snapshots: scheduler@0.27.0: {} + schema-utils@4.3.3: + dependencies: + '@types/json-schema': 7.0.15 + ajv: 8.17.1 + ajv-formats: 2.1.1(ajv@8.17.1) + ajv-keywords: 5.1.0(ajv@8.17.1) + semver@6.3.1: {} semver@7.7.3: {} + semver@7.7.4: {} + + serialize-javascript@6.0.2: + dependencies: + randombytes: 2.1.0 + set-function-length@1.2.2: dependencies: define-data-property: 1.1.4 @@ -8116,7 +8644,7 @@ snapshots: dependencies: '@img/colour': 1.0.0 detect-libc: 2.1.2 - semver: 7.7.3 + semver: 7.7.4 optionalDependencies: '@img/sharp-darwin-arm64': 0.34.5 '@img/sharp-darwin-x64': 0.34.5 @@ -8190,10 +8718,8 @@ snapshots: dependencies: buffer-from: 1.1.2 source-map: 0.6.1 - optional: true - source-map@0.6.1: - optional: true + source-map@0.6.1: {} source-map@0.7.6: {} @@ -8283,10 +8809,12 @@ snapshots: strip-json-comments@3.1.1: {} - styled-jsx@5.1.6(react@19.2.3): + styled-jsx@5.1.6(@babel/core@7.28.5)(react@19.2.4): dependencies: client-only: 0.0.1 - react: 19.2.3 + react: 19.2.4 + optionalDependencies: + '@babel/core': 7.28.5 sucrase@3.35.0: dependencies: @@ -8302,6 +8830,10 @@ snapshots: dependencies: has-flag: 4.0.0 + supports-color@8.1.1: + dependencies: + has-flag: 4.0.0 + supports-preserve-symlinks-flag@1.0.0: {} system-architecture@0.1.0: {} @@ -8324,18 +8856,29 @@ snapshots: normalize-path: 3.0.0 object-hash: 3.0.0 picocolors: 1.1.1 - postcss: 8.4.47 - postcss-import: 15.1.0(postcss@8.4.47) - postcss-js: 4.0.1(postcss@8.4.47) - postcss-load-config: 4.0.2(postcss@8.4.47) - postcss-nested: 6.2.0(postcss@8.4.47) + postcss: 8.5.6 + postcss-import: 15.1.0(postcss@8.5.6) + postcss-js: 4.0.1(postcss@8.5.6) + postcss-load-config: 4.0.2(postcss@8.5.6) + postcss-nested: 6.2.0(postcss@8.5.6) postcss-selector-parser: 6.1.2 resolve: 1.22.8 sucrase: 3.35.0 transitivePeerDependencies: - ts-node - tapable@2.2.1: {} + tapable@2.3.0: {} + + terser-webpack-plugin@5.3.16(esbuild@0.27.0)(webpack@5.104.1(esbuild@0.27.0)): + dependencies: + '@jridgewell/trace-mapping': 0.3.29 + jest-worker: 27.5.1 + schema-utils: 4.3.3 + serialize-javascript: 6.0.2 + terser: 5.31.6 + webpack: 5.104.1(esbuild@0.27.0) + optionalDependencies: + esbuild: 0.27.0 terser@5.31.6: dependencies: @@ -8343,7 +8886,6 @@ snapshots: acorn: 8.15.0 commander: 2.20.3 source-map-support: 0.5.21 - optional: true thenify-all@1.6.0: dependencies: @@ -8359,6 +8901,8 @@ snapshots: tinyexec@0.3.2: {} + tinyexec@1.0.2: {} + tinyglobby@0.2.14: dependencies: fdir: 6.4.6(picomatch@4.0.2) @@ -8397,13 +8941,9 @@ snapshots: node-addon-api: 8.3.0 node-gyp-build: 4.8.4 - ts-api-utils@2.1.0(typescript@5.5.4): + ts-api-utils@2.1.0(typescript@5.9.3): dependencies: - typescript: 5.5.4 - - ts-api-utils@2.1.0(typescript@5.6.3): - dependencies: - typescript: 5.6.3 + typescript: 5.9.3 ts-interface-checker@0.1.13: {} @@ -8452,32 +8992,32 @@ snapshots: fsevents: 2.3.3 optional: true - turbo-darwin-64@2.7.2: + turbo-darwin-64@2.7.6: optional: true - turbo-darwin-arm64@2.7.2: + turbo-darwin-arm64@2.7.6: optional: true - turbo-linux-64@2.7.2: + turbo-linux-64@2.7.6: optional: true - turbo-linux-arm64@2.7.2: + turbo-linux-arm64@2.7.6: optional: true - turbo-windows-64@2.7.2: + turbo-windows-64@2.7.6: optional: true - turbo-windows-arm64@2.7.2: + turbo-windows-arm64@2.7.6: optional: true - turbo@2.7.2: + turbo@2.7.6: optionalDependencies: - turbo-darwin-64: 2.7.2 - turbo-darwin-arm64: 2.7.2 - turbo-linux-64: 2.7.2 - turbo-linux-arm64: 2.7.2 - turbo-windows-64: 2.7.2 - turbo-windows-arm64: 2.7.2 + turbo-darwin-64: 2.7.6 + turbo-darwin-arm64: 2.7.6 + turbo-linux-64: 2.7.6 + turbo-linux-arm64: 2.7.6 + turbo-windows-64: 2.7.6 + turbo-windows-arm64: 2.7.6 typanion@3.14.0: {} @@ -8522,36 +9062,27 @@ snapshots: possible-typed-array-names: 1.0.0 reflect.getprototypeof: 1.0.10 - typescript-eslint@8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.5.4): - dependencies: - '@typescript-eslint/eslint-plugin': 8.47.0(@typescript-eslint/parser@8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.5.4))(eslint@9.39.2(jiti@2.6.1))(typescript@5.5.4) - '@typescript-eslint/parser': 8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.5.4) - '@typescript-eslint/typescript-estree': 8.47.0(typescript@5.5.4) - '@typescript-eslint/utils': 8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.5.4) - eslint: 9.39.2(jiti@2.6.1) - typescript: 5.5.4 - transitivePeerDependencies: - - supports-color - - typescript-eslint@8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.6.3): + typescript-eslint@8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3): dependencies: - '@typescript-eslint/eslint-plugin': 8.47.0(@typescript-eslint/parser@8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.6.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.6.3) - '@typescript-eslint/parser': 8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.6.3) - '@typescript-eslint/typescript-estree': 8.47.0(typescript@5.6.3) - '@typescript-eslint/utils': 8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.6.3) + '@typescript-eslint/eslint-plugin': 8.47.0(@typescript-eslint/parser@8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/parser': 8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/typescript-estree': 8.47.0(typescript@5.9.3) + '@typescript-eslint/utils': 8.47.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) eslint: 9.39.2(jiti@2.6.1) - typescript: 5.6.3 + typescript: 5.9.3 transitivePeerDependencies: - supports-color typescript@5.5.4: {} - typescript@5.6.3: {} + typescript@5.9.3: {} ufo@1.5.4: {} ufo@1.6.1: {} + ufo@1.6.3: {} + unbox-primitive@1.1.0: dependencies: call-bound: 1.0.4 @@ -8561,8 +9092,6 @@ snapshots: uncrypto@0.1.3: {} - undici-types@5.26.5: {} - undici-types@6.21.0: {} unicorn-magic@0.3.0: {} @@ -8595,44 +9124,61 @@ snapshots: util-deprecate@1.0.2: {} - vite@7.0.0(@types/node@20.19.1)(jiti@2.6.1)(lightningcss@1.30.2(patch_hash=tzyxy3asfxcqc7ihrooumyi5fm))(terser@5.31.6)(tsx@4.19.1)(yaml@2.6.0): + vite@7.0.0(@types/node@20.19.1)(jiti@2.6.1)(lightningcss@1.31.1(patch_hash=tzyxy3asfxcqc7ihrooumyi5fm))(terser@5.31.6)(tsx@4.19.1)(yaml@2.6.0): dependencies: esbuild: 0.25.0 - fdir: 6.4.6(picomatch@4.0.2) - picomatch: 4.0.2 + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 postcss: 8.5.6 rollup: 4.44.0 - tinyglobby: 0.2.14 + tinyglobby: 0.2.15 optionalDependencies: '@types/node': 20.19.1 fsevents: 2.3.3 jiti: 2.6.1 - lightningcss: 1.30.2(patch_hash=tzyxy3asfxcqc7ihrooumyi5fm) + lightningcss: 1.31.1(patch_hash=tzyxy3asfxcqc7ihrooumyi5fm) terser: 5.31.6 tsx: 4.19.1 yaml: 2.6.0 - vitest@4.0.12(@types/node@20.19.1)(jiti@2.6.1)(lightningcss@1.30.2(patch_hash=tzyxy3asfxcqc7ihrooumyi5fm))(terser@5.31.6)(tsx@4.19.1)(yaml@2.6.0): + vite@7.3.1(@types/node@20.19.1)(jiti@2.6.1)(lightningcss@1.31.1(patch_hash=tzyxy3asfxcqc7ihrooumyi5fm))(terser@5.31.6)(tsx@4.19.1)(yaml@2.6.0): dependencies: - '@vitest/expect': 4.0.12 - '@vitest/mocker': 4.0.12(vite@7.0.0(@types/node@20.19.1)(jiti@2.6.1)(lightningcss@1.30.2(patch_hash=tzyxy3asfxcqc7ihrooumyi5fm))(terser@5.31.6)(tsx@4.19.1)(yaml@2.6.0)) - '@vitest/pretty-format': 4.0.12 - '@vitest/runner': 4.0.12 - '@vitest/snapshot': 4.0.12 - '@vitest/spy': 4.0.12 - '@vitest/utils': 4.0.12 - debug: 4.4.3 + esbuild: 0.27.0 + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + postcss: 8.5.6 + rollup: 4.44.0 + tinyglobby: 0.2.15 + optionalDependencies: + '@types/node': 20.19.1 + fsevents: 2.3.3 + jiti: 2.6.1 + lightningcss: 1.31.1(patch_hash=tzyxy3asfxcqc7ihrooumyi5fm) + terser: 5.31.6 + tsx: 4.19.1 + yaml: 2.6.0 + + vitest@4.0.18(@types/node@20.19.1)(jiti@2.6.1)(lightningcss@1.31.1(patch_hash=tzyxy3asfxcqc7ihrooumyi5fm))(terser@5.31.6)(tsx@4.19.1)(yaml@2.6.0): + dependencies: + '@vitest/expect': 4.0.18 + '@vitest/mocker': 4.0.18(vite@7.0.0(@types/node@20.19.1)(jiti@2.6.1)(lightningcss@1.31.1(patch_hash=tzyxy3asfxcqc7ihrooumyi5fm))(terser@5.31.6)(tsx@4.19.1)(yaml@2.6.0)) + '@vitest/pretty-format': 4.0.18 + '@vitest/runner': 4.0.18 + '@vitest/snapshot': 4.0.18 + '@vitest/spy': 4.0.18 + '@vitest/utils': 4.0.18 es-module-lexer: 1.7.0 expect-type: 1.2.2 magic-string: 0.30.21 + obug: 2.1.1 pathe: 2.0.3 picomatch: 4.0.3 std-env: 3.10.0 tinybench: 2.9.0 - tinyexec: 0.3.2 + tinyexec: 1.0.2 tinyglobby: 0.2.15 tinyrainbow: 3.0.3 - vite: 7.0.0(@types/node@20.19.1)(jiti@2.6.1)(lightningcss@1.30.2(patch_hash=tzyxy3asfxcqc7ihrooumyi5fm))(terser@5.31.6)(tsx@4.19.1)(yaml@2.6.0) + vite: 7.0.0(@types/node@20.19.1)(jiti@2.6.1)(lightningcss@1.31.1(patch_hash=tzyxy3asfxcqc7ihrooumyi5fm))(terser@5.31.6)(tsx@4.19.1)(yaml@2.6.0) why-is-node-running: 2.3.0 optionalDependencies: '@types/node': 20.19.1 @@ -8645,11 +9191,49 @@ snapshots: - sass-embedded - stylus - sugarss - - supports-color - terser - tsx - yaml + watchpack@2.5.1: + dependencies: + glob-to-regexp: 0.4.1 + graceful-fs: 4.2.11 + + webpack-sources@3.3.3: {} + + webpack@5.104.1(esbuild@0.27.0): + dependencies: + '@types/eslint-scope': 3.7.7 + '@types/estree': 1.0.8 + '@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.15.0 + acorn-import-phases: 1.0.4(acorn@8.15.0) + browserslist: 4.28.1 + chrome-trace-event: 1.0.4 + enhanced-resolve: 5.19.0 + es-module-lexer: 2.0.0 + eslint-scope: 5.1.1 + events: 3.3.0 + glob-to-regexp: 0.4.1 + graceful-fs: 4.2.11 + json-parse-even-better-errors: 2.3.1 + loader-runner: 4.3.1 + mime-types: 2.1.35 + neo-async: 2.6.2 + schema-utils: 4.3.3 + tapable: 2.3.0 + terser-webpack-plugin: 5.3.16(esbuild@0.27.0)(webpack@5.104.1(esbuild@0.27.0)) + watchpack: 2.5.1 + webpack-sources: 3.3.3 + transitivePeerDependencies: + - '@swc/core' + - esbuild + - uglify-js + which-boxed-primitive@1.1.1: dependencies: is-bigint: 1.1.0 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 8f662c07fc67..4752226d9c0a 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -7,13 +7,14 @@ packages: catalog: '@types/node': ^20.19.0 - prettier: 3.6.2 - vite: ^7.0.0 - lightningcss: 1.30.2 - lightningcss-darwin-arm64: 1.30.2 - lightningcss-darwin-x64: 1.30.2 - lightningcss-linux-arm64-gnu: 1.30.2 - lightningcss-linux-arm64-musl: 1.30.2 - lightningcss-linux-x64-gnu: 1.30.2 - lightningcss-linux-x64-musl: 1.30.2 - lightningcss-win32-x64-msvc: 1.30.2 + prettier: 3.8.1 + vite: ^7.3.1 + webpack: ^5 + lightningcss: 1.31.1 + lightningcss-darwin-arm64: 1.31.1 + lightningcss-darwin-x64: 1.31.1 + lightningcss-linux-arm64-gnu: 1.31.1 + lightningcss-linux-arm64-musl: 1.31.1 + lightningcss-linux-x64-gnu: 1.31.1 + lightningcss-linux-x64-musl: 1.31.1 + lightningcss-win32-x64-msvc: 1.31.1