From ac7cf3bd80facea1ee9608c495728f77b8a85c24 Mon Sep 17 00:00:00 2001 From: dangreen Date: Sat, 8 Aug 2026 00:37:23 +0400 Subject: [PATCH] feat(svelte): add Svelte components --- packages/svelte/README.md | 69 ++++++ packages/svelte/oxlint.config.ts | 38 +++ packages/svelte/package.json | 88 +++++++ packages/svelte/src/Image.spec.ts | 216 ++++++++++++++++ packages/svelte/src/Image.svelte | 87 +++++++ packages/svelte/src/Picture.spec.ts | 86 +++++++ packages/svelte/src/Picture.svelte | 54 ++++ packages/svelte/src/index.ts | 2 + packages/svelte/test/RefHolder.svelte | 18 ++ packages/svelte/test/setup.ts | 7 + packages/svelte/test/src.mock.ts | 41 +++ packages/svelte/tsconfig.json | 20 ++ packages/svelte/vite.config.js | 20 ++ pnpm-lock.yaml | 344 ++++++++++++++++++++++++++ 14 files changed, 1090 insertions(+) create mode 100644 packages/svelte/README.md create mode 100644 packages/svelte/oxlint.config.ts create mode 100644 packages/svelte/package.json create mode 100644 packages/svelte/src/Image.spec.ts create mode 100644 packages/svelte/src/Image.svelte create mode 100644 packages/svelte/src/Picture.spec.ts create mode 100644 packages/svelte/src/Picture.svelte create mode 100644 packages/svelte/src/index.ts create mode 100644 packages/svelte/test/RefHolder.svelte create mode 100644 packages/svelte/test/setup.ts create mode 100644 packages/svelte/test/src.mock.ts create mode 100644 packages/svelte/tsconfig.json create mode 100644 packages/svelte/vite.config.js diff --git a/packages/svelte/README.md b/packages/svelte/README.md new file mode 100644 index 0000000..b0a637b --- /dev/null +++ b/packages/svelte/README.md @@ -0,0 +1,69 @@ +# @srcset/svelte + +[![ESM-only package][package]][package-url] +[![NPM version][npm]][npm-url] +[![Node version][node]][node-url] +[![Dependencies status][deps]][deps-url] +[![Install size][size]][size-url] +[![Build status][build]][build-url] +[![Coverage status][coverage]][coverage-url] + +[package]: https://img.shields.io/badge/package-ESM--only-ffe536.svg +[package-url]: https://nodejs.org/api/esm.html + +[npm]: https://img.shields.io/npm/v/%40srcset%2Fsvelte.svg +[npm-url]: https://npmjs.com/package/@srcset/svelte + +[node]: https://img.shields.io/node/v/%40srcset%2Fsvelte.svg +[node-url]: https://nodejs.org + +[deps]: https://img.shields.io/librariesio/release/npm/%40srcset%2Fsvelte +[deps-url]: https://libraries.io/npm/%40srcset%2Fsvelte + +[size]: https://deno.bundlejs.com/badge?q=%40srcset%2Fsvelte +[size-url]: https://bundlejs.com/?q=%40srcset%2Fsvelte + +[build]: https://img.shields.io/github/actions/workflow/status/TrigenSoftware/srcset/tests.yml?branch=main +[build-url]: https://github.com/TrigenSoftware/srcset/actions + +[coverage]: https://img.shields.io/codecov/c/github/TrigenSoftware/srcset.svg +[coverage-url]: https://app.codecov.io/gh/TrigenSoftware/srcset + +Svelte components for responsive images: Picture and Image. + +- 🖼 `` sources grouped by mime type and ordered by format efficiency +- 🚀 Lazy loading and async decoding by default, `priority` for above-the-fold images +- 🌫 Blur-up placeholder background until the image loads +- 📐 Anti-CLS: intrinsic size from the image variant + +## Install + +```bash +# pnpm +pnpm add @srcset/svelte @srcset/runtime +# yarn +yarn add @srcset/svelte @srcset/runtime +# npm +npm i @srcset/svelte @srcset/runtime +``` + +## Usage + +```svelte + + + + Hero photo + +``` + +## Documentation + +For more details, guides and API references, check out the [documentation website](https://srcset.js.org/components/svelte/). diff --git a/packages/svelte/oxlint.config.ts b/packages/svelte/oxlint.config.ts new file mode 100644 index 0000000..042e7d7 --- /dev/null +++ b/packages/svelte/oxlint.config.ts @@ -0,0 +1,38 @@ +import { defineConfig } from '@trigen/oxlint' +import testConfig from '@trigen/oxlint-config/test' +import tsTypeCheckedConfig from '@trigen/oxlint-config/typescript-type-checked' +import rootConfig from '../../oxlint.config.ts' + +export default defineConfig({ + ignorePatterns: ['.svelte-kit'], + extends: [ + rootConfig, + tsTypeCheckedConfig, + testConfig + ], + env: { + node: false, + browser: true + }, + overrides: [ + { + files: ['**/*.svelte'], + globals: { + $props: 'readonly', + $state: 'readonly', + $derived: 'readonly', + $effect: 'readonly', + $bindable: 'readonly' + }, + rules: { + // Svelte requires `let` for reactive props: reassignment is done by the compiler. + 'prefer-const': 'off', + // Script blocks are indented inside the ` + + + + + + { + loaded = true + onload?.(event) + }} + style={showPlaceholder + ? `background-image:url(${placeholder});background-size:cover;${style ?? ''}` + : style} +/> diff --git a/packages/svelte/src/Picture.spec.ts b/packages/svelte/src/Picture.spec.ts new file mode 100644 index 0000000..6fd2e6f --- /dev/null +++ b/packages/svelte/src/Picture.spec.ts @@ -0,0 +1,86 @@ +import { + describe, + it, + expect +} from 'vitest' +import { + render, + screen +} from '@testing-library/svelte' +import { createRawSnippet } from 'svelte' +import Picture from './Picture.svelte' +import { createSrcSet } from '../test/src.mock.ts' + +const srcSet = [ + ...createSrcSet('jpg', [320, 640]), + ...createSrcSet('webp', [320, 640]), + ...createSrcSet('avif', [320, 640]) +] +const image = createRawSnippet(() => ({ + render: () => 'photo' +})) + +describe('svelte', () => { + describe('Picture', () => { + it('should render sources ordered by format efficiency', () => { + const { container } = render(Picture, { + props: { + srcSet, + children: image + } + }) + const sources = [...container.querySelectorAll('source')] + + expect(sources.map(source => source.type)).toEqual([ + 'image/avif', + 'image/webp', + 'image/jpeg' + ]) + expect(sources[0]).toHaveAttribute( + 'srcset', + '/images/image@320w.avif 320w, /images/image@640w.avif 640w' + ) + }) + + it('should apply sizes to every source', () => { + const { container } = render(Picture, { + props: { + srcSet, + sizes: '(max-width: 600px) 100vw, 50vw', + children: image + } + }) + const sources = [...container.querySelectorAll('source')] + + expect(sources.length).toBeGreaterThan(0) + sources.forEach((source) => { + expect(source).toHaveAttribute('sizes', '(max-width: 600px) 100vw, 50vw') + }) + }) + + it('should render img child inside picture', () => { + const { container } = render(Picture, { + props: { + srcSet, + children: image + } + }) + const img = screen.getByAltText('photo') + + expect(img.closest('picture')).toBe(container.querySelector('picture')) + expect(img).toHaveAttribute('src', '/images/image@640w.jpg') + }) + + it('should pass picture attributes through', () => { + const { container } = render(Picture, { + props: { + srcSet, + class: 'hero', + children: image + } + }) + + expect(container.querySelector('picture')).toHaveClass('hero') + }) + }) +}) diff --git a/packages/svelte/src/Picture.svelte b/packages/svelte/src/Picture.svelte new file mode 100644 index 0000000..a75b484 --- /dev/null +++ b/packages/svelte/src/Picture.svelte @@ -0,0 +1,54 @@ + + + + + + + + {#each sources as source (source.type)} + + {/each} + {@render children()} + diff --git a/packages/svelte/src/index.ts b/packages/svelte/src/index.ts new file mode 100644 index 0000000..b099153 --- /dev/null +++ b/packages/svelte/src/index.ts @@ -0,0 +1,2 @@ +export { default as Image } from './Image.svelte' +export { default as Picture } from './Picture.svelte' diff --git a/packages/svelte/test/RefHolder.svelte b/packages/svelte/test/RefHolder.svelte new file mode 100644 index 0000000..5e33855 --- /dev/null +++ b/packages/svelte/test/RefHolder.svelte @@ -0,0 +1,18 @@ + + +photo diff --git a/packages/svelte/test/setup.ts b/packages/svelte/test/setup.ts new file mode 100644 index 0000000..c258a3d --- /dev/null +++ b/packages/svelte/test/setup.ts @@ -0,0 +1,7 @@ +import '@testing-library/jest-dom/vitest' +import { afterEach } from 'vitest' +import { cleanup } from '@testing-library/svelte' + +afterEach(() => { + cleanup() +}) diff --git a/packages/svelte/test/src.mock.ts b/packages/svelte/test/src.mock.ts new file mode 100644 index 0000000..f8baa09 --- /dev/null +++ b/packages/svelte/test/src.mock.ts @@ -0,0 +1,41 @@ +import type { + SrcSetEntry, + ImageFormat +} from '@srcset/runtime' + +const mimeTypes: Record = { + avif: 'image/avif', + webp: 'image/webp', + jpg: 'image/jpeg', + png: 'image/png', + gif: 'image/gif', + svg: 'image/svg+xml' +} + +/** + * Create an image variant stub. + * @param format - Image format. + * @param width - Image width. + * @param height - Image height. + * @returns Image variant. + */ +export function createSrc(format: ImageFormat, width: number, height = Math.round(width * 0.75)): SrcSetEntry { + return { + id: `${format}${width}`, + format, + type: mimeTypes[format], + width, + height, + url: `/images/image@${width}w.${format}` + } +} + +/** + * Create a set of image variant stubs. + * @param format - Image format. + * @param widths - Image widths. + * @returns Set of image variants. + */ +export function createSrcSet(format: ImageFormat, widths: number[]): SrcSetEntry[] { + return widths.map(width => createSrc(format, width)) +} diff --git a/packages/svelte/tsconfig.json b/packages/svelte/tsconfig.json new file mode 100644 index 0000000..883b1ff --- /dev/null +++ b/packages/svelte/tsconfig.json @@ -0,0 +1,20 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "rootDir": "../../", + "allowJs": true, + "noEmit": true, + "lib": [ + "esnext", + "dom", + "dom.iterable" + ] + }, + "include": [ + "src", + "test", + "*.js", + "*.ts" + ], + "exclude": [] +} diff --git a/packages/svelte/vite.config.js b/packages/svelte/vite.config.js new file mode 100644 index 0000000..a596a78 --- /dev/null +++ b/packages/svelte/vite.config.js @@ -0,0 +1,20 @@ +import { defineConfig } from 'vite' +import { configDefaults } from 'vitest/config' +import { svelte } from '@sveltejs/vite-plugin-svelte' + +export default defineConfig({ + plugins: [svelte()], + resolve: { + // Svelte components are tested in the client runtime. + conditions: ['browser'] + }, + test: { + environment: 'happy-dom', + setupFiles: ['./test/setup.ts'], + exclude: [...configDefaults.exclude, './package', '.svelte-kit/**'], + coverage: { + reporter: ['lcovonly', 'text'], + include: ['src/**/*'] + } + } +}) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 79d1936..709ca1b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -241,6 +241,40 @@ importers: version: 12.1.0(jiti@2.6.1) publishDirectory: package + packages/svelte: + devDependencies: + '@srcset/runtime': + specifier: workspace:^ + version: link:../runtime + '@sveltejs/package': + specifier: ^2.0.0 + version: 2.5.8(svelte@5.56.8(@typescript-eslint/types@8.64.0)) + '@sveltejs/vite-plugin-svelte': + specifier: ^6.0.0 + version: 6.2.4(svelte@5.56.8(@typescript-eslint/types@8.64.0))(vite@8.1.5(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.49.0)) + '@testing-library/dom': + specifier: ^10.0.0 + version: 10.4.1 + '@testing-library/jest-dom': + specifier: ^6.6.3 + version: 6.10.0(@testing-library/dom@10.4.1) + '@testing-library/svelte': + specifier: ^5.2.0 + version: 5.4.2(svelte@5.56.8(@typescript-eslint/types@8.64.0))(vite@8.1.5(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.49.0))(vitest@4.1.10) + happy-dom: + specifier: ^20.0.0 + version: 20.11.1 + svelte: + specifier: ^5.0.0 + version: 5.56.8(@typescript-eslint/types@8.64.0) + svelte-check: + specifier: ^4.0.0 + version: 4.7.4(picomatch@4.0.5)(svelte@5.56.8(@typescript-eslint/types@8.64.0))(typescript@5.9.3) + typescript: + specifier: ^5.9.0 + version: 5.9.3 + publishDirectory: package + packages/vite-plugin: dependencies: '@srcset/bundler-utils': @@ -752,6 +786,9 @@ packages: '@jridgewell/gen-mapping@0.3.13': resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} + '@jridgewell/remapping@2.3.5': + resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} + '@jridgewell/resolve-uri@3.1.2': resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} engines: {node: '>=6.0.0'} @@ -1302,6 +1339,37 @@ packages: peerDependencies: eslint: ^9.0.0 || ^10.0.0 + '@sveltejs/acorn-typescript@1.0.12': + resolution: {integrity: sha512-J1jNYG23QWd67UfrQSFHtjhV37r9mVi0gdc12A3MWPldOjRK35Xk+um+qACPVjgw3AleiqoyEAhok8Wm3q46NA==} + peerDependencies: + acorn: ^8.9.0 + + '@sveltejs/load-config@0.2.1': + resolution: {integrity: sha512-5m3B2cbqQ4TbwW6Xkh66Ntw6dD7gNc77cCxABTTesWcq9jxIzMgTk97pZx5vEtvQx8iokgi7GIphqZe+PGwcZA==} + engines: {node: '>= 18.0.0'} + + '@sveltejs/package@2.5.8': + resolution: {integrity: sha512-zeBbsXYvHiBu56v4gJaGQoEHzg96w0E1j3dOMX8vo56s6vI5eQ57ZEZhudjwjnegnVitRRu5MrmhO0eNvaonIw==} + engines: {node: ^16.14 || >=18} + hasBin: true + peerDependencies: + svelte: ^3.44.0 || ^4.0.0 || ^5.0.0-next.1 + + '@sveltejs/vite-plugin-svelte-inspector@5.0.2': + resolution: {integrity: sha512-TZzRTcEtZffICSAoZGkPSl6Etsj2torOVrx6Uw0KpXxrec9Gg6jFWQ60Q3+LmNGfZSxHRCZL7vXVZIWmuV50Ig==} + engines: {node: ^20.19 || ^22.12 || >=24} + peerDependencies: + '@sveltejs/vite-plugin-svelte': ^6.0.0-next.0 + svelte: ^5.0.0 + vite: ^6.3.0 || ^7.0.0 + + '@sveltejs/vite-plugin-svelte@6.2.4': + resolution: {integrity: sha512-ou/d51QSdTyN26D7h6dSpusAKaZkAiGM55/AKYi+9AGZw7q85hElbjK3kEyzXHhLSnRISHOYzVge6x0jRZ7DXA==} + engines: {node: ^20.19 || ^22.12 || >=24} + peerDependencies: + svelte: ^5.0.0 + vite: ^6.3.0 || ^7.0.0 + '@testing-library/dom@10.4.1': resolution: {integrity: sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==} engines: {node: '>=18'} @@ -1338,6 +1406,25 @@ packages: '@types/react-dom': optional: true + '@testing-library/svelte-core@1.1.3': + resolution: {integrity: sha512-KkMAvXeWorxN2Yn0kdC1lfoAItxpoj4uOWzxK5leDrNxonLvS5nwBFvztrroyTszQ0Wf/EU6iLT8JhY5qcn22g==} + engines: {node: '>=16'} + peerDependencies: + svelte: ^3 || ^4 || ^5 || ^5.0.0-next.0 + + '@testing-library/svelte@5.4.2': + resolution: {integrity: sha512-4o31E4HGo5BU5KwPkulNRocEden+7Tt9JYm9uhln5ajF7DULeyFA46BBWVfKJ8Ms9B3JmOFPTIiVamH7n3KpuQ==} + engines: {node: '>= 10'} + peerDependencies: + svelte: ^3 || ^4 || ^5 || ^5.0.0-next.0 + vite: '*' + vitest: '*' + peerDependenciesMeta: + vite: + optional: true + vitest: + optional: true + '@trigen/oxlint-config@10.1.2': resolution: {integrity: sha512-v5RsINtl8dYo7VJnfL0FiP13ITtWuY66Po89WX8N3+u1LkBGc9l5i64ZJUnfYP59zY3l3067cPJ7s+Feas7UzA==} engines: {node: '>=22'} @@ -1392,6 +1479,9 @@ packages: '@types/react@19.2.18': resolution: {integrity: sha512-AnzbBERsrLKtk2XSfTbYRLjQPdy116Sty4q+T+Bp3IC4l6jNBvreVPAHmpq9qhXQM7CXZPjLVmGMw9sy+hxQ3w==} + '@types/trusted-types@2.0.7': + resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} + '@types/whatwg-mimetype@3.0.2': resolution: {integrity: sha512-c2AKvDT8ToxLIOUlN51gTiHXflsfIFisS4pO7pDPoKouJCESkhZnEy623gwP9laCy5lnLDAw1vAzu2vM2YLOrA==} @@ -1692,6 +1782,10 @@ packages: aria-query@5.3.0: resolution: {integrity: sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==} + aria-query@5.3.1: + resolution: {integrity: sha512-Z/ZeOgVl7bcSYZ/u/rh0fOpvEpq//LZmdbkXyc7syVzjPAhfOa9ebsdTSjEBDU4vs5nC98Kfduj1uFo0qyET3g==} + engines: {node: '>= 0.4'} + aria-query@5.3.2: resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==} engines: {node: '>= 0.4'} @@ -1715,6 +1809,10 @@ packages: resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} engines: {node: '>= 0.4'} + axobject-query@4.1.0: + resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} + engines: {node: '>= 0.4'} + balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} @@ -1793,6 +1891,14 @@ packages: chardet@2.2.0: resolution: {integrity: sha512-rddelWYNPRrXq6PtNEN2S3f6t9ILzvqaN5pVgi4kqt9jHQaXIial9PznB5iSPVlQSLNaaH22ItWz3EJtQ10+OA==} + chokidar@4.0.3: + resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} + engines: {node: '>= 14.16.0'} + + chokidar@5.0.0: + resolution: {integrity: sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==} + engines: {node: '>= 20.19.0'} + chrome-trace-event@1.0.4: resolution: {integrity: sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==} engines: {node: '>=6.0'} @@ -1822,6 +1928,10 @@ packages: resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} engines: {node: '>=0.8'} + clsx@2.1.1: + resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} + engines: {node: '>=6'} + color-convert@1.9.3: resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} @@ -1899,6 +2009,9 @@ packages: resolution: {integrity: sha512-U466fIzU5U22eES5lTNiNbZ+d8dfcHcssH4o7QsdWaCcRs/feIPCxKYSWkYBNs5mny7MvEfwpTLWjvbm94hecw==} engines: {node: '>= 10'} + dedent-js@1.0.1: + resolution: {integrity: sha512-OUepMozQULMLUmhxS95Vudo0jb0UchLimi3+pQ2plj61Fcy8axbP9hbiD4Sz6DPqn6XG3kfmziVfQ1rSys5AJQ==} + dedent@0.7.0: resolution: {integrity: sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==} @@ -1906,6 +2019,10 @@ packages: resolution: {integrity: sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==} engines: {node: '>= 0.4'} + deepmerge@4.3.1: + resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} + engines: {node: '>=0.10.0'} + defaults@1.0.4: resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} @@ -1942,6 +2059,9 @@ packages: resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} engines: {node: '>=8'} + devalue@5.9.0: + resolution: {integrity: sha512-RWrqdArjvPbsATEhOPUo6Wndc/iWnkWKlhIrdlF3zMMYo/c3CVtoaVAyLtWxz5h8nSlkHzxnzV2uLydPXmtF+A==} + dom-accessibility-api@0.5.16: resolution: {integrity: sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==} @@ -2022,10 +2142,21 @@ packages: resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + esm-env@1.2.2: + resolution: {integrity: sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA==} + espree@10.4.0: resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + esrap@2.3.1: + resolution: {integrity: sha512-MXjVkrBAjuwIZ8xq9+a1MOOnLIwANZOx/4gtdWHfSJtXOrUh2QQK2I5mMC3urLli559jTlq2j+kSqht80uRgog==} + peerDependencies: + '@typescript-eslint/types': ^8.2.0 + peerDependenciesMeta: + '@typescript-eslint/types': + optional: true + esrecurse@4.3.0: resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} engines: {node: '>=4.0'} @@ -2326,6 +2457,9 @@ packages: resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} engines: {node: '>=12'} + is-reference@3.0.3: + resolution: {integrity: sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw==} + is-regex@1.2.1: resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==} engines: {node: '>= 0.4'} @@ -2415,6 +2549,10 @@ packages: jsonfile@6.2.1: resolution: {integrity: sha512-zwOTdL3rFQ/lRdBnntKVOX6k5cKJwEc1HdilT71BWEu7J41gXIB2MRp+vxduPSwZJPWBxEzv4yH1wYLJGUHX4Q==} + kleur@4.1.5: + resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} + engines: {node: '>=6'} + lightningcss-android-arm64@1.32.0: resolution: {integrity: sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==} engines: {node: '>= 12.0.0'} @@ -2500,6 +2638,9 @@ packages: resolution: {integrity: sha512-DFEqQ3ihfS9blba08cLfYf1NRAIEm+dDjic073DRDc3/JspI/8wYmtDsHwd3+4hwvdxSK7PGaElfTmm0awWJ4w==} engines: {node: '>=6.11.5'} + locate-character@3.0.0: + resolution: {integrity: sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==} + lodash.clonedeep@4.5.0: resolution: {integrity: sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==} @@ -2617,6 +2758,10 @@ packages: uglify-js: optional: true + mri@1.2.0: + resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} + engines: {node: '>=4'} + mute-stream@0.0.8: resolution: {integrity: sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==} @@ -2790,6 +2935,14 @@ packages: resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} engines: {node: '>= 6'} + readdirp@4.1.2: + resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} + engines: {node: '>= 14.18.0'} + + readdirp@5.1.1: + resolution: {integrity: sha512-Kko+Y5XQ6fM+Ce3dq3m9YGxnacYZYl9cA1wZjaF3Vbry2L3i1qVg8+CAgNPsXRArPMUMCaOR7oa9Nqntc43JKA==} + engines: {node: '>= 20.19.0'} + redent@3.0.0: resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==} engines: {node: '>=8'} @@ -2837,6 +2990,10 @@ packages: rxjs@7.8.2: resolution: {integrity: sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==} + sade@1.8.1: + resolution: {integrity: sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==} + engines: {node: '>=6'} + safe-buffer@5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} @@ -2854,6 +3011,9 @@ packages: resolution: {integrity: sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==} engines: {node: '>= 10.13.0'} + scule@1.3.0: + resolution: {integrity: sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==} + semver@7.8.5: resolution: {integrity: sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==} engines: {node: '>=10'} @@ -3003,6 +3163,24 @@ packages: resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} engines: {node: '>=10'} + svelte-check@4.7.4: + resolution: {integrity: sha512-IW9ot9YqAoyv8FvyN+eb4ZTe8zgcKZrJLNYU6dzSKkGwEBsSPc4K7lmQ8bKn8W2YMXM6WDfZSSVOaGtekyUfOQ==} + engines: {node: '>= 18.0.0'} + hasBin: true + peerDependencies: + svelte: ^4.0.0 || ^5.0.0-next.0 + typescript: ^5.0.0 || ^6.0.0 + + svelte2tsx@0.7.59: + resolution: {integrity: sha512-Itj7Wz9WIiGFl/uJa58+rf43ajezaljKK/KTOHq5abUjto56xe+o5SOzLwSoeJ5hma9NZEstpZiazFW2q1nZPQ==} + peerDependencies: + svelte: ^3.55 || ^4.0.0-next.0 || ^4.0 || ^5.0.0-next.0 + typescript: ^4.9.4 || ^5.0.0 || ^6.0.0 + + svelte@5.56.8: + resolution: {integrity: sha512-PY8LOw7xP6c8IOiVqdo0sbbZVYhXRSfklOQLAUyGBKqjTX0wx/z4l/9J+PmBpmlLnxzEb1NqltxQ5/wZme/Cmg==} + engines: {node: '>=18'} + tapable@2.3.3: resolution: {integrity: sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==} engines: {node: '>=6'} @@ -3053,6 +3231,11 @@ packages: resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} engines: {node: '>=10'} + typescript@5.9.3: + resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} + engines: {node: '>=14.17'} + hasBin: true + typescript@7.0.2: resolution: {integrity: sha512-8FYau96o3NKOhbjKi/qNvG/W5jhzxkbdm5sj9AbZ/5T5sWqn3hJgLfGx27sRKZWTvyzCP8dLRBTf5tBTSRVUNA==} engines: {node: '>=16.20.0'} @@ -3121,6 +3304,14 @@ packages: yaml: optional: true + vitefu@1.1.3: + resolution: {integrity: sha512-ub4okH7Z5KLjb6hDyjqrGXqWtWvoYdU3IGm/NorpgHncKoLTCfRIbvlhBm7r0YstIaQRYlp4yEbFqDcKSzXSSg==} + peerDependencies: + vite: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 + peerDependenciesMeta: + vite: + optional: true + vitest@4.1.10: resolution: {integrity: sha512-R9jUTe5S4Qb0HCd4TNqpC7oGcrMssMRGXLW80ubjWsW9VH5GF8y1Y0SFLY9AbqSk6nt0PnOx4H4WNJYZ13GUPw==} engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0} @@ -3264,6 +3455,9 @@ packages: resolution: {integrity: sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==} engines: {node: '>=12.20'} + zimmerframe@1.1.4: + resolution: {integrity: sha512-B58NGBEoc8Y9MWWCQGl/gq9xBCe4IiKM0a2x7GZdQKOW5Exr8S1W24J6OgM1njK8xCRGvAJIL/MxXHf6SkmQKQ==} + snapshots: '@adobe/css-tools@4.5.0': {} @@ -3658,6 +3852,11 @@ snapshots: '@jridgewell/sourcemap-codec': 1.5.5 '@jridgewell/trace-mapping': 0.3.31 + '@jridgewell/remapping@2.3.5': + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + '@jridgewell/resolve-uri@3.1.2': {} '@jridgewell/source-map@0.3.11': @@ -4089,6 +4288,39 @@ snapshots: estraverse: 5.3.0 picomatch: 4.0.5 + '@sveltejs/acorn-typescript@1.0.12(acorn@8.17.0)': + dependencies: + acorn: 8.17.0 + + '@sveltejs/load-config@0.2.1': {} + + '@sveltejs/package@2.5.8(svelte@5.56.8(@typescript-eslint/types@8.64.0))': + dependencies: + chokidar: 5.0.0 + kleur: 4.1.5 + sade: 1.8.1 + semver: 7.8.5 + svelte: 5.56.8(@typescript-eslint/types@8.64.0) + svelte2tsx: 0.7.59(svelte@5.56.8(@typescript-eslint/types@8.64.0))(typescript@5.9.3) + typescript: 5.9.3 + + '@sveltejs/vite-plugin-svelte-inspector@5.0.2(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.56.8(@typescript-eslint/types@8.64.0))(vite@8.1.5(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.49.0)))(svelte@5.56.8(@typescript-eslint/types@8.64.0))(vite@8.1.5(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.49.0))': + dependencies: + '@sveltejs/vite-plugin-svelte': 6.2.4(svelte@5.56.8(@typescript-eslint/types@8.64.0))(vite@8.1.5(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.49.0)) + obug: 2.1.4 + svelte: 5.56.8(@typescript-eslint/types@8.64.0) + vite: 8.1.5(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.49.0) + + '@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.56.8(@typescript-eslint/types@8.64.0))(vite@8.1.5(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.49.0))': + dependencies: + '@sveltejs/vite-plugin-svelte-inspector': 5.0.2(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.56.8(@typescript-eslint/types@8.64.0))(vite@8.1.5(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.49.0)))(svelte@5.56.8(@typescript-eslint/types@8.64.0))(vite@8.1.5(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.49.0)) + deepmerge: 4.3.1 + magic-string: 0.30.21 + obug: 2.1.4 + svelte: 5.56.8(@typescript-eslint/types@8.64.0) + vite: 8.1.5(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.49.0) + vitefu: 1.1.3(vite@8.1.5(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.49.0)) + '@testing-library/dom@10.4.1': dependencies: '@babel/code-frame': 7.29.7 @@ -4136,6 +4368,19 @@ snapshots: '@types/react': 19.2.18 '@types/react-dom': 19.2.4(@types/react@19.2.18) + '@testing-library/svelte-core@1.1.3(svelte@5.56.8(@typescript-eslint/types@8.64.0))': + dependencies: + svelte: 5.56.8(@typescript-eslint/types@8.64.0) + + '@testing-library/svelte@5.4.2(svelte@5.56.8(@typescript-eslint/types@8.64.0))(vite@8.1.5(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.49.0))(vitest@4.1.10)': + dependencies: + '@testing-library/dom': 10.4.1 + '@testing-library/svelte-core': 1.1.3(svelte@5.56.8(@typescript-eslint/types@8.64.0)) + svelte: 5.56.8(@typescript-eslint/types@8.64.0) + optionalDependencies: + vite: 8.1.5(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.49.0) + vitest: 4.1.10(@types/node@22.20.1)(@vitest/coverage-v8@4.1.10)(happy-dom@20.11.1)(vite@8.1.5(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.49.0)) + '@trigen/oxlint-config@10.1.2(oxlint-tsgolint@0.25.0)(oxlint@1.74.0(oxlint-tsgolint@0.25.0))': dependencies: '@stylistic/eslint-plugin': 5.10.0 @@ -4188,6 +4433,8 @@ snapshots: dependencies: csstype: 3.2.3 + '@types/trusted-types@2.0.7': {} + '@types/whatwg-mimetype@3.0.2': {} '@types/ws@8.18.1': @@ -4454,6 +4701,8 @@ snapshots: dependencies: dequal: 2.0.3 + aria-query@5.3.1: {} + aria-query@5.3.2: {} array-buffer-byte-length@1.0.2: @@ -4475,6 +4724,8 @@ snapshots: dependencies: possible-typed-array-names: 1.1.0 + axobject-query@4.1.0: {} + balanced-match@1.0.2: {} base64-js@1.5.1: {} @@ -4555,6 +4806,14 @@ snapshots: chardet@2.2.0: {} + chokidar@4.0.3: + dependencies: + readdirp: 4.1.2 + + chokidar@5.0.0: + dependencies: + readdirp: 5.1.1 + chrome-trace-event@1.0.4: {} clean-publish@5.2.2: @@ -4580,6 +4839,8 @@ snapshots: clone@1.0.4: {} + clsx@2.1.1: {} + color-convert@1.9.3: dependencies: color-name: 1.1.3 @@ -4675,6 +4936,8 @@ snapshots: - '@types/node' - typescript + dedent-js@1.0.1: {} + dedent@0.7.0: {} deep-equal@2.2.3: @@ -4698,6 +4961,8 @@ snapshots: which-collection: 1.0.2 which-typed-array: 1.1.22 + deepmerge@4.3.1: {} + defaults@1.0.4: dependencies: clone: 1.0.4 @@ -4738,6 +5003,8 @@ snapshots: detect-libc@2.1.2: {} + devalue@5.9.0: {} + dom-accessibility-api@0.5.16: {} dom-accessibility-api@0.6.3: {} @@ -4833,12 +5100,20 @@ snapshots: eslint-visitor-keys@4.2.1: {} + esm-env@1.2.2: {} + espree@10.4.0: dependencies: acorn: 8.17.0 acorn-jsx: 5.3.2(acorn@8.17.0) eslint-visitor-keys: 4.2.1 + esrap@2.3.1(@typescript-eslint/types@8.64.0): + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + optionalDependencies: + '@typescript-eslint/types': 8.64.0 + esrecurse@4.3.0: dependencies: estraverse: 5.3.0 @@ -5142,6 +5417,10 @@ snapshots: is-plain-obj@4.1.0: {} + is-reference@3.0.3: + dependencies: + '@types/estree': 1.0.9 + is-regex@1.2.1: dependencies: call-bound: 1.0.4 @@ -5224,6 +5503,8 @@ snapshots: optionalDependencies: graceful-fs: 4.2.11 + kleur@4.1.5: {} + lightningcss-android-arm64@1.32.0: optional: true @@ -5279,6 +5560,8 @@ snapshots: loader-runner@4.3.2: {} + locate-character@3.0.0: {} + lodash.clonedeep@4.5.0: {} lodash.map@4.6.0: {} @@ -5362,6 +5645,8 @@ snapshots: optionalDependencies: esbuild: 0.28.1 + mri@1.2.0: {} + mute-stream@0.0.8: {} nano-staged@1.0.2: {} @@ -5528,6 +5813,10 @@ snapshots: string_decoder: 1.3.0 util-deprecate: 1.0.2 + readdirp@4.1.2: {} + + readdirp@5.1.1: {} + redent@3.0.0: dependencies: indent-string: 4.0.0 @@ -5591,6 +5880,10 @@ snapshots: dependencies: tslib: 2.8.1 + sade@1.8.1: + dependencies: + mri: 1.2.0 + safe-buffer@5.2.1: {} safe-regex-test@1.1.0: @@ -5610,6 +5903,8 @@ snapshots: ajv-formats: 2.1.1 ajv-keywords: 5.1.0(ajv@8.20.0) + scule@1.3.0: {} + semver@7.8.5: {} set-function-length@1.2.2: @@ -5785,6 +6080,47 @@ snapshots: dependencies: has-flag: 4.0.0 + svelte-check@4.7.4(picomatch@4.0.5)(svelte@5.56.8(@typescript-eslint/types@8.64.0))(typescript@5.9.3): + dependencies: + '@jridgewell/trace-mapping': 0.3.31 + '@sveltejs/load-config': 0.2.1 + chokidar: 4.0.3 + fdir: 6.5.0(picomatch@4.0.5) + picocolors: 1.1.1 + sade: 1.8.1 + svelte: 5.56.8(@typescript-eslint/types@8.64.0) + typescript: 5.9.3 + transitivePeerDependencies: + - picomatch + + svelte2tsx@0.7.59(svelte@5.56.8(@typescript-eslint/types@8.64.0))(typescript@5.9.3): + dependencies: + dedent-js: 1.0.1 + scule: 1.3.0 + svelte: 5.56.8(@typescript-eslint/types@8.64.0) + typescript: 5.9.3 + + svelte@5.56.8(@typescript-eslint/types@8.64.0): + dependencies: + '@jridgewell/remapping': 2.3.5 + '@jridgewell/sourcemap-codec': 1.5.5 + '@sveltejs/acorn-typescript': 1.0.12(acorn@8.17.0) + '@types/estree': 1.0.9 + '@types/trusted-types': 2.0.7 + acorn: 8.17.0 + aria-query: 5.3.1 + axobject-query: 4.1.0 + clsx: 2.1.1 + devalue: 5.9.0 + esm-env: 1.2.2 + esrap: 2.3.1(@typescript-eslint/types@8.64.0) + is-reference: 3.0.3 + locate-character: 3.0.0 + magic-string: 0.30.21 + zimmerframe: 1.1.4 + transitivePeerDependencies: + - '@typescript-eslint/types' + tapable@2.3.3: {} terser@5.49.0: @@ -5823,6 +6159,8 @@ snapshots: type-fest@0.21.3: {} + typescript@5.9.3: {} + typescript@7.0.2: optionalDependencies: '@typescript/typescript-aix-ppc64': 7.0.2 @@ -5874,6 +6212,10 @@ snapshots: jiti: 2.6.1 terser: 5.49.0 + vitefu@1.1.3(vite@8.1.5(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.49.0)): + optionalDependencies: + vite: 8.1.5(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.49.0) + vitest@4.1.10(@types/node@22.20.1)(@vitest/coverage-v8@4.1.10)(happy-dom@20.11.1)(vite@8.1.5(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.49.0)): dependencies: '@vitest/expect': 4.1.10 @@ -6033,3 +6375,5 @@ snapshots: yargs-parser: 22.0.0 yocto-queue@1.2.2: {} + + zimmerframe@1.1.4: {}