diff --git a/.agents/skills/changelog-entries/SKILL.md b/.agents/skills/changelog-entries/SKILL.md index 5ccd0fd0686..98d70cb36e1 100644 --- a/.agents/skills/changelog-entries/SKILL.md +++ b/.agents/skills/changelog-entries/SKILL.md @@ -1,7 +1,7 @@ --- name: changelog-entries description: > - Write changelog entries for CHANGELOG.md. Use when work has been completed + Write changelog entries for CHANGELOG.md or CHANGELOG-WIP.md. Use when work has been completed and changelog entries need to be added, or when the user asks to write, add, or update changelog entries, release notes, or document changes. Triggers on requests like "add changelog entry", "update the changelog", "write release notes", or after completing a feature/fix that needs documenting. @@ -13,8 +13,10 @@ Write entries that match the established format in the target changelog file. ## Determine Target File -1. If the user specifies a file, use that, otherwise use `CHANGELOG.md`. -2. Read the first ~80 lines of the target file to confirm the current format and find the insertion point. +1. If the user specifies a file, use that. +2. If both `CHANGELOG.md` and `CHANGELOG-WIP.md` exist, ask the user which to target. +3. If only one exists, use that file. +4. Read the first ~80 lines of the target file to confirm the current format and find the insertion point. ## CHANGELOG.md Format @@ -26,7 +28,7 @@ Each entry is a `- ` prefixed line. No blank lines between entries within a sect ## Unreleased - Added `craft\helpers\SomeHelper::someMethod()`. -- Fixed a bug where something wasn't working properly. ([#12345](https://github.com/craftcms/cms/pull/12345)) +- Fixed a bug where something wasn't working properly. ([#12345](https://github.com/craftcms/cms/issues/12345)) - Deprecated `craft\old\Thing`. `craft\new\Thing` should be used instead. ``` @@ -41,6 +43,23 @@ Each entry is a `- ` prefixed line. No blank lines between entries within a sect > Important note about breaking changes. ``` +## CHANGELOG-WIP.md Format + +Work-in-progress changelog for the next major version. Entries organized by domain under `##` headers (e.g., `## Fields`, `## Elements`, `## Auth`). Within a domain, entries may be further grouped under `###`/`####` subheaders like `### Added`, `### Deprecations`, `### Events`. + +```markdown +## Fields + +- Added `CraftCms\Cms\Field\NewField`. +- Deprecated `craft\fields\OldField`. `CraftCms\Cms\Field\NewField` should be used instead. + +### Events + +- Deprecated `craft\events\OldEvent`. `CraftCms\Cms\New\Events\NewEvent` should be used instead. +``` + +Place new entries under the most appropriate existing `##` domain section, or create a new one if none fits. Group entries by type: Added first, then Deprecated, then Removed. + ## Writing Rules 1. **Start with a past-tense verb** — capitalize it: @@ -57,9 +76,9 @@ Each entry is a `- ` prefixed line. No blank lines between entries within a sect 4. **End entries with a period.** -5. **Link issues/PRs** at the end when applicable, prefer PRs when there is one: - - PRs: `([#12345](https://github.com/craftcms/cms/pull/12345))` +5. **Link issues/PRs** at the end when applicable: - Issues: `([#12345](https://github.com/craftcms/cms/issues/12345))` + - PRs: `([#12345](https://github.com/craftcms/cms/pull/12345))` - Security: `(GHSA-xxxx-xxxx-xxxx)` - External repos: `([craftcms/commerce#4006](https://github.com/craftcms/commerce/issues/4006))` diff --git a/.agents/skills/changelog-entries/references/entry-templates.md b/.agents/skills/changelog-entries/references/entry-templates.md index 2dd6bdb761f..c20f72ace22 100644 --- a/.agents/skills/changelog-entries/references/entry-templates.md +++ b/.agents/skills/changelog-entries/references/entry-templates.md @@ -64,7 +64,7 @@ **Bug fix:** ``` -- Fixed a bug where something wasn't working properly. ([#12345](https://github.com/craftcms/cms/pull/12345)) +- Fixed a bug where something wasn't working properly. ([#12345](https://github.com/craftcms/cms/issues/12345)) - Fixed a bug where Matrix fields in Blocks view could lose their existing values when they became editable. ``` @@ -76,8 +76,8 @@ **JavaScript fix:** ``` -- Fixed a JavaScript error that occurred if a Matrix field's label was hidden. ([#18366](https://github.com/craftcms/cms/pull/18366)) -- Fixed potential JavaScript errors that could occur if a disclosure menu's trigger was missing. ([#18358](https://github.com/craftcms/cms/pull/18358)) +- Fixed a JavaScript error that occurred if a Matrix field's label was hidden. ([#18366](https://github.com/craftcms/cms/issues/18366)) +- Fixed potential JavaScript errors that could occur if a disclosure menu's trigger was missing. ([#18358](https://github.com/craftcms/cms/issues/18358)) ``` **Security fix:** @@ -89,7 +89,7 @@ **Styling fix:** ``` -- Fixed a styling issue with slideouts within Live Preview. ([#18383](https://github.com/craftcms/cms/pull/18383)) +- Fixed a styling issue with slideouts within Live Preview. ([#18383](https://github.com/craftcms/cms/issues/18383)) ``` ## Deprecated @@ -210,8 +210,8 @@ ``` - `CraftCms\Cms\User\Elements\User` now implements `Illuminate\Contracts\Auth\Authenticatable`. - `craft\services\Elements::stopCollectingCacheInfo()` no longer sets the returned duration to the `cacheDuration` config setting if a duration wasn't explicitly declared. ([#16796](https://github.com/craftcms/cms/pull/16796)) -- Element indexes now show "Paste" buttons alongside bulk element action buttons. ([#18427](https://github.com/craftcms/cms/pull/18427)) -- `slug` columns referenced in element queries' `select`, `where`, or `orderBy` expressions now explicitly resolve to `elements_sites.slug`. ([#18416](https://github.com/craftcms/cms/pull/18416)) +- Element indexes now show "Paste" buttons alongside bulk element action buttons. ([#18427](https://github.com/craftcms/cms/issues/18427)) +- `slug` columns referenced in element queries' `select`, `where`, or `orderBy` expressions now explicitly resolve to `elements_sites.slug`. ([#18416](https://github.com/craftcms/cms/issues/18416)) - The `maxCachedCloudImageSize` config setting is now set to `0` by default. ([#17997](https://github.com/craftcms/cms/pull/17997)) ``` diff --git a/.agents/skills/testing-guidelines/SKILL.md b/.agents/skills/testing-guidelines/SKILL.md index 8a95abae4da..b7a80b693bd 100644 --- a/.agents/skills/testing-guidelines/SKILL.md +++ b/.agents/skills/testing-guidelines/SKILL.md @@ -44,9 +44,7 @@ uses(UnitTestCase::class)->in('Unit'); - For element traits, create minimal test elements that override only what is needed. - Use Laravel event fakes/listeners to assert dispatch, cancellation, or data changes. - Use Pest's `->with()` data providers to consolidate tests that share the same structure but differ only in input/expected values. Use named dataset entries for clarity. -- Avoid long chains of `toContain()` / `not()->toContain()` assertions against rendered HTML. They tend to test incidental markup, labels, ordering, and template structure instead of behavior. Prefer assertions that target the semantic contract directly, such as input names, selected values, option values, or data attributes. Keep raw string containment assertions for small, stable strings that are themselves the contract. - Tests that assert Yii2 backwards-compatibility surfaces (legacy aliases, `ValidateMixin` helpers like `hasErrors()`, other adapter-only behavior) must live in `yii2-adapter/tests-laravel/`, not `tests/Feature/` or `tests/Unit/`. -- Test actual behavior and ensure assertions aren't brittle ## When to Load References diff --git a/.gitattributes b/.gitattributes index 8803b908dd3..d52ed1446a7 100644 --- a/.gitattributes +++ b/.gitattributes @@ -7,8 +7,12 @@ /.gitattributes export-ignore /.github/ export-ignore /.gitignore export-ignore +/.husky/ export-ignore /.lando.yml export-ignore -/.vite-hooks/ export-ignore +/.lintstagedrc.json export-ignore +/.nvmrc export-ignore +/.prettierignore export-ignore +/.prettierrc.json export-ignore /CHANGELOG-WIP.md export-ignore /CHANGELOG.md export-ignore /README.md export-ignore @@ -23,8 +27,6 @@ /package.json export-ignore /packages/ export-ignore /phpstan.neon export-ignore -/resources/css/ export-ignore -/resources/js/ export-ignore /scripts/ export-ignore /src/web/assets/**/src/ export-ignore /stubs/ export-ignore @@ -36,9 +38,6 @@ # Ignore exporting the adapter as it will be split off and released on its own. /yii2-adapter export-ignore -# Workbench is only for development -/workbench export-ignore - # Identify generated files /resources/translations/a*/app.php linguist-generated=true /resources/translations/c*/app.php linguist-generated=true @@ -61,8 +60,8 @@ /src/web/assets/**/dist/**/*.min.js linguist-generated=true /src/web/assets/**/dist/**/*.min.js.map linguist-generated=true -# Built CMS assets generated files -/cms-assets/resources/**/* linguist-generated=true +# resources/build generated files +/resources/build/**/* linguist-generated=true # Auto detect text files and perform LF normalization * text=auto diff --git a/.github/actions/run-tests/action.yml b/.github/actions/run-tests/action.yml index ad3f0677b66..be11816c7ce 100644 --- a/.github/actions/run-tests/action.yml +++ b/.github/actions/run-tests/action.yml @@ -33,7 +33,7 @@ runs: uses: shivammathur/setup-php@v2 with: php-version: ${{ inputs.php-version }} - extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, sqlite, pdo_sqlite, bcmath, soap, intl, gd, exif, iconv, imagick, fileinfo, ffi + extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, sqlite, pdo_sqlite, bcmath, soap, intl, gd, exif, iconv, imagick, fileinfo tools: composer:v2 ini-values: display_errors=On, memory_limit=2G coverage: none diff --git a/.github/instructions/a11y.instructions.md b/.github/instructions/a11y.instructions.md index 08e3c83c902..aa3a8ef2a87 100644 --- a/.github/instructions/a11y.instructions.md +++ b/.github/instructions/a11y.instructions.md @@ -1,6 +1,6 @@ --- description: "Guidance for creating more accessible code" -applyTo: "resources/js/**,resources/css/**,resources/templates/**,packages/craftcms-ui/src/**" +applyTo: "resources/js/**,resources/css/**,resources/templates/**,packages/craftcms-cp/src/**" --- # Accessibility instructions @@ -11,11 +11,11 @@ You are an expert in accessibility with deep software engineering expertise. - Conform to [WCAG 2.2 Level AA](https://www.w3.org/TR/WCAG22/). - Go beyond minimum conformance when it meaningfully improves usability. -- UI components are defined as Lit Web Components in the component library (`@craftcms/ui`) or as Vue components in `./resources/js/`. You SHOULD use the component patterns as defined. Do not recreate patterns. +- UI components are defined as Lit Web Components in the component library (`@craftcms/cp`) or as Vue components in `./resources/js/`. You SHOULD use the component patterns as defined. Do not recreate patterns. - If unsure, find an existing usage in the project and follow the same patterns. - Ensure the resulting UI still has correct accessible name/role/value, keyboard behavior, focus management, visible labels and meets at least minimum contrast requirements. - If a needed component does not exist, prefer native HTML elements/attributes over ARIA. - - The `@craftcms/ui` component library should include components that can be reused by plugin developers, or outside the context of this application. Vue components should be used for application-specific UI. + - The `@craftcms/cp` component library should include components that can be reused by plugin developers, or outside the context of this application. Vue components should be used for application-specific UI. - Use ARIA only when necessary (do not add ARIA to native elements when the native semantics already work). - Ensure correct accessible **name, role, value, states, and properties**. - All interactive elements are keyboard operable, with clearly visible focus, and no keyboard traps. diff --git a/.github/instructions/php.instructions.md b/.github/instructions/php.instructions.md deleted file mode 100644 index 724c52546c1..00000000000 --- a/.github/instructions/php.instructions.md +++ /dev/null @@ -1,167 +0,0 @@ ---- -description: "PHP 8.4 and 8.5 language and review guidance" -applyTo: "**/*.php" ---- - -# PHP 8.5 instructions - -This project requires PHP 8.5. Treat all PHP 8.4 and 8.5 syntax below as valid. Do not report it as a parse error, require an older equivalent, or suggest compatibility with PHP 8.3 and below. - -## PHP 8.4 - -### Property hooks - -Properties may define `get` and `set` hooks. Hooks may use blocks or expression bodies; an implicit setter parameter is named `$value`. - -```php -class User -{ - public string $firstName { - set => ucfirst(strtolower($value)); - } - - public string $fullName { - get => "$this->firstName $this->lastName"; - } - - public string $lastName { - set(string|Stringable $value) { - $this->lastName = trim((string) $value); - } - } -} -``` - -- A hook that refers to its own property as `$this->property` uses a backing value. Otherwise the property is virtual and has no storage. -- `set => expression` stores the expression result in the backing value. A block setter must assign the backing value itself when storage is intended. -- A setter parameter may be contravariant (wider) than the property type. -- A virtual property supports only the operations for which it defines hooks. -- Hooks are supported on promoted properties, in interfaces, and in abstract classes. Hooks and individual properties may be `final`. -- A child hook can invoke its parent hook with `parent::$property::get()` or `parent::$property::set($value)`. -- `&get` returns by reference. Indirect mutation such as `$object->items[] = $item` requires reference-compatible hook behavior. -- Property hooks are not supported on `static` or `readonly` properties. - -### Asymmetric property visibility - -Read and write visibility may differ. The first visibility controls reads; `private(set)` or `protected(set)` controls writes. - -```php -class Post -{ - public function __construct( - public private(set) int $id, - public protected(set) string $title, - ) {} -} -``` - -- Only typed properties support asymmetric visibility. -- Set visibility must be the same as or more restrictive than read visibility. -- `private(set)` is valid syntax with no internal spaces and implies a final property. -- References and indirect array mutation use set visibility. -- PHP 8.4 supports this on instance properties; PHP 8.5 also supports it on static properties. - -### Other language and core features - -- A `new` expression can be dereferenced without parentheses: `new Service()->run()`. -- `#[\Deprecated]` may annotate functions, methods, and class constants and emits `E_USER_DEPRECATED` when used. -- Reflection supports lazy ghosts and proxies through `ReflectionClass::newLazyGhost()`, `newLazyProxy()`, and related lazy-object methods. -- `exit()` and `die()` behave like functions: they can be first-class callables and follow `strict_types` and normal argument coercion. -- `request_parse_body()` parses URL-encoded or multipart bodies for non-POST requests. -- The new `Dom` namespace provides HTML5/WHATWG-compliant DOM classes; legacy `DOM*` classes remain available. -- `BcMath\Number` provides immutable, object-oriented arbitrary-precision numbers with operator support. -- `array_find()`, `array_find_key()`, `array_any()`, and `array_all()` provide native callback-based array searches and predicates. -- `RoundingMode` is accepted by `round()` and adds `PositiveInfinity`, `NegativeInfinity`, `TowardsZero`, and `AwayFromZero`. -- Date/time APIs support creation from timestamps and getting or setting microseconds. -- New multibyte helpers include `mb_trim()`, `mb_ltrim()`, `mb_rtrim()`, `mb_ucfirst()`, and `mb_lcfirst()`. -- New standard helpers include `http_get_last_response_headers()`, `http_clear_last_response_headers()`, `fpow()`, and `grapheme_str_split()`. -- `XMLReader` and `XMLWriter` have `from*()` and `to*()` factories for strings, URIs, streams, and memory. -- PCRE supports variable-length lookbehind and the `r` caseless-restrict modifier. -- PDO supports driver-specific subclasses such as `Pdo\Mysql`, `Pdo\Pgsql`, and `Pdo\Sqlite`, including `PDO::connect()`. - -## PHP 8.5 - -### Pipe operator - -`|>` evaluates its left operand, passes that value as the single argument to the callable on the right, and evaluates to the result. - -```php -$slug = $title - |> trim(...) - |> (fn(string $value): string => str_replace(' ', '-', $value)) - |> strtolower(...); -``` - -- The right operand may be any expression that evaluates to a callable accepting one non-reference argument. -- First-class callables such as `trim(...)`, closures, and invokable objects are valid. -- Parenthesize an arrow function used as the right operand. -- Each stage receives exactly the previous stage's result. Use a closure when extra arguments are needed. - -### Clone with changed properties - -`clone` also has function syntax and can be a first-class callable. Its second argument replaces properties after the shallow copy and after `__clone()` runs, including `readonly` properties where set visibility permits it. - -```php -$published = clone($draft, [ - 'status' => Status::Published, - 'publishedAt' => new DateTimeImmutable(), -]); -``` - -Replacements run in array iteration order and follow normal assignment rules for visibility, types, hooks, `__set()`, and dynamic properties; only the `readonly` state is temporarily unlocked. - -### Constant expressions - -Static closures, first-class callables, and casts are valid constant expressions, including in constants, attributes, property defaults, and parameter defaults. - -```php -const NORMALIZE = strtolower(...); -const DEFAULT_LIMIT = (int) 10.5; - -const VALIDATE = static function (string $value): bool { - return $value !== ''; -}; - -function map(Closure $callback = strtoupper(...)): array -{ - // ... -} -``` - -- A constant-expression closure must be `static` and cannot capture variables. Arrow functions are not supported there because they implicitly capture scope. -- A constant-expression first-class callable must directly name a free-standing function or static method. - -### Attributes and declarations - -- `#[\NoDiscard]` marks a function or method return value as significant. Intentionally ignore it with the new `(void)` cast: `(void) $service->save()`. -- Attributes may annotate global compile-time constants declared with `const`; `#[\Deprecated]` is valid on global constants and traits too. -- `#[\DelayedTargetValidation]` defers invalid-target checks for an attribute until `ReflectionAttribute::newInstance()`. -- `#[\Override]` may annotate properties as well as methods. -- Asymmetric visibility is valid on static properties: `public private(set) static int $count = 0;`. -- Promoted properties may be `final`: `public function __construct(public final string $name) {}`. -- Fatal errors include backtraces by default, controlled by `fatal_error_backtraces`. - -### New and expanded APIs - -- The always-enabled `Uri` extension provides RFC 3986 URI and WHATWG URL implementations. -- `array_first()` and `array_last()` return the first or last array value, or `null` for an empty array. -- `Closure::getCurrent()` provides the currently executing closure, including for recursive anonymous functions. -- `get_error_handler()` and `get_exception_handler()` return the active handlers. -- `IntlListFormatter` formats localized conjunction, disjunction, and unit lists. -- `FILTER_THROW_ON_FAILURE` makes filter validation failures throw; it cannot be combined with `FILTER_NULL_ON_FAILURE`. -- Cookie and session APIs accept the `partitioned` option. -- `getimagesize()` supports HEIF/HEIC and, with libxml, SVG. -- `Dom\Element::$outerHTML`, `Dom\ParentNode::$children`, `Dom\Element::getElementsByClassName()`, and `Dom\Element::insertAdjacentHTML()` are available. -- `grapheme_levenshtein()` calculates grapheme-aware edit distance. -- `curl_share_init_persistent()` creates persistent cURL share handles for cross-request connection reuse. -- `flock()` supports zlib streams. - -## Review rules - -- Prefer PHP 8.5 syntax when it makes code clearer; do not request compatibility workarounds for older PHP versions. -- Do not mistake a hook's assignment to its own property for infinite recursion; it accesses the backing value. -- Do not mistake `private(set)`, `protected(set)`, `|>`, `(void)`, `clone($object, [...])`, callable constants, or `new Class()->method()` for invalid syntax. -- Flag real hook issues: accidental virtual properties, missing backing assignments, invalid indirect mutation, incompatible setter types, or writes outside set visibility. -- Flag discarded `#[\NoDiscard]` results unless explicitly cast to `(void)`. -- Flag PHP 8.4/8.5 deprecations, especially implicit nullable parameters (`Type $value = null`), non-canonical casts, semicolon-style `case` statements, backtick execution, `__sleep()`/`__wakeup()`, null array offsets, and incrementing non-numeric strings. -- For exhaustive extension APIs and compatibility changes, consult the official [PHP 8.4 migration guide](https://www.php.net/manual/en/migration84.php) and [PHP 8.5 migration guide](https://www.php.net/manual/en/migration85.php) before claiming an API is unavailable or deprecated. diff --git a/.github/scripts/storybook-preview-comment.cjs b/.github/scripts/storybook-preview-comment.cjs deleted file mode 100644 index 7c6263ff605..00000000000 --- a/.github/scripts/storybook-preview-comment.cjs +++ /dev/null @@ -1,140 +0,0 @@ -// Creates or updates a single PR comment that links each changed component to -// its rendered story in the deployed Storybook previews. -// -// Invoked from .github/workflows/storybook.yml via actions/github-script: -// -// const run = require('./.github/scripts/storybook-preview-comment.cjs') -// await run({github, context}) -// -// The deploy results/URLs are passed in through the environment (CP_RESULT, -// CP_URL, RESOURCES_RESULT, RESOURCES_URL) so untrusted values never get -// interpolated into the workflow's inline script. - -const MARKER = ''; - -// Directory portion of a story's importPath, normalized for comparison against -// the repo-relative paths returned by the GitHub API. -const dirOf = (p) => p.replace(/^\.\//, '').split('/').slice(0, -1).join('/'); - -// Storybook publishes an index of every story at `/index.json`. We use -// it to turn a changed file into a deep link to its rendered component. -async function storyIndex(url) { - try { - const res = await fetch(`${url}/index.json`); - if (!res.ok) return []; - return Object.values((await res.json()).entries || {}); - } catch { - return []; - } -} - -// Build the markdown section for one preview: an "open Storybook" link plus a -// list of the components touched by this PR, each deep-linked into the preview. -async function sectionFor(preview, changed) { - if (preview.result !== 'success' || !preview.url) { - return `**${preview.name}** — ⚠️ deploy ${preview.result}, no preview available`; - } - - const entries = await storyIndex(preview.url); - - // A component "changed" if any changed file lives in the same directory as one - // of this Storybook's story entries. Collapse the several entries per story - // file down to one link per component, preferring the Docs page when present. - // - // Scope the changed-file matching to the relevant subtree so similarly-named - // directories elsewhere in the repo don't create false positives. - const baseDir = - preview.name === '@craftcms/ui' - ? 'packages/craftcms-ui' - : preview.name === 'resources/js' - ? 'resources/js' - : null; - - const changedInScope = baseDir - ? changed - .filter((file) => file.startsWith(`${baseDir}/`)) - .map((file) => file.slice(baseDir.length + 1)) - : changed; - - const byImport = new Map(); - for (const entry of entries) { - if (!entry?.importPath) continue; - const dir = dirOf(entry.importPath); - if (!dir || !changedInScope.some((file) => file.startsWith(`${dir}/`))) - continue; - const current = byImport.get(entry.importPath); - if (!current || (entry.type === 'docs' && current.type !== 'docs')) { - byImport.set(entry.importPath, entry); - } - } - - const links = [...byImport.values()] - .sort((a, b) => a.title.localeCompare(b.title)) - .map((entry) => { - const kind = entry.type === 'docs' ? 'docs' : 'story'; - return `- [${entry.title}](${preview.url}/?path=/${kind}/${entry.id})`; - }); - - const heading = `**${preview.name}** — [open Storybook](${preview.url})`; - return links.length - ? `${heading}\n\nChanged components:\n${links.join('\n')}` - : `${heading}\n\n_No changed components detected in this Storybook._`; -} - -module.exports = async ({github, context}) => { - const previews = [ - { - name: '@craftcms/ui', - result: process.env.CP_RESULT, - url: process.env.CP_URL, - }, - { - name: 'resources/js', - result: process.env.RESOURCES_RESULT, - url: process.env.RESOURCES_URL, - }, - ]; - - // Every file changed in this PR (excluding deletions, which no longer have a - // rendered story to point at). - const changed = ( - await github.paginate(github.rest.pulls.listFiles, { - owner: context.repo.owner, - repo: context.repo.repo, - pull_number: context.issue.number, - per_page: 100, - }) - ) - .filter((file) => file.status !== 'removed') - .map((file) => file.filename); - - const sections = []; - for (const preview of previews) { - sections.push(await sectionFor(preview, changed)); - } - - const body = `${MARKER}\n### 📚 Storybook previews\n\n${sections.join('\n\n')}`; - - const {data: comments} = await github.rest.issues.listComments({ - owner: context.repo.owner, - repo: context.repo.repo, - issue_number: context.issue.number, - }); - const existing = comments.find((comment) => comment.body.includes(MARKER)); - - if (existing) { - await github.rest.issues.updateComment({ - owner: context.repo.owner, - repo: context.repo.repo, - comment_id: existing.id, - body, - }); - } else { - await github.rest.issues.createComment({ - owner: context.repo.owner, - repo: context.repo.repo, - issue_number: context.issue.number, - body, - }); - } -}; diff --git a/.github/workflows/build-artifacts.yml b/.github/workflows/build-artifacts.yml new file mode 100644 index 00000000000..3ce5a8a18ac --- /dev/null +++ b/.github/workflows/build-artifacts.yml @@ -0,0 +1,51 @@ +name: build-artifacts + +on: + push: + branches: + - main + - '*.x' + + workflow_dispatch: + +permissions: + contents: write + +jobs: + update: + runs-on: ubuntu-24.04 + + strategy: + fail-fast: true + + name: Update build artifacts + + steps: + - name: Checkout code + uses: actions/checkout@v6 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: '8.5' + + - name: Install Composer dependencies + run: composer install --no-interaction --no-progress + + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: '22' + cache: 'npm' + + - name: Install dependencies + run: npm ci + + - name: Run build:all + run: npm run build:all + + - name: Commit build artifacts + uses: stefanzweifel/git-auto-commit-action@v7 + with: + commit_message: Update build artifacts + file_pattern: resources/ diff --git a/.github/workflows/facades.yml b/.github/workflows/facades.yml index 6d6116ccb25..85d88563ff6 100644 --- a/.github/workflows/facades.yml +++ b/.github/workflows/facades.yml @@ -62,7 +62,6 @@ jobs: done php -f vendor/bin/facade.php -- "${facade_classes[@]}" - vendor/bin/pint "${facades[@]}" - name: Commit facade docblocks uses: stefanzweifel/git-auto-commit-action@v7 diff --git a/.github/workflows/js-ci.yml b/.github/workflows/js-ci.yml index f2a48f3a228..4a458739970 100644 --- a/.github/workflows/js-ci.yml +++ b/.github/workflows/js-ci.yml @@ -12,12 +12,9 @@ concurrency: cancel-in-progress: true env: - NODE_VERSION: '24' + NODE_VERSION: '22' PHP_VERSION: '8.5' -permissions: - contents: read - jobs: setup: name: 'Setup / Install + Build + Generate' @@ -34,11 +31,11 @@ jobs: with: php-version: ${{ env.PHP_VERSION }} - - name: Setup Vite+ - uses: voidzero-dev/setup-vp@v1 + - name: Setup Node + uses: actions/setup-node@v4 with: node-version: ${{ env.NODE_VERSION }} - cache: true + cache: 'npm' - name: Compute cache key id: cache-key @@ -47,7 +44,7 @@ jobs: # `testbench typescript:transform` and `testbench wayfinder:generate` # derive their output from controllers, DTOs, and routes in src/. run: | - echo "value=js-ci-v3-${{ runner.os }}-${{ hashFiles('package-lock.json', 'composer.lock', 'package.json', 'packages/*/package.json', 'packages/craftcms-ui/src/**', 'packages/craftcms-ui/tsconfig*.json', 'packages/craftcms-ui/vite.config.*', 'packages/craftcms-ui/tsdown.config.*', 'packages/craftcms-garnish/src/**', 'packages/craftcms-garnish/tsconfig*.json', 'packages/craftcms-garnish/vite.config.*', 'src/**/*.php', 'workbench/**/*.php') }}" >> "$GITHUB_OUTPUT" + echo "value=js-ci-v2-${{ runner.os }}-${{ hashFiles('package-lock.json', 'composer.lock', 'package.json', 'packages/*/package.json', 'packages/craftcms-cp/src/**', 'packages/craftcms-cp/tsconfig*.json', 'packages/craftcms-cp/vite.config.*', 'packages/craftcms-cp/tsdown.config.*', 'src/**/*.php') }}" >> "$GITHUB_OUTPUT" - name: Restore install + build + generated cache id: cache @@ -56,8 +53,7 @@ jobs: path: | node_modules packages/*/node_modules - packages/craftcms-ui/dist - packages/craftcms-garnish/dist + packages/craftcms-cp/dist vendor resources/js/actions resources/js/routes @@ -69,40 +65,24 @@ jobs: if: steps.cache.outputs.cache-hit != 'true' run: composer install --no-interaction --no-progress - - name: Install frontend dependencies - if: steps.cache.outputs.cache-hit != 'true' - run: vp install --frozen-lockfile - env: - CRAFT_FONTAWESOME_TOKEN: ${{ secrets.CRAFT_FONTAWESOME_TOKEN }} - - # Build the garnish package so its `dist/*.d.ts` exist — `vue-tsc` resolves - # `@craftcms/garnish` from `dist` (its `types`), and dist is gitignored. - # Without this the typecheck job fails to resolve the module. - - name: Build @craftcms/garnish - if: steps.cache.outputs.cache-hit != 'true' - run: vp run build:garnish - - - name: Build @craftcms/ui + - name: Install npm dependencies if: steps.cache.outputs.cache-hit != 'true' - run: vp run build:ui + run: npm ci - # `build:cp` does not produce the Custom Elements Manifest (only the - # Storybook pre-hooks do), so generate it explicitly — it lands in the - # packages/craftcms-cp/dist cache path above for the downstream jobs. - - name: Build Custom Elements Manifest + - name: Build @craftcms/cp if: steps.cache.outputs.cache-hit != 'true' - run: vp run @craftcms/ui#build:manifest + run: npm run build:cp - name: Generate TypeScript types if: steps.cache.outputs.cache-hit != 'true' - run: vp run generate:types + run: npm run generate:types - name: Generate Wayfinder routes if: steps.cache.outputs.cache-hit != 'true' - run: vp run generate:wayfinder + run: npm run generate:wayfinder eslint: - name: 'Code Quality / Oxlint' + name: 'Code Quality / ESLint' runs-on: ubuntu-latest timeout-minutes: 5 needs: setup @@ -110,11 +90,11 @@ jobs: - name: Checkout code uses: actions/checkout@v4 - - name: Setup Vite+ - uses: voidzero-dev/setup-vp@v1 + - name: Setup Node + uses: actions/setup-node@v4 with: node-version: ${{ env.NODE_VERSION }} - cache: true + cache: 'npm' - name: Restore install + build + generated cache uses: actions/cache@v4 @@ -122,8 +102,7 @@ jobs: path: | node_modules packages/*/node_modules - packages/craftcms-ui/dist - packages/craftcms-garnish/dist + packages/craftcms-cp/dist vendor resources/js/actions resources/js/routes @@ -131,8 +110,8 @@ jobs: resources/js/generated key: ${{ needs.setup.outputs.cache-key }} - - name: Run Oxlint - run: vp lint resources/js/ + - name: Run ESLint + run: npm run lint:js typecheck: name: 'Code Quality / TypeScript' @@ -143,11 +122,11 @@ jobs: - name: Checkout code uses: actions/checkout@v4 - - name: Setup Vite+ - uses: voidzero-dev/setup-vp@v1 + - name: Setup Node + uses: actions/setup-node@v4 with: node-version: ${{ env.NODE_VERSION }} - cache: true + cache: 'npm' - name: Restore install + build + generated cache uses: actions/cache@v4 @@ -155,8 +134,7 @@ jobs: path: | node_modules packages/*/node_modules - packages/craftcms-ui/dist - packages/craftcms-garnish/dist + packages/craftcms-cp/dist vendor resources/js/actions resources/js/routes @@ -168,41 +146,4 @@ jobs: # generate:wayfinder, which need PHP/Composer that this job doesn't set # up — the setup job already produced and cached the output). - name: Run TypeScript type check - run: vp run typecheck - - test-ui: - name: 'Tests / @craftcms/ui' - runs-on: ubuntu-latest - timeout-minutes: 10 - needs: setup - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Setup Vite+ - uses: voidzero-dev/setup-vp@v1 - with: - node-version: ${{ env.NODE_VERSION }} - cache: true - - - name: Restore install + build + generated cache - uses: actions/cache@v4 - with: - path: | - node_modules - packages/*/node_modules - packages/craftcms-ui/dist - packages/craftcms-garnish/dist - vendor - resources/js/actions - resources/js/routes - resources/js/wayfinder - resources/js/generated - key: ${{ needs.setup.outputs.cache-key }} - - # The storybook tests run in real Chromium via @vitest/browser-playwright. - - name: Install Playwright Chromium - run: vp exec playwright install --with-deps chromium - - - name: Run @craftcms/ui tests - run: vp run test:ui + run: npm run typecheck diff --git a/.github/workflows/laravel-ci.yml b/.github/workflows/laravel-ci.yml index bcf61ae29fd..b79908c5471 100644 --- a/.github/workflows/laravel-ci.yml +++ b/.github/workflows/laravel-ci.yml @@ -11,9 +11,6 @@ concurrency: group: laravel-ci-${{ github.ref }} cancel-in-progress: true -permissions: - contents: read - jobs: pint: name: 'Code Quality / Pint' @@ -104,7 +101,7 @@ jobs: - name: Install composer dependencies uses: ramsey/composer-install@v3 - + - name: PHPStan Cache uses: actions/cache@v4 with: @@ -129,23 +126,6 @@ jobs: - name: Checkout code uses: actions/checkout@v4 - # ComponentManifestDriftTest needs the Custom Elements Manifest, which is - # gitignored (packages/craftcms-ui/dist). The cache key hashes everything - # the analyzer reads, so a hit is never stale; the cache itself is shared - # repo-wide, so whichever workflow generates it first serves the rest. On - # a miss the pinned npx run (~seconds) needs no npm install. - - name: Restore Custom Elements Manifest - id: cem - uses: actions/cache@v4 - with: - path: packages/craftcms-ui/dist/custom-elements.json - key: cem-${{ hashFiles('packages/craftcms-ui/src/components/**', 'packages/craftcms-ui/custom-elements-manifest.config.mjs', 'packages/craftcms-ui/package.json', 'packages/craftcms-ui/tsconfig.json') }} - - - name: Generate Custom Elements Manifest - if: steps.cem.outputs.cache-hit != 'true' - working-directory: packages/craftcms-ui - run: npx --yes @custom-elements-manifest/analyzer@0.11.0 analyze - - name: Run tests uses: ./.github/actions/run-tests with: @@ -213,10 +193,6 @@ jobs: - name: Checkout code uses: actions/checkout@v4 - - name: Install libvips - if: matrix.os == 'ubuntu-latest' && matrix.db == 'sqlite' - run: sudo apt-get update && sudo apt-get install -y libvips-dev - - name: Copy tests .env shell: bash run: | @@ -226,8 +202,6 @@ jobs: - name: Run tests uses: ./.github/actions/run-tests - env: - CRAFT_REQUIRE_VIPS: ${{ matrix.os == 'ubuntu-latest' && matrix.db == 'sqlite' && '1' || '' }} with: test-command: ./vendor/bin/pest --ci --compact --testsuite=Feature github-token: ${{ secrets.GITHUB_TOKEN }} @@ -247,7 +221,7 @@ jobs: - name: Run tests uses: ./.github/actions/run-tests with: - test-command: yii2-adapter/vendor/bin/pest --ci --compact --configuration ./yii2-adapter/phpunit.xml.dist --test-directory ./tests-laravel + test-command: vendor/bin/pest --ci --compact --configuration ./yii2-adapter/phpunit.xml.dist --test-directory ./yii2-adapter/tests-laravel github-token: ${{ secrets.GITHUB_TOKEN }} packagist-username: ${{ secrets.packagist_username }} packagist-token: ${{ secrets.packagist_token }} diff --git a/.github/workflows/monorepo-split.yml b/.github/workflows/monorepo-split.yml index 1c4a9ee8b96..d201bb53a02 100644 --- a/.github/workflows/monorepo-split.yml +++ b/.github/workflows/monorepo-split.yml @@ -9,9 +9,6 @@ on: - feature/split-packages tags: '*' -permissions: - contents: read - jobs: split-monorepo: runs-on: ubuntu-latest @@ -39,7 +36,7 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GH_ACCESS_TOKEN }} with: - tag: ${{ github.ref_name }} + tag: ${GITHUB_REF#refs/tags/} package_directory: 'yii2-adapter' repository_organization: 'craftcms' repository_name: 'yii2-adapter' diff --git a/.github/workflows/storybook.yml b/.github/workflows/storybook.yml deleted file mode 100644 index 4ff1a28fddf..00000000000 --- a/.github/workflows/storybook.yml +++ /dev/null @@ -1,239 +0,0 @@ -name: 'Storybook' -on: - workflow_dispatch: - push: - branches: - - 6.x - paths: - - 'packages/craftcms-ui/**' - - 'packages/craftcms-garnish/**' - - 'resources/js/**' - - 'src/**/*.php' - pull_request: - paths: - - 'packages/craftcms-ui/**' - - 'packages/craftcms-garnish/**' - - 'resources/js/**' - - 'src/**/*.php' - -concurrency: - group: storybook-${{ github.event.pull_request.number || github.ref }} - cancel-in-progress: true - -env: - NODE_VERSION: '24' - PHP_VERSION: '8.5' - -permissions: - contents: read - -jobs: - # Gate: install deps, build the packages, and generate the TS/wayfinder - # output. The deploy jobs only run once this succeeds, so we never publish a - # Storybook built from assets that don't compile. Results are cached and - # restored by the parallel deploy jobs below. - build-assets: - name: 'Build assets' - runs-on: ubuntu-latest - timeout-minutes: 15 - outputs: - cache-key: ${{ steps.cache-key.outputs.value }} - deploy-branch: ${{ steps.branch.outputs.value }} - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: ${{ env.PHP_VERSION }} - - - name: Setup Vite+ - uses: voidzero-dev/setup-vp@v1 - with: - node-version: ${{ env.NODE_VERSION }} - cache: true - - - name: Compute cache key - id: cache-key - # Keep this in sync with .github/workflows/js-ci.yml so the built assets - # and generated files are shared between the two workflows. - run: | - echo "value=js-ci-v3-${{ runner.os }}-${{ hashFiles('package-lock.json', 'composer.lock', 'package.json', 'packages/*/package.json', 'packages/craftcms-ui/src/**', 'packages/craftcms-ui/tsconfig*.json', 'packages/craftcms-ui/vite.config.*', 'packages/craftcms-ui/tsdown.config.*', 'packages/craftcms-garnish/src/**', 'packages/craftcms-garnish/tsconfig*.json', 'packages/craftcms-garnish/vite.config.*', 'src/**/*.php', 'workbench/**/*.php') }}" >> "$GITHUB_OUTPUT" - - - name: Restore install + build + generated cache - id: cache - uses: actions/cache@v4 - with: - path: | - node_modules - packages/*/node_modules - packages/craftcms-ui/dist - packages/craftcms-garnish/dist - vendor - resources/js/actions - resources/js/routes - resources/js/wayfinder - resources/js/generated - key: ${{ steps.cache-key.outputs.value }} - - - name: Install Composer dependencies - if: steps.cache.outputs.cache-hit != 'true' - run: composer install --no-interaction --no-progress - - - name: Install frontend dependencies - if: steps.cache.outputs.cache-hit != 'true' - run: vp install --frozen-lockfile - env: - CRAFT_FONTAWESOME_TOKEN: ${{ secrets.CRAFT_FONTAWESOME_TOKEN }} - - # Build the garnish package so its `dist/*.d.ts` exist — `vue-tsc` resolves - # `@craftcms/garnish` from `dist` (its `types`), and dist is gitignored. - - name: Build @craftcms/garnish - if: steps.cache.outputs.cache-hit != 'true' - run: vp run build:garnish - - - name: Build @craftcms/ui - if: steps.cache.outputs.cache-hit != 'true' - run: vp run build:ui - - - name: Generate TypeScript types - if: steps.cache.outputs.cache-hit != 'true' - run: vp run generate:types - - - name: Generate Wayfinder routes - if: steps.cache.outputs.cache-hit != 'true' - run: vp run generate:wayfinder - - - name: Determine deploy branch - id: branch - run: | - if [ "${{ github.event_name }}" = "pull_request" ]; then - echo "value=pr-${{ github.event.number }}" >> "$GITHUB_OUTPUT" - else - echo "value=${{ github.ref_name }}" >> "$GITHUB_OUTPUT" - fi - - deploy-cp: - name: 'Deploy / craftcms-ui' - runs-on: ubuntu-latest - timeout-minutes: 10 - needs: build-assets - outputs: - url: ${{ steps.deploy.outputs.deployment-url }} - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Setup Vite+ - uses: voidzero-dev/setup-vp@v1 - with: - node-version: ${{ env.NODE_VERSION }} - cache: true - - - name: Restore install + build + generated cache - uses: actions/cache@v4 - with: - path: | - node_modules - packages/*/node_modules - packages/craftcms-ui/dist - packages/craftcms-garnish/dist - vendor - resources/js/actions - resources/js/routes - resources/js/wayfinder - resources/js/generated - key: ${{ needs.build-assets.outputs.cache-key }} - - - name: Build Storybook - run: vp run @craftcms/ui#build:storybook - - - name: Deploy to Cloudflare Pages - id: deploy - uses: cloudflare/wrangler-action@v3 - with: - apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} - accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} - command: pages deploy packages/craftcms-ui/storybook-static --project-name=craftcms-ui-storybook --branch=${{ needs.build-assets.outputs.deploy-branch }} - - deploy-resources: - name: 'Deploy / resources' - runs-on: ubuntu-latest - timeout-minutes: 15 - needs: build-assets - outputs: - url: ${{ steps.deploy.outputs.deployment-url }} - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Setup Vite+ - uses: voidzero-dev/setup-vp@v1 - with: - node-version: ${{ env.NODE_VERSION }} - cache: true - - - name: Restore install + build + generated cache - uses: actions/cache@v4 - with: - path: | - node_modules - packages/*/node_modules - packages/craftcms-ui/dist - packages/craftcms-garnish/dist - vendor - resources/js/actions - resources/js/routes - resources/js/wayfinder - resources/js/generated - key: ${{ needs.build-assets.outputs.cache-key }} - - - name: Build Storybook - # build-assets already ran the transformer and Wayfinder, and their - # output is restored from the cache above. Regenerating would shell out - # to ./vendor/bin/testbench, and this job installs no PHP. - env: - CRAFT_SKIP_PHP_CODEGEN: '1' - run: vp run build:storybook - - - name: Deploy to Cloudflare Pages - id: deploy - uses: cloudflare/wrangler-action@v3 - with: - apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} - accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} - command: pages deploy storybook-static --project-name=craftcms-storybook --branch=${{ needs.build-assets.outputs.deploy-branch }} - - # Single writer for the PR comment. Runs after both deploys (regardless of - # their result) and renders one comment covering both previews, so the two - # parallel jobs never race to create duplicate comments. Skipped entirely if - # the gate failed and neither deploy ran. - comment: - name: 'Comment preview URLs' - runs-on: ubuntu-latest - needs: [deploy-cp, deploy-resources] - if: ${{ always() && github.event_name == 'pull_request' && (needs.deploy-cp.result != 'skipped' || needs.deploy-resources.result != 'skipped') }} - permissions: - contents: read - pull-requests: write - steps: - # Checkout so the comment script is on disk for github-script to require. - # Only the scripts directory is needed, so keep the checkout sparse. - - name: Checkout comment script - uses: actions/checkout@v4 - with: - sparse-checkout: .github/scripts - sparse-checkout-cone-mode: false - - - name: Create or update the preview comment - uses: actions/github-script@v7 - env: - CP_RESULT: ${{ needs.deploy-cp.result }} - CP_URL: ${{ needs.deploy-cp.outputs.url }} - RESOURCES_RESULT: ${{ needs.deploy-resources.result }} - RESOURCES_URL: ${{ needs.deploy-resources.outputs.url }} - with: - script: | - const run = require('./.github/scripts/storybook-preview-comment.cjs') - await run({github, context}) diff --git a/.github/workflows/sync-cms-assets.yml b/.github/workflows/sync-cms-assets.yml deleted file mode 100644 index 40fbbadaacd..00000000000 --- a/.github/workflows/sync-cms-assets.yml +++ /dev/null @@ -1,82 +0,0 @@ -name: Sync CMS Assets - -on: - workflow_dispatch: - push: - branches: - - 6.x - - feature/icons-to-cms-assets - tags: - - '*' - -permissions: - contents: read - -jobs: - sync: - name: Sync CMS assets - runs-on: ubuntu-24.04 - steps: - - name: Checkout - uses: actions/checkout@v6 - - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: '8.5' - tools: composer:v2 - - - name: Setup Vite+ - uses: voidzero-dev/setup-vp@v1 - with: - node-version: '24' - cache: true - - - name: Install frontend dependencies - run: vp install --frozen-lockfile - env: - CRAFT_FONTAWESOME_TOKEN: ${{ secrets.CRAFT_FONTAWESOME_TOKEN }} - - - name: Install Composer dependencies - uses: ramsey/composer-install@v3 - - - name: Copy icons - run: php ./scripts/copyicons.php - - - name: Build assets - run: | - rm -rf cms-assets/resources/build - rm -rf cms-assets/resources/legacy - vp run build:all - - test -f cms-assets/resources/build/manifest.json || { echo "::error::Missing cms-assets/resources/build/manifest.json"; exit 1; } - test -f cms-assets/resources/legacy/cp/dist/cp.js || { echo "::error::Missing cms-assets/resources/legacy/cp/dist/cp.js"; exit 1; } - test -f cms-assets/resources/legacy/cp/dist/css/cp.css || { echo "::error::Missing cms-assets/resources/legacy/cp/dist/css/cp.css"; exit 1; } - test -f cms-assets/resources/icons/index.php || { echo "::error::Missing cms-assets/resources/icons/index.php"; exit 1; } - - - name: Monorepo Split - if: "!startsWith(github.ref, 'refs/tags/')" - uses: danharrin/monorepo-split-github-action@v2.3.0 - env: - GITHUB_TOKEN: ${{ secrets.GH_ACCESS_TOKEN }} - with: - package_directory: 'cms-assets' - repository_organization: 'craftcms' - repository_name: 'cms-assets' - branch: ${{ github.head_ref || github.ref_name }} - user_name: 'shinybrad' - user_email: 'shinybrad@pixelandtonic.com' - - - name: Monorepo Split - if: "startsWith(github.ref, 'refs/tags/')" - uses: danharrin/monorepo-split-github-action@v2.3.0 - env: - GITHUB_TOKEN: ${{ secrets.GH_ACCESS_TOKEN }} - with: - tag: ${{ github.ref_name }} - package_directory: 'cms-assets' - repository_organization: 'craftcms' - repository_name: 'cms-assets' - branch: '6.x' - user_name: 'shinybrad' - user_email: 'shinybrad@pixelandtonic.com' diff --git a/.gitignore b/.gitignore index dc014079afa..2c25645f9eb 100644 --- a/.gitignore +++ b/.gitignore @@ -2,7 +2,6 @@ .env .php-cs-fixer.cache .phpunit.cache -.claude/settings.local.json Source/.idea/* *.log *.bak @@ -32,14 +31,3 @@ resources/js/wayfinder # TypeScript transformer generated files resources/js/generated/* !resources/js/generated/.gitkeep - -# Built CMS assets -cms-assets/resources/build -cms-assets/resources/hot -cms-assets/resources/legacy -cms-assets/resources/icons/* -!cms-assets/resources/icons/custom-icons - -# Storybook build output -/storybook-static -resources/build diff --git a/.husky/.gitignore b/.husky/.gitignore new file mode 100644 index 00000000000..31354ec1389 --- /dev/null +++ b/.husky/.gitignore @@ -0,0 +1 @@ +_ diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100755 index 00000000000..2312dc587f6 --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1 @@ +npx lint-staged diff --git a/.lintstagedrc.mjs b/.lintstagedrc.mjs new file mode 100644 index 00000000000..3558ead5160 --- /dev/null +++ b/.lintstagedrc.mjs @@ -0,0 +1,17 @@ +export default { + 'yii2-adapter/**/*.php': [ + './yii2-adapter/vendor/bin/ecs check --config ./yii2-adapter/ecs.php --ansi --fix', + ], + '!(yii2-adapter)/**/*.php': ['./vendor/bin/rector', './vendor/bin/pint'], + 'yii2-adapter/**/*.scss': [ + 'stylelint --fix --allow-empty-input -c ./yii2-adapter/.stylelintrc.json', + ], + '!(yii2-adapter)/**/*.scss': ['stylelint --fix --allow-empty-input'], + '!(yii2-adapter)/**/*.{html,json,css,scss}': 'prettier --ignore-unknown --write', + // eslint takes the staged files; vue-tsc must run project-wide with no file + // args, otherwise it ignores tsconfig.json and throws TS5112. + 'resources/js/**/*.{ts,vue}': (files) => [ + `eslint ${files.join(' ')}`, + 'vue-tsc --noEmit', + ], +}; diff --git a/.node-version b/.node-version deleted file mode 100644 index a45fd52cc58..00000000000 --- a/.node-version +++ /dev/null @@ -1 +0,0 @@ -24 diff --git a/.npmrc b/.npmrc index e0748a7aefb..cd4642dbf71 100644 --- a/.npmrc +++ b/.npmrc @@ -1,4 +1,2 @@ @fortawesome:registry=https://npm.fontawesome.com/ -@awesome.me:registry=https://npm.fontawesome.com/ //npm.fontawesome.com/:_authToken=${CRAFT_FONTAWESOME_TOKEN} -allow-git=all diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 00000000000..54c65116f15 --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +v24 diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 00000000000..2a3df9da8a8 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,14 @@ +*.md +*.php +composer.lock +**/dist/* +vendor/* +.ddev/* +resources/icons/* +resources/build/* +resources/public/* +resources/js/actions/* +resources/js/routes/* +resources/js/wayfinder/* +yii2-adapter/* +tests-playwright/.authentication.json diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 00000000000..991d63c2661 --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,6 @@ +{ + "singleQuote": true, + "bracketSpacing": false, + "vueIndentScriptAndStyle": true, + "trailingComma": "es5" +} diff --git a/.storybook/main.ts b/.storybook/main.ts index 009e3246e52..e7fc48c2c03 100644 --- a/.storybook/main.ts +++ b/.storybook/main.ts @@ -17,10 +17,7 @@ function getAbsolutePath(value: string): string { } const config: StorybookConfig = { - stories: [ - '../resources/js/**/*.mdx', - '../resources/js/**/*.stories.@(js|jsx|mjs|ts|tsx)', - ], + stories: ['../resources/js/**/*.mdx', '../resources/js/**/*.stories.@(js|jsx|mjs|ts|tsx)'], addons: [ getAbsolutePath('@storybook/addon-themes'), getAbsolutePath('@storybook/addon-docs'), @@ -35,7 +32,7 @@ const config: StorybookConfig = { viteFinal(config) { // Storybook's vue3-vite framework adds its own Vue plugin with default options. // We need to configure `isCustomElement` so Vue treats `craft-*` tags as web - // components (from @craftcms/ui) rather than trying to resolve them as Vue + // components (from @craftcms/cp) rather than trying to resolve them as Vue // components. Since Vite's mergeConfig doesn't deep-merge plugin options, // we remove Storybook's Vue plugin and add our own with the correct config. const filteredPlugins = (config.plugins || []).flat().filter((plugin) => { diff --git a/.storybook/preview.ts b/.storybook/preview.ts index a2ed9d3e6ed..8194479ba14 100644 --- a/.storybook/preview.ts +++ b/.storybook/preview.ts @@ -1,7 +1,7 @@ import type {Preview} from '@storybook/vue3'; import {setup} from '@storybook/vue3'; import {withThemeByDataAttribute} from '@storybook/addon-themes'; -import '@craftcms/ui'; +import '@craftcms/cp'; import '../resources/css/cp.css'; import './preview.css'; import {installInertiaMock, setPageProps} from './inertia-mock'; diff --git a/.vite-hooks/pre-commit b/.vite-hooks/pre-commit deleted file mode 100755 index 85fb65b4fc3..00000000000 --- a/.vite-hooks/pre-commit +++ /dev/null @@ -1 +0,0 @@ -vp staged diff --git a/AGENTS.md b/AGENTS.md index 5616bc0fb37..59cb48036af 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -10,42 +10,8 @@ New core work should be Laravel-first. Do not add Yii dependencies to `src/`; pu This is a large codebase with some large files. Search narrowly before reading full files. -## Commands - -### PHP - -```bash -composer tests # Run main tests only (tests/) -composer tests-adapter # Run yii2-adapter tests only -./vendor/bin/pest tests/path/to/TestFile.php # Run a main test file -composer tests-adapter -- yii2-adapter/tests-laravel/path/to/TestFile.php -composer tests-adapter -- --filter "test description" -composer fix-cs # Run Rector + Pint + ECS (auto-fixes code style) -composer phpstan # Run PHPStan static analysis (level 5) -composer ci # Full CI pipeline: pint, rector, phpstan, tests, tests-adapter -composer serve # Start the testbench dev server -``` - -### Frontend - -```bash -vp dev # Vite dev server (HMR) for the Inertia/Vue CP -vp build # Production Vite build (cp.ts + legacy.ts + cp.css) -vp run build:all # Build legacy bundles + CP component package + Vite -vp run dev:bundles # Webpack dev watch for legacy jQuery bundles -vp run dev:ui # Dev build for the @craftcms/ui component package -vp run build:ui # Production build for the @craftcms/ui component package -vp check # Oxfmt + Oxlint + TypeScript type-check -vp run typecheck # TypeScript type-check only (vue-tsc) -vp run test:ui # Vitest tests for the @craftcms/ui package -``` - -> **Note:** `@craftcms/ui` must be built (`vp run build:ui`) before building or running the main Vite app if you've -> made changes to it. - ## Testing -- Main and adapter tests are separate Pest suites. Never mix `tests/...` and `yii2-adapter/tests-laravel/...` in one Pest invocation. Run adapter tests through `composer tests-adapter`; passing the adapter PHPUnit configuration alone is insufficient because Pest also needs the adapter test directory to load `yii2-adapter/tests-laravel/Pest.php`. - Pest tests using `tests/TestCase.php` or `yii2-adapter/tests-laravel/TestCase.php` share a database lock. If another process has the lock, the next process will wait and print `Another Pest process is already using the shared test database. Waiting for the lock...`. - `tests/Unit/` tests using `UnitTestCase` do not take that lock and can still run concurrently. - When writing tests, prefer real code paths, or use Laravel facades to set up service mocks. @@ -62,67 +28,9 @@ vp run test:ui # Vitest tests for the @craftcms/ui package - Laravel events are the native event system. Yii event constants and bridge registration belong in `yii2-adapter` for compatibility only. - Services that should be singletons generally use Laravel's `#[Singleton]` or `#[Scoped]` attribute. -## Frontend Architecture - -The CP has two parallel rendering stacks that are actively being consolidated: - -**Inertia/Vue (new):** `resources/js/cp.ts` is the entrypoint. Inertia pages live in `resources/js/pages/`, shared Vue -components in `resources/js/common/`. `HandleInertiaRequests` middleware provides shared CP config, navigation, and -global props to all Inertia pages. The root Blade template is `resources/views/app.blade.php`. - -VueUse (`@vueuse/core`) is installed — before hand-rolling composable behavior in Vue code (event listeners with -mount/unmount cleanup, media queries, storage, observers, etc.), check whether a VueUse utility already covers it -(e.g. `useEventListener` accepts ref targets and cleans up automatically, `useMediaQuery`). - -**Legacy jQuery (old):** `resources/js/legacy.ts` loads the old surface. The individual jQuery modules live in -`packages/craftcms-legacy/` and are bundled with webpack (separate from Vite). Pages still on this stack return `view()` -from their controllers. - -**`CpScreenResponse`** is an intermediate state used by pages mid-migration: the outer CP shell is rendered via Inertia, -but the inner content is PHP-rendered HTML injected into the page. Controllers returning `CpScreenResponse` are -partially migrated; full migration means converting the inner form to a Vue component and switching to -`Inertia::render()`. - -**Packages:** +## Frontend -- `packages/craftcms-ui` — the `@craftcms/ui` component library (Web Components built on Lit/WebAwesome). Imported as - `@craftcms/ui` in Vue pages. Has its own build (`npm run build:ui`) and Vitest tests (`npm run test:ui`). -- `packages/craftcms-legacy` — webpack-bundled jQuery modules used by legacy CP surfaces. - -**TypeScript types** for PHP classes are auto-generated via `spatie/laravel-typescript-transformer` and written to -`resources/js/generated/`. This runs automatically on `vite dev`/`vite build` when relevant PHP files change; run -`./vendor/bin/testbench typescript:transform` manually if needed. - -**Wayfinder** generates typed route URL helpers into `resources/js/` from Laravel routes. Regenerate with -`./vendor/bin/testbench wayfinder:generate`. - -**Custom elements** (anything with a hyphen in the tag name) are treated as native web components by the Vue compiler — -they pass through to the browser without Vue trying to resolve them as Vue components. - -### PHP UI Components - -Server-rendered CP UI is moving onto the `@craftcms/ui` web components via PHP component classes in -`src/Cp/Components/`: - -- Each component (e.g. `Button`, `Checkbox`, `Lightswitch`, `Field`) extends `ViewComponent` and renders its custom - element tag (``, ``, …) with typed fluent setters, named-slot handling, and lazily - evaluated Closure values (DI-resolved, Filament-style). Build instances with `Component::make()->…`; - `configure(array)` maps config-array keys (kebab/snake camelized) onto the setters. -- `ComponentRegistry` (`#[Singleton]`, plugin-extensible) maps template-facing names to component classes and backs - the `ui()` PHP helper and the `ui` Twig function. -- `CraftCms\Cms\Cp\FormFields` is the legacy shim layer. Its `*FromConfig()` methods translate the legacy Twig - config-array surface (the old `_includes/forms/*` option names) onto a component's fluent API, preserving legacy - semantics; keys the components no longer support get `Deprecator` warnings via `deprecateConfig()`. The - `*FieldHtml()` methods wrap an input in the `Field` component via `fieldHtml()`. -- Migrated `resources/templates/_includes/forms/*.twig` templates are one-line delegates to the Twig `Cp` variable - (`craft.cp.button(_context)` → `FormFields::buttonFromConfig()`); inputs not yet ported still render their Twig - template via `FormFields::renderTemplate()`. - -When porting a form input to this pattern: add the component class to `src/Cp/Components/` (and register it), add a -`FormFields::*FromConfig()` mapping that keeps the legacy config keys working, and reduce the Twig template to a -delegate — don't drop legacy config support without a deprecation. - -When porting behavior out of the legacy jQuery bundle (`packages/craftcms-legacy/cp/src/js/*.js`) into modern TypeScript, follow the shared module pattern documented in `resources/js/modules/README.md` — a logic class (`.ts` on `@craftcms/garnish` `Base`), a `ControllerElement` custom element (`.ce.ts`), an instance-registry `support.ts` WeakMap, and an `index.ts` shim that registers the element and assigns the legacy `window.Craft.*` global. Note the source-vs-`dist` gotcha in that README: after editing `packages/craftcms-garnish/src` (or `@craftcms/cp`), rebuild the package's `dist` or `npm run typecheck` won't see the change. +The Control Panel contains both legacy Twig/jQuery surfaces and newer Inertia + Vue screens. Prefer `@craftcms/cp` components when building UI, and match whichever surface the surrounding feature already uses. ## Adapter Work @@ -135,12 +43,3 @@ When porting behavior out of the legacy jQuery bundle (`packages/craftcms-legacy - `declare(strict_types=1)` is required in PHP files. - Classes are non-final by default; use `readonly` when it fits. - You do not need to manually remove unused imports; Pint will fix them. - -## Pull Requests - -When creating a pull request, follow these steps: - -- Verify first that `composer ci` passes locally -- Prefix the PR title with the origin branch, for example [6.x] or [5.x], omit if the origin branch does not look like a version. -- Use a single `### Description` header with a to-the-point description of the PR and a `### Related issues` header only if there are any related issues being fixed or referenced. No other headers or content necessary. You must not add "Validated with.." statements -- If related issues you find are Linear issues and you are on a branch referencing a Linear issue (xxx-1234-slug), there is no need to add that issue identifier to the related issues. Find the GitHub related issue instead and reference that. diff --git a/CHANGELOG-WIP.md b/CHANGELOG-WIP.md index 42eb3a6df8d..6b672907bac 100644 --- a/CHANGELOG-WIP.md +++ b/CHANGELOG-WIP.md @@ -182,7 +182,7 @@ Craft's Mutex classes have been deprecated. [Laravel's atomic locking](https://l ##### Events -- Deprecated `craft\services\Dashboard::EVENT_REGISTER_WIDGET_TYPES`. `CraftCms\Cms\Dashboard\WidgetTypes::register()` should be used instead. +- Deprecated `craft\services\Dashboard::EVENT_REGISTER_WIDGET_TYPES`. `CraftCms\Cms\Dashboard\Events\WidgetTypesResolving` should be used instead. - Deprecated `craft\events\WidgetEvent` in favor of the following new events: - `craft\services\Dashboard::EVENT_BEFORE_SAVE_WIDGET` => `CraftCms\Cms\Dashboard\Events\WidgetSaving` - `craft\services\Dashboard::EVENT_AFTER_SAVE_WIDGET` => `CraftCms\Cms\Dashboard\Events\WidgetSaved` @@ -238,7 +238,7 @@ Craft's Mutex classes have been deprecated. [Laravel's atomic locking](https://l - Added `CraftCms\Cms\Auth\Events\SettingPassword`. - Added `CraftCms\Cms\User\Notifications\ResetPasswordNotification`. - Deprecated `craft\services\Auth`. `CraftCms\Cms\Auth\Auth` should be used instead. -- Deprecated `craft\web\User`. `auth()->user()` or `CraftCms\Cms\User\Elements\User` methods should be used instead. +- Deprecated `craft\web\User`. `auth('craft')->user()` or `CraftCms\Cms\User\Elements\User` methods should be used instead. - Deprecated `craft\events\AuthenticateUserEvent`. `CraftCms\Cms\Auth\Events\UserAuthenticating` should be used instead. - Deprecated `\craft\records\Authenticator`. `\CraftCms\Cms\Auth\Models\Authenticator` should be used instead. - Deprecated `\craft\records\RecoveryCodes`. `\CraftCms\Cms\Auth\Models\RecoveryCodes` should be used instead. @@ -247,7 +247,7 @@ Craft's Mutex classes have been deprecated. [Laravel's atomic locking](https://l - Deprecated `craft\behaviors\SessionBehavior::authorize`. `CraftCms\Cms\Auth\SessionAuth::authorize` should be used instead. - Deprecated `craft\behaviors\SessionBehavior::deauthorize`. `CraftCms\Cms\Auth\SessionAuth::deauthorize` should be used instead. - Deprecated `craft\behaviors\SessionBehavior::checkAuthorization`. `CraftCms\Cms\Auth\SessionAuth::checkAuthorization` should be used instead. -- Deprecated `craft\services\Users::isVerificationCodeValidForUser()`. `Password::broker()->tokenExists($user, $code)` should be used instead. +- Deprecated `craft\services\Users::isVerificationCodeValidForUser()`. `Password::broker('craft')->tokenExists($user, $code)` should be used instead. - Deprecated the `elevatedSessionDuration` general config setting. The `auth.password_timeout` config value should be used instead. To disable password confirmation (elevated sessions), you now set this value to `-1` instead of `0`. - Elevated sessions now work through [Laravel's password confirmation](https://laravel.com/docs/12.x/authentication#password-confirmation) system. - Removed `craft\controllers\AuthController`. The following controllers now implement this functionality: @@ -415,11 +415,6 @@ Craft 6 now uses [Laravel's authorization system](https://laravel.com/docs/12.x/ - Deprecated `craft\events\RegisterConditionRulesEvent`. `CraftCms\Cms\Condition\Events\ConditionRulesResolving` should be used instead. -### Control Panel - -- Removed the `Craft.Accordion` and `Craft.EnvVarGenerator` control panel JavaScript classes. ([#19323](https://github.com/craftcms/cms/pull/19323)) -- Deprecated the `Craft.LightSwitch`, `Craft.InfoIcon`, `Craft.ColorInput`, `Craft.PasswordInput`, `Craft.IconPicker`, `Craft.SlidePicker`, `Craft.SlideRuleInput`, and `Craft.Tooltip` control panel JavaScript classes, along with the `.infoicon` jQuery plugin. The corresponding `@craftcms/ui` web components should be used instead. - ### Drafts - Deprecated `craft\services\Drafts`. `CraftCms\Cms\Element\Drafts` should be used instead. @@ -606,7 +601,7 @@ Craft 6 introduces a new validation system that uses Laravel's Validator instead - Deprecated `craft\events\CreateFieldLayoutFormEvent`. `CraftCms\Cms\FieldLayout\Events\FieldLayoutFormCreating` should be used instead. - Deprecated `craft\events\DefineFieldLayoutCustomFieldsEvent`. `CraftCms\Cms\FieldLayout\Events\FieldLayoutCustomFieldsResolving` should be used instead. - Deprecated `craft\events\DefineFieldLayoutElementsEvent`. `CraftCms\Cms\FieldLayout\Events\FieldLayoutUIElementsResolving` should be used instead. -- Deprecated `craft\events\DefineFieldLayoutFieldsEvent`. `CraftCms\Cms\FieldLayout\NativeFields` should be used instead. +- Deprecated `craft\events\DefineFieldLayoutFieldsEvent`. `CraftCms\Cms\FieldLayout\Events\NativeFieldsResolving` should be used instead. - Deprecated `craft\events\DefineShowFieldLayoutComponentInFormEvent`. `CraftCms\Cms\FieldLayout\Events\FieldLayoutComponentShowInFormResolving` should be used instead. - Deprecated `craft\events\DefineFieldActionsEvent`. `CraftCms\Cms\FieldLayout\Events\FieldLayoutActionMenuItemsResolving` should be used instead. @@ -882,8 +877,8 @@ Moved the following controllers: - Deprecated `craft\search\SearchQueryTermGroup`. `CraftCms\Cms\Search\SearchQueryTermGroup` should be used instead. - Deprecated `craft\events\SearchEvent` in favor of the following new events: - `craft\services\Search::EVENT_BEFORE_SEARCH` => `CraftCms\Cms\Search\Events\SearchStarting` - - `craft\services\Search::EVENT_AFTER_SEARCH` => `CraftCms\Cms\Search\Events\SearchScoresResolving` and `CraftCms\Cms\Search\Events\SearchPerformed` - - `craft\services\Search::EVENT_BEFORE_SCORE_RESULTS` => `CraftCms\Cms\Search\Events\SearchResultsResolving` and `CraftCms\Cms\Search\Events\SearchScoresResolving` + - `craft\services\Search::EVENT_AFTER_SEARCH` => `CraftCms\Cms\Search\Events\SearchPerformed` + - `craft\services\Search::EVENT_BEFORE_SCORE_RESULTS` => `CraftCms\Cms\Search\Events\ScoringResults` - Deprecated `craft\events\IndexKeywordsEvent`. `CraftCms\Cms\Search\Events\KeywordsIndexing` should be used instead. ### Sections @@ -953,10 +948,10 @@ Moved the following controllers: - Updated Twig `{% paginate %}` queries to use Laravel paginators and generate query-string pagination URLs based on the `pageTrigger` general config setting. - Added `CraftCms\Cms\Twig\Twig` service for managing Twig environments, replacing the Twig management logic previously in `craft\web\View`. - Added `CraftCms\Cms\Twig\TemplateRenderer` for rendering templates, replacing the rendering logic previously in `craft\web\View`. -- Added `CraftCms\Cms\View\PageLifecycle` for managing the page rendering lifecycle (head/body placeholder replacement), replacing the page lifecycle logic previously in `craft\web\View`. +- Added `CraftCms\Cms\Twig\PageLifecycle` for managing the page rendering lifecycle (head/body placeholder replacement), replacing the page lifecycle logic previously in `craft\web\View`. - Added `CraftCms\Cms\Support\Facades\Twig` facade, resolving to `CraftCms\Cms\Twig\TemplateRenderer`. - Added `CraftCms\Cms\Twig\Environment`, moved from `craft\web\twig\Environment`. -- Added `CraftCms\Cms\View\TemplateResolver`. +- Added `CraftCms\Cms\Twig\TemplateResolver`. - Added `CraftCms\Cms\Twig\TemplateLoader`. - Added `CraftCms\Cms\Twig\Exceptions\TemplateLoaderException`. - Added helper functions in the `CraftCms\Cms` namespace: `template()`, `sandboxedTemplate()`, `pageTemplate()`, `renderString()`, `renderSandboxedString()`, `renderObjectTemplate()`, `renderSandboxedObjectTemplate()`. @@ -980,8 +975,8 @@ Moved the following controllers: - Deprecated `craft\web\View::getIsRenderingPageTemplate()`. `CraftCms\Cms\Twig\TemplateRenderer::isRenderingPageTemplate` should be used instead. - Deprecated `craft\web\twig\Environment`. `CraftCms\Cms\Twig\Environment` should be used instead. - Deprecated `craft\web\View::EVENT_AFTER_CREATE_TWIG`. `CraftCms\Cms\Twig\Events\TwigCreated` should be used instead. -- Deprecated `craft\web\View::doesTemplateExist()`. `CraftCms\Cms\View\TemplateResolver::doesTemplateExist()` should be used instead. -- Deprecated `craft\web\View::resolveTemplate()`. `CraftCms\Cms\View\TemplateResolver::resolveTemplate()` should be used instead. +- Deprecated `craft\web\View::doesTemplateExist()`. `CraftCms\Cms\Twig\TemplateResolver::doesTemplateExist()` should be used instead. +- Deprecated `craft\web\View::resolveTemplate()`. `CraftCms\Cms\Twig\TemplateResolver::resolveTemplate()` should be used instead. - Deprecated `craft\web\twig\TemplateLoader`. `CraftCms\Cms\Twig\TemplateLoader` should be used instead. - Deprecated `craft\web\twig\TemplateLoaderException`. `CraftCms\Cms\Twig\Exceptions\TemplateLoaderException` should be used instead. @@ -1016,14 +1011,14 @@ Moved the following controllers: - Added `CraftCms\Cms\User\Notifications\VerifyEmailNotification`. - `Users::purgeExpiredPendingUsers()` now joins the `password_reset_tokens` table to find expired pending users. - Removed `verificationCode` and `verificationCodeIssuedDate` columns on the `users` table in favor of the `password_reset_tokens` table. -- Deprecated `craft\services\Users::isVerificationCodeValidForUser()`. `Password::broker()->tokenExists($user, $code)` should be used instead. +- Deprecated `craft\services\Users::isVerificationCodeValidForUser()`. `Password::broker('craft')->tokenExists($user, $code)` should be used instead. - Removed `craft\controllers\UsersController` in favor of: - `CraftCms\Cms\Http\Controllers\Users\ActivateController`. - `CraftCms\Cms\Http\Controllers\Users\PasswordController`. - `CraftCms\Cms\Http\Controllers\Users\SaveUserController`. - Removed `\craft\controllers\UserSettingsController` in favor of: - - `CraftCms\Cms\Http\Controllers\Settings\Users\UserGroupsController` - - `CraftCms\Cms\Http\Controllers\Settings\Users\UserSettingsController` + - `CraftCms\Cms\Http\Controllers\Settings\UserGroupsController` + - `CraftCms\Cms\Http\Controllers\Settings\UserSettingsController` - Deprecated `UserGroupEvent` in favor of: - `CraftCms\Cms\User\Events\UserGroupSaving` - `CraftCms\Cms\User\Events\UserGroupSaved` @@ -1053,13 +1048,14 @@ Moved the following controllers: - Added `CraftCms\Cms\View\DeltaRegistry`. - Added `CraftCms\Cms\Support\Facades\DeltaRegistry`. - Added `CraftCms\Cms\View\TemplateMode` enum. -- Added `CraftCms\Cms\View\TemplateRoots`. +- Added `CraftCms\Cms\View\Events\CpTemplateRootsResolving`. +- Added `CraftCms\Cms\View\Events\SiteTemplateRootsResolving`. - Added `CraftCms\Cms\View\TemplateCaches`. - Added `CraftCms\Cms\View\CacheCollectors\DependencyCollector`. - Added `CraftCms\Cms\View\CacheCollectors\ResourceCollector`. - Added `CraftCms\Cms\View\Contracts\CacheCollectorInterface`. - Added `CraftCms\Cms\View\Data\TemplateCacheContext`. -- Added `CraftCms\Cms\View\TemplateCacheCollectors`. +- Added `CraftCms\Cms\View\Events\TemplateCacheCollectorsResolving`. - Deprecated `craft\services\TemplateCaches`. `CraftCms\Cms\View\TemplateCaches` should be used instead. - Deprecated `craft\web\View::registerJs()`. `CraftCms\Cms\View\HtmlStack::js()` should be used instead. - Deprecated `craft\web\View::registerJsWithVars()`. `CraftCms\Cms\View\HtmlStack::jsWithVars()` should be used instead. @@ -1102,8 +1098,8 @@ Moved the following controllers: - Deprecated `craft\web\View::getTemplatesPath()`. `CraftCms\Cms\View\TemplateMode::templatesPath()` should be used instead. - Deprecated `craft\web\View::getCpTemplateRoots()`. `CraftCms\Cms\View\TemplateMode::templateRoots()` should be used instead. - Deprecated `craft\web\View::getSiteTemplateRoots()`. `CraftCms\Cms\View\TemplateMode::templateRoots()` should be used instead. -- Deprecated `craft\web\View::EVENT_REGISTER_CP_TEMPLATE_ROOTS`. `CraftCms\Cms\View\TemplateRoots::register()` should be used instead. -- Deprecated `craft\web\View::EVENT_REGISTER_SITE_TEMPLATE_ROOTS`. `CraftCms\Cms\View\TemplateRoots::register()` should be used instead. +- Deprecated `craft\web\View::EVENT_REGISTER_CP_TEMPLATE_ROOTS`. `CraftCms\Cms\View\Events\CpTemplateRootsResolving` should be used instead. +- Deprecated `craft\web\View::EVENT_REGISTER_SITE_TEMPLATE_ROOTS`. `CraftCms\Cms\View\Events\SiteTemplateRootsResolving` should be used instead. - Deprecated `craft\web\View::registerDeltaName()`. `CraftCms\Cms\View\DeltaRegistry::registerName()` should be used instead. - Deprecated `craft\web\View::getDeltaNames()`. `CraftCms\Cms\View\DeltaRegistry::getNames()` should be used instead. - Deprecated `craft\web\View::getModifiedDeltaNames()`. `CraftCms\Cms\View\DeltaRegistry::getModifiedNames()` should be used instead. diff --git a/CHANGELOG.md b/CHANGELOG.md index cd781fa253e..db1858fb5a6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,327 +2,24 @@ ## Unreleased -- Replaced `pixelandtonic/imagine` with `intervention/image` for image manipulation. -- Added support for the libvips image driver via the optional `intervention/image-driver-vips` package. -- Added BMP, HEIC, ICO, JPEG 2000, JPEG XL, and TIFF image transform formats when supported by the active image driver. -- Added support for configuring field layout field instruction positions. -- Added fluent APIs for creating and modifying `CraftCms\Cms\FieldLayout\FieldLayout`, `CraftCms\Cms\FieldLayout\FieldLayoutTab`, and field layout elements, including dependency-injected closure values. -- Changed `craft:resave:all` to discover registered `craft:resave:*` Artisan commands directly, rather than relying on a resolving event. ([#19270](https://github.com/craftcms/cms/pull/19270)) -- Changed the My Account → Addresses page to a full Inertia/Vue page, rendering nested-element cards from data instead of server-rendered HTML. ([#19324](https://github.com/craftcms/cms/pull/19324)) -- Changed `CraftCms\Cms\Cp\FormFields::textFromConfig()` to accept an optional `CraftCms\Cms\Cp\Components\Input` instance as a second argument, so callers can build on an existing component instead of always creating a plain `Input`. ([#19323](https://github.com/craftcms/cms/pull/19323)) -- Changed `CraftCms\Cms\Search\Events\SearchPerformed` to be a readonly, immutable event; its `$results` and `$scores` properties can no longer be overridden by listeners. `CraftCms\Cms\Search\Events\SearchScoresResolving` should be used to override scores instead. ([#19308](https://github.com/craftcms/cms/pull/19308)) -- Added `CraftCms\Cms\Asset\AssetFileKinds`. ([#19270](https://github.com/craftcms/cms/pull/19270)) -- Added `CraftCms\Cms\Cp\Components\Button::action()`, for declarative click actions. ([#19324](https://github.com/craftcms/cms/pull/19324)) -- Added `CraftCms\Cms\Cp\Components\Button::inherit()`. ([#19306](https://github.com/craftcms/cms/pull/19306)) -- Added `CraftCms\Cms\Cp\Components\InputColor`. ([#19323](https://github.com/craftcms/cms/pull/19323)) -- Added `CraftCms\Cms\Cp\Components\InputPassword`. ([#19323](https://github.com/craftcms/cms/pull/19323)) -- Added `CraftCms\Cms\Cp\Data\NavItem::group()`. ([#19350](https://github.com/craftcms/cms/pull/19350)) -- Added `CraftCms\Cms\Cp\Enums\ButtonVariant`. ([#19306](https://github.com/craftcms/cms/pull/19306)) -- Added `CraftCms\Cms\Cp\FormFields::colorFromConfig()`. ([#19323](https://github.com/craftcms/cms/pull/19323)) -- Added `CraftCms\Cms\Cp\FormFields::passwordFromConfig()`, `passwordHtml()`, and `passwordFieldHtml()`. ([#19323](https://github.com/craftcms/cms/pull/19323)) -- Added `CraftCms\Cms\Cp\Html\ElementHtml::elementCardLabelHtml()`, `elementCardActionsHtml()`, `elementCardThumbHtml()`, and `elementCardThumbAlignment()`. ([#19324](https://github.com/craftcms/cms/pull/19324)) -- Added `CraftCms\Cms\Cp\Settings::registerSetting()` and `registerReadOnlySetting()`. ([#19270](https://github.com/craftcms/cms/pull/19270)) -- Added `CraftCms\Cms\Dashboard\WidgetTypes`. ([#19270](https://github.com/craftcms/cms/pull/19270)) -- Added `CraftCms\Cms\Database\Commands\MigrateCommand::registerMigrator()`. ([#19270](https://github.com/craftcms/cms/pull/19270)) -- Added `CraftCms\Cms\Element\ElementTypes`. ([#19270](https://github.com/craftcms/cms/pull/19270)) -- Added `CraftCms\Cms\Element\NestedElementManager::getCardsData()` and `getIndexData()`. ([#19324](https://github.com/craftcms/cms/pull/19324)) -- Added `CraftCms\Cms\Field\FieldTypes`. ([#19270](https://github.com/craftcms/cms/pull/19270)) -- Added `CraftCms\Cms\Field\LinkTypes`. ([#19270](https://github.com/craftcms/cms/pull/19270)) -- Added `CraftCms\Cms\Field\NestedEntryFieldTypes`. ([#19270](https://github.com/craftcms/cms/pull/19270)) -- Added `CraftCms\Cms\FieldLayout\NativeFields`. ([#19270](https://github.com/craftcms/cms/pull/19270)) -- Added `CraftCms\Cms\Filesystem\FilesystemTypes`. ([#19270](https://github.com/craftcms/cms/pull/19270)) -- Added `CraftCms\Cms\Gql\GqlArguments`. ([#19270](https://github.com/craftcms/cms/pull/19270)) -- Added `CraftCms\Cms\Gql\GqlDirectives`. ([#19270](https://github.com/craftcms/cms/pull/19270)) -- Added `CraftCms\Cms\Gql\GqlMutations`. ([#19270](https://github.com/craftcms/cms/pull/19270)) -- Added `CraftCms\Cms\Gql\GqlQueries`. ([#19270](https://github.com/craftcms/cms/pull/19270)) -- Added `CraftCms\Cms\Gql\GqlTypes`. ([#19270](https://github.com/craftcms/cms/pull/19270)) -- Added `CraftCms\Cms\Image\ImageTransformers`. ([#19270](https://github.com/craftcms/cms/pull/19270)) -- Added `CraftCms\Cms\Image\Raster::getInterventionImage()`. -- Added `CraftCms\Cms\Plugin\Plugin::$filesystemTypes`. ([#19307](https://github.com/craftcms/cms/pull/19307)) -- Added `CraftCms\Cms\Plugin\Plugin::$gqlDirectives`. ([#19307](https://github.com/craftcms/cms/pull/19307)) -- Added `CraftCms\Cms\Plugin\Plugin::$gqlMutations`. ([#19307](https://github.com/craftcms/cms/pull/19307)) -- Added `CraftCms\Cms\Plugin\Plugin::$gqlQueries`. ([#19307](https://github.com/craftcms/cms/pull/19307)) -- Added `CraftCms\Cms\Plugin\Plugin::$gqlTypes`. ([#19307](https://github.com/craftcms/cms/pull/19307)) -- Added `CraftCms\Cms\Plugin\Plugin::$linkTypes`. ([#19307](https://github.com/craftcms/cms/pull/19307)) -- Added `CraftCms\Cms\Plugin\Plugin::$siteTemplateRoots`. ([#19307](https://github.com/craftcms/cms/pull/19307)) -- Added `CraftCms\Cms\Plugin\Plugin::getCacheOptions()`. ([#19307](https://github.com/craftcms/cms/pull/19307)) -- Added `CraftCms\Cms\Plugin\Plugin::getCacheTags()`. ([#19307](https://github.com/craftcms/cms/pull/19307)) -- Added `CraftCms\Cms\Plugin\Plugin::getNativeFields()`. ([#19307](https://github.com/craftcms/cms/pull/19307)) -- Added `CraftCms\Cms\Plugin\Plugin::getSystemMessages()`. ([#19307](https://github.com/craftcms/cms/pull/19307)) -- Added `CraftCms\Cms\Search\Events\SearchResultsResolving`. ([#19308](https://github.com/craftcms/cms/pull/19308)) -- Added `CraftCms\Cms\Search\Events\SearchScoresResolving`. ([#19308](https://github.com/craftcms/cms/pull/19308)) -- Added `CraftCms\Cms\Support\Facades\AuthMethods`. ([#19270](https://github.com/craftcms/cms/pull/19270)) -- Added `CraftCms\Cms\SystemMessage\SystemMessages::register()`. ([#19270](https://github.com/craftcms/cms/pull/19270)) -- Added `CraftCms\Cms\Twig\Variables\Cp::color()` and `password()`. ([#19323](https://github.com/craftcms/cms/pull/19323)) -- Added `CraftCms\Cms\User\UserPermissions::registerPermissionGroup()`. ([#19270](https://github.com/craftcms/cms/pull/19270)) -- Added `CraftCms\Cms\Utility\Utilities\ClearCaches::add()` and `addTag()`. ([#19270](https://github.com/craftcms/cms/pull/19270)) -- Added `CraftCms\Cms\Utility\UtilityTypes`. ([#19270](https://github.com/craftcms/cms/pull/19270)) -- Added `CraftCms\Cms\View\TemplateCacheCollectors`. ([#19270](https://github.com/craftcms/cms/pull/19270)) -- Added `CraftCms\Cms\View\TemplateRoots`. ([#19270](https://github.com/craftcms/cms/pull/19270)) -- Moved `CraftCms\Cms\Cp\Concerns\EvaluatesClosures` to `CraftCms\Cms\Support\Concerns\EvaluatesClosures`. -- Changed `CraftCms\Cms\FieldLayout\LayoutElements\BaseField::label()` to accept an optional label and return the field layout element when one is passed. Overrides must accept the new optional argument. -- Changed `CraftCms\Cms\Image\Raster::getTextBox()` to return a `width` and `height` array. -- Renamed the protected `CraftCms\Cms\FieldLayout\LayoutElements\BaseField::instructions()`, `tip()`, and `warning()` methods to `instructionsText()`, `tipText()`, and `warningText()`. -- Removed `CraftCms\Cms\Asset\Events\AssetFileKindsResolving`. `CraftCms\Cms\Asset\AssetFileKinds::register()` should be used instead. ([#19270](https://github.com/craftcms/cms/pull/19270)) -- Removed `CraftCms\Cms\Auth\Events\AuthMethodsResolving`. `CraftCms\Cms\Auth\AuthMethods::register()` should be used instead. ([#19270](https://github.com/craftcms/cms/pull/19270)) -- Removed `CraftCms\Cms\Cp\Events\RegisterCpSettings` and `CraftCms\Cms\Cp\Events\RegisterReadonlyCpSettings`. `CraftCms\Cms\Cp\Settings::registerSetting()` and `registerReadOnlySetting()` should be used instead. ([#19270](https://github.com/craftcms/cms/pull/19270)) -- Removed `CraftCms\Cms\Dashboard\Events\WidgetTypesResolving`. `CraftCms\Cms\Dashboard\WidgetTypes::register()` should be used instead. ([#19270](https://github.com/craftcms/cms/pull/19270)) -- Removed `CraftCms\Cms\Database\Events\MigratorsResolving`. `CraftCms\Cms\Database\Commands\MigrateCommand::registerMigrator()` should be used instead. ([#19270](https://github.com/craftcms/cms/pull/19270)) -- Removed `CraftCms\Cms\Element\Events\ElementResaveCommandsResolving`. A normal Artisan command in the `craft:resave` namespace should be registered instead. ([#19270](https://github.com/craftcms/cms/pull/19270)) -- Removed `CraftCms\Cms\Element\Events\ElementTypesResolving`. `CraftCms\Cms\Element\ElementTypes::register()` should be used instead. ([#19270](https://github.com/craftcms/cms/pull/19270)) -- Removed `CraftCms\Cms\Field\Events\FieldTypesResolving`. `CraftCms\Cms\Field\FieldTypes::register()` should be used instead. ([#19270](https://github.com/craftcms/cms/pull/19270)) -- Removed `CraftCms\Cms\Field\Events\LinkTypesResolving`. `CraftCms\Cms\Field\LinkTypes::register()` should be used instead. ([#19270](https://github.com/craftcms/cms/pull/19270)) -- Removed `CraftCms\Cms\Field\Events\NestedEntryFieldTypesResolving`. `CraftCms\Cms\Field\NestedEntryFieldTypes::register()` should be used instead. ([#19270](https://github.com/craftcms/cms/pull/19270)) -- Removed `CraftCms\Cms\FieldLayout\Events\NativeFieldsResolving`. `CraftCms\Cms\FieldLayout\NativeFields::register()` should be used instead. ([#19270](https://github.com/craftcms/cms/pull/19270)) -- Removed `CraftCms\Cms\Filesystem\Events\FilesystemTypesResolving`. `CraftCms\Cms\Filesystem\FilesystemTypes::register()` should be used instead. ([#19270](https://github.com/craftcms/cms/pull/19270)) -- Removed `CraftCms\Cms\Gql\Events\GqlArgumentHandlersResolving`. `CraftCms\Cms\Gql\GqlArguments::register()` should be used instead. ([#19270](https://github.com/craftcms/cms/pull/19270)) -- Removed `CraftCms\Cms\Gql\Events\GqlDirectivesResolving`. `CraftCms\Cms\Gql\GqlDirectives::register()` should be used instead. ([#19270](https://github.com/craftcms/cms/pull/19270)) -- Removed `CraftCms\Cms\Gql\Events\GqlMutationsResolving`. `CraftCms\Cms\Gql\GqlMutations::register()` should be used instead. ([#19270](https://github.com/craftcms/cms/pull/19270)) -- Removed `CraftCms\Cms\Gql\Events\GqlQueriesResolving`. `CraftCms\Cms\Gql\GqlQueries::register()` should be used instead. ([#19270](https://github.com/craftcms/cms/pull/19270)) -- Removed `CraftCms\Cms\Gql\Events\GqlTypesResolving`. `CraftCms\Cms\Gql\GqlTypes::register()` should be used instead. ([#19270](https://github.com/craftcms/cms/pull/19270)) -- Removed `CraftCms\Cms\Image\Events\ImageTransformersResolving`. `CraftCms\Cms\Image\ImageTransformers::register()` should be used instead. ([#19270](https://github.com/craftcms/cms/pull/19270)) -- Removed `CraftCms\Cms\Image\Images::MINIMUM_IMAGICK_VERSION` and `craft\services\Images::MINIMUM_IMAGICK_VERSION`. -- Removed `CraftCms\Cms\Image\Raster::getImagineImage()`. -- Removed `CraftCms\Cms\Search\Events\ScoringResults` in favor of the following new events: ([#19308](https://github.com/craftcms/cms/pull/19308)) - - `CraftCms\Cms\Search\Events\SearchResultsResolving` - - `CraftCms\Cms\Search\Events\SearchScoresResolving` -- Removed `CraftCms\Cms\SystemMessage\Events\SystemMessagesResolving`. `CraftCms\Cms\SystemMessage\SystemMessages::register()` should be used instead. ([#19270](https://github.com/craftcms/cms/pull/19270)) -- Removed `CraftCms\Cms\User\Events\UserPermissionsResolving`. `CraftCms\Cms\User\UserPermissions::registerPermissionGroup()` should be used instead. ([#19270](https://github.com/craftcms/cms/pull/19270)) -- Removed `CraftCms\Cms\Utility\Events\ClearCachesOptionsResolving` and `CraftCms\Cms\Utility\Events\ClearCachesTagOptionsResolving`. `CraftCms\Cms\Utility\Utilities\ClearCaches::add()` and `addTag()` should be used instead. ([#19270](https://github.com/craftcms/cms/pull/19270)) -- Removed `CraftCms\Cms\Utility\Events\UtilitiesResolving`. `CraftCms\Cms\Utility\UtilityTypes::register()` should be used instead. ([#19270](https://github.com/craftcms/cms/pull/19270)) -- Removed `CraftCms\Cms\View\Events\CpTemplateRootsResolving` and `CraftCms\Cms\View\Events\SiteTemplateRootsResolving`. `CraftCms\Cms\View\TemplateRoots::register()` should be used instead. ([#19270](https://github.com/craftcms/cms/pull/19270)) -- Removed `CraftCms\Cms\View\Events\TemplateCacheCollectorsResolving`. `CraftCms\Cms\View\TemplateCacheCollectors::register()` should be used instead. ([#19270](https://github.com/craftcms/cms/pull/19270)) -- Added the `@craftcms/ui/factory` module, a jQuery-free layer of typed element factories that mirror the `src/Cp/Components` PHP builders. ([#19323](https://github.com/craftcms/cms/pull/19323)) -- Added `createTextInput()` and `createCopyTextPrompt()` to the `@craftcms/ui/factory` module. ([#19333](https://github.com/craftcms/cms/pull/19333)) -- Added `turnOn()`, `turnOff()`, and `turnIndeterminate()` methods to the `` web component. ([#19323](https://github.com/craftcms/cms/pull/19323)) -- Added a `group` property to the `` web component, for rendering a subnav as a non-collapsible semantic grouping. ([#19350](https://github.com/craftcms/cms/pull/19350)) -- Added `Garnish.CustomSelect` and `Garnish.MenuBtn` to `@craftcms/garnish`, jQuery-free TypeScript ports of the legacy floating listbox menu and menu-button classes. ([#19352](https://github.com/craftcms/cms/pull/19352)) -- Moved the `Craft.ComponentSelectInput` control panel JavaScript class out of the core bundle into a `yii2-adapter` compatibility asset, since `` is now used everywhere in core; the `componentSelect.twig` `jsClass` escape hatch still works for plugin subclasses. ([#19333](https://github.com/craftcms/cms/pull/19333)) -- Moved the `Craft.AssetMover`, `Craft.AssetSelectorModal`, `Craft.BaseElementSelectInput`, `Craft.BaseElementSelectorModal`, `Craft.BaseUploader`, `Craft.Chart`, `Craft.CpModal`, `Craft.CustomizeSourcesModal`, `Craft.DataTableSorter`, `Craft.ElementActionTrigger`, `Craft.ElementDeletionManager`, `Craft.ElementTableSorter`, `Craft.EntrySelectInput`, `Craft.Grid`, `Craft.PreviewFileModal`, `Craft.Tabs`, `Craft.TagSelectInput`, `Craft.Uploader`, and `Craft.VolumeFolderSelectorModal` control panel JavaScript classes from the legacy jQuery bundle to TypeScript modules. ([#19352](https://github.com/craftcms/cms/pull/19352)) -- Changed `` to render as a `` instead of an `` when it has no `href`, dropping `aria-current` in that case. ([#19350](https://github.com/craftcms/cms/pull/19350)) -- Changed element index table rows and cards so clicking anywhere on them (other than an interactive control) selects them, extending the selection range on shift-click just like clicking a row’s checkbox. ([#19351](https://github.com/craftcms/cms/pull/19351)) -- Deprecated the `Craft.LightSwitch`, `Craft.InfoIcon`, `Craft.ColorInput`, `Craft.PasswordInput`, `Craft.IconPicker`, `Craft.SlidePicker`, `Craft.SlideRuleInput`, and `Craft.Tooltip` control panel JavaScript classes, along with the `.infoicon` jQuery plugin. The corresponding `@craftcms/ui` web components should be used instead. ([#19323](https://github.com/craftcms/cms/pull/19323)) -- Removed the `Craft.Accordion` and `Craft.EnvVarGenerator` control panel JavaScript classes. ([#19323](https://github.com/craftcms/cms/pull/19323)) -- Removed the `Craft.DeleteUserModal` control panel JavaScript class. It was deprecated in 5.10.0 and unused. ([#19352](https://github.com/craftcms/cms/pull/19352)) -- Fixed a bug where Blade templates rendered through Craft used path-based view names, preventing named Laravel view composers from running. ([#19177](https://github.com/craftcms/cms/issues/19177)) -- Fixed a bug where the `accent` semantic color used by colorable elements (e.g. `craft-callout`, `[data-color]`) rendered red instead of blue, due to a drifted color mapping in `@craftcms/ui`. ([#19306](https://github.com/craftcms/cms/pull/19306)) -- Fixed a styling issue. ([#19296](https://github.com/craftcms/cms/pull/19296)) -- Fixed a bug where Yii adapter plugins could cause legacy Control Panel assets to be omitted. ([#19302](https://github.com/craftcms/cms/pull/19302)) -- Fixed a bug where assets’ Alternative Text values could not be cleared. ([#19310](https://github.com/craftcms/cms/issues/19310)) -- Fixed a bug where element deletion confirmation dialogs could display unresolved pluralization syntax. ([#19311](https://github.com/craftcms/cms/issues/19311)) -- Fixed a bug where replacing an asset would fail silently. ([#19312](https://github.com/craftcms/cms/issues/19312)) -- Fixed JavaScript errors that could occur throughout the control panel. ([#19313](https://github.com/craftcms/cms/issues/19313)) -- Fixed a bug where `forms.checkboxField()` and `CraftCms\Cms\Cp\FormFields::checkboxFieldHtml()` rendered an empty field. ([#19338](https://github.com/craftcms/cms/pull/19338)) -- Fixed a bug where Utility pages weren’t rendering, and were logging `$ is not defined` and `window.Cp.config is not a function` errors to the console. ([#19340](https://github.com/craftcms/cms/pull/19340)) -- Fixed a bug where `actionClient` requests for bare action paths could corrupt the `?site=` query string on multi-site installs. ([#19342](https://github.com/craftcms/cms/pull/19342)) -- `Craft.cp.announce()` now accepts live regions that are plain elements as well as jQuery collections. ([#19340](https://github.com/craftcms/cms/pull/19340)) - -## 6.0.0-alpha.14 - 2026-07-22 - -> [!IMPORTANT] -> This update contains breaking changes for plugins. See [#19263](https://github.com/craftcms/cms/pull/19263) for details. - -- Plugins should no longer define `extra.laravel.providers` in `composer.json`. ([#19263](https://github.com/craftcms/cms/pull/19263)) -- Removed automatic plugin trait lifecycle hooks. ([#19263](https://github.com/craftcms/cms/pull/19263)) -- Added `CraftCms\Cms\Cp\Components\Button`. ([#19248](https://github.com/craftcms/cms/pull/19248)) -- Added `CraftCms\Cms\Cp\Components\ButtonGroup`. ([#19248](https://github.com/craftcms/cms/pull/19248)) -- Added `CraftCms\Cms\Cp\Components\Callout::hideIcon()`. ([#19297](https://github.com/craftcms/cms/pull/19297)) -- Added `CraftCms\Cms\Cp\Components\Callout`. ([#19248](https://github.com/craftcms/cms/pull/19248)) -- Added `CraftCms\Cms\Cp\Components\Checkbox`. ([#19248](https://github.com/craftcms/cms/pull/19248)) -- Added `CraftCms\Cms\Cp\Components\CheckboxGroup`. ([#19248](https://github.com/craftcms/cms/pull/19248)) -- Added `CraftCms\Cms\Cp\Components\CheckboxSelect`. ([#19248](https://github.com/craftcms/cms/pull/19248)) -- Added `CraftCms\Cms\Cp\Components\ChoiceGroup`. ([#19248](https://github.com/craftcms/cms/pull/19248)) -- Added `CraftCms\Cms\Cp\Components\ComponentRegistry`. ([#19248](https://github.com/craftcms/cms/pull/19248)) -- Added `CraftCms\Cms\Cp\Components\Field`. ([#19248](https://github.com/craftcms/cms/pull/19248)) -- Added `CraftCms\Cms\Cp\Components\FieldGroup`. ([#19248](https://github.com/craftcms/cms/pull/19248)) -- Added `CraftCms\Cms\Cp\Components\Icon`. ([#19297](https://github.com/craftcms/cms/pull/19297)) -- Added `CraftCms\Cms\Cp\Components\Input`. ([#19297](https://github.com/craftcms/cms/pull/19297)) -- Added `CraftCms\Cms\Cp\Components\Lightswitch`. ([#19248](https://github.com/craftcms/cms/pull/19248)) -- Added `CraftCms\Cms\Cp\Components\Radio`. ([#19248](https://github.com/craftcms/cms/pull/19248)) -- Added `CraftCms\Cms\Cp\Components\RadioGroup`. ([#19248](https://github.com/craftcms/cms/pull/19248)) -- Added `CraftCms\Cms\Cp\Components\Textarea`. ([#19297](https://github.com/craftcms/cms/pull/19297)) -- Added `CraftCms\Cms\Cp\Components\ViewComponent`. ([#19248](https://github.com/craftcms/cms/pull/19248)) -- Added `CraftCms\Cms\Cp\Concerns\EvaluatesClosures`. ([#19248](https://github.com/craftcms/cms/pull/19248)) -- Added `CraftCms\Cms\Cp\Concerns\HasAppearance`. ([#19248](https://github.com/craftcms/cms/pull/19248)) -- Added `CraftCms\Cms\Cp\Concerns\HasDisabled`. ([#19248](https://github.com/craftcms/cms/pull/19248)) -- Added `CraftCms\Cms\Cp\Concerns\HasId`. ([#19248](https://github.com/craftcms/cms/pull/19248)) -- Added `CraftCms\Cms\Cp\Concerns\HasSize`. ([#19248](https://github.com/craftcms/cms/pull/19248)) -- Added `CraftCms\Cms\Cp\Concerns\HasVariant`. ([#19248](https://github.com/craftcms/cms/pull/19248)) -- Added `CraftCms\Cms\Cp\Enums\Appearance`. ([#19248](https://github.com/craftcms/cms/pull/19248)) -- Added `CraftCms\Cms\Cp\Enums\Size`. ([#19248](https://github.com/craftcms/cms/pull/19248)) -- Added `CraftCms\Cms\Cp\Enums\Variant`. ([#19248](https://github.com/craftcms/cms/pull/19248)) -- Added `CraftCms\Cms\Cp\FormFields::buttonFromConfig()`. ([#19248](https://github.com/craftcms/cms/pull/19248)) -- Added `CraftCms\Cms\Cp\FormFields::buttonGroupFromConfig()`. ([#19248](https://github.com/craftcms/cms/pull/19248)) -- Added `CraftCms\Cms\Cp\FormFields::checkboxFromConfig()`. ([#19248](https://github.com/craftcms/cms/pull/19248)) -- Added `CraftCms\Cms\Cp\FormFields::checkboxGroupFromConfig()`. ([#19248](https://github.com/craftcms/cms/pull/19248)) -- Added `CraftCms\Cms\Cp\FormFields::checkboxSelectFromConfig()`. ([#19248](https://github.com/craftcms/cms/pull/19248)) -- Added `CraftCms\Cms\Cp\FormFields::lightswitchFromConfig()`. ([#19248](https://github.com/craftcms/cms/pull/19248)) -- Added `CraftCms\Cms\Cp\FormFields::radioFromConfig()`. ([#19248](https://github.com/craftcms/cms/pull/19248)) -- Added `CraftCms\Cms\Cp\FormFields::radioGroupFieldHtml()`. ([#19248](https://github.com/craftcms/cms/pull/19248)) -- Added `CraftCms\Cms\Cp\FormFields::radioGroupFromConfig()`. ([#19248](https://github.com/craftcms/cms/pull/19248)) -- Added `CraftCms\Cms\Cp\FormFields::textareaFromConfig()`. ([#19297](https://github.com/craftcms/cms/pull/19297)) -- Added `CraftCms\Cms\Cp\FormFields::textFromConfig()`. ([#19297](https://github.com/craftcms/cms/pull/19297)) -- Added `CraftCms\Cms\Support\Facades\Template`. ([#19290](https://github.com/craftcms/cms/pull/19290)) -- Added `CraftCms\Cms\Twig\Contracts\TwigRendererInterface`. ([#19290](https://github.com/craftcms/cms/pull/19290)) -- Added `CraftCms\Cms\Twig\Variables\Cp::button()`. ([#19248](https://github.com/craftcms/cms/pull/19248)) -- Added `CraftCms\Cms\Twig\Variables\Cp::buttonGroup()`. ([#19248](https://github.com/craftcms/cms/pull/19248)) -- Added `CraftCms\Cms\Twig\Variables\Cp::checkbox()`. ([#19248](https://github.com/craftcms/cms/pull/19248)) -- Added `CraftCms\Cms\Twig\Variables\Cp::checkboxGroup()`. ([#19248](https://github.com/craftcms/cms/pull/19248)) -- Added `CraftCms\Cms\Twig\Variables\Cp::checkboxSelect()`. ([#19248](https://github.com/craftcms/cms/pull/19248)) -- Added `CraftCms\Cms\Twig\Variables\Cp::lightswitch()`. ([#19248](https://github.com/craftcms/cms/pull/19248)) -- Added `CraftCms\Cms\Twig\Variables\Cp::radio()`. ([#19248](https://github.com/craftcms/cms/pull/19248)) -- Added `CraftCms\Cms\Twig\Variables\Cp::radioGroup()`. ([#19248](https://github.com/craftcms/cms/pull/19248)) -- Added `CraftCms\Cms\Twig\Variables\Cp::text()`. ([#19297](https://github.com/craftcms/cms/pull/19297)) -- Added `CraftCms\Cms\Twig\Variables\Cp::textarea()`. ([#19297](https://github.com/craftcms/cms/pull/19297)) -- Added `CraftCms\Cms\ui()`. ([#19248](https://github.com/craftcms/cms/pull/19248)) -- Added `CraftCms\Cms\View\TemplateManager`. ([#19290](https://github.com/craftcms/cms/pull/19290)) -- `template()` and `pageTemplate()` now accept an optional template renderer name. ([#19290](https://github.com/craftcms/cms/pull/19290)) -- `TemplateRendered` and `PageTemplateRendered` events now expose the final renderer name via `$rendererName`; the corresponding before events no longer expose renderer identity. ([#19290](https://github.com/craftcms/cms/pull/19290)) -- Replaced `CraftCms\Cms\Support\HtmlSanitizer\HtmlSanitizers` with `CraftCms\Cms\Support\HtmlSanitizer\HtmlSanitizerManager`. HTML sanitizers should now be registered via `CraftCms\Cms\Support\Facades\HtmlSanitizers::extend()` rather than `CraftCms\Cms\Support\HtmlSanitizer\HtmlSanitizers::register()`. ([#19292](https://github.com/craftcms/cms/pull/19292)) -- Removed `CraftCms\Cms\Plugin\Events\PluginUnregistered`. ([#19263](https://github.com/craftcms/cms/pull/19263)) -- Removed `CraftCms\Cms\Plugin\Plugin::bootPlugin()`. `boot()` should be used instead. ([#19263](https://github.com/craftcms/cms/pull/19263)) -- Removed `CraftCms\Cms\Plugin\Plugin::registerPlugin()`. `register()` should be used instead. ([#19263](https://github.com/craftcms/cms/pull/19263)) -- Fixed a bug where the legacy `yii\web\JqueryAsset` wasn’t resolving properly. ([#19264](https://github.com/craftcms/cms/pull/19264)) -- Fixed a bug where bulk entry moves could assign entries to sections that didn’t support their entry types. ([#19267](https://github.com/craftcms/cms/pull/19267)) -- Fixed a bug where queued resaves ignored offset and limit criteria or accepted non-positive batch sizes. ([#19271](https://github.com/craftcms/cms/pull/19271)) -- Fixed a bug where failed password and passkey login attempts incremented invalid-login counters twice. ([#19283](https://github.com/craftcms/cms/pull/19283)) -- Fixed bugs that could prevent authored content from being deleted or reassigned safely when deleting users. ([#19273](https://github.com/craftcms/cms/pull/19273)) -- Fixed an issue where disabled and archived user accounts could still authenticate. ([#19265](https://github.com/craftcms/cms/pull/19265)) -- Fixed a bug where one-time two-factor authentication credentials could be accepted by concurrent login attempts. ([#19282](https://github.com/craftcms/cms/pull/19282)) -- Fixed issues with `craft:users:set-password` password validation, exit statuses, and session invalidation. ([#19272](https://github.com/craftcms/cms/pull/19272)) -- Fixed a bug where selected GraphQL mutations could be mistaken for cacheable queries. ([#19284](https://github.com/craftcms/cms/pull/19284)) -- Fixed a [high-severity](https://github.com/craftcms/cms/security/policy#severity--remediation) authorization bypass vulnerability. -- Fixed a bug where two-factor authentication could lose login state or verify the wrong user during impersonation. ([#19274](https://github.com/craftcms/cms/pull/19274)) -- Fixed a bug where new Matrix blocks weren’t getting created. ([#19161](https://github.com/craftcms/cms/issues/19161)) - -## 6.0.0-alpha.13 - 2026-07-16 - -- Updated logout routes to require CSRF-protected POST requests. ([#19252](https://github.com/craftcms/cms/pull/19252/changes/ff6f20717a48e7ede5fbbe47487e7bb8ef71da78)) -- Updated Control Panel configuration serialization to use `Illuminate\Support\Js::from()`. ([#19252](https://github.com/craftcms/cms/pull/19252/changes/f844ae1cc3b02659ff68eb320ff7d2190a2a01da)) -- Updated the project testing guidelines to emphasize behavior-focused tests. ([#19252](https://github.com/craftcms/cms/pull/19252/changes/63b452d4b82d066566ad653ea39f6c1ad949eaa3)) -- Updated queue connection retry windows to exceed Craft’s maximum job timeout. ([#19252](https://github.com/craftcms/cms/pull/19252/changes/21bff956e964679a3f9951545bdf059473e0e5e8)) -- Updated core queue jobs to resolve their dependencies through Laravel’s service container. ([#19252](https://github.com/craftcms/cms/pull/19252/changes/dced32fc03120f27bc82ca61a9d960b95786ee03)) -- Updated automatic garbage collection to run as a unique queue job. ([#19252](https://github.com/craftcms/cms/pull/19252/changes/a35f815f3d9096311fc891b33c31427af865d902)) -- Updated two-factor authentication recovery codes to be encrypted at rest. ([#19252](https://github.com/craftcms/cms/pull/19252/changes/fb560d68a1d4f3a4e02b360c5bcacde27780fa05)) -- Improved field reference cleanup performance. ([#19252](https://github.com/craftcms/cms/pull/19252/changes/303054c48d45f33d43c6781664729fd01a6130f3)) -- Improved numeric element reference resolution performance. ([#19252](https://github.com/craftcms/cms/pull/19252/changes/08e882820aa0681e55c346f57102dfb1792e142c)) -- Improved element merge performance by avoiding per-relation and per-structure queries. ([#19252](https://github.com/craftcms/cms/pull/19252/changes/202c2f6782ac59d15cf8cbda32ab4304807b0407)) -- Improved search indexing memory use when indexing many elements. ([#19252](https://github.com/craftcms/cms/pull/19252/changes/117c2c5f222eec8acb2371937928a364a52c0fb0)) -- Improved asset indexing performance when finding missing and empty folders. ([#19252](https://github.com/craftcms/cms/pull/19252/changes/fe4974ab449f2e0402b333cf77282d04f4ee5558)) -- Prevented duplicate image transform jobs from being queued for the same transform. ([#19252](https://github.com/craftcms/cms/pull/19252/changes/059ccbed6ccd41c12dea1a5eb806f281e5878290)) -- Removed duplicate Control Panel icon alias registrations. ([#19252](https://github.com/craftcms/cms/pull/19252/changes/e8acf264f2bad6fd4c7c0f3de742ad85f89cdbbb)) -- Fixed a bug where GraphQL asset mutations weren’t executing HTTP requests for remote asset URLs. ([#19252](https://github.com/craftcms/cms/pull/19252/changes/35e54924d7404ce21a591ece04a970afc5a3ae80)) -- Fixed a bug where failed relation writes could leave partial relation changes persisted. ([#19252](https://github.com/craftcms/cms/pull/19252/changes/4f466d0730e266ea347a069807be6bc7a61e3afc)) -- Fixed a bug where element merge replacement jobs could be dispatched before their database transaction was committed. ([#19252](https://github.com/craftcms/cms/pull/19252/changes/a50f8cb6fe6f037d7fc95a3b7305fb09a57759ff)) -- Fixed a bug where section project-config jobs could be dispatched before their database transaction was committed. ([#19252](https://github.com/craftcms/cms/pull/19252/changes/3b54bc28253cade054a10a879252a8d102571a33)) -- Fixed a bug where passkey login attempts weren’t rate limited. ([#19252](https://github.com/craftcms/cms/pull/19252/changes/e6f7deca8eaba4c056b27358bb9b0b89b96e0cc5)) -- Fixed a bug where relation localization could not be retried safely after a failed run. ([#19252](https://github.com/craftcms/cms/pull/19252/changes/915b8196d920cc1d27d352e1fe773a921a258e46)) -- Fixed a bug where project config mutex cleanup could release a lock owned by another process. ([#19252](https://github.com/craftcms/cms/pull/19252/changes/845e2795c5158dfe1249d7543331e2a163e9dc3f)) -- Fixed a bug where nested structure operations could release their mutex lock before the outer operation completed. ([#19252](https://github.com/craftcms/cms/pull/19252/changes/9f5157ae9745a4677117cdfeb0051a82b8af916b)) -- Fixed a bug where two-factor authentication verification attempts weren’t rate limited. ([#19252](https://github.com/craftcms/cms/pull/19252/changes/f4f11c8ef465fa981ee32d2c1ed84ea8b8e8d13e)) -- Fixed a bug where user photo uploads could exceed the configured maximum upload size. ([#19252](https://github.com/craftcms/cms/pull/19252/changes/fc3fa25f5e7c9108b9e465b1d93ea5d116cf3e08)) -- Fixed a bug where unsafe filenames could be used for Craft support attachments. ([#19252](https://github.com/craftcms/cms/pull/19252/changes/2872b891eca9d243901e186b6bba76150fc0d16e)) -- Fixed a bug where a failed legacy field type migration could leave project config events muted. ([#19252](https://github.com/craftcms/cms/pull/19252/changes/0b22858254f9d6ef54e1f4aaca4de055a1c7f388)) -- Fixed a bug where TemplateGlobals were being resolved every time a Blade component rendered. ([#19257](https://github.com/craftcms/cms/pull/19257)) -- Fixed a bug where Craft updates could fail with a 503 response when the action URL contained query parameters. - -## 6.0.0-alpha.12 - 2026-07-15 - -- Added `Illuminate\Contracts\Translation\HasLocalePreference` support to user elements, allowing Laravel notifications to use users’ Language preferences. ([#19228](https://github.com/craftcms/cms/pull/19228)) -- Login attempts are now rate limited. -- Updated core asset I/O to resolve Craft filesystem definitions and configured storage targets through Laravel filesystem disks. -- Updated elevated session prompts to use the modern control panel frontend while preserving the legacy JavaScript APIs. -- Fixed a bug where site routes weren't being registered for each localized site value. -- Fixed a bug where POST requests to the `loginPath` weren’t being handled properly. ([#19220](https://github.com/craftcms/cms/pull/19220)) -- Fixed a bug where users were redirected to the previous page on logout. ([#19220](https://github.com/craftcms/cms/pull/19220)) -- Fixed a bug where requests to the `loginPath`, `setPasswordPath`, and `verifyEmailPath` were getting redirected to the control panel. ([#19229](https://github.com/craftcms/cms/pull/19229)) -- Fixed a bug where Laravel translation fallbacks weren’t applied when `translationDebugOutput` was enabled. ([#19228](https://github.com/craftcms/cms/pull/19228)) -- Fixed a bug where custom plugin settings `FormRequest` classes could persist unvalidated settings. ([#19228](https://github.com/craftcms/cms/pull/19228)) -- Fixed a bug where failed Craft API responses weren’t processing response headers. ([#19228](https://github.com/craftcms/cms/pull/19228)) -- Fixed a bug where Craft plugin service providers could be skipped when the plugin’s Composer metadata also defined Laravel package discovery settings. ([#19228](https://github.com/craftcms/cms/pull/19228)) -- Fixed a bug where event-registered user permissions weren’t getting saved. ([#19232](https://github.com/craftcms/cms/issues/19232)) -- Fixed lifecycle leaks where asset, GraphQL, route token, user, and user permission state could persist in long-running application processes. ([#19242](https://github.com/craftcms/cms/pull/19242)) -- Fixed [moderate-severity](https://github.com/craftcms/cms/security/policy#severity--remediation) authorization bypass vulnerabilities. -- Fixed a [low-severity](https://github.com/craftcms/cms/security/policy#severity--remediation) authorization bypass vulnerability. -- Fixed a [low-severity](https://github.com/craftcms/cms/security/policy#severity--remediation) XSS vulnerability. - -## 6.0.0-alpha.11 - 2026-07-07 - -- Users can now connect their accounts to one or more Socialite providers. ([#19202](https://github.com/craftcms/cms/pull/19202)) -- The login page now lists Socialite providers. ([#19202](https://github.com/craftcms/cms/pull/19202)) -- Fixed a bug where some control panel resources and pages weren’t loading properly. ([#19214](https://github.com/craftcms/cms/issues/19214)) - -## 6.0.0-alpha.10 - 2026-07-03 - -- It’s now possible to load Blade views within Twig templates. ([#19148](https://github.com/craftcms/cms/pull/19148)) -- Craft now registers several Blade directives, bringing near feature parity with Twig templating. ([#19148](https://github.com/craftcms/cms/pull/19148)) -- Added SQLite database support. ([#19149](https://github.com/craftcms/cms/pull/19149)) -- Control panel resources are now provided by a `craftcms/cms-assets` package. ([#19162](https://github.com/craftcms/cms/pull/19162)) -- Renamed `CraftCms\Cms\Twig\PageLifecycle` to `CraftCms\Cms\View\PageLifecycle`. ([#19148](https://github.com/craftcms/cms/pull/19148)) -- Renamed `CraftCms\Cms\Twig\TemplateResolver` to `CraftCms\Cms\View\TemplateResolver`. ([#19148](https://github.com/craftcms/cms/pull/19148)) -- Fixed a bug where anonymous homepage and fallback site-template requests could bypass offline-site access enforcement. ([#19151](https://github.com/craftcms/cms/pull/19151)) -- Fixed a bug where the login page would show a CSRF token mismatch on http requests -- Fixed an error that could occur during Craft 6 upgrades when the `migrations` table was missing its `track` column. ([#19168](https://github.com/craftcms/cms/pull/19168)) -- Fixed an error that occurred when saving Users source settings after selecting the Groups table column. ([#19184](https://github.com/craftcms/cms/pull/19184)) -- Fixed a bug where database backups weren’t using the `--single-transaction` or `--column-statistics=0` flags on MySQL. -- Fixed a bug where Content Block fields’ nested fields weren’t available as table columns on element indexes. - -## 6.0.0-alpha.9 - 2026-06-23 - -- Added `CraftCms\Yii2Adapter\Database\DeprecatedTable`. -- Added `CraftCms\Cms\Translation\Formatter::asRelativeTime()`. ([#19146](https://github.com/craftcms/cms/pull/19146)) -- Updated `webonyx/graphql-php` to 15.33.1. ([#18757](https://github.com/craftcms/cms/pull/18757)) -- `craft\elements\Category::find()` now returns a `CraftCms\Yii2Adapter\Element\Queries\CategoryQuery` object. ([#19120](https://github.com/craftcms/cms/pull/19120)) -- `craft\elements\GlobalSet::find()` now returns a `CraftCms\Yii2Adapter\Element\Queries\GlobalSetQuery` object. ([#19120](https://github.com/craftcms/cms/pull/19120)) -- `craft\elements\Tag::find()` now returns a `CraftCms\Yii2Adapter\Element\Queries\TagQuery` object. ([#19120](https://github.com/craftcms/cms/pull/19120)) -- Fixed a “This password does not use the Bcrypt algorithm” error that could occur when logging in with a user whose password was set in an earlier version of Craft. -- Fixed a “File name is not a string” error that could occur when an error was encountered when rendering a string template. ([#19122](https://github.com/craftcms/cms/pull/19122)) -- Fixed a bug where parsed site names would get saved to the project config. ([#19123](https://github.com/craftcms/cms/issues/19123)) -- Fixed a bug where plugin `$styles`, `$scripts`, and `$publishables` weren’t published automatically when the plugin was installed or enabled. ([#19137](https://github.com/craftcms/cms/pull/19137)) -- Fixed several issues that occurred when Craft was configured with a custom (or no) `cpTrigger`. ([#19127](https://github.com/craftcms/cms/pull/19127)) -- Fixed a bug where Craft wasn’t applying the Settings → General timezone to PHP’s default timezone. ([#19138](https://github.com/craftcms/cms/pull/19138)) -- Fixed a bug where entry queries weren’t fetching structure data by default. -- Fixed a bug where top-level structure elements were always repositioned to the end of the structure on save. -- Fixed a bug where the Settings index page didn’t include “Globals”, “Categories”, or “Tags” links, when the concepts were supported. ([#19120](https://github.com/craftcms/cms/pull/19120)) -- Fixed errors that occurred when editing global sets, category groups, and tag groups. ([#19120](https://github.com/craftcms/cms/pull/19120)) -- Fixed a bug where it wasn’t possible to create new categories. ([#19120](https://github.com/craftcms/cms/pull/19120)) -- Fixed an error that occurred when editing a category. ([#19120](https://github.com/craftcms/cms/pull/19120)) -- Fixed a bug where users’ Language preference field could be set to Arabic by default when the browser’s preferred language included a territory ID (e.g. `en-US`). -- Fixed a bug where preview tokens weren’t taking the `previewTokenDuration` config setting into account. - -## 6.0.0-alpha.8 - 2026-06-17 - -- Added `CraftCms\Cms\Twig\AllowableInSandbox`. -- Fixed a bug where Blade templates weren’t loading for text/Markdown mail. ([#19106](https://github.com/craftcms/cms/pull/19106)) -- Fixed a bug where it wasn’t possible to change the primary site, or edit site statuses. ([#19109](https://github.com/craftcms/cms/issues/19109)) - -## 6.0.0-alpha.7 - 2026-06-16 - -- Added a new core Markdown field ([#18960](https://github.com/craftcms/cms/pull/18960)) -- Added a way for fields to track references and register a deletion blocker for them ([#19014](https://github.com/craftcms/cms/pull/19014)) -- Added `CraftCms\Cms\Validation\Events\ValidationRulesResolving::$ruleset`. -- Relaxed the allowed types in the `ValidationRulesResolving` event to include any implementation `ValidatesWithRuleset` or a `Illuminate\Http\Request` object. -- Renamed `CraftCms\Cms\Validation\Events\ValidationRulesResolving::$component` to `$subject`. -- Relocated `CraftCms\Cms\Element\Validation\Events\ValidationRulesResolving` to `CraftCms\Cms\Validation\Events\` to reflect its broader applicability to components and rulesets. - Fixed errors that could occur when Craft user elements were expected but the authenticated user was resolved as a Laravel user model. ([#19051](https://github.com/craftcms/cms/pull/19051)) - Fixed a bug where the `craft:install` command would hang if run within a production environment. -- Fixed an error that could occur when `CraftCms\Cms\Support\DateTimeHelper::toDateTime()` returned a `DateTimeInterface` implementation other than `DateTime`. ([#19079](https://github.com/craftcms/cms/pull/19079)) - Fixed a bug where “Replace relation” action buttons weren’t working. - Fixed a “Invalid URL” JavaScript error in the control panel. ([#19041](https://github.com/craftcms/cms/pull/19041)) - Fixed an error that could occur during Craft 6 upgrades when legacy relational or Matrix field settings included `showCardsInGrid`. ([#19047](https://github.com/craftcms/cms/pull/19047)) - Fixed a bug where queue job progress labels weren’t getting translated. - Fixed a bug where the control panel sidebar and Queue Manager were showing completed jobs. -- Fixed a bug where `CraftCms\Yii2Adapter\Mixins\ValidateMixin::addErrors()` had incorrect arguments. ([#19065](https://github.com/craftcms/cms/pull/19065)) -- Fixed a bug where plugin templates were not being loaded correctly -- Fixed a bug where query string params were getting registered as variables in Twig templates. ([#19090](https://github.com/craftcms/cms/discussions/19090)) -- Fixed a bug where parsed site URLs would get saved to the project config. ([#19092](https://github.com/craftcms/cms/issues/19092)) +- Relocated `CraftCms\Cms\Element\Validation\Events\ValidationRulesResolving` to `CraftCms\Cms\Validation\Events\ValidationRulesResolving` to reflect its broader applicability to components and rulesets. +- Relaxed the allowed types in the `ValidationRulesResolving` event to include any implementation `ValidatesWithRuleset` or a `Illuminate\Http\Request` object. +- Renamed `CraftCms\Cms\Validation\Events\ValidationRulesResolving::$component` to `$subject` +- Added `CraftCms\Cms\Validation\Events\ValidationRulesResolving::$ruleset` ## 6.0.0-alpha.6 - 2026-06-03 - Improved the accessibility of the Login page. ([#19025](https://github.com/craftcms/cms/pull/19025)) - Added `CraftCms\Cms\User\Contracts\CraftUser` and `CraftUserTrait`. ([#19009](https://github.com/craftcms/cms/pull/19009)) - Removed `CraftCms\Cms\Auth\UserProvider`; the Craft guard now defaults to Laravel’s Eloquent provider using `CraftCms\Cms\User\Models\User`. ([#19009](https://github.com/craftcms/cms/pull/19009)) -- Added `\CraftCms\Cms\craftUser()`/`\CraftCms\Cms\craftUser()` and `request()->craftUser()` as Craft-safe ways to access the authenticated user. ([#19009](https://github.com/craftcms/cms/pull/19009)) +- Added `Auth::craftUser()`/`auth('craft')->craftUser()` and `request()->craftUser()` as Craft-safe ways to access the authenticated user. ([#19009](https://github.com/craftcms/cms/pull/19009)) - `Element::getIterator()` no longer includes custom field values. ([#19004](https://github.com/craftcms/cms/issues/19004)) - Fixed a bug where checking the elevated session timeout could overwrite newer session data, which could prevent passkeys from being created. - Fixed a bug where legacy plugin-defined `actions.php` routes could collide between plugins. ([#18994](https://github.com/craftcms/cms/pull/18994)) @@ -696,7 +393,7 @@ Craft’s Mutex classes have been deprecated. [Laravel’s atomic locking](https - Added `CraftCms\Cms\Auth\Events\SettingPassword`. - Added `CraftCms\Cms\User\Notifications\ResetPasswordNotification`. - Deprecated `craft\services\Auth`. `CraftCms\Cms\Auth\Auth` should be used instead. -- Deprecated `craft\web\User`. `auth()->user()` or `CraftCms\Cms\User\Elements\User` methods should be used instead. +- Deprecated `craft\web\User`. `auth('craft')->user()` or `CraftCms\Cms\User\Elements\User` methods should be used instead. - Deprecated `craft\events\AuthenticateUserEvent`. `CraftCms\Cms\Auth\Events\UserAuthenticating` should be used instead. - Deprecated `\craft\records\Authenticator`. `\CraftCms\Cms\Auth\Models\Authenticator` should be used instead. - Deprecated `\craft\records\RecoveryCodes`. `\CraftCms\Cms\Auth\Models\RecoveryCodes` should be used instead. @@ -705,7 +402,7 @@ Craft’s Mutex classes have been deprecated. [Laravel’s atomic locking](https - Deprecated `craft\behaviors\SessionBehavior::authorize`. `CraftCms\Cms\Auth\SessionAuth::authorize` should be used instead. - Deprecated `craft\behaviors\SessionBehavior::deauthorize`. `CraftCms\Cms\Auth\SessionAuth::deauthorize` should be used instead. - Deprecated `craft\behaviors\SessionBehavior::checkAuthorization`. `CraftCms\Cms\Auth\SessionAuth::checkAuthorization` should be used instead. -- Deprecated `craft\services\Users::isVerificationCodeValidForUser()`. `Password::broker()->tokenExists($user, $code)` should be used instead. +- Deprecated `craft\services\Users::isVerificationCodeValidForUser()`. `Password::broker('craft')->tokenExists($user, $code)` should be used instead. - Deprecated the `elevatedSessionDuration` general config setting. The `auth.password_timeout` config value should be used instead. To disable password confirmation (elevated sessions), you now set this value to `-1` instead of `0`. - Elevated sessions now work through [Laravel’s password confirmation](https://laravel.com/docs/12.x/authentication#password-confirmation) system. - Removed `craft\controllers\AuthController`. The following controllers now implement this functionality: @@ -1404,9 +1101,9 @@ Moved the following controllers: - Updated Twig `{% paginate %}` queries to use Laravel paginators and generate query-string pagination URLs based on the `pageTrigger` general config setting. - Added `CraftCms\Cms\Twig\Twig` service for managing Twig environments, replacing the Twig management logic previously in `craft\web\View`. -- Added `CraftCms\Cms\View\TemplateManager` for rendering templates, replacing the rendering logic previously in `craft\web\View`. +- Added `CraftCms\Cms\Twig\TemplateRenderer` for rendering templates, replacing the rendering logic previously in `craft\web\View`. - Added `CraftCms\Cms\Twig\PageLifecycle` for managing the page rendering lifecycle (head/body placeholder replacement), replacing the page lifecycle logic previously in `craft\web\View`. -- Added `CraftCms\Cms\Support\Facades\Twig` facade, resolving to `CraftCms\Cms\Twig\Twig`. +- Added `CraftCms\Cms\Support\Facades\Twig` facade, resolving to `CraftCms\Cms\Twig\TemplateRenderer`. - Added `CraftCms\Cms\Twig\Environment`, moved from `craft\web\twig\Environment`. - Added `CraftCms\Cms\Twig\TemplateResolver`. - Added `CraftCms\Cms\Twig\TemplateLoader`. @@ -1419,16 +1116,16 @@ Moved the following controllers: - Deprecated `craft\web\View::registerCpTwigExtension()`. `CraftCms\Cms\Twig\Twig::registerExtension()` should be used instead. - Deprecated `craft\web\View::registerSiteTwigExtension()`. `CraftCms\Cms\Twig\Twig::registerExtension()` should be used instead. - Deprecated `craft\web\View::registerTwigExtension()`. `CraftCms\Cms\Twig\Twig::registerExtension()` should be used instead. -- Deprecated `craft\web\View::renderTemplate()`. `CraftCms\Cms\View\TemplateManager::renderTemplate()` or the `template()` helper should be used instead. -- Deprecated `craft\web\View::renderSandboxedTemplate()`. `CraftCms\Cms\View\TemplateManager::renderSandboxedTemplate()` or the `sandboxedTemplate()` helper should be used instead. -- Deprecated `craft\web\View::renderPageTemplate()`. `CraftCms\Cms\View\TemplateManager::renderPageTemplate()` or the `pageTemplate()` helper should be used instead. -- Deprecated `craft\web\View::renderString()`. `CraftCms\Cms\View\TemplateManager::renderTwigString()` or the `renderString()` helper should be used instead. -- Deprecated `craft\web\View::renderSandboxedString()`. `CraftCms\Cms\View\TemplateManager::renderSandboxedString()` or the `renderSandboxedString()` helper should be used instead. -- Deprecated `craft\web\View::renderObjectTemplate()`. `CraftCms\Cms\View\TemplateManager::renderObjectTemplate()` or the `renderObjectTemplate()` helper should be used instead. -- Deprecated `craft\web\View::renderSandboxedObjectTemplate()`. `CraftCms\Cms\View\TemplateManager::renderSandboxedObjectTemplate()` or the `renderSandboxedObjectTemplate()` helper should be used instead. -- Deprecated `craft\web\View::normalizeObjectTemplate()`. `CraftCms\Cms\View\TemplateManager::normalizeObjectTemplate()` should be used instead. -- Deprecated `craft\web\View::getIsRenderingTemplate()`. `CraftCms\Cms\View\TemplateManager::isRenderingTemplate()` should be used instead. -- Deprecated `craft\web\View::getIsRenderingPageTemplate()`. `CraftCms\Cms\View\TemplateManager::isRenderingPageTemplate()` should be used instead. +- Deprecated `craft\web\View::renderTemplate()`. `CraftCms\Cms\Twig\TemplateRenderer::renderTemplate()` or the `template()` helper should be used instead. +- Deprecated `craft\web\View::renderSandboxedTemplate()`. `CraftCms\Cms\Twig\TemplateRenderer::renderSandboxedTemplate()` or the `sandboxedTemplate()` helper should be used instead. +- Deprecated `craft\web\View::renderPageTemplate()`. `CraftCms\Cms\Twig\TemplateRenderer::renderPageTemplate()` or the `pageTemplate()` helper should be used instead. +- Deprecated `craft\web\View::renderString()`. `CraftCms\Cms\Twig\TemplateRenderer::renderString()` or the `renderString()` helper should be used instead. +- Deprecated `craft\web\View::renderSandboxedString()`. `CraftCms\Cms\Twig\TemplateRenderer::renderSandboxedString()` or the `renderSandboxedString()` helper should be used instead. +- Deprecated `craft\web\View::renderObjectTemplate()`. `CraftCms\Cms\Twig\TemplateRenderer::renderObjectTemplate()` or the `renderObjectTemplate()` helper should be used instead. +- Deprecated `craft\web\View::renderSandboxedObjectTemplate()`. `CraftCms\Cms\Twig\TemplateRenderer::renderSandboxedObjectTemplate()` or the `renderSandboxedObjectTemplate()` helper should be used instead. +- Deprecated `craft\web\View::normalizeObjectTemplate()`. `CraftCms\Cms\Twig\TemplateRenderer::normalizeObjectTemplate()` should be used instead. +- Deprecated `craft\web\View::getIsRenderingTemplate()`. `CraftCms\Cms\Twig\TemplateRenderer::isRenderingTemplate` should be used instead. +- Deprecated `craft\web\View::getIsRenderingPageTemplate()`. `CraftCms\Cms\Twig\TemplateRenderer::isRenderingPageTemplate` should be used instead. - Deprecated `craft\web\twig\Environment`. `CraftCms\Cms\Twig\Environment` should be used instead. - Deprecated `craft\web\View::EVENT_AFTER_CREATE_TWIG`. `CraftCms\Cms\Twig\Events\TwigCreated` should be used instead. - Deprecated `craft\web\View::doesTemplateExist()`. `CraftCms\Cms\Twig\TemplateResolver::doesTemplateExist()` should be used instead. @@ -1467,14 +1164,14 @@ Moved the following controllers: - Added `CraftCms\Cms\User\Notifications\VerifyEmailNotification`. - `Users::purgeExpiredPendingUsers()` now joins the `password_reset_tokens` table to find expired pending users. - Removed `verificationCode` and `verificationCodeIssuedDate` columns on the `users` table in favor of the `password_reset_tokens` table. -- Deprecated `craft\services\Users::isVerificationCodeValidForUser()`. `Password::broker()->tokenExists($user, $code)` should be used instead. +- Deprecated `craft\services\Users::isVerificationCodeValidForUser()`. `Password::broker('craft')->tokenExists($user, $code)` should be used instead. - Removed `craft\controllers\UsersController` in favor of: - `CraftCms\Cms\Http\Controllers\Users\ActivateController`. - `CraftCms\Cms\Http\Controllers\Users\PasswordController`. - `CraftCms\Cms\Http\Controllers\Users\SaveUserController`. - Removed `\craft\controllers\UserSettingsController` in favor of: - - `CraftCms\Cms\Http\Controllers\Settings\Users\UserGroupsController` - - `CraftCms\Cms\Http\Controllers\Settings\Users\UserSettingsController` + - `CraftCms\Cms\Http\Controllers\Settings\UserGroupsController` + - `CraftCms\Cms\Http\Controllers\Settings\UserSettingsController` - Deprecated `UserGroupEvent` in favor of: - `CraftCms\Cms\User\Events\UserGroupSaving` - `CraftCms\Cms\User\Events\UserGroupSaved` diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1e8275483d8..476edd4ce53 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -69,15 +69,18 @@ If you would like to work on a new core feature or improvement, first create a [ ## Control Panel Front End -In order to work on the control panel front end, run `npm run dev`. On first run, this ensures the build artifacts the dev server depends on exist (building them if they don't), then starts the Vite development server together with the `@craftcms/ui` watcher, with output from each prefixed so you can tell them apart. +In order to work on the control panel front end, we recommend opening two terminal windows. -That covers most control panel work. If you also need to edit files under `packages/craftcms-legacy`, run `npm run dev:legacy` instead, which additionally starts the legacy webpack watcher. +1. Run `npm run dev` in one window to start the Vite development server. +2. Run `npm run dev:cp` in the other window to start the Vite process for the `@craftcms/cp` package. -If getting into the weeds is your thing, more detail on these pieces is provided below. +With both processes running, you'll be able to work on most aspects of the control panel. + +If getting into the weeds is your thing, more detail on these pieces is provided below. ### Control Panel Assets -The source files specific to the control panel live in the `resources` folder. Production builds are written to the local `cms-assets` package so they can be published through `craftcms/cms-assets`. To develop assets for the control panel, there are two commands: +The assets specific to the control panel live in the `resources` folder. Those are built using a fairly typical Vite setup. To develop assets for the control panel, there are two commands: ```shell # Run the Vite development server npm run dev @@ -86,22 +89,18 @@ npm run dev npm run build ``` -### `@craftcms/ui` package +### `@craftcms/cp` package -The control panel is largely backed by web components that live in the `@craftcms/ui` package within the `packages/craftcms-ui` directory. Like other packages, it has its own build process that can be run independently of the control panel. +The control panel is largely backed by web components that live in the `@craftcms/cp` package within the `packages/craftcms-cp` directory. Like other packages, it has its own build process that can be run independently of the control panel. ```shell # Run the build in watch mode. Assets will be rebuilt on every change -npm run dev:ui +npm run dev:cp # Run the build for production -npm run build:ui +npm run build:cp ``` -In practice, you rarely work on one without the other, which is why `npm run dev` runs both together. - -### `@craftcms/garnish` package - -`@craftcms/garnish` doesn't need its own watcher during development. The Vite dev server resolves it directly from source in `packages/craftcms-garnish/src`, so changes show up immediately. Production builds (and typechecking) use its built `dist` output instead, produced by `npm run build:garnish` or `npm run build:all`. +In practice, you rarely work on one without the other, so we recommend having two terminal panes open. One running the main control panel assets build and another building the web components. ### Legacy Bundles diff --git a/cms-assets/.gitattributes b/cms-assets/.gitattributes deleted file mode 100644 index a7ee10288e6..00000000000 --- a/cms-assets/.gitattributes +++ /dev/null @@ -1 +0,0 @@ -/resources/**/* linguist-generated=true diff --git a/cms-assets/composer.json b/cms-assets/composer.json deleted file mode 100644 index 2689250852b..00000000000 --- a/cms-assets/composer.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "name": "craftcms/cms-assets", - "description": "Built assets for Craft CMS.", - "license": "proprietary", - "type": "library" -} diff --git a/composer.json b/composer.json index e8a61c42723..f76975599fb 100644 --- a/composer.json +++ b/composer.json @@ -37,18 +37,15 @@ "bacon/bacon-qr-code": "^3.0", "commerceguys/addressing": "^2.1.1", "composer/semver": "^3.3.2", - "craftcms/cms-assets": "self.version", "craftcms/laravel-aliases": "^2.0", "craftcms/laravel-dependency-aware-cache": "^1.2.3", "craftcms/laravel-ruleset-validation": "^1.1", "craftcms/plugin-installer": "~1.6.0", "craftcms/server-check": "~6.0.0", - "craftcms/url-validator": "^1.0", "elvanto/litemoji": "^5.2.0", "enshrined/svg-sanitize": "~0.22.0", "guzzlehttp/guzzle": "^7.2.0", "inertiajs/inertia-laravel": "^3.0", - "intervention/image": "^4.2", "laravel/framework": "^13.0.0", "laravel/wayfinder": "^0.1.12", "league/commonmark": "^2.8", @@ -56,6 +53,8 @@ "league/uri": "^7.0", "moneyphp/money": "^4.0", "phpoffice/phpspreadsheet": "^5.3", + "pixelandtonic/graphql-php": "~14.11.10.1", + "pixelandtonic/imagine": "~1.5.2.1", "pragmarx/google2fa": "^9.0", "pragmarx/recovery": "^0.2.1", "symfony/css-selector": "^7.0|^8.0", @@ -66,10 +65,9 @@ "symfony/yaml": "^7.0|^8.0", "theiconic/name-parser": "^1.2", "tpetry/laravel-query-expressions": "^1.5", - "twig/twig": "~3.28.0", + "twig/twig": "~3.27.0", "voku/portable-ascii": "^2.0", - "web-auth/webauthn-lib": "~5.3.5", - "webonyx/graphql-php": "~15.33.1", + "web-auth/webauthn-lib": "~5.2.4", "yiisoft/arrays": "^3.2", "yiisoft/html": "^4.1", "yiisoft/translator": "^3.2", @@ -80,15 +78,14 @@ "dg/bypass-finals": "^1.9", "driftingly/rector-laravel": "^2.1", "fakerphp/faker": "^1.19.0", - "intervention/image-driver-vips": "^4.1", "larastan/larastan": "^3.4", "laravel/pao": "^1.0", "laravel/pint": "^1.22", "laravel/socialite": "^5.23", "orchestra/testbench": "^11.0", - "pestphp/pest": "^5.0", - "pestphp/pest-plugin-arch": "^5.0", - "pestphp/pest-plugin-laravel": "^5.0", + "pestphp/pest": "^4.0", + "pestphp/pest-plugin-arch": "^4.0", + "pestphp/pest-plugin-laravel": "^4.0", "phpstan/phpstan": "^2.1", "rector/rector": "^2.3", "spatie/laravel-typescript-transformer": "^3.2" @@ -97,16 +94,11 @@ { "type": "path", "url": "./yii2-adapter" - }, - { - "type": "path", - "url": "./cms-assets" } ], "suggest": { "ext-exif": "Adds support for parsing image EXIF data.", "ext-imagick": "Adds support for more image processing formats and options.", - "intervention/image-driver-vips": "Adds support for image processing with libvips (requires ext-ffi and libvips).", "ext-iconv": "Adds support for more character encodings than PHP\u2019s built-in mb_convert_encoding() function, which Craft will take advantage of when converting strings to UTF-8.", "laravel/socialite": "Adds OAuth login support for providers configured with `GeneralConfig::oauthProviders()`." }, @@ -137,23 +129,22 @@ "Composer\\Config::disableProcessTimeout", "./vendor/bin/pest --compact" ], - "tests-adapter": "./yii2-adapter/vendor/bin/pest --configuration ./yii2-adapter/phpunit.xml.dist --test-directory ./tests-laravel", + "tests-adapter": "./vendor/bin/pest --configuration ./yii2-adapter/phpunit.xml.dist --test-directory ./yii2-adapter/tests-laravel", "post-autoload-dump": [ "@clear", "@prepare" ], "clear": "@php vendor/bin/testbench package:purge-skeleton --ansi", "prepare": "@php vendor/bin/testbench package:discover --ansi", - "build": [ - "@php vendor/bin/testbench package:create-sqlite-db --ansi", - "@php vendor/bin/testbench workbench:build --ansi" - ], + "build": "@php vendor/bin/testbench workbench:build --ansi", "serve": [ "Composer\\Config::disableProcessTimeout", - "@php vendor/bin/testbench workbench:serve --ansi" + "@php vendor/bin/testbench package:sync-skeleton --ansi", + "@build", + "@php vendor/bin/testbench serve --ansi" ], "ci": [ - "@php pint --parallel", + "@php pint", "@rector", "@phpstan", "@tests", @@ -219,7 +210,6 @@ "SiteGroups": "CraftCms\\Cms\\Support\\Facades\\SiteGroups", "Sites": "CraftCms\\Cms\\Support\\Facades\\Sites", "Structures": "CraftCms\\Cms\\Support\\Facades\\Structures", - "Template": "CraftCms\\Cms\\Support\\Facades\\Template", "TemplateHooks": "CraftCms\\Cms\\Support\\Facades\\TemplateHooks", "Twig": "CraftCms\\Cms\\Support\\Facades\\Twig", "Updates": "CraftCms\\Cms\\Support\\Facades\\Updates", diff --git a/composer.lock b/composer.lock index 750d7220712..b901d96084c 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "84796e77430ac384e8ac609e35d63e9d", + "content-hash": "b958943aaa951fca6c36ce6c38f5b550", "packages": [ { "name": "bacon/bacon-qr-code", @@ -63,16 +63,16 @@ }, { "name": "brick/math", - "version": "0.17.2", + "version": "0.17.0", "source": { "type": "git", "url": "https://github.com/brick/math.git", - "reference": "8189e751995f9e15729c1aa2f89fa8f166ffe818" + "reference": "a62af7ab2e3cee9f9bf4cf77a5d1e6ba408a44ee" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/brick/math/zipball/8189e751995f9e15729c1aa2f89fa8f166ffe818", - "reference": "8189e751995f9e15729c1aa2f89fa8f166ffe818", + "url": "https://api.github.com/repos/brick/math/zipball/a62af7ab2e3cee9f9bf4cf77a5d1e6ba408a44ee", + "reference": "a62af7ab2e3cee9f9bf4cf77a5d1e6ba408a44ee", "shasum": "" }, "require": { @@ -110,7 +110,7 @@ ], "support": { "issues": "https://github.com/brick/math/issues", - "source": "https://github.com/brick/math/tree/0.17.2" + "source": "https://github.com/brick/math/tree/0.17.0" }, "funding": [ { @@ -118,7 +118,7 @@ "type": "github" } ], - "time": "2026-05-25T20:34:43+00:00" + "time": "2026-03-17T12:54:54+00:00" }, { "name": "carbonphp/carbon-doctrine-types", @@ -409,23 +409,6 @@ ], "time": "2025-08-20T19:15:30+00:00" }, - { - "name": "craftcms/cms-assets", - "version": "dev-6.x-5.11", - "dist": { - "type": "path", - "url": "./cms-assets", - "reference": "6b7f21fe6abe9c9750de4682b6b318fbeb79a9b3" - }, - "type": "library", - "license": [ - "proprietary" - ], - "description": "Built assets for Craft CMS.", - "transport-options": { - "relative": true - } - }, { "name": "craftcms/laravel-aliases", "version": "2.1.0", @@ -727,62 +710,6 @@ }, "time": "2026-05-06T18:15:11+00:00" }, - { - "name": "craftcms/url-validator", - "version": "1.0.0", - "source": { - "type": "git", - "url": "https://github.com/craftcms/url-validator.git", - "reference": "75b44bc4d3f89feb9410b85d385f01210edd5eb1" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/craftcms/url-validator/zipball/75b44bc4d3f89feb9410b85d385f01210edd5eb1", - "reference": "75b44bc4d3f89feb9410b85d385f01210edd5eb1", - "shasum": "" - }, - "require": { - "ext-filter": "*", - "php": "^8.0.2" - }, - "require-dev": { - "laravel/pint": "^1.29", - "nunomaduro/collision": "^8.1", - "pestphp/pest": "^3.0", - "phpstan/phpstan": "^2.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "CraftCms\\UrlValidator\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Pixel & Tonic", - "homepage": "https://pixelandtonic.com/" - } - ], - "description": "Validate URLs and IP addresses against SSRF, DNS rebinding, and cloud-metadata attacks.", - "homepage": "https://github.com/craftcms/url-validator", - "keywords": [ - "IP", - "craftcms", - "security", - "ssrf", - "url", - "validation" - ], - "support": { - "issues": "https://github.com/craftcms/url-validator/issues", - "source": "https://github.com/craftcms/url-validator/tree/1.0.0" - }, - "time": "2026-06-15T17:29:09+00:00" - }, { "name": "dasprid/enum", "version": "1.0.7", @@ -1563,26 +1490,25 @@ }, { "name": "guzzlehttp/guzzle", - "version": "7.15.2", + "version": "7.10.6", "source": { "type": "git", "url": "https://github.com/guzzle/guzzle.git", - "reference": "744101956d78b7c1384d0cbf379db13e859167bf" + "reference": "e7412b3180912c01650cc66647f18c1d1cbe9b94" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/744101956d78b7c1384d0cbf379db13e859167bf", - "reference": "744101956d78b7c1384d0cbf379db13e859167bf", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/e7412b3180912c01650cc66647f18c1d1cbe9b94", + "reference": "e7412b3180912c01650cc66647f18c1d1cbe9b94", "shasum": "" }, "require": { "ext-json": "*", - "guzzlehttp/promises": "^2.5.1", - "guzzlehttp/psr7": "^2.13", + "guzzlehttp/promises": "^2.3", + "guzzlehttp/psr7": "^2.8", "php": "^7.2.5 || ^8.0", "psr/http-client": "^1.0", - "symfony/deprecation-contracts": "^2.5 || ^3.0", - "symfony/polyfill-php80": "^1.25" + "symfony/deprecation-contracts": "^2.2 || ^3.0" }, "provide": { "psr/http-client-implementation": "1.0" @@ -1590,8 +1516,8 @@ "require-dev": { "bamarni/composer-bin-plugin": "^1.8.2", "ext-curl": "*", - "guzzle/client-integration-tests": "3.0.3", - "guzzlehttp/test-server": "^0.7", + "guzzle/client-integration-tests": "3.0.2", + "guzzlehttp/test-server": "^0.4", "php-http/message-factory": "^1.1", "phpunit/phpunit": "^8.5.52 || ^9.6.34", "psr/log": "^1.1 || ^2.0 || ^3.0" @@ -1671,7 +1597,7 @@ ], "support": { "issues": "https://github.com/guzzle/guzzle/issues", - "source": "https://github.com/guzzle/guzzle/tree/7.15.2" + "source": "https://github.com/guzzle/guzzle/tree/7.10.6" }, "funding": [ { @@ -1687,25 +1613,24 @@ "type": "tidelift" } ], - "time": "2026-07-26T23:23:20+00:00" + "time": "2026-06-01T13:06:22+00:00" }, { "name": "guzzlehttp/promises", - "version": "2.5.1", + "version": "2.4.1", "source": { "type": "git", "url": "https://github.com/guzzle/promises.git", - "reference": "9ad1e4fc607446a055b95870c7f668e93b5cff29" + "reference": "09e8a212562fb1fb6a512c4156ed71525969d6c2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/promises/zipball/9ad1e4fc607446a055b95870c7f668e93b5cff29", - "reference": "9ad1e4fc607446a055b95870c7f668e93b5cff29", + "url": "https://api.github.com/repos/guzzle/promises/zipball/09e8a212562fb1fb6a512c4156ed71525969d6c2", + "reference": "09e8a212562fb1fb6a512c4156ed71525969d6c2", "shasum": "" }, "require": { - "php": "^7.2.5 || ^8.0", - "symfony/deprecation-contracts": "^2.5 || ^3.0" + "php": "^7.2.5 || ^8.0" }, "require-dev": { "bamarni/composer-bin-plugin": "^1.8.2", @@ -1755,7 +1680,7 @@ ], "support": { "issues": "https://github.com/guzzle/promises/issues", - "source": "https://github.com/guzzle/promises/tree/2.5.1" + "source": "https://github.com/guzzle/promises/tree/2.4.1" }, "funding": [ { @@ -1771,29 +1696,27 @@ "type": "tidelift" } ], - "time": "2026-07-08T15:48:39+00:00" + "time": "2026-05-20T22:57:30+00:00" }, { "name": "guzzlehttp/psr7", - "version": "2.13.0", + "version": "2.10.4", "source": { "type": "git", "url": "https://github.com/guzzle/psr7.git", - "reference": "dad89620b7a6edb60c15858442eb2e408b45d8f4" + "reference": "d2a1a094e396da8957e797489fddaf860c340cfc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/dad89620b7a6edb60c15858442eb2e408b45d8f4", - "reference": "dad89620b7a6edb60c15858442eb2e408b45d8f4", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/d2a1a094e396da8957e797489fddaf860c340cfc", + "reference": "d2a1a094e396da8957e797489fddaf860c340cfc", "shasum": "" }, "require": { "php": "^7.2.5 || ^8.0", "psr/http-factory": "^1.0", "psr/http-message": "^1.1 || ^2.0", - "ralouphie/getallheaders": "^3.0", - "symfony/deprecation-contracts": "^2.5 || ^3.0", - "symfony/polyfill-php80": "^1.25" + "ralouphie/getallheaders": "^3.0" }, "provide": { "psr/http-factory-implementation": "1.0", @@ -1874,7 +1797,7 @@ ], "support": { "issues": "https://github.com/guzzle/psr7/issues", - "source": "https://github.com/guzzle/psr7/tree/2.13.0" + "source": "https://github.com/guzzle/psr7/tree/2.10.4" }, "funding": [ { @@ -1890,25 +1813,25 @@ "type": "tidelift" } ], - "time": "2026-07-16T22:23:49+00:00" + "time": "2026-05-29T12:59:07+00:00" }, { "name": "guzzlehttp/uri-template", - "version": "v1.0.10", + "version": "v1.0.6", "source": { "type": "git", "url": "https://github.com/guzzle/uri-template.git", - "reference": "f6c24c21f42b990e9a58912b332d0874df6ba839" + "reference": "eef7f87bab6f204eba3c39224d8075c70c637946" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/uri-template/zipball/f6c24c21f42b990e9a58912b332d0874df6ba839", - "reference": "f6c24c21f42b990e9a58912b332d0874df6ba839", + "url": "https://api.github.com/repos/guzzle/uri-template/zipball/eef7f87bab6f204eba3c39224d8075c70c637946", + "reference": "eef7f87bab6f204eba3c39224d8075c70c637946", "shasum": "" }, "require": { "php": "^7.2.5 || ^8.0", - "symfony/polyfill-php80": "^1.25" + "symfony/polyfill-php80": "^1.24" }, "require-dev": { "bamarni/composer-bin-plugin": "^1.8.2", @@ -1960,7 +1883,7 @@ ], "support": { "issues": "https://github.com/guzzle/uri-template/issues", - "source": "https://github.com/guzzle/uri-template/tree/v1.0.10" + "source": "https://github.com/guzzle/uri-template/tree/v1.0.6" }, "funding": [ { @@ -1976,7 +1899,7 @@ "type": "tidelift" } ], - "time": "2026-07-17T13:53:03+00:00" + "time": "2026-05-23T22:00:21+00:00" }, { "name": "inertiajs/inertia-laravel", @@ -2051,166 +1974,22 @@ }, "time": "2026-04-30T15:30:29+00:00" }, - { - "name": "intervention/gif", - "version": "5.0.1", - "source": { - "type": "git", - "url": "https://github.com/Intervention/gif.git", - "reference": "bb395af960deffe64d70c976b4df9283f68e762d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Intervention/gif/zipball/bb395af960deffe64d70c976b4df9283f68e762d", - "reference": "bb395af960deffe64d70c976b4df9283f68e762d", - "shasum": "" - }, - "require": { - "php": "^8.3" - }, - "require-dev": { - "phpstan/phpstan": "^2.1", - "phpunit/phpunit": "^12.0", - "slevomat/coding-standard": "~8.0", - "squizlabs/php_codesniffer": "^4" - }, - "type": "library", - "autoload": { - "psr-4": { - "Intervention\\Gif\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Oliver Vogel", - "email": "oliver@intervention.io", - "homepage": "https://intervention.io/" - } - ], - "description": "PHP GIF Encoder/Decoder", - "homepage": "https://github.com/intervention/gif", - "keywords": [ - "animation", - "gd", - "gif", - "image" - ], - "support": { - "issues": "https://github.com/Intervention/gif/issues", - "source": "https://github.com/Intervention/gif/tree/5.0.1" - }, - "funding": [ - { - "url": "https://paypal.me/interventionio", - "type": "custom" - }, - { - "url": "https://github.com/Intervention", - "type": "github" - }, - { - "url": "https://ko-fi.com/interventionphp", - "type": "ko_fi" - } - ], - "time": "2026-05-03T06:04:47+00:00" - }, - { - "name": "intervention/image", - "version": "4.2.0", - "source": { - "type": "git", - "url": "https://github.com/Intervention/image.git", - "reference": "830907fc5397dfc2a51a4e90322d586989fc8364" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Intervention/image/zipball/830907fc5397dfc2a51a4e90322d586989fc8364", - "reference": "830907fc5397dfc2a51a4e90322d586989fc8364", - "shasum": "" - }, - "require": { - "ext-mbstring": "*", - "intervention/gif": "^5", - "php": "^8.3" - }, - "require-dev": { - "mockery/mockery": "^1.6", - "phpstan/phpstan": "^2.1", - "phpunit/phpunit": "^12.0", - "slevomat/coding-standard": "~8.0", - "squizlabs/php_codesniffer": "^4" - }, - "suggest": { - "ext-exif": "Recommended to be able to read EXIF data properly." - }, - "type": "library", - "autoload": { - "psr-4": { - "Intervention\\Image\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Oliver Vogel", - "email": "oliver@intervention.io", - "homepage": "https://intervention.io" - } - ], - "description": "PHP Image Processing", - "homepage": "https://image.intervention.io", - "keywords": [ - "gd", - "image", - "imagick", - "resize", - "thumbnail", - "watermark" - ], - "support": { - "issues": "https://github.com/Intervention/image/issues", - "source": "https://github.com/Intervention/image/tree/4.2.0" - }, - "funding": [ - { - "url": "https://paypal.me/interventionio", - "type": "custom" - }, - { - "url": "https://github.com/Intervention", - "type": "github" - }, - { - "url": "https://ko-fi.com/interventionphp", - "type": "ko_fi" - } - ], - "time": "2026-07-09T13:07:14+00:00" - }, { "name": "laravel/framework", - "version": "v13.23.0", + "version": "v13.12.0", "source": { "type": "git", "url": "https://github.com/laravel/framework.git", - "reference": "92a707229148e57f08a249211c8a5a194159c619" + "reference": "6ac27a7fcfa728250c9f77921cb8fb955546b591" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/framework/zipball/92a707229148e57f08a249211c8a5a194159c619", - "reference": "92a707229148e57f08a249211c8a5a194159c619", + "url": "https://api.github.com/repos/laravel/framework/zipball/6ac27a7fcfa728250c9f77921cb8fb955546b591", + "reference": "6ac27a7fcfa728250c9f77921cb8fb955546b591", "shasum": "" }, "require": { - "brick/math": "^0.14.2 || ^0.15 || ^0.16 || ^0.17 || ^0.18", + "brick/math": "^0.14.2 || ^0.15 || ^0.16 || ^0.17", "composer-runtime-api": "^2.2", "doctrine/inflector": "^2.0.5", "dragonmantank/cron-expression": "^3.4", @@ -2232,7 +2011,7 @@ "league/flysystem": "^3.25.1", "league/flysystem-local": "^3.25.1", "league/uri": "^7.5.1", - "monolog/monolog": "^3.10", + "monolog/monolog": "^3.0", "nesbot/carbon": "^3.8.4", "nunomaduro/termwind": "^2.0", "php": "^8.3", @@ -2285,7 +2064,6 @@ "illuminate/filesystem": "self.version", "illuminate/hashing": "self.version", "illuminate/http": "self.version", - "illuminate/image": "self.version", "illuminate/json-schema": "self.version", "illuminate/log": "self.version", "illuminate/macroable": "self.version", @@ -2312,7 +2090,6 @@ "ext-gmp": "*", "fakerphp/faker": "^1.24", "guzzlehttp/psr7": "^2.9", - "intervention/image": "^4.0", "laravel/pint": "^1.18", "league/flysystem-aws-s3-v3": "^3.25.1", "league/flysystem-ftp": "^3.25.1", @@ -2349,7 +2126,6 @@ "ext-redis": "Required to use the Redis cache and queue drivers (^4.0 || ^5.0 || ^6.0).", "fakerphp/faker": "Required to generate fake data using the fake() helper (^1.23).", "filp/whoops": "Required for friendly error pages in development (^2.14.3).", - "intervention/image": "Required to use the image processing features (^4.0).", "laravel/tinker": "Required to use the tinker console command (^2.0).", "league/flysystem-aws-s3-v3": "Required to use the Flysystem S3 driver (^3.25.1).", "league/flysystem-ftp": "Required to use the Flysystem FTP driver (^3.25.1).", @@ -2420,20 +2196,20 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2026-07-27T14:48:58+00:00" + "time": "2026-05-26T23:39:26+00:00" }, { "name": "laravel/prompts", - "version": "v0.3.21", + "version": "v0.3.18", "source": { "type": "git", "url": "https://github.com/laravel/prompts.git", - "reference": "7753c65c281c2550c7c183f14e18062073b7d821" + "reference": "a19af51bb144bf87f08397921fa619f85c7d4e72" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/prompts/zipball/7753c65c281c2550c7c183f14e18062073b7d821", - "reference": "7753c65c281c2550c7c183f14e18062073b7d821", + "url": "https://api.github.com/repos/laravel/prompts/zipball/a19af51bb144bf87f08397921fa619f85c7d4e72", + "reference": "a19af51bb144bf87f08397921fa619f85c7d4e72", "shasum": "" }, "require": { @@ -2477,22 +2253,22 @@ "description": "Add beautiful and user-friendly forms to your command-line applications.", "support": { "issues": "https://github.com/laravel/prompts/issues", - "source": "https://github.com/laravel/prompts/tree/v0.3.21" + "source": "https://github.com/laravel/prompts/tree/v0.3.18" }, - "time": "2026-06-26T00:11:25+00:00" + "time": "2026-05-19T00:47:18+00:00" }, { "name": "laravel/serializable-closure", - "version": "v2.0.15", + "version": "v2.0.13", "source": { "type": "git", "url": "https://github.com/laravel/serializable-closure.git", - "reference": "dccd8bcb851bb03fcc005df650b708b57cc52661" + "reference": "b566ee0dd251f3c4078bed003a7ce015f5ea6dce" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/serializable-closure/zipball/dccd8bcb851bb03fcc005df650b708b57cc52661", - "reference": "dccd8bcb851bb03fcc005df650b708b57cc52661", + "url": "https://api.github.com/repos/laravel/serializable-closure/zipball/b566ee0dd251f3c4078bed003a7ce015f5ea6dce", + "reference": "b566ee0dd251f3c4078bed003a7ce015f5ea6dce", "shasum": "" }, "require": { @@ -2540,7 +2316,7 @@ "issues": "https://github.com/laravel/serializable-closure/issues", "source": "https://github.com/laravel/serializable-closure" }, - "time": "2026-07-21T16:49:22+00:00" + "time": "2026-04-16T14:03:50+00:00" }, { "name": "laravel/wayfinder", @@ -2607,16 +2383,16 @@ }, { "name": "league/commonmark", - "version": "2.8.3", + "version": "2.8.2", "source": { "type": "git", "url": "https://github.com/thephpleague/commonmark.git", - "reference": "1902f60f984235023acbe03db6ad614a37b3c3e7" + "reference": "59fb075d2101740c337c7216e3f32b36c204218b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/1902f60f984235023acbe03db6ad614a37b3c3e7", - "reference": "1902f60f984235023acbe03db6ad614a37b3c3e7", + "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/59fb075d2101740c337c7216e3f32b36c204218b", + "reference": "59fb075d2101740c337c7216e3f32b36c204218b", "shasum": "" }, "require": { @@ -2638,8 +2414,8 @@ "github/gfm": "0.29.0", "michelf/php-markdown": "^1.4 || ^2.0", "nyholm/psr7": "^1.5", - "phpstan/phpstan": "^2.0.0", - "phpunit/phpunit": "^9.5.21 || ^10.5.9 || ^11.0.0 || ^12.0.0 || ^13.0.0", + "phpstan/phpstan": "^1.8.2", + "phpunit/phpunit": "^9.5.21 || ^10.5.9 || ^11.0.0", "scrutinizer/ocular": "^1.8.1", "symfony/finder": "^5.3 | ^6.0 | ^7.0 || ^8.0", "symfony/process": "^5.4 | ^6.0 | ^7.0 || ^8.0", @@ -2710,7 +2486,7 @@ "type": "tidelift" } ], - "time": "2026-07-12T15:29:16+00:00" + "time": "2026-03-19T13:16:38+00:00" }, { "name": "league/config", @@ -2796,16 +2572,16 @@ }, { "name": "league/flysystem", - "version": "3.35.2", + "version": "3.34.0", "source": { "type": "git", "url": "https://github.com/thephpleague/flysystem.git", - "reference": "b277b5dc3d56650b68904117124e79c851e12376" + "reference": "2daaac3b0d4c83ea7ed5d8586e786f5d00f3540e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/b277b5dc3d56650b68904117124e79c851e12376", - "reference": "b277b5dc3d56650b68904117124e79c851e12376", + "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/2daaac3b0d4c83ea7ed5d8586e786f5d00f3540e", + "reference": "2daaac3b0d4c83ea7ed5d8586e786f5d00f3540e", "shasum": "" }, "require": { @@ -2873,9 +2649,9 @@ ], "support": { "issues": "https://github.com/thephpleague/flysystem/issues", - "source": "https://github.com/thephpleague/flysystem/tree/3.35.2" + "source": "https://github.com/thephpleague/flysystem/tree/3.34.0" }, - "time": "2026-07-06T14:42:07+00:00" + "time": "2026-05-14T10:28:08+00:00" }, { "name": "league/flysystem-local", @@ -2974,16 +2750,16 @@ }, { "name": "league/mime-type-detection", - "version": "1.17.0", + "version": "1.16.0", "source": { "type": "git", "url": "https://github.com/thephpleague/mime-type-detection.git", - "reference": "f5f47eff7c48ed1003069a2ca67f316fb4021c76" + "reference": "2d6702ff215bf922936ccc1ad31007edc76451b9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/mime-type-detection/zipball/f5f47eff7c48ed1003069a2ca67f316fb4021c76", - "reference": "f5f47eff7c48ed1003069a2ca67f316fb4021c76", + "url": "https://api.github.com/repos/thephpleague/mime-type-detection/zipball/2d6702ff215bf922936ccc1ad31007edc76451b9", + "reference": "2d6702ff215bf922936ccc1ad31007edc76451b9", "shasum": "" }, "require": { @@ -2993,7 +2769,7 @@ "require-dev": { "friendsofphp/php-cs-fixer": "^3.2", "phpstan/phpstan": "^0.12.68", - "phpunit/phpunit": "^8.5.8 || ^9.3 || ^10.0 || ^11.0 || ^12.0" + "phpunit/phpunit": "^8.5.8 || ^9.3 || ^10.0" }, "type": "library", "autoload": { @@ -3014,7 +2790,7 @@ "description": "Mime-type detection for Flysystem", "support": { "issues": "https://github.com/thephpleague/mime-type-detection/issues", - "source": "https://github.com/thephpleague/mime-type-detection/tree/1.17.0" + "source": "https://github.com/thephpleague/mime-type-detection/tree/1.16.0" }, "funding": [ { @@ -3026,7 +2802,7 @@ "type": "tidelift" } ], - "time": "2026-07-09T11:49:27+00:00" + "time": "2024-09-21T08:32:55+00:00" }, { "name": "league/uri", @@ -3590,16 +3366,16 @@ }, { "name": "nesbot/carbon", - "version": "3.13.1", + "version": "3.11.4", "source": { "type": "git", "url": "https://github.com/CarbonPHP/carbon.git", - "reference": "2937ad3d1d2c506fd2bc97d571438a95641f44e2" + "reference": "e890471a3494740f7d9326d72ce6a8c559ffee60" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/CarbonPHP/carbon/zipball/2937ad3d1d2c506fd2bc97d571438a95641f44e2", - "reference": "2937ad3d1d2c506fd2bc97d571438a95641f44e2", + "url": "https://api.github.com/repos/CarbonPHP/carbon/zipball/e890471a3494740f7d9326d72ce6a8c559ffee60", + "reference": "e890471a3494740f7d9326d72ce6a8c559ffee60", "shasum": "" }, "require": { @@ -3691,7 +3467,7 @@ "type": "tidelift" } ], - "time": "2026-07-09T18:23:49+00:00" + "time": "2026-04-07T09:57:54+00:00" }, { "name": "nette/schema", @@ -3762,16 +3538,16 @@ }, { "name": "nette/utils", - "version": "v4.1.5", + "version": "v4.1.4", "source": { "type": "git", "url": "https://github.com/nette/utils.git", - "reference": "b043439dbdf954e6c28b5ea7e34b0100f83165e0" + "reference": "7da6c396d7ebe142bc857c20479d5e70a5e1aac7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nette/utils/zipball/b043439dbdf954e6c28b5ea7e34b0100f83165e0", - "reference": "b043439dbdf954e6c28b5ea7e34b0100f83165e0", + "url": "https://api.github.com/repos/nette/utils/zipball/7da6c396d7ebe142bc857c20479d5e70a5e1aac7", + "reference": "7da6c396d7ebe142bc857c20479d5e70a5e1aac7", "shasum": "" }, "require": { @@ -3791,7 +3567,7 @@ }, "suggest": { "ext-gd": "to use Image", - "ext-iconv": "to use Strings::chr(), ord() and reverse()", + "ext-iconv": "to use Strings::webalize(), toAscii(), chr() and reverse()", "ext-intl": "to use Strings::webalize(), toAscii(), normalize() and compare()", "ext-json": "to use Nette\\Utils\\Json", "ext-mbstring": "to use Strings::lower() etc...", @@ -3847,9 +3623,9 @@ ], "support": { "issues": "https://github.com/nette/utils/issues", - "source": "https://github.com/nette/utils/tree/v4.1.5" + "source": "https://github.com/nette/utils/tree/v4.1.4" }, - "time": "2026-07-17T23:02:45+00:00" + "time": "2026-05-11T20:49:54+00:00" }, { "name": "nunomaduro/termwind", @@ -4062,16 +3838,16 @@ }, { "name": "phpdocumentor/reflection-docblock", - "version": "6.0.3", + "version": "5.6.7", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "7bae67520aa9f5ecc506d646810bd40d9da54582" + "reference": "31a105931bc8ffa3a123383829772e832fd8d903" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/7bae67520aa9f5ecc506d646810bd40d9da54582", - "reference": "7bae67520aa9f5ecc506d646810bd40d9da54582", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/31a105931bc8ffa3a123383829772e832fd8d903", + "reference": "31a105931bc8ffa3a123383829772e832fd8d903", "shasum": "" }, "require": { @@ -4079,8 +3855,8 @@ "ext-filter": "*", "php": "^7.4 || ^8.0", "phpdocumentor/reflection-common": "^2.2", - "phpdocumentor/type-resolver": "^2.0", - "phpstan/phpdoc-parser": "^2.0", + "phpdocumentor/type-resolver": "^1.7", + "phpstan/phpdoc-parser": "^1.7|^2.0", "webmozart/assert": "^1.9.1 || ^2" }, "require-dev": { @@ -4090,8 +3866,7 @@ "phpstan/phpstan-mockery": "^1.1", "phpstan/phpstan-webmozart-assert": "^1.2", "phpunit/phpunit": "^9.5", - "psalm/phar": "^5.26", - "shipmonk/dead-code-detector": "^0.5.1" + "psalm/phar": "^5.26" }, "type": "library", "extra": { @@ -4121,44 +3896,44 @@ "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", "support": { "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", - "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/6.0.3" + "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.6.7" }, - "time": "2026-03-18T20:49:53+00:00" + "time": "2026-03-18T20:47:46+00:00" }, { "name": "phpdocumentor/type-resolver", - "version": "2.0.0", + "version": "1.12.0", "source": { "type": "git", "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "327a05bbee54120d4786a0dc67aad30226ad4cf9" + "reference": "92a98ada2b93d9b201a613cb5a33584dde25f195" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/327a05bbee54120d4786a0dc67aad30226ad4cf9", - "reference": "327a05bbee54120d4786a0dc67aad30226ad4cf9", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/92a98ada2b93d9b201a613cb5a33584dde25f195", + "reference": "92a98ada2b93d9b201a613cb5a33584dde25f195", "shasum": "" }, "require": { "doctrine/deprecations": "^1.0", - "php": "^7.4 || ^8.0", + "php": "^7.3 || ^8.0", "phpdocumentor/reflection-common": "^2.0", - "phpstan/phpdoc-parser": "^2.0" + "phpstan/phpdoc-parser": "^1.18|^2.0" }, "require-dev": { "ext-tokenizer": "*", "phpbench/phpbench": "^1.2", - "phpstan/extension-installer": "^1.4", - "phpstan/phpstan": "^2.1", - "phpstan/phpstan-phpunit": "^2.0", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan": "^1.8", + "phpstan/phpstan-phpunit": "^1.1", "phpunit/phpunit": "^9.5", - "psalm/phar": "^4" + "rector/rector": "^0.13.9", + "vimeo/psalm": "^4.25" }, "type": "library", "extra": { "branch-alias": { - "dev-1.x": "1.x-dev", - "dev-2.x": "2.x-dev" + "dev-1.x": "1.x-dev" } }, "autoload": { @@ -4179,9 +3954,9 @@ "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", "support": { "issues": "https://github.com/phpDocumentor/TypeResolver/issues", - "source": "https://github.com/phpDocumentor/TypeResolver/tree/2.0.0" + "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.12.0" }, - "time": "2026-01-06T21:53:42+00:00" + "time": "2025-11-21T15:09:14+00:00" }, { "name": "phpoffice/phpspreadsheet", @@ -4369,16 +4144,16 @@ }, { "name": "phpstan/phpdoc-parser", - "version": "2.3.3", + "version": "2.3.2", "source": { "type": "git", "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "fb19eedd2bb67ff8cf7a5502ad329e701d6398a3" + "reference": "a004701b11273a26cd7955a61d67a7f1e525a45a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/fb19eedd2bb67ff8cf7a5502ad329e701d6398a3", - "reference": "fb19eedd2bb67ff8cf7a5502ad329e701d6398a3", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/a004701b11273a26cd7955a61d67a7f1e525a45a", + "reference": "a004701b11273a26cd7955a61d67a7f1e525a45a", "shasum": "" }, "require": { @@ -4410,9 +4185,134 @@ "description": "PHPDoc parser with support for nullable, intersection and generic types", "support": { "issues": "https://github.com/phpstan/phpdoc-parser/issues", - "source": "https://github.com/phpstan/phpdoc-parser/tree/2.3.3" + "source": "https://github.com/phpstan/phpdoc-parser/tree/2.3.2" + }, + "time": "2026-01-25T14:56:51+00:00" + }, + { + "name": "pixelandtonic/graphql-php", + "version": "v14.11.10.1", + "source": { + "type": "git", + "url": "https://github.com/pixelandtonic/graphql-php.git", + "reference": "fdb4a288878fc9ee449245e17209d676fc7c57fd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pixelandtonic/graphql-php/zipball/fdb4a288878fc9ee449245e17209d676fc7c57fd", + "reference": "fdb4a288878fc9ee449245e17209d676fc7c57fd", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-mbstring": "*", + "php": "^7.1 || ^8" + }, + "require-dev": { + "amphp/amp": "^2.3", + "doctrine/coding-standard": "^6.0", + "nyholm/psr7": "^1.2", + "phpbench/phpbench": "^1.2", + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "0.12.82", + "phpstan/phpstan-phpunit": "0.12.18", + "phpstan/phpstan-strict-rules": "0.12.9", + "phpunit/phpunit": "^7.2 || ^8.5", + "psr/http-message": "^1.0", + "react/promise": "2.*", + "simpod/php-coveralls-mirror": "^3.0" + }, + "suggest": { + "psr/http-message": "To use standard GraphQL server", + "react/promise": "To leverage async resolving on React PHP platform" + }, + "type": "library", + "autoload": { + "psr-4": { + "GraphQL\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A PHP port of GraphQL reference implementation", + "homepage": "https://github.com/webonyx/graphql-php", + "keywords": [ + "api", + "graphql" + ], + "support": { + "source": "https://github.com/pixelandtonic/graphql-php/tree/v14.11.10.1" + }, + "funding": [ + { + "url": "https://opencollective.com/webonyx-graphql-php", + "type": "open_collective" + } + ], + "time": "2026-04-14T15:27:52+00:00" + }, + { + "name": "pixelandtonic/imagine", + "version": "1.5.2.1", + "source": { + "type": "git", + "url": "https://github.com/pixelandtonic/Imagine.git", + "reference": "8e6c5cf929400142724b31482da51dc556277e15" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pixelandtonic/Imagine/zipball/8e6c5cf929400142724b31482da51dc556277e15", + "reference": "8e6c5cf929400142724b31482da51dc556277e15", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "require-dev": { + "phpunit/phpunit": "^4.8 || ^5.7 || ^6.5 || ^7.5 || ^8.4 || ^9.3" + }, + "suggest": { + "ext-exif": "to read EXIF metadata", + "ext-gd": "to use the GD implementation", + "ext-gmagick": "to use the Gmagick implementation", + "ext-imagick": "to use the Imagick implementation" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-develop": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Imagine\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bulat Shakirzyanov", + "email": "mallluhuct@gmail.com", + "homepage": "http://avalanche123.com" + } + ], + "description": "Image processing for PHP", + "homepage": "http://imagine.readthedocs.org/", + "keywords": [ + "drawing", + "graphics", + "image manipulation", + "image processing" + ], + "support": { + "source": "https://github.com/pixelandtonic/Imagine/tree/1.5.2.1" }, - "time": "2026-07-08T07:01:06+00:00" + "time": "2026-02-25T23:13:43+00:00" }, { "name": "pragmarx/google2fa", @@ -5135,20 +5035,20 @@ }, { "name": "ramsey/uuid", - "version": "4.9.3", + "version": "4.x-dev", "source": { "type": "git", "url": "https://github.com/ramsey/uuid.git", - "reference": "1df15849d00943a67d677dc9cfd80795f038c9f8" + "reference": "1a1f98b037d664d9093a620cfa85305c7e50b244" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ramsey/uuid/zipball/1df15849d00943a67d677dc9cfd80795f038c9f8", - "reference": "1df15849d00943a67d677dc9cfd80795f038c9f8", + "url": "https://api.github.com/repos/ramsey/uuid/zipball/1a1f98b037d664d9093a620cfa85305c7e50b244", + "reference": "1a1f98b037d664d9093a620cfa85305c7e50b244", "shasum": "" }, "require": { - "brick/math": ">=0.8.16 <=0.18", + "brick/math": ">=0.8.16 <=0.17", "php": "^8.0", "ramsey/collection": "^1.2 || ^2.0" }, @@ -5181,6 +5081,7 @@ "paragonie/random-lib": "Provides RandomLib for use with the RandomLibAdapter", "ramsey/uuid-doctrine": "Allows the use of Ramsey\\Uuid\\Uuid as Doctrine field type." }, + "default-branch": true, "type": "library", "extra": { "captainhook": { @@ -5207,9 +5108,9 @@ ], "support": { "issues": "https://github.com/ramsey/uuid/issues", - "source": "https://github.com/ramsey/uuid/tree/4.9.3" + "source": "https://github.com/ramsey/uuid/tree/4.x" }, - "time": "2026-06-18T03:57:49+00:00" + "time": "2026-04-27T22:11:13+00:00" }, { "name": "spomky-labs/cbor-php", @@ -5394,21 +5295,22 @@ }, { "name": "symfony/clock", - "version": "v8.1.0", + "version": "v7.4.8", "source": { "type": "git", "url": "https://github.com/symfony/clock.git", - "reference": "701ef4de9705d6c32292ebee5e8044094a09fbf6" + "reference": "674fa3b98e21531dd040e613479f5f6fa8f32111" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/clock/zipball/701ef4de9705d6c32292ebee5e8044094a09fbf6", - "reference": "701ef4de9705d6c32292ebee5e8044094a09fbf6", + "url": "https://api.github.com/repos/symfony/clock/zipball/674fa3b98e21531dd040e613479f5f6fa8f32111", + "reference": "674fa3b98e21531dd040e613479f5f6fa8f32111", "shasum": "" }, "require": { - "php": ">=8.4.1", - "psr/clock": "^1.0" + "php": ">=8.2", + "psr/clock": "^1.0", + "symfony/polyfill-php83": "^1.28" }, "provide": { "psr/clock-implementation": "1.0" @@ -5447,7 +5349,7 @@ "time" ], "support": { - "source": "https://github.com/symfony/clock/tree/v8.1.0" + "source": "https://github.com/symfony/clock/tree/v7.4.8" }, "funding": [ { @@ -5467,20 +5369,20 @@ "type": "tidelift" } ], - "time": "2026-05-29T05:06:50+00:00" + "time": "2026-03-24T13:12:05+00:00" }, { "name": "symfony/console", - "version": "v8.1.1", + "version": "v8.1.0", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "b711a8ab808b6c074c6b8caef70d0fd8d6b6d07d" + "reference": "f5a856c6ecb56b3c21ed94a5b7bf940d857d110a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/b711a8ab808b6c074c6b8caef70d0fd8d6b6d07d", - "reference": "b711a8ab808b6c074c6b8caef70d0fd8d6b6d07d", + "url": "https://api.github.com/repos/symfony/console/zipball/f5a856c6ecb56b3c21ed94a5b7bf940d857d110a", + "reference": "f5a856c6ecb56b3c21ed94a5b7bf940d857d110a", "shasum": "" }, "require": { @@ -5547,7 +5449,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v8.1.1" + "source": "https://github.com/symfony/console/tree/v8.1.0" }, "funding": [ { @@ -5567,7 +5469,7 @@ "type": "tidelift" } ], - "time": "2026-06-16T12:55:20+00:00" + "time": "2026-05-29T05:06:50+00:00" }, { "name": "symfony/css-selector", @@ -5640,16 +5542,16 @@ }, { "name": "symfony/deprecation-contracts", - "version": "v3.7.1", + "version": "v3.7.0", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "f3202fa1b5097b0af062dc978b32ecf63404e31d" + "reference": "50f59d1f3ca46d41ac911f97a78626b6756af35b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/f3202fa1b5097b0af062dc978b32ecf63404e31d", - "reference": "f3202fa1b5097b0af062dc978b32ecf63404e31d", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/50f59d1f3ca46d41ac911f97a78626b6756af35b", + "reference": "50f59d1f3ca46d41ac911f97a78626b6756af35b", "shasum": "" }, "require": { @@ -5687,7 +5589,7 @@ "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v3.7.1" + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.7.0" }, "funding": [ { @@ -5707,7 +5609,7 @@ "type": "tidelift" } ], - "time": "2026-06-05T06:23:12+00:00" + "time": "2026-04-13T15:52:40+00:00" }, { "name": "symfony/dom-crawler", @@ -5862,16 +5764,16 @@ }, { "name": "symfony/event-dispatcher", - "version": "v8.1.1", + "version": "v8.1.0", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "abd6c11dc468725d1627302ad10f6cd486e9e3d0" + "reference": "f249ae3f680958b6f1f9dd76e5747cf0695b4102" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/abd6c11dc468725d1627302ad10f6cd486e9e3d0", - "reference": "abd6c11dc468725d1627302ad10f6cd486e9e3d0", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/f249ae3f680958b6f1f9dd76e5747cf0695b4102", + "reference": "f249ae3f680958b6f1f9dd76e5747cf0695b4102", "shasum": "" }, "require": { @@ -5924,7 +5826,7 @@ "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/event-dispatcher/tree/v8.1.1" + "source": "https://github.com/symfony/event-dispatcher/tree/v8.1.0" }, "funding": [ { @@ -5944,20 +5846,20 @@ "type": "tidelift" } ], - "time": "2026-06-09T12:28:30+00:00" + "time": "2026-05-29T05:06:50+00:00" }, { "name": "symfony/event-dispatcher-contracts", - "version": "v3.7.1", + "version": "v3.7.0", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher-contracts.git", - "reference": "c7de7a00ffb67842132da02ea92988a39ccd9f4e" + "reference": "ccba7060602b7fed0b03c85bf025257f76d9ef32" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/c7de7a00ffb67842132da02ea92988a39ccd9f4e", - "reference": "c7de7a00ffb67842132da02ea92988a39ccd9f4e", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/ccba7060602b7fed0b03c85bf025257f76d9ef32", + "reference": "ccba7060602b7fed0b03c85bf025257f76d9ef32", "shasum": "" }, "require": { @@ -6004,7 +5906,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.7.1" + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.7.0" }, "funding": [ { @@ -6024,7 +5926,7 @@ "type": "tidelift" } ], - "time": "2026-06-05T06:23:12+00:00" + "time": "2026-01-05T13:30:16+00:00" }, { "name": "symfony/filesystem", @@ -6099,16 +6001,16 @@ }, { "name": "symfony/finder", - "version": "v8.1.1", + "version": "v8.1.0", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "e2989e762c70f9490fa3a00a0ac0fae5aa97a531" + "reference": "58d2e767a66052c1487356f953445634a8194c64" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/e2989e762c70f9490fa3a00a0ac0fae5aa97a531", - "reference": "e2989e762c70f9490fa3a00a0ac0fae5aa97a531", + "url": "https://api.github.com/repos/symfony/finder/zipball/58d2e767a66052c1487356f953445634a8194c64", + "reference": "58d2e767a66052c1487356f953445634a8194c64", "shasum": "" }, "require": { @@ -6143,7 +6045,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/finder/tree/v8.1.1" + "source": "https://github.com/symfony/finder/tree/v8.1.0" }, "funding": [ { @@ -6163,7 +6065,7 @@ "type": "tidelift" } ], - "time": "2026-06-27T09:05:56+00:00" + "time": "2026-05-29T05:06:50+00:00" }, { "name": "symfony/html-sanitizer", @@ -6239,16 +6141,16 @@ }, { "name": "symfony/http-foundation", - "version": "v8.1.1", + "version": "v8.1.0", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "6a168c8fcee806b57ac020244da14293d1f9a883" + "reference": "af11474600f06718086c2cda4fa6fa8d0a672e7e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/6a168c8fcee806b57ac020244da14293d1f9a883", - "reference": "6a168c8fcee806b57ac020244da14293d1f9a883", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/af11474600f06718086c2cda4fa6fa8d0a672e7e", + "reference": "af11474600f06718086c2cda4fa6fa8d0a672e7e", "shasum": "" }, "require": { @@ -6296,7 +6198,7 @@ "description": "Defines an object-oriented layer for the HTTP specification", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-foundation/tree/v8.1.1" + "source": "https://github.com/symfony/http-foundation/tree/v8.1.0" }, "funding": [ { @@ -6316,20 +6218,20 @@ "type": "tidelift" } ], - "time": "2026-06-12T08:43:41+00:00" + "time": "2026-05-29T05:06:50+00:00" }, { "name": "symfony/http-kernel", - "version": "v8.1.1", + "version": "v8.1.0", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "89d8d6e7fbab3d9eda89ccb5ecdf44a74c4ec9d2" + "reference": "cefeb37c82eed3e0c42fa25ba64cd3a908d90f39" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/89d8d6e7fbab3d9eda89ccb5ecdf44a74c4ec9d2", - "reference": "89d8d6e7fbab3d9eda89ccb5ecdf44a74c4ec9d2", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/cefeb37c82eed3e0c42fa25ba64cd3a908d90f39", + "reference": "cefeb37c82eed3e0c42fa25ba64cd3a908d90f39", "shasum": "" }, "require": { @@ -6405,7 +6307,7 @@ "description": "Provides a structured process for converting a Request into a Response", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-kernel/tree/v8.1.1" + "source": "https://github.com/symfony/http-kernel/tree/v8.1.0" }, "funding": [ { @@ -6425,20 +6327,20 @@ "type": "tidelift" } ], - "time": "2026-06-27T09:27:36+00:00" + "time": "2026-05-29T08:46:08+00:00" }, { "name": "symfony/mailer", - "version": "v8.1.1", + "version": "v8.1.0", "source": { "type": "git", "url": "https://github.com/symfony/mailer.git", - "reference": "4fa583a7377f28d54e4de442fba76375b2e20a12" + "reference": "9418d772df3a03a142e3bc06f602adb2b8724877" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mailer/zipball/4fa583a7377f28d54e4de442fba76375b2e20a12", - "reference": "4fa583a7377f28d54e4de442fba76375b2e20a12", + "url": "https://api.github.com/repos/symfony/mailer/zipball/9418d772df3a03a142e3bc06f602adb2b8724877", + "reference": "9418d772df3a03a142e3bc06f602adb2b8724877", "shasum": "" }, "require": { @@ -6485,7 +6387,7 @@ "description": "Helps sending emails", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/mailer/tree/v8.1.1" + "source": "https://github.com/symfony/mailer/tree/v8.1.0" }, "funding": [ { @@ -6505,7 +6407,7 @@ "type": "tidelift" } ], - "time": "2026-06-16T12:55:20+00:00" + "time": "2026-05-29T05:06:50+00:00" }, { "name": "symfony/mime", @@ -6678,16 +6580,16 @@ }, { "name": "symfony/polyfill-intl-grapheme", - "version": "v1.41.0", + "version": "v1.38.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-grapheme.git", - "reference": "bb899c1db0aa8127dc3afe8cda4a67eb24915f8d" + "reference": "e9247d281d694a5120554d9afaf54e070e88a603" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/bb899c1db0aa8127dc3afe8cda4a67eb24915f8d", - "reference": "bb899c1db0aa8127dc3afe8cda4a67eb24915f8d", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/e9247d281d694a5120554d9afaf54e070e88a603", + "reference": "e9247d281d694a5120554d9afaf54e070e88a603", "shasum": "" }, "require": { @@ -6736,7 +6638,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.41.0" + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.38.1" }, "funding": [ { @@ -6756,7 +6658,7 @@ "type": "tidelift" } ], - "time": "2026-07-28T08:25:59+00:00" + "time": "2026-05-26T05:58:03+00:00" }, { "name": "symfony/polyfill-intl-idn", @@ -6932,16 +6834,16 @@ }, { "name": "symfony/polyfill-mbstring", - "version": "v1.38.2", + "version": "v1.38.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "d3d318bad5e7a1bfbd026009c8bfb8d8f99ae6b6" + "reference": "14c5439eec4ccff081ac14eca2dc57feb2a66d92" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/d3d318bad5e7a1bfbd026009c8bfb8d8f99ae6b6", - "reference": "d3d318bad5e7a1bfbd026009c8bfb8d8f99ae6b6", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/14c5439eec4ccff081ac14eca2dc57feb2a66d92", + "reference": "14c5439eec4ccff081ac14eca2dc57feb2a66d92", "shasum": "" }, "require": { @@ -6993,7 +6895,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.38.2" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.38.1" }, "funding": [ { @@ -7013,7 +6915,7 @@ "type": "tidelift" } ], - "time": "2026-05-27T06:59:30+00:00" + "time": "2026-05-26T12:51:13+00:00" }, { "name": "symfony/polyfill-php80", @@ -7100,12 +7002,92 @@ "time": "2026-04-10T16:19:22+00:00" }, { - "name": "symfony/polyfill-php84", + "name": "symfony/polyfill-php83", "version": "v1.38.1", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-php84.git", - "reference": "f4e1dfaee5b74aba5964fe1fd4dfc7ba5e3085fa" + "url": "https://github.com/symfony/polyfill-php83.git", + "reference": "8339098cae28673c15cce00d80734af0453054e2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/8339098cae28673c15cce00d80734af0453054e2", + "reference": "8339098cae28673c15cce00d80734af0453054e2", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php83\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.3+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php83/tree/v1.38.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-05-26T12:51:13+00:00" + }, + { + "name": "symfony/polyfill-php84", + "version": "v1.38.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php84.git", + "reference": "f4e1dfaee5b74aba5964fe1fd4dfc7ba5e3085fa" }, "dist": { "type": "zip", @@ -7181,16 +7163,16 @@ }, { "name": "symfony/polyfill-php85", - "version": "v1.41.0", + "version": "v1.38.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php85.git", - "reference": "255fab485aaa1006ed411040c42aecd7b5302d7a" + "reference": "ba2ba04f3352cfa2dcbbcb90aee13ed967f505b1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php85/zipball/255fab485aaa1006ed411040c42aecd7b5302d7a", - "reference": "255fab485aaa1006ed411040c42aecd7b5302d7a", + "url": "https://api.github.com/repos/symfony/polyfill-php85/zipball/ba2ba04f3352cfa2dcbbcb90aee13ed967f505b1", + "reference": "ba2ba04f3352cfa2dcbbcb90aee13ed967f505b1", "shasum": "" }, "require": { @@ -7237,7 +7219,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php85/tree/v1.41.0" + "source": "https://github.com/symfony/polyfill-php85/tree/v1.38.1" }, "funding": [ { @@ -7257,20 +7239,20 @@ "type": "tidelift" } ], - "time": "2026-07-01T12:47:55+00:00" + "time": "2026-05-26T02:25:22+00:00" }, { "name": "symfony/polyfill-php86", - "version": "v1.41.0", + "version": "v1.38.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php86.git", - "reference": "6bc356ed3d8dbfeea8f0de235e34d670704e880e" + "reference": "fcec68d64f46dc84e1f6ffcf2c6dda40ff3143ad" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php86/zipball/6bc356ed3d8dbfeea8f0de235e34d670704e880e", - "reference": "6bc356ed3d8dbfeea8f0de235e34d670704e880e", + "url": "https://api.github.com/repos/symfony/polyfill-php86/zipball/fcec68d64f46dc84e1f6ffcf2c6dda40ff3143ad", + "reference": "fcec68d64f46dc84e1f6ffcf2c6dda40ff3143ad", "shasum": "" }, "require": { @@ -7317,7 +7299,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php86/tree/v1.41.0" + "source": "https://github.com/symfony/polyfill-php86/tree/v1.38.0" }, "funding": [ { @@ -7337,7 +7319,7 @@ "type": "tidelift" } ], - "time": "2026-07-02T13:42:24+00:00" + "time": "2026-05-25T11:52:35+00:00" }, { "name": "symfony/polyfill-uuid", @@ -7489,25 +7471,25 @@ }, { "name": "symfony/property-access", - "version": "v8.1.0", + "version": "v7.4.8", "source": { "type": "git", "url": "https://github.com/symfony/property-access.git", - "reference": "9261ef060f26cc7b728f67f141ba19b98a6209a9" + "reference": "b7dad9dae8b8a47ef7ecc76c8569e7d8c7d90cfc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/property-access/zipball/9261ef060f26cc7b728f67f141ba19b98a6209a9", - "reference": "9261ef060f26cc7b728f67f141ba19b98a6209a9", + "url": "https://api.github.com/repos/symfony/property-access/zipball/b7dad9dae8b8a47ef7ecc76c8569e7d8c7d90cfc", + "reference": "b7dad9dae8b8a47ef7ecc76c8569e7d8c7d90cfc", "shasum": "" }, "require": { - "php": ">=8.4.1", - "symfony/property-info": "^7.4.4|^8.0.4" + "php": ">=8.2", + "symfony/property-info": "^6.4.32|~7.3.10|^7.4.4|^8.0.4" }, "require-dev": { - "symfony/cache": "^7.4|^8.0", - "symfony/var-exporter": "^7.4|^8.0" + "symfony/cache": "^6.4|^7.0|^8.0", + "symfony/var-exporter": "^6.4.1|^7.0.1|^8.0" }, "type": "library", "autoload": { @@ -7546,7 +7528,7 @@ "reflection" ], "support": { - "source": "https://github.com/symfony/property-access/tree/v8.1.0" + "source": "https://github.com/symfony/property-access/tree/v7.4.8" }, "funding": [ { @@ -7566,37 +7548,41 @@ "type": "tidelift" } ], - "time": "2026-05-29T05:06:50+00:00" + "time": "2026-03-24T13:12:05+00:00" }, { "name": "symfony/property-info", - "version": "v8.1.0", + "version": "v7.4.8", "source": { "type": "git", "url": "https://github.com/symfony/property-info.git", - "reference": "4721e8c56d0cd2378e0ef9a9899f810008b859f7" + "reference": "ac5e82528b986c4f7cfccbf7764b5d2e824d6175" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/property-info/zipball/4721e8c56d0cd2378e0ef9a9899f810008b859f7", - "reference": "4721e8c56d0cd2378e0ef9a9899f810008b859f7", + "url": "https://api.github.com/repos/symfony/property-info/zipball/ac5e82528b986c4f7cfccbf7764b5d2e824d6175", + "reference": "ac5e82528b986c4f7cfccbf7764b5d2e824d6175", "shasum": "" }, "require": { - "php": ">=8.4.1", - "symfony/string": "^7.4|^8.0", + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/string": "^6.4|^7.0|^8.0", "symfony/type-info": "^7.4.7|^8.0.7" }, "conflict": { "phpdocumentor/reflection-docblock": "<5.2|>=7", - "phpdocumentor/type-resolver": "<1.5.1" + "phpdocumentor/type-resolver": "<1.5.1", + "symfony/cache": "<6.4", + "symfony/dependency-injection": "<6.4", + "symfony/serializer": "<6.4" }, "require-dev": { "phpdocumentor/reflection-docblock": "^5.2|^6.0", "phpstan/phpdoc-parser": "^1.0|^2.0", - "symfony/cache": "^7.4|^8.0", - "symfony/dependency-injection": "^7.4|^8.0", - "symfony/serializer": "^7.4|^8.0" + "symfony/cache": "^6.4|^7.0|^8.0", + "symfony/dependency-injection": "^6.4|^7.0|^8.0", + "symfony/serializer": "^6.4|^7.0|^8.0" }, "type": "library", "autoload": { @@ -7632,7 +7618,7 @@ "validator" ], "support": { - "source": "https://github.com/symfony/property-info/tree/v8.1.0" + "source": "https://github.com/symfony/property-info/tree/v7.4.8" }, "funding": [ { @@ -7652,7 +7638,7 @@ "type": "tidelift" } ], - "time": "2026-05-29T05:06:50+00:00" + "time": "2026-03-24T13:12:05+00:00" }, { "name": "symfony/routing", @@ -7736,54 +7722,59 @@ }, { "name": "symfony/serializer", - "version": "v8.1.1", + "version": "v7.4.10", "source": { "type": "git", "url": "https://github.com/symfony/serializer.git", - "reference": "f911b744bc24658f435ea30439cfe536f0173a3a" + "reference": "268c5aa6c4bd675eddd89348e7ecac292a843ddd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/serializer/zipball/f911b744bc24658f435ea30439cfe536f0173a3a", - "reference": "f911b744bc24658f435ea30439cfe536f0173a3a", + "url": "https://api.github.com/repos/symfony/serializer/zipball/268c5aa6c4bd675eddd89348e7ecac292a843ddd", + "reference": "268c5aa6c4bd675eddd89348e7ecac292a843ddd", "shasum": "" }, "require": { - "php": ">=8.4.1", + "php": ">=8.2", "symfony/deprecation-contracts": "^2.5|^3", - "symfony/polyfill-ctype": "^1.8" + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-php84": "^1.30" }, "conflict": { "phpdocumentor/reflection-docblock": "<5.2|>=7", "phpdocumentor/type-resolver": "<1.5.1", - "symfony/property-access": "<8.1", - "symfony/property-info": "<7.4", - "symfony/type-info": "<7.4" + "symfony/dependency-injection": "<6.4", + "symfony/property-access": "<6.4.31|>=7.0,<7.4.2|>=8.0,<8.0.2", + "symfony/property-info": "<6.4", + "symfony/type-info": "<7.2.5", + "symfony/uid": "<6.4", + "symfony/validator": "<6.4", + "symfony/yaml": "<6.4" }, "require-dev": { "phpdocumentor/reflection-docblock": "^5.2|^6.0", "phpstan/phpdoc-parser": "^1.0|^2.0", "seld/jsonlint": "^1.10", - "symfony/cache": "^7.4|^8.0", - "symfony/config": "^7.4|^8.0", - "symfony/console": "^7.4|^8.0", - "symfony/dependency-injection": "^7.4|^8.0", - "symfony/error-handler": "^7.4|^8.0", - "symfony/filesystem": "^7.4|^8.0", - "symfony/form": "^7.4|^8.0", - "symfony/http-foundation": "^7.4|^8.0", - "symfony/http-kernel": "^7.4|^8.0", - "symfony/messenger": "^7.4|^8.0", - "symfony/mime": "^7.4|^8.0", - "symfony/property-access": "^8.1", - "symfony/property-info": "^7.4|^8.0", + "symfony/cache": "^6.4|^7.0|^8.0", + "symfony/config": "^6.4|^7.0|^8.0", + "symfony/console": "^6.4|^7.0|^8.0", + "symfony/dependency-injection": "^7.2|^8.0", + "symfony/error-handler": "^6.4|^7.0|^8.0", + "symfony/filesystem": "^6.4|^7.0|^8.0", + "symfony/form": "^6.4|^7.0|^8.0", + "symfony/http-foundation": "^6.4|^7.0|^8.0", + "symfony/http-kernel": "^6.4|^7.0|^8.0", + "symfony/messenger": "^6.4|^7.0|^8.0", + "symfony/mime": "^6.4|^7.0|^8.0", + "symfony/property-access": "^6.4.31|^7.4.2|^8.0.2", + "symfony/property-info": "^6.4|^7.0|^8.0", "symfony/translation-contracts": "^2.5|^3", - "symfony/type-info": "^7.4|^8.0", - "symfony/uid": "^7.4|^8.0", - "symfony/validator": "^7.4|^8.0", - "symfony/var-dumper": "^7.4|^8.0", - "symfony/var-exporter": "^7.4|^8.0", - "symfony/yaml": "^7.4|^8.0" + "symfony/type-info": "^7.2.5|^8.0", + "symfony/uid": "^6.4|^7.0|^8.0", + "symfony/validator": "^6.4|^7.0|^8.0", + "symfony/var-dumper": "^6.4|^7.0|^8.0", + "symfony/var-exporter": "^6.4|^7.0|^8.0", + "symfony/yaml": "^6.4|^7.0|^8.0" }, "type": "library", "autoload": { @@ -7811,7 +7802,7 @@ "description": "Handles serializing and deserializing data structures, including object graphs, into array structures or other formats like XML and JSON.", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/serializer/tree/v8.1.1" + "source": "https://github.com/symfony/serializer/tree/v7.4.10" }, "funding": [ { @@ -7831,20 +7822,20 @@ "type": "tidelift" } ], - "time": "2026-06-27T09:05:56+00:00" + "time": "2026-05-03T13:03:28+00:00" }, { "name": "symfony/service-contracts", - "version": "v3.7.1", + "version": "v3.7.0", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "c0a284bab1ed8aa0417e3d69250ab437739563a0" + "reference": "d25d82433a80eba6aa0e6c24b61d7370d99e444a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/c0a284bab1ed8aa0417e3d69250ab437739563a0", - "reference": "c0a284bab1ed8aa0417e3d69250ab437739563a0", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/d25d82433a80eba6aa0e6c24b61d7370d99e444a", + "reference": "d25d82433a80eba6aa0e6c24b61d7370d99e444a", "shasum": "" }, "require": { @@ -7898,7 +7889,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/service-contracts/tree/v3.7.1" + "source": "https://github.com/symfony/service-contracts/tree/v3.7.0" }, "funding": [ { @@ -7918,7 +7909,7 @@ "type": "tidelift" } ], - "time": "2026-06-16T09:55:08+00:00" + "time": "2026-03-28T09:44:51+00:00" }, { "name": "symfony/string", @@ -8012,16 +8003,16 @@ }, { "name": "symfony/translation", - "version": "v8.1.1", + "version": "v8.1.0", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "342b4218630dc2cf284cedcb2080c80b13404014" + "reference": "b2bd012ca28c4acae830ee1206a5b6e35dd99693" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/342b4218630dc2cf284cedcb2080c80b13404014", - "reference": "342b4218630dc2cf284cedcb2080c80b13404014", + "url": "https://api.github.com/repos/symfony/translation/zipball/b2bd012ca28c4acae830ee1206a5b6e35dd99693", + "reference": "b2bd012ca28c4acae830ee1206a5b6e35dd99693", "shasum": "" }, "require": { @@ -8081,7 +8072,7 @@ "description": "Provides tools to internationalize your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/translation/tree/v8.1.1" + "source": "https://github.com/symfony/translation/tree/v8.1.0" }, "funding": [ { @@ -8101,20 +8092,20 @@ "type": "tidelift" } ], - "time": "2026-06-06T11:11:44+00:00" + "time": "2026-05-29T05:06:50+00:00" }, { "name": "symfony/translation-contracts", - "version": "v3.7.1", + "version": "v3.7.0", "source": { "type": "git", "url": "https://github.com/symfony/translation-contracts.git", - "reference": "ccb206b98faccc511ebae8e5fad50f2dc0b30621" + "reference": "0ab302977a952b42fd51475c4ebac81f8da0a95d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/ccb206b98faccc511ebae8e5fad50f2dc0b30621", - "reference": "ccb206b98faccc511ebae8e5fad50f2dc0b30621", + "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/0ab302977a952b42fd51475c4ebac81f8da0a95d", + "reference": "0ab302977a952b42fd51475c4ebac81f8da0a95d", "shasum": "" }, "require": { @@ -8163,7 +8154,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/translation-contracts/tree/v3.7.1" + "source": "https://github.com/symfony/translation-contracts/tree/v3.7.0" }, "funding": [ { @@ -8183,7 +8174,7 @@ "type": "tidelift" } ], - "time": "2026-06-05T06:23:12+00:00" + "time": "2026-01-05T13:30:16+00:00" }, { "name": "symfony/type-info", @@ -8269,24 +8260,24 @@ }, { "name": "symfony/uid", - "version": "v8.1.0", + "version": "v7.4.9", "source": { "type": "git", "url": "https://github.com/symfony/uid.git", - "reference": "7393f157a55f7e70a4de0334435c55a5a8fe749a" + "reference": "2676b524340abcfe4d6151ec698463cebafee439" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/uid/zipball/7393f157a55f7e70a4de0334435c55a5a8fe749a", - "reference": "7393f157a55f7e70a4de0334435c55a5a8fe749a", + "url": "https://api.github.com/repos/symfony/uid/zipball/2676b524340abcfe4d6151ec698463cebafee439", + "reference": "2676b524340abcfe4d6151ec698463cebafee439", "shasum": "" }, "require": { - "php": ">=8.4.1", + "php": ">=8.2", "symfony/polyfill-uuid": "^1.15" }, "require-dev": { - "symfony/console": "^7.4|^8.0" + "symfony/console": "^6.4|^7.0|^8.0" }, "type": "library", "autoload": { @@ -8323,7 +8314,7 @@ "uuid" ], "support": { - "source": "https://github.com/symfony/uid/tree/v8.1.0" + "source": "https://github.com/symfony/uid/tree/v7.4.9" }, "funding": [ { @@ -8343,20 +8334,20 @@ "type": "tidelift" } ], - "time": "2026-05-29T05:06:50+00:00" + "time": "2026-04-30T15:19:22+00:00" }, { "name": "symfony/var-dumper", - "version": "v8.1.1", + "version": "v8.1.0", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "40096a2515a979f3125c5c928603995b8664c62a" + "reference": "c2c4df1d21477cc21c9f6dc1b14d07c3abc4963e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/40096a2515a979f3125c5c928603995b8664c62a", - "reference": "40096a2515a979f3125c5c928603995b8664c62a", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/c2c4df1d21477cc21c9f6dc1b14d07c3abc4963e", + "reference": "c2c4df1d21477cc21c9f6dc1b14d07c3abc4963e", "shasum": "" }, "require": { @@ -8410,7 +8401,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v8.1.1" + "source": "https://github.com/symfony/var-dumper/tree/v8.1.0" }, "funding": [ { @@ -8430,20 +8421,20 @@ "type": "tidelift" } ], - "time": "2026-06-09T10:54:51+00:00" + "time": "2026-05-29T05:06:50+00:00" }, { "name": "symfony/yaml", - "version": "v8.1.1", + "version": "v8.1.0", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "8e4cdd4311683516be06944f4b85244063cdb886" + "reference": "efb42bd2c6f4f3ccfd4683583449938b5fc146b0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/8e4cdd4311683516be06944f4b85244063cdb886", - "reference": "8e4cdd4311683516be06944f4b85244063cdb886", + "url": "https://api.github.com/repos/symfony/yaml/zipball/efb42bd2c6f4f3ccfd4683583449938b5fc146b0", + "reference": "efb42bd2c6f4f3ccfd4683583449938b5fc146b0", "shasum": "" }, "require": { @@ -8486,7 +8477,7 @@ "description": "Loads and dumps YAML files", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/yaml/tree/v8.1.1" + "source": "https://github.com/symfony/yaml/tree/v8.1.0" }, "funding": [ { @@ -8506,7 +8497,7 @@ "type": "tidelift" } ], - "time": "2026-06-09T11:06:24+00:00" + "time": "2026-05-29T05:06:50+00:00" }, { "name": "theiconic/name-parser", @@ -8669,16 +8660,16 @@ }, { "name": "twig/twig", - "version": "v3.28.0", + "version": "v3.27.1", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "597c12ed286fb9d1701a36684ce6e0cbe28ebc8b" + "reference": "ae2071bffb38f04847fc0864d730c94b9cb8ab74" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/597c12ed286fb9d1701a36684ce6e0cbe28ebc8b", - "reference": "597c12ed286fb9d1701a36684ce6e0cbe28ebc8b", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/ae2071bffb38f04847fc0864d730c94b9cb8ab74", + "reference": "ae2071bffb38f04847fc0864d730c94b9cb8ab74", "shasum": "" }, "require": { @@ -8733,7 +8724,7 @@ ], "support": { "issues": "https://github.com/twigphp/Twig/issues", - "source": "https://github.com/twigphp/Twig/tree/v3.28.0" + "source": "https://github.com/twigphp/Twig/tree/v3.27.1" }, "funding": [ { @@ -8745,20 +8736,20 @@ "type": "tidelift" } ], - "time": "2026-07-03T20:44:34+00:00" + "time": "2026-05-30T17:09:26+00:00" }, { "name": "vlucas/phpdotenv", - "version": "v5.6.4", + "version": "v5.6.3", "source": { "type": "git", "url": "https://github.com/vlucas/phpdotenv.git", - "reference": "416df702837983f8d5ff48c9c3fee4f5f57b980b" + "reference": "955e7815d677a3eaa7075231212f2110983adecc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/416df702837983f8d5ff48c9c3fee4f5f57b980b", - "reference": "416df702837983f8d5ff48c9c3fee4f5f57b980b", + "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/955e7815d677a3eaa7075231212f2110983adecc", + "reference": "955e7815d677a3eaa7075231212f2110983adecc", "shasum": "" }, "require": { @@ -8817,7 +8808,7 @@ ], "support": { "issues": "https://github.com/vlucas/phpdotenv/issues", - "source": "https://github.com/vlucas/phpdotenv/tree/v5.6.4" + "source": "https://github.com/vlucas/phpdotenv/tree/v5.6.3" }, "funding": [ { @@ -8829,7 +8820,7 @@ "type": "tidelift" } ], - "time": "2026-07-06T19:11:50+00:00" + "time": "2025-12-27T19:49:13+00:00" }, { "name": "voku/portable-ascii", @@ -8978,16 +8969,16 @@ }, { "name": "web-auth/webauthn-lib", - "version": "5.3.5", + "version": "5.2.6", "source": { "type": "git", "url": "https://github.com/web-auth/webauthn-lib.git", - "reference": "9e0986d999f4102e24ac8a598d3a80d98b56c19f" + "reference": "0785f55f242c1cc026ec24a9c8653eac59fe3493" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/web-auth/webauthn-lib/zipball/9e0986d999f4102e24ac8a598d3a80d98b56c19f", - "reference": "9e0986d999f4102e24ac8a598d3a80d98b56c19f", + "url": "https://api.github.com/repos/web-auth/webauthn-lib/zipball/0785f55f242c1cc026ec24a9c8653eac59fe3493", + "reference": "0785f55f242c1cc026ec24a9c8653eac59fe3493", "shasum": "" }, "require": { @@ -8995,18 +8986,18 @@ "ext-openssl": "*", "paragonie/constant_time_encoding": "^2.6|^3.0", "php": ">=8.2", - "phpdocumentor/reflection-docblock": "^5.3|^6.0", + "phpdocumentor/reflection-docblock": "^5.3", "psr/clock": "^1.0", "psr/event-dispatcher": "^1.0", "psr/log": "^1.0|^2.0|^3.0", "spomky-labs/cbor-php": "^3.0", "spomky-labs/pki-framework": "^1.0", - "symfony/clock": "^6.4|^7.0|^8.0", + "symfony/clock": "^6.4|^7.0", "symfony/deprecation-contracts": "^3.2", - "symfony/property-access": "^6.4|^7.0|^8.0", - "symfony/property-info": "^6.4|^7.0|^8.0", - "symfony/serializer": "^6.4|^7.0|^8.0", - "symfony/uid": "^6.4|^7.0|^8.0", + "symfony/property-access": "^6.4|^7.0", + "symfony/property-info": "^6.4|^7.0", + "symfony/serializer": "^6.4|^7.0", + "symfony/uid": "^6.4|^7.0", "web-auth/cose-lib": "^4.2.3" }, "suggest": { @@ -9048,7 +9039,7 @@ "webauthn" ], "support": { - "source": "https://github.com/web-auth/webauthn-lib/tree/5.3.5" + "source": "https://github.com/web-auth/webauthn-lib/tree/5.2.6" }, "funding": [ { @@ -9060,20 +9051,20 @@ "type": "patreon" } ], - "time": "2026-05-31T15:00:08+00:00" + "time": "2026-03-23T22:13:50+00:00" }, { "name": "webmozart/assert", - "version": "2.4.1", + "version": "2.4.0", "source": { "type": "git", "url": "https://github.com/webmozarts/assert.git", - "reference": "2ccb7c2e821038c03a3e6e1700c570c158c55f70" + "reference": "9007ea6f45ecf352a9422b36644e4bfc039b9155" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/webmozarts/assert/zipball/2ccb7c2e821038c03a3e6e1700c570c158c55f70", - "reference": "2ccb7c2e821038c03a3e6e1700c570c158c55f70", + "url": "https://api.github.com/repos/webmozarts/assert/zipball/9007ea6f45ecf352a9422b36644e4bfc039b9155", + "reference": "9007ea6f45ecf352a9422b36644e4bfc039b9155", "shasum": "" }, "require": { @@ -9124,89 +9115,9 @@ ], "support": { "issues": "https://github.com/webmozarts/assert/issues", - "source": "https://github.com/webmozarts/assert/tree/2.4.1" - }, - "time": "2026-06-15T15:31:57+00:00" - }, - { - "name": "webonyx/graphql-php", - "version": "v15.33.1", - "source": { - "type": "git", - "url": "https://github.com/webonyx/graphql-php.git", - "reference": "e0f40ce40a527ee27413cceced4825aacbc7de5b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/webonyx/graphql-php/zipball/e0f40ce40a527ee27413cceced4825aacbc7de5b", - "reference": "e0f40ce40a527ee27413cceced4825aacbc7de5b", - "shasum": "" - }, - "require": { - "ext-json": "*", - "ext-mbstring": "*", - "php": "^7.4 || ^8" - }, - "require-dev": { - "amphp/amp": "^2.6 || ^3", - "amphp/http-server": "^2.1 || ^3", - "dms/phpunit-arraysubset-asserts": "dev-master", - "ergebnis/composer-normalize": "^2.28", - "friendsofphp/php-cs-fixer": "3.95.8", - "mll-lab/php-cs-fixer-config": "5.13.0", - "nyholm/psr7": "^1.5", - "phpbench/phpbench": "^1.2", - "phpstan/extension-installer": "^1.1", - "phpstan/phpstan": "2.2.2", - "phpstan/phpstan-phpunit": "2.0.16", - "phpstan/phpstan-strict-rules": "2.0.11", - "phpunit/phpunit": "^9.5 || ^10.5.21 || ^11", - "psr/http-message": "^1 || ^2", - "react/http": "^1.6", - "react/promise": "^2.0 || ^3.0", - "rector/rector": "^2.0", - "symfony/polyfill-php81": "^1.23", - "symfony/var-exporter": "^5 || ^6 || ^7 || ^8", - "thecodingmachine/safe": "^1.3 || ^2 || ^3", - "ticketswap/phpstan-error-formatter": "1.3.0" - }, - "suggest": { - "amphp/amp": "To leverage async resolving on AMPHP platform (v3 with AmpFutureAdapter, v2 with AmpPromiseAdapter)", - "amphp/http-server": "To leverage async resolving with webserver on AMPHP platform", - "psr/http-message": "To use standard GraphQL server", - "react/promise": "To leverage async resolving on React PHP platform" - }, - "type": "library", - "autoload": { - "psr-4": { - "GraphQL\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "A PHP port of GraphQL reference implementation", - "homepage": "https://github.com/webonyx/graphql-php", - "keywords": [ - "api", - "graphql" - ], - "support": { - "issues": "https://github.com/webonyx/graphql-php/issues", - "source": "https://github.com/webonyx/graphql-php/tree/v15.33.1" + "source": "https://github.com/webmozarts/assert/tree/2.4.0" }, - "funding": [ - { - "url": "https://github.com/spawnia", - "type": "github" - }, - { - "url": "https://opencollective.com/webonyx-graphql-php", - "type": "open_collective" - } - ], - "time": "2026-06-17T06:05:59+00:00" + "time": "2026-05-20T13:07:01+00:00" }, { "name": "yiisoft/aliases", @@ -9947,16 +9858,16 @@ }, { "name": "brianium/paratest", - "version": "v7.23.0", + "version": "v7.20.0", "source": { "type": "git", "url": "https://github.com/paratestphp/paratest.git", - "reference": "6a3adf37c2726fefb66e03cc93bb0e8f75d92134" + "reference": "81c80677c9ec0ed4ef16b246167f11dec81a6e3d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/paratestphp/paratest/zipball/6a3adf37c2726fefb66e03cc93bb0e8f75d92134", - "reference": "6a3adf37c2726fefb66e03cc93bb0e8f75d92134", + "url": "https://api.github.com/repos/paratestphp/paratest/zipball/81c80677c9ec0ed4ef16b246167f11dec81a6e3d", + "reference": "81c80677c9ec0ed4ef16b246167f11dec81a6e3d", "shasum": "" }, "require": { @@ -9966,25 +9877,25 @@ "ext-simplexml": "*", "fidry/cpu-core-counter": "^1.3.0", "jean85/pretty-package-versions": "^2.1.1", - "php": "~8.4.0 || ~8.5.0", - "phpunit/php-code-coverage": "^14.2.0", - "phpunit/php-file-iterator": "^7", - "phpunit/php-timer": "^9", - "phpunit/phpunit": "^13.2.0", - "sebastian/environment": "^9.3.2", - "symfony/console": "^7.4.8 || ^8.1.0", - "symfony/process": "^7.4.8 || ^8.1.0" + "php": "~8.3.0 || ~8.4.0 || ~8.5.0", + "phpunit/php-code-coverage": "^12.5.3 || ^13.0.1", + "phpunit/php-file-iterator": "^6.0.1 || ^7", + "phpunit/php-timer": "^8 || ^9", + "phpunit/phpunit": "^12.5.14 || ^13.0.5", + "sebastian/environment": "^8.0.3 || ^9", + "symfony/console": "^7.4.7 || ^8.0.7", + "symfony/process": "^7.4.5 || ^8.0.5" }, "require-dev": { "doctrine/coding-standard": "^14.0.0", "ext-pcntl": "*", "ext-pcov": "*", "ext-posix": "*", - "phpstan/phpstan": "^2.2.2", + "phpstan/phpstan": "^2.1.44", "phpstan/phpstan-deprecation-rules": "^2.0.4", "phpstan/phpstan-phpunit": "^2.0.16", - "phpstan/phpstan-strict-rules": "^2.0.11", - "symfony/filesystem": "^7.4.8 || ^8.1.0" + "phpstan/phpstan-strict-rules": "^2.0.10", + "symfony/filesystem": "^7.4.6 || ^8.0.6" }, "bin": [ "bin/paratest", @@ -10024,7 +9935,7 @@ ], "support": { "issues": "https://github.com/paratestphp/paratest/issues", - "source": "https://github.com/paratestphp/paratest/tree/v7.23.0" + "source": "https://github.com/paratestphp/paratest/tree/v7.20.0" }, "funding": [ { @@ -10036,7 +9947,73 @@ "type": "paypal" } ], - "time": "2026-06-05T10:56:52+00:00" + "time": "2026-03-29T15:46:14+00:00" + }, + { + "name": "composer/xdebug-handler", + "version": "3.0.5", + "source": { + "type": "git", + "url": "https://github.com/composer/xdebug-handler.git", + "reference": "6c1925561632e83d60a44492e0b344cf48ab85ef" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/6c1925561632e83d60a44492e0b344cf48ab85ef", + "reference": "6c1925561632e83d60a44492e0b344cf48ab85ef", + "shasum": "" + }, + "require": { + "composer/pcre": "^1 || ^2 || ^3", + "php": "^7.2.5 || ^8.0", + "psr/log": "^1 || ^2 || ^3" + }, + "require-dev": { + "phpstan/phpstan": "^1.0", + "phpstan/phpstan-strict-rules": "^1.1", + "phpunit/phpunit": "^8.5 || ^9.6 || ^10.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Composer\\XdebugHandler\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "John Stevenson", + "email": "john-stevenson@blueyonder.co.uk" + } + ], + "description": "Restarts a process without Xdebug.", + "keywords": [ + "Xdebug", + "performance" + ], + "support": { + "irc": "ircs://irc.libera.chat:6697/composer", + "issues": "https://github.com/composer/xdebug-handler/issues", + "source": "https://github.com/composer/xdebug-handler/tree/3.0.5" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2024-05-06T16:37:16+00:00" }, { "name": "dg/bypass-finals", @@ -10479,165 +10456,30 @@ "time": "2026-01-28T22:20:33+00:00" }, { - "name": "intervention/image-driver-vips", - "version": "4.1.0", + "name": "jean85/pretty-package-versions", + "version": "2.1.1", "source": { "type": "git", - "url": "https://github.com/Intervention/image-driver-vips.git", - "reference": "93ac16415dc7020edc9707926d08310be71d902b" + "url": "https://github.com/Jean85/pretty-package-versions.git", + "reference": "4d7aa5dab42e2a76d99559706022885de0e18e1a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Intervention/image-driver-vips/zipball/93ac16415dc7020edc9707926d08310be71d902b", - "reference": "93ac16415dc7020edc9707926d08310be71d902b", + "url": "https://api.github.com/repos/Jean85/pretty-package-versions/zipball/4d7aa5dab42e2a76d99559706022885de0e18e1a", + "reference": "4d7aa5dab42e2a76d99559706022885de0e18e1a", "shasum": "" }, "require": { - "intervention/image": "^4.2", - "jcupitt/vips": "^2.6", - "php": "^8.3" + "composer-runtime-api": "^2.1.0", + "php": "^7.4|^8.0" }, "require-dev": { - "ext-fileinfo": "*", - "phpstan/phpstan": "^2", - "phpunit/phpunit": "^12.0", - "slevomat/coding-standard": "~8.0", - "squizlabs/php_codesniffer": "^4" - }, - "type": "library", - "autoload": { - "psr-4": { - "Intervention\\Image\\Drivers\\Vips\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Oliver Vogel", - "email": "oliver@intervention.io", - "homepage": "https://intervention.io/" - }, - { - "name": "Thomas Picquet", - "email": "thomas@sctr.net" - } - ], - "description": "libvips driver for Intervention Image", - "homepage": "https://image.intervention.io/", - "keywords": [ - "image", - "libvips", - "vips" - ], - "support": { - "issues": "https://github.com/Intervention/image-driver-vips/issues", - "source": "https://github.com/Intervention/image-driver-vips/tree/4.1.0" - }, - "funding": [ - { - "url": "https://paypal.me/interventionio", - "type": "custom" - }, - { - "url": "https://github.com/Intervention", - "type": "github" - }, - { - "url": "https://ko-fi.com/interventionphp", - "type": "ko_fi" - } - ], - "time": "2026-07-11T07:34:41+00:00" - }, - { - "name": "jcupitt/vips", - "version": "v2.6.1", - "source": { - "type": "git", - "url": "https://github.com/libvips/php-vips.git", - "reference": "6dbba1bb3a4ba1e39edb71016a2aa6da5bff32ee" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/libvips/php-vips/zipball/6dbba1bb3a4ba1e39edb71016a2aa6da5bff32ee", - "reference": "6dbba1bb3a4ba1e39edb71016a2aa6da5bff32ee", - "shasum": "" - }, - "require": { - "ext-ffi": "*", - "php": ">=7.4", - "psr/log": "^1.1.3|^2.0|^3.0" - }, - "require-dev": { - "php-parallel-lint/php-parallel-lint": "^1.3", - "phpdocumentor/shim": "^3.3", - "phpunit/phpunit": "^9.5", - "squizlabs/php_codesniffer": "^3.7" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Jcupitt\\Vips\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "John Cupitt", - "email": "jcupitt@gmail.com", - "homepage": "https://github.com/jcupitt", - "role": "Developer" - } - ], - "description": "A high-level interface to the libvips image processing library.", - "homepage": "https://github.com/libvips/php-vips", - "keywords": [ - "image", - "libvips", - "processing" - ], - "support": { - "issues": "https://github.com/libvips/php-vips/issues", - "source": "https://github.com/libvips/php-vips/tree/v2.6.1" - }, - "time": "2025-12-10T14:03:20+00:00" - }, - { - "name": "jean85/pretty-package-versions", - "version": "2.1.1", - "source": { - "type": "git", - "url": "https://github.com/Jean85/pretty-package-versions.git", - "reference": "4d7aa5dab42e2a76d99559706022885de0e18e1a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Jean85/pretty-package-versions/zipball/4d7aa5dab42e2a76d99559706022885de0e18e1a", - "reference": "4d7aa5dab42e2a76d99559706022885de0e18e1a", - "shasum": "" - }, - "require": { - "composer-runtime-api": "^2.1.0", - "php": "^7.4|^8.0" - }, - "require-dev": { - "friendsofphp/php-cs-fixer": "^3.2", - "jean85/composer-provided-replaced-stub-package": "^1.0", - "phpstan/phpstan": "^2.0", - "phpunit/phpunit": "^7.5|^8.5|^9.6", - "rector/rector": "^2.0", - "vimeo/psalm": "^4.3 || ^5.0" + "friendsofphp/php-cs-fixer": "^3.2", + "jean85/composer-provided-replaced-stub-package": "^1.0", + "phpstan/phpstan": "^2.0", + "phpunit/phpunit": "^7.5|^8.5|^9.6", + "rector/rector": "^2.0", + "vimeo/psalm": "^4.3 || ^5.0" }, "type": "library", "extra": { @@ -11464,19 +11306,20 @@ }, { "name": "nikic/php-parser", - "version": "v5.8.0", + "version": "v5.7.0", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "044a6a392ff8ad0d61f14370a5fbbd0a0107152f" + "reference": "dca41cd15c2ac9d055ad70dbfd011130757d1f82" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/044a6a392ff8ad0d61f14370a5fbbd0a0107152f", - "reference": "044a6a392ff8ad0d61f14370a5fbbd0a0107152f", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/dca41cd15c2ac9d055ad70dbfd011130757d1f82", + "reference": "dca41cd15c2ac9d055ad70dbfd011130757d1f82", "shasum": "" }, "require": { + "ext-ctype": "*", "ext-json": "*", "ext-tokenizer": "*", "php": ">=7.4" @@ -11515,29 +11358,29 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v5.8.0" + "source": "https://github.com/nikic/PHP-Parser/tree/v5.7.0" }, - "time": "2026-07-04T14:30:18+00:00" + "time": "2025-12-06T11:56:16+00:00" }, { "name": "nunomaduro/collision", - "version": "v8.9.5", + "version": "v8.9.4", "source": { "type": "git", "url": "https://github.com/nunomaduro/collision.git", - "reference": "fb53eacd509a1d303858e2d20cfebf2d630254ec" + "reference": "716af8f95a470e9094cfca09ed897b023be191a5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nunomaduro/collision/zipball/fb53eacd509a1d303858e2d20cfebf2d630254ec", - "reference": "fb53eacd509a1d303858e2d20cfebf2d630254ec", + "url": "https://api.github.com/repos/nunomaduro/collision/zipball/716af8f95a470e9094cfca09ed897b023be191a5", + "reference": "716af8f95a470e9094cfca09ed897b023be191a5", "shasum": "" }, "require": { "filp/whoops": "^2.18.4", "nunomaduro/termwind": "^2.4.0", "php": "^8.2.0", - "symfony/console": "^7.4.14 || ^8.1.1" + "symfony/console": "^7.4.8 || ^8.0.8" }, "conflict": { "laravel/framework": "<11.48.0 || >=14.0.0", @@ -11545,12 +11388,12 @@ }, "require-dev": { "brianium/paratest": "^7.8.5", - "larastan/larastan": "^3.10.0", - "laravel/framework": "^11.48.0 || ^12.56.0 || ^13.20.0", - "laravel/pint": "^1.29.3", - "orchestra/testbench-core": "^9.12.0 || ^10.12.1 || ^11.3.5", - "pestphp/pest": "^3.8.5 || ^4.7.5 || ^5.0.0", - "sebastian/environment": "^7.2.1 || ^8.1.2 || ^9.3.2" + "larastan/larastan": "^3.9.6", + "laravel/framework": "^11.48.0 || ^12.56.0 || ^13.5.0", + "laravel/pint": "^1.29.1", + "orchestra/testbench-core": "^9.12.0 || ^10.12.1 || ^11.2.1", + "pestphp/pest": "^3.8.5 || ^4.4.3 || ^5.0.0", + "sebastian/environment": "^7.2.1 || ^8.0.4 || ^9.3.0" }, "type": "library", "extra": { @@ -11613,7 +11456,7 @@ "type": "patreon" } ], - "time": "2026-07-15T19:09:14+00:00" + "time": "2026-04-21T14:04:20+00:00" }, { "name": "orchestra/canvas", @@ -11867,16 +11710,16 @@ }, { "name": "orchestra/testbench-core", - "version": "v11.3.5", + "version": "v11.3.3", "source": { "type": "git", "url": "https://github.com/orchestral/testbench-core.git", - "reference": "a6773cd554177edb800f1e610d128b5acf813783" + "reference": "8b85d7754a08b4ff88fc65ab86edf81d70fd1e26" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/orchestral/testbench-core/zipball/a6773cd554177edb800f1e610d128b5acf813783", - "reference": "a6773cd554177edb800f1e610d128b5acf813783", + "url": "https://api.github.com/repos/orchestral/testbench-core/zipball/8b85d7754a08b4ff88fc65ab86edf81d70fd1e26", + "reference": "8b85d7754a08b4ff88fc65ab86edf81d70fd1e26", "shasum": "" }, "require": { @@ -11888,14 +11731,14 @@ }, "conflict": { "brianium/paratest": "<7.3.0|>=8.0.0", - "laravel/framework": "<13.10.0|>=14.0.0", + "laravel/framework": "<13.9.0|>=14.0.0", "laravel/serializable-closure": ">=2.0.0 <2.0.10|>=3.0.0", "nunomaduro/collision": "<8.9.0|>=9.0.0", - "phpunit/phpunit": "<11.5.50|>=12.0.0 <12.5.8|>=13.3.0" + "phpunit/phpunit": "<11.5.50|>=12.0.0 <12.5.8|>=13.2.0" }, "require-dev": { "fakerphp/faker": "^1.24", - "laravel/framework": "^13.10.0", + "laravel/framework": "^13.9.0", "laravel/pint": "^1.24", "laravel/serializable-closure": "^2.0.10", "mockery/mockery": "^1.6.10", @@ -11956,20 +11799,20 @@ "issues": "https://github.com/orchestral/testbench/issues", "source": "https://github.com/orchestral/testbench-core" }, - "time": "2026-06-23T11:50:08+00:00" + "time": "2026-05-14T11:22:09+00:00" }, { "name": "orchestra/workbench", - "version": "v11.2.0", + "version": "v11.1.0", "source": { "type": "git", "url": "https://github.com/orchestral/workbench.git", - "reference": "78f27959b8e5caa72c996c6ccd0ddfeff462cb2b" + "reference": "e750c7bcae4405e054ff286475502e23274de04b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/orchestral/workbench/zipball/78f27959b8e5caa72c996c6ccd0ddfeff462cb2b", - "reference": "78f27959b8e5caa72c996c6ccd0ddfeff462cb2b", + "url": "https://api.github.com/repos/orchestral/workbench/zipball/e750c7bcae4405e054ff286475502e23274de04b", + "reference": "e750c7bcae4405e054ff286475502e23274de04b", "shasum": "" }, "require": { @@ -12021,9 +11864,9 @@ ], "support": { "issues": "https://github.com/orchestral/workbench/issues", - "source": "https://github.com/orchestral/workbench/tree/v11.2.0" + "source": "https://github.com/orchestral/workbench/tree/v11.1.0" }, - "time": "2026-07-22T09:55:13+00:00" + "time": "2026-03-24T23:09:55+00:00" }, { "name": "paragonie/random_compat", @@ -12077,44 +11920,43 @@ }, { "name": "pestphp/pest", - "version": "v5.0.1", + "version": "v4.7.2", "source": { "type": "git", "url": "https://github.com/pestphp/pest.git", - "reference": "6b2cd358e8a9d6d1abb93804b70e1c659bbc411b" + "reference": "40b88b62ef8a7c6fcae5fc28f1fa747f601c131b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pestphp/pest/zipball/6b2cd358e8a9d6d1abb93804b70e1c659bbc411b", - "reference": "6b2cd358e8a9d6d1abb93804b70e1c659bbc411b", + "url": "https://api.github.com/repos/pestphp/pest/zipball/40b88b62ef8a7c6fcae5fc28f1fa747f601c131b", + "reference": "40b88b62ef8a7c6fcae5fc28f1fa747f601c131b", "shasum": "" }, "require": { - "brianium/paratest": "^7.23.0", - "nunomaduro/collision": "^8.9.5", + "brianium/paratest": "^7.20.0", + "composer/xdebug-handler": "^3.0.5", + "nunomaduro/collision": "^8.9.4", "nunomaduro/termwind": "^2.4.0", - "pestphp/pest-plugin": "^5.0.0", - "pestphp/pest-plugin-arch": "^5.0.0", - "pestphp/pest-plugin-mutate": "^5.0.0", - "pestphp/pest-plugin-profanity": "^5.0.0", - "php": "^8.4", - "phpunit/phpunit": "^13.2.4", - "symfony/process": "^8.1.0" + "pestphp/pest-plugin": "^4.0.0", + "pestphp/pest-plugin-arch": "^4.0.2", + "pestphp/pest-plugin-mutate": "^4.0.1", + "pestphp/pest-plugin-profanity": "^4.2.1", + "php": "^8.3.0", + "phpunit/phpunit": "^12.5.28", + "symfony/process": "^7.4.13|^8.1.0" }, "conflict": { "filp/whoops": "<2.18.3", - "phpunit/phpunit": ">13.2.4", + "phpunit/phpunit": ">12.5.28", "sebastian/exporter": "<7.0.0", "webmozart/assert": "<1.11.0" }, "require-dev": { - "laravel/pao": "^1.1.2", - "pestphp/pest-dev-tools": "^5.0.0", - "pestphp/pest-plugin-browser": "^5.0.0", - "pestphp/pest-plugin-phpstan": "^5.0.0", - "pestphp/pest-plugin-rector": "^5.0.0", - "pestphp/pest-plugin-type-coverage": "^5.0.0", - "psy/psysh": "^0.12.24" + "mrpunyapal/peststan": "^0.2.10", + "pestphp/pest-dev-tools": "^4.1.0", + "pestphp/pest-plugin-browser": "^4.3.1", + "pestphp/pest-plugin-type-coverage": "^4.0.4", + "psy/psysh": "^0.12.23" }, "bin": [ "bin/pest" @@ -12181,7 +12023,7 @@ ], "support": { "issues": "https://github.com/pestphp/pest/issues", - "source": "https://github.com/pestphp/pest/tree/v5.0.1" + "source": "https://github.com/pestphp/pest/tree/v4.7.2" }, "funding": [ { @@ -12193,34 +12035,34 @@ "type": "github" } ], - "time": "2026-07-28T17:28:46+00:00" + "time": "2026-06-01T06:08:59+00:00" }, { "name": "pestphp/pest-plugin", - "version": "v5.0.0", + "version": "v4.0.0", "source": { "type": "git", "url": "https://github.com/pestphp/pest-plugin.git", - "reference": "87283f41aafa2561b7618be53eab00f2d06f4140" + "reference": "9d4b93d7f73d3f9c3189bb22c220fef271cdf568" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pestphp/pest-plugin/zipball/87283f41aafa2561b7618be53eab00f2d06f4140", - "reference": "87283f41aafa2561b7618be53eab00f2d06f4140", + "url": "https://api.github.com/repos/pestphp/pest-plugin/zipball/9d4b93d7f73d3f9c3189bb22c220fef271cdf568", + "reference": "9d4b93d7f73d3f9c3189bb22c220fef271cdf568", "shasum": "" }, "require": { "composer-plugin-api": "^2.0.0", "composer-runtime-api": "^2.2.2", - "php": "^8.4" + "php": "^8.3" }, "conflict": { - "pestphp/pest": "<5.0.0" + "pestphp/pest": "<4.0.0" }, "require-dev": { - "composer/composer": "^2.10.2", - "pestphp/pest": "^5.0.0", - "pestphp/pest-dev-tools": "^5.0.0" + "composer/composer": "^2.8.10", + "pestphp/pest": "^4.0.0", + "pestphp/pest-dev-tools": "^4.0.0" }, "type": "composer-plugin", "extra": { @@ -12247,7 +12089,7 @@ "unit" ], "support": { - "source": "https://github.com/pestphp/pest-plugin/tree/v5.0.0" + "source": "https://github.com/pestphp/pest-plugin/tree/v4.0.0" }, "funding": [ { @@ -12263,33 +12105,30 @@ "type": "patreon" } ], - "time": "2026-07-18T17:10:45+00:00" + "time": "2025-08-20T12:35:58+00:00" }, { "name": "pestphp/pest-plugin-arch", - "version": "v5.0.0", + "version": "v4.0.2", "source": { "type": "git", "url": "https://github.com/pestphp/pest-plugin-arch.git", - "reference": "244465d5dc9ea9fb5ac5c9badb7eb47d1594e4c1" + "reference": "3fb0d02a91b9da504b139dc7ab2a31efb7c3215c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pestphp/pest-plugin-arch/zipball/244465d5dc9ea9fb5ac5c9badb7eb47d1594e4c1", - "reference": "244465d5dc9ea9fb5ac5c9badb7eb47d1594e4c1", + "url": "https://api.github.com/repos/pestphp/pest-plugin-arch/zipball/3fb0d02a91b9da504b139dc7ab2a31efb7c3215c", + "reference": "3fb0d02a91b9da504b139dc7ab2a31efb7c3215c", "shasum": "" }, "require": { - "pestphp/pest-plugin": "^5.0.0", - "php": "^8.4", + "pestphp/pest-plugin": "^4.0.0", + "php": "^8.3", "ta-tikoma/phpunit-architecture-test": "^0.8.7" }, - "conflict": { - "pestphp/pest": "<5.0.0" - }, "require-dev": { - "pestphp/pest": "^5.0.0", - "pestphp/pest-dev-tools": "^5.0.0" + "pestphp/pest": "^4.4.6", + "pestphp/pest-dev-tools": "^4.1.0" }, "type": "library", "extra": { @@ -12324,7 +12163,7 @@ "unit" ], "support": { - "source": "https://github.com/pestphp/pest-plugin-arch/tree/v5.0.0" + "source": "https://github.com/pestphp/pest-plugin-arch/tree/v4.0.2" }, "funding": [ { @@ -12336,34 +12175,31 @@ "type": "github" } ], - "time": "2026-07-21T07:48:55+00:00" + "time": "2026-04-10T17:20:19+00:00" }, { "name": "pestphp/pest-plugin-laravel", - "version": "v5.0.0", + "version": "v4.1.0", "source": { "type": "git", "url": "https://github.com/pestphp/pest-plugin-laravel.git", - "reference": "37a988d2c880c3dcf631a41250e84f6a7b2b9307" + "reference": "3057a36669ff11416cc0dc2b521b3aec58c488d0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pestphp/pest-plugin-laravel/zipball/37a988d2c880c3dcf631a41250e84f6a7b2b9307", - "reference": "37a988d2c880c3dcf631a41250e84f6a7b2b9307", + "url": "https://api.github.com/repos/pestphp/pest-plugin-laravel/zipball/3057a36669ff11416cc0dc2b521b3aec58c488d0", + "reference": "3057a36669ff11416cc0dc2b521b3aec58c488d0", "shasum": "" }, "require": { - "laravel/framework": "^11.45.2|^12.25.0|^13.20.0", - "pestphp/pest": "^5.0.0", - "php": "^8.4" - }, - "conflict": { - "pestphp/pest": "<5.0.0" + "laravel/framework": "^11.45.2|^12.52.0|^13.0", + "pestphp/pest": "^4.4.1", + "php": "^8.3.0" }, "require-dev": { - "laravel/dusk": "^8.6.0", - "orchestra/testbench": "^9.13.0|^10.5.0|^11.1", - "pestphp/pest-dev-tools": "^5.0.0" + "laravel/dusk": "^8.3.6", + "orchestra/testbench": "^9.13.0|^10.9.0|^11.0", + "pestphp/pest-dev-tools": "^4.1.0" }, "type": "library", "extra": { @@ -12401,7 +12237,7 @@ "unit" ], "support": { - "source": "https://github.com/pestphp/pest-plugin-laravel/tree/v5.0.0" + "source": "https://github.com/pestphp/pest-plugin-laravel/tree/v4.1.0" }, "funding": [ { @@ -12413,35 +12249,32 @@ "type": "github" } ], - "time": "2026-07-21T07:48:56+00:00" + "time": "2026-02-21T00:29:45+00:00" }, { "name": "pestphp/pest-plugin-mutate", - "version": "v5.0.0", + "version": "v4.0.1", "source": { "type": "git", "url": "https://github.com/pestphp/pest-plugin-mutate.git", - "reference": "fc4a0b3d3bc75bad1148d4c046cf0fa66c508f77" + "reference": "d9b32b60b2385e1688a68cc227594738ec26d96c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pestphp/pest-plugin-mutate/zipball/fc4a0b3d3bc75bad1148d4c046cf0fa66c508f77", - "reference": "fc4a0b3d3bc75bad1148d4c046cf0fa66c508f77", + "url": "https://api.github.com/repos/pestphp/pest-plugin-mutate/zipball/d9b32b60b2385e1688a68cc227594738ec26d96c", + "reference": "d9b32b60b2385e1688a68cc227594738ec26d96c", "shasum": "" }, "require": { - "nikic/php-parser": "^5.8.0", - "pestphp/pest-plugin": "^5.0.0", - "php": "^8.4", + "nikic/php-parser": "^5.6.1", + "pestphp/pest-plugin": "^4.0.0", + "php": "^8.3", "psr/simple-cache": "^3.0.0" }, - "conflict": { - "pestphp/pest": "<5.0.0" - }, "require-dev": { - "pestphp/pest": "^5.0.0", - "pestphp/pest-dev-tools": "^5.0.0", - "pestphp/pest-plugin-type-coverage": "^5.0.0" + "pestphp/pest": "^4.0.0", + "pestphp/pest-dev-tools": "^4.0.0", + "pestphp/pest-plugin-type-coverage": "^4.0.0" }, "type": "library", "autoload": { @@ -12476,7 +12309,7 @@ "unit" ], "support": { - "source": "https://github.com/pestphp/pest-plugin-mutate/tree/v5.0.0" + "source": "https://github.com/pestphp/pest-plugin-mutate/tree/v4.0.1" }, "funding": [ { @@ -12492,33 +12325,30 @@ "type": "github" } ], - "time": "2026-07-21T07:48:56+00:00" + "time": "2025-08-21T20:19:25+00:00" }, { "name": "pestphp/pest-plugin-profanity", - "version": "v5.0.0", + "version": "v4.2.1", "source": { "type": "git", "url": "https://github.com/pestphp/pest-plugin-profanity.git", - "reference": "3dedf9ea6e2876b5b31f7733d3eacbd86f4653b9" + "reference": "343cfa6f3564b7e35df0ebb77b7fa97039f72b27" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pestphp/pest-plugin-profanity/zipball/3dedf9ea6e2876b5b31f7733d3eacbd86f4653b9", - "reference": "3dedf9ea6e2876b5b31f7733d3eacbd86f4653b9", + "url": "https://api.github.com/repos/pestphp/pest-plugin-profanity/zipball/343cfa6f3564b7e35df0ebb77b7fa97039f72b27", + "reference": "343cfa6f3564b7e35df0ebb77b7fa97039f72b27", "shasum": "" }, "require": { - "pestphp/pest-plugin": "^5.0.0", - "php": "^8.4" - }, - "conflict": { - "pestphp/pest": "<5.0.0" + "pestphp/pest-plugin": "^4.0.0", + "php": "^8.3" }, "require-dev": { - "faissaloux/pest-plugin-inside": "^1.11", - "pestphp/pest": "^5.0.0", - "pestphp/pest-dev-tools": "^5.0.0" + "faissaloux/pest-plugin-inside": "^1.9", + "pestphp/pest": "^4.0.0", + "pestphp/pest-dev-tools": "^4.0.0" }, "type": "library", "extra": { @@ -12549,9 +12379,9 @@ "unit" ], "support": { - "source": "https://github.com/pestphp/pest-plugin-profanity/tree/v5.0.0" + "source": "https://github.com/pestphp/pest-plugin-profanity/tree/v4.2.1" }, - "time": "2026-07-21T07:48:56+00:00" + "time": "2025-12-08T00:13:17+00:00" }, { "name": "phar-io/manifest", @@ -12951,11 +12781,11 @@ }, { "name": "phpstan/phpstan", - "version": "2.2.5", + "version": "2.2.1", "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/909c1e5fef7989ac0d0c1c5c42e32a5c4f6198a0", - "reference": "909c1e5fef7989ac0d0c1c5c42e32a5c4f6198a0", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/dea9c8f2d25cc849391042b71e429c1a4bf82660", + "reference": "dea9c8f2d25cc849391042b71e429c1a4bf82660", "shasum": "" }, "require": { @@ -13011,39 +12841,37 @@ "type": "github" } ], - "time": "2026-07-05T06:31:06+00:00" + "time": "2026-05-28T14:44:12+00:00" }, { "name": "phpunit/php-code-coverage", - "version": "14.2.3", + "version": "12.5.7", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "82f6e49ff224e2cde923d74425e583a883910783" + "reference": "186dab580576598076de6818596d12b61801880e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/82f6e49ff224e2cde923d74425e583a883910783", - "reference": "82f6e49ff224e2cde923d74425e583a883910783", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/186dab580576598076de6818596d12b61801880e", + "reference": "186dab580576598076de6818596d12b61801880e", "shasum": "" }, "require": { "ext-dom": "*", "ext-libxml": "*", - "ext-mbstring": "*", "ext-xmlwriter": "*", - "nikic/php-parser": "^5.8.0", - "php": ">=8.4", - "phpunit/php-text-template": "^6.0", - "sebastian/complexity": "^6.0", - "sebastian/environment": "^9.3.2", - "sebastian/git-state": "^1.0", - "sebastian/lines-of-code": "^5.0.1", - "sebastian/version": "^7.0", + "nikic/php-parser": "^5.7.0", + "php": ">=8.3", + "phpunit/php-text-template": "^5.0", + "sebastian/complexity": "^5.0", + "sebastian/environment": "^8.1.2", + "sebastian/lines-of-code": "^4.0.1", + "sebastian/version": "^6.0", "theseer/tokenizer": "^2.0.1" }, "require-dev": { - "phpunit/phpunit": "^13.2.2" + "phpunit/phpunit": "^12.5.28" }, "suggest": { "ext-pcov": "PHP extension that provides line coverage", @@ -13052,7 +12880,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "14.2.x-dev" + "dev-main": "12.5.x-dev" } }, "autoload": { @@ -13081,7 +12909,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/14.2.3" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/12.5.7" }, "funding": [ { @@ -13101,32 +12929,32 @@ "type": "tidelift" } ], - "time": "2026-07-06T15:04:02+00:00" + "time": "2026-06-01T13:24:19+00:00" }, { "name": "phpunit/php-file-iterator", - "version": "7.0.0", + "version": "6.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "6e5aa1fb0a95b1703d83e721299ee18bb4e2de50" + "reference": "3d1cd096ef6bea4bf2762ba586e35dbd317cbfd5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/6e5aa1fb0a95b1703d83e721299ee18bb4e2de50", - "reference": "6e5aa1fb0a95b1703d83e721299ee18bb4e2de50", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/3d1cd096ef6bea4bf2762ba586e35dbd317cbfd5", + "reference": "3d1cd096ef6bea4bf2762ba586e35dbd317cbfd5", "shasum": "" }, "require": { - "php": ">=8.4" + "php": ">=8.3" }, "require-dev": { - "phpunit/phpunit": "^13.0" + "phpunit/phpunit": "^12.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "7.0-dev" + "dev-main": "6.0-dev" } }, "autoload": { @@ -13154,7 +12982,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", "security": "https://github.com/sebastianbergmann/php-file-iterator/security/policy", - "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/7.0.0" + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/6.0.1" }, "funding": [ { @@ -13174,28 +13002,28 @@ "type": "tidelift" } ], - "time": "2026-02-06T04:33:26+00:00" + "time": "2026-02-02T14:04:18+00:00" }, { "name": "phpunit/php-invoker", - "version": "7.0.0", + "version": "6.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-invoker.git", - "reference": "42e5c5cae0c65df12d1b1a3ab52bf3f50f244d88" + "reference": "12b54e689b07a25a9b41e57736dfab6ec9ae5406" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/42e5c5cae0c65df12d1b1a3ab52bf3f50f244d88", - "reference": "42e5c5cae0c65df12d1b1a3ab52bf3f50f244d88", + "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/12b54e689b07a25a9b41e57736dfab6ec9ae5406", + "reference": "12b54e689b07a25a9b41e57736dfab6ec9ae5406", "shasum": "" }, "require": { - "php": ">=8.4" + "php": ">=8.3" }, "require-dev": { "ext-pcntl": "*", - "phpunit/phpunit": "^13.0" + "phpunit/phpunit": "^12.0" }, "suggest": { "ext-pcntl": "*" @@ -13203,7 +13031,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "7.0-dev" + "dev-main": "6.0-dev" } }, "autoload": { @@ -13230,52 +13058,40 @@ "support": { "issues": "https://github.com/sebastianbergmann/php-invoker/issues", "security": "https://github.com/sebastianbergmann/php-invoker/security/policy", - "source": "https://github.com/sebastianbergmann/php-invoker/tree/7.0.0" + "source": "https://github.com/sebastianbergmann/php-invoker/tree/6.0.0" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" - }, - { - "url": "https://liberapay.com/sebastianbergmann", - "type": "liberapay" - }, - { - "url": "https://thanks.dev/u/gh/sebastianbergmann", - "type": "thanks_dev" - }, - { - "url": "https://tidelift.com/funding/github/packagist/phpunit/php-invoker", - "type": "tidelift" } ], - "time": "2026-02-06T04:34:47+00:00" + "time": "2025-02-07T04:58:58+00:00" }, { "name": "phpunit/php-text-template", - "version": "6.0.0", + "version": "5.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "a47af19f93f76aa3368303d752aa5272ca3299f4" + "reference": "e1367a453f0eda562eedb4f659e13aa900d66c53" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/a47af19f93f76aa3368303d752aa5272ca3299f4", - "reference": "a47af19f93f76aa3368303d752aa5272ca3299f4", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/e1367a453f0eda562eedb4f659e13aa900d66c53", + "reference": "e1367a453f0eda562eedb4f659e13aa900d66c53", "shasum": "" }, "require": { - "php": ">=8.4" + "php": ">=8.3" }, "require-dev": { - "phpunit/phpunit": "^13.0" + "phpunit/phpunit": "^12.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "6.0-dev" + "dev-main": "5.0-dev" } }, "autoload": { @@ -13302,52 +13118,40 @@ "support": { "issues": "https://github.com/sebastianbergmann/php-text-template/issues", "security": "https://github.com/sebastianbergmann/php-text-template/security/policy", - "source": "https://github.com/sebastianbergmann/php-text-template/tree/6.0.0" + "source": "https://github.com/sebastianbergmann/php-text-template/tree/5.0.0" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" - }, - { - "url": "https://liberapay.com/sebastianbergmann", - "type": "liberapay" - }, - { - "url": "https://thanks.dev/u/gh/sebastianbergmann", - "type": "thanks_dev" - }, - { - "url": "https://tidelift.com/funding/github/packagist/phpunit/php-text-template", - "type": "tidelift" } ], - "time": "2026-02-06T04:36:37+00:00" + "time": "2025-02-07T04:59:16+00:00" }, { "name": "phpunit/php-timer", - "version": "9.0.0", + "version": "8.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "a0e12065831f6ab0d83120dc61513eb8d9a966f6" + "reference": "f258ce36aa457f3aa3339f9ed4c81fc66dc8c2cc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/a0e12065831f6ab0d83120dc61513eb8d9a966f6", - "reference": "a0e12065831f6ab0d83120dc61513eb8d9a966f6", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/f258ce36aa457f3aa3339f9ed4c81fc66dc8c2cc", + "reference": "f258ce36aa457f3aa3339f9ed4c81fc66dc8c2cc", "shasum": "" }, "require": { - "php": ">=8.4" + "php": ">=8.3" }, "require-dev": { - "phpunit/phpunit": "^13.0" + "phpunit/phpunit": "^12.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "9.0-dev" + "dev-main": "8.0-dev" } }, "autoload": { @@ -13374,70 +13178,56 @@ "support": { "issues": "https://github.com/sebastianbergmann/php-timer/issues", "security": "https://github.com/sebastianbergmann/php-timer/security/policy", - "source": "https://github.com/sebastianbergmann/php-timer/tree/9.0.0" + "source": "https://github.com/sebastianbergmann/php-timer/tree/8.0.0" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" - }, - { - "url": "https://liberapay.com/sebastianbergmann", - "type": "liberapay" - }, - { - "url": "https://thanks.dev/u/gh/sebastianbergmann", - "type": "thanks_dev" - }, - { - "url": "https://tidelift.com/funding/github/packagist/phpunit/php-timer", - "type": "tidelift" } ], - "time": "2026-02-06T04:37:53+00:00" + "time": "2025-02-07T04:59:38+00:00" }, { "name": "phpunit/phpunit", - "version": "13.2.4", + "version": "12.5.28", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "8f5180f4627fc1978be2f61d8d9979dbe37e0c10" + "reference": "5895d05f5bf421ed230fbd76e1277e4b8955def4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/8f5180f4627fc1978be2f61d8d9979dbe37e0c10", - "reference": "8f5180f4627fc1978be2f61d8d9979dbe37e0c10", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/5895d05f5bf421ed230fbd76e1277e4b8955def4", + "reference": "5895d05f5bf421ed230fbd76e1277e4b8955def4", "shasum": "" }, "require": { "ext-dom": "*", - "ext-filter": "*", "ext-json": "*", "ext-libxml": "*", "ext-mbstring": "*", + "ext-xml": "*", "ext-xmlwriter": "*", "myclabs/deep-copy": "^1.13.4", "phar-io/manifest": "^2.0.4", "phar-io/version": "^3.2.1", - "php": ">=8.4.1", - "phpunit/php-code-coverage": "^14.2.3", - "phpunit/php-file-iterator": "^7.0.0", - "phpunit/php-invoker": "^7.0.0", - "phpunit/php-text-template": "^6.0.0", - "phpunit/php-timer": "^9.0.0", - "sebastian/cli-parser": "^5.0.0", - "sebastian/comparator": "^8.3.0", - "sebastian/diff": "^9.0", - "sebastian/environment": "^9.3.2", - "sebastian/exporter": "^8.1.0", - "sebastian/file-filter": "^1.0", - "sebastian/git-state": "^1.0", - "sebastian/global-state": "^9.0.1", - "sebastian/object-enumerator": "^8.0.0", - "sebastian/recursion-context": "^8.0.0", - "sebastian/type": "^7.0.1", - "sebastian/version": "^7.0.0", + "php": ">=8.3", + "phpunit/php-code-coverage": "^12.5.6", + "phpunit/php-file-iterator": "^6.0.1", + "phpunit/php-invoker": "^6.0.0", + "phpunit/php-text-template": "^5.0.0", + "phpunit/php-timer": "^8.0.0", + "sebastian/cli-parser": "^4.2.1", + "sebastian/comparator": "^7.1.8", + "sebastian/diff": "^7.0.0", + "sebastian/environment": "^8.1.2", + "sebastian/exporter": "^7.0.3", + "sebastian/global-state": "^8.0.2", + "sebastian/object-enumerator": "^7.0.0", + "sebastian/recursion-context": "^7.0.1", + "sebastian/type": "^6.0.4", + "sebastian/version": "^6.0.0", "staabm/side-effects-detector": "^1.0.5" }, "bin": [ @@ -13446,7 +13236,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "13.2-dev" + "dev-main": "12.5-dev" } }, "autoload": { @@ -13478,7 +13268,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/13.2.4" + "source": "https://github.com/sebastianbergmann/phpunit/tree/12.5.28" }, "funding": [ { @@ -13486,20 +13276,20 @@ "type": "other" } ], - "time": "2026-07-08T08:36:51+00:00" + "time": "2026-05-27T14:01:10+00:00" }, { "name": "psy/psysh", - "version": "v0.12.24", + "version": "v0.12.23", "source": { "type": "git", "url": "https://github.com/bobthecow/psysh.git", - "reference": "ca0fdcf8a7617afa3adfdf1b5fef573dffb69ca1" + "reference": "4dcc0f08047d52bbde475eda481146fd8e27e1a4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/bobthecow/psysh/zipball/ca0fdcf8a7617afa3adfdf1b5fef573dffb69ca1", - "reference": "ca0fdcf8a7617afa3adfdf1b5fef573dffb69ca1", + "url": "https://api.github.com/repos/bobthecow/psysh/zipball/4dcc0f08047d52bbde475eda481146fd8e27e1a4", + "reference": "4dcc0f08047d52bbde475eda481146fd8e27e1a4", "shasum": "" }, "require": { @@ -13563,9 +13353,9 @@ ], "support": { "issues": "https://github.com/bobthecow/psysh/issues", - "source": "https://github.com/bobthecow/psysh/tree/v0.12.24" + "source": "https://github.com/bobthecow/psysh/tree/v0.12.23" }, - "time": "2026-06-29T15:41:09+00:00" + "time": "2026-05-23T13:41:31+00:00" }, { "name": "rector/rector", @@ -13698,28 +13488,28 @@ }, { "name": "sebastian/cli-parser", - "version": "5.0.0", + "version": "4.2.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/cli-parser.git", - "reference": "48a4654fa5e48c1c81214e9930048a572d4b23ca" + "reference": "7d05781b13f7dec9043a629a21d086ed74582a15" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/48a4654fa5e48c1c81214e9930048a572d4b23ca", - "reference": "48a4654fa5e48c1c81214e9930048a572d4b23ca", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/7d05781b13f7dec9043a629a21d086ed74582a15", + "reference": "7d05781b13f7dec9043a629a21d086ed74582a15", "shasum": "" }, "require": { - "php": ">=8.4" + "php": ">=8.3" }, "require-dev": { - "phpunit/phpunit": "^13.0" + "phpunit/phpunit": "^12.5.25" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "5.0-dev" + "dev-main": "4.2-dev" } }, "autoload": { @@ -13743,7 +13533,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/cli-parser/issues", "security": "https://github.com/sebastianbergmann/cli-parser/security/policy", - "source": "https://github.com/sebastianbergmann/cli-parser/tree/5.0.0" + "source": "https://github.com/sebastianbergmann/cli-parser/tree/4.2.1" }, "funding": [ { @@ -13763,31 +13553,31 @@ "type": "tidelift" } ], - "time": "2026-02-06T04:39:44+00:00" + "time": "2026-05-17T05:29:34+00:00" }, { "name": "sebastian/comparator", - "version": "8.3.0", + "version": "7.1.8", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "c025fc7604afab3f195fab7cdaf72327331af241" + "reference": "7c65c1e79836812819705b473a90c12399542485" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/c025fc7604afab3f195fab7cdaf72327331af241", - "reference": "c025fc7604afab3f195fab7cdaf72327331af241", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/7c65c1e79836812819705b473a90c12399542485", + "reference": "7c65c1e79836812819705b473a90c12399542485", "shasum": "" }, "require": { "ext-dom": "*", "ext-mbstring": "*", - "php": ">=8.4", - "sebastian/diff": "^9.0", - "sebastian/exporter": "^8.1.0" + "php": ">=8.3", + "sebastian/diff": "^7.0", + "sebastian/exporter": "^7.0.3" }, "require-dev": { - "phpunit/phpunit": "^13.2" + "phpunit/phpunit": "^12.5.25" }, "suggest": { "ext-bcmath": "For comparing BcMath\\Number objects" @@ -13795,7 +13585,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "8.3-dev" + "dev-main": "7.1-dev" } }, "autoload": { @@ -13835,7 +13625,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/comparator/issues", "security": "https://github.com/sebastianbergmann/comparator/security/policy", - "source": "https://github.com/sebastianbergmann/comparator/tree/8.3.0" + "source": "https://github.com/sebastianbergmann/comparator/tree/7.1.8" }, "funding": [ { @@ -13855,33 +13645,33 @@ "type": "tidelift" } ], - "time": "2026-06-05T03:06:45+00:00" + "time": "2026-05-21T04:45:25+00:00" }, { "name": "sebastian/complexity", - "version": "6.0.0", + "version": "5.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/complexity.git", - "reference": "c5651c795c98093480df79350cb050813fc7a2f3" + "reference": "bad4316aba5303d0221f43f8cee37eb58d384bbb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/c5651c795c98093480df79350cb050813fc7a2f3", - "reference": "c5651c795c98093480df79350cb050813fc7a2f3", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/bad4316aba5303d0221f43f8cee37eb58d384bbb", + "reference": "bad4316aba5303d0221f43f8cee37eb58d384bbb", "shasum": "" }, "require": { "nikic/php-parser": "^5.0", - "php": ">=8.4" + "php": ">=8.3" }, "require-dev": { - "phpunit/phpunit": "^13.0" + "phpunit/phpunit": "^12.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "6.0-dev" + "dev-main": "5.0-dev" } }, "autoload": { @@ -13905,53 +13695,41 @@ "support": { "issues": "https://github.com/sebastianbergmann/complexity/issues", "security": "https://github.com/sebastianbergmann/complexity/security/policy", - "source": "https://github.com/sebastianbergmann/complexity/tree/6.0.0" + "source": "https://github.com/sebastianbergmann/complexity/tree/5.0.0" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" - }, - { - "url": "https://liberapay.com/sebastianbergmann", - "type": "liberapay" - }, - { - "url": "https://thanks.dev/u/gh/sebastianbergmann", - "type": "thanks_dev" - }, - { - "url": "https://tidelift.com/funding/github/packagist/sebastian/complexity", - "type": "tidelift" } ], - "time": "2026-02-06T04:41:32+00:00" + "time": "2025-02-07T04:55:25+00:00" }, { "name": "sebastian/diff", - "version": "9.0.0", + "version": "7.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "a3fb6a298a265ff487a91bbea46e03cd01dbb226" + "reference": "7ab1ea946c012266ca32390913653d844ecd085f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/a3fb6a298a265ff487a91bbea46e03cd01dbb226", - "reference": "a3fb6a298a265ff487a91bbea46e03cd01dbb226", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/7ab1ea946c012266ca32390913653d844ecd085f", + "reference": "7ab1ea946c012266ca32390913653d844ecd085f", "shasum": "" }, "require": { - "php": ">=8.4" + "php": ">=8.3" }, "require-dev": { - "phpunit/phpunit": "^13.2", - "symfony/process": "^7.4.13" + "phpunit/phpunit": "^12.0", + "symfony/process": "^7.2" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "9.0-dev" + "dev-main": "7.0-dev" } }, "autoload": { @@ -13984,47 +13762,35 @@ "support": { "issues": "https://github.com/sebastianbergmann/diff/issues", "security": "https://github.com/sebastianbergmann/diff/security/policy", - "source": "https://github.com/sebastianbergmann/diff/tree/9.0.0" + "source": "https://github.com/sebastianbergmann/diff/tree/7.0.0" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" - }, - { - "url": "https://liberapay.com/sebastianbergmann", - "type": "liberapay" - }, - { - "url": "https://thanks.dev/u/gh/sebastianbergmann", - "type": "thanks_dev" - }, - { - "url": "https://tidelift.com/funding/github/packagist/sebastian/diff", - "type": "tidelift" } ], - "time": "2026-06-05T03:04:51+00:00" + "time": "2025-02-07T04:55:46+00:00" }, { "name": "sebastian/environment", - "version": "9.3.2", + "version": "8.1.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "6c9e487c9eb706a8d258102a1c0b0a3e53e86c2e" + "reference": "9d32c685773823b1983e256ae4ecd48a10d6e439" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/6c9e487c9eb706a8d258102a1c0b0a3e53e86c2e", - "reference": "6c9e487c9eb706a8d258102a1c0b0a3e53e86c2e", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/9d32c685773823b1983e256ae4ecd48a10d6e439", + "reference": "9d32c685773823b1983e256ae4ecd48a10d6e439", "shasum": "" }, "require": { - "php": ">=8.4" + "php": ">=8.3" }, "require-dev": { - "phpunit/phpunit": "^13.1.11" + "phpunit/phpunit": "^12.5.26" }, "suggest": { "ext-posix": "*" @@ -14032,7 +13798,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "9.3-dev" + "dev-main": "8.1-dev" } }, "autoload": { @@ -14060,7 +13826,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/environment/issues", "security": "https://github.com/sebastianbergmann/environment/security/policy", - "source": "https://github.com/sebastianbergmann/environment/tree/9.3.2" + "source": "https://github.com/sebastianbergmann/environment/tree/8.1.2" }, "funding": [ { @@ -14080,34 +13846,34 @@ "type": "tidelift" } ], - "time": "2026-05-25T13:41:38+00:00" + "time": "2026-05-25T13:40:20+00:00" }, { "name": "sebastian/exporter", - "version": "8.1.1", + "version": "7.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "cfaa77c750dcad6f44c9bac8f62ac486e1c82c26" + "reference": "c5e21b5de653ce0a769fb36f5cdfcb5e7a32cf23" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/cfaa77c750dcad6f44c9bac8f62ac486e1c82c26", - "reference": "cfaa77c750dcad6f44c9bac8f62ac486e1c82c26", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/c5e21b5de653ce0a769fb36f5cdfcb5e7a32cf23", + "reference": "c5e21b5de653ce0a769fb36f5cdfcb5e7a32cf23", "shasum": "" }, "require": { "ext-mbstring": "*", - "php": ">=8.4", - "sebastian/recursion-context": "^8.0" + "php": ">=8.3", + "sebastian/recursion-context": "^7.0.1" }, "require-dev": { - "phpunit/phpunit": "^13.2.4" + "phpunit/phpunit": "^12.5.25" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "8.1-dev" + "dev-main": "7.0-dev" } }, "autoload": { @@ -14150,7 +13916,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/exporter/issues", "security": "https://github.com/sebastianbergmann/exporter/security/policy", - "source": "https://github.com/sebastianbergmann/exporter/tree/8.1.1" + "source": "https://github.com/sebastianbergmann/exporter/tree/7.0.3" }, "funding": [ { @@ -14170,173 +13936,35 @@ "type": "tidelift" } ], - "time": "2026-07-13T11:35:11+00:00" - }, - { - "name": "sebastian/file-filter", - "version": "1.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/file-filter.git", - "reference": "33a26f394330f6faa7684bb9cc73afb7727aae93" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/file-filter/zipball/33a26f394330f6faa7684bb9cc73afb7727aae93", - "reference": "33a26f394330f6faa7684bb9cc73afb7727aae93", - "shasum": "" - }, - "require": { - "php": ">=8.4" - }, - "require-dev": { - "phpunit/phpunit": "^13.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Library for filtering files", - "homepage": "https://github.com/sebastianbergmann/file-filter", - "support": { - "issues": "https://github.com/sebastianbergmann/file-filter/issues", - "security": "https://github.com/sebastianbergmann/file-filter/security/policy", - "source": "https://github.com/sebastianbergmann/file-filter/tree/1.0.0" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - }, - { - "url": "https://liberapay.com/sebastianbergmann", - "type": "liberapay" - }, - { - "url": "https://thanks.dev/u/gh/sebastianbergmann", - "type": "thanks_dev" - }, - { - "url": "https://tidelift.com/funding/github/packagist/sebastian/file-filter", - "type": "tidelift" - } - ], - "time": "2026-04-22T07:20:04+00:00" - }, - { - "name": "sebastian/git-state", - "version": "1.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/git-state.git", - "reference": "792a952e0eba55b6960a48aeceb9f371aad1f76b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/git-state/zipball/792a952e0eba55b6960a48aeceb9f371aad1f76b", - "reference": "792a952e0eba55b6960a48aeceb9f371aad1f76b", - "shasum": "" - }, - "require": { - "php": ">=8.4" - }, - "require-dev": { - "phpunit/phpunit": "^13.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Library for describing the state of a Git checkout", - "homepage": "https://github.com/sebastianbergmann/git-state", - "support": { - "issues": "https://github.com/sebastianbergmann/git-state/issues", - "security": "https://github.com/sebastianbergmann/git-state/security/policy", - "source": "https://github.com/sebastianbergmann/git-state/tree/1.0.0" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - }, - { - "url": "https://liberapay.com/sebastianbergmann", - "type": "liberapay" - }, - { - "url": "https://thanks.dev/u/gh/sebastianbergmann", - "type": "thanks_dev" - }, - { - "url": "https://tidelift.com/funding/github/packagist/sebastian/git-state", - "type": "tidelift" - } - ], - "time": "2026-03-21T12:54:28+00:00" + "time": "2026-05-20T04:37:17+00:00" }, { "name": "sebastian/global-state", - "version": "9.0.1", + "version": "8.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "ba68ba79da690cf7eddefd3ce5b78b20b9ba9945" + "reference": "ef1377171613d09edd25b7816f05be8313f9115d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/ba68ba79da690cf7eddefd3ce5b78b20b9ba9945", - "reference": "ba68ba79da690cf7eddefd3ce5b78b20b9ba9945", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/ef1377171613d09edd25b7816f05be8313f9115d", + "reference": "ef1377171613d09edd25b7816f05be8313f9115d", "shasum": "" }, "require": { - "php": ">=8.4", - "sebastian/object-reflector": "^6.0", - "sebastian/recursion-context": "^8.0" + "php": ">=8.3", + "sebastian/object-reflector": "^5.0", + "sebastian/recursion-context": "^7.0" }, "require-dev": { "ext-dom": "*", - "phpunit/phpunit": "^13.1.13" + "phpunit/phpunit": "^12.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "9.0-dev" + "dev-main": "8.0-dev" } }, "autoload": { @@ -14362,7 +13990,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/global-state/issues", "security": "https://github.com/sebastianbergmann/global-state/security/policy", - "source": "https://github.com/sebastianbergmann/global-state/tree/9.0.1" + "source": "https://github.com/sebastianbergmann/global-state/tree/8.0.2" }, "funding": [ { @@ -14382,33 +14010,33 @@ "type": "tidelift" } ], - "time": "2026-06-01T15:11:33+00:00" + "time": "2025-08-29T11:29:25+00:00" }, { "name": "sebastian/lines-of-code", - "version": "5.0.2", + "version": "4.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/lines-of-code.git", - "reference": "d1b6f8fce682505dbd048977f1abedf1b8ad3ff8" + "reference": "d543b8ef219dcd8da262cbb958639a96bedba10e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/d1b6f8fce682505dbd048977f1abedf1b8ad3ff8", - "reference": "d1b6f8fce682505dbd048977f1abedf1b8ad3ff8", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/d543b8ef219dcd8da262cbb958639a96bedba10e", + "reference": "d543b8ef219dcd8da262cbb958639a96bedba10e", "shasum": "" }, "require": { - "nikic/php-parser": "^5.8.0", - "php": ">=8.4" + "nikic/php-parser": "^5.7.0", + "php": ">=8.3" }, "require-dev": { - "phpunit/phpunit": "^13.2.4" + "phpunit/phpunit": "^12.5.25" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "5.0-dev" + "dev-main": "4.0-dev" } }, "autoload": { @@ -14432,7 +14060,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", "security": "https://github.com/sebastianbergmann/lines-of-code/security/policy", - "source": "https://github.com/sebastianbergmann/lines-of-code/tree/5.0.2" + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/4.0.1" }, "funding": [ { @@ -14452,34 +14080,34 @@ "type": "tidelift" } ], - "time": "2026-07-09T08:42:34+00:00" + "time": "2026-05-19T16:22:07+00:00" }, { "name": "sebastian/object-enumerator", - "version": "8.0.0", + "version": "7.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "b39ab125fd9a7434b0ecbc4202eebce11a98cfc5" + "reference": "1effe8e9b8e068e9ae228e542d5d11b5d16db894" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/b39ab125fd9a7434b0ecbc4202eebce11a98cfc5", - "reference": "b39ab125fd9a7434b0ecbc4202eebce11a98cfc5", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/1effe8e9b8e068e9ae228e542d5d11b5d16db894", + "reference": "1effe8e9b8e068e9ae228e542d5d11b5d16db894", "shasum": "" }, "require": { - "php": ">=8.4", - "sebastian/object-reflector": "^6.0", - "sebastian/recursion-context": "^8.0" + "php": ">=8.3", + "sebastian/object-reflector": "^5.0", + "sebastian/recursion-context": "^7.0" }, "require-dev": { - "phpunit/phpunit": "^13.0" + "phpunit/phpunit": "^12.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "8.0-dev" + "dev-main": "7.0-dev" } }, "autoload": { @@ -14502,52 +14130,40 @@ "support": { "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", "security": "https://github.com/sebastianbergmann/object-enumerator/security/policy", - "source": "https://github.com/sebastianbergmann/object-enumerator/tree/8.0.0" + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/7.0.0" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" - }, - { - "url": "https://liberapay.com/sebastianbergmann", - "type": "liberapay" - }, - { - "url": "https://thanks.dev/u/gh/sebastianbergmann", - "type": "thanks_dev" - }, - { - "url": "https://tidelift.com/funding/github/packagist/sebastian/object-enumerator", - "type": "tidelift" } ], - "time": "2026-02-06T04:46:36+00:00" + "time": "2025-02-07T04:57:48+00:00" }, { "name": "sebastian/object-reflector", - "version": "6.0.0", + "version": "5.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-reflector.git", - "reference": "3ca042c2c60b0eab094f8a1b6a7093f4d4c72200" + "reference": "4bfa827c969c98be1e527abd576533293c634f6a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/3ca042c2c60b0eab094f8a1b6a7093f4d4c72200", - "reference": "3ca042c2c60b0eab094f8a1b6a7093f4d4c72200", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/4bfa827c969c98be1e527abd576533293c634f6a", + "reference": "4bfa827c969c98be1e527abd576533293c634f6a", "shasum": "" }, "require": { - "php": ">=8.4" + "php": ">=8.3" }, "require-dev": { - "phpunit/phpunit": "^13.0" + "phpunit/phpunit": "^12.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "6.0-dev" + "dev-main": "5.0-dev" } }, "autoload": { @@ -14570,52 +14186,40 @@ "support": { "issues": "https://github.com/sebastianbergmann/object-reflector/issues", "security": "https://github.com/sebastianbergmann/object-reflector/security/policy", - "source": "https://github.com/sebastianbergmann/object-reflector/tree/6.0.0" + "source": "https://github.com/sebastianbergmann/object-reflector/tree/5.0.0" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" - }, - { - "url": "https://liberapay.com/sebastianbergmann", - "type": "liberapay" - }, - { - "url": "https://thanks.dev/u/gh/sebastianbergmann", - "type": "thanks_dev" - }, - { - "url": "https://tidelift.com/funding/github/packagist/sebastian/object-reflector", - "type": "tidelift" } ], - "time": "2026-02-06T04:47:13+00:00" + "time": "2025-02-07T04:58:17+00:00" }, { "name": "sebastian/recursion-context", - "version": "8.0.0", + "version": "7.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "74c5af21f6a5833e91767ca068c4d3dfec15317e" + "reference": "0b01998a7d5b1f122911a66bebcb8d46f0c82d8c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/74c5af21f6a5833e91767ca068c4d3dfec15317e", - "reference": "74c5af21f6a5833e91767ca068c4d3dfec15317e", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/0b01998a7d5b1f122911a66bebcb8d46f0c82d8c", + "reference": "0b01998a7d5b1f122911a66bebcb8d46f0c82d8c", "shasum": "" }, "require": { - "php": ">=8.4" + "php": ">=8.3" }, "require-dev": { - "phpunit/phpunit": "^13.0" + "phpunit/phpunit": "^12.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "8.0-dev" + "dev-main": "7.0-dev" } }, "autoload": { @@ -14646,7 +14250,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/recursion-context/issues", "security": "https://github.com/sebastianbergmann/recursion-context/security/policy", - "source": "https://github.com/sebastianbergmann/recursion-context/tree/8.0.0" + "source": "https://github.com/sebastianbergmann/recursion-context/tree/7.0.1" }, "funding": [ { @@ -14666,32 +14270,32 @@ "type": "tidelift" } ], - "time": "2026-02-06T04:51:28+00:00" + "time": "2025-08-13T04:44:59+00:00" }, { "name": "sebastian/type", - "version": "7.0.1", + "version": "6.0.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/type.git", - "reference": "fee0309275847fefd7636167085e379c1dbf6990" + "reference": "82ff822c2edc46724be9f7411d3163021f602773" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/fee0309275847fefd7636167085e379c1dbf6990", - "reference": "fee0309275847fefd7636167085e379c1dbf6990", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/82ff822c2edc46724be9f7411d3163021f602773", + "reference": "82ff822c2edc46724be9f7411d3163021f602773", "shasum": "" }, "require": { - "php": ">=8.4" + "php": ">=8.3" }, "require-dev": { - "phpunit/phpunit": "^13.1.10" + "phpunit/phpunit": "^12.5.25" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "7.0-dev" + "dev-main": "6.0-dev" } }, "autoload": { @@ -14715,7 +14319,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/type/issues", "security": "https://github.com/sebastianbergmann/type/security/policy", - "source": "https://github.com/sebastianbergmann/type/tree/7.0.1" + "source": "https://github.com/sebastianbergmann/type/tree/6.0.4" }, "funding": [ { @@ -14735,29 +14339,29 @@ "type": "tidelift" } ], - "time": "2026-05-20T06:49:11+00:00" + "time": "2026-05-20T06:45:45+00:00" }, { "name": "sebastian/version", - "version": "7.0.0", + "version": "6.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/version.git", - "reference": "ad37a5552c8e2b88572249fdc19b6da7792e021b" + "reference": "3e6ccf7657d4f0a59200564b08cead899313b53c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/ad37a5552c8e2b88572249fdc19b6da7792e021b", - "reference": "ad37a5552c8e2b88572249fdc19b6da7792e021b", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/3e6ccf7657d4f0a59200564b08cead899313b53c", + "reference": "3e6ccf7657d4f0a59200564b08cead899313b53c", "shasum": "" }, "require": { - "php": ">=8.4" + "php": ">=8.3" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "7.0-dev" + "dev-main": "6.0-dev" } }, "autoload": { @@ -14781,27 +14385,15 @@ "support": { "issues": "https://github.com/sebastianbergmann/version/issues", "security": "https://github.com/sebastianbergmann/version/security/policy", - "source": "https://github.com/sebastianbergmann/version/tree/7.0.0" + "source": "https://github.com/sebastianbergmann/version/tree/6.0.0" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" - }, - { - "url": "https://liberapay.com/sebastianbergmann", - "type": "liberapay" - }, - { - "url": "https://thanks.dev/u/gh/sebastianbergmann", - "type": "thanks_dev" - }, - { - "url": "https://tidelift.com/funding/github/packagist/sebastian/version", - "type": "tidelift" } ], - "time": "2026-02-06T04:52:52+00:00" + "time": "2025-02-07T05:00:38+00:00" }, { "name": "spatie/file-system-watcher", @@ -15199,86 +14791,6 @@ ], "time": "2024-10-20T05:08:20+00:00" }, - { - "name": "symfony/polyfill-php83", - "version": "v1.41.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php83.git", - "reference": "5ea99087fb99c273a9b9236ed4c31e78b16103c6" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/5ea99087fb99c273a9b9236ed4c31e78b16103c6", - "reference": "5ea99087fb99c273a9b9236ed4c31e78b16103c6", - "shasum": "" - }, - "require": { - "php": ">=7.2" - }, - "type": "library", - "extra": { - "thanks": { - "url": "https://github.com/symfony/polyfill", - "name": "symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Php83\\": "" - }, - "classmap": [ - "Resources/stubs" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 8.3+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-php83/tree/v1.41.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://github.com/nicolas-grekas", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2026-07-01T12:47:55+00:00" - }, { "name": "ta-tikoma/phpunit-architecture-test", "version": "0.8.7", @@ -15391,9 +14903,7 @@ ], "aliases": [], "minimum-stability": "dev", - "stability-flags": { - "craftcms/cms-assets": 20 - }, + "stability-flags": {}, "prefer-stable": true, "prefer-lowest": false, "platform": { diff --git a/database/Factories/FieldLayoutFactory.php b/database/Factories/FieldLayoutFactory.php index f2360a59150..a5101265dfd 100644 --- a/database/Factories/FieldLayoutFactory.php +++ b/database/Factories/FieldLayoutFactory.php @@ -7,11 +7,9 @@ use CraftCms\Cms\Entry\Elements\Entry; use CraftCms\Cms\Field\Field; use CraftCms\Cms\Field\Models\Field as FieldModel; -use CraftCms\Cms\FieldLayout\FieldLayout as FieldLayoutConfig; -use CraftCms\Cms\FieldLayout\FieldLayoutElement; -use CraftCms\Cms\FieldLayout\FieldLayoutTab; use CraftCms\Cms\FieldLayout\LayoutElements\CustomField; use CraftCms\Cms\FieldLayout\Models\FieldLayout; +use CraftCms\Cms\Support\Str; use Illuminate\Database\Eloquent\Factories\Factory; class FieldLayoutFactory extends Factory @@ -26,23 +24,30 @@ public function definition(): array ]; } - /** @param FieldLayoutElement[] $elements */ - public function withContentTab(array $elements = [], ?string $name = null): self + public function withContentTab(array $elements = [], string $name = 'Content'): self { - return $this->state(function (array $attributes) use ($elements, $name) { - $layout = FieldLayoutConfig::make($attributes['type']); - $layout->tab($name ?? FieldLayoutConfig::defaultTabName(), fn (FieldLayoutTab $tab) => $tab->add(...$elements)); - - return ['config' => $layout->getConfig()]; - }); + return $this->state(fn () => [ + 'config' => [ + 'tabs' => [ + [ + 'uid' => Str::uuid()->toString(), + 'name' => $name, + 'elements' => $elements, + ], + ], + ], + ]); } public function forField(Field|FieldModel $field, bool $required = false): self { - $element = $field instanceof FieldModel - ? new CustomField(config: ['fieldUid' => $field->uid]) - : CustomField::make($field); - - return $this->withContentTab([$element->required($required)]); + return $this->withContentTab([ + [ + 'uid' => Str::uuid()->toString(), + 'type' => CustomField::class, + 'fieldUid' => $field->uid, + 'required' => $required, + ], + ]); } } diff --git a/docs/admin-table.md b/docs/admin-table.md index 44e467cb2ee..ee2ab4b596b 100644 --- a/docs/admin-table.md +++ b/docs/admin-table.md @@ -9,7 +9,7 @@ The `AdminTable` component renders data tables in the Craft CMS Control Panel. I import {getCoreRowModel, useVueTable} from '@tanstack/vue-table'; import AdminTable from '@/components/AdminTable/AdminTable.vue'; import {createCraftColumnHelper} from '@/components/AdminTable/createCraftColumnHelper'; -import {t} from '@craftcms/ui'; +import {t} from '@craftcms/cp'; interface RowData { id: number; @@ -55,7 +55,7 @@ const table = useVueTable({ | `selectable` | `boolean` | `true` | Reserved for future row selection support. | | `readOnly` | `boolean` | — | When `true`, hides reorder handles (used with `reorderable`). | | `layout` | `'auto' \| 'fixed'` | `'auto'` | CSS table layout mode. | -| `spacing` | `TableSpacingValue` | — | Row density: `'compact'` or `'spacious'`. | +| `spacing` | `TableSpacingValue` | — | Row density: `'compact'`, `'relaxed'`, or `'spacious'`. | | `from` | `number` | — | Start index of displayed rows (for "X–Y of Z" display). | | `to` | `number` | — | End index of displayed rows. | | `total` | `number` | — | Total number of items (all pages). | diff --git a/docs/blade.md b/docs/blade.md deleted file mode 100644 index 60ec28d74d9..00000000000 --- a/docs/blade.md +++ /dev/null @@ -1,465 +0,0 @@ -# Blade Templates - -Craft 6 can render Laravel Blade templates through the same template lifecycle used by Twig page templates. - -Blade support is outcome parity with Twig, not a clone of Twig syntax. Use native Blade and Laravel features where they already exist, and use Craft's Blade directives for Craft-specific template behavior such as page lifecycle placeholders, resource registration, template caches, hooks, namespacing, and response control. - -Blade templates are trusted PHP-backed templates. They are compiled to PHP and are not sandboxed. Use sandboxed Twig rendering for untrusted template strings. - -## Template Discovery - -Front-end site templates can use `.blade.php` files. The default front-end template extension order is: - -- `twig` -- `html` -- `blade.php` - -That means `templates/news.twig` will be chosen before `templates/news.blade.php` when both exist. Change `defaultTemplateExtensions` if a project needs a different order: - -```php - ['blade.php', 'twig', 'html'], -]; -``` - -Craft's template resolver still owns template lookup before either engine renders anything. Public/private template filtering, path containment, localized site template lookup, index template lookup, and registered template roots all apply before Craft decides whether the resolved file should be rendered by Twig or Blade. - -Control panel template lookup supports `twig`, `html`, and `blade.php`. Blade application and plugin views can also be rendered directly through Laravel's view system. - -## Rendering Templates - -The engine-neutral renderer resolves a Craft template name and then chooses Twig or Blade based on the resolved file extension. - -```php - $entry, -]); - -$pageHtml = Template::renderPageTemplate('articles/show', [ - 'entry' => $entry, -]); -``` - -The global helpers use the same renderer: - -```php - $entry]); -$pageHtml = pageTemplate('articles/show', ['entry' => $entry]); -``` - -Automatic selection uses the first registered renderer that supports the resolved file. Pass a `TemplateEngine` or custom renderer name to force a renderer: - -```php - $entry], renderer: TemplateEngine::Blade); -``` - -`renderPageTemplate()` and `pageTemplate()` wrap Blade templates in Craft's page lifecycle, so queued head/body resources are rendered into the page placeholders. - -If you already have a Laravel view name or file path, resolve the low-level `BladeRenderer` through the `Template` facade: - -```php -renderTemplate('my-plugin::tokens.index', [ - 'token' => $token, -], TemplateMode::Cp); - -$inline = $renderer->renderString('Hello, {{ $name }}', [ - 'name' => 'Craft', -], TemplateMode::Cp); -``` - -Slash-style view names and namespaced views both work: - -```php -file($path, $variables)` when you intentionally want to render a concrete file path. - -## Renderers - -`TemplateManager` is a scoped Laravel manager. Its built-in renderer names are `twig` and `blade`, represented by `TemplateEngine`. Custom renderers implement `TemplateRendererInterface`, including file support, resolved-template rendering, and inline-string rendering. A replacement for the built-in Twig renderer must implement `TwigRendererInterface`. - -Register renderers once, typically from a service provider’s `boot()` method, through the `Template` facade. The registration is replayed whenever Laravel creates a new manager scope: - -```php - $container->make(MarkdownRenderer::class), - ); - } -} -``` - -New renderer names are appended after the built-in renderers. Re-registering an existing name replaces its creator without changing its selection position. Like other Laravel managers, an already-resolved renderer remains cached in the current scope until `forgetRenderers()` is called. New manager scopes receive the latest creator automatically and resolve their own renderer instances. - -Don’t wrap `extend()` in `callAfterResolving()`, because the manager registers its own scope replay. Renderer creators should resolve scoped dependencies from the supplied container rather than capturing request-specific instances. - -## Routes - -Dynamic template routes now render Blade templates through the shared renderer. Template routes still resolve the Craft template first, then render the resolved `.blade.php` file as a page template. - -This means routed Blade site templates respect: - -- public/private template filtering -- project-config and element route variables -- headless-mode 404 behavior for site requests -- Craft template mode restoration -- page lifecycle resource injection -- template rendering events - -## Template Globals - -Blade views receive the same Craft template globals as Twig through a Laravel view composer. Common globals include: - -- `$craft` -- `$currentSite` -- `$currentUser` -- `$siteName` -- `$siteUrl` -- `$systemName` -- `$language` -- `$devMode` -- `$isInstalled` -- `$loginUrl` -- `$logoutUrl` (the action URL for a CSRF-protected POST logout form) -- `$setPasswordUrl` -- `$now` -- `$today` -- `$tomorrow` -- `$yesterday` - -Plugins can customize the shared globals with `TemplateGlobalsResolving`: - -```php -globals['myGlobal'] = 'value'; -}); -``` - -Blade also keeps Laravel's normal view data, helpers, components, stacks, composers, and escaping behavior. - -## Page Lifecycle - -Page Blade templates can mark where Craft should output registered resources: - -```blade - - - - {{ $entry->title }} - @craftHead - - - @craftBeginBody - -
- {{ $entry->title }} -
- - @craftEndBody - - -``` - -Use these directives in full page templates: - -| Directive | Output position | -|---|---| -| `@craftHead` | Registered head resources | -| `@craftBeginBody` | Registered body-begin resources | -| `@craftEndBody` | Registered body-end resources | - -## Resource Directives - -Craft's resource directives register assets and arbitrary HTML with `HtmlStack`. - -```blade -@craftCss('body { color: red; }') -@craftJs('console.log("ready")') -@craftHtml('
') -@craftScript('{"@context":"https://schema.org"}', \CraftCms\Cms\View\Enums\Position::Head, ['type' => 'application/ld+json']) -``` - -Each resource directive also supports block capture: - -```blade -@craftCss - body { - color: red; - } -@endCraftCss - -@craftJs - console.log('ready'); -@endCraftJs - -@craftHtml -
-@endCraftHtml - -@craftScript - {"name": "Craft"} -@endCraftScript -``` - -Directive signatures: - -| Directive | Signature | -|---|---| -| `@craftCss` | `(string $css, array $options = [], ?string $key = null)` | -| `@craftJs` | `(string $js, array $options = [], ?string $key = null)` | -| `@craftHtml` | `(string $html, int\|Position $position = Position::BodyEnd, ?string $key = null)` | -| `@craftScript` | `(string $script, int\|Position $position = Position::BodyEnd, array $options = [], ?string $key = null)` | - -`@craftCss` and `@craftJs` can register inline code or file URLs. `@craftJs` accepts a `position` option: - -```blade -@craftJs('/assets/app.js', ['position' => \CraftCms\Cms\View\Enums\Position::BodyEnd->value]) -``` - -## Template Cache Directives - -Blade templates can use Craft's template cache service: - -```blade -@craftCache('entry-'.$entry->id, duration: '+1 hour') - {{ $entry->title }} -@endCraftCache -``` - -The first argument is the cache key. Without `global: true`, the key is scoped to the current site and request path. With `global: true`, it is scoped to the current site only. - -```blade -@craftCache('navigation', global: true) - @include('_navigation') -@endCraftCache -``` - -The directive supports these options: - -| Option | Description | -|---|---| -| `global` | Store the fragment outside the current request path. | -| `duration` | A date string, such as `'+1 hour'`. | -| `expiration` | A concrete expiration value, such as a `DateTimeInterface` or Carbon instance. | -| `withResources` | Capture and replay registered resources with the cached body. Defaults to `true`. | -| `condition` | Cache only when this value is truthy. | -| `unless` | Bypass caching when this value is truthy. | - -For Twig-style conditional cache blocks, use the Blade-specific aliases: - -```blade -@craftCacheIf($entry->cacheable, 'entry-'.$entry->id, duration: '+1 hour') - {{ $entry->title }} -@endCraftCache - -@craftCacheUnless($isPreview, 'entry-'.$entry->id) - {{ $entry->title }} -@endCraftCache -``` - -`@craftCacheIf($condition, ...$cacheArguments)` caches when `$condition` is true. `@craftCacheUnless($condition, ...$cacheArguments)` caches when `$condition` is false. - -Preview requests and tokenized requests bypass template caches automatically. - -## Hooks - -Use `@craftHook` to invoke Craft template hooks from Blade: - -```blade -@craftHook('cp.elements.toolbar') -``` - -The current Blade scope is passed to hook handlers by reference. If a hook mutates the context, the mutated values are extracted back into the Blade scope after the hook runs. - -```blade -@php($label = 'Original') - -@craftHook('my-plugin.label') - -{{ $label }} -``` - -## Namespaces - -Use `@craftNamespace` when rendering field inputs or other markup that needs Craft's input-name namespacing: - -```blade -@craftNamespace('fields') - - -@endCraftNamespace -``` - -This rewrites the captured HTML so the input is submitted under `fields[title]`, with matching ID and `for` attributes. Pass `true` as the second argument to also namespace classes: - -```blade -@craftNamespace('fields', true) - ... -@endCraftNamespace -``` - -## Pagination - -Use `@craftPaginate` with a paginatable query. It assigns `$paginate` and `$paginatedItems` in the current Blade scope: - -```blade -@craftPaginate($entries) - -@foreach($paginatedItems as $entry) -
{{ $entry->title }}
-@endforeach - -@if($paginate->nextUrl) -
Next -@endif -``` - -## Auth and Edition Requirements - -Craft-specific access directives are available for template-level requirements: - -```blade -@craftRequireLogin -@craftRequireGuest -@craftRequireAdmin -@craftRequireAdmin(false) -@craftRequirePermission('accessCp') -@craftRequireEdition('pro') -``` - -Use Laravel-native Blade directives for normal Laravel authorization flows where they already fit: - -```blade -@auth - ... -@endauth - -@can('update', $entry) - ... -@endcan -``` - -## Response Directives - -Blade templates can control the response in the same way Craft templates can: - -```blade -@craftRedirect('news', 302, notice: 'Redirected') -@craftHeader('X-Robots-Tag: noindex') -@craftExpires(1, 'hour') -@craftExit -@craftExit(404, 'Not found') -``` - -`@craftExit` without a status exits the template and returns whatever has already been rendered. With a status, it aborts with that HTTP response. - -## Twig and Blade Interop - -Blade can include any Twig or Blade view that Laravel's view finder can resolve. Craft registers Twig as a Laravel view engine, and registered application, plugin, and template roots are available to `@include()`. - -This is Laravel view resolution, not a second call to Craft's template resolver. Use `template()` or `pageTemplate()` from PHP when you need Craft template-name resolution, public/private template checks, or page-template wrapping. - -```blade -@include('_navigation') -@include('articles/_entry', ['entry' => $entry]) -@include('my-plugin::tokens.index') -``` - -There is no separate `@craftTemplate` directive. Use Blade's native `@include`, `@extends`, components, and stacks where those are the natural Blade features. - -Twig can render Laravel Blade views with the `blade()` function: - -```twig -{{ blade('my-plugin::tokens.index', { token: token }) }} -{{ blade('my-plugin::nested/screen', { entry: entry }) }} -``` - -The `blade()` function returns safe HTML and uses Laravel view resolution. - -## Rendering Events - -Craft exposes engine-neutral rendering events for both Twig and Blade: - -- `CraftCms\Cms\View\Events\TemplateRendering` -- `CraftCms\Cms\View\Events\TemplateRendered` -- `CraftCms\Cms\View\Events\PageTemplateRendering` -- `CraftCms\Cms\View\Events\PageTemplateRendered` - -Before events run before template resolution, so listeners can mutate the template name, variables, or template mode before a renderer is selected. After events expose the final renderer name as a string: - -```php -rendererName !== TemplateEngine::Blade->value) { - return; - } - - $event->output = trim($event->output); -}); -``` - -`TemplateRendering` and `PageTemplateRendering` can cancel rendering by setting the event invalid. `TemplateRendered` and `PageTemplateRendered` can mutate the rendered output. - -## Native Blade Features - -Craft does not wrap features Blade and Laravel already provide. Use the native Blade syntax for: - -- escaped output with `{{ }}` -- raw output with `{!! !!}` -- control flow like `@if`, `@foreach`, `@switch`, and `@class` -- includes, layouts, components, and stacks -- `@auth`, `@guest`, and `@can` -- `@csrf`, `@method`, `@vite`, `@dd`, and other Laravel directives -- Laravel view composers - -## Security - -Blade templates are trusted code. They can execute PHP and call application services. Do not render untrusted user-editable Blade templates or strings. - -Twig remains the safe path for sandboxed or user-authored templates. diff --git a/docs/html-sanitizers.md b/docs/html-sanitizers.md index 2472bb94f43..03a46bcfb3e 100644 --- a/docs/html-sanitizers.md +++ b/docs/html-sanitizers.md @@ -1,18 +1,20 @@ # HTML Sanitizers -Craft 6 includes a Laravel-native `HtmlSanitizerManager` built on [Symfony HtmlSanitizer](https://symfony.com/doc/current/html_sanitizer.html). Application code can access it through the plural `HtmlSanitizers` facade. +Craft 6 includes a Laravel-native HTML sanitizer registry built on [Symfony HtmlSanitizer](https://symfony.com/doc/current/html_sanitizer.html). -The manager lets plugins and apps: +The `HtmlSanitizers` service lets plugins and apps: -- sanitize HTML with Craft’s default sanitizer +- sanitize HTML with Craft's default sanitizer - register named sanitizers for project-specific rules - customize the default sanitizer config -- reuse Craft’s default config when defining custom sanitizers +- reuse Craft's default config when defining custom sanitizers -Legacy HtmlPurifier support remains available through the Yii2 adapter layer. The legacy Twig `|purify` filter still uses HtmlPurifier, while `|sanitize` uses the sanitizer manager. +Legacy HtmlPurifier support remains available through the Yii2 adapter layer. The legacy Twig `|purify` filter still uses HtmlPurifier, while the new `|sanitize` filter uses the new sanitizer registry. ## Basic Usage +Use the facade and call `sanitize()`: + ```php register('links-only', new HtmlSanitizer( (new HtmlSanitizerConfig()) ->allowElement('a') ->allowAttribute('href', ['a']) @@ -50,32 +63,29 @@ class AppServiceProvider extends ServiceProvider } ``` -`extend()` accepts any of these definitions: +Use the registered sanitizer by name: -- an array of sanitizer settings -- an `HtmlSanitizerInterface` instance -- a creator closure that returns either an array or an `HtmlSanitizerInterface` instance +```php + [ - 'allow_elements' => [ - 'a' => ['href'], - ], -]); +$cleanHtml = HtmlSanitizers::sanitize($dirtyHtml, 'links-only'); ``` -Use a sanitizer by name or resolve it directly: +You can also resolve the sanitizer instance directly: ```php -$cleanHtml = HtmlSanitizers::sanitize($dirtyHtml, 'links-only'); +sanitize($dirtyHtml); ``` ## Array Config Files -Named sanitizers can also be defined in `config/craft/sanitizers/`. The file name becomes the sanitizer name and the returned array is loaded through Laravel’s configuration repository, including when configuration is cached. +Named sanitizers can also be registered with Symfony-style array config files in `config/craft/sanitizers/`. The file name becomes the sanitizer name. ```php $config - ->allowAttribute('class', ['p', 'span']) - ->allowElement('iframe') - ->allowAttribute('src', ['iframe']) -); +defaults(fn (HtmlSanitizerConfig $config) => $config + ->allowAttribute('class', ['p', 'span']) + ->allowElement('iframe') + ->allowAttribute('src', ['iframe']) + ); + } +} ``` -To create a named sanitizer starting from Craft’s defaults: +Each callback receives the current default config and may return the same config or a modified one. + +The default sanitizer instance is built lazily from `defaultConfig()`, so calling `defaults()` changes what `sanitize($html)` uses by default. + +## Reusing the Default Config + +If you want a custom named sanitizer that starts from Craft's defaults, call `defaultConfig()` and keep building from there. ```php -HtmlSanitizers::extend('embedded-content', fn () => new HtmlSanitizer( - HtmlSanitizers::defaultConfig() - ->allowElement('iframe') - ->allowAttribute('src', ['iframe']) -)); +defaultConfig() + ->allowElement('iframe') + ->allowAttribute('src', ['iframe']); + + $sanitizers->register('embedded-content', new HtmlSanitizer($config)); + } +} ``` -## Resolution and Caching +This is the recommended way to define custom sanitizers that should stay close to Craft's defaults. + +## Twig Filters -Sanitizers are created lazily and cached by name. Register extensions and default callbacks before their sanitizers are first resolved. Replacing a creator or adding a default callback does not change an already-resolved sanitizer. Call `HtmlSanitizers::forgetDrivers()` to clear all resolved instances when an intentional runtime change must take effect. +Craft now provides two distinct Twig filters: -Calling `all()` eagerly resolves every registered sanitizer. `getDrivers()` returns only sanitizers that have already been resolved. +- `|sanitize` uses the new `HtmlSanitizers` service -## Twig Filter +Examples: ```twig {{ body|sanitize }} @@ -131,3 +175,11 @@ Calling `all()` eagerly resolves every registered sanitizer. `getDrivers()` retu ``` You may also pass a concrete sanitizer instance from PHP into a template context and use it directly with `|sanitize`. + +## Recommended Direction + +For new code: + +- prefer the `HtmlSanitizers` service or facade for application code +- prefer `|sanitize` in Twig +- define named sanitizers in service providers when they need custom PHP logic diff --git a/docs/oauth.md b/docs/oauth.md index 92783491463..c8004a3dce8 100644 --- a/docs/oauth.md +++ b/docs/oauth.md @@ -54,14 +54,12 @@ Each provider supports the following keys: - `clientSecret` optional for named drivers when already defined in Laravel's `services` config. Required for provider classes. - `name` optional. Human-friendly provider name. - `label` optional. Button label. Defaults to `Sign in with {name}`. -- `icon` optional. Control panel brand icon name for the sign-in providers screen. - `scopes` optional. Array of scopes passed to Socialite. - `with` optional. Array of extra request parameters passed to the provider. - `stateless` optional. Set to `true` to bypass Socialite state validation. - `groups` optional. Array of user group IDs, UIDs, or handles to assign to newly-created users. - `createsUsers` optional. Defaults to `null`, which inherits Craft's public registration setting. - `activatesUsers` optional. Defaults to `false`. -- `trustsEmail` optional. Defaults to `false`. Set to `true` only when the provider is trusted to verify ownership of the returned email address; this allows first-time matching to existing Craft users by email. - `identityResolver` optional. Class implementing `\CraftCms\Cms\Auth\OAuth\Contracts\ResolvesOAuthIdentity`. - `userResolver` optional. Class implementing `\CraftCms\Cms\Auth\OAuth\Contracts\ResolvesOAuthUser`. - `userPopulator` optional. Class implementing `\CraftCms\Cms\Auth\OAuth\Contracts\PopulatesOAuthUser`. @@ -84,12 +82,10 @@ return GeneralConfig::create() 'clientId' => env('GITHUB_CLIENT_ID'), 'clientSecret' => env('GITHUB_CLIENT_SECRET'), 'label' => 'Continue with GitHub', - 'icon' => 'github', 'scopes' => ['read:user', 'user:email'], 'groups' => ['members', 'editors'], 'createsUsers' => true, 'activatesUsers' => true, - 'trustsEmail' => true, 'userPopulator' => GitHubUserPopulator::class, 'buttonRenderer' => GitHubButtonRenderer::class, ], @@ -130,13 +126,11 @@ The default user resolver tries, in order: 1. An existing link in `sso_identities` 2. The `ResolvingOAuthUserLink` event -3. An existing user with the provider email, only when `trustsEmail` is `true` +3. `Users::getUserByUsernameOrEmail()` using the provider email If none of those produce a user, the resolver returns `null`. The controller will only create a new user record afterward if `createsUsers` allows it. -If `trustsEmail` is `false` or the provider does not return an email, there is no default email fallback match to an existing user. This prevents untrusted providers from linking to existing accounts by asserting someone else's email address. - -Only enable `trustsEmail` for additional providers when your provider configuration guarantees the returned email address belongs to the authenticated external user. Set it to `false` to opt out for a known provider. +If the provider does not return an email, there is no default username/email fallback match. ### User Population @@ -169,8 +163,6 @@ OAuth will create a new user according to `createsUsers`: If no existing user can be matched and creation is not allowed by that policy, the OAuth login is rejected without creating an account. -If `trustsEmail` is `false` and the provider email already belongs to an existing Craft user, the OAuth login is rejected instead of linking the existing user or creating a duplicate account. - ### Group Assignment Configured `groups` are normalized from IDs, UIDs, or handles to group IDs. diff --git a/docs/server-driven-menu-actions.md b/docs/server-driven-menu-actions.md index 4646a4bbf47..3d7fb8443d6 100644 --- a/docs/server-driven-menu-actions.md +++ b/docs/server-driven-menu-actions.md @@ -181,3 +181,4 @@ If you're rendering a menu item manually in a Vue or Inertia page, pass `action` The `feedbackDuration` attribute (milliseconds, default `1000`) controls how long success/error messages show before the item resets to idle. + diff --git a/eslint.config.ts b/eslint.config.ts new file mode 100644 index 00000000000..41af0542eb7 --- /dev/null +++ b/eslint.config.ts @@ -0,0 +1,70 @@ +import eslint from '@eslint/js'; +import tseslint from 'typescript-eslint'; +import pluginVue from 'eslint-plugin-vue'; + +export default tseslint.config( + { + ignores: [ + 'resources/build/**', + 'resources/legacy/**', + // Fixture file uses PHP-style escaped strings (\/); not real JS issues + 'resources/js/**/fixtures/**', + ], + }, + eslint.configs.recommended, + ...tseslint.configs.recommended, + ...pluginVue.configs['flat/recommended'], + { + files: ['resources/js/**/*.{ts,vue}'], + languageOptions: { + globals: { + // Craft CMS globals injected at runtime + Craft: 'readonly', + Garnish: 'readonly', + }, + parserOptions: { + parser: tseslint.parser, + extraFileExtensions: ['.vue'], + sourceType: 'module', + }, + }, + rules: { + // Downgrade to warn — widespread in the codebase, address in follow-up + '@typescript-eslint/no-explicit-any': 'off', + + 'vue/no-unused-vars': 'warn', + + // Vue single-word component names are intentional in this codebase + 'vue/multi-word-component-names': 'off', + + // Craft uses both Vue components (CamelCase) and web components (kebab-case). + // Web components require slot="name" (HTML standard), not #name (Vue syntax). + // eslint-plugin-vue cannot distinguish the two, so this rule is disabled. + 'vue/no-deprecated-slot-attribute': 'off', + + // v-html is used intentionally; XSS risk is accepted in Craft's admin context + 'vue/no-v-html': 'off', + + // v-html on Craft web components (custom elements) is intentional — they render slot content as HTML + 'vue/no-v-text-v-html-on-component': 'off', + + // I don't find this useful when writing in typescript. + 'vue/require-default-prop': 'off', + + // Lion/WebAwesome web components expose camelCase DOM properties (e.g. + // .choiceValue). Hyphenating them would bind the wrong property name, so + // camelCase prop bindings on custom elements are required, not optional. + 'vue/attribute-hyphenation': 'off', + + // Formatting rules — Prettier handles these + 'vue/html-self-closing': 'off', + 'vue/max-attributes-per-line': 'off', + 'vue/attributes-order': 'off', + 'vue/singleline-html-element-content-newline': 'off', + 'vue/multiline-html-element-content-newline': 'off', + 'vue/html-closing-bracket-newline': 'off', + 'vue/first-attribute-linebreak': 'off', + 'vue/html-indent': 'off', + }, + } +); diff --git a/ide.json b/ide.json index 2e072e1c3e8..702620842e6 100644 --- a/ide.json +++ b/ide.json @@ -12,16 +12,6 @@ "parameters": [1] } ] - }, - { - "complete": "inertiaPage", - "condition": [ - { - "methodNames": ["inertiaPage"], - "classFqn": ["\\CraftCms\\Cms\\Http\\Responses\\CpScreenResponse"], - "parameters": [1] - } - ] } ] } diff --git a/package-lock.json b/package-lock.json index 3f85a895005..b7e3836e069 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,8 +11,7 @@ "dependencies": { "@atlaskit/pragmatic-drag-and-drop": "^1.8.1", "@atlaskit/pragmatic-drag-and-drop-hitbox": "^1.1.0", - "@craftcms/graphiql": "file:packages/craftcms-graphiql", - "@craftcms/ui": "file:packages/craftcms-ui", + "@craftcms/cp": "file:packages/craftcms-cp", "@headlessui/vue": "^1.7.23", "@inertiajs/vite": "^3.0.3", "@inertiajs/vue3": "^3.0.3", @@ -21,35 +20,37 @@ "axios": "^1.17.0", "laravel-vite-plugin": "^3.1.0", "lit": "^3.3.2", - "overtype": "^2.4.0", "tailwindcss": "^4.2.4", "vue": "^3.5.33" }, "devDependencies": { - "@craftcms/garnish": "file:packages/craftcms-garnish", "@craftcms/playwright": "file:packages/craftcms-playwright", "@craftcms/webpack": "file:packages/craftcms-webpack", "@laravel/vite-plugin-wayfinder": "^0.1.7", "@playwright/test": "^1.59.1", - "@storybook/addon-a11y": "^10.5.5", - "@storybook/addon-docs": "^10.5.5", - "@storybook/addon-themes": "^10.5.5", - "@storybook/vue3-vite": "^10.5.5", + "@storybook/addon-a11y": "^10.4.1", + "@storybook/addon-docs": "^10.4.1", + "@storybook/addon-themes": "^10.4.1", + "@storybook/vue3-vite": "^10.4.1", "@tailwindcss/vite": "^4.2.4", "@total-typescript/tsconfig": "^1.0.4", "@vitejs/plugin-vue": "^6.0.6", "esbuild": "^0.28.0", + "eslint": "^9.39.4", + "eslint-plugin-vue": "^9.33.0", + "husky": "^9.1.7", + "lint-staged": "^16.4.0", "npm-run-all": "^4.1.5", - "storybook": "^10.5.5", + "prettier": "3.8.3", + "storybook": "^10.4.1", "stylelint": "^17.9.1", "stylelint-config-standard": "^40.0.0", "stylelint-config-standard-scss": "^17.0.0", "stylelint-prettier": "^5.0.3", "stylelint-use-logical": "^2.1.3", "typescript": "^6.0.3", - "vite": "npm:@voidzero-dev/vite-plus-core@0.2.6", - "vite-plus": "0.2.6", - "vitest": "4.1.10", + "typescript-eslint": "^8.60.0", + "vite": "^8.0.10", "vue-tsc": "^3.2.7" }, "engines": { @@ -88,7 +89,7 @@ }, "node_modules/@andrewbranch/untar.js": { "version": "1.0.3", - "devOptional": true + "dev": true }, "node_modules/@arethetypeswrong/cli": { "version": "0.18.2", @@ -195,7 +196,7 @@ }, "node_modules/@arethetypeswrong/core": { "version": "0.18.2", - "devOptional": true, + "dev": true, "license": "MIT", "dependencies": { "@andrewbranch/untar.js": "^1.0.3", @@ -213,7 +214,7 @@ }, "node_modules/@arethetypeswrong/core/node_modules/semver": { "version": "7.7.3", - "devOptional": true, + "dev": true, "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -224,7 +225,7 @@ }, "node_modules/@arethetypeswrong/core/node_modules/typescript": { "version": "5.6.1-rc", - "devOptional": true, + "dev": true, "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", @@ -253,8 +254,6 @@ }, "node_modules/@awesome.me/kit-ddaed3f5c5": { "version": "1.0.74", - "resolved": "https://npm.fontawesome.com/@awesome.me/kit-ddaed3f5c5/-/kit-ddaed3f5c5-1.0.74.tgz", - "integrity": "sha512-/9WEaBdZWJhQPuSW9Kw2XBgit5DI5QxO4tJpxbNz7uUE09kN2+NySWx2NGc5riu36YZVPtAlYiRnWW4A1SSQkQ==", "license": "UNLICENSED", "optional": true, "dependencies": { @@ -264,6 +263,37 @@ "node": ">=16" } }, + "node_modules/@awesome.me/webawesome": { + "version": "3.6.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@ctrl/tinycolor": "4.1.0", + "@floating-ui/dom": "^1.6.13", + "@lit/react": "^1.0.8", + "@shoelace-style/animations": "^1.2.0", + "@shoelace-style/localize": "^3.2.2", + "composed-offset-position": "^0.0.6", + "lit": "^3.2.1", + "marked": "^11.2.0", + "nanoid": "^5.1.5", + "qr-creator": "^1.0.0" + }, + "engines": { + "node": ">=14.17.0" + } + }, + "node_modules/@awesome.me/webawesome/node_modules/marked": { + "version": "11.2.0", + "dev": true, + "license": "MIT", + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 18" + } + }, "node_modules/@babel/code-frame": { "version": "7.27.1", "license": "MIT", @@ -558,18 +588,14 @@ } }, "node_modules/@babel/helper-string-parser": { - "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz", - "integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==", + "version": "7.27.1", "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz", - "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==", + "version": "7.28.5", "license": "MIT", "engines": { "node": ">=6.9.0" @@ -606,12 +632,10 @@ } }, "node_modules/@babel/parser": { - "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.7.tgz", - "integrity": "sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg==", + "version": "7.29.2", "license": "MIT", "dependencies": { - "@babel/types": "^7.29.7" + "@babel/types": "^7.29.0" }, "bin": { "parser": "bin/babel-parser.js" @@ -1801,13 +1825,11 @@ } }, "node_modules/@babel/types": { - "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.7.tgz", - "integrity": "sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==", + "version": "7.29.0", "license": "MIT", "dependencies": { - "@babel/helper-string-parser": "^7.29.7", - "@babel/helper-validator-identifier": "^7.29.7" + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" }, "engines": { "node": ">=6.9.0" @@ -1815,7 +1837,7 @@ }, "node_modules/@bcoe/v8-coverage": { "version": "1.0.2", - "devOptional": true, + "dev": true, "license": "MIT", "engines": { "node": ">=18" @@ -1831,7 +1853,7 @@ }, "node_modules/@braidai/lang": { "version": "1.1.2", - "devOptional": true, + "dev": true, "license": "ISC" }, "node_modules/@bundled-es-modules/message-format": { @@ -1889,8 +1911,8 @@ "resolved": "packages/craftcms-browserslist-config", "link": true }, - "node_modules/@craftcms/garnish": { - "resolved": "packages/craftcms-garnish", + "node_modules/@craftcms/cp": { + "resolved": "packages/craftcms-cp", "link": true }, "node_modules/@craftcms/graphiql": { @@ -1909,10 +1931,6 @@ "resolved": "packages/craftcms-sass", "link": true }, - "node_modules/@craftcms/ui": { - "resolved": "packages/craftcms-ui", - "link": true - }, "node_modules/@craftcms/vue": { "resolved": "packages/craftcms-vue", "link": true @@ -2173,9 +2191,9 @@ } }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.1.tgz", - "integrity": "sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.0.tgz", + "integrity": "sha512-lhRUCeuOyJQURhTxl4WkpFTjIsbDayJHih5kZC1giwE+MhIzAb7mEsQMqMf18rHLsrb5qI1tafG20mLxEWcWlA==", "cpu": [ "ppc64" ], @@ -2189,9 +2207,9 @@ } }, "node_modules/@esbuild/android-arm": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.1.tgz", - "integrity": "sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.0.tgz", + "integrity": "sha512-wqh0ByljabXLKHeWXYLqoJ5jKC4XBaw6Hk08OfMrCRd2nP2ZQ5eleDZC41XHyCNgktBGYMbqnrJKq/K/lzPMSQ==", "cpu": [ "arm" ], @@ -2205,9 +2223,9 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.1.tgz", - "integrity": "sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.0.tgz", + "integrity": "sha512-+WzIXQOSaGs33tLEgYPYe/yQHf0WTU0X42Jca3y8NWMbUVhp7rUnw+vAsRC/QiDrdD31IszMrZy+qwPOPjd+rw==", "cpu": [ "arm64" ], @@ -2221,9 +2239,9 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.1.tgz", - "integrity": "sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.0.tgz", + "integrity": "sha512-+VJggoaKhk2VNNqVL7f6S189UzShHC/mR9EE8rDdSkdpN0KflSwWY/gWjDrNxxisg8Fp1ZCD9jLMo4m0OUfeUA==", "cpu": [ "x64" ], @@ -2237,9 +2255,7 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.1.tgz", - "integrity": "sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q==", + "version": "0.28.0", "cpu": [ "arm64" ], @@ -2253,9 +2269,9 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.1.tgz", - "integrity": "sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.0.tgz", + "integrity": "sha512-fyzLm/DLDl/84OCfp2f/XQ4flmORsjU7VKt8HLjvIXChJoFFOIL6pLJPH4Yhd1n1gGFF9mPwtlN5Wf82DZs+LQ==", "cpu": [ "x64" ], @@ -2269,9 +2285,9 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.1.tgz", - "integrity": "sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.0.tgz", + "integrity": "sha512-l9GeW5UZBT9k9brBYI+0WDffcRxgHQD8ShN2Ur4xWq/NFzUKm3k5lsH4PdaRgb2w7mI9u61nr2gI2mLI27Nh3Q==", "cpu": [ "arm64" ], @@ -2285,9 +2301,9 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.1.tgz", - "integrity": "sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.0.tgz", + "integrity": "sha512-BXoQai/A0wPO6Es3yFJ7APCiKGc1tdAEOgeTNy3SsB491S3aHn4S4r3e976eUnPdU+NbdtmBuLncYir2tMU9Nw==", "cpu": [ "x64" ], @@ -2301,9 +2317,9 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.1.tgz", - "integrity": "sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.0.tgz", + "integrity": "sha512-CjaaREJagqJp7iTaNQjjidaNbCKYcd4IDkzbwwxtSvjI7NZm79qiHc8HqciMddQ6CKvJT6aBd8lO9kN/ZudLlw==", "cpu": [ "arm" ], @@ -2317,9 +2333,9 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.1.tgz", - "integrity": "sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.0.tgz", + "integrity": "sha512-RVyzfb3FWsGA55n6WY0MEIEPURL1FcbhFE6BffZEMEekfCzCIMtB5yyDcFnVbTnwk+CLAgTujmV/Lgvih56W+A==", "cpu": [ "arm64" ], @@ -2333,9 +2349,9 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.1.tgz", - "integrity": "sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.0.tgz", + "integrity": "sha512-KBnSTt1kxl9x70q+ydterVdl+Cn0H18ngRMRCEQfrbqdUuntQQ0LoMZv47uB97NljZFzY6HcfqEZ2SAyIUTQBQ==", "cpu": [ "ia32" ], @@ -2349,9 +2365,9 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.1.tgz", - "integrity": "sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.0.tgz", + "integrity": "sha512-zpSlUce1mnxzgBADvxKXX5sl8aYQHo2ezvMNI8I0lbblJtp8V4odlm3Yzlj7gPyt3T8ReksE6bK+pT3WD+aJRg==", "cpu": [ "loong64" ], @@ -2365,9 +2381,9 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.1.tgz", - "integrity": "sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.0.tgz", + "integrity": "sha512-2jIfP6mmjkdmeTlsX/9vmdmhBmKADrWqN7zcdtHIeNSCH1SqIoNI63cYsjQR8J+wGa4Y5izRcSHSm8K3QWmk3w==", "cpu": [ "mips64el" ], @@ -2381,9 +2397,9 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.1.tgz", - "integrity": "sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.0.tgz", + "integrity": "sha512-bc0FE9wWeC0WBm49IQMPSPILRocGTQt3j5KPCA8os6VprfuJ7KD+5PzESSrJ6GmPIPJK965ZJHTUlSA6GNYEhg==", "cpu": [ "ppc64" ], @@ -2397,9 +2413,9 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.1.tgz", - "integrity": "sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.0.tgz", + "integrity": "sha512-SQPZOwoTTT/HXFXQJG/vBX8sOFagGqvZyXcgLA3NhIqcBv1BJU1d46c0rGcrij2B56Z2rNiSLaZOYW5cUk7yLQ==", "cpu": [ "riscv64" ], @@ -2413,9 +2429,9 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.1.tgz", - "integrity": "sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.0.tgz", + "integrity": "sha512-SCfR0HN8CEEjnYnySJTd2cw0k9OHB/YFzt5zgJEwa+wL/T/raGWYMBqwDNAC6dqFKmJYZoQBRfHjgwLHGSrn3Q==", "cpu": [ "s390x" ], @@ -2429,9 +2445,9 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.1.tgz", - "integrity": "sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.0.tgz", + "integrity": "sha512-us0dSb9iFxIi8srnpl931Nvs65it/Jd2a2K3qs7fz2WfGPHqzfzZTfec7oxZJRNPXPnNYZtanmRc4AL/JwVzHQ==", "cpu": [ "x64" ], @@ -2445,9 +2461,9 @@ } }, "node_modules/@esbuild/netbsd-arm64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.1.tgz", - "integrity": "sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.0.tgz", + "integrity": "sha512-CR/RYotgtCKwtftMwJlUU7xCVNg3lMYZ0RzTmAHSfLCXw3NtZtNpswLEj/Kkf6kEL3Gw+BpOekRX0BYCtklhUw==", "cpu": [ "arm64" ], @@ -2461,9 +2477,9 @@ } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.1.tgz", - "integrity": "sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.0.tgz", + "integrity": "sha512-nU1yhmYutL+fQ71Kxnhg8uEOdC0pwEW9entHykTgEbna2pw2dkbFSMeqjjyHZoCmt8SBkOSvV+yNmm94aUrrqw==", "cpu": [ "x64" ], @@ -2477,9 +2493,9 @@ } }, "node_modules/@esbuild/openbsd-arm64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.1.tgz", - "integrity": "sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.0.tgz", + "integrity": "sha512-cXb5vApOsRsxsEl4mcZ1XY3D4DzcoMxR/nnc4IyqYs0rTI8ZKmW6kyyg+11Z8yvgMfAEldKzP7AdP64HnSC/6g==", "cpu": [ "arm64" ], @@ -2493,9 +2509,9 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.1.tgz", - "integrity": "sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.0.tgz", + "integrity": "sha512-8wZM2qqtv9UP3mzy7HiGYNH/zjTA355mpeuA+859TyR+e+Tc08IHYpLJuMsfpDJwoLo1ikIJI8jC3GFjnRClzA==", "cpu": [ "x64" ], @@ -2509,9 +2525,9 @@ } }, "node_modules/@esbuild/openharmony-arm64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.1.tgz", - "integrity": "sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.0.tgz", + "integrity": "sha512-FLGfyizszcef5C3YtoyQDACyg95+dndv79i2EekILBofh5wpCa1KuBqOWKrEHZg3zrL3t5ouE5jgr94vA+Wb2w==", "cpu": [ "arm64" ], @@ -2525,9 +2541,9 @@ } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.1.tgz", - "integrity": "sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.0.tgz", + "integrity": "sha512-1ZgjUoEdHZZl/YlV76TSCz9Hqj9h9YmMGAgAPYd+q4SicWNX3G5GCyx9uhQWSLcbvPW8Ni7lj4gDa1T40akdlw==", "cpu": [ "x64" ], @@ -2541,9 +2557,9 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.1.tgz", - "integrity": "sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.0.tgz", + "integrity": "sha512-Q9StnDmQ/enxnpxCCLSg0oo4+34B9TdXpuyPeTedN/6+iXBJ4J+zwfQI28u/Jl40nOYAxGoNi7mFP40RUtkmUA==", "cpu": [ "arm64" ], @@ -2557,9 +2573,9 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.1.tgz", - "integrity": "sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.0.tgz", + "integrity": "sha512-zF3ag/gfiCe6U2iczcRzSYJKH1DCI+ByzSENHlM2FcDbEeo5Zd2C86Aq0tKUYAJJ1obRP84ymxIAksZUcdztHA==", "cpu": [ "ia32" ], @@ -2573,9 +2589,9 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.1.tgz", - "integrity": "sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.0.tgz", + "integrity": "sha512-pEl1bO9mfAmIC+tW5btTmrKaujg3zGtUmWNdCw/xs70FBjwAL3o9OEKNHvNmnyylD6ubxUERiEhdsL0xBQ9efw==", "cpu": [ "x64" ], @@ -2591,7 +2607,6 @@ "node_modules/@eslint-community/eslint-utils": { "version": "4.9.1", "license": "MIT", - "peer": true, "dependencies": { "eslint-visitor-keys": "^3.4.3" }, @@ -2608,7 +2623,6 @@ "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { "version": "3.4.3", "license": "Apache-2.0", - "peer": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, @@ -2619,7 +2633,6 @@ "node_modules/@eslint-community/regexpp": { "version": "4.12.2", "license": "MIT", - "peer": true, "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } @@ -2627,7 +2640,6 @@ "node_modules/@eslint/config-array": { "version": "0.21.2", "license": "Apache-2.0", - "peer": true, "dependencies": { "@eslint/object-schema": "^2.1.7", "debug": "^4.3.1", @@ -2640,7 +2652,6 @@ "node_modules/@eslint/config-helpers": { "version": "0.4.2", "license": "Apache-2.0", - "peer": true, "dependencies": { "@eslint/core": "^0.17.0" }, @@ -2651,7 +2662,6 @@ "node_modules/@eslint/core": { "version": "0.17.0", "license": "Apache-2.0", - "peer": true, "dependencies": { "@types/json-schema": "^7.0.15" }, @@ -2662,7 +2672,6 @@ "node_modules/@eslint/eslintrc": { "version": "3.3.5", "license": "MIT", - "peer": true, "dependencies": { "ajv": "^6.14.0", "debug": "^4.3.2", @@ -2684,7 +2693,6 @@ "node_modules/@eslint/eslintrc/node_modules/eslint-visitor-keys": { "version": "4.2.1", "license": "Apache-2.0", - "peer": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, @@ -2695,7 +2703,6 @@ "node_modules/@eslint/eslintrc/node_modules/espree": { "version": "10.4.0", "license": "BSD-2-Clause", - "peer": true, "dependencies": { "acorn": "^8.15.0", "acorn-jsx": "^5.3.2", @@ -2711,7 +2718,6 @@ "node_modules/@eslint/eslintrc/node_modules/globals": { "version": "14.0.0", "license": "MIT", - "peer": true, "engines": { "node": ">=18" }, @@ -2722,7 +2728,6 @@ "node_modules/@eslint/eslintrc/node_modules/ignore": { "version": "5.3.2", "license": "MIT", - "peer": true, "engines": { "node": ">= 4" } @@ -2730,7 +2735,6 @@ "node_modules/@eslint/js": { "version": "9.39.4", "license": "MIT", - "peer": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, @@ -2741,7 +2745,6 @@ "node_modules/@eslint/object-schema": { "version": "2.1.7", "license": "Apache-2.0", - "peer": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } @@ -2749,7 +2752,6 @@ "node_modules/@eslint/plugin-kit": { "version": "0.4.1", "license": "Apache-2.0", - "peer": true, "dependencies": { "@eslint/core": "^0.17.0", "levn": "^0.4.1" @@ -2826,8 +2828,6 @@ }, "node_modules/@fortawesome/fontawesome-common-types": { "version": "6.7.2", - "resolved": "https://npm.fontawesome.com/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.7.2.tgz", - "integrity": "sha512-Zs+YeHUC5fkt7Mg1l6XTniei3k4bwG/yo3iFUtZWd/pMx9g3fdvkSK9E0FOC+++phXOka78uJcYb8JaFkW52Xg==", "license": "MIT", "optional": true, "engines": { @@ -2955,7 +2955,6 @@ "node_modules/@humanfs/core": { "version": "0.19.2", "license": "Apache-2.0", - "peer": true, "dependencies": { "@humanfs/types": "^0.15.0" }, @@ -2966,7 +2965,6 @@ "node_modules/@humanfs/node": { "version": "0.16.8", "license": "Apache-2.0", - "peer": true, "dependencies": { "@humanfs/core": "^0.19.2", "@humanfs/types": "^0.15.0", @@ -2979,15 +2977,25 @@ "node_modules/@humanfs/types": { "version": "0.15.0", "license": "Apache-2.0", - "peer": true, "engines": { "node": ">=18.18.0" } }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.13.0", + "license": "Apache-2.0", + "dependencies": { + "@humanwhocodes/object-schema": "^2.0.3", + "debug": "^4.3.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, "node_modules/@humanwhocodes/module-importer": { "version": "1.0.1", "license": "Apache-2.0", - "peer": true, "engines": { "node": ">=12.22" }, @@ -2996,10 +3004,13 @@ "url": "https://github.com/sponsors/nzakas" } }, + "node_modules/@humanwhocodes/object-schema": { + "version": "2.0.3", + "license": "BSD-3-Clause" + }, "node_modules/@humanwhocodes/retry": { "version": "0.4.3", "license": "Apache-2.0", - "peer": true, "engines": { "node": ">=18.18" }, @@ -3348,7 +3359,7 @@ }, "node_modules/@loaderkit/resolve": { "version": "1.0.4", - "devOptional": true, + "dev": true, "license": "ISC", "dependencies": { "@braidai/lang": "^1.0.0" @@ -3844,15 +3855,6 @@ "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@oxc-project/runtime": { - "version": "0.141.0", - "resolved": "https://registry.npmjs.org/@oxc-project/runtime/-/runtime-0.141.0.tgz", - "integrity": "sha512-Z/6jQ0dyvE2fVjMUO7GoD4h+3q0G4lI4BWQNjaPhC4RPxaS4hF1b7/QYKB/Tl+KAQwqqKgMF54ukR/VvV5FILg==", - "license": "MIT", - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, "node_modules/@oxc-project/types": { "version": "0.127.0", "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.127.0.tgz", @@ -4123,26 +4125,44 @@ "win32" ] }, - "node_modules/@oxfmt/binding-android-arm-eabi": { - "version": "0.60.0", - "resolved": "https://registry.npmjs.org/@oxfmt/binding-android-arm-eabi/-/binding-android-arm-eabi-0.60.0.tgz", - "integrity": "sha512-1q4q4Jc8FlOMVojEisyFAVyl8h1yawNv6phjgmhGVEDeyeOdsSnSr9x0+D4mOnEKvpO5L4mxKZ/DP9X6U3A/Mw==", - "cpu": [ - "arm" - ], + "node_modules/@parcel/watcher": { + "version": "2.5.1", + "hasInstallScript": true, "license": "MIT", "optional": true, - "os": [ - "android" - ], + "dependencies": { + "detect-libc": "^1.0.3", + "is-glob": "^4.0.3", + "micromatch": "^4.0.5", + "node-addon-api": "^7.0.0" + }, "engines": { - "node": "^20.19.0 || >=22.12.0" + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "@parcel/watcher-android-arm64": "2.5.1", + "@parcel/watcher-darwin-arm64": "2.5.1", + "@parcel/watcher-darwin-x64": "2.5.1", + "@parcel/watcher-freebsd-x64": "2.5.1", + "@parcel/watcher-linux-arm-glibc": "2.5.1", + "@parcel/watcher-linux-arm-musl": "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-arm64": "2.5.1", + "@parcel/watcher-win32-ia32": "2.5.1", + "@parcel/watcher-win32-x64": "2.5.1" } }, - "node_modules/@oxfmt/binding-android-arm64": { - "version": "0.60.0", - "resolved": "https://registry.npmjs.org/@oxfmt/binding-android-arm64/-/binding-android-arm64-0.60.0.tgz", - "integrity": "sha512-tD41I6nCt9k8SQXft0CSjjU9jg6SwG7uMu7PxodSEHXl+GDW0868oy6tTtoJkyUze8YKFgTpz/k5LuPUnFiGLw==", + "node_modules/@parcel/watcher-android-arm64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.1.tgz", + "integrity": "sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA==", "cpu": [ "arm64" ], @@ -4152,13 +4172,15 @@ "android" ], "engines": { - "node": "^20.19.0 || >=22.12.0" + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, - "node_modules/@oxfmt/binding-darwin-arm64": { - "version": "0.60.0", - "resolved": "https://registry.npmjs.org/@oxfmt/binding-darwin-arm64/-/binding-darwin-arm64-0.60.0.tgz", - "integrity": "sha512-TTpzPug96Zxdyb46KvTyIUQDdsqbumXh2TKG9C23PCT0kF7JkW56Z/quPuG9rqOFKQIi1gpRNZ7DX18LwxXPnw==", + "node_modules/@parcel/watcher-darwin-arm64": { + "version": "2.5.1", "cpu": [ "arm64" ], @@ -4168,13 +4190,17 @@ "darwin" ], "engines": { - "node": "^20.19.0 || >=22.12.0" + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, - "node_modules/@oxfmt/binding-darwin-x64": { - "version": "0.60.0", - "resolved": "https://registry.npmjs.org/@oxfmt/binding-darwin-x64/-/binding-darwin-x64-0.60.0.tgz", - "integrity": "sha512-CnOoWgQ7L+JL/YQaRJ+NyATciSfcftncm7y3kqyte1cGtFEGnStaCd1TAyrinkfQ7nRBfHrTs1/vTwUJr3WF2Q==", + "node_modules/@parcel/watcher-darwin-x64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.1.tgz", + "integrity": "sha512-1ZXDthrnNmwv10A0/3AJNZ9JGlzrF82i3gNQcWOzd7nJ8aj+ILyW1MTxVk35Db0u91oD5Nlk9MBiujMlwmeXZg==", "cpu": [ "x64" ], @@ -4184,13 +4210,17 @@ "darwin" ], "engines": { - "node": "^20.19.0 || >=22.12.0" + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, - "node_modules/@oxfmt/binding-freebsd-x64": { - "version": "0.60.0", - "resolved": "https://registry.npmjs.org/@oxfmt/binding-freebsd-x64/-/binding-freebsd-x64-0.60.0.tgz", - "integrity": "sha512-ychJo7S3hZxdO6eDZ9zM6F2lM9fpJS3EKS5CAUSWyprdLYxTu4gbaUKV/VBPTcMJwQa2Bpo+643y3OJ537pihA==", + "node_modules/@parcel/watcher-freebsd-x64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.1.tgz", + "integrity": "sha512-SI4eljM7Flp9yPuKi8W0ird8TI/JK6CSxju3NojVI6BjHsTyK7zxA9urjVjEKJ5MBYC+bLmMcbAWlZ+rFkLpJQ==", "cpu": [ "x64" ], @@ -4200,13 +4230,17 @@ "freebsd" ], "engines": { - "node": "^20.19.0 || >=22.12.0" + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, - "node_modules/@oxfmt/binding-linux-arm-gnueabihf": { - "version": "0.60.0", - "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-0.60.0.tgz", - "integrity": "sha512-36IH5o55T2Fx7E0feDttt+mifxN6yk9pWv4KfhAIsP0dFnUq27331OwbpOsZdoXF9soOLWm7mQUz5+UUmyec4g==", + "node_modules/@parcel/watcher-linux-arm-glibc": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.1.tgz", + "integrity": "sha512-RCdZlEyTs8geyBkkcnPWvtXLY44BCeZKmGYRtSgtwwnHR4dxfHRG3gR99XdMEdQ7KeiDdasJwwvNSF5jKtDwdA==", "cpu": [ "arm" ], @@ -4216,13 +4250,17 @@ "linux" ], "engines": { - "node": "^20.19.0 || >=22.12.0" + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, - "node_modules/@oxfmt/binding-linux-arm-musleabihf": { - "version": "0.60.0", - "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-arm-musleabihf/-/binding-linux-arm-musleabihf-0.60.0.tgz", - "integrity": "sha512-G1Ve7lAa6sFBolVI2LWHfEAqy0YKh4vnioH8uYO9kAEdgM7mR40IksIx9/Zk4+vbYew/sGa4J9Q4tZ3n9gXDHA==", + "node_modules/@parcel/watcher-linux-arm-musl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.1.tgz", + "integrity": "sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q==", "cpu": [ "arm" ], @@ -4232,56 +4270,59 @@ "linux" ], "engines": { - "node": "^20.19.0 || >=22.12.0" + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, - "node_modules/@oxfmt/binding-linux-arm64-gnu": { - "version": "0.60.0", - "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-0.60.0.tgz", - "integrity": "sha512-LTQdRBf6uzj/h7Xk6lKzbGD2hrF/fK4YI9LIN1c0509tPUn8wRa3mCmrFQpEWJPLYGFrLFFMTYW1Ljj6VqW2Hw==", + "node_modules/@parcel/watcher-linux-arm64-glibc": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.1.tgz", + "integrity": "sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==", "cpu": [ "arm64" ], - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": "^20.19.0 || >=22.12.0" + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, - "node_modules/@oxfmt/binding-linux-arm64-musl": { - "version": "0.60.0", - "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-arm64-musl/-/binding-linux-arm64-musl-0.60.0.tgz", - "integrity": "sha512-2JMo3XPxMPx3hiqddSZYyaH+fKJm6cz0u8n1naYjP/CdOQOZW34i8lKBUfmbWiuFvd6KoYXLmhAyBuvojsYS7Q==", + "node_modules/@parcel/watcher-linux-arm64-musl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.1.tgz", + "integrity": "sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg==", "cpu": [ "arm64" ], - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": "^20.19.0 || >=22.12.0" + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, - "node_modules/@oxfmt/binding-linux-ppc64-gnu": { - "version": "0.60.0", - "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-0.60.0.tgz", - "integrity": "sha512-L3C+nBD13lr306tr/PjM3RMll+BVqgFrIgUyoeHuai5oueJrRLgO3j+GO5/Cbhtkf5PSlHYTI1JY7iqBd1qa6A==", + "node_modules/@parcel/watcher-linux-x64-glibc": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.1.tgz", + "integrity": "sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A==", "cpu": [ - "ppc64" - ], - "libc": [ - "glibc" + "x64" ], "license": "MIT", "optional": true, @@ -4289,18 +4330,19 @@ "linux" ], "engines": { - "node": "^20.19.0 || >=22.12.0" + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, - "node_modules/@oxfmt/binding-linux-riscv64-gnu": { - "version": "0.60.0", - "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-riscv64-gnu/-/binding-linux-riscv64-gnu-0.60.0.tgz", - "integrity": "sha512-M4MsmvqlxFiPtSRGyBYQSZxchEf463AOyd+Dh4/9xDpjWBsRtDUTDMFN5EdHinjVK1/eDJQ8MLpcYjpYayaCnA==", + "node_modules/@parcel/watcher-linux-x64-musl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.1.tgz", + "integrity": "sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg==", "cpu": [ - "riscv64" - ], - "libc": [ - "glibc" + "x64" ], "license": "MIT", "optional": true, @@ -4308,851 +4350,64 @@ "linux" ], "engines": { - "node": "^20.19.0 || >=22.12.0" + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, - "node_modules/@oxfmt/binding-linux-riscv64-musl": { - "version": "0.60.0", - "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-riscv64-musl/-/binding-linux-riscv64-musl-0.60.0.tgz", - "integrity": "sha512-OH+9UskYuxRB+GxqdGkVN8f5UpwhqG8YscNo1wl8+KJ62cd7wZdGga6iGLJIf8kibF1WBwvlfDUx3cez/VXwFg==", + "node_modules/@parcel/watcher-win32-arm64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.1.tgz", + "integrity": "sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw==", "cpu": [ - "riscv64" - ], - "libc": [ - "musl" + "arm64" ], "license": "MIT", "optional": true, "os": [ - "linux" + "win32" ], "engines": { - "node": "^20.19.0 || >=22.12.0" + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, - "node_modules/@oxfmt/binding-linux-s390x-gnu": { - "version": "0.60.0", - "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-0.60.0.tgz", - "integrity": "sha512-y7AAFutt9wFWBFOAn6+BHaV39usZmcr3YYH2385f+NHgPNpIF9HpqKp0jgUxPaUOCyG3oaX5VhJduL1Nw164rw==", + "node_modules/@parcel/watcher-win32-ia32": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.1.tgz", + "integrity": "sha512-c2KkcVN+NJmuA7CGlaGD1qJh1cLfDnQsHjE89E60vUEMlqduHGCdCLJCID5geFVM0dOtA3ZiIO8BoEQmzQVfpQ==", "cpu": [ - "s390x" - ], - "libc": [ - "glibc" + "ia32" ], "license": "MIT", "optional": true, "os": [ - "linux" + "win32" ], "engines": { - "node": "^20.19.0 || >=22.12.0" + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, - "node_modules/@oxfmt/binding-linux-x64-gnu": { - "version": "0.60.0", - "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-x64-gnu/-/binding-linux-x64-gnu-0.60.0.tgz", - "integrity": "sha512-yKZ9+CXAI+1RO5nH/4Z/9M6DAsfOzd5bw/gtWk81KB4mpalMaRRSXfouc5/tHxazDmBek55HNPepNYBgaCew0Q==", + "node_modules/@parcel/watcher-win32-x64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.1.tgz", + "integrity": "sha512-9lHBdJITeNR++EvSQVUcaZoWupyHfXe1jZvGZ06O/5MflPcuPLtEphScIBL+AiCWBO46tDSHzWyD0uDmmZqsgA==", "cpu": [ "x64" ], - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxfmt/binding-linux-x64-musl": { - "version": "0.60.0", - "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-x64-musl/-/binding-linux-x64-musl-0.60.0.tgz", - "integrity": "sha512-bCUGaF6hJOYnQzLJdHLZbvGsOd5oSvGAyJhPAKum2uyLYUuXmP8vqg690DWi2hqcnIoYpqSqCrjzE5aiUAgwQg==", - "cpu": [ - "x64" - ], - "libc": [ - "musl" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxfmt/binding-openharmony-arm64": { - "version": "0.60.0", - "resolved": "https://registry.npmjs.org/@oxfmt/binding-openharmony-arm64/-/binding-openharmony-arm64-0.60.0.tgz", - "integrity": "sha512-GrUeZOvzP30ExxfCuQiyofuUGI+OmvAgFwOO5w5p9mGPlxcyuqI+6Sy9fAKFFfLQrqKYWFgc5sYA2Unj/29nPg==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxfmt/binding-win32-arm64-msvc": { - "version": "0.60.0", - "resolved": "https://registry.npmjs.org/@oxfmt/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-0.60.0.tgz", - "integrity": "sha512-WD4Q954kUl2TDJV/6q7UnE2rlKk047kXLJsr4bJ2mXRaAqNXcmV3nwKUsGCc3mz/jYDBnXtJEaBErJEybK8iQQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxfmt/binding-win32-ia32-msvc": { - "version": "0.60.0", - "resolved": "https://registry.npmjs.org/@oxfmt/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-0.60.0.tgz", - "integrity": "sha512-HqDekjr8JXzVDUP1YthDZ1Y3CBEcuZT4WX3B+1kaxj8CvZA8Y2YhcEsXqoSop3tVsgjACxjnFQFDkBo0r/jq1Q==", - "cpu": [ - "ia32" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxfmt/binding-win32-x64-msvc": { - "version": "0.60.0", - "resolved": "https://registry.npmjs.org/@oxfmt/binding-win32-x64-msvc/-/binding-win32-x64-msvc-0.60.0.tgz", - "integrity": "sha512-tz78yhmGPKboTMHCHSaUqXK8JrmoSejgDcWeqAtg2s07ZGKQ3rH5Jn8NuXPGNG33CDbY2e9NoQWXIVEmKO21Rw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxlint-tsgolint/darwin-arm64": { - "version": "7.0.2001", - "resolved": "https://registry.npmjs.org/@oxlint-tsgolint/darwin-arm64/-/darwin-arm64-7.0.2001.tgz", - "integrity": "sha512-CUJEdbSZ54+Xy9OXqOhWLTKZKV0BBiV7C2i/ygyVmXtkUNXx5YCzN8DpSSshTAKktoL7S+tnQ/ftFG/i7X896w==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@oxlint-tsgolint/darwin-x64": { - "version": "7.0.2001", - "resolved": "https://registry.npmjs.org/@oxlint-tsgolint/darwin-x64/-/darwin-x64-7.0.2001.tgz", - "integrity": "sha512-pXfBb5BqONCcgrXQNUZWXgiYmRSWJzd97S8i41VVOh6ut0tyo+cJ5FKFpczDHxiVNfj/3e7c9B4MtztNdpIVCw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@oxlint-tsgolint/linux-arm64": { - "version": "7.0.2001", - "resolved": "https://registry.npmjs.org/@oxlint-tsgolint/linux-arm64/-/linux-arm64-7.0.2001.tgz", - "integrity": "sha512-roP7zujb/QDPzDwEKsFFpzNHHy91/Y7oX9vQXk78ekyZtcQj1QXDIMH33gjDdHBfRl4K9pZ36xhRgrP4Zr+R8A==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@oxlint-tsgolint/linux-x64": { - "version": "7.0.2001", - "resolved": "https://registry.npmjs.org/@oxlint-tsgolint/linux-x64/-/linux-x64-7.0.2001.tgz", - "integrity": "sha512-UDezNqdECVmngu2TPnjaS1YoAmcTaBoI5lV9vk3VahBxoi+I5r9k3iJTT7qZoYWOXTD/7T7bNcwRgrocR6BscQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@oxlint-tsgolint/win32-arm64": { - "version": "7.0.2001", - "resolved": "https://registry.npmjs.org/@oxlint-tsgolint/win32-arm64/-/win32-arm64-7.0.2001.tgz", - "integrity": "sha512-uJZhqB6pdXLuN+AD1F5082byyQti/NPmJA77GtcFlmT2HzRelqbNls3SaIqxpjdFgvSBF9g0yOKGBkGFg7kX8Q==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@oxlint-tsgolint/win32-x64": { - "version": "7.0.2001", - "resolved": "https://registry.npmjs.org/@oxlint-tsgolint/win32-x64/-/win32-x64-7.0.2001.tgz", - "integrity": "sha512-FkDRm8hx9OwzGQqyWG1tO5QrTLRApff9DzSgpz9QZau37BR8d1VYKOxMLGf6shPZntJFoTwIIJYT68VndYDCog==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@oxlint/binding-android-arm-eabi": { - "version": "1.75.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-android-arm-eabi/-/binding-android-arm-eabi-1.75.0.tgz", - "integrity": "sha512-lutovtFzJqlRaqpZrCqSSGaHZzl9nIxxpjLzhSRLunN6dCLylj0uzlCyQGaQDIys7rrv8kVXiFO+R4Zpn0bX7g==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxlint/binding-android-arm64": { - "version": "1.75.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-android-arm64/-/binding-android-arm64-1.75.0.tgz", - "integrity": "sha512-hXI0hDgHkw4w5nfru72aG7y+2iQJmC4waH/KV6H/hbgA6yAP5jYNx0P9yug15Hs0tWl/+mda3Jjn/2gmDT48tw==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxlint/binding-darwin-arm64": { - "version": "1.75.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-darwin-arm64/-/binding-darwin-arm64-1.75.0.tgz", - "integrity": "sha512-D91BWbK/dMYfCcrghspPIuKs2D9LF4Z/OabVSQjw1AO6PWxArD7teDA48bm0ySFqWDaPVqmQRl5GMWNglTXyrQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxlint/binding-darwin-x64": { - "version": "1.75.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-darwin-x64/-/binding-darwin-x64-1.75.0.tgz", - "integrity": "sha512-02mpwzf12BonZ6PT0TuQoomvEh2kVl2WGBIKWezCyToIS+rYkQZ6GXnARBAl9A4Ovm2V+Xe7M4KretyqmmcnJQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxlint/binding-freebsd-x64": { - "version": "1.75.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-freebsd-x64/-/binding-freebsd-x64-1.75.0.tgz", - "integrity": "sha512-qZJgLnDaBsiL5YESx2t/TZ8eXkL9fEkKoXEdzegROhlz9A0lgyGnZ0dAzJrh7LJAHQl2K9RdRueN2s/9N7+odg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxlint/binding-linux-arm-gnueabihf": { - "version": "1.75.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.75.0.tgz", - "integrity": "sha512-7XlaWA5BJD3XpCfrEqjEe6Zseeb14S7QGa304XfwKignRaKQ+eIj775BQ7nIslggWickl4IsPUFqJ+/gAyNHVg==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxlint/binding-linux-arm-musleabihf": { - "version": "1.75.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-arm-musleabihf/-/binding-linux-arm-musleabihf-1.75.0.tgz", - "integrity": "sha512-av6Tpv8yrcMMMOadOqENBhlsLRcGFXXwoQ0hzHhsmS9FJ4Wioy8we427GbcMe2XTxmL2e60T67H1Dyr3up+tAA==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxlint/binding-linux-arm64-gnu": { - "version": "1.75.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.75.0.tgz", - "integrity": "sha512-WcUhd8fHT5plrA14lANevl+hOl815mVI5t2hU21oFWrZKFXIVV/Sr4rWQV0NzSvzBupbMLNc5ErEA6Ehxh5jMg==", - "cpu": [ - "arm64" - ], - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxlint/binding-linux-arm64-musl": { - "version": "1.75.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.75.0.tgz", - "integrity": "sha512-UWzp5wRHFe/ESO3+eEaxXsTkYTGLYjnTsi/I5neEacXSItQ6WNleapfOAeA4x2b8nyhJ4uQxqvtv9pHv8kWJtQ==", - "cpu": [ - "arm64" - ], - "libc": [ - "musl" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxlint/binding-linux-ppc64-gnu": { - "version": "1.75.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.75.0.tgz", - "integrity": "sha512-XEVRwGMLKCUKrvhLAz4F6AIh8MJrQVdSZtAmPpRZt9tGPsUnamPOcl3dS/ZQzJnar/Ymgc//+xho0L60Emzuxg==", - "cpu": [ - "ppc64" - ], - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxlint/binding-linux-riscv64-gnu": { - "version": "1.75.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-riscv64-gnu/-/binding-linux-riscv64-gnu-1.75.0.tgz", - "integrity": "sha512-mAG4DUXqfLC8cTjMD2kt3jDmVzFREYtDyeLNdLdsCcBc4Zbl2EMuiFektGBilQwkNjYnMvCqJs55U+Hyb+b+jw==", - "cpu": [ - "riscv64" - ], - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxlint/binding-linux-riscv64-musl": { - "version": "1.75.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-riscv64-musl/-/binding-linux-riscv64-musl-1.75.0.tgz", - "integrity": "sha512-95hrAvriAlI+pekSomTFIn0+bawMDlDwTNVmdjsFusTHyL2JWh7TWvRNG/Lkim72uN8OiCcO9wcaC6omLP5E3w==", - "cpu": [ - "riscv64" - ], - "libc": [ - "musl" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxlint/binding-linux-s390x-gnu": { - "version": "1.75.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.75.0.tgz", - "integrity": "sha512-4b6f2+FrtruAESrCqIKcrarzfrSx+wk2QNcp+RT91/Prc+pMQMAfyZ1rG1c3tFQNl8Bc616tx40uNXyxNBRPbQ==", - "cpu": [ - "s390x" - ], - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxlint/binding-linux-x64-gnu": { - "version": "1.75.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.75.0.tgz", - "integrity": "sha512-nshAhrUvXFUWOvqQ2soIw7HFNWvpvEV4o0cYSqPtzLiPF5gKyYTDOOTJ6Rn8g8K/iGvPIrbDA4v8+5MvnjJrrg==", - "cpu": [ - "x64" - ], - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxlint/binding-linux-x64-musl": { - "version": "1.75.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-x64-musl/-/binding-linux-x64-musl-1.75.0.tgz", - "integrity": "sha512-e4jNxLKnxLC6sYBQRxrI2pgIIxnmMtF8U/VwNYcjTT/CLS+spH624cYVnj07bTKwaEWT37/e025isOs6j/0xqA==", - "cpu": [ - "x64" - ], - "libc": [ - "musl" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxlint/binding-openharmony-arm64": { - "version": "1.75.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-openharmony-arm64/-/binding-openharmony-arm64-1.75.0.tgz", - "integrity": "sha512-hZ2lH+1qLf/DiEP9UWuQTK2JWj/BgvMB4jhIV4SmNU1wfEiYYX4TynQyAZXx0j9X4qRYizAL042SKaV+8ynh4w==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxlint/binding-win32-arm64-msvc": { - "version": "1.75.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.75.0.tgz", - "integrity": "sha512-Ilj6PNzGDS3bCU0MSJH7Msh0NhH+T/mRp2shwg+q+GHeVlPwP5LEboW96aW+3kVKFk6zYZy1Xi5pZkqZh6X8KQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxlint/binding-win32-ia32-msvc": { - "version": "1.75.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-1.75.0.tgz", - "integrity": "sha512-QVit2nOEOiPhkmsrksPSkoGCdnZRNkspt8fwoYyP09te1VEbnSj4LAxua4rc8FKTmWkySVe05j8iz9GXYfF1AQ==", - "cpu": [ - "ia32" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxlint/binding-win32-x64-msvc": { - "version": "1.75.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.75.0.tgz", - "integrity": "sha512-DSxnNkBUAYARPwJtR12Ig3deWr8w0H997xP6jy33i+e0SyYJw8FKuz4+cZtpmPEhQmvlPJE3X/2vNxDmLkd/rA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxlint/plugins": { - "version": "1.73.0", - "resolved": "https://registry.npmjs.org/@oxlint/plugins/-/plugins-1.73.0.tgz", - "integrity": "sha512-OhgMQeMmZA0dcFcX4/priaJZWdFECxiClgq6mRX6aatZEcV9PbKC3P3/v8U1hVjviT1i5U+vR8lAtBV6m4FXAA==", - "devOptional": true, - "license": "MIT", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/Boshen" - } - }, - "node_modules/@parcel/watcher": { - "version": "2.5.1", - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "dependencies": { - "detect-libc": "^1.0.3", - "is-glob": "^4.0.3", - "micromatch": "^4.0.5", - "node-addon-api": "^7.0.0" - }, - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - }, - "optionalDependencies": { - "@parcel/watcher-android-arm64": "2.5.1", - "@parcel/watcher-darwin-arm64": "2.5.1", - "@parcel/watcher-darwin-x64": "2.5.1", - "@parcel/watcher-freebsd-x64": "2.5.1", - "@parcel/watcher-linux-arm-glibc": "2.5.1", - "@parcel/watcher-linux-arm-musl": "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-arm64": "2.5.1", - "@parcel/watcher-win32-ia32": "2.5.1", - "@parcel/watcher-win32-x64": "2.5.1" - } - }, - "node_modules/@parcel/watcher-android-arm64": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.1.tgz", - "integrity": "sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-darwin-arm64": { - "version": "2.5.1", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-darwin-x64": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.1.tgz", - "integrity": "sha512-1ZXDthrnNmwv10A0/3AJNZ9JGlzrF82i3gNQcWOzd7nJ8aj+ILyW1MTxVk35Db0u91oD5Nlk9MBiujMlwmeXZg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-freebsd-x64": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.1.tgz", - "integrity": "sha512-SI4eljM7Flp9yPuKi8W0ird8TI/JK6CSxju3NojVI6BjHsTyK7zxA9urjVjEKJ5MBYC+bLmMcbAWlZ+rFkLpJQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-linux-arm-glibc": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.1.tgz", - "integrity": "sha512-RCdZlEyTs8geyBkkcnPWvtXLY44BCeZKmGYRtSgtwwnHR4dxfHRG3gR99XdMEdQ7KeiDdasJwwvNSF5jKtDwdA==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-linux-arm-musl": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.1.tgz", - "integrity": "sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-linux-arm64-glibc": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.1.tgz", - "integrity": "sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-linux-arm64-musl": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.1.tgz", - "integrity": "sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-linux-x64-glibc": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.1.tgz", - "integrity": "sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-linux-x64-musl": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.1.tgz", - "integrity": "sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-win32-arm64": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.1.tgz", - "integrity": "sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-win32-ia32": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.1.tgz", - "integrity": "sha512-c2KkcVN+NJmuA7CGlaGD1qJh1cLfDnQsHjE89E60vUEMlqduHGCdCLJCID5geFVM0dOtA3ZiIO8BoEQmzQVfpQ==", - "cpu": [ - "ia32" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-win32-x64": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.1.tgz", - "integrity": "sha512-9lHBdJITeNR++EvSQVUcaZoWupyHfXe1jZvGZ06O/5MflPcuPLtEphScIBL+AiCWBO46tDSHzWyD0uDmmZqsgA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" + "win32" ], "engines": { "node": ">= 10.0.0" @@ -5207,6 +4462,32 @@ "url": "https://opencollective.com/popperjs" } }, + "node_modules/@quansync/fs": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "quansync": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sxzz" + } + }, + "node_modules/@quansync/fs/node_modules/quansync": { + "version": "1.0.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/antfu" + }, + { + "type": "individual", + "url": "https://github.com/sponsors/sxzz" + } + ], + "license": "MIT" + }, "node_modules/@radix-ui/primitive": { "version": "1.1.3", "license": "MIT" @@ -5865,6 +5146,253 @@ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, + "node_modules/@rolldown/binding-android-arm64": { + "version": "1.0.0-rc.17", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.0-rc.17.tgz", + "integrity": "sha512-s70pVGhw4zqGeFnXWvAzJDlvxhlRollagdCCKRgOsgUOH3N1l0LIxf83AtGzmb5SiVM4Hjl5HyarMRfdfj3DaQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-x64": { + "version": "1.0.0-rc.17", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.0-rc.17.tgz", + "integrity": "sha512-SUSDOI6WwUVNcWxd02QEBjLdY1VPHvlEkw6T/8nYG322iYWCTxRb1vzk4E+mWWYehTp7ERibq54LSJGjmouOsw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-freebsd-x64": { + "version": "1.0.0-rc.17", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.0-rc.17.tgz", + "integrity": "sha512-hwnz3nw9dbJ05EDO/PvcjaaewqqDy7Y1rn1UO81l8iIK1GjenME75dl16ajbvSSMfv66WXSRCYKIqfgq2KCfxw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm-gnueabihf": { + "version": "1.0.0-rc.17", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.0-rc.17.tgz", + "integrity": "sha512-IS+W7epTcwANmFSQFrS1SivEXHtl1JtuQA9wlxrZTcNi6mx+FDOYrakGevvvTwgj2JvWiK8B29/qD9BELZPyXQ==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-gnu": { + "version": "1.0.0-rc.17", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.0-rc.17.tgz", + "integrity": "sha512-e6usGaHKW5BMNZOymS1UcEYGowQMWcgZ71Z17Sl/h2+ZziNJ1a9n3Zvcz6LdRyIW5572wBCTH/Z+bKuZouGk9Q==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-musl": { + "version": "1.0.0-rc.17", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.0-rc.17.tgz", + "integrity": "sha512-b/CgbwAJpmrRLp02RPfhbudf5tZnN9nsPWK82znefso832etkem8H7FSZwxrOI9djcdTP7U6YfNhbRnh7djErg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-ppc64-gnu": { + "version": "1.0.0-rc.17", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.0-rc.17.tgz", + "integrity": "sha512-4EII1iNGRUN5WwGbF/kOh/EIkoDN9HsupgLQoXfY+D1oyJm7/F4t5PYU5n8SWZgG0FEwakyM8pGgwcBYruGTlA==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-s390x-gnu": { + "version": "1.0.0-rc.17", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.0-rc.17.tgz", + "integrity": "sha512-AH8oq3XqQo4IibpVXvPeLDI5pzkpYn0WiZAfT05kFzoJ6tQNzwRdDYQ45M8I/gslbodRZwW8uxLhbSBbkv96rA==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-x64-gnu": { + "version": "1.0.0-rc.17", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.0-rc.17.tgz", + "integrity": "sha512-cLnjV3xfo7KslbU41Z7z8BH/E1y5mzUYzAqih1d1MDaIGZRCMqTijqLv76/P7fyHuvUcfGsIpqCdddbxLLK9rA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-x64-musl": { + "version": "1.0.0-rc.17", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.0-rc.17.tgz", + "integrity": "sha512-0phclDw1spsL7dUB37sIARuis2tAgomCJXAHZlpt8PXZ4Ba0dRP1e+66lsRqrfhISeN9bEGNjQs+T/Fbd7oYGw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-openharmony-arm64": { + "version": "1.0.0-rc.17", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.0-rc.17.tgz", + "integrity": "sha512-0ag/hEgXOwgw4t8QyQvUCxvEg+V0KBcA6YuOx9g0r02MprutRF5dyljgm3EmR02O292UX7UeS6HzWHAl6KgyhA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-wasm32-wasi": { + "version": "1.0.0-rc.17", + "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.0-rc.17.tgz", + "integrity": "sha512-LEXei6vo0E5wTGwpkJ4KoT3OZJRnglwldt5ziLzOlc6qqb55z4tWNq2A+PFqCJuvWWdP53CVhG1Z9NtToDPJrA==", + "cpu": [ + "wasm32" + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "1.10.0", + "@emnapi/runtime": "1.10.0", + "@napi-rs/wasm-runtime": "^1.1.4" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-wasm32-wasi/node_modules/@emnapi/core": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz", + "integrity": "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==", + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.2.1", + "tslib": "^2.4.0" + } + }, + "node_modules/@rolldown/binding-wasm32-wasi/node_modules/@emnapi/runtime": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz", + "integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@rolldown/binding-win32-arm64-msvc": { + "version": "1.0.0-rc.17", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0-rc.17.tgz", + "integrity": "sha512-gUmyzBl3SPMa6hrqFUth9sVfcLBlYsbMzBx5PlexMroZStgzGqlZ26pYG89rBb45Mnia+oil6YAIFeEWGWhoZA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-win32-x64-msvc": { + "version": "1.0.0-rc.17", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.0-rc.17.tgz", + "integrity": "sha512-3hkiolcUAvPB9FLb3UZdfjVVNWherN1f/skkGWJP/fgSQhYUZpSIRr0/I8ZK9TkF3F7kxvJAk0+IcKvPHk9qQg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, "node_modules/@rolldown/pluginutils": { "version": "1.0.0-rc.13", "dev": true, @@ -5899,7 +5427,6 @@ "node_modules/@selectize/selectize": { "version": "0.15.2", "resolved": "git+ssh://git@github.com/selectize/selectize.js.git#e6ca6d3ba8f902c38da157f2caf7962c38e82095", - "integrity": "sha512-+naiygi4eHpMRg11JNtVDToP2LvD0uOd6cjrsHDpxXLnLYn1CrBwWhsIpQO1TAAyj5rPyJe9MYJi8dluxUafaA==", "license": "Apache-2.0", "engines": { "node": "*" @@ -5984,9 +5511,9 @@ "license": "MIT" }, "node_modules/@storybook/addon-a11y": { - "version": "10.5.5", - "resolved": "https://registry.npmjs.org/@storybook/addon-a11y/-/addon-a11y-10.5.5.tgz", - "integrity": "sha512-nsMnSRe7pzepXIkUUqI/rL7sp8juXOluyypU4Dz0UuYHhw/cKaxfzuO+3WJN5EtEr/gcnKYb4awxH/duPGavUw==", + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/@storybook/addon-a11y/-/addon-a11y-10.4.1.tgz", + "integrity": "sha512-MGft/IXjJ20a9KbaSVG9bHTAAoanbucKrgEiJJRNqpim8DsXA01+XTdSk17LmiOCB203Rrq9mWgdQ6+79cc8iA==", "dev": true, "license": "MIT", "dependencies": { @@ -5998,20 +5525,20 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^10.5.5" + "storybook": "^10.4.1" } }, "node_modules/@storybook/addon-docs": { - "version": "10.5.5", - "resolved": "https://registry.npmjs.org/@storybook/addon-docs/-/addon-docs-10.5.5.tgz", - "integrity": "sha512-0YpKlimS4XE0kQ8Maa5coeefQxdyDrBHg1wOP3WTPuBe4FolFSCDveR0ge2+vuUBk+fZfn2+l+3Q2jmAWaRGDg==", + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/@storybook/addon-docs/-/addon-docs-10.4.1.tgz", + "integrity": "sha512-IYqUdjoZe4VO2LFZlKL/gwy7DsQSWCq6hX+zc1MBmZo04yycDASk1tte57n9pdlW3ajw9yYMF/+lVBi+xQjyvw==", "dev": true, "license": "MIT", "dependencies": { "@mdx-js/react": "^3.0.0", - "@storybook/csf-plugin": "10.5.5", + "@storybook/csf-plugin": "10.4.1", "@storybook/icons": "^2.0.2", - "@storybook/react-dom-shim": "10.5.5", + "@storybook/react-dom-shim": "10.4.1", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "ts-dedent": "^2.0.0" @@ -6022,7 +5549,7 @@ }, "peerDependencies": { "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", - "storybook": "^10.5.5" + "storybook": "^10.4.1" }, "peerDependenciesMeta": { "@types/react": { @@ -6031,9 +5558,9 @@ } }, "node_modules/@storybook/addon-themes": { - "version": "10.5.5", - "resolved": "https://registry.npmjs.org/@storybook/addon-themes/-/addon-themes-10.5.5.tgz", - "integrity": "sha512-ENZCJkvTdGYBRuaE3tEE6jRilMRdGgfYUhnFNEUXAg4II2iVYg9mnrq6tuQfwSVjGuEOTAUen/3YV+l7U4oOOA==", + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/@storybook/addon-themes/-/addon-themes-10.4.1.tgz", + "integrity": "sha512-nxNskZwpgptCUWyci+jiM5IrKY6xSaTpv3xzgkL6NCU+5PyCxyp0Z6jE8NDvew9jolzOC9pBhGJAW26A/jbFqg==", "dev": true, "license": "MIT", "dependencies": { @@ -6044,13 +5571,13 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^10.5.5" + "storybook": "^10.4.1" } }, "node_modules/@storybook/addon-vitest": { - "version": "10.5.5", - "resolved": "https://registry.npmjs.org/@storybook/addon-vitest/-/addon-vitest-10.5.5.tgz", - "integrity": "sha512-Ymq9ErkSkYiIDuqpJ2+hE5GCQ5J6TCLOWhutqArvwaeAO+HAibM82XNExpJ1/kvPqk9y961GDPkv2W15I88JIw==", + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/@storybook/addon-vitest/-/addon-vitest-10.4.1.tgz", + "integrity": "sha512-ymrX9EOou1x3d21iDhjP3j3XfhOAiflhlPZWKcipULBoJCq/aZPbV68EghzovkJNuGRl9ezMYxbbKxwrMmCmGg==", "dev": true, "license": "MIT", "dependencies": { @@ -6065,7 +5592,7 @@ "@vitest/browser": "^3.0.0 || ^4.0.0", "@vitest/browser-playwright": "^4.0.0", "@vitest/runner": "^3.0.0 || ^4.0.0", - "storybook": "^10.5.5", + "storybook": "^10.4.1", "vitest": "^3.0.0 || ^4.0.0" }, "peerDependenciesMeta": { @@ -6084,13 +5611,13 @@ } }, "node_modules/@storybook/builder-vite": { - "version": "10.5.5", - "resolved": "https://registry.npmjs.org/@storybook/builder-vite/-/builder-vite-10.5.5.tgz", - "integrity": "sha512-dQoJ7gUl8y0z5rV9cE0mz6qTBNmN9R4GOLIZk98rJ8CwduNJOb9eGZXusDzzvnYcp8TnNkqDtyx4tXQSUDInPQ==", + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/@storybook/builder-vite/-/builder-vite-10.4.1.tgz", + "integrity": "sha512-/oyQrXoNOqN8SW5hNnYP+I1uvgFxKxWXj/EP6NXYzc5SQwImofgru+D2+6gDhL0+Q//+Hx05DJoQO2omvUJ8bQ==", "dev": true, "license": "MIT", "dependencies": { - "@storybook/csf-plugin": "10.5.5", + "@storybook/csf-plugin": "10.4.1", "ts-dedent": "^2.0.0" }, "funding": { @@ -6098,14 +5625,14 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^10.5.5", + "storybook": "^10.4.1", "vite": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" } }, "node_modules/@storybook/csf-plugin": { - "version": "10.5.5", - "resolved": "https://registry.npmjs.org/@storybook/csf-plugin/-/csf-plugin-10.5.5.tgz", - "integrity": "sha512-/euibhRFqklYCZqUseokojmfYcQpXshVY2QmA1qCuxMz9SzVFD3iSTw+aFLTxpsJGGdcZJk8fnm/rEthLzZ9jA==", + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/@storybook/csf-plugin/-/csf-plugin-10.4.1.tgz", + "integrity": "sha512-WdPepGBxDGOUDjYd8KxMtcf+us/2PAcnBczl77XtrnxxHNs0jWesxKkiJ9yiuGrge4BPhDeAj6rxjbBoaHxLBA==", "dev": true, "license": "MIT", "dependencies": { @@ -6118,7 +5645,7 @@ "peerDependencies": { "esbuild": "*", "rollup": "*", - "storybook": "^10.5.5", + "storybook": "^10.4.1", "vite": "*", "webpack": "*" }, @@ -6139,45 +5666,10 @@ }, "node_modules/@storybook/global": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@storybook/global/-/global-5.0.0.tgz", + "integrity": "sha512-FcOqPAXACP0I3oJ/ws6/rrPT9WGhu915Cg8D02a9YxLo0DE9zI+a9A5gRGvmQ09fiWPukqI8ZAEoQEdWUKMQdQ==", "license": "MIT" }, - "node_modules/@storybook/html": { - "version": "10.5.5", - "resolved": "https://registry.npmjs.org/@storybook/html/-/html-10.5.5.tgz", - "integrity": "sha512-Dm2Ud+UiDgtgolURvpZpN7SbOSjPJ2iy4RAxSZLR2BglE5QL7u4Uewpbs5/kw/VFT5u9SAenxEK6P/kbZuZC0g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@storybook/global": "^5.0.0", - "ts-dedent": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - }, - "peerDependencies": { - "storybook": "^10.5.5" - } - }, - "node_modules/@storybook/html-vite": { - "version": "10.5.5", - "resolved": "https://registry.npmjs.org/@storybook/html-vite/-/html-vite-10.5.5.tgz", - "integrity": "sha512-u6LuYN61dYbw8F6MHvDU3TGmYrOlYd8vPOhlK/z0Wg9Xd8634xlTpcKaVOYt0zETqh33nnrf+LQh4t1OvLFPvQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@storybook/builder-vite": "10.5.5", - "@storybook/html": "10.5.5" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - }, - "peerDependencies": { - "storybook": "^10.5.5", - "vite": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, "node_modules/@storybook/icons": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/@storybook/icons/-/icons-2.0.2.tgz", @@ -6189,9 +5681,9 @@ } }, "node_modules/@storybook/react-dom-shim": { - "version": "10.5.5", - "resolved": "https://registry.npmjs.org/@storybook/react-dom-shim/-/react-dom-shim-10.5.5.tgz", - "integrity": "sha512-PIk7N3LLrZIxfNxmkvmQN1d5UQ70XEedT8n0GhBiXnM6XL09xPGB8n8TZXeJBRYluKhDQcAyQeT0/OZmcDVQJg==", + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/@storybook/react-dom-shim/-/react-dom-shim-10.4.1.tgz", + "integrity": "sha512-6QFqfDNH4DMrt7yHKRfpqRopsVUc/Az+sXIdJ39IetYnHUxL3nW4NVaPc6uy/8Qi8urzUyEXL/nn7cpSIP2aPQ==", "dev": true, "license": "MIT", "funding": { @@ -6203,7 +5695,7 @@ "@types/react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", - "storybook": "^10.5.5" + "storybook": "^10.4.1" }, "peerDependenciesMeta": { "@types/react": { @@ -6215,14 +5707,14 @@ } }, "node_modules/@storybook/vue3": { - "version": "10.5.5", - "resolved": "https://registry.npmjs.org/@storybook/vue3/-/vue3-10.5.5.tgz", - "integrity": "sha512-SOBloEQVq7t+BHrafesl2TqJtYb0YlSHadc1W15ThrM86vzKgiHniP8DE5SDOdnJSceMPiL5VL3whB7nhhk7Ig==", + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/@storybook/vue3/-/vue3-10.4.1.tgz", + "integrity": "sha512-NytbVIfU6x9LO69WrWoxIIFXSmKG5UH4QTBw1heMozZxCLoFVx99HXiq+CQANP0w2Ly8XBALXO6yOf2g+hRMaw==", "dev": true, "license": "MIT", "dependencies": { "@storybook/global": "^5.0.0", - "type-fest": "^5.6.0", + "type-fest": "~2.19", "vue-component-type-helpers": "^3.2.9" }, "funding": { @@ -6230,22 +5722,22 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^10.5.5", + "storybook": "^10.4.1", "vue": "^3.0.0" } }, "node_modules/@storybook/vue3-vite": { - "version": "10.5.5", - "resolved": "https://registry.npmjs.org/@storybook/vue3-vite/-/vue3-vite-10.5.5.tgz", - "integrity": "sha512-VQj32JXx6cv1yyOO7u27cq//mOx6OEX7k+bH6ocyi2gU++QMnl43YPq00vFnQajsbE2WwIlqQwHKb5zEcU6kdg==", + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/@storybook/vue3-vite/-/vue3-vite-10.4.1.tgz", + "integrity": "sha512-ni4vKb5K7BLBvdbSRo4nVHXxbuPOgVqVH1ODKDy4hvdXDAi/VUvw2L2lsGM5Xo82VR/x72GZEfgJGZpuP9MWxg==", "dev": true, "license": "MIT", "dependencies": { - "@storybook/builder-vite": "10.5.5", - "@storybook/vue3": "10.5.5", + "@storybook/builder-vite": "10.4.1", + "@storybook/vue3": "10.4.1", "magic-string": "^0.30.0", "typescript": "^5.9.3", - "vue-component-meta": "^3.2.7", + "vue-component-meta": "^2.0.0", "vue-docgen-api": "^4.75.1" }, "funding": { @@ -6253,12 +5745,14 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^10.5.5", + "storybook": "^10.4.1", "vite": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" } }, "node_modules/@storybook/vue3-vite/node_modules/typescript": { "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "dev": true, "license": "Apache-2.0", "bin": { @@ -6269,10 +5763,23 @@ "node": ">=14.17" } }, + "node_modules/@storybook/vue3/node_modules/type-fest": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", + "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/@storybook/web-components": { - "version": "10.5.5", - "resolved": "https://registry.npmjs.org/@storybook/web-components/-/web-components-10.5.5.tgz", - "integrity": "sha512-ZUk1TmJ6JsRrf7Wh4NnuTxenKrbav7NlHAwzEQtnA3eE0Kzv204k8IskTFr8tKDEYxXzjBppONdRgJZf5i128g==", + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/@storybook/web-components/-/web-components-10.4.1.tgz", + "integrity": "sha512-bvvIQZK7vdxoVrBmQtbvtNU5ugFF8dETc0l2j58nPUerDHUook8dFNXUiKfK1KmnLsBZ/7KEjPPmk7sEHygvlQ==", "dev": true, "license": "MIT", "dependencies": { @@ -6286,25 +5793,25 @@ }, "peerDependencies": { "lit": "^2.0.0 || ^3.0.0", - "storybook": "^10.5.5" + "storybook": "^10.4.1" } }, "node_modules/@storybook/web-components-vite": { - "version": "10.5.5", - "resolved": "https://registry.npmjs.org/@storybook/web-components-vite/-/web-components-vite-10.5.5.tgz", - "integrity": "sha512-5Gw5bdqgLJTASGtUQoeQVmc4mRiHUCjuGPWiwrcAjkcAhiuYZ4sZnHNJaCCO9IXoB0SN/ZHDojtEadK7mrnLBA==", + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/@storybook/web-components-vite/-/web-components-vite-10.4.1.tgz", + "integrity": "sha512-i66ublYmQNK9zvSgiT7w9zSHCcXh+g7lHWFoxO+QX7riRLMmtk5uOlWna9P7Ny41fkoQ7POKWJAuZ9PLBPl/Ug==", "dev": true, "license": "MIT", "dependencies": { - "@storybook/builder-vite": "10.5.5", - "@storybook/web-components": "10.5.5" + "@storybook/builder-vite": "10.4.1", + "@storybook/web-components": "10.4.1" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^10.5.5", + "storybook": "^10.4.1", "vite": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" } }, @@ -6654,7 +6161,10 @@ }, "node_modules/@testing-library/dom": { "version": "10.4.1", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.1.tgz", + "integrity": "sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==", "license": "MIT", + "peer": true, "dependencies": { "@babel/code-frame": "^7.10.4", "@babel/runtime": "^7.12.5", @@ -6732,7 +6242,10 @@ }, "node_modules/@types/aria-query": { "version": "5.0.4", - "license": "MIT" + "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", + "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==", + "license": "MIT", + "peer": true }, "node_modules/@types/body-parser": { "version": "1.19.6", @@ -6800,9 +6313,7 @@ } }, "node_modules/@types/estree": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", - "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==", + "version": "1.0.8", "license": "MIT" }, "node_modules/@types/express": { @@ -6898,6 +6409,11 @@ "@types/sizzle": "*" } }, + "node_modules/@types/jsesc": { + "version": "2.5.1", + "dev": true, + "license": "MIT" + }, "node_modules/@types/json-schema": { "version": "7.0.15", "license": "MIT" @@ -6953,6 +6469,8 @@ }, "node_modules/@types/react": { "version": "19.2.15", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.15.tgz", + "integrity": "sha512-eRwcGNHve+E8qtEQSSRl6urh+rFop4v8gm6O8rGv25CodbvFdLjA1vVQ1KkiFE0w0UPOnb8tDiFKL5lp0rtY5Q==", "devOptional": true, "license": "MIT", "peer": true, @@ -6964,989 +6482,602 @@ "version": "0.12.0", "license": "MIT" }, - "node_modules/@types/send": { - "version": "1.2.1", - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/serve-index": { - "version": "1.9.4", - "license": "MIT", - "dependencies": { - "@types/express": "*" - } - }, - "node_modules/@types/serve-static": { - "version": "1.15.10", - "license": "MIT", - "dependencies": { - "@types/http-errors": "*", - "@types/node": "*", - "@types/send": "<1" - } - }, - "node_modules/@types/serve-static/node_modules/@types/send": { - "version": "0.17.6", - "license": "MIT", - "dependencies": { - "@types/mime": "^1", - "@types/node": "*" - } - }, - "node_modules/@types/sizzle": { - "version": "2.3.10", - "license": "MIT" - }, - "node_modules/@types/sockjs": { - "version": "0.3.36", - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/tern": { - "version": "0.23.9", - "license": "MIT", - "dependencies": { - "@types/estree": "*" - } - }, - "node_modules/@types/through": { - "version": "0.0.33", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/trusted-types": { - "version": "2.0.7", - "license": "MIT" - }, - "node_modules/@types/web-bluetooth": { - "version": "0.0.21", - "license": "MIT" - }, - "node_modules/@types/whatwg-mimetype": { - "version": "3.0.2", - "devOptional": true, - "license": "MIT" - }, - "node_modules/@types/ws": { - "version": "8.18.1", - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/yargs": { - "version": "17.0.34", - "license": "MIT", - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/@types/yargs-parser": { - "version": "21.0.3", - "license": "MIT" - }, - "node_modules/@vitejs/plugin-vue": { - "version": "6.0.6", - "dev": true, - "license": "MIT", - "dependencies": { - "@rolldown/pluginutils": "1.0.0-rc.13" - }, - "engines": { - "node": "^20.19.0 || >=22.12.0" - }, - "peerDependencies": { - "vite": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0", - "vue": "^3.2.25" - } - }, - "node_modules/@vitest/browser": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/@vitest/browser/-/browser-4.1.10.tgz", - "integrity": "sha512-UDwuWGwXj646CBx/bQHOaJSX7np0I8JL/UKQYa1e4QrVHH8VdWtx8eaOuf8sy0ShwDgR6NjJAsp5eF6vjF6qng==", - "license": "MIT", - "dependencies": { - "@blazediff/core": "1.9.1", - "@vitest/mocker": "4.1.10", - "@vitest/utils": "4.1.10", - "magic-string": "^0.30.21", - "pngjs": "^7.0.0", - "sirv": "^3.0.2", - "tinyrainbow": "^3.1.0", - "ws": "^8.19.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - }, - "peerDependencies": { - "vitest": "4.1.10" - } - }, - "node_modules/@vitest/browser-playwright": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/@vitest/browser-playwright/-/browser-playwright-4.1.10.tgz", - "integrity": "sha512-nMoXGEiRpT7m3W7NsbvrM2aKNwiNHZf+zEpUCvMteGjZFvfT96Q9fh7QyB98dvDWXiKvrLxA7bJ1mCOOv+JQPw==", - "license": "MIT", - "dependencies": { - "@vitest/browser": "4.1.10", - "@vitest/mocker": "4.1.10", - "tinyrainbow": "^3.1.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - }, - "peerDependencies": { - "playwright": "*", - "vitest": "4.1.10" - }, - "peerDependenciesMeta": { - "playwright": { - "optional": false - } - } - }, - "node_modules/@vitest/browser-playwright/node_modules/tinyrainbow": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.1.0.tgz", - "integrity": "sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==", - "license": "MIT", - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@vitest/browser-preview": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/@vitest/browser-preview/-/browser-preview-4.1.10.tgz", - "integrity": "sha512-14MJrL59ZFkqXLjwfSk6RzTDy5Czf9UG4+8q8L6Gxjs2aPjEce/cVNYV14bXAc2BvMjUNu904+ZEZA1Xc1wtvQ==", - "devOptional": true, - "license": "MIT", - "dependencies": { - "@testing-library/dom": "^10.4.1", - "@testing-library/user-event": "^14.6.1", - "@vitest/browser": "4.1.10" - }, - "funding": { - "url": "https://opencollective.com/vitest" - }, - "peerDependencies": { - "vitest": "4.1.10" - } - }, - "node_modules/@vitest/browser/node_modules/@vitest/pretty-format": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.10.tgz", - "integrity": "sha512-W1HsjSH4MXQ9YfmmhLAoIYf1HRfekQCGngeIgcei6MP5QQGWUe0gkopdZQaVCFO+JDJMrAJGwa5pRpNpvy4P8Q==", - "license": "MIT", - "dependencies": { - "tinyrainbow": "^3.1.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/browser/node_modules/@vitest/utils": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.10.tgz", - "integrity": "sha512-fy9am/HWxbaGt/Sawrp90vt6Y6jQwf1RX77cz3uwoJwJVMli/e1IEwRPnMNJ7vKfPTwo0diXifkpPvwH9v7nGA==", - "license": "MIT", - "dependencies": { - "@vitest/pretty-format": "4.1.10", - "convert-source-map": "^2.0.0", - "tinyrainbow": "^3.1.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/browser/node_modules/tinyrainbow": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.1.0.tgz", - "integrity": "sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==", - "license": "MIT", - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@vitest/coverage-v8": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-4.1.10.tgz", - "integrity": "sha512-IM49HmthevbgAO4anp1hwtoT9wYe59w0LR00gr+eagHE+ZJ5lK4sLPeO0ubgoJcwLk6dehU3R24N+FbEEKDc8g==", - "devOptional": true, - "license": "MIT", - "dependencies": { - "@bcoe/v8-coverage": "^1.0.2", - "@vitest/utils": "4.1.10", - "ast-v8-to-istanbul": "^1.0.0", - "istanbul-lib-coverage": "^3.2.2", - "istanbul-lib-report": "^3.0.1", - "istanbul-reports": "^3.2.0", - "magicast": "^0.5.2", - "obug": "^2.1.1", - "std-env": "^4.0.0-rc.1", - "tinyrainbow": "^3.1.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - }, - "peerDependencies": { - "@vitest/browser": "4.1.10", - "vitest": "4.1.10" - }, - "peerDependenciesMeta": { - "@vitest/browser": { - "optional": true - } - } - }, - "node_modules/@vitest/coverage-v8/node_modules/@vitest/pretty-format": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.10.tgz", - "integrity": "sha512-W1HsjSH4MXQ9YfmmhLAoIYf1HRfekQCGngeIgcei6MP5QQGWUe0gkopdZQaVCFO+JDJMrAJGwa5pRpNpvy4P8Q==", - "devOptional": true, - "license": "MIT", - "dependencies": { - "tinyrainbow": "^3.1.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/coverage-v8/node_modules/@vitest/utils": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.10.tgz", - "integrity": "sha512-fy9am/HWxbaGt/Sawrp90vt6Y6jQwf1RX77cz3uwoJwJVMli/e1IEwRPnMNJ7vKfPTwo0diXifkpPvwH9v7nGA==", - "devOptional": true, - "license": "MIT", - "dependencies": { - "@vitest/pretty-format": "4.1.10", - "convert-source-map": "^2.0.0", - "tinyrainbow": "^3.1.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/coverage-v8/node_modules/tinyrainbow": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.1.0.tgz", - "integrity": "sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==", - "devOptional": true, - "license": "MIT", - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@vitest/expect": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.2.4.tgz", - "integrity": "sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig==", + "node_modules/@types/send": { + "version": "1.2.1", "license": "MIT", "dependencies": { - "@types/chai": "^5.2.2", - "@vitest/spy": "3.2.4", - "@vitest/utils": "3.2.4", - "chai": "^5.2.0", - "tinyrainbow": "^2.0.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" + "@types/node": "*" } }, - "node_modules/@vitest/mocker": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.10.tgz", - "integrity": "sha512-v0xaezt+DKEmKfaxg133ldzADrwLGd7Ze1MfQQTYfvs8OqZIwbxyxaYURivwV7sWy5fqn3rH5uOrSp07bp44Ow==", + "node_modules/@types/serve-index": { + "version": "1.9.4", "license": "MIT", "dependencies": { - "@vitest/spy": "4.1.10", - "estree-walker": "^3.0.3", - "magic-string": "^0.30.21" - }, - "funding": { - "url": "https://opencollective.com/vitest" - }, - "peerDependencies": { - "msw": "^2.4.9", - "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "msw": { - "optional": true - }, - "vite": { - "optional": true - } + "@types/express": "*" } }, - "node_modules/@vitest/mocker/node_modules/@vitest/spy": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.10.tgz", - "integrity": "sha512-PLf/Ugvoq5wO/b4rwYCR1h2PSIdXz7wnkQFMiUpLdtM7l6pqVFcQIBEHyT1+l+cj7mNwAfZHzqXqDyjvOuwbDw==", + "node_modules/@types/serve-static": { + "version": "1.15.10", "license": "MIT", - "funding": { - "url": "https://opencollective.com/vitest" + "dependencies": { + "@types/http-errors": "*", + "@types/node": "*", + "@types/send": "<1" } }, - "node_modules/@vitest/pretty-format": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.2.4.tgz", - "integrity": "sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA==", + "node_modules/@types/serve-static/node_modules/@types/send": { + "version": "0.17.6", "license": "MIT", "dependencies": { - "tinyrainbow": "^2.0.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" + "@types/mime": "^1", + "@types/node": "*" } }, - "node_modules/@vitest/runner": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.10.tgz", - "integrity": "sha512-IKI6kpIH+LmpROplyLwBBaCfMgOZOMsygVa6BARD6ahA04VRuJSa6OaVG7kRvSEMD870Vd91rSSw0eegtWyLGg==", + "node_modules/@types/sizzle": { + "version": "2.3.10", + "license": "MIT" + }, + "node_modules/@types/sockjs": { + "version": "0.3.36", "license": "MIT", "dependencies": { - "@vitest/utils": "4.1.10", - "pathe": "^2.0.3" - }, - "funding": { - "url": "https://opencollective.com/vitest" + "@types/node": "*" } }, - "node_modules/@vitest/runner/node_modules/@vitest/pretty-format": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.10.tgz", - "integrity": "sha512-W1HsjSH4MXQ9YfmmhLAoIYf1HRfekQCGngeIgcei6MP5QQGWUe0gkopdZQaVCFO+JDJMrAJGwa5pRpNpvy4P8Q==", + "node_modules/@types/tern": { + "version": "0.23.9", "license": "MIT", "dependencies": { - "tinyrainbow": "^3.1.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" + "@types/estree": "*" } }, - "node_modules/@vitest/runner/node_modules/@vitest/utils": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.10.tgz", - "integrity": "sha512-fy9am/HWxbaGt/Sawrp90vt6Y6jQwf1RX77cz3uwoJwJVMli/e1IEwRPnMNJ7vKfPTwo0diXifkpPvwH9v7nGA==", + "node_modules/@types/through": { + "version": "0.0.33", + "dev": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "4.1.10", - "convert-source-map": "^2.0.0", - "tinyrainbow": "^3.1.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" + "@types/node": "*" } }, - "node_modules/@vitest/runner/node_modules/tinyrainbow": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.1.0.tgz", - "integrity": "sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==", + "node_modules/@types/trusted-types": { + "version": "2.0.7", + "license": "MIT" + }, + "node_modules/@types/web-bluetooth": { + "version": "0.0.21", + "license": "MIT" + }, + "node_modules/@types/whatwg-mimetype": { + "version": "3.0.2", + "devOptional": true, + "license": "MIT" + }, + "node_modules/@types/ws": { + "version": "8.18.1", "license": "MIT", - "engines": { - "node": ">=14.0.0" + "dependencies": { + "@types/node": "*" } }, - "node_modules/@vitest/snapshot": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.10.tgz", - "integrity": "sha512-xRkfOT1qpTAi/Ti4Y1LtfRc3kEuqxGw59eN2jN9pRWMtS/XDevekhcFSqvQqjUNGksfjMJu3Y+oJ+4Ypn2OaJw==", + "node_modules/@types/yargs": { + "version": "17.0.34", "license": "MIT", "dependencies": { - "@vitest/pretty-format": "4.1.10", - "@vitest/utils": "4.1.10", - "magic-string": "^0.30.21", - "pathe": "^2.0.3" - }, - "funding": { - "url": "https://opencollective.com/vitest" + "@types/yargs-parser": "*" } }, - "node_modules/@vitest/snapshot/node_modules/@vitest/pretty-format": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.10.tgz", - "integrity": "sha512-W1HsjSH4MXQ9YfmmhLAoIYf1HRfekQCGngeIgcei6MP5QQGWUe0gkopdZQaVCFO+JDJMrAJGwa5pRpNpvy4P8Q==", + "node_modules/@types/yargs-parser": { + "version": "21.0.3", + "license": "MIT" + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "8.60.0", + "dev": true, "license": "MIT", "dependencies": { - "tinyrainbow": "^3.1.0" + "@eslint-community/regexpp": "^4.12.2", + "@typescript-eslint/scope-manager": "8.60.0", + "@typescript-eslint/type-utils": "8.60.0", + "@typescript-eslint/utils": "8.60.0", + "@typescript-eslint/visitor-keys": "8.60.0", + "ignore": "^7.0.5", + "natural-compare": "^1.4.0", + "ts-api-utils": "^2.5.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://opencollective.com/vitest" + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^8.60.0", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" } }, - "node_modules/@vitest/snapshot/node_modules/@vitest/utils": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.10.tgz", - "integrity": "sha512-fy9am/HWxbaGt/Sawrp90vt6Y6jQwf1RX77cz3uwoJwJVMli/e1IEwRPnMNJ7vKfPTwo0diXifkpPvwH9v7nGA==", + "node_modules/@typescript-eslint/parser": { + "version": "8.60.0", + "dev": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "4.1.10", - "convert-source-map": "^2.0.0", - "tinyrainbow": "^3.1.0" + "@typescript-eslint/scope-manager": "8.60.0", + "@typescript-eslint/types": "8.60.0", + "@typescript-eslint/typescript-estree": "8.60.0", + "@typescript-eslint/visitor-keys": "8.60.0", + "debug": "^4.4.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://opencollective.com/vitest" + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" } }, - "node_modules/@vitest/snapshot/node_modules/tinyrainbow": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.1.0.tgz", - "integrity": "sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==", + "node_modules/@typescript-eslint/project-service": { + "version": "8.60.0", + "dev": true, "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.60.0", + "@typescript-eslint/types": "^8.60.0", + "debug": "^4.4.3" + }, "engines": { - "node": ">=14.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" } }, - "node_modules/@vitest/spy": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.2.4.tgz", - "integrity": "sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw==", + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.60.0", + "dev": true, "license": "MIT", "dependencies": { - "tinyspy": "^4.0.3" + "@typescript-eslint/types": "8.60.0", + "@typescript-eslint/visitor-keys": "8.60.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://opencollective.com/vitest" + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@vitest/utils": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.2.4.tgz", - "integrity": "sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==", + "node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.60.0", + "dev": true, "license": "MIT", - "dependencies": { - "@vitest/pretty-format": "3.2.4", - "loupe": "^3.1.4", - "tinyrainbow": "^2.0.0" + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://opencollective.com/vitest" + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" } }, - "node_modules/@voidzero-dev/vite-plus-core": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/@voidzero-dev/vite-plus-core/-/vite-plus-core-0.2.6.tgz", - "integrity": "sha512-vqDuuLJWS2JHWkFO7r8Z6AehtKnurpnYtw2XEQtjIfwE2GgSAO3zJdPIeaEZiovS6CqfQa+iOMn3kzVzeTSpTw==", - "devOptional": true, + "node_modules/@typescript-eslint/type-utils": { + "version": "8.60.0", + "dev": true, "license": "MIT", "dependencies": { - "@oxc-project/runtime": "=0.141.0", - "@oxc-project/types": "=0.141.0", - "lightningcss": "^1.33.0", - "postcss": "^8.5.6", - "yuku-codegen": "^0.5.44", - "yuku-parser": "^0.5.44" + "@typescript-eslint/types": "8.60.0", + "@typescript-eslint/typescript-estree": "8.60.0", + "@typescript-eslint/utils": "8.60.0", + "debug": "^4.4.3", + "ts-api-utils": "^2.5.0" }, "engines": { - "node": "^20.19.0 || ^22.18.0 || >=24.11.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, - "optionalDependencies": { - "fsevents": "~2.3.3" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@arethetypeswrong/core": "^0.18.1", - "@types/node": "^20.19.0 || >=22.12.0", - "@vitejs/devtools": "^0.3.0", - "esbuild": "^0.27.0 || ^0.28.0", - "jiti": ">=1.21.0", - "less": "^4.0.0", - "publint": "^0.3.8", - "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", - "typescript": "^5.0.0 || ^6.0.0 || ^7.0.0", - "unplugin-unused": "^0.5.0", - "unrun": "*", - "yaml": "^2.4.2" + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "8.60.0", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, - "peerDependenciesMeta": { - "@arethetypeswrong/core": { - "optional": true - }, - "@types/node": { - "optional": true - }, - "@vitejs/devtools": { - "optional": true - }, - "esbuild": { - "optional": true - }, - "jiti": { - "optional": true - }, - "less": { - "optional": true - }, - "publint": { - "optional": true - }, - "sass": { - "optional": true - }, - "sass-embedded": { - "optional": true - }, - "stylus": { - "optional": true - }, - "sugarss": { - "optional": true - }, - "terser": { - "optional": true - }, - "tsx": { - "optional": true - }, - "typescript": { - "optional": true - }, - "unplugin-unused": { - "optional": true - }, - "unrun": { - "optional": true - }, - "yaml": { - "optional": true - } + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.60.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/project-service": "8.60.0", + "@typescript-eslint/tsconfig-utils": "8.60.0", + "@typescript-eslint/types": "8.60.0", + "@typescript-eslint/visitor-keys": "8.60.0", + "debug": "^4.4.3", + "minimatch": "^10.2.2", + "semver": "^7.7.3", + "tinyglobby": "^0.2.15", + "ts-api-utils": "^2.5.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" } }, - "node_modules/@voidzero-dev/vite-plus-core/node_modules/@oxc-project/types": { - "version": "0.141.0", - "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.141.0.tgz", - "integrity": "sha512-S4as7z0j0xQkXcJlyY5ehntwK8/wRkQb9Cyqw+J/N2rkWGQGK0SxD6X6DhQTc7qsxVTBxXbxZtBJh3mr3PtIzQ==", - "devOptional": true, + "node_modules/@typescript-eslint/typescript-estree/node_modules/balanced-match": { + "version": "4.0.4", + "dev": true, "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/Boshen" + "engines": { + "node": "18 || 20 || >=22" } }, - "node_modules/@voidzero-dev/vite-plus-core/node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "hasInstallScript": true, + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { + "version": "5.0.6", + "dev": true, "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], + "dependencies": { + "balanced-match": "^4.0.2" + }, "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + "node": "18 || 20 || >=22" } }, - "node_modules/@voidzero-dev/vite-plus-core/node_modules/lightningcss": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.33.0.tgz", - "integrity": "sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA==", - "devOptional": true, - "license": "MPL-2.0", + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "10.2.5", + "dev": true, + "license": "BlueOak-1.0.0", "dependencies": { - "detect-libc": "^2.0.3" + "brace-expansion": "^5.0.5" }, "engines": { - "node": ">= 12.0.0" + "node": "18 || 20 || >=22" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { + "version": "7.8.1", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" }, - "optionalDependencies": { - "lightningcss-android-arm64": "1.33.0", - "lightningcss-darwin-arm64": "1.33.0", - "lightningcss-darwin-x64": "1.33.0", - "lightningcss-freebsd-x64": "1.33.0", - "lightningcss-linux-arm-gnueabihf": "1.33.0", - "lightningcss-linux-arm64-gnu": "1.33.0", - "lightningcss-linux-arm64-musl": "1.33.0", - "lightningcss-linux-x64-gnu": "1.33.0", - "lightningcss-linux-x64-musl": "1.33.0", - "lightningcss-win32-arm64-msvc": "1.33.0", - "lightningcss-win32-x64-msvc": "1.33.0" - } - }, - "node_modules/@voidzero-dev/vite-plus-core/node_modules/lightningcss-android-arm64": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.33.0.tgz", - "integrity": "sha512-gEpRTalKdosp4Bb8qWtc2iOgE5SeIHlpS1up9bFq2wAyYhl1UdTObYiHe98zEM9SQvSoqQZ1IQD0JNpg3Ml5pg==", - "cpu": [ - "arm64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "android" - ], "engines": { - "node": ">= 12.0.0" + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "8.60.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.9.1", + "@typescript-eslint/scope-manager": "8.60.0", + "@typescript-eslint/types": "8.60.0", + "@typescript-eslint/typescript-estree": "8.60.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/parcel" + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" } }, - "node_modules/@voidzero-dev/vite-plus-core/node_modules/lightningcss-darwin-arm64": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.33.0.tgz", - "integrity": "sha512-Sciaz8eenNTKn9b3t7+xr0ipTp9YxKQY4npwQ3mrRuL0BAVHBLyZxofhaKBAVtzmtRZ/zTyo0/to4B1uWG/Djg==", - "cpu": [ - "arm64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "darwin" - ], + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.60.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.60.0", + "eslint-visitor-keys": "^5.0.0" + }, "engines": { - "node": ">= 12.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/parcel" + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@voidzero-dev/vite-plus-core/node_modules/lightningcss-darwin-x64": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.33.0.tgz", - "integrity": "sha512-Z5UPAxzrjlWNNyGy6i65cJzzvgJ5D3T6wMvs+gWpY9d7qRhANrxqAp6LhxIgZhWEw18RfJTGcRxjuLIBr+m8XQ==", - "cpu": [ - "x64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "darwin" - ], + "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { + "version": "5.0.1", + "dev": true, + "license": "Apache-2.0", "engines": { - "node": ">= 12.0.0" + "node": "^20.19.0 || ^22.13.0 || >=24" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "url": "https://opencollective.com/eslint" } }, - "node_modules/@voidzero-dev/vite-plus-core/node_modules/lightningcss-freebsd-x64": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.33.0.tgz", - "integrity": "sha512-QQM/Ti/hQajJwCY+RiWuCZ9sdtI/XQk7nDK5vC8kkdwixezOlDgvDx7+RT+QjK6FcFT4MpsuoBnHIo/O3StRRg==", - "cpu": [ - "x64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "freebsd" - ], + "node_modules/@ungap/structured-clone": { + "version": "1.3.1", + "license": "ISC" + }, + "node_modules/@vitejs/plugin-vue": { + "version": "6.0.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@rolldown/pluginutils": "1.0.0-rc.13" + }, "engines": { - "node": ">= 12.0.0" + "node": "^20.19.0 || >=22.12.0" + }, + "peerDependencies": { + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0", + "vue": "^3.2.25" + } + }, + "node_modules/@vitest/browser": { + "version": "4.1.5", + "license": "MIT", + "dependencies": { + "@blazediff/core": "1.9.1", + "@vitest/mocker": "4.1.5", + "@vitest/utils": "4.1.5", + "magic-string": "^0.30.21", + "pngjs": "^7.0.0", + "sirv": "^3.0.2", + "tinyrainbow": "^3.1.0", + "ws": "^8.19.0" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "vitest": "4.1.5" } }, - "node_modules/@voidzero-dev/vite-plus-core/node_modules/lightningcss-linux-arm-gnueabihf": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.33.0.tgz", - "integrity": "sha512-N7FVBe6iS24MlM6R/4RBTxGhQheZGs7tiQ9U32UtF75NzP5Q7xWPRqLBCKxlRQRk3rY1jCIPLzx7WzOhuUIRLQ==", - "cpu": [ - "arm" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" + "node_modules/@vitest/browser-playwright": { + "version": "4.1.5", + "license": "MIT", + "dependencies": { + "@vitest/browser": "4.1.5", + "@vitest/mocker": "4.1.5", + "tinyrainbow": "^3.1.0" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "playwright": "*", + "vitest": "4.1.5" + }, + "peerDependenciesMeta": { + "playwright": { + "optional": false + } } }, - "node_modules/@voidzero-dev/vite-plus-core/node_modules/lightningcss-linux-arm64-gnu": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.33.0.tgz", - "integrity": "sha512-j2v/itmy4HlNxlc6voKXYgBqNi0Ng2LShg4z7GufpEgs05P+2suBVyi9I6YHq5uoVFx9ETin3eCEhLVyXGQnKg==", - "cpu": [ - "arm64" - ], - "libc": [ - "glibc" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], + "node_modules/@vitest/browser-playwright/node_modules/tinyrainbow": { + "version": "3.1.0", + "license": "MIT", "engines": { - "node": ">= 12.0.0" + "node": ">=14.0.0" + } + }, + "node_modules/@vitest/browser/node_modules/@vitest/pretty-format": { + "version": "4.1.5", + "license": "MIT", + "dependencies": { + "tinyrainbow": "^3.1.0" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "url": "https://opencollective.com/vitest" } }, - "node_modules/@voidzero-dev/vite-plus-core/node_modules/lightningcss-linux-arm64-musl": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.33.0.tgz", - "integrity": "sha512-yiO5ROMuYQgXbC60yjZU5CYSFZGKXL0HFATXt9mHJn1+zW55oCtMI9NfcVhYLMFDL7gV7oBPon/EmMMGg2OvtQ==", - "cpu": [ - "arm64" - ], - "libc": [ - "musl" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" + "node_modules/@vitest/browser/node_modules/@vitest/utils": { + "version": "4.1.5", + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "4.1.5", + "convert-source-map": "^2.0.0", + "tinyrainbow": "^3.1.0" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "url": "https://opencollective.com/vitest" } }, - "node_modules/@voidzero-dev/vite-plus-core/node_modules/lightningcss-linux-x64-gnu": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.33.0.tgz", - "integrity": "sha512-ar+Ju7LmcN0Jo4FpL4hpFybwNG9/3A/Br5KW2n2jyODg3MEZXaDYADdemoNS+BDNfMgKvylJLj4S5tyRActuAg==", - "cpu": [ - "x64" - ], - "libc": [ - "glibc" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], + "node_modules/@vitest/browser/node_modules/tinyrainbow": { + "version": "3.1.0", + "license": "MIT", "engines": { - "node": ">= 12.0.0" + "node": ">=14.0.0" + } + }, + "node_modules/@vitest/expect": { + "version": "3.2.4", + "license": "MIT", + "dependencies": { + "@types/chai": "^5.2.2", + "@vitest/spy": "3.2.4", + "@vitest/utils": "3.2.4", + "chai": "^5.2.0", + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/mocker": { + "version": "4.1.5", + "license": "MIT", + "dependencies": { + "@vitest/spy": "4.1.5", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.21" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "msw": "^2.4.9", + "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" }, + "peerDependenciesMeta": { + "msw": { + "optional": true + }, + "vite": { + "optional": true + } + } + }, + "node_modules/@vitest/mocker/node_modules/@vitest/spy": { + "version": "4.1.5", + "license": "MIT", "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "url": "https://opencollective.com/vitest" } }, - "node_modules/@voidzero-dev/vite-plus-core/node_modules/lightningcss-linux-x64-musl": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.33.0.tgz", - "integrity": "sha512-RYiYbkokw0trfKqqzfF55lginwEPrD3OJDfTuJzFs1MK6iFnDenaz1fqLLtX4ITG3OktJQXOeTaw1awrBAlZPw==", - "cpu": [ - "x64" - ], - "libc": [ - "musl" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" + "node_modules/@vitest/pretty-format": { + "version": "3.2.4", + "license": "MIT", + "dependencies": { + "tinyrainbow": "^2.0.0" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "url": "https://opencollective.com/vitest" } }, - "node_modules/@voidzero-dev/vite-plus-core/node_modules/lightningcss-win32-arm64-msvc": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.33.0.tgz", - "integrity": "sha512-1K+MPfLSFVpphzpdbfkhlWk6wBrTObBzS2T6db10PNOZgR9GoVsAWzwNyuhUYYbTp23j+4RrncfujZ4uAzXvwA==", - "cpu": [ - "arm64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 12.0.0" + "node_modules/@vitest/runner": { + "version": "4.1.5", + "license": "MIT", + "dependencies": { + "@vitest/utils": "4.1.5", + "pathe": "^2.0.3" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "url": "https://opencollective.com/vitest" } }, - "node_modules/@voidzero-dev/vite-plus-core/node_modules/lightningcss-win32-x64-msvc": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.33.0.tgz", - "integrity": "sha512-OlEICDx/Xl0FqSp4bry8zFnCvGpig3Gl4gCquvYwHuqJKEC1+n9NgDniFvqHGmMv1ZkqDJrDqKKSykTDX+ehuA==", - "cpu": [ - "x64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 12.0.0" + "node_modules/@vitest/runner/node_modules/@vitest/pretty-format": { + "version": "4.1.5", + "license": "MIT", + "dependencies": { + "tinyrainbow": "^3.1.0" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "url": "https://opencollective.com/vitest" } }, - "node_modules/@voidzero-dev/vite-plus-darwin-arm64": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/@voidzero-dev/vite-plus-darwin-arm64/-/vite-plus-darwin-arm64-0.2.6.tgz", - "integrity": "sha512-QSZWgfqPx5lrIKZ0vwgVRujRqo7gORcc9Oq4fI1UDjKZFgYz9gXVMibSjEqYU3R1webN6FKTOCnzFmrfXchWYw==", - "cpu": [ - "arm64" - ], + "node_modules/@vitest/runner/node_modules/@vitest/utils": { + "version": "4.1.5", "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=20.0.0" + "dependencies": { + "@vitest/pretty-format": "4.1.5", + "convert-source-map": "^2.0.0", + "tinyrainbow": "^3.1.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" } }, - "node_modules/@voidzero-dev/vite-plus-darwin-x64": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/@voidzero-dev/vite-plus-darwin-x64/-/vite-plus-darwin-x64-0.2.6.tgz", - "integrity": "sha512-pMQZGCQO0s+akuxbjgh31hOUgrdDndCmfbP7BciJuts436qrBb8KaVzBhNjJQtxD6H8yY21CIOjD8nlrp4eDIw==", - "cpu": [ - "x64" - ], + "node_modules/@vitest/runner/node_modules/tinyrainbow": { + "version": "3.1.0", "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], "engines": { - "node": ">=20.0.0" + "node": ">=14.0.0" } }, - "node_modules/@voidzero-dev/vite-plus-linux-arm64-gnu": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/@voidzero-dev/vite-plus-linux-arm64-gnu/-/vite-plus-linux-arm64-gnu-0.2.6.tgz", - "integrity": "sha512-0e6nrJgUDN5WwoDRjyh7KV/jbL7WDUhTEWslI64KGpuvD7M6OoPBXYo8Et176O2ENwf52CKVDjXwuvMMNIAzAA==", - "cpu": [ - "arm64" - ], - "libc": [ - "glibc" - ], + "node_modules/@vitest/snapshot": { + "version": "4.1.5", "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=20.0.0" + "dependencies": { + "@vitest/pretty-format": "4.1.5", + "@vitest/utils": "4.1.5", + "magic-string": "^0.30.21", + "pathe": "^2.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" } }, - "node_modules/@voidzero-dev/vite-plus-linux-arm64-musl": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/@voidzero-dev/vite-plus-linux-arm64-musl/-/vite-plus-linux-arm64-musl-0.2.6.tgz", - "integrity": "sha512-j2yvyv3r2ZEuJG73rWlXFrYrxA7u5+bFSlWTqhsfHZhdb1FKMkklfYRuLtBBdBRLXJ+YMNt9GZT6VTVPJDZnnQ==", - "cpu": [ - "arm64" - ], - "libc": [ - "musl" - ], + "node_modules/@vitest/snapshot/node_modules/@vitest/pretty-format": { + "version": "4.1.5", "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=20.0.0" + "dependencies": { + "tinyrainbow": "^3.1.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" } }, - "node_modules/@voidzero-dev/vite-plus-linux-x64-gnu": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/@voidzero-dev/vite-plus-linux-x64-gnu/-/vite-plus-linux-x64-gnu-0.2.6.tgz", - "integrity": "sha512-5vqldBBnRjIAUmQ88oKli+wPd5vSQaA2AZ2xs+omRlZfeJhC8chlud6DyJV6fVZCC9GI4otK2zSGpfQZx8Kc3A==", - "cpu": [ - "x64" - ], - "libc": [ - "glibc" - ], + "node_modules/@vitest/snapshot/node_modules/@vitest/utils": { + "version": "4.1.5", "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=20.0.0" + "dependencies": { + "@vitest/pretty-format": "4.1.5", + "convert-source-map": "^2.0.0", + "tinyrainbow": "^3.1.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" } }, - "node_modules/@voidzero-dev/vite-plus-linux-x64-musl": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/@voidzero-dev/vite-plus-linux-x64-musl/-/vite-plus-linux-x64-musl-0.2.6.tgz", - "integrity": "sha512-29ned+euDKAl+BmCigzGrPykQ/kxTjtsPGV6G3hkImwakHNUnmLRayqmsWKHSwXmBk5xo5m+wqjMbo3G0npJQg==", - "cpu": [ - "x64" - ], - "libc": [ - "musl" - ], + "node_modules/@vitest/snapshot/node_modules/tinyrainbow": { + "version": "3.1.0", "license": "MIT", - "optional": true, - "os": [ - "linux" - ], "engines": { - "node": ">=20.0.0" + "node": ">=14.0.0" } }, - "node_modules/@voidzero-dev/vite-plus-win32-arm64-msvc": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/@voidzero-dev/vite-plus-win32-arm64-msvc/-/vite-plus-win32-arm64-msvc-0.2.6.tgz", - "integrity": "sha512-4b5ASpQlkxSXDYzuM6MYsOc1GnYkqG9CbSA1QzobXm87V/Q+MGPn57eILyacgfbmNNLrO2HQ5hasoLvd2BXaSg==", - "cpu": [ - "arm64" - ], + "node_modules/@vitest/spy": { + "version": "3.2.4", "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=20.0.0" + "dependencies": { + "tinyspy": "^4.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" } }, - "node_modules/@voidzero-dev/vite-plus-win32-x64-msvc": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/@voidzero-dev/vite-plus-win32-x64-msvc/-/vite-plus-win32-x64-msvc-0.2.6.tgz", - "integrity": "sha512-rvGkm4WmVkCKPhvUbLkRtlVhi7EYb8GU8KaqIGJ0dVfNQHDEqnFboaiUHuPN1npFNwB+80Ulzz9AkQ/Q8MswQA==", - "cpu": [ - "x64" - ], + "node_modules/@vitest/utils": { + "version": "3.2.4", "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=20.0.0" + "dependencies": { + "@vitest/pretty-format": "3.2.4", + "loupe": "^3.1.4", + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" } }, "node_modules/@volar/language-core": { @@ -8234,6 +7365,15 @@ "@vue/shared": "3.5.24" } }, + "node_modules/@vue/compiler-vue2": { + "version": "2.7.16", + "dev": true, + "license": "MIT", + "dependencies": { + "de-indent": "^1.0.2", + "he": "^1.2.0" + } + }, "node_modules/@vue/component-compiler-utils": { "version": "3.3.0", "license": "MIT", @@ -8278,35 +7418,93 @@ "url": "https://opencollective.com/postcss/" } }, - "node_modules/@vue/component-compiler-utils/node_modules/postcss-selector-parser": { - "version": "6.1.2", + "node_modules/@vue/component-compiler-utils/node_modules/postcss-selector-parser": { + "version": "6.1.2", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@vue/component-compiler-utils/node_modules/prettier": { + "version": "2.8.8", + "license": "MIT", + "optional": true, + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/@vue/component-compiler-utils/node_modules/yallist": { + "version": "2.1.2", + "license": "ISC" + }, + "node_modules/@vue/language-core": { + "version": "2.2.12", + "dev": true, + "license": "MIT", + "dependencies": { + "@volar/language-core": "2.4.15", + "@vue/compiler-dom": "^3.5.0", + "@vue/compiler-vue2": "^2.7.16", + "@vue/shared": "^3.5.0", + "alien-signals": "^1.0.3", + "minimatch": "^9.0.3", + "muggle-string": "^0.4.1", + "path-browserify": "^1.0.1" + }, + "peerDependencies": { + "typescript": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@vue/language-core/node_modules/@volar/language-core": { + "version": "2.4.15", + "dev": true, + "license": "MIT", + "dependencies": { + "@volar/source-map": "2.4.15" + } + }, + "node_modules/@vue/language-core/node_modules/@volar/source-map": { + "version": "2.4.15", + "dev": true, + "license": "MIT" + }, + "node_modules/@vue/language-core/node_modules/brace-expansion": { + "version": "2.1.0", + "dev": true, "license": "MIT", "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" + "balanced-match": "^1.0.0" } }, - "node_modules/@vue/component-compiler-utils/node_modules/prettier": { - "version": "2.8.8", - "license": "MIT", - "optional": true, - "bin": { - "prettier": "bin-prettier.js" + "node_modules/@vue/language-core/node_modules/minimatch": { + "version": "9.0.9", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.2" }, "engines": { - "node": ">=10.13.0" + "node": ">=16 || 14 >=14.17" }, "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@vue/component-compiler-utils/node_modules/yallist": { - "version": "2.1.2", - "license": "ISC" - }, "node_modules/@vue/reactivity": { "version": "3.5.33", "license": "MIT", @@ -8515,435 +7713,129 @@ "@xtuc/long": "4.2.2" } }, - "node_modules/@webassemblyjs/utf8": { - "version": "1.13.2", - "license": "MIT" - }, - "node_modules/@webassemblyjs/wasm-edit": { - "version": "1.14.1", - "license": "MIT", - "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" - } - }, - "node_modules/@webassemblyjs/wasm-gen": { - "version": "1.14.1", - "license": "MIT", - "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" - } - }, - "node_modules/@webassemblyjs/wasm-opt": { - "version": "1.14.1", - "license": "MIT", - "dependencies": { - "@webassemblyjs/ast": "1.14.1", - "@webassemblyjs/helper-buffer": "1.14.1", - "@webassemblyjs/wasm-gen": "1.14.1", - "@webassemblyjs/wasm-parser": "1.14.1" - } - }, - "node_modules/@webassemblyjs/wasm-parser": { - "version": "1.14.1", - "license": "MIT", - "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" - } - }, - "node_modules/@webassemblyjs/wast-printer": { - "version": "1.14.1", - "license": "MIT", - "dependencies": { - "@webassemblyjs/ast": "1.14.1", - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webcontainer/env": { - "version": "1.1.1", - "license": "MIT" - }, - "node_modules/@webpack-cli/configtest": { - "version": "2.1.1", - "license": "MIT", - "engines": { - "node": ">=14.15.0" - }, - "peerDependencies": { - "webpack": "5.x.x", - "webpack-cli": "5.x.x" - } - }, - "node_modules/@webpack-cli/info": { - "version": "2.0.2", - "license": "MIT", - "engines": { - "node": ">=14.15.0" - }, - "peerDependencies": { - "webpack": "5.x.x", - "webpack-cli": "5.x.x" - } - }, - "node_modules/@webpack-cli/serve": { - "version": "2.0.5", - "license": "MIT", - "engines": { - "node": ">=14.15.0" - }, - "peerDependencies": { - "webpack": "5.x.x", - "webpack-cli": "5.x.x" - }, - "peerDependenciesMeta": { - "webpack-dev-server": { - "optional": true - } - } - }, - "node_modules/@xn-sakina/rml-darwin-arm64": { - "version": "2.8.0", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=14" - } - }, - "node_modules/@xtuc/ieee754": { - "version": "1.2.0", - "license": "BSD-3-Clause" - }, - "node_modules/@xtuc/long": { - "version": "4.2.2", - "license": "Apache-2.0" - }, - "node_modules/@yuku-codegen/binding-darwin-arm64": { - "version": "0.5.48", - "resolved": "https://registry.npmjs.org/@yuku-codegen/binding-darwin-arm64/-/binding-darwin-arm64-0.5.48.tgz", - "integrity": "sha512-yo96Oef12WzqnphInfz/eexVse3+kWgfGS5g2S3rFS3dcGn1ENW9xLFDZUP9rh+yP76DOq38wBoFi1+I9+6qBg==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@yuku-codegen/binding-darwin-x64": { - "version": "0.5.48", - "resolved": "https://registry.npmjs.org/@yuku-codegen/binding-darwin-x64/-/binding-darwin-x64-0.5.48.tgz", - "integrity": "sha512-aRCTw0EZC4bVosmw//0OMYP5tGWFE0Cu5yUBFkUbhXx/iBzvORcJ2xPNlOp/vtCCo9Ys4vp8b0DigJV6uOVb2g==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@yuku-codegen/binding-freebsd-x64": { - "version": "0.5.48", - "resolved": "https://registry.npmjs.org/@yuku-codegen/binding-freebsd-x64/-/binding-freebsd-x64-0.5.48.tgz", - "integrity": "sha512-CA0AQAEApDkbw51PdLWMtKPJ41/7rvXsS3SJs+phG7fHJI+MuFzWuLbkucZfZoEOiDscmcsfYIdgL8BsfuyKKQ==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "freebsd" - ] - }, - "node_modules/@yuku-codegen/binding-linux-arm-gnu": { - "version": "0.5.48", - "resolved": "https://registry.npmjs.org/@yuku-codegen/binding-linux-arm-gnu/-/binding-linux-arm-gnu-0.5.48.tgz", - "integrity": "sha512-DuSQlk8bH4gpmW3/00P0NLagAcMv8jOxjT40cQmxKRkktr+SUOALCfkT89tdDq3qtY95NR2GXOZ7AjNh7KKqCw==", - "cpu": [ - "arm" - ], - "libc": [ - "glibc" - ], - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@yuku-codegen/binding-linux-arm-musl": { - "version": "0.5.48", - "resolved": "https://registry.npmjs.org/@yuku-codegen/binding-linux-arm-musl/-/binding-linux-arm-musl-0.5.48.tgz", - "integrity": "sha512-bxj4Ee+wlaJcWJwft2ReJXWw5sfl1qavDz6+dlRdU1xfTEtjPSNiAWhiCHnJR0R4Ygd57DnzSQmAVGvFv6RcGw==", - "cpu": [ - "arm" - ], - "libc": [ - "musl" - ], - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@yuku-codegen/binding-linux-arm64-gnu": { - "version": "0.5.48", - "resolved": "https://registry.npmjs.org/@yuku-codegen/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-0.5.48.tgz", - "integrity": "sha512-mk5JVWh+0JOe5ue8k17kbYX8uGBoKt3ZqoCyxNh4nYAAcX7+X1tFUiU7jbjctu4vHeejCBFSTdQ021+V31cUCQ==", - "cpu": [ - "arm64" - ], - "libc": [ - "glibc" - ], - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@yuku-codegen/binding-linux-arm64-musl": { - "version": "0.5.48", - "resolved": "https://registry.npmjs.org/@yuku-codegen/binding-linux-arm64-musl/-/binding-linux-arm64-musl-0.5.48.tgz", - "integrity": "sha512-4q3vkrNghbllyxOm2KesFLxCPKHF7r3JyQ7BWZccY1j2Y05yKoIFhoWCqIuQ2W/dpte9RI0+OVfwyxnrKg6fkA==", - "cpu": [ - "arm64" - ], - "libc": [ - "musl" - ], - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@yuku-codegen/binding-linux-x64-gnu": { - "version": "0.5.48", - "resolved": "https://registry.npmjs.org/@yuku-codegen/binding-linux-x64-gnu/-/binding-linux-x64-gnu-0.5.48.tgz", - "integrity": "sha512-csd4M1EVrGaohM8acM6gq1zpUA/Rwe2ulUMBKUcwQXm/k6n7cq1A++qdew78SOVb4do3JH1WE+WFwoGQAcWc1w==", - "cpu": [ - "x64" - ], - "libc": [ - "glibc" - ], - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@yuku-codegen/binding-linux-x64-musl": { - "version": "0.5.48", - "resolved": "https://registry.npmjs.org/@yuku-codegen/binding-linux-x64-musl/-/binding-linux-x64-musl-0.5.48.tgz", - "integrity": "sha512-KcDuEOT+GFoVKdvAWOv1v9iYjwnmvMZlO+j1Rw+5PYdeFLGWGzv/DD11y4SAAdwXIFcil4T0hibeIaF82WStMg==", - "cpu": [ - "x64" - ], - "libc": [ - "musl" - ], - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@yuku-codegen/binding-win32-arm64": { - "version": "0.5.48", - "resolved": "https://registry.npmjs.org/@yuku-codegen/binding-win32-arm64/-/binding-win32-arm64-0.5.48.tgz", - "integrity": "sha512-HI8qNrI8dWM5BuqIMKsqornRvTNFrE6sm5zToIJ9YIa9zt5+29P7fJ7Nr39EVf6dAWSb6q7JSpScJnRsQ+FgZA==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@yuku-codegen/binding-win32-x64": { - "version": "0.5.48", - "resolved": "https://registry.npmjs.org/@yuku-codegen/binding-win32-x64/-/binding-win32-x64-0.5.48.tgz", - "integrity": "sha512-X5YWJLO6EfBZpeBqO0AYESnUizbpFDWArcvVD61w0PEWQ3CaFRLnbQXs+kpM4ZZfGMfIE22zfA08QSY67q7TNQ==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@yuku-parser/binding-darwin-arm64": { - "version": "0.5.48", - "resolved": "https://registry.npmjs.org/@yuku-parser/binding-darwin-arm64/-/binding-darwin-arm64-0.5.48.tgz", - "integrity": "sha512-If8mb7HH3vqghJ2NNZ8SuHfhsnjVzOxJpB8xcNOXS5WjYrs2mUhHIh5KOIvK13hDOzh0htGeGK3A6MsiEqE7HQ==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@yuku-parser/binding-darwin-x64": { - "version": "0.5.48", - "resolved": "https://registry.npmjs.org/@yuku-parser/binding-darwin-x64/-/binding-darwin-x64-0.5.48.tgz", - "integrity": "sha512-EimvPXfspzxf1K11eB6tCW5oiQEXB8g84T2wP1TwzQagdDKo33bkmmVF0B32vTIpXnk/Ifu5IB61izZ1MylljA==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "darwin" - ] + "node_modules/@webassemblyjs/utf8": { + "version": "1.13.2", + "license": "MIT" }, - "node_modules/@yuku-parser/binding-freebsd-x64": { - "version": "0.5.48", - "resolved": "https://registry.npmjs.org/@yuku-parser/binding-freebsd-x64/-/binding-freebsd-x64-0.5.48.tgz", - "integrity": "sha512-0GcUMrumLHheThY9r5Tp46gaZYzn0irWPS1Zba6WY+vVQfhUtzGiWgXxI6tuXX0N32kEaaEVRpkKctvo6Kx3aQ==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "freebsd" - ] + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.14.1", + "license": "MIT", + "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" + } }, - "node_modules/@yuku-parser/binding-linux-arm-gnu": { - "version": "0.5.48", - "resolved": "https://registry.npmjs.org/@yuku-parser/binding-linux-arm-gnu/-/binding-linux-arm-gnu-0.5.48.tgz", - "integrity": "sha512-8S5T5wjCC73dmmpQeZ49aYsSunIUM3D4Fc6rdK96c+Ayg/p3FmeSPF3xuLZHejcTmqJIIvnbfPlUF+rB6DITjQ==", - "cpu": [ - "arm" - ], - "libc": [ - "glibc" - ], - "optional": true, - "os": [ - "linux" - ] + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.14.1", + "license": "MIT", + "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" + } }, - "node_modules/@yuku-parser/binding-linux-arm-musl": { - "version": "0.5.48", - "resolved": "https://registry.npmjs.org/@yuku-parser/binding-linux-arm-musl/-/binding-linux-arm-musl-0.5.48.tgz", - "integrity": "sha512-tTmbxvnUHcK2/crS9547vk2SMmsajH1yqJ8ltXhIuHJgqR1v+d9n9KT+kSayo/5CS76LegeYxhMFjEivBH2hFA==", - "cpu": [ - "arm" - ], - "libc": [ - "musl" - ], - "optional": true, - "os": [ - "linux" - ] + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.14.1", + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1" + } }, - "node_modules/@yuku-parser/binding-linux-arm64-gnu": { - "version": "0.5.48", - "resolved": "https://registry.npmjs.org/@yuku-parser/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-0.5.48.tgz", - "integrity": "sha512-KGYCBMqI2zfwyhgq5tpPVNe7jpUeYTBm8DhjdS+zqWNumde/PEC170QE5RHxcOAlsirIDeIUk0jqx+r/axoFSw==", - "cpu": [ - "arm64" - ], - "libc": [ - "glibc" - ], - "optional": true, - "os": [ - "linux" - ] + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.14.1", + "license": "MIT", + "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" + } }, - "node_modules/@yuku-parser/binding-linux-arm64-musl": { - "version": "0.5.48", - "resolved": "https://registry.npmjs.org/@yuku-parser/binding-linux-arm64-musl/-/binding-linux-arm64-musl-0.5.48.tgz", - "integrity": "sha512-2wTSMsCSXLTc2lZUjMAuU5X4cje55u205WJqfV5NWNF6j9pW/tXyxr15dJeekj8ziLqBXzIsj4DbRh4sY/WcjA==", - "cpu": [ - "arm64" - ], - "libc": [ - "musl" - ], - "optional": true, - "os": [ - "linux" - ] + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.14.1", + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@xtuc/long": "4.2.2" + } }, - "node_modules/@yuku-parser/binding-linux-x64-gnu": { - "version": "0.5.48", - "resolved": "https://registry.npmjs.org/@yuku-parser/binding-linux-x64-gnu/-/binding-linux-x64-gnu-0.5.48.tgz", - "integrity": "sha512-d/6v9UnGglVu1WC2JQyv/5aWSi5fXZeGSlidCfmHp4+N65N1GDKUnFtys5MK5eAPeAjTgSHGGtOc/yCcKTlv3A==", - "cpu": [ - "x64" - ], - "libc": [ - "glibc" - ], - "optional": true, - "os": [ - "linux" - ] + "node_modules/@webcontainer/env": { + "version": "1.1.1", + "license": "MIT" }, - "node_modules/@yuku-parser/binding-linux-x64-musl": { - "version": "0.5.48", - "resolved": "https://registry.npmjs.org/@yuku-parser/binding-linux-x64-musl/-/binding-linux-x64-musl-0.5.48.tgz", - "integrity": "sha512-gX19gw6u4ApPy7SYMPKfFlEkrtj6WlORvrTKK3sBQqjyV+8+mUAkQgxXNjHw4RnOiAmVYg7TOlZcg8d+Qqod9A==", - "cpu": [ - "x64" - ], - "libc": [ - "musl" - ], - "optional": true, - "os": [ - "linux" - ] + "node_modules/@webpack-cli/configtest": { + "version": "2.1.1", + "license": "MIT", + "engines": { + "node": ">=14.15.0" + }, + "peerDependencies": { + "webpack": "5.x.x", + "webpack-cli": "5.x.x" + } }, - "node_modules/@yuku-parser/binding-win32-arm64": { - "version": "0.5.48", - "resolved": "https://registry.npmjs.org/@yuku-parser/binding-win32-arm64/-/binding-win32-arm64-0.5.48.tgz", - "integrity": "sha512-w6cQQLbqj3Jcom5Q7ifm103NUOQ9d+Cb4VU5lkrZDjMnwVJ9Hzzg1vCQR7miJuF44vhCXldbme5UryE3giEKlA==", + "node_modules/@webpack-cli/info": { + "version": "2.0.2", + "license": "MIT", + "engines": { + "node": ">=14.15.0" + }, + "peerDependencies": { + "webpack": "5.x.x", + "webpack-cli": "5.x.x" + } + }, + "node_modules/@webpack-cli/serve": { + "version": "2.0.5", + "license": "MIT", + "engines": { + "node": ">=14.15.0" + }, + "peerDependencies": { + "webpack": "5.x.x", + "webpack-cli": "5.x.x" + }, + "peerDependenciesMeta": { + "webpack-dev-server": { + "optional": true + } + } + }, + "node_modules/@xn-sakina/rml-darwin-arm64": { + "version": "2.8.0", "cpu": [ "arm64" ], + "dev": true, + "license": "MIT", "optional": true, "os": [ - "win32" - ] - }, - "node_modules/@yuku-parser/binding-win32-x64": { - "version": "0.5.48", - "resolved": "https://registry.npmjs.org/@yuku-parser/binding-win32-x64/-/binding-win32-x64-0.5.48.tgz", - "integrity": "sha512-4gO0HmG7fzFxrw1rs0dUdnnaY9YgennjETqDWrTSp7x9fmTUOAoN4VsMfP7YyliQeG1WJJHc55O+rOhmsLppow==", - "cpu": [ - "x64" + "darwin" ], - "optional": true, - "os": [ - "win32" - ] + "engines": { + "node": ">=14" + } }, - "node_modules/@yuku-toolchain/types": { - "version": "0.5.43", - "resolved": "https://registry.npmjs.org/@yuku-toolchain/types/-/types-0.5.43.tgz", - "integrity": "sha512-kSpvPntnXw5+lYjO71ffBEnQ5ycQ74KGIYknh0TS4xeyCuBkOqxyJumxZkMhLBBUCLjDAbx2+Icnr3Zh4ftjpQ==", - "license": "MIT" + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "license": "BSD-3-Clause" + }, + "node_modules/@xtuc/long": { + "version": "4.2.2", + "license": "Apache-2.0" }, "node_modules/abbrev": { "version": "1.1.1", @@ -8993,7 +7885,6 @@ "node_modules/acorn-jsx": { "version": "5.3.2", "license": "MIT", - "peer": true, "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } @@ -9032,7 +7923,6 @@ "node_modules/ajv": { "version": "6.15.0", "license": "MIT", - "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -9078,9 +7968,7 @@ "license": "MIT" }, "node_modules/alien-signals": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/alien-signals/-/alien-signals-3.2.1.tgz", - "integrity": "sha512-I8FjmltrfnDFoZedi5CG8DghVYNhzb/Ijluz7tCSJH0xpd0484Kowhbb1XDYOxfJpU1p5wnM2X54dA+IfGyD1g==", + "version": "1.0.13", "dev": true, "license": "MIT" }, @@ -9128,6 +8016,14 @@ "node": ">=4" } }, + "node_modules/ansis": { + "version": "4.2.0", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + } + }, "node_modules/any-promise": { "version": "1.3.0", "dev": true, @@ -9328,25 +8224,6 @@ "node": ">=4" } }, - "node_modules/ast-v8-to-istanbul": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/ast-v8-to-istanbul/-/ast-v8-to-istanbul-1.0.4.tgz", - "integrity": "sha512-0bC0/4bTSrnwdhU3IsZDwEdojvuPrSg59OYZfKsLRtJZ0u8VBx9DebfqqG8bRdCC0I7vjgxmPi41P0lpkhJHtA==", - "devOptional": true, - "license": "MIT", - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.31", - "estree-walker": "^3.0.3", - "js-tokens": "^10.0.0" - } - }, - "node_modules/ast-v8-to-istanbul/node_modules/js-tokens": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-10.0.0.tgz", - "integrity": "sha512-lM/UBzQmfJRo9ABXbPWemivdCW8V2G8FHaHdypQaIy523snUjog0W71ayWXTjiR+ixeMyVHN2XcpnTd/liPg/Q==", - "devOptional": true, - "license": "MIT" - }, "node_modules/astral-regex": { "version": "2.0.0", "dev": true, @@ -9592,6 +8469,14 @@ "file-uri-to-path": "1.0.0" } }, + "node_modules/birpc": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, "node_modules/bl": { "version": "4.1.0", "dev": true, @@ -10220,7 +9105,7 @@ }, "node_modules/cjs-module-lexer": { "version": "1.4.3", - "devOptional": true, + "dev": true, "license": "MIT" }, "node_modules/clean-stack": { @@ -11608,6 +10493,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/de-indent": { + "version": "1.0.2", + "dev": true, + "license": "MIT" + }, "node_modules/debounce": { "version": "1.2.1", "dev": true, @@ -11641,8 +10531,7 @@ }, "node_modules/deep-is": { "version": "0.1.4", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/default-browser": { "version": "5.5.0", @@ -11730,6 +10619,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/defu": { + "version": "6.1.7", + "dev": true, + "license": "MIT" + }, "node_modules/del": { "version": "4.1.1", "license": "MIT", @@ -11904,6 +10798,16 @@ "node": ">=6" } }, + "node_modules/doctrine": { + "version": "3.0.0", + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/doctypes": { "version": "1.1.0", "dev": true, @@ -11911,7 +10815,10 @@ }, "node_modules/dom-accessibility-api": { "version": "0.5.16", - "license": "MIT" + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz", + "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==", + "license": "MIT", + "peer": true }, "node_modules/dom-serializer": { "version": "2.0.0", @@ -12004,6 +10911,25 @@ "webpack": "^4 || ^5" } }, + "node_modules/dts-resolver": { + "version": "2.1.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20.19.0" + }, + "funding": { + "url": "https://github.com/sponsors/sxzz" + }, + "peerDependencies": { + "oxc-resolver": ">=11.0.0" + }, + "peerDependenciesMeta": { + "oxc-resolver": { + "optional": true + } + } + }, "node_modules/dunder-proto": { "version": "1.0.1", "license": "MIT", @@ -12044,6 +10970,14 @@ "node": ">= 4" } }, + "node_modules/empathic": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + } + }, "node_modules/encodeurl": { "version": "2.0.0", "license": "MIT", @@ -12278,9 +11212,8 @@ "license": "MIT" }, "node_modules/esbuild": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.1.tgz", - "integrity": "sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==", + "version": "0.28.0", + "devOptional": true, "hasInstallScript": true, "license": "MIT", "bin": { @@ -12290,32 +11223,32 @@ "node": ">=18" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.28.1", - "@esbuild/android-arm": "0.28.1", - "@esbuild/android-arm64": "0.28.1", - "@esbuild/android-x64": "0.28.1", - "@esbuild/darwin-arm64": "0.28.1", - "@esbuild/darwin-x64": "0.28.1", - "@esbuild/freebsd-arm64": "0.28.1", - "@esbuild/freebsd-x64": "0.28.1", - "@esbuild/linux-arm": "0.28.1", - "@esbuild/linux-arm64": "0.28.1", - "@esbuild/linux-ia32": "0.28.1", - "@esbuild/linux-loong64": "0.28.1", - "@esbuild/linux-mips64el": "0.28.1", - "@esbuild/linux-ppc64": "0.28.1", - "@esbuild/linux-riscv64": "0.28.1", - "@esbuild/linux-s390x": "0.28.1", - "@esbuild/linux-x64": "0.28.1", - "@esbuild/netbsd-arm64": "0.28.1", - "@esbuild/netbsd-x64": "0.28.1", - "@esbuild/openbsd-arm64": "0.28.1", - "@esbuild/openbsd-x64": "0.28.1", - "@esbuild/openharmony-arm64": "0.28.1", - "@esbuild/sunos-x64": "0.28.1", - "@esbuild/win32-arm64": "0.28.1", - "@esbuild/win32-ia32": "0.28.1", - "@esbuild/win32-x64": "0.28.1" + "@esbuild/aix-ppc64": "0.28.0", + "@esbuild/android-arm": "0.28.0", + "@esbuild/android-arm64": "0.28.0", + "@esbuild/android-x64": "0.28.0", + "@esbuild/darwin-arm64": "0.28.0", + "@esbuild/darwin-x64": "0.28.0", + "@esbuild/freebsd-arm64": "0.28.0", + "@esbuild/freebsd-x64": "0.28.0", + "@esbuild/linux-arm": "0.28.0", + "@esbuild/linux-arm64": "0.28.0", + "@esbuild/linux-ia32": "0.28.0", + "@esbuild/linux-loong64": "0.28.0", + "@esbuild/linux-mips64el": "0.28.0", + "@esbuild/linux-ppc64": "0.28.0", + "@esbuild/linux-riscv64": "0.28.0", + "@esbuild/linux-s390x": "0.28.0", + "@esbuild/linux-x64": "0.28.0", + "@esbuild/netbsd-arm64": "0.28.0", + "@esbuild/netbsd-x64": "0.28.0", + "@esbuild/openbsd-arm64": "0.28.0", + "@esbuild/openbsd-x64": "0.28.0", + "@esbuild/openharmony-arm64": "0.28.0", + "@esbuild/sunos-x64": "0.28.0", + "@esbuild/win32-arm64": "0.28.0", + "@esbuild/win32-ia32": "0.28.0", + "@esbuild/win32-x64": "0.28.0" } }, "node_modules/escalade": { @@ -12339,7 +11272,6 @@ "node_modules/eslint": { "version": "9.39.4", "license": "MIT", - "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", @@ -12394,6 +11326,47 @@ } } }, + "node_modules/eslint-plugin-vue": { + "version": "9.33.0", + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "globals": "^13.24.0", + "natural-compare": "^1.4.0", + "nth-check": "^2.1.1", + "postcss-selector-parser": "^6.0.15", + "semver": "^7.6.3", + "vue-eslint-parser": "^9.4.3", + "xml-name-validator": "^4.0.0" + }, + "engines": { + "node": "^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.2.0 || ^7.0.0 || ^8.0.0 || ^9.0.0" + } + }, + "node_modules/eslint-plugin-vue/node_modules/postcss-selector-parser": { + "version": "6.1.2", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-plugin-vue/node_modules/semver": { + "version": "7.7.3", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/eslint-scope": { "version": "5.1.1", "license": "BSD-2-Clause", @@ -12415,7 +11388,6 @@ "node_modules/eslint/node_modules/ansi-styles": { "version": "4.3.0", "license": "MIT", - "peer": true, "dependencies": { "color-convert": "^2.0.1" }, @@ -12429,7 +11401,6 @@ "node_modules/eslint/node_modules/chalk": { "version": "4.1.2", "license": "MIT", - "peer": true, "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -12444,7 +11415,6 @@ "node_modules/eslint/node_modules/color-convert": { "version": "2.0.1", "license": "MIT", - "peer": true, "dependencies": { "color-name": "~1.1.4" }, @@ -12454,13 +11424,11 @@ }, "node_modules/eslint/node_modules/color-name": { "version": "1.1.4", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/eslint/node_modules/cross-spawn": { "version": "7.0.6", "license": "MIT", - "peer": true, "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -12473,7 +11441,6 @@ "node_modules/eslint/node_modules/escape-string-regexp": { "version": "4.0.0", "license": "MIT", - "peer": true, "engines": { "node": ">=10" }, @@ -12484,7 +11451,6 @@ "node_modules/eslint/node_modules/eslint-scope": { "version": "8.4.0", "license": "BSD-2-Clause", - "peer": true, "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" @@ -12499,7 +11465,6 @@ "node_modules/eslint/node_modules/eslint-visitor-keys": { "version": "4.2.1", "license": "Apache-2.0", - "peer": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, @@ -12510,7 +11475,6 @@ "node_modules/eslint/node_modules/espree": { "version": "10.4.0", "license": "BSD-2-Clause", - "peer": true, "dependencies": { "acorn": "^8.15.0", "acorn-jsx": "^5.3.2", @@ -12526,7 +11490,6 @@ "node_modules/eslint/node_modules/estraverse": { "version": "5.3.0", "license": "BSD-2-Clause", - "peer": true, "engines": { "node": ">=4.0" } @@ -12534,7 +11497,6 @@ "node_modules/eslint/node_modules/file-entry-cache": { "version": "8.0.0", "license": "MIT", - "peer": true, "dependencies": { "flat-cache": "^4.0.0" }, @@ -12545,7 +11507,6 @@ "node_modules/eslint/node_modules/flat-cache": { "version": "4.0.1", "license": "MIT", - "peer": true, "dependencies": { "flatted": "^3.2.9", "keyv": "^4.5.4" @@ -12557,7 +11518,6 @@ "node_modules/eslint/node_modules/glob-parent": { "version": "6.0.2", "license": "ISC", - "peer": true, "dependencies": { "is-glob": "^4.0.3" }, @@ -12568,7 +11528,6 @@ "node_modules/eslint/node_modules/has-flag": { "version": "4.0.0", "license": "MIT", - "peer": true, "engines": { "node": ">=8" } @@ -12576,7 +11535,6 @@ "node_modules/eslint/node_modules/ignore": { "version": "5.3.2", "license": "MIT", - "peer": true, "engines": { "node": ">= 4" } @@ -12584,7 +11542,6 @@ "node_modules/eslint/node_modules/keyv": { "version": "4.5.4", "license": "MIT", - "peer": true, "dependencies": { "json-buffer": "3.0.1" } @@ -12592,7 +11549,6 @@ "node_modules/eslint/node_modules/path-key": { "version": "3.1.1", "license": "MIT", - "peer": true, "engines": { "node": ">=8" } @@ -12600,7 +11556,6 @@ "node_modules/eslint/node_modules/shebang-command": { "version": "2.0.0", "license": "MIT", - "peer": true, "dependencies": { "shebang-regex": "^3.0.0" }, @@ -12611,7 +11566,6 @@ "node_modules/eslint/node_modules/shebang-regex": { "version": "3.0.0", "license": "MIT", - "peer": true, "engines": { "node": ">=8" } @@ -12619,7 +11573,6 @@ "node_modules/eslint/node_modules/supports-color": { "version": "7.2.0", "license": "MIT", - "peer": true, "dependencies": { "has-flag": "^4.0.0" }, @@ -12630,7 +11583,6 @@ "node_modules/eslint/node_modules/which": { "version": "2.0.2", "license": "ISC", - "peer": true, "dependencies": { "isexe": "^2.0.0" }, @@ -12646,6 +11598,31 @@ "dev": true, "license": "Apache-2.0" }, + "node_modules/espree": { + "version": "9.6.1", + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, "node_modules/esprima": { "version": "4.0.1", "license": "BSD-2-Clause", @@ -12660,7 +11637,6 @@ "node_modules/esquery": { "version": "1.6.0", "license": "BSD-3-Clause", - "peer": true, "dependencies": { "estraverse": "^5.1.0" }, @@ -12671,7 +11647,6 @@ "node_modules/esquery/node_modules/estraverse": { "version": "5.3.0", "license": "BSD-2-Clause", - "peer": true, "engines": { "node": ">=4.0" } @@ -12971,13 +11946,11 @@ }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/fast-levenshtein": { "version": "2.0.6", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/fast-uri": { "version": "3.1.0", @@ -13034,7 +12007,7 @@ }, "node_modules/fflate": { "version": "0.8.2", - "devOptional": true, + "dev": true, "license": "MIT" }, "node_modules/figures": { @@ -13621,6 +12594,17 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-tsconfig": { + "version": "4.14.0", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, "node_modules/get-value": { "version": "3.0.1", "license": "MIT", @@ -13707,6 +12691,19 @@ "node": ">=6" } }, + "node_modules/globals": { + "version": "13.24.0", + "license": "MIT", + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/globalthis": { "version": "1.0.4", "dev": true, @@ -13723,9 +12720,7 @@ } }, "node_modules/globby": { - "version": "16.2.2", - "resolved": "https://registry.npmjs.org/globby/-/globby-16.2.2.tgz", - "integrity": "sha512-NLvV9ubZ6NDsJaOpKPy3cQeJpKi9DcWiyCiFUpJPA0YihRqiE6RWaLUmgNNPr8MgPpLZjnBjSmou7uZBRJv9wA==", + "version": "16.2.0", "dev": true, "license": "MIT", "dependencies": { @@ -13811,6 +12806,10 @@ "version": "4.2.11", "license": "ISC" }, + "node_modules/graphemer": { + "version": "1.4.0", + "license": "MIT" + }, "node_modules/graphiql": { "version": "4.1.2", "license": "MIT", @@ -14021,6 +13020,14 @@ "node": ">= 0.4" } }, + "node_modules/he": { + "version": "1.2.0", + "dev": true, + "license": "MIT", + "bin": { + "he": "bin/he" + } + }, "node_modules/highlight.js": { "version": "10.7.3", "dev": true, @@ -14109,7 +13116,7 @@ }, "node_modules/html-escaper": { "version": "2.0.2", - "devOptional": true, + "dev": true, "license": "MIT" }, "node_modules/html-tags": { @@ -14423,6 +13430,17 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/import-without-cache": { + "version": "0.3.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20.19.0" + }, + "funding": { + "url": "https://github.com/sponsors/sxzz" + } + }, "node_modules/imurmurhash": { "version": "0.1.4", "license": "MIT", @@ -14989,6 +14007,13 @@ "node": ">=6" } }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/is-plain-obj": { "version": "3.0.0", "license": "MIT", @@ -15236,7 +14261,7 @@ }, "node_modules/istanbul-lib-coverage": { "version": "3.2.2", - "devOptional": true, + "dev": true, "license": "BSD-3-Clause", "engines": { "node": ">=8" @@ -15244,7 +14269,7 @@ }, "node_modules/istanbul-lib-report": { "version": "3.0.1", - "devOptional": true, + "dev": true, "license": "BSD-3-Clause", "dependencies": { "istanbul-lib-coverage": "^3.0.0", @@ -15257,7 +14282,7 @@ }, "node_modules/istanbul-lib-report/node_modules/has-flag": { "version": "4.0.0", - "devOptional": true, + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -15265,7 +14290,7 @@ }, "node_modules/istanbul-lib-report/node_modules/supports-color": { "version": "7.2.0", - "devOptional": true, + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -15276,7 +14301,7 @@ }, "node_modules/istanbul-reports": { "version": "3.2.0", - "devOptional": true, + "dev": true, "license": "BSD-3-Clause", "dependencies": { "html-escaper": "^2.0.0", @@ -15472,8 +14497,7 @@ }, "node_modules/json-buffer": { "version": "3.0.1", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/json-minimizer-webpack-plugin": { "version": "4.0.0", @@ -15502,13 +14526,11 @@ }, "node_modules/json-schema-traverse": { "version": "0.4.1", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/json5": { "version": "2.2.3", @@ -15520,12 +14542,6 @@ "node": ">=6" } }, - "node_modules/jsonc-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", - "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==", - "license": "MIT" - }, "node_modules/jsonfile": { "version": "6.2.1", "license": "MIT", @@ -15628,7 +14644,6 @@ "node_modules/levn": { "version": "0.4.1", "license": "MIT", - "peer": true, "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" @@ -15656,7 +14671,6 @@ }, "node_modules/lightningcss": { "version": "1.32.0", - "dev": true, "license": "MPL-2.0", "dependencies": { "detect-libc": "^2.0.3" @@ -15689,7 +14703,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MPL-2.0", "optional": true, "os": [ @@ -15708,7 +14721,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MPL-2.0", "optional": true, "os": [ @@ -15729,7 +14741,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MPL-2.0", "optional": true, "os": [ @@ -15750,7 +14761,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MPL-2.0", "optional": true, "os": [ @@ -15771,7 +14781,6 @@ "cpu": [ "arm" ], - "dev": true, "license": "MPL-2.0", "optional": true, "os": [ @@ -15792,7 +14801,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MPL-2.0", "optional": true, "os": [ @@ -15813,7 +14821,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MPL-2.0", "optional": true, "os": [ @@ -15834,7 +14841,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MPL-2.0", "optional": true, "os": [ @@ -15855,7 +14861,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MPL-2.0", "optional": true, "os": [ @@ -15876,7 +14881,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MPL-2.0", "optional": true, "os": [ @@ -15897,7 +14901,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MPL-2.0", "optional": true, "os": [ @@ -16101,8 +15104,7 @@ }, "node_modules/lodash.merge": { "version": "4.6.2", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/lodash.truncate": { "version": "4.4.2", @@ -16216,7 +15218,7 @@ }, "node_modules/lru-cache": { "version": "11.2.2", - "devOptional": true, + "dev": true, "license": "ISC", "engines": { "node": "20 || >=22" @@ -16224,7 +15226,10 @@ }, "node_modules/lz-string": { "version": "1.5.0", + "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz", + "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", "license": "MIT", + "peer": true, "bin": { "lz-string": "bin/bin.js" } @@ -16236,21 +15241,9 @@ "@jridgewell/sourcemap-codec": "^1.5.5" } }, - "node_modules/magicast": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.5.3.tgz", - "integrity": "sha512-pVKE4UdSQ7DvHzivsCIFx2BJn1mHG6KsyrFcaxFx6tONdneEuThrDx0Cj3AMg58KyN4pzYT+LHOotxDQDjNvkw==", - "devOptional": true, - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.29.3", - "@babel/types": "^7.29.0", - "source-map-js": "^1.2.1" - } - }, "node_modules/make-dir": { "version": "4.0.0", - "devOptional": true, + "dev": true, "license": "MIT", "dependencies": { "semver": "^7.5.3" @@ -16264,7 +15257,7 @@ }, "node_modules/make-dir/node_modules/semver": { "version": "7.7.3", - "devOptional": true, + "dev": true, "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -16327,10 +15320,6 @@ "node": ">=0.10.0" } }, - "node_modules/markdown-actions": { - "version": "1.1.2", - "license": "MIT" - }, "node_modules/markdown-it": { "version": "14.1.0", "license": "MIT", @@ -16891,6 +15880,23 @@ "version": "2.26.2", "license": "MIT" }, + "node_modules/nanoid": { + "version": "5.1.6", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.js" + }, + "engines": { + "node": "^18 || >=20" + } + }, "node_modules/nanospinner": { "version": "1.2.2", "dev": true, @@ -16901,8 +15907,7 @@ }, "node_modules/natural-compare": { "version": "1.4.0", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/negotiator": { "version": "0.6.4", @@ -17307,7 +16312,6 @@ "node_modules/optionator": { "version": "0.9.4", "license": "MIT", - "peer": true, "dependencies": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", @@ -17467,16 +16471,6 @@ "node": ">=8" } }, - "node_modules/overtype": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/overtype/-/overtype-2.4.0.tgz", - "integrity": "sha512-V5HJcdwyN/Lye1vvU0d47y1VaEqSGsWRdCa3ZCZB/DZHdR840i1z0oBGYAmbLe/I2H2cxLx9Bv3tuVl4dTgUpA==", - "license": "MIT", - "dependencies": { - "@floating-ui/dom": "^1.7.4", - "markdown-actions": "^1.1.2" - } - }, "node_modules/own-keys": { "version": "1.0.1", "dev": true, @@ -17559,125 +16553,6 @@ "@oxc-resolver/binding-win32-x64-msvc": "11.19.1" } }, - "node_modules/oxfmt": { - "version": "0.60.0", - "resolved": "https://registry.npmjs.org/oxfmt/-/oxfmt-0.60.0.tgz", - "integrity": "sha512-fViX6i+gJuZWY+jI/fnR6WRbRj70GZ9RlCd30MygJrHTUNc4DxvKHWw8vBjMjffv3PgU5qWDR0AzmojQByqaZA==", - "devOptional": true, - "license": "MIT", - "dependencies": { - "tinypool": "2.1.0" - }, - "bin": { - "oxfmt": "bin/oxfmt" - }, - "engines": { - "node": "^20.19.0 || >=22.12.0" - }, - "funding": { - "url": "https://github.com/sponsors/Boshen" - }, - "optionalDependencies": { - "@oxfmt/binding-android-arm-eabi": "0.60.0", - "@oxfmt/binding-android-arm64": "0.60.0", - "@oxfmt/binding-darwin-arm64": "0.60.0", - "@oxfmt/binding-darwin-x64": "0.60.0", - "@oxfmt/binding-freebsd-x64": "0.60.0", - "@oxfmt/binding-linux-arm-gnueabihf": "0.60.0", - "@oxfmt/binding-linux-arm-musleabihf": "0.60.0", - "@oxfmt/binding-linux-arm64-gnu": "0.60.0", - "@oxfmt/binding-linux-arm64-musl": "0.60.0", - "@oxfmt/binding-linux-ppc64-gnu": "0.60.0", - "@oxfmt/binding-linux-riscv64-gnu": "0.60.0", - "@oxfmt/binding-linux-riscv64-musl": "0.60.0", - "@oxfmt/binding-linux-s390x-gnu": "0.60.0", - "@oxfmt/binding-linux-x64-gnu": "0.60.0", - "@oxfmt/binding-linux-x64-musl": "0.60.0", - "@oxfmt/binding-openharmony-arm64": "0.60.0", - "@oxfmt/binding-win32-arm64-msvc": "0.60.0", - "@oxfmt/binding-win32-ia32-msvc": "0.60.0", - "@oxfmt/binding-win32-x64-msvc": "0.60.0" - }, - "peerDependencies": { - "svelte": "^5.0.0", - "vite-plus": "*" - }, - "peerDependenciesMeta": { - "svelte": { - "optional": true - }, - "vite-plus": { - "optional": true - } - } - }, - "node_modules/oxlint": { - "version": "1.75.0", - "resolved": "https://registry.npmjs.org/oxlint/-/oxlint-1.75.0.tgz", - "integrity": "sha512-m9WzjRcRYA/uqIZDa9tclrieoPJ/ln1QYTKdFx6NUOs8uY5DiHlIwRQoCrHT6OM6O3ww3l2skY5gO7G7ZphE7g==", - "devOptional": true, - "license": "MIT", - "bin": { - "oxlint": "bin/oxlint" - }, - "engines": { - "node": "^20.19.0 || >=22.12.0" - }, - "funding": { - "url": "https://github.com/sponsors/Boshen" - }, - "optionalDependencies": { - "@oxlint/binding-android-arm-eabi": "1.75.0", - "@oxlint/binding-android-arm64": "1.75.0", - "@oxlint/binding-darwin-arm64": "1.75.0", - "@oxlint/binding-darwin-x64": "1.75.0", - "@oxlint/binding-freebsd-x64": "1.75.0", - "@oxlint/binding-linux-arm-gnueabihf": "1.75.0", - "@oxlint/binding-linux-arm-musleabihf": "1.75.0", - "@oxlint/binding-linux-arm64-gnu": "1.75.0", - "@oxlint/binding-linux-arm64-musl": "1.75.0", - "@oxlint/binding-linux-ppc64-gnu": "1.75.0", - "@oxlint/binding-linux-riscv64-gnu": "1.75.0", - "@oxlint/binding-linux-riscv64-musl": "1.75.0", - "@oxlint/binding-linux-s390x-gnu": "1.75.0", - "@oxlint/binding-linux-x64-gnu": "1.75.0", - "@oxlint/binding-linux-x64-musl": "1.75.0", - "@oxlint/binding-openharmony-arm64": "1.75.0", - "@oxlint/binding-win32-arm64-msvc": "1.75.0", - "@oxlint/binding-win32-ia32-msvc": "1.75.0", - "@oxlint/binding-win32-x64-msvc": "1.75.0" - }, - "peerDependencies": { - "oxlint-tsgolint": ">=7.0.2001", - "vite-plus": "*" - }, - "peerDependenciesMeta": { - "oxlint-tsgolint": { - "optional": true - }, - "vite-plus": { - "optional": true - } - } - }, - "node_modules/oxlint-tsgolint": { - "version": "7.0.2001", - "resolved": "https://registry.npmjs.org/oxlint-tsgolint/-/oxlint-tsgolint-7.0.2001.tgz", - "integrity": "sha512-KjK/XLcXr1DSyonKhsuFqJRiuKqcyG9j3LJ8nkOsrLzGvodBPqzHOKauy10asLMDI0sUpvb+1sxlzff3udZvfg==", - "devOptional": true, - "license": "MIT", - "bin": { - "tsgolint": "bin/tsgolint.js" - }, - "optionalDependencies": { - "@oxlint-tsgolint/darwin-arm64": "7.0.2001", - "@oxlint-tsgolint/darwin-x64": "7.0.2001", - "@oxlint-tsgolint/linux-arm64": "7.0.2001", - "@oxlint-tsgolint/linux-x64": "7.0.2001", - "@oxlint-tsgolint/win32-arm64": "7.0.2001", - "@oxlint-tsgolint/win32-x64": "7.0.2001" - } - }, "node_modules/p-limit": { "version": "3.1.0", "license": "MIT", @@ -18484,14 +17359,268 @@ "postcss": "^8.4.31" } }, - "node_modules/postcss-merge-rules": { - "version": "6.1.1", + "node_modules/postcss-merge-rules": { + "version": "6.1.1", + "license": "MIT", + "dependencies": { + "browserslist": "^4.23.0", + "caniuse-api": "^3.0.0", + "cssnano-utils": "^4.0.2", + "postcss-selector-parser": "^6.0.16" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-merge-rules/node_modules/postcss-selector-parser": { + "version": "6.1.2", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-minify-font-values": { + "version": "6.1.0", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-minify-gradients": { + "version": "6.0.3", + "license": "MIT", + "dependencies": { + "colord": "^2.9.3", + "cssnano-utils": "^4.0.2", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-minify-params": { + "version": "6.1.0", + "license": "MIT", + "dependencies": { + "browserslist": "^4.23.0", + "cssnano-utils": "^4.0.2", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-minify-selectors": { + "version": "6.0.4", + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^6.0.16" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-minify-selectors/node_modules/postcss-selector-parser": { + "version": "6.1.2", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-modules-extract-imports": { + "version": "3.1.0", + "license": "ISC", + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-local-by-default": { + "version": "4.2.0", + "license": "MIT", + "dependencies": { + "icss-utils": "^5.0.0", + "postcss-selector-parser": "^7.0.0", + "postcss-value-parser": "^4.1.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-scope": { + "version": "3.2.1", + "license": "ISC", + "dependencies": { + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-values": { + "version": "4.0.0", + "license": "ISC", + "dependencies": { + "icss-utils": "^5.0.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-nested": { + "version": "6.2.0", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^6.1.1" + }, + "engines": { + "node": ">=12.0" + }, + "peerDependencies": { + "postcss": "^8.2.14" + } + }, + "node_modules/postcss-nested/node_modules/postcss-selector-parser": { + "version": "6.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-normalize-charset": { + "version": "6.0.2", + "license": "MIT", + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-display-values": { + "version": "6.0.2", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-positions": { + "version": "6.0.2", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-repeat-style": { + "version": "6.0.2", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-string": { + "version": "6.0.2", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-timing-functions": { + "version": "6.0.2", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-unicode": { + "version": "6.1.0", "license": "MIT", "dependencies": { "browserslist": "^4.23.0", - "caniuse-api": "^3.0.0", - "cssnano-utils": "^4.0.2", - "postcss-selector-parser": "^6.0.16" + "postcss-value-parser": "^4.2.0" }, "engines": { "node": "^14 || ^16 || >=18.0" @@ -18500,19 +17629,21 @@ "postcss": "^8.4.31" } }, - "node_modules/postcss-merge-rules/node_modules/postcss-selector-parser": { - "version": "6.1.2", + "node_modules/postcss-normalize-url": { + "version": "6.0.2", "license": "MIT", "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" + "postcss-value-parser": "^4.2.0" }, "engines": { - "node": ">=4" + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" } }, - "node_modules/postcss-minify-font-values": { - "version": "6.1.0", + "node_modules/postcss-normalize-whitespace": { + "version": "6.0.2", "license": "MIT", "dependencies": { "postcss-value-parser": "^4.2.0" @@ -18524,11 +17655,10 @@ "postcss": "^8.4.31" } }, - "node_modules/postcss-minify-gradients": { - "version": "6.0.3", + "node_modules/postcss-ordered-values": { + "version": "6.0.2", "license": "MIT", "dependencies": { - "colord": "^2.9.3", "cssnano-utils": "^4.0.2", "postcss-value-parser": "^4.2.0" }, @@ -18539,13 +17669,12 @@ "postcss": "^8.4.31" } }, - "node_modules/postcss-minify-params": { + "node_modules/postcss-reduce-initial": { "version": "6.1.0", "license": "MIT", "dependencies": { "browserslist": "^4.23.0", - "cssnano-utils": "^4.0.2", - "postcss-value-parser": "^4.2.0" + "caniuse-api": "^3.0.0" }, "engines": { "node": "^14 || ^16 || >=18.0" @@ -18554,11 +17683,11 @@ "postcss": "^8.4.31" } }, - "node_modules/postcss-minify-selectors": { - "version": "6.0.4", + "node_modules/postcss-reduce-transforms": { + "version": "6.0.2", "license": "MIT", "dependencies": { - "postcss-selector-parser": "^6.0.16" + "postcss-value-parser": "^4.2.0" }, "engines": { "node": "^14 || ^16 || >=18.0" @@ -18567,1015 +17696,1148 @@ "postcss": "^8.4.31" } }, - "node_modules/postcss-minify-selectors/node_modules/postcss-selector-parser": { - "version": "6.1.2", + "node_modules/postcss-resolve-nested-selector": { + "version": "0.1.6", + "dev": true, + "license": "MIT" + }, + "node_modules/postcss-safe-parser": { + "version": "7.0.1", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss-safe-parser" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], "license": "MIT", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, "engines": { - "node": ">=4" + "node": ">=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" } }, - "node_modules/postcss-modules-extract-imports": { - "version": "3.1.0", - "license": "ISC", + "node_modules/postcss-scss": { + "version": "4.0.9", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss-scss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", "engines": { - "node": "^10 || ^12 || >= 14" + "node": ">=12.0" }, "peerDependencies": { - "postcss": "^8.1.0" + "postcss": "^8.4.29" } }, - "node_modules/postcss-modules-local-by-default": { - "version": "4.2.0", + "node_modules/postcss-selector-parser": { + "version": "7.1.0", "license": "MIT", "dependencies": { - "icss-utils": "^5.0.0", - "postcss-selector-parser": "^7.0.0", - "postcss-value-parser": "^4.1.0" + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" }, "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" + "node": ">=4" } }, - "node_modules/postcss-modules-scope": { - "version": "3.2.1", - "license": "ISC", + "node_modules/postcss-svgo": { + "version": "6.0.3", + "license": "MIT", "dependencies": { - "postcss-selector-parser": "^7.0.0" + "postcss-value-parser": "^4.2.0", + "svgo": "^3.2.0" }, "engines": { - "node": "^10 || ^12 || >= 14" + "node": "^14 || ^16 || >= 18" }, "peerDependencies": { - "postcss": "^8.1.0" + "postcss": "^8.4.31" } }, - "node_modules/postcss-modules-values": { - "version": "4.0.0", - "license": "ISC", + "node_modules/postcss-unique-selectors": { + "version": "6.0.4", + "license": "MIT", "dependencies": { - "icss-utils": "^5.0.0" + "postcss-selector-parser": "^6.0.16" }, "engines": { - "node": "^10 || ^12 || >= 14" + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.1.0" + "postcss": "^8.4.31" } }, - "node_modules/postcss-nested": { - "version": "6.2.0", - "dev": true, + "node_modules/postcss-unique-selectors/node_modules/postcss-selector-parser": { + "version": "6.1.2", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "license": "MIT" + }, + "node_modules/postcss/node_modules/nanoid": { + "version": "3.3.11", "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, { "type": "github", "url": "https://github.com/sponsors/ai" } ], "license": "MIT", - "dependencies": { - "postcss-selector-parser": "^6.1.1" + "bin": { + "nanoid": "bin/nanoid.cjs" }, "engines": { - "node": ">=12.0" - }, - "peerDependencies": { - "postcss": "^8.2.14" + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, - "node_modules/postcss-nested/node_modules/postcss-selector-parser": { - "version": "6.1.2", + "node_modules/prelude-ls": { + "version": "1.2.1", + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/presentable-error": { + "version": "0.0.1", "dev": true, "license": "MIT", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, "engines": { - "node": ">=4" + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/postcss-normalize-charset": { - "version": "6.0.2", + "node_modules/prettier": { + "version": "3.8.3", + "devOptional": true, "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" + }, "engines": { - "node": "^14 || ^16 || >=18.0" + "node": ">=14" }, - "peerDependencies": { - "postcss": "^8.4.31" + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" } }, - "node_modules/postcss-normalize-display-values": { - "version": "6.0.2", + "node_modules/prettier-linter-helpers": { + "version": "1.0.0", + "dev": true, "license": "MIT", "dependencies": { - "postcss-value-parser": "^4.2.0" + "fast-diff": "^1.1.2" }, "engines": { - "node": "^14 || ^16 || >=18.0" + "node": ">=6.0.0" + } + }, + "node_modules/pretty-format": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", + "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" }, - "peerDependencies": { - "postcss": "^8.4.31" + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/pretty-format/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "license": "MIT" + }, + "node_modules/promise": { + "version": "7.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "asap": "~2.0.3" } }, - "node_modules/postcss-normalize-positions": { - "version": "6.0.2", + "node_modules/promise-inflight": { + "version": "1.0.1", + "license": "ISC" + }, + "node_modules/promise-retry": { + "version": "2.0.1", "license": "MIT", "dependencies": { - "postcss-value-parser": "^4.2.0" + "err-code": "^2.0.2", + "retry": "^0.12.0" }, "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" + "node": ">=10" } }, - "node_modules/postcss-normalize-repeat-style": { - "version": "6.0.2", + "node_modules/promise-retry/node_modules/retry": { + "version": "0.12.0", "license": "MIT", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" + "node": ">= 4" } }, - "node_modules/postcss-normalize-string": { - "version": "6.0.2", + "node_modules/proxy-addr": { + "version": "2.0.7", "license": "MIT", "dependencies": { - "postcss-value-parser": "^4.2.0" + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" }, "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" + "node": ">= 0.10" } }, - "node_modules/postcss-normalize-timing-functions": { - "version": "6.0.2", + "node_modules/proxy-addr/node_modules/ipaddr.js": { + "version": "1.9.1", "license": "MIT", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" + "node": ">= 0.10" } }, - "node_modules/postcss-normalize-unicode": { - "version": "6.1.0", + "node_modules/proxy-from-env": { + "version": "2.1.0", "license": "MIT", - "dependencies": { - "browserslist": "^4.23.0", - "postcss-value-parser": "^4.2.0" - }, "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" + "node": ">=10" } }, - "node_modules/postcss-normalize-url": { - "version": "6.0.2", + "node_modules/prr": { + "version": "1.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/pseudomap": { + "version": "1.0.2", + "license": "ISC" + }, + "node_modules/pug": { + "version": "3.0.4", + "dev": true, "license": "MIT", "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" + "pug-code-gen": "^3.0.4", + "pug-filters": "^4.0.0", + "pug-lexer": "^5.0.1", + "pug-linker": "^4.0.0", + "pug-load": "^3.0.0", + "pug-parser": "^6.0.0", + "pug-runtime": "^3.0.1", + "pug-strip-comments": "^2.0.0" } }, - "node_modules/postcss-normalize-whitespace": { - "version": "6.0.2", + "node_modules/pug-attrs": { + "version": "3.0.0", + "dev": true, "license": "MIT", "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" + "constantinople": "^4.0.1", + "js-stringify": "^1.0.2", + "pug-runtime": "^3.0.0" } }, - "node_modules/postcss-ordered-values": { - "version": "6.0.2", + "node_modules/pug-code-gen": { + "version": "3.0.4", + "dev": true, "license": "MIT", "dependencies": { - "cssnano-utils": "^4.0.2", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" + "constantinople": "^4.0.1", + "doctypes": "^1.1.0", + "js-stringify": "^1.0.2", + "pug-attrs": "^3.0.0", + "pug-error": "^2.1.0", + "pug-runtime": "^3.0.1", + "void-elements": "^3.1.0", + "with": "^7.0.0" } }, - "node_modules/postcss-reduce-initial": { - "version": "6.1.0", + "node_modules/pug-error": { + "version": "2.1.0", + "dev": true, + "license": "MIT" + }, + "node_modules/pug-filters": { + "version": "4.0.0", + "dev": true, "license": "MIT", "dependencies": { - "browserslist": "^4.23.0", - "caniuse-api": "^3.0.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" + "constantinople": "^4.0.1", + "jstransformer": "1.0.0", + "pug-error": "^2.0.0", + "pug-walk": "^2.0.0", + "resolve": "^1.15.1" } }, - "node_modules/postcss-reduce-transforms": { - "version": "6.0.2", + "node_modules/pug-lexer": { + "version": "5.0.1", + "dev": true, "license": "MIT", "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" + "character-parser": "^2.2.0", + "is-expression": "^4.0.0", + "pug-error": "^2.0.0" } }, - "node_modules/postcss-resolve-nested-selector": { - "version": "0.1.6", + "node_modules/pug-linker": { + "version": "4.0.0", "dev": true, - "license": "MIT" + "license": "MIT", + "dependencies": { + "pug-error": "^2.0.0", + "pug-walk": "^2.0.0" + } }, - "node_modules/postcss-safe-parser": { - "version": "7.0.1", + "node_modules/pug-load": { + "version": "3.0.0", "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss-safe-parser" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], "license": "MIT", - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" + "dependencies": { + "object-assign": "^4.1.1", + "pug-walk": "^2.0.0" } }, - "node_modules/postcss-scss": { - "version": "4.0.9", + "node_modules/pug-parser": { + "version": "6.0.0", "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss-scss" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], "license": "MIT", - "engines": { - "node": ">=12.0" - }, - "peerDependencies": { - "postcss": "^8.4.29" + "dependencies": { + "pug-error": "^2.0.0", + "token-stream": "1.0.0" } }, - "node_modules/postcss-selector-parser": { - "version": "7.1.0", + "node_modules/pug-runtime": { + "version": "3.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/pug-strip-comments": { + "version": "2.0.0", + "dev": true, "license": "MIT", "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" + "pug-error": "^2.0.0" } }, - "node_modules/postcss-svgo": { - "version": "6.0.3", + "node_modules/pug-walk": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/punycode": { + "version": "2.3.1", "license": "MIT", - "dependencies": { - "postcss-value-parser": "^4.2.0", - "svgo": "^3.2.0" - }, "engines": { - "node": "^14 || ^16 || >= 18" - }, - "peerDependencies": { - "postcss": "^8.4.31" + "node": ">=6" } }, - "node_modules/postcss-unique-selectors": { - "version": "6.0.4", + "node_modules/punycode.js": { + "version": "2.3.1", "license": "MIT", - "dependencies": { - "postcss-selector-parser": "^6.0.16" - }, "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" + "node": ">=6" } }, - "node_modules/postcss-unique-selectors/node_modules/postcss-selector-parser": { - "version": "6.1.2", + "node_modules/qified": { + "version": "0.6.0", + "dev": true, "license": "MIT", "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" + "hookified": "^1.14.0" }, "engines": { - "node": ">=4" + "node": ">=20" } }, - "node_modules/postcss-value-parser": { - "version": "4.2.0", + "node_modules/qr-creator": { + "version": "1.0.0", + "dev": true, "license": "MIT" }, - "node_modules/postcss/node_modules/nanoid": { - "version": "3.3.11", + "node_modules/quansync": { + "version": "0.2.11", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/antfu" + }, + { + "type": "individual", + "url": "https://github.com/sponsors/sxzz" + } + ], + "license": "MIT" + }, + "node_modules/queue-microtask": { + "version": "1.2.3", "funding": [ { "type": "github", - "url": "https://github.com/sponsors/ai" + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" } ], + "license": "MIT" + }, + "node_modules/raf-schd": { + "version": "4.0.3", + "license": "MIT" + }, + "node_modules/randombytes": { + "version": "2.1.0", "license": "MIT", - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + "dependencies": { + "safe-buffer": "^5.1.0" } }, - "node_modules/prelude-ls": { + "node_modules/range-parser": { "version": "1.2.1", "license": "MIT", - "peer": true, "engines": { - "node": ">= 0.8.0" + "node": ">= 0.6" } }, - "node_modules/presentable-error": { - "version": "0.0.1", - "dev": true, + "node_modules/raw-body": { + "version": "2.5.2", "license": "MIT", - "engines": { - "node": ">=16" + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": ">= 0.8" } }, - "node_modules/prettier": { - "version": "3.8.3", - "devOptional": true, + "node_modules/raw-body/node_modules/iconv-lite": { + "version": "0.4.24", "license": "MIT", - "peer": true, - "bin": { - "prettier": "bin/prettier.cjs" + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" }, "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" + "node": ">=0.10.0" } }, - "node_modules/prettier-linter-helpers": { - "version": "1.0.0", - "dev": true, + "node_modules/react": { + "version": "19.2.5", "license": "MIT", - "dependencies": { - "fast-diff": "^1.1.2" - }, "engines": { - "node": ">=6.0.0" + "node": ">=0.10.0" } }, - "node_modules/pretty-format": { - "version": "27.5.1", - "license": "MIT", + "node_modules/react-aria": { + "version": "3.48.0", + "license": "Apache-2.0", "dependencies": { - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^17.0.1" + "@internationalized/date": "^3.12.1", + "@internationalized/number": "^3.6.6", + "@internationalized/string": "^3.2.8", + "@react-types/shared": "^3.34.0", + "@swc/helpers": "^0.5.0", + "aria-hidden": "^1.2.3", + "clsx": "^2.0.0", + "react-stately": "3.46.0", + "use-sync-external-store": "^1.6.0" }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, - "node_modules/pretty-format/node_modules/ansi-regex": { - "version": "5.0.1", + "node_modules/react-aria/node_modules/clsx": { + "version": "2.1.1", "license": "MIT", "engines": { - "node": ">=8" + "node": ">=6" } }, - "node_modules/pretty-format/node_modules/ansi-styles": { - "version": "5.2.0", + "node_modules/react-compiler-runtime": { + "version": "19.1.0-rc.1", "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "peerDependencies": { + "react": "^17.0.0 || ^18.0.0 || ^19.0.0 || ^0.0.0-experimental" } }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "license": "MIT" - }, - "node_modules/promise": { - "version": "7.3.1", - "dev": true, + "node_modules/react-dom": { + "version": "19.2.5", "license": "MIT", "dependencies": { - "asap": "~2.0.3" + "scheduler": "^0.27.0" + }, + "peerDependencies": { + "react": "^19.2.5" } }, - "node_modules/promise-inflight": { - "version": "1.0.1", - "license": "ISC" + "node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "license": "MIT", + "peer": true }, - "node_modules/promise-retry": { - "version": "2.0.1", + "node_modules/react-remove-scroll": { + "version": "2.7.1", "license": "MIT", "dependencies": { - "err-code": "^2.0.2", - "retry": "^0.12.0" + "react-remove-scroll-bar": "^2.3.7", + "react-style-singleton": "^2.2.3", + "tslib": "^2.1.0", + "use-callback-ref": "^1.3.3", + "use-sidecar": "^1.1.3" }, "engines": { "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, - "node_modules/promise-retry/node_modules/retry": { - "version": "0.12.0", - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/proxy-addr": { - "version": "2.0.7", + "node_modules/react-remove-scroll-bar": { + "version": "2.3.8", "license": "MIT", "dependencies": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" + "react-style-singleton": "^2.2.2", + "tslib": "^2.0.0" }, "engines": { - "node": ">= 0.10" + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, - "node_modules/proxy-addr/node_modules/ipaddr.js": { - "version": "1.9.1", - "license": "MIT", - "engines": { - "node": ">= 0.10" + "node_modules/react-stately": { + "version": "3.46.0", + "license": "Apache-2.0", + "dependencies": { + "@internationalized/date": "^3.12.1", + "@internationalized/number": "^3.6.6", + "@internationalized/string": "^3.2.8", + "@react-types/shared": "^3.34.0", + "@swc/helpers": "^0.5.0", + "use-sync-external-store": "^1.6.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, - "node_modules/proxy-from-env": { - "version": "2.1.0", + "node_modules/react-style-singleton": { + "version": "2.2.3", "license": "MIT", + "dependencies": { + "get-nonce": "^1.0.0", + "tslib": "^2.0.0" + }, "engines": { "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, - "node_modules/prr": { - "version": "1.0.1", - "dev": true, - "license": "MIT" - }, - "node_modules/pseudomap": { - "version": "1.0.2", - "license": "ISC" - }, - "node_modules/pug": { - "version": "3.0.4", + "node_modules/read-cache": { + "version": "1.0.0", "dev": true, "license": "MIT", "dependencies": { - "pug-code-gen": "^3.0.4", - "pug-filters": "^4.0.0", - "pug-lexer": "^5.0.1", - "pug-linker": "^4.0.0", - "pug-load": "^3.0.0", - "pug-parser": "^6.0.0", - "pug-runtime": "^3.0.1", - "pug-strip-comments": "^2.0.0" + "pify": "^2.3.0" } }, - "node_modules/pug-attrs": { - "version": "3.0.0", + "node_modules/read-cache/node_modules/pify": { + "version": "2.3.0", "dev": true, "license": "MIT", - "dependencies": { - "constantinople": "^4.0.1", - "js-stringify": "^1.0.2", - "pug-runtime": "^3.0.0" + "engines": { + "node": ">=0.10.0" } }, - "node_modules/pug-code-gen": { - "version": "3.0.4", + "node_modules/read-pkg": { + "version": "3.0.0", "dev": true, "license": "MIT", "dependencies": { - "constantinople": "^4.0.1", - "doctypes": "^1.1.0", - "js-stringify": "^1.0.2", - "pug-attrs": "^3.0.0", - "pug-error": "^2.1.0", - "pug-runtime": "^3.0.1", - "void-elements": "^3.1.0", - "with": "^7.0.0" + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + }, + "engines": { + "node": ">=4" } }, - "node_modules/pug-error": { - "version": "2.1.0", - "dev": true, - "license": "MIT" - }, - "node_modules/pug-filters": { - "version": "4.0.0", - "dev": true, + "node_modules/readable-stream": { + "version": "3.6.2", "license": "MIT", "dependencies": { - "constantinople": "^4.0.1", - "jstransformer": "1.0.0", - "pug-error": "^2.0.0", - "pug-walk": "^2.0.0", - "resolve": "^1.15.1" + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" } }, - "node_modules/pug-lexer": { - "version": "5.0.1", - "dev": true, + "node_modules/readdirp": { + "version": "3.6.0", "license": "MIT", "dependencies": { - "character-parser": "^2.2.0", - "is-expression": "^4.0.0", - "pug-error": "^2.0.0" + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" } }, - "node_modules/pug-linker": { - "version": "4.0.0", - "dev": true, + "node_modules/readdirp/node_modules/picomatch": { + "version": "2.3.2", "license": "MIT", - "dependencies": { - "pug-error": "^2.0.0", - "pug-walk": "^2.0.0" + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/pug-load": { - "version": "3.0.0", - "dev": true, + "node_modules/recast": { + "version": "0.23.11", "license": "MIT", "dependencies": { - "object-assign": "^4.1.1", - "pug-walk": "^2.0.0" + "ast-types": "^0.16.1", + "esprima": "~4.0.0", + "source-map": "~0.6.1", + "tiny-invariant": "^1.3.3", + "tslib": "^2.0.1" + }, + "engines": { + "node": ">= 4" } }, - "node_modules/pug-parser": { - "version": "6.0.0", - "dev": true, + "node_modules/rechoir": { + "version": "0.8.0", "license": "MIT", "dependencies": { - "pug-error": "^2.0.0", - "token-stream": "1.0.0" + "resolve": "^1.20.0" + }, + "engines": { + "node": ">= 10.13.0" } }, - "node_modules/pug-runtime": { - "version": "3.0.1", - "dev": true, - "license": "MIT" - }, - "node_modules/pug-strip-comments": { - "version": "2.0.0", + "node_modules/recursive-copy": { + "version": "2.0.14", "dev": true, - "license": "MIT", + "license": "ISC", "dependencies": { - "pug-error": "^2.0.0" + "errno": "^0.1.2", + "graceful-fs": "^4.1.4", + "junk": "^1.0.1", + "maximatch": "^0.1.0", + "mkdirp": "^0.5.1", + "pify": "^2.3.0", + "promise": "^7.0.1", + "rimraf": "^2.7.1", + "slash": "^1.0.0" } }, - "node_modules/pug-walk": { - "version": "2.0.0", + "node_modules/recursive-copy/node_modules/pify": { + "version": "2.3.0", "dev": true, - "license": "MIT" - }, - "node_modules/punycode": { - "version": "2.3.1", "license": "MIT", "engines": { - "node": ">=6" + "node": ">=0.10.0" } }, - "node_modules/punycode.js": { - "version": "2.3.1", + "node_modules/recursive-copy/node_modules/slash": { + "version": "1.0.0", + "dev": true, "license": "MIT", "engines": { - "node": ">=6" + "node": ">=0.10.0" } }, - "node_modules/qified": { - "version": "0.6.0", - "dev": true, + "node_modules/redent": { + "version": "3.0.0", "license": "MIT", "dependencies": { - "hookified": "^1.14.0" + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" }, "engines": { - "node": ">=20" + "node": ">=8" } }, - "node_modules/qr-creator": { - "version": "1.0.0", - "dev": true, - "license": "MIT" - }, - "node_modules/quansync": { - "version": "0.2.11", + "node_modules/reflect.getprototypeof": { + "version": "1.0.10", "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/antfu" - }, - { - "type": "individual", - "url": "https://github.com/sponsors/sxzz" - } - ], - "license": "MIT" - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/raf-schd": { - "version": "4.0.3", - "license": "MIT" - }, - "node_modules/randombytes": { - "version": "2.1.0", "license": "MIT", "dependencies": { - "safe-buffer": "^5.1.0" - } - }, - "node_modules/range-parser": { - "version": "1.2.1", - "license": "MIT", + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.7", + "get-proto": "^1.0.1", + "which-builtin-type": "^1.2.1" + }, "engines": { - "node": ">= 0.6" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/raw-body": { - "version": "2.5.2", + "node_modules/regenerate": { + "version": "1.4.2", + "license": "MIT" + }, + "node_modules/regenerate-unicode-properties": { + "version": "10.2.2", "license": "MIT", "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" + "regenerate": "^1.4.2" }, "engines": { - "node": ">= 0.8" + "node": ">=4" } }, - "node_modules/raw-body/node_modules/iconv-lite": { - "version": "0.4.24", + "node_modules/regexp.prototype.flags": { + "version": "1.5.4", + "dev": true, "license": "MIT", "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "set-function-name": "^2.0.2" }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/react": { - "version": "19.2.5", + "node_modules/regexpu-core": { + "version": "6.4.0", "license": "MIT", + "dependencies": { + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.2.2", + "regjsgen": "^0.8.0", + "regjsparser": "^0.13.0", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.2.1" + }, "engines": { - "node": ">=0.10.0" + "node": ">=4" } }, - "node_modules/react-aria": { - "version": "3.48.0", - "license": "Apache-2.0", + "node_modules/regjsgen": { + "version": "0.8.0", + "license": "MIT" + }, + "node_modules/regjsparser": { + "version": "0.13.0", + "license": "BSD-2-Clause", "dependencies": { - "@internationalized/date": "^3.12.1", - "@internationalized/number": "^3.6.6", - "@internationalized/string": "^3.2.8", - "@react-types/shared": "^3.34.0", - "@swc/helpers": "^0.5.0", - "aria-hidden": "^1.2.3", - "clsx": "^2.0.0", - "react-stately": "3.46.0", - "use-sync-external-store": "^1.6.0" + "jsesc": "~3.1.0" }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + "bin": { + "regjsparser": "bin/parser" } }, - "node_modules/react-aria/node_modules/clsx": { + "node_modules/require-directory": { "version": "2.1.1", "license": "MIT", "engines": { - "node": ">=6" + "node": ">=0.10.0" } }, - "node_modules/react-compiler-runtime": { - "version": "19.1.0-rc.1", + "node_modules/require-from-string": { + "version": "2.0.2", "license": "MIT", - "peerDependencies": { - "react": "^17.0.0 || ^18.0.0 || ^19.0.0 || ^0.0.0-experimental" + "engines": { + "node": ">=0.10.0" } }, - "node_modules/react-dom": { - "version": "19.2.5", + "node_modules/requires-port": { + "version": "1.0.0", + "license": "MIT" + }, + "node_modules/resolve": { + "version": "1.22.11", "license": "MIT", "dependencies": { - "scheduler": "^0.27.0" + "is-core-module": "^2.16.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" }, - "peerDependencies": { - "react": "^19.2.5" + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/react-is": { - "version": "17.0.2", - "license": "MIT" - }, - "node_modules/react-remove-scroll": { - "version": "2.7.1", + "node_modules/resolve-cwd": { + "version": "3.0.0", "license": "MIT", "dependencies": { - "react-remove-scroll-bar": "^2.3.7", - "react-style-singleton": "^2.2.3", - "tslib": "^2.1.0", - "use-callback-ref": "^1.3.3", - "use-sidecar": "^1.1.3" + "resolve-from": "^5.0.0" }, "engines": { - "node": ">=10" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } + "node": ">=8" } }, - "node_modules/react-remove-scroll-bar": { - "version": "2.3.8", + "node_modules/resolve-dir": { + "version": "1.0.1", + "dev": true, "license": "MIT", "dependencies": { - "react-style-singleton": "^2.2.2", - "tslib": "^2.0.0" + "expand-tilde": "^2.0.0", + "global-modules": "^1.0.0" }, "engines": { - "node": ">=10" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } + "node": ">=0.10.0" } }, - "node_modules/react-stately": { - "version": "3.46.0", - "license": "Apache-2.0", + "node_modules/resolve-dir/node_modules/global-modules": { + "version": "1.0.0", + "dev": true, + "license": "MIT", "dependencies": { - "@internationalized/date": "^3.12.1", - "@internationalized/number": "^3.6.6", - "@internationalized/string": "^3.2.8", - "@react-types/shared": "^3.34.0", - "@swc/helpers": "^0.5.0", - "use-sync-external-store": "^1.6.0" + "global-prefix": "^1.0.1", + "is-windows": "^1.0.1", + "resolve-dir": "^1.0.0" }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + "engines": { + "node": ">=0.10.0" } }, - "node_modules/react-style-singleton": { - "version": "2.2.3", + "node_modules/resolve-dir/node_modules/global-prefix": { + "version": "1.0.2", + "dev": true, "license": "MIT", "dependencies": { - "get-nonce": "^1.0.0", - "tslib": "^2.0.0" + "expand-tilde": "^2.0.2", + "homedir-polyfill": "^1.0.1", + "ini": "^1.3.4", + "is-windows": "^1.0.1", + "which": "^1.2.14" }, "engines": { - "node": ">=10" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } + "node": ">=0.10.0" } }, - "node_modules/read-cache": { + "node_modules/resolve-from": { + "version": "5.0.0", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-pkg-maps": { "version": "1.0.0", "dev": true, "license": "MIT", - "dependencies": { - "pify": "^2.3.0" + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" } }, - "node_modules/read-cache/node_modules/pify": { - "version": "2.3.0", + "node_modules/restore-cursor": { + "version": "5.1.0", "dev": true, "license": "MIT", + "dependencies": { + "onetime": "^7.0.0", + "signal-exit": "^4.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/retry": { + "version": "0.13.1", + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "license": "MIT", "engines": { + "iojs": ">=1.0.0", "node": ">=0.10.0" } }, - "node_modules/read-pkg": { + "node_modules/rev-hash": { "version": "3.0.0", - "dev": true, "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/rfdc": { + "version": "1.4.1", + "dev": true, + "license": "MIT" + }, + "node_modules/rimraf": { + "version": "2.7.1", + "license": "ISC", "dependencies": { - "load-json-file": "^4.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^3.0.0" + "glob": "^7.1.3" }, - "engines": { - "node": ">=4" + "bin": { + "rimraf": "bin.js" } }, - "node_modules/readable-stream": { - "version": "3.6.2", - "license": "MIT", + "node_modules/rimraf/node_modules/glob": { + "version": "7.2.3", + "license": "ISC", "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" }, "engines": { - "node": ">= 6" + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/readdirp": { - "version": "3.6.0", + "node_modules/robust-predicates": { + "version": "3.0.3", + "license": "Unlicense" + }, + "node_modules/rs-module-lexer": { + "version": "2.8.0", + "dev": true, + "hasInstallScript": true, "license": "MIT", - "dependencies": { - "picomatch": "^2.2.1" - }, "engines": { - "node": ">=8.10.0" + "node": ">=14" + }, + "optionalDependencies": { + "@xn-sakina/rml-darwin-arm64": "2.8.0", + "@xn-sakina/rml-darwin-x64": "2.8.0", + "@xn-sakina/rml-linux-arm-gnueabihf": "2.8.0", + "@xn-sakina/rml-linux-arm64-gnu": "2.8.0", + "@xn-sakina/rml-linux-arm64-musl": "2.8.0", + "@xn-sakina/rml-linux-x64-gnu": "2.8.0", + "@xn-sakina/rml-linux-x64-musl": "2.8.0", + "@xn-sakina/rml-win32-arm64-msvc": "2.8.0", + "@xn-sakina/rml-win32-x64-msvc": "2.8.0" } }, - "node_modules/readdirp/node_modules/picomatch": { - "version": "2.3.2", + "node_modules/run-applescript": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.1.0.tgz", + "integrity": "sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==", "license": "MIT", "engines": { - "node": ">=8.6" + "node": ">=18" }, "funding": { - "url": "https://github.com/sponsors/jonschlinkert" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/recast": { - "version": "0.23.11", + "node_modules/run-async": { + "version": "3.0.0", + "dev": true, "license": "MIT", - "dependencies": { - "ast-types": "^0.16.1", - "esprima": "~4.0.0", - "source-map": "~0.6.1", - "tiny-invariant": "^1.3.3", - "tslib": "^2.0.1" - }, "engines": { - "node": ">= 4" + "node": ">=0.12.0" } }, - "node_modules/rechoir": { - "version": "0.8.0", + "node_modules/run-parallel": { + "version": "1.2.0", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], "license": "MIT", "dependencies": { - "resolve": "^1.20.0" - }, - "engines": { - "node": ">= 10.13.0" + "queue-microtask": "^1.2.2" } }, - "node_modules/recursive-copy": { - "version": "2.0.14", + "node_modules/rw": { + "version": "1.3.3", + "license": "BSD-3-Clause" + }, + "node_modules/rxjs": { + "version": "7.8.2", "dev": true, - "license": "ISC", + "license": "Apache-2.0", "dependencies": { - "errno": "^0.1.2", - "graceful-fs": "^4.1.4", - "junk": "^1.0.1", - "maximatch": "^0.1.0", - "mkdirp": "^0.5.1", - "pify": "^2.3.0", - "promise": "^7.0.1", - "rimraf": "^2.7.1", - "slash": "^1.0.0" + "tslib": "^2.1.0" } }, - "node_modules/recursive-copy/node_modules/pify": { - "version": "2.3.0", + "node_modules/safe-array-concat": { + "version": "1.1.3", "dev": true, "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "has-symbols": "^1.1.0", + "isarray": "^2.0.5" + }, "engines": { - "node": ">=0.10.0" + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/recursive-copy/node_modules/slash": { + "node_modules/safe-buffer": { + "version": "5.2.1", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safe-push-apply": { "version": "1.0.0", "dev": true, "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/redent": { - "version": "3.0.0", - "license": "MIT", "dependencies": { - "indent-string": "^4.0.0", - "strip-indent": "^3.0.0" + "es-errors": "^1.3.0", + "isarray": "^2.0.5" }, "engines": { - "node": ">=8" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/reflect.getprototypeof": { - "version": "1.0.10", + "node_modules/safe-regex-test": { + "version": "1.1.0", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.8", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.9", + "call-bound": "^1.0.2", "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "get-intrinsic": "^1.2.7", - "get-proto": "^1.0.1", - "which-builtin-type": "^1.2.1" + "is-regex": "^1.2.1" }, "engines": { "node": ">= 0.4" @@ -19584,1154 +18846,1199 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/regenerate": { - "version": "1.4.2", + "node_modules/safer-buffer": { + "version": "2.1.2", "license": "MIT" }, - "node_modules/regenerate-unicode-properties": { - "version": "10.2.2", + "node_modules/sass": { + "version": "1.94.0", "license": "MIT", "dependencies": { - "regenerate": "^1.4.2" + "chokidar": "^4.0.0", + "immutable": "^5.0.2", + "source-map-js": ">=0.6.2 <2.0.0" + }, + "bin": { + "sass": "sass.js" }, "engines": { - "node": ">=4" + "node": ">=14.0.0" + }, + "optionalDependencies": { + "@parcel/watcher": "^2.4.1" } }, - "node_modules/regexp.prototype.flags": { - "version": "1.5.4", - "dev": true, + "node_modules/sass-loader": { + "version": "13.3.3", "license": "MIT", "dependencies": { - "call-bind": "^1.0.8", - "define-properties": "^1.2.1", - "es-errors": "^1.3.0", - "get-proto": "^1.0.1", - "gopd": "^1.2.0", - "set-function-name": "^2.0.2" + "neo-async": "^2.6.2" }, "engines": { - "node": ">= 0.4" + "node": ">= 14.15.0" }, "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/regexpu-core": { - "version": "6.4.0", - "license": "MIT", - "dependencies": { - "regenerate": "^1.4.2", - "regenerate-unicode-properties": "^10.2.2", - "regjsgen": "^0.8.0", - "regjsparser": "^0.13.0", - "unicode-match-property-ecmascript": "^2.0.0", - "unicode-match-property-value-ecmascript": "^2.2.1" + "type": "opencollective", + "url": "https://opencollective.com/webpack" }, - "engines": { - "node": ">=4" - } - }, - "node_modules/regjsgen": { - "version": "0.8.0", - "license": "MIT" - }, - "node_modules/regjsparser": { - "version": "0.13.0", - "license": "BSD-2-Clause", - "dependencies": { - "jsesc": "~3.1.0" + "peerDependencies": { + "fibers": ">= 3.1.0", + "node-sass": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0", + "sass": "^1.3.0", + "sass-embedded": "*", + "webpack": "^5.0.0" }, - "bin": { - "regjsparser": "bin/parser" + "peerDependenciesMeta": { + "fibers": { + "optional": true + }, + "node-sass": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + } } }, - "node_modules/require-directory": { - "version": "2.1.1", + "node_modules/sass/node_modules/chokidar": { + "version": "4.0.3", "license": "MIT", + "dependencies": { + "readdirp": "^4.0.1" + }, "engines": { - "node": ">=0.10.0" + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" } }, - "node_modules/require-from-string": { - "version": "2.0.2", + "node_modules/sass/node_modules/readdirp": { + "version": "4.1.2", "license": "MIT", "engines": { - "node": ">=0.10.0" + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" } }, - "node_modules/requires-port": { - "version": "1.0.0", + "node_modules/scheduler": { + "version": "0.27.0", "license": "MIT" }, - "node_modules/resolve": { - "version": "1.22.11", + "node_modules/schema-utils": { + "version": "4.3.3", "license": "MIT", "dependencies": { - "is-core-module": "^2.16.1", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" }, "engines": { - "node": ">= 0.4" + "node": ">= 10.13.0" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "type": "opencollective", + "url": "https://opencollective.com/webpack" } }, - "node_modules/resolve-cwd": { - "version": "3.0.0", + "node_modules/schema-utils/node_modules/ajv": { + "version": "8.17.1", "license": "MIT", "dependencies": { - "resolve-from": "^5.0.0" + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" }, - "engines": { - "node": ">=8" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/resolve-dir": { - "version": "1.0.1", - "dev": true, + "node_modules/schema-utils/node_modules/ajv-keywords": { + "version": "5.1.0", "license": "MIT", "dependencies": { - "expand-tilde": "^2.0.0", - "global-modules": "^1.0.0" + "fast-deep-equal": "^3.1.3" }, - "engines": { - "node": ">=0.10.0" + "peerDependencies": { + "ajv": "^8.8.2" } }, - "node_modules/resolve-dir/node_modules/global-modules": { + "node_modules/schema-utils/node_modules/json-schema-traverse": { "version": "1.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "global-prefix": "^1.0.1", - "is-windows": "^1.0.1", - "resolve-dir": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } + "license": "MIT" }, - "node_modules/resolve-dir/node_modules/global-prefix": { - "version": "1.0.2", - "dev": true, + "node_modules/select-hose": { + "version": "2.0.0", + "license": "MIT" + }, + "node_modules/selfsigned": { + "version": "2.4.1", "license": "MIT", "dependencies": { - "expand-tilde": "^2.0.2", - "homedir-polyfill": "^1.0.1", - "ini": "^1.3.4", - "is-windows": "^1.0.1", - "which": "^1.2.14" + "@types/node-forge": "^1.3.0", + "node-forge": "^1" }, "engines": { - "node": ">=0.10.0" + "node": ">=10" } }, - "node_modules/resolve-from": { - "version": "5.0.0", - "license": "MIT", - "engines": { - "node": ">=8" + "node_modules/semver": { + "version": "5.7.2", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" } }, - "node_modules/restore-cursor": { - "version": "5.1.0", - "dev": true, + "node_modules/send": { + "version": "0.19.0", "license": "MIT", "dependencies": { - "onetime": "^7.0.0", - "signal-exit": "^4.1.0" + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" }, "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">= 0.8.0" } }, - "node_modules/retry": { - "version": "0.13.1", + "node_modules/send/node_modules/debug": { + "version": "2.6.9", "license": "MIT", - "engines": { - "node": ">= 4" + "dependencies": { + "ms": "2.0.0" } }, - "node_modules/reusify": { - "version": "1.1.0", - "license": "MIT", - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "license": "MIT" }, - "node_modules/rev-hash": { - "version": "3.0.0", + "node_modules/send/node_modules/encodeurl": { + "version": "1.0.2", "license": "MIT", "engines": { - "node": ">=8" + "node": ">= 0.8" } }, - "node_modules/rfdc": { - "version": "1.4.1", - "dev": true, - "license": "MIT" - }, - "node_modules/rimraf": { - "version": "2.7.1", - "license": "ISC", + "node_modules/serialize-javascript": { + "version": "6.0.2", + "license": "BSD-3-Clause", "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" + "randombytes": "^2.1.0" } }, - "node_modules/rimraf/node_modules/glob": { - "version": "7.2.3", - "license": "ISC", + "node_modules/serve-index": { + "version": "1.9.1", + "license": "MIT", "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "accepts": "~1.3.4", + "batch": "0.6.1", + "debug": "2.6.9", + "escape-html": "~1.0.3", + "http-errors": "~1.6.2", + "mime-types": "~2.1.17", + "parseurl": "~1.3.2" }, "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": ">= 0.8.0" } }, - "node_modules/robust-predicates": { - "version": "3.0.3", - "license": "Unlicense" + "node_modules/serve-index/node_modules/debug": { + "version": "2.6.9", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } }, - "node_modules/rs-module-lexer": { - "version": "2.8.0", - "dev": true, - "hasInstallScript": true, + "node_modules/serve-index/node_modules/depd": { + "version": "1.1.2", "license": "MIT", "engines": { - "node": ">=14" - }, - "optionalDependencies": { - "@xn-sakina/rml-darwin-arm64": "2.8.0", - "@xn-sakina/rml-darwin-x64": "2.8.0", - "@xn-sakina/rml-linux-arm-gnueabihf": "2.8.0", - "@xn-sakina/rml-linux-arm64-gnu": "2.8.0", - "@xn-sakina/rml-linux-arm64-musl": "2.8.0", - "@xn-sakina/rml-linux-x64-gnu": "2.8.0", - "@xn-sakina/rml-linux-x64-musl": "2.8.0", - "@xn-sakina/rml-win32-arm64-msvc": "2.8.0", - "@xn-sakina/rml-win32-x64-msvc": "2.8.0" + "node": ">= 0.6" } }, - "node_modules/run-applescript": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.1.0.tgz", - "integrity": "sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==", + "node_modules/serve-index/node_modules/http-errors": { + "version": "1.6.3", "license": "MIT", - "engines": { - "node": ">=18" + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": ">= 0.6" } }, - "node_modules/run-async": { - "version": "3.0.0", - "dev": true, + "node_modules/serve-index/node_modules/inherits": { + "version": "2.0.3", + "license": "ISC" + }, + "node_modules/serve-index/node_modules/ms": { + "version": "2.0.0", + "license": "MIT" + }, + "node_modules/serve-index/node_modules/setprototypeof": { + "version": "1.1.0", + "license": "ISC" + }, + "node_modules/serve-index/node_modules/statuses": { + "version": "1.5.0", "license": "MIT", "engines": { - "node": ">=0.12.0" + "node": ">= 0.6" } }, - "node_modules/run-parallel": { - "version": "1.2.0", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], + "node_modules/serve-static": { + "version": "1.16.2", "license": "MIT", "dependencies": { - "queue-microtask": "^1.2.2" + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.19.0" + }, + "engines": { + "node": ">= 0.8.0" } }, - "node_modules/rw": { - "version": "1.3.3", - "license": "BSD-3-Clause" + "node_modules/set-blocking": { + "version": "2.0.0", + "license": "ISC" }, - "node_modules/rxjs": { - "version": "7.8.2", - "dev": true, - "license": "Apache-2.0", + "node_modules/set-function-length": { + "version": "1.2.2", + "license": "MIT", "dependencies": { - "tslib": "^2.1.0" + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" } }, - "node_modules/safe-array-concat": { - "version": "1.1.3", + "node_modules/set-function-name": { + "version": "2.0.2", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.2", - "get-intrinsic": "^1.2.6", - "has-symbols": "^1.1.0", - "isarray": "^2.0.5" + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" }, "engines": { - "node": ">=0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">= 0.4" } }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/safe-push-apply": { + "node_modules/set-proto": { "version": "1.0.0", "dev": true, "license": "MIT", "dependencies": { + "dunder-proto": "^1.0.1", "es-errors": "^1.3.0", - "isarray": "^2.0.5" + "es-object-atoms": "^1.0.0" }, "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/safe-regex-test": { - "version": "1.1.0", - "dev": true, + "node_modules/set-value": { + "version": "4.1.0", + "funding": [ + "https://github.com/sponsors/jonschlinkert", + "https://paypal.me/jonathanschlinkert", + "https://jonschlinkert.dev/sponsor" + ], "license": "MIT", "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "is-regex": "^1.2.1" + "is-plain-object": "^2.0.4", + "is-primitive": "^3.0.1" }, "engines": { - "node": ">= 0.4" + "node": ">=11.0" + } + }, + "node_modules/set-value/node_modules/is-plain-object": { + "version": "2.0.4", + "license": "MIT", + "dependencies": { + "isobject": "^3.0.1" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": ">=0.10.0" } }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "license": "MIT" + "node_modules/setprototypeof": { + "version": "1.2.0", + "license": "ISC" }, - "node_modules/sass": { - "version": "1.94.0", + "node_modules/shallow-clone": { + "version": "3.0.1", "license": "MIT", "dependencies": { - "chokidar": "^4.0.0", - "immutable": "^5.0.2", - "source-map-js": ">=0.6.2 <2.0.0" - }, - "bin": { - "sass": "sass.js" + "kind-of": "^6.0.2" }, "engines": { - "node": ">=14.0.0" - }, - "optionalDependencies": { - "@parcel/watcher": "^2.4.1" + "node": ">=8" } }, - "node_modules/sass-loader": { - "version": "13.3.3", + "node_modules/shebang-command": { + "version": "1.2.0", + "dev": true, "license": "MIT", "dependencies": { - "neo-async": "^2.6.2" + "shebang-regex": "^1.0.0" }, "engines": { - "node": ">= 14.15.0" + "node": ">=0.10.0" + } + }, + "node_modules/shebang-regex": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/shell-quote": { + "version": "1.8.3", + "license": "MIT", + "engines": { + "node": ">= 0.4" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel": { + "version": "1.1.0", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" }, - "peerDependencies": { - "fibers": ">= 3.1.0", - "node-sass": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0", - "sass": "^1.3.0", - "sass-embedded": "*", - "webpack": "^5.0.0" + "engines": { + "node": ">= 0.4" }, - "peerDependenciesMeta": { - "fibers": { - "optional": true - }, - "node-sass": { - "optional": true - }, - "sass": { - "optional": true - }, - "sass-embedded": { - "optional": true - } + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/sass/node_modules/chokidar": { - "version": "4.0.3", + "node_modules/side-channel-list": { + "version": "1.0.0", "license": "MIT", "dependencies": { - "readdirp": "^4.0.1" + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" }, "engines": { - "node": ">= 14.16.0" + "node": ">= 0.4" }, "funding": { - "url": "https://paulmillr.com/funding/" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/sass/node_modules/readdirp": { - "version": "4.1.2", + "node_modules/side-channel-map": { + "version": "1.0.1", "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, "engines": { - "node": ">= 14.18.0" + "node": ">= 0.4" }, "funding": { - "type": "individual", - "url": "https://paulmillr.com/funding/" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/scheduler": { - "version": "0.27.0", - "license": "MIT" - }, - "node_modules/schema-utils": { - "version": "4.3.3", + "node_modules/side-channel-weakmap": { + "version": "1.0.2", "license": "MIT", "dependencies": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.9.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.1.0" + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" }, "engines": { - "node": ">= 10.13.0" + "node": ">= 0.4" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/schema-utils/node_modules/ajv": { - "version": "8.17.1", - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" + "node_modules/siginfo": { + "version": "2.0.0", + "license": "ISC" + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "license": "ISC", + "engines": { + "node": ">=14" }, "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/schema-utils/node_modules/ajv-keywords": { - "version": "5.1.0", + "node_modules/signale": { + "version": "1.4.0", "license": "MIT", "dependencies": { - "fast-deep-equal": "^3.1.3" + "chalk": "^2.3.2", + "figures": "^2.0.0", + "pkg-conf": "^2.1.0" }, - "peerDependencies": { - "ajv": "^8.8.2" + "engines": { + "node": ">=6" } }, - "node_modules/schema-utils/node_modules/json-schema-traverse": { - "version": "1.0.0", - "license": "MIT" - }, - "node_modules/select-hose": { - "version": "2.0.0", + "node_modules/singleton-manager": { + "version": "1.8.0", + "dev": true, "license": "MIT" }, - "node_modules/selfsigned": { - "version": "2.4.1", + "node_modules/sirv": { + "version": "3.0.2", "license": "MIT", "dependencies": { - "@types/node-forge": "^1.3.0", - "node-forge": "^1" + "@polka/url": "^1.0.0-next.24", + "mrmime": "^2.0.0", + "totalist": "^3.0.0" }, "engines": { - "node": ">=10" + "node": ">=18" } }, - "node_modules/semver": { - "version": "5.7.2", + "node_modules/skin-tone": { + "version": "2.0.0", "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/send": { - "version": "0.19.0", "license": "MIT", "dependencies": { - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "2.4.1", - "range-parser": "~1.2.1", - "statuses": "2.0.1" + "unicode-emoji-modifier-base": "^1.0.0" }, "engines": { - "node": ">= 0.8.0" + "node": ">=8" } }, - "node_modules/send/node_modules/debug": { - "version": "2.6.9", + "node_modules/slash": { + "version": "3.0.0", + "dev": true, "license": "MIT", - "dependencies": { - "ms": "2.0.0" + "engines": { + "node": ">=8" } }, - "node_modules/send/node_modules/debug/node_modules/ms": { - "version": "2.0.0", - "license": "MIT" - }, - "node_modules/send/node_modules/encodeurl": { - "version": "1.0.2", + "node_modules/slice-ansi": { + "version": "7.1.2", + "dev": true, "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "is-fullwidth-code-point": "^5.0.0" + }, "engines": { - "node": ">= 0.8" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" } }, - "node_modules/serialize-javascript": { - "version": "6.0.2", - "license": "BSD-3-Clause", - "dependencies": { - "randombytes": "^2.1.0" + "node_modules/slice-ansi/node_modules/ansi-styles": { + "version": "6.2.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/serve-index": { - "version": "1.9.1", + "node_modules/smart-buffer": { + "version": "4.2.0", "license": "MIT", - "dependencies": { - "accepts": "~1.3.4", - "batch": "0.6.1", - "debug": "2.6.9", - "escape-html": "~1.0.3", - "http-errors": "~1.6.2", - "mime-types": "~2.1.17", - "parseurl": "~1.3.2" - }, "engines": { - "node": ">= 0.8.0" + "node": ">= 6.0.0", + "npm": ">= 3.0.0" } }, - "node_modules/serve-index/node_modules/debug": { - "version": "2.6.9", + "node_modules/sockjs": { + "version": "0.3.24", "license": "MIT", "dependencies": { - "ms": "2.0.0" + "faye-websocket": "^0.11.3", + "uuid": "^8.3.2", + "websocket-driver": "^0.7.4" } }, - "node_modules/serve-index/node_modules/depd": { - "version": "1.1.2", + "node_modules/socks": { + "version": "2.8.7", "license": "MIT", + "dependencies": { + "ip-address": "^10.0.1", + "smart-buffer": "^4.2.0" + }, "engines": { - "node": ">= 0.6" + "node": ">= 10.0.0", + "npm": ">= 3.0.0" } }, - "node_modules/serve-index/node_modules/http-errors": { - "version": "1.6.3", + "node_modules/socks-proxy-agent": { + "version": "7.0.0", "license": "MIT", "dependencies": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.0", - "statuses": ">= 1.4.0 < 2" + "agent-base": "^6.0.2", + "debug": "^4.3.3", + "socks": "^2.6.2" }, "engines": { - "node": ">= 0.6" + "node": ">= 10" } }, - "node_modules/serve-index/node_modules/inherits": { - "version": "2.0.3", - "license": "ISC" - }, - "node_modules/serve-index/node_modules/ms": { - "version": "2.0.0", + "node_modules/sortablejs": { + "version": "1.15.6", "license": "MIT" }, - "node_modules/serve-index/node_modules/setprototypeof": { - "version": "1.1.0", - "license": "ISC" + "node_modules/source-list-map": { + "version": "2.0.1", + "license": "MIT" }, - "node_modules/serve-index/node_modules/statuses": { - "version": "1.5.0", - "license": "MIT", + "node_modules/source-map": { + "version": "0.6.1", + "license": "BSD-3-Clause", "engines": { - "node": ">= 0.6" + "node": ">=0.10.0" } }, - "node_modules/serve-static": { - "version": "1.16.2", - "license": "MIT", - "dependencies": { - "encodeurl": "~2.0.0", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.19.0" - }, + "node_modules/source-map-js": { + "version": "1.2.1", + "license": "BSD-3-Clause", "engines": { - "node": ">= 0.8.0" + "node": ">=0.10.0" } }, - "node_modules/set-blocking": { - "version": "2.0.0", - "license": "ISC" - }, - "node_modules/set-function-length": { - "version": "1.2.2", + "node_modules/source-map-support": { + "version": "0.5.21", "license": "MIT", "dependencies": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" } }, - "node_modules/set-function-name": { - "version": "2.0.2", + "node_modules/spdx-correct": { + "version": "3.2.0", "dev": true, - "license": "MIT", + "license": "Apache-2.0", "dependencies": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "functions-have-names": "^1.2.3", - "has-property-descriptors": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" } }, - "node_modules/set-proto": { - "version": "1.0.0", + "node_modules/spdx-exceptions": { + "version": "2.5.0", + "dev": true, + "license": "CC-BY-3.0" + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", "dev": true, "license": "MIT", - "dependencies": { - "dunder-proto": "^1.0.1", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" } }, - "node_modules/set-value": { - "version": "4.1.0", - "funding": [ - "https://github.com/sponsors/jonschlinkert", - "https://paypal.me/jonathanschlinkert", - "https://jonschlinkert.dev/sponsor" - ], + "node_modules/spdx-license-ids": { + "version": "3.0.22", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/spdy": { + "version": "4.0.2", "license": "MIT", "dependencies": { - "is-plain-object": "^2.0.4", - "is-primitive": "^3.0.1" + "debug": "^4.1.0", + "handle-thing": "^2.0.0", + "http-deceiver": "^1.2.7", + "select-hose": "^2.0.0", + "spdy-transport": "^3.0.0" }, "engines": { - "node": ">=11.0" + "node": ">=6.0.0" } }, - "node_modules/set-value/node_modules/is-plain-object": { - "version": "2.0.4", + "node_modules/spdy-transport": { + "version": "3.0.0", "license": "MIT", "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" + "debug": "^4.1.0", + "detect-node": "^2.0.4", + "hpack.js": "^2.1.6", + "obuf": "^1.1.2", + "readable-stream": "^3.0.6", + "wbuf": "^1.7.3" } }, - "node_modules/setprototypeof": { - "version": "1.2.0", - "license": "ISC" + "node_modules/ssr-window": { + "version": "4.0.2", + "license": "MIT" }, - "node_modules/shallow-clone": { - "version": "3.0.1", - "license": "MIT", + "node_modules/ssri": { + "version": "9.0.1", + "license": "ISC", "dependencies": { - "kind-of": "^6.0.2" + "minipass": "^3.1.1" }, "engines": { - "node": ">=8" + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, - "node_modules/shebang-command": { - "version": "1.2.0", - "dev": true, - "license": "MIT", + "node_modules/ssri/node_modules/minipass": { + "version": "3.3.6", + "license": "ISC", "dependencies": { - "shebang-regex": "^1.0.0" + "yallist": "^4.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/shebang-regex": { - "version": "1.0.0", - "dev": true, + "node_modules/ssri/node_modules/yallist": { + "version": "4.0.0", + "license": "ISC" + }, + "node_modules/stackback": { + "version": "0.0.2", + "license": "MIT" + }, + "node_modules/statuses": { + "version": "2.0.1", "license": "MIT", "engines": { - "node": ">=0.10.0" + "node": ">= 0.8" } }, - "node_modules/shell-quote": { - "version": "1.8.3", + "node_modules/std-env": { + "version": "4.1.0", + "license": "MIT" + }, + "node_modules/stdin-discarder": { + "version": "0.3.2", + "dev": true, "license": "MIT", "engines": { - "node": ">= 0.4" + "node": ">=18" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/side-channel": { + "node_modules/stop-iteration-iterator": { "version": "1.1.0", + "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0", - "object-inspect": "^1.13.3", - "side-channel-list": "^1.0.0", - "side-channel-map": "^1.0.1", - "side-channel-weakmap": "^1.0.2" + "internal-slot": "^1.1.0" }, "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/side-channel-list": { - "version": "1.0.0", + "node_modules/storybook": { + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/storybook/-/storybook-10.4.1.tgz", + "integrity": "sha512-V1Zd2e+gBFufqAQVZ1JR8KLqALsEZ3JYSBnWwQbKa6zCfWWanR6AFMyuOkLt2gZOgGp3h2Riuz88pGNVTQSG0A==", "license": "MIT", "dependencies": { - "es-errors": "^1.3.0", - "object-inspect": "^1.13.3" + "@storybook/global": "^5.0.0", + "@storybook/icons": "^2.0.2", + "@testing-library/jest-dom": "^6.9.1", + "@testing-library/user-event": "^14.6.1", + "@vitest/expect": "3.2.4", + "@vitest/spy": "3.2.4", + "@webcontainer/env": "^1.1.1", + "esbuild": "^0.18.0 || ^0.19.0 || ^0.20.0 || ^0.21.0 || ^0.22.0 || ^0.23.0 || ^0.24.0 || ^0.25.0 || ^0.26.0 || ^0.27.0", + "open": "^10.2.0", + "oxc-parser": "^0.127.0", + "oxc-resolver": "^11.19.1", + "recast": "^0.23.5", + "semver": "^7.7.3", + "use-sync-external-store": "^1.5.0", + "ws": "^8.18.0" }, - "engines": { - "node": ">= 0.4" + "bin": { + "storybook": "dist/bin/dispatcher.js" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "prettier": "^2 || ^3", + "vite-plus": "^0.1.15" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "prettier": { + "optional": true + }, + "vite-plus": { + "optional": true + } } }, - "node_modules/side-channel-map": { - "version": "1.0.1", + "node_modules/storybook/node_modules/@esbuild/aix-ppc64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.7.tgz", + "integrity": "sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==", + "cpu": [ + "ppc64" + ], "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.5", - "object-inspect": "^1.13.3" - }, + "optional": true, + "os": [ + "aix" + ], "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=18" } }, - "node_modules/side-channel-weakmap": { - "version": "1.0.2", + "node_modules/storybook/node_modules/@esbuild/android-arm": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.7.tgz", + "integrity": "sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==", + "cpu": [ + "arm" + ], "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.5", - "object-inspect": "^1.13.3", - "side-channel-map": "^1.0.1" - }, + "optional": true, + "os": [ + "android" + ], "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=18" } }, - "node_modules/siginfo": { - "version": "2.0.0", - "license": "ISC" - }, - "node_modules/signal-exit": { - "version": "4.1.0", - "license": "ISC", + "node_modules/storybook/node_modules/@esbuild/android-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.7.tgz", + "integrity": "sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": ">=18" } }, - "node_modules/signale": { - "version": "1.4.0", + "node_modules/storybook/node_modules/@esbuild/android-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.7.tgz", + "integrity": "sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg==", + "cpu": [ + "x64" + ], "license": "MIT", - "dependencies": { - "chalk": "^2.3.2", - "figures": "^2.0.0", - "pkg-conf": "^2.1.0" - }, + "optional": true, + "os": [ + "android" + ], "engines": { - "node": ">=6" + "node": ">=18" } }, - "node_modules/singleton-manager": { - "version": "1.8.0", - "dev": true, - "license": "MIT" - }, - "node_modules/sirv": { - "version": "3.0.2", + "node_modules/storybook/node_modules/@esbuild/darwin-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.7.tgz", + "integrity": "sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==", + "cpu": [ + "arm64" + ], "license": "MIT", - "dependencies": { - "@polka/url": "^1.0.0-next.24", - "mrmime": "^2.0.0", - "totalist": "^3.0.0" - }, + "optional": true, + "os": [ + "darwin" + ], "engines": { "node": ">=18" } }, - "node_modules/skin-tone": { - "version": "2.0.0", - "dev": true, + "node_modules/storybook/node_modules/@esbuild/darwin-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.7.tgz", + "integrity": "sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ==", + "cpu": [ + "x64" + ], "license": "MIT", - "dependencies": { - "unicode-emoji-modifier-base": "^1.0.0" - }, + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">=8" + "node": ">=18" } }, - "node_modules/slash": { - "version": "3.0.0", - "dev": true, + "node_modules/storybook/node_modules/@esbuild/freebsd-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.7.tgz", + "integrity": "sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==", + "cpu": [ + "arm64" + ], "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], "engines": { - "node": ">=8" + "node": ">=18" } }, - "node_modules/slice-ansi": { - "version": "7.1.2", - "dev": true, + "node_modules/storybook/node_modules/@esbuild/freebsd-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.7.tgz", + "integrity": "sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ==", + "cpu": [ + "x64" + ], "license": "MIT", - "dependencies": { - "ansi-styles": "^6.2.1", - "is-fullwidth-code-point": "^5.0.0" - }, + "optional": true, + "os": [ + "freebsd" + ], "engines": { "node": ">=18" - }, - "funding": { - "url": "https://github.com/chalk/slice-ansi?sponsor=1" } }, - "node_modules/slice-ansi/node_modules/ansi-styles": { - "version": "6.2.3", - "dev": true, + "node_modules/storybook/node_modules/@esbuild/linux-arm": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.7.tgz", + "integrity": "sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA==", + "cpu": [ + "arm" + ], "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "node": ">=18" } }, - "node_modules/smart-buffer": { - "version": "4.2.0", + "node_modules/storybook/node_modules/@esbuild/linux-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.7.tgz", + "integrity": "sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==", + "cpu": [ + "arm64" + ], "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">= 6.0.0", - "npm": ">= 3.0.0" + "node": ">=18" } }, - "node_modules/sockjs": { - "version": "0.3.24", + "node_modules/storybook/node_modules/@esbuild/linux-ia32": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.7.tgz", + "integrity": "sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg==", + "cpu": [ + "ia32" + ], "license": "MIT", - "dependencies": { - "faye-websocket": "^0.11.3", - "uuid": "^8.3.2", - "websocket-driver": "^0.7.4" + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" } }, - "node_modules/socks": { - "version": "2.8.7", + "node_modules/storybook/node_modules/@esbuild/linux-loong64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.7.tgz", + "integrity": "sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==", + "cpu": [ + "loong64" + ], "license": "MIT", - "dependencies": { - "ip-address": "^10.0.1", - "smart-buffer": "^4.2.0" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">= 10.0.0", - "npm": ">= 3.0.0" + "node": ">=18" } }, - "node_modules/socks-proxy-agent": { - "version": "7.0.0", + "node_modules/storybook/node_modules/@esbuild/linux-mips64el": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.7.tgz", + "integrity": "sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw==", + "cpu": [ + "mips64el" + ], "license": "MIT", - "dependencies": { - "agent-base": "^6.0.2", - "debug": "^4.3.3", - "socks": "^2.6.2" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">= 10" + "node": ">=18" } }, - "node_modules/sortablejs": { - "version": "1.15.6", - "license": "MIT" - }, - "node_modules/source-list-map": { - "version": "2.0.1", - "license": "MIT" - }, - "node_modules/source-map": { - "version": "0.6.1", - "license": "BSD-3-Clause", + "node_modules/storybook/node_modules/@esbuild/linux-ppc64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.7.tgz", + "integrity": "sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=0.10.0" + "node": ">=18" } }, - "node_modules/source-map-js": { - "version": "1.2.1", - "license": "BSD-3-Clause", + "node_modules/storybook/node_modules/@esbuild/linux-riscv64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.7.tgz", + "integrity": "sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=0.10.0" + "node": ">=18" } }, - "node_modules/source-map-support": { - "version": "0.5.21", + "node_modules/storybook/node_modules/@esbuild/linux-s390x": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.7.tgz", + "integrity": "sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==", + "cpu": [ + "s390x" + ], "license": "MIT", - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/spdx-correct": { - "version": "3.2.0", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" } }, - "node_modules/spdx-exceptions": { - "version": "2.5.0", - "dev": true, - "license": "CC-BY-3.0" - }, - "node_modules/spdx-expression-parse": { - "version": "3.0.1", - "dev": true, + "node_modules/storybook/node_modules/@esbuild/linux-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.7.tgz", + "integrity": "sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA==", + "cpu": [ + "x64" + ], "license": "MIT", - "dependencies": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" } }, - "node_modules/spdx-license-ids": { - "version": "3.0.22", - "dev": true, - "license": "CC0-1.0" - }, - "node_modules/spdy": { - "version": "4.0.2", + "node_modules/storybook/node_modules/@esbuild/netbsd-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.7.tgz", + "integrity": "sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==", + "cpu": [ + "arm64" + ], "license": "MIT", - "dependencies": { - "debug": "^4.1.0", - "handle-thing": "^2.0.0", - "http-deceiver": "^1.2.7", - "select-hose": "^2.0.0", - "spdy-transport": "^3.0.0" - }, + "optional": true, + "os": [ + "netbsd" + ], "engines": { - "node": ">=6.0.0" + "node": ">=18" } }, - "node_modules/spdy-transport": { - "version": "3.0.0", + "node_modules/storybook/node_modules/@esbuild/netbsd-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.7.tgz", + "integrity": "sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw==", + "cpu": [ + "x64" + ], "license": "MIT", - "dependencies": { - "debug": "^4.1.0", - "detect-node": "^2.0.4", - "hpack.js": "^2.1.6", - "obuf": "^1.1.2", - "readable-stream": "^3.0.6", - "wbuf": "^1.7.3" + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" } }, - "node_modules/ssr-window": { - "version": "4.0.2", - "license": "MIT" - }, - "node_modules/ssri": { - "version": "9.0.1", - "license": "ISC", - "dependencies": { - "minipass": "^3.1.1" - }, + "node_modules/storybook/node_modules/@esbuild/openbsd-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.7.tgz", + "integrity": "sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": ">=18" } }, - "node_modules/ssri/node_modules/minipass": { - "version": "3.3.6", - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, + "node_modules/storybook/node_modules/@esbuild/openbsd-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.7.tgz", + "integrity": "sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], "engines": { - "node": ">=8" + "node": ">=18" } }, - "node_modules/ssri/node_modules/yallist": { - "version": "4.0.0", - "license": "ISC" - }, - "node_modules/stackback": { - "version": "0.0.2", - "license": "MIT" - }, - "node_modules/statuses": { - "version": "2.0.1", + "node_modules/storybook/node_modules/@esbuild/openharmony-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.7.tgz", + "integrity": "sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==", + "cpu": [ + "arm64" + ], "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], "engines": { - "node": ">= 0.8" + "node": ">=18" } }, - "node_modules/std-env": { - "version": "4.1.0", - "license": "MIT" + "node_modules/storybook/node_modules/@esbuild/sunos-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.7.tgz", + "integrity": "sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } }, - "node_modules/stdin-discarder": { - "version": "0.3.2", - "dev": true, + "node_modules/storybook/node_modules/@esbuild/win32-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.7.tgz", + "integrity": "sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==", + "cpu": [ + "arm64" + ], "license": "MIT", + "optional": true, + "os": [ + "win32" + ], "engines": { "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/stop-iteration-iterator": { - "version": "1.1.0", - "dev": true, + "node_modules/storybook/node_modules/@esbuild/win32-ia32": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.7.tgz", + "integrity": "sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw==", + "cpu": [ + "ia32" + ], "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "internal-slot": "^1.1.0" - }, + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": ">= 0.4" + "node": ">=18" } }, - "node_modules/storybook": { - "version": "10.5.5", - "resolved": "https://registry.npmjs.org/storybook/-/storybook-10.5.5.tgz", - "integrity": "sha512-UscBIBJDloUeqntukHOhP1a5W/vouePDJbzPSxj466WK801FZtzQiMffMtkjzJiWSuj20wfaYlB2QQKh9aOYAg==", + "node_modules/storybook/node_modules/@esbuild/win32-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.7.tgz", + "integrity": "sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg==", + "cpu": [ + "x64" + ], "license": "MIT", - "dependencies": { - "@storybook/global": "^5.0.0", - "@storybook/icons": "^2.0.2", - "@testing-library/dom": "^10.4.1", - "@testing-library/jest-dom": "^6.9.1", - "@testing-library/user-event": "^14.6.1", - "@vitest/expect": "3.2.4", - "@vitest/spy": "3.2.4", - "@webcontainer/env": "^1.1.1", - "esbuild": "^0.18.0 || ^0.19.0 || ^0.20.0 || ^0.21.0 || ^0.22.0 || ^0.23.0 || ^0.24.0 || ^0.25.0 || ^0.26.0 || ^0.27.0 || ^0.28.0", - "jsonc-parser": "^3.3.1", - "open": "^10.2.0", - "oxc-parser": "^0.127.0", - "oxc-resolver": "^11.19.1", - "recast": "^0.23.5", - "semver": "^7.7.3", - "use-sync-external-store": "^1.5.0", - "ws": "^8.21.1" - }, - "bin": { - "storybook": "dist/bin/dispatcher.js" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - }, - "peerDependencies": { - "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", - "prettier": "^2 || ^3", - "vite-plus": "^0.1.15 || ^0.2.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "prettier": { - "optional": true - }, - "vite-plus": { - "optional": true - } + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" } }, "node_modules/storybook/node_modules/define-lazy-prop": { @@ -20746,6 +20053,47 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/storybook/node_modules/esbuild": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.7.tgz", + "integrity": "sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w==", + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.27.7", + "@esbuild/android-arm": "0.27.7", + "@esbuild/android-arm64": "0.27.7", + "@esbuild/android-x64": "0.27.7", + "@esbuild/darwin-arm64": "0.27.7", + "@esbuild/darwin-x64": "0.27.7", + "@esbuild/freebsd-arm64": "0.27.7", + "@esbuild/freebsd-x64": "0.27.7", + "@esbuild/linux-arm": "0.27.7", + "@esbuild/linux-arm64": "0.27.7", + "@esbuild/linux-ia32": "0.27.7", + "@esbuild/linux-loong64": "0.27.7", + "@esbuild/linux-mips64el": "0.27.7", + "@esbuild/linux-ppc64": "0.27.7", + "@esbuild/linux-riscv64": "0.27.7", + "@esbuild/linux-s390x": "0.27.7", + "@esbuild/linux-x64": "0.27.7", + "@esbuild/netbsd-arm64": "0.27.7", + "@esbuild/netbsd-x64": "0.27.7", + "@esbuild/openbsd-arm64": "0.27.7", + "@esbuild/openbsd-x64": "0.27.7", + "@esbuild/openharmony-arm64": "0.27.7", + "@esbuild/sunos-x64": "0.27.7", + "@esbuild/win32-arm64": "0.27.7", + "@esbuild/win32-ia32": "0.27.7", + "@esbuild/win32-x64": "0.27.7" + } + }, "node_modules/storybook/node_modules/open": { "version": "10.2.0", "resolved": "https://registry.npmjs.org/open/-/open-10.2.0.tgz", @@ -20776,27 +20124,6 @@ "node": ">=10" } }, - "node_modules/storybook/node_modules/ws": { - "version": "8.21.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.1.tgz", - "integrity": "sha512-+0NTnW77fFN/DjQi6k/Sq/Yvk4Sgajw7urW8V+asjXnRgDs9gyGkdb7EzgfhA4goXsRIZKE28fzIXBHEzhuiWw==", - "license": "MIT", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, "node_modules/string_decoder": { "version": "1.3.0", "license": "MIT", @@ -20992,7 +20319,6 @@ "node_modules/strip-json-comments": { "version": "3.1.1", "license": "MIT", - "peer": true, "engines": { "node": ">=8" }, @@ -21618,19 +20944,6 @@ "node": ">=8" } }, - "node_modules/tagged-tag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/tagged-tag/-/tagged-tag-1.0.0.tgz", - "integrity": "sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/tailwindcss": { "version": "4.2.4", "license": "MIT" @@ -21766,6 +21079,10 @@ "version": "2.20.3", "license": "MIT" }, + "node_modules/text-table": { + "version": "0.2.0", + "license": "MIT" + }, "node_modules/thenify": { "version": "3.3.1", "dev": true, @@ -21825,16 +21142,6 @@ "url": "https://github.com/sponsors/SuperchupuDev" } }, - "node_modules/tinypool": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-2.1.0.tgz", - "integrity": "sha512-Pugqs6M0m7Lv1I7FtxN4aoyToKg1C4tu+/381vH35y8oENM/Ai7f7C4StcoK4/+BSw9ebcS8jRiVrORFKCALLw==", - "devOptional": true, - "license": "MIT", - "engines": { - "node": "^20.0.0 || >=22.0.0" - } - }, "node_modules/tinyrainbow": { "version": "2.0.0", "license": "MIT", @@ -21887,6 +21194,25 @@ "node": ">=6" } }, + "node_modules/tree-kill": { + "version": "1.2.2", + "dev": true, + "license": "MIT", + "bin": { + "tree-kill": "cli.js" + } + }, + "node_modules/ts-api-utils": { + "version": "2.5.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.12" + }, + "peerDependencies": { + "typescript": ">=4.8.4" + } + }, "node_modules/ts-dedent": { "version": "2.2.0", "dev": true, @@ -22022,7 +21348,6 @@ "node_modules/type-check": { "version": "0.4.0", "license": "MIT", - "peer": true, "dependencies": { "prelude-ls": "^1.2.1" }, @@ -22031,16 +21356,10 @@ } }, "node_modules/type-fest": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-5.8.0.tgz", - "integrity": "sha512-YGYEVz3Fm5iy/AybuA0oyNFq7H4CgQNfRp/qfe8nurE1kuCeNm3/vfm9X4Mtl+qLyaKJUh5xrFZwogr41SMjYA==", - "dev": true, + "version": "0.20.2", "license": "(MIT OR CC0-1.0)", - "dependencies": { - "tagged-tag": "^1.0.0" - }, "engines": { - "node": ">=20" + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -22138,6 +21457,28 @@ "node": ">=14.17" } }, + "node_modules/typescript-eslint": { + "version": "8.60.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/eslint-plugin": "8.60.0", + "@typescript-eslint/parser": "8.60.0", + "@typescript-eslint/typescript-estree": "8.60.0", + "@typescript-eslint/utils": "8.60.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, "node_modules/typical": { "version": "4.0.0", "dev": true, @@ -22192,6 +21533,33 @@ "node": ">=0.10.0" } }, + "node_modules/unconfig-core": { + "version": "7.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@quansync/fs": "^1.0.0", + "quansync": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/unconfig-core/node_modules/quansync": { + "version": "1.0.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/antfu" + }, + { + "type": "individual", + "url": "https://github.com/sponsors/sxzz" + } + ], + "license": "MIT" + }, "node_modules/undici-types": { "version": "7.19.2", "license": "MIT" @@ -22348,6 +21716,83 @@ } } }, + "node_modules/unrun": { + "version": "0.2.37", + "dev": true, + "license": "MIT", + "dependencies": { + "rolldown": "1.0.0-rc.17" + }, + "bin": { + "unrun": "dist/cli.mjs" + }, + "engines": { + "node": ">=20.19.0" + }, + "funding": { + "url": "https://github.com/sponsors/Gugustinette" + }, + "peerDependencies": { + "synckit": "^0.11.11" + }, + "peerDependenciesMeta": { + "synckit": { + "optional": true + } + } + }, + "node_modules/unrun/node_modules/@rolldown/binding-darwin-arm64": { + "version": "1.0.0-rc.17", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/unrun/node_modules/@rolldown/pluginutils": { + "version": "1.0.0-rc.17", + "dev": true, + "license": "MIT" + }, + "node_modules/unrun/node_modules/rolldown": { + "version": "1.0.0-rc.17", + "dev": true, + "license": "MIT", + "dependencies": { + "@oxc-project/types": "=0.127.0", + "@rolldown/pluginutils": "1.0.0-rc.17" + }, + "bin": { + "rolldown": "bin/cli.mjs" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "optionalDependencies": { + "@rolldown/binding-android-arm64": "1.0.0-rc.17", + "@rolldown/binding-darwin-arm64": "1.0.0-rc.17", + "@rolldown/binding-darwin-x64": "1.0.0-rc.17", + "@rolldown/binding-freebsd-x64": "1.0.0-rc.17", + "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-rc.17", + "@rolldown/binding-linux-arm64-gnu": "1.0.0-rc.17", + "@rolldown/binding-linux-arm64-musl": "1.0.0-rc.17", + "@rolldown/binding-linux-ppc64-gnu": "1.0.0-rc.17", + "@rolldown/binding-linux-s390x-gnu": "1.0.0-rc.17", + "@rolldown/binding-linux-x64-gnu": "1.0.0-rc.17", + "@rolldown/binding-linux-x64-musl": "1.0.0-rc.17", + "@rolldown/binding-openharmony-arm64": "1.0.0-rc.17", + "@rolldown/binding-wasm32-wasi": "1.0.0-rc.17", + "@rolldown/binding-win32-arm64-msvc": "1.0.0-rc.17", + "@rolldown/binding-win32-x64-msvc": "1.0.0-rc.17" + } + }, "node_modules/update-browserslist-db": { "version": "1.1.4", "funding": [ @@ -22379,7 +21824,6 @@ "node_modules/uri-js": { "version": "4.4.1", "license": "BSD-2-Clause", - "peer": true, "dependencies": { "punycode": "^2.1.0" } @@ -22487,7 +21931,7 @@ }, "node_modules/validate-npm-package-name": { "version": "5.0.1", - "devOptional": true, + "dev": true, "license": "ISC", "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" @@ -22505,48 +21949,42 @@ "license": "MIT" }, "node_modules/vite": { - "name": "@voidzero-dev/vite-plus-core", - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/@voidzero-dev/vite-plus-core/-/vite-plus-core-0.2.6.tgz", - "integrity": "sha512-vqDuuLJWS2JHWkFO7r8Z6AehtKnurpnYtw2XEQtjIfwE2GgSAO3zJdPIeaEZiovS6CqfQa+iOMn3kzVzeTSpTw==", + "version": "8.0.10", "license": "MIT", "dependencies": { - "@oxc-project/runtime": "=0.141.0", - "@oxc-project/types": "=0.141.0", - "lightningcss": "^1.33.0", - "postcss": "^8.5.6", - "yuku-codegen": "^0.5.44", - "yuku-parser": "^0.5.44" + "lightningcss": "^1.32.0", + "picomatch": "^4.0.4", + "postcss": "^8.5.10", + "rolldown": "1.0.0-rc.17", + "tinyglobby": "^0.2.16" + }, + "bin": { + "vite": "bin/vite.js" }, "engines": { - "node": "^20.19.0 || ^22.18.0 || >=24.11.0" + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { - "@arethetypeswrong/core": "^0.18.1", "@types/node": "^20.19.0 || >=22.12.0", - "@vitejs/devtools": "^0.3.0", + "@vitejs/devtools": "^0.1.0", "esbuild": "^0.27.0 || ^0.28.0", "jiti": ">=1.21.0", "less": "^4.0.0", - "publint": "^0.3.8", "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", - "typescript": "^5.0.0 || ^6.0.0 || ^7.0.0", - "unplugin-unused": "^0.5.0", - "unrun": "*", "yaml": "^2.4.2" }, "peerDependenciesMeta": { - "@arethetypeswrong/core": { - "optional": true - }, "@types/node": { "optional": true }, @@ -22562,9 +22000,6 @@ "less": { "optional": true }, - "publint": { - "optional": true - }, "sass": { "optional": true }, @@ -22583,15 +22018,6 @@ "tsx": { "optional": true }, - "typescript": { - "optional": true - }, - "unplugin-unused": { - "optional": true - }, - "unrun": { - "optional": true - }, "yaml": { "optional": true } @@ -22639,83 +22065,193 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/vite-plus": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/vite-plus/-/vite-plus-0.2.6.tgz", - "integrity": "sha512-fFX8GLENhtzvnE4NmTPC8INRxjD2kZKcqUW0p7jOdawmHTNZqM5FiieyWOG6WH1a/axu9FCsbUNb918grfzDTw==", - "devOptional": true, + "node_modules/vite-tsconfig-paths": { + "version": "6.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.1.1", + "globrex": "^0.1.2", + "tsconfck": "^3.0.3" + }, + "peerDependencies": { + "vite": "*" + } + }, + "node_modules/vite-tsconfig-paths/node_modules/tsconfck": { + "version": "3.1.6", + "dev": true, + "license": "MIT", + "bin": { + "tsconfck": "bin/tsconfck.js" + }, + "engines": { + "node": "^18 || >=20" + }, + "peerDependencies": { + "typescript": "^5.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/vite/node_modules/@rolldown/binding-darwin-arm64": { + "version": "1.0.0-rc.17", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/vite/node_modules/@rolldown/pluginutils": { + "version": "1.0.0-rc.17", + "license": "MIT" + }, + "node_modules/vite/node_modules/fsevents": { + "version": "2.3.3", + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/vite/node_modules/rolldown": { + "version": "1.0.0-rc.17", "license": "MIT", "dependencies": { - "@oxc-project/types": "=0.141.0", - "@oxlint/plugins": "=1.73.0", - "@vitest/browser": "4.1.10", - "@vitest/browser-preview": "4.1.10", - "@vitest/expect": "4.1.10", - "@vitest/mocker": "4.1.10", - "@vitest/pretty-format": "4.1.10", - "@vitest/runner": "4.1.10", - "@vitest/snapshot": "4.1.10", - "@vitest/spy": "4.1.10", - "@vitest/utils": "4.1.10", - "@voidzero-dev/vite-plus-core": "0.2.6", - "oxfmt": "=0.60.0", - "oxlint": "=1.75.0", - "oxlint-tsgolint": "=7.0.2001", - "vitest": "4.1.10" + "@oxc-project/types": "=0.127.0", + "@rolldown/pluginutils": "1.0.0-rc.17" }, "bin": { - "oxfmt": "bin/oxfmt", - "oxlint": "bin/oxlint", - "vp": "bin/vp", - "vpr": "bin/vpr" + "rolldown": "bin/cli.mjs" }, "engines": { - "node": "^20.19.0 || ^22.18.0 || >=24.11.0" + "node": "^20.19.0 || >=22.12.0" }, "optionalDependencies": { - "@voidzero-dev/vite-plus-darwin-arm64": "0.2.6", - "@voidzero-dev/vite-plus-darwin-x64": "0.2.6", - "@voidzero-dev/vite-plus-linux-arm64-gnu": "0.2.6", - "@voidzero-dev/vite-plus-linux-arm64-musl": "0.2.6", - "@voidzero-dev/vite-plus-linux-x64-gnu": "0.2.6", - "@voidzero-dev/vite-plus-linux-x64-musl": "0.2.6", - "@voidzero-dev/vite-plus-win32-arm64-msvc": "0.2.6", - "@voidzero-dev/vite-plus-win32-x64-msvc": "0.2.6" + "@rolldown/binding-android-arm64": "1.0.0-rc.17", + "@rolldown/binding-darwin-arm64": "1.0.0-rc.17", + "@rolldown/binding-darwin-x64": "1.0.0-rc.17", + "@rolldown/binding-freebsd-x64": "1.0.0-rc.17", + "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-rc.17", + "@rolldown/binding-linux-arm64-gnu": "1.0.0-rc.17", + "@rolldown/binding-linux-arm64-musl": "1.0.0-rc.17", + "@rolldown/binding-linux-ppc64-gnu": "1.0.0-rc.17", + "@rolldown/binding-linux-s390x-gnu": "1.0.0-rc.17", + "@rolldown/binding-linux-x64-gnu": "1.0.0-rc.17", + "@rolldown/binding-linux-x64-musl": "1.0.0-rc.17", + "@rolldown/binding-openharmony-arm64": "1.0.0-rc.17", + "@rolldown/binding-wasm32-wasi": "1.0.0-rc.17", + "@rolldown/binding-win32-arm64-msvc": "1.0.0-rc.17", + "@rolldown/binding-win32-x64-msvc": "1.0.0-rc.17" + } + }, + "node_modules/vitest": { + "version": "4.1.5", + "license": "MIT", + "dependencies": { + "@vitest/expect": "4.1.5", + "@vitest/mocker": "4.1.5", + "@vitest/pretty-format": "4.1.5", + "@vitest/runner": "4.1.5", + "@vitest/snapshot": "4.1.5", + "@vitest/spy": "4.1.5", + "@vitest/utils": "4.1.5", + "es-module-lexer": "^2.0.0", + "expect-type": "^1.3.0", + "magic-string": "^0.30.21", + "obug": "^2.1.1", + "pathe": "^2.0.3", + "picomatch": "^4.0.3", + "std-env": "^4.0.0-rc.1", + "tinybench": "^2.9.0", + "tinyexec": "^1.0.2", + "tinyglobby": "^0.2.15", + "tinyrainbow": "^3.1.0", + "vite": "^6.0.0 || ^7.0.0 || ^8.0.0", + "why-is-node-running": "^2.3.0" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": "^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" }, "peerDependencies": { - "@vitest/browser-playwright": "4.1.10", - "@vitest/browser-webdriverio": "4.1.10" + "@edge-runtime/vm": "*", + "@opentelemetry/api": "^1.9.0", + "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0", + "@vitest/browser-playwright": "4.1.5", + "@vitest/browser-preview": "4.1.5", + "@vitest/browser-webdriverio": "4.1.5", + "@vitest/coverage-istanbul": "4.1.5", + "@vitest/coverage-v8": "4.1.5", + "@vitest/ui": "4.1.5", + "happy-dom": "*", + "jsdom": "*", + "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" }, "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@opentelemetry/api": { + "optional": true + }, + "@types/node": { + "optional": true + }, "@vitest/browser-playwright": { "optional": true }, + "@vitest/browser-preview": { + "optional": true + }, "@vitest/browser-webdriverio": { "optional": true + }, + "@vitest/coverage-istanbul": { + "optional": true + }, + "@vitest/coverage-v8": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + }, + "vite": { + "optional": false } } }, - "node_modules/vite-plus/node_modules/@oxc-project/types": { - "version": "0.141.0", - "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.141.0.tgz", - "integrity": "sha512-S4as7z0j0xQkXcJlyY5ehntwK8/wRkQb9Cyqw+J/N2rkWGQGK0SxD6X6DhQTc7qsxVTBxXbxZtBJh3mr3PtIzQ==", - "devOptional": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/Boshen" - } - }, - "node_modules/vite-plus/node_modules/@vitest/expect": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.10.tgz", - "integrity": "sha512-YsCn+qAk1GWjQOWFEsEcL2gNQ0zmVmQu3T03qP6UyjhtmdtwtbuI+DASn/7iQB3HGTXkdBwGddzxPlmiql5vlA==", - "devOptional": true, + "node_modules/vitest/node_modules/@vitest/expect": { + "version": "4.1.5", "license": "MIT", "dependencies": { "@standard-schema/spec": "^1.1.0", "@types/chai": "^5.2.2", - "@vitest/spy": "4.1.10", - "@vitest/utils": "4.1.10", + "@vitest/spy": "4.1.5", + "@vitest/utils": "4.1.5", "chai": "^6.2.2", "tinyrainbow": "^3.1.0" }, @@ -22723,11 +22259,8 @@ "url": "https://opencollective.com/vitest" } }, - "node_modules/vite-plus/node_modules/@vitest/pretty-format": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.10.tgz", - "integrity": "sha512-W1HsjSH4MXQ9YfmmhLAoIYf1HRfekQCGngeIgcei6MP5QQGWUe0gkopdZQaVCFO+JDJMrAJGwa5pRpNpvy4P8Q==", - "devOptional": true, + "node_modules/vitest/node_modules/@vitest/pretty-format": { + "version": "4.1.5", "license": "MIT", "dependencies": { "tinyrainbow": "^3.1.0" @@ -22736,24 +22269,18 @@ "url": "https://opencollective.com/vitest" } }, - "node_modules/vite-plus/node_modules/@vitest/spy": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.10.tgz", - "integrity": "sha512-PLf/Ugvoq5wO/b4rwYCR1h2PSIdXz7wnkQFMiUpLdtM7l6pqVFcQIBEHyT1+l+cj7mNwAfZHzqXqDyjvOuwbDw==", - "devOptional": true, + "node_modules/vitest/node_modules/@vitest/spy": { + "version": "4.1.5", "license": "MIT", "funding": { "url": "https://opencollective.com/vitest" } }, - "node_modules/vite-plus/node_modules/@vitest/utils": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.10.tgz", - "integrity": "sha512-fy9am/HWxbaGt/Sawrp90vt6Y6jQwf1RX77cz3uwoJwJVMli/e1IEwRPnMNJ7vKfPTwo0diXifkpPvwH9v7nGA==", - "devOptional": true, + "node_modules/vitest/node_modules/@vitest/utils": { + "version": "4.1.5", "license": "MIT", "dependencies": { - "@vitest/pretty-format": "4.1.10", + "@vitest/pretty-format": "4.1.5", "convert-source-map": "^2.0.0", "tinyrainbow": "^3.1.0" }, @@ -22761,51 +22288,113 @@ "url": "https://opencollective.com/vitest" } }, - "node_modules/vite-plus/node_modules/chai": { + "node_modules/vitest/node_modules/chai": { "version": "6.2.2", - "resolved": "https://registry.npmjs.org/chai/-/chai-6.2.2.tgz", - "integrity": "sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==", - "devOptional": true, "license": "MIT", "engines": { "node": ">=18" } }, - "node_modules/vite-plus/node_modules/tinyrainbow": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.1.1.tgz", - "integrity": "sha512-yau8yJdTt989Mm0Bd/236QnzEiPf2xLLTqUZRUJOo/3CB078LSwzei343DgtJVmfJKJE3TMINY1u42SQsP6mXw==", - "devOptional": true, + "node_modules/vitest/node_modules/es-module-lexer": { + "version": "2.1.0", + "license": "MIT" + }, + "node_modules/vitest/node_modules/tinyrainbow": { + "version": "3.1.0", "license": "MIT", "engines": { "node": ">=14.0.0" } }, - "node_modules/vite-tsconfig-paths": { - "version": "6.1.1", + "node_modules/void-elements": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/vscode-languageserver-types": { + "version": "3.17.5", + "license": "MIT" + }, + "node_modules/vscode-uri": { + "version": "3.1.0", "dev": true, + "license": "MIT" + }, + "node_modules/vue": { + "version": "3.5.33", "license": "MIT", "dependencies": { - "debug": "^4.1.1", - "globrex": "^0.1.2", - "tsconfck": "^3.0.3" + "@vue/compiler-dom": "3.5.33", + "@vue/compiler-sfc": "3.5.33", + "@vue/runtime-dom": "3.5.33", + "@vue/server-renderer": "3.5.33", + "@vue/shared": "3.5.33" }, "peerDependencies": { - "vite": "*" + "typescript": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/vite-tsconfig-paths/node_modules/tsconfck": { - "version": "3.1.6", + "node_modules/vue-apexcharts": { + "version": "1.7.0", "dev": true, "license": "MIT", - "bin": { - "tsconfck": "bin/tsconfck.js" + "peerDependencies": { + "apexcharts": ">=4.0.0", + "vue": "^2.5.17" + } + }, + "node_modules/vue-autosuggest": { + "version": "2.2.0", + "license": "MIT", + "engines": { + "node": "> 4", + "npm": "> 3" }, + "peerDependencies": { + "vue": ">= 2.5.0" + } + }, + "node_modules/vue-awesome-swiper": { + "version": "4.1.1", + "license": "MIT", "engines": { - "node": "^18 || >=20" + "node": ">=8" + }, + "peerDependencies": { + "swiper": "^5.2.0", + "vue": "2.x" + } + }, + "node_modules/vue-cleave": { + "version": "1.2.2", + "license": "MIT", + "dependencies": { + "cleave.js": "^0.7.15" + }, + "peerDependencies": { + "vue": ">=2" + } + }, + "node_modules/vue-component-meta": { + "version": "2.2.12", + "dev": true, + "license": "MIT", + "dependencies": { + "@volar/typescript": "2.4.15", + "@vue/language-core": "2.2.12", + "path-browserify": "^1.0.1", + "vue-component-type-helpers": "2.2.12" }, "peerDependencies": { - "typescript": "^5.0.0" + "typescript": "*" }, "peerDependenciesMeta": { "typescript": { @@ -22813,1333 +22402,1206 @@ } } }, - "node_modules/vite/node_modules/@oxc-project/types": { - "version": "0.141.0", - "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.141.0.tgz", - "integrity": "sha512-S4as7z0j0xQkXcJlyY5ehntwK8/wRkQb9Cyqw+J/N2rkWGQGK0SxD6X6DhQTc7qsxVTBxXbxZtBJh3mr3PtIzQ==", + "node_modules/vue-component-meta/node_modules/@volar/language-core": { + "version": "2.4.15", + "dev": true, "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/Boshen" + "dependencies": { + "@volar/source-map": "2.4.15" } }, - "node_modules/vite/node_modules/fsevents": { - "version": "2.3.3", - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } + "node_modules/vue-component-meta/node_modules/@volar/source-map": { + "version": "2.4.15", + "dev": true, + "license": "MIT" }, - "node_modules/vite/node_modules/lightningcss": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.33.0.tgz", - "integrity": "sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA==", - "license": "MPL-2.0", + "node_modules/vue-component-meta/node_modules/@volar/typescript": { + "version": "2.4.15", + "dev": true, + "license": "MIT", "dependencies": { - "detect-libc": "^2.0.3" - }, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - }, - "optionalDependencies": { - "lightningcss-android-arm64": "1.33.0", - "lightningcss-darwin-arm64": "1.33.0", - "lightningcss-darwin-x64": "1.33.0", - "lightningcss-freebsd-x64": "1.33.0", - "lightningcss-linux-arm-gnueabihf": "1.33.0", - "lightningcss-linux-arm64-gnu": "1.33.0", - "lightningcss-linux-arm64-musl": "1.33.0", - "lightningcss-linux-x64-gnu": "1.33.0", - "lightningcss-linux-x64-musl": "1.33.0", - "lightningcss-win32-arm64-msvc": "1.33.0", - "lightningcss-win32-x64-msvc": "1.33.0" - } - }, - "node_modules/vite/node_modules/lightningcss-android-arm64": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.33.0.tgz", - "integrity": "sha512-gEpRTalKdosp4Bb8qWtc2iOgE5SeIHlpS1up9bFq2wAyYhl1UdTObYiHe98zEM9SQvSoqQZ1IQD0JNpg3Ml5pg==", - "cpu": [ - "arm64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "@volar/language-core": "2.4.15", + "path-browserify": "^1.0.1", + "vscode-uri": "^3.0.8" } }, - "node_modules/vite/node_modules/lightningcss-darwin-arm64": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.33.0.tgz", - "integrity": "sha512-Sciaz8eenNTKn9b3t7+xr0ipTp9YxKQY4npwQ3mrRuL0BAVHBLyZxofhaKBAVtzmtRZ/zTyo0/to4B1uWG/Djg==", - "cpu": [ - "arm64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } + "node_modules/vue-component-meta/node_modules/vue-component-type-helpers": { + "version": "2.2.12", + "dev": true, + "license": "MIT" }, - "node_modules/vite/node_modules/lightningcss-darwin-x64": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.33.0.tgz", - "integrity": "sha512-Z5UPAxzrjlWNNyGy6i65cJzzvgJ5D3T6wMvs+gWpY9d7qRhANrxqAp6LhxIgZhWEw18RfJTGcRxjuLIBr+m8XQ==", - "cpu": [ - "x64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } + "node_modules/vue-component-type-helpers": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/vue-component-type-helpers/-/vue-component-type-helpers-3.3.2.tgz", + "integrity": "sha512-l4Z2Y34m7nFMlx8vrslJaVtXxUpzgDMSESC7TakG/c5kwjYT/do+E0NcT2/vWDzaoIhsShg/2OKwX7Q4nbzC0g==", + "dev": true, + "license": "MIT" }, - "node_modules/vite/node_modules/lightningcss-freebsd-x64": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.33.0.tgz", - "integrity": "sha512-QQM/Ti/hQajJwCY+RiWuCZ9sdtI/XQk7nDK5vC8kkdwixezOlDgvDx7+RT+QjK6FcFT4MpsuoBnHIo/O3StRRg==", - "cpu": [ - "x64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">= 12.0.0" + "node_modules/vue-docgen-api": { + "version": "4.79.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.24.7", + "@babel/types": "^7.24.7", + "@vue/compiler-dom": "^3.2.0", + "@vue/compiler-sfc": "^3.2.0", + "ast-types": "^0.16.1", + "esm-resolve": "^1.0.8", + "hash-sum": "^2.0.0", + "lru-cache": "^8.0.3", + "pug": "^3.0.2", + "recast": "^0.23.1", + "ts-map": "^1.0.3", + "vue-inbrowser-compiler-independent-utils": "^4.69.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "peerDependencies": { + "vue": ">=2" } }, - "node_modules/vite/node_modules/lightningcss-linux-arm-gnueabihf": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.33.0.tgz", - "integrity": "sha512-N7FVBe6iS24MlM6R/4RBTxGhQheZGs7tiQ9U32UtF75NzP5Q7xWPRqLBCKxlRQRk3rY1jCIPLzx7WzOhuUIRLQ==", - "cpu": [ - "arm" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } + "node_modules/vue-docgen-api/node_modules/hash-sum": { + "version": "2.0.0", + "dev": true, + "license": "MIT" }, - "node_modules/vite/node_modules/lightningcss-linux-arm64-gnu": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.33.0.tgz", - "integrity": "sha512-j2v/itmy4HlNxlc6voKXYgBqNi0Ng2LShg4z7GufpEgs05P+2suBVyi9I6YHq5uoVFx9ETin3eCEhLVyXGQnKg==", - "cpu": [ - "arm64" - ], - "libc": [ - "glibc" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], + "node_modules/vue-docgen-api/node_modules/lru-cache": { + "version": "8.0.5", + "dev": true, + "license": "ISC", "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "node": ">=16.14" } }, - "node_modules/vite/node_modules/lightningcss-linux-arm64-musl": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.33.0.tgz", - "integrity": "sha512-yiO5ROMuYQgXbC60yjZU5CYSFZGKXL0HFATXt9mHJn1+zW55oCtMI9NfcVhYLMFDL7gV7oBPon/EmMMGg2OvtQ==", - "cpu": [ - "arm64" - ], - "libc": [ - "musl" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" + "node_modules/vue-eslint-parser": { + "version": "9.4.3", + "license": "MIT", + "dependencies": { + "debug": "^4.3.4", + "eslint-scope": "^7.1.1", + "eslint-visitor-keys": "^3.3.0", + "espree": "^9.3.1", + "esquery": "^1.4.0", + "lodash": "^4.17.21", + "semver": "^7.3.6" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/vite/node_modules/lightningcss-linux-x64-gnu": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.33.0.tgz", - "integrity": "sha512-ar+Ju7LmcN0Jo4FpL4hpFybwNG9/3A/Br5KW2n2jyODg3MEZXaDYADdemoNS+BDNfMgKvylJLj4S5tyRActuAg==", - "cpu": [ - "x64" - ], - "libc": [ - "glibc" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], "engines": { - "node": ">= 12.0.0" + "node": "^14.17.0 || >=16.0.0" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/vite/node_modules/lightningcss-linux-x64-musl": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.33.0.tgz", - "integrity": "sha512-RYiYbkokw0trfKqqzfF55lginwEPrD3OJDfTuJzFs1MK6iFnDenaz1fqLLtX4ITG3OktJQXOeTaw1awrBAlZPw==", - "cpu": [ - "x64" - ], - "libc": [ - "musl" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" + "url": "https://github.com/sponsors/mysticatea" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "peerDependencies": { + "eslint": ">=6.0.0" } }, - "node_modules/vite/node_modules/lightningcss-win32-arm64-msvc": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.33.0.tgz", - "integrity": "sha512-1K+MPfLSFVpphzpdbfkhlWk6wBrTObBzS2T6db10PNOZgR9GoVsAWzwNyuhUYYbTp23j+4RrncfujZ4uAzXvwA==", - "cpu": [ - "arm64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "win32" - ], + "node_modules/vue-eslint-parser/node_modules/eslint-scope": { + "version": "7.2.2", + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, "engines": { - "node": ">= 12.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "url": "https://opencollective.com/eslint" } }, - "node_modules/vite/node_modules/lightningcss-win32-x64-msvc": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.33.0.tgz", - "integrity": "sha512-OlEICDx/Xl0FqSp4bry8zFnCvGpig3Gl4gCquvYwHuqJKEC1+n9NgDniFvqHGmMv1ZkqDJrDqKKSykTDX+ehuA==", - "cpu": [ - "x64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "win32" - ], + "node_modules/vue-eslint-parser/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "license": "Apache-2.0", "engines": { - "node": ">= 12.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "url": "https://opencollective.com/eslint" } - }, - "node_modules/vitest": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.10.tgz", - "integrity": "sha512-R9jUTe5S4Qb0HCd4TNqpC7oGcrMssMRGXLW80ubjWsW9VH5GF8y1Y0SFLY9AbqSk6nt0PnOx4H4WNJYZ13GUPw==", - "license": "MIT", - "dependencies": { - "@vitest/expect": "4.1.10", - "@vitest/mocker": "4.1.10", - "@vitest/pretty-format": "4.1.10", - "@vitest/runner": "4.1.10", - "@vitest/snapshot": "4.1.10", - "@vitest/spy": "4.1.10", - "@vitest/utils": "4.1.10", - "es-module-lexer": "^2.0.0", - "expect-type": "^1.3.0", - "magic-string": "^0.30.21", - "obug": "^2.1.1", - "pathe": "^2.0.3", - "picomatch": "^4.0.3", - "std-env": "^4.0.0-rc.1", - "tinybench": "^2.9.0", - "tinyexec": "^1.0.2", - "tinyglobby": "^0.2.15", - "tinyrainbow": "^3.1.0", - "vite": "^6.0.0 || ^7.0.0 || ^8.0.0", - "why-is-node-running": "^2.3.0" - }, + }, + "node_modules/vue-eslint-parser/node_modules/estraverse": { + "version": "5.3.0", + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/vue-eslint-parser/node_modules/semver": { + "version": "7.7.3", + "license": "ISC", "bin": { - "vitest": "vitest.mjs" + "semver": "bin/semver.js" }, "engines": { - "node": "^20.0.0 || ^22.0.0 || >=24.0.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" + "node": ">=10" + } + }, + "node_modules/vue-hot-reload-api": { + "version": "2.3.4", + "license": "MIT" + }, + "node_modules/vue-inbrowser-compiler-independent-utils": { + "version": "4.71.1", + "dev": true, + "license": "MIT", + "peerDependencies": { + "vue": ">=2" + } + }, + "node_modules/vue-loader": { + "version": "15.11.1", + "license": "MIT", + "dependencies": { + "@vue/component-compiler-utils": "^3.1.0", + "hash-sum": "^1.0.2", + "loader-utils": "^1.1.0", + "vue-hot-reload-api": "^2.3.0", + "vue-style-loader": "^4.1.0" }, "peerDependencies": { - "@edge-runtime/vm": "*", - "@opentelemetry/api": "^1.9.0", - "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0", - "@vitest/browser-playwright": "4.1.10", - "@vitest/browser-preview": "4.1.10", - "@vitest/browser-webdriverio": "4.1.10", - "@vitest/coverage-istanbul": "4.1.10", - "@vitest/coverage-v8": "4.1.10", - "@vitest/ui": "4.1.10", - "happy-dom": "*", - "jsdom": "*", - "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" + "css-loader": "*", + "webpack": "^3.0.0 || ^4.1.0 || ^5.0.0-0" }, "peerDependenciesMeta": { - "@edge-runtime/vm": { - "optional": true - }, - "@opentelemetry/api": { - "optional": true - }, - "@types/node": { - "optional": true - }, - "@vitest/browser-playwright": { - "optional": true - }, - "@vitest/browser-preview": { - "optional": true - }, - "@vitest/browser-webdriverio": { - "optional": true - }, - "@vitest/coverage-istanbul": { - "optional": true - }, - "@vitest/coverage-v8": { - "optional": true - }, - "@vitest/ui": { + "cache-loader": { "optional": true }, - "happy-dom": { + "prettier": { "optional": true }, - "jsdom": { + "vue-template-compiler": { "optional": true - }, - "vite": { - "optional": false } } }, - "node_modules/vitest/node_modules/@vitest/expect": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.10.tgz", - "integrity": "sha512-YsCn+qAk1GWjQOWFEsEcL2gNQ0zmVmQu3T03qP6UyjhtmdtwtbuI+DASn/7iQB3HGTXkdBwGddzxPlmiql5vlA==", + "node_modules/vue-lodash": { + "version": "1.0.4", + "license": "AFL-2.0", + "peerDependencies": { + "vue": ">= 2.0.0" + } + }, + "node_modules/vue-router": { + "version": "3.6.5", + "license": "MIT" + }, + "node_modules/vue-style-loader": { + "version": "4.1.3", "license": "MIT", "dependencies": { - "@standard-schema/spec": "^1.1.0", - "@types/chai": "^5.2.2", - "@vitest/spy": "4.1.10", - "@vitest/utils": "4.1.10", - "chai": "^6.2.2", - "tinyrainbow": "^3.1.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" + "hash-sum": "^1.0.2", + "loader-utils": "^1.0.2" } }, - "node_modules/vitest/node_modules/@vitest/pretty-format": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.10.tgz", - "integrity": "sha512-W1HsjSH4MXQ9YfmmhLAoIYf1HRfekQCGngeIgcei6MP5QQGWUe0gkopdZQaVCFO+JDJMrAJGwa5pRpNpvy4P8Q==", + "node_modules/vue-template-es2015-compiler": { + "version": "1.9.1", + "license": "MIT" + }, + "node_modules/vue-tsc": { + "version": "3.2.7", + "dev": true, "license": "MIT", "dependencies": { - "tinyrainbow": "^3.1.0" + "@volar/typescript": "2.4.28", + "@vue/language-core": "3.2.7" }, - "funding": { - "url": "https://opencollective.com/vitest" + "bin": { + "vue-tsc": "bin/vue-tsc.js" + }, + "peerDependencies": { + "typescript": ">=5.0.0" } }, - "node_modules/vitest/node_modules/@vitest/spy": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.10.tgz", - "integrity": "sha512-PLf/Ugvoq5wO/b4rwYCR1h2PSIdXz7wnkQFMiUpLdtM7l6pqVFcQIBEHyT1+l+cj7mNwAfZHzqXqDyjvOuwbDw==", + "node_modules/vue-tsc/node_modules/@vue/language-core": { + "version": "3.2.7", + "dev": true, "license": "MIT", - "funding": { - "url": "https://opencollective.com/vitest" + "dependencies": { + "@volar/language-core": "2.4.28", + "@vue/compiler-dom": "^3.5.0", + "@vue/shared": "^3.5.0", + "alien-signals": "^3.1.2", + "muggle-string": "^0.4.1", + "path-browserify": "^1.0.1", + "picomatch": "^4.0.4" } }, - "node_modules/vitest/node_modules/@vitest/utils": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.10.tgz", - "integrity": "sha512-fy9am/HWxbaGt/Sawrp90vt6Y6jQwf1RX77cz3uwoJwJVMli/e1IEwRPnMNJ7vKfPTwo0diXifkpPvwH9v7nGA==", + "node_modules/vue-tsc/node_modules/alien-signals": { + "version": "3.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/vue/node_modules/@vue/compiler-core": { + "version": "3.5.33", "license": "MIT", "dependencies": { - "@vitest/pretty-format": "4.1.10", - "convert-source-map": "^2.0.0", - "tinyrainbow": "^3.1.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" + "@babel/parser": "^7.29.2", + "@vue/shared": "3.5.33", + "entities": "^7.0.1", + "estree-walker": "^2.0.2", + "source-map-js": "^1.2.1" } }, - "node_modules/vitest/node_modules/chai": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/chai/-/chai-6.2.2.tgz", - "integrity": "sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==", + "node_modules/vue/node_modules/@vue/compiler-dom": { + "version": "3.5.33", "license": "MIT", - "engines": { - "node": ">=18" + "dependencies": { + "@vue/compiler-core": "3.5.33", + "@vue/shared": "3.5.33" } }, - "node_modules/vitest/node_modules/es-module-lexer": { - "version": "2.1.0", - "license": "MIT" - }, - "node_modules/vitest/node_modules/tinyrainbow": { - "version": "3.1.0", + "node_modules/vue/node_modules/@vue/compiler-sfc": { + "version": "3.5.33", "license": "MIT", - "engines": { - "node": ">=14.0.0" + "dependencies": { + "@babel/parser": "^7.29.2", + "@vue/compiler-core": "3.5.33", + "@vue/compiler-dom": "3.5.33", + "@vue/compiler-ssr": "3.5.33", + "@vue/shared": "3.5.33", + "estree-walker": "^2.0.2", + "magic-string": "^0.30.21", + "postcss": "^8.5.10", + "source-map-js": "^1.2.1" } }, - "node_modules/void-elements": { - "version": "3.1.0", - "dev": true, + "node_modules/vue/node_modules/@vue/compiler-ssr": { + "version": "3.5.33", "license": "MIT", - "engines": { - "node": ">=0.10.0" + "dependencies": { + "@vue/compiler-dom": "3.5.33", + "@vue/shared": "3.5.33" } }, - "node_modules/vscode-languageserver-types": { - "version": "3.17.5", + "node_modules/vue/node_modules/@vue/shared": { + "version": "3.5.33", "license": "MIT" }, - "node_modules/vscode-uri": { - "version": "3.1.0", - "dev": true, + "node_modules/vue/node_modules/entities": { + "version": "7.0.1", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/vue/node_modules/estree-walker": { + "version": "2.0.2", "license": "MIT" }, - "node_modules/vue": { - "version": "3.5.33", + "node_modules/vuetable-2": { + "version": "1.7.5", "license": "MIT", "dependencies": { - "@vue/compiler-dom": "3.5.33", - "@vue/compiler-sfc": "3.5.33", - "@vue/runtime-dom": "3.5.33", - "@vue/server-renderer": "3.5.33", - "@vue/shared": "3.5.33" - }, - "peerDependencies": { - "typescript": "*" + "axios": "^0.15.3" }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "engines": { + "node": ">= 4.0.0", + "npm": ">= 3.0.0" } }, - "node_modules/vue-apexcharts": { - "version": "1.7.0", - "dev": true, + "node_modules/vuetable-2/node_modules/axios": { + "version": "0.15.3", + "license": "MIT", + "dependencies": { + "follow-redirects": "1.0.0" + } + }, + "node_modules/vuetable-2/node_modules/debug": { + "version": "2.6.9", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/vuetable-2/node_modules/follow-redirects": { + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "debug": "^2.2.0" + } + }, + "node_modules/vuetable-2/node_modules/ms": { + "version": "2.0.0", + "license": "MIT" + }, + "node_modules/vuex": { + "version": "3.6.2", "license": "MIT", "peerDependencies": { - "apexcharts": ">=4.0.0", - "vue": "^2.5.17" + "vue": "^2.0.0" } }, - "node_modules/vue-autosuggest": { - "version": "2.2.0", + "node_modules/watchpack": { + "version": "2.4.4", "license": "MIT", - "engines": { - "node": "> 4", - "npm": "> 3" + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" }, - "peerDependencies": { - "vue": ">= 2.5.0" + "engines": { + "node": ">=10.13.0" } }, - "node_modules/vue-awesome-swiper": { - "version": "4.1.1", + "node_modules/wbuf": { + "version": "1.7.3", "license": "MIT", - "engines": { - "node": ">=8" - }, - "peerDependencies": { - "swiper": "^5.2.0", - "vue": "2.x" + "dependencies": { + "minimalistic-assert": "^1.0.0" } }, - "node_modules/vue-cleave": { - "version": "1.2.2", + "node_modules/wcwidth": { + "version": "1.0.1", + "dev": true, "license": "MIT", "dependencies": { - "cleave.js": "^0.7.15" + "defaults": "^1.0.3" + } + }, + "node_modules/webpack": { + "version": "5.102.1", + "license": "MIT", + "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.3", + "browserslist": "^4.26.3", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.17.3", + "es-module-lexer": "^1.2.1", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.11", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^4.3.3", + "tapable": "^2.3.0", + "terser-webpack-plugin": "^5.3.11", + "watchpack": "^2.4.4", + "webpack-sources": "^3.3.3" }, - "peerDependencies": { - "vue": ">=2" + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } } }, - "node_modules/vue-component-meta": { - "version": "3.3.8", - "resolved": "https://registry.npmjs.org/vue-component-meta/-/vue-component-meta-3.3.8.tgz", - "integrity": "sha512-ISPs6028bEvf1Hn44kFZ+uOiDomEkZCvfUgcdA83sVOYJ9g6EkH1M8yCmJP0ewLyf/0M+sF41bjgIg7jPw4MmA==", - "dev": true, + "node_modules/webpack-cli": { + "version": "5.1.4", "license": "MIT", "dependencies": { - "@volar/typescript": "2.4.28", - "@vue/language-core": "3.3.8", - "path-browserify": "^1.0.1" + "@discoveryjs/json-ext": "^0.5.0", + "@webpack-cli/configtest": "^2.1.1", + "@webpack-cli/info": "^2.0.2", + "@webpack-cli/serve": "^2.0.5", + "colorette": "^2.0.14", + "commander": "^10.0.1", + "cross-spawn": "^7.0.3", + "envinfo": "^7.7.3", + "fastest-levenshtein": "^1.0.12", + "import-local": "^3.0.2", + "interpret": "^3.1.1", + "rechoir": "^0.8.0", + "webpack-merge": "^5.7.3" + }, + "bin": { + "webpack-cli": "bin/cli.js" + }, + "engines": { + "node": ">=14.15.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" }, "peerDependencies": { - "typescript": "*" + "webpack": "5.x.x" }, "peerDependenciesMeta": { - "typescript": { + "@webpack-cli/generators": { + "optional": true + }, + "webpack-bundle-analyzer": { + "optional": true + }, + "webpack-dev-server": { "optional": true } } }, - "node_modules/vue-component-meta/node_modules/@vue/language-core": { - "version": "3.3.8", - "resolved": "https://registry.npmjs.org/@vue/language-core/-/language-core-3.3.8.tgz", - "integrity": "sha512-ieGT8jJdhhy0mGzStZhsg/qPw5bQZJg5yF+3+XU6saf4sM7yo9ZXy3h+nCwrm2+b4qS/SypkNdR2jAF3uei9tA==", - "dev": true, + "node_modules/webpack-cli/node_modules/commander": { + "version": "10.0.1", + "license": "MIT", + "engines": { + "node": ">=14" + } + }, + "node_modules/webpack-cli/node_modules/cross-spawn": { + "version": "7.0.6", "license": "MIT", "dependencies": { - "@volar/language-core": "2.4.28", - "@vue/compiler-dom": "^3.5.0", - "@vue/shared": "^3.5.0", - "alien-signals": "^3.2.1", - "muggle-string": "^0.4.1", - "path-browserify": "^1.0.1", - "picomatch": "^4.0.4" + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" } }, - "node_modules/vue-component-type-helpers": { - "version": "3.3.8", - "resolved": "https://registry.npmjs.org/vue-component-type-helpers/-/vue-component-type-helpers-3.3.8.tgz", - "integrity": "sha512-troqCMmQodQDqUqn63NQaFi+CDSclSe7sc8VEBFqf5GFLqmGR2Ph3P2WEC7qwpRVyEWsTi/aAr4vyOe/B1hU3g==", - "dev": true, - "license": "MIT" + "node_modules/webpack-cli/node_modules/path-key": { + "version": "3.1.1", + "license": "MIT", + "engines": { + "node": ">=8" + } }, - "node_modules/vue-docgen-api": { - "version": "4.79.2", - "dev": true, + "node_modules/webpack-cli/node_modules/shebang-command": { + "version": "2.0.0", "license": "MIT", "dependencies": { - "@babel/parser": "^7.24.7", - "@babel/types": "^7.24.7", - "@vue/compiler-dom": "^3.2.0", - "@vue/compiler-sfc": "^3.2.0", - "ast-types": "^0.16.1", - "esm-resolve": "^1.0.8", - "hash-sum": "^2.0.0", - "lru-cache": "^8.0.3", - "pug": "^3.0.2", - "recast": "^0.23.1", - "ts-map": "^1.0.3", - "vue-inbrowser-compiler-independent-utils": "^4.69.0" + "shebang-regex": "^3.0.0" }, - "peerDependencies": { - "vue": ">=2" + "engines": { + "node": ">=8" } }, - "node_modules/vue-docgen-api/node_modules/hash-sum": { - "version": "2.0.0", - "dev": true, - "license": "MIT" + "node_modules/webpack-cli/node_modules/shebang-regex": { + "version": "3.0.0", + "license": "MIT", + "engines": { + "node": ">=8" + } }, - "node_modules/vue-docgen-api/node_modules/lru-cache": { - "version": "8.0.5", - "dev": true, + "node_modules/webpack-cli/node_modules/which": { + "version": "2.0.2", "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, "engines": { - "node": ">=16.14" + "node": ">= 8" } }, - "node_modules/vue-hot-reload-api": { - "version": "2.3.4", - "license": "MIT" - }, - "node_modules/vue-inbrowser-compiler-independent-utils": { - "version": "4.71.1", - "dev": true, + "node_modules/webpack-dev-middleware": { + "version": "5.3.4", "license": "MIT", + "dependencies": { + "colorette": "^2.0.10", + "memfs": "^3.4.3", + "mime-types": "^2.1.31", + "range-parser": "^1.2.1", + "schema-utils": "^4.0.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, "peerDependencies": { - "vue": ">=2" + "webpack": "^4.0.0 || ^5.0.0" } }, - "node_modules/vue-loader": { - "version": "15.11.1", + "node_modules/webpack-dev-server": { + "version": "4.15.2", "license": "MIT", "dependencies": { - "@vue/component-compiler-utils": "^3.1.0", - "hash-sum": "^1.0.2", - "loader-utils": "^1.1.0", - "vue-hot-reload-api": "^2.3.0", - "vue-style-loader": "^4.1.0" + "@types/bonjour": "^3.5.9", + "@types/connect-history-api-fallback": "^1.3.5", + "@types/express": "^4.17.13", + "@types/serve-index": "^1.9.1", + "@types/serve-static": "^1.13.10", + "@types/sockjs": "^0.3.33", + "@types/ws": "^8.5.5", + "ansi-html-community": "^0.0.8", + "bonjour-service": "^1.0.11", + "chokidar": "^3.5.3", + "colorette": "^2.0.10", + "compression": "^1.7.4", + "connect-history-api-fallback": "^2.0.0", + "default-gateway": "^6.0.3", + "express": "^4.17.3", + "graceful-fs": "^4.2.6", + "html-entities": "^2.3.2", + "http-proxy-middleware": "^2.0.3", + "ipaddr.js": "^2.0.1", + "launch-editor": "^2.6.0", + "open": "^8.0.9", + "p-retry": "^4.5.0", + "rimraf": "^3.0.2", + "schema-utils": "^4.0.0", + "selfsigned": "^2.1.1", + "serve-index": "^1.9.1", + "sockjs": "^0.3.24", + "spdy": "^4.0.2", + "webpack-dev-middleware": "^5.3.4", + "ws": "^8.13.0" + }, + "bin": { + "webpack-dev-server": "bin/webpack-dev-server.js" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" }, "peerDependencies": { - "css-loader": "*", - "webpack": "^3.0.0 || ^4.1.0 || ^5.0.0-0" + "webpack": "^4.37.0 || ^5.0.0" }, "peerDependenciesMeta": { - "cache-loader": { - "optional": true - }, - "prettier": { + "webpack": { "optional": true }, - "vue-template-compiler": { + "webpack-cli": { "optional": true } } }, - "node_modules/vue-lodash": { - "version": "1.0.4", - "license": "AFL-2.0", - "peerDependencies": { - "vue": ">= 2.0.0" - } - }, - "node_modules/vue-router": { - "version": "3.6.5", - "license": "MIT" - }, - "node_modules/vue-style-loader": { - "version": "4.1.3", - "license": "MIT", - "dependencies": { - "hash-sum": "^1.0.2", - "loader-utils": "^1.0.2" - } - }, - "node_modules/vue-template-es2015-compiler": { - "version": "1.9.1", - "license": "MIT" - }, - "node_modules/vue-tsc": { - "version": "3.2.7", - "dev": true, + "node_modules/webpack-dev-server/node_modules/chokidar": { + "version": "3.6.0", "license": "MIT", "dependencies": { - "@volar/typescript": "2.4.28", - "@vue/language-core": "3.2.7" + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" }, - "bin": { - "vue-tsc": "bin/vue-tsc.js" + "engines": { + "node": ">= 8.10.0" }, - "peerDependencies": { - "typescript": ">=5.0.0" - } - }, - "node_modules/vue-tsc/node_modules/@vue/language-core": { - "version": "3.2.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@volar/language-core": "2.4.28", - "@vue/compiler-dom": "^3.5.0", - "@vue/shared": "^3.5.0", - "alien-signals": "^3.1.2", - "muggle-string": "^0.4.1", - "path-browserify": "^1.0.1", - "picomatch": "^4.0.4" + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" } }, - "node_modules/vue/node_modules/@vue/compiler-core": { - "version": "3.5.33", - "license": "MIT", + "node_modules/webpack-dev-server/node_modules/glob": { + "version": "7.2.3", + "license": "ISC", "dependencies": { - "@babel/parser": "^7.29.2", - "@vue/shared": "3.5.33", - "entities": "^7.0.1", - "estree-walker": "^2.0.2", - "source-map-js": "^1.2.1" + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/vue/node_modules/@vue/compiler-dom": { - "version": "3.5.33", - "license": "MIT", + "node_modules/webpack-dev-server/node_modules/rimraf": { + "version": "3.0.2", + "license": "ISC", "dependencies": { - "@vue/compiler-core": "3.5.33", - "@vue/shared": "3.5.33" + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/vue/node_modules/@vue/compiler-sfc": { - "version": "3.5.33", + "node_modules/webpack-manifest-plugin": { + "version": "5.0.1", "license": "MIT", "dependencies": { - "@babel/parser": "^7.29.2", - "@vue/compiler-core": "3.5.33", - "@vue/compiler-dom": "3.5.33", - "@vue/compiler-ssr": "3.5.33", - "@vue/shared": "3.5.33", - "estree-walker": "^2.0.2", - "magic-string": "^0.30.21", - "postcss": "^8.5.10", - "source-map-js": "^1.2.1" + "tapable": "^2.0.0", + "webpack-sources": "^2.2.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "webpack": "^5.75.0" } }, - "node_modules/vue/node_modules/@vue/compiler-ssr": { - "version": "3.5.33", + "node_modules/webpack-manifest-plugin/node_modules/webpack-sources": { + "version": "2.3.1", "license": "MIT", "dependencies": { - "@vue/compiler-dom": "3.5.33", - "@vue/shared": "3.5.33" - } - }, - "node_modules/vue/node_modules/@vue/shared": { - "version": "3.5.33", - "license": "MIT" - }, - "node_modules/vue/node_modules/entities": { - "version": "7.0.1", - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.12" + "source-list-map": "^2.0.1", + "source-map": "^0.6.1" }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" + "engines": { + "node": ">=10.13.0" } }, - "node_modules/vue/node_modules/estree-walker": { - "version": "2.0.2", - "license": "MIT" - }, - "node_modules/vuetable-2": { - "version": "1.7.5", + "node_modules/webpack-merge": { + "version": "5.10.0", "license": "MIT", "dependencies": { - "axios": "^0.15.3" + "clone-deep": "^4.0.1", + "flat": "^5.0.2", + "wildcard": "^2.0.0" }, "engines": { - "node": ">= 4.0.0", - "npm": ">= 3.0.0" + "node": ">=10.0.0" } }, - "node_modules/vuetable-2/node_modules/axios": { - "version": "0.15.3", + "node_modules/webpack-merge-and-include-globally": { + "version": "2.3.4", "license": "MIT", "dependencies": { - "follow-redirects": "1.0.0" + "es6-promisify": "^6.1.1", + "glob": "^7.1.6", + "rev-hash": "^3.0.0" + }, + "peerDependencies": { + "webpack": ">=1.0.0" } }, - "node_modules/vuetable-2/node_modules/debug": { - "version": "2.6.9", - "license": "MIT", + "node_modules/webpack-merge-and-include-globally/node_modules/glob": { + "version": "7.2.3", + "license": "ISC", "dependencies": { - "ms": "2.0.0" + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/vuetable-2/node_modules/follow-redirects": { - "version": "1.0.0", + "node_modules/webpack-sources": { + "version": "3.3.3", "license": "MIT", - "dependencies": { - "debug": "^2.2.0" + "engines": { + "node": ">=10.13.0" } }, - "node_modules/vuetable-2/node_modules/ms": { - "version": "2.0.0", + "node_modules/webpack-virtual-modules": { + "version": "0.6.2", + "dev": true, "license": "MIT" }, - "node_modules/vuex": { - "version": "3.6.2", - "license": "MIT", - "peerDependencies": { - "vue": "^2.0.0" - } - }, - "node_modules/watchpack": { - "version": "2.4.4", - "license": "MIT", + "node_modules/websocket-driver": { + "version": "0.7.4", + "license": "Apache-2.0", "dependencies": { - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.1.2" + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" }, "engines": { - "node": ">=10.13.0" + "node": ">=0.8.0" + } + }, + "node_modules/websocket-extensions": { + "version": "0.1.4", + "license": "Apache-2.0", + "engines": { + "node": ">=0.8.0" } }, - "node_modules/wbuf": { - "version": "1.7.3", + "node_modules/whatwg-mimetype": { + "version": "3.0.0", + "devOptional": true, "license": "MIT", - "dependencies": { - "minimalistic-assert": "^1.0.0" + "engines": { + "node": ">=12" } }, - "node_modules/wcwidth": { - "version": "1.0.1", + "node_modules/which": { + "version": "1.3.1", "dev": true, - "license": "MIT", + "license": "ISC", "dependencies": { - "defaults": "^1.0.3" + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" } }, - "node_modules/webpack": { - "version": "5.102.1", + "node_modules/which-boxed-primitive": { + "version": "1.1.1", + "dev": true, "license": "MIT", "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.3", - "browserslist": "^4.26.3", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.17.3", - "es-module-lexer": "^1.2.1", - "eslint-scope": "5.1.1", - "events": "^3.2.0", - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.11", - "json-parse-even-better-errors": "^2.3.1", - "loader-runner": "^4.2.0", - "mime-types": "^2.1.27", - "neo-async": "^2.6.2", - "schema-utils": "^4.3.3", - "tapable": "^2.3.0", - "terser-webpack-plugin": "^5.3.11", - "watchpack": "^2.4.4", - "webpack-sources": "^3.3.3" - }, - "bin": { - "webpack": "bin/webpack.js" + "is-bigint": "^1.1.0", + "is-boolean-object": "^1.2.1", + "is-number-object": "^1.1.1", + "is-string": "^1.1.1", + "is-symbol": "^1.1.1" }, "engines": { - "node": ">=10.13.0" + "node": ">= 0.4" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependenciesMeta": { - "webpack-cli": { - "optional": true - } + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/webpack-cli": { - "version": "5.1.4", + "node_modules/which-builtin-type": { + "version": "1.2.1", + "dev": true, "license": "MIT", "dependencies": { - "@discoveryjs/json-ext": "^0.5.0", - "@webpack-cli/configtest": "^2.1.1", - "@webpack-cli/info": "^2.0.2", - "@webpack-cli/serve": "^2.0.5", - "colorette": "^2.0.14", - "commander": "^10.0.1", - "cross-spawn": "^7.0.3", - "envinfo": "^7.7.3", - "fastest-levenshtein": "^1.0.12", - "import-local": "^3.0.2", - "interpret": "^3.1.1", - "rechoir": "^0.8.0", - "webpack-merge": "^5.7.3" - }, - "bin": { - "webpack-cli": "bin/cli.js" + "call-bound": "^1.0.2", + "function.prototype.name": "^1.1.6", + "has-tostringtag": "^1.0.2", + "is-async-function": "^2.0.0", + "is-date-object": "^1.1.0", + "is-finalizationregistry": "^1.1.0", + "is-generator-function": "^1.0.10", + "is-regex": "^1.2.1", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.1.0", + "which-collection": "^1.0.2", + "which-typed-array": "^1.1.16" }, "engines": { - "node": ">=14.15.0" + "node": ">= 0.4" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "5.x.x" - }, - "peerDependenciesMeta": { - "@webpack-cli/generators": { - "optional": true - }, - "webpack-bundle-analyzer": { - "optional": true - }, - "webpack-dev-server": { - "optional": true - } + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/webpack-cli/node_modules/commander": { - "version": "10.0.1", + "node_modules/which-collection": { + "version": "1.0.2", + "dev": true, "license": "MIT", + "dependencies": { + "is-map": "^2.0.3", + "is-set": "^2.0.3", + "is-weakmap": "^2.0.2", + "is-weakset": "^2.0.3" + }, "engines": { - "node": ">=14" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/webpack-cli/node_modules/cross-spawn": { - "version": "7.0.6", + "node_modules/which-typed-array": { + "version": "1.1.19", + "dev": true, "license": "MIT", "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "for-each": "^0.3.5", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2" }, "engines": { - "node": ">= 8" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/webpack-cli/node_modules/path-key": { - "version": "3.1.1", + "node_modules/why-is-node-running": { + "version": "2.3.0", "license": "MIT", + "dependencies": { + "siginfo": "^2.0.0", + "stackback": "0.0.2" + }, + "bin": { + "why-is-node-running": "cli.js" + }, "engines": { "node": ">=8" } }, - "node_modules/webpack-cli/node_modules/shebang-command": { - "version": "2.0.0", - "license": "MIT", + "node_modules/wide-align": { + "version": "1.1.5", + "license": "ISC", "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" + "string-width": "^1.0.2 || 2 || 3 || 4" } }, - "node_modules/webpack-cli/node_modules/shebang-regex": { - "version": "3.0.0", + "node_modules/wide-align/node_modules/ansi-regex": { + "version": "5.0.1", "license": "MIT", "engines": { "node": ">=8" } }, - "node_modules/webpack-cli/node_modules/which": { - "version": "2.0.2", - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/webpack-dev-middleware": { - "version": "5.3.4", + "node_modules/wide-align/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", "license": "MIT", - "dependencies": { - "colorette": "^2.0.10", - "memfs": "^3.4.3", - "mime-types": "^2.1.31", - "range-parser": "^1.2.1", - "schema-utils": "^4.0.0" - }, "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^4.0.0 || ^5.0.0" + "node": ">=8" } }, - "node_modules/webpack-dev-server": { - "version": "4.15.2", - "license": "MIT", - "dependencies": { - "@types/bonjour": "^3.5.9", - "@types/connect-history-api-fallback": "^1.3.5", - "@types/express": "^4.17.13", - "@types/serve-index": "^1.9.1", - "@types/serve-static": "^1.13.10", - "@types/sockjs": "^0.3.33", - "@types/ws": "^8.5.5", - "ansi-html-community": "^0.0.8", - "bonjour-service": "^1.0.11", - "chokidar": "^3.5.3", - "colorette": "^2.0.10", - "compression": "^1.7.4", - "connect-history-api-fallback": "^2.0.0", - "default-gateway": "^6.0.3", - "express": "^4.17.3", - "graceful-fs": "^4.2.6", - "html-entities": "^2.3.2", - "http-proxy-middleware": "^2.0.3", - "ipaddr.js": "^2.0.1", - "launch-editor": "^2.6.0", - "open": "^8.0.9", - "p-retry": "^4.5.0", - "rimraf": "^3.0.2", - "schema-utils": "^4.0.0", - "selfsigned": "^2.1.1", - "serve-index": "^1.9.1", - "sockjs": "^0.3.24", - "spdy": "^4.0.2", - "webpack-dev-middleware": "^5.3.4", - "ws": "^8.13.0" - }, - "bin": { - "webpack-dev-server": "bin/webpack-dev-server.js" + "node_modules/wide-align/node_modules/string-width": { + "version": "4.2.3", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" }, "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^4.37.0 || ^5.0.0" - }, - "peerDependenciesMeta": { - "webpack": { - "optional": true - }, - "webpack-cli": { - "optional": true - } + "node": ">=8" } }, - "node_modules/webpack-dev-server/node_modules/chokidar": { - "version": "3.6.0", + "node_modules/wide-align/node_modules/strip-ansi": { + "version": "6.0.1", "license": "MIT", "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" + "ansi-regex": "^5.0.1" }, "engines": { - "node": ">= 8.10.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" + "node": ">=8" + } + }, + "node_modules/wildcard": { + "version": "2.0.1", + "license": "MIT" + }, + "node_modules/with": { + "version": "7.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.9.6", + "@babel/types": "^7.9.6", + "assert-never": "^1.2.1", + "babel-walk": "3.0.0-canary-5" }, - "optionalDependencies": { - "fsevents": "~2.3.2" + "engines": { + "node": ">= 10.0.0" } }, - "node_modules/webpack-dev-server/node_modules/glob": { - "version": "7.2.3", - "license": "ISC", + "node_modules/word-wrap": { + "version": "1.2.5", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wordwrap": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/wrap-ansi": { + "version": "9.0.2", + "dev": true, + "license": "MIT", "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" }, "engines": { - "node": "*" + "node": ">=18" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/webpack-dev-server/node_modules/rimraf": { - "version": "3.0.2", - "license": "ISC", + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "license": "MIT", "dependencies": { - "glob": "^7.1.3" + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" }, - "bin": { - "rimraf": "bin.js" + "engines": { + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/webpack-manifest-plugin": { + "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { "version": "5.0.1", "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { + "version": "4.3.0", + "license": "MIT", "dependencies": { - "tapable": "^2.0.0", - "webpack-sources": "^2.2.0" + "color-convert": "^2.0.1" }, "engines": { - "node": ">=14" + "node": ">=8" }, - "peerDependencies": { - "webpack": "^5.75.0" + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/webpack-manifest-plugin/node_modules/webpack-sources": { - "version": "2.3.1", + "node_modules/wrap-ansi-cjs/node_modules/color-convert": { + "version": "2.0.1", "license": "MIT", "dependencies": { - "source-list-map": "^2.0.1", - "source-map": "^0.6.1" + "color-name": "~1.1.4" }, "engines": { - "node": ">=10.13.0" + "node": ">=7.0.0" } }, - "node_modules/webpack-merge": { - "version": "5.10.0", + "node_modules/wrap-ansi-cjs/node_modules/color-name": { + "version": "1.1.4", + "license": "MIT" + }, + "node_modules/wrap-ansi-cjs/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", "license": "MIT", - "dependencies": { - "clone-deep": "^4.0.1", - "flat": "^5.0.2", - "wildcard": "^2.0.0" - }, "engines": { - "node": ">=10.0.0" + "node": ">=8" } }, - "node_modules/webpack-merge-and-include-globally": { - "version": "2.3.4", + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", "license": "MIT", "dependencies": { - "es6-promisify": "^6.1.1", - "glob": "^7.1.6", - "rev-hash": "^3.0.0" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" }, - "peerDependencies": { - "webpack": ">=1.0.0" + "engines": { + "node": ">=8" } }, - "node_modules/webpack-merge-and-include-globally/node_modules/glob": { - "version": "7.2.3", - "license": "ISC", + "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "license": "MIT", "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "ansi-regex": "^5.0.1" }, "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": ">=8" } }, - "node_modules/webpack-sources": { - "version": "3.3.3", + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.3", + "dev": true, "license": "MIT", "engines": { - "node": ">=10.13.0" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/webpack-virtual-modules": { - "version": "0.6.2", + "node_modules/wrap-ansi/node_modules/emoji-regex": { + "version": "10.6.0", "dev": true, "license": "MIT" }, - "node_modules/websocket-driver": { - "version": "0.7.4", - "license": "Apache-2.0", + "node_modules/wrap-ansi/node_modules/string-width": { + "version": "7.2.0", + "dev": true, + "license": "MIT", "dependencies": { - "http-parser-js": ">=0.5.1", - "safe-buffer": ">=5.1.0", - "websocket-extensions": ">=0.1.1" + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" }, "engines": { - "node": ">=0.8.0" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/websocket-extensions": { - "version": "0.1.4", - "license": "Apache-2.0", + "node_modules/wrappy": { + "version": "1.0.2", + "license": "ISC" + }, + "node_modules/write-file-atomic": { + "version": "7.0.1", + "dev": true, + "license": "ISC", + "dependencies": { + "signal-exit": "^4.0.1" + }, "engines": { - "node": ">=0.8.0" + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/whatwg-mimetype": { - "version": "3.0.0", - "devOptional": true, + "node_modules/ws": { + "version": "8.20.0", "license": "MIT", "engines": { - "node": ">=12" - } - }, - "node_modules/which": { - "version": "1.3.1", - "dev": true, - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" + "node": ">=10.0.0" }, - "bin": { - "which": "bin/which" + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } } }, - "node_modules/which-boxed-primitive": { - "version": "1.1.1", - "dev": true, + "node_modules/wsl-utils": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/wsl-utils/-/wsl-utils-0.1.0.tgz", + "integrity": "sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw==", "license": "MIT", "dependencies": { - "is-bigint": "^1.1.0", - "is-boolean-object": "^1.2.1", - "is-number-object": "^1.1.1", - "is-string": "^1.1.1", - "is-symbol": "^1.1.1" + "is-wsl": "^3.1.0" }, "engines": { - "node": ">= 0.4" + "node": ">=18" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/which-builtin-type": { - "version": "1.2.1", - "dev": true, + "node_modules/wsl-utils/node_modules/is-wsl": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.1.tgz", + "integrity": "sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw==", "license": "MIT", "dependencies": { - "call-bound": "^1.0.2", - "function.prototype.name": "^1.1.6", - "has-tostringtag": "^1.0.2", - "is-async-function": "^2.0.0", - "is-date-object": "^1.1.0", - "is-finalizationregistry": "^1.1.0", - "is-generator-function": "^1.0.10", - "is-regex": "^1.2.1", - "is-weakref": "^1.0.2", - "isarray": "^2.0.5", - "which-boxed-primitive": "^1.1.0", - "which-collection": "^1.0.2", - "which-typed-array": "^1.1.16" + "is-inside-container": "^1.0.0" }, "engines": { - "node": ">= 0.4" + "node": ">=16" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/which-collection": { - "version": "1.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "is-map": "^2.0.3", - "is-set": "^2.0.3", - "is-weakmap": "^2.0.2", - "is-weakset": "^2.0.3" - }, + "node_modules/xml-name-validator": { + "version": "4.0.0", + "license": "Apache-2.0", "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=12" } }, - "node_modules/which-typed-array": { - "version": "1.1.19", - "dev": true, + "node_modules/xmldom": { + "version": "0.1.31", + "license": "(LGPL-2.0 or MIT)", + "optional": true, + "engines": { + "node": ">=0.1" + } + }, + "node_modules/xregexp": { + "version": "5.1.2", "license": "MIT", "dependencies": { - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.8", - "call-bound": "^1.0.4", - "for-each": "^0.3.5", - "get-proto": "^1.0.1", - "gopd": "^1.2.0", - "has-tostringtag": "^1.0.2" + "@babel/runtime-corejs3": "^7.26.9" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "license": "ISC" + }, + "node_modules/yaml": { + "version": "2.8.3", + "devOptional": true, + "license": "ISC", + "bin": { + "yaml": "bin.mjs" }, "engines": { - "node": ">= 0.4" + "node": ">= 14.6" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/eemeli" } }, - "node_modules/why-is-node-running": { - "version": "2.3.0", + "node_modules/yargs": { + "version": "16.2.0", + "dev": true, "license": "MIT", "dependencies": { - "siginfo": "^2.0.0", - "stackback": "0.0.2" - }, - "bin": { - "why-is-node-running": "cli.js" + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" }, "engines": { - "node": ">=8" + "node": ">=10" } }, - "node_modules/wide-align": { - "version": "1.1.5", + "node_modules/yargs-parser": { + "version": "20.2.9", + "dev": true, "license": "ISC", - "dependencies": { - "string-width": "^1.0.2 || 2 || 3 || 4" + "engines": { + "node": ">=10" } }, - "node_modules/wide-align/node_modules/ansi-regex": { + "node_modules/yargs/node_modules/ansi-regex": { "version": "5.0.1", + "dev": true, "license": "MIT", "engines": { "node": ">=8" } }, - "node_modules/wide-align/node_modules/is-fullwidth-code-point": { + "node_modules/yargs/node_modules/is-fullwidth-code-point": { "version": "3.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8" } }, - "node_modules/wide-align/node_modules/string-width": { + "node_modules/yargs/node_modules/string-width": { "version": "4.2.3", + "dev": true, "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", @@ -24150,8 +23612,9 @@ "node": ">=8" } }, - "node_modules/wide-align/node_modules/strip-ansi": { + "node_modules/yargs/node_modules/strip-ansi": { "version": "6.0.1", + "dev": true, "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" @@ -24160,352 +23623,445 @@ "node": ">=8" } }, - "node_modules/wildcard": { - "version": "2.0.1", - "license": "MIT" + "node_modules/yii2-pjax": { + "version": "2.0.8" }, - "node_modules/with": { - "version": "7.0.2", + "node_modules/yocto-queue": { + "version": "0.1.0", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yoctocolors": { + "version": "2.1.2", "dev": true, "license": "MIT", - "dependencies": { - "@babel/parser": "^7.9.6", - "@babel/types": "^7.9.6", - "assert-never": "^1.2.1", - "babel-walk": "3.0.0-canary-5" + "engines": { + "node": ">=18" }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yoctocolors-cjs": { + "version": "2.1.3", + "dev": true, + "license": "MIT", "engines": { - "node": ">= 10.0.0" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/word-wrap": { - "version": "1.2.5", + "node_modules/zustand": { + "version": "5.0.12", "license": "MIT", - "peer": true, "engines": { - "node": ">=0.10.0" + "node": ">=12.20.0" + }, + "peerDependencies": { + "@types/react": ">=18.0.0", + "immer": ">=9.0.6", + "react": ">=18.0.0", + "use-sync-external-store": ">=1.2.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "immer": { + "optional": true + }, + "react": { + "optional": true + }, + "use-sync-external-store": { + "optional": true + } } }, - "node_modules/wordwrap": { - "version": "1.0.0", - "dev": true, + "packages/craftcms-browserslist-config": { + "name": "@craftcms/browserslist-config", + "version": "2.0.0", "license": "MIT" }, - "node_modules/wrap-ansi": { - "version": "9.0.2", - "dev": true, + "packages/craftcms-cp": { + "name": "@craftcms/cp", + "version": "0.0.0", "license": "MIT", "dependencies": { - "ansi-styles": "^6.2.1", - "string-width": "^7.0.0", - "strip-ansi": "^7.1.0" + "@chromatic-com/storybook": "^5.1.2", + "@formatjs/intl-durationformat": "^0.10.8", + "@github/relative-time-element": "^5.0.0", + "@simplewebauthn/browser": "^13.3.0", + "@vitest/browser-playwright": "^4.1.5", + "axios": "^1.17.0" }, - "engines": { - "node": ">=18" + "devDependencies": { + "@adobe/leonardo-contrast-colors": "^1.1.0", + "@arethetypeswrong/cli": "^0.18.2", + "@awesome.me/webawesome": "^3.6.0", + "@custom-elements-manifest/analyzer": "^0.11.0", + "@lion/ui": "^0.16.1", + "@shoelace-style/shoelace": "^2.20.1", + "@storybook/addon-a11y": "^10.4.1", + "@storybook/addon-docs": "^10.4.1", + "@storybook/addon-themes": "^10.4.1", + "@storybook/addon-vitest": "^10.4.1", + "@storybook/web-components-vite": "^10.4.1", + "@total-typescript/tsconfig": "^1.0.4", + "@types/humanize-duration": "^3.27.4", + "@types/jquery": "^4.0.0", + "@types/node": "^25.6.0", + "@vitest/browser": "^4.1.5", + "@vitest/coverage-v8": "^4.1.5", + "@wc-toolkit/storybook-helpers": "^10.3.0", + "del": "^8.0.1", + "dom-accessibility-api": "^0.7.1", + "esbuild": "^0.28.0", + "globby": "^16.2.0", + "happy-dom": "^20.9.0", + "humanize-duration": "^3.33.2", + "lit": "^3.3.2", + "ora": "^9.4.0", + "playwright": "^1.59.1", + "plop": "^4.0.5", + "recursive-copy": "^2.0.14", + "rimraf": "^6.1.3", + "storybook": "^10.4.1", + "tsdown": "^0.21.10", + "typescript": "^6.0.3", + "unplugin-dts": "^1.0.0", + "vite-plugin-dts": "^5.0.0", + "vite-tsconfig-paths": "^6.1.1", + "vitest": "^4.1.5" }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + "peerDependencies": { + "@awesome.me/webawesome": "^3.0.0", + "@lion/ui": "0.x", + "lit": "3.x" } }, - "node_modules/wrap-ansi-cjs": { - "name": "wrap-ansi", - "version": "7.0.0", + "packages/craftcms-cp/node_modules/@babel/generator": { + "version": "8.0.0-rc.3", + "dev": true, "license": "MIT", "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" + "@babel/parser": "^8.0.0-rc.3", + "@babel/types": "^8.0.0-rc.3", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "@types/jsesc": "^2.5.0", + "jsesc": "^3.0.2" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { - "version": "5.0.1", + "packages/craftcms-cp/node_modules/@babel/generator/node_modules/@babel/helper-validator-identifier": { + "version": "8.0.0-rc.4", + "dev": true, "license": "MIT", "engines": { - "node": ">=8" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { - "version": "4.3.0", + "packages/craftcms-cp/node_modules/@babel/generator/node_modules/@babel/parser": { + "version": "8.0.0-rc.4", + "dev": true, "license": "MIT", "dependencies": { - "color-convert": "^2.0.1" + "@babel/types": "^8.0.0-rc.4" }, - "engines": { - "node": ">=8" + "bin": { + "parser": "bin/babel-parser.js" }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "engines": { + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/wrap-ansi-cjs/node_modules/color-convert": { - "version": "2.0.1", + "packages/craftcms-cp/node_modules/@babel/generator/node_modules/@babel/types": { + "version": "8.0.0-rc.4", + "dev": true, "license": "MIT", "dependencies": { - "color-name": "~1.1.4" + "@babel/helper-string-parser": "^8.0.0-rc.4", + "@babel/helper-validator-identifier": "^8.0.0-rc.4" }, "engines": { - "node": ">=7.0.0" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/wrap-ansi-cjs/node_modules/color-name": { - "version": "1.1.4", - "license": "MIT" - }, - "node_modules/wrap-ansi-cjs/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", + "packages/craftcms-cp/node_modules/@babel/helper-string-parser": { + "version": "8.0.0-rc.4", + "dev": true, "license": "MIT", "engines": { - "node": ">=8" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/wrap-ansi-cjs/node_modules/string-width": { - "version": "4.2.3", + "packages/craftcms-cp/node_modules/@babel/helper-validator-identifier": { + "version": "8.0.0-rc.3", + "dev": true, "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, "engines": { - "node": ">=8" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { - "version": "6.0.1", + "packages/craftcms-cp/node_modules/@rolldown/binding-darwin-arm64": { + "version": "1.0.0-rc.17", + "cpu": [ + "arm64" + ], + "dev": true, "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">=8" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/wrap-ansi/node_modules/ansi-styles": { - "version": "6.2.3", + "packages/craftcms-cp/node_modules/@rolldown/pluginutils": { + "version": "1.0.0-rc.17", "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } + "license": "MIT" }, - "node_modules/wrap-ansi/node_modules/emoji-regex": { - "version": "10.6.0", + "packages/craftcms-cp/node_modules/@types/jquery": { + "version": "4.0.0", "dev": true, "license": "MIT" }, - "node_modules/wrap-ansi/node_modules/string-width": { - "version": "7.2.0", + "packages/craftcms-cp/node_modules/@vitest/coverage-v8": { + "version": "4.1.5", "dev": true, "license": "MIT", "dependencies": { - "emoji-regex": "^10.3.0", - "get-east-asian-width": "^1.0.0", - "strip-ansi": "^7.1.0" - }, - "engines": { - "node": ">=18" + "@bcoe/v8-coverage": "^1.0.2", + "@vitest/utils": "4.1.5", + "ast-v8-to-istanbul": "^1.0.0", + "istanbul-lib-coverage": "^3.2.2", + "istanbul-lib-report": "^3.0.1", + "istanbul-reports": "^3.2.0", + "magicast": "^0.5.2", + "obug": "^2.1.1", + "std-env": "^4.0.0-rc.1", + "tinyrainbow": "^3.1.0" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "license": "ISC" - }, - "node_modules/write-file-atomic": { - "version": "7.0.1", - "dev": true, - "license": "ISC", - "dependencies": { - "signal-exit": "^4.0.1" - }, - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, - "node_modules/ws": { - "version": "8.21.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.0.tgz", - "integrity": "sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==", - "license": "MIT", - "engines": { - "node": ">=10.0.0" + "url": "https://opencollective.com/vitest" }, "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" + "@vitest/browser": "4.1.5", + "vitest": "4.1.5" }, "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { + "@vitest/browser": { "optional": true } } }, - "node_modules/wsl-utils": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/wsl-utils/-/wsl-utils-0.1.0.tgz", - "integrity": "sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw==", + "packages/craftcms-cp/node_modules/@vitest/pretty-format": { + "version": "4.1.5", + "dev": true, "license": "MIT", "dependencies": { - "is-wsl": "^3.1.0" - }, - "engines": { - "node": ">=18" + "tinyrainbow": "^3.1.0" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://opencollective.com/vitest" } }, - "node_modules/wsl-utils/node_modules/is-wsl": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.1.tgz", - "integrity": "sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw==", + "packages/craftcms-cp/node_modules/@vitest/utils": { + "version": "4.1.5", + "dev": true, "license": "MIT", "dependencies": { - "is-inside-container": "^1.0.0" - }, - "engines": { - "node": ">=16" + "@vitest/pretty-format": "4.1.5", + "convert-source-map": "^2.0.0", + "tinyrainbow": "^3.1.0" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://opencollective.com/vitest" } }, - "node_modules/xmldom": { - "version": "0.1.31", - "license": "(LGPL-2.0 or MIT)", - "optional": true, - "engines": { - "node": ">=0.1" + "packages/craftcms-cp/node_modules/@wc-toolkit/storybook-helpers": { + "version": "10.3.0", + "dev": true, + "license": "MIT", + "peerDependencies": { + "lit": "^2.0.0 || ^3.0.0", + "storybook": ">=10.1.11-0 <11.0.0-0" } }, - "node_modules/xregexp": { - "version": "5.1.2", + "packages/craftcms-cp/node_modules/ast-kit": { + "version": "3.0.0-beta.1", + "dev": true, "license": "MIT", "dependencies": { - "@babel/runtime-corejs3": "^7.26.9" + "@babel/parser": "^8.0.0-beta.4", + "estree-walker": "^3.0.3", + "pathe": "^2.0.3" + }, + "engines": { + "node": ">=20.19.0" + }, + "funding": { + "url": "https://github.com/sponsors/sxzz" } }, - "node_modules/y18n": { - "version": "5.0.8", - "license": "ISC", + "packages/craftcms-cp/node_modules/ast-kit/node_modules/@babel/helper-validator-identifier": { + "version": "8.0.0-rc.4", + "dev": true, + "license": "MIT", "engines": { - "node": ">=10" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/yallist": { - "version": "3.1.1", - "license": "ISC" - }, - "node_modules/yaml": { - "version": "2.8.3", - "devOptional": true, - "license": "ISC", + "packages/craftcms-cp/node_modules/ast-kit/node_modules/@babel/parser": { + "version": "8.0.0-rc.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^8.0.0-rc.4" + }, "bin": { - "yaml": "bin.mjs" + "parser": "bin/babel-parser.js" }, "engines": { - "node": ">= 14.6" - }, - "funding": { - "url": "https://github.com/sponsors/eemeli" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/yargs": { - "version": "16.2.0", + "packages/craftcms-cp/node_modules/ast-kit/node_modules/@babel/types": { + "version": "8.0.0-rc.4", "dev": true, "license": "MIT", "dependencies": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" + "@babel/helper-string-parser": "^8.0.0-rc.4", + "@babel/helper-validator-identifier": "^8.0.0-rc.4" }, "engines": { - "node": ">=10" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/yargs-parser": { - "version": "20.2.9", + "packages/craftcms-cp/node_modules/ast-v8-to-istanbul": { + "version": "1.0.0", "dev": true, - "license": "ISC", + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.31", + "estree-walker": "^3.0.3", + "js-tokens": "^10.0.0" + } + }, + "packages/craftcms-cp/node_modules/balanced-match": { + "version": "4.0.4", + "dev": true, + "license": "MIT", "engines": { - "node": ">=10" + "node": "18 || 20 || >=22" } }, - "node_modules/yargs/node_modules/ansi-regex": { - "version": "5.0.1", + "packages/craftcms-cp/node_modules/brace-expansion": { + "version": "5.0.5", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, + "packages/craftcms-cp/node_modules/cac": { + "version": "7.0.0", "dev": true, "license": "MIT", "engines": { - "node": ">=8" + "node": ">=20.19.0" } }, - "node_modules/yargs/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", + "packages/craftcms-cp/node_modules/chalk": { + "version": "5.6.2", "dev": true, "license": "MIT", "engines": { - "node": ">=8" + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/yargs/node_modules/string-width": { - "version": "4.2.3", + "packages/craftcms-cp/node_modules/cli-spinners": { + "version": "3.3.0", "dev": true, "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, "engines": { - "node": ">=8" + "node": ">=18.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/yargs/node_modules/strip-ansi": { - "version": "6.0.1", + "packages/craftcms-cp/node_modules/del": { + "version": "8.0.1", "dev": true, "license": "MIT", "dependencies": { - "ansi-regex": "^5.0.1" + "globby": "^14.0.2", + "is-glob": "^4.0.3", + "is-path-cwd": "^3.0.0", + "is-path-inside": "^4.0.0", + "p-map": "^7.0.2", + "presentable-error": "^0.0.1", + "slash": "^5.1.0" }, "engines": { - "node": ">=8" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/yii2-pjax": { - "version": "2.0.8" + "packages/craftcms-cp/node_modules/dom-accessibility-api": { + "version": "0.7.1", + "dev": true, + "license": "MIT" }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "license": "MIT", + "packages/craftcms-cp/node_modules/glob": { + "version": "13.0.6", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "minimatch": "^10.2.2", + "minipass": "^7.1.3", + "path-scurry": "^2.0.2" + }, "engines": { - "node": ">=10" + "node": "18 || 20 || >=22" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/yoctocolors": { - "version": "2.1.2", + "packages/craftcms-cp/node_modules/globby": { + "version": "14.1.0", "dev": true, "license": "MIT", + "dependencies": { + "@sindresorhus/merge-streams": "^2.1.0", + "fast-glob": "^3.3.3", + "ignore": "^7.0.3", + "path-type": "^6.0.0", + "slash": "^5.1.0", + "unicorn-magic": "^0.3.0" + }, "engines": { "node": ">=18" }, @@ -24513,1056 +24069,978 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/yoctocolors-cjs": { - "version": "2.1.3", + "packages/craftcms-cp/node_modules/hookable": { + "version": "6.1.1", + "dev": true, + "license": "MIT" + }, + "packages/craftcms-cp/node_modules/is-interactive": { + "version": "2.0.0", "dev": true, "license": "MIT", "engines": { - "node": ">=18" + "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/yuku-codegen": { - "version": "0.5.48", - "resolved": "https://registry.npmjs.org/yuku-codegen/-/yuku-codegen-0.5.48.tgz", - "integrity": "sha512-p7HxD5Xl4jzDzqMrGePAOeSHmRY4g58h4HuGq15weQFPxuPWd/W6e7nqp/+Lea6JfpOdBwJOAyXFqIZ/J9Zfnw==", + "packages/craftcms-cp/node_modules/is-path-cwd": { + "version": "3.0.0", + "dev": true, "license": "MIT", - "dependencies": { - "@yuku-toolchain/types": "0.5.43" + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, - "optionalDependencies": { - "@yuku-codegen/binding-darwin-arm64": "0.5.48", - "@yuku-codegen/binding-darwin-x64": "0.5.48", - "@yuku-codegen/binding-freebsd-x64": "0.5.48", - "@yuku-codegen/binding-linux-arm-gnu": "0.5.48", - "@yuku-codegen/binding-linux-arm-musl": "0.5.48", - "@yuku-codegen/binding-linux-arm64-gnu": "0.5.48", - "@yuku-codegen/binding-linux-arm64-musl": "0.5.48", - "@yuku-codegen/binding-linux-x64-gnu": "0.5.48", - "@yuku-codegen/binding-linux-x64-musl": "0.5.48", - "@yuku-codegen/binding-win32-arm64": "0.5.48", - "@yuku-codegen/binding-win32-x64": "0.5.48" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/yuku-parser": { - "version": "0.5.48", - "resolved": "https://registry.npmjs.org/yuku-parser/-/yuku-parser-0.5.48.tgz", - "integrity": "sha512-OWBfhrpgK9+/4+IXG9oT8Bao4AhViQA7vdyNNH7EUg8dQYgwa70XtIBWTpCEme1P1ECyoDNYkn0wT63f8XRcVA==", + "packages/craftcms-cp/node_modules/is-path-inside": { + "version": "4.0.0", + "dev": true, "license": "MIT", - "dependencies": { - "@yuku-toolchain/types": "0.5.43" + "engines": { + "node": ">=12" }, - "optionalDependencies": { - "@yuku-parser/binding-darwin-arm64": "0.5.48", - "@yuku-parser/binding-darwin-x64": "0.5.48", - "@yuku-parser/binding-freebsd-x64": "0.5.48", - "@yuku-parser/binding-linux-arm-gnu": "0.5.48", - "@yuku-parser/binding-linux-arm-musl": "0.5.48", - "@yuku-parser/binding-linux-arm64-gnu": "0.5.48", - "@yuku-parser/binding-linux-arm64-musl": "0.5.48", - "@yuku-parser/binding-linux-x64-gnu": "0.5.48", - "@yuku-parser/binding-linux-x64-musl": "0.5.48", - "@yuku-parser/binding-win32-arm64": "0.5.48", - "@yuku-parser/binding-win32-x64": "0.5.48" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/zustand": { - "version": "5.0.12", + "packages/craftcms-cp/node_modules/is-unicode-supported": { + "version": "2.1.0", + "dev": true, "license": "MIT", "engines": { - "node": ">=12.20.0" - }, - "peerDependencies": { - "@types/react": ">=18.0.0", - "immer": ">=9.0.6", - "react": ">=18.0.0", - "use-sync-external-store": ">=1.2.0" + "node": ">=18" }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "immer": { - "optional": true - }, - "react": { - "optional": true - }, - "use-sync-external-store": { - "optional": true - } + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "packages/craftcms-browserslist-config": { - "name": "@craftcms/browserslist-config", - "version": "2.0.0", + "packages/craftcms-cp/node_modules/js-tokens": { + "version": "10.0.0", + "dev": true, "license": "MIT" }, - "packages/craftcms-garnish": { - "name": "@craftcms/garnish", - "version": "0.0.0", + "packages/craftcms-cp/node_modules/log-symbols": { + "version": "7.0.1", + "dev": true, "license": "MIT", - "devDependencies": { - "@storybook/addon-a11y": "^10.5.5", - "@storybook/addon-docs": "^10.5.5", - "@storybook/addon-themes": "^10.5.5", - "@storybook/html-vite": "^10.5.5", - "@total-typescript/tsconfig": "^1.0.4", - "@types/node": "^25.6.0", - "@vitest/coverage-v8": "4.1.10", - "happy-dom": "^20.9.0", - "storybook": "^10.5.5", - "typescript": "^6.0.3", - "vite": "npm:@voidzero-dev/vite-plus-core@0.2.6", - "vite-plus": "0.2.6", - "vitest": "4.1.10" + "dependencies": { + "is-unicode-supported": "^2.0.0", + "yoctocolors": "^2.1.1" }, - "peerDependencies": { - "jquery": "^3.5.0" + "engines": { + "node": ">=18" }, - "peerDependenciesMeta": { - "jquery": { - "optional": true - } + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "packages/craftcms-graphiql": { - "name": "@craftcms/graphiql", - "version": "1.0.0", + "packages/craftcms-cp/node_modules/magicast": { + "version": "0.5.2", + "dev": true, "license": "MIT", "dependencies": { - "graphiql": "^4.1.0", - "graphql": "^16.10.0", - "graphql-ws": "^6.0.4", - "react": "^19.2.0", - "react-dom": "^19.2.0" - }, - "devDependencies": { - "@craftcms/sass": "file:../craftcms-sass", - "@craftcms/webpack": "file:../craftcms-webpack" + "@babel/parser": "^7.29.0", + "@babel/types": "^7.29.0", + "source-map-js": "^1.2.1" + } + }, + "packages/craftcms-cp/node_modules/minimatch": { + "version": "10.2.5", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.5" }, "engines": { - "node": ">=20" + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "packages/craftcms-legacy": { - "name": "@craftcms/legacy", + "packages/craftcms-cp/node_modules/ora": { + "version": "9.4.0", + "dev": true, + "license": "MIT", "dependencies": { - "@benmajor/jquery-touch-events": "^2.0.3", - "@craftcms/sass": "file:../craftcms-sass", - "@craftcms/ui": "file:../craftcms-ui", - "@craftcms/vue": "file:../craftcms-vue", - "@floating-ui/dom": "^1.7.6", - "@selectize/selectize": "git+https://github.com/selectize/selectize.js.git#e6ca6d3ba8f902c38da157f2caf7962c38e82095", - "@simplewebauthn/browser": "^13.3.0", - "@types/jquery": "^3.5.34", - "accounting": "^0.4.1", - "apexcharts": "^5.10.6", - "axios": "^1.17.0", - "blueimp-file-upload": "^10.32.0", - "codemirror": "^5.65.21", - "d3": "^7.9.0", - "fabric": "^1.7.22", - "htmx.org": "^1.9.12", - "iframe-resizer": "^4.4.5", - "inputmask": "^5.0.9", - "jquery": "^3.7.1", - "jquery-ui": "^1.14.2", - "jquery.payment": "^3.0.0", - "picturefill": "^3.0.3", - "punycode": "^2.3.1", - "swiper": "^8.4.7", - "timepicker": "^1.14.1", - "ttf2woff2": "^5.0.0", - "typescript": "^5.9.3", - "v-tooltip": "^2.1.3", - "velocity-animate": "^1.5.2", - "vue": "^2.7.16", - "vue-autosuggest": "^2.2.0", - "vue-awesome-swiper": "^4.1.1", - "vue-cleave": "^1.2.2", - "vue-lodash": "^1.0.4", - "vue-router": "^3.6.5", - "vuex": "^3.6.2", - "xregexp": "^5.1.2", - "yii2-pjax": "~2.0.8" - }, - "devDependencies": { - "@craftcms/playwright": "file:../craftcms-playwright", - "@craftcms/webpack": "file:../craftcms-webpack", - "@playwright/test": "^1.59.1", - "husky": "^9.1.7", - "lint-staged": "^16.4.0", - "pkg-dir": "^5.0.0", - "stylelint": "^16.26.1", - "stylelint-config-standard": "^36.0.1", - "stylelint-config-standard-scss": "^13.1.0", - "stylelint-prettier": "^5.0.3", - "stylelint-use-logical-spec": "^5.0.1", - "tailwindcss": "^3.4.19", - "vue-apexcharts": "^1.7.0" + "chalk": "^5.6.2", + "cli-cursor": "^5.0.0", + "cli-spinners": "^3.2.0", + "is-interactive": "^2.0.0", + "is-unicode-supported": "^2.1.0", + "log-symbols": "^7.0.1", + "stdin-discarder": "^0.3.2", + "string-width": "^8.1.0" }, "engines": { "node": ">=20" }, - "optionalDependencies": { - "@awesome.me/kit-ddaed3f5c5": "^1.0.74" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "packages/craftcms-legacy/node_modules/@csstools/css-parser-algorithms": { - "version": "3.0.5", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], + "packages/craftcms-cp/node_modules/p-map": { + "version": "7.0.4", + "dev": true, "license": "MIT", "engines": { "node": ">=18" }, - "peerDependencies": { - "@csstools/css-tokenizer": "^3.0.4" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "packages/craftcms-legacy/node_modules/@csstools/css-tokenizer": { - "version": "3.0.4", + "packages/craftcms-cp/node_modules/path-scurry": { + "version": "2.0.2", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT", + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" + }, "engines": { - "node": ">=18" + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "packages/craftcms-legacy/node_modules/@csstools/media-query-list-parser": { - "version": "4.0.3", + "packages/craftcms-cp/node_modules/path-type": { + "version": "6.0.0", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], "license": "MIT", "engines": { "node": ">=18" }, - "peerDependencies": { - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "packages/craftcms-legacy/node_modules/@vue/compiler-sfc": { - "version": "2.7.16", + "packages/craftcms-cp/node_modules/rimraf": { + "version": "6.1.3", + "dev": true, + "license": "BlueOak-1.0.0", "dependencies": { - "@babel/parser": "^7.23.5", - "postcss": "^8.4.14", - "source-map": "^0.6.1" + "glob": "^13.0.3", + "package-json-from-dist": "^1.0.1" }, - "optionalDependencies": { - "prettier": "^1.18.2 || ^2.0.0" - } - }, - "packages/craftcms-legacy/node_modules/@vue/compiler-sfc/node_modules/prettier": { - "version": "2.8.8", - "license": "MIT", - "optional": true, "bin": { - "prettier": "bin-prettier.js" + "rimraf": "dist/esm/bin.mjs" }, "engines": { - "node": ">=10.13.0" + "node": "20 || >=22" }, "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" + "url": "https://github.com/sponsors/isaacs" } }, - "packages/craftcms-legacy/node_modules/ansi-regex": { - "version": "5.0.1", + "packages/craftcms-cp/node_modules/rolldown": { + "version": "1.0.0-rc.17", "dev": true, "license": "MIT", + "dependencies": { + "@oxc-project/types": "=0.127.0", + "@rolldown/pluginutils": "1.0.0-rc.17" + }, + "bin": { + "rolldown": "bin/cli.mjs" + }, "engines": { - "node": ">=8" + "node": "^20.19.0 || >=22.12.0" + }, + "optionalDependencies": { + "@rolldown/binding-android-arm64": "1.0.0-rc.17", + "@rolldown/binding-darwin-arm64": "1.0.0-rc.17", + "@rolldown/binding-darwin-x64": "1.0.0-rc.17", + "@rolldown/binding-freebsd-x64": "1.0.0-rc.17", + "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-rc.17", + "@rolldown/binding-linux-arm64-gnu": "1.0.0-rc.17", + "@rolldown/binding-linux-arm64-musl": "1.0.0-rc.17", + "@rolldown/binding-linux-ppc64-gnu": "1.0.0-rc.17", + "@rolldown/binding-linux-s390x-gnu": "1.0.0-rc.17", + "@rolldown/binding-linux-x64-gnu": "1.0.0-rc.17", + "@rolldown/binding-linux-x64-musl": "1.0.0-rc.17", + "@rolldown/binding-openharmony-arm64": "1.0.0-rc.17", + "@rolldown/binding-wasm32-wasi": "1.0.0-rc.17", + "@rolldown/binding-win32-arm64-msvc": "1.0.0-rc.17", + "@rolldown/binding-win32-x64-msvc": "1.0.0-rc.17" + } + }, + "packages/craftcms-cp/node_modules/rolldown-plugin-dts": { + "version": "0.23.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/generator": "8.0.0-rc.3", + "@babel/helper-validator-identifier": "8.0.0-rc.3", + "@babel/parser": "8.0.0-rc.3", + "@babel/types": "8.0.0-rc.3", + "ast-kit": "^3.0.0-beta.1", + "birpc": "^4.0.0", + "dts-resolver": "^2.1.3", + "get-tsconfig": "^4.13.7", + "obug": "^2.1.1", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">=20.19.0" + }, + "funding": { + "url": "https://github.com/sponsors/sxzz" + }, + "peerDependencies": { + "@ts-macro/tsc": "^0.3.6", + "@typescript/native-preview": ">=7.0.0-dev.20260325.1", + "rolldown": "^1.0.0-rc.12", + "typescript": "^5.0.0 || ^6.0.0", + "vue-tsc": "~3.2.0" + }, + "peerDependenciesMeta": { + "@ts-macro/tsc": { + "optional": true + }, + "@typescript/native-preview": { + "optional": true + }, + "typescript": { + "optional": true + }, + "vue-tsc": { + "optional": true + } } }, - "packages/craftcms-legacy/node_modules/balanced-match": { - "version": "2.0.0", - "dev": true, - "license": "MIT" - }, - "packages/craftcms-legacy/node_modules/chokidar": { - "version": "3.6.0", + "packages/craftcms-cp/node_modules/rolldown-plugin-dts/node_modules/@babel/parser": { + "version": "8.0.0-rc.3", "dev": true, "license": "MIT", "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" + "@babel/types": "^8.0.0-rc.3" }, - "funding": { - "url": "https://paulmillr.com/funding/" + "bin": { + "parser": "bin/babel-parser.js" }, - "optionalDependencies": { - "fsevents": "~2.3.2" + "engines": { + "node": "^20.19.0 || >=22.12.0" } }, - "packages/craftcms-legacy/node_modules/globby": { - "version": "11.1.0", + "packages/craftcms-cp/node_modules/rolldown-plugin-dts/node_modules/@babel/types": { + "version": "8.0.0-rc.3", "dev": true, "license": "MIT", "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" + "@babel/helper-string-parser": "^8.0.0-rc.3", + "@babel/helper-validator-identifier": "^8.0.0-rc.3" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": "^20.19.0 || >=22.12.0" } }, - "packages/craftcms-legacy/node_modules/globby/node_modules/ignore": { - "version": "5.3.2", + "packages/craftcms-cp/node_modules/semver": { + "version": "7.7.4", "dev": true, - "license": "MIT", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, "engines": { - "node": ">= 4" + "node": ">=10" } }, - "packages/craftcms-legacy/node_modules/html-tags": { - "version": "3.3.1", + "packages/craftcms-cp/node_modules/slash": { + "version": "5.1.0", "dev": true, "license": "MIT", "engines": { - "node": ">=8" + "node": ">=14.16" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "packages/craftcms-legacy/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", + "packages/craftcms-cp/node_modules/tinyrainbow": { + "version": "3.1.0", "dev": true, "license": "MIT", "engines": { - "node": ">=8" + "node": ">=14.0.0" } }, - "packages/craftcms-legacy/node_modules/jiti": { - "version": "1.21.7", + "packages/craftcms-cp/node_modules/tsdown": { + "version": "0.21.10", "dev": true, "license": "MIT", + "dependencies": { + "ansis": "^4.2.0", + "cac": "^7.0.0", + "defu": "^6.1.7", + "empathic": "^2.0.0", + "hookable": "^6.1.1", + "import-without-cache": "^0.3.3", + "obug": "^2.1.1", + "picomatch": "^4.0.4", + "rolldown": "1.0.0-rc.17", + "rolldown-plugin-dts": "^0.23.2", + "semver": "^7.7.4", + "tinyexec": "^1.1.1", + "tinyglobby": "^0.2.16", + "tree-kill": "^1.2.2", + "unconfig-core": "^7.5.0", + "unrun": "^0.2.37" + }, "bin": { - "jiti": "bin/jiti.js" - } - }, - "packages/craftcms-legacy/node_modules/mathml-tag-names": { - "version": "2.1.3", - "dev": true, - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "packages/craftcms-legacy/node_modules/meow": { - "version": "13.2.0", - "dev": true, - "license": "MIT", + "tsdown": "dist/run.mjs" + }, "engines": { - "node": ">=18" + "node": ">=20.19.0" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/sxzz" + }, + "peerDependencies": { + "@arethetypeswrong/core": "^0.18.1", + "@tsdown/css": "0.21.10", + "@tsdown/exe": "0.21.10", + "@vitejs/devtools": "*", + "publint": "^0.3.0", + "typescript": "^5.0.0 || ^6.0.0", + "unplugin-unused": "^0.5.0" + }, + "peerDependenciesMeta": { + "@arethetypeswrong/core": { + "optional": true + }, + "@tsdown/css": { + "optional": true + }, + "@tsdown/exe": { + "optional": true + }, + "@vitejs/devtools": { + "optional": true + }, + "publint": { + "optional": true + }, + "typescript": { + "optional": true + }, + "unplugin-unused": { + "optional": true + } } }, - "packages/craftcms-legacy/node_modules/pkg-dir": { - "version": "5.0.0", - "dev": true, + "packages/craftcms-graphiql": { + "name": "@craftcms/graphiql", + "version": "1.0.0", "license": "MIT", "dependencies": { - "find-up": "^5.0.0" + "graphiql": "^4.1.0", + "graphql": "^16.10.0", + "graphql-ws": "^6.0.4", + "react": "^19.2.0", + "react-dom": "^19.2.0" + }, + "devDependencies": { + "@craftcms/sass": "file:../craftcms-sass", + "@craftcms/webpack": "file:../craftcms-webpack" }, "engines": { - "node": ">=10" + "node": ">=20" } }, - "packages/craftcms-legacy/node_modules/postcss-selector-parser": { - "version": "7.1.1", - "dev": true, - "license": "MIT", + "packages/craftcms-legacy": { + "name": "@craftcms/legacy", "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" + "@benmajor/jquery-touch-events": "^2.0.3", + "@craftcms/cp": "file:../craftcms-cp", + "@craftcms/graphiql": "file:../craftcms-graphiql", + "@craftcms/sass": "file:../craftcms-sass", + "@craftcms/vue": "file:../craftcms-vue", + "@floating-ui/dom": "^1.7.6", + "@selectize/selectize": "selectize/selectize.js#master", + "@simplewebauthn/browser": "^13.3.0", + "@types/jquery": "^3.5.34", + "accounting": "^0.4.1", + "apexcharts": "^5.10.6", + "axios": "^1.17.0", + "blueimp-file-upload": "^10.32.0", + "codemirror": "^5.65.21", + "d3": "^7.9.0", + "fabric": "^1.7.22", + "htmx.org": "^1.9.12", + "iframe-resizer": "^4.4.5", + "inputmask": "^5.0.9", + "jquery": "^3.7.1", + "jquery-ui": "^1.14.2", + "jquery.payment": "^3.0.0", + "picturefill": "^3.0.3", + "punycode": "^2.3.1", + "swiper": "^8.4.7", + "timepicker": "^1.14.1", + "ttf2woff2": "^5.0.0", + "typescript": "^5.9.3", + "v-tooltip": "^2.1.3", + "velocity-animate": "^1.5.2", + "vue": "^2.7.16", + "vue-autosuggest": "^2.2.0", + "vue-awesome-swiper": "^4.1.1", + "vue-cleave": "^1.2.2", + "vue-lodash": "^1.0.4", + "vue-router": "^3.6.5", + "vuex": "^3.6.2", + "xregexp": "^5.1.2", + "yii2-pjax": "~2.0.8" }, - "engines": { - "node": ">=4" - } - }, - "packages/craftcms-legacy/node_modules/string-width": { - "version": "4.2.3", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" + "devDependencies": { + "@craftcms/playwright": "file:../craftcms-playwright", + "@craftcms/webpack": "file:../craftcms-webpack", + "@playwright/test": "^1.59.1", + "husky": "^9.1.7", + "lint-staged": "^16.4.0", + "pkg-dir": "^5.0.0", + "prettier": "3.8.3", + "stylelint": "^16.26.1", + "stylelint-config-standard": "^36.0.1", + "stylelint-config-standard-scss": "^13.1.0", + "stylelint-prettier": "^5.0.3", + "stylelint-use-logical-spec": "^5.0.1", + "tailwindcss": "^3.4.19", + "vue-apexcharts": "^1.7.0" }, "engines": { - "node": ">=8" - } - }, - "packages/craftcms-legacy/node_modules/strip-ansi": { - "version": "6.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" + "node": ">=20" }, - "engines": { - "node": ">=8" + "optionalDependencies": { + "@awesome.me/kit-ddaed3f5c5": "^1.0.74" } }, - "packages/craftcms-legacy/node_modules/stylelint": { - "version": "16.26.1", + "packages/craftcms-legacy/node_modules/@csstools/css-parser-algorithms": { + "version": "3.0.5", "dev": true, "funding": [ { - "type": "opencollective", - "url": "https://opencollective.com/stylelint" + "type": "github", + "url": "https://github.com/sponsors/csstools" }, { - "type": "github", - "url": "https://github.com/sponsors/stylelint" + "type": "opencollective", + "url": "https://opencollective.com/csstools" } ], "license": "MIT", - "dependencies": { - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-syntax-patches-for-csstree": "^1.0.19", - "@csstools/css-tokenizer": "^3.0.4", - "@csstools/media-query-list-parser": "^4.0.3", - "@csstools/selector-specificity": "^5.0.0", - "@dual-bundle/import-meta-resolve": "^4.2.1", - "balanced-match": "^2.0.0", - "colord": "^2.9.3", - "cosmiconfig": "^9.0.0", - "css-functions-list": "^3.2.3", - "css-tree": "^3.1.0", - "debug": "^4.4.3", - "fast-glob": "^3.3.3", - "fastest-levenshtein": "^1.0.16", - "file-entry-cache": "^11.1.1", - "global-modules": "^2.0.0", - "globby": "^11.1.0", - "globjoin": "^0.1.4", - "html-tags": "^3.3.1", - "ignore": "^7.0.5", - "imurmurhash": "^0.1.4", - "is-plain-object": "^5.0.0", - "known-css-properties": "^0.37.0", - "mathml-tag-names": "^2.1.3", - "meow": "^13.2.0", - "micromatch": "^4.0.8", - "normalize-path": "^3.0.0", - "picocolors": "^1.1.1", - "postcss": "^8.5.6", - "postcss-resolve-nested-selector": "^0.1.6", - "postcss-safe-parser": "^7.0.1", - "postcss-selector-parser": "^7.1.0", - "postcss-value-parser": "^4.2.0", - "resolve-from": "^5.0.0", - "string-width": "^4.2.3", - "supports-hyperlinks": "^3.2.0", - "svg-tags": "^1.0.0", - "table": "^6.9.0", - "write-file-atomic": "^5.0.1" - }, - "bin": { - "stylelint": "bin/stylelint.mjs" - }, "engines": { - "node": ">=18.12.0" + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-tokenizer": "^3.0.4" } }, - "packages/craftcms-legacy/node_modules/stylelint-config-recommended": { - "version": "14.0.1", + "packages/craftcms-legacy/node_modules/@csstools/css-tokenizer": { + "version": "3.0.4", "dev": true, "funding": [ { - "type": "opencollective", - "url": "https://opencollective.com/stylelint" + "type": "github", + "url": "https://github.com/sponsors/csstools" }, { - "type": "github", - "url": "https://github.com/sponsors/stylelint" + "type": "opencollective", + "url": "https://opencollective.com/csstools" } ], "license": "MIT", "engines": { - "node": ">=18.12.0" - }, - "peerDependencies": { - "stylelint": "^16.1.0" - } - }, - "packages/craftcms-legacy/node_modules/stylelint-config-recommended-scss": { - "version": "14.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "postcss-scss": "^4.0.9", - "stylelint-config-recommended": "^14.0.1", - "stylelint-scss": "^6.4.0" - }, - "engines": { - "node": ">=18.12.0" - }, - "peerDependencies": { - "postcss": "^8.3.3", - "stylelint": "^16.6.1" - }, - "peerDependenciesMeta": { - "postcss": { - "optional": true - } + "node": ">=18" } }, - "packages/craftcms-legacy/node_modules/stylelint-config-standard": { - "version": "36.0.1", + "packages/craftcms-legacy/node_modules/@csstools/media-query-list-parser": { + "version": "4.0.3", "dev": true, "funding": [ { - "type": "opencollective", - "url": "https://opencollective.com/stylelint" + "type": "github", + "url": "https://github.com/sponsors/csstools" }, { - "type": "github", - "url": "https://github.com/sponsors/stylelint" + "type": "opencollective", + "url": "https://opencollective.com/csstools" } ], "license": "MIT", - "dependencies": { - "stylelint-config-recommended": "^14.0.1" - }, "engines": { - "node": ">=18.12.0" + "node": ">=18" }, "peerDependencies": { - "stylelint": "^16.1.0" + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" } }, - "packages/craftcms-legacy/node_modules/stylelint-config-standard-scss": { - "version": "13.1.0", - "dev": true, - "license": "MIT", + "packages/craftcms-legacy/node_modules/@vue/compiler-sfc": { + "version": "2.7.16", "dependencies": { - "stylelint-config-recommended-scss": "^14.0.0", - "stylelint-config-standard": "^36.0.0" - }, - "engines": { - "node": ">=18.12.0" - }, - "peerDependencies": { - "postcss": "^8.3.3", - "stylelint": "^16.3.1" + "@babel/parser": "^7.23.5", + "postcss": "^8.4.14", + "source-map": "^0.6.1" }, - "peerDependenciesMeta": { - "postcss": { - "optional": true - } + "optionalDependencies": { + "prettier": "^1.18.2 || ^2.0.0" } }, - "packages/craftcms-legacy/node_modules/stylelint-scss": { - "version": "6.14.0", - "dev": true, + "packages/craftcms-legacy/node_modules/@vue/compiler-sfc/node_modules/prettier": { + "version": "2.8.8", "license": "MIT", - "dependencies": { - "css-tree": "^3.0.1", - "is-plain-object": "^5.0.0", - "known-css-properties": "^0.37.0", - "mdn-data": "^2.25.0", - "postcss-media-query-parser": "^0.2.3", - "postcss-resolve-nested-selector": "^0.1.6", - "postcss-selector-parser": "^7.1.1", - "postcss-value-parser": "^4.2.0" + "optional": true, + "bin": { + "prettier": "bin-prettier.js" }, "engines": { - "node": ">=18.12.0" + "node": ">=10.13.0" }, - "peerDependencies": { - "stylelint": "^16.8.2" + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" } }, - "packages/craftcms-legacy/node_modules/tailwindcss": { - "version": "3.4.19", + "packages/craftcms-legacy/node_modules/ansi-regex": { + "version": "5.0.1", "dev": true, "license": "MIT", - "dependencies": { - "@alloc/quick-lru": "^5.2.0", - "arg": "^5.0.2", - "chokidar": "^3.6.0", - "didyoumean": "^1.2.2", - "dlv": "^1.1.3", - "fast-glob": "^3.3.2", - "glob-parent": "^6.0.2", - "is-glob": "^4.0.3", - "jiti": "^1.21.7", - "lilconfig": "^3.1.3", - "micromatch": "^4.0.8", - "normalize-path": "^3.0.0", - "object-hash": "^3.0.0", - "picocolors": "^1.1.1", - "postcss": "^8.4.47", - "postcss-import": "^15.1.0", - "postcss-js": "^4.0.1", - "postcss-load-config": "^4.0.2 || ^5.0 || ^6.0", - "postcss-nested": "^6.2.0", - "postcss-selector-parser": "^6.1.2", - "resolve": "^1.22.8", - "sucrase": "^3.35.0" - }, - "bin": { - "tailwind": "lib/cli.js", - "tailwindcss": "lib/cli.js" - }, "engines": { - "node": ">=14.0.0" + "node": ">=8" } }, - "packages/craftcms-legacy/node_modules/tailwindcss/node_modules/glob-parent": { - "version": "6.0.2", + "packages/craftcms-legacy/node_modules/balanced-match": { + "version": "2.0.0", "dev": true, - "license": "ISC", + "license": "MIT" + }, + "packages/craftcms-legacy/node_modules/chokidar": { + "version": "3.6.0", + "dev": true, + "license": "MIT", "dependencies": { - "is-glob": "^4.0.3" + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" }, "engines": { - "node": ">=10.13.0" + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" } }, - "packages/craftcms-legacy/node_modules/tailwindcss/node_modules/postcss-selector-parser": { - "version": "6.1.2", + "packages/craftcms-legacy/node_modules/globby": { + "version": "11.1.0", "dev": true, "license": "MIT", "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" }, "engines": { - "node": ">=4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "packages/craftcms-legacy/node_modules/typescript": { - "version": "5.9.3", - "license": "Apache-2.0", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, + "packages/craftcms-legacy/node_modules/globby/node_modules/ignore": { + "version": "5.3.2", + "dev": true, + "license": "MIT", "engines": { - "node": ">=14.17" + "node": ">= 4" } }, - "packages/craftcms-legacy/node_modules/vue": { - "version": "2.7.16", + "packages/craftcms-legacy/node_modules/html-tags": { + "version": "3.3.1", + "dev": true, "license": "MIT", - "dependencies": { - "@vue/compiler-sfc": "2.7.16", - "csstype": "^3.1.0" + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "packages/craftcms-legacy/node_modules/write-file-atomic": { - "version": "5.0.1", + "packages/craftcms-legacy/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", "dev": true, - "license": "ISC", - "dependencies": { - "imurmurhash": "^0.1.4", - "signal-exit": "^4.0.1" - }, + "license": "MIT", "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": ">=8" } }, - "packages/craftcms-playwright": { - "name": "@craftcms/playwright", - "version": "1.0.0", + "packages/craftcms-legacy/node_modules/jiti": { + "version": "1.21.7", + "dev": true, "license": "MIT", - "dependencies": { - "@playwright/test": "^1.47.0", - "events": "^3.3.0", - "signale": "^1.4.0" - }, "bin": { - "craft-playwright": "src/cli.js" + "jiti": "bin/jiti.js" } }, - "packages/craftcms-sass": { - "name": "@craftcms/sass", - "version": "1.1.0", - "license": "MIT" + "packages/craftcms-legacy/node_modules/mathml-tag-names": { + "version": "2.1.3", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } }, - "packages/craftcms-ui": { - "name": "@craftcms/ui", - "version": "0.0.0", + "packages/craftcms-legacy/node_modules/meow": { + "version": "13.2.0", + "dev": true, "license": "MIT", - "dependencies": { - "@chromatic-com/storybook": "^5.1.2", - "@formatjs/intl-durationformat": "^0.10.8", - "@github/relative-time-element": "^5.0.0", - "@simplewebauthn/browser": "^13.3.0", - "@vitest/browser-playwright": "4.1.10", - "axios": "^1.17.0" - }, - "devDependencies": { - "@adobe/leonardo-contrast-colors": "^1.1.0", - "@arethetypeswrong/cli": "^0.18.2", - "@custom-elements-manifest/analyzer": "^0.11.0", - "@lion/ui": "^0.16.1", - "@shoelace-style/shoelace": "^2.20.1", - "@storybook/addon-a11y": "^10.5.5", - "@storybook/addon-docs": "^10.5.5", - "@storybook/addon-themes": "^10.5.5", - "@storybook/addon-vitest": "^10.5.5", - "@storybook/web-components-vite": "^10.5.5", - "@total-typescript/tsconfig": "^1.0.4", - "@types/humanize-duration": "^3.27.4", - "@types/jquery": "^4.0.0", - "@types/node": "^25.6.0", - "@vitest/coverage-v8": "4.1.10", - "@wc-toolkit/storybook-helpers": "^10.3.0", - "del": "^8.0.1", - "dom-accessibility-api": "^0.7.1", - "esbuild": "^0.28.0", - "globby": "^16.2.0", - "happy-dom": "^20.9.0", - "humanize-duration": "^3.33.2", - "lit": "^3.3.2", - "ora": "^9.4.0", - "playwright": "^1.59.1", - "plop": "^4.0.5", - "recursive-copy": "^2.0.14", - "rimraf": "^6.1.3", - "storybook": "^10.5.5", - "typescript": "^6.0.3", - "unplugin-dts": "^1.0.0", - "vite": "npm:@voidzero-dev/vite-plus-core@0.2.6", - "vite-plugin-dts": "^5.0.0", - "vite-plus": "0.2.6", - "vite-tsconfig-paths": "^6.1.1", - "vitest": "4.1.10" + "engines": { + "node": ">=18" }, - "peerDependencies": { - "@lion/ui": "0.x", - "lit": "3.x" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "packages/craftcms-ui/node_modules/@types/jquery": { - "version": "4.0.0", + "packages/craftcms-legacy/node_modules/pkg-dir": { + "version": "5.0.0", "dev": true, - "license": "MIT" + "license": "MIT", + "dependencies": { + "find-up": "^5.0.0" + }, + "engines": { + "node": ">=10" + } }, - "packages/craftcms-ui/node_modules/@wc-toolkit/storybook-helpers": { - "version": "10.3.0", + "packages/craftcms-legacy/node_modules/postcss-selector-parser": { + "version": "7.1.1", "dev": true, "license": "MIT", - "peerDependencies": { - "lit": "^2.0.0 || ^3.0.0", - "storybook": ">=10.1.11-0 <11.0.0-0" + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" } }, - "packages/craftcms-ui/node_modules/balanced-match": { - "version": "4.0.4", + "packages/craftcms-legacy/node_modules/string-width": { + "version": "4.2.3", "dev": true, "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, "engines": { - "node": "18 || 20 || >=22" + "node": ">=8" } }, - "packages/craftcms-ui/node_modules/brace-expansion": { - "version": "5.0.5", + "packages/craftcms-legacy/node_modules/strip-ansi": { + "version": "6.0.1", "dev": true, "license": "MIT", "dependencies": { - "balanced-match": "^4.0.2" + "ansi-regex": "^5.0.1" }, "engines": { - "node": "18 || 20 || >=22" + "node": ">=8" } }, - "packages/craftcms-ui/node_modules/chalk": { - "version": "5.6.2", + "packages/craftcms-legacy/node_modules/stylelint": { + "version": "16.26.1", "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/stylelint" + }, + { + "type": "github", + "url": "https://github.com/sponsors/stylelint" + } + ], "license": "MIT", - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" + "dependencies": { + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-syntax-patches-for-csstree": "^1.0.19", + "@csstools/css-tokenizer": "^3.0.4", + "@csstools/media-query-list-parser": "^4.0.3", + "@csstools/selector-specificity": "^5.0.0", + "@dual-bundle/import-meta-resolve": "^4.2.1", + "balanced-match": "^2.0.0", + "colord": "^2.9.3", + "cosmiconfig": "^9.0.0", + "css-functions-list": "^3.2.3", + "css-tree": "^3.1.0", + "debug": "^4.4.3", + "fast-glob": "^3.3.3", + "fastest-levenshtein": "^1.0.16", + "file-entry-cache": "^11.1.1", + "global-modules": "^2.0.0", + "globby": "^11.1.0", + "globjoin": "^0.1.4", + "html-tags": "^3.3.1", + "ignore": "^7.0.5", + "imurmurhash": "^0.1.4", + "is-plain-object": "^5.0.0", + "known-css-properties": "^0.37.0", + "mathml-tag-names": "^2.1.3", + "meow": "^13.2.0", + "micromatch": "^4.0.8", + "normalize-path": "^3.0.0", + "picocolors": "^1.1.1", + "postcss": "^8.5.6", + "postcss-resolve-nested-selector": "^0.1.6", + "postcss-safe-parser": "^7.0.1", + "postcss-selector-parser": "^7.1.0", + "postcss-value-parser": "^4.2.0", + "resolve-from": "^5.0.0", + "string-width": "^4.2.3", + "supports-hyperlinks": "^3.2.0", + "svg-tags": "^1.0.0", + "table": "^6.9.0", + "write-file-atomic": "^5.0.1" }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "bin": { + "stylelint": "bin/stylelint.mjs" + }, + "engines": { + "node": ">=18.12.0" } }, - "packages/craftcms-ui/node_modules/cli-spinners": { - "version": "3.3.0", + "packages/craftcms-legacy/node_modules/stylelint-config-recommended": { + "version": "14.0.1", "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/stylelint" + }, + { + "type": "github", + "url": "https://github.com/sponsors/stylelint" + } + ], "license": "MIT", "engines": { - "node": ">=18.20" + "node": ">=18.12.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "peerDependencies": { + "stylelint": "^16.1.0" } }, - "packages/craftcms-ui/node_modules/del": { - "version": "8.0.1", + "packages/craftcms-legacy/node_modules/stylelint-config-recommended-scss": { + "version": "14.1.0", "dev": true, "license": "MIT", "dependencies": { - "globby": "^14.0.2", - "is-glob": "^4.0.3", - "is-path-cwd": "^3.0.0", - "is-path-inside": "^4.0.0", - "p-map": "^7.0.2", - "presentable-error": "^0.0.1", - "slash": "^5.1.0" + "postcss-scss": "^4.0.9", + "stylelint-config-recommended": "^14.0.1", + "stylelint-scss": "^6.4.0" }, "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/craftcms-ui/node_modules/dom-accessibility-api": { - "version": "0.7.1", - "dev": true, - "license": "MIT" - }, - "packages/craftcms-ui/node_modules/glob": { - "version": "13.0.6", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "minimatch": "^10.2.2", - "minipass": "^7.1.3", - "path-scurry": "^2.0.2" + "node": ">=18.12.0" }, - "engines": { - "node": "18 || 20 || >=22" + "peerDependencies": { + "postcss": "^8.3.3", + "stylelint": "^16.6.1" }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "peerDependenciesMeta": { + "postcss": { + "optional": true + } } }, - "packages/craftcms-ui/node_modules/globby": { - "version": "14.1.0", + "packages/craftcms-legacy/node_modules/stylelint-config-standard": { + "version": "36.0.1", "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/stylelint" + }, + { + "type": "github", + "url": "https://github.com/sponsors/stylelint" + } + ], "license": "MIT", "dependencies": { - "@sindresorhus/merge-streams": "^2.1.0", - "fast-glob": "^3.3.3", - "ignore": "^7.0.3", - "path-type": "^6.0.0", - "slash": "^5.1.0", - "unicorn-magic": "^0.3.0" + "stylelint-config-recommended": "^14.0.1" }, "engines": { - "node": ">=18" + "node": ">=18.12.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "peerDependencies": { + "stylelint": "^16.1.0" } }, - "packages/craftcms-ui/node_modules/is-interactive": { - "version": "2.0.0", + "packages/craftcms-legacy/node_modules/stylelint-config-standard-scss": { + "version": "13.1.0", "dev": true, "license": "MIT", - "engines": { - "node": ">=12" + "dependencies": { + "stylelint-config-recommended-scss": "^14.0.0", + "stylelint-config-standard": "^36.0.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/craftcms-ui/node_modules/is-path-cwd": { - "version": "3.0.0", - "dev": true, - "license": "MIT", "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">=18.12.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/craftcms-ui/node_modules/is-path-inside": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" + "peerDependencies": { + "postcss": "^8.3.3", + "stylelint": "^16.3.1" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "peerDependenciesMeta": { + "postcss": { + "optional": true + } } }, - "packages/craftcms-ui/node_modules/is-unicode-supported": { - "version": "2.1.0", + "packages/craftcms-legacy/node_modules/stylelint-scss": { + "version": "6.14.0", "dev": true, "license": "MIT", + "dependencies": { + "css-tree": "^3.0.1", + "is-plain-object": "^5.0.0", + "known-css-properties": "^0.37.0", + "mdn-data": "^2.25.0", + "postcss-media-query-parser": "^0.2.3", + "postcss-resolve-nested-selector": "^0.1.6", + "postcss-selector-parser": "^7.1.1", + "postcss-value-parser": "^4.2.0" + }, "engines": { - "node": ">=18" + "node": ">=18.12.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "peerDependencies": { + "stylelint": "^16.8.2" } }, - "packages/craftcms-ui/node_modules/log-symbols": { - "version": "7.0.1", + "packages/craftcms-legacy/node_modules/tailwindcss": { + "version": "3.4.19", "dev": true, "license": "MIT", "dependencies": { - "is-unicode-supported": "^2.0.0", - "yoctocolors": "^2.1.1" + "@alloc/quick-lru": "^5.2.0", + "arg": "^5.0.2", + "chokidar": "^3.6.0", + "didyoumean": "^1.2.2", + "dlv": "^1.1.3", + "fast-glob": "^3.3.2", + "glob-parent": "^6.0.2", + "is-glob": "^4.0.3", + "jiti": "^1.21.7", + "lilconfig": "^3.1.3", + "micromatch": "^4.0.8", + "normalize-path": "^3.0.0", + "object-hash": "^3.0.0", + "picocolors": "^1.1.1", + "postcss": "^8.4.47", + "postcss-import": "^15.1.0", + "postcss-js": "^4.0.1", + "postcss-load-config": "^4.0.2 || ^5.0 || ^6.0", + "postcss-nested": "^6.2.0", + "postcss-selector-parser": "^6.1.2", + "resolve": "^1.22.8", + "sucrase": "^3.35.0" }, - "engines": { - "node": ">=18" + "bin": { + "tailwind": "lib/cli.js", + "tailwindcss": "lib/cli.js" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": ">=14.0.0" } }, - "packages/craftcms-ui/node_modules/minimatch": { - "version": "10.2.5", + "packages/craftcms-legacy/node_modules/tailwindcss/node_modules/glob-parent": { + "version": "6.0.2", "dev": true, - "license": "BlueOak-1.0.0", + "license": "ISC", "dependencies": { - "brace-expansion": "^5.0.5" + "is-glob": "^4.0.3" }, "engines": { - "node": "18 || 20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": ">=10.13.0" } }, - "packages/craftcms-ui/node_modules/ora": { - "version": "9.4.0", + "packages/craftcms-legacy/node_modules/tailwindcss/node_modules/postcss-selector-parser": { + "version": "6.1.2", "dev": true, "license": "MIT", "dependencies": { - "chalk": "^5.6.2", - "cli-cursor": "^5.0.0", - "cli-spinners": "^3.2.0", - "is-interactive": "^2.0.0", - "is-unicode-supported": "^2.1.0", - "log-symbols": "^7.0.1", - "stdin-discarder": "^0.3.2", - "string-width": "^8.1.0" - }, - "engines": { - "node": ">=20" + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/craftcms-ui/node_modules/p-map": { - "version": "7.0.4", - "dev": true, - "license": "MIT", "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=4" } }, - "packages/craftcms-ui/node_modules/path-scurry": { - "version": "2.0.2", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "lru-cache": "^11.0.0", - "minipass": "^7.1.2" + "packages/craftcms-legacy/node_modules/typescript": { + "version": "5.9.3", + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" }, "engines": { - "node": "18 || 20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": ">=14.17" } }, - "packages/craftcms-ui/node_modules/path-type": { - "version": "6.0.0", - "dev": true, + "packages/craftcms-legacy/node_modules/vue": { + "version": "2.7.16", "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "dependencies": { + "@vue/compiler-sfc": "2.7.16", + "csstype": "^3.1.0" } }, - "packages/craftcms-ui/node_modules/rimraf": { - "version": "6.1.3", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "glob": "^13.0.3", - "package-json-from-dist": "^1.0.1" - }, - "bin": { - "rimraf": "dist/esm/bin.mjs" + "packages/craftcms-legacy/node_modules/write-file-atomic": { + "version": "5.0.1", + "dev": true, + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^4.0.1" }, "engines": { - "node": "20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "packages/craftcms-ui/node_modules/slash": { - "version": "5.1.0", - "dev": true, + "packages/craftcms-playwright": { + "name": "@craftcms/playwright", + "version": "1.0.0", "license": "MIT", - "engines": { - "node": ">=14.16" + "dependencies": { + "@playwright/test": "^1.47.0", + "events": "^3.3.0", + "signale": "^1.4.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "bin": { + "craft-playwright": "src/cli.js" } }, + "packages/craftcms-sass": { + "name": "@craftcms/sass", + "version": "1.1.0", + "license": "MIT" + }, "packages/craftcms-vue": { "name": "@craftcms/vue", "version": "1.0.1", @@ -25595,6 +25073,8 @@ "css-minimizer-webpack-plugin": "^5.0.1", "dotenv": "^16.3.1", "dotenv-webpack": "^8.0.1", + "eslint": "^8.56.0", + "eslint-plugin-vue": "^9.19.2", "expose-loader": "^4.1.0", "glob": "^10.3.10", "json-minimizer-webpack-plugin": "^4.0.0", @@ -25616,6 +25096,34 @@ "yargs": "^17.7.2" } }, + "packages/craftcms-webpack/node_modules/@eslint/eslintrc": { + "version": "2.1.4", + "license": "MIT", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "packages/craftcms-webpack/node_modules/@eslint/js": { + "version": "8.57.1", + "license": "MIT", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, "packages/craftcms-webpack/node_modules/ansi-regex": { "version": "5.0.1", "license": "MIT", @@ -25636,6 +25144,20 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "packages/craftcms-webpack/node_modules/chalk": { + "version": "4.1.2", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, "packages/craftcms-webpack/node_modules/cliui": { "version": "8.0.1", "license": "ISC", @@ -25662,6 +25184,158 @@ "version": "1.1.4", "license": "MIT" }, + "packages/craftcms-webpack/node_modules/cross-spawn": { + "version": "7.0.6", + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "packages/craftcms-webpack/node_modules/escape-string-regexp": { + "version": "4.0.0", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "packages/craftcms-webpack/node_modules/eslint": { + "version": "8.57.1", + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.1", + "@humanwhocodes/config-array": "^0.13.0", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "packages/craftcms-webpack/node_modules/eslint-scope": { + "version": "7.2.2", + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "packages/craftcms-webpack/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "packages/craftcms-webpack/node_modules/estraverse": { + "version": "5.3.0", + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "packages/craftcms-webpack/node_modules/file-entry-cache": { + "version": "6.0.1", + "license": "MIT", + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "packages/craftcms-webpack/node_modules/flat-cache": { + "version": "3.2.0", + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "packages/craftcms-webpack/node_modules/glob-parent": { + "version": "6.0.2", + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "packages/craftcms-webpack/node_modules/has-flag": { + "version": "4.0.0", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "packages/craftcms-webpack/node_modules/ignore": { + "version": "5.3.2", + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, "packages/craftcms-webpack/node_modules/is-fullwidth-code-point": { "version": "3.0.0", "license": "MIT", @@ -25669,6 +25343,20 @@ "node": ">=8" } }, + "packages/craftcms-webpack/node_modules/keyv": { + "version": "4.5.4", + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "packages/craftcms-webpack/node_modules/path-key": { + "version": "3.1.1", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "packages/craftcms-webpack/node_modules/pkg-dir": { "version": "8.0.0", "license": "MIT", @@ -25682,6 +25370,54 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "packages/craftcms-webpack/node_modules/rimraf": { + "version": "3.0.2", + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "packages/craftcms-webpack/node_modules/rimraf/node_modules/glob": { + "version": "7.2.3", + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "packages/craftcms-webpack/node_modules/shebang-command": { + "version": "2.0.0", + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "packages/craftcms-webpack/node_modules/shebang-regex": { + "version": "3.0.0", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "packages/craftcms-webpack/node_modules/string-width": { "version": "4.2.3", "license": "MIT", @@ -25704,6 +25440,29 @@ "node": ">=8" } }, + "packages/craftcms-webpack/node_modules/supports-color": { + "version": "7.2.0", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "packages/craftcms-webpack/node_modules/which": { + "version": "2.0.2", + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, "packages/craftcms-webpack/node_modules/wrap-ansi": { "version": "7.0.0", "license": "MIT", diff --git a/package.json b/package.json index 52501724198..1592b85abdd 100644 --- a/package.json +++ b/package.json @@ -4,18 +4,14 @@ "main": "webpack.config.js", "type": "module", "scripts": { - "check-prettier": "vp fmt --check ./resources", - "fix-prettier": "vp fmt ./resources", - "prepare": "vp config", + "check-prettier": "prettier --check ./resources", + "fix-prettier": "prettier --write ./resources", + "prepare": "husky", "prebuild": "npm run fix-prettier", - "build": "vp build", - "build:fe": "npm run build:ui && npm run build", - "predev": "node scripts/ensure-built.mjs", - "dev": "run-p -l dev:vite dev:ui", - "dev:vite": "vp dev", - "predev:legacy": "node scripts/ensure-built.mjs", - "dev:legacy": "run-p -l dev:vite dev:ui dev:bundles", - "lint:js": "vp lint resources/js/", + "build": "vite build", + "build:fe": "npm run build:cp && npm run build", + "dev": "vite", + "lint:js": "eslint resources/js/", "lint:styles": "stylelint \"resources/**/*.css\"", "generate:types": "./vendor/bin/testbench typescript:transform", "generate:wayfinder": "./vendor/bin/testbench wayfinder:generate --path resources/js", @@ -24,15 +20,13 @@ "build:bundles": "cd ./packages/craftcms-legacy && npm run build", "dev:bundles": "cd ./packages/craftcms-legacy && npm run dev", "serve:bundles": "cd ./packages/craftcms-legacy && npm run serve", - "dev:ui": "cd ./packages/craftcms-ui && npm run dev", - "build:ui": "cd ./packages/craftcms-ui && npm run build", - "build:garnish": "cd ./packages/craftcms-garnish && npm run build", - "test": "vp test run", - "test:ui": "cd ./packages/craftcms-ui && npm run test", + "dev:cp": "cd ./packages/craftcms-cp && npm run dev", + "build:cp": "cd ./packages/craftcms-cp && npm run build", + "test:cp": "cd ./packages/craftcms-cp && npm run test", "storybook": "storybook dev -p 6007", "build:storybook": "storybook build", - "storybook:ui": "cd ./packages/craftcms-ui && npm run storybook", - "build:all": "npm run build:garnish && npm run build:ui && npm run build:bundles && npm run build" + "storybook:cp": "cd ./packages/craftcms-cp && npm run storybook", + "build:all": "npm run build:cp && npm run build:bundles && npm run build" }, "workspaces": [ "packages/*" @@ -40,39 +34,35 @@ "engines": { "node": ">=22" }, - "devEngines": { - "packageManager": { - "name": "npm", - "version": ">=10 <13", - "onFail": "download" - } - }, "devDependencies": { - "@craftcms/garnish": "file:packages/craftcms-garnish", "@craftcms/playwright": "file:packages/craftcms-playwright", "@craftcms/webpack": "file:packages/craftcms-webpack", "@laravel/vite-plugin-wayfinder": "^0.1.7", "@playwright/test": "^1.59.1", - "@storybook/addon-a11y": "^10.5.5", - "@storybook/addon-docs": "^10.5.5", - "@storybook/addon-themes": "^10.5.5", - "@storybook/vue3-vite": "^10.5.5", + "@storybook/addon-a11y": "^10.4.1", + "@storybook/addon-docs": "^10.4.1", + "@storybook/addon-themes": "^10.4.1", + "@storybook/vue3-vite": "^10.4.1", "@tailwindcss/vite": "^4.2.4", "@total-typescript/tsconfig": "^1.0.4", "@vitejs/plugin-vue": "^6.0.6", "esbuild": "^0.28.0", + "eslint": "^9.39.4", + "eslint-plugin-vue": "^9.33.0", + "husky": "^9.1.7", + "lint-staged": "^16.4.0", "npm-run-all": "^4.1.5", - "storybook": "^10.5.5", + "prettier": "3.8.3", + "storybook": "^10.4.1", "stylelint": "^17.9.1", "stylelint-config-standard": "^40.0.0", "stylelint-config-standard-scss": "^17.0.0", "stylelint-prettier": "^5.0.3", "stylelint-use-logical": "^2.1.3", "typescript": "^6.0.3", - "vite": "npm:@voidzero-dev/vite-plus-core@0.2.6", - "vitest": "4.1.10", - "vue-tsc": "^3.2.7", - "vite-plus": "0.2.6" + "typescript-eslint": "^8.60.0", + "vite": "^8.0.10", + "vue-tsc": "^3.2.7" }, "optionalDependencies": { "@awesome.me/kit-ddaed3f5c5": "^1.0.74" @@ -80,8 +70,7 @@ "dependencies": { "@atlaskit/pragmatic-drag-and-drop": "^1.8.1", "@atlaskit/pragmatic-drag-and-drop-hitbox": "^1.1.0", - "@craftcms/ui": "file:packages/craftcms-ui", - "@craftcms/graphiql": "file:packages/craftcms-graphiql", + "@craftcms/cp": "file:packages/craftcms-cp", "@headlessui/vue": "^1.7.23", "@inertiajs/vite": "^3.0.3", "@inertiajs/vue3": "^3.0.3", @@ -90,18 +79,7 @@ "axios": "^1.17.0", "laravel-vite-plugin": "^3.1.0", "lit": "^3.3.2", - "overtype": "^2.4.0", "tailwindcss": "^4.2.4", "vue": "^3.5.33" - }, - "overrides": { - "vite": "npm:@voidzero-dev/vite-plus-core@0.2.6", - "vitest": "4.1.10" - }, - "allowScripts": { - "@parcel/watcher": true, - "esbuild@0.28.1": true, - "rs-module-lexer": true, - "ttf2woff2": true } } diff --git a/packages/craftcms-ui/.gitignore b/packages/craftcms-cp/.gitignore similarity index 100% rename from packages/craftcms-ui/.gitignore rename to packages/craftcms-cp/.gitignore diff --git a/packages/craftcms-garnish/.nvmrc b/packages/craftcms-cp/.nvmrc similarity index 100% rename from packages/craftcms-garnish/.nvmrc rename to packages/craftcms-cp/.nvmrc diff --git a/packages/craftcms-ui/.prettierignore b/packages/craftcms-cp/.prettierignore similarity index 100% rename from packages/craftcms-ui/.prettierignore rename to packages/craftcms-cp/.prettierignore diff --git a/packages/craftcms-ui/.storybook/main.ts b/packages/craftcms-cp/.storybook/main.ts similarity index 100% rename from packages/craftcms-ui/.storybook/main.ts rename to packages/craftcms-cp/.storybook/main.ts diff --git a/packages/craftcms-ui/.storybook/preview.css b/packages/craftcms-cp/.storybook/preview.css similarity index 100% rename from packages/craftcms-ui/.storybook/preview.css rename to packages/craftcms-cp/.storybook/preview.css diff --git a/packages/craftcms-cp/.storybook/preview.ts b/packages/craftcms-cp/.storybook/preview.ts new file mode 100644 index 00000000000..82cdb1d6cf0 --- /dev/null +++ b/packages/craftcms-cp/.storybook/preview.ts @@ -0,0 +1,67 @@ +import type { + Preview, + WebComponentsRenderer, +} from '@storybook/web-components-vite'; +import '../src/styles/cp.css'; +import './preview.css'; +import {icons} from '@lion/ui/icon.js'; +import {html} from 'lit'; +import {withThemeByDataAttribute} from '@storybook/addon-themes'; +import {setCustomElementsManifest} from '@storybook/web-components'; +import manifest from '../dist/custom-elements.json' with {type: 'json'}; +import {setStorybookHelpersConfig} from '@wc-toolkit/storybook-helpers'; + +setStorybookHelpersConfig({ + /** hides the `arg ref` label on each control */ + hideArgRef: false, + /** sets the custom type reference in the Custom Elements Manifest */ + typeRef: 'parsedTypes', + /** Adds a + + +`; +} + +function generateCheckedWrapper(component) { + return ` + + + +`; +} + +function generateGroupWrapper(component) { + return ` + + + +`; +} + +// ─── Declaration File Generators ──────────────────────────────────────────── + +/** + * Generate a `.vue.d.ts` declaration file for a Vue wrapper component. + * TypeScript will use this instead of processing the `.vue` source, avoiding + * broken relative imports (e.g. `../components/input/input`) in the dist folder. + */ +function generateValueDeclaration(component) { + return `/** + * Auto-generated type declaration for ${component.fileName}.vue + * Generated by: scripts/generate-vue-wrappers.js + */ +import type {DefineComponent} from 'vue'; +declare const _default: DefineComponent<{ + error?: string | null; + modelValue?: ${component.modelType}; + 'onUpdate:modelValue'?: (val: ${component.modelType}) => void; +}>; +export default _default; +`; +} + +function generateCheckedDeclaration(component) { + return `/** + * Auto-generated type declaration for ${component.fileName}.vue + * Generated by: scripts/generate-vue-wrappers.js + */ +import type {DefineComponent} from 'vue'; +declare const _default: DefineComponent<{ + error?: string | null; + modelValue?: boolean; + 'onUpdate:modelValue'?: (val: boolean) => void; +}>; +export default _default; +`; +} + +function generateGroupDeclaration(component) { + return `/** + * Auto-generated type declaration for ${component.fileName}.vue + * Generated by: scripts/generate-vue-wrappers.js + */ +import type {DefineComponent} from 'vue'; +declare const _default: DefineComponent<{ + error?: string | null; + modelValue?: ${component.modelType}; + 'onUpdate:modelValue'?: (val: ${component.modelType}) => void; +}>; +export default _default; +`; +} + +// ─── Type Augmentation Generator ──────────────────────────────────────────── + +/** + * All craft-* web components with their class names and import paths. + * Used to generate Vue IntrinsicElements type augmentations. + */ +const ALL_COMPONENTS = [ + // Form components (value-based) + ...VALUE_COMPONENTS, + // Form components (checked-based) + ...CHECKED_COMPONENTS, + // Form components (groups) + ...GROUP_COMPONENTS, + // Choice inputs used inside groups (not typically needing v-model wrappers) + { + tagName: 'craft-radio', + className: 'CraftRadio', + importPath: '../components/radio/radio', + }, + { + tagName: 'craft-checkbox-indeterminate', + className: 'CraftCheckboxIndeterminate', + importPath: '../components/checkbox-indeterminate/checkbox-indeterminate', + }, + // Display components + { + tagName: 'craft-button', + className: 'CraftButton', + importPath: '../components/button/button', + }, + { + tagName: 'craft-button-group', + className: 'CraftButtonGroup', + importPath: '../components/button-group/button-group', + }, + { + tagName: 'craft-icon', + className: 'CraftIcon', + importPath: '../components/icon/icon', + }, + { + tagName: 'craft-option', + className: 'CraftOption', + importPath: '../components/option/option', + }, + { + tagName: 'craft-action-menu', + className: 'CraftActionMenu', + importPath: '../components/action-menu/action-menu', + }, + { + tagName: 'craft-action-item', + className: 'CraftActionItem', + importPath: '../components/action-item/action-item', + }, + { + tagName: 'craft-avatar', + className: 'CraftAvatar', + importPath: '../components/avatar/avatar', + }, + { + tagName: 'craft-badge-indicator', + className: 'CraftBadgeIndicator', + importPath: '../components/badge-indicator/badge-indicator', + }, + { + tagName: 'craft-breadcrumbs', + className: 'CraftBreadcrumbs', + importPath: '../components/breadcrumbs/breadcrumbs', + }, + { + tagName: 'craft-breadcrumb-item', + className: 'CraftBreadcrumbItem', + importPath: '../components/breadcrumb-item/breadcrumb-item', + }, + { + tagName: 'craft-callout', + className: 'CraftCallout', + importPath: '../components/callout/callout', + }, + { + tagName: 'craft-card', + className: 'CraftCard', + importPath: '../components/card/card', + }, + { + tagName: 'craft-chip', + className: 'CraftChip', + importPath: '../components/chip/chip', + }, + { + tagName: 'craft-copy-attribute', + className: 'CraftCopyAttribute', + importPath: '../components/copy-attribute/copy-attribute', + }, + { + tagName: 'craft-copy-button', + className: 'CraftCopyButton', + importPath: '../components/copy-button/copy-button', + }, + { + tagName: 'craft-dialog', + className: 'CraftDialog', + importPath: '../components/dialog/dialog', + }, + { + tagName: 'craft-disclosure', + className: 'CraftDisclosure', + importPath: '../components/disclosure/disclosure', + }, + { + tagName: 'craft-drawer', + className: 'CraftDrawer', + importPath: '../components/drawer/drawer', + }, + { + tagName: 'craft-dropdown', + className: 'CraftDropdown', + importPath: '../components/dropdown/dropdown', + }, + { + tagName: 'craft-indicator', + className: 'CraftIndicator', + importPath: '../components/indicator/indicator', + }, + { + tagName: 'craft-nav-list', + className: 'CraftNavList', + importPath: '../components/nav-list/nav-list', + }, + { + tagName: 'craft-nav-item', + className: 'CraftNavItem', + importPath: '../components/nav-item/nav-item', + }, + { + tagName: 'craft-popover', + className: 'CraftPopover', + importPath: '../components/popover/popover', + }, + { + tagName: 'craft-progress', + className: 'CraftProgress', + importPath: '../components/progress/progress', + }, + { + tagName: 'craft-progress-bar', + className: 'CraftProgressBar', + importPath: '../components/progress-bar/progress-bar', + }, + { + tagName: 'craft-shortcut', + className: 'CraftShortcut', + importPath: '../components/shortcut/shortcut', + }, + { + tagName: 'craft-spinner', + className: 'CraftSpinner', + importPath: '../components/spinner/spinner', + }, + { + tagName: 'craft-status', + className: 'CraftStatus', + importPath: '../components/status/status', + }, + { + tagName: 'craft-switch-button', + className: 'CraftSwitchButton', + importPath: '../components/switch-button/switch-button', + }, + { + tagName: 'craft-tab', + className: 'CraftTab', + importPath: '../components/tab/tab', + }, + { + tagName: 'craft-tabs', + className: 'CraftTabs', + importPath: '../components/tabs/tabs', + }, + { + tagName: 'craft-selected-file-list', + className: 'CraftSelectedFileList', + importPath: '../components/input-file/selected-file-list', + }, + { + tagName: 'c-tooltip', + className: 'CraftTooltip', + importPath: '../components/tooltip/tooltip', + }, +]; + +function generateTypeAugmentations() { + const imports = ALL_COMPONENTS.map( + (c) => `import type ${c.className} from '${c.importPath}';` + ).join('\n'); + + const entries = ALL_COMPONENTS.map( + (c) => ` '${c.tagName}': ${c.className};` + ).join('\n'); + + return `/** + * Vue type augmentations for Craft CMS web components. + * Provides IntrinsicElements declarations so Vue templates get + * type-checking and autocomplete for all craft-* custom elements. + * + * Auto-generated by: scripts/generate-vue-wrappers.js + */ + +${imports} + +declare module 'vue' { + interface IntrinsicElements { +${entries} + } +} + +export {}; +`; +} + +// ─── Main ─────────────────────────────────────────────────────────────────── + +export default function main() { + // Ensure output directory exists + mkdirSync(VUE_DIR, {recursive: true}); + + let count = 0; + + // Generate value-based wrappers + for (const component of VALUE_COMPONENTS) { + const content = generateValueWrapper(component); + const filePath = resolve(VUE_DIR, `${component.fileName}.vue`); + writeFileSync(filePath, content); + const declContent = generateValueDeclaration(component); + const declPath = resolve(VUE_DIR, `${component.fileName}.vue.d.ts`); + writeFileSync(declPath, declContent); + console.log(` Generated: ${VUE_DIR}/${component.fileName}.vue`); + count++; + } + + // Generate checked-based wrappers + for (const component of CHECKED_COMPONENTS) { + const content = generateCheckedWrapper(component); + const filePath = resolve(VUE_DIR, `${component.fileName}.vue`); + writeFileSync(filePath, content); + const declContent = generateCheckedDeclaration(component); + const declPath = resolve(VUE_DIR, `${component.fileName}.vue.d.ts`); + writeFileSync(declPath, declContent); + console.log(` Generated: ${VUE_DIR}/${component.fileName}.vue`); + count++; + } + + // Generate group wrappers + for (const component of GROUP_COMPONENTS) { + const content = generateGroupWrapper(component); + const filePath = resolve(VUE_DIR, `${component.fileName}.vue`); + writeFileSync(filePath, content); + const declContent = generateGroupDeclaration(component); + const declPath = resolve(VUE_DIR, `${component.fileName}.vue.d.ts`); + writeFileSync(declPath, declContent); + console.log(` Generated: ${VUE_DIR}/${component.fileName}.vue`); + count++; + } + + console.log(`\n ${count} Vue wrappers generated in ${VUE_DIR}/`); + + // Generate type augmentations + const types = generateTypeAugmentations(); + const typesPath = resolve(VUE_DIR, 'craft-elements.d.ts'); + writeFileSync(typesPath, types); + console.log(` Generated: ${VUE_DIR}/craft-elements.d.ts`); + + console.log('\nDone!'); +} + +main(); diff --git a/packages/craftcms-ui/scripts/utils.js b/packages/craftcms-cp/scripts/utils.js similarity index 100% rename from packages/craftcms-ui/scripts/utils.js rename to packages/craftcms-cp/scripts/utils.js diff --git a/packages/craftcms-cp/src/actions/index.ts b/packages/craftcms-cp/src/actions/index.ts new file mode 100644 index 00000000000..1e90fe236f7 --- /dev/null +++ b/packages/craftcms-cp/src/actions/index.ts @@ -0,0 +1,108 @@ +import type {VariantKey} from '@src/constants/variants'; + +export type BaseAction = + | {type: 'clipboard'; value: string} + | { + type: 'http'; + method?: 'GET' | 'POST' | 'PATCH' | 'DELETE'; + url: string; + body?: Record; + confirm?: string; + } + | { + type: 'event'; + name: string; + detail?: Record; + confirm?: string; + } + | {type: 'download'; url: string; filename?: string}; + +export type FeedbackData = { + message?: string; + // @TODO + // display?: 'inline' | 'toast'; +}; + +export type ActionFeedback = { + loading?: FeedbackData; + success?: FeedbackData; + error?: FeedbackData; +}; + +export interface BaseActionItem { + type?: 'button' | 'link' | 'hr'; + icon?: string; + label: string; +} + +export interface ActionItemLink { + type: 'link'; + href: string; + disabled?: boolean; +} + +export interface ActionItemHr { + type: 'hr'; +} + +export interface ActionItemButton extends BaseActionItem { + type?: 'button'; + action: BaseAction; + feedback?: ActionFeedback; // same feedback shape as before + disabled?: boolean; + variant?: VariantKey | string; +} + +export type ActionItem = ActionItemButton | ActionItemHr | ActionItemLink; + +export async function runAction(action: BaseAction): Promise { + switch (action.type) { + case 'clipboard': + await navigator.clipboard.writeText(action.value); + break; + + case 'http': + if (action.confirm) { + if (!confirm(action.confirm)) { + return; + } + } + + const response = await fetch(action.url, { + method: action.method || 'POST', + headers: {'Content-Type': 'application/json'}, + body: action.body ? JSON.stringify(action.body) : undefined, + }); + + if (!response.ok) { + const data = await response.json().catch(() => ({})); + throw new Error(data.message ?? 'Request failed'); + } + + break; + + case 'event': + if (action.confirm) { + if (!confirm(action.confirm)) { + return; + } + } + + window.dispatchEvent( + new CustomEvent(action.name, {detail: action.detail ?? {}}) + ); + break; + + case 'download': + const a = document.createElement('a'); + a.href = action.url; + a.download = action.filename ?? ''; + a.click(); + break; + + default: { + const unhandled: never = action; + throw new Error(`Unknown action type: ${(unhandled as BaseAction).type}`); + } + } +} diff --git a/packages/craftcms-ui/src/components/action-item/action-item.stories.ts b/packages/craftcms-cp/src/components/action-item/action-item.stories.ts similarity index 100% rename from packages/craftcms-ui/src/components/action-item/action-item.stories.ts rename to packages/craftcms-cp/src/components/action-item/action-item.stories.ts diff --git a/packages/craftcms-ui/src/components/action-item/action-item.styles.ts b/packages/craftcms-cp/src/components/action-item/action-item.styles.ts similarity index 96% rename from packages/craftcms-ui/src/components/action-item/action-item.styles.ts rename to packages/craftcms-cp/src/components/action-item/action-item.styles.ts index dbf5a8c322d..e271f8f23d4 100644 --- a/packages/craftcms-ui/src/components/action-item/action-item.styles.ts +++ b/packages/craftcms-cp/src/components/action-item/action-item.styles.ts @@ -5,10 +5,6 @@ export default css` display: contents; } - :host([hidden]) { - display: none; - } - .action-item { border-color: var(--c-color-border-quiet, transparent); color: var(--c-color-on-quiet, inherit); @@ -17,7 +13,6 @@ export default css` font: inherit; text-align: left; display: flex; - width: 100%; align-items: center; text-decoration: none; padding-inline: var(--c-spacing-sm); diff --git a/packages/craftcms-ui/src/components/action-item/action-item.ts b/packages/craftcms-cp/src/components/action-item/action-item.ts similarity index 80% rename from packages/craftcms-ui/src/components/action-item/action-item.ts rename to packages/craftcms-cp/src/components/action-item/action-item.ts index dae63b07ae1..84474e40e40 100644 --- a/packages/craftcms-ui/src/components/action-item/action-item.ts +++ b/packages/craftcms-cp/src/components/action-item/action-item.ts @@ -10,44 +10,25 @@ import { type ActionFeedback, type BaseAction, type FeedbackData, - normalizeAction, runAction, } from '@src/actions'; -import {Variant, type VariantValue} from '@src/constants/variants'; +import {Variant, type VariantKey} from '@src/constants/variants'; /** * @summary Either a link or button typically used in a menu. */ export default class CraftActionItem extends LitElement { static override styles = [variantsStyles, styles]; - - /** - * Delegate focus into the shadow root, so `host.focus()` (used by - * `craft-action-menu`'s keyboard navigation) lands on the internal - * button/anchor and native Enter/Space activation keeps working. - */ - static override shadowRootOptions = { - ...LitElement.shadowRootOptions, - delegatesFocus: true, - }; - @property() icon: string | null = null; - /** - * Optional Craft color name used to tint the item's icon. The icon renders - * with `currentColor`, so we set the icon element's `color` to a matching - * `--c-color-*` token. - */ - @property({attribute: 'icon-color'}) iconColor: string | null = null; @property() href: string | null = null; @property({type: Boolean}) disabled: boolean = false; - @property({reflect: true}) variant: VariantValue = Variant.Neutral; + @property({reflect: true}) variant: VariantKey = Variant.Neutral; @property({type: Boolean}) checked: boolean = false; @property({type: Boolean}) active: boolean = false; @property() type: 'button' | 'checkbox' = 'button'; - @property({type: Object}) action: BaseAction | string | null = null; + @property({type: Object}) action: BaseAction | null = null; @property({type: Object}) feedback: ActionFeedback | null = null; - @property({type: Number, attribute: 'feedback-duration'}) - feedbackDuration: number = 1000; + @property({type: Number}) feedbackDuration: number = 1000; @property() confirm: string | null = null; @state() private state: AsyncState = AsyncStates.Idle; @@ -116,7 +97,7 @@ export default class CraftActionItem extends LitElement { composed: true, detail: { state, - actionType: normalizeAction(this.action)?.type, + actionType: this.action?.type, ...detail, }, }) @@ -129,16 +110,14 @@ export default class CraftActionItem extends LitElement { return; } - const action = normalizeAction(this.action); - - if (event.type === 'click' && action) { + if (event.type === 'click' && this.action) { // Only show loading spinner for http requests - if (action.type === 'http') { + if (this.action.type === 'http') { this.setState(AsyncStates.Loading); } try { - await runAction(action, {trigger: this, sourceEvent: event}); + await runAction(this.action); this.setState(AsyncStates.Success, this.feedback?.success); } catch (error: any) { this.setState(AsyncStates.Error, { @@ -179,12 +158,7 @@ export default class CraftActionItem extends LitElement { return html` ${this.icon - ? html`` + ? html`` : nothing} `; diff --git a/packages/craftcms-cp/src/components/action-menu/action-menu.stories.ts b/packages/craftcms-cp/src/components/action-menu/action-menu.stories.ts new file mode 100644 index 00000000000..b1d835b49c7 --- /dev/null +++ b/packages/craftcms-cp/src/components/action-menu/action-menu.stories.ts @@ -0,0 +1,57 @@ +import type {Meta, StoryObj} from '@storybook/web-components-vite'; + +import {html} from 'lit'; + +import '../action-item/action-item.js'; +import './action-menu.js'; + +// More on how to set up stories at: https://storybook.js.org/docs/writing-stories +const meta = { + title: 'Components/Action Menu', + component: 'craft-action-menu', + argTypes: {}, + render: ({label, open}) => { + return html` + + + + Open Menu + + +
+ View in a new tab + Preview File +
+ Download + + Show in folder + + Edit asset +
+ + Open in Image Editor + +
+ + Replace + + + Remove + +
+
+ `; + }, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +// More on writing stories with args: https://storybook.js.org/docs/writing-stories/args +export const Default: Story = { + args: {}, +}; diff --git a/packages/craftcms-cp/src/components/action-menu/action-menu.ts b/packages/craftcms-cp/src/components/action-menu/action-menu.ts new file mode 100644 index 00000000000..4b60425557d --- /dev/null +++ b/packages/craftcms-cp/src/components/action-menu/action-menu.ts @@ -0,0 +1,106 @@ +import {css, html, LitElement} from 'lit'; +import {OverlayMixin, withDropdownConfig} from '@lion/ui/overlays.js'; +import {queryAssignedElements} from 'lit/decorators.js'; +import type CraftActionItem from '@src/components/action-item/action-item'; +import {uuid} from '@lion/ui/core.js'; + +/** + * @slot - Items to be rendered in the menu. + * @slot invoker - Element that triggers the menu. + * @slot backdrop - Element that covers the screen when the menu is open. + * @slot content - Content to be rendered inside the menu. + */ +export default class CraftActionMenu extends OverlayMixin(LitElement) { + static override styles = css` + ::slotted([slot='content']) { + font-size: var(--c-text-base); + font-weight: 400; + display: grid; + gap: var(--c-spacing-xs); + border: 1px solid var(--c-color-neutral-border-quiet); + border-radius: var(--c-radius-md); + background-color: var(--c-surface-overlay); + box-shadow: var(--c-shadow-sm); + padding: var(--c-spacing-sm); + min-width: calc(180rem / 16); + max-width: calc(320rem / 16); + } + + ::slotted(hr) { + margin: 0; + } + `; + + @queryAssignedElements({selector: 'craft-action-item'}) + actionItems!: CraftActionItem[]; + + @queryAssignedElements({slot: 'invoker'}) + invokerNodes!: HTMLElement[]; + + @queryAssignedElements({slot: 'content'}) + contentNodes!: HTMLElement[]; + + private uid: string; + + // @ts-ignore + _defineOverlayConfig() { + return { + ...withDropdownConfig(), + }; + } + + private _addEventListeners() { + // Close the menu when an item is clicked. + // @TODO is this good or bad? + this.actionItems.forEach((item) => { + item.addEventListener('click', (e) => { + e.target?.dispatchEvent(new Event('close-overlay', {bubbles: true})); + }); + }); + } + + private _setupInvoker() { + const firstInvoker = this.invokerNodes[0]; + if (firstInvoker) { + firstInvoker.setAttribute('id', `invoker-${this.uid}`); + firstInvoker.setAttribute('aria-controls', `content-${this.uid}`); + } + } + + private _setupContent() { + const firstContent = this.contentNodes[0]; + if (firstContent) { + firstContent.setAttribute('id', `content-${this.uid}`); + firstContent.setAttribute('role', 'none'); + } + } + + override _setupOverlayCtrl() { + super._setupOverlayCtrl(); + this._setupInvoker(); + this._setupContent(); + } + + override firstUpdated() { + this.uid = uuid(); + this._addEventListeners(); + } + + protected override render(): unknown { + return html` + + + + `; + } +} + +if (!customElements.get('craft-action-menu')) { + customElements.define('craft-action-menu', CraftActionMenu); +} + +declare global { + interface HTMLElementTagNameMap { + 'craft-action-menu': CraftActionMenu; + } +} diff --git a/resources/js/modules/auth/components/auth-challenge-form.ts b/packages/craftcms-cp/src/components/auth-challenge-form/auth-challenge-form.ts similarity index 90% rename from resources/js/modules/auth/components/auth-challenge-form.ts rename to packages/craftcms-cp/src/components/auth-challenge-form/auth-challenge-form.ts index 213152a5955..1b7f70a30f8 100644 --- a/resources/js/modules/auth/components/auth-challenge-form.ts +++ b/packages/craftcms-cp/src/components/auth-challenge-form/auth-challenge-form.ts @@ -1,7 +1,6 @@ import {css, html, LitElement} from 'lit'; import {property, query, state} from 'lit/decorators.js'; -import {actionClient, t} from '@craftcms/ui'; -import {registerCraftGlobals} from '@/common/craft-global'; +import {actionClient, t} from '@src/index'; /** @internal Module-private registry of PHP METHOD handle → element class. */ const _registry = new Map(); @@ -21,10 +20,9 @@ const _registry = new Map(); * @example * ```typescript * import {html} from 'lit'; + * import {CraftAuthChallengeForm} from '@craftcms/cp'; * - * const {AuthChallengeForm} = window.Craft; - * - * class MyPluginForm extends AuthChallengeForm { + * class MyPluginForm extends CraftAuthChallengeForm { * static METHOD = 'my-method'; * * protected override get endpoint() { @@ -41,7 +39,7 @@ const _registry = new Map(); * } * } * - * AuthChallengeForm.register('my-plugin-form', MyPluginForm); + * CraftAuthChallengeForm.register('my-plugin-form', MyPluginForm); * ``` * * @fires login-verified - Verification succeeded; bubbles to `craft-login-challenge`. Detail: `{ returnUrl: string }` @@ -243,12 +241,7 @@ export abstract class CraftAuthChallengeForm extends LitElement { elementClass: T ): void { if (!customElements.get(tagName)) { - // Cast required: the base class is abstract, but concrete subclasses - // passed here are valid custom element constructors. - customElements.define( - tagName, - elementClass as unknown as CustomElementConstructor - ); + customElements.define(tagName, elementClass); } // Cast required: TypeScript does not support abstract static properties, // so METHOD cannot be declared abstract on the base class. @@ -266,9 +259,3 @@ export abstract class CraftAuthChallengeForm extends LitElement { return _registry.has(method); } } - -// Plugin auth methods extend this class at runtime through the `Craft` global -// (bundling their own copy from an import would give them a separate, useless -// method registry). Assigned here so the global exists in any bundle that can -// render a challenge form. -registerCraftGlobals({AuthChallengeForm: CraftAuthChallengeForm}); diff --git a/packages/craftcms-ui/src/components/avatar/avatar.stories.ts b/packages/craftcms-cp/src/components/avatar/avatar.stories.ts similarity index 100% rename from packages/craftcms-ui/src/components/avatar/avatar.stories.ts rename to packages/craftcms-cp/src/components/avatar/avatar.stories.ts diff --git a/packages/craftcms-ui/src/components/avatar/avatar.styles.ts b/packages/craftcms-cp/src/components/avatar/avatar.styles.ts similarity index 100% rename from packages/craftcms-ui/src/components/avatar/avatar.styles.ts rename to packages/craftcms-cp/src/components/avatar/avatar.styles.ts diff --git a/packages/craftcms-ui/src/components/avatar/avatar.ts b/packages/craftcms-cp/src/components/avatar/avatar.ts similarity index 100% rename from packages/craftcms-ui/src/components/avatar/avatar.ts rename to packages/craftcms-cp/src/components/avatar/avatar.ts diff --git a/packages/craftcms-ui/src/components/badge-indicator/badge-indicator.stories.ts b/packages/craftcms-cp/src/components/badge-indicator/badge-indicator.stories.ts similarity index 100% rename from packages/craftcms-ui/src/components/badge-indicator/badge-indicator.stories.ts rename to packages/craftcms-cp/src/components/badge-indicator/badge-indicator.stories.ts diff --git a/packages/craftcms-ui/src/components/badge-indicator/badge-indicator.styles.ts b/packages/craftcms-cp/src/components/badge-indicator/badge-indicator.styles.ts similarity index 100% rename from packages/craftcms-ui/src/components/badge-indicator/badge-indicator.styles.ts rename to packages/craftcms-cp/src/components/badge-indicator/badge-indicator.styles.ts diff --git a/packages/craftcms-ui/src/components/badge-indicator/badge-indicator.ts b/packages/craftcms-cp/src/components/badge-indicator/badge-indicator.ts similarity index 92% rename from packages/craftcms-ui/src/components/badge-indicator/badge-indicator.ts rename to packages/craftcms-cp/src/components/badge-indicator/badge-indicator.ts index 58df8f0fbef..5a07cc593db 100644 --- a/packages/craftcms-ui/src/components/badge-indicator/badge-indicator.ts +++ b/packages/craftcms-cp/src/components/badge-indicator/badge-indicator.ts @@ -14,14 +14,13 @@ export default class CraftBadgeIndicator extends LitElement { static override styles = [styles]; /** Alternative text if the badge is not decorative */ - @property({attribute: 'alt-text'}) altText: string | null = null; + @property() altText: string | null = null; /** Displays a number on the badge. If using `badgeCount`, the `badgeCountSuffix` should also be used to describe what the number represents. */ - @property({attribute: 'badge-count'}) badgeCount: number | null = null; + @property() badgeCount: number | null = null; /** Visually hidden text that comes after the count to provide additional context. */ - @property({attribute: 'badge-count-suffix'}) badgeCountSuffix: string | null = - null; + @property() badgeCountSuffix: string | null = null; /** Theme variant of the badge indicator. Defaults to "primary" */ @property() variant: 'primary' | 'secondary' | 'inverse' = 'primary'; diff --git a/packages/craftcms-cp/src/components/breadcrumb-item/breadcrumb-item.ts b/packages/craftcms-cp/src/components/breadcrumb-item/breadcrumb-item.ts new file mode 100644 index 00000000000..f7f4a1c3ea0 --- /dev/null +++ b/packages/craftcms-cp/src/components/breadcrumb-item/breadcrumb-item.ts @@ -0,0 +1,43 @@ +import {css} from 'lit'; +import WaBreadcrumbItem from '@awesome.me/webawesome/dist/components/breadcrumb-item/breadcrumb-item.js'; + +export default class CraftBreadcrumbItem extends WaBreadcrumbItem { + static override get styles() { + return [ + WaBreadcrumbItem.styles, + css` + :host { + --wa-font-weight-action: 400; + --wa-space-s: var(--c-spacing-sm); + white-space: nowrap; + display: inline-flex; + align-items: center; + color: inherit; + } + + .start { + margin-inline-end: var(--c-spacing-sm); + } + + .end { + margin-inline-start: var(--c-spacing-sm); + } + + .separator { + color: var(--c-text-quiet); + margin: 0 var(--c-spacing-md); + } + `, + ]; + } +} + +if (!customElements.get('craft-breadcrumb-item')) { + customElements.define('craft-breadcrumb-item', CraftBreadcrumbItem); +} + +declare global { + interface HTMLElementTagNameMap { + 'craft-breadcrumb-item': CraftBreadcrumbItem; + } +} diff --git a/packages/craftcms-ui/src/components/breadcrumbs/breadcrumbs.stories.ts b/packages/craftcms-cp/src/components/breadcrumbs/breadcrumbs.stories.ts similarity index 100% rename from packages/craftcms-ui/src/components/breadcrumbs/breadcrumbs.stories.ts rename to packages/craftcms-cp/src/components/breadcrumbs/breadcrumbs.stories.ts diff --git a/packages/craftcms-ui/src/components/breadcrumbs/breadcrumbs.styles.ts b/packages/craftcms-cp/src/components/breadcrumbs/breadcrumbs.styles.ts similarity index 100% rename from packages/craftcms-ui/src/components/breadcrumbs/breadcrumbs.styles.ts rename to packages/craftcms-cp/src/components/breadcrumbs/breadcrumbs.styles.ts diff --git a/packages/craftcms-ui/src/components/breadcrumbs/breadcrumbs.ts b/packages/craftcms-cp/src/components/breadcrumbs/breadcrumbs.ts similarity index 100% rename from packages/craftcms-ui/src/components/breadcrumbs/breadcrumbs.ts rename to packages/craftcms-cp/src/components/breadcrumbs/breadcrumbs.ts diff --git a/packages/craftcms-cp/src/components/button-group/button-group.stories.ts b/packages/craftcms-cp/src/components/button-group/button-group.stories.ts new file mode 100644 index 00000000000..cb72219d66b --- /dev/null +++ b/packages/craftcms-cp/src/components/button-group/button-group.stories.ts @@ -0,0 +1,28 @@ +import type {Meta, StoryObj} from '@storybook/web-components-vite'; + +import {html} from 'lit'; + +import './button-group.js'; +import '../button/button.js'; + +// More on how to set up stories at: https://storybook.js.org/docs/writing-stories +const meta = { + title: 'Components/Button Group', + component: 'craft-button-group', + argTypes: {}, + render: (args) => html` + + One + Two + Three + + `, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +// More on writing stories with args: https://storybook.js.org/docs/writing-stories/args +export const Default: Story = { + args: {}, +}; diff --git a/packages/craftcms-cp/src/components/button-group/button-group.styles.ts b/packages/craftcms-cp/src/components/button-group/button-group.styles.ts new file mode 100644 index 00000000000..2c99be7d61c --- /dev/null +++ b/packages/craftcms-cp/src/components/button-group/button-group.styles.ts @@ -0,0 +1,23 @@ +import {css} from 'lit'; + +export default css` + :host { + display: flex; + gap: var(--c-spacing-1px); + } + + ::slotted(craft-button), + ::slotted(button) { + border-radius: 0; + } + + ::slotted(craft-button:first-child) { + border-start-start-radius: var(--c-radius-sm); + border-end-start-radius: var(--c-radius-sm); + } + + ::slotted(craft-button:last-child) { + border-start-end-radius: var(--c-radius-sm); + border-end-end-radius: var(--c-radius-sm); + } +`; diff --git a/packages/craftcms-cp/src/components/button-group/button-group.ts b/packages/craftcms-cp/src/components/button-group/button-group.ts new file mode 100644 index 00000000000..7538eb9a619 --- /dev/null +++ b/packages/craftcms-cp/src/components/button-group/button-group.ts @@ -0,0 +1,27 @@ +import {property} from 'lit/decorators.js'; +import {html, LitElement} from 'lit'; +import styles from './button-group.styles.js'; +import type {CSSResultGroup} from 'lit'; + +/** + * @summary Wrapper component used to group a set of buttons together. + * + * @slot - The default slot. + */ +export default class CraftButtonGroup extends LitElement { + static override styles: CSSResultGroup = [styles]; + + override render() { + return html``; + } +} + +if (!customElements.get('craft-button-group')) { + customElements.define('craft-button-group', CraftButtonGroup); +} + +declare global { + interface HTMLElementTagNameMap { + 'craft-button-group': CraftButtonGroup; + } +} diff --git a/packages/craftcms-cp/src/components/button/Docs.mdx b/packages/craftcms-cp/src/components/button/Docs.mdx new file mode 100644 index 00000000000..aba2d6ced23 --- /dev/null +++ b/packages/craftcms-cp/src/components/button/Docs.mdx @@ -0,0 +1,46 @@ +import {Canvas, Meta} from '@storybook/addon-docs/blocks'; +import * as ButtonStories from './button.stories'; + + + +# Button + +A button represents a clickable element that performs an action when activated. + + + +## Appearance + +`appearance` controls how visually prominent the button is. Use it to signal importance relative to other buttons on the page. + +- `solid` — Solid colored background. The highest-emphasis style. Use for the single most important action in a given context. +- `outline` — Transparent background with a colored border. Medium emphasis. Use for secondary actions alongside a solid button. +- `plain` — No background or border. Lowest emphasis. Use for tertiary or destructive actions that shouldn't draw attention on their own. + +## Variant + +`variant` controls the button's color, which communicates the _intent_ of the action — not how prominent it is. Appearance and variant are independent: any appearance can be combined with any variant. + +- `accent` — Blue. Use for the primary action on a page, such as Save or Confirm. +- `neutral` — Gray. The default. Use for everyday actions that don't carry a strong positive or negative meaning. +- `danger` — Red. Use for actions that delete, remove, or permanently change data. + + + +### Inherit + +`variant="inherit"` is a special case for buttons placed inside [Colorable](?path=/docs/concepts-colorable--docs) containers. Instead of applying its own color, the button picks up the color from its parent container. + +Avoid using the standard color variants (`accent`, `neutral`, `danger`) inside Colorable components — the two color systems can conflict and produce unexpected results. + +## Sizes + + + +## Icon buttons + + + +## Loading state + + diff --git a/packages/craftcms-cp/src/components/button/button.stories.ts b/packages/craftcms-cp/src/components/button/button.stories.ts new file mode 100644 index 00000000000..045c298eabe --- /dev/null +++ b/packages/craftcms-cp/src/components/button/button.stories.ts @@ -0,0 +1,126 @@ +import type {Meta, StoryObj} from '@storybook/web-components-vite'; + +import {html} from 'lit'; + +import './button.js'; +import '../icon/icon.js'; +import '../chip/chip.js'; +import {ButtonVariant, ButtonAppearance} from '@src/components/button/button'; + +const buttonVariants = Object.values(ButtonVariant); +const appearance = Object.values(ButtonAppearance); + +// More on how to set up stories at: https://storybook.js.org/docs/writing-stories +const meta = { + title: 'Components/Button', + component: 'craft-button', + parameters: { + layout: 'centered', + }, + args: { + label: 'Button', + appearance: 'solid', + loading: false, + variant: 'neutral', + }, + argTypes: { + appearance: { + control: {type: 'select'}, + options: appearance, + }, + loading: { + control: {type: 'boolean'}, + }, + }, + render: (args) => html` +
+ ${buttonVariants.map( + (variant) => html` +
+ ${variant ?? 'None'} solid + ${variant} outline + ${variant} plain +
+ ` + )} + + +
+ Chip Buttons + Outline + Plain +
+
+
+ `, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +// More on writing stories with args: https://storybook.js.org/docs/writing-stories/args +export const Default: Story = { + args: {}, +}; + +export const Variants: Story = { + args: { + variant: 'accent', + }, + argTypes: { + variant: { + control: {type: 'select'}, + options: buttonVariants, + }, + }, + render: () => + html`${buttonVariants.map( + (variant) => html` + ${variant} + ` + )}`, +}; + +export const Sizes: Story = { + args: {}, + render: (args) => html` +
+ ${['zero', 'small', 'medium', 'large'].map( + (size) => html`${size}` + )} +
+ `, +}; + +export const Icon: Story = { + args: {}, + render: (args) => html` +
+ + + + + + +
+ `, +}; + +export const Loading: Story = { + args: { + loading: true, + }, + render: (args) => html` + Submit + `, +}; diff --git a/packages/craftcms-cp/src/components/button/button.styles.ts b/packages/craftcms-cp/src/components/button/button.styles.ts new file mode 100644 index 00000000000..ea521b416b7 --- /dev/null +++ b/packages/craftcms-cp/src/components/button/button.styles.ts @@ -0,0 +1,328 @@ +import {css} from 'lit'; +export default css` + :host { + // Necessary to use variables here to override the default active style specificity + --_active-background-color: hsl( + from var(--c-color-fill-loud, var(--c-color-neutral-fill-normal)) h s + calc(l - 10) + ); + --_active-color: var(--c-color-on-loud); + cursor: pointer; + font: inherit; + display: inline-flex; + justify-content: center; + gap: var(--c-spacing-sm); + align-items: center; + border-radius: var(--c-button-radius, var(--c-form-control-radius)); + padding-inline: var( + --c-button-spacing-inline, + var(--c-form-control-spacing-inline) + ); + padding-block: 0; + width: auto; + min-height: var(--c-button-height, var(--c-size-control-md)); + min-width: var(--c-button-width, var(--c-size-control-md)); + white-space: nowrap; + border-width: var(--c-button-border-width, 1px); + border-style: var(--c-button-border-style, solid); + + /* Colorable styles */ + color: var(--c-color-on-loud, var(--c-color-neutral-on-loud)); + border-color: var( + --c-color-border-loud, + var(--c-color-neutral-border-loud) + ); + background-color: var( + --c-color-fill-loud, + var(--c-color-neutral-fill-loud) + ); + } + + @media (hover: hover) { + :host(:hover) { + background-color: hsl( + from var(--c-color-fill-loud, var(--c-button-default-fill)) h s + calc(l - 5) + ); + color: var(--c-color-on-loud); + } + } + + :host(:not(:disabled):not(.loading):active) { + color: var(--_active-color); + background-color: var(--_active-background-color); + } + + /* + Sizes + */ + :host([size~='zero']) { + min-width: 0; + min-height: 0; + padding-inline: 0; + } + + :host([size~='small']) { + padding-inline: var(--c-spacing-sm); + min-width: var(--c-size-control-sm); + min-height: var(--c-size-control-sm); + font-size: 0.9em; + } + + :host([size~='large']) { + padding-inline: var(--c-spacing-lg); + min-height: var(--c-size-control-lg); + min-width: var(--c-size-control-lg); + } + + :host([loading]) { + position: relative; + + .prefix, + .label, + .suffix { + visibility: hidden; + } + + craft-spinner { + --size: 1.25em; + position: absolute; + inset-block-start: calc(50% - var(--size) / 2); + inset-inline-start: calc(50% - var(--size) / 2); + } + } + + /* + Icon + */ + :host([icon]) { + aspect-ratio: 1; + padding-inline: 0; + padding-block: 0; + display: inline-flex; + flex-direction: column; + justify-content: center; + align-items: center; + line-height: 1; + } + + :host([icon][size~='small']) { + font-size: 0.8em; + } + + /* + Appearances + */ + :host([appearance~='inline']) { + display: inline; + appearance: none; + background-color: transparent; + border-color: currentColor; + color: inherit; + font: inherit; + padding: 0; + min-height: auto; + min-width: auto; + + &::before { + /* remove the sizer added by lion */ + display: none; + } + + .button-content { + padding: 0; + } + } + + :host([appearance='inline']:not(:disabled):not(.loading):hover) { + background-color: color-mix( + in oklab, + var(--c-color-fill-quiet, var(--c-button-default-fill)), + var(--c-color-mix-hover) + ); + color: var(--c-color-on-quiet); + } + + :host([appearance='inline']:not(:disabled):not(.loading):active) { + color: var(--c-color-on-quiet, var(--c-color-neutral-on-quiet)); + background-color: color-mix( + in oklab, + var(--c-color-fill-quiet, var(--c-color-neutral-fill-quiet)), + var(--c-color-mix-active) + ); + } + + /* Plain & Outline (Shared) */ + :host([appearance~='plain']), + :host([appearance~='outline']) { + background-color: transparent; + color: var(--c-color-on-quiet); + } + + :host([appearance~='plain']:hover), + :host([appearance~='outline']:hover) { + background-color: hsl( + from var(--c-color-fill-quiet, var(--c-color-neutral-fill-quiet)) h s + calc(l - 5) + ); + } + + :host([appearance~='plain']:active), + :host([appearance~='outline']:active) { + --_active-background-color: hsl( + from var(--c-color-fill-quiet, var(--c-color-neutral-fill-quiet)) h s + calc(l - 8) + ); + --_active-color: var(--c-color-on-quiet, var(--c-color-neutral-on-quiet)); + } + + /* Plain */ + :host([appearance~='plain']) { + border-color: transparent; + color: inherit; + + &:before { + display: none; + } + } + + :host([appearance='plain']:not(:disabled):not(.loading):hover) { + background-color: color-mix( + in oklab, + var(--c-color-fill-quiet, var(--c-button-default-fill)), + var(--c-color-mix-hover) + ); + color: var(--c-color-on-quiet); + } + + :host([appearance='plain']:not(:disabled):not(.loading):active) { + color: var(--c-color-on-quiet, var(--c-color-neutral-on-quiet)); + background-color: color-mix( + in oklab, + var(--c-color-fill-quiet, var(--c-color-neutral-fill-quiet)), + var(--c-color-mix-active) + ); + } + + /* Filled */ + :host([appearance~='solid']) { + background-color: var( + --c-color-fill-loud, + var(--c-color-neutral-fill-loud) + ); + border-color: transparent; + color: var(--c-color-on-loud, var(--c-color-neutral-on-loud)); + } + + :host([appearance='solid']:hover) { + background-color: hsl( + from var(--c-color-fill-loud, var(--c-color-neutral-fill-loud)) h s + calc(l - 5) + ); + color: var(--c-color-on-loud, var(--c-color-neutral-on-loud)); + } + + :host([appearance='solid']:active) { + --_active-background-color: hsl( + from var(--c-color-fill-loud, var(--c-color-neutral-fill-loud)) h s + calc(l - 10) + ); + --_active-color: var(--c-color-on-loud, var(--c-color-neutral-on-loud)); + } + + /* Outline */ + :host([appearance='outline']) { + border-color: var(--c-color-border-loud); + } + + /* + Variants (aka fill colors) + */ + :host([variant~='accent']) { + --c-color-fill-loud: var(--c-color-accent-fill-loud); + --c-color-fill-normal: var(--c-color-accent-fill-normal); + --c-color-fill-quiet: var(--c-color-accent-fill-quiet); + --c-color-border-loud: var(--c-color-accent-border-loud); + --c-color-border-normal: var(--c-color-accent-border-normal); + --c-color-border-quiet: var(--c-color-accent-border-quiet); + --c-color-on-loud: var(--c-color-accent-on-loud); + --c-color-on-normal: var(--c-color-accent-on-normal); + --c-color-on-quiet: var(--c-color-accent-on-quiet); + } + + :host([variant='neutral']) { + --c-color-fill-loud: var(--c-color-neutral-fill-loud); + --c-color-fill-normal: var(--c-color-neutral-fill-normal); + --c-color-fill-quiet: var(--c-color-neutral-fill-quiet); + --c-color-border-loud: var(--c-color-neutral-border-loud); + --c-color-border-normal: var(--c-color-neutral-border-normal); + --c-color-border-quiet: var(--c-color-neutral-border-quiet); + --c-color-on-loud: var(--c-color-neutral-on-loud); + --c-color-on-normal: var(--c-color-neutral-on-normal); + --c-color-on-quiet: var(--c-color-neutral-on-quiet); + } + + :host([variant~='danger']) { + --c-color-fill-loud: var(--c-color-danger-fill-loud); + --c-color-fill-normal: var(--c-color-danger-fill-normal); + --c-color-fill-quiet: var(--c-color-danger-fill-quiet); + --c-color-border-loud: var(--c-color-danger-border-loud); + --c-color-border-normal: var(--c-color-danger-border-normal); + --c-color-border-quiet: var(--c-color-danger-border-quiet); + --c-color-on-loud: var(--c-color-danger-on-loud); + --c-color-on-normal: var(--c-color-danger-on-normal); + --c-color-on-quiet: var(--c-color-danger-on-quiet); + } + + .button-content { + display: flex; + align-items: center; + gap: 0.25em; + width: 100%; + } + + .prefix, + .suffix { + display: inline-flex; + flex-direction: column; + justify-content: center; + align-items: center; + } + + .button-content--start { + justify-content: start; + } + + .button-content--end { + justify-content: end; + } + + craft-button-group craft-button { + border-radius: 0; + } + + craft-button-reset, + craft-button-submit { + /* Temporarily make it very obvious when these are used */ + outline: 10px solid var(--c-button-danger-border); + } + + .a11y-error { + position: relative; + outline: 2px solid var(--c-color-danger-border-normal) !important; + background-color: rgba(255, 0, 0, 0.1) !important; + + &:after { + content: '!'; + position: absolute; + display: inline-flex; + font-size: calc(11rem / 16); + padding: 0.125em 0.5em 0.25em; + inset-block-start: -2px; + inset-inline-start: 0; + background: var(--c-color-danger-bg-emphasis); + color: white; + transform: translateX(-100%); + } + } +`; diff --git a/packages/craftcms-cp/src/components/button/button.ts b/packages/craftcms-cp/src/components/button/button.ts new file mode 100644 index 00000000000..3f62f4f93fb --- /dev/null +++ b/packages/craftcms-cp/src/components/button/button.ts @@ -0,0 +1,132 @@ +import {LionButtonSubmit} from '@lion/ui/button.js'; +import {html, nothing} from 'lit'; +import {property, state} from 'lit/decorators.js'; +import styles from './button.styles.js'; +import '../spinner/spinner.js'; +import '../icon/icon.js'; +import {computeAccessibleName} from 'dom-accessibility-api'; +import {classMap} from 'lit/directives/class-map.js'; + +export const ButtonAppearance = { + Solid: 'solid', + Outline: 'outline', + Plain: 'plain', +} as const; + +export const ButtonVariant = { + Accent: 'accent', + Neutral: 'neutral', + Danger: 'danger', +} as const; + +export type ButtonVariant = (typeof ButtonVariant)[keyof typeof ButtonVariant]; +export type ButtonAppearance = + (typeof ButtonAppearance)[keyof typeof ButtonAppearance]; + +/** + * @summary Interactive element that triggers an action or event. + * @since 1.0 + * + * @dependency craft-spinner + * + * @slot - The button's label. + * @slot prefix - Content to display before the label (typically an icon). + * @slot suffix - Content to display after the label (typically an icon). + * + * @csspart content - The button's content wrapper. + * @csspart prefix - The button's prefix slot. + * @csspart label - The button's label slot. + * @csspart suffix - The button's suffix slot. + * @csspart spinner - Spinner that shows when the button is in a loading state. + */ +export default class CraftButton extends LionButtonSubmit { + static override get styles() { + return [...super.styles, styles]; + } + + override async firstUpdated(changedProperties: Map) { + super.firstUpdated(changedProperties); + + await this.updateComplete; + + const childComponents = this.querySelectorAll('craft-icon, craft-spinner'); + await Promise.all( + Array.from(childComponents).map((child: any) => child.updateComplete) + ); + + if (!this.accessibleName) { + this.accessibleName = computeAccessibleName(this); + } + + this._hasAccessibilityError = + !this.accessibleName || this.accessibleName.trim() === ''; + } + + /** The computed accessible name */ + @property() accessibleName: string; + + /** Visual appearance of the button */ + @property({reflect: true}) appearance: ButtonAppearance = 'solid'; + + /** + * Theme variant of the button. Defaults to "neutral" + * + * Accent: The primary action on a page + * Neutral: Used in most cases + * Danger: Indicates a dangerous action, when data will be removed or deleted + * Inherit: Useful for colorable elements, button will reflect the parent theme + */ + @property({reflect: true}) variant: ButtonVariant = 'neutral'; + + /** Size of the button. Defaults to "medium" */ + @property({reflect: true}) size: 'zero' | 'small' | 'medium' | 'large' = + 'medium'; + + /** Show a spinner instead of the label */ + @property({reflect: true, type: Boolean}) loading: boolean = false; + + /** Set align-items for the content */ + @property() align: 'start' | 'end' | 'center' = 'center'; + + @property() icon: string | null = null; + + @state() + private _hasAccessibilityError: boolean = false; + + override render() { + return html` + + +
+ + ${this.icon + ? html`` + : nothing} + + + +
+ ${this.loading + ? html`` + : nothing} + `; + } +} + +if (!customElements.get('craft-button')) { + customElements.define('craft-button', CraftButton); +} + +declare global { + interface HTMLElementTagNameMap { + 'craft-button': CraftButton; + } +} diff --git a/packages/craftcms-ui/src/components/callout/callout.stories.ts b/packages/craftcms-cp/src/components/callout/callout.stories.ts similarity index 100% rename from packages/craftcms-ui/src/components/callout/callout.stories.ts rename to packages/craftcms-cp/src/components/callout/callout.stories.ts diff --git a/packages/craftcms-ui/src/components/callout/callout.styles.ts b/packages/craftcms-cp/src/components/callout/callout.styles.ts similarity index 100% rename from packages/craftcms-ui/src/components/callout/callout.styles.ts rename to packages/craftcms-cp/src/components/callout/callout.styles.ts diff --git a/packages/craftcms-ui/src/components/callout/callout.ts b/packages/craftcms-cp/src/components/callout/callout.ts similarity index 81% rename from packages/craftcms-ui/src/components/callout/callout.ts rename to packages/craftcms-cp/src/components/callout/callout.ts index 583a983bd39..85ad0193de8 100644 --- a/packages/craftcms-ui/src/components/callout/callout.ts +++ b/packages/craftcms-cp/src/components/callout/callout.ts @@ -2,22 +2,21 @@ import {type CSSResultGroup, html, LitElement, nothing} from 'lit'; import {property} from 'lit/decorators.js'; import styles from './callout.styles.js'; import '../icon/icon.js'; -import {Appearance, type AppearanceValue} from '@src/constants/appearances'; -import {Variant, type VariantValue} from '@src/constants/variants'; +import {Appearance, type AppearanceKey} from '@src/constants/appearances'; +import {Variant, type VariantKey} from '@src/constants/variants'; import variantsStyles from '@src/styles/variants.styles.js'; export default class CraftCallout extends LitElement { static override styles: CSSResultGroup = [variantsStyles, styles]; /** Variant style of the callout */ - @property({reflect: true}) variant: VariantValue = Variant.Neutral; + @property({reflect: true}) variant: VariantKey = Variant.Neutral; /** * Appearance style of the callout * @TODO maybe drop "outline"? */ - @property({reflect: true}) appearance: AppearanceValue = - Appearance.OutlineFill; + @property({reflect: true}) appearance: AppearanceKey = Appearance.OutlineFill; /** Title of the callout */ @property() override title: string = ''; @@ -25,8 +24,6 @@ export default class CraftCallout extends LitElement { /** Icon to display in the callout */ @property() icon: string | null = null; - @property({type: Boolean, attribute: 'hide-icon'}) hideIcon: boolean = false; - @property({reflect: true}) rounded: 'all' | 'start' | 'end' | 'none' = 'all'; @@ -49,8 +46,10 @@ export default class CraftCallout extends LitElement { } protected override render(): unknown { + const hasIcon = !!this.icon || !!this.querySelector('[slot="icon"]'); + return html` - ${!this.hideIcon + ${hasIcon ? html` html` + + Cards are really pretty boring, their mostly available as a convienience + for layout. + + `, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +// More on writing stories with args: https://storybook.js.org/docs/writing-stories/args +export const Default: Story = { + args: {}, +}; diff --git a/packages/craftcms-cp/src/components/card/card.styles.ts b/packages/craftcms-cp/src/components/card/card.styles.ts new file mode 100644 index 00000000000..55b8c97b8fb --- /dev/null +++ b/packages/craftcms-cp/src/components/card/card.styles.ts @@ -0,0 +1,57 @@ +import {css} from 'lit'; + +export default css` + :host { + display: block; + } + + .card { + color: var(--c-card-color, var(--c-color-neutral-on-quiet)); + background-color: var(--c-card-fill, var(--c-color-neutral-fill-quiet)); + border: 1px solid var(--c-card-border, var(--c-color-neutral-border-quiet)); + border-radius: var(--c-card-radius, var(--c-radius-md)); + box-shadow: var(--c-card-shadow, var(--c-shadow-sm)); + position: relative; + } + + .card__header, + .card__footer { + font-size: 0.875em; + padding-block: var(--c-card-padding-block, var(--c-spacing-sm)); + padding-inline-start: var(--c-card-padding-inline, var(--c-spacing-md)); + padding-inline-end: var(--c-card-padding-inline, var(--c-spacing-sm)); + color: var(--c-card-bars-text, var(--c-color-neutral-on-quiet)); + background-color: var( + --c-card-bars-fill, + var(--c-color-neutral-fill-quiet) + ); + border-width: 0; + border-color: var(--c-card-border, var(--c-color-neutral-border-quiet)); + border-style: solid; + } + + .card__footer { + border-block-start-width: 1px; + border-end-start-radius: var(--c-card-radius, var(--c-radius-md)); + border-end-end-radius: var(--c-card-radius, var(--c-radius-md)); + } + + .card__header { + border-start-start-radius: var(--c-card-radius, var(--c-radius-md)); + border-start-end-radius: var(--c-card-radius, var(--c-radius-md)); + border-block-end-width: 1px; + display: flex; + justify-content: space-between; + align-items: center; + } + + .card__body { + padding-inline: var(--c-card-padding-inline, var(--c-spacing-md)); + padding-block: var(--c-card-padding-block, var(--c-spacing-md)); + } + + .card__actions { + display: flex; + gap: var(--c-spacing-sm); + } +`; diff --git a/packages/craftcms-cp/src/components/card/card.ts b/packages/craftcms-cp/src/components/card/card.ts new file mode 100644 index 00000000000..19cad8bcebb --- /dev/null +++ b/packages/craftcms-cp/src/components/card/card.ts @@ -0,0 +1,67 @@ +import {property} from 'lit/decorators.js'; +import {html, LitElement, nothing} from 'lit'; +import styles from './card.styles.js'; +import type {CSSResultGroup} from 'lit'; + +/** + * @summary Short summary of the component's intended use. + * + * @event craft-event-name - Emitted as an example. + * + * @slot - The default slot. + * @slot example - An example slot. + * + * @csspart base - The component's base wrapper. + * + * @cssproperty --example - An example CSS custom property. + */ +export default class CraftCard extends LitElement { + static override styles: CSSResultGroup = [styles]; + + /** Label for the card. */ + @property() label = ''; + + override render() { + const hasSlottedHeader = + !!this.label || + !!this.querySelector('[slot="header"]') || + !!this.querySelector('[slot="label"]') || + !!this.querySelector('[slot="actions"]'); + const hasSlottedFooter = !!this.querySelector('[slot="footer"]'); + + return html` +
+
+ ${hasSlottedHeader + ? html`
+ + ${this.label} + + +
` + : nothing} + +
+ +
+ + ${hasSlottedFooter + ? html`` + : nothing} +
+
+ `; + } +} + +if (!customElements.get('craft-card')) { + customElements.define('craft-card', CraftCard); +} + +declare global { + interface HTMLElementTagNameMap { + 'craft-card': CraftCard; + } +} diff --git a/packages/craftcms-cp/src/components/checkbox-group/checkbox-group.ts b/packages/craftcms-cp/src/components/checkbox-group/checkbox-group.ts new file mode 100644 index 00000000000..c673f26e4ae --- /dev/null +++ b/packages/craftcms-cp/src/components/checkbox-group/checkbox-group.ts @@ -0,0 +1,28 @@ +import {LionCheckboxGroup} from '@lion/ui/checkbox-group.js'; +import {css} from 'lit'; + +export default class CraftCheckboxGroup extends LionCheckboxGroup { + static override get styles() { + return [ + ...LionCheckboxGroup.styles, + css` + .input-group { + display: grid; + gap: var(--c-spacing-sm); + } + + .form-field__group-two { + margin-top: var(--c-spacing-sm); + } + + ::slotted(label) { + font-weight: bold; + } + `, + ]; + } +} + +if (!customElements.get('craft-checkbox-group')) { + customElements.define('craft-checkbox-group', CraftCheckboxGroup); +} diff --git a/packages/craftcms-ui/src/components/checkbox-indeterminate/checkbox-indeterminate.stories.ts b/packages/craftcms-cp/src/components/checkbox-indeterminate/checkbox-indeterminate.stories.ts similarity index 100% rename from packages/craftcms-ui/src/components/checkbox-indeterminate/checkbox-indeterminate.stories.ts rename to packages/craftcms-cp/src/components/checkbox-indeterminate/checkbox-indeterminate.stories.ts diff --git a/packages/craftcms-ui/src/components/checkbox-indeterminate/checkbox-indeterminate.ts b/packages/craftcms-cp/src/components/checkbox-indeterminate/checkbox-indeterminate.ts similarity index 100% rename from packages/craftcms-ui/src/components/checkbox-indeterminate/checkbox-indeterminate.ts rename to packages/craftcms-cp/src/components/checkbox-indeterminate/checkbox-indeterminate.ts diff --git a/packages/craftcms-ui/src/components/checkbox/checkbox.stories.ts b/packages/craftcms-cp/src/components/checkbox/checkbox.stories.ts similarity index 75% rename from packages/craftcms-ui/src/components/checkbox/checkbox.stories.ts rename to packages/craftcms-cp/src/components/checkbox/checkbox.stories.ts index 7a334d2cb65..a235698cd54 100644 --- a/packages/craftcms-ui/src/components/checkbox/checkbox.stories.ts +++ b/packages/craftcms-cp/src/components/checkbox/checkbox.stories.ts @@ -24,13 +24,3 @@ type Story = StoryObj; export const Default: Story = { args: {}, }; - -export const NoLabel: Story = { - render: function () { - return html``; - }, -}; diff --git a/packages/craftcms-cp/src/components/checkbox/checkbox.ts b/packages/craftcms-cp/src/components/checkbox/checkbox.ts new file mode 100644 index 00000000000..b17c5ad13e4 --- /dev/null +++ b/packages/craftcms-cp/src/components/checkbox/checkbox.ts @@ -0,0 +1,56 @@ +import {LionCheckbox} from '@lion/ui/checkbox-group.js'; +import {css} from 'lit'; + +export default class CraftCheckbox extends LionCheckbox { + static override get styles() { + return [ + ...LionCheckbox.styles, + css` + /* same as radio, potentially consolidate */ + :host { + --_gap-x: var(--gap-x, var(--c-spacing-md)); + display: grid; + align-items: center; + gap: 0 var(--_gap-x); + grid-template-areas: 'input label' '. help-text'; + grid-template-columns: auto 1fr; + grid-template-rows: repeat(2, auto); + } + + ::slotted(label) { + font: inherit; + grid-area: label; + } + + ::slotted([slot='input']) { + background-color: var(--c-input-fill, var(--c-form-control-fill)); + border-width: var( + --c-input-border-width, + var(--c-form-control-border-width) + ); + border-style: var( + --c-input-border-style, + var(--c-form-control-border-style) + ); + border-color: var( + --c-input-border-color, + var(--c-form-control-border-color) + ); + border-radius: var(--c-input-radius, var(--c-radius-sm)); + width: var(--c-size-control-2xs); + height: var(--c-size-control-2xs); + } + + .choice-field__help-text { + font-size: 1em; + color: var(--c-text-quiet); + grid-area: help-text; + } + `, + ]; + } +} + +if (!customElements.get('craft-checkbox')) { + customElements.define('craft-checkbox', CraftCheckbox); +} diff --git a/packages/craftcms-ui/src/components/chip/chip.stories.ts b/packages/craftcms-cp/src/components/chip/chip.stories.ts similarity index 76% rename from packages/craftcms-ui/src/components/chip/chip.stories.ts rename to packages/craftcms-cp/src/components/chip/chip.stories.ts index 3a93695b529..02deef05e31 100644 --- a/packages/craftcms-ui/src/components/chip/chip.stories.ts +++ b/packages/craftcms-cp/src/components/chip/chip.stories.ts @@ -29,20 +29,7 @@ export const PrefixAndSuffix: Story = { This is a chip - - - - - `, -}; - -export const Thumbnail: Story = { - args: {}, - render: (args) => html` - - - This is a chip - + @@ -63,7 +50,7 @@ export const SuffixOnly: Story = { args: {}, render: (args) => html` - + This is a chip @@ -81,7 +68,11 @@ export const Colors: Story = { ([name, value]) => html` ${name} - Button ` diff --git a/packages/craftcms-cp/src/components/chip/chip.styles.ts b/packages/craftcms-cp/src/components/chip/chip.styles.ts new file mode 100644 index 00000000000..5889249eec8 --- /dev/null +++ b/packages/craftcms-cp/src/components/chip/chip.styles.ts @@ -0,0 +1,78 @@ +import {css} from 'lit'; + +export default css` + :host { + display: contents; + } + + .cp-chip { + --_min-height: var(--c-chip-height, var(--c-size-control-sm)); + display: inline-flex; + min-width: auto; + border-radius: var(--c-chip-radius, var(--c-radius-md)); + padding-inline: var(--c-chip-spacing-inline, 0); + padding-block: var(--c-chip-spacing-block, var(--c-spacing-sm)); + align-items: start; + box-shadow: var(--c-chip-shadow, var(--c-shadow-sm)); + + /* colorable styles */ + color: var(--c-color-on-quiet, var(--c-color-neutral-on-quiet)); + border-width: var(--c-chip-border-width, 1px); + border-style: var(--c-chip-border-style, solid); + border-color: var( + --c-color-border-quiet, + var(--c-color-neutral-border-quiet) + ); + background-color: var(--c-color-fill-quiet, var(--c-surface-raised)); + } + + .cp-chip__body ::slotted(a) { + text-decoration: none; + font-weight: bold; + display: flex; + } + + .cp-chip[appearance='plain'], + .cp-chip--plain { + padding-block: 0; + padding-inline: 0; + border-color: transparent; + background-color: transparent; + box-shadow: none; + } + + .cp-chip[size='small'], + .cp-chip--small { + --_min-height: var(--c-size-control-sm); + padding-block: calc(var(--c-spacing-xs) / 2); + } + + .cp-chip[size='medium'], + .cp-chip--medium { + padding-block: 0; + min-height: var(--c-size-control-md); + } + + .cp-chip__prefix, + .cp-chip__body, + .cp-chip__suffix { + display: inline-flex; + flex-direction: column; + min-height: var(--_min-height); + } + + .cp-chip__body { + flex: 1 1 auto; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } + + .cp-chip__prefix { + padding-inline: calc(var(--c-spacing-md) / 2); + } + + .cp-chip__suffix { + padding-inline-start: var(--c-spacing-md); + } +`; diff --git a/packages/craftcms-cp/src/components/chip/chip.ts b/packages/craftcms-cp/src/components/chip/chip.ts new file mode 100644 index 00000000000..cdf57e9ebf7 --- /dev/null +++ b/packages/craftcms-cp/src/components/chip/chip.ts @@ -0,0 +1,84 @@ +import {property} from 'lit/decorators.js'; +import type {CSSResultGroup} from 'lit'; +import {html, LitElement, nothing} from 'lit'; +import styles from './chip.styles.js'; +import {classMap} from 'lit/directives/class-map.js'; + +/** + * @summary Short summary of the component's intended use. + * + * @event craft-event-name - Emitted as an example. + * + * @slot - The default slot. + * @slot example - An example slot. + * + * @csspart base - The component's base wrapper. + * + * @cssproperty --example - An example CSS custom property. + */ +export default class CraftChip extends LitElement { + static override styles: CSSResultGroup = [styles]; + + /** Size of the chip. */ + @property() size: 'small' | 'medium' | 'large' | '' = ''; + + /** Variant of the chip. `plain` will render with no border or padding */ + @property() variant: 'plain' | '' = ''; + + /** Shortcut for adding an icon as the prefix */ + @property() icon: string | null = null; + + renderPrefix() { + return html`
+ + + ${this.icon + ? html`` + : nothing} + + +
`; + } + + override render() { + // query the element Light DOM children for slotted elements + const renderPrefix = + !!this.querySelector('[slot="prefix"]') || + !!this.querySelector('[slot="icon"]') || + this.icon; + const renderSuffix = !!this.querySelector('[slot="suffix"]'); + + return html` +
+ ${renderPrefix ? this.renderPrefix() : nothing} +
+ +
+ ${renderSuffix + ? html`
+ +
` + : nothing} +
+ `; + } +} + +if (!customElements.get('craft-chip')) { + customElements.define('craft-chip', CraftChip); +} + +declare global { + interface HTMLElementTagNameMap { + 'craft-chip': CraftChip; + } +} diff --git a/packages/craftcms-cp/src/components/combobox/combobox.stories.ts b/packages/craftcms-cp/src/components/combobox/combobox.stories.ts new file mode 100644 index 00000000000..03cedada5ad --- /dev/null +++ b/packages/craftcms-cp/src/components/combobox/combobox.stories.ts @@ -0,0 +1,52 @@ +import type {Meta, StoryObj} from '@storybook/web-components-vite'; +import {html} from 'lit'; +import './combobox.js'; +import '../option/option.js'; +import '../indicator/indicator.js'; + +const meta = { + title: 'Controls/Combobox', + component: 'craft-combobox', + args: {}, + render: function () { + return html` + + United States + Canada + Mexico + United Kingdom + France + Germany + + `; + }, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: {}, +}; + +export const RichOptions: Story = { + args: {}, + render: function () { + return html` + + +
+ + Online +
+
+ +
+ + Offline +
+
+
+ `; + }, +}; diff --git a/packages/craftcms-cp/src/components/combobox/combobox.styles.ts b/packages/craftcms-cp/src/components/combobox/combobox.styles.ts new file mode 100644 index 00000000000..8cfb9704582 --- /dev/null +++ b/packages/craftcms-cp/src/components/combobox/combobox.styles.ts @@ -0,0 +1,51 @@ +import {css} from 'lit'; +import {baseFieldStyles, baseInputStyles} from '../../styles/form.styles'; + +export default css` + ${baseFieldStyles} + + :host { + width: 100%; + } + + ::slotted(.form-control) { + width: 100%; + height: 100%; + appearance: none; + border: 0; + min-height: none; + padding-inline: var(--c-input-spacing-inline) + calc(var(--c-input-spacing-inline) * 1.5 + 1em); + border-radius: var(--c-input-radius); + } + + ::slotted([slot='listbox']) { + display: grid; + gap: var(--c-spacing-xs); + border: 1px solid var(--c-color-neutral-border-quiet); + border-radius: var(--c-radius-md); + background-color: var(--c-surface-overlay); + box-shadow: var(--c-shadow-sm); + padding: var(--c-spacing-sm); + } + + .input-group__input { + ${baseInputStyles} + padding-inline: 0; + position: relative; + min-height: calc(var(--c-input-height, var(--c-size-control-md)) - 2px); + } + + .input-group__container { + border: 0; + } + + .indicator { + position: absolute; + inset-block-start: 50%; + inset-inline-end: var(--c-input-spacing-inline); + transform: translateY(-50%); + width: 1em; + height: 1em; + } +`; diff --git a/packages/craftcms-cp/src/components/combobox/combobox.ts b/packages/craftcms-cp/src/components/combobox/combobox.ts new file mode 100644 index 00000000000..e859daad2bd --- /dev/null +++ b/packages/craftcms-cp/src/components/combobox/combobox.ts @@ -0,0 +1,63 @@ +import {LionCombobox} from '@lion/ui/combobox.js'; +import {html} from 'lit'; +import styles from './combobox.styles.js'; +import type CraftOption from '../option/option.js'; +import '../option/option.js'; +import '../icon/icon.js'; + +export default class CraftCombobox extends LionCombobox { + static override get styles() { + return [...super.styles, styles]; + } + + constructor() { + super(); + // Configure validators on construction + this.defaultValidators = []; + } + + // eslint-disable-next-line class-methods-use-this + override _inputGroupInputTemplate() { + return html` +
+ + +
+ `; + } + + override parser(value: string | Array) { + if (value !== '') { + return value; + } + + return super.parser(value); + } + + /** + * Override to use the option's text content instead of choiceValue + */ + override _getTextboxValueFromOption(option: CraftOption) { + if (option) { + // Return the option's text content instead of choiceValue + return option.textContent?.trim() || ''; + } + + // @ts-ignore Lion's code handles `null` but the types don't account for it + return super._getTextboxValueFromOption(option); + } +} + +if (!customElements.get('craft-combobox')) { + customElements.define('craft-combobox', CraftCombobox); +} + +declare global { + interface HTMLElementTagNameMap { + 'craft-combobox': CraftCombobox; + } +} diff --git a/packages/craftcms-ui/src/components/copy-attribute/copy-attribute.stories.ts b/packages/craftcms-cp/src/components/copy-attribute/copy-attribute.stories.ts similarity index 100% rename from packages/craftcms-ui/src/components/copy-attribute/copy-attribute.stories.ts rename to packages/craftcms-cp/src/components/copy-attribute/copy-attribute.stories.ts diff --git a/packages/craftcms-ui/src/components/copy-attribute/copy-attribute.styles.ts b/packages/craftcms-cp/src/components/copy-attribute/copy-attribute.styles.ts similarity index 95% rename from packages/craftcms-ui/src/components/copy-attribute/copy-attribute.styles.ts rename to packages/craftcms-cp/src/components/copy-attribute/copy-attribute.styles.ts index badf753fea3..c638dfe8e2f 100644 --- a/packages/craftcms-ui/src/components/copy-attribute/copy-attribute.styles.ts +++ b/packages/craftcms-cp/src/components/copy-attribute/copy-attribute.styles.ts @@ -34,11 +34,11 @@ export default css` } .copy-attribute::part(button):not(.copy-attribute--success):not( - .copy-attribute--error - ):hover, + .copy-attribute--error + ):hover, .copy-attribute::part(button):not(.copy-attribute--success):not( - .copy-attribute--error - ):focus { + .copy-attribute--error + ):focus { border-color: var(--c-color-neutral-border-quiet); color: var(--c-text-default); } diff --git a/packages/craftcms-ui/src/components/copy-attribute/copy-attribute.ts b/packages/craftcms-cp/src/components/copy-attribute/copy-attribute.ts similarity index 100% rename from packages/craftcms-ui/src/components/copy-attribute/copy-attribute.ts rename to packages/craftcms-cp/src/components/copy-attribute/copy-attribute.ts diff --git a/packages/craftcms-ui/src/components/copy-button/copy-button.stories.ts b/packages/craftcms-cp/src/components/copy-button/copy-button.stories.ts similarity index 100% rename from packages/craftcms-ui/src/components/copy-button/copy-button.stories.ts rename to packages/craftcms-cp/src/components/copy-button/copy-button.stories.ts diff --git a/packages/craftcms-ui/src/components/copy-button/copy-button.styles.ts b/packages/craftcms-cp/src/components/copy-button/copy-button.styles.ts similarity index 100% rename from packages/craftcms-ui/src/components/copy-button/copy-button.styles.ts rename to packages/craftcms-cp/src/components/copy-button/copy-button.styles.ts diff --git a/packages/craftcms-ui/src/components/copy-button/copy-button.ts b/packages/craftcms-cp/src/components/copy-button/copy-button.ts similarity index 97% rename from packages/craftcms-ui/src/components/copy-button/copy-button.ts rename to packages/craftcms-cp/src/components/copy-button/copy-button.ts index 2d1def68141..29438d147a2 100644 --- a/packages/craftcms-ui/src/components/copy-button/copy-button.ts +++ b/packages/craftcms-cp/src/components/copy-button/copy-button.ts @@ -53,7 +53,7 @@ export default class CraftCopyButton extends LitElement { @property({attribute: 'feedback-duration', type: Number}) feedbackDuration = 1000; - @property({attribute: 'tooltip-label'}) + @property() tooltipLabel: string | null = null; async copyValue() { @@ -149,7 +149,7 @@ export default class CraftCopyButton extends LitElement { override render() { return html` - ${this.tooltipLabel} + ${this.tooltipLabel} +
This will toggle
+ + `, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +// More on writing stories with args: https://storybook.js.org/docs/writing-stories/args +export const Basic: Story = { + args: {}, +}; + +export const Expanded: Story = { + args: { + state: 'expanded', + }, + play: async ({canvas, userEvent}) => { + await expect(canvas.getByTestId('trigger')).toHaveAttribute( + 'aria-expanded', + 'true' + ); + }, +}; + +export const Persistant: Story = { + args: { + cookieName: 'persistent-disclosure', + }, +}; diff --git a/packages/craftcms-cp/src/components/disclosure/disclosure.ts b/packages/craftcms-cp/src/components/disclosure/disclosure.ts new file mode 100644 index 00000000000..4db5ec2a9cc --- /dev/null +++ b/packages/craftcms-cp/src/components/disclosure/disclosure.ts @@ -0,0 +1,129 @@ +/** + * Very simple disclosure trigger. + * + * Allows you to wrap a button[type="button"] and target an element to toggle the `data-state` attribute on. + * Set `aria-expanded` on the button + */ +export default class CraftDisclosure extends HTMLElement { + static observedAttributes = ['state']; + private cookieName: string | null = null; + private state: string = 'collapsed'; + private expanded: boolean = false; + + get trigger() { + return this.querySelector('button[type="button"]'); + } + + get target() { + if (!this.trigger) { + console.warn('No trigger found for disclosure.'); + return null; + } + + const targetSelector = this.trigger.getAttribute('aria-controls'); + if (!targetSelector) { + console.warn('No target selector found for disclosure.'); + return null; + } + + return document.getElementById(targetSelector); + } + + connectedCallback() { + if (!this.trigger) { + console.error(`craft-disclosure elements must include a button`, this); + return; + } + + if (!this.target) { + console.error( + `No target with id ${this.trigger.getAttribute( + 'aria-controls' + )} found for disclosure. `, + this.trigger + ); + return; + } + + this.cookieName = this.getAttribute('cookie-name'); + this.state = this.getAttribute('state') ?? 'expanded'; + + this.trigger.setAttribute( + 'aria-expanded', + this.state === 'expanded' ? 'true' : 'false' + ); + + this.trigger.addEventListener('click', this.toggle.bind(this)); + + this.state === 'expanded' ? this.open() : this.close(); + } + + disconnectedCallback() { + this.open(); + this.trigger?.removeEventListener('click', this.toggle.bind(this)); + } + + attributeChangedCallback(name: string, oldValue: string, newValue: string) { + if (name === 'state') { + if (newValue === 'expanded') { + this.handleOpen(); + } else { + this.handleClose(); + } + } + } + + toggle() { + if (this.expanded) { + this.close(); + } else { + this.open(); + } + } + + handleOpen = () => { + this.trigger?.setAttribute('aria-expanded', 'true'); + this.expanded = true; + this.dispatchEvent(new CustomEvent('open')); + + if (this.target) { + this.target.dataset.state = 'expanded'; + } + + if (this.cookieName) { + window.Craft?.setCookie(this.cookieName, 'expanded'); + } + }; + + open() { + this.setAttribute('state', 'expanded'); + } + + handleClose = () => { + this.trigger?.setAttribute('aria-expanded', 'false'); + this.expanded = false; + this.dispatchEvent(new CustomEvent('close')); + + if (this.target) { + this.target.dataset.state = 'collapsed'; + } + + if (this.cookieName) { + window.Craft?.setCookie(this.cookieName, 'collapsed'); + } + }; + + close() { + this.setAttribute('state', 'collapsed'); + } +} + +if (!customElements.get('craft-disclosure')) { + customElements.define('craft-disclosure', CraftDisclosure); +} + +declare global { + interface HTMLElementTagNameMap { + 'craft-disclosure': CraftDisclosure; + } +} diff --git a/packages/craftcms-cp/src/components/drawer/drawer.stories.ts b/packages/craftcms-cp/src/components/drawer/drawer.stories.ts new file mode 100644 index 00000000000..eea1cc32f01 --- /dev/null +++ b/packages/craftcms-cp/src/components/drawer/drawer.stories.ts @@ -0,0 +1,43 @@ +import type {Meta, StoryObj} from '@storybook/web-components-vite'; + +import {html} from 'lit'; + +import './drawer.js'; +import '../button/button.js'; + +import type CraftDrawer from './drawer.js'; + +// More on how to set up stories at: https://storybook.js.org/docs/writing-stories +const meta = { + title: 'Components/Drawer', + component: 'craft-drawer', + args: {}, + parameters: { + layout: 'centered', + }, + render: function (args) { + function openDrawer() { + const drawer = document.getElementById('drawer-overview') as CraftDrawer; + drawer.open = true; + } + + return html` + + Lorem ipsum dolor sit amet, consectetur adipiscing elit. + Close + + + Open Drawer + `; + }, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +// More on writing stories with args: https://storybook.js.org/docs/writing-stories/args +export const Default: Story = { + args: {}, +}; diff --git a/packages/craftcms-cp/src/components/drawer/drawer.ts b/packages/craftcms-cp/src/components/drawer/drawer.ts new file mode 100644 index 00000000000..0c8ce97b831 --- /dev/null +++ b/packages/craftcms-cp/src/components/drawer/drawer.ts @@ -0,0 +1,25 @@ +import {css} from 'lit'; +import WaDrawer from '@awesome.me/webawesome/dist/components/drawer/drawer.js'; + +/** + * craft-drawer extends wa-drawer from web awesome. + * + * Anything you can do over there you can do here. + */ +export default class CraftDrawer extends WaDrawer { + static override get styles() { + return [ + WaDrawer.styles, + css` + :host { + --wa-color-surface-raised: var(--c-surface-raised); + --spacing: var(--c-spacing-lg); + } + `, + ]; + } +} + +if (!customElements.get('craft-drawer')) { + customElements.define('craft-drawer', CraftDrawer); +} diff --git a/packages/craftcms-cp/src/components/dropdown/dropdown.stories.ts b/packages/craftcms-cp/src/components/dropdown/dropdown.stories.ts new file mode 100644 index 00000000000..d91719a9b18 --- /dev/null +++ b/packages/craftcms-cp/src/components/dropdown/dropdown.stories.ts @@ -0,0 +1,36 @@ +import type {Meta, StoryObj} from '@storybook/web-components-vite'; + +import {html} from 'lit'; + +import './dropdown.js'; +import '../button/button.js'; + +// More on how to set up stories at: https://storybook.js.org/docs/writing-stories +const meta = { + title: 'Components/Dropdown', + component: 'craft-dropdown', + argTypes: {}, + render: (args) => html` + + Dropdown + + This is a thing + Another thing + Yet another thing + + `, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +// More on writing stories with args: https://storybook.js.org/docs/writing-stories/args +export const Default: Story = { + args: {}, +}; + +export const Open: Story = { + args: { + open: true, + }, +}; diff --git a/packages/craftcms-cp/src/components/dropdown/dropdown.styles.ts b/packages/craftcms-cp/src/components/dropdown/dropdown.styles.ts new file mode 100644 index 00000000000..3a3135df80e --- /dev/null +++ b/packages/craftcms-cp/src/components/dropdown/dropdown.styles.ts @@ -0,0 +1,19 @@ +import {css} from 'lit'; + +export default css` + :host { + display: contents; + } + + .panel { + display: grid; + gap: 1px; + flex-direction: column; + width: max-content; + position: absolute; + padding: var(--spacing-sm); + background-color: var(--bg-overlay); + border: 1px solid var(--border-subtle); + border-radius: var(--radius-sm); + } +`; diff --git a/packages/craftcms-cp/src/components/dropdown/dropdown.ts b/packages/craftcms-cp/src/components/dropdown/dropdown.ts new file mode 100644 index 00000000000..a5d1caec60e --- /dev/null +++ b/packages/craftcms-cp/src/components/dropdown/dropdown.ts @@ -0,0 +1,62 @@ +import WaDropdown from '@awesome.me/webawesome/dist/components/dropdown/dropdown.js'; +import WaDropdownItem from '@awesome.me/webawesome/dist/components/dropdown-item/dropdown-item.js'; +import {css} from 'lit'; + +export default class CraftDropdown extends WaDropdown { + static override get styles() { + return [ + WaDropdown.styles, + css` + :host { + --wa-border-style: solid; + --wa-border-width-s: 1px; + --wa-color-surface-raised: var(--c-surface-raised); + --wa-color-surface-border: var(--c-color-neutral-border-quiet); + --wa-border-radius-m: var(--c-radius-lg); + } + + #menu { + gap: 1px; + } + `, + ]; + } +} + +export class CraftDropdownItem extends WaDropdownItem { + static override get styles() { + return [ + WaDropdownItem.styles, + css` + @layer components.dropdown-item { + :host { + --wa-font-weight-action: 400; + --wa-space-s: var(--c-spacing-sm); + --wa-color-neutral-fill-normal: var(--c-color-neutral-fill-quiet); + white-space: nowrap; + display: inline-flex; + align-items: center; + border-radius: var(--c-radius-sm); + padding-block: calc(var(--c-spacing, 0.25rem) * 1); + padding-inline: calc(var(--c-spacing, 0.25rem) * 2.5); + } + } + `, + ]; + } +} + +if (!customElements.get('craft-dropdown')) { + customElements.define('craft-dropdown', CraftDropdown); +} + +if (!customElements.get('craft-dropdown-item')) { + customElements.define('craft-dropdown-item', CraftDropdownItem); +} + +declare global { + interface HTMLElementTagNameMap { + 'craft-dropdown': CraftDropdown; + 'craft-dropdown-item': CraftDropdownItem; + } +} diff --git a/packages/craftcms-cp/src/components/field-group/field-group.ts b/packages/craftcms-cp/src/components/field-group/field-group.ts new file mode 100644 index 00000000000..38e96387987 --- /dev/null +++ b/packages/craftcms-cp/src/components/field-group/field-group.ts @@ -0,0 +1,26 @@ +import {css, html, LitElement} from 'lit'; + +export default class CraftFieldGroup extends LitElement { + static override styles = [ + css` + :host { + display: grid; + gap: var(--c-spacing-md); + } + `, + ]; + + override render() { + return html``; + } +} + +if (!customElements.get('craft-field-group')) { + customElements.define('craft-field-group', CraftFieldGroup); +} + +declare global { + interface HTMLElementTagNameMap { + 'craft-field-group': CraftFieldGroup; + } +} diff --git a/packages/craftcms-cp/src/components/icon/icon.stories.ts b/packages/craftcms-cp/src/components/icon/icon.stories.ts new file mode 100644 index 00000000000..e91cfdc193a --- /dev/null +++ b/packages/craftcms-cp/src/components/icon/icon.stories.ts @@ -0,0 +1,25 @@ +import type {Meta, StoryObj} from '@storybook/web-components-vite'; + +import {html} from 'lit'; + +import './icon.js'; + +// More on how to set up stories at: https://storybook.js.org/docs/writing-stories +const meta = { + title: 'Components/Icon', + component: 'craft-icon', + args: { + iconId: 'chevron-down', + }, + render: function ({iconId}) { + return html``; + }, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +// More on writing stories with args: https://storybook.js.org/docs/writing-stories/args +export const Default: Story = { + args: {}, +}; diff --git a/packages/craftcms-cp/src/components/icon/icon.ts b/packages/craftcms-cp/src/components/icon/icon.ts new file mode 100644 index 00000000000..99ec23366fe --- /dev/null +++ b/packages/craftcms-cp/src/components/icon/icon.ts @@ -0,0 +1,49 @@ +import WaIcon from '@awesome.me/webawesome/dist/components/icon/icon.js'; +import {css} from 'lit'; +import {property} from 'lit/decorators.js'; + +/** + * craft-icon is just an alias to wa-icon from web awesome. + * + * Anything you can do over there you can do here. + */ +export default class CraftIcon extends WaIcon { + @property({reflect: true}) appearance?: 'plain' | 'badge' = 'plain'; + + override connectedCallback() { + super.connectedCallback(); + + if (this.appearance === 'badge' && !this.getAttribute('data-color')) { + this.setAttribute('data-color', 'warning'); + } + } + + static override get styles() { + return [ + WaIcon.styles, + css` + :host { + font-size: 0.8em; + } + + :host([appearance~='badge']) { + border: 1px solid var(--c-color-border-quiet); + color: var(--c-color-on-quiet); + background-color: var(--c-color-fill-quiet); + border-radius: var(--c-radius-sm); + width: 1.6em; + height: 1.6em; + + svg { + width: 0.9em; + } + } + `, + ]; + } +} + +// Alias to `craft-icon` +if (!customElements.get('craft-icon')) { + customElements.define('craft-icon', CraftIcon); +} diff --git a/packages/craftcms-ui/src/components/indicator/Indicator.mdx b/packages/craftcms-cp/src/components/indicator/Indicator.mdx similarity index 100% rename from packages/craftcms-ui/src/components/indicator/Indicator.mdx rename to packages/craftcms-cp/src/components/indicator/Indicator.mdx diff --git a/packages/craftcms-cp/src/components/indicator/indicator.stories.ts b/packages/craftcms-cp/src/components/indicator/indicator.stories.ts new file mode 100644 index 00000000000..f33bd29a026 --- /dev/null +++ b/packages/craftcms-cp/src/components/indicator/indicator.stories.ts @@ -0,0 +1,101 @@ +import type {Meta, StoryObj} from '@storybook/web-components-vite'; + +import {html, nothing} from 'lit'; + +import './indicator.js'; +import type CraftIndicator from './indicator.js'; +import {Variant} from '@src/constants/variants'; + +const appearances = ['outline-fill', 'solid', 'outline']; + +/** + * Renders the indicator in each appearance, with a label, so every story shares + * the same markup. + */ +const renderIndicators = ( + label: string, + attrs: {fill?: string; size?: CraftIndicator['size']} = {} +) => html` + + ${label} + ${appearances.map( + (appearance) => html` + + + + ` + )} + +`; + +// More on how to set up stories at: https://storybook.js.org/docs/writing-stories +const meta = { + title: 'Components/Indicator', + component: 'craft-indicator', + args: {}, + render: () => html` + + + + ${appearances.map((appearance) => html``)} + + + ${Object.values(Variant).map((variant) => + renderIndicators(variant, {fill: variant}) + )} + +
${appearance}
+ `, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +// More on writing stories with args: https://storybook.js.org/docs/writing-stories/args +export const Default: Story = { + args: {}, +}; + +const arbitraryValues = [ + '#2c61de', + 'rgba(30, 40, 40, 0.2)', + 'linear-gradient(red, blue)', +]; + +export const ArbitraryColor: Story = { + render: () => html` + + + + ${appearances.map((appearance) => html``)} + + + ${arbitraryValues.map((value) => + renderIndicators(value, {fill: value}) + )} + +
${appearance}
+ `, +}; + +const sizes: Array = ['md', 'lg']; + +export const ArbitrarySize: Story = { + render: () => html` + + + + ${appearances.map((appearance) => html``)} + + + ${sizes.map((size) => + renderIndicators(size === 'md' ? 'md (default)' : size, {size}) + )} + +
${appearance}
+ `, +}; diff --git a/packages/craftcms-ui/src/components/indicator/indicator.ts b/packages/craftcms-cp/src/components/indicator/indicator.ts similarity index 90% rename from packages/craftcms-ui/src/components/indicator/indicator.ts rename to packages/craftcms-cp/src/components/indicator/indicator.ts index 4952ff06f4e..fd2ea9414bd 100644 --- a/packages/craftcms-ui/src/components/indicator/indicator.ts +++ b/packages/craftcms-cp/src/components/indicator/indicator.ts @@ -1,4 +1,4 @@ -import {css, html, LitElement, nothing} from 'lit'; +import {css, html, LitElement} from 'lit'; import {property} from 'lit/decorators.js'; import {classMap} from 'lit/directives/class-map.js'; import variantsStyles from '@src/styles/variants.styles'; @@ -85,12 +85,10 @@ export default class CraftIndicator extends LitElement { } protected override render(): unknown { - // Without a label the indicator is purely decorative, so omit the image role - // and name rather than exposing an unnamed `role="img"`. return html` + return ` +
Tooltip content for icon 1 Tooltip content for icon 2 Tooltip content for icon 3 diff --git a/packages/craftcms-ui/src/components/info-icon/info-icon.ts b/packages/craftcms-cp/src/components/info-icon/info-icon.ts similarity index 90% rename from packages/craftcms-ui/src/components/info-icon/info-icon.ts rename to packages/craftcms-cp/src/components/info-icon/info-icon.ts index 1619fc0e4d8..cb2364b98dd 100644 --- a/packages/craftcms-ui/src/components/info-icon/info-icon.ts +++ b/packages/craftcms-cp/src/components/info-icon/info-icon.ts @@ -27,7 +27,7 @@ export default class CraftInfoIcon extends LitElement { @state() status = ''; - @query('craft-tooltip') tooltip!: HTMLElement; + @query('c-tooltip') tooltip!: HTMLElement; #eventController = new AbortController(); @@ -46,7 +46,7 @@ export default class CraftInfoIcon extends LitElement { const {signal} = this.#eventController; this.addEventListener( - 'craft-show', + 'wa-show', () => { if ( CraftInfoIcon.#openInstance && @@ -54,7 +54,7 @@ export default class CraftInfoIcon extends LitElement { ) { const otherTooltip = CraftInfoIcon.#openInstance.renderRoot.querySelector( - 'craft-tooltip' + 'c-tooltip' ); otherTooltip?.hide(); } @@ -64,7 +64,7 @@ export default class CraftInfoIcon extends LitElement { ); this.addEventListener( - 'craft-after-show', + 'wa-after-show', () => { this.status = ''; setTimeout(() => { @@ -75,7 +75,7 @@ export default class CraftInfoIcon extends LitElement { ); this.addEventListener( - 'craft-after-hide', + 'wa-after-hide', () => { if (CraftInfoIcon.#openInstance === this) { CraftInfoIcon.#openInstance = null; @@ -105,15 +105,13 @@ export default class CraftInfoIcon extends LitElement { type="button" icon size="zero" - variant="plain" + appearance="plain" id="${this.id}" > - +
`; } diff --git a/packages/craftcms-ui/src/components/input-file/input-file.stories.ts b/packages/craftcms-cp/src/components/input-file/input-file.stories.ts similarity index 100% rename from packages/craftcms-ui/src/components/input-file/input-file.stories.ts rename to packages/craftcms-cp/src/components/input-file/input-file.stories.ts diff --git a/packages/craftcms-ui/src/components/input-file/input-file.styles.ts b/packages/craftcms-cp/src/components/input-file/input-file.styles.ts similarity index 100% rename from packages/craftcms-ui/src/components/input-file/input-file.styles.ts rename to packages/craftcms-cp/src/components/input-file/input-file.styles.ts diff --git a/packages/craftcms-ui/src/components/input-file/input-file.ts b/packages/craftcms-cp/src/components/input-file/input-file.ts similarity index 100% rename from packages/craftcms-ui/src/components/input-file/input-file.ts rename to packages/craftcms-cp/src/components/input-file/input-file.ts diff --git a/packages/craftcms-ui/src/components/input-file/selected-file-list.ts b/packages/craftcms-cp/src/components/input-file/selected-file-list.ts similarity index 97% rename from packages/craftcms-ui/src/components/input-file/selected-file-list.ts rename to packages/craftcms-cp/src/components/input-file/selected-file-list.ts index 62ed0d3eea9..cda7694a03c 100644 --- a/packages/craftcms-ui/src/components/input-file/selected-file-list.ts +++ b/packages/craftcms-cp/src/components/input-file/selected-file-list.ts @@ -54,7 +54,7 @@ export default class CraftSelectedFileList extends LionSelectedFileList { ]; } - // oxlint-disable-next-line no-unused-vars + // eslint-disable-next-line no-unused-vars override _listItemAfterTemplate(file: InputFile, fileUuid: string) { return html` ${this._visible diff --git a/packages/craftcms-cp/src/components/input/input.stories.ts b/packages/craftcms-cp/src/components/input/input.stories.ts new file mode 100644 index 00000000000..71ea43775de --- /dev/null +++ b/packages/craftcms-cp/src/components/input/input.stories.ts @@ -0,0 +1,56 @@ +import type {Meta, StoryObj} from '@storybook/web-components-vite'; + +import {html} from 'lit'; + +import './input.js'; + +// More on how to set up stories at: https://storybook.js.org/docs/writing-stories +const meta = { + title: 'Controls/Input', + component: 'craft-input', + args: { + size: undefined, + }, + argTypes: { + size: { + control: {type: 'number'}, + }, + }, + render: function ({maxlength}) { + return html``; + }, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +// More on writing stories with args: https://storybook.js.org/docs/writing-stories/args +export const Default: Story = { + args: {}, +}; + +export const WithMaxLength: Story = { + args: { + maxlength: 5, + }, +}; + +export const WithPrefix: Story = { + render: () => html` + + + + `, +}; + +export const WithSuffix: Story = { + render: () => html` + + + + `, +}; diff --git a/packages/craftcms-cp/src/components/input/input.styles.ts b/packages/craftcms-cp/src/components/input/input.styles.ts new file mode 100644 index 00000000000..a6c742c2149 --- /dev/null +++ b/packages/craftcms-cp/src/components/input/input.styles.ts @@ -0,0 +1,26 @@ +import {css} from 'lit'; + +export default css` + craft-input input[type='checkbox'], + craft-input input[type='radio'] { + background-color: var(--c-input-fill, var(--c-form-control-fill)); + border-width: var( + --c-input-border-width, + var(--c-form-control-border-width) + ); + border-style: var( + --c-input-border-style, + var(--c-form-control-border-style) + ); + border-color: var( + --c-input-border-color, + var(--c-form-control-border-color) + ); + border-radius: var(--c-input-radius, var(--c-radius-sm)); + } + + [slot='help-text'] { + font-size: var(--c-text-base); + color: var(--c-text-quiet); + } +`; diff --git a/packages/craftcms-cp/src/components/input/input.ts b/packages/craftcms-cp/src/components/input/input.ts new file mode 100644 index 00000000000..7bafe449ff5 --- /dev/null +++ b/packages/craftcms-cp/src/components/input/input.ts @@ -0,0 +1,36 @@ +import {LionInput} from '@lion/ui/input.js'; +import {inputStyles} from '@src/styles/form.styles'; +import styles from './input.styles.js'; +import {property} from 'lit/decorators.js'; + +export default class CraftInput extends LionInput { + static override get styles() { + return [...super.styles, inputStyles, styles]; + } + + @property({type: Number, reflect: true}) maxlength?: number; + @property({type: String, reflect: true}) size?: 'small' | 'medium' | 'large' = + 'medium'; + @property({reflect: true, type: Boolean}) small = false; + @property({reflect: true, type: Boolean}) center = false; + + override connectedCallback() { + super.connectedCallback(); + + if (this._inputNode && this.maxlength) { + if (this.maxlength > 0) { + this._inputNode.maxLength = this.maxlength; + } + } + } +} + +if (!customElements.get('craft-input')) { + customElements.define('craft-input', CraftInput); +} + +declare global { + interface HTMLElementTagNameMap { + 'craft-input': CraftInput; + } +} diff --git a/packages/craftcms-cp/src/components/nav-item/nav-item.stories.ts b/packages/craftcms-cp/src/components/nav-item/nav-item.stories.ts new file mode 100644 index 00000000000..05cdb249666 --- /dev/null +++ b/packages/craftcms-cp/src/components/nav-item/nav-item.stories.ts @@ -0,0 +1,80 @@ +import type {Meta, StoryObj} from '@storybook/web-components-vite'; + +import {html} from 'lit'; + +import '../icon/icon.js'; +import '../nav-list/nav-list.js'; +import '../button/button.js'; +import './nav-item.js'; + +// More on how to set up stories at: https://storybook.js.org/docs/writing-stories +const meta = { + title: 'Components/Nav Item', + component: 'craft-nav-item', + argTypes: {}, + parameters: { + a11y: { + config: { + rules: [ + { + id: 'list', + enabled: false, + }, + { + id: 'listitem', + enabled: false, + }, + ], + }, + }, + }, + render: ({active, indicator}) => { + return html` + + Dashboard + + `; + }, +} satisfies Meta; + +export default meta; +type Story = StoryObj; +// More on writing stories with args: https://storybook.js.org/docs/writing-stories/args +export const Default: Story = { + args: {}, +}; + +export const Active: Story = { + args: { + active: true, + }, +}; + +export const WithIndicator: Story = { + args: { + indicator: true, + }, +}; + +export const WithChildren: Story = { + args: {}, + render(args) { + return html` + + + GraphQL + + Schemas + Tokens + GraphiQL + + + + `; + }, +}; diff --git a/packages/craftcms-ui/src/components/nav-item/nav-item.styles.ts b/packages/craftcms-cp/src/components/nav-item/nav-item.styles.ts similarity index 86% rename from packages/craftcms-ui/src/components/nav-item/nav-item.styles.ts rename to packages/craftcms-cp/src/components/nav-item/nav-item.styles.ts index f7cda86d08a..153700ab00f 100644 --- a/packages/craftcms-ui/src/components/nav-item/nav-item.styles.ts +++ b/packages/craftcms-cp/src/components/nav-item/nav-item.styles.ts @@ -34,10 +34,6 @@ export default css` .nav-item--flush { margin-inline-start: calc(var(--_padding-inline) * -1); } - - :host([group]) { - margin-block-start: var(--c-spacing-sm); - } :host([active]) .nav-item { &:before { @@ -53,15 +49,10 @@ export default css` } } - .nav-item:not(.nav-item--static):hover:not(:has(craft-button:hover)) { + .nav-item:hover:not(:has(craft-button:hover)) { background-color: color-mix(in srgb, currentColor, transparent 95%); } - /* No href: render as a plain label, not an interactive item. */ - .nav-item--static { - cursor: default; - } - .nav-item__prefix { position: relative; display: grid; @@ -70,10 +61,6 @@ export default css` aspect-ratio: 1; width: 100%; } - - .nav-item__suffix { - justify-self: end; - } .active-indicator { display: inline-block; @@ -87,7 +74,7 @@ export default css` } } - :host(:not([group])) .subnav { + .subnav { margin-block-start: var(--c-spacing-sm); margin-inline-start: calc( (var(--c-size-icon-md) / 2) + var(--c-spacing-sm) + 1px diff --git a/packages/craftcms-cp/src/components/nav-item/nav-item.ts b/packages/craftcms-cp/src/components/nav-item/nav-item.ts new file mode 100644 index 00000000000..fee63bc351c --- /dev/null +++ b/packages/craftcms-cp/src/components/nav-item/nav-item.ts @@ -0,0 +1,196 @@ +import {html, LitElement, nothing} from 'lit'; +import {styleMap} from 'lit/directives/style-map.js'; +import {property, state} from 'lit/decorators.js'; +import '../badge-indicator/badge-indicator'; +import styles from './nav-item.styles'; +import {t} from '@src/utilities/translate.js'; +import {classMap} from 'lit/directives/class-map.js'; + +/** + * + */ +export default class CraftNavItem extends LitElement { + static override styles = styles; + + /** Icon to render within the prefix. */ + @property() + icon: string; + + /** The URL of the navigation item. */ + @property() + href: string; + + /** Displays the item as active. */ + @property({type: Boolean, reflect: true}) + active: boolean = false; + + /** Opens the item in a new tab and displays an external link icon in the suffix. */ + @property({type: Boolean}) + external: boolean = false; + + /** Displays an indicator in the prefix. */ + @property({type: Boolean}) + indicator: boolean = false; + + @property() + override id: string; + + @property({reflect: true, type: Boolean, attribute: 'icon-only'}) + iconOnly: boolean = false; + + /** Compensate for padding with a negative margin for better visual alignment */ + @property() + flush: boolean = false; + + @state() + subnavState: string = 'closed'; + + constructor() { + super(); + this.id = this.id || Math.random().toString(36).substring(2, 6); + } + + override connectedCallback() { + super.connectedCallback(); + // Default to open when the item is active + this.subnavState = this.active ? 'open' : 'closed'; + } + + toggleSubnav(event: Event) { + event.preventDefault(); + event.stopPropagation(); + this.subnavState = this.subnavState === 'open' ? 'closed' : 'open'; + } + + renderIconItem(hasSubnav: boolean) { + const itemId = `item-${this.id}`; + + return html` + + ${this.renderPrefix()} ${this.renderSuffix(hasSubnav)} + + + `; + } + + renderPrefix() { + return html` + + + + ${this.icon + ? html` ` + : nothing} + + ${this.indicator + ? html`` + : nothing} + + + `; + } + + renderSuffix(hasSubnav: boolean = false) { + return html` + + `; + } + + renderItem(hasSubnav: boolean, hasPrefix: boolean = false) { + return html` + + ${hasPrefix ? this.renderPrefix() : nothing} + + ${this.renderSuffix(hasSubnav)} + + `; + } + + override render() { + const hasSubnav = !!this.querySelector('[slot="subnav"]'); + const hasPrefix = + !!this.icon || + !!this.querySelector('[slot="prefix"]') || + !!this.querySelector('[slot="icon"]'); + + return html` +
  • + ${this.iconOnly + ? this.renderIconItem(hasSubnav) + : this.renderItem(hasSubnav, hasPrefix)} + ${hasSubnav + ? html` + + ` + : nothing} +
  • + `; + } +} + +if (!customElements.get('craft-nav-item')) { + customElements.define('craft-nav-item', CraftNavItem); +} + +declare global { + interface HTMLElementTagNameMap { + 'craft-nav-item': CraftNavItem; + } +} diff --git a/packages/craftcms-ui/src/components/nav-list/nav-list.ts b/packages/craftcms-cp/src/components/nav-list/nav-list.ts similarity index 100% rename from packages/craftcms-ui/src/components/nav-list/nav-list.ts rename to packages/craftcms-cp/src/components/nav-list/nav-list.ts diff --git a/packages/craftcms-ui/src/components/option/option.styles.ts b/packages/craftcms-cp/src/components/option/option.styles.ts similarity index 100% rename from packages/craftcms-ui/src/components/option/option.styles.ts rename to packages/craftcms-cp/src/components/option/option.styles.ts diff --git a/packages/craftcms-cp/src/components/option/option.ts b/packages/craftcms-cp/src/components/option/option.ts new file mode 100644 index 00000000000..d61a63a85a5 --- /dev/null +++ b/packages/craftcms-cp/src/components/option/option.ts @@ -0,0 +1,51 @@ +import styles from './option.styles.js'; +import {LionOption} from '@lion/ui/listbox.js'; +import {html, nothing} from 'lit'; +import {property} from 'lit/decorators.js'; + +export default class CraftOption extends LionOption { + static override get styles() { + return [...LionOption.styles, styles]; + } + + @property() + hint?: string | null = null; + + #wideThreshold: number = 640; + + constructor() { + super(); + this.#wideThreshold = parseInt( + getComputedStyle(this).getPropertyValue('--c-option-wide-threshold') || + '640', + 10 + ); + } + + override connectedCallback() { + super.connectedCallback(); + + const width = this.getBoundingClientRect().width ?? 0; + this.toggleAttribute('wide', width >= this.#wideThreshold); + } + + override render() { + return html` +
    + + ${this.hint ? html`${this.hint}` : nothing} + +
    + `; + } +} + +if (!customElements.get('craft-option')) { + customElements.define('craft-option', CraftOption); +} + +declare global { + interface HTMLElementTagNameMap { + 'craft-option': CraftOption; + } +} diff --git a/packages/craftcms-ui/src/components/pane/pane.ts b/packages/craftcms-cp/src/components/pane/pane.ts similarity index 100% rename from packages/craftcms-ui/src/components/pane/pane.ts rename to packages/craftcms-cp/src/components/pane/pane.ts diff --git a/packages/craftcms-cp/src/components/popover/popover.ts b/packages/craftcms-cp/src/components/popover/popover.ts new file mode 100644 index 00000000000..c3fbd482343 --- /dev/null +++ b/packages/craftcms-cp/src/components/popover/popover.ts @@ -0,0 +1,34 @@ +import {css} from 'lit'; +import WaPopover from '@awesome.me/webawesome/dist/components/popover/popover.js'; + +export default class CraftPopover extends WaPopover { + static override get styles() { + return [ + WaPopover.styles, + css` + :host { + --wa-border-style: solid; + --wa-border-width-s: 1px; + --wa-color-surface-default: var(--c-surface-raised); + --wa-color-surface-raised: var(--c-surface-raised); + --wa-color-surface-border: var(--c-color-neutral-border-quiet); + --wa-border-radius-m: var(--c-radius-lg); + } + + .body { + padding: var(--c-spacing-md); + } + `, + ]; + } +} + +if (!customElements.get('craft-popover')) { + customElements.define('craft-popover', CraftPopover); +} + +declare global { + interface HTMLElementTagNameMap { + 'craft-popover': CraftPopover; + } +} diff --git a/packages/craftcms-ui/src/components/progress-bar/progress-bar.stories.ts b/packages/craftcms-cp/src/components/progress-bar/progress-bar.stories.ts similarity index 100% rename from packages/craftcms-ui/src/components/progress-bar/progress-bar.stories.ts rename to packages/craftcms-cp/src/components/progress-bar/progress-bar.stories.ts diff --git a/packages/craftcms-ui/src/components/progress-bar/progress-bar.styles.ts b/packages/craftcms-cp/src/components/progress-bar/progress-bar.styles.ts similarity index 100% rename from packages/craftcms-ui/src/components/progress-bar/progress-bar.styles.ts rename to packages/craftcms-cp/src/components/progress-bar/progress-bar.styles.ts diff --git a/packages/craftcms-ui/src/components/progress-bar/progress-bar.ts b/packages/craftcms-cp/src/components/progress-bar/progress-bar.ts similarity index 100% rename from packages/craftcms-ui/src/components/progress-bar/progress-bar.ts rename to packages/craftcms-cp/src/components/progress-bar/progress-bar.ts diff --git a/packages/craftcms-ui/src/components/progress/progress.stories.ts b/packages/craftcms-cp/src/components/progress/progress.stories.ts similarity index 100% rename from packages/craftcms-ui/src/components/progress/progress.stories.ts rename to packages/craftcms-cp/src/components/progress/progress.stories.ts diff --git a/packages/craftcms-ui/src/components/progress/progress.ts b/packages/craftcms-cp/src/components/progress/progress.ts similarity index 100% rename from packages/craftcms-ui/src/components/progress/progress.ts rename to packages/craftcms-cp/src/components/progress/progress.ts diff --git a/packages/craftcms-cp/src/components/radio-group/radio-group.ts b/packages/craftcms-cp/src/components/radio-group/radio-group.ts new file mode 100644 index 00000000000..ff0f58d8cbb --- /dev/null +++ b/packages/craftcms-cp/src/components/radio-group/radio-group.ts @@ -0,0 +1,28 @@ +import {LionRadioGroup} from '@lion/ui/radio-group.js'; +import {inputStyles} from '@src/styles/form.styles'; +import {css} from 'lit'; + +export default class CraftRadioGroup extends LionRadioGroup { + static override get styles() { + return [ + ...super.styles, + inputStyles, + css` + .input-group { + display: grid; + gap: var(--c-spacing-xs); + } + `, + ]; + } +} + +if (!customElements.get('craft-radio-group')) { + customElements.define('craft-radio-group', CraftRadioGroup); +} + +declare global { + interface HTMLElementTagNameMap { + 'craft-radio-group': CraftRadioGroup; + } +} diff --git a/packages/craftcms-ui/src/components/radio/radio.ts b/packages/craftcms-cp/src/components/radio/radio.ts similarity index 77% rename from packages/craftcms-ui/src/components/radio/radio.ts rename to packages/craftcms-cp/src/components/radio/radio.ts index d8c444b3eff..5533c52d194 100644 --- a/packages/craftcms-ui/src/components/radio/radio.ts +++ b/packages/craftcms-cp/src/components/radio/radio.ts @@ -1,8 +1,7 @@ import {LionRadio} from '@lion/ui/radio-group.js'; import {css} from 'lit'; -import {SsrChoiceInputMixin} from '@src/mixins/SsrChoiceInputMixin'; -export default class CraftRadio extends SsrChoiceInputMixin(LionRadio) { +export default class CraftRadio extends LionRadio { static override get styles() { return [ ...super.styles, diff --git a/packages/craftcms-ui/src/components/select/select.stories.ts b/packages/craftcms-cp/src/components/select/select.stories.ts similarity index 100% rename from packages/craftcms-ui/src/components/select/select.stories.ts rename to packages/craftcms-cp/src/components/select/select.stories.ts diff --git a/packages/craftcms-ui/src/components/select/select.styles.ts b/packages/craftcms-cp/src/components/select/select.styles.ts similarity index 100% rename from packages/craftcms-ui/src/components/select/select.styles.ts rename to packages/craftcms-cp/src/components/select/select.styles.ts diff --git a/packages/craftcms-cp/src/components/select/select.ts b/packages/craftcms-cp/src/components/select/select.ts new file mode 100644 index 00000000000..77cac8e9c1a --- /dev/null +++ b/packages/craftcms-cp/src/components/select/select.ts @@ -0,0 +1,39 @@ +import styles from './select.styles.js'; +import {LionSelect} from '@lion/ui/select.js'; +import {html} from 'lit'; +import '../option/option.js'; +import '../icon/icon.js'; +import {property} from 'lit/decorators.js'; + +export default class CraftSelect extends LionSelect { + static override get styles() { + return [...super.styles, styles]; + } + + @property({reflect: true, type: Boolean}) small = false; + + // eslint-disable-next-line class-methods-use-this + override _inputGroupInputTemplate() { + return html` +
    + + +
    + `; + } +} + +if (!customElements.get('craft-select')) { + customElements.define('craft-select', CraftSelect); +} + +declare global { + interface HTMLElementTagNameMap { + 'craft-select': CraftSelect; + // 'craft-select-invoker': CraftSelectInvoker; + } +} diff --git a/packages/craftcms-ui/src/components/shortcut/shortcut.stories.ts b/packages/craftcms-cp/src/components/shortcut/shortcut.stories.ts similarity index 100% rename from packages/craftcms-ui/src/components/shortcut/shortcut.stories.ts rename to packages/craftcms-cp/src/components/shortcut/shortcut.stories.ts diff --git a/packages/craftcms-ui/src/components/shortcut/shortcut.ts b/packages/craftcms-cp/src/components/shortcut/shortcut.ts similarity index 100% rename from packages/craftcms-ui/src/components/shortcut/shortcut.ts rename to packages/craftcms-cp/src/components/shortcut/shortcut.ts diff --git a/packages/craftcms-ui/src/components/spinner/spinner.stories.ts b/packages/craftcms-cp/src/components/spinner/spinner.stories.ts similarity index 100% rename from packages/craftcms-ui/src/components/spinner/spinner.stories.ts rename to packages/craftcms-cp/src/components/spinner/spinner.stories.ts diff --git a/packages/craftcms-ui/src/components/spinner/spinner.styles.ts b/packages/craftcms-cp/src/components/spinner/spinner.styles.ts similarity index 100% rename from packages/craftcms-ui/src/components/spinner/spinner.styles.ts rename to packages/craftcms-cp/src/components/spinner/spinner.styles.ts diff --git a/packages/craftcms-ui/src/components/spinner/spinner.ts b/packages/craftcms-cp/src/components/spinner/spinner.ts similarity index 100% rename from packages/craftcms-ui/src/components/spinner/spinner.ts rename to packages/craftcms-cp/src/components/spinner/spinner.ts diff --git a/packages/craftcms-ui/src/components/status/status.stories.ts b/packages/craftcms-cp/src/components/status/status.stories.ts similarity index 100% rename from packages/craftcms-ui/src/components/status/status.stories.ts rename to packages/craftcms-cp/src/components/status/status.stories.ts diff --git a/packages/craftcms-ui/src/components/status/status.styles.ts b/packages/craftcms-cp/src/components/status/status.styles.ts similarity index 100% rename from packages/craftcms-ui/src/components/status/status.styles.ts rename to packages/craftcms-cp/src/components/status/status.styles.ts diff --git a/packages/craftcms-ui/src/components/status/status.ts b/packages/craftcms-cp/src/components/status/status.ts similarity index 100% rename from packages/craftcms-ui/src/components/status/status.ts rename to packages/craftcms-cp/src/components/status/status.ts diff --git a/packages/craftcms-ui/src/components/switch-button/switch-button.ts b/packages/craftcms-cp/src/components/switch-button/switch-button.ts similarity index 79% rename from packages/craftcms-ui/src/components/switch-button/switch-button.ts rename to packages/craftcms-cp/src/components/switch-button/switch-button.ts index 02a32dcd948..45a00b9f46d 100644 --- a/packages/craftcms-ui/src/components/switch-button/switch-button.ts +++ b/packages/craftcms-cp/src/components/switch-button/switch-button.ts @@ -1,27 +1,7 @@ import {LionSwitchButton} from '@lion/ui/switch.js'; -import {css, type PropertyValues} from 'lit'; -import {property} from 'lit/decorators.js'; +import {css} from 'lit'; export default class CraftSwitchButton extends LionSwitchButton { - /** - * Display-only mixed state (thumb centered, `aria-checked="mixed"`). - * State transitions are managed by `craft-switch`. - */ - @property({type: Boolean, reflect: true}) indeterminate = false; - - override updated(changedProperties: PropertyValues): void { - super.updated(changedProperties); - if ( - changedProperties.has('indeterminate') || - changedProperties.has('checked') - ) { - this.setAttribute( - 'aria-checked', - this.checked ? 'true' : this.indeterminate ? 'mixed' : 'false' - ); - } - } - static override get styles() { return [ ...super.styles, @@ -68,11 +48,6 @@ export default class CraftSwitchButton extends LionSwitchButton { inset-inline-end: auto; } - :host([indeterminate]:not([checked])) .switch-button__thumb { - inset-inline-start: calc(50% - (var(--c-switch-thumb-height) / 2)); - inset-inline-end: auto; - } - :host([checked]) .switch-button__track { background-color: var(--c-color-static-success-fill); } diff --git a/packages/craftcms-cp/src/components/switch/switch.stories.ts b/packages/craftcms-cp/src/components/switch/switch.stories.ts new file mode 100644 index 00000000000..9dc2052f892 --- /dev/null +++ b/packages/craftcms-cp/src/components/switch/switch.stories.ts @@ -0,0 +1,81 @@ +import type {Meta, StoryObj} from '@storybook/web-components-vite'; + +import {html} from 'lit'; + +import './switch.js'; + +const meta = { + title: 'Controls/Switch', + component: 'craft-switch', + args: { + label: 'Enable feature', + helpText: '', + size: 'medium', + disabled: false, + checked: false, + labelSrOnly: false, + }, + argTypes: { + size: { + control: 'select', + options: ['small', 'medium'], + }, + }, + render: ({label, helpText, size, disabled, checked, labelSrOnly}) => { + return html``; + }, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: {}, +}; + +export const Checked: Story = { + args: { + checked: true, + }, +}; + +export const WithHelpText: Story = { + args: { + helpText: 'This toggles the feature on or off', + }, +}; + +export const Sizes: Story = { + render: () => html` +
    + + +
    + `, +}; + +export const Disabled: Story = { + args: { + disabled: true, + }, +}; + +export const DisabledChecked: Story = { + args: { + disabled: true, + checked: true, + }, +}; + +export const LabelSrOnly: Story = { + args: { + labelSrOnly: true, + }, +}; diff --git a/packages/craftcms-cp/src/components/switch/switch.styles.ts b/packages/craftcms-cp/src/components/switch/switch.styles.ts new file mode 100644 index 00000000000..f5fdb99cc70 --- /dev/null +++ b/packages/craftcms-cp/src/components/switch/switch.styles.ts @@ -0,0 +1,14 @@ +import {css} from 'lit'; +export default css` + :host { + display: grid; + } + + .input-group { + display: inline-flex; + } + + ::slotted(label) { + font-weight: bold; + } +`; diff --git a/packages/craftcms-cp/src/components/switch/switch.ts b/packages/craftcms-cp/src/components/switch/switch.ts new file mode 100644 index 00000000000..1db52dabe48 --- /dev/null +++ b/packages/craftcms-cp/src/components/switch/switch.ts @@ -0,0 +1,42 @@ +import {LionSwitch} from '@lion/ui/switch.js'; +import CraftSwitchButton from '../switch-button/switch-button.js'; +import styles from './switch.styles.js'; +import {baseFieldStyles} from '@src/styles/form.styles'; +import {property} from 'lit/decorators.js'; + +export default class CraftSwitch extends LionSwitch { + static override get styles() { + return [...super.styles, baseFieldStyles, styles]; + } + + @property({type: String, reflect: true}) size: 'small' | 'medium' = 'medium'; + + override get slots() { + return { + ...super.slots, + input: () => { + const btnEl = this.createScopedElement('craft-switch-button'); + btnEl.setAttribute('size', this.size); + btnEl.setAttribute('data-tag-name', 'craft-switch-button'); + return btnEl; + }, + }; + } + + static override get scopedElements() { + return { + ...super.scopedElements, + 'craft-switch-button': CraftSwitchButton, + }; + } +} + +if (!customElements.get('craft-switch')) { + customElements.define('craft-switch', CraftSwitch); +} + +declare global { + interface HTMLElementTagNameMap { + 'craft-switch': CraftSwitch; + } +} diff --git a/packages/craftcms-ui/src/components/tab/tab.styles.ts b/packages/craftcms-cp/src/components/tab/tab.styles.ts similarity index 100% rename from packages/craftcms-ui/src/components/tab/tab.styles.ts rename to packages/craftcms-cp/src/components/tab/tab.styles.ts diff --git a/packages/craftcms-ui/src/components/tab/tab.ts b/packages/craftcms-cp/src/components/tab/tab.ts similarity index 100% rename from packages/craftcms-ui/src/components/tab/tab.ts rename to packages/craftcms-cp/src/components/tab/tab.ts diff --git a/packages/craftcms-ui/src/components/tabs/tabs.stories.ts b/packages/craftcms-cp/src/components/tabs/tabs.stories.ts similarity index 100% rename from packages/craftcms-ui/src/components/tabs/tabs.stories.ts rename to packages/craftcms-cp/src/components/tabs/tabs.stories.ts diff --git a/packages/craftcms-ui/src/components/tabs/tabs.styles.ts b/packages/craftcms-cp/src/components/tabs/tabs.styles.ts similarity index 100% rename from packages/craftcms-ui/src/components/tabs/tabs.styles.ts rename to packages/craftcms-cp/src/components/tabs/tabs.styles.ts diff --git a/packages/craftcms-ui/src/components/tabs/tabs.ts b/packages/craftcms-cp/src/components/tabs/tabs.ts similarity index 100% rename from packages/craftcms-ui/src/components/tabs/tabs.ts rename to packages/craftcms-cp/src/components/tabs/tabs.ts diff --git a/packages/craftcms-ui/src/components/textarea/textarea.stories.ts b/packages/craftcms-cp/src/components/textarea/textarea.stories.ts similarity index 100% rename from packages/craftcms-ui/src/components/textarea/textarea.stories.ts rename to packages/craftcms-cp/src/components/textarea/textarea.stories.ts diff --git a/packages/craftcms-ui/src/components/textarea/textarea.styles.ts b/packages/craftcms-cp/src/components/textarea/textarea.styles.ts similarity index 100% rename from packages/craftcms-ui/src/components/textarea/textarea.styles.ts rename to packages/craftcms-cp/src/components/textarea/textarea.styles.ts diff --git a/packages/craftcms-ui/src/components/textarea/textarea.ts b/packages/craftcms-cp/src/components/textarea/textarea.ts similarity index 100% rename from packages/craftcms-ui/src/components/textarea/textarea.ts rename to packages/craftcms-cp/src/components/textarea/textarea.ts diff --git a/packages/craftcms-cp/src/components/tooltip/Tooltip.mdx b/packages/craftcms-cp/src/components/tooltip/Tooltip.mdx new file mode 100644 index 00000000000..d223cff065e --- /dev/null +++ b/packages/craftcms-cp/src/components/tooltip/Tooltip.mdx @@ -0,0 +1,10 @@ +import {Canvas, Meta} from '@storybook/addon-docs/blocks'; +import TooltipMeta, {Playground} from './tooltip.stories'; + + + +# Tooltip + +``](https://webawesome.com/docs/components/tooltip) element so all of the options and properties of `` can be used with ``. + + diff --git a/packages/craftcms-ui/src/components/tooltip/tooltip.stories.ts b/packages/craftcms-cp/src/components/tooltip/tooltip.stories.ts similarity index 92% rename from packages/craftcms-ui/src/components/tooltip/tooltip.stories.ts rename to packages/craftcms-cp/src/components/tooltip/tooltip.stories.ts index 7fbec3585f7..556f01f38a8 100644 --- a/packages/craftcms-ui/src/components/tooltip/tooltip.stories.ts +++ b/packages/craftcms-cp/src/components/tooltip/tooltip.stories.ts @@ -2,6 +2,7 @@ import type {Meta, StoryObj} from '@storybook/web-components-vite'; import {html} from 'lit'; +// import "@awesome.me/webawesome/dist/components/tooltip/tooltip.js"; import './tooltip.js'; import '../button/button.js'; @@ -23,11 +24,11 @@ const meta = { } return html` - ${args.content}${args.content} Hover me `; diff --git a/packages/craftcms-cp/src/components/tooltip/tooltip.ts b/packages/craftcms-cp/src/components/tooltip/tooltip.ts new file mode 100644 index 00000000000..d4f7d2a836e --- /dev/null +++ b/packages/craftcms-cp/src/components/tooltip/tooltip.ts @@ -0,0 +1,56 @@ +import WaTooltip from '@awesome.me/webawesome/dist/components/tooltip/tooltip.js'; +import {css} from 'lit'; + +// export default class CraftTooltip extends LitElement { +// override render() { +// return html`` +// } +// } + +export default class CraftTooltip extends WaTooltip { + static override get styles() { + return [ + WaTooltip.styles, + css` + :host { + --wa-tooltip-background-color: var(--c-color-black-fill-loud); + --wa-tooltip-border-color: var(--c-color-black-border-loud); + --wa-tooltip-content-color: var(--c-color-black-on-loud); + --wa-tooltip-padding: var( + --c-tooltip-padding, + calc(4rem / 16) calc(8rem / 16) + ); + --wa-tooltip-arrow-size: var(--c-tooltip-arrow-size, 5px); + --wa-tooltip-font-family: var(--c-font-body); + --wa-tooltip-font-size: var(--c-text-base); + --wa-tooltip-font-weight: 400; + --wa-tooltip-line-height: 1.3; + --wa-tooltip-border-radius: var(--c-radius-sm); + } + + &::part(base) { + box-shadow: var(--c-shadow-md); + } + + .body { + color: var(--wa-tooltip-content-color); + font-weight: var(--wa-tooltip-font-weight); + font-family: var(--c-font-body); + } + `, + ]; + } +} + +/** + * @TODO rename this once I figure out what to do with the existing `craft-tooltip` + */ +if (!customElements.get('c-tooltip')) { + customElements.define('c-tooltip', CraftTooltip); +} + +declare global { + interface HTMLElementTagNameMap { + 'craft-tooltip': CraftTooltip; + } +} diff --git a/packages/craftcms-ui/src/components/visually-hidden/visually-hidden.ts b/packages/craftcms-cp/src/components/visually-hidden/visually-hidden.ts similarity index 100% rename from packages/craftcms-ui/src/components/visually-hidden/visually-hidden.ts rename to packages/craftcms-cp/src/components/visually-hidden/visually-hidden.ts diff --git a/packages/craftcms-cp/src/constants/appearances.ts b/packages/craftcms-cp/src/constants/appearances.ts new file mode 100644 index 00000000000..ba950ff4b0a --- /dev/null +++ b/packages/craftcms-cp/src/constants/appearances.ts @@ -0,0 +1,12 @@ +export const Appearance = { + Solid: 'solid', + OutlineFill: 'outline-fill', + Fill: 'fill', + Outline: 'outline', + Plain: 'plain', +} as const; + +export const appearances = Object.values(Appearance); + +export type AppearanceKey = (typeof Appearance)[keyof typeof Appearance]; +export type AppearanceValue = typeof appearances; diff --git a/packages/craftcms-cp/src/constants/colors.ts b/packages/craftcms-cp/src/constants/colors.ts new file mode 100644 index 00000000000..eab6854cccc --- /dev/null +++ b/packages/craftcms-cp/src/constants/colors.ts @@ -0,0 +1,27 @@ +export const Color = { + Red: 'red', + Orange: 'orange', + Amber: 'amber', + Yellow: 'yellow', + Lime: 'lime', + Green: 'green', + Emerald: 'emerald', + Teal: 'teal', + Cyan: 'cyan', + Sky: 'sky', + Blue: 'blue', + Indigo: 'indigo', + Violet: 'violet', + Purple: 'purple', + Fuchsia: 'fuchsia', + Pink: 'pink', + Rose: 'rose', + White: 'white', + Gray: 'gray', + Black: 'black', +} as const; + +export const colors = Object.values(Color); + +export type ColorKey = (typeof Color)[keyof typeof Color]; +export type ColorValue = typeof colors; diff --git a/packages/craftcms-cp/src/constants/variants.ts b/packages/craftcms-cp/src/constants/variants.ts new file mode 100644 index 00000000000..63742403ee1 --- /dev/null +++ b/packages/craftcms-cp/src/constants/variants.ts @@ -0,0 +1,12 @@ +export const Variant = { + Neutral: 'neutral', + Success: 'success', + Warning: 'warning', + Danger: 'danger', + Info: 'info', +} as const; + +export const variants = Object.values(Variant); + +export type VariantKey = (typeof Variant)[keyof typeof Variant]; +export type VariantValue = typeof variants; diff --git a/packages/craftcms-cp/src/index.ts b/packages/craftcms-cp/src/index.ts new file mode 100644 index 00000000000..cf4b2bab405 --- /dev/null +++ b/packages/craftcms-cp/src/index.ts @@ -0,0 +1,101 @@ +import '@github/relative-time-element'; +import {configureIcons} from './utilities/icons'; + +// Types +import './types/globals.js'; +import './types/events.js'; +import './types/index.js'; +import './types/queue.js'; + +export {default as CraftDisclosure} from './components/disclosure/disclosure.js'; +export {default as CraftSpinner} from './components/spinner/spinner.js'; +export {default as CraftTooltip} from './components/tooltip/tooltip.js'; +export {default as CraftCopyAttribute} from './components/copy-attribute/copy-attribute.js'; +export {default as CraftCopyButton} from './components/copy-button/copy-button.js'; +export {default as CraftButton} from './components/button/button.js'; +export {default as CraftAvatar} from './components/avatar/avatar.js'; +export {default as CraftInput} from './components/input/input.js'; +export {default as CraftInputFile} from './components/input-file/input-file.js'; +export {default as CraftInputHandle} from './components/input-handle/input-handle.js'; +export {default as CraftInputPassword} from './components/input-password/input-password.js'; +export {default as CraftSelectedFileList} from './components/input-file/selected-file-list.js'; +export {default as CraftChip} from './components/chip/chip.js'; +export {default as CraftStatus} from './components/status/status.js'; +export {default as CraftTextarea} from './components/textarea/textarea.js'; +export {default as CraftButtonGroup} from './components/button-group/button-group.js'; +export {default as CraftSelect} from './components/select/select.js'; +export {default as CraftOption} from './components/option/option.js'; +export {default as CraftDropdown} from './components/dropdown/dropdown.js'; +export {default as CraftIcon} from './components/icon/icon.js'; +export {default as CraftInfoIcon} from './components/info-icon/info-icon.js'; +export {default as CraftTabs} from './components/tabs/tabs.js'; +export {default as CraftCard} from './components/card/card.js'; +export {default as CraftTab} from './components/tab/tab.js'; +export {default as CraftSwitch} from './components/switch/switch.js'; +export {default as CraftSwitchButton} from './components/switch-button/switch-button.js'; +export {default as CraftBreadcrumbs} from './components/breadcrumbs/breadcrumbs.js'; +export {default as CraftBreadcrumbItem} from './components/breadcrumb-item/breadcrumb-item.js'; +export {default as CraftPopover} from './components/popover/popover.js'; +export {default as CraftNavList} from './components/nav-list/nav-list.js'; +export {default as CraftNavItem} from './components/nav-item/nav-item.js'; +export {default as CraftDrawer} from './components/drawer/drawer.js'; +export {default as CraftDialog} from './components/dialog/dialog.js'; +export {default as CraftCheckboxGroup} from './components/checkbox-group/checkbox-group.js'; +export {default as CraftCheckbox} from './components/checkbox/checkbox.js'; +export {default as CraftCheckboxIndeterminate} from './components/checkbox-indeterminate/checkbox-indeterminate.js'; +export {default as CraftCallout} from './components/callout/callout.js'; +export {default as CraftActionItem} from './components/action-item/action-item.js'; +export {default as CraftActionMenu} from './components/action-menu/action-menu.js'; +export {default as CraftCombobox} from './components/combobox/combobox.js'; +export {default as CraftIndicator} from './components/indicator/indicator.js'; +export {default as CraftShortcut} from './components/shortcut/shortcut.js'; +export {default as CraftProgress} from './components/progress/progress.js'; +export {default as CraftProgressBar} from './components/progress-bar/progress-bar.js'; +export {default as CraftRadioGroup} from './components/radio-group/radio-group.js'; +export {default as CraftRadio} from './components/radio/radio.js'; +export {default as CraftFieldGroup} from './components/field-group/field-group.js'; +export {default as CraftPane} from './components/pane/pane.js'; +export {CraftAuthChallengeForm} from './components/auth-challenge-form/auth-challenge-form.js'; +export {default as CraftVisuallyHidden} from './components/visually-hidden/visually-hidden.js'; +/* plop:component */ + +export * from './utilities/cookies.js'; +export * from './utilities/translate.js'; +export * from './utilities/format.js'; +export * from './utilities/api/actionClient.js'; +export * from './utilities/api/apiClient.js'; +export * from './utilities/string.js'; +export * from './utilities/dom.js'; + +// Services +export {QueueService} from './services/Queue.js'; +export {ConfigService} from './services/Config.js'; +export {AssetIndexer} from './services/AssetIndexer.js'; +export type { + IndexingSession, + IndexingResponse, + StartIndexingParams, + FinishIndexingParams, + ChangeEventData, + ErrorEventData, + MissingEntries, + IndexerEventType, + IndexerEventListener, +} from './services/AssetIndexer.js'; +export {IndexingActions} from './services/AssetIndexer.js'; + +// Types +export * from './types/index.js'; + +// Web component styles +export * from './styles/form.styles.js'; +export {default as hostStyles} from './styles/host.styles.js'; +export {default as variantStyles} from './styles/variants.styles.js'; +export {default as visuallyHiddenStyles} from './styles/visually-hidden.styles.js'; + +// Constants +export * from './constants/variants'; +export * from './constants/appearances'; +export * from './constants/colors'; + +configureIcons(); diff --git a/packages/craftcms-ui/src/services/AssetIndexer.ts b/packages/craftcms-cp/src/services/AssetIndexer.ts similarity index 100% rename from packages/craftcms-ui/src/services/AssetIndexer.ts rename to packages/craftcms-cp/src/services/AssetIndexer.ts diff --git a/packages/craftcms-cp/src/services/Config.ts b/packages/craftcms-cp/src/services/Config.ts new file mode 100644 index 00000000000..3f1f69b9f1f --- /dev/null +++ b/packages/craftcms-cp/src/services/Config.ts @@ -0,0 +1,55 @@ +export class ConfigService { + static #instance: ConfigService | null = null; + + #config: Map = new Map(); + + /** Get the singleton instance */ + static getInstance(initialConfig = {}): ConfigService { + if (!ConfigService.#instance) { + ConfigService.#instance = new ConfigService(); + } + return ConfigService.#instance; + } + + /** Reset the singleton (mainly for testing) */ + static resetInstance(): void { + if (ConfigService.#instance) { + ConfigService.#instance = null; + } + } + + initialize(initialConfig = {}) { + this.#config = new Map(Object.entries(initialConfig)); + } + + #buildUrl(baseUrl: string, path: string): string { + const url = new URL(baseUrl); + const cleanPath = path.startsWith('/') ? path.slice(1) : path; + url.pathname = `${url.pathname}/${cleanPath}`; + return url.toString(); + } + + getCpUrl(path: string) { + return this.#buildUrl(this.#config.get('baseCpUrl'), path); + } + + getActionUrl(path: string) { + return this.#buildUrl(this.#config.get('actionUrl'), path); + } + + all() { + return this.#config; + } + + set(key: string, value: any): void { + this.#config.set(key, value); + } + + get(key: string, fallback: any = null): any { + if (this.#config.has(key)) { + return this.#config.get(key); + } + + return fallback; + } +} diff --git a/packages/craftcms-ui/src/services/Csrf.ts b/packages/craftcms-cp/src/services/Csrf.ts similarity index 100% rename from packages/craftcms-ui/src/services/Csrf.ts rename to packages/craftcms-cp/src/services/Csrf.ts diff --git a/packages/craftcms-cp/src/services/Queue.test.ts b/packages/craftcms-cp/src/services/Queue.test.ts new file mode 100644 index 00000000000..1138e45b1ad --- /dev/null +++ b/packages/craftcms-cp/src/services/Queue.test.ts @@ -0,0 +1,147 @@ +import {afterEach, beforeEach, describe, expect, test, vi} from 'vitest'; +import {QueueService} from './Queue.js'; +import {ConfigService} from './Config.js'; +import type {JobInfo} from '../types/index.js'; +import {JobStatus} from '../types/index.js'; + +// Mock axios +vi.mock('axios', () => ({ + default: { + post: vi.fn().mockResolvedValue({}), + get: vi.fn().mockResolvedValue({data: {jobs: []}}), + }, +})); + +// Mock ConfigService +vi.mock('./Config', () => ({ + ConfigService: { + getInstance: vi.fn(() => ({ + getActionUrl: vi.fn( + (path: string) => `https://example.com/actions/${path}` + ), + })), + }, +})); + +describe('QueueService', () => { + beforeEach(() => { + QueueService.resetInstance(); + ConfigService.getInstance(); + vi.clearAllMocks(); + }); + + afterEach(() => { + QueueService.resetInstance(); + }); + + describe('runQueue', () => { + test('makes HTTP request and starts tracking when runAutomatically is true', async () => { + const axios = await import('axios'); + const queue = QueueService.getInstance(); + queue.initialize({runAutomatically: true}); + + const startTrackingSpy = vi.spyOn(queue, 'startTracking'); + await queue.runQueue(); + + expect(axios.default.post).toHaveBeenCalledWith( + 'https://example.com/actions/queue/run' + ); + expect(startTrackingSpy).toHaveBeenCalledWith(false, true); + }); + + test('skips HTTP request but still tracks when runAutomatically is false', async () => { + const axios = await import('axios'); + const queue = QueueService.getInstance(); + queue.initialize({runAutomatically: false}); + + const startTrackingSpy = vi.spyOn(queue, 'startTracking'); + await queue.runQueue(); + + expect(axios.default.post).not.toHaveBeenCalled(); + expect(startTrackingSpy).toHaveBeenCalledWith(false, true); + }); + }); + + describe('setJobData', () => { + test('selects reserved job as displayed job over pending', () => { + const queue = QueueService.getInstance(); + queue.initialize(); + + queue.setJobData([ + createMockJob({id: 1, status: JobStatus.Pending}), + createMockJob({id: 2, status: JobStatus.Reserved}), + ]); + + expect(queue.displayedJob?.id).toBe(2); + }); + + test('selects failed job as displayed job over pending', () => { + const queue = QueueService.getInstance(); + queue.initialize(); + + queue.setJobData([ + createMockJob({id: 1, status: JobStatus.Pending}), + createMockJob({id: 2, status: JobStatus.Failed}), + ]); + + expect(queue.displayedJob?.id).toBe(2); + }); + + test('skips delayed pending jobs when selecting displayed job', () => { + const queue = QueueService.getInstance(); + queue.initialize(); + + queue.setJobData([ + createMockJob({id: 1, status: JobStatus.Pending, delay: 60}), + createMockJob({id: 2, status: JobStatus.Pending, delay: 0}), + ]); + + expect(queue.displayedJob?.id).toBe(2); + }); + + test('emits job-complete event when jobs become empty', () => { + const queue = QueueService.getInstance(); + queue.initialize(); + queue.setJobData([createMockJob({id: 1, status: JobStatus.Pending})]); + + const handler = vi.fn(); + queue.addEventListener('job-complete', handler); + queue.setJobData([]); + + expect(handler).toHaveBeenCalled(); + }); + + test('emits job-failed event when displayed job is failed', () => { + const queue = QueueService.getInstance(); + queue.initialize(); + + const handler = vi.fn(); + queue.addEventListener('job-failed', handler); + queue.setJobData([createMockJob({id: 1, status: JobStatus.Failed})]); + + expect(handler).toHaveBeenCalled(); + }); + }); +}); + +function createMockJob(overrides: { + id?: number; + status: number; + delay?: number; +}): JobInfo { + const id = overrides.id ?? 1; + return { + uid: `uid-${id}`, + id: id, + description: 'Test job', + dateCreated: '2024-01-01', + progress: 0, + progressLabel: null, + status: { + label: overrides.status as any, + value: overrides.status, + }, + delay: overrides.delay ?? 0, + label: 'Test job', + }; +} diff --git a/packages/craftcms-cp/src/services/Queue.ts b/packages/craftcms-cp/src/services/Queue.ts new file mode 100644 index 00000000000..61eedc699da --- /dev/null +++ b/packages/craftcms-cp/src/services/Queue.ts @@ -0,0 +1,352 @@ +import type { + JobFailedDetail, + JobInfo, + JobStatusKey, + JobUpdateDetail, + QueueJobData, + QueueServiceOptions, +} from '@src/types'; +import {JobStatus} from '@src/types'; +import axios from 'axios'; +import {ConfigService} from '@src/services/Config'; + +/** + * Service for managing queue job tracking. + * + * @event job-update - Fired when job data changes + * @event job-complete - Fired when all jobs are done + * @event job-failed - Fired when a job fails + * + * @example + * ```ts + * const queue = QueueService.getInstance(); + * queue.addEventListener('job-update', (e) => { + * console.log(e.detail.displayedJob); + * }); + * queue.startTracking(); + * ``` + */ +export class QueueService extends EventTarget { + static #instance: QueueService | null = null; + #instanceId = Math.random().toString(36).slice(2); + + // Configuration + enabled: boolean = true; + #appId: string = ''; + canAccessQueueManager: boolean = false; + #runAutomatically: boolean = true; + + // Job state + totalJobs: number = 0; + jobInfo: JobInfo[] = []; + displayedJob: JobInfo | null = null; + displayedJobUnchangedCount: number = 1; + + // Polling control + #trackingTimeout: ReturnType | null = null; + isTracking: boolean = false; + #abortController: AbortController | null = null; + + // Cross-tab broadcasting + #broadcaster: BroadcastChannel | null = null; + + // Configuration service instance + #config: ConfigService = ConfigService.getInstance(); + + /** Get the singleton instance */ + static getInstance(): QueueService { + if (!QueueService.#instance) { + QueueService.#instance = new QueueService(); + } + return QueueService.#instance; + } + + /** Reset the singleton (mainly for testing) */ + static resetInstance(): void { + if (QueueService.#instance) { + QueueService.#instance.stopTracking(); + QueueService.#instance.#broadcaster?.close(); + QueueService.#instance = null; + } + } + + initialize(options: QueueServiceOptions = {}) { + this.#appId = options.appId ?? ''; + this.canAccessQueueManager = options.canAccessQueueManager ?? false; + this.#runAutomatically = options.runAutomatically ?? true; + this.#initBroadcaster(); + } + + // ─── Public Methods ────────────────────────────────────────────────────────── + + /** + * Run the queue and start tracking jobs. + * Sends a request to execute waiting jobs. + * Does nothing if runAutomatically is false. + */ + async runQueue(): Promise { + if (!this.#runAutomatically) { + // Just track progress without triggering queue execution + this.startTracking(false, true); + return; + } + + try { + await axios.post(this.#config.getActionUrl('queue/run')); + } catch (e: unknown) { + // Ignore errors - queue might already be running + console.error(e); + } + + this.startTracking(false, true); + } + + /** + * Start tracking job progress. + * @param delay - Delay before starting: true for adaptive delay, number for ms, false for immediate + * @param force - Force tracking even if already tracking + */ + startTracking(delay: boolean | number = false, force: boolean = false): void { + if (this.isTracking && !force) { + return; + } + + // Clear any existing timeout + if (this.#trackingTimeout) { + clearTimeout(this.#trackingTimeout); + this.#trackingTimeout = null; + } + + // Determine delay + let delayMs = 0; + if (delay === true) { + delayMs = this.#getAdaptiveDelay(); + } else if (typeof delay === 'number') { + delayMs = delay; + } + + if (delayMs > 0) { + this.#trackingTimeout = setTimeout(() => { + this.#trackJobProgress(); + }, delayMs); + } else { + this.#trackJobProgress(); + } + } + + /** Stop tracking job progress */ + stopTracking(): void { + this.isTracking = false; + + if (this.#trackingTimeout) { + clearTimeout(this.#trackingTimeout); + this.#trackingTimeout = null; + } + + if (this.#abortController) { + this.#abortController.abort(); + this.#abortController = null; + } + } + + /** + * Set job data from server response. + * Used for initial data and cross-tab sync. + */ + setJobData(data: Array): void { + this.totalJobs = data.length; + this.#setJobInfo(data); + } + + // ─── Private Methods ───────────────────────────────────────────────────────── + + #initBroadcaster(): void { + if (typeof BroadcastChannel === 'undefined' || !this.#appId) { + return; + } + + const channelName = `CraftCMS:${this.#appId}:queue`; + this.#broadcaster = new BroadcastChannel(channelName); + + this.#broadcaster.addEventListener('message', (ev) => { + this.#handleBroadcastMessage(ev.data); + }); + } + + #handleBroadcastMessage(data: { + event: string; + instanceId?: string; + jobData?: QueueJobData; + }): void { + // Ignore messages from our own tab + if (data.instanceId === this.#instanceId) return; + + switch (data.event) { + case 'beforeTrackJobProgress': + // Another tab is taking over tracking + this.stopTracking(); + break; + + case 'trackJobProgress': + // Another tab finished polling - use their data + if (data.jobData) { + this.setJobData(data.jobData.jobs); + } + // Schedule our next poll with extra delay to avoid conflicts + if (this.displayedJob !== null) { + const delay = this.#getAdaptiveDelay() + 1000; + this.startTracking(delay); + } + break; + } + } + + #broadcast(event: string, data?: object): void { + this.#broadcaster?.postMessage({ + event, + instanceId: this.#instanceId, + ...data, + }); + } + + #getAdaptiveDelay(): number { + // Start at 500ms, increase by 500ms for each unchanged poll, cap at 60s + return Math.min(60000, this.displayedJobUnchangedCount * 500); + } + + async #trackJobProgress(): Promise { + // Notify other tabs we're taking over + this.#broadcast('beforeTrackJobProgress'); + + this.isTracking = true; + this.#abortController = new AbortController(); + + try { + const response = await axios.get( + this.#config.getActionUrl('queue/get-job-info'), + { + params: {dontExtendSession: 1}, + signal: this.#abortController.signal, + } + ); + + this.setJobData(response.data.jobs); + + // Broadcast to other tabs + this.#broadcast('trackJobProgress', {jobData: response.data}); + + // Continue polling while there's an active job to display + if (this.displayedJob !== null) { + this.startTracking(true, true); + } + } catch (error) { + // Ignore aborted requests + if (error instanceof Error && error.name === 'CanceledError') { + return; + } + + // For auth errors, stop tracking - user needs to log in + const axiosError = error as {response?: {status: number}}; + if ( + axiosError.response?.status === 400 || + axiosError.response?.status === 403 + ) { + this.stopTracking(); + return; + } + + // For other errors, retry with delay if there's still an active job + if (this.displayedJob !== null) { + this.startTracking(true, true); + } + } finally { + this.isTracking = false; + this.#abortController = null; + } + } + + #displayedJobEqual(a: JobInfo | null, b: JobInfo | null): boolean { + if (a === null && b === null) return true; + if (a === null || b === null) return false; + return ( + a.id === b.id && + a.progress === b.progress && + a.progressLabel === b.progressLabel && + a.status === b.status + ); + } + + #setJobInfo(jobs: JobInfo[]): void { + const oldDisplayedJob = this.displayedJob; + + this.jobInfo = jobs; + this.displayedJob = this.#selectDisplayedJob(); + + if (this.#displayedJobEqual(oldDisplayedJob, this.displayedJob)) { + this.displayedJobUnchangedCount++; + } else { + this.displayedJobUnchangedCount = 1; + } + + // Emit events + this.#emitJobUpdate(); + + // Check for failed jobs + if (this.displayedJob?.status.value === JobStatus.Failed) { + this.#emitJobFailed(this.displayedJob); + } + + // Check for completion + if (this.displayedJob === null && oldDisplayedJob) { + this.#emitJobComplete(); + } + } + + #selectDisplayedJob(): JobInfo | null { + if (this.jobInfo?.length === 0) { + return null; + } + + // Priority: Reserved > Failed > Waiting (non-delayed) + const priorities: JobStatusKey[] = [ + JobStatus.Reserved, + JobStatus.Failed, + JobStatus.Pending, + ]; + + for (const status of priorities) { + const job = this.jobInfo.find((j) => { + if (j.status.value !== status) { + return false; + } + + // Skip delayed waiting jobs + return !(status === JobStatus.Pending && j.delay > 0); + }); + + if (job) { + return job; + } + } + + return null; + } + + #emitJobUpdate(): void { + const detail: JobUpdateDetail = { + totalJobs: this.totalJobs, + jobInfo: this.jobInfo, + displayedJob: this.displayedJob, + }; + this.dispatchEvent(new CustomEvent('job-update', {detail})); + } + + #emitJobComplete(): void { + this.dispatchEvent(new CustomEvent('job-complete')); + } + + #emitJobFailed(job: JobInfo): void { + const detail: JobFailedDetail = {job}; + this.dispatchEvent(new CustomEvent('job-failed', {detail})); + } +} diff --git a/packages/craftcms-ui/src/stories/tokens/Colors.mdx b/packages/craftcms-cp/src/stories/tokens/Colors.mdx similarity index 100% rename from packages/craftcms-ui/src/stories/tokens/Colors.mdx rename to packages/craftcms-cp/src/stories/tokens/Colors.mdx diff --git a/packages/craftcms-ui/src/stories/tokens/Docs.mdx b/packages/craftcms-cp/src/stories/tokens/Docs.mdx similarity index 100% rename from packages/craftcms-ui/src/stories/tokens/Docs.mdx rename to packages/craftcms-cp/src/stories/tokens/Docs.mdx diff --git a/packages/craftcms-ui/src/stories/tokens/colorable.stories.ts b/packages/craftcms-cp/src/stories/tokens/colorable.stories.ts similarity index 100% rename from packages/craftcms-ui/src/stories/tokens/colorable.stories.ts rename to packages/craftcms-cp/src/stories/tokens/colorable.stories.ts diff --git a/packages/craftcms-ui/src/stories/tokens/colors.stories.ts b/packages/craftcms-cp/src/stories/tokens/colors.stories.ts similarity index 100% rename from packages/craftcms-ui/src/stories/tokens/colors.stories.ts rename to packages/craftcms-cp/src/stories/tokens/colors.stories.ts diff --git a/packages/craftcms-ui/src/stories/tokens/helpers.ts b/packages/craftcms-cp/src/stories/tokens/helpers.ts similarity index 100% rename from packages/craftcms-ui/src/stories/tokens/helpers.ts rename to packages/craftcms-cp/src/stories/tokens/helpers.ts diff --git a/packages/craftcms-ui/src/stories/tokens/spacing.stories.ts b/packages/craftcms-cp/src/stories/tokens/spacing.stories.ts similarity index 100% rename from packages/craftcms-ui/src/stories/tokens/spacing.stories.ts rename to packages/craftcms-cp/src/stories/tokens/spacing.stories.ts diff --git a/packages/craftcms-ui/src/stories/tokens/surface.stories.ts b/packages/craftcms-cp/src/stories/tokens/surface.stories.ts similarity index 100% rename from packages/craftcms-ui/src/stories/tokens/surface.stories.ts rename to packages/craftcms-cp/src/stories/tokens/surface.stories.ts diff --git a/packages/craftcms-ui/src/stories/tokens/text.stories.ts b/packages/craftcms-cp/src/stories/tokens/text.stories.ts similarity index 100% rename from packages/craftcms-ui/src/stories/tokens/text.stories.ts rename to packages/craftcms-cp/src/stories/tokens/text.stories.ts diff --git a/packages/craftcms-ui/src/stories/tokens/variants.stories.ts b/packages/craftcms-cp/src/stories/tokens/variants.stories.ts similarity index 83% rename from packages/craftcms-ui/src/stories/tokens/variants.stories.ts rename to packages/craftcms-cp/src/stories/tokens/variants.stories.ts index 909b6efd29c..17e67e0b0a0 100644 --- a/packages/craftcms-ui/src/stories/tokens/variants.stories.ts +++ b/packages/craftcms-cp/src/stories/tokens/variants.stories.ts @@ -8,9 +8,10 @@ import '../../components/indicator/indicator.js'; import {appearances} from '@src/constants/appearances'; import {variants} from '@src/constants/variants'; -import {ButtonVariant} from '@src/components/button/button'; +import {ButtonVariant, ButtonAppearance} from '@src/components/button/button'; const buttonVariants = Object.values(ButtonVariant); +const buttonAppearances = Object.values(ButtonAppearance); const meta: Meta = { title: 'Tokens/Variants & Appearances', @@ -63,20 +64,42 @@ export const CalloutMatrix: Story = { }; /** - * Buttons use a single `variant` axis (primary, danger, solid, fill, outline, - * dashed, plain, link, none — plus inherit). + * Buttons use their own variant subset (accent, neutral, danger) + * and appearance subset (solid, outline, plain). */ export const ButtonMatrix: Story = { name: 'Button Matrix', render: () => html`
    -
    - ${buttonVariants.map( - (variant) => html` - ${variant} - ` - )} -
    + + + + + ${buttonAppearances.map((a) => html``)} + + + + ${buttonVariants.map( + (variant) => html` + + + ${buttonAppearances.map( + (appearance) => html` + + ` + )} + + ` + )} + +
    variant${a}
    ${variant} + + ${variant} + +
    `, }; diff --git a/packages/craftcms-ui/src/styles/color-definitions.js b/packages/craftcms-cp/src/styles/color-definitions.js similarity index 100% rename from packages/craftcms-ui/src/styles/color-definitions.js rename to packages/craftcms-cp/src/styles/color-definitions.js diff --git a/packages/craftcms-ui/src/styles/cp.css b/packages/craftcms-cp/src/styles/cp.css similarity index 100% rename from packages/craftcms-ui/src/styles/cp.css rename to packages/craftcms-cp/src/styles/cp.css diff --git a/packages/craftcms-ui/src/styles/form.styles.ts b/packages/craftcms-cp/src/styles/form.styles.ts similarity index 92% rename from packages/craftcms-ui/src/styles/form.styles.ts rename to packages/craftcms-cp/src/styles/form.styles.ts index 695c957fab4..eeba5d58567 100644 --- a/packages/craftcms-ui/src/styles/form.styles.ts +++ b/packages/craftcms-cp/src/styles/form.styles.ts @@ -20,7 +20,6 @@ export const baseInputStyles = css` flex: 1 1 auto; background-color: var(--c-input-fill, var(--c-form-control-fill)); box-shadow: var(--c-input-shadow); - overflow: clip; /* Detect mobile devices and up the font size of inputs to avoid zoom on focus */ @media (pointer: none), (pointer: coarse) { @@ -63,11 +62,6 @@ export const baseFieldStyles = css` export const inputStyles = css` ${baseFieldStyles} - :host([monospace]) .input-group__container { - font-family: var(--c-font-mono); - font-size: 0.9em; - } - ::slotted([slot='input']) { font: inherit; padding-block: 0; @@ -75,7 +69,6 @@ export const inputStyles = css` appearance: none; padding-inline: var(--c-input-spacing-inline); background-color: transparent; - width: 100%; } .input-group__container { @@ -102,8 +95,4 @@ export const inputStyles = css` :host([center]) ::slotted([slot='input']) { text-align: center; } - - ::slotted([slot='input']) { - width: 100%; - } `; diff --git a/packages/craftcms-ui/src/styles/host.styles.ts b/packages/craftcms-cp/src/styles/host.styles.ts similarity index 100% rename from packages/craftcms-ui/src/styles/host.styles.ts rename to packages/craftcms-cp/src/styles/host.styles.ts diff --git a/packages/craftcms-cp/src/styles/shared/base.css b/packages/craftcms-cp/src/styles/shared/base.css new file mode 100644 index 00000000000..db9f1b089db --- /dev/null +++ b/packages/craftcms-cp/src/styles/shared/base.css @@ -0,0 +1,270 @@ +html, +body { + background-color: var(--c-surface-default); +} + +body { + width: 100%; + overflow-x: hidden; + font-family: var(--c-font-body, sans-serif); + font-size: var(--c-text-base); + line-height: var(--c-leading-normal); + color: var(--c-text-default); + -webkit-font-smoothing: subpixel-antialiased; +} + +h1, +h2, +h3, +h4, +h5, +h6, +p, +pre { + margin: 0; +} + +a { + cursor: pointer; + color: var(--c-text-link); +} + +/* + Make lists unstyled by default. +*/ + +ol, +ul { + margin: 0; + padding: 0; + list-style: none; +} + +.cp-code { + font-size: 0.75em; + font-family: var(--c-font-mono); + display: inline-flex; + padding: 0 var(--c-spacing-sm); + color: var(--c-color-on-quiet); + border: 1px solid var(--c-color-border-quiet); + background-color: color-mix( + var(--c-color-fill-quiet) 90%, + var(--c-color-fill-loud) + ); + border-radius: var(--c-radius-sm); +} + +.cp-icon { + width: 1em; + height: 1em; +} + +hr { + display: block; + width: 100%; + border: 0; + height: 0; + border-block-start: 1px solid var(--c-color-neutral-border-quiet); + margin-block: var(--c-spacing-lg); + margin-inline: 0; + color: transparent; +} + +.index-grid { + display: grid; + gap: var(--c-spacing-md); + + @container (width >= 768px) { + grid-template-columns: + clamp(calc(120rem / 16), 20%, calc(220rem / 16)) + 6fr; + align-items: start; + } +} + +.index-grid__aside, +.index-grid__main { + display: flex; + gap: var(--c-spacing-md); + align-items: center; +} + +.index-grid--header { + align-items: center; + min-height: calc(40rem / 16); + padding-block: var(--c-spacing-lg); + + @container (width >= 768px) { + padding-block-end: var(--c-spacing-md); + } +} + +.index-grid--header .index-grid__main { + @container (width >= 768px) { + justify-self: end; + } +} + +/** +Prose class, wrap around WYSIWYG text or markdown text. +Previously `.readable` + */ +.prose { + > *:first-child { + margin-block-start: 0; + } + + h1, + h2, + h3, + h4, + h5, + h6 { + margin-block: 0.5rem; + } + + ol, + ul { + padding-inline-start: 1.5em; + display: grid; + gap: 0.25em; + } + + ul { + list-style: disc; + } +} + +/** +CP Table + +Applies some basic styling to table elements. + +The idea here is that you can just apply `cp-table` to the parent table and have +most of the element display correctly which is why we don't do BEM or anything here + +Modify with `cp-table--compact` to reduce the vertical cell padding +Modify with `cp-table--borderless` to remove the inline cell padding +Modify with `cp-table--auto` to apply table-layout: auto + */ +.cp-table { + --_cell-spacing-inline: var(--c-spacing-md); + --_cell-spacing-block: var(--c-spacing-md); + text-align: left; + width: 100%; + border-spacing: 0; + font-variant-numeric: tabular-nums; + + @container (width >= 840px) { + table-layout: fixed; + } + + thead, + th { + background-color: var(--c-color-neutral-fill-quiet); + } + + th, + td { + padding-block: var(--_cell-spacing-block); + padding-inline: var(--_cell-spacing-inline); + position: relative; + + &:has(.cp-table-input:not([type='checkbox']):not([type='radio'])) { + padding: 0; + } + } + + td, + th { + border-block-end: 1px solid + color-mix(var(--c-color-neutral-border-quiet) 60%, transparent); + } + + /* Add a rule to the first cells */ + tr:first-child { + td, + th { + border-block-start: 1px solid + color-mix(var(--c-color-neutral-border-quiet) 60%, transparent); + } + } + + textarea, + input:not([type='checkbox']):not([type='radio']) { + border: 0; + padding-block: var(--_cell-spacing-block); + padding-inline: var(--_cell-spacing-inline); + margin: 0; + width: 100%; + height: 100%; + } + + textarea { + resize: none; + line-height: 1.2; + } +} + +.cp-table--ruled { + td:not(:first-child), + th:not(:first-child) { + border-inline-start: 1px solid var(--c-color-neutral-border-quiet); + } +} + +.cp-table--grid { + --table-column-count: auto-fill; + --table-template-columns: repeat(var(--table-column-count), 1fr); + + tr { + display: grid; + grid-template-columns: var(--table-template-columns); + grid-template-rows: minmax(var(--c-size-control-md), auto); + } + + th, + td { + display: flex; + align-items: start; + flex-direction: column; + justify-content: center; + } +} + +.cp-table--padded { + th, + td { + padding-block: var(--c-spacing-md); + } +} + +.cp-table--auto { + table-layout: auto; +} + +.cp-table--fixed { + table-layout: fixed; +} + +.cp-table--collapsed, +.cp-table--borderless { + --_cell-spacing-block: 0; +} + +.cp-table--compact { + --_cell-spacing-block: var(--c-spacing-sm); +} + +.cp-table--spacious { + --_cell-spacing-block: var(--c-spacing-lg); +} + +.cp-table-header, +.cp-table-footer { + padding: var(--c-spacing-md); + background-color: var(--c-color-neutral-fill-quiet); + display: flex; + align-items: center; + justify-content: space-between; +} diff --git a/packages/craftcms-ui/src/styles/shared/color-palette.css b/packages/craftcms-cp/src/styles/shared/color-palette.css similarity index 100% rename from packages/craftcms-ui/src/styles/shared/color-palette.css rename to packages/craftcms-cp/src/styles/shared/color-palette.css diff --git a/packages/craftcms-ui/src/styles/shared/colorable.css b/packages/craftcms-cp/src/styles/shared/colorable.css similarity index 93% rename from packages/craftcms-ui/src/styles/shared/colorable.css rename to packages/craftcms-cp/src/styles/shared/colorable.css index c97c886df11..c4d1f2fa47b 100644 --- a/packages/craftcms-ui/src/styles/shared/colorable.css +++ b/packages/craftcms-cp/src/styles/shared/colorable.css @@ -220,17 +220,6 @@ --c-color-black-on-quiet: var(--color-static-gray-100); --c-color-black-on-normal: var(--color-static-gray-100); --c-color-black-on-loud: var(--color-static-gray-100); - - /* slate */ - --c-color-slate-fill-quiet: var(--color-slate-50); - --c-color-slate-fill-normal: var(--color-slate-100); - --c-color-slate-fill-loud: var(--color-slate-600); - --c-color-slate-border-quiet: var(--color-slate-400); - --c-color-slate-border-normal: var(--color-slate-600); - --c-color-slate-border-loud: var(--color-slate-800); - --c-color-slate-on-quiet: var(--color-slate-800); - --c-color-slate-on-normal: var(--color-slate-950); - --c-color-slate-on-loud: var(--color-slate-50); /* Semantics colors - neutral */ --c-color-neutral-fill-quiet: var(--color-slate-50); --c-color-neutral-fill-normal: var(--color-slate-100); @@ -243,26 +232,26 @@ --c-color-neutral-on-loud: var(--color-slate-50); /* Semantics colors - accent */ - --c-color-accent-fill-quiet: var(--color-blue-50); - --c-color-accent-fill-normal: var(--color-blue-100); - --c-color-accent-fill-loud: var(--color-blue-600); - --c-color-accent-border-quiet: var(--color-blue-400); - --c-color-accent-border-normal: var(--color-blue-600); - --c-color-accent-border-loud: var(--color-blue-800); - --c-color-accent-on-quiet: var(--color-blue-800); - --c-color-accent-on-normal: var(--color-blue-950); - --c-color-accent-on-loud: var(--color-blue-50); + --c-color-accent-fill-quiet: var(--color-red-50); + --c-color-accent-fill-normal: var(--color-red-100); + --c-color-accent-fill-loud: var(--color-red-600); + --c-color-accent-border-quiet: var(--color-red-400); + --c-color-accent-border-normal: var(--color-red-600); + --c-color-accent-border-loud: var(--color-red-800); + --c-color-accent-on-quiet: var(--color-red-800); + --c-color-accent-on-normal: var(--color-red-950); + --c-color-accent-on-loud: var(--color-red-50); /* Semantics colors - info */ - --c-color-info-fill-quiet: var(--color-sky-50); - --c-color-info-fill-normal: var(--color-sky-100); - --c-color-info-fill-loud: var(--color-sky-600); - --c-color-info-border-quiet: var(--color-sky-400); - --c-color-info-border-normal: var(--color-sky-600); - --c-color-info-border-loud: var(--color-sky-800); - --c-color-info-on-quiet: var(--color-sky-800); - --c-color-info-on-normal: var(--color-sky-950); - --c-color-info-on-loud: var(--color-sky-50); + --c-color-info-fill-quiet: var(--color-blue-50); + --c-color-info-fill-normal: var(--color-blue-100); + --c-color-info-fill-loud: var(--color-blue-600); + --c-color-info-border-quiet: var(--color-blue-400); + --c-color-info-border-normal: var(--color-blue-600); + --c-color-info-border-loud: var(--color-blue-800); + --c-color-info-on-quiet: var(--color-blue-800); + --c-color-info-on-normal: var(--color-blue-950); + --c-color-info-on-loud: var(--color-blue-50); /* Semantics colors - success */ --c-color-success-fill-quiet: var(--color-emerald-50); @@ -538,18 +527,6 @@ --c-color-border-loud: var(--c-color-black-border-loud); --c-color-on-loud: var(--c-color-black-on-loud); } -.cp-color-slate, -[data-color='slate'] { - --c-color-fill-quiet: var(--c-color-slate-fill-quiet); - --c-color-border-quiet: var(--c-color-slate-border-quiet); - --c-color-on-quiet: var(--c-color-slate-on-quiet); - --c-color-fill-normal: var(--c-color-slate-fill-normal); - --c-color-border-normal: var(--c-color-slate-border-normal); - --c-color-on-normal: var(--c-color-slate-on-normal); - --c-color-fill-loud: var(--c-color-slate-fill-loud); - --c-color-border-loud: var(--c-color-slate-border-loud); - --c-color-on-loud: var(--c-color-slate-on-loud); -} .cp-color-neutral, [data-color='neutral'] { --c-color-fill-quiet: var(--c-color-neutral-fill-quiet); diff --git a/packages/craftcms-ui/src/styles/shared/preflight.css b/packages/craftcms-cp/src/styles/shared/preflight.css similarity index 100% rename from packages/craftcms-ui/src/styles/shared/preflight.css rename to packages/craftcms-cp/src/styles/shared/preflight.css diff --git a/packages/craftcms-ui/src/styles/shared/tokens.css b/packages/craftcms-cp/src/styles/shared/tokens.css similarity index 95% rename from packages/craftcms-ui/src/styles/shared/tokens.css rename to packages/craftcms-cp/src/styles/shared/tokens.css index 47d6accd0e7..8338d1a75dd 100644 --- a/packages/craftcms-ui/src/styles/shared/tokens.css +++ b/packages/craftcms-cp/src/styles/shared/tokens.css @@ -7,11 +7,6 @@ --c-leading-normal: 1.42; - /* Focus outline tokens */ - --c-color-focus-outline: var(--color-blue-500); - --c-focus-outline-offset: 2px; - --c-focus-outline-width: 2px; - /* Surface tokens (replaces --c-bg-*) */ --c-surface-default: var(--color-base-100); --c-surface-raised: var(--color-base-50); @@ -59,7 +54,6 @@ --c-spacing-2xl: calc(var(--c-spacing) * 16); --c-size-touch-target: calc(34rem / 16); - --c-size-touch-target-sm: calc(24rem / 16); --c-size-icon-xs: calc(10rem / 16); --c-size-icon-sm: calc(12rem / 16); @@ -208,4 +202,15 @@ --c-modal-shadow: 0 0 0 1px hsl(from var(--color-gray-400) h s l / 25%), 0 25px 100px hsl(from var(--color-gray-900) h s l / 50%); + + /** + Web Awesome + */ + --wa-panel-border-style: solid; + --wa-panel-border-width: 1px; + --wa-color-surface-border: var(--c-color-neutral-border-quiet); + --wa-panel-border-color: var(--c-color-neutral-border-quiet); + --wa-panel-border-radius: var(--c-radius-md); + --wa-color-surface-raised: var(--c-surface-raised); + --wa-shadow-l: var(--c-shadow-lg); } diff --git a/packages/craftcms-ui/src/styles/shared/variables.css b/packages/craftcms-cp/src/styles/shared/variables.css similarity index 91% rename from packages/craftcms-ui/src/styles/shared/variables.css rename to packages/craftcms-cp/src/styles/shared/variables.css index f9ae07ab4ce..863a86a36ad 100644 --- a/packages/craftcms-ui/src/styles/shared/variables.css +++ b/packages/craftcms-cp/src/styles/shared/variables.css @@ -143,33 +143,33 @@ --c-color-on-quiet: var(--c-color-neutral-on-quiet); --c-color-on-normal: var(--c-color-neutral-on-normal); --c-color-on-loud: var(--c-color-neutral-on-loud); -} -@keyframes spin { - to { - transform: rotate(360deg); + @keyframes spin { + to { + transform: rotate(360deg); + } } -} -@keyframes ping { - 75%, - 100% { - transform: scale(2); - opacity: 0; + @keyframes ping { + 75%, + 100% { + transform: scale(2); + opacity: 0; + } } -} -@keyframes pulse { - 50% { - opacity: 0.5; - } -} -@keyframes bounce { - 0%, - 100% { - transform: translateY(-25%); - animation-timing-function: cubic-bezier(0.8, 0, 1, 1); + @keyframes pulse { + 50% { + opacity: 0.5; + } } - 50% { - transform: none; - animation-timing-function: cubic-bezier(0, 0, 0.2, 1); + @keyframes bounce { + 0%, + 100% { + transform: translateY(-25%); + animation-timing-function: cubic-bezier(0.8, 0, 1, 1); + } + 50% { + transform: none; + animation-timing-function: cubic-bezier(0, 0, 0.2, 1); + } } } diff --git a/packages/craftcms-ui/src/styles/static-variants.styles.ts b/packages/craftcms-cp/src/styles/static-variants.styles.ts similarity index 100% rename from packages/craftcms-ui/src/styles/static-variants.styles.ts rename to packages/craftcms-cp/src/styles/static-variants.styles.ts diff --git a/packages/craftcms-cp/src/styles/variants.styles.ts b/packages/craftcms-cp/src/styles/variants.styles.ts new file mode 100644 index 00000000000..906db69267b --- /dev/null +++ b/packages/craftcms-cp/src/styles/variants.styles.ts @@ -0,0 +1,63 @@ +import {css} from 'lit'; + +export default css` + :host([variant='default']) { + --c-color-fill-loud: var(--c-color-neutral-fill-loud); + --c-color-fill-normal: var(--c-color-neutral-fill-normal); + --c-color-fill-quiet: var(--c-color-neutral-fill-quiet); + --c-color-border-loud: var(--c-color-neutral-border-loud); + --c-color-border-normal: var(--c-color-neutral-border-normal); + --c-color-border-quiet: var(--c-color-neutral-border-quiet); + --c-color-on-loud: var(--c-color-neutral-on-loud); + --c-color-on-normal: var(--c-color-neutral-on-normal); + --c-color-on-quiet: var(--c-color-neutral-on-quiet); + } + + :host([variant='danger']) { + --c-color-fill-loud: var(--c-color-danger-fill-loud); + --c-color-fill-normal: var(--c-color-danger-fill-normal); + --c-color-fill-quiet: var(--c-color-danger-fill-quiet); + --c-color-border-loud: var(--c-color-danger-border-loud); + --c-color-border-normal: var(--c-color-danger-border-normal); + --c-color-border-quiet: var(--c-color-danger-border-quiet); + --c-color-on-loud: var(--c-color-danger-on-loud); + --c-color-on-normal: var(--c-color-danger-on-normal); + --c-color-on-quiet: var(--c-color-danger-on-quiet); + } + + :host([variant='info']) { + --c-color-fill-loud: var(--c-color-info-fill-loud); + --c-color-fill-normal: var(--c-color-info-fill-normal); + --c-color-fill-quiet: var(--c-color-info-fill-quiet); + --c-color-border-loud: var(--c-color-info-border-loud); + --c-color-border-normal: var(--c-color-info-border-normal); + --c-color-border-quiet: var(--c-color-info-border-quiet); + --c-color-on-loud: var(--c-color-info-on-loud); + --c-color-on-normal: var(--c-color-info-on-normal); + --c-color-on-quiet: var(--c-color-info-on-quiet); + } + + :host([variant='warning']) { + --c-color-fill-loud: var(--c-color-warning-fill-loud); + --c-color-fill-normal: var(--c-color-warning-fill-normal); + --c-color-fill-quiet: var(--c-color-warning-fill-quiet); + --c-color-border-loud: var(--c-color-warning-border-loud); + --c-color-border-normal: var(--c-color-warning-border-normal); + --c-color-border-quiet: var(--c-color-warning-border-quiet); + --c-color-on-loud: var(--c-color-warning-on-loud); + --c-color-on-normal: var(--c-color-warning-on-normal); + --c-color-on-quiet: var(--c-color-warning-on-quiet); + } + + :host([variant='success']) { + --c-color-fill-loud: var(--c-color-success-fill-loud); + --c-color-fill-normal: var(--c-color-success-fill-normal); + --c-color-fill-quiet: var(--c-color-success-fill-quiet); + --c-color-border-loud: var(--c-color-success-border-loud); + --c-color-border-normal: var(--c-color-success-border-normal); + --c-color-border-quiet: var(--c-color-success-border-quiet); + --c-color-on-loud: var(--c-color-success-on-loud); + --c-color-on-normal: var(--c-color-success-on-normal); + --c-color-on-quiet: var(--c-color-success-on-quiet); + } +`; diff --git a/packages/craftcms-ui/src/styles/visually-hidden.styles.ts b/packages/craftcms-cp/src/styles/visually-hidden.styles.ts similarity index 100% rename from packages/craftcms-ui/src/styles/visually-hidden.styles.ts rename to packages/craftcms-cp/src/styles/visually-hidden.styles.ts diff --git a/packages/craftcms-ui/src/types/events.ts b/packages/craftcms-cp/src/types/events.ts similarity index 100% rename from packages/craftcms-ui/src/types/events.ts rename to packages/craftcms-cp/src/types/events.ts diff --git a/packages/craftcms-cp/src/types/globals.ts b/packages/craftcms-cp/src/types/globals.ts new file mode 100644 index 00000000000..f6c8a51ed29 --- /dev/null +++ b/packages/craftcms-cp/src/types/globals.ts @@ -0,0 +1,45 @@ +import {QueueService} from '@src/services/Queue'; +import {ConfigService} from '@src/services/Config'; + +declare const d3: any | undefined; +declare const d3FormatLocaleDefinition: any | undefined; + +interface ProgressBarInterface { + $progressBar: JQuery; + + new ( + $element: JQuery, + displaySteps?: boolean, + settings?: Object + ): ProgressBarInterface; + + setItemCount(count: number): void; + + setProcessedItemCount(count: number): void; + + updateProgressBar(): void; + + showProgressBar(): void; +} + +interface IntervalManagerInterface { + new (settings?: Object): IntervalManagerInterface; + + stop(): void; + + start(): void; +} + +type Site = { + handle: string; + id: number; + name: string; + uid: string; +}; + +export interface CpServices { + $queue: QueueService; + $config: ConfigService; +} + +export {}; diff --git a/packages/craftcms-cp/src/types/index.ts b/packages/craftcms-cp/src/types/index.ts new file mode 100644 index 00000000000..f8866fcbcc4 --- /dev/null +++ b/packages/craftcms-cp/src/types/index.ts @@ -0,0 +1,16 @@ +export interface DateObject { + date: string; + timezone_type: string; + timezone: string; +} + +export const AsyncStates = { + Idle: 'idle', + Loading: 'loading', + Success: 'success', + Error: 'error', +} as const; + +export type AsyncState = (typeof AsyncStates)[keyof typeof AsyncStates]; + +export * from './queue.js'; diff --git a/resources/js/modules/queue/types.ts b/packages/craftcms-cp/src/types/queue.ts similarity index 100% rename from resources/js/modules/queue/types.ts rename to packages/craftcms-cp/src/types/queue.ts diff --git a/packages/craftcms-cp/src/utilities/api/actionClient.ts b/packages/craftcms-cp/src/utilities/api/actionClient.ts new file mode 100644 index 00000000000..4969ff9b1a4 --- /dev/null +++ b/packages/craftcms-cp/src/utilities/api/actionClient.ts @@ -0,0 +1,86 @@ +import axios, {type RawAxiosRequestHeaders} from 'axios'; +import {Csrf} from '@src/services/Csrf'; + +/** + * @TODO + */ +export function getActionUrl(action: string = '') { + return `/admin/actions/${action}`; +} + +/** + * @TODO + */ +export function actionHeaders(): RawAxiosRequestHeaders { + let headers: Record = { + 'X-Registered-Asset-Bundles': [...new Set(Cp.registeredAssetBundles)].join( + ',' + ), + 'X-Registered-Js-Files': [...new Set(Cp.registeredJsFiles)].join(','), + }; + + // @TODO Make sure we really don't need this anymore + // if (Cp.csrfTokenValue) { + // headers['X-CSRF-Token'] = Cp.csrfTokenValue; + // } + + return headers; +} + +export const actionClient = axios.create({ + baseURL: getActionUrl(), +}); + +const csrf = new Csrf(); + +actionClient.interceptors.request.use(async (config) => { + // Set X-Requested-With header + config.headers.set('X-Requested-With', 'XMLHttpRequest'); + + // Merge action headers + const headers = actionHeaders(); + Object.entries(headers).forEach(([key, value]) => { + config.headers.set(key, value); + }); + + // @TODO Make sure we really don't need this anymore + // if ( + // ['post', 'put', 'patch', 'delete'].includes( + // config.method?.toLowerCase() || '' + // ) && + // !config.url?.includes('users/session-info') + // ) { + // const tokenValue = await csrf.getToken(); + // if (tokenValue) { + // config.headers.set('X-CSRF-Token', tokenValue); + // } + // } + + return config; +}); + +actionClient.interceptors.response.use( + (response) => response, + async (error) => { + const originalRequest = error.config; + + if ( + error.response?.status === 419 || + (error.response?.status === 403 && !originalRequest._retry) + ) { + originalRequest._retry = true; + + try { + csrf.clearToken(); + originalRequest.headers['X-CSRF-Token'] = await csrf.refreshToken(); + + return axios(originalRequest); + } catch (refreshError) { + console.error('Failed to refresh CSRF token:', refreshError); + return Promise.reject(refreshError); + } + } + + return Promise.reject(error); + } +); diff --git a/packages/craftcms-ui/src/utilities/api/apiClient.ts b/packages/craftcms-cp/src/utilities/api/apiClient.ts similarity index 100% rename from packages/craftcms-ui/src/utilities/api/apiClient.ts rename to packages/craftcms-cp/src/utilities/api/apiClient.ts diff --git a/packages/craftcms-ui/src/utilities/cookies.test.ts b/packages/craftcms-cp/src/utilities/cookies.test.ts similarity index 96% rename from packages/craftcms-ui/src/utilities/cookies.test.ts rename to packages/craftcms-cp/src/utilities/cookies.test.ts index 85ef898b48b..47ca9c8cafe 100644 --- a/packages/craftcms-ui/src/utilities/cookies.test.ts +++ b/packages/craftcms-cp/src/utilities/cookies.test.ts @@ -1,5 +1,5 @@ import {Cookies} from './cookies.js'; -import {beforeEach, describe, expect, test} from 'vite-plus/test'; +import {beforeEach, describe, expect, test} from 'vitest'; describe('Cookies', () => { beforeEach(() => { diff --git a/packages/craftcms-ui/src/utilities/cookies.ts b/packages/craftcms-cp/src/utilities/cookies.ts similarity index 100% rename from packages/craftcms-ui/src/utilities/cookies.ts rename to packages/craftcms-cp/src/utilities/cookies.ts diff --git a/packages/craftcms-cp/src/utilities/dom.test.ts b/packages/craftcms-cp/src/utilities/dom.test.ts new file mode 100644 index 00000000000..aceeca14a8c --- /dev/null +++ b/packages/craftcms-cp/src/utilities/dom.test.ts @@ -0,0 +1,165 @@ +import {describe, test, expect, beforeEach, vi} from 'vitest'; + +// Prevent happy-dom from making real network requests for CSS/JS files +const happyDOM = (window as any).happyDOM; +if (happyDOM?.settings) { + happyDOM.settings.disableCSSFileLoading = true; + happyDOM.settings.disableJavaScriptFileLoading = true; +} + +// Helper to get a fresh module instance (resets cached existingCss/existingJs) +async function freshImport() { + vi.resetModules(); + return await import('./dom.js'); +} + +describe('appendHeadHtml', () => { + beforeEach(() => { + document.head.innerHTML = ''; + document.body.innerHTML = ''; + }); + + test('does nothing for empty string', async () => { + const {appendHeadHtml} = await freshImport(); + await appendHeadHtml(''); + expect(document.head.children.length).toBe(0); + }); + + test('appends a link element to head', async () => { + const {appendHeadHtml} = await freshImport(); + await appendHeadHtml( + '' + ); + const links = document.head.querySelectorAll('link'); + expect(links.length).toBe(1); + expect(links[0].getAttribute('rel')).toBe('stylesheet'); + expect(links[0].getAttribute('href')).toBe('https://example.com/style.css'); + }); + + test('appends a script element to head', async () => { + const {appendHeadHtml} = await freshImport(); + await appendHeadHtml( + '' + ); + const scripts = document.head.querySelectorAll('script'); + expect(scripts.length).toBe(1); + expect(scripts[0].getAttribute('src')).toBe( + 'https://example.com/script.js' + ); + }); + + test('appends an inline script to head', async () => { + const {appendHeadHtml} = await freshImport(); + await appendHeadHtml(''); + const scripts = document.head.querySelectorAll('script'); + expect(scripts.length).toBe(1); + expect(scripts[0].textContent).toBe('console.log("hello")'); + }); + + test('appends arbitrary HTML to head', async () => { + const {appendHeadHtml} = await freshImport(); + await appendHeadHtml(''); + const metas = document.head.querySelectorAll('meta[name="description"]'); + expect(metas.length).toBe(1); + expect(metas[0].getAttribute('content')).toBe('test'); + }); + + test('preserves link attributes when appending', async () => { + const {appendHeadHtml} = await freshImport(); + await appendHeadHtml( + '' + ); + const link = document.head.querySelector('link')!; + expect(link.getAttribute('rel')).toBe('stylesheet'); + expect(link.getAttribute('href')).toBe('https://example.com/a.css'); + expect(link.getAttribute('media')).toBe('print'); + expect(link.getAttribute('crossorigin')).toBe('anonymous'); + }); + + test('preserves script attributes when appending', async () => { + const {appendHeadHtml} = await freshImport(); + await appendHeadHtml( + '' + ); + const script = document.head.querySelector('script')!; + expect(script.getAttribute('src')).toBe('https://example.com/b.js'); + expect(script.getAttribute('type')).toBe('module'); + expect(script.hasAttribute('defer')).toBe(true); + }); +}); + +describe('appendBodyHtml', () => { + beforeEach(() => { + document.head.innerHTML = ''; + document.body.innerHTML = ''; + }); + + test('appends elements to body', async () => { + const {appendBodyHtml} = await freshImport(); + await appendBodyHtml('
    Hello
    '); + const div = document.body.querySelector('#test-div'); + expect(div).not.toBeNull(); + expect(div!.textContent).toBe('Hello'); + }); + + test('appends script with src to body', async () => { + const {appendBodyHtml} = await freshImport(); + await appendBodyHtml(''); + const scripts = document.body.querySelectorAll('script'); + expect(scripts.length).toBe(1); + expect(scripts[0].getAttribute('src')).toBe('https://example.com/body.js'); + }); +}); + +describe('CSS deduplication', () => { + beforeEach(() => { + document.head.innerHTML = ''; + document.body.innerHTML = ''; + }); + + test('does not add duplicate CSS links', async () => { + const {appendHeadHtml} = await freshImport(); + const css = ''; + await appendHeadHtml(css); + await appendHeadHtml(css); + const links = document.head.querySelectorAll('link'); + expect(links.length).toBe(1); + }); + + test('adds different CSS links', async () => { + const {appendHeadHtml} = await freshImport(); + await appendHeadHtml( + '' + ); + await appendHeadHtml( + '' + ); + const links = document.head.querySelectorAll('link'); + expect(links.length).toBe(2); + }); +}); + +describe('JS deduplication', () => { + beforeEach(() => { + document.head.innerHTML = ''; + document.body.innerHTML = ''; + }); + + test('does not add duplicate script src', async () => { + const {appendBodyHtml} = await freshImport(); + const js = ''; + await appendBodyHtml(js); + await appendBodyHtml(js); + const scripts = document.body.querySelectorAll('script'); + expect(scripts.length).toBe(1); + }); + + test('inline scripts are always added (no deduplication)', async () => { + const {appendBodyHtml} = await freshImport(); + const inline = ''; + await appendBodyHtml(inline); + await appendBodyHtml(inline); + const scripts = document.body.querySelectorAll('script'); + expect(scripts.length).toBe(2); + }); +}); diff --git a/packages/craftcms-cp/src/utilities/dom.ts b/packages/craftcms-cp/src/utilities/dom.ts new file mode 100644 index 00000000000..0f133bf3263 --- /dev/null +++ b/packages/craftcms-cp/src/utilities/dom.ts @@ -0,0 +1,131 @@ +let existingCss: string[] | null = null; +let existingJs: string[] | null = null; + +/** + * Disposer returned from {@link appendHeadHtml} / {@link appendBodyHtml}. + * Calling it removes any nodes that were appended and rolls back the + * dedup cache entries for stylesheets and scripts that were added. + */ +export type AppendHtmlDisposer = () => void; + +async function appendHtml( + html: string, + parent: HTMLElement +): Promise { + const appended: Node[] = []; + const cssAdded: string[] = []; + const jsAdded: string[] = []; + + const dispose: AppendHtmlDisposer = () => { + for (const node of appended) { + node.parentNode?.removeChild(node); + } + if (existingCss) { + for (const href of cssAdded) { + const idx = existingCss.indexOf(href); + if (idx !== -1) { + existingCss.splice(idx, 1); + } + } + } + if (existingJs) { + for (const src of jsAdded) { + const idx = existingJs.indexOf(src); + if (idx !== -1) { + existingJs.splice(idx, 1); + } + } + } + }; + + if (!html) { + return dispose; + } + + const div = document.createElement('div'); + div.innerHTML = html.trim(); + const nodes = Array.from(div.childNodes); + + for (const node of nodes) { + if (node instanceof HTMLLinkElement && node.href) { + if (!existingCss) { + existingCss = Array.from(document.querySelectorAll('link[href]')).map( + (n) => (n as HTMLLinkElement).href.replace(/&/g, '&') + ); + } + + const href = node.href.replace(/&/g, '&'); + if (existingCss.includes(href)) { + continue; + } + + existingCss.push(href); + cssAdded.push(href); + const link = document.createElement('link'); + Array.from(node.attributes).forEach((attr) => { + link.setAttribute(attr.name, attr.value); + }); + parent.appendChild(link); + appended.push(link); + continue; + } + + if (node instanceof HTMLScriptElement) { + const script = document.createElement('script'); + Array.from(node.attributes).forEach((attr) => { + script.setAttribute(attr.name, attr.value); + }); + + if (node.src) { + if (!existingJs) { + existingJs = Array.from(document.querySelectorAll('script[src]')).map( + (n) => (n as HTMLScriptElement).src.replace(/&/g, '&') + ); + } + + const src = node.src.replace(/&/g, '&'); + if (existingJs.includes(src)) { + continue; + } + + existingJs.push(src); + jsAdded.push(src); + script.async = false; + } else { + script.textContent = node.textContent; + } + + parent.appendChild(script); + appended.push(script); + continue; + } + + const cloned = node.cloneNode(true); + parent.appendChild(cloned); + appended.push(cloned); + } + + return dispose; +} + +/** + * Appends HTML to the page ``. + * + * Returns a disposer that removes the appended nodes when called. + */ +export async function appendHeadHtml( + html: string +): Promise { + return appendHtml(html, document.head); +} + +/** + * Appends HTML to the page ``. + * + * Returns a disposer that removes the appended nodes when called. + */ +export async function appendBodyHtml( + html: string +): Promise { + return appendHtml(html, document.body); +} diff --git a/packages/craftcms-ui/src/utilities/escapeHtml.ts b/packages/craftcms-cp/src/utilities/escapeHtml.ts similarity index 100% rename from packages/craftcms-ui/src/utilities/escapeHtml.ts rename to packages/craftcms-cp/src/utilities/escapeHtml.ts diff --git a/packages/craftcms-ui/src/utilities/format.test.ts b/packages/craftcms-cp/src/utilities/format.test.ts similarity index 98% rename from packages/craftcms-ui/src/utilities/format.test.ts rename to packages/craftcms-cp/src/utilities/format.test.ts index 0c6553eff39..0549ea33810 100644 --- a/packages/craftcms-ui/src/utilities/format.test.ts +++ b/packages/craftcms-cp/src/utilities/format.test.ts @@ -1,4 +1,4 @@ -import {describe, test, expect} from 'vite-plus/test'; +import {describe, test, expect} from 'vitest'; import {formatNumber} from './format.js'; describe('formatNumber', () => { diff --git a/packages/craftcms-ui/src/utilities/format.ts b/packages/craftcms-cp/src/utilities/format.ts similarity index 100% rename from packages/craftcms-ui/src/utilities/format.ts rename to packages/craftcms-cp/src/utilities/format.ts diff --git a/packages/craftcms-cp/src/utilities/icons.test.ts b/packages/craftcms-cp/src/utilities/icons.test.ts new file mode 100644 index 00000000000..d5af6fdcc85 --- /dev/null +++ b/packages/craftcms-cp/src/utilities/icons.test.ts @@ -0,0 +1,14 @@ +import {describe, test, expect} from 'vitest'; +import {getIconUrl} from './icons.js'; + +describe('getIconUrl', () => { + test.for([ + ['custom-icons/graphql', '/vendor/craft/icons/custom-icons/graphql.svg'], + ['light/sliders', '/vendor/craft/icons/light/sliders.svg'], + ['x', '/vendor/craft/icons/regular/x.svg'], + ['newstamp', '/vendor/craft/icons/regular/certificate.svg'], + ])('%s', ([name, expected]) => { + // console.log(args); + expect(getIconUrl(name as string)).toBe(expected as string); + }); +}); diff --git a/packages/craftcms-cp/src/utilities/icons.ts b/packages/craftcms-cp/src/utilities/icons.ts new file mode 100644 index 00000000000..bcd65d2df8c --- /dev/null +++ b/packages/craftcms-cp/src/utilities/icons.ts @@ -0,0 +1,119 @@ +import {registerIconLibrary} from '@awesome.me/webawesome/dist/webawesome.js'; + +const LEGACY_NAMES: Record = { + alert: 'triangle-exclamation', + asc: 'arrow-down-short-wide', + asset: 'image', + assets: 'image', + circleuarr: 'circle-arrow-up', + collapse: 'down-left-and-up-right-to-center', + condition: 'diamond', + darr: 'arrow-down', + date: 'calendar', + desc: 'arrow-down-wide-short', + disabled: 'circle-dashed', + done: 'circle-check', + downangle: 'angle-down', + draft: 'scribble', + edit: 'pencil', + enabled: 'circle', + expand: 'up-right-and-down-left-from-center', + external: 'arrow-up-right-from-square', + field: 'pen-to-square', + help: 'circle-question', + home: 'house', + info: 'circle-info', + insecure: 'unlock', + larr: 'arrow-left', + layout: 'table-layout', + leftangle: 'angle-left', + listrtl: 'list-flip', + location: 'location-dot', + mail: 'envelope', + menu: 'bars', + move: 'grip-dots', + newstamp: 'certificate', + paperplane: 'paper-plane', + plugin: 'plug', + rarr: 'arrow-right', + refresh: 'arrows-rotate', + remove: 'xmark', + rightangle: 'angle-right', + rotate: 'rotate-left', + routes: 'signs-post', + search: 'magnifying-glass', + secure: 'lock', + settings: 'gear', + shareleft: 'share-flip', + shuteye: 'eye-slash', + 'sidebar-left': 'sidebar', + 'sidebar-right': 'sidebar-flip', + 'sidebar-start': 'sidebar', // Note: Was conditional based on $orientation (ltr: 'sidebar', rtl: 'sidebar-flip') + 'sidebar-end': 'sidebar-flip', // Note: Was conditional based on $orientation (ltr: 'sidebar-flip', rtl: 'sidebar') + structure: 'list-tree', + structurertl: 'list-tree-flip', + template: 'file-code', + time: 'clock', + tool: 'wrench', + uarr: 'arrow-up', + upangle: 'angle-up', + view: 'eye', + wand: 'wand-magic-sparkles', +}; + +/** + * This is mostly copied from font awesome directly because they don't seem to + * give you a way to access the default library settings and extend them, only + * overwrite them entirely. + * + * https://github.com/shoelace-style/webawesome/blob/da206a87873e3ab43ded7466a05005225aa50e69/packages/webawesome/src/components/icon/library.default.ts + */ +export function getIconUrl( + name: string, + family: string = 'classic', + variant: string = 'regular' +) { + let folder = 'solid'; + let resolvedVariant = variant; + let resolvedName = name.endsWith('.svg') ? name.split('.svg')[0]! : name; + + if (name.includes('/')) { + const [tmpVariant, ...tmpName] = name.split('/'); + + resolvedVariant = tmpVariant ?? resolvedVariant; + resolvedName = tmpName.join('/'); + } + + if (resolvedVariant === 'thin') { + folder = 'thin'; + } else if (resolvedVariant === 'light') { + folder = 'light'; + } else if (resolvedVariant === 'regular') { + folder = 'regular'; + } else if (resolvedVariant === 'solid') { + folder = 'solid'; + } + + // Brands + if (family === 'brands') { + folder = 'brands'; + } + + if (family === 'custom-icons' || resolvedVariant === 'custom-icons') { + folder = 'custom-icons'; + } + + resolvedName = LEGACY_NAMES[resolvedName] ?? resolvedName; + + // Use the default CDN + return `/vendor/craft/icons/${folder}/${resolvedName}.svg`; +} + +export function configureIcons() { + registerIconLibrary('default', { + resolver: (name: string, family = 'classic', variant = 'solid') => { + return getIconUrl(name, family, variant); + }, + mutator: (svg) => svg.setAttribute('fill', 'currentColor'), + }); +} diff --git a/packages/craftcms-ui/src/utilities/string.test.ts b/packages/craftcms-cp/src/utilities/string.test.ts similarity index 97% rename from packages/craftcms-ui/src/utilities/string.test.ts rename to packages/craftcms-cp/src/utilities/string.test.ts index d9c20bfbb3b..37036d30359 100644 --- a/packages/craftcms-ui/src/utilities/string.test.ts +++ b/packages/craftcms-cp/src/utilities/string.test.ts @@ -1,4 +1,4 @@ -import {describe, expect, test} from 'vite-plus/test'; +import {describe, expect, test} from 'vitest'; import {toEnvVar, toHandle, toUriFormat} from './string'; describe('toHandle', () => { diff --git a/packages/craftcms-ui/src/utilities/string.ts b/packages/craftcms-cp/src/utilities/string.ts similarity index 99% rename from packages/craftcms-ui/src/utilities/string.ts rename to packages/craftcms-cp/src/utilities/string.ts index 98fb4d2d845..8cd7f427f85 100644 --- a/packages/craftcms-ui/src/utilities/string.ts +++ b/packages/craftcms-cp/src/utilities/string.ts @@ -1613,7 +1613,3 @@ export function toUriFormat(value: string): string { export function capitalize(str: string): string { return str.charAt(0).toUpperCase() + str.slice(1); } - -export function rand() { - return Math.floor(Math.random() * 1000000); -} diff --git a/packages/craftcms-ui/src/utilities/translate.test.ts b/packages/craftcms-cp/src/utilities/translate.test.ts similarity index 99% rename from packages/craftcms-ui/src/utilities/translate.test.ts rename to packages/craftcms-cp/src/utilities/translate.test.ts index 0199434a662..15556fbf64e 100644 --- a/packages/craftcms-ui/src/utilities/translate.test.ts +++ b/packages/craftcms-cp/src/utilities/translate.test.ts @@ -1,4 +1,4 @@ -import {describe, test, expect} from 'vite-plus/test'; +import {describe, test, expect} from 'vitest'; import {t, tokenizePattern, parseToken, formatMessage} from './translate.js'; const translations = { diff --git a/packages/craftcms-ui/src/utilities/translate.ts b/packages/craftcms-cp/src/utilities/translate.ts similarity index 100% rename from packages/craftcms-ui/src/utilities/translate.ts rename to packages/craftcms-cp/src/utilities/translate.ts diff --git a/packages/craftcms-ui/tailwind.css b/packages/craftcms-cp/tailwind.css similarity index 87% rename from packages/craftcms-ui/tailwind.css rename to packages/craftcms-cp/tailwind.css index 725f6bae61e..fd95de39987 100644 --- a/packages/craftcms-ui/tailwind.css +++ b/packages/craftcms-cp/tailwind.css @@ -6,8 +6,8 @@ * * Usage in your CSS entry file: * - * @import "@craftcms/ui/dist/styles/cp.css"; // loads :root token values - * @import "@craftcms/ui/tailwind.css"; // @theme inline — generate utilities + * @import "@craftcms/cp/dist/styles/cp.css"; // loads :root token values + * @import "@craftcms/cp/tailwind.css"; // @theme inline — generate utilities * @import "tailwindcss"; // Tailwind v4 engine * * The --c-* variables must already be in scope (via cp.css) for var() to @@ -26,7 +26,7 @@ /* ——— Text ——— */ --color-text-default: var(--c-text-default); - --color-text-quiet: var(--c-text-quiet); + --color-text-muted: var(--c-text-quiet); --color-text-link: var(--c-text-link); --color-text-white: var(--c-text-white); @@ -110,20 +110,4 @@ --color-border-default: var(--c-color-neutral-border-normal); --color-border-strong: var(--c-color-neutral-border-loud); --color-border-form: var(--c-form-control-border-color); - - /* ——— Fill utilities ——— */ - --color-fill-quiet: var( - --c-color-fill-quiet, - var(--c-color-neutral-fill-quiet) - ); - --color-fill-normal: var( - --c-color-fill-normal, - var(--c-color-neutral-fill-normal) - ); - --color-fill-loud: var(--c-color-fill-loud, var(--c-color-neutral-fill-loud)); - - /* ——— Text utilities ——— */ - --color-on-quiet: var(--c-color-on-quiet, var(--c-color-neutral-on-quiet)); - --color-on-normal: var(--c-color-on-normal, var(--c-color-neutral-on-normal)); - --color-on-loud: var(--c-color-on-loud, var(--c-color-neutral-on-loud)); } diff --git a/packages/craftcms-cp/tsconfig.json b/packages/craftcms-cp/tsconfig.json new file mode 100644 index 00000000000..2381ef040c1 --- /dev/null +++ b/packages/craftcms-cp/tsconfig.json @@ -0,0 +1,14 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "experimentalDecorators": true, + "strictPropertyInitialization": false, + "outDir": "./dist", + "rootDir": ".", + "types": ["vite/client", "jquery"], + "paths": { + "@src/*": ["./src/*"] + } + }, + "include": ["src"] +} diff --git a/packages/craftcms-cp/vitest.config.ts b/packages/craftcms-cp/vitest.config.ts new file mode 100644 index 00000000000..4b413cdd686 --- /dev/null +++ b/packages/craftcms-cp/vitest.config.ts @@ -0,0 +1,55 @@ +import path from 'node:path'; +import {fileURLToPath} from 'node:url'; +import {playwright} from '@vitest/browser-playwright'; + +import {defineConfig} from 'vitest/config'; + +import {storybookTest} from '@storybook/addon-vitest/vitest-plugin'; + +const dirname = + typeof __dirname !== 'undefined' + ? __dirname + : path.dirname(fileURLToPath(import.meta.url)); + +// More info at: https://storybook.js.org/docs/next/writing-tests/integrations/vitest-addon +export default defineConfig({ + test: { + projects: [ + { + test: { + name: 'utilities', + root: './src/utilities', + environment: 'happy-dom', + }, + }, + { + resolve: { + tsconfigPaths: true, + }, + test: { + name: 'services', + root: './src/services', + environment: 'happy-dom', + }, + }, + { + extends: true, + plugins: [ + // The plugin will run tests for the stories defined in your Storybook config + // See options at: https://storybook.js.org/docs/next/writing-tests/integrations/vitest-addon#storybooktest + storybookTest({configDir: path.join(dirname, '.storybook')}), + ], + test: { + name: 'storybook', + browser: { + enabled: true, + headless: true, + provider: playwright(), + instances: [{browser: 'chromium'}], + }, + setupFiles: ['.storybook/vitest.setup.ts'], + }, + }, + ], + }, +}); diff --git a/packages/craftcms-cp/vitest.shims.d.ts b/packages/craftcms-cp/vitest.shims.d.ts new file mode 100644 index 00000000000..a1d31e5a7b8 --- /dev/null +++ b/packages/craftcms-cp/vitest.shims.d.ts @@ -0,0 +1 @@ +/// diff --git a/packages/craftcms-garnish/.gitignore b/packages/craftcms-garnish/.gitignore deleted file mode 100644 index 5a2cce0d039..00000000000 --- a/packages/craftcms-garnish/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -/dist -/node_modules -/coverage -/storybook-static diff --git a/packages/craftcms-garnish/.storybook/main.ts b/packages/craftcms-garnish/.storybook/main.ts deleted file mode 100644 index 151f9aee0c9..00000000000 --- a/packages/craftcms-garnish/.storybook/main.ts +++ /dev/null @@ -1,34 +0,0 @@ -import type {StorybookConfig} from '@storybook/html-vite'; - -import {dirname} from 'path'; -import {fileURLToPath} from 'url'; - -/** - * Resolve the absolute path of a package. Needed in monorepos so Storybook finds - * the hoisted addons/framework regardless of where node_modules ends up. - */ -function getAbsolutePath(value: string): string { - return dirname(fileURLToPath(import.meta.resolve(`${value}/package.json`))); -} - -/** - * Storybook config for @craftcms/garnish. - * - * Garnish widgets are imperative (`new Modal(container)`, `new DisclosureMenu(trigger)`) - * operating on plain DOM — NOT web components — so we use the `html-vite` renderer - * (cp uses `web-components-vite`). Each story's `render()` returns an `HTMLElement` - * in which the Garnish class is instantiated against the REAL source under `../src`. - */ -const config: StorybookConfig = { - stories: ['../stories/**/*.stories.@(ts|mdx)'], - addons: [ - getAbsolutePath('@storybook/addon-docs'), - getAbsolutePath('@storybook/addon-a11y'), - getAbsolutePath('@storybook/addon-themes'), - ], - framework: { - name: getAbsolutePath('@storybook/html-vite'), - options: {}, - }, -}; -export default config; diff --git a/packages/craftcms-garnish/.storybook/preview.css b/packages/craftcms-garnish/.storybook/preview.css deleted file mode 100644 index bf0e582561e..00000000000 --- a/packages/craftcms-garnish/.storybook/preview.css +++ /dev/null @@ -1,673 +0,0 @@ -/** - * Global demo styles for @craftcms/garnish stories. - * - * Migrated from the old `playground/styles.css`. Stories reuse the same `.pg-*` - * class names so the imperative widgets (which the package itself renders into - * `.modal-shade`, `.hud .tip`, `.menu--disclosure`, etc.) look identical to the - * playground. The only structural change from the playground: the event-log - * panel is mounted INSIDE each story (`.pg-story` flex layout) instead of being - * a single page-fixed panel, so it scopes to the story canvas. - */ - -:root { - --bg: #f4f5f7; - --surface: #ffffff; - --border: #d6d9de; - --text: #1c1f24; - --muted: #5c636e; - --accent: #1f6feb; - --accent-text: #ffffff; - --good: #1a7f37; - --bad: #b42318; - --radius: 6px; - --shadow: 0 6px 24px rgba(0, 0, 0, 0.18); -} - -/* --- Story layout ------------------------------------------------------- */ -/* Events surface in Storybook's Actions panel, so the canvas is just the demo. */ -.pg-story { - font-family: - system-ui, - -apple-system, - 'Segoe UI', - Roboto, - sans-serif; - color: var(--text); - line-height: 1.5; - max-width: 60ch; -} - -.pg-story > p { - margin: 0 0 1rem; - color: var(--muted); -} - -.pg-controls { - display: flex; - flex-wrap: wrap; - gap: 0.5rem; -} - -.pg-story button { - font: inherit; - cursor: pointer; - padding: 0.45rem 0.9rem; - border: 1px solid var(--border); - border-radius: var(--radius); - background: var(--surface); - color: var(--text); - transition: background 0.12s ease; -} - -.pg-story button:hover { - background: #eef0f3; -} - -.pg-story button:focus-visible { - outline: 2px solid var(--accent); - outline-offset: 2px; -} - -.pg-story code, -.pg-story kbd { - font-family: ui-monospace, 'SFMono-Regular', Menlo, monospace; - font-size: 0.85em; -} - -.pg-story code { - background: #eef0f3; - padding: 0.05rem 0.3rem; - border-radius: 4px; -} - -.pg-story kbd { - background: #2a2f37; - color: #fff; - padding: 0.05rem 0.35rem; - border-radius: 4px; -} - -/* --- Focusable sample --------------------------------------------------- */ -.pg-focus-sample { - margin-top: 1rem; - display: flex; - flex-wrap: wrap; - gap: 0.5rem; - padding: 1rem; - border: 1px dashed var(--border); - border-radius: var(--radius); -} - -.pg-focus-sample > * { - padding: 0.35rem 0.6rem; - border: 1px solid var(--border); - border-radius: 4px; - background: #fafbfc; - margin: 0; -} - -.pg-focus-sample a { - color: var(--accent); -} - -.pg-highlight-focusable { - outline: 2px solid var(--good) !important; - outline-offset: 1px; - background: #e7f6ec !important; -} - -.pg-highlight-keyboard { - box-shadow: 0 0 0 2px var(--accent); -} - -/* --- Modal + shade (the part the package itself renders) ---------------- */ -.modal-shade { - position: fixed; - inset: 0; - background: rgba(15, 18, 22, 0.55); - z-index: 100; - display: none; - opacity: 0; -} - -.pg-modal { - position: fixed; - z-index: 101; - display: none; - opacity: 0; - background: var(--surface); - color: var(--text); - border-radius: var(--radius); - box-shadow: var(--shadow); - padding: 1.5rem; - min-width: 320px; - max-width: 90vw; - overflow: auto; -} - -.pg-modal h3 { - margin-top: 0; -} - -.pg-modal .pg-modal-actions { - display: flex; - gap: 0.5rem; - margin-top: 1rem; - flex-wrap: wrap; -} - -.pg-modal button { - font: inherit; - cursor: pointer; - padding: 0.45rem 0.9rem; - border: 1px solid var(--border); - border-radius: var(--radius); - background: var(--surface); - color: var(--text); -} - -.pg-modal-primary { - background: var(--accent) !important; - color: var(--accent-text) !important; - border-color: var(--accent) !important; -} - -.pg-modal-primary:hover { - background: #1a5fce !important; -} - -body.no-scroll { - overflow: hidden; -} - -/* Draggable modal: give it a draggable look + a grabbable header. */ -.pg-modal.pg-modal--draggable { - cursor: grab; - /* Handles must opt out of browser touch gestures so pointer drags work on - touch devices (doc 08 §4). */ - touch-action: none; -} - -.pg-modal-drag-handle { - margin: -1.5rem -1.5rem 1rem; - padding: 0.75rem 1.5rem; - background: #11151b; - color: #e6e9ee; - border-radius: var(--radius) var(--radius) 0 0; - cursor: grab; - touch-action: none; - user-select: none; -} - -/* The resize handle Modal injects (.resizehandle) — give it a visible target. */ -.pg-modal .resizehandle { - position: absolute; - right: 0; - bottom: 0; - width: 20px; - height: 20px; - cursor: nwse-resize; - touch-action: none; - color: var(--muted); - display: flex; - align-items: flex-end; - justify-content: flex-end; - padding: 2px; -} - -.pg-modal .resizehandle svg { - width: 14px; - height: 14px; -} - -/* --- Standalone drag arena --------------------------------------------- */ -.pg-drag-arena { - position: relative; - margin-top: 1rem; - height: 280px; - border: 1px dashed var(--border); - border-radius: var(--radius); - background: repeating-linear-gradient( - 45deg, - #fafbfc, - #fafbfc 10px, - #f2f4f7 10px, - #f2f4f7 20px - ); - overflow: hidden; -} - -.pg-drag-box { - position: absolute; - width: 130px; - min-height: 56px; - padding: 0.5rem; - border-radius: var(--radius); - font-size: 0.8rem; - font-weight: 600; - color: #fff; - display: flex; - align-items: center; - justify-content: center; - text-align: center; - box-shadow: var(--shadow); - cursor: grab; - user-select: none; - /* Required so pointer drags aren't eaten by touch scrolling/panning. */ - touch-action: none; -} - -.pg-drag-box:active { - cursor: grabbing; -} - -.pg-drag-box--move { - background: var(--good); -} - -.pg-drag-box--xlock { - background: #0a6d2f; -} - -.pg-drag-box--base { - background: var(--accent); -} - -.pg-drag-box--scroll { - background: #b85c00; -} - -/* --- Auto-scroll container ---------------------------------------------- */ -.pg-scroll-container { - position: relative; - margin-top: 1rem; - height: 260px; - overflow: auto; - border: 1px solid var(--border); - border-radius: var(--radius); - background: #fafbfc; -} - -.pg-scroll-tall { - position: relative; - height: 1100px; - padding: 1rem; -} - -.pg-scroll-filler { - margin: 0; - padding: 8rem 0; - text-align: center; - color: var(--muted); -} - -.pg-scroll-container .pg-drag-box--scroll { - position: absolute; - top: 20px; - left: 20px; -} - -/* --- Drag with helpers -------------------------------------------------- */ -.pg-helper-list { - margin-top: 1rem; - display: flex; - flex-direction: column; - gap: 0.5rem; -} - -.pg-helper-item { - display: flex; - align-items: center; - gap: 0.6rem; - padding: 0.65rem 0.9rem; - border: 1px solid var(--border); - border-radius: var(--radius); - background: #fafbfc; - font-weight: 600; - font-size: 0.85rem; - cursor: grab; - user-select: none; - /* Required so pointer drags aren't eaten by touch scrolling/panning. */ - touch-action: none; -} - -.pg-helper-item:active { - cursor: grabbing; -} - -.pg-helper-grip { - color: var(--muted); - font-size: 1.1rem; - line-height: 1; - letter-spacing: -0.15em; -} - -/* The clone Drag creates gets the .draghelper class; give it a lifted look. */ -.draghelper { - box-shadow: var(--shadow); - opacity: 0.92; - border-color: var(--accent) !important; - cursor: grabbing; -} - -/* --- DragDrop / drop targets -------------------------------------------- */ -.pg-dragdrop-layout { - margin-top: 1rem; - display: grid; - grid-template-columns: 1fr 1fr; - gap: 1rem; - align-items: start; -} - -.pg-dragdrop-chips { - display: flex; - flex-direction: column; - gap: 0.5rem; - padding: 0.75rem; - border: 1px dashed var(--border); - border-radius: var(--radius); - background: #fafbfc; -} - -.pg-dragdrop-chip { - padding: 0.5rem 0.75rem; - border-radius: var(--radius); - background: var(--accent); - color: var(--accent-text); - font-weight: 600; - font-size: 0.85rem; - text-align: center; - cursor: grab; - user-select: none; - /* Required so pointer drags aren't eaten by touch scrolling/panning. */ - touch-action: none; -} - -.pg-dragdrop-chip:active { - cursor: grabbing; -} - -.pg-dragdrop-zones { - display: flex; - flex-direction: column; - gap: 0.5rem; -} - -.pg-dropzone { - padding: 1.1rem 0.75rem; - border: 2px dashed var(--border); - border-radius: var(--radius); - text-align: center; - font-weight: 600; - font-size: 0.85rem; - color: var(--muted); - background: var(--surface); - transition: - background 0.12s ease, - border-color 0.12s ease, - color 0.12s ease; -} - -/* DragDrop toggles `activeDropTargetClass` (default: 'active') on hover. */ -.pg-dropzone.active { - border-color: var(--good); - border-style: solid; - background: #e7f6ec; - color: var(--good); -} - -/* Briefly flashed by the demo when a drop lands on a zone. */ -.pg-dropzone.pg-dropzone--hit { - border-color: var(--accent); - background: #e6f0ff; - color: var(--accent); -} - -/* --- DragSort / reorderable list ---------------------------------------- */ -.pg-sort-list { - margin-top: 1rem; - padding: 0; - list-style: none; - display: flex; - flex-direction: column; - gap: 0.5rem; -} - -.pg-sort-item { - display: flex; - align-items: center; - gap: 0.6rem; - padding: 0.65rem 0.9rem; - border: 1px solid var(--border); - border-radius: var(--radius); - background: #fafbfc; - font-weight: 600; - font-size: 0.85rem; - cursor: grab; - user-select: none; - /* Required so pointer drags aren't eaten by touch scrolling/panning. */ - touch-action: none; -} - -.pg-sort-item:active { - cursor: grabbing; -} - -.pg-sort-grip { - color: var(--muted); - font-size: 1.1rem; - line-height: 1; - letter-spacing: -0.15em; -} - -/* The placeholder DragSort inserts at the landing spot. */ -.pg-sort-insertion { - list-style: none; - height: 2.5rem; - border: 2px dashed var(--accent); - border-radius: var(--radius); - background: #e6f0ff; -} - -/* --- HUD / anchored popover -------------------------------------------- */ -.pg-hud-arena { - position: relative; - margin-top: 1rem; - height: 360px; - border: 1px dashed var(--border); - border-radius: var(--radius); - background: repeating-linear-gradient( - -45deg, - #fafbfc, - #fafbfc 10px, - #f2f4f7 10px, - #f2f4f7 20px - ); -} - -.pg-hud-trigger { - position: absolute; -} - -/* The HUD container — the HUD JS sets display/position/left/top inline. */ -.hud { - z-index: 102; - background: var(--surface); - border: 1px solid var(--border); - border-radius: var(--radius); - box-shadow: var(--shadow); -} - -.hud .body { - margin: 0; -} - -.hud .main-container { - overflow: hidden; -} - -.hud .main { - padding: 0.9rem 1.1rem; - min-width: 200px; - max-width: 260px; -} - -/* The tip/arrow. The JS positions it along the relevant edge (the perpendicular - offset), and the orientation class (tip-top/-bottom/-left/-right) pins it to - the correct edge. */ -.hud .tip { - position: absolute; - width: 30px; - height: 30px; - pointer-events: none; -} - -.hud .tip::after { - content: ''; - position: absolute; - left: 8px; - top: 8px; - width: 14px; - height: 14px; - background: var(--surface); - border: 1px solid var(--border); - transform: rotate(45deg); -} - -.hud .tip-top { - top: -15px; -} - -.hud .tip-bottom { - bottom: -15px; -} - -.hud .tip-left { - left: -15px; -} - -.hud .tip-right { - right: -15px; -} - -.pg-hud-content h4 { - margin: 0 0 0.4rem; - font-size: 0.95rem; -} - -.pg-hud-content p { - margin: 0 0 0.75rem; - color: var(--muted); - font-size: 0.85rem; -} - -.hud-shade { - position: fixed; - inset: 0; - z-index: 100; - background: rgba(15, 18, 22, 0.25); - display: none; -} - -/* --- DisclosureMenu / dropdown menu ------------------------------------ */ -.pg-disc-trigger { - font-weight: 600; -} - -/* The menu panel — the JS sets display/top/left/right/opacity inline. */ -.menu.menu--disclosure { - position: absolute; - display: none; - z-index: 102; - min-width: 180px; - padding: 4px; - background: var(--surface); - color: var(--text); - border: 1px solid var(--border); - border-radius: var(--radius); - box-shadow: var(--shadow); - opacity: 0; -} - -.menu.menu--disclosure.visible { - display: block; -} - -.menu--disclosure ul { - list-style: none; - margin: 0; - padding: 0; -} - -.menu--disclosure h3 { - margin: 0.4rem 0 0.2rem; - padding: 0 0.6rem; - font-size: 0.72rem; - text-transform: uppercase; - letter-spacing: 0.04em; - color: var(--muted); -} - -.menu--disclosure hr { - margin: 0.35rem 0; - border: none; - border-top: 1px solid var(--border); -} - -.menu--disclosure .menu-item { - display: block; - width: 100%; - text-align: left; - padding: 0.4rem 0.6rem; - border: 0; - border-radius: 5px; - background: transparent; - color: inherit; - font: inherit; - cursor: pointer; -} - -.menu--disclosure .menu-item:hover, -.menu--disclosure .menu-item:focus { - background: var(--accent-soft, #eef2ff); - outline: none; -} - -.menu--disclosure .menu-item.sel { - font-weight: 600; -} - -.menu--disclosure .menu-item.error { - color: #c0392b; -} - -.menu--disclosure .menu-item.disabled { - opacity: 0.45; - cursor: default; -} - -.menu--disclosure .search-container { - padding: 0.25rem 0.25rem 0.5rem; -} - -.menu--disclosure .search-container input { - width: 100%; - box-sizing: border-box; - padding: 0.35rem 0.5rem; - border: 1px solid var(--border); - border-radius: 5px; - font: inherit; -} - -.menu--disclosure .clear-btn { - display: none; -} - -/* Hidden / filtered items + their empty groups/separators collapse. */ -.menu--disclosure li.hidden, -.menu--disclosure li.filtered, -.menu--disclosure ul.hidden, -.menu--disclosure hr.hidden, -.menu--disclosure h3.hidden { - display: none; -} diff --git a/packages/craftcms-garnish/.storybook/preview.ts b/packages/craftcms-garnish/.storybook/preview.ts deleted file mode 100644 index e7ec2d44b9d..00000000000 --- a/packages/craftcms-garnish/.storybook/preview.ts +++ /dev/null @@ -1,45 +0,0 @@ -import type {HtmlRenderer, Preview} from '@storybook/html-vite'; -import {withThemeByDataAttribute} from '@storybook/addon-themes'; -import './preview.css'; - -/** - * Global Storybook config for @craftcms/garnish. - * - * The global demo styles (modal/shade, drag arena/boxes, HUD tip, menu panel, - * the event-log panel) are migrated from the old `playground/styles.css` into - * `preview.css`, imported here so every story shares them. - */ -const preview: Preview = { - parameters: { - controls: { - expanded: true, - matchers: { - color: /(background|color)$/i, - date: /Date$/i, - }, - }, - options: { - storySort: { - method: 'alphabetical', - }, - }, - a11y: { - // 'todo' surfaces a11y violations in the UI without failing the build — - // these are imperative widget demos, not production-accessible markup. - test: 'todo', - }, - }, - decorators: [ - withThemeByDataAttribute({ - themes: { - light: 'light', - dark: 'dark', - }, - defaultTheme: 'light', - attributeName: 'data-theme', - }), - ], - tags: ['autodocs'], -}; - -export default preview; diff --git a/packages/craftcms-garnish/README.md b/packages/craftcms-garnish/README.md deleted file mode 100644 index a3eade88f18..00000000000 --- a/packages/craftcms-garnish/README.md +++ /dev/null @@ -1,384 +0,0 @@ -# @craftcms/garnish - -Modern, tree-shakeable TypeScript rewrite of Craft CMS's Garnish UI library. - -It ships **two surfaces from one package**: - -- A **modern**, jQuery-free, ESM-only API of native `class`es, native events, and - tree-shakeable utilities — the preferred surface for new code. -- An opt-in **compat** layer (`@craftcms/garnish/compat`) that restores the legacy - `Garnish.Base.extend()` / `this.base()` / jQuery authoring contract on top of the - same modern core, so existing Craft plugins can adopt it with (near) zero changes - and migrate incrementally. - -## Features - -- jQuery-free modern core (the `.` entry never imports or touches jQuery) -- Native ES classes with a real `extends` / `super` model -- Object pub/sub + namespaced DOM listeners that preserve the legacy event grammar -- Accessible, animated `Modal` (focus trapping, ARIA backgrounding, Web Animations - API fades that respect `prefers-reduced-motion`) -- A broad utility surface (DOM, focus, ARIA, forms, animation, environment helpers) -- Full TypeScript types -- An opt-in compat layer that wraps every class so `.extend()` / `init` / - `this.base()` / jQuery args keep working, and installs a legacy-shaped - `window.Garnish` - -## Installation - -```bash -npm install @craftcms/garnish -``` - -jQuery is an **optional peer dependency** — required only by the `compat` entry, and -only at runtime. The modern `.` entry never needs it. - -## Usage - -### Mode A — Modern (recommended for new code) - -Import named exports. ES classes, native events, no jQuery. Anything you don't -import is tree-shaken away. - -```ts -import {Modal} from '@craftcms/garnish'; - -const el = document.querySelector('#my-modal')!; -const modal = new Modal(el, { - closeOtherModals: true, - hideOnEsc: true, - onShow: () => console.log('shown'), -}); - -// Subscribe to events with the native emitter: -modal.on('hide', () => console.log('hidden')); -modal.on('fadeOut.myPlugin', () => cleanup()); -modal.off('.myPlugin'); // remove everything in that namespace - -// Later: -modal.hide(); -modal.destroy(); -``` - -Subclass with plain `class extends` and `super`: - -```ts -import {Modal, type ModalSettings} from '@craftcms/garnish'; - -class ConfirmModal extends Modal { - constructor(container: Element, settings?: Partial) { - super(container, settings); - // ...your setup... - } - - override onShow(): void { - super.onShow(); // preserves the `show` event + onShow callback - // ...custom behavior... - } -} -``` - -Utilities are individual named exports — import only what you use: - -```ts -import {trapFocusWithin, releaseFocusWithin, getPostData} from '@craftcms/garnish'; -``` - -#### Dragging — `BaseDrag` / `DragMove` - -`BaseDrag` is the jQuery-free drag foundation (Pointer Events, native auto-scroll). -`DragMove` is a thin subclass that positions the dragged element under the cursor. -Drag handles need `touch-action: none` so the browser doesn't eat the gesture on -touch devices. - -```ts -import {DragMove} from '@craftcms/garnish'; - -const box = document.querySelector('#draggable')!; -box.style.touchAction = 'none'; // required for touch/pen - -const dragger = new DragMove(box, { - // axis: 'x', // optionally lock to one axis - // handle: '.drag-handle', // drag only by a child selector - onDragStart: () => console.log('start'), - onDrag: () => console.log('moving'), - onDragStop: () => console.log('stop'), -}); - -dragger.on('drag', () => {/* same events are also emitted */}); -// later: dragger.destroy(); -``` - -For full control, use `BaseDrag` directly and position the element yourself in -`onDrag` (read `mouseX/mouseY`/`mouseOffsetX/mouseOffsetY` off the dragger). - -#### Helpers & drop targets — `Drag` / `DragDrop` - -`Drag` picks up the selected element(s): on drag start it builds floating -*helper* clones that trail the cursor with lag, and on drop you choose what -happens — animate them back to their source (`returnHelpersToDraggees()`, a Web -Animations API tween that respects `prefers-reduced-motion`) or fade them out -(`fadeOutHelpers()`). `DragDrop` adds drop targets on top: while dragging, the -target under the cursor is highlighted (its `activeDropTargetClass` is toggled) -and `onDropTargetChange` fires; there is no separate `drop` event — read -`$activeDropTarget` inside your own `dragStop` handler to perform the drop. - -```ts -import {DragDrop} from '@craftcms/garnish'; - -const dd = new DragDrop({ - dropTargets: '.dropzone', // selector, element(s), or a () => elements fn - onDropTargetChange: (active) => console.log('over:', active), - onDragStop() { - if (dd.$activeDropTarget) { - // a raw HTMLElement | null — NOT a jQuery object (drop the `[0]`) - console.log('dropped on', dd.$activeDropTarget); - } - dd.returnHelpersToDraggees(); // send the helper clone home - }, -}); -dd.addItems(document.querySelectorAll('.chip')); // items added after construction -``` - -As with `BaseDrag`, draggable items and handles need `touch-action: none`. - -#### Sortable lists — `DragSort` - -`DragSort` is the sortable-list dragger built on `Drag`: drag an item to reorder it -within its container, with **live insertion feedback** — as the cursor moves, the -dragged item (and an optional `insertion` placeholder) is re-inserted into the DOM at -the spot it will land, so the surrounding items reflow in real time. On drop the new -order is committed and `sortChange` fires if anything moved. `insertionPointChange` -fires whenever the landing spot moves. - -```ts -import {DragSort} from '@craftcms/garnish'; - -const list = document.querySelector('#sortable')!; -const sort = new DragSort(list.querySelectorAll('li'), { - container: list, // the sort is constrained to this (heighted) container - axis: 'y', // single-column list - insertion: () => { - const ph = document.createElement('li'); - ph.className = 'insertion'; - return ph; // a placeholder shown at the landing spot - }, - onInsertionPointChange: () => console.log('insertion moved'), - onSortChange: () => console.log('new order committed'), - // gate where items may land: - // canInsertBefore: (item) => !item.classList.contains('locked'), -}); -sort.on('sortChange', () => persistOrder()); -``` - -`magnetStrength > 1` rubber-bands the helper toward the dragged item's home; -`moveTargetItemToFront` keeps a multi-select drag's target leading the block. As with -`BaseDrag`, the sortable items / handles need `touch-action: none`. - -#### Anchored popovers — `HUD` - -`HUD` is the anchored popover/bubble. It attaches to a trigger element, picks one of -four orientations (`bottom` / `top` / `right` / `left`) from the available clearance -around the trigger, draws a tip pointing back at it, follows the trigger on -scroll/resize, traps `Tab` focus between the trigger and the body, and registers a -UI layer + Escape shortcut (the same `UiLayerManager` `Modal` uses). Append your -content into `hud.$main` — a raw `HTMLElement`, not a jQuery object. - -```ts -import {HUD} from '@craftcms/garnish'; - -const addBtn = document.querySelector('#add-btn')!; -const hud = new HUD(addBtn, { - hudClass: 'hud fld-library-hud', - orientations: ['right', 'bottom', 'left'], - showOnInit: false, -}); - -hud.on('show', () => hud.$main!.append(library)); // $main is an HTMLElement -hud.on('hide', () => addBtn.focus()); -addBtn.addEventListener('click', () => hud.show()); -// hud.toggle(); hud.updateSizeAndPosition(); hud.destroy(); -``` - -The constructor mirrors the legacy shape — `new HUD(trigger, bodyContents?, settings?)`, -with a `new HUD(trigger, settings)` param shift — so a legacy -`new Garnish.HUD($addBtn, {...})` call ports across unchanged. - -#### Dropdown menus — `DisclosureMenu` - -`DisclosureMenu` is the disclosure dropdown/menu: a trigger button (carrying -`aria-controls` / `aria-expanded`) paired with a menu panel referenced by that id. -It anchors the panel below the trigger (flipping above when there's no room), -aligns it left/center/right, manages full keyboard navigation + type-ahead search -and focus, registers a UI layer + Escape shortcut, dismisses on an outside click, -and exposes item/group builders (`addItem` / `addGroup` / `addHr`) consumers use to -populate it. An optional `withSearchInput` filters items live. - -```ts -import {DisclosureMenu} from '@craftcms/garnish'; - -// -// -const menu = new DisclosureMenu(document.querySelector('button')!); - -menu.addItem({label: 'Rename', onActivate: (el) => rename(el)}); -const group = menu.addGroup('Danger zone'); -menu.addItem({label: 'Delete', destructive: true, onActivate: () => remove()}, group); - -menu.on('show', () => console.log('opened')); -// menu.show(); menu.hide(); menu.isExpanded(); menu.destroy(); -``` - -Selection is per-item: each item's `onActivate` / `callback` runs on activation, -then the menu hides. `DisclosureMenu.getInstance(triggerOrContainer)` is the native -replacement for the legacy `$el.data('disclosureMenu')`. A legacy -`new Garnish.DisclosureMenu($trigger, settings)` call ports across unchanged. - -#### Item selection — `Select` - -`Select` is the selection interface over a set of sibling items: click to select, -shift-click to extend a contiguous range, and ctrl/⌘-click to toggle individual -items (the ctrl/shift roles swap under `checkboxMode`). Selected items get the -`selectedClass` (`sel` by default); arrow keys move the selection two-dimensionally -by measuring item geometry, so it works for vertical lists and wrapping grids alike. -It pairs naturally with `DragSort` for drag-a-multi-selection lists (see -``). - -```ts -import {Select} from '@craftcms/garnish'; - -const select = new Select({multi: true, filter: (t) => !(t as Element)?.closest('button')}); -select.addItems(list.querySelectorAll('li')); -select.on('selectionChange', () => console.log(select.getSelectedItems())); -``` - -The constructor mirrors the legacy shape — `new Select(container, items?, settings?)`, -with `new Select(settings)` / `new Select(container, settings)` param shifts — so a -legacy `new Garnish.Select({...})` call ports across unchanged. `getSelectedItems()` -returns a native `HTMLElement[]` (not a jQuery collection). - -**No-jQuery guarantee:** importing from `@craftcms/garnish` (the `.` entry) never -pulls in jQuery, never reads `window.jQuery`/`$`, and never assigns -`window.Garnish`. Those behaviors live exclusively in the `compat` entry. - -### Mode B — Compat / upgrade path (for existing plugins) - -The compat entry restores the legacy authoring contract: a `window.Garnish` global, -`.extend()`-able classes, `init()` as the constructor, `this.base()` super-dispatch, -and jQuery-collection constructor arguments. - -#### How to ADD the compat layer - -Add a single side-effecting import at your bundle entry point: - -```ts -import '@craftcms/garnish/compat'; - -// `window.Garnish` is now populated. Existing code keeps working unchanged: -Craft.MyModal = Garnish.Modal.extend({ - init(container) { - this.base(container, {closeOtherModals: true}); // calls Modal's constructor - }, - onShow() { - this.base(); // calls Modal.prototype.onShow - // ...custom behavior... - }, -}); - -new Craft.MyModal($('#my-modal')); // jQuery collection args are unwrapped for you -``` - -That import installs `window.Garnish` (guarded by -`if (typeof window.Garnish === 'undefined')`, so it never clobbers an existing -legacy-bundle global). jQuery must be present on the global scope for the -jQuery-shaped parts (`$container` args, `$win`/`$doc`/`$bod`, `isJquery`, -`$.fn.activate/textchange/resize` sugar); the layer throws a clear, actionable -error if a jQuery-only feature is used while jQuery is absent. - -For programmatic (non-auto-install) use, call `installGarnishCompat()` or work with -the named `compatify` / `GarnishCompat` exports directly: - -```ts -import {installGarnishCompat, compatify} from '@craftcms/garnish/compat'; -import {Modal} from '@craftcms/garnish'; - -const Garnish = installGarnishCompat(); -const LegacyModal = compatify(Modal); // one class, without the global -``` - -#### How to DROP the compat layer - -The compat layer is **opt-in and tree-shakeable** — you remove it by removing its -import. Migrate one class at a time: - -1. Convert a `Garnish.X.extend({init(){…}})` subclass to - `class extends X { constructor(){ super(); … } }`, replacing `this.base(...)` - with `super.method(...)` and importing the modern named export - (`import {Modal} from '@craftcms/garnish'`). Modern and compat code can coexist - in the same bundle during the transition. -2. Once nothing depends on `window.Garnish` or the legacy affordances, **delete the - `import '@craftcms/garnish/compat'` line.** Tree-shaking then drops all of the - compat code, the `window.Garnish` global, and the jQuery peer requirement. - -## Documentation - -In-depth docs live in [`docs/`](docs/): - -- [`docs/api-reference.md`](docs/api-reference.md) — the full public surface: every - class, its settings, methods, properties, and events, plus the `Garnish` namespace, - utilities, and constants. -- [`docs/architecture.md`](docs/architecture.md) — how the class system, dual event - system, utility surface, and settings system fit together. -- [`docs/compat-and-migration.md`](docs/compat-and-migration.md) — the opt-in compat - entry and how to migrate a plugin onto the modern surface. -- [`docs/contributing.md`](docs/contributing.md) — working on the package itself. - -Public API symbols carry TSDoc — your editor's IntelliSense is the fastest reference. - -## Development - -```bash -npm run dev # Storybook dev server at http://localhost:6006 -npm run storybook # alias of `npm run dev` -npm run build:storybook # static Storybook build -npm run build # production build (dual `.` + `/compat` entries) -npm run build:watch # Vite+ pack watch build -npm run test # Vitest suite -npm run check:types # tsc --noEmit (includes stories) -npm run format # Oxfmt (writes ./src ./tests ./stories ./.storybook) -``` - -Interactive component demos live in **Storybook** (`npm run dev` or -`npm run storybook` → http://localhost:6006), with one story file per component -under `stories/`. Stories import the real source from `../src`, so edits -hot-reload instantly. See [`docs/contributing.md`](docs/contributing.md) for the -toolchain, the verification gates, how stories are organized, the Actions-panel event -logger, and how to add a story when building a new component. - -## Components - -All of the following are implemented, tested, and available as named exports. See the -[API reference](docs/api-reference.md) for each one's full surface. - -- **`Modal`** — accessible, animated dialog with focus trapping and ARIA - backgrounding. Optional `draggable` (via `DragMove`) and `resizable` (via `BaseDrag` - on a generated corner handle); both default to `false`. -- **`HUD`** — anchored popover/bubble with smart 4-way positioning, a tip/arrow, - scroll-follow, focus trapping, and `UiLayerManager` layer + Escape integration. -- **`DisclosureMenu`** — disclosure dropdown/menu with above/below + left/center/right - positioning, full keyboard navigation + type-ahead search, focus management, an - optional search input, and an item/group builder surface. -- **`Listbox`** — single-select toggle group built on `aria-pressed`. -- **Drag cluster** — `BaseDrag` / `DragMove` (Pointer Events + native auto-scroll), - `Drag` (helper clones + return-to-source / fade-out, Web Animations API, - reduced-motion aware), `DragDrop` (drop targets + hit detection), and `DragSort` - (sortable lists with live insertion feedback). -- **Utilities** — a broad named-export surface for DOM, focus, ARIA, forms, animation, - and environment helpers. - -The opt-in [`compat`](docs/compat-and-migration.md) layer wraps every class to restore -the legacy `Garnish.Base.extend()` / `this.base()` / jQuery authoring contract. - -## License - -MIT © Pixel & Tonic, Inc. diff --git a/packages/craftcms-garnish/docs/README.md b/packages/craftcms-garnish/docs/README.md deleted file mode 100644 index 6cb789cf7a6..00000000000 --- a/packages/craftcms-garnish/docs/README.md +++ /dev/null @@ -1,15 +0,0 @@ -# `@craftcms/garnish` — Documentation - -Reference documentation for consumers of the package. For installation and quick -per-component usage examples, start with the package [README](../README.md); the docs -here go deeper. - -| Doc | What it covers | -| --- | --- | -| [Architecture](architecture.md) | How the class system, dual event system, utility surface, and settings system fit together — and the behaviors worth knowing before you subclass. | -| [API Reference](api-reference.md) | The full public surface: every class, its settings, methods, properties, and events, plus the `Garnish` namespace, utilities, and constants. | -| [Compat & Migration](compat-and-migration.md) | The opt-in `@craftcms/garnish/compat` entry — adopting it in an existing plugin and migrating off it onto the modern surface, class by class. | -| [Contributing](contributing.md) | Working on the package: toolchain, scripts, verification gates, and the Storybook demos. | - -Public API symbols carry TSDoc, so your editor's IntelliSense is the fastest reference -for individual signatures. diff --git a/packages/craftcms-garnish/docs/api-reference.md b/packages/craftcms-garnish/docs/api-reference.md deleted file mode 100644 index dabd134f392..00000000000 --- a/packages/craftcms-garnish/docs/api-reference.md +++ /dev/null @@ -1,802 +0,0 @@ -# API Reference - -A concise "what can I call" cheat sheet for the public surface of -`@craftcms/garnish`. Signatures are simplified for readability; the source TSDoc -(and your editor's IntelliSense) is authoritative. - -Two entry points: - -| Import | Surface | -| --- | --- | -| `@craftcms/garnish` | Modern, jQuery-free named exports + the `Garnish` namespace object. | -| `@craftcms/garnish/compat` | Side-effecting: installs `window.Garnish`, restores `.extend()`/`this.base()`/jQuery args. | - ---- - -## `Base` - -`abstract class Base` — the -base class every component extends. Native `class` + `super`; no `init`/`this.base` -(those are compat-only). - -| Member | Signature | Description | -| --- | --- | --- | -| `settings` | `S \| null` | Resolved settings; `null` until `setSettings` runs. | -| `disabled` | `get => boolean` | Whether the instance is disabled. | -| `setSettings` | `(settings?, defaults?) => void` | Shallow-merge defaults ← overrides into `settings`. | -| `on` | `(events, [data,] handler) => void` | Subscribe to instance event(s); supports `.namespace`s. `'*'` subscribes to **every** event. | -| `once` | `(events, [data,] handler) => void` | Like `on`, auto-removed after first fire. | -| `off` | `(events, handler?) => void` | Unsubscribe (namespaced, by type, and/or by handler ref). | -| `trigger` | `(type, data?) => void` | Emit an event to instance + class-level handlers. | -| `addListener` | `(elem, events, [data,] handler) => void` | Bind tracked DOM listener(s); `handler` may be a method-name string. | -| `removeListener` | `(elem, events) => void` | Remove specific DOM listener(s). | -| `removeAllListeners` | `(elem) => void` | Remove all DOM listeners on an element. | -| `enable` / `disable` | `() => void` | Toggle the DOM-listener gate. | -| `destroy` | `() => void` | Emit `destroy`, remove all listeners, clear handlers. | - -Event objects passed to handlers are `GarnishEvent` (for DOM events, the native -`Event` augmented with `data`/`target`). - ---- - -## `Modal` - -`class Modal extends Base` — accessible, animated modal dialog. - -**Constructor:** `new Modal(container?, settings?)` — also `new Modal(settings)` -(param shift when the first arg is a plain object). - -### Statics - -| Member | Type | Description | -| --- | --- | --- | -| `Modal.instances` | `Modal[]` | All live modals. | -| `Modal.visibleModal` | `Modal \| null` | The currently visible modal. | -| `Modal.defaults` | `ModalSettings` | Default settings (below). | -| `Modal.relativeElemPadding` | `number` (`8`) | Legacy parity constant. | - -### Settings (`ModalSettings`) - -| Key | Default | Description | -| --- | --- | --- | -| `autoShow` | `true` | Show immediately on construction (when a container is given). | -| `draggable` | `false` | Make the modal draggable (via `DragMove` on its container). | -| `dragHandleSelector` | `null` | Restrict dragging to this selector within the container (e.g. a header). | -| `resizable` | `false` | Add a corner resize handle (via `BaseDrag`). | -| `minGutter` | `10` | Min px between modal and viewport edge. | -| `onShow` / `onHide` | no-op | Show/hide callbacks. | -| `onFadeIn` / `onFadeOut` | no-op | Post-fade callbacks. | -| `closeOtherModals` | `false` | Hide any other visible modal on show. | -| `hideOnEsc` | `true` | Hide on Escape. | -| `hideOnShadeClick` | `true` | Hide on backdrop click. | -| `triggerElement` | `null` | Focus-restore target (defaults to focus at construction). | -| `shadeClass` | `'modal-shade'` | CSS class for the shade/backdrop. | - -### Methods & properties - -| Member | Signature | Description | -| --- | --- | --- | -| `show` / `hide` | `() => void` / `(ev?) => void` | Show / hide with fade. | -| `quickShow` / `quickHide` | `() => void` | Show / hide without fade. | -| `onShow` / `onHide` / `onFadeIn` / `onFadeOut` | `() => void` | Overridable hooks (emit the event + run the callback). | -| `updateSizeAndPosition` | `() => void` | Re-center and re-fit; emits `updateSizeAndPosition`. | -| `getWidth` / `getHeight` | `() => number` | Measure the container (throws if unset). | -| `setContainer` | `(container) => void` | Assign/replace the container. | -| `addLiveRegion` | `() => void` | Append the live region to the container. | -| `destroy` | `() => void` | Remove DOM, drop from `instances`, base teardown. | -| `$container` / `$shade` / `$liveRegion` / `$triggerElement` | `HTMLElement \| Element \| null` | Element refs. | -| `visible` | `boolean` | Whether currently shown. | -| `desiredWidth` / `desiredHeight` | `number \| null` | Optional fixed dimensions. | -| `dragger` | `DragMove \| null` | The `DragMove` driving `draggable` (when enabled), else `null`. | -| `resizeDragger` | `BaseDrag \| null` | The `BaseDrag` driving `resizable` (on the resize handle), else `null`. | - -**Events:** `show`, `hide`, `fadeIn`, `fadeOut`, `updateSizeAndPosition`, `escape`, -`destroy`. - ---- - -## `HUD` - -`class HUD extends Base` — an anchored, accessible popover/bubble with -smart 4-way positioning and scroll-follow. Attaches to a trigger element, picks the -best of four orientations from the available clearance, draws a tip pointing back at -the trigger, traps Tab focus between trigger and body, and registers a UI layer + -Escape shortcut (via the shared `UiLayerManager`, like `Modal`). Show/hide are -display toggles — legacy HUD does not animate. - -**Constructor:** `new HUD(trigger, bodyContents?, settings?)` — also -`new HUD(trigger, settings)` (param shift when the 2nd arg is a plain object). This -is exactly the `FieldLayoutDesigner` call shape: `new HUD($addBtn, {...})`. - -### Statics - -| Member | Type | Description | -| --- | --- | --- | -| `HUD.instances` | `HUD[]` | All live HUDs. | -| `HUD.activeHUDs` | `Record` | Open HUDs by namespace (powers `closeOtherHUDs`). | -| `HUD.tipClasses` | `Record` | Orientation → tip-class suffix. | -| `HUD.defaults` | `HUDSettings` | Default settings (below). | - -### Settings (`HUDSettings`) - -| Key | Default | Description | -| --- | --- | --- | -| `hudClass` | `'hud'` | Class(es) for the HUD container (multi-class string OK). | -| `tipClass` | `'tip'` | Base class for the tip; orientation suffix appended. | -| `shadeClass` | `'hud-shade'` | Class for the shade/backdrop. | -| `bodyClass` / `mainContainerClass` / `mainClass` | `'body'` / `'main-container'` / `'main'` | Body / scroll-wrapper / content classes. | -| `headerClass` / `footerClass` | `'hud-header'` / `'hud-footer'` | Header/footer hoisted out of the body content. | -| `orientations` | `['bottom','top','right','left']` | Sides to try, in order of preference. | -| `triggerSpacing` / `windowSpacing` | `10` / `10` | Gap to the trigger / viewport edge (px). | -| `tipWidth` | `30` | Tip/arrow width (px). | -| `minBodyWidth` / `minBodyHeight` | `200` / `0` | Min body dimensions (px). | -| `withShade` | `true` | Render a shade behind the HUD. | -| `onShow` / `onHide` / `onSubmit` | no-op | Registered as `show`/`hide`/`submit` handlers. | -| `closeBtn` | `null` | Element whose `activate` hides the HUD. | -| `listenToMainResize` | `true` | Reposition on the main element's `resize`. | -| `showOnInit` | `true` | Show immediately on construction. | -| `closeOtherHUDs` | `true` | Hide every other open HUD on show. | -| `hideOnEsc` | `true` | Hide on Escape. | -| `hideOnShadeClick` | `true` | Hide on shade click. | - -### Methods & properties - -| Member | Signature | Description | -| --- | --- | --- | -| `show` / `hide` | `(ev?) => void` / `() => void` | Show / hide (display toggle); no-op if already in that state. | -| `toggle` | `() => void` | Flip visibility. | -| `showContainer` / `hideContainer` | `() => void` | The raw display toggles (overridable). | -| `updateBody` | `(contents) => void` | Replace body content; re-extract header/footer. | -| `updateRecords` | `() => boolean` | Re-measure; returns whether anything changed. | -| `updateSizeAndPosition` | `(force?) => void` | Schedule a RAF reposition. | -| `updateSizeAndPositionInternal` | `() => void` | The 4-way positioning pass. | -| `submit` | `() => void` | Fire the `submit` flow. | -| `onShow` / `onHide` / `onSubmit` | `() => void` | Overridable hooks (emit the event). | -| `destroy` | `() => void` | Remove DOM, drop from `instances`/`activeHUDs`, base teardown. | -| `$trigger` / `$hud` / `$tip` / `$body` / `$main` / `$mainContainer` / `$header` / `$footer` / `$shade` | `HTMLElement \| null` | Element refs (`$main` is where consumers append content). | -| `showing` | `boolean` | Whether currently shown. | -| `orientation` | `HUDOrientation \| null` | The chosen side after positioning. | - -**Events:** `show`, `hide`, `submit`, `updateSizeAndPosition`, `destroy`. - -```ts -import {HUD} from '@craftcms/garnish'; - -const hud = new HUD(addBtn, { - hudClass: 'hud fld-library-hud', - orientations: ['right', 'bottom', 'left'], - showOnInit: false, -}); -hud.on('show', () => populate(hud.$main!)); // $main is a raw HTMLElement -hud.on('hide', () => addBtn.focus()); -addBtn.addEventListener('click', () => hud.show()); -``` - ---- - -## `DisclosureMenu` - -`class DisclosureMenu extends Base` — the disclosure -dropdown/menu. Pairs a trigger button (`aria-controls` / `aria-expanded`) with a -pre-existing menu panel: anchors it below the trigger (flipping above when there's -no room) and aligns it left/center/right, manages keyboard nav + type-ahead -search and focus, registers a UI layer + Escape shortcut (via the shared -`UiLayerManager`, like `Modal`/`HUD`), dismisses on outside click, and exposes -item/group builders. Show is instant; hide fades out (WAAPI, reduced-motion aware). - -**Constructor:** `new DisclosureMenu(trigger, settings?)` — `trigger` is an -`ElementInput` (coerced via `getElement`) carrying `aria-controls` (or with the -panel as its next sibling). No param shift (legacy `init(trigger, settings)` has no -body arg). This is the CP call shape: `new DisclosureMenu($trigger, {...})`. - -### Statics - -| Member | Type | Description | -| --- | --- | --- | -| `DisclosureMenu.instances` | `DisclosureMenu[]` | All live menus. | -| `DisclosureMenu.defaults` | `DisclosureMenuSettings` | Default settings (below). | -| `DisclosureMenu.getInstance(el)` | `(Element \| null) => DisclosureMenu \| undefined` | The menu registered for a trigger/container (native `$el.data('disclosureMenu')`). | - -### Settings (`DisclosureMenuSettings`) - -| Key | Default | Description | -| --- | --- | --- | -| `position` | `null` | `'below'` forces the panel below; else clearance picks above/below. | -| `windowSpacing` | `5` | Min gap (px) to the viewport edge. | -| `withSearchInput` | `false` | Render a live item-filtering search input (also via `data-with-search-input`). | - -### Methods & properties - -| Member | Signature | Description | -| --- | --- | --- | -| `show` / `hide` | `() => void` | Show / hide; no-op if already in that state (show also no-ops on a `.disabled` trigger). | -| `handleTriggerClick` | `() => void` | Toggle (re-captures the alignment element). | -| `isExpanded` | `() => boolean` | Whether `aria-expanded === 'true'`. | -| `setContainerPosition` | `() => void` | Above/below + left/center/right positioning (also the scroll/resize handler). | -| `focusElement` | `(el \| 'prev' \| 'next') => void` | Focus an element, or move within the menu's focusables. | -| `addItem` / `addItems` | `(item(s), ul?, prepend?) => HTMLElement \| void` | Build + insert item(s); returns the item's element. | -| `createItem` | `(item) => HTMLLIElement` | Build an item `
  • ` from a config (or pass an element through). | -| `addGroup` / `addList` / `addHr` | — | Add a group (`

    ` + `