diff --git a/.gitignore b/.gitignore index acd6a09b..35fa9a41 100644 --- a/.gitignore +++ b/.gitignore @@ -17,6 +17,9 @@ backups .netlify .vercel +# Claude generated files +docs/superpowers + # Others logs *.log diff --git a/frameworks/angular/CHANGELOG.md b/frameworks/angular/CHANGELOG.md new file mode 100644 index 00000000..6b8c75ed --- /dev/null +++ b/frameworks/angular/CHANGELOG.md @@ -0,0 +1,7 @@ +# Changelog + +All notable changes to the library will be documented in this file. + +## v0.0.1 (Month DD, YYYY) + +- Initial release diff --git a/frameworks/angular/eslint.config.ts b/frameworks/angular/eslint.config.ts new file mode 100644 index 00000000..497e3216 --- /dev/null +++ b/frameworks/angular/eslint.config.ts @@ -0,0 +1,28 @@ +import eslint from '@eslint/js'; +import { commonRules, importPlugin, jsdoc } from '@formisch/eslint-config'; +import pluginSecurity from 'eslint-plugin-security'; +import tseslint from 'typescript-eslint'; + +export default tseslint.config( + { ignores: ['eslint.config.ts', 'dist', 'coverage'] }, + eslint.configs.recommended, + jsdoc.configs['flat/recommended'], + pluginSecurity.configs.recommended, + ...tseslint.configs.strictTypeChecked, + ...tseslint.configs.stylisticTypeChecked, + { + name: 'app/files-to-lint', + files: ['src/**/*.ts'], + extends: [importPlugin.flatConfigs.recommended], + plugins: { jsdoc }, + languageOptions: { + parserOptions: { + project: true, + tsconfigRootDir: import.meta.dirname, + }, + }, + rules: { + ...commonRules, + }, + } +); diff --git a/frameworks/angular/package.json b/frameworks/angular/package.json new file mode 100644 index 00000000..94a31286 --- /dev/null +++ b/frameworks/angular/package.json @@ -0,0 +1,71 @@ +{ + "name": "@formisch/angular", + "description": "The lightweight, schema-first, and fully type-safe form library for Angular", + "version": "0.0.1", + "license": "MIT", + "author": "Fabian Hiller", + "homepage": "https://formisch.dev", + "repository": { + "type": "git", + "url": "https://github.com/open-circle/formisch" + }, + "keywords": [ + "angular", + "form", + "typescript", + "schema", + "validation" + ], + "type": "module", + "main": "./dist/index.js", + "types": "./dist/index.d.ts", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/index.js" + } + }, + "sideEffects": false, + "files": [ + "dist" + ], + "publishConfig": { + "access": "public" + }, + "scripts": { + "build": "tsdown", + "test": "vitest run --typecheck --passWithNoTests", + "lint": "eslint \"src/**/*.ts*\" && tsc --noEmit", + "lint.fix": "eslint \"src/**/*.ts*\" --fix", + "format": "prettier --write ./src", + "format.check": "prettier --check ./src" + }, + "devDependencies": { + "@angular/common": "^19.0.0", + "@angular/compiler": "^19.0.0", + "@angular/core": "^19.0.0", + "@angular/platform-browser": "^19.0.0", + "@formisch/core": "workspace:*", + "@formisch/eslint-config": "workspace:*", + "@formisch/methods": "workspace:*", + "@types/node": "^24.0.0", + "@vitest/coverage-v8": "^3.2.4", + "eslint": "^9.31.0", + "jsdom": "^26.1.0", + "tsdown": "^0.16.8", + "typescript": "~5.8.3", + "valibot": "^1.2.0", + "vitest": "^3.2.4", + "zone.js": "^0.15.0" + }, + "peerDependencies": { + "@angular/core": ">=17.0.0", + "typescript": ">=5", + "valibot": "^1.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } +} diff --git a/frameworks/angular/src/components/FormischField/FormischField.test.ts b/frameworks/angular/src/components/FormischField/FormischField.test.ts new file mode 100644 index 00000000..9e08dd6d --- /dev/null +++ b/frameworks/angular/src/components/FormischField/FormischField.test.ts @@ -0,0 +1,47 @@ +import { Component, provideExperimentalZonelessChangeDetection } from '@angular/core'; +import { TestBed } from '@angular/core/testing'; +import * as v from 'valibot'; +import { describe, beforeEach, expect, it } from 'vitest'; +import { injectForm } from '../../functions/index.ts'; +import { FormischField } from './FormischField.ts'; + +const Schema = v.object({ email: v.pipe(v.string(), v.email()) }); + +@Component({ + standalone: true, + imports: [FormischField], + template: ` + + + + {{ field.errors() }} + + + `, +}) +class TestHost { + form = injectForm({ schema: Schema }); +} + +describe('FormischField', () => { + beforeEach(() => { + TestBed.configureTestingModule({ + imports: [TestHost], + providers: [provideExperimentalZonelessChangeDetection()], + }); + }); + + it('renders the template with the field store', async () => { + const fixture = TestBed.createComponent(TestHost); + await fixture.whenStable(); + const input = (fixture.nativeElement as HTMLElement).querySelector('[data-testid="input"]'); + expect(input).not.toBeNull(); + }); + + it('passes the field name prop to the template context', async () => { + const fixture = TestBed.createComponent(TestHost); + await fixture.whenStable(); + const input = (fixture.nativeElement as HTMLElement).querySelector('[data-testid="input"]'); + expect(input.getAttribute('name')).not.toBeNull(); + }); +}); diff --git a/frameworks/angular/src/components/FormischField/FormischField.ts b/frameworks/angular/src/components/FormischField/FormischField.ts new file mode 100644 index 00000000..11474166 --- /dev/null +++ b/frameworks/angular/src/components/FormischField/FormischField.ts @@ -0,0 +1,57 @@ +import { + Component, + contentChild, + input, + type InputSignal, + type Signal, + TemplateRef, +} from '@angular/core'; +import { NgTemplateOutlet } from '@angular/common'; +import { + type RequiredPath, + type Schema, + type ValidPath, +} from '@formisch/core/angular'; +import type * as v from 'valibot'; +import type { FieldStore, FormStore } from '../../types/index.ts'; +import { injectField } from '../../functions/injectField/injectField.ts'; + +/** + * Headless field component that provides reactive field state via an Angular template. + * Uses ContentChild TemplateRef pattern to pass the FieldStore as $implicit context. + * + * @example + * ```html + * + * + * + * + * + * ``` + */ +@Component({ + selector: 'formisch-field', + standalone: true, + imports: [NgTemplateOutlet], + template: ` + @if (template()) { + + } + `, +}) +export class FormischField< + TSchema extends Schema = Schema, + TFieldPath extends RequiredPath = RequiredPath, +> { + readonly of: InputSignal> = input.required>(); + readonly path: InputSignal, TFieldPath>> = input.required, TFieldPath>>(); + + protected readonly template: Signal | undefined> = contentChild(TemplateRef); + protected readonly field: FieldStore = injectField(this.of, { path: this.path }); +} diff --git a/frameworks/angular/src/components/FormischField/index.ts b/frameworks/angular/src/components/FormischField/index.ts new file mode 100644 index 00000000..ab831c49 --- /dev/null +++ b/frameworks/angular/src/components/FormischField/index.ts @@ -0,0 +1 @@ +export * from './FormischField.ts'; diff --git a/frameworks/angular/src/components/FormischFieldArray/FormischFieldArray.test.ts b/frameworks/angular/src/components/FormischFieldArray/FormischFieldArray.test.ts new file mode 100644 index 00000000..28f88f3b --- /dev/null +++ b/frameworks/angular/src/components/FormischFieldArray/FormischFieldArray.test.ts @@ -0,0 +1,48 @@ +import { Component, provideExperimentalZonelessChangeDetection } from '@angular/core'; +import { TestBed } from '@angular/core/testing'; +import * as v from 'valibot'; +import { describe, beforeEach, expect, it } from 'vitest'; +import { injectForm } from '../../functions/index.ts'; +import { FormischFieldArray } from './FormischFieldArray.ts'; + +const Schema = v.object({ + todos: v.array(v.object({ title: v.string() })), +}); + +@Component({ + standalone: true, + imports: [FormischFieldArray], + template: ` + + + {{ fieldArray.items().length }} + + + `, +}) +class TestHost { + form = injectForm({ schema: Schema }); +} + +describe('FormischFieldArray', () => { + beforeEach(() => { + TestBed.configureTestingModule({ + imports: [TestHost], + providers: [provideExperimentalZonelessChangeDetection()], + }); + }); + + it('renders the template with the field array store', async () => { + const fixture = TestBed.createComponent(TestHost); + await fixture.whenStable(); + const span = fixture.nativeElement.querySelector('[data-testid="count"]'); + expect(span).not.toBeNull(); + }); + + it('passes items signal with initial empty array', async () => { + const fixture = TestBed.createComponent(TestHost); + await fixture.whenStable(); + const span = fixture.nativeElement.querySelector('[data-testid="count"]'); + expect(span.textContent.trim()).toBe('0'); + }); +}); diff --git a/frameworks/angular/src/components/FormischFieldArray/FormischFieldArray.ts b/frameworks/angular/src/components/FormischFieldArray/FormischFieldArray.ts new file mode 100644 index 00000000..0a4f09f1 --- /dev/null +++ b/frameworks/angular/src/components/FormischFieldArray/FormischFieldArray.ts @@ -0,0 +1,56 @@ +import { + Component, + contentChild, + input, + type InputSignal, + type Signal, + TemplateRef, +} from '@angular/core'; +import { NgTemplateOutlet } from '@angular/common'; +import { + type RequiredPath, + type Schema, + type ValidArrayPath, +} from '@formisch/core/angular'; +import type * as v from 'valibot'; +import type { FieldArrayStore, FormStore } from '../../types/index.ts'; +import { injectFieldArray } from '../../functions/injectFieldArray/injectFieldArray.ts'; + +/** + * Headless field array component that provides reactive field array state via an Angular template. + * Uses ContentChild TemplateRef pattern to pass the FieldArrayStore as $implicit context. + * + * @example + * ```html + * + * + * @for (item of fieldArray.items(); track item) { + * ... + * } + * + * + * ``` + */ +@Component({ + selector: 'formisch-field-array', + standalone: true, + imports: [NgTemplateOutlet], + template: ` + @if (template()) { + + } + `, +}) +export class FormischFieldArray< + TSchema extends Schema = Schema, + TFieldArrayPath extends RequiredPath = RequiredPath, +> { + readonly of: InputSignal> = input.required>(); + readonly path: InputSignal, TFieldArrayPath>> = input.required, TFieldArrayPath>>(); + + protected readonly template: Signal | undefined> = contentChild(TemplateRef); + protected readonly fieldArray: FieldArrayStore = injectFieldArray(this.of, { path: this.path }); +} diff --git a/frameworks/angular/src/components/FormischFieldArray/index.ts b/frameworks/angular/src/components/FormischFieldArray/index.ts new file mode 100644 index 00000000..b08eb34b --- /dev/null +++ b/frameworks/angular/src/components/FormischFieldArray/index.ts @@ -0,0 +1 @@ +export * from './FormischFieldArray.ts'; diff --git a/frameworks/angular/src/components/FormischForm/FormischForm.test.ts b/frameworks/angular/src/components/FormischForm/FormischForm.test.ts new file mode 100644 index 00000000..06330439 --- /dev/null +++ b/frameworks/angular/src/components/FormischForm/FormischForm.test.ts @@ -0,0 +1,53 @@ +import { Component, provideExperimentalZonelessChangeDetection } from '@angular/core'; +import { TestBed } from '@angular/core/testing'; +import * as v from 'valibot'; +import { describe, beforeEach, expect, it, vi } from 'vitest'; +import { injectForm } from '../../functions/index.ts'; +import { FormischForm } from './FormischForm.ts'; + +const Schema = v.object({ email: v.pipe(v.string(), v.email()) }); + +@Component({ + standalone: true, + imports: [FormischForm], + template: ` + + Submit + + `, +}) +class TestHost { + form = injectForm({ schema: Schema }); + handleSubmit = vi.fn(); +} + +describe('FormischForm', () => { + beforeEach(() => { + TestBed.configureTestingModule({ + imports: [TestHost], + providers: [provideExperimentalZonelessChangeDetection()], + }); + }); + + it('renders a native form element', async () => { + const fixture = TestBed.createComponent(TestHost); + await fixture.whenStable(); + const form = (fixture.nativeElement as HTMLElement).querySelector('form'); + expect(form).not.toBeNull(); + }); + + it('sets novalidate on the form element', async () => { + const fixture = TestBed.createComponent(TestHost); + await fixture.whenStable(); + const form = (fixture.nativeElement as HTMLElement).querySelector('form'); + expect(form.hasAttribute('novalidate')).toBe(true); + }); + + it('registers the form element on the internal store', async () => { + const fixture = TestBed.createComponent(TestHost); + await fixture.whenStable(); + const { INTERNAL } = await import('@formisch/core/angular'); + const internalStore = fixture.componentInstance.form[INTERNAL]; + expect(internalStore.element).toBeInstanceOf(HTMLFormElement); + }); +}); diff --git a/frameworks/angular/src/components/FormischForm/FormischForm.ts b/frameworks/angular/src/components/FormischForm/FormischForm.ts new file mode 100644 index 00000000..7b617383 --- /dev/null +++ b/frameworks/angular/src/components/FormischForm/FormischForm.ts @@ -0,0 +1,53 @@ +import { + afterNextRender, + Component, + ElementRef, + inject, + input, + type InputSignal, +} from '@angular/core'; +import { + INTERNAL, + type Schema, + type SubmitEventHandler, +} from '@formisch/core/angular'; +import { handleSubmit } from '@formisch/methods/angular'; +import type { FormStore } from '../../types/index.ts'; + +/** + * Form component that manages form submission and registers the form element. + * Wraps the native form element and delegates submission to handleSubmit. + * + * @example + * ```html + * + * ... + * + * ``` + */ +@Component({ + selector: 'formisch-form', + standalone: true, + template: ``, +}) +export class FormischForm { + readonly of: InputSignal> = input.required>(); + readonly submitFn: InputSignal> = input.required>(); + + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + private readonly hostEl: ElementRef = inject(ElementRef); + + constructor() { + afterNextRender(() => { + const formElement = + this.hostEl.nativeElement.querySelector('form'); + if (formElement) { + this.of()[INTERNAL].element = formElement; + } + }); + } + + protected handleFormSubmit(event: SubmitEvent): void { + void handleSubmit(this.of(), this.submitFn())(event); + } +} diff --git a/frameworks/angular/src/components/FormischForm/index.ts b/frameworks/angular/src/components/FormischForm/index.ts new file mode 100644 index 00000000..758a4e87 --- /dev/null +++ b/frameworks/angular/src/components/FormischForm/index.ts @@ -0,0 +1 @@ +export * from './FormischForm.ts'; diff --git a/frameworks/angular/src/components/index.ts b/frameworks/angular/src/components/index.ts new file mode 100644 index 00000000..f72ea479 --- /dev/null +++ b/frameworks/angular/src/components/index.ts @@ -0,0 +1,3 @@ +export * from './FormischField/index.ts'; +export * from './FormischFieldArray/index.ts'; +export * from './FormischForm/index.ts'; diff --git a/frameworks/angular/src/functions/index.ts b/frameworks/angular/src/functions/index.ts new file mode 100644 index 00000000..7d1e0f9d --- /dev/null +++ b/frameworks/angular/src/functions/index.ts @@ -0,0 +1,3 @@ +export * from './injectField/index.ts'; +export * from './injectFieldArray/index.ts'; +export * from './injectForm/index.ts'; diff --git a/frameworks/angular/src/functions/injectField/index.ts b/frameworks/angular/src/functions/injectField/index.ts new file mode 100644 index 00000000..84ef33a7 --- /dev/null +++ b/frameworks/angular/src/functions/injectField/index.ts @@ -0,0 +1 @@ +export * from './injectField.ts'; diff --git a/frameworks/angular/src/functions/injectField/injectField.test-d.ts b/frameworks/angular/src/functions/injectField/injectField.test-d.ts new file mode 100644 index 00000000..eb99c358 --- /dev/null +++ b/frameworks/angular/src/functions/injectField/injectField.test-d.ts @@ -0,0 +1,83 @@ +import type { Signal } from '@angular/core'; +import * as v from 'valibot'; +import { describe, expectTypeOf, test } from 'vitest'; +import type { FieldStore } from '../../types/index.ts'; +import { injectForm } from '../injectForm/index.ts'; +import { injectField } from './injectField.ts'; + +describe('injectField', () => { + test('should return a FieldStore typed against the form schema and path', () => { + const schema = v.object({ name: v.string() }); + const form = injectForm({ schema }); + const field = injectField(form, { path: ['name'] }); + + expectTypeOf(field).toEqualTypeOf>(); + }); + + test('should narrow input type for primitive leaves', () => { + const schema = v.object({ name: v.string(), age: v.number() }); + const form = injectForm({ schema }); + + expectTypeOf(injectField(form, { path: ['name'] }).input).toEqualTypeOf< + Signal + >(); + expectTypeOf(injectField(form, { path: ['age'] }).input).toEqualTypeOf< + Signal + >(); + }); + + test('should narrow onInput value type for primitive leaves', () => { + const schema = v.object({ name: v.string() }); + const form = injectForm({ schema }); + + expectTypeOf( + injectField(form, { path: ['name'] }).onInput + ).toEqualTypeOf<(value: string | undefined) => void>(); + }); + + test('should narrow input type through nested object and array index paths', () => { + const schema = v.object({ + user: v.object({ email: v.string() }), + tags: v.array(v.string()), + }); + const form = injectForm({ schema }); + + expectTypeOf( + injectField(form, { path: ['user', 'email'] }).input + ).toEqualTypeOf>(); + expectTypeOf( + injectField(form, { path: ['tags', 0] }).input + ).toEqualTypeOf>(); + }); + + test('should expose Signal boolean state properties', () => { + const schema = v.object({ email: v.pipe(v.string(), v.email()) }); + const form = injectForm({ schema }); + const field = injectField(form, { path: ['email'] }); + + expectTypeOf(field.errors).toEqualTypeOf>(); + expectTypeOf(field.isTouched).toEqualTypeOf>(); + expectTypeOf(field.isDirty).toEqualTypeOf>(); + expectTypeOf(field.isValid).toEqualTypeOf>(); + }); + + test('should expose props with name and autofocus', () => { + const schema = v.object({ email: v.pipe(v.string(), v.email()) }); + const form = injectForm({ schema }); + const field = injectField(form, { path: ['email'] }); + + expectTypeOf(field.props.name).toEqualTypeOf(); + expectTypeOf(field.props.autofocus).toEqualTypeOf(); + }); + + test('should reject invalid paths', () => { + const schema = v.object({ name: v.string() }); + const form = injectForm({ schema }); + + // @ts-expect-error nonexistent field + injectField(form, { path: ['nonexistent'] }); + + // @ts-expect-error path through a string leaf + injectField(form, { path: ['name', 'nested'] }); + }); +}); diff --git a/frameworks/angular/src/functions/injectField/injectField.test.ts b/frameworks/angular/src/functions/injectField/injectField.test.ts new file mode 100644 index 00000000..8a343bb7 --- /dev/null +++ b/frameworks/angular/src/functions/injectField/injectField.test.ts @@ -0,0 +1,67 @@ +import { provideExperimentalZonelessChangeDetection } from '@angular/core'; +import { TestBed } from '@angular/core/testing'; +import * as v from 'valibot'; +import { describe, beforeEach, expect, it } from 'vitest'; +import { injectForm } from '../injectForm/index.ts'; +import { injectField } from './injectField.ts'; + +const Schema = v.object({ + email: v.pipe(v.string(), v.email()), +}); + +describe('injectField', () => { + beforeEach(() => { + TestBed.configureTestingModule({ + providers: [provideExperimentalZonelessChangeDetection()], + }); + }); + + function setup() { + return TestBed.runInInjectionContext(() => { + const form = injectForm({ schema: Schema }); + const field = injectField(form, { path: ['email'] }); + return { form, field }; + }); + } + + it('returns the correct path', () => { + const { field } = setup(); + expect(field.path).toEqual(['email']); + }); + + it('initializes input as a signal with undefined', () => { + const { field } = setup(); + expect(field.input()).toBeUndefined(); + }); + + it('initializes errors to null', () => { + const { field } = setup(); + expect(field.errors()).toBeNull(); + }); + + it('initializes isTouched to false', () => { + const { field } = setup(); + expect(field.isTouched()).toBe(false); + }); + + it('initializes isDirty to false', () => { + const { field } = setup(); + expect(field.isDirty()).toBe(false); + }); + + it('initializes isValid to true', () => { + const { field } = setup(); + expect(field.isValid()).toBe(true); + }); + + it('updates input signal when onInput is called', () => { + const { field } = setup(); + field.onInput('test@example.com'); + expect(field.input()).toBe('test@example.com'); + }); + + it('exposes a name prop as JSON-stringified path', () => { + const { field } = setup(); + expect(field.props.name).toBe('["email"]'); + }); +}); diff --git a/frameworks/angular/src/functions/injectField/injectField.ts b/frameworks/angular/src/functions/injectField/injectField.ts new file mode 100644 index 00000000..a7cd075e --- /dev/null +++ b/frameworks/angular/src/functions/injectField/injectField.ts @@ -0,0 +1,160 @@ +import { + assertInInjectionContext, + computed, + DestroyRef, + inject, + type Signal, +} from '@angular/core'; +import { + type FieldElement, + getElementInput, + getFieldBool, + getFieldInput, + getFieldStore, + INTERNAL, + type RequiredPath, + type Schema, + setFieldBool, + setFieldInput, + validateIfRequired, + type ValidPath, +} from '@formisch/core/angular'; +import type * as v from 'valibot'; +import type { FieldStore, FormStore } from '../../types/index.ts'; + +/** + * Inject field config interface. + */ +export interface InjectFieldConfig< + TSchema extends Schema = Schema, + TFieldPath extends RequiredPath = RequiredPath, +> { + /** + * The path to the field within the form schema. + */ + readonly path: ValidPath, TFieldPath>; +} + +/** + * Inject field config interface for signal-based inputs. + */ +export interface InjectFieldConfigSignal< + TSchema extends Schema = Schema, + TFieldPath extends RequiredPath = RequiredPath, +> { + /** + * A signal that returns the path to the field within the form schema. + */ + readonly path: Signal, TFieldPath>>; +} + +/** + * Creates a reactive field store for a specific field within a form store. + * Exposes all reactive state as Angular Signals callable in templates. + * + * Must be called in an injection context (component constructor or field initializer). + * + * @param form The form store instance. + * @param config The field configuration. + * + * @returns The field store with reactive Signal properties and element props. + */ +export function injectField< + TSchema extends Schema, + TFieldPath extends RequiredPath, +>( + form: FormStore, + config: InjectFieldConfig +): FieldStore; + +/** + * Creates a reactive field store for a specific field within a form store. + * Accepts signal inputs for use inside Angular components. + * + * Must be called in an injection context (component constructor or field initializer). + * + * @param form A signal returning the form store instance. + * @param config The field configuration with a signal path. + * + * @returns The field store with reactive Signal properties and element props. + */ +export function injectField< + TSchema extends Schema, + TFieldPath extends RequiredPath, +>( + form: Signal>, + config: InjectFieldConfigSignal +): FieldStore; + +// @__NO_SIDE_EFFECTS__ +export function injectField( + form: FormStore | Signal, + config: InjectFieldConfig | InjectFieldConfigSignal +): FieldStore { + assertInInjectionContext(injectField); + + const destroyRef = inject(DestroyRef); + const getForm: () => FormStore = + typeof form === 'function' ? form : () => form; + // Path may be a plain value or a signal — normalize to a zero-arg accessor. + const getPath: () => InjectFieldConfig['path'] = + typeof config.path === 'function' + ? config.path + : () => config.path as InjectFieldConfig['path']; + + const internalFormStore = computed(() => getForm()[INTERNAL]); + const internalFieldStore = computed(() => getFieldStore(internalFormStore(), getPath())); + + destroyRef.onDestroy(() => { + internalFieldStore().elements = internalFieldStore().elements.filter( + (element) => element.isConnected + ); + }); + + return { + get path() { + return getPath(); + }, + input: computed(() => getFieldInput(internalFieldStore())), + errors: computed(() => internalFieldStore().errors.value), + isTouched: computed(() => getFieldBool(internalFieldStore(), 'isTouched')), + isDirty: computed(() => getFieldBool(internalFieldStore(), 'isDirty')), + isValid: computed(() => !getFieldBool(internalFieldStore(), 'errors')), + onInput(value) { + setFieldInput(internalFormStore(), getPath(), value); + validateIfRequired(internalFormStore(), internalFieldStore(), 'input'); + }, + props: { + get name() { + return internalFieldStore().name; + }, + get autofocus() { + return !!internalFieldStore().errors.value; + }, + ref(element) { + if (element) { + internalFieldStore().elements.push(element); + } + }, + onFocus() { + setFieldBool(internalFieldStore(), 'isTouched', true); + validateIfRequired(internalFormStore(), internalFieldStore(), 'touch'); + }, + onChange(event) { + setFieldInput( + internalFormStore(), + getPath(), + getElementInput( + event.currentTarget as FieldElement, + internalFieldStore() + ) + ); + validateIfRequired(internalFormStore(), internalFieldStore(), 'input'); + validateIfRequired(internalFormStore(), internalFieldStore(), 'change'); + }, + onBlur() { + validateIfRequired(internalFormStore(), internalFieldStore(), 'blur'); + }, + }, + }; +} diff --git a/frameworks/angular/src/functions/injectFieldArray/index.ts b/frameworks/angular/src/functions/injectFieldArray/index.ts new file mode 100644 index 00000000..be7a9c75 --- /dev/null +++ b/frameworks/angular/src/functions/injectFieldArray/index.ts @@ -0,0 +1 @@ +export * from './injectFieldArray.ts'; diff --git a/frameworks/angular/src/functions/injectFieldArray/injectFieldArray.test-d.ts b/frameworks/angular/src/functions/injectFieldArray/injectFieldArray.test-d.ts new file mode 100644 index 00000000..e40f1f78 --- /dev/null +++ b/frameworks/angular/src/functions/injectFieldArray/injectFieldArray.test-d.ts @@ -0,0 +1,24 @@ +import type { Signal } from '@angular/core'; +import * as v from 'valibot'; +import { describe, expectTypeOf, test } from 'vitest'; +import type { FieldArrayStore } from '../../types/index.ts'; +import { injectForm } from '../injectForm/index.ts'; +import { injectFieldArray } from './injectFieldArray.ts'; + +describe('injectFieldArray', () => { + test('should return a FieldArrayStore typed against the form schema and path', () => { + const schema = v.object({ + todos: v.array(v.object({ title: v.string() })), + }); + const form = injectForm({ schema }); + const fieldArray = injectFieldArray(form, { path: ['todos'] }); + + expectTypeOf(fieldArray).toExtend>(); + expectTypeOf(fieldArray.path).toEqualTypeOf<['todos']>(); + expectTypeOf(fieldArray.items).toEqualTypeOf>(); + expectTypeOf(fieldArray.errors).toEqualTypeOf>(); + expectTypeOf(fieldArray.isTouched).toEqualTypeOf>(); + expectTypeOf(fieldArray.isDirty).toEqualTypeOf>(); + expectTypeOf(fieldArray.isValid).toEqualTypeOf>(); + }); +}); diff --git a/frameworks/angular/src/functions/injectFieldArray/injectFieldArray.test.ts b/frameworks/angular/src/functions/injectFieldArray/injectFieldArray.test.ts new file mode 100644 index 00000000..908ef57c --- /dev/null +++ b/frameworks/angular/src/functions/injectFieldArray/injectFieldArray.test.ts @@ -0,0 +1,58 @@ +import { + provideExperimentalZonelessChangeDetection, +} from '@angular/core'; +import { TestBed } from '@angular/core/testing'; +import * as v from 'valibot'; +import { describe, beforeEach, expect, it } from 'vitest'; +import { injectForm } from '../injectForm/index.ts'; +import { injectFieldArray } from './injectFieldArray.ts'; + +const Schema = v.object({ + todos: v.array(v.object({ title: v.string() })), +}); + +describe('injectFieldArray', () => { + beforeEach(() => { + TestBed.configureTestingModule({ + providers: [provideExperimentalZonelessChangeDetection()], + }); + }); + + function setup() { + return TestBed.runInInjectionContext(() => { + const form = injectForm({ schema: Schema }); + const fieldArray = injectFieldArray(form, { path: ['todos'] }); + return { form, fieldArray }; + }); + } + + it('returns the correct path', () => { + const { fieldArray } = setup(); + expect(fieldArray.path).toEqual(['todos']); + }); + + it('initializes items as an empty signal array', () => { + const { fieldArray } = setup(); + expect(fieldArray.items()).toEqual([]); + }); + + it('initializes errors to null', () => { + const { fieldArray } = setup(); + expect(fieldArray.errors()).toBeNull(); + }); + + it('initializes isTouched to false', () => { + const { fieldArray } = setup(); + expect(fieldArray.isTouched()).toBe(false); + }); + + it('initializes isDirty to false', () => { + const { fieldArray } = setup(); + expect(fieldArray.isDirty()).toBe(false); + }); + + it('initializes isValid to true', () => { + const { fieldArray } = setup(); + expect(fieldArray.isValid()).toBe(true); + }); +}); diff --git a/frameworks/angular/src/functions/injectFieldArray/injectFieldArray.ts b/frameworks/angular/src/functions/injectFieldArray/injectFieldArray.ts new file mode 100644 index 00000000..494632a1 --- /dev/null +++ b/frameworks/angular/src/functions/injectFieldArray/injectFieldArray.ts @@ -0,0 +1,113 @@ +import { + assertInInjectionContext, + computed, + type Signal, +} from '@angular/core'; +import { + getFieldBool, + getFieldStore, + INTERNAL, + type InternalArrayStore, + type RequiredPath, + type Schema, + type ValidArrayPath, +} from '@formisch/core/angular'; +import type * as v from 'valibot'; +import type { FieldArrayStore, FormStore } from '../../types/index.ts'; + +/** + * Inject field array config interface. + */ +export interface InjectFieldArrayConfig< + TSchema extends Schema = Schema, + TFieldArrayPath extends RequiredPath = RequiredPath, +> { + /** + * The path to the field array within the form schema. + */ + readonly path: ValidArrayPath, TFieldArrayPath>; +} + +/** + * Inject field array config interface for signal-based inputs. + */ +export interface InjectFieldArrayConfigSignal< + TSchema extends Schema = Schema, + TFieldArrayPath extends RequiredPath = RequiredPath, +> { + /** + * A signal that returns the path to the field array within the form schema. + */ + readonly path: Signal, TFieldArrayPath>>; +} + +/** + * Creates a reactive field array store for a specific array field within a form store. + * Exposes all reactive state as Angular Signals callable in templates. + * + * Must be called in an injection context (component constructor or field initializer). + * + * @param form The form store instance. + * @param config The field array configuration. + * + * @returns The field array store with reactive Signal properties. + */ +// @ts-expect-error +export function injectFieldArray< + TSchema extends Schema, + TFieldArrayPath extends RequiredPath, +>( + form: FormStore, + config: InjectFieldArrayConfig +): FieldArrayStore; + +/** + * Creates a reactive field array store for a specific array field within a form store. + * Accepts signal inputs for use inside Angular components. + * + * Must be called in an injection context (component constructor or field initializer). + * + * @param form A signal returning the form store instance. + * @param config The field array configuration with a signal path. + * + * @returns The field array store with reactive Signal properties. + */ +export function injectFieldArray< + TSchema extends Schema, + TFieldArrayPath extends RequiredPath, +>( + form: Signal>, + config: InjectFieldArrayConfigSignal +): FieldArrayStore; + +// @__NO_SIDE_EFFECTS__ +export function injectFieldArray( + form: FormStore | Signal, + // eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents + config: InjectFieldArrayConfig | InjectFieldArrayConfigSignal +): FieldArrayStore { + assertInInjectionContext(injectFieldArray); + + const getForm: () => FormStore = + typeof form === 'function' ? form : () => form; + // Path may be a plain value or a signal — normalize to a zero-arg accessor. + const getPath: () => InjectFieldArrayConfig['path'] = + typeof config.path === 'function' + ? config.path + : () => config.path as InjectFieldArrayConfig['path']; + + const internalFieldStore = computed( + () => getFieldStore(getForm()[INTERNAL], getPath()) as InternalArrayStore + ); + + return { + get path() { + return getPath(); + }, + items: computed(() => internalFieldStore().items.value), + errors: computed(() => internalFieldStore().errors.value), + isTouched: computed(() => getFieldBool(internalFieldStore(), 'isTouched')), + isDirty: computed(() => getFieldBool(internalFieldStore(), 'isDirty')), + isValid: computed(() => !getFieldBool(internalFieldStore(), 'errors')), + }; +} diff --git a/frameworks/angular/src/functions/injectForm/index.ts b/frameworks/angular/src/functions/injectForm/index.ts new file mode 100644 index 00000000..7ebb6877 --- /dev/null +++ b/frameworks/angular/src/functions/injectForm/index.ts @@ -0,0 +1 @@ +export * from './injectForm.ts'; diff --git a/frameworks/angular/src/functions/injectForm/injectForm.test-d.ts b/frameworks/angular/src/functions/injectForm/injectForm.test-d.ts new file mode 100644 index 00000000..da3edbf7 --- /dev/null +++ b/frameworks/angular/src/functions/injectForm/injectForm.test-d.ts @@ -0,0 +1,34 @@ +import type { Signal } from '@angular/core'; +import * as v from 'valibot'; +import { describe, expectTypeOf, test } from 'vitest'; +import type { FormStore } from '../../types/index.ts'; +import { injectForm } from './injectForm.ts'; + +describe('injectForm', () => { + test('should return a FormStore typed against the schema', () => { + const schema = v.object({ + email: v.pipe(v.string(), v.email()), + password: v.pipe(v.string(), v.minLength(8)), + }); + const form = injectForm({ schema }); + + expectTypeOf(form).toExtend>(); + expectTypeOf(form.isSubmitting).toEqualTypeOf>(); + expectTypeOf(form.isSubmitted).toEqualTypeOf>(); + expectTypeOf(form.isValidating).toEqualTypeOf>(); + expectTypeOf(form.isTouched).toEqualTypeOf>(); + expectTypeOf(form.isDirty).toEqualTypeOf>(); + expectTypeOf(form.isValid).toEqualTypeOf>(); + expectTypeOf(form.errors).toEqualTypeOf>(); + }); + + test('should accept full, partial, and reject mistyped initialInput', () => { + const schema = v.object({ name: v.string(), age: v.number() }); + + injectForm({ schema, initialInput: { name: 'John', age: 30 } }); + injectForm({ schema, initialInput: { name: 'John' } }); + + // @ts-expect-error wrong leaf type + injectForm({ schema, initialInput: { name: 123 } }); + }); +}); diff --git a/frameworks/angular/src/functions/injectForm/injectForm.test.ts b/frameworks/angular/src/functions/injectForm/injectForm.test.ts new file mode 100644 index 00000000..8b777598 --- /dev/null +++ b/frameworks/angular/src/functions/injectForm/injectForm.test.ts @@ -0,0 +1,58 @@ +import { provideExperimentalZonelessChangeDetection } from '@angular/core'; +import { TestBed } from '@angular/core/testing'; +import * as v from 'valibot'; +import { describe, beforeEach, expect, it } from 'vitest'; +import { injectForm } from './injectForm.ts'; + +const Schema = v.object({ + email: v.pipe(v.string(), v.email()), +}); + +describe('injectForm', () => { + beforeEach(() => { + TestBed.configureTestingModule({ + providers: [provideExperimentalZonelessChangeDetection()], + }); + }); + + function setup() { + return TestBed.runInInjectionContext(() => + injectForm({ schema: Schema }) + ); + } + + it('initializes isSubmitting to false', () => { + const form = setup(); + expect(form.isSubmitting()).toBe(false); + }); + + it('initializes isSubmitted to false', () => { + const form = setup(); + expect(form.isSubmitted()).toBe(false); + }); + + it('initializes isValidating to false', () => { + const form = setup(); + expect(form.isValidating()).toBe(false); + }); + + it('initializes isTouched to false', () => { + const form = setup(); + expect(form.isTouched()).toBe(false); + }); + + it('initializes isDirty to false', () => { + const form = setup(); + expect(form.isDirty()).toBe(false); + }); + + it('initializes isValid to true when no validation errors', () => { + const form = setup(); + expect(form.isValid()).toBe(true); + }); + + it('initializes errors to null', () => { + const form = setup(); + expect(form.errors()).toBeNull(); + }); +}); diff --git a/frameworks/angular/src/functions/injectForm/injectForm.ts b/frameworks/angular/src/functions/injectForm/injectForm.ts new file mode 100644 index 00000000..5801b6d3 --- /dev/null +++ b/frameworks/angular/src/functions/injectForm/injectForm.ts @@ -0,0 +1,55 @@ +import { + afterNextRender, + assertInInjectionContext, + computed, +} from '@angular/core'; +import { + createFormStore, + type FormConfig, + getFieldBool, + INTERNAL, + type Schema, + validateFormInput, +} from '@formisch/core/angular'; +import * as v from 'valibot'; +import type { FormStore } from '../../types/index.ts'; + +/** + * Creates a reactive form store from a form configuration. The form store + * manages form state and provides reactive Signal properties callable in templates. + * + * Must be called in an injection context (component constructor or field initializer). + * + * @param config The form configuration. + * + * @returns The form store with reactive Signal properties. + */ +export function injectForm( + config: FormConfig +): FormStore; + +// @__NO_SIDE_EFFECTS__ +export function injectForm(config: FormConfig): FormStore { + assertInInjectionContext(injectForm); + + const internalFormStore = createFormStore(config, (input: unknown) => + v.safeParseAsync(config.schema, input) + ); + + if (config.validate === 'initial') { + afterNextRender(() => { + void validateFormInput(internalFormStore); + }); + } + + return { + [INTERNAL]: internalFormStore, + isSubmitting: computed(() => internalFormStore.isSubmitting.value), + isSubmitted: computed(() => internalFormStore.isSubmitted.value), + isValidating: computed(() => internalFormStore.isValidating.value), + isTouched: computed(() => getFieldBool(internalFormStore, 'isTouched')), + isDirty: computed(() => getFieldBool(internalFormStore, 'isDirty')), + isValid: computed(() => !getFieldBool(internalFormStore, 'errors')), + errors: computed(() => internalFormStore.errors.value), + }; +} diff --git a/frameworks/angular/src/index.ts b/frameworks/angular/src/index.ts new file mode 100644 index 00000000..d67a363c --- /dev/null +++ b/frameworks/angular/src/index.ts @@ -0,0 +1,18 @@ +export type { + DeepPartial, + FieldElement, + FormConfig, + PartialValues, + PathValue, + RequiredPath, + Schema, + SubmitEventHandler, + SubmitHandler, + ValidArrayPath, + ValidationMode, + ValidPath, +} from '@formisch/core/angular'; +export * from '@formisch/methods/angular'; +export * from './components/index.ts'; +export * from './functions/index.ts'; +export * from './types/index.ts'; diff --git a/frameworks/angular/src/types/field.ts b/frameworks/angular/src/types/field.ts new file mode 100644 index 00000000..7bbe1cef --- /dev/null +++ b/frameworks/angular/src/types/field.ts @@ -0,0 +1,119 @@ +import type { Signal } from '@angular/core'; +import type { + FieldElement, + PartialValues, + PathValue, + RequiredPath, + Schema, + ValidArrayPath, + ValidPath, +} from '@formisch/core/angular'; +import type * as v from 'valibot'; + +/** + * Field element props interface. + */ +export interface FieldElementProps { + /** + * The name attribute of the field element. + */ + readonly name: string; + /** + * Whether to autofocus the field element when there are errors. + */ + readonly autofocus: boolean; + /** + * The ref callback to register the field element. + */ + readonly ref: (element: FieldElement | null) => void; + /** + * The focus event handler of the field element. + */ + readonly onFocus: (event: FocusEvent) => void; + /** + * The change event handler of the field element. + */ + readonly onChange: (event: Event) => void; + /** + * The blur event handler of the field element. + */ + readonly onBlur: (event: FocusEvent) => void; +} + +/** + * Field store interface. + */ +export interface FieldStore< + TSchema extends Schema = Schema, + TFieldPath extends RequiredPath = RequiredPath, +> { + /** + * The path to the field within the form. + */ + readonly path: ValidPath, TFieldPath>; + /** + * The current input value of the field as a reactive signal. + */ + readonly input: Signal< + PartialValues, TFieldPath>> + >; + /** + * The current error messages of the field. + */ + readonly errors: Signal<[string, ...string[]] | null>; + /** + * Whether the field has been touched. + */ + readonly isTouched: Signal; + /** + * Whether the field input differs from its initial value. + */ + readonly isDirty: Signal; + /** + * Whether the field is valid according to the schema. + */ + readonly isValid: Signal; + /** + * Sets the field input value programmatically. + */ + readonly onInput: ( + value: PartialValues, TFieldPath>> + ) => void; + /** + * The props to spread onto the field element for integration. + */ + readonly props: FieldElementProps; +} + +/** + * Field array store interface. + */ +export interface FieldArrayStore< + TSchema extends Schema = Schema, + TFieldArrayPath extends RequiredPath = RequiredPath, +> { + /** + * The path to the array field within the form. + */ + readonly path: ValidArrayPath, TFieldArrayPath>; + /** + * The item IDs of the array field. + */ + readonly items: Signal; + /** + * The current error messages of the field array. + */ + readonly errors: Signal<[string, ...string[]] | null>; + /** + * Whether the field array has been touched. + */ + readonly isTouched: Signal; + /** + * Whether the field array input differs from its initial value. + */ + readonly isDirty: Signal; + /** + * Whether the field array is valid according to the schema. + */ + readonly isValid: Signal; +} diff --git a/frameworks/angular/src/types/form.ts b/frameworks/angular/src/types/form.ts new file mode 100644 index 00000000..bcf6e7c5 --- /dev/null +++ b/frameworks/angular/src/types/form.ts @@ -0,0 +1,40 @@ +import type { Signal } from '@angular/core'; +import type { BaseFormStore, Schema } from '@formisch/core/angular'; + +/** + * Form store interface. + */ +export interface FormStore + extends BaseFormStore { + /** + * Whether the form is currently submitting. + */ + readonly isSubmitting: Signal; + /** + * Whether the form has been submitted. + */ + readonly isSubmitted: Signal; + /** + * Whether the form is currently validating. + */ + readonly isValidating: Signal; + /** + * Whether any field in the form has been touched. + */ + readonly isTouched: Signal; + /** + * Whether any field in the form differs from its initial value. + */ + readonly isDirty: Signal; + /** + * Whether the form is valid according to the schema. + */ + readonly isValid: Signal; + /** + * The current error messages of the form. + * + * Hint: This property only contains validation errors at the root level + * of the form. To get all errors from all fields, use `getAllErrors`. + */ + readonly errors: Signal<[string, ...string[]] | null>; +} diff --git a/frameworks/angular/src/types/index.ts b/frameworks/angular/src/types/index.ts new file mode 100644 index 00000000..f0cc7379 --- /dev/null +++ b/frameworks/angular/src/types/index.ts @@ -0,0 +1,2 @@ +export * from './field.ts'; +export * from './form.ts'; diff --git a/frameworks/angular/src/vitest/setup.ts b/frameworks/angular/src/vitest/setup.ts new file mode 100644 index 00000000..4138a686 --- /dev/null +++ b/frameworks/angular/src/vitest/setup.ts @@ -0,0 +1,14 @@ +import { TestBed } from '@angular/core/testing'; +import { + BrowserTestingModule, + platformBrowserTesting, +} from '@angular/platform-browser/testing'; +import { afterEach, beforeAll } from 'vitest'; + +beforeAll(() => { + TestBed.initTestEnvironment(BrowserTestingModule, platformBrowserTesting()); +}); + +afterEach(() => { + TestBed.resetTestingModule(); +}); diff --git a/frameworks/angular/tsconfig.json b/frameworks/angular/tsconfig.json new file mode 100644 index 00000000..d430093f --- /dev/null +++ b/frameworks/angular/tsconfig.json @@ -0,0 +1,18 @@ +{ + "compilerOptions": { + "allowImportingTsExtensions": true, + "declaration": true, + "experimentalDecorators": true, + "isolatedDeclarations": true, + "exactOptionalPropertyTypes": true, + "lib": ["ES2020", "DOM"], + "module": "ES2020", + "moduleResolution": "Bundler", + "noEmit": true, + "skipLibCheck": true, + "strict": true, + "target": "ES2020", + "types": ["node"] + }, + "include": ["src"] +} diff --git a/frameworks/angular/tsdown.config.ts b/frameworks/angular/tsdown.config.ts new file mode 100644 index 00000000..0d0c7a17 --- /dev/null +++ b/frameworks/angular/tsdown.config.ts @@ -0,0 +1,13 @@ +import { defineConfig } from 'tsdown'; + +export default defineConfig({ + entry: ['./src/index.ts'], + outDir: 'dist', + outExtensions: () => ({ + js: '.js', + dts: '.d.ts', + }), + dts: { + resolve: ['@formisch/core/angular', '@formisch/methods/angular'], + }, +}); diff --git a/frameworks/angular/vitest.config.ts b/frameworks/angular/vitest.config.ts new file mode 100644 index 00000000..e5457132 --- /dev/null +++ b/frameworks/angular/vitest.config.ts @@ -0,0 +1,18 @@ +import { defineConfig } from 'vitest/config'; + +export default defineConfig({ + test: { + environment: 'jsdom', + setupFiles: ['./src/vitest/setup.ts'], + coverage: { + include: ['src'], + exclude: [ + 'src/types', + 'src/vitest', + '**/index.ts', + '**/*.test.ts', + '**/*.test-d.ts', + ], + }, + }, +}); diff --git a/packages/methods/package.json b/packages/methods/package.json index 12bd3e9a..6cf16c18 100644 --- a/packages/methods/package.json +++ b/packages/methods/package.json @@ -20,6 +20,10 @@ ], "type": "module", "exports": { + "./angular": { + "types": "./dist/index.angular.d.ts", + "default": "./dist/index.angular.js" + }, "./preact": { "types": "./dist/index.preact.d.ts", "default": "./dist/index.preact.js" @@ -62,6 +66,7 @@ "build": "tsdown" }, "devDependencies": { + "@angular/core": "^21.0.0", "@formisch/core": "workspace:*", "@formisch/eslint-config": "workspace:*", "@types/node": "24.0.13", @@ -77,11 +82,15 @@ "vitest": "3.2.4" }, "peerDependencies": { + "@angular/core": ">=17.0.0", "react": "^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "typescript": ">=5", "valibot": "^1.4.1" }, "peerDependenciesMeta": { + "@angular/core": { + "optional": true + }, "react": { "optional": true }, diff --git a/packages/methods/tsdown.config.ts b/packages/methods/tsdown.config.ts index 864907a3..0367792d 100644 --- a/packages/methods/tsdown.config.ts +++ b/packages/methods/tsdown.config.ts @@ -4,7 +4,7 @@ import { join } from 'node:path'; import type { RolldownPluginOption } from 'rolldown'; import { defineConfig, type UserConfig, type UserConfigFn } from 'tsdown'; -type Framework = 'preact' | 'qwik' | 'react' | 'solid' | 'svelte' | 'vue'; +type Framework = 'angular' | 'preact' | 'qwik' | 'react' | 'solid' | 'svelte' | 'vue'; /** * Rolldown plugin to rewrite framework-specific imports. @@ -89,6 +89,7 @@ function defineFrameworkConfig( return defineConfig({ entry: ['./src/index.ts'], external: [ + '@angular/core', '@formisch/core', `@formisch/core/${framework}`, '@preact/signals', @@ -113,6 +114,7 @@ function defineFrameworkConfig( } const config: (UserConfig | UserConfigFn)[] = [ + defineFrameworkConfig('angular'), defineFrameworkConfig('preact'), defineFrameworkConfig('qwik'), defineFrameworkConfig('react'), diff --git a/playgrounds/angular/index.html b/playgrounds/angular/index.html new file mode 100644 index 00000000..ffa18a1e --- /dev/null +++ b/playgrounds/angular/index.html @@ -0,0 +1,17 @@ + + + + + + + Angular Playground | Formisch + + + + + + diff --git a/playgrounds/angular/package.json b/playgrounds/angular/package.json new file mode 100644 index 00000000..c904e9cf --- /dev/null +++ b/playgrounds/angular/package.json @@ -0,0 +1,32 @@ +{ + "name": "formisch-playground-angular", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "tsc -b && vite build", + "preview": "vite preview" + }, + "dependencies": { + "@angular/common": "^19.0.0", + "@angular/compiler": "^19.0.0", + "@angular/core": "^19.0.0", + "@angular/platform-browser": "^19.0.0", + "@angular/router": "^19.0.0", + "@formisch/angular": "workspace:*", + "@tailwindcss/vite": "^4.1.17", + "clsx": "^2.1.1", + "valibot": "^1.2.0", + "@formkit/auto-animate": "^0.8.4" + }, + "devDependencies": { + "@analogjs/vite-plugin-angular": "^1.10.0", + "@angular/build": "^19.0.0", + "@angular/compiler-cli": "^19.0.0", + "@types/node": "^24.10.1", + "tailwindcss": "^4.1.17", + "typescript": "~5.8.3", + "vite": "^7.2.4" + } +} diff --git a/playgrounds/angular/src/app.component.ts b/playgrounds/angular/src/app.component.ts new file mode 100644 index 00000000..99c83c5a --- /dev/null +++ b/playgrounds/angular/src/app.component.ts @@ -0,0 +1,114 @@ +import { + Component, + ElementRef, + HostListener, + inject, + signal, + viewChild, +} from '@angular/core'; +import { + NavigationEnd, + Router, + RouterLink, + RouterLinkActive, + RouterOutlet, +} from '@angular/router'; +import { filter } from 'rxjs/operators'; +import { disableTransitions } from './utils/disable-transitions.ts'; + +interface IndicatorStyle { + left: string; + width: string; +} + +/** + * Root application component with tab navigation and sliding indicator. + */ +@Component({ + selector: 'app-root', + standalone: true, + imports: [RouterOutlet, RouterLink, RouterLinkActive], + template: ` + + + + @for (tab of tabs; track tab.path) { + {{ tab.label }} + } + + @if (indicatorStyle()) { + + } + + + + + + `, +}) +export class AppComponent { + readonly tabs = [ + { path: '/login', label: 'Login' }, + { path: '/payment', label: 'Payment' }, + { path: '/todos', label: 'Todos' }, + { path: '/special', label: 'Special' }, + { path: '/nested', label: 'Nested' }, + ]; + + private readonly navEl = + viewChild>('navEl'); + protected readonly indicatorStyle = signal( + undefined + ); + + constructor() { + const router = inject(Router); + router.events + .pipe(filter((e) => e instanceof NavigationEnd)) + .subscribe(() => setTimeout(() => this.updateIndicatorStyle())); + } + + @HostListener('window:resize') + onResize(): void { + disableTransitions(); + this.updateIndicatorStyle(); + } + + private updateIndicatorStyle(): void { + const nav = this.navEl()?.nativeElement; + if (!nav) return; + const activeEl = [...nav.children].find( + (el) => (el as HTMLAnchorElement).href?.endsWith(location.pathname) + ) as HTMLAnchorElement | undefined; + this.indicatorStyle.set( + activeEl + ? { + left: `${activeEl.offsetLeft}px`, + width: `${activeEl.offsetWidth}px`, + } + : undefined + ); + } + + protected scrollIntoView(event: MouseEvent): void { + (event.currentTarget as HTMLElement).scrollIntoView({ + block: 'nearest', + inline: 'center', + }); + } +} diff --git a/playgrounds/angular/src/app.config.ts b/playgrounds/angular/src/app.config.ts new file mode 100644 index 00000000..296f5d4f --- /dev/null +++ b/playgrounds/angular/src/app.config.ts @@ -0,0 +1,10 @@ +import { provideExperimentalZonelessChangeDetection, type ApplicationConfig } from '@angular/core'; +import { provideRouter } from '@angular/router'; +import { routes } from './app.routes.ts'; + +export const appConfig: ApplicationConfig = { + providers: [ + provideExperimentalZonelessChangeDetection(), + provideRouter(routes), + ], +}; diff --git a/playgrounds/angular/src/app.routes.ts b/playgrounds/angular/src/app.routes.ts new file mode 100644 index 00000000..2f6223dc --- /dev/null +++ b/playgrounds/angular/src/app.routes.ts @@ -0,0 +1,40 @@ +import type { Routes } from '@angular/router'; + +export const routes: Routes = [ + { path: '', redirectTo: 'login', pathMatch: 'full' }, + { + path: 'login', + loadComponent: () => + import('./routes/login/login.component.ts').then( + (m) => m.LoginComponent + ), + }, + { + path: 'payment', + loadComponent: () => + import('./routes/payment/payment.component.ts').then( + (m) => m.PaymentComponent + ), + }, + { + path: 'todos', + loadComponent: () => + import('./routes/todos/todos.component.ts').then( + (m) => m.TodosComponent + ), + }, + { + path: 'special', + loadComponent: () => + import('./routes/special/special.component.ts').then( + (m) => m.SpecialComponent + ), + }, + { + path: 'nested', + loadComponent: () => + import('./routes/nested/nested.component.ts').then( + (m) => m.NestedComponent + ), + }, +]; diff --git a/playgrounds/angular/src/components/action-button.component.ts b/playgrounds/angular/src/components/action-button.component.ts new file mode 100644 index 00000000..479353da --- /dev/null +++ b/playgrounds/angular/src/components/action-button.component.ts @@ -0,0 +1,40 @@ +import { Component, input, output } from '@angular/core'; +import clsx from 'clsx'; +import { UnstyledButtonComponent } from './unstyled-button.component.ts'; + +/** + * Button used for navigation, to confirm form entries, or perform actions. + */ +@Component({ + selector: 'app-action-button', + standalone: true, + imports: [UnstyledButtonComponent], + template: ` + + {{ label() }} + + `, +}) +export class ActionButtonComponent { + readonly type = input<'button' | 'submit' | 'reset'>('button'); + readonly variant = input.required<'primary' | 'secondary'>(); + readonly label = input.required(); + readonly loading = input(false); + readonly onClick = input<(() => unknown) | undefined>(undefined); + readonly clicked = output(); + + protected readonly classes = () => + clsx( + 'relative flex cursor-pointer items-center justify-center rounded-2xl px-5 py-2.5 font-medium no-underline transition-colors md:text-lg lg:rounded-2xl lg:px-6 lg:py-3 lg:text-xl', + this.variant() === 'primary' && + 'bg-sky-600 text-white hover:bg-sky-600/80 dark:bg-sky-400 dark:text-gray-900 dark:hover:bg-sky-400/80', + this.variant() === 'secondary' && + 'bg-sky-600/10 text-sky-600 hover:bg-sky-600/20 dark:bg-sky-400/10 dark:text-sky-400 dark:hover:bg-sky-400/20' + ); +} diff --git a/playgrounds/angular/src/components/auto-animate.directive.ts b/playgrounds/angular/src/components/auto-animate.directive.ts new file mode 100644 index 00000000..ba54d150 --- /dev/null +++ b/playgrounds/angular/src/components/auto-animate.directive.ts @@ -0,0 +1,20 @@ +import { afterNextRender, Directive, ElementRef, inject, input } from '@angular/core'; +import autoAnimate, { type AutoAnimateOptions } from '@formkit/auto-animate'; + +/** + * Directive that enables auto-animate on the host element. + */ +@Directive({ + selector: '[auto-animate]', + standalone: true, +}) +export class AutoAnimateDirective { + readonly options = input>(); + + constructor() { + const el = inject>(ElementRef); + afterNextRender(() => { + autoAnimate(el.nativeElement, this.options() ?? {}); + }); + } +} diff --git a/playgrounds/angular/src/components/button-group.component.ts b/playgrounds/angular/src/components/button-group.component.ts new file mode 100644 index 00000000..56a27917 --- /dev/null +++ b/playgrounds/angular/src/components/button-group.component.ts @@ -0,0 +1,21 @@ +import { Component, input } from '@angular/core'; +import clsx from 'clsx'; + +/** + * Button group displays multiple related actions side-by-side. + */ +@Component({ + selector: 'app-button-group', + standalone: true, + template: ` + + + + `, +}) +export class ButtonGroupComponent { + readonly class = input(''); + + protected readonly classes = () => + clsx('flex flex-wrap gap-6 px-8 lg:gap-8 lg:px-10', this.class()); +} diff --git a/playgrounds/angular/src/components/checkbox.component.ts b/playgrounds/angular/src/components/checkbox.component.ts new file mode 100644 index 00000000..b5b3cd92 --- /dev/null +++ b/playgrounds/angular/src/components/checkbox.component.ts @@ -0,0 +1,54 @@ +import { Component, input, output } from '@angular/core'; +import clsx from 'clsx'; +import { InputErrorsComponent } from './input-errors.component.ts'; + +/** + * Checkbox that allows users to select an option. The label next to the + * checkbox describes the selection option. + */ +@Component({ + selector: 'app-checkbox', + standalone: true, + imports: [InputErrorsComponent], + template: ` + + + + {{ label() }} + @if (required()) { + * + } + + + + `, +}) +export class CheckboxComponent { + readonly name = input.required(); + readonly label = input(''); + readonly value = input(); + readonly input = input(); + readonly required = input(false); + readonly errors = input<[string, ...string[]] | null>(null); + readonly class = input(''); + + readonly fieldFocus = output(); + readonly fieldChange = output(); + readonly fieldBlur = output(); + + protected readonly containerClasses = () => + clsx('px-8 lg:px-10', this.class()); +} diff --git a/playgrounds/angular/src/components/color-button.component.ts b/playgrounds/angular/src/components/color-button.component.ts new file mode 100644 index 00000000..751d5fbc --- /dev/null +++ b/playgrounds/angular/src/components/color-button.component.ts @@ -0,0 +1,40 @@ +import { Component, input, output } from '@angular/core'; +import clsx from 'clsx'; + +type Color = 'green' | 'yellow' | 'purple' | 'blue' | 'red'; + +/** + * Button with a specified color used for demo purposes in the playground. + */ +@Component({ + selector: 'app-color-button', + standalone: true, + template: ` + + {{ label() }} + + `, +}) +export class ColorButtonComponent { + readonly type = input<'button' | 'submit'>('button'); + readonly color = input.required(); + readonly label = input.required(); + readonly width = input<'auto' | undefined>(undefined); + readonly clicked = output(); + + protected readonly classes = () => + clsx( + 'h-14 rounded-2xl border-2 bg-white px-5 font-medium md:h-16 md:text-lg lg:h-[70px] lg:px-6 lg:text-xl dark:bg-gray-900', + this.color() === 'green' && + 'border-emerald-600/20 text-emerald-600 hover:bg-emerald-600/10 dark:border-emerald-400/20 dark:text-emerald-400 dark:hover:bg-emerald-400/10', + this.color() === 'yellow' && + 'border-yellow-600/20 text-yellow-600 hover:bg-yellow-600/10 dark:border-amber-300/20 dark:text-amber-300 dark:hover:bg-amber-300/10', + this.color() === 'purple' && + 'border-purple-600/20 text-purple-600 hover:bg-purple-600/10 dark:border-purple-400/20 dark:text-purple-400 dark:hover:bg-purple-400/10', + this.color() === 'blue' && + 'border-sky-600/20 text-sky-600 hover:bg-sky-600/10 dark:border-sky-400/20 dark:text-sky-400 dark:hover:bg-sky-400/10', + this.color() === 'red' && + 'border-red-600/20 text-red-600 hover:bg-red-600/10 dark:border-red-400/20 dark:text-red-400 dark:hover:bg-red-400/10', + this.width() !== 'auto' && 'w-full md:w-auto' + ); +} diff --git a/playgrounds/angular/src/components/expandable.component.ts b/playgrounds/angular/src/components/expandable.component.ts new file mode 100644 index 00000000..a64a9b95 --- /dev/null +++ b/playgrounds/angular/src/components/expandable.component.ts @@ -0,0 +1,56 @@ +import { + afterRenderEffect, + Component, + computed, + ElementRef, + HostListener, + input, + viewChild, +} from '@angular/core'; +import clsx from 'clsx'; + +/** + * Wrapper component to vertically expand or collapse content. + */ +@Component({ + selector: 'app-expandable', + standalone: true, + template: ` + + + + `, +}) +export class ExpandableComponent { + readonly expanded = input.required(); + + private readonly el = viewChild>('el'); + + protected readonly classes = computed(() => + clsx( + 'm-0! h-0 origin-top overflow-hidden duration-200', + !this.expanded() && 'invisible -translate-y-2 scale-y-75 opacity-0' + ) + ); + + constructor() { + afterRenderEffect(() => { + this.updateHeight(this.expanded()); + }); + } + + @HostListener('window:resize') + onResize(): void { + this.updateHeight(this.expanded()); + } + + private updateHeight(expanded: boolean): void { + const el = this.el()?.nativeElement; + if (!el) return; + el.style.height = expanded ? `${el.scrollHeight}px` : '0'; + } +} diff --git a/playgrounds/angular/src/components/file-input.component.ts b/playgrounds/angular/src/components/file-input.component.ts new file mode 100644 index 00000000..4c9168b2 --- /dev/null +++ b/playgrounds/angular/src/components/file-input.component.ts @@ -0,0 +1,77 @@ +import { Component, computed, input, output } from '@angular/core'; +import clsx from 'clsx'; +import { InputLabelComponent } from './input-label.component.ts'; +import { InputErrorsComponent } from './input-errors.component.ts'; + +/** + * File input field that users can click or drag files into. Various + * decorations can be displayed in or around the field to communicate the entry + * requirements. + */ +@Component({ + selector: 'app-file-input', + standalone: true, + imports: [InputLabelComponent, InputErrorsComponent], + template: ` + + + + {{ displayText() }} + + + + + `, +}) +export class FileInputComponent { + readonly name = input.required(); + readonly label = input(); + readonly accept = input(); + readonly multiple = input(false); + readonly required = input(false); + readonly input = input(); + readonly errors = input<[string, ...string[]] | null>(null); + readonly class = input(''); + + readonly fieldFocus = output(); + readonly fieldChange = output(); + readonly fieldBlur = output(); + + protected readonly files = computed(() => { + const val = this.input(); + if (!val) return []; + return Array.isArray(val) ? val : [val]; + }); + + protected readonly displayText = computed(() => { + const files = this.files(); + if (files.length) { + return `Selected file${this.multiple() ? 's' : ''}: ${files.map((f) => f.name).join(', ')}`; + } + return `Click or drag and drop file${this.multiple() ? 's' : ''}`; + }); + + protected readonly containerClasses = () => + clsx('px-8 lg:px-10', this.class()); + + protected readonly labelClasses = computed(() => + clsx( + 'relative flex min-h-24 w-full items-center justify-center rounded-2xl border-[3px] border-dashed border-slate-200 p-8 text-center focus-within:border-sky-600/50 hover:border-slate-300 md:min-h-28 md:text-lg lg:min-h-32 lg:p-10 lg:text-xl dark:border-slate-800 dark:focus-within:border-sky-400/50 dark:hover:border-slate-700', + !this.files().length && 'text-slate-500' + ) + ); +} diff --git a/playgrounds/angular/src/components/form-error.component.ts b/playgrounds/angular/src/components/form-error.component.ts new file mode 100644 index 00000000..b0f9f759 --- /dev/null +++ b/playgrounds/angular/src/components/form-error.component.ts @@ -0,0 +1,31 @@ +import { Component, input } from '@angular/core'; +import clsx from 'clsx'; +import { type FormStore } from '@formisch/angular'; +import { ExpandableComponent } from './expandable.component.ts'; + +/** + * Error component usually used at the end of a form to provide feedback to the + * user. + */ +@Component({ + selector: 'app-form-error', + standalone: true, + imports: [ExpandableComponent], + template: ` + + + {{ of().errors()?.[0] }} + + + `, +}) +export class FormErrorComponent { + readonly of = input.required(); + readonly class = input(''); + + protected readonly classes = () => + clsx( + 'px-8 text-red-500 md:text-lg lg:px-10 lg:text-xl dark:text-red-400', + this.class() + ); +} diff --git a/playgrounds/angular/src/components/form-footer.component.ts b/playgrounds/angular/src/components/form-footer.component.ts new file mode 100644 index 00000000..3aeaf04d --- /dev/null +++ b/playgrounds/angular/src/components/form-footer.component.ts @@ -0,0 +1,30 @@ +import { Component, input } from '@angular/core'; +import { reset, type FormStore } from '@formisch/angular'; +import { ActionButtonComponent } from './action-button.component.ts'; + +/** + * Form footer with buttons to reset and submit the form. + */ +@Component({ + selector: 'app-form-footer', + standalone: true, + imports: [ActionButtonComponent], + template: ` + + `, +}) +export class FormFooterComponent { + readonly of = input.required(); + + protected handleReset(): void { + reset(this.of()); + } +} diff --git a/playgrounds/angular/src/components/form-header.component.ts b/playgrounds/angular/src/components/form-header.component.ts new file mode 100644 index 00000000..283a9777 --- /dev/null +++ b/playgrounds/angular/src/components/form-header.component.ts @@ -0,0 +1,36 @@ +import { Component, input } from '@angular/core'; +import { reset, type FormStore } from '@formisch/angular'; +import { ActionButtonComponent } from './action-button.component.ts'; + +/** + * Form header with heading and buttons to reset and submit the form. + */ +@Component({ + selector: 'app-form-header', + standalone: true, + imports: [ActionButtonComponent], + template: ` + + + {{ heading() }} + + + + + + + `, +}) +export class FormHeaderComponent { + readonly of = input.required(); + readonly heading = input.required(); + + protected handleReset(): void { + reset(this.of()); + } +} diff --git a/playgrounds/angular/src/components/input-errors.component.ts b/playgrounds/angular/src/components/input-errors.component.ts new file mode 100644 index 00000000..66beb91a --- /dev/null +++ b/playgrounds/angular/src/components/input-errors.component.ts @@ -0,0 +1,25 @@ +import { Component, input } from '@angular/core'; +import { ExpandableComponent } from './expandable.component.ts'; + +/** + * Input error that tells the user what to do to fix the problem. + */ +@Component({ + selector: 'app-input-errors', + standalone: true, + imports: [ExpandableComponent], + template: ` + + + {{ errors()?.[0] }} + + + `, +}) +export class InputErrorsComponent { + readonly name = input.required(); + readonly errors = input<[string, ...string[]] | null>(null); +} diff --git a/playgrounds/angular/src/components/input-label.component.ts b/playgrounds/angular/src/components/input-label.component.ts new file mode 100644 index 00000000..e3b0ac54 --- /dev/null +++ b/playgrounds/angular/src/components/input-label.component.ts @@ -0,0 +1,50 @@ +import { Component, input } from '@angular/core'; +import clsx from 'clsx'; + +/** + * Input label for a form field. + */ +@Component({ + selector: 'app-input-label', + standalone: true, + template: ` + @if (label()) { + @let labelClass = labelClasses(); + @if (component() === 'legend') { + + {{ label() }} + @if (required()) { + * + } + + } @else if (name()) { + + {{ label() }} + @if (required()) { + * + } + + } @else { + + {{ label() }} + @if (required()) { + * + } + + } + } + `, +}) +export class InputLabelComponent { + readonly component = input<'label' | 'legend' | 'div'>(); + readonly name = input(); + readonly label = input(); + readonly required = input(false); + readonly margin = input<'none'>(); + + protected readonly labelClasses = () => + clsx( + 'inline-block font-medium md:text-lg lg:text-xl', + this.margin() !== 'none' && 'mb-4 lg:mb-5' + ); +} diff --git a/playgrounds/angular/src/components/radio-group.component.ts b/playgrounds/angular/src/components/radio-group.component.ts new file mode 100644 index 00000000..16e93c79 --- /dev/null +++ b/playgrounds/angular/src/components/radio-group.component.ts @@ -0,0 +1,59 @@ +import { Component, input, output } from '@angular/core'; +import clsx from 'clsx'; +import { InputLabelComponent } from './input-label.component.ts'; +import { InputErrorsComponent } from './input-errors.component.ts'; +import { RadioComponent } from './radio.component.ts'; + +interface RadioOption { + label: string; + value: string; +} + +/** + * Radio group that allows users to select a single option from a list. + * Uses fieldset and legend for proper HTML semantics and accessibility. + */ +@Component({ + selector: 'app-radio-group', + standalone: true, + imports: [InputLabelComponent, InputErrorsComponent, RadioComponent], + template: ` + + + + @for (option of options(); track option.value) { + + } + + + + `, +}) +export class RadioGroupComponent { + readonly name = input.required(); + readonly label = input(); + readonly options = input.required(); + readonly required = input(false); + readonly input = input(); + readonly errors = input<[string, ...string[]] | null>(null); + readonly class = input(''); + + readonly fieldFocus = output(); + readonly fieldChange = output(); + readonly fieldBlur = output(); + + protected readonly containerClasses = () => + clsx('px-8 lg:px-10', this.class()); +} diff --git a/playgrounds/angular/src/components/radio.component.ts b/playgrounds/angular/src/components/radio.component.ts new file mode 100644 index 00000000..14986696 --- /dev/null +++ b/playgrounds/angular/src/components/radio.component.ts @@ -0,0 +1,34 @@ +import { Component, input, output } from '@angular/core'; + +/** + * Simple radio button input. Should be used inside a RadioGroup component. + */ +@Component({ + selector: 'app-radio', + standalone: true, + template: ` + + + {{ label() }} + + `, +}) +export class RadioComponent { + readonly name = input.required(); + readonly label = input.required(); + readonly value = input.required(); + readonly checked = input(false); + + readonly fieldFocus = output(); + readonly fieldChange = output(); + readonly fieldBlur = output(); +} diff --git a/playgrounds/angular/src/components/select.component.ts b/playgrounds/angular/src/components/select.component.ts new file mode 100644 index 00000000..470c4b32 --- /dev/null +++ b/playgrounds/angular/src/components/select.component.ts @@ -0,0 +1,92 @@ +import { Component, computed, input, output } from '@angular/core'; +import clsx from 'clsx'; +import { InputLabelComponent } from './input-label.component.ts'; +import { InputErrorsComponent } from './input-errors.component.ts'; +import { AngleDownIconComponent } from '../icons/angle-down-icon.component.ts'; + +interface SelectOption { + label: string; + value: string; +} + +/** + * Select field that allows users to select predefined values. Various + * decorations can be displayed in or around the field to communicate the + * entry requirements. + */ +@Component({ + selector: 'app-select', + standalone: true, + imports: [InputLabelComponent, InputErrorsComponent, AngleDownIconComponent], + template: ` + + + + + @if (placeholder()) { + {{ placeholder() }} + } + @for (option of options(); track option.value) { + + {{ option.label }} + + } + + @if (!multiple()) { + + } + + + + `, +}) +export class SelectComponent { + readonly name = input.required(); + readonly label = input(); + readonly options = input.required(); + readonly multiple = input(false); + readonly size = input(); + readonly placeholder = input(); + readonly required = input(false); + readonly input = input(); + readonly errors = input<[string, ...string[]] | null>(null); + readonly class = input(''); + + readonly fieldFocus = output(); + readonly fieldChange = output(); + readonly fieldBlur = output(); + + protected readonly values = computed(() => { + const val = this.input(); + if (Array.isArray(val)) return val; + if (val && typeof val === 'string') return [val]; + return []; + }); + + protected readonly containerClasses = () => + clsx('px-8 lg:px-10', this.class()); + + protected readonly selectClasses = computed(() => + clsx( + 'w-full appearance-none space-y-2 rounded-2xl border-2 bg-transparent px-5 outline-none md:text-lg lg:space-y-3 lg:px-6 lg:text-xl', + this.errors() + ? 'border-red-600/50 dark:border-red-400/50' + : 'border-slate-200 hover:border-slate-300 focus:border-sky-600/50 dark:border-slate-800 dark:hover:border-slate-700 dark:focus:border-sky-400/50', + this.multiple() ? 'py-5' : 'h-14 md:h-16 lg:h-[70px]', + this.placeholder() && !this.values().length && 'text-slate-500' + ) + ); +} diff --git a/playgrounds/angular/src/components/slider.component.ts b/playgrounds/angular/src/components/slider.component.ts new file mode 100644 index 00000000..26ef0805 --- /dev/null +++ b/playgrounds/angular/src/components/slider.component.ts @@ -0,0 +1,54 @@ +import { Component, input, output } from '@angular/core'; +import clsx from 'clsx'; +import { InputLabelComponent } from './input-label.component.ts'; +import { InputErrorsComponent } from './input-errors.component.ts'; + +/** + * Range slider that allows users to select predefined numbers. Various + * decorations can be displayed in or around the field to communicate the + * entry requirements. + */ +@Component({ + selector: 'app-slider', + standalone: true, + imports: [InputLabelComponent, InputErrorsComponent], + template: ` + + + + + + `, +}) +export class SliderComponent { + readonly name = input.required(); + readonly label = input(); + readonly min = input(); + readonly max = input(); + readonly step = input(); + readonly required = input(false); + readonly input = input(); + readonly errors = input<[string, ...string[]] | null>(null); + readonly class = input(''); + + readonly fieldFocus = output(); + readonly fieldChange = output(); + readonly fieldBlur = output(); + + protected readonly containerClasses = () => + clsx('px-8 lg:px-10', this.class()); +} diff --git a/playgrounds/angular/src/components/spinner.component.ts b/playgrounds/angular/src/components/spinner.component.ts new file mode 100644 index 00000000..64bf10fa --- /dev/null +++ b/playgrounds/angular/src/components/spinner.component.ts @@ -0,0 +1,16 @@ +import { Component } from '@angular/core'; + +/** + * Spinner provides a visual cue that an action is being processed. + */ +@Component({ + selector: 'app-spinner', + standalone: true, + template: ` + + `, +}) +export class SpinnerComponent {} diff --git a/playgrounds/angular/src/components/text-input.component.ts b/playgrounds/angular/src/components/text-input.component.ts new file mode 100644 index 00000000..541aa0e6 --- /dev/null +++ b/playgrounds/angular/src/components/text-input.component.ts @@ -0,0 +1,59 @@ +import { Component, computed, input, output } from '@angular/core'; +import clsx from 'clsx'; +import { InputLabelComponent } from './input-label.component.ts'; +import { InputErrorsComponent } from './input-errors.component.ts'; + +/** + * Text input field that users can type into. Various decorations can be + * displayed in or around the field to communicate the entry requirements. + */ +@Component({ + selector: 'app-text-input', + standalone: true, + imports: [InputLabelComponent, InputErrorsComponent], + template: ` + + + + + + `, +}) +export class TextInputComponent { + readonly name = input.required(); + readonly type = input('text'); + readonly label = input(); + readonly placeholder = input(); + readonly required = input(false); + readonly value = input(); + readonly errors = input<[string, ...string[]] | null>(null); + readonly class = input(''); + + readonly fieldFocus = output(); + readonly fieldChange = output(); + readonly fieldBlur = output(); + + protected readonly containerClasses = () => + clsx('px-8 lg:px-10', this.class()); + + protected readonly inputClass = computed(() => + clsx( + 'h-14 w-full rounded-2xl border-2 bg-white px-5 outline-none placeholder:text-slate-500 md:h-16 md:text-lg lg:h-[70px] lg:px-6 lg:text-xl dark:bg-gray-900', + this.errors() + ? 'border-red-600/50 dark:border-red-400/50' + : 'border-slate-200 hover:border-slate-300 focus:border-sky-600/50 dark:border-slate-800 dark:hover:border-slate-700 dark:focus:border-sky-400/50' + ) + ); +} diff --git a/playgrounds/angular/src/components/unstyled-button.component.ts b/playgrounds/angular/src/components/unstyled-button.component.ts new file mode 100644 index 00000000..dde3c083 --- /dev/null +++ b/playgrounds/angular/src/components/unstyled-button.component.ts @@ -0,0 +1,63 @@ +import { Component, input, output, signal } from '@angular/core'; +import clsx from 'clsx'; +import { SpinnerComponent } from './spinner.component.ts'; + +/** + * Basic button component with loading state and spinner animation. + */ +@Component({ + selector: 'app-unstyled-button', + standalone: true, + imports: [SpinnerComponent], + template: ` + + + + + + + + + `, +}) +export class UnstyledButtonComponent { + readonly type = input<'button' | 'submit' | 'reset'>('button'); + readonly class = input(''); + readonly loading = input(false); + readonly onClick = input<(() => unknown) | undefined>(undefined); + readonly clicked = output(); + + protected readonly isLoading = signal(false); + protected readonly clsx = clsx; + + protected async handleClick(): Promise { + const handler = this.onClick(); + this.clicked.emit(); + if (!handler) return; + this.isLoading.set(true); + try { + await handler(); + } finally { + this.isLoading.set(false); + } + } +} diff --git a/playgrounds/angular/src/global.css b/playgrounds/angular/src/global.css new file mode 100644 index 00000000..6ad1ba7e --- /dev/null +++ b/playgrounds/angular/src/global.css @@ -0,0 +1,26 @@ +@import 'tailwindcss'; + +/* Lexend 400 */ +@font-face { + font-family: 'Lexend'; + font-style: normal; + font-weight: 400; + font-display: swap; + src: url(/fonts/lexend-400.woff2) format('woff2'); +} + +/* Base styles */ +html { + font-family: 'Lexend', ui-sans-serif, system-ui, sans-serif; +} + +/* Disable-transitions */ +.disable-transitions, +.disable-transitions * { + transition: none !important; +} + +/* Reset appearance */ +[type='date'] { + @apply flex appearance-none items-center justify-start; +} diff --git a/playgrounds/angular/src/icons/angle-down-icon.component.ts b/playgrounds/angular/src/icons/angle-down-icon.component.ts new file mode 100644 index 00000000..df4548ce --- /dev/null +++ b/playgrounds/angular/src/icons/angle-down-icon.component.ts @@ -0,0 +1,24 @@ +import { Component, input } from '@angular/core'; + +@Component({ + selector: 'app-angle-down-icon', + standalone: true, + template: ` + + + + `, +}) +export class AngleDownIconComponent { + readonly class = input(''); +} diff --git a/playgrounds/angular/src/main.ts b/playgrounds/angular/src/main.ts new file mode 100644 index 00000000..76b90249 --- /dev/null +++ b/playgrounds/angular/src/main.ts @@ -0,0 +1,6 @@ +import { bootstrapApplication } from '@angular/platform-browser'; +import { AppComponent } from './app.component.ts'; +import { appConfig } from './app.config.ts'; +import './global.css'; + +bootstrapApplication(AppComponent, appConfig).catch(console.error); diff --git a/playgrounds/angular/src/routes/login/login.component.ts b/playgrounds/angular/src/routes/login/login.component.ts new file mode 100644 index 00000000..f882261f --- /dev/null +++ b/playgrounds/angular/src/routes/login/login.component.ts @@ -0,0 +1,79 @@ +import { Component } from '@angular/core'; +import * as v from 'valibot'; +import { FormischForm, FormischField, injectForm } from '@formisch/angular'; +import { FormHeaderComponent } from '../../components/form-header.component.ts'; +import { FormFooterComponent } from '../../components/form-footer.component.ts'; +import { TextInputComponent } from '../../components/text-input.component.ts'; + +const LoginSchema = v.object({ + email: v.pipe( + v.string('Please enter your email.'), + v.nonEmpty('Please enter your email.'), + v.email('The email address is badly formatted.') + ), + password: v.pipe( + v.string('Please enter your password.'), + v.nonEmpty('Please enter your password.'), + v.minLength(8, 'Your password must have 8 characters or more.') + ), +}); + +@Component({ + selector: 'app-login', + standalone: true, + imports: [FormischForm, FormischField, FormHeaderComponent, FormFooterComponent, TextInputComponent], + template: ` + + + + + + + + + + + + + + + + + + + + `, +}) +export class LoginComponent { + readonly form = injectForm({ schema: LoginSchema, validate: 'blur' }); + + readonly handleSubmit = (output: v.InferOutput) => { + console.log(output); + }; +} diff --git a/playgrounds/angular/src/routes/nested/nested.component.ts b/playgrounds/angular/src/routes/nested/nested.component.ts new file mode 100644 index 00000000..24393c5f --- /dev/null +++ b/playgrounds/angular/src/routes/nested/nested.component.ts @@ -0,0 +1,220 @@ +import { Component } from '@angular/core'; +import * as v from 'valibot'; +import { + FormischForm, + FormischField, + FormischFieldArray, + insert, + move, + remove, + replace, + swap, + injectForm, +} from '@formisch/angular'; +import { AutoAnimateDirective } from '../../components/auto-animate.directive.ts'; +import { FormHeaderComponent } from '../../components/form-header.component.ts'; +import { FormFooterComponent } from '../../components/form-footer.component.ts'; +import { TextInputComponent } from '../../components/text-input.component.ts'; +import { ColorButtonComponent } from '../../components/color-button.component.ts'; + +const NestedFormSchema = v.object({ + items: v.array( + v.object({ + label: v.optional(v.string()), + options: v.array(v.optional(v.string())), + }) + ), +}); + +@Component({ + selector: 'app-nested', + standalone: true, + imports: [ + FormischForm, + FormischField, + FormischFieldArray, + AutoAnimateDirective, + FormHeaderComponent, + FormFooterComponent, + TextInputComponent, + ColorButtonComponent, + ], + template: ` + + + + + + + + @for (item of fieldArray.items(); track item; let itemIndex = $index) { + + + + + + + + + + + + + + + + + @for (opt of optionsArray.items(); track opt; let optionIndex = $index) { + + + + + + + + + + } + + + + + + + + + + + } + + + + + + + + + + + + + + + `, +}) +export class NestedComponent { + readonly form = injectForm({ + schema: NestedFormSchema, + initialInput: { + items: [ + { label: 'Item 1', options: ['Option 1', 'Option 2'] }, + { label: 'Item 2', options: ['Option 1', 'Option 2'] }, + ], + }, + }); + + readonly handleSubmit = (output: v.InferOutput) => { + console.log(output); + }; + + addItem(): void { + insert(this.form, { path: ['items'], initialInput: { label: '', options: [''] } }); + } + + moveItemFirstToEnd(length: number): void { + move(this.form, { path: ['items'], from: 0, to: length - 1 }); + } + + swapItemsFirstTwo(): void { + swap(this.form, { path: ['items'], at: 0, and: 1 }); + } + + replaceFirst(): void { + replace(this.form, { path: ['items'], at: 0, initialInput: { label: '', options: [''] } }); + } + + removeItem(index: number): void { + remove(this.form, { path: ['items'], at: index }); + } + + addOption(itemIndex: number): void { + insert(this.form, { path: ['items', itemIndex, 'options'], initialInput: '' }); + } + + moveOptionFirstToEnd(itemIndex: number, length: number): void { + move(this.form, { path: ['items', itemIndex, 'options'], from: 0, to: length - 1 }); + } + + swapOptionsFirstTwo(itemIndex: number): void { + swap(this.form, { path: ['items', itemIndex, 'options'], at: 0, and: 1 }); + } + + removeOption(itemIndex: number, optionIndex: number): void { + remove(this.form, { path: ['items', itemIndex, 'options'], at: optionIndex }); + } +} diff --git a/playgrounds/angular/src/routes/payment/payment.component.ts b/playgrounds/angular/src/routes/payment/payment.component.ts new file mode 100644 index 00000000..d43e4443 --- /dev/null +++ b/playgrounds/angular/src/routes/payment/payment.component.ts @@ -0,0 +1,181 @@ +import { Component, computed } from '@angular/core'; +import * as v from 'valibot'; +import { FormischForm, FormischField, getInput, injectForm } from '@formisch/angular'; +import { FormHeaderComponent } from '../../components/form-header.component.ts'; +import { FormFooterComponent } from '../../components/form-footer.component.ts'; +import { TextInputComponent } from '../../components/text-input.component.ts'; + +const PaymentSchema = v.intersect([ + v.object({ + owner: v.pipe( + v.string('Please enter your name.'), + v.nonEmpty('Please enter your name.') + ), + }), + v.variant('type', [ + v.object({ + type: v.literal('card'), + card: v.object({ + number: v.pipe( + v.string('Please enter your card number.'), + v.nonEmpty('Please enter your card number.'), + v.creditCard('The card number is badly formatted.') + ), + expiration: v.pipe( + v.string('Please enter the expiration date.'), + v.nonEmpty('Please enter the expiration date.'), + v.regex( + /^(?:0[1-9]|1[0-2])\/(?:2[5-9]|3[0-9])$/, + 'The expiration date is badly formatted.' + ) + ), + }), + }), + v.object({ + type: v.literal('paypal'), + paypal: v.object({ + email: v.pipe( + v.string('Please enter your PayPal email.'), + v.nonEmpty('Please enter your PayPal email.'), + v.email('The email address is badly formatted.') + ), + }), + }), + ], 'Please select the payment type.'), +]); + +@Component({ + selector: 'app-payment', + standalone: true, + imports: [FormischForm, FormischField, FormHeaderComponent, FormFooterComponent, TextInputComponent], + template: ` + + + + + + + + + + + + + + + Type * + + + @for (option of paymentTypes; track option.value) { + + + {{ option.label }} + + } + + @if (field.errors()) { + + {{ field.errors()![0] }} + + } + + + + + @if (paymentType() === 'card') { + + + + + + + + + + + + } + + @if (paymentType() === 'paypal') { + + + + + + } + + + + + `, +}) +export class PaymentComponent { + readonly form = injectForm({ schema: PaymentSchema, validate: 'blur' }); + + readonly paymentTypes = [ + { value: 'card', label: 'Card' }, + { value: 'paypal', label: 'PayPal' }, + ]; + + readonly paymentType = computed(() => + getInput(this.form, { path: ['type'] }) + ); + + readonly handleSubmit = (output: v.InferOutput) => { + console.log(output); + }; +} diff --git a/playgrounds/angular/src/routes/special/special.component.ts b/playgrounds/angular/src/routes/special/special.component.ts new file mode 100644 index 00000000..ef76e314 --- /dev/null +++ b/playgrounds/angular/src/routes/special/special.component.ts @@ -0,0 +1,226 @@ +import { Component } from '@angular/core'; +import * as v from 'valibot'; +import { FormischForm, FormischField, injectForm } from '@formisch/angular'; +import { FormHeaderComponent } from '../../components/form-header.component.ts'; +import { FormFooterComponent } from '../../components/form-footer.component.ts'; +import { TextInputComponent } from '../../components/text-input.component.ts'; +import { SliderComponent } from '../../components/slider.component.ts'; +import { CheckboxComponent } from '../../components/checkbox.component.ts'; +import { RadioGroupComponent } from '../../components/radio-group.component.ts'; +import { SelectComponent } from '../../components/select.component.ts'; +import { FileInputComponent } from '../../components/file-input.component.ts'; + +const SpecialFormSchema = v.object({ + number: v.optional(v.string()), + range: v.optional(v.string(), '50'), + checkbox: v.object({ + array: v.array(v.string()), + boolean: v.optional(v.boolean(), false), + }), + radio: v.optional(v.string()), + select: v.object({ + array: v.array(v.string()), + string: v.optional(v.string()), + }), + file: v.object({ + list: v.array(v.file()), + item: v.optional(v.file()), + }), +}); + +@Component({ + selector: 'app-special', + standalone: true, + imports: [ + FormischForm, + FormischField, + FormHeaderComponent, + FormFooterComponent, + TextInputComponent, + SliderComponent, + CheckboxComponent, + RadioGroupComponent, + SelectComponent, + FileInputComponent, + ], + template: ` + + + + + + + + + + + + + + + + + + Checkbox array + + + + @for (option of checkboxOptions; track option.value) { + + + + + + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + `, +}) +export class SpecialComponent { + readonly form = injectForm({ schema: SpecialFormSchema }); + + readonly checkboxOptions = [ + { label: 'Option 1', value: 'option_1' }, + { label: 'Option 2', value: 'option_2' }, + { label: 'Option 3', value: 'option_3' }, + ]; + + readonly radioOptions = [ + { label: 'Option 1', value: 'option_1' }, + { label: 'Option 2', value: 'option_2' }, + { label: 'Option 3', value: 'option_3' }, + ]; + + readonly selectOptions = [ + { label: 'Option 1', value: 'option_1' }, + { label: 'Option 2', value: 'option_2' }, + { label: 'Option 3', value: 'option_3' }, + ]; + + readonly handleSubmit = (output: v.InferOutput) => { + console.log(output); + }; +} diff --git a/playgrounds/angular/src/routes/todos/todos.component.ts b/playgrounds/angular/src/routes/todos/todos.component.ts new file mode 100644 index 00000000..798ef989 --- /dev/null +++ b/playgrounds/angular/src/routes/todos/todos.component.ts @@ -0,0 +1,211 @@ +import { Component } from '@angular/core'; +import * as v from 'valibot'; +import { + FormischForm, + FormischField, + FormischFieldArray, + insert, + move, + remove, + replace, + swap, + injectForm, +} from '@formisch/angular'; +import { AutoAnimateDirective } from '../../components/auto-animate.directive.ts'; +import { FormHeaderComponent } from '../../components/form-header.component.ts'; +import { FormFooterComponent } from '../../components/form-footer.component.ts'; +import { TextInputComponent } from '../../components/text-input.component.ts'; +import { InputLabelComponent } from '../../components/input-label.component.ts'; +import { InputErrorsComponent } from '../../components/input-errors.component.ts'; +import { ColorButtonComponent } from '../../components/color-button.component.ts'; + +const TodosSchema = v.object({ + heading: v.pipe( + v.string('Please enter a heading.'), + v.nonEmpty('Please enter a heading.') + ), + todos: v.pipe( + v.array( + v.object({ + label: v.pipe( + v.string('Please enter a label.'), + v.nonEmpty('Please enter a label.') + ), + deadline: v.pipe( + v.string('Please enter a deadline.'), + v.nonEmpty('Please enter a deadline.') + ), + }) + ), + v.nonEmpty('Please add at least one todo.'), + v.maxLength(4, 'You can only add up to 4 todos.') + ), +}); + +@Component({ + selector: 'app-todos', + standalone: true, + imports: [ + FormischForm, + FormischField, + FormischFieldArray, + AutoAnimateDirective, + FormHeaderComponent, + FormFooterComponent, + TextInputComponent, + InputLabelComponent, + InputErrorsComponent, + ColorButtonComponent, + ], + template: ` + + + + + + + + + + + + + + + + + + @for (item of fieldArray.items(); track item; let index = $index) { + + + + + + + + + + + + + + + + } + + + + + + + + + + + + + + + + + + `, +}) +export class TodosComponent { + readonly form = injectForm({ + schema: TodosSchema, + validate: 'blur', + initialInput: { + heading: '', + todos: [{ label: '', deadline: '' }], + }, + }); + + readonly handleSubmit = (output: v.InferOutput) => { + console.log(output); + }; + + handleInsert(): void { + insert(this.form, { path: ['todos'], initialInput: { label: '', deadline: '' } }); + } + + handleRemove(index: number): void { + remove(this.form, { path: ['todos'], at: index }); + } + + handleMoveFirstToEnd(length: number): void { + move(this.form, { path: ['todos'], from: 0, to: length - 1 }); + } + + handleSwapFirstTwo(): void { + swap(this.form, { path: ['todos'], at: 0, and: 1 }); + } + + handleReplaceFirst(): void { + replace(this.form, { + path: ['todos'], + at: 0, + initialInput: { + label: Math.random().toString(36).slice(2), + deadline: new Date().toISOString().split('T')[0], + }, + }); + } +} diff --git a/playgrounds/angular/src/utils/disable-transitions.ts b/playgrounds/angular/src/utils/disable-transitions.ts new file mode 100644 index 00000000..ec61732e --- /dev/null +++ b/playgrounds/angular/src/utils/disable-transitions.ts @@ -0,0 +1,8 @@ +/** + * Disables CSS transitions for a short moment. + */ +export function disableTransitions(): void { + const { classList } = document.documentElement; + classList.add('disable-transitions'); + setTimeout(() => classList.remove('disable-transitions'), 250); +} diff --git a/playgrounds/angular/tsconfig.app.json b/playgrounds/angular/tsconfig.app.json new file mode 100644 index 00000000..42648a69 --- /dev/null +++ b/playgrounds/angular/tsconfig.app.json @@ -0,0 +1,32 @@ +{ + "compilerOptions": { + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", + "target": "ES2022", + "useDefineForClassFields": false, + "lib": ["ES2022", "DOM", "DOM.Iterable"], + "module": "ESNext", + "types": ["vite/client"], + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "verbatimModuleSyntax": true, + "moduleDetection": "force", + /* Angular */ + "experimentalDecorators": true, + "emitDecoratorMetadata": false, + "strictPropertyInitialization": false, + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true, + "noUncheckedSideEffectImports": true, + "paths": { + "@formisch/angular": ["../../frameworks/angular/src/index.ts"] + } + }, + "include": ["src"] +} diff --git a/playgrounds/angular/tsconfig.json b/playgrounds/angular/tsconfig.json new file mode 100644 index 00000000..426eda2b --- /dev/null +++ b/playgrounds/angular/tsconfig.json @@ -0,0 +1,6 @@ +{ + "files": [], + "references": [ + { "path": "./tsconfig.app.json" } + ] +} diff --git a/playgrounds/angular/vite.config.ts b/playgrounds/angular/vite.config.ts new file mode 100644 index 00000000..148d9f23 --- /dev/null +++ b/playgrounds/angular/vite.config.ts @@ -0,0 +1,15 @@ +import tailwindcss from '@tailwindcss/vite'; +import angular from '@analogjs/vite-plugin-angular'; +import { defineConfig } from 'vite'; +import { fileURLToPath, URL } from 'node:url'; + +export default defineConfig({ + plugins: [angular(), tailwindcss()], + resolve: { + alias: { + '@formisch/angular': fileURLToPath( + new URL('../../frameworks/angular/src/index.ts', import.meta.url) + ), + }, + }, +}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f0df9efc..d8057fb1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -35,6 +35,57 @@ importers: specifier: ^5.8.3 version: 5.8.3 + frameworks/angular: + devDependencies: + '@angular/common': + specifier: ^19.0.0 + version: 19.2.22(@angular/core@19.2.22(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2) + '@angular/compiler': + specifier: ^19.0.0 + version: 19.2.22 + '@angular/core': + specifier: ^19.0.0 + version: 19.2.22(rxjs@7.8.2)(zone.js@0.15.1) + '@angular/platform-browser': + specifier: ^19.0.0 + version: 19.2.22(@angular/common@19.2.22(@angular/core@19.2.22(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.22(rxjs@7.8.2)(zone.js@0.15.1)) + '@formisch/core': + specifier: workspace:* + version: link:../../packages/core + '@formisch/eslint-config': + specifier: workspace:* + version: link:../../packages/eslint-config + '@formisch/methods': + specifier: workspace:* + version: link:../../packages/methods + '@types/node': + specifier: ^24.0.0 + version: 24.10.1 + '@vitest/coverage-v8': + specifier: ^3.2.4 + version: 3.2.4(vitest@3.2.4(@edge-runtime/vm@3.2.0)(@types/debug@4.1.12)(@types/node@24.10.1)(jiti@2.6.1)(jsdom@26.1.0)(less@4.4.2)(lightningcss@1.30.2)(sass@1.93.2)(stylus@0.62.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) + eslint: + specifier: ^9.31.0 + version: 9.39.1(jiti@2.6.1) + jsdom: + specifier: ^26.1.0 + version: 26.1.0 + tsdown: + specifier: ^0.16.8 + version: 0.16.8(publint@0.3.15)(typescript@5.8.3)(vue-tsc@3.1.2(typescript@5.8.3)) + typescript: + specifier: ~5.8.3 + version: 5.8.3 + valibot: + specifier: ^1.2.0 + version: 1.2.0(typescript@5.8.3) + vitest: + specifier: ^3.2.4 + version: 3.2.4(@edge-runtime/vm@3.2.0)(@types/debug@4.1.12)(@types/node@24.10.1)(jiti@2.6.1)(jsdom@26.1.0)(less@4.4.2)(lightningcss@1.30.2)(sass@1.93.2)(stylus@0.62.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) + zone.js: + specifier: ^0.15.0 + version: 0.15.1 + frameworks/preact: devDependencies: '@formisch/core': @@ -48,10 +99,10 @@ importers: version: link:../../packages/methods '@preact/preset-vite': specifier: ^2.10.5 - version: 2.10.5(@babel/core@7.28.5)(preact@10.29.2)(rollup@4.52.5)(vite@6.3.5(@types/node@24.10.1)(jiti@2.6.1)(less@4.4.2)(lightningcss@1.30.2)(sass@1.93.2)(stylus@0.62.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) + version: 2.10.5(@babel/core@7.28.5)(preact@10.29.2)(rollup@4.59.0)(vite@6.3.5(@types/node@24.10.1)(jiti@2.6.1)(less@4.4.2)(lightningcss@1.30.2)(sass@1.93.2)(stylus@0.62.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) '@preact/signals': specifier: ^2.9.0 - version: 2.9.0(preact@10.29.2) + version: 2.9.1(preact@10.29.2) '@testing-library/jest-dom': specifier: ^6.6.0 version: 6.9.1 @@ -253,7 +304,7 @@ importers: version: 8.5.0(jiti@2.6.1)(postcss@8.5.6)(tsx@4.20.6)(typescript@5.8.3)(yaml@2.8.1) tsup-preset-solid: specifier: ^2.2.0 - version: 2.2.0(esbuild@0.25.11)(solid-js@1.9.9)(tsup@8.5.0(jiti@2.6.1)(postcss@8.5.6)(tsx@4.20.6)(typescript@5.8.3)(yaml@2.8.1)) + version: 2.2.0(esbuild@0.28.0)(solid-js@1.9.9)(tsup@8.5.0(jiti@2.6.1)(postcss@8.5.6)(tsx@4.20.6)(typescript@5.8.3)(yaml@2.8.1)) typescript: specifier: ^5.8.3 version: 5.8.3 @@ -397,13 +448,13 @@ importers: devDependencies: '@angular/core': specifier: ^21.0.0 - version: 21.2.13(rxjs@7.8.2) + version: 21.2.13(rxjs@7.8.2)(zone.js@0.15.1) '@formisch/eslint-config': specifier: workspace:* version: link:../eslint-config '@preact/signals': specifier: ^2.9.0 - version: 2.9.0(preact@10.29.2) + version: 2.9.1(preact@10.29.2) '@qwik.dev/core': specifier: 2.0.0-beta.5 version: 2.0.0-beta.5(prettier@3.6.2)(vite@7.2.6(@types/node@24.0.13)(jiti@2.6.1)(less@4.4.2)(lightningcss@1.30.2)(sass@1.93.2)(stylus@0.62.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vitest@3.2.4(@edge-runtime/vm@3.2.0)(@types/debug@4.1.12)(@types/node@24.0.13)(jiti@2.6.1)(jsdom@26.1.0)(less@4.4.2)(lightningcss@1.30.2)(sass@1.93.2)(stylus@0.62.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) @@ -474,6 +525,9 @@ importers: specifier: ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 version: 19.2.1 devDependencies: + '@angular/core': + specifier: ^21.0.0 + version: 21.2.13(rxjs@7.8.2)(zone.js@0.15.1) '@formisch/core': specifier: workspace:* version: link:../core @@ -514,6 +568,61 @@ importers: specifier: 3.2.4 version: 3.2.4(@edge-runtime/vm@3.2.0)(@types/debug@4.1.12)(@types/node@24.0.13)(jiti@2.6.1)(jsdom@26.1.0)(less@4.4.2)(lightningcss@1.30.2)(sass@1.93.2)(stylus@0.62.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) + playgrounds/angular: + dependencies: + '@angular/common': + specifier: ^19.0.0 + version: 19.2.22(@angular/core@19.2.22(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2) + '@angular/compiler': + specifier: ^19.0.0 + version: 19.2.22 + '@angular/core': + specifier: ^19.0.0 + version: 19.2.22(rxjs@7.8.2)(zone.js@0.15.1) + '@angular/platform-browser': + specifier: ^19.0.0 + version: 19.2.22(@angular/common@19.2.22(@angular/core@19.2.22(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.22(rxjs@7.8.2)(zone.js@0.15.1)) + '@angular/router': + specifier: ^19.0.0 + version: 19.2.22(@angular/common@19.2.22(@angular/core@19.2.22(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.22(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@19.2.22(@angular/common@19.2.22(@angular/core@19.2.22(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.22(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2) + '@formisch/angular': + specifier: workspace:* + version: link:../../frameworks/angular + '@formkit/auto-animate': + specifier: ^0.8.4 + version: 0.8.4 + '@tailwindcss/vite': + specifier: ^4.1.17 + version: 4.1.17(vite@7.2.6(@types/node@24.10.1)(jiti@2.6.1)(less@4.4.2)(lightningcss@1.30.2)(sass@1.85.0)(stylus@0.62.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) + clsx: + specifier: ^2.1.1 + version: 2.1.1 + valibot: + specifier: ^1.2.0 + version: 1.2.0(typescript@5.8.3) + devDependencies: + '@analogjs/vite-plugin-angular': + specifier: ^1.10.0 + version: 1.22.5(@angular/build@19.2.26(@angular/compiler-cli@19.2.22(@angular/compiler@19.2.22)(typescript@5.8.3))(@angular/compiler@19.2.22)(@types/node@24.10.1)(chokidar@4.0.3)(jiti@2.6.1)(less@4.4.2)(lightningcss@1.30.2)(postcss@8.5.6)(stylus@0.62.0)(tailwindcss@4.1.17)(terser@5.44.0)(tsx@4.20.6)(typescript@5.8.3)(yaml@2.8.1)) + '@angular/build': + specifier: ^19.0.0 + version: 19.2.26(@angular/compiler-cli@19.2.22(@angular/compiler@19.2.22)(typescript@5.8.3))(@angular/compiler@19.2.22)(@types/node@24.10.1)(chokidar@4.0.3)(jiti@2.6.1)(less@4.4.2)(lightningcss@1.30.2)(postcss@8.5.6)(stylus@0.62.0)(tailwindcss@4.1.17)(terser@5.44.0)(tsx@4.20.6)(typescript@5.8.3)(yaml@2.8.1) + '@angular/compiler-cli': + specifier: ^19.0.0 + version: 19.2.22(@angular/compiler@19.2.22)(typescript@5.8.3) + '@types/node': + specifier: ^24.10.1 + version: 24.10.1 + tailwindcss: + specifier: ^4.1.17 + version: 4.1.17 + typescript: + specifier: ~5.8.3 + version: 5.8.3 + vite: + specifier: ^7.2.4 + version: 7.2.6(@types/node@24.10.1)(jiti@2.6.1)(less@4.4.2)(lightningcss@1.30.2)(sass@1.85.0)(stylus@0.62.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) + playgrounds/preact: dependencies: '@formisch/preact': @@ -524,7 +633,7 @@ importers: version: 0.8.4 '@preact/signals': specifier: ^2.9.0 - version: 2.9.0(preact@10.29.2) + version: 2.9.1(preact@10.29.2) clsx: specifier: ^2.1.1 version: 2.1.1 @@ -543,7 +652,7 @@ importers: version: link:../../packages/eslint-config '@preact/preset-vite': specifier: ^2.10.5 - version: 2.10.5(@babel/core@7.28.5)(preact@10.29.2)(rollup@4.52.5)(vite@6.3.5(@types/node@24.10.1)(jiti@2.6.1)(less@4.4.2)(lightningcss@1.30.2)(sass@1.93.2)(stylus@0.62.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) + version: 2.10.5(@babel/core@7.28.5)(preact@10.29.2)(rollup@4.59.0)(vite@6.3.5(@types/node@24.10.1)(jiti@2.6.1)(less@4.4.2)(lightningcss@1.30.2)(sass@1.93.2)(stylus@0.62.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) '@tailwindcss/vite': specifier: ^4.1.11 version: 4.1.16(vite@6.3.5(@types/node@24.10.1)(jiti@2.6.1)(less@4.4.2)(lightningcss@1.30.2)(sass@1.93.2)(stylus@0.62.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) @@ -793,7 +902,7 @@ importers: version: 5.42.1 svelte-check: specifier: ^4.3.1 - version: 4.3.3(picomatch@4.0.3)(svelte@5.42.1)(typescript@5.9.3) + version: 4.3.3(picomatch@4.0.4)(svelte@5.42.1)(typescript@5.9.3) tailwindcss: specifier: ^4.1.13 version: 4.1.16 @@ -903,7 +1012,7 @@ importers: version: 2.0.0-beta.9(prettier@3.6.2)(vite@5.4.21(@types/node@22.18.12)(less@4.4.2)(lightningcss@1.30.2)(sass@1.93.2)(stylus@0.62.0)(terser@5.44.0))(vitest@3.2.4(@edge-runtime/vm@3.2.0)(@types/debug@4.1.12)(@types/node@22.18.12)(jiti@2.6.1)(jsdom@26.1.0)(less@4.4.2)(lightningcss@1.30.2)(sass@1.93.2)(stylus@0.62.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) '@qwik.dev/router': specifier: 2.0.0-beta.9 - version: 2.0.0-beta.9(patch_hash=e002def78f4681060d18bc24d686c24ee1d1b997c399a2cb1c03baf3b860e4c8)(rollup@4.52.5)(typescript@5.8.3) + version: 2.0.0-beta.9(patch_hash=e002def78f4681060d18bc24d686c24ee1d1b997c399a2cb1c03baf3b860e4c8)(rollup@4.59.0)(typescript@5.8.3) '@shikijs/rehype': specifier: ^3.13.0 version: 3.13.0 @@ -975,7 +1084,7 @@ importers: version: 5.4.21(@types/node@22.18.12)(less@4.4.2)(lightningcss@1.30.2)(sass@1.93.2)(stylus@0.62.0)(terser@5.44.0) vite-imagetools: specifier: ^7.0.5 - version: 7.1.1(rollup@4.52.5) + version: 7.1.1(rollup@4.59.0) vite-tsconfig-paths: specifier: ^5.1.4 version: 5.1.4(typescript@5.8.3)(vite@5.4.21(@types/node@22.18.12)(less@4.4.2)(lightningcss@1.30.2)(sass@1.93.2)(stylus@0.62.0)(terser@5.44.0)) @@ -992,6 +1101,92 @@ packages: resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} engines: {node: '>=6.0.0'} + '@analogjs/vite-plugin-angular@1.22.5': + resolution: {integrity: sha512-N1BQD6HQSp2Imbb1fThymskWFSLq0ZF+d2fe3DgErwlBFf6SzRp++iFltddQc3wIzenTXE+5brS4fAPXO8UT9g==} + peerDependencies: + '@angular-devkit/build-angular': ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^20.0.0 + '@angular/build': ^18.0.0 || ^19.0.0 || ^20.0.0 + peerDependenciesMeta: + '@angular-devkit/build-angular': + optional: true + '@angular/build': + optional: true + + '@angular-devkit/architect@0.1902.26': + resolution: {integrity: sha512-YL0SE4B+zLkPJa7glWBqNJzZS2qMMq8GzuGACJvHnRETL3jad34q3ByIM+wOTXbAVbKef3Poa/sPPunjMLdZUA==} + engines: {node: ^18.19.1 || ^20.11.1 || >=22.0.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} + + '@angular-devkit/core@19.2.26': + resolution: {integrity: sha512-50HrZQ2S/t9bWDEg30qqkwHUCH+k7pmslPqHLMFe0q+oUNaL5Ru+fi/L84bDzqRP/0mkeIIY2rOuUWrw6ZpGvQ==} + engines: {node: ^18.19.1 || ^20.11.1 || >=22.0.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} + peerDependencies: + chokidar: ^4.0.0 + peerDependenciesMeta: + chokidar: + optional: true + + '@angular/build@19.2.26': + resolution: {integrity: sha512-pcV/m+hm5dD05d2xAOjr5dIdSJoSZDmM1OKbD551196OXiXb88F52hw0Rmn+TWk1+ksX3ivjgH0lSe7ww65mPA==} + engines: {node: ^18.19.1 || ^20.11.1 || >=22.0.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} + peerDependencies: + '@angular/compiler': ^19.0.0 || ^19.2.0-next.0 + '@angular/compiler-cli': ^19.0.0 || ^19.2.0-next.0 + '@angular/localize': ^19.0.0 || ^19.2.0-next.0 + '@angular/platform-server': ^19.0.0 || ^19.2.0-next.0 + '@angular/service-worker': ^19.0.0 || ^19.2.0-next.0 + '@angular/ssr': ^19.2.26 + karma: ^6.4.0 + less: ^4.2.0 + ng-packagr: ^19.0.0 || ^19.2.0-next.0 + postcss: ^8.4.0 + tailwindcss: ^2.0.0 || ^3.0.0 || ^4.0.0 + typescript: '>=5.5 <5.9' + peerDependenciesMeta: + '@angular/localize': + optional: true + '@angular/platform-server': + optional: true + '@angular/service-worker': + optional: true + '@angular/ssr': + optional: true + karma: + optional: true + less: + optional: true + ng-packagr: + optional: true + postcss: + optional: true + tailwindcss: + optional: true + + '@angular/common@19.2.22': + resolution: {integrity: sha512-OGvJkK9xvlXF0LsM8T2NTgL6ehr+P4t493xztdIwiO7CzseDzHCBNZ8L1TwaVqqP3Xj0UhGTtWXp7YN4N9+u7Q==} + engines: {node: ^18.19.1 || ^20.11.1 || >=22.0.0} + peerDependencies: + '@angular/core': 19.2.22 + rxjs: ^6.5.3 || ^7.4.0 + + '@angular/compiler-cli@19.2.22': + resolution: {integrity: sha512-zwl4gh5smX95AduH60RpeToKRpRtj2oVEJ3KsgCb6KUfLbe/PK3lCQaLVW4tp1BbiCvCC05lhYC7ARtMbFFHrA==} + engines: {node: ^18.19.1 || ^20.11.1 || >=22.0.0} + hasBin: true + peerDependencies: + '@angular/compiler': 19.2.22 + typescript: '>=5.5 <5.9' + + '@angular/compiler@19.2.22': + resolution: {integrity: sha512-NO3q39TMq88MRyBM9E/cSn4KFEItPrp79izX3nRkWlGQ0D9nJPdzm2cHtZoB9dCZ3N6EOazTgBK+2jKylQrUFQ==} + engines: {node: ^18.19.1 || ^20.11.1 || >=22.0.0} + + '@angular/core@19.2.22': + resolution: {integrity: sha512-ImujBPIrV9eetYl2GaEBRw9CetklFtXB11oVaxOjflE2z6juTjugzXhszo/khMLj6UFfS+Anvp7Vv/Ot6DJL7A==} + engines: {node: ^18.19.1 || ^20.11.1 || >=22.0.0} + peerDependencies: + rxjs: ^6.5.3 || ^7.4.0 + zone.js: ~0.15.0 + '@angular/core@21.2.13': resolution: {integrity: sha512-23tS4oNL8nvkHcI4l9rbruQs2WS4yqQmBVQxWakqS9cmRpArLGgveR+hKNU5tPXm5EAi8oLO34/Zy7z70jUpCg==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} @@ -1005,6 +1200,26 @@ packages: zone.js: optional: true + '@angular/platform-browser@19.2.22': + resolution: {integrity: sha512-7OE80uM3DYDXa8D+1c3D231yzfqWz+2YaQElKK5MTPIDobSA9Dsu4YIFX80FRFxaopo3673RepZgxxFx3KzRzA==} + engines: {node: ^18.19.1 || ^20.11.1 || >=22.0.0} + peerDependencies: + '@angular/animations': 19.2.22 + '@angular/common': 19.2.22 + '@angular/core': 19.2.22 + peerDependenciesMeta: + '@angular/animations': + optional: true + + '@angular/router@19.2.22': + resolution: {integrity: sha512-FNxNJ2WifZdcOzieJHHugNTZWgZArD35bnmpO3m7V9Bow43Hy42xAOpHvAGMw8wZgVFBQl6C+Wr6GZB3eQzX/w==} + engines: {node: ^18.19.1 || ^20.11.1 || >=22.0.0} + peerDependencies: + '@angular/common': 19.2.22 + '@angular/core': 19.2.22 + '@angular/platform-browser': 19.2.22 + rxjs: ^6.5.3 || ^7.4.0 + '@asamuzakjp/css-color@3.2.0': resolution: {integrity: sha512-K1A6z8tS3XsmCMM86xoWdn7Fkdn9m6RSVtocUrJYIwZnFVkng/PvkEoWtOWmP+Scc6saYWHWZYbndEEXxl24jw==} @@ -1020,6 +1235,14 @@ packages: resolution: {integrity: sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA==} engines: {node: '>=6.9.0'} + '@babel/core@7.26.10': + resolution: {integrity: sha512-vMqyb7XCDMPvJFFOaT9kxtiRh42GwlZEg1/uIgtZshS5a/8OaduUfCi7kynKgc3Tw/6Uo2D+db9qBttghhmxwQ==} + engines: {node: '>=6.9.0'} + + '@babel/core@7.26.9': + resolution: {integrity: sha512-lWBYIrF7qK5+GjY5Uy+/hEgp8OJWOD/rpy74GplYRhEauvbHDeFB8t5hPOZxCZ0Oxf4Cc36tK51/l3ymJysrKw==} + engines: {node: '>=6.9.0'} + '@babel/core@7.28.5': resolution: {integrity: sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==} engines: {node: '>=6.9.0'} @@ -1035,6 +1258,10 @@ packages: resolution: {integrity: sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==} engines: {node: '>=6.9.0'} + '@babel/helper-annotate-as-pure@7.25.9': + resolution: {integrity: sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==} + engines: {node: '>=6.9.0'} + '@babel/helper-annotate-as-pure@7.27.3': resolution: {integrity: sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==} engines: {node: '>=6.9.0'} @@ -1106,6 +1333,10 @@ packages: resolution: {integrity: sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==} engines: {node: '>=6.9.0'} + '@babel/helper-split-export-declaration@7.24.7': + resolution: {integrity: sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==} + engines: {node: '>=6.9.0'} + '@babel/helper-string-parser@7.27.1': resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} engines: {node: '>=6.9.0'} @@ -1190,6 +1421,12 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/plugin-syntax-import-attributes@7.26.0': + resolution: {integrity: sha512-e2dttdsJ1ZTpi3B9UYGLw41hifAubg19AtCu/2I/F1QNVclOBr1dYpTdmdyZ84Xiz43BS/tCUkMAZNLv12Pi+A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + '@babel/plugin-syntax-import-attributes@7.27.1': resolution: {integrity: sha512-oFT0FrKHgF53f4vOsZGi2Hh3I35PfSmVs4IBFLFj4dnafP+hIWDLg3VyKmUHfLoLHlyxY4C7DGtmHuJgn+IGww==} engines: {node: '>=6.9.0'} @@ -1691,6 +1928,12 @@ packages: cpu: [ppc64] os: [aix] + '@esbuild/aix-ppc64@0.28.0': + resolution: {integrity: sha512-lhRUCeuOyJQURhTxl4WkpFTjIsbDayJHih5kZC1giwE+MhIzAb7mEsQMqMf18rHLsrb5qI1tafG20mLxEWcWlA==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + '@esbuild/android-arm64@0.17.19': resolution: {integrity: sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA==} engines: {node: '>=12'} @@ -1715,6 +1958,12 @@ packages: cpu: [arm64] os: [android] + '@esbuild/android-arm64@0.28.0': + resolution: {integrity: sha512-+WzIXQOSaGs33tLEgYPYe/yQHf0WTU0X42Jca3y8NWMbUVhp7rUnw+vAsRC/QiDrdD31IszMrZy+qwPOPjd+rw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + '@esbuild/android-arm@0.15.18': resolution: {integrity: sha512-5GT+kcs2WVGjVs7+boataCkO5Fg0y4kCjzkB5bAip7H4jfnOS3dA6KPiww9W1OEKTKeAcUVhdZGvgI65OXmUnw==} engines: {node: '>=12'} @@ -1745,6 +1994,12 @@ packages: cpu: [arm] os: [android] + '@esbuild/android-arm@0.28.0': + resolution: {integrity: sha512-wqh0ByljabXLKHeWXYLqoJ5jKC4XBaw6Hk08OfMrCRd2nP2ZQ5eleDZC41XHyCNgktBGYMbqnrJKq/K/lzPMSQ==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + '@esbuild/android-x64@0.17.19': resolution: {integrity: sha512-uUTTc4xGNDT7YSArp/zbtmbhO0uEEK9/ETW29Wk1thYUJBz3IVnvgEiEwEa9IeLyvnpKrWK64Utw2bgUmDveww==} engines: {node: '>=12'} @@ -1769,6 +2024,12 @@ packages: cpu: [x64] os: [android] + '@esbuild/android-x64@0.28.0': + resolution: {integrity: sha512-+VJggoaKhk2VNNqVL7f6S189UzShHC/mR9EE8rDdSkdpN0KflSwWY/gWjDrNxxisg8Fp1ZCD9jLMo4m0OUfeUA==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + '@esbuild/darwin-arm64@0.17.19': resolution: {integrity: sha512-80wEoCfF/hFKM6WE1FyBHc9SfUblloAWx6FJkFWTWiCoht9Mc0ARGEM47e67W9rI09YoUxJL68WHfDRYEAvOhg==} engines: {node: '>=12'} @@ -1793,6 +2054,12 @@ packages: cpu: [arm64] os: [darwin] + '@esbuild/darwin-arm64@0.28.0': + resolution: {integrity: sha512-0T+A9WZm+bZ84nZBtk1ckYsOvyA3x7e2Acj1KdVfV4/2tdG4fzUp91YHx+GArWLtwqp77pBXVCPn2We7Letr0Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + '@esbuild/darwin-x64@0.17.19': resolution: {integrity: sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw==} engines: {node: '>=12'} @@ -1817,6 +2084,12 @@ packages: cpu: [x64] os: [darwin] + '@esbuild/darwin-x64@0.28.0': + resolution: {integrity: sha512-fyzLm/DLDl/84OCfp2f/XQ4flmORsjU7VKt8HLjvIXChJoFFOIL6pLJPH4Yhd1n1gGFF9mPwtlN5Wf82DZs+LQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + '@esbuild/freebsd-arm64@0.17.19': resolution: {integrity: sha512-pBwbc7DufluUeGdjSU5Si+P3SoMF5DQ/F/UmTSb8HXO80ZEAJmrykPyzo1IfNbAoaqw48YRpv8shwd1NoI0jcQ==} engines: {node: '>=12'} @@ -1841,6 +2114,12 @@ packages: cpu: [arm64] os: [freebsd] + '@esbuild/freebsd-arm64@0.28.0': + resolution: {integrity: sha512-l9GeW5UZBT9k9brBYI+0WDffcRxgHQD8ShN2Ur4xWq/NFzUKm3k5lsH4PdaRgb2w7mI9u61nr2gI2mLI27Nh3Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + '@esbuild/freebsd-x64@0.17.19': resolution: {integrity: sha512-4lu+n8Wk0XlajEhbEffdy2xy53dpR06SlzvhGByyg36qJw6Kpfk7cp45DR/62aPH9mtJRmIyrXAS5UWBrJT6TQ==} engines: {node: '>=12'} @@ -1865,6 +2144,12 @@ packages: cpu: [x64] os: [freebsd] + '@esbuild/freebsd-x64@0.28.0': + resolution: {integrity: sha512-BXoQai/A0wPO6Es3yFJ7APCiKGc1tdAEOgeTNy3SsB491S3aHn4S4r3e976eUnPdU+NbdtmBuLncYir2tMU9Nw==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + '@esbuild/linux-arm64@0.17.19': resolution: {integrity: sha512-ct1Tg3WGwd3P+oZYqic+YZF4snNl2bsnMKRkb3ozHmnM0dGWuxcPTTntAF6bOP0Sp4x0PjSF+4uHQ1xvxfRKqg==} engines: {node: '>=12'} @@ -1889,6 +2174,12 @@ packages: cpu: [arm64] os: [linux] + '@esbuild/linux-arm64@0.28.0': + resolution: {integrity: sha512-RVyzfb3FWsGA55n6WY0MEIEPURL1FcbhFE6BffZEMEekfCzCIMtB5yyDcFnVbTnwk+CLAgTujmV/Lgvih56W+A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + '@esbuild/linux-arm@0.17.19': resolution: {integrity: sha512-cdmT3KxjlOQ/gZ2cjfrQOtmhG4HJs6hhvm3mWSRDPtZ/lP5oe8FWceS10JaSJC13GBd4eH/haHnqf7hhGNLerA==} engines: {node: '>=12'} @@ -1913,6 +2204,12 @@ packages: cpu: [arm] os: [linux] + '@esbuild/linux-arm@0.28.0': + resolution: {integrity: sha512-CjaaREJagqJp7iTaNQjjidaNbCKYcd4IDkzbwwxtSvjI7NZm79qiHc8HqciMddQ6CKvJT6aBd8lO9kN/ZudLlw==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + '@esbuild/linux-ia32@0.17.19': resolution: {integrity: sha512-w4IRhSy1VbsNxHRQpeGCHEmibqdTUx61Vc38APcsRbuVgK0OPEnQ0YD39Brymn96mOx48Y2laBQGqgZ0j9w6SQ==} engines: {node: '>=12'} @@ -1937,6 +2234,12 @@ packages: cpu: [ia32] os: [linux] + '@esbuild/linux-ia32@0.28.0': + resolution: {integrity: sha512-KBnSTt1kxl9x70q+ydterVdl+Cn0H18ngRMRCEQfrbqdUuntQQ0LoMZv47uB97NljZFzY6HcfqEZ2SAyIUTQBQ==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + '@esbuild/linux-loong64@0.15.18': resolution: {integrity: sha512-L4jVKS82XVhw2nvzLg/19ClLWg0y27ulRwuP7lcyL6AbUWB5aPglXY3M21mauDQMDfRLs8cQmeT03r/+X3cZYQ==} engines: {node: '>=12'} @@ -1967,6 +2270,12 @@ packages: cpu: [loong64] os: [linux] + '@esbuild/linux-loong64@0.28.0': + resolution: {integrity: sha512-zpSlUce1mnxzgBADvxKXX5sl8aYQHo2ezvMNI8I0lbblJtp8V4odlm3Yzlj7gPyt3T8ReksE6bK+pT3WD+aJRg==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + '@esbuild/linux-mips64el@0.17.19': resolution: {integrity: sha512-LKJltc4LVdMKHsrFe4MGNPp0hqDFA1Wpt3jE1gEyM3nKUvOiO//9PheZZHfYRfYl6AwdTH4aTcXSqBerX0ml4A==} engines: {node: '>=12'} @@ -1991,6 +2300,12 @@ packages: cpu: [mips64el] os: [linux] + '@esbuild/linux-mips64el@0.28.0': + resolution: {integrity: sha512-2jIfP6mmjkdmeTlsX/9vmdmhBmKADrWqN7zcdtHIeNSCH1SqIoNI63cYsjQR8J+wGa4Y5izRcSHSm8K3QWmk3w==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + '@esbuild/linux-ppc64@0.17.19': resolution: {integrity: sha512-/c/DGybs95WXNS8y3Ti/ytqETiW7EU44MEKuCAcpPto3YjQbyK3IQVKfF6nbghD7EcLUGl0NbiL5Rt5DMhn5tg==} engines: {node: '>=12'} @@ -2015,6 +2330,12 @@ packages: cpu: [ppc64] os: [linux] + '@esbuild/linux-ppc64@0.28.0': + resolution: {integrity: sha512-bc0FE9wWeC0WBm49IQMPSPILRocGTQt3j5KPCA8os6VprfuJ7KD+5PzESSrJ6GmPIPJK965ZJHTUlSA6GNYEhg==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + '@esbuild/linux-riscv64@0.17.19': resolution: {integrity: sha512-FC3nUAWhvFoutlhAkgHf8f5HwFWUL6bYdvLc/TTuxKlvLi3+pPzdZiFKSWz/PF30TB1K19SuCxDTI5KcqASJqA==} engines: {node: '>=12'} @@ -2039,6 +2360,12 @@ packages: cpu: [riscv64] os: [linux] + '@esbuild/linux-riscv64@0.28.0': + resolution: {integrity: sha512-SQPZOwoTTT/HXFXQJG/vBX8sOFagGqvZyXcgLA3NhIqcBv1BJU1d46c0rGcrij2B56Z2rNiSLaZOYW5cUk7yLQ==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + '@esbuild/linux-s390x@0.17.19': resolution: {integrity: sha512-IbFsFbxMWLuKEbH+7sTkKzL6NJmG2vRyy6K7JJo55w+8xDk7RElYn6xvXtDW8HCfoKBFK69f3pgBJSUSQPr+4Q==} engines: {node: '>=12'} @@ -2063,6 +2390,12 @@ packages: cpu: [s390x] os: [linux] + '@esbuild/linux-s390x@0.28.0': + resolution: {integrity: sha512-SCfR0HN8CEEjnYnySJTd2cw0k9OHB/YFzt5zgJEwa+wL/T/raGWYMBqwDNAC6dqFKmJYZoQBRfHjgwLHGSrn3Q==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + '@esbuild/linux-x64@0.17.19': resolution: {integrity: sha512-68ngA9lg2H6zkZcyp22tsVt38mlhWde8l3eJLWkyLrp4HwMUr3c1s/M2t7+kHIhvMjglIBrFpncX1SzMckomGw==} engines: {node: '>=12'} @@ -2087,12 +2420,24 @@ packages: cpu: [x64] os: [linux] + '@esbuild/linux-x64@0.28.0': + resolution: {integrity: sha512-us0dSb9iFxIi8srnpl931Nvs65it/Jd2a2K3qs7fz2WfGPHqzfzZTfec7oxZJRNPXPnNYZtanmRc4AL/JwVzHQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + '@esbuild/netbsd-arm64@0.25.11': resolution: {integrity: sha512-hr9Oxj1Fa4r04dNpWr3P8QKVVsjQhqrMSUzZzf+LZcYjZNqhA3IAfPQdEh1FLVUJSiu6sgAwp3OmwBfbFgG2Xg==} engines: {node: '>=18'} cpu: [arm64] os: [netbsd] + '@esbuild/netbsd-arm64@0.28.0': + resolution: {integrity: sha512-CR/RYotgtCKwtftMwJlUU7xCVNg3lMYZ0RzTmAHSfLCXw3NtZtNpswLEj/Kkf6kEL3Gw+BpOekRX0BYCtklhUw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + '@esbuild/netbsd-x64@0.17.19': resolution: {integrity: sha512-CwFq42rXCR8TYIjIfpXCbRX0rp1jo6cPIUPSaWwzbVI4aOfX96OXY8M6KNmtPcg7QjYeDmN+DD0Wp3LaBOLf4Q==} engines: {node: '>=12'} @@ -2117,12 +2462,24 @@ packages: cpu: [x64] os: [netbsd] + '@esbuild/netbsd-x64@0.28.0': + resolution: {integrity: sha512-nU1yhmYutL+fQ71Kxnhg8uEOdC0pwEW9entHykTgEbna2pw2dkbFSMeqjjyHZoCmt8SBkOSvV+yNmm94aUrrqw==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + '@esbuild/openbsd-arm64@0.25.11': resolution: {integrity: sha512-Qq6YHhayieor3DxFOoYM1q0q1uMFYb7cSpLD2qzDSvK1NAvqFi8Xgivv0cFC6J+hWVw2teCYltyy9/m/14ryHg==} engines: {node: '>=18'} cpu: [arm64] os: [openbsd] + '@esbuild/openbsd-arm64@0.28.0': + resolution: {integrity: sha512-cXb5vApOsRsxsEl4mcZ1XY3D4DzcoMxR/nnc4IyqYs0rTI8ZKmW6kyyg+11Z8yvgMfAEldKzP7AdP64HnSC/6g==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + '@esbuild/openbsd-x64@0.17.19': resolution: {integrity: sha512-cnq5brJYrSZ2CF6c35eCmviIN3k3RczmHz8eYaVlNasVqsNY+JKohZU5MKmaOI+KkllCdzOKKdPs762VCPC20g==} engines: {node: '>=12'} @@ -2147,12 +2504,24 @@ packages: cpu: [x64] os: [openbsd] + '@esbuild/openbsd-x64@0.28.0': + resolution: {integrity: sha512-8wZM2qqtv9UP3mzy7HiGYNH/zjTA355mpeuA+859TyR+e+Tc08IHYpLJuMsfpDJwoLo1ikIJI8jC3GFjnRClzA==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + '@esbuild/openharmony-arm64@0.25.11': resolution: {integrity: sha512-rOREuNIQgaiR+9QuNkbkxubbp8MSO9rONmwP5nKncnWJ9v5jQ4JxFnLu4zDSRPf3x4u+2VN4pM4RdyIzDty/wQ==} engines: {node: '>=18'} cpu: [arm64] os: [openharmony] + '@esbuild/openharmony-arm64@0.28.0': + resolution: {integrity: sha512-FLGfyizszcef5C3YtoyQDACyg95+dndv79i2EekILBofh5wpCa1KuBqOWKrEHZg3zrL3t5ouE5jgr94vA+Wb2w==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + '@esbuild/sunos-x64@0.17.19': resolution: {integrity: sha512-vCRT7yP3zX+bKWFeP/zdS6SqdWB8OIpaRq/mbXQxTGHnIxspRtigpkUcDMlSCOejlHowLqII7K2JKevwyRP2rg==} engines: {node: '>=12'} @@ -2177,6 +2546,12 @@ packages: cpu: [x64] os: [sunos] + '@esbuild/sunos-x64@0.28.0': + resolution: {integrity: sha512-1ZgjUoEdHZZl/YlV76TSCz9Hqj9h9YmMGAgAPYd+q4SicWNX3G5GCyx9uhQWSLcbvPW8Ni7lj4gDa1T40akdlw==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + '@esbuild/win32-arm64@0.17.19': resolution: {integrity: sha512-yYx+8jwowUstVdorcMdNlzklLYhPxjniHWFKgRqH7IFlUEa0Umu3KuYplf1HUZZ422e3NU9F4LGb+4O0Kdcaag==} engines: {node: '>=12'} @@ -2201,6 +2576,12 @@ packages: cpu: [arm64] os: [win32] + '@esbuild/win32-arm64@0.28.0': + resolution: {integrity: sha512-Q9StnDmQ/enxnpxCCLSg0oo4+34B9TdXpuyPeTedN/6+iXBJ4J+zwfQI28u/Jl40nOYAxGoNi7mFP40RUtkmUA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + '@esbuild/win32-ia32@0.17.19': resolution: {integrity: sha512-eggDKanJszUtCdlVs0RB+h35wNlb5v4TWEkq4vZcmVt5u/HiDZrTXe2bWFQUez3RgNHwx/x4sk5++4NSSicKkw==} engines: {node: '>=12'} @@ -2225,6 +2606,12 @@ packages: cpu: [ia32] os: [win32] + '@esbuild/win32-ia32@0.28.0': + resolution: {integrity: sha512-zF3ag/gfiCe6U2iczcRzSYJKH1DCI+ByzSENHlM2FcDbEeo5Zd2C86Aq0tKUYAJJ1obRP84ymxIAksZUcdztHA==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + '@esbuild/win32-x64@0.17.19': resolution: {integrity: sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA==} engines: {node: '>=12'} @@ -2249,6 +2636,12 @@ packages: cpu: [x64] os: [win32] + '@esbuild/win32-x64@0.28.0': + resolution: {integrity: sha512-pEl1bO9mfAmIC+tW5btTmrKaujg3zGtUmWNdCw/xs70FBjwAL3o9OEKNHvNmnyylD6ubxUERiEhdsL0xBQ9efw==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + '@eslint-community/eslint-utils@4.9.0': resolution: {integrity: sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -2601,6 +2994,28 @@ packages: cpu: [x64] os: [win32] + '@inquirer/ansi@1.0.2': + resolution: {integrity: sha512-S8qNSZiYzFd0wAcyG5AXCvUHC5Sr7xpZ9wZ2py9XR88jUz8wooStVx5M6dRzczbBWjic9NP7+rY0Xi7qqK/aMQ==} + engines: {node: '>=18'} + + '@inquirer/confirm@5.1.6': + resolution: {integrity: sha512-6ZXYK3M1XmaVBZX6FCfChgtponnL0R6I7k8Nu+kaoNkT828FVZTcca1MqmWQipaW2oNREQl5AaPCUOOCVNdRMw==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/core@10.3.2': + resolution: {integrity: sha512-43RTuEbfP8MbKzedNqBrlhhNKVwoK//vUFNW3Q3vZ88BLcrs4kYpGg+B2mm5p2K/HfygoCxuKwJJiv8PbGmE0A==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + '@inquirer/external-editor@1.0.2': resolution: {integrity: sha512-yy9cOoBnx58TlsPrIxauKIFQTiyH+0MK4e97y4sV9ERbI+zDxw7i2hxHLCIEGIE/8PPvDxGhgzIOTSOWcs6/MQ==} engines: {node: '>=18'} @@ -2610,6 +3025,19 @@ packages: '@types/node': optional: true + '@inquirer/figures@1.0.15': + resolution: {integrity: sha512-t2IEY+unGHOzAaVM5Xx6DEWKeXlDDcNPeDyUpsRc6CUhBfU3VQOEl+Vssh7VNp1dR8MdUJBWhuObjXCsVpjN5g==} + engines: {node: '>=18'} + + '@inquirer/type@3.0.10': + resolution: {integrity: sha512-BvziSRxfz5Ov8ch0z/n3oijRSEcEsHnhggm4xFZe93DHcUCTlutlq9Ox4SVENAfcRD22UQq7T/atg9Wr3k09eA==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + '@ioredis/commands@1.4.0': resolution: {integrity: sha512-aFT2yemJJo+TZCmieA7qnYGQooOS7QfNmYrzGtsYd3g9j5iDP8AimYYAesf79ohjbLG12XxC4nG5DyEnC88AsQ==} @@ -2650,14 +3078,44 @@ packages: '@jspm/core@2.1.0': resolution: {integrity: sha512-3sRl+pkyFY/kLmHl0cgHiFp2xEqErA8N3ECjMs7serSUBmoJ70lBa0PG5t0IM6WJgdZNyyI0R8YFfi5wM8+mzg==} - '@mapbox/node-pre-gyp@1.0.11': - resolution: {integrity: sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==} - hasBin: true + '@lmdb/lmdb-darwin-arm64@3.2.6': + resolution: {integrity: sha512-yF/ih9EJJZc72psFQbwnn8mExIWfTnzWJg+N02hnpXtDPETYLmQswIMBn7+V88lfCaFrMozJsUvcEQIkEPU0Gg==} + cpu: [arm64] + os: [darwin] - '@mapbox/node-pre-gyp@2.0.0': - resolution: {integrity: sha512-llMXd39jtP0HpQLVI37Bf1m2ADlEb35GYSh1SDSLsBhR+5iCxiNGlT31yqbNtVHygHAtMy6dWFERpU2JgufhPg==} - engines: {node: '>=18'} - hasBin: true + '@lmdb/lmdb-darwin-x64@3.2.6': + resolution: {integrity: sha512-5BbCumsFLbCi586Bb1lTWQFkekdQUw8/t8cy++Uq251cl3hbDIGEwD9HAwh8H6IS2F6QA9KdKmO136LmipRNkg==} + cpu: [x64] + os: [darwin] + + '@lmdb/lmdb-linux-arm64@3.2.6': + resolution: {integrity: sha512-l5VmJamJ3nyMmeD1ANBQCQqy7do1ESaJQfKPSm2IG9/ADZryptTyCj8N6QaYgIWewqNUrcbdMkJajRQAt5Qjfg==} + cpu: [arm64] + os: [linux] + + '@lmdb/lmdb-linux-arm@3.2.6': + resolution: {integrity: sha512-+6XgLpMb7HBoWxXj+bLbiiB4s0mRRcDPElnRS3LpWRzdYSe+gFk5MT/4RrVNqd2MESUDmb53NUXw1+BP69bjiQ==} + cpu: [arm] + os: [linux] + + '@lmdb/lmdb-linux-x64@3.2.6': + resolution: {integrity: sha512-nDYT8qN9si5+onHYYaI4DiauDMx24OAiuZAUsEqrDy+ja/3EbpXPX/VAkMV8AEaQhy3xc4dRC+KcYIvOFefJ4Q==} + cpu: [x64] + os: [linux] + + '@lmdb/lmdb-win32-x64@3.2.6': + resolution: {integrity: sha512-XlqVtILonQnG+9fH2N3Aytria7P/1fwDgDhl29rde96uH2sLB8CHORIf2PfuLVzFQJ7Uqp8py9AYwr3ZUCFfWg==} + cpu: [x64] + os: [win32] + + '@mapbox/node-pre-gyp@1.0.11': + resolution: {integrity: sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==} + hasBin: true + + '@mapbox/node-pre-gyp@2.0.0': + resolution: {integrity: sha512-llMXd39jtP0HpQLVI37Bf1m2ADlEb35GYSh1SDSLsBhR+5iCxiNGlT31yqbNtVHygHAtMy6dWFERpU2JgufhPg==} + engines: {node: '>=18'} + hasBin: true '@mdn/browser-compat-data@5.7.6': resolution: {integrity: sha512-7xdrMX0Wk7grrTZQwAoy1GkvPMFoizStUoL+VmtUkAxegbCCec+3FKwOM6yc/uGU5+BEczQHXAlWiqvM8JeENg==} @@ -2665,6 +3123,142 @@ packages: '@mdx-js/mdx@3.1.1': resolution: {integrity: sha512-f6ZO2ifpwAQIpzGWaBQT2TXxPv6z3RBzQKpVftEWN78Vl/YweF1uwussDx8ECAXVtr3Rs89fKyG9YlzUs9DyGQ==} + '@msgpackr-extract/msgpackr-extract-darwin-arm64@3.0.3': + resolution: {integrity: sha512-QZHtlVgbAdy2zAqNA9Gu1UpIuI8Xvsd1v8ic6B2pZmeFnFcMWiPLfWXh7TVw4eGEZ/C9TH281KwhVoeQUKbyjw==} + cpu: [arm64] + os: [darwin] + + '@msgpackr-extract/msgpackr-extract-darwin-x64@3.0.3': + resolution: {integrity: sha512-mdzd3AVzYKuUmiWOQ8GNhl64/IoFGol569zNRdkLReh6LRLHOXxU4U8eq0JwaD8iFHdVGqSy4IjFL4reoWCDFw==} + cpu: [x64] + os: [darwin] + + '@msgpackr-extract/msgpackr-extract-linux-arm64@3.0.3': + resolution: {integrity: sha512-YxQL+ax0XqBJDZiKimS2XQaf+2wDGVa1enVRGzEvLLVFeqa5kx2bWbtcSXgsxjQB7nRqqIGFIcLteF/sHeVtQg==} + cpu: [arm64] + os: [linux] + + '@msgpackr-extract/msgpackr-extract-linux-arm@3.0.3': + resolution: {integrity: sha512-fg0uy/dG/nZEXfYilKoRe7yALaNmHoYeIoJuJ7KJ+YyU2bvY8vPv27f7UKhGRpY6euFYqEVhxCFZgAUNQBM3nw==} + cpu: [arm] + os: [linux] + + '@msgpackr-extract/msgpackr-extract-linux-x64@3.0.3': + resolution: {integrity: sha512-cvwNfbP07pKUfq1uH+S6KJ7dT9K8WOE4ZiAcsrSes+UY55E/0jLYc+vq+DO7jlmqRb5zAggExKm0H7O/CBaesg==} + cpu: [x64] + os: [linux] + + '@msgpackr-extract/msgpackr-extract-win32-x64@3.0.3': + resolution: {integrity: sha512-x0fWaQtYp4E6sktbsdAqnehxDgEc/VwM7uLsRCYWaiGu0ykYdZPiS8zCWdnjHwyiumousxfBm4SO31eXqwEZhQ==} + cpu: [x64] + os: [win32] + + '@napi-rs/nice-android-arm-eabi@1.1.1': + resolution: {integrity: sha512-kjirL3N6TnRPv5iuHw36wnucNqXAO46dzK9oPb0wj076R5Xm8PfUVA9nAFB5ZNMmfJQJVKACAPd/Z2KYMppthw==} + engines: {node: '>= 10'} + cpu: [arm] + os: [android] + + '@napi-rs/nice-android-arm64@1.1.1': + resolution: {integrity: sha512-blG0i7dXgbInN5urONoUCNf+DUEAavRffrO7fZSeoRMJc5qD+BJeNcpr54msPF6qfDD6kzs9AQJogZvT2KD5nw==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [android] + + '@napi-rs/nice-darwin-arm64@1.1.1': + resolution: {integrity: sha512-s/E7w45NaLqTGuOjC2p96pct4jRfo61xb9bU1unM/MJ/RFkKlJyJDx7OJI/O0ll/hrfpqKopuAFDV8yo0hfT7A==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + + '@napi-rs/nice-darwin-x64@1.1.1': + resolution: {integrity: sha512-dGoEBnVpsdcC+oHHmW1LRK5eiyzLwdgNQq3BmZIav+9/5WTZwBYX7r5ZkQC07Nxd3KHOCkgbHSh4wPkH1N1LiQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + + '@napi-rs/nice-freebsd-x64@1.1.1': + resolution: {integrity: sha512-kHv4kEHAylMYmlNwcQcDtXjklYp4FCf0b05E+0h6nDHsZ+F0bDe04U/tXNOqrx5CmIAth4vwfkjjUmp4c4JktQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [freebsd] + + '@napi-rs/nice-linux-arm-gnueabihf@1.1.1': + resolution: {integrity: sha512-E1t7K0efyKXZDoZg1LzCOLxgolxV58HCkaEkEvIYQx12ht2pa8hoBo+4OB3qh7e+QiBlp1SRf+voWUZFxyhyqg==} + engines: {node: '>= 10'} + cpu: [arm] + os: [linux] + + '@napi-rs/nice-linux-arm64-gnu@1.1.1': + resolution: {integrity: sha512-CIKLA12DTIZlmTaaKhQP88R3Xao+gyJxNWEn04wZwC2wmRapNnxCUZkVwggInMJvtVElA+D4ZzOU5sX4jV+SmQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@napi-rs/nice-linux-arm64-musl@1.1.1': + resolution: {integrity: sha512-+2Rzdb3nTIYZ0YJF43qf2twhqOCkiSrHx2Pg6DJaCPYhhaxbLcdlV8hCRMHghQ+EtZQWGNcS2xF4KxBhSGeutg==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@napi-rs/nice-linux-ppc64-gnu@1.1.1': + resolution: {integrity: sha512-4FS8oc0GeHpwvv4tKciKkw3Y4jKsL7FRhaOeiPei0X9T4Jd619wHNe4xCLmN2EMgZoeGg+Q7GY7BsvwKpL22Tg==} + engines: {node: '>= 10'} + cpu: [ppc64] + os: [linux] + + '@napi-rs/nice-linux-riscv64-gnu@1.1.1': + resolution: {integrity: sha512-HU0nw9uD4FO/oGCCk409tCi5IzIZpH2agE6nN4fqpwVlCn5BOq0MS1dXGjXaG17JaAvrlpV5ZeyZwSon10XOXw==} + engines: {node: '>= 10'} + cpu: [riscv64] + os: [linux] + + '@napi-rs/nice-linux-s390x-gnu@1.1.1': + resolution: {integrity: sha512-2YqKJWWl24EwrX0DzCQgPLKQBxYDdBxOHot1KWEq7aY2uYeX+Uvtv4I8xFVVygJDgf6/92h9N3Y43WPx8+PAgQ==} + engines: {node: '>= 10'} + cpu: [s390x] + os: [linux] + + '@napi-rs/nice-linux-x64-gnu@1.1.1': + resolution: {integrity: sha512-/gaNz3R92t+dcrfCw/96pDopcmec7oCcAQ3l/M+Zxr82KT4DljD37CpgrnXV+pJC263JkW572pdbP3hP+KjcIg==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@napi-rs/nice-linux-x64-musl@1.1.1': + resolution: {integrity: sha512-xScCGnyj/oppsNPMnevsBe3pvNaoK7FGvMjT35riz9YdhB2WtTG47ZlbxtOLpjeO9SqqQ2J2igCmz6IJOD5JYw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@napi-rs/nice-openharmony-arm64@1.1.1': + resolution: {integrity: sha512-6uJPRVwVCLDeoOaNyeiW0gp2kFIM4r7PL2MczdZQHkFi9gVlgm+Vn+V6nTWRcu856mJ2WjYJiumEajfSm7arPQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [openharmony] + + '@napi-rs/nice-win32-arm64-msvc@1.1.1': + resolution: {integrity: sha512-uoTb4eAvM5B2aj/z8j+Nv8OttPf2m+HVx3UjA5jcFxASvNhQriyCQF1OB1lHL43ZhW+VwZlgvjmP5qF3+59atA==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + + '@napi-rs/nice-win32-ia32-msvc@1.1.1': + resolution: {integrity: sha512-CNQqlQT9MwuCsg1Vd/oKXiuH+TcsSPJmlAFc5frFyX/KkOh0UpBLEj7aoY656d5UKZQMQFP7vJNa1DNUNORvug==} + engines: {node: '>= 10'} + cpu: [ia32] + os: [win32] + + '@napi-rs/nice-win32-x64-msvc@1.1.1': + resolution: {integrity: sha512-vB+4G/jBQCAh0jelMTY3+kgFy00Hlx2f2/1zjMoH821IbplbWZOkLiTYXQkygNTzQJTq5cvwBDgn2ppHD+bglQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + + '@napi-rs/nice@1.1.1': + resolution: {integrity: sha512-xJIPs+bYuc9ASBl+cvGsKbGrJmS6fAKaSZCnT0lhahT5rhA2VVy9/EcIgd2JhtEuFOJNx7UHNn/qiTPTY4nrQw==} + engines: {node: '>= 10'} + '@napi-rs/wasm-runtime@0.2.12': resolution: {integrity: sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==} @@ -2892,8 +3486,8 @@ packages: '@preact/signals-core@1.14.2': resolution: {integrity: sha512-RZHdBj9ZF4n40Rp4jS052EHHjBWf96P9oNdXPfhQTovCuWY9iQn3Gq+gOTJSgBO9A/JBuPfMOWsSX/lIU9Pc/A==} - '@preact/signals@2.9.0': - resolution: {integrity: sha512-hYrY0KyUqkDgOl1qba/JGn6y81pXnurn21PMaxfcMwdncdZ3M/oVdmpTvEnsGjh48dIwDVc7bjWHqIsngSjYug==} + '@preact/signals@2.9.1': + resolution: {integrity: sha512-xVqN8mJjbSN5IB/8Ubmd9NN+Ew6zJswoRxrjZbH3YsgkMshFeO6d8zxEFpHRTq9GJZx7cnPs2CnCpFqtGXGNsw==} peerDependencies: preact: '>= 10.25.0 || >=11.0.0-0' @@ -3220,111 +3814,236 @@ packages: cpu: [arm] os: [android] + '@rollup/rollup-android-arm-eabi@4.59.0': + resolution: {integrity: sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==} + cpu: [arm] + os: [android] + '@rollup/rollup-android-arm64@4.52.5': resolution: {integrity: sha512-mQGfsIEFcu21mvqkEKKu2dYmtuSZOBMmAl5CFlPGLY94Vlcm+zWApK7F/eocsNzp8tKmbeBP8yXyAbx0XHsFNA==} cpu: [arm64] os: [android] + '@rollup/rollup-android-arm64@4.59.0': + resolution: {integrity: sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q==} + cpu: [arm64] + os: [android] + '@rollup/rollup-darwin-arm64@4.52.5': resolution: {integrity: sha512-takF3CR71mCAGA+v794QUZ0b6ZSrgJkArC+gUiG6LB6TQty9T0Mqh3m2ImRBOxS2IeYBo4lKWIieSvnEk2OQWA==} cpu: [arm64] os: [darwin] + '@rollup/rollup-darwin-arm64@4.59.0': + resolution: {integrity: sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==} + cpu: [arm64] + os: [darwin] + '@rollup/rollup-darwin-x64@4.52.5': resolution: {integrity: sha512-W901Pla8Ya95WpxDn//VF9K9u2JbocwV/v75TE0YIHNTbhqUTv9w4VuQ9MaWlNOkkEfFwkdNhXgcLqPSmHy0fA==} cpu: [x64] os: [darwin] + '@rollup/rollup-darwin-x64@4.59.0': + resolution: {integrity: sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w==} + cpu: [x64] + os: [darwin] + '@rollup/rollup-freebsd-arm64@4.52.5': resolution: {integrity: sha512-QofO7i7JycsYOWxe0GFqhLmF6l1TqBswJMvICnRUjqCx8b47MTo46W8AoeQwiokAx3zVryVnxtBMcGcnX12LvA==} cpu: [arm64] os: [freebsd] + '@rollup/rollup-freebsd-arm64@4.59.0': + resolution: {integrity: sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA==} + cpu: [arm64] + os: [freebsd] + '@rollup/rollup-freebsd-x64@4.52.5': resolution: {integrity: sha512-jr21b/99ew8ujZubPo9skbrItHEIE50WdV86cdSoRkKtmWa+DDr6fu2c/xyRT0F/WazZpam6kk7IHBerSL7LDQ==} cpu: [x64] os: [freebsd] + '@rollup/rollup-freebsd-x64@4.59.0': + resolution: {integrity: sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg==} + cpu: [x64] + os: [freebsd] + '@rollup/rollup-linux-arm-gnueabihf@4.52.5': resolution: {integrity: sha512-PsNAbcyv9CcecAUagQefwX8fQn9LQ4nZkpDboBOttmyffnInRy8R8dSg6hxxl2Re5QhHBf6FYIDhIj5v982ATQ==} cpu: [arm] os: [linux] + '@rollup/rollup-linux-arm-gnueabihf@4.59.0': + resolution: {integrity: sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==} + cpu: [arm] + os: [linux] + '@rollup/rollup-linux-arm-musleabihf@4.52.5': resolution: {integrity: sha512-Fw4tysRutyQc/wwkmcyoqFtJhh0u31K+Q6jYjeicsGJJ7bbEq8LwPWV/w0cnzOqR2m694/Af6hpFayLJZkG2VQ==} cpu: [arm] os: [linux] + '@rollup/rollup-linux-arm-musleabihf@4.59.0': + resolution: {integrity: sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==} + cpu: [arm] + os: [linux] + '@rollup/rollup-linux-arm64-gnu@4.52.5': resolution: {integrity: sha512-a+3wVnAYdQClOTlyapKmyI6BLPAFYs0JM8HRpgYZQO02rMR09ZcV9LbQB+NL6sljzG38869YqThrRnfPMCDtZg==} cpu: [arm64] os: [linux] + '@rollup/rollup-linux-arm64-gnu@4.59.0': + resolution: {integrity: sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==} + cpu: [arm64] + os: [linux] + '@rollup/rollup-linux-arm64-musl@4.52.5': resolution: {integrity: sha512-AvttBOMwO9Pcuuf7m9PkC1PUIKsfaAJ4AYhy944qeTJgQOqJYJ9oVl2nYgY7Rk0mkbsuOpCAYSs6wLYB2Xiw0Q==} cpu: [arm64] os: [linux] + '@rollup/rollup-linux-arm64-musl@4.59.0': + resolution: {integrity: sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==} + cpu: [arm64] + os: [linux] + '@rollup/rollup-linux-loong64-gnu@4.52.5': resolution: {integrity: sha512-DkDk8pmXQV2wVrF6oq5tONK6UHLz/XcEVow4JTTerdeV1uqPeHxwcg7aFsfnSm9L+OO8WJsWotKM2JJPMWrQtA==} cpu: [loong64] os: [linux] + '@rollup/rollup-linux-loong64-gnu@4.59.0': + resolution: {integrity: sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==} + cpu: [loong64] + os: [linux] + + '@rollup/rollup-linux-loong64-musl@4.59.0': + resolution: {integrity: sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==} + cpu: [loong64] + os: [linux] + '@rollup/rollup-linux-ppc64-gnu@4.52.5': resolution: {integrity: sha512-W/b9ZN/U9+hPQVvlGwjzi+Wy4xdoH2I8EjaCkMvzpI7wJUs8sWJ03Rq96jRnHkSrcHTpQe8h5Tg3ZzUPGauvAw==} cpu: [ppc64] os: [linux] + '@rollup/rollup-linux-ppc64-gnu@4.59.0': + resolution: {integrity: sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==} + cpu: [ppc64] + os: [linux] + + '@rollup/rollup-linux-ppc64-musl@4.59.0': + resolution: {integrity: sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==} + cpu: [ppc64] + os: [linux] + '@rollup/rollup-linux-riscv64-gnu@4.52.5': resolution: {integrity: sha512-sjQLr9BW7R/ZiXnQiWPkErNfLMkkWIoCz7YMn27HldKsADEKa5WYdobaa1hmN6slu9oWQbB6/jFpJ+P2IkVrmw==} cpu: [riscv64] os: [linux] + '@rollup/rollup-linux-riscv64-gnu@4.59.0': + resolution: {integrity: sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==} + cpu: [riscv64] + os: [linux] + '@rollup/rollup-linux-riscv64-musl@4.52.5': resolution: {integrity: sha512-hq3jU/kGyjXWTvAh2awn8oHroCbrPm8JqM7RUpKjalIRWWXE01CQOf/tUNWNHjmbMHg/hmNCwc/Pz3k1T/j/Lg==} cpu: [riscv64] os: [linux] + '@rollup/rollup-linux-riscv64-musl@4.59.0': + resolution: {integrity: sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==} + cpu: [riscv64] + os: [linux] + '@rollup/rollup-linux-s390x-gnu@4.52.5': resolution: {integrity: sha512-gn8kHOrku8D4NGHMK1Y7NA7INQTRdVOntt1OCYypZPRt6skGbddska44K8iocdpxHTMMNui5oH4elPH4QOLrFQ==} cpu: [s390x] os: [linux] + '@rollup/rollup-linux-s390x-gnu@4.59.0': + resolution: {integrity: sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==} + cpu: [s390x] + os: [linux] + '@rollup/rollup-linux-x64-gnu@4.52.5': resolution: {integrity: sha512-hXGLYpdhiNElzN770+H2nlx+jRog8TyynpTVzdlc6bndktjKWyZyiCsuDAlpd+j+W+WNqfcyAWz9HxxIGfZm1Q==} cpu: [x64] os: [linux] + '@rollup/rollup-linux-x64-gnu@4.59.0': + resolution: {integrity: sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==} + cpu: [x64] + os: [linux] + '@rollup/rollup-linux-x64-musl@4.52.5': resolution: {integrity: sha512-arCGIcuNKjBoKAXD+y7XomR9gY6Mw7HnFBv5Rw7wQRvwYLR7gBAgV7Mb2QTyjXfTveBNFAtPt46/36vV9STLNg==} cpu: [x64] os: [linux] + '@rollup/rollup-linux-x64-musl@4.59.0': + resolution: {integrity: sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-openbsd-x64@4.59.0': + resolution: {integrity: sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==} + cpu: [x64] + os: [openbsd] + '@rollup/rollup-openharmony-arm64@4.52.5': resolution: {integrity: sha512-QoFqB6+/9Rly/RiPjaomPLmR/13cgkIGfA40LHly9zcH1S0bN2HVFYk3a1eAyHQyjs3ZJYlXvIGtcCs5tko9Cw==} cpu: [arm64] os: [openharmony] + '@rollup/rollup-openharmony-arm64@4.59.0': + resolution: {integrity: sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA==} + cpu: [arm64] + os: [openharmony] + '@rollup/rollup-win32-arm64-msvc@4.52.5': resolution: {integrity: sha512-w0cDWVR6MlTstla1cIfOGyl8+qb93FlAVutcor14Gf5Md5ap5ySfQ7R9S/NjNaMLSFdUnKGEasmVnu3lCMqB7w==} cpu: [arm64] os: [win32] + '@rollup/rollup-win32-arm64-msvc@4.59.0': + resolution: {integrity: sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A==} + cpu: [arm64] + os: [win32] + '@rollup/rollup-win32-ia32-msvc@4.52.5': resolution: {integrity: sha512-Aufdpzp7DpOTULJCuvzqcItSGDH73pF3ko/f+ckJhxQyHtp67rHw3HMNxoIdDMUITJESNE6a8uh4Lo4SLouOUg==} cpu: [ia32] os: [win32] + '@rollup/rollup-win32-ia32-msvc@4.59.0': + resolution: {integrity: sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA==} + cpu: [ia32] + os: [win32] + '@rollup/rollup-win32-x64-gnu@4.52.5': resolution: {integrity: sha512-UGBUGPFp1vkj6p8wCRraqNhqwX/4kNQPS57BCFc8wYh0g94iVIW33wJtQAx3G7vrjjNtRaxiMUylM0ktp/TRSQ==} cpu: [x64] os: [win32] + '@rollup/rollup-win32-x64-gnu@4.59.0': + resolution: {integrity: sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA==} + cpu: [x64] + os: [win32] + '@rollup/rollup-win32-x64-msvc@4.52.5': resolution: {integrity: sha512-TAcgQh2sSkykPRWLrdyy2AiceMckNf5loITqXxFI5VuQjS5tSuw3WlwdN8qv8vzjLAUTvYaH/mVjSFpbkFbpTg==} cpu: [x64] os: [win32] + '@rollup/rollup-win32-x64-msvc@4.59.0': + resolution: {integrity: sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA==} + cpu: [x64] + os: [win32] + '@rtsao/scc@1.1.0': resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==} @@ -3753,6 +4472,9 @@ packages: '@ts-morph/common@0.11.1': resolution: {integrity: sha512-7hWZS0NRpEsNV8vWJzg7FEz6V8MaLNeJOmwmghqUXTpzk16V1LLZhdo+4QvE/+zv4cVci0OviuJFnqhEfoV3+g==} + '@ts-morph/common@0.22.0': + resolution: {integrity: sha512-HqNBuV/oIlMKdkLshXd1zKBqNQCsuPEsgQOkfFQ/eUKjRlwndXW1AjN9LVkBEIukm00gGXSRmfkl0Wv5VXLnlw==} + '@tsconfig/node10@1.0.11': resolution: {integrity: sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==} @@ -4181,6 +4903,12 @@ packages: peerDependencies: vinxi: ^0.5.5 + '@vitejs/plugin-basic-ssl@1.2.0': + resolution: {integrity: sha512-mkQnxTkcldAzIsomk1UuLfAu9n+kpQ3JbHcpCp7d2Oo6ITtji8pHS3QToOWjhPFvNQSnhlkAjmGbhv2QvwO/7Q==} + engines: {node: '>=14.21.3'} + peerDependencies: + vite: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 + '@vitejs/plugin-react@5.1.1': resolution: {integrity: sha512-WQfkSw0QbQ5aJ2CHYw23ZGkqnRwqKHD/KYsMeTkZzPT4Jcf0DcBxBtwMJxnu6E7oxw5+JC6ZAiePgh28uJ1HBA==} engines: {node: ^20.19.0 || >=22.12.0} @@ -4402,9 +5130,20 @@ packages: resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==} engines: {node: '>=8'} + ajv-formats@3.0.1: + resolution: {integrity: sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==} + peerDependencies: + ajv: ^8.0.0 + peerDependenciesMeta: + ajv: + optional: true + ajv@6.12.6: resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + ajv@8.18.0: + resolution: {integrity: sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==} + ajv@8.6.3: resolution: {integrity: sha512-SMJOdDP6LqTkD0Uq8qLi+gMwSt0imXLSV080qFVwJCpH9U6Mb+SUGHAXM0KNbcBPguytWyvFxcHgMLe2D2XSpw==} @@ -4418,6 +5157,10 @@ packages: resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} engines: {node: '>=8'} + ansi-escapes@7.3.0: + resolution: {integrity: sha512-BvU8nYgGQBxcmMuEeUEmNTvrMVjJNSH7RgW24vXexN4Ven6qCvy4TntnvlnwnMLTVlcRQQdbRY8NKnaIoeWDNg==} + engines: {node: '>=18'} + ansi-regex@5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} @@ -4663,6 +5406,10 @@ packages: resolution: {integrity: sha512-JMWsdF+O8Orq3EMukbUN1QfbLK9mX2CkUmQBcW2T0s8OmdAUL5LLM/6wFwSrqXzlXB13yhyK9gTKS1rIizOduQ==} hasBin: true + beasties@0.3.2: + resolution: {integrity: sha512-p4AF8uYzm9Fwu8m/hSVTCPXrRBPmB34hQpHsec2KOaR9CZmgoU8IOv4Cvwq4hgz2p4hLMNbsdNl5XeA6XbAQwA==} + engines: {node: '>=14.0.0'} + before-after-hook@4.0.0: resolution: {integrity: sha512-q6tR3RPqIB1pMiTRMFcZwuG5T8vwp+vUvEG0vuI6B+Rikh5BfPp2fQ82c925FOs+b0lcFQ8CFrL+KbilfZFhOQ==} @@ -4863,14 +5610,26 @@ packages: resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} engines: {node: '>=8'} + cli-cursor@5.0.0: + resolution: {integrity: sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==} + engines: {node: '>=18'} + cli-spinners@2.9.2: resolution: {integrity: sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==} engines: {node: '>=6'} + cli-truncate@4.0.0: + resolution: {integrity: sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==} + engines: {node: '>=18'} + cli-width@3.0.0: resolution: {integrity: sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==} engines: {node: '>= 10'} + cli-width@4.1.0: + resolution: {integrity: sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==} + engines: {node: '>= 12'} + clipboardy@4.0.0: resolution: {integrity: sha512-5mOlNS0mhX0707P2I0aZ2V/cmHUEO/fL7VFLqszkhUsxt7RwnmrInf/eEQKlf5GzvYeHIjT+Ov1HRfNmymlG0w==} engines: {node: '>=18'} @@ -4897,6 +5656,9 @@ packages: code-block-writer@10.1.1: resolution: {integrity: sha512-67ueh2IRGst/51p0n6FvPrnRjAGHY5F8xdjkgrYE7DDzpJe6qA07RYQ9VcoUeo5ATOjSOiWpSL3SWBRRbempMw==} + code-block-writer@12.0.0: + resolution: {integrity: sha512-q4dMFMlXtKR3XNBHyMHt/3pwYNA69EDk00lloMOaaUMKPUXBw6lpXtbu3MMVG6/uOihGnRDOlkyqsONEUj60+w==} + collapse-white-space@2.1.0: resolution: {integrity: sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==} @@ -4988,6 +5750,9 @@ packages: resolution: {integrity: sha512-7V+KqSvMiHp8yWDuwfww06XleMWVVB9b9tURBx+G7UTADuo5hYPuowKloz4OzOqbPezxgo+fdQ1522WzPG4OeA==} engines: {node: '>=8'} + convert-source-map@1.9.0: + resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} + convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} @@ -5452,6 +6217,14 @@ packages: resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==} engines: {node: '>=0.12'} + entities@7.0.1: + resolution: {integrity: sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==} + engines: {node: '>=0.12'} + + environment@1.1.0: + resolution: {integrity: sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==} + engines: {node: '>=18'} + errno@0.1.8: resolution: {integrity: sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==} hasBin: true @@ -5788,6 +6561,11 @@ packages: engines: {node: '>=18'} hasBin: true + esbuild@0.28.0: + resolution: {integrity: sha512-sNR9MHpXSUV/XB4zmsFKN+QgVG82Cc7+/aaxJ8Adi8hyOac+EXptIp45QBPaVyX3N70664wRbTcLTOemCAnyqw==} + engines: {node: '>=18'} + hasBin: true + escalade@3.2.0: resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} engines: {node: '>=6'} @@ -6087,6 +6865,9 @@ packages: eventemitter3@4.0.7: resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} + eventemitter3@5.0.4: + resolution: {integrity: sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==} + events-universal@1.0.1: resolution: {integrity: sha512-LUd5euvbMLpwOF8m6ivPCbhQeSiYVNb8Vs0fQ8QjXo0JTkEHpz8pxdQf0gStltaPpw0Cca8b39KxvK9cfKRiAw==} @@ -6147,6 +6928,9 @@ packages: fast-levenshtein@2.0.6: resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + fast-uri@3.1.2: + resolution: {integrity: sha512-rVjf7ArG3LTk+FS6Yw81V1DLuZl1bRbNrev6Tmd/9RaroeeRRJhAt7jg/6YFxbvAQXUCavSoZhPPj6oOx+5KjQ==} + fastq@1.19.1: resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==} @@ -6365,6 +7149,9 @@ packages: resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} engines: {node: '>=10.13.0'} + glob-to-regexp@0.4.1: + resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} + glob@10.4.5: resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} hasBin: true @@ -6535,6 +7322,9 @@ packages: html-void-elements@3.0.0: resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==} + htmlparser2@10.1.0: + resolution: {integrity: sha512-VTZkM9GWRAtEpveh7MSF6SjjrpNVNNVJfFup7xTY3UpFtm67foy9HDVXneLtFVt4pMz5kZtgNcvCniNFb1hlEQ==} + http-cache-semantics@4.2.0: resolution: {integrity: sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==} @@ -6774,6 +7564,14 @@ packages: resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} engines: {node: '>=8'} + is-fullwidth-code-point@4.0.0: + resolution: {integrity: sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==} + engines: {node: '>=12'} + + is-fullwidth-code-point@5.1.0: + resolution: {integrity: sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ==} + engines: {node: '>=18'} + is-generator-function@1.1.2: resolution: {integrity: sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==} engines: {node: '>= 0.4'} @@ -6937,6 +7735,10 @@ packages: resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} engines: {node: '>=8'} + istanbul-lib-instrument@6.0.3: + resolution: {integrity: sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==} + engines: {node: '>=10'} + istanbul-lib-report@3.0.1: resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} engines: {node: '>=10'} @@ -7051,6 +7853,9 @@ packages: engines: {node: '>=6'} hasBin: true + jsonc-parser@3.3.1: + resolution: {integrity: sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==} + jsonfile@4.0.0: resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} @@ -7196,6 +8001,14 @@ packages: resolution: {integrity: sha512-I8oW2+QL5KJo8zXNWX046M134WchxsXC7SawLPvRQpogCbkyQIaFxPE89A2HiwR7vAK2Dm2ERBAmyjTYGYEpBg==} hasBin: true + listr2@8.2.5: + resolution: {integrity: sha512-iyAZCeyD+c1gPyE9qpFu8af0Y+MRtmKOncdGoA2S5EY8iFq99dmmvkNnHiWo+pj0s7yH7l3KPIgee77tKpXPWQ==} + engines: {node: '>=18.0.0'} + + lmdb@3.2.6: + resolution: {integrity: sha512-SuHqzPl7mYStna8WRotY8XX/EUZBjjv3QyKIByeCLFfC9uXT/OIHByEcA07PzbMfQAM0KYJtLgtpMRlIe5dErQ==} + hasBin: true + load-tsconfig@0.2.5: resolution: {integrity: sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -7247,6 +8060,10 @@ packages: resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} engines: {node: '>=10'} + log-update@6.1.0: + resolution: {integrity: sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==} + engines: {node: '>=18'} + longest-streak@3.1.0: resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==} @@ -7279,6 +8096,9 @@ packages: resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} hasBin: true + magic-string@0.30.17: + resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==} + magic-string@0.30.21: resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} @@ -7631,6 +8451,10 @@ packages: resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} engines: {node: '>=12'} + mimic-function@5.0.1: + resolution: {integrity: sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==} + engines: {node: '>=18'} + mimic-response@1.0.1: resolution: {integrity: sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==} engines: {node: '>=4'} @@ -7700,6 +8524,11 @@ packages: engines: {node: '>=10'} hasBin: true + mkdirp@3.0.1: + resolution: {integrity: sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==} + engines: {node: '>=10'} + hasBin: true + mlly@1.8.0: resolution: {integrity: sha512-l8D9ODSRWLe2KHJSifWGwBqpTZXIXTeo8mlKjY+E2HAakaTeNpqAyBZ8GSqLzHgw4XmHmC8whvpjJNMbFZN7/g==} @@ -7720,12 +8549,23 @@ packages: ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + msgpackr-extract@3.0.3: + resolution: {integrity: sha512-P0efT1C9jIdVRefqjzOQ9Xml57zpOXnIuS+csaB4MdZbTdmGDLo8XhzBG1N7aO11gKDDkJvBLULeFTo46wwreA==} + hasBin: true + + msgpackr@1.11.12: + resolution: {integrity: sha512-RBdJ1Un7yGlXWajrkxcSa93nvQ0w4zBf60c0yYv7YtBelP8H2FA7XsfBbMHtXKXUMUxH7zV3Zuozh+kUQWhHvg==} + muggle-string@0.4.1: resolution: {integrity: sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==} mute-stream@0.0.8: resolution: {integrity: sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==} + mute-stream@2.0.0: + resolution: {integrity: sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==} + engines: {node: ^18.17.0 || >=20.5.0} + mz@2.7.0: resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} @@ -7768,6 +8608,9 @@ packages: node-addon-api@1.7.2: resolution: {integrity: sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg==} + node-addon-api@6.1.0: + resolution: {integrity: sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==} + node-addon-api@7.1.1: resolution: {integrity: sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==} @@ -7796,6 +8639,10 @@ packages: resolution: {integrity: sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==} engines: {node: '>= 6.13.0'} + node-gyp-build-optional-packages@5.2.2: + resolution: {integrity: sha512-s+w+rBWnpTMwSFbaE0UXsRlg7hU4FjekKU4eyAih5T8nJuNZT1nNsskXpxmeqSK9UzkBl6UgRlnKc8hz8IEqOw==} + hasBin: true + node-gyp-build@4.8.4: resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==} hasBin: true @@ -7924,6 +8771,10 @@ packages: resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} engines: {node: '>=12'} + onetime@7.0.0: + resolution: {integrity: sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==} + engines: {node: '>=18'} + oniguruma-parser@0.12.1: resolution: {integrity: sha512-8Unqkvk1RYc6yq2WBYRj4hdnsAxVze8i7iPfQr8e4uSP3tRv0rpZcbGUDvxfQQcdwHt/e9PrMvGCsa8OqG9X3w==} @@ -7953,6 +8804,9 @@ packages: resolution: {integrity: sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==} engines: {node: '>=10'} + ordered-binary@1.6.1: + resolution: {integrity: sha512-QkCdPooczexPLiXIrbVOPYkR3VO3T6v2OyKRkR1Xbhpy7/LAVXwahnRCgRp78Oe/Ehf0C/HATAxfSr6eA1oX+w==} + outdent@0.8.0: resolution: {integrity: sha512-KiOAIsdpUTcAXuykya5fnVVT+/5uS0Q1mrkRHcF89tpieSmY33O/tmc54CqwA+bfhbtEfZUNLHaPUiB9X3jt1A==} @@ -8017,6 +8871,12 @@ packages: parse-statements@1.0.11: resolution: {integrity: sha512-HlsyYdMBnbPQ9Jr/VgJ1YF4scnldvJpJxCVx6KgqPL4dxppsWrJHCIIxQXMJrqGnsRkNPATbeMJ8Yxu7JMsYcA==} + parse5-html-rewriting-stream@7.0.0: + resolution: {integrity: sha512-mazCyGWkmCRWDI15Zp+UiCqMp/0dgEmkZRvhlsqqKYr4SsVm/TvnSpD9fCvqCA2zoWJcfRym846ejWBBHRiYEg==} + + parse5-sax-parser@7.0.0: + resolution: {integrity: sha512-5A+v2SNsq8T6/mG3ahcz8ZtQ0OUFTatxPbeidoMB7tkJSGDY3tdfl4MHovtLQHkEn5CGxijNWRQHhRQ6IRpXKg==} + parse5@7.3.0: resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==} @@ -8103,6 +8963,10 @@ packages: resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} engines: {node: '>=12'} + picomatch@4.0.4: + resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==} + engines: {node: '>=12'} + pidtree@0.6.0: resolution: {integrity: sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==} engines: {node: '>=0.10'} @@ -8116,6 +8980,9 @@ packages: resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==} engines: {node: '>= 6'} + piscina@4.8.0: + resolution: {integrity: sha512-EZJb+ZxDrQf3dihsUL7p42pjNyrNIFJCrRHPMgxu/svsj+P3xS3fuEWp7k2+rfsavfl1N0G29b1HGs7J0m8rZA==} + pkg-types@1.3.1: resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==} @@ -8174,6 +9041,9 @@ packages: yaml: optional: true + postcss-media-query-parser@0.2.3: + resolution: {integrity: sha512-3sOlxmbKcSHMjlUXQZKQ06jOswE7oVkXPxmZdoB1r5l0q6gTFTQSHxNxOrCccElbW7dxNytifNEo8qidX2Vsig==} + postcss-modules-extract-imports@3.1.0: resolution: {integrity: sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q==} engines: {node: ^10 || ^12 || >= 14} @@ -8542,6 +9412,9 @@ packages: resolution: {integrity: sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A==} engines: {node: '>=4'} + reflect-metadata@0.2.2: + resolution: {integrity: sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==} + reflect.getprototypeof@1.0.10: resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==} engines: {node: '>= 0.4'} @@ -8665,6 +9538,10 @@ packages: resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==} engines: {node: '>=8'} + restore-cursor@5.1.0: + resolution: {integrity: sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==} + engines: {node: '>=18'} + reusify@1.1.0: resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} @@ -8742,7 +9619,12 @@ packages: engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true - rrweb-cssom@0.8.0: + rollup@4.59.0: + resolution: {integrity: sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + + rrweb-cssom@0.8.0: resolution: {integrity: sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==} run-applescript@7.1.0: @@ -8756,6 +9638,9 @@ packages: run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + rxjs@7.8.1: + resolution: {integrity: sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==} + rxjs@7.8.2: resolution: {integrity: sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==} @@ -8787,6 +9672,11 @@ packages: safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + sass@1.85.0: + resolution: {integrity: sha512-3ToiC1xZ1Y8aU7+CkgCI/tqyuPXEmYGJXO7H4uqp0xkLXUqp88rQQ4j1HmP37xSJLbCJPaIiv+cT1y+grssrww==} + engines: {node: '>=14.0.0'} + hasBin: true + sass@1.93.2: resolution: {integrity: sha512-t+YPtOQHpGW1QWsh1CHQ5cPIr9lbbGZLZnbihP/D/qZj/yuV68m8qarcV17nvkOX81BCrvzAlq2klCQFZghyTg==} engines: {node: '>=14.0.0'} @@ -8836,6 +9726,11 @@ packages: engines: {node: '>=10'} hasBin: true + semver@7.7.1: + resolution: {integrity: sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==} + engines: {node: '>=10'} + hasBin: true + semver@7.7.3: resolution: {integrity: sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==} engines: {node: '>=10'} @@ -8964,6 +9859,14 @@ packages: resolution: {integrity: sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==} engines: {node: '>=14.16'} + slice-ansi@5.0.0: + resolution: {integrity: sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==} + engines: {node: '>=12'} + + slice-ansi@7.1.2: + resolution: {integrity: sha512-iOBWFgUX7caIZiuutICxVgX1SdxwAVFFKwt1EvMYYec/NWO5meOJ6K5uQxhrYBdQJne4KxiqZc+KptFOWFSI9w==} + engines: {node: '>=18'} + smart-buffer@4.2.0: resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==} engines: {node: '>= 6.0.0', npm: '>= 3.0.0'} @@ -9011,6 +9914,10 @@ packages: resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} engines: {node: '>=0.10.0'} + source-map@0.7.4: + resolution: {integrity: sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==} + engines: {node: '>= 8'} + source-map@0.7.6: resolution: {integrity: sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==} engines: {node: '>= 12'} @@ -9397,6 +10304,9 @@ packages: ts-morph@12.0.0: resolution: {integrity: sha512-VHC8XgU2fFW7yO1f/b3mxKDje1vmyzFXHWzOYmKEkCEwcLjDtbdLgBQviqj4ZwP4MJkQtRo6Ha2I29lq/B+VxA==} + ts-morph@21.0.1: + resolution: {integrity: sha512-dbDtVdEAncKctzrVZ+Nr7kHpHkv+0JDJb2MjjpBaj8bFeCkePU9rHfMklmhuLFnpeq/EJZk2IhStY6NzqgjOkg==} + ts-node@10.9.1: resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} hasBin: true @@ -9867,6 +10777,14 @@ packages: v8-compile-cache-lib@3.0.1: resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} + valibot@1.2.0: + resolution: {integrity: sha512-mm1rxUsmOxzrwnX5arGS+U4T25RdvpPjPN4yR0u9pUBov9+zGVtO84tif1eY4r6zWxVxu3KzIyknJy3rxfRZZg==} + peerDependencies: + typescript: '>=5' + peerDependenciesMeta: + typescript: + optional: true + valibot@1.4.1: resolution: {integrity: sha512-klCmFTz2jeDluy9RwX+F884TCiogtdBJ/YaxSx1EOBYXa3NXNWj8kR1jjN8rzluwojJVWWaHJ4r1U5LfICnM3g==} peerDependencies: @@ -10045,6 +10963,46 @@ packages: yaml: optional: true + vite@6.4.2: + resolution: {integrity: sha512-2N/55r4JDJ4gdrCvGgINMy+HH3iRpNIz8K6SFwVsA+JbQScLiC+clmAxBgwiSPgcG9U15QmvqCGWzMbqda5zGQ==} + engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 + jiti: '>=1.21.0' + less: '*' + lightningcss: ^1.21.0 + sass: '*' + sass-embedded: '*' + stylus: '*' + sugarss: '*' + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + '@types/node': + optional: true + jiti: + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + vite@7.0.4: resolution: {integrity: sha512-SkaSguuS7nnmV7mfJ8l81JGBFV7Gvzp8IzgE8A8t23+AxuNX61Q5H1Tpz5efduSN7NHC8nQXD3sKQKZAu5mNEA==} engines: {node: ^20.19.0 || >=22.12.0} @@ -10241,9 +11199,16 @@ packages: resolution: {integrity: sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==} engines: {node: '>=18'} + watchpack@2.4.2: + resolution: {integrity: sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==} + engines: {node: '>=10.13.0'} + wcwidth@1.0.1: resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==} + weak-lru-cache@1.2.2: + resolution: {integrity: sha512-DEAoo25RfSYMuTGc9vPJzZcZullwIqRDSI9LOy+fkCJPi6hykCnfKaXTuPBDuXAUcqHXyOgFtHNp/kB2FjYHbw==} + web-vitals@0.2.4: resolution: {integrity: sha512-6BjspCO9VriYy12z356nL6JBS0GYeEcA457YyRzD+dD6XYCQ75NKhcOHUMHentOE7OcVCIXXDvOm0jKFfQG2Gg==} @@ -10444,6 +11409,10 @@ packages: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} + yoctocolors-cjs@2.1.3: + resolution: {integrity: sha512-U/PBtDf35ff0D8X8D0jfdzHYEPFxAI7jJlxZXwCSez5M3190m+QobIfh+sWDWSHMCWWJN2AWamkegn6vr6YBTw==} + engines: {node: '>=18'} + yoga-wasm-web@0.3.3: resolution: {integrity: sha512-N+d4UJSJbt/R3wqY7Coqs5pcV0aUj2j9IaQ3rNj9bVCLld8tTGKRa2USARjnvZJWVx1NDmQev8EknoczaOQDOA==} @@ -10475,6 +11444,9 @@ packages: zod@3.25.76: resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} + zone.js@0.15.1: + resolution: {integrity: sha512-XE96n56IQpJM7NAoXswY3XRLcWFW83xe0BiAOeMD7K5k5xecOeul3Qcpx6GqEeeHNkW5DWL5zOyTbEfB4eti8w==} + zwitch@2.0.4: resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} @@ -10490,8 +11462,129 @@ snapshots: '@jridgewell/gen-mapping': 0.3.13 '@jridgewell/trace-mapping': 0.3.31 - '@angular/core@21.2.13(rxjs@7.8.2)': + '@analogjs/vite-plugin-angular@1.22.5(@angular/build@19.2.26(@angular/compiler-cli@19.2.22(@angular/compiler@19.2.22)(typescript@5.8.3))(@angular/compiler@19.2.22)(@types/node@24.10.1)(chokidar@4.0.3)(jiti@2.6.1)(less@4.4.2)(lightningcss@1.30.2)(postcss@8.5.6)(stylus@0.62.0)(tailwindcss@4.1.17)(terser@5.44.0)(tsx@4.20.6)(typescript@5.8.3)(yaml@2.8.1))': + dependencies: + ts-morph: 21.0.1 + vfile: 6.0.3 + optionalDependencies: + '@angular/build': 19.2.26(@angular/compiler-cli@19.2.22(@angular/compiler@19.2.22)(typescript@5.8.3))(@angular/compiler@19.2.22)(@types/node@24.10.1)(chokidar@4.0.3)(jiti@2.6.1)(less@4.4.2)(lightningcss@1.30.2)(postcss@8.5.6)(stylus@0.62.0)(tailwindcss@4.1.17)(terser@5.44.0)(tsx@4.20.6)(typescript@5.8.3)(yaml@2.8.1) + + '@angular-devkit/architect@0.1902.26(chokidar@4.0.3)': + dependencies: + '@angular-devkit/core': 19.2.26(chokidar@4.0.3) + rxjs: 7.8.1 + transitivePeerDependencies: + - chokidar + + '@angular-devkit/core@19.2.26(chokidar@4.0.3)': + dependencies: + ajv: 8.18.0 + ajv-formats: 3.0.1(ajv@8.18.0) + jsonc-parser: 3.3.1 + picomatch: 4.0.4 + rxjs: 7.8.1 + source-map: 0.7.4 + optionalDependencies: + chokidar: 4.0.3 + + '@angular/build@19.2.26(@angular/compiler-cli@19.2.22(@angular/compiler@19.2.22)(typescript@5.8.3))(@angular/compiler@19.2.22)(@types/node@24.10.1)(chokidar@4.0.3)(jiti@2.6.1)(less@4.4.2)(lightningcss@1.30.2)(postcss@8.5.6)(stylus@0.62.0)(tailwindcss@4.1.17)(terser@5.44.0)(tsx@4.20.6)(typescript@5.8.3)(yaml@2.8.1)': + dependencies: + '@ampproject/remapping': 2.3.0 + '@angular-devkit/architect': 0.1902.26(chokidar@4.0.3) + '@angular/compiler': 19.2.22 + '@angular/compiler-cli': 19.2.22(@angular/compiler@19.2.22)(typescript@5.8.3) + '@babel/core': 7.26.10 + '@babel/helper-annotate-as-pure': 7.25.9 + '@babel/helper-split-export-declaration': 7.24.7 + '@babel/plugin-syntax-import-attributes': 7.26.0(@babel/core@7.26.10) + '@inquirer/confirm': 5.1.6(@types/node@24.10.1) + '@vitejs/plugin-basic-ssl': 1.2.0(vite@6.4.2(@types/node@24.10.1)(jiti@2.6.1)(less@4.4.2)(lightningcss@1.30.2)(sass@1.85.0)(stylus@0.62.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) + beasties: 0.3.2 + browserslist: 4.27.0 + esbuild: 0.28.0 + fast-glob: 3.3.3 + https-proxy-agent: 7.0.6 + istanbul-lib-instrument: 6.0.3 + listr2: 8.2.5 + magic-string: 0.30.17 + mrmime: 2.0.1 + parse5-html-rewriting-stream: 7.0.0 + picomatch: 4.0.4 + piscina: 4.8.0 + rollup: 4.59.0 + sass: 1.85.0 + semver: 7.7.1 + source-map-support: 0.5.21 + typescript: 5.8.3 + vite: 6.4.2(@types/node@24.10.1)(jiti@2.6.1)(less@4.4.2)(lightningcss@1.30.2)(sass@1.85.0)(stylus@0.62.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) + watchpack: 2.4.2 + optionalDependencies: + less: 4.4.2 + lmdb: 3.2.6 + postcss: 8.5.6 + tailwindcss: 4.1.17 + transitivePeerDependencies: + - '@types/node' + - chokidar + - jiti + - lightningcss + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + - tsx + - yaml + + '@angular/common@19.2.22(@angular/core@19.2.22(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2)': dependencies: + '@angular/core': 19.2.22(rxjs@7.8.2)(zone.js@0.15.1) + rxjs: 7.8.2 + tslib: 2.8.1 + + '@angular/compiler-cli@19.2.22(@angular/compiler@19.2.22)(typescript@5.8.3)': + dependencies: + '@angular/compiler': 19.2.22 + '@babel/core': 7.26.9 + '@jridgewell/sourcemap-codec': 1.5.5 + chokidar: 4.0.3 + convert-source-map: 1.9.0 + reflect-metadata: 0.2.2 + semver: 7.7.3 + tslib: 2.8.1 + typescript: 5.8.3 + yargs: 17.7.2 + transitivePeerDependencies: + - supports-color + + '@angular/compiler@19.2.22': + dependencies: + tslib: 2.8.1 + + '@angular/core@19.2.22(rxjs@7.8.2)(zone.js@0.15.1)': + dependencies: + rxjs: 7.8.2 + tslib: 2.8.1 + zone.js: 0.15.1 + + '@angular/core@21.2.13(rxjs@7.8.2)(zone.js@0.15.1)': + dependencies: + rxjs: 7.8.2 + tslib: 2.8.1 + optionalDependencies: + zone.js: 0.15.1 + + '@angular/platform-browser@19.2.22(@angular/common@19.2.22(@angular/core@19.2.22(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.22(rxjs@7.8.2)(zone.js@0.15.1))': + dependencies: + '@angular/common': 19.2.22(@angular/core@19.2.22(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2) + '@angular/core': 19.2.22(rxjs@7.8.2)(zone.js@0.15.1) + tslib: 2.8.1 + + '@angular/router@19.2.22(@angular/common@19.2.22(@angular/core@19.2.22(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.22(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@19.2.22(@angular/common@19.2.22(@angular/core@19.2.22(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.22(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2)': + dependencies: + '@angular/common': 19.2.22(@angular/core@19.2.22(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2) + '@angular/core': 19.2.22(rxjs@7.8.2)(zone.js@0.15.1) + '@angular/platform-browser': 19.2.22(@angular/common@19.2.22(@angular/core@19.2.22(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.22(rxjs@7.8.2)(zone.js@0.15.1)) rxjs: 7.8.2 tslib: 2.8.1 @@ -10517,6 +11610,46 @@ snapshots: '@babel/compat-data@7.28.5': {} + '@babel/core@7.26.10': + dependencies: + '@ampproject/remapping': 2.3.0 + '@babel/code-frame': 7.27.1 + '@babel/generator': 7.28.5 + '@babel/helper-compilation-targets': 7.27.2 + '@babel/helper-module-transforms': 7.28.3(@babel/core@7.26.10) + '@babel/helpers': 7.28.4 + '@babel/parser': 7.28.5 + '@babel/template': 7.27.2 + '@babel/traverse': 7.28.5 + '@babel/types': 7.28.5 + convert-source-map: 2.0.0 + debug: 4.4.3 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/core@7.26.9': + dependencies: + '@ampproject/remapping': 2.3.0 + '@babel/code-frame': 7.27.1 + '@babel/generator': 7.28.5 + '@babel/helper-compilation-targets': 7.27.2 + '@babel/helper-module-transforms': 7.28.3(@babel/core@7.26.9) + '@babel/helpers': 7.28.4 + '@babel/parser': 7.28.5 + '@babel/template': 7.27.2 + '@babel/traverse': 7.28.5 + '@babel/types': 7.28.5 + convert-source-map: 2.0.0 + debug: 4.4.3 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + '@babel/core@7.28.5': dependencies: '@babel/code-frame': 7.27.1 @@ -10553,6 +11686,10 @@ snapshots: '@jridgewell/trace-mapping': 0.3.31 jsesc: 3.1.0 + '@babel/helper-annotate-as-pure@7.25.9': + dependencies: + '@babel/types': 7.28.5 + '@babel/helper-annotate-as-pure@7.27.3': dependencies: '@babel/types': 7.28.5 @@ -10616,6 +11753,24 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/helper-module-transforms@7.28.3(@babel/core@7.26.10)': + dependencies: + '@babel/core': 7.26.10 + '@babel/helper-module-imports': 7.27.1 + '@babel/helper-validator-identifier': 7.28.5 + '@babel/traverse': 7.28.5 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-transforms@7.28.3(@babel/core@7.26.9)': + dependencies: + '@babel/core': 7.26.9 + '@babel/helper-module-imports': 7.27.1 + '@babel/helper-validator-identifier': 7.28.5 + '@babel/traverse': 7.28.5 + transitivePeerDependencies: + - supports-color + '@babel/helper-module-transforms@7.28.3(@babel/core@7.28.5)': dependencies: '@babel/core': 7.28.5 @@ -10656,6 +11811,10 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/helper-split-export-declaration@7.24.7': + dependencies: + '@babel/types': 7.28.5 + '@babel/helper-string-parser@7.27.1': {} '@babel/helper-validator-identifier@7.28.5': {} @@ -10742,6 +11901,11 @@ snapshots: '@babel/core': 7.28.5 '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-import-attributes@7.26.0(@babel/core@7.26.10)': + dependencies: + '@babel/core': 7.26.10 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-import-attributes@7.27.1(@babel/core@7.28.5)': dependencies: '@babel/core': 7.28.5 @@ -11354,6 +12518,9 @@ snapshots: '@esbuild/aix-ppc64@0.25.11': optional: true + '@esbuild/aix-ppc64@0.28.0': + optional: true + '@esbuild/android-arm64@0.17.19': optional: true @@ -11366,6 +12533,9 @@ snapshots: '@esbuild/android-arm64@0.25.11': optional: true + '@esbuild/android-arm64@0.28.0': + optional: true + '@esbuild/android-arm@0.15.18': optional: true @@ -11381,6 +12551,9 @@ snapshots: '@esbuild/android-arm@0.25.11': optional: true + '@esbuild/android-arm@0.28.0': + optional: true + '@esbuild/android-x64@0.17.19': optional: true @@ -11393,6 +12566,9 @@ snapshots: '@esbuild/android-x64@0.25.11': optional: true + '@esbuild/android-x64@0.28.0': + optional: true + '@esbuild/darwin-arm64@0.17.19': optional: true @@ -11405,6 +12581,9 @@ snapshots: '@esbuild/darwin-arm64@0.25.11': optional: true + '@esbuild/darwin-arm64@0.28.0': + optional: true + '@esbuild/darwin-x64@0.17.19': optional: true @@ -11417,6 +12596,9 @@ snapshots: '@esbuild/darwin-x64@0.25.11': optional: true + '@esbuild/darwin-x64@0.28.0': + optional: true + '@esbuild/freebsd-arm64@0.17.19': optional: true @@ -11429,6 +12611,9 @@ snapshots: '@esbuild/freebsd-arm64@0.25.11': optional: true + '@esbuild/freebsd-arm64@0.28.0': + optional: true + '@esbuild/freebsd-x64@0.17.19': optional: true @@ -11441,6 +12626,9 @@ snapshots: '@esbuild/freebsd-x64@0.25.11': optional: true + '@esbuild/freebsd-x64@0.28.0': + optional: true + '@esbuild/linux-arm64@0.17.19': optional: true @@ -11453,6 +12641,9 @@ snapshots: '@esbuild/linux-arm64@0.25.11': optional: true + '@esbuild/linux-arm64@0.28.0': + optional: true + '@esbuild/linux-arm@0.17.19': optional: true @@ -11465,6 +12656,9 @@ snapshots: '@esbuild/linux-arm@0.25.11': optional: true + '@esbuild/linux-arm@0.28.0': + optional: true + '@esbuild/linux-ia32@0.17.19': optional: true @@ -11477,6 +12671,9 @@ snapshots: '@esbuild/linux-ia32@0.25.11': optional: true + '@esbuild/linux-ia32@0.28.0': + optional: true + '@esbuild/linux-loong64@0.15.18': optional: true @@ -11492,6 +12689,9 @@ snapshots: '@esbuild/linux-loong64@0.25.11': optional: true + '@esbuild/linux-loong64@0.28.0': + optional: true + '@esbuild/linux-mips64el@0.17.19': optional: true @@ -11504,6 +12704,9 @@ snapshots: '@esbuild/linux-mips64el@0.25.11': optional: true + '@esbuild/linux-mips64el@0.28.0': + optional: true + '@esbuild/linux-ppc64@0.17.19': optional: true @@ -11516,6 +12719,9 @@ snapshots: '@esbuild/linux-ppc64@0.25.11': optional: true + '@esbuild/linux-ppc64@0.28.0': + optional: true + '@esbuild/linux-riscv64@0.17.19': optional: true @@ -11528,6 +12734,9 @@ snapshots: '@esbuild/linux-riscv64@0.25.11': optional: true + '@esbuild/linux-riscv64@0.28.0': + optional: true + '@esbuild/linux-s390x@0.17.19': optional: true @@ -11540,6 +12749,9 @@ snapshots: '@esbuild/linux-s390x@0.25.11': optional: true + '@esbuild/linux-s390x@0.28.0': + optional: true + '@esbuild/linux-x64@0.17.19': optional: true @@ -11552,9 +12764,15 @@ snapshots: '@esbuild/linux-x64@0.25.11': optional: true + '@esbuild/linux-x64@0.28.0': + optional: true + '@esbuild/netbsd-arm64@0.25.11': optional: true + '@esbuild/netbsd-arm64@0.28.0': + optional: true + '@esbuild/netbsd-x64@0.17.19': optional: true @@ -11567,9 +12785,15 @@ snapshots: '@esbuild/netbsd-x64@0.25.11': optional: true + '@esbuild/netbsd-x64@0.28.0': + optional: true + '@esbuild/openbsd-arm64@0.25.11': optional: true + '@esbuild/openbsd-arm64@0.28.0': + optional: true + '@esbuild/openbsd-x64@0.17.19': optional: true @@ -11582,9 +12806,15 @@ snapshots: '@esbuild/openbsd-x64@0.25.11': optional: true + '@esbuild/openbsd-x64@0.28.0': + optional: true + '@esbuild/openharmony-arm64@0.25.11': optional: true + '@esbuild/openharmony-arm64@0.28.0': + optional: true + '@esbuild/sunos-x64@0.17.19': optional: true @@ -11597,6 +12827,9 @@ snapshots: '@esbuild/sunos-x64@0.25.11': optional: true + '@esbuild/sunos-x64@0.28.0': + optional: true + '@esbuild/win32-arm64@0.17.19': optional: true @@ -11609,6 +12842,9 @@ snapshots: '@esbuild/win32-arm64@0.25.11': optional: true + '@esbuild/win32-arm64@0.28.0': + optional: true + '@esbuild/win32-ia32@0.17.19': optional: true @@ -11621,6 +12857,9 @@ snapshots: '@esbuild/win32-ia32@0.25.11': optional: true + '@esbuild/win32-ia32@0.28.0': + optional: true + '@esbuild/win32-x64@0.17.19': optional: true @@ -11633,6 +12872,9 @@ snapshots: '@esbuild/win32-x64@0.25.11': optional: true + '@esbuild/win32-x64@0.28.0': + optional: true + '@eslint-community/eslint-utils@4.9.0(eslint@8.57.1)': dependencies: eslint: 8.57.1 @@ -11934,6 +13176,28 @@ snapshots: '@img/sharp-win32-x64@0.34.4': optional: true + '@inquirer/ansi@1.0.2': {} + + '@inquirer/confirm@5.1.6(@types/node@24.10.1)': + dependencies: + '@inquirer/core': 10.3.2(@types/node@24.10.1) + '@inquirer/type': 3.0.10(@types/node@24.10.1) + optionalDependencies: + '@types/node': 24.10.1 + + '@inquirer/core@10.3.2(@types/node@24.10.1)': + dependencies: + '@inquirer/ansi': 1.0.2 + '@inquirer/figures': 1.0.15 + '@inquirer/type': 3.0.10(@types/node@24.10.1) + cli-width: 4.1.0 + mute-stream: 2.0.0 + signal-exit: 4.1.0 + wrap-ansi: 6.2.0 + yoctocolors-cjs: 2.1.3 + optionalDependencies: + '@types/node': 24.10.1 + '@inquirer/external-editor@1.0.2(@types/node@22.18.12)': dependencies: chardet: 2.1.0 @@ -11941,6 +13205,12 @@ snapshots: optionalDependencies: '@types/node': 22.18.12 + '@inquirer/figures@1.0.15': {} + + '@inquirer/type@3.0.10(@types/node@24.10.1)': + optionalDependencies: + '@types/node': 24.10.1 + '@ioredis/commands@1.4.0': {} '@isaacs/cliui@8.0.2': @@ -11989,6 +13259,24 @@ snapshots: '@jspm/core@2.1.0': {} + '@lmdb/lmdb-darwin-arm64@3.2.6': + optional: true + + '@lmdb/lmdb-darwin-x64@3.2.6': + optional: true + + '@lmdb/lmdb-linux-arm64@3.2.6': + optional: true + + '@lmdb/lmdb-linux-arm@3.2.6': + optional: true + + '@lmdb/lmdb-linux-x64@3.2.6': + optional: true + + '@lmdb/lmdb-win32-x64@3.2.6': + optional: true + '@mapbox/node-pre-gyp@1.0.11': dependencies: detect-libc: 2.1.2 @@ -12045,10 +13333,100 @@ snapshots: unist-util-position-from-estree: 2.0.0 unist-util-stringify-position: 4.0.0 unist-util-visit: 5.0.0 - vfile: 6.0.2 + vfile: 6.0.3 transitivePeerDependencies: - supports-color + '@msgpackr-extract/msgpackr-extract-darwin-arm64@3.0.3': + optional: true + + '@msgpackr-extract/msgpackr-extract-darwin-x64@3.0.3': + optional: true + + '@msgpackr-extract/msgpackr-extract-linux-arm64@3.0.3': + optional: true + + '@msgpackr-extract/msgpackr-extract-linux-arm@3.0.3': + optional: true + + '@msgpackr-extract/msgpackr-extract-linux-x64@3.0.3': + optional: true + + '@msgpackr-extract/msgpackr-extract-win32-x64@3.0.3': + optional: true + + '@napi-rs/nice-android-arm-eabi@1.1.1': + optional: true + + '@napi-rs/nice-android-arm64@1.1.1': + optional: true + + '@napi-rs/nice-darwin-arm64@1.1.1': + optional: true + + '@napi-rs/nice-darwin-x64@1.1.1': + optional: true + + '@napi-rs/nice-freebsd-x64@1.1.1': + optional: true + + '@napi-rs/nice-linux-arm-gnueabihf@1.1.1': + optional: true + + '@napi-rs/nice-linux-arm64-gnu@1.1.1': + optional: true + + '@napi-rs/nice-linux-arm64-musl@1.1.1': + optional: true + + '@napi-rs/nice-linux-ppc64-gnu@1.1.1': + optional: true + + '@napi-rs/nice-linux-riscv64-gnu@1.1.1': + optional: true + + '@napi-rs/nice-linux-s390x-gnu@1.1.1': + optional: true + + '@napi-rs/nice-linux-x64-gnu@1.1.1': + optional: true + + '@napi-rs/nice-linux-x64-musl@1.1.1': + optional: true + + '@napi-rs/nice-openharmony-arm64@1.1.1': + optional: true + + '@napi-rs/nice-win32-arm64-msvc@1.1.1': + optional: true + + '@napi-rs/nice-win32-ia32-msvc@1.1.1': + optional: true + + '@napi-rs/nice-win32-x64-msvc@1.1.1': + optional: true + + '@napi-rs/nice@1.1.1': + optionalDependencies: + '@napi-rs/nice-android-arm-eabi': 1.1.1 + '@napi-rs/nice-android-arm64': 1.1.1 + '@napi-rs/nice-darwin-arm64': 1.1.1 + '@napi-rs/nice-darwin-x64': 1.1.1 + '@napi-rs/nice-freebsd-x64': 1.1.1 + '@napi-rs/nice-linux-arm-gnueabihf': 1.1.1 + '@napi-rs/nice-linux-arm64-gnu': 1.1.1 + '@napi-rs/nice-linux-arm64-musl': 1.1.1 + '@napi-rs/nice-linux-ppc64-gnu': 1.1.1 + '@napi-rs/nice-linux-riscv64-gnu': 1.1.1 + '@napi-rs/nice-linux-s390x-gnu': 1.1.1 + '@napi-rs/nice-linux-x64-gnu': 1.1.1 + '@napi-rs/nice-linux-x64-musl': 1.1.1 + '@napi-rs/nice-openharmony-arm64': 1.1.1 + '@napi-rs/nice-win32-arm64-msvc': 1.1.1 + '@napi-rs/nice-win32-ia32-msvc': 1.1.1 + '@napi-rs/nice-win32-x64-msvc': 1.1.1 + optional: true + '@napi-rs/wasm-runtime@0.2.12': dependencies: '@emnapi/core': 1.6.0 @@ -12258,13 +13636,13 @@ snapshots: '@poppinss/exception@1.2.2': {} - '@preact/preset-vite@2.10.5(@babel/core@7.28.5)(preact@10.29.2)(rollup@4.52.5)(vite@6.3.5(@types/node@24.10.1)(jiti@2.6.1)(less@4.4.2)(lightningcss@1.30.2)(sass@1.93.2)(stylus@0.62.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))': + '@preact/preset-vite@2.10.5(@babel/core@7.28.5)(preact@10.29.2)(rollup@4.59.0)(vite@6.3.5(@types/node@24.10.1)(jiti@2.6.1)(less@4.4.2)(lightningcss@1.30.2)(sass@1.93.2)(stylus@0.62.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))': dependencies: '@babel/core': 7.28.5 '@babel/plugin-transform-react-jsx': 7.27.1(@babel/core@7.28.5) '@babel/plugin-transform-react-jsx-development': 7.27.1(@babel/core@7.28.5) '@prefresh/vite': 2.4.11(preact@10.29.2)(vite@6.3.5(@types/node@24.10.1)(jiti@2.6.1)(less@4.4.2)(lightningcss@1.30.2)(sass@1.93.2)(stylus@0.62.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) - '@rollup/pluginutils': 5.3.0(rollup@4.52.5) + '@rollup/pluginutils': 5.3.0(rollup@4.59.0) babel-plugin-transform-hook-names: 1.0.2(@babel/core@7.28.5) debug: 4.4.3 magic-string: 0.30.21 @@ -12279,7 +13657,7 @@ snapshots: '@preact/signals-core@1.14.2': {} - '@preact/signals@2.9.0(preact@10.29.2)': + '@preact/signals@2.9.1(preact@10.29.2)': dependencies: '@preact/signals-core': 1.14.2 preact: 10.29.2 @@ -12354,14 +13732,14 @@ snapshots: valibot: 1.4.1(typescript@5.8.3) vfile: 6.0.2 vite: 6.3.5(@types/node@24.0.13)(jiti@2.6.1)(less@4.4.2)(lightningcss@1.30.2)(sass@1.93.2)(stylus@0.62.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) - vite-imagetools: 7.1.1(rollup@4.52.5) + vite-imagetools: 7.1.1 zod: 3.22.4 transitivePeerDependencies: - rollup - supports-color - typescript - '@qwik.dev/router@2.0.0-beta.9(patch_hash=e002def78f4681060d18bc24d686c24ee1d1b997c399a2cb1c03baf3b860e4c8)(rollup@4.52.5)(typescript@5.8.3)': + '@qwik.dev/router@2.0.0-beta.9(patch_hash=e002def78f4681060d18bc24d686c24ee1d1b997c399a2cb1c03baf3b860e4c8)(rollup@4.59.0)(typescript@5.8.3)': dependencies: '@mdx-js/mdx': 3.1.1 '@types/mdx': 2.0.13 @@ -12370,7 +13748,7 @@ snapshots: undici: 7.16.0 valibot: 1.4.1(typescript@5.8.3) vfile: 6.0.3 - vite-imagetools: 7.1.1(rollup@4.52.5) + vite-imagetools: 7.1.1(rollup@4.59.0) zod: 3.25.48 transitivePeerDependencies: - rollup @@ -12499,10 +13877,10 @@ snapshots: '@rollup/pluginutils': 5.3.0(rollup@4.52.5) commondir: 1.0.1 estree-walker: 2.0.2 - fdir: 6.5.0(picomatch@4.0.3) + fdir: 6.5.0(picomatch@4.0.4) is-reference: 1.2.1 magic-string: 0.30.21 - picomatch: 4.0.3 + picomatch: 4.0.4 optionalDependencies: rollup: 4.52.5 @@ -12550,80 +13928,169 @@ snapshots: estree-walker: 2.0.2 picomatch: 2.3.1 + '@rollup/pluginutils@5.3.0': + dependencies: + '@types/estree': 1.0.8 + estree-walker: 2.0.2 + picomatch: 4.0.4 + '@rollup/pluginutils@5.3.0(rollup@4.52.5)': dependencies: '@types/estree': 1.0.8 estree-walker: 2.0.2 - picomatch: 4.0.3 + picomatch: 4.0.4 optionalDependencies: rollup: 4.52.5 + '@rollup/pluginutils@5.3.0(rollup@4.59.0)': + dependencies: + '@types/estree': 1.0.8 + estree-walker: 2.0.2 + picomatch: 4.0.4 + optionalDependencies: + rollup: 4.59.0 + '@rollup/rollup-android-arm-eabi@4.52.5': optional: true + '@rollup/rollup-android-arm-eabi@4.59.0': + optional: true + '@rollup/rollup-android-arm64@4.52.5': optional: true - '@rollup/rollup-darwin-arm64@4.52.5': + '@rollup/rollup-android-arm64@4.59.0': + optional: true + + '@rollup/rollup-darwin-arm64@4.52.5': + optional: true + + '@rollup/rollup-darwin-arm64@4.59.0': + optional: true + + '@rollup/rollup-darwin-x64@4.52.5': + optional: true + + '@rollup/rollup-darwin-x64@4.59.0': + optional: true + + '@rollup/rollup-freebsd-arm64@4.52.5': + optional: true + + '@rollup/rollup-freebsd-arm64@4.59.0': + optional: true + + '@rollup/rollup-freebsd-x64@4.52.5': + optional: true + + '@rollup/rollup-freebsd-x64@4.59.0': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.52.5': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.59.0': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.52.5': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.59.0': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.52.5': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.59.0': optional: true - '@rollup/rollup-darwin-x64@4.52.5': + '@rollup/rollup-linux-arm64-musl@4.52.5': optional: true - '@rollup/rollup-freebsd-arm64@4.52.5': + '@rollup/rollup-linux-arm64-musl@4.59.0': optional: true - '@rollup/rollup-freebsd-x64@4.52.5': + '@rollup/rollup-linux-loong64-gnu@4.52.5': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.52.5': + '@rollup/rollup-linux-loong64-gnu@4.59.0': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.52.5': + '@rollup/rollup-linux-loong64-musl@4.59.0': optional: true - '@rollup/rollup-linux-arm64-gnu@4.52.5': + '@rollup/rollup-linux-ppc64-gnu@4.52.5': optional: true - '@rollup/rollup-linux-arm64-musl@4.52.5': + '@rollup/rollup-linux-ppc64-gnu@4.59.0': optional: true - '@rollup/rollup-linux-loong64-gnu@4.52.5': + '@rollup/rollup-linux-ppc64-musl@4.59.0': optional: true - '@rollup/rollup-linux-ppc64-gnu@4.52.5': + '@rollup/rollup-linux-riscv64-gnu@4.52.5': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.52.5': + '@rollup/rollup-linux-riscv64-gnu@4.59.0': optional: true '@rollup/rollup-linux-riscv64-musl@4.52.5': optional: true + '@rollup/rollup-linux-riscv64-musl@4.59.0': + optional: true + '@rollup/rollup-linux-s390x-gnu@4.52.5': optional: true + '@rollup/rollup-linux-s390x-gnu@4.59.0': + optional: true + '@rollup/rollup-linux-x64-gnu@4.52.5': optional: true + '@rollup/rollup-linux-x64-gnu@4.59.0': + optional: true + '@rollup/rollup-linux-x64-musl@4.52.5': optional: true + '@rollup/rollup-linux-x64-musl@4.59.0': + optional: true + + '@rollup/rollup-openbsd-x64@4.59.0': + optional: true + '@rollup/rollup-openharmony-arm64@4.52.5': optional: true + '@rollup/rollup-openharmony-arm64@4.59.0': + optional: true + '@rollup/rollup-win32-arm64-msvc@4.52.5': optional: true + '@rollup/rollup-win32-arm64-msvc@4.59.0': + optional: true + '@rollup/rollup-win32-ia32-msvc@4.52.5': optional: true + '@rollup/rollup-win32-ia32-msvc@4.59.0': + optional: true + '@rollup/rollup-win32-x64-gnu@4.52.5': optional: true + '@rollup/rollup-win32-x64-gnu@4.59.0': + optional: true + '@rollup/rollup-win32-x64-msvc@4.52.5': optional: true + '@rollup/rollup-win32-x64-msvc@4.59.0': + optional: true + '@rtsao/scc@1.1.0': {} '@shikijs/core@1.29.2': @@ -12986,6 +14453,13 @@ snapshots: tailwindcss: 4.1.16 vite: 7.1.12(@types/node@24.9.1)(jiti@2.6.1)(less@4.4.2)(lightningcss@1.30.2)(sass@1.93.2)(stylus@0.62.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) + '@tailwindcss/vite@4.1.17(vite@7.2.6(@types/node@24.10.1)(jiti@2.6.1)(less@4.4.2)(lightningcss@1.30.2)(sass@1.85.0)(stylus@0.62.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))': + dependencies: + '@tailwindcss/node': 4.1.17 + '@tailwindcss/oxide': 4.1.17 + tailwindcss: 4.1.17 + vite: 7.2.6(@types/node@24.10.1)(jiti@2.6.1)(less@4.4.2)(lightningcss@1.30.2)(sass@1.85.0)(stylus@0.62.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) + '@tailwindcss/vite@4.1.17(vite@7.2.6(@types/node@24.10.1)(jiti@2.6.1)(less@4.4.2)(lightningcss@1.30.2)(sass@1.93.2)(stylus@0.62.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))': dependencies: '@tailwindcss/node': 4.1.17 @@ -13121,6 +14595,13 @@ snapshots: mkdirp: 1.0.4 path-browserify: 1.0.1 + '@ts-morph/common@0.22.0': + dependencies: + fast-glob: 3.3.3 + minimatch: 9.0.5 + mkdirp: 3.0.1 + path-browserify: 1.0.1 + '@tsconfig/node10@1.0.11': {} '@tsconfig/node12@1.0.11': {} @@ -13441,8 +14922,8 @@ snapshots: '@typescript-eslint/project-service@8.36.0(typescript@5.8.3)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.48.0(typescript@5.8.3) - '@typescript-eslint/types': 8.48.0 + '@typescript-eslint/tsconfig-utils': 8.36.0(typescript@5.8.3) + '@typescript-eslint/types': 8.36.0 debug: 4.4.3 typescript: 5.8.3 transitivePeerDependencies: @@ -13879,7 +15360,7 @@ snapshots: glob: 10.4.5 graceful-fs: 4.2.11 node-gyp-build: 4.8.4 - picomatch: 4.0.3 + picomatch: 4.0.4 resolve-from: 5.0.0 transitivePeerDependencies: - encoding @@ -14095,6 +15576,10 @@ snapshots: recast: 0.23.11 vinxi: 0.5.8(@types/node@24.10.1)(db0@0.3.4)(ioredis@5.8.2)(jiti@2.6.1)(less@4.4.2)(lightningcss@1.30.2)(rolldown@1.0.0-beta.52)(sass@1.93.2)(stylus@0.62.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) + '@vitejs/plugin-basic-ssl@1.2.0(vite@6.4.2(@types/node@24.10.1)(jiti@2.6.1)(less@4.4.2)(lightningcss@1.30.2)(sass@1.85.0)(stylus@0.62.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))': + dependencies: + vite: 6.4.2(@types/node@24.10.1)(jiti@2.6.1)(less@4.4.2)(lightningcss@1.30.2)(sass@1.85.0)(stylus@0.62.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) + '@vitejs/plugin-react@5.1.1(vite@7.2.6(@types/node@24.10.1)(jiti@2.6.1)(less@4.4.2)(lightningcss@1.30.2)(sass@1.93.2)(stylus@0.62.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))': dependencies: '@babel/core': 7.28.5 @@ -14464,6 +15949,10 @@ snapshots: clean-stack: 2.2.0 indent-string: 4.0.0 + ajv-formats@3.0.1(ajv@8.18.0): + optionalDependencies: + ajv: 8.18.0 + ajv@6.12.6: dependencies: fast-deep-equal: 3.1.3 @@ -14471,6 +15960,13 @@ snapshots: json-schema-traverse: 0.4.1 uri-js: 4.4.1 + ajv@8.18.0: + dependencies: + fast-deep-equal: 3.1.3 + fast-uri: 3.1.2 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + ajv@8.6.3: dependencies: fast-deep-equal: 3.1.3 @@ -14488,6 +15984,10 @@ snapshots: dependencies: type-fest: 0.21.3 + ansi-escapes@7.3.0: + dependencies: + environment: 1.1.0 + ansi-regex@5.0.1: {} ansi-regex@6.2.2: {} @@ -14754,6 +16254,17 @@ snapshots: baseline-browser-mapping@2.8.20: {} + beasties@0.3.2: + dependencies: + css-select: 5.2.2 + css-what: 6.2.2 + dom-serializer: 2.0.0 + domhandler: 5.0.3 + htmlparser2: 10.1.0 + picocolors: 1.1.1 + postcss: 8.5.6 + postcss-media-query-parser: 0.2.3 + before-after-hook@4.0.0: {} big.js@5.2.2: {} @@ -15000,10 +16511,21 @@ snapshots: dependencies: restore-cursor: 3.1.0 + cli-cursor@5.0.0: + dependencies: + restore-cursor: 5.1.0 + cli-spinners@2.9.2: {} + cli-truncate@4.0.0: + dependencies: + slice-ansi: 5.0.0 + string-width: 7.2.0 + cli-width@3.0.0: {} + cli-width@4.1.0: {} + clipboardy@4.0.0: dependencies: execa: 8.0.1 @@ -15028,6 +16550,8 @@ snapshots: code-block-writer@10.1.1: {} + code-block-writer@12.0.0: {} + collapse-white-space@2.1.0: {} color-convert@2.0.1: @@ -15101,6 +16625,8 @@ snapshots: convert-hrtime@3.0.0: {} + convert-source-map@1.9.0: {} + convert-source-map@2.0.0: {} cookie-es@1.2.2: {} @@ -15483,6 +17009,10 @@ snapshots: entities@6.0.1: {} + entities@7.0.1: {} + + environment@1.1.0: {} + errno@0.1.8: dependencies: prr: 1.0.1 @@ -15725,12 +17255,12 @@ snapshots: esbuild: 0.17.6 import-meta-resolve: 2.2.2 - esbuild-plugin-solid@0.5.0(esbuild@0.25.11)(solid-js@1.9.9): + esbuild-plugin-solid@0.5.0(esbuild@0.28.0)(solid-js@1.9.9): dependencies: '@babel/core': 7.28.5 '@babel/preset-typescript': 7.28.5(@babel/core@7.28.5) babel-preset-solid: 1.9.9(@babel/core@7.28.5)(solid-js@1.9.9) - esbuild: 0.25.11 + esbuild: 0.28.0 solid-js: 1.9.9 transitivePeerDependencies: - supports-color @@ -15912,6 +17442,35 @@ snapshots: '@esbuild/win32-ia32': 0.25.11 '@esbuild/win32-x64': 0.25.11 + esbuild@0.28.0: + optionalDependencies: + '@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 + escalade@3.2.0: {} escape-html@1.0.3: {} @@ -16432,6 +17991,8 @@ snapshots: eventemitter3@4.0.7: {} + eventemitter3@5.0.4: {} + events-universal@1.0.1: dependencies: bare-events: 2.8.1 @@ -16538,6 +18099,8 @@ snapshots: fast-levenshtein@2.0.6: {} + fast-uri@3.1.2: {} + fastq@1.19.1: dependencies: reusify: 1.1.0 @@ -16550,6 +18113,10 @@ snapshots: optionalDependencies: picomatch: 4.0.3 + fdir@6.5.0(picomatch@4.0.4): + optionalDependencies: + picomatch: 4.0.4 + fflate@0.7.4: {} figures@3.2.0: @@ -16776,6 +18343,8 @@ snapshots: dependencies: is-glob: 4.0.3 + glob-to-regexp@0.4.1: {} + glob@10.4.5: dependencies: foreground-child: 3.3.1 @@ -17038,6 +18607,13 @@ snapshots: html-void-elements@3.0.0: {} + htmlparser2@10.1.0: + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + domutils: 3.2.2 + entities: 7.0.1 + http-cache-semantics@4.2.0: {} http-errors@2.0.0: @@ -17283,6 +18859,12 @@ snapshots: is-fullwidth-code-point@3.0.0: {} + is-fullwidth-code-point@4.0.0: {} + + is-fullwidth-code-point@5.1.0: + dependencies: + get-east-asian-width: 1.4.0 + is-generator-function@1.1.2: dependencies: call-bound: 1.0.4 @@ -17415,6 +18997,16 @@ snapshots: istanbul-lib-coverage@3.2.2: {} + istanbul-lib-instrument@6.0.3: + dependencies: + '@babel/core': 7.28.5 + '@babel/parser': 7.28.5 + '@istanbuljs/schema': 0.1.3 + istanbul-lib-coverage: 3.2.2 + semver: 7.7.3 + transitivePeerDependencies: + - supports-color + istanbul-lib-report@3.0.1: dependencies: istanbul-lib-coverage: 3.2.2 @@ -17538,6 +19130,8 @@ snapshots: json5@2.2.3: {} + jsonc-parser@3.3.1: {} + jsonfile@4.0.0: optionalDependencies: graceful-fs: 4.2.11 @@ -17684,6 +19278,31 @@ snapshots: untun: 0.1.3 uqr: 0.1.2 + listr2@8.2.5: + dependencies: + cli-truncate: 4.0.0 + colorette: 2.0.20 + eventemitter3: 5.0.4 + log-update: 6.1.0 + rfdc: 1.4.1 + wrap-ansi: 9.0.2 + + lmdb@3.2.6: + dependencies: + msgpackr: 1.11.12 + node-addon-api: 6.1.0 + node-gyp-build-optional-packages: 5.2.2 + ordered-binary: 1.6.1 + weak-lru-cache: 1.2.2 + optionalDependencies: + '@lmdb/lmdb-darwin-arm64': 3.2.6 + '@lmdb/lmdb-darwin-x64': 3.2.6 + '@lmdb/lmdb-linux-arm': 3.2.6 + '@lmdb/lmdb-linux-arm64': 3.2.6 + '@lmdb/lmdb-linux-x64': 3.2.6 + '@lmdb/lmdb-win32-x64': 3.2.6 + optional: true + load-tsconfig@0.2.5: {} loader-utils@2.0.4: @@ -17727,6 +19346,14 @@ snapshots: chalk: 4.1.2 is-unicode-supported: 0.1.0 + log-update@6.1.0: + dependencies: + ansi-escapes: 7.3.0 + cli-cursor: 5.0.0 + slice-ansi: 7.1.2 + strip-ansi: 7.1.2 + wrap-ansi: 9.0.2 + longest-streak@3.1.0: {} loose-envify@1.4.0: @@ -17751,6 +19378,10 @@ snapshots: lz-string@1.5.0: {} + magic-string@0.30.17: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + magic-string@0.30.21: dependencies: '@jridgewell/sourcemap-codec': 1.5.5 @@ -17955,7 +19586,7 @@ snapshots: trim-lines: 3.0.1 unist-util-position: 5.0.0 unist-util-visit: 5.0.0 - vfile: 6.0.2 + vfile: 6.0.3 mdast-util-to-markdown@1.5.0: dependencies: @@ -18464,6 +20095,8 @@ snapshots: mimic-fn@4.0.0: {} + mimic-function@5.0.1: {} + mimic-response@1.0.1: {} mimic-response@3.1.0: {} @@ -18519,6 +20152,8 @@ snapshots: mkdirp@1.0.4: {} + mkdirp@3.0.1: {} + mlly@1.8.0: dependencies: acorn: 8.15.0 @@ -18536,10 +20171,29 @@ snapshots: ms@2.1.3: {} + msgpackr-extract@3.0.3: + dependencies: + node-gyp-build-optional-packages: 5.2.2 + optionalDependencies: + '@msgpackr-extract/msgpackr-extract-darwin-arm64': 3.0.3 + '@msgpackr-extract/msgpackr-extract-darwin-x64': 3.0.3 + '@msgpackr-extract/msgpackr-extract-linux-arm': 3.0.3 + '@msgpackr-extract/msgpackr-extract-linux-arm64': 3.0.3 + '@msgpackr-extract/msgpackr-extract-linux-x64': 3.0.3 + '@msgpackr-extract/msgpackr-extract-win32-x64': 3.0.3 + optional: true + + msgpackr@1.11.12: + optionalDependencies: + msgpackr-extract: 3.0.3 + optional: true + muggle-string@0.4.1: {} mute-stream@0.0.8: {} + mute-stream@2.0.0: {} + mz@2.7.0: dependencies: any-promise: 1.3.0 @@ -18667,6 +20321,9 @@ snapshots: node-addon-api@1.7.2: optional: true + node-addon-api@6.1.0: + optional: true + node-addon-api@7.1.1: {} node-fetch-native@1.6.7: {} @@ -18681,6 +20338,11 @@ snapshots: node-forge@1.3.1: {} + node-gyp-build-optional-packages@5.2.2: + dependencies: + detect-libc: 2.1.2 + optional: true + node-gyp-build@4.8.4: {} node-html-parser@6.1.13: @@ -18823,6 +20485,10 @@ snapshots: dependencies: mimic-fn: 4.0.0 + onetime@7.0.0: + dependencies: + mimic-function: 5.0.1 + oniguruma-parser@0.12.1: {} oniguruma-to-es@2.3.0: @@ -18880,6 +20546,9 @@ snapshots: strip-ansi: 6.0.1 wcwidth: 1.0.1 + ordered-binary@1.6.1: + optional: true + outdent@0.8.0: {} own-keys@1.0.1: @@ -18957,6 +20626,16 @@ snapshots: parse-statements@1.0.11: {} + parse5-html-rewriting-stream@7.0.0: + dependencies: + entities: 4.5.0 + parse5: 7.3.0 + parse5-sax-parser: 7.0.0 + + parse5-sax-parser@7.0.0: + dependencies: + parse5: 7.3.0 + parse5@7.3.0: dependencies: entities: 6.0.1 @@ -19020,6 +20699,8 @@ snapshots: picomatch@4.0.3: {} + picomatch@4.0.4: {} + pidtree@0.6.0: {} pify@4.0.1: @@ -19027,6 +20708,10 @@ snapshots: pirates@4.0.7: {} + piscina@4.8.0: + optionalDependencies: + '@napi-rs/nice': 1.1.1 + pkg-types@1.3.1: dependencies: confbox: 0.1.8 @@ -19078,6 +20763,8 @@ snapshots: tsx: 4.20.6 yaml: 2.8.1 + postcss-media-query-parser@0.2.3: {} + postcss-modules-extract-imports@3.1.0(postcss@8.5.6): dependencies: postcss: 8.5.6 @@ -19374,7 +21061,7 @@ snapshots: dependencies: '@types/estree': 1.0.8 estree-util-build-jsx: 3.0.1 - vfile: 6.0.2 + vfile: 6.0.3 recma-jsx@1.0.1(acorn@8.15.0): dependencies: @@ -19390,14 +21077,14 @@ snapshots: '@types/estree': 1.0.8 esast-util-from-js: 2.0.1 unified: 11.0.5 - vfile: 6.0.2 + vfile: 6.0.3 recma-stringify@1.0.0: dependencies: '@types/estree': 1.0.8 estree-util-to-js: 2.0.0 unified: 11.0.5 - vfile: 6.0.2 + vfile: 6.0.3 redent@3.0.0: dependencies: @@ -19410,6 +21097,8 @@ snapshots: dependencies: redis-errors: 1.2.0 + reflect-metadata@0.2.2: {} + reflect.getprototypeof@1.0.10: dependencies: call-bind: 1.0.8 @@ -19535,7 +21224,7 @@ snapshots: '@types/mdast': 4.0.4 mdast-util-to-hast: 13.2.0 unified: 11.0.5 - vfile: 6.0.2 + vfile: 6.0.3 remark-rehype@9.1.0: dependencies: @@ -19583,6 +21272,11 @@ snapshots: onetime: 5.1.2 signal-exit: 3.0.7 + restore-cursor@5.1.0: + dependencies: + onetime: 7.0.0 + signal-exit: 4.1.0 + reusify@1.1.0: {} rfdc@1.4.1: {} @@ -19688,7 +21382,7 @@ snapshots: rollup-plugin-visualizer@6.0.5(rolldown@1.0.0-beta.52)(rollup@4.52.5): dependencies: open: 8.4.2 - picomatch: 4.0.3 + picomatch: 4.0.4 source-map: 0.7.6 yargs: 17.7.2 optionalDependencies: @@ -19741,6 +21435,37 @@ snapshots: '@rollup/rollup-win32-x64-msvc': 4.52.5 fsevents: 2.3.3 + rollup@4.59.0: + dependencies: + '@types/estree': 1.0.8 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.59.0 + '@rollup/rollup-android-arm64': 4.59.0 + '@rollup/rollup-darwin-arm64': 4.59.0 + '@rollup/rollup-darwin-x64': 4.59.0 + '@rollup/rollup-freebsd-arm64': 4.59.0 + '@rollup/rollup-freebsd-x64': 4.59.0 + '@rollup/rollup-linux-arm-gnueabihf': 4.59.0 + '@rollup/rollup-linux-arm-musleabihf': 4.59.0 + '@rollup/rollup-linux-arm64-gnu': 4.59.0 + '@rollup/rollup-linux-arm64-musl': 4.59.0 + '@rollup/rollup-linux-loong64-gnu': 4.59.0 + '@rollup/rollup-linux-loong64-musl': 4.59.0 + '@rollup/rollup-linux-ppc64-gnu': 4.59.0 + '@rollup/rollup-linux-ppc64-musl': 4.59.0 + '@rollup/rollup-linux-riscv64-gnu': 4.59.0 + '@rollup/rollup-linux-riscv64-musl': 4.59.0 + '@rollup/rollup-linux-s390x-gnu': 4.59.0 + '@rollup/rollup-linux-x64-gnu': 4.59.0 + '@rollup/rollup-linux-x64-musl': 4.59.0 + '@rollup/rollup-openbsd-x64': 4.59.0 + '@rollup/rollup-openharmony-arm64': 4.59.0 + '@rollup/rollup-win32-arm64-msvc': 4.59.0 + '@rollup/rollup-win32-ia32-msvc': 4.59.0 + '@rollup/rollup-win32-x64-gnu': 4.59.0 + '@rollup/rollup-win32-x64-msvc': 4.59.0 + fsevents: 2.3.3 + rrweb-cssom@0.8.0: {} run-applescript@7.1.0: {} @@ -19751,6 +21476,10 @@ snapshots: dependencies: queue-microtask: 1.2.3 + rxjs@7.8.1: + dependencies: + tslib: 2.8.1 + rxjs@7.8.2: dependencies: tslib: 2.8.1 @@ -19788,6 +21517,14 @@ snapshots: safer-buffer@2.1.2: {} + sass@1.85.0: + dependencies: + chokidar: 4.0.3 + immutable: 5.1.4 + source-map-js: 1.2.1 + optionalDependencies: + '@parcel/watcher': 2.5.1 + sass@1.93.2: dependencies: chokidar: 4.0.3 @@ -19844,6 +21581,8 @@ snapshots: dependencies: lru-cache: 6.0.0 + semver@7.7.1: {} + semver@7.7.3: {} send@0.19.0: @@ -20077,6 +21816,16 @@ snapshots: slash@5.1.0: {} + slice-ansi@5.0.0: + dependencies: + ansi-styles: 6.2.3 + is-fullwidth-code-point: 4.0.0 + + slice-ansi@7.1.2: + dependencies: + ansi-styles: 6.2.3 + is-fullwidth-code-point: 5.1.0 + smart-buffer@4.2.0: {} smob@1.5.0: {} @@ -20133,6 +21882,8 @@ snapshots: source-map@0.6.1: {} + source-map@0.7.4: {} + source-map@0.7.6: {} source-map@0.8.0-beta.0: @@ -20356,6 +22107,18 @@ snapshots: transitivePeerDependencies: - picomatch + svelte-check@4.3.3(picomatch@4.0.4)(svelte@5.42.1)(typescript@5.9.3): + dependencies: + '@jridgewell/trace-mapping': 0.3.31 + chokidar: 4.0.3 + fdir: 6.5.0(picomatch@4.0.4) + picocolors: 1.1.1 + sade: 1.8.1 + svelte: 5.42.1 + typescript: 5.9.3 + transitivePeerDependencies: + - picomatch + svelte-eslint-parser@1.4.0(svelte@5.42.1): dependencies: eslint-scope: 8.4.0 @@ -20571,6 +22334,11 @@ snapshots: '@ts-morph/common': 0.11.1 code-block-writer: 10.1.1 + ts-morph@21.0.1: + dependencies: + '@ts-morph/common': 0.22.0 + code-block-writer: 12.0.0 + ts-node@10.9.1(@types/node@14.18.33)(typescript@4.9.5): dependencies: '@cspotcode/source-map-support': 0.8.1 @@ -20749,9 +22517,9 @@ snapshots: dependencies: esbuild: 0.15.18 - tsup-preset-solid@2.2.0(esbuild@0.25.11)(solid-js@1.9.9)(tsup@8.5.0(jiti@2.6.1)(postcss@8.5.6)(tsx@4.20.6)(typescript@5.8.3)(yaml@2.8.1)): + tsup-preset-solid@2.2.0(esbuild@0.28.0)(solid-js@1.9.9)(tsup@8.5.0(jiti@2.6.1)(postcss@8.5.6)(tsx@4.20.6)(typescript@5.8.3)(yaml@2.8.1)): dependencies: - esbuild-plugin-solid: 0.5.0(esbuild@0.25.11)(solid-js@1.9.9) + esbuild-plugin-solid: 0.5.0(esbuild@0.28.0)(solid-js@1.9.9) tsup: 8.5.0(jiti@2.6.1)(postcss@8.5.6)(tsx@4.20.6)(typescript@5.8.3)(yaml@2.8.1) transitivePeerDependencies: - esbuild @@ -21028,7 +22796,7 @@ snapshots: magic-string: 0.30.21 mlly: 1.8.0 pathe: 2.0.3 - picomatch: 4.0.3 + picomatch: 4.0.4 pkg-types: 2.3.0 scule: 1.3.0 strip-literal: 3.1.0 @@ -21120,7 +22888,7 @@ snapshots: unplugin-utils@0.3.1: dependencies: pathe: 2.0.3 - picomatch: 4.0.3 + picomatch: 4.0.4 unplugin-vue@7.0.3(@types/node@24.9.1)(jiti@2.6.1)(less@4.4.2)(lightningcss@1.30.2)(sass@1.93.2)(stylus@0.62.0)(terser@5.44.0)(tsx@4.20.6)(vue@3.5.22(typescript@5.8.3))(yaml@2.8.1): dependencies: @@ -21219,6 +22987,10 @@ snapshots: v8-compile-cache-lib@3.0.1: {} + valibot@1.2.0(typescript@5.8.3): + optionalDependencies: + typescript: 5.8.3 + valibot@1.4.1(typescript@5.8.3): optionalDependencies: typescript: 5.8.3 @@ -21382,9 +23154,17 @@ snapshots: dependencies: vite: 7.1.12(@types/node@24.9.1)(jiti@2.6.1)(less@4.4.2)(lightningcss@1.30.2)(sass@1.93.2)(stylus@0.62.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) - vite-imagetools@7.1.1(rollup@4.52.5): + vite-imagetools@7.1.1: dependencies: - '@rollup/pluginutils': 5.3.0(rollup@4.52.5) + '@rollup/pluginutils': 5.3.0 + imagetools-core: 7.1.0 + sharp: 0.34.4 + transitivePeerDependencies: + - rollup + + vite-imagetools@7.1.1(rollup@4.59.0): + dependencies: + '@rollup/pluginutils': 5.3.0(rollup@4.59.0) imagetools-core: 7.1.0 sharp: 0.34.4 transitivePeerDependencies: @@ -21664,6 +23444,26 @@ snapshots: tsx: 4.20.6 yaml: 2.8.1 + vite@6.4.2(@types/node@24.10.1)(jiti@2.6.1)(less@4.4.2)(lightningcss@1.30.2)(sass@1.85.0)(stylus@0.62.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1): + dependencies: + esbuild: 0.25.11 + fdir: 6.5.0(picomatch@4.0.4) + picomatch: 4.0.4 + postcss: 8.5.6 + rollup: 4.59.0 + tinyglobby: 0.2.15 + optionalDependencies: + '@types/node': 24.10.1 + fsevents: 2.3.3 + jiti: 2.6.1 + less: 4.4.2 + lightningcss: 1.30.2 + sass: 1.85.0 + stylus: 0.62.0 + terser: 5.44.0 + tsx: 4.20.6 + yaml: 2.8.1 + vite@7.0.4(@types/node@24.0.13)(jiti@2.6.1)(less@4.4.2)(lightningcss@1.30.2)(sass@1.93.2)(stylus@0.62.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1): dependencies: esbuild: 0.25.11 @@ -21765,6 +23565,26 @@ snapshots: tsx: 4.20.6 yaml: 2.8.1 + vite@7.2.6(@types/node@24.10.1)(jiti@2.6.1)(less@4.4.2)(lightningcss@1.30.2)(sass@1.85.0)(stylus@0.62.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1): + dependencies: + esbuild: 0.25.11 + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + postcss: 8.5.6 + rollup: 4.52.5 + tinyglobby: 0.2.15 + optionalDependencies: + '@types/node': 24.10.1 + fsevents: 2.3.3 + jiti: 2.6.1 + less: 4.4.2 + lightningcss: 1.30.2 + sass: 1.85.0 + stylus: 0.62.0 + terser: 5.44.0 + tsx: 4.20.6 + yaml: 2.8.1 + vite@7.2.6(@types/node@24.10.1)(jiti@2.6.1)(less@4.4.2)(lightningcss@1.30.2)(sass@1.93.2)(stylus@0.62.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1): dependencies: esbuild: 0.25.11 @@ -22047,10 +23867,18 @@ snapshots: dependencies: xml-name-validator: 5.0.0 + watchpack@2.4.2: + dependencies: + glob-to-regexp: 0.4.1 + graceful-fs: 4.2.11 + wcwidth@1.0.1: dependencies: defaults: 1.0.4 + weak-lru-cache@1.2.2: + optional: true + web-vitals@0.2.4: {} webidl-conversions@3.0.1: {} @@ -22253,6 +24081,8 @@ snapshots: yocto-queue@0.1.0: {} + yoctocolors-cjs@2.1.3: {} + yoga-wasm-web@0.3.3: {} youch-core@0.3.3: @@ -22286,4 +24116,6 @@ snapshots: zod@3.25.76: {} + zone.js@0.15.1: {} + zwitch@2.0.4: {}