diff --git a/.env b/.env index 14e36c5ec..267bdf204 100644 --- a/.env +++ b/.env @@ -1,2 +1,2 @@ -VITE_VERSION_LATEST="v11.0.0" -VITE_VERSION_NEXT="v12.0.0" \ No newline at end of file +VITE_VERSION_LATEST="v12.0.0" +VITE_VERSION_NEXT="v13.0.0" diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index eb7a7b01d..2b8c29b1a 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -50,6 +50,38 @@ jobs: echo "SAFE_BRANCH=$SAFE_BRANCH" >> "$GITHUB_ENV" echo "VITE_DEPLOYMENT_URL=https://${SAFE_BRANCH}.rescript-lang.pages.dev" >> "$GITHUB_ENV" fi + - name: Set Algolia env + shell: bash + env: + ALGOLIA_APP_ID: ${{ vars.ALGOLIA_APP_ID }} + ALGOLIA_INDEX_BASENAME: ${{ vars.ALGOLIA_INDEX_BASENAME }} + ALGOLIA_SEARCH_API_KEY_DEV: ${{ vars.ALGOLIA_SEARCH_API_KEY_DEV }} + ALGOLIA_SEARCH_API_KEY_PROD: ${{ vars.ALGOLIA_SEARCH_API_KEY_PROD }} + ALGOLIA_ADMIN_API_KEY_DEV: ${{ secrets.ALGOLIA_ADMIN_API_KEY_DEV }} + ALGOLIA_ADMIN_API_KEY_PROD: ${{ secrets.ALGOLIA_ADMIN_API_KEY_PROD }} + run: | + if [[ "${{ github.event_name }}" == "push" && "${{ github.ref_name }}" == "master" ]]; then + INDEX_PREFIX="prod" + SEARCH_KEY="$ALGOLIA_SEARCH_API_KEY_PROD" + ADMIN_KEY="$ALGOLIA_ADMIN_API_KEY_PROD" + elif [[ "${{ github.event_name }}" == "workflow_dispatch" && "${{ inputs.environment }}" == "production" ]]; then + INDEX_PREFIX="prod" + SEARCH_KEY="$ALGOLIA_SEARCH_API_KEY_PROD" + ADMIN_KEY="$ALGOLIA_ADMIN_API_KEY_PROD" + else + INDEX_PREFIX="dev" + SEARCH_KEY="$ALGOLIA_SEARCH_API_KEY_DEV" + ADMIN_KEY="$ALGOLIA_ADMIN_API_KEY_DEV" + fi + + INDEX_NAME="${INDEX_PREFIX}_${ALGOLIA_INDEX_BASENAME}" + + echo "VITE_ALGOLIA_APP_ID=$ALGOLIA_APP_ID" >> "$GITHUB_ENV" + echo "VITE_ALGOLIA_INDEX_NAME=$INDEX_NAME" >> "$GITHUB_ENV" + echo "VITE_ALGOLIA_SEARCH_API_KEY=$SEARCH_KEY" >> "$GITHUB_ENV" + echo "ALGOLIA_APP_ID=$ALGOLIA_APP_ID" >> "$GITHUB_ENV" + echo "ALGOLIA_INDEX_NAME=$INDEX_NAME" >> "$GITHUB_ENV" + echo "ALGOLIA_ADMIN_API_KEY=$ADMIN_KEY" >> "$GITHUB_ENV" - name: Build run: yarn build env: diff --git a/.gitignore b/.gitignore index 4e1e38164..b01b1b5aa 100644 --- a/.gitignore +++ b/.gitignore @@ -28,6 +28,7 @@ scripts/gendocs.mjs scripts/generate_*.mjs scripts/gendocs.jsx scripts/generate_*.jsx +scripts/LogAlgoliaEnvStatus.jsx # Generated via generate-llms script public/llms/manual/**/llm*.txt diff --git a/__tests__/AlgoliaConfig_.test.res b/__tests__/AlgoliaConfig_.test.res new file mode 100644 index 000000000..8a826bb22 --- /dev/null +++ b/__tests__/AlgoliaConfig_.test.res @@ -0,0 +1,37 @@ +open Vitest + +test("publicConfigFrom returns config when all public vars are present", async () => { + let result = AlgoliaConfig.publicConfigFrom( + ~appId=Some("app_123"), + ~indexName=Some("dev_rescript_lang"), + ~searchApiKey=Some("search_123"), + ) + + let expected: AlgoliaConfig.publicConfig = { + appId: "app_123", + indexName: "dev_rescript_lang", + searchApiKey: "search_123", + } + + expect(result)->toEqual(Some(expected)) +}) + +test("publicConfigFrom reports missing public vars in declaration order", async () => { + let result = AlgoliaConfig.missingPublicVars( + ~appId=None, + ~indexName=Some("dev_rescript_lang"), + ~searchApiKey=None, + ) + + expect(result)->toEqual(["VITE_ALGOLIA_APP_ID", "VITE_ALGOLIA_SEARCH_API_KEY"]) +}) + +test("publisherConfigFrom reports missing publisher vars in declaration order", async () => { + let result = AlgoliaConfig.missingPublisherVars( + ~appId=Some("app_123"), + ~indexName=None, + ~adminApiKey=None, + ) + + expect(result)->toEqual(["ALGOLIA_INDEX_NAME", "ALGOLIA_ADMIN_API_KEY"]) +}) diff --git a/__tests__/AlgoliaEnvStatus_.test.res b/__tests__/AlgoliaEnvStatus_.test.res new file mode 100644 index 000000000..7c5784ae6 --- /dev/null +++ b/__tests__/AlgoliaEnvStatus_.test.res @@ -0,0 +1,19 @@ +open Vitest + +test("reports missing public vars in declaration order", async () => { + let env = Dict.fromArray([ + ("VITE_ALGOLIA_APP_ID", ""), + ("VITE_ALGOLIA_INDEX_NAME", "dev_rescript_lang"), + ]) + + expect(AlgoliaEnvStatus.getMissingPublicAlgoliaVars(~env))->toEqual([ + "VITE_ALGOLIA_APP_ID", + "VITE_ALGOLIA_SEARCH_API_KEY", + ]) +}) + +test("formats the disabled search warning", async () => { + expect(AlgoliaEnvStatus.formatDisabledMessage(["VITE_ALGOLIA_APP_ID"]))->toBe( + "Algolia search disabled: missing VITE_ALGOLIA_APP_ID", + ) +}) diff --git a/__tests__/DocsOverview_.test.res b/__tests__/DocsOverview_.test.res index b8e6eb05f..916af7861 100644 --- a/__tests__/DocsOverview_.test.res +++ b/__tests__/DocsOverview_.test.res @@ -49,6 +49,39 @@ test("desktop docs overview shows ecosystem links", async () => { await element(wrapper)->toMatchScreenshot("desktop-docs-overview-ecosystem") }) +test("docs overview uses unversioned docs links", async () => { + await viewport(1440, 900) + + let _screen = await render( + +
+ +
+
, + ) + + let overviewLink = switch document->WebAPI.Document.querySelector( + "a[href='/docs/manual/introduction']", + ) { + | Value(link) => link + | Null => failwith("expected docs overview to link to the unversioned manual introduction") + } + await element(overviewLink)->toBeVisible + + let genTypeLink = switch document->WebAPI.Document.querySelector( + "a[href='/docs/manual/typescript-integration']", + ) { + | Value(link) => link + | Null => failwith("expected docs overview to link to the unversioned GenType docs page") + } + await element(genTypeLink)->toBeVisible + + switch document->WebAPI.Document.querySelector("a[href*='/docs/manual/v']") { + | Value(_) => failwith("expected docs overview to avoid versioned manual links") + | Null => () + } +}) + test("mobile docs overview", async () => { await viewport(600, 1200) diff --git a/__tests__/SearchIndex_.test.res b/__tests__/SearchIndex_.test.res new file mode 100644 index 000000000..0504f980f --- /dev/null +++ b/__tests__/SearchIndex_.test.res @@ -0,0 +1,555 @@ +open Vitest + +// --------------------------------------------------------------------------- +// maxContentLength +// --------------------------------------------------------------------------- + +test("maxContentLength is 500", async () => { + expect(SearchIndex.maxContentLength)->toBe(500) +}) + +// --------------------------------------------------------------------------- +// truncate +// --------------------------------------------------------------------------- + +test("truncate returns string as-is when shorter than maxLen", async () => { + expect(SearchIndex.truncate("hello", ~maxLen=10))->toBe("hello") +}) + +test("truncate returns string as-is when exactly maxLen", async () => { + expect(SearchIndex.truncate("hello", ~maxLen=5))->toBe("hello") +}) + +test("truncate truncates and adds ellipsis when longer than maxLen", async () => { + expect(SearchIndex.truncate("hello world", ~maxLen=5))->toBe("hello...") +}) + +test("truncate handles empty string", async () => { + expect(SearchIndex.truncate("", ~maxLen=5))->toBe("") +}) + +test("truncate handles maxLen=0 with ellipsis", async () => { + expect(SearchIndex.truncate("abc", ~maxLen=0))->toBe("...") +}) + +test("truncate truncates to single character with ellipsis", async () => { + expect(SearchIndex.truncate("abcdef", ~maxLen=1))->toBe("a...") +}) + +// --------------------------------------------------------------------------- +// slugify +// --------------------------------------------------------------------------- + +test("slugify lowercases text", async () => { + expect(SearchIndex.slugify("Hello World"))->toBe("hello-world") +}) + +test("slugify replaces spaces with hyphens", async () => { + expect(SearchIndex.slugify("foo bar baz"))->toBe("foo-bar-baz") +}) + +test("slugify removes non-alphanumeric characters", async () => { + expect(SearchIndex.slugify("Hello, World!"))->toBe("hello-world") +}) + +test("slugify collapses multiple spaces into a single hyphen", async () => { + expect(SearchIndex.slugify("foo bar"))->toBe("foo-bar") +}) + +test("slugify handles empty string", async () => { + expect(SearchIndex.slugify(""))->toBe("") +}) + +test("slugify preserves numbers", async () => { + expect(SearchIndex.slugify("Section 42"))->toBe("section-42") +}) + +test("slugify removes special characters like parentheses and dots", async () => { + expect(SearchIndex.slugify("Array.map()"))->toBe("arraymap") +}) + +test("slugify handles already-slugified text", async () => { + expect(SearchIndex.slugify("already-slugified"))->toBe("already-slugified") +}) + +// --------------------------------------------------------------------------- +// stripMdxTags +// --------------------------------------------------------------------------- + +test("stripMdxTags removes CodeTab blocks", async () => { + let input = "before\n\nsome code\n\nafter" + expect(SearchIndex.stripMdxTags(input))->toBe("before\nafter") +}) + +test("stripMdxTags removes HTML tags", async () => { + expect(SearchIndex.stripMdxTags("
hello
"))->toBe("hello") +}) + +test("stripMdxTags removes fenced code blocks", async () => { + let input = "before\n```rescript\nlet x = 1\n```\nafter" + expect(SearchIndex.stripMdxTags(input))->toBe("before\nafter") +}) + +test("stripMdxTags strips inline code backticks", async () => { + expect(SearchIndex.stripMdxTags("use `Array.map` here"))->toBe("use Array.map here") +}) + +test("stripMdxTags strips bold markers", async () => { + expect(SearchIndex.stripMdxTags("this is **bold** text"))->toBe("this is bold text") +}) + +test("stripMdxTags strips italic markers", async () => { + expect(SearchIndex.stripMdxTags("this is *italic* text"))->toBe("this is italic text") +}) + +test("stripMdxTags strips markdown links while keeping link text", async () => { + expect(SearchIndex.stripMdxTags("click [here](https://example.com) now"))->toBe("click here now") +}) + +test("stripMdxTags removes heading markers", async () => { + expect(SearchIndex.stripMdxTags("## My Heading"))->toBe("My Heading") +}) + +test("stripMdxTags removes h1 through h6 markers", async () => { + let input = "# H1\n## H2\n### H3\n#### H4\n##### H5\n###### H6" + expect(SearchIndex.stripMdxTags(input))->toBe("H1\nH2\nH3\nH4\nH5\nH6") +}) + +test("stripMdxTags collapses multiple newlines to a single newline", async () => { + expect(SearchIndex.stripMdxTags("a\n\n\nb"))->toBe("a\nb") +}) + +test("stripMdxTags handles empty string", async () => { + expect(SearchIndex.stripMdxTags(""))->toBe("") +}) + +test("stripMdxTags handles combined markdown formatting", async () => { + let input = "Use **`Array.map`** to [transform](http://x.com) items." + let result = SearchIndex.stripMdxTags(input) + expect(result)->toBe("Use Array.map to transform items.") +}) + +// --------------------------------------------------------------------------- +// cleanDocstring +// --------------------------------------------------------------------------- + +test("cleanDocstring returns simple text as-is", async () => { + expect(SearchIndex.cleanDocstring("Simple description"))->toBe("Simple description") +}) + +test("cleanDocstring takes content before first ## heading", async () => { + let input = "Intro text\n## Details\nMore info" + expect(SearchIndex.cleanDocstring(input))->toBe("Intro text") +}) + +test("cleanDocstring takes content before first code block", async () => { + let input = "Intro text\n```rescript\nlet x = 1\n```" + expect(SearchIndex.cleanDocstring(input))->toBe("Intro text") +}) + +test("cleanDocstring strips inline code backticks", async () => { + expect(SearchIndex.cleanDocstring("Returns `true` or `false`"))->toBe("Returns true or false") +}) + +test("cleanDocstring strips bold formatting", async () => { + expect(SearchIndex.cleanDocstring("This is **important**"))->toBe("This is important") +}) + +test("cleanDocstring strips italic formatting", async () => { + expect(SearchIndex.cleanDocstring("This is *emphasized*"))->toBe("This is emphasized") +}) + +test("cleanDocstring strips markdown links", async () => { + expect(SearchIndex.cleanDocstring("See [docs](http://example.com)"))->toBe("See docs") +}) + +test("cleanDocstring collapses multiple newlines to spaces", async () => { + let input = "line one\n\nline two\n\nline three" + expect(SearchIndex.cleanDocstring(input))->toBe("line one line two line three") +}) + +test("cleanDocstring replaces single newlines with spaces", async () => { + let input = "line one\nline two" + expect(SearchIndex.cleanDocstring(input))->toBe("line one line two") +}) + +test("cleanDocstring handles empty string", async () => { + expect(SearchIndex.cleanDocstring(""))->toBe("") +}) + +test("cleanDocstring lets headings take priority over code blocks", async () => { + let input = "Intro\n## Section\nText\n```\ncode\n```" + expect(SearchIndex.cleanDocstring(input))->toBe("Intro") +}) + +// --------------------------------------------------------------------------- +// extractIntro +// --------------------------------------------------------------------------- + +test("extractIntro extracts text before first ## heading", async () => { + let input = "Some intro text.\n## First Section\nDetails here." + let result = SearchIndex.extractIntro(input) + expect(result)->toBe("Some intro text.") +}) + +test("extractIntro removes an H1 heading at the start", async () => { + let input = "# Page Title\nIntro paragraph.\n## Section" + let result = SearchIndex.extractIntro(input) + expect(result)->toBe("Intro paragraph.") +}) + +test("extractIntro returns stripped content when there are no headings", async () => { + let input = "Just some plain text content." + expect(SearchIndex.extractIntro(input))->toBe("Just some plain text content.") +}) + +test("extractIntro handles empty string", async () => { + expect(SearchIndex.extractIntro(""))->toBe("") +}) + +test("extractIntro strips MDX tags from the intro", async () => { + let input = "Use **bold** and `code`.\n## Section" + expect(SearchIndex.extractIntro(input))->toBe("Use bold and code.") +}) + +test("extractIntro removes H1 but preserves the rest of the content", async () => { + let input = "# Title\nFirst paragraph.\nSecond paragraph." + expect(SearchIndex.extractIntro(input))->toBe("First paragraph.\nSecond paragraph.") +}) + +// --------------------------------------------------------------------------- +// extractHeadings +// --------------------------------------------------------------------------- + +test("extractHeadings extracts h2 headings", async () => { + let input = "Intro\n## First\nContent one.\n## Second\nContent two." + let headings = SearchIndex.extractHeadings(input) + expect(Array.length(headings))->toBe(2) + expect(headings[0]->Option.map(h => h.level))->toEqual(Some(2)) + expect(headings[0]->Option.map(h => h.text))->toEqual(Some("First")) + expect(headings[1]->Option.map(h => h.text))->toEqual(Some("Second")) +}) + +test("extractHeadings extracts h3 headings", async () => { + let input = "## Parent\n### Child\nSub content." + let headings = SearchIndex.extractHeadings(input) + expect(headings[0]->Option.map(h => h.level))->toEqual(Some(2)) + expect(headings[1]->Option.map(h => h.level))->toEqual(Some(3)) + expect(headings[1]->Option.map(h => h.text))->toEqual(Some("Child")) +}) + +test("extractHeadings does not extract h1 headings", async () => { + let input = "# Title\nSome text\n## Real Heading\nContent." + let headings = SearchIndex.extractHeadings(input) + expect(Array.length(headings))->toBe(1) + expect(headings[0]->Option.map(h => h.text))->toEqual(Some("Real Heading")) +}) + +test("extractHeadings returns an empty array when there are no headings", async () => { + let input = "Just plain text with no headings." + let headings = SearchIndex.extractHeadings(input) + expect(Array.length(headings))->toBe(0) +}) + +test("extractHeadings includes section content between headings", async () => { + let input = "## Heading\nThis is the content of the section." + let headings = SearchIndex.extractHeadings(input) + expect(headings[0]->Option.map(h => h.content))->toEqual( + Some("This is the content of the section."), + ) +}) + +test("extractHeadings strips MDX tags from section content", async () => { + let input = "## Heading\nUse **bold** and `code` here." + let headings = SearchIndex.extractHeadings(input) + expect(headings[0]->Option.map(h => h.content))->toEqual(Some("Use bold and code here.")) +}) + +test("extractHeadings truncates section content to maxContentLength", async () => { + let longContent = String.repeat("a", 600) + let input = "## Heading\n" ++ longContent + let headings = SearchIndex.extractHeadings(input) + let contentLen = headings[0]->Option.map(h => String.length(h.content))->Option.getOr(0) + // 500 chars + "..." = 503 + expect(contentLen)->toBe(503) +}) + +test("extractHeadings handles multiple heading levels", async () => { + let input = "## H2\nA\n### H3\nB\n#### H4\nC\n##### H5\nD\n###### H6\nE" + let headings = SearchIndex.extractHeadings(input) + expect(Array.length(headings))->toBe(5) + expect(headings[0]->Option.map(h => h.level))->toEqual(Some(2)) + expect(headings[1]->Option.map(h => h.level))->toEqual(Some(3)) + expect(headings[2]->Option.map(h => h.level))->toEqual(Some(4)) + expect(headings[3]->Option.map(h => h.level))->toEqual(Some(5)) + expect(headings[4]->Option.map(h => h.level))->toEqual(Some(6)) +}) + +// --------------------------------------------------------------------------- +// makeHierarchy +// --------------------------------------------------------------------------- + +test("makeHierarchy creates a hierarchy with only required fields", async () => { + let h = SearchIndex.makeHierarchy(~lvl0="Docs", ~lvl1="Overview", ()) + expect(h.lvl0)->toBe("Docs") + expect(h.lvl1)->toBe("Overview") + expect(h.lvl2)->toEqual(None) + expect(h.lvl3)->toEqual(None) + expect(h.lvl4)->toEqual(None) + expect(h.lvl5)->toEqual(None) + expect(h.lvl6)->toEqual(None) +}) + +test("makeHierarchy creates a hierarchy with all optional fields", async () => { + let h = SearchIndex.makeHierarchy( + ~lvl0="Docs", + ~lvl1="Guide", + ~lvl2="Chapter", + ~lvl3="Section", + ~lvl4="Sub A", + ~lvl5="Sub B", + ~lvl6="Sub C", + (), + ) + expect(h.lvl0)->toBe("Docs") + expect(h.lvl1)->toBe("Guide") + expect(h.lvl2)->toEqual(Some("Chapter")) + expect(h.lvl3)->toEqual(Some("Section")) + expect(h.lvl4)->toEqual(Some("Sub A")) + expect(h.lvl5)->toEqual(Some("Sub B")) + expect(h.lvl6)->toEqual(Some("Sub C")) +}) + +test("makeHierarchy creates a hierarchy with partial optional fields", async () => { + let h = SearchIndex.makeHierarchy(~lvl0="API", ~lvl1="Array", ~lvl2="map", ()) + expect(h.lvl2)->toEqual(Some("map")) + expect(h.lvl3)->toEqual(None) +}) + +// --------------------------------------------------------------------------- +// optionToJson +// --------------------------------------------------------------------------- + +test("optionToJson converts Some to a JSON string", async () => { + expect(SearchIndex.optionToJson(Some("hello")))->toEqual(JSON.String("hello")) +}) + +test("optionToJson converts None to JSON null", async () => { + expect(SearchIndex.optionToJson(None))->toEqual(JSON.Null) +}) + +test("optionToJson converts Some empty string to a JSON string", async () => { + expect(SearchIndex.optionToJson(Some("")))->toEqual(JSON.String("")) +}) + +// --------------------------------------------------------------------------- +// hierarchyToJson +// --------------------------------------------------------------------------- + +test("hierarchyToJson serializes a hierarchy with only required fields", async () => { + let h = SearchIndex.makeHierarchy(~lvl0="Docs", ~lvl1="Page", ()) + let json = SearchIndex.hierarchyToJson(h) + let expected = { + let d = Dict.make() + d->Dict.set("lvl0", JSON.String("Docs")) + d->Dict.set("lvl1", JSON.String("Page")) + d->Dict.set("lvl2", JSON.Null) + d->Dict.set("lvl3", JSON.Null) + d->Dict.set("lvl4", JSON.Null) + d->Dict.set("lvl5", JSON.Null) + d->Dict.set("lvl6", JSON.Null) + JSON.Object(d) + } + expect(json)->toEqual(expected) +}) + +test("hierarchyToJson serializes optional fields as JSON strings", async () => { + let h = SearchIndex.makeHierarchy(~lvl0="API", ~lvl1="Array", ~lvl2="map", ()) + let json = SearchIndex.hierarchyToJson(h) + let expected = { + let d = Dict.make() + d->Dict.set("lvl0", JSON.String("API")) + d->Dict.set("lvl1", JSON.String("Array")) + d->Dict.set("lvl2", JSON.String("map")) + d->Dict.set("lvl3", JSON.Null) + d->Dict.set("lvl4", JSON.Null) + d->Dict.set("lvl5", JSON.Null) + d->Dict.set("lvl6", JSON.Null) + JSON.Object(d) + } + expect(json)->toEqual(expected) +}) + +// --------------------------------------------------------------------------- +// weightToJson +// --------------------------------------------------------------------------- + +test("weightToJson serializes weight to a JSON object with number values", async () => { + let w: SearchIndex.weight = {pageRank: 10, level: 80, position: 3} + let json = SearchIndex.weightToJson(w) + let expected = { + let d = Dict.make() + d->Dict.set("pageRank", JSON.Number(10.0)) + d->Dict.set("level", JSON.Number(80.0)) + d->Dict.set("position", JSON.Number(3.0)) + JSON.Object(d) + } + expect(json)->toEqual(expected) +}) + +test("weightToJson serializes zero values correctly", async () => { + let w: SearchIndex.weight = {pageRank: 0, level: 0, position: 0} + let json = SearchIndex.weightToJson(w) + let expected = { + let d = Dict.make() + d->Dict.set("pageRank", JSON.Number(0.0)) + d->Dict.set("level", JSON.Number(0.0)) + d->Dict.set("position", JSON.Number(0.0)) + JSON.Object(d) + } + expect(json)->toEqual(expected) +}) + +// --------------------------------------------------------------------------- +// withBaseUrl +// --------------------------------------------------------------------------- + +test("withBaseUrl prepends the site URL to relative record URLs", async () => { + let record: SearchIndex.record = { + objectID: "docs/manual/introduction", + url: "/docs/manual/introduction#what-is-rescript", + url_without_anchor: "/docs/manual/introduction", + anchor: Some("what-is-rescript"), + content: Some("Intro"), + type_: "lvl2", + hierarchy: SearchIndex.makeHierarchy(~lvl0="Docs", ~lvl1="Introduction", ()), + weight: {pageRank: 5, level: 80, position: 1}, + } + + let result = SearchIndex.withBaseUrl(record, ~siteUrl="https://rescript-lang.org") + + expect(result.url)->toBe("https://rescript-lang.org/docs/manual/introduction#what-is-rescript") + expect(result.url_without_anchor)->toBe("https://rescript-lang.org/docs/manual/introduction") +}) + +test("withBaseUrl avoids double slashes when the site URL ends with /", async () => { + let record: SearchIndex.record = { + objectID: "docs/manual/api", + url: "/docs/manual/api", + url_without_anchor: "/docs/manual/api", + anchor: None, + content: None, + type_: "lvl1", + hierarchy: SearchIndex.makeHierarchy(~lvl0="Docs", ~lvl1="API", ()), + weight: {pageRank: 5, level: 100, position: 0}, + } + + let result = SearchIndex.withBaseUrl(record, ~siteUrl="https://rescript-lang.org/") + + expect(result.url)->toBe("https://rescript-lang.org/docs/manual/api") + expect(result.url_without_anchor)->toBe("https://rescript-lang.org/docs/manual/api") +}) + +// --------------------------------------------------------------------------- +// toJson +// --------------------------------------------------------------------------- + +test("toJson serializes a full record with all fields", async () => { + let r: SearchIndex.record = { + objectID: "docs/overview", + url: "/docs/overview#intro", + url_without_anchor: "/docs/overview", + anchor: Some("intro"), + content: Some("Introduction text"), + type_: "lvl2", + hierarchy: SearchIndex.makeHierarchy(~lvl0="Docs", ~lvl1="Overview", ~lvl2="Intro", ()), + weight: {pageRank: 5, level: 80, position: 1}, + } + let json = SearchIndex.toJson(r) + + let expected = { + let d = Dict.make() + d->Dict.set("objectID", JSON.String("docs/overview")) + d->Dict.set("url", JSON.String("/docs/overview#intro")) + d->Dict.set("url_without_anchor", JSON.String("/docs/overview")) + d->Dict.set("anchor", JSON.String("intro")) + d->Dict.set("content", JSON.String("Introduction text")) + d->Dict.set("type", JSON.String("lvl2")) + d->Dict.set( + "hierarchy", + { + let hd = Dict.make() + hd->Dict.set("lvl0", JSON.String("Docs")) + hd->Dict.set("lvl1", JSON.String("Overview")) + hd->Dict.set("lvl2", JSON.String("Intro")) + hd->Dict.set("lvl3", JSON.Null) + hd->Dict.set("lvl4", JSON.Null) + hd->Dict.set("lvl5", JSON.Null) + hd->Dict.set("lvl6", JSON.Null) + JSON.Object(hd) + }, + ) + d->Dict.set( + "weight", + { + let wd = Dict.make() + wd->Dict.set("pageRank", JSON.Number(5.0)) + wd->Dict.set("level", JSON.Number(80.0)) + wd->Dict.set("position", JSON.Number(1.0)) + JSON.Object(wd) + }, + ) + JSON.Object(d) + } + expect(json)->toEqual(expected) +}) + +test("toJson serializes a record with None optional fields as null", async () => { + let r: SearchIndex.record = { + objectID: "page", + url: "/page", + url_without_anchor: "/page", + anchor: None, + content: None, + type_: "lvl1", + hierarchy: SearchIndex.makeHierarchy(~lvl0="Cat", ~lvl1="Page", ()), + weight: {pageRank: 1, level: 100, position: 0}, + } + let json = SearchIndex.toJson(r) + + let expected = { + let d = Dict.make() + d->Dict.set("objectID", JSON.String("page")) + d->Dict.set("url", JSON.String("/page")) + d->Dict.set("url_without_anchor", JSON.String("/page")) + d->Dict.set("anchor", JSON.Null) + d->Dict.set("content", JSON.Null) + d->Dict.set("type", JSON.String("lvl1")) + d->Dict.set( + "hierarchy", + { + let hd = Dict.make() + hd->Dict.set("lvl0", JSON.String("Cat")) + hd->Dict.set("lvl1", JSON.String("Page")) + hd->Dict.set("lvl2", JSON.Null) + hd->Dict.set("lvl3", JSON.Null) + hd->Dict.set("lvl4", JSON.Null) + hd->Dict.set("lvl5", JSON.Null) + hd->Dict.set("lvl6", JSON.Null) + JSON.Object(hd) + }, + ) + d->Dict.set( + "weight", + { + let wd = Dict.make() + wd->Dict.set("pageRank", JSON.Number(1.0)) + wd->Dict.set("level", JSON.Number(100.0)) + wd->Dict.set("position", JSON.Number(0.0)) + JSON.Object(wd) + }, + ) + JSON.Object(d) + } + expect(json)->toEqual(expected) +}) diff --git a/__tests__/Search_.test.res b/__tests__/Search_.test.res new file mode 100644 index 000000000..fdb906e88 --- /dev/null +++ b/__tests__/Search_.test.res @@ -0,0 +1,268 @@ +open Vitest + +// --------------------------------------------------------------------------- +// Helper +// --------------------------------------------------------------------------- + +let makeHit = (~type_: DocSearch.contentType, ~url: string): DocSearch.docSearchHit => { + objectID: "test", + content: Nullable.null, + url, + url_without_anchor: url, + type_, + anchor: Nullable.null, + hierarchy: { + lvl0: Nullable.make("Test"), + lvl1: Nullable.make("Test Page"), + lvl2: Nullable.null, + lvl3: Nullable.null, + lvl4: Nullable.null, + lvl5: Nullable.null, + lvl6: Nullable.null, + }, + deprecated: None, + _highlightResult: Obj.magic(Dict.make()), + _snippetResult: Obj.magic(Dict.make()), +} + +// --------------------------------------------------------------------------- +// markdownToHtml +// --------------------------------------------------------------------------- + +test("markdownToHtml strips leading backslash + whitespace", async () => { + expect(Search.markdownToHtml("\\ hello"))->toBe("hello") +}) + +test("markdownToHtml replaces interior backslash + whitespace with a space", async () => { + expect(Search.markdownToHtml("foo\\ bar"))->toBe("foo bar") +}) + +test("markdownToHtml handles multiple interior backslashes", async () => { + expect(Search.markdownToHtml("a\\ b\\ c"))->toBe("a b c") +}) + +test("markdownToHtml strips leading and replaces interior backslashes together", async () => { + expect(Search.markdownToHtml("\\ a\\ b"))->toBe("a b") +}) + +test( + "markdownToHtml removes an MDN reference with a markdown link and trailing period", + async () => { + expect( + Search.markdownToHtml("Some text. See [Array](https://developer.mozilla.org/array) on MDN."), + )->toBe("Some text.") + }, +) + +test( + "markdownToHtml removes an MDN reference with a markdown link without trailing period", + async () => { + expect( + Search.markdownToHtml("Some text. See [Array](https://developer.mozilla.org/array) on MDN"), + )->toBe("Some text.") + }, +) + +test("markdownToHtml removes an MDN plain URL reference with trailing period", async () => { + expect(Search.markdownToHtml("Read more. See https://developer.mozilla.org/foo on MDN."))->toBe( + "Read more.", + ) +}) + +test("markdownToHtml removes an MDN plain URL reference without trailing period", async () => { + expect(Search.markdownToHtml("Read more. See https://developer.mozilla.org/foo on MDN"))->toBe( + "Read more.", + ) +}) + +test("markdownToHtml converts a markdown link to plain text", async () => { + expect(Search.markdownToHtml("[click here](https://example.com)"))->toBe("click here") +}) + +test("markdownToHtml converts multiple markdown links", async () => { + expect(Search.markdownToHtml("[foo](http://a.com) and [bar](http://b.com)"))->toBe("foo and bar") +}) + +test("markdownToHtml passes through a link with empty text", async () => { + expect(Search.markdownToHtml("[](https://example.com)"))->toBe("[](https://example.com)") +}) + +test("markdownToHtml converts backtick code to tags", async () => { + expect(Search.markdownToHtml("`Array.map`"))->toBe("Array.map") +}) + +test("markdownToHtml converts multiple backtick spans", async () => { + expect(Search.markdownToHtml("Use `map` and `filter`"))->toBe( + "Use map and filter", + ) +}) + +test("markdownToHtml converts **text** to tags", async () => { + expect(Search.markdownToHtml("**important**"))->toBe("important") +}) + +test("markdownToHtml converts bold within a sentence", async () => { + expect(Search.markdownToHtml("This is **very** important"))->toBe( + "This is very important", + ) +}) + +test("markdownToHtml converts *text* to tags", async () => { + expect(Search.markdownToHtml("*emphasis*"))->toBe("emphasis") +}) + +test("markdownToHtml converts italic within a sentence", async () => { + expect(Search.markdownToHtml("This is *quite* nice"))->toBe("This is quite nice") +}) + +test("markdownToHtml converts double newline to
", async () => { + expect(Search.markdownToHtml("first\n\nsecond"))->toBe("first
second") +}) + +test("markdownToHtml converts triple+ newlines to a single
", async () => { + expect(Search.markdownToHtml("first\n\n\nsecond"))->toBe("first
second") +}) + +test("markdownToHtml converts single newline to a space", async () => { + expect(Search.markdownToHtml("first\nsecond"))->toBe("first second") +}) + +test("markdownToHtml trims leading whitespace", async () => { + expect(Search.markdownToHtml(" hello"))->toBe("hello") +}) + +test("markdownToHtml trims trailing whitespace", async () => { + expect(Search.markdownToHtml("hello "))->toBe("hello") +}) + +test("markdownToHtml trims both sides", async () => { + expect(Search.markdownToHtml(" hello "))->toBe("hello") +}) + +test("markdownToHtml handles empty string", async () => { + expect(Search.markdownToHtml(""))->toBe("") +}) + +test("markdownToHtml passes plain text through unchanged", async () => { + expect(Search.markdownToHtml("just plain text"))->toBe("just plain text") +}) + +test("markdownToHtml applies multiple transformations together", async () => { + expect( + Search.markdownToHtml("Use `map` on **arrays**.\n\nSee [docs](http://x.com) for *details*."), + )->toBe("Use map on arrays.
See docs for details.") +}) + +test( + "markdownToHtml still converts bold inside code because regexes run sequentially", + async () => { + expect(Search.markdownToHtml("`**notbold**`"))->toBe("notbold") + }, +) + +// --------------------------------------------------------------------------- +// isChildHit +// --------------------------------------------------------------------------- + +test("isChildHit treats Lvl2 as a child hit", async () => { + expect(Search.isChildHit(makeHit(~type_=Lvl2, ~url="https://example.com/page")))->toBe(true) +}) + +test("isChildHit treats Lvl3 as a child hit", async () => { + expect(Search.isChildHit(makeHit(~type_=Lvl3, ~url="https://example.com/page")))->toBe(true) +}) + +test("isChildHit treats Lvl4 as a child hit", async () => { + expect(Search.isChildHit(makeHit(~type_=Lvl4, ~url="https://example.com/page")))->toBe(true) +}) + +test("isChildHit treats Lvl5 as a child hit", async () => { + expect(Search.isChildHit(makeHit(~type_=Lvl5, ~url="https://example.com/page")))->toBe(true) +}) + +test("isChildHit treats Lvl6 as a child hit", async () => { + expect(Search.isChildHit(makeHit(~type_=Lvl6, ~url="https://example.com/page")))->toBe(true) +}) + +test("isChildHit treats Content as a child hit", async () => { + expect(Search.isChildHit(makeHit(~type_=Content, ~url="https://example.com/page")))->toBe(true) +}) + +test("isChildHit treats Lvl2 as a child hit even without a hash in the URL", async () => { + expect(Search.isChildHit(makeHit(~type_=Lvl2, ~url="https://example.com/no-hash")))->toBe(true) +}) + +test("isChildHit treats Content as a child hit even with a hash in the URL", async () => { + expect(Search.isChildHit(makeHit(~type_=Content, ~url="https://example.com/page#section")))->toBe( + true, + ) +}) + +test("isChildHit treats Lvl0 without a hash as not a child hit", async () => { + expect(Search.isChildHit(makeHit(~type_=Lvl0, ~url="https://example.com/page")))->toBe(false) +}) + +test("isChildHit treats Lvl0 with a hash as a child hit", async () => { + expect(Search.isChildHit(makeHit(~type_=Lvl0, ~url="https://example.com/page#section")))->toBe( + true, + ) +}) + +test("isChildHit treats Lvl0 with a trailing # as a child hit", async () => { + expect(Search.isChildHit(makeHit(~type_=Lvl0, ~url="https://example.com/page#")))->toBe(true) +}) + +test("isChildHit treats Lvl1 without a hash as not a child hit", async () => { + expect(Search.isChildHit(makeHit(~type_=Lvl1, ~url="https://example.com/page")))->toBe(false) +}) + +test("isChildHit treats Lvl1 with a hash as a child hit", async () => { + expect(Search.isChildHit(makeHit(~type_=Lvl1, ~url="https://example.com/page#heading")))->toBe( + true, + ) +}) + +test("isChildHit treats Lvl1 with a deeply nested hash anchor as a child hit", async () => { + expect( + Search.isChildHit( + makeHit(~type_=Lvl1, ~url="https://example.com/docs/manual/api#some-section"), + ), + )->toBe(true) +}) + +test("isChildHit treats Lvl1 with an empty URL as not a child hit", async () => { + expect(Search.isChildHit(makeHit(~type_=Lvl1, ~url="")))->toBe(false) +}) + +test("toRelativeSiteUrl strips the site origin from an absolute URL", async () => { + let result = Search.toRelativeSiteUrl( + "https://rescript-lang.org/docs/manual/introduction#what-is-rescript", + ~siteUrl="https://rescript-lang.org/", + ) + + expect(result)->toBe("/docs/manual/introduction#what-is-rescript") +}) + +test("normalizeHitUrls rewrites absolute site URLs to relative paths", async () => { + let hit = makeHit( + ~type_=Lvl1, + ~url="https://rescript-lang.org/docs/manual/typescript-integration#gentype", + ) + let result = Search.normalizeHitUrls([hit], ~siteUrl="https://rescript-lang.org/") + + expect(result[0]->Option.map(hit => hit.url))->toEqual( + Some("/docs/manual/typescript-integration#gentype"), + ) + expect(result[0]->Option.map(hit => hit.url_without_anchor))->toEqual( + Some("/docs/manual/typescript-integration#gentype"), + ) +}) + +test("renders disabled search copy when Algolia config is missing", async () => { + await viewport(1440, 500) + + let screen = await render() + + await element(await screen->getByText("Search unavailable"))->toBeVisible + await element(await screen->getByLabelText("Search unavailable for this build"))->toBeVisible +}) diff --git a/__tests__/Url_.test.res b/__tests__/Url_.test.res new file mode 100644 index 000000000..fd29c2185 --- /dev/null +++ b/__tests__/Url_.test.res @@ -0,0 +1,29 @@ +open Vitest + +test("Url.parse splits an unversioned route into path segments", async () => { + let result = Url.parse("/docs/manual/introduction") + expect(result.base)->toEqual(["docs", "manual", "introduction"]) + expect(result.pagepath)->toEqual([]) + expect(result.fullpath)->toEqual(["docs", "manual", "introduction"]) +}) + +test("Url.parse treats version-like segments as ordinary path content", async () => { + let result = Url.parse("/docs/manual/v12.0.0/introduction") + expect(result.base)->toEqual(["docs", "manual", "v12.0.0", "introduction"]) + expect(result.pagepath)->toEqual([]) + expect(result.fullpath)->toEqual(["docs", "manual", "v12.0.0", "introduction"]) +}) + +test("Url.parse treats latest as ordinary path content", async () => { + let result = Url.parse("/docs/manual/latest/arrays") + expect(result.base)->toEqual(["docs", "manual", "latest", "arrays"]) + expect(result.pagepath)->toEqual([]) + expect(result.fullpath)->toEqual(["docs", "manual", "latest", "arrays"]) +}) + +test("Url.parse parses routes outside docs without special handling", async () => { + let result = Url.parse("/community/overview") + expect(result.base)->toEqual(["community", "overview"]) + expect(result.pagepath)->toEqual([]) + expect(result.fullpath)->toEqual(["community", "overview"]) +}) diff --git a/__tests__/__screenshots__/SearchIndex_.test.jsx/slugify-collapses-multiple-spaces-into-single-hyphen-1.png b/__tests__/__screenshots__/SearchIndex_.test.jsx/slugify-collapses-multiple-spaces-into-single-hyphen-1.png new file mode 100644 index 000000000..a35891721 Binary files /dev/null and b/__tests__/__screenshots__/SearchIndex_.test.jsx/slugify-collapses-multiple-spaces-into-single-hyphen-1.png differ diff --git a/__tests__/__screenshots__/Search_.test.jsx/markdownToHtml-combined-transformations-bold-inside-code-stays-as-is--code-matched-first--1.png b/__tests__/__screenshots__/Search_.test.jsx/markdownToHtml-combined-transformations-bold-inside-code-stays-as-is--code-matched-first--1.png new file mode 100644 index 000000000..a35891721 Binary files /dev/null and b/__tests__/__screenshots__/Search_.test.jsx/markdownToHtml-combined-transformations-bold-inside-code-stays-as-is--code-matched-first--1.png differ diff --git a/__tests__/__screenshots__/Search_.test.jsx/markdownToHtml-markdown-link-stripping-handles-link-with-empty-text-1.png b/__tests__/__screenshots__/Search_.test.jsx/markdownToHtml-markdown-link-stripping-handles-link-with-empty-text-1.png new file mode 100644 index 000000000..a35891721 Binary files /dev/null and b/__tests__/__screenshots__/Search_.test.jsx/markdownToHtml-markdown-link-stripping-handles-link-with-empty-text-1.png differ diff --git a/__tests__/__screenshots__/Url_.test.jsx/Url-parse-version-detection-parses-next-keyword-1.png b/__tests__/__screenshots__/Url_.test.jsx/Url-parse-version-detection-parses-next-keyword-1.png new file mode 100644 index 000000000..a35891721 Binary files /dev/null and b/__tests__/__screenshots__/Url_.test.jsx/Url-parse-version-detection-parses-next-keyword-1.png differ diff --git a/__tests__/__screenshots__/Url_.test.jsx/Url-parse-version-detection-parses-version-without-v-prefix--PR--1231--1.png b/__tests__/__screenshots__/Url_.test.jsx/Url-parse-version-detection-parses-version-without-v-prefix--PR--1231--1.png new file mode 100644 index 000000000..a35891721 Binary files /dev/null and b/__tests__/__screenshots__/Url_.test.jsx/Url-parse-version-detection-parses-version-without-v-prefix--PR--1231--1.png differ diff --git a/app/routes/ApiRoute.res b/app/routes/ApiRoute.res index 1f8ef40cb..894ea7e8f 100644 --- a/app/routes/ApiRoute.res +++ b/app/routes/ApiRoute.res @@ -98,23 +98,26 @@ let groupItems = apiDocs => { } let makeBreadcrumbs = (~prefix: Url.breadcrumb, route: Path.t): list => { - let url = Url.parse((route :> string)) - - let (_, rest) = // Strip the "api" part of the url before creating the rest of the breadcrumbs - Array.slice(url.pagepath, ~start=1)->Array.reduce((prefix.href, []), (acc, path) => { - let (baseHref, ret) = acc - - let href = baseHref ++ ("/" ++ path) - - Array.push( - ret, - { - Url.name: Url.prettyString(path), - href, - }, - )->ignore - (href, ret) - }) + let (_, rest) = + // Strip the "/docs/manual/api" base path before creating the rest of the breadcrumbs + (route :> string) + ->String.split("/") + ->Array.filter(s => s !== "") + ->Array.slice(~start=3) + ->Array.reduce((prefix.href, []), (acc, path) => { + let (baseHref, ret) = acc + + let href = baseHref ++ ("/" ++ path) + + Array.push( + ret, + { + Url.name: Url.prettyString(path), + href, + }, + )->ignore + (href, ret) + }) Array.concat([prefix], rest)->List.fromArray } diff --git a/app/routes/DocsOverview.res b/app/routes/DocsOverview.res index e5df82e57..dbffbd735 100644 --- a/app/routes/DocsOverview.res +++ b/app/routes/DocsOverview.res @@ -16,17 +16,12 @@ module Card = { @react.component let default = (~showVersionSelect=true) => { - let {pathname} = ReactRouter.useLocation() - let url = (pathname :> string)->Url.parse - - let version = url->Url.getVersionString - - let languageManual = Constants.languageManual(version) + let languageManual = Constants.languageManual let ecosystem = [ ("Package Index", "/packages"), ("rescript-react", "/docs/react/introduction"), - ("GenType", `/docs/manual/${version}/typescript-integration`), + ("GenType", "/docs/manual/typescript-integration"), ("Reanalyze", "https://github.com/rescript-lang/reanalyze"), ] diff --git a/package.json b/package.json index 4822e005a..100235bf6 100644 --- a/package.json +++ b/package.json @@ -10,9 +10,11 @@ "build:generate-llms": "node _scripts/generate_llms.mjs", "build:res": "rescript build --warn-error +3+8+11+12+26+27+31+32+33+34+35+39+44+45+110", "build:sync-bundles": "node scripts/sync-playground-bundles.mjs", - "build:update-index": "yarn build:generate-llms && node _scripts/generate_feed.mjs > public/blog/feed.xml", + "build:search-index": "node --env-file-if-exists=.env --env-file-if-exists=.env.local _scripts/generate_search_index.mjs", + "build:update-index": "yarn build:generate-llms && node _scripts/generate_feed.mjs > public/blog/feed.xml && yarn build:search-index", "build:vite": "react-router build", - "build": "yarn build:res && yarn build:scripts && yarn build:update-index && yarn build:vite", + "check:algolia-public-env": "node _scripts/LogAlgoliaEnvStatus.mjs", + "build": "yarn build:res && yarn build:scripts && yarn check:algolia-public-env && yarn build:update-index && yarn build:vite", "ci:format": "oxfmt --check", "ci:test": "yarn vitest --run --browser.headless", "clean:res": "rescript clean", @@ -22,7 +24,7 @@ "dev:wrangler": "yarn wrangler pages dev build/client", "dev": "yarn prepare && yarn dev:res & yarn dev:vite & yarn dev:wrangler", "format": "oxfmt && rescript format", - "prepare": "yarn build:res && yarn build:scripts && yarn build:update-index", + "prepare": "yarn build:res && yarn build:scripts && yarn check:algolia-public-env && yarn build:update-index", "preview": "yarn build && static-server build/client", "reanalyze": "rescript-tools reanalyze -all-cmt .", "test": "node scripts/test.mjs", @@ -54,6 +56,7 @@ "@rescript/react": "^0.14.2", "@rescript/webapi": "0.1.0-experimental-29db5f4", "@tsnobip/rescript-lezer": "^0.8.0", + "algoliasearch": "^5.50.1", "docson": "^2.1.0", "fuse.js": "^6.6.2", "highlight.js": "^11.11.1", diff --git a/scripts/LogAlgoliaEnvStatus.res b/scripts/LogAlgoliaEnvStatus.res new file mode 100644 index 000000000..887c08825 --- /dev/null +++ b/scripts/LogAlgoliaEnvStatus.res @@ -0,0 +1,19 @@ +@val @scope(("import", "meta")) external url: string = "url" + +let run = () => { + let missing = AlgoliaEnvStatus.getMissingPublicAlgoliaVars(~env=Node.Process.env) + if Array.length(missing) > 0 { + Console.warn(AlgoliaEnvStatus.formatDisabledMessage(missing)) + } +} + +let isMainModule = () => + switch Node.Process.argv[1] { + | Some(entrypoint) => + Node.URL.fileURLToPath(url) === Node.Path.resolve(Node.Process.cwd(), entrypoint) + | None => false + } + +let _ = if isMainModule() { + run() +} diff --git a/scripts/generate_search_index.res b/scripts/generate_search_index.res new file mode 100644 index 000000000..57051a34c --- /dev/null +++ b/scripts/generate_search_index.res @@ -0,0 +1,232 @@ +// Build script: reads all site content, builds Algolia search records, and uploads them. +// Runs as a standalone Node script via: node --env-file-if-exists=.env --env-file-if-exists=.env.local _scripts/generate_search_index.mjs +// +// Required env vars: +// ALGOLIA_APP_ID -- Algolia application ID +// ALGOLIA_ADMIN_API_KEY -- API key with addObject/deleteObject/editSettings ACLs +// ALGOLIA_INDEX_NAME -- e.g. "rescript-lang-dev" or "rescript-lang" +// +// If any are missing, the script logs a warning and exits 0 (graceful skip). + +let getEnv = (key: string): option => + Node.Process.env + ->Dict.get(key) + ->Option.flatMap(v => + switch v { + | "" => None + | s => Some(s) + } + ) + +let compareVersions = (a: string, b: string): float => { + let parse = (v: string) => + v + ->String.replaceRegExp(RegExp.fromString("^v", ~flags=""), "") + ->String.split(".") + ->Array.map(s => Int.fromString(s)->Option.getOr(0)) + let partsA = parse(a) + let partsB = parse(b) + switch (partsA[0], partsB[0]) { + | (Some(a0), Some(b0)) if a0 !== b0 => Int.toFloat(a0 - b0) + | _ => + switch (partsA[1], partsB[1]) { + | (Some(a1), Some(b1)) if a1 !== b1 => Int.toFloat(a1 - b1) + | _ => + switch (partsA[2], partsB[2]) { + | (Some(a2), Some(b2)) => Int.toFloat(a2 - b2) + | _ => 0.0 + } + } + } +} + +let resolveApiDir = (): option => { + let majorVersion = + getEnv("VITE_VERSION_LATEST") + ->Option.map(v => v->String.replaceRegExp(RegExp.fromString("^v", ~flags=""), "")) + ->Option.flatMap(v => v->String.split(".")->Array.get(0)) + switch majorVersion { + | None => { + Console.log("[search-index] VITE_VERSION_LATEST not set, cannot resolve API version.") + None + } + | Some(major) => { + let prefix = "v" ++ major ++ "." + let entries = Node.Fs.readdirSync("data/api") + let matching = + entries + ->Array.filter(entry => String.startsWith(entry, prefix)) + ->Array.toSorted(compareVersions) + switch matching->Array.at(-1) { + | Some(dir) => { + Console.log(`[search-index] Resolved API version: ${dir}`) + Some("data/api/" ++ dir) + } + | None => { + Console.log(`[search-index] No API version found matching v${major}.*`) + None + } + } + } + } +} + +let resolveSiteUrl = (): string => + getEnv("VITE_DEPLOYMENT_URL")->Option.getOr("https://rescript-lang.org") + +let main = async () => { + let appId = getEnv("ALGOLIA_APP_ID") + let adminApiKey = getEnv("ALGOLIA_ADMIN_API_KEY") + let indexName = getEnv("ALGOLIA_INDEX_NAME") + let publisherConfig = AlgoliaConfig.publisherConfigFrom(~appId, ~indexName, ~adminApiKey) + + switch publisherConfig { + | Some({appId, indexName, adminApiKey}) => { + Console.log("[search-index] Building search index records...") + + let apiDir = resolveApiDir()->Option.getOr("markdown-pages/docs/api") + let siteUrl = resolveSiteUrl() + + // 1. Build records from all content sources + let manualRecords = SearchIndex.buildMarkdownRecords( + ~category="Manual", + ~basePath="/docs/manual", + ~dirPath="markdown-pages/docs/manual", + ~pageRank=100, + ) + Console.log( + `[search-index] Manual docs: ${Int.toString(Array.length(manualRecords))} records`, + ) + + let reactRecords = SearchIndex.buildMarkdownRecords( + ~category="React", + ~basePath="/docs/react", + ~dirPath="markdown-pages/docs/react", + ~pageRank=90, + ) + Console.log( + `[search-index] React docs: ${Int.toString(Array.length(reactRecords))} records`, + ) + + let communityRecords = SearchIndex.buildMarkdownRecords( + ~category="Community", + ~basePath="/community", + ~dirPath="markdown-pages/community", + ~pageRank=50, + ) + Console.log( + `[search-index] Community: ${Int.toString(Array.length(communityRecords))} records`, + ) + + let blogRecords = SearchIndex.buildBlogRecords(~dirPath="markdown-pages/blog", ~pageRank=40) + Console.log(`[search-index] Blog: ${Int.toString(Array.length(blogRecords))} records`) + + let syntaxRecords = SearchIndex.buildSyntaxLookupRecords( + ~dirPath="markdown-pages/syntax-lookup", + ~pageRank=70, + ) + Console.log( + `[search-index] Syntax lookup: ${Int.toString(Array.length(syntaxRecords))} records`, + ) + + let stdlibApiRecords = SearchIndex.buildApiRecords( + ~basePath="/docs/manual/api", + ~dirPath=apiDir, + ~pageRank=80, + ~category="API / StdLib", + ~files=["stdlib.json"], + ) + Console.log( + `[search-index] API / StdLib: ${Int.toString(Array.length(stdlibApiRecords))} records`, + ) + + let beltApiRecords = SearchIndex.buildApiRecords( + ~basePath="/docs/manual/api", + ~dirPath=apiDir, + ~pageRank=75, + ~category="API / Belt", + ~files=["belt.json"], + ) + Console.log( + `[search-index] API / Belt: ${Int.toString(Array.length(beltApiRecords))} records`, + ) + + let domApiRecords = SearchIndex.buildApiRecords( + ~basePath="/docs/manual/api", + ~dirPath=apiDir, + ~pageRank=70, + ~category="API / DOM", + ~files=["dom.json"], + ) + Console.log( + `[search-index] API / DOM: ${Int.toString(Array.length(domApiRecords))} records`, + ) + + // 2. Concatenate all records + let allRecords = + [ + manualRecords, + reactRecords, + communityRecords, + blogRecords, + syntaxRecords, + stdlibApiRecords, + beltApiRecords, + domApiRecords, + ]->Array.flat + + let totalCount = Array.length(allRecords) + Console.log(`[search-index] Total: ${Int.toString(totalCount)} records`) + + // 3. Convert to JSON for Algolia + let jsonRecords = + allRecords + ->Array.map(record => SearchIndex.withBaseUrl(record, ~siteUrl)) + ->Array.map(SearchIndex.toJson) + + // 4. Initialize Algolia client and upload + let client = Algolia.make(appId, adminApiKey) + + Console.log(`[search-index] Uploading to index "${indexName}"...`) + let _ = await client->Algolia.replaceAllObjects({ + indexName, + objects: jsonRecords, + batchSize: 1000, + }) + Console.log("[search-index] Records uploaded successfully.") + + // 5. Configure index settings + Console.log("[search-index] Updating index settings...") + let _ = await client->Algolia.setSettings({ + indexName, + indexSettings: { + searchableAttributes: [ + "hierarchy.lvl0", + "hierarchy.lvl1", + "hierarchy.lvl2", + "hierarchy.lvl3", + "hierarchy.lvl4", + "hierarchy.lvl5", + "hierarchy.lvl6", + "content", + ], + ranking: ["typo", "words", "attribute", "exact", "custom", "proximity", "filters"], + exactOnSingleWordQuery: "word", + attributesForFaceting: ["type"], + customRanking: ["desc(weight.pageRank)", "desc(weight.level)", "asc(weight.position)"], + attributesToSnippet: [], + attributeForDistinct: "hierarchy.lvl0", + }, + }) + Console.log("[search-index] Index settings updated.") + + Console.log("[search-index] Done.") + } + | None => + AlgoliaConfig.missingPublisherVars(~appId, ~indexName, ~adminApiKey)->Array.forEach(name => { + Console.log(`[search-index] ${name} not set, skipping index upload.`) + }) + } +} + +let _ = main() diff --git a/src/bindings/Algolia.res b/src/bindings/Algolia.res new file mode 100644 index 000000000..30cf205ca --- /dev/null +++ b/src/bindings/Algolia.res @@ -0,0 +1,54 @@ +// Bindings for algoliasearch v5 SDK +// https://github.com/algolia/algoliasearch-client-javascript + +module SearchClient = { + type t +} + +module BatchResponse = { + type t +} + +module SetSettingsResponse = { + type t +} + +module IndexSettings = { + type t = { + searchableAttributes?: array, + attributesForFaceting?: array, + customRanking?: array, + ranking?: array, + attributesToSnippet?: array, + attributeForDistinct?: string, + exactOnSingleWordQuery?: string, + } +} + +module ReplaceAllObjectsOptions = { + type t = { + indexName: string, + objects: array, + batchSize?: int, + } +} + +module SetSettingsOptions = { + type t = { + indexName: string, + indexSettings: IndexSettings.t, + } +} + +@module("algoliasearch") +external make: (string, string) => SearchClient.t = "algoliasearch" + +@send +external replaceAllObjects: ( + SearchClient.t, + ReplaceAllObjectsOptions.t, +) => promise> = "replaceAllObjects" + +@send +external setSettings: (SearchClient.t, SetSettingsOptions.t) => promise = + "setSettings" diff --git a/src/bindings/DocSearch.res b/src/bindings/DocSearch.res index 0c42d8586..a97c2540f 100644 --- a/src/bindings/DocSearch.res +++ b/src/bindings/DocSearch.res @@ -44,7 +44,12 @@ type item = {itemUrl: string} type navigator = {navigate: item => unit} -type searchParameters = {facetFilters: array} +type searchParameters = { + facetFilters?: array, + hitsPerPage?: int, + distinct?: int, + attributesToSnippet?: array, +} @module("@docsearch/react") @react.component external make: ( diff --git a/src/bindings/Env.res b/src/bindings/Env.res index 29a6c4e1b..615215de5 100644 --- a/src/bindings/Env.res +++ b/src/bindings/Env.res @@ -9,3 +9,37 @@ let root_url = switch deployment_url { | Some(url) => url | None => dev ? "http://localhost:5173/" : "https://rescript-lang.org/" } + +// Algolia search configuration (read from .env via Vite) +external algoliaAppIdRaw: option = "import.meta.env.VITE_ALGOLIA_APP_ID" +external algoliaIndexNameRaw: option = "import.meta.env.VITE_ALGOLIA_INDEX_NAME" +external algoliaSearchApiKeyRaw: option = "import.meta.env.VITE_ALGOLIA_SEARCH_API_KEY" + +let algoliaMissingPublicVars = AlgoliaConfig.missingPublicVars( + ~appId=algoliaAppIdRaw, + ~indexName=algoliaIndexNameRaw, + ~searchApiKey=algoliaSearchApiKeyRaw, +) + +let algoliaPublicConfig = AlgoliaConfig.publicConfigFrom( + ~appId=algoliaAppIdRaw, + ~indexName=algoliaIndexNameRaw, + ~searchApiKey=algoliaSearchApiKeyRaw, +) + +let algolia_app_id = switch algoliaPublicConfig { +| Some(config) => config.appId +| None => "" +} + +let algolia_index_name = switch algoliaPublicConfig { +| Some(config) => config.indexName +| None => "" +} + +let algolia_search_api_key = switch algoliaPublicConfig { +| Some(config) => config.searchApiKey +| None => "" +} + +let algolia_read_api_key = algolia_search_api_key diff --git a/src/bindings/Vitest.res b/src/bindings/Vitest.res index b8f20fef8..9ec449715 100644 --- a/src/bindings/Vitest.res +++ b/src/bindings/Vitest.res @@ -65,6 +65,9 @@ external click: element => promise = "click" @send external toBe: (expect, 'a) => unit = "toBe" +@send +external toEqual: (expect, 'a) => unit = "toEqual" + @send external toHaveBeenCalled: expect => unit = "toHaveBeenCalled" diff --git a/src/common/AlgoliaConfig.res b/src/common/AlgoliaConfig.res new file mode 100644 index 000000000..f499d9b9a --- /dev/null +++ b/src/common/AlgoliaConfig.res @@ -0,0 +1,69 @@ +type publicConfig = { + appId: string, + indexName: string, + searchApiKey: string, +} + +type publisherConfig = { + appId: string, + indexName: string, + adminApiKey: string, +} + +let isPresent = value => + switch value { + | Some(v) => v !== "" + | None => false + } + +let missingPublicVars = (~appId, ~indexName, ~searchApiKey): array => { + let missing = [] + if !isPresent(appId) { + missing->Array.push("VITE_ALGOLIA_APP_ID") + } + if !isPresent(indexName) { + missing->Array.push("VITE_ALGOLIA_INDEX_NAME") + } + if !isPresent(searchApiKey) { + missing->Array.push("VITE_ALGOLIA_SEARCH_API_KEY") + } + missing +} + +let publicConfigFrom = (~appId, ~indexName, ~searchApiKey): option => + switch (appId, indexName, searchApiKey) { + | (Some(appId), Some(indexName), Some(searchApiKey)) + if missingPublicVars( + ~appId=Some(appId), + ~indexName=Some(indexName), + ~searchApiKey=Some(searchApiKey), + )->Array.length === 0 => + Some({appId, indexName, searchApiKey}) + | _ => None + } + +let missingPublisherVars = (~appId, ~indexName, ~adminApiKey): array => { + let missing = [] + if !isPresent(appId) { + missing->Array.push("ALGOLIA_APP_ID") + } + if !isPresent(indexName) { + missing->Array.push("ALGOLIA_INDEX_NAME") + } + if !isPresent(adminApiKey) { + missing->Array.push("ALGOLIA_ADMIN_API_KEY") + } + missing +} + +let publisherConfigFrom = (~appId, ~indexName, ~adminApiKey): option => + switch (appId, indexName, adminApiKey) { + | (Some(appId), Some(indexName), Some(adminApiKey)) + if missingPublisherVars( + ~appId=Some(appId), + ~indexName=Some(indexName), + ~adminApiKey=Some(adminApiKey), + )->Array.length === 0 => + Some({appId, indexName, adminApiKey}) + | _ => None + } diff --git a/src/common/AlgoliaEnvStatus.res b/src/common/AlgoliaEnvStatus.res new file mode 100644 index 000000000..20c52ceca --- /dev/null +++ b/src/common/AlgoliaEnvStatus.res @@ -0,0 +1,12 @@ +let publicKeys = ["VITE_ALGOLIA_APP_ID", "VITE_ALGOLIA_INDEX_NAME", "VITE_ALGOLIA_SEARCH_API_KEY"] + +let getMissingPublicAlgoliaVars = (~env: Dict.t): array => + publicKeys->Array.filter(key => + switch env->Dict.get(key) { + | None | Some("") => true + | Some(_) => false + } + ) + +let formatDisabledMessage = (missing: array) => + `Algolia search disabled: missing ${missing->Array.join(", ")}` diff --git a/src/common/Constants.res b/src/common/Constants.res index 3e1e23462..ec4129cc4 100644 --- a/src/common/Constants.res +++ b/src/common/Constants.res @@ -46,14 +46,12 @@ let dropdownLabelNext = "--- Next ---" let dropdownLabelReleased = "--- Released ---" // Used for the DocsOverview and collapsible navigation -let languageManual = version => { - [ - ("Overview", `/docs/manual/${version}/introduction`), - ("Language Features", `/docs/manual/${version}/overview`), - ("JS Interop", `/docs/manual/${version}/embed-raw-javascript`), - ("Build System", `/docs/manual/${version}/build-overview`), - ] -} +let languageManual = [ + ("Overview", "/docs/manual/introduction"), + ("Language Features", "/docs/manual/overview"), + ("JS Interop", "/docs/manual/embed-raw-javascript"), + ("Build System", "/docs/manual/build-overview"), +] let tools = [("Syntax Lookup", "/syntax-lookup")] diff --git a/src/common/SearchIndex.res b/src/common/SearchIndex.res new file mode 100644 index 000000000..8b653e5c6 --- /dev/null +++ b/src/common/SearchIndex.res @@ -0,0 +1,522 @@ +type hierarchy = { + lvl0: string, + lvl1: string, + lvl2: option, + lvl3: option, + lvl4: option, + lvl5: option, + lvl6: option, +} + +type weight = { + pageRank: int, + level: int, + position: int, +} + +type record = { + objectID: string, + url: string, + url_without_anchor: string, + anchor: option, + content: option, + @as("type") type_: string, + hierarchy: hierarchy, + weight: weight, +} + +type heading = { + level: int, + text: string, + content: string, +} + +let maxContentLength = 500 + +let makeHierarchy = (~lvl0, ~lvl1, ~lvl2=?, ~lvl3=?, ~lvl4=?, ~lvl5=?, ~lvl6=?, ()) => { + lvl0, + lvl1, + lvl2, + lvl3, + lvl4, + lvl5, + lvl6, +} + +let truncate = (str: string, ~maxLen: int): string => + switch String.length(str) > maxLen { + | true => String.slice(str, ~start=0, ~end=maxLen) ++ "..." + | false => str + } + +// --- Helpers --- + +let slugify = (text: string): string => + text + ->String.toLowerCase + ->String.replaceRegExp(RegExp.fromString("\\s+", ~flags="g"), "-") + ->String.replaceRegExp(RegExp.fromString("[^a-z0-9\\-]", ~flags="g"), "") + +let stripMdxTags = (text: string): string => + text + ->String.replaceRegExp(RegExp.fromString("", ~flags="g"), "") + ->String.replaceRegExp(RegExp.fromString("<[^>]+>", ~flags="g"), "") + ->String.replaceRegExp(RegExp.fromString("```[\\s\\S]*?```", ~flags="g"), "") + ->String.replaceRegExp(RegExp.fromString("`([^`]+)`", ~flags="g"), "$1") + ->String.replaceRegExp(RegExp.fromString("\\*\\*([^*]+)\\*\\*", ~flags="g"), "$1") + ->String.replaceRegExp(RegExp.fromString("\\*([^*]+)\\*", ~flags="g"), "$1") + ->String.replaceRegExp(RegExp.fromString("\\[([^\\]]+)\\]\\([^)]*\\)", ~flags="g"), "$1") + ->String.replaceRegExp(RegExp.fromString("^#{1,6}\\s+", ~flags="gm"), "") + ->String.replaceRegExp(RegExp.fromString("\\n{2,}", ~flags="g"), "\n") + ->String.trim + +let cleanDocstring = (text: string): string => + text + // Take content before first heading + ->String.split("\n## ") + ->Array.get(0) + ->Option.getOr(text) + // Take content before first code block + ->String.split("\n```") + ->Array.get(0) + ->Option.getOr(text) + // Strip inline code backticks + ->String.replaceRegExp(RegExp.fromString("`([^`]+)`", ~flags="g"), "$1") + // Strip bold + ->String.replaceRegExp(RegExp.fromString("\\*\\*([^*]+)\\*\\*", ~flags="g"), "$1") + // Strip italic + ->String.replaceRegExp(RegExp.fromString("\\*([^*]+)\\*", ~flags="g"), "$1") + // Strip links + ->String.replaceRegExp(RegExp.fromString("\\[([^\\]]+)\\]\\([^)]*\\)", ~flags="g"), "$1") + // Collapse multiple newlines into space + ->String.replaceRegExp(RegExp.fromString("\\n{2,}", ~flags="g"), " ") + // Replace remaining newlines with space + ->String.replaceRegExp(RegExp.fromString("\\n", ~flags="g"), " ") + ->String.trim + +let extractIntro = (content: string): string => { + let parts = content->String.split("\n## ") + let intro = parts[0]->Option.getOr("") + intro + // Remove the # H1 heading line if present at the start + ->String.replaceRegExp(RegExp.fromString("^#[^#].*\\n", ~flags=""), "") + ->stripMdxTags + ->String.trim +} + +let findHeadingMatches: string => array<{..}> = %raw(` + function(content) { + var regex = /^(#{2,6})\s+(.+)$/gm; + var results = []; + var match; + while ((match = regex.exec(content)) !== null) { + results.push({ index: match.index, level: match[1].length, text: match[2] }); + } + return results; + } +`) + +let extractHeadings = (content: string): array => { + let matches = findHeadingMatches(content) + + matches->Array.mapWithIndex((m, i) => { + let startIdx = m["index"] + String.length(m["text"]) + m["level"] + 2 + let endIdx = switch matches[i + 1] { + | Some(next) => next["index"] + | None => String.length(content) + } + let sectionContent = + content + ->String.slice(~start=startIdx, ~end=endIdx) + ->stripMdxTags + ->String.trim + ->truncate(~maxLen=maxContentLength) + + { + level: m["level"], + text: m["text"], + content: sectionContent, + } + }) +} + +// --- File collection --- + +let rec collectFiles = (dirPath: string): array => { + let entries = Node.Fs.readdirSync(dirPath) + entries->Array.reduce([], (acc, entry) => { + let fullPath = Node.Path.join([dirPath, entry]) + let stats = Node.Fs.statSync(fullPath) + switch stats["isDirectory"]() { + | true => acc->Array.concat(collectFiles(fullPath)) + | false => { + acc->Array.push(fullPath) + acc + } + } + }) +} + +let isMdxFile = (path: string): bool => Node.Path.extname(path) === ".mdx" + +let filenameWithoutExt = (path: string): string => + Node.Path.basename(path)->String.replace(".mdx", "") + +// --- Record builders --- + +let buildMarkdownRecords = ( + ~category: string, + ~basePath: string, + ~dirPath: string, + ~pageRank: int, +): array => { + collectFiles(dirPath) + ->Array.filter(isMdxFile) + ->Array.flatMap(filePath => { + let fileContent = Node.Fs.readFileSync2(filePath, "utf8") + let parsed = MarkdownParser.parseSync(fileContent) + + switch DocFrontmatter.decode(parsed.frontmatter) { + | None => [] + | Some(fm) => { + let pageUrl = switch fm.canonical->Null.toOption { + | Some(canonical) => canonical + | None => basePath ++ "/" ++ filenameWithoutExt(filePath) + } + + let introText = parsed.content->extractIntro->truncate(~maxLen=maxContentLength) + let pageContent = switch introText { + | "" => fm.description->Null.toOption->Option.getOr("") + | text => text + } + + let pageRecord = { + objectID: pageUrl, + url: pageUrl, + url_without_anchor: pageUrl, + anchor: None, + content: Some(pageContent->truncate(~maxLen=maxContentLength)), + type_: "lvl1", + hierarchy: makeHierarchy(~lvl0=category, ~lvl1=fm.title, ()), + weight: {pageRank, level: 100, position: 0}, + } + + let headingRecords = + parsed.content + ->extractHeadings + ->Array.mapWithIndex((heading, i) => { + let anchor = slugify(heading.text) + let headingUrl = pageUrl ++ "#" ++ anchor + let typeLvl = switch heading.level { + | 2 => "lvl2" + | 3 => "lvl3" + | 4 => "lvl4" + | 5 => "lvl5" + | _ => "lvl6" + } + let weightLevel = switch heading.level { + | 2 => 80 + | 3 => 60 + | 4 => 40 + | 5 => 20 + | _ => 10 + } + let hierarchy = switch heading.level { + | 2 => makeHierarchy(~lvl0=category, ~lvl1=fm.title, ~lvl2=heading.text, ()) + | 3 => + makeHierarchy( + ~lvl0=category, + ~lvl1=fm.title, + ~lvl2=heading.text, + ~lvl3=heading.text, + (), + ) + | 4 => + makeHierarchy( + ~lvl0=category, + ~lvl1=fm.title, + ~lvl2=heading.text, + ~lvl3=heading.text, + ~lvl4=heading.text, + (), + ) + | _ => makeHierarchy(~lvl0=category, ~lvl1=fm.title, ~lvl2=heading.text, ()) + } + + { + objectID: headingUrl, + url: headingUrl, + url_without_anchor: pageUrl, + anchor: Some(anchor), + content: switch heading.content { + | "" => None + | c => Some(c) + }, + type_: typeLvl, + hierarchy, + weight: {pageRank, level: weightLevel, position: i + 1}, + } + }) + + [pageRecord]->Array.concat(headingRecords) + } + } + }) +} + +let buildBlogRecords = (~dirPath: string, ~pageRank: int): array => { + open JSON + Node.Fs.readdirSync(dirPath) + ->Array.filter(entry => isMdxFile(entry) && entry !== "archived") + ->Array.filterMap(entry => { + let fullPath = Node.Path.join([dirPath, entry]) + let stats = Node.Fs.statSync(fullPath) + switch stats["isDirectory"]() { + | true => None + | false => { + let fileContent = Node.Fs.readFileSync2(fullPath, "utf8") + let parsed = MarkdownParser.parseSync(fileContent) + + switch parsed.frontmatter { + | Object(dict{"title": String(title), "description": ?description}) => { + let slug = filenameWithoutExt(fullPath) + let url = "/blog/" ++ slug + let desc = switch description { + | Some(String(d)) => Some(d->truncate(~maxLen=maxContentLength)) + | _ => None + } + + Some({ + objectID: url, + url, + url_without_anchor: url, + anchor: None, + content: desc, + type_: "lvl1", + hierarchy: makeHierarchy(~lvl0="Blog", ~lvl1=title, ()), + weight: {pageRank, level: 100, position: 0}, + }) + } + | _ => None + } + } + } + }) +} + +let buildSyntaxLookupRecords = (~dirPath: string, ~pageRank: int): array => { + open JSON + Node.Fs.readdirSync(dirPath) + ->Array.filter(isMdxFile) + ->Array.filterMap(entry => { + let fullPath = Node.Path.join([dirPath, entry]) + let fileContent = Node.Fs.readFileSync2(fullPath, "utf8") + let parsed = MarkdownParser.parseSync(fileContent) + + switch parsed.frontmatter { + | Object(dict{ + "id": String(id), + "name": String(name), + "summary": String(summary), + "keywords": ?_keywords, + }) => + Some({ + objectID: "syntax-" ++ id, + url: "/syntax-lookup", + url_without_anchor: "/syntax-lookup", + anchor: None, + content: Some(summary->truncate(~maxLen=maxContentLength)), + type_: "lvl1", + hierarchy: makeHierarchy(~lvl0="Syntax", ~lvl1=name, ()), + weight: {pageRank, level: 100, position: 0}, + }) + | _ => None + } + }) +} + +let buildApiRecords = ( + ~basePath: string, + ~dirPath: string, + ~pageRank: int, + ~category: string, + ~files: option>=?, +): array => { + open JSON + Node.Fs.readdirSync(dirPath) + ->Array.filter(entry => { + let isJson = String.endsWith(entry, ".json") && entry !== "toc_tree.json" + switch files { + | Some(allowed) => isJson && allowed->Array.includes(entry) + | None => isJson + } + }) + ->Array.flatMap(entry => { + let fullPath = Node.Path.join([dirPath, entry]) + let fileContent = Node.Fs.readFileSync2(fullPath, "utf8") + + switch JSON.parseOrThrow(fileContent) { + | Object(modules) => + modules + ->Dict.toArray + ->Array.flatMap(((key, moduleJson)) => { + switch moduleJson { + | Object(dict{ + "id": String(id), + "name": String(name), + "docstrings": Array(docstrings), + "items": Array(items), + }) => { + let moduleUrl = basePath ++ "/" ++ key + let moduleDocstring = switch docstrings[0] { + | Some(String(d)) => Some(d->cleanDocstring->truncate(~maxLen=maxContentLength)) + | _ => None + } + + let moduleRecord = { + objectID: id, + url: moduleUrl, + url_without_anchor: moduleUrl, + anchor: None, + content: moduleDocstring, + type_: "lvl1", + hierarchy: makeHierarchy(~lvl0=category, ~lvl1=name, ()), + weight: {pageRank, level: 90, position: 0}, + } + + let sortedItems = items->Array.toSorted( + (a, b) => { + switch (a, b) { + | (Object(dict{"name": String(nameA)}), Object(dict{"name": String(nameB)})) => + nameA->String.localeCompare(nameB) + | _ => 0. + } + }, + ) + + let itemRecords = sortedItems->Array.filterMapWithIndex( + (item, i) => { + switch item { + | Object(dict{ + "id": String(itemId), + "name": String(itemName), + "docstrings": Array(itemDocstrings), + "signature": ?signature, + "kind": String(kind), + }) => { + let kindPrefix = switch kind { + | "type" => "type-" + | _ => "value-" + } + let itemAnchor = kindPrefix ++ itemName + let itemUrl = moduleUrl ++ "#" ++ itemAnchor + let qualifiedName = name ++ "." ++ itemName + let docstringIntro = switch itemDocstrings[0] { + | Some(String(d)) if String.length(d) > 0 => { + // Take content before first heading or code block + let intro = + d + ->String.split("\n## ") + ->Array.get(0) + ->Option.getOr(d) + ->String.split("\n```") + ->Array.get(0) + ->Option.getOr(d) + ->String.trim + Some(intro->truncate(~maxLen=2000)) + } + | _ => None + } + let content = switch docstringIntro { + | Some(d) if String.length(d) > 0 => Some(d) + | _ => + switch signature { + | Some(String(s)) => Some(s) + | _ => None + } + } + + Some({ + objectID: itemId, + url: itemUrl, + url_without_anchor: moduleUrl, + anchor: Some(itemAnchor), + content, + type_: "lvl1", + hierarchy: makeHierarchy(~lvl0=category, ~lvl1=qualifiedName, ()), + weight: {pageRank, level: 70, position: i}, + }) + } + | _ => None + } + }, + ) + + [moduleRecord]->Array.concat(itemRecords) + } + | _ => [] + } + }) + | _ => [] + | exception _ => [] + } + }) +} + +// --- JSON serialization --- + +let optionToJson = (opt: option): JSON.t => + switch opt { + | Some(s) => JSON.String(s) + | None => JSON.Null + } + +let hierarchyToJson = (h: hierarchy): JSON.t => { + let dict = Dict.make() + dict->Dict.set("lvl0", JSON.String(h.lvl0)) + dict->Dict.set("lvl1", JSON.String(h.lvl1)) + dict->Dict.set("lvl2", optionToJson(h.lvl2)) + dict->Dict.set("lvl3", optionToJson(h.lvl3)) + dict->Dict.set("lvl4", optionToJson(h.lvl4)) + dict->Dict.set("lvl5", optionToJson(h.lvl5)) + dict->Dict.set("lvl6", optionToJson(h.lvl6)) + JSON.Object(dict) +} + +let weightToJson = (w: weight): JSON.t => { + let dict = Dict.make() + dict->Dict.set("pageRank", JSON.Number(Int.toFloat(w.pageRank))) + dict->Dict.set("level", JSON.Number(Int.toFloat(w.level))) + dict->Dict.set("position", JSON.Number(Int.toFloat(w.position))) + JSON.Object(dict) +} + +let withBaseUrl = (record: record, ~siteUrl: string): record => { + let normalizedSiteUrl = siteUrl->String.replaceRegExp(RegExp.fromString("/+$", ~flags=""), "") + let absolutize = (url: string) => + if RegExp.test(RegExp.fromString("^https?://", ~flags=""), url) { + url + } else { + let normalizedPath = String.startsWith(url, "/") ? url : "/" ++ url + normalizedSiteUrl ++ normalizedPath + } + + { + ...record, + url: absolutize(record.url), + url_without_anchor: absolutize(record.url_without_anchor), + } +} + +let toJson = (r: record): JSON.t => { + let dict = Dict.make() + dict->Dict.set("objectID", JSON.String(r.objectID)) + dict->Dict.set("url", JSON.String(r.url)) + dict->Dict.set("url_without_anchor", JSON.String(r.url_without_anchor)) + dict->Dict.set("anchor", optionToJson(r.anchor)) + dict->Dict.set("content", optionToJson(r.content)) + dict->Dict.set("type", JSON.String(r.type_)) + dict->Dict.set("hierarchy", hierarchyToJson(r.hierarchy)) + dict->Dict.set("weight", weightToJson(r.weight)) + JSON.Object(dict) +} diff --git a/src/common/SearchIndex.resi b/src/common/SearchIndex.resi new file mode 100644 index 000000000..5e27feb6d --- /dev/null +++ b/src/common/SearchIndex.resi @@ -0,0 +1,86 @@ +type hierarchy = { + lvl0: string, + lvl1: string, + lvl2: option, + lvl3: option, + lvl4: option, + lvl5: option, + lvl6: option, +} + +type weight = { + pageRank: int, + level: int, + position: int, +} + +type record = { + objectID: string, + url: string, + url_without_anchor: string, + anchor: option, + content: option, + @as("type") type_: string, + hierarchy: hierarchy, + weight: weight, +} + +type heading = { + level: int, + text: string, + content: string, +} + +let maxContentLength: int + +let makeHierarchy: ( + ~lvl0: string, + ~lvl1: string, + ~lvl2: string=?, + ~lvl3: string=?, + ~lvl4: string=?, + ~lvl5: string=?, + ~lvl6: string=?, + unit, +) => hierarchy + +let truncate: (string, ~maxLen: int) => string + +let slugify: string => string + +let stripMdxTags: string => string + +let cleanDocstring: string => string + +let extractIntro: string => string + +let extractHeadings: string => array + +let optionToJson: option => JSON.t + +let hierarchyToJson: hierarchy => JSON.t + +let weightToJson: weight => JSON.t + +let withBaseUrl: (record, ~siteUrl: string) => record + +let buildMarkdownRecords: ( + ~category: string, + ~basePath: string, + ~dirPath: string, + ~pageRank: int, +) => array + +let buildBlogRecords: (~dirPath: string, ~pageRank: int) => array + +let buildSyntaxLookupRecords: (~dirPath: string, ~pageRank: int) => array + +let buildApiRecords: ( + ~basePath: string, + ~dirPath: string, + ~pageRank: int, + ~category: string, + ~files: array=?, +) => array + +let toJson: record => JSON.t diff --git a/src/common/Url.res b/src/common/Url.res index fb31e28cd..9122cb867 100644 --- a/src/common/Url.res +++ b/src/common/Url.res @@ -1,46 +1,6 @@ -type version = - | Latest - | Next - | NoVersion - | Version(string) - -/* - Example 1: - Url: "/docs/manual/latest/advanced/introduction" - - Results in: - fullpath: ["docs", "manual", "latest", "advanced", "introduction"] - base: ["docs", "manual"] - version: Latest - pagepath: ["advanced", "introduction"] - */ - -/* - Example 2: - Url: "/apis/" - - Results in: - fullpath: ["apis"] - base: ["apis"] - version: NoVersion - pagepath: [] - */ - -/* - Example 3: - Url: "/apis/javascript/v7.1.1/node" - - Results in: - fullpath: ["apis", "javascript", "v7.1.1", "node"] - base: ["apis", "javascript"] - version: Version("v7.1.1"), - pagepath: ["node"] - */ - type t = { fullpath: array, base: array, - version: version, pagepath: array, } @@ -56,29 +16,13 @@ let prettyString = (str: string) => { } let parse = (route: string): t => { - let fullpath = route->String.split("/")->Array.filter(s => s !== "") - let foundVersionIndex = Array.findIndex(fullpath, chunk => { - RegExp.test(/latest|next|v\d+(\.\d+)?(\.\d+)?/, chunk) - }) + let routePath = route->String.split("/")->Array.filter(s => s !== "") - let (version, base, pagepath) = if foundVersionIndex == -1 { - (NoVersion, fullpath, []) - } else { - let version = switch fullpath[foundVersionIndex] { - | Some(version) if version === Constants.versions.next => Next - | Some(version) if version === Constants.versions.latest => Latest - | Some("latest") => Latest // still used for React docs - | Some(v) => Version(v) - | None => NoVersion - } - ( - version, - fullpath->Array.slice(~start=0, ~end=foundVersionIndex), - fullpath->Array.slice(~start=foundVersionIndex + 1, ~end=Array.length(fullpath)), - ) + { + fullpath: routePath, + base: routePath, + pagepath: [], } - - {fullpath, base, version, pagepath} } @unboxed @@ -95,13 +39,6 @@ let getVersionFromStorage = (key: storageKey) => { } } -let getVersionString = url => - switch url.version { - | Next => Constants.versions.next - | Latest | NoVersion => Constants.versions.latest - | Version(version) => version - } - let normalizePath = string => { string->String.replaceRegExp(/\/$/, "")->String.toLocaleLowerCase } diff --git a/src/common/Url.resi b/src/common/Url.resi index afbeb91c2..991ca39cf 100644 --- a/src/common/Url.resi +++ b/src/common/Url.resi @@ -1,13 +1,6 @@ -type version = - | Latest - | Next - | NoVersion - | Version(string) - type t = { fullpath: array, base: array, - version: version, pagepath: array, } @@ -29,8 +22,6 @@ type storageKey = let getVersionFromStorage: storageKey => option -let getVersionString: t => string - let normalizePath: string => string let normalizeAnchor: string => string diff --git a/src/components/Icon.res b/src/components/Icon.res index daac2bdf4..7830a805d 100644 --- a/src/components/Icon.res +++ b/src/components/Icon.res @@ -291,3 +291,84 @@ module Clipboard = { } + +module DocPage = { + @react.component + let make = () => +
+ + + + + + + +
+} + +module DocHash = { + @react.component + let make = () => +
+ + + + + + +
+} + +module DocTree = { + @react.component + let make = () => + + + + + +} + +module DocSelect = { + @react.component + let make = () => +
+ + + + + + +
+} diff --git a/src/components/Icon.resi b/src/components/Icon.resi index 4087c13b6..df1f0e24b 100644 --- a/src/components/Icon.resi +++ b/src/components/Icon.resi @@ -82,3 +82,23 @@ module Clipboard: { @react.component let make: (~className: string=?) => React.element } + +module DocPage: { + @react.component + let make: unit => React.element +} + +module DocHash: { + @react.component + let make: unit => React.element +} + +module DocTree: { + @react.component + let make: unit => React.element +} + +module DocSelect: { + @react.component + let make: unit => React.element +} diff --git a/src/components/Meta.res b/src/components/Meta.res index 4985bdb18..62eda84b4 100644 --- a/src/components/Meta.res +++ b/src/components/Meta.res @@ -72,8 +72,6 @@ let make = ( - // Docsearch meta tags - // Robots meta tag diff --git a/src/components/Search.res b/src/components/Search.res index b9ccbb103..41ff20e4c 100644 --- a/src/components/Search.res +++ b/src/components/Search.res @@ -1,108 +1,122 @@ -let apiKey = "a2485ef172b8cd82a2dfa498d551399b" -let indexName = "rescript-lang" -let appId = "S32LNEY41T" - type state = Active | Inactive -let hit = ({hit, children}: DocSearch.hitComponent) => { - let toTitle = str => str->String.charAt(0)->String.toUpperCase ++ String.slice(str, ~start=1) - - let description = switch hit.url - ->String.split("/") - ->Array.slice(~start=1) - ->List.fromArray { - | list{"blog" as r | "community" as r, ..._} => r->toTitle - | list{"docs", doc, version, ...rest} => - let path = rest->List.toArray - - let info = - path - ->Array.slice(~start=0, ~end=Array.length(path) - 1) - ->Array.map(path => - switch path { - | "api" => "API" - | other => toTitle(other) - } - ) - - [doc->toTitle, version->toTitle]->Array.concat(info)->Array.join(" / ") - | _ => "" +let unavailableText = "Search unavailable" +let unavailableLabel = "Search unavailable for this build" + +let toRelativeSiteUrl = (url: string, ~siteUrl: string): string => { + let normalizedSiteUrl = siteUrl->String.replaceRegExp(RegExp.fromString("/+$", ~flags=""), "") + if String.startsWith(url, normalizedSiteUrl) { + let relativePath = String.slice(url, ~start=String.length(normalizedSiteUrl)) + if relativePath === "" { + "/" + } else if String.startsWith(relativePath, "/") { + relativePath + } else { + "/" ++ relativePath + } + } else { + url } +} - let isDeprecated = hit.deprecated->Option.isSome - let deprecatedBadge = isDeprecated - ? - {"Deprecated"->React.string} - - : React.null - - - - {deprecatedBadge} - {description->React.string} - - children - +let normalizeHitUrls = (items: array, ~siteUrl: string) => + items->Array.map(hit => { + let url = toRelativeSiteUrl(hit.url, ~siteUrl) + let url_without_anchor = toRelativeSiteUrl(hit.url_without_anchor, ~siteUrl) + {...hit, url, url_without_anchor} + }) + +let navigator = (~siteUrl: string): DocSearch.navigator => { + navigate: ({itemUrl}) => { + ReactRouter.navigate(toRelativeSiteUrl(itemUrl, ~siteUrl)) + }, } -let transformItems = (items: DocSearch.transformItems) => { - items - ->Array.filterMap(item => { - let url = try WebAPI.URL.make(~url=item.url)->Some catch { - | JsExn(obj) => - Console.error2(`Failed to parse URL ${item.url}`, obj) - None +let getHighlightedTitle: DocSearch.docSearchHit => string = %raw(` + function(hit) { + var type = hit.type; + var h = hit._highlightResult && hit._highlightResult.hierarchy; + var raw = hit.hierarchy; + try { + if (type && type !== 'lvl1' && type !== 'lvl0') { + var lvl = h && h[type] && h[type].value; + if (lvl) return lvl; + } + if (h && h.lvl1 && h.lvl1.value) return h.lvl1.value; + } catch(e) {} + return (raw && raw.lvl1) || ''; + } +`) + +let getSubtitle: DocSearch.docSearchHit => option = %raw(` + function(hit) { + var type = hit.type; + if (type && type !== 'lvl1' && type !== 'lvl0') { + var raw = hit.hierarchy; + if (raw && raw.lvl1) return raw.lvl1; } - switch url { - | Some({pathname, hash}) => - RegExp.test(/v(8|9|10|11)\./, pathname) - ? None - : { - // DocSearch internally calls .replace() on hierarchy.lvl1, so we must - // provide a fallback for items where lvl1 is null to prevent crashes - let hierarchy = item.hierarchy - let lvl0 = hierarchy.lvl0->Nullable.toOption->Option.getOr("") - let lvl1 = hierarchy.lvl1->Nullable.toOption->Option.getOr(lvl0) - Some({ - ...item, - deprecated: pathname->String.includes("api/js") || - pathname->String.includes("api/core") - ? Some("Deprecated") - : None, - url: pathname->String.replace("/v12.0.0/", "/") ++ hash, - hierarchy: { - ...hierarchy, - lvl0: Nullable.make(lvl0), - lvl1: Nullable.make(lvl1), - }, - }) - } + return undefined; + } +`) + +let markdownToHtml = (text: string): string => + text + // Strip stray backslashes from MDX processing + ->String.replaceRegExp(RegExp.fromString("^\\\\\\s+", ~flags=""), "") + ->String.replaceRegExp(RegExp.fromString("\\\\\\s+", ~flags="g"), " ") + ->String.replaceRegExp( + RegExp.fromString("See\\s+\\[([^\\]]+)\\]\\([^)]*\\)\\s+on MDN\\.?", ~flags="g"), + "", + ) + ->String.replaceRegExp(RegExp.fromString("See\\s+\\S+\\s+on MDN\\.?", ~flags="g"), "") + ->String.replaceRegExp(RegExp.fromString("\\[([^\\]]+)\\]\\([^)]*\\)", ~flags="g"), "$1") + ->String.replaceRegExp(RegExp.fromString("\\x60([^\\x60]+)\\x60", ~flags="g"), "$1") + ->String.replaceRegExp( + RegExp.fromString("\\*\\*([^*]+)\\*\\*", ~flags="g"), + "$1", + ) + ->String.replaceRegExp(RegExp.fromString("\\*([^*]+)\\*", ~flags="g"), "$1") + ->String.replaceRegExp(RegExp.fromString("\\n{2,}", ~flags="g"), "
") + ->String.replaceRegExp(RegExp.fromString("\\n", ~flags="g"), " ") + ->String.trim + +let isChildHit = (hit: DocSearch.docSearchHit) => + switch hit.type_ { + | Lvl2 | Lvl3 | Lvl4 | Lvl5 | Lvl6 | Content => true + | Lvl0 | Lvl1 => hit.url->String.includes("#") + } - | None => None - } - }) - // Sort deprecated items to the end - ->Array.toSorted((a, b) => { - switch (a.deprecated, b.deprecated) { - | (Some(_), None) => 1. // a is deprecated, b is not - put a after b - | (None, Some(_)) => -1. // a is not deprecated, b is - put a before b - | _ => 0. - } - }) - ->Array.toSorted((a, b) => { - switch (a.url->String.includes("api/stdlib"), b.url->String.includes("api/stdlib")) { - | (true, false) => -1. // a is a stdlib doc, b is not - put a before b - | (false, true) => 1. // a is not a stdlib doc, b is - put a after b - | _ => 0. // both same API status - maintain original order - } - }) +let hitComponent = ({hit, children: _}: DocSearch.hitComponent): React.element => { + let titleHtml = getHighlightedTitle(hit) + let subtitle = getSubtitle(hit) + let contentHtml = hit.content->Nullable.toOption->Option.map(markdownToHtml) + let isChild = isChildHit(hit) + + +
+ {isChild ? : React.null} + {isChild ? : } +
+ + {switch subtitle { + | Some(s) => {React.string(s)} + | None => React.null + }} + {switch contentHtml { + | Some(c) if String.length(c) > 0 => + + | _ => React.null + }} +
+ +
+
} @react.component let make = () => { let (state, setState) = React.useState(_ => Inactive) + let algoliaConfig = Env.algoliaPublicConfig let handleCloseModal = () => { let () = switch WebAPI.Document.querySelector(document, ".DocSearch-Modal") { @@ -120,33 +134,36 @@ let make = () => { } React.useEffect(() => { - let isEditableTag = (el: WebAPI.DOMAPI.element) => - switch el.tagName { - | "TEXTAREA" | "SELECT" | "INPUT" => true - | _ => false - } + switch algoliaConfig { + | None => None + | Some(_) => + let isEditableTag = (el: WebAPI.DOMAPI.element) => + switch el.tagName { + | "TEXTAREA" | "SELECT" | "INPUT" => true + | _ => false + } - let focusSearch = (e: WebAPI.UIEventsAPI.keyboardEvent) => { - switch document.activeElement { - | Value(el) - if el->isEditableTag || (Obj.magic(el): WebAPI.DOMAPI.htmlElement).isContentEditable => () - | _ => - setState(_ => Active) - WebAPI.KeyboardEvent.preventDefault(e) + let focusSearch = (e: WebAPI.UIEventsAPI.keyboardEvent) => { + switch document.activeElement { + | Value(el) + if el->isEditableTag || (Obj.magic(el): WebAPI.DOMAPI.htmlElement).isContentEditable => () + | _ => + setState(_ => Active) + WebAPI.KeyboardEvent.preventDefault(e) + } } - } - let handleGlobalKeyDown = (e: WebAPI.UIEventsAPI.keyboardEvent) => { - switch e.key { - | "/" => focusSearch(e) - | "k" if e.ctrlKey || e.metaKey => focusSearch(e) - | "Escape" => handleCloseModal() - | _ => () + let handleGlobalKeyDown = (e: WebAPI.UIEventsAPI.keyboardEvent) => { + switch e.key { + | "/" => focusSearch(e) + | "k" if e.ctrlKey || e.metaKey => focusSearch(e) + | _ => () + } } + WebAPI.Window.addEventListener(window, Keydown, handleGlobalKeyDown) + Some(() => WebAPI.Window.removeEventListener(window, Keydown, handleGlobalKeyDown)) } - WebAPI.Window.addEventListener(window, Keydown, handleGlobalKeyDown) - Some(() => WebAPI.Window.removeEventListener(window, Keydown, handleGlobalKeyDown)) - }, [setState]) + }, [algoliaConfig]) let onClick = _ => { setState(_ => Active) @@ -156,34 +173,54 @@ let make = () => { handleCloseModal() }, [setState]) - <> + switch algoliaConfig { + | None => - {switch state { - | Active => - switch ReactDOM.querySelector("body") { - | Some(element) => - ReactDOM.createPortal( - Float.toInt} - transformItems={transformItems} - hitComponent=hit - />, - element, - ) - | None => React.null - } - | Inactive => React.null - }} - + | Some({appId, indexName, searchApiKey}) => + <> + + {switch state { + | Active => + switch ReactDOM.querySelector("body") { + | Some(element) => + ReactDOM.createPortal( + normalizeHitUrls(items, ~siteUrl=Env.root_url)} + hitComponent + onClose + initialScrollY={window.scrollY->Float.toInt} + searchParameters={ + distinct: 3, + hitsPerPage: 20, + attributesToSnippet: ["content:9999"], + } + />, + element, + ) + | None => React.null + } + | Inactive => React.null + }} + + } } diff --git a/styles/_docsearch.css b/styles/_docsearch.css index ac8c167b7..ba5f02688 100644 --- a/styles/_docsearch.css +++ b/styles/_docsearch.css @@ -137,17 +137,17 @@ @apply hidden; } +.DocSearch-Clear { + @apply hidden; +} + .DocSearch-LoadingIndicator svg, .DocSearch-MagnifierLabel svg { @apply w-4 h-4; } .DocSearch-Cancel { - font-size: 0; - background-image: url("data:image/svg+xml,%3Csvg width='16' height='7' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M.506 6h3.931V4.986H1.736v-1.39h2.488V2.583H1.736V1.196h2.69V.182H.506V6ZM8.56 1.855h1.18C9.721.818 8.87.102 7.574.102c-1.276 0-2.21.705-2.205 1.762-.003.858.602 1.35 1.585 1.585l.634.159c.633.153.986.335.988.727-.002.426-.406.716-1.03.716-.64 0-1.1-.295-1.14-.878h-1.19c.03 1.259.931 1.91 2.343 1.91 1.42 0 2.256-.68 2.259-1.745-.003-.969-.733-1.483-1.744-1.71l-.523-.125c-.506-.117-.93-.304-.92-.722 0-.375.332-.65.934-.65.588 0 .949.267.994.724ZM15.78 2.219C15.618.875 14.6.102 13.254.102c-1.537 0-2.71 1.086-2.71 2.989 0 1.898 1.153 2.989 2.71 2.989 1.492 0 2.392-.992 2.526-2.063l-1.244-.006c-.117.623-.606.98-1.262.98-.883 0-1.483-.656-1.483-1.9 0-1.21.591-1.9 1.492-1.9.673 0 1.159.389 1.253 1.028h1.244Z' fill='%2394a3b8'/%3E%3C/svg%3E") !important; - background-size: 57.1428571429% auto; - @apply w-9 h-7 bg-no-repeat bg-center appearance-none border border-gray-20 - rounded; + display: none !important; } /* Modal Dropdown */ @@ -273,8 +273,16 @@ svg.DocSearch-Hit-Select-Icon { @apply text-14 text-gray-60; } +.DocSearch-Hit-subtitle { + @apply text-12 text-gray-40; +} + .DocSearch-Hit-path { - @apply text-12; + @apply text-14 text-gray-60; +} + +.DocSearch-Hit-path code { + @apply bg-gray-10 text-black rounded-sm px-1 py-0.5 text-12 font-mono; } .DocSearch-Hit[aria-selected="true"] .DocSearch-Hit-title, @@ -319,12 +327,40 @@ svg.DocSearch-Hit-Select-Icon { /* Modal Footer */ .DocSearch-Footer { - @apply flex flex-row-reverse flex-shrink-0 justify-between relative - select-none w-full z-100 p-4; + border-top: 1px solid; + @apply flex flex-shrink-0 items-center justify-between relative + select-none w-full z-100 px-4 py-3 border-gray-20; } .DocSearch-Commands { - display: none !important; + @apply flex items-center gap-3 list-none m-0 p-0; +} + +.DocSearch-Commands li { + @apply flex items-center gap-1.5 text-12 text-gray-40; +} + +.DocSearch-Commands-Key { + @apply inline-flex items-center justify-center w-5 h-5 rounded + border border-gray-20 bg-gray-5 text-11 text-gray-60 font-medium; +} + +/* Swap "to close" / "to clear" based on whether the input has a query. + :placeholder-shown is true when the input is empty, false when it has text. */ +.DocSearch-Commands li:last-child .DocSearch-Label { + font-size: 0; +} + +.DocSearch-Commands li:last-child .DocSearch-Label::after { + content: "to close"; + font-size: 0.75rem; +} + +.DocSearch-Modal:has(.DocSearch-Input:not(:placeholder-shown)) + .DocSearch-Commands + li:last-child + .DocSearch-Label::after { + content: "to clear"; } /* Responsive */ diff --git a/yarn.lock b/yarn.lock index 895464783..0f8ee4b83 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5,6 +5,18 @@ __metadata: version: 8 cacheKey: 10c0 +"@algolia/abtesting@npm:1.16.1": + version: 1.16.1 + resolution: "@algolia/abtesting@npm:1.16.1" + dependencies: + "@algolia/client-common": "npm:5.50.1" + "@algolia/requester-browser-xhr": "npm:5.50.1" + "@algolia/requester-fetch": "npm:5.50.1" + "@algolia/requester-node-http": "npm:5.50.1" + checksum: 10c0/0ca113338a447693b4827bdf87f37490ccd81bc1bbbe39b02c338ff79582379a68853c3d35fb2297fd5636fa43818dac9e04b59965a8b47851e8b1da041b45e8 + languageName: node + linkType: hard + "@algolia/autocomplete-core@npm:1.19.2": version: 1.19.2 resolution: "@algolia/autocomplete-core@npm:1.19.2" @@ -36,6 +48,148 @@ __metadata: languageName: node linkType: hard +"@algolia/client-abtesting@npm:5.50.1": + version: 5.50.1 + resolution: "@algolia/client-abtesting@npm:5.50.1" + dependencies: + "@algolia/client-common": "npm:5.50.1" + "@algolia/requester-browser-xhr": "npm:5.50.1" + "@algolia/requester-fetch": "npm:5.50.1" + "@algolia/requester-node-http": "npm:5.50.1" + checksum: 10c0/a3fb097e72acc5f1b009694774c0b23e1a7701ec4f54bbf4b20114f9adc73565f8d8c7fba492d769b6f5becd1ef4bf6b92073fb289cd06bfb3e12b2f0989f9ae + languageName: node + linkType: hard + +"@algolia/client-analytics@npm:5.50.1": + version: 5.50.1 + resolution: "@algolia/client-analytics@npm:5.50.1" + dependencies: + "@algolia/client-common": "npm:5.50.1" + "@algolia/requester-browser-xhr": "npm:5.50.1" + "@algolia/requester-fetch": "npm:5.50.1" + "@algolia/requester-node-http": "npm:5.50.1" + checksum: 10c0/ade9f7ee8e8872f0c54149a9292fc32bad9e0b189068ca283f7110ce3f638b14c5078ce43d2c00c2bf752d3aa96e6bea63e4f1184cbe5bc36501074d96595d05 + languageName: node + linkType: hard + +"@algolia/client-common@npm:5.50.1": + version: 5.50.1 + resolution: "@algolia/client-common@npm:5.50.1" + checksum: 10c0/4750773473748fec73a7a9be3081274e21f2c4ccac463618b2ec470113c44c1f6961a991382c999acf04bd83e074547cd57c6304c4218d31bb0089b5c1099bf3 + languageName: node + linkType: hard + +"@algolia/client-insights@npm:5.50.1": + version: 5.50.1 + resolution: "@algolia/client-insights@npm:5.50.1" + dependencies: + "@algolia/client-common": "npm:5.50.1" + "@algolia/requester-browser-xhr": "npm:5.50.1" + "@algolia/requester-fetch": "npm:5.50.1" + "@algolia/requester-node-http": "npm:5.50.1" + checksum: 10c0/62ca243328f38e9a245e2860c12d1e76529e9bf68d5a30881a053adf5cbaddda27af631edd33e23d879a9e5445c66e2654f0149695cd1b75b09b42ea57ef575f + languageName: node + linkType: hard + +"@algolia/client-personalization@npm:5.50.1": + version: 5.50.1 + resolution: "@algolia/client-personalization@npm:5.50.1" + dependencies: + "@algolia/client-common": "npm:5.50.1" + "@algolia/requester-browser-xhr": "npm:5.50.1" + "@algolia/requester-fetch": "npm:5.50.1" + "@algolia/requester-node-http": "npm:5.50.1" + checksum: 10c0/cbc099bd7a5f8ccefd4135a59dfa2b6136b751ed35d451a0c89738c8ad404195348d5553630ab8e59f056f17b8a284e918151696050b740d96e304c8f40174fd + languageName: node + linkType: hard + +"@algolia/client-query-suggestions@npm:5.50.1": + version: 5.50.1 + resolution: "@algolia/client-query-suggestions@npm:5.50.1" + dependencies: + "@algolia/client-common": "npm:5.50.1" + "@algolia/requester-browser-xhr": "npm:5.50.1" + "@algolia/requester-fetch": "npm:5.50.1" + "@algolia/requester-node-http": "npm:5.50.1" + checksum: 10c0/345e0ecaf587aec2a956c2039da817fd26e203c8689fe8e0d428baf6ab03f0809a936099ae420e779d3ec252bbcaf3061c6e8670c660d7a9d66e98627d8938df + languageName: node + linkType: hard + +"@algolia/client-search@npm:5.50.1": + version: 5.50.1 + resolution: "@algolia/client-search@npm:5.50.1" + dependencies: + "@algolia/client-common": "npm:5.50.1" + "@algolia/requester-browser-xhr": "npm:5.50.1" + "@algolia/requester-fetch": "npm:5.50.1" + "@algolia/requester-node-http": "npm:5.50.1" + checksum: 10c0/7910c074aa7b4fbbad2af082a7623d7d65ba0c19e0933d4658e43d588cd87ed2e851aad0c5428ce2a00a3e3248349fcda20ed5abb7700b93d03a475e2ce7a378 + languageName: node + linkType: hard + +"@algolia/ingestion@npm:1.50.1": + version: 1.50.1 + resolution: "@algolia/ingestion@npm:1.50.1" + dependencies: + "@algolia/client-common": "npm:5.50.1" + "@algolia/requester-browser-xhr": "npm:5.50.1" + "@algolia/requester-fetch": "npm:5.50.1" + "@algolia/requester-node-http": "npm:5.50.1" + checksum: 10c0/0d5264db46783d648246406349fe88dbc6fa1cdd74ed16500bb8a4e5efb1bdfd7174780065566fcb7317f7ba8ac858677ffb0d5194a1315c0ce6003bd4219d87 + languageName: node + linkType: hard + +"@algolia/monitoring@npm:1.50.1": + version: 1.50.1 + resolution: "@algolia/monitoring@npm:1.50.1" + dependencies: + "@algolia/client-common": "npm:5.50.1" + "@algolia/requester-browser-xhr": "npm:5.50.1" + "@algolia/requester-fetch": "npm:5.50.1" + "@algolia/requester-node-http": "npm:5.50.1" + checksum: 10c0/378076310011c77c91378a597d86d791d4821d1d00e3c500ec8828e72b9036bb974abb09bd0c10aa05fc75a50aa443be26985104ca78524a0a0cf34707536c70 + languageName: node + linkType: hard + +"@algolia/recommend@npm:5.50.1": + version: 5.50.1 + resolution: "@algolia/recommend@npm:5.50.1" + dependencies: + "@algolia/client-common": "npm:5.50.1" + "@algolia/requester-browser-xhr": "npm:5.50.1" + "@algolia/requester-fetch": "npm:5.50.1" + "@algolia/requester-node-http": "npm:5.50.1" + checksum: 10c0/0cf061bf2fc46240d93c6fe032693e143a5eb61a3fc27f619141ebea735b7e7f6c5c38b31b152e9ef074b61373549a1f72a76399d80ed55840251cc71438f829 + languageName: node + linkType: hard + +"@algolia/requester-browser-xhr@npm:5.50.1": + version: 5.50.1 + resolution: "@algolia/requester-browser-xhr@npm:5.50.1" + dependencies: + "@algolia/client-common": "npm:5.50.1" + checksum: 10c0/aa55122f483a0d1572da20b71b0b533493960894460ad545a6a50e1c73780affd4764d68aa5a1687894d23c31a972cc92886a0d8ed3324b6f5457efd58b424af + languageName: node + linkType: hard + +"@algolia/requester-fetch@npm:5.50.1": + version: 5.50.1 + resolution: "@algolia/requester-fetch@npm:5.50.1" + dependencies: + "@algolia/client-common": "npm:5.50.1" + checksum: 10c0/07232c12ff0a5b25e5e6dfeeed8e46765f347926f263774e9ae061e65bd1ddce029f78fd5feaa34e23c80e80b0a84874d8799f817368e924cc904aef4f8f8181 + languageName: node + linkType: hard + +"@algolia/requester-node-http@npm:5.50.1": + version: 5.50.1 + resolution: "@algolia/requester-node-http@npm:5.50.1" + dependencies: + "@algolia/client-common": "npm:5.50.1" + checksum: 10c0/51be1452a28d4aeb97306121d164a3161fb55b775189df631f968bc752e00538a9872d0e0a2ad97744f8ca87c39f8352b526b8b290805ddaf5a2d4f43ae3360f + languageName: node + linkType: hard + "@asamuzakjp/css-color@npm:^3.2.0": version: 3.2.0 resolution: "@asamuzakjp/css-color@npm:3.2.0" @@ -60,33 +214,44 @@ __metadata: languageName: node linkType: hard -"@babel/compat-data@npm:^7.28.6": - version: 7.29.0 - resolution: "@babel/compat-data@npm:7.29.0" - checksum: 10c0/08f348554989d23aa801bf1405aa34b15e841c0d52d79da7e524285c77a5f9d298e70e11d91cc578d8e2c9542efc586d50c5f5cf8e1915b254a9dcf786913a94 +"@babel/code-frame@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/code-frame@npm:7.27.1" + dependencies: + "@babel/helper-validator-identifier": "npm:^7.27.1" + js-tokens: "npm:^4.0.0" + picocolors: "npm:^1.1.1" + checksum: 10c0/5dd9a18baa5fce4741ba729acc3a3272c49c25cb8736c4b18e113099520e7ef7b545a4096a26d600e4416157e63e87d66db46aa3fbf0a5f2286da2705c12da00 + languageName: node + linkType: hard + +"@babel/compat-data@npm:^7.27.2": + version: 7.28.5 + resolution: "@babel/compat-data@npm:7.28.5" + checksum: 10c0/702a25de73087b0eba325c1d10979eed7c9b6662677386ba7b5aa6eace0fc0676f78343bae080a0176ae26f58bd5535d73b9d0fbb547fef377692e8b249353a7 languageName: node linkType: hard "@babel/core@npm:^7.23.7, @babel/core@npm:^7.27.7": - version: 7.29.0 - resolution: "@babel/core@npm:7.29.0" - dependencies: - "@babel/code-frame": "npm:^7.29.0" - "@babel/generator": "npm:^7.29.0" - "@babel/helper-compilation-targets": "npm:^7.28.6" - "@babel/helper-module-transforms": "npm:^7.28.6" - "@babel/helpers": "npm:^7.28.6" - "@babel/parser": "npm:^7.29.0" - "@babel/template": "npm:^7.28.6" - "@babel/traverse": "npm:^7.29.0" - "@babel/types": "npm:^7.29.0" + version: 7.28.5 + resolution: "@babel/core@npm:7.28.5" + dependencies: + "@babel/code-frame": "npm:^7.27.1" + "@babel/generator": "npm:^7.28.5" + "@babel/helper-compilation-targets": "npm:^7.27.2" + "@babel/helper-module-transforms": "npm:^7.28.3" + "@babel/helpers": "npm:^7.28.4" + "@babel/parser": "npm:^7.28.5" + "@babel/template": "npm:^7.27.2" + "@babel/traverse": "npm:^7.28.5" + "@babel/types": "npm:^7.28.5" "@jridgewell/remapping": "npm:^2.3.5" convert-source-map: "npm:^2.0.0" debug: "npm:^4.1.0" gensync: "npm:^1.0.0-beta.2" json5: "npm:^2.2.3" semver: "npm:^6.3.1" - checksum: 10c0/5127d2e8e842ae409e11bcbb5c2dff9874abf5415e8026925af7308e903f4f43397341467a130490d1a39884f461bc2b67f3063bce0be44340db89687fd852aa + checksum: 10c0/535f82238027621da6bdffbdbe896ebad3558b311d6f8abc680637a9859b96edbf929ab010757055381570b29cf66c4a295b5618318d27a4273c0e2033925e72 languageName: node linkType: hard @@ -103,6 +268,19 @@ __metadata: languageName: node linkType: hard +"@babel/generator@npm:^7.28.5": + version: 7.28.5 + resolution: "@babel/generator@npm:7.28.5" + dependencies: + "@babel/parser": "npm:^7.28.5" + "@babel/types": "npm:^7.28.5" + "@jridgewell/gen-mapping": "npm:^0.3.12" + "@jridgewell/trace-mapping": "npm:^0.3.28" + jsesc: "npm:^3.0.2" + checksum: 10c0/9f219fe1d5431b6919f1a5c60db8d5d34fe546c0d8f5a8511b32f847569234ffc8032beb9e7404649a143f54e15224ecb53a3d11b6bb85c3203e573d91fca752 + languageName: node + linkType: hard + "@babel/helper-annotate-as-pure@npm:^7.27.3": version: 7.27.3 resolution: "@babel/helper-annotate-as-pure@npm:7.27.3" @@ -112,33 +290,33 @@ __metadata: languageName: node linkType: hard -"@babel/helper-compilation-targets@npm:^7.28.6": - version: 7.28.6 - resolution: "@babel/helper-compilation-targets@npm:7.28.6" +"@babel/helper-compilation-targets@npm:^7.27.2": + version: 7.27.2 + resolution: "@babel/helper-compilation-targets@npm:7.27.2" dependencies: - "@babel/compat-data": "npm:^7.28.6" + "@babel/compat-data": "npm:^7.27.2" "@babel/helper-validator-option": "npm:^7.27.1" browserslist: "npm:^4.24.0" lru-cache: "npm:^5.1.1" semver: "npm:^6.3.1" - checksum: 10c0/3fcdf3b1b857a1578e99d20508859dbd3f22f3c87b8a0f3dc540627b4be539bae7f6e61e49d931542fe5b557545347272bbdacd7f58a5c77025a18b745593a50 + checksum: 10c0/f338fa00dcfea931804a7c55d1a1c81b6f0a09787e528ec580d5c21b3ecb3913f6cb0f361368973ce953b824d910d3ac3e8a8ee15192710d3563826447193ad1 languageName: node linkType: hard -"@babel/helper-create-class-features-plugin@npm:^7.28.6": - version: 7.28.6 - resolution: "@babel/helper-create-class-features-plugin@npm:7.28.6" +"@babel/helper-create-class-features-plugin@npm:^7.28.5": + version: 7.28.5 + resolution: "@babel/helper-create-class-features-plugin@npm:7.28.5" dependencies: "@babel/helper-annotate-as-pure": "npm:^7.27.3" "@babel/helper-member-expression-to-functions": "npm:^7.28.5" "@babel/helper-optimise-call-expression": "npm:^7.27.1" - "@babel/helper-replace-supers": "npm:^7.28.6" + "@babel/helper-replace-supers": "npm:^7.27.1" "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.27.1" - "@babel/traverse": "npm:^7.28.6" + "@babel/traverse": "npm:^7.28.5" semver: "npm:^6.3.1" peerDependencies: "@babel/core": ^7.0.0 - checksum: 10c0/0b62b46717891f4366006b88c9b7f277980d4f578c4c3789b7a4f5a2e09e121de4cda9a414ab403986745cd3ad1af3fe2d948c9f78ab80d4dc085afc9602af50 + checksum: 10c0/786a6514efcf4514aaad85beed419b9184d059f4c9a9a95108f320142764999827252a851f7071de19f29424d369616573ecbaa347f1ce23fb12fc6827d9ff56 languageName: node linkType: hard @@ -149,7 +327,7 @@ __metadata: languageName: node linkType: hard -"@babel/helper-member-expression-to-functions@npm:^7.28.5": +"@babel/helper-member-expression-to-functions@npm:^7.27.1, @babel/helper-member-expression-to-functions@npm:^7.28.5": version: 7.28.5 resolution: "@babel/helper-member-expression-to-functions@npm:7.28.5" dependencies: @@ -159,26 +337,26 @@ __metadata: languageName: node linkType: hard -"@babel/helper-module-imports@npm:^7.28.6": - version: 7.28.6 - resolution: "@babel/helper-module-imports@npm:7.28.6" +"@babel/helper-module-imports@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/helper-module-imports@npm:7.27.1" dependencies: - "@babel/traverse": "npm:^7.28.6" - "@babel/types": "npm:^7.28.6" - checksum: 10c0/b49d8d8f204d9dbfd5ac70c54e533e5269afb3cea966a9d976722b13e9922cc773a653405f53c89acb247d5aebdae4681d631a3ae3df77ec046b58da76eda2ac + "@babel/traverse": "npm:^7.27.1" + "@babel/types": "npm:^7.27.1" + checksum: 10c0/e00aace096e4e29290ff8648455c2bc4ed982f0d61dbf2db1b5e750b9b98f318bf5788d75a4f974c151bd318fd549e81dbcab595f46b14b81c12eda3023f51e8 languageName: node linkType: hard -"@babel/helper-module-transforms@npm:^7.28.6": - version: 7.28.6 - resolution: "@babel/helper-module-transforms@npm:7.28.6" +"@babel/helper-module-transforms@npm:^7.27.1, @babel/helper-module-transforms@npm:^7.28.3": + version: 7.28.3 + resolution: "@babel/helper-module-transforms@npm:7.28.3" dependencies: - "@babel/helper-module-imports": "npm:^7.28.6" - "@babel/helper-validator-identifier": "npm:^7.28.5" - "@babel/traverse": "npm:^7.28.6" + "@babel/helper-module-imports": "npm:^7.27.1" + "@babel/helper-validator-identifier": "npm:^7.27.1" + "@babel/traverse": "npm:^7.28.3" peerDependencies: "@babel/core": ^7.0.0 - checksum: 10c0/6f03e14fc30b287ce0b839474b5f271e72837d0cafe6b172d759184d998fbee3903a035e81e07c2c596449e504f453463d58baa65b6f40a37ded5bec74620b2b + checksum: 10c0/549be62515a6d50cd4cfefcab1b005c47f89bd9135a22d602ee6a5e3a01f27571868ada10b75b033569f24dc4a2bb8d04bfa05ee75c16da7ade2d0db1437fcdb languageName: node linkType: hard @@ -191,23 +369,23 @@ __metadata: languageName: node linkType: hard -"@babel/helper-plugin-utils@npm:^7.27.1, @babel/helper-plugin-utils@npm:^7.28.6": +"@babel/helper-plugin-utils@npm:^7.27.1": version: 7.28.6 resolution: "@babel/helper-plugin-utils@npm:7.28.6" checksum: 10c0/3f5f8acc152fdbb69a84b8624145ff4f9b9f6e776cb989f9f968f8606eb7185c5c3cfcf3ba08534e37e1e0e1c118ac67080610333f56baa4f7376c99b5f1143d languageName: node linkType: hard -"@babel/helper-replace-supers@npm:^7.28.6": - version: 7.28.6 - resolution: "@babel/helper-replace-supers@npm:7.28.6" +"@babel/helper-replace-supers@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/helper-replace-supers@npm:7.27.1" dependencies: - "@babel/helper-member-expression-to-functions": "npm:^7.28.5" + "@babel/helper-member-expression-to-functions": "npm:^7.27.1" "@babel/helper-optimise-call-expression": "npm:^7.27.1" - "@babel/traverse": "npm:^7.28.6" + "@babel/traverse": "npm:^7.27.1" peerDependencies: "@babel/core": ^7.0.0 - checksum: 10c0/04663c6389551b99b8c3e7ba4e2638b8ca2a156418c26771516124c53083aa8e74b6a45abe5dd46360af79709a0e9c6b72c076d0eab9efecdd5aaf836e79d8d5 + checksum: 10c0/4f2eaaf5fcc196580221a7ccd0f8873447b5d52745ad4096418f6101a1d2e712e9f93722c9a32bc9769a1dc197e001f60d6f5438d4dfde4b9c6a9e4df719354c languageName: node linkType: hard @@ -228,7 +406,7 @@ __metadata: languageName: node linkType: hard -"@babel/helper-validator-identifier@npm:^7.28.5": +"@babel/helper-validator-identifier@npm:^7.27.1, @babel/helper-validator-identifier@npm:^7.28.5": version: 7.28.5 resolution: "@babel/helper-validator-identifier@npm:7.28.5" checksum: 10c0/42aaebed91f739a41f3d80b72752d1f95fd7c72394e8e4bd7cdd88817e0774d80a432451bcba17c2c642c257c483bf1d409dd4548883429ea9493a3bc4ab0847 @@ -242,13 +420,13 @@ __metadata: languageName: node linkType: hard -"@babel/helpers@npm:^7.28.6": - version: 7.29.2 - resolution: "@babel/helpers@npm:7.29.2" +"@babel/helpers@npm:^7.28.4": + version: 7.28.4 + resolution: "@babel/helpers@npm:7.28.4" dependencies: - "@babel/template": "npm:^7.28.6" - "@babel/types": "npm:^7.29.0" - checksum: 10c0/dab0e65b9318b2502a62c58bc0913572318595eec0482c31f0ad416b72636e6698a1d7c57cd2791d4528eb8c548bca88d338dc4d2a55a108dc1f6702f9bc5512 + "@babel/template": "npm:^7.27.2" + "@babel/types": "npm:^7.28.4" + checksum: 10c0/aaa5fb8098926dfed5f223adf2c5e4c7fbba4b911b73dfec2d7d3083f8ba694d201a206db673da2d9b3ae8c01793e795767654558c450c8c14b4c2175b4fcb44 languageName: node linkType: hard @@ -263,52 +441,63 @@ __metadata: languageName: node linkType: hard +"@babel/parser@npm:^7.27.2, @babel/parser@npm:^7.28.5": + version: 7.28.5 + resolution: "@babel/parser@npm:7.28.5" + dependencies: + "@babel/types": "npm:^7.28.5" + bin: + parser: ./bin/babel-parser.js + checksum: 10c0/5bbe48bf2c79594ac02b490a41ffde7ef5aa22a9a88ad6bcc78432a6ba8a9d638d531d868bd1f104633f1f6bba9905746e15185b8276a3756c42b765d131b1ef + languageName: node + linkType: hard + "@babel/plugin-syntax-jsx@npm:^7.27.1": - version: 7.28.6 - resolution: "@babel/plugin-syntax-jsx@npm:7.28.6" + version: 7.27.1 + resolution: "@babel/plugin-syntax-jsx@npm:7.27.1" dependencies: - "@babel/helper-plugin-utils": "npm:^7.28.6" + "@babel/helper-plugin-utils": "npm:^7.27.1" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/b98fc3cd75e4ca3d5ca1162f610c286e14ede1486e0d297c13a5eb0ac85680ac9656d17d348bddd9160a54d797a08cea5eaac02b9330ddebb7b26732b7b99fb5 + checksum: 10c0/bc5afe6a458d5f0492c02a54ad98c5756a0c13bd6d20609aae65acd560a9e141b0876da5f358dce34ea136f271c1016df58b461184d7ae9c4321e0f98588bc84 languageName: node linkType: hard -"@babel/plugin-syntax-typescript@npm:^7.28.6": - version: 7.28.6 - resolution: "@babel/plugin-syntax-typescript@npm:7.28.6" +"@babel/plugin-syntax-typescript@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-syntax-typescript@npm:7.27.1" dependencies: - "@babel/helper-plugin-utils": "npm:^7.28.6" + "@babel/helper-plugin-utils": "npm:^7.27.1" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/b0c392a35624883ac480277401ac7d92d8646b66e33639f5d350de7a6723924265985ae11ab9ebd551740ded261c443eaa9a87ea19def9763ca1e0d78c97dea8 + checksum: 10c0/11589b4c89c66ef02d57bf56c6246267851ec0c361f58929327dc3e070b0dab644be625bbe7fb4c4df30c3634bfdfe31244e1f517be397d2def1487dbbe3c37d languageName: node linkType: hard "@babel/plugin-transform-modules-commonjs@npm:^7.27.1": - version: 7.28.6 - resolution: "@babel/plugin-transform-modules-commonjs@npm:7.28.6" + version: 7.27.1 + resolution: "@babel/plugin-transform-modules-commonjs@npm:7.27.1" dependencies: - "@babel/helper-module-transforms": "npm:^7.28.6" - "@babel/helper-plugin-utils": "npm:^7.28.6" + "@babel/helper-module-transforms": "npm:^7.27.1" + "@babel/helper-plugin-utils": "npm:^7.27.1" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/7c45992797c6150644c8552feff4a016ba7bd6d59ff2b039ed969a9c5b20a6804cd9d21db5045fc8cca8ca7f08262497e354e93f8f2be6a1cdf3fbfa8c31a9b6 + checksum: 10c0/4def972dcd23375a266ea1189115a4ff61744b2c9366fc1de648b3fab2c650faf1a94092de93a33ff18858d2e6c4dddeeee5384cb42ba0129baeab01a5cdf1e2 languageName: node linkType: hard "@babel/plugin-transform-typescript@npm:^7.28.5": - version: 7.28.6 - resolution: "@babel/plugin-transform-typescript@npm:7.28.6" + version: 7.28.5 + resolution: "@babel/plugin-transform-typescript@npm:7.28.5" dependencies: "@babel/helper-annotate-as-pure": "npm:^7.27.3" - "@babel/helper-create-class-features-plugin": "npm:^7.28.6" - "@babel/helper-plugin-utils": "npm:^7.28.6" + "@babel/helper-create-class-features-plugin": "npm:^7.28.5" + "@babel/helper-plugin-utils": "npm:^7.27.1" "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.27.1" - "@babel/plugin-syntax-typescript": "npm:^7.28.6" + "@babel/plugin-syntax-typescript": "npm:^7.27.1" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/72dbfd3e5f71c4e30445e610758ec0eef65347fafd72bd46f4903733df0d537663a72a81c1626f213a0feab7afc68ba83f1648ffece888dd0868115c9cb748f6 + checksum: 10c0/09e574ba5462e56452b4ceecae65e53c8e697a2d3559ce5d210bed10ac28a18aa69377e7550c30520eb29b40c417ee61997d5d58112657f22983244b78915a7c languageName: node linkType: hard @@ -327,6 +516,17 @@ __metadata: languageName: node linkType: hard +"@babel/template@npm:^7.27.2": + version: 7.27.2 + resolution: "@babel/template@npm:7.27.2" + dependencies: + "@babel/code-frame": "npm:^7.27.1" + "@babel/parser": "npm:^7.27.2" + "@babel/types": "npm:^7.27.1" + checksum: 10c0/ed9e9022651e463cc5f2cc21942f0e74544f1754d231add6348ff1b472985a3b3502041c0be62dc99ed2d12cfae0c51394bf827452b98a2f8769c03b87aadc81 + languageName: node + linkType: hard + "@babel/template@npm:^7.28.6": version: 7.28.6 resolution: "@babel/template@npm:7.28.6" @@ -338,7 +538,7 @@ __metadata: languageName: node linkType: hard -"@babel/traverse@npm:^7.23.7, @babel/traverse@npm:^7.27.1, @babel/traverse@npm:^7.27.7, @babel/traverse@npm:^7.28.5, @babel/traverse@npm:^7.28.6, @babel/traverse@npm:^7.29.0": +"@babel/traverse@npm:^7.23.7, @babel/traverse@npm:^7.27.1, @babel/traverse@npm:^7.27.7, @babel/traverse@npm:^7.28.5, @babel/traverse@npm:^7.29.0": version: 7.29.0 resolution: "@babel/traverse@npm:7.29.0" dependencies: @@ -353,6 +553,21 @@ __metadata: languageName: node linkType: hard +"@babel/traverse@npm:^7.28.3": + version: 7.28.5 + resolution: "@babel/traverse@npm:7.28.5" + dependencies: + "@babel/code-frame": "npm:^7.27.1" + "@babel/generator": "npm:^7.28.5" + "@babel/helper-globals": "npm:^7.28.0" + "@babel/parser": "npm:^7.28.5" + "@babel/template": "npm:^7.27.2" + "@babel/types": "npm:^7.28.5" + debug: "npm:^4.3.1" + checksum: 10c0/f6c4a595993ae2b73f2d4cd9c062f2e232174d293edd4abe1d715bd6281da8d99e47c65857e8d0917d9384c65972f4acdebc6749a7c40a8fcc38b3c7fb3e706f + languageName: node + linkType: hard + "@babel/types@npm:^7.23.6, @babel/types@npm:^7.27.1, @babel/types@npm:^7.27.3, @babel/types@npm:^7.27.7, @babel/types@npm:^7.28.5, @babel/types@npm:^7.28.6, @babel/types@npm:^7.29.0": version: 7.29.0 resolution: "@babel/types@npm:7.29.0" @@ -363,6 +578,16 @@ __metadata: languageName: node linkType: hard +"@babel/types@npm:^7.28.4": + version: 7.28.5 + resolution: "@babel/types@npm:7.28.5" + dependencies: + "@babel/helper-string-parser": "npm:^7.27.1" + "@babel/helper-validator-identifier": "npm:^7.28.5" + checksum: 10c0/a5a483d2100befbf125793640dec26b90b95fd233a94c19573325898a5ce1e52cdfa96e495c7dcc31b5eca5b66ce3e6d4a0f5a4a62daec271455959f208ab08a + languageName: node + linkType: hard + "@blazediff/core@npm:1.9.1": version: 1.9.1 resolution: "@blazediff/core@npm:1.9.1" @@ -433,14 +658,14 @@ __metadata: linkType: hard "@codemirror/autocomplete@npm:^6.0.0": - version: 6.20.1 - resolution: "@codemirror/autocomplete@npm:6.20.1" + version: 6.20.0 + resolution: "@codemirror/autocomplete@npm:6.20.0" dependencies: "@codemirror/language": "npm:^6.0.0" "@codemirror/state": "npm:^6.0.0" "@codemirror/view": "npm:^6.17.0" "@lezer/common": "npm:^1.0.0" - checksum: 10c0/ec3ecdd8098778c0764827ffcb6252edc763de3500314ad6b36d77bd09f73c03cb9a95b952b2b928354e1c83f2ae1bfef92b406eae40f94b47104b51bd508b35 + checksum: 10c0/d0d1cf3eca6269811eb66edcf742ffa0a5423d7d115ab82b0d62a24d6cfcfb2a4c3779333b2cb68e3004af46556ac6203049f581d35785c46ffd1b852f6e8076 languageName: node linkType: hard @@ -471,7 +696,21 @@ __metadata: languageName: node linkType: hard -"@codemirror/language@npm:^6.0.0, @codemirror/language@npm:^6.12.3, @codemirror/language@npm:^6.6.0": +"@codemirror/language@npm:^6.0.0, @codemirror/language@npm:^6.6.0": + version: 6.11.3 + resolution: "@codemirror/language@npm:6.11.3" + dependencies: + "@codemirror/state": "npm:^6.0.0" + "@codemirror/view": "npm:^6.23.0" + "@lezer/common": "npm:^1.1.0" + "@lezer/highlight": "npm:^1.0.0" + "@lezer/lr": "npm:^1.0.0" + style-mod: "npm:^4.0.0" + checksum: 10c0/0cbc2a98bd9e94e8e186af30613741a553fc45479e3875c79bddc32340d4d75ecc36229c66e2ee5fcffbc8fdd49b442e43847799d1d68651e3b4f8ec20d3d092 + languageName: node + linkType: hard + +"@codemirror/language@npm:^6.12.3": version: 6.12.3 resolution: "@codemirror/language@npm:6.12.3" dependencies: @@ -695,7 +934,7 @@ __metadata: languageName: node linkType: hard -"@emnapi/wasi-threads@npm:1.2.1, @emnapi/wasi-threads@npm:^1.1.0": +"@emnapi/wasi-threads@npm:1.2.1": version: 1.2.1 resolution: "@emnapi/wasi-threads@npm:1.2.1" dependencies: @@ -704,6 +943,22 @@ __metadata: languageName: node linkType: hard +"@emnapi/wasi-threads@npm:^1.1.0": + version: 1.1.0 + resolution: "@emnapi/wasi-threads@npm:1.1.0" + dependencies: + tslib: "npm:^2.4.0" + checksum: 10c0/e6d54bf2b1e64cdd83d2916411e44e579b6ae35d5def0dea61a3c452d9921373044dff32a8b8473ae60c80692bdc39323e98b96a3f3d87ba6886b24dd0ef7ca1 + languageName: node + linkType: hard + +"@esbuild/aix-ppc64@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/aix-ppc64@npm:0.25.12" + conditions: os=aix & cpu=ppc64 + languageName: node + linkType: hard + "@esbuild/aix-ppc64@npm:0.27.3": version: 0.27.3 resolution: "@esbuild/aix-ppc64@npm:0.27.3" @@ -711,10 +966,10 @@ __metadata: languageName: node linkType: hard -"@esbuild/aix-ppc64@npm:0.27.7": - version: 0.27.7 - resolution: "@esbuild/aix-ppc64@npm:0.27.7" - conditions: os=aix & cpu=ppc64 +"@esbuild/android-arm64@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/android-arm64@npm:0.25.12" + conditions: os=android & cpu=arm64 languageName: node linkType: hard @@ -725,10 +980,10 @@ __metadata: languageName: node linkType: hard -"@esbuild/android-arm64@npm:0.27.7": - version: 0.27.7 - resolution: "@esbuild/android-arm64@npm:0.27.7" - conditions: os=android & cpu=arm64 +"@esbuild/android-arm@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/android-arm@npm:0.25.12" + conditions: os=android & cpu=arm languageName: node linkType: hard @@ -739,10 +994,10 @@ __metadata: languageName: node linkType: hard -"@esbuild/android-arm@npm:0.27.7": - version: 0.27.7 - resolution: "@esbuild/android-arm@npm:0.27.7" - conditions: os=android & cpu=arm +"@esbuild/android-x64@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/android-x64@npm:0.25.12" + conditions: os=android & cpu=x64 languageName: node linkType: hard @@ -753,10 +1008,10 @@ __metadata: languageName: node linkType: hard -"@esbuild/android-x64@npm:0.27.7": - version: 0.27.7 - resolution: "@esbuild/android-x64@npm:0.27.7" - conditions: os=android & cpu=x64 +"@esbuild/darwin-arm64@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/darwin-arm64@npm:0.25.12" + conditions: os=darwin & cpu=arm64 languageName: node linkType: hard @@ -767,10 +1022,10 @@ __metadata: languageName: node linkType: hard -"@esbuild/darwin-arm64@npm:0.27.7": - version: 0.27.7 - resolution: "@esbuild/darwin-arm64@npm:0.27.7" - conditions: os=darwin & cpu=arm64 +"@esbuild/darwin-x64@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/darwin-x64@npm:0.25.12" + conditions: os=darwin & cpu=x64 languageName: node linkType: hard @@ -781,10 +1036,10 @@ __metadata: languageName: node linkType: hard -"@esbuild/darwin-x64@npm:0.27.7": - version: 0.27.7 - resolution: "@esbuild/darwin-x64@npm:0.27.7" - conditions: os=darwin & cpu=x64 +"@esbuild/freebsd-arm64@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/freebsd-arm64@npm:0.25.12" + conditions: os=freebsd & cpu=arm64 languageName: node linkType: hard @@ -795,10 +1050,10 @@ __metadata: languageName: node linkType: hard -"@esbuild/freebsd-arm64@npm:0.27.7": - version: 0.27.7 - resolution: "@esbuild/freebsd-arm64@npm:0.27.7" - conditions: os=freebsd & cpu=arm64 +"@esbuild/freebsd-x64@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/freebsd-x64@npm:0.25.12" + conditions: os=freebsd & cpu=x64 languageName: node linkType: hard @@ -809,10 +1064,10 @@ __metadata: languageName: node linkType: hard -"@esbuild/freebsd-x64@npm:0.27.7": - version: 0.27.7 - resolution: "@esbuild/freebsd-x64@npm:0.27.7" - conditions: os=freebsd & cpu=x64 +"@esbuild/linux-arm64@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/linux-arm64@npm:0.25.12" + conditions: os=linux & cpu=arm64 languageName: node linkType: hard @@ -823,10 +1078,10 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-arm64@npm:0.27.7": - version: 0.27.7 - resolution: "@esbuild/linux-arm64@npm:0.27.7" - conditions: os=linux & cpu=arm64 +"@esbuild/linux-arm@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/linux-arm@npm:0.25.12" + conditions: os=linux & cpu=arm languageName: node linkType: hard @@ -837,10 +1092,10 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-arm@npm:0.27.7": - version: 0.27.7 - resolution: "@esbuild/linux-arm@npm:0.27.7" - conditions: os=linux & cpu=arm +"@esbuild/linux-ia32@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/linux-ia32@npm:0.25.12" + conditions: os=linux & cpu=ia32 languageName: node linkType: hard @@ -851,10 +1106,10 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-ia32@npm:0.27.7": - version: 0.27.7 - resolution: "@esbuild/linux-ia32@npm:0.27.7" - conditions: os=linux & cpu=ia32 +"@esbuild/linux-loong64@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/linux-loong64@npm:0.25.12" + conditions: os=linux & cpu=loong64 languageName: node linkType: hard @@ -865,10 +1120,10 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-loong64@npm:0.27.7": - version: 0.27.7 - resolution: "@esbuild/linux-loong64@npm:0.27.7" - conditions: os=linux & cpu=loong64 +"@esbuild/linux-mips64el@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/linux-mips64el@npm:0.25.12" + conditions: os=linux & cpu=mips64el languageName: node linkType: hard @@ -879,10 +1134,10 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-mips64el@npm:0.27.7": - version: 0.27.7 - resolution: "@esbuild/linux-mips64el@npm:0.27.7" - conditions: os=linux & cpu=mips64el +"@esbuild/linux-ppc64@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/linux-ppc64@npm:0.25.12" + conditions: os=linux & cpu=ppc64 languageName: node linkType: hard @@ -893,10 +1148,10 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-ppc64@npm:0.27.7": - version: 0.27.7 - resolution: "@esbuild/linux-ppc64@npm:0.27.7" - conditions: os=linux & cpu=ppc64 +"@esbuild/linux-riscv64@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/linux-riscv64@npm:0.25.12" + conditions: os=linux & cpu=riscv64 languageName: node linkType: hard @@ -907,10 +1162,10 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-riscv64@npm:0.27.7": - version: 0.27.7 - resolution: "@esbuild/linux-riscv64@npm:0.27.7" - conditions: os=linux & cpu=riscv64 +"@esbuild/linux-s390x@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/linux-s390x@npm:0.25.12" + conditions: os=linux & cpu=s390x languageName: node linkType: hard @@ -921,10 +1176,10 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-s390x@npm:0.27.7": - version: 0.27.7 - resolution: "@esbuild/linux-s390x@npm:0.27.7" - conditions: os=linux & cpu=s390x +"@esbuild/linux-x64@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/linux-x64@npm:0.25.12" + conditions: os=linux & cpu=x64 languageName: node linkType: hard @@ -935,10 +1190,10 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-x64@npm:0.27.7": - version: 0.27.7 - resolution: "@esbuild/linux-x64@npm:0.27.7" - conditions: os=linux & cpu=x64 +"@esbuild/netbsd-arm64@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/netbsd-arm64@npm:0.25.12" + conditions: os=netbsd & cpu=arm64 languageName: node linkType: hard @@ -949,10 +1204,10 @@ __metadata: languageName: node linkType: hard -"@esbuild/netbsd-arm64@npm:0.27.7": - version: 0.27.7 - resolution: "@esbuild/netbsd-arm64@npm:0.27.7" - conditions: os=netbsd & cpu=arm64 +"@esbuild/netbsd-x64@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/netbsd-x64@npm:0.25.12" + conditions: os=netbsd & cpu=x64 languageName: node linkType: hard @@ -963,10 +1218,10 @@ __metadata: languageName: node linkType: hard -"@esbuild/netbsd-x64@npm:0.27.7": - version: 0.27.7 - resolution: "@esbuild/netbsd-x64@npm:0.27.7" - conditions: os=netbsd & cpu=x64 +"@esbuild/openbsd-arm64@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/openbsd-arm64@npm:0.25.12" + conditions: os=openbsd & cpu=arm64 languageName: node linkType: hard @@ -977,10 +1232,10 @@ __metadata: languageName: node linkType: hard -"@esbuild/openbsd-arm64@npm:0.27.7": - version: 0.27.7 - resolution: "@esbuild/openbsd-arm64@npm:0.27.7" - conditions: os=openbsd & cpu=arm64 +"@esbuild/openbsd-x64@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/openbsd-x64@npm:0.25.12" + conditions: os=openbsd & cpu=x64 languageName: node linkType: hard @@ -991,10 +1246,10 @@ __metadata: languageName: node linkType: hard -"@esbuild/openbsd-x64@npm:0.27.7": - version: 0.27.7 - resolution: "@esbuild/openbsd-x64@npm:0.27.7" - conditions: os=openbsd & cpu=x64 +"@esbuild/openharmony-arm64@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/openharmony-arm64@npm:0.25.12" + conditions: os=openharmony & cpu=arm64 languageName: node linkType: hard @@ -1005,10 +1260,10 @@ __metadata: languageName: node linkType: hard -"@esbuild/openharmony-arm64@npm:0.27.7": - version: 0.27.7 - resolution: "@esbuild/openharmony-arm64@npm:0.27.7" - conditions: os=openharmony & cpu=arm64 +"@esbuild/sunos-x64@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/sunos-x64@npm:0.25.12" + conditions: os=sunos & cpu=x64 languageName: node linkType: hard @@ -1019,10 +1274,10 @@ __metadata: languageName: node linkType: hard -"@esbuild/sunos-x64@npm:0.27.7": - version: 0.27.7 - resolution: "@esbuild/sunos-x64@npm:0.27.7" - conditions: os=sunos & cpu=x64 +"@esbuild/win32-arm64@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/win32-arm64@npm:0.25.12" + conditions: os=win32 & cpu=arm64 languageName: node linkType: hard @@ -1033,10 +1288,10 @@ __metadata: languageName: node linkType: hard -"@esbuild/win32-arm64@npm:0.27.7": - version: 0.27.7 - resolution: "@esbuild/win32-arm64@npm:0.27.7" - conditions: os=win32 & cpu=arm64 +"@esbuild/win32-ia32@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/win32-ia32@npm:0.25.12" + conditions: os=win32 & cpu=ia32 languageName: node linkType: hard @@ -1047,10 +1302,10 @@ __metadata: languageName: node linkType: hard -"@esbuild/win32-ia32@npm:0.27.7": - version: 0.27.7 - resolution: "@esbuild/win32-ia32@npm:0.27.7" - conditions: os=win32 & cpu=ia32 +"@esbuild/win32-x64@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/win32-x64@npm:0.25.12" + conditions: os=win32 & cpu=x64 languageName: node linkType: hard @@ -1061,13 +1316,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/win32-x64@npm:0.27.7": - version: 0.27.7 - resolution: "@esbuild/win32-x64@npm:0.27.7" - conditions: os=win32 & cpu=x64 - languageName: node - linkType: hard - "@fastify/accept-negotiator@npm:^2.0.0": version: 2.0.1 resolution: "@fastify/accept-negotiator@npm:2.0.1" @@ -1192,34 +1440,34 @@ __metadata: languageName: node linkType: hard -"@floating-ui/core@npm:^1.7.5": - version: 1.7.5 - resolution: "@floating-ui/core@npm:1.7.5" +"@floating-ui/core@npm:^1.7.3": + version: 1.7.3 + resolution: "@floating-ui/core@npm:1.7.3" dependencies: - "@floating-ui/utils": "npm:^0.2.11" - checksum: 10c0/f9c52205e198b231d63a387b09c659aab08c46a1899e0b0bbe147b8b4f048b546f15ba17cb5d2a471da9534f1883d979425e13e5c4ceee67be63e4b0abd4db5d + "@floating-ui/utils": "npm:^0.2.10" + checksum: 10c0/edfc23800122d81df0df0fb780b7328ae6c5f00efbb55bd48ea340f4af8c5b3b121ceb4bb81220966ab0f87b443204d37105abdd93d94846468be3243984144c languageName: node linkType: hard -"@floating-ui/dom@npm:^1.7.6": - version: 1.7.6 - resolution: "@floating-ui/dom@npm:1.7.6" +"@floating-ui/dom@npm:^1.7.4": + version: 1.7.4 + resolution: "@floating-ui/dom@npm:1.7.4" dependencies: - "@floating-ui/core": "npm:^1.7.5" - "@floating-ui/utils": "npm:^0.2.11" - checksum: 10c0/5c098e0d7b58c9bc769f276cca1766994c2c9c70c92d091a61bba8b3e9be53c011e0a79a8457fc2fb2f3d91697a26eb52e0a4962ef936dc963b45f58613c212f + "@floating-ui/core": "npm:^1.7.3" + "@floating-ui/utils": "npm:^0.2.10" + checksum: 10c0/da6166c25f9b0729caa9f498685a73a0e28251613b35d27db8de8014bc9d045158a23c092b405321a3d67c2064909b6e2a7e6c1c9cc0f62967dca5779f5aef30 languageName: node linkType: hard "@floating-ui/react-dom@npm:^2.1.2": - version: 2.1.8 - resolution: "@floating-ui/react-dom@npm:2.1.8" + version: 2.1.6 + resolution: "@floating-ui/react-dom@npm:2.1.6" dependencies: - "@floating-ui/dom": "npm:^1.7.6" + "@floating-ui/dom": "npm:^1.7.4" peerDependencies: react: ">=16.8.0" react-dom: ">=16.8.0" - checksum: 10c0/26260ca4bb23b57c73b824062505abf977a008ce6e0463bdacca74f7e49853c4cd1d2bbf1a77c6caa17fa37dfffda2c6c4cd07a8737ebd7474aaff7818401d75 + checksum: 10c0/6654834a8e73ecbdbc6cad2ad8f7abc698ac7c1800ded4d61113525c591c03d2e3b59d3cf9205859221465ea38c87af4f9e6e204703c5b7a7e85332d1eef2e18 languageName: node linkType: hard @@ -1237,17 +1485,17 @@ __metadata: languageName: node linkType: hard -"@floating-ui/utils@npm:^0.2.11, @floating-ui/utils@npm:^0.2.8": - version: 0.2.11 - resolution: "@floating-ui/utils@npm:0.2.11" - checksum: 10c0/f4bcea1559bdbb721ecc8e8ead423ac58d6a5b6e70b602cf0810ba6ad4ed1c77211b207faa88b278a9042f0c743133de08a203ed6741c1b6443423332884d5b3 +"@floating-ui/utils@npm:^0.2.10": + version: 0.2.10 + resolution: "@floating-ui/utils@npm:0.2.10" + checksum: 10c0/e9bc2a1730ede1ee25843937e911ab6e846a733a4488623cd353f94721b05ec2c9ec6437613a2ac9379a94c2fd40c797a2ba6fa1df2716f5ce4aa6ddb1cf9ea4 languageName: node linkType: hard -"@gar/promise-retry@npm:^1.0.0": - version: 1.0.3 - resolution: "@gar/promise-retry@npm:1.0.3" - checksum: 10c0/885b02c8b0d75b2d215da25f3b639158c4fbe8fefe0d79163304534b9a6d0710db4b7699f7cd3cc1a730792bff04cbe19f4850a62d3e105a663eaeec88f38332 +"@floating-ui/utils@npm:^0.2.8": + version: 0.2.11 + resolution: "@floating-ui/utils@npm:0.2.11" + checksum: 10c0/f4bcea1559bdbb721ecc8e8ead423ac58d6a5b6e70b602cf0810ba6ad4ed1c77211b207faa88b278a9042f0c743133de08a203ed6741c1b6443423332884d5b3 languageName: node linkType: hard @@ -1268,9 +1516,9 @@ __metadata: linkType: hard "@img/colour@npm:^1.0.0": - version: 1.1.0 - resolution: "@img/colour@npm:1.1.0" - checksum: 10c0/2ebea2c0bbaee73b99badcefa04e1e71d83f36e5369337d3121dca841f4569533c4e2faddda6d62dd247f0d5cca143711f9446c59bcce81e427ba433a7a94a17 + version: 1.0.0 + resolution: "@img/colour@npm:1.0.0" + checksum: 10c0/02261719c1e0d7aa5a2d585981954f2ac126f0c432400aa1a01b925aa2c41417b7695da8544ee04fd29eba7ecea8eaf9b8bef06f19dc8faba78f94eeac40667d languageName: node linkType: hard @@ -1494,6 +1742,22 @@ __metadata: languageName: node linkType: hard +"@isaacs/balanced-match@npm:^4.0.1": + version: 4.0.1 + resolution: "@isaacs/balanced-match@npm:4.0.1" + checksum: 10c0/7da011805b259ec5c955f01cee903da72ad97c5e6f01ca96197267d3f33103d5b2f8a1af192140f3aa64526c593c8d098ae366c2b11f7f17645d12387c2fd420 + languageName: node + linkType: hard + +"@isaacs/brace-expansion@npm:^5.0.0": + version: 5.0.1 + resolution: "@isaacs/brace-expansion@npm:5.0.1" + dependencies: + "@isaacs/balanced-match": "npm:^4.0.1" + checksum: 10c0/e5d67c7bbf1f17b88132a35bc638af306d48acbb72810d48fa6e6edd8ab375854773108e8bf70f021f7ef6a8273455a6d1f0c3b5aa2aff06ce7894049ab77fb8 + languageName: node + linkType: hard + "@isaacs/cliui@npm:^8.0.2": version: 8.0.2 resolution: "@isaacs/cliui@npm:8.0.2" @@ -1599,11 +1863,11 @@ __metadata: linkType: hard "@lezer/lr@npm:^1.0.0, @lezer/lr@npm:^1.3.0, @lezer/lr@npm:^1.4.2": - version: 1.4.8 - resolution: "@lezer/lr@npm:1.4.8" + version: 1.4.3 + resolution: "@lezer/lr@npm:1.4.3" dependencies: "@lezer/common": "npm:^1.0.0" - checksum: 10c0/8bd2228a316a5ef8da01908e3e22aca95fa9695211ffe56f3e8be756b37d0810d5aa91fbbdd274b198a343051d8637e130e26f51161161f089244af242b653c9 + checksum: 10c0/3c9fd7eefb0641addfdd0955b4c4014bb8702285c52890b58c937d766320ba2fec8c6b374b46f514079a093c9dd21b6632746a01fed16c250c90d649e5dd12c1 languageName: node linkType: hard @@ -1673,40 +1937,40 @@ __metadata: languageName: node linkType: hard -"@node-cli/logger@npm:1.3.7": - version: 1.3.7 - resolution: "@node-cli/logger@npm:1.3.7" +"@node-cli/logger@npm:1.3.6": + version: 1.3.6 + resolution: "@node-cli/logger@npm:1.3.6" dependencies: boxen: "npm:8.0.1" kleur: "npm:4.1.5" ora: "npm:9.3.0" - checksum: 10c0/54713e785cfc74c277719bf761b4064fa676ac6341724f6b180f96ba5e76d569d3de93e6f49fed7c290bc449642e9d894f92e817fc08d7670d791f5233c90d27 + checksum: 10c0/cf1249a56d1be97078b0b518d66fc3342e4a89bbf6c7a97f2a933f74e4227fb78eb1a2968318ddfd68160f70e1526f6afd8135f1ad394289b100476d729417c6 languageName: node linkType: hard -"@node-cli/parser@npm:2.4.8": - version: 2.4.8 - resolution: "@node-cli/parser@npm:2.4.8" +"@node-cli/parser@npm:2.4.7": + version: 2.4.7 + resolution: "@node-cli/parser@npm:2.4.7" dependencies: - "@node-cli/logger": "npm:1.3.7" - "@node-cli/utilities": "npm:1.0.8" + "@node-cli/logger": "npm:1.3.6" + "@node-cli/utilities": "npm:1.0.7" cli-table3: "npm:0.6.5" kleur: "npm:4.1.5" meow: "npm:14.1.0" - checksum: 10c0/eb843ac292fa4d3407bb30526f497f2cc05bd00ab87ee89f98d0c0eb2db987670bf9f59b368b9fba73d06b5931cb0417b464fa45ef09ce5567a1a3336c232153 + checksum: 10c0/25c3b16c5c33e23451bef60f41e5375fdef66dcb18cc200beb0b5f3f9b66f666c2d294aa2c1726879d1f23ec1c47030e10a1113cd66dd4bf3b476bdeee20cdd3 languageName: node linkType: hard "@node-cli/static-server@npm:^3.1.10": - version: 3.1.11 - resolution: "@node-cli/static-server@npm:3.1.11" + version: 3.1.10 + resolution: "@node-cli/static-server@npm:3.1.10" dependencies: "@fastify/caching": "npm:9.0.3" "@fastify/compress": "npm:8.3.1" "@fastify/cors": "npm:11.2.0" "@fastify/static": "npm:9.0.0" - "@node-cli/logger": "npm:1.3.7" - "@node-cli/parser": "npm:2.4.8" + "@node-cli/logger": "npm:1.3.6" + "@node-cli/parser": "npm:2.4.7" fastify: "npm:5.8.4" fastify-plugin: "npm:5.1.0" fs-extra: "npm:11.3.4" @@ -1716,16 +1980,16 @@ __metadata: portfinder: "npm:1.0.38" bin: static-server: dist/server.js - checksum: 10c0/9905bd99dd94a725ecd54d3943540e7ba014cc0ecebcf7fbe792ebe56a8bec1108f0b4404b6eac0ce2aab602095f23c7c70402b3260b2ff3f7a6b02982b24874 + checksum: 10c0/e12a839df99bfba1559828fb672694b79c41d6c471fb45e764e96e8344e8c647c3114087b67e81d104fbe5d3c2ab734ee3e36a9c2f1486965ecbc33d473abbc1 languageName: node linkType: hard -"@node-cli/utilities@npm:1.0.8": - version: 1.0.8 - resolution: "@node-cli/utilities@npm:1.0.8" +"@node-cli/utilities@npm:1.0.7": + version: 1.0.7 + resolution: "@node-cli/utilities@npm:1.0.7" dependencies: - lodash-es: "npm:4.18.1" - checksum: 10c0/48e3f6776db8839fa5778980304db01ec8ffe077c76126c89cec4113d32705a68c237f3dea227003133759f47f1b0cd458f88fd5e9f548d0adb4b23e6bd0d62c + lodash-es: "npm:4.17.23" + checksum: 10c0/547380450fc36614a260a30790dc91e5531b1d3bd72eaef7dfcdb0dd0b991b476c151fa4cafeeee8dc17e311e5847ebc4ec059922601858e8ad99d96210d40ad languageName: node linkType: hard @@ -1854,13 +2118,6 @@ __metadata: languageName: node linkType: hard -"@npmcli/redact@npm:^4.0.0": - version: 4.0.0 - resolution: "@npmcli/redact@npm:4.0.0" - checksum: 10c0/a1e9ba9c70a6b40e175bda2c3dd8cfdaf096e6b7f7a132c855c083c8dfe545c3237cd56702e2e6627a580b1d63373599d49a1192c4078a85bf47bbde824df31c - languageName: node - linkType: hard - "@oxc-project/types@npm:=0.122.0": version: 0.122.0 resolution: "@oxc-project/types@npm:0.122.0" @@ -2023,11 +2280,11 @@ __metadata: linkType: hard "@poppinss/colors@npm:^4.1.5": - version: 4.1.6 - resolution: "@poppinss/colors@npm:4.1.6" + version: 4.1.5 + resolution: "@poppinss/colors@npm:4.1.5" dependencies: kleur: "npm:^4.1.5" - checksum: 10c0/5c2cec5393e33294465873002f4c570adf36b5405b9f06551485162a6fb422d01de90ac20cb00800be6ab2f0d93da26e67302e95691dff2e0aa339cf93e5bf7f + checksum: 10c0/e9d5c9e9a8c1eb7cd37e9b431bda7b7573476be7395123b26815d758f38ca93db0ba62bb2831281f4f04a6e1620b4d4f9377268d32c61c2c9f6599a02c2112b7 languageName: node linkType: hard @@ -2043,29 +2300,29 @@ __metadata: linkType: hard "@poppinss/exception@npm:^1.2.2": - version: 1.2.3 - resolution: "@poppinss/exception@npm:1.2.3" - checksum: 10c0/44e48400c9f2d33a4904bee99321b89239774bb9210049f1c55864725fd524ff55bc78a5a94a13d5edea93b84e13023c229c88ebba8c2dc717fb4b2205e42ac7 + version: 1.2.2 + resolution: "@poppinss/exception@npm:1.2.2" + checksum: 10c0/b14d1e3d532230f58238231fce6ba3bf51dab50d4ec015f3192f04320be1d692eadd831a8d437e2fc345787c96350104149fd9920264362bca143d04ec03bc4e languageName: node linkType: hard "@react-aria/focus@npm:^3.20.2": - version: 3.21.5 - resolution: "@react-aria/focus@npm:3.21.5" + version: 3.21.2 + resolution: "@react-aria/focus@npm:3.21.2" dependencies: - "@react-aria/interactions": "npm:^3.27.1" - "@react-aria/utils": "npm:^3.33.1" - "@react-types/shared": "npm:^3.33.1" + "@react-aria/interactions": "npm:^3.25.6" + "@react-aria/utils": "npm:^3.31.0" + "@react-types/shared": "npm:^3.32.1" "@swc/helpers": "npm:^0.5.0" clsx: "npm:^2.0.0" peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 - checksum: 10c0/f14f3d2d14b11d1e70028c4040cae46f132a24594e9217d7041d63ebff4cf8bc5d7f07b029c97481f267a440cfd6e1521181484b665f2a410b76ee77ceb641bf + checksum: 10c0/bfcdbb8d47bf038c035b025df6b9c292eeea9a2af7c77ec2ac27c302cb64dc481cfe80bb6575b399301ad1516feba134dec01e3c112ca2cf912ca13b47965917 languageName: node linkType: hard -"@react-aria/interactions@npm:^3.25.0, @react-aria/interactions@npm:^3.27.1": +"@react-aria/interactions@npm:^3.25.0": version: 3.27.1 resolution: "@react-aria/interactions@npm:3.27.1" dependencies: @@ -2081,6 +2338,22 @@ __metadata: languageName: node linkType: hard +"@react-aria/interactions@npm:^3.25.6": + version: 3.25.6 + resolution: "@react-aria/interactions@npm:3.25.6" + dependencies: + "@react-aria/ssr": "npm:^3.9.10" + "@react-aria/utils": "npm:^3.31.0" + "@react-stately/flags": "npm:^3.1.2" + "@react-types/shared": "npm:^3.32.1" + "@swc/helpers": "npm:^0.5.0" + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 10c0/000300ee3cfab724228c89f7261e94e1357f91f746256c352466a014ab6e1e907a3e6c6a2c0e73a6dd7efc97c1a608c96462de5b41a3eebda22cbc97550a797d + languageName: node + linkType: hard + "@react-aria/ssr@npm:^3.9.10": version: 3.9.10 resolution: "@react-aria/ssr@npm:3.9.10" @@ -2092,6 +2365,23 @@ __metadata: languageName: node linkType: hard +"@react-aria/utils@npm:^3.31.0": + version: 3.31.0 + resolution: "@react-aria/utils@npm:3.31.0" + dependencies: + "@react-aria/ssr": "npm:^3.9.10" + "@react-stately/flags": "npm:^3.1.2" + "@react-stately/utils": "npm:^3.10.8" + "@react-types/shared": "npm:^3.32.1" + "@swc/helpers": "npm:^0.5.0" + clsx: "npm:^2.0.0" + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 10c0/a6b5c6b85a51fa9ca204f045f70d36a55e16b56b85141d556eaacb7b74c4c0915189f6d2baea06df59bdd2926dcca08c2313c98478dbb50ed8e59f9b6754735c + languageName: node + linkType: hard + "@react-aria/utils@npm:^3.33.1": version: 3.33.1 resolution: "@react-aria/utils@npm:3.33.1" @@ -2190,6 +2480,17 @@ __metadata: languageName: node linkType: hard +"@react-stately/utils@npm:^3.10.8": + version: 3.10.8 + resolution: "@react-stately/utils@npm:3.10.8" + dependencies: + "@swc/helpers": "npm:^0.5.0" + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 10c0/a97cc292986e3eeb2ceb1626671ce60e8342a3ff35ab92bcfcb94bd6b28729836cc592e3fe4df2fba603e5fdd26291be77b7f60441920298c282bb93f424feba + languageName: node + linkType: hard + "@react-stately/utils@npm:^3.11.0": version: 3.11.0 resolution: "@react-stately/utils@npm:3.11.0" @@ -2201,6 +2502,15 @@ __metadata: languageName: node linkType: hard +"@react-types/shared@npm:^3.32.1": + version: 3.32.1 + resolution: "@react-types/shared@npm:3.32.1" + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 10c0/0a67a34e791c598c5819beb9aa5c11e67db06c9fccc9c5304453147b877fdfc7e73d520e92fcdde8b743e2f155b4cb6a50a15792001a776151191af73d60e24c + languageName: node + linkType: hard + "@react-types/shared@npm:^3.33.1": version: 3.33.1 resolution: "@react-types/shared@npm:3.33.1" @@ -2412,192 +2722,171 @@ __metadata: languageName: node linkType: hard -"@rollup/rollup-android-arm-eabi@npm:4.60.1": - version: 4.60.1 - resolution: "@rollup/rollup-android-arm-eabi@npm:4.60.1" +"@rollup/rollup-android-arm-eabi@npm:4.53.3": + version: 4.53.3 + resolution: "@rollup/rollup-android-arm-eabi@npm:4.53.3" conditions: os=android & cpu=arm languageName: node linkType: hard -"@rollup/rollup-android-arm64@npm:4.60.1": - version: 4.60.1 - resolution: "@rollup/rollup-android-arm64@npm:4.60.1" +"@rollup/rollup-android-arm64@npm:4.53.3": + version: 4.53.3 + resolution: "@rollup/rollup-android-arm64@npm:4.53.3" conditions: os=android & cpu=arm64 languageName: node linkType: hard -"@rollup/rollup-darwin-arm64@npm:4.60.1": - version: 4.60.1 - resolution: "@rollup/rollup-darwin-arm64@npm:4.60.1" +"@rollup/rollup-darwin-arm64@npm:4.53.3": + version: 4.53.3 + resolution: "@rollup/rollup-darwin-arm64@npm:4.53.3" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@rollup/rollup-darwin-x64@npm:4.60.1": - version: 4.60.1 - resolution: "@rollup/rollup-darwin-x64@npm:4.60.1" +"@rollup/rollup-darwin-x64@npm:4.53.3": + version: 4.53.3 + resolution: "@rollup/rollup-darwin-x64@npm:4.53.3" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@rollup/rollup-freebsd-arm64@npm:4.60.1": - version: 4.60.1 - resolution: "@rollup/rollup-freebsd-arm64@npm:4.60.1" +"@rollup/rollup-freebsd-arm64@npm:4.53.3": + version: 4.53.3 + resolution: "@rollup/rollup-freebsd-arm64@npm:4.53.3" conditions: os=freebsd & cpu=arm64 languageName: node linkType: hard -"@rollup/rollup-freebsd-x64@npm:4.60.1": - version: 4.60.1 - resolution: "@rollup/rollup-freebsd-x64@npm:4.60.1" +"@rollup/rollup-freebsd-x64@npm:4.53.3": + version: 4.53.3 + resolution: "@rollup/rollup-freebsd-x64@npm:4.53.3" conditions: os=freebsd & cpu=x64 languageName: node linkType: hard -"@rollup/rollup-linux-arm-gnueabihf@npm:4.60.1": - version: 4.60.1 - resolution: "@rollup/rollup-linux-arm-gnueabihf@npm:4.60.1" +"@rollup/rollup-linux-arm-gnueabihf@npm:4.53.3": + version: 4.53.3 + resolution: "@rollup/rollup-linux-arm-gnueabihf@npm:4.53.3" conditions: os=linux & cpu=arm & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-arm-musleabihf@npm:4.60.1": - version: 4.60.1 - resolution: "@rollup/rollup-linux-arm-musleabihf@npm:4.60.1" +"@rollup/rollup-linux-arm-musleabihf@npm:4.53.3": + version: 4.53.3 + resolution: "@rollup/rollup-linux-arm-musleabihf@npm:4.53.3" conditions: os=linux & cpu=arm & libc=musl languageName: node linkType: hard -"@rollup/rollup-linux-arm64-gnu@npm:4.60.1": - version: 4.60.1 - resolution: "@rollup/rollup-linux-arm64-gnu@npm:4.60.1" +"@rollup/rollup-linux-arm64-gnu@npm:4.53.3": + version: 4.53.3 + resolution: "@rollup/rollup-linux-arm64-gnu@npm:4.53.3" conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-arm64-musl@npm:4.60.1": - version: 4.60.1 - resolution: "@rollup/rollup-linux-arm64-musl@npm:4.60.1" +"@rollup/rollup-linux-arm64-musl@npm:4.53.3": + version: 4.53.3 + resolution: "@rollup/rollup-linux-arm64-musl@npm:4.53.3" conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard -"@rollup/rollup-linux-loong64-gnu@npm:4.60.1": - version: 4.60.1 - resolution: "@rollup/rollup-linux-loong64-gnu@npm:4.60.1" +"@rollup/rollup-linux-loong64-gnu@npm:4.53.3": + version: 4.53.3 + resolution: "@rollup/rollup-linux-loong64-gnu@npm:4.53.3" conditions: os=linux & cpu=loong64 & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-loong64-musl@npm:4.60.1": - version: 4.60.1 - resolution: "@rollup/rollup-linux-loong64-musl@npm:4.60.1" - conditions: os=linux & cpu=loong64 & libc=musl - languageName: node - linkType: hard - -"@rollup/rollup-linux-ppc64-gnu@npm:4.60.1": - version: 4.60.1 - resolution: "@rollup/rollup-linux-ppc64-gnu@npm:4.60.1" +"@rollup/rollup-linux-ppc64-gnu@npm:4.53.3": + version: 4.53.3 + resolution: "@rollup/rollup-linux-ppc64-gnu@npm:4.53.3" conditions: os=linux & cpu=ppc64 & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-ppc64-musl@npm:4.60.1": - version: 4.60.1 - resolution: "@rollup/rollup-linux-ppc64-musl@npm:4.60.1" - conditions: os=linux & cpu=ppc64 & libc=musl - languageName: node - linkType: hard - -"@rollup/rollup-linux-riscv64-gnu@npm:4.60.1": - version: 4.60.1 - resolution: "@rollup/rollup-linux-riscv64-gnu@npm:4.60.1" +"@rollup/rollup-linux-riscv64-gnu@npm:4.53.3": + version: 4.53.3 + resolution: "@rollup/rollup-linux-riscv64-gnu@npm:4.53.3" conditions: os=linux & cpu=riscv64 & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-riscv64-musl@npm:4.60.1": - version: 4.60.1 - resolution: "@rollup/rollup-linux-riscv64-musl@npm:4.60.1" +"@rollup/rollup-linux-riscv64-musl@npm:4.53.3": + version: 4.53.3 + resolution: "@rollup/rollup-linux-riscv64-musl@npm:4.53.3" conditions: os=linux & cpu=riscv64 & libc=musl languageName: node linkType: hard -"@rollup/rollup-linux-s390x-gnu@npm:4.60.1": - version: 4.60.1 - resolution: "@rollup/rollup-linux-s390x-gnu@npm:4.60.1" +"@rollup/rollup-linux-s390x-gnu@npm:4.53.3": + version: 4.53.3 + resolution: "@rollup/rollup-linux-s390x-gnu@npm:4.53.3" conditions: os=linux & cpu=s390x & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-x64-gnu@npm:4.60.1": - version: 4.60.1 - resolution: "@rollup/rollup-linux-x64-gnu@npm:4.60.1" +"@rollup/rollup-linux-x64-gnu@npm:4.53.3": + version: 4.53.3 + resolution: "@rollup/rollup-linux-x64-gnu@npm:4.53.3" conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-x64-musl@npm:4.60.1": - version: 4.60.1 - resolution: "@rollup/rollup-linux-x64-musl@npm:4.60.1" +"@rollup/rollup-linux-x64-musl@npm:4.53.3": + version: 4.53.3 + resolution: "@rollup/rollup-linux-x64-musl@npm:4.53.3" conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard -"@rollup/rollup-openbsd-x64@npm:4.60.1": - version: 4.60.1 - resolution: "@rollup/rollup-openbsd-x64@npm:4.60.1" - conditions: os=openbsd & cpu=x64 - languageName: node - linkType: hard - -"@rollup/rollup-openharmony-arm64@npm:4.60.1": - version: 4.60.1 - resolution: "@rollup/rollup-openharmony-arm64@npm:4.60.1" +"@rollup/rollup-openharmony-arm64@npm:4.53.3": + version: 4.53.3 + resolution: "@rollup/rollup-openharmony-arm64@npm:4.53.3" conditions: os=openharmony & cpu=arm64 languageName: node linkType: hard -"@rollup/rollup-win32-arm64-msvc@npm:4.60.1": - version: 4.60.1 - resolution: "@rollup/rollup-win32-arm64-msvc@npm:4.60.1" +"@rollup/rollup-win32-arm64-msvc@npm:4.53.3": + version: 4.53.3 + resolution: "@rollup/rollup-win32-arm64-msvc@npm:4.53.3" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@rollup/rollup-win32-ia32-msvc@npm:4.60.1": - version: 4.60.1 - resolution: "@rollup/rollup-win32-ia32-msvc@npm:4.60.1" +"@rollup/rollup-win32-ia32-msvc@npm:4.53.3": + version: 4.53.3 + resolution: "@rollup/rollup-win32-ia32-msvc@npm:4.53.3" conditions: os=win32 & cpu=ia32 languageName: node linkType: hard -"@rollup/rollup-win32-x64-gnu@npm:4.60.1": - version: 4.60.1 - resolution: "@rollup/rollup-win32-x64-gnu@npm:4.60.1" +"@rollup/rollup-win32-x64-gnu@npm:4.53.3": + version: 4.53.3 + resolution: "@rollup/rollup-win32-x64-gnu@npm:4.53.3" conditions: os=win32 & cpu=x64 languageName: node linkType: hard -"@rollup/rollup-win32-x64-msvc@npm:4.60.1": - version: 4.60.1 - resolution: "@rollup/rollup-win32-x64-msvc@npm:4.60.1" +"@rollup/rollup-win32-x64-msvc@npm:4.53.3": + version: 4.53.3 + resolution: "@rollup/rollup-win32-x64-msvc@npm:4.53.3" conditions: os=win32 & cpu=x64 languageName: node linkType: hard "@sindresorhus/is@npm:^7.0.2": - version: 7.2.0 - resolution: "@sindresorhus/is@npm:7.2.0" - checksum: 10c0/0040c17d7826414363f99f5d56077c200789d51e6dfe5542920bfb29ab3828ec0ebf2845e8bae796bee461debb646b5e4c0a623140131cf3143471e915b50b54 + version: 7.1.1 + resolution: "@sindresorhus/is@npm:7.1.1" + checksum: 10c0/96f021b8c5680e0687ceba5619c2e56fe6b089b190b3149280a1e418e6315c66839e3f1519cf1c89f7a888b5a0017a0ef1db17436d783ee398b7d5a515caa3ef languageName: node linkType: hard "@speed-highlight/core@npm:^1.2.7": - version: 1.2.15 - resolution: "@speed-highlight/core@npm:1.2.15" - checksum: 10c0/1e069429a46aa1d1c15afde27ee94f78073c948357abccb17ddab71fe7cad0eb2fc761d553a918d30a13723e5c30a0374304844297e9bd37dd01953466cb93bb + version: 1.2.12 + resolution: "@speed-highlight/core@npm:1.2.12" + checksum: 10c0/37613c7a031af3b239282cc09211cefc1c9e164df07110520d2116ae7b4741512c1905bf1e011706ee2e652cef24df834f2068c4c4fff71e0257ec22fa655ff2 languageName: node linkType: hard @@ -2609,11 +2898,11 @@ __metadata: linkType: hard "@swc/helpers@npm:^0.5.0": - version: 0.5.21 - resolution: "@swc/helpers@npm:0.5.21" + version: 0.5.17 + resolution: "@swc/helpers@npm:0.5.17" dependencies: tslib: "npm:^2.8.0" - checksum: 10c0/692018ec8a9f7ea5ea3fe576fea5af1a782c8bc1752fcb60f949b482fb2521609d1d3710908aebae67086f152e57d231d59b08f4653fd20a2e3e0fa4a34e6322 + checksum: 10c0/fe1f33ebb968558c5a0c595e54f2e479e4609bff844f9ca9a2d1ffd8dd8504c26f862a11b031f48f75c95b0381c2966c3dd156e25942f90089badd24341e7dbb languageName: node linkType: hard @@ -2782,21 +3071,21 @@ __metadata: linkType: hard "@tanstack/react-virtual@npm:^3.13.9": - version: 3.13.23 - resolution: "@tanstack/react-virtual@npm:3.13.23" + version: 3.13.12 + resolution: "@tanstack/react-virtual@npm:3.13.12" dependencies: - "@tanstack/virtual-core": "npm:3.13.23" + "@tanstack/virtual-core": "npm:3.13.12" peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - checksum: 10c0/a3e33463eb471067f9539858655bbefb99778f930156165afb0218fe5ffa181bc2e3dacfe3b6f655f1716d9994064f58ef009370975f801b4c83826aa33a5791 + checksum: 10c0/0eda3d5691ec3bf93a1cdaa955f4972c7aa9a5026179622824bb52ff8c47e59ee4634208e52d77f43ffb3ce435ee39a0899d6a81f6316918ce89d68122490371 languageName: node linkType: hard -"@tanstack/virtual-core@npm:3.13.23": - version: 3.13.23 - resolution: "@tanstack/virtual-core@npm:3.13.23" - checksum: 10c0/3487089ea4e1dcbb01836f51a1b35b709f9ba03312fe600ddb97c893c16be213e1690af735717b1d6b2e22dfec691c338bc96b5965228c195840249699d5273a +"@tanstack/virtual-core@npm:3.13.12": + version: 3.13.12 + resolution: "@tanstack/virtual-core@npm:3.13.12" + checksum: 10c0/483f38761b73db05c181c10181f0781c1051be3350ae5c378e65057e5f1fdd6606e06e17dbaad8a5e36c04b208ea1a1344cacd4eca0dcde60f335cf398e4d698 languageName: node linkType: hard @@ -2840,11 +3129,11 @@ __metadata: linkType: hard "@types/debug@npm:^4.0.0": - version: 4.1.13 - resolution: "@types/debug@npm:4.1.13" + version: 4.1.12 + resolution: "@types/debug@npm:4.1.12" dependencies: "@types/ms": "npm:*" - checksum: 10c0/e5e124021bbdb23a82727eee0a726ae0fc8a3ae1f57253cbcc47497f259afb357de7f6941375e773e1abbfa1604c1555b901a409d762ec2bb4c1612131d4afb7 + checksum: 10c0/5dcd465edbb5a7f226e9a5efd1f399c6172407ef5840686b73e3608ce135eeca54ae8037dcd9f16bdb2768ac74925b820a8b9ecc588a58ca09eca6acabe33e2f languageName: node linkType: hard @@ -2918,20 +3207,20 @@ __metadata: linkType: hard "@types/node@npm:*": - version: 25.5.2 - resolution: "@types/node@npm:25.5.2" + version: 24.10.1 + resolution: "@types/node@npm:24.10.1" dependencies: - undici-types: "npm:~7.18.0" - checksum: 10c0/11e41a85401724cd1a4de6fb7bd4264ec46db10c09fc8cf8d41de4ede0a7063db458348f859ead4ec0929906aa26aaf45a5fef3aa59742ca0521cda9cee52377 + undici-types: "npm:~7.16.0" + checksum: 10c0/d6bca7a78f550fbb376f236f92b405d676003a8a09a1b411f55920ef34286ee3ee51f566203920e835478784df52662b5b2af89159d9d319352e9ea21801c002 languageName: node linkType: hard "@types/node@npm:^22.0.0": - version: 22.19.17 - resolution: "@types/node@npm:22.19.17" + version: 22.19.1 + resolution: "@types/node@npm:22.19.1" dependencies: undici-types: "npm:~6.21.0" - checksum: 10c0/b66c484c0a9f6d88b1ef360b0f487717234ee1a482cb2551ff73d9f3c43a42a777daf4c8a5eee970960728f8fe1f3877d3d8c6ffabcbca74cb401a59db700fa4 + checksum: 10c0/6edd93aea86da740cb7872626839cd6f4a67a049d3a3a6639cb592c620ec591408a30989ab7410008d1a0b2d4985ce50f1e488e79c033e4476d3bec6833b0a2f languageName: node linkType: hard @@ -3192,7 +3481,7 @@ __metadata: languageName: node linkType: hard -"accepts@npm:~1.3.8": +"accepts@npm:~1.3.4, accepts@npm:~1.3.8": version: 1.3.8 resolution: "accepts@npm:1.3.8" dependencies: @@ -3212,11 +3501,11 @@ __metadata: linkType: hard "acorn@npm:^8.0.0": - version: 8.16.0 - resolution: "acorn@npm:8.16.0" + version: 8.15.0 + resolution: "acorn@npm:8.15.0" bin: acorn: bin/acorn - checksum: 10c0/c9c52697227661b68d0debaf972222d4f622aa06b185824164e153438afa7b08273432ca43ea792cadb24dada1d46f6f6bb1ef8de9956979288cc1b96bf9914e + checksum: 10c0/dec73ff59b7d6628a01eebaece7f2bdb8bb62b9b5926dcad0f8931f2b8b79c2be21f6c68ac095592adb5adb15831a3635d9343e6a91d028bbe85d564875ec3ec languageName: node linkType: hard @@ -3252,14 +3541,36 @@ __metadata: linkType: hard "ajv@npm:^8.0.0, ajv@npm:^8.12.0": - version: 8.18.0 - resolution: "ajv@npm:8.18.0" + version: 8.17.1 + resolution: "ajv@npm:8.17.1" dependencies: fast-deep-equal: "npm:^3.1.3" fast-uri: "npm:^3.0.1" json-schema-traverse: "npm:^1.0.0" require-from-string: "npm:^2.0.2" - checksum: 10c0/e7517c426173513a07391be951879932bdf3348feaebd2199f5b901c20f99d60db8cd1591502d4d551dc82f594e82a05c4fe1c70139b15b8937f7afeaed9532f + checksum: 10c0/ec3ba10a573c6b60f94639ffc53526275917a2df6810e4ab5a6b959d87459f9ef3f00d5e7865b82677cb7d21590355b34da14d1d0b9c32d75f95a187e76fff35 + languageName: node + linkType: hard + +"algoliasearch@npm:^5.50.1": + version: 5.50.1 + resolution: "algoliasearch@npm:5.50.1" + dependencies: + "@algolia/abtesting": "npm:1.16.1" + "@algolia/client-abtesting": "npm:5.50.1" + "@algolia/client-analytics": "npm:5.50.1" + "@algolia/client-common": "npm:5.50.1" + "@algolia/client-insights": "npm:5.50.1" + "@algolia/client-personalization": "npm:5.50.1" + "@algolia/client-query-suggestions": "npm:5.50.1" + "@algolia/client-search": "npm:5.50.1" + "@algolia/ingestion": "npm:1.50.1" + "@algolia/monitoring": "npm:1.50.1" + "@algolia/recommend": "npm:5.50.1" + "@algolia/requester-browser-xhr": "npm:5.50.1" + "@algolia/requester-fetch": "npm:5.50.1" + "@algolia/requester-node-http": "npm:5.50.1" + checksum: 10c0/4b91f019c89324786e23f90b7773eb82b142e8075c95f204cf6fc07f320fcbbf623ca338509647d93b9776f4645a1f72debb2800627c4bf1b80e3ed8f2b398b1 languageName: node linkType: hard @@ -3456,8 +3767,8 @@ __metadata: linkType: hard "auto-image-converter@npm:^2.2.0": - version: 2.2.2 - resolution: "auto-image-converter@npm:2.2.2" + version: 2.2.0 + resolution: "auto-image-converter@npm:2.2.0" dependencies: chokidar: "npm:^4.0.3" commander: "npm:^14.0.1" @@ -3467,7 +3778,7 @@ __metadata: auto-convert-images: bin/index.js auto-convert-images-resize: bin/onetimeresizer.mjs auto-convert-images-watch: bin/watcher.mjs - checksum: 10c0/6776271495e1c83ede0dceef85c432b30ceac3129e835e765bfc811d4e3ab3aa6a8ef52e7c862a9ffffc93698354574d444d28719f5b298758ae0419d1a18493 + checksum: 10c0/3a7afe5abecaf8ed149678fb35f72b49d6ae50b3240885025bdc965e3c2c3daeb5b7feb09614779cadaf08c3cf6a37dc4b20417e93555b0e622ebab5e1dd9153 languageName: node linkType: hard @@ -3481,12 +3792,12 @@ __metadata: linkType: hard "avvio@npm:^9.0.0": - version: 9.2.0 - resolution: "avvio@npm:9.2.0" + version: 9.1.0 + resolution: "avvio@npm:9.1.0" dependencies: "@fastify/error": "npm:^4.0.0" fastq: "npm:^1.17.1" - checksum: 10c0/ebeb1613a507d001922a3a2763336191da731bbd9df93f67d51b08fc98549e14499b058e008220d5df3354e0f14316cfa57107198caf09df6c8ba42c94ce9f51 + checksum: 10c0/bdc294a7e8f38e1e21f9d338d97d7240025db54f1005fc419cfe0499a35edf2276ab1fe91135739faa3a9437358ec6912d5a56f23361b061880333cb4f1c7884 languageName: node linkType: hard @@ -3505,14 +3816,14 @@ __metadata: linkType: hard "babel-dead-code-elimination@npm:^1.0.6": - version: 1.0.12 - resolution: "babel-dead-code-elimination@npm:1.0.12" + version: 1.0.10 + resolution: "babel-dead-code-elimination@npm:1.0.10" dependencies: "@babel/core": "npm:^7.23.7" "@babel/parser": "npm:^7.23.6" "@babel/traverse": "npm:^7.23.7" "@babel/types": "npm:^7.23.6" - checksum: 10c0/9289b66ce202a5f2b8c160f6a0ed16b97c42a9e06e92ea997df4e34d6a8309a01cf641b21467ee6a2713efd7e158b4b770e04a07f3f9d30eb05d428d186f7a60 + checksum: 10c0/9503662f28cf8f86e7a27c5cc1fa63fc556100cd3bc6f1a4382aa8e9c6df54b15d2e0fcc073016f315d26a9e4004bc4d70829a395f056172b8f9240314da8973 languageName: node linkType: hard @@ -3530,13 +3841,6 @@ __metadata: languageName: node linkType: hard -"balanced-match@npm:^4.0.2": - version: 4.0.4 - resolution: "balanced-match@npm:4.0.4" - checksum: 10c0/07e86102a3eb2ee2a6a1a89164f29d0dbaebd28f2ca3f5ca786f36b8b23d9e417eb3be45a4acf754f837be5ac0a2317de90d3fcb7f4f4dc95720a1f36b26a17b - languageName: node - linkType: hard - "base64-js@npm:^1.3.1": version: 1.5.1 resolution: "base64-js@npm:1.5.1" @@ -3544,12 +3848,12 @@ __metadata: languageName: node linkType: hard -"baseline-browser-mapping@npm:^2.10.12": - version: 2.10.16 - resolution: "baseline-browser-mapping@npm:2.10.16" +"baseline-browser-mapping@npm:^2.8.25": + version: 2.8.31 + resolution: "baseline-browser-mapping@npm:2.8.31" bin: - baseline-browser-mapping: dist/cli.cjs - checksum: 10c0/9947243bb8f16db3f8e05397c5c3e7a91243dcf2d1ec6a681ad5ffabeadee36c1061cd18e5f0432088df6798fa0689890ba26db173b9ad23c5650709b7b2e7cf + baseline-browser-mapping: dist/cli.js + checksum: 10c0/e0b2fcb41bf36c5e27e122a4d4cc9e5f6b9747d31cd0bd1f771aee9c490eb1e01cd11a31db32286bd4b9221139ee332b5ab7e3893c18a4dbd0ce8915a9e180ed languageName: node linkType: hard @@ -3597,23 +3901,23 @@ __metadata: languageName: node linkType: hard -"body-parser@npm:~1.20.3": - version: 1.20.4 - resolution: "body-parser@npm:1.20.4" +"body-parser@npm:1.20.3": + version: 1.20.3 + resolution: "body-parser@npm:1.20.3" dependencies: - bytes: "npm:~3.1.2" + bytes: "npm:3.1.2" content-type: "npm:~1.0.5" debug: "npm:2.6.9" depd: "npm:2.0.0" - destroy: "npm:~1.2.0" - http-errors: "npm:~2.0.1" - iconv-lite: "npm:~0.4.24" - on-finished: "npm:~2.4.1" - qs: "npm:~6.14.0" - raw-body: "npm:~2.5.3" + destroy: "npm:1.2.0" + http-errors: "npm:2.0.0" + iconv-lite: "npm:0.4.24" + on-finished: "npm:2.4.1" + qs: "npm:6.13.0" + raw-body: "npm:2.5.2" type-is: "npm:~1.6.18" - unpipe: "npm:~1.0.0" - checksum: 10c0/569c1e896297d1fcd8f34026c8d0ab70b90d45343c15c5d8dff5de2bad08125fc1e2f8c2f3f4c1ac6c0caaad115218202594d37dcb8d89d9b5dcae1c2b736aa9 + unpipe: "npm:1.0.0" + checksum: 10c0/0a9a93b7518f222885498dcecaad528cf010dd109b071bf471c93def4bfe30958b83e03496eb9c1ad4896db543d999bb62be1a3087294162a88cfa1b42c16310 languageName: node linkType: hard @@ -3633,21 +3937,12 @@ __metadata: languageName: node linkType: hard -"brace-expansion@npm:^2.0.2": - version: 2.0.3 - resolution: "brace-expansion@npm:2.0.3" +"brace-expansion@npm:^2.0.1": + version: 2.0.2 + resolution: "brace-expansion@npm:2.0.2" dependencies: balanced-match: "npm:^1.0.0" - checksum: 10c0/468436c9b2fa6f9e64d0cff8784b21300677571a7196e258593e95e7c3db9973a80fbafdb0f01404d5d298a04dc666eae1fc3c9052e2edbb9f2510541deeddfe - languageName: node - linkType: hard - -"brace-expansion@npm:^5.0.5": - version: 5.0.5 - resolution: "brace-expansion@npm:5.0.5" - dependencies: - balanced-match: "npm:^4.0.2" - checksum: 10c0/4d238e14ed4f5cc9c07285550a41cef23121ca08ba99fa9eb5b55b580dcb6bf868b8210aa10526bdc9f8dc97f33ca2a7259039c4cc131a93042beddb424c48e3 + checksum: 10c0/6d117a4c793488af86b83172deb6af143e94c17bc53b0b3cec259733923b4ca84679d506ac261f4ba3c7ed37c46018e2ff442f9ce453af8643ecd64f4a54e6cf languageName: node linkType: hard @@ -3661,17 +3956,17 @@ __metadata: linkType: hard "browserslist@npm:^4.24.0": - version: 4.28.2 - resolution: "browserslist@npm:4.28.2" - dependencies: - baseline-browser-mapping: "npm:^2.10.12" - caniuse-lite: "npm:^1.0.30001782" - electron-to-chromium: "npm:^1.5.328" - node-releases: "npm:^2.0.36" - update-browserslist-db: "npm:^1.2.3" + version: 4.28.0 + resolution: "browserslist@npm:4.28.0" + dependencies: + baseline-browser-mapping: "npm:^2.8.25" + caniuse-lite: "npm:^1.0.30001754" + electron-to-chromium: "npm:^1.5.249" + node-releases: "npm:^2.0.27" + update-browserslist-db: "npm:^1.1.4" bin: browserslist: cli.js - checksum: 10c0/c0228b6330f785b7fa59d2d360124ec6d9322f96ed9f3ee1f873e33ecc9503a6f0ffc3b71191a28c4ff6e930b753b30043da1c33844a9548f3018d491f09ce60 + checksum: 10c0/4284fd568f7d40a496963083860d488cb2a89fb055b6affd316bebc59441fec938e090b3e62c0ee065eb0bc88cd1bc145f4300a16c75f3f565621c5823715ae1 languageName: node linkType: hard @@ -3718,7 +4013,7 @@ __metadata: languageName: node linkType: hard -"bytes@npm:~3.1.2": +"bytes@npm:3.1.2": version: 3.1.2 resolution: "bytes@npm:3.1.2" checksum: 10c0/76d1c43cbd602794ad8ad2ae94095cddeb1de78c5dddaa7005c51af10b0176c69971a6d88e805a90c2b6550d76636e43c40d8427a808b8645ede885de4a0358e @@ -3733,8 +4028,8 @@ __metadata: linkType: hard "cacache@npm:^20.0.1": - version: 20.0.4 - resolution: "cacache@npm:20.0.4" + version: 20.0.3 + resolution: "cacache@npm:20.0.3" dependencies: "@npmcli/fs": "npm:^5.0.0" fs-minipass: "npm:^3.0.0" @@ -3746,7 +4041,8 @@ __metadata: minipass-pipeline: "npm:^1.2.4" p-map: "npm:^7.0.2" ssri: "npm:^13.0.0" - checksum: 10c0/539bf4020e44ba9ca5afc2ec435623ed7e0dd80c020097677e6b4a0545df5cc9d20b473212d01209c8b4aea43c0d095af0bb6da97bcb991642ea6fac0d7c462b + unique-filename: "npm:^5.0.0" + checksum: 10c0/c7da1ca694d20e8f8aedabd21dc11518f809a7d2b59aa76a1fc655db5a9e62379e465c157ddd2afe34b19230808882288effa6911b2de26a088a6d5645123462 languageName: node linkType: hard @@ -3796,10 +4092,10 @@ __metadata: languageName: node linkType: hard -"caniuse-lite@npm:^1.0.30001782": - version: 1.0.30001786 - resolution: "caniuse-lite@npm:1.0.30001786" - checksum: 10c0/9895f0add1991eefb91cfae98e7baa9daffc6b862b0996c983d30e6be90ef679b6aef32dcb6eca312977fb67c2636ee575820f101213e69c1e0dbffd6ee8e09e +"caniuse-lite@npm:^1.0.30001754": + version: 1.0.30001757 + resolution: "caniuse-lite@npm:1.0.30001757" + checksum: 10c0/3ccb71fa2bf1f8c96ff1bf9b918b08806fed33307e20a3ce3259155fda131eaf96cfcd88d3d309c8fd7f8285cc71d89a3b93648a1c04814da31c301f98508d42 languageName: node linkType: hard @@ -4054,9 +4350,9 @@ __metadata: linkType: hard "commander@npm:^14.0.1": - version: 14.0.3 - resolution: "commander@npm:14.0.3" - checksum: 10c0/755652564bbf56ff2ff083313912b326450d3f8d8c85f4b71416539c9a05c3c67dbd206821ca72635bf6b160e2afdefcb458e86b317827d5cb333b69ce7f1a24 + version: 14.0.2 + resolution: "commander@npm:14.0.2" + checksum: 10c0/245abd1349dbad5414cb6517b7b5c584895c02c4f7836ff5395f301192b8566f9796c82d7bd6c92d07eba8775fe4df86602fca5d86d8d10bcc2aded1e21c2aeb languageName: node linkType: hard @@ -4100,14 +4396,7 @@ __metadata: languageName: node linkType: hard -"content-disposition@npm:^1.0.1": - version: 1.0.1 - resolution: "content-disposition@npm:1.0.1" - checksum: 10c0/bd7ff1fe8d2542d3a2b9a29428cc3591f6ac27bb5595bba2c69664408a68f9538b14cbd92479796ea835b317a09a527c8c7209c4200381dedb0c34d3b658849e - languageName: node - linkType: hard - -"content-disposition@npm:~0.5.4": +"content-disposition@npm:0.5.4": version: 0.5.4 resolution: "content-disposition@npm:0.5.4" dependencies: @@ -4116,6 +4405,13 @@ __metadata: languageName: node linkType: hard +"content-disposition@npm:^1.0.1": + version: 1.0.1 + resolution: "content-disposition@npm:1.0.1" + checksum: 10c0/bd7ff1fe8d2542d3a2b9a29428cc3591f6ac27bb5595bba2c69664408a68f9538b14cbd92479796ea835b317a09a527c8c7209c4200381dedb0c34d3b658849e + languageName: node + linkType: hard + "content-type@npm:~1.0.4, content-type@npm:~1.0.5": version: 1.0.5 resolution: "content-type@npm:1.0.5" @@ -4130,10 +4426,17 @@ __metadata: languageName: node linkType: hard -"cookie-signature@npm:~1.0.6": - version: 1.0.7 - resolution: "cookie-signature@npm:1.0.7" - checksum: 10c0/e7731ad2995ae2efeed6435ec1e22cdd21afef29d300c27281438b1eab2bae04ef0d1a203928c0afec2cee72aa36540b8747406ebe308ad23c8e8cc3c26c9c51 +"cookie-signature@npm:1.0.6": + version: 1.0.6 + resolution: "cookie-signature@npm:1.0.6" + checksum: 10c0/b36fd0d4e3fef8456915fcf7742e58fbfcc12a17a018e0eb9501c9d5ef6893b596466f03b0564b81af29ff2538fd0aa4b9d54fe5ccbfb4c90ea50ad29fe2d221 + languageName: node + linkType: hard + +"cookie@npm:0.7.1": + version: 0.7.1 + resolution: "cookie@npm:0.7.1" + checksum: 10c0/5de60c67a410e7c8dc8a46a4b72eb0fe925871d057c9a5d2c0e8145c4270a4f81076de83410c4d397179744b478e33cd80ccbcc457abf40a9409ad27dcd21dde languageName: node linkType: hard @@ -4144,13 +4447,6 @@ __metadata: languageName: node linkType: hard -"cookie@npm:~0.7.1": - version: 0.7.2 - resolution: "cookie@npm:0.7.2" - checksum: 10c0/9596e8ccdbf1a3a88ae02cf5ee80c1c50959423e1022e4e60b91dd87c622af1da309253d8abdb258fb5e3eacb4f08e579dc58b4897b8087574eee0fd35dfa5d2 - languageName: node - linkType: hard - "core-util-is@npm:1.0.2": version: 1.0.2 resolution: "core-util-is@npm:1.0.2" @@ -4357,23 +4653,23 @@ __metadata: linkType: hard "decode-named-character-reference@npm:^1.0.0": - version: 1.3.0 - resolution: "decode-named-character-reference@npm:1.3.0" + version: 1.2.0 + resolution: "decode-named-character-reference@npm:1.2.0" dependencies: character-entities: "npm:^2.0.0" - checksum: 10c0/787f4c87f3b82ea342aa7c2d7b1882b6fb9511bb77f72ae44dcaabea0470bacd1e9c6a0080ab886545019fa0cb3a7109573fad6b61a362844c3a0ac52b36e4bb + checksum: 10c0/761a89de6b0e0a2d4b21ae99074e4cc3344dd11eb29f112e23cc5909f2e9f33c5ed20cd6b146b27fb78170bce0f3f9b3362a84b75638676a05c938c24a60f5d7 languageName: node linkType: hard "dedent@npm:^1.5.3": - version: 1.7.2 - resolution: "dedent@npm:1.7.2" + version: 1.7.0 + resolution: "dedent@npm:1.7.0" peerDependencies: babel-plugin-macros: ^3.1.0 peerDependenciesMeta: babel-plugin-macros: optional: true - checksum: 10c0/acaff07cac355b93f17b1b17ebbb84d3cc55af6ab4b7814c3f505e061903e168bc6bf9ddce331552d64dee1525f0b4c549c9ade46aebfac6f69caaed74e90751 + checksum: 10c0/c5e8a8beb5072bd5e520cb64b27a82d7ec3c2a63ee5ce47dbc2a05d5b7700cefd77a992a752cd0a8b1d979c1db06b14fb9486e805f3ad6088eda6e07cd9bf2d5 languageName: node linkType: hard @@ -4451,7 +4747,7 @@ __metadata: languageName: node linkType: hard -"destroy@npm:1.2.0, destroy@npm:~1.2.0": +"destroy@npm:1.2.0": version: 1.2.0 resolution: "destroy@npm:1.2.0" checksum: 10c0/bd7633942f57418f5a3b80d5cb53898127bcf53e24cdf5d5f4396be471417671f0fee48a4ebe9a1e9defbde2a31280011af58a57e090ff822f589b443ed4e643 @@ -4576,10 +4872,10 @@ __metadata: languageName: node linkType: hard -"electron-to-chromium@npm:^1.5.328": - version: 1.5.332 - resolution: "electron-to-chromium@npm:1.5.332" - checksum: 10c0/0e9aedd5634e81f323919a5fba7e1cf34c18860262a50915fb2371a6c65324cbfa50eaea231d05d235cc40b1b60cfaf0c1546d3f2daa6ad6c03e89dfe21cb55f +"electron-to-chromium@npm:^1.5.249": + version: 1.5.260 + resolution: "electron-to-chromium@npm:1.5.260" + checksum: 10c0/5be308adbe7f9b370f628eb3ae35528bccc8e8592ee4848f9dfa308af658deaa87e915dd6929b6993e712929e7e6828f40434814506476ae11051381ee423fdf languageName: node linkType: hard @@ -4604,6 +4900,13 @@ __metadata: languageName: node linkType: hard +"encodeurl@npm:~1.0.2": + version: 1.0.2 + resolution: "encodeurl@npm:1.0.2" + checksum: 10c0/f6c2387379a9e7c1156c1c3d4f9cb7bb11cf16dd4c1682e1f6746512564b053df5781029b6061296832b59fb22f459dbe250386d217c2f6e203601abb2ee0bec + languageName: node + linkType: hard + "encodeurl@npm:~2.0.0": version: 2.0.0 resolution: "encodeurl@npm:2.0.0" @@ -4611,6 +4914,15 @@ __metadata: languageName: node linkType: hard +"encoding@npm:^0.1.13": + version: 0.1.13 + resolution: "encoding@npm:0.1.13" + dependencies: + iconv-lite: "npm:^0.6.2" + checksum: 10c0/36d938712ff00fe1f4bac88b43bcffb5930c1efa57bbcdca9d67e1d9d6c57cfb1200fb01efe0f3109b2ce99b231f90779532814a81370a1bd3274a0f58585039 + languageName: node + linkType: hard + "end-of-stream@npm:^1.0.0, end-of-stream@npm:^1.1.0, end-of-stream@npm:^1.4.1": version: 1.4.5 resolution: "end-of-stream@npm:1.4.5" @@ -4678,8 +4990,8 @@ __metadata: linkType: hard "es-abstract@npm:^1.23.5, es-abstract@npm:^1.23.9": - version: 1.24.1 - resolution: "es-abstract@npm:1.24.1" + version: 1.24.0 + resolution: "es-abstract@npm:1.24.0" dependencies: array-buffer-byte-length: "npm:^1.0.2" arraybuffer.prototype.slice: "npm:^1.0.4" @@ -4735,7 +5047,7 @@ __metadata: typed-array-length: "npm:^1.0.7" unbox-primitive: "npm:^1.1.0" which-typed-array: "npm:^1.1.19" - checksum: 10c0/fca062ef8b5daacf743732167d319a212d45cb655b0bb540821d38d715416ae15b04b84fc86da9e2c89135aa7b337337b6c867f84dcde698d75d55688d5d765c + checksum: 10c0/b256e897be32df5d382786ce8cce29a1dd8c97efbab77a26609bd70f2ed29fbcfc7a31758cb07488d532e7ccccdfca76c1118f2afe5a424cdc05ca007867c318 languageName: node linkType: hard @@ -4912,36 +5224,36 @@ __metadata: languageName: node linkType: hard -"esbuild@npm:^0.27.0": - version: 0.27.7 - resolution: "esbuild@npm:0.27.7" - dependencies: - "@esbuild/aix-ppc64": "npm:0.27.7" - "@esbuild/android-arm": "npm:0.27.7" - "@esbuild/android-arm64": "npm:0.27.7" - "@esbuild/android-x64": "npm:0.27.7" - "@esbuild/darwin-arm64": "npm:0.27.7" - "@esbuild/darwin-x64": "npm:0.27.7" - "@esbuild/freebsd-arm64": "npm:0.27.7" - "@esbuild/freebsd-x64": "npm:0.27.7" - "@esbuild/linux-arm": "npm:0.27.7" - "@esbuild/linux-arm64": "npm:0.27.7" - "@esbuild/linux-ia32": "npm:0.27.7" - "@esbuild/linux-loong64": "npm:0.27.7" - "@esbuild/linux-mips64el": "npm:0.27.7" - "@esbuild/linux-ppc64": "npm:0.27.7" - "@esbuild/linux-riscv64": "npm:0.27.7" - "@esbuild/linux-s390x": "npm:0.27.7" - "@esbuild/linux-x64": "npm:0.27.7" - "@esbuild/netbsd-arm64": "npm:0.27.7" - "@esbuild/netbsd-x64": "npm:0.27.7" - "@esbuild/openbsd-arm64": "npm:0.27.7" - "@esbuild/openbsd-x64": "npm:0.27.7" - "@esbuild/openharmony-arm64": "npm:0.27.7" - "@esbuild/sunos-x64": "npm:0.27.7" - "@esbuild/win32-arm64": "npm:0.27.7" - "@esbuild/win32-ia32": "npm:0.27.7" - "@esbuild/win32-x64": "npm:0.27.7" +"esbuild@npm:^0.25.0": + version: 0.25.12 + resolution: "esbuild@npm:0.25.12" + dependencies: + "@esbuild/aix-ppc64": "npm:0.25.12" + "@esbuild/android-arm": "npm:0.25.12" + "@esbuild/android-arm64": "npm:0.25.12" + "@esbuild/android-x64": "npm:0.25.12" + "@esbuild/darwin-arm64": "npm:0.25.12" + "@esbuild/darwin-x64": "npm:0.25.12" + "@esbuild/freebsd-arm64": "npm:0.25.12" + "@esbuild/freebsd-x64": "npm:0.25.12" + "@esbuild/linux-arm": "npm:0.25.12" + "@esbuild/linux-arm64": "npm:0.25.12" + "@esbuild/linux-ia32": "npm:0.25.12" + "@esbuild/linux-loong64": "npm:0.25.12" + "@esbuild/linux-mips64el": "npm:0.25.12" + "@esbuild/linux-ppc64": "npm:0.25.12" + "@esbuild/linux-riscv64": "npm:0.25.12" + "@esbuild/linux-s390x": "npm:0.25.12" + "@esbuild/linux-x64": "npm:0.25.12" + "@esbuild/netbsd-arm64": "npm:0.25.12" + "@esbuild/netbsd-x64": "npm:0.25.12" + "@esbuild/openbsd-arm64": "npm:0.25.12" + "@esbuild/openbsd-x64": "npm:0.25.12" + "@esbuild/openharmony-arm64": "npm:0.25.12" + "@esbuild/sunos-x64": "npm:0.25.12" + "@esbuild/win32-arm64": "npm:0.25.12" + "@esbuild/win32-ia32": "npm:0.25.12" + "@esbuild/win32-x64": "npm:0.25.12" dependenciesMeta: "@esbuild/aix-ppc64": optional: true @@ -4997,7 +5309,7 @@ __metadata: optional: true bin: esbuild: bin/esbuild - checksum: 10c0/ccd51f0555708bc9ff4ec9dc3ac92d3daacd45ecaac949ca8645984c5c323bf8cefe98c2df307418685e0b4ce37f9a3bdbfe8e3651fe632a0059a436195a17d4 + checksum: 10c0/c205357531423220a9de8e1e6c6514242bc9b1666e762cd67ccdf8fdfdc3f1d0bd76f8d9383958b97ad4c953efdb7b6e8c1f9ca5951cd2b7c5235e8755b34a6b languageName: node linkType: hard @@ -5173,41 +5485,41 @@ __metadata: linkType: hard "express@npm:^4.16.3": - version: 4.22.1 - resolution: "express@npm:4.22.1" + version: 4.21.2 + resolution: "express@npm:4.21.2" dependencies: accepts: "npm:~1.3.8" array-flatten: "npm:1.1.1" - body-parser: "npm:~1.20.3" - content-disposition: "npm:~0.5.4" + body-parser: "npm:1.20.3" + content-disposition: "npm:0.5.4" content-type: "npm:~1.0.4" - cookie: "npm:~0.7.1" - cookie-signature: "npm:~1.0.6" + cookie: "npm:0.7.1" + cookie-signature: "npm:1.0.6" debug: "npm:2.6.9" depd: "npm:2.0.0" encodeurl: "npm:~2.0.0" escape-html: "npm:~1.0.3" etag: "npm:~1.8.1" - finalhandler: "npm:~1.3.1" - fresh: "npm:~0.5.2" - http-errors: "npm:~2.0.0" + finalhandler: "npm:1.3.1" + fresh: "npm:0.5.2" + http-errors: "npm:2.0.0" merge-descriptors: "npm:1.0.3" methods: "npm:~1.1.2" - on-finished: "npm:~2.4.1" + on-finished: "npm:2.4.1" parseurl: "npm:~1.3.3" - path-to-regexp: "npm:~0.1.12" + path-to-regexp: "npm:0.1.12" proxy-addr: "npm:~2.0.7" - qs: "npm:~6.14.0" + qs: "npm:6.13.0" range-parser: "npm:~1.2.1" safe-buffer: "npm:5.2.1" - send: "npm:~0.19.0" - serve-static: "npm:~1.16.2" + send: "npm:0.19.0" + serve-static: "npm:1.16.2" setprototypeof: "npm:1.2.0" - statuses: "npm:~2.0.1" + statuses: "npm:2.0.1" type-is: "npm:~1.6.18" utils-merge: "npm:1.0.1" vary: "npm:~1.1.2" - checksum: 10c0/ea57f512ab1e05e26b53a14fd432f65a10ec735ece342b37d0b63a7bcb8d337ffbb830ecb8ca15bcdfe423fbff88cea09786277baff200e8cde3ab40faa665cd + checksum: 10c0/38168fd0a32756600b56e6214afecf4fc79ec28eca7f7a91c2ab8d50df4f47562ca3f9dee412da7f5cea6b1a1544b33b40f9f8586dbacfbdada0fe90dbb10a1f languageName: node linkType: hard @@ -5291,8 +5603,8 @@ __metadata: linkType: hard "fast-json-stringify@npm:^6.0.0": - version: 6.3.0 - resolution: "fast-json-stringify@npm:6.3.0" + version: 6.1.1 + resolution: "fast-json-stringify@npm:6.1.1" dependencies: "@fastify/merge-json-schemas": "npm:^0.2.0" ajv: "npm:^8.12.0" @@ -5300,7 +5612,7 @@ __metadata: fast-uri: "npm:^3.0.0" json-schema-ref-resolver: "npm:^3.0.0" rfdc: "npm:^1.2.0" - checksum: 10c0/5562eee1b18a7db92dce5eca969068da26ff3f8cb940bd875124b02f46992329b248953c8190906a8a638ec980e1f5ec72a70254796d5fb735f2cb315b026fa0 + checksum: 10c0/15bf8e1e183c1631687d40907e4330b1ae764f790fbdeedf1f2b5d75fece457a445a1a99c0ea8e8113612928e4dae32bfccd7a7a7da57555d6be893471478a7a languageName: node linkType: hard @@ -5358,11 +5670,11 @@ __metadata: linkType: hard "fastq@npm:^1.17.1, fastq@npm:^1.6.0": - version: 1.20.1 - resolution: "fastq@npm:1.20.1" + version: 1.19.1 + resolution: "fastq@npm:1.19.1" dependencies: reusify: "npm:^1.0.4" - checksum: 10c0/e5dd725884decb1f11e5c822221d76136f239d0236f176fab80b7b8f9e7619ae57e6b4e5b73defc21e6b9ef99437ee7b545cff8e6c2c337819633712fa9d352e + checksum: 10c0/ebc6e50ac7048daaeb8e64522a1ea7a26e92b3cee5cd1c7f2316cdca81ba543aa40a136b53891446ea5c3a67ec215fbaca87ad405f102dd97012f62916905630 languageName: node linkType: hard @@ -5414,29 +5726,29 @@ __metadata: languageName: node linkType: hard -"finalhandler@npm:~1.3.1": - version: 1.3.2 - resolution: "finalhandler@npm:1.3.2" +"finalhandler@npm:1.3.1": + version: 1.3.1 + resolution: "finalhandler@npm:1.3.1" dependencies: debug: "npm:2.6.9" encodeurl: "npm:~2.0.0" escape-html: "npm:~1.0.3" - on-finished: "npm:~2.4.1" + on-finished: "npm:2.4.1" parseurl: "npm:~1.3.3" - statuses: "npm:~2.0.2" + statuses: "npm:2.0.1" unpipe: "npm:~1.0.0" - checksum: 10c0/435a4fd65e4e4e4c71bb5474980090b73c353a123dd415583f67836bdd6516e528cf07298e219a82b94631dee7830eae5eece38d3c178073cf7df4e8c182f413 + checksum: 10c0/d38035831865a49b5610206a3a9a9aae4e8523cbbcd01175d0480ffbf1278c47f11d89be3ca7f617ae6d94f29cf797546a4619cd84dd109009ef33f12f69019f languageName: node linkType: hard "find-my-way@npm:^9.0.0": - version: 9.5.0 - resolution: "find-my-way@npm:9.5.0" + version: 9.3.0 + resolution: "find-my-way@npm:9.3.0" dependencies: fast-deep-equal: "npm:^3.1.3" fast-querystring: "npm:^1.0.0" safe-regex2: "npm:^5.0.0" - checksum: 10c0/a70cb80a296dbb57a16940fd0697a47dbe372d35a5096bc2a827d8d67f66c22244e308e599ec19bfee4be25910aaf1d9e157a82cad6deaf9cc9cd7460740daec + checksum: 10c0/f221bc0c70b2c2a6f9282fd3e0ac1911fcbb68ac718da043ddcefdec3b9d884a54d6ef1bf92e1b2ff83400e50f3c22141206a8ea3308bf0e9e37fd177843425d languageName: node linkType: hard @@ -5493,7 +5805,7 @@ __metadata: languageName: node linkType: hard -"fresh@npm:~0.5.2": +"fresh@npm:0.5.2": version: 0.5.2 resolution: "fresh@npm:0.5.2" checksum: 10c0/c6d27f3ed86cc5b601404822f31c900dd165ba63fff8152a3ef714e2012e7535027063bc67ded4cb5b3a49fa596495d46cacd9f47d6328459cf570f08b7d9e5a @@ -5719,13 +6031,13 @@ __metadata: linkType: hard "glob@npm:^13.0.0": - version: 13.0.6 - resolution: "glob@npm:13.0.6" + version: 13.0.0 + resolution: "glob@npm:13.0.0" dependencies: - minimatch: "npm:^10.2.2" - minipass: "npm:^7.1.3" - path-scurry: "npm:^2.0.2" - checksum: 10c0/269c236f11a9b50357fe7a8c6aadac667e01deb5242b19c84975628f05f4438d8ee1354bb62c5d6c10f37fd59911b54d7799730633a2786660d8c69f1d18120a + minimatch: "npm:^10.1.1" + minipass: "npm:^7.1.2" + path-scurry: "npm:^2.0.0" + checksum: 10c0/8e2f5821f3f7c312dd102e23a15b80c79e0837a9872784293ba2e15ec73b3f3749a49a42a31bfcb4e52c84820a474e92331c2eebf18819d20308f5c33876630a languageName: node linkType: hard @@ -5763,8 +6075,8 @@ __metadata: linkType: hard "handlebars@npm:^4.0.11": - version: 4.7.9 - resolution: "handlebars@npm:4.7.9" + version: 4.7.8 + resolution: "handlebars@npm:4.7.8" dependencies: minimist: "npm:^1.2.5" neo-async: "npm:^2.6.2" @@ -5776,7 +6088,7 @@ __metadata: optional: true bin: handlebars: bin/handlebars - checksum: 10c0/22f8105a7e68e81aff2662bb434edf05f757d21d850731d71cec886d69c10cd33d3c43e34b2892968ec62de8241611851d3d0674c8ef324ea3e01dc66262faa9 + checksum: 10c0/7aff423ea38a14bb379316f3857fe0df3c5d66119270944247f155ba1f08e07a92b340c58edaa00cfe985c21508870ee5183e0634dcb53dd405f35c93ef7f10d languageName: node linkType: hard @@ -6000,7 +6312,20 @@ __metadata: languageName: node linkType: hard -"http-errors@npm:^2.0.0, http-errors@npm:~2.0.0, http-errors@npm:~2.0.1": +"http-errors@npm:2.0.0": + version: 2.0.0 + resolution: "http-errors@npm:2.0.0" + dependencies: + depd: "npm:2.0.0" + inherits: "npm:2.0.4" + setprototypeof: "npm:1.2.0" + statuses: "npm:2.0.1" + toidentifier: "npm:1.0.1" + checksum: 10c0/fc6f2715fe188d091274b5ffc8b3657bd85c63e969daa68ccb77afb05b071a4b62841acb7a21e417b5539014dff2ebf9550f0b14a9ff126f2734a7c1387f8e19 + languageName: node + linkType: hard + +"http-errors@npm:^2.0.0": version: 2.0.1 resolution: "http-errors@npm:2.0.1" dependencies: @@ -6013,16 +6338,15 @@ __metadata: languageName: node linkType: hard -"http-errors@npm:~1.8.0": - version: 1.8.1 - resolution: "http-errors@npm:1.8.1" +"http-errors@npm:~1.6.2": + version: 1.6.3 + resolution: "http-errors@npm:1.6.3" dependencies: depd: "npm:~1.1.2" - inherits: "npm:2.0.4" - setprototypeof: "npm:1.2.0" - statuses: "npm:>= 1.5.0 < 2" - toidentifier: "npm:1.0.1" - checksum: 10c0/f01aeecd76260a6fe7f08e192fcbe9b2f39ed20fc717b852669a69930167053b01790998275c6297d44f435cf0e30edd50c05223d1bec9bc484e6cf35b2d6f43 + inherits: "npm:2.0.3" + setprototypeof: "npm:1.1.0" + statuses: "npm:>= 1.4.0 < 2" + checksum: 10c0/17ec4046ee974477778bfdd525936c254b872054703ec2caa4d6f099566b8adade636ae6aeeacb39302c5cd6e28fb407ebd937f500f5010d0b6850750414ff78 languageName: node linkType: hard @@ -6064,30 +6388,21 @@ __metadata: languageName: node linkType: hard -"iconv-lite@npm:0.6.3": - version: 0.6.3 - resolution: "iconv-lite@npm:0.6.3" +"iconv-lite@npm:0.4.24": + version: 0.4.24 + resolution: "iconv-lite@npm:0.4.24" dependencies: - safer-buffer: "npm:>= 2.1.2 < 3.0.0" - checksum: 10c0/98102bc66b33fcf5ac044099d1257ba0b7ad5e3ccd3221f34dd508ab4070edff183276221684e1e0555b145fce0850c9f7d2b60a9fcac50fbb4ea0d6e845a3b1 + safer-buffer: "npm:>= 2.1.2 < 3" + checksum: 10c0/c6886a24cc00f2a059767440ec1bc00d334a89f250db8e0f7feb4961c8727118457e27c495ba94d082e51d3baca378726cd110aaf7ded8b9bbfd6a44760cf1d4 languageName: node linkType: hard -"iconv-lite@npm:^0.7.2": - version: 0.7.2 - resolution: "iconv-lite@npm:0.7.2" +"iconv-lite@npm:0.6.3, iconv-lite@npm:^0.6.2": + version: 0.6.3 + resolution: "iconv-lite@npm:0.6.3" dependencies: safer-buffer: "npm:>= 2.1.2 < 3.0.0" - checksum: 10c0/3c228920f3bd307f56bf8363706a776f4a060eb042f131cd23855ceca962951b264d0997ab38a1ad340e1c5df8499ed26e1f4f0db6b2a2ad9befaff22f14b722 - languageName: node - linkType: hard - -"iconv-lite@npm:~0.4.24": - version: 0.4.24 - resolution: "iconv-lite@npm:0.4.24" - dependencies: - safer-buffer: "npm:>= 2.1.2 < 3" - checksum: 10c0/c6886a24cc00f2a059767440ec1bc00d334a89f250db8e0f7feb4961c8727118457e27c495ba94d082e51d3baca378726cd110aaf7ded8b9bbfd6a44760cf1d4 + checksum: 10c0/98102bc66b33fcf5ac044099d1257ba0b7ad5e3ccd3221f34dd508ab4070edff183276221684e1e0555b145fce0850c9f7d2b60a9fcac50fbb4ea0d6e845a3b1 languageName: node linkType: hard @@ -6112,6 +6427,13 @@ __metadata: languageName: node linkType: hard +"imurmurhash@npm:^0.1.4": + version: 0.1.4 + resolution: "imurmurhash@npm:0.1.4" + checksum: 10c0/8b51313850dd33605c6c9d3fd9638b714f4c4c40250cff658209f30d40da60f78992fb2df5dabee4acf589a6a82bbc79ad5486550754bd9ec4e3fc0d4a57d6a6 + languageName: node + linkType: hard + "indent-string@npm:^4.0.0": version: 4.0.0 resolution: "indent-string@npm:4.0.0" @@ -6119,6 +6441,13 @@ __metadata: languageName: node linkType: hard +"inherits@npm:2.0.3": + version: 2.0.3 + resolution: "inherits@npm:2.0.3" + checksum: 10c0/6e56402373149ea076a434072671f9982f5fad030c7662be0332122fe6c0fa490acb3cc1010d90b6eff8d640b1167d77674add52dfd1bb85d545cf29e80e73e7 + languageName: node + linkType: hard + "inherits@npm:2.0.4, inherits@npm:^2.0.1, inherits@npm:^2.0.3, inherits@npm:~2.0.3, inherits@npm:~2.0.4": version: 2.0.4 resolution: "inherits@npm:2.0.4" @@ -6173,9 +6502,9 @@ __metadata: linkType: hard "ipaddr.js@npm:^2.1.0": - version: 2.3.0 - resolution: "ipaddr.js@npm:2.3.0" - checksum: 10c0/084bab99e2f6875d7a62adc3325e1c64b038a12c9521e35fb967b5e263a8b3afb1b8884dd77c276092331f5d63298b767491e10997ef147c62da01b143780bbd + version: 2.2.0 + resolution: "ipaddr.js@npm:2.2.0" + checksum: 10c0/e4ee875dc1bd92ac9d27e06cfd87cdb63ca786ff9fd7718f1d4f7a8ef27db6e5d516128f52d2c560408cbb75796ac2f83ead669e73507c86282d45f84c5abbb6 languageName: node linkType: hard @@ -6565,11 +6894,11 @@ __metadata: linkType: hard "is-wsl@npm:^3.1.0": - version: 3.1.1 - resolution: "is-wsl@npm:3.1.1" + version: 3.1.0 + resolution: "is-wsl@npm:3.1.0" dependencies: is-inside-container: "npm:^1.0.0" - checksum: 10c0/7e5023522bfb8f27de4de960b0d82c4a8146c0bddb186529a3616d78b5bbbfc19ef0c5fc60d0b3a3cc0bf95a415fbdedc18454310ea3049587c879b07ace5107 + checksum: 10c0/d3317c11995690a32c362100225e22ba793678fe8732660c6de511ae71a0ff05b06980cf21f98a6bf40d7be0e9e9506f859abe00a1118287d63e53d0a3d06947 languageName: node linkType: hard @@ -6602,16 +6931,9 @@ __metadata: linkType: hard "isexe@npm:^3.1.1": - version: 3.1.5 - resolution: "isexe@npm:3.1.5" - checksum: 10c0/8be2973a09f2f804ea1f34bfccfd5ea219ef48083bdb12107fe5bcf96b3e36b85084409e1b09ddaf2fae8927fdd9f6d70d90baadb78caa1ca7c530935706c8a4 - languageName: node - linkType: hard - -"isexe@npm:^4.0.0": - version: 4.0.0 - resolution: "isexe@npm:4.0.0" - checksum: 10c0/5884815115bceac452877659a9c7726382531592f43dc29e5d48b7c4100661aed54018cb90bd36cb2eaeba521092570769167acbb95c18d39afdccbcca06c5ce + version: 3.1.1 + resolution: "isexe@npm:3.1.1" + checksum: 10c0/9ec257654093443eb0a528a9c8cbba9c0ca7616ccb40abd6dde7202734d96bb86e4ac0d764f0f8cd965856aacbff2f4ce23e730dc19dfb41e3b0d865ca6fdcc7 languageName: node linkType: hard @@ -6815,90 +7137,90 @@ __metadata: languageName: node linkType: hard -"lefthook-darwin-arm64@npm:2.1.5": - version: 2.1.5 - resolution: "lefthook-darwin-arm64@npm:2.1.5" +"lefthook-darwin-arm64@npm:2.1.4": + version: 2.1.4 + resolution: "lefthook-darwin-arm64@npm:2.1.4" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"lefthook-darwin-x64@npm:2.1.5": - version: 2.1.5 - resolution: "lefthook-darwin-x64@npm:2.1.5" +"lefthook-darwin-x64@npm:2.1.4": + version: 2.1.4 + resolution: "lefthook-darwin-x64@npm:2.1.4" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"lefthook-freebsd-arm64@npm:2.1.5": - version: 2.1.5 - resolution: "lefthook-freebsd-arm64@npm:2.1.5" +"lefthook-freebsd-arm64@npm:2.1.4": + version: 2.1.4 + resolution: "lefthook-freebsd-arm64@npm:2.1.4" conditions: os=freebsd & cpu=arm64 languageName: node linkType: hard -"lefthook-freebsd-x64@npm:2.1.5": - version: 2.1.5 - resolution: "lefthook-freebsd-x64@npm:2.1.5" +"lefthook-freebsd-x64@npm:2.1.4": + version: 2.1.4 + resolution: "lefthook-freebsd-x64@npm:2.1.4" conditions: os=freebsd & cpu=x64 languageName: node linkType: hard -"lefthook-linux-arm64@npm:2.1.5": - version: 2.1.5 - resolution: "lefthook-linux-arm64@npm:2.1.5" +"lefthook-linux-arm64@npm:2.1.4": + version: 2.1.4 + resolution: "lefthook-linux-arm64@npm:2.1.4" conditions: os=linux & cpu=arm64 languageName: node linkType: hard -"lefthook-linux-x64@npm:2.1.5": - version: 2.1.5 - resolution: "lefthook-linux-x64@npm:2.1.5" +"lefthook-linux-x64@npm:2.1.4": + version: 2.1.4 + resolution: "lefthook-linux-x64@npm:2.1.4" conditions: os=linux & cpu=x64 languageName: node linkType: hard -"lefthook-openbsd-arm64@npm:2.1.5": - version: 2.1.5 - resolution: "lefthook-openbsd-arm64@npm:2.1.5" +"lefthook-openbsd-arm64@npm:2.1.4": + version: 2.1.4 + resolution: "lefthook-openbsd-arm64@npm:2.1.4" conditions: os=openbsd & cpu=arm64 languageName: node linkType: hard -"lefthook-openbsd-x64@npm:2.1.5": - version: 2.1.5 - resolution: "lefthook-openbsd-x64@npm:2.1.5" +"lefthook-openbsd-x64@npm:2.1.4": + version: 2.1.4 + resolution: "lefthook-openbsd-x64@npm:2.1.4" conditions: os=openbsd & cpu=x64 languageName: node linkType: hard -"lefthook-windows-arm64@npm:2.1.5": - version: 2.1.5 - resolution: "lefthook-windows-arm64@npm:2.1.5" +"lefthook-windows-arm64@npm:2.1.4": + version: 2.1.4 + resolution: "lefthook-windows-arm64@npm:2.1.4" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"lefthook-windows-x64@npm:2.1.5": - version: 2.1.5 - resolution: "lefthook-windows-x64@npm:2.1.5" +"lefthook-windows-x64@npm:2.1.4": + version: 2.1.4 + resolution: "lefthook-windows-x64@npm:2.1.4" conditions: os=win32 & cpu=x64 languageName: node linkType: hard "lefthook@npm:^2.1.4": - version: 2.1.5 - resolution: "lefthook@npm:2.1.5" - dependencies: - lefthook-darwin-arm64: "npm:2.1.5" - lefthook-darwin-x64: "npm:2.1.5" - lefthook-freebsd-arm64: "npm:2.1.5" - lefthook-freebsd-x64: "npm:2.1.5" - lefthook-linux-arm64: "npm:2.1.5" - lefthook-linux-x64: "npm:2.1.5" - lefthook-openbsd-arm64: "npm:2.1.5" - lefthook-openbsd-x64: "npm:2.1.5" - lefthook-windows-arm64: "npm:2.1.5" - lefthook-windows-x64: "npm:2.1.5" + version: 2.1.4 + resolution: "lefthook@npm:2.1.4" + dependencies: + lefthook-darwin-arm64: "npm:2.1.4" + lefthook-darwin-x64: "npm:2.1.4" + lefthook-freebsd-arm64: "npm:2.1.4" + lefthook-freebsd-x64: "npm:2.1.4" + lefthook-linux-arm64: "npm:2.1.4" + lefthook-linux-x64: "npm:2.1.4" + lefthook-openbsd-arm64: "npm:2.1.4" + lefthook-openbsd-x64: "npm:2.1.4" + lefthook-windows-arm64: "npm:2.1.4" + lefthook-windows-x64: "npm:2.1.4" dependenciesMeta: lefthook-darwin-arm64: optional: true @@ -6922,7 +7244,7 @@ __metadata: optional: true bin: lefthook: bin/index.js - checksum: 10c0/534c0e3b62e5032d6b61031b695aa562932e5cb147d124884fa66d12d1849a9b2843ae434fc2846b06d2f59a3e2d0d4fb0c099f2f972a93e55c331f8a50607f9 + checksum: 10c0/8238c33a00a5770e02bf2b12c6191994f05a785339a4ac2e994c2027209b49af8f7e9d38e4f9ca6d16a6815c8141c9f7d69a162571d632ee746f0b7a27e06047 languageName: node linkType: hard @@ -7104,10 +7426,10 @@ __metadata: languageName: node linkType: hard -"lodash-es@npm:4.18.1": - version: 4.18.1 - resolution: "lodash-es@npm:4.18.1" - checksum: 10c0/35d4dcf87ef07f8d090f409447575800108057e360b445f590d0d25d09e3d1e33a163d2fc100d4d072b0f901d5e2fc533cd7c4bfd8eeb38a06abec693823c8b8 +"lodash-es@npm:4.17.23": + version: 4.17.23 + resolution: "lodash-es@npm:4.17.23" + checksum: 10c0/3150fb6660c14c7a6b5f23bd11597d884b140c0e862a17fdb415aaa5ef7741523182904a6b7929f04e5f60a11edb5a79499eb448734381c99ffb3c4734beeddd languageName: node linkType: hard @@ -7172,9 +7494,9 @@ __metadata: linkType: hard "lru-cache@npm:^11.0.0, lru-cache@npm:^11.1.0, lru-cache@npm:^11.2.1": - version: 11.3.2 - resolution: "lru-cache@npm:11.3.2" - checksum: 10c0/1981baec397c1e7875ac7456ea123e1f8016b878bf3a88b083bbe3f791ba77212d0507751a069f3d4c12441d70ca255d150c2a1c489d3cbe5ed6b8c625bb1be2 + version: 11.2.2 + resolution: "lru-cache@npm:11.2.2" + checksum: 10c0/72d7831bbebc85e2bdefe01047ee5584db69d641c48d7a509e86f66f6ee111b30af7ec3bd68a967d47b69a4b1fa8bbf3872630bd06a63b6735e6f0a5f1c8e83d languageName: node linkType: hard @@ -7213,12 +7535,10 @@ __metadata: linkType: hard "make-fetch-happen@npm:^15.0.0": - version: 15.0.5 - resolution: "make-fetch-happen@npm:15.0.5" + version: 15.0.3 + resolution: "make-fetch-happen@npm:15.0.3" dependencies: - "@gar/promise-retry": "npm:^1.0.0" "@npmcli/agent": "npm:^4.0.0" - "@npmcli/redact": "npm:^4.0.0" cacache: "npm:^20.0.1" http-cache-semantics: "npm:^4.1.1" minipass: "npm:^7.0.2" @@ -7227,8 +7547,9 @@ __metadata: minipass-pipeline: "npm:^1.2.4" negotiator: "npm:^1.0.0" proc-log: "npm:^6.0.0" + promise-retry: "npm:^2.0.1" ssri: "npm:^13.0.0" - checksum: 10c0/527580eb5e5476e6ad07a4e3bd017d13e935f4be815674b442081ae5a721c13d3af5715006619e6be79a85723067e047f83a0c9e699f41d8cec43609a8de4f7b + checksum: 10c0/525f74915660be60b616bcbd267c4a5b59481b073ba125e45c9c3a041bb1a47a2bd0ae79d028eb6f5f95bf9851a4158423f5068539c3093621abb64027e8e461 languageName: node linkType: hard @@ -8072,7 +8393,7 @@ __metadata: languageName: node linkType: hard -"mime-types@npm:^2.1.12, mime-types@npm:~2.1.19, mime-types@npm:~2.1.24, mime-types@npm:~2.1.34, mime-types@npm:~2.1.35": +"mime-types@npm:^2.1.12, mime-types@npm:~2.1.17, mime-types@npm:~2.1.19, mime-types@npm:~2.1.24, mime-types@npm:~2.1.34": version: 2.1.35 resolution: "mime-types@npm:2.1.35" dependencies: @@ -8129,21 +8450,21 @@ __metadata: languageName: node linkType: hard -"minimatch@npm:^10.2.2": - version: 10.2.5 - resolution: "minimatch@npm:10.2.5" +"minimatch@npm:^10.1.1": + version: 10.1.1 + resolution: "minimatch@npm:10.1.1" dependencies: - brace-expansion: "npm:^5.0.5" - checksum: 10c0/6bb058bd6324104b9ec2f763476a35386d05079c1f5fe4fbf1f324a25237cd4534d6813ecd71f48208f4e635c1221899bef94c3c89f7df55698fe373aaae20fd + "@isaacs/brace-expansion": "npm:^5.0.0" + checksum: 10c0/c85d44821c71973d636091fddbfbffe62370f5ee3caf0241c5b60c18cd289e916200acb2361b7e987558cd06896d153e25d505db9fc1e43e6b4b6752e2702902 languageName: node linkType: hard "minimatch@npm:^9.0.0, minimatch@npm:^9.0.4": - version: 9.0.9 - resolution: "minimatch@npm:9.0.9" + version: 9.0.5 + resolution: "minimatch@npm:9.0.5" dependencies: - brace-expansion: "npm:^2.0.2" - checksum: 10c0/0b6a58530dbb00361745aa6c8cffaba4c90f551afe7c734830bd95fd88ebf469dd7355a027824ea1d09e37181cfeb0a797fb17df60c15ac174303ac110eb7e86 + brace-expansion: "npm:^2.0.1" + checksum: 10c0/de96cf5e35bdf0eab3e2c853522f98ffbe9a36c37797778d2665231ec1f20a9447a7e567cb640901f89e4daaa95ae5d70c65a9e8aa2bb0019b6facbc3c0575ed languageName: node linkType: hard @@ -8164,26 +8485,26 @@ __metadata: linkType: hard "minipass-fetch@npm:^5.0.0": - version: 5.0.2 - resolution: "minipass-fetch@npm:5.0.2" + version: 5.0.0 + resolution: "minipass-fetch@npm:5.0.0" dependencies: - iconv-lite: "npm:^0.7.2" + encoding: "npm:^0.1.13" minipass: "npm:^7.0.3" - minipass-sized: "npm:^2.0.0" + minipass-sized: "npm:^1.0.3" minizlib: "npm:^3.0.1" dependenciesMeta: - iconv-lite: + encoding: optional: true - checksum: 10c0/ce4ab9f21cfabaead2097d95dd33f485af8072fbc6b19611bce694965393453a1639d641c2bcf1c48f2ea7d41ea7fab8278373f1d0bee4e63b0a5b2cdd0ef649 + checksum: 10c0/9443aab5feab190972f84b64116e54e58dd87a58e62399cae0a4a7461b80568281039b7c3a38ba96453431ebc799d1e26999e548540156216729a4967cd5ef06 languageName: node linkType: hard "minipass-flush@npm:^1.0.5": - version: 1.0.7 - resolution: "minipass-flush@npm:1.0.7" + version: 1.0.5 + resolution: "minipass-flush@npm:1.0.5" dependencies: minipass: "npm:^3.0.0" - checksum: 10c0/960915c02aa0991662c37c404517dd93708d17f96533b2ca8c1e776d158715d8107c5ced425ffc61674c167d93607f07f48a83c139ce1057f8781e5dfb4b90c2 + checksum: 10c0/2a51b63feb799d2bb34669205eee7c0eaf9dce01883261a5b77410c9408aa447e478efd191b4de6fc1101e796ff5892f8443ef20d9544385819093dbb32d36bd languageName: node linkType: hard @@ -8196,12 +8517,12 @@ __metadata: languageName: node linkType: hard -"minipass-sized@npm:^2.0.0": - version: 2.0.0 - resolution: "minipass-sized@npm:2.0.0" +"minipass-sized@npm:^1.0.3": + version: 1.0.3 + resolution: "minipass-sized@npm:1.0.3" dependencies: - minipass: "npm:^7.1.2" - checksum: 10c0/f9201696a6f6d68610d04c9c83e3d2e5cb9c026aae1c8cbf7e17f386105cb79c1bb088dbc21bf0b1eb4f3fb5df384fd1e7aa3bf1f33868c416ae8c8a92679db8 + minipass: "npm:^3.0.0" + checksum: 10c0/298f124753efdc745cfe0f2bdfdd81ba25b9f4e753ca4a2066eb17c821f25d48acea607dfc997633ee5bf7b6dfffb4eee4f2051eb168663f0b99fad2fa4829cb languageName: node linkType: hard @@ -8214,7 +8535,7 @@ __metadata: languageName: node linkType: hard -"minipass@npm:^5.0.0 || ^6.0.2 || ^7.0.0, minipass@npm:^7.0.2, minipass@npm:^7.0.3, minipass@npm:^7.0.4, minipass@npm:^7.1.2, minipass@npm:^7.1.3": +"minipass@npm:^5.0.0 || ^6.0.2 || ^7.0.0, minipass@npm:^7.0.2, minipass@npm:^7.0.3, minipass@npm:^7.0.4, minipass@npm:^7.1.2": version: 7.1.3 resolution: "minipass@npm:7.1.3" checksum: 10c0/539da88daca16533211ea5a9ee98dc62ff5742f531f54640dd34429e621955e91cc280a91a776026264b7f9f6735947629f920944e9c1558369e8bf22eb33fbb @@ -8282,8 +8603,8 @@ __metadata: linkType: hard "node-gyp@npm:latest": - version: 12.2.0 - resolution: "node-gyp@npm:12.2.0" + version: 12.1.0 + resolution: "node-gyp@npm:12.1.0" dependencies: env-paths: "npm:^2.2.0" exponential-backoff: "npm:^3.1.1" @@ -8292,19 +8613,19 @@ __metadata: nopt: "npm:^9.0.0" proc-log: "npm:^6.0.0" semver: "npm:^7.3.5" - tar: "npm:^7.5.4" + tar: "npm:^7.5.2" tinyglobby: "npm:^0.2.12" which: "npm:^6.0.0" bin: node-gyp: bin/node-gyp.js - checksum: 10c0/3ed046746a5a7d90950cd8b0547332b06598443f31fe213ef4332a7174c7b7d259e1704835feda79b87d3f02e59d7791842aac60642ede4396ab25fdf0f8f759 + checksum: 10c0/f43efea8aaf0beb6b2f6184e533edad779b2ae38062953e21951f46221dd104006cc574154f2ad4a135467a5aae92c49e84ef289311a82e08481c5df0e8dc495 languageName: node linkType: hard -"node-releases@npm:^2.0.36": - version: 2.0.37 - resolution: "node-releases@npm:2.0.37" - checksum: 10c0/306df89190b3225d0cb001260de52f0befd225a782ec85311ce97b0aa3b2e22f5e4e4c00395c6dc9bc9ef440c64723f6205fe1e27d32b8dd1d140891fbadf901 +"node-releases@npm:^2.0.27": + version: 2.0.27 + resolution: "node-releases@npm:2.0.27" + checksum: 10c0/f1e6583b7833ea81880627748d28a3a7ff5703d5409328c216ae57befbced10ce2c991bea86434e8ec39003bd017f70481e2e5f8c1f7e0a7663241f81d6e00e2 languageName: node linkType: hard @@ -8398,9 +8719,9 @@ __metadata: linkType: hard "nwsapi@npm:^2.2.16": - version: 2.2.23 - resolution: "nwsapi@npm:2.2.23" - checksum: 10c0/e44bfc9246baf659581206ed716d291a1905185247795fb8a302cb09315c943a31023b4ac4d026a5eaf32b2def51d77b3d0f9ebf4f3d35f70e105fcb6447c76e + version: 2.2.22 + resolution: "nwsapi@npm:2.2.22" + checksum: 10c0/b6a0e5ea6754aacfdfe551c8c0f1b374eaf94d48b0a4e7eac666f879ecbc1892ef1d7c457e9b02eefad3fa1323ea1faebcba533eeab6582e24c9c503411bf879 languageName: node linkType: hard @@ -8446,7 +8767,7 @@ __metadata: languageName: node linkType: hard -"on-finished@npm:~2.4.1": +"on-finished@npm:2.4.1": version: 2.4.1 resolution: "on-finished@npm:2.4.1" dependencies: @@ -8659,7 +8980,7 @@ __metadata: languageName: node linkType: hard -"parseurl@npm:~1.3.3": +"parseurl@npm:~1.3.2, parseurl@npm:~1.3.3": version: 1.3.3 resolution: "parseurl@npm:1.3.3" checksum: 10c0/90dd4760d6f6174adb9f20cf0965ae12e23879b5f5464f38e92fce8073354341e4b3b76fa3d878351efe7d01e617121955284cfd002ab087fba1a0726ec0b4f5 @@ -8683,13 +9004,20 @@ __metadata: languageName: node linkType: hard -"path-scurry@npm:^2.0.2": - version: 2.0.2 - resolution: "path-scurry@npm:2.0.2" +"path-scurry@npm:^2.0.0": + version: 2.0.1 + resolution: "path-scurry@npm:2.0.1" dependencies: lru-cache: "npm:^11.0.0" minipass: "npm:^7.1.2" - checksum: 10c0/b35ad37cf6557a87fd057121ce2be7695380c9138d93e87ae928609da259ea0a170fac6f3ef1eb3ece8a068e8b7f2f3adf5bb2374cf4d4a57fe484954fcc9482 + checksum: 10c0/2a16ed0e81fbc43513e245aa5763354e25e787dab0d539581a6c3f0f967461a159ed6236b2559de23aa5b88e7dc32b469b6c47568833dd142a4b24b4f5cd2620 + languageName: node + linkType: hard + +"path-to-regexp@npm:0.1.12": + version: 0.1.12 + resolution: "path-to-regexp@npm:0.1.12" + checksum: 10c0/1c6ff10ca169b773f3bba943bbc6a07182e332464704572962d277b900aeee81ac6aa5d060ff9e01149636c30b1f63af6e69dd7786ba6e0ddb39d4dee1f0645b languageName: node linkType: hard @@ -8700,13 +9028,6 @@ __metadata: languageName: node linkType: hard -"path-to-regexp@npm:~0.1.12": - version: 0.1.13 - resolution: "path-to-regexp@npm:0.1.13" - checksum: 10c0/1cae3921739c154a8926e136185a10c916f79a249b9072a5001b266d96e193860ca03867e8e8cc808b786862d750f427ed93686bc259355442c3407a62deab1a - languageName: node - linkType: hard - "pathe@npm:^1.1.2": version: 1.1.2 resolution: "pathe@npm:1.1.2" @@ -8754,9 +9075,9 @@ __metadata: linkType: hard "picomatch@npm:^2.0.4, picomatch@npm:^2.2.1, picomatch@npm:^2.3.1": - version: 2.3.2 - resolution: "picomatch@npm:2.3.2" - checksum: 10c0/a554d1709e59be97d1acb9eaedbbc700a5c03dbd4579807baed95100b00420bc729335440ef15004ae2378984e2487a7c1cebd743cfdb72b6fa9ab69223c0d61 + version: 2.3.1 + resolution: "picomatch@npm:2.3.1" + checksum: 10c0/26c02b8d06f03206fc2ab8d16f19960f2ff9e81a658f831ecb656d8f17d9edc799e8364b1f4a7873e89d9702dff96204be0fa26fe4181f6843f040f819dac4be languageName: node linkType: hard @@ -8807,9 +9128,9 @@ __metadata: linkType: hard "pino-std-serializers@npm:^7.0.0": - version: 7.1.0 - resolution: "pino-std-serializers@npm:7.1.0" - checksum: 10c0/d158615aa93ebdeac2d3912ad4227a23ef78cf14229e886214771f581e96eff312257f2d6368c75b2fbf53e5024eda475d81305014f4ed1a6d5eeab9107f6ef0 + version: 7.0.0 + resolution: "pino-std-serializers@npm:7.0.0" + checksum: 10c0/73e694d542e8de94445a03a98396cf383306de41fd75ecc07085d57ed7a57896198508a0dec6eefad8d701044af21eb27253ccc352586a03cf0d4a0bd25b4133 languageName: node linkType: hard @@ -8893,7 +9214,7 @@ __metadata: languageName: node linkType: hard -"postcss@npm:^8.5.6, postcss@npm:^8.5.8": +"postcss@npm:^8.5.6": version: 8.5.10 resolution: "postcss@npm:8.5.10" dependencies: @@ -8904,6 +9225,17 @@ __metadata: languageName: node linkType: hard +"postcss@npm:^8.5.8": + version: 8.5.8 + resolution: "postcss@npm:8.5.8" + dependencies: + nanoid: "npm:^3.3.11" + picocolors: "npm:^1.1.1" + source-map-js: "npm:^1.2.1" + checksum: 10c0/dd918f7127ee7c60a0295bae2e72b3787892296e1d1c3c564d7a2a00c68d8df83cadc3178491259daa19ccc54804fb71ed8c937c6787e08d8bd4bedf8d17044c + languageName: node + linkType: hard + "powershell-utils@npm:^0.1.0": version: 0.1.0 resolution: "powershell-utils@npm:0.1.0" @@ -8912,11 +9244,11 @@ __metadata: linkType: hard "prettier@npm:^3.6.2": - version: 3.8.1 - resolution: "prettier@npm:3.8.1" + version: 3.6.2 + resolution: "prettier@npm:3.6.2" bin: prettier: bin/prettier.cjs - checksum: 10c0/33169b594009e48f570471271be7eac7cdcf88a209eed39ac3b8d6d78984039bfa9132f82b7e6ba3b06711f3bfe0222a62a1bfb87c43f50c25a83df1b78a2c42 + checksum: 10c0/488cb2f2b99ec13da1e50074912870217c11edaddedeadc649b1244c749d15ba94e846423d062e2c4c9ae683e2d65f754de28889ba06e697ac4f988d44f45812 languageName: node linkType: hard @@ -8935,9 +9267,9 @@ __metadata: linkType: hard "proc-log@npm:^6.0.0": - version: 6.1.0 - resolution: "proc-log@npm:6.1.0" - checksum: 10c0/4f178d4062733ead9d71a9b1ab24ebcecdfe2250916a5b1555f04fe2eda972a0ec76fbaa8df1ad9c02707add6749219d118a4fc46dc56bdfe4dde4b47d80bb82 + version: 6.0.0 + resolution: "proc-log@npm:6.0.0" + checksum: 10c0/40c5e2b4c55e395a3bd72e38cba9c26e58598a1f4844fa6a115716d5231a0919f46aa8e351147035d91583ad39a794593615078c948bc001fe3beb99276be776 languageName: node linkType: hard @@ -9020,12 +9352,12 @@ __metadata: linkType: hard "pump@npm:^3.0.0": - version: 3.0.4 - resolution: "pump@npm:3.0.4" + version: 3.0.3 + resolution: "pump@npm:3.0.3" dependencies: end-of-stream: "npm:^1.1.0" once: "npm:^1.3.1" - checksum: 10c0/2780e66b5471c19e3e3e1063b84f3f6a3a08367f24c5ed552f98cd5901e6ada27c7ad6495d4244f553fd03b01884a4561933064f053f47c8994d84fd352768ea + checksum: 10c0/ada5cdf1d813065bbc99aa2c393b8f6beee73b5de2890a8754c9f488d7323ffd2ca5f5a0943b48934e3fcbd97637d0337369c3c631aeb9614915db629f1c75c9 languageName: node linkType: hard @@ -9047,7 +9379,16 @@ __metadata: languageName: node linkType: hard -"qs@npm:~6.14.0, qs@npm:~6.14.1": +"qs@npm:6.13.0": + version: 6.13.0 + resolution: "qs@npm:6.13.0" + dependencies: + side-channel: "npm:^1.0.6" + checksum: 10c0/62372cdeec24dc83a9fb240b7533c0fdcf0c5f7e0b83343edd7310f0ab4c8205a5e7c56406531f2e47e1b4878a3821d652be4192c841de5b032ca83619d8f860 + languageName: node + linkType: hard + +"qs@npm:~6.14.1": version: 6.14.2 resolution: "qs@npm:6.14.2" dependencies: @@ -9084,15 +9425,15 @@ __metadata: languageName: node linkType: hard -"raw-body@npm:~2.5.3": - version: 2.5.3 - resolution: "raw-body@npm:2.5.3" +"raw-body@npm:2.5.2": + version: 2.5.2 + resolution: "raw-body@npm:2.5.2" dependencies: - bytes: "npm:~3.1.2" - http-errors: "npm:~2.0.1" - iconv-lite: "npm:~0.4.24" - unpipe: "npm:~1.0.0" - checksum: 10c0/449844344fc90547fb994383a494b83300e4f22199f146a79f68d78a199a8f2a923ea9fd29c3be979bfd50291a3884733619ffc15ba02a32e703b612f8d3f74a + bytes: "npm:3.1.2" + http-errors: "npm:2.0.0" + iconv-lite: "npm:0.4.24" + unpipe: "npm:1.0.0" + checksum: 10c0/b201c4b66049369a60e766318caff5cb3cc5a900efd89bdac431463822d976ad0670912c931fdbdcf5543207daf6f6833bca57aa116e1661d2ea91e12ca692c4 languageName: node linkType: hard @@ -9532,6 +9873,7 @@ __metadata: "@types/react": "npm:^19.2.14" "@vitejs/plugin-react": "npm:^6.0.1" "@vitest/browser-playwright": "npm:^4.1.2" + algoliasearch: "npm:^5.50.1" auto-image-converter: "npm:^2.2.0" chokidar: "npm:^4.0.3" cypress: "npm:^15.13.1" @@ -9719,34 +10061,31 @@ __metadata: linkType: hard "rollup@npm:^4.43.0": - version: 4.60.1 - resolution: "rollup@npm:4.60.1" - dependencies: - "@rollup/rollup-android-arm-eabi": "npm:4.60.1" - "@rollup/rollup-android-arm64": "npm:4.60.1" - "@rollup/rollup-darwin-arm64": "npm:4.60.1" - "@rollup/rollup-darwin-x64": "npm:4.60.1" - "@rollup/rollup-freebsd-arm64": "npm:4.60.1" - "@rollup/rollup-freebsd-x64": "npm:4.60.1" - "@rollup/rollup-linux-arm-gnueabihf": "npm:4.60.1" - "@rollup/rollup-linux-arm-musleabihf": "npm:4.60.1" - "@rollup/rollup-linux-arm64-gnu": "npm:4.60.1" - "@rollup/rollup-linux-arm64-musl": "npm:4.60.1" - "@rollup/rollup-linux-loong64-gnu": "npm:4.60.1" - "@rollup/rollup-linux-loong64-musl": "npm:4.60.1" - "@rollup/rollup-linux-ppc64-gnu": "npm:4.60.1" - "@rollup/rollup-linux-ppc64-musl": "npm:4.60.1" - "@rollup/rollup-linux-riscv64-gnu": "npm:4.60.1" - "@rollup/rollup-linux-riscv64-musl": "npm:4.60.1" - "@rollup/rollup-linux-s390x-gnu": "npm:4.60.1" - "@rollup/rollup-linux-x64-gnu": "npm:4.60.1" - "@rollup/rollup-linux-x64-musl": "npm:4.60.1" - "@rollup/rollup-openbsd-x64": "npm:4.60.1" - "@rollup/rollup-openharmony-arm64": "npm:4.60.1" - "@rollup/rollup-win32-arm64-msvc": "npm:4.60.1" - "@rollup/rollup-win32-ia32-msvc": "npm:4.60.1" - "@rollup/rollup-win32-x64-gnu": "npm:4.60.1" - "@rollup/rollup-win32-x64-msvc": "npm:4.60.1" + version: 4.53.3 + resolution: "rollup@npm:4.53.3" + dependencies: + "@rollup/rollup-android-arm-eabi": "npm:4.53.3" + "@rollup/rollup-android-arm64": "npm:4.53.3" + "@rollup/rollup-darwin-arm64": "npm:4.53.3" + "@rollup/rollup-darwin-x64": "npm:4.53.3" + "@rollup/rollup-freebsd-arm64": "npm:4.53.3" + "@rollup/rollup-freebsd-x64": "npm:4.53.3" + "@rollup/rollup-linux-arm-gnueabihf": "npm:4.53.3" + "@rollup/rollup-linux-arm-musleabihf": "npm:4.53.3" + "@rollup/rollup-linux-arm64-gnu": "npm:4.53.3" + "@rollup/rollup-linux-arm64-musl": "npm:4.53.3" + "@rollup/rollup-linux-loong64-gnu": "npm:4.53.3" + "@rollup/rollup-linux-ppc64-gnu": "npm:4.53.3" + "@rollup/rollup-linux-riscv64-gnu": "npm:4.53.3" + "@rollup/rollup-linux-riscv64-musl": "npm:4.53.3" + "@rollup/rollup-linux-s390x-gnu": "npm:4.53.3" + "@rollup/rollup-linux-x64-gnu": "npm:4.53.3" + "@rollup/rollup-linux-x64-musl": "npm:4.53.3" + "@rollup/rollup-openharmony-arm64": "npm:4.53.3" + "@rollup/rollup-win32-arm64-msvc": "npm:4.53.3" + "@rollup/rollup-win32-ia32-msvc": "npm:4.53.3" + "@rollup/rollup-win32-x64-gnu": "npm:4.53.3" + "@rollup/rollup-win32-x64-msvc": "npm:4.53.3" "@types/estree": "npm:1.0.8" fsevents: "npm:~2.3.2" dependenciesMeta: @@ -9772,12 +10111,8 @@ __metadata: optional: true "@rollup/rollup-linux-loong64-gnu": optional: true - "@rollup/rollup-linux-loong64-musl": - optional: true "@rollup/rollup-linux-ppc64-gnu": optional: true - "@rollup/rollup-linux-ppc64-musl": - optional: true "@rollup/rollup-linux-riscv64-gnu": optional: true "@rollup/rollup-linux-riscv64-musl": @@ -9788,8 +10123,6 @@ __metadata: optional: true "@rollup/rollup-linux-x64-musl": optional: true - "@rollup/rollup-openbsd-x64": - optional: true "@rollup/rollup-openharmony-arm64": optional: true "@rollup/rollup-win32-arm64-msvc": @@ -9804,7 +10137,7 @@ __metadata: optional: true bin: rollup: dist/bin/rollup - checksum: 10c0/48d3f2216b5533639b007e6756e2275c7f594e45adee21ce03674aa2e004406c661f8b86c7a0b471c9e889c6a9efbb29240ca0b7673c50e391406c490c309833 + checksum: 10c0/a21305aac72013083bd0dec92162b0f7f24cacf57c876ca601ec76e892895952c9ea592c1c07f23b8c125f7979c2b17f7fb565e386d03ee4c1f0952ac4ab0d75 languageName: node linkType: hard @@ -9889,13 +10222,11 @@ __metadata: linkType: hard "safe-regex2@npm:^5.0.0": - version: 5.1.0 - resolution: "safe-regex2@npm:5.1.0" + version: 5.0.0 + resolution: "safe-regex2@npm:5.0.0" dependencies: ret: "npm:~0.5.0" - bin: - safe-regex2: bin/safe-regex2.js - checksum: 10c0/9ee1e1c0336dbbf7a9cc182766d193371cff8adc4e390d9d709a5fb72fe0dc42500efc77eb5a266d8feb442ae3872a189021e73e7286420b4ad65db9896977b0 + checksum: 10c0/83d5b1b60a5a97cb71a6e615518ec4a47761b3600aba389089be59a417498185250db2368080afc2f5e91237d68809c6c634b97a2e1cc8bd56a4c7eef2eeb6cf languageName: node linkType: hard @@ -9953,59 +10284,59 @@ __metadata: linkType: hard "semver@npm:^7.1.1, semver@npm:^7.3.5, semver@npm:^7.3.7, semver@npm:^7.5.3, semver@npm:^7.6.0, semver@npm:^7.7.3": - version: 7.7.4 - resolution: "semver@npm:7.7.4" + version: 7.7.3 + resolution: "semver@npm:7.7.3" bin: semver: bin/semver.js - checksum: 10c0/5215ad0234e2845d4ea5bb9d836d42b03499546ddafb12075566899fc617f68794bb6f146076b6881d755de17d6c6cc73372555879ec7dce2c2feee947866ad2 + checksum: 10c0/4afe5c986567db82f44c8c6faef8fe9df2a9b1d98098fc1721f57c696c4c21cebd572f297fc21002f81889492345b8470473bc6f4aff5fb032a6ea59ea2bc45e languageName: node linkType: hard -"send@npm:~0.19.0, send@npm:~0.19.1": - version: 0.19.2 - resolution: "send@npm:0.19.2" +"send@npm:0.19.0": + version: 0.19.0 + resolution: "send@npm:0.19.0" dependencies: debug: "npm:2.6.9" depd: "npm:2.0.0" destroy: "npm:1.2.0" - encodeurl: "npm:~2.0.0" + encodeurl: "npm:~1.0.2" escape-html: "npm:~1.0.3" etag: "npm:~1.8.1" - fresh: "npm:~0.5.2" - http-errors: "npm:~2.0.1" + fresh: "npm:0.5.2" + http-errors: "npm:2.0.0" mime: "npm:1.6.0" ms: "npm:2.1.3" - on-finished: "npm:~2.4.1" + on-finished: "npm:2.4.1" range-parser: "npm:~1.2.1" - statuses: "npm:~2.0.2" - checksum: 10c0/20c2389fe0fdf3fc499938cac598bc32272287e993c4960717381a10de8550028feadfb9076f959a3a3ebdea42e1f690e116f0d16468fa56b9fd41866d3dc267 + statuses: "npm:2.0.1" + checksum: 10c0/ea3f8a67a8f0be3d6bf9080f0baed6d2c51d11d4f7b4470de96a5029c598a7011c497511ccc28968b70ef05508675cebff27da9151dd2ceadd60be4e6cf845e3 languageName: node linkType: hard "serve-index@npm:^1.9.1": - version: 1.9.2 - resolution: "serve-index@npm:1.9.2" + version: 1.9.1 + resolution: "serve-index@npm:1.9.1" dependencies: - accepts: "npm:~1.3.8" + accepts: "npm:~1.3.4" batch: "npm:0.6.1" debug: "npm:2.6.9" escape-html: "npm:~1.0.3" - http-errors: "npm:~1.8.0" - mime-types: "npm:~2.1.35" - parseurl: "npm:~1.3.3" - checksum: 10c0/b4e48da75c9262cfcf6a4707748a33a127f6c3cd3a095782c22312c4915545b7695071fedc8f5717bae165e6e63053cd963847013b1f1e984213f07186f78a74 + http-errors: "npm:~1.6.2" + mime-types: "npm:~2.1.17" + parseurl: "npm:~1.3.2" + checksum: 10c0/a666471a24196f74371edf2c3c7bcdd82adbac52f600804508754b5296c3567588bf694258b19e0cb23a567acfa20d9721bfdaed3286007b81f9741ada8a3a9c languageName: node linkType: hard -"serve-static@npm:~1.16.2": - version: 1.16.3 - resolution: "serve-static@npm:1.16.3" +"serve-static@npm:1.16.2": + version: 1.16.2 + resolution: "serve-static@npm:1.16.2" dependencies: encodeurl: "npm:~2.0.0" escape-html: "npm:~1.0.3" parseurl: "npm:~1.3.3" - send: "npm:~0.19.1" - checksum: 10c0/36320397a073c71bedf58af48a4a100fe6d93f07459af4d6f08b9a7217c04ce2a4939e0effd842dc7bece93ffcd59eb52f58c4fff2a8e002dc29ae6b219cd42b + send: "npm:0.19.0" + checksum: 10c0/528fff6f5e12d0c5a391229ad893910709bc51b5705962b09404a1d813857578149b8815f35d3ee5752f44cd378d0f31669d4b1d7e2d11f41e08283d5134bd1f languageName: node linkType: hard @@ -10053,6 +10384,13 @@ __metadata: languageName: node linkType: hard +"setprototypeof@npm:1.1.0": + version: 1.1.0 + resolution: "setprototypeof@npm:1.1.0" + checksum: 10c0/a77b20876689c6a89c3b42f0c3596a9cae02f90fc902570cbd97198e9e8240382086c9303ad043e88cee10f61eae19f1004e51d885395a1e9bf49f9ebed12872 + languageName: node + linkType: hard + "setprototypeof@npm:1.2.0, setprototypeof@npm:~1.2.0": version: 1.2.0 resolution: "setprototypeof@npm:1.2.0" @@ -10195,7 +10533,7 @@ __metadata: languageName: node linkType: hard -"side-channel@npm:^1.1.0": +"side-channel@npm:^1.0.6, side-channel@npm:^1.1.0": version: 1.1.0 resolution: "side-channel@npm:1.1.0" dependencies: @@ -10291,11 +10629,11 @@ __metadata: linkType: hard "sonic-boom@npm:^4.0.1": - version: 4.2.1 - resolution: "sonic-boom@npm:4.2.1" + version: 4.2.0 + resolution: "sonic-boom@npm:4.2.0" dependencies: atomic-sleep: "npm:^1.0.0" - checksum: 10c0/f374e9c3dfe194d706d8ef8aed4e28bc10638f9952fd19bcbddf2cef05d53334ad9e9dca3e01e24e88dd88fb278c6b8c5b2ae5002494b289c4914aaea3d9eae9 + checksum: 10c0/ae897e6c2cd6d3cb7cdcf608bc182393b19c61c9413a85ce33ffd25891485589f39bece0db1de24381d0a38fc03d08c9862ded0c60f184f1b852f51f97af9684 languageName: node linkType: hard @@ -10355,9 +10693,9 @@ __metadata: linkType: hard "spdx-license-ids@npm:^3.0.0": - version: 3.0.23 - resolution: "spdx-license-ids@npm:3.0.23" - checksum: 10c0/8495620f6f2a237749cce922ea2d593a66f7885c301b1a0f5542183e7041182f27f616a8f13345cefdea0c9b3e0899328e0aa8cec100cf4f3fac4bb3bd975515 + version: 3.0.22 + resolution: "spdx-license-ids@npm:3.0.22" + checksum: 10c0/4a85e44c2ccfc06eebe63239193f526508ebec1abc7cf7bca8ee43923755636234395447c2c87f40fb672cf580a9c8e684513a676bfb2da3d38a4983684bbb38 languageName: node linkType: hard @@ -10390,11 +10728,11 @@ __metadata: linkType: hard "ssri@npm:^13.0.0": - version: 13.0.1 - resolution: "ssri@npm:13.0.1" + version: 13.0.0 + resolution: "ssri@npm:13.0.0" dependencies: minipass: "npm:^7.0.3" - checksum: 10c0/cf6408a18676c57ff2ed06b8a20dc64bb3e748e5c7e095332e6aecaa2b8422b1e94a739a8453bf65156a8a47afe23757ba4ab52d3ea3b62322dc40875763e17a + checksum: 10c0/405f3a531cd98b013cecb355d63555dca42fd12c7bc6671738aaa9a82882ff41cdf0ef9a2b734ca4f9a760338f114c29d01d9238a65db3ccac27929bd6e6d4b2 languageName: node linkType: hard @@ -10405,14 +10743,21 @@ __metadata: languageName: node linkType: hard -"statuses@npm:>= 1.5.0 < 2": +"statuses@npm:2.0.1": + version: 2.0.1 + resolution: "statuses@npm:2.0.1" + checksum: 10c0/34378b207a1620a24804ce8b5d230fea0c279f00b18a7209646d5d47e419d1cc23e7cbf33a25a1e51ac38973dc2ac2e1e9c647a8e481ef365f77668d72becfd0 + languageName: node + linkType: hard + +"statuses@npm:>= 1.4.0 < 2": version: 1.5.0 resolution: "statuses@npm:1.5.0" checksum: 10c0/e433900956357b3efd79b1c547da4d291799ac836960c016d10a98f6a810b1b5c0dcc13b5a7aa609a58239b5190e1ea176ad9221c2157d2fd1c747393e6b2940 languageName: node linkType: hard -"statuses@npm:~2.0.1, statuses@npm:~2.0.2": +"statuses@npm:~2.0.2": version: 2.0.2 resolution: "statuses@npm:2.0.2" checksum: 10c0/a9947d98ad60d01f6b26727570f3bcceb6c8fa789da64fe6889908fe2e294d57503b14bf2b5af7605c2d36647259e856635cd4c49eab41667658ec9d0080ec3f @@ -10677,19 +11022,26 @@ __metadata: linkType: hard "tabbable@npm:^6.0.0": - version: 6.4.0 - resolution: "tabbable@npm:6.4.0" - checksum: 10c0/d931427f4a96b801fd8801ba296a702119e06f70ad262fed8abc5271225c9f1ca51b89fdec4fb2f22e1d35acb3d2881db0a17cedc758272e9ecb540d00299d76 + version: 6.3.0 + resolution: "tabbable@npm:6.3.0" + checksum: 10c0/57ba019d29b5cfa0c862248883bcec0e6d29d8f156ba52a1f425e7cfeca4a0fc701ab8d035c4c86ddf74ecdbd0e9f454a88d9b55d924a51f444038e9cd14d7a0 languageName: node linkType: hard -"tailwindcss@npm:4.2.2, tailwindcss@npm:^4": +"tailwindcss@npm:4.2.2": version: 4.2.2 resolution: "tailwindcss@npm:4.2.2" checksum: 10c0/6eae8a125c35d504ba6c518d26ec64fba694ff4a9ab9b9cd9883050128e0b7afdf491388c472d9bed2624664c1c7d4a133d19b653151a6b52e6ce6953168a857 languageName: node linkType: hard +"tailwindcss@npm:^4": + version: 4.1.17 + resolution: "tailwindcss@npm:4.1.17" + checksum: 10c0/1fecf618ba9895e068e5a6d842b978f56a815bc849a28338cebbcb07b13df763715c2f8848def938403c73d59f08ffff33a4b83a977a9e38fa56adc60d1d56c8 + languageName: node + linkType: hard + "tapable@npm:^2.3.0": version: 2.3.2 resolution: "tapable@npm:2.3.2" @@ -10697,16 +11049,16 @@ __metadata: languageName: node linkType: hard -"tar@npm:^7.5.4": - version: 7.5.13 - resolution: "tar@npm:7.5.13" +"tar@npm:^7.5.2": + version: 7.5.7 + resolution: "tar@npm:7.5.7" dependencies: "@isaacs/fs-minipass": "npm:^4.0.0" chownr: "npm:^3.0.0" minipass: "npm:^7.1.2" minizlib: "npm:^3.1.0" yallist: "npm:^5.0.0" - checksum: 10c0/5c65b8084799bde7a791593a1c1a45d3d6ee98182e3700b24c247b7b8f8654df4191642abbdb07ff25043d45dcff35620827c3997b88ae6c12040f64bed5076b + checksum: 10c0/51f261afc437e1112c3e7919478d6176ea83f7f7727864d8c2cce10f0b03a631d1911644a567348c3063c45abdae39718ba97abb073d22aa3538b9a53ae1e31c languageName: node linkType: hard @@ -10758,9 +11110,9 @@ __metadata: linkType: hard "tinyexec@npm:^1.0.2": - version: 1.0.4 - resolution: "tinyexec@npm:1.0.4" - checksum: 10c0/d4a5bbcf6bdb23527a4b74c4aa566f41432167112fe76f420ec7e3a90a3ecfd3a7d944383e2719fc3987b69400f7b928daf08700d145fb527c2e80ec01e198bd + version: 1.0.2 + resolution: "tinyexec@npm:1.0.2" + checksum: 10c0/1261a8e34c9b539a9aae3b7f0bb5372045ff28ee1eba035a2a059e532198fe1a182ec61ac60fa0b4a4129f0c4c4b1d2d57355b5cb9aa2d17ac9454ecace502ee languageName: node linkType: hard @@ -11085,10 +11437,10 @@ __metadata: languageName: node linkType: hard -"undici-types@npm:~7.18.0": - version: 7.18.2 - resolution: "undici-types@npm:7.18.2" - checksum: 10c0/85a79189113a238959d7a647368e4f7c5559c3a404ebdb8fc4488145ce9426fcd82252a844a302798dfc0e37e6fb178ff481ed03bc4caf634c5757d9ef43521d +"undici-types@npm:~7.16.0": + version: 7.16.0 + resolution: "undici-types@npm:7.16.0" + checksum: 10c0/3033e2f2b5c9f1504bdc5934646cb54e37ecaca0f9249c983f7b1fc2e87c6d18399ebb05dc7fd5419e02b2e915f734d872a65da2e3eeed1813951c427d33cc9a languageName: node linkType: hard @@ -11169,6 +11521,24 @@ __metadata: languageName: node linkType: hard +"unique-filename@npm:^5.0.0": + version: 5.0.0 + resolution: "unique-filename@npm:5.0.0" + dependencies: + unique-slug: "npm:^6.0.0" + checksum: 10c0/afb897e9cf4c2fb622ea716f7c2bb462001928fc5f437972213afdf1cc32101a230c0f1e9d96fc91ee5185eca0f2feb34127145874975f347be52eb91d6ccc2c + languageName: node + linkType: hard + +"unique-slug@npm:^6.0.0": + version: 6.0.0 + resolution: "unique-slug@npm:6.0.0" + dependencies: + imurmurhash: "npm:^0.1.4" + checksum: 10c0/da7ade4cb04eb33ad0499861f82fe95ce9c7c878b7139dc54d140ecfb6a6541c18a5c8dac16188b8b379fe62c0c1f1b710814baac910cde5f4fec06212126c6a + languageName: node + linkType: hard + "unist-util-inspect@npm:^8.0.0": version: 8.1.0 resolution: "unist-util-inspect@npm:8.1.0" @@ -11225,13 +11595,13 @@ __metadata: linkType: hard "unist-util-visit@npm:^5.0.0": - version: 5.1.0 - resolution: "unist-util-visit@npm:5.1.0" + version: 5.0.0 + resolution: "unist-util-visit@npm:5.0.0" dependencies: "@types/unist": "npm:^3.0.0" unist-util-is: "npm:^6.0.0" unist-util-visit-parents: "npm:^6.0.0" - checksum: 10c0/a56e1bbbf63fcb55abe379e660b9a3367787e8be1e2473bdb7e86cfa6f32b6c1fa0092432d7040b8a30b2fc674bbbe024ffe6d03c3d6bf4839b064f584463a4e + checksum: 10c0/51434a1d80252c1540cce6271a90fd1a106dbe624997c09ed8879279667fb0b2d3a685e02e92bf66598dcbe6cdffa7a5f5fb363af8fdf90dda6c855449ae39a5 languageName: node linkType: hard @@ -11242,7 +11612,7 @@ __metadata: languageName: node linkType: hard -"unpipe@npm:~1.0.0": +"unpipe@npm:1.0.0, unpipe@npm:~1.0.0": version: 1.0.0 resolution: "unpipe@npm:1.0.0" checksum: 10c0/193400255bd48968e5c5383730344fbb4fa114cdedfab26e329e50dd2d81b134244bb8a72c6ac1b10ab0281a58b363d06405632c9d49ca9dfd5e90cbd7d0f32c @@ -11256,9 +11626,9 @@ __metadata: languageName: node linkType: hard -"update-browserslist-db@npm:^1.2.3": - version: 1.2.3 - resolution: "update-browserslist-db@npm:1.2.3" +"update-browserslist-db@npm:^1.1.4": + version: 1.1.4 + resolution: "update-browserslist-db@npm:1.1.4" dependencies: escalade: "npm:^3.2.0" picocolors: "npm:^1.1.1" @@ -11266,7 +11636,7 @@ __metadata: browserslist: ">= 4.21.0" bin: update-browserslist-db: cli.js - checksum: 10c0/13a00355ea822388f68af57410ce3255941d5fb9b7c49342c4709a07c9f230bbef7f7499ae0ca7e0de532e79a82cc0c4edbd125f1a323a1845bf914efddf8bec + checksum: 10c0/db0c9aaecf1258a6acda5e937fc27a7996ccca7a7580a1b4aa8bba6a9b0e283e5e65c49ebbd74ec29288ef083f1b88d4da13e3d4d326c1e5fc55bf72d7390702 languageName: node linkType: hard @@ -11480,10 +11850,10 @@ __metadata: linkType: hard "vite@npm:^5.0.0 || ^6.0.0 || ^7.0.0-0": - version: 7.3.2 - resolution: "vite@npm:7.3.2" + version: 7.2.4 + resolution: "vite@npm:7.2.4" dependencies: - esbuild: "npm:^0.27.0" + esbuild: "npm:^0.25.0" fdir: "npm:^6.5.0" fsevents: "npm:~2.3.3" picomatch: "npm:^4.0.3" @@ -11530,13 +11900,13 @@ __metadata: optional: true bin: vite: bin/vite.js - checksum: 10c0/74be36907e208916f18bfec81c8eba18b869f0a170f1ece0a4dcb14874d0f0e7c022fb6c2ad896e3ee6c973fe88f53ac23b4078879ada340d8b263260868b8d4 + checksum: 10c0/26aa0cad01d6e00f17c837b2a0587ab52f6bd0d0e64606b4220cfc58fa5fa76a4095ef3ea27c886bea542a346363912c4fad9f9462ef1e6757262fedfd5196b2 languageName: node linkType: hard "vite@npm:^6.0.0 || ^7.0.0 || ^8.0.0, vite@npm:^8.0.3": - version: 8.0.5 - resolution: "vite@npm:8.0.5" + version: 8.0.3 + resolution: "vite@npm:8.0.3" dependencies: fsevents: "npm:~2.3.3" lightningcss: "npm:^1.32.0" @@ -11547,7 +11917,7 @@ __metadata: peerDependencies: "@types/node": ^20.19.0 || >=22.12.0 "@vitejs/devtools": ^0.1.0 - esbuild: ^0.27.0 || ^0.28.0 + esbuild: ^0.27.0 jiti: ">=1.21.0" less: ^4.0.0 sass: ^1.70.0 @@ -11587,7 +11957,7 @@ __metadata: optional: true bin: vite: bin/vite.js - checksum: 10c0/bfc22896b2661753c01c398a058f1859bdbd3ebe55f3d8505ab629b39e5f68790c0a6f55f8644b6692b0b9b8e210f698082ef9f4fd0d76509f4a46762fbfbba2 + checksum: 10c0/bed9520358080393a02fe22565b3309b4b3b8f916afe4c97577528f3efb05c1bf4b29f7b552179bc5b3938629e50fbd316231727457411dbc96648fa5c9d14bf languageName: node linkType: hard @@ -11774,8 +12144,8 @@ __metadata: linkType: hard "which-typed-array@npm:^1.1.16, which-typed-array@npm:^1.1.18, which-typed-array@npm:^1.1.19": - version: 1.1.20 - resolution: "which-typed-array@npm:1.1.20" + version: 1.1.19 + resolution: "which-typed-array@npm:1.1.19" dependencies: available-typed-arrays: "npm:^1.0.7" call-bind: "npm:^1.0.8" @@ -11784,7 +12154,7 @@ __metadata: get-proto: "npm:^1.0.1" gopd: "npm:^1.2.0" has-tostringtag: "npm:^1.0.2" - checksum: 10c0/16fcdada95c8afb821cd1117f0ab50b4d8551677ac08187f21d4e444530913c9ffd2dac634f0c1183345f96344b69280f40f9a8bc52164ef409e555567c2604b + checksum: 10c0/702b5dc878addafe6c6300c3d0af5983b175c75fcb4f2a72dfc3dd38d93cf9e89581e4b29c854b16ea37e50a7d7fca5ae42ece5c273d8060dcd603b2404bbb3f languageName: node linkType: hard @@ -11811,13 +12181,13 @@ __metadata: linkType: hard "which@npm:^6.0.0": - version: 6.0.1 - resolution: "which@npm:6.0.1" + version: 6.0.0 + resolution: "which@npm:6.0.0" dependencies: - isexe: "npm:^4.0.0" + isexe: "npm:^3.1.1" bin: node-which: bin/which.js - checksum: 10c0/7e710e54ea36d2d6183bee2f9caa27a3b47b9baf8dee55a199b736fcf85eab3b9df7556fca3d02b50af7f3dfba5ea3a45644189836df06267df457e354da66d5 + checksum: 10c0/fe9d6463fe44a76232bb6e3b3181922c87510a5b250a98f1e43a69c99c079b3f42ddeca7e03d3e5f2241bf2d334f5a7657cfa868b97c109f3870625842f4cc15 languageName: node linkType: hard @@ -12037,11 +12407,11 @@ __metadata: linkType: hard "yaml@npm:^2.0.0": - version: 2.8.3 - resolution: "yaml@npm:2.8.3" + version: 2.8.1 + resolution: "yaml@npm:2.8.1" bin: yaml: bin.mjs - checksum: 10c0/ddff0e11c1b467728d7eb4633db61c5f5de3d8e9373cf84d08fb0cdee03e1f58f02b9f1c51a4a8a865751695addbd465a77f73f1079be91fe5493b29c305fd77 + checksum: 10c0/7c587be00d9303d2ae1566e03bc5bc7fe978ba0d9bf39cc418c3139d37929dfcb93a230d9749f2cb578b6aa5d9ebebc322415e4b653cb83acd8bc0bc321707f3 languageName: node linkType: hard