diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e5a505b..ce6767e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -60,7 +60,12 @@ jobs: working-directory: crates/napi run: pnpm run smoke:napi -- fixtures/core/markdown/hello.md - - name: Run NAPI tests (AVA) + - name: Install Bun + uses: oven-sh/setup-bun@v2 + with: + bun-version: latest + + - name: Run NAPI tests (Bun) working-directory: crates/napi run: pnpm test diff --git a/.github/workflows/compatibility.yml b/.github/workflows/compatibility.yml index b5eb8e2..cb760f8 100644 --- a/.github/workflows/compatibility.yml +++ b/.github/workflows/compatibility.yml @@ -134,6 +134,11 @@ jobs: working-directory: crates/napi run: pnpm run smoke:napi -- fixtures/core/markdown/hello.md + - name: Install Bun + uses: oven-sh/setup-bun@v2 + with: + bun-version: latest + - name: Run NAPI tests working-directory: crates/napi run: pnpm test diff --git a/crates/napi/package.json b/crates/napi/package.json index 701393b..6cf4358 100644 --- a/crates/napi/package.json +++ b/crates/napi/package.json @@ -13,11 +13,10 @@ "build": "napi build --platform --release --esm", "build:napi": "pnpm run build", "smoke:napi": "node ../../scripts/smoke-napi.mjs", - "test": "ava" + "test": "bun test" }, "devDependencies": { "@napi-rs/cli": "^3.4.1", - "ava": "^6.4.1", "prettier": "^3.6.2" }, "keywords": [ @@ -37,12 +36,5 @@ }, "engines": { "node": ">= 10" - }, - "ava": { - "files": [ - "tests/**/*.test.js" - ], - "timeout": "30s", - "workerThreads": false } } diff --git a/crates/napi/tests/auto_import.test.js b/crates/napi/tests/auto_import.test.ts similarity index 65% rename from crates/napi/tests/auto_import.test.js rename to crates/napi/tests/auto_import.test.ts index d22fe83..b4aa432 100644 --- a/crates/napi/tests/auto_import.test.js +++ b/crates/napi/tests/auto_import.test.ts @@ -1,25 +1,25 @@ -import test from 'ava'; +import { test, expect } from 'bun:test'; import { createCompiler } from '../index.js'; const compiler = createCompiler(); -test('compile converts directive to Aside component', (t) => { +test('compile converts directive to Aside component', () => { const source = ':::note\nBody\n:::'; const result = compiler.compile(source, '/virtual.mdx'); // Directive should be converted to Aside component with type in spread props - t.true(result.code.includes(' { +test('compile preserves existing Aside import without duplication', () => { const source = "import { Aside } from '@astrojs/starlight/components';\n\n:::note\nBody\n:::"; const result = compiler.compile(source, '/virtual.mdx'); // User-provided import should be preserved - t.true(result.code.includes("import { Aside } from '@astrojs/starlight/components';")); + expect(result.code.includes("import { Aside } from '@astrojs/starlight/components';")).toBe(true); // Should not be duplicated const occurrences = result.code.split("import { Aside } from '@astrojs/starlight/components';").length - 1; - t.is(occurrences, 1); + expect(occurrences).toBe(1); }); diff --git a/crates/napi/tests/fixtures-parity.test.js b/crates/napi/tests/fixtures-parity.test.js deleted file mode 100644 index 135d4ca..0000000 --- a/crates/napi/tests/fixtures-parity.test.js +++ /dev/null @@ -1,24 +0,0 @@ -import test from 'ava' -import { readFileSync } from 'node:fs' -import { resolve } from 'node:path' - -import { compileIr } from '../index.js' - -const fixturePath = resolve(process.cwd(), '../../fixtures/core/markdown/hello.md') -const markdown = readFileSync(fixturePath, 'utf8') - -test('compileIr produces consistent output for hello.md', (t) => { - const result = compileIr(markdown, '/hello.md') - - t.is(typeof result.html, 'string') - t.true(result.html.length > 0) - t.true(Array.isArray(result.headings)) -}) - -test('compileIr with url option produces same html', (t) => { - const result1 = compileIr(markdown, '/hello.md') - const result2 = compileIr(markdown, '/hello.md', { url: '/test' }) - - t.is(result1.html, result2.html) - t.is(result2.url, '/test') -}) diff --git a/crates/napi/tests/fixtures-parity.test.ts b/crates/napi/tests/fixtures-parity.test.ts new file mode 100644 index 0000000..4a44cd3 --- /dev/null +++ b/crates/napi/tests/fixtures-parity.test.ts @@ -0,0 +1,24 @@ +import { test, expect } from 'bun:test'; +import { readFileSync } from 'node:fs'; +import { resolve } from 'node:path'; + +import { compileIr } from '../index.js'; + +const fixturePath = resolve(import.meta.dir, '../../../fixtures/core/markdown/hello.md'); +const markdown = readFileSync(fixturePath, 'utf8'); + +test('compileIr produces consistent output for hello.md', () => { + const result = compileIr(markdown, '/hello.md'); + + expect(typeof result.html).toBe('string'); + expect(result.html.length > 0).toBe(true); + expect(Array.isArray(result.headings)).toBe(true); +}); + +test('compileIr with url option produces same html', () => { + const result1 = compileIr(markdown, '/hello.md'); + const result2 = compileIr(markdown, '/hello.md', { url: '/test' }); + + expect(result1.html).toBe(result2.html); + expect(result2.url).toBe('/test'); +}); diff --git a/crates/napi/tests/parse.test.js b/crates/napi/tests/parse.test.js deleted file mode 100644 index ea5c324..0000000 --- a/crates/napi/tests/parse.test.js +++ /dev/null @@ -1,85 +0,0 @@ -import test from 'ava'; -import { compileIr } from '../index.js'; - -test('compileIr() converts markdown to HTML', (t) => { - const input = '# Hello World'; - const result = compileIr(input, '/virtual.md'); - - t.true(result.html.includes('')); -}); - -test('compileIr() handles bold and italic text', (t) => { - const input = 'This is **bold** and *italic* text'; - const result = compileIr(input, '/virtual.md'); - - t.true(result.html.includes('bold')); - t.true(result.html.includes('italic')); -}); - -test('compileIr() handles code blocks', (t) => { - const input = '```javascript\nconsole.log("test");\n```'; - const result = compileIr(input, '/virtual.md'); - - t.true(result.html.includes(' { - const input = '![Alt text](image.png)'; - const result = compileIr(input, '/virtual.md'); - - // HTML is now inside a JSON string (via set:html), so quotes are escaped - t.true(result.html.includes('alt=\\"Alt text\\"')); - t.true(result.html.includes('src=\\"image.png\\"')); -}); - -test('compileIr() handles lists', (t) => { - const input = '- Item 1\n- Item 2\n- Item 3'; - const result = compileIr(input, '/virtual.md'); - - t.true(result.html.includes('
    ')); - t.true(result.html.includes('
  • ')); - t.true(result.html.includes('Item 1')); - t.true(result.html.includes('Item 2')); - t.true(result.html.includes('
')); -}); - -test('compileIr() assigns heading ids', (t) => { - const input = '# Hello Heading'; - const result = compileIr(input, '/virtual.md'); - - // HTML is now inside a JSON string (via set:html), so quotes are escaped - t.true(result.html.includes('id=\\"hello-heading\\"')); -}); - -test('compileIr() handles links', (t) => { - const input = '[Link text](https://example.com)'; - const result = compileIr(input, '/virtual.md'); - - // HTML is now inside a JSON string (via set:html), so quotes are escaped - t.true(result.html.includes('')); - t.true(result.html.includes('Link text')); - t.true(result.html.includes('')); -}); - -test('compileIr() returns an object with html', (t) => { - const result = compileIr('# Test', '/virtual.md'); - t.is(typeof result, 'object'); - t.is(typeof result.html, 'string'); -}); - -test('compileIr() handles empty input', (t) => { - const result = compileIr('', '/virtual.md'); - t.is(typeof result.html, 'string'); -}); - -test('compileIr() passes through HTML blocks', (t) => { - const input = '
Hello
\n\nSome text'; - const result = compileIr(input, '/virtual.md'); - - // Raw HTML is preserved (possibly as JSX spread format) - t.true(result.html.includes('section') || result.html.includes('Hello')); -}); diff --git a/crates/napi/tests/parse.test.ts b/crates/napi/tests/parse.test.ts new file mode 100644 index 0000000..db58545 --- /dev/null +++ b/crates/napi/tests/parse.test.ts @@ -0,0 +1,85 @@ +import { test, expect } from 'bun:test'; +import { compileIr } from '../index.js'; + +test('compileIr() converts markdown to HTML', () => { + const input = '# Hello World'; + const result = compileIr(input, '/virtual.md'); + + expect(result.html.includes('')).toBe(true); +}); + +test('compileIr() handles bold and italic text', () => { + const input = 'This is **bold** and *italic* text'; + const result = compileIr(input, '/virtual.md'); + + expect(result.html.includes('bold')).toBe(true); + expect(result.html.includes('italic')).toBe(true); +}); + +test('compileIr() handles code blocks', () => { + const input = '```javascript\nconsole.log("test");\n```'; + const result = compileIr(input, '/virtual.md'); + + expect(result.html.includes(' { + const input = '![Alt text](image.png)'; + const result = compileIr(input, '/virtual.md'); + + // HTML is now inside a JSON string (via set:html), so quotes are escaped + expect(result.html.includes('alt=\\"Alt text\\"')).toBe(true); + expect(result.html.includes('src=\\"image.png\\"')).toBe(true); +}); + +test('compileIr() handles lists', () => { + const input = '- Item 1\n- Item 2\n- Item 3'; + const result = compileIr(input, '/virtual.md'); + + expect(result.html.includes('
    ')).toBe(true); + expect(result.html.includes('
  • ')).toBe(true); + expect(result.html.includes('Item 1')).toBe(true); + expect(result.html.includes('Item 2')).toBe(true); + expect(result.html.includes('
')).toBe(true); +}); + +test('compileIr() assigns heading ids', () => { + const input = '# Hello Heading'; + const result = compileIr(input, '/virtual.md'); + + // HTML is now inside a JSON string (via set:html), so quotes are escaped + expect(result.html.includes('id=\\"hello-heading\\"')).toBe(true); +}); + +test('compileIr() handles links', () => { + const input = '[Link text](https://example.com)'; + const result = compileIr(input, '/virtual.md'); + + // HTML is now inside a JSON string (via set:html), so quotes are escaped + expect(result.html.includes('')).toBe(true); + expect(result.html.includes('Link text')).toBe(true); + expect(result.html.includes('')).toBe(true); +}); + +test('compileIr() returns an object with html', () => { + const result = compileIr('# Test', '/virtual.md'); + expect(typeof result).toBe('object'); + expect(typeof result.html).toBe('string'); +}); + +test('compileIr() handles empty input', () => { + const result = compileIr('', '/virtual.md'); + expect(typeof result.html).toBe('string'); +}); + +test('compileIr() passes through HTML blocks', () => { + const input = '
Hello
\n\nSome text'; + const result = compileIr(input, '/virtual.md'); + + // Raw HTML is preserved (possibly as JSX spread format) + expect(result.html.includes('section') || result.html.includes('Hello')).toBe(true); +}); diff --git a/crates/napi/tests/parseWithOptions.test.js b/crates/napi/tests/parseWithOptions.test.js deleted file mode 100644 index 2dbe5dd..0000000 --- a/crates/napi/tests/parseWithOptions.test.js +++ /dev/null @@ -1,52 +0,0 @@ -import test from 'ava'; -import { compileIr, FileInputType } from '../index.js'; - -test('compileIr() handles images', (t) => { - const input = '![alt](image.png)'; - const result = compileIr(input, '/virtual.md'); - - // HTML is now inside a JSON string (via set:html), so quotes are escaped - t.true(result.html.includes('alt=\\"alt\\"')); - t.true(result.html.includes('src=\\"image.png\\"')); -}); - -test('compileIr() handles raw HTML img tags', (t) => { - const input = ''; - const result = compileIr(input, '/virtual.md'); - - // Raw HTML is converted to JSX spread format - t.true(result.html.includes('img')); - t.true(result.html.includes('/hero.png')); -}); - -test('compileIr() with url option sets the url in result', (t) => { - const input = '# Test'; - const result = compileIr(input, '/virtual.md', { url: '/test-page' }); - - t.is(result.url, '/test-page'); -}); - -test('compileIr() with fileType option can force MDX mode', (t) => { - // Even with .md extension, can force MDX processing - const input = '# Header\n\n**Bold** text'; - const result = compileIr(input, '/virtual.md', { fileType: FileInputType.Mdx }); - - t.true(result.html.includes('Bold')); -}); - -test('compileIr() converts markdown to HTML correctly', (t) => { - const input = '# Header\n\n**Bold** text'; - const result = compileIr(input, '/virtual.md'); - - t.true(result.html.includes('Bold')); -}); - -test('compileIr() returns an object with html property', (t) => { - const result = compileIr('# Test', '/virtual.md'); - t.is(typeof result, 'object'); - t.is(typeof result.html, 'string'); -}); diff --git a/crates/napi/tests/parseWithOptions.test.ts b/crates/napi/tests/parseWithOptions.test.ts new file mode 100644 index 0000000..270aea9 --- /dev/null +++ b/crates/napi/tests/parseWithOptions.test.ts @@ -0,0 +1,52 @@ +import { test, expect } from 'bun:test'; +import { compileIr, FileInputType } from '../index.js'; + +test('compileIr() handles images', () => { + const input = '![alt](image.png)'; + const result = compileIr(input, '/virtual.md'); + + // HTML is now inside a JSON string (via set:html), so quotes are escaped + expect(result.html.includes('alt=\\"alt\\"')).toBe(true); + expect(result.html.includes('src=\\"image.png\\"')).toBe(true); +}); + +test('compileIr() handles raw HTML img tags', () => { + const input = ''; + const result = compileIr(input, '/virtual.md'); + + // Raw HTML is converted to JSX spread format + expect(result.html.includes('img')).toBe(true); + expect(result.html.includes('/hero.png')).toBe(true); +}); + +test('compileIr() with url option sets the url in result', () => { + const input = '# Test'; + const result = compileIr(input, '/virtual.md', { url: '/test-page' }); + + expect(result.url).toBe('/test-page'); +}); + +test('compileIr() with fileType option can force MDX mode', () => { + // Even with .md extension, can force MDX processing + const input = '# Header\n\n**Bold** text'; + const result = compileIr(input, '/virtual.md', { fileType: FileInputType.Mdx }); + + expect(result.html.includes('Bold')).toBe(true); +}); + +test('compileIr() converts markdown to HTML correctly', () => { + const input = '# Header\n\n**Bold** text'; + const result = compileIr(input, '/virtual.md'); + + expect(result.html.includes('Bold')).toBe(true); +}); + +test('compileIr() returns an object with html property', () => { + const result = compileIr('# Test', '/virtual.md'); + expect(typeof result).toBe('object'); + expect(typeof result.html).toBe('string'); +}); diff --git a/crates/napi/tests/parseWithStats.test.js b/crates/napi/tests/parseWithStats.test.js deleted file mode 100644 index 2959e8c..0000000 --- a/crates/napi/tests/parseWithStats.test.js +++ /dev/null @@ -1,73 +0,0 @@ -import test from 'ava'; -import { compileIr, compileBatch } from '../index.js'; - -test('compileIr() returns an object with html and headings', (t) => { - const input = '# Test Heading'; - const result = compileIr(input, '/virtual.md'); - - t.is(typeof result, 'object'); - t.true('html' in result); - t.true('headings' in result); -}); - -test('compileIr() html contains correct output', (t) => { - const input = '# Test Heading'; - const result = compileIr(input, '/virtual.md'); - - t.true(result.html.includes(' { - const input = '# Test\n\n## Subheading'; - const result = compileIr(input, '/virtual.md'); - - t.true(Array.isArray(result.headings)); - t.is(result.headings.length, 2); - t.is(result.headings[0].depth, 1); - t.is(result.headings[0].text, 'Test'); - t.is(result.headings[1].depth, 2); - t.is(result.headings[1].text, 'Subheading'); -}); - -test('compileIr() includes filePath in result', (t) => { - const input = '# Test'; - const result = compileIr(input, '/path/to/file.md'); - - t.is(result.filePath, '/path/to/file.md'); -}); - -test('compileIr() handles images', (t) => { - const input = '![alt](image.png)'; - const result = compileIr(input, '/virtual.md'); - - t.true(result.html.includes('img')); - t.true(result.html.includes('image.png')); -}); - -test('compileIr() works with large input', (t) => { - const input = '# Heading\n\n' + 'Lorem ipsum dolor sit amet. '.repeat(100); - const result = compileIr(input, '/virtual.md'); - - t.true(result.html.length > input.length); -}); - -test('compileIr() works with empty input', (t) => { - const result = compileIr('', '/virtual.md'); - - t.is(typeof result.html, 'string'); -}); - -test('compileBatch() returns processing stats with timing', (t) => { - const inputs = [ - { id: 'file1.md', source: '# Hello' }, - { id: 'file2.md', source: '# World' }, - ]; - const batchResult = compileBatch(inputs); - - t.is(typeof batchResult.stats, 'object'); - t.is(typeof batchResult.stats.processingTimeMs, 'number'); - t.true(batchResult.stats.processingTimeMs >= 0); - t.is(batchResult.stats.total, 2); - t.is(batchResult.stats.succeeded, 2); -}); diff --git a/crates/napi/tests/parseWithStats.test.ts b/crates/napi/tests/parseWithStats.test.ts new file mode 100644 index 0000000..17fd4da --- /dev/null +++ b/crates/napi/tests/parseWithStats.test.ts @@ -0,0 +1,73 @@ +import { test, expect } from 'bun:test'; +import { compileIr, compileBatch } from '../index.js'; + +test('compileIr() returns an object with html and headings', () => { + const input = '# Test Heading'; + const result = compileIr(input, '/virtual.md'); + + expect(typeof result).toBe('object'); + expect('html' in result).toBe(true); + expect('headings' in result).toBe(true); +}); + +test('compileIr() html contains correct output', () => { + const input = '# Test Heading'; + const result = compileIr(input, '/virtual.md'); + + expect(result.html.includes(' { + const input = '# Test\n\n## Subheading'; + const result = compileIr(input, '/virtual.md'); + + expect(Array.isArray(result.headings)).toBe(true); + expect(result.headings.length).toBe(2); + expect(result.headings[0].depth).toBe(1); + expect(result.headings[0].text).toBe('Test'); + expect(result.headings[1].depth).toBe(2); + expect(result.headings[1].text).toBe('Subheading'); +}); + +test('compileIr() includes filePath in result', () => { + const input = '# Test'; + const result = compileIr(input, '/path/to/file.md'); + + expect(result.filePath).toBe('/path/to/file.md'); +}); + +test('compileIr() handles images', () => { + const input = '![alt](image.png)'; + const result = compileIr(input, '/virtual.md'); + + expect(result.html.includes('img')).toBe(true); + expect(result.html.includes('image.png')).toBe(true); +}); + +test('compileIr() works with large input', () => { + const input = '# Heading\n\n' + 'Lorem ipsum dolor sit amet. '.repeat(100); + const result = compileIr(input, '/virtual.md'); + + expect(result.html.length > input.length).toBe(true); +}); + +test('compileIr() works with empty input', () => { + const result = compileIr('', '/virtual.md'); + + expect(typeof result.html).toBe('string'); +}); + +test('compileBatch() returns processing stats with timing', () => { + const inputs = [ + { id: 'file1.md', source: '# Hello' }, + { id: 'file2.md', source: '# World' }, + ]; + const batchResult = compileBatch(inputs); + + expect(typeof batchResult.stats).toBe('object'); + expect(typeof batchResult.stats.processingTimeMs).toBe('number'); + expect(batchResult.stats.processingTimeMs >= 0).toBe(true); + expect(batchResult.stats.total).toBe(2); + expect(batchResult.stats.succeeded).toBe(2); +}); diff --git a/crates/napi/tests/template_literal_bug.test.js b/crates/napi/tests/template_literal_bug.test.ts similarity index 68% rename from crates/napi/tests/template_literal_bug.test.js rename to crates/napi/tests/template_literal_bug.test.ts index 930c29f..434100d 100644 --- a/crates/napi/tests/template_literal_bug.test.js +++ b/crates/napi/tests/template_literal_bug.test.ts @@ -1,9 +1,9 @@ -import test from 'ava'; +import { test, expect } from 'bun:test'; import { createCompiler } from '../index.js'; const compiler = createCompiler(); -test('inline code with template literal syntax should not be evaluated', async (t) => { +test('inline code with template literal syntax should not be evaluated', async () => { // This is the pattern that causes runtime errors: // The ${variable} inside backticks should be treated as literal text const source = 'Use `style={`--myVar:${value}`}` to set the style.'; @@ -12,42 +12,38 @@ test('inline code with template literal syntax should not be evaluated', async ( // The output should NOT contain an actual template literal that would // evaluate ${value} as a JavaScript expression // It should contain escaped or quoted content - t.false( - result.code.includes('`--myVar:${value}`'), - 'Template literal should not be present as raw backticks in output' - ); + expect( + result.code.includes('`--myVar:${value}`') + ).toBe(false); // The content should be safely rendered as a string - t.true( - result.code.includes(''), - 'Should contain code element' - ); + expect( + result.code.includes('') + ).toBe(true); }); -test('inline code with dollar sign should be safe in JSX', async (t) => { +test('inline code with dollar sign should be safe in JSX', async () => { const source = 'Use `${variable}` in template literals.'; const result = await compiler.compile(source, '/virtual.mdx'); // Should not cause reference errors when evaluated // The ${variable} should be escaped or rendered as text - t.true( - result.code.includes(''), - 'Should contain code element' - ); + expect( + result.code.includes('') + ).toBe(true); }); -test('double backtick inline code preserves content', async (t) => { +test('double backtick inline code preserves content', async () => { // Double backticks are used to include backticks in inline code const source = 'Use `` `template` `` for templates.'; const result = await compiler.compile(source, '/virtual.mdx'); - t.true( - result.code.includes(''), - 'Should contain code element' - ); + expect( + result.code.includes('') + ).toBe(true); }); -test('REPRO: double backtick with template literal causes runtime error', async (t) => { +test('REPRO: double backtick with template literal causes runtime error', async () => { // This is the exact pattern from astro-syntax.mdx that causes: // "value is not defined" runtime error const source = 'then you can manually add a ``style={`--myVar:${value}`}`` to your Element.'; @@ -57,13 +53,11 @@ test('REPRO: double backtick with template literal causes runtime error', async // The output should NOT contain an unescaped template literal // that would cause ${value} to be evaluated - t.false( - /`[^`]*\$\{value\}[^`]*`/.test(result.code), - 'Template literal should be escaped or quoted, not raw' - ); + expect( + /`[^`]*\$\{value\}[^`]*`/.test(result.code) + ).toBe(false); - t.true( - result.code.includes(''), - 'Should contain code element' - ); + expect( + result.code.includes('') + ).toBe(true); }); diff --git a/packages/astro-markflow/src/pipeline/orchestrator.ts b/packages/astro-markflow/src/pipeline/orchestrator.ts index 52f41ab..1a5773b 100644 --- a/packages/astro-markflow/src/pipeline/orchestrator.ts +++ b/packages/astro-markflow/src/pipeline/orchestrator.ts @@ -10,7 +10,6 @@ import { transformInjectComponentsFromRegistry, transformShikiHighlight, } from '../transforms/index.js'; -import { normalizeSteps } from '../transforms/normalize-steps.js'; /** * Default context values for transforms. @@ -97,14 +96,6 @@ export function createPipeline(options: PipelineOptions = {}): Transform { // Built-in: Shiki highlighting transformShikiHighlight, - // Built-in: Normalize Steps to single
    - (ctx) => { - if (!ctx.code) return ctx; - const { code, changed } = normalizeSteps(ctx.code); - if (!changed) return ctx; - return { ...ctx, code }; - }, - // User hooks: beforeOutput ...beforeOutput ); diff --git a/packages/astro-markflow/src/transforms/blocks-to-jsx.test.ts b/packages/astro-markflow/src/transforms/blocks-to-jsx.test.ts index c694c54..54da813 100644 --- a/packages/astro-markflow/src/transforms/blocks-to-jsx.test.ts +++ b/packages/astro-markflow/src/transforms/blocks-to-jsx.test.ts @@ -1,5 +1,5 @@ import { describe, it, expect } from 'bun:test'; -import { blocksToJsx, type Block, type BlocksToJsxOptions } from './blocks-to-jsx.js'; +import { blocksToJsx, type Block } from './blocks-to-jsx.js'; import { createRegistry, starlightLibrary } from 'markflow/registry'; describe('blocksToJsx', () => { @@ -445,22 +445,20 @@ describe('blocksToJsx', () => { expect(result).toContain('let x = 1;'); }); - it('should render as ExpressiveCode component when expressiveCodeComponent is set', () => { + it('should always render code blocks as
     (EC rewriting is pipeline-only)', () => {
           const blocks: Block[] = [
             { type: 'code', code: 'const x = 1;', lang: 'js', meta: 'title="example"' },
           ];
     
    -      const result = blocksToJsx(blocks, {}, [], null, undefined, [], {
    -        expressiveCodeComponent: 'Code',
    -      });
    +      const result = blocksToJsx(blocks);
     
    -      expect(result).toContain(' {
    +    it('should render code blocks as 
     in slots too', () => {
           const blocks: Block[] = [
             {
               type: 'component',
    @@ -472,13 +470,12 @@ describe('blocksToJsx', () => {
             },
           ];
     
    -      const result = blocksToJsx(blocks, {}, [], null, undefined, [], {
    -        expressiveCodeComponent: 'Code',
    -      });
    +      const result = blocksToJsx(blocks);
     
    -      expect(result).toContain(' {
    diff --git a/packages/astro-markflow/src/transforms/blocks-to-jsx.ts b/packages/astro-markflow/src/transforms/blocks-to-jsx.ts
    index e951fbc..073d73a 100644
    --- a/packages/astro-markflow/src/transforms/blocks-to-jsx.ts
    +++ b/packages/astro-markflow/src/transforms/blocks-to-jsx.ts
    @@ -3,8 +3,18 @@
      * @module transforms/blocks-to-jsx
      */
     
    -import type { Registry } from 'markflow/registry';
     import type { HeadingEntry } from 'markflow';
    +
    +/**
    + * Minimal registry interface consumed by blocksToJsx.
    + * Avoids coupling to the full Registry type.
    + */
    +export interface BlocksRegistry {
    +  getSupportedDirectives(): string[];
    +  getDirectiveMapping(directive: string): { component: string; injectProps?: Record } | undefined;
    +  getSlotNormalization(component: string): { strategy: 'wrap_in_ol' | 'wrap_in_ul' } | undefined;
    +  getComponent(name: string): { modulePath: string; exportType: string } | undefined;
    +}
     import { htmlEntitiesToJsx, hasPascalCaseTag } from 'markflow-napi';
     
     /**
    @@ -52,9 +62,8 @@ function escapeHtml(s: string): string {
      */
     function slotChildrenToHtml(
       blocks: Block[],
    -  ecComponent?: string,
       componentImports?: Map,
    -  registry?: Registry,
    +  registry?: BlocksRegistry,
       userImportedNames?: Set,
     ): string {
       let result = '';
    @@ -63,25 +72,11 @@ function slotChildrenToHtml(
           // Escape braces so JSX text does not become expressions
           result += (block.content ?? '').replace(/\{/g, '{').replace(/\}/g, '}');
         } else if (block.type === 'code') {
    -      if (ecComponent) {
    -        // Direct ExpressiveCode component rendering
    -        const langProp = block.lang ? ` lang="${escapeJsString(block.lang)}"` : '';
    -        const metaProp = block.meta ? ` meta="${escapeJsString(block.meta)}"` : '';
    -        result += `<${ecComponent} code={${JSON.stringify(block.code ?? '')}}${langProp}${metaProp} />`;
    -        // Register EC import for slot children
    -        if (componentImports && !userImportedNames?.has(ecComponent)) {
    -          const componentDef = registry?.getComponent(ecComponent);
    -          const modulePath = componentDef?.modulePath ?? 'astro-expressive-code/components';
    -          const exportType = componentDef?.exportType ?? 'default';
    -          componentImports.set(ecComponent, { modulePath, exportType });
    -        }
    -      } else {
    -        // Render code block as HTML
    -        const langAttr = block.lang ? ` class="language-${escapeHtml(block.lang)}"` : '';
    -        result += `
    ${escapeHtml(block.code ?? '')}
    `; - } + // Always render as HTML
    ; ExpressiveCode rewriting happens in pipeline
    +      const langAttr = block.lang ? ` class="language-${escapeHtml(block.lang)}"` : '';
    +      result += `
    ${escapeHtml(block.code ?? '')}
    `; } else if (block.type === 'component') { - const innerHtml = slotChildrenToHtml(block.slotChildren ?? [], ecComponent, componentImports, registry, userImportedNames); + const innerHtml = slotChildrenToHtml(block.slotChildren ?? [], componentImports, registry, userImportedNames); // Fragment-with-slot: render as // so Astro's slot distribution works (Fragment VNodes are unwrapped, @@ -259,18 +254,13 @@ function extractNamesFromImports(imports: string[]): Set { * @param userImports - User import statements to preserve (these take precedence over registry) * @returns Complete JSX module code with imports, exports, and default component */ -export interface BlocksToJsxOptions { - expressiveCodeComponent?: string; -} - export function blocksToJsx( blocks: Block[], frontmatter: Record = {}, headings: HeadingEntry[] = [], - registry: Registry | null = null, + registry: BlocksRegistry | null = null, filename?: string, userImports: string[] = [], - options: BlocksToJsxOptions = {} ): string { const fragments: string[] = []; const componentImports = new Map(); @@ -287,24 +277,10 @@ export function blocksToJsx( // JSON.stringify handles all escaping; Astro parses the HTML at runtime fragments.push(`<_Fragment set:html={${JSON.stringify(block.content ?? '')}} />`); } else if (block.type === 'code') { - if (options.expressiveCodeComponent) { - // Direct ExpressiveCode rendering - avoids HTML→regex→component roundtrip - const comp = options.expressiveCodeComponent; - const langProp = block.lang ? ` lang="${escapeJsString(block.lang)}"` : ''; - const metaProp = block.meta ? ` meta="${escapeJsString(block.meta)}"` : ''; - fragments.push(`<${comp} code={${JSON.stringify(block.code ?? '')}}${langProp}${metaProp} />`); - if (!userImportedNames.has(comp)) { - const componentDef = registry?.getComponent(comp); - const modulePath = componentDef?.modulePath ?? 'astro-expressive-code/components'; - const exportType = componentDef?.exportType ?? 'default'; - componentImports.set(comp, { modulePath, exportType }); - } - } else { - // Render as HTML
     for pipeline processing
    -        const langAttr = block.lang ? ` class="language-${escapeHtml(block.lang)}"` : '';
    -        const html = `
    ${escapeHtml(block.code ?? '')}
    `; - fragments.push(`<_Fragment set:html={${JSON.stringify(html)}} />`); - } + // Always render as HTML
    ; ExpressiveCode rewriting happens in pipeline
    +      const langAttr = block.lang ? ` class="language-${escapeHtml(block.lang)}"` : '';
    +      const html = `
    ${escapeHtml(block.code ?? '')}
    `; + fragments.push(`<_Fragment set:html={${JSON.stringify(html)}} />`); } else if (block.type === 'component') { // Handle directive components using registry const isDirective = block.name ? supportedDirectives.includes(block.name) : false; @@ -342,7 +318,7 @@ export function blocksToJsx( // Convert regular (non-fragment-slot) children to HTML string for slot processing let effectiveSlot = stripParagraphFragmentWrappers( - slotChildrenToHtml(regularChildren, options.expressiveCodeComponent, componentImports, registry ?? undefined, userImportedNames) + slotChildrenToHtml(regularChildren, componentImports, registry ?? undefined, userImportedNames) ); if (isDirective && registry && block.name) { @@ -427,7 +403,7 @@ export function blocksToJsx( // Using a real HTML element (not Fragment) so Astro's slot distribution // correctly assigns the content to the named slot. for (const { slotName, inner } of fragmentSlotChildren) { - const innerHtml = slotChildrenToHtml(inner, options.expressiveCodeComponent, componentImports, registry ?? undefined, userImportedNames); + const innerHtml = slotChildrenToHtml(inner, componentImports, registry ?? undefined, userImportedNames); children += ``; if (innerHtml) { if (hasPascalCaseTag(innerHtml)) { diff --git a/packages/astro-markflow/src/transforms/index.ts b/packages/astro-markflow/src/transforms/index.ts index 31500bb..5257b9d 100644 --- a/packages/astro-markflow/src/transforms/index.ts +++ b/packages/astro-markflow/src/transforms/index.ts @@ -15,8 +15,6 @@ import { } from './inject-components.js'; import { rewriteAstroSetHtml, highlightJsxCodeBlocks } from './shiki.js'; import type { TransformContext } from '../types.js'; -import { normalizeSteps } from './normalize-steps.js'; -import { normalizeFileTree } from './normalize-filetree.js'; /** * Transform that rewrites
     blocks to ExpressiveCode components.
    @@ -100,5 +98,3 @@ export {
     } from './inject-components.js';
     export { rewriteAstroSetHtml, highlightHtmlBlocks, highlightJsxCodeBlocks } from './shiki.js';
     export { blocksToJsx } from './blocks-to-jsx.js';
    -export { normalizeSteps } from './normalize-steps.js';
    -export { normalizeFileTree } from './normalize-filetree.js';
    diff --git a/packages/astro-markflow/src/transforms/normalize-filetree.ts b/packages/astro-markflow/src/transforms/normalize-filetree.ts
    deleted file mode 100644
    index a63b77b..0000000
    --- a/packages/astro-markflow/src/transforms/normalize-filetree.ts
    +++ /dev/null
    @@ -1,42 +0,0 @@
    -/**
    - * Ensures Starlight  receives a single 
      child. - * If the slot already starts with
        , it is left untouched. - * If the slot is empty, inject an empty
          . - * Otherwise the inner HTML is wrapped in
            ...
          . - */ -export function normalizeFileTree(code: string): { code: string; changed: boolean } { - if (!code || typeof code !== 'string') { - return { code, changed: false }; - } - - const pattern = /]*)?>([\s\S]*?)<\/FileTree>/g; - let changed = false; - - const next = code.replace(pattern, (match, attrs = '', inner = '') => { - const trimmed = inner.trim(); - const containsLi = /]/i.test(trimmed); - - // Empty slot: inject ul with an empty li - if (!trimmed) { - changed = true; - return `
          `; - } - - // Already a ul wrapper - if (trimmed.startsWith('')) { - if (containsLi) return match; // compliant - // add a placeholder li - changed = true; - return `${trimmed.replace('
        ', '
      ')}
      `; - } - - // Wrap and ensure at least one li - changed = true; - if (containsLi) { - return `
        ${inner}
      `; - } - return `
      • ${inner}
      `; - }); - - return { code: next, changed }; -} diff --git a/packages/astro-markflow/src/transforms/normalize-steps.ts b/packages/astro-markflow/src/transforms/normalize-steps.ts deleted file mode 100644 index cb0bb71..0000000 --- a/packages/astro-markflow/src/transforms/normalize-steps.ts +++ /dev/null @@ -1,24 +0,0 @@ -/** - * Ensures Starlight receives a single
        child. - * If the slot already starts with
          , it is left untouched. - * Otherwise the inner HTML is wrapped in
          1. ...
          . - */ -export function normalizeSteps(code: string): { code: string; changed: boolean } { - if (!code || typeof code !== 'string') { - return { code, changed: false }; - } - - const pattern = /]*)?>([\s\S]*?)<\/Steps>/g; - let changed = false; - - const next = code.replace(pattern, (match, attrs = '', inner = '') => { - const trimmed = inner.trim(); - if (trimmed.startsWith('')) { - return match; // already compliant - } - changed = true; - return `
          1. ${inner}
          `; - }); - - return { code: next, changed }; -} diff --git a/packages/astro-markflow/src/vite-plugin.ts b/packages/astro-markflow/src/vite-plugin.ts index c504f0d..5bbb6cf 100644 --- a/packages/astro-markflow/src/vite-plugin.ts +++ b/packages/astro-markflow/src/vite-plugin.ts @@ -60,7 +60,7 @@ import type { import { loadMarkflowBinding, ENABLE_SHIKI, IS_MDAST } from './vite-plugin/binding-loader.js'; import { wrapHtmlInJsxModule, compileFallbackModule } from './vite-plugin/jsx-module.js'; import { normalizeStarlightComponents } from './vite-plugin/normalize-config.js'; -import { createShikiHighlighter } from './vite-plugin/shiki-highlighter.js'; +import { ShikiManager } from './vite-plugin/shiki-manager.js'; /** * Resolves library configuration from options. @@ -150,6 +150,13 @@ export function markflowPlugin(userOptions: MarkflowPluginOptions = {}): Plugin const plugins = userOptions.plugins ?? []; const hooks = collectHooks(plugins); + // Create pipeline once (shared across buildStart and load hooks) + const transformPipeline = createPipeline({ + afterParse: hooks.afterParse, + beforeInject: hooks.beforeInject, + beforeOutput: hooks.beforeOutput, + }); + // Build compiler options with default code_sample_components const compilerOptions = { ...(userOptions.compiler ?? {}), @@ -182,20 +189,10 @@ export function markflowPlugin(userOptions: MarkflowPluginOptions = {}): Plugin ? value.slice(VIRTUAL_MODULE_PREFIX.length) : value; - let shikiReady: Promise<(code: string, lang?: string) => Promise> | undefined; - // Enable Shiki when: // 1. MARKFLOW_SHIKI=1 env var is set, OR // 2. ExpressiveCode is explicitly disabled (fallback highlighting) - const shouldEnableShiki = ENABLE_SHIKI || !expressiveCode; - - const getShiki = (): Promise<(code: string, lang?: string) => Promise> | null => { - if (!shouldEnableShiki) return null; - if (!shikiReady) { - shikiReady = createShikiHighlighter(); - } - return shikiReady; - }; + const shikiManager = new ShikiManager(ENABLE_SHIKI || !expressiveCode); // Lazy compiler initialization to avoid Vite module runner timing issues const getCompiler = async (): Promise => { @@ -405,23 +402,12 @@ export function markflowPlugin(userOptions: MarkflowPluginOptions = {}): Plugin const jsxInputs: Array<{ id: string; virtualId: string; jsx: string }> = []; debugTime('buildStart:shikiInit'); - - // Initialize shiki highlighter if enabled (shared across all files) - const shikiHighlighter = getShiki(); - const resolvedShiki = shikiHighlighter ? await shikiHighlighter : null; - + const resolvedShiki = await shikiManager.init(); debugTimeEnd('buildStart:shikiInit'); // Normalize starlightComponents for TransformContext const normalizedStarlightComponents = normalizeStarlightComponents(starlightComponents); - // Create pipeline once (reusable) - const transformPipeline = createPipeline({ - afterParse: hooks.afterParse, - beforeInject: hooks.beforeInject, - beforeOutput: hooks.beforeOutput, - }); - debugTime('buildStart:pipelineProcessing'); // Process each cached file through the pipeline @@ -455,9 +441,6 @@ export function markflowPlugin(userOptions: MarkflowPluginOptions = {}): Plugin hasUserDefaultExport: cached.hasUserDefaultExport, }); - // PERF: Only enable shiki for files with code blocks - const hasCodeBlocks = /]/.test(jsxCode); - // Get source for hooks const sourceForHooks = originalSourceCache.get(filename) ?? @@ -477,7 +460,7 @@ export function markflowPlugin(userOptions: MarkflowPluginOptions = {}): Plugin config: { expressiveCode, starlightComponents: normalizedStarlightComponents, - shiki: hasCodeBlocks ? resolvedShiki : null, + shiki: shikiManager.forCode(jsxCode, resolvedShiki), }, }; @@ -698,9 +681,6 @@ export function markflowPlugin(userOptions: MarkflowPluginOptions = {}): Plugin totalProcessingTimeMs += endTime - startTime; processedFiles.add(filename); - // PERF: Only enable shiki for files with code blocks - const hasCodeBlocks = /]/.test(result.code); - const shikiHighlighter = hasCodeBlocks ? getShiki() : null; const normalizedStarlightComponents = normalizeStarlightComponents(starlightComponents); const sourceForHooks = originalSourceCache.get(filename) ?? @@ -718,16 +698,10 @@ export function markflowPlugin(userOptions: MarkflowPluginOptions = {}): Plugin config: { expressiveCode, starlightComponents: normalizedStarlightComponents, - shiki: shikiHighlighter ? await shikiHighlighter : null, + shiki: await shikiManager.getFor(result.code), }, }; - const transformPipeline = createPipeline({ - afterParse: hooks.afterParse, - beforeInject: hooks.beforeInject, - beforeOutput: hooks.beforeOutput, - }); - const transformed = await transformPipeline(ctx); result.code = transformed.code; @@ -793,9 +767,7 @@ export function markflowPlugin(userOptions: MarkflowPluginOptions = {}): Plugin frontmatter = frontmatterResult.frontmatter || {}; result = { - code: blocksToJsx(parseResult.blocks, frontmatter, headings, registry, filename, userImports, { - expressiveCodeComponent: expressiveCode?.component, - }), + code: blocksToJsx(parseResult.blocks, frontmatter, headings, registry, filename, userImports), map: null, frontmatter_json: JSON.stringify(frontmatter), headings, @@ -828,9 +800,6 @@ export function markflowPlugin(userOptions: MarkflowPluginOptions = {}): Plugin } } - // PERF: Only enable shiki for files with code blocks - const hasCodeBlocks = /]/.test(result.code); - const shikiHighlighter = hasCodeBlocks ? getShiki() : null; const normalizedStarlightComponents = normalizeStarlightComponents(starlightComponents); const ctx: TransformContext = { code: result.code, @@ -842,16 +811,10 @@ export function markflowPlugin(userOptions: MarkflowPluginOptions = {}): Plugin config: { expressiveCode, starlightComponents: normalizedStarlightComponents, - shiki: shikiHighlighter ? await shikiHighlighter : null, + shiki: await shikiManager.getFor(result.code), }, }; - const transformPipeline = createPipeline({ - afterParse: hooks.afterParse, - beforeInject: hooks.beforeInject, - beforeOutput: hooks.beforeOutput, - }); - const transformed = await transformPipeline(ctx); result.code = transformed.code; diff --git a/packages/astro-markflow/src/vite-plugin/shiki-manager.ts b/packages/astro-markflow/src/vite-plugin/shiki-manager.ts new file mode 100644 index 0000000..4eb302e --- /dev/null +++ b/packages/astro-markflow/src/vite-plugin/shiki-manager.ts @@ -0,0 +1,53 @@ +/** + * Manages Shiki highlighter lifecycle as a lazy singleton. + * @module vite-plugin/shiki-manager + */ + +import { createShikiHighlighter } from './shiki-highlighter.js'; +import type { ShikiHighlighter } from '../transforms/shiki.js'; + +export class ShikiManager { + private instance: Promise | undefined; + private enabled: boolean; + + constructor(enabled: boolean) { + this.enabled = enabled; + } + + /** + * Returns the Shiki highlighter promise, initializing on first call. + * Returns null if Shiki is disabled or code has no `
          ` tags.
          +   */
          +  async getFor(code: string): Promise {
          +    if (!this.enabled || !ShikiManager.hasCodeBlocks(code)) return null;
          +    if (!this.instance) {
          +      this.instance = createShikiHighlighter();
          +    }
          +    return this.instance.catch(() => null);
          +  }
          +
          +  /**
          +   * Eagerly initializes the highlighter (e.g. in buildStart).
          +   * Returns the resolved highlighter or null.
          +   */
          +  async init(): Promise {
          +    if (!this.enabled) return null;
          +    if (!this.instance) {
          +      this.instance = createShikiHighlighter();
          +    }
          +    return this.instance.catch(() => null);
          +  }
          +
          +  /**
          +   * Returns the already-resolved highlighter for code with pre tags,
          +   * using a pre-resolved instance to avoid extra awaits in hot paths.
          +   */
          +  forCode(code: string, resolved: ShikiHighlighter | null): ShikiHighlighter | null {
          +    if (!this.enabled || !resolved || !ShikiManager.hasCodeBlocks(code)) return null;
          +    return resolved;
          +  }
          +
          +  static hasCodeBlocks(code: string): boolean {
          +    return /]/.test(code);
          +  }
          +}
          diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
          index 205cd88..f1399a7 100644
          --- a/pnpm-lock.yaml
          +++ b/pnpm-lock.yaml
          @@ -42,9 +42,6 @@ importers:
                 '@napi-rs/cli':
                   specifier: ^3.4.1
                   version: 3.5.0(@emnapi/runtime@1.7.1)(@types/node@25.0.3)
          -      ava:
          -        specifier: ^6.4.1
          -        version: 6.4.1(rollup@4.54.0)
                 prettier:
                   specifier: ^3.6.2
                   version: 3.7.4
          @@ -1197,10 +1194,6 @@ packages:
               resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==}
               engines: {node: '>=12'}
           
          -  '@isaacs/fs-minipass@4.0.1':
          -    resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==}
          -    engines: {node: '>=18.0.0'}
          -
             '@jridgewell/gen-mapping@0.3.13':
               resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==}
           
          @@ -1238,11 +1231,6 @@ packages:
               version: 0.1.1
               engines: {node: '>=18.17.0'}
           
          -  '@mapbox/node-pre-gyp@2.0.3':
          -    resolution: {integrity: sha512-uwPAhccfFJlsfCxMYTwOdVfOz3xqyj8xYL3zJj8f0pb30tLohnnFPhLuqp4/qoEz8sNxe4SESZedcBojRefIzg==}
          -    engines: {node: '>=18'}
          -    hasBin: true
          -
             '@mdx-js/mdx@3.1.1':
               resolution: {integrity: sha512-f6ZO2ifpwAQIpzGWaBQT2TXxPv6z3RBzQKpVftEWN78Vl/YweF1uwussDx8ECAXVtr3Rs89fKyG9YlzUs9DyGQ==}
           
          @@ -1921,10 +1909,6 @@ packages:
             '@shikijs/vscode-textmate@10.0.2':
               resolution: {integrity: sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==}
           
          -  '@sindresorhus/merge-streams@2.3.0':
          -    resolution: {integrity: sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==}
          -    engines: {node: '>=18'}
          -
             '@sindresorhus/merge-streams@4.0.0':
               resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==}
               engines: {node: '>=18'}
          @@ -2126,11 +2110,6 @@ packages:
             '@ungap/structured-clone@1.3.0':
               resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==}
           
          -  '@vercel/nft@0.29.4':
          -    resolution: {integrity: sha512-6lLqMNX3TuycBPABycx7A9F1bHQR7kiQln6abjFbPrf5C/05qHM9M5E4PeTE59c7z8g6vHnx1Ioihb2AQl7BTA==}
          -    engines: {node: '>=18'}
          -    hasBin: true
          -
             '@volar/kit@2.4.27':
               resolution: {integrity: sha512-ilZoQDMLzqmSsImJRWx4YiZ4FcvvPrPnFVmL6hSsIWB6Bn3qc7k88J9yP32dagrs5Y8EXIlvvD/mAFaiuEOACQ==}
               peerDependencies:
          @@ -2160,33 +2139,16 @@ packages:
             '@webgpu/types@0.1.21':
               resolution: {integrity: sha512-pUrWq3V5PiSGFLeLxoGqReTZmiiXwY3jRkIG5sLLKjyqNxrwm/04b4nw7LSmGWJcKk59XOM/YRTUwOzo4MMlow==}
           
          -  abbrev@3.0.1:
          -    resolution: {integrity: sha512-AO2ac6pjRB3SJmGJo+v5/aK6Omggp6fsLrs6wN9bd35ulu4cCwaAU9+7ZhXjeqHVkaHThLuzH0nZr0YpCDhygg==}
          -    engines: {node: ^18.17.0 || >=20.5.0}
          -
          -  acorn-import-attributes@1.9.5:
          -    resolution: {integrity: sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==}
          -    peerDependencies:
          -      acorn: ^8
          -
             acorn-jsx@5.3.2:
               resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==}
               peerDependencies:
                 acorn: ^6.0.0 || ^7.0.0 || ^8.0.0
           
          -  acorn-walk@8.3.4:
          -    resolution: {integrity: sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==}
          -    engines: {node: '>=0.4.0'}
          -
             acorn@8.15.0:
               resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==}
               engines: {node: '>=0.4.0'}
               hasBin: true
           
          -  agent-base@7.1.4:
          -    resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==}
          -    engines: {node: '>= 14'}
          -
             ajv-draft-04@1.0.0:
               resolution: {integrity: sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==}
               peerDependencies:
          @@ -2248,21 +2210,9 @@ packages:
               resolution: {integrity: sha512-gUAZ7HPyb4SJczXAMUXMGAvI976JoK3qEx9v1FTmeYuJj0IBiaKttG1ydtGKdkfqWkIkouke7nG8ufGy77+Cvw==}
               engines: {node: '>=12.17'}
           
          -  array-find-index@1.0.2:
          -    resolution: {integrity: sha512-M1HQyIXcBGtVywBt8WVdim+lrNaK7VHp99Qt5pSNziXznKHViIBbXWtfRTpEFpF/c4FdfxNAsCCwPp5phBYJtw==}
          -    engines: {node: '>=0.10.0'}
          -
             array-iterate@2.0.1:
               resolution: {integrity: sha512-I1jXZMjAgCMmxT4qxXfPXa6SthSoE8h6gkSI9BGGNv8mP8G/v0blc+qFnZu6K42vTOiuME596QaLO0TP3Lk0xg==}
           
          -  arrgv@1.0.2:
          -    resolution: {integrity: sha512-a4eg4yhp7mmruZDQFqVMlxNRFGi/i1r87pt8SDHy0/I8PqSXoUTlWZRdAZo0VXgvEARcujbtTk8kiZRi1uDGRw==}
          -    engines: {node: '>=8.0.0'}
          -
          -  arrify@3.0.0:
          -    resolution: {integrity: sha512-tLkvA81vQG/XqE2mjDkGQHoOINtMHtysSnemrmoGe6PydDPMRbVugqyk4A6V/WDWEfm3l+0d8anA9r8cv/5Jaw==}
          -    engines: {node: '>=12'}
          -
             ast-kit@2.2.0:
               resolution: {integrity: sha512-m1Q/RaVOnTp9JxPX+F+Zn7IcLYMzM8kZofDImfsKZd8MbR+ikdOzTeztStWqfrqIxZnYWryyI9ePm3NGjnZgGw==}
               engines: {node: '>=20.19.0'}
          @@ -2310,19 +2260,6 @@ packages:
               peerDependencies:
                 '@astrojs/compiler': '>=0.27.0'
           
          -  async-sema@3.1.1:
          -    resolution: {integrity: sha512-tLRNUXati5MFePdAk8dw7Qt7DpxPB60ofAgn8WRhW6a2rcimZnYBP9oxHiv0OHy+Wz7kPMG+t4LGdt31+4EmGg==}
          -
          -  ava@6.4.1:
          -    resolution: {integrity: sha512-vxmPbi1gZx9zhAjHBgw81w/iEDKcrokeRk/fqDTyA2DQygZ0o+dUGRHFOtX8RA5N0heGJTTsIk7+xYxitDb61Q==}
          -    engines: {node: ^18.18 || ^20.8 || ^22 || ^23 || >=24}
          -    hasBin: true
          -    peerDependencies:
          -      '@ava/typescript': '*'
          -    peerDependenciesMeta:
          -      '@ava/typescript':
          -        optional: true
          -
             axobject-query@4.1.0:
               resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==}
               engines: {node: '>= 0.4'}
          @@ -2351,18 +2288,12 @@ packages:
             before-after-hook@4.0.0:
               resolution: {integrity: sha512-q6tR3RPqIB1pMiTRMFcZwuG5T8vwp+vUvEG0vuI6B+Rikh5BfPp2fQ82c925FOs+b0lcFQ8CFrL+KbilfZFhOQ==}
           
          -  bindings@1.5.0:
          -    resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==}
          -
             birpc@2.9.0:
               resolution: {integrity: sha512-KrayHS5pBi69Xi9JmvoqrIgYGDkD6mcSe/i6YKi3w5kekCLzrX4+nawcXqrj2tIp50Kw/mT/s3p+GVK0A0sKxw==}
           
             bluebird@3.7.2:
               resolution: {integrity: sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==}
           
          -  blueimp-md5@2.19.0:
          -    resolution: {integrity: sha512-DRQrD6gJyy8FbiE4s+bDoXS9hiW3Vbx5uCdwvcCf3zLHL+Iv7LtGHLpr+GZV8rHG8tK766FGYBwRbu8pELTt+w==}
          -
             boolbase@1.0.0:
               resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==}
           
          @@ -2414,10 +2345,6 @@ packages:
               resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==}
               engines: {node: '>=6'}
           
          -  callsites@4.2.0:
          -    resolution: {integrity: sha512-kfzR4zzQtAE9PC7CzZsjl3aBNbXWuXiSeOCdLcPpBfGW8YuCqQHcRPFDbr/BPVmd3EEPVpuFzLyuT/cUhPr4OQ==}
          -    engines: {node: '>=12.20'}
          -
             camelcase@8.0.0:
               resolution: {integrity: sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA==}
               engines: {node: '>=16'}
          @@ -2432,10 +2359,6 @@ packages:
               resolution: {integrity: sha512-prMTQVpcns/tzFgFVkVp6ak6RykZyWb3gu8ckUpd6YkTlacOd3DXGJjIpD4Q6zJirizvaiAjSSHlOsA+6sNh2A==}
               engines: {node: '>= 10'}
           
          -  cbor@10.0.11:
          -    resolution: {integrity: sha512-vIwORDd/WyB8Nc23o2zNN5RrtFGlR6Fca61TtjkUXueI3Jf2DOZDl1zsshvBntZ3wZHBM9ztjnkXSmzQDaq3WA==}
          -    engines: {node: '>=20'}
          -
             ccount@1.1.0:
               resolution: {integrity: sha512-vlNK021QdI7PNeiUh/lKkC/mNHHfV0m/Ad5JoI0TYtlBnJAslM/JIkm/tGC88bkLIwO6OQ5uV6ztS6kVAtCDlg==}
           
          @@ -2481,28 +2404,14 @@ packages:
               resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==}
               engines: {node: '>= 14.16.0'}
           
          -  chownr@3.0.0:
          -    resolution: {integrity: sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==}
          -    engines: {node: '>=18'}
          -
          -  chunkd@2.0.1:
          -    resolution: {integrity: sha512-7d58XsFmOq0j6el67Ug9mHf9ELUXsQXYJBkyxhH/k+6Ke0qXRnv0kbemx+Twc6fRJ07C49lcbdgm9FL1Ei/6SQ==}
          -
             ci-info@4.3.1:
               resolution: {integrity: sha512-Wdy2Igu8OcBpI2pZePZ5oWjPC38tmDVx5WKUXKwlLYkA0ozo85sLsLvkBbBn/sZaSCMFOGZJ14fvW9t5/d7kdA==}
               engines: {node: '>=8'}
           
          -  ci-parallel-vars@1.0.1:
          -    resolution: {integrity: sha512-uvzpYrpmidaoxvIQHM+rKSrigjOe9feHYbw4uOI2gdfe1C3xIlxO+kVXq83WQWNniTf8bAxVpy+cQeFQsMERKg==}
          -
             cli-boxes@3.0.0:
               resolution: {integrity: sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==}
               engines: {node: '>=10'}
           
          -  cli-truncate@4.0.0:
          -    resolution: {integrity: sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==}
          -    engines: {node: '>=18'}
          -
             cli-width@4.1.0:
               resolution: {integrity: sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==}
               engines: {node: '>= 12'}
          @@ -2524,10 +2433,6 @@ packages:
               resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==}
               engines: {node: '>=6'}
           
          -  code-excerpt@4.0.0:
          -    resolution: {integrity: sha512-xxodCmBen3iy2i0WtAK8FlFNrRzjUqjRsMfho58xT/wvZU1YTM3fCnRjcy1gJPMepaRlgm/0e6w8SpWHpn3/cA==}
          -    engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
          -
             collapse-white-space@2.1.0:
               resolution: {integrity: sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==}
           
          @@ -2551,24 +2456,13 @@ packages:
             common-ancestor-path@1.0.1:
               resolution: {integrity: sha512-L3sHRo1pXXEqX8VU28kfgUY+YGsk09hPqZiZmLacNib6XNTCM8ubYeT7ryXQw8asB1sKgcU5lkB7ONug08aB8w==}
           
          -  common-path-prefix@3.0.0:
          -    resolution: {integrity: sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==}
          -
             concat-map@0.0.1:
               resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
           
          -  concordance@5.0.4:
          -    resolution: {integrity: sha512-OAcsnTEYu1ARJqWVGwf4zh4JDfHZEaSNlNccFmt8YjB2l/n19/PF2viLINHc57vO4FKIAFl2FWASIGZZWZ2Kxw==}
          -    engines: {node: '>=10.18.0 <11 || >=12.14.0 <13 || >=14'}
          -
             consola@3.4.2:
               resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==}
               engines: {node: ^14.18.0 || >=16.10.0}
           
          -  convert-to-spaces@2.0.1:
          -    resolution: {integrity: sha512-rcQ1bsQO9799wq24uE5AM2tAILy4gXGIK/njFWcVQkGNZ96edlpY+A7bjwvzjYvLDyzmG1MmMLZhpcsb+klNMQ==}
          -    engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
          -
             cookie-es@1.2.2:
               resolution: {integrity: sha512-+W7VmiVINB+ywl1HGXJXmrqkOhpKrIiVZV6tQuV54ZyQC7MMuBt81Vc336GMLoHBq5hV/F9eXgt5Mnx0Rha5Fg==}
           
          @@ -2617,14 +2511,6 @@ packages:
               resolution: {integrity: sha512-7AH+ZTRKikdK4s1RmY0l6067UD/NZc7p3zZVZxvmnH80G31kr0y0W0E6ibYM4IS01MEm8DiC5FnTcgcgkbFHoA==}
               engines: {node: '>=12.17'}
           
          -  currently-unhandled@0.4.1:
          -    resolution: {integrity: sha512-/fITjgjGU50vjQ4FH6eUoYu+iUoUKIXws2hL15JJpIR+BbTxaXQsMuuyjtNh2WqsSBS5nsaZHFsFecyw5CCAng==}
          -    engines: {node: '>=0.10.0'}
          -
          -  date-time@3.1.0:
          -    resolution: {integrity: sha512-uqCUKXE5q1PNBXjPqvwhwJf9SwMoAHBgWJ6DcrnS5o+W2JOiIILl0JEdVD8SGujrNS02GGxgwAg2PN2zONgtjg==}
          -    engines: {node: '>=6'}
          -
             debug@4.4.3:
               resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==}
               engines: {node: '>=6.0'}
          @@ -2726,10 +2612,6 @@ packages:
             eastasianwidth@0.2.0:
               resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
           
          -  emittery@1.2.0:
          -    resolution: {integrity: sha512-KxdRyyFcS85pH3dnU8Y5yFUm2YJdaHwcBZWrfG8o89ZY9a13/f9itbN+YG3ELbBo9Pg5zvIozstmuV8bX13q6g==}
          -    engines: {node: '>=14.16'}
          -
             emmet@2.4.11:
               resolution: {integrity: sha512-23QPJB3moh/U9sT4rQzGgeyyGIrcM+GH5uVYg2C6wZIxAIJq7Ng3QLT79tl8FUwDXhyq9SusfknOrofAKqvgyQ==}
           
          @@ -2921,9 +2803,6 @@ packages:
             fast-deep-equal@3.1.3:
               resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
           
          -  fast-diff@1.3.0:
          -    resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==}
          -
             fast-equals@4.0.3:
               resolution: {integrity: sha512-G3BSX9cfKttjr+2o1O22tYMLq0DPluZnYtq1rXumE1SpL/F/SLIfHx08WYQoWSIpeMYf8sRbJ8++71+v6Pnxfg==}
           
          @@ -2955,10 +2834,6 @@ packages:
                 picomatch:
                   optional: true
           
          -  figures@6.1.0:
          -    resolution: {integrity: sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==}
          -    engines: {node: '>=18'}
          -
             file-entry-cache@10.1.4:
               resolution: {integrity: sha512-5XRUFc0WTtUbjfGzEwXc42tiGxQHBmtbUG1h9L2apu4SulCGN3Hqm//9D6FAolf8MYNL7f/YlJl9vy08pj5JuA==}
           
          @@ -2975,17 +2850,10 @@ packages:
                 '@75lb/nature':
                   optional: true
           
          -  file-uri-to-path@1.0.0:
          -    resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==}
          -
             fill-range@7.1.1:
               resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==}
               engines: {node: '>=8'}
           
          -  find-up-simple@1.0.1:
          -    resolution: {integrity: sha512-afd4O7zpqHeRyg4PfDQsXmlDe2PfdHtJt6Akt8jOWaApLOZk5JXs6VMR29lz03pRe9mpykrRCYIYxaJYcfpncQ==}
          -    engines: {node: '>=18'}
          -
             find-up@2.1.0:
               resolution: {integrity: sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==}
               engines: {node: '>=4'}
          @@ -3085,10 +2953,6 @@ packages:
               resolution: {integrity: sha512-c/c15i26VrJ4IRt5Z89DnIzCGDn9EcebibhAOjw5ibqEHsE1wLUgkPn9RDmNcUKyU87GeaL633nyJ+pplFR2ZQ==}
               engines: {node: '>=18'}
           
          -  globby@14.1.0:
          -    resolution: {integrity: sha512-0Ia46fDOaT7k4og1PDW4YbodWWr3scS2vAr2lTbsplOt2WkKp0vQbkI9wKis/T5LV/dqPjO3bpS/z6GTJB82LA==}
          -    engines: {node: '>=18'}
          -
             globby@16.0.0:
               resolution: {integrity: sha512-ejy4TJFga99yW6Q0uhM3pFawKWZmtZzZD/v/GwI5+9bCV5Ew+D2pSND6W7fUes5UykqSsJkUfxFVdRh7Q1+P3Q==}
               engines: {node: '>=20'}
          @@ -3216,10 +3080,6 @@ packages:
             http-cache-semantics@4.2.0:
               resolution: {integrity: sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==}
           
          -  https-proxy-agent@7.0.6:
          -    resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==}
          -    engines: {node: '>= 14'}
          -
             i18next@23.16.8:
               resolution: {integrity: sha512-06r/TitrM88Mg5FdUXAKL96dJMzgqLE5dv3ryBAra4KCwD9mJ4ndOTS95ZuymIGoE+2hzfdaMak2X11/es7ZWg==}
           
          @@ -3227,10 +3087,6 @@ packages:
               resolution: {integrity: sha512-2Tth85cXwGFHfvRgZWszZSvdo+0Xsqmw8k8ZwxScfcBneNUraK+dxRxRm24nszx80Y0TVio8kKLt5sLE7ZCLlw==}
               engines: {node: '>=0.10.0'}
           
          -  ignore-by-default@2.1.0:
          -    resolution: {integrity: sha512-yiWd4GVmJp0Q6ghmM2B/V3oZGRmjrKLXvHR3TE1nfoXsmoggllfZUQe74EN0fJdPFZu2NIvNdrMMLm3OsV7Ohw==}
          -    engines: {node: '>=10 <11 || >=12 <13 || >=14'}
          -
             ignore@5.3.2:
               resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==}
               engines: {node: '>= 4'}
          @@ -3250,20 +3106,12 @@ packages:
               resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==}
               engines: {node: '>=0.8.19'}
           
          -  indent-string@5.0.0:
          -    resolution: {integrity: sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==}
          -    engines: {node: '>=12'}
          -
             inline-style-parser@0.2.7:
               resolution: {integrity: sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA==}
           
             iron-webcrypto@1.2.1:
               resolution: {integrity: sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg==}
           
          -  irregular-plurals@3.5.0:
          -    resolution: {integrity: sha512-1ANGLZ+Nkv1ptFb2pa8oG8Lem4krflKuX/gINiHJHjJUKaJHk/SXk5x6K3J+39/p0h1RQ2saROclJJ+QLvETCQ==}
          -    engines: {node: '>=8'}
          -
             is-alphabetical@1.0.4:
               resolution: {integrity: sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==}
           
          @@ -3313,10 +3161,6 @@ packages:
               resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
               engines: {node: '>=8'}
           
          -  is-fullwidth-code-point@4.0.0:
          -    resolution: {integrity: sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==}
          -    engines: {node: '>=12'}
          -
             is-glob@4.0.3:
               resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
               engines: {node: '>=0.10.0'}
          @@ -3348,17 +3192,6 @@ packages:
               resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==}
               engines: {node: '>=12'}
           
          -  is-plain-object@5.0.0:
          -    resolution: {integrity: sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==}
          -    engines: {node: '>=0.10.0'}
          -
          -  is-promise@4.0.0:
          -    resolution: {integrity: sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==}
          -
          -  is-unicode-supported@2.1.0:
          -    resolution: {integrity: sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==}
          -    engines: {node: '>=18'}
          -
             is-utf8@0.2.1:
               resolution: {integrity: sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q==}
           
          @@ -3384,10 +3217,6 @@ packages:
               resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==}
               hasBin: true
           
          -  js-string-escape@1.0.1:
          -    resolution: {integrity: sha512-Smw4xcfIQ5LVjAOuJCvN/zIodzA/BBSsluuoSykP+lUvScIi4U6RJLfwHet5cxFnCswUjISV8oAXaqaJDY3chg==}
          -    engines: {node: '>= 0.8'}
          -
             js-yaml@3.14.2:
               resolution: {integrity: sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==}
               hasBin: true
          @@ -3484,10 +3313,6 @@ packages:
               resolution: {integrity: sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==}
               engines: {node: '>=4'}
           
          -  load-json-file@7.0.1:
          -    resolution: {integrity: sha512-Gnxj3ev3mB5TkVBGad0JM6dmLiQL+o0t23JPBZ9sd+yvSLk05mFoqKBw5N8gbbkU4TNXyqCgIrl/VM17OgUIgQ==}
          -    engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
          -
             locate-path@2.0.0:
               resolution: {integrity: sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==}
               engines: {node: '>=4'}
          @@ -3561,18 +3386,10 @@ packages:
             match-index@1.0.3:
               resolution: {integrity: sha512-1XjyBWqCvEFFUDW/MPv0RwbITRD4xQXOvKoPYtLDq8IdZTfdF/cQSo5Yn4qvhfSSZgjgkTFsqJD2wOUG4ovV8Q==}
           
          -  matcher@5.0.0:
          -    resolution: {integrity: sha512-s2EMBOWtXFc8dgqvoAzKJXxNHibcdJMV0gwqKUaw9E2JBJuGUK7DrNKrA6g/i+v72TT16+6sVm5mS3thaMLQUw==}
          -    engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
          -
             math-intrinsics@1.1.0:
               resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==}
               engines: {node: '>= 0.4'}
           
          -  md5-hex@3.0.1:
          -    resolution: {integrity: sha512-BUiRtTtV39LIJwinWBjqVsU9xhdnz7/i889V859IBFpuqGAj6LuOvHv5XLbgZ2R7ptJoJaEcxkv88/h25T7Ciw==}
          -    engines: {node: '>=8'}
          -
             md5@2.3.0:
               resolution: {integrity: sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==}
           
          @@ -3672,10 +3489,6 @@ packages:
             mdurl@2.0.0:
               resolution: {integrity: sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==}
           
          -  memoize@10.2.0:
          -    resolution: {integrity: sha512-DeC6b7QBrZsRs3Y02A6A7lQyzFbsQbqgjI6UW0GigGWV+u1s25TycMr0XHZE4cJce7rY/vyw2ctMQqfDkIhUEA==}
          -    engines: {node: '>=18'}
          -
             merge2@1.4.1:
               resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
               engines: {node: '>= 8'}
          @@ -3819,10 +3632,6 @@ packages:
               resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==}
               engines: {node: '>=8.6'}
           
          -  mimic-function@5.0.1:
          -    resolution: {integrity: sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==}
          -    engines: {node: '>=18'}
          -
             minimatch@10.1.1:
               resolution: {integrity: sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==}
               engines: {node: 20 || >=22}
          @@ -3841,10 +3650,6 @@ packages:
               resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==}
               engines: {node: '>=16 || 14 >=14.17'}
           
          -  minizlib@3.1.0:
          -    resolution: {integrity: sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==}
          -    engines: {node: '>= 18'}
          -
             mkdirp@0.5.6:
               resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==}
               hasBin: true
          @@ -3886,31 +3691,9 @@ packages:
             node-fetch-native@1.6.7:
               resolution: {integrity: sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==}
           
          -  node-fetch@2.7.0:
          -    resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==}
          -    engines: {node: 4.x || >=6.0.0}
          -    peerDependencies:
          -      encoding: ^0.1.0
          -    peerDependenciesMeta:
          -      encoding:
          -        optional: true
          -
          -  node-gyp-build@4.8.4:
          -    resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==}
          -    hasBin: true
          -
             node-mock-http@1.0.4:
               resolution: {integrity: sha512-8DY+kFsDkNXy1sJglUfuODx1/opAGJGyrTuFqEoN90oRc2Vk0ZbD4K2qmKXBBEhZQzdKHIVfEJpDU8Ak2NJEvQ==}
           
          -  nofilter@3.1.0:
          -    resolution: {integrity: sha512-l2NNj07e9afPnhAhvgVrCD/oy2Ai1yfLpuo3EpiO1jFTsB4sFz6oIfAfSZyQzVpkZQ9xS8ZS5g1jCBgq4Hwo0g==}
          -    engines: {node: '>=12.19'}
          -
          -  nopt@8.1.0:
          -    resolution: {integrity: sha512-ieGu42u/Qsa4TFktmaKEwM6MQH0pOWnaB3htzh0JRtx84+Mebc0cbZYN5bC+6WTZ4+77xrL9Pn5m7CV6VIkV7A==}
          -    engines: {node: ^18.17.0 || >=20.5.0}
          -    hasBin: true
          -
             normalize-package-data@2.5.0:
               resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==}
           
          @@ -3976,10 +3759,6 @@ packages:
               resolution: {integrity: sha512-T8BatKGY+k5rU+Q/GTYgrEf2r4xRMevAN5mtXc2aPc4rS1j3s+vWTaO2Wag94neXuCAUAs8cxBL9EeB5EA6diw==}
               engines: {node: '>=16'}
           
          -  p-map@7.0.4:
          -    resolution: {integrity: sha512-tkAQEw8ysMzmkhgw8k+1U/iPhWNhykKnSk4Rd5zLoPJCuJaGRPo6YposrZgaxHKzDHdDWWZvE/Sk7hsL2X/CpQ==}
          -    engines: {node: '>=18'}
          -
             p-queue@8.1.1:
               resolution: {integrity: sha512-aNZ+VfjobsWryoiPnEApGGmf5WmNsCo9xu8dfaYamG5qaLP7ClhLN6NgsFe6SwJ2UbLEBK5dv9x8Mn5+RVhMWQ==}
               engines: {node: '>=18'}
          @@ -3992,10 +3771,6 @@ packages:
               resolution: {integrity: sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==}
               engines: {node: '>=4'}
           
          -  package-config@5.0.0:
          -    resolution: {integrity: sha512-GYTTew2slBcYdvRHqjhwaaydVMvn/qrGC323+nKclYioNSLTDUM/lGgtGTgyHVtYcozb+XkE8CNhwcraOmZ9Mg==}
          -    engines: {node: '>=18'}
          -
             package-json-from-dist@1.0.1:
               resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==}
           
          @@ -4030,10 +3805,6 @@ packages:
             parse-latin@7.0.0:
               resolution: {integrity: sha512-mhHgobPPua5kZ98EF4HWiH167JWBfl4pvAIXXdbaVohtK7a6YBOy56kvhCqduqyo/f3yrHFWmqmiMg/BkBkYYQ==}
           
          -  parse-ms@4.0.0:
          -    resolution: {integrity: sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==}
          -    engines: {node: '>=18'}
          -
             parse5@7.3.0:
               resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==}
           
          @@ -4077,10 +3848,6 @@ packages:
               resolution: {integrity: sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==}
               engines: {node: '>=4'}
           
          -  path-type@6.0.0:
          -    resolution: {integrity: sha512-Vj7sf++t5pBD637NSfkxpHSMfWaeig5+DKWLhcqIYx6mWQz5hdJTGDVMQiJcw1ZYkhs7AazKDGpRVji1LJCZUQ==}
          -    engines: {node: '>=18'}
          -
             pathe@2.0.3:
               resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==}
           
          @@ -4128,10 +3895,6 @@ packages:
               engines: {node: '>=18'}
               hasBin: true
           
          -  plur@5.1.0:
          -    resolution: {integrity: sha512-VP/72JeXqak2KiOzjgKtQen5y3IZHn+9GOuLDafPv0eXa47xq0At93XahYBs26MsifCQ4enGKwbjBTKgb9QJXg==}
          -    engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
          -
             pluralize@2.0.0:
               resolution: {integrity: sha512-TqNZzQCD4S42De9IfnnBvILN7HAW7riLqsCyp8lgjXeysyPlX5HhqKAcJHHHb9XskE4/a+7VGC9zzx8Ls0jOAw==}
           
          @@ -4177,10 +3940,6 @@ packages:
               engines: {node: '>=14'}
               hasBin: true
           
          -  pretty-ms@9.3.0:
          -    resolution: {integrity: sha512-gjVS5hOP+M3wMm5nmNOucbIrqudzs9v/57bWRHQWLYklXqoXKrVfYW2W9+glfGsqtPgpiz5WwyEEB+ksXIx3gQ==}
          -    engines: {node: '>=18'}
          -
             prismjs@1.30.0:
               resolution: {integrity: sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==}
               engines: {node: '>=6'}
          @@ -4353,18 +4112,10 @@ packages:
             requizzle@0.2.4:
               resolution: {integrity: sha512-JRrFk1D4OQ4SqovXOgdav+K8EAhSB/LJZqCz8tbX0KObcdeM15Ss59ozWMBWmmINMagCwmqn4ZNryUGpBsl6Jw==}
           
          -  resolve-cwd@3.0.0:
          -    resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==}
          -    engines: {node: '>=8'}
          -
             resolve-from@4.0.0:
               resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==}
               engines: {node: '>=4'}
           
          -  resolve-from@5.0.0:
          -    resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==}
          -    engines: {node: '>=8'}
          -
             resolve-pkg-maps@1.0.0:
               resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==}
           
          @@ -4452,10 +4203,6 @@ packages:
               engines: {node: '>=10'}
               hasBin: true
           
          -  serialize-error@7.0.1:
          -    resolution: {integrity: sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==}
          -    engines: {node: '>=10'}
          -
             set-function-length@1.2.2:
               resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==}
               engines: {node: '>= 0.4'}
          @@ -4502,10 +4249,6 @@ packages:
               resolution: {integrity: sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==}
               engines: {node: '>=10'}
           
          -  slice-ansi@5.0.0:
          -    resolution: {integrity: sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==}
          -    engines: {node: '>=12'}
          -
             smol-toml@1.5.2:
               resolution: {integrity: sha512-QlaZEqcAH3/RtNyet1IPIYPsEWAaYyXXv1Krsi+1L/QHppjX4Ifm8MQsBISz9vE8cHicIq3clogsheili5vhaQ==}
               engines: {node: '>= 18'}
          @@ -4536,10 +4279,6 @@ packages:
             sprintf-js@1.0.3:
               resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==}
           
          -  stack-utils@2.0.6:
          -    resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==}
          -    engines: {node: '>=10'}
          -
             starlight-llms-txt@0.6.1:
               resolution: {integrity: sha512-V0XEj92hrWHCDOu2SiDbgPviKnlB/O4Fqh9yeDxjV+udw9y+mSQ+4Obhlj6UUhjn6gfoj0V7dPLM0Dhbd6j1NA==}
               engines: {node: ^18.17.1 || ^20.3.0 || >=21.0.0}
          @@ -4601,10 +4340,6 @@ packages:
             suf-log@2.5.3:
               resolution: {integrity: sha512-KvC8OPjzdNOe+xQ4XWJV2whQA0aM1kGVczMQ8+dStAO6KfEB140JEVQ9dE76ONZ0/Ylf67ni4tILPJB41U0eow==}
           
          -  supertap@3.0.1:
          -    resolution: {integrity: sha512-u1ZpIBCawJnO+0QePsEiOknOfCRq0yERxiAchT0i4li0WHNUJbf0evXXSXOcCAR4M8iMDoajXYmstm/qO81Isw==}
          -    engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
          -
             supports-color@7.2.0:
               resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
               engines: {node: '>=8'}
          @@ -4626,14 +4361,6 @@ packages:
               resolution: {integrity: sha512-9kY+CygyYM6j02t5YFHbNz2FN5QmYGv9zAjVp4lCDjlCw7amdckXlEt/bjMhUIfj4ThGRE4gCUH5+yGnNuPo5A==}
               engines: {node: '>=10.0.0'}
           
          -  tar@7.5.2:
          -    resolution: {integrity: sha512-7NyxrTE4Anh8km8iEy7o0QYPs+0JKBTj5ZaqHg6B39erLg0qYXN3BijtShwbsNSvQ+LN75+KV+C4QR/f6Gwnpg==}
          -    engines: {node: '>=18'}
          -
          -  temp-dir@3.0.0:
          -    resolution: {integrity: sha512-nHc6S/bwIilKHNRgK/3jlhDoIHcp45YgyiwcAk46Tr0LfEqGBVpmiAyuiuxeVE44m3mXnEeVhaipLOEWmH+Njw==}
          -    engines: {node: '>=14.16'}
          -
             text-table@0.2.0:
               resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==}
           
          @@ -4677,10 +4404,6 @@ packages:
               engines: {node: '>=18.14.0'}
               hasBin: true
           
          -  time-zone@1.0.0:
          -    resolution: {integrity: sha512-TIsDdtKo6+XrPtiTm1ssmMngN1sAhyKnTO2kunQWqNPWIVvCm15Wmw4SWInwTVgJ5u/Tr04+8Ei9TNcw4x4ONA==}
          -    engines: {node: '>=4'}
          -
             tiny-inflate@1.0.3:
               resolution: {integrity: sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==}
           
          @@ -4696,9 +4419,6 @@ packages:
               resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
               engines: {node: '>=8.0'}
           
          -  tr46@0.0.3:
          -    resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==}
          -
             tree-kill@1.2.2:
               resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==}
               hasBin: true
          @@ -4767,10 +4487,6 @@ packages:
               resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==}
               engines: {node: '>= 0.8.0'}
           
          -  type-fest@0.13.1:
          -    resolution: {integrity: sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==}
          -    engines: {node: '>=10'}
          -
             type-fest@4.41.0:
               resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==}
               engines: {node: '>=16'}
          @@ -4838,10 +4554,6 @@ packages:
             unicode-trie@2.0.0:
               resolution: {integrity: sha512-x7bc76x0bm4prf1VLg79uhAzKw8DVboClSN5VxJuQ+LKDOVEW9CdH+VY7SP+vX7xCYQqzzgQpFqz15zeLvAtZQ==}
           
          -  unicorn-magic@0.3.0:
          -    resolution: {integrity: sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==}
          -    engines: {node: '>=18'}
          -
             unicorn-magic@0.4.0:
               resolution: {integrity: sha512-wH590V9VNgYH9g3lH9wWjTrUoKsjLF6sGLjhR4sH1LWpLmCOH0Zf7PukhDA8BiS7KHe4oPNkcTHqYkj7SOGUOw==}
               engines: {node: '>=20'}
          @@ -5179,16 +4891,6 @@ packages:
             web-namespaces@2.0.1:
               resolution: {integrity: sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==}
           
          -  webidl-conversions@3.0.1:
          -    resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==}
          -
          -  well-known-symbols@2.0.0:
          -    resolution: {integrity: sha512-ZMjC3ho+KXo0BfJb7JgtQ5IBuvnShdlACNkKkdsqBmYw3bPAaJfPeYUo6tLUaT5tG/Gkh7xkpBhKRQ9e7pyg9Q==}
          -    engines: {node: '>=6'}
          -
          -  whatwg-url@5.0.0:
          -    resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==}
          -
             which-pm-runs@1.1.0:
               resolution: {integrity: sha512-n1brCuqClxfFfq/Rb0ICg9giSZqCS+pLtccdag6C2HyufBrh3fBOiy9nb6ggRMvWOVH5GrdJskj5iGTZNxd7SA==}
               engines: {node: '>=4'}
          @@ -5218,10 +4920,6 @@ packages:
               resolution: {integrity: sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==}
               engines: {node: '>=18'}
           
          -  write-file-atomic@6.0.0:
          -    resolution: {integrity: sha512-GmqrO8WJ1NuzJ2DrziEI2o57jKAVIQNf8a18W3nCYU3H7PNWqCCVTeH6/NQE93CIllIgQS98rrmVkYgTX9fFJQ==}
          -    engines: {node: ^18.17.0 || >=20.5.0}
          -
             xmlcreate@2.0.4:
               resolution: {integrity: sha512-nquOebG4sngPmGPICTS5EnxqhKbCmz5Ox5hsszI2T6U5qdrJizBc+0ilYSEjTSzU0yZcmvppztXe/5Al5fUwdg==}
           
          @@ -5232,10 +4930,6 @@ packages:
               resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==}
               engines: {node: '>=10'}
           
          -  yallist@5.0.0:
          -    resolution: {integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==}
          -    engines: {node: '>=18'}
          -
             yaml-language-server@1.19.2:
               resolution: {integrity: sha512-9F3myNmJzUN/679jycdMxqtydPSDRAarSj3wPiF7pchEPnO9Dg07Oc+gIYLqXR4L+g+FSEVXXv2+mr54StLFOg==}
               hasBin: true
          @@ -6226,10 +5920,6 @@ snapshots:
                 wrap-ansi: 8.1.0
                 wrap-ansi-cjs: wrap-ansi@7.0.0
           
          -  '@isaacs/fs-minipass@4.0.1':
          -    dependencies:
          -      minipass: 7.1.2
          -
             '@jridgewell/gen-mapping@0.3.13':
               dependencies:
                 '@jridgewell/sourcemap-codec': 1.5.5
          @@ -6280,19 +5970,6 @@ snapshots:
               transitivePeerDependencies:
                 - supports-color
           
          -  '@mapbox/node-pre-gyp@2.0.3':
          -    dependencies:
          -      consola: 3.4.2
          -      detect-libc: 2.1.2
          -      https-proxy-agent: 7.0.6
          -      node-fetch: 2.7.0
          -      nopt: 8.1.0
          -      semver: 7.7.3
          -      tar: 7.5.2
          -    transitivePeerDependencies:
          -      - encoding
          -      - supports-color
          -
             '@mdx-js/mdx@3.1.1':
               dependencies:
                 '@types/estree': 1.0.8
          @@ -6836,8 +6513,6 @@ snapshots:
           
             '@shikijs/vscode-textmate@10.0.2': {}
           
          -  '@sindresorhus/merge-streams@2.3.0': {}
          -
             '@sindresorhus/merge-streams@4.0.0': {}
           
             '@swc/helpers@0.5.17':
          @@ -7148,25 +6823,6 @@ snapshots:
           
             '@ungap/structured-clone@1.3.0': {}
           
          -  '@vercel/nft@0.29.4(rollup@4.54.0)':
          -    dependencies:
          -      '@mapbox/node-pre-gyp': 2.0.3
          -      '@rollup/pluginutils': 5.3.0(rollup@4.54.0)
          -      acorn: 8.15.0
          -      acorn-import-attributes: 1.9.5(acorn@8.15.0)
          -      async-sema: 3.1.1
          -      bindings: 1.5.0
          -      estree-walker: 2.0.2
          -      glob: 10.5.0
          -      graceful-fs: 4.2.11
          -      node-gyp-build: 4.8.4
          -      picomatch: 4.0.3
          -      resolve-from: 5.0.0
          -    transitivePeerDependencies:
          -      - encoding
          -      - rollup
          -      - supports-color
          -
             '@volar/kit@2.4.27(typescript@5.6.2)':
               dependencies:
                 '@volar/language-service': 2.4.27
          @@ -7219,24 +6875,12 @@ snapshots:
           
             '@webgpu/types@0.1.21': {}
           
          -  abbrev@3.0.1: {}
          -
          -  acorn-import-attributes@1.9.5(acorn@8.15.0):
          -    dependencies:
          -      acorn: 8.15.0
          -
             acorn-jsx@5.3.2(acorn@8.15.0):
               dependencies:
                 acorn: 8.15.0
           
          -  acorn-walk@8.3.4:
          -    dependencies:
          -      acorn: 8.15.0
          -
             acorn@8.15.0: {}
           
          -  agent-base@7.1.4: {}
          -
             ajv-draft-04@1.0.0(ajv@8.17.1):
               optionalDependencies:
                 ajv: 8.17.1
          @@ -7306,14 +6950,8 @@ snapshots:
           
             array-back@6.2.2: {}
           
          -  array-find-index@1.0.2: {}
          -
             array-iterate@2.0.1: {}
           
          -  arrgv@1.0.2: {}
          -
          -  arrify@3.0.0: {}
          -
             ast-kit@2.2.0:
               dependencies:
                 '@babel/parser': 7.28.5
          @@ -7760,55 +7398,6 @@ snapshots:
                 '@astrojs/compiler': 2.13.0
                 synckit: 0.11.12
           
          -  async-sema@3.1.1: {}
          -
          -  ava@6.4.1(rollup@4.54.0):
          -    dependencies:
          -      '@vercel/nft': 0.29.4(rollup@4.54.0)
          -      acorn: 8.15.0
          -      acorn-walk: 8.3.4
          -      ansi-styles: 6.2.3
          -      arrgv: 1.0.2
          -      arrify: 3.0.0
          -      callsites: 4.2.0
          -      cbor: 10.0.11
          -      chalk: 5.6.2
          -      chunkd: 2.0.1
          -      ci-info: 4.3.1
          -      ci-parallel-vars: 1.0.1
          -      cli-truncate: 4.0.0
          -      code-excerpt: 4.0.0
          -      common-path-prefix: 3.0.0
          -      concordance: 5.0.4
          -      currently-unhandled: 0.4.1
          -      debug: 4.4.3
          -      emittery: 1.2.0
          -      figures: 6.1.0
          -      globby: 14.1.0
          -      ignore-by-default: 2.1.0
          -      indent-string: 5.0.0
          -      is-plain-object: 5.0.0
          -      is-promise: 4.0.0
          -      matcher: 5.0.0
          -      memoize: 10.2.0
          -      ms: 2.1.3
          -      p-map: 7.0.4
          -      package-config: 5.0.0
          -      picomatch: 4.0.3
          -      plur: 5.1.0
          -      pretty-ms: 9.3.0
          -      resolve-cwd: 3.0.0
          -      stack-utils: 2.0.6
          -      strip-ansi: 7.1.2
          -      supertap: 3.0.1
          -      temp-dir: 3.0.0
          -      write-file-atomic: 6.0.0
          -      yargs: 17.7.2
          -    transitivePeerDependencies:
          -      - encoding
          -      - rollup
          -      - supports-color
          -
             axobject-query@4.1.0: {}
           
             bail@1.0.5: {}
          @@ -7831,16 +7420,10 @@ snapshots:
           
             before-after-hook@4.0.0: {}
           
          -  bindings@1.5.0:
          -    dependencies:
          -      file-uri-to-path: 1.0.0
          -
             birpc@2.9.0: {}
           
             bluebird@3.7.2: {}
           
          -  blueimp-md5@2.19.0: {}
          -
             boolbase@1.0.0: {}
           
             boundary@2.0.0: {}
          @@ -7901,8 +7484,6 @@ snapshots:
           
             callsites@3.1.0: {}
           
          -  callsites@4.2.0: {}
          -
             camelcase@8.0.0: {}
           
             canvas-confetti@1.9.4: {}
          @@ -7915,10 +7496,6 @@ snapshots:
               dependencies:
                 lodash: 4.17.21
           
          -  cbor@10.0.11:
          -    dependencies:
          -      nofilter: 3.1.0
          -
             ccount@1.1.0: {}
           
             ccount@2.0.1: {}
          @@ -7952,21 +7529,10 @@ snapshots:
               dependencies:
                 readdirp: 4.1.2
           
          -  chownr@3.0.0: {}
          -
          -  chunkd@2.0.1: {}
          -
             ci-info@4.3.1: {}
           
          -  ci-parallel-vars@1.0.1: {}
          -
             cli-boxes@3.0.0: {}
           
          -  cli-truncate@4.0.0:
          -    dependencies:
          -      slice-ansi: 5.0.0
          -      string-width: 7.2.0
          -
             cli-width@4.1.0: {}
           
             clipanion@4.0.0-rc.4(typanion@3.14.0):
          @@ -7983,10 +7549,6 @@ snapshots:
           
             clsx@2.1.1: {}
           
          -  code-excerpt@4.0.0:
          -    dependencies:
          -      convert-to-spaces: 2.0.1
          -
             collapse-white-space@2.1.0: {}
           
             color-convert@2.0.1:
          @@ -8003,25 +7565,10 @@ snapshots:
           
             common-ancestor-path@1.0.1: {}
           
          -  common-path-prefix@3.0.0: {}
          -
             concat-map@0.0.1: {}
           
          -  concordance@5.0.4:
          -    dependencies:
          -      date-time: 3.1.0
          -      esutils: 2.0.3
          -      fast-diff: 1.3.0
          -      js-string-escape: 1.0.1
          -      lodash: 4.17.21
          -      md5-hex: 3.0.1
          -      semver: 7.7.3
          -      well-known-symbols: 2.0.0
          -
             consola@3.4.2: {}
           
          -  convert-to-spaces@2.0.1: {}
          -
             cookie-es@1.2.2: {}
           
             cookie@1.1.1: {}
          @@ -8068,14 +7615,6 @@ snapshots:
           
             current-module-paths@1.1.3: {}
           
          -  currently-unhandled@0.4.1:
          -    dependencies:
          -      array-find-index: 1.0.2
          -
          -  date-time@3.1.0:
          -    dependencies:
          -      time-zone: 1.0.0
          -
             debug@4.4.3:
               dependencies:
                 ms: 2.1.3
          @@ -8158,8 +7697,6 @@ snapshots:
           
             eastasianwidth@0.2.0: {}
           
          -  emittery@1.2.0: {}
          -
             emmet@2.4.11:
               dependencies:
                 '@emmetio/abbreviation': 2.3.3
          @@ -8420,8 +7957,6 @@ snapshots:
           
             fast-deep-equal@3.1.3: {}
           
          -  fast-diff@1.3.0: {}
          -
             fast-equals@4.0.3: {}
           
             fast-glob@3.3.3:
          @@ -8450,10 +7985,6 @@ snapshots:
               optionalDependencies:
                 picomatch: 4.0.3
           
          -  figures@6.1.0:
          -    dependencies:
          -      is-unicode-supported: 2.1.0
          -
             file-entry-cache@10.1.4:
               dependencies:
                 flat-cache: 6.1.19
          @@ -8467,14 +7998,10 @@ snapshots:
                 array-back: 6.2.2
                 fast-glob: 3.3.3
           
          -  file-uri-to-path@1.0.0: {}
          -
             fill-range@7.1.1:
               dependencies:
                 to-regex-range: 5.0.1
           
          -  find-up-simple@1.0.1: {}
          -
             find-up@2.1.0:
               dependencies:
                 locate-path: 2.0.0
          @@ -8591,15 +8118,6 @@ snapshots:
           
             globals@16.5.0: {}
           
          -  globby@14.1.0:
          -    dependencies:
          -      '@sindresorhus/merge-streams': 2.3.0
          -      fast-glob: 3.3.3
          -      ignore: 7.0.5
          -      path-type: 6.0.0
          -      slash: 5.1.0
          -      unicorn-magic: 0.3.0
          -
             globby@16.0.0:
               dependencies:
                 '@sindresorhus/merge-streams': 4.0.0
          @@ -8879,13 +8397,6 @@ snapshots:
           
             http-cache-semantics@4.2.0: {}
           
          -  https-proxy-agent@7.0.6:
          -    dependencies:
          -      agent-base: 7.1.4
          -      debug: 4.4.3
          -    transitivePeerDependencies:
          -      - supports-color
          -
             i18next@23.16.8:
               dependencies:
                 '@babel/runtime': 7.28.6
          @@ -8894,8 +8405,6 @@ snapshots:
               dependencies:
                 safer-buffer: 2.1.2
           
          -  ignore-by-default@2.1.0: {}
          -
             ignore@5.3.2: {}
           
             ignore@7.0.5: {}
          @@ -8909,14 +8418,10 @@ snapshots:
           
             imurmurhash@0.1.4: {}
           
          -  indent-string@5.0.0: {}
          -
             inline-style-parser@0.2.7: {}
           
             iron-webcrypto@1.2.1: {}
           
          -  irregular-plurals@3.5.0: {}
          -
             is-alphabetical@1.0.4: {}
           
             is-alphabetical@2.0.1: {}
          @@ -8953,8 +8458,6 @@ snapshots:
           
             is-fullwidth-code-point@3.0.0: {}
           
          -  is-fullwidth-code-point@4.0.0: {}
          -
             is-glob@4.0.3:
               dependencies:
                 is-extglob: 2.1.1
          @@ -8975,12 +8478,6 @@ snapshots:
           
             is-plain-obj@4.1.0: {}
           
          -  is-plain-object@5.0.0: {}
          -
          -  is-promise@4.0.0: {}
          -
          -  is-unicode-supported@2.1.0: {}
          -
             is-utf8@0.2.1: {}
           
             is-wsl@3.1.0:
          @@ -9003,8 +8500,6 @@ snapshots:
           
             jiti@2.6.1: {}
           
          -  js-string-escape@1.0.1: {}
          -
             js-yaml@3.14.2:
               dependencies:
                 argparse: 1.0.10
          @@ -9108,8 +8603,6 @@ snapshots:
                 pify: 3.0.0
                 strip-bom: 3.0.0
           
          -  load-json-file@7.0.1: {}
          -
             locate-path@2.0.0:
               dependencies:
                 p-locate: 2.0.0
          @@ -9177,16 +8670,8 @@ snapshots:
               dependencies:
                 regexp.prototype.flags: 1.5.4
           
          -  matcher@5.0.0:
          -    dependencies:
          -      escape-string-regexp: 5.0.0
          -
             math-intrinsics@1.1.0: {}
           
          -  md5-hex@3.0.1:
          -    dependencies:
          -      blueimp-md5: 2.19.0
          -
             md5@2.3.0:
               dependencies:
                 charenc: 0.0.2
          @@ -9451,10 +8936,6 @@ snapshots:
           
             mdurl@2.0.0: {}
           
          -  memoize@10.2.0:
          -    dependencies:
          -      mimic-function: 5.0.1
          -
             merge2@1.4.1: {}
           
             micromark-core-commonmark@2.0.3:
          @@ -9790,8 +9271,6 @@ snapshots:
                 braces: 3.0.3
                 picomatch: 2.3.1
           
          -  mimic-function@5.0.1: {}
          -
             minimatch@10.1.1:
               dependencies:
                 '@isaacs/brace-expansion': 5.0.0
          @@ -9808,10 +9287,6 @@ snapshots:
           
             minipass@7.1.2: {}
           
          -  minizlib@3.1.0:
          -    dependencies:
          -      minipass: 7.1.2
          -
             mkdirp@0.5.6:
               dependencies:
                 minimist: 1.2.8
          @@ -9838,20 +9313,8 @@ snapshots:
           
             node-fetch-native@1.6.7: {}
           
          -  node-fetch@2.7.0:
          -    dependencies:
          -      whatwg-url: 5.0.0
          -
          -  node-gyp-build@4.8.4: {}
          -
             node-mock-http@1.0.4: {}
           
          -  nofilter@3.1.0: {}
          -
          -  nopt@8.1.0:
          -    dependencies:
          -      abbrev: 3.0.1
          -
             normalize-package-data@2.5.0:
               dependencies:
                 hosted-git-info: 2.8.9
          @@ -9922,8 +9385,6 @@ snapshots:
           
             p-map@6.0.0: {}
           
          -  p-map@7.0.4: {}
          -
             p-queue@8.1.1:
               dependencies:
                 eventemitter3: 5.0.1
          @@ -9933,11 +9394,6 @@ snapshots:
           
             p-try@1.0.0: {}
           
          -  package-config@5.0.0:
          -    dependencies:
          -      find-up-simple: 1.0.1
          -      load-json-file: 7.0.1
          -
             package-json-from-dist@1.0.1: {}
           
             package-manager-detector@1.6.0: {}
          @@ -9994,8 +9450,6 @@ snapshots:
                 unist-util-visit-children: 3.0.0
                 vfile: 6.0.3
           
          -  parse-ms@4.0.0: {}
          -
             parse5@7.3.0:
               dependencies:
                 entities: 6.0.1
          @@ -10034,8 +9488,6 @@ snapshots:
               dependencies:
                 pify: 3.0.0
           
          -  path-type@6.0.0: {}
          -
             pathe@2.0.3: {}
           
             piccolore@0.1.3: {}
          @@ -10068,10 +9520,6 @@ snapshots:
               optionalDependencies:
                 fsevents: 2.3.2
           
          -  plur@5.1.0:
          -    dependencies:
          -      irregular-plurals: 3.5.0
          -
             pluralize@2.0.0: {}
           
             pngjs@6.0.0: {}
          @@ -10111,10 +9559,6 @@ snapshots:
           
             prettier@3.7.4: {}
           
          -  pretty-ms@9.3.0:
          -    dependencies:
          -      parse-ms: 4.0.0
          -
             prismjs@1.30.0: {}
           
             prompts@2.4.2:
          @@ -10394,14 +9838,8 @@ snapshots:
               dependencies:
                 lodash: 4.17.21
           
          -  resolve-cwd@3.0.0:
          -    dependencies:
          -      resolve-from: 5.0.0
          -
             resolve-from@4.0.0: {}
           
          -  resolve-from@5.0.0: {}
          -
             resolve-pkg-maps@1.0.0: {}
           
             resolve@1.22.11:
          @@ -10529,10 +9967,6 @@ snapshots:
           
             semver@7.7.3: {}
           
          -  serialize-error@7.0.1:
          -    dependencies:
          -      type-fest: 0.13.1
          -
             set-function-length@1.2.2:
               dependencies:
                 define-data-property: 1.1.4
          @@ -10624,11 +10058,6 @@ snapshots:
                 astral-regex: 2.0.0
                 is-fullwidth-code-point: 3.0.0
           
          -  slice-ansi@5.0.0:
          -    dependencies:
          -      ansi-styles: 6.2.3
          -      is-fullwidth-code-point: 4.0.0
          -
             smol-toml@1.5.2: {}
           
             source-map-js@1.2.1: {}
          @@ -10653,10 +10082,6 @@ snapshots:
           
             sprintf-js@1.0.3: {}
           
          -  stack-utils@2.0.6:
          -    dependencies:
          -      escape-string-regexp: 2.0.0
          -
             starlight-llms-txt@0.6.1(@astrojs/starlight@0.37.3(astro@5.16.6(@types/node@22.19.7)(jiti@2.6.1)(rollup@4.54.0)(typescript@5.6.2)(yaml@2.8.2)))(astro@5.16.6(@types/node@22.19.7)(jiti@2.6.1)(rollup@4.54.0)(typescript@5.6.2)(yaml@2.8.2)):
               dependencies:
                 '@astrojs/mdx': 4.3.13(astro@5.16.6(@types/node@22.19.7)(jiti@2.6.1)(rollup@4.54.0)(typescript@5.6.2)(yaml@2.8.2))
          @@ -10735,13 +10160,6 @@ snapshots:
               dependencies:
                 s.color: 0.0.15
           
          -  supertap@3.0.1:
          -    dependencies:
          -      indent-string: 5.0.0
          -      js-yaml: 3.14.2
          -      serialize-error: 7.0.1
          -      strip-ansi: 7.1.2
          -
             supports-color@7.2.0:
               dependencies:
                 has-flag: 4.0.0
          @@ -10770,16 +10188,6 @@ snapshots:
                 string-width: 4.2.3
                 strip-ansi: 6.0.1
           
          -  tar@7.5.2:
          -    dependencies:
          -      '@isaacs/fs-minipass': 4.0.1
          -      chownr: 3.0.0
          -      minipass: 7.1.2
          -      minizlib: 3.1.0
          -      yallist: 5.0.0
          -
          -  temp-dir@3.0.0: {}
          -
             text-table@0.2.0: {}
           
             textlint-plugin-mdx@1.0.2(typescript@5.6.2):
          @@ -10874,8 +10282,6 @@ snapshots:
               transitivePeerDependencies:
                 - supports-color
           
          -  time-zone@1.0.0: {}
          -
             tiny-inflate@1.0.3: {}
           
             tinyexec@1.0.2: {}
          @@ -10889,8 +10295,6 @@ snapshots:
               dependencies:
                 is-number: 7.0.0
           
          -  tr46@0.0.3: {}
          -
             tree-kill@1.2.2: {}
           
             trim-lines@3.0.1: {}
          @@ -10948,8 +10352,6 @@ snapshots:
               dependencies:
                 prelude-ls: 1.2.1
           
          -  type-fest@0.13.1: {}
          -
             type-fest@4.41.0: {}
           
             typesafe-path@0.2.2: {}
          @@ -11017,8 +10419,6 @@ snapshots:
                 pako: 0.2.9
                 tiny-inflate: 1.0.3
           
          -  unicorn-magic@0.3.0: {}
          -
             unicorn-magic@0.4.0: {}
           
             unified@11.0.5:
          @@ -11338,15 +10738,6 @@ snapshots:
           
             web-namespaces@2.0.1: {}
           
          -  webidl-conversions@3.0.1: {}
          -
          -  well-known-symbols@2.0.0: {}
          -
          -  whatwg-url@5.0.0:
          -    dependencies:
          -      tr46: 0.0.3
          -      webidl-conversions: 3.0.1
          -
             which-pm-runs@1.1.0: {}
           
             which@2.0.2:
          @@ -11377,19 +10768,12 @@ snapshots:
                 string-width: 7.2.0
                 strip-ansi: 7.1.2
           
          -  write-file-atomic@6.0.0:
          -    dependencies:
          -      imurmurhash: 0.1.4
          -      signal-exit: 4.1.0
          -
             xmlcreate@2.0.4: {}
           
             xxhash-wasm@1.1.0: {}
           
             y18n@5.0.8: {}
           
          -  yallist@5.0.0: {}
          -
             yaml-language-server@1.19.2:
               dependencies:
                 '@vscode/l10n': 0.0.18