From 25467c17f97e42e69e293d4dfcdff2fb49f68d39 Mon Sep 17 00:00:00 2001 From: dangreen Date: Fri, 7 Aug 2026 20:02:31 +0400 Subject: [PATCH] feat(preact): add Preact components --- packages/preact/.size-limit.json | 8 + packages/preact/README.md | 71 ++++ packages/preact/oxlint.config.ts | 22 + packages/preact/package.json | 83 ++++ packages/preact/src/Image.spec.tsx | 246 +++++++++++ packages/preact/src/Image.tsx | 132 ++++++ packages/preact/src/Picture.spec.tsx | 89 ++++ packages/preact/src/Picture.tsx | 54 +++ packages/preact/src/index.ts | 2 + packages/preact/test/setup.ts | 7 + packages/preact/test/src.mock.ts | 41 ++ packages/preact/tsconfig.build.json | 21 + packages/preact/tsconfig.json | 14 + packages/preact/vite.config.js | 32 ++ pnpm-lock.yaml | 615 +++++++++++++++++++++++++++ 15 files changed, 1437 insertions(+) create mode 100644 packages/preact/.size-limit.json create mode 100644 packages/preact/README.md create mode 100644 packages/preact/oxlint.config.ts create mode 100644 packages/preact/package.json create mode 100644 packages/preact/src/Image.spec.tsx create mode 100644 packages/preact/src/Image.tsx create mode 100644 packages/preact/src/Picture.spec.tsx create mode 100644 packages/preact/src/Picture.tsx create mode 100644 packages/preact/src/index.ts create mode 100644 packages/preact/test/setup.ts create mode 100644 packages/preact/test/src.mock.ts create mode 100644 packages/preact/tsconfig.build.json create mode 100644 packages/preact/tsconfig.json create mode 100644 packages/preact/vite.config.js diff --git a/packages/preact/.size-limit.json b/packages/preact/.size-limit.json new file mode 100644 index 0000000..1614270 --- /dev/null +++ b/packages/preact/.size-limit.json @@ -0,0 +1,8 @@ +[ + { + "name": "All publics", + "path": "dist/index.js", + "import": "*", + "limit": "1 kB" + } +] diff --git a/packages/preact/README.md b/packages/preact/README.md new file mode 100644 index 0000000..cc7ddc5 --- /dev/null +++ b/packages/preact/README.md @@ -0,0 +1,71 @@ +# @srcset/preact + +[![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%2Fpreact.svg +[npm-url]: https://npmjs.com/package/@srcset/preact + +[node]: https://img.shields.io/node/v/%40srcset%2Fpreact.svg +[node-url]: https://nodejs.org + +[deps]: https://img.shields.io/librariesio/release/npm/%40srcset%2Fpreact +[deps-url]: https://libraries.io/npm/%40srcset%2Fpreact + +[size]: https://deno.bundlejs.com/badge?q=%40srcset%2Fpreact +[size-url]: https://bundlejs.com/?q=%40srcset%2Fpreact + +[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 + +Preact 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/preact @srcset/runtime +# yarn +yarn add @srcset/preact @srcset/runtime +# npm +npm i @srcset/preact @srcset/runtime +``` + +## Usage + +```tsx +import { src, srcSet, placeholder } from './photo.jpg' +import { Picture, Image } from '@srcset/preact' + +function Hero() { + return ( + + Hero photo + + ) +} +``` + +## Documentation + +For more details, guides and API references, check out the [documentation website](https://srcset.js.org/components/preact/). diff --git a/packages/preact/oxlint.config.ts b/packages/preact/oxlint.config.ts new file mode 100644 index 0000000..adeec91 --- /dev/null +++ b/packages/preact/oxlint.config.ts @@ -0,0 +1,22 @@ +import { defineConfig } from '@trigen/oxlint' +import reactConfig from '@trigen/oxlint-config/react' +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({ + extends: [ + rootConfig, + reactConfig, + tsTypeCheckedConfig, + testConfig + ], + env: { + node: false, + browser: true + }, + rules: { + // Preact JSX uses real DOM attribute names, like `fetchpriority`. + 'react/no-unknown-property': 'off' + } +}) diff --git a/packages/preact/package.json b/packages/preact/package.json new file mode 100644 index 0000000..90538c0 --- /dev/null +++ b/packages/preact/package.json @@ -0,0 +1,83 @@ +{ + "name": "@srcset/preact", + "type": "module", + "version": "1.0.0", + "description": "Preact components for responsive images: Picture and Image.", + "author": { + "name": "Dan Onoshko", + "email": "danon0404@gmail.com", + "url": "https://github.com/dangreen" + }, + "license": "MIT", + "homepage": "https://srcset.js.org/components/preact/", + "funding": "https://ko-fi.com/dangreen", + "repository": { + "type": "git", + "url": "https://github.com/TrigenSoftware/srcset.git", + "directory": "packages/preact" + }, + "bugs": { + "url": "https://github.com/TrigenSoftware/srcset/issues" + }, + "keywords": [ + "srcset", + "image", + "picture", + "responsive", + "preact", + "components" + ], + "engines": { + "node": ">=22" + }, + "sideEffects": false, + "exports": { + "./package.json": "./package.json", + ".": "./src/index.ts" + }, + "publishConfig": { + "exports": { + "./package.json": "./package.json", + ".": { + "types": "./dist/index.d.ts", + "default": "./dist/index.js" + } + }, + "directory": "package", + "linkDirectory": false + }, + "files": [ + "dist" + ], + "scripts": { + "clear:package": "del ./package", + "clear:dist": "del ./dist", + "clear": "del ./package ./dist ./coverage", + "prepublishOnly": "run build clear:package clean-publish", + "postpublish": "pnpm clear:package", + "emitDeclarations": "tsc -p ./tsconfig.build.json --emitDeclarationOnly", + "build:dist": "run -p emitDeclarations [ vite build ]", + "build": "run clear:dist build:dist", + "lint": "oxlint", + "format": "oxlint --fix", + "test:unit": "vitest run --coverage", + "test:unit:watch": "vitest watch", + "test:size": "size-limit", + "test:types": "tsc --noEmit", + "test": "run -p lint test:unit test:types" + }, + "peerDependencies": { + "@srcset/runtime": "workspace:^", + "preact": ">=10.11" + }, + "devDependencies": { + "@size-limit/preset-small-lib": "^12.0.0", + "@srcset/runtime": "workspace:^", + "@testing-library/dom": "^10.0.0", + "@testing-library/jest-dom": "^6.6.3", + "@testing-library/preact": "^3.2.4", + "happy-dom": "^20.0.0", + "preact": "^10.25.0", + "size-limit": "^12.0.0" + } +} diff --git a/packages/preact/src/Image.spec.tsx b/packages/preact/src/Image.spec.tsx new file mode 100644 index 0000000..9830552 --- /dev/null +++ b/packages/preact/src/Image.spec.tsx @@ -0,0 +1,246 @@ +import { + describe, + it, + expect, + vi +} from 'vitest' +import { + render, + screen, + fireEvent +} from '@testing-library/preact' +import { createRef } from 'preact' +import { Image } from './Image.tsx' +import { + createSrc, + createSrcSet +} from '../test/src.mock.ts' + +describe('preact', () => { + describe('Image', () => { + it('should render img from variant with intrinsic size', () => { + render( + photo + ) + + const image = screen.getByAltText('photo') + + expect(image).toHaveAttribute('src', '/images/image@640w.jpg') + expect(image).toHaveAttribute('width', '640') + expect(image).toHaveAttribute('height', '480') + }) + + it('should build srcset from variants of src format', () => { + render( + photo + ) + + expect(screen.getByAltText('photo')).toHaveAttribute( + 'srcset', + '/images/image@320w.jpg 320w, /images/image@640w.jpg 640w' + ) + }) + + it('should accept srcset string as is', () => { + render( + photo + ) + + expect(screen.getByAltText('photo')).toHaveAttribute('srcset', 'custom 2x') + }) + + it('should override intrinsic size with props', () => { + render( + photo + ) + + const image = screen.getByAltText('photo') + + expect(image).toHaveAttribute('width', '100') + expect(image).toHaveAttribute('height', '75') + }) + + it('should not fill the other dimension for a single override', () => { + render( + photo + ) + + const image = screen.getByAltText('photo') + + expect(image).toHaveAttribute('width', '100') + expect(image).not.toHaveAttribute('height') + }) + + it('should drop placeholder for an image completed before hydration', () => { + const complete = vi.spyOn(window.HTMLImageElement.prototype, 'complete', 'get').mockReturnValue(true) + const naturalWidth = vi.spyOn(window.HTMLImageElement.prototype, 'naturalWidth', 'get').mockReturnValue(640) + + try { + render( + photo + ) + + const image = screen.getByAltText('photo') + + expect(image).not.toHaveAttribute('data-loading') + expect(image.style.backgroundImage).toBe('') + } finally { + complete.mockRestore() + naturalWidth.mockRestore() + } + }) + + it('should run callback ref cleanup on unmount', () => { + const cleanup = vi.fn() + const imgRef = vi.fn(() => cleanup) + const { unmount } = render( + photo + ) + + expect(imgRef).toHaveBeenCalledOnce() + + unmount() + + expect(cleanup).toHaveBeenCalledOnce() + // With a cleanup returned, Preact must not call the ref with `null`. + expect(imgRef).toHaveBeenCalledOnce() + }) + + it('should be lazy with async decoding by default', () => { + render( + photo + ) + + const image = screen.getByAltText('photo') + + expect(image).toHaveAttribute('loading', 'lazy') + expect(image).toHaveAttribute('decoding', 'async') + }) + + it('should load eagerly with high priority', () => { + render( + photo + ) + + const image = screen.getByAltText('photo') + + expect(image).toHaveAttribute('loading', 'eager') + expect(image).toHaveAttribute('fetchpriority', 'high') + }) + + it('should keep camel-case fetchPriority when priority toggles off', () => { + const { rerender } = render( + photo + ) + const image = screen.getByAltText('photo') + + expect(image).toHaveAttribute('fetchpriority', 'high') + + rerender( + photo + ) + + expect(image).toHaveAttribute('fetchpriority', 'low') + }) + + it('should show placeholder background until load', () => { + render( + photo + ) + + const image = screen.getByAltText('photo') + + expect(image).toHaveAttribute('data-loading') + expect(image.style.backgroundImage).toBe('url("data:image/webp;base64,abc")') + + fireEvent.load(image) + + expect(image).not.toHaveAttribute('data-loading') + expect(image.style.backgroundImage).toBe('') + }) + + it('should call onLoad prop', () => { + const onLoad = vi.fn() + + render( + photo + ) + + fireEvent.load(screen.getByAltText('photo')) + + expect(onLoad).toHaveBeenCalledOnce() + }) + + it('should pass class and imgRef through', () => { + const ref = createRef() + + render( + photo + ) + + expect(screen.getByAltText('photo')).toHaveClass('hero') + expect(ref.current).toBeInstanceOf(HTMLImageElement) + }) + }) +}) diff --git a/packages/preact/src/Image.tsx b/packages/preact/src/Image.tsx new file mode 100644 index 0000000..d0811ea --- /dev/null +++ b/packages/preact/src/Image.tsx @@ -0,0 +1,132 @@ +import type { + CSSProperties, + ComponentProps, + Ref, + TargetedEvent +} from 'preact' +import { + useCallback, + useState +} from 'preact/hooks' +import { + type SrcSetEntry, + getImageProps +} from '@srcset/runtime' + +function applyRef(ref: Ref | undefined, node: T | null) { + if (typeof ref === 'function') { + // Preact 10.23+ callback refs may return a cleanup function: pass it through. + return ref(node) + } + + if (ref) { + ref.current = node + } + + return undefined +} + +export interface ImageProps extends Omit, 'src' | 'srcSet' | 'srcset' | 'placeholder' | 'style' | 'ref' | 'fetchpriority'> { + /** + * Image variant for the `src` attribute and intrinsic size. + */ + src?: SrcSetEntry + /** + * Variants for the `srcset` attribute: array to build a width descriptors string + * from the variants of the `src` format, or a ready `srcset` string. + */ + srcSet?: SrcSetEntry[] | string + /** + * Data-url shown as a background until the image loads. + * Shown once per mount: remount with a `key` for a new image source. + */ + placeholder?: string + /** + * Load the image eagerly with high priority. + */ + priority?: boolean + /** + * Inline styles, merged with the placeholder background. + */ + style?: CSSProperties + /** + * Ref to the `` element: plain Preact does not forward + * the `ref` prop to function components. + */ + imgRef?: Ref +} + +/** + * `` element from image variants: intrinsic size, lazy loading + * and async decoding by default, optional blur-up placeholder. + * @param props - Image props. + */ +export function Image({ + src, + srcSet, + placeholder, + priority, + width, + height, + loading, + decoding, + fetchPriority, + style, + onLoad, + imgRef, + ...props +}: ImageProps) { + const [loaded, setLoaded] = useState(false) + const imageProps = getImageProps(src, srcSet) + const showPlaceholder = Boolean(placeholder) && !loaded + const onLoadCallback = useCallback( + (event: TargetedEvent) => { + setLoaded(true) + onLoad?.(event) + }, + [onLoad] + ) + // The load event may have fired before hydration for cached images. + const refCallback = useCallback( + (node: HTMLImageElement | null) => { + if (node?.complete && node.naturalWidth > 0) { + setLoaded(true) + } + + return applyRef(imgRef, node) + }, + [imgRef] + ) + let finalWidth = width + let finalHeight = height + + // The intrinsic pair applies only as a whole: with a single explicit + // dimension, filling the other from the variant would skew the ratio. + if (width === undefined && height === undefined && src) { + finalWidth = src.width + finalHeight = src.height + } + + return ( + + ) +} diff --git a/packages/preact/src/Picture.spec.tsx b/packages/preact/src/Picture.spec.tsx new file mode 100644 index 0000000..7b0970d --- /dev/null +++ b/packages/preact/src/Picture.spec.tsx @@ -0,0 +1,89 @@ +import { + describe, + it, + expect +} from 'vitest' +import { + render, + screen +} from '@testing-library/preact' +import { Picture } from './Picture.tsx' +import { Image } from './Image.tsx' +import { + createSrc, + createSrcSet +} from '../test/src.mock.ts' + +const srcSet = [ + ...createSrcSet('jpg', [320, 640]), + ...createSrcSet('webp', [320, 640]), + ...createSrcSet('avif', [320, 640]) +] + +describe('preact', () => { + describe('Picture', () => { + it('should render sources ordered by format efficiency', () => { + const { container } = render( + + photo + + ) + 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( + + photo + + ) + 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( + + photo + + ) + const image = screen.getByAltText('photo') + + expect(image.closest('picture')).toBe(container.querySelector('picture')) + expect(image).toHaveAttribute('src', '/images/image@640w.jpg') + }) + + it('should pass picture attributes through', () => { + const { container } = render( + + photo + + ) + + expect(container.querySelector('picture')).toHaveClass('hero') + }) + }) +}) diff --git a/packages/preact/src/Picture.tsx b/packages/preact/src/Picture.tsx new file mode 100644 index 0000000..9487676 --- /dev/null +++ b/packages/preact/src/Picture.tsx @@ -0,0 +1,54 @@ +import type { + ComponentProps, + ComponentChildren +} from 'preact' +import { + type SrcSetEntry, + getSourceProps +} from '@srcset/runtime' + +export interface PictureProps extends ComponentProps<'picture'> { + /** + * Variants to render `` elements from, grouped by mime type + * and ordered by format efficiency. + */ + srcSet: SrcSetEntry[] + /** + * `sizes` for the generated `` elements: the `sizes` of the + * child `` does not apply to a selected ``. + * Should match the image `sizes`. + */ + sizes?: string + /** + * `` element, required: `` renders nothing without it. + */ + children: ComponentChildren +} + +/** + * `` element with `` per format group of the variants, + * ordered by format efficiency (avif, webp, then the rest). + * Children must contain an `` element, e.g. the `Image` component: + * `` renders nothing without it. + * @param props - Picture props. + */ +export function Picture({ + srcSet, + sizes, + children, + ...props +}: PictureProps) { + return ( + + {getSourceProps(srcSet).map(source => ( + + ))} + {children} + + ) +} diff --git a/packages/preact/src/index.ts b/packages/preact/src/index.ts new file mode 100644 index 0000000..a2496da --- /dev/null +++ b/packages/preact/src/index.ts @@ -0,0 +1,2 @@ +export * from './Image.tsx' +export * from './Picture.tsx' diff --git a/packages/preact/test/setup.ts b/packages/preact/test/setup.ts new file mode 100644 index 0000000..0554751 --- /dev/null +++ b/packages/preact/test/setup.ts @@ -0,0 +1,7 @@ +import '@testing-library/jest-dom/vitest' +import { afterEach } from 'vitest' +import { cleanup } from '@testing-library/preact' + +afterEach(() => { + cleanup() +}) diff --git a/packages/preact/test/src.mock.ts b/packages/preact/test/src.mock.ts new file mode 100644 index 0000000..f8baa09 --- /dev/null +++ b/packages/preact/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/preact/tsconfig.build.json b/packages/preact/tsconfig.build.json new file mode 100644 index 0000000..40f961e --- /dev/null +++ b/packages/preact/tsconfig.build.json @@ -0,0 +1,21 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "rootDir": "./src", + "outDir": "dist", + "jsx": "react-jsx", + "jsxImportSource": "preact", + "lib": [ + "esnext", + "dom" + ] + }, + "include": [ + "src" + ], + "exclude": [ + "**/*.config.ts", + "**/*.spec.ts", + "**/*.spec.tsx" + ] +} diff --git a/packages/preact/tsconfig.json b/packages/preact/tsconfig.json new file mode 100644 index 0000000..2783c96 --- /dev/null +++ b/packages/preact/tsconfig.json @@ -0,0 +1,14 @@ +{ + "extends": "./tsconfig.build.json", + "compilerOptions": { + "rootDir": "../../", + "allowJs": true + }, + "include": [ + "src", + "test", + "*.js", + "*.ts" + ], + "exclude": [] +} diff --git a/packages/preact/vite.config.js b/packages/preact/vite.config.js new file mode 100644 index 0000000..71be62e --- /dev/null +++ b/packages/preact/vite.config.js @@ -0,0 +1,32 @@ +import { defineConfig } from 'vite' +import { configDefaults } from 'vitest/config' + +export default defineConfig({ + build: { + target: 'esnext', + lib: { + formats: ['es'], + entry: { + index: './src/index.ts' + } + }, + rolldownOptions: { + external: id => /^(preact|@srcset)\/?/.test(id), + output: { + topLevelVar: false + } + }, + sourcemap: true, + minify: false, + emptyOutDir: false + }, + test: { + environment: 'happy-dom', + setupFiles: ['./test/setup.ts'], + exclude: [...configDefaults.exclude, './package'], + coverage: { + reporter: ['lcovonly', 'text'], + include: ['src/**/*'] + } + } +}) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 11c3131..79d1936 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -163,6 +163,34 @@ importers: version: 5.108.4(esbuild@0.28.1) publishDirectory: package + packages/preact: + devDependencies: + '@size-limit/preset-small-lib': + specifier: ^12.0.0 + version: 12.1.0(size-limit@12.1.0(jiti@2.6.1)) + '@srcset/runtime': + specifier: workspace:^ + version: link:../runtime + '@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/preact': + specifier: ^3.2.4 + version: 3.2.4(preact@10.29.8) + happy-dom: + specifier: ^20.0.0 + version: 20.11.1 + preact: + specifier: ^10.25.0 + version: 10.29.8 + size-limit: + specifier: ^12.0.0 + version: 12.1.0(jiti@2.6.1) + publishDirectory: package + packages/react: devDependencies: '@size-limit/preset-small-lib': @@ -1278,6 +1306,10 @@ packages: resolution: {integrity: sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==} engines: {node: '>=18'} + '@testing-library/dom@8.20.1': + resolution: {integrity: sha512-/DiOQ5xBxgdYRC8LNk7U+RWat0S3qRLeIw3ZIkMQ9kkVlRmwD/Eg8k8CqIpD6GW7u20JIUOfMKbxtiLutpjQ4g==} + engines: {node: '>=12'} + '@testing-library/jest-dom@6.10.0': resolution: {integrity: sha512-HQwu0KaB2zyT0iLzBL+8CLyZDL3KlZlZJ+2iyc9uCUnlJVskJU/UlPuVCyIPhtukjPQdT2QNoR5nCP5FqTmmDQ==} engines: {node: '>=22', npm: '>=6', yarn: '>=1'} @@ -1285,6 +1317,12 @@ packages: peerDependencies: '@testing-library/dom': '>=10 <11' + '@testing-library/preact@3.2.4': + resolution: {integrity: sha512-F+kJ243LP6VmEK1M809unzTE/ijg+bsMNuiRN0JEDIJBELKKDNhdgC/WrUSZ7klwJvtlO3wQZ9ix+jhObG07Fg==} + engines: {node: '>= 12'} + peerDependencies: + preact: '>=10 || ^10.0.0-alpha.0 || ^10.0.0-beta.0' + '@testing-library/react@16.3.2': resolution: {integrity: sha512-XU5/SytQM+ykqMnAnvB2umaJNIOsLF3PVv//1Ew4CTcpz0/BRyy/af40qqrt7SjKpDdT1saBMc42CUok5gaw+g==} engines: {node: '>=18'} @@ -1648,6 +1686,9 @@ packages: resolution: {integrity: sha512-DhBpBfXL4SS2uC0N922MMajKR3CdrTG0u2or1PNYgXMsrSzViJrbtvT0nCLlLGUI0plam/ZZCs7aAauHtW9thw==} engines: {node: '>=22'} + aria-query@5.1.3: + resolution: {integrity: sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==} + aria-query@5.3.0: resolution: {integrity: sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==} @@ -1655,6 +1696,10 @@ packages: resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==} engines: {node: '>= 0.4'} + array-buffer-byte-length@1.0.2: + resolution: {integrity: sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==} + engines: {node: '>= 0.4'} + assertion-error@2.0.1: resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} engines: {node: '>=12'} @@ -1666,6 +1711,10 @@ packages: resolution: {integrity: sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==} engines: {node: '>= 4.0.0'} + available-typed-arrays@1.0.7: + resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} + engines: {node: '>= 0.4'} + balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} @@ -1710,6 +1759,18 @@ packages: resolution: {integrity: sha512-9EtFOZR8g22CL7BWjJ9BUx1+A/djkofnyW3aOXZORNW2kxoUpx2h+uN2cOqwPmFhnpVmxg+KW2OjOSgChTEvsQ==} engines: {node: '>=6'} + call-bind-apply-helpers@1.0.2: + resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} + engines: {node: '>= 0.4'} + + call-bind@1.0.9: + resolution: {integrity: sha512-a/hy+pNsFUTR+Iz8TCJvXudKVLAnz/DyeSUo10I5yvFDQJBFU2s9uqQpoSrJlroHUKoKqzg+epxyP9lqFdzfBQ==} + engines: {node: '>= 0.4'} + + call-bound@1.0.4: + resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} + engines: {node: '>= 0.4'} + callsites@3.1.0: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} @@ -1841,9 +1902,21 @@ packages: dedent@0.7.0: resolution: {integrity: sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==} + deep-equal@2.2.3: + resolution: {integrity: sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==} + engines: {node: '>= 0.4'} + defaults@1.0.4: resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} + define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + + define-properties@1.2.1: + resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} + engines: {node: '>= 0.4'} + del-cli@7.0.0: resolution: {integrity: sha512-fRl4pWJYu9WFQH8jXdQUYvcD0IMtij9WEc7qmB7xOyJEweNJNuE7iKmqNeoOT1DbBUjtRjxlw8Y63qKBI/NQ1g==} engines: {node: '>=18'} @@ -1875,6 +1948,10 @@ packages: dom-accessibility-api@0.6.3: resolution: {integrity: sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==} + dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} + electron-to-chromium@1.5.393: resolution: {integrity: sha512-kiDJdIUawuEIcp9XoICKp1iTYDEbgguIPq526N1Q7jIQDeQ3CqoMx71025PI/7E48Ddtw2HuWsVjY7afEgNxmg==} @@ -1899,9 +1976,24 @@ packages: error-ex@1.3.4: resolution: {integrity: sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==} + es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es-get-iterator@1.1.3: + resolution: {integrity: sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==} + es-module-lexer@2.3.1: resolution: {integrity: sha512-shc1dbU90Yl/xq1QrC7QRtfcwURZuVRfPhZbDoldJ1cn1gzDvBaBWlv0eFolj5+0znnPJz5TXLxsN77X/12KTA==} + es-object-atoms@1.1.2: + resolution: {integrity: sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==} + engines: {node: '>= 0.4'} + es-toolkit@1.49.0: resolution: {integrity: sha512-G5iZ6Pc/FNRY/soKZHC+TxGDD83rHUDXxzaWhGCX44vAv/tMs56WMusnm/KMNK+luUPsgA9U28cGr4RDlSzL2g==} @@ -2001,6 +2093,10 @@ packages: resolution: {integrity: sha512-6jvvn/12IC4quLBL1KNokxC7wWTvYncaVUYSoxWw7YykPLuRrnv4qdHcSOywOI5RpkOVGeQRtWM8/q+G6W6qfQ==} engines: {node: '>= 8'} + for-each@0.3.5: + resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} + engines: {node: '>= 0.4'} + fs-extra@9.1.0: resolution: {integrity: sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==} engines: {node: '>=10'} @@ -2013,6 +2109,12 @@ packages: engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} os: [darwin] + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + functions-have-names@1.2.3: + resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + get-caller-file@2.0.5: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} @@ -2021,6 +2123,14 @@ packages: resolution: {integrity: sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA==} engines: {node: '>=18'} + get-intrinsic@1.3.0: + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} + engines: {node: '>= 0.4'} + + get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} + engines: {node: '>= 0.4'} + glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} @@ -2051,6 +2161,10 @@ packages: resolution: {integrity: sha512-0Ia46fDOaT7k4og1PDW4YbodWWr3scS2vAr2lTbsplOt2WkKp0vQbkI9wKis/T5LV/dqPjO3bpS/z6GTJB82LA==} engines: {node: '>=18'} + gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} + graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} @@ -2058,6 +2172,10 @@ packages: resolution: {integrity: sha512-XSt8tMzbW9ymE7687xztkO1ckR7qJNQ3LywY9vlYGhGi3zXrGBHuUo2Cl1ztZaICW+1eAGdkLbj6iwVqDT33kg==} engines: {node: '>=20.0.0'} + has-bigints@1.1.0: + resolution: {integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==} + engines: {node: '>= 0.4'} + has-flag@3.0.0: resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} engines: {node: '>=4'} @@ -2066,6 +2184,21 @@ packages: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} + has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + + has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} + + has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + + hasown@2.0.4: + resolution: {integrity: sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==} + engines: {node: '>= 0.4'} + homedir-polyfill@1.0.3: resolution: {integrity: sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==} engines: {node: '>=0.10.0'} @@ -2118,9 +2251,37 @@ packages: resolution: {integrity: sha512-UjOaSel/iddGZJ5xP/Eixh6dY1XghiBw4XK13rCCIJcJfyhhoul/7KhLLUGtebEj6GDYM6Vnx/mVsjx2L/mFIA==} engines: {node: '>=12.0.0'} + internal-slot@1.1.0: + resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==} + engines: {node: '>= 0.4'} + + is-arguments@1.2.0: + resolution: {integrity: sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==} + engines: {node: '>= 0.4'} + + is-array-buffer@3.0.5: + resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==} + engines: {node: '>= 0.4'} + is-arrayish@0.2.1: resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + is-bigint@1.1.0: + resolution: {integrity: sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==} + engines: {node: '>= 0.4'} + + is-boolean-object@1.2.2: + resolution: {integrity: sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==} + engines: {node: '>= 0.4'} + + is-callable@1.2.7: + resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} + engines: {node: '>= 0.4'} + + is-date-object@1.1.0: + resolution: {integrity: sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==} + engines: {node: '>= 0.4'} + is-extglob@2.1.1: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} @@ -2137,6 +2298,14 @@ packages: resolution: {integrity: sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==} engines: {node: '>=8'} + is-map@2.0.3: + resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} + engines: {node: '>= 0.4'} + + is-number-object@1.1.1: + resolution: {integrity: sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==} + engines: {node: '>= 0.4'} + is-number@7.0.0: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} @@ -2157,6 +2326,26 @@ packages: resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} engines: {node: '>=12'} + is-regex@1.2.1: + resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==} + engines: {node: '>= 0.4'} + + is-set@2.0.3: + resolution: {integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==} + engines: {node: '>= 0.4'} + + is-shared-array-buffer@1.0.4: + resolution: {integrity: sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==} + engines: {node: '>= 0.4'} + + is-string@1.1.1: + resolution: {integrity: sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==} + engines: {node: '>= 0.4'} + + is-symbol@1.1.1: + resolution: {integrity: sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==} + engines: {node: '>= 0.4'} + is-unicode-supported@0.1.0: resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} engines: {node: '>=10'} @@ -2164,10 +2353,21 @@ packages: is-utf8@0.2.1: resolution: {integrity: sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q==} + is-weakmap@2.0.2: + resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==} + engines: {node: '>= 0.4'} + + is-weakset@2.0.4: + resolution: {integrity: sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==} + engines: {node: '>= 0.4'} + is-windows@1.0.2: resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} engines: {node: '>=0.10.0'} + isarray@2.0.5: + resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} @@ -2331,6 +2531,10 @@ packages: resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} engines: {node: '>=10'} + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + memfs@4.64.0: resolution: {integrity: sha512-Kw72fgY7Wn+sD8KmtNWSafl1dz0UvAsE/PHs3YVfLiaZuA3HxNm9sRLqAu0ATiBGJvME1PxZXbBZPv5GycDeAw==} @@ -2441,6 +2645,22 @@ packages: resolution: {integrity: sha512-wRNIrw4DmVLKQlbgOMdkMx27Wrpzes2hh5Jtbi2bjPd+4wJstWIqP5A+lscnqbm0xxmT5Bpg8Lec5ItEBwx6BQ==} engines: {node: '>=18'} + object-inspect@1.13.4: + resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} + engines: {node: '>= 0.4'} + + object-is@1.1.6: + resolution: {integrity: sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==} + engines: {node: '>= 0.4'} + + object-keys@1.1.1: + resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} + engines: {node: '>= 0.4'} + + object.assign@4.1.7: + resolution: {integrity: sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==} + engines: {node: '>= 0.4'} + obug@2.1.4: resolution: {integrity: sha512-4a+OsYv9UktOJKE+l1A4OufDgdRF9PifWj+tJnHURo/P+WOxpG4GzUFL9qCalmWauao6ogiG+QvnCovwPoyAWA==} engines: {node: '>=12.20.0'} @@ -2519,10 +2739,22 @@ packages: resolution: {integrity: sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==} engines: {node: '>=12'} + possible-typed-array-names@1.1.0: + resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} + engines: {node: '>= 0.4'} + postcss@8.5.20: resolution: {integrity: sha512-lW616l85ucIQL+FocMmL7pQFPqBmwejrCMg+iPxyImlrANNJG9NHq/RkyCZopDhd8C3LA03PHRJDjkbGu8vvug==} engines: {node: ^10 || ^12 || >=14} + preact@10.29.8: + resolution: {integrity: sha512-ej2aVZ+vZ8WO7tvlQWRM9N63A0KzF9q4mWJfDUHgYaIofWY9hu74QdnQrjoPMmZi2/nZ5gN0bJCQF49xQqx09Q==} + peerDependencies: + preact-render-to-string: '>=5' + peerDependenciesMeta: + preact-render-to-string: + optional: true + presentable-error@0.0.1: resolution: {integrity: sha512-E6rsNU1QNJgB3sjj7OANinGncFKuK+164sLXw1/CqBjj/EkXSoSdHCtWQGBNlREIGLnL7IEUEGa08YFVUbrhVg==} engines: {node: '>=16'} @@ -2562,6 +2794,10 @@ packages: resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==} engines: {node: '>=8'} + regexp.prototype.flags@1.5.4: + resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==} + engines: {node: '>= 0.4'} + require-from-string@2.0.2: resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} engines: {node: '>=0.10.0'} @@ -2604,6 +2840,10 @@ packages: safe-buffer@5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + safe-regex-test@1.1.0: + resolution: {integrity: sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==} + engines: {node: '>= 0.4'} + safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} @@ -2619,6 +2859,14 @@ packages: engines: {node: '>=10'} hasBin: true + set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} + engines: {node: '>= 0.4'} + + set-function-name@2.0.2: + resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} + engines: {node: '>= 0.4'} + sharp@0.35.3: resolution: {integrity: sha512-ej0zVHuZGHCiABXcNxeYhpRnPNPAcvbG8RMdBAhDAxLKkCRVSpK3Iyu7qbqw3JMzoj0REeM6f3tJLtVwl0023Q==} engines: {node: '>=20.9.0'} @@ -2636,6 +2884,22 @@ packages: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} + side-channel-list@1.0.1: + resolution: {integrity: sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==} + engines: {node: '>= 0.4'} + + side-channel-map@1.0.1: + resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} + engines: {node: '>= 0.4'} + + side-channel-weakmap@1.0.2: + resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} + engines: {node: '>= 0.4'} + + side-channel@1.1.1: + resolution: {integrity: sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==} + engines: {node: '>= 0.4'} + siginfo@2.0.0: resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} @@ -2685,6 +2949,10 @@ packages: std-env@4.2.0: resolution: {integrity: sha512-oCUKSupKTHX53EyjDtuZQ64pjLJ6yYCtpmEw0goYxtjG9KpbRe8KAsl2tBUGU9DyMcJ0RwJ8GqJAFzMXcXW1Rw==} + stop-iteration-iterator@1.1.0: + resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==} + engines: {node: '>= 0.4'} + string-width@4.2.3: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} @@ -2919,6 +3187,18 @@ packages: resolution: {integrity: sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==} engines: {node: '>=12'} + which-boxed-primitive@1.1.1: + resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==} + engines: {node: '>= 0.4'} + + which-collection@1.0.2: + resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} + engines: {node: '>= 0.4'} + + which-typed-array@1.1.22: + resolution: {integrity: sha512-fvO4ExWMFsqyhG3AiPAObMuY1lxaqgYcxbc49CNdWDDECOJNgQyvsOWVwbZc+qf3rzRtxojBK+CMEv0Ld5CYpw==} + engines: {node: '>= 0.4'} + which@1.3.1: resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==} hasBin: true @@ -3820,6 +4100,17 @@ snapshots: picocolors: 1.1.1 pretty-format: 27.5.1 + '@testing-library/dom@8.20.1': + dependencies: + '@babel/code-frame': 7.29.7 + '@babel/runtime': 7.29.7 + '@types/aria-query': 5.0.4 + aria-query: 5.1.3 + chalk: 4.1.2 + dom-accessibility-api: 0.5.16 + lz-string: 1.5.0 + pretty-format: 27.5.1 + '@testing-library/jest-dom@6.10.0(@testing-library/dom@10.4.1)': dependencies: '@adobe/css-tools': 4.5.0 @@ -3830,6 +4121,11 @@ snapshots: picocolors: 1.1.1 redent: 3.0.0 + '@testing-library/preact@3.2.4(preact@10.29.8)': + dependencies: + '@testing-library/dom': 8.20.1 + preact: 10.29.8 + '@testing-library/react@16.3.2(@testing-library/dom@10.4.1)(@types/react-dom@19.2.4(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': dependencies: '@babel/runtime': 7.29.7 @@ -4150,12 +4446,21 @@ snapshots: argue-cli@3.1.0: {} + aria-query@5.1.3: + dependencies: + deep-equal: 2.2.3 + aria-query@5.3.0: dependencies: dequal: 2.0.3 aria-query@5.3.2: {} + array-buffer-byte-length@1.0.2: + dependencies: + call-bound: 1.0.4 + is-array-buffer: 3.0.5 + assertion-error@2.0.1: {} ast-v8-to-istanbul@1.0.5: @@ -4166,6 +4471,10 @@ snapshots: at-least-node@1.0.0: {} + available-typed-arrays@1.0.7: + dependencies: + possible-typed-array-names: 1.1.0 + balanced-match@1.0.2: {} base64-js@1.5.1: {} @@ -4210,6 +4519,23 @@ snapshots: cachedir@2.4.0: {} + call-bind-apply-helpers@1.0.2: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + + call-bind@1.0.9: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + get-intrinsic: 1.3.0 + set-function-length: 1.2.2 + + call-bound@1.0.4: + dependencies: + call-bind-apply-helpers: 1.0.2 + get-intrinsic: 1.3.0 + callsites@3.1.0: {} caniuse-lite@1.0.30001806: {} @@ -4351,10 +4677,43 @@ snapshots: dedent@0.7.0: {} + deep-equal@2.2.3: + dependencies: + array-buffer-byte-length: 1.0.2 + call-bind: 1.0.9 + es-get-iterator: 1.1.3 + get-intrinsic: 1.3.0 + is-arguments: 1.2.0 + is-array-buffer: 3.0.5 + is-date-object: 1.1.0 + is-regex: 1.2.1 + is-shared-array-buffer: 1.0.4 + isarray: 2.0.5 + object-is: 1.1.6 + object-keys: 1.1.1 + object.assign: 4.1.7 + regexp.prototype.flags: 1.5.4 + side-channel: 1.1.1 + which-boxed-primitive: 1.1.1 + which-collection: 1.0.2 + which-typed-array: 1.1.22 + defaults@1.0.4: dependencies: clone: 1.0.4 + define-data-property@1.1.4: + dependencies: + es-define-property: 1.0.1 + es-errors: 1.3.0 + gopd: 1.2.0 + + define-properties@1.2.1: + dependencies: + define-data-property: 1.1.4 + has-property-descriptors: 1.0.2 + object-keys: 1.1.1 + del-cli@7.0.0: dependencies: del: 8.0.1 @@ -4383,6 +4742,12 @@ snapshots: dom-accessibility-api@0.6.3: {} + dunder-proto@1.0.1: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 + electron-to-chromium@1.5.393: {} emoji-regex@10.6.0: {} @@ -4402,8 +4767,28 @@ snapshots: dependencies: is-arrayish: 0.2.1 + es-define-property@1.0.1: {} + + es-errors@1.3.0: {} + + es-get-iterator@1.1.3: + dependencies: + call-bind: 1.0.9 + get-intrinsic: 1.3.0 + has-symbols: 1.1.0 + is-arguments: 1.2.0 + is-map: 2.0.3 + is-set: 2.0.3 + is-string: 1.1.1 + isarray: 2.0.5 + stop-iteration-iterator: 1.1.0 + es-module-lexer@2.3.1: {} + es-object-atoms@1.1.2: + dependencies: + es-errors: 1.3.0 + es-toolkit@1.49.0: {} esbuild@0.28.1: @@ -4516,6 +4901,10 @@ snapshots: micromatch: 4.0.8 resolve-dir: 1.0.1 + for-each@0.3.5: + dependencies: + is-callable: 1.2.7 + fs-extra@9.1.0: dependencies: at-least-node: 1.0.0 @@ -4528,10 +4917,32 @@ snapshots: fsevents@2.3.3: optional: true + function-bind@1.1.2: {} + + functions-have-names@1.2.3: {} + get-caller-file@2.0.5: {} get-east-asian-width@1.6.0: {} + get-intrinsic@1.3.0: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.2 + function-bind: 1.1.2 + get-proto: 1.0.1 + gopd: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.4 + math-intrinsics: 1.1.0 + + get-proto@1.0.1: + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.1.2 + glob-parent@5.1.2: dependencies: is-glob: 4.0.3 @@ -4576,6 +4987,8 @@ snapshots: slash: 5.1.0 unicorn-magic: 0.3.0 + gopd@1.2.0: {} + graceful-fs@4.2.11: {} happy-dom@20.11.1: @@ -4591,10 +5004,26 @@ snapshots: - bufferutil - utf-8-validate + has-bigints@1.1.0: {} + has-flag@3.0.0: {} has-flag@4.0.0: {} + has-property-descriptors@1.0.2: + dependencies: + es-define-property: 1.0.1 + + has-symbols@1.1.0: {} + + has-tostringtag@1.0.2: + dependencies: + has-symbols: 1.1.0 + + hasown@2.0.4: + dependencies: + function-bind: 1.1.2 + homedir-polyfill@1.0.3: dependencies: parse-passwd: 1.0.0 @@ -4651,8 +5080,41 @@ snapshots: transitivePeerDependencies: - '@types/node' + internal-slot@1.1.0: + dependencies: + es-errors: 1.3.0 + hasown: 2.0.4 + side-channel: 1.1.1 + + is-arguments@1.2.0: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-array-buffer@3.0.5: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + is-arrayish@0.2.1: {} + is-bigint@1.1.0: + dependencies: + has-bigints: 1.1.0 + + is-boolean-object@1.2.2: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-callable@1.2.7: {} + + is-date-object@1.1.0: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + is-extglob@2.1.1: {} is-fullwidth-code-point@3.0.0: {} @@ -4663,6 +5125,13 @@ snapshots: is-interactive@1.0.0: {} + is-map@2.0.3: {} + + is-number-object@1.1.1: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + is-number@7.0.0: {} is-path-cwd@3.0.0: {} @@ -4673,12 +5142,45 @@ snapshots: is-plain-obj@4.1.0: {} + is-regex@1.2.1: + dependencies: + call-bound: 1.0.4 + gopd: 1.2.0 + has-tostringtag: 1.0.2 + hasown: 2.0.4 + + is-set@2.0.3: {} + + is-shared-array-buffer@1.0.4: + dependencies: + call-bound: 1.0.4 + + is-string@1.1.1: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-symbol@1.1.1: + dependencies: + call-bound: 1.0.4 + has-symbols: 1.1.0 + safe-regex-test: 1.1.0 + is-unicode-supported@0.1.0: {} is-utf8@0.2.1: {} + is-weakmap@2.0.2: {} + + is-weakset@2.0.4: + dependencies: + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + is-windows@1.0.2: {} + isarray@2.0.5: {} + isexe@2.0.0: {} istanbul-lib-coverage@3.2.2: {} @@ -4806,6 +5308,8 @@ snapshots: dependencies: semver: 7.8.5 + math-intrinsics@1.1.0: {} + memfs@4.64.0: dependencies: '@jsonjoy.com/fs-core': 4.64.0(tslib@2.8.1) @@ -4874,6 +5378,24 @@ snapshots: node-releases@2.0.51: {} + object-inspect@1.13.4: {} + + object-is@1.1.6: + dependencies: + call-bind: 1.0.9 + define-properties: 1.2.1 + + object-keys@1.1.1: {} + + object.assign@4.1.7: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.2 + has-symbols: 1.1.0 + object-keys: 1.1.1 + obug@2.1.4: {} once@1.4.0: @@ -4961,12 +5483,16 @@ snapshots: picomatch@4.0.5: {} + possible-typed-array-names@1.1.0: {} + postcss@8.5.20: dependencies: nanoid: 3.3.16 picocolors: 1.1.1 source-map-js: 1.2.1 + preact@10.29.8: {} + presentable-error@0.0.1: {} pretty-format@27.5.1: @@ -5007,6 +5533,15 @@ snapshots: indent-string: 4.0.0 strip-indent: 3.0.0 + regexp.prototype.flags@1.5.4: + dependencies: + call-bind: 1.0.9 + 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 + require-from-string@2.0.2: {} resolve-dir@1.0.1: @@ -5058,6 +5593,12 @@ snapshots: safe-buffer@5.2.1: {} + safe-regex-test@1.1.0: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-regex: 1.2.1 + safer-buffer@2.1.2: {} scheduler@0.27.0: {} @@ -5071,6 +5612,22 @@ snapshots: semver@7.8.5: {} + set-function-length@1.2.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.3.0 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + + set-function-name@2.0.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + functions-have-names: 1.2.3 + has-property-descriptors: 1.0.2 + sharp@0.35.3(@types/node@22.20.1): dependencies: '@img/colour': 1.1.0 @@ -5110,6 +5667,34 @@ snapshots: shebang-regex@3.0.0: {} + side-channel-list@1.0.1: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + + side-channel-map@1.0.1: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + + side-channel-weakmap@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + side-channel-map: 1.0.1 + + side-channel@1.1.1: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + side-channel-list: 1.0.1 + side-channel-map: 1.0.1 + side-channel-weakmap: 1.0.2 + siginfo@2.0.0: {} signal-exit@3.0.7: {} @@ -5147,6 +5732,11 @@ snapshots: std-env@4.2.0: {} + stop-iteration-iterator@1.1.0: + dependencies: + es-errors: 1.3.0 + internal-slot: 1.1.0 + string-width@4.2.3: dependencies: emoji-regex: 8.0.0 @@ -5363,6 +5953,31 @@ snapshots: whatwg-mimetype@3.0.0: {} + which-boxed-primitive@1.1.1: + dependencies: + is-bigint: 1.1.0 + is-boolean-object: 1.2.2 + is-number-object: 1.1.1 + is-string: 1.1.1 + is-symbol: 1.1.1 + + which-collection@1.0.2: + dependencies: + is-map: 2.0.3 + is-set: 2.0.3 + is-weakmap: 2.0.2 + is-weakset: 2.0.4 + + which-typed-array@1.1.22: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.9 + call-bound: 1.0.4 + for-each: 0.3.5 + get-proto: 1.0.1 + gopd: 1.2.0 + has-tostringtag: 1.0.2 + which@1.3.1: dependencies: isexe: 2.0.0