From 7a75252b9e7bc4e404285ebc039a5c20f3b1bc73 Mon Sep 17 00:00:00 2001 From: David Pine <7679720+IEvangelist@users.noreply.github.com> Date: Sun, 11 Oct 2026 09:02:36 -0500 Subject: [PATCH 01/28] Add opt-in hybrid API documentation POC Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .github/workflows/ci.yml | 13 +- .github/workflows/frontend-build.yml | 27 +- .github/workflows/hybrid-api-docs-poc.yml | 88 +++++++ .gitignore | 3 + CONTRIBUTING.md | 57 +++++ src/apphost/Aspire.Dev.AppHost/AppHost.cs | 13 +- .../HybridApiDocsExtensions.cs | 33 +++ src/frontend/astro.config.mjs | 11 +- src/frontend/config/hybrid-api-docs.mjs | 101 ++++++++ src/frontend/eslint.config.mjs | 1 + src/frontend/frontend.esproj | 2 + src/frontend/package.json | 4 + src/frontend/playwright.hybrid.config.mjs | 8 + src/frontend/pnpm-lock.yaml | 141 ++++++++++- src/frontend/scripts/build-hybrid.mjs | 9 + src/frontend/scripts/serve-api-docs.mjs | 57 +++++ src/frontend/scripts/test-hybrid-host.mjs | 112 +++++++++ src/frontend/scripts/verify-hybrid-output.mjs | 46 ++++ .../reference/api/csharp/[package].md.ts | 6 +- .../api/csharp/[package]/[type].md.ts | 6 +- .../[package]/[type]/[memberKind].astro | 5 +- .../[package]/[type]/[memberKind].md.ts | 6 +- .../api/csharp/[package]/[type]/index.astro | 5 +- .../api/csharp/[package]/index.astro | 5 +- .../reference/api/typescript/[module].md.ts | 6 +- .../api/typescript/[module]/[item].md.ts | 6 +- .../typescript/[module]/[item]/[member].md.ts | 6 +- .../[module]/[item]/[member]/index.astro | 5 +- .../typescript/[module]/[item]/index.astro | 5 +- .../api/typescript/[module]/index.astro | 5 +- src/frontend/src/utils/api-route-catalog.ts | 106 ++++++++ src/frontend/src/utils/api-route-data.ts | 28 +++ .../src/utils/csharp-route-identity.ts | 25 ++ src/frontend/src/utils/packages.ts | 42 +--- .../tests/e2e/hybrid-api-docs.spec.ts | 25 ++ .../tests/unit/api-markdown.vitest.test.ts | 14 ++ .../unit/build-performance.vitest.test.ts | 2 +- .../tests/unit/hybrid-api-docs.vitest.test.ts | 119 +++++++++ src/frontend/tsconfig.json | 2 +- .../AgentReadiness/LinkHeaderMiddleware.cs | 6 +- .../MarkdownNegotiationMiddleware.cs | 5 + .../HybridApiDocs/HybridApiDocsArtifact.cs | 105 ++++++++ .../HybridApiDocs/HybridApiDocsExtensions.cs | 45 ++++ .../HybridApiDocs/HybridApiDocsRenderer.cs | 97 ++++++++ .../HybridApiDocsRoutingMiddleware.cs | 59 +++++ src/statichost/StaticHost/Program.cs | 18 +- src/statichost/StaticHost/StaticHost.csproj | 1 + .../HybridApiDocsConfigurationTests.cs | 15 ++ tests/StaticHost.Tests/HybridApiDocsTests.cs | 235 ++++++++++++++++++ 49 files changed, 1666 insertions(+), 75 deletions(-) create mode 100644 .github/workflows/hybrid-api-docs-poc.yml create mode 100644 src/apphost/Aspire.Dev.AppHost/HybridApiDocsExtensions.cs create mode 100644 src/frontend/config/hybrid-api-docs.mjs create mode 100644 src/frontend/playwright.hybrid.config.mjs create mode 100644 src/frontend/scripts/build-hybrid.mjs create mode 100644 src/frontend/scripts/serve-api-docs.mjs create mode 100644 src/frontend/scripts/test-hybrid-host.mjs create mode 100644 src/frontend/scripts/verify-hybrid-output.mjs create mode 100644 src/frontend/src/utils/api-route-catalog.ts create mode 100644 src/frontend/src/utils/api-route-data.ts create mode 100644 src/frontend/src/utils/csharp-route-identity.ts create mode 100644 src/frontend/tests/e2e/hybrid-api-docs.spec.ts create mode 100644 src/frontend/tests/unit/hybrid-api-docs.vitest.test.ts create mode 100644 src/statichost/StaticHost/HybridApiDocs/HybridApiDocsArtifact.cs create mode 100644 src/statichost/StaticHost/HybridApiDocs/HybridApiDocsExtensions.cs create mode 100644 src/statichost/StaticHost/HybridApiDocs/HybridApiDocsRenderer.cs create mode 100644 src/statichost/StaticHost/HybridApiDocs/HybridApiDocsRoutingMiddleware.cs create mode 100644 tests/Aspire.Dev.AppHost.Tests/HybridApiDocsConfigurationTests.cs create mode 100644 tests/StaticHost.Tests/HybridApiDocsTests.cs diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 615e43ca96..20554d7878 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -103,6 +103,11 @@ jobs: if: ${{ needs.changes.outputs.apphost == 'true' }} uses: ./.github/workflows/apphost-build.yml + hybrid-api-poc: + needs: changes + if: ${{ github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'hybrid-api-poc') }} + uses: ./.github/workflows/hybrid-api-docs-poc.yml + release-sync-tests: runs-on: ubuntu-latest steps: @@ -115,7 +120,7 @@ jobs: bash .github/scripts/test-merge-main-into-release.sh ci-gate: - needs: [changes, frontend-build, apphost-build, release-sync-tests] + needs: [changes, frontend-build, apphost-build, release-sync-tests, hybrid-api-poc] if: ${{ always() && !cancelled() }} runs-on: ubuntu-latest steps: @@ -128,6 +133,8 @@ jobs: FRONTEND_RESULT: ${{ needs['frontend-build'].result }} APPHOST_RESULT: ${{ needs['apphost-build'].result }} RELEASE_SYNC_RESULT: ${{ needs['release-sync-tests'].result }} + HYBRID_REQUESTED: ${{ github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'hybrid-api-poc') }} + HYBRID_RESULT: ${{ needs['hybrid-api-poc'].result }} run: | echo "changes result: $CHANGES_RESULT" echo "frontend changed: $FRONTEND_CHANGED" @@ -135,6 +142,10 @@ jobs: echo "apphost changed: $APPHOST_CHANGED" echo "apphost-build result: $APPHOST_RESULT" echo "release-sync-tests result: $RELEASE_SYNC_RESULT" + if [[ "$HYBRID_REQUESTED" == "true" && "$HYBRID_RESULT" != "success" ]]; then + echo "The opted-in hybrid API POC checks must succeed." + exit 1 + fi if [[ "$RELEASE_SYNC_RESULT" != "success" ]]; then echo "The release sync tests must succeed." diff --git a/.github/workflows/frontend-build.yml b/.github/workflows/frontend-build.yml index 2abb8ad48b..f2646cce87 100644 --- a/.github/workflows/frontend-build.yml +++ b/.github/workflows/frontend-build.yml @@ -1,6 +1,16 @@ name: Frontend Build on: + workflow_dispatch: + inputs: + node_version: + description: Node.js version + default: "24.x" + type: string + hybrid_api_poc: + description: Also verify the opt-in hybrid API documentation POC + default: false + type: boolean workflow_call: inputs: node_version: @@ -18,6 +28,11 @@ on: required: false default: false type: boolean + hybrid_api_poc: + description: Also verify the opt-in hybrid API documentation POC + required: false + default: false + type: boolean secrets: ASPIRE_BOT_APP_ID: required: false @@ -28,6 +43,10 @@ permissions: contents: read jobs: + hybrid-api-poc: + if: ${{ inputs.hybrid_api_poc }} + uses: ./.github/workflows/hybrid-api-docs-poc.yml + build: name: Frontend Build runs-on: ubuntu-latest @@ -422,7 +441,7 @@ jobs: frontend-gate: name: Frontend gate if: ${{ always() }} - needs: [build, validation, e2e, report] + needs: [build, validation, e2e, report, hybrid-api-poc] runs-on: ubuntu-latest steps: - name: Require all frontend checks @@ -431,7 +450,13 @@ jobs: VALIDATION: ${{ needs.validation.result }} E2E: ${{ needs.e2e.result }} REPORT: ${{ needs.report.result }} + HYBRID_REQUESTED: ${{ inputs.hybrid_api_poc }} + HYBRID_RESULT: ${{ needs['hybrid-api-poc'].result }} run: | + if [[ "$HYBRID_REQUESTED" == "true" && "$HYBRID_RESULT" != "success" ]]; then + echo "::error::The opted-in hybrid POC must succeed." + exit 1 + fi for result in "$BUILD" "$VALIDATION" "$E2E" "$REPORT"; do if [[ "$result" != "success" ]]; then echo "::error::Every frontend job must succeed (build=$BUILD validation=$VALIDATION e2e=$E2E report=$REPORT)." diff --git a/.github/workflows/hybrid-api-docs-poc.yml b/.github/workflows/hybrid-api-docs-poc.yml new file mode 100644 index 0000000000..e6eec574ce --- /dev/null +++ b/.github/workflows/hybrid-api-docs-poc.yml @@ -0,0 +1,88 @@ +name: Hybrid API docs POC + +on: + workflow_call: + workflow_dispatch: + +permissions: + contents: read + +jobs: + verify: + runs-on: ubuntu-latest + services: + redis: + image: redis:8.2-alpine + ports: + - 6379:6379 + options: >- + --health-cmd "redis-cli ping" + --health-interval 5s + --health-timeout 3s + --health-retries 10 + defaults: + run: + working-directory: src/frontend + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + fetch-depth: 0 + persist-credentials: false + - uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6.0.10 + - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 + with: + node-version: 24.x + cache: pnpm + cache-dependency-path: src/frontend/pnpm-lock.yaml + - uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0 + with: + global-json-file: global.json + - name: Install dependencies + run: pnpm install --frozen-lockfile --prefer-offline + - name: Build static baseline + env: + ASTRO_TELEMETRY_DISABLED: '1' + NODE_OPTIONS: --max-old-space-size=8192 + BUILD_TIMING: '1' + BUILD_TIMING_OUT: ${{ runner.temp }}/hybrid-poc/static-timing.jsonl + run: | + mkdir -p "$RUNNER_TEMP/hybrid-poc" + /usr/bin/time -v -o "$RUNNER_TEMP/hybrid-poc/static-resources.txt" pnpm build:production + - name: Build opted-in hybrid artifact + env: + ASTRO_TELEMETRY_DISABLED: '1' + NODE_OPTIONS: --max-old-space-size=8192 + ASPIRE_HYBRID_API_DOCS: '1' + BUILD_TIMING: '1' + BUILD_TIMING_OUT: ${{ runner.temp }}/hybrid-poc/hybrid-timing.jsonl + run: /usr/bin/time -v -o "$RUNNER_TEMP/hybrid-poc/hybrid-resources.txt" pnpm build:production + - name: Verify output and non-API parity + run: node scripts/verify-hybrid-output.mjs + - name: Build existing StaticHost with hybrid client assets + env: + ASPIRE_HYBRID_API_DOCS: '1' + run: dotnet build ../statichost/StaticHost/StaticHost.csproj -c Release --nologo + - name: Verify rendering, caching and worker outages + env: + ConnectionStrings__cache: localhost:6379,abortConnect=false + HYBRID_TEST_BROWSER: '1' + run: node scripts/test-hybrid-host.mjs + - name: Upload private POC artifact + if: always() + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: hybrid-api-docs-poc + path: src/frontend/dist-hybrid + if-no-files-found: warn + retention-days: 7 + - name: Upload POC measurements + if: always() + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: hybrid-api-docs-results + path: | + src/frontend/hybrid-output-results.json + src/frontend/hybrid-host-results.json + ${{ runner.temp }}/hybrid-poc + if-no-files-found: warn + retention-days: 7 diff --git a/.gitignore b/.gitignore index 370280c0c3..7783a04eac 100644 --- a/.gitignore +++ b/.gitignore @@ -14,6 +14,9 @@ # build output dist/ +dist-hybrid/ +hybrid-output-results.json +hybrid-host-results.json playwright-report/ blob-report/ test-results/ diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index dcc1ba8175..60c582204f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -26,6 +26,63 @@ We welcome translation contributions! Please see our [Translation guide](https:/ └───📂 public # Static assets served as-is ``` +## Hybrid API documentation POC + +The normal build remains fully static. Opting in with `ASPIRE_HYBRID_API_DOCS=1` +at **build time** leaves non-API documentation and assets static, but renders all +C# and TypeScript API HTML and Markdown on demand through the existing StaticHost. +This includes both API search pages. The convenience command `build:hybrid` sets +the flag only for its child build; `build:hybrid:skip-search` also skips Pagefind. +Setting a runtime flag alone cannot convert an already-static artifact. + +Run full-site comparisons in CI, not on your development machine. From the +**Frontend Build** workflow, select the POC option, or use: + +```powershell +gh workflow run frontend-build.yml --repo microsoft/aspire.dev --ref YOUR_BRANCH -f hybrid_api_poc=true +``` + +A PR carrying the `hybrid-api-poc` label also runs the POC checks when CI is +triggered by opening, reopening, or pushing to the PR. The comparison builds both +modes from the same commit and reports output counts, build resource usage, and +cold/warm rendering measurements in `hybrid-api-docs-results`. + +Download the completed `hybrid-api-docs-poc` artifact into the frontend directory: + +```powershell +gh run download RUN_ID --repo microsoft/aspire.dev --name hybrid-api-docs-poc --dir .\src\frontend\dist-hybrid +$env:ASPIRE_HYBRID_API_DOCS = '1' +aspire start --non-interactive +``` + +Restore frontend dependencies with the repository's existing pnpm setup first. +The downloaded directory contains `client`, `server`, and `hybrid-api-docs.json`. +The manifest and server stay outside the public static root. Browse the +StaticHost endpoint in the Aspire dashboard; the Node worker is internal. +Missing or incompatible artifacts cause an actionable startup error instead of +starting a development server or rebuilding the site. + +The API response cache is process-local, bounded to 128 MiB, and expires entries +after 30 minutes. Individual renderer responses are limited to 64 MiB and use +bounded buffering with an exact content length. Successful responses are keyed +by build identity, request URL, and representation. Negotiated Markdown uses a +separate variant so its private headers cannot contaminate direct Markdown or +HTML responses. Failed, interrupted, authenticated, private, or cookie-setting +responses are not cached. + +Restart StaticHost to clear the cache; rebuild/download and restart the host and +worker together to change builds. A worker outage does not prevent static pages +or warmed API responses from being served, but a cold API request returns a +gateway error. Existing Redis usage for live status is unchanged; API output +caching does not use Redis. Azure hybrid publishing is intentionally rejected +for this local POC, and the production deployment path remains static. + +Unset the flag to return to the ordinary Vite/local workflow: + +```powershell +Remove-Item Env:ASPIRE_HYBRID_API_DOCS +``` + ## Environment badge Set `PUBLIC_ENVIRONMENT_BADGE` to display a small text badge beside the header logo diff --git a/src/apphost/Aspire.Dev.AppHost/AppHost.cs b/src/apphost/Aspire.Dev.AppHost/AppHost.cs index 62ff26e743..719948cc8f 100644 --- a/src/apphost/Aspire.Dev.AppHost/AppHost.cs +++ b/src/apphost/Aspire.Dev.AppHost/AppHost.cs @@ -1,4 +1,8 @@ var builder = DistributedApplication.CreateBuilder(args); +var hybridApiDocs = HybridApiDocsExtensions.IsHybridApiDocsEnabled( + builder.Configuration["ASPIRE_HYBRID_API_DOCS"]); +if (hybridApiDocs && !builder.ExecutionContext.IsRunMode) + throw new InvalidOperationException("Hybrid API documentation is a local POC; Azure publishing requires the normal static build."); // For deployment: We want to pick AppService as the environment to publish to. builder.AddAzureAppServiceEnvironment("production") @@ -25,11 +29,18 @@ // The live-status client calls same-origin /api/live[/stream]; inject StaticHost's // origin so the Vite dev server can proxy those to the API (see astro.config.mjs). // Without this, /api/live 404s against the Vite origin under `aspire run`. - builder.AddViteApp("frontend", "../../frontend") + if (hybridApiDocs) + { + staticHostWebsite.WithHybridApiDocs(builder, Path.GetFullPath("../../frontend", builder.AppHostDirectory)); + } + else + { + builder.AddViteApp("frontend", "../../frontend") .WithPnpm() .WithEnvironment("ASPIRE_STATICHOST_URL", staticHostWebsite.GetEndpoint("https")) .WithUrlForEndpoint("http", static url => url.DisplayText = "aspire.dev (Local)") .WithExternalHttpEndpoints(); + } } else { diff --git a/src/apphost/Aspire.Dev.AppHost/HybridApiDocsExtensions.cs b/src/apphost/Aspire.Dev.AppHost/HybridApiDocsExtensions.cs new file mode 100644 index 0000000000..eed99d4cc1 --- /dev/null +++ b/src/apphost/Aspire.Dev.AppHost/HybridApiDocsExtensions.cs @@ -0,0 +1,33 @@ +using System.Text.Json; +using Aspire.Hosting; +using Aspire.Hosting.ApplicationModel; + +internal static class HybridApiDocsExtensions +{ + public static bool IsHybridApiDocsEnabled(string? value) => value switch + { + null or "0" => false, + "1" => true, + _ => throw new InvalidOperationException("ASPIRE_HYBRID_API_DOCS must be unset, 0, or 1."), + }; + + public static void WithHybridApiDocs(this IResourceBuilder website, + IDistributedApplicationBuilder builder, string frontendDirectory) + { + var manifest = Path.GetFullPath(Path.Combine(frontendDirectory, "dist-hybrid", "hybrid-api-docs.json")); + if (!File.Exists(manifest)) + throw new InvalidOperationException($"Download the opted-in hybrid CI artifact before starting: {manifest}"); + using var json = JsonDocument.Parse(File.ReadAllText(manifest)); + if (json.RootElement.GetProperty("mode").GetString() != "hybrid-api-docs") + throw new InvalidOperationException("The selected artifact is not a hybrid API documentation build."); + + var worker = builder.AddNodeApp("api-docs", frontendDirectory, "scripts/serve-api-docs.mjs") + .WithPnpm() + .WithHttpEndpoint(env: "PORT") + .WithEnvironment("HOST", "127.0.0.1") + .WithEnvironment("HYBRID_API_DOCS_MANIFEST", manifest) + .WithHttpHealthCheck("/__hybrid-api-docs/health"); + website.WithEnvironment("HybridApiDocs__ArtifactPath", manifest) + .WithEnvironment("HybridApiDocs__RendererUrl", worker.GetEndpoint("http")); + } +} diff --git a/src/frontend/astro.config.mjs b/src/frontend/astro.config.mjs index 87f40a0aeb..35d1c9fe24 100644 --- a/src/frontend/astro.config.mjs +++ b/src/frontend/astro.config.mjs @@ -25,7 +25,10 @@ import buildTiming from './config/build-timing.mjs'; import { contributorCacheIntegration } from './src/utils/contributors.ts'; import UnoCSS from 'unocss/astro'; import Icons from 'starlight-plugin-icons'; +import node from '@astrojs/node'; +import { isHybridApiDocs, hybridOutputDirectory, hybridApiDocsIntegration } from './config/hybrid-api-docs.mjs'; +const hybridApiDocs = isHybridApiDocs(); const modeArgIndex = process.argv.indexOf('--mode'); const isSkipSearchBuild = modeArgIndex >= 0 && process.argv[modeArgIndex + 1] === 'skip-search'; const outDir = process.env.ASTRO_OUT_DIR; @@ -55,8 +58,10 @@ const buildConcurrency = Number(process.env.ASPIRE_BUILD_CONCURRENCY) || 4; // https://astro.build/config export default defineConfig({ - cacheDir: './node_modules/.astro', - ...(outDir ? { outDir } : {}), + cacheDir: hybridApiDocs ? './node_modules/.astro-hybrid' : './node_modules/.astro', + ...(hybridApiDocs + ? { outDir: hybridOutputDirectory(process.cwd(), outDir), adapter: node({ mode: 'middleware' }), session: false } + : outDir ? { outDir } : {}), vite: { define: { // Resolve filesystem-backed redirects before prerender modules are bundled. @@ -80,6 +85,7 @@ export default defineConfig({ prefetch: true, site: 'https://aspire.dev', trailingSlash: 'always', + ...(hybridApiDocs ? { security: { allowedDomains: [{ hostname: 'aspire.dev', protocol: 'https' }] } } : {}), markdown: { processor: unified({ remarkPlugins: [remarkTypeScriptFirstAppHostTabs, remarkAspireVersionPlaceholders, remarkMermaid], @@ -236,6 +242,7 @@ export default defineConfig({ }), ...(isBuildTimingEnabled ? [buildTiming()] : []), aspireVersionPlaceholdersIntegration(), + ...(hybridApiDocs ? [hybridApiDocsIntegration(redirects)] : []), ], build: { concurrency: buildConcurrency, diff --git a/src/frontend/config/hybrid-api-docs.mjs b/src/frontend/config/hybrid-api-docs.mjs new file mode 100644 index 0000000000..583fd8ff57 --- /dev/null +++ b/src/frontend/config/hybrid-api-docs.mjs @@ -0,0 +1,101 @@ +// @ts-check +import { createHash } from 'node:crypto'; +import { cp, readFile, readdir, writeFile } from 'node:fs/promises'; +import { resolve } from 'node:path'; +import { fileURLToPath } from 'node:url'; +import { buildApiRouteCatalog } from '../src/utils/api-route-catalog.ts'; + +export function isHybridApiDocs(value = process.env.ASPIRE_HYBRID_API_DOCS) { + if (value === undefined || value === '0') return false; + if (value === '1') return true; + throw new Error('ASPIRE_HYBRID_API_DOCS must be unset, 0, or 1.'); +} + +/** @param {string} component */ +export function isApiRouteComponent(component) { + return /(?:^|\/)src\/pages\/reference\/api\//.test(component.replace(/\\/g, '/')); +} + +/** @param {string} root @param {string | undefined} requested */ +export function hybridOutputDirectory(root, requested) { + const directory = resolve(root, requested || 'dist-hybrid'); + const expected = resolve(root, 'dist-hybrid'); + const matches = process.platform === 'win32' + ? directory.toLowerCase() === expected.toLowerCase() : directory === expected; + if (!matches) { + throw new Error('Hybrid output must use dist-hybrid, outside the normal dist/, public/ and wwwroot/ roots.'); + } + return directory; +} + +/** @template T @param {string} directory @returns {Promise} */ +async function readDocuments(directory) { + const files = (await readdir(directory)).filter((name) => name.endsWith('.json')).sort(); + return Promise.all(files.map(async (name) => JSON.parse(await readFile(resolve(directory, name), 'utf8')))); +} + +/** @param {string} directory @param {import('node:crypto').Hash} hash */ +async function hashDirectory(directory, hash, prefix = '') { + const entries = (await readdir(directory, { withFileTypes: true })).sort((a, b) => a.name.localeCompare(b.name)); + for (const entry of entries) { + const path = resolve(directory, entry.name); + const name = `${prefix}${entry.name}`; + if (entry.isDirectory()) await hashDirectory(path, hash, `${name}/`); + else if (entry.isFile()) hash.update(name).update(await readFile(path)); + } +} + +/** + * @param {Record} redirects + * @returns {import('astro').AstroIntegration} + */ +export function hybridApiDocsIntegration(redirects) { + let root = ''; + let out = ''; + let site = ''; + return { + name: 'aspire-hybrid-api-docs', + hooks: { + 'astro:route:setup': ({ route }) => { + if (isApiRouteComponent(route.component)) route.prerender = false; + }, + 'astro:config:done': ({ config }) => { + root = fileURLToPath(config.root); + out = fileURLToPath(config.outDir); + if (!config.site) throw new Error('Hybrid API documentation requires a configured site URL.'); + site = config.site.replace(/\/$/, ''); + }, + 'astro:build:done': async () => { + /** @type {[import('../src/utils/packages').PackageApiDocument[], import('../src/utils/ts-modules').TsApiDocument[]]} */ + const [packages, modules] = await Promise.all([ + readDocuments(resolve(root, 'src/data/pkgs')), + readDocuments(resolve(root, 'src/data/ts-modules')), + ]); + const routes = buildApiRouteCatalog(packages, modules); + const redirectEntries = Object.entries(redirects).map(([path, value]) => ({ + path, destination: typeof value === 'string' ? value : value.destination, + status: typeof value === 'string' ? 301 : value.status, + })); + await cp(resolve(root, '../statichost/StaticHost/wwwroot/scalar'), + resolve(out, 'client/scalar'), { recursive: true }); + const hash = createHash('sha256'); + hash.update(JSON.stringify({ routes, redirects: redirectEntries, site })); + await hashDirectory(resolve(out, 'client'), hash, 'client/'); + await hashDirectory(resolve(out, 'server'), hash, 'server/'); + const manifest = { + schemaVersion: 1, mode: 'hybrid-api-docs', buildId: hash.digest('hex'), + client: 'client', server: 'server/entry.mjs', site, + routes, redirects: redirectEntries, + }; + await writeFile(resolve(out, 'hybrid-api-docs.json'), JSON.stringify(manifest)); + const urls = routes.filter(({ html }) => html).map(({ html }) => `${site}${html}`).join(''); + await writeFile(resolve(out, 'client/sitemap-api.xml'), + `${urls}`); + const sitemap = resolve(out, 'client/sitemap-index.xml'); + const content = await readFile(sitemap, 'utf8'); + await writeFile(sitemap, content.replace('', + `${site}/sitemap-api.xml`)); + }, + }, + }; +} diff --git a/src/frontend/eslint.config.mjs b/src/frontend/eslint.config.mjs index 1034ca018c..fdbaf9d140 100644 --- a/src/frontend/eslint.config.mjs +++ b/src/frontend/eslint.config.mjs @@ -16,6 +16,7 @@ export default [ '**/*.test-d.ts', '**/examples/', '**/dist/', + '**/dist-hybrid/', '**/build/', '**/examples/', ], diff --git a/src/frontend/frontend.esproj b/src/frontend/frontend.esproj index c72d5c4501..44d8d33277 100644 --- a/src/frontend/frontend.esproj +++ b/src/frontend/frontend.esproj @@ -1,10 +1,12 @@  $(MSBuildProjectDirectory)/dist + $(MSBuildProjectDirectory)/dist-hybrid/client pnpm run build false false $(MSBuildProjectDirectory)/obj/$(Configuration) + $(MSBuildProjectDirectory)/obj/$(Configuration)/hybrid \ No newline at end of file diff --git a/src/frontend/package.json b/src/frontend/package.json index 4dec81b28f..b368aeec55 100644 --- a/src/frontend/package.json +++ b/src/frontend/package.json @@ -26,6 +26,9 @@ "build": "pnpm git-env && pnpm compute-skill-digests && astro build", "build:skip-search": "pnpm git-env && pnpm compute-skill-digests && astro build --mode skip-search", "build:production": "pnpm git-env && pnpm compute-skill-digests && astro build --mode production", + "build:hybrid": "node ./scripts/build-hybrid.mjs", + "build:hybrid:skip-search": "node ./scripts/build-hybrid.mjs --skip-search", + "serve:hybrid": "node ./scripts/serve-api-docs.mjs", "build:statichost": "node ./scripts/build-static-host.mjs", "build:statichost:skip-search": "node ./scripts/build-static-host.mjs --skip-search", "preview": "astro preview", @@ -68,6 +71,7 @@ "@astro-community/astro-embed-youtube": "^0.5.10", "@astrojs/markdown-remark": "7.2.1", "@astrojs/mdx": "^7.0.3", + "@astrojs/node": "11.1.6", "@astrojs/rss": "^4.0.19", "@astrojs/starlight": "^0.41.3", "@catppuccin/starlight": "^2.1.0", diff --git a/src/frontend/playwright.hybrid.config.mjs b/src/frontend/playwright.hybrid.config.mjs new file mode 100644 index 0000000000..c505341d10 --- /dev/null +++ b/src/frontend/playwright.hybrid.config.mjs @@ -0,0 +1,8 @@ +import { defineConfig } from '@playwright/test'; + +export default defineConfig({ + testDir: './tests/e2e', + testMatch: 'hybrid-api-docs.spec.ts', + workers: 1, + use: { baseURL: process.env.HYBRID_TEST_URL || 'http://127.0.0.1:14324' }, +}); diff --git a/src/frontend/pnpm-lock.yaml b/src/frontend/pnpm-lock.yaml index 4d04ec824a..f89fc9b7a6 100644 --- a/src/frontend/pnpm-lock.yaml +++ b/src/frontend/pnpm-lock.yaml @@ -62,6 +62,9 @@ importers: '@astrojs/mdx': specifier: ^7.0.3 version: 7.0.3(@astrojs/markdown-satteri@0.3.4)(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.3)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0)) + '@astrojs/node': + specifier: 11.1.6 + version: 11.1.6(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.3)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0)) '@astrojs/rss': specifier: ^4.0.19 version: 4.0.19 @@ -383,6 +386,11 @@ packages: '@astrojs/markdown-satteri': optional: true + '@astrojs/node@11.1.6': + resolution: {integrity: sha512-jNZ10/vAT+HuXkX0E/tITsIYCSn3BmAvsooVAN1OjagG+FEzelpUWToy1bA3x6Irmu0VaknWRfReY+1twd35sQ==} + peerDependencies: + astro: ^7.2.1 + '@astrojs/prism@4.0.2': resolution: {integrity: sha512-KTivpmnz6lDsC6o9H4+DNm2SrE/GHzw8cNAvEJwAvUT+eoaEnn/4NtbDNfRRaxaJHdp15gf+tfHAWiXR4wB3BA==} engines: {node: '>=22.12.0'} @@ -2367,6 +2375,10 @@ packages: delaunator@5.1.0: resolution: {integrity: sha512-AGrQ4QSgssa1NGmWmLPqN5NY2KajF5MqxetNEO+o0n3ZwZZeTmt7bBnvzHWrmkZFxGgr4HdyFgelzgi06otLuQ==} + depd@2.0.0: + resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} + engines: {node: '>= 0.8'} + dequal@2.0.3: resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} engines: {node: '>=6'} @@ -2415,10 +2427,17 @@ packages: duplexer@0.1.2: resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==} + ee-first@1.1.1: + resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} + emoji-regex-xs@2.0.1: resolution: {integrity: sha512-1QFuh8l7LqUcKe24LsPUNzjrzJQ7pgRwp1QMcZ5MX6mFplk2zQ08NVCM84++1cveaUUYtcCYHmeFEuNg16sU4g==} engines: {node: '>=10.0.0'} + encodeurl@2.0.0: + resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} + engines: {node: '>= 0.8'} + entities@4.5.0: resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} engines: {node: '>=0.12'} @@ -2542,6 +2561,10 @@ packages: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} engines: {node: '>=0.10.0'} + etag@1.8.1: + resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} + engines: {node: '>= 0.6'} + eventemitter3@5.0.4: resolution: {integrity: sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==} @@ -2652,6 +2675,10 @@ packages: resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==} engines: {node: '>=12.20.0'} + fresh@2.0.0: + resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==} + engines: {node: '>= 0.8'} + fsevents@2.3.2: resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} @@ -2784,6 +2811,10 @@ packages: http-cache-semantics@4.2.0: resolution: {integrity: sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==} + http-errors@2.0.1: + resolution: {integrity: sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==} + engines: {node: '>= 0.8'} + http-proxy-agent@9.1.0: resolution: {integrity: sha512-2NxoveTT58mjYT4n3RPTEfCZGLMbidoO8XEieXfpSYxu+PQJ1qpx4ypwH6N+uF9twBPIvRRgvkvW5HUTYWENig==} engines: {node: '>= 20'} @@ -2819,6 +2850,9 @@ packages: resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} engines: {node: '>=0.8.19'} + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + inline-style-parser@0.2.7: resolution: {integrity: sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA==} @@ -3228,6 +3262,14 @@ packages: resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} engines: {node: '>=8.6'} + mime-db@1.54.0: + resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==} + engines: {node: '>= 0.6'} + + mime-types@3.0.2: + resolution: {integrity: sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==} + engines: {node: '>=18'} + minimatch@10.2.5: resolution: {integrity: sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==} engines: {node: 18 || 20 || >=22} @@ -3296,6 +3338,10 @@ packages: ohash@2.0.11: resolution: {integrity: sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==} + on-finished@2.4.1: + resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} + engines: {node: '>= 0.8'} + oniguruma-parser@0.12.2: resolution: {integrity: sha512-6HVa5oIrgMC6aA6WF6XyyqbhRPJrKR02L20+2+zpDtO5QAzGHAUGw5TKQvwi5vctNnRHkJYmjAhRVQF2EKdTQw==} @@ -3498,6 +3544,10 @@ packages: radix3@1.1.2: resolution: {integrity: sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA==} + range-parser@1.3.0: + resolution: {integrity: sha512-hek2mFQpPuI4E1BBKrSto+BU3e3x4xuarsbiwr3+lf7p44juvFMV0XFWQAP3xUyqXA4RrXLIoaSUGbSt056ZMw==} + engines: {node: '>= 0.6'} + readdirp@3.6.0: resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} engines: {node: '>=8.10.0'} @@ -3637,10 +3687,6 @@ packages: satteri@0.9.5: resolution: {integrity: sha512-ZuWVl+vnM64y+/TtX8Kosv2c00W+hLQiiwnEL6H0UKVVrxFqMw4D2CJHHQaouVd89OAhtBBfjWLqhKi3TVUV4w==} - sax@1.6.0: - resolution: {integrity: sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA==} - engines: {node: '>=11.0.0'} - sax@1.6.1: resolution: {integrity: sha512-42tBVwLWnaQvW5zc4HbZrTuWccECCZfBi92FDuwtqxasH+JbPB3/FOKb1m222K42R4WxuxzzMsTswfzgtSu64Q==} engines: {node: '>=11.0.0'} @@ -3650,6 +3696,10 @@ packages: engines: {node: '>=10'} hasBin: true + send@1.2.1: + resolution: {integrity: sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==} + engines: {node: '>= 18'} + seroval-plugins@1.5.6: resolution: {integrity: sha512-HXuLAX2pu/UByPpaeo/TaMfvMIi+1QqIoPJYCcAtU8QkVNwgR6MPlGuCQTErV1JwraaMbYaWVIBX7mppzGLATQ==} engines: {node: '>=10'} @@ -3660,6 +3710,12 @@ packages: resolution: {integrity: sha512-rVQVWjjSvlINzaQPZH5JFqsqEsIWdTxY3iJZCnTL/5gQbXIRooVZKI60tVCkOVfzcRPejboxO2t0P89dg5mQaA==} engines: {node: '>=10'} + server-destroy@1.0.1: + resolution: {integrity: sha512-rb+9B5YBIEzYcD6x2VKidaa+cqYBJQKnU4oe4E3ANwRRN56yk/ua1YCJT1n21NTS8w6CcOclAKNP3PhdCXKYtQ==} + + setprototypeof@1.2.0: + resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} + sharp@0.35.4: resolution: {integrity: sha512-n++8XWcj+jCOr2IOl7h8LbKnGBDY4aPbmprMONBNFdn0ImXqpGVv5zliDs0V9HbmbCQLpbuo2ej9rAoOQTvMDA==} engines: {node: '>=20.9.0'} @@ -3787,6 +3843,10 @@ packages: peerDependencies: '@astrojs/starlight': '>=0.38.0' + statuses@2.0.2: + resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} + engines: {node: '>= 0.8'} + std-env@4.2.0: resolution: {integrity: sha512-oCUKSupKTHX53EyjDtuZQ64pjLJ6yYCtpmEw0goYxtjG9KpbRe8KAsl2tBUGU9DyMcJ0RwJ8GqJAFzMXcXW1Rw==} @@ -3863,6 +3923,10 @@ packages: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} + toidentifier@1.0.1: + resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} + engines: {node: '>=0.6'} + totalist@3.0.1: resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==} engines: {node: '>=6'} @@ -4477,6 +4541,15 @@ snapshots: transitivePeerDependencies: - supports-color + '@astrojs/node@11.1.6(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.3)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))': + dependencies: + '@astrojs/internal-helpers': 0.11.0 + astro: 7.3.2(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.3)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0) + send: 1.2.1 + server-destroy: 1.0.1 + transitivePeerDependencies: + - supports-color + '@astrojs/prism@4.0.2': dependencies: prismjs: 1.30.0 @@ -6524,6 +6597,8 @@ snapshots: dependencies: robust-predicates: 3.0.3 + depd@2.0.0: {} + dequal@2.0.3: {} destr@2.0.5: {} @@ -6566,8 +6641,12 @@ snapshots: duplexer@0.1.2: {} + ee-first@1.1.1: {} + emoji-regex-xs@2.0.1: {} + encodeurl@2.0.0: {} + entities@4.5.0: {} entities@6.0.1: {} @@ -6738,6 +6817,8 @@ snapshots: esutils@2.0.3: {} + etag@1.8.1: {} + eventemitter3@5.0.4: {} expect-type@1.4.0: {} @@ -6862,6 +6943,8 @@ snapshots: dependencies: fetch-blob: 3.2.0 + fresh@2.0.0: {} + fsevents@2.3.2: optional: true @@ -7131,6 +7214,14 @@ snapshots: http-cache-semantics@4.2.0: {} + http-errors@2.0.1: + dependencies: + depd: 2.0.0 + inherits: 2.0.4 + setprototypeof: 1.2.0 + statuses: 2.0.2 + toidentifier: 1.0.1 + http-proxy-agent@9.1.0: dependencies: agent-base: 9.0.0 @@ -7165,6 +7256,8 @@ snapshots: imurmurhash@0.1.4: {} + inherits@2.0.4: {} + inline-style-parser@0.2.7: {} internmap@1.0.1: {} @@ -7835,6 +7928,12 @@ snapshots: braces: 3.0.3 picomatch: 2.3.2 + mime-db@1.54.0: {} + + mime-types@3.0.2: + dependencies: + mime-db: 1.54.0 + minimatch@10.2.5: dependencies: brace-expansion: 5.0.9 @@ -7892,6 +7991,10 @@ snapshots: ohash@2.0.11: {} + on-finished@2.4.1: + dependencies: + ee-first: 1.1.1 + oniguruma-parser@0.12.2: {} oniguruma-to-es@4.3.6: @@ -8104,6 +8207,8 @@ snapshots: radix3@1.1.2: {} + range-parser@1.3.0: {} + readdirp@3.6.0: dependencies: picomatch: 2.3.2 @@ -8384,18 +8489,36 @@ snapshots: '@bruits/satteri-win32-arm64-msvc': 0.9.5 '@bruits/satteri-win32-x64-msvc': 0.9.5 - sax@1.6.0: {} - sax@1.6.1: {} semver@7.8.5: {} + send@1.2.1: + dependencies: + debug: 4.4.3 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + fresh: 2.0.0 + http-errors: 2.0.1 + mime-types: 3.0.2 + ms: 2.1.3 + on-finished: 2.4.1 + range-parser: 1.3.0 + statuses: 2.0.2 + transitivePeerDependencies: + - supports-color + seroval-plugins@1.5.6(seroval@1.5.6): dependencies: seroval: 1.5.6 seroval@1.5.6: {} + server-destroy@1.0.1: {} + + setprototypeof@1.2.0: {} + sharp@0.35.4(@types/node@24.13.3): dependencies: '@img/colour': 1.1.0 @@ -8484,7 +8607,7 @@ snapshots: '@types/node': 24.13.3 '@types/sax': 1.2.7 arg: 5.0.2 - sax: 1.6.0 + sax: 1.6.1 smol-toml@1.7.1: {} @@ -8596,6 +8719,8 @@ snapshots: '@astrojs/starlight': 0.41.3(patch_hash=ad8925179f0e3050ae6c804196faa6d38a2be2b718acf138001215a18648d3b5)(@astrojs/markdown-remark@7.2.1)(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.3)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))(typescript@6.0.3) picomatch: 4.0.4 + statuses@2.0.2: {} + std-env@4.2.0: {} stream-replace-string@2.0.0: {} @@ -8672,6 +8797,8 @@ snapshots: dependencies: is-number: 7.0.0 + toidentifier@1.0.1: {} + totalist@3.0.1: {} trim-lines@3.0.1: {} diff --git a/src/frontend/scripts/build-hybrid.mjs b/src/frontend/scripts/build-hybrid.mjs new file mode 100644 index 0000000000..f1ffff9a63 --- /dev/null +++ b/src/frontend/scripts/build-hybrid.mjs @@ -0,0 +1,9 @@ +import { execFileSync } from 'node:child_process'; +import { dirname, resolve } from 'node:path'; +import { fileURLToPath } from 'node:url'; + +const cwd = resolve(dirname(fileURLToPath(import.meta.url)), '..'); +const env = { ...process.env, ASPIRE_HYBRID_API_DOCS: '1' }; +execFileSync('pnpm', [process.argv.includes('--skip-search') ? 'build:skip-search' : 'build'], { + cwd, env, stdio: 'inherit', shell: process.platform === 'win32', +}); diff --git a/src/frontend/scripts/serve-api-docs.mjs b/src/frontend/scripts/serve-api-docs.mjs new file mode 100644 index 0000000000..3e2c662a04 --- /dev/null +++ b/src/frontend/scripts/serve-api-docs.mjs @@ -0,0 +1,57 @@ +import http from 'node:http'; +import { readFile } from 'node:fs/promises'; +import { dirname, resolve, relative, isAbsolute } from 'node:path'; +import { fileURLToPath, pathToFileURL } from 'node:url'; + +const frontend = resolve(dirname(fileURLToPath(import.meta.url)), '..'); +const manifestPath = resolve(process.env.HYBRID_API_DOCS_MANIFEST || resolve(frontend, 'dist-hybrid/hybrid-api-docs.json')); +const manifest = JSON.parse(await readFile(manifestPath, 'utf8')); +if (manifest.schemaVersion !== 1 || manifest.mode !== 'hybrid-api-docs' || !/^[a-f0-9]{64}$/.test(manifest.buildId)) { + throw new Error('Expected a compatible prebuilt hybrid-api-docs.json artifact.'); +} +const root = dirname(manifestPath); +const entry = resolve(root, manifest.server); +const entryRelative = relative(root, entry); +if (isAbsolute(entryRelative) || entryRelative.startsWith('..')) throw new Error('Renderer entrypoint escapes its artifact.'); +const { handler } = await import(pathToFileURL(entry).href); +const paths = new Set(manifest.routes.flatMap(({ html, markdown }) => html ? [html, markdown] : [markdown])); +let renders = 0; +const started = process.memoryUsage(); +const server = http.createServer((req, res) => { + res.setHeader('X-Aspire-Build-Id', manifest.buildId); + const url = new URL(req.url, 'http://localhost'); + if (url.pathname === '/__hybrid-api-docs/health') { + res.setHeader('Content-Type', 'application/json'); + res.end(JSON.stringify({ buildId: manifest.buildId, renders, started, memory: process.memoryUsage() })); + return; + } + if (!['GET', 'HEAD'].includes(req.method)) { + res.writeHead(405, { Allow: 'GET, HEAD' }); + res.end(); + return; + } + if (!paths.has(url.pathname)) { + res.writeHead(404); + res.end('API route not found'); + return; + } + renders++; + handler(req, res, () => { + res.writeHead(404); + res.end('API route not found'); + }).catch((error) => { + console.error(`[hybrid-api-docs] Rendering ${url.pathname} failed`, error); + if (res.headersSent) res.destroy(error); + else { + res.writeHead(500, { 'Cache-Control': 'no-store' }); + res.end('API rendering failed'); + } + }); +}); +server.on('error', (error) => { console.error(error); process.exitCode = 1; }); +server.listen(Number(process.env.PORT || 4323), process.env.HOST || '127.0.0.1', () => { + console.log(`[hybrid-api-docs] ${manifest.buildId} listening on ${JSON.stringify(server.address())}`); +}); +for (const signal of ['SIGINT', 'SIGTERM']) { + process.on(signal, () => { server.close(); server.closeAllConnections(); }); +} diff --git a/src/frontend/scripts/test-hybrid-host.mjs b/src/frontend/scripts/test-hybrid-host.mjs new file mode 100644 index 0000000000..ce6607cb2f --- /dev/null +++ b/src/frontend/scripts/test-hybrid-host.mjs @@ -0,0 +1,112 @@ +import assert from 'node:assert/strict'; +import { spawn } from 'node:child_process'; +import { once } from 'node:events'; +import { readFile, writeFile } from 'node:fs/promises'; +import { dirname, resolve } from 'node:path'; +import { fileURLToPath } from 'node:url'; + +const root = resolve(dirname(fileURLToPath(import.meta.url)), '..'); +const manifestPath = resolve(root, 'dist-hybrid/hybrid-api-docs.json'); +const manifest = JSON.parse(await readFile(manifestPath, 'utf8')); +const children = []; +let output = ''; + +function launch(command, args, env) { + const child = spawn(command, args, { cwd: root, env, stdio: ['ignore', 'pipe', 'pipe'], + shell: process.platform === 'win32' && command === 'pnpm' }); + children.push(child); + child.on('error', (error) => { output += `${command}: ${error.message}\n`; }); + for (const stream of [child.stdout, child.stderr]) stream.on('data', (data) => { output += data.toString(); }); + return child; +} + +async function ready(url) { + for (let attempt = 0; attempt < 120; attempt++) { + try { + const response = await fetch(url, { signal: AbortSignal.timeout(2000) }); + if (response.ok) return; + } catch (error) { + if (children.some((child) => child.exitCode !== null)) throw new Error(`POC process exited: ${output}`, { cause: error }); + } + await new Promise((resolve) => setTimeout(resolve, 500)); + } + throw new Error(`POC endpoint did not become ready: ${url}\n${output}`); +} + +const workerUrl = 'http://127.0.0.1:14323'; +const hostUrl = 'http://127.0.0.1:14324'; +const measures = {}; +try { + const worker = launch(process.execPath, ['scripts/serve-api-docs.mjs'], { + ...process.env, PORT: '14323', HYBRID_API_DOCS_MANIFEST: manifestPath, + }); + await ready(`${workerUrl}/__hybrid-api-docs/health`); + launch('dotnet', [resolve(root, '../statichost/StaticHost/bin/Release/net10.0/StaticHost.dll')], { + ...process.env, + ASPNETCORE_URLS: hostUrl, + ASPNETCORE_ENVIRONMENT: 'Production', + HybridApiDocs__ArtifactPath: manifestPath, + HybridApiDocs__RendererUrl: workerUrl, + Live__Twitch__ClientId: '', + Live__YouTube__ApiKey: '', + }); + await ready(`${hostUrl}/healthz`); + const stats = async () => (await fetch(`${workerUrl}/__hybrid-api-docs/health`)).json(); + async function page(path, init = {}) { + const start = performance.now(); + const response = await fetch(hostUrl + path, { ...init, signal: AbortSignal.timeout(60000) }); + const text = await response.text(); + assert.equal(response.status, 200, `${path}: ${response.status}\n${text.slice(0, 500)}\n${output}`); + measures[path] ??= []; + measures[path].push(Math.round((performance.now() - start) * 100) / 100); + return { response, text }; + } + const initial = await stats(); + await page('/docs/'); + assert.equal((await stats()).renders, initial.renders); + const csharp = await page('/reference/api/csharp/'); + const cold = await stats(); + assert.ok(cold.renders > initial.renders); + assert.equal((await page('/reference/api/csharp/')).text, csharp.text); + assert.equal((await stats()).renders, cold.renders); + const typescript = await page('/reference/api/typescript/'); + assert.ok(Buffer.byteLength(typescript.text) >= 13_621_124); + assert.equal(Number(typescript.response.headers.get('content-length')), Buffer.byteLength(typescript.text)); + for (const language of ['csharp', 'typescript']) { + const route = manifest.routes.find(({ html }) => html?.startsWith(`/reference/api/${language}/`) && html.split('/').length >= 7); + assert.ok(route); + const before = await stats(); + const pages = await Promise.all(Array.from({ length: 20 }, () => page(route.html))); + assert.ok(pages.every(({ text }) => text === pages[0].text)); + assert.equal((await stats()).renders, before.renders + 1); + const direct = await page(route.markdown); + const negotiated = await page(route.html, { headers: { Accept: 'text/markdown' } }); + assert.equal(negotiated.text, direct.text); + assert.ok(negotiated.response.headers.get('cache-control').includes('private')); + assert.ok(pages[0].response.headers.get('link').includes(route.markdown)); + } + const unknown = await fetch(`${hostUrl}/reference/api/not-a-page/`); + assert.equal(unknown.status, 404); + if (process.env.HYBRID_TEST_BROWSER === '1') { + const install = launch('pnpm', ['exec', 'playwright', 'install', '--with-deps', 'chromium'], process.env); + assert.equal((await once(install, 'exit'))[0], 0, output); + const browser = launch('pnpm', ['exec', 'playwright', 'test', '--config', 'playwright.hybrid.config.mjs'], + { ...process.env, HYBRID_TEST_URL: hostUrl }); + assert.equal((await once(browser, 'exit'))[0], 0, output); + } + const final = await stats(); + const stopped = once(worker, 'exit'); + worker.kill(); + await stopped; + await page('/docs/'); + await page('/reference/api/csharp/'); + const unwarmed = manifest.routes.find(({ html }) => html && !measures[html]); + assert.ok(unwarmed); + const failure = await fetch(hostUrl + unwarmed.html); + assert.equal(failure.status, 502); + const results = { success: true, buildId: manifest.buildId, measures, initial, final }; + await writeFile(resolve(root, 'hybrid-host-results.json'), JSON.stringify(results, null, 2)); + console.log(JSON.stringify(results, null, 2)); +} finally { + for (const child of children) if (child.exitCode === null) child.kill(); +} diff --git a/src/frontend/scripts/verify-hybrid-output.mjs b/src/frontend/scripts/verify-hybrid-output.mjs new file mode 100644 index 0000000000..ffc19a0c9e --- /dev/null +++ b/src/frontend/scripts/verify-hybrid-output.mjs @@ -0,0 +1,46 @@ +import assert from 'node:assert/strict'; +import { readFile, writeFile } from 'node:fs/promises'; +import { resolve } from 'node:path'; +import { pathToFileURL } from 'node:url'; +import { measureOutput } from './measure-build-output.mjs'; + +export async function verifyHybridOutput(staticRoot, hybridRoot) { + const manifest = JSON.parse(await readFile(resolve(hybridRoot, 'hybrid-api-docs.json'), 'utf8')); + assert.equal(manifest.mode, 'hybrid-api-docs'); + assert.equal(manifest.schemaVersion, 1); + const [baseline, hybrid, server] = await Promise.all([ + measureOutput(staticRoot), measureOutput(resolve(hybridRoot, manifest.client)), + measureOutput(resolve(hybridRoot, 'server')), + ]); + const api = (path) => path.startsWith('reference/api/') && /\.(html|md)$/.test(path); + assert.ok(baseline.files.some(({ path }) => api(path)), 'The baseline must include static API output.'); + assert.deepEqual(hybrid.files.filter(({ path }) => api(path)), [], 'API HTML/Markdown was prerendered.'); + assert.ok(server.files.some(({ path }) => path === 'entry.mjs'), 'Missing private renderer entrypoint.'); + const redirectFiles = new Set(manifest.redirects.map(({ path }) => `${path.replace(/^\/|\/$/g, '')}/index.html`)); + const nonApi = (files) => files.filter(({ path }) => + /\.(html|md)$/.test(path) && !api(path) && !redirectFiles.has(path)).map(({ path }) => path); + assert.deepEqual(nonApi(hybrid.files), nonApi(baseline.files), 'Non-API page inventory changed.'); + for (const file of ['index.html', '404.html', 'llms.txt', 'sitemap-index.xml', 'sitemap-api.xml']) { + assert.ok(hybrid.files.some(({ path }) => path === file), `Missing ${file}`); + } + assert.ok(!hybrid.files.some(({ path }) => path === 'hybrid-api-docs.json' || path.startsWith('server/'))); + const sitemap = await readFile(resolve(hybridRoot, manifest.client, 'sitemap-api.xml'), 'utf8'); + for (const { html } of manifest.routes) { + if (html) assert.ok(sitemap.includes(`${manifest.site}${html}`), `Missing sitemap URL ${html}`); + } + return { + buildId: manifest.buildId, + baseline: { bytes: baseline.totalBytes, files: baseline.files.length }, + hybridClient: { bytes: hybrid.totalBytes, files: hybrid.files.length }, + hybridServer: { bytes: server.totalBytes, files: server.files.length }, + staticApiFilesAvoided: baseline.files.filter(({ path }) => api(path)).length, + nonApiPages: nonApi(hybrid.files).length, + apiRoutes: manifest.routes.length, + }; +} + +if (process.argv[1] && import.meta.url === pathToFileURL(resolve(process.argv[1])).href) { + const result = await verifyHybridOutput(resolve(process.argv[2] || 'dist'), resolve(process.argv[3] || 'dist-hybrid')); + await writeFile(resolve('hybrid-output-results.json'), JSON.stringify(result, null, 2)); + console.log(JSON.stringify(result, null, 2)); +} diff --git a/src/frontend/src/pages/reference/api/csharp/[package].md.ts b/src/frontend/src/pages/reference/api/csharp/[package].md.ts index 1aa3b064e4..be29c6c0ee 100644 --- a/src/frontend/src/pages/reference/api/csharp/[package].md.ts +++ b/src/frontend/src/pages/reference/api/csharp/[package].md.ts @@ -4,6 +4,7 @@ import { markdownResponse } from '@utils/api-markdown-shared'; import { renderCSharpPackageMarkdown } from '@utils/csharp-api-markdown'; import type { PackageApiDocument } from '@utils/packages'; import { getPackages, packageSlug } from '@utils/packages'; +import { resolveCSharpApiRoute } from '@utils/api-route-data'; export const prerender = true; @@ -27,8 +28,9 @@ export async function getStaticPaths(): Promise { })); } -export const GET: APIRoute = ({ props }) => { +export const GET: APIRoute = async ({ props, url }) => { const base = import.meta.env.BASE_URL.replace(/\/$/, ''); - const routeProps = props as RouteProps; + const routeProps = (props.pkg ? props : await resolveCSharpApiRoute(url.pathname)) as RouteProps | undefined; + if (!routeProps) return new Response('API package not found', { status: 404 }); return markdownResponse(renderCSharpPackageMarkdown(routeProps.pkg, base)); }; diff --git a/src/frontend/src/pages/reference/api/csharp/[package]/[type].md.ts b/src/frontend/src/pages/reference/api/csharp/[package]/[type].md.ts index b6b78253a4..38c553c428 100644 --- a/src/frontend/src/pages/reference/api/csharp/[package]/[type].md.ts +++ b/src/frontend/src/pages/reference/api/csharp/[package]/[type].md.ts @@ -4,6 +4,7 @@ import { markdownResponse } from '@utils/api-markdown-shared'; import { renderCSharpTypeMarkdown } from '@utils/csharp-api-markdown'; import type { PackageApiDocument, PackageType } from '@utils/packages'; import { genericArity, getPackages, packageSlug, slugify } from '@utils/packages'; +import { resolveCSharpApiRoute } from '@utils/api-route-data'; export const prerender = true; @@ -49,9 +50,10 @@ export async function getStaticPaths(): Promise { return paths; } -export const GET: APIRoute = ({ props }) => { +export const GET: APIRoute = async ({ props, url }) => { const base = import.meta.env.BASE_URL.replace(/\/$/, ''); - const routeProps = props as RouteProps; + const routeProps = (props.pkg ? props : await resolveCSharpApiRoute(url.pathname)) as RouteProps | undefined; + if (!routeProps?.type) return new Response('API type not found', { status: 404 }); return markdownResponse( renderCSharpTypeMarkdown(routeProps.pkg, routeProps.type, routeProps.allTypes, base) diff --git a/src/frontend/src/pages/reference/api/csharp/[package]/[type]/[memberKind].astro b/src/frontend/src/pages/reference/api/csharp/[package]/[type]/[memberKind].astro index 882a899aa8..cc65022d60 100644 --- a/src/frontend/src/pages/reference/api/csharp/[package]/[type]/[memberKind].astro +++ b/src/frontend/src/pages/reference/api/csharp/[package]/[type]/[memberKind].astro @@ -9,6 +9,7 @@ import StarlightPage from '@astrojs/starlight/components/StarlightPage.astro'; import { getApiReferenceSidebar } from '@utils/api-sidebar'; import Breadcrumb from '@components/Breadcrumb.astro'; import MemberCard from '@components/api-reference/MemberCard.astro'; +import { resolveCSharpApiRoute } from '@utils/api-route-data'; import DocContent from '@components/api-reference/DocContent.astro'; import { slugify, @@ -65,7 +66,9 @@ export async function getStaticPaths() { return paths; } -const { pkg, type, allTypes, kind } = Astro.props; +const routeProps = Astro.props.pkg ? Astro.props : await resolveCSharpApiRoute(Astro.url.pathname); +if (!routeProps?.type || !routeProps.kind) return new Response('API member group not found', { status: 404 }); +const { pkg, type, allTypes, kind } = routeProps; const base = import.meta.env.BASE_URL.replace(/\/$/, ''); const apiSidebar = await getApiReferenceSidebar({ packageName: pkg.package.name }); diff --git a/src/frontend/src/pages/reference/api/csharp/[package]/[type]/[memberKind].md.ts b/src/frontend/src/pages/reference/api/csharp/[package]/[type]/[memberKind].md.ts index 58044dcb67..42bfb41dc5 100644 --- a/src/frontend/src/pages/reference/api/csharp/[package]/[type]/[memberKind].md.ts +++ b/src/frontend/src/pages/reference/api/csharp/[package]/[type]/[memberKind].md.ts @@ -2,6 +2,7 @@ import type { APIRoute } from 'astro'; import { markdownResponse } from '@utils/api-markdown-shared'; import { renderCSharpMemberKindMarkdown } from '@utils/csharp-api-markdown'; +import { resolveCSharpApiRoute } from '@utils/api-route-data'; import type { PackageApiDocument, PackageMember, PackageType } from '@utils/packages'; import { genericArity, @@ -67,9 +68,10 @@ export async function getStaticPaths(): Promise { return paths; } -export const GET: APIRoute = ({ props }) => { +export const GET: APIRoute = async ({ props, url }) => { const base = import.meta.env.BASE_URL.replace(/\/$/, ''); - const routeProps = props as RouteProps; + const routeProps = (props.pkg ? props : await resolveCSharpApiRoute(url.pathname)) as RouteProps | undefined; + if (!routeProps?.type || !routeProps.memberKind) return new Response('API member group not found', { status: 404 }); return markdownResponse( renderCSharpMemberKindMarkdown( diff --git a/src/frontend/src/pages/reference/api/csharp/[package]/[type]/index.astro b/src/frontend/src/pages/reference/api/csharp/[package]/[type]/index.astro index 0f0c8d0951..18756d5162 100644 --- a/src/frontend/src/pages/reference/api/csharp/[package]/[type]/index.astro +++ b/src/frontend/src/pages/reference/api/csharp/[package]/[type]/index.astro @@ -16,6 +16,7 @@ import AnchorHeading from '@components/api-reference/AnchorHeading.astro'; import InpageSearch from '@components/api-reference/InpageSearch.astro'; import PolyglotAttributePanel from '@components/api-reference/PolyglotAttributePanel.astro'; import { findAttribute, hasAttribute, resolveDiagnosticSlug } from '@utils/api-attributes'; +import { resolveCSharpApiRoute } from '@utils/api-route-data'; import { slugify, genericArity, @@ -54,7 +55,9 @@ export async function getStaticPaths() { return paths; } -const { pkg, type, allTypes } = Astro.props; +const routeProps = Astro.props.pkg ? Astro.props : await resolveCSharpApiRoute(Astro.url.pathname); +if (!routeProps?.type) return new Response('API type not found', { status: 404 }); +const { pkg, type, allTypes } = routeProps; const base = import.meta.env.BASE_URL.replace(/\/$/, ''); const apiSidebar = await getApiReferenceSidebar({ packageName: pkg.package.name }); diff --git a/src/frontend/src/pages/reference/api/csharp/[package]/index.astro b/src/frontend/src/pages/reference/api/csharp/[package]/index.astro index fe2d5c85e7..b6f84bae25 100644 --- a/src/frontend/src/pages/reference/api/csharp/[package]/index.astro +++ b/src/frontend/src/pages/reference/api/csharp/[package]/index.astro @@ -15,6 +15,7 @@ import Breadcrumb from '@components/Breadcrumb.astro'; import DocContent from '@components/api-reference/DocContent.astro'; import NuGetButton from '@components/api-reference/NuGetButton.astro'; import { hasAttribute } from '@utils/api-attributes'; +import { resolveCSharpApiRoute } from '@utils/api-route-data'; export async function getStaticPaths() { const packages = await getPackages(); @@ -24,7 +25,9 @@ export async function getStaticPaths() { })); } -const { pkg } = Astro.props; +const routeProps = Astro.props.pkg ? Astro.props : await resolveCSharpApiRoute(Astro.url.pathname); +if (!routeProps) return new Response('API package not found', { status: 404 }); +const { pkg } = routeProps; const base = import.meta.env.BASE_URL.replace(/\/$/, ''); const validTypes = pkg.types.filter((t: any) => t.name); // skip types with empty names const isOfficial = pkg.package.name.startsWith('Aspire.'); diff --git a/src/frontend/src/pages/reference/api/typescript/[module].md.ts b/src/frontend/src/pages/reference/api/typescript/[module].md.ts index 197417fc57..268dc7168f 100644 --- a/src/frontend/src/pages/reference/api/typescript/[module].md.ts +++ b/src/frontend/src/pages/reference/api/typescript/[module].md.ts @@ -4,6 +4,7 @@ import { markdownResponse } from '@utils/api-markdown-shared'; import { renderTypeScriptModuleMarkdown } from '@utils/typescript-api-markdown'; import type { TsApiDocument } from '@utils/ts-modules'; import { getTsModules, tsModuleSlug } from '@utils/ts-modules'; +import { resolveTypeScriptApiRoute } from '@utils/api-route-data'; export const prerender = true; @@ -27,8 +28,9 @@ export async function getStaticPaths(): Promise { })); } -export const GET: APIRoute = ({ props }) => { +export const GET: APIRoute = async ({ props, url }) => { const base = import.meta.env.BASE_URL.replace(/\/$/, ''); - const routeProps = props as RouteProps; + const routeProps = (props.pkg ? props : await resolveTypeScriptApiRoute(url.pathname)) as RouteProps | undefined; + if (!routeProps) return new Response('API module not found', { status: 404 }); return markdownResponse(renderTypeScriptModuleMarkdown(routeProps.pkg, base)); }; diff --git a/src/frontend/src/pages/reference/api/typescript/[module]/[item].md.ts b/src/frontend/src/pages/reference/api/typescript/[module]/[item].md.ts index 260436e2d1..9977d2eef5 100644 --- a/src/frontend/src/pages/reference/api/typescript/[module]/[item].md.ts +++ b/src/frontend/src/pages/reference/api/typescript/[module]/[item].md.ts @@ -5,6 +5,7 @@ import { renderTypeScriptItemMarkdown } from '@utils/typescript-api-markdown'; import type { TsApiDocument, TsDtoType, TsEnumType, TsFunction, TsHandleType } from '@utils/ts-modules'; import { getTsModules, tsModuleSlug, tsSlugify } from '@utils/ts-modules'; import { getTsItemSlug, getTsStandaloneFunctions, getTsTopLevelRouteItems } from '@utils/ts-api-routes'; +import { resolveTypeScriptApiRoute } from '@utils/api-route-data'; export const prerender = true; @@ -121,9 +122,10 @@ export async function getStaticPaths(): Promise { return [...paths, ...legacy.values()]; } -export const GET: APIRoute = ({ props }) => { +export const GET: APIRoute = async ({ props, url }) => { const base = import.meta.env.BASE_URL.replace(/\/$/, ''); - const routeProps = props as RouteProps; + const routeProps = (props.pkg ? props : await resolveTypeScriptApiRoute(url.pathname)) as RouteProps | undefined; + if (!routeProps?.item) return new Response('API item not found', { status: 404 }); return markdownResponse( renderTypeScriptItemMarkdown(routeProps.pkg, routeProps.item, routeProps.itemKind, base) diff --git a/src/frontend/src/pages/reference/api/typescript/[module]/[item]/[member].md.ts b/src/frontend/src/pages/reference/api/typescript/[module]/[item]/[member].md.ts index 1cf25aa896..d1bff9a674 100644 --- a/src/frontend/src/pages/reference/api/typescript/[module]/[item]/[member].md.ts +++ b/src/frontend/src/pages/reference/api/typescript/[module]/[item]/[member].md.ts @@ -5,6 +5,7 @@ import { renderTypeScriptMemberMarkdownPage } from '@utils/typescript-api-markdo import type { TsApiDocument, TsFunction, TsHandleType } from '@utils/ts-modules'; import { getTsModules, tsModuleSlug, tsSlugify } from '@utils/ts-modules'; import { getTsItemSlug, getTsMethods, getTsMethodSlug, getTsTopLevelRouteItems } from '@utils/ts-api-routes'; +import { resolveTypeScriptApiRoute } from '@utils/api-route-data'; export const prerender = true; @@ -70,9 +71,10 @@ export async function getStaticPaths(): Promise { return [...paths, ...legacy.values()]; } -export const GET: APIRoute = ({ props }) => { +export const GET: APIRoute = async ({ props, url }) => { const base = import.meta.env.BASE_URL.replace(/\/$/, ''); - const routeProps = props as RouteProps; + const routeProps = (props.pkg ? props : await resolveTypeScriptApiRoute(url.pathname)) as RouteProps | undefined; + if (!routeProps?.method || !routeProps.parentType) return new Response('API member not found', { status: 404 }); return markdownResponse( renderTypeScriptMemberMarkdownPage(routeProps.pkg, routeProps.parentType, routeProps.method, base) diff --git a/src/frontend/src/pages/reference/api/typescript/[module]/[item]/[member]/index.astro b/src/frontend/src/pages/reference/api/typescript/[module]/[item]/[member]/index.astro index 94b3155107..0359c7953c 100644 --- a/src/frontend/src/pages/reference/api/typescript/[module]/[item]/[member]/index.astro +++ b/src/frontend/src/pages/reference/api/typescript/[module]/[item]/[member]/index.astro @@ -10,6 +10,7 @@ import StarlightPage from '@astrojs/starlight/components/StarlightPage.astro'; import { Code } from '@astrojs/starlight/components'; import { tsModuleSlug, getTsModules, simplifyType, formatTsSignature } from '@utils/ts-modules'; import { getTsApiReferenceSidebar } from '@utils/ts-api-sidebar'; +import { resolveTypeScriptApiRoute } from '@utils/api-route-data'; import { getTsItemSlug, getTsMethods, getTsMethodSlug, getTsTopLevelRouteItems } from '@utils/ts-api-routes'; import Breadcrumb from '@components/Breadcrumb.astro'; import TsMemberCard from '@components/api-reference/TsMemberCard.astro'; @@ -47,7 +48,9 @@ export async function getStaticPaths() { return paths; } -const { pkg, parentType, method } = Astro.props; +const routeProps = Astro.props.pkg ? Astro.props : await resolveTypeScriptApiRoute(Astro.url.pathname); +if (!routeProps?.method || !routeProps.parentType) return new Response('API member not found', { status: 404 }); +const { pkg, parentType, method } = routeProps; const base = import.meta.env.BASE_URL.replace(/\/$/, ''); const pkgSlug = tsModuleSlug(pkg.package.name); const parentSlug = Astro.params.item ?? getTsItemSlug(parentType, getTsTopLevelRouteItems(pkg)); diff --git a/src/frontend/src/pages/reference/api/typescript/[module]/[item]/index.astro b/src/frontend/src/pages/reference/api/typescript/[module]/[item]/index.astro index ceb1ba788b..82fc091e9f 100644 --- a/src/frontend/src/pages/reference/api/typescript/[module]/[item]/index.astro +++ b/src/frontend/src/pages/reference/api/typescript/[module]/[item]/index.astro @@ -9,6 +9,7 @@ import StarlightPage from '@astrojs/starlight/components/StarlightPage.astro'; import { Code } from '@astrojs/starlight/components'; import { tsModuleSlug, getTsModules, simplifyType, formatTsSignature, type TsFunction } from '@utils/ts-modules'; import { getTsApiReferenceSidebar } from '@utils/ts-api-sidebar'; +import { resolveTypeScriptApiRoute } from '@utils/api-route-data'; import { getTsFunctionDisplayLabel, isTsExtensionStyleFunction } from '@utils/ts-api-function-kind'; import { getTsItemSlug, getTsMemberAnchor, getTsMethods, getTsMethodSlug, getTsStandaloneFunctions, getTsTopLevelRouteItems, getTsTypeByName } from '@utils/ts-api-routes'; import Breadcrumb from '@components/Breadcrumb.astro'; @@ -67,7 +68,9 @@ export async function getStaticPaths() { return paths; } -const { pkg, item, itemKind } = Astro.props; +const routeProps = Astro.props.pkg ? Astro.props : await resolveTypeScriptApiRoute(Astro.url.pathname); +if (!routeProps?.item) return new Response('API item not found', { status: 404 }); +const { pkg, item, itemKind } = routeProps; const base = import.meta.env.BASE_URL.replace(/\/$/, ''); const pkgSlug = tsModuleSlug(pkg.package.name); const topLevelItems = getTsTopLevelRouteItems(pkg); diff --git a/src/frontend/src/pages/reference/api/typescript/[module]/index.astro b/src/frontend/src/pages/reference/api/typescript/[module]/index.astro index 6a99e3440d..e8c7485465 100644 --- a/src/frontend/src/pages/reference/api/typescript/[module]/index.astro +++ b/src/frontend/src/pages/reference/api/typescript/[module]/index.astro @@ -9,6 +9,7 @@ import StarlightPage from '@astrojs/starlight/components/StarlightPage.astro'; import { tsModuleSlug, getTsModules, simplifyType } from '@utils/ts-modules'; import { getTsApiReferenceSidebar } from '@utils/ts-api-sidebar'; +import { resolveTypeScriptApiRoute } from '@utils/api-route-data'; import { getTsCallableIdentityKey, getTsFunctionDisplayKind, @@ -26,7 +27,9 @@ export async function getStaticPaths() { })); } -const { pkg } = Astro.props; +const routeProps = Astro.props.pkg ? Astro.props : await resolveTypeScriptApiRoute(Astro.url.pathname); +if (!routeProps) return new Response('API module not found', { status: 404 }); +const { pkg } = routeProps; const base = import.meta.env.BASE_URL.replace(/\/$/, ''); const pkgSlug = tsModuleSlug(pkg.package.name); const isOfficial = pkg.package.name.startsWith('Aspire.'); diff --git a/src/frontend/src/utils/api-route-catalog.ts b/src/frontend/src/utils/api-route-catalog.ts new file mode 100644 index 0000000000..1a8e9a3a6a --- /dev/null +++ b/src/frontend/src/utils/api-route-catalog.ts @@ -0,0 +1,106 @@ +import type { PackageApiDocument, PackageType } from './packages'; +import type { TsApiDocument, TsDtoType, TsEnumType, TsFunction, TsHandleType } from './ts-modules'; +import { genericArity, memberKindOrder, memberKindSlugs, packageSlug, slugify } from './csharp-route-identity'; +import { getTsItemSlug, getTsMethods, getTsMethodSlug, getTsStandaloneFunctions, getTsTopLevelRouteItems, tsSlugify } from './ts-api-routes'; + +export interface ApiRoute { + html: string | null; + markdown: string; +} + +export interface CSharpRouteProps { + pkg: PackageApiDocument; + allTypes: PackageType[]; + type?: PackageType; + kind?: string; + memberKind?: string; +} + +export interface TypeScriptRouteProps { + pkg: TsApiDocument; + item?: TsHandleType | TsDtoType | TsEnumType | TsFunction; + itemKind?: 'handle' | 'dto' | 'enum' | 'function'; + parentType?: TsHandleType; + method?: TsFunction; +} + +interface RouteEntry extends ApiRoute { + props: T; +} + +function entry(path: string, props: T): RouteEntry { + return { html: `${path}/`, markdown: `${path}.md`, props }; +} + +export function getCSharpRouteEntries(pkg: PackageApiDocument): RouteEntry[] { + const root = `/reference/api/csharp/${packageSlug(pkg.package.name)}`; + const props = { pkg, allTypes: pkg.types }; + const routes: RouteEntry[] = [entry(root, props)]; + for (const type of pkg.types) { + const slug = slugify(type.name, genericArity(type)); + if (!slug) continue; + const path = `${root}/${slug}`; + routes.push(entry(path, { ...props, type })); + for (const kind of memberKindOrder) { + if (type.members?.some((member) => member.kind === kind)) { + routes.push(entry(`${path}/${memberKindSlugs[kind]}`, { + ...props, type, kind, memberKind: kind, + })); + } + } + } + return routes; +} + +export function getTypeScriptRouteEntries(pkg: TsApiDocument): RouteEntry[] { + const root = `/reference/api/typescript/${packageSlug(pkg.package.name)}`; + const routes: RouteEntry[] = [entry(root, { pkg })]; + const items = getTsTopLevelRouteItems(pkg); + const groups = [ + { kind: 'handle' as const, items: pkg.handleTypes ?? [] }, + { kind: 'dto' as const, items: pkg.dtoTypes ?? [] }, + { kind: 'enum' as const, items: pkg.enumTypes ?? [] }, + { kind: 'function' as const, items: getTsStandaloneFunctions(pkg) }, + ]; + for (const group of groups) { + for (const item of group.items) { + const slug = getTsItemSlug(item, items); + if (slug) routes.push(entry(`${root}/${slug}`, { pkg, item, itemKind: group.kind })); + } + } + for (const handle of pkg.handleTypes ?? []) { + const item = getTsItemSlug(handle, items); + if (!item) continue; + const methods = getTsMethods(handle); + for (const method of methods) { + const member = getTsMethodSlug(method, methods, handle.name); + if (member) routes.push(entry(`${root}/${item}/${member}`, { pkg, parentType: handle, method })); + } + } + + // Published Markdown aliases resolve to the last source entry, but never replace a canonical URL. + const canonical = new Set(routes.map((route) => route.markdown)); + const aliases = new Map>(); + for (const route of routes) { + const { item, parentType, method } = route.props; + const segments = item ? [tsSlugify(item.name)] + : parentType && method ? [tsSlugify(parentType.name), tsSlugify(method.name)] : []; + if (!segments.length || segments.some((segment) => !segment)) continue; + const markdown = `${root}/${segments.join('/')}.md`; + if (!canonical.has(markdown)) aliases.set(markdown, { ...route, html: null, markdown }); + } + return [...routes, ...aliases.values()]; +} + +export function buildApiRouteCatalog(packages: PackageApiDocument[], modules: TsApiDocument[]): ApiRoute[] { + const routes: ApiRoute[] = ['csharp', 'typescript'].map((language) => ({ + html: `/reference/api/${language}/`, markdown: `/reference/api/${language}.md`, + })); + for (const pkg of packages) { + if (pkg.types.length) routes.push(...getCSharpRouteEntries(pkg)); + } + for (const pkg of modules) routes.push(...getTypeScriptRouteEntries(pkg)); + const unique = new Map(); + for (const { html, markdown } of routes) unique.set(markdown, { html, markdown }); + return [...unique.values()]; +} diff --git a/src/frontend/src/utils/api-route-data.ts b/src/frontend/src/utils/api-route-data.ts new file mode 100644 index 0000000000..ed945bc83e --- /dev/null +++ b/src/frontend/src/utils/api-route-data.ts @@ -0,0 +1,28 @@ +import { getPackages } from './packages'; +import { getTsModules } from './ts-modules'; +import { getCSharpRouteEntries, getTypeScriptRouteEntries } from './api-route-catalog'; +import type { CSharpRouteProps, TypeScriptRouteProps } from './api-route-catalog'; + +function index(entries: { html: string | null; markdown: string; props: T }[]): Map { + const result = new Map(); + for (const route of entries) { + if (route.html) result.set(route.html, route.props); + result.set(route.markdown, route.props); + } + return result; +} + +let csharp: Promise> | undefined; +let typescript: Promise> | undefined; + +export async function resolveCSharpApiRoute(pathname: string) { + const load = () => getPackages().then((packages) => index(packages.flatMap(({ data }) => getCSharpRouteEntries(data)))); + const routes = await (import.meta.env.PROD ? (csharp ??= load()) : load()); + return routes.get(pathname); +} + +export async function resolveTypeScriptApiRoute(pathname: string) { + const load = () => getTsModules().then((packages) => index(packages.flatMap(({ data }) => getTypeScriptRouteEntries(data)))); + const routes = await (import.meta.env.PROD ? (typescript ??= load()) : load()); + return routes.get(pathname); +} diff --git a/src/frontend/src/utils/csharp-route-identity.ts b/src/frontend/src/utils/csharp-route-identity.ts new file mode 100644 index 0000000000..ea52b43d1e --- /dev/null +++ b/src/frontend/src/utils/csharp-route-identity.ts @@ -0,0 +1,25 @@ +export function genericArity(type: { genericParameters?: { name: string }[] }): number { + return type.genericParameters?.length ?? 0; +} + +export function slugify(name: string, arity = 0): string { + const slug = name.toLowerCase(); + return arity > 0 ? `${slug}-${arity}` : slug; +} + +export function packageSlug(name: string): string { + return name.toLowerCase(); +} + +export const memberKindOrder = [ + 'constructor', 'property', 'method', 'field', 'event', 'indexer', +] as const; + +export const memberKindSlugs: Record = { + constructor: 'constructors', + property: 'properties', + method: 'methods', + field: 'fields', + event: 'events', + indexer: 'indexers', +}; diff --git a/src/frontend/src/utils/packages.ts b/src/frontend/src/utils/packages.ts index c94166397b..291b1b4000 100644 --- a/src/frontend/src/utils/packages.ts +++ b/src/frontend/src/utils/packages.ts @@ -5,6 +5,9 @@ import type { CollectionEntry } from 'astro:content'; import { getCollection } from 'astro:content'; import { shortTypeName } from './api-member-anchors'; +import { genericArity, slugify, packageSlug, memberKindOrder, memberKindSlugs } from './csharp-route-identity'; + +export { genericArity, slugify, packageSlug, memberKindOrder, memberKindSlugs }; export { memberAnchorAliases, @@ -84,11 +87,6 @@ export function getPackages(): Promise { return packagesPromise; } -/** Count generic type parameters on a type object. */ -export function genericArity(type: { genericParameters?: GenericParameter[] }): number { - return type.genericParameters?.length ?? 0; -} - /** Display name including generic type parameters (e.g. `InteractionResult`). */ export function typeDisplayName(type: { name: string; @@ -100,21 +98,6 @@ export function typeDisplayName(type: { : type.name; } -/** - * Convert a PascalCase type name to a lowercase URL slug. - * When `arity` > 0, appends `-N` to disambiguate generic types - * (e.g. `InteractionResult` → `interactionresult-1`). - */ -export function slugify(name: string, arity: number = 0): string { - const slug = name.toLowerCase(); - return arity > 0 ? `${slug}-${arity}` : slug; -} - -/** Normalize a NuGet package name for use in a URL path segment. */ -export function packageSlug(name: string): string { - return name.toLowerCase(); -} - /* ---- kind helpers ------------------------------------------------ */ export const kindOrder = [ @@ -137,15 +120,6 @@ export const kindLabels: Record = { delegate: 'Delegates', }; -export const memberKindOrder = [ - 'constructor', - 'property', - 'method', - 'field', - 'event', - 'indexer', -] as const; - export const memberKindLabels: Record = { constructor: 'Constructors', property: 'Properties', @@ -155,16 +129,6 @@ export const memberKindLabels: Record = { indexer: 'Indexers', }; -/** URL-safe plural slug for each member kind. */ -export const memberKindSlugs: Record = { - constructor: 'constructors', - property: 'properties', - method: 'methods', - field: 'fields', - event: 'events', - indexer: 'indexers', -}; - /* ---- type helpers ------------------------------------------------ */ /** Group an array of types by their `kind`, maintaining a meaningful order. */ diff --git a/src/frontend/tests/e2e/hybrid-api-docs.spec.ts b/src/frontend/tests/e2e/hybrid-api-docs.spec.ts new file mode 100644 index 0000000000..ffb5a0f05b --- /dev/null +++ b/src/frontend/tests/e2e/hybrid-api-docs.spec.ts @@ -0,0 +1,25 @@ +import { expect, test } from '@playwright/test'; + +test('built StaticHost navigation keeps API styles, search and Markdown actions usable', async ({ page, context }) => { + await context.grantPermissions(['clipboard-read', 'clipboard-write']); + await page.goto('/docs/'); + await expect(page.locator('meta[name="git-commit-id"]')).toHaveCount(1); + await page.goto('/reference/api/typescript/'); + await expect(page.locator('[data-api-search-language="typescript"]')).toBeVisible(); + const index = await page.locator('[data-api-search-index]').textContent(); + expect(index?.length).toBeGreaterThan(0); + const markdownRequest = page.waitForResponse(response => + response.url().endsWith('/reference/api/typescript.md') && response.ok()); + await page.locator('[data-page-action="copy-markdown"]:visible').first().click(); + expect(await (await markdownRequest).text()).toContain('# TypeScript API Reference'); + const link = page.locator('#ts-api-package-list a').first(); + await link.click(); + await expect(page.locator('h1')).toBeVisible(); + await expect.poll(() => page.locator('img').evaluateAll(images => images.every(image => + !(image instanceof HTMLImageElement) || !image.src.startsWith(location.origin) + || image.complete && image.naturalWidth > 0))).toBe(true); + await page.goto('/reference/api/csharp/'); + await expect(page.locator('[data-api-search-language="csharp"]')).toBeVisible(); + await page.goto('/docs/'); + await expect(page.locator('h1')).toBeVisible(); +}); diff --git a/src/frontend/tests/unit/api-markdown.vitest.test.ts b/src/frontend/tests/unit/api-markdown.vitest.test.ts index 5b32213c8a..c714be291d 100644 --- a/src/frontend/tests/unit/api-markdown.vitest.test.ts +++ b/src/frontend/tests/unit/api-markdown.vitest.test.ts @@ -90,6 +90,20 @@ const typeScriptItemRoute = getRouteModule('../../src/pages/reference/api/typesc const typeScriptMemberRoute = getRouteModule('../../src/pages/reference/api/typescript/[module]/[item]/[member].md.ts'); describe('API markdown routes', () => { + it('resolves request-time Markdown without static props and rejects unknown API URLs', async () => { + const paths = await csharpTypeRoute.getStaticPaths?.(); + const route = paths?.[0]; + if (!route) throw new Error('Expected a C# static fixture route.'); + const pathname = `/reference/api/csharp/${route.params.package}/${route.params.type}.md`; + const response = await csharpTypeRoute.GET?.({ props: {}, url: new URL(pathname, 'https://aspire.dev') }); + expect(response?.status).toBe(200); + expect(await response?.text()).toContain(`# ${route.props.type.name}`); + const missing = await csharpTypeRoute.GET?.({ + props: {}, url: new URL('/reference/api/csharp/missing/type.md', 'https://aspire.dev'), + }); + expect(missing?.status).toBe(404); + }); + it('returns markdown for the C# API index route', async () => { const markdown = await readMarkdown(csharpIndexRoute.GET?.({} as any)); diff --git a/src/frontend/tests/unit/build-performance.vitest.test.ts b/src/frontend/tests/unit/build-performance.vitest.test.ts index a956a6a0cc..f06770d1fc 100644 --- a/src/frontend/tests/unit/build-performance.vitest.test.ts +++ b/src/frontend/tests/unit/build-performance.vitest.test.ts @@ -61,7 +61,7 @@ test('frontend workflow keeps validation parallel and every shard required', asy expect(job('e2e')).toContain('--shard=${{ matrix.shard }}/2'); expect(job('e2e')).toContain('frontend-blob-report-${{ matrix.project }}-${{ matrix.shard }}'); expect(job('e2e')).toContain('frontend-test-results-${{ matrix.project }}-${{ matrix.shard }}'); - expect(job('frontend-gate')).toContain('needs: [build, validation, e2e, report]'); + expect(job('frontend-gate')).toContain('needs: [build, validation, e2e, report, hybrid-api-poc]'); expect(job('frontend-gate')).toContain('for result in "$BUILD" "$VALIDATION" "$E2E" "$REPORT"'); expect(job('frontend-gate')).toContain('if [[ "$result" != "success" ]]'); expect(job('frontend-gate')).toContain('exit 1'); diff --git a/src/frontend/tests/unit/hybrid-api-docs.vitest.test.ts b/src/frontend/tests/unit/hybrid-api-docs.vitest.test.ts new file mode 100644 index 0000000000..230ef86831 --- /dev/null +++ b/src/frontend/tests/unit/hybrid-api-docs.vitest.test.ts @@ -0,0 +1,119 @@ +import { readFileSync, readdirSync } from 'node:fs'; +import { fileURLToPath } from 'node:url'; +import { resolve } from 'node:path'; +import { mkdtemp, mkdir, readFile, rm, writeFile } from 'node:fs/promises'; +import { tmpdir } from 'node:os'; +import { pathToFileURL } from 'node:url'; +import { describe, expect, it } from 'vitest'; +import { hybridApiDocsIntegration, hybridOutputDirectory, isApiRouteComponent, isHybridApiDocs } from '../../config/hybrid-api-docs.mjs'; +import { buildApiRouteCatalog, getCSharpRouteEntries, getTypeScriptRouteEntries } from '@utils/api-route-catalog'; +import type { PackageApiDocument } from '@utils/packages'; +import type { TsApiDocument } from '@utils/ts-modules'; + +describe('build-time hybrid opt-in', () => { + it('requires an explicit supported flag value', () => { + expect(isHybridApiDocs('0')).toBe(false); + expect(isHybridApiDocs('1')).toBe(true); + expect(() => isHybridApiDocs('true')).toThrow('ASPIRE_HYBRID_API_DOCS'); + }); + + it('only opts API HTML and Markdown entrypoints out of prerendering', async () => { + const setup = hybridApiDocsIntegration({}).hooks['astro:route:setup']; + if (!setup) throw new Error('Missing route setup hook.'); + for (const component of [ + 'src/pages/reference/api/csharp/index.astro', + 'E:\\repo\\src\\pages\\reference\\api\\typescript\\[module].md.ts', + '/repo/src/pages/reference/api/typescript/[module]/[item]/index.astro', + ]) { + const route = { component, prerender: true }; + await Reflect.apply(setup, undefined, [{ route }]); + expect(route.prerender).toBe(false); + } + for (const component of ['src/content/docs/reference/api-guidance.mdx', 'src/pages/reference/samples/[sample].md.ts']) { + expect(isApiRouteComponent(component)).toBe(false); + } + }); + + it('isolates output and rejects publishing the server in a public root', () => { + const root = resolve('test-project'); + expect(hybridOutputDirectory(root, undefined)).toBe(resolve(root, 'dist-hybrid')); + expect(() => hybridOutputDirectory(root, 'public/build')).toThrow('public/'); + expect(() => hybridOutputDirectory(root, '../StaticHost/wwwroot')).toThrow('wwwroot'); + expect(() => hybridOutputDirectory(root, 'dist')).toThrow('dist-hybrid'); + expect(() => hybridOutputDirectory(root, 'src')).toThrow('dist-hybrid'); + }); + + it('writes a relocatable private manifest and static API sitemap without page props', async () => { + const directory = await mkdtemp(resolve(tmpdir(), 'aspire-hybrid-manifest-')); + try { + const root = resolve(directory, 'frontend'); + const out = resolve(root, 'dist-hybrid'); + for (const path of ['src/data/pkgs', 'src/data/ts-modules', 'dist-hybrid/client', 'dist-hybrid/server']) { + await mkdir(resolve(root, path), { recursive: true }); + } + await mkdir(resolve(directory, 'statichost/StaticHost/wwwroot/scalar'), { recursive: true }); + await writeFile(resolve(directory, 'statichost/StaticHost/wwwroot/scalar/theme.css'), 'scalar styles'); + await writeFile(resolve(out, 'client/sitemap-index.xml'), ''); + await writeFile(resolve(out, 'server/entry.mjs'), 'export const handler = () => {};'); + const integration = hybridApiDocsIntegration({ '/old/': '/new/' }); + const configure = integration.hooks['astro:config:done']; + const done = integration.hooks['astro:build:done']; + if (!configure || !done) throw new Error('Missing hybrid build hooks.'); + await Reflect.apply(configure, undefined, [{ + config: { root: pathToFileURL(root + '/'), outDir: pathToFileURL(out + '/'), site: 'https://aspire.dev' }, + }]); + await Reflect.apply(done, undefined, [{}]); + const manifest = JSON.parse(await readFile(resolve(out, 'hybrid-api-docs.json'), 'utf8')) as { + buildId: string; client: string; server: string; routes: { html: string; markdown: string }[]; + }; + expect(manifest.buildId).toMatch(/^[a-f0-9]{64}$/); + expect(manifest.client).toBe('client'); + expect(manifest.server).toBe('server/entry.mjs'); + expect(manifest.routes).toHaveLength(2); + expect(await readFile(resolve(out, 'client/sitemap-api.xml'), 'utf8')).toContain('https://aspire.dev/reference/api/typescript/'); + expect(await readFile(resolve(out, 'client/scalar/theme.css'), 'utf8')).toBe('scalar styles'); + } finally { + await rm(directory, { recursive: true, force: true }); + } + }); +}); + +describe('API route catalogue', () => { + it('retains C# generic arity and only existing member-kind groups', () => { + const pkg: PackageApiDocument = { + package: { name: 'Test.Package', version: '1', targetFramework: 'net10.0' }, + types: [{ name: 'Thing', kind: 'class', genericParameters: [{ name: 'T' }], + members: [{ name: 'Run', kind: 'method' }] }], + }; + expect(getCSharpRouteEntries(pkg).map(({ html }) => html)).toEqual([ + '/reference/api/csharp/test.package/', + '/reference/api/csharp/test.package/thing-1/', + '/reference/api/csharp/test.package/thing-1/methods/', + ]); + }); + + it('keeps collision-safe peers and last-entry Markdown aliases', () => { + const first = { name: 'Thing', capabilities: [{ name: 'Run', kind: 'Method' }] }; + const last = { name: 'Thing', capabilities: [{ name: 'Run', kind: 'Method' }] }; + const pkg: TsApiDocument = { package: { name: 'Test' }, handleTypes: [first, last] }; + const routes = getTypeScriptRouteEntries(pkg); + expect(routes.find(({ markdown }) => markdown === '/reference/api/typescript/test/thing.md')?.props.item).toBe(last); + expect(routes.find(({ markdown }) => markdown === '/reference/api/typescript/test/thing/run.md')?.props.parentType).toBe(last); + expect(routes.filter(({ html }) => html).every(({ html, markdown }) => `${html?.slice(0, -1)}.md` === markdown)).toBe(true); + }); + + it('covers both real catalogues without serializing API props into manifest routes', () => { + function documents(directory: string): T[] { + const root = fileURLToPath(new URL(`../../src/data/${directory}/`, import.meta.url)); + return readdirSync(root).filter((file) => file.endsWith('.json')) + .map((file) => JSON.parse(readFileSync(resolve(root, file), 'utf8')) as T); + } + const routes = buildApiRouteCatalog(documents('pkgs'), documents('ts-modules')); + expect(routes.filter(({ html }) => html).length).toBeGreaterThan(24000); + expect(new Set(routes.map(({ markdown }) => markdown)).size).toBe(routes.length); + expect(routes.every((route) => Object.keys(route).length === 2)).toBe(true); + expect(routes.slice(0, 2).map(({ html }) => html)).toEqual([ + '/reference/api/csharp/', '/reference/api/typescript/', + ]); + }); +}); diff --git a/src/frontend/tsconfig.json b/src/frontend/tsconfig.json index 9b6f74b162..dd393bde58 100644 --- a/src/frontend/tsconfig.json +++ b/src/frontend/tsconfig.json @@ -1,7 +1,7 @@ { "extends": "astro/tsconfigs/strict", "include": [".astro/types.d.ts", "**/*"], - "exclude": ["dist"], + "exclude": ["dist", "dist-hybrid"], "compilerOptions": { "paths": { "@assets/*": ["./src/assets/*"], diff --git a/src/statichost/StaticHost/AgentReadiness/LinkHeaderMiddleware.cs b/src/statichost/StaticHost/AgentReadiness/LinkHeaderMiddleware.cs index ce3628493f..ff35b6a958 100644 --- a/src/statichost/StaticHost/AgentReadiness/LinkHeaderMiddleware.cs +++ b/src/statichost/StaticHost/AgentReadiness/LinkHeaderMiddleware.cs @@ -59,9 +59,9 @@ public Task InvokeAsync(HttpContext context) // Resolve the markdown companion against the ORIGINAL request path, // before UseDefaultFiles rewrites it to /foo/index.html. - var companionPath = MarkdownPathMapper.TryGetMarkdownCompanion( - context.Request.Path, - _fileProvider); + var hybrid = context.Features.Get(); + var companionPath = hybrid is not null ? hybrid.MarkdownPeer + : MarkdownPathMapper.TryGetMarkdownCompanion(context.Request.Path, _fileProvider); context.Response.OnStarting(static state => { diff --git a/src/statichost/StaticHost/AgentReadiness/MarkdownNegotiationMiddleware.cs b/src/statichost/StaticHost/AgentReadiness/MarkdownNegotiationMiddleware.cs index 8dc52cde71..80bb8e5228 100644 --- a/src/statichost/StaticHost/AgentReadiness/MarkdownNegotiationMiddleware.cs +++ b/src/statichost/StaticHost/AgentReadiness/MarkdownNegotiationMiddleware.cs @@ -50,6 +50,11 @@ public MarkdownNegotiationMiddleware( public async Task InvokeAsync(HttpContext context) { + if (context.Features.Get() is not null) + { + await _next(context); + return; + } if (!ShouldHandle(context.Request)) { await _next(context); diff --git a/src/statichost/StaticHost/HybridApiDocs/HybridApiDocsArtifact.cs b/src/statichost/StaticHost/HybridApiDocs/HybridApiDocsArtifact.cs new file mode 100644 index 0000000000..12a085589b --- /dev/null +++ b/src/statichost/StaticHost/HybridApiDocs/HybridApiDocsArtifact.cs @@ -0,0 +1,105 @@ +using System.Text.Json; +using System.Text.RegularExpressions; + +namespace StaticHost.HybridApiDocs; + +internal sealed record HybridApiRoute(string? Html, string Markdown); +internal sealed record HybridRedirect(string Path, string Destination, int Status); +internal sealed record HybridApiManifest( + int SchemaVersion, string Mode, string BuildId, string Client, string Server, + string Site, HybridApiRoute[] Routes, HybridRedirect[] Redirects); + +internal sealed class HybridApiDocsArtifact +{ + private readonly Dictionary _canonical = new(StringComparer.OrdinalIgnoreCase); + private readonly Dictionary _routes = new(StringComparer.Ordinal); + private readonly Dictionary _redirects = new(StringComparer.Ordinal); + + public HybridApiManifest Manifest { get; } + public string ClientDirectory { get; } + public Uri Site { get; } + + private HybridApiDocsArtifact(string path, HybridApiManifest manifest) + { + Manifest = manifest; + if (manifest.SchemaVersion != 1 || manifest.Mode != "hybrid-api-docs" || + !Regex.IsMatch(manifest.BuildId ?? "", "^[a-f0-9]{64}$") || + manifest.Routes is null || manifest.Redirects is null || + !Uri.TryCreate(manifest.Site, UriKind.Absolute, out var site) || + site.Scheme is not ("http" or "https")) + { + throw new InvalidOperationException("Incompatible hybrid API documentation manifest."); + } + Site = site; + var root = Path.GetDirectoryName(Path.GetFullPath(path))!; + ClientDirectory = ResolveArtifactPath(root, manifest.Client); + var server = ResolveArtifactPath(root, manifest.Server); + if (!Directory.Exists(ClientDirectory) || !File.Exists(server) || + server.StartsWith(ClientDirectory + Path.DirectorySeparatorChar, StringComparison.OrdinalIgnoreCase)) + { + throw new InvalidOperationException("The hybrid artifact must contain a static client and a private server entrypoint."); + } + foreach (var route in manifest.Routes) + { + if (route.Html is not null) + { + AddRoute(route.Html, route); + _canonical.TryAdd(route.Html.TrimEnd('/'), route.Html); + _canonical.TryAdd(route.Html + "index.html", route.Html); + } + AddRoute(route.Markdown, route); + } + foreach (var redirect in manifest.Redirects) + { + ValidatePath(redirect.Path); + ValidatePath(redirect.Destination); + if (redirect.Status is not (301 or 302 or 303 or 307 or 308)) + throw new InvalidOperationException("Invalid hybrid redirect status."); + _redirects.Add(redirect.Path, redirect); + _canonical.TryAdd(redirect.Path, redirect.Path); + _canonical.TryAdd(redirect.Path.TrimEnd('/'), redirect.Path); + } + } + + public static HybridApiDocsArtifact Load(string path) + { + if (!File.Exists(path)) + throw new InvalidOperationException($"Build or download the opted-in CI artifact before starting StaticHost: {path}"); + var manifest = JsonSerializer.Deserialize( + File.ReadAllText(path), new JsonSerializerOptions(JsonSerializerDefaults.Web)) + ?? throw new InvalidOperationException("Empty hybrid API documentation manifest."); + return new HybridApiDocsArtifact(path, manifest); + } + + public bool TryCanonical(string path, out string? canonical) => _canonical.TryGetValue(path, out canonical); + public bool TryRoute(string path, out HybridApiRoute? route) => _routes.TryGetValue(path, out route); + public bool TryRedirect(string path, out HybridRedirect? redirect) => _redirects.TryGetValue(path, out redirect); + + private void AddRoute(string path, HybridApiRoute route) + { + ValidatePath(path); + if (!path.StartsWith("/reference/api/", StringComparison.Ordinal) || + !(path.EndsWith('/') || path.EndsWith(".md", StringComparison.Ordinal))) + throw new InvalidOperationException($"Invalid API catalogue path: {path}"); + _routes.Add(path, route); + _canonical.TryAdd(path, path); + } + + private static void ValidatePath(string path) + { + if (string.IsNullOrEmpty(path) || !path.StartsWith('/') || path.StartsWith("//") || + path.Contains('\\') || path.Contains('#') || path.Contains('?') || + path.Split('/').Any(segment => segment is "." or "..")) + throw new InvalidOperationException($"Invalid hybrid artifact URL path: {path}"); + } + + private static string ResolveArtifactPath(string root, string path) + { + if (string.IsNullOrWhiteSpace(path) || Path.IsPathRooted(path)) + throw new InvalidOperationException("Hybrid artifact paths must be relative."); + var full = Path.GetFullPath(Path.Combine(root, path)); + if (!full.StartsWith(root + Path.DirectorySeparatorChar, StringComparison.OrdinalIgnoreCase)) + throw new InvalidOperationException("Hybrid artifact path escapes its root."); + return full; + } +} diff --git a/src/statichost/StaticHost/HybridApiDocs/HybridApiDocsExtensions.cs b/src/statichost/StaticHost/HybridApiDocs/HybridApiDocsExtensions.cs new file mode 100644 index 0000000000..b71b1cf547 --- /dev/null +++ b/src/statichost/StaticHost/HybridApiDocs/HybridApiDocsExtensions.cs @@ -0,0 +1,45 @@ +using System.Net; + +namespace StaticHost.HybridApiDocs; + +internal static class HybridApiDocsExtensions +{ + public static void AddHybridApiDocs(this IServiceCollection services, + HybridApiDocsArtifact artifact, string? rendererUrl) + { + if (!Uri.TryCreate(rendererUrl, UriKind.Absolute, out var renderer) || + renderer.Scheme is not ("http" or "https")) + throw new InvalidOperationException("HybridApiDocs:RendererUrl must specify the private Astro worker endpoint."); + services.AddSingleton(artifact); + services.AddHttpClient(client => + { + client.BaseAddress = renderer; + client.Timeout = Timeout.InfiniteTimeSpan; + client.MaxResponseContentBufferSize = HybridApiDocsRenderer.MaximumBodySize; + }).ConfigurePrimaryHttpMessageHandler(() => new SocketsHttpHandler + { + UseProxy = false, UseCookies = false, AllowAutoRedirect = false, + AutomaticDecompression = DecompressionMethods.None, + ConnectTimeout = TimeSpan.FromSeconds(5), + }); + services.AddOutputCache(options => + { + options.SizeLimit = 128 * 1024 * 1024; + options.MaximumBodySize = HybridApiDocsRenderer.MaximumBodySize; + options.AddPolicy("HybridApiDocs", policy => policy + .Expire(TimeSpan.FromMinutes(30)) + .VaryByValue("build", artifact.Manifest.BuildId) + .VaryByValue(context => new KeyValuePair("representation", + context.Features.Get()?.Representation ?? "none")) + .AddPolicy()); + }); + } + + public static void UseHybridApiDocsRouting(this IApplicationBuilder app) + => app.UseMiddleware(); + + public static void MapHybridApiDocs(this IEndpointRouteBuilder app) + => app.MapMethods("/reference/api/{**path}", ["GET", "HEAD"], + (HttpContext context, HybridApiDocsRenderer renderer) => renderer.RenderAsync(context)) + .CacheOutput("HybridApiDocs"); +} diff --git a/src/statichost/StaticHost/HybridApiDocs/HybridApiDocsRenderer.cs b/src/statichost/StaticHost/HybridApiDocs/HybridApiDocsRenderer.cs new file mode 100644 index 0000000000..d6161ee533 --- /dev/null +++ b/src/statichost/StaticHost/HybridApiDocs/HybridApiDocsRenderer.cs @@ -0,0 +1,97 @@ +using System.Net; +using Microsoft.AspNetCore.OutputCaching; + +namespace StaticHost.HybridApiDocs; + +internal sealed class HybridApiDocsRenderer(HttpClient client, HybridApiDocsArtifact artifact, + ILogger logger) +{ + internal const long MaximumBodySize = 64 * 1024 * 1024; + private static readonly HashSet ExcludedHeaders = new(StringComparer.OrdinalIgnoreCase) + { + "Connection", "Keep-Alive", "Transfer-Encoding", "Content-Length", "TE", "Trailer", + "Upgrade", "Proxy-Authenticate", "Proxy-Authorization", "X-Aspire-Build-Id", + }; + + public async Task RenderAsync(HttpContext context) + { + var selection = context.Features.Get(); + if (selection is null) + { + context.Response.StatusCode = StatusCodes.Status404NotFound; + return; + } + using var timeout = CancellationTokenSource.CreateLinkedTokenSource(context.RequestAborted); + timeout.CancelAfter(TimeSpan.FromSeconds(30)); + using var request = new HttpRequestMessage(HttpMethod.Get, + selection.RendererPath + context.Request.QueryString); + request.Headers.Host = artifact.Site.Authority; + request.Headers.TryAddWithoutValidation("X-Forwarded-Host", artifact.Site.Authority); + request.Headers.TryAddWithoutValidation("X-Forwarded-Proto", artifact.Site.Scheme); + try + { + using var response = await client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, timeout.Token); + if (!response.Headers.TryGetValues("X-Aspire-Build-Id", out var ids) || + ids.SingleOrDefault() != artifact.Manifest.BuildId) + throw new HttpRequestException("The renderer and StaticHost have different build identities."); + await response.Content.LoadIntoBufferAsync(MaximumBodySize, timeout.Token); + var body = await response.Content.ReadAsByteArrayAsync(timeout.Token); + var control = response.Headers.CacheControl; + selection.Cacheable = !(control?.Private == true || control?.NoStore == true || control?.NoCache == true); + context.Response.StatusCode = (int)response.StatusCode; + var excluded = new HashSet(ExcludedHeaders, StringComparer.OrdinalIgnoreCase); + foreach (var value in response.Headers.Connection) excluded.Add(value); + foreach (var header in response.Headers.Concat(response.Content.Headers)) + { + if (!excluded.Contains(header.Key)) context.Response.Headers[header.Key] = header.Value.ToArray(); + } + if (selection.Representation == "markdown-negotiated") + { + context.Response.Headers.CacheControl = "private, max-age=0, must-revalidate"; + context.Response.Headers.Vary = "Accept"; + } + else if (!context.Response.Headers.ContainsKey("Cache-Control")) + context.Response.Headers.CacheControl = "public, max-age=0, must-revalidate"; + context.Response.Headers["X-Aspire-Build-Id"] = artifact.Manifest.BuildId; + context.Response.ContentLength = body.Length; + if (!HttpMethods.IsHead(context.Request.Method)) + await context.Response.Body.WriteAsync(body, context.RequestAborted); + logger.LogInformation("Rendered hybrid API {Path} ({Bytes} bytes) from build {BuildId}", + selection.RendererPath, body.Length, artifact.Manifest.BuildId); + } + catch (OperationCanceledException) when (context.RequestAborted.IsCancellationRequested) + { + selection.Cacheable = false; + context.Abort(); + } + catch (Exception error) when (error is HttpRequestException or IOException or OperationCanceledException) + { + selection.Cacheable = false; + logger.LogError(error, "Hybrid API rendering failed for {Path}", selection.RendererPath); + if (context.Response.HasStarted) + { + context.Abort(); + return; + } + context.Response.StatusCode = error is OperationCanceledException + ? StatusCodes.Status504GatewayTimeout : StatusCodes.Status502BadGateway; + context.Response.Headers.CacheControl = "no-store"; + } + } +} + +internal sealed class HybridApiDocsCachePolicy : IOutputCachePolicy +{ + public ValueTask CacheRequestAsync(OutputCacheContext context, CancellationToken cancellationToken) + => ValueTask.CompletedTask; + + public ValueTask ServeFromCacheAsync(OutputCacheContext context, CancellationToken cancellationToken) + => ValueTask.CompletedTask; + + public ValueTask ServeResponseAsync(OutputCacheContext context, CancellationToken cancellationToken) + { + if (context.HttpContext.Features.Get()?.Cacheable != true) + context.AllowCacheStorage = false; + return ValueTask.CompletedTask; + } +} diff --git a/src/statichost/StaticHost/HybridApiDocs/HybridApiDocsRoutingMiddleware.cs b/src/statichost/StaticHost/HybridApiDocs/HybridApiDocsRoutingMiddleware.cs new file mode 100644 index 0000000000..fa314e013e --- /dev/null +++ b/src/statichost/StaticHost/HybridApiDocs/HybridApiDocsRoutingMiddleware.cs @@ -0,0 +1,59 @@ +using Microsoft.AspNetCore.Http.Extensions; + +namespace StaticHost.HybridApiDocs; + +internal sealed record HybridApiDocsRequest(string RendererPath, string Representation, string? MarkdownPeer) +{ + public bool Cacheable { get; set; } = true; +} + +internal sealed class HybridApiDocsRoutingMiddleware(RequestDelegate next, HybridApiDocsArtifact artifact) +{ + public async Task InvokeAsync(HttpContext context) + { + var path = context.Request.Path.Value ?? "/"; + if (artifact.TryCanonical(path, out var canonical) && canonical != path) + { + context.Response.Redirect(UriHelper.BuildRelative( + context.Request.PathBase, new PathString(canonical), context.Request.QueryString), + permanent: true, preserveMethod: true); + return; + } + if (artifact.TryRedirect(path, out var redirect)) + { + context.Response.StatusCode = redirect!.Status; + context.Response.Headers.Location = redirect.Destination + context.Request.QueryString; + return; + } + if (!context.Request.Path.StartsWithSegments("/reference/api")) + { + await next(context); + return; + } + if (!HttpMethods.IsGet(context.Request.Method) && !HttpMethods.IsHead(context.Request.Method)) + { + context.Response.StatusCode = StatusCodes.Status405MethodNotAllowed; + context.Response.Headers.Allow = "GET, HEAD"; + return; + } + if (!artifact.TryRoute(path, out var route)) + { + context.Response.StatusCode = StatusCodes.Status404NotFound; + context.Response.Headers.CacheControl = "no-store"; + return; + } + var isMarkdown = path.EndsWith(".md", StringComparison.Ordinal); + var negotiation = AcceptHeaderParser.Negotiate(context.Request.Headers.Accept); + var negotiated = !isMarkdown && negotiation.PrefersMarkdown; + if (!isMarkdown && !negotiated && !negotiation.AcceptsHtml) + { + context.Response.StatusCode = StatusCodes.Status406NotAcceptable; + return; + } + context.Features.Set(new HybridApiDocsRequest( + negotiated ? route!.Markdown : path, + negotiated ? "markdown-negotiated" : isMarkdown ? "markdown" : "html", + isMarkdown || negotiated ? null : route!.Markdown)); + await next(context); + } +} diff --git a/src/statichost/StaticHost/Program.cs b/src/statichost/StaticHost/Program.cs index 9463687b5e..1ec550f8c3 100644 --- a/src/statichost/StaticHost/Program.cs +++ b/src/statichost/StaticHost/Program.cs @@ -1,6 +1,14 @@ using Scalar.AspNetCore; +using StaticHost.HybridApiDocs; -var builder = WebApplication.CreateBuilder(args); +var hybridArtifactPath = new ConfigurationBuilder() + .AddEnvironmentVariables().AddCommandLine(args).Build()["HybridApiDocs:ArtifactPath"]; +var hybridArtifact = hybridArtifactPath is null ? null : HybridApiDocsArtifact.Load(hybridArtifactPath); +var builder = WebApplication.CreateBuilder(new WebApplicationOptions +{ + Args = args, + WebRootPath = hybridArtifact?.ClientDirectory, +}); builder.AddServiceDefaults(); builder.AddForwardedClientIp(); @@ -13,6 +21,11 @@ builder.AddLiveStatus(); +if (hybridArtifact is not null) +{ + builder.Services.AddHybridApiDocs(hybridArtifact, builder.Configuration["HybridApiDocs:RendererUrl"]); +} + builder.Services.AddHsts(options => { options.Preload = true; @@ -39,6 +52,7 @@ app.UseHttpsRedirection(); // Resolve request casing before any middleware rewrites or matches the static path. +if (hybridArtifact is not null) app.UseHybridApiDocsRouting(); app.UseCanonicalPathRedirects(); // Agent-readiness middlewares MUST run before UseDefaultFiles + UseRouting: @@ -53,6 +67,7 @@ // add routing after default files, so the default file middleware can modify the path first app.UseRouting(); +if (hybridArtifact is not null) app.UseOutputCache(); app.UseStatusCodePages(async context => { @@ -130,5 +145,6 @@ }); app.MapStaticAssets(); +if (hybridArtifact is not null) app.MapHybridApiDocs(); await app.RunAsync(); diff --git a/src/statichost/StaticHost/StaticHost.csproj b/src/statichost/StaticHost/StaticHost.csproj index f6e5fdfb8e..69a1960f97 100644 --- a/src/statichost/StaticHost/StaticHost.csproj +++ b/src/statichost/StaticHost/StaticHost.csproj @@ -7,6 +7,7 @@ false true noble-chiseled + obj/$(Configuration)/hybrid/ false diff --git a/tests/Aspire.Dev.AppHost.Tests/HybridApiDocsConfigurationTests.cs b/tests/Aspire.Dev.AppHost.Tests/HybridApiDocsConfigurationTests.cs new file mode 100644 index 0000000000..9d89515c6c --- /dev/null +++ b/tests/Aspire.Dev.AppHost.Tests/HybridApiDocsConfigurationTests.cs @@ -0,0 +1,15 @@ +namespace Aspire.Dev.AppHost.Tests; + +public sealed class HybridApiDocsConfigurationTests +{ + [Theory] + [InlineData(null, false)] + [InlineData("0", false)] + [InlineData("1", true)] + public void BuildModeRequiresExplicitOptIn(string? value, bool expected) + => Assert.Equal(expected, HybridApiDocsExtensions.IsHybridApiDocsEnabled(value)); + + [Fact] + public void InvalidBuildModeFailsClearly() + => Assert.Throws(() => HybridApiDocsExtensions.IsHybridApiDocsEnabled("true")); +} diff --git a/tests/StaticHost.Tests/HybridApiDocsTests.cs b/tests/StaticHost.Tests/HybridApiDocsTests.cs new file mode 100644 index 0000000000..5f2f129ecf --- /dev/null +++ b/tests/StaticHost.Tests/HybridApiDocsTests.cs @@ -0,0 +1,235 @@ +using System.Collections.Concurrent; +using System.Net; +using System.Text.Json; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.TestHost; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using StaticHost.AgentReadiness; +using StaticHost.HybridApiDocs; + +namespace StaticHost.Tests; + +public sealed class HybridApiDocsTests +{ + [Fact] + public async Task CachesSuccessfulResponsesAndCoalescesConcurrentMisses() + { + await using var host = await HybridHost.StartAsync(); + var responses = await Task.WhenAll(Enumerable.Range(0, 20) + .Select(_ => host.Client.GetStringAsync("/reference/api/demo/"))); + Assert.All(responses, body => Assert.Equal("html:demo", body)); + Assert.Equal(1, host.Renderer.Calls["/reference/api/demo/"]); + Assert.Equal("html:demo", await host.Client.GetStringAsync("/reference/api/demo/")); + Assert.Equal(1, host.Renderer.Calls["/reference/api/demo/"]); + } + + [Theory] + [InlineData(true)] + [InlineData(false)] + public async Task KeepsMarkdownAndHtmlHeadersIsolatedInEitherOrder(bool negotiatedFirst) + { + await using var host = await HybridHost.StartAsync(); + async Task CheckNegotiated() + { + using var request = new HttpRequestMessage(HttpMethod.Get, "/reference/api/demo/"); + request.Headers.Accept.ParseAdd("text/markdown"); + using var response = await host.Client.SendAsync(request); + Assert.Equal("markdown:demo", await response.Content.ReadAsStringAsync()); + Assert.True(response.Headers.CacheControl!.Private); + Assert.Contains("Accept", response.Headers.Vary); + } + if (negotiatedFirst) await CheckNegotiated(); + using var markdown = await host.Client.GetAsync("/reference/api/demo.md"); + Assert.Equal("markdown:demo", await markdown.Content.ReadAsStringAsync()); + Assert.False(markdown.Headers.CacheControl!.Private); + using var html = await host.Client.GetAsync("/reference/api/demo/"); + Assert.Equal("html:demo", await html.Content.ReadAsStringAsync()); + Assert.Contains("text/html", html.Content.Headers.ContentType!.ToString()); + Assert.Contains("/reference/api/demo.md", string.Join("", html.Headers.GetValues("Link"))); + if (!negotiatedFirst) await CheckNegotiated(); + await CheckNegotiated(); + Assert.Equal("html:demo", await host.Client.GetStringAsync("/reference/api/demo/")); + } + + [Fact] + public async Task HeadDoesNotPoisonGetAndUsesTheCompleteContentLength() + { + await using var host = await HybridHost.StartAsync(); + using var head = await host.Client.SendAsync(new HttpRequestMessage(HttpMethod.Head, "/reference/api/demo/")); + Assert.Empty(await head.Content.ReadAsByteArrayAsync()); + Assert.Equal("html:demo".Length, head.Content.Headers.ContentLength); + Assert.Equal("html:demo", await host.Client.GetStringAsync("/reference/api/demo/")); + } + + [Theory] + [InlineData("failure", HttpStatusCode.ServiceUnavailable)] + [InlineData("broken", HttpStatusCode.BadGateway)] + [InlineData("mismatch", HttpStatusCode.BadGateway)] + [InlineData("oversize", HttpStatusCode.BadGateway)] + public async Task DoesNotCacheRendererErrors(string page, HttpStatusCode expected) + { + await using var host = await HybridHost.StartAsync(); + for (var index = 0; index < 2; index++) + { + using var response = await host.Client.GetAsync($"/reference/api/{page}/"); + Assert.Equal(expected, response.StatusCode); + } + Assert.Equal(2, host.Renderer.Calls[$"/reference/api/{page}/"]); + } + + [Theory] + [InlineData("private")] + [InlineData("cookie")] + public async Task DoesNotCachePrivateOrCookieSettingResponses(string page) + { + await using var host = await HybridHost.StartAsync(); + await host.Client.GetStringAsync($"/reference/api/{page}/"); + await host.Client.GetStringAsync($"/reference/api/{page}/"); + Assert.Equal(2, host.Renderer.Calls[$"/reference/api/{page}/"]); + } + + [Fact] + public async Task DoesNotCacheAuthenticatedRequests() + { + await using var host = await HybridHost.StartAsync(); + host.Client.DefaultRequestHeaders.Authorization = new("Bearer", "test"); + await host.Client.GetStringAsync("/reference/api/demo/"); + await host.Client.GetStringAsync("/reference/api/demo/"); + Assert.Equal(2, host.Renderer.Calls["/reference/api/demo/"]); + } + + [Fact] + public async Task BuffersLargeResponsesAndKeepsStaticAndWarmOutputAvailableWithoutWorker() + { + await using var host = await HybridHost.StartAsync(); + using var large = await host.Client.GetAsync("/reference/api/large/"); + var body = await large.Content.ReadAsByteArrayAsync(); + Assert.True(body.Length >= 13_621_124); + Assert.Equal(body.Length, large.Content.Headers.ContentLength); + Assert.Empty(large.Headers.TransferEncoding); + await host.Client.GetStringAsync("/reference/api/demo/"); + host.Renderer.Offline = true; + Assert.Equal("static guide", await host.Client.GetStringAsync("/guide/")); + Assert.Equal("html:demo", await host.Client.GetStringAsync("/reference/api/demo/")); + using var cold = await host.Client.GetAsync("/reference/api/cold/"); + Assert.Equal(HttpStatusCode.BadGateway, cold.StatusCode); + } + + [Fact] + public async Task CanonicalizesAndRedirectsWithoutInvokingWorker() + { + await using var host = await HybridHost.StartAsync(); + using var canonical = await host.Client.GetAsync("/REFERENCE/API/DEMO"); + Assert.Equal(HttpStatusCode.PermanentRedirect, canonical.StatusCode); + Assert.Equal("/reference/api/demo/", canonical.Headers.Location!.OriginalString); + using var redirect = await host.Client.GetAsync("/old-guide/?a=1"); + Assert.Equal(HttpStatusCode.Found, redirect.StatusCode); + Assert.Equal("/guide/?a=1", redirect.Headers.Location!.OriginalString); + using var missing = await host.Client.GetAsync("/reference/api/not-a-page/"); + Assert.Equal(HttpStatusCode.NotFound, missing.StatusCode); + using var method = await host.Client.PostAsync("/reference/api/demo/", null); + Assert.Equal(HttpStatusCode.MethodNotAllowed, method.StatusCode); + Assert.Empty(host.Renderer.Calls); + } + + [Fact] + public void RejectsMissingOrEscapingArtifacts() + { + using var root = new TempWebRoot(); + Assert.Throws(() => HybridApiDocsArtifact.Load(Path.Combine(root.Path, "missing.json"))); + root.WriteFile("hybrid.json", JsonSerializer.Serialize(new HybridApiManifest( + 1, "hybrid-api-docs", new string('a', 64), "../escape", "server/entry.mjs", + "https://aspire.dev", [], []), new JsonSerializerOptions(JsonSerializerDefaults.Web))); + Assert.Throws(() => HybridApiDocsArtifact.Load(Path.Combine(root.Path, "hybrid.json"))); + } +} + +internal sealed class HybridHost : IAsyncDisposable +{ + private readonly WebApplication _app; + private readonly TempWebRoot _root; + public HttpClient Client { get; } + public TestApiRenderer Renderer { get; } + + private HybridHost(WebApplication app, TempWebRoot root, TestApiRenderer renderer) + { + _app = app; + _root = root; + Renderer = renderer; + Client = app.GetTestClient(); + } + + public static async Task StartAsync() + { + var root = new TempWebRoot(); + root.WriteFile("client/guide/index.html", "static guide"); + root.WriteFile("server/entry.mjs", "private server"); + var pages = new[] { "demo", "private", "cookie", "failure", "broken", "mismatch", "oversize", "large", "cold" }; + root.WriteFile("hybrid.json", JsonSerializer.Serialize(new HybridApiManifest( + 1, "hybrid-api-docs", new string('a', 64), "client", "server/entry.mjs", "https://aspire.dev", + pages.Select(page => new HybridApiRoute($"/reference/api/{page}/", $"/reference/api/{page}.md")).ToArray(), + [new("/old-guide/", "/guide/", 302)]), new JsonSerializerOptions(JsonSerializerDefaults.Web))); + var artifact = HybridApiDocsArtifact.Load(Path.Combine(root.Path, "hybrid.json")); + var builder = WebApplication.CreateBuilder(new WebApplicationOptions { WebRootPath = artifact.ClientDirectory }); + builder.Logging.ClearProviders(); + builder.WebHost.UseTestServer(); + builder.Services.AddHybridApiDocs(artifact, "http://renderer/"); + var renderer = new TestApiRenderer(); + builder.Services.AddHttpClient().ConfigurePrimaryHttpMessageHandler(() => renderer); + var app = builder.Build(); + app.UseHybridApiDocsRouting(); + app.UseAgentReadiness(); + app.UseDefaultFiles(); + app.UseStaticFiles(); + app.UseRouting(); + app.UseOutputCache(); + app.MapHybridApiDocs(); + await app.StartAsync(); + return new HybridHost(app, root, renderer); + } + + public async ValueTask DisposeAsync() + { + Client.Dispose(); + await _app.DisposeAsync(); + _root.Dispose(); + } +} + +internal sealed class TestApiRenderer : HttpMessageHandler +{ + public ConcurrentDictionary Calls { get; } = new(); + public bool Offline { get; set; } + + protected override async Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) + { + var path = request.RequestUri!.AbsolutePath; + Calls.AddOrUpdate(path, 1, (_, count) => count + 1); + if (Offline) throw new HttpRequestException("Renderer unavailable."); + await Task.Delay(30, cancellationToken); + var page = path.Split('/').Last(segment => segment.Length > 0).Replace(".md", ""); + var response = new HttpResponseMessage(page == "failure" ? HttpStatusCode.ServiceUnavailable : HttpStatusCode.OK); + response.Headers.Add("X-Aspire-Build-Id", new string(page == "mismatch" ? 'b' : 'a', 64)); + response.Content = page switch + { + "broken" => new BrokenContent(), + "oversize" => new ByteArrayContent(new byte[HybridApiDocsRenderer.MaximumBodySize + 1]), + "large" => new ByteArrayContent(new byte[13_621_124]), + _ => new StringContent((path.EndsWith(".md") ? "markdown:" : "html:") + page), + }; + response.Content.Headers.ContentType = new(path.EndsWith(".md") ? "text/markdown" : "text/html"); + if (page == "cookie") response.Headers.Add("Set-Cookie", "test=value"); + response.Headers.CacheControl = page == "private" + ? new() { Private = true, NoStore = true } : new() { Public = true }; + return response; + } + + private sealed class BrokenContent : HttpContent + { + protected override bool TryComputeLength(out long length) { length = 0; return false; } + protected override Task SerializeToStreamAsync(Stream stream, TransportContext? context) + => throw new IOException("Interrupted renderer body."); + } +} From 755965e8efab35a75048b1db1f0a8cd20513cbcd Mon Sep 17 00:00:00 2001 From: David Pine <7679720+IEvangelist@users.noreply.github.com> Date: Sun, 11 Oct 2026 09:20:55 -0500 Subject: [PATCH 02/28] Preserve hybrid Markdown paths and verify local renderer wiring Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .github/workflows/hybrid-api-docs-poc.yml | 1 + src/frontend/astro.config.mjs | 1 + src/frontend/scripts/test-hybrid-host.mjs | 1 + src/frontend/src/middleware.ts | 5 ++- .../tests/unit/hybrid-api-docs.vitest.test.ts | 13 ++++++ .../HybridApiDocs/HybridApiDocsArtifact.cs | 1 + .../HybridApiDocsConfigurationTests.cs | 41 +++++++++++++++++++ tests/StaticHost.Tests/HybridApiDocsTests.cs | 18 ++++++++ 8 files changed, 80 insertions(+), 1 deletion(-) diff --git a/.github/workflows/hybrid-api-docs-poc.yml b/.github/workflows/hybrid-api-docs-poc.yml index e6eec574ce..1d37322fb2 100644 --- a/.github/workflows/hybrid-api-docs-poc.yml +++ b/.github/workflows/hybrid-api-docs-poc.yml @@ -83,6 +83,7 @@ jobs: path: | src/frontend/hybrid-output-results.json src/frontend/hybrid-host-results.json + src/frontend/hybrid-host-processes.log ${{ runner.temp }}/hybrid-poc if-no-files-found: warn retention-days: 7 diff --git a/src/frontend/astro.config.mjs b/src/frontend/astro.config.mjs index 35d1c9fe24..724ff3ae50 100644 --- a/src/frontend/astro.config.mjs +++ b/src/frontend/astro.config.mjs @@ -66,6 +66,7 @@ export default defineConfig({ define: { // Resolve filesystem-backed redirects before prerender modules are bundled. __ASPIRE_REDIRECT_PATHS__: JSON.stringify(Object.keys(redirects)), + __ASPIRE_HYBRID_API_DOCS__: JSON.stringify(hybridApiDocs), }, ...(staticHostUrl ? { diff --git a/src/frontend/scripts/test-hybrid-host.mjs b/src/frontend/scripts/test-hybrid-host.mjs index ce6607cb2f..42fdc639da 100644 --- a/src/frontend/scripts/test-hybrid-host.mjs +++ b/src/frontend/scripts/test-hybrid-host.mjs @@ -109,4 +109,5 @@ try { console.log(JSON.stringify(results, null, 2)); } finally { for (const child of children) if (child.exitCode === null) child.kill(); + await writeFile(resolve(root, 'hybrid-host-processes.log'), output); } diff --git a/src/frontend/src/middleware.ts b/src/frontend/src/middleware.ts index 8883c4c8de..0afdb53032 100644 --- a/src/frontend/src/middleware.ts +++ b/src/frontend/src/middleware.ts @@ -1,6 +1,8 @@ import { defineMiddleware } from 'astro:middleware'; import { stripApiReferenceLocale } from './utils/api-reference-routes'; +declare const __ASPIRE_HYBRID_API_DOCS__: boolean; + const nestedApiMarkdownPattern = /^\/reference\/(?:api\/(?:csharp|typescript)|samples)\/.+\.md$/; const cliConfigSchemaPattern = /^\/reference\/cli\/configuration\/schema\/[^/]+\.json$/; @@ -28,7 +30,8 @@ export const onRequest = defineMiddleware((context, next) => { return redirect(`${canonicalApiPath}${search}`); } - if (nestedApiMarkdownPattern.test(pathname) || cliConfigSchemaPattern.test(pathname)) { + const hybridApiMarkdown = __ASPIRE_HYBRID_API_DOCS__ && pathname.startsWith('/reference/api/'); + if ((!hybridApiMarkdown && nestedApiMarkdownPattern.test(pathname)) || cliConfigSchemaPattern.test(pathname)) { return redirect(`${pathname}/${search}`); } } diff --git a/src/frontend/tests/unit/hybrid-api-docs.vitest.test.ts b/src/frontend/tests/unit/hybrid-api-docs.vitest.test.ts index 230ef86831..a6f9fb27f5 100644 --- a/src/frontend/tests/unit/hybrid-api-docs.vitest.test.ts +++ b/src/frontend/tests/unit/hybrid-api-docs.vitest.test.ts @@ -9,6 +9,7 @@ import { hybridApiDocsIntegration, hybridOutputDirectory, isApiRouteComponent, i import { buildApiRouteCatalog, getCSharpRouteEntries, getTypeScriptRouteEntries } from '@utils/api-route-catalog'; import type { PackageApiDocument } from '@utils/packages'; import type { TsApiDocument } from '@utils/ts-modules'; +import { onRequest } from '../../src/middleware'; describe('build-time hybrid opt-in', () => { it('requires an explicit supported flag value', () => { @@ -76,6 +77,18 @@ describe('build-time hybrid opt-in', () => { await rm(directory, { recursive: true, force: true }); } }); + + it('keeps hybrid Markdown URLs extension-based without changing normal prerendered endpoints', async () => { + const url = 'https://aspire.dev/reference/api/typescript/aspire.hosting/item.md'; + const response: Response = await Reflect.apply(onRequest, undefined, [{ + request: new Request(url), isPrerendered: false, + }, () => Promise.resolve(new Response('Markdown endpoint'))]); + expect(response.status).toBe(isHybridApiDocs() ? 200 : 308); + const staticResponse: Response = await Reflect.apply(onRequest, undefined, [{ + request: new Request(url), isPrerendered: true, + }, () => Promise.resolve(new Response('Markdown endpoint'))]); + expect(staticResponse.status).toBe(200); + }); }); describe('API route catalogue', () => { diff --git a/src/statichost/StaticHost/HybridApiDocs/HybridApiDocsArtifact.cs b/src/statichost/StaticHost/HybridApiDocs/HybridApiDocsArtifact.cs index 12a085589b..a9e17477f3 100644 --- a/src/statichost/StaticHost/HybridApiDocs/HybridApiDocsArtifact.cs +++ b/src/statichost/StaticHost/HybridApiDocs/HybridApiDocsArtifact.cs @@ -48,6 +48,7 @@ site.Scheme is not ("http" or "https")) _canonical.TryAdd(route.Html + "index.html", route.Html); } AddRoute(route.Markdown, route); + _canonical.TryAdd(route.Markdown + "/", route.Markdown); } foreach (var redirect in manifest.Redirects) { diff --git a/tests/Aspire.Dev.AppHost.Tests/HybridApiDocsConfigurationTests.cs b/tests/Aspire.Dev.AppHost.Tests/HybridApiDocsConfigurationTests.cs index 9d89515c6c..c944d6f8dd 100644 --- a/tests/Aspire.Dev.AppHost.Tests/HybridApiDocsConfigurationTests.cs +++ b/tests/Aspire.Dev.AppHost.Tests/HybridApiDocsConfigurationTests.cs @@ -1,3 +1,5 @@ +using Aspire.Hosting; + namespace Aspire.Dev.AppHost.Tests; public sealed class HybridApiDocsConfigurationTests @@ -12,4 +14,43 @@ public void BuildModeRequiresExplicitOptIn(string? value, bool expected) [Fact] public void InvalidBuildModeFailsClearly() => Assert.Throws(() => HybridApiDocsExtensions.IsHybridApiDocsEnabled("true")); + + [Fact] + public async Task LocalGraphUsesPrivateWorkerAndEndpointReferences() + { + var directory = Path.Combine(Path.GetTempPath(), $"aspire-hybrid-graph-{Guid.NewGuid():N}"); + Directory.CreateDirectory(Path.Combine(directory, "dist-hybrid")); + try + { + File.WriteAllText(Path.Combine(directory, "dist-hybrid", "hybrid-api-docs.json"), + """{"mode":"hybrid-api-docs"}"""); + var builder = DistributedApplication.CreateBuilder(new DistributedApplicationOptions + { + DisableDashboard = true, + }); + var website = builder.AddProject("aspiredev"); + website.WithHybridApiDocs(builder, directory); + await using var app = builder.Build(); + var worker = Assert.Single(builder.Resources.OfType()); + Assert.Equal("api-docs", worker.Name); + Assert.All(worker.Annotations.OfType(), + endpoint => Assert.False(endpoint.IsExternal)); + + var environment = new Dictionary(); + var context = new Aspire.Hosting.ApplicationModel.EnvironmentCallbackContext( + builder.ExecutionContext, website.Resource, environment, CancellationToken.None); + foreach (var annotation in website.Resource.Annotations + .OfType()) + { + await annotation.Callback(context); + } + Assert.IsType(environment["HybridApiDocs__RendererUrl"]); + Assert.Equal(Path.Combine(directory, "dist-hybrid", "hybrid-api-docs.json"), + environment["HybridApiDocs__ArtifactPath"]); + } + finally + { + Directory.Delete(directory, recursive: true); + } + } } diff --git a/tests/StaticHost.Tests/HybridApiDocsTests.cs b/tests/StaticHost.Tests/HybridApiDocsTests.cs index 5f2f129ecf..bad933d699 100644 --- a/tests/StaticHost.Tests/HybridApiDocsTests.cs +++ b/tests/StaticHost.Tests/HybridApiDocsTests.cs @@ -100,6 +100,19 @@ public async Task DoesNotCacheAuthenticatedRequests() Assert.Equal(2, host.Renderer.Calls["/reference/api/demo/"]); } + [Fact] + public async Task RendererTimeoutsAreExplicitAndNotCached() + { + await using var host = await HybridHost.StartAsync(); + host.Renderer.Timeout = true; + for (var index = 0; index < 2; index++) + { + using var response = await host.Client.GetAsync("/reference/api/demo/"); + Assert.Equal(HttpStatusCode.GatewayTimeout, response.StatusCode); + } + Assert.Equal(2, host.Renderer.Calls["/reference/api/demo/"]); + } + [Fact] public async Task BuffersLargeResponsesAndKeepsStaticAndWarmOutputAvailableWithoutWorker() { @@ -124,6 +137,9 @@ public async Task CanonicalizesAndRedirectsWithoutInvokingWorker() using var canonical = await host.Client.GetAsync("/REFERENCE/API/DEMO"); Assert.Equal(HttpStatusCode.PermanentRedirect, canonical.StatusCode); Assert.Equal("/reference/api/demo/", canonical.Headers.Location!.OriginalString); + using var markdown = await host.Client.GetAsync("/reference/api/demo.md/"); + Assert.Equal(HttpStatusCode.PermanentRedirect, markdown.StatusCode); + Assert.Equal("/reference/api/demo.md", markdown.Headers.Location!.OriginalString); using var redirect = await host.Client.GetAsync("/old-guide/?a=1"); Assert.Equal(HttpStatusCode.Found, redirect.StatusCode); Assert.Equal("/guide/?a=1", redirect.Headers.Location!.OriginalString); @@ -202,12 +218,14 @@ internal sealed class TestApiRenderer : HttpMessageHandler { public ConcurrentDictionary Calls { get; } = new(); public bool Offline { get; set; } + public bool Timeout { get; set; } protected override async Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { var path = request.RequestUri!.AbsolutePath; Calls.AddOrUpdate(path, 1, (_, count) => count + 1); if (Offline) throw new HttpRequestException("Renderer unavailable."); + if (Timeout) throw new OperationCanceledException("Renderer timed out."); await Task.Delay(30, cancellationToken); var page = path.Split('/').Last(segment => segment.Length > 0).Replace(".md", ""); var response = new HttpResponseMessage(page == "failure" ? HttpStatusCode.ServiceUnavailable : HttpStatusCode.OK); From 63fdfee44d4cf4d16a4b7d64890d5e02063663ac Mon Sep 17 00:00:00 2001 From: David Pine <7679720+IEvangelist@users.noreply.github.com> Date: Sun, 11 Oct 2026 09:38:14 -0500 Subject: [PATCH 03/28] Verify emitted hybrid artifacts in focused opt-in CI Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .github/workflows/frontend-build.yml | 8 ++++- .github/workflows/hybrid-api-docs-poc.yml | 9 ++++++ CONTRIBUTING.md | 2 ++ .../tests/unit/hybrid-api-docs.vitest.test.ts | 30 +++++++++++++++++++ 4 files changed, 48 insertions(+), 1 deletion(-) diff --git a/.github/workflows/frontend-build.yml b/.github/workflows/frontend-build.yml index f2646cce87..9a569142c8 100644 --- a/.github/workflows/frontend-build.yml +++ b/.github/workflows/frontend-build.yml @@ -8,7 +8,7 @@ on: default: "24.x" type: string hybrid_api_poc: - description: Also verify the opt-in hybrid API documentation POC + description: Run the opt-in static/hybrid POC comparison default: false type: boolean workflow_call: @@ -48,6 +48,7 @@ jobs: uses: ./.github/workflows/hybrid-api-docs-poc.yml build: + if: ${{ github.event_name != 'workflow_dispatch' || !inputs.hybrid_api_poc }} name: Frontend Build runs-on: ubuntu-latest defaults: @@ -266,6 +267,7 @@ jobs: ls -la dist validation: + if: ${{ github.event_name != 'workflow_dispatch' || !inputs.hybrid_api_poc }} name: Frontend validation runs-on: ubuntu-latest defaults: @@ -452,11 +454,15 @@ jobs: REPORT: ${{ needs.report.result }} HYBRID_REQUESTED: ${{ inputs.hybrid_api_poc }} HYBRID_RESULT: ${{ needs['hybrid-api-poc'].result }} + POC_ONLY: ${{ github.event_name == 'workflow_dispatch' && inputs.hybrid_api_poc }} run: | if [[ "$HYBRID_REQUESTED" == "true" && "$HYBRID_RESULT" != "success" ]]; then echo "::error::The opted-in hybrid POC must succeed." exit 1 fi + if [[ "$POC_ONLY" == "true" ]]; then + exit 0 + fi for result in "$BUILD" "$VALIDATION" "$E2E" "$REPORT"; do if [[ "$result" != "success" ]]; then echo "::error::Every frontend job must succeed (build=$BUILD validation=$VALIDATION e2e=$E2E report=$REPORT)." diff --git a/.github/workflows/hybrid-api-docs-poc.yml b/.github/workflows/hybrid-api-docs-poc.yml index 1d37322fb2..428691c062 100644 --- a/.github/workflows/hybrid-api-docs-poc.yml +++ b/.github/workflows/hybrid-api-docs-poc.yml @@ -39,6 +39,15 @@ jobs: global-json-file: global.json - name: Install dependencies run: pnpm install --frozen-lockfile --prefer-offline + - name: Verify POC unit contracts + env: + ASTRO_TELEMETRY_DISABLED: '1' + run: | + pnpm exec astro sync + pnpm exec eslint . --max-warnings 0 + pnpm exec vitest run --config vitest.config.ts tests/unit/hybrid-api-docs.vitest.test.ts tests/unit/api-markdown.vitest.test.ts tests/unit/ts-api-route-catalog.vitest.test.ts tests/unit/build-performance.vitest.test.ts + dotnet test ../../tests/StaticHost.Tests/StaticHost.Tests.csproj --filter 'FullyQualifiedName~HybridApiDocs' --nologo + dotnet test ../../tests/Aspire.Dev.AppHost.Tests/Aspire.Dev.AppHost.Tests.csproj --filter 'FullyQualifiedName~HybridApiDocs' --nologo - name: Build static baseline env: ASTRO_TELEMETRY_DISABLED: '1' diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 60c582204f..08228705d5 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -46,6 +46,8 @@ A PR carrying the `hybrid-api-poc` label also runs the POC checks when CI is triggered by opening, reopening, or pushing to the PR. The comparison builds both modes from the same commit and reports output counts, build resource usage, and cold/warm rendering measurements in `hybrid-api-docs-results`. +The manual POC selection runs its focused checks and comparison without also +duplicating the ordinary frontend build and all viewport test shards. Download the completed `hybrid-api-docs-poc` artifact into the frontend directory: diff --git a/src/frontend/tests/unit/hybrid-api-docs.vitest.test.ts b/src/frontend/tests/unit/hybrid-api-docs.vitest.test.ts index a6f9fb27f5..48b90cb231 100644 --- a/src/frontend/tests/unit/hybrid-api-docs.vitest.test.ts +++ b/src/frontend/tests/unit/hybrid-api-docs.vitest.test.ts @@ -10,6 +10,7 @@ import { buildApiRouteCatalog, getCSharpRouteEntries, getTypeScriptRouteEntries import type { PackageApiDocument } from '@utils/packages'; import type { TsApiDocument } from '@utils/ts-modules'; import { onRequest } from '../../src/middleware'; +import { verifyHybridOutput } from '../../scripts/verify-hybrid-output.mjs'; describe('build-time hybrid opt-in', () => { it('requires an explicit supported flag value', () => { @@ -92,6 +93,35 @@ describe('build-time hybrid opt-in', () => { }); describe('API route catalogue', () => { + it('checks emitted output rather than merely trusting route prerender flags', async () => { + const directory = await mkdtemp(resolve(tmpdir(), 'aspire-hybrid-output-')); + try { + const baseline = resolve(directory, 'static'); + const hybrid = resolve(directory, 'hybrid'); + await mkdir(resolve(baseline, 'reference/api/csharp'), { recursive: true }); + await mkdir(resolve(hybrid, 'client'), { recursive: true }); + await mkdir(resolve(hybrid, 'server'), { recursive: true }); + await writeFile(resolve(baseline, 'reference/api/csharp/index.html'), 'API'); + for (const file of ['index.html', '404.html', 'llms.txt', 'sitemap-index.xml']) { + await writeFile(resolve(baseline, file), 'static'); + await writeFile(resolve(hybrid, 'client', file), 'static'); + } + await writeFile(resolve(hybrid, 'server/entry.mjs'), 'renderer'); + await writeFile(resolve(hybrid, 'client/sitemap-api.xml'), + 'https://aspire.dev/reference/api/csharp/'); + await writeFile(resolve(hybrid, 'hybrid-api-docs.json'), JSON.stringify({ + mode: 'hybrid-api-docs', schemaVersion: 1, buildId: 'test', client: 'client', site: 'https://aspire.dev', + routes: [{ html: '/reference/api/csharp/', markdown: '/reference/api/csharp.md' }], redirects: [], + })); + expect((await verifyHybridOutput(baseline, hybrid)).staticApiFilesAvoided).toBe(1); + await mkdir(resolve(hybrid, 'client/reference/api/csharp'), { recursive: true }); + await writeFile(resolve(hybrid, 'client/reference/api/csharp/index.html'), 'unexpected API'); + await expect(verifyHybridOutput(baseline, hybrid)).rejects.toThrow('API HTML/Markdown was prerendered.'); + } finally { + await rm(directory, { recursive: true, force: true }); + } + }); + it('retains C# generic arity and only existing member-kind groups', () => { const pkg: PackageApiDocument = { package: { name: 'Test.Package', version: '1', targetFramework: 'net10.0' }, From 16571967f1977effe1806b642ad7a82a9c0a8f44 Mon Sep 17 00:00:00 2001 From: David Pine <7679720+IEvangelist@users.noreply.github.com> Date: Sun, 11 Oct 2026 09:44:24 -0500 Subject: [PATCH 04/28] Validate hybrid redirects without requiring static redirect files Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- src/frontend/astro.config.mjs | 2 ++ src/frontend/scripts/verify-hybrid-output.mjs | 8 ++++++++ 2 files changed, 10 insertions(+) diff --git a/src/frontend/astro.config.mjs b/src/frontend/astro.config.mjs index 724ff3ae50..1a06c77a5c 100644 --- a/src/frontend/astro.config.mjs +++ b/src/frontend/astro.config.mjs @@ -162,6 +162,8 @@ export default defineConfig({ errorOnFallbackPages: false, exclude: [ '/i18n/', '/reference/api', '/reference/api/**', + // These remain real StaticHost redirects but the Node adapter emits no static redirect file. + ...(hybridApiDocs ? Object.keys(redirects).flatMap(path => [path, `${path}#*`]) : []), // Custom Astro destinations checked by the Dev Hub browser tests. '/hub/', '/hub/glossary/ats/', '/get-started/glossary/#polyglot', ], diff --git a/src/frontend/scripts/verify-hybrid-output.mjs b/src/frontend/scripts/verify-hybrid-output.mjs index ffc19a0c9e..591e64d58d 100644 --- a/src/frontend/scripts/verify-hybrid-output.mjs +++ b/src/frontend/scripts/verify-hybrid-output.mjs @@ -17,6 +17,14 @@ export async function verifyHybridOutput(staticRoot, hybridRoot) { assert.deepEqual(hybrid.files.filter(({ path }) => api(path)), [], 'API HTML/Markdown was prerendered.'); assert.ok(server.files.some(({ path }) => path === 'entry.mjs'), 'Missing private renderer entrypoint.'); const redirectFiles = new Set(manifest.redirects.map(({ path }) => `${path.replace(/^\/|\/$/g, '')}/index.html`)); + const clientFiles = new Set(hybrid.files.map(({ path }) => path)); + for (const redirect of manifest.redirects) { + const destination = redirect.destination.replace(/^\/|\/$/g, ''); + assert.ok(clientFiles.has(`${destination}/index.html`) || clientFiles.has(`${destination}.html`) + || manifest.routes.some(({ html }) => html === redirect.destination) + || manifest.redirects.some(({ path }) => path === redirect.destination), + `Configured redirect has no destination: ${redirect.path} -> ${redirect.destination}`); + } const nonApi = (files) => files.filter(({ path }) => /\.(html|md)$/.test(path) && !api(path) && !redirectFiles.has(path)).map(({ path }) => path); assert.deepEqual(nonApi(hybrid.files), nonApi(baseline.files), 'Non-API page inventory changed.'); From 406316251af5d15bf5148ec404a3e1e15ff6396d Mon Sep 17 00:00:00 2001 From: David Pine <7679720+IEvangelist@users.noreply.github.com> Date: Sun, 11 Oct 2026 09:54:10 -0500 Subject: [PATCH 05/28] Support platform-matched POC artifacts and bounded runtime images Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .github/workflows/hybrid-api-docs-poc.yml | 40 +++++++++++++++++++ CONTRIBUTING.md | 7 +++- .../HybridApiDocsExtensions.cs | 3 ++ src/frontend/config/hybrid-api-docs.mjs | 3 +- src/frontend/scripts/serve-api-docs.mjs | 5 ++- .../HybridApiDocs/HybridApiDocsArtifact.cs | 18 ++++++++- .../HybridApiDocs/HybridApiDocsExtensions.cs | 7 +++- .../HybridApiDocs/HybridApiDocsRenderer.cs | 2 +- .../HybridApiDocsRoutingMiddleware.cs | 18 ++++++++- src/statichost/StaticHost/Program.cs | 7 ++++ src/statichost/StaticHost/StaticHost.csproj | 1 + .../HybridApiDocsConfigurationTests.cs | 2 +- tests/StaticHost.Tests/HybridApiDocsTests.cs | 19 ++++++++- 13 files changed, 122 insertions(+), 10 deletions(-) diff --git a/.github/workflows/hybrid-api-docs-poc.yml b/.github/workflows/hybrid-api-docs-poc.yml index 428691c062..d5f35cb83a 100644 --- a/.github/workflows/hybrid-api-docs-poc.yml +++ b/.github/workflows/hybrid-api-docs-poc.yml @@ -8,6 +8,46 @@ permissions: contents: read jobs: + windows-artifact: + runs-on: windows-latest + defaults: + run: + working-directory: src/frontend + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + fetch-depth: 0 + persist-credentials: false + - uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6.0.10 + - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 + with: + node-version: 24.x + cache: pnpm + cache-dependency-path: src/frontend/pnpm-lock.yaml + - uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0 + with: + global-json-file: global.json + - name: Install dependencies + run: pnpm install --frozen-lockfile --prefer-offline + - name: Build Windows hybrid artifact + env: + ASTRO_TELEMETRY_DISABLED: '1' + NODE_OPTIONS: --max-old-space-size=8192 + ASPIRE_HYBRID_API_DOCS: '1' + run: pnpm build:production + - name: Verify Windows StaticHost contracts + env: + ASPIRE_HYBRID_API_DOCS: '1' + run: dotnet test ../../tests/StaticHost.Tests/StaticHost.Tests.csproj --filter 'FullyQualifiedName~HybridApiDocs' --nologo + - name: Upload Windows POC artifact + if: success() + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: hybrid-api-docs-poc-windows + path: src/frontend/dist-hybrid + if-no-files-found: error + retention-days: 7 + verify: runs-on: ubuntu-latest services: diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 08228705d5..0b9babf7c6 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -52,13 +52,16 @@ duplicating the ordinary frontend build and all viewport test shards. Download the completed `hybrid-api-docs-poc` artifact into the frontend directory: ```powershell -gh run download RUN_ID --repo microsoft/aspire.dev --name hybrid-api-docs-poc --dir .\src\frontend\dist-hybrid +gh run download RUN_ID --repo microsoft/aspire.dev --name hybrid-api-docs-poc-windows --dir .\src\frontend\dist-hybrid $env:ASPIRE_HYBRID_API_DOCS = '1' aspire start --non-interactive ``` Restore frontend dependencies with the repository's existing pnpm setup first. The downloaded directory contains `client`, `server`, and `hybrid-api-docs.json`. +Use `hybrid-api-docs-poc` on Linux or `hybrid-api-docs-poc-windows` on Windows. +The Node adapter's build paths are platform-specific; a Linux artifact cannot +run on Windows. The manifest checks the platform before starting the renderer. The manifest and server stay outside the public static root. Browse the StaticHost endpoint in the Aspire dashboard; the Node worker is internal. Missing or incompatible artifacts cause an actionable startup error instead of @@ -78,6 +81,8 @@ or warmed API responses from being served, but a cold API request returns a gateway error. Existing Redis usage for live status is unchanged; API output caching does not use Redis. Azure hybrid publishing is intentionally rejected for this local POC, and the production deployment path remains static. +On-demand image requests are limited to bundled local images and dimensions up +to 4096 pixels; arbitrary remote URLs are not forwarded to the renderer. Unset the flag to return to the ordinary Vite/local workflow: diff --git a/src/apphost/Aspire.Dev.AppHost/HybridApiDocsExtensions.cs b/src/apphost/Aspire.Dev.AppHost/HybridApiDocsExtensions.cs index eed99d4cc1..a7c5bd929c 100644 --- a/src/apphost/Aspire.Dev.AppHost/HybridApiDocsExtensions.cs +++ b/src/apphost/Aspire.Dev.AppHost/HybridApiDocsExtensions.cs @@ -20,6 +20,9 @@ public static void WithHybridApiDocs(this IResourceBuilder webs using var json = JsonDocument.Parse(File.ReadAllText(manifest)); if (json.RootElement.GetProperty("mode").GetString() != "hybrid-api-docs") throw new InvalidOperationException("The selected artifact is not a hybrid API documentation build."); + if (json.RootElement.GetProperty("platform").GetString() != + (OperatingSystem.IsWindows() ? "win32" : OperatingSystem.IsMacOS() ? "darwin" : "linux")) + throw new InvalidOperationException("Download the hybrid CI artifact matching this operating system."); var worker = builder.AddNodeApp("api-docs", frontendDirectory, "scripts/serve-api-docs.mjs") .WithPnpm() diff --git a/src/frontend/config/hybrid-api-docs.mjs b/src/frontend/config/hybrid-api-docs.mjs index 583fd8ff57..2af32b425f 100644 --- a/src/frontend/config/hybrid-api-docs.mjs +++ b/src/frontend/config/hybrid-api-docs.mjs @@ -79,11 +79,12 @@ export function hybridApiDocsIntegration(redirects) { await cp(resolve(root, '../statichost/StaticHost/wwwroot/scalar'), resolve(out, 'client/scalar'), { recursive: true }); const hash = createHash('sha256'); - hash.update(JSON.stringify({ routes, redirects: redirectEntries, site })); + hash.update(JSON.stringify({ routes, redirects: redirectEntries, site, platform: process.platform })); await hashDirectory(resolve(out, 'client'), hash, 'client/'); await hashDirectory(resolve(out, 'server'), hash, 'server/'); const manifest = { schemaVersion: 1, mode: 'hybrid-api-docs', buildId: hash.digest('hex'), + platform: process.platform, client: 'client', server: 'server/entry.mjs', site, routes, redirects: redirectEntries, }; diff --git a/src/frontend/scripts/serve-api-docs.mjs b/src/frontend/scripts/serve-api-docs.mjs index 3e2c662a04..1eeea11079 100644 --- a/src/frontend/scripts/serve-api-docs.mjs +++ b/src/frontend/scripts/serve-api-docs.mjs @@ -9,6 +9,9 @@ const manifest = JSON.parse(await readFile(manifestPath, 'utf8')); if (manifest.schemaVersion !== 1 || manifest.mode !== 'hybrid-api-docs' || !/^[a-f0-9]{64}$/.test(manifest.buildId)) { throw new Error('Expected a compatible prebuilt hybrid-api-docs.json artifact.'); } +if (manifest.platform !== process.platform) { + throw new Error(`This Astro adapter artifact targets ${manifest.platform}; download the ${process.platform} POC artifact instead.`); +} const root = dirname(manifestPath); const entry = resolve(root, manifest.server); const entryRelative = relative(root, entry); @@ -30,7 +33,7 @@ const server = http.createServer((req, res) => { res.end(); return; } - if (!paths.has(url.pathname)) { + if (!paths.has(url.pathname) && !['/_image', '/_image/'].includes(url.pathname)) { res.writeHead(404); res.end('API route not found'); return; diff --git a/src/statichost/StaticHost/HybridApiDocs/HybridApiDocsArtifact.cs b/src/statichost/StaticHost/HybridApiDocs/HybridApiDocsArtifact.cs index a9e17477f3..806a5a2953 100644 --- a/src/statichost/StaticHost/HybridApiDocs/HybridApiDocsArtifact.cs +++ b/src/statichost/StaticHost/HybridApiDocs/HybridApiDocsArtifact.cs @@ -7,13 +7,14 @@ internal sealed record HybridApiRoute(string? Html, string Markdown); internal sealed record HybridRedirect(string Path, string Destination, int Status); internal sealed record HybridApiManifest( int SchemaVersion, string Mode, string BuildId, string Client, string Server, - string Site, HybridApiRoute[] Routes, HybridRedirect[] Redirects); + string Site, HybridApiRoute[] Routes, HybridRedirect[] Redirects, string Platform); internal sealed class HybridApiDocsArtifact { private readonly Dictionary _canonical = new(StringComparer.OrdinalIgnoreCase); private readonly Dictionary _routes = new(StringComparer.Ordinal); private readonly Dictionary _redirects = new(StringComparer.Ordinal); + private readonly HashSet _images = new(StringComparer.Ordinal); public HybridApiManifest Manifest { get; } public string ClientDirectory { get; } @@ -25,6 +26,7 @@ private HybridApiDocsArtifact(string path, HybridApiManifest manifest) if (manifest.SchemaVersion != 1 || manifest.Mode != "hybrid-api-docs" || !Regex.IsMatch(manifest.BuildId ?? "", "^[a-f0-9]{64}$") || manifest.Routes is null || manifest.Redirects is null || + manifest.Platform != (OperatingSystem.IsWindows() ? "win32" : OperatingSystem.IsMacOS() ? "darwin" : "linux") || !Uri.TryCreate(manifest.Site, UriKind.Absolute, out var site) || site.Scheme is not ("http" or "https")) { @@ -60,6 +62,19 @@ site.Scheme is not ("http" or "https")) _canonical.TryAdd(redirect.Path, redirect.Path); _canonical.TryAdd(redirect.Path.TrimEnd('/'), redirect.Path); } + var assets = Path.Combine(ClientDirectory, "_astro"); + if (Directory.Exists(assets)) + { + foreach (var image in Directory.EnumerateFiles(assets, "*", new EnumerationOptions + { + RecurseSubdirectories = true, + AttributesToSkip = FileAttributes.ReparsePoint, + })) + { + if (Path.GetExtension(image).ToLowerInvariant() is ".svg" or ".png" or ".jpg" or ".jpeg" or ".webp" or ".avif" or ".gif") + _images.Add("/" + Path.GetRelativePath(ClientDirectory, image).Replace(Path.DirectorySeparatorChar, '/')); + } + } } public static HybridApiDocsArtifact Load(string path) @@ -75,6 +90,7 @@ public static HybridApiDocsArtifact Load(string path) public bool TryCanonical(string path, out string? canonical) => _canonical.TryGetValue(path, out canonical); public bool TryRoute(string path, out HybridApiRoute? route) => _routes.TryGetValue(path, out route); public bool TryRedirect(string path, out HybridRedirect? redirect) => _redirects.TryGetValue(path, out redirect); + public bool IsLocalImage(string path) => _images.Contains(path); private void AddRoute(string path, HybridApiRoute route) { diff --git a/src/statichost/StaticHost/HybridApiDocs/HybridApiDocsExtensions.cs b/src/statichost/StaticHost/HybridApiDocs/HybridApiDocsExtensions.cs index b71b1cf547..464479e68c 100644 --- a/src/statichost/StaticHost/HybridApiDocs/HybridApiDocsExtensions.cs +++ b/src/statichost/StaticHost/HybridApiDocs/HybridApiDocsExtensions.cs @@ -39,7 +39,12 @@ public static void UseHybridApiDocsRouting(this IApplicationBuilder app) => app.UseMiddleware(); public static void MapHybridApiDocs(this IEndpointRouteBuilder app) - => app.MapMethods("/reference/api/{**path}", ["GET", "HEAD"], + { + app.MapMethods("/reference/api/{**path}", ["GET", "HEAD"], + (HttpContext context, HybridApiDocsRenderer renderer) => renderer.RenderAsync(context)) + .CacheOutput("HybridApiDocs"); + app.MapMethods("/_image", ["GET", "HEAD"], (HttpContext context, HybridApiDocsRenderer renderer) => renderer.RenderAsync(context)) .CacheOutput("HybridApiDocs"); + } } diff --git a/src/statichost/StaticHost/HybridApiDocs/HybridApiDocsRenderer.cs b/src/statichost/StaticHost/HybridApiDocs/HybridApiDocsRenderer.cs index d6161ee533..9a79a2e3c6 100644 --- a/src/statichost/StaticHost/HybridApiDocs/HybridApiDocsRenderer.cs +++ b/src/statichost/StaticHost/HybridApiDocs/HybridApiDocsRenderer.cs @@ -32,7 +32,7 @@ public async Task RenderAsync(HttpContext context) { using var response = await client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, timeout.Token); if (!response.Headers.TryGetValues("X-Aspire-Build-Id", out var ids) || - ids.SingleOrDefault() != artifact.Manifest.BuildId) + !ids.SequenceEqual([artifact.Manifest.BuildId])) throw new HttpRequestException("The renderer and StaticHost have different build identities."); await response.Content.LoadIntoBufferAsync(MaximumBodySize, timeout.Token); var body = await response.Content.ReadAsByteArrayAsync(timeout.Token); diff --git a/src/statichost/StaticHost/HybridApiDocs/HybridApiDocsRoutingMiddleware.cs b/src/statichost/StaticHost/HybridApiDocs/HybridApiDocsRoutingMiddleware.cs index fa314e013e..827a8337eb 100644 --- a/src/statichost/StaticHost/HybridApiDocs/HybridApiDocsRoutingMiddleware.cs +++ b/src/statichost/StaticHost/HybridApiDocs/HybridApiDocsRoutingMiddleware.cs @@ -25,7 +25,8 @@ public async Task InvokeAsync(HttpContext context) context.Response.Headers.Location = redirect.Destination + context.Request.QueryString; return; } - if (!context.Request.Path.StartsWithSegments("/reference/api")) + var image = path is "/_image" or "/_image/"; + if (!image && !context.Request.Path.StartsWithSegments("/reference/api")) { await next(context); return; @@ -36,6 +37,21 @@ public async Task InvokeAsync(HttpContext context) context.Response.Headers.Allow = "GET, HEAD"; return; } + if (image) + { + var query = context.Request.Query; + if (query["href"].Count != 1 || !artifact.IsLocalImage(query["href"].ToString()) || + new[] { "w", "h" }.Any(key => query.TryGetValue(key, out var values) && + (values.Count != 1 || !int.TryParse(values.ToString(), out var size) || size is < 1 or > 4096))) + { + context.Response.StatusCode = StatusCodes.Status400BadRequest; + context.Response.Headers.CacheControl = "no-store"; + return; + } + context.Features.Set(new HybridApiDocsRequest("/_image", "image", null)); + await next(context); + return; + } if (!artifact.TryRoute(path, out var route)) { context.Response.StatusCode = StatusCodes.Status404NotFound; diff --git a/src/statichost/StaticHost/Program.cs b/src/statichost/StaticHost/Program.cs index 1ec550f8c3..66921f892b 100644 --- a/src/statichost/StaticHost/Program.cs +++ b/src/statichost/StaticHost/Program.cs @@ -4,6 +4,13 @@ var hybridArtifactPath = new ConfigurationBuilder() .AddEnvironmentVariables().AddCommandLine(args).Build()["HybridApiDocs:ArtifactPath"]; var hybridArtifact = hybridArtifactPath is null ? null : HybridApiDocsArtifact.Load(hybridArtifactPath); +#if HYBRID_API_DOCS_BUILD +if (hybridArtifact is null) + throw new InvalidOperationException("A hybrid StaticHost build requires HybridApiDocs:ArtifactPath and its private renderer endpoint."); +#else +if (hybridArtifact is not null) + throw new InvalidOperationException("Build StaticHost with ASPIRE_HYBRID_API_DOCS=1 to select the hybrid client's static-asset manifest."); +#endif var builder = WebApplication.CreateBuilder(new WebApplicationOptions { Args = args, diff --git a/src/statichost/StaticHost/StaticHost.csproj b/src/statichost/StaticHost/StaticHost.csproj index 69a1960f97..b6dbc3b23c 100644 --- a/src/statichost/StaticHost/StaticHost.csproj +++ b/src/statichost/StaticHost/StaticHost.csproj @@ -8,6 +8,7 @@ true noble-chiseled obj/$(Configuration)/hybrid/ + $(DefineConstants);HYBRID_API_DOCS_BUILD false diff --git a/tests/Aspire.Dev.AppHost.Tests/HybridApiDocsConfigurationTests.cs b/tests/Aspire.Dev.AppHost.Tests/HybridApiDocsConfigurationTests.cs index c944d6f8dd..fbd497656c 100644 --- a/tests/Aspire.Dev.AppHost.Tests/HybridApiDocsConfigurationTests.cs +++ b/tests/Aspire.Dev.AppHost.Tests/HybridApiDocsConfigurationTests.cs @@ -23,7 +23,7 @@ public async Task LocalGraphUsesPrivateWorkerAndEndpointReferences() try { File.WriteAllText(Path.Combine(directory, "dist-hybrid", "hybrid-api-docs.json"), - """{"mode":"hybrid-api-docs"}"""); + $$"""{"mode":"hybrid-api-docs","platform":"{{(OperatingSystem.IsWindows() ? "win32" : "linux")}}"}"""); var builder = DistributedApplication.CreateBuilder(new DistributedApplicationOptions { DisableDashboard = true, diff --git a/tests/StaticHost.Tests/HybridApiDocsTests.cs b/tests/StaticHost.Tests/HybridApiDocsTests.cs index bad933d699..b689feea2a 100644 --- a/tests/StaticHost.Tests/HybridApiDocsTests.cs +++ b/tests/StaticHost.Tests/HybridApiDocsTests.cs @@ -150,6 +150,19 @@ public async Task CanonicalizesAndRedirectsWithoutInvokingWorker() Assert.Empty(host.Renderer.Calls); } + [Fact] + public async Task AllowsOnlyBundledImagesAndBoundsTransformDimensions() + { + await using var host = await HybridHost.StartAsync(); + using var allowed = await host.Client.GetAsync("/_image?href=%2F_astro%2Flogo.svg&w=48&h=48"); + Assert.Equal(HttpStatusCode.OK, allowed.StatusCode); + using var remote = await host.Client.GetAsync("/_image?href=https%3A%2F%2Fexample.com%2Fimage.svg"); + Assert.Equal(HttpStatusCode.BadRequest, remote.StatusCode); + using var oversized = await host.Client.GetAsync("/_image?href=%2F_astro%2Flogo.svg&w=999999"); + Assert.Equal(HttpStatusCode.BadRequest, oversized.StatusCode); + Assert.Equal(1, host.Renderer.Calls["/_image"]); + } + [Fact] public void RejectsMissingOrEscapingArtifacts() { @@ -157,7 +170,7 @@ public void RejectsMissingOrEscapingArtifacts() Assert.Throws(() => HybridApiDocsArtifact.Load(Path.Combine(root.Path, "missing.json"))); root.WriteFile("hybrid.json", JsonSerializer.Serialize(new HybridApiManifest( 1, "hybrid-api-docs", new string('a', 64), "../escape", "server/entry.mjs", - "https://aspire.dev", [], []), new JsonSerializerOptions(JsonSerializerDefaults.Web))); + "https://aspire.dev", [], [], OperatingSystem.IsWindows() ? "win32" : "linux"), new JsonSerializerOptions(JsonSerializerDefaults.Web))); Assert.Throws(() => HybridApiDocsArtifact.Load(Path.Combine(root.Path, "hybrid.json"))); } } @@ -181,12 +194,14 @@ public static async Task StartAsync() { var root = new TempWebRoot(); root.WriteFile("client/guide/index.html", "static guide"); + root.WriteFile("client/_astro/logo.svg", ""); root.WriteFile("server/entry.mjs", "private server"); var pages = new[] { "demo", "private", "cookie", "failure", "broken", "mismatch", "oversize", "large", "cold" }; root.WriteFile("hybrid.json", JsonSerializer.Serialize(new HybridApiManifest( 1, "hybrid-api-docs", new string('a', 64), "client", "server/entry.mjs", "https://aspire.dev", pages.Select(page => new HybridApiRoute($"/reference/api/{page}/", $"/reference/api/{page}.md")).ToArray(), - [new("/old-guide/", "/guide/", 302)]), new JsonSerializerOptions(JsonSerializerDefaults.Web))); + [new("/old-guide/", "/guide/", 302)], OperatingSystem.IsWindows() ? "win32" : "linux"), + new JsonSerializerOptions(JsonSerializerDefaults.Web))); var artifact = HybridApiDocsArtifact.Load(Path.Combine(root.Path, "hybrid.json")); var builder = WebApplication.CreateBuilder(new WebApplicationOptions { WebRootPath = artifact.ClientDirectory }); builder.Logging.ClearProviders(); From 8a80476b4ee9d290919fb594da609899ba17d5d6 Mon Sep 17 00:00:00 2001 From: David Pine <7679720+IEvangelist@users.noreply.github.com> Date: Sun, 11 Oct 2026 10:08:07 -0500 Subject: [PATCH 06/28] Preserve slash-form image requests and clarify POC build command Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- CONTRIBUTING.md | 1 + .../StaticHost/HybridApiDocs/HybridApiDocsRoutingMiddleware.cs | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0b9babf7c6..0e50696d54 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -34,6 +34,7 @@ C# and TypeScript API HTML and Markdown on demand through the existing StaticHos This includes both API search pages. The convenience command `build:hybrid` sets the flag only for its child build; `build:hybrid:skip-search` also skips Pagefind. Setting a runtime flag alone cannot convert an already-static artifact. +Use `build:hybrid`, not the static-only `build:statichost` command, for this mode. Run full-site comparisons in CI, not on your development machine. From the **Frontend Build** workflow, select the POC option, or use: diff --git a/src/statichost/StaticHost/HybridApiDocs/HybridApiDocsRoutingMiddleware.cs b/src/statichost/StaticHost/HybridApiDocs/HybridApiDocsRoutingMiddleware.cs index 827a8337eb..a0ab853385 100644 --- a/src/statichost/StaticHost/HybridApiDocs/HybridApiDocsRoutingMiddleware.cs +++ b/src/statichost/StaticHost/HybridApiDocs/HybridApiDocsRoutingMiddleware.cs @@ -48,7 +48,7 @@ public async Task InvokeAsync(HttpContext context) context.Response.Headers.CacheControl = "no-store"; return; } - context.Features.Set(new HybridApiDocsRequest("/_image", "image", null)); + context.Features.Set(new HybridApiDocsRequest(path, "image", null)); await next(context); return; } From 32e2034aa897d4af141d9bf4714ceee04a5481ab Mon Sep 17 00:00:00 2001 From: David Pine <7679720+IEvangelist@users.noreply.github.com> Date: Sun, 11 Oct 2026 10:36:17 -0500 Subject: [PATCH 07/28] Serve the selected hybrid client without placeholder asset shadowing Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- src/frontend/scripts/test-hybrid-host.mjs | 6 ++++-- .../tests/e2e/hybrid-api-docs.spec.ts | 3 +++ src/statichost/StaticHost/Program.cs | 19 +++++++++++++++++++ src/statichost/StaticHost/StaticHost.csproj | 1 + 4 files changed, 27 insertions(+), 2 deletions(-) diff --git a/src/frontend/scripts/test-hybrid-host.mjs b/src/frontend/scripts/test-hybrid-host.mjs index 42fdc639da..f9bd289f54 100644 --- a/src/frontend/scripts/test-hybrid-host.mjs +++ b/src/frontend/scripts/test-hybrid-host.mjs @@ -62,6 +62,8 @@ try { return { response, text }; } const initial = await stats(); + const home = await page('/'); + assert.ok(!home.text.includes('Aspire Static Host'), 'The placeholder wwwroot home must not shadow the hybrid homepage.'); await page('/docs/'); assert.equal((await stats()).renders, initial.renders); const csharp = await page('/reference/api/csharp/'); @@ -89,10 +91,10 @@ try { assert.equal(unknown.status, 404); if (process.env.HYBRID_TEST_BROWSER === '1') { const install = launch('pnpm', ['exec', 'playwright', 'install', '--with-deps', 'chromium'], process.env); - assert.equal((await once(install, 'exit'))[0], 0, output); + assert.equal((await once(install, 'exit'))[0], 0, output.slice(-10000)); const browser = launch('pnpm', ['exec', 'playwright', 'test', '--config', 'playwright.hybrid.config.mjs'], { ...process.env, HYBRID_TEST_URL: hostUrl }); - assert.equal((await once(browser, 'exit'))[0], 0, output); + assert.equal((await once(browser, 'exit'))[0], 0, output.slice(-10000)); } const final = await stats(); const stopped = once(worker, 'exit'); diff --git a/src/frontend/tests/e2e/hybrid-api-docs.spec.ts b/src/frontend/tests/e2e/hybrid-api-docs.spec.ts index ffb5a0f05b..eda238d916 100644 --- a/src/frontend/tests/e2e/hybrid-api-docs.spec.ts +++ b/src/frontend/tests/e2e/hybrid-api-docs.spec.ts @@ -2,6 +2,8 @@ import { expect, test } from '@playwright/test'; test('built StaticHost navigation keeps API styles, search and Markdown actions usable', async ({ page, context }) => { await context.grantPermissions(['clipboard-read', 'clipboard-write']); + await page.goto('/'); + await expect(page).not.toHaveTitle('Aspire Static Host'); await page.goto('/docs/'); await expect(page.locator('meta[name="git-commit-id"]')).toHaveCount(1); await page.goto('/reference/api/typescript/'); @@ -15,6 +17,7 @@ test('built StaticHost navigation keeps API styles, search and Markdown actions const link = page.locator('#ts-api-package-list a').first(); await link.click(); await expect(page.locator('h1')).toBeVisible(); + await page.locator('img').last().scrollIntoViewIfNeeded(); await expect.poll(() => page.locator('img').evaluateAll(images => images.every(image => !(image instanceof HTMLImageElement) || !image.src.startsWith(location.origin) || image.complete && image.naturalWidth > 0))).toBe(true); diff --git a/src/statichost/StaticHost/Program.cs b/src/statichost/StaticHost/Program.cs index 66921f892b..029e193dd9 100644 --- a/src/statichost/StaticHost/Program.cs +++ b/src/statichost/StaticHost/Program.cs @@ -1,5 +1,6 @@ using Scalar.AspNetCore; using StaticHost.HybridApiDocs; +using Microsoft.Extensions.FileProviders; var hybridArtifactPath = new ConfigurationBuilder() .AddEnvironmentVariables().AddCommandLine(args).Build()["HybridApiDocs:ArtifactPath"]; @@ -46,6 +47,12 @@ } await using var app = builder.Build(); +if (hybridArtifact is not null) +{ + var clientFiles = new PhysicalFileProvider(hybridArtifact.ClientDirectory); + app.Environment.WebRootFileProvider = clientFiles; + app.Lifetime.ApplicationStopped.Register(clientFiles.Dispose); +} // Restore the Front Door client IP before telemetry or any middleware reads it. app.UseForwardedClientIp(); @@ -71,6 +78,18 @@ app.UseAgentReadiness(); app.UseDefaultFiles(); +if (hybridArtifact is not null) +{ + app.UseStaticFiles(new StaticFileOptions + { + OnPrepareResponse = context => + { + context.Context.Response.Headers.CacheControl = + context.Context.Request.Path.StartsWithSegments("/_astro") + ? "public, max-age=31536000, immutable" : "no-cache"; + }, + }); +} // add routing after default files, so the default file middleware can modify the path first app.UseRouting(); diff --git a/src/statichost/StaticHost/StaticHost.csproj b/src/statichost/StaticHost/StaticHost.csproj index b6dbc3b23c..7c75253452 100644 --- a/src/statichost/StaticHost/StaticHost.csproj +++ b/src/statichost/StaticHost/StaticHost.csproj @@ -38,6 +38,7 @@ + - + diff --git a/tests/Aspire.Dev.AppHost.Tests/HybridApiDocsConfigurationTests.cs b/tests/Aspire.Dev.AppHost.Tests/HybridApiDocsConfigurationTests.cs index 854f3347f5..fa6f6f0bcf 100644 --- a/tests/Aspire.Dev.AppHost.Tests/HybridApiDocsConfigurationTests.cs +++ b/tests/Aspire.Dev.AppHost.Tests/HybridApiDocsConfigurationTests.cs @@ -1,4 +1,6 @@ using Aspire.Hosting; +using Aspire.Hosting.Azure; +using Azure.Provisioning.AppService; namespace Aspire.Dev.AppHost.Tests; @@ -56,4 +58,73 @@ public async Task LocalGraphUsesTwoPrivateWorkersAndEndpointReferences() Directory.Delete(directory, recursive: true); } } + + [Fact] + public async Task PublishModelKeepsBothRenderersInsideTheSameWebsite() + { + var directory = Path.Combine(Path.GetTempPath(), $"aspire-hybrid-sidecars-{Guid.NewGuid():N}"); + Directory.CreateDirectory(Path.Combine(directory, "dist-hybrid")); + try + { + File.WriteAllText(Path.Combine(directory, "dist-hybrid", "hybrid-api-docs.json"), + """{"mode":"hybrid-api-docs","platform":"linux"}"""); + var builder = DistributedApplication.CreateBuilder(new DistributedApplicationOptions + { + Args = ["--publisher", "manifest"], DisableDashboard = true, + }); + var website = builder.AddProject("aspiredev") + .PublishAsAzureAppServiceWebsite((infra, site) => site.IsEndToEndEncryptionEnabled = true); + website.WithHybridApiDocs(builder, directory); + Assert.Empty(builder.Resources.OfType()); + var image = Assert.Single(builder.Resources.OfType()); + Assert.Equal("api-docs-image", image.Name); + + var infrastructure = builder.AddAzureInfrastructure("hybrid-test", infra => + { + var site = new WebSite("website") { Name = "hybrid-test", SiteConfig = new SiteConfigProperties() }; + infra.Add(site); + infra.Add(new SiteContainer("mainContainer") + { + Parent = site, Name = "main", IsMain = true, Image = "example/main:build", + AuthType = SiteContainerAuthType.UserAssigned, + UserManagedIdentityClientId = "00000000-0000-0000-0000-000000000000", + }); + foreach (var annotation in website.Resource.Annotations.OfType()) + annotation.Configure(infra, site); + + var containers = infra.GetProvisionableResources().OfType().ToArray(); + Assert.Equal(3, containers.Length); + var sidecars = containers.Where(container => !container.IsMain.Value).ToArray(); + Assert.Equal(2, sidecars.Length); + Assert.All(sidecars, container => + { + Assert.Same(site, container.Parent); + Assert.False(container.InheritAppSettingsAndConnectionStrings.Value); + Assert.Empty(container.VolumeMounts); + Assert.Equal(SiteContainerAuthType.UserAssigned, container.AuthType.Value); + Assert.Equal("00000000-0000-0000-0000-000000000000", container.UserManagedIdentityClientId.Value); + var port = Assert.IsType(Assert.Single(container.EnvironmentVariables).Value); + Assert.Equal("PORT", port.Name.Value); + Assert.Equal(container.TargetPort.Value, port.Value.Value); + }); + Assert.Equal(new string?[] { "4323", "4324" }, sidecars.Select(container => container.TargetPort.Value)); + Assert.Equal("/healthz/api-docs", site.SiteConfig.HealthCheckPath.Value); + Assert.Equal(2, site.SiteConfig.NumberOfWorkers.Value); + Assert.True(site.SiteConfig.IsAlwaysOn.Value); + Assert.True(site.IsEndToEndEncryptionEnabled.Value); + Assert.Contains(site.SiteConfig.AppSettings, setting => + setting.Value is { } pair && + pair.Name.Value == "WEBSITE_HEALTHCHECK_MAXPINGFAILURES" && pair.Value.Value == "2"); + }); + await using var app = builder.Build(); + var bicep = infrastructure.Resource.GetBicepTemplateString(); + Assert.Contains("isMain: false", bicep, StringComparison.Ordinal); + Assert.Contains("healthCheckPath: '/healthz/api-docs'", bicep, StringComparison.Ordinal); + Assert.Contains("endToEndEncryptionEnabled: true", bicep, StringComparison.Ordinal); + } + finally + { + Directory.Delete(directory, recursive: true); + } + } } diff --git a/tests/StaticHost.Tests/HybridApiDocsTests.cs b/tests/StaticHost.Tests/HybridApiDocsTests.cs index 4c3d77ef83..f4d8f4ce53 100644 --- a/tests/StaticHost.Tests/HybridApiDocsTests.cs +++ b/tests/StaticHost.Tests/HybridApiDocsTests.cs @@ -263,7 +263,6 @@ public static async Task StartAsync(string[]? endpoints = null) var root = new TempWebRoot(); root.WriteFile("client/guide/index.html", "static guide"); root.WriteFile("client/_astro/logo.svg", ""); - root.WriteFile("server/entry.mjs", "private server"); var pages = new[] { "demo", "private", "cookie", "failure", "broken", "mismatch", "oversize", "large", "cold" }; root.WriteFile("hybrid.json", JsonSerializer.Serialize(new HybridApiManifest( 1, "hybrid-api-docs", new string('a', 64), "client", "server/entry.mjs", "https://aspire.dev", From 861d8e20e2b73f3a8e313967fd45c3bf1be2d740 Mon Sep 17 00:00:00 2001 From: David Pine <7679720+IEvangelist@users.noreply.github.com> Date: Tue, 13 Oct 2026 10:03:16 -0500 Subject: [PATCH 11/28] Require renderer readiness during App Service warmup Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- src/apphost/Aspire.Dev.AppHost/HybridApiDocsExtensions.cs | 8 ++++++++ .../HybridApiDocsConfigurationTests.cs | 6 ++++++ 2 files changed, 14 insertions(+) diff --git a/src/apphost/Aspire.Dev.AppHost/HybridApiDocsExtensions.cs b/src/apphost/Aspire.Dev.AppHost/HybridApiDocsExtensions.cs index 110b5d44e7..86edd72948 100644 --- a/src/apphost/Aspire.Dev.AppHost/HybridApiDocsExtensions.cs +++ b/src/apphost/Aspire.Dev.AppHost/HybridApiDocsExtensions.cs @@ -46,6 +46,14 @@ public static void WithHybridApiDocs(this IResourceBuilder webs { Name = "WEBSITE_HEALTHCHECK_MAXPINGFAILURES", Value = "2", }); + site.SiteConfig.AppSettings.Add(new AppServiceNameValuePair + { + Name = "WEBSITE_WARMUP_PATH", Value = "/healthz/api-docs", + }); + site.SiteConfig.AppSettings.Add(new AppServiceNameValuePair + { + Name = "WEBSITE_WARMUP_STATUSES", Value = "200", + }); var main = infra.GetProvisionableResources().OfType() .Single(container => ReferenceEquals(container.Parent, site) && container.IsMain.Value); for (var index = 0; index < 2; index++) diff --git a/tests/Aspire.Dev.AppHost.Tests/HybridApiDocsConfigurationTests.cs b/tests/Aspire.Dev.AppHost.Tests/HybridApiDocsConfigurationTests.cs index fa6f6f0bcf..d41c1958a5 100644 --- a/tests/Aspire.Dev.AppHost.Tests/HybridApiDocsConfigurationTests.cs +++ b/tests/Aspire.Dev.AppHost.Tests/HybridApiDocsConfigurationTests.cs @@ -115,6 +115,12 @@ public async Task PublishModelKeepsBothRenderersInsideTheSameWebsite() Assert.Contains(site.SiteConfig.AppSettings, setting => setting.Value is { } pair && pair.Name.Value == "WEBSITE_HEALTHCHECK_MAXPINGFAILURES" && pair.Value.Value == "2"); + Assert.Contains(site.SiteConfig.AppSettings, setting => + setting.Value is { } pair && + pair.Name.Value == "WEBSITE_WARMUP_PATH" && pair.Value.Value == "/healthz/api-docs"); + Assert.Contains(site.SiteConfig.AppSettings, setting => + setting.Value is { } pair && + pair.Name.Value == "WEBSITE_WARMUP_STATUSES" && pair.Value.Value == "200"); }); await using var app = builder.Build(); var bicep = infrastructure.Resource.GetBicepTemplateString(); From 55f9ba5b56644964df757ff3774efa3a0ce40f29 Mon Sep 17 00:00:00 2001 From: David Pine <7679720+IEvangelist@users.noreply.github.com> Date: Tue, 13 Oct 2026 10:59:21 -0500 Subject: [PATCH 12/28] Close the hybrid renderer runtime dependency set Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .github/workflows/ci.yml | 1 + .github/workflows/frontend-build.yml | 12 +++++++ .github/workflows/hybrid-api-docs-poc.yml | 27 ++++++++++++++- src/frontend/Dockerfile.hybrid | 1 + src/frontend/Dockerfile.hybrid.dockerignore | 1 + src/frontend/package.json | 12 +++---- src/frontend/pnpm-lock.yaml | 38 +++++++++++++-------- 7 files changed, 70 insertions(+), 22 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 20554d7878..e834d72cfb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,6 +21,7 @@ concurrency: permissions: contents: read + actions: read security-events: write jobs: diff --git a/.github/workflows/frontend-build.yml b/.github/workflows/frontend-build.yml index 9a569142c8..5ea0348a39 100644 --- a/.github/workflows/frontend-build.yml +++ b/.github/workflows/frontend-build.yml @@ -11,6 +11,10 @@ on: description: Run the opt-in static/hybrid POC comparison default: false type: boolean + hybrid_artifact_run_id: + description: Recheck hybrid container packaging against an existing Linux artifact + default: "" + type: string workflow_call: inputs: node_version: @@ -33,6 +37,11 @@ on: required: false default: false type: boolean + hybrid_artifact_run_id: + description: Recheck hybrid container packaging against an existing Linux artifact + required: false + default: "" + type: string secrets: ASPIRE_BOT_APP_ID: required: false @@ -41,11 +50,14 @@ on: permissions: contents: read + actions: read jobs: hybrid-api-poc: if: ${{ inputs.hybrid_api_poc }} uses: ./.github/workflows/hybrid-api-docs-poc.yml + with: + artifact_run_id: ${{ inputs.hybrid_artifact_run_id }} build: if: ${{ github.event_name != 'workflow_dispatch' || !inputs.hybrid_api_poc }} diff --git a/.github/workflows/hybrid-api-docs-poc.yml b/.github/workflows/hybrid-api-docs-poc.yml index c99236fc0d..d0924eb7c8 100644 --- a/.github/workflows/hybrid-api-docs-poc.yml +++ b/.github/workflows/hybrid-api-docs-poc.yml @@ -2,13 +2,27 @@ name: Hybrid API docs POC on: workflow_call: + inputs: + artifact_run_id: + description: Recheck container packaging using an existing Linux hybrid artifact + required: false + default: '' + type: string workflow_dispatch: + inputs: + artifact_run_id: + description: Recheck container packaging using an existing Linux hybrid artifact + required: false + default: '' + type: string permissions: contents: read + actions: read jobs: windows-artifact: + if: ${{ inputs.artifact_run_id == '' }} runs-on: windows-latest defaults: run: @@ -80,6 +94,14 @@ jobs: global-json-file: global.json - name: Install dependencies run: pnpm install --frozen-lockfile --prefer-offline + - name: Download existing Linux hybrid artifact for packaging verification + if: ${{ inputs.artifact_run_id != '' }} + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: hybrid-api-docs-poc + path: src/frontend/dist-hybrid + github-token: ${{ github.token }} + run-id: ${{ inputs.artifact_run_id }} - name: Verify POC unit contracts env: ASTRO_TELEMETRY_DISABLED: '1' @@ -90,6 +112,7 @@ jobs: dotnet test ../../tests/StaticHost.Tests/StaticHost.Tests.csproj --filter 'FullyQualifiedName~HybridApiDocs' --nologo dotnet test ../../tests/Aspire.Dev.AppHost.Tests/Aspire.Dev.AppHost.Tests.csproj --filter 'FullyQualifiedName~HybridApiDocs' --nologo - name: Build static baseline + if: ${{ inputs.artifact_run_id == '' }} env: ASTRO_TELEMETRY_DISABLED: '1' NODE_OPTIONS: --max-old-space-size=8192 @@ -99,6 +122,7 @@ jobs: mkdir -p "$RUNNER_TEMP/hybrid-poc" /usr/bin/time -v -o "$RUNNER_TEMP/hybrid-poc/static-resources.txt" pnpm build:production - name: Build opted-in hybrid artifact + if: ${{ inputs.artifact_run_id == '' }} env: ASTRO_TELEMETRY_DISABLED: '1' NODE_OPTIONS: --max-old-space-size=8192 @@ -107,6 +131,7 @@ jobs: BUILD_TIMING_OUT: ${{ runner.temp }}/hybrid-poc/hybrid-timing.jsonl run: /usr/bin/time -v -o "$RUNNER_TEMP/hybrid-poc/hybrid-resources.txt" pnpm build:production - name: Verify output and non-API parity + if: ${{ inputs.artifact_run_id == '' }} run: | node scripts/verify-hybrid-output.mjs rm -r dist @@ -124,7 +149,7 @@ jobs: HYBRID_TEST_CONTAINERS: '1' run: node scripts/test-hybrid-host.mjs - name: Upload private POC artifact - if: always() + if: ${{ always() && inputs.artifact_run_id == '' }} uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: hybrid-api-docs-poc diff --git a/src/frontend/Dockerfile.hybrid b/src/frontend/Dockerfile.hybrid index 11ef39a027..a50b11278d 100644 --- a/src/frontend/Dockerfile.hybrid +++ b/src/frontend/Dockerfile.hybrid @@ -12,6 +12,7 @@ ENV NODE_ENV=production \ PORT=4323 \ HYBRID_API_DOCS_MANIFEST=/app/hybrid-api-docs.json COPY --from=dependencies --chown=node:node /app/node_modules ./node_modules +COPY --chown=node:node package.json tsconfig.json ./ COPY --chown=node:node dist-hybrid/server ./server COPY --chown=node:node dist-hybrid/renderer/client ./client COPY --chown=node:node dist-hybrid/renderer/.starlight-icons ./.starlight-icons diff --git a/src/frontend/Dockerfile.hybrid.dockerignore b/src/frontend/Dockerfile.hybrid.dockerignore index b3ebcca929..5f45f17d6a 100644 --- a/src/frontend/Dockerfile.hybrid.dockerignore +++ b/src/frontend/Dockerfile.hybrid.dockerignore @@ -1,6 +1,7 @@ ** !Dockerfile.hybrid !package.json +!tsconfig.json !pnpm-lock.yaml !pnpm-workspace.yaml !patches/ diff --git a/src/frontend/package.json b/src/frontend/package.json index cbba7e78dd..9340e02a4e 100644 --- a/src/frontend/package.json +++ b/src/frontend/package.json @@ -87,9 +87,13 @@ "astro": "^7.2.8", "astro-expressive-code": "^0.44.1", "expressive-code-twoslash": "^0.6.1", + "hast-util-select": "^6.0.4", "hast-util-to-html": "^9.0.5", + "https-proxy-agent": "^9.1.0", "mdast-util-to-hast": "^13.2.1", "mermaid": "^11.16.1", + "node-fetch": "^3.3.2", + "rehype-parse": "^9.0.1", "remark-directive": "^4.0.0", "satori": "^0.28.1", "satteri": "^0.9.5", @@ -104,7 +108,8 @@ "starlight-sidebar-topics": "^0.8.0", "tippy.js": "6.3.7", "tsx": "^4.23.1", - "typescript": "^6.0.3" + "typescript": "^6.0.3", + "unified": "^11.0.5" }, "devDependencies": { "@axe-core/playwright": "^4.12.1", @@ -122,18 +127,13 @@ "eslint": "^10.7.0", "eslint-config-prettier": "^10.1.8", "globals": "^17.7.0", - "hast-util-select": "^6.0.4", "http-proxy-agent": "^9.1.0", - "https-proxy-agent": "^9.1.0", - "node-fetch": "^3.3.2", "prettier": "^3.9.5", "prettier-plugin-astro": "^0.14.1", - "rehype-parse": "^9.0.1", "rehype-remark": "^10.0.1", "remark-gfm": "^4.0.1", "remark-stringify": "^11.0.0", "typescript-eslint": "^8.65.0", - "unified": "^11.0.5", "unist-util-remove": "^4.0.0", "unocss": "66.7.5", "vitest": "^4.1.11" diff --git a/src/frontend/pnpm-lock.yaml b/src/frontend/pnpm-lock.yaml index c38bcdc46e..3323bb41cb 100644 --- a/src/frontend/pnpm-lock.yaml +++ b/src/frontend/pnpm-lock.yaml @@ -110,15 +110,27 @@ importers: expressive-code-twoslash: specifier: ^0.6.1 version: 0.6.1(@expressive-code/core@0.44.1)(eslint@10.7.0(jiti@2.7.0))(expressive-code@0.44.1)(typescript@6.0.3) + hast-util-select: + specifier: ^6.0.4 + version: 6.0.4 hast-util-to-html: specifier: ^9.0.5 version: 9.0.5 + https-proxy-agent: + specifier: ^9.1.0 + version: 9.1.0 mdast-util-to-hast: specifier: ^13.2.1 version: 13.2.1 mermaid: specifier: ^11.16.1 version: 11.16.1 + node-fetch: + specifier: ^3.3.2 + version: 3.3.2 + rehype-parse: + specifier: ^9.0.1 + version: 9.0.1 remark-directive: specifier: ^4.0.0 version: 4.0.0 @@ -164,6 +176,9 @@ importers: typescript: specifier: ^6.0.3 version: 6.0.3 + unified: + specifier: ^11.0.5 + version: 11.0.5 devDependencies: '@axe-core/playwright': specifier: ^4.12.1 @@ -210,27 +225,15 @@ importers: globals: specifier: ^17.7.0 version: 17.7.0 - hast-util-select: - specifier: ^6.0.4 - version: 6.0.4 http-proxy-agent: specifier: ^9.1.0 version: 9.1.0 - https-proxy-agent: - specifier: ^9.1.0 - version: 9.1.0 - node-fetch: - specifier: ^3.3.2 - version: 3.3.2 prettier: specifier: ^3.9.5 version: 3.9.5 prettier-plugin-astro: specifier: ^0.14.1 version: 0.14.1 - rehype-parse: - specifier: ^9.0.1 - version: 9.0.1 rehype-remark: specifier: ^10.0.1 version: 10.0.1 @@ -243,9 +246,6 @@ importers: typescript-eslint: specifier: ^8.65.0 version: 8.65.0(eslint@10.7.0(jiti@2.7.0))(typescript@6.0.3) - unified: - specifier: ^11.0.5 - version: 11.0.5 unist-util-remove: specifier: ^4.0.0 version: 4.0.0 @@ -5167,6 +5167,13 @@ snapshots: dependencies: '@chevrotain/types': 11.1.2 + '@napi-rs/wasm-runtime@1.1.6(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)': + dependencies: + '@emnapi/core': 1.10.0 + '@emnapi/runtime': 1.10.0 + '@tybys/wasm-util': 0.10.3 + optional: true + '@napi-rs/wasm-runtime@1.1.6(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)': dependencies: '@emnapi/core': 1.11.1 @@ -5242,6 +5249,7 @@ snapshots: dependencies: '@emnapi/core': 1.10.0 '@emnapi/runtime': 1.10.0 + '@napi-rs/wasm-runtime': 1.1.6(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) optional: true '@oxc-parser/binding-win32-arm64-msvc@0.131.0': From 45d688f91a6b6585de4ed63e051ff0009f468850 Mon Sep 17 00:00:00 2001 From: David Pine <7679720+IEvangelist@users.noreply.github.com> Date: Tue, 13 Oct 2026 12:02:14 -0500 Subject: [PATCH 13/28] Allow isolated local and Azure hybrid artifact selection Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- CONTRIBUTING.md | 3 +++ src/apphost/Aspire.Dev.AppHost/AppHost.cs | 1 + .../Aspire.Dev.AppHost/HybridApiDocsExtensions.cs | 4 +++- src/statichost/StaticHost/StaticHost.csproj | 5 +++-- .../HybridApiDocsConfigurationTests.cs | 14 +++++++++----- 5 files changed, 19 insertions(+), 8 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a6f7c78792..47d8fee4ea 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -93,6 +93,9 @@ Aspire deployment. Both images must use the same Linux build artifact. No Azure resources are provisioned by the POC CI. Runtime images are restricted to bundled local files and dimensions up to 4096 pixels. +Set `HybridApiDocsArtifactDirectory` to select an artifact outside `dist-hybrid`, +for example when keeping Windows local and Linux deployment artifacts separate. + Unset the flag to return to the ordinary Vite/local workflow: ```powershell diff --git a/src/apphost/Aspire.Dev.AppHost/AppHost.cs b/src/apphost/Aspire.Dev.AppHost/AppHost.cs index b23bebb9ac..34211e6fc9 100644 --- a/src/apphost/Aspire.Dev.AppHost/AppHost.cs +++ b/src/apphost/Aspire.Dev.AppHost/AppHost.cs @@ -17,6 +17,7 @@ .RunAsContainer(); var staticHostWebsite = builder.AddProject("aspiredev") + .WithComputeEnvironment(production) .WithReference(cache) .WithExternalHttpEndpoints() .PublishAsAzureAppServiceWebsite((infra, website) => diff --git a/src/apphost/Aspire.Dev.AppHost/HybridApiDocsExtensions.cs b/src/apphost/Aspire.Dev.AppHost/HybridApiDocsExtensions.cs index 86edd72948..f1184e692c 100644 --- a/src/apphost/Aspire.Dev.AppHost/HybridApiDocsExtensions.cs +++ b/src/apphost/Aspire.Dev.AppHost/HybridApiDocsExtensions.cs @@ -16,7 +16,9 @@ internal static class HybridApiDocsExtensions public static void WithHybridApiDocs(this IResourceBuilder website, IDistributedApplicationBuilder builder, string frontendDirectory) { - var manifest = Path.GetFullPath(Path.Combine(frontendDirectory, "dist-hybrid", "hybrid-api-docs.json")); + var artifactDirectory = builder.Configuration["HybridApiDocsArtifactDirectory"] + ?? Path.Combine(frontendDirectory, "dist-hybrid"); + var manifest = Path.GetFullPath(Path.Combine(artifactDirectory, "hybrid-api-docs.json")); if (!File.Exists(manifest)) throw new InvalidOperationException($"Build or download the opted-in hybrid CI artifact: {manifest}"); using var json = JsonDocument.Parse(File.ReadAllText(manifest)); diff --git a/src/statichost/StaticHost/StaticHost.csproj b/src/statichost/StaticHost/StaticHost.csproj index 8f9caf4b93..bc0f621996 100644 --- a/src/statichost/StaticHost/StaticHost.csproj +++ b/src/statichost/StaticHost/StaticHost.csproj @@ -9,6 +9,7 @@ noble-chiseled obj/$(Configuration)/hybrid/ $(DefineConstants);HYBRID_API_DOCS_BUILD + $(MSBuildProjectDirectory)/../../frontend/dist-hybrid false @@ -39,11 +40,11 @@ - - diff --git a/tests/Aspire.Dev.AppHost.Tests/HybridApiDocsConfigurationTests.cs b/tests/Aspire.Dev.AppHost.Tests/HybridApiDocsConfigurationTests.cs index d41c1958a5..ba16ba719e 100644 --- a/tests/Aspire.Dev.AppHost.Tests/HybridApiDocsConfigurationTests.cs +++ b/tests/Aspire.Dev.AppHost.Tests/HybridApiDocsConfigurationTests.cs @@ -17,19 +17,23 @@ public void BuildModeRequiresExplicitOptIn(string? value, bool expected) public void InvalidBuildModeFailsClearly() => Assert.Throws(() => HybridApiDocsExtensions.IsHybridApiDocsEnabled("true")); - [Fact] - public async Task LocalGraphUsesTwoPrivateWorkersAndEndpointReferences() + [Theory] + [InlineData(false)] + [InlineData(true)] + public async Task LocalGraphUsesTwoPrivateWorkersAndEndpointReferences(bool externalArtifact) { var directory = Path.Combine(Path.GetTempPath(), $"aspire-hybrid-graph-{Guid.NewGuid():N}"); - Directory.CreateDirectory(Path.Combine(directory, "dist-hybrid")); + var artifactDirectory = Path.Combine(directory, externalArtifact ? "artifact-windows" : "dist-hybrid"); + Directory.CreateDirectory(artifactDirectory); try { - File.WriteAllText(Path.Combine(directory, "dist-hybrid", "hybrid-api-docs.json"), + File.WriteAllText(Path.Combine(artifactDirectory, "hybrid-api-docs.json"), $$"""{"mode":"hybrid-api-docs","platform":"{{(OperatingSystem.IsWindows() ? "win32" : "linux")}}"}"""); var builder = DistributedApplication.CreateBuilder(new DistributedApplicationOptions { DisableDashboard = true, }); + if (externalArtifact) builder.Configuration["HybridApiDocsArtifactDirectory"] = artifactDirectory; var website = builder.AddProject("aspiredev"); website.WithHybridApiDocs(builder, directory); await using var app = builder.Build(); @@ -50,7 +54,7 @@ public async Task LocalGraphUsesTwoPrivateWorkersAndEndpointReferences() } Assert.IsType(environment["HybridApiDocs__RendererUrls__0"]); Assert.IsType(environment["HybridApiDocs__RendererUrls__1"]); - Assert.Equal(Path.Combine(directory, "dist-hybrid", "hybrid-api-docs.json"), + Assert.Equal(Path.Combine(artifactDirectory, "hybrid-api-docs.json"), environment["HybridApiDocs__ArtifactPath"]); } finally From ecbdc0cd6fd82c70c01b666f69e99e5d0614e66a Mon Sep 17 00:00:00 2001 From: David Pine <7679720+IEvangelist@users.noreply.github.com> Date: Tue, 13 Oct 2026 13:16:17 -0500 Subject: [PATCH 14/28] Compress hybrid static and forwarded responses Hybrid mode serves plain files and forwards uncompressed renderer output, so pages, assets and sitemaps lost the precompression of the static build. Enable Brotli and gzip response compression for the hybrid pipeline. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .../HybridApiDocs/HybridApiDocsExtensions.cs | 9 ++++++ src/statichost/StaticHost/Program.cs | 6 +++- tests/StaticHost.Tests/HybridApiDocsTests.cs | 30 +++++++++++++++++++ 3 files changed, 44 insertions(+), 1 deletion(-) diff --git a/src/statichost/StaticHost/HybridApiDocs/HybridApiDocsExtensions.cs b/src/statichost/StaticHost/HybridApiDocs/HybridApiDocsExtensions.cs index 20e8593b5b..20b1d024ef 100644 --- a/src/statichost/StaticHost/HybridApiDocs/HybridApiDocsExtensions.cs +++ b/src/statichost/StaticHost/HybridApiDocs/HybridApiDocsExtensions.cs @@ -1,4 +1,5 @@ using System.Net; +using Microsoft.AspNetCore.ResponseCompression; namespace StaticHost.HybridApiDocs; @@ -21,6 +22,14 @@ endpoint.Scheme is not ("http" or "https") || }).Distinct().ToArray(); if (endpoints.Length == 0) throw new InvalidOperationException("At least one private Astro worker endpoint is required."); + // The hybrid client is served from plain files and renderer responses are forwarded + // uncompressed, so neither has the build-time precompression of static web assets. + services.AddResponseCompression(options => + { + options.EnableForHttps = true; + options.MimeTypes = ResponseCompressionDefaults.MimeTypes + .Union(["text/javascript", "text/markdown", "image/svg+xml"]); + }); services.AddSingleton(artifact); services.AddSingleton(new HybridApiDocsEndpointPool(endpoints)); services.AddHttpClient(client => diff --git a/src/statichost/StaticHost/Program.cs b/src/statichost/StaticHost/Program.cs index 1128798d4b..66abef0cdb 100644 --- a/src/statichost/StaticHost/Program.cs +++ b/src/statichost/StaticHost/Program.cs @@ -68,7 +68,11 @@ app.UseHttpsRedirection(); // Resolve request casing before any middleware rewrites or matches the static path. -if (hybridArtifact is not null) app.UseHybridApiDocsRouting(); +if (hybridArtifact is not null) +{ + app.UseResponseCompression(); + app.UseHybridApiDocsRouting(); +} app.UseCanonicalPathRedirects(); // Agent-readiness middlewares MUST run before UseDefaultFiles + UseRouting: diff --git a/tests/StaticHost.Tests/HybridApiDocsTests.cs b/tests/StaticHost.Tests/HybridApiDocsTests.cs index f4d8f4ce53..9c9cecf030 100644 --- a/tests/StaticHost.Tests/HybridApiDocsTests.cs +++ b/tests/StaticHost.Tests/HybridApiDocsTests.cs @@ -146,6 +146,35 @@ public async Task BuffersLargeResponsesButRequiresWorkerEvenForPreviouslyVisited Assert.Equal(HttpStatusCode.BadGateway, cold.StatusCode); } + [Theory] + [InlineData("/reference/api/large/", "br")] + [InlineData("/reference/api/large/", "gzip")] + [InlineData("/reference/api/demo.md", "br")] + [InlineData("/guide/", "br")] + public async Task CompressesForwardedAndStaticResponsesWhenTheClientAllowsIt(string path, string encoding) + { + await using var host = await HybridHost.StartAsync(); + using var plain = await host.Client.GetAsync(path); + var expected = await plain.Content.ReadAsByteArrayAsync(); + Assert.Empty(plain.Content.Headers.ContentEncoding); + + using var request = new HttpRequestMessage(HttpMethod.Get, path); + request.Headers.AcceptEncoding.ParseAdd(encoding); + using var response = await host.Client.SendAsync(request); + var compressed = await response.Content.ReadAsByteArrayAsync(); + Assert.Equal(encoding, Assert.Single(response.Content.Headers.ContentEncoding)); + Assert.Contains("Accept-Encoding", response.Headers.Vary); + Assert.True(compressed.Length < expected.Length); + + await using var input = new MemoryStream(compressed); + await using Stream decoder = encoding == "br" + ? new System.IO.Compression.BrotliStream(input, System.IO.Compression.CompressionMode.Decompress) + : new System.IO.Compression.GZipStream(input, System.IO.Compression.CompressionMode.Decompress); + using var decoded = new MemoryStream(); + await decoder.CopyToAsync(decoded); + Assert.Equal(expected, decoded.ToArray()); + } + [Fact] public async Task FailsOverAndKeepsUsingTheHealthyReplica() { @@ -277,6 +306,7 @@ public static async Task StartAsync(string[]? endpoints = null) var renderer = new TestApiRenderer(); builder.Services.AddHttpClient().ConfigurePrimaryHttpMessageHandler(() => renderer); var app = builder.Build(); + app.UseResponseCompression(); app.UseHybridApiDocsRouting(); app.UseAgentReadiness(); app.UseDefaultFiles(); From 5f6063c035b16c69dbf1815048eaaa900e719e66 Mon Sep 17 00:00:00 2001 From: David Pine <7679720+IEvangelist@users.noreply.github.com> Date: Tue, 13 Oct 2026 13:17:10 -0500 Subject: [PATCH 15/28] Assert compression savings only for the large body Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- tests/StaticHost.Tests/HybridApiDocsTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/StaticHost.Tests/HybridApiDocsTests.cs b/tests/StaticHost.Tests/HybridApiDocsTests.cs index 9c9cecf030..0950771a4e 100644 --- a/tests/StaticHost.Tests/HybridApiDocsTests.cs +++ b/tests/StaticHost.Tests/HybridApiDocsTests.cs @@ -164,7 +164,7 @@ public async Task CompressesForwardedAndStaticResponsesWhenTheClientAllowsIt(str var compressed = await response.Content.ReadAsByteArrayAsync(); Assert.Equal(encoding, Assert.Single(response.Content.Headers.ContentEncoding)); Assert.Contains("Accept-Encoding", response.Headers.Vary); - Assert.True(compressed.Length < expected.Length); + if (path.EndsWith("/large/")) Assert.True(compressed.Length < 1_000_000); await using var input = new MemoryStream(compressed); await using Stream decoder = encoding == "br" From 8b974b29ea60d099ee87f56d876b87fb07dcc739 Mon Sep 17 00:00:00 2001 From: David Pine <7679720+IEvangelist@users.noreply.github.com> Date: Tue, 13 Oct 2026 13:56:36 -0500 Subject: [PATCH 16/28] Serve API search indexes as separate JSON instead of inline HTML The TypeScript API landing page embedded a 13 MB search index in its HTML. Landing, package and module pages now fetch a prerendered JSON file with a delayed loading state and an in-place retry when the download fails. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- src/frontend/scripts/verify-hybrid-output.mjs | 4 + .../api-reference/search-lifecycle.ts | 40 +++ .../pages/reference/api-search/csharp.json.ts | 13 + .../api-search/csharp/[package].json.ts | 24 ++ .../reference/api-search/typescript.json.ts | 15 + .../api-search/typescript/[module].json.ts | 25 ++ .../reference/api/_search-presentation.ts | 87 +++++- .../api/csharp/[package]/index.astro | 87 +----- .../pages/reference/api/csharp/index.astro | 104 +------ .../api/typescript/[module]/index.astro | 145 +-------- .../reference/api/typescript/index.astro | 17 +- src/frontend/src/utils/api-search-index.ts | 277 ++++++++++++++++++ .../tests/e2e/api-search-contract.spec.ts | 74 +++-- .../tests/e2e/hybrid-api-docs.spec.ts | 7 +- .../api-search-index-loading.vitest.test.ts | 161 ++++++++++ .../unit/api-search-lifecycle.vitest.test.ts | 16 +- .../tests/unit/hybrid-api-docs.vitest.test.ts | 14 +- 17 files changed, 758 insertions(+), 352 deletions(-) create mode 100644 src/frontend/src/pages/reference/api-search/csharp.json.ts create mode 100644 src/frontend/src/pages/reference/api-search/csharp/[package].json.ts create mode 100644 src/frontend/src/pages/reference/api-search/typescript.json.ts create mode 100644 src/frontend/src/pages/reference/api-search/typescript/[module].json.ts create mode 100644 src/frontend/src/utils/api-search-index.ts create mode 100644 src/frontend/tests/unit/api-search-index-loading.vitest.test.ts diff --git a/src/frontend/scripts/verify-hybrid-output.mjs b/src/frontend/scripts/verify-hybrid-output.mjs index 591e64d58d..91c238b950 100644 --- a/src/frontend/scripts/verify-hybrid-output.mjs +++ b/src/frontend/scripts/verify-hybrid-output.mjs @@ -28,6 +28,10 @@ export async function verifyHybridOutput(staticRoot, hybridRoot) { const nonApi = (files) => files.filter(({ path }) => /\.(html|md)$/.test(path) && !api(path) && !redirectFiles.has(path)).map(({ path }) => path); assert.deepEqual(nonApi(hybrid.files), nonApi(baseline.files), 'Non-API page inventory changed.'); + const searchIndex = (files) => files.map(({ path }) => path) + .filter((path) => path.startsWith('reference/api-search/') && path.endsWith('.json')); + assert.ok(searchIndex(hybrid.files).includes('reference/api-search/typescript.json'), 'Missing API search index.'); + assert.deepEqual(searchIndex(hybrid.files), searchIndex(baseline.files), 'API search indexes must stay prerendered.'); for (const file of ['index.html', '404.html', 'llms.txt', 'sitemap-index.xml', 'sitemap-api.xml']) { assert.ok(hybrid.files.some(({ path }) => path === file), `Missing ${file}`); } diff --git a/src/frontend/src/components/api-reference/search-lifecycle.ts b/src/frontend/src/components/api-reference/search-lifecycle.ts index a0a0856c39..5ac7573d3c 100644 --- a/src/frontend/src/components/api-reference/search-lifecycle.ts +++ b/src/frontend/src/components/api-reference/search-lifecycle.ts @@ -48,3 +48,43 @@ export function readApiSearchIndex(root: HTMLElement): T[] { } return JSON.parse(indexJson) as T[]; } + +/** The index could not be downloaded or understood, so trying again may succeed. */ +export class ApiSearchIndexLoadError extends Error { + constructor(message: string, options?: ErrorOptions) { + super(message, options); + this.name = 'ApiSearchIndexLoadError'; + } +} + +/** + * Large indexes are served as a separate JSON file named by `data-api-search-index-url`. + * Small ones are still embedded in the page and read synchronously. + */ +export async function loadApiSearchIndex(root: HTMLElement, signal: AbortSignal): Promise { + const url = root.dataset.apiSearchIndexUrl; + if (!url) return readApiSearchIndex(root); + + let response: Response; + try { + response = await fetch(url, { signal, headers: { Accept: 'application/json' } }); + } catch (error) { + if (signal.aborted) throw error; + throw new ApiSearchIndexLoadError('API search: the search index could not be downloaded', { cause: error }); + } + if (!response.ok) { + throw new ApiSearchIndexLoadError(`API search: the search index request failed (HTTP ${response.status})`); + } + + let index: unknown; + try { + index = await response.json(); + } catch (error) { + if (signal.aborted) throw error; + throw new ApiSearchIndexLoadError('API search: the search index is not valid JSON', { cause: error }); + } + if (!Array.isArray(index)) { + throw new ApiSearchIndexLoadError('API search: the search index is not a list'); + } + return index as T[]; +} diff --git a/src/frontend/src/pages/reference/api-search/csharp.json.ts b/src/frontend/src/pages/reference/api-search/csharp.json.ts new file mode 100644 index 0000000000..1e8999c53b --- /dev/null +++ b/src/frontend/src/pages/reference/api-search/csharp.json.ts @@ -0,0 +1,13 @@ +import type { APIRoute } from 'astro'; + +import { apiSearchIndexResponse, buildCSharpApiSearchIndex } from '@utils/api-search-index'; +import { getPackages } from '@utils/packages'; + +export const prerender = true; + +export const GET: APIRoute = async () => { + const packages = (await getPackages()) + .map((entry) => entry.data) + .sort((a, b) => a.package.name.localeCompare(b.package.name)); + return apiSearchIndexResponse(buildCSharpApiSearchIndex(packages).index); +}; diff --git a/src/frontend/src/pages/reference/api-search/csharp/[package].json.ts b/src/frontend/src/pages/reference/api-search/csharp/[package].json.ts new file mode 100644 index 0000000000..41e65e45b3 --- /dev/null +++ b/src/frontend/src/pages/reference/api-search/csharp/[package].json.ts @@ -0,0 +1,24 @@ +import type { APIRoute } from 'astro'; + +import { apiSearchIndexResponse, buildCSharpPackageSearchIndex } from '@utils/api-search-index'; +import type { PackageApiDocument } from '@utils/packages'; +import { getPackages, packageSlug } from '@utils/packages'; + +export const prerender = true; + +type RouteProps = { + pkg: PackageApiDocument; +}; + +export async function getStaticPaths() { + const packages = await getPackages(); + return packages.map((entry) => ({ + params: { package: packageSlug(entry.data.package.name) }, + props: { pkg: entry.data } satisfies RouteProps, + })); +} + +export const GET: APIRoute = ({ props }) => { + const { pkg } = props as RouteProps; + return apiSearchIndexResponse(buildCSharpPackageSearchIndex(pkg.types.filter((type) => type.name)).index); +}; diff --git a/src/frontend/src/pages/reference/api-search/typescript.json.ts b/src/frontend/src/pages/reference/api-search/typescript.json.ts new file mode 100644 index 0000000000..99440f55b7 --- /dev/null +++ b/src/frontend/src/pages/reference/api-search/typescript.json.ts @@ -0,0 +1,15 @@ +import type { APIRoute } from 'astro'; + +import { apiSearchIndexResponse } from '@utils/api-search-index'; +import { buildTsApiSearchIndex } from '@utils/ts-api-search'; +import { getTsModules } from '@utils/ts-modules'; + +export const prerender = true; + +export const GET: APIRoute = async () => { + const base = import.meta.env.BASE_URL.replace(/\/$/, ''); + const modules = (await getTsModules()) + .map((entry) => entry.data) + .sort((a, b) => a.package.name.localeCompare(b.package.name)); + return apiSearchIndexResponse(buildTsApiSearchIndex(modules, base)); +}; diff --git a/src/frontend/src/pages/reference/api-search/typescript/[module].json.ts b/src/frontend/src/pages/reference/api-search/typescript/[module].json.ts new file mode 100644 index 0000000000..2034cb156c --- /dev/null +++ b/src/frontend/src/pages/reference/api-search/typescript/[module].json.ts @@ -0,0 +1,25 @@ +import type { APIRoute } from 'astro'; + +import { apiSearchIndexResponse, buildTsModuleSearchIndex } from '@utils/api-search-index'; +import type { TsApiDocument } from '@utils/ts-modules'; +import { getTsModules, tsModuleSlug } from '@utils/ts-modules'; + +export const prerender = true; + +type RouteProps = { + pkg: TsApiDocument; +}; + +export async function getStaticPaths() { + const modules = await getTsModules(); + return modules.map((entry) => ({ + params: { module: tsModuleSlug(entry.data.package.name) }, + props: { pkg: entry.data } satisfies RouteProps, + })); +} + +export const GET: APIRoute = ({ props }) => { + const base = import.meta.env.BASE_URL.replace(/\/$/, ''); + const { pkg } = props as RouteProps; + return apiSearchIndexResponse(buildTsModuleSearchIndex(pkg, base).index); +}; diff --git a/src/frontend/src/pages/reference/api/_search-presentation.ts b/src/frontend/src/pages/reference/api/_search-presentation.ts index 8c0d37c97e..f759563619 100644 --- a/src/frontend/src/pages/reference/api/_search-presentation.ts +++ b/src/frontend/src/pages/reference/api/_search-presentation.ts @@ -1,28 +1,87 @@ import { createSearchEmptyState, searchRecoveryAction } from '@components/search/search-empty-state'; +import { ApiSearchIndexLoadError } from '@components/api-reference/search-lifecycle'; -/** A corrupt/unavailable embedded index is not a valid zero-result response. */ -export function withApiSearchFallback(mount: (root: HTMLElement, signal: AbortSignal) => void) { +const LOADING_TEXT = 'Loading search index…'; +const LOADING_DELAY_MS = 150; + +/** + * A corrupt or unavailable index is not a valid zero-result response. Downloaded + * indexes can be retried in place; anything else needs a page reload. A slow + * download shows a loading message only after a short delay, to avoid flashing. + */ +export function withApiSearchFallback(mount: (root: HTMLElement, signal: AbortSignal) => unknown) { return (root: HTMLElement, signal: AbortSignal) => { - const controller = new AbortController(); - signal.addEventListener('abort', () => controller.abort(), { once: true }); - try { - mount(root, controller.signal); - } catch (error) { - controller.abort(); - console.error('API search unavailable', error); + const statusElements = [...root.querySelectorAll('[id$="-search-status"], [id$="-search-count"]')]; + const originalText = new Map(statusElements.map(element => [element, element.textContent])); + const disabled: (HTMLInputElement | HTMLButtonElement)[] = []; + + const showLoading = (attemptSignal: AbortSignal) => { + const timer = setTimeout(() => { + root.dataset.apiSearchState = 'loading'; + statusElements.forEach(element => { element.textContent = LOADING_TEXT; }); + }, LOADING_DELAY_MS); + attemptSignal.addEventListener('abort', () => clearTimeout(timer), { once: true }); + return () => { + clearTimeout(timer); + delete root.dataset.apiSearchState; + statusElements.forEach(element => { + if (element.textContent === LOADING_TEXT) element.textContent = originalText.get(element) ?? ''; + }); + }; + }; + + const retry = (results: HTMLElement) => { + results.replaceChildren(); + results.style.display = 'none'; + statusElements.forEach(element => { element.textContent = originalText.get(element) ?? ''; }); + disabled.splice(0).forEach(element => { element.disabled = false; }); + start(); + }; + + const showUnavailable = (retryable: boolean) => { const results = root.querySelector('[id$="-search-results"]'); if (!results) return; results.style.display = ''; results.replaceChildren(createSearchEmptyState({ title: 'Search unavailable', - hint: 'Reload this page to try again. You can still browse the API reference below.', - action: { label: 'Reload page', run: () => { if (!signal.aborted) window.location.reload(); } }, + hint: retryable + ? 'The search index could not be loaded. You can still browse the API reference below.' + : 'Reload this page to try again. You can still browse the API reference below.', + action: retryable + ? { label: 'Try again', run: () => { if (!signal.aborted) retry(results); } } + : { label: 'Reload page', run: () => { if (!signal.aborted) window.location.reload(); } }, })); - root.querySelectorAll('[id$="-search-status"], [id$="-search-count"]') - .forEach(element => { element.textContent = 'Search unavailable'; }); + statusElements.forEach(element => { element.textContent = 'Search unavailable'; }); root.querySelectorAll('.inpage-search input, .inpage-search button') - .forEach(element => { if (!results.contains(element)) element.disabled = true; }); + .forEach(element => { + if (results.contains(element)) return; + element.disabled = true; + disabled.push(element); + }); + }; + + function start() { + const controller = new AbortController(); + signal.addEventListener('abort', () => controller.abort(), { once: true }); + const stopLoading = showLoading(controller.signal); + const fail = (error: unknown) => { + stopLoading(); + controller.abort(); + if (signal.aborted) return; + console.error('API search unavailable', error); + showUnavailable(error instanceof ApiSearchIndexLoadError); + }; + try { + const pending = mount(root, controller.signal); + if (typeof (pending as PromiseLike | undefined)?.then === 'function') { + (pending as PromiseLike).then(stopLoading, fail); + } else stopLoading(); + } catch (error) { + fail(error); + } } + + start(); }; } diff --git a/src/frontend/src/pages/reference/api/csharp/[package]/index.astro b/src/frontend/src/pages/reference/api/csharp/[package]/index.astro index b6f84bae25..8af2488000 100644 --- a/src/frontend/src/pages/reference/api/csharp/[package]/index.astro +++ b/src/frontend/src/pages/reference/api/csharp/[package]/index.astro @@ -7,7 +7,8 @@ * and collapsible namespace sections. */ import StarlightPage from '@astrojs/starlight/components/StarlightPage.astro'; -import { genericArity, typeDisplayName, groupTypesByNamespace, typeHref, nugetHref, packageSlug, slugify, getPackages, resolveMemberAnchors } from '@utils/packages'; +import { genericArity, typeDisplayName, groupTypesByNamespace, typeHref, nugetHref, packageSlug, getPackages } from '@utils/packages'; +import { apiSearchIndexUrl, buildCSharpPackageSearchIndex } from '@utils/api-search-index'; import { getApiReferenceSidebar } from '@utils/api-sidebar'; import InpageSearch from '@components/api-reference/InpageSearch.astro'; import Expand from '@components/Expand.astro'; @@ -42,76 +43,9 @@ const headings = [...namespaceGroups.keys()].map((ns) => ({ /* Build package-scoped search index */ -interface PkgIndexEntry { - /** Short name */ - n: string; - /** Fully-qualified name */ - f: string; - /** Namespace */ - ns: string; - /** Kind (class, interface, enum, method, property, ...) */ - k: string; - /** Summary text (first ~160 chars) */ - s: string; - /** Parent type name (for members only) */ - t?: string; - /** Precomputed anchor slug (when it differs from the name-derived slug) */ - a?: string; -} - -function extractSummary(summary: any): string { - if (!summary || !Array.isArray(summary)) return ''; - return summary - .map((node: any) => { - if (node.kind === 'text') return node.text; - if (node.kind === 'cref') return node.value?.split('.').pop() ?? ''; - if (node.kind === 'paramref' || node.kind === 'typeparamref') return node.value ?? ''; - if (node.kind === 'langword') return node.value ?? ''; - return ''; - }) - .join('') - .replace(/\s+/g, ' ') - .trim() - .slice(0, 160); -} - -const pkgIndex: PkgIndexEntry[] = []; -let memberCount = 0; - -for (const type of validTypes) { - const typeSlug = slugify(type.name, genericArity(type)); - pkgIndex.push({ - n: type.name, - f: type.fullName ?? type.name, - ns: type.namespace ?? '', - k: type.kind ?? 'class', - s: extractSummary(type.docs?.summary), - ...(typeSlug !== type.name.toLowerCase() ? { g: typeSlug } : {}), - }); - - const members: any[] = type.members ?? []; - const memberAnchors = resolveMemberAnchors(members); - for (const [memberIndex, member] of members.entries()) { - memberCount++; - const memberName = member.name === '.ctor' ? `${type.name} (constructor)` : member.name; - const memberFull = `${type.fullName ?? type.name}.${member.name === '.ctor' ? '.ctor' : member.name}`; - const slug = memberAnchors[memberIndex].exact; - const defaultSlug = memberName.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, ''); - pkgIndex.push({ - n: memberName, - f: memberFull, - ns: type.namespace ?? '', - k: member.kind ?? 'method', - s: extractSummary(member.docs?.summary), - t: type.name, - ...(slug !== defaultSlug ? { a: slug } : {}), - ...(typeSlug !== type.name.toLowerCase() ? { ts: typeSlug } : {}), - }); - } -} +const { index: pkgIndex, memberCount } = buildCSharpPackageSearchIndex(validTypes); const allKinds = [...new Set(pkgIndex.map(e => e.k))].sort(); -const pkgIndexJson = JSON.stringify(pkgIndex); const pkgName = pkg.package.name; function getCommonSourceDirectory(types: any[]): string | null { @@ -213,8 +147,7 @@ const packageSourceHref = pkg.package.sourceRepository && pkg.package.sourceComm -
- +

API reference temporarily unavailable

+

This page could not be loaded right now. Try again in a moment.

+ Try againBack to the docs
+ """); + + public static async Task WriteUnavailableAsync(HttpContext context, int statusCode) + { + var response = context.Response; + response.StatusCode = statusCode; + response.Headers.CacheControl = "no-store"; + response.Headers.RetryAfter = "5"; + response.ContentType = "text/html; charset=utf-8"; + response.ContentLength = Unavailable.Length; + if (!HttpMethods.IsHead(context.Request.Method)) await response.Body.WriteAsync(Unavailable, context.RequestAborted); + } +} diff --git a/src/statichost/StaticHost/HybridApiDocs/HybridApiDocsExtensions.cs b/src/statichost/StaticHost/HybridApiDocs/HybridApiDocsExtensions.cs index 20b1d024ef..6017a92004 100644 --- a/src/statichost/StaticHost/HybridApiDocs/HybridApiDocsExtensions.cs +++ b/src/statichost/StaticHost/HybridApiDocs/HybridApiDocsExtensions.cs @@ -32,6 +32,7 @@ endpoint.Scheme is not ("http" or "https") || }); services.AddSingleton(artifact); services.AddSingleton(new HybridApiDocsEndpointPool(endpoints)); + services.AddSingleton(); services.AddHttpClient(client => { client.Timeout = Timeout.InfiniteTimeSpan; diff --git a/src/statichost/StaticHost/HybridApiDocs/HybridApiDocsFlights.cs b/src/statichost/StaticHost/HybridApiDocs/HybridApiDocsFlights.cs new file mode 100644 index 0000000000..702ecb7833 --- /dev/null +++ b/src/statichost/StaticHost/HybridApiDocs/HybridApiDocsFlights.cs @@ -0,0 +1,21 @@ +using System.Collections.Concurrent; + +namespace StaticHost.HybridApiDocs; + +internal sealed record HybridApiDocsResponse( + int Status, KeyValuePair[] Headers, byte[] Body, bool Unavailable, bool Cacheable) +{ + public string? CacheStatus => Headers.FirstOrDefault(header => + header.Key.Equals("X-Astro-Cache", StringComparison.OrdinalIgnoreCase)).Value?.FirstOrDefault(); + + public static HybridApiDocsResponse Failure(int status) => new(status, [], [], true, false); +} + +/// +/// The renderer client is transient, so identical in-flight renders are tracked here. One render per +/// URL is shared by every waiting request; a stampede on a cold page costs a single render. +/// +internal sealed class HybridApiDocsFlights +{ + public ConcurrentDictionary>> Requests { get; } = new(); +} diff --git a/src/statichost/StaticHost/HybridApiDocs/HybridApiDocsRenderer.cs b/src/statichost/StaticHost/HybridApiDocs/HybridApiDocsRenderer.cs index 33278cee81..d095c6bb3d 100644 --- a/src/statichost/StaticHost/HybridApiDocs/HybridApiDocsRenderer.cs +++ b/src/statichost/StaticHost/HybridApiDocs/HybridApiDocsRenderer.cs @@ -1,9 +1,11 @@ -using System.Net; +using Microsoft.Net.Http.Headers; +using System.Security.Cryptography; +using System.Text; namespace StaticHost.HybridApiDocs; internal sealed class HybridApiDocsRenderer(HttpClient client, HybridApiDocsArtifact artifact, HybridApiDocsEndpointPool endpoints, - ILogger logger) + HybridApiDocsFlights flights, ILogger logger) { internal const long MaximumBodySize = 64 * 1024 * 1024; private static readonly HashSet ExcludedHeaders = new(StringComparer.OrdinalIgnoreCase) @@ -20,21 +22,121 @@ public async Task RenderAsync(HttpContext context) context.Response.StatusCode = StatusCodes.Status404NotFound; return; } - using var timeout = CancellationTokenSource.CreateLinkedTokenSource(context.RequestAborted); - timeout.CancelAfter(TimeSpan.FromSeconds(30)); - var candidates = endpoints.Candidates().ToArray(); + + // Pages never vary by query string, so it is not forwarded and cannot multiply renders. + var image = selection.Representation == "image"; + var upstream = image ? selection.RendererPath + context.Request.QueryString : selection.RendererPath; + + // A page is immutable for a build, so a matching validator is answered without the renderer. + var etag = selection.Representation is "html" or "markdown" ? ETagFor(selection.RendererPath) : null; + if (etag is not null && IsNotModified(context.Request, etag)) + { + context.Response.StatusCode = StatusCodes.Status304NotModified; + context.Response.Headers.ETag = etag; + context.Response.Headers.CacheControl = "no-cache"; + context.Response.Headers["X-Aspire-Build-Id"] = artifact.Manifest.BuildId; + return; + } + + HybridApiDocsResponse result; + try + { + var flight = flights.Requests.GetOrAdd(upstream, key => new(() => FetchSharedAsync(key))); + result = await flight.Value.WaitAsync(context.RequestAborted); + } + catch (OperationCanceledException) when (context.RequestAborted.IsCancellationRequested) + { + context.Abort(); + return; + } + + if (result.Unavailable) + { + await HybridApiDocsErrorPages.WriteUnavailableAsync(context, result.Status); + return; + } + + var response = context.Response; + response.StatusCode = result.Status; + foreach (var (key, values) in result.Headers) response.Headers[key] = values; + var vary = response.Headers.Vary.ToString().Split(',', StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries) + .Where(value => !value.Equals("X-Aspire-Cache-Bypass", StringComparison.OrdinalIgnoreCase)).ToArray(); + if (vary.Length == 0) response.Headers.Remove("Vary"); + else response.Headers.Vary = string.Join(", ", vary); + if (selection.Representation == "markdown-negotiated") + { + response.Headers.CacheControl = "private, no-store"; + response.Headers.Vary = "Accept"; + } + else if (result.Cacheable && etag is not null) + { + response.Headers.CacheControl = "no-cache"; + response.Headers.ETag = etag; + } + else + { + response.Headers.CacheControl = IsPrivate(result) ? "private, no-store" : "no-store"; + } + response.Headers["X-Aspire-Build-Id"] = artifact.Manifest.BuildId; + response.ContentLength = result.Body.Length; + if (!HttpMethods.IsHead(context.Request.Method)) + await response.Body.WriteAsync(result.Body, context.RequestAborted); + logger.LogInformation("Forwarded hybrid API {Path} ({Bytes} bytes, Astro cache {CacheStatus}) from build {BuildId}", + selection.RendererPath, result.Body.Length, result.CacheStatus ?? "bypass", artifact.Manifest.BuildId); + } + + public async Task IsReadyAsync(CancellationToken cancellationToken) + { + foreach (var candidate in endpoints.Candidates("")) + { + using var timeout = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken); + timeout.CancelAfter(TimeSpan.FromSeconds(2)); + try + { + using var response = await client.GetAsync( + new Uri(candidate.Address, "/__hybrid-api-docs/health"), HttpCompletionOption.ResponseHeadersRead, timeout.Token); + if (response.IsSuccessStatusCode && MatchesBuild(response)) return true; + } + catch (OperationCanceledException) when (cancellationToken.IsCancellationRequested) + { + throw; + } + catch (Exception error) when (error is HttpRequestException or IOException or OperationCanceledException) + { + logger.LogWarning(error, "Hybrid API readiness probe failed for {Endpoint}", candidate.Address); + } + } + return false; + } + + private async Task FetchSharedAsync(string upstream) + { + // Yield so the in-flight entry is always registered before it can be removed. + await Task.Yield(); + try + { + return await FetchAsync(upstream); + } + finally + { + flights.Requests.TryRemove(upstream, out _); + } + } + + private async Task FetchAsync(string upstream) + { + // The shared render outlives any single caller, so only this deadline cancels it. + using var timeout = new CancellationTokenSource(TimeSpan.FromSeconds(30)); + var candidates = endpoints.Candidates(upstream).ToArray(); var timedOut = false; for (var index = 0; index < candidates.Length; index++) { using var attempt = CancellationTokenSource.CreateLinkedTokenSource(timeout.Token); attempt.CancelAfter(TimeSpan.FromSeconds(10)); - using var request = new HttpRequestMessage(HttpMethod.Get, - new Uri(candidates[index].Address, selection.RendererPath + context.Request.QueryString)); + using var request = new HttpRequestMessage(HttpMethod.Get, new Uri(candidates[index].Address, upstream)); request.Headers.Host = artifact.Site.Authority; request.Headers.TryAddWithoutValidation("X-Forwarded-Host", artifact.Site.Authority); request.Headers.TryAddWithoutValidation("X-Forwarded-Proto", artifact.Site.Scheme); - if (context.Request.Headers.Authorization.Count > 0 || context.User.Identity?.IsAuthenticated == true) - request.Headers.TryAddWithoutValidation("X-Aspire-Cache-Bypass", "1"); try { using var response = await client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, attempt.Token); @@ -48,82 +150,44 @@ public async Task RenderAsync(HttpContext context) } await response.Content.LoadIntoBufferAsync(MaximumBodySize, attempt.Token); var body = await response.Content.ReadAsByteArrayAsync(attempt.Token); - context.Response.StatusCode = (int)response.StatusCode; + if ((int)response.StatusCode < 500) endpoints.MarkHealthy(candidates[index].Index); + var excluded = new HashSet(ExcludedHeaders, StringComparer.OrdinalIgnoreCase); foreach (var value in response.Headers.Connection) excluded.Add(value); - foreach (var header in response.Headers.Concat(response.Content.Headers)) - { - if (!excluded.Contains(header.Key)) context.Response.Headers[header.Key] = header.Value.ToArray(); - } - var vary = context.Response.Headers.Vary.ToString().Split(',', StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries) - .Where(value => !value.Equals("X-Aspire-Cache-Bypass", StringComparison.OrdinalIgnoreCase)).ToArray(); - if (vary.Length == 0) context.Response.Headers.Remove("Vary"); - else context.Response.Headers.Vary = string.Join(", ", vary); - if (selection.Representation == "markdown-negotiated") - { - context.Response.Headers.CacheControl = "private, no-store"; - context.Response.Headers.Vary = "Accept"; - } - else - context.Response.Headers.CacheControl = response.Headers.CacheControl?.Private == true - ? "private, no-store" : "no-store"; - if ((int)response.StatusCode >= 500) context.Response.Headers.CacheControl = "no-store"; - context.Response.Headers["X-Aspire-Build-Id"] = artifact.Manifest.BuildId; - context.Response.ContentLength = body.Length; - if ((int)response.StatusCode < 500) endpoints.Prefer(candidates[index].Index); - if (!HttpMethods.IsHead(context.Request.Method)) - await context.Response.Body.WriteAsync(body, context.RequestAborted); - logger.LogInformation("Forwarded hybrid API {Path} ({Bytes} bytes, Astro cache {CacheStatus}) from build {BuildId}", - selection.RendererPath, body.Length, - response.Headers.TryGetValues("X-Astro-Cache", out var cacheStatus) ? string.Join(", ", cacheStatus) : "bypass", - artifact.Manifest.BuildId); - return; - } - catch (OperationCanceledException) when (context.RequestAborted.IsCancellationRequested) - { - context.Abort(); - return; + var headers = response.Headers.Concat(response.Content.Headers) + .Where(header => !excluded.Contains(header.Key)) + .Select(header => KeyValuePair.Create(header.Key, header.Value.ToArray())).ToArray(); + var status = (int)response.StatusCode; + var privateOrCookie = response.Headers.CacheControl?.Private == true || response.Headers.Contains("Set-Cookie"); + return new HybridApiDocsResponse(status, headers, body, false, status is >= 200 and < 300 && !privateOrCookie); } catch (Exception error) when (error is HttpRequestException or IOException or OperationCanceledException) { timedOut = error is OperationCanceledException; - logger.LogWarning(error, "Hybrid API renderer {Endpoint} failed for {Path}", - candidates[index].Address, selection.RendererPath); - if (context.Response.HasStarted) - { - context.Abort(); - return; - } + endpoints.MarkFailed(candidates[index].Index); + logger.LogWarning(error, "Hybrid API renderer {Endpoint} failed for {Path}", candidates[index].Address, upstream); if (timeout.IsCancellationRequested) break; } } - logger.LogError("All hybrid API renderers failed for {Path}", selection.RendererPath); - context.Response.StatusCode = timedOut ? StatusCodes.Status504GatewayTimeout : StatusCodes.Status502BadGateway; - context.Response.Headers.CacheControl = "no-store"; + logger.LogError("All hybrid API renderers failed for {Path}", upstream); + return HybridApiDocsResponse.Failure(timedOut ? StatusCodes.Status504GatewayTimeout : StatusCodes.Status502BadGateway); } - public async Task IsReadyAsync(CancellationToken cancellationToken) + private static bool IsPrivate(HybridApiDocsResponse result) => result.Headers.Any(header => + header.Key.Equals("Cache-Control", StringComparison.OrdinalIgnoreCase) + && header.Value.Any(value => value.Contains("private", StringComparison.OrdinalIgnoreCase))); + + private string ETagFor(string rendererPath) { - foreach (var candidate in endpoints.Candidates()) - { - using var timeout = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken); - timeout.CancelAfter(TimeSpan.FromSeconds(2)); - try - { - using var response = await client.GetAsync( - new Uri(candidate.Address, "/__hybrid-api-docs/health"), HttpCompletionOption.ResponseHeadersRead, timeout.Token); - if (response.IsSuccessStatusCode && MatchesBuild(response)) return true; - } - catch (OperationCanceledException) when (cancellationToken.IsCancellationRequested) - { - throw; - } - catch (Exception error) when (error is HttpRequestException or IOException or OperationCanceledException) - { - logger.LogWarning(error, "Hybrid API readiness probe failed for {Endpoint}", candidate.Address); - } - } - return false; + var hash = SHA256.HashData(Encoding.UTF8.GetBytes($"{artifact.Manifest.BuildId}\n{rendererPath}")); + return $"W/\"{Convert.ToHexStringLower(hash.AsSpan(0, 12))}\""; + } + + private static bool IsNotModified(HttpRequest request, string etag) + { + var current = EntityTagHeaderValue.Parse(etag); + return request.GetTypedHeaders().IfNoneMatch + .Any(candidate => candidate == EntityTagHeaderValue.Any || candidate.Compare(current, useStrongComparison: false)); } private bool MatchesBuild(HttpResponseMessage response) diff --git a/src/statichost/StaticHost/HybridApiDocs/HybridApiDocsRoutingMiddleware.cs b/src/statichost/StaticHost/HybridApiDocs/HybridApiDocsRoutingMiddleware.cs index 3a84e387cf..01a124fb6b 100644 --- a/src/statichost/StaticHost/HybridApiDocs/HybridApiDocsRoutingMiddleware.cs +++ b/src/statichost/StaticHost/HybridApiDocs/HybridApiDocsRoutingMiddleware.cs @@ -53,6 +53,7 @@ public async Task InvokeAsync(HttpContext context) { context.Response.StatusCode = StatusCodes.Status404NotFound; context.Response.Headers.CacheControl = "no-store"; + await NotFoundPage.WriteAsync(context); return; } var isMarkdown = path.EndsWith(".md", StringComparison.Ordinal); diff --git a/src/statichost/StaticHost/NotFoundPage.cs b/src/statichost/StaticHost/NotFoundPage.cs new file mode 100644 index 0000000000..8eebac86ef --- /dev/null +++ b/src/statichost/StaticHost/NotFoundPage.cs @@ -0,0 +1,23 @@ +namespace StaticHost; + +internal static class NotFoundPage +{ + /// Serves the site's 404 page for a response that is already a 404 with no body. + public static async Task WriteAsync(HttpContext context) + { + var response = context.Response; + if (response is not { StatusCode: 404, HasStarted: false }) return; + + var env = context.RequestServices.GetRequiredService(); + var notFoundPath = Path.Combine(env.WebRootPath ?? string.Empty, "404.html"); + if (!File.Exists(notFoundPath)) return; + + // Ensure the 404 page itself is not cached aggressively so new deployments update quickly + response.Headers.CacheControl = "no-cache, no-store, must-revalidate"; + response.Headers.Pragma = "no-cache"; + response.Headers.Expires = "0"; + response.ContentType = "text/html; charset=utf-8"; + + await response.SendFileAsync(notFoundPath); + } +} diff --git a/src/statichost/StaticHost/Program.cs b/src/statichost/StaticHost/Program.cs index 66abef0cdb..62aa2886b8 100644 --- a/src/statichost/StaticHost/Program.cs +++ b/src/statichost/StaticHost/Program.cs @@ -100,27 +100,7 @@ // add routing after default files, so the default file middleware can modify the path first app.UseRouting(); -app.UseStatusCodePages(async context => -{ - var response = context.HttpContext.Response; - if (response is { StatusCode: 404, HasStarted: false }) - { - var env = context.HttpContext.RequestServices.GetRequiredService(); - - var notFoundPath = Path.Combine(env.WebRootPath ?? string.Empty, "404.html"); - - if (File.Exists(notFoundPath)) - { - // Ensure the 404 page itself is not cached aggressively so new deployments update quickly - response.Headers.CacheControl = "no-cache, no-store, must-revalidate"; - response.Headers.Pragma = "no-cache"; - response.Headers.Expires = "0"; - response.ContentType = "text/html; charset=utf-8"; - - await response.SendFileAsync(notFoundPath); - } - } -}); +app.UseStatusCodePages(context => NotFoundPage.WriteAsync(context.HttpContext)); // Ensure text/plain responses include UTF-8 charset to fix encoding issues with .txt files app.Use(async (context, next) => diff --git a/tests/Aspire.Dev.AppHost.Tests/HybridApiDocsConfigurationTests.cs b/tests/Aspire.Dev.AppHost.Tests/HybridApiDocsConfigurationTests.cs index ba16ba719e..b121ba93d8 100644 --- a/tests/Aspire.Dev.AppHost.Tests/HybridApiDocsConfigurationTests.cs +++ b/tests/Aspire.Dev.AppHost.Tests/HybridApiDocsConfigurationTests.cs @@ -112,7 +112,7 @@ public async Task PublishModelKeepsBothRenderersInsideTheSameWebsite() Assert.Equal(container.TargetPort.Value, port.Value.Value); }); Assert.Equal(new string?[] { "4323", "4324" }, sidecars.Select(container => container.TargetPort.Value)); - Assert.Equal("/healthz/api-docs", site.SiteConfig.HealthCheckPath.Value); + Assert.Equal("/healthz", site.SiteConfig.HealthCheckPath.Value); Assert.Equal(2, site.SiteConfig.NumberOfWorkers.Value); Assert.True(site.SiteConfig.IsAlwaysOn.Value); Assert.True(site.IsEndToEndEncryptionEnabled.Value); @@ -129,7 +129,7 @@ setting.Value is { } pair && await using var app = builder.Build(); var bicep = infrastructure.Resource.GetBicepTemplateString(); Assert.Contains("isMain: false", bicep, StringComparison.Ordinal); - Assert.Contains("healthCheckPath: '/healthz/api-docs'", bicep, StringComparison.Ordinal); + Assert.Contains("healthCheckPath: '/healthz'", bicep, StringComparison.Ordinal); Assert.Contains("endToEndEncryptionEnabled: true", bicep, StringComparison.Ordinal); } finally diff --git a/tests/StaticHost.Tests/HybridApiDocsTests.cs b/tests/StaticHost.Tests/HybridApiDocsTests.cs index 0950771a4e..42f20fc732 100644 --- a/tests/StaticHost.Tests/HybridApiDocsTests.cs +++ b/tests/StaticHost.Tests/HybridApiDocsTests.cs @@ -14,21 +14,106 @@ namespace StaticHost.Tests; public sealed class HybridApiDocsTests { [Fact] - public async Task AlwaysForwardsRequestsEvenWhenAstroReportsCacheHits() + public async Task AlwaysForwardsSequentialRequestsEvenWhenAstroReportsCacheHits() { await using var host = await HybridHost.StartAsync(); - var responses = await Task.WhenAll(Enumerable.Range(0, 20) - .Select(_ => host.Client.GetStringAsync("/reference/api/demo/"))); - Assert.All(responses, body => Assert.Equal("html:demo", body)); - Assert.Equal(20, host.Renderer.Calls["/reference/api/demo/"]); - Assert.Equal("html:demo", await host.Client.GetStringAsync("/reference/api/demo/")); - Assert.Equal(21, host.Renderer.Calls["/reference/api/demo/"]); + for (var index = 0; index < 3; index++) + Assert.Equal("html:demo", await host.Client.GetStringAsync("/reference/api/demo/")); + Assert.Equal(3, host.Renderer.Calls["/reference/api/demo/"]); using var response = await host.Client.GetAsync("/reference/api/demo/"); Assert.Equal("HIT", Assert.Single(response.Headers.GetValues("X-Astro-Cache"))); - Assert.True(response.Headers.CacheControl!.NoStore); + Assert.True(response.Headers.CacheControl!.NoCache); + Assert.False(response.Headers.CacheControl.NoStore); + Assert.True(response.Headers.ETag!.IsWeak); Assert.False(response.Headers.Contains("Vary")); } + [Fact] + public async Task ConcurrentRequestsForOneColdPageShareASingleRender() + { + await using var host = await HybridHost.StartAsync(); + host.Renderer.Gate = new(TaskCreationOptions.RunContinuationsAsynchronously); + var requests = Enumerable.Range(0, 20).Select(_ => host.Client.GetStringAsync("/reference/api/demo/")).ToArray(); + await Task.Delay(200); + host.Renderer.Gate.SetResult(); + Assert.All(await Task.WhenAll(requests), body => Assert.Equal("html:demo", body)); + Assert.Equal(1, host.Renderer.Calls["/reference/api/demo/"]); + Assert.Equal("html:demo", await host.Client.GetStringAsync("/reference/api/demo/")); + Assert.Equal(2, host.Renderer.Calls["/reference/api/demo/"]); + } + + [Fact] + public async Task AbandonedRequestsDoNotCancelTheRenderOthersAreWaitingFor() + { + await using var host = await HybridHost.StartAsync(); + host.Renderer.Gate = new(TaskCreationOptions.RunContinuationsAsynchronously); + using var abandon = new CancellationTokenSource(); + var abandoned = host.Client.GetAsync("/reference/api/demo/", abandon.Token); + var waiting = host.Client.GetStringAsync("/reference/api/demo/"); + await Task.Delay(200); + abandon.Cancel(); + await Assert.ThrowsAnyAsync(() => abandoned); + host.Renderer.Gate.SetResult(); + Assert.Equal("html:demo", await waiting); + Assert.Equal(1, host.Renderer.Calls["/reference/api/demo/"]); + } + + [Fact] + public async Task AnswersMatchingValidatorsWithoutCallingTheRenderer() + { + await using var host = await HybridHost.StartAsync(); + using var first = await host.Client.GetAsync("/reference/api/demo/"); + var etag = first.Headers.ETag!; + async Task Revalidate(string path, string tag) + { + using var request = new HttpRequestMessage(HttpMethod.Get, path); + request.Headers.TryAddWithoutValidation("If-None-Match", tag); + return await host.Client.SendAsync(request); + } + + using var notModified = await Revalidate("/reference/api/demo/", $"\"other\", {etag}"); + Assert.Equal(HttpStatusCode.NotModified, notModified.StatusCode); + Assert.Equal(etag, notModified.Headers.ETag); + Assert.Empty(await notModified.Content.ReadAsByteArrayAsync()); + using var any = await Revalidate("/reference/api/demo/", "*"); + Assert.Equal(HttpStatusCode.NotModified, any.StatusCode); + Assert.Equal(1, host.Renderer.Calls["/reference/api/demo/"]); + + using var changed = await Revalidate("/reference/api/demo/", "W/\"stale\""); + Assert.Equal(HttpStatusCode.OK, changed.StatusCode); + Assert.Equal(2, host.Renderer.Calls["/reference/api/demo/"]); + using var markdown = await Revalidate("/reference/api/demo.md", etag.ToString()); + Assert.Equal(HttpStatusCode.OK, markdown.StatusCode); + Assert.NotEqual(etag, markdown.Headers.ETag); + } + + [Fact] + public async Task OnlyCacheablePagesGetValidators() + { + await using var host = await HybridHost.StartAsync(); + foreach (var page in new[] { "private", "cookie", "failure" }) + { + using var response = await host.Client.GetAsync($"/reference/api/{page}/"); + Assert.Null(response.Headers.ETag); + Assert.True(response.Headers.CacheControl!.NoStore); + } + using var request = new HttpRequestMessage(HttpMethod.Get, "/reference/api/demo/"); + request.Headers.Accept.ParseAdd("text/markdown"); + using var negotiated = await host.Client.SendAsync(request); + Assert.Null(negotiated.Headers.ETag); + } + + [Fact] + public async Task QueryStringsAreNotForwardedForPages() + { + await using var host = await HybridHost.StartAsync(); + foreach (var path in new[] { "/reference/api/demo/?a=1", "/reference/api/demo/?a=2&q=redis", "/reference/api/demo.md?x=1" }) + await host.Client.GetStringAsync(path); + Assert.Equal(3, host.Renderer.Requests.Count); + Assert.DoesNotContain(host.Renderer.Requests, request => request.Contains('?')); + Assert.Equal(2, host.Renderer.Calls["/reference/api/demo/"]); + } + [Theory] [InlineData(true)] [InlineData(false)] @@ -95,14 +180,13 @@ public async Task DoesNotCachePrivateOrCookieSettingResponses(string page) } [Fact] - public async Task MarksAuthenticatedRequestsForNativeCacheBypass() + public async Task AuthorizationHeadersDoNotBypassTheNativeCache() { await using var host = await HybridHost.StartAsync(); host.Client.DefaultRequestHeaders.Authorization = new("Bearer", "test"); - await host.Client.GetStringAsync("/reference/api/demo/"); - await host.Client.GetStringAsync("/reference/api/demo/"); - Assert.Equal(2, host.Renderer.Calls["/reference/api/demo/"]); - Assert.True(host.Renderer.SawCacheBypass); + using var response = await host.Client.GetAsync("/reference/api/demo/"); + Assert.NotNull(response.Headers.ETag); + Assert.False(host.Renderer.SawCacheBypass); } [Fact] @@ -176,14 +260,28 @@ public async Task CompressesForwardedAndStaticResponsesWhenTheClientAllowsIt(str } [Fact] - public async Task FailsOverAndKeepsUsingTheHealthyReplica() + public async Task SpreadsPagesAcrossReplicasAndKeepsEachPageOnTheSameOne() + { + await using var host = await HybridHost.StartAsync(["http://primary/", "http://standby/"]); + foreach (var page in HybridHost.SpreadPages) + for (var visit = 0; visit < 3; visit++) + Assert.Equal($"html:{page}", await host.Client.GetStringAsync($"/reference/api/{page}/")); + var primaryPages = HybridHost.SpreadPages.Count(page => HybridHost.PreferredReplica(page) == 0); + Assert.InRange(primaryPages, 1, HybridHost.SpreadPages.Length - 1); + Assert.Equal(primaryPages * 3, host.Renderer.EndpointCalls["primary"]); + Assert.Equal((HybridHost.SpreadPages.Length - primaryPages) * 3, host.Renderer.EndpointCalls["standby"]); + } + + [Fact] + public async Task FailsOverAndSkipsAFailedReplicaDuringItsCooldown() { await using var host = await HybridHost.StartAsync(["http://primary/", "http://standby/"]); host.Renderer.OfflineHosts.Add("primary"); - Assert.Equal("html:demo", await host.Client.GetStringAsync("/reference/api/demo/")); + var page = HybridHost.PageFor(0); + Assert.Equal($"html:{page}", await host.Client.GetStringAsync($"/reference/api/{page}/")); Assert.Equal(1, host.Renderer.EndpointCalls["primary"]); Assert.Equal(1, host.Renderer.EndpointCalls["standby"]); - Assert.Equal("html:demo", await host.Client.GetStringAsync("/reference/api/demo/")); + Assert.Equal($"html:{page}", await host.Client.GetStringAsync($"/reference/api/{page}/")); Assert.Equal(1, host.Renderer.EndpointCalls["primary"]); Assert.Equal(2, host.Renderer.EndpointCalls["standby"]); } @@ -205,16 +303,17 @@ public async Task ReadinessRequiresAnAvailableMatchingBuild() } [Fact] - public async Task RejectsMismatchedPrimaryAndRecoversAfterReplicaAvailabilityChanges() + public async Task RejectsMismatchedReplicasButStillUsesThemAsALastResort() { await using var host = await HybridHost.StartAsync(["http://primary/", "http://standby/"]); + var page = HybridHost.PageFor(0); host.Renderer.MismatchedHosts.Add("primary"); - Assert.Equal("html:demo", await host.Client.GetStringAsync("/reference/api/demo/")); + Assert.Equal($"html:{page}", await host.Client.GetStringAsync($"/reference/api/{page}/")); + Assert.Equal(1, host.Renderer.EndpointCalls["standby"]); host.Renderer.MismatchedHosts.Clear(); host.Renderer.OfflineHosts.Add("standby"); - Assert.Equal("html:demo", await host.Client.GetStringAsync("/reference/api/demo/")); + Assert.Equal($"html:{page}", await host.Client.GetStringAsync($"/reference/api/{page}/")); Assert.Equal(2, host.Renderer.EndpointCalls["primary"]); - Assert.Equal(2, host.Renderer.EndpointCalls["standby"]); } [Fact] @@ -222,11 +321,44 @@ public async Task RetriesServerErrorsAgainstAnotherReplicaBeforeSendingTheRespon { await using var host = await HybridHost.StartAsync(["http://primary/", "http://standby/"]); host.Renderer.ErrorHosts.Add("primary"); - Assert.Equal("html:demo", await host.Client.GetStringAsync("/reference/api/demo/")); + var page = HybridHost.PageFor(0); + Assert.Equal($"html:{page}", await host.Client.GetStringAsync($"/reference/api/{page}/")); Assert.Equal(1, host.Renderer.EndpointCalls["primary"]); Assert.Equal(1, host.Renderer.EndpointCalls["standby"]); } + [Fact] + public async Task UnknownApiPagesGetTheSiteNotFoundPage() + { + await using var host = await HybridHost.StartAsync(); + using var missing = await host.Client.GetAsync("/reference/api/not-a-page/"); + Assert.Equal(HttpStatusCode.NotFound, missing.StatusCode); + Assert.Equal("site not found", await missing.Content.ReadAsStringAsync()); + Assert.Contains("text/html", missing.Content.Headers.ContentType!.ToString()); + Assert.True(missing.Headers.CacheControl!.NoStore); + Assert.Empty(host.Renderer.Calls); + } + + [Theory] + [InlineData(false, HttpStatusCode.BadGateway)] + [InlineData(true, HttpStatusCode.GatewayTimeout)] + public async Task UnavailableRenderersGetARetryPage(bool timeout, HttpStatusCode expected) + { + await using var host = await HybridHost.StartAsync(); + host.Renderer.Offline = !timeout; + host.Renderer.Timeout = timeout; + using var response = await host.Client.GetAsync("/reference/api/demo/"); + Assert.Equal(expected, response.StatusCode); + Assert.Contains("Try again", await response.Content.ReadAsStringAsync()); + Assert.Contains("text/html", response.Content.Headers.ContentType!.ToString()); + Assert.True(response.Headers.CacheControl!.NoStore); + Assert.Equal("5", Assert.Single(response.Headers.GetValues("Retry-After"))); + + using var head = await host.Client.SendAsync(new HttpRequestMessage(HttpMethod.Head, "/reference/api/demo/")); + Assert.Equal(expected, head.StatusCode); + Assert.Empty(await head.Content.ReadAsByteArrayAsync()); + } + [Fact] public async Task CanonicalizesAndRedirectsWithoutInvokingWorker() { @@ -258,6 +390,7 @@ public async Task AllowsOnlyBundledImagesAndBoundsTransformDimensions() using var oversized = await host.Client.GetAsync("/_image?href=%2F_astro%2Flogo.svg&w=999999"); Assert.Equal(HttpStatusCode.BadRequest, oversized.StatusCode); Assert.Equal(1, host.Renderer.Calls["/_image"]); + Assert.Contains(host.Renderer.Requests, request => request.StartsWith("/_image?href=", StringComparison.Ordinal)); } [Fact] @@ -279,6 +412,11 @@ internal sealed class HybridHost : IAsyncDisposable public HttpClient Client { get; } public TestApiRenderer Renderer { get; } + // Generic pages with a stable preferred replica, so routing assertions do not depend on a hash value. + internal static readonly string[] SpreadPages = ["alpha", "beta", "gamma", "delta", "epsilon", "zeta", "eta", "theta"]; + internal static int PreferredReplica(string page) => HybridApiDocsEndpointPool.PreferredIndex($"/reference/api/{page}/", 2); + internal static string PageFor(int replica) => SpreadPages.First(page => PreferredReplica(page) == replica); + private HybridHost(WebApplication app, TempWebRoot root, TestApiRenderer renderer) { _app = app; @@ -291,8 +429,10 @@ public static async Task StartAsync(string[]? endpoints = null) { var root = new TempWebRoot(); root.WriteFile("client/guide/index.html", "static guide"); + root.WriteFile("client/404.html", "site not found"); root.WriteFile("client/_astro/logo.svg", ""); - var pages = new[] { "demo", "private", "cookie", "failure", "broken", "mismatch", "oversize", "large", "cold" }; + var pages = new[] { "demo", "private", "cookie", "failure", "broken", "mismatch", "oversize", "large", "cold" } + .Concat(SpreadPages).ToArray(); root.WriteFile("hybrid.json", JsonSerializer.Serialize(new HybridApiManifest( 1, "hybrid-api-docs", new string('a', 64), "client", "server/entry.mjs", "https://aspire.dev", pages.Select(page => new HybridApiRoute($"/reference/api/{page}/", $"/reference/api/{page}.md")).ToArray(), @@ -328,12 +468,14 @@ public async ValueTask DisposeAsync() internal sealed class TestApiRenderer : HttpMessageHandler { public ConcurrentDictionary Calls { get; } = new(); + public ConcurrentQueue Requests { get; } = new(); public ConcurrentDictionary EndpointCalls { get; } = new(); public HashSet OfflineHosts { get; } = []; public HashSet MismatchedHosts { get; } = []; public HashSet ErrorHosts { get; } = []; public bool Offline { get; set; } public bool Timeout { get; set; } + public TaskCompletionSource? Gate { get; set; } public bool SawCacheBypass { get; private set; } public bool SawCookie { get; private set; } @@ -346,8 +488,10 @@ protected override async Task SendAsync(HttpRequestMessage && bypass.SequenceEqual(["1"]); SawCookie = request.Headers.Contains("Cookie"); Calls.AddOrUpdate(path, 1, (_, count) => count + 1); + if (request.RequestUri.AbsolutePath != "/__hybrid-api-docs/health") Requests.Enqueue(request.RequestUri.PathAndQuery); if (Offline || OfflineHosts.Contains(endpoint)) throw new HttpRequestException("Renderer unavailable."); if (Timeout) throw new OperationCanceledException("Renderer timed out."); + if (Gate is not null) await Gate.Task.WaitAsync(cancellationToken); await Task.Delay(30, cancellationToken); var page = path.Split('/').Last(segment => segment.Length > 0).Replace(".md", ""); var response = new HttpResponseMessage(page == "failure" || ErrorHosts.Contains(endpoint) From b9cb3542fa8e1d750dde1ef4d31c785bd0e735c8 Mon Sep 17 00:00:00 2001 From: David Pine <7679720+IEvangelist@users.noreply.github.com> Date: Tue, 13 Oct 2026 21:18:23 -0500 Subject: [PATCH 21/28] Fix the acceptance validator check to ignore the direct worker hit Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- src/frontend/scripts/test-hybrid-host.mjs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/frontend/scripts/test-hybrid-host.mjs b/src/frontend/scripts/test-hybrid-host.mjs index 35aa1a8679..acafbea3aa 100644 --- a/src/frontend/scripts/test-hybrid-host.mjs +++ b/src/frontend/scripts/test-hybrid-host.mjs @@ -155,9 +155,10 @@ try { }); assert.equal(directHit.headers.get('X-Astro-Cache'), 'HIT', 'The same response must be cached in Astro itself.'); assert.equal(await directHit.text(), csharp.text); + const beforeRevalidation = await stats(); const revalidated = await fetch(hostUrl + packageRoute.html, { headers: { 'If-None-Match': etag } }); assert.equal(revalidated.status, 304); - assert.equal((await stats()).requests, cold.requests + 1, 'A matching validator must not reach the renderer.'); + assert.equal((await stats()).requests, beforeRevalidation.requests, 'A matching validator must not reach the renderer.'); const queried = await page(`${packageRoute.html}?cachebust=1`); assert.equal(queried.response.headers.get('X-Astro-Cache'), 'HIT', 'Query strings must not multiply renders.'); const credentialRequest = await page(packageRoute.html, { headers: { Authorization: 'Bearer poc-test' } }); From 1ffec64c17726a227beef908ba5e70d1cde09e25 Mon Sep 17 00:00:00 2001 From: David Pine <7679720+IEvangelist@users.noreply.github.com> Date: Tue, 13 Oct 2026 21:50:32 -0500 Subject: [PATCH 22/28] Serve prerendered API landings as static files Paths outside the on-demand manifest now fall through to static files, and the site 404 page is the fallback for unknown API URLs. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .../StaticHost/HybridApiDocs/HybridApiDocsRenderer.cs | 2 ++ .../HybridApiDocs/HybridApiDocsRoutingMiddleware.cs | 5 ++--- tests/StaticHost.Tests/HybridApiDocsTests.cs | 9 +++++++++ 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/statichost/StaticHost/HybridApiDocs/HybridApiDocsRenderer.cs b/src/statichost/StaticHost/HybridApiDocs/HybridApiDocsRenderer.cs index d095c6bb3d..157560af36 100644 --- a/src/statichost/StaticHost/HybridApiDocs/HybridApiDocsRenderer.cs +++ b/src/statichost/StaticHost/HybridApiDocs/HybridApiDocsRenderer.cs @@ -20,6 +20,8 @@ public async Task RenderAsync(HttpContext context) if (selection is null) { context.Response.StatusCode = StatusCodes.Status404NotFound; + context.Response.Headers.CacheControl = "no-store"; + await NotFoundPage.WriteAsync(context); return; } diff --git a/src/statichost/StaticHost/HybridApiDocs/HybridApiDocsRoutingMiddleware.cs b/src/statichost/StaticHost/HybridApiDocs/HybridApiDocsRoutingMiddleware.cs index 01a124fb6b..386dc61980 100644 --- a/src/statichost/StaticHost/HybridApiDocs/HybridApiDocsRoutingMiddleware.cs +++ b/src/statichost/StaticHost/HybridApiDocs/HybridApiDocsRoutingMiddleware.cs @@ -49,11 +49,10 @@ public async Task InvokeAsync(HttpContext context) await next(context); return; } + // Prerendered API pages (the landings) are plain static files; anything else is a 404. if (!artifact.TryRoute(path, out var route)) { - context.Response.StatusCode = StatusCodes.Status404NotFound; - context.Response.Headers.CacheControl = "no-store"; - await NotFoundPage.WriteAsync(context); + await next(context); return; } var isMarkdown = path.EndsWith(".md", StringComparison.Ordinal); diff --git a/tests/StaticHost.Tests/HybridApiDocsTests.cs b/tests/StaticHost.Tests/HybridApiDocsTests.cs index 42f20fc732..9527e1b3d6 100644 --- a/tests/StaticHost.Tests/HybridApiDocsTests.cs +++ b/tests/StaticHost.Tests/HybridApiDocsTests.cs @@ -327,6 +327,14 @@ public async Task RetriesServerErrorsAgainstAnotherReplicaBeforeSendingTheRespon Assert.Equal(1, host.Renderer.EndpointCalls["standby"]); } + [Fact] + public async Task PrerenderedApiPagesAreServedAsStaticFilesWithoutTheRenderer() + { + await using var host = await HybridHost.StartAsync(); + Assert.Equal("static landing", await host.Client.GetStringAsync("/reference/api/landing/")); + Assert.Empty(host.Renderer.Calls); + } + [Fact] public async Task UnknownApiPagesGetTheSiteNotFoundPage() { @@ -430,6 +438,7 @@ public static async Task StartAsync(string[]? endpoints = null) var root = new TempWebRoot(); root.WriteFile("client/guide/index.html", "static guide"); root.WriteFile("client/404.html", "site not found"); + root.WriteFile("client/reference/api/landing/index.html", "static landing"); root.WriteFile("client/_astro/logo.svg", ""); var pages = new[] { "demo", "private", "cookie", "failure", "broken", "mismatch", "oversize", "large", "cold" } .Concat(SpreadPages).ToArray(); From 20469b6112a2fdd170bb229a00e37bdc18d5baec Mon Sep 17 00:00:00 2001 From: David Pine <7679720+IEvangelist@users.noreply.github.com> Date: Tue, 13 Oct 2026 22:36:20 -0500 Subject: [PATCH 23/28] Serve client files without a MIME mapping in hybrid mode UseStaticFiles refuses unknown extensions, so Pagefind's index files, its WASM and the terminal recordings returned 404. The acceptance script now requests one file per extension in the client output. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- src/frontend/scripts/test-hybrid-host.mjs | 17 ++++++++++++++- .../HybridApiDocs/HybridApiDocsExtensions.cs | 16 ++++++++++++++ src/statichost/StaticHost/Program.cs | 10 +-------- tests/StaticHost.Tests/HybridApiDocsTests.cs | 21 ++++++++++++++++++- 4 files changed, 53 insertions(+), 11 deletions(-) diff --git a/src/frontend/scripts/test-hybrid-host.mjs b/src/frontend/scripts/test-hybrid-host.mjs index acafbea3aa..d88a98b8da 100644 --- a/src/frontend/scripts/test-hybrid-host.mjs +++ b/src/frontend/scripts/test-hybrid-host.mjs @@ -1,7 +1,7 @@ import assert from 'node:assert/strict'; import { execFile, execFileSync, spawn } from 'node:child_process'; import { once } from 'node:events'; -import { readFile, writeFile } from 'node:fs/promises'; +import { readFile, readdir, writeFile } from 'node:fs/promises'; import { dirname, resolve } from 'node:path'; import { fileURLToPath } from 'node:url'; import { promisify } from 'node:util'; @@ -136,6 +136,21 @@ try { assert.ok(!home.text.includes('Aspire Static Host'), 'The placeholder wwwroot home must not shadow the hybrid homepage.'); await page('/docs/'); assert.equal((await stats()).requests, initial.requests); + // Every kind of file the static build emits (recordings, Pagefind indexes, WASM, ...) must be served. + const clientRoot = resolve(dirname(manifestPath), manifest.client); + const samples = new Map(); + for (const entry of await readdir(clientRoot, { recursive: true, withFileTypes: true })) { + const extension = entry.name.includes('.') ? entry.name.slice(entry.name.lastIndexOf('.')) : ''; + if (!entry.isFile() || !extension || extension === '.md' || samples.has(extension)) continue; + const relative = resolve(entry.parentPath, entry.name).slice(clientRoot.length).replaceAll('\\', '/'); + samples.set(extension, relative.startsWith('/') ? relative : `/${relative}`); + } + for (const [extension, path] of samples) { + const response = await fetch(hostUrl + path.split('/').map(encodeURIComponent).join('/')); + assert.equal(response.status, 200, `Client files ending in ${extension} must be served: ${path}`); + await response.arrayBuffer(); + } + assert.ok(['.cast', '.pagefind', '.pf_meta'].every((extension) => samples.has(extension)), 'The sample set must cover the file types that need explicit serving.'); const packageRoute = manifest.routes.find(({ html }) => html?.startsWith('/reference/api/csharp/') && html.split('/').length === 6); assert.ok(packageRoute); const csharp = await page(packageRoute.html); diff --git a/src/statichost/StaticHost/HybridApiDocs/HybridApiDocsExtensions.cs b/src/statichost/StaticHost/HybridApiDocs/HybridApiDocsExtensions.cs index 6017a92004..f73575346c 100644 --- a/src/statichost/StaticHost/HybridApiDocs/HybridApiDocsExtensions.cs +++ b/src/statichost/StaticHost/HybridApiDocs/HybridApiDocsExtensions.cs @@ -48,6 +48,22 @@ endpoint.Scheme is not ("http" or "https") || public static void UseHybridApiDocsRouting(this IApplicationBuilder app) => app.UseMiddleware(); + /// + /// Serves the prebuilt client as plain files. Unlike static web assets, UseStaticFiles refuses + /// extensions without a MIME mapping, which would drop Pagefind's index files and the terminal recordings. + /// + public static StaticFileOptions HybridStaticFileOptions() => new() + { + ServeUnknownFileTypes = true, + DefaultContentType = "application/octet-stream", + OnPrepareResponse = context => + { + context.Context.Response.Headers.CacheControl = + context.Context.Request.Path.StartsWithSegments("/_astro") + ? "public, max-age=31536000, immutable" : "no-cache"; + }, + }; + public static void MapHybridApiDocs(this IEndpointRouteBuilder app) { app.MapMethods("/reference/api/{**path}", ["GET", "HEAD"], diff --git a/src/statichost/StaticHost/Program.cs b/src/statichost/StaticHost/Program.cs index 62aa2886b8..819f0bfac5 100644 --- a/src/statichost/StaticHost/Program.cs +++ b/src/statichost/StaticHost/Program.cs @@ -86,15 +86,7 @@ app.UseDefaultFiles(); if (hybridArtifact is not null) { - app.UseStaticFiles(new StaticFileOptions - { - OnPrepareResponse = context => - { - context.Context.Response.Headers.CacheControl = - context.Context.Request.Path.StartsWithSegments("/_astro") - ? "public, max-age=31536000, immutable" : "no-cache"; - }, - }); + app.UseStaticFiles(HybridApiDocsExtensions.HybridStaticFileOptions()); } // add routing after default files, so the default file middleware can modify the path first diff --git a/tests/StaticHost.Tests/HybridApiDocsTests.cs b/tests/StaticHost.Tests/HybridApiDocsTests.cs index 9527e1b3d6..fb82dbb3ad 100644 --- a/tests/StaticHost.Tests/HybridApiDocsTests.cs +++ b/tests/StaticHost.Tests/HybridApiDocsTests.cs @@ -327,6 +327,22 @@ public async Task RetriesServerErrorsAgainstAnotherReplicaBeforeSendingTheRespon Assert.Equal(1, host.Renderer.EndpointCalls["standby"]); } + [Theory] + [InlineData("/casts/demo.cast", "application/octet-stream")] + [InlineData("/pagefind/pagefind.en_abc.pf_meta", "application/octet-stream")] + [InlineData("/pagefind/wasm.en.pagefind", "application/octet-stream")] + [InlineData("/_astro/logo.svg", "image/svg+xml")] + public async Task ServesEveryClientFileIncludingTypesWithoutAMimeMapping(string path, string contentType) + { + await using var host = await HybridHost.StartAsync(); + using var response = await host.Client.GetAsync(path); + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + Assert.Equal(contentType, response.Content.Headers.ContentType!.MediaType); + Assert.Equal(path.StartsWith("/_astro") ? "public, max-age=31536000, immutable" : "no-cache", + response.Headers.CacheControl!.ToString()); + Assert.Empty(host.Renderer.Calls); + } + [Fact] public async Task PrerenderedApiPagesAreServedAsStaticFilesWithoutTheRenderer() { @@ -439,6 +455,9 @@ public static async Task StartAsync(string[]? endpoints = null) root.WriteFile("client/guide/index.html", "static guide"); root.WriteFile("client/404.html", "site not found"); root.WriteFile("client/reference/api/landing/index.html", "static landing"); + root.WriteFile("client/casts/demo.cast", "{\"version\":2}"); + root.WriteFile("client/pagefind/pagefind.en_abc.pf_meta", "meta"); + root.WriteFile("client/pagefind/wasm.en.pagefind", "wasm"); root.WriteFile("client/_astro/logo.svg", ""); var pages = new[] { "demo", "private", "cookie", "failure", "broken", "mismatch", "oversize", "large", "cold" } .Concat(SpreadPages).ToArray(); @@ -459,7 +478,7 @@ public static async Task StartAsync(string[]? endpoints = null) app.UseHybridApiDocsRouting(); app.UseAgentReadiness(); app.UseDefaultFiles(); - app.UseStaticFiles(); + app.UseStaticFiles(HybridApiDocsExtensions.HybridStaticFileOptions()); app.UseRouting(); app.MapHybridApiDocs(); await app.StartAsync(); From 3a73428fdf87a63c526bfe1b268eebe52cdf7b3f Mon Sep 17 00:00:00 2001 From: David Pine <7679720+IEvangelist@users.noreply.github.com> Date: Wed, 14 Oct 2026 07:48:49 -0500 Subject: [PATCH 24/28] Leave the production plan's instance count and scaling alone The hybrid model forced the plan to 2 instances and the site to 2 workers, which would override the existing 3 automatically scaled instances. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- src/apphost/Aspire.Dev.AppHost/AppHost.cs | 8 -------- src/apphost/Aspire.Dev.AppHost/HybridApiDocsExtensions.cs | 1 - .../HybridApiDocsConfigurationTests.cs | 3 ++- 3 files changed, 2 insertions(+), 10 deletions(-) diff --git a/src/apphost/Aspire.Dev.AppHost/AppHost.cs b/src/apphost/Aspire.Dev.AppHost/AppHost.cs index 34211e6fc9..1b041bb0eb 100644 --- a/src/apphost/Aspire.Dev.AppHost/AppHost.cs +++ b/src/apphost/Aspire.Dev.AppHost/AppHost.cs @@ -4,14 +4,6 @@ // For deployment: We want to pick AppService as the environment to publish to. var production = builder.AddAzureAppServiceEnvironment("production") .WithDashboard(false); -if (hybridApiDocs) -{ - production.ConfigureInfrastructure(infra => - { - var plan = infra.GetProvisionableResources().OfType().Single(); - plan.Sku.Capacity = 2; - }); -} var cache = builder.AddAzureManagedRedis("cache") .RunAsContainer(); diff --git a/src/apphost/Aspire.Dev.AppHost/HybridApiDocsExtensions.cs b/src/apphost/Aspire.Dev.AppHost/HybridApiDocsExtensions.cs index baed4c13ed..646c3c3bc6 100644 --- a/src/apphost/Aspire.Dev.AppHost/HybridApiDocsExtensions.cs +++ b/src/apphost/Aspire.Dev.AppHost/HybridApiDocsExtensions.cs @@ -42,7 +42,6 @@ public static void WithHybridApiDocs(this IResourceBuilder webs website.PublishAsAzureAppServiceWebsite((infra, site) => { site.SiteConfig.IsAlwaysOn = true; - site.SiteConfig.NumberOfWorkers = 2; // Renderer readiness only gates warmup; a renderer outage must not make the instance unhealthy. site.SiteConfig.HealthCheckPath = "/healthz"; site.SiteConfig.AppSettings.Add(new AppServiceNameValuePair diff --git a/tests/Aspire.Dev.AppHost.Tests/HybridApiDocsConfigurationTests.cs b/tests/Aspire.Dev.AppHost.Tests/HybridApiDocsConfigurationTests.cs index b121ba93d8..0e496b4f8a 100644 --- a/tests/Aspire.Dev.AppHost.Tests/HybridApiDocsConfigurationTests.cs +++ b/tests/Aspire.Dev.AppHost.Tests/HybridApiDocsConfigurationTests.cs @@ -113,8 +113,8 @@ public async Task PublishModelKeepsBothRenderersInsideTheSameWebsite() }); Assert.Equal(new string?[] { "4323", "4324" }, sidecars.Select(container => container.TargetPort.Value)); Assert.Equal("/healthz", site.SiteConfig.HealthCheckPath.Value); - Assert.Equal(2, site.SiteConfig.NumberOfWorkers.Value); Assert.True(site.SiteConfig.IsAlwaysOn.Value); + // The plan's instance count and scaling stay as configured on the existing production plan. Assert.True(site.IsEndToEndEncryptionEnabled.Value); Assert.Contains(site.SiteConfig.AppSettings, setting => setting.Value is { } pair && @@ -129,6 +129,7 @@ setting.Value is { } pair && await using var app = builder.Build(); var bicep = infrastructure.Resource.GetBicepTemplateString(); Assert.Contains("isMain: false", bicep, StringComparison.Ordinal); + Assert.DoesNotContain("numberOfWorkers", bicep, StringComparison.Ordinal); Assert.Contains("healthCheckPath: '/healthz'", bicep, StringComparison.Ordinal); Assert.Contains("endToEndEncryptionEnabled: true", bicep, StringComparison.Ordinal); } From 20c4fe942aa81586c218b3af0f926153efd9c3d5 Mon Sep 17 00:00:00 2001 From: David Pine <7679720+IEvangelist@users.noreply.github.com> Date: Wed, 14 Oct 2026 08:37:31 -0500 Subject: [PATCH 25/28] Run the hybrid API POC checks on this PR Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> From a5238169d3e4a6568a32e1002e16aee3a0a8a1ef Mon Sep 17 00:00:00 2001 From: David Pine <7679720+IEvangelist@users.noreply.github.com> Date: Wed, 14 Oct 2026 18:37:21 -0500 Subject: [PATCH 26/28] Give each sidecar its own port through an app setting App Service resolves a sidecar environment variable's value as the name of an app setting, so the literal PORT values were ignored and both renderers bound 4323, which stopped the whole site from starting. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- src/apphost/Aspire.Dev.AppHost/HybridApiDocsExtensions.cs | 8 +++++++- .../HybridApiDocsConfigurationTests.cs | 8 +++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/apphost/Aspire.Dev.AppHost/HybridApiDocsExtensions.cs b/src/apphost/Aspire.Dev.AppHost/HybridApiDocsExtensions.cs index 646c3c3bc6..e6fe787c1f 100644 --- a/src/apphost/Aspire.Dev.AppHost/HybridApiDocsExtensions.cs +++ b/src/apphost/Aspire.Dev.AppHost/HybridApiDocsExtensions.cs @@ -60,6 +60,12 @@ public static void WithHybridApiDocs(this IResourceBuilder webs .Single(container => ReferenceEquals(container.Parent, site) && container.IsMain.Value); for (var index = 0; index < 2; index++) { + // A sidecar environment variable's value names an app setting; it is not a literal. + var portSetting = $"API_DOCS_PORT_{index}"; + site.SiteConfig.AppSettings.Add(new AppServiceNameValuePair + { + Name = portSetting, Value = $"{4323 + index}", + }); var sidecar = new SiteContainer($"apiDocs{index}") { Parent = site, @@ -71,7 +77,7 @@ public static void WithHybridApiDocs(this IResourceBuilder webs UserManagedIdentityClientId = main.UserManagedIdentityClientId, InheritAppSettingsAndConnectionStrings = false, }; - sidecar.EnvironmentVariables.Add(new WebAppEnvironmentVariable { Name = "PORT", Value = $"{4323 + index}" }); + sidecar.EnvironmentVariables.Add(new WebAppEnvironmentVariable { Name = "PORT", Value = portSetting }); infra.Add(sidecar); } }); diff --git a/tests/Aspire.Dev.AppHost.Tests/HybridApiDocsConfigurationTests.cs b/tests/Aspire.Dev.AppHost.Tests/HybridApiDocsConfigurationTests.cs index 0e496b4f8a..c38d1d72a9 100644 --- a/tests/Aspire.Dev.AppHost.Tests/HybridApiDocsConfigurationTests.cs +++ b/tests/Aspire.Dev.AppHost.Tests/HybridApiDocsConfigurationTests.cs @@ -109,9 +109,15 @@ public async Task PublishModelKeepsBothRenderersInsideTheSameWebsite() Assert.Equal("00000000-0000-0000-0000-000000000000", container.UserManagedIdentityClientId.Value); var port = Assert.IsType(Assert.Single(container.EnvironmentVariables).Value); Assert.Equal("PORT", port.Name.Value); - Assert.Equal(container.TargetPort.Value, port.Value.Value); + // The value names an app setting (App Service does not treat it as a literal), so that + // setting must exist and carry this sidecar's own port. + Assert.Contains(site.SiteConfig.AppSettings, setting => + setting.Value is { } pair && + pair.Name.Value == port.Value.Value && pair.Value.Value == container.TargetPort.Value); }); Assert.Equal(new string?[] { "4323", "4324" }, sidecars.Select(container => container.TargetPort.Value)); + Assert.Equal(2, sidecars.Select(container => + Assert.IsType(Assert.Single(container.EnvironmentVariables).Value).Value.Value).Distinct().Count()); Assert.Equal("/healthz", site.SiteConfig.HealthCheckPath.Value); Assert.True(site.SiteConfig.IsAlwaysOn.Value); // The plan's instance count and scaling stay as configured on the existing production plan. From 1883e42a86678cc5fc7285036055b5cef936900a Mon Sep 17 00:00:00 2001 From: David Pine <7679720+IEvangelist@users.noreply.github.com> Date: Wed, 14 Oct 2026 18:54:58 -0500 Subject: [PATCH 27/28] Re-run CI for the sidecar port fix Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> From 2f75c4432ab69ce0ad33ae1a0cb34a200a1d9aa4 Mon Sep 17 00:00:00 2001 From: David Pine <7679720+IEvangelist@users.noreply.github.com> Date: Wed, 14 Oct 2026 19:11:05 -0500 Subject: [PATCH 28/28] Regenerate the lockfile against the public npm registry The earlier merge resolution recorded tarball URLs from a corporate proxy, which the supply-chain policy check rejects. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- src/frontend/pnpm-lock.yaml | 2171 +++++++++++++++++------------------ 1 file changed, 1062 insertions(+), 1109 deletions(-) diff --git a/src/frontend/pnpm-lock.yaml b/src/frontend/pnpm-lock.yaml index 1e9fc7a83b..ef6809ae5c 100644 --- a/src/frontend/pnpm-lock.yaml +++ b/src/frontend/pnpm-lock.yaml @@ -62,19 +62,19 @@ importers: version: 7.2.1 '@astrojs/mdx': specifier: ^7.0.3 - version: 7.0.3(@astrojs/markdown-satteri@0.3.4)(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.3)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0)) + version: 7.0.3(@astrojs/markdown-satteri@0.3.4)(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0)) '@astrojs/node': specifier: 11.1.6 - version: 11.1.6(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.3)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0)) + version: 11.1.6(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0)) '@astrojs/rss': specifier: ^4.0.19 version: 4.0.19 '@astrojs/starlight': specifier: ^0.41.3 - version: 0.41.3(patch_hash=ad8925179f0e3050ae6c804196faa6d38a2be2b718acf138001215a18648d3b5)(@astrojs/markdown-remark@7.2.1)(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.3)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))(typescript@6.0.3) + version: 0.41.3(patch_hash=ad8925179f0e3050ae6c804196faa6d38a2be2b718acf138001215a18648d3b5)(@astrojs/markdown-remark@7.2.1)(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))(typescript@6.0.3) '@catppuccin/starlight': specifier: ^2.1.0 - version: 2.1.0(@astrojs/starlight@0.41.3(patch_hash=ad8925179f0e3050ae6c804196faa6d38a2be2b718acf138001215a18648d3b5)(@astrojs/markdown-remark@7.2.1)(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.3)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))(typescript@6.0.3))(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.3)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0)) + version: 2.1.0(@astrojs/starlight@0.41.3(patch_hash=ad8925179f0e3050ae6c804196faa6d38a2be2b718acf138001215a18648d3b5)(@astrojs/markdown-remark@7.2.1)(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))(typescript@6.0.3))(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0)) '@expressive-code/plugin-collapsible-sections': specifier: ^0.44.1 version: 0.44.1 @@ -95,7 +95,7 @@ importers: version: 0.1.1 '@lunariajs/starlight': specifier: ^0.1.1 - version: 0.1.1(@astrojs/starlight@0.41.3(patch_hash=ad8925179f0e3050ae6c804196faa6d38a2be2b718acf138001215a18648d3b5)(@astrojs/markdown-remark@7.2.1)(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.3)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))(typescript@6.0.3))(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.3)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0)) + version: 0.1.1(@astrojs/starlight@0.41.3(patch_hash=ad8925179f0e3050ae6c804196faa6d38a2be2b718acf138001215a18648d3b5)(@astrojs/markdown-remark@7.2.1)(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))(typescript@6.0.3))(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0)) '@mdx-js/mdx': specifier: ^3.1.1 version: 3.1.1 @@ -104,10 +104,10 @@ importers: version: 3.17.0 astro: specifier: ^7.2.8 - version: 7.3.2(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.3)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0) + version: 7.3.2(@astrojs/markdown-remark@7.2.1)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0) astro-expressive-code: specifier: ^0.44.1 - version: 0.44.1(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.3)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0)) + version: 0.44.1(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0)) expressive-code-twoslash: specifier: ^0.6.1 version: 0.6.1(@expressive-code/core@0.44.1)(eslint@10.7.0(jiti@2.7.0))(expressive-code@0.44.1)(typescript@6.0.3) @@ -146,28 +146,28 @@ importers: version: 0.35.4(@types/node@24.13.3) starlight-github-alerts: specifier: ^0.4.0 - version: 0.4.0(@astrojs/starlight@0.41.3(patch_hash=ad8925179f0e3050ae6c804196faa6d38a2be2b718acf138001215a18648d3b5)(@astrojs/markdown-remark@7.2.1)(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.3)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))(typescript@6.0.3)) + version: 0.4.0(@astrojs/starlight@0.41.3(patch_hash=ad8925179f0e3050ae6c804196faa6d38a2be2b718acf138001215a18648d3b5)(@astrojs/markdown-remark@7.2.1)(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))(typescript@6.0.3)) starlight-image-zoom: specifier: ^0.15.0 - version: 0.15.0(@astrojs/starlight@0.41.3(patch_hash=ad8925179f0e3050ae6c804196faa6d38a2be2b718acf138001215a18648d3b5)(@astrojs/markdown-remark@7.2.1)(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.3)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))(typescript@6.0.3)) + version: 0.15.0(@astrojs/starlight@0.41.3(patch_hash=ad8925179f0e3050ae6c804196faa6d38a2be2b718acf138001215a18648d3b5)(@astrojs/markdown-remark@7.2.1)(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))(typescript@6.0.3)) starlight-kbd: specifier: ^0.4.0 - version: 0.4.0(@astrojs/starlight@0.41.3(patch_hash=ad8925179f0e3050ae6c804196faa6d38a2be2b718acf138001215a18648d3b5)(@astrojs/markdown-remark@7.2.1)(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.3)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))(typescript@6.0.3)) + version: 0.4.0(@astrojs/starlight@0.41.3(patch_hash=ad8925179f0e3050ae6c804196faa6d38a2be2b718acf138001215a18648d3b5)(@astrojs/markdown-remark@7.2.1)(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))(typescript@6.0.3)) starlight-links-validator: specifier: ^0.25.2 - version: 0.25.2(@astrojs/starlight@0.41.3(patch_hash=ad8925179f0e3050ae6c804196faa6d38a2be2b718acf138001215a18648d3b5)(@astrojs/markdown-remark@7.2.1)(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.3)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))(typescript@6.0.3))(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.3)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0)) + version: 0.25.2(@astrojs/starlight@0.41.3(patch_hash=ad8925179f0e3050ae6c804196faa6d38a2be2b718acf138001215a18648d3b5)(@astrojs/markdown-remark@7.2.1)(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))(typescript@6.0.3))(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0)) starlight-llms-txt: specifier: ^0.11.0 - version: 0.11.0(@astrojs/markdown-satteri@0.3.4)(@astrojs/starlight@0.41.3(patch_hash=ad8925179f0e3050ae6c804196faa6d38a2be2b718acf138001215a18648d3b5)(@astrojs/markdown-remark@7.2.1)(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.3)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))(typescript@6.0.3))(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.3)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0)) + version: 0.11.0(@astrojs/markdown-satteri@0.3.4)(@astrojs/starlight@0.41.3(patch_hash=ad8925179f0e3050ae6c804196faa6d38a2be2b718acf138001215a18648d3b5)(@astrojs/markdown-remark@7.2.1)(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))(typescript@6.0.3))(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0)) starlight-page-actions: specifier: ^0.7.0 - version: 0.7.0(patch_hash=584b28601fea4de666f3eb91e3425afd11f8da7e4d8aba649c15ec5be5b5d54c)(@astrojs/starlight@0.41.3(patch_hash=ad8925179f0e3050ae6c804196faa6d38a2be2b718acf138001215a18648d3b5)(@astrojs/markdown-remark@7.2.1)(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.3)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))(typescript@6.0.3))(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.3)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))(vite@8.1.5(@types/node@24.13.3)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0)) + version: 0.7.0(patch_hash=584b28601fea4de666f3eb91e3425afd11f8da7e4d8aba649c15ec5be5b5d54c)(@astrojs/starlight@0.41.3(patch_hash=ad8925179f0e3050ae6c804196faa6d38a2be2b718acf138001215a18648d3b5)(@astrojs/markdown-remark@7.2.1)(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))(typescript@6.0.3))(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))(vite@8.1.5(@types/node@24.13.3)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0)) starlight-plugin-icons: specifier: ^1.1.6 - version: 1.1.6(patch_hash=ecdc00afa0722d3cdc77871f9debee551f67d1c02d82fea11c5aa41bf0f48a54)(@astrojs/starlight@0.41.3(patch_hash=ad8925179f0e3050ae6c804196faa6d38a2be2b718acf138001215a18648d3b5)(@astrojs/markdown-remark@7.2.1)(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.3)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))(typescript@6.0.3))(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.3)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))(typescript@6.0.3)(unocss@66.7.5(@unocss/astro@66.7.5(vite@8.1.5(@types/node@24.13.3)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0)))(vite@8.1.5(@types/node@24.13.3)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0)))(zod@4.4.3) + version: 1.1.6(patch_hash=ecdc00afa0722d3cdc77871f9debee551f67d1c02d82fea11c5aa41bf0f48a54)(@astrojs/starlight@0.41.3(patch_hash=ad8925179f0e3050ae6c804196faa6d38a2be2b718acf138001215a18648d3b5)(@astrojs/markdown-remark@7.2.1)(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))(typescript@6.0.3))(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))(typescript@6.0.3)(unocss@66.7.5(@unocss/astro@66.7.5(vite@8.1.5(@types/node@24.13.3)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0)))(vite@8.1.5(@types/node@24.13.3)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0)))(zod@4.4.3) starlight-sidebar-topics: specifier: ^0.8.0 - version: 0.8.0(@astrojs/starlight@0.41.3(patch_hash=ad8925179f0e3050ae6c804196faa6d38a2be2b718acf138001215a18648d3b5)(@astrojs/markdown-remark@7.2.1)(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.3)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))(typescript@6.0.3)) + version: 0.8.0(@astrojs/starlight@0.41.3(patch_hash=ad8925179f0e3050ae6c804196faa6d38a2be2b718acf138001215a18648d3b5)(@astrojs/markdown-remark@7.2.1)(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))(typescript@6.0.3)) tippy.js: specifier: 6.3.7 version: 6.3.7 @@ -213,7 +213,7 @@ importers: version: 66.7.5(vite@8.1.5(@types/node@24.13.3)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0)) astro-embed: specifier: ^0.13.1 - version: 0.13.1(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.3)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))(typescript@6.0.3) + version: 0.13.1(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))(typescript@6.0.3) astro-vtbot: specifier: ^3.0.0 version: 3.0.0 @@ -260,125 +260,125 @@ importers: packages: '@antfu/install-pkg@1.1.0': - resolution: {integrity: sha1-ePoDa+GmCBtad6XPWfUMd1K2uiY=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@antfu/install-pkg/-/install-pkg-1.1.0.tgz} + resolution: {integrity: sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ==} '@astro-community/astro-embed-baseline-status@0.2.2': - resolution: {integrity: sha1-9CtuxtytfZh45fYyjUn9L2SNlnE=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@astro-community/astro-embed-baseline-status/-/astro-embed-baseline-status-0.2.2.tgz} + resolution: {integrity: sha512-07TBEb+xQWWZfMuoHohcZv/r2VSB80/1xN5iLhzSqavLmdsMyebEnbc6tvw3yMkxvX9IBLduNA5SxvVkpmowNQ==} '@astro-community/astro-embed-bluesky@0.2.3': - resolution: {integrity: sha1-+bs11MdAmTlvwg9vCxeBeQiB+Tg=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@astro-community/astro-embed-bluesky/-/astro-embed-bluesky-0.2.3.tgz} + resolution: {integrity: sha512-smevGXIBZTOwsS4S4KpSRzQp9v2C2DOg/3kR5cfpLB9Tc1TG4WFy2qxY6zyxzMfHsEAk7RsLdkQqrdEQ8ylf6A==} '@astro-community/astro-embed-gist@0.1.0': - resolution: {integrity: sha1-sptSO1Z17Jk94uM/l7PR5N1ZyMw=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@astro-community/astro-embed-gist/-/astro-embed-gist-0.1.0.tgz} + resolution: {integrity: sha512-wP3EoBZZjDoPLH6TZzem8jDJxOuweDoK5zWmSra0QBKz3Lry1tZGCwKII5mlnOL2AmTKLrfqrBXTxSGwb7AimQ==} '@astro-community/astro-embed-integration@0.12.1': - resolution: {integrity: sha1-aeoV6X/E91RJN9KRZkfgNAL/GaE=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@astro-community/astro-embed-integration/-/astro-embed-integration-0.12.1.tgz} + resolution: {integrity: sha512-c0OFLOWnfJ/nOE/pTaSp50PIbcijZ0UeTcn8+/pDuIIGTIAH+Z2LYtxpG5+wktXnxarr47Ed7WEVcKHFV75TLQ==} peerDependencies: astro: ^5.0.0 || ^6.0.0-alpha || ^7.0.0 '@astro-community/astro-embed-link-preview@0.3.1': - resolution: {integrity: sha1-4pOqaYgjKlxsN+s3o7iOyJW2xWk=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@astro-community/astro-embed-link-preview/-/astro-embed-link-preview-0.3.1.tgz} + resolution: {integrity: sha512-TI++efm08+kJqxqA7bvxBr7+Zt4yCceA6s3wvAQJ87eiaxbLqAFUSQ+paQD66ET9dIC+IuKzHOMwsoDfqBidYw==} '@astro-community/astro-embed-mastodon@0.1.1': - resolution: {integrity: sha1-trTCF2pWI2Y26rUnOZgwvp5pYVU=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@astro-community/astro-embed-mastodon/-/astro-embed-mastodon-0.1.1.tgz} + resolution: {integrity: sha512-g5Mt1H6GxjkIvXC0HcKqLanZgXHu1e0vNqiQJ8ckryPKmbijYPfhGJYJLPHxE6PaFEA5tmwcmJouVcMPMjf2Kg==} '@astro-community/astro-embed-twitter@0.5.11': - resolution: {integrity: sha1-/3r4lEW6gCB9vXekIsFMxhewVP8=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@astro-community/astro-embed-twitter/-/astro-embed-twitter-0.5.11.tgz} + resolution: {integrity: sha512-6cmyQY4LVVJj6x7qC6XrhWcxNffLvR+QGE/iw5HTOtAn60AStr6u+IX2Txpy6N6bta0DLjGqhTBhkC3NxmVKJg==} '@astro-community/astro-embed-utils@0.2.0': - resolution: {integrity: sha1-dSb6zgCeqrHqPPOiMcEJgDTW3K8=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@astro-community/astro-embed-utils/-/astro-embed-utils-0.2.0.tgz} + resolution: {integrity: sha512-Ia70AMCFOUOSoaMfMaK7Ovk7VyIY4opwzBJoA6GeL+omkvpFwDbSWmA8MOiMF4gJC0j/1dgrEir+txIb+WvsCA==} '@astro-community/astro-embed-vimeo@0.3.12': - resolution: {integrity: sha1-r93+hv1qPaYbeRe8Q4trE0wP3S0=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@astro-community/astro-embed-vimeo/-/astro-embed-vimeo-0.3.12.tgz} + resolution: {integrity: sha512-VLNcsniT5qZ/7GaSGFWnX4ar0qcGyAYB1HQnAH362Zjqs0QI2he9u1nWv1kEx4xr3fZVxl6D2QuNN4xKtd8/ig==} '@astro-community/astro-embed-youtube@0.5.10': - resolution: {integrity: sha1-ukHsxagGro6IN4VvBFW/v+EozPs=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@astro-community/astro-embed-youtube/-/astro-embed-youtube-0.5.10.tgz} + resolution: {integrity: sha512-hVlx77KQLjKzElVQnrU5znQ5/E60keVSAPrhuWvQQHuqva5auJtt8YBpOThkwDMuEKXjQybEF1/3C07RZ8MAOQ==} '@astrojs/compiler-binding-darwin-arm64@0.4.0': - resolution: {integrity: sha1-Z8uYZH0/0dpDRpgTue4sNCHYBfE=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@astrojs/compiler-binding-darwin-arm64/-/compiler-binding-darwin-arm64-0.4.0.tgz} + resolution: {integrity: sha512-ZVUwHundaQyFNjE6uoa0usaC0WOCitDCLS/4mdb4rOiJXwVUuKJBMxI5WMzXLWmamsXtK/Z//ifLXvV5Yeh4Hw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] '@astrojs/compiler-binding-darwin-x64@0.4.0': - resolution: {integrity: sha1-bxJ1yO9sZ7VCCNVUuYdM7vNUJ0Y=, tarball: https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@astrojs/compiler-binding-darwin-x64/-/compiler-binding-darwin-x64-0.4.0.tgz} + resolution: {integrity: sha512-FI6G8AY8u6fR1SI/QRR5yGMwtvZwP34CDmZpZ5HwJGa50UM1VISTLhqkhV4a476pmgd25X1Aur2dqw6hUnrlKA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] '@astrojs/compiler-binding-linux-arm64-gnu@0.4.0': - resolution: {integrity: sha1-muwOaxdIw1cJll67PboMwmpMc5A=, tarball: https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@astrojs/compiler-binding-linux-arm64-gnu/-/compiler-binding-linux-arm64-gnu-0.4.0.tgz} + resolution: {integrity: sha512-lB9gLFJK7m82EnjaU8nlRBEfcwGNeHidW3sSjODTUjMNaoewVuUz9fwwdY5M4jiSXIqWLH3yl6TX8FTDKA74Sw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [glibc] '@astrojs/compiler-binding-linux-arm64-musl@0.4.0': - resolution: {integrity: sha1-3+JPDiD5SKCmFTaFR6iA0GJBa6s=, tarball: https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@astrojs/compiler-binding-linux-arm64-musl/-/compiler-binding-linux-arm64-musl-0.4.0.tgz} + resolution: {integrity: sha512-HPbvWqbxFxyaoQJhLxCaSjtYBx9KBo7JGVzEFZCmMl968a2PsSH0UfiODYgYPXofTOIsIH2aoCcrHXML0IA3ig==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [musl] '@astrojs/compiler-binding-linux-x64-gnu@0.4.0': - resolution: {integrity: sha1-qrbsbQrAWiYSBzNiSjZ8/8tkKYY=, tarball: https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@astrojs/compiler-binding-linux-x64-gnu/-/compiler-binding-linux-x64-gnu-0.4.0.tgz} + resolution: {integrity: sha512-tQKolMxoJ/+0AmLWm1PmJ/i+z3i10ZU1bNuVjEDulCf48azEMtUNjTZgHJ5MPtpYRNc7dlETr8QujUfduzoC7Q==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [glibc] '@astrojs/compiler-binding-linux-x64-musl@0.4.0': - resolution: {integrity: sha1-ZO1Gtpcqz8H25fhQSSdzVUrv5KE=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@astrojs/compiler-binding-linux-x64-musl/-/compiler-binding-linux-x64-musl-0.4.0.tgz} + resolution: {integrity: sha512-5v5YymudsxMHp3NBLCS8BUlu5CRqeLtWD9cKS/4nIhIEHCbpz9okmVV6I0HWqmBAPhWYcDa3vw/vltYPrOQCTA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [musl] '@astrojs/compiler-binding-wasm32-wasi@0.4.0': - resolution: {integrity: sha1-NSld3jttSBLmECAOCNslKfwfEEM=, tarball: https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@astrojs/compiler-binding-wasm32-wasi/-/compiler-binding-wasm32-wasi-0.4.0.tgz} + resolution: {integrity: sha512-m/phuH3x3PREvv1OnkM44NoPh4MatUadix1fB1u5SvMLCyDTUZykDJbKnWf1cjnYmHdlB8HcjTjl6JrCqAIXcw==} engines: {node: '>=14.0.0'} cpu: [wasm32] '@astrojs/compiler-binding-win32-arm64-msvc@0.4.0': - resolution: {integrity: sha1-nSNZZzj0GYMGhiAVW36rIu2VjT4=, tarball: https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@astrojs/compiler-binding-win32-arm64-msvc/-/compiler-binding-win32-arm64-msvc-0.4.0.tgz} + resolution: {integrity: sha512-B9zYf3okEY83kM8gydlpH2BHP00w4ifxPqlYlWrgTwuD6wnkrJDCwBlgy1q31cERjCJRXN1lrE2VmkLvFjv/6g==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [win32] '@astrojs/compiler-binding-win32-x64-msvc@0.4.0': - resolution: {integrity: sha1-0ACfvx77kkXOPzyhmycMq2fALzM=, tarball: https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@astrojs/compiler-binding-win32-x64-msvc/-/compiler-binding-win32-x64-msvc-0.4.0.tgz} + resolution: {integrity: sha512-zB0Nrv0dGc0zZWPGDRmmETTPhDRqyZjAjk+gWMlVrJX5U89obpB3VUUE1ZiHxOCN5LQojeLK6O8L/dnoHolvNQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [win32] '@astrojs/compiler-binding@0.4.0': - resolution: {integrity: sha1-tKua4zkgUe3L+QH+6ExmOR3Pw0c=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@astrojs/compiler-binding/-/compiler-binding-0.4.0.tgz} + resolution: {integrity: sha512-x2RjDUuWfwLNtc3mjAdSRInwqh/rqbLar9cm/5FOMbHvmYZB7yfKewzSclAxWjIZsypJDXv1lhaP2WG+P8TK3g==} engines: {node: ^20.19.0 || >=22.12.0} '@astrojs/compiler-rs@0.4.0': - resolution: {integrity: sha1-ygcYnZ7aBHDgDmHf4mOVGNqxzfE=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@astrojs/compiler-rs/-/compiler-rs-0.4.0.tgz} + resolution: {integrity: sha512-koVikeon1kreEy+/JzLQRy3vzHHQVOjycs4degg4vFufKApZOwMZvSSAEztYNhmcQVfNVsVZZI4cEge3cexAbQ==} engines: {node: '>=22.12.0'} '@astrojs/compiler@2.13.1': - resolution: {integrity: sha1-088m7ZjhnT0QDNvrZhznuFZxnKc=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@astrojs/compiler/-/compiler-2.13.1.tgz} + resolution: {integrity: sha512-f3FN83d2G/v32ipNClRKgYv30onQlMZX1vCeZMjPsMMPl1mDpmbl0+N5BYo4S/ofzqJyS5hvwacEo0CCVDn/Qg==} '@astrojs/internal-helpers@0.10.1': - resolution: {integrity: sha1-P5a2TPc9ORmbGnCQneSIoAXFB3Y=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@astrojs/internal-helpers/-/internal-helpers-0.10.1.tgz} + resolution: {integrity: sha512-5phcroT/vmOOrYuuAxtkbPixy5hePtlz9i8K4OeDv3dNK6/UQRuXPOSRTxIOBbUY5Sonw2UaxjbuVc43Mcir6Q==} '@astrojs/internal-helpers@0.11.0': - resolution: {integrity: sha1-5bYRnnzBo1IP5D4w0lowthV2u0k=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@astrojs/internal-helpers/-/internal-helpers-0.11.0.tgz} + resolution: {integrity: sha512-3rzxJ+xbo0+8YyqOzLziIN32wmsHdCjEVz2sGOpRxJ+Ben/KiLph4ItxBy1abEL+E8fkRzqjg0rfXmaHJGw9JA==} '@astrojs/markdown-remark@7.2.1': - resolution: {integrity: sha1-aqr0TwtErS/QUYN+btMULs0y5Mg=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@astrojs/markdown-remark/-/markdown-remark-7.2.1.tgz} + resolution: {integrity: sha512-jPVNIqTvk+yKviikszv/Y1U4jGUSKpp/Nw48QZV4qjWgp70j4Lkq3lhSDRbWwCfgKvEyO9GHuVbV1dM2WYXy1w==} '@astrojs/markdown-satteri@0.3.4': - resolution: {integrity: sha1-sahWagsSwKfUyzrALYIvWG7sgiw=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@astrojs/markdown-satteri/-/markdown-satteri-0.3.4.tgz} + resolution: {integrity: sha512-6Lvt/bQZEBW+zzdhPblvfZEy5PGEYJaUsUqaCgwHeRPxZJL1gc9I+DRLKWJjjYTWDzVUTzXlMq4WwSK+X34CVw==} '@astrojs/markdown-satteri@0.4.1': - resolution: {integrity: sha1-Lni7CIou349B+wY7hL7e4qj+EuY=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@astrojs/markdown-satteri/-/markdown-satteri-0.4.1.tgz} + resolution: {integrity: sha512-EniHbFNa6SQHDih7JnpPos3NWXO6hdt4raBcOosfGmlfc3gP9CI/sESA3VOf1PgJZ7SFfewlZW9Livn0JugEZg==} '@astrojs/mdx@7.0.3': - resolution: {integrity: sha1-WpBVQuiXNVyMHTau/alIGaykxOM=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@astrojs/mdx/-/mdx-7.0.3.tgz} + resolution: {integrity: sha512-RxyIwU0uFam5ftwqKOjpIdhnFxZ/kEikeimLyQy3eGXbHT8WgRGzzesOIHVU8+m9TY8ag5WVOyvV24/GyqPdPQ==} engines: {node: '>=22.12.0'} peerDependencies: '@astrojs/markdown-satteri': ^0.3.1 @@ -388,22 +388,22 @@ packages: optional: true '@astrojs/node@11.1.6': - resolution: {integrity: sha512-jNZ10/vAT+HuXkX0E/tITsIYCSn3BmAvsooVAN1OjagG+FEzelpUWToy1bA3x6Irmu0VaknWRfReY+1twd35sQ==, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@astrojs/node/-/node-11.1.6.tgz} + resolution: {integrity: sha512-jNZ10/vAT+HuXkX0E/tITsIYCSn3BmAvsooVAN1OjagG+FEzelpUWToy1bA3x6Irmu0VaknWRfReY+1twd35sQ==} peerDependencies: astro: ^7.2.1 '@astrojs/prism@4.0.2': - resolution: {integrity: sha1-XcByWmHqb+ZlpIR05lyWgHmlH0A=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@astrojs/prism/-/prism-4.0.2.tgz} + resolution: {integrity: sha512-KTivpmnz6lDsC6o9H4+DNm2SrE/GHzw8cNAvEJwAvUT+eoaEnn/4NtbDNfRRaxaJHdp15gf+tfHAWiXR4wB3BA==} engines: {node: '>=22.12.0'} '@astrojs/rss@4.0.19': - resolution: {integrity: sha1-oOYZjbqBJfw+DYomRdCYf1OMvAk=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@astrojs/rss/-/rss-4.0.19.tgz} + resolution: {integrity: sha512-e+z5wYeYtffQdHQO8c2tkSd2JEBdAuRXJV4ZEU5IxkYeE6e39woDd7nw1PH1Kk2tEYNCYuKdylnnbhGmt61awA==} '@astrojs/sitemap@3.7.3': - resolution: {integrity: sha1-9u7WLkFP7zNBRrhT18Vv5iaZTPg=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@astrojs/sitemap/-/sitemap-3.7.3.tgz} + resolution: {integrity: sha512-f8euLVsyeAmAkSm/1M2Kb8sL8byQmfgbvBNaHFItCheTj/IpiJYSEWVcqDHZ/yEHxiS7+w87mQkzwZaPHmk5GA==} '@astrojs/starlight@0.41.3': - resolution: {integrity: sha1-voGEk/8IZ8vY2io6D1btP+1vhnY=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@astrojs/starlight/-/starlight-0.41.3.tgz} + resolution: {integrity: sha512-8xsG6UpK581TJmtOc7/pnxHKEbP16rV06VLWaVa7FOyE/VEwnaHOsLtL+miifCEfuiuv0Wn+j8u3JSluRQesMQ==} peerDependencies: '@astrojs/markdown-remark': ^7.2.0 astro: ^7.0.2 @@ -412,412 +412,409 @@ packages: optional: true '@astrojs/telemetry@3.3.3': - resolution: {integrity: sha1-JOW88gPRrAd0fALj8HEBNycggrg=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@astrojs/telemetry/-/telemetry-3.3.3.tgz} + resolution: {integrity: sha512-C1TLn5sPJr0x4vk56piHWKbnqlEB8BKyte5Y45V02U+D7BGO5eMqZDH5aPjnkXQWJggvmsTXxH03QMZ9NgWLzQ==} engines: {node: 18.20.8 || ^20.3.0 || >=22.0.0} '@atcute/atproto@4.0.3': - resolution: {integrity: sha1-cdZeX0Ik/1K4a5b3KR9oVhmdr6s=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@atcute/atproto/-/atproto-4.0.3.tgz} + resolution: {integrity: sha512-BNylfO7nK0yYBpSpnGhOYgrJTeZWrXHPrb6tOQmp9A3Am0epctIWm6/5lPC4ZNPHpUbwr5w/LzH/v7kjAoKEDg==} peerDependencies: '@atcute/lexicons': ^2.0.0 '@atcute/bluesky-richtext-segmenter@3.0.2': - resolution: {integrity: sha1-XRgHxg9SirXGCKEjB6reMQxCLts=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@atcute/bluesky-richtext-segmenter/-/bluesky-richtext-segmenter-3.0.2.tgz} + resolution: {integrity: sha512-LXsUuElLQ/gQe2g04SzgTeEbSwhcnmswioGdneve8e3vE+FU353EjuEVIsnA/H5rnGeLswLdrua7Io1twezynA==} '@atcute/bluesky@4.0.14': - resolution: {integrity: sha1-t+6K/9mLaMQdQsdIFUi/yLiI2pE=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@atcute/bluesky/-/bluesky-4.0.14.tgz} + resolution: {integrity: sha512-XttxcMS81Ld089FFqSF8c1bBZutlNkTWMxCL150IuQeoC/aKNK1M9jd0RrMtVVsaxiWUFSX5yetfEfOCwIZm7A==} peerDependencies: '@atcute/lexicons': ^2.0.0 '@atcute/client@5.1.1': - resolution: {integrity: sha1-fbfP0PrX6LMpKalmJMtsCRgX/eM=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@atcute/client/-/client-5.1.1.tgz} + resolution: {integrity: sha512-cn5/Zi/qo37WtQG6gzIC7JPs0RDzX9Z4eaceX45SpKgLZoc3fCFDJcE7C8xsbxBNfjry2T6PmUxWA8obebZsEQ==} peerDependencies: '@atcute/lexicons': ^2.0.0 '@atcute/identity@2.0.2': - resolution: {integrity: sha1-75BO4Y3m/jkHHSFqyu0WAi/7Jp4=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@atcute/identity/-/identity-2.0.2.tgz} + resolution: {integrity: sha512-amr/EQceqVtBVmjBK4uUF7nKKYuRttadigpvOcAn4dnO6SNSwSjQi8KDH9LnukEotPsSP4UDsQvNfHWEoUcslw==} peerDependencies: '@atcute/lexicons': ^2.0.0 '@atcute/lexicons@2.0.3': - resolution: {integrity: sha1-xHU8zW1S+NAnYjYbwLEoABV0Ujg=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@atcute/lexicons/-/lexicons-2.0.3.tgz} + resolution: {integrity: sha512-rs3WqZIQ7lhSYXEvRU/x9rBMY2/fzvrsTgTf2/bgt+MgIQqOKAMySK3TWqfrvesGHDLxFlunHE3uMXeNdEC90Q==} '@atcute/uint8array@1.1.5': - resolution: {integrity: sha1-zOatl0iUScm5plSHVfI69F4BnBY=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@atcute/uint8array/-/uint8array-1.1.5.tgz} + resolution: {integrity: sha512-1SFCXOtjE3ismP92CqzbOfYSwJmPPPFbj798wLXSpLv2hSd5OIaUrTh6EqRVR1VZ3ZhR+vaBmd3kxAN0wkw+gQ==} '@atcute/util-text@1.3.4': - resolution: {integrity: sha1-a3A3xdmNRDCAZFD9J0O349LaNM4=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@atcute/util-text/-/util-text-1.3.4.tgz} + resolution: {integrity: sha512-u2UAM7iSM09sQaSG9jtxWFSPgB8boVj50/BoyMvYnhVgGBu+nXIuAcdDUQCsZA44YZgTPPhN/b86JX+jH7SPzQ==} '@axe-core/playwright@4.12.1': - resolution: {integrity: sha1-ShTNQe7MH/Ae3Nw9sSouiKzTQYA=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@axe-core/playwright/-/playwright-4.12.1.tgz} + resolution: {integrity: sha512-rMd7xriptqKpP+w5265i4Hdkv2X5kbu6uiBi/B2I7uf3hieRBM3qDCfaKPtxfiYb2mKXfF+yLODJwIx+Jv1GDw==} peerDependencies: playwright-core: '>= 1.0.0' '@babel/helper-string-parser@7.29.7': - resolution: {integrity: sha1-fwhx2Zgk0jE31g+G/PYTD9WhtR8=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz} + resolution: {integrity: sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==} engines: {node: '>=6.9.0'} '@babel/helper-validator-identifier@7.29.7': - resolution: {integrity: sha1-vYcITO0MeW7Ea9pJLeboPSnon8I=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz} + resolution: {integrity: sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==} engines: {node: '>=6.9.0'} '@babel/parser@7.29.7': - resolution: {integrity: sha1-g3uHOHy/XsVTDLY0s8Yi9o7bkzQ=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@babel/parser/-/parser-7.29.7.tgz} + resolution: {integrity: sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg==} engines: {node: '>=6.0.0'} hasBin: true '@babel/runtime@7.29.7': - resolution: {integrity: sha1-EgIkUMRaTabY2Ch7GKT/Ldsj92g=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@babel/runtime/-/runtime-7.29.7.tgz} + resolution: {integrity: sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==} engines: {node: '>=6.9.0'} '@babel/types@7.29.7': - resolution: {integrity: sha1-gAXjHYJxLuetrvbiPGO3GmJ3CpI=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@babel/types/-/types-7.29.7.tgz} + resolution: {integrity: sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==} engines: {node: '>=6.9.0'} '@braintree/sanitize-url@7.1.2': - resolution: {integrity: sha1-yiA1sP7+lWqGdv8Maa9z5gX82B8=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@braintree/sanitize-url/-/sanitize-url-7.1.2.tgz} + resolution: {integrity: sha512-jigsZK+sMF/cuiB7sERuo9V7N9jx+dhmHHnQyDSVdpZwVutaBu7WvNYqMDLSgFgfB30n452TP3vjDAvFC973mA==} '@bruits/satteri-darwin-arm64@0.10.5': - resolution: {integrity: sha1-BAlHHVGBA/qMJCF1i8n6n3i6KFY=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@bruits/satteri-darwin-arm64/-/satteri-darwin-arm64-0.10.5.tgz} + resolution: {integrity: sha512-27KTVl4TJkVahMy/ohyA7qd4938G5UNneFUz/PsScYfpIhj0IVAS23mpcJXdPF44sa6nva198lmV/cKIb2YPyA==} cpu: [arm64] os: [darwin] '@bruits/satteri-darwin-arm64@0.9.5': - resolution: {integrity: sha1-pcWWW56qHQao6pJP2bSrAY9LVnM=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@bruits/satteri-darwin-arm64/-/satteri-darwin-arm64-0.9.5.tgz} + resolution: {integrity: sha512-iw4nZgx9v30lWo/MTngQqi1pI78KI0DnkSm+lVJGYdmPLgAyDNJigVhpG42/Iq55A6c1Ll8q66ljyyRiQUxwow==} cpu: [arm64] os: [darwin] '@bruits/satteri-darwin-x64@0.10.5': - resolution: {integrity: sha1-in1J3qfgW2dW3c0+dIr8fHb28Vg=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@bruits/satteri-darwin-x64/-/satteri-darwin-x64-0.10.5.tgz} + resolution: {integrity: sha512-IjnLe3nKspq6qaeqGgjT7MT8VrTV74yWRlaag7ZdNsI8TDAYZ0iPxMCo+9KQZHUk5EyVB+reBI/PFWL5KuFw9Q==} cpu: [x64] os: [darwin] '@bruits/satteri-darwin-x64@0.9.5': - resolution: {integrity: sha1-O89jnHPIOCin43q7+AGfan65/lg=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@bruits/satteri-darwin-x64/-/satteri-darwin-x64-0.9.5.tgz} + resolution: {integrity: sha512-6T26Z5Kf3cFW2PSlk9p7zT7yVxvuBSiJvYyz9u8KjYwMTqZyIDOj2wDyNpxKV4+6yUVG7rddq2QwvG/8LJA2+Q==} cpu: [x64] os: [darwin] '@bruits/satteri-linux-arm64-gnu@0.10.5': - resolution: {integrity: sha1-IhXb9OAxIPQCbsddEor3W3H3GuY=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@bruits/satteri-linux-arm64-gnu/-/satteri-linux-arm64-gnu-0.10.5.tgz} + resolution: {integrity: sha512-glkYXZCJywjP13v67eAyAMSJdF+ncvEbYvgi/wOtffL9tQ27lr/zsyzUfgs+ovjJ9d8JNQKiXeiArJcX8PJL9w==} cpu: [arm64] os: [linux] libc: [glibc] '@bruits/satteri-linux-arm64-gnu@0.9.5': - resolution: {integrity: sha1-CF3WnAH5+J9kE9gC0BjjBHFLlXI=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@bruits/satteri-linux-arm64-gnu/-/satteri-linux-arm64-gnu-0.9.5.tgz} + resolution: {integrity: sha512-u51id17uJwNEMK9nBlICsq6U31c+XVqQueVBkwRIzZG+gMpS8TOJctt5h5Wz33Z8xnMdTd+adtACVz0yHgGuOA==} cpu: [arm64] os: [linux] libc: [glibc] '@bruits/satteri-linux-arm64-musl@0.10.5': - resolution: {integrity: sha1-P+0dp/al2g8GWd0JpngWrEaxLi4=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@bruits/satteri-linux-arm64-musl/-/satteri-linux-arm64-musl-0.10.5.tgz} + resolution: {integrity: sha512-yWdgG1g17Nh2QyGVlFUxGRa3FEFwiMcpZEyMNWkbM3deC94cmVc+/i9OuyFpdKuWo3GkgoCtYVOoxk1uCnCZIA==} cpu: [arm64] os: [linux] libc: [musl] '@bruits/satteri-linux-arm64-musl@0.9.5': - resolution: {integrity: sha1-Yts0XlGnqK7CBKDzbzjctb03rp0=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@bruits/satteri-linux-arm64-musl/-/satteri-linux-arm64-musl-0.9.5.tgz} + resolution: {integrity: sha512-v39HxiwGC5Rqm01HksP6+5Y+xKLPlsuVFgIgpEAo+SiQ22c+mJVhS3u7Z6ePAKdhL5NJoK1xq70kLz3L13AhpQ==} cpu: [arm64] os: [linux] libc: [musl] '@bruits/satteri-linux-x64-gnu@0.10.5': - resolution: {integrity: sha1-SHZWUP7jsgVL4fSivXShCxtNeWM=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@bruits/satteri-linux-x64-gnu/-/satteri-linux-x64-gnu-0.10.5.tgz} + resolution: {integrity: sha512-FVaLoPT1fBgGl0J+AYebyyXJYBachGl8Oyyrf1lye4RTqCB4S0Gwkj1uM9RJyThUOvx5VUmAT1CnNh1SFHA+kw==} cpu: [x64] os: [linux] libc: [glibc] '@bruits/satteri-linux-x64-gnu@0.9.5': - resolution: {integrity: sha1-Quq2YdUoEBC48gO+X+r8/TppUgQ=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@bruits/satteri-linux-x64-gnu/-/satteri-linux-x64-gnu-0.9.5.tgz} + resolution: {integrity: sha512-F3uO8uFp3pAP5ZGXttwvh57GS7s0lL953tnNdyI2gRyP4kOOkp6pyGojNJzCjkDvWI2Cvb9iNrKok3aqQPauAw==} cpu: [x64] os: [linux] libc: [glibc] '@bruits/satteri-linux-x64-musl@0.10.5': - resolution: {integrity: sha1-ryp6yUUFE3gXB6sm1eeA4b9jCoQ=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@bruits/satteri-linux-x64-musl/-/satteri-linux-x64-musl-0.10.5.tgz} + resolution: {integrity: sha512-EHpVAx2bqW3GINHTKkljtxVfQmVDGWIuwOYOP5YghTj+0PkBa2o8oKPRtQ9Kbsr1Fye8jtUcDjhwj2jMNugZKg==} cpu: [x64] os: [linux] libc: [musl] '@bruits/satteri-linux-x64-musl@0.9.5': - resolution: {integrity: sha1-UOdkjpOU+bYsfWQwJO8GppodZFI=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@bruits/satteri-linux-x64-musl/-/satteri-linux-x64-musl-0.9.5.tgz} + resolution: {integrity: sha512-bicEqglLlz++mWyADaZoP0JY20s4vDfLjaPYgQqC+NI4zZLTOOg1T4GB8aqtc822Pqji8SQBmSrTb7CrP8i08Q==} cpu: [x64] os: [linux] libc: [musl] '@bruits/satteri-wasm32-wasi@0.10.5': - resolution: {integrity: sha1-KkRBGNjwMYPsnyI6pwVrnlxON3g=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@bruits/satteri-wasm32-wasi/-/satteri-wasm32-wasi-0.10.5.tgz} + resolution: {integrity: sha512-ypz8c/Zmipxp4IoeDa228Gstv6TLzVmNs3yC6wKCoNSOjx1iwpgzu87Y3hTkXFdwChVGU85qeUDuOIarGUZQLw==} engines: {node: '>=14.0.0'} cpu: [wasm32] '@bruits/satteri-wasm32-wasi@0.9.5': - resolution: {integrity: sha1-zST/vhZQV35ivtes0hxItMXrrR0=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@bruits/satteri-wasm32-wasi/-/satteri-wasm32-wasi-0.9.5.tgz} + resolution: {integrity: sha512-zauAuMwfPnKPUkd4AFixRFpXdgKwP2mKgxrIIo2gJzW0/ZneF9dbHnLkojSpaBnCCp7VUL1hIi5WWZvB1CqmAQ==} engines: {node: '>=14.0.0'} cpu: [wasm32] '@bruits/satteri-win32-arm64-msvc@0.10.5': - resolution: {integrity: sha1-O2yrEN0S5ClK287p3NtXslDRKlI=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@bruits/satteri-win32-arm64-msvc/-/satteri-win32-arm64-msvc-0.10.5.tgz} + resolution: {integrity: sha512-siTV88nb0LRqNpkL2gXboqCwVdq95sLtzMHS1/3eONV2gLbB3NAK46wmSMvCO/yquBvI2lvaFIfd8P12ecsxBw==} cpu: [arm64] os: [win32] '@bruits/satteri-win32-arm64-msvc@0.9.5': - resolution: {integrity: sha1-DYOFJTX2PFCrkCU/4gnlzlz/6wk=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@bruits/satteri-win32-arm64-msvc/-/satteri-win32-arm64-msvc-0.9.5.tgz} + resolution: {integrity: sha512-SrfE7NEsgZjBvU3c+RR6oQRu0ToXY5uVJEbieXEF0YTctIV2zAVlbaMjWLts074QCgh3a+XHWkR/lWh2VH2LUg==} cpu: [arm64] os: [win32] '@bruits/satteri-win32-x64-msvc@0.10.5': - resolution: {integrity: sha1-Im5ZHoxj0y51qA2GNDvnBk55wag=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@bruits/satteri-win32-x64-msvc/-/satteri-win32-x64-msvc-0.10.5.tgz} + resolution: {integrity: sha512-C3IfPvfvMXmlzBxaMPKFS1XiuV9pu2mC7YqkPk7PSvTgPZ8gbdASIpHpztDLvTTQjqZ0z1Ol8tK5X+V6XXC0wQ==} cpu: [x64] os: [win32] '@bruits/satteri-win32-x64-msvc@0.9.5': - resolution: {integrity: sha1-FUinVztYRp3GM+zDhArqwZSJNxA=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@bruits/satteri-win32-x64-msvc/-/satteri-win32-x64-msvc-0.9.5.tgz} + resolution: {integrity: sha512-5Kw9ZAtTGS8WHizyn+CJhjjfIQrw+7jcZodpmpXJjefnO15M8UexIi6JR2E5thyvsmHyhL6ZDDMUNR4bKJPd4g==} cpu: [x64] os: [win32] '@capsizecss/unpack@4.0.1': - resolution: {integrity: sha1-X8Xzo3GpOmnXZOgaCbrfAUM4Fzk=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@capsizecss/unpack/-/unpack-4.0.1.tgz} + resolution: {integrity: sha512-CuNiSqg7+e1cO/GjffyMOm5Tt2jUF9CWHHnvQ/UkqvtkGfHdgwEC0wpmq7fkN3gxwpRnrAN0WzO3vREKmNolMQ==} engines: {node: '>=18'} '@catppuccin/starlight@2.1.0': - resolution: {integrity: sha1-ESnWZTrR3imB8cRoyNM4Y3LC530=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@catppuccin/starlight/-/starlight-2.1.0.tgz} + resolution: {integrity: sha512-S5zr0WMHUZgsKzoAebj48DAT5r96jRgJSNftNEIoSi9Nk9KatxP5IUntYqmX5B2L5PGfvKO/oEjINuLLaiRn0g==} peerDependencies: '@astrojs/starlight': '>=0.38' astro: ^6.0.0 || ^7.0.0 '@chevrotain/types@11.1.2': - resolution: {integrity: sha1-6DoaJwTwxeSedZKyFAMaD0o01+U=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@chevrotain/types/-/types-11.1.2.tgz} + resolution: {integrity: sha512-U+HFai5+zmJCkK86QsaJtoITlboZHBqrVketcO2ROv865xfCMSFpELQoz1GkX5GzME8pTa+3kbKrZHQtI0gdbw==} '@clack/core@0.3.5': - resolution: {integrity: sha1-PhRUyDoyk1PMOm/4SR5ChNSVZbs=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@clack/core/-/core-0.3.5.tgz} + resolution: {integrity: sha512-5cfhQNH+1VQ2xLQlmzXMqUoiaH0lRBq9/CLW9lTyMbuKLC3+xEK01tHVvyut++mLOn5urSHmkm6I0Lg9MaJSTQ==} '@clack/core@1.4.3': - resolution: {integrity: sha1-HoMZdPgR1zNwfsZQ5Y9pDX10xfo=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@clack/core/-/core-1.4.3.tgz} + resolution: {integrity: sha512-/kr3UWNtdJfxZtPgDqUOmG2pvwlmcLGheex5yiZKdwbzZJxhV+HMNR9QNmyY5cGwTNV6LrR7Jtp+KjhUAP1qBQ==} engines: {node: '>= 20.12.0'} '@clack/prompts@1.7.0': - resolution: {integrity: sha1-LWztNjpgi6I/a5YRIFuDBshbvw0=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@clack/prompts/-/prompts-1.7.0.tgz} + resolution: {integrity: sha512-y7/yvZ2TPAnR9+jnc00klvNNLkJiXFFrQA/hlLCcxA9a2A4zQIOimyFQ9XfwYKiGD1fb5GY8vbKIIgO8d5Tb2A==} engines: {node: '>= 20.12.0'} '@ctrl/tinycolor@4.2.0': - resolution: {integrity: sha1-ul0LkXMDwLPTwUxIZc3G3tJawF8=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@ctrl/tinycolor/-/tinycolor-4.2.0.tgz} + resolution: {integrity: sha512-kzyuwOAQnXJNLS9PSyrk0CWk35nWJW/zl/6KvnTBMFK65gm7U1/Z5BqjxeapjZCIhQcM/DsrEmcbRwDyXyXK4A==} engines: {node: '>=14'} '@ec-ts/twoslash-vue@1.0.0': - resolution: {integrity: sha1-JVlsNZTOaGNm4KxIP/QnvyBRQSc=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@ec-ts/twoslash-vue/-/twoslash-vue-1.0.0.tgz} + resolution: {integrity: sha512-3bB0/1DPPLHjS0eok2Cne7xQjCQVU5AWScEBGYTqsKuTCTukDUMxUiYI54rDPQME3OLnpysiORi0FQKLA96pAg==} peerDependencies: typescript: ^5.5.0 '@ec-ts/twoslash@1.0.0': - resolution: {integrity: sha1-tIYoSsUW/gLgAjmJbxopKz4h1Dc=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@ec-ts/twoslash/-/twoslash-1.0.0.tgz} + resolution: {integrity: sha512-Bp4MCmeDWVRkTkuytPTszan+QGUqeftiasOBadvxSfQpbXYiWsle/N0lMrG+S14bfS9iBzI8mEqdGgd3Fvr3jQ==} peerDependencies: typescript: ^5.5.0 '@ec-ts/vfs@1.0.0': - resolution: {integrity: sha1-19liTE9RbrLPem5ENtjWJ4eA7IA=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@ec-ts/vfs/-/vfs-1.0.0.tgz} + resolution: {integrity: sha512-GQYRPMp58p9ak+TOwSLB/HZ+iknFyTRjqMTdXDkitNN3h5yjHuO+yeeO+/cuXiv7dyXGLYs4HaYrFgRKImp8yg==} peerDependencies: typescript: ^5.5.0 '@emnapi/core@1.10.0': - resolution: {integrity: sha1-OAzMjyQS6iLR2XLff47iOjucdGc=, tarball: https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@emnapi/core/-/core-1.10.0.tgz} + resolution: {integrity: sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==} '@emnapi/core@1.11.1': - resolution: {integrity: sha1-ueEGTzprFjHiQeY460jXNr/TcqY=, tarball: https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@emnapi/core/-/core-1.11.1.tgz} + resolution: {integrity: sha512-RSvbQmHzdKzNsLYa/wHrbc3KN4sYLKAdPZxqiM2HATqv/SBk2/ENSHpvXGaLOMcsAyz0poEGqkmmKYG3OWiJEQ==} '@emnapi/runtime@1.10.0': - resolution: {integrity: sha1-SyYMDTU0IE6YxhELjbGph9JuyHw=, tarball: https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@emnapi/runtime/-/runtime-1.10.0.tgz} + resolution: {integrity: sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==} '@emnapi/runtime@1.11.1': - resolution: {integrity: sha1-WPHz1dgamxL3k6tojJY3GQECfCQ=, tarball: https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@emnapi/runtime/-/runtime-1.11.1.tgz} - - '@emnapi/runtime@1.11.3': - resolution: {integrity: sha1-hCV647BTHrKuwf+iPXBwDaAHupU=, tarball: https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@emnapi/runtime/-/runtime-1.11.3.tgz} + resolution: {integrity: sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw==} '@emnapi/wasi-threads@1.2.1': - resolution: {integrity: sha1-KP7SGhuhznl8RKBwq8lNQvOuhUg=, tarball: https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz} + resolution: {integrity: sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==} '@emnapi/wasi-threads@1.2.2': - resolution: {integrity: sha1-TJO+z1v6OxPRu9zAau44MhrYE5o=, tarball: https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@emnapi/wasi-threads/-/wasi-threads-1.2.2.tgz} + resolution: {integrity: sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA==} '@esbuild/aix-ppc64@0.28.1': - resolution: {integrity: sha1-egGo0uwvuy2seK2tCbD6eB5Agr4=, tarball: https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/aix-ppc64/-/aix-ppc64-0.28.1.tgz} + resolution: {integrity: sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ==} engines: {node: '>=18'} cpu: [ppc64] os: [aix] '@esbuild/android-arm64@0.28.1': - resolution: {integrity: sha1-tUCifRTkr9BYSWpNvsTT9BTbEQo=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/android-arm64/-/android-arm64-0.28.1.tgz} + resolution: {integrity: sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg==} engines: {node: '>=18'} cpu: [arm64] os: [android] '@esbuild/android-arm@0.28.1': - resolution: {integrity: sha1-cEvSl95tdi3lTqu+r79V9nVqvi8=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/android-arm/-/android-arm-0.28.1.tgz} + resolution: {integrity: sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ==} engines: {node: '>=18'} cpu: [arm] os: [android] '@esbuild/android-x64@0.28.1': - resolution: {integrity: sha1-0csWbTSw+/D+irRgpVlPJKN4cB4=, tarball: https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/android-x64/-/android-x64-0.28.1.tgz} + resolution: {integrity: sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng==} engines: {node: '>=18'} cpu: [x64] os: [android] '@esbuild/darwin-arm64@0.28.1': - resolution: {integrity: sha1-EDSyZFf8iGNo/mG70J9lP2r6jlQ=, tarball: https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/darwin-arm64/-/darwin-arm64-0.28.1.tgz} + resolution: {integrity: sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q==} engines: {node: '>=18'} cpu: [arm64] os: [darwin] '@esbuild/darwin-x64@0.28.1': - resolution: {integrity: sha1-ZVVqQyoeTXIDLYIYwZMvzKGkl3I=, tarball: https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/darwin-x64/-/darwin-x64-0.28.1.tgz} + resolution: {integrity: sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ==} engines: {node: '>=18'} cpu: [x64] os: [darwin] '@esbuild/freebsd-arm64@0.28.1': - resolution: {integrity: sha1-LmHgWS+QMNfj2uGO4l68U1kYrvY=, tarball: https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.1.tgz} + resolution: {integrity: sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw==} engines: {node: '>=18'} cpu: [arm64] os: [freebsd] '@esbuild/freebsd-x64@0.28.1': - resolution: {integrity: sha1-yV7CiZWe+AecTcqBeh4sS+Zrm9M=, tarball: https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/freebsd-x64/-/freebsd-x64-0.28.1.tgz} + resolution: {integrity: sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ==} engines: {node: '>=18'} cpu: [x64] os: [freebsd] '@esbuild/linux-arm64@0.28.1': - resolution: {integrity: sha1-QLIhdd2gYYLz7oFBGGxf8wTEpxc=, tarball: https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/linux-arm64/-/linux-arm64-0.28.1.tgz} + resolution: {integrity: sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g==} engines: {node: '>=18'} cpu: [arm64] os: [linux] '@esbuild/linux-arm@0.28.1': - resolution: {integrity: sha1-wJoPZ5F1kqwN6JKpvk04FN69Kmw=, tarball: https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/linux-arm/-/linux-arm-0.28.1.tgz} + resolution: {integrity: sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ==} engines: {node: '>=18'} cpu: [arm] os: [linux] '@esbuild/linux-ia32@0.28.1': - resolution: {integrity: sha1-pYD5xnZ5eDOJHlGfx6EzfIr9jbM=, tarball: https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/linux-ia32/-/linux-ia32-0.28.1.tgz} + resolution: {integrity: sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w==} engines: {node: '>=18'} cpu: [ia32] os: [linux] '@esbuild/linux-loong64@0.28.1': - resolution: {integrity: sha1-RkUs8yHcf56Rwvp4Cla7Vuec1os=, tarball: https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/linux-loong64/-/linux-loong64-0.28.1.tgz} + resolution: {integrity: sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg==} engines: {node: '>=18'} cpu: [loong64] os: [linux] '@esbuild/linux-mips64el@0.28.1': - resolution: {integrity: sha1-QhGzGE3WYI9T3LIuOfXTTuCIUsg=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/linux-mips64el/-/linux-mips64el-0.28.1.tgz} + resolution: {integrity: sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ==} engines: {node: '>=18'} cpu: [mips64el] os: [linux] '@esbuild/linux-ppc64@0.28.1': - resolution: {integrity: sha1-aXhXwqYcubC2u2ZS5AwdxeHKjl0=, tarball: https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/linux-ppc64/-/linux-ppc64-0.28.1.tgz} + resolution: {integrity: sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ==} engines: {node: '>=18'} cpu: [ppc64] os: [linux] '@esbuild/linux-riscv64@0.28.1': - resolution: {integrity: sha1-0ZKUPrFGpArExkl9DPe+NbmGvwg=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/linux-riscv64/-/linux-riscv64-0.28.1.tgz} + resolution: {integrity: sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ==} engines: {node: '>=18'} cpu: [riscv64] os: [linux] '@esbuild/linux-s390x@0.28.1': - resolution: {integrity: sha1-rOoDVtoODrwI+Xz3ucLkAeHmSNw=, tarball: https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/linux-s390x/-/linux-s390x-0.28.1.tgz} + resolution: {integrity: sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag==} engines: {node: '>=18'} cpu: [s390x] os: [linux] '@esbuild/linux-x64@0.28.1': - resolution: {integrity: sha1-bww84MtkxTS3DExF7LLBbTTjXf0=, tarball: https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/linux-x64/-/linux-x64-0.28.1.tgz} + resolution: {integrity: sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA==} engines: {node: '>=18'} cpu: [x64] os: [linux] '@esbuild/netbsd-arm64@0.28.1': - resolution: {integrity: sha1-i813B3oNzjN4tXT+2ybSolO3PTY=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.1.tgz} + resolution: {integrity: sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw==} engines: {node: '>=18'} cpu: [arm64] os: [netbsd] '@esbuild/netbsd-x64@0.28.1': - resolution: {integrity: sha1-5/sqAemcgwyU5mI82f77TI+1g0c=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/netbsd-x64/-/netbsd-x64-0.28.1.tgz} + resolution: {integrity: sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg==} engines: {node: '>=18'} cpu: [x64] os: [netbsd] '@esbuild/openbsd-arm64@0.28.1': - resolution: {integrity: sha1-xSkJNy24uG4sVeBaiUADO1Zgo7I=, tarball: https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.1.tgz} + resolution: {integrity: sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q==} engines: {node: '>=18'} cpu: [arm64] os: [openbsd] '@esbuild/openbsd-x64@0.28.1': - resolution: {integrity: sha1-xCe5vlpkwmL/mn63C1+7qt9EbGw=, tarball: https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/openbsd-x64/-/openbsd-x64-0.28.1.tgz} + resolution: {integrity: sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw==} engines: {node: '>=18'} cpu: [x64] os: [openbsd] '@esbuild/openharmony-arm64@0.28.1': - resolution: {integrity: sha1-3JsUe6yi5sSzyFVxdB70hgpIkJc=, tarball: https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.1.tgz} + resolution: {integrity: sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg==} engines: {node: '>=18'} cpu: [arm64] os: [openharmony] '@esbuild/sunos-x64@0.28.1': - resolution: {integrity: sha1-zoZtEt8TwV5MmfBzo9Rm9uBkmzo=, tarball: https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/sunos-x64/-/sunos-x64-0.28.1.tgz} + resolution: {integrity: sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ==} engines: {node: '>=18'} cpu: [x64] os: [sunos] '@esbuild/win32-arm64@0.28.1': - resolution: {integrity: sha1-dGjjaS0B1inVlB5dg4F7uA+eObQ=, tarball: https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/win32-arm64/-/win32-arm64-0.28.1.tgz} + resolution: {integrity: sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA==} engines: {node: '>=18'} cpu: [arm64] os: [win32] '@esbuild/win32-ia32@0.28.1': - resolution: {integrity: sha1-pbwAY/sryrbQ7WPyoVN5WLwmnsY=, tarball: https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/win32-ia32/-/win32-ia32-0.28.1.tgz} + resolution: {integrity: sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg==} engines: {node: '>=18'} cpu: [ia32] os: [win32] '@esbuild/win32-x64@0.28.1': - resolution: {integrity: sha1-EAZO5E9DR7kMmgK0Rrv4CpFjKxI=, tarball: https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/win32-x64/-/win32-x64-0.28.1.tgz} + resolution: {integrity: sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A==} engines: {node: '>=18'} cpu: [x64] os: [win32] '@eslint-community/eslint-utils@4.9.1': - resolution: {integrity: sha1-TpCvZ7xR3e5s3vUoTt9XLsN2tZU=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz} + resolution: {integrity: sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 '@eslint-community/regexpp@4.12.2': - resolution: {integrity: sha1-vM32Fbz3tujbgw7AuNIcmiXeWXs=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@eslint-community/regexpp/-/regexpp-4.12.2.tgz} + resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} '@eslint/config-array@0.23.5': - resolution: {integrity: sha1-VuhtJDBJGV2KzAwGobPf3D+j3pU=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@eslint/config-array/-/config-array-0.23.5.tgz} + resolution: {integrity: sha512-Y3kKLvC1dvTOT+oGlqNQ1XLqK6D1HU2YXPc52NmAlJZbMMWDzGYXMiPRJ8TYD39muD/OTjlZmNJ4ib7dvSrMBA==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} '@eslint/config-helpers@0.6.0': - resolution: {integrity: sha1-75o2iB0539Xb6sIrDamX+r+wiwM=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@eslint/config-helpers/-/config-helpers-0.6.0.tgz} + resolution: {integrity: sha512-ii6Bw9jJ2zi2cWA2Z+9/QZ/+3DX6kwaV5Q986D/CdP3Lap3w/pgQZ373FV7byY/i7L4IRH/G43I5dz1ClsCbpA==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} '@eslint/core@1.2.1': - resolution: {integrity: sha1-wdp80bgvqHh/mLVin7gRhIobY84=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@eslint/core/-/core-1.2.1.tgz} + resolution: {integrity: sha512-MwcE1P+AZ4C6DWlpin/OmOA54mmIZ/+xZuJiQd4SyB29oAJjN30UW9wkKNptW2ctp4cEsvhlLY/CsQ1uoHDloQ==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} '@eslint/js@10.0.1': - resolution: {integrity: sha1-HoqHb1ARevirZ+R9WtlNONZiJYM=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@eslint/js/-/js-10.0.1.tgz} + resolution: {integrity: sha512-zeR9k5pd4gxjZ0abRoIaxdc7I3nDktoXZk2qOv9gCNWx3mVwEn32VRhyLaRsDiJjTs0xq/T8mfPtyuXu7GWBcA==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} peerDependencies: eslint: ^10.0.0 @@ -826,852 +823,845 @@ packages: optional: true '@eslint/object-schema@3.0.5': - resolution: {integrity: sha1-iOm/TRHSsZwILnjr586IckpesJE=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@eslint/object-schema/-/object-schema-3.0.5.tgz} + resolution: {integrity: sha512-vqTaUEgxzm+YDSdElad6PiRoX4t8VGDjCtt05zn4nU810UIx/uNEV7/lZJ6KwFThKZOzOxzXy48da+No7HZaMw==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} '@eslint/plugin-kit@0.7.2': - resolution: {integrity: sha1-Swli8/LHzovJiz7P40UlwJ0styk=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@eslint/plugin-kit/-/plugin-kit-0.7.2.tgz} + resolution: {integrity: sha512-+CNAzxglkrpNf/kKywqQfk74QjtceuOE7Qm+AF8miRvPF/wmmK5+OJOgVh3AVTT3RP2mH3+FOaxlE5v72owk0A==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} '@expressive-code/core@0.44.1': - resolution: {integrity: sha1-f0K9tpME4GoxR6GoA5xwXuSOsvs=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@expressive-code/core/-/core-0.44.1.tgz} + resolution: {integrity: sha512-3dDo9N8D7hYrLNNMMWFovg3+aDUtnQm7c7z0GZc1c0LEFVBc0Q6lKG+tVT28gDadOvsgOANfCn35fgpe97Pmgg==} '@expressive-code/plugin-collapsible-sections@0.44.1': - resolution: {integrity: sha1-9TEzp4FGazLW8ZgU66g/rBkbiWY=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@expressive-code/plugin-collapsible-sections/-/plugin-collapsible-sections-0.44.1.tgz} + resolution: {integrity: sha512-1XG4PfamU5JPpWf9Z5jEsS1mNbeymntwn1EoQE40PPS5K9rUNTKpY5GFYEI60vWwj890a3/Oz9bCWTomvFityQ==} '@expressive-code/plugin-frames@0.44.1': - resolution: {integrity: sha1-ZBYWl09zUuE1cmQGPIwhHzmyhDk=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@expressive-code/plugin-frames/-/plugin-frames-0.44.1.tgz} + resolution: {integrity: sha512-HC/bdRao9225ApcgO/e3jn8ZOhldKO7ob1O/Tcipvtv7Vb5nMphZhMtD9uuywpvxkPYBHJi3504WhrKg05Dwqg==} '@expressive-code/plugin-line-numbers@0.44.1': - resolution: {integrity: sha1-cKthtCKv3DDW3bf3BKRvMpFrqI0=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@expressive-code/plugin-line-numbers/-/plugin-line-numbers-0.44.1.tgz} + resolution: {integrity: sha512-rWZmmSXBq9sq0DSe5+bXA+7j+3bYrh4EwXJdaBZtxEKB2I99OUSrU2d+4FAyu9Afpm5tCijbCs9AOg7Y93suOw==} '@expressive-code/plugin-shiki@0.44.1': - resolution: {integrity: sha1-zsr85/Ob5h0UfLel/VAD+obj54g=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@expressive-code/plugin-shiki/-/plugin-shiki-0.44.1.tgz} + resolution: {integrity: sha512-YApiZt3buUzBwL5tqj8G+sYC5NjMjRCHgQwr9bmGl69rtcHy6fE9dooWUeKYB978fJT2BuxT5FeHcF47rA3SEg==} '@expressive-code/plugin-text-markers@0.44.1': - resolution: {integrity: sha1-fRMq5v7NKhAu40xR9uP/XUnoOwg=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@expressive-code/plugin-text-markers/-/plugin-text-markers-0.44.1.tgz} + resolution: {integrity: sha512-B3BsJoJ8CFMlcIX9f+X9tcI3C4zPDO601+YuLi9GheSTNro7ZfqSjLptMQKBHOWZvxnAtY5zvIX7iO/qtBhNBg==} '@fontsource-variable/fira-code@5.3.0': - resolution: {integrity: sha1-aFqUPY+NGkg9NtN4hXdDFC5wOkY=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@fontsource-variable/fira-code/-/fira-code-5.3.0.tgz} + resolution: {integrity: sha512-ZhvHeknlicraKVSJBa1NrJnXDVByUkC407zwgELYfmnx3p9g8vwIPfQCxx8YD3K7dAeCdLuHJOHlpMfRsIcApQ==} '@fontsource-variable/rubik@5.3.0': - resolution: {integrity: sha1-3l5zEUXnQ10H8U9u/AgxItTlHdA=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@fontsource-variable/rubik/-/rubik-5.3.0.tgz} + resolution: {integrity: sha512-yQUf8qle24MJYA+EuauyF+cqjjN6I715nGjitt3sGmwZA0XfA4fWJcLq1C/diREZl4Qzn1E80nLMc0ipC/a4Lg==} '@fontsource/poppins@5.3.0': - resolution: {integrity: sha1-KwuVrW0iHKgfiEeWQpsgmDeVS4k=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@fontsource/poppins/-/poppins-5.3.0.tgz} + resolution: {integrity: sha512-cms1nM7U6SN8epIV1WMVOV8VsA645aSm3wHfzIQnkk188U341ThbJGSl2Sv54V29gnDbT2arMPfLzvVIIVCceQ==} '@humanfs/core@0.19.2': - resolution: {integrity: sha1-qCcsoDsqz0kmcCIrIyC2xCG/3mA=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@humanfs/core/-/core-0.19.2.tgz} + resolution: {integrity: sha512-UhXNm+CFMWcbChXywFwkmhqjs3PRCmcSa/hfBgLIb7oQ5HNb1wS0icWsGtSAUNgefHeI+eBrA8I1fxmbHsGdvA==} engines: {node: '>=18.18.0'} '@humanfs/node@0.16.8': - resolution: {integrity: sha1-j4AMzME/T4zTEW4tnAqUk52j4+0=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@humanfs/node/-/node-0.16.8.tgz} + resolution: {integrity: sha512-gE1eQNZ3R++kTzFUpdGlpmy8kDZD/MLyHqDwqjkVQI0JMdI1D51sy1H958PNXYkM2rAac7e5/CnIKZrHtPh3BQ==} engines: {node: '>=18.18.0'} '@humanfs/types@0.15.0': - resolution: {integrity: sha1-8qCfYgEjkLK/8/xvskjd7IwJoJA=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@humanfs/types/-/types-0.15.0.tgz} + resolution: {integrity: sha512-ZZ1w0aoQkwuUuC7Yf+7sdeaNfqQiiLcSRbfI08oAxqLtpXQr9AIVX7Ay7HLDuiLYAaFPu8oBYNq/QIi9URHJ3Q==} engines: {node: '>=18.18.0'} '@humanwhocodes/module-importer@1.0.1': - resolution: {integrity: sha1-r1smkaIrRL6EewyoFkHF+2rQFyw=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz} + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} engines: {node: '>=12.22'} '@humanwhocodes/retry@0.4.3': - resolution: {integrity: sha1-wrnS43TuYsWG062+qHGZsdenpro=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@humanwhocodes/retry/-/retry-0.4.3.tgz} + resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} engines: {node: '>=18.18'} '@iconify-json/devicon@1.2.62': - resolution: {integrity: sha1-jNK1rMZlH+Yvuy796IyERlIigj8=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@iconify-json/devicon/-/devicon-1.2.62.tgz} + resolution: {integrity: sha512-X0o0+fOJL2t5JTbDCGLRzrmvf8Pv5q8dr86+fW+F/VJ9qvXTtny6lqGIwjE9AY4VTLm3i8f/N+VtRheSW6OkEg==} '@iconify-json/material-icon-theme@1.2.69': - resolution: {integrity: sha1-SqrXW3El23NmJR53ZOzKh6aKSUU=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@iconify-json/material-icon-theme/-/material-icon-theme-1.2.69.tgz} + resolution: {integrity: sha512-BqVadW0C19qyzp7Gtl2z0wExBFhfGKDPrgq4ajnGUe9atBcqSwz/yULCbZWzjPlOPrFFu4P3hhfs8Vl503nhEg==} '@iconify-json/mdi@1.2.3': - resolution: {integrity: sha1-Xk7p2MiqrQQ4HIzGxu2+MyfwMbU=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@iconify-json/mdi/-/mdi-1.2.3.tgz} + resolution: {integrity: sha512-O3cLwbDOK7NNDf2ihaQOH5F9JglnulNDFV7WprU2dSoZu3h3cWH//h74uQAB87brHmvFVxIOkuBX2sZSzYhScg==} '@iconify/types@2.0.0': - resolution: {integrity: sha1-qw6epoHWyKEhTzDNdB/jogzFf1c=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@iconify/types/-/types-2.0.0.tgz} + resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==} '@iconify/utils@3.1.4': - resolution: {integrity: sha1-BNrQFOjtgLG740H10JAFnqDGBXg=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@iconify/utils/-/utils-3.1.4.tgz} + resolution: {integrity: sha512-b1S7B1k9ohZ+iNTi2ATxbRYG9fTrJmUT0rc46bvVnNxqNRGW7dyo/vRREwyniI5IRN2RSJHDcm+s3BjWrSAjHw==} '@img/colour@1.1.0': - resolution: {integrity: sha1-sMLC+mYa33Xv/WtJZEl82AAQu50=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@img/colour/-/colour-1.1.0.tgz} + resolution: {integrity: sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==} engines: {node: '>=18'} '@img/sharp-darwin-arm64@0.35.4': - resolution: {integrity: sha1-vBCyYt4vyACIAT9fmYKY0ciQn78=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.35.4.tgz} + resolution: {integrity: sha512-Uhfl4V4lhP2nbUVF9+hyH1+luj86f1gUFeo8ALYxFoULoU+G87D43BfeMP8XHsk9boxAnCY/bf2EHwhA7MuGsA==} engines: {node: '>=20.9.0'} cpu: [arm64] os: [darwin] '@img/sharp-darwin-x64@0.35.4': - resolution: {integrity: sha1-dsSf8E+z+dhGsNBXWEG37lm+7Gg=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.35.4.tgz} + resolution: {integrity: sha512-hWniXY3bG5qKpkKrAwPe4y+VTPmf086YQAnkxWh7uA1YrlRouWGa0M0Mxj3ZjnXFkv7/TD1bTy9lGUK26vRvWw==} engines: {node: '>=20.9.0'} cpu: [x64] os: [darwin] '@img/sharp-freebsd-wasm32@0.35.4': - resolution: {integrity: sha1-ulX9YDxdHQGhyxT/tNlwvGztgOE=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@img/sharp-freebsd-wasm32/-/sharp-freebsd-wasm32-0.35.4.tgz} + resolution: {integrity: sha512-lIsKw/BU+kjB4eZjxrYrZmwOJYi3Ajrv66iAlBmUPyKc3HpnloevB1g3wxGD9P/5BbQ1brBGl65VRRrCvQDEqA==} engines: {node: '>=20.9.0'} os: [freebsd] '@img/sharp-libvips-darwin-arm64@1.3.3': - resolution: {integrity: sha1-CKbPT7TujUX5lASladyqayk5HZc=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.3.3.tgz} + resolution: {integrity: sha512-suTBPTDGrI9WodccaDdwZItTSaBYASlBk1NSfElSHrUfzu3szG6lvIF58+WiFvnfzuK8ZBFS5zE00PxqxnRiPg==} cpu: [arm64] os: [darwin] '@img/sharp-libvips-darwin-x64@1.3.3': - resolution: {integrity: sha1-FGHm+zEKhps8E1BFibjdXAZiTag=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.3.3.tgz} + resolution: {integrity: sha512-FVJZ5mITMobmXIz/hPDTw0EintTW5H3WfrxwLqEqjiIihlu+hVRyGrFQ60xl0Lxn7Bt3zdpevPaQi0HEzqz9fw==} cpu: [x64] os: [darwin] '@img/sharp-libvips-linux-arm64@1.3.3': - resolution: {integrity: sha1-y5OKOXG5o2MpvJlCfx5bcuJmui4=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.3.3.tgz} + resolution: {integrity: sha512-0DaL0A6Xu6sQSQFwe4iVCrKWU2cCTItnRsYsCdxAMm9NF6twAA9BKnoqy4hqz4+azQ0JHuA26qiUKsf1XJ/v5A==} cpu: [arm64] os: [linux] libc: [glibc] '@img/sharp-libvips-linux-arm@1.3.3': - resolution: {integrity: sha1-cQMpQbn8v468PBtilJknuETLrWI=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.3.3.tgz} + resolution: {integrity: sha512-3rbU4vqXXc3hY/OiXdl52xZvT0F1yEngWfvqudtPJg/KkyiaQw2DRsFrNzpmLvfavbwOq3qXn36GP8obHRULQA==} cpu: [arm] os: [linux] libc: [glibc] '@img/sharp-libvips-linux-ppc64@1.3.3': - resolution: {integrity: sha1-gkbS3sFSNP0cxUzFXcuhrrwmxBQ=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.3.3.tgz} + resolution: {integrity: sha512-cdn1OvUBwsXhbC0zSzJnNzf5MZ/mTrobawDvNXBTxe8VtqKAm0sRuEY2Evzovb/w9JMk4TvRxqt1mekSuJz64w==} cpu: [ppc64] os: [linux] libc: [glibc] '@img/sharp-libvips-linux-riscv64@1.3.3': - resolution: {integrity: sha1-Wf9mPCqmtBiFc1fNd8pMyuzpWHY=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.3.3.tgz} + resolution: {integrity: sha512-HjPVx7yKz+0lqdhDlTw1tt90wamBoxhiXpvl1XZpJLiHH4RCJ5yDTqH+VlYPv2fwFs89JFw4c1IexYOcQUi4IQ==} cpu: [riscv64] os: [linux] libc: [glibc] '@img/sharp-libvips-linux-s390x@1.3.3': - resolution: {integrity: sha1-vBdFH4DZ8xZjs+kGFJ8Vmg7LHKg=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.3.3.tgz} + resolution: {integrity: sha512-neWLh+3yCNThxnfy3c4BbVBeGgt9aftno+XbT56iK28RgeDs3UOFWviLWlUu0bArYVYJaFDK+RRohbicUNCm8Q==} cpu: [s390x] os: [linux] libc: [glibc] '@img/sharp-libvips-linux-x64@1.3.3': - resolution: {integrity: sha1-x9H4O8HP4iLNnckn88UTeql5HnY=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.3.3.tgz} + resolution: {integrity: sha512-4vKmvAst9nrowcqquKFAyZJUDolUaIp8uRiN0mWFguJ1IplC9/pitXtlnnlU4aa/eJw3J7i67V+pwUL+wZGdsA==} cpu: [x64] os: [linux] libc: [glibc] '@img/sharp-libvips-linuxmusl-arm64@1.3.3': - resolution: {integrity: sha1-MD3+Ko5tH9J56tVZ9NLM/yVF4qI=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.3.3.tgz} + resolution: {integrity: sha512-Y9kQaLMuNoB0bPYOOdcZMaseNrFpPodIWWMrx+CZyydf2xn68j9WYc6sWWRrDwNkzCQjKYfc68L7jKjGlHMibw==} cpu: [arm64] os: [linux] libc: [musl] '@img/sharp-libvips-linuxmusl-x64@1.3.3': - resolution: {integrity: sha1-N1D3CtRq2H5KCO6NNyq5p+F+K2w=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.3.3.tgz} + resolution: {integrity: sha512-fj8Mv0HHfD1Rr+4I68+3agJynxDWtBFgicTbSOb9Bke6pIwzGcJ+RX/yHjmiEGFMCavY/dxvem7MyNaJF+wDiw==} cpu: [x64] os: [linux] libc: [musl] '@img/sharp-linux-arm64@0.35.4': - resolution: {integrity: sha1-wvU7+RP6G0Z2KxksUnorNkeiEag=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.35.4.tgz} + resolution: {integrity: sha512-De4jpEnAU8Hd5oT0j1G3uL4ZvTuipVMn7YC6vPaJhy6/7EwEae0SVAoBrUMYQbkLGDm85taVWwuPc1a44LTzCQ==} engines: {node: '>=20.9.0'} cpu: [arm64] os: [linux] libc: [glibc] '@img/sharp-linux-arm@0.35.4': - resolution: {integrity: sha1-3o2g2i7lUiZ8rncVlzMqhjN45Ds=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@img/sharp-linux-arm/-/sharp-linux-arm-0.35.4.tgz} + resolution: {integrity: sha512-7OAS8gI0EReKGVN2HssHlM6umJgxF5VI3xN0p9FA91p/YO+ou5hiNghLdZ5BEHztwaaK5+bLKRf8x/o2L2nk9A==} engines: {node: '>=20.9.0'} cpu: [arm] os: [linux] libc: [glibc] '@img/sharp-linux-ppc64@0.35.4': - resolution: {integrity: sha1-xA18X4ziFsNSJMWO3O+OZEWTUlY=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.35.4.tgz} + resolution: {integrity: sha512-2oYZJeIl4kCcMGk4ouZVjnkCtFrpQFlNEtJ6GbxzhHQchwH0NH/qEb9ykmOl29dqwMq+JhFdZn+1ak2FKhI9fQ==} engines: {node: '>=20.9.0'} cpu: [ppc64] os: [linux] libc: [glibc] '@img/sharp-linux-riscv64@0.35.4': - resolution: {integrity: sha1-AyyiBucTsRee/g4Y1SUYjGcndzA=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.35.4.tgz} + resolution: {integrity: sha512-cPbNChoRURAWdebDIHSenxRpgEdy7JkPydSnUxRm9VvKD7m0/xVaR/8Fzlu81pk5nHEvHH87UZUA7cTtwnbJSA==} engines: {node: '>=20.9.0'} cpu: [riscv64] os: [linux] libc: [glibc] '@img/sharp-linux-s390x@0.35.4': - resolution: {integrity: sha1-GdrHUBoVyHSLx6ESGfyjkeQkttc=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.35.4.tgz} + resolution: {integrity: sha512-RY0JFY8Fd6RonCBtHz+DvadaPkXDSI1AUn6yWL9TipqkZ1vY8w8evqdgyDFnkm4/K1ve1TvZiaePP5oSd4+WVQ==} engines: {node: '>=20.9.0'} cpu: [s390x] os: [linux] libc: [glibc] '@img/sharp-linux-x64@0.35.4': - resolution: {integrity: sha1-fR1BTUpTjgcEumt2zmVH5g9iEc4=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@img/sharp-linux-x64/-/sharp-linux-x64-0.35.4.tgz} + resolution: {integrity: sha512-9qvvEAuk8k89TfWUoX2htWjbAMX8p+NxCppjpcg5k6xMsjhBQPTsoIh36h9Qde4WRuGpJeYnOjdosDn/cnv+OA==} engines: {node: '>=20.9.0'} cpu: [x64] os: [linux] libc: [glibc] '@img/sharp-linuxmusl-arm64@0.35.4': - resolution: {integrity: sha1-lTTJOAeCL0KC0HmjIvrMbbU9UPY=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.35.4.tgz} + resolution: {integrity: sha512-KB5jxpfWQTr0nc3xdHtWChdbifHrBGsd2SM62Eyxrl8afikm+f5qGBU75SJIZBT/S1MC8XyacdlXBMSWq6OURA==} engines: {node: '>=20.9.0'} cpu: [arm64] os: [linux] libc: [musl] '@img/sharp-linuxmusl-x64@0.35.4': - resolution: {integrity: sha1-9IjnoCkZkb/2Q874K1r9PP1w/PI=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.35.4.tgz} + resolution: {integrity: sha512-f+eZJZIQNEEd26RPSW+76chwOf1XtA2Y/O+5ocVyLliHkeih3e+jhLVBdNTd2rS3IbNXK8+ug93Vf5ZXtF5Lxg==} engines: {node: '>=20.9.0'} cpu: [x64] os: [linux] libc: [musl] '@img/sharp-wasm32@0.35.4': - resolution: {integrity: sha1-gfcfP8DYRH3Dr2yzeOJOdY/1QiU=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@img/sharp-wasm32/-/sharp-wasm32-0.35.4.tgz} + resolution: {integrity: sha512-zQnl4Kwp7Q6NHsENtU2T/00Zi+w3AQNwz3+UaTyVBy2FpXrzXzGjndpK61onhZjRtRpQXxCTeqw19bVyXOh7jA==} engines: {node: '>=20.9.0'} '@img/sharp-webcontainers-wasm32@0.35.4': - resolution: {integrity: sha1-d9LoiS06OCXw3JWrAs62E8shMoY=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@img/sharp-webcontainers-wasm32/-/sharp-webcontainers-wasm32-0.35.4.tgz} + resolution: {integrity: sha512-ESfNkywmCfPNyaZjxooddJQiQ+l/nTpGEOGthxiLnIHXC/CmcBixnfwUleX9mCz9ovrUUvKMap/pm8RYbzfwaA==} engines: {node: '>=20.9.0'} cpu: [wasm32] '@img/sharp-win32-arm64@0.35.4': - resolution: {integrity: sha1-QQG0Tj+5fW8ac8KpxhQtSR0aqDE=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.35.4.tgz} + resolution: {integrity: sha512-iNdlBX9gLVvqe2I3uIJSIKTq6wckP/DYxZtcqxm09x5Gi24DnFBmPAWZmr60ZyYMG0xlzo6goG3670ar+RXvRw==} engines: {node: '>=20.9.0'} cpu: [arm64] os: [win32] '@img/sharp-win32-ia32@0.35.4': - resolution: {integrity: sha1-jUdVvSbV/zT7iceQe9icCApdyfU=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.35.4.tgz} + resolution: {integrity: sha512-kqRsbaa5CS6KHlpxnN7WhE6vAAugXyZButpRdvDWetlv6Qv4N9WTcrWzF7tXfB9T7MsoadqdI8hmwLq6UlLvtw==} engines: {node: ^20.9.0} cpu: [ia32] os: [win32] '@img/sharp-win32-x64@0.35.4': - resolution: {integrity: sha1-C2e9Cx8BEjqYKvzGug3AC4d7igo=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@img/sharp-win32-x64/-/sharp-win32-x64-0.35.4.tgz} + resolution: {integrity: sha512-XtmnYhBcrORsJ4XJngyzr/EWP0hRZLAZRFaApdKuviyqF78+ylxh2y06ZmtULAMOnObJ3ucpN0AcwSWnMowTRg==} engines: {node: '>=20.9.0'} cpu: [x64] os: [win32] '@isaacs/cliui@9.0.0': - resolution: {integrity: sha1-TQo/EnBYBDvy5+4Wnq8w7ZATAvM=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@isaacs/cliui/-/cliui-9.0.0.tgz} + resolution: {integrity: sha512-AokJm4tuBHillT+FpMtxQ60n8ObyXBatq7jD2/JA9dxbDDokKQm8KMht5ibGzLVU9IJDIKK4TPKgMHEYMn3lMg==} engines: {node: '>=18'} '@jridgewell/gen-mapping@0.3.13': - resolution: {integrity: sha1-Y0Khn0Q0dRjJPkOxrGnes8Rlah8=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz} + resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} '@jridgewell/remapping@2.3.5': - resolution: {integrity: sha1-N1xHbRlylHhRuh4Vro8SMEdEWqE=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@jridgewell/remapping/-/remapping-2.3.5.tgz} + resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} '@jridgewell/resolve-uri@3.1.2': - resolution: {integrity: sha1-eg7mAfYPmaIMfHxf8MgDiMEYm9Y=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz} + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} engines: {node: '>=6.0.0'} '@jridgewell/sourcemap-codec@1.5.5': - resolution: {integrity: sha1-aRKwDSxjHA0Vzhp6tXzWV/Ko+Lo=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz} + resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} '@jridgewell/trace-mapping@0.3.31': - resolution: {integrity: sha1-2xXWeByTHzolGj2sOVAcmKYIL9A=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz} + resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} '@kwsites/file-exists@1.1.1': - resolution: {integrity: sha1-rR78rBPhmH2NuvI17zvlsNlvqpk=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@kwsites/file-exists/-/file-exists-1.1.1.tgz} + resolution: {integrity: sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw==} '@kwsites/promise-deferred@1.1.1': - resolution: {integrity: sha1-is5SWSVEJszvV/MXW8ZO1wle2Rk=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@kwsites/promise-deferred/-/promise-deferred-1.1.1.tgz} + resolution: {integrity: sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==} '@lunariajs/core@0.1.1': - resolution: {integrity: sha1-I7UDDMw4v+9pP8kITVAKaZk1uP8=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@lunariajs/core/-/core-0.1.1.tgz} + resolution: {integrity: sha512-sAqM9+DVsLe3xHM9wu2pEnKGYMs/bWS9qpR+CGHol3RihOELnOQTzHddXbdB1MtgesbI8dnQuG64Ocd8KkWsng==} engines: {node: '>=18.17.0'} hasBin: true '@lunariajs/starlight@0.1.1': - resolution: {integrity: sha1-36Tb4V6MWHvyzDtLSdRDH6OfIVw=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@lunariajs/starlight/-/starlight-0.1.1.tgz} + resolution: {integrity: sha512-tpkqv8TCGUvz0z5nVk1ACb/2bT3seqDx+CHimNQugcpAFSip9BqDPOiWqaCujzZFajfR/L4mUsPAnavnnE8KVw==} engines: {node: '>=18.17.0'} peerDependencies: '@astrojs/starlight': '>=0.14.0' astro: '>=4.0.0' '@mdx-js/mdx@3.1.1': - resolution: {integrity: sha1-xf/ZkadTaxSeFxde7lehoqURxtE=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@mdx-js/mdx/-/mdx-3.1.1.tgz} + resolution: {integrity: sha512-f6ZO2ifpwAQIpzGWaBQT2TXxPv6z3RBzQKpVftEWN78Vl/YweF1uwussDx8ECAXVtr3Rs89fKyG9YlzUs9DyGQ==} '@mermaid-js/parser@1.2.0': - resolution: {integrity: sha1-Jm1yjFTS1ANNJw+LMdeQ4mKWpfo=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@mermaid-js/parser/-/parser-1.2.0.tgz} + resolution: {integrity: sha512-oYPyv8A4As1yH5Bx+04iQEQxXuIQDe0GKCNSRgao6z8AM9jixXIfP0vsppRLvGf+nKIOb9/LdpWA4YuJiVvESA==} '@napi-rs/wasm-runtime@1.1.6': - resolution: {integrity: sha1-7TOAbQ+b6Y3HbQw9T9hy/acBtdU=, tarball: https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.6.tgz} + resolution: {integrity: sha512-ZLv/JdUfkvOy9eCnnBaGfiO+XimbjebAeO+MRQqD/B+FR1tnRN0tpKSJHRbE8sFfS6aqsXZ67TQjfwfsxULVbg==} peerDependencies: '@emnapi/core': ^1.7.1 '@emnapi/runtime': ^1.7.1 - '@napi-rs/wasm-runtime@1.2.3': - resolution: {integrity: sha1-l+PUXXQk3F2h1OMvO/OykvbBtEw=, tarball: https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@napi-rs/wasm-runtime/-/wasm-runtime-1.2.3.tgz} - engines: {node: ^20.19.0 || ^22.13.0 || >=23.5.0} - peerDependencies: - '@emnapi/core': ^1.7.1 || ^2.0.0-alpha.4 - '@emnapi/runtime': ^1.7.1 || ^2.0.0-alpha.4 - '@nodable/entities@3.0.0': - resolution: {integrity: sha1-aUcDvIZNMOrtVcLj3vANvWFJNnA=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@nodable/entities/-/entities-3.0.0.tgz} + resolution: {integrity: sha512-8L9xFeTYKhm49xfIypoe2W5wV1m/3Z58kT+7kR9A8OyFxcPduI4VmxaUMQyKYrRjUoLLSXv6EKKID5Tvj9cUVw==} '@nodelib/fs.scandir@2.1.5': - resolution: {integrity: sha1-dhnC6yGyVIP20WdUi0z9WnSIw9U=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz} + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} '@nodelib/fs.stat@2.0.5': - resolution: {integrity: sha1-W9Jir5Tp0lvR5xsF3u1Eh2oiLos=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz} + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} engines: {node: '>= 8'} '@nodelib/fs.walk@1.2.8': - resolution: {integrity: sha1-6Vc36LtnRt3t9pxVaVNJTxlv5po=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz} + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} '@oslojs/encoding@1.1.0': - resolution: {integrity: sha1-VfPZpZdDCgHype9jxrQvdp+c404=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@oslojs/encoding/-/encoding-1.1.0.tgz} + resolution: {integrity: sha512-70wQhgYmndg4GCPxPPxPGevRKqTIJ2Nh4OkiMWmDAVYsTQ+Ta7Sq+rPevXyXGdzr30/qZBnyOalCszoMxlyldQ==} '@oxc-parser/binding-android-arm-eabi@0.131.0': - resolution: {integrity: sha1-//WqeZxQShj46aSIiV+NYibLoXo=, tarball: https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@oxc-parser/binding-android-arm-eabi/-/binding-android-arm-eabi-0.131.0.tgz} + resolution: {integrity: sha512-t2xicr9pfzkSRYx5aPqZqlLaayIwJTqgQ81Jor31Xep2nGyL2Aq3d0K5wOfeR7VevaSdxaS9dzSQP9xDwn8fDg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [android] '@oxc-parser/binding-android-arm64@0.131.0': - resolution: {integrity: sha1-TBlMZHlO9cdTGjJtqW5xvSTCRy0=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@oxc-parser/binding-android-arm64/-/binding-android-arm64-0.131.0.tgz} + resolution: {integrity: sha512-nlGIod6gw75x1aEDgLS+srj+JRGY0HHm9MI9YgzE/B64l6d6+H3MSP9NOgp0+HTg8tp4vV9rVfgQGgd+TfVZcA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [android] '@oxc-parser/binding-darwin-arm64@0.131.0': - resolution: {integrity: sha1-dGt1+nUmUerdSmKKUQ9VVa8nIYU=, tarball: https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@oxc-parser/binding-darwin-arm64/-/binding-darwin-arm64-0.131.0.tgz} + resolution: {integrity: sha512-jukuV6xe5RbQKFo7QD34NDCLDZp4PSOm8rmckhNdH/60ymG5zXbDzGBEyc+nTkuLQNama2aSGCt+CPfpjNTqyw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] '@oxc-parser/binding-darwin-x64@0.131.0': - resolution: {integrity: sha1-V8zB9Xzr1BJlclSW40XAlDrasP0=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@oxc-parser/binding-darwin-x64/-/binding-darwin-x64-0.131.0.tgz} + resolution: {integrity: sha512-g3JOo4khe9rslHm5WYaVDWb0HS/M1MLR3I9S8560MkKIcC96VQY00QjOlsuRyfSj/JDXj8i9T7ryPO2RidiXVg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] '@oxc-parser/binding-freebsd-x64@0.131.0': - resolution: {integrity: sha1-fbXyJJs8L+nEzoAmt6oB7AaeHDY=, tarball: https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@oxc-parser/binding-freebsd-x64/-/binding-freebsd-x64-0.131.0.tgz} + resolution: {integrity: sha512-1hziITDTxjMePnX+dR9ocVT+EuZkQ8wm4FPAbmbEiKG+Phbo73J1ZnPAA6Y/aGsWF3McOFnQuZIktAFwalkfJQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] '@oxc-parser/binding-linux-arm-gnueabihf@0.131.0': - resolution: {integrity: sha1-0QB+17z4k/Xt78gCBZENenw2++g=, tarball: https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@oxc-parser/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-0.131.0.tgz} + resolution: {integrity: sha512-9uRxfXwyKG9+MwmGQBo2ncPNwZH5HTmCETFM2WiuDBNDCW4NC5ttSQkwCAMrTAWgwMzVBH1CP8pM0v7nebCWXQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] '@oxc-parser/binding-linux-arm-musleabihf@0.131.0': - resolution: {integrity: sha1-SCh6udNKxjiwVvFwa/McFzIS/3s=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@oxc-parser/binding-linux-arm-musleabihf/-/binding-linux-arm-musleabihf-0.131.0.tgz} + resolution: {integrity: sha512-mgbLvzRShXOLBdWGInf08Af4q+pfj1xD8hSgLClDZ9of/BXkB6+LIhTH7fihiDUipqB3yoSkKBWaZ3Ejlf5Yag==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] '@oxc-parser/binding-linux-arm64-gnu@0.131.0': - resolution: {integrity: sha1-r/gC/PH0sCimt/8B3rZhW3TKwcM=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@oxc-parser/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-0.131.0.tgz} + resolution: {integrity: sha512-OPT8++4aN6j2GJ8+3IZHS/byXoZP4aSBn+FoG6rgBJ2fKwPKXWF3MqrFMNW7NKHM28FLY579xYLxJSfgobEqPA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [glibc] '@oxc-parser/binding-linux-arm64-musl@0.131.0': - resolution: {integrity: sha1-jTKJTGJBqlicw5jOItsq2stl4G4=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@oxc-parser/binding-linux-arm64-musl/-/binding-linux-arm64-musl-0.131.0.tgz} + resolution: {integrity: sha512-vtPiwmfVTAXzaxDKsOXG+LwgRAA7WEnaeHzhS5z0GE89gAK18KSXnly7Z6saXXq6L3dVMyK44uoTI03zKxrpmw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [musl] '@oxc-parser/binding-linux-ppc64-gnu@0.131.0': - resolution: {integrity: sha1-OO9E6Na10D5Dquea7sr1XKBPmrg=, tarball: https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@oxc-parser/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-0.131.0.tgz} + resolution: {integrity: sha512-8AW8L7w5cGHSdZPcyZX2yR0+GUODsT15rbRjfdD54rv6DMbtuEB19ysLOpKJlRGfH6UNYNpCHaU1uJWgTWf1/w==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ppc64] os: [linux] libc: [glibc] '@oxc-parser/binding-linux-riscv64-gnu@0.131.0': - resolution: {integrity: sha1-FZ8pCk0Fqows4heSAowFDA7dFV0=, tarball: https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@oxc-parser/binding-linux-riscv64-gnu/-/binding-linux-riscv64-gnu-0.131.0.tgz} + resolution: {integrity: sha512-vvpjkjEOUsPcsYf8evE4MO3aGx9+3wodXEBOicGNnOwTuAik8eBONNkgSdhkGsAblQmfVHJyanRnpxglddTXIA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [riscv64] os: [linux] libc: [glibc] '@oxc-parser/binding-linux-riscv64-musl@0.131.0': - resolution: {integrity: sha1-oUYT8l1Jfpo56PW6C9cjbVn7NmQ=, tarball: https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@oxc-parser/binding-linux-riscv64-musl/-/binding-linux-riscv64-musl-0.131.0.tgz} + resolution: {integrity: sha512-AqmcNC3fClXX+fxQ6VGEN1667xVFiRBkY0CZmDMSiaeFUsv1+UkBPYYi48IUKcA9/ivvoKNRzQl2I4//kT9F/w==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [riscv64] os: [linux] libc: [musl] '@oxc-parser/binding-linux-s390x-gnu@0.131.0': - resolution: {integrity: sha1-eTnIzbVv1C6oy9qZf4vI9X9vJf4=, tarball: https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@oxc-parser/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-0.131.0.tgz} + resolution: {integrity: sha512-7d3jOMKy7RSQCcDLIci+ySll2FgsOMl/GiRux4q2JNv0zg4EdhFISa9idvrdN/HEUIQQJNg6dmveUeJl2YErGA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [s390x] os: [linux] libc: [glibc] '@oxc-parser/binding-linux-x64-gnu@0.131.0': - resolution: {integrity: sha1-gF8Dd8HwASfhAcp4OPeq9yUwFCw=, tarball: https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@oxc-parser/binding-linux-x64-gnu/-/binding-linux-x64-gnu-0.131.0.tgz} + resolution: {integrity: sha512-JHK/h95qVqVQ+ITER837kcTdwBDFpFaNnOTYGCP0zdUSX/mLKC7tXOoyrTb6vG7iRPwGlcgBil3v2IjYw1FqJA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [glibc] '@oxc-parser/binding-linux-x64-musl@0.131.0': - resolution: {integrity: sha1-hQhWQ1EoXJNJeXSYqeGuQUOuSIw=, tarball: https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@oxc-parser/binding-linux-x64-musl/-/binding-linux-x64-musl-0.131.0.tgz} + resolution: {integrity: sha512-b2BO82O8azXAyf7EUgOPKu145nWypbNyk07HbU09fkzhm9lEA5oPvaN/M8Nlo7tOErVTa2WOgS4QbOnxAPXdDQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [musl] '@oxc-parser/binding-openharmony-arm64@0.131.0': - resolution: {integrity: sha1-TP7pKhqq7MgUbjbKcHfjP0/+y14=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@oxc-parser/binding-openharmony-arm64/-/binding-openharmony-arm64-0.131.0.tgz} + resolution: {integrity: sha512-GHO9glZaX7LkX/OGfluEPf1yjg+ehiFbUdowbX6uNWOQhmwKWU4m4+nZ9FJkrHNKuxyI1KKertMdGjVKCApKWA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [openharmony] '@oxc-parser/binding-wasm32-wasi@0.131.0': - resolution: {integrity: sha1-YCbnqpj7QgRCGEWNaQjnhw4oqHM=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@oxc-parser/binding-wasm32-wasi/-/binding-wasm32-wasi-0.131.0.tgz} + resolution: {integrity: sha512-3SkikPaEFoih1N83qLVEDLRLeY4nYsf6JT9SnWiMCQ5lGQdKup6bEuKCqkRiG9dD1IIaFeYz9RjlciPmYoFIWA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [wasm32] '@oxc-parser/binding-win32-arm64-msvc@0.131.0': - resolution: {integrity: sha1-5V8rXSPEwMa32RFRhlbxXiLIvN0=, tarball: https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@oxc-parser/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-0.131.0.tgz} + resolution: {integrity: sha512-Os5bEhryeA2jkH+ZrnZyAC1EP5gs+X4YB1Fjqml7UPD5kU7ecsK1MPEVMfCrdt/GDNpDbavYXiOXOdyJ5b3OPw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [win32] '@oxc-parser/binding-win32-ia32-msvc@0.131.0': - resolution: {integrity: sha1-zzCeGr8GdqzGyS69yOkOccnYddo=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@oxc-parser/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-0.131.0.tgz} + resolution: {integrity: sha512-m+jNz9EuF0NXoiptc6B9h5yompZQVW/a5MJeOu5zojfH5yWk82tvF2ccrHkfhgtrS9h9DD5l1Qv8dWlfY7Nz8g==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ia32] os: [win32] '@oxc-parser/binding-win32-x64-msvc@0.131.0': - resolution: {integrity: sha1-r0Nb0/YLCnWgesZ8fJ6bdJB3RuA=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@oxc-parser/binding-win32-x64-msvc/-/binding-win32-x64-msvc-0.131.0.tgz} + resolution: {integrity: sha512-o14Hk8dAyiEUMFEWEgmAwFZvBt1RzAYLM3xeQ+5315JXgVYhoemivgYcbYVRbsFkS71ShMGlAFE0kPnr460rww==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [win32] '@oxc-project/types@0.131.0': - resolution: {integrity: sha1-vpEu/SIaYA/cD34SfvEki5t76wo=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@oxc-project/types/-/types-0.131.0.tgz} + resolution: {integrity: sha512-PgnWDfV0h+b16XNKbXU7Daib/BFSt/J2mEzfYIBu6JB/wNdlU+kVYXCkGA1A9fWkTbOgbjh4e6NhPeQOYvFhEA==} '@oxc-project/types@0.139.0': - resolution: {integrity: sha1-ONdrnb+TTCoCvhdPsyzuvxgv50I=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@oxc-project/types/-/types-0.139.0.tgz} + resolution: {integrity: sha512-r9gHphtCs+1M7J0pw6Sn/hh/Wpa/iQrOOkrNAlVLF/gHq+/CJmHIWKKUUhdWjcD6CIa8idarspCsASiXCXvFUw==} '@pagefind/darwin-arm64@1.5.2': - resolution: {integrity: sha1-llFS/8IrzNgpngZffPvGhpob/+A=, tarball: https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@pagefind/darwin-arm64/-/darwin-arm64-1.5.2.tgz} + resolution: {integrity: sha512-MXpI+7HsAdPkvJ0gk9xj9g541BCqBZOBbdwj9g6lB5LCj6kSV6nqDSjzcAJwvOsfu0fjwvC8hQU+ecfhp+MpiQ==} cpu: [arm64] os: [darwin] '@pagefind/darwin-x64@1.5.2': - resolution: {integrity: sha1-tbm0dnPK97KAiRFU4qR1q8SZ+t0=, tarball: https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@pagefind/darwin-x64/-/darwin-x64-1.5.2.tgz} + resolution: {integrity: sha512-IojxFWMEJe0RQ7PQ3KXQsPIImNsbpPYpoZ+QUDrL8fAl/O27IX+LVLs74/UzEZy5uA2LD8Nz1AiwKr72vrkZQw==} cpu: [x64] os: [darwin] '@pagefind/default-ui@1.5.2': - resolution: {integrity: sha1-ZHPNLDSpS4IhxTNKX+8xTNSETDc=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@pagefind/default-ui/-/default-ui-1.5.2.tgz} + resolution: {integrity: sha512-pm1LMnQg8N2B3n2TnjKlhaFihpz6zTiA4HiGQ6/slKO/+8K9CAU5kcjdSSPgpuk1PMuuN4hxLipUIifnrkl3Sg==} '@pagefind/freebsd-x64@1.5.2': - resolution: {integrity: sha1-z24nnZOMI2hzG7ZVi/j2agyAomk=, tarball: https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@pagefind/freebsd-x64/-/freebsd-x64-1.5.2.tgz} + resolution: {integrity: sha512-7EVzo9+0w+2cbe671BtMj10UlNo83I+HrLVLfRxO731svHRJKUfJ/mo05gU14pe9PCfpKNQT8FS3Xc/oDN6pOA==} cpu: [x64] os: [freebsd] '@pagefind/linux-arm64@1.5.2': - resolution: {integrity: sha1-iyLPwaNMWQM8W9Zmdreobvug9fQ=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@pagefind/linux-arm64/-/linux-arm64-1.5.2.tgz} + resolution: {integrity: sha512-Ovt9+K35sqzn8H3ZMXGwls4TD/wMJuvRtShHIsmUQREmaxjrDEX7gHckRCrwYJ4XE1H1p6HkLz3wukrAnsfXQw==} cpu: [arm64] os: [linux] '@pagefind/linux-x64@1.5.2': - resolution: {integrity: sha1-pzPRwKnZBTEfafiGh3HAzEKQn+Q=, tarball: https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@pagefind/linux-x64/-/linux-x64-1.5.2.tgz} + resolution: {integrity: sha512-V+tFqHKXhQKq/WqPBD67AFy7scn1/aZID00ws4fSDd+1daSi5UHR9VVlRrOUYKxn3VuFQYRD7lYXdZK1WED1YA==} cpu: [x64] os: [linux] '@pagefind/windows-arm64@1.5.2': - resolution: {integrity: sha1-bWyzlaVhNqkrkcC9hm9/7DsLvnw=, tarball: https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@pagefind/windows-arm64/-/windows-arm64-1.5.2.tgz} + resolution: {integrity: sha512-hN9Nh90fNW61nNRCW9ZyQrAj/mD0eRvmJ8NlTUzkbuW8kIzGJUi3cxjFkEcMZ5h/8FsKWD/VcouZl4yo1F7B6g==} cpu: [arm64] os: [win32] '@pagefind/windows-x64@1.5.2': - resolution: {integrity: sha1-kx/byfAPcgV5UM0mDvll1P0CqS4=, tarball: https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@pagefind/windows-x64/-/windows-x64-1.5.2.tgz} + resolution: {integrity: sha512-Fa2Iyw7kaDRzGMfNYNUXNW2zbL5FQVDgSOcbDHdzBrDEdpqOqg8TcZ68F22ol6NJ9IGzvUdmeyZypLW5dyhqsg==} cpu: [x64] os: [win32] '@parse5/tools@0.7.0': - resolution: {integrity: sha1-W0NIItIlvKOk7AvKux4UDsQ6GE4=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@parse5/tools/-/tools-0.7.0.tgz} + resolution: {integrity: sha512-JDvrGhc8kYBq7/SM4obJkpgwWo6pRjF/fo9CCaiJyVOkDf203Ciq2UF6TjzCFXKs7Q/zS2sS4deyBx0XzRvh9Q==} peerDependencies: parse5: 7.x || 8.x '@playwright/test@1.61.1': - resolution: {integrity: sha1-SFaNwir3gZ5V+l6OO8ebfmo+ZnU=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@playwright/test/-/test-1.61.1.tgz} + resolution: {integrity: sha512-8nKv6+0RJSL9FE4jYOEGXnPeM/Hg12qZpmqzZjRh3qM0Y7c3z1mrOTfFLids72RDQYVh9WpLEfR5WdpNX4fkig==} engines: {node: '>=18'} hasBin: true '@polka/url@1.0.0-next.29': - resolution: {integrity: sha1-WkAQmhq1+E1v2PySixnzZ8vn57E=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@polka/url/-/url-1.0.0-next.29.tgz} + resolution: {integrity: sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==} '@popperjs/core@2.11.8': - resolution: {integrity: sha1-a3kDLnYKCJnNQgRxC+7elyo6GF8=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@popperjs/core/-/core-2.11.8.tgz} + resolution: {integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==} '@quansync/fs@1.0.0': - resolution: {integrity: sha1-FxMbHxwmH8+2OJMnLEiN+Jxz9I8=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@quansync/fs/-/fs-1.0.0.tgz} + resolution: {integrity: sha512-4TJ3DFtlf1L5LDMaM6CanJ/0lckGNtJcMjQ1NAV6zDmA0tEHKZtxNKin8EgPaVX1YzljbxckyT2tJrpQKAtngQ==} '@rolldown/binding-android-arm64@1.1.5': - resolution: {integrity: sha1-9Yy5oKgSjtBYIoJyBShUf8XANfM=, tarball: https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@rolldown/binding-android-arm64/-/binding-android-arm64-1.1.5.tgz} + resolution: {integrity: sha512-lZg8fqIv2v7FF237bwMgzGZEJvGL79/s5knJ/i6FmsGF4XXlzccZ4jb+TrFIxtSSxFtIpdsgrPZeMk1I9AFcyQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [android] '@rolldown/binding-darwin-arm64@1.1.5': - resolution: {integrity: sha1-RBFEwFpKgxqnUmmrw6SjJDdOpwc=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.1.5.tgz} + resolution: {integrity: sha512-51Bnx9pNiMRKSUNtBfySkNJ9vMU9Hh3I1ozDd6gyPPYzaXCfnptUcEZxXGYFn+ul2dtcMUiqGR1Yai2K10uoTw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] '@rolldown/binding-darwin-x64@1.1.5': - resolution: {integrity: sha1-yC4wZSzvUsSvkl1cZsiVWkAxmBY=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.1.5.tgz} + resolution: {integrity: sha512-Tm+gbfC0aHu1tBA/JvKQh32S0K6YgCHkiAF4/W6xX0K0RmNuc94VeK419dJoE65R5aRxmo+noZQSWrAMF6yb6g==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] '@rolldown/binding-freebsd-x64@1.1.5': - resolution: {integrity: sha1-wy6c5/ocD7K4CROio6BcPpB9BrA=, tarball: https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.1.5.tgz} + resolution: {integrity: sha512-JMzDKCCXq93YccG5gz3hvOs1oXRKAf0XYpfOS88e+wZrC8Iugj6j68867vrYZkvpDDpKn/KoKORThmchMpF6TA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] '@rolldown/binding-linux-arm-gnueabihf@1.1.5': - resolution: {integrity: sha1-zpC14iMWretQLqAQWC9JjNBgTyc=, tarball: https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.1.5.tgz} + resolution: {integrity: sha512-uML21j2K5TfPGutKxub+M+nLjZIrWjXQ5Grx4lCe/nimTj9B4L63zHpjXLl4y0L3mcm2htEQIb06oCG/szerNw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] '@rolldown/binding-linux-arm64-gnu@1.1.5': - resolution: {integrity: sha1-kZRxEMTdqk7vsATlJogHCXcIUgE=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.1.5.tgz} + resolution: {integrity: sha512-navSiuTMogvnQoZoM/v+l3ZWo50/NTwSHSzheABx/RCnmUPaKwq9qSo4Br2OYRs21+Fz8uFqITZM3H4opOB0/Q==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [glibc] '@rolldown/binding-linux-arm64-musl@1.1.5': - resolution: {integrity: sha1-6zKy1BCMHHArkejN6KBD6uXKqU0=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.1.5.tgz} + resolution: {integrity: sha512-lAryqH7IteztmCXQXk0etKj4wBQ7Gx5S6LjKhsgp9zb8I5bsuvU/2llH1hDQcjsFeqIsovMVN339/8pUDDBXxA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [musl] '@rolldown/binding-linux-ppc64-gnu@1.1.5': - resolution: {integrity: sha1-zLlDwR5acmVcuwL8EWNUHOtkB4I=, tarball: https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.1.5.tgz} + resolution: {integrity: sha512-fsK/sNBnxzBlL4O1JNrZakVQxPspqpED5dLtNsZS9oOKmtSpdNIzxH2kkol5HYTWJN47sE20ztMJPxfZ89qGOg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ppc64] os: [linux] libc: [glibc] '@rolldown/binding-linux-s390x-gnu@1.1.5': - resolution: {integrity: sha1-ozcx7lZ+kLdfrG5eVTB+iiswOPA=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.1.5.tgz} + resolution: {integrity: sha512-gLYb4BIadlfTOYT5gO503n8zQjXflgzpD0FcyKh0Mzx3rqCZKnHoJWV9xe1KXUJ5lx2JfcSHr/mhzS0PC/McAA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [s390x] os: [linux] libc: [glibc] '@rolldown/binding-linux-x64-gnu@1.1.5': - resolution: {integrity: sha1-p0wBqqzt/BHDm2/rozpfoMZUlJ8=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.1.5.tgz} + resolution: {integrity: sha512-FjcpEKUyJygHgs1o50VYNvkt5+7Le/VEdYt0AkRpkL33MnyQfwr8l5mXwMmfmTbyMPr5vJLC+8/Gd9gXnwU1QQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [glibc] '@rolldown/binding-linux-x64-musl@1.1.5': - resolution: {integrity: sha1-KM0XhJT6HmXbpBIim1zlXE3Vy9E=, tarball: https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.1.5.tgz} + resolution: {integrity: sha512-Me+PfPI2TMeOQk0gYWfLQZtTktrmzbr8cDboqX83XKc7UrgAi55gF+2dUkWdxd19n55Essp2yeca+O9N5rBxHg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [musl] '@rolldown/binding-openharmony-arm64@1.1.5': - resolution: {integrity: sha1-98dfqRP8IIhNJqfUiNT1xZfNccA=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.1.5.tgz} + resolution: {integrity: sha512-yc5WrLzXks6zCQfn9Oxr8pORKyl/pF+QjHmW/Qx3qu0oyrrNC+y2JLTU1E2rcWYAmzlnqngWXHQjy51VzW70Vw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [openharmony] '@rolldown/binding-wasm32-wasi@1.1.5': - resolution: {integrity: sha1-w3lYGUd4cIHfNj6hBhQPzV/sJS0=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.1.5.tgz} + resolution: {integrity: sha512-VbQGPX2b4r48TAMIM2cjgluIM1HYutm4pcTEJsle7iEP7sB1dFqtPLBVbdLAZCxy1txCcPxf4QFf4v8uvltPqA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [wasm32] '@rolldown/binding-win32-arm64-msvc@1.1.5': - resolution: {integrity: sha1-8jyIaU96cpoS85UCSu4434Cha6M=, tarball: https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.1.5.tgz} + resolution: {integrity: sha512-gHv82k63z4qpV5+Q1y/12KrK0ltWBukVDI8nZcbT7Tt/ZlOIVwppazneq0F93oDxTo3IgAMEDIoQh3E2n6mVsw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [win32] '@rolldown/binding-win32-x64-msvc@1.1.5': - resolution: {integrity: sha1-M3fI3g5WqIV/ESF1YRRwkOh0y0Y=, tarball: https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.1.5.tgz} + resolution: {integrity: sha512-tTZuDBPw85tEN5PQi1pnEBzDy0Z49HtScLAbD5t6hyeU92A95pRWaSMw1GZZi/RwgSgUIl0xrSlXIT/9QzvYSA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [win32] '@rolldown/pluginutils@1.0.1': - resolution: {integrity: sha1-4/zuCT+7XOdl4a0Ij/TeKIn2+b4=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@rolldown/pluginutils/-/pluginutils-1.0.1.tgz} + resolution: {integrity: sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==} '@shikijs/core@4.3.1': - resolution: {integrity: sha1-0eS2f3R9VHF3UZ73aLBjbJfO3V0=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@shikijs/core/-/core-4.3.1.tgz} + resolution: {integrity: sha512-ANMDxuaPsNMdDC1m4vfvhlDmJweMwkE5XitTwrq2rWHx5jM+dlm4MmHt2PP6t0uejfR77SuhrhJ0zEijIF/uhA==} engines: {node: '>=20'} '@shikijs/core@4.4.2': - resolution: {integrity: sha1-NiK5E3pqdptUj2eKASKuk833XhU=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@shikijs/core/-/core-4.4.2.tgz} + resolution: {integrity: sha512-StyzbAyxg2/tBGf78gwbBkGyeQ73lf8UiJArFaQhTQIDqQOCKPCQFanvrs4/Yv3Yfyc+ONInJM6K+FMIf+P+kA==} engines: {node: '>=20'} '@shikijs/engine-javascript@4.3.1': - resolution: {integrity: sha1-ToY9sQazYVFIo628yxBFtonPyrA=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@shikijs/engine-javascript/-/engine-javascript-4.3.1.tgz} + resolution: {integrity: sha512-JBItcnPuYq7jVJdZo/vMj94r+szT7XEjHFX+mvFDGSEIbVAXAGyHAHzhbWzpGOwYidCZrErJLLgn2PVeiokHnQ==} engines: {node: '>=20'} '@shikijs/engine-javascript@4.4.2': - resolution: {integrity: sha1-Mwa1y81g/T6NglHq/fARGXk6qDQ=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@shikijs/engine-javascript/-/engine-javascript-4.4.2.tgz} + resolution: {integrity: sha512-MnIkeqWdVPUWsxlx8gKLVCJFTsqrQJgpTPBPpQwaFeJ56lOnJxj5aN2LUFnfxUEcvOQuNocmbaMnVrCEln6rkw==} engines: {node: '>=20'} '@shikijs/engine-oniguruma@4.3.1': - resolution: {integrity: sha1-z9XD+a21g1VFFV/f3AU9nR5cVWU=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@shikijs/engine-oniguruma/-/engine-oniguruma-4.3.1.tgz} + resolution: {integrity: sha512-OXyNMzg0pews+msMj4cHeqT4xiYKKvbnn6VbdAXxfoFl3SSx4fJTc8FadECuc5/H9p3BzhNAoAUXKwAu9rWYhg==} engines: {node: '>=20'} '@shikijs/engine-oniguruma@4.4.2': - resolution: {integrity: sha1-P3q4UNcfh47fZ4UQ9/oHFKv4WNA=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@shikijs/engine-oniguruma/-/engine-oniguruma-4.4.2.tgz} + resolution: {integrity: sha512-GLhowz1+jixjz+wiZ3wMnOn1jTxiFCGl2PkXufivbnwPHKuyw1AYqu5/hbWhZZ2oAb0NP05WUJhYeigY14drnw==} engines: {node: '>=20'} '@shikijs/langs@4.3.1': - resolution: {integrity: sha1-mR6zILljDB/LXLVh7HsisCzbXoU=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@shikijs/langs/-/langs-4.3.1.tgz} + resolution: {integrity: sha512-m0l9nsDqgBHvbZbk7A0/kXz/impK3uB/c6rAn6Gpg/uPtdZRQ+alsN/17MU5thb68XTj/4DxkZAotrM0GGSpDQ==} engines: {node: '>=20'} '@shikijs/langs@4.4.2': - resolution: {integrity: sha1-hiRUdsECeq2yFFNVgoPrm3BXqCM=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@shikijs/langs/-/langs-4.4.2.tgz} + resolution: {integrity: sha512-8DfeusD+Zdv/eYIDdXyJTUnSMHt+aAWjAOCXV20HNGAHRlInXpG8wh421v6B91WOm9TFwRLN+b/LG5F2NAIojg==} engines: {node: '>=20'} '@shikijs/primitive@4.3.1': - resolution: {integrity: sha1-vy3lVZLcVeA27+mEvHXEV4BSGC0=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@shikijs/primitive/-/primitive-4.3.1.tgz} + resolution: {integrity: sha512-CXQRQOYy1leqQ8ceTeJdmXv/bsUY++6QyLpXJ94LZAAYj5X2SKRdc5ipguv4NPyGVKItB2PPwUpRNe0Sjh5S1A==} engines: {node: '>=20'} '@shikijs/primitive@4.4.2': - resolution: {integrity: sha1-UbHyWtYEGwpXqiOJ5uD/U9wJVOg=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@shikijs/primitive/-/primitive-4.4.2.tgz} + resolution: {integrity: sha512-l6fQQKsOMlz72n38fztmSgZ76MO6KSWuw8o+GJ+FhmqrpC9pIOJNQNXGgbb5yX2AwpzlEHwsaLPnk/8o4Fm+rA==} engines: {node: '>=20'} '@shikijs/themes@4.3.1': - resolution: {integrity: sha1-rpb23pocvckvbTUxYoENoDTwXlo=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@shikijs/themes/-/themes-4.3.1.tgz} + resolution: {integrity: sha512-dgpoJ4WqNi2yTmizQHBJ5zcX6j2lE6icN/0yt4l1kkf16jrY/pwPLoTb1ETsWMz0OBLf9ZNvwmxft+cH+N9qSA==} engines: {node: '>=20'} '@shikijs/themes@4.4.2': - resolution: {integrity: sha1-el0zhPXN66KLmCeg8jpdJ5t/vnI=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@shikijs/themes/-/themes-4.4.2.tgz} + resolution: {integrity: sha512-H0CFoL07ddDC2Dd6EdrPYNkRhUR6YCkJlnuYFceYYUJJA5TIm2b5B33qqiDYryBExgbKMndFJPb2u1gTuqO37g==} engines: {node: '>=20'} '@shikijs/types@4.3.1': - resolution: {integrity: sha1-V9lQox9fSJtEeU+muaW17lB+C8M=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@shikijs/types/-/types-4.3.1.tgz} + resolution: {integrity: sha512-CHFxE0jztBIZRHH6gxXE7DXUCFXjReEGxZ/j0rfSLGKZuwp2xBYycEP14875DSa9KLL/6700oxIq6oO6ef9K2g==} engines: {node: '>=20'} '@shikijs/types@4.4.2': - resolution: {integrity: sha1-1PqbOj4xiOl8pdBbjwtXRdzX7kc=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@shikijs/types/-/types-4.4.2.tgz} + resolution: {integrity: sha512-PFYitV4vpDr/iPCIhnHp+Q4ftic5N5VeNJ3KQ1O8gn3h2ar8qgwMAXF7tq4m1CWaMS60fV4VqF6vfnWH4F7vqQ==} engines: {node: '>=20'} '@shikijs/vscode-textmate@10.0.2': - resolution: {integrity: sha1-qQqzHQzB37VMZqaeUVv2JPp7IiQ=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@shikijs/vscode-textmate/-/vscode-textmate-10.0.2.tgz} + resolution: {integrity: sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==} '@shuding/opentype.js@1.4.0-beta.0': - resolution: {integrity: sha1-XR5+ngVvVGqtQd8cUEP4+F054ks=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@shuding/opentype.js/-/opentype.js-1.4.0-beta.0.tgz} + resolution: {integrity: sha512-3NgmNyH3l/Hv6EvsWJbsvpcpUba6R8IREQ83nH83cyakCw7uM1arZKNfHwv1Wz6jgqrF/j4x5ELvR6PnK9nTcA==} engines: {node: '>= 8.0.0'} hasBin: true '@simple-git/args-pathspec@1.0.3': - resolution: {integrity: sha1-nvSirV9Jq0BWNi0D+T93W5MRjKU=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@simple-git/args-pathspec/-/args-pathspec-1.0.3.tgz} + resolution: {integrity: sha512-ngJMaHlsWDTfjyq9F3VIQ8b7NXbBLq5j9i5bJ6XLYtD6qlDXT7fdKY2KscWWUF8t18xx052Y/PUO1K1TRc9yKA==} '@simple-git/argv-parser@1.1.1': - resolution: {integrity: sha1-J1uDnG7rUDCHLHOx6oOaQWiF2p0=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@simple-git/argv-parser/-/argv-parser-1.1.1.tgz} + resolution: {integrity: sha512-Q9lBcfQ+VQCpQqGJFHe5yooOS5hGdLFFbJ5R+R5aDsnkPCahtn1hSkMcORX65J2Z5lxSkD0lQorMsncuBQxYUw==} '@solid-primitives/refs@1.1.4': - resolution: {integrity: sha1-2K71WlHVFBUntq0VH3yYogfTtkQ=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@solid-primitives/refs/-/refs-1.1.4.tgz} + resolution: {integrity: sha512-bLjwIs6ZPu8NQnuw04sU3Zc8qKSpbc0umUU/O4SHf6oWOdO4+dHY8vb1T7C4b/Tg103+9WGr6sEE0+NFlbaB/A==} peerDependencies: solid-js: ^1.6.12 '@solid-primitives/transition-group@1.1.2': - resolution: {integrity: sha1-vprwWHGnymMjJ3+XgvSusgy39z8=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@solid-primitives/transition-group/-/transition-group-1.1.2.tgz} + resolution: {integrity: sha512-gnHS0OmcdjeoHN9n7Khu8KNrOlRc8a2weETDt2YT6o1zeW/XtUC6Db3Q9pkMU/9cCKdEmN4b0a/41MKAHRhzWA==} peerDependencies: solid-js: ^1.6.12 '@solid-primitives/utils@6.4.1': - resolution: {integrity: sha1-qqkAasnfp7mbEGCreGaahyOrKWI=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@solid-primitives/utils/-/utils-6.4.1.tgz} + resolution: {integrity: sha512-ISSB5QX1qP2ynrheIpYwc4oKR5Ny4siNuUyf1qZniy+Il+p/PtDB0QK1Dnle8noiHpwRD3gpPdubOC3qI/Zamg==} peerDependencies: solid-js: ^1.6.12 '@standard-schema/spec@1.1.0': - resolution: {integrity: sha1-p5tV26+GBIEvUtFAssmrQbwVC7g=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@standard-schema/spec/-/spec-1.1.0.tgz} + resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} '@tybys/wasm-util@0.10.3': - resolution: {integrity: sha1-AVy6np3UfOFNA9KoxdVHv7FpZl0=, tarball: https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@tybys/wasm-util/-/wasm-util-0.10.3.tgz} + resolution: {integrity: sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg==} '@types/braces@3.0.5': - resolution: {integrity: sha1-kRWfl+UWYwx5Rtiw1b9gJFmG4Ew=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@types/braces/-/braces-3.0.5.tgz} + resolution: {integrity: sha512-SQFof9H+LXeWNz8wDe7oN5zu7ket0qwMu5vZubW4GCJ8Kkeh6nBWUz87+KTz/G3Kqsrp0j/W253XJb3KMEeg3w==} '@types/chai@5.2.3': - resolution: {integrity: sha1-jpzZ4cNYH6azQaWu1ViOsoW+C0o=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@types/chai/-/chai-5.2.3.tgz} + resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==} '@types/d3-array@3.2.2': - resolution: {integrity: sha1-4CFRRk0C1KG0RkbQ/NuT+viP3ow=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@types/d3-array/-/d3-array-3.2.2.tgz} + resolution: {integrity: sha512-hOLWVbm7uRza0BYXpIIW5pxfrKe0W+D5lrFiAEYR+pb6w3N2SwSMaJbXdUfSEv+dT4MfHBLtn5js0LAWaO6otw==} '@types/d3-axis@3.0.6': - resolution: {integrity: sha1-52DldluBiLHe+jK8i7YGL4Hkx5U=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@types/d3-axis/-/d3-axis-3.0.6.tgz} + resolution: {integrity: sha512-pYeijfZuBd87T0hGn0FO1vQ/cgLk6E1ALJjfkC0oJ8cbwkZl3TpgS8bVBLZN+2jjGgg38epgxb2zmoGtSfvgMw==} '@types/d3-brush@3.0.6': - resolution: {integrity: sha1-wvQ2KwRdRy4bGGzb7DKbpSva7mw=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@types/d3-brush/-/d3-brush-3.0.6.tgz} + resolution: {integrity: sha512-nH60IZNNxEcrh6L1ZSMNA28rj27ut/2ZmI3r96Zd+1jrZD++zD3LsMIjWlvg4AYrHn/Pqz4CF3veCxGjtbqt7A==} '@types/d3-chord@3.0.6': - resolution: {integrity: sha1-FwbKQM9+pZoK3Y9EVu//j4d1eT0=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@types/d3-chord/-/d3-chord-3.0.6.tgz} + resolution: {integrity: sha512-LFYWWd8nwfwEmTZG9PfQxd17HbNPksHBiJHaKuY1XeqscXacsS2tyoo6OdRsjf+NQYeB6XrNL3a25E3gH69lcg==} '@types/d3-color@3.1.3': - resolution: {integrity: sha1-NoyWGhjech2oIA6AvzlD+1MTavI=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@types/d3-color/-/d3-color-3.1.3.tgz} + resolution: {integrity: sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==} '@types/d3-contour@3.0.6': - resolution: {integrity: sha1-mto/qcTQDjpQk/7QNWx6uSlgQjE=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@types/d3-contour/-/d3-contour-3.0.6.tgz} + resolution: {integrity: sha512-BjzLgXGnCWjUSYGfH1cpdo41/hgdWETu4YxpezoztawmqsvCeep+8QGfiY6YbDvfgHz/DkjeIkkZVJavB4a3rg==} '@types/d3-delaunay@6.0.4': - resolution: {integrity: sha1-GFwagMyAf92io/6WD3wRxKJ5UuE=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@types/d3-delaunay/-/d3-delaunay-6.0.4.tgz} + resolution: {integrity: sha512-ZMaSKu4THYCU6sV64Lhg6qjf1orxBthaC161plr5KuPHo3CNm8DTHiLw/5Eq2b6TsNP0W0iJrUOFscY6Q450Hw==} '@types/d3-dispatch@3.0.7': - resolution: {integrity: sha1-7wBNihKARs/OQ00XGC+DTkTvlbI=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@types/d3-dispatch/-/d3-dispatch-3.0.7.tgz} + resolution: {integrity: sha512-5o9OIAdKkhN1QItV2oqaE5KMIiXAvDWBDPrD85e58Qlz1c1kI/J0NcqbEG88CoTwJrYe7ntUCVfeUl2UJKbWgA==} '@types/d3-drag@3.0.7': - resolution: {integrity: sha1-sTq6iyRCtAaMmp5tHYL4vOp3/AI=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@types/d3-drag/-/d3-drag-3.0.7.tgz} + resolution: {integrity: sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ==} '@types/d3-dsv@3.0.7': - resolution: {integrity: sha1-CjUfmW3Jmzf0+li0ksLRwE49rBc=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@types/d3-dsv/-/d3-dsv-3.0.7.tgz} + resolution: {integrity: sha512-n6QBF9/+XASqcKK6waudgL0pf/S5XHPPI8APyMLLUHd8NqouBGLsU8MgtO7NINGtPBtk9Kko/W4ea0oAspwh9g==} '@types/d3-ease@3.0.2': - resolution: {integrity: sha1-4o2xv7+mFwdvd3DdHZpI6qO2xRs=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@types/d3-ease/-/d3-ease-3.0.2.tgz} + resolution: {integrity: sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==} '@types/d3-fetch@3.0.7': - resolution: {integrity: sha1-wEorTyMYGqN28wrwKD28eztWmYA=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@types/d3-fetch/-/d3-fetch-3.0.7.tgz} + resolution: {integrity: sha512-fTAfNmxSb9SOWNB9IoG5c8Hg6R+AzUHDRlsXsDZsNp6sxAEOP0tkP3gKkNSO/qmHPoBFTxNrjDprVHDQDvo5aA==} '@types/d3-force@3.0.10': - resolution: {integrity: sha1-bcj8bh81cE87BXCQvu63rGdL/xo=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@types/d3-force/-/d3-force-3.0.10.tgz} + resolution: {integrity: sha512-ZYeSaCF3p73RdOKcjj+swRlZfnYpK1EbaDiYICEEp5Q6sUiqFaFQ9qgoshp5CzIyyb/yD09kD9o2zEltCexlgw==} '@types/d3-format@3.0.4': - resolution: {integrity: sha1-seRGVkTds/3zomP+uyQKbNYW3pA=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@types/d3-format/-/d3-format-3.0.4.tgz} + resolution: {integrity: sha512-fALi2aI6shfg7vM5KiR1wNJnZ7r6UuggVqtDA+xiEdPZQwy/trcQaHnwShLuLdta2rTymCNpxYTiMZX/e09F4g==} '@types/d3-geo@3.1.1': - resolution: {integrity: sha1-nig68XlgHFSVgWALP+wllBkRMp0=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@types/d3-geo/-/d3-geo-3.1.1.tgz} + resolution: {integrity: sha512-65Emv9fQiQQqphLlRkuQ5ypPsOmWPhtBGCMv61JDPEPMvsx+gzhGf74yw1a78xFKPj6zw4AgQICJoQv0vK9M2w==} '@types/d3-hierarchy@3.1.7': - resolution: {integrity: sha1-YCP7Oy1GMiny1oD5rEtHRm9x8Xs=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@types/d3-hierarchy/-/d3-hierarchy-3.1.7.tgz} + resolution: {integrity: sha512-tJFtNoYBtRtkNysX1Xq4sxtjK8YgoWUNpIiUee0/jHGRwqvzYxkq0hGVbbOGSz+JgFxxRu4K8nb3YpG3CMARtg==} '@types/d3-interpolate@3.0.4': - resolution: {integrity: sha1-QSuQ6EhwKF8v+KhGxutgNE8SpBw=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz} + resolution: {integrity: sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==} '@types/d3-path@3.1.1': - resolution: {integrity: sha1-9jKzgMOsoduo40qgSbzWpK8j34o=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@types/d3-path/-/d3-path-3.1.1.tgz} + resolution: {integrity: sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==} '@types/d3-polygon@3.0.2': - resolution: {integrity: sha1-365UptNdGedqyVZbyzKo5UaTGJw=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@types/d3-polygon/-/d3-polygon-3.0.2.tgz} + resolution: {integrity: sha512-ZuWOtMaHCkN9xoeEMr1ubW2nGWsp4nIql+OPQRstu4ypeZ+zk3YKqQT0CXVe/PYqrKpZAi+J9mTs05TKwjXSRA==} '@types/d3-quadtree@3.0.6': - resolution: {integrity: sha1-1HQLD+NbHFi2bhSI9OftApUvVw8=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@types/d3-quadtree/-/d3-quadtree-3.0.6.tgz} + resolution: {integrity: sha512-oUzyO1/Zm6rsxKRHA1vH0NEDG58HrT5icx/azi9MF1TWdtttWl0UIUsjEQBBh+SIkrpd21ZjEv7ptxWys1ncsg==} '@types/d3-random@3.0.4': - resolution: {integrity: sha1-a9NoO4My/A8B5wWbdja8XH7eczc=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@types/d3-random/-/d3-random-3.0.4.tgz} + resolution: {integrity: sha512-UHYId5WTCx4L4YNel7NU00XUXXgvgpgZOvp10PuvsQENjMDXhh2RyFc0KBjO7B45ne4Ha1yVH7ii0vnzKkuzWA==} '@types/d3-scale-chromatic@3.1.0': - resolution: {integrity: sha1-3G1Pmpg3bxjqULrWw5U38bVGPDk=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@types/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz} + resolution: {integrity: sha512-iWMJgwkK7yTRmWqRB5plb1kadXyQ5Sj8V/zYlFGMUBbIPKQScw+Dku9cAAMgJG+z5GYDoMjWGLVOvjghDEFnKQ==} '@types/d3-scale@4.0.9': - resolution: {integrity: sha1-V6L3ByQub+Hega17/Myq9gYXmvs=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@types/d3-scale/-/d3-scale-4.0.9.tgz} + resolution: {integrity: sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw==} '@types/d3-selection@3.0.11': - resolution: {integrity: sha1-vXpF/AqMMWemMWdeYbwsorBY1KM=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@types/d3-selection/-/d3-selection-3.0.11.tgz} + resolution: {integrity: sha512-bhAXu23DJWsrI45xafYpkQ4NtcKMwWnAC/vKrd2l+nxMFuvOT3XMYTIj2opv8vq8AO5Yh7Qac/nSeP/3zjTK0w==} '@types/d3-shape@3.1.8': - resolution: {integrity: sha1-0VFsxQh1O+BoUs0GdY47tUoisOM=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@types/d3-shape/-/d3-shape-3.1.8.tgz} + resolution: {integrity: sha512-lae0iWfcDeR7qt7rA88BNiqdvPS5pFVPpo5OfjElwNaT2yyekbM0C9vK+yqBqEmHr6lDkRnYNoTBYlAgJa7a4w==} '@types/d3-time-format@4.0.3': - resolution: {integrity: sha1-1rwea2p9tpzM+73Uw0twYy2enbI=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@types/d3-time-format/-/d3-time-format-4.0.3.tgz} + resolution: {integrity: sha512-5xg9rC+wWL8kdDj153qZcsJ0FWiFt0J5RB6LYUNZjwSnesfblqrI/bJ1wBdJ8OQfncgbJG5+2F+qfqnqyzYxyg==} '@types/d3-time@3.0.4': - resolution: {integrity: sha1-hHL+7NY5aRRQ3YAA6zPt1EThMj8=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@types/d3-time/-/d3-time-3.0.4.tgz} + resolution: {integrity: sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==} '@types/d3-timer@3.0.2': - resolution: {integrity: sha1-cLvad9wjqnJ0E+IuIUr6Pw6FL3A=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@types/d3-timer/-/d3-timer-3.0.2.tgz} + resolution: {integrity: sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==} '@types/d3-transition@3.0.9': - resolution: {integrity: sha1-ETa8V+nds8OQ3MybX/O30rjZRwY=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@types/d3-transition/-/d3-transition-3.0.9.tgz} + resolution: {integrity: sha512-uZS5shfxzO3rGlu0cC3bjmMFKsXv+SmZZcgp0KD22ts4uGXp5EVYGzu/0YdwZeKmddhcAccYtREJKkPfXkZuCg==} '@types/d3-zoom@3.0.8': - resolution: {integrity: sha1-3Msy0cVrHhxuDxGA2ZSJbwOLxAs=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@types/d3-zoom/-/d3-zoom-3.0.8.tgz} + resolution: {integrity: sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw==} '@types/d3@7.4.3': - resolution: {integrity: sha1-1FUKhdCPSXj68KTDa4SMYeqsB+I=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@types/d3/-/d3-7.4.3.tgz} + resolution: {integrity: sha512-lZXZ9ckh5R8uiFVt8ogUNf+pIrK4EsWrx2Np75WvF/eTpJ0FMHNhjXk8CKEx/+gpHbNQyJWehbFaTvqmHWB3ww==} '@types/debug@4.1.13': - resolution: {integrity: sha1-ItHMnVQtNZPK6nZPl0MGqzYobuc=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@types/debug/-/debug-4.1.13.tgz} + resolution: {integrity: sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw==} '@types/deep-eql@4.0.2': - resolution: {integrity: sha1-M0MRlx06BxIefrkbaEpgXn7qnL0=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@types/deep-eql/-/deep-eql-4.0.2.tgz} + resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} '@types/esrecurse@4.3.1': - resolution: {integrity: sha1-b2Nq+WL75hkbgwvWdrpZhpJrzOw=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@types/esrecurse/-/esrecurse-4.3.1.tgz} + resolution: {integrity: sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw==} '@types/estree-jsx@1.0.5': - resolution: {integrity: sha1-hYqI6iDzT+ZREfAFpon6Hr9w3Bg=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@types/estree-jsx/-/estree-jsx-1.0.5.tgz} + resolution: {integrity: sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==} '@types/estree@1.0.9': - resolution: {integrity: sha1-zz8Oh2177hWpOrkluCv1cKOQSiQ=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@types/estree/-/estree-1.0.9.tgz} + resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==} '@types/geojson@7946.0.16': - resolution: {integrity: sha1-jr5T1p762nBERU4zBcGQF9l87So=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@types/geojson/-/geojson-7946.0.16.tgz} + resolution: {integrity: sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg==} '@types/hast@3.0.5': - resolution: {integrity: sha1-SAIN5MDmNJL0yp20IGjBCPaLf48=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@types/hast/-/hast-3.0.5.tgz} + resolution: {integrity: sha512-rp/ezSWaD1m44dPKICGhiskI13nVr7qTloFwDa/IYkhhf5nzwP+zIQcIJh3WIFSBOy/H1PzB40jPjMDksN4F+g==} '@types/js-yaml@4.0.9': - resolution: {integrity: sha1-zYI4LE+QL+2WkaLteexoxYmK9MI=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@types/js-yaml/-/js-yaml-4.0.9.tgz} + resolution: {integrity: sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==} '@types/json-schema@7.0.15': - resolution: {integrity: sha1-WWoXRyM2lNUPatinhp/Lb1bPWEE=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@types/json-schema/-/json-schema-7.0.15.tgz} + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} '@types/mdast@4.0.4': - resolution: {integrity: sha1-fM9y7dLxqn3TQ34YDGQ3NYWATdY=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@types/mdast/-/mdast-4.0.4.tgz} + resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} '@types/mdx@2.0.14': - resolution: {integrity: sha1-weVBEyZbFSAhqwr+BDTjyt2Qv+M=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@types/mdx/-/mdx-2.0.14.tgz} + resolution: {integrity: sha512-T48PeuJtvLosNTPVhfnIp3i/n3a4g4Bad7YCq5k64D4u7NwDrAotikQ+5+sjtUvBmxCMlbo3dVL+C2dP0rWHzg==} '@types/micromatch@4.0.10': - resolution: {integrity: sha1-+DuLBc6h+s4qfPO36Gb/l9IEtjI=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@types/micromatch/-/micromatch-4.0.10.tgz} + resolution: {integrity: sha512-5jOhFDElqr4DKTrTEbnW8DZ4Hz5LRUEmyrGpCMrD/NphYv3nUnaF08xmSLx1rGGnyEs/kFnhiw6dCgcDqMr5PQ==} '@types/ms@2.1.0': - resolution: {integrity: sha1-BSqmekjszEMJ1/AZG35BQ0uQu3g=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@types/ms/-/ms-2.1.0.tgz} + resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} '@types/nlcst@2.0.3': - resolution: {integrity: sha1-McrTRuqrSKmopYRl09BeJTDdp2I=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@types/nlcst/-/nlcst-2.0.3.tgz} + resolution: {integrity: sha512-vSYNSDe6Ix3q+6Z7ri9lyWqgGhJTmzRjZRqyq15N0Z/1/UnVsno9G/N40NBijoYx2seFDIl0+B2mgAb9mezUCA==} '@types/node@24.13.3': - resolution: {integrity: sha1-SfGL08ZHhm3NpRoHVsFF4UWQzhY=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@types/node/-/node-24.13.3.tgz} + resolution: {integrity: sha512-Dh8vAsV36ig5wa9OX4pXvMc9D3Veibfw2wix0CUwYODLD8nkj9UsLjASr49nPg+2eKzxhBV+v7L8pXvT4e639Q==} '@types/picomatch@4.0.3': - resolution: {integrity: sha1-2Su/JBZkeMVFfIu5ukGn9J1V4JQ=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@types/picomatch/-/picomatch-4.0.3.tgz} + resolution: {integrity: sha512-iG0T6+nYJ9FAPmx9SsUlnwcq1ZVRuCXcVEvWnntoPlrOpwtSTKNDC9uVAxTsC3PUvJ+99n4RpAcNgBbHX3JSnQ==} '@types/sax@1.2.7': - resolution: {integrity: sha1-ul/n35qpyJtt/3aIoZAj3SljCR0=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@types/sax/-/sax-1.2.7.tgz} + resolution: {integrity: sha512-rO73L89PJxeYM3s3pPPjiPgVVcymqU490g0YO5n5By0k2Erzj6tay/4lr1CHAAU4JyOWd1rpQ8bCf6cZfHU96A==} '@types/trusted-types@2.0.7': - resolution: {integrity: sha1-usywepcLkXB986PoumiWxX6tLRE=, tarball: https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@types/trusted-types/-/trusted-types-2.0.7.tgz} + resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} '@types/unist@2.0.11': - resolution: {integrity: sha1-Ea9XsSfjJId3SEH3pOVOqxZtA8Q=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@types/unist/-/unist-2.0.11.tgz} + resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==} '@types/unist@3.0.3': - resolution: {integrity: sha1-rKqw+RnOaczmKcLU7S60rcG2wgw=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@types/unist/-/unist-3.0.3.tgz} + resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} '@typescript-eslint/eslint-plugin@8.65.0': - resolution: {integrity: sha1-Cljfb+qMC/azlvUYB3CZvIt2K7U=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.65.0.tgz} + resolution: {integrity: sha512-IEgob78X12rHpUmtcwFsXhZdVGJtwTVP8FiCLZkR6GlYVrl2PcuB+KhCE5BlVC/eQpQnu8WXRtkHZuPar+gCRA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: '@typescript-eslint/parser': ^8.65.0 @@ -1679,101 +1669,101 @@ packages: typescript: '>=4.8.4 <6.1.0' '@typescript-eslint/parser@8.62.0': - resolution: {integrity: sha1-hTMJT7REJ/ULgoE8bTh2eC8g3D4=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@typescript-eslint/parser/-/parser-8.62.0.tgz} + resolution: {integrity: sha512-dzHeT2gySzZtLDsuqxU9AkYgIsQoHAHtRBpOqM+Ofzx1Bwrd2RcCjQJ+6iQbsHOIR6NS33bF2W1k3blN1zLDrA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' '@typescript-eslint/parser@8.65.0': - resolution: {integrity: sha1-UpXBBYwKHddG7yi6r5wDQdvfA9w=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@typescript-eslint/parser/-/parser-8.65.0.tgz} + resolution: {integrity: sha512-CZ4nMxWwgu1HEEFNkeaCptra9QCtkmKdgf3sWh1rl1trIhmxLilgTV4cwcbQ4wemnT4sWQN8CaKOmdYx+g2gMA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' '@typescript-eslint/project-service@8.62.0': - resolution: {integrity: sha1-q3TBq7SVn7TDun1+3GVU7iRduZA=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@typescript-eslint/project-service/-/project-service-8.62.0.tgz} + resolution: {integrity: sha512-wexnCqiTg7BOGtbLDftYpRWlmLq4xfoMd7BKFR6Y75sZS3QmRKLdN3yWLhmIYgqMmP/OXWpj3H8odkb5nGURCQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' '@typescript-eslint/project-service@8.65.0': - resolution: {integrity: sha1-Zfu8mhWRq/+uq1UTIA+EgnHLCqU=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@typescript-eslint/project-service/-/project-service-8.65.0.tgz} + resolution: {integrity: sha512-SxnPhbTsGahizDgbu7oqFH/xVtzIqMd/s+WtnSxNxJZJpLbdT5IPdzg8EZxO3+PoKahXmwJLeNQOpKJb3/bi7Q==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' '@typescript-eslint/scope-manager@8.62.0': - resolution: {integrity: sha1-p6e0KNMkRLyaT+FvJKePwSQoP9Q=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@typescript-eslint/scope-manager/-/scope-manager-8.62.0.tgz} + resolution: {integrity: sha512-1lX38kNxXIRb8mEc3lbq5mdHq1Pf2+U0nFU65KfT18mtPxxl0fvjuEE92mHuXPuCtElJhOrddOpyMlM3Z0umEA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@typescript-eslint/scope-manager@8.65.0': - resolution: {integrity: sha1-lUcgLOfmCOe2KD31hXA7mAoOpw0=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@typescript-eslint/scope-manager/-/scope-manager-8.65.0.tgz} + resolution: {integrity: sha512-Esbl8OSYiVxBokYgWPf7VVWg/BE798wXhimnn9ML9Pt5qoDf8bfQlgjlKXR/k98+AcNzlLKYrpCcrcuZ9DZLgg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@typescript-eslint/tsconfig-utils@8.62.0': - resolution: {integrity: sha1-lECmc1gcbZ3jCMTVgD3VLtXXFyk=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.62.0.tgz} + resolution: {integrity: sha512-y2GAdB6ykaXUvuspbYnizQc4oDDz0Tz/Yc7iWrXf9mx8vm/L/0vLHCe0tS2boG96Zy+DivnVDQ9ZUEWoHqqx1g==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' '@typescript-eslint/tsconfig-utils@8.65.0': - resolution: {integrity: sha1-NvFo/NuxKV90Rv8DeWZ/mMPPG/M=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.65.0.tgz} + resolution: {integrity: sha512-j6GzGqCiRdA7Qhur2VVmKZAkBLfnHFQfx4TaJGL9RMveZqCo48jSHHO0DTgizEnGhtWnqmbtCUSrqSkdiY/0Hg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' '@typescript-eslint/type-utils@8.65.0': - resolution: {integrity: sha1-0xbXUi2Tz/TNFPMF4C898tgE+cE=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@typescript-eslint/type-utils/-/type-utils-8.65.0.tgz} + resolution: {integrity: sha512-YjaZ7PRI5qY7ax2L3PbvX0rRyGtipAReCWs0mhhDBHjH/vl0g0BonaGXrKdKpMbIIsMIwDgbk/xzkBTyAltS5g==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' '@typescript-eslint/types@8.62.0': - resolution: {integrity: sha1-YBQnwQID2fDzTws+R033NesStZM=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@typescript-eslint/types/-/types-8.62.0.tgz} + resolution: {integrity: sha512-KvAclkktORPvM54TgLgA4z9HIV1M8zOgw9ZVNXl9f/8dLYfXYX1wkMXP7qmabpijQRV5bHJLOmoyGQbLMaUYeg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@typescript-eslint/types@8.65.0': - resolution: {integrity: sha1-PoZzhBand8i4klq0Z0X0js+QTJ8=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@typescript-eslint/types/-/types-8.65.0.tgz} + resolution: {integrity: sha512-JSSwWNy+H0E/01jJEM+hrX6N0OFDzFzeIhHFSAS01tlVaevpG8cFyYRPhS5yjGOvBUx3sqQHVMjCL1CAZZMxBg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@typescript-eslint/typescript-estree@8.62.0': - resolution: {integrity: sha1-uWtV0C4mqglDRCHD+meOUlygmkw=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@typescript-eslint/typescript-estree/-/typescript-estree-8.62.0.tgz} + resolution: {integrity: sha512-+hVbNxtW64pIcZWDPGbyaKF7vp2IBTVY5ma1blwwksrjdsbdqqEKvJWMGbBofei4F6Dovx1M0RJgoFeNu2279A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' '@typescript-eslint/typescript-estree@8.65.0': - resolution: {integrity: sha1-8fUUgI9qpxPi1niuj/WSpl4WMq8=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@typescript-eslint/typescript-estree/-/typescript-estree-8.65.0.tgz} + resolution: {integrity: sha512-JboAE2swaYt4tb1fHhHTABE2K+OLy09XfcTbhnk4Pw96f9dd2e9iYsJ28gBggHlo5z5x1rkyWvcPoTuNTd4oGg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' '@typescript-eslint/utils@8.65.0': - resolution: {integrity: sha1-r+3ZdKDI3u71U7UJ31gAuv1hWnI=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@typescript-eslint/utils/-/utils-8.65.0.tgz} + resolution: {integrity: sha512-gXiwIHsYreboxeJucHKPvgwl7dXt50mF8s1/c00cP/WoVTyWKFdtfhRWwZiXYFU5H2O8vVoSLNrexFZjYS/SGA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' '@typescript-eslint/visitor-keys@8.62.0': - resolution: {integrity: sha1-ttqrGQv48YYS9bhjI0aaEiiMazE=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@typescript-eslint/visitor-keys/-/visitor-keys-8.62.0.tgz} + resolution: {integrity: sha512-CY3uyFSRbcQv3nnSv8S0+lDftMVz6P963PoRlxrV7ew/Md564g9ut60PYzdLM5qW4jFn93GBF+Soi90ISAN+GQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@typescript-eslint/visitor-keys@8.65.0': - resolution: {integrity: sha1-43BME8tKHCJFTBq/KP9HN+FQGMY=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@typescript-eslint/visitor-keys/-/visitor-keys-8.65.0.tgz} + resolution: {integrity: sha512-8C71BQkGjiMmXtop7pHVJu1l2NNShFdkCyD6a2ezzs5vU/L3LRtb69EtcteFwz0mYMPzIgOw0n6OV4VBUWZd7A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@ungap/structured-clone@1.3.2': - resolution: {integrity: sha1-oDrYLNVnZBTQaLqG+IDFaBGUqt8=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@ungap/structured-clone/-/structured-clone-1.3.2.tgz} + resolution: {integrity: sha512-5jsZFwgR5rTdKwidH9Qmat75RKwqfpKlWWB1frDkljN127mwqBu8K0PYo7/hFpF03IEJpfVPpCQDY/eDx3iHvA==} '@ungap/structured-clone@1.3.3': - resolution: {integrity: sha1-CUBB4aTLGYfwODNUISgayL45C8w=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@ungap/structured-clone/-/structured-clone-1.3.3.tgz} + resolution: {integrity: sha512-60YRaenCQcVjYEKOcG824+DRGGIQ3VKErcBoAEDJZz5bKIs2ZG+X/H9Nk+Q6EVkwJk5QNApxbrc5QtBSwtrXAg==} '@unocss/astro@66.7.5': - resolution: {integrity: sha1-9Vz1z7dqybk8ypZJS2MvN+UYo9E=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@unocss/astro/-/astro-66.7.5.tgz} + resolution: {integrity: sha512-OjXSlwj3SI3pmDVyJlSI6Lm2romCxkUuHi7l5p5Nud4ITyYjOqQWV8nzwXFLGK2+91vNiqUE6IkdsDf23qJR6A==} peerDependencies: vite: ^5.0.0-0 || ^6.0.0-0 || ^7.0.0-0 || ^8.0.0-0 peerDependenciesMeta: @@ -1781,82 +1771,82 @@ packages: optional: true '@unocss/cli@66.7.5': - resolution: {integrity: sha1-oDTDhKtrKh3uGFd1lPlycmVxyDU=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@unocss/cli/-/cli-66.7.5.tgz} + resolution: {integrity: sha512-fgWkECRn2LGVo9sEpmjk/KJ3NSKUDitaZCNrJcEYM93DG+ELriTHcL+VWBlF4rcZf9fdGlq1nKbbRHUZirFCHQ==} hasBin: true '@unocss/config@66.7.5': - resolution: {integrity: sha1-Pslb7GA4Q/Byr/4hOD5N1QJfVV4=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@unocss/config/-/config-66.7.5.tgz} + resolution: {integrity: sha512-dkPl9glhEahJ+Xoja5ZseKKnH+vZaeaKQzg8b0otcKcPPNrHQgu1nu3QgfeOjnXOGrjZIotHwUeVtt4ZA2Skgg==} '@unocss/core@66.7.5': - resolution: {integrity: sha1-PQTLoaEk12d0V4Of97phMUgm+OQ=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@unocss/core/-/core-66.7.5.tgz} + resolution: {integrity: sha512-UdJb8MiMywcau8QrWEVgUAz0kvoFHyR+sACwYCgmBh/BpKJGyR/zw/Ys3wvysbm0f+i/20VGBex/QQxYVlzdyQ==} '@unocss/extractor-arbitrary-variants@66.7.5': - resolution: {integrity: sha1-fYbkQepkgLxviTizIBcTqZn3wCE=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@unocss/extractor-arbitrary-variants/-/extractor-arbitrary-variants-66.7.5.tgz} + resolution: {integrity: sha512-5zOkbnLIJc8E749qNjLXfPHl3FdHloop12h706/ojr6idK4ix0KLm43R//uLnphixCehdHJRuHnavnM4C/kQbA==} '@unocss/inspector@66.7.5': - resolution: {integrity: sha1-vnvZRQAPQhpz2uGsgTQJvyA1Xgc=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@unocss/inspector/-/inspector-66.7.5.tgz} + resolution: {integrity: sha512-WmTJMnj8bmRxvw/wGeShmL2eEHr2/L0BdGTXSxhfzwcO8y5XZEbBmVciLcM7pqaTXQ6JY4+KnITrDUf1urjZxQ==} '@unocss/preset-attributify@66.7.5': - resolution: {integrity: sha1-1ZIjRNVTBrl1GsfVb1QFV7wzmeI=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@unocss/preset-attributify/-/preset-attributify-66.7.5.tgz} + resolution: {integrity: sha512-1Oi1Cp81pqYJwG3h4+OlP5A0FKyaa07MFBXaXc4Yr3faiTbsI8SKj2TqnZCb+NQvBsEqslEd+jKXGZ3lKzCVOQ==} '@unocss/preset-icons@66.7.5': - resolution: {integrity: sha1-7OK+lbxXYgq4v/574LaLDyQCgdI=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@unocss/preset-icons/-/preset-icons-66.7.5.tgz} + resolution: {integrity: sha512-ZsxadWnGGtHdANTikuMnjkQaT1qwUFJHZBF4fzVsPMnUiiKGs8rzXukwM9w3Gi9ontM7nbG2FYi9clWETSlpFg==} '@unocss/preset-mini@66.7.5': - resolution: {integrity: sha1-xGP7xo8Xkae/6q9hyhoaEW42IfU=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@unocss/preset-mini/-/preset-mini-66.7.5.tgz} + resolution: {integrity: sha512-o37TSl4ecT0dKu+3/TYuTYht75h82SEwDNl476m9ve0KW4Pv1O2tT/9TWd7N5cutEpySr8/YtjMwtWBD+drxBg==} '@unocss/preset-tagify@66.7.5': - resolution: {integrity: sha1-KNpiGIrfOK+1dhRh2g7dSXe0gYE=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@unocss/preset-tagify/-/preset-tagify-66.7.5.tgz} + resolution: {integrity: sha512-/8YB1tXVi+WmNKPhsCdtO1xnQKEkshSnWDp6AbvVP3f6qOF7adlMYpAt3kpWCoVUBsfOQ06ZQlnfricMjObyoQ==} '@unocss/preset-typography@66.7.5': - resolution: {integrity: sha1-UM5StYKMayDrb02fzOsJ3M6zMbI=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@unocss/preset-typography/-/preset-typography-66.7.5.tgz} + resolution: {integrity: sha512-2dxC8LT9KYa29UZT4muDFl7DbIXvKktTfeSMbUGMdZKbHcuMtKSP2U52wti1PL5I9duqp4v+8G33EeVutGTUaQ==} '@unocss/preset-uno@66.7.5': - resolution: {integrity: sha1-u8uLwgcmenKW6im/bU+N2hNCNxY=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@unocss/preset-uno/-/preset-uno-66.7.5.tgz} + resolution: {integrity: sha512-zaUlYgNngbt50fZA/LbtsEnmPKojPqeiXCyUUiKQMv2uJQhncR32xhLZXVQ+TJD7hlfZ+6FAqlco1NIiAcub9w==} '@unocss/preset-web-fonts@66.7.5': - resolution: {integrity: sha1-8fKW1ddKwcMEG2wUvZ+KW6gWp4w=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@unocss/preset-web-fonts/-/preset-web-fonts-66.7.5.tgz} + resolution: {integrity: sha512-OLLTK7kswdSu51qxEm6O+AehecgCfS08Ivqo+280lKzFW7V1jXr5okeJ1ty+85oHCprJqzcD9iG1khxNRLomcA==} '@unocss/preset-wind3@66.7.5': - resolution: {integrity: sha1-01HhqESiwSD6gyq7PjrR4VYmw1A=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@unocss/preset-wind3/-/preset-wind3-66.7.5.tgz} + resolution: {integrity: sha512-atFe/7Qein+oMdyZs0hEo+3EjV99Av2LVxDbzpCungxIfbS3TnQt70EIuHXMPNCVWLYwrMV+/P1n9Ntb0E3mow==} '@unocss/preset-wind4@66.7.5': - resolution: {integrity: sha1-by77fpemjD3Xip0EC4kbnTd3dTE=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@unocss/preset-wind4/-/preset-wind4-66.7.5.tgz} + resolution: {integrity: sha512-n3jIvQv8x1jXpmWfvNFBIqHNARki4mKZXfxAA31gekpXsRRTg16u1+yC1+PBBJgoEDFEnnmKnG7EZP88S8LVXA==} '@unocss/preset-wind@66.7.5': - resolution: {integrity: sha1-8W+Khs62jiYnQgCM0wqVMHwA8gE=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@unocss/preset-wind/-/preset-wind-66.7.5.tgz} + resolution: {integrity: sha512-LVKgGr0A9Lc7F85xGXrrb71DDXMlHGA8bcj/Kht8BCsuRdBZadNbLlnv5qnSJiHYhi3/blzcgVoaeRor6L9yNA==} '@unocss/reset@66.7.5': - resolution: {integrity: sha1-vM+ZGeLG2de+jkF1Rcs+kotcnMc=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@unocss/reset/-/reset-66.7.5.tgz} + resolution: {integrity: sha512-z3wbt2cuQPjtT6w5xzRYZYFIIlUPzhVKz8yIcE9fvu7BgR3hO7uVsg/5mzDoGwQ96Ya3Sk68rpmI/gLYl4bJag==} '@unocss/rule-utils@66.7.5': - resolution: {integrity: sha1-MgwW3PzH6TU/JjdUnMRc53Y3lk0=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@unocss/rule-utils/-/rule-utils-66.7.5.tgz} + resolution: {integrity: sha512-/AKHBRF6ZOexE3EDDv8ZEYh40P5e2Eha41IYUbE1wjigW7++ssmvimSTdufJzZvU5DGP++E3B3WEsFPprZMjAg==} '@unocss/transformer-attributify-jsx@66.7.5': - resolution: {integrity: sha1-vJ8gyVHwVPO3DfuzKhy8tkXtAb8=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@unocss/transformer-attributify-jsx/-/transformer-attributify-jsx-66.7.5.tgz} + resolution: {integrity: sha512-r8qDwNSt0eGSwWws3xsuIHb3PZYR2embFdYoE67hD/xlYgLjX1uPy/HUlGCSSh4uLc4vVYjurr0Oq5xF/B8YiA==} '@unocss/transformer-compile-class@66.7.5': - resolution: {integrity: sha1-A4Rr9uUq8fyix8lzMZEwS9Wk3Tk=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@unocss/transformer-compile-class/-/transformer-compile-class-66.7.5.tgz} + resolution: {integrity: sha512-KuECgsGF7tGe808vIvKViEjI0UCUgYgneJfK+/TWBkjC7s8dLVaUtJzzcP9/r6OfGlgyn/x1YTdRqTaCENa7Xg==} '@unocss/transformer-directives@66.7.5': - resolution: {integrity: sha1-l9CDGriqlC2PFlSIJSuxOYtlqX0=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@unocss/transformer-directives/-/transformer-directives-66.7.5.tgz} + resolution: {integrity: sha512-VMJApXXOwlDubkW+cNMmOkfxLefFupJr+yU23gGYUB2NPsuVltc8H5CDM0gfVebpeL5CUW05evxzEAk2wsju+Q==} '@unocss/transformer-variant-group@66.7.5': - resolution: {integrity: sha1-jUL4bNZw/yR3mOZzPk6KVxTlrds=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@unocss/transformer-variant-group/-/transformer-variant-group-66.7.5.tgz} + resolution: {integrity: sha512-iDmP3mM8J+IxuQf5Uh33zsi528xnGxTpKRJ0c+LCrqBTTkR2tZr4aCzNmJ0g29Js2yEOsyNXRRc8BNTuvgn0AA==} '@unocss/vite@66.7.5': - resolution: {integrity: sha1-chGSQUCxpihEF2TlfHMIg4n5Mns=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@unocss/vite/-/vite-66.7.5.tgz} + resolution: {integrity: sha512-1z1TBCNJCR2WzjPtjzmCHr8rtzXHosMjLdsCNe6Mzsfwiw044gzzLVuiEZO9vIjkI50lvQ+gIOxOiVQG0hGAeA==} peerDependencies: vite: ^5.0.0-0 || ^6.0.0-0 || ^7.0.0-0 || ^8.0.0-0 '@upsetjs/venn.js@2.0.0': - resolution: {integrity: sha1-O+GSA4zdqSeqT4siq1Gvgqv0fzQ=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@upsetjs/venn.js/-/venn.js-2.0.0.tgz} + resolution: {integrity: sha512-WbBhLrooyePuQ1VZxrJjtLvTc4NVfpOyKx0sKqioq9bX1C1m7Jgykkn8gLrtwumBioXIqam8DLxp88Adbue6Hw==} '@vitest/expect@4.1.11': - resolution: {integrity: sha1-X1gNH5zbujFNvyOy2RH46yOHj18=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@vitest/expect/-/expect-4.1.11.tgz} + resolution: {integrity: sha512-VX2x5vNJXET47KAFzwERI+KRMtTTCSWTfSMKsW7JsUsXV4psq++e3DvZpuTDOpHcxytiDs6p2nhVb2tVDiiUYw==} '@vitest/mocker@4.1.11': - resolution: {integrity: sha1-jikGNhvF36JxdXqFiugGQxGPy7Q=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@vitest/mocker/-/mocker-4.1.11.tgz} + resolution: {integrity: sha512-2XJVD55d1o5AZous5CCGKS74g/riOj9odEt2bQpCVZeblHyHdnMeFl4jl0XjU21stf4mbjUkew2eXQZt65g5CQ==} peerDependencies: msw: ^2.4.9 vite: ^6.0.0 || ^7.0.0 || ^8.0.0 @@ -1867,133 +1857,133 @@ packages: optional: true '@vitest/pretty-format@4.1.11': - resolution: {integrity: sha1-iyjrgkB3HW6pcOM76utBOEtRho4=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@vitest/pretty-format/-/pretty-format-4.1.11.tgz} + resolution: {integrity: sha512-yiZzPbGTS9Sr/JpFl8zHrcIkAofNbFV6k21vIgQN/cY/oxZeXhJv5sc/MBJ5jFKWmWs+oJHw0UXLZjmf931+Vw==} '@vitest/runner@4.1.11': - resolution: {integrity: sha1-v7rZjI1sPx+03xIFatVpgh/3fyE=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@vitest/runner/-/runner-4.1.11.tgz} + resolution: {integrity: sha512-LztvUgdwMNJMIkj3hQnnxiC2Xy1zNxq928W/xhjCLaNCzqTZOudjwbQf6v9IntZGPw132i2Lq2rgTRZHD3JHNw==} '@vitest/snapshot@4.1.11': - resolution: {integrity: sha1-30YesWWSSjFVmG3eaOEzYPU/PUw=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@vitest/snapshot/-/snapshot-4.1.11.tgz} + resolution: {integrity: sha512-pN7ikn1ON7h8ee4gIAp4AzyK+zBtJPzVbqOgu5LCEh4VaJVbPQcgYQYJIMGQPXVeJJq1fnfazis7a5pFNPahog==} '@vitest/spy@4.1.11': - resolution: {integrity: sha1-Ct1FyulTr+2ciPmOL2/JFkVYwyo=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@vitest/spy/-/spy-4.1.11.tgz} + resolution: {integrity: sha512-apNa/prQy2qCeywhnixOHPRCgGNhvg7T4Dapfl1GahLp/R+uhBm5cPyFoNVyqsNd2h1nJxL6BqqdIjiABL60YA==} '@vitest/utils@4.1.11': - resolution: {integrity: sha1-myekKTuCeUKyI1Ob+rG9n36toxs=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@vitest/utils/-/utils-4.1.11.tgz} + resolution: {integrity: sha512-zTCVGpyFsGWBhllOyKlTw/vnr6D9qxsfSDyfbyZmTyjHw5N/VuvzHpHoQjm2ZJzn4RJgx5w4r7V0er69CmLgPQ==} '@volar/language-core@2.4.28': - resolution: {integrity: sha1-wh82WpHB3/6L1yZP1JF3DI10/vM=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@volar/language-core/-/language-core-2.4.28.tgz} + resolution: {integrity: sha512-w4qhIJ8ZSitgLAkVay6AbcnC7gP3glYM3fYwKV3srj8m494E3xtrCv6E+bWviiK/8hs6e6t1ij1s2Endql7vzQ==} '@volar/source-map@2.4.28': - resolution: {integrity: sha1-tAJU6MlhmeXx4Hlnd8WTxhetJw4=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@volar/source-map/-/source-map-2.4.28.tgz} + resolution: {integrity: sha512-yX2BDBqJkRXfKw8my8VarTyjv48QwxdJtvRgUpNE5erCsgEUdI2DsLbpa+rOQVAJYshY99szEcRDmyHbF10ggQ==} '@vtbag/cam-shaft@1.0.6': - resolution: {integrity: sha1-5eBpohDkbFtxBa/pZ4In7JxeQts=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@vtbag/cam-shaft/-/cam-shaft-1.0.6.tgz} + resolution: {integrity: sha512-Xy1bmJJLXuCqxmY2agwPfhGNv1XZViqh54H0VGK4mouGsItFsh8Mz/wWAP6mZwAOEuu9bEOJ1mJ+oNoaczZ1zw==} '@vtbag/element-crossing@1.1.0': - resolution: {integrity: sha1-F4xG+4uZwOrA29+gPYrn7Fa09ig=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@vtbag/element-crossing/-/element-crossing-1.1.0.tgz} + resolution: {integrity: sha512-1YL609KPwhHUKRrVNfoogQCVJPfFrE5DubOLcCJZLHVCjWZ2ZAPcaq1wR2OP6nXD0Ok9JLX41YsEtYBYzw6CxQ==} '@vtbag/inspection-chamber@1.0.24': - resolution: {integrity: sha1-x+twvFnWBDKHeTQG5DDzmLNVryI=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@vtbag/inspection-chamber/-/inspection-chamber-1.0.24.tgz} + resolution: {integrity: sha512-L6CrMbzJ0gdG/P5WnGyVgRxHVeLhlQgXh3mp+OI4JdJjFiwIhh9+sG/FXM2DneBs5HQvaWUq4qf6NiSlgVbyvQ==} '@vtbag/turn-signal@1.3.1': - resolution: {integrity: sha1-fLJv0y3XwTw6iZX6If4vzEn1u2Q=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@vtbag/turn-signal/-/turn-signal-1.3.1.tgz} + resolution: {integrity: sha512-6rWkG+ik3U+KQGI94yNOrOh5QedB9zmP/8H51X5WQwrJz8m2MAU5YwGRRcweO/dJ6wW/Bn7OsgC1vRURnwrvCg==} '@vtbag/utensil-drawer@1.2.16': - resolution: {integrity: sha1-i9w7KA6hOHs5kYAp+oo2iKAOnJQ=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@vtbag/utensil-drawer/-/utensil-drawer-1.2.16.tgz} + resolution: {integrity: sha512-RSahZXk4NAFTF3zDYQH1x4qv8gFLcWus7qD//D0b58zoZIeqa2uKePLMy4lSHagYdkwBlKXKlfcDSrqUvWmxnw==} '@vue/compiler-core@3.5.39': - resolution: {integrity: sha1-O26iuV88DtQEjv2H1xxGjkAhlR0=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@vue/compiler-core/-/compiler-core-3.5.39.tgz} + resolution: {integrity: sha512-16KBTEXAJCpDr0mwlw+AZyhu8iyC7R3S2vBwsI7QnWJU6X3WKc9VKeNEZpiMdZ569qWhz9574L3vV55qRL0Vtw==} '@vue/compiler-dom@3.5.39': - resolution: {integrity: sha1-1CYWciM0QnYr7hcJ3MNM7vwa6HM=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@vue/compiler-dom/-/compiler-dom-3.5.39.tgz} + resolution: {integrity: sha512-oQPigALqYbNxTNPvNgSOe+czwVExfbVF02lz8jP0S3AXJiu3jxYDygNUiqSep4ezzW8XgnubqH63My2A7JR/vg==} '@vue/language-core@3.3.5': - resolution: {integrity: sha1-fwPiwutIZS6SXsgRsEi3oXwjzGA=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@vue/language-core/-/language-core-3.3.5.tgz} + resolution: {integrity: sha512-UkKu5nhX89fg4VhlG/FOeI10G3cj/7radKT/cy9BT4Q9qJmJlSTAc/dP63Xqs29aypN4f39xUV6PsLNk/dcD6g==} '@vue/shared@3.5.39': - resolution: {integrity: sha1-aUva6dRzgcL8/txtUnTyRQBowew=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@vue/shared/-/shared-3.5.39.tgz} + resolution: {integrity: sha512-l1rrBtBfTnmxvtsvdQDXltUUy8S1Y+ZaqdfUzmAnJkTd8Z8rv5v/ytW+TKiqEOWyHPoqtPlNFSs0lhRmYVSHVA==} acorn-jsx@5.3.2: - resolution: {integrity: sha1-ftW7VZCLOy8bxVxq8WU7rafweTc=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/acorn-jsx/-/acorn-jsx-5.3.2.tgz} + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 acorn@8.17.0: - resolution: {integrity: sha1-F4WtuE+vjYrdEDabk4Jvwr0I8f4=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/acorn/-/acorn-8.17.0.tgz} + resolution: {integrity: sha512-xRQbDb9BnwDafYNn6Vwl839DYVjqXYb1XVGtWAZ1kcDc6iwAL4hg3B1dZlRiuENFeO2H53gFG3in621AdERVAg==} engines: {node: '>=0.4.0'} hasBin: true agent-base@9.0.0: - resolution: {integrity: sha1-7J77CDFOHnWwhS10qr+aOH+Zg04=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/agent-base/-/agent-base-9.0.0.tgz} + resolution: {integrity: sha512-TQf59BsZnytt8GdJKLPfUZ54g/iaUL2OWDSFCCvMOhsHduDQxO8xC4PNeyIkVcA5KwL2phPSv0douC0fgWzmnA==} engines: {node: '>= 20'} ajv@6.15.0: - resolution: {integrity: sha1-B+mCx0YmFnqnoklcU4F4ktcTlJI=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/ajv/-/ajv-6.15.0.tgz} + resolution: {integrity: sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==} alien-signals@3.2.1: - resolution: {integrity: sha1-62YlaUm86Qt9MNBV4nUuYtaTDHw=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/alien-signals/-/alien-signals-3.2.1.tgz} + resolution: {integrity: sha512-I8FjmltrfnDFoZedi5CG8DghVYNhzb/Ijluz7tCSJH0xpd0484Kowhbb1XDYOxfJpU1p5wnM2X54dA+IfGyD1g==} am-i-vibing@0.4.0: - resolution: {integrity: sha1-Tbp96V+brbPmGg8Fk/rEOEpKvH4=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/am-i-vibing/-/am-i-vibing-0.4.0.tgz} + resolution: {integrity: sha512-MxT4XZL7pzLHpuvhDKdMaQHMGGkJDLluKBLsbstn+8wv9sWcFT6h+0ve9qkml95amVTZtZV83gQe2hY+ojgHLg==} hasBin: true ansi-escapes@7.3.0: - resolution: {integrity: sha1-U5W7dLIVCkodbjwlZfSuynjShic=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/ansi-escapes/-/ansi-escapes-7.3.0.tgz} + resolution: {integrity: sha512-BvU8nYgGQBxcmMuEeUEmNTvrMVjJNSH7RgW24vXexN4Ven6qCvy4TntnvlnwnMLTVlcRQQdbRY8NKnaIoeWDNg==} engines: {node: '>=18'} anymatch@3.1.3: - resolution: {integrity: sha1-eQxYsZuhcgqEIFtXxhjVrYUklz4=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/anymatch/-/anymatch-3.1.3.tgz} + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} engines: {node: '>= 8'} anynum@1.0.1: - resolution: {integrity: sha1-KqwA4I3603JsHUYuYNvC+DFlmkQ=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/anynum/-/anynum-1.0.1.tgz} + resolution: {integrity: sha512-N6//FLET/tXYNM/F6ABca1oH6fWB+KlTt909Le28WMDBk8oaT4vY17DCrwg2MvmuqUKt3Ni4N5dGJ/EoBgcO6A==} arg@5.0.2: - resolution: {integrity: sha1-yBQzzEJ8ksTc9IZRQtvKbxWs1Zw=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/arg/-/arg-5.0.2.tgz} + resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} argparse@2.0.1: - resolution: {integrity: sha1-JG9Q88p4oyQPbJl+ipvR6sSeSzg=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/argparse/-/argparse-2.0.1.tgz} + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} aria-query@5.3.2: - resolution: {integrity: sha1-k/gaQ0gOM6M48ZFjo9EKUMAdzVk=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/aria-query/-/aria-query-5.3.2.tgz} + resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==} engines: {node: '>= 0.4'} array-iterate@2.0.1: - resolution: {integrity: sha1-bv1D+ClbP+4GJR09YurUvZgF3SQ=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/array-iterate/-/array-iterate-2.0.1.tgz} + resolution: {integrity: sha512-I1jXZMjAgCMmxT4qxXfPXa6SthSoE8h6gkSI9BGGNv8mP8G/v0blc+qFnZu6K42vTOiuME596QaLO0TP3Lk0xg==} asciinema-player@3.17.0: - resolution: {integrity: sha1-bVA+LTZI5ndWlrKI7kkHNgO2vHk=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/asciinema-player/-/asciinema-player-3.17.0.tgz} + resolution: {integrity: sha512-JbjNJmA2TLIeYNaOEja+kVSzXadKoqpIzVVmfBGNj2DmdtE/vExBCnkE8NYEcpaQcDvUYg8Ltt0urT80frACmw==} assertion-error@2.0.1: - resolution: {integrity: sha1-9kGhlrM1aQsQcL8AtudZP+wZC/c=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/assertion-error/-/assertion-error-2.0.1.tgz} + resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} engines: {node: '>=12'} astring@1.9.0: - resolution: {integrity: sha1-zHPmBip+sD59GcItiws0Uf2b/u8=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/astring/-/astring-1.9.0.tgz} + resolution: {integrity: sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==} hasBin: true astro-auto-import@0.5.2: - resolution: {integrity: sha1-qBdnnp9Ns+s1NPpZ65gso0K2O3M=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/astro-auto-import/-/astro-auto-import-0.5.2.tgz} + resolution: {integrity: sha512-C7sxtj0nK4F7AiafNoS8lY/JyqW6/JlnkXTdNIT6CKroV/p4m5j6dkpKEAXZf/7Z+SeDcmAlWI6G1nVMssRRPQ==} engines: {node: '>=20.0.0'} peerDependencies: astro: ^5.0.0 || ^6.0.0 || ^7.0.0 astro-embed@0.13.1: - resolution: {integrity: sha1-7fYdAOAUWMYpGOhwZnvTFjakYAw=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/astro-embed/-/astro-embed-0.13.1.tgz} + resolution: {integrity: sha512-X79C+Uh9wA4JWkBRTk6drLpOfzqpPlibAL/p0MTV2811canAPzF9Sv9Bq3gdUSCDCQXRFxTVsW89CKtDkg8xqA==} peerDependencies: astro: ^5.0.0 || ^6.0.0-alpha || ^7.0.0 astro-expressive-code@0.44.1: - resolution: {integrity: sha1-3ar6xKhrRMmn7mW3WR46pT6lafE=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/astro-expressive-code/-/astro-expressive-code-0.44.1.tgz} + resolution: {integrity: sha512-DT1LnCqbHasBKlvzJ3m6LR4VI94wwx3W9EV/YbP1te4rqjOHsvsezHYuqb5MeLWLftXms/1FA9QBbwCo43DnJQ==} peerDependencies: astro: ^4.0.0-beta || ^5.0.0-beta || ^3.3.0 || ^6.0.0-beta || ^7.0.0 astro-vtbot@3.0.0: - resolution: {integrity: sha1-8OB7UQV2A71a/DkswBB9v7OI1b0=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/astro-vtbot/-/astro-vtbot-3.0.0.tgz} + resolution: {integrity: sha512-jVpYqaPi9Nz5UP9KgDFatSzXIe6n0w2YJjjzdsxNicd2ETQlfOkzbP8Qu7W6HC0DCE4dNTWLs8o7QRiFDqJkfw==} astro@7.3.2: - resolution: {integrity: sha1-InSpTKQ6yzcBTx/FBReuPM5VoaQ=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/astro/-/astro-7.3.2.tgz} + resolution: {integrity: sha512-ysTcdpGP61XZpHoMRYC/CK19DQ94qkBvzXMtXEo0gEqPNkmOU/Tv++CtWmzaI4nF2Ck8RXFdiWvdlTWa2oOr9w==} engines: {node: '>=22.12.0', npm: '>=9.6.5', pnpm: '>=7.1.0'} hasBin: true peerDependencies: @@ -2003,360 +1993,360 @@ packages: optional: true axe-core@4.12.1: - resolution: {integrity: sha1-af4r9t/Asklzr5Gx2OlF954bfEQ=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/axe-core/-/axe-core-4.12.1.tgz} + resolution: {integrity: sha512-s7iGf5GaVMxEG0ENN9x+xTr7GFZCb1ZP/1uATUpCEK2X78nDB3RwbtFCo9pGAf9ru+VwoQ464DkaLEeRM08wJA==} engines: {node: '>=4'} axobject-query@4.1.0: - resolution: {integrity: sha1-KHaMdtDjz/IbxiqeLQtqwwBCoe4=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/axobject-query/-/axobject-query-4.1.0.tgz} + resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} engines: {node: '>= 0.4'} bail@2.0.2: - resolution: {integrity: sha1-0m9c2P5db4MqMVF7n3w1YEC6bV0=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/bail/-/bail-2.0.2.tgz} + resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==} balanced-match@4.0.4: - resolution: {integrity: sha1-v7EGYv7tgZaixi58aOF3IMJ0F5o=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/balanced-match/-/balanced-match-4.0.4.tgz} + resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} engines: {node: 18 || 20 || >=22} base64-js@0.0.8: - resolution: {integrity: sha1-EQHpVE9KdrG8OybUUsqW16NeeXg=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/base64-js/-/base64-js-0.0.8.tgz} + resolution: {integrity: sha512-3XSA2cR/h/73EzlXXdU6YNycmYI7+kicTxks4eJg2g39biHR84slg2+des+p7iHYhbRg/udIS4TD53WabcOUkw==} engines: {node: '>= 0.4'} bcp-47-match@2.0.3: - resolution: {integrity: sha1-YDIm9uXTkUpYFAi+M7KKUxRLCdA=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/bcp-47-match/-/bcp-47-match-2.0.3.tgz} + resolution: {integrity: sha512-JtTezzbAibu8G0R9op9zb3vcWZd9JF6M0xOYGPn0fNCd7wOpRB1mU2mH9T8gaBGbAAyIIVgB2G7xG0GP98zMAQ==} bcp-47@2.1.1: - resolution: {integrity: sha1-8+kNN4shqh26bbOEXbzZW78dqqo=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/bcp-47/-/bcp-47-2.1.1.tgz} + resolution: {integrity: sha512-KLw+H/gd2p4zly1X7Yh/qziuyae5/w/QFnvTng9eZL5fvszL7Whl3MBoWF8yxL7ksUjBfOD+OxkytiqbBpG+Fw==} binary-extensions@2.3.0: - resolution: {integrity: sha1-9uFKl4WNMnJSIAJC1Mz+UixEVSI=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/binary-extensions/-/binary-extensions-2.3.0.tgz} + resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} engines: {node: '>=8'} boolbase@1.0.0: - resolution: {integrity: sha1-aN/1++YMUes3cl6p4+0xDcwed24=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/boolbase/-/boolbase-1.0.0.tgz} + resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} brace-expansion@5.0.9: - resolution: {integrity: sha1-fHJDiAm1+lur9UGZofHCgaaYT88=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/brace-expansion/-/brace-expansion-5.0.9.tgz} + resolution: {integrity: sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg==} engines: {node: 20 || >=22} braces@3.0.3: - resolution: {integrity: sha1-SQMy9AkZRSJy1VqEgK3AxEE1h4k=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/braces/-/braces-3.0.3.tgz} + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} cac@7.0.0: - resolution: {integrity: sha1-fdqD2iJo91+ECriaw7zDbBIKeNo=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/cac/-/cac-7.0.0.tgz} + resolution: {integrity: sha512-tixWYgm5ZoOD+3g6UTea91eow5z6AAHaho3g0V9CNSNb45gM8SmflpAc+GRd1InC4AqN/07Unrgp56Y94N9hJQ==} engines: {node: '>=20.19.0'} camelize@1.0.1: - resolution: {integrity: sha1-ibfhaIQFYzGjXWta0GQzLJHapsM=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/camelize/-/camelize-1.0.1.tgz} + resolution: {integrity: sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==} ccount@2.0.1: - resolution: {integrity: sha1-F6O/gjAuCHDW2kOgExGovAKj7PU=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/ccount/-/ccount-2.0.1.tgz} + resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} chai@6.2.2: - resolution: {integrity: sha1-rkG1LJrKh3NFBTYnF/MlX6zaNg4=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/chai/-/chai-6.2.2.tgz} + resolution: {integrity: sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==} engines: {node: '>=18'} character-entities-html4@2.1.0: - resolution: {integrity: sha1-HxrblAyXGksiujndymthjcblays=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/character-entities-html4/-/character-entities-html4-2.1.0.tgz} + resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==} character-entities-legacy@3.0.0: - resolution: {integrity: sha1-dryDqQc4kB17wiOp6TdZ/dVgEls=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz} + resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==} character-entities@2.0.2: - resolution: {integrity: sha1-LQnC5yzZUjB2zLIRV9/2atQ/zCI=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/character-entities/-/character-entities-2.0.2.tgz} + resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==} character-reference-invalid@2.0.1: - resolution: {integrity: sha1-hcZrBB5DtHIQ+vQBJ4q/gIrEXLk=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz} + resolution: {integrity: sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==} chokidar@3.6.0: - resolution: {integrity: sha1-GXxsxmnvKo3F57TZfuTgksPrDVs=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/chokidar/-/chokidar-3.6.0.tgz} + resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} engines: {node: '>= 8.10.0'} chokidar@5.0.0: - resolution: {integrity: sha1-lJwSapI4qAeSvpoCZZNPCYrzaaU=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/chokidar/-/chokidar-5.0.0.tgz} + resolution: {integrity: sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==} engines: {node: '>= 20.19.0'} ci-info@4.4.0: - resolution: {integrity: sha1-fVTv+fVLRbYkAcJgMmlutZyL0Yw=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/ci-info/-/ci-info-4.4.0.tgz} + resolution: {integrity: sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==} engines: {node: '>=8'} clsx@2.1.1: - resolution: {integrity: sha1-7tOXyf2L2IK/sY3qtxAgSaLzKZk=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/clsx/-/clsx-2.1.1.tgz} + resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} engines: {node: '>=6'} collapse-white-space@2.1.0: - resolution: {integrity: sha1-ZAJXF0+fQsdAtA87Ve51KST+78o=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/collapse-white-space/-/collapse-white-space-2.1.0.tgz} + resolution: {integrity: sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==} color-name@1.1.4: - resolution: {integrity: sha1-wqCah6y95pVD3m9j+jmVyCbFNqI=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/color-name/-/color-name-1.1.4.tgz} + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} colorette@2.0.20: - resolution: {integrity: sha1-nreT5oMwZ/cjWQL807CZF6AAqVo=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/colorette/-/colorette-2.0.20.tgz} + resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} comma-separated-tokens@2.0.3: - resolution: {integrity: sha1-TonJRYrLYbyP7xn0UplzsjkoOe4=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz} + resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} commander@11.1.0: - resolution: {integrity: sha1-Yv3OdgBqaOXBqzMU3JLoAOuD2QY=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/commander/-/commander-11.1.0.tgz} + resolution: {integrity: sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==} engines: {node: '>=16'} commander@7.2.0: - resolution: {integrity: sha1-o2y1fQtQHOEI5NIFWaFQo5HZerc=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/commander/-/commander-7.2.0.tgz} + resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==} engines: {node: '>= 10'} commander@8.3.0: - resolution: {integrity: sha1-SDfqGy2me5xhamevuw+v7lZ7ymY=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/commander/-/commander-8.3.0.tgz} + resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==} engines: {node: '>= 12'} common-ancestor-path@2.0.0: - resolution: {integrity: sha1-8dNhrqkjaq1bkqD/W53xQi3TYP8=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/common-ancestor-path/-/common-ancestor-path-2.0.0.tgz} + resolution: {integrity: sha512-dnN3ibLeoRf2HNC+OlCiNc5d2zxbLJXOtiZUudNFSXZrNSydxcCsSpRzXwfu7BBWCIfHPw+xTayeBvJCP/D8Ng==} engines: {node: '>= 18'} confbox@0.1.8: - resolution: {integrity: sha1-gg1z07PILZvZEGUsXU1Znvj/iwY=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/confbox/-/confbox-0.1.8.tgz} + resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} consola@3.4.2: - resolution: {integrity: sha1-WvEQFFOXu2ev2rdwE/3DTK5ZDqc=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/consola/-/consola-3.4.2.tgz} + resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==} engines: {node: ^14.18.0 || >=16.10.0} convert-source-map@2.0.0: - resolution: {integrity: sha1-S1YPZJ/E6RjdCrdc9JYei8iC2Co=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/convert-source-map/-/convert-source-map-2.0.0.tgz} + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} cookie-es@1.2.3: - resolution: {integrity: sha1-Bso8X181MWhKIFlmajYRc/dKicg=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/cookie-es/-/cookie-es-1.2.3.tgz} + resolution: {integrity: sha512-lXVyvUvrNXblMqzIRrxHb57UUVmqsSWlxqt3XIjCkUP0wDAf6uicO6KMbEgYrMNtEvWgWHwe42CKxPu9MYAnWw==} cookie@2.0.1: - resolution: {integrity: sha1-H8fpvd84+pVnzU11CCAIfNtdbpg=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/cookie/-/cookie-2.0.1.tgz} + resolution: {integrity: sha512-yuToqVvRrj6pfDXREyQAAv8SkAEk/8GS3jQRTiUMm66TVtBYmqQeoEjL2Lmq8Rpo6271vH76InTChTitEAm65w==} engines: {node: '>=22'} cose-base@1.0.3: - resolution: {integrity: sha1-ZQM0tBuGlXilQzWLgM2n4Kvgpgo=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/cose-base/-/cose-base-1.0.3.tgz} + resolution: {integrity: sha512-s9whTXInMSgAp/NVXVNuVxVKzGH2qck3aQlVHxDCdAEPgtMKwc4Wq6/QKhgdEdgbLSi9rBTAcPoRa6JpiG4ksg==} cose-base@2.2.0: - resolution: {integrity: sha1-HDlcNbbhC7g/l2nKi4F9YUrdXAE=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/cose-base/-/cose-base-2.2.0.tgz} + resolution: {integrity: sha512-AzlgcsCbUMymkADOJtQm3wO9S3ltPfYOFD5033keQn9NJzIbtnZj+UdBJe7DYml/8TdbtHJW3j58SOnKhWY/5g==} cross-spawn@7.0.6: - resolution: {integrity: sha1-ilj+ePANzXDDcEUXWd+/rwPo7p8=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/cross-spawn/-/cross-spawn-7.0.6.tgz} + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} crossws@0.3.5: - resolution: {integrity: sha1-2q0zHUQUjqZQAJi8hYhp86WrgaY=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/crossws/-/crossws-0.3.5.tgz} + resolution: {integrity: sha512-ojKiDvcmByhwa8YYqbQI/hg7MEU0NC03+pSdEq4ZUnZR9xXpwk7E43SMNGkn+JxJGPFtNvQ48+vV2p+P1ml5PA==} css-background-parser@0.1.0: - resolution: {integrity: sha1-SKF/f+bU1PG8oxd93xbFYXlQdBs=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/css-background-parser/-/css-background-parser-0.1.0.tgz} + resolution: {integrity: sha512-2EZLisiZQ+7m4wwur/qiYJRniHX4K5Tc9w93MT3AS0WS1u5kaZ4FKXlOTBhOjc+CgEgPiGY+fX1yWD8UwpEqUA==} css-box-shadow@1.0.0-3: - resolution: {integrity: sha1-nq63FAlHv11kn8SaGeS7ql9gJxM=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/css-box-shadow/-/css-box-shadow-1.0.0-3.tgz} + resolution: {integrity: sha512-9jaqR6e7Ohds+aWwmhe6wILJ99xYQbfmK9QQB9CcMjDbTxPZjwEmUQpU91OG05Xgm8BahT5fW+svbsQGjS/zPg==} css-color-keywords@1.0.0: - resolution: {integrity: sha1-/qJhbcZ2spYmhrOvjb2+GAskTgU=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/css-color-keywords/-/css-color-keywords-1.0.0.tgz} + resolution: {integrity: sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==} engines: {node: '>=4'} css-gradient-parser@0.0.17: - resolution: {integrity: sha1-mlI0GfMorSd3rnkMKWppMtRwqpo=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/css-gradient-parser/-/css-gradient-parser-0.0.17.tgz} + resolution: {integrity: sha512-w2Xy9UMMwlKtou0vlRnXvWglPAceXCTtcmVSo8ZBUvqCV5aXEFP/PC6d+I464810I9FT++UACwTD5511bmGPUg==} engines: {node: '>=16'} css-js-gen@1.1.0: - resolution: {integrity: sha1-/KuEg0Z692Cy4uiy+k36cn2TcMI=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/css-js-gen/-/css-js-gen-1.1.0.tgz} + resolution: {integrity: sha512-CuPSTe6EwlrDHcMFOfcO3SwVqclVKLnqSbTGGYzfFt8z2NenGeupp47Z3wx+yhQ2pdozb3R8hc+nyECBTykooQ==} css-select@6.0.0: - resolution: {integrity: sha1-fmPwmIGtEYCECRBI7VQ3htrZZkQ=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/css-select/-/css-select-6.0.0.tgz} + resolution: {integrity: sha512-rZZVSLle8v0+EY8QAkDWrKhpgt6SA5OtHsgBnsj6ZaLb5dmDVOWUDtQitd9ydxxvEjhewNudS6eTVU7uOyzvXw==} css-selector-parser@3.3.0: - resolution: {integrity: sha1-GjQiDXZ2LJKa6ZmT31pgch9QUII=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/css-selector-parser/-/css-selector-parser-3.3.0.tgz} + resolution: {integrity: sha512-Y2asgMGFqJKF4fq4xHDSlFYIkeVfRsm69lQC1q9kbEsH5XtnINTMrweLkjYMeaUgiXBy/uvKeO/a1JHTNnmB2g==} css-to-react-native@3.2.0: - resolution: {integrity: sha1-zdgJn3ECThSeT2/hen1G7NVfHjI=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/css-to-react-native/-/css-to-react-native-3.2.0.tgz} + resolution: {integrity: sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==} css-tree@2.2.1: - resolution: {integrity: sha1-NhFdOC1gr9Jx43f5xfZ9Ar1IwDI=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/css-tree/-/css-tree-2.2.1.tgz} + resolution: {integrity: sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==} engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'} css-tree@3.2.1: - resolution: {integrity: sha1-hsrHARVhJysw5rHgQrps4EeqdRg=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/css-tree/-/css-tree-3.2.1.tgz} + resolution: {integrity: sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA==} engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} css-what@7.0.0: - resolution: {integrity: sha1-V5b769Q1cdc8YLoN16bnXdDSL+Q=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/css-what/-/css-what-7.0.0.tgz} + resolution: {integrity: sha512-wD5oz5xibMOPHzy13CyGmogB3phdvcDaB5t0W/Nr5Z2O/agcB8YwOz6e2Lsp10pNDzBoDO9nVa3RGs/2BttpHQ==} engines: {node: '>= 6'} cssesc@3.0.0: - resolution: {integrity: sha1-N3QZGZA7hoVl4cCep0dEXNGJg+4=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/cssesc/-/cssesc-3.0.0.tgz} + resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} engines: {node: '>=4'} hasBin: true csso@5.0.5: - resolution: {integrity: sha1-+bf+bMasC32QeBuxbV6YdDA+LKY=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/csso/-/csso-5.0.5.tgz} + resolution: {integrity: sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==} engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'} csstype@3.2.3: - resolution: {integrity: sha1-7EjA8+mT5QZIyG2lWeJhCZXPmJo=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/csstype/-/csstype-3.2.3.tgz} + resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} cytoscape-cose-bilkent@4.1.0: - resolution: {integrity: sha1-di+hId+ZMP/rUaSV2HkXxXCsIJs=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/cytoscape-cose-bilkent/-/cytoscape-cose-bilkent-4.1.0.tgz} + resolution: {integrity: sha512-wgQlVIUJF13Quxiv5e1gstZ08rnZj2XaLHGoFMYXz7SkNfCDOOteKBE6SYRfA9WxxI/iBc3ajfDoc6hb/MRAHQ==} peerDependencies: cytoscape: ^3.2.0 cytoscape-fcose@2.2.0: - resolution: {integrity: sha1-5Nb2SQ30+rWK6c6p5cOrjXRy9HE=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/cytoscape-fcose/-/cytoscape-fcose-2.2.0.tgz} + resolution: {integrity: sha512-ki1/VuRIHFCzxWNrsshHYPs6L7TvLu3DL+TyIGEsRcvVERmxokbf5Gdk7mFxZnTdiGtnA4cfSmjZJMviqSuZrQ==} peerDependencies: cytoscape: ^3.2.0 cytoscape@3.34.0: - resolution: {integrity: sha1-X74usc92sHCo7NVkfDX2WqCXycY=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/cytoscape/-/cytoscape-3.34.0.tgz} + resolution: {integrity: sha512-62rNSrioXw93uliKFBwjukeQyeWwH2PqDrTac31r2P6464u3AUvTk0xS4LVvT251g7IgkFunrI48ZEZGjywSOg==} engines: {node: '>=0.10'} d3-array@2.12.1: - resolution: {integrity: sha1-4gtBqvzf/fXVCSgATs7PgVpGXoE=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/d3-array/-/d3-array-2.12.1.tgz} + resolution: {integrity: sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==} d3-array@3.2.4: - resolution: {integrity: sha1-Ff7DOyN/l6xdfJhtx32ic6jtC7U=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/d3-array/-/d3-array-3.2.4.tgz} + resolution: {integrity: sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==} engines: {node: '>=12'} d3-axis@3.0.0: - resolution: {integrity: sha1-xCpKE+gTHWN7dF/Clzgkz+r5MyI=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/d3-axis/-/d3-axis-3.0.0.tgz} + resolution: {integrity: sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==} engines: {node: '>=12'} d3-brush@3.0.0: - resolution: {integrity: sha1-b3Z8Ttjct53n7ePhwPieY+9k0xw=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/d3-brush/-/d3-brush-3.0.0.tgz} + resolution: {integrity: sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==} engines: {node: '>=12'} d3-chord@3.0.1: - resolution: {integrity: sha1-0VbWH0hfzoMn5qvzOctB2Mu6aWY=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/d3-chord/-/d3-chord-3.0.1.tgz} + resolution: {integrity: sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g==} engines: {node: '>=12'} d3-color@3.1.0: - resolution: {integrity: sha1-OVsoM9+scVB/EqwvevI7+BneJOI=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/d3-color/-/d3-color-3.1.0.tgz} + resolution: {integrity: sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==} engines: {node: '>=12'} d3-contour@4.0.2: - resolution: {integrity: sha1-u5IGO8jFZjrLJCL5nHPLtsauO8w=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/d3-contour/-/d3-contour-4.0.2.tgz} + resolution: {integrity: sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA==} engines: {node: '>=12'} d3-delaunay@6.0.4: - resolution: {integrity: sha1-mBaQOHM6ClurvtpVBU95W7nkpYs=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/d3-delaunay/-/d3-delaunay-6.0.4.tgz} + resolution: {integrity: sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==} engines: {node: '>=12'} d3-dispatch@3.0.1: - resolution: {integrity: sha1-X8dShOnCN1w2yDlBGgz1UMv8TV4=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/d3-dispatch/-/d3-dispatch-3.0.1.tgz} + resolution: {integrity: sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==} engines: {node: '>=12'} d3-drag@3.0.0: - resolution: {integrity: sha1-mUqunNI8cZ9TteEOOgphCMaWB7o=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/d3-drag/-/d3-drag-3.0.0.tgz} + resolution: {integrity: sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==} engines: {node: '>=12'} d3-dsv@3.0.1: - resolution: {integrity: sha1-xjr5ePTWoNCEpSpnOSK+IWB4m3M=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/d3-dsv/-/d3-dsv-3.0.1.tgz} + resolution: {integrity: sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==} engines: {node: '>=12'} hasBin: true d3-ease@3.0.1: - resolution: {integrity: sha1-llisOKIUDVnTRhYPH2ww/aC9EvQ=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/d3-ease/-/d3-ease-3.0.1.tgz} + resolution: {integrity: sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==} engines: {node: '>=12'} d3-fetch@3.0.1: - resolution: {integrity: sha1-gxQb/5hWoO21443onNz+Y9CmCiI=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/d3-fetch/-/d3-fetch-3.0.1.tgz} + resolution: {integrity: sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==} engines: {node: '>=12'} d3-force@3.0.0: - resolution: {integrity: sha1-Piuhph5wiI/j2RlOMNbRTuzhVcQ=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/d3-force/-/d3-force-3.0.0.tgz} + resolution: {integrity: sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==} engines: {node: '>=12'} d3-format@3.1.2: - resolution: {integrity: sha1-Af20a1i+sfVbELQq1wtuNE1esq4=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/d3-format/-/d3-format-3.1.2.tgz} + resolution: {integrity: sha512-AJDdYOdnyRDV5b6ArilzCPPwc1ejkHcoyFarqlPqT7zRYjhavcT3uSrqcMvsgh2CgoPbK3RCwyHaVyxYcP2Arg==} engines: {node: '>=12'} d3-geo@3.1.1: - resolution: {integrity: sha1-YCfPUSRvmy69ZPmeAdx8M2QDOk0=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/d3-geo/-/d3-geo-3.1.1.tgz} + resolution: {integrity: sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q==} engines: {node: '>=12'} d3-hierarchy@3.1.2: - resolution: {integrity: sha1-sBzULB7tPUbbd6WWbPcm+MCRYMY=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz} + resolution: {integrity: sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==} engines: {node: '>=12'} d3-interpolate@3.0.1: - resolution: {integrity: sha1-PEeqWzLFs9+1bvP9Q0IHimMrQA0=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/d3-interpolate/-/d3-interpolate-3.0.1.tgz} + resolution: {integrity: sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==} engines: {node: '>=12'} d3-path@1.0.9: - resolution: {integrity: sha1-SMBQux/owmJJOoyvVSTj6VkXAc8=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/d3-path/-/d3-path-1.0.9.tgz} + resolution: {integrity: sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg==} d3-path@3.1.0: - resolution: {integrity: sha1-It+TkDL7WnGuixgA1h3beFHEJSY=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/d3-path/-/d3-path-3.1.0.tgz} + resolution: {integrity: sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==} engines: {node: '>=12'} d3-polygon@3.0.1: - resolution: {integrity: sha1-C0XT3RxIopyOBX5hNWk+yAvxY5g=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/d3-polygon/-/d3-polygon-3.0.1.tgz} + resolution: {integrity: sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg==} engines: {node: '>=12'} d3-quadtree@3.0.1: - resolution: {integrity: sha1-bco+i+Kzk8mp1RTau9gKkt7vGk8=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/d3-quadtree/-/d3-quadtree-3.0.1.tgz} + resolution: {integrity: sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==} engines: {node: '>=12'} d3-random@3.0.1: - resolution: {integrity: sha1-1JJjeNMz2cC/0eb6AZTTCuuqIPQ=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/d3-random/-/d3-random-3.0.1.tgz} + resolution: {integrity: sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==} engines: {node: '>=12'} d3-sankey@0.12.3: - resolution: {integrity: sha1-s8JoYnvXLl2AM26N5qy/7J0V0B0=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/d3-sankey/-/d3-sankey-0.12.3.tgz} + resolution: {integrity: sha512-nQhsBRmM19Ax5xEIPLMY9ZmJ/cDvd1BG3UVvt5h3WRxKg5zGRbvnteTyWAbzeSvlh3tW7ZEmq4VwR5mB3tutmQ==} d3-scale-chromatic@3.1.0: - resolution: {integrity: sha1-NMOdopiyPCDgLxpLI5vQ8i5/ExQ=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz} + resolution: {integrity: sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ==} engines: {node: '>=12'} d3-scale@4.0.2: - resolution: {integrity: sha1-grOOjo/3CAdk+Nzsd71L45Nok5Y=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/d3-scale/-/d3-scale-4.0.2.tgz} + resolution: {integrity: sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==} engines: {node: '>=12'} d3-selection@3.0.0: - resolution: {integrity: sha1-wlM4IH76csxbm9FFihpBkB8eGzE=, tarball: https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/d3-selection/-/d3-selection-3.0.0.tgz} + resolution: {integrity: sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==} engines: {node: '>=12'} d3-shape@1.3.7: - resolution: {integrity: sha1-32OAG+B7yYa8VPY3ibT+UCmStdc=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/d3-shape/-/d3-shape-1.3.7.tgz} + resolution: {integrity: sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==} d3-shape@3.2.0: - resolution: {integrity: sha1-oag5y9m6RfKGdMadf4Vbz5HfxqU=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/d3-shape/-/d3-shape-3.2.0.tgz} + resolution: {integrity: sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==} engines: {node: '>=12'} d3-time-format@4.1.0: - resolution: {integrity: sha1-erUlelBB0R7LT+cKXH0WoZW7QIo=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/d3-time-format/-/d3-time-format-4.1.0.tgz} + resolution: {integrity: sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==} engines: {node: '>=12'} d3-time@3.1.0: - resolution: {integrity: sha1-kxDbVumS48AXXh7zheVF5Iqbtcc=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/d3-time/-/d3-time-3.1.0.tgz} + resolution: {integrity: sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==} engines: {node: '>=12'} d3-timer@3.0.1: - resolution: {integrity: sha1-YoTSonCChbGrt+IB7aQ4CvNeY7A=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/d3-timer/-/d3-timer-3.0.1.tgz} + resolution: {integrity: sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==} engines: {node: '>=12'} d3-transition@3.0.1: - resolution: {integrity: sha1-aGn93hRIhoB3/dWYkgDLYbKhZF8=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/d3-transition/-/d3-transition-3.0.1.tgz} + resolution: {integrity: sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==} engines: {node: '>=12'} peerDependencies: d3-selection: 2 - 3 d3-zoom@3.0.0: - resolution: {integrity: sha1-0T9BZccyF//qpUKVzWlps+eu6PM=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/d3-zoom/-/d3-zoom-3.0.0.tgz} + resolution: {integrity: sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==} engines: {node: '>=12'} d3@7.9.0: - resolution: {integrity: sha1-V556yz10nK+IYL0XQa6NNxBwzV0=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/d3/-/d3-7.9.0.tgz} + resolution: {integrity: sha512-e1U46jVP+w7Iut8Jt8ri1YsPOvFpg46k+K8TpCb0P+zjCkjkPnV7WzfDJzMHy1LnA+wj5pLT1wjO901gLXeEhA==} engines: {node: '>=12'} dagre-d3-es@7.0.14: - resolution: {integrity: sha1-EnInbiZFfPO5faxWn48FMewzw3c=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/dagre-d3-es/-/dagre-d3-es-7.0.14.tgz} + resolution: {integrity: sha512-P4rFMVq9ESWqmOgK+dlXvOtLwYg0i7u0HBGJER0LZDJT2VHIPAMZ/riPxqJceWMStH5+E61QxFra9kIS3AqdMg==} data-uri-to-buffer@4.0.1: - resolution: {integrity: sha1-2P6ysogeak9YwuCKz9Dig04mIi4=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz} + resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==} engines: {node: '>= 12'} dayjs@1.11.21: - resolution: {integrity: sha1-V/h1YuYt5288cEvSuNUi/DMGjrI=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/dayjs/-/dayjs-1.11.21.tgz} + resolution: {integrity: sha512-98IT+HOahAisibz/yjKbzuOBwYcjJ7BCLPzARyHiyEBmRz4fatF+KPJszEHXsGYjUG234aH/cOjW1wwTbKUZlA==} debug@4.4.3: - resolution: {integrity: sha1-xq5DLZvZZiWC/OCHCbA4xY6ePWo=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/debug/-/debug-4.4.3.tgz} + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} engines: {node: '>=6.0'} peerDependencies: supports-color: '*' @@ -2365,148 +2355,148 @@ packages: optional: true decode-named-character-reference@1.3.0: - resolution: {integrity: sha1-PkBgN2CHTC5YZ2kbWZ1zp9oltT8=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/decode-named-character-reference/-/decode-named-character-reference-1.3.0.tgz} + resolution: {integrity: sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==} deep-is@0.1.4: - resolution: {integrity: sha1-pvLc5hL63S7x9Rm3NVHxfoUZmDE=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/deep-is/-/deep-is-0.1.4.tgz} + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} defu@6.1.7: - resolution: {integrity: sha1-clQ1Z8jp+X/xPOQCttvgmsWuTSM=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/defu/-/defu-6.1.7.tgz} + resolution: {integrity: sha512-7z22QmUWiQ/2d0KkdYmANbRUVABpZ9SNYyH5vx6PZ+nE5bcC0l7uFvEfHlyld/HcGBFTL536ClDt3DEcSlEJAQ==} delaunator@5.1.0: - resolution: {integrity: sha1-0TJx+/Ov9nU/nqbiNVV/IJAQRuo=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/delaunator/-/delaunator-5.1.0.tgz} + resolution: {integrity: sha512-AGrQ4QSgssa1NGmWmLPqN5NY2KajF5MqxetNEO+o0n3ZwZZeTmt7bBnvzHWrmkZFxGgr4HdyFgelzgi06otLuQ==} depd@2.0.0: - resolution: {integrity: sha1-tpYWPMdXVg0JzyLMj60Vcbeedt8=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/depd/-/depd-2.0.0.tgz} + resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} engines: {node: '>= 0.8'} dequal@2.0.3: - resolution: {integrity: sha1-JkQhTxmX057Q7g7OcjNUkKesZ74=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/dequal/-/dequal-2.0.3.tgz} + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} engines: {node: '>=6'} destr@2.0.5: - resolution: {integrity: sha1-fREv8bkl+40gefrFvbSpCXO1H9s=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/destr/-/destr-2.0.5.tgz} + resolution: {integrity: sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==} detect-libc@2.1.2: - resolution: {integrity: sha1-aJxdzcGQDvVYOky59te0c3QgdK0=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/detect-libc/-/detect-libc-2.1.2.tgz} + resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} engines: {node: '>=8'} devalue@5.8.1: - resolution: {integrity: sha1-8nKQ06Mk4usgwnFDabAbjsTeTGE=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/devalue/-/devalue-5.8.1.tgz} + resolution: {integrity: sha512-4CXDYRBGqN+57wVJkuXBYmpAVUSg3L6JAQa/DFqm238G73E1wuyc/JhGQJzN7vUf/CMphYau2zXbfWzDR5aTEw==} devlop@1.1.0: - resolution: {integrity: sha1-TbfCyk3G4Og0wwvnDJS7yXbccBg=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/devlop/-/devlop-1.1.0.tgz} + resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} diff@9.0.0: - resolution: {integrity: sha1-KXwxzXwoDxPf4zV5HsIGO9SnOm8=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/diff/-/diff-9.0.0.tgz} + resolution: {integrity: sha512-svtcdpS8CgJyqAjEQIXdb3OjhFVVYjzGAPO8WGCmRbrml64SPw/jJD4GoE98aR7r25A0XcgrK3F02yw9R/vhQw==} engines: {node: '>=0.3.1'} direction@2.0.1: - resolution: {integrity: sha1-cYAN08T6ECQGUCkF04ZuZb3ruYU=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/direction/-/direction-2.0.1.tgz} + resolution: {integrity: sha512-9S6m9Sukh1cZNknO1CWAr2QAWsbKLafQiyM5gZ7VgXHeuaoUwffKN4q6NC4A/Mf9iiPlOXQEKW/Mv/mh9/3YFA==} hasBin: true dom-serializer@2.0.0: - resolution: {integrity: sha1-5BuALh7t+fbK4YPOXmIteJ19jlM=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/dom-serializer/-/dom-serializer-2.0.0.tgz} + resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} domelementtype@2.3.0: - resolution: {integrity: sha1-XEXo6GmVJiYzHXqrMm0B2vZdWJ0=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/domelementtype/-/domelementtype-2.3.0.tgz} + resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} domhandler@5.0.3: - resolution: {integrity: sha1-zDhff3UfHR/GUMITdIBCVFOMfTE=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/domhandler/-/domhandler-5.0.3.tgz} + resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} engines: {node: '>= 4'} dompurify@3.4.13: - resolution: {integrity: sha1-/CiUnVn5LWLiijp2S8vu41iXob4=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/dompurify/-/dompurify-3.4.13.tgz} + resolution: {integrity: sha512-2vmYIoqjze2d+kakP8S/nS5shfsl587kzwEjcGlTdiksUVgFHnFCsLYDVj/JNqJVOQZGSYBTmuycv0PodwmnMQ==} domutils@3.2.2: - resolution: {integrity: sha1-7b/itmiwwdl8JLrw8QYrEyIhvHg=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/domutils/-/domutils-3.2.2.tgz} + resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==} dset@3.1.4: - resolution: {integrity: sha1-+Or18CPwaKA20IzQfcn/t9AGUkg=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/dset/-/dset-3.1.4.tgz} + resolution: {integrity: sha512-2QF/g9/zTaPDc3BjNcVTGoBbXBgYfMTTceLaYcFJ/W9kggFUkhxD/hMEeuLKbugyef9SqAx8cpgwlIP/jinUTA==} engines: {node: '>=4'} duplexer@0.1.2: - resolution: {integrity: sha1-Or5DrvODX4rgd9E23c4PJ2sEAOY=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/duplexer/-/duplexer-0.1.2.tgz} + resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==} ee-first@1.1.1: - resolution: {integrity: sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/ee-first/-/ee-first-1.1.1.tgz} + resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} emoji-regex-xs@2.0.1: - resolution: {integrity: sha1-AS9OTYjs7IOX3zLVtO+J1CJVnA4=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/emoji-regex-xs/-/emoji-regex-xs-2.0.1.tgz} + resolution: {integrity: sha512-1QFuh8l7LqUcKe24LsPUNzjrzJQ7pgRwp1QMcZ5MX6mFplk2zQ08NVCM84++1cveaUUYtcCYHmeFEuNg16sU4g==} engines: {node: '>=10.0.0'} encodeurl@2.0.0: - resolution: {integrity: sha1-e46omAd9fkCdOsRUdOo46vCFelg=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/encodeurl/-/encodeurl-2.0.0.tgz} + resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} engines: {node: '>= 0.8'} entities@4.5.0: - resolution: {integrity: sha1-XSaOpecRPsdMTQM7eepaNaSI+0g=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/entities/-/entities-4.5.0.tgz} + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} engines: {node: '>=0.12'} entities@6.0.1: - resolution: {integrity: sha1-wow0pDN5yn9h0HQTCy9fcCCjBpQ=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/entities/-/entities-6.0.1.tgz} + resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==} engines: {node: '>=0.12'} entities@7.0.1: - resolution: {integrity: sha1-JuioiInbY0F9y5oeeaPxvJK1l2s=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/entities/-/entities-7.0.1.tgz} + resolution: {integrity: sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==} engines: {node: '>=0.12'} entities@8.0.0: - resolution: {integrity: sha1-wd9f42AkKXR/ojPQ3SbxQvDOR0M=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/entities/-/entities-8.0.0.tgz} + resolution: {integrity: sha512-zwfzJecQ/Uej6tusMqwAqU/6KL2XaB2VZ2Jg54Je6ahNBGNH6Ek6g3jjNCF0fG9EWQKGZNddNjU5F1ZQn/sBnA==} engines: {node: '>=20.19.0'} environment@1.1.0: - resolution: {integrity: sha1-jobGaxgPNjx6sxF4fgJZZl9FqfE=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/environment/-/environment-1.1.0.tgz} + resolution: {integrity: sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==} engines: {node: '>=18'} es-module-lexer@2.3.1: - resolution: {integrity: sha1-W/LfBpmdu+XwBqX0ahH7n1t7ORs=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/es-module-lexer/-/es-module-lexer-2.3.1.tgz} + resolution: {integrity: sha512-shc1dbU90Yl/xq1QrC7QRtfcwURZuVRfPhZbDoldJ1cn1gzDvBaBWlv0eFolj5+0znnPJz5TXLxsN77X/12KTA==} es-toolkit@1.50.0: - resolution: {integrity: sha1-JmXCHQq3Yob0eOzjojVGMJeuq9M=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/es-toolkit/-/es-toolkit-1.50.0.tgz} + resolution: {integrity: sha512-OyZKhUVvEep9ITEiwHn8GKnMRQIVqoSIX7WnRbkWgJkllCujilqP2rD0u979tkl8wqyc8ICwlc1UBVv/Sl1G6w==} esast-util-from-estree@2.0.0: - resolution: {integrity: sha1-jRz7Ua1TTS8VncJQ5gTzR4p58a0=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/esast-util-from-estree/-/esast-util-from-estree-2.0.0.tgz} + resolution: {integrity: sha512-4CyanoAudUSBAn5K13H4JhsMH6L9ZP7XbLVe/dKybkxMO7eDyLsT8UHl9TRNrU2Gr9nz+FovfSIjuXWJ81uVwQ==} esast-util-from-js@2.0.1: - resolution: {integrity: sha1-UUe+w0zJ2kSsz1L4fyOaQKw+giU=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/esast-util-from-js/-/esast-util-from-js-2.0.1.tgz} + resolution: {integrity: sha512-8Ja+rNJ0Lt56Pcf3TAmpBZjmx8ZcK5Ts4cAzIOjsjevg9oSXJnl6SUQ2EevU8tv3h6ZLWmoKL5H4fgWvdvfETw==} esbuild@0.28.1: - resolution: {integrity: sha1-70W0Y0ycnZeilq6kEUpfmED5VXg=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/esbuild/-/esbuild-0.28.1.tgz} + resolution: {integrity: sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==} engines: {node: '>=18'} hasBin: true escape-html@1.0.3: - resolution: {integrity: sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/escape-html/-/escape-html-1.0.3.tgz} + resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} escape-string-regexp@4.0.0: - resolution: {integrity: sha1-FLqDpdNz49MR5a/KKc9b+tllvzQ=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz} + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} engines: {node: '>=10'} escape-string-regexp@5.0.0: - resolution: {integrity: sha1-RoMSa1ALYXYvLb66zhgG6L4xscg=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz} + resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} engines: {node: '>=12'} eslint-config-prettier@10.1.8: - resolution: {integrity: sha1-FXNM5K+MJ3jMMvCwGzewtc0ey5c=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/eslint-config-prettier/-/eslint-config-prettier-10.1.8.tgz} + resolution: {integrity: sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==} hasBin: true peerDependencies: eslint: '>=7.0.0' eslint-scope@9.1.2: - resolution: {integrity: sha1-ud5qzi+rHP8k0uWNhbdMj86jmAI=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/eslint-scope/-/eslint-scope-9.1.2.tgz} + resolution: {integrity: sha512-xS90H51cKw0jltxmvmHy2Iai1LIqrfbw57b79w/J7MfvDfkIkFZ+kj6zC3BjtUwh150HsSSdxXZcsuv72miDFQ==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} eslint-visitor-keys@3.4.3: - resolution: {integrity: sha1-DNcv6FUOPC6uFWqWpN3c0cisWAA=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz} + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} eslint-visitor-keys@5.0.1: - resolution: {integrity: sha1-njyUiWl4JNLUzjqK0SYo+R6fWb4=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz} + resolution: {integrity: sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} eslint@10.7.0: - resolution: {integrity: sha1-zTuAIvOx47GDdg2Q38WOnTZEEGs=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/eslint/-/eslint-10.7.0.tgz} + resolution: {integrity: sha512-GVTD7s1vdIl6UYvAfriOPeY1Df8LIZjfofLvHwde+erDHGGuHyuM6xoxRxmHiebhYuD2p1vN4wWh0XzPARSGDQ==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} hasBin: true peerDependencies: @@ -2516,110 +2506,110 @@ packages: optional: true esm-env@1.2.2: - resolution: {integrity: sha1-JjyUVcVYYfQWGN8xsgy1cfwgt14=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/esm-env/-/esm-env-1.2.2.tgz} + resolution: {integrity: sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA==} espree@11.2.0: - resolution: {integrity: sha1-AdXkfcMyqrowWQCDYkVKjMNMyqU=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/espree/-/espree-11.2.0.tgz} + resolution: {integrity: sha512-7p3DrVEIopW1B1avAGLuCSh1jubc01H2JHc8B4qqGblmg5gI9yumBgACjWo4JlIc04ufug4xJ3SQI8HkS/Rgzw==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} esquery@1.7.0: - resolution: {integrity: sha1-CNBI8mHw3e21uulfRoCUY9nJSW0=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/esquery/-/esquery-1.7.0.tgz} + resolution: {integrity: sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==} engines: {node: '>=0.10'} esrecurse@4.3.0: - resolution: {integrity: sha1-eteWTWeauyi+5yzsY3WLHF0smSE=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/esrecurse/-/esrecurse-4.3.0.tgz} + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} engines: {node: '>=4.0'} estraverse@5.3.0: - resolution: {integrity: sha1-LupSkHAvJquP5TcDcP+GyWXSESM=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/estraverse/-/estraverse-5.3.0.tgz} + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} engines: {node: '>=4.0'} estree-util-attach-comments@3.0.0: - resolution: {integrity: sha1-NEveamTIox0VIx5e6eKXVmppHC0=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/estree-util-attach-comments/-/estree-util-attach-comments-3.0.0.tgz} + resolution: {integrity: sha512-cKUwm/HUcTDsYh/9FgnuFqpfquUbwIqwKM26BVCGDPVgvaCl/nDCCjUfiLlx6lsEZ3Z4RFxNbOQ60pkaEwFxGw==} estree-util-build-jsx@3.0.1: - resolution: {integrity: sha1-ttC87R3MTwbyXPDO2istyvmBaPE=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/estree-util-build-jsx/-/estree-util-build-jsx-3.0.1.tgz} + resolution: {integrity: sha512-8U5eiL6BTrPxp/CHbs2yMgP8ftMhR5ww1eIKoWRMlqvltHF8fZn5LRDvTKuxD3DUn+shRbLGqXemcP51oFCsGQ==} estree-util-is-identifier-name@3.0.0: - resolution: {integrity: sha1-C170xP8TUIs03NAez6lF9h/OXb0=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/estree-util-is-identifier-name/-/estree-util-is-identifier-name-3.0.0.tgz} + resolution: {integrity: sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==} estree-util-scope@1.0.0: - resolution: {integrity: sha1-nL38d/XLUePZ7UrZxK2/8i1D5YU=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/estree-util-scope/-/estree-util-scope-1.0.0.tgz} + resolution: {integrity: sha512-2CAASclonf+JFWBNJPndcOpA8EMJwa0Q8LUFJEKqXLW6+qBvbFZuF5gItbQOs/umBUkjviCSDCbBwU2cXbmrhQ==} estree-util-to-js@2.0.0: - resolution: {integrity: sha1-EKb7kkgU5qu2K+zw0rxN6lHQTxc=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/estree-util-to-js/-/estree-util-to-js-2.0.0.tgz} + resolution: {integrity: sha512-WDF+xj5rRWmD5tj6bIqRi6CkLIXbbNQUcxQHzGysQzvHmdYG2G7p/Tf0J0gpxGgkeMZNTIjT/AoSvC9Xehcgdg==} estree-util-visit@2.0.0: - resolution: {integrity: sha1-E6mp9A/1DtDAIvgx3fS1jQVEb+s=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/estree-util-visit/-/estree-util-visit-2.0.0.tgz} + resolution: {integrity: sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww==} estree-walker@2.0.2: - resolution: {integrity: sha1-UvAQF4wqTBF6d1fP6UKtt9LaTKw=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/estree-walker/-/estree-walker-2.0.2.tgz} + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} estree-walker@3.0.3: - resolution: {integrity: sha1-Z8PlSexAKkh7T8GT0ZU6UkdSNA0=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/estree-walker/-/estree-walker-3.0.3.tgz} + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} esutils@2.0.3: - resolution: {integrity: sha1-dNLrTeC42hKTcRkQ1Qd1ubcQ72Q=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/esutils/-/esutils-2.0.3.tgz} + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} engines: {node: '>=0.10.0'} etag@1.8.1: - resolution: {integrity: sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/etag/-/etag-1.8.1.tgz} + resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} engines: {node: '>= 0.6'} eventemitter3@5.0.4: - resolution: {integrity: sha1-qG1mFwQzcS3egUcHrFK1JxzrH+s=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/eventemitter3/-/eventemitter3-5.0.4.tgz} + resolution: {integrity: sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==} expect-type@1.4.0: - resolution: {integrity: sha1-JO338MxppE0AhWe6RZSrlvPDo9Y=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/expect-type/-/expect-type-1.4.0.tgz} + resolution: {integrity: sha512-KfYbmpRm0VbLjEvVa9yGwCi9GI34xvi7A/HXYWQO65CSD2u3MczUJSuwXKFIxlGsgBQizV9q5J9NHj4VG0n+pA==} engines: {node: '>=12.0.0'} expressive-code-twoslash@0.6.1: - resolution: {integrity: sha1-vwatgoVXbxZiUxNeTqX4xHfat3k=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/expressive-code-twoslash/-/expressive-code-twoslash-0.6.1.tgz} + resolution: {integrity: sha512-aEeKBgqg6cF4rQPxT5BHNbRffwsA66zWkNT/Y7CcUIE8eHW6KJHPCnZrGCLxvQ5xRd+qWj7ZXq84gT2zd2ECbg==} peerDependencies: '@expressive-code/core': ^0.41.7 expressive-code: ^0.41.7 typescript: ^5.5.0 expressive-code@0.44.1: - resolution: {integrity: sha1-gaKP35qNRiJv8qNkoTtlQITGe2E=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/expressive-code/-/expressive-code-0.44.1.tgz} + resolution: {integrity: sha512-GakidxhapWDzpKLqEaFQ8wGk6gAqEtPQibu8+yPBfnDLgev5Vdsh1pasTxnrXL/mzIknyqeTwhMHTghdaiUrTg==} extend@3.0.2: - resolution: {integrity: sha1-+LETa0Bx+9jrFAr/hYsQGewpFfo=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/extend/-/extend-3.0.2.tgz} + resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} fast-deep-equal@3.1.3: - resolution: {integrity: sha1-On1WtVnWy8PrUSMlJE5hmmXGxSU=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz} + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} fast-glob@3.3.3: - resolution: {integrity: sha1-0G1YXOjbqQoWsFBcVDw8z7OuuBg=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/fast-glob/-/fast-glob-3.3.3.tgz} + resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} engines: {node: '>=8.6.0'} fast-json-stable-stringify@2.1.0: - resolution: {integrity: sha1-h0v2nG9ATCtdmcSBNBOZ/VWJJjM=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz} + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} fast-levenshtein@2.0.6: - resolution: {integrity: sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz} + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} fast-string-truncated-width@3.0.3: - resolution: {integrity: sha1-I6/g2mfXUsoHJ1OPHmlndZcozkk=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/fast-string-truncated-width/-/fast-string-truncated-width-3.0.3.tgz} + resolution: {integrity: sha512-0jjjIEL6+0jag3l2XWWizO64/aZVtpiGE3t0Zgqxv0DPuxiMjvB3M24fCyhZUO4KomJQPj3LTSUnDP3GpdwC0g==} fast-string-width@3.0.2: - resolution: {integrity: sha1-FturtJHOVYW17LZ1tlwWXXFojus=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/fast-string-width/-/fast-string-width-3.0.2.tgz} + resolution: {integrity: sha512-gX8LrtNEI5hq8DVUfRQMbr5lpaS4nMIWV+7XEbXk2b8kiQIizgnlr12B4dA3ZEx3308ze0O4Q1R+cHts8kyUJg==} fast-wrap-ansi@0.2.2: - resolution: {integrity: sha1-lelSoBRbzj9ZrVbhefhMSNQHKTU=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/fast-wrap-ansi/-/fast-wrap-ansi-0.2.2.tgz} + resolution: {integrity: sha512-7F2Fl+TjRSenLqlU3UjSH0iyqopqoZIu7eZVpEirP2g1GtWa2G/ecEmBdgz31+Mxr+ELclgg6sokpSFIQiZ02Q==} fast-xml-builder@1.3.0: - resolution: {integrity: sha1-vISYBHlv5Hv5FQIt2Tmw/DC6RV0=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/fast-xml-builder/-/fast-xml-builder-1.3.0.tgz} + resolution: {integrity: sha512-F74cZEdCvuw9P41GAC3rod4X04jjWGM1JPEv/GWSqFTWLsdyMSBMBMlm9Hk3GLBgLBbdBNY8yee0pQh2RBVESQ==} fast-xml-parser@5.10.1: - resolution: {integrity: sha1-GTE/fJOGxH+kod5SdUe3PtLPzt4=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/fast-xml-parser/-/fast-xml-parser-5.10.1.tgz} + resolution: {integrity: sha512-IEMIf7298kXuZSRFoGfMYrl7is8LpavODgbNz1cwIudv7KwVFnuU+UsMporfq6PD6aXSlawZlARiA3UywCTfMw==} hasBin: true fastq@1.20.1: - resolution: {integrity: sha1-ynUKENySW8ixiDn9ID4+9LPO1nU=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/fastq/-/fastq-1.20.1.tgz} + resolution: {integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==} fdir@6.5.0: - resolution: {integrity: sha1-7Sq5Z6MxreYvGNB32uGSaE1Q01A=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/fdir/-/fdir-6.5.0.tgz} + resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} engines: {node: '>=12.0.0'} peerDependencies: picomatch: ^3 || ^4 @@ -2628,204 +2618,204 @@ packages: optional: true fetch-blob@3.2.0: - resolution: {integrity: sha1-8JuNS71Frcbwwgt+eH55PjCdzOk=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/fetch-blob/-/fetch-blob-3.2.0.tgz} + resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==} engines: {node: ^12.20 || >= 14.13} fflate@0.7.5: - resolution: {integrity: sha1-Hfy3GJvBBNWZ2gQ26s4U7Sbeh58=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/fflate/-/fflate-0.7.5.tgz} + resolution: {integrity: sha512-QieYf//cis6ywHNi5qW1+PXPQ4bC+XVJAtS4AXIML8P76GroEiOxm/oQtn1f02UkJY1+KsXMJcC+R2v/Eg4G3g==} file-entry-cache@8.0.0: - resolution: {integrity: sha1-d4e93PETG/+5JjbGlFe7wO3W2B8=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/file-entry-cache/-/file-entry-cache-8.0.0.tgz} + resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} engines: {node: '>=16.0.0'} fill-range@7.1.1: - resolution: {integrity: sha1-RCZdPKwH4+p9wkdRY4BkN1SgUpI=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/fill-range/-/fill-range-7.1.1.tgz} + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} find-proc@0.1.0: - resolution: {integrity: sha1-zV5yLGkiE2VtmviIh/wEpKexigY=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/find-proc/-/find-proc-0.1.0.tgz} + resolution: {integrity: sha512-OaOpEYv2PiQ7SQ5LIrl+deA1XaWcxEjnpM6VuWXTUvn+teIXxeFTLDmu18/zDQpFmHN4o3oDBX+BT0AGwEhemg==} engines: {node: ^20.19.0 || >=22.12.0} find-up@5.0.0: - resolution: {integrity: sha1-TJKBnstwg1YeT0okCoa+UZj1Nvw=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/find-up/-/find-up-5.0.0.tgz} + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} engines: {node: '>=10'} flat-cache@4.0.1: - resolution: {integrity: sha1-Ds45/LFO4BL0sEEL0z3ZwfAREnw=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/flat-cache/-/flat-cache-4.0.1.tgz} + resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} engines: {node: '>=16'} flatted@3.4.2: - resolution: {integrity: sha1-9cI8EH8PN96NvfJPE3IrO5jVJyY=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/flatted/-/flatted-3.4.2.tgz} + resolution: {integrity: sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==} flattie@1.1.1: - resolution: {integrity: sha1-iBgiNXIxE2Z9NiF/7FU1knXW/j0=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/flattie/-/flattie-1.1.1.tgz} + resolution: {integrity: sha512-9UbaD6XdAL97+k/n+N7JwX46K/M6Zc6KcFYskrYL8wbBV/Uyk0CTAMY0VT+qiK5PM7AIc9aTWYtq65U7T+aCNQ==} engines: {node: '>=8'} fontace@0.4.1: - resolution: {integrity: sha1-3ip2zzYQiAFpAabyqPK9AWya6EQ=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/fontace/-/fontace-0.4.1.tgz} + resolution: {integrity: sha512-lDMvbAzSnHmbYMTEld5qdtvNH2/pWpICOqpean9IgC7vUbUJc3k+k5Dokp85CegamqQpFbXf0rAVkbzpyTA8aw==} fontkitten@1.0.3: - resolution: {integrity: sha1-u6/e3bseBUln8IRv3HV6zKuIu2g=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/fontkitten/-/fontkitten-1.0.3.tgz} + resolution: {integrity: sha512-Wp1zXWPVUPBmfoa3Cqc9ctaKuzKAV6uLstRqlR56kSjplf5uAce+qeyYym7F+PHbGTk+tCEdkCW6RD7DX/gBZw==} engines: {node: '>=20'} foreground-child@3.3.1: - resolution: {integrity: sha1-Mujp7Rtoo0l777msK2rfkqY4V28=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/foreground-child/-/foreground-child-3.3.1.tgz} + resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} engines: {node: '>=14'} formdata-polyfill@4.0.10: - resolution: {integrity: sha1-JIB8McnUAuACqz2McgFEzriEhCM=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz} + resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==} engines: {node: '>=12.20.0'} fresh@2.0.0: - resolution: {integrity: sha1-jdffahs6Gzpc8YbAWl3SZ2ImNaQ=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/fresh/-/fresh-2.0.0.tgz} + resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==} engines: {node: '>= 0.8'} fsevents@2.3.2: - resolution: {integrity: sha1-ilJveLj99GI7cJ4Ll1xSwkwC/Ro=, tarball: https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/fsevents/-/fsevents-2.3.2.tgz} + resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} os: [darwin] fsevents@2.3.3: - resolution: {integrity: sha1-ysZAd4XQNnWipeGlMFxpezR9kNY=, tarball: https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/fsevents/-/fsevents-2.3.3.tgz} + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} os: [darwin] get-port@7.2.0: - resolution: {integrity: sha1-2w1S6y2JiQzcAQ7Q6aby1LeMu+c=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/get-port/-/get-port-7.2.0.tgz} + resolution: {integrity: sha512-afP4W205ONCuMoPBqcR6PSXnzX35KTcJygfJfcp+QY+uwm3p20p1YczWXhlICIzGMCxYBQcySEcOgsJcrkyobg==} engines: {node: '>=16'} get-tsconfig@5.0.0-beta.4: - resolution: {integrity: sha1-SOHISRnRb9Ht/r0E6JWNqUKUXCU=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/get-tsconfig/-/get-tsconfig-5.0.0-beta.4.tgz} + resolution: {integrity: sha512-7nF7C9fIPFEMHgEMEfgIlO9wDdZ8CyHw27rWciFZfHvHDReIiPhsYuzPRXsfvBCqFy1l8RRyyWV7QLM+ZhUJsQ==} engines: {node: '>=20.20.0'} github-slugger@2.0.0: - resolution: {integrity: sha1-Us8vknmiHrbFndOFtBDwwK3ajxo=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/github-slugger/-/github-slugger-2.0.0.tgz} + resolution: {integrity: sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==} glob-parent@5.1.2: - resolution: {integrity: sha1-hpgyxYA0/mikCTwX3BXoNA2EAcQ=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/glob-parent/-/glob-parent-5.1.2.tgz} + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} glob-parent@6.0.2: - resolution: {integrity: sha1-bSN9mQg5UMeSkPJMdkKj3poo+eM=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/glob-parent/-/glob-parent-6.0.2.tgz} + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} engines: {node: '>=10.13.0'} glob@11.1.0: - resolution: {integrity: sha1-T4JlduTrmcfa04N5PS+fCPZ+UKY=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/glob/-/glob-11.1.0.tgz} + resolution: {integrity: sha512-vuNwKSaKiqm7g0THUBu2x7ckSs3XJLXE+2ssL7/MfTGPLLcrJQ/4Uq1CjPTtO5cCIiRxqvN6Twy1qOwhL0Xjcw==} engines: {node: 20 || >=22} deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me hasBin: true globals@17.7.0: - resolution: {integrity: sha1-VT1VCQtN3oIJ7C2kJYDW5+fYsQ0=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/globals/-/globals-17.7.0.tgz} + resolution: {integrity: sha512-Czmyns5dUsq4seFBR/Kdydhmo8y9kC79hiSkPn0YcGtNnYWnrgt0vjrSjx9tspoDGWm2CMarffRuLjM4xUz8xg==} engines: {node: '>=18'} gzip-size@6.0.0: - resolution: {integrity: sha1-BlNn/VDCOcBnHLy61b4+LusQ5GI=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/gzip-size/-/gzip-size-6.0.0.tgz} + resolution: {integrity: sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==} engines: {node: '>=10'} h3@1.15.11: - resolution: {integrity: sha1-gxF5/GtLwG3orRB356XH1jt5ZXc=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/h3/-/h3-1.15.11.tgz} + resolution: {integrity: sha512-L3THSe2MPeBwgIZVSH5zLdBBU90TOxarvhK9d04IDY2AmVS8j2Jz2LIWtwsGOU3lu2I5jCN7FNvVfY2+XyF+mg==} hachure-fill@0.5.2: - resolution: {integrity: sha1-0ZvEzIdQpZYrR/sTAFV6hfz5NMw=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/hachure-fill/-/hachure-fill-0.5.2.tgz} + resolution: {integrity: sha512-3GKBOn+m2LX9iq+JC1064cSFprJY4jL1jCXTcpnfER5HYE2l/4EfWSGzkPa/ZDBmYI0ZOEj5VHV/eKnPGkHuOg==} has-flag@5.0.1: - resolution: {integrity: sha1-VIPbKuAqRy0dBpFGL8WH0YQ82UA=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/has-flag/-/has-flag-5.0.1.tgz} + resolution: {integrity: sha512-CsNUt5x9LUdx6hnk/E2SZLsDyvfqANZSUq4+D3D8RzDJ2M+HDTIkF60ibS1vHaK55vzgiZw1bEPFG9yH7l33wA==} engines: {node: '>=12'} hast-util-embedded@3.0.0: - resolution: {integrity: sha1-vkR3eA+74HnNuiKYLjV6DeS6hT4=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/hast-util-embedded/-/hast-util-embedded-3.0.0.tgz} + resolution: {integrity: sha512-naH8sld4Pe2ep03qqULEtvYr7EjrLK2QHY8KJR6RJkTUjPGObe1vnx585uzem2hGra+s1q08DZZpfgDVYRbaXA==} hast-util-format@1.1.0: - resolution: {integrity: sha1-Nz53OC4H3rBPZnbxtEN+fYVJ2YU=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/hast-util-format/-/hast-util-format-1.1.0.tgz} + resolution: {integrity: sha512-yY1UDz6bC9rDvCWHpx12aIBGRG7krurX0p0Fm6pT547LwDIZZiNr8a+IHDogorAdreULSEzP82Nlv5SZkHZcjA==} hast-util-from-html@2.0.3: - resolution: {integrity: sha1-SFx0eFNYvrgMS6Y0YpkxGsTEnII=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/hast-util-from-html/-/hast-util-from-html-2.0.3.tgz} + resolution: {integrity: sha512-CUSRHXyKjzHov8yKsQjGOElXy/3EKpyX56ELnkHH34vDVw1N1XSQ1ZcAvTyAPtGqLTuKP/uxM+aLkSPqF/EtMw==} hast-util-from-parse5@8.0.3: - resolution: {integrity: sha1-gwo1Ai//KMP+o2l6mML0zGuDWi4=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/hast-util-from-parse5/-/hast-util-from-parse5-8.0.3.tgz} + resolution: {integrity: sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg==} hast-util-has-property@3.0.0: - resolution: {integrity: sha1-TllePN24zlMOqS9vxBEagY2Of5M=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/hast-util-has-property/-/hast-util-has-property-3.0.0.tgz} + resolution: {integrity: sha512-MNilsvEKLFpV604hwfhVStK0usFY/QmM5zX16bo7EjnAEGofr5YyI37kzopBlZJkHD4t887i+q/C8/tr5Q94cA==} hast-util-is-body-ok-link@3.0.1: - resolution: {integrity: sha1-72PLLxTwTs93UTnNkr2lAmOA2LQ=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/hast-util-is-body-ok-link/-/hast-util-is-body-ok-link-3.0.1.tgz} + resolution: {integrity: sha512-0qpnzOBLztXHbHQenVB8uNuxTnm/QBFUOmdOSsEn7GnBtyY07+ENTWVFBAnXd/zEgd9/SUG3lRY7hSIBWRgGpQ==} hast-util-is-element@3.0.0: - resolution: {integrity: sha1-bjGmUywhfltTOEjH5Sydk2nKCTI=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/hast-util-is-element/-/hast-util-is-element-3.0.0.tgz} + resolution: {integrity: sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==} hast-util-minify-whitespace@1.0.1: - resolution: {integrity: sha1-dYj9GlP0jx0wQGuBlZ3/w2UNr1U=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/hast-util-minify-whitespace/-/hast-util-minify-whitespace-1.0.1.tgz} + resolution: {integrity: sha512-L96fPOVpnclQE0xzdWb/D12VT5FabA7SnZOUMtL1DbXmYiHJMXZvFkIZfiMmTCNJHUeO2K9UYNXoVyfz+QHuOw==} hast-util-parse-selector@4.0.0: - resolution: {integrity: sha1-NSh5+obiVhYDYDfdiTH7XzTLSic=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/hast-util-parse-selector/-/hast-util-parse-selector-4.0.0.tgz} + resolution: {integrity: sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==} hast-util-phrasing@3.0.1: - resolution: {integrity: sha1-+ihMDNSoKg3WAg3oMAp7Hr/6FpA=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/hast-util-phrasing/-/hast-util-phrasing-3.0.1.tgz} + resolution: {integrity: sha512-6h60VfI3uBQUxHqTyMymMZnEbNl1XmEGtOxxKYL7stY2o601COo62AWAYBQR9lZbYXYSBoxag8UpPRXK+9fqSQ==} hast-util-raw@9.1.0: - resolution: {integrity: sha1-ebZrJvb2j7UN+0cWss3KkNkq3y4=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/hast-util-raw/-/hast-util-raw-9.1.0.tgz} + resolution: {integrity: sha512-Y8/SBAHkZGoNkpzqqfCldijcuUKh7/su31kEBp67cFY09Wy0mTRgtsLYsiIxMJxlu0f6AA5SUTbDR8K0rxnbUw==} hast-util-select@6.0.4: - resolution: {integrity: sha1-HY9pZXpXRB0M4K3jWIeHTT5lowM=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/hast-util-select/-/hast-util-select-6.0.4.tgz} + resolution: {integrity: sha512-RqGS1ZgI0MwxLaKLDxjprynNzINEkRHY2i8ln4DDjgv9ZhcYVIHN9rlpiYsqtFwrgpYU361SyWDQcGNIBVu3lw==} hast-util-to-estree@3.1.3: - resolution: {integrity: sha1-5lTByTdGRRNWlcwKufcLj8r3M9c=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/hast-util-to-estree/-/hast-util-to-estree-3.1.3.tgz} + resolution: {integrity: sha512-48+B/rJWAp0jamNbAAf9M7Uf//UVqAoMmgXhBdxTDJLGKY+LRnZ99qcG+Qjl5HfMpYNzS5v4EAwVEF34LeAj7w==} hast-util-to-html@9.0.5: - resolution: {integrity: sha1-zMZzpVu46Fd1sIrCg4D3LUcWcAU=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/hast-util-to-html/-/hast-util-to-html-9.0.5.tgz} + resolution: {integrity: sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==} hast-util-to-jsx-runtime@2.3.6: - resolution: {integrity: sha1-/zGJeq5Z9iIy4hWU6sfva2MzPpg=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.6.tgz} + resolution: {integrity: sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==} hast-util-to-mdast@10.1.2: - resolution: {integrity: sha1-vHb39fcvLN5NamatTNCrqCu3mQk=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/hast-util-to-mdast/-/hast-util-to-mdast-10.1.2.tgz} + resolution: {integrity: sha512-FiCRI7NmOvM4y+f5w32jPRzcxDIz+PUqDwEqn1A+1q2cdp3B8Gx7aVrXORdOKjMNDQsD1ogOr896+0jJHW1EFQ==} hast-util-to-parse5@8.0.1: - resolution: {integrity: sha1-lao5HMBRS0lRQY0ByIPRA4r0L10=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/hast-util-to-parse5/-/hast-util-to-parse5-8.0.1.tgz} + resolution: {integrity: sha512-MlWT6Pjt4CG9lFCjiz4BH7l9wmrMkfkJYCxFwKQic8+RTZgWPuWxwAfjJElsXkex7DJjfSJsQIt931ilUgmwdA==} hast-util-to-string@3.0.1: - resolution: {integrity: sha1-pPFeaChJMm3SEclxKclLDD52Unw=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/hast-util-to-string/-/hast-util-to-string-3.0.1.tgz} + resolution: {integrity: sha512-XelQVTDWvqcl3axRfI0xSeoVKzyIFPwsAGSLIsKdJKQMXDYJS4WYrBNF/8J7RdhIcFI2BOHgAifggsvsxp/3+A==} hast-util-to-text@4.0.2: - resolution: {integrity: sha1-V7Z2kx5xv5y4UkU2eElbMIC/rj4=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/hast-util-to-text/-/hast-util-to-text-4.0.2.tgz} + resolution: {integrity: sha512-KK6y/BN8lbaq654j7JgBydev7wuNMcID54lkRav1P0CaE1e47P72AWWPiGKXTJU271ooYzcvTAn/Zt0REnvc7A==} hast-util-whitespace@3.0.0: - resolution: {integrity: sha1-d3jtnTyS3Z6MXI9kiknCH8UctiE=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz} + resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==} hastscript@9.0.1: - resolution: {integrity: sha1-28hL72BR1ACENCwinEUc2dxWff8=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/hastscript/-/hastscript-9.0.1.tgz} + resolution: {integrity: sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w==} hex-rgb@4.3.0: - resolution: {integrity: sha1-r16XToO7L+/kTVUYKwBOyBjAd3Y=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/hex-rgb/-/hex-rgb-4.3.0.tgz} + resolution: {integrity: sha512-Ox1pJVrDCyGHMG9CFg1tmrRUMRPRsAWYc/PinY0XzJU4K7y7vjNoLKIQ7BR5UJMCxNN8EM1MNDmHWA/B3aZUuw==} engines: {node: '>=6'} html-escaper@3.0.3: - resolution: {integrity: sha1-TTNmdGUr6x3Lwp72trp/a+b9/tY=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/html-escaper/-/html-escaper-3.0.3.tgz} + resolution: {integrity: sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ==} html-void-elements@3.0.0: - resolution: {integrity: sha1-/J29hK+edHJJA01NYmAt72UX8dc=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/html-void-elements/-/html-void-elements-3.0.0.tgz} + resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==} html-whitespace-sensitive-tag-names@3.0.1: - resolution: {integrity: sha1-w17dKCBfO/jB/QMnRgjWC5I95bI=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/html-whitespace-sensitive-tag-names/-/html-whitespace-sensitive-tag-names-3.0.1.tgz} + resolution: {integrity: sha512-q+310vW8zmymYHALr1da4HyXUQ0zgiIwIicEfotYPWGN0OJVEN/58IJ3A4GBYcEq3LGAZqKb+ugvP0GNB9CEAA==} http-cache-semantics@4.2.0: - resolution: {integrity: sha1-IF9Ntk+FYrdqT/kjWqUnmDmgndU=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz} + resolution: {integrity: sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==} http-errors@2.0.1: - resolution: {integrity: sha1-NtL2W8kJyHkAGN02+02T2myq4Gs=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/http-errors/-/http-errors-2.0.1.tgz} + resolution: {integrity: sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==} engines: {node: '>= 0.8'} http-proxy-agent@9.1.0: - resolution: {integrity: sha1-/Ys53LWKyARhOeX06oDeeOi+r3s=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/http-proxy-agent/-/http-proxy-agent-9.1.0.tgz} + resolution: {integrity: sha512-2NxoveTT58mjYT4n3RPTEfCZGLMbidoO8XEieXfpSYxu+PQJ1qpx4ypwH6N+uF9twBPIvRRgvkvW5HUTYWENig==} engines: {node: '>= 20'} https-proxy-agent@9.1.0: - resolution: {integrity: sha1-qfYPebwVeMN7Fm3X9Ytry1xX5Es=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/https-proxy-agent/-/https-proxy-agent-9.1.0.tgz} + resolution: {integrity: sha512-ag87y7cJJ9/3+GxFr8Oy4O5faDsGRGnBGsJj/YjOSsSx/5eadKLYTMPlzuR6obgoCDDm0abAAZitXXQkMOPSpA==} engines: {node: '>= 20'} i18next@26.3.6: - resolution: {integrity: sha1-WZ2ydcULZtKKadj2xRYsJFzpKWs=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/i18next/-/i18next-26.3.6.tgz} + resolution: {integrity: sha512-Bu5Z2nAXgfVyM8xvW3jk9EKRIuX37PudsrBViThNFx7CR7aaYTpP01cxNB/E4c4UUzTDiAZRstEhsRfPOL/8xA==} peerDependencies: typescript: ^5 || ^6 || ^7 peerDependenciesMeta: @@ -2833,698 +2823,698 @@ packages: optional: true iconv-lite@0.6.3: - resolution: {integrity: sha1-pS+AvzjaGVLrXGgXkHGYcaGnJQE=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/iconv-lite/-/iconv-lite-0.6.3.tgz} + resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} engines: {node: '>=0.10.0'} ignore@5.3.2: - resolution: {integrity: sha1-PNQOcp82Q/2HywTlC/DrcivFlvU=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/ignore/-/ignore-5.3.2.tgz} + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} engines: {node: '>= 4'} ignore@7.0.6: - resolution: {integrity: sha1-aleq70yQ3yesNZCHXSno8RmIyI4=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/ignore/-/ignore-7.0.6.tgz} + resolution: {integrity: sha512-BAg6QkE8W+TuQLrrw0Ugr7HegXduRuuj8/ti2kSOc+jz1dmx8/WNcjr6XGnq5YpDWxFwwaavqD0+jIUOKelTsw==} engines: {node: '>= 4'} import-meta-resolve@4.2.0: - resolution: {integrity: sha1-CMuFtb037MjrHg9nDcJ2cALUNzQ=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/import-meta-resolve/-/import-meta-resolve-4.2.0.tgz} + resolution: {integrity: sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==} imurmurhash@0.1.4: - resolution: {integrity: sha1-khi5srkoojixPcT7a21XbyMUU+o=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/imurmurhash/-/imurmurhash-0.1.4.tgz} + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} engines: {node: '>=0.8.19'} inherits@2.0.4: - resolution: {integrity: sha1-D6LGT5MpF8NDOg3tVTY6rjdBa3w=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/inherits/-/inherits-2.0.4.tgz} + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} inline-style-parser@0.2.7: - resolution: {integrity: sha1-sfxov8AxO4aFdF5EZON/k3a5yQk=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/inline-style-parser/-/inline-style-parser-0.2.7.tgz} + resolution: {integrity: sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA==} internmap@1.0.1: - resolution: {integrity: sha1-ABfMijuZYF8DAvKxmNJy4BXl35U=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/internmap/-/internmap-1.0.1.tgz} + resolution: {integrity: sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==} internmap@2.0.3: - resolution: {integrity: sha1-ZoXyN1XkPFJOJR0py8lySOMGEAk=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/internmap/-/internmap-2.0.3.tgz} + resolution: {integrity: sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==} engines: {node: '>=12'} iron-webcrypto@1.2.1: - resolution: {integrity: sha1-qmD/KqEFUGMPTAsR/SRCvs2zWm8=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/iron-webcrypto/-/iron-webcrypto-1.2.1.tgz} + resolution: {integrity: sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg==} is-absolute-url@5.0.0: - resolution: {integrity: sha1-KEsXLcObRpfw5/j1i9pOhMAesgY=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/is-absolute-url/-/is-absolute-url-5.0.0.tgz} + resolution: {integrity: sha512-sdJyNpBnQHuVnBunfzjAecOhZr2+A30ywfFvu3EnxtKLUWfwGgyWUmqHbGZiU6vTfHpCPm5GvLe4BAvlU9n8VQ==} engines: {node: '>=20'} is-alphabetical@2.0.1: - resolution: {integrity: sha1-AQcgU+p8EDbfPH0Zptqux/GeeJs=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/is-alphabetical/-/is-alphabetical-2.0.1.tgz} + resolution: {integrity: sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==} is-alphanumerical@2.0.1: - resolution: {integrity: sha1-fAP76W4+kxET5X+WSwo2jMLf2HU=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz} + resolution: {integrity: sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==} is-binary-path@2.1.0: - resolution: {integrity: sha1-6h9/O4DwZCNug0cPhsCcJU+0Wwk=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/is-binary-path/-/is-binary-path-2.1.0.tgz} + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} engines: {node: '>=8'} is-decimal@2.0.1: - resolution: {integrity: sha1-lGnS3BkNAhT9h9eLeMrswMwU7vc=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/is-decimal/-/is-decimal-2.0.1.tgz} + resolution: {integrity: sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==} is-docker@4.0.0: - resolution: {integrity: sha1-aquHx3ow3f85xGCvNy7heVrueEg=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/is-docker/-/is-docker-4.0.0.tgz} + resolution: {integrity: sha512-LHE+wROyG/Y/0ZnbktRCoTix2c1RhgWaZraMZ8o1Q7zCh0VSrICJQO5oqIIISrcSBtrXv0o233w1IYwsWCjTzA==} engines: {node: '>=20'} hasBin: true is-extglob@2.1.1: - resolution: {integrity: sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/is-extglob/-/is-extglob-2.1.1.tgz} + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} is-glob@4.0.3: - resolution: {integrity: sha1-ZPYeQsu7LuwgcanawLKLoeZdUIQ=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/is-glob/-/is-glob-4.0.3.tgz} + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} is-hexadecimal@2.0.1: - resolution: {integrity: sha1-hrW/Zo/KMHSY0xnfwDKJ14GpACc=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz} + resolution: {integrity: sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==} is-number@7.0.0: - resolution: {integrity: sha1-dTU0W4lnNNX4DE0GxQlVUnoU8Ss=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/is-number/-/is-number-7.0.0.tgz} + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} is-plain-obj@4.1.0: - resolution: {integrity: sha1-1lAl7ew2V84DL9fbY8l4g+rtcfA=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/is-plain-obj/-/is-plain-obj-4.1.0.tgz} + resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} engines: {node: '>=12'} is-unsafe@2.0.0: - resolution: {integrity: sha1-wNzk4GdCZi3eJjYBYOQU6kh9ouk=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/is-unsafe/-/is-unsafe-2.0.0.tgz} + resolution: {integrity: sha512-2LdV822R+wmI86unXA93WCFpL6g+av8ynWk0nrHyJqGop5VoocYsSLFgN8jrfalT6iGeLNM4KXuVSsULP53kEA==} isexe@2.0.0: - resolution: {integrity: sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/isexe/-/isexe-2.0.0.tgz} + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} jackspeak@4.2.3: - resolution: {integrity: sha1-J++A8zuTQSA3w76k+O3fgOGTFIM=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/jackspeak/-/jackspeak-4.2.3.tgz} + resolution: {integrity: sha512-ykkVRwrYvFm1nb2AJfKKYPr0emF6IiXDYUaFx4Zn9ZuIH7MrzEZ3sD5RlqGXNRpHtvUHJyOnCEFxOlNDtGo7wg==} engines: {node: 20 || >=22} jiti@1.21.7: - resolution: {integrity: sha1-ndgQQ0JKPShFixk9ll8NGKIwC6k=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/jiti/-/jiti-1.21.7.tgz} + resolution: {integrity: sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==} hasBin: true jiti@2.7.0: - resolution: {integrity: sha1-l0Io8vTKK8IYhaF5e0X+po6VDGQ=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/jiti/-/jiti-2.7.0.tgz} + resolution: {integrity: sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==} hasBin: true js-yaml@4.3.2: - resolution: {integrity: sha1-jkT7FKJkPFlya7FXh7XxUSyz0/s=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/js-yaml/-/js-yaml-4.3.2.tgz} + resolution: {integrity: sha512-SFNOvSJ+Dgf/9An904Yx+CgSlIPCkIpao4qo51lpee25TIRejdH3rhR4EZMGoNx3/TP3O+wzWuiTFl4sqbltzA==} hasBin: true json-buffer@3.0.1: - resolution: {integrity: sha1-kziAKjDTtmBfvgYT4JQAjKjAWhM=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/json-buffer/-/json-buffer-3.0.1.tgz} + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} json-schema-traverse@0.4.1: - resolution: {integrity: sha1-afaofZUTq4u4/mO9sJecRI5oRmA=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz} + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} json-stable-stringify-without-jsonify@1.0.1: - resolution: {integrity: sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz} + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} jsonc-parser@3.3.1: - resolution: {integrity: sha1-8qUktPf9EePXkeVZl3rWC5i3mLQ=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/jsonc-parser/-/jsonc-parser-3.3.1.tgz} + resolution: {integrity: sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==} katex@0.16.47: - resolution: {integrity: sha1-ChOkLC3rT3TmHxYtRAuRZaVIAw8=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/katex/-/katex-0.16.47.tgz} + resolution: {integrity: sha512-Eeo8Ys1doU1z+x8AZsPpQu+p/QcZBI5PeOo7QGQdy2x2m0MU/hYagBbGOmXwr5KVbEfVuWv9LpnQWeehogurjg==} hasBin: true keyv@4.5.4: - resolution: {integrity: sha1-qHmpnilFL5QkOfKkBeOvizHU3pM=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/keyv/-/keyv-4.5.4.tgz} + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} khroma@2.1.0: - resolution: {integrity: sha1-RfLOlM4jGkN89bY8LohubrQru7E=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/khroma/-/khroma-2.1.0.tgz} + resolution: {integrity: sha512-Ls993zuzfayK269Svk9hzpeGUKob/sIgZzyHYdjQoAdQetRKpOLj+k/QQQ/6Qi0Yz65mlROrfd+Ev+1+7dz9Kw==} klona@2.0.6: - resolution: {integrity: sha1-hb/7+BnAOy9TJwQSQgpFVe+ILiI=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/klona/-/klona-2.0.6.tgz} + resolution: {integrity: sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==} engines: {node: '>= 8'} layout-base@1.0.2: - resolution: {integrity: sha1-EpHilog8Miqd1MXdggY3IbU+JuI=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/layout-base/-/layout-base-1.0.2.tgz} + resolution: {integrity: sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg==} layout-base@2.0.1: - resolution: {integrity: sha1-0DN5E1hskPnCwHUpIGn1wtpd0oU=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/layout-base/-/layout-base-2.0.1.tgz} + resolution: {integrity: sha512-dp3s92+uNI1hWIpPGH3jK2kxE2lMjdXdr+DH8ynZHpd6PUlH6x6cbuXnoMmiNumznqaNO31xu9e79F0uuZ0JFg==} levn@0.4.1: - resolution: {integrity: sha1-rkViwAdHO5MqYgDUAyaN0v/8at4=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/levn/-/levn-0.4.1.tgz} + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} lightningcss-android-arm64@1.33.0: - resolution: {integrity: sha1-mmhB+IrlD8g1ApA4krQa9BvCuQc=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/lightningcss-android-arm64/-/lightningcss-android-arm64-1.33.0.tgz} + resolution: {integrity: sha512-gEpRTalKdosp4Bb8qWtc2iOgE5SeIHlpS1up9bFq2wAyYhl1UdTObYiHe98zEM9SQvSoqQZ1IQD0JNpg3Ml5pg==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [android] lightningcss-darwin-arm64@1.33.0: - resolution: {integrity: sha1-wPLDHAv9GfpN0/GOlXofGhUgl9Y=, tarball: https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.33.0.tgz} + resolution: {integrity: sha512-Sciaz8eenNTKn9b3t7+xr0ipTp9YxKQY4npwQ3mrRuL0BAVHBLyZxofhaKBAVtzmtRZ/zTyo0/to4B1uWG/Djg==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [darwin] lightningcss-darwin-x64@1.33.0: - resolution: {integrity: sha1-ywcFllrLU4xmg5Sc5pJfs833w2E=, tarball: https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.33.0.tgz} + resolution: {integrity: sha512-Z5UPAxzrjlWNNyGy6i65cJzzvgJ5D3T6wMvs+gWpY9d7qRhANrxqAp6LhxIgZhWEw18RfJTGcRxjuLIBr+m8XQ==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [darwin] lightningcss-freebsd-x64@1.33.0: - resolution: {integrity: sha1-djU4gosmurJoDa2vzITueLDrUCs=, tarball: https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.33.0.tgz} + resolution: {integrity: sha512-QQM/Ti/hQajJwCY+RiWuCZ9sdtI/XQk7nDK5vC8kkdwixezOlDgvDx7+RT+QjK6FcFT4MpsuoBnHIo/O3StRRg==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [freebsd] lightningcss-linux-arm-gnueabihf@1.33.0: - resolution: {integrity: sha1-aGLjF2ozGu297B7TUrTX0N0HhN4=, tarball: https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.33.0.tgz} + resolution: {integrity: sha512-N7FVBe6iS24MlM6R/4RBTxGhQheZGs7tiQ9U32UtF75NzP5Q7xWPRqLBCKxlRQRk3rY1jCIPLzx7WzOhuUIRLQ==} engines: {node: '>= 12.0.0'} cpu: [arm] os: [linux] lightningcss-linux-arm64-gnu@1.33.0: - resolution: {integrity: sha1-xqOi7RUUHa9r3CYokw+OOb30c6o=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.33.0.tgz} + resolution: {integrity: sha512-j2v/itmy4HlNxlc6voKXYgBqNi0Ng2LShg4z7GufpEgs05P+2suBVyi9I6YHq5uoVFx9ETin3eCEhLVyXGQnKg==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] libc: [glibc] lightningcss-linux-arm64-musl@1.33.0: - resolution: {integrity: sha1-f6EzSXH8goRfmCffbvigsgkUusY=, tarball: https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.33.0.tgz} + resolution: {integrity: sha512-yiO5ROMuYQgXbC60yjZU5CYSFZGKXL0HFATXt9mHJn1+zW55oCtMI9NfcVhYLMFDL7gV7oBPon/EmMMGg2OvtQ==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] libc: [musl] lightningcss-linux-x64-gnu@1.33.0: - resolution: {integrity: sha1-i5J4YuqMK7xoMaRlCSRLUNmTblU=, tarball: https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.33.0.tgz} + resolution: {integrity: sha512-ar+Ju7LmcN0Jo4FpL4hpFybwNG9/3A/Br5KW2n2jyODg3MEZXaDYADdemoNS+BDNfMgKvylJLj4S5tyRActuAg==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] libc: [glibc] lightningcss-linux-x64-musl@1.33.0: - resolution: {integrity: sha1-DFJbsHff2UQEwFnP5C2teX6Wrq8=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.33.0.tgz} + resolution: {integrity: sha512-RYiYbkokw0trfKqqzfF55lginwEPrD3OJDfTuJzFs1MK6iFnDenaz1fqLLtX4ITG3OktJQXOeTaw1awrBAlZPw==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] libc: [musl] lightningcss-win32-arm64-msvc@1.33.0: - resolution: {integrity: sha1-hQ7hED2smJz6tQ46wi0aaeOU5j0=, tarball: https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.33.0.tgz} + resolution: {integrity: sha512-1K+MPfLSFVpphzpdbfkhlWk6wBrTObBzS2T6db10PNOZgR9GoVsAWzwNyuhUYYbTp23j+4RrncfujZ4uAzXvwA==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [win32] lightningcss-win32-x64-msvc@1.33.0: - resolution: {integrity: sha1-40OuFS7tNgncbhGUnRo785oclG8=, tarball: https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.33.0.tgz} + resolution: {integrity: sha512-OlEICDx/Xl0FqSp4bry8zFnCvGpig3Gl4gCquvYwHuqJKEC1+n9NgDniFvqHGmMv1ZkqDJrDqKKSykTDX+ehuA==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [win32] lightningcss@1.33.0: - resolution: {integrity: sha1-wIhn1xp5OFxuGQIU/XL+8+X5Xws=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/lightningcss/-/lightningcss-1.33.0.tgz} + resolution: {integrity: sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA==} engines: {node: '>= 12.0.0'} linebreak@1.1.0: - resolution: {integrity: sha1-gxzzeNmLztOB2KsRj4Ur1Q2B5Gs=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/linebreak/-/linebreak-1.1.0.tgz} + resolution: {integrity: sha512-MHp03UImeVhB7XZtjd0E4n6+3xr5Dq/9xI/5FptGk5FrbDR3zagPa2DS6U8ks/3HjbKWG9Q1M2ufOzxV2qLYSQ==} lite-youtube-embed@0.3.4: - resolution: {integrity: sha1-+A8y9JRKQk3Zr4eDacjb7RRHr54=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/lite-youtube-embed/-/lite-youtube-embed-0.3.4.tgz} + resolution: {integrity: sha512-aXgxpwK7AIW58GEbRzA8EYaY4LWvF3FKak6B9OtSJmuNyLhX2ouD4cMTxz/yR5HFInhknaYd2jLWOTRTvT8oAw==} locate-path@6.0.0: - resolution: {integrity: sha1-VTIeswn+u8WcSAHZMackUqaB0oY=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/locate-path/-/locate-path-6.0.0.tgz} + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} engines: {node: '>=10'} lodash-es@4.18.1: - resolution: {integrity: sha1-uWLuuA2dmDqQC/NClh+3QYyhCx0=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/lodash-es/-/lodash-es-4.18.1.tgz} + resolution: {integrity: sha512-J8xewKD/Gk22OZbhpOVSwcs60zhd95ESDwezOFuA3/099925PdHJ7OFHNTGtajL3AlZkykD32HykiMo+BIBI8A==} longest-streak@3.1.0: - resolution: {integrity: sha1-YvpnzZWHQqFXSvnzmGY2QQLZDNQ=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/longest-streak/-/longest-streak-3.1.0.tgz} + resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==} lru-cache@11.5.2: - resolution: {integrity: sha1-AOFmZckMYg+6FKPDaHMql2ST92A=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/lru-cache/-/lru-cache-11.5.2.tgz} + resolution: {integrity: sha512-4pfM1Ff0x50o0tQwb5ucw/RzNyD0/YJME6IVcStalZuMWxdt3sR3huStTtxz4PUmvZfRguvDejasvQ2kifR11g==} engines: {node: 20 || >=22} magic-regexp@0.10.0: - resolution: {integrity: sha1-eLRCGlDSt6ZxKb8sQkozOSfDoOU=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/magic-regexp/-/magic-regexp-0.10.0.tgz} + resolution: {integrity: sha512-Uly1Bu4lO1hwHUW0CQeSWuRtzCMNO00CmXtS8N6fyvB3B979GOEEeAkiTUDsmbYLAbvpUS/Kt5c4ibosAzVyVg==} magic-string@0.30.21: - resolution: {integrity: sha1-VnY+wJoPqAkd8nh5/ZTRkHjADZE=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/magic-string/-/magic-string-0.30.21.tgz} + resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} magic-string@1.2.3: - resolution: {integrity: sha1-aPBwyg8FaXw65XzkSoj8fUg9TfE=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/magic-string/-/magic-string-1.2.3.tgz} + resolution: {integrity: sha512-Bpb0W2TbLKOZ7vJnOUnVRGq3WL2p+ISV29M6hYPL1AFCpyKZpdr5ytiXoTSSxRVhg8YW7f65+6gbG8WG6PCa/g==} magicast@0.5.3: - resolution: {integrity: sha1-GAD2523YsNvnJXQ4osM2rvq72QU=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/magicast/-/magicast-0.5.3.tgz} + resolution: {integrity: sha512-pVKE4UdSQ7DvHzivsCIFx2BJn1mHG6KsyrFcaxFx6tONdneEuThrDx0Cj3AMg58KyN4pzYT+LHOotxDQDjNvkw==} markdown-extensions@2.0.0: - resolution: {integrity: sha1-NL68g+mTjK4W4OAX5KmBSoMw08Q=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/markdown-extensions/-/markdown-extensions-2.0.0.tgz} + resolution: {integrity: sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q==} engines: {node: '>=16'} markdown-table@3.0.4: - resolution: {integrity: sha1-/kTW1BD/nW8uoXl6P2CqTStjHCo=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/markdown-table/-/markdown-table-3.0.4.tgz} + resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==} marked@16.4.2: - resolution: {integrity: sha1-SVmmS+bEhvDbdGfq184ojeVCkKM=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/marked/-/marked-16.4.2.tgz} + resolution: {integrity: sha512-TI3V8YYWvkVf3KJe1dRkpnjs68JUPyEa5vjKrp1XEEJUAOaQc+Qj+L1qWbPd0SJuAdQkFU0h73sXXqwDYxsiDA==} engines: {node: '>= 20'} hasBin: true mdast-util-definitions@6.0.0: - resolution: {integrity: sha1-wbtwbl52u5P5oJ3XrxdAAq5prCQ=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/mdast-util-definitions/-/mdast-util-definitions-6.0.0.tgz} + resolution: {integrity: sha512-scTllyX6pnYNZH/AIp/0ePz6s4cZtARxImwoPJ7kS42n+MnVsI4XbnG6d4ibehRIldYMWM2LD7ImQblVhUejVQ==} mdast-util-directive@3.1.0: - resolution: {integrity: sha1-82VvSqtq43Z9PHLPq16AVVcsy6E=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/mdast-util-directive/-/mdast-util-directive-3.1.0.tgz} + resolution: {integrity: sha512-I3fNFt+DHmpWCYAT7quoM6lHf9wuqtI+oCOfvILnoicNIqjh5E3dEJWiXuYME2gNe8vl1iMQwyUHa7bgFmak6Q==} mdast-util-find-and-replace@3.0.2: - resolution: {integrity: sha1-cKMXTIlOFN9yKr9DvCUMuuRLEd8=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.2.tgz} + resolution: {integrity: sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==} mdast-util-from-markdown@2.0.3: - resolution: {integrity: sha1-yVgiuRqrdfGKTL6LL1G4c+0s8Mc=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.3.tgz} + resolution: {integrity: sha512-W4mAWTvSlKvf8L6J+VN9yLSqQ9AOAAvHuoDAmPkz4dHf553m5gVj2ejadHJhoJmcmxEnOv6Pa8XJhpxE93kb8Q==} mdast-util-gfm-autolink-literal@2.0.1: - resolution: {integrity: sha1-q9VXYwM3vTCm1aS9glLhwtwIddU=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-2.0.1.tgz} + resolution: {integrity: sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==} mdast-util-gfm-footnote@2.1.0: - resolution: {integrity: sha1-d3jp2co99yOMwr0/orG/amWxlAM=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.1.0.tgz} + resolution: {integrity: sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==} mdast-util-gfm-strikethrough@2.0.0: - resolution: {integrity: sha1-1E756O0oOsjBFlqw0N/QWMJ2TBY=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.0.tgz} + resolution: {integrity: sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==} mdast-util-gfm-table@2.0.0: - resolution: {integrity: sha1-ekNftiI6crCGKzOvvXErba6HjTg=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/mdast-util-gfm-table/-/mdast-util-gfm-table-2.0.0.tgz} + resolution: {integrity: sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==} mdast-util-gfm-task-list-item@2.0.0: - resolution: {integrity: sha1-5oCV0vikMD7yQJSrZC4QR7mRqTY=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-2.0.0.tgz} + resolution: {integrity: sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==} mdast-util-gfm@3.1.0: - resolution: {integrity: sha1-LN9juSwqMxQGsPsNtMB3wbAzF1E=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/mdast-util-gfm/-/mdast-util-gfm-3.1.0.tgz} + resolution: {integrity: sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==} mdast-util-mdx-expression@2.0.1: - resolution: {integrity: sha1-Q/CrrJrcdW4ghvY4IqOMjTw6UJY=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.1.tgz} + resolution: {integrity: sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==} mdast-util-mdx-jsx@3.2.0: - resolution: {integrity: sha1-/QTGeip0me+5BailxXjd3J/a2g0=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-3.2.0.tgz} + resolution: {integrity: sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q==} mdast-util-mdx@3.0.0: - resolution: {integrity: sha1-eS+c8DYbRr7h/fHvNr6sQkoJnEE=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/mdast-util-mdx/-/mdast-util-mdx-3.0.0.tgz} + resolution: {integrity: sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w==} mdast-util-mdxjs-esm@2.0.1: - resolution: {integrity: sha1-AZz751etYt1VfbNaaV5zFLzJ+pc=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-2.0.1.tgz} + resolution: {integrity: sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==} mdast-util-phrasing@4.1.0: - resolution: {integrity: sha1-fMCo3sMOrwS3salmGpKtszgqpuM=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz} + resolution: {integrity: sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==} mdast-util-to-hast@13.2.1: - resolution: {integrity: sha1-1/+EykmaV+LAYK5nVIrZUOaJoFM=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/mdast-util-to-hast/-/mdast-util-to-hast-13.2.1.tgz} + resolution: {integrity: sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==} mdast-util-to-markdown@2.1.2: - resolution: {integrity: sha1-+RD/5giX8Eu0t+fuQ0SG92KINhs=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.2.tgz} + resolution: {integrity: sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==} mdast-util-to-string@4.0.0: - resolution: {integrity: sha1-elEhR1VWoE5+3etnsmSq550xKBQ=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz} + resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==} mdn-data@2.0.28: - resolution: {integrity: sha1-XsSOe+8SBlRTkGnhrk3cgcpJDro=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/mdn-data/-/mdn-data-2.0.28.tgz} + resolution: {integrity: sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==} mdn-data@2.27.1: - resolution: {integrity: sha1-43ucUIgLdTZsTUCsY9m7ys22Hw4=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/mdn-data/-/mdn-data-2.27.1.tgz} + resolution: {integrity: sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==} merge2@1.4.1: - resolution: {integrity: sha1-Q2iJL4hekHRVpv19xVwMnUBJkK4=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/merge2/-/merge2-1.4.1.tgz} + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} mermaid@11.16.1: - resolution: {integrity: sha1-V64jQvbEW5ZxE7BMklhDC90Ffug=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/mermaid/-/mermaid-11.16.1.tgz} + resolution: {integrity: sha512-TQsq6u22fAn3rek5VOubrhKPo1g5hwC3FXUN9hiyupTckcYiGuuKGkNQrKYwGJkXUxZdojwRG46gsSCFZMDp4g==} micromark-core-commonmark@2.0.3: - resolution: {integrity: sha1-xpFjDkhQIaaM8o28Kyyifr9njNQ=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/micromark-core-commonmark/-/micromark-core-commonmark-2.0.3.tgz} + resolution: {integrity: sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==} micromark-extension-directive@4.0.0: - resolution: {integrity: sha1-rzieM/4GVMFfhGa3Og9a9ZjQA2g=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/micromark-extension-directive/-/micromark-extension-directive-4.0.0.tgz} + resolution: {integrity: sha512-/C2nqVmXXmiseSSuCdItCMho7ybwwop6RrrRPk0KbOHW21JKoCldC+8rFOaundDoRBUWBnJJcxeA/Kvi34WQXg==} micromark-extension-gfm-autolink-literal@2.1.0: - resolution: {integrity: sha1-Yoau6WhsRGLB41UqnVBf7dzuuTU=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.1.0.tgz} + resolution: {integrity: sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==} micromark-extension-gfm-footnote@2.1.0: - resolution: {integrity: sha1-TatW1OOYuYU/b+TvrE/JNh8+B1A=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.1.0.tgz} + resolution: {integrity: sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==} micromark-extension-gfm-strikethrough@2.1.0: - resolution: {integrity: sha1-hhBt+LOmkrX2qSKA04eb5r5G2SM=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-2.1.0.tgz} + resolution: {integrity: sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==} micromark-extension-gfm-table@2.1.1: - resolution: {integrity: sha1-+scLy/Uf5l9fRAMxGNOb6Km1lAs=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.1.tgz} + resolution: {integrity: sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==} micromark-extension-gfm-tagfilter@2.0.0: - resolution: {integrity: sha1-8m2KeAe1mF+6E89hRltYyl/33Fc=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-2.0.0.tgz} + resolution: {integrity: sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==} micromark-extension-gfm-task-list-item@2.1.0: - resolution: {integrity: sha1-vMNNgFY5gpmQ7BdcPuoSu1t4Hyw=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-2.1.0.tgz} + resolution: {integrity: sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==} micromark-extension-gfm@3.0.0: - resolution: {integrity: sha1-PhM3arld16XP0OKVYN/pmWV7PFs=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz} + resolution: {integrity: sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==} micromark-extension-mdx-expression@3.0.1: - resolution: {integrity: sha1-Q9BY2ZlTL7MEEZWjw8BcRvqEVDs=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/micromark-extension-mdx-expression/-/micromark-extension-mdx-expression-3.0.1.tgz} + resolution: {integrity: sha512-dD/ADLJ1AeMvSAKBwO22zG22N4ybhe7kFIZ3LsDI0GlsNr2A3KYxb0LdC1u5rj4Nw+CHKY0RVdnHX8vj8ejm4Q==} micromark-extension-mdx-jsx@3.0.2: - resolution: {integrity: sha1-/8mL22SXmJAvqfxWifZ/nByQIEQ=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/micromark-extension-mdx-jsx/-/micromark-extension-mdx-jsx-3.0.2.tgz} + resolution: {integrity: sha512-e5+q1DjMh62LZAJOnDraSSbDMvGJ8x3cbjygy2qFEi7HCeUT4BDKCvMozPozcD6WmOt6sVvYDNBKhFSz3kjOVQ==} micromark-extension-mdx-md@2.0.0: - resolution: {integrity: sha1-HSUogeo110aYQjq0SRfh9bGXuS0=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/micromark-extension-mdx-md/-/micromark-extension-mdx-md-2.0.0.tgz} + resolution: {integrity: sha512-EpAiszsB3blw4Rpba7xTOUptcFeBFi+6PY8VnJ2hhimH+vCQDirWgsMpz7w1XcZE7LVrSAUGb9VJpG9ghlYvYQ==} micromark-extension-mdxjs-esm@3.0.0: - resolution: {integrity: sha1-3iGysEX9IFm9ANNnRggd44OQ1Uo=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/micromark-extension-mdxjs-esm/-/micromark-extension-mdxjs-esm-3.0.0.tgz} + resolution: {integrity: sha512-DJFl4ZqkErRpq/dAPyeWp15tGrcrrJho1hKK5uBS70BCtfrIFg81sqcTVu3Ta+KD1Tk5vAtBNElWxtAa+m8K9A==} micromark-extension-mdxjs@3.0.0: - resolution: {integrity: sha1-taLg7USSiPP29sVENYFZVXVJ3hg=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/micromark-extension-mdxjs/-/micromark-extension-mdxjs-3.0.0.tgz} + resolution: {integrity: sha512-A873fJfhnJ2siZyUrJ31l34Uqwy4xIFmvPY1oj+Ean5PHcPBYzEsvqvWGaWcfEIr11O5Dlw3p2y0tZWpKHDejQ==} micromark-factory-destination@2.0.1: - resolution: {integrity: sha1-j++OD3CB8EdPvdkt61DJkKAmRjk=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz} + resolution: {integrity: sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==} micromark-factory-label@2.0.1: - resolution: {integrity: sha1-UmfvqX8eUlTvx/ILRZo4yyEFi6E=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/micromark-factory-label/-/micromark-factory-label-2.0.1.tgz} + resolution: {integrity: sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==} micromark-factory-mdx-expression@2.0.3: - resolution: {integrity: sha1-uwmYhhBYnAfRweRCUoWJUEGz36k=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/micromark-factory-mdx-expression/-/micromark-factory-mdx-expression-2.0.3.tgz} + resolution: {integrity: sha512-kQnEtA3vzucU2BkrIa8/VaSAsP+EJ3CKOvhMuJgOEGg9KDC6OAY6nSnNDVRiVNRqj7Y4SlSzcStaH/5jge8JdQ==} micromark-factory-space@2.0.1: - resolution: {integrity: sha1-NtAhLpYrKzEh+FJfx6PHwCnzNPw=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz} + resolution: {integrity: sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==} micromark-factory-title@2.0.1: - resolution: {integrity: sha1-I35KpdWKlYY/AQMtnumwkPHebpQ=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/micromark-factory-title/-/micromark-factory-title-2.0.1.tgz} + resolution: {integrity: sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==} micromark-factory-whitespace@2.0.1: - resolution: {integrity: sha1-BrJrKYPE0nv8xlezPiUTTUhosLE=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.1.tgz} + resolution: {integrity: sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==} micromark-util-character@2.1.1: - resolution: {integrity: sha1-L5h4MaQNTFEKwmHomFLE6XA8zaY=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/micromark-util-character/-/micromark-util-character-2.1.1.tgz} + resolution: {integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==} micromark-util-chunked@2.0.1: - resolution: {integrity: sha1-R/vNk0caP8yrhs/wOEf8NVLbEFE=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/micromark-util-chunked/-/micromark-util-chunked-2.0.1.tgz} + resolution: {integrity: sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==} micromark-util-classify-character@2.0.1: - resolution: {integrity: sha1-05n6+cRcoUyLS+mLHqSBvO2Htik=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/micromark-util-classify-character/-/micromark-util-classify-character-2.0.1.tgz} + resolution: {integrity: sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==} micromark-util-combine-extensions@2.0.1: - resolution: {integrity: sha1-Kg9JCrCL/1zC/V7sbdDKBPibMKk=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.1.tgz} + resolution: {integrity: sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==} micromark-util-decode-numeric-character-reference@2.0.2: - resolution: {integrity: sha1-/PFbZgl5OI5vEYzba/fXnXPSb+U=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.2.tgz} + resolution: {integrity: sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==} micromark-util-decode-string@2.0.1: - resolution: {integrity: sha1-bLmVguXScehO/KjmGoB5lNcWHrI=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/micromark-util-decode-string/-/micromark-util-decode-string-2.0.1.tgz} + resolution: {integrity: sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==} micromark-util-encode@2.0.1: - resolution: {integrity: sha1-DVHRwJVVHPqsNoMmljz1XxX1QLg=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz} + resolution: {integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==} micromark-util-events-to-acorn@2.0.3: - resolution: {integrity: sha1-56imtVpH5aBscg1aHEq66MN8mPM=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/micromark-util-events-to-acorn/-/micromark-util-events-to-acorn-2.0.3.tgz} + resolution: {integrity: sha512-jmsiEIiZ1n7X1Rr5k8wVExBQCg5jy4UXVADItHmNk1zkwEVhBuIUKRu3fqv+hs4nxLISi2DQGlqIOGiFxgbfHg==} micromark-util-html-tag-name@2.0.1: - resolution: {integrity: sha1-5AQDCWSBmGtBwQZif5j3LU0QuCU=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.1.tgz} + resolution: {integrity: sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==} micromark-util-normalize-identifier@2.0.1: - resolution: {integrity: sha1-ww13sugyrPZSb4vxqke8nJQ4wW0=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.1.tgz} + resolution: {integrity: sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==} micromark-util-resolve-all@2.0.1: - resolution: {integrity: sha1-4aLWLN0jcjCirhGDkCexk4HjHos=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.1.tgz} + resolution: {integrity: sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==} micromark-util-sanitize-uri@2.0.1: - resolution: {integrity: sha1-q4l4m4GKWHUrc9a1UjhiG3+qj9c=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz} + resolution: {integrity: sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==} micromark-util-subtokenize@2.1.0: - resolution: {integrity: sha1-2K3lug8xl6HPaimZ+7/mNXoaGe4=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/micromark-util-subtokenize/-/micromark-util-subtokenize-2.1.0.tgz} + resolution: {integrity: sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==} micromark-util-symbol@2.0.1: - resolution: {integrity: sha1-5dpJTo6ysHGg0I+zT2zv7GwKGbg=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz} + resolution: {integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==} micromark-util-types@2.0.2: - resolution: {integrity: sha1-8AIl9fWg68MlT5bDa2YFxLOTkI4=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/micromark-util-types/-/micromark-util-types-2.0.2.tgz} + resolution: {integrity: sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==} micromark@4.0.2: - resolution: {integrity: sha1-kTlaPhiEoZjmIRbjPJxWjjmTb9s=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/micromark/-/micromark-4.0.2.tgz} + resolution: {integrity: sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==} micromatch@4.0.8: - resolution: {integrity: sha1-1m+hjzpHB2eJMgubGvMr2G2fogI=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/micromatch/-/micromatch-4.0.8.tgz} + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} engines: {node: '>=8.6'} mime-db@1.54.0: - resolution: {integrity: sha1-zds+5PnGRTDf9kAjZmHULLajFPU=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/mime-db/-/mime-db-1.54.0.tgz} + resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==} engines: {node: '>= 0.6'} mime-types@3.0.2: - resolution: {integrity: sha1-OQAtQYJXXVrwNv+hGBAPJSSy4qs=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/mime-types/-/mime-types-3.0.2.tgz} + resolution: {integrity: sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==} engines: {node: '>=18'} minimatch@10.2.5: - resolution: {integrity: sha1-vUhoegvjjtKWE5kQVgD4MglYYdE=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/minimatch/-/minimatch-10.2.5.tgz} + resolution: {integrity: sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==} engines: {node: 18 || 20 || >=22} minipass@7.1.3: - resolution: {integrity: sha1-eTibTrG7LQA6m7qH1JLyvTe9xls=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/minipass/-/minipass-7.1.3.tgz} + resolution: {integrity: sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==} engines: {node: '>=16 || 14 >=14.17'} mlly@1.8.2: - resolution: {integrity: sha1-5/eRmoLROxdEBWExFySaP0SdeLs=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/mlly/-/mlly-1.8.2.tgz} + resolution: {integrity: sha512-d+ObxMQFmbt10sretNDytwt85VrbkhhUA/JBGm1MPaWJ65Cl4wOgLaB1NYvJSZ0Ef03MMEU/0xpPMXUIQ29UfA==} mrmime@2.0.1: - resolution: {integrity: sha1-vD6H95h4U6VMmFDusfEHjNRK3dw=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/mrmime/-/mrmime-2.0.1.tgz} + resolution: {integrity: sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==} engines: {node: '>=10'} ms@2.1.3: - resolution: {integrity: sha1-V0yBOM4dK1hh8LRFedut1gxmFbI=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/ms/-/ms-2.1.3.tgz} + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} muggle-string@0.4.1: - resolution: {integrity: sha1-OzZr1Dsy+AncIGWVNN0w58ig0yg=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/muggle-string/-/muggle-string-0.4.1.tgz} + resolution: {integrity: sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==} nanoid@3.3.18: - resolution: {integrity: sha1-9mot4Rmf/eD88hyKXxMQaxwIGRM=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/nanoid/-/nanoid-3.3.18.tgz} + resolution: {integrity: sha512-DTg4MJbGMWkfi6VZFdNt2/caMbQy4Ou+Op/hJQvGEWcnVfoA1QA+xzRKAzw9jD6+GVOOeYr/mIcuDSdug6F6+w==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true natural-compare@1.4.0: - resolution: {integrity: sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/natural-compare/-/natural-compare-1.4.0.tgz} + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} neotraverse@1.0.1: - resolution: {integrity: sha1-fIm0P2UE74WSjHGPV4xoYhV20ZQ=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/neotraverse/-/neotraverse-1.0.1.tgz} + resolution: {integrity: sha512-WmmLty1YWwJl9yZi77v2dVIV6X2kuYV8YYBI/G3LWGKdGHmHUvL1z7FW0iDvEvGAwNEoc5x1tOOOyDnf5jJw/w==} engines: {node: '>= 10'} nlcst-to-string@4.0.0: - resolution: {integrity: sha1-BVEehGHr+0FZUusLfpoafUBHG9Q=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/nlcst-to-string/-/nlcst-to-string-4.0.0.tgz} + resolution: {integrity: sha512-YKLBCcUYKAg0FNlOBT6aI91qFmSiFKiluk655WzPF+DDMA02qIyy8uiRqI8QXtcFpEvll12LpL5MXqEmAZ+dcA==} node-domexception@1.0.0: - resolution: {integrity: sha1-aIjbRqH3HAt2s/dVUBa2P+ZHZuU=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/node-domexception/-/node-domexception-1.0.0.tgz} + resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} engines: {node: '>=10.5.0'} deprecated: Use your platform's native DOMException instead node-fetch-native@1.6.7: - resolution: {integrity: sha1-nQnKYwZsxIQjIR7UyvXXAHXXanE=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/node-fetch-native/-/node-fetch-native-1.6.7.tgz} + resolution: {integrity: sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==} node-fetch@3.3.2: - resolution: {integrity: sha1-0eiJus33M7T/OyskPrehKGagt4s=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/node-fetch/-/node-fetch-3.3.2.tgz} + resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} node-mock-http@1.0.4: - resolution: {integrity: sha1-IfKrTOL+T76KZg18UZWh24XgQqQ=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/node-mock-http/-/node-mock-http-1.0.4.tgz} + resolution: {integrity: sha512-8DY+kFsDkNXy1sJglUfuODx1/opAGJGyrTuFqEoN90oRc2Vk0ZbD4K2qmKXBBEhZQzdKHIVfEJpDU8Ak2NJEvQ==} normalize-path@3.0.0: - resolution: {integrity: sha1-Dc1p/yOhybEf0JeDFmRKA4ghamU=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/normalize-path/-/normalize-path-3.0.0.tgz} + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} nth-check@2.1.1: - resolution: {integrity: sha1-yeq0KO/842zWuSySS9sADvHx7R0=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/nth-check/-/nth-check-2.1.1.tgz} + resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} obug@2.1.4: - resolution: {integrity: sha1-kJDYpUilIlF5FdKqaq6QcZesbPg=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/obug/-/obug-2.1.4.tgz} + resolution: {integrity: sha512-4a+OsYv9UktOJKE+l1A4OufDgdRF9PifWj+tJnHURo/P+WOxpG4GzUFL9qCalmWauao6ogiG+QvnCovwPoyAWA==} engines: {node: '>=12.20.0'} ofetch@1.5.1: - resolution: {integrity: sha1-XEPMVuAzmLJzAUlXBgNEJUUFxcc=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/ofetch/-/ofetch-1.5.1.tgz} + resolution: {integrity: sha512-2W4oUZlVaqAPAil6FUg/difl6YhqhUR7x2eZY4bQCko22UXg3hptq9KLQdqFClV+Wu85UX7hNtdGTngi/1BxcA==} ohash@2.0.11: - resolution: {integrity: sha1-YLEejP9iyp3uiNE3R6W6oUX1kAs=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/ohash/-/ohash-2.0.11.tgz} + resolution: {integrity: sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==} on-finished@2.4.1: - resolution: {integrity: sha1-WMjEQRblSEWtV/FKsQsDUzGErD8=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/on-finished/-/on-finished-2.4.1.tgz} + resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} engines: {node: '>= 0.8'} oniguruma-parser@0.12.2: - resolution: {integrity: sha1-4nykRvf88JaWYqOrm09DF21isTk=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/oniguruma-parser/-/oniguruma-parser-0.12.2.tgz} + resolution: {integrity: sha512-6HVa5oIrgMC6aA6WF6XyyqbhRPJrKR02L20+2+zpDtO5QAzGHAUGw5TKQvwi5vctNnRHkJYmjAhRVQF2EKdTQw==} oniguruma-to-es@4.3.6: - resolution: {integrity: sha1-Q+ZAKAJBsNaHoxTnpkHUdkB6HE0=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/oniguruma-to-es/-/oniguruma-to-es-4.3.6.tgz} + resolution: {integrity: sha512-csuQ9x3Yr0cEIs/Zgx/OEt9iBw9vqIunAPQkx19R/fiMq2oGVTgcMqO/V3Ybqefr1TBvosI6jU539ksaBULJyA==} optionator@0.9.4: - resolution: {integrity: sha1-fqHBpdkddk+yghOciP4R4YKjpzQ=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/optionator/-/optionator-0.9.4.tgz} + resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} engines: {node: '>= 0.8.0'} oxc-parser@0.131.0: - resolution: {integrity: sha1-jk/J6TvU+2ih+LT0Bw4e4XqpkRQ=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/oxc-parser/-/oxc-parser-0.131.0.tgz} + resolution: {integrity: sha512-SJ3/7ZPbgie8dr5Z9BI/M51zZbpXba+hRSG0MDzVwMW5CRQg2fjYE0jHGlLX4eeiibGgC/mzoDFKSDHwVZEHRQ==} engines: {node: ^20.19.0 || >=22.12.0} oxc-walker@0.7.0: - resolution: {integrity: sha1-+ZxhvHZW5zVKFYNHCjk51oZ1nn0=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/oxc-walker/-/oxc-walker-0.7.0.tgz} + resolution: {integrity: sha512-54B4KUhrzbzc4sKvKwVYm7E2PgeROpGba0/2nlNZMqfDyca+yOor5IMb4WLGBatGDT0nkzYdYuzylg7n3YfB7A==} peerDependencies: oxc-parser: '>=0.98.0' p-limit@3.1.0: - resolution: {integrity: sha1-4drMvnjQ0TiMoYxk/qOOPlfjcGs=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/p-limit/-/p-limit-3.1.0.tgz} + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} engines: {node: '>=10'} p-limit@7.3.0: - resolution: {integrity: sha1-ghOY2RSRxrahNA7NCc3EAqnI0O4=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/p-limit/-/p-limit-7.3.0.tgz} + resolution: {integrity: sha512-7cIXg/Z0M5WZRblrsOla88S4wAK+zOQQWeBYfV3qJuJXMr+LnbYjaadrFaS0JILfEDPVqHyKnZ1Z/1d6J9VVUw==} engines: {node: '>=20'} p-locate@5.0.0: - resolution: {integrity: sha1-g8gxXGeFAF470CGDlBHJ4RDm2DQ=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/p-locate/-/p-locate-5.0.0.tgz} + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} engines: {node: '>=10'} p-map@7.0.5: - resolution: {integrity: sha1-5IvQm/3fK19d45Oq0Qm9WpBBUHo=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/p-map/-/p-map-7.0.5.tgz} + resolution: {integrity: sha512-e8vJF4XdVkzqqSHguEMz41mQO1wKwxKm5ENrUJQUu9kLDCtn83cxbyHZcszr4QC5zEA7WffRRC4gsTecC7J9oA==} engines: {node: '>=18'} p-queue@9.3.1: - resolution: {integrity: sha1-97+KSu8kQVBlf8fSY1qKaL8cMEs=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/p-queue/-/p-queue-9.3.1.tgz} + resolution: {integrity: sha512-POWdiIPmsUPGwb4FeQ4OBg46aqmcInSWe45CKDsGHiOBiVQM9chqfQTuqhuTzcg2Vz9faTI65at0KkVyVEiCHw==} engines: {node: '>=20'} p-timeout@7.0.1: - resolution: {integrity: sha1-lWgKaqaTxTDxSsM3uL0y1Oxq5PA=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/p-timeout/-/p-timeout-7.0.1.tgz} + resolution: {integrity: sha512-AxTM2wDGORHGEkPCt8yqxOTMgpfbEHqF51f/5fJCmwFC3C/zNcGT63SymH2ttOAaiIws2zVg4+izQCjrakcwHg==} engines: {node: '>=20'} package-json-from-dist@1.0.1: - resolution: {integrity: sha1-TxRxoBCCeob5TP2bByfjbSZ95QU=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz} + resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} package-manager-detector@1.8.0: - resolution: {integrity: sha1-cMmixL0aUT3NbK0Aap/OvsIqElM=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/package-manager-detector/-/package-manager-detector-1.8.0.tgz} + resolution: {integrity: sha512-yQA4H19AmPEoMUeavPMDIe1higySl/gH/yaQrkT/s07Qp+7pp2hYz30N3z2l5BkjVkF9Ow6o0wjJamm2y7Sn0A==} pagefind@1.5.2: - resolution: {integrity: sha1-RH3YABjX/QwpJKVmOfe3K7vR8WU=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/pagefind/-/pagefind-1.5.2.tgz} + resolution: {integrity: sha512-XTUaK0hXMCu2jszWE584JGQT7y284TmMV9l/HX3rnG5uo3rHI/uHU56XTyyyPFjeWEBxECbAi0CaFDJOONtG0Q==} hasBin: true pako@0.2.9: - resolution: {integrity: sha1-8/dSL073gjSNqBYbrZ7P1Rv4OnU=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/pako/-/pako-0.2.9.tgz} + resolution: {integrity: sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==} parse-css-color@0.2.1: - resolution: {integrity: sha1-toelg/LkLmb/386ApXBwaWboB8k=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/parse-css-color/-/parse-css-color-0.2.1.tgz} + resolution: {integrity: sha512-bwS/GGIFV3b6KS4uwpzCFj4w297Yl3uqnSgIPsoQkx7GMLROXfMnWvxfNkL0oh8HVhZA4hvJoEoEIqonfJ3BWg==} parse-entities@4.0.2: - resolution: {integrity: sha1-YdRvXtKOTuYundxD1rAQGIRD8Vk=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/parse-entities/-/parse-entities-4.0.2.tgz} + resolution: {integrity: sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==} parse-latin@7.0.0: - resolution: {integrity: sha1-jfrKwm+mA/dkF/NiM/xFYCoyPh0=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/parse-latin/-/parse-latin-7.0.0.tgz} + resolution: {integrity: sha512-mhHgobPPua5kZ98EF4HWiH167JWBfl4pvAIXXdbaVohtK7a6YBOy56kvhCqduqyo/f3yrHFWmqmiMg/BkBkYYQ==} parse5@7.3.0: - resolution: {integrity: sha1-1+Ik+nI5nHoXUJn0X8KtAksF7AU=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/parse5/-/parse5-7.3.0.tgz} + resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==} parse5@8.0.1: - resolution: {integrity: sha1-9DvNLNaD7+CEB1Mz6c4Np9Btox4=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/parse5/-/parse5-8.0.1.tgz} + resolution: {integrity: sha512-z1e/HMG90obSGeidlli3hj7cbocou0/wa5HacvI3ASx34PecNjNQeaHNo5WIZpWofN9kgkqV1q5YvXe3F0FoPw==} path-browserify@1.0.1: - resolution: {integrity: sha1-2YRUqcN1PVeQhg8W9ohnueRr4f0=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/path-browserify/-/path-browserify-1.0.1.tgz} + resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==} path-data-parser@0.1.0: - resolution: {integrity: sha1-j1ulzHD8e+yz3O+uoI4mWaumC4w=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/path-data-parser/-/path-data-parser-0.1.0.tgz} + resolution: {integrity: sha512-NOnmBpt5Y2RWbuv0LMzsayp3lVylAHLPUTut412ZA3l+C4uw4ZVkQbjShYCQ8TCpUMdPapr4YjUqLYD6v68j+w==} path-exists@4.0.0: - resolution: {integrity: sha1-UTvb4tO5XXdi6METfvoZXGxhtbM=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/path-exists/-/path-exists-4.0.0.tgz} + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} engines: {node: '>=8'} path-expression-matcher@1.6.2: - resolution: {integrity: sha1-VnxzwHGX6dzvJOkO3NxXEFZZkWg=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/path-expression-matcher/-/path-expression-matcher-1.6.2.tgz} + resolution: {integrity: sha512-enSlaiat05iasnzmgNxRj8reFdj3puY2QpNgP1aPIaVfT6nn9ICuPoFlKHk8EN22HcwewshO+mN2DGbkCEOtqQ==} engines: {node: '>=14.0.0'} path-key@3.1.1: - resolution: {integrity: sha1-WB9q3mWMu6ZaDTOA3ndTKVBU83U=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/path-key/-/path-key-3.1.1.tgz} + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} path-scurry@2.0.2: - resolution: {integrity: sha1-a+DQ7gKhDZ4N56mLrmXhgskGH4U=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/path-scurry/-/path-scurry-2.0.2.tgz} + resolution: {integrity: sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==} engines: {node: 18 || 20 || >=22} path-to-regexp@6.3.0: - resolution: {integrity: sha1-K2omozdzeo4UFvknLtB2axwDifQ=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/path-to-regexp/-/path-to-regexp-6.3.0.tgz} + resolution: {integrity: sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==} pathe@2.0.3: - resolution: {integrity: sha1-PsvsVUIWhbcKnahyss/z4cvtFxY=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/pathe/-/pathe-2.0.3.tgz} + resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} perfect-debounce@2.1.0: - resolution: {integrity: sha1-5weOOPIxyxkYVcMTakQjrvcl0mE=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/perfect-debounce/-/perfect-debounce-2.1.0.tgz} + resolution: {integrity: sha512-LjgdTytVFXeUgtHZr9WYViYSM/g8MkcTPYDlPa3cDqMirHjKiSZPYd6DoL7pK8AJQr+uWkQvCjHNdiMqsrJs+g==} piccolore@0.1.3: - resolution: {integrity: sha1-7zP2GA5qN7Nf4SpFdlqQAXHPrtw=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/piccolore/-/piccolore-0.1.3.tgz} + resolution: {integrity: sha512-o8bTeDWjE086iwKrROaDf31K0qC/BENdm15/uH9usSC/uZjJOKb2YGiVHfLY4GhwsERiPI1jmwI2XrA7ACOxVw==} picocolors@1.1.1: - resolution: {integrity: sha1-PTIa8+q5ObCDyPkpodEs2oHCa2s=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/picocolors/-/picocolors-1.1.1.tgz} + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} picomatch@2.3.2: - resolution: {integrity: sha1-WpQpFeJrNy3A8OZ1MUmhbmscVgE=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/picomatch/-/picomatch-2.3.2.tgz} + resolution: {integrity: sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==} engines: {node: '>=8.6'} picomatch@4.0.4: - resolution: {integrity: sha1-/W9eAKFDCG4HTf/kySS4+yk7BYk=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/picomatch/-/picomatch-4.0.4.tgz} + resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==} engines: {node: '>=12'} picomatch@4.0.5: - resolution: {integrity: sha1-UepXoX2G9gX4EDlZX7xA7QalX6s=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/picomatch/-/picomatch-4.0.5.tgz} + resolution: {integrity: sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==} engines: {node: '>=12'} pkg-types@1.3.1: - resolution: {integrity: sha1-vXzHCIEZJ3fu9TJsGd60bokJF98=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/pkg-types/-/pkg-types-1.3.1.tgz} + resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==} playwright-core@1.61.1: - resolution: {integrity: sha1-PJmEEwfvu6vJ1yTEGojJFHBdFfw=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/playwright-core/-/playwright-core-1.61.1.tgz} + resolution: {integrity: sha512-h7Qlt6m4REp25qvIdvbDtVmD4LqVXfpRxhORv9L0jzETM05p4fuPJ3dKyuSXQxDSbXnmS79HAgi9589lGSpLkg==} engines: {node: '>=18'} hasBin: true playwright@1.61.1: - resolution: {integrity: sha1-2MDAbrk8KJga/HR7rORTvb1QGLw=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/playwright/-/playwright-1.61.1.tgz} + resolution: {integrity: sha512-DWnY5o3YbLWK4GovuAVwpqL+1VwGNdUGrRr++8j8PtQQzvAVZUIMjKQ90fY689sEJZJBbZVw1rXaOKSTitkzPQ==} engines: {node: '>=18'} hasBin: true points-on-curve@0.2.0: - resolution: {integrity: sha1-fbuYxDeRhZQ0KEdhMw+ok8uBtNE=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/points-on-curve/-/points-on-curve-0.2.0.tgz} + resolution: {integrity: sha512-0mYKnYYe9ZcqMCWhUjItv/oHjvgEsfKvnUTg8sAtnHr3GVy7rGkXCb6d5cSyqrWqL4k81b9CPg3urd+T7aop3A==} points-on-path@0.2.1: - resolution: {integrity: sha1-VTICtUJMU77TcTWzGIWOrP+F3VI=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/points-on-path/-/points-on-path-0.2.1.tgz} + resolution: {integrity: sha512-25ClnWWuw7JbWZcgqY/gJ4FQWadKxGWk+3kR/7kD0tCaDtPPMj7oHu2ToLaVhfpnHrZzYby2w6tUA0eOIuUg8g==} postcss-nested@6.2.0: - resolution: {integrity: sha1-TC0iq18gucth4sXFkVlQeE0GgTE=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/postcss-nested/-/postcss-nested-6.2.0.tgz} + resolution: {integrity: sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==} engines: {node: '>=12.0'} peerDependencies: postcss: '>=8.5.23' postcss-selector-parser@6.1.4: - resolution: {integrity: sha1-/exMqA9Xgb0hbKm/iaKg/M//pfA=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/postcss-selector-parser/-/postcss-selector-parser-6.1.4.tgz} + resolution: {integrity: sha512-bIoJLOmjCO1S9XdY/DcnR5hJxvrDir1PbGChrzXG3vw0/FOliy/fA3dmdhQ441kah4gKv+TwckGzex6wNS5cnQ==} engines: {node: '>=4'} postcss-value-parser@4.2.0: - resolution: {integrity: sha1-cjwJkgg2um0+WvAZ+SvAlxwC5RQ=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz} + resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} postcss@8.5.25: - resolution: {integrity: sha1-UBKlmOqqiX8hu+hVO+PLe9K9eMs=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/postcss/-/postcss-8.5.25.tgz} + resolution: {integrity: sha512-DTPx3RWSSnWyzLxQnlH0rJP+EW5ekl16ZU4/psbIhA0e53kJfdgaN5vKM+xP7yJtXVu+nfdVFmlgFDEKAe4Pyw==} engines: {node: ^10 || ^12 || >=14} prelude-ls@1.2.1: - resolution: {integrity: sha1-3rxkidem5rDnYRiIzsiAM30xY5Y=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/prelude-ls/-/prelude-ls-1.2.1.tgz} + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} prettier-plugin-astro@0.14.1: - resolution: {integrity: sha1-UL/4plnypqT/Ox1+pz8t6TyVshM=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/prettier-plugin-astro/-/prettier-plugin-astro-0.14.1.tgz} + resolution: {integrity: sha512-RiBETaaP9veVstE4vUwSIcdATj6dKmXljouXc/DDNwBSPTp8FRkLGDSGFClKsAFeeg+13SB0Z1JZvbD76bigJw==} engines: {node: ^14.15.0 || >=16.0.0} prettier@3.9.5: - resolution: {integrity: sha1-T+yXc24zudC2ILSJFP6TtTDoNa0=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/prettier/-/prettier-3.9.5.tgz} + resolution: {integrity: sha512-/FVl766LpUfB5vXgCYOYa0MeV/441Ia99AeICQIQFTY/Nw0roZwULcXpku5i1/m5kt/baz+s4Zogspd839HSMg==} engines: {node: '>=14'} hasBin: true prismjs@1.30.0: - resolution: {integrity: sha1-2XCZadnU4WQD9vNIxjVTsZ8Jdak=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/prismjs/-/prismjs-1.30.0.tgz} + resolution: {integrity: sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==} engines: {node: '>=6'} process-ancestry@0.1.0: - resolution: {integrity: sha1-BqGLsGxBPYJ1AhkEWPx2BO5rPe0=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/process-ancestry/-/process-ancestry-0.1.0.tgz} + resolution: {integrity: sha512-tGqJW/UnclpYASFcM6Xh8D8l/BMtaQ9+CSG0vlJSJTcdMM4lDRv4c6H0Pdcsfted+bVczdYSfk2fdukg2gQkZg==} engines: {node: '>=18.0.0'} property-information@7.2.0: - resolution: {integrity: sha1-CAmzQmTplcC/zTInAooeNSEK+Ao=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/property-information/-/property-information-7.2.0.tgz} + resolution: {integrity: sha512-IAtzIB6sUiWaJYrX9smp3V46pBGbBeLFRGdh25kg1334VcBlD8HzhPeNIWQH9zhGmo2itIe25EHt9dQP7G5hmg==} proxy-agent-negotiate@1.1.0: - resolution: {integrity: sha1-3n03rt6dcedDRhJdb0hPrICSthU=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/proxy-agent-negotiate/-/proxy-agent-negotiate-1.1.0.tgz} + resolution: {integrity: sha512-N8IBcM3UgCVzz2L2Lqv8DVntDnnC8/hiV4nEDUPkqq72TPUgYWjQc+bdZlBPZK9LzPAvOY//gAt0S0DApoOXWQ==} engines: {node: '>= 20'} peerDependencies: kerberos: ^2.0.0 @@ -3533,192 +3523,196 @@ packages: optional: true punycode@2.3.1: - resolution: {integrity: sha1-AnQi4vrsCyXhVJw+G9gwm5EztuU=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/punycode/-/punycode-2.3.1.tgz} + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} quansync@1.0.0: - resolution: {integrity: sha1-HCmszNVEzWjZenNQxQmeCpvH5e4=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/quansync/-/quansync-1.0.0.tgz} + resolution: {integrity: sha512-5xZacEEufv3HSTPQuchrvV6soaiACMFnq1H8wkVioctoH3TRha9Sz66lOxRwPK/qZj7HPiSveih9yAyh98gvqA==} queue-microtask@1.2.3: - resolution: {integrity: sha1-SSkii7xyTfrEPg77BYyve2z7YkM=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/queue-microtask/-/queue-microtask-1.2.3.tgz} + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} radix3@1.1.2: - resolution: {integrity: sha1-/SfSrziWxr9Lzfq2Qnxpwq/GnsA=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/radix3/-/radix3-1.1.2.tgz} + resolution: {integrity: sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA==} range-parser@1.3.0: - resolution: {integrity: sha1-1/Gb6BK7YnIUcrRdO+IZ7wlXK0c=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/range-parser/-/range-parser-1.3.0.tgz} + resolution: {integrity: sha512-hek2mFQpPuI4E1BBKrSto+BU3e3x4xuarsbiwr3+lf7p44juvFMV0XFWQAP3xUyqXA4RrXLIoaSUGbSt056ZMw==} engines: {node: '>= 0.6'} readdirp@3.6.0: - resolution: {integrity: sha1-dKNwvYVxFuJFspzJc0DNQxoCpsc=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/readdirp/-/readdirp-3.6.0.tgz} + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} engines: {node: '>=8.10.0'} readdirp@5.0.0: - resolution: {integrity: sha1-+/H3GnJ4kdaFuxeG+bp0CE9uL5E=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/readdirp/-/readdirp-5.0.0.tgz} + resolution: {integrity: sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==} engines: {node: '>= 20.19.0'} recma-build-jsx@1.0.0: - resolution: {integrity: sha1-wC8p4EfhA9L6sgVJVOF2G46iU8Q=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/recma-build-jsx/-/recma-build-jsx-1.0.0.tgz} + resolution: {integrity: sha512-8GtdyqaBcDfva+GUKDr3nev3VpKAhup1+RvkMvUxURHpW7QyIvk9F5wz7Vzo06CEMSilw6uArgRqhpiUcWp8ew==} recma-jsx@1.0.1: - resolution: {integrity: sha1-WOcY9F4hAu0L8vqZTwW3DXaAGho=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/recma-jsx/-/recma-jsx-1.0.1.tgz} + resolution: {integrity: sha512-huSIy7VU2Z5OLv6oFLosQGGDqPqdO1iq6bWNAdhzMxSJP7RAso4fCZ1cKu8j9YHCZf3TPrq4dw3okhrylgcd7w==} peerDependencies: acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 recma-parse@1.0.0: - resolution: {integrity: sha1-w1HhYbsKtH2GuSqYqdiR+baBS1I=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/recma-parse/-/recma-parse-1.0.0.tgz} + resolution: {integrity: sha512-OYLsIGBB5Y5wjnSnQW6t3Xg7q3fQ7FWbw/vcXtORTnyaSFscOtABg+7Pnz6YZ6c27fG1/aN8CjfwoUEUIdwqWQ==} recma-stringify@1.0.0: - resolution: {integrity: sha1-VGMgMGMeDHVGE2/574/ejntE8TA=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/recma-stringify/-/recma-stringify-1.0.0.tgz} + resolution: {integrity: sha512-cjwII1MdIIVloKvC9ErQ+OgAtwHBmcZ0Bg4ciz78FtbT8In39aAYbaA7zvxQ61xVMSPE8WxhLwLbhif4Js2C+g==} regex-recursion@6.0.2: - resolution: {integrity: sha1-oLGXenTIfwczd7k42+36supYKzM=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/regex-recursion/-/regex-recursion-6.0.2.tgz} + resolution: {integrity: sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==} regex-utilities@2.3.0: - resolution: {integrity: sha1-hxY1EqFdzikIzweciWDVFY/0MoA=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/regex-utilities/-/regex-utilities-2.3.0.tgz} + resolution: {integrity: sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==} regex@6.1.0: - resolution: {integrity: sha1-186Y+O4y2nSXwT9mAfyivEpqeAM=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/regex/-/regex-6.1.0.tgz} + resolution: {integrity: sha512-6VwtthbV4o/7+OaAF9I5L5V3llLEsoPyq9P1JVXkedTP33c7MfCG0/5NOPcSJn0TzXcG9YUrR0gQSWioew3LDg==} regexp-tree@0.1.27: - resolution: {integrity: sha1-IZjw71RRj/p0P+dNmDtW/9Yxts0=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/regexp-tree/-/regexp-tree-0.1.27.tgz} + resolution: {integrity: sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA==} hasBin: true rehype-expressive-code@0.44.1: - resolution: {integrity: sha1-puKJiFR7LTBppC69ymlOAhhEzmA=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/rehype-expressive-code/-/rehype-expressive-code-0.44.1.tgz} + resolution: {integrity: sha512-+VZgs7Evw4LXRN3owpoBNSTpYuW6GeOdjqcUT1TuY8o/4MGPtbd0EU7Bgrju7X8KrQ6SslOBAuGWJ5fV5TriJQ==} rehype-format@5.0.1: - resolution: {integrity: sha1-4lXlm+0MBiFWqvUcFvrVpSGh9cg=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/rehype-format/-/rehype-format-5.0.1.tgz} + resolution: {integrity: sha512-zvmVru9uB0josBVpr946OR8ui7nJEdzZobwLOOqHb/OOD88W0Vk2SqLwoVOj0fM6IPCCO6TaV9CvQvJMWwukFQ==} rehype-minify-whitespace@6.0.2: - resolution: {integrity: sha1-fdI0zgd1ZWzmtrCq0KYJPeKbIng=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/rehype-minify-whitespace/-/rehype-minify-whitespace-6.0.2.tgz} + resolution: {integrity: sha512-Zk0pyQ06A3Lyxhe9vGtOtzz3Z0+qZ5+7icZ/PL/2x1SHPbKao5oB/g/rlc6BCTajqBb33JcOe71Ye1oFsuYbnw==} rehype-parse@9.0.1: - resolution: {integrity: sha1-mZO9oSmsxkxBep02VKe+OLKpTCA=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/rehype-parse/-/rehype-parse-9.0.1.tgz} + resolution: {integrity: sha512-ksCzCD0Fgfh7trPDxr2rSylbwq9iYDkSn8TCDmEJ49ljEUBxDVCzCHv7QNzZOfODanX4+bWQ4WZqLCRWYLfhag==} rehype-raw@7.0.0: - resolution: {integrity: sha1-Wdc0j9Xb7zgHu6odRD79LdhezuQ=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/rehype-raw/-/rehype-raw-7.0.0.tgz} + resolution: {integrity: sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==} rehype-recma@1.0.0: - resolution: {integrity: sha1-1o72NE0FkWvZbiVADGJhd1QRqnY=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/rehype-recma/-/rehype-recma-1.0.0.tgz} + resolution: {integrity: sha512-lqA4rGUf1JmacCNWWZx0Wv1dHqMwxzsDWYMTowuplHF3xH0N/MmrZ/G3BDZnzAkRmxDadujCjaKM2hqYdCBOGw==} rehype-remark@10.0.1: - resolution: {integrity: sha1-9mn6aM+4tbqvT6lUdqkjUWERpDs=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/rehype-remark/-/rehype-remark-10.0.1.tgz} + resolution: {integrity: sha512-EmDndlb5NVwXGfUa4c9GPK+lXeItTilLhE6ADSaQuHr4JUlKw9MidzGzx4HpqZrNCt6vnHmEifXQiiA+CEnjYQ==} rehype-stringify@10.0.1: - resolution: {integrity: sha1-LsHrxWxqugeQXTtEcL3w9oTzC3U=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/rehype-stringify/-/rehype-stringify-10.0.1.tgz} + resolution: {integrity: sha512-k9ecfXHmIPuFVI61B9DeLPN0qFHfawM6RsuX48hoqlaKSF61RskNjSm1lI8PhBEM0MRdLxVVm4WmTqJQccH9mA==} rehype@13.0.2: - resolution: {integrity: sha1-qws6wmVz17JloAmf7/rUUOTPGVI=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/rehype/-/rehype-13.0.2.tgz} + resolution: {integrity: sha512-j31mdaRFrwFRUIlxGeuPXXKWQxet52RBQRvCmzl5eCefn/KGbomK5GMHNMsOJf55fgo3qw5tST5neDuarDYR2A==} remark-directive@4.0.0: - resolution: {integrity: sha1-TpCYJuBcref4Z4Uy9IFc2THUfo0=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/remark-directive/-/remark-directive-4.0.0.tgz} + resolution: {integrity: sha512-7sxn4RfF1o3izevPV1DheyGDD6X4c9hrGpfdUpm7uC++dqrnJxIZVkk7CoKqcLm0VUMAuOol7Mno3m6g8cfMuA==} remark-gfm@4.0.1: - resolution: {integrity: sha1-MyJ7KnQ5dnDTV78FwJjq+FE/DWs=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/remark-gfm/-/remark-gfm-4.0.1.tgz} + resolution: {integrity: sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==} remark-mdx@3.1.1: - resolution: {integrity: sha1-BH+XA4vH7Dh667SwpP4jd5mZ2EU=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/remark-mdx/-/remark-mdx-3.1.1.tgz} + resolution: {integrity: sha512-Pjj2IYlUY3+D8x00UJsIOg5BEvfMyeI+2uLPn9VO9Wg4MEtN/VTIq2NEJQfde9PnX15KgtHyl9S0BcTnWrIuWg==} remark-parse@11.0.0: - resolution: {integrity: sha1-qmB0P8s36/awaSBOtNowTkDbRaE=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/remark-parse/-/remark-parse-11.0.0.tgz} + resolution: {integrity: sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==} remark-rehype@11.1.2: - resolution: {integrity: sha1-Kt2q3agMqb2aoNp2PnTRYydoOzc=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/remark-rehype/-/remark-rehype-11.1.2.tgz} + resolution: {integrity: sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==} remark-smartypants@3.0.2: - resolution: {integrity: sha1-y68rOWJMePy9bvoiRnjB0um8Hfs=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/remark-smartypants/-/remark-smartypants-3.0.2.tgz} + resolution: {integrity: sha512-ILTWeOriIluwEvPjv67v7Blgrcx+LZOkAUVtKI3putuhlZm84FnqDORNXPPm+HY3NdZOMhyDwZ1E+eZB/Df5dA==} engines: {node: '>=16.0.0'} remark-stringify@11.0.0: - resolution: {integrity: sha1-TFsB3XEcJp3xqq4RdD634udjb9M=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/remark-stringify/-/remark-stringify-11.0.0.tgz} + resolution: {integrity: sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==} resolve-pkg-maps@1.0.0: - resolution: {integrity: sha1-YWs9wsVwVrVYjDHN9LPWTbEzcg8=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz} + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} retext-latin@4.0.0: - resolution: {integrity: sha1-0CSYqh/TnxvwDi/1mxOEwF0MfOM=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/retext-latin/-/retext-latin-4.0.0.tgz} + resolution: {integrity: sha512-hv9woG7Fy0M9IlRQloq/N6atV82NxLGveq+3H2WOi79dtIYWN8OaxogDm77f8YnVXJL2VD3bbqowu5E3EMhBYA==} retext-smartypants@6.2.0: - resolution: {integrity: sha1-ToUsKXTPLPolPu7EJ8l+/EO10Vg=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/retext-smartypants/-/retext-smartypants-6.2.0.tgz} + resolution: {integrity: sha512-kk0jOU7+zGv//kfjXEBjdIryL1Acl4i9XNkHxtM7Tm5lFiCog576fjNC9hjoR7LTKQ0DsPWy09JummSsH1uqfQ==} retext-stringify@4.0.0: - resolution: {integrity: sha1-UB1UQL1NEh41HHxQn4UH3pYR4Vk=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/retext-stringify/-/retext-stringify-4.0.0.tgz} + resolution: {integrity: sha512-rtfN/0o8kL1e+78+uxPTqu1Klt0yPzKuQ2BfWwwfgIUSayyzxpM1PJzkKt4V8803uB9qSy32MvI7Xep9khTpiA==} retext@9.0.0: - resolution: {integrity: sha1-q1zXKDaJQWewymrnD9z6oWYmf3o=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/retext/-/retext-9.0.0.tgz} + resolution: {integrity: sha512-sbMDcpHCNjvlheSgMfEcVrZko3cDzdbe1x/e7G66dFp0Ff7Mldvi2uv6JkJQzdRcvLYE8CA8Oe8siQx8ZOgTcA==} reusify@1.1.0: - resolution: {integrity: sha1-D+E7lSLhRz9RtVjueW4I8R+bSJ8=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/reusify/-/reusify-1.1.0.tgz} + resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} robust-predicates@3.0.3: - resolution: {integrity: sha1-EJkGGzNJ4sWr7GwqsKzUQNJNQGI=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/robust-predicates/-/robust-predicates-3.0.3.tgz} + resolution: {integrity: sha512-NS3levdsRIUOmiJ8FZWCP7LG3QpJyrs/TE0Zpf1yvZu8cAJJ6QMW92H1c7kWpdIHo8RvmLxN/o2JXTKHp74lUA==} rolldown@1.1.5: - resolution: {integrity: sha1-M5quJQhENR/FW3TiZS0+vW+6OJ0=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/rolldown/-/rolldown-1.1.5.tgz} + resolution: {integrity: sha512-t9z29cJjXf/vxQ8dyhCSpt6H6aSwHTk8cT5I3iy6SMXuFpk5mB6PL6XfC8PCwrPTx93udwKUm9HRteAlTGBLiA==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true roughjs@4.6.6: - resolution: {integrity: sha1-EFn0ml4MgN7lQaAFsgzDIrIiFYs=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/roughjs/-/roughjs-4.6.6.tgz} + resolution: {integrity: sha512-ZUz/69+SYpFN/g/lUlo2FXcIjRkSu3nDarreVdGGndHEBJ6cXPdKguS8JGxwj5HA5xIbVKSmLgr5b3AWxtRfvQ==} run-parallel@1.2.0: - resolution: {integrity: sha1-ZtE2jae9+SHrnZW9GpIp5/IaQ+4=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/run-parallel/-/run-parallel-1.2.0.tgz} + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} rw@1.3.3: - resolution: {integrity: sha1-P4Yt+pGrdmsUiF700BEkv9oHT7Q=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/rw/-/rw-1.3.3.tgz} + resolution: {integrity: sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==} s.color@0.0.15: - resolution: {integrity: sha1-azLNItjbqVcDpRIt3t4gIKFWAYY=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/s.color/-/s.color-0.0.15.tgz} + resolution: {integrity: sha512-AUNrbEUHeKY8XsYr/DYpl+qk5+aM+DChopnWOPEzn8YKzOhv4l2zH6LzZms3tOZP3wwdOyc0RmTciyi46HLIuA==} safer-buffer@2.1.2: - resolution: {integrity: sha1-RPoWGwGHuVSd2Eu5GAL5vYOFzWo=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/safer-buffer/-/safer-buffer-2.1.2.tgz} + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} sass-formatter@0.7.9: - resolution: {integrity: sha1-z3fgLpj4Haq9kbGFGSFE0p/ATKU=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/sass-formatter/-/sass-formatter-0.7.9.tgz} + resolution: {integrity: sha512-CWZ8XiSim+fJVG0cFLStwDvft1VI7uvXdCNJYXhDvowiv+DsbD1nXLiQ4zrE5UBvj5DWZJ93cwN0NX5PMsr1Pw==} satori@0.28.1: - resolution: {integrity: sha1-IxqwzxxAN1lVPbOn3PwHk/dwfYc=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/satori/-/satori-0.28.1.tgz} + resolution: {integrity: sha512-PjF/PhstPlvBHxsBhMi8A8F2z9pgd1VkEI8a7n2ZkFg4cKE1f8rRP/LGiXLv3EFTw7a2gr9wS2pWwgMYdVJKUg==} engines: {node: '>=16'} satteri@0.10.5: - resolution: {integrity: sha1-S0Sk8OIuZDlkjgZd38E0hj/SjDE=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/satteri/-/satteri-0.10.5.tgz} + resolution: {integrity: sha512-Ao1LKpAEa9Wdg0otgbVKViZHEq9ebdXe4DMrp3s9vQAU0HNIuHnFEuMuOcm0ZIXyV0Yzxj91NvhLpvXZJO/5ZQ==} satteri@0.9.5: - resolution: {integrity: sha1-J8h+v3YIuxYfTLUQi5YchDjBiLc=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/satteri/-/satteri-0.9.5.tgz} + resolution: {integrity: sha512-ZuWVl+vnM64y+/TtX8Kosv2c00W+hLQiiwnEL6H0UKVVrxFqMw4D2CJHHQaouVd89OAhtBBfjWLqhKi3TVUV4w==} + + sax@1.6.0: + resolution: {integrity: sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA==} + engines: {node: '>=11.0.0'} sax@1.6.1: - resolution: {integrity: sha1-TCPPYIwLaTq1S0tYiOks/pd7mEM=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/sax/-/sax-1.6.1.tgz} + resolution: {integrity: sha512-42tBVwLWnaQvW5zc4HbZrTuWccECCZfBi92FDuwtqxasH+JbPB3/FOKb1m222K42R4WxuxzzMsTswfzgtSu64Q==} engines: {node: '>=11.0.0'} semver@7.8.5: - resolution: {integrity: sha1-ObZGA33VDBT7RR5+TKxY7YuGP2k=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/semver/-/semver-7.8.5.tgz} + resolution: {integrity: sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==} engines: {node: '>=10'} hasBin: true send@1.2.1: - resolution: {integrity: sha1-nqt0O4dPNVD0CiaGe/KGrWDT8+0=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/send/-/send-1.2.1.tgz} + resolution: {integrity: sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==} engines: {node: '>= 18'} seroval-plugins@1.5.6: - resolution: {integrity: sha1-e8pJWs61skKLnLRLSwnmfC3hyUg=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/seroval-plugins/-/seroval-plugins-1.5.6.tgz} + resolution: {integrity: sha512-HXuLAX2pu/UByPpaeo/TaMfvMIi+1QqIoPJYCcAtU8QkVNwgR6MPlGuCQTErV1JwraaMbYaWVIBX7mppzGLATQ==} engines: {node: '>=10'} peerDependencies: seroval: '>=1.4.1' seroval@1.5.6: - resolution: {integrity: sha1-aNT2oFw73iXaquprciAUb/QjU8o=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/seroval/-/seroval-1.5.6.tgz} + resolution: {integrity: sha512-rVQVWjjSvlINzaQPZH5JFqsqEsIWdTxY3iJZCnTL/5gQbXIRooVZKI60tVCkOVfzcRPejboxO2t0P89dg5mQaA==} engines: {node: '>=10'} server-destroy@1.0.1: - resolution: {integrity: sha1-8Tv5KOQrnD55OD5hzDmYtdFObN0=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/server-destroy/-/server-destroy-1.0.1.tgz} + resolution: {integrity: sha512-rb+9B5YBIEzYcD6x2VKidaa+cqYBJQKnU4oe4E3ANwRRN56yk/ua1YCJT1n21NTS8w6CcOclAKNP3PhdCXKYtQ==} setprototypeof@1.2.0: - resolution: {integrity: sha1-ZsmiSnP5/CjL5msJ/tPTPcrxtCQ=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/setprototypeof/-/setprototypeof-1.2.0.tgz} + resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} sharp@0.35.4: - resolution: {integrity: sha1-Nh3zspWdrrOAVBKJlgRWxr4Pkt4=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/sharp/-/sharp-0.35.4.tgz} + resolution: {integrity: sha512-n++8XWcj+jCOr2IOl7h8LbKnGBDY4aPbmprMONBNFdn0ImXqpGVv5zliDs0V9HbmbCQLpbuo2ej9rAoOQTvMDA==} engines: {node: '>=20.9.0'} peerDependencies: '@types/node': '*' @@ -3727,110 +3721,110 @@ packages: optional: true shebang-command@2.0.0: - resolution: {integrity: sha1-zNCvT4g1+9wmW4JGGq8MNmY/NOo=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/shebang-command/-/shebang-command-2.0.0.tgz} + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} engines: {node: '>=8'} shebang-regex@3.0.0: - resolution: {integrity: sha1-rhbxZE2HPsrYQ7AwexQzYtTEIXI=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/shebang-regex/-/shebang-regex-3.0.0.tgz} + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} shiki@4.3.1: - resolution: {integrity: sha1-Cmq/ptAGRmtemy9u7Hnm4QWpPAA=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/shiki/-/shiki-4.3.1.tgz} + resolution: {integrity: sha512-oR+qDVi2OjX1tmDpyv+3KviX01KzO6Af+0NNnKnsp9491UEGz2YpxTuJboS/6VhYpTdqzmuJBuiTlrAWWJAssw==} engines: {node: '>=20'} shiki@4.4.2: - resolution: {integrity: sha1-fIrhXeAymnstqPyLBs5C090YzK8=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/shiki/-/shiki-4.4.2.tgz} + resolution: {integrity: sha512-P8F/dFhRevaw2uSdeIYlq/5SXZNY85DPtmXQ947gD1Zj2JqO5AkNvVVBar0Me9JkFx3uzVud/qOtP5ek9NEQGA==} engines: {node: '>=20'} siginfo@2.0.0: - resolution: {integrity: sha1-MudscLeXJOO7Vny51UPrhYzPrzA=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/siginfo/-/siginfo-2.0.0.tgz} + resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} signal-exit@4.1.0: - resolution: {integrity: sha1-lSGIwcvVRgcOLdIND0HArgUwywQ=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/signal-exit/-/signal-exit-4.1.0.tgz} + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} engines: {node: '>=14'} simple-git@3.36.0: - resolution: {integrity: sha1-AZsowKNYR+40KZxvtjdwqxst/7c=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/simple-git/-/simple-git-3.36.0.tgz} + resolution: {integrity: sha512-cGQjLjK8bxJw4QuYT7gxHw3/IouVESbhahSsHrX97MzCL1gu2u7oy38W6L2ZIGECEfIBG4BabsWDPjBxJENv9Q==} sirv@3.0.2: - resolution: {integrity: sha1-93X8zxDiKkCDJoSEjWNjRvQc2XA=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/sirv/-/sirv-3.0.2.tgz} + resolution: {integrity: sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g==} engines: {node: '>=18'} sisteransi@1.0.5: - resolution: {integrity: sha1-E01oEpd1ZDfMBcoBNw06elcQde0=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/sisteransi/-/sisteransi-1.0.5.tgz} + resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} sitemap@9.0.1: - resolution: {integrity: sha1-M+mwniF364luBbFtpCGfU5GYQvY=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/sitemap/-/sitemap-9.0.1.tgz} + resolution: {integrity: sha512-S6hzjGJSG3d6if0YoF5kTyeRJvia6FSTBroE5fQ0bu1QNxyJqhhinfUsXi9fH3MgtXODWvwo2BDyQSnhPQ88uQ==} engines: {node: '>=20.19.5', npm: '>=10.8.2'} hasBin: true smol-toml@1.7.1: - resolution: {integrity: sha1-uj4o0uQ0iHSoJP2OHXP+xhjLdjs=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/smol-toml/-/smol-toml-1.7.1.tgz} + resolution: {integrity: sha512-PPlsspAZ4jbMBu5DMFhfUGDQLu/vrL4SyBROVS37x8ynnVmFIs1VPBz1Co8Xks3TvpIaZXmU85y4DrQ+UyVFoQ==} engines: {node: '>= 18'} solid-js@1.9.14: - resolution: {integrity: sha1-saezBkALNIaNAHI7NOyRR/NFCfs=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/solid-js/-/solid-js-1.9.14.tgz} + resolution: {integrity: sha512-sAEXC0Kk0S1EDg+8ysEWJDbYhA3RRoEjwuySUGlKIemeo0I5YZfOyumNjNs9Sv3y2nmhD+0rW66ag2HsMuQiGQ==} solid-transition-group@0.2.3: - resolution: {integrity: sha1-70QdnkYgzdxNKc28lYsJ+U21FcQ=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/solid-transition-group/-/solid-transition-group-0.2.3.tgz} + resolution: {integrity: sha512-iB72c9N5Kz9ykRqIXl0lQohOau4t0dhel9kjwFvx81UZJbVwaChMuBuyhiZmK24b8aKEK0w3uFM96ZxzcyZGdg==} engines: {node: '>=18.0.0', pnpm: '>=8.6.0'} peerDependencies: solid-js: ^1.6.12 source-map-js@1.2.1: - resolution: {integrity: sha1-HOVlD93YerwJnto33P8CTCZnrkY=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/source-map-js/-/source-map-js-1.2.1.tgz} + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} engines: {node: '>=0.10.0'} source-map@0.7.6: - resolution: {integrity: sha1-o2WKuH5bZCnIofO6AIPUxhyj7wI=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/source-map/-/source-map-0.7.6.tgz} + resolution: {integrity: sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==} engines: {node: '>= 12'} space-separated-tokens@2.0.2: - resolution: {integrity: sha1-Hs2dI1CjhEVyw/SjErzrAYNIhZ8=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz} + resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} stackback@0.0.2: - resolution: {integrity: sha1-Gsig2Ug4SNFpXkGLbQMaPDzmjjs=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/stackback/-/stackback-0.0.2.tgz} + resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} starlight-github-alerts@0.4.0: - resolution: {integrity: sha1-YOn/tsyEJkSp7ZTTLBXTCHM/5hg=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/starlight-github-alerts/-/starlight-github-alerts-0.4.0.tgz} + resolution: {integrity: sha512-YxyL1OKed12ZcvdgHXA2iZX21Cz9h0Ei7DuAzHym6nbt5St0V3/w2djjM+/z05ktp0fA3F+BkOgWc6je4BOf/w==} engines: {node: '>=22.12.0'} peerDependencies: '@astrojs/starlight': '>=0.41.0' starlight-image-zoom@0.15.0: - resolution: {integrity: sha1-31PnUZaLVjOeZeRYD13krDEvWrc=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/starlight-image-zoom/-/starlight-image-zoom-0.15.0.tgz} + resolution: {integrity: sha512-GIZVuaiaVuFsbyYqiT7M4FYJBvkTsvdO1XoOKM/iNHt85BaVn/A7/kLpdb5XnUsAZohOMS77ahaolofnGIqeOQ==} engines: {node: '>=22.12.0'} peerDependencies: '@astrojs/starlight': '>=0.41.0' starlight-kbd@0.4.0: - resolution: {integrity: sha1-/IH/em1TGMYmH7PmOBqkZ635yVE=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/starlight-kbd/-/starlight-kbd-0.4.0.tgz} + resolution: {integrity: sha512-Uz/MimnPaRqHsv2EllVnkD78ab2k3SQbVls3VZ53nUMbPMjIzg0+evgicqxrF8ZukQSRdve5sykKlbBEdH4xzQ==} engines: {node: '>=22.12.0'} peerDependencies: '@astrojs/starlight': '>=0.38.0' starlight-links-validator@0.25.2: - resolution: {integrity: sha1-DwqPY9kQvsC6fxvooTVFpuX8fMo=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/starlight-links-validator/-/starlight-links-validator-0.25.2.tgz} + resolution: {integrity: sha512-RQiHkM8FHKermsjMkSb+uS/q50Dv5P0O0ECWKxJyTv4stuO8QTorIEKnITDDLEf9/xyg7M69arxiK2ola3OMqA==} engines: {node: '>=22.12.0'} peerDependencies: '@astrojs/starlight': '>=0.41.0' astro: '>=7.0.2' starlight-llms-txt@0.11.0: - resolution: {integrity: sha1-rn60EiO0I8icxTLp6FDrHflzCGE=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/starlight-llms-txt/-/starlight-llms-txt-0.11.0.tgz} + resolution: {integrity: sha512-83TU5zPgJhL9fXIWAOWjQjyQ6EKocshEjJyA4zOJjOqu/oxQsrTpYGYxjHLyfZe4LRD52N9eCuykSkaIYwUyDw==} peerDependencies: '@astrojs/starlight': '>=0.41.0' astro: ^7.0.0 starlight-page-actions@0.7.0: - resolution: {integrity: sha1-A27Npc9UhP2rH1cNHodavYvlgIQ=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/starlight-page-actions/-/starlight-page-actions-0.7.0.tgz} + resolution: {integrity: sha512-zZFtBB1x5KKfgh/P0iki0JJleaAu2I0isnqze1B2ThPMlhUrZEmMyHouq7Altff6mmiSSQRvAhHGK7kP5xwLdQ==} engines: {node: ^22.0.0 || >=24.0.0} peerDependencies: '@astrojs/starlight': '>=0.36.0' astro: '>=5.6.0' starlight-plugin-icons@1.1.6: - resolution: {integrity: sha1-f94WfWUmDpgrarbyVl+LqkoEcYg=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/starlight-plugin-icons/-/starlight-plugin-icons-1.1.6.tgz} + resolution: {integrity: sha512-Gke6ASVr918GmT2F1AtVKa5+iUC30Qw5nefUTOMY6DG9D0ca1VzM7H9UkZKrCqhSOop8XlK1eceKL54rTxdn6g==} peerDependencies: '@astrojs/starlight': '>=0.35.0' astro: '>=4' @@ -3839,228 +3833,228 @@ packages: zod: '>=3.22.0 || >=4.0.0' starlight-sidebar-topics@0.8.0: - resolution: {integrity: sha1-XkGS2bpDeUxKcGMYLVtAMOZX8VM=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/starlight-sidebar-topics/-/starlight-sidebar-topics-0.8.0.tgz} + resolution: {integrity: sha512-hE8+w2vNL13h6cq3UJGl05milJQ3+1BSlhaV5V4a993YzYczU6uLAj6jfUDKQ2mmgkdVWp8/UNDF4Je/rQXNQw==} engines: {node: '>=22.12.0'} peerDependencies: '@astrojs/starlight': '>=0.38.0' statuses@2.0.2: - resolution: {integrity: sha1-j3XuzvdlteHPzcCA2llAntQk44I=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/statuses/-/statuses-2.0.2.tgz} + resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} engines: {node: '>= 0.8'} std-env@4.2.0: - resolution: {integrity: sha1-jr4OxgSFZoq0ciezEvQlTN+AydM=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/std-env/-/std-env-4.2.0.tgz} + resolution: {integrity: sha512-oCUKSupKTHX53EyjDtuZQ64pjLJ6yYCtpmEw0goYxtjG9KpbRe8KAsl2tBUGU9DyMcJ0RwJ8GqJAFzMXcXW1Rw==} stream-replace-string@2.0.0: - resolution: {integrity: sha1-5J/VhL0cYzYT4BC8c7nbSctQJK0=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/stream-replace-string/-/stream-replace-string-2.0.0.tgz} + resolution: {integrity: sha512-TlnjJ1C0QrmxRNrON00JvaFFlNh5TTG00APw23j74ET7gkQpTASi6/L2fuiav8pzK715HXtUeClpBTw2NPSn6w==} string.prototype.codepointat@0.2.1: - resolution: {integrity: sha1-AErUTIr8cnUnsQjNRitNlxzUabw=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/string.prototype.codepointat/-/string.prototype.codepointat-0.2.1.tgz} + resolution: {integrity: sha512-2cBVCj6I4IOvEnjgO/hWqXjqBGsY+zwPmHl12Srk9IXSZ56Jwwmy+66XO5Iut/oQVR7t5ihYdLB0GMa4alEUcg==} stringify-entities@4.0.4: - resolution: {integrity: sha1-s7ee9fJ3zErHPK6wI2xbqTmzpPM=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/stringify-entities/-/stringify-entities-4.0.4.tgz} + resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==} strnum@2.4.1: - resolution: {integrity: sha1-hUF/aDETut6g/n4XInZ2+In/flg=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/strnum/-/strnum-2.4.1.tgz} + resolution: {integrity: sha512-M9eUSMT2dCB2cTNPG7UYj6KuK7RJR2SN2+yCV/fTW3xzTCS6EaGZ5pSMgDIjB7r8zSfTGk+dvvn9rTjpVS9Mwg==} style-to-js@1.1.21: - resolution: {integrity: sha1-KQiUEYf4V+eeKOnNeACLmgs+Do0=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/style-to-js/-/style-to-js-1.1.21.tgz} + resolution: {integrity: sha512-RjQetxJrrUJLQPHbLku6U/ocGtzyjbJMP9lCNK7Ag0CNh690nSH8woqWH9u16nMjYBAok+i7JO1NP2pOy8IsPQ==} style-to-object@1.0.14: - resolution: {integrity: sha1-HSLw5yZruMbYyuXK9OxPAF4I9hE=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/style-to-object/-/style-to-object-1.0.14.tgz} + resolution: {integrity: sha512-LIN7rULI0jBscWQYaSswptyderlarFkjQ+t79nzty8tcIAceVomEVlLzH5VP4Cmsv6MtKhs7qaAiwlcp+Mgaxw==} stylis@4.4.0: - resolution: {integrity: sha1-xYRsk0X0v8Ub0MvXyjWgdE9IWl0=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/stylis/-/stylis-4.4.0.tgz} + resolution: {integrity: sha512-5Z9ZpRzfuH6l/UAvCPAPUo3665Nk2wLaZU3x+TLHKVzIz33+sbJqbtrYoC3KD4/uVOr2Zp+L0LySezP9OHV9yA==} suf-log@2.5.3: - resolution: {integrity: sha1-CRmn/O6lMqmbV4yXgUxOM1stZNE=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/suf-log/-/suf-log-2.5.3.tgz} + resolution: {integrity: sha512-KvC8OPjzdNOe+xQ4XWJV2whQA0aM1kGVczMQ8+dStAO6KfEB140JEVQ9dE76ONZ0/Ylf67ni4tILPJB41U0eow==} supports-color@10.2.2: - resolution: {integrity: sha1-RmwpeMxc0AUtVCoLV2RhwrgC67Q=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/supports-color/-/supports-color-10.2.2.tgz} + resolution: {integrity: sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g==} engines: {node: '>=18'} supports-hyperlinks@4.5.0: - resolution: {integrity: sha1-XlzXRUKjGub9+6514TYrewCcdM0=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/supports-hyperlinks/-/supports-hyperlinks-4.5.0.tgz} + resolution: {integrity: sha512-ZW2OvfeCXrNTbLakPUzjQG922EeGCOteFSVoek5DKStTh898wf7zgtuFlzQN8HfZCxC3Eh02yJVrRW51hADf+w==} engines: {node: '>=20'} svgo@4.1.0: - resolution: {integrity: sha1-yXfraWQO8jKl6CNqWjJ+2MnVKFM=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/svgo/-/svgo-4.1.0.tgz} + resolution: {integrity: sha512-bkxnTg1kSU0guhIBmibA6UUhrQmPVA1XsQLN+ylCd+UWzbnLkySOcXpyk1mrl05f+pcaCx2eHb+sp6BgMZWX+Q==} engines: {node: '>=16'} hasBin: true terminal-link@5.0.0: - resolution: {integrity: sha1-8ER8iUBBirSbm5u8R6StL6i6gec=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/terminal-link/-/terminal-link-5.0.0.tgz} + resolution: {integrity: sha512-qFAy10MTMwjzjU8U16YS4YoZD+NQLHzLssFMNqgravjbvIPNiqkGFR4yjhJfmY9R5OFU7+yHxc6y+uGHkKwLRA==} engines: {node: '>=20'} tidymd@0.1.0: - resolution: {integrity: sha1-2mB1zCHSVk2cn//gdtPafFLf3D4=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/tidymd/-/tidymd-0.1.0.tgz} + resolution: {integrity: sha512-zgwjLyj5KvZSNtoAFZgq7AVXuztNamC69/NNPjd4LJ/DnF3l4kCCgj9u82TO+LbZ7F+lOo8Vc+FPMfBFG4nz+Q==} tiny-inflate@1.0.3: - resolution: {integrity: sha1-EicVSUkToYBRZqr3yTRnkz7qJsQ=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/tiny-inflate/-/tiny-inflate-1.0.3.tgz} + resolution: {integrity: sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==} tinybench@2.9.0: - resolution: {integrity: sha1-EDyfi6bXI3pHq23R3P93JRhjQms=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/tinybench/-/tinybench-2.9.0.tgz} + resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} tinyclip@0.1.15: - resolution: {integrity: sha1-2zXqor1f5iez7y6jjYsEB/K8Le8=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/tinyclip/-/tinyclip-0.1.15.tgz} + resolution: {integrity: sha512-uo33abH+Ays0xYaDysoBt494Hb3hsEczMpcC0MwFl773pazORx4fmvKhclhR1wonUbB6vvpRsvVMwnhfqeMc+A==} engines: {node: ^16.14.0 || >= 17.3.0} tinyexec@1.3.0: - resolution: {integrity: sha1-qswdux1Ok+atjdZJROCfmtFHpHQ=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/tinyexec/-/tinyexec-1.3.0.tgz} + resolution: {integrity: sha512-QKAl9m8gWWGHV8jZcPeym6j+XULi6tOf1mT83WYJ4Lk2ytW/uwAWkrP0uFsdoYMdueVJ0qs26wZ+23xeB4ibNQ==} engines: {node: '>=18'} tinyglobby@0.2.17: - resolution: {integrity: sha1-ViqabJ6ys7Ej05cZ+a9btE/NdjE=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/tinyglobby/-/tinyglobby-0.2.17.tgz} + resolution: {integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==} engines: {node: '>=12.0.0'} tinyrainbow@3.1.0: - resolution: {integrity: sha1-HYpiOJP5XPCi3bnl0RFQ4ZFAlCE=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/tinyrainbow/-/tinyrainbow-3.1.0.tgz} + resolution: {integrity: sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==} engines: {node: '>=14.0.0'} tippy.js@6.3.7: - resolution: {integrity: sha1-jM+2UdZCAQ7Zoy/ymw6eGcW4xhw=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/tippy.js/-/tippy.js-6.3.7.tgz} + resolution: {integrity: sha512-E1d3oP2emgJ9dRQZdf3Kkn0qJgI6ZLpyS5z6ZkY1DF3kaQaBsGZsndEpHwx+eC+tYM41HaSNvNtLx8tU57FzTQ==} to-regex-range@5.0.1: - resolution: {integrity: sha1-FkjESq58jZiKMmAY7XL1tN0DkuQ=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/to-regex-range/-/to-regex-range-5.0.1.tgz} + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} toidentifier@1.0.1: - resolution: {integrity: sha1-O+NDIaiKgg7RvYDfqjPkefu43TU=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/toidentifier/-/toidentifier-1.0.1.tgz} + resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} engines: {node: '>=0.6'} totalist@3.0.1: - resolution: {integrity: sha1-ujo9YAyRWxqXhyNI95wSdHX2rPg=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/totalist/-/totalist-3.0.1.tgz} + resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==} engines: {node: '>=6'} trim-lines@3.0.1: - resolution: {integrity: sha1-2ALjMqB9+GHEiALAQyEBexvYczg=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/trim-lines/-/trim-lines-3.0.1.tgz} + resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} trim-trailing-lines@2.1.0: - resolution: {integrity: sha1-mqx+ibCcs1ut9mPecTPG3hZPht8=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/trim-trailing-lines/-/trim-trailing-lines-2.1.0.tgz} + resolution: {integrity: sha512-5UR5Biq4VlVOtzqkm2AZlgvSlDJtME46uV0br0gENbwN4l5+mMKT4b9gJKqWtuL2zAIqajGJGuvbCbcAJUZqBg==} trough@2.2.0: - resolution: {integrity: sha1-lKYL1r03XBUsHfkRpLEdWwJW9Q8=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/trough/-/trough-2.2.0.tgz} + resolution: {integrity: sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==} ts-api-utils@2.5.0: - resolution: {integrity: sha1-Ss1KFV4ic0mQpe0f6el/ETvLN8E=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/ts-api-utils/-/ts-api-utils-2.5.0.tgz} + resolution: {integrity: sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==} engines: {node: '>=18.12'} peerDependencies: typescript: '>=4.8.4' ts-dedent@2.3.0: - resolution: {integrity: sha1-j6w2x5ArVBwVSsE6J6xGeZevEfg=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/ts-dedent/-/ts-dedent-2.3.0.tgz} + resolution: {integrity: sha512-JfJeIHke7y2egdGGgRAvpCwYFUsHlM2gPcrVOxFkznt/4uzQ7HFmvE63iFHVLBJNDuyDOQgijDK/tXH/f6Msjg==} engines: {node: '>=6.10'} tslib@2.8.1: - resolution: {integrity: sha1-YS7+TtI11Wfoq6Xypfq3AoCt6D8=, tarball: https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/tslib/-/tslib-2.8.1.tgz} + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} tsx@4.23.1: - resolution: {integrity: sha1-FwPaAC7kQyuaBTkXQx+RRi/KI1s=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/tsx/-/tsx-4.23.1.tgz} + resolution: {integrity: sha512-GQHnkIfxyx1wYCOS/wonik5MVRZU9hi1TEZmzGZSCJB1y9YgoZ8H6itNE/u4suE+yLmOzuE4E5S4TZ/ZX2wcWQ==} engines: {node: '>=18.0.0'} hasBin: true twoslash-eslint@0.3.9: - resolution: {integrity: sha1-4g045UiLHD5brmbZlfTEL3uCco8=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/twoslash-eslint/-/twoslash-eslint-0.3.9.tgz} + resolution: {integrity: sha512-KxXHj3iCSIR3blHk7OUI0WqXpR9brhOW8/DYQ54ghijmKmH0BBZFETJetWERAD823tTnXbugvRx89XHQNDNkww==} peerDependencies: eslint: '>=8.50.0' twoslash-protocol@0.3.9: - resolution: {integrity: sha1-WBX/Rj/6jIQXkb9/TrVV8Szo1pw=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/twoslash-protocol/-/twoslash-protocol-0.3.9.tgz} + resolution: {integrity: sha512-9/iwp+CXOnjFMPQuPL5PkuRbZnDoNpBvtJCLs9t8kDYkL3YHujbvnHfZA1i5fApDftVEdBw+T/4F+dH5kIzpYQ==} type-check@0.4.0: - resolution: {integrity: sha1-B7ggO/pwVsBlcFDjzNLDdzC6uPE=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/type-check/-/type-check-0.4.0.tgz} + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} type-level-regexp@0.1.17: - resolution: {integrity: sha1-7Bv33WW4UgH5hjAx1vAjve/CQQ8=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/type-level-regexp/-/type-level-regexp-0.1.17.tgz} + resolution: {integrity: sha512-wTk4DH3cxwk196uGLK/E9pE45aLfeKJacKmcEgEOA/q5dnPGNxXt0cfYdFxb57L+sEpf1oJH4Dnx/pnRcku9jg==} typescript-eslint@8.65.0: - resolution: {integrity: sha1-dUyVP9apo9NvpUAVvbqApusqSVc=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/typescript-eslint/-/typescript-eslint-8.65.0.tgz} + resolution: {integrity: sha512-/ggrHAwyjENDusvyxbuqxAC2dTnZg/Z8F+fgQtYIz+L6n/9HfSlEZcFGV/NsMNa6CkGk0xUjUAFwC0vHOflvIA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' typescript@6.0.3: - resolution: {integrity: sha1-kCUdwAeRbpcnhsuU100VsYVXfSE=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/typescript/-/typescript-6.0.3.tgz} + resolution: {integrity: sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==} engines: {node: '>=14.17'} hasBin: true ufo@1.6.4: - resolution: {integrity: sha1-eo+4dfzGOC0sfQs2knOLBQCpJGc=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/ufo/-/ufo-1.6.4.tgz} + resolution: {integrity: sha512-JFNbkD1Svwe0KvGi8GOeLcP4kAWQ609twvCdcHxq1oSL8svv39ZuSvajcD8B+5D0eL4+s1Is2D/O6KN3qcTeRA==} ultrahtml@1.7.0: - resolution: {integrity: sha1-jn1ZfjOKSB6oKFKpul6AIcVK7RA=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/ultrahtml/-/ultrahtml-1.7.0.tgz} + resolution: {integrity: sha512-2xRd0VHoAQE4M+vF/DvFFB7pUV0ZxTW1TLi7lHQWnF/Sb5TPeEUV/l+hxcNnGO00ZXGnR0voCMmYRKQf+rvJ2g==} ultramatter@0.0.4: - resolution: {integrity: sha1-z2O2REwhGh+tiuwGixrEPl5lfoE=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/ultramatter/-/ultramatter-0.0.4.tgz} + resolution: {integrity: sha512-1f/hO3mR+/Hgue4eInOF/Qm/wzDqwhYha4DxM0hre9YIUyso3fE2XtrAU6B4njLqTC8CM49EZaYgsVSa+dXHGw==} unconfig-core@7.5.0: - resolution: {integrity: sha1-aPPQAHASiEGPPTYgPYhvOMOYZnc=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/unconfig-core/-/unconfig-core-7.5.0.tgz} + resolution: {integrity: sha512-Su3FauozOGP44ZmKdHy2oE6LPjk51M/TRRjHv2HNCWiDvfvCoxC2lno6jevMA91MYAdCdwP05QnWdWpSbncX/w==} unconfig@7.5.0: - resolution: {integrity: sha1-Ei2O8n4nrt9VUUhQaRYcCFKrU00=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/unconfig/-/unconfig-7.5.0.tgz} + resolution: {integrity: sha512-oi8Qy2JV4D3UQ0PsopR28CzdQ3S/5A1zwsUwp/rosSbfhJ5z7b90bIyTwi/F7hCLD4SGcZVjDzd4XoUQcEanvA==} uncrypto@0.1.3: - resolution: {integrity: sha1-4SiNYJIm8tAtjWnuhh+iDYNI7ys=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/uncrypto/-/uncrypto-0.1.3.tgz} + resolution: {integrity: sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==} undici-types@7.18.2: - resolution: {integrity: sha1-KTV6iee3ykrvO/D9P9DNc4hCKek=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/undici-types/-/undici-types-7.18.2.tgz} + resolution: {integrity: sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==} undici@8.10.2: - resolution: {integrity: sha1-lgvLC0PCZ/hpEOp8pAitqEOkS8c=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/undici/-/undici-8.10.2.tgz} + resolution: {integrity: sha512-/y4/bH9YNU5hi9NIrpOuvGXFcxrj3CMrV+/AYpowAYTpHn8gX/XPFjNy766FPoYY0miQhdW977JFWKGNhBdwyQ==} engines: {node: '>=22.19.0'} unicode-segmenter@0.17.0: - resolution: {integrity: sha1-tH0FqURoQjYsPxvhG1Dw4SzGedE=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/unicode-segmenter/-/unicode-segmenter-0.17.0.tgz} + resolution: {integrity: sha512-rN+u/LmZx2SISURhq2vy+JeQmmf+9lFVsdVgvFJHa6wL42h3ojnYaS/UK4Fgsjku9C2P23WB/JK5sQWeBaZt+A==} unicode-trie@2.0.0: - resolution: {integrity: sha1-j9iEVpbi4UqLZ9ePqeDdLK1i/sg=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/unicode-trie/-/unicode-trie-2.0.0.tgz} + resolution: {integrity: sha512-x7bc76x0bm4prf1VLg79uhAzKw8DVboClSN5VxJuQ+LKDOVEW9CdH+VY7SP+vX7xCYQqzzgQpFqz15zeLvAtZQ==} unified@11.0.5: - resolution: {integrity: sha1-9mZ3YQpcCp7pDKsrjU1mA3Am2eE=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/unified/-/unified-11.0.5.tgz} + resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==} unifont@0.7.5: - resolution: {integrity: sha1-KPt5c2kyY9of1uC8KiRYW2mmARw=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/unifont/-/unifont-0.7.5.tgz} + resolution: {integrity: sha512-ULe/Cs+ZIsq+dcFofNkhqielCrUJnb5mr+Yc4EBM2VlL+6OZR6+cjtI2mT1bJvRBrVncqHAbLURxmPLcCXzWMg==} unist-util-find-after@5.0.0: - resolution: {integrity: sha1-P8zBsIa1bzTIt5jh/5C1xURo6JY=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/unist-util-find-after/-/unist-util-find-after-5.0.0.tgz} + resolution: {integrity: sha512-amQa0Ep2m6hE2g72AugUItjbuM8X8cGQnFoHk0pGfrFeT9GZhzN5SW8nRsiGKK7Aif4CrACPENkA6P/Lw6fHGQ==} unist-util-is@6.0.1: - resolution: {integrity: sha1-0KP4by3Q23rNfYwkeAgLXGf5xqk=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/unist-util-is/-/unist-util-is-6.0.1.tgz} + resolution: {integrity: sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==} unist-util-modify-children@4.0.0: - resolution: {integrity: sha1-mB1jCOiHsAXR9JGBHTy8wlSzFek=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/unist-util-modify-children/-/unist-util-modify-children-4.0.0.tgz} + resolution: {integrity: sha512-+tdN5fGNddvsQdIzUF3Xx82CU9sMM+fA0dLgR9vOmT0oPT2jH+P1nd5lSqfCfXAw+93NhcXNY2qqvTUtE4cQkw==} unist-util-position-from-estree@2.0.0: - resolution: {integrity: sha1-2U2k31llKdH6o95QYgLwyaI/IgA=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/unist-util-position-from-estree/-/unist-util-position-from-estree-2.0.0.tgz} + resolution: {integrity: sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ==} unist-util-position@5.0.0: - resolution: {integrity: sha1-Z48gq1yhIHqX1+qKOINzyc+Ja+Q=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/unist-util-position/-/unist-util-position-5.0.0.tgz} + resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==} unist-util-remove-position@5.0.0: - resolution: {integrity: sha1-/qaKJWWECclGBAi8a0mRuWW1IWM=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/unist-util-remove-position/-/unist-util-remove-position-5.0.0.tgz} + resolution: {integrity: sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q==} unist-util-remove@4.0.0: - resolution: {integrity: sha1-lLfWu9JOQtL4QelH7Qh75cgrIi4=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/unist-util-remove/-/unist-util-remove-4.0.0.tgz} + resolution: {integrity: sha512-b4gokeGId57UVRX/eVKej5gXqGlc9+trkORhFJpu9raqZkZhU0zm8Doi05+HaiBsMEIJowL+2WtQ5ItjsngPXg==} unist-util-select@5.1.0: - resolution: {integrity: sha1-ktsQ3w0D0uWY+deCv8bUuZsgV+s=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/unist-util-select/-/unist-util-select-5.1.0.tgz} + resolution: {integrity: sha512-4A5mfokSHG/rNQ4g7gSbdEs+H586xyd24sdJqF1IWamqrLHvYb+DH48fzxowyOhOfK7YSqX+XlCojAyuuyyT2A==} unist-util-stringify-position@4.0.0: - resolution: {integrity: sha1-RJxuIaiA4IVb9aq63rOnQDFKusI=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz} + resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==} unist-util-visit-children@3.0.0: - resolution: {integrity: sha1-S87Rmbcdfzw5dUPqbMOeen833H4=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/unist-util-visit-children/-/unist-util-visit-children-3.0.0.tgz} + resolution: {integrity: sha512-RgmdTfSBOg04sdPcpTSD1jzoNBjt9a80/ZCzp5cI9n1qPzLZWF9YdvWGN2zmTumP1HWhXKdUWexjy/Wy/lJ7tA==} unist-util-visit-parents@6.0.2: - resolution: {integrity: sha1-d333+5hlLOFrS3zZmdChpA76OgI=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/unist-util-visit-parents/-/unist-util-visit-parents-6.0.2.tgz} + resolution: {integrity: sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==} unist-util-visit@5.1.0: - resolution: {integrity: sha1-mioosKp2oV4NpwoIpYY6LwYOJGg=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/unist-util-visit/-/unist-util-visit-5.1.0.tgz} + resolution: {integrity: sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==} unocss@66.7.5: - resolution: {integrity: sha1-oGWL2gtbctDcgw5aG9VrueYkrPk=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/unocss/-/unocss-66.7.5.tgz} + resolution: {integrity: sha512-nAdmU8TwnQoiLnQjZ6Hm1GmHy9lTexKsAZNEJtZnxN9wyFRc1eLjQgmh9r7UEGxBQMQLD8OZOgmk5HpwObbh0Q==} peerDependencies: '@unocss/astro': 66.7.5 '@unocss/postcss': 66.7.5 @@ -4074,15 +4068,15 @@ packages: optional: true unplugin-utils@0.3.2: - resolution: {integrity: sha1-IvaFZAiICwstfdl0CE+vlAlGE+8=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/unplugin-utils/-/unplugin-utils-0.3.2.tgz} + resolution: {integrity: sha512-xVToRh2CTmLk2HnEG7ac4rl1MJTT3RFkpS8B++/SnB0kXvuaavD+n3m/vrzyWQOdJNSZQACnbz01pnppbwV5BA==} engines: {node: '>=20.19.0'} unplugin@2.3.11: - resolution: {integrity: sha1-QR4CDdK6kOL74ee9Y6WjmebuO1Q=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/unplugin/-/unplugin-2.3.11.tgz} + resolution: {integrity: sha512-5uKD0nqiYVzlmCRs01Fhs2BdkEgBS3SAVP6ndrBsuK42iC2+JHyxM05Rm9G8+5mkmRtzMZGY8Ct5+mliZxU/Ww==} engines: {node: '>=18.12.0'} unstorage@1.17.5: - resolution: {integrity: sha1-52yC/cHSwEyw4sCh3giqCLIlP1E=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/unstorage/-/unstorage-1.17.5.tgz} + resolution: {integrity: sha512-0i3iqvRfx29hkNntHyQvJTpf5W9dQ9ZadSoRU8+xVlhVtT7jAX57fazYO9EHvcRCfBCyi5YRya7XCDOsbTgkPg==} peerDependencies: '@azure/app-configuration': ^1.8.0 '@azure/cosmos': ^4.2.0 @@ -4144,21 +4138,21 @@ packages: optional: true uri-js@4.4.1: - resolution: {integrity: sha1-mxpSWVIlhZ5V9mnZKPiMbFfyp34=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/uri-js/-/uri-js-4.4.1.tgz} + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} url-extras@0.1.0: - resolution: {integrity: sha1-kFxfPR0tYoTZcxyHYlu/pwL9ra0=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/url-extras/-/url-extras-0.1.0.tgz} + resolution: {integrity: sha512-8tzwTeXFPuX/5PHuCDQE5Dd9Ts4rwoq2t9aIT+HS4iAVpmj5l4Ao7Q+BuuFjvWRqrLswBhQDk8O96ZicgCqQqw==} engines: {node: '>=20'} util-deprecate@1.0.2: - resolution: {integrity: sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/util-deprecate/-/util-deprecate-1.0.2.tgz} + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} uuid@14.0.1: - resolution: {integrity: sha1-ill1s+A4kCv9FpoQtSAvXsDPP68=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/uuid/-/uuid-14.0.1.tgz} + resolution: {integrity: sha512-6ZxzVpzDXDa3bJWaHilVayA+BH/1zmxCJoVgvmqJnid/gPoKHxUrS/aC/T6LGQtNHT+XHG9fXPJB4d+IrU30Ew==} hasBin: true valibot@1.4.2: - resolution: {integrity: sha1-2oV3gRh/Fwrq9EmNRj0lAoYVsNY=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/valibot/-/valibot-1.4.2.tgz} + resolution: {integrity: sha512-gjdCvJ6d3RyHAneqxMYMW9QMCwYMb3jpOO0IyHZV1bnRHFBHrX3VkIILt5XYR0WhwHiH7Mty8ovuPZ/O3gamrg==} peerDependencies: typescript: '>=5' peerDependenciesMeta: @@ -4166,27 +4160,27 @@ packages: optional: true vfile-location@5.0.3: - resolution: {integrity: sha1-y56s0g8rZCbRlFHg6vo9CoRiJcM=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/vfile-location/-/vfile-location-5.0.3.tgz} + resolution: {integrity: sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==} vfile-message@4.0.3: - resolution: {integrity: sha1-h7RN3de3DwZBwuPtCGS6c+LqjfQ=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/vfile-message/-/vfile-message-4.0.3.tgz} + resolution: {integrity: sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==} vfile@6.0.3: - resolution: {integrity: sha1-NlKrHEllMYUr9VprrFevmB68OKs=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/vfile/-/vfile-6.0.3.tgz} + resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} vite-plugin-static-copy@4.1.1: - resolution: {integrity: sha1-cJnjW6IC/C3vML0pRcvweQWW7os=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/vite-plugin-static-copy/-/vite-plugin-static-copy-4.1.1.tgz} + resolution: {integrity: sha512-GrlA8YklrAfSyxJ4M3fdQLOo9oNkp56IM9FYgX/WtEgeIFkPwhu4wzpufBCIuNKCa6Fn77FkRdYxkHqV0FwjAw==} engines: {node: ^22.0.0 || >=24.0.0} peerDependencies: vite: ^6.0.0 || ^7.0.0 || ^8.0.0 vite-plugin-virtual@0.5.0: - resolution: {integrity: sha1-hXNGIDAe15rMXgrWgPfWZ40CrOU=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/vite-plugin-virtual/-/vite-plugin-virtual-0.5.0.tgz} + resolution: {integrity: sha512-vKqZRK1k67VvMeUyvXNAboVwBHcdNuULR/+s7x+WVohM/i2kz2ZiCuHlp4JdQe2DjQ0Cnb9wZJH95BgpZ3lJvw==} peerDependencies: vite: ^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 vite@8.1.5: - resolution: {integrity: sha1-zP/OPuSHsYhiI7JOuye5FnSCfTA=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/vite/-/vite-8.1.5.tgz} + resolution: {integrity: sha512-7ULLwsCdYx/nRyrpiEwvqb5TFHrMVZyBt+rg/OAXT7rgj/z+DtTDyKFeLAdDkubDVDKD8jOsndmy7m55XcfUsw==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true peerDependencies: @@ -4229,7 +4223,7 @@ packages: optional: true vitefu@1.1.3: - resolution: {integrity: sha1-WbmIWxwgCFYxnX6c6w6ZoGVDAAk=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/vitefu/-/vitefu-1.1.3.tgz} + resolution: {integrity: sha512-ub4okH7Z5KLjb6hDyjqrGXqWtWvoYdU3IGm/NorpgHncKoLTCfRIbvlhBm7r0YstIaQRYlp4yEbFqDcKSzXSSg==} peerDependencies: vite: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 peerDependenciesMeta: @@ -4237,7 +4231,7 @@ packages: optional: true vitest@4.1.11: - resolution: {integrity: sha1-FlPBUhrpF/lg2bIYd3l8R9/YvyE=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/vitest/-/vitest-4.1.11.tgz} + resolution: {integrity: sha512-fhACrNXUidIbGSBr5FlbuBkO7VWC1ZyLl0DO4CU2DrQoAPxX84Ysxs+HeGQpii5lZWV1Q4gBZTTu49mF+A6Edw==} engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0} hasBin: true peerDependencies: @@ -4278,67 +4272,67 @@ packages: optional: true web-namespaces@2.0.1: - resolution: {integrity: sha1-EBD/fGUOzLJZLOvur5obJT/UBpI=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/web-namespaces/-/web-namespaces-2.0.1.tgz} + resolution: {integrity: sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==} web-streams-polyfill@3.3.3: - resolution: {integrity: sha1-IHO5Gi/bH7+9QB594KyfghTOy0s=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz} + resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==} engines: {node: '>= 8'} webpack-virtual-modules@0.6.2: - resolution: {integrity: sha1-BX+qkGXIrPSPJMtXrA53c5q5p+g=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/webpack-virtual-modules/-/webpack-virtual-modules-0.6.2.tgz} + resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==} which@2.0.2: - resolution: {integrity: sha1-fGqN0KY2oDJ+ELWckobu6T8/UbE=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/which/-/which-2.0.2.tgz} + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} engines: {node: '>= 8'} hasBin: true why-is-node-running@2.3.0: - resolution: {integrity: sha1-o/aalxB/SUs83Dvd3Yg6fWXOvwQ=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/why-is-node-running/-/why-is-node-running-2.3.0.tgz} + resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} engines: {node: '>=8'} hasBin: true word-wrap@1.2.5: - resolution: {integrity: sha1-0sRcbdT7zmIaZvE2y+Mor9BBCzQ=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/word-wrap/-/word-wrap-1.2.5.tgz} + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} engines: {node: '>=0.10.0'} xml-naming@0.3.0: - resolution: {integrity: sha1-RsHhi/4oWEeZgt0qzPNNFudJ7aI=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/xml-naming/-/xml-naming-0.3.0.tgz} + resolution: {integrity: sha512-ghig2TBE/H11aOVgmahA3MhimvkBr6JIYknH/Dhdk10nXwdbIqBJsbfMxpvFPG8bAw77gN29aQWvKpmVoPlvPQ==} engines: {node: '>=16.0.0'} xxhash-wasm@1.1.0: - resolution: {integrity: sha1-/+fwuYIgpK+sFx4/ubbR+HcfAV4=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/xxhash-wasm/-/xxhash-wasm-1.1.0.tgz} + resolution: {integrity: sha512-147y/6YNh+tlp6nd/2pWq38i9h6mz/EuQ6njIrmW8D1BS5nCqs0P6DG+m6zTGnNz5I+uhZ0SHxBs9BsPrwcKDA==} yaml@2.9.0: - resolution: {integrity: sha1-eCdK/ZNZih391hMN9qVm3vy/mqQ=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/yaml/-/yaml-2.9.0.tgz} + resolution: {integrity: sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==} engines: {node: '>= 14.6'} hasBin: true yargs-parser@22.0.0: - resolution: {integrity: sha1-h7gglAUbBWdxc0bs0A/RSASzV8g=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/yargs-parser/-/yargs-parser-22.0.0.tgz} + resolution: {integrity: sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==} engines: {node: ^20.19.0 || ^22.12.0 || >=23} yocto-queue@0.1.0: - resolution: {integrity: sha1-ApTrPe4FAo0x7hpfosVWpqrxChs=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/yocto-queue/-/yocto-queue-0.1.0.tgz} + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} yocto-queue@1.2.2: - resolution: {integrity: sha1-PgnJXT8aqJpYwRTJkiPt9jkVLAA=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/yocto-queue/-/yocto-queue-1.2.2.tgz} + resolution: {integrity: sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==} engines: {node: '>=12.20'} yoga-layout@3.2.1: - resolution: {integrity: sha1-0tG6BvDoHC62UMPlrYsLSt3h6EM=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/yoga-layout/-/yoga-layout-3.2.1.tgz} + resolution: {integrity: sha512-0LPOt3AxKqMdFBZA3HBAt/t/8vIKq7VaQYbuA8WxCgung+p9TVyKRYdpvCb80HcdTN2NkbIKbhNwKUfm3tQywQ==} zod@3.25.76: - resolution: {integrity: sha1-JoQcP2/SKmonYOfMtxkXl2hHHjQ=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/zod/-/zod-3.25.76.tgz} + resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} zod@4.4.3: - resolution: {integrity: sha1-toDxcohdGLvr8hqDTqJeVaG781Y=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/zod/-/zod-4.4.3.tgz} + resolution: {integrity: sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==} zod@4.5.4: - resolution: {integrity: sha1-4hXGJCDFKN15UeMftSxUOPH9GEo=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/zod/-/zod-4.5.4.tgz} + resolution: {integrity: sha512-sC95tT5iHHH9gtpj6A81kh+NEaRAUFN+qlUPDUbRfOMvNf5QCBqsb3WgvnpVtK5Y+4UfA6KqufotuTvMGiTlsA==} zwitch@2.0.4: - resolution: {integrity: sha1-yCfUsKy3b8PmhaTG7CkC1RBw6dc=, tarball: https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/zwitch/-/zwitch-2.0.4.tgz} + resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} snapshots: @@ -4365,7 +4359,7 @@ snapshots: dependencies: '@astro-community/astro-embed-utils': 0.2.0 - '@astro-community/astro-embed-integration@0.12.1(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.3)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))(typescript@6.0.3)': + '@astro-community/astro-embed-integration@0.12.1(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))(typescript@6.0.3)': dependencies: '@astro-community/astro-embed-bluesky': 0.2.3(typescript@6.0.3) '@astro-community/astro-embed-gist': 0.1.0 @@ -4375,8 +4369,8 @@ snapshots: '@astro-community/astro-embed-vimeo': 0.3.12 '@astro-community/astro-embed-youtube': 0.5.10 '@types/unist': 3.0.3 - astro: 7.3.2(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.3)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0) - astro-auto-import: 0.5.2(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.3)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0)) + astro: 7.3.2(@astrojs/markdown-remark@7.2.1)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0) + astro-auto-import: 0.5.2(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0)) unist-util-select: 5.1.0 transitivePeerDependencies: - typescript @@ -4423,12 +4417,7 @@ snapshots: '@astrojs/compiler-binding-linux-x64-musl@0.4.0': optional: true - '@astrojs/compiler-binding-wasm32-wasi@0.4.0(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.3)': - dependencies: - '@napi-rs/wasm-runtime': 1.2.3(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.3) - transitivePeerDependencies: - - '@emnapi/core' - - '@emnapi/runtime' + '@astrojs/compiler-binding-wasm32-wasi@0.4.0': optional: true '@astrojs/compiler-binding-win32-arm64-msvc@0.4.0': @@ -4437,7 +4426,7 @@ snapshots: '@astrojs/compiler-binding-win32-x64-msvc@0.4.0': optional: true - '@astrojs/compiler-binding@0.4.0(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.3)': + '@astrojs/compiler-binding@0.4.0': optionalDependencies: '@astrojs/compiler-binding-darwin-arm64': 0.4.0 '@astrojs/compiler-binding-darwin-x64': 0.4.0 @@ -4445,19 +4434,13 @@ snapshots: '@astrojs/compiler-binding-linux-arm64-musl': 0.4.0 '@astrojs/compiler-binding-linux-x64-gnu': 0.4.0 '@astrojs/compiler-binding-linux-x64-musl': 0.4.0 - '@astrojs/compiler-binding-wasm32-wasi': 0.4.0(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.3) + '@astrojs/compiler-binding-wasm32-wasi': 0.4.0 '@astrojs/compiler-binding-win32-arm64-msvc': 0.4.0 '@astrojs/compiler-binding-win32-x64-msvc': 0.4.0 - transitivePeerDependencies: - - '@emnapi/core' - - '@emnapi/runtime' - '@astrojs/compiler-rs@0.4.0(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.3)': + '@astrojs/compiler-rs@0.4.0': dependencies: - '@astrojs/compiler-binding': 0.4.0(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.3) - transitivePeerDependencies: - - '@emnapi/core' - - '@emnapi/runtime' + '@astrojs/compiler-binding': 0.4.0 '@astrojs/compiler@2.13.1': {} @@ -4520,13 +4503,13 @@ snapshots: github-slugger: 2.0.0 satteri: 0.10.5 - '@astrojs/mdx@7.0.3(@astrojs/markdown-satteri@0.3.4)(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.3)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))': + '@astrojs/mdx@7.0.3(@astrojs/markdown-satteri@0.3.4)(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))': dependencies: '@astrojs/internal-helpers': 0.10.1 '@astrojs/markdown-remark': 7.2.1 '@mdx-js/mdx': 3.1.1 acorn: 8.17.0 - astro: 7.3.2(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.3)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0) + astro: 7.3.2(@astrojs/markdown-remark@7.2.1)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0) es-module-lexer: 2.3.1 estree-util-visit: 2.0.0 hast-util-to-html: 9.0.5 @@ -4542,10 +4525,10 @@ snapshots: transitivePeerDependencies: - supports-color - '@astrojs/node@11.1.6(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.3)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))': + '@astrojs/node@11.1.6(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))': dependencies: '@astrojs/internal-helpers': 0.11.0 - astro: 7.3.2(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.3)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0) + astro: 7.3.2(@astrojs/markdown-remark@7.2.1)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0) send: 1.2.1 server-destroy: 1.0.1 transitivePeerDependencies: @@ -4567,17 +4550,17 @@ snapshots: stream-replace-string: 2.0.0 zod: 4.5.4 - '@astrojs/starlight@0.41.3(patch_hash=ad8925179f0e3050ae6c804196faa6d38a2be2b718acf138001215a18648d3b5)(@astrojs/markdown-remark@7.2.1)(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.3)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))(typescript@6.0.3)': + '@astrojs/starlight@0.41.3(patch_hash=ad8925179f0e3050ae6c804196faa6d38a2be2b718acf138001215a18648d3b5)(@astrojs/markdown-remark@7.2.1)(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))(typescript@6.0.3)': dependencies: '@astrojs/markdown-satteri': 0.3.4 - '@astrojs/mdx': 7.0.3(@astrojs/markdown-satteri@0.3.4)(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.3)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0)) + '@astrojs/mdx': 7.0.3(@astrojs/markdown-satteri@0.3.4)(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0)) '@astrojs/sitemap': 3.7.3 '@pagefind/default-ui': 1.5.2 '@types/hast': 3.0.5 '@types/js-yaml': 4.0.9 '@types/mdast': 4.0.4 - astro: 7.3.2(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.3)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0) - astro-expressive-code: 0.44.1(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.3)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0)) + astro: 7.3.2(@astrojs/markdown-remark@7.2.1)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0) + astro-expressive-code: 0.44.1(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0)) bcp-47: 2.1.1 hast-util-from-html: 2.0.3 hast-util-select: 6.0.4 @@ -4712,7 +4695,6 @@ snapshots: dependencies: '@emnapi/core': 1.11.1 '@emnapi/runtime': 1.11.1 - '@napi-rs/wasm-runtime': 1.2.3(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1) optional: true '@bruits/satteri-wasm32-wasi@0.9.5': @@ -4738,10 +4720,10 @@ snapshots: dependencies: fontkitten: 1.0.3 - '@catppuccin/starlight@2.1.0(@astrojs/starlight@0.41.3(patch_hash=ad8925179f0e3050ae6c804196faa6d38a2be2b718acf138001215a18648d3b5)(@astrojs/markdown-remark@7.2.1)(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.3)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))(typescript@6.0.3))(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.3)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))': + '@catppuccin/starlight@2.1.0(@astrojs/starlight@0.41.3(patch_hash=ad8925179f0e3050ae6c804196faa6d38a2be2b718acf138001215a18648d3b5)(@astrojs/markdown-remark@7.2.1)(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))(typescript@6.0.3))(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))': dependencies: - '@astrojs/starlight': 0.41.3(patch_hash=ad8925179f0e3050ae6c804196faa6d38a2be2b718acf138001215a18648d3b5)(@astrojs/markdown-remark@7.2.1)(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.3)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))(typescript@6.0.3) - astro: 7.3.2(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.3)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0) + '@astrojs/starlight': 0.41.3(patch_hash=ad8925179f0e3050ae6c804196faa6d38a2be2b718acf138001215a18648d3b5)(@astrojs/markdown-remark@7.2.1)(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))(typescript@6.0.3) + astro: 7.3.2(@astrojs/markdown-remark@7.2.1)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0) '@chevrotain/types@11.1.2': {} @@ -4803,11 +4785,6 @@ snapshots: tslib: 2.8.1 optional: true - '@emnapi/runtime@1.11.3': - dependencies: - tslib: 2.8.1 - optional: true - '@emnapi/wasi-threads@1.2.1': dependencies: tslib: 2.8.1 @@ -5093,8 +5070,6 @@ snapshots: optional: true '@img/sharp-wasm32@0.35.4': - dependencies: - '@emnapi/runtime': 1.11.3 optional: true '@img/sharp-webcontainers-wasm32@0.35.4': @@ -5155,11 +5130,11 @@ snapshots: transitivePeerDependencies: - supports-color - '@lunariajs/starlight@0.1.1(@astrojs/starlight@0.41.3(patch_hash=ad8925179f0e3050ae6c804196faa6d38a2be2b718acf138001215a18648d3b5)(@astrojs/markdown-remark@7.2.1)(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.3)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))(typescript@6.0.3))(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.3)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))': + '@lunariajs/starlight@0.1.1(@astrojs/starlight@0.41.3(patch_hash=ad8925179f0e3050ae6c804196faa6d38a2be2b718acf138001215a18648d3b5)(@astrojs/markdown-remark@7.2.1)(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))(typescript@6.0.3))(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))': dependencies: - '@astrojs/starlight': 0.41.3(patch_hash=ad8925179f0e3050ae6c804196faa6d38a2be2b718acf138001215a18648d3b5)(@astrojs/markdown-remark@7.2.1)(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.3)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))(typescript@6.0.3) + '@astrojs/starlight': 0.41.3(patch_hash=ad8925179f0e3050ae6c804196faa6d38a2be2b718acf138001215a18648d3b5)(@astrojs/markdown-remark@7.2.1)(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))(typescript@6.0.3) '@lunariajs/core': 0.1.1 - astro: 7.3.2(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.3)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0) + astro: 7.3.2(@astrojs/markdown-remark@7.2.1)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0) transitivePeerDependencies: - supports-color @@ -5204,27 +5179,6 @@ snapshots: '@tybys/wasm-util': 0.10.3 optional: true - '@napi-rs/wasm-runtime@1.2.3(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)': - dependencies: - '@emnapi/core': 1.10.0 - '@emnapi/runtime': 1.10.0 - '@tybys/wasm-util': 0.10.3 - optional: true - - '@napi-rs/wasm-runtime@1.2.3(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)': - dependencies: - '@emnapi/core': 1.11.1 - '@emnapi/runtime': 1.11.1 - '@tybys/wasm-util': 0.10.3 - optional: true - - '@napi-rs/wasm-runtime@1.2.3(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.3)': - dependencies: - '@emnapi/core': 1.11.1 - '@emnapi/runtime': 1.11.3 - '@tybys/wasm-util': 0.10.3 - optional: true - '@nodable/entities@3.0.0': {} '@nodelib/fs.scandir@2.1.5': @@ -5293,7 +5247,6 @@ snapshots: dependencies: '@emnapi/core': 1.10.0 '@emnapi/runtime': 1.10.0 - '@napi-rs/wasm-runtime': 1.2.3(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) optional: true '@oxc-parser/binding-win32-arm64-msvc@0.131.0': @@ -5388,7 +5341,7 @@ snapshots: dependencies: '@emnapi/core': 1.11.1 '@emnapi/runtime': 1.11.1 - '@napi-rs/wasm-runtime': 1.2.3(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1) + '@napi-rs/wasm-runtime': 1.1.6(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1) optional: true '@rolldown/binding-win32-arm64-msvc@1.1.5': @@ -6112,29 +6065,29 @@ snapshots: astring@1.9.0: {} - astro-auto-import@0.5.2(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.3)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0)): + astro-auto-import@0.5.2(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0)): dependencies: acorn: 8.17.0 - astro: 7.3.2(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.3)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0) + astro: 7.3.2(@astrojs/markdown-remark@7.2.1)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0) - astro-embed@0.13.1(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.3)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))(typescript@6.0.3): + astro-embed@0.13.1(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))(typescript@6.0.3): dependencies: '@astro-community/astro-embed-baseline-status': 0.2.2 '@astro-community/astro-embed-bluesky': 0.2.3(typescript@6.0.3) '@astro-community/astro-embed-gist': 0.1.0 - '@astro-community/astro-embed-integration': 0.12.1(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.3)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))(typescript@6.0.3) + '@astro-community/astro-embed-integration': 0.12.1(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))(typescript@6.0.3) '@astro-community/astro-embed-link-preview': 0.3.1 '@astro-community/astro-embed-mastodon': 0.1.1 '@astro-community/astro-embed-twitter': 0.5.11 '@astro-community/astro-embed-vimeo': 0.3.12 '@astro-community/astro-embed-youtube': 0.5.10 - astro: 7.3.2(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.3)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0) + astro: 7.3.2(@astrojs/markdown-remark@7.2.1)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0) transitivePeerDependencies: - typescript - astro-expressive-code@0.44.1(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.3)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0)): + astro-expressive-code@0.44.1(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0)): dependencies: - astro: 7.3.2(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.3)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0) + astro: 7.3.2(@astrojs/markdown-remark@7.2.1)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0) rehype-expressive-code: 0.44.1 url-extras: 0.1.0 @@ -6146,9 +6099,9 @@ snapshots: '@vtbag/turn-signal': 1.3.1 '@vtbag/utensil-drawer': 1.2.16 - astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.3)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0): + astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0): dependencies: - '@astrojs/compiler-rs': 0.4.0(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.3) + '@astrojs/compiler-rs': 0.4.0 '@astrojs/internal-helpers': 0.11.0 '@astrojs/markdown-satteri': 0.4.1 '@astrojs/telemetry': 3.3.3 @@ -6213,8 +6166,6 @@ snapshots: - '@azure/storage-blob' - '@capacitor/preferences' - '@deno/kv' - - '@emnapi/core' - - '@emnapi/runtime' - '@netlify/blobs' - '@planetscale/database' - '@types/node' @@ -8490,6 +8441,8 @@ snapshots: '@bruits/satteri-win32-arm64-msvc': 0.9.5 '@bruits/satteri-win32-x64-msvc': 0.9.5 + sax@1.6.0: {} + sax@1.6.1: {} semver@7.8.5: {} @@ -8608,7 +8561,7 @@ snapshots: '@types/node': 24.13.3 '@types/sax': 1.2.7 arg: 5.0.2 - sax: 1.6.1 + sax: 1.6.0 smol-toml@1.7.1: {} @@ -8632,15 +8585,15 @@ snapshots: stackback@0.0.2: {} - starlight-github-alerts@0.4.0(@astrojs/starlight@0.41.3(patch_hash=ad8925179f0e3050ae6c804196faa6d38a2be2b718acf138001215a18648d3b5)(@astrojs/markdown-remark@7.2.1)(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.3)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))(typescript@6.0.3)): + starlight-github-alerts@0.4.0(@astrojs/starlight@0.41.3(patch_hash=ad8925179f0e3050ae6c804196faa6d38a2be2b718acf138001215a18648d3b5)(@astrojs/markdown-remark@7.2.1)(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))(typescript@6.0.3)): dependencies: - '@astrojs/starlight': 0.41.3(patch_hash=ad8925179f0e3050ae6c804196faa6d38a2be2b718acf138001215a18648d3b5)(@astrojs/markdown-remark@7.2.1)(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.3)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))(typescript@6.0.3) + '@astrojs/starlight': 0.41.3(patch_hash=ad8925179f0e3050ae6c804196faa6d38a2be2b718acf138001215a18648d3b5)(@astrojs/markdown-remark@7.2.1)(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))(typescript@6.0.3) satteri: 0.9.5 unist-util-visit: 5.1.0 - starlight-image-zoom@0.15.0(@astrojs/starlight@0.41.3(patch_hash=ad8925179f0e3050ae6c804196faa6d38a2be2b718acf138001215a18648d3b5)(@astrojs/markdown-remark@7.2.1)(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.3)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))(typescript@6.0.3)): + starlight-image-zoom@0.15.0(@astrojs/starlight@0.41.3(patch_hash=ad8925179f0e3050ae6c804196faa6d38a2be2b718acf138001215a18648d3b5)(@astrojs/markdown-remark@7.2.1)(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))(typescript@6.0.3)): dependencies: - '@astrojs/starlight': 0.41.3(patch_hash=ad8925179f0e3050ae6c804196faa6d38a2be2b718acf138001215a18648d3b5)(@astrojs/markdown-remark@7.2.1)(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.3)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))(typescript@6.0.3) + '@astrojs/starlight': 0.41.3(patch_hash=ad8925179f0e3050ae6c804196faa6d38a2be2b718acf138001215a18648d3b5)(@astrojs/markdown-remark@7.2.1)(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))(typescript@6.0.3) mdast-util-mdx-jsx: 3.2.0 rehype-raw: 7.0.0 unist-util-visit: 5.1.0 @@ -8648,16 +8601,16 @@ snapshots: transitivePeerDependencies: - supports-color - starlight-kbd@0.4.0(@astrojs/starlight@0.41.3(patch_hash=ad8925179f0e3050ae6c804196faa6d38a2be2b718acf138001215a18648d3b5)(@astrojs/markdown-remark@7.2.1)(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.3)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))(typescript@6.0.3)): + starlight-kbd@0.4.0(@astrojs/starlight@0.41.3(patch_hash=ad8925179f0e3050ae6c804196faa6d38a2be2b718acf138001215a18648d3b5)(@astrojs/markdown-remark@7.2.1)(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))(typescript@6.0.3)): dependencies: - '@astrojs/starlight': 0.41.3(patch_hash=ad8925179f0e3050ae6c804196faa6d38a2be2b718acf138001215a18648d3b5)(@astrojs/markdown-remark@7.2.1)(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.3)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))(typescript@6.0.3) + '@astrojs/starlight': 0.41.3(patch_hash=ad8925179f0e3050ae6c804196faa6d38a2be2b718acf138001215a18648d3b5)(@astrojs/markdown-remark@7.2.1)(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))(typescript@6.0.3) - starlight-links-validator@0.25.2(@astrojs/starlight@0.41.3(patch_hash=ad8925179f0e3050ae6c804196faa6d38a2be2b718acf138001215a18648d3b5)(@astrojs/markdown-remark@7.2.1)(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.3)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))(typescript@6.0.3))(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.3)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0)): + starlight-links-validator@0.25.2(@astrojs/starlight@0.41.3(patch_hash=ad8925179f0e3050ae6c804196faa6d38a2be2b718acf138001215a18648d3b5)(@astrojs/markdown-remark@7.2.1)(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))(typescript@6.0.3))(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0)): dependencies: '@astrojs/markdown-satteri': 0.3.4 - '@astrojs/starlight': 0.41.3(patch_hash=ad8925179f0e3050ae6c804196faa6d38a2be2b718acf138001215a18648d3b5)(@astrojs/markdown-remark@7.2.1)(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.3)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))(typescript@6.0.3) + '@astrojs/starlight': 0.41.3(patch_hash=ad8925179f0e3050ae6c804196faa6d38a2be2b718acf138001215a18648d3b5)(@astrojs/markdown-remark@7.2.1)(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))(typescript@6.0.3) '@types/picomatch': 4.0.3 - astro: 7.3.2(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.3)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0) + astro: 7.3.2(@astrojs/markdown-remark@7.2.1)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0) github-slugger: 2.0.0 hast-util-from-html: 2.0.3 is-absolute-url: 5.0.0 @@ -8671,13 +8624,13 @@ snapshots: transitivePeerDependencies: - supports-color - starlight-llms-txt@0.11.0(@astrojs/markdown-satteri@0.3.4)(@astrojs/starlight@0.41.3(patch_hash=ad8925179f0e3050ae6c804196faa6d38a2be2b718acf138001215a18648d3b5)(@astrojs/markdown-remark@7.2.1)(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.3)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))(typescript@6.0.3))(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.3)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0)): + starlight-llms-txt@0.11.0(@astrojs/markdown-satteri@0.3.4)(@astrojs/starlight@0.41.3(patch_hash=ad8925179f0e3050ae6c804196faa6d38a2be2b718acf138001215a18648d3b5)(@astrojs/markdown-remark@7.2.1)(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))(typescript@6.0.3))(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0)): dependencies: - '@astrojs/mdx': 7.0.3(@astrojs/markdown-satteri@0.3.4)(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.3)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0)) - '@astrojs/starlight': 0.41.3(patch_hash=ad8925179f0e3050ae6c804196faa6d38a2be2b718acf138001215a18648d3b5)(@astrojs/markdown-remark@7.2.1)(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.3)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))(typescript@6.0.3) + '@astrojs/mdx': 7.0.3(@astrojs/markdown-satteri@0.3.4)(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0)) + '@astrojs/starlight': 0.41.3(patch_hash=ad8925179f0e3050ae6c804196faa6d38a2be2b718acf138001215a18648d3b5)(@astrojs/markdown-remark@7.2.1)(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))(typescript@6.0.3) '@types/hast': 3.0.5 '@types/micromatch': 4.0.10 - astro: 7.3.2(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.3)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0) + astro: 7.3.2(@astrojs/markdown-remark@7.2.1)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0) github-slugger: 2.0.0 hast-util-select: 6.0.4 micromatch: 4.0.8 @@ -8691,20 +8644,20 @@ snapshots: - '@astrojs/markdown-satteri' - supports-color - starlight-page-actions@0.7.0(patch_hash=584b28601fea4de666f3eb91e3425afd11f8da7e4d8aba649c15ec5be5b5d54c)(@astrojs/starlight@0.41.3(patch_hash=ad8925179f0e3050ae6c804196faa6d38a2be2b718acf138001215a18648d3b5)(@astrojs/markdown-remark@7.2.1)(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.3)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))(typescript@6.0.3))(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.3)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))(vite@8.1.5(@types/node@24.13.3)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0)): + starlight-page-actions@0.7.0(patch_hash=584b28601fea4de666f3eb91e3425afd11f8da7e4d8aba649c15ec5be5b5d54c)(@astrojs/starlight@0.41.3(patch_hash=ad8925179f0e3050ae6c804196faa6d38a2be2b718acf138001215a18648d3b5)(@astrojs/markdown-remark@7.2.1)(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))(typescript@6.0.3))(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))(vite@8.1.5(@types/node@24.13.3)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0)): dependencies: - '@astrojs/starlight': 0.41.3(patch_hash=ad8925179f0e3050ae6c804196faa6d38a2be2b718acf138001215a18648d3b5)(@astrojs/markdown-remark@7.2.1)(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.3)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))(typescript@6.0.3) - astro: 7.3.2(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.3)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0) + '@astrojs/starlight': 0.41.3(patch_hash=ad8925179f0e3050ae6c804196faa6d38a2be2b718acf138001215a18648d3b5)(@astrojs/markdown-remark@7.2.1)(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))(typescript@6.0.3) + astro: 7.3.2(@astrojs/markdown-remark@7.2.1)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0) tidymd: 0.1.0 vite-plugin-static-copy: 4.1.1(vite@8.1.5(@types/node@24.13.3)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0)) vite-plugin-virtual: 0.5.0(vite@8.1.5(@types/node@24.13.3)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0)) transitivePeerDependencies: - vite - starlight-plugin-icons@1.1.6(patch_hash=ecdc00afa0722d3cdc77871f9debee551f67d1c02d82fea11c5aa41bf0f48a54)(@astrojs/starlight@0.41.3(patch_hash=ad8925179f0e3050ae6c804196faa6d38a2be2b718acf138001215a18648d3b5)(@astrojs/markdown-remark@7.2.1)(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.3)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))(typescript@6.0.3))(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.3)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))(typescript@6.0.3)(unocss@66.7.5(@unocss/astro@66.7.5(vite@8.1.5(@types/node@24.13.3)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0)))(vite@8.1.5(@types/node@24.13.3)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0)))(zod@4.4.3): + starlight-plugin-icons@1.1.6(patch_hash=ecdc00afa0722d3cdc77871f9debee551f67d1c02d82fea11c5aa41bf0f48a54)(@astrojs/starlight@0.41.3(patch_hash=ad8925179f0e3050ae6c804196faa6d38a2be2b718acf138001215a18648d3b5)(@astrojs/markdown-remark@7.2.1)(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))(typescript@6.0.3))(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))(typescript@6.0.3)(unocss@66.7.5(@unocss/astro@66.7.5(vite@8.1.5(@types/node@24.13.3)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0)))(vite@8.1.5(@types/node@24.13.3)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0)))(zod@4.4.3): dependencies: - '@astrojs/starlight': 0.41.3(patch_hash=ad8925179f0e3050ae6c804196faa6d38a2be2b718acf138001215a18648d3b5)(@astrojs/markdown-remark@7.2.1)(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.3)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))(typescript@6.0.3) - astro: 7.3.2(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.3)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0) + '@astrojs/starlight': 0.41.3(patch_hash=ad8925179f0e3050ae6c804196faa6d38a2be2b718acf138001215a18648d3b5)(@astrojs/markdown-remark@7.2.1)(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))(typescript@6.0.3) + astro: 7.3.2(@astrojs/markdown-remark@7.2.1)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0) glob: 11.1.0 hast-util-select: 6.0.4 hast-util-to-string: 3.0.1 @@ -8715,9 +8668,9 @@ snapshots: unocss: 66.7.5(@unocss/astro@66.7.5(vite@8.1.5(@types/node@24.13.3)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0)))(vite@8.1.5(@types/node@24.13.3)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0)) zod: 4.4.3 - starlight-sidebar-topics@0.8.0(@astrojs/starlight@0.41.3(patch_hash=ad8925179f0e3050ae6c804196faa6d38a2be2b718acf138001215a18648d3b5)(@astrojs/markdown-remark@7.2.1)(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.3)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))(typescript@6.0.3)): + starlight-sidebar-topics@0.8.0(@astrojs/starlight@0.41.3(patch_hash=ad8925179f0e3050ae6c804196faa6d38a2be2b718acf138001215a18648d3b5)(@astrojs/markdown-remark@7.2.1)(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))(typescript@6.0.3)): dependencies: - '@astrojs/starlight': 0.41.3(patch_hash=ad8925179f0e3050ae6c804196faa6d38a2be2b718acf138001215a18648d3b5)(@astrojs/markdown-remark@7.2.1)(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.3)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))(typescript@6.0.3) + '@astrojs/starlight': 0.41.3(patch_hash=ad8925179f0e3050ae6c804196faa6d38a2be2b718acf138001215a18648d3b5)(@astrojs/markdown-remark@7.2.1)(astro@7.3.2(@astrojs/markdown-remark@7.2.1)(@types/node@24.13.3)(jiti@2.7.0)(tsx@4.23.1)(yaml@2.9.0))(typescript@6.0.3) picomatch: 4.0.4 statuses@2.0.2: {}