From 80fc43e976330bc47804bb7ccdbad5adc064c4d4 Mon Sep 17 00:00:00 2001 From: studiolxd Date: Mon, 15 Jun 2026 15:49:57 +0200 Subject: [PATCH 01/13] =?UTF-8?q?refactor!:=20rename=20to=20@studiolxd/sco?= =?UTF-8?q?rm=20=E2=80=94=20agnostic=20core=20+=20subpaths?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BREAKING: package renamed @studiolxd/react-scorm → @studiolxd/scorm. React adapter now at the ./react subpath. - Move package packages/react-scorm → packages/scorm; name @studiolxd/scorm@2.0.0 - Split entries: "." = framework-agnostic core (no React imports), "./react" = adapter - New createScormSession() observable session (on/off/destroy emitter) - Extract autoTerminate/autoCommit to framework-agnostic src/lifecycle; React hooks now delegate to them; useScormSession uses useSyncExternalStore over session - Provider builds a ScormSession and exposes it via context - tsup multi-entry (index, react) + IIFE global build (window.Scorm) for + * {#if $status.initialized}live{/if} + * ``` + */ +export function createScormStore( + version: ScormVersion | 'auto', + options: ScormStoreOptions = {}, +): ScormStore { + const { autoTerminate: enableAutoTerminate = false, autoCommitMs = 0, ...providerOptions } = options; + + const session = createScormSession(version, providerOptions); + const disposers: Array<() => void> = []; + if (enableAutoTerminate) disposers.push(autoTerminate(session)); + if (autoCommitMs > 0) disposers.push(autoCommit(session, autoCommitMs)); + + const status = readable(session.status, (set) => session.on('change', set)); + + return { + session, + status, + destroy() { + for (const dispose of disposers) dispose(); + session.destroy(); + }, + }; +} diff --git a/packages/scorm/src/vue/index.ts b/packages/scorm/src/vue/index.ts new file mode 100644 index 0000000..011cd68 --- /dev/null +++ b/packages/scorm/src/vue/index.ts @@ -0,0 +1,72 @@ +// ───────────────────────────────────────────────────────────────────────────── +// @studiolxd/scorm/vue — Vue 3 composable +// ───────────────────────────────────────────────────────────────────────────── +import { shallowRef, onScopeDispose, type ShallowRef } from 'vue'; +import { createScormSession, type ScormSession } from '../session/create-scorm-session'; +import { autoTerminate } from '../lifecycle/auto-terminate'; +import { autoCommit } from '../lifecycle/auto-commit'; +import type { ScormStatus } from '../types/status'; +import type { ScormVersion } from '../types/common'; +import type { ScormProviderOptions } from '../types/options'; +import type { Result } from '../result/result'; +import type { ScormError } from '../errors/scorm-error'; + +/** Extra options for {@link useScorm}. */ +export interface UseScormOptions extends ScormProviderOptions { + /** Initialize on setup and terminate on scope dispose / unload. Default: false. */ + autoTerminate?: boolean; + /** Commit every N ms while mounted. 0 disables. Default: 0. */ + autoCommitMs?: number; +} + +/** Return value of {@link useScorm}. */ +export interface UseScormReturn { + session: ScormSession; + /** Reactive status. Updates on every lifecycle change. */ + status: ShallowRef; + initialize: () => Result | undefined; + commit: () => Result | undefined; + terminate: () => Result | undefined; +} + +/** + * Vue composable that creates an observable SCORM session bound to the component + * scope. The session is destroyed automatically on `onScopeDispose`. + * + * @example + * ```vue + * + * + * ``` + */ +export function useScorm( + version: ScormVersion | 'auto', + options: UseScormOptions = {}, +): UseScormReturn { + const { autoTerminate: enableAutoTerminate = false, autoCommitMs = 0, ...providerOptions } = options; + + const session = createScormSession(version, providerOptions); + const status = shallowRef(session.status); + const off = session.on('change', (s) => { status.value = s; }); + + const disposers: Array<() => void> = []; + if (enableAutoTerminate) disposers.push(autoTerminate(session)); + if (autoCommitMs > 0) disposers.push(autoCommit(session, autoCommitMs)); + + onScopeDispose(() => { + off(); + for (const dispose of disposers) dispose(); + session.destroy(); + }); + + return { + session, + status, + initialize: () => session.initialize(), + commit: () => session.commit(), + terminate: () => session.terminate(), + }; +} diff --git a/packages/scorm/src/wc/index.ts b/packages/scorm/src/wc/index.ts new file mode 100644 index 0000000..9c6eaff --- /dev/null +++ b/packages/scorm/src/wc/index.ts @@ -0,0 +1,101 @@ +// ───────────────────────────────────────────────────────────────────────────── +// @studiolxd/scorm/wc — Web Component +// +// Importing this module registers the custom element (browser only). Use from any +// framework or plain HTML: +// +// +// el.addEventListener('change', (e) => console.log(e.detail.status)) +// el.session.api?.setComplete() +// ───────────────────────────────────────────────────────────────────────────── +import { createScormSession, type ScormSession } from '../session/create-scorm-session'; +import { autoTerminate } from '../lifecycle/auto-terminate'; +import { autoCommit } from '../lifecycle/auto-commit'; +import type { ScormVersion } from '../types/common'; +import type { NoLmsBehavior } from '../types/options'; + +/** + * Register the `` custom element. + * + * Called automatically on import (browser only). No-op under SSR or if the element + * is already registered. Pass a custom `tag` to register under a different name. + * + * Supported attributes: + * - `version` — `"1.2" | "2004" | "auto"` (default `"auto"`) + * - `no-lms-behavior` — `"error" | "mock" | "throw"` (default `"error"`) + * - `fallback-version` — `"1.2" | "2004"` for `version="auto"` with no API + * - `debug` — boolean attribute, enables console logging + * - `auto-terminate` — boolean attribute, wires init-on-connect + terminate-on-disconnect/unload + * - `auto-commit` — number of ms; periodic commit while connected + * + * Emits a `change` CustomEvent (`detail: { status }`) on connect and on every + * lifecycle change. The element also exposes `.session`, `.api`, and + * `initialize()/commit()/terminate()` for imperative use. + */ +export function defineScormSession(tag = 'scorm-session'): void { + if (typeof HTMLElement === 'undefined' || typeof customElements === 'undefined') return; + if (customElements.get(tag)) return; + + class ScormSessionElement extends HTMLElement { + /** The underlying observable session (null before connect). */ + session: ScormSession | null = null; + private disposers: Array<() => void> = []; + private offChange: (() => void) | null = null; + + get api() { + return this.session?.api ?? null; + } + + connectedCallback(): void { + const version = (this.getAttribute('version') as ScormVersion | 'auto' | null) ?? 'auto'; + const noLmsBehavior = (this.getAttribute('no-lms-behavior') as NoLmsBehavior | null) ?? undefined; + const fallbackVersion = (this.getAttribute('fallback-version') as ScormVersion | null) ?? undefined; + const debug = this.hasAttribute('debug'); + + const session = createScormSession(version, { + ...(noLmsBehavior ? { noLmsBehavior } : {}), + ...(fallbackVersion ? { fallbackVersion } : {}), + debug, + }); + this.session = session; + + this.offChange = session.on('change', (status) => { + this.dispatchEvent(new CustomEvent('change', { detail: { status } })); + }); + + if (this.hasAttribute('auto-terminate')) { + this.disposers.push(autoTerminate(session)); + } + const commitMs = Number(this.getAttribute('auto-commit')); + if (commitMs > 0) { + this.disposers.push(autoCommit(session, commitMs)); + } + + // Announce the initial state. + this.dispatchEvent(new CustomEvent('change', { detail: { status: session.status } })); + } + + disconnectedCallback(): void { + for (const dispose of this.disposers) dispose(); + this.disposers = []; + this.offChange?.(); + this.offChange = null; + this.session?.destroy(); + } + + initialize() { + return this.session?.initialize(); + } + commit() { + return this.session?.commit(); + } + terminate() { + return this.session?.terminate(); + } + } + + customElements.define(tag, ScormSessionElement); +} + +// Auto-register on import (browser only). +defineScormSession(); diff --git a/packages/scorm/tests/adapters/angular.test.ts b/packages/scorm/tests/adapters/angular.test.ts new file mode 100644 index 0000000..55cb342 --- /dev/null +++ b/packages/scorm/tests/adapters/angular.test.ts @@ -0,0 +1,14 @@ +import { describe, it, expect } from 'vitest'; +import { provideScorm, SCORM } from '../../src/angular/index'; + +/* eslint-disable @typescript-eslint/no-explicit-any */ + +// Structural test only. The factory uses inject(DestroyRef), which requires an +// Angular injection context — exercised by the Angular CI smoke test, not here. +describe('angular adapter — provideScorm', () => { + it('returns a provider bound to the SCORM token with a factory', () => { + const provider = provideScorm('2004', { noLmsBehavior: 'mock' }) as any; + expect(provider.provide).toBe(SCORM); + expect(typeof provider.useFactory).toBe('function'); + }); +}); diff --git a/packages/scorm/tests/adapters/svelte.test.ts b/packages/scorm/tests/adapters/svelte.test.ts new file mode 100644 index 0000000..2ee2309 --- /dev/null +++ b/packages/scorm/tests/adapters/svelte.test.ts @@ -0,0 +1,23 @@ +import { describe, it, expect } from 'vitest'; +import type { ScormStatus } from '../../src/types/status'; +import { createScormStore } from '../../src/svelte/index'; + +describe('svelte adapter — createScormStore', () => { + it('store reflects lifecycle changes for active subscribers', () => { + const store = createScormStore('2004', { noLmsBehavior: 'mock' }); + + const seen: ScormStatus[] = []; + const unsub = store.status.subscribe((v) => seen.push(v)); + const last = () => seen[seen.length - 1]; + expect(last().initialized).toBe(false); + + store.session.initialize(); + expect(last().initialized).toBe(true); + + store.session.terminate(); + expect(last().terminated).toBe(true); + + unsub(); + store.destroy(); + }); +}); diff --git a/packages/scorm/tests/adapters/vue.test.ts b/packages/scorm/tests/adapters/vue.test.ts new file mode 100644 index 0000000..bccfa30 --- /dev/null +++ b/packages/scorm/tests/adapters/vue.test.ts @@ -0,0 +1,21 @@ +import { describe, it, expect } from 'vitest'; +import { effectScope } from 'vue'; +import { useScorm } from '../../src/vue/index'; + +describe('vue adapter — useScorm', () => { + it('creates a session with reactive status', () => { + const scope = effectScope(); + const result = scope.run(() => useScorm('2004', { noLmsBehavior: 'mock' }))!; + + expect(result.session.api).not.toBeNull(); + expect(result.status.value.initialized).toBe(false); + + result.initialize(); + expect(result.status.value.initialized).toBe(true); + + result.terminate(); + expect(result.status.value.terminated).toBe(true); + + scope.stop(); // triggers onScopeDispose → session.destroy() + }); +}); diff --git a/packages/scorm/tests/wc/scorm-session.test.ts b/packages/scorm/tests/wc/scorm-session.test.ts new file mode 100644 index 0000000..4e6f925 --- /dev/null +++ b/packages/scorm/tests/wc/scorm-session.test.ts @@ -0,0 +1,52 @@ +import { describe, it, expect, vi } from 'vitest'; +import '../../src/wc/index'; + +/* eslint-disable @typescript-eslint/no-explicit-any */ + +describe(' web component', () => { + it('registers the custom element on import', () => { + expect(customElements.get('scorm-session')).toBeTruthy(); + }); + + it('creates a session on connect and emits an initial change event', () => { + const el = document.createElement('scorm-session') as any; + el.setAttribute('version', '2004'); + el.setAttribute('no-lms-behavior', 'mock'); + const onChange = vi.fn(); + el.addEventListener('change', onChange); + + document.body.appendChild(el); + expect(el.session).not.toBeNull(); + expect(el.api).not.toBeNull(); + expect(onChange).toHaveBeenCalled(); + + document.body.removeChild(el); + }); + + it('initialize/terminate proxy to the session', () => { + const el = document.createElement('scorm-session') as any; + el.setAttribute('version', '2004'); + el.setAttribute('no-lms-behavior', 'mock'); + document.body.appendChild(el); + + const r = el.initialize(); + expect(r.ok).toBe(true); + expect(el.session.status.initialized).toBe(true); + el.terminate(); + expect(el.session.status.terminated).toBe(true); + + document.body.removeChild(el); + }); + + it('auto-terminate: initializes on connect, terminates on disconnect', () => { + const el = document.createElement('scorm-session') as any; + el.setAttribute('version', '2004'); + el.setAttribute('no-lms-behavior', 'mock'); + el.setAttribute('auto-terminate', ''); + document.body.appendChild(el); + expect(el.session.status.initialized).toBe(true); + + document.body.removeChild(el); + expect(el.session.status.terminated).toBe(true); + }); +}); diff --git a/packages/scorm/tsup.config.ts b/packages/scorm/tsup.config.ts index 280f3d3..3cca654 100644 --- a/packages/scorm/tsup.config.ts +++ b/packages/scorm/tsup.config.ts @@ -1,7 +1,8 @@ import { defineConfig } from 'tsup'; // Framework deps are never bundled — they are optional peer dependencies. -const external = ['react', 'react-dom', 'vue', '@angular/core', 'svelte']; +// Regexes cover subpath imports like 'svelte/store' and '@angular/core/...'. +const external = ['react', 'react-dom', 'vue', /^@angular\//, /^svelte($|\/)/]; export default defineConfig([ // ── ESM + CJS library, one entry per subpath ────────────────────────────── @@ -9,6 +10,10 @@ export default defineConfig([ entry: { index: 'src/index.ts', react: 'src/react/index.ts', + wc: 'src/wc/index.ts', + vue: 'src/vue/index.ts', + angular: 'src/angular/index.ts', + svelte: 'src/svelte/index.ts', }, format: ['esm', 'cjs'], dts: true, From a5882d8b602d52d082a6ceb1888a4a0ff41636b8 Mon Sep 17 00:00:00 2001 From: studiolxd Date: Mon, 15 Jun 2026 16:11:39 +0200 Subject: [PATCH 03/13] docs: llms.txt + AGENTS.md + README for @studiolxd/scorm - packages/scorm/llms.txt: LLM-friendly API overview (shipped in the tarball) - AGENTS.md: repo conventions for AI coding agents - README.md (en): new name, entry-points table, vanilla quickstart, Vue/Angular/ Svelte/WC/CDN snippets, useScormSession reactive note - Fix import/install lines across all language READMEs to @studiolxd/scorm[/react] Note: non-English README prose still needs a full translation pass (follow-up). Co-Authored-By: Claude Opus 4.8 (1M context) --- AGENTS.md | 58 +++++++++++++++++++ example/README.de.md | 6 +- example/README.es.md | 6 +- example/README.fr.md | 6 +- example/README.md | 6 +- example/README.pl.md | 6 +- example/README.pt.md | 6 +- packages/scorm/README.de.md | 14 ++--- packages/scorm/README.es.md | 14 ++--- packages/scorm/README.fr.md | 14 ++--- packages/scorm/README.md | 107 ++++++++++++++++++++++++++++++----- packages/scorm/README.pl.md | 14 ++--- packages/scorm/README.pt.md | 14 ++--- packages/scorm/llms.txt | 108 ++++++++++++++++++++++++++++++++++++ 14 files changed, 311 insertions(+), 68 deletions(-) create mode 100644 AGENTS.md create mode 100644 packages/scorm/llms.txt diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..afc7e50 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,58 @@ +# AGENTS.md — working in this repository + +Guidance for AI coding agents (Claude Code, Cursor, Copilot, etc.) operating in this +monorepo. For how to *use* the published library, see `packages/scorm/llms.txt`. + +## What this is + +`@studiolxd/scorm` — a headless SCORM 1.2 / 2004 runtime. npm workspaces monorepo: + +- `packages/scorm/` — the published library (`@studiolxd/scorm`). + - `src/` core is **framework-agnostic** (no framework imports outside `src/react`, + `src/vue`, `src/angular`, `src/svelte`, `src/wc`). + - Entry points map to subpaths: `.` (core+vanilla), `./react`, `./vue`, + `./angular`, `./svelte`, `./wc`. Built with `tsup` (ESM + CJS + IIFE). +- `example/` — the single demo app (React + Vite). Not published. +- `docs/` — planning + design docs. + +## Commands (run from repo root) + +- `npm run build` — build the library. +- `npm run test` — run the library test suite (vitest). +- `npm run dev:example` — run the demo at http://localhost:5173. +- Per-package: `npm run typecheck --workspace=packages/scorm`. + +Always run `typecheck` + `test:run` + `build` in `packages/scorm` before committing. + +## Conventions + +- **TypeScript strict.** Every public symbol has JSDoc, ideally with an `@example`. +- **`Result`** is the universal return type — never throw across the + public API (except `noLmsBehavior: 'throw'`). Check `.ok` before `.value`. +- **Framework isolation.** Code in `src/` (outside the adapter folders) must not + import any framework. Adapters are thin bridges over `createScormSession` and the + vanilla `autoTerminate`/`autoCommit` helpers — put shared logic in the core, not + in an adapter. +- **SSR-safe.** Guard any `window`/`document`/`HTMLElement` access with + `typeof … === 'undefined'`. +- **Tests** live in `packages/scorm/tests/`, mirroring `src/`. Use mock mode + (`noLmsBehavior: 'mock'`) — no real LMS needed. + +## Adding a framework adapter + +1. Create `src//index.ts` — bridge `session.on('change')` to the + framework's reactivity; reuse `autoTerminate`/`autoCommit`. +2. Add the entry to `tsup.config.ts` and an `exports` subpath in `package.json`. +3. Add the framework as an **optional** peerDependency (+ devDependency for builds). +4. Add a test under `tests/adapters/`. + +## Release workflow + +See `docs/PLAN-agnostic-core.md` §7 and the version-bump steps: update CHANGELOG → +`npm version` → commit → (publish is manual and gated on npm auth). + +## Do not + +- Do not introduce a framework dependency into the core. +- Do not bundle framework deps (they are externalized/optional peers). +- Do not read `.value` without checking `.ok`. diff --git a/example/README.de.md b/example/README.de.md index 4039e8c..01f146f 100644 --- a/example/README.de.md +++ b/example/README.de.md @@ -67,7 +67,7 @@ Die App verwendet `noLmsBehavior: 'mock'` im `ScormProvider`. Damit wird eine In **1. Provider + Hook** ```tsx -import { ScormProvider, useScorm } from '@studiolxd/react-scorm'; +import { ScormProvider, useScorm } from '@studiolxd/scorm/react'; // Wrap your app (or lesson root) function Root() { @@ -101,7 +101,7 @@ useEffect(() => { Oder verwende den optionalen Auto-Terminate-hook: ```tsx -import { useScormAutoTerminate } from '@studiolxd/react-scorm'; +import { useScormAutoTerminate } from '@studiolxd/scorm/react'; function Lesson() { // Auto-initializes on mount, auto-terminates on unmount/unload @@ -112,7 +112,7 @@ function Lesson() { Oder nutze `useScormSession()` für reaktiven initialisierten/terminierten Zustand: ```tsx -import { useScormSession } from '@studiolxd/react-scorm'; +import { useScormSession } from '@studiolxd/scorm/react'; function Course() { const { initialized, initialize, terminate, api } = useScormSession(); diff --git a/example/README.es.md b/example/README.es.md index 71f4901..2df910d 100644 --- a/example/README.es.md +++ b/example/README.es.md @@ -65,7 +65,7 @@ La aplicación usa `noLmsBehavior: 'mock'` en `ScormProvider`. Esto activa una A **1. Provider + Hook** ```tsx -import { ScormProvider, useScorm } from '@studiolxd/react-scorm'; +import { ScormProvider, useScorm } from '@studiolxd/scorm/react'; // Wrap your app (or lesson root) function Root() { @@ -99,7 +99,7 @@ useEffect(() => { O usa el hook de terminación automática opt-in: ```tsx -import { useScormAutoTerminate } from '@studiolxd/react-scorm'; +import { useScormAutoTerminate } from '@studiolxd/scorm/react'; function Lesson() { // Auto-initializes on mount, auto-terminates on unmount/unload @@ -110,7 +110,7 @@ function Lesson() { O usa `useScormSession()` para estado reactivo de initialized/terminated: ```tsx -import { useScormSession } from '@studiolxd/react-scorm'; +import { useScormSession } from '@studiolxd/scorm/react'; function Course() { const { initialized, initialize, terminate, api } = useScormSession(); diff --git a/example/README.fr.md b/example/README.fr.md index 349348f..541f29a 100644 --- a/example/README.fr.md +++ b/example/README.fr.md @@ -66,7 +66,7 @@ L'application utilise `noLmsBehavior: 'mock'` dans `ScormProvider`. Cela active **1. Provider + Hook** ```tsx -import { ScormProvider, useScorm } from '@studiolxd/react-scorm'; +import { ScormProvider, useScorm } from '@studiolxd/scorm/react'; // Wrap your app (or lesson root) function Root() { @@ -100,7 +100,7 @@ useEffect(() => { Ou utilisez le hook optionnel d'auto-terminaison : ```tsx -import { useScormAutoTerminate } from '@studiolxd/react-scorm'; +import { useScormAutoTerminate } from '@studiolxd/scorm/react'; function Lesson() { // Auto-initializes on mount, auto-terminates on unmount/unload @@ -111,7 +111,7 @@ function Lesson() { Ou utilisez `useScormSession()` pour un état réactif `initialized`/`terminated` : ```tsx -import { useScormSession } from '@studiolxd/react-scorm'; +import { useScormSession } from '@studiolxd/scorm/react'; function Course() { const { initialized, initialize, terminate, api } = useScormSession(); diff --git a/example/README.md b/example/README.md index d72fec2..bac229e 100644 --- a/example/README.md +++ b/example/README.md @@ -71,7 +71,7 @@ on page refresh. **1. Provider + Hook** ```tsx -import { ScormProvider, useScorm } from '@studiolxd/react-scorm'; +import { ScormProvider, useScorm } from '@studiolxd/scorm/react'; // Wrap your app (or lesson root) function Root() { @@ -105,7 +105,7 @@ useEffect(() => { Or use the opt-in auto-terminate hook: ```tsx -import { useScormAutoTerminate } from '@studiolxd/react-scorm'; +import { useScormAutoTerminate } from '@studiolxd/scorm/react'; function Lesson() { // Auto-initializes on mount, auto-terminates on unmount/unload @@ -116,7 +116,7 @@ function Lesson() { Or use `useScormSession()` for reactive initialized/terminated state: ```tsx -import { useScormSession } from '@studiolxd/react-scorm'; +import { useScormSession } from '@studiolxd/scorm/react'; function Course() { const { initialized, initialize, terminate, api } = useScormSession(); diff --git a/example/README.pl.md b/example/README.pl.md index 1db74f6..2f2caca 100644 --- a/example/README.pl.md +++ b/example/README.pl.md @@ -71,7 +71,7 @@ są przechowywane w pamięci i tracone po odświeżeniu strony. **1. Provider + Hook** ```tsx -import { ScormProvider, useScorm } from '@studiolxd/react-scorm'; +import { ScormProvider, useScorm } from '@studiolxd/scorm/react'; // Wrap your app (or lesson root) function Root() { @@ -105,7 +105,7 @@ useEffect(() => { Możesz też skorzystać z opcjonalnego hook'a auto-terminate: ```tsx -import { useScormAutoTerminate } from '@studiolxd/react-scorm'; +import { useScormAutoTerminate } from '@studiolxd/scorm/react'; function Lesson() { // Auto-initializes on mount, auto-terminates on unmount/unload @@ -116,7 +116,7 @@ function Lesson() { Albo użyć `useScormSession()` dla reaktywnego stanu `initialized`/`terminated`: ```tsx -import { useScormSession } from '@studiolxd/react-scorm'; +import { useScormSession } from '@studiolxd/scorm/react'; function Course() { const { initialized, initialize, terminate, api } = useScormSession(); diff --git a/example/README.pt.md b/example/README.pt.md index 8464529..e7617eb 100644 --- a/example/README.pt.md +++ b/example/README.pt.md @@ -71,7 +71,7 @@ armazenados em memória e perdidos ao atualizar a página. **1. Provider + Hook** ```tsx -import { ScormProvider, useScorm } from '@studiolxd/react-scorm'; +import { ScormProvider, useScorm } from '@studiolxd/scorm/react'; // Wrap your app (or lesson root) function Root() { @@ -105,7 +105,7 @@ useEffect(() => { Ou use o hook opcional de terminação automática: ```tsx -import { useScormAutoTerminate } from '@studiolxd/react-scorm'; +import { useScormAutoTerminate } from '@studiolxd/scorm/react'; function Lesson() { // Auto-initializes on mount, auto-terminates on unmount/unload @@ -116,7 +116,7 @@ function Lesson() { Ou use `useScormSession()` para estado reativo de inicialização/encerramento: ```tsx -import { useScormSession } from '@studiolxd/react-scorm'; +import { useScormSession } from '@studiolxd/scorm/react'; function Course() { const { initialized, initialize, terminate, api } = useScormSession(); diff --git a/packages/scorm/README.de.md b/packages/scorm/README.de.md index 21589a8..eab42b2 100644 --- a/packages/scorm/README.de.md +++ b/packages/scorm/README.de.md @@ -16,7 +16,7 @@ Eine headless React + TypeScript-Bibliothek zur SCORM-Laufzeitintegration. Sie s ## Installation ```bash -npm install @studiolxd/react-scorm +npm install @studiolxd/scorm ``` React 18+ ist als Peer-Dependency erforderlich. @@ -24,7 +24,7 @@ React 18+ ist als Peer-Dependency erforderlich. ## Schnellstart ```tsx -import { ScormProvider, useScorm } from '@studiolxd/react-scorm'; +import { ScormProvider, useScorm } from '@studiolxd/scorm/react'; function App() { return ( @@ -275,7 +275,7 @@ Hilfsfunktionen: `isOk()`, `isErr()`, `unwrap()`, `unwrapOr()`. `useScorm()` hält `status.initialized` bewusst als statischen Schnappschuss — der provider verfolgt den Lifecycle-Zustand nicht. Wenn du `initialized` und `terminated` als reaktiven React-Zustand benötigst (um Re-Renders auszulösen), verwende stattdessen `useScormSession()`. ```tsx -import { useScormSession } from '@studiolxd/react-scorm'; +import { useScormSession } from '@studiolxd/scorm/react'; function Course() { const { initialized, initialize, terminate, api } = useScormSession(); @@ -322,7 +322,7 @@ function CourseContent() { Typisierte Hilfsfunktionen zum Erstellen indizierter CMI-Pfade: ```ts -import { scorm12ObjectivePath, scorm2004InteractionPath } from '@studiolxd/react-scorm'; +import { scorm12ObjectivePath, scorm2004InteractionPath } from '@studiolxd/scorm/react'; scorm12ObjectivePath(0, 'score.raw') // "cmi.objectives.0.score.raw" scorm2004InteractionPath(1, 'learner_response') // "cmi.interactions.1.learner_response" @@ -331,7 +331,7 @@ scorm2004InteractionPath(1, 'learner_response') // "cmi.interactions.1.learner_ ## Zeit-Formatierer ```ts -import { formatScorm12Time, formatScorm2004Time } from '@studiolxd/react-scorm'; +import { formatScorm12Time, formatScorm2004Time } from '@studiolxd/scorm/react'; formatScorm12Time(90000) // "00:01:30.00" formatScorm2004Time(90000) // "PT1M30S" @@ -351,7 +351,7 @@ Verwende `noLmsBehavior: 'mock'` für Tests. Der mock nutzt einen In-Memory-Spei Du kannst die mock-Klassen auch direkt verwenden: ```ts -import { MockScorm12Api, Scorm12Driver, ScormApi, createLogger } from '@studiolxd/react-scorm'; +import { MockScorm12Api, Scorm12Driver, ScormApi, createLogger } from '@studiolxd/scorm/react'; const mockApi = new MockScorm12Api(); const driver = new Scorm12Driver(mockApi, createLogger(false)); @@ -365,7 +365,7 @@ api.initialize(); Alle CMI-Pfade sind streng typisiert: ```ts -import type { Scorm12CmiPath, Scorm2004CmiPath } from '@studiolxd/react-scorm'; +import type { Scorm12CmiPath, Scorm2004CmiPath } from '@studiolxd/scorm/react'; // These types catch typos at compile time: const path: Scorm12CmiPath = 'cmi.core.lesson_status'; // OK diff --git a/packages/scorm/README.es.md b/packages/scorm/README.es.md index ed28816..46617be 100644 --- a/packages/scorm/README.es.md +++ b/packages/scorm/README.es.md @@ -16,7 +16,7 @@ Una librería headless de React + TypeScript para la integración del runtime SC ## Instalación ```bash -npm install @studiolxd/react-scorm +npm install @studiolxd/scorm ``` Se requiere React 18+ como dependencia par (peer dependency). @@ -24,7 +24,7 @@ Se requiere React 18+ como dependencia par (peer dependency). ## Inicio rápido ```tsx -import { ScormProvider, useScorm } from '@studiolxd/react-scorm'; +import { ScormProvider, useScorm } from '@studiolxd/scorm/react'; function App() { return ( @@ -275,7 +275,7 @@ Funciones de ayuda: `isOk()`, `isErr()`, `unwrap()`, `unwrapOr()`. `useScorm()` mantiene intencionalmente `status.initialized` como una instantánea estática — el provider no rastrea el estado del ciclo de vida. Si necesitas `initialized` y `terminated` como estado reactivo de React (para disparar re-renderizados), usa `useScormSession()` en su lugar. ```tsx -import { useScormSession } from '@studiolxd/react-scorm'; +import { useScormSession } from '@studiolxd/scorm/react'; function Course() { const { initialized, initialize, terminate, api } = useScormSession(); @@ -322,7 +322,7 @@ function CourseContent() { Funciones de ayuda tipadas para construir rutas CMI indexadas: ```ts -import { scorm12ObjectivePath, scorm2004InteractionPath } from '@studiolxd/react-scorm'; +import { scorm12ObjectivePath, scorm2004InteractionPath } from '@studiolxd/scorm/react'; scorm12ObjectivePath(0, 'score.raw') // "cmi.objectives.0.score.raw" scorm2004InteractionPath(1, 'learner_response') // "cmi.interactions.1.learner_response" @@ -331,7 +331,7 @@ scorm2004InteractionPath(1, 'learner_response') // "cmi.interactions.1.learner_ ## Formateadores de tiempo ```ts -import { formatScorm12Time, formatScorm2004Time } from '@studiolxd/react-scorm'; +import { formatScorm12Time, formatScorm2004Time } from '@studiolxd/scorm/react'; formatScorm12Time(90000) // "00:01:30.00" formatScorm2004Time(90000) // "PT1M30S" @@ -351,7 +351,7 @@ Usa `noLmsBehavior: 'mock'` para las pruebas. El mock utiliza un almacén en mem También puedes usar las clases mock directamente: ```ts -import { MockScorm12Api, Scorm12Driver, ScormApi, createLogger } from '@studiolxd/react-scorm'; +import { MockScorm12Api, Scorm12Driver, ScormApi, createLogger } from '@studiolxd/scorm/react'; const mockApi = new MockScorm12Api(); const driver = new Scorm12Driver(mockApi, createLogger(false)); @@ -365,7 +365,7 @@ api.initialize(); Todas las rutas CMI están tipadas de forma estricta: ```ts -import type { Scorm12CmiPath, Scorm2004CmiPath } from '@studiolxd/react-scorm'; +import type { Scorm12CmiPath, Scorm2004CmiPath } from '@studiolxd/scorm/react'; // These types catch typos at compile time: const path: Scorm12CmiPath = 'cmi.core.lesson_status'; // OK diff --git a/packages/scorm/README.fr.md b/packages/scorm/README.fr.md index 673e76a..4b64656 100644 --- a/packages/scorm/README.fr.md +++ b/packages/scorm/README.fr.md @@ -16,7 +16,7 @@ Une bibliothèque React + TypeScript sans interface graphique pour l'intégratio ## Installation ```bash -npm install @studiolxd/react-scorm +npm install @studiolxd/scorm ``` React 18+ est requis comme dépendance pair. @@ -24,7 +24,7 @@ React 18+ est requis comme dépendance pair. ## Démarrage rapide ```tsx -import { ScormProvider, useScorm } from '@studiolxd/react-scorm'; +import { ScormProvider, useScorm } from '@studiolxd/scorm/react'; function App() { return ( @@ -275,7 +275,7 @@ Fonctions utilitaires : `isOk()`, `isErr()`, `unwrap()`, `unwrapOr()`. `useScorm()` maintient intentionnellement `status.initialized` comme un instantané statique — le provider ne suit pas l'état du cycle de vie. Si vous avez besoin de `initialized` et `terminated` comme état React réactif (pour déclencher des rendus), utilisez `useScormSession()` à la place. ```tsx -import { useScormSession } from '@studiolxd/react-scorm'; +import { useScormSession } from '@studiolxd/scorm/react'; function Course() { const { initialized, initialize, terminate, api } = useScormSession(); @@ -322,7 +322,7 @@ function CourseContent() { Fonctions utilitaires typées pour construire des chemins CMI indexés : ```ts -import { scorm12ObjectivePath, scorm2004InteractionPath } from '@studiolxd/react-scorm'; +import { scorm12ObjectivePath, scorm2004InteractionPath } from '@studiolxd/scorm/react'; scorm12ObjectivePath(0, 'score.raw') // "cmi.objectives.0.score.raw" scorm2004InteractionPath(1, 'learner_response') // "cmi.interactions.1.learner_response" @@ -331,7 +331,7 @@ scorm2004InteractionPath(1, 'learner_response') // "cmi.interactions.1.learner_ ## Formateurs de temps ```ts -import { formatScorm12Time, formatScorm2004Time } from '@studiolxd/react-scorm'; +import { formatScorm12Time, formatScorm2004Time } from '@studiolxd/scorm/react'; formatScorm12Time(90000) // "00:01:30.00" formatScorm2004Time(90000) // "PT1M30S" @@ -351,7 +351,7 @@ Utilisez `noLmsBehavior: 'mock'` pour les tests. Le mock utilise un store en mé Vous pouvez également utiliser les classes mock directement : ```ts -import { MockScorm12Api, Scorm12Driver, ScormApi, createLogger } from '@studiolxd/react-scorm'; +import { MockScorm12Api, Scorm12Driver, ScormApi, createLogger } from '@studiolxd/scorm/react'; const mockApi = new MockScorm12Api(); const driver = new Scorm12Driver(mockApi, createLogger(false)); @@ -365,7 +365,7 @@ api.initialize(); Tous les chemins CMI sont strictement typés : ```ts -import type { Scorm12CmiPath, Scorm2004CmiPath } from '@studiolxd/react-scorm'; +import type { Scorm12CmiPath, Scorm2004CmiPath } from '@studiolxd/scorm/react'; // These types catch typos at compile time: const path: Scorm12CmiPath = 'cmi.core.lesson_status'; // OK diff --git a/packages/scorm/README.md b/packages/scorm/README.md index df77457..867e76a 100644 --- a/packages/scorm/README.md +++ b/packages/scorm/README.md @@ -1,30 +1,57 @@ 🌐 [English](README.md) · [Español](README.es.md) · [Français](README.fr.md) · [Português](README.pt.md) · [Deutsch](README.de.md) · [Polski](README.pl.md) -# @studiolxd/react-scorm +# @studiolxd/scorm -A headless React + TypeScript library for SCORM runtime integration. Provides a `` and `useScorm()` hook to communicate with an LMS via SCORM 1.2 or SCORM 2004 (4th Edition). +A headless TypeScript library for SCORM runtime integration. A **framework-agnostic core** talks to an LMS via SCORM 1.2 or SCORM 2004 (4th Edition), with thin adapters for **React, Vue, Angular, Svelte, Web Components**, and plain vanilla JS / ` +{#if $status.initialized}live{/if} +``` + +**Web Component / plain HTML** +```html + + + +``` + +**CDN ` + +``` + ## ScormProvider The `` component locates the LMS API and makes it available via context. It does **not** auto-initialize — you must call `api.initialize()` explicitly. @@ -100,7 +177,7 @@ const { status, api, raw } = useScorm(); | `api` | `IScormApi \| null` | High-level version-agnostic API. `null` when no API found with `"error"` behavior. | | `raw` | `IScormDriver \| null` | Low-level driver for direct API calls (escape hatch). | -> **Note:** `status.initialized` and `status.terminated` are always `false` in the context value — the provider does not track runtime state. If you need reactive initialized/terminated state, maintain it yourself with `useState` after calling `api.initialize()` and `api.terminate()`. +> **Note:** the `status` from `useScorm()` is a snapshot read at render time. For **reactive** `initialized`/`terminated` state (and wrapped `initialize`/`terminate`/`commit`), use **`useScormSession()`**, which subscribes to the underlying session via `useSyncExternalStore`. ## High-Level API @@ -275,7 +352,7 @@ Helper functions: `isOk()`, `isErr()`, `unwrap()`, `unwrapOr()`. `useScorm()` intentionally keeps `status.initialized` as a static snapshot — the provider does not track lifecycle state. If you need `initialized` and `terminated` as reactive React state (to trigger re-renders), use `useScormSession()` instead. ```tsx -import { useScormSession } from '@studiolxd/react-scorm'; +import { useScormSession } from '@studiolxd/scorm/react'; function Course() { const { initialized, initialize, terminate, api } = useScormSession(); @@ -322,7 +399,7 @@ function CourseContent() { Typed helper functions for building indexed CMI paths: ```ts -import { scorm12ObjectivePath, scorm2004InteractionPath } from '@studiolxd/react-scorm'; +import { scorm12ObjectivePath, scorm2004InteractionPath } from '@studiolxd/scorm/react'; scorm12ObjectivePath(0, 'score.raw') // "cmi.objectives.0.score.raw" scorm2004InteractionPath(1, 'learner_response') // "cmi.interactions.1.learner_response" @@ -331,7 +408,7 @@ scorm2004InteractionPath(1, 'learner_response') // "cmi.interactions.1.learner_ ## Time Formatters ```ts -import { formatScorm12Time, formatScorm2004Time } from '@studiolxd/react-scorm'; +import { formatScorm12Time, formatScorm2004Time } from '@studiolxd/scorm/react'; formatScorm12Time(90000) // "00:01:30.00" formatScorm2004Time(90000) // "PT1M30S" @@ -351,7 +428,7 @@ Use `noLmsBehavior: 'mock'` for testing. The mock uses an in-memory store with r You can also use the mock classes directly: ```ts -import { MockScorm12Api, Scorm12Driver, ScormApi, createLogger } from '@studiolxd/react-scorm'; +import { MockScorm12Api, Scorm12Driver, ScormApi, createLogger } from '@studiolxd/scorm/react'; const mockApi = new MockScorm12Api(); const driver = new Scorm12Driver(mockApi, createLogger(false)); @@ -365,7 +442,7 @@ api.initialize(); All CMI paths are strictly typed: ```ts -import type { Scorm12CmiPath, Scorm2004CmiPath } from '@studiolxd/react-scorm'; +import type { Scorm12CmiPath, Scorm2004CmiPath } from '@studiolxd/scorm/react'; // These types catch typos at compile time: const path: Scorm12CmiPath = 'cmi.core.lesson_status'; // OK diff --git a/packages/scorm/README.pl.md b/packages/scorm/README.pl.md index dcd0dd4..f5043ee 100644 --- a/packages/scorm/README.pl.md +++ b/packages/scorm/README.pl.md @@ -16,7 +16,7 @@ Bezinterfejsowa biblioteka React + TypeScript do integracji ze środowiskiem uru ## Instalacja ```bash -npm install @studiolxd/react-scorm +npm install @studiolxd/scorm ``` Wymagany jest React 18+ jako peer dependency. @@ -24,7 +24,7 @@ Wymagany jest React 18+ jako peer dependency. ## Szybki start ```tsx -import { ScormProvider, useScorm } from '@studiolxd/react-scorm'; +import { ScormProvider, useScorm } from '@studiolxd/scorm/react'; function App() { return ( @@ -275,7 +275,7 @@ Funkcje pomocnicze: `isOk()`, `isErr()`, `unwrap()`, `unwrapOr()`. `useScorm()` celowo utrzymuje `status.initialized` jako statyczną migawkę — provider nie śledzi stanu cyklu życia. Jeśli potrzebujesz `initialized` i `terminated` jako reaktywnego stanu React (wyzwalającego ponowne renderowanie), użyj zamiast tego `useScormSession()`. ```tsx -import { useScormSession } from '@studiolxd/react-scorm'; +import { useScormSession } from '@studiolxd/scorm/react'; function Course() { const { initialized, initialize, terminate, api } = useScormSession(); @@ -322,7 +322,7 @@ function CourseContent() { Typowane funkcje pomocnicze do budowania indeksowanych ścieżek CMI: ```ts -import { scorm12ObjectivePath, scorm2004InteractionPath } from '@studiolxd/react-scorm'; +import { scorm12ObjectivePath, scorm2004InteractionPath } from '@studiolxd/scorm/react'; scorm12ObjectivePath(0, 'score.raw') // "cmi.objectives.0.score.raw" scorm2004InteractionPath(1, 'learner_response') // "cmi.interactions.1.learner_response" @@ -331,7 +331,7 @@ scorm2004InteractionPath(1, 'learner_response') // "cmi.interactions.1.learner_ ## Formatery czasu ```ts -import { formatScorm12Time, formatScorm2004Time } from '@studiolxd/react-scorm'; +import { formatScorm12Time, formatScorm2004Time } from '@studiolxd/scorm/react'; formatScorm12Time(90000) // "00:01:30.00" formatScorm2004Time(90000) // "PT1M30S" @@ -351,7 +351,7 @@ Do testów używaj `noLmsBehavior: 'mock'`. Mock korzysta z magazynu in-memory z Możesz też bezpośrednio korzystać z klas mock: ```ts -import { MockScorm12Api, Scorm12Driver, ScormApi, createLogger } from '@studiolxd/react-scorm'; +import { MockScorm12Api, Scorm12Driver, ScormApi, createLogger } from '@studiolxd/scorm/react'; const mockApi = new MockScorm12Api(); const driver = new Scorm12Driver(mockApi, createLogger(false)); @@ -365,7 +365,7 @@ api.initialize(); Wszystkie ścieżki CMI są ściśle typowane: ```ts -import type { Scorm12CmiPath, Scorm2004CmiPath } from '@studiolxd/react-scorm'; +import type { Scorm12CmiPath, Scorm2004CmiPath } from '@studiolxd/scorm/react'; // These types catch typos at compile time: const path: Scorm12CmiPath = 'cmi.core.lesson_status'; // OK diff --git a/packages/scorm/README.pt.md b/packages/scorm/README.pt.md index ec893e0..7341136 100644 --- a/packages/scorm/README.pt.md +++ b/packages/scorm/README.pt.md @@ -16,7 +16,7 @@ Uma biblioteca headless React + TypeScript para integração com o runtime SCORM ## Instalação ```bash -npm install @studiolxd/react-scorm +npm install @studiolxd/scorm ``` React 18+ é necessário como peer dependency. @@ -24,7 +24,7 @@ React 18+ é necessário como peer dependency. ## Início Rápido ```tsx -import { ScormProvider, useScorm } from '@studiolxd/react-scorm'; +import { ScormProvider, useScorm } from '@studiolxd/scorm/react'; function App() { return ( @@ -275,7 +275,7 @@ Funções auxiliares: `isOk()`, `isErr()`, `unwrap()`, `unwrapOr()`. `useScorm()` mantém intencionalmente `status.initialized` como um snapshot estático — o provider não rastreia o estado do ciclo de vida. Se você precisar de `initialized` e `terminated` como estado reativo do React (para acionar re-renderizações), use `useScormSession()` no lugar. ```tsx -import { useScormSession } from '@studiolxd/react-scorm'; +import { useScormSession } from '@studiolxd/scorm/react'; function Course() { const { initialized, initialize, terminate, api } = useScormSession(); @@ -322,7 +322,7 @@ function CourseContent() { Funções auxiliares tipadas para construir caminhos CMI indexados: ```ts -import { scorm12ObjectivePath, scorm2004InteractionPath } from '@studiolxd/react-scorm'; +import { scorm12ObjectivePath, scorm2004InteractionPath } from '@studiolxd/scorm/react'; scorm12ObjectivePath(0, 'score.raw') // "cmi.objectives.0.score.raw" scorm2004InteractionPath(1, 'learner_response') // "cmi.interactions.1.learner_response" @@ -331,7 +331,7 @@ scorm2004InteractionPath(1, 'learner_response') // "cmi.interactions.1.learner_ ## Formatadores de Tempo ```ts -import { formatScorm12Time, formatScorm2004Time } from '@studiolxd/react-scorm'; +import { formatScorm12Time, formatScorm2004Time } from '@studiolxd/scorm/react'; formatScorm12Time(90000) // "00:01:30.00" formatScorm2004Time(90000) // "PT1M30S" @@ -351,7 +351,7 @@ Use `noLmsBehavior: 'mock'` para testes. O mock utiliza um armazenamento em mem Você também pode usar as classes mock diretamente: ```ts -import { MockScorm12Api, Scorm12Driver, ScormApi, createLogger } from '@studiolxd/react-scorm'; +import { MockScorm12Api, Scorm12Driver, ScormApi, createLogger } from '@studiolxd/scorm/react'; const mockApi = new MockScorm12Api(); const driver = new Scorm12Driver(mockApi, createLogger(false)); @@ -365,7 +365,7 @@ api.initialize(); Todos os caminhos CMI são estritamente tipados: ```ts -import type { Scorm12CmiPath, Scorm2004CmiPath } from '@studiolxd/react-scorm'; +import type { Scorm12CmiPath, Scorm2004CmiPath } from '@studiolxd/scorm/react'; // These types catch typos at compile time: const path: Scorm12CmiPath = 'cmi.core.lesson_status'; // OK diff --git a/packages/scorm/llms.txt b/packages/scorm/llms.txt new file mode 100644 index 0000000..71a7d57 --- /dev/null +++ b/packages/scorm/llms.txt @@ -0,0 +1,108 @@ +# @studiolxd/scorm + +> Headless SCORM 1.2 / 2004 runtime for the browser. Framework-agnostic core with +> a built-in mock mode (run without a real LMS) and adapters for React, Vue, +> Angular, Svelte, and Web Components. Every API call returns a typed Result. + +Install: `npm i @studiolxd/scorm` + +## Entry points (subpath imports) + +- `@studiolxd/scorm` — framework-agnostic core + vanilla (`createScormSession`, `autoTerminate`, `autoCommit`, `ScormApi`, `Result`, `ScormError`, locator, mock). +- `@studiolxd/scorm/react` — `ScormProvider`, `useScorm`, `useScormSession`, `useScormAutoTerminate`, `useScormAutoCommit` (re-exports the core too). +- `@studiolxd/scorm/vue` — `useScorm()` composable. +- `@studiolxd/scorm/angular` — `provideScorm()` + `SCORM` token (Angular >= 17). +- `@studiolxd/scorm/svelte` — `createScormStore()`. +- `@studiolxd/scorm/wc` — registers the `` custom element. +- CDN ` + +``` + +## Gotchas (read these) + +- Always check `.ok` before `.value`. On the session, lifecycle methods return + `undefined` when no SCORM API was found (`noLmsBehavior: 'error'`). +- SCORM 1.2 interactions are WRITE-ONLY: `getInteraction()` returns an error (code + 404) in 1.2; only 2004 can read them back. +- SCORM 1.2 `setScore` raw/min/max must be 0–100 (validated, error 405 otherwise). + SCORM 2004 `scaled` must be -1..1. +- `setProgressMeasure` is a no-op in 1.2. +- A terminated session/driver cannot be re-initialized (SCORM rule). To start a new + session, create a new one (or remount the React provider with a changed `key`). +- SSR-safe: API discovery is guarded against missing `window`. The `/wc` import is + a no-op under SSR. Import `/wc` client-side only. +- `setSessionTime(ms)` takes milliseconds and formats internally. From e2b58020c4c7d1de11ddbf683ac2b8264b2f012f Mon Sep 17 00:00:00 2001 From: studiolxd Date: Mon, 15 Jun 2026 16:23:33 +0200 Subject: [PATCH 04/13] =?UTF-8?q?feat(skills):=20scorm-skills=20=E2=80=94?= =?UTF-8?q?=20one=20source,=20multi-tool=20agent=20instructions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - source/skill.md: canonical skill teaching @studiolxd/scorm usage - scripts/build.mjs: generates Claude Code plugin+marketplace, Cursor .mdc rule, and a portable AGENTS-style baseline from the single source - build/: generated outputs; README explains per-tool install + distribution Co-Authored-By: Claude Opus 4.8 (1M context) --- skills/README.md | 43 +++++++++++ skills/build/agents/scorm-integration.md | 72 ++++++++++++++++++ .../.claude-plugin/marketplace.json | 15 ++++ .../.claude-plugin/plugin.json | 5 ++ .../skills/scorm-integration/SKILL.md | 75 ++++++++++++++++++ skills/build/cursor/scorm-integration.mdc | 76 +++++++++++++++++++ skills/scripts/build.mjs | 69 +++++++++++++++++ skills/source/skill.md | 76 +++++++++++++++++++ 8 files changed, 431 insertions(+) create mode 100644 skills/README.md create mode 100644 skills/build/agents/scorm-integration.md create mode 100644 skills/build/claude-plugin/.claude-plugin/marketplace.json create mode 100644 skills/build/claude-plugin/plugins/scorm-integration/.claude-plugin/plugin.json create mode 100644 skills/build/claude-plugin/plugins/scorm-integration/skills/scorm-integration/SKILL.md create mode 100644 skills/build/cursor/scorm-integration.mdc create mode 100644 skills/scripts/build.mjs create mode 100644 skills/source/skill.md diff --git a/skills/README.md b/skills/README.md new file mode 100644 index 0000000..b347596 --- /dev/null +++ b/skills/README.md @@ -0,0 +1,43 @@ +# scorm-skills + +Agent instructions that teach AI coding tools how to use `@studiolxd/scorm`. + +**One canonical source → many tool formats.** Everything in `build/` is generated; +edit only `source/skill.md`. + +``` +source/skill.md # the single source of truth (edit this) +scripts/build.mjs # generator: source → build/* +build/ # generated (do not edit by hand) + claude-plugin/ # Claude Code plugin + marketplace + .claude-plugin/marketplace.json + plugins/scorm-integration/... + cursor/scorm-integration.mdc # Cursor rule + agents/scorm-integration.md # portable baseline (Antigravity, Copilot, generic) +``` + +Regenerate after editing the source: + +```bash +node skills/scripts/build.mjs +``` + +## Using it per tool + +- **Claude Code** — add `skills/build/claude-plugin` as a plugin marketplace (its + `.claude-plugin/marketplace.json`), then install the `scorm-integration` plugin. + For distribution, publish `build/claude-plugin` as its own public repo. +- **Cursor** — copy `build/cursor/scorm-integration.mdc` into your project's + `.cursor/rules/`. +- **Other agents (Antigravity, Copilot, …)** — drop `build/agents/scorm-integration.md` + into the project (e.g. append to `AGENTS.md`), or point the tool's rules at it. + +## Why this is separate from the npm package + +The runtime package `@studiolxd/scorm` ships only `dist/` + `llms.txt` — it stays lean. +Agent skills target a different audience (coding-assistant toolchains) and are +distributed via marketplaces/rules, not `npm install`. Per the plan they live in a +dedicated location (here, intended to be published as `studiolxd/scorm-skills`). + +> Note: marketplace/plugin manifest schemas evolve — verify `marketplace.json` and +> `plugin.json` against the current Claude Code plugin docs before publishing. diff --git a/skills/build/agents/scorm-integration.md b/skills/build/agents/scorm-integration.md new file mode 100644 index 0000000..33e1154 --- /dev/null +++ b/skills/build/agents/scorm-integration.md @@ -0,0 +1,72 @@ +# scorm-integration + +# Using @studiolxd/scorm + +`@studiolxd/scorm` is a headless SCORM 1.2/2004 runtime. A framework-agnostic core +(`createScormSession`) plus thin adapters. Built-in **mock mode** runs without an LMS. + +## Pick the entry point + +- Vanilla / any framework: `import { createScormSession } from '@studiolxd/scorm'` +- React: `import { ScormProvider, useScorm, useScormSession } from '@studiolxd/scorm/react'` +- Vue: `import { useScorm } from '@studiolxd/scorm/vue'` +- Angular (>=17): `import { provideScorm, SCORM } from '@studiolxd/scorm/angular'` +- Svelte: `import { createScormStore } from '@studiolxd/scorm/svelte'` +- Web Component: `import '@studiolxd/scorm/wc'` then `` +- CDN ` + + +`} + + + + ); +} From b902891dfec2ce486b92978729bde8dcd88d5944 Mon Sep 17 00:00:00 2001 From: studiolxd Date: Mon, 15 Jun 2026 16:52:23 +0200 Subject: [PATCH 06/13] docs(changelog): 2.0.0 rename + agnostic core; rename example to scorm-example Co-Authored-By: Claude Opus 4.8 (1M context) --- example/package.json | 2 +- packages/scorm/CHANGELOG.md | 28 +++++++++++++++++++++++++++- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/example/package.json b/example/package.json index dabb9dc..3d97c49 100644 --- a/example/package.json +++ b/example/package.json @@ -1,5 +1,5 @@ { - "name": "my-app", + "name": "scorm-example", "private": true, "version": "0.0.0", "type": "module", diff --git a/packages/scorm/CHANGELOG.md b/packages/scorm/CHANGELOG.md index 5fe0222..f6cc302 100644 --- a/packages/scorm/CHANGELOG.md +++ b/packages/scorm/CHANGELOG.md @@ -1,6 +1,32 @@ # Changelog -All notable changes to `@studiolxd/react-scorm` are documented here. +All notable changes to `@studiolxd/scorm` are documented here. + +## [2.0.0] - 2026-06-15 + +### Changed (BREAKING) +- **Renamed** `@studiolxd/react-scorm` → `@studiolxd/scorm`. The React API moved to the + `@studiolxd/scorm/react` subpath (`import { ScormProvider, useScorm } from '@studiolxd/scorm/react'`). +- The package root (`@studiolxd/scorm`) is now **framework-agnostic** — no React imports. + +### Added +- **Framework-agnostic core**: `createScormSession(version, options)` — an observable + session with `on('change')` / `off` / `destroy` and reactive `status`. +- **Vanilla lifecycle helpers**: `autoTerminate(session, opts)` and `autoCommit(session, ms)`, + each returning a `dispose()` (the React hooks now delegate to these). +- **Adapters as subpaths**: + - `@studiolxd/scorm/vue` — `useScorm()` composable (Vue 3.3+) + - `@studiolxd/scorm/angular` — `provideScorm()` + `SCORM` token (Angular 17+, decorator-free) + - `@studiolxd/scorm/svelte` — `createScormStore()` (Svelte 4+) + - `@studiolxd/scorm/wc` — `` Web Component +- **IIFE/global build** for plain ` +{#if $status.initialized}live{/if} +``` + +**Web Component / reines HTML** +```html + + + +``` + +**CDN ` + +``` + ## ScormProvider Die ``-Komponente sucht die LMS-API und stellt sie über den Kontext bereit. Sie initialisiert **nicht** automatisch — du musst `api.initialize()` explizit aufrufen. @@ -81,9 +158,9 @@ Die ``-Komponente sucht die LMS-API und stellt sie über den Kont ### `noLmsBehavior`-Optionen | Wert | Verhalten | -|------|-----------| +|-------|----------| | `"error"` (Standard) | `api` ist `null`, `status.apiFound` ist `false`. Operationen können nicht aufgerufen werden. | -| `"mock"` | Verwendet eine In-Memory-mock-SCORM-API. Ideal für lokale Entwicklung und Tests. | +| `"mock"` | Verwendet eine In-Memory-Mock-SCORM-API. Ideal für lokale Entwicklung und Tests. | | `"throw"` | Wirft einen `ScormError` beim Rendern. Mit einer React **Error Boundary** umschließen. | > **`"throw"`-Modus** wirft synchron innerhalb von `useMemo`. Ohne eine Error Boundary propagiert der Fehler nach oben und bringt den gesamten Teilbaum zum Absturz. Umschließe `` bei Verwendung dieses Modus immer mit einer Error Boundary. @@ -95,12 +172,12 @@ const { status, api, raw } = useScorm(); ``` | Feld | Typ | Beschreibung | -|------|-----|--------------| +|-------|------|-------------| | `status` | `ScormStatus` | Verbindungsstatus: `apiFound`, `initialized`*, `terminated`*, `version`, `noLmsBehavior` | | `api` | `IScormApi \| null` | Versionsneutrale High-Level-API. `null`, wenn bei `"error"`-Verhalten keine API gefunden wurde. | -| `raw` | `IScormDriver \| null` | Low-Level-driver für direkte API-Aufrufe (Notausstieg). | +| `raw` | `IScormDriver \| null` | Low-Level-Treiber für direkte API-Aufrufe (Notausstieg). | -> **Hinweis:** `status.initialized` und `status.terminated` sind im Kontextwert immer `false` — der provider verfolgt den Laufzeitzustand nicht. Wenn du reaktiven initialisierten/terminierten Zustand benötigst, verwalte ihn selbst mit `useState` nach dem Aufruf von `api.initialize()` und `api.terminate()`. +> **Hinweis:** Der `status` aus `useScorm()` ist ein zur Renderzeit gelesener Schnappschuss. Für **reaktiven** `initialized`/`terminated`-Zustand (und umschlossene `initialize`/`terminate`/`commit`) verwende **`useScormSession()`**, das die zugrunde liegende Session über `useSyncExternalStore` abonniert. ## High-Level-API @@ -268,11 +345,11 @@ if (result.ok) { Hilfsfunktionen: `isOk()`, `isErr()`, `unwrap()`, `unwrapOr()`. -> **Sicherheit:** `errorString` und `diagnostic` sind Zeichenketten, die direkt vom LMS stammen. Rendere sie niemals über `innerHTML` oder eine nicht-bereinigte DOM-API — behandle sie als nicht vertrauenswürdige Eingaben und escape HTML vor jeder DOM-Einfügung. +> **Sicherheit:** `errorString` und `diagnostic` sind Zeichenketten, die direkt vom LMS stammen. Rendere sie niemals über `innerHTML` oder eine nicht bereinigte DOM-API — behandle sie als nicht vertrauenswürdige Eingaben und escape HTML vor jeder DOM-Einfügung. ## useScormSession (reaktiver Zustand, opt-in) -`useScorm()` hält `status.initialized` bewusst als statischen Schnappschuss — der provider verfolgt den Lifecycle-Zustand nicht. Wenn du `initialized` und `terminated` als reaktiven React-Zustand benötigst (um Re-Renders auszulösen), verwende stattdessen `useScormSession()`. +`useScorm()` hält `status.initialized` bewusst als statischen Schnappschuss — der Provider verfolgt den Lifecycle-Zustand nicht. Wenn du `initialized` und `terminated` als reaktiven React-Zustand benötigst (um Re-Renders auszulösen), verwende stattdessen `useScormSession()`. ```tsx import { useScormSession } from '@studiolxd/scorm/react'; @@ -290,7 +367,7 @@ function Course() { `useScormSession()` ist eine Obermenge von `useScorm()` — es gibt alles zurück, was `useScorm()` zurückgibt (`api`, `status`, `raw`), plus: | Feld | Typ | Beschreibung | -|------|-----|--------------| +|-------|------|-------------| | `initialized` | `boolean` | `true` nach erfolgreichem `initialize()`-Aufruf. Reaktiv. | | `terminated` | `boolean` | `true` nach erfolgreichem `terminate()`-Aufruf. Reaktiv. | | `initialize()` | `Result \| undefined` | Ruft `api.initialize()` auf und aktualisiert den Zustand. `undefined` wenn keine API vorhanden. | @@ -339,7 +416,7 @@ formatScorm2004Time(90000) // "PT1M30S" ## Tests -Verwende `noLmsBehavior: 'mock'` für Tests. Der mock nutzt einen In-Memory-Speicher mit echtem driver-Verhalten. +Verwende `noLmsBehavior: 'mock'` für Tests. Der Mock nutzt einen In-Memory-Speicher mit echtem Treiber-Verhalten. ```tsx // In tests @@ -348,7 +425,7 @@ Verwende `noLmsBehavior: 'mock'` für Tests. Der mock nutzt einen In-Memory-Spei ``` -Du kannst die mock-Klassen auch direkt verwenden: +Du kannst die Mock-Klassen auch direkt verwenden: ```ts import { MockScorm12Api, Scorm12Driver, ScormApi, createLogger } from '@studiolxd/scorm/react'; @@ -375,7 +452,7 @@ const path: Scorm12CmiPath = 'cmi.core.lesson_status'; // OK ## Weitere Dokumentation - [SCORM 1.2 vs 2004 Mapping-Tabelle](./docs/scorm-mapping-table.md) -- [Testen mit dem mock-Modus](./docs/mock-mode.md) +- [Testen mit dem Mock-Modus](./docs/mock-mode.md) - [Integrationsleitfaden](./docs/integration-guide.md) ## Lizenz diff --git a/packages/scorm/README.es.md b/packages/scorm/README.es.md index 46617be..a4d5531 100644 --- a/packages/scorm/README.es.md +++ b/packages/scorm/README.es.md @@ -1,17 +1,19 @@ 🌐 [English](README.md) · [Español](README.es.md) · [Français](README.fr.md) · [Português](README.pt.md) · [Deutsch](README.de.md) · [Polski](README.pl.md) -# @studiolxd/react-scorm +# @studiolxd/scorm -Una librería headless de React + TypeScript para la integración del runtime SCORM. Proporciona un componente `` y un hook `useScorm()` para comunicarse con un LMS mediante SCORM 1.2 o SCORM 2004 (4.ª edición). +Una librería TypeScript headless para la integración del runtime SCORM. Un **núcleo agnóstico al framework** se comunica con un LMS mediante SCORM 1.2 o SCORM 2004 (4.ª edición), con adaptadores ligeros para **React, Vue, Angular, Svelte, Web Components** y JavaScript vanilla / ` +{#if $status.initialized}live{/if} +``` + +**Web Component / HTML plano** +```html + + + +``` + +**CDN ` + +``` + ## ScormProvider El componente `` localiza la API del LMS y la pone a disposición a través del contexto. **No** inicializa automáticamente — debes llamar a `api.initialize()` de forma explícita. @@ -100,7 +177,7 @@ const { status, api, raw } = useScorm(); | `api` | `IScormApi \| null` | API de alto nivel independiente de la versión. `null` cuando no se encuentra la API con el comportamiento `"error"`. | | `raw` | `IScormDriver \| null` | Driver de bajo nivel para llamadas directas a la API (vía de escape). | -> **Nota:** `status.initialized` y `status.terminated` son siempre `false` en el valor del contexto — el provider no rastrea el estado del runtime. Si necesitas estado reactivo de initialized/terminated, mantenlo tú mismo con `useState` después de llamar a `api.initialize()` y `api.terminate()`. +> **Nota:** el `status` de `useScorm()` es una instantánea leída en el momento del renderizado. Para estado **reactivo** de `initialized`/`terminated` (y métodos envueltos `initialize`/`terminate`/`commit`), usa **`useScormSession()`**, que se suscribe a la sesión subyacente mediante `useSyncExternalStore`. ## API de alto nivel diff --git a/packages/scorm/README.fr.md b/packages/scorm/README.fr.md index 4b64656..09d20f6 100644 --- a/packages/scorm/README.fr.md +++ b/packages/scorm/README.fr.md @@ -1,17 +1,19 @@ 🌐 [English](README.md) · [Español](README.es.md) · [Français](README.fr.md) · [Português](README.pt.md) · [Deutsch](README.de.md) · [Polski](README.pl.md) -# @studiolxd/react-scorm +# @studiolxd/scorm -Une bibliothèque React + TypeScript sans interface graphique pour l'intégration du runtime SCORM. Elle fournit un composant `` et un hook `useScorm()` permettant de communiquer avec un LMS via SCORM 1.2 ou SCORM 2004 (4e édition). +Une bibliothèque TypeScript headless pour l'intégration du runtime SCORM. Un **cœur agnostique vis-à-vis du framework** communique avec un LMS via SCORM 1.2 ou SCORM 2004 (4e édition), accompagné d'adaptateurs légers pour **React, Vue, Angular, Svelte, Web Components** et du JavaScript vanilla / ` +{#if $status.initialized}live{/if} +``` + +**Web Component / HTML simple** +```html + + + +``` + +**CDN ` + +``` + ## ScormProvider -Le composant `` localise l'API du LMS et la rend disponible via le contexte React. Il **n'initialise pas automatiquement** — vous devez appeler `api.initialize()` explicitement. +Le composant `` localise l'API du LMS et la rend disponible via le contexte. Il **n'initialise pas automatiquement** — vous devez appeler `api.initialize()` explicitement. ```tsx ` localise l'API du LMS et la rend disponible via l ### Options de `noLmsBehavior` | Valeur | Comportement | -|--------|--------------| +|-------|----------| | `"error"` (défaut) | `api` vaut `null`, `status.apiFound` vaut `false`. Aucune opération ne peut être appelée. | | `"mock"` | Utilise une API SCORM mock en mémoire. Idéal pour le développement local et les tests. | | `"throw"` | Lève une `ScormError` pendant le rendu. À encapsuler dans une **Error Boundary** React. | -> **Mode `"throw"`** : l'erreur est levée de manière synchrone dans `useMemo`. Sans Error Boundary, elle se propage vers le haut et fait planter tout le sous-arbre. Encapsulez toujours `` dans une Error Boundary lorsque vous utilisez ce mode. +> **Le mode `"throw"`** lève l'exception de manière synchrone à l'intérieur de `useMemo`. Sans Error Boundary, l'erreur se propage vers le haut et fait planter tout le sous-arbre. Encapsulez toujours `` dans une Error Boundary lorsque vous utilisez ce mode. ## useScorm() @@ -100,7 +177,7 @@ const { status, api, raw } = useScorm(); | `api` | `IScormApi \| null` | API de haut niveau indépendante de la version. `null` si aucune API n'est trouvée avec le comportement `"error"`. | | `raw` | `IScormDriver \| null` | Driver bas niveau pour les appels directs à l'API (accès de secours). | -> **Remarque :** `status.initialized` et `status.terminated` sont toujours `false` dans la valeur de contexte — le provider ne suit pas l'état du runtime. Si vous avez besoin d'un état réactif pour `initialized`/`terminated`, gérez-le vous-même avec `useState` après les appels à `api.initialize()` et `api.terminate()`. +> **Remarque :** le `status` retourné par `useScorm()` est un instantané lu au moment du rendu. Pour un état **réactif** `initialized`/`terminated` (et des méthodes `initialize`/`terminate`/`commit` encapsulées), utilisez **`useScormSession()`**, qui s'abonne à la session sous-jacente via `useSyncExternalStore`. ## API de haut niveau diff --git a/packages/scorm/README.pl.md b/packages/scorm/README.pl.md index f5043ee..564407f 100644 --- a/packages/scorm/README.pl.md +++ b/packages/scorm/README.pl.md @@ -1,17 +1,19 @@ 🌐 [English](README.md) · [Español](README.es.md) · [Français](README.fr.md) · [Português](README.pt.md) · [Deutsch](README.de.md) · [Polski](README.pl.md) -# @studiolxd/react-scorm +# @studiolxd/scorm -Bezinterfejsowa biblioteka React + TypeScript do integracji ze środowiskiem uruchomieniowym SCORM. Udostępnia komponent `` oraz hook `useScorm()`, umożliwiające komunikację z LMS za pośrednictwem SCORM 1.2 lub SCORM 2004 (4. edycja). +Bezgłowa biblioteka TypeScript do integracji ze środowiskiem uruchomieniowym SCORM. **Rdzeń niezależny od frameworka** komunikuje się z LMS za pośrednictwem SCORM 1.2 lub SCORM 2004 (4. edycja), z cienkimi adapterami dla **React, Vue, Angular, Svelte, Web Components** oraz czystego JavaScriptu (vanilla) / ` +{#if $status.initialized}live{/if} +``` + +**Web Component / czysty HTML** +```html + + + +``` + +**CDN ` + +``` + ## ScormProvider Komponent `` lokalizuje API LMS i udostępnia je przez kontekst. **Nie** inicjalizuje się automatycznie — musisz jawnie wywołać `api.initialize()`. @@ -81,7 +158,7 @@ Komponent `` lokalizuje API LMS i udostępnia je przez kontekst. ### Opcje `noLmsBehavior` | Wartość | Zachowanie | -|---------|------------| +|-------|----------| | `"error"` (domyślna) | `api` jest `null`, `status.apiFound` wynosi `false`. Operacje nie mogą być wywoływane. | | `"mock"` | Używa in-memory mock SCORM API. Idealne do lokalnego developmentu i testów. | | `"throw"` | Rzuca `ScormError` podczas renderowania. Opakuj komponent w React **Error Boundary**. | @@ -95,12 +172,12 @@ const { status, api, raw } = useScorm(); ``` | Pole | Typ | Opis | -|------|-----|------| +|-------|------|-------------| | `status` | `ScormStatus` | Stan połączenia: `apiFound`, `initialized`*, `terminated`*, `version`, `noLmsBehavior` | | `api` | `IScormApi \| null` | Wysokopoziomowe API niezależne od wersji. `null`, gdy nie znaleziono API przy zachowaniu `"error"`. | | `raw` | `IScormDriver \| null` | Niskopoziomowy driver do bezpośrednich wywołań API (wyjście awaryjne). | -> **Uwaga:** `status.initialized` i `status.terminated` mają zawsze wartość `false` w wartości kontekstu — provider nie śledzi stanu środowiska uruchomieniowego. Jeśli potrzebujesz reaktywnego stanu `initialized`/`terminated`, zarządzaj nim samodzielnie przez `useState` po wywołaniu `api.initialize()` i `api.terminate()`. +> **Uwaga:** `status` z `useScorm()` to migawka odczytana w momencie renderowania. Aby uzyskać **reaktywny** stan `initialized`/`terminated` (oraz opakowane `initialize`/`terminate`/`commit`), użyj **`useScormSession()`**, który subskrybuje bazową sesję za pośrednictwem `useSyncExternalStore`. ## Wysokopoziomowe API @@ -290,7 +367,7 @@ function Course() { `useScormSession()` jest nadzbiorem `useScorm()` — zwraca wszystko, co `useScorm()` (`api`, `status`, `raw`), a dodatkowo: | Pole | Typ | Opis | -|------|-----|------| +|-------|------|-------------| | `initialized` | `boolean` | `true` po pomyślnym wywołaniu `initialize()`. Reaktywne. | | `terminated` | `boolean` | `true` po pomyślnym wywołaniu `terminate()`. Reaktywne. | | `initialize()` | `Result \| undefined` | Wywołuje `api.initialize()` i aktualizuje stan. `undefined`, gdy brak API. | diff --git a/packages/scorm/README.pt.md b/packages/scorm/README.pt.md index 7341136..69e5ea1 100644 --- a/packages/scorm/README.pt.md +++ b/packages/scorm/README.pt.md @@ -1,17 +1,19 @@ 🌐 [English](README.md) · [Español](README.es.md) · [Français](README.fr.md) · [Português](README.pt.md) · [Deutsch](README.de.md) · [Polski](README.pl.md) -# @studiolxd/react-scorm +# @studiolxd/scorm -Uma biblioteca headless React + TypeScript para integração com o runtime SCORM. Fornece um `` e o hook `useScorm()` para comunicação com um LMS via SCORM 1.2 ou SCORM 2004 (4ª Edição). +Uma biblioteca TypeScript headless para integração com o runtime SCORM. Um **núcleo agnóstico de framework** comunica com um LMS através de SCORM 1.2 ou SCORM 2004 (4ª Edição), com adaptadores leves para **React, Vue, Angular, Svelte, Web Components** e JavaScript vanilla / ` +{#if $status.initialized}live{/if} +``` + +**Web Component / HTML simples** +```html + + + +``` + +**CDN ` + +``` + ## ScormProvider -O componente `` localiza a API do LMS e a disponibiliza via contexto. Ele **não** inicializa automaticamente — você deve chamar `api.initialize()` explicitamente. +O componente `` localiza a API do LMS e disponibiliza-a através do contexto. **Não** inicializa automaticamente — tem de chamar `api.initialize()` explicitamente. ```tsx ` localiza a API do LMS e a disponibiliza via conte ### Opções de `noLmsBehavior` | Valor | Comportamento | -|-------|---------------| -| `"error"` (padrão) | `api` é `null`, `status.apiFound` é `false`. As operações não podem ser chamadas. | +|-------|----------| +| `"error"` (predefinição) | `api` é `null`, `status.apiFound` é `false`. As operações não podem ser chamadas. | | `"mock"` | Usa uma API SCORM mock em memória. Ideal para desenvolvimento local e testes. | -| `"throw"` | Lança um `ScormError` durante a renderização. Envolva com um **Error Boundary** do React. | +| `"throw"` | Lança um `ScormError` durante o render. Envolva com um **Error Boundary** do React. | -> **Modo `"throw"`** lança de forma síncrona dentro do `useMemo`. Sem um Error Boundary, o erro se propagará e derrubará toda a subárvore. Sempre envolva o `` em um Error Boundary ao usar esse modo. +> O **modo `"throw"`** lança a exceção de forma síncrona dentro de `useMemo`. Sem um Error Boundary, o erro propaga-se para cima e faz crash de toda a subárvore. Envolva sempre `` num Error Boundary ao usar este modo. ## useScorm() @@ -95,18 +172,18 @@ const { status, api, raw } = useScorm(); ``` | Campo | Tipo | Descrição | -|-------|------|-----------| -| `status` | `ScormStatus` | Status da conexão: `apiFound`, `initialized`*, `terminated`*, `version`, `noLmsBehavior` | -| `api` | `IScormApi \| null` | API de alto nível agnóstica à versão. `null` quando nenhuma API é encontrada com o comportamento `"error"`. | +|-------|------|-------------| +| `status` | `ScormStatus` | Estado da ligação: `apiFound`, `initialized`*, `terminated`*, `version`, `noLmsBehavior` | +| `api` | `IScormApi \| null` | API de alto nível agnóstica de versão. `null` quando não é encontrada API com o comportamento `"error"`. | | `raw` | `IScormDriver \| null` | Driver de baixo nível para chamadas diretas à API (escape hatch). | -> **Nota:** `status.initialized` e `status.terminated` são sempre `false` no valor de contexto — o provider não rastreia o estado do runtime. Se você precisar de estado reativo de inicialização/encerramento, mantenha-o você mesmo com `useState` após chamar `api.initialize()` e `api.terminate()`. +> **Nota:** o `status` de `useScorm()` é um snapshot lido no momento do render. Para estado **reativo** de `initialized`/`terminated` (e métodos `initialize`/`terminate`/`commit` envolvidos), use **`useScormSession()`**, que subscreve a sessão subjacente através de `useSyncExternalStore`. ## API de Alto Nível -Todos os métodos retornam `Result` — verifique `result.ok` antes de acessar o valor. +Todos os métodos devolvem `Result` — verifique `result.ok` antes de aceder ao valor. -### Ciclo de Vida +### Ciclo de vida ```ts api.initialize() // Result @@ -114,7 +191,7 @@ api.terminate() // Result api.commit() // Result ``` -### Status +### Estado ```ts api.setComplete() // 1.2: cmi.core.lesson_status="completed" | 2004: cmi.completion_status="completed" @@ -132,7 +209,7 @@ api.setScore({ raw: 85, min: 0, max: 100, scaled: 0.85 }) // scaled is 2004 onl api.getScore() // Result ``` -**Validação:** `raw`, `min` e `max` devem ser números finitos (NaN/Infinity são rejeitados com o código de erro 405). `scaled` deve estar no intervalo `[-1, 1]` (código de erro 407 se fora do intervalo). Para SCORM 1.2, `scaled` é silenciosamente ignorado. +**Validação:** `raw`, `min` e `max` têm de ser números finitos (NaN/Infinity são rejeitados com o código de erro 405). `scaled` tem de estar no intervalo `[-1, 1]` (código de erro 407 se estiver fora do intervalo). No SCORM 1.2, `scaled` é silenciosamente ignorado. ### Localização e Dados de Suspensão @@ -150,7 +227,7 @@ api.setSessionTime(90000) // 1.2: "00:01:30.00" | 2004: "PT1M30S" api.getTotalTime() ``` -### Informações do Aprendiz (somente leitura) +### Informação do Aluno (apenas leitura) ```ts api.getLearnerId() @@ -211,7 +288,7 @@ api.setPreference('language', 'en') api.getPreferences() // Result, ScormError> ``` -### Progresso (somente SCORM 2004) +### Progresso (apenas SCORM 2004) ```ts api.setProgressMeasure(0.75) // value must be in range [0, 1] — error 407 otherwise @@ -225,7 +302,7 @@ api.setExit('suspend') // 1.2: cmi.core.exit | 2004: cmi.exit // Common values: 'suspend', 'logout', 'time-out', '' ``` -### Dados do Aluno (somente leitura, definido pelo LMS) +### Dados do Estudante (apenas leitura, definidos pelo LMS) ```ts api.getMasteryScore() // 1.2: cmi.student_data.mastery_score | 2004: cmi.scaled_passing_score @@ -233,7 +310,7 @@ api.getMaxTimeAllowed() // 1.2: cmi.student_data.max_time_allowed | 2004: cmi. api.getTimeLimitAction() // 1.2: cmi.student_data.time_limit_action | 2004: cmi.time_limit_action ``` -### Navegação (somente SCORM 2004) +### Navegação (apenas SCORM 2004) ```ts api.setNavRequest('continue') // no-op (returns ok) for SCORM 1.2 @@ -241,7 +318,7 @@ api.getNavRequestValid('continue') // 'continue' | 'previous' api.getNavRequestValid('previous') ``` -### Acesso Direto (escape hatch) +### Acesso Raw (escape hatch) ```ts api.getRaw('cmi.core.lesson_status') @@ -250,7 +327,7 @@ api.setRaw('cmi.core.lesson_status', 'completed') ## Tratamento de Erros -Todas as operações retornam `Result` em vez de lançar exceções: +Todas as operações devolvem `Result` em vez de lançar exceções: ```ts const result = api.setComplete(); @@ -268,11 +345,11 @@ if (result.ok) { Funções auxiliares: `isOk()`, `isErr()`, `unwrap()`, `unwrapOr()`. -> **Segurança:** `errorString` e `diagnostic` são strings provenientes diretamente do LMS. Não as renderize via `innerHTML` ou qualquer API DOM sem sanitização — trate-as como entrada não confiável e faça escape de HTML antes de qualquer inserção no DOM. +> **Segurança:** `errorString` e `diagnostic` são strings provenientes diretamente do LMS. Não as renderize através de `innerHTML` ou de qualquer API do DOM não sanitizada — trate-as como entrada não confiável e faça escape de HTML antes de qualquer inserção no DOM. ## useScormSession (estado reativo opcional) -`useScorm()` mantém intencionalmente `status.initialized` como um snapshot estático — o provider não rastreia o estado do ciclo de vida. Se você precisar de `initialized` e `terminated` como estado reativo do React (para acionar re-renderizações), use `useScormSession()` no lugar. +`useScorm()` mantém intencionalmente `status.initialized` como um snapshot estático — o provider não rastreia o estado do ciclo de vida. Se precisar de `initialized` e `terminated` como estado reativo do React (para despoletar re-renders), use antes `useScormSession()`. ```tsx import { useScormSession } from '@studiolxd/scorm/react'; @@ -287,21 +364,21 @@ function Course() { } ``` -`useScormSession()` é um superconjunto de `useScorm()` — retorna tudo que `useScorm()` retorna (`api`, `status`, `raw`) mais: +`useScormSession()` é um superconjunto de `useScorm()` — devolve tudo o que `useScorm()` devolve (`api`, `status`, `raw`) mais: | Campo | Tipo | Descrição | -|-------|------|-----------| -| `initialized` | `boolean` | `true` após `initialize()` ser executado com sucesso. Reativo. | -| `terminated` | `boolean` | `true` após `terminate()` ser executado com sucesso. Reativo. | +|-------|------|-------------| +| `initialized` | `boolean` | `true` após `initialize()` ser bem-sucedido. Reativo. | +| `terminated` | `boolean` | `true` após `terminate()` ser bem-sucedido. Reativo. | | `initialize()` | `Result \| undefined` | Chama `api.initialize()` e atualiza o estado. `undefined` se não houver API. | | `terminate()` | `Result \| undefined` | Chama `api.terminate()` e atualiza o estado. `undefined` se não houver API. | | `commit()` | `Result \| undefined` | Chama `api.commit()`. `undefined` se não houver API. | -> **Nota:** Quando `noLmsBehavior` é `'error'` e nenhum LMS é encontrado, `api` é `null` e os três métodos retornam `undefined`. Verifique `status.apiFound` se precisar distinguir esse caso. +> **Nota:** Quando `noLmsBehavior` é `'error'` e não é encontrado nenhum LMS, `api` é `null` e os três métodos devolvem `undefined`. Verifique `status.apiFound` se precisar de distinguir este caso. ## useScormAutoTerminate (opcional) -Gerencia o ciclo de vida SCORM automaticamente: +Gere o ciclo de vida SCORM automaticamente: ```tsx function CourseContent() { @@ -339,7 +416,7 @@ formatScorm2004Time(90000) // "PT1M30S" ## Testes -Use `noLmsBehavior: 'mock'` para testes. O mock utiliza um armazenamento em memória com comportamento real do driver. +Use `noLmsBehavior: 'mock'` para testes. O mock usa um armazenamento em memória com comportamento real do driver. ```tsx // In tests @@ -348,7 +425,7 @@ Use `noLmsBehavior: 'mock'` para testes. O mock utiliza um armazenamento em mem ``` -Você também pode usar as classes mock diretamente: +Também pode usar as classes mock diretamente: ```ts import { MockScorm12Api, Scorm12Driver, ScormApi, createLogger } from '@studiolxd/scorm/react'; @@ -375,7 +452,7 @@ const path: Scorm12CmiPath = 'cmi.core.lesson_status'; // OK ## Documentação Adicional - [Tabela de Mapeamento SCORM 1.2 vs 2004](./docs/scorm-mapping-table.md) -- [Testes com o Modo Mock](./docs/mock-mode.md) +- [Testes com Modo Mock](./docs/mock-mode.md) - [Guia de Integração](./docs/integration-guide.md) ## Licença From eaf1bd4234f40b2f839d5791fce2614fcb27d3a9 Mon Sep 17 00:00:00 2001 From: studiolxd Date: Mon, 15 Jun 2026 21:15:06 +0200 Subject: [PATCH 10/13] fix(example): depend on @studiolxd/scorm (not the old react-scorm name) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Review finding: example/package.json still declared @studiolxd/react-scorm@^1.0.1 (the renamed-away package), leaving a dangling node_modules symlink to the deleted packages/react-scorm and stale package-lock entries — a potential npm ci break. Build only passed via workspace hoisting. - example/package.json: dependency -> @studiolxd/scorm; root name -> @studiolxd/scorm-monorepo; removed leftover packages/react-scorm/ dir; regenerated clean lockfile (npm ci --dry-run in sync); 415 tests + example build green Co-Authored-By: Claude Opus 4.8 (1M context) --- example/package.json | 2 +- package-lock.json | 2348 +++--------------------------------------- package.json | 2 +- 3 files changed, 166 insertions(+), 2186 deletions(-) diff --git a/example/package.json b/example/package.json index 3d97c49..8b2d84b 100644 --- a/example/package.json +++ b/example/package.json @@ -10,7 +10,7 @@ "preview": "vite preview" }, "dependencies": { - "@studiolxd/react-scorm": "^1.0.1", + "@studiolxd/scorm": "*", "react": "^19.2.0", "react-dom": "^19.2.0" }, diff --git a/package-lock.json b/package-lock.json index 960b10a..f58372f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,10 +1,10 @@ { - "name": "@studiolxd/react-scorm-monorepo", + "name": "@studiolxd/scorm-monorepo", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "@studiolxd/react-scorm-monorepo", + "name": "@studiolxd/scorm-monorepo", "workspaces": [ "packages/*", "example" @@ -14,10 +14,10 @@ } }, "example": { - "name": "my-app", + "name": "scorm-example", "version": "0.0.0", "dependencies": { - "@studiolxd/react-scorm": "^1.0.1", + "@studiolxd/scorm": "*", "react": "^19.2.0", "react-dom": "^19.2.0" }, @@ -1666,8 +1666,6 @@ }, "node_modules/@ampproject/remapping": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", - "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -1680,8 +1678,6 @@ }, "node_modules/@angular/core": { "version": "17.3.12", - "resolved": "https://registry.npmjs.org/@angular/core/-/core-17.3.12.tgz", - "integrity": "sha512-MuFt5yKi161JmauUta4Dh0m8ofwoq6Ino+KoOtkYMBGsSx+A7dSm+DUxxNwdj7+DNyg3LjVGCFgBFnq4g8z06A==", "dev": true, "license": "MIT", "dependencies": { @@ -1697,8 +1693,6 @@ }, "node_modules/@asamuzakjp/css-color": { "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-3.2.0.tgz", - "integrity": "sha512-K1A6z8tS3XsmCMM86xoWdn7Fkdn9m6RSVtocUrJYIwZnFVkng/PvkEoWtOWmP+Scc6saYWHWZYbndEEXxl24jw==", "dev": true, "license": "MIT", "dependencies": { @@ -1711,8 +1705,6 @@ }, "node_modules/@babel/code-frame": { "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", - "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==", "dev": true, "license": "MIT", "dependencies": { @@ -1726,8 +1718,6 @@ }, "node_modules/@babel/helper-string-parser": { "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz", - "integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==", "dev": true, "license": "MIT", "engines": { @@ -1736,8 +1726,6 @@ }, "node_modules/@babel/helper-validator-identifier": { "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz", - "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==", "dev": true, "license": "MIT", "engines": { @@ -1746,8 +1734,6 @@ }, "node_modules/@babel/parser": { "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.7.tgz", - "integrity": "sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg==", "dev": true, "license": "MIT", "dependencies": { @@ -1762,8 +1748,6 @@ }, "node_modules/@babel/runtime": { "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.7.tgz", - "integrity": "sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==", "dev": true, "license": "MIT", "engines": { @@ -1772,8 +1756,6 @@ }, "node_modules/@babel/types": { "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.7.tgz", - "integrity": "sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==", "dev": true, "license": "MIT", "dependencies": { @@ -1786,8 +1768,6 @@ }, "node_modules/@bcoe/v8-coverage": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-1.0.2.tgz", - "integrity": "sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==", "dev": true, "license": "MIT", "engines": { @@ -1796,8 +1776,6 @@ }, "node_modules/@csstools/color-helpers": { "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-5.1.0.tgz", - "integrity": "sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA==", "dev": true, "funding": [ { @@ -1816,8 +1794,6 @@ }, "node_modules/@csstools/css-calc": { "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-2.1.4.tgz", - "integrity": "sha512-3N8oaj+0juUw/1H3YwmDDJXCgTB1gKU6Hc/bB502u9zR0q2vd786XJH9QfrKIEgFlZmhZiq6epXl4rHqhzsIgQ==", "dev": true, "funding": [ { @@ -1840,8 +1816,6 @@ }, "node_modules/@csstools/css-color-parser": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-3.1.0.tgz", - "integrity": "sha512-nbtKwh3a6xNVIp/VRuXV64yTKnb1IjTAEEh3irzS+HkKjAOYLTGNb9pmVNntZ8iVBHcWDA2Dof0QtPgFI1BaTA==", "dev": true, "funding": [ { @@ -1868,8 +1842,6 @@ }, "node_modules/@csstools/css-parser-algorithms": { "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.5.tgz", - "integrity": "sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==", "dev": true, "funding": [ { @@ -1891,8 +1863,6 @@ }, "node_modules/@csstools/css-tokenizer": { "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-3.0.4.tgz", - "integrity": "sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==", "dev": true, "funding": [ { @@ -1909,1165 +1879,62 @@ "node": ">=18" } }, - "node_modules/@emnapi/core": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.9.1.tgz", - "integrity": "sha512-mukuNALVsoix/w1BJwFzwXBN/dHeejQtuVzcDsfOEsdpCumXb/E9j8w11h5S54tT1xhifGfbbSm/ICrObRb3KA==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@emnapi/wasi-threads": "1.2.0", - "tslib": "^2.4.0" - } - }, - "node_modules/@emnapi/runtime": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.9.1.tgz", - "integrity": "sha512-VYi5+ZVLhpgK4hQ0TAjiQiZ6ol0oe4mBx7mVv7IflsiEp0OWoVsp/+f9Vc1hOhE0TtkORVrI1GvzyreqpgWtkA==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@emnapi/wasi-threads": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.0.tgz", - "integrity": "sha512-N10dEJNSsUx41Z6pZsXU8FjPjpBEplgH24sfkmITrBED1/U2Esum9F3lfLrMjKHHjmi557zQn7kR9R+XWXu5Rg==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.7.tgz", - "integrity": "sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.7.tgz", - "integrity": "sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.7.tgz", - "integrity": "sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.7.tgz", - "integrity": "sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.7.tgz", - "integrity": "sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.7.tgz", - "integrity": "sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.7.tgz", - "integrity": "sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.7.tgz", - "integrity": "sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.7.tgz", - "integrity": "sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.7.tgz", - "integrity": "sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.7.tgz", - "integrity": "sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.7.tgz", - "integrity": "sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.7.tgz", - "integrity": "sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw==", - "cpu": [ - "mips64el" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.7.tgz", - "integrity": "sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.7.tgz", - "integrity": "sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.7.tgz", - "integrity": "sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.7.tgz", - "integrity": "sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-arm64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.7.tgz", - "integrity": "sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.7.tgz", - "integrity": "sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-arm64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.7.tgz", - "integrity": "sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.7.tgz", - "integrity": "sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openharmony-arm64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.7.tgz", - "integrity": "sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.7.tgz", - "integrity": "sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.7.tgz", - "integrity": "sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.7.tgz", - "integrity": "sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.7.tgz", - "integrity": "sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.13", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", - "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.0", - "@jridgewell/trace-mapping": "^0.3.24" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", - "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", - "dev": true, - "license": "MIT" - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.31", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", - "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "node_modules/@napi-rs/wasm-runtime": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.1.tgz", - "integrity": "sha512-p64ah1M1ld8xjWv3qbvFwHiFVWrq1yFvV4f7w+mzaqiR4IlSgkqhcRdHwsGgomwzBH51sRY4NEowLxnaBjcW/A==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@emnapi/core": "^1.7.1", - "@emnapi/runtime": "^1.7.1", - "@tybys/wasm-util": "^0.10.1" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/Brooooooklyn" - } - }, - "node_modules/@oxc-project/types": { - "version": "0.122.0", - "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.122.0.tgz", - "integrity": "sha512-oLAl5kBpV4w69UtFZ9xqcmTi+GENWOcPF7FCrczTiBbmC0ibXxCwyvZGbO39rCVEuLGAZM84DH0pUIyyv/YJzA==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/Boshen" - } - }, - "node_modules/@rolldown/binding-android-arm64": { - "version": "1.0.0-rc.11", - "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.0-rc.11.tgz", - "integrity": "sha512-SJ+/g+xNnOh6NqYxD0V3uVN4W3VfnrGsC9/hoglicgTNfABFG9JjISvkkU0dNY84MNHLWyOgxP9v9Y9pX4S7+A==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@rolldown/binding-darwin-arm64": { - "version": "1.0.0-rc.11", - "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.0-rc.11.tgz", - "integrity": "sha512-7WQgR8SfOPwmDZGFkThUvsmd/nwAWv91oCO4I5LS7RKrssPZmOt7jONN0cW17ydGC1n/+puol1IpoieKqQidmg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@rolldown/binding-darwin-x64": { - "version": "1.0.0-rc.11", - "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.0-rc.11.tgz", - "integrity": "sha512-39Ks6UvIHq4rEogIfQBoBRusj0Q0nPVWIvqmwBLaT6aqQGIakHdESBVOPRRLacy4WwUPIx4ZKzfZ9PMW+IeyUQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@rolldown/binding-freebsd-x64": { - "version": "1.0.0-rc.11", - "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.0-rc.11.tgz", - "integrity": "sha512-jfsm0ZHfhiqrvWjJAmzsqiIFPz5e7mAoCOPBNTcNgkiid/LaFKiq92+0ojH+nmJmKYkre4t71BWXUZDNp7vsag==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@rolldown/binding-linux-arm-gnueabihf": { - "version": "1.0.0-rc.11", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.0-rc.11.tgz", - "integrity": "sha512-zjQaUtSyq1nVe3nxmlSCuR96T1LPlpvmJ0SZy0WJFEsV4kFbXcq2u68L4E6O0XeFj4aex9bEauqjW8UQBeAvfQ==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@rolldown/binding-linux-arm64-gnu": { - "version": "1.0.0-rc.11", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.0-rc.11.tgz", - "integrity": "sha512-WMW1yE6IOnehTcFE9eipFkm3XN63zypWlrJQ2iF7NrQ9b2LDRjumFoOGJE8RJJTJCTBAdmLMnJ8uVitACUUo1Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@rolldown/binding-linux-arm64-musl": { - "version": "1.0.0-rc.11", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.0-rc.11.tgz", - "integrity": "sha512-jfndI9tsfm4APzjNt6QdBkYwre5lRPUgHeDHoI7ydKUuJvz3lZeCfMsI56BZj+7BYqiKsJm7cfd/6KYV7ubrBg==", - "cpu": [ - "arm64" - ], - "dev": true, - "libc": [ - "musl" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@rolldown/binding-linux-ppc64-gnu": { - "version": "1.0.0-rc.11", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.0-rc.11.tgz", - "integrity": "sha512-ZlFgw46NOAGMgcdvdYwAGu2Q+SLFA9LzbJLW+iyMOJyhj5wk6P3KEE9Gct4xWwSzFoPI7JCdYmYMzVtlgQ+zfw==", - "cpu": [ - "ppc64" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@rolldown/binding-linux-s390x-gnu": { - "version": "1.0.0-rc.11", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.0-rc.11.tgz", - "integrity": "sha512-hIOYmuT6ofM4K04XAZd3OzMySEO4K0/nc9+jmNcxNAxRi6c5UWpqfw3KMFV4MVFWL+jQsSh+bGw2VqmaPMTLyw==", - "cpu": [ - "s390x" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@rolldown/binding-linux-x64-gnu": { - "version": "1.0.0-rc.11", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.0-rc.11.tgz", - "integrity": "sha512-qXBQQO9OvkjjQPLdUVr7Nr2t3QTZI7s4KZtfw7HzBgjbmAPSFwSv4rmET9lLSgq3rH/ndA3ngv3Qb8l2njoPNA==", - "cpu": [ - "x64" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@rolldown/binding-linux-x64-musl": { - "version": "1.0.0-rc.11", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.0-rc.11.tgz", - "integrity": "sha512-/tpFfoSTzUkH9LPY+cYbqZBDyyX62w5fICq9qzsHLL8uTI6BHip3Q9Uzft0wylk/i8OOwKik8OxW+QAhDmzwmg==", - "cpu": [ - "x64" - ], - "dev": true, - "libc": [ - "musl" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@rolldown/binding-openharmony-arm64": { - "version": "1.0.0-rc.11", - "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.0-rc.11.tgz", - "integrity": "sha512-mcp3Rio2w72IvdZG0oQ4bM2c2oumtwHfUfKncUM6zGgz0KgPz4YmDPQfnXEiY5t3+KD/i8HG2rOB/LxdmieK2g==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@rolldown/binding-wasm32-wasi": { - "version": "1.0.0-rc.11", - "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.0-rc.11.tgz", - "integrity": "sha512-LXk5Hii1Ph9asuGRjBuz8TUxdc1lWzB7nyfdoRgI0WGPZKmCxvlKk8KfYysqtr4MfGElu/f/pEQRh8fcEgkrWw==", - "cpu": [ - "wasm32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@napi-rs/wasm-runtime": "^1.1.1" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@rolldown/binding-win32-arm64-msvc": { - "version": "1.0.0-rc.11", - "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0-rc.11.tgz", - "integrity": "sha512-dDwf5otnx0XgRY1yqxOC4ITizcdzS/8cQ3goOWv3jFAo4F+xQYni+hnMuO6+LssHHdJW7+OCVL3CoU4ycnh35Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@rolldown/binding-win32-x64-msvc": { - "version": "1.0.0-rc.11", - "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.0-rc.11.tgz", - "integrity": "sha512-LN4/skhSggybX71ews7dAj6r2geaMJfm3kMbK2KhFMg9B10AZXnKoLCVVgzhMHL0S+aKtr4p8QbAW8k+w95bAA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@rolldown/pluginutils": { - "version": "1.0.0-rc.11", - "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.11.tgz", - "integrity": "sha512-xQO9vbwBecJRv9EUcQ/y0dzSTJgA7Q6UVN7xp6B81+tBGSLVAK03yJ9NkJaUA7JFD91kbjxRSC/mDnmvXzbHoQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.62.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.62.0.tgz", - "integrity": "sha512-IPIQ55ythEHkfEd9jMEi32OQ7SxURsGA43JI22lj01OLZNt2NUbJX8YUHxkVWyQ6daHPNn0truF5nSj3DQp6YQ==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-android-arm64": { - "version": "4.62.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.62.0.tgz", - "integrity": "sha512-M6s9cr10MibETyo8JsOkq+Lo1+lU6hcvb1MApnUql5qte/5hMEgzlN8/ReIKNfRV8rrqX50W1BX9zoUhC192RA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.62.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.62.0.tgz", - "integrity": "sha512-BqCoMoIbn0keKys+dEAdBa70EtOwV1bEsQCUgU9FdiZmmMge/Zk7LlkYGqbrdHR+Frnt0E1FOanly+rlwvvQzw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.62.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.62.0.tgz", - "integrity": "sha512-SIMzST3VFNXDAbeIWDWiFCNM5qncUBDWaEV7NfE7oZbDt2mgfW4MvbKdbYiGOLoM32gbTv608UMd0XktEYSD7w==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.62.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.62.0.tgz", - "integrity": "sha512-ezjfSQMP7ArdUsbBwbQIfwAlhE84I2iVnzQNCFSveqV42q+BmKlzVpf7mxv5EchLcoWU4y6/heFzVg1F+hodUQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ] - }, - "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.62.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.62.0.tgz", - "integrity": "sha512-9+qTWGW9AZRhnUgwtTwzNwcPlL87ngkeN0LA+q1bADvmY9aNvWaF2TFW8BZgnQPYxpDI7+rMVLivcd4V737TAQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ] - }, - "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.62.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.62.0.tgz", - "integrity": "sha512-T1dMEQhXA/jkJ/jyMIw9IovK8bSUq7A8kLIlvZTb/6YIVsp2zLavr4F3oyllHWo7eIVJRyE5n3tUjQJEbE1IuQ==", - "cpu": [ - "arm" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.62.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.62.0.tgz", - "integrity": "sha512-2as0LgT7qQpyceQq6VUJYnumUMUrgGQCWIiDIN9DE0/tglsk6o66uCB4f3djRawAltvfCNLyZZrsqbPA6inCsA==", - "cpu": [ - "arm" - ], - "dev": true, - "libc": [ - "musl" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.62.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.62.0.tgz", - "integrity": "sha512-bVURMg+6eNN9C/yc0aVjooZcwTTtYF4YW3xta5pP0//r3o1V8gXEHXWCndj47w/HhwsFroZrFhR+6uQP5T0n0g==", - "cpu": [ - "arm64" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.62.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.62.0.tgz", - "integrity": "sha512-Ful8pM/2yYI83PViWdFdpZhdI8HJ5qsXANe5atypbHDf+KIBBDsZsbyy8hbXnULVvW9NsTh5DHwbcBftyLTfiw==", + "node_modules/@esbuild/darwin-arm64": { + "version": "0.27.7", "cpu": [ "arm64" ], "dev": true, - "libc": [ - "musl" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-loong64-gnu": { - "version": "4.62.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.62.0.tgz", - "integrity": "sha512-9Gp/DgrkzfUBmNPVTyPTvay+4xEP7M/clXpj3efXBcm6uTIVIgDg4rqUpqKXvLEuFRVuEpSAOkhgNeecvaZ4Cg==", - "cpu": [ - "loong64" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-loong64-musl": { - "version": "4.62.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.62.0.tgz", - "integrity": "sha512-m9tsJz54LUXkSYM8+8PG81B9IKK5r+2T0clMq4QrS16xFosufU7firBDAZEsDheDs7wTlP7h3++S7lMsU955HA==", - "cpu": [ - "loong64" - ], - "dev": true, - "libc": [ - "musl" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-ppc64-gnu": { - "version": "4.62.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.62.0.tgz", - "integrity": "sha512-3UvJ5PNVU16aJf6M3tFI24pWzAl2/ynfbyRN3ICyQajK1lSkrnVYNnLz3v04J32qKa0FczJc22zeToc0lr2A3w==", - "cpu": [ - "ppc64" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-ppc64-musl": { - "version": "4.62.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.62.0.tgz", - "integrity": "sha512-vRWUAbYLGHBZS6Q8Msb2sfnf1fvJf+47t8l/TwOerM2qArzy+IeNMTHrYLHXh95h8MoatPHI5hhSZNs+mGXKPg==", - "cpu": [ - "ppc64" - ], - "dev": true, - "libc": [ - "musl" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.62.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.62.0.tgz", - "integrity": "sha512-c00T5SYENHAt86cfW47URaP3Us5vLC/4QO7GYud1G5VNRffCwwCuBspwqYrriuJB+5m0WFzClCn9wed0FBjKvg==", - "cpu": [ - "riscv64" - ], - "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.62.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.62.0.tgz", - "integrity": "sha512-krrCDilhXOwFkSkO3Wm9I/f9H0L92XHHwy2fwxjukxIbh0dem8gZqOW5Y8BsHrpJv5qwlRBV+Wl4ZFyRWhUpwg==", - "cpu": [ - "riscv64" - ], - "dev": true, - "libc": [ - "musl" + "darwin" ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] + "engines": { + "node": ">=18" + } }, - "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.62.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.62.0.tgz", - "integrity": "sha512-7pfYFSTc4/rUC/FtAI0Qp6QthDBCIi6/AuP1xYqFk5vanI6KnL5dWKP60OM/05LOsbwTmIcvr6eXC4CJuJ75IA==", - "cpu": [ - "s390x" - ], + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", - "optional": true, - "os": [ - "linux" - ] + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } }, - "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.62.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.62.0.tgz", - "integrity": "sha512-7SDIalKeIpG0Ifogbbdn58HmSotYMlf23K3dCJEmiVd9Fg36Vmni82iPQec27N3wY4Bvbxftkxz6vSx9OcouTg==", - "cpu": [ - "x64" - ], + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", - "optional": true, - "os": [ - "linux" - ] + "engines": { + "node": ">=6.0.0" + } }, - "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.62.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.62.0.tgz", - "integrity": "sha512-eRZevouTH2i1HeAVLqJuLnt256krQkGY0TN6WsTmsIhuzbh457HuWDMakKwmi0Cjadux983CoSr8Lim2QhUIFw==", - "cpu": [ - "x64" - ], + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", "dev": true, - "libc": [ - "musl" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] + "license": "MIT" }, - "node_modules/@rollup/rollup-openbsd-x64": { - "version": "4.62.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.62.0.tgz", - "integrity": "sha512-3oVS7FLGa4U1qcvao9ylGxrjXZyUQqR8UwxEcnUEyPX53O/C/mKDZegNXTdHCP+h3e6ta/f1EN38Yif1mmZHYg==", - "cpu": [ - "x64" - ], + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ] + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } }, - "node_modules/@rollup/rollup-openharmony-arm64": { - "version": "4.62.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.62.0.tgz", - "integrity": "sha512-yTB9TgfWj5wHe5QgktAgXTLLot1gvEjl1NiPPAUiCs4oPrIWFl5V4nC3GrkNdj9LaAU4s94nVrGbGOCqUpyWsg==", - "cpu": [ - "arm64" - ], + "node_modules/@oxc-project/types": { + "version": "0.122.0", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ] + "funding": { + "url": "https://github.com/sponsors/Boshen" + } }, - "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.62.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.62.0.tgz", - "integrity": "sha512-5LOhoaesY3doG1c+ac/2JtgREpKoJr5bUHH8tKY0V8di7+uSV6BwLs2PlR0/yzefGOkR+wE7ZolZphHCsyG5Rw==", + "node_modules/@rolldown/binding-darwin-arm64": { + "version": "1.0.0-rc.11", "cpu": [ "arm64" ], @@ -3075,70 +1942,40 @@ "license": "MIT", "optional": true, "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.62.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.62.0.tgz", - "integrity": "sha512-yYkWHhmbhRTWTnWos5HC4GcPQfjlzzCNbM9e/+GXrLuaBXYA3qSDR9f0Vgufd5S8yX81U8jPKp7ZnAjZFMtRnw==", - "cpu": [ - "ia32" + "darwin" ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-win32-x64-gnu": { - "version": "4.62.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.62.0.tgz", - "integrity": "sha512-SoTb6lPg25xZlA2ibwQ++ahCCnH+FP0qmEuafMJ4gznZKOlXioKEAeJLgCrqjM98ACziXM9V1amFjICVL4IFoA==", - "cpu": [ - "x64" - ], + "node_modules/@rolldown/pluginutils": { + "version": "1.0.0-rc.11", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] + "license": "MIT" }, - "node_modules/@rollup/rollup-win32-x64-msvc": { + "node_modules/@rollup/rollup-darwin-arm64": { "version": "4.62.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.62.0.tgz", - "integrity": "sha512-5L+T1fMX4RIEBoZzT0+sQ0PhTS36NULFmMXtl1TZo44TMAROIMHbZufSOjVWt/Y622BtxgxtaNOokbTDvfsrZA==", "cpu": [ - "x64" + "arm64" ], "dev": true, "license": "MIT", "optional": true, "os": [ - "win32" + "darwin" ] }, "node_modules/@standard-schema/spec": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", - "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", "dev": true, "license": "MIT" }, - "node_modules/@studiolxd/react-scorm": { - "resolved": "packages/react-scorm", - "link": true - }, "node_modules/@studiolxd/scorm": { "resolved": "packages/scorm", "link": true }, "node_modules/@testing-library/dom": { "version": "10.4.1", - "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.1.tgz", - "integrity": "sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==", "dev": true, "license": "MIT", "dependencies": { @@ -3157,8 +1994,6 @@ }, "node_modules/@testing-library/react": { "version": "16.3.2", - "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-16.3.2.tgz", - "integrity": "sha512-XU5/SytQM+ykqMnAnvB2umaJNIOsLF3PVv//1Ew4CTcpz0/BRyy/af40qqrt7SjKpDdT1saBMc42CUok5gaw+g==", "dev": true, "license": "MIT", "dependencies": { @@ -3167,202 +2002,64 @@ "engines": { "node": ">=18" }, - "peerDependencies": { - "@testing-library/dom": "^10.0.0", - "@types/react": "^18.0.0 || ^19.0.0", - "@types/react-dom": "^18.0.0 || ^19.0.0", - "react": "^18.0.0 || ^19.0.0", - "react-dom": "^18.0.0 || ^19.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@tybys/wasm-util": { - "version": "0.10.1", - "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz", - "integrity": "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@types/aria-query": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", - "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/chai": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz", - "integrity": "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/deep-eql": "*", - "assertion-error": "^2.0.1" - } - }, - "node_modules/@types/deep-eql": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", - "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/estree": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", - "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/react": { - "version": "19.2.17", - "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.17.tgz", - "integrity": "sha512-MXfmqaVPEVgkBT/aY0aGCkRWWtByiYQXo3xdQ8r5RzuFrPiRn8Gar2tQdXSUQ2GKV3bkXckek89V8wQBY2Q/Aw==", - "dev": true, - "license": "MIT", - "dependencies": { - "csstype": "^3.2.2" - } - }, - "node_modules/@types/react-dom": { - "version": "19.2.3", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz", - "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "@types/react": "^19.2.0" - } - }, - "node_modules/@vitest/expect": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.1.tgz", - "integrity": "sha512-xAV0fqBTk44Rn6SjJReEQkHP3RrqbJo6JQ4zZ7/uVOiJZRarBtblzrOfFIZeYUrukp2YD6snZG6IBqhOoHTm+A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@standard-schema/spec": "^1.1.0", - "@types/chai": "^5.2.2", - "@vitest/spy": "4.1.1", - "@vitest/utils": "4.1.1", - "chai": "^6.2.2", - "tinyrainbow": "^3.0.3" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/mocker": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.1.tgz", - "integrity": "sha512-h3BOylsfsCLPeceuCPAAJ+BvNwSENgJa4hXoXu4im0bs9Lyp4URc4JYK4pWLZ4pG/UQn7AT92K6IByi6rE6g3A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@vitest/spy": "4.1.1", - "estree-walker": "^3.0.3", - "magic-string": "^0.30.21" - }, - "funding": { - "url": "https://opencollective.com/vitest" - }, - "peerDependencies": { - "msw": "^2.4.9", - "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" + "peerDependencies": { + "@testing-library/dom": "^10.0.0", + "@types/react": "^18.0.0 || ^19.0.0", + "@types/react-dom": "^18.0.0 || ^19.0.0", + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" }, "peerDependenciesMeta": { - "msw": { + "@types/react": { "optional": true }, - "vite": { + "@types/react-dom": { "optional": true } } }, - "node_modules/@vitest/pretty-format": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.1.tgz", - "integrity": "sha512-GM+TEQN5WhOygr1lp7skeVjdLPqqWMHsfzXrcHAqZJi/lIVh63H0kaRCY8MDhNWikx19zBUK8ceaLB7X5AH9NQ==", + "node_modules/@types/aria-query": { + "version": "5.0.4", "dev": true, - "license": "MIT", - "dependencies": { - "tinyrainbow": "^3.0.3" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } + "license": "MIT" }, - "node_modules/@vitest/runner": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.1.tgz", - "integrity": "sha512-f7+FPy75vN91QGWsITueq0gedwUZy1fLtHOCMeQpjs8jTekAHeKP80zfDEnhrleviLHzVSDXIWuCIOFn3D3f8A==", + "node_modules/@types/chai": { + "version": "5.2.3", "dev": true, "license": "MIT", "dependencies": { - "@vitest/utils": "4.1.1", - "pathe": "^2.0.3" - }, - "funding": { - "url": "https://opencollective.com/vitest" + "@types/deep-eql": "*", + "assertion-error": "^2.0.1" } }, - "node_modules/@vitest/snapshot": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.1.tgz", - "integrity": "sha512-kMVSgcegWV2FibXEx9p9WIKgje58lcTbXgnJixfcg15iK8nzCXhmalL0ZLtTWLW9PH1+1NEDShiFFedB3tEgWg==", + "node_modules/@types/deep-eql": { + "version": "4.0.2", "dev": true, - "license": "MIT", - "dependencies": { - "@vitest/pretty-format": "4.1.1", - "@vitest/utils": "4.1.1", - "magic-string": "^0.30.21", - "pathe": "^2.0.3" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } + "license": "MIT" }, - "node_modules/@vitest/spy": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.1.tgz", - "integrity": "sha512-6Ti/KT5OVaiupdIZEuZN7l3CZcR0cxnxt70Z0//3CtwgObwA6jZhmVBA3yrXSVN3gmwjgd7oDNLlsXz526gpRA==", + "node_modules/@types/estree": { + "version": "1.0.9", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/react": { + "version": "19.2.17", "dev": true, "license": "MIT", - "funding": { - "url": "https://opencollective.com/vitest" + "dependencies": { + "csstype": "^3.2.2" } }, - "node_modules/@vitest/utils": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.1.tgz", - "integrity": "sha512-cNxAlaB3sHoCdL6pj6yyUXv9Gry1NHNg0kFTXdvSIZXLHsqKH7chiWOkwJ5s5+d/oMwcoG9T0bKU38JZWKusrQ==", + "node_modules/@types/react-dom": { + "version": "19.2.3", "dev": true, "license": "MIT", - "dependencies": { - "@vitest/pretty-format": "4.1.1", - "convert-source-map": "^2.0.0", - "tinyrainbow": "^3.0.3" - }, - "funding": { - "url": "https://opencollective.com/vitest" + "peerDependencies": { + "@types/react": "^19.2.0" } }, "node_modules/@vue/compiler-core": { "version": "3.5.38", - "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.38.tgz", - "integrity": "sha512-s99aGxWYig9ErHbct27KXEGhrBYlRI6c4MwAgXErOAbX9xiW37/uMa+XUDO69zLz83dng8UUZ70CTOJrLrYrEQ==", "dev": true, "license": "MIT", "dependencies": { @@ -3375,8 +2072,6 @@ }, "node_modules/@vue/compiler-core/node_modules/entities": { "version": "7.0.1", - "resolved": "https://registry.npmjs.org/entities/-/entities-7.0.1.tgz", - "integrity": "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==", "dev": true, "license": "BSD-2-Clause", "engines": { @@ -3388,15 +2083,11 @@ }, "node_modules/@vue/compiler-core/node_modules/estree-walker": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", "dev": true, "license": "MIT" }, "node_modules/@vue/compiler-dom": { "version": "3.5.38", - "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.38.tgz", - "integrity": "sha512-JTqp25l8aFfJYF7/KmsXZjAxJz7T+SjmTJLoXVjHtc2BrSgSiW2n9Aem/cWq1OPe68A8JL06B3eVdhlP0H4TVw==", "dev": true, "license": "MIT", "dependencies": { @@ -3406,8 +2097,6 @@ }, "node_modules/@vue/compiler-sfc": { "version": "3.5.38", - "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.38.tgz", - "integrity": "sha512-DuA2GiZawSEW442iw/9+Fkol8hTgb4Ke5KkhmSry65QA7YuyMbIdy8p0XZRMvNwJdgRz307W8g1CSzdvS4nuNg==", "dev": true, "license": "MIT", "dependencies": { @@ -3424,15 +2113,11 @@ }, "node_modules/@vue/compiler-sfc/node_modules/estree-walker": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", "dev": true, "license": "MIT" }, "node_modules/@vue/compiler-ssr": { "version": "3.5.38", - "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.38.tgz", - "integrity": "sha512-7s+W5Gc42FGxZMcuwl8H5B29T8BJPMdBT7KHFE+BbAuZ/iTEdTtv7z2XiMjiaUUw4w3ZcCEdHs36RuYJ2VA7bA==", "dev": true, "license": "MIT", "dependencies": { @@ -3442,8 +2127,6 @@ }, "node_modules/@vue/reactivity": { "version": "3.5.38", - "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.38.tgz", - "integrity": "sha512-pG6LV/NDNRbKizcUjFFLAfjaL8mcv4DmR9avNcUw2gDHBzZneuS2TWCmp633ynzxz9YYKNeEPK2I8Wraqy2HUQ==", "dev": true, "license": "MIT", "dependencies": { @@ -3452,8 +2135,6 @@ }, "node_modules/@vue/runtime-core": { "version": "3.5.38", - "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.38.tgz", - "integrity": "sha512-iyW8WVfF1CpCXxncZY5Ei6rSd6oZr5DgEom//fUjRBRl56AXPD+s9ATvukRt77ZFTuYlnVA1bxY+dJB94tWVYw==", "dev": true, "license": "MIT", "dependencies": { @@ -3463,8 +2144,6 @@ }, "node_modules/@vue/runtime-dom": { "version": "3.5.38", - "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.38.tgz", - "integrity": "sha512-apX2wt9sdfDshS+a2xueFZLVpt0GkRJZSoPmrW/SA4yzXTznhfcMVW59gr7h4YQeY0vJhdJkk2rsIDwgfFgC5A==", "dev": true, "license": "MIT", "dependencies": { @@ -3476,8 +2155,6 @@ }, "node_modules/@vue/server-renderer": { "version": "3.5.38", - "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.38.tgz", - "integrity": "sha512-vue8vbf2QlV4quHqzwmJy6dWfmRhP1J8l4wtZg60CL6VoKqcPY2oe7may3+1d9qfpedjK5PRLFqd5k3Isj9mUw==", "dev": true, "license": "MIT", "dependencies": { @@ -3490,15 +2167,11 @@ }, "node_modules/@vue/shared": { "version": "3.5.38", - "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.38.tgz", - "integrity": "sha512-FTW0AFZNaK5/mOqvGBwVfUlNLU38TiQn4+DQgIFUnrBBJQ1crMJ82yeGQLV5jyKFsO8yRukpbuP7x+nRbH6aug==", "dev": true, "license": "MIT" }, "node_modules/acorn": { "version": "8.17.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.17.0.tgz", - "integrity": "sha512-xRQbDb9BnwDafYNn6Vwl839DYVjqXYb1XVGtWAZ1kcDc6iwAL4hg3B1dZlRiuENFeO2H53gFG3in621AdERVAg==", "dev": true, "license": "MIT", "bin": { @@ -3510,8 +2183,6 @@ }, "node_modules/agent-base": { "version": "7.1.4", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", - "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", "dev": true, "license": "MIT", "engines": { @@ -3520,8 +2191,6 @@ }, "node_modules/ansi-regex": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, "license": "MIT", "engines": { @@ -3530,8 +2199,6 @@ }, "node_modules/ansi-styles": { "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, "license": "MIT", "engines": { @@ -3543,15 +2210,11 @@ }, "node_modules/any-promise": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", - "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", "dev": true, "license": "MIT" }, "node_modules/aria-query": { "version": "5.3.0", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", - "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -3560,8 +2223,6 @@ }, "node_modules/assertion-error": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", - "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", "dev": true, "license": "MIT", "engines": { @@ -3570,8 +2231,6 @@ }, "node_modules/ast-v8-to-istanbul": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/ast-v8-to-istanbul/-/ast-v8-to-istanbul-1.0.4.tgz", - "integrity": "sha512-0bC0/4bTSrnwdhU3IsZDwEdojvuPrSg59OYZfKsLRtJZ0u8VBx9DebfqqG8bRdCC0I7vjgxmPi41P0lpkhJHtA==", "dev": true, "license": "MIT", "dependencies": { @@ -3582,22 +2241,16 @@ }, "node_modules/ast-v8-to-istanbul/node_modules/js-tokens": { "version": "10.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-10.0.0.tgz", - "integrity": "sha512-lM/UBzQmfJRo9ABXbPWemivdCW8V2G8FHaHdypQaIy523snUjog0W71ayWXTjiR+ixeMyVHN2XcpnTd/liPg/Q==", "dev": true, "license": "MIT" }, "node_modules/asynckit": { "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", "dev": true, "license": "MIT" }, "node_modules/axobject-query": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", - "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==", "dev": true, "license": "Apache-2.0", "engines": { @@ -3606,8 +2259,6 @@ }, "node_modules/bundle-require": { "version": "5.1.0", - "resolved": "https://registry.npmjs.org/bundle-require/-/bundle-require-5.1.0.tgz", - "integrity": "sha512-3WrrOuZiyaaZPWiEt4G3+IffISVC9HYlWueJEBWED4ZH4aIAC2PnkdnuRrR94M+w6yGWn4AglWtJtBI8YqvgoA==", "dev": true, "license": "MIT", "dependencies": { @@ -3622,8 +2273,6 @@ }, "node_modules/cac": { "version": "6.7.14", - "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", - "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", "dev": true, "license": "MIT", "engines": { @@ -3632,8 +2281,6 @@ }, "node_modules/call-bind-apply-helpers": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", - "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", "dev": true, "license": "MIT", "dependencies": { @@ -3646,8 +2293,6 @@ }, "node_modules/chai": { "version": "6.2.2", - "resolved": "https://registry.npmjs.org/chai/-/chai-6.2.2.tgz", - "integrity": "sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==", "dev": true, "license": "MIT", "engines": { @@ -3656,8 +2301,6 @@ }, "node_modules/chokidar": { "version": "4.0.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", - "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", "dev": true, "license": "MIT", "dependencies": { @@ -3672,8 +2315,6 @@ }, "node_modules/code-red": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/code-red/-/code-red-1.0.4.tgz", - "integrity": "sha512-7qJWqItLA8/VPVlKJlFXU+NBlo/qyfs39aJcuMT/2ere32ZqvF5OSxgdM5xOfJJ7O429gg2HM47y8v9P+9wrNw==", "dev": true, "license": "MIT", "dependencies": { @@ -3686,8 +2327,6 @@ }, "node_modules/color-convert": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "license": "MIT", "dependencies": { @@ -3699,15 +2338,11 @@ }, "node_modules/color-name": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true, "license": "MIT" }, "node_modules/combined-stream": { "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", "dev": true, "license": "MIT", "dependencies": { @@ -3719,8 +2354,6 @@ }, "node_modules/commander": { "version": "4.1.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", - "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", "dev": true, "license": "MIT", "engines": { @@ -3729,15 +2362,11 @@ }, "node_modules/confbox": { "version": "0.1.8", - "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz", - "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==", "dev": true, "license": "MIT" }, "node_modules/consola": { "version": "3.4.2", - "resolved": "https://registry.npmjs.org/consola/-/consola-3.4.2.tgz", - "integrity": "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==", "dev": true, "license": "MIT", "engines": { @@ -3746,15 +2375,11 @@ }, "node_modules/convert-source-map": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", "dev": true, "license": "MIT" }, "node_modules/cross-spawn": { "version": "7.0.6", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", - "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, "license": "MIT", "dependencies": { @@ -3768,8 +2393,6 @@ }, "node_modules/css-tree": { "version": "2.3.1", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", - "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", "dev": true, "license": "MIT", "dependencies": { @@ -3782,8 +2405,6 @@ }, "node_modules/cssstyle": { "version": "4.6.0", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.6.0.tgz", - "integrity": "sha512-2z+rWdzbbSZv6/rhtvzvqeZQHrBaqgogqt85sqFNbabZOuFbCVFb8kPeEtZjiKkbrm395irpNKiYeFeLiQnFPg==", "dev": true, "license": "MIT", "dependencies": { @@ -3796,22 +2417,16 @@ }, "node_modules/cssstyle/node_modules/rrweb-cssom": { "version": "0.8.0", - "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.8.0.tgz", - "integrity": "sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==", "dev": true, "license": "MIT" }, "node_modules/csstype": { "version": "3.2.3", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", - "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", "dev": true, "license": "MIT" }, "node_modules/data-urls": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-5.0.0.tgz", - "integrity": "sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==", "dev": true, "license": "MIT", "dependencies": { @@ -3824,8 +2439,6 @@ }, "node_modules/debug": { "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", "dev": true, "license": "MIT", "dependencies": { @@ -3842,15 +2455,11 @@ }, "node_modules/decimal.js": { "version": "10.6.0", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.6.0.tgz", - "integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==", "dev": true, "license": "MIT" }, "node_modules/delayed-stream": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", "dev": true, "license": "MIT", "engines": { @@ -3859,8 +2468,6 @@ }, "node_modules/dequal": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", - "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", "dev": true, "license": "MIT", "engines": { @@ -3869,8 +2476,6 @@ }, "node_modules/detect-libc": { "version": "2.1.2", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", - "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", "dev": true, "license": "Apache-2.0", "engines": { @@ -3879,15 +2484,11 @@ }, "node_modules/dom-accessibility-api": { "version": "0.5.16", - "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz", - "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==", "dev": true, "license": "MIT" }, "node_modules/dunder-proto": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", - "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", "dev": true, "license": "MIT", "dependencies": { @@ -3901,8 +2502,6 @@ }, "node_modules/entities": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", - "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", "dev": true, "license": "BSD-2-Clause", "engines": { @@ -3914,8 +2513,6 @@ }, "node_modules/es-define-property": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", - "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", "dev": true, "license": "MIT", "engines": { @@ -3924,8 +2521,6 @@ }, "node_modules/es-errors": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", "dev": true, "license": "MIT", "engines": { @@ -3934,15 +2529,11 @@ }, "node_modules/es-module-lexer": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.0.0.tgz", - "integrity": "sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw==", "dev": true, "license": "MIT" }, "node_modules/es-object-atoms": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", - "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", "dev": true, "license": "MIT", "dependencies": { @@ -3954,8 +2545,6 @@ }, "node_modules/es-set-tostringtag": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", - "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", "dev": true, "license": "MIT", "dependencies": { @@ -3970,8 +2559,6 @@ }, "node_modules/esbuild": { "version": "0.27.7", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.7.tgz", - "integrity": "sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w==", "dev": true, "hasInstallScript": true, "license": "MIT", @@ -4012,8 +2599,6 @@ }, "node_modules/estree-walker": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", - "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", "dev": true, "license": "MIT", "dependencies": { @@ -4022,8 +2607,6 @@ }, "node_modules/expect-type": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.3.0.tgz", - "integrity": "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==", "dev": true, "license": "Apache-2.0", "engines": { @@ -4032,8 +2615,6 @@ }, "node_modules/fdir": { "version": "6.5.0", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", - "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", "dev": true, "license": "MIT", "engines": { @@ -4050,8 +2631,6 @@ }, "node_modules/fix-dts-default-cjs-exports": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/fix-dts-default-cjs-exports/-/fix-dts-default-cjs-exports-1.0.1.tgz", - "integrity": "sha512-pVIECanWFC61Hzl2+oOCtoJ3F17kglZC/6N94eRWycFgBH35hHx0Li604ZIzhseh97mf2p0cv7vVrOZGoqhlEg==", "dev": true, "license": "MIT", "dependencies": { @@ -4062,8 +2641,6 @@ }, "node_modules/form-data": { "version": "4.0.5", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", - "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", "dev": true, "license": "MIT", "dependencies": { @@ -4079,10 +2656,7 @@ }, "node_modules/fsevents": { "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, - "hasInstallScript": true, "license": "MIT", "optional": true, "os": [ @@ -4094,8 +2668,6 @@ }, "node_modules/function-bind": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", "dev": true, "license": "MIT", "funding": { @@ -4104,8 +2676,6 @@ }, "node_modules/get-intrinsic": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", - "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", "dev": true, "license": "MIT", "dependencies": { @@ -4129,8 +2699,6 @@ }, "node_modules/get-proto": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", - "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", "dev": true, "license": "MIT", "dependencies": { @@ -4143,8 +2711,6 @@ }, "node_modules/gopd": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", - "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", "dev": true, "license": "MIT", "engines": { @@ -4156,8 +2722,6 @@ }, "node_modules/has-flag": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, "license": "MIT", "engines": { @@ -4166,8 +2730,6 @@ }, "node_modules/has-symbols": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", - "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", "dev": true, "license": "MIT", "engines": { @@ -4179,8 +2741,6 @@ }, "node_modules/has-tostringtag": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", - "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", "dev": true, "license": "MIT", "dependencies": { @@ -4195,8 +2755,6 @@ }, "node_modules/hasown": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", "dev": true, "license": "MIT", "dependencies": { @@ -4208,8 +2766,6 @@ }, "node_modules/html-encoding-sniffer": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz", - "integrity": "sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==", "dev": true, "license": "MIT", "dependencies": { @@ -4221,15 +2777,11 @@ }, "node_modules/html-escaper": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", "dev": true, "license": "MIT" }, "node_modules/http-proxy-agent": { "version": "7.0.2", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", - "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", "dev": true, "license": "MIT", "dependencies": { @@ -4242,8 +2794,6 @@ }, "node_modules/https-proxy-agent": { "version": "7.0.6", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", - "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", "dev": true, "license": "MIT", "dependencies": { @@ -4256,8 +2806,6 @@ }, "node_modules/iconv-lite": { "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", "dev": true, "license": "MIT", "dependencies": { @@ -4269,15 +2817,11 @@ }, "node_modules/is-potential-custom-element-name": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", - "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", "dev": true, "license": "MIT" }, "node_modules/is-reference": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.3.tgz", - "integrity": "sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw==", "dev": true, "license": "MIT", "dependencies": { @@ -4286,372 +2830,132 @@ }, "node_modules/isexe": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true, "license": "ISC" }, "node_modules/istanbul-lib-coverage": { "version": "3.2.2", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", - "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", "dev": true, "license": "BSD-3-Clause", - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-report": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", - "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^4.0.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/istanbul-reports": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz", - "integrity": "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/joycon": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/joycon/-/joycon-3.1.1.tgz", - "integrity": "sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - } - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/jsdom": { - "version": "25.0.1", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-25.0.1.tgz", - "integrity": "sha512-8i7LzZj7BF8uplX+ZyOlIz86V6TAsSs+np6m1kpW9u0JWi4z/1t+FzcK1aek+ybTnAC4KhBL4uXCNT0wcUIeCw==", - "dev": true, - "license": "MIT", - "dependencies": { - "cssstyle": "^4.1.0", - "data-urls": "^5.0.0", - "decimal.js": "^10.4.3", - "form-data": "^4.0.0", - "html-encoding-sniffer": "^4.0.0", - "http-proxy-agent": "^7.0.2", - "https-proxy-agent": "^7.0.5", - "is-potential-custom-element-name": "^1.0.1", - "nwsapi": "^2.2.12", - "parse5": "^7.1.2", - "rrweb-cssom": "^0.7.1", - "saxes": "^6.0.0", - "symbol-tree": "^3.2.4", - "tough-cookie": "^5.0.0", - "w3c-xmlserializer": "^5.0.0", - "webidl-conversions": "^7.0.0", - "whatwg-encoding": "^3.1.1", - "whatwg-mimetype": "^4.0.0", - "whatwg-url": "^14.0.0", - "ws": "^8.18.0", - "xml-name-validator": "^5.0.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "canvas": "^2.11.2" - }, - "peerDependenciesMeta": { - "canvas": { - "optional": true - } - } - }, - "node_modules/lightningcss": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz", - "integrity": "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==", - "dev": true, - "license": "MPL-2.0", - "dependencies": { - "detect-libc": "^2.0.3" - }, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - }, - "optionalDependencies": { - "lightningcss-android-arm64": "1.32.0", - "lightningcss-darwin-arm64": "1.32.0", - "lightningcss-darwin-x64": "1.32.0", - "lightningcss-freebsd-x64": "1.32.0", - "lightningcss-linux-arm-gnueabihf": "1.32.0", - "lightningcss-linux-arm64-gnu": "1.32.0", - "lightningcss-linux-arm64-musl": "1.32.0", - "lightningcss-linux-x64-gnu": "1.32.0", - "lightningcss-linux-x64-musl": "1.32.0", - "lightningcss-win32-arm64-msvc": "1.32.0", - "lightningcss-win32-x64-msvc": "1.32.0" - } - }, - "node_modules/lightningcss-android-arm64": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz", - "integrity": "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-darwin-arm64": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz", - "integrity": "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-darwin-x64": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz", - "integrity": "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-freebsd-x64": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz", - "integrity": "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-arm-gnueabihf": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz", - "integrity": "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "engines": { + "node": ">=8" } }, - "node_modules/lightningcss-linux-arm64-gnu": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz", - "integrity": "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==", - "cpu": [ - "arm64" - ], + "node_modules/istanbul-lib-report": { + "version": "3.0.1", "dev": true, - "libc": [ - "glibc" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" + "license": "BSD-3-Clause", + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "engines": { + "node": ">=10" } }, - "node_modules/lightningcss-linux-arm64-musl": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz", - "integrity": "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==", - "cpu": [ - "arm64" - ], + "node_modules/istanbul-reports": { + "version": "3.2.0", "dev": true, - "libc": [ - "musl" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" + "license": "BSD-3-Clause", + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "engines": { + "node": ">=8" } }, - "node_modules/lightningcss-linux-x64-gnu": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz", - "integrity": "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==", - "cpu": [ - "x64" - ], + "node_modules/joycon": { + "version": "3.1.1", "dev": true, - "libc": [ - "glibc" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], + "license": "MIT", "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "node": ">=10" } }, - "node_modules/lightningcss-linux-x64-musl": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz", - "integrity": "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==", - "cpu": [ - "x64" - ], + "node_modules/js-tokens": { + "version": "4.0.0", "dev": true, - "libc": [ - "musl" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], + "license": "MIT" + }, + "node_modules/jsdom": { + "version": "25.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "cssstyle": "^4.1.0", + "data-urls": "^5.0.0", + "decimal.js": "^10.4.3", + "form-data": "^4.0.0", + "html-encoding-sniffer": "^4.0.0", + "http-proxy-agent": "^7.0.2", + "https-proxy-agent": "^7.0.5", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.12", + "parse5": "^7.1.2", + "rrweb-cssom": "^0.7.1", + "saxes": "^6.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^5.0.0", + "w3c-xmlserializer": "^5.0.0", + "webidl-conversions": "^7.0.0", + "whatwg-encoding": "^3.1.1", + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^14.0.0", + "ws": "^8.18.0", + "xml-name-validator": "^5.0.0" + }, "engines": { - "node": ">= 12.0.0" + "node": ">=18" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "peerDependencies": { + "canvas": "^2.11.2" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } } }, - "node_modules/lightningcss-win32-arm64-msvc": { + "node_modules/lightningcss": { "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz", - "integrity": "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==", - "cpu": [ - "arm64" - ], "dev": true, "license": "MPL-2.0", - "optional": true, - "os": [ - "win32" - ], + "dependencies": { + "detect-libc": "^2.0.3" + }, "engines": { "node": ">= 12.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-android-arm64": "1.32.0", + "lightningcss-darwin-arm64": "1.32.0", + "lightningcss-darwin-x64": "1.32.0", + "lightningcss-freebsd-x64": "1.32.0", + "lightningcss-linux-arm-gnueabihf": "1.32.0", + "lightningcss-linux-arm64-gnu": "1.32.0", + "lightningcss-linux-arm64-musl": "1.32.0", + "lightningcss-linux-x64-gnu": "1.32.0", + "lightningcss-linux-x64-musl": "1.32.0", + "lightningcss-win32-arm64-msvc": "1.32.0", + "lightningcss-win32-x64-msvc": "1.32.0" } }, - "node_modules/lightningcss-win32-x64-msvc": { + "node_modules/lightningcss-darwin-arm64": { "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz", - "integrity": "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==", "cpu": [ - "x64" + "arm64" ], "dev": true, "license": "MPL-2.0", "optional": true, "os": [ - "win32" + "darwin" ], "engines": { "node": ">= 12.0.0" @@ -4663,8 +2967,6 @@ }, "node_modules/lilconfig": { "version": "3.1.3", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", - "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", "dev": true, "license": "MIT", "engines": { @@ -4676,15 +2978,11 @@ }, "node_modules/lines-and-columns": { "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", "dev": true, "license": "MIT" }, "node_modules/load-tsconfig": { "version": "0.2.5", - "resolved": "https://registry.npmjs.org/load-tsconfig/-/load-tsconfig-0.2.5.tgz", - "integrity": "sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==", "dev": true, "license": "MIT", "engines": { @@ -4693,22 +2991,16 @@ }, "node_modules/locate-character": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-character/-/locate-character-3.0.0.tgz", - "integrity": "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==", "dev": true, "license": "MIT" }, "node_modules/lru-cache": { "version": "10.4.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", - "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", "dev": true, "license": "ISC" }, "node_modules/lz-string": { "version": "1.5.0", - "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz", - "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", "dev": true, "license": "MIT", "bin": { @@ -4717,8 +3009,6 @@ }, "node_modules/magic-string": { "version": "0.30.21", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", - "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", "dev": true, "license": "MIT", "dependencies": { @@ -4727,8 +3017,6 @@ }, "node_modules/magicast": { "version": "0.5.3", - "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.5.3.tgz", - "integrity": "sha512-pVKE4UdSQ7DvHzivsCIFx2BJn1mHG6KsyrFcaxFx6tONdneEuThrDx0Cj3AMg58KyN4pzYT+LHOotxDQDjNvkw==", "dev": true, "license": "MIT", "dependencies": { @@ -4739,8 +3027,6 @@ }, "node_modules/make-dir": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", - "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", "dev": true, "license": "MIT", "dependencies": { @@ -4755,8 +3041,6 @@ }, "node_modules/math-intrinsics": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", - "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", "dev": true, "license": "MIT", "engines": { @@ -4765,15 +3049,11 @@ }, "node_modules/mdn-data": { "version": "2.0.30", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", - "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", "dev": true, "license": "CC0-1.0" }, "node_modules/mime-db": { "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", "dev": true, "license": "MIT", "engines": { @@ -4782,8 +3062,6 @@ }, "node_modules/mime-types": { "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", "dev": true, "license": "MIT", "dependencies": { @@ -4795,8 +3073,6 @@ }, "node_modules/mlly": { "version": "1.8.2", - "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.8.2.tgz", - "integrity": "sha512-d+ObxMQFmbt10sretNDytwt85VrbkhhUA/JBGm1MPaWJ65Cl4wOgLaB1NYvJSZ0Ef03MMEU/0xpPMXUIQ29UfA==", "dev": true, "license": "MIT", "dependencies": { @@ -4808,19 +3084,11 @@ }, "node_modules/ms": { "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true, "license": "MIT" }, - "node_modules/my-app": { - "resolved": "example", - "link": true - }, "node_modules/mz": { "version": "2.7.0", - "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", - "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", "dev": true, "license": "MIT", "dependencies": { @@ -4831,8 +3099,6 @@ }, "node_modules/nanoid": { "version": "3.3.12", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.12.tgz", - "integrity": "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==", "dev": true, "funding": [ { @@ -4850,15 +3116,11 @@ }, "node_modules/nwsapi": { "version": "2.2.23", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.23.tgz", - "integrity": "sha512-7wfH4sLbt4M0gCDzGE6vzQBo0bfTKjU7Sfpqy/7gs1qBfYz2vEJH6vXcBKpO3+6Yu1telwd0t9HpyOoLEQQbIQ==", "dev": true, "license": "MIT" }, "node_modules/object-assign": { "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", "dev": true, "license": "MIT", "engines": { @@ -4867,8 +3129,6 @@ }, "node_modules/obug": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.1.tgz", - "integrity": "sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==", "dev": true, "funding": [ "https://github.com/sponsors/sxzz", @@ -4878,8 +3138,6 @@ }, "node_modules/parse5": { "version": "7.3.0", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", - "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", "dev": true, "license": "MIT", "dependencies": { @@ -4891,8 +3149,6 @@ }, "node_modules/path-key": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true, "license": "MIT", "engines": { @@ -4901,15 +3157,11 @@ }, "node_modules/pathe": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", - "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", "dev": true, "license": "MIT" }, "node_modules/periscopic": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/periscopic/-/periscopic-3.1.0.tgz", - "integrity": "sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==", "dev": true, "license": "MIT", "dependencies": { @@ -4920,15 +3172,11 @@ }, "node_modules/picocolors": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", - "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", "dev": true, "license": "ISC" }, "node_modules/picomatch": { "version": "4.0.4", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", - "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", "dev": true, "license": "MIT", "engines": { @@ -4940,8 +3188,6 @@ }, "node_modules/pirates": { "version": "4.0.7", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz", - "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==", "dev": true, "license": "MIT", "engines": { @@ -4950,8 +3196,6 @@ }, "node_modules/pkg-types": { "version": "1.3.1", - "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.3.1.tgz", - "integrity": "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==", "dev": true, "license": "MIT", "dependencies": { @@ -4962,8 +3206,6 @@ }, "node_modules/postcss": { "version": "8.5.15", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.15.tgz", - "integrity": "sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==", "dev": true, "funding": [ { @@ -4991,8 +3233,6 @@ }, "node_modules/postcss-load-config": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-6.0.1.tgz", - "integrity": "sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==", "dev": true, "funding": [ { @@ -5034,8 +3274,6 @@ }, "node_modules/pretty-format": { "version": "27.5.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", - "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", "dev": true, "license": "MIT", "dependencies": { @@ -5049,8 +3287,6 @@ }, "node_modules/punycode": { "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "dev": true, "license": "MIT", "engines": { @@ -5059,8 +3295,6 @@ }, "node_modules/react": { "version": "19.2.7", - "resolved": "https://registry.npmjs.org/react/-/react-19.2.7.tgz", - "integrity": "sha512-HNe9WslTbXmFK8o8cmwgAeJFSBvt1bPdHCVKtaaV+WlAN36mpT4hcRpwbf3fY56ar2oIXzsBpOAiIRHAdY0OlQ==", "license": "MIT", "engines": { "node": ">=0.10.0" @@ -5068,8 +3302,6 @@ }, "node_modules/react-dom": { "version": "19.2.7", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.7.tgz", - "integrity": "sha512-t0BRVXvbiE/o20Hfw669rLbMCDWtYZLvmJigy2f0MxsXF+71pxhR3xOkspmsO8h3ZlNzyibAmtCa3l4lYKk6gQ==", "license": "MIT", "dependencies": { "scheduler": "^0.27.0" @@ -5080,15 +3312,11 @@ }, "node_modules/react-is": { "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", "dev": true, "license": "MIT" }, "node_modules/readdirp": { "version": "4.1.2", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", - "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", "dev": true, "license": "MIT", "engines": { @@ -5101,8 +3329,6 @@ }, "node_modules/resolve-from": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true, "license": "MIT", "engines": { @@ -5111,8 +3337,6 @@ }, "node_modules/rolldown": { "version": "1.0.0-rc.11", - "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.0-rc.11.tgz", - "integrity": "sha512-NRjoKMusSjfRbSYiH3VSumlkgFe7kYAa3pzVOsVYVFY3zb5d7nS+a3KGQ7hJKXuYWbzJKPVQ9Wxq2UvyK+ENpw==", "dev": true, "license": "MIT", "dependencies": { @@ -5145,8 +3369,6 @@ }, "node_modules/rollup": { "version": "4.62.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.62.0.tgz", - "integrity": "sha512-nc72Wgq62I7rtDV4izT5/aaS0zxy3kttkinf9586ApknY3jZO9NYsmtc24fUckA0X7Q2v+ML4a15pdUlV5V/jA==", "dev": true, "license": "MIT", "dependencies": { @@ -5190,15 +3412,11 @@ }, "node_modules/rrweb-cssom": { "version": "0.7.1", - "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.7.1.tgz", - "integrity": "sha512-TrEMa7JGdVm0UThDJSx7ddw5nVm3UJS9o9CCIZ72B1vSyEZoziDqBYP3XIoi/12lKrJR8rE3jeFHMok2F/Mnsg==", "dev": true, "license": "MIT" }, "node_modules/rxjs": { "version": "7.8.2", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", - "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -5207,15 +3425,11 @@ }, "node_modules/safer-buffer": { "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true, "license": "MIT" }, "node_modules/saxes": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", - "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", "dev": true, "license": "ISC", "dependencies": { @@ -5227,14 +3441,14 @@ }, "node_modules/scheduler": { "version": "0.27.0", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", - "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", "license": "MIT" }, + "node_modules/scorm-example": { + "resolved": "example", + "link": true + }, "node_modules/semver": { "version": "7.7.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", - "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", "dev": true, "license": "ISC", "bin": { @@ -5246,8 +3460,6 @@ }, "node_modules/shebang-command": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, "license": "MIT", "dependencies": { @@ -5259,8 +3471,6 @@ }, "node_modules/shebang-regex": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true, "license": "MIT", "engines": { @@ -5269,15 +3479,11 @@ }, "node_modules/siginfo": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", - "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", "dev": true, "license": "ISC" }, "node_modules/source-map": { "version": "0.7.6", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz", - "integrity": "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==", "dev": true, "license": "BSD-3-Clause", "engines": { @@ -5286,8 +3492,6 @@ }, "node_modules/source-map-js": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", - "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", "dev": true, "license": "BSD-3-Clause", "engines": { @@ -5296,22 +3500,16 @@ }, "node_modules/stackback": { "version": "0.0.2", - "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", - "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", "dev": true, "license": "MIT" }, "node_modules/std-env": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/std-env/-/std-env-4.0.0.tgz", - "integrity": "sha512-zUMPtQ/HBY3/50VbpkupYHbRroTRZJPRLvreamgErJVys0ceuzMkD44J/QjqhHjOzK42GQ3QZIeFG1OYfOtKqQ==", "dev": true, "license": "MIT" }, "node_modules/sucrase": { "version": "3.35.1", - "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.1.tgz", - "integrity": "sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==", "dev": true, "license": "MIT", "dependencies": { @@ -5333,8 +3531,6 @@ }, "node_modules/supports-color": { "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "license": "MIT", "dependencies": { @@ -5346,8 +3542,6 @@ }, "node_modules/svelte": { "version": "4.2.20", - "resolved": "https://registry.npmjs.org/svelte/-/svelte-4.2.20.tgz", - "integrity": "sha512-eeEgGc2DtiUil5ANdtd8vPwt9AgaMdnuUFnPft9F5oMvU/FHu5IHFic+p1dR/UOB7XU2mX2yHW+NcTch4DCh5Q==", "dev": true, "license": "MIT", "dependencies": { @@ -5372,15 +3566,11 @@ }, "node_modules/symbol-tree": { "version": "3.2.4", - "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", - "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", "dev": true, "license": "MIT" }, "node_modules/thenify": { "version": "3.3.1", - "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", - "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", "dev": true, "license": "MIT", "dependencies": { @@ -5389,8 +3579,6 @@ }, "node_modules/thenify-all": { "version": "1.6.0", - "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", - "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", "dev": true, "license": "MIT", "dependencies": { @@ -5402,15 +3590,11 @@ }, "node_modules/tinybench": { "version": "2.9.0", - "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", - "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", "dev": true, "license": "MIT" }, "node_modules/tinyexec": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.4.tgz", - "integrity": "sha512-u9r3uZC0bdpGOXtlxUIdwf9pkmvhqJdrVCH9fapQtgy/OeTTMZ1nqH7agtvEfmGui6e1XxjcdrlxvxJvc3sMqw==", "dev": true, "license": "MIT", "engines": { @@ -5419,8 +3603,6 @@ }, "node_modules/tinyglobby": { "version": "0.2.15", - "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", - "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", "dev": true, "license": "MIT", "dependencies": { @@ -5436,8 +3618,6 @@ }, "node_modules/tinyrainbow": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.1.0.tgz", - "integrity": "sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==", "dev": true, "license": "MIT", "engines": { @@ -5446,8 +3626,6 @@ }, "node_modules/tldts": { "version": "6.1.86", - "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.86.tgz", - "integrity": "sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ==", "dev": true, "license": "MIT", "dependencies": { @@ -5459,15 +3637,11 @@ }, "node_modules/tldts-core": { "version": "6.1.86", - "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.86.tgz", - "integrity": "sha512-Je6p7pkk+KMzMv2XXKmAE3McmolOQFdxkKw0R8EYNr7sELW46JqnNeTX8ybPiQgvg1ymCoF8LXs5fzFaZvJPTA==", "dev": true, "license": "MIT" }, "node_modules/tough-cookie": { "version": "5.1.2", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-5.1.2.tgz", - "integrity": "sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -5479,8 +3653,6 @@ }, "node_modules/tr46": { "version": "5.1.1", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.1.1.tgz", - "integrity": "sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==", "dev": true, "license": "MIT", "dependencies": { @@ -5492,8 +3664,6 @@ }, "node_modules/tree-kill": { "version": "1.2.2", - "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", - "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", "dev": true, "license": "MIT", "bin": { @@ -5502,22 +3672,16 @@ }, "node_modules/ts-interface-checker": { "version": "0.1.13", - "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", - "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", "dev": true, "license": "Apache-2.0" }, "node_modules/tslib": { "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", "dev": true, "license": "0BSD" }, "node_modules/tsup": { "version": "8.5.1", - "resolved": "https://registry.npmjs.org/tsup/-/tsup-8.5.1.tgz", - "integrity": "sha512-xtgkqwdhpKWr3tKPmCkvYmS9xnQK3m3XgxZHwSUjvfTjp7YfXe5tT3GgWi0F2N+ZSMsOeWeZFh7ZZFg5iPhing==", "dev": true, "license": "MIT", "dependencies": { @@ -5569,15 +3733,11 @@ }, "node_modules/tsup/node_modules/tinyexec": { "version": "0.3.2", - "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz", - "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==", "dev": true, "license": "MIT" }, "node_modules/typescript": { "version": "5.9.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", - "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "dev": true, "license": "Apache-2.0", "bin": { @@ -5590,15 +3750,11 @@ }, "node_modules/ufo": { "version": "1.6.4", - "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.4.tgz", - "integrity": "sha512-JFNbkD1Svwe0KvGi8GOeLcP4kAWQ609twvCdcHxq1oSL8svv39ZuSvajcD8B+5D0eL4+s1Is2D/O6KN3qcTeRA==", "dev": true, "license": "MIT" }, "node_modules/vite": { "version": "8.0.2", - "resolved": "https://registry.npmjs.org/vite/-/vite-8.0.2.tgz", - "integrity": "sha512-1gFhNi+bHhRE/qKZOJXACm6tX4bA3Isy9KuKF15AgSRuRazNBOJfdDemPBU16/mpMxApDPrWvZ08DcLPEoRnuA==", "dev": true, "license": "MIT", "dependencies": { @@ -5673,92 +3829,8 @@ } } }, - "node_modules/vitest": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.1.tgz", - "integrity": "sha512-yF+o4POL41rpAzj5KVILUxm1GCjKnELvaqmU9TLLUbMfDzuN0UpUR9uaDs+mCtjPe+uYPksXDRLQGGPvj1cTmA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@vitest/expect": "4.1.1", - "@vitest/mocker": "4.1.1", - "@vitest/pretty-format": "4.1.1", - "@vitest/runner": "4.1.1", - "@vitest/snapshot": "4.1.1", - "@vitest/spy": "4.1.1", - "@vitest/utils": "4.1.1", - "es-module-lexer": "^2.0.0", - "expect-type": "^1.3.0", - "magic-string": "^0.30.21", - "obug": "^2.1.1", - "pathe": "^2.0.3", - "picomatch": "^4.0.3", - "std-env": "^4.0.0-rc.1", - "tinybench": "^2.9.0", - "tinyexec": "^1.0.2", - "tinyglobby": "^0.2.15", - "tinyrainbow": "^3.0.3", - "vite": "^6.0.0 || ^7.0.0 || ^8.0.0", - "why-is-node-running": "^2.3.0" - }, - "bin": { - "vitest": "vitest.mjs" - }, - "engines": { - "node": "^20.0.0 || ^22.0.0 || >=24.0.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - }, - "peerDependencies": { - "@edge-runtime/vm": "*", - "@opentelemetry/api": "^1.9.0", - "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0", - "@vitest/browser-playwright": "4.1.1", - "@vitest/browser-preview": "4.1.1", - "@vitest/browser-webdriverio": "4.1.1", - "@vitest/ui": "4.1.1", - "happy-dom": "*", - "jsdom": "*", - "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "@edge-runtime/vm": { - "optional": true - }, - "@opentelemetry/api": { - "optional": true - }, - "@types/node": { - "optional": true - }, - "@vitest/browser-playwright": { - "optional": true - }, - "@vitest/browser-preview": { - "optional": true - }, - "@vitest/browser-webdriverio": { - "optional": true - }, - "@vitest/ui": { - "optional": true - }, - "happy-dom": { - "optional": true - }, - "jsdom": { - "optional": true - }, - "vite": { - "optional": false - } - } - }, "node_modules/vue": { "version": "3.5.38", - "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.38.tgz", - "integrity": "sha512-vAMKHfImQlYSy0C+PBue4s3ERZ2xGKfgZg5GXAsLInq1dyh2H78ILVP5sK0KPFPVW4kv+OGCIvBEondcjpZp7A==", "dev": true, "license": "MIT", "dependencies": { @@ -5779,8 +3851,6 @@ }, "node_modules/w3c-xmlserializer": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz", - "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==", "dev": true, "license": "MIT", "dependencies": { @@ -5792,8 +3862,6 @@ }, "node_modules/webidl-conversions": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", - "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", "dev": true, "license": "BSD-2-Clause", "engines": { @@ -5802,9 +3870,6 @@ }, "node_modules/whatwg-encoding": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", - "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", - "deprecated": "Use @exodus/bytes instead for a more spec-conformant and faster implementation", "dev": true, "license": "MIT", "dependencies": { @@ -5816,8 +3881,6 @@ }, "node_modules/whatwg-mimetype": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", - "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", "dev": true, "license": "MIT", "engines": { @@ -5826,8 +3889,6 @@ }, "node_modules/whatwg-url": { "version": "14.2.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.2.0.tgz", - "integrity": "sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==", "dev": true, "license": "MIT", "dependencies": { @@ -5840,8 +3901,6 @@ }, "node_modules/which": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, "license": "ISC", "dependencies": { @@ -5856,8 +3915,6 @@ }, "node_modules/why-is-node-running": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", - "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", "dev": true, "license": "MIT", "dependencies": { @@ -5873,8 +3930,6 @@ }, "node_modules/ws": { "version": "8.20.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.20.0.tgz", - "integrity": "sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA==", "dev": true, "license": "MIT", "engines": { @@ -5895,8 +3950,6 @@ }, "node_modules/xml-name-validator": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz", - "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==", "dev": true, "license": "Apache-2.0", "engines": { @@ -5905,70 +3958,15 @@ }, "node_modules/xmlchars": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", - "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", "dev": true, "license": "MIT" }, "node_modules/zone.js": { "version": "0.14.10", - "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.14.10.tgz", - "integrity": "sha512-YGAhaO7J5ywOXW6InXNlLmfU194F8lVgu7bRntUF3TiG8Y3nBK0x1UJJuHUP/e8IyihkjCYqhCScpSwnlaSRkQ==", "dev": true, "license": "MIT", "peer": true }, - "packages/react-scorm": { - "name": "@studiolxd/react-scorm", - "version": "1.1.0", - "license": "MIT", - "devDependencies": { - "@testing-library/dom": "^10.4.1", - "@testing-library/react": "^16.0.0", - "@types/react": "^19.0.0", - "@types/react-dom": "^19.0.0", - "@vitest/coverage-v8": "^4.1.1", - "jsdom": "^25.0.0", - "react": "^19.0.0", - "react-dom": "^19.0.0", - "tsup": "^8.0.0", - "typescript": "^5.5.0", - "vitest": "^4.1.1" - }, - "peerDependencies": { - "react": ">=18.0.0", - "react-dom": ">=18.0.0" - } - }, - "packages/react-scorm/node_modules/@vitest/coverage-v8": { - "version": "4.1.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@bcoe/v8-coverage": "^1.0.2", - "@vitest/utils": "4.1.1", - "ast-v8-to-istanbul": "^1.0.0", - "istanbul-lib-coverage": "^3.2.2", - "istanbul-lib-report": "^3.0.1", - "istanbul-reports": "^3.2.0", - "magicast": "^0.5.2", - "obug": "^2.1.1", - "std-env": "^4.0.0-rc.1", - "tinyrainbow": "^3.0.3" - }, - "funding": { - "url": "https://opencollective.com/vitest" - }, - "peerDependencies": { - "@vitest/browser": "4.1.1", - "vitest": "4.1.1" - }, - "peerDependenciesMeta": { - "@vitest/browser": { - "optional": true - } - } - }, "packages/scorm": { "name": "@studiolxd/scorm", "version": "2.0.0", @@ -6017,8 +4015,6 @@ }, "packages/scorm/node_modules/@vitest/coverage-v8": { "version": "4.1.9", - "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-4.1.9.tgz", - "integrity": "sha512-G9/lgqibheLVBDRuya45EbsEXTYcWoSG+TLg7i2axuzx0Eq62eXn+aWXyaVdV5vKvFSWd6ywcX8hA7la9Pvu8g==", "dev": true, "license": "MIT", "dependencies": { @@ -6048,8 +4044,6 @@ }, "packages/scorm/node_modules/@vitest/expect": { "version": "4.1.9", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.9.tgz", - "integrity": "sha512-vl/rYsUKcBr3SnQn166+XR5ZQcgMx3DQhFWdfli/cWpLnLUmbxZvyrJZotLFUryib+LtArYMSTJ5RbQ57ZqrlA==", "dev": true, "license": "MIT", "dependencies": { @@ -6066,8 +4060,6 @@ }, "packages/scorm/node_modules/@vitest/pretty-format": { "version": "4.1.9", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.9.tgz", - "integrity": "sha512-s0iufns3iIFitdgm+YR7g1whCAaGtXz459VS9/PqyKDEEFgYIhsHOQmXgIgDuYCt7DeQmiZT0Qe2OA2p4ZPu5A==", "dev": true, "license": "MIT", "dependencies": { @@ -6079,8 +4071,6 @@ }, "packages/scorm/node_modules/@vitest/runner": { "version": "4.1.9", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.9.tgz", - "integrity": "sha512-KXLMDtc7oe70+3mJfGrPUWPesswH+3sTxAMAMl8DG7I8IUQT4XW718dY5ID3vPUcmlu27CcKfY4P3h3I29SLJg==", "dev": true, "license": "MIT", "dependencies": { @@ -6093,8 +4083,6 @@ }, "packages/scorm/node_modules/@vitest/snapshot": { "version": "4.1.9", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.9.tgz", - "integrity": "sha512-Jc7RKGNBo8Z28WYIm0Niej4xdSPByRf6mU58VpHQkd6Zh05rlnA+twjbK5HyeIGHxrzsc3mJgS43uM0CZKzaIA==", "dev": true, "license": "MIT", "dependencies": { @@ -6109,8 +4097,6 @@ }, "packages/scorm/node_modules/@vitest/spy": { "version": "4.1.9", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.9.tgz", - "integrity": "sha512-fHpsS6mIi+PiEW+vcRVOMkX1oSaPKne3VOclSFICPcGOmfKgXPU5iAah+wcNcj2xPrCCmfq99IDGf+EojhhvhA==", "dev": true, "license": "MIT", "funding": { @@ -6119,8 +4105,6 @@ }, "packages/scorm/node_modules/@vitest/utils": { "version": "4.1.9", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.9.tgz", - "integrity": "sha512-A51o8ymO5PpqlWNnBP9ZHPXDIpuMtTLlGSjN7la4US+LJzoUMyhwjA5QXlm39JexgwHKW4Xjs8Z2d3dLCXOeuA==", "dev": true, "license": "MIT", "dependencies": { @@ -6134,8 +4118,6 @@ }, "packages/scorm/node_modules/vitest": { "version": "4.1.9", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.9.tgz", - "integrity": "sha512-nE3/LEyc0z87uHYLZebqCUOaJr2hdtuPp7BQ4BosVFnfltxgAvMG08NyrSGlPpOUWvR27c5flSmYFTNr78L9GQ==", "dev": true, "license": "MIT", "dependencies": { @@ -6224,8 +4206,6 @@ }, "packages/scorm/node_modules/vitest/node_modules/@vitest/mocker": { "version": "4.1.9", - "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.9.tgz", - "integrity": "sha512-EVkXzBjrPGM+cK8/ANWgBrkUCfJfb38/EfTSO8h7pWvKkyPkpWxvR7BkD2MyItMF62C97zAEoqdpUixwR/e+Rw==", "dev": true, "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index 9103d17..bec4656 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "@studiolxd/react-scorm-monorepo", + "name": "@studiolxd/scorm-monorepo", "private": true, "workspaces": [ "packages/*", From 2938ab45290e4bf486257b30a041211fae032c43 Mon Sep 17 00:00:00 2001 From: studiolxd Date: Mon, 15 Jun 2026 21:18:45 +0200 Subject: [PATCH 11/13] fix(adapters): resolve the three minor review observations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - wc: announce initial state before auto-wiring so auto-terminate yields a distinct initialized event instead of a duplicate initial one - vue: return destroy() and guard onScopeDispose with getCurrentScope() — no silent session leak when used outside an effect scope - svelte: readable pushes the current status on subscribe so late subscribers do not see the stale creation-time snapshot +4 tests (419 total); typecheck + build green Co-Authored-By: Claude Opus 4.8 (1M context) --- packages/scorm/src/svelte/index.ts | 8 +++++- packages/scorm/src/vue/index.ts | 20 +++++++++++-- packages/scorm/src/wc/index.ts | 8 ++++-- packages/scorm/tests/adapters/svelte.test.ts | 13 +++++++++ packages/scorm/tests/adapters/vue.test.ts | 14 ++++++++++ packages/scorm/tests/wc/scorm-session.test.ts | 28 +++++++++++++++++++ 6 files changed, 84 insertions(+), 7 deletions(-) diff --git a/packages/scorm/src/svelte/index.ts b/packages/scorm/src/svelte/index.ts index 42a83de..4699c36 100644 --- a/packages/scorm/src/svelte/index.ts +++ b/packages/scorm/src/svelte/index.ts @@ -52,7 +52,13 @@ export function createScormStore( if (enableAutoTerminate) disposers.push(autoTerminate(session)); if (autoCommitMs > 0) disposers.push(autoCommit(session, autoCommitMs)); - const status = readable(session.status, (set) => session.on('change', set)); + const status = readable(session.status, (set) => { + // Push the *current* status to a (possibly late) subscriber, then track changes — + // otherwise a subscriber that attaches after an early change would see the stale + // creation-time snapshot until the next change. + set(session.status); + return session.on('change', set); + }); return { session, diff --git a/packages/scorm/src/vue/index.ts b/packages/scorm/src/vue/index.ts index 011cd68..a5af4e7 100644 --- a/packages/scorm/src/vue/index.ts +++ b/packages/scorm/src/vue/index.ts @@ -1,7 +1,7 @@ // ───────────────────────────────────────────────────────────────────────────── // @studiolxd/scorm/vue — Vue 3 composable // ───────────────────────────────────────────────────────────────────────────── -import { shallowRef, onScopeDispose, type ShallowRef } from 'vue'; +import { shallowRef, onScopeDispose, getCurrentScope, type ShallowRef } from 'vue'; import { createScormSession, type ScormSession } from '../session/create-scorm-session'; import { autoTerminate } from '../lifecycle/auto-terminate'; import { autoCommit } from '../lifecycle/auto-commit'; @@ -27,6 +27,12 @@ export interface UseScormReturn { initialize: () => Result | undefined; commit: () => Result | undefined; terminate: () => Result | undefined; + /** + * Tear down listeners and destroy the session. Called automatically on scope + * dispose when used inside a component `setup()`. Call it manually when using + * this composable outside an effect scope. + */ + destroy: () => void; } /** @@ -56,11 +62,18 @@ export function useScorm( if (enableAutoTerminate) disposers.push(autoTerminate(session)); if (autoCommitMs > 0) disposers.push(autoCommit(session, autoCommitMs)); - onScopeDispose(() => { + let destroyed = false; + const destroy = () => { + if (destroyed) return; + destroyed = true; off(); for (const dispose of disposers) dispose(); session.destroy(); - }); + }; + + // Auto-clean only when there is an active effect scope (i.e. inside setup()). + // Outside a scope, onScopeDispose is a no-op, so the caller uses `destroy()`. + if (getCurrentScope()) onScopeDispose(destroy); return { session, @@ -68,5 +81,6 @@ export function useScorm( initialize: () => session.initialize(), commit: () => session.commit(), terminate: () => session.terminate(), + destroy, }; } diff --git a/packages/scorm/src/wc/index.ts b/packages/scorm/src/wc/index.ts index 9c6eaff..adeab7f 100644 --- a/packages/scorm/src/wc/index.ts +++ b/packages/scorm/src/wc/index.ts @@ -63,6 +63,11 @@ export function defineScormSession(tag = 'scorm-session'): void { this.dispatchEvent(new CustomEvent('change', { detail: { status } })); }); + // Announce the initial state first, before any auto-wiring. This way + // `auto-terminate` (which initializes) produces a distinct follow-up `change` + // event rather than a duplicate of the initial one. + this.dispatchEvent(new CustomEvent('change', { detail: { status: session.status } })); + if (this.hasAttribute('auto-terminate')) { this.disposers.push(autoTerminate(session)); } @@ -70,9 +75,6 @@ export function defineScormSession(tag = 'scorm-session'): void { if (commitMs > 0) { this.disposers.push(autoCommit(session, commitMs)); } - - // Announce the initial state. - this.dispatchEvent(new CustomEvent('change', { detail: { status: session.status } })); } disconnectedCallback(): void { diff --git a/packages/scorm/tests/adapters/svelte.test.ts b/packages/scorm/tests/adapters/svelte.test.ts index 2ee2309..f6c1bb3 100644 --- a/packages/scorm/tests/adapters/svelte.test.ts +++ b/packages/scorm/tests/adapters/svelte.test.ts @@ -20,4 +20,17 @@ describe('svelte adapter — createScormStore', () => { unsub(); store.destroy(); }); + + it('a late subscriber sees the current status, not the creation-time snapshot', () => { + const store = createScormStore('2004', { noLmsBehavior: 'mock' }); + // Change state BEFORE anyone subscribes. + store.session.initialize(); + + let first: ScormStatus | undefined; + const unsub = store.status.subscribe((v) => { first ??= v; }); + expect(first?.initialized).toBe(true); // current state, not stale + + unsub(); + store.destroy(); + }); }); diff --git a/packages/scorm/tests/adapters/vue.test.ts b/packages/scorm/tests/adapters/vue.test.ts index bccfa30..91df953 100644 --- a/packages/scorm/tests/adapters/vue.test.ts +++ b/packages/scorm/tests/adapters/vue.test.ts @@ -18,4 +18,18 @@ describe('vue adapter — useScorm', () => { scope.stop(); // triggers onScopeDispose → session.destroy() }); + + it('works outside an effect scope and exposes destroy() for manual cleanup', () => { + // No effectScope: onScopeDispose is a no-op, so the caller must use destroy(). + const result = useScorm('2004', { noLmsBehavior: 'mock' }); + expect(typeof result.destroy).toBe('function'); + + result.initialize(); + expect(result.status.value.initialized).toBe(true); + + // destroy() detaches the change listener: further changes don't update status. + result.destroy(); + result.session.terminate(); + expect(result.status.value.terminated).toBe(false); // not observed after destroy + }); }); diff --git a/packages/scorm/tests/wc/scorm-session.test.ts b/packages/scorm/tests/wc/scorm-session.test.ts index 4e6f925..f3afa88 100644 --- a/packages/scorm/tests/wc/scorm-session.test.ts +++ b/packages/scorm/tests/wc/scorm-session.test.ts @@ -38,6 +38,34 @@ describe(' web component', () => { document.body.removeChild(el); }); + it('emits exactly one initial change event without auto-terminate', () => { + const el = document.createElement('scorm-session') as any; + el.setAttribute('version', '2004'); + el.setAttribute('no-lms-behavior', 'mock'); + const events: boolean[] = []; + el.addEventListener('change', (e: Event) => events.push((e as CustomEvent).detail.status.initialized)); + + document.body.appendChild(el); + expect(events).toEqual([false]); // single initial event, uninitialized + + document.body.removeChild(el); + }); + + it('auto-terminate emits a distinct initial then initialized event (no duplicate)', () => { + const el = document.createElement('scorm-session') as any; + el.setAttribute('version', '2004'); + el.setAttribute('no-lms-behavior', 'mock'); + el.setAttribute('auto-terminate', ''); + const events: boolean[] = []; + el.addEventListener('change', (e: Event) => events.push((e as CustomEvent).detail.status.initialized)); + + document.body.appendChild(el); + // initial (uninitialized) then the auto-terminate initialize (initialized) + expect(events).toEqual([false, true]); + + document.body.removeChild(el); + }); + it('auto-terminate: initializes on connect, terminates on disconnect', () => { const el = document.createElement('scorm-session') as any; el.setAttribute('version', '2004'); From bac88fa4121bb8816ad933d7fa80ec0423ab9d1e Mon Sep 17 00:00:00 2001 From: studiolxd Date: Mon, 15 Jun 2026 21:22:38 +0200 Subject: [PATCH 12/13] ci(angular-smoke): use npm install to avoid npm optional-dep bug (rollup on Linux) npm/cli#4828: a macOS-generated lockfile makes npm ci skip @rollup/rollup-linux-x64-gnu on the Linux runner, breaking tsup. npm install re-resolves the platform binary. Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/workflows/angular-smoke.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/angular-smoke.yml b/.github/workflows/angular-smoke.yml index b63b1ae..5cd39b6 100644 --- a/.github/workflows/angular-smoke.yml +++ b/.github/workflows/angular-smoke.yml @@ -30,7 +30,10 @@ jobs: cache: npm - name: Install monorepo deps - run: npm ci + # npm install (not npm ci) to sidestep npm's cross-platform optional-dependency + # bug (npm/cli#4828): a lockfile generated on macOS makes `npm ci` skip the + # Linux rollup native binary that tsup/rollup need on the runner. + run: npm install --no-audit --no-fund - name: Build @studiolxd/scorm run: npm run build --workspace=packages/scorm From 5e68b670eb900278b7f0470609cf05daf8ad1a00 Mon Sep 17 00:00:00 2001 From: studiolxd Date: Mon, 15 Jun 2026 21:35:43 +0200 Subject: [PATCH 13/13] ci(angular-smoke): remove lockfile before install (rollup linux optional-dep fix) npm install alone still respected the macOS lockfile and skipped @rollup/rollup-linux-x64-gnu. Removing package-lock.json forces a fresh platform-correct resolution on the runner (npm/cli#4828). Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/workflows/angular-smoke.yml | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/.github/workflows/angular-smoke.yml b/.github/workflows/angular-smoke.yml index 5cd39b6..235a022 100644 --- a/.github/workflows/angular-smoke.yml +++ b/.github/workflows/angular-smoke.yml @@ -30,10 +30,13 @@ jobs: cache: npm - name: Install monorepo deps - # npm install (not npm ci) to sidestep npm's cross-platform optional-dependency - # bug (npm/cli#4828): a lockfile generated on macOS makes `npm ci` skip the - # Linux rollup native binary that tsup/rollup need on the runner. - run: npm install --no-audit --no-fund + # Remove the lockfile before installing to sidestep npm's cross-platform + # optional-dependency bug (npm/cli#4828): a lockfile generated on macOS makes + # npm skip the Linux rollup native binary tsup/rollup need on the runner. + # A fresh install resolves the correct platform binaries. + run: | + rm -f package-lock.json + npm install --no-audit --no-fund - name: Build @studiolxd/scorm run: npm run build --workspace=packages/scorm