diff --git a/.env.example b/.env.example index fe917fe..d6b7df4 100644 --- a/.env.example +++ b/.env.example @@ -1,5 +1,3 @@ -# Add your env variables here - -# The environment of the app. This is different from NODE_ENV, and will be used for deployments. -# Default: development -#APP_ENV="staging" +GITHUB_OWNER="github-owner" # Your username or organization name (Optional. For edit/report an issue for the documentation page) +GITHUB_REPO="github-repo" # Repository name (Optional. For edit/report an issue for the documentation page) +APP_ROOT_PATH="/path/to/your/app" # Optional. Default is `process.cwd()` diff --git a/.gitignore b/.gitignore index e8ed9db..f24a830 100644 --- a/.gitignore +++ b/.gitignore @@ -80,3 +80,7 @@ blob-report *.sqlite *.sqlite3 *.db-journal + + +# Content collections output files +.content-collections diff --git a/.vscode/settings.json b/.vscode/settings.json index edb107e..85f2f2c 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -42,5 +42,6 @@ }, "[typescriptreact]": { "editor.defaultFormatter": "biomejs.biome" - } + }, + "editor.formatOnPaste": true } diff --git a/README.md b/README.md index ed8a9a2..ebe5a74 100644 --- a/README.md +++ b/README.md @@ -1,65 +1,89 @@ +# Welcome to Forge 42 Documentation Template +This template is designed to support a flexible content structure using `.md` and `.mdx` files organized into folders. It enables deeply nested sections and subsections, making it easy to manage complex documentation with a clear and scalable hierarchy. + +The project is built using the [@forge-42/base-stack](https://github.com/forge-42/base-stack) and leverages the [content-collections](https://github.com/sdorra/content-collections). + + +## Documentation Template Structure Overview + +`app/` + +This folder contains React Router v7 web application folders and files, including components and UI primitives for the documentation site’s interface, internal hooks and utilities, and the tailwind.css file for styling. + + +`resources/` + +This folder contains all the resources used by the documentation site, such as SVG icons, fonts, and other assets. + +`content/` + +This folder contains sections and subsections with .mdx files that hold your documentation content. Below is the recommended structure to follow. + + +An example of a valid content/ folder structure for organizing your package documentation: -
-
-
+ {lines.map((line, index) => (
+
+ ))}
+
+)
+
+interface PreElementProps extends Omit++) diff --git a/app/components/code-block/code-block-parser.ts b/app/components/code-block/code-block-parser.ts new file mode 100644 index 0000000..ec64f3d --- /dev/null +++ b/app/components/code-block/code-block-parser.ts @@ -0,0 +1,53 @@ +import { cleanDiffLine, getDiffStyles, getDiffType } from "./code-block-diff" +import { tokenize } from "./code-block-syntax-highlighter" + +interface CodeBlockChild { + props?: { + children?: string + } +} + +export const extractCodeContent = (children: string | CodeBlockChild) => { + const code = typeof children === "string" ? children : (children?.props?.children ?? "") + return { code } +} + +export const processLines = (content: string) => { + const lines = content.split("\n") + return filterEmptyLines(lines) +} + +const filterEmptyLines = (lines: string[]) => { + return lines.filter((line, index, array) => { + const isLastLine = index === array.length - 1 + const isEmpty = line.trim() === "" + return !(isEmpty && isLastLine) + }) +} + +export const createLineData = (line: string) => { + const diffType = getDiffType(line) + const cleanLine = cleanDiffLine(line) + const tokens = tokenize(cleanLine) + const styles = getDiffStyles(diffType) + const isNormalDiff = diffType === "normal" + + return { + diffType, + cleanLine, + tokens, + styles, + isNormalDiff, + } +} + +export const processCopyContent = (content: string): { code: string } => { + // removes diff markers from content + const code = content + .split("\n") + .filter((line) => !line.trimStart().startsWith("- ")) + .map((line) => line.replace(/^(\s*)\+ /, "$1")) + .join("\n") + + return { code } +} diff --git a/app/components/code-block/code-block-syntax-highlighter.ts b/app/components/code-block/code-block-syntax-highlighter.ts new file mode 100644 index 0000000..d452b8d --- /dev/null +++ b/app/components/code-block/code-block-syntax-highlighter.ts @@ -0,0 +1,153 @@ +/** + * Tokenization utility for syntax highlighting code snippets. + * This utils will produce syntax-highlighted JSX output using theme colors. + */ + +type TokenType = "keyword" | "string" | "number" | "comment" | "operator" | "punctuation" | "function" | "text" + +const MASTER_REGEX = new RegExp( + [ + // whitespace + "\\s+", + // single-line comment + "//.*?(?=\\n|$)", + // multi-line comment + "/\\*[\\s\\S]*?\\*/", + // strings + "(['\"])(?:(?!\\1)[^\\\\]|\\\\.)*\\1", + // numbers + "\\d+\\.?\\d*", + // identifiers + "[a-zA-Z_$][a-zA-Z0-9_$]*", + // operators and punctuation + "===|!==|<=|>=|==|!=|&&|\\|\\||\\+\\+|--|[+\\-*/%=<>!?:(){}\\[\\];,.]|[+\\-*/%]=", + // arrow function + "=>", + ].join("|"), + "g" +) + +const KEYWORDS = [ + "import", + "export", + "default", + "from", + "const", + "let", + "var", + "function", + "return", + "if", + "else", + "for", + "while", + "do", + "switch", + "case", + "break", + "continue", + "try", + "catch", + "finally", + "throw", + "new", + "class", + "extends", + "interface", + "type", + "public", + "private", + "protected", + "static", + "async", + "await", + "true", + "false", + "null", + "undefined", + "typeof", + "instanceof", +] + +const OPERATORS = [ + "+", + "-", + "*", + "/", + "=", + "==", + "===", + "!=", + "!==", + "<", + ">", + "<=", + ">=", + "&&", + "||", + "!", + "?", + ":", + "++", + "--", + "+=", + "-=", + "*=", + "/=", + "=>", +] + +const isKeyword = (value: string) => KEYWORDS.includes(value) +const isOperator = (value: string) => OPERATORS.includes(value) +const isFunction = (value: string) => /^[A-Z]/.test(value) +const isWhitespace = (value: string) => /^\s/.test(value) +const isComment = (value: string) => value.startsWith("//") || value.startsWith("/*") +const isString = (value: string) => /^['"`]/.test(value) +const isNumber = (value: string) => /^\d/.test(value) +const isIdentifier = (value: string) => /^[a-zA-Z_$]/.test(value) + +const classifyIdentifier = (value: string) => { + return isKeyword(value) ? "keyword" : isFunction(value) ? "function" : "text" +} + +const classifyToken = (value: string) => { + switch (true) { + case isWhitespace(value): + return "text" + case isComment(value): + return "comment" + case isString(value): + return "string" + case isNumber(value): + return "number" + case isIdentifier(value): + return classifyIdentifier(value) + case isOperator(value): + return "operator" + default: + return "punctuation" + } +} + +export const tokenize = (code: string) => + Array.from(code.matchAll(MASTER_REGEX), (match) => ({ + type: classifyToken(match[0]), + value: match[0], + })) + +const TOKEN_COLORS = { + keyword: "var(--color-code-keyword)", + string: "var(--color-code-string)", + number: "var(--color-code-number)", + comment: "var(--color-code-comment)", + operator: "var(--color-code-operator)", + punctuation: "var(--color-code-punctuation)", + function: "var(--color-code-function)", + text: "var(--color-code-block-text)", +} as const + +export const getTokenColor = (type: TokenType) => TOKEN_COLORS[type] + +export function isTokenType(value: unknown): value is TokenType { + return typeof value === "string" && value in TOKEN_COLORS +} diff --git a/app/components/code-block/code-block.tsx b/app/components/code-block/code-block.tsx new file mode 100644 index 0000000..85870ef --- /dev/null +++ b/app/components/code-block/code-block.tsx @@ -0,0 +1,20 @@ +import type { ComponentPropsWithoutRef } from "react" +import { PreElement } from "./code-block-elements" +import { extractCodeContent, processLines } from "./code-block-parser" +import { CopyButton } from "./copy-button" + +interface CodeBlockProps extends Omit+
+ {t(`error.${errorStatusCode}.description`)} +
+{t(`error.${errorStatusCode}.description`)}
++ {t(`error.${errorStatusCode}.description`)} +
{t("error.404.description")}
++ {t("error.404.description")} +
-
-
-
-
- Base
-
- Stack
-
- - Welcome to Forge 42 base stack. The minimal stack required to get you up and running. This stack was - chosen to provide a solid foundation for your project, without the bloat. Check the{" "} - - README.md - {" "} - file for detailed instructions. -
- element, used to display inline code snippets with consistent styling.
+ *
+ * Useful for rendering short code expressions, variable names, or commands within paragraphs or markdown content.
+ *
+ * Example usage:
+ *
+ * Install it using npm install forge42/base-stack .
+ *
+ */
+export const InlineCode = (props: ComponentPropsWithoutRef<"code">) => {
+ return (
+
+ )
+}
diff --git a/app/ui/list-item.tsx b/app/ui/list-item.tsx
new file mode 100644
index 0000000..5260e37
--- /dev/null
+++ b/app/ui/list-item.tsx
@@ -0,0 +1,14 @@
+import type { ComponentPropsWithoutRef } from "react"
+import { cn } from "~/utils/css"
+
+export const ListItem = (props: ComponentPropsWithoutRef<"li">) => {
+ return (
+ li]:ml-2 [&>li]:marker:font-medium",
+ props.className
+ )}
+ />
+ )
+}
diff --git a/app/ui/ordered-list.tsx b/app/ui/ordered-list.tsx
new file mode 100644
index 0000000..d3ff4cb
--- /dev/null
+++ b/app/ui/ordered-list.tsx
@@ -0,0 +1,25 @@
+import type { ComponentPropsWithoutRef } from "react"
+import { cn } from "~/utils/css"
+
+/**
+ * A styled wrapper around the native element, used to render ordered lists
+ * with consistent spacing, indentation, and text styling.
+ *
+ * Example usage:
+ *
+ * - Clone the repository
+ * - Install dependencies
+ * - Run the development server
+ *
+ */
+export const OrderedList = (props: ComponentPropsWithoutRef<"ol">) => {
+ return (
+ li]:ml-2 [&>li]:marker:font-medium",
+ props.className
+ )}
+ />
+ )
+}
diff --git a/app/ui/strong-text.tsx b/app/ui/strong-text.tsx
new file mode 100644
index 0000000..7c27482
--- /dev/null
+++ b/app/ui/strong-text.tsx
@@ -0,0 +1,6 @@
+import type { ComponentPropsWithoutRef } from "react"
+import { cn } from "~/utils/css"
+
+export const Strong = (props: ComponentPropsWithoutRef<"strong">) => {
+ return
+}
diff --git a/app/ui/title.tsx b/app/ui/title.tsx
new file mode 100644
index 0000000..f96d08a
--- /dev/null
+++ b/app/ui/title.tsx
@@ -0,0 +1,53 @@
+import { cn } from "../utils/css"
+
+export const ValidTitleElements = {
+ h1: "text-2xl sm:text-3xl md:text-4xl",
+ h2: "text-xl sm:text-2xl md:text-3xl",
+ h3: "text-lg sm:text-xl md:text-2xl",
+ h4: "text-base sm:text-lg md:text-xl",
+ h5: "text-sm sm:text-base md:text-lg",
+ h6: "text-xs sm:text-sm md:text-base",
+} as const
+
+interface TitleProps extends React.HTMLAttributes {
+ children: React.ReactNode
+ as: keyof typeof ValidTitleElements
+ className?: string
+}
+
+/**
+ * A reusable, styled heading component for consistent typography across the project.
+ *
+ * The `Title` component renders a heading element (`h1` through `h6`) with
+ * predefined responsive font sizes, weights, and line heights based on a design scale.
+ * It ensures consistent visual hierarchy and styling throughout the app.
+ *
+ * You can customize the appearance further using the `className` prop, and the rendered
+ * element type is controlled via the `as` prop.
+ *
+ * @param as - The HTML heading element to render (`h1` through `h6`). Required.
+ * @param children - The title content to display inside the heading.
+ * @param className - Optional additional Tailwind or custom classes to override or extend the default styles.
+ * @param props - Any additional valid HTML attributes for the heading element.
+ *
+ * @example
+ * ```tsx
+ *
+ * Getting Started
+ *
+ * ```
+ *
+ * @returns A JSX element with consistent project-specific title styling.
+ */
+const Title = ({ children, as, className, ...props }: TitleProps) => {
+ const Component = as
+ const titleClasses = cn(ValidTitleElements[as], "text-[var(--color-text-normal)]", className)
+
+ return (
+
+ {children}
+
+ )
+}
+
+export { Title }
diff --git a/app/ui/warning-alert.tsx b/app/ui/warning-alert.tsx
new file mode 100644
index 0000000..36849f5
--- /dev/null
+++ b/app/ui/warning-alert.tsx
@@ -0,0 +1,16 @@
+import type { ReactNode } from "react"
+import { Alert } from "./alert"
+
+interface WarningAlertProps {
+ children: ReactNode
+ title?: string
+ className?: string
+}
+
+export const WarningAlert = ({ children, title, className }: WarningAlertProps) => {
+ return (
+
+ {children}
+
+ )
+}
diff --git a/app/utils/README.md b/app/utils/README.md
deleted file mode 100644
index da63108..0000000
--- a/app/utils/README.md
+++ /dev/null
@@ -1,7 +0,0 @@
-# Utils
-
-This directory contains utility functions that are used throughout the app.
-
-We recommend you put all your utility functions in this directory. This will make it easier to find and use them.
-
-If the utilities are server only then you can call them `x.server.ts`
\ No newline at end of file
diff --git a/app/utils/create-github-contribution-links.ts b/app/utils/create-github-contribution-links.ts
new file mode 100644
index 0000000..825f2a6
--- /dev/null
+++ b/app/utils/create-github-contribution-links.ts
@@ -0,0 +1,26 @@
+interface GitHubContributionLinkOptions {
+ pagePath: string
+ owner: string
+ repo: string
+}
+
+export function createGitHubContributionLinks({ pagePath, owner, repo }: GitHubContributionLinkOptions) {
+ const githubBase = `https://github.com/${owner}/${repo}`
+ const editUrl = `${githubBase}/edit/main/content/${pagePath}`
+
+ const issueTitle = `Issue with the "${pagePath}" doc`
+ const issueBody = `I found an issue with this document.
+
+**Title:** ${pagePath}
+**Source:** ${githubBase}/blob/main/content/${pagePath}
+
+### Describe the issue
+
+
+### Additional info
+`
+
+ const issueUrl = `${githubBase}/issues/new?title=${encodeURIComponent(issueTitle)}&body=${encodeURIComponent(issueBody)}`
+
+ return { editUrl, issueUrl }
+}
diff --git a/app/utils/create-sidebar-tree.ts b/app/utils/create-sidebar-tree.ts
new file mode 100644
index 0000000..9703dd5
--- /dev/null
+++ b/app/utils/create-sidebar-tree.ts
@@ -0,0 +1,30 @@
+import { allPages, allSections } from "content-collections"
+import type { SidebarSection } from "~/components/sidebar/sidebar"
+
+const parentOf = (slug: string) => slug.split("/").slice(0, -1).join("/")
+
+// builds a nested sidebar tree of sections and pages for a given version, auto generated by the content-collections or by the build script
+export function createSidebarTree(version = "latest") {
+ const map = new Map()
+
+ for (const s of allSections.filter((s) => s.version === version)) {
+ map.set(s.slug, { ...s, subsections: [], documentationPages: [] })
+ }
+
+ for (const node of map.values()) {
+ const parentSlug = parentOf(node.slug)
+ if (parentSlug && parentSlug !== version) {
+ map.get(parentSlug)?.subsections.push(node)
+ }
+ }
+
+ for (const p of allPages) {
+ if (!p.slug.startsWith(`${version}/`)) continue
+ const parentSlug = parentOf(p.slug)
+ map.get(parentSlug)?.documentationPages.push({ slug: p.slug, title: p.title })
+ }
+
+ const rootSections = [...map.values()].filter((section) => parentOf(section.slug) === version)
+
+ return rootSections
+}
diff --git a/app/utils/dates.ts b/app/utils/dates.ts
deleted file mode 100644
index 2a319df..0000000
--- a/app/utils/dates.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-import { getTimeZone } from "../services/client-hints"
-
-function convertTz(date: string | Date, tzString: string) {
- const dateToConvert = typeof date === "string" ? new Date(date) : date
- // Convert to the target timezone
- const convertedDate = new Date(dateToConvert.toLocaleString("en-US", { timeZone: tzString }))
- return convertedDate
-}
-
-export function convertDateToUserTz(date: Date | string, request?: Request) {
- const tz = getTimeZone(request)
- const dates = convertTz(date, tz)
- return dates
-}
diff --git a/app/utils/extract-heading-tree-from-mdx.ts b/app/utils/extract-heading-tree-from-mdx.ts
new file mode 100644
index 0000000..6478311
--- /dev/null
+++ b/app/utils/extract-heading-tree-from-mdx.ts
@@ -0,0 +1,62 @@
+import slugify from "slug"
+
+export type HeadingItem = {
+ slug: string
+ title: string
+ level: number
+ children: HeadingItem[]
+}
+
+const headingRegex = /^\s*(#{1,6})\s+(.+?)\s*$/
+
+const cleanMarkdown = (text: string) =>
+ text
+ //remove inline code backticks
+ .replace(/`([^`]+)`/g, "$1")
+ //remove bold markers
+ .replace(/\*\*([^*]+)\*\*/g, "$1")
+ //remove italic markers
+ .replace(/\*([^*]+)\*/g, "$1")
+ //remove markdown links, keep the link text
+ .replace(/\[([^\]]+)\]\([^)]+\)/g, "$1")
+ //remove curly-brace content
+ .replace(/\{[^}]*\}/g, "")
+ //remove HTML tags
+ .replace(/<\/?[^>]+(>|$)/g, "")
+ //tTrim trailing whitespace
+ .trim()
+
+export function extractHeadingTreeFromMarkdown(content: string) {
+ const root: HeadingItem[] = []
+ const stack: HeadingItem[] = []
+
+ for (const line of content.split("\n")) {
+ const match = headingRegex.exec(line)
+ if (!match) continue
+
+ const level = match[1].length
+ if (level > 3) continue
+
+ const title = cleanMarkdown(match[2])
+ const node: HeadingItem = {
+ title,
+ slug: slugify(title),
+ level,
+ children: [],
+ }
+
+ while (stack.length && stack[stack.length - 1].level >= level) {
+ stack.pop()
+ }
+
+ if (stack.length === 0) {
+ root.push(node)
+ } else {
+ stack[stack.length - 1].children.push(node)
+ }
+
+ stack.push(node)
+ }
+
+ return root
+}
diff --git a/app/utils/flatten-sidebar.ts b/app/utils/flatten-sidebar.ts
new file mode 100644
index 0000000..bb56199
--- /dev/null
+++ b/app/utils/flatten-sidebar.ts
@@ -0,0 +1,10 @@
+import type { SidebarSection } from "~/components/sidebar/sidebar"
+
+export function flattenSidebarItems(sections: SidebarSection[]) {
+ const collectPages = (section: SidebarSection): { title: string; slug: string }[] => [
+ ...section.documentationPages,
+ ...section.subsections.flatMap(collectPages),
+ ]
+
+ return sections.flatMap(collectPages)
+}
diff --git a/app/utils/fonts.ts b/app/utils/fonts.ts
new file mode 100644
index 0000000..643780a
--- /dev/null
+++ b/app/utils/fonts.ts
@@ -0,0 +1,164 @@
+import dynaPuffBold from "../../resources/fonts/dyna-puff/DynaPuff-Bold.ttf"
+import dynaPuffMedium from "../../resources/fonts/dyna-puff/DynaPuff-Medium.ttf"
+import dynaPuffRegular from "../../resources/fonts/dyna-puff/DynaPuff-Regular.ttf"
+import dynaPuffSemiBold from "../../resources/fonts/dyna-puff/DynaPuff-SemiBold.ttf"
+import interBlack from "../../resources/fonts/inter/Inter-Black.ttf"
+import interBlackItalic from "../../resources/fonts/inter/Inter-BlackItalic.ttf"
+import interBold from "../../resources/fonts/inter/Inter-Bold.ttf"
+import interBoldItalic from "../../resources/fonts/inter/Inter-BoldItalic.ttf"
+import interExtraBold from "../../resources/fonts/inter/Inter-ExtraBold.ttf"
+import interExtraBoldItalic from "../../resources/fonts/inter/Inter-ExtraBoldItalic.ttf"
+import interExtraLight from "../../resources/fonts/inter/Inter-ExtraLight.ttf"
+import interExtraLightItalic from "../../resources/fonts/inter/Inter-ExtraLightItalic.ttf"
+import interItalic from "../../resources/fonts/inter/Inter-Italic.ttf"
+import interLight from "../../resources/fonts/inter/Inter-Light.ttf"
+import interLightItalic from "../../resources/fonts/inter/Inter-LightItalic.ttf"
+import interMedium from "../../resources/fonts/inter/Inter-Medium.ttf"
+import interMediumItalic from "../../resources/fonts/inter/Inter-MediumItalic.ttf"
+import interRegular from "../../resources/fonts/inter/Inter-Regular.ttf"
+import interSemiBold from "../../resources/fonts/inter/Inter-SemiBold.ttf"
+import interSemiBoldItalic from "../../resources/fonts/inter/Inter-SemiBoldItalic.ttf"
+import interThin from "../../resources/fonts/inter/Inter-Thin.ttf"
+import interThinItalic from "../../resources/fonts/inter/Inter-ThinItalic.ttf"
+import spaceNormal from "../../resources/fonts/space/Space.woff2"
+
+export const fonts = [
+ {
+ fontFamily: "Dyna Puff",
+ fontStyle: "normal",
+ fontWeight: 400,
+ src: dynaPuffRegular,
+ },
+ {
+ fontFamily: "Dyna Puff",
+ fontStyle: "normal",
+ fontWeight: 700,
+ src: dynaPuffBold,
+ },
+ {
+ fontFamily: "Dyna Puff",
+ fontStyle: "normal",
+ fontWeight: 500,
+ src: dynaPuffMedium,
+ },
+ {
+ fontFamily: "Dyna Puff",
+ fontStyle: "normal",
+ fontWeight: 600,
+ src: dynaPuffSemiBold,
+ },
+ {
+ fontFamily: "Inter",
+ fontStyle: "normal",
+ fontWeight: 400,
+ src: interRegular,
+ },
+ {
+ fontFamily: "Inter",
+ fontStyle: "normal",
+ fontWeight: 700,
+ src: interBold,
+ },
+ {
+ fontFamily: "Inter",
+ fontStyle: "normal",
+ fontWeight: 900,
+ src: interBlack,
+ },
+ {
+ fontFamily: "Inter",
+ fontStyle: "normal",
+ fontWeight: 200,
+ src: interExtraLight,
+ },
+ {
+ fontFamily: "Inter",
+ fontStyle: "normal",
+ fontWeight: 300,
+ src: interLight,
+ },
+ {
+ fontFamily: "Inter",
+ fontStyle: "normal",
+ fontWeight: 500,
+ src: interMedium,
+ },
+ {
+ fontFamily: "Inter",
+ fontStyle: "normal",
+ fontWeight: 600,
+ src: interSemiBold,
+ },
+ {
+ fontFamily: "Inter",
+ fontStyle: "normal",
+ fontWeight: 800,
+ src: interExtraBold,
+ },
+ {
+ fontFamily: "Inter",
+ fontStyle: "normal",
+ fontWeight: 100,
+ src: interThin,
+ },
+ {
+ fontFamily: "Inter",
+ fontStyle: "italic",
+ fontWeight: 400,
+ src: interItalic,
+ },
+ {
+ fontFamily: "Inter",
+ fontStyle: "italic",
+ fontWeight: 700,
+ src: interBoldItalic,
+ },
+ {
+ fontFamily: "Inter",
+ fontStyle: "italic",
+ fontWeight: 900,
+ src: interBlackItalic,
+ },
+ {
+ fontFamily: "Inter",
+ fontStyle: "italic",
+ fontWeight: 200,
+ src: interExtraLightItalic,
+ },
+ {
+ fontFamily: "Inter",
+ fontStyle: "italic",
+ fontWeight: 300,
+ src: interLightItalic,
+ },
+ {
+ fontFamily: "Inter",
+ fontStyle: "italic",
+ fontWeight: 500,
+ src: interMediumItalic,
+ },
+ {
+ fontFamily: "Inter",
+ fontStyle: "italic",
+ fontWeight: 600,
+ src: interSemiBoldItalic,
+ },
+ {
+ fontFamily: "Inter",
+ fontStyle: "italic",
+ fontWeight: 800,
+ src: interExtraBoldItalic,
+ },
+ {
+ fontFamily: "Inter",
+ fontStyle: "italic",
+ fontWeight: 100,
+ src: interThinItalic,
+ },
+ {
+ fontFamily: "Space",
+ fontStyle: "normal",
+ fontWeight: 400,
+ src: spaceNormal,
+ },
+]
diff --git a/app/utils/local-storage.ts b/app/utils/local-storage.ts
new file mode 100644
index 0000000..44f649b
--- /dev/null
+++ b/app/utils/local-storage.ts
@@ -0,0 +1,10 @@
+export const getStorageItem = (key: string) => localStorage.getItem(key)
+export const setStorageItem = (key: string, value: string) => {
+ try {
+ localStorage.setItem(key, value)
+ } catch (_e) {
+ return
+ }
+}
+
+export const THEME = "theme"
diff --git a/app/utils/scroll-into-view.ts b/app/utils/scroll-into-view.ts
new file mode 100644
index 0000000..27e19d8
--- /dev/null
+++ b/app/utils/scroll-into-view.ts
@@ -0,0 +1,21 @@
+export function scrollIntoView(e: React.MouseEvent, id: string, offset = -80, behavior: ScrollBehavior = "smooth") {
+ e.preventDefault()
+
+ const element = document.getElementById(id)
+ if (!element) return Promise.resolve()
+
+ const targetY = element.getBoundingClientRect().top + window.scrollY + offset
+
+ window.scrollTo({ top: targetY, behavior })
+
+ if (behavior !== "smooth") {
+ return Promise.resolve()
+ }
+
+ const distance = Math.abs(window.scrollY - targetY)
+ const duration = Math.min(distance / 2, 1000)
+
+ return new Promise((resolve) => {
+ setTimeout(resolve, duration)
+ })
+}
diff --git a/app/utils/split-slug.ts b/app/utils/split-slug.ts
new file mode 100644
index 0000000..5848dfe
--- /dev/null
+++ b/app/utils/split-slug.ts
@@ -0,0 +1,16 @@
+export function splitSlug(slug: string) {
+ const parts = slug.split("/")
+
+ if (parts.length < 3 || parts.length > 4) {
+ throw new Error(`Invalid slug format: expected 3 or 4 segments but got ${parts.length} — slug: ${slug}`)
+ }
+
+ const [version, section, third, fourth] = parts
+
+ return {
+ version,
+ section,
+ subsection: parts.length === 4 ? third : undefined,
+ filename: parts.length === 4 ? fourth : third,
+ }
+}
diff --git a/app/utils/css.test.ts b/app/utils/tests/css.test.ts
similarity index 96%
rename from app/utils/css.test.ts
rename to app/utils/tests/css.test.ts
index 2dfe8dd..78abdfc 100644
--- a/app/utils/css.test.ts
+++ b/app/utils/tests/css.test.ts
@@ -1,4 +1,4 @@
-import { cn } from "./css"
+import { cn } from "../css"
describe("cn", () => {
it("should merge classes", () => {
diff --git a/app/utils/tests/local-storage.test.ts b/app/utils/tests/local-storage.test.ts
new file mode 100644
index 0000000..e3efc61
--- /dev/null
+++ b/app/utils/tests/local-storage.test.ts
@@ -0,0 +1,62 @@
+import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"
+import { THEME, getStorageItem, setStorageItem } from "../local-storage"
+
+let store: Record
+let fake!: Storage
+
+function installFakeLocalStorage() {
+ store = {}
+ fake = {
+ getItem: vi.fn((k: string) => (k in store ? store[k] : null)),
+ setItem: vi.fn((k: string, v: string) => {
+ store[k] = String(v)
+ }),
+ removeItem: vi.fn((k: string) => {
+ delete store[k]
+ }),
+ clear: vi.fn(() => {
+ store = {}
+ }),
+ key: vi.fn((i: number) => Object.keys(store)[i] ?? null),
+ get length() {
+ return Object.keys(store).length
+ },
+ } as unknown as Storage
+
+ if (typeof window === "undefined") {
+ globalThis.localStorage = fake
+ return
+ }
+
+ vi.spyOn(window, "localStorage", "get").mockReturnValue(fake)
+}
+
+describe("local storage test suite", () => {
+ beforeEach(() => {
+ vi.restoreAllMocks()
+ installFakeLocalStorage()
+ localStorage.clear()
+ })
+
+ afterEach(() => {
+ vi.restoreAllMocks()
+ })
+
+ describe("getStorageItem", () => {
+ it("returns the stored value for the given key", () => {
+ localStorage.setItem(THEME, "dark")
+ expect(getStorageItem(THEME)).toBe("dark")
+ })
+
+ it("returns null if the key is not found", () => {
+ expect(getStorageItem("nonexistent")).toBeNull()
+ })
+ })
+
+ describe("setStorageItem", () => {
+ it("stores the value for the given key", () => {
+ setStorageItem(THEME, "light")
+ expect(localStorage.getItem(THEME)).toBe("light")
+ })
+ })
+})
diff --git a/app/utils/tests/split-slug.test.ts b/app/utils/tests/split-slug.test.ts
new file mode 100644
index 0000000..7a06d11
--- /dev/null
+++ b/app/utils/tests/split-slug.test.ts
@@ -0,0 +1,71 @@
+import { splitSlug } from "../split-slug"
+
+describe("splitSlug test suite", () => {
+ it("should split a slug with 3 parts (no subsection)", () => {
+ const result = splitSlug("v1.0.0/getting-started/intro")
+ expect(result).toEqual({
+ version: "v1.0.0",
+ section: "getting-started",
+ subsection: undefined,
+ filename: "intro",
+ })
+ })
+
+ it("should split a slug with 4 parts (with subsection)", () => {
+ const result = splitSlug("v1.0.0/getting-started/basics/intro")
+ expect(result).toEqual({
+ version: "v1.0.0",
+ section: "getting-started",
+ subsection: "basics",
+ filename: "intro",
+ })
+ })
+
+ it("should throw if slug has less than 3 parts", () => {
+ expect(() => splitSlug("v1.0.0/getting-started")).toThrowError(/expected 3 or 4 segments/i)
+ })
+
+ it("should throw if slug has more than 4 parts", () => {
+ expect(() => splitSlug("v1.0.0/section/subsection/file/extra")).toThrowError(/expected 3 or 4 segments/i)
+ })
+
+ it("should handle numeric or dashed parts", () => {
+ const result = splitSlug("v2.3.4/01-intro/02-basics/file-name")
+ expect(result).toEqual({
+ version: "v2.3.4",
+ section: "01-intro",
+ subsection: "02-basics",
+ filename: "file-name",
+ })
+ })
+
+ it("should handle version without 'v' prefix", () => {
+ const result = splitSlug("1.0.0/setup/install")
+ expect(result).toEqual({
+ version: "1.0.0",
+ section: "setup",
+ subsection: undefined,
+ filename: "install",
+ })
+ })
+
+ it("should handle special characters in parts", () => {
+ const result = splitSlug("v1.0.0/@special$/#weird$/file-name")
+ expect(result).toEqual({
+ version: "v1.0.0",
+ section: "@special$",
+ subsection: "#weird$",
+ filename: "file-name",
+ })
+ })
+
+ it("should handle uppercase letters in slug", () => {
+ const result = splitSlug("v1.0.0/GettingStarted/Intro")
+ expect(result).toEqual({
+ version: "v1.0.0",
+ section: "GettingStarted",
+ subsection: undefined,
+ filename: "Intro",
+ })
+ })
+})
diff --git a/app/utils/theme.ts b/app/utils/theme.ts
new file mode 100644
index 0000000..dcb932a
--- /dev/null
+++ b/app/utils/theme.ts
@@ -0,0 +1,17 @@
+import { THEME, setStorageItem } from "./local-storage"
+
+export function getSystemTheme(): "light" | "dark" {
+ if (typeof window === "undefined") return "light"
+ return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light"
+}
+
+export function getCurrentTheme(): "light" | "dark" {
+ if (typeof document === "undefined") return "light"
+ const theme = document.documentElement.getAttribute("data-theme")
+ return theme === "dark" ? "dark" : "light"
+}
+
+export function applyTheme(theme: "light" | "dark") {
+ document.documentElement.setAttribute("data-theme", theme)
+ setStorageItem(THEME, theme)
+}
diff --git a/content-collections.ts b/content-collections.ts
new file mode 100644
index 0000000..9f183c7
--- /dev/null
+++ b/content-collections.ts
@@ -0,0 +1,110 @@
+import { defineCollection, defineConfig } from "@content-collections/core"
+import { compileMDX } from "@content-collections/mdx"
+import rehypeSlug from "rehype-slug"
+import { z } from "zod"
+
+const DEFAULT_VERSION = "latest"
+
+// matches "v1.0.0", "1.0.0", or with suffix like "v1.0.0-alpha", "1.0.0-alpha"
+const isVersionFolder = (s: string) => /^v?\d+\.\d+\.\d+(-[\w.-]+)?$/.test(s)
+
+function splitPath(path: string) {
+ const parts = path.split("/")
+ const hasVersion = isVersionFolder(parts[0])
+ const withoutVersion = hasVersion ? parts.slice(1) : parts
+ const version = hasVersion ? parts[0] : DEFAULT_VERSION
+ return { hasVersion, parts, withoutVersion, version }
+}
+
+const sectionSchema = z.object({
+ title: z.string(),
+})
+
+/**
+ * Removes leading number prefixes like "01-", "02-" from each path segment.
+ */
+const cleanSlug = (path: string) =>
+ path
+ .split("/")
+ .map((seg) => seg.replace(/^\d{2,}-/, ""))
+ .join("/")
+
+/*
+ * This collection defines a documentation section shown in the sidebar of the package documentation.
+ *
+ * Each section is represented by a directory in the `content` folder and must contain an `index.md` file
+ * with metadata (title).
+ *
+ * - `title`: Used as the section heading in the sidebar.
+ *
+ * Sections must have unique `title` value.
+ *
+ * Sections can contain multiple `.mdx` pages or subdirectories with their own `.mdx` pages and `index.md` files.
+ */
+const section = defineCollection({
+ name: "section",
+ directory: "content",
+ include: "**/index.md",
+ schema: sectionSchema,
+ transform: (document) => {
+ const rawPath = document._meta.path
+ const { withoutVersion, version } = splitPath(rawPath)
+ const pathNoVersion = withoutVersion.join("/")
+ const slugNoVersion = cleanSlug(pathNoVersion)
+ const slug = `${version}/${slugNoVersion}`
+ return {
+ ...document,
+ slug,
+ sectionId: pathNoVersion.split("/")[0] || "root",
+ version,
+ }
+ },
+})
+
+const pageSchema = z.object({
+ title: z.string(),
+ summary: z.string(),
+ description: z.string(),
+})
+
+/*
+ * This collection defines an individual documentation page within the package documentation.
+ *
+ * Pages are `.mdx` files located inside section folders or their subdirectories.
+ *
+ * - `title`: Displayed as the page header.
+ * - `summary`: A short summary of the page.
+ * - `description`: A more detailed explanation of the page content.
+ *
+ * Each page must have a unique `title` within its section.
+ */
+const page = defineCollection({
+ name: "page",
+ directory: "content",
+ include: "**/**/*.mdx",
+ schema: pageSchema,
+ transform: async (document, context) => {
+ const rawPath = document._meta.path
+ const { withoutVersion, version } = splitPath(rawPath)
+ const pathNoVersion = withoutVersion.join("/")
+ const slugNoVersion = cleanSlug(pathNoVersion)
+ const slug = `${version}/${slugNoVersion}`
+ const content = await compileMDX(context, document, {
+ rehypePlugins: [rehypeSlug],
+ })
+ // rawMdx is the content without the frontmatter, used to read headings from the mdx file and create a content tree for the table of content component
+ const rawMdx = document.content.replace(/^---\s*[\r\n](.*?|\r|\n)---/, "").trim()
+ return {
+ ...document,
+ content,
+ slug,
+ section: withoutVersion[0] ?? "",
+ rawMdx,
+ version,
+ }
+ },
+})
+
+export default defineConfig({
+ collections: [section, page],
+})
diff --git a/content/01-started/01-installation.mdx b/content/01-started/01-installation.mdx
new file mode 100644
index 0000000..6a28be6
--- /dev/null
+++ b/content/01-started/01-installation.mdx
@@ -0,0 +1,67 @@
+---
+title: "Setting up React Router Devtools"
+summary: "Beginner's Guide"
+description: "Follow this page to learn how to set up React Router Devtools in your React Router project."
+---
+
+
+## Installation
+Adding React Router Devtools to your project is easy. First install it into your project by running:
+
+```bash
+npm install react-router-devtools -D
+```
+
+This will install it as a dev dependency in your project.
+
+## Enabling the tools
+
+After you have installed the tools, you need to go to your `vite.config.ts` file which will probably look something like this:
+
+```ts
+import { reactRouter } from '@react-router/dev/vite'
+import { defineConfig } from 'vite'
+import tsconfigPaths from 'vite-tsconfig-paths'
+
+export default defineConfig({
+ plugins: [reactRouter(), tsconfigPaths()],
+})
+
+```
+
+All you have to do is add the plugin into the `plugins` array in your `vite.config.ts` file.
+
+```diff
+import { reactRouter } from '@react-router/dev/vite'
+import { defineConfig } from 'vite'
+import tsconfigPaths from 'vite-tsconfig-paths'
++ import { reactRouterDevTools } from "react-router-devtools";
+
+export default defineConfig({
+- plugins: [reactRouter(), tsconfigPaths()],
++ plugins: [reactRouterDevTools(), reactRouter(), tsconfigPaths()],
+})
+
+```
+
+Make sure your plugin is BEFORE the react router one!
+
+
+### CloudFlare
+
+If you're trying to spin it up on CF, try adding this to your `optimizeDeps` in your `vite.config.js` file:
+```ts
+optimizeDeps: {
+ include: [
+ // other optimized deps
+ "beautify",
+ "react-diff-viewer-continued",
+ "classnames",
+ "@bkrem/react-transition-group",
+ ],
+},
+```
+
+**That's it!**
+
+You should now see the React Router Devtools in your browser when you run your app.
diff --git a/content/01-started/02-fac/01-common-questions.mdx b/content/01-started/02-fac/01-common-questions.mdx
new file mode 100644
index 0000000..aa47d71
--- /dev/null
+++ b/content/01-started/02-fac/01-common-questions.mdx
@@ -0,0 +1,12 @@
+---
+title: "Frequently Asked Questions"
+summary: "Common issues and answers when using React Router Devtools"
+description: "Find answers to common questions about installing, enabling, and troubleshooting React Router Devtools."
+---
+
+## Do I need to install React Router Devtools in production?
+
+No. You should only install it as a development dependency by running:
+
+```bash
+npm install react-router-devtools -D
diff --git a/content/01-started/02-fac/index.md b/content/01-started/02-fac/index.md
new file mode 100644
index 0000000..5dac46d
--- /dev/null
+++ b/content/01-started/02-fac/index.md
@@ -0,0 +1,3 @@
+---
+title: FYI
+---
diff --git a/content/01-started/04-guides/01-migration.mdx b/content/01-started/04-guides/01-migration.mdx
new file mode 100644
index 0000000..37d03db
--- /dev/null
+++ b/content/01-started/04-guides/01-migration.mdx
@@ -0,0 +1,26 @@
+---
+title: Migration guide
+description: Migration guide from remix-development-tools
+summary: Beginner's Guide
+---
+
+### vite.config.ts
+
+If you're migrating your `remix-development-tools` from v4.x to react-router v7 and you were already running it as
+a Vite plugin here is all you need to do:
+
+```diff
+import { defineConfig } from 'vite';
+- import { vitePlugin as remix } from '@remix-run/dev';
++ import { reactRouter } from '@react-router/dev/vite';
+- import { remixDevTools } from 'remix-development-tools'
++ import { reactRouterDevTools } from 'react-router-devtools'
+
+export default defineConfig({
+- plugins: [remixDevTools(), remix()],
++ plugins: [reactRouterDevTools(), reactRouter()],
+})
+```
+
+
+And that's it! You should be good to go. If you have any issues, please reach out to us.
diff --git a/content/01-started/04-guides/02-plugins.mdx b/content/01-started/04-guides/02-plugins.mdx
new file mode 100644
index 0000000..68f9e37
--- /dev/null
+++ b/content/01-started/04-guides/02-plugins.mdx
@@ -0,0 +1,21 @@
+---
+title: Plugins
+description: React Router Devtools plugins
+summary: Beginner's Guide
+---
+
+## Plugins in Vite
+Plugins work in a different way in Vite. You create a directory for plugins and just provide the path to the directory to the plugin. The plugin will automatically import all the plugins from the directory and add them to the dev tools. You only need to make sure your exports are named exports and not default exports and that they are uniquely named.
+
+You can create a directory called plugins in your project and add your plugins there. Then you can add the following to your vite.config.js file:
+```ts
+import { reactRouterDevTools } from "react-router-devtools";
+export default defineConfig({
+ plugins: [
+ reactRouterDevTools({
+ pluginDir: "./plugins"
+ })],
+});
+```
+
+After you're done share your plugin with the community by opening a discussion and a PR with the plugin to the repo!
diff --git a/content/01-started/04-guides/04-hydrogen-oxygen.mdx b/content/01-started/04-guides/04-hydrogen-oxygen.mdx
new file mode 100644
index 0000000..efbd9eb
--- /dev/null
+++ b/content/01-started/04-guides/04-hydrogen-oxygen.mdx
@@ -0,0 +1,91 @@
+---
+title: "Integration with Shopify Hydrogen and Oxygen"
+description: "Guide on getting react-router-devtools working with Shopify Hydrogen and Oxygen"
+summary: "Beginner's Guide"
+---
+
+## Adding react-router-devtools to your project
+
+Even though react-router-devtools is an ESM package, some of the dependencies it relies on are unfortunately not. This means that
+these dependencies will break the shopify CLI when running your React Router app built on top of Shopify Hydrogen and Oxygen.
+
+In case your package.json script `dev` command looks like this:
+
+```json
+"dev": "shopify hydrogen dev --codegen",
+```
+
+This means you'll have to do the following to get it working.
+
+Go to your `vite.config.ts` and add `react-router-devtools`, depending on your project the file will look something like this:
+```diff
+import { defineConfig } from 'vite';
+import { hydrogen } from '@shopify/hydrogen/vite';
+import { oxygen } from '@shopify/mini-oxygen/vite';
+import { reactRouter } from '@react-router/dev/vite';
+import tsconfigPaths from 'vite-tsconfig-paths';
++ import { reactRouterDevTools } from 'react-router-devtools';
+export default defineConfig({
+ plugins: [
++ reactRouterDevTools(),
+ hydrogen(),
+ oxygen(),
+ reactRouter({
+ presets: [hydrogen.preset()]
+ }),
+ tsconfigPaths(),
+ ],
+ build: {
+ assetsInlineLimit: 0,
+ },
+ ssr: {
+ optimizeDeps: {
+ include: [],
+ },
+ },
+});
+
+```
+## Adding problematic dependencies
+
+Add the following dependencies to `ssr.optimizeDeps.include` array:
+```diff
+export default defineConfig({
+ plugins: [
+ reactRouterDevTools(),
+ hydrogen(),
+ oxygen(),
+ reactRouter({
+ presets: [hydrogen.preset()]
+ }),
+ tsconfigPaths(),
+ ],
+ build: {
+ assetsInlineLimit: 0,
+ },
++ ssr: {
++ optimizeDeps: {
++ include: [
++ 'beautify',
++ 'react-diff-viewer-continued',
++ 'react-d3-tree',
++ ],
++ },
++ },
+});
+```
+
+### Debugging issues
+If you're still having issues, look at the error log output by the Shopify CLI and see if there are any errors related to the dependencies, the usual errors you might see are:
+- `require is not defined`
+- `module.exports is not defined`
+- `Cannot find module 'X'`
+
+This all indicated that there is a problem with a dependency that is used by react-router-devtools. Sometimes it's even a dependency not
+directly used by react-router-devtools, but it's a dependency of a dependency that is used by react-router-devtools.
+
+So if adding the first depedency in the error stack strace does not work, see if there are any additional dependencies in the stack trace before
+react-router-devtools. This package will be the last one in the stack trace.
+
+
+Enjoy your new react-router-devtools 🚀
diff --git a/content/01-started/04-guides/05-contributing.mdx b/content/01-started/04-guides/05-contributing.mdx
new file mode 100644
index 0000000..0ebc9a2
--- /dev/null
+++ b/content/01-started/04-guides/05-contributing.mdx
@@ -0,0 +1,19 @@
+---
+title: "Contributing to React Router Devtools"
+description: "Contributions to React Router Devtools are welcome! To contribute, please follow these guidelines."
+summary: "Beginner's Guide"
+
+---
+
+## Contributing
+
+Contributions to React Router Devtools are welcome! To contribute, please follow these guidelines:
+
+1. Fork the repository and clone it locally.
+2. Create a new branch for your feature or bug fix.
+3. Run `npm install`
+4. Run `npm run dev` to start the development server with a vanilla React Router app setup.
+5. Implement your changes, adhering to the existing code style and best practices.
+5. Please add tests for any new features or bug fixes.
+6. Commit and push your changes to your forked repository.
+7. Open a pull request, providing a clear description of your changes and their purpose.
diff --git a/content/01-started/04-guides/index.md b/content/01-started/04-guides/index.md
new file mode 100644
index 0000000..5bf01e8
--- /dev/null
+++ b/content/01-started/04-guides/index.md
@@ -0,0 +1,3 @@
+---
+title: Guides
+---
diff --git a/content/01-started/index.md b/content/01-started/index.md
new file mode 100644
index 0000000..f15cbd3
--- /dev/null
+++ b/content/01-started/index.md
@@ -0,0 +1,3 @@
+---
+title: Getting Started
+---
diff --git a/content/02-configuration/01-general.mdx b/content/02-configuration/01-general.mdx
new file mode 100644
index 0000000..e4d93c6
--- /dev/null
+++ b/content/02-configuration/01-general.mdx
@@ -0,0 +1,64 @@
+---
+title: React Router Devtools General Configuration
+description: General Configuration options for the React Router Devtools to interface with
+ your editor
+summary: Beginner's Guide
+---
+
+
+This covers the general configuration options for the React Router Devtools.
+
+## General Config
+
+```ts
+type GeneralConfig = {
+ pluginDir?: string
+ includeInProd?: {
+ client?: boolean
+ server?: boolean
+ }
+}
+```
+
+## `pluginDir`
+
+The relative path to your plugin directory. If you have a directory for react-router-devtools plugins you can point to it and they
+will be automatically imported and added to the dev tools.
+
+## `includeInProd`
+
+This option is used to set whether the plugin should be included in production builds or not.
+
+By default it is set to `undefined` and if you set this option to an object with the `client`, `context` and `server` properties set to `true` the plugin will be included in production builds.
+
+The client part includes the dev tools with the plugin and the server part includes the info logs. You can granularly configure the
+exact behavior of both sides with client and server configs respectively.
+
+
+Each of these flags will include a part of the plugin in production, in order for any of these to work `react-router-devtools` need to be switched over to
+a regular dependency and included in your project. If you only want to include the `devTools` helper in production, for example, you can
+set `includeInProd` to `{ devTools: true }` and the `devTools` part will be included in production and available always.
+
+
+ If you decide to deploy parts to production you should be very careful that you don't expose the dev tools to your clients or anybody
+ who is not supposed to see them. Also the server part uses chalk which might not work in non-node environments!
+
+ Also, if you wish to edit the plugin server config in production you can set `process.rdt_config` to an object with the same shape as the
+ config object and it will be used instead of the default production config (`{ silent: true }`).
+
+
+ ```ts
+ import { reactRouterDevTools } from "react-router-devtools";
+
+ export default defineConfig({
+ plugins: [
+ reactRouterDevTools({
+ includeInProd: {
+ client: true,
+ server: true,
+ devTools: true
+ },
+ }),
+ ],
+ });
+ ```
diff --git a/content/02-configuration/02-client.mdx b/content/02-configuration/02-client.mdx
new file mode 100644
index 0000000..71631e6
--- /dev/null
+++ b/content/02-configuration/02-client.mdx
@@ -0,0 +1,200 @@
+---
+title: React Router Devtools Client Configuration
+description: Configuration options for the React Router Devtools client
+summary: Beginner's Guide
+---
+
+
+All of the following options can be set in the dev tools panel **"Settings page"** and they override the default ones. Your preferences are
+stored in localStorage and if they do not exist there the default ones are used.
+
+
+Before explaining all the possible options here is the client configuration Typescript type:
+
+```ts
+type RdtClientConfig = {
+ position: "top-left" | "top-right" | "bottom-left" | "bottom-right" | "middle-left" | "middle-right";
+ liveUrls: { name: string, url: string }[];
+ liveUrlsPosition: "top-left" | "top-right" | "bottom-left" | "bottom-right";
+ defaultOpen: boolean;
+ expansionLevel: number;
+ height: number;
+ minHeight: number;
+ maxHeight: number;
+ hideUntilHover: boolean;
+ panelLocation: "top" | "bottom";
+ requireUrlFlag: boolean;
+ urlFlag: string;
+ breakpoints: {name: string, min: number, max: number }[],
+ routeBoundaryGradient: "sea" | "hyper" | "gotham" | "gray" | "watermelon" | "ice" | "silver";
+ showBreakpointIndicator: boolean;
+ showRouteBoundariesOn: "hover" | "click";
+}
+```
+
+Let's go through each option and see what it does.
+
+## Live URLs
+
+This option is used to set the live urls that will be displayed in the bottom left corner of the screen. The default value is an empty array.
+It allows you to specify multiple live urls that you can use to open the current page in a new tab.
+
+## Live URLs position
+
+This option is used to set the position of the live urls that will be displayed in the bottom left corner of the screen. The possible values are:
+- `top-left` - the live urls will be positioned at the top left corner of the screen
+- `top-right` - the live urls will be positioned at the top right corner of the screen
+- `bottom-left` - the live urls will be positioned at the bottom left corner of the screen
+- `bottom-right` - the live urls will be positioned at the bottom right corner of the screen
+
+## Position
+
+This option is used to set the position of the React Router Devtools trigger (the button that opens the panel). The possible values are:
+- `top-left` - the trigger will be positioned at the top left corner of the screen
+- `top-right` - the trigger will be positioned at the top right corner of the screen
+- `bottom-left` - the trigger will be positioned at the bottom left corner of the screen
+- `bottom-right` - the trigger will be positioned at the bottom right corner of the screen
+- `middle-left` - the trigger will be positioned at the middle left of the screen
+- `middle-right` - the trigger will be positioned at the middle right of the screen
+
+## Default Open
+
+This option is used to set the initial state of the panel. If set to `true` the panel will be open by default, if set to `false`
+the panel will be closed by default.
+
+## Expansion Level
+
+This option is used to set the initial expansion level of the returned JSON data in the **Active Page** tab. By default it is set to
+1 and if you open up the **Active Page** and look at the returned loader data it will look like this:
+
+```ts
+"data": { ... } +
+```
+
+If you set the expansion level to 1 the returned loader data will look like this:
+
+```ts
+"data": {
+ "property": "value"
+}
+```
+
+## Height
+
+This option is used to set the initial height of the panel. The default value is 400px.
+
+## Min Height
+
+This option is used to set the minimum height of the panel. The default value is 200px.
+
+## Max Height
+
+This option is used to set the maximum height of the panel. The default value is 800px.
+
+## Hide Until Hover
+
+This option is used to set whether the trigger should be hidden until you hover over it. The default value is `false`.
+
+## Panel Location
+
+This option is used to set the location of the panel. The possible values are:
+- `top` - the panel will be positioned at the top of the screen
+- `bottom` - the panel will be positioned at the bottom of the screen
+
+## Require URL Flag
+
+This option is used to set whether the panel should be opened only if the URL contains a specific flag. The default value is `false`.
+
+
+If you set this option to `true` and you forget to set the URL flag, the panel will hide and you will not be able to see it
+until you enter the url flag.
+
+The default one is `rdt=true` and if you set this option to `true` you will have to add `?rdt=true` to the URL in order to see the panel.
+
+
+## URL Flag
+
+This option is used to set the URL flag that is required to open the panel. The default value is `rdt`.
+
+You can set it to whatever you wish and if you set the **Require URL Flag** option to `true` you will have to add `?yourFlag=true` to the URL in order to see the panel.
+
+## Route Boundary Gradient
+
+This option is used to set the color of the route boundary gradient. The possible values are:
+- `sea`
+- `hyper`
+- `gotham`
+- `gray`
+- `watermelon`
+- `ice`
+- `silver`
+
+
+This changes the color of the route boundary gradient in the **Active Page** tab. When you hover over any route in the panel it will show you it's boundaries.
+
+
+The default value is `ice`.
+
+## Breakpoints
+
+This option allows you to define custom breakpoints that show in the bottom left corner of the panel to help you determine the current screen breakpoint you have defined.
+By default the breakpoints are set to tailwind breakpoints but you can change them to whatever you want.
+
+Eg:
+```ts
+breakpoints: [{name: "lg", min: 0, max: 768}, {name: "xl", min: 768, max: 1024}, {name: "2xl", min: 1024, max: Infinity}],
+```
+
+## Show breakpoint indicator
+
+This option allows you to show/hide the current breakpoint in the bottom left corner of the panel.
+
+## Show route boundaries on
+
+This option allows you to either show route boundaries when you hover a route segment on the pages tab or
+it shows a dedicated button called "Show Route Boundary" that shows the route boundary for that route on click.
+
+Default value is `click`;
+
+## Creating a custom configuration
+
+To create a custom configuration you can use the following code snippet:
+
+ ```ts
+ import { defineRdtConfig } from "react-router-devtools";
+
+ const customConfig = defineRdtConfig({
+ client: {
+ position: "top-right",
+ defaultOpen: true,
+ expansionLevel: 1,
+ height: 500,
+ minHeight: 300,
+ maxHeight: 1000,
+ hideUntilHover: true,
+ panelLocation: "bottom",
+ requireUrlFlag: true,
+ urlFlag: "customFlag",
+ routeBoundaryGradient: "gotham",
+ breakpoints: [{name: "lg", min: 0, max: 768}, {name: "xl", min: 768, max: 1024}, {name: "2xl", min: 1024, max: Infinity}],
+ showBreakpointIndicator: false
+ }
+ });
+
+ export default customConfig;
+ ```
+
+Then you can use this configuration in your `vite.config.js` file like this:
+
+```ts
+import customConfig from "./rdt.config";
+import { reactRouterDevTools } from "react-router-devtools";
+
+export default defineConfig({
+ plugins: [reactRouterDevTools(customConfig)],
+});
+```
+
+
+ Try opening up the dev tools panel deployed on this site and playing around with the settings in the settings tab!
+
diff --git a/content/02-configuration/03-editor.mdx b/content/02-configuration/03-editor.mdx
new file mode 100644
index 0000000..fa6f8b7
--- /dev/null
+++ b/content/02-configuration/03-editor.mdx
@@ -0,0 +1,82 @@
+---
+title: React Router Devtools Editor Configuration
+description: Configuration options for the React Router Devtools to interface with your
+ editor
+summary: Beginner's Guide
+---
+
+Everyone uses their own editors, so it's important to be able to configure the editor that React Router Devtools will open your files in.
+
+```ts
+type EditorConfig = {
+ name: string;
+ open(path: string, lineNumber: string | undefined): void;
+}
+```
+
+## `name`
+
+The name of the editor that will be displayed on the Open in Editor button.
+
+## `open`
+
+This function will be called when the user clicks the Open in Editor button. It will receive the path to the file and the line number to open the file at.
+This function will both handle the case where you shift + right click an element on the page AND the open in X button in the UI, they return different values
+so be sure to cover both of them.
+
+```ts
+import { exec } from "node:child_process";
+import { normalizePath } from "vite";
+
+function open(path: string, lineNumber: string | undefined) {
+ exec(`code -g "${normalizePath(path)}${lineNumber ? `:${lineNumber}` : ""}"`);
+}
+```
+
+## Editors
+
+Below are some examples of configurations for popular editors.
+
+### VS Code
+
+To use VS Code as your editor, you don't need to do anything, it's the default editor.
+
+### WebStorm
+
+To use WebStorm as your editor, you can use the following configuration:
+
+```ts
+import { exec } from "node:child_process";
+import { cwd } from "node:process";
+
+const editor = {
+ name: "WebStorm",
+ open(path, lineNumber) {
+ exec(
+ `webstorm "${process.cwd()}/${path}" --line ${lineNumber ? `--line ${lineNumber}` : ""}`.replace(
+ /\$/g,
+ "\\$",
+ ),
+ );
+ },
+};
+```
+
+### GoLand
+
+To use WebStorm as your editor, you can use the following configuration:
+
+```ts
+import { exec } from "node:child_process";
+import { cwd } from "node:process";
+
+const editor = {
+ name: "WebStorm",
+ open(path, lineNumber) {
+ if (!path) return;
+ exec(
+ `goland "${process.cwd()}/${path}" ${lineNumber ? `--line ${lineNumber}` : ""}`
+ );
+ },
+};
+```
diff --git a/content/02-configuration/04-server.mdx b/content/02-configuration/04-server.mdx
new file mode 100644
index 0000000..8ed8c70
--- /dev/null
+++ b/content/02-configuration/04-server.mdx
@@ -0,0 +1,71 @@
+---
+title: React Router Devtools Server Configuration
+description: Configuration options for the React Router Devtools server
+summary: Beginner's Guide
+---
+
+As with the client configuration, we will first see the full configuration type:
+
+```ts
+interface ReactRouterServerConfig {
+ silent?: boolean;
+ logs?: {
+ cookies?: boolean;
+ defer?: boolean;
+ actions?: boolean;
+ loaders?: boolean;
+ cache?: boolean;
+ siteClear?: boolean;
+ serverTimings?: boolean;
+ };
+}
+```
+
+## `silent`
+
+When `true`, the server will not log anything to the console. This is useful for production environments.
+
+## `logs`
+
+This object allows you to configure the server logs. Each key is a log type and the value is a boolean indicating whether to log that type.
+All are `true` by default so you don't have to provide anything, if you want to be granular you can, otherwise you can use the `silent` option to turn off
+all logs.
+
+### `cookies`
+
+When `true`, the server will log all cookies sent by the server in the "Set-Cookie" header.
+
+### `defer`
+
+When `true`, the server will log all deferred actions.
+The following gets logged:
+- The defer location
+- The keys that were deferred
+- The time it took for each key to resolve
+
+### `actions`
+
+When `true`, the server will log all actions that are hit with a request.
+
+### `loaders`
+
+When `true`, the server will log all loaders that are hit with a request.
+
+### `cache`
+
+When `true`, the server will log all loaders/actions that return a `Cache Control` header.
+
+### `siteClear`
+
+When `true`, the server will log when the site cache is cleared, or anything else with the `Clear-Site-Data` header.
+
+### `serverTimings`
+
+When `true`, the server will log all server timings that are returned with a request
+
+## `serverTimingThreshold`
+
+This option is used to set the threshold for server timings to be logged in the console.
+If the server timing is greater than this threshold, it will be logged in red, otherwise it will be logged in green.
+
+By default it is set to `Number.POSITIVE_INFINITY` which means that all server timings will be logged in green.
diff --git a/content/02-configuration/index.md b/content/02-configuration/index.md
new file mode 100644
index 0000000..460f763
--- /dev/null
+++ b/content/02-configuration/index.md
@@ -0,0 +1,3 @@
+---
+title: Configuration
+---
diff --git a/content/03-features/01-shortcuts.mdx b/content/03-features/01-shortcuts.mdx
new file mode 100644
index 0000000..e579c2d
--- /dev/null
+++ b/content/03-features/01-shortcuts.mdx
@@ -0,0 +1,28 @@
+---
+title: Keyboard Shortcuts
+description: Detailed overview of all keyboard shortcuts in React Router Devtools
+summary: Beginner's Guide
+---
+
+## Go To Source
+
+**Shift + Right Click**
+
+When you are in the browser and you want to go to the source code of a component, you can right click on the component
+while holding down shift. This will open the source code of the component in your code editor.
+
+## Opening/closing the DevTools
+
+**Shift + A**
+
+When you are in the browser and you want to open the React Router Devtools, you can press `Shift + A`.
+This will open the DevTools, if you're already in the DevTools, it will close it.
+
+While in the DevTools, you can also use `Esc` to close them.
+
+From version 4.2.0 is fully configurable and you can change the shortcut in the settings.
+
+We use [react-hotkeys-hook](https://www.npmjs.com/package/react-hotkeys-hook) to handle the keyboard shortcuts under the hood.
+You can adapt to their API to add your own shortcuts.
+
+Check out the settings tab for details
diff --git a/content/03-features/02-devtools.mdx b/content/03-features/02-devtools.mdx
new file mode 100644
index 0000000..a0c209c
--- /dev/null
+++ b/content/03-features/02-devtools.mdx
@@ -0,0 +1,195 @@
+---
+title: Devtools context
+description: Using the devtools context to trace events and send them to the network tab
+summary: Beginner's Guide
+---
+
+## Devtools extended context
+
+The devtools context is a set of utilities that you can use in your data fetching functions to trace events
+in the network tab of react-router-devtools. You can also include them in your production builds if you do not want
+the hassle of having to optionally check if they are defined.
+
+The general usage of the devtools context is as follows:
+
+```ts
+// The devTools object is available in all data fetching functions
+export const loader = async ({ request, devTools }: LoaderFunctionArgs) => {
+ const tracing = devTools?.tracing;
+ // tracing is a set of utilities to be used in your data fetching functions to trace events
+ // in network tab of react-router-devtools
+ const startTime = tracing.start("my-event")
+ // do something here, eg DB call
+ tracing.end("my-event", startTime!)
+ return "data"
+}
+```
+
+You can also use the devtools context in your action functions:
+
+```ts
+export const action = async ({ request, devTools }: ActionFunctionArgs) => {
+ const tracing = devTools?.tracing;
+ // tracing is a set of utilities to be used in your data fetching functions to trace events
+ // in network tab of react-router-devtools
+ const startTime = tracing?.start("my-event")
+ // do something
+ tracing?.end("my-event", startTime!)
+ return "data"
+}
+```
+
+The devtools context is also available in your client loader and client action functions:
+
+```ts
+export const clientLoader = async ({ request, devTools }: ClientLoaderFunctionArgs) => {
+ const tracing = devTools?.tracing;
+ // tracing is a set of utilities to be used in your data fetching functions to trace events
+ // in network tab of react-router-devtools
+ const startTime = tracing?.start("my-event")
+ // do something
+ tracing?.end("my-event", startTime!)
+ return "data"
+}
+```
+
+```ts
+export const clientAction = async ({ request, devTools }: ClientActionFunctionArgs) => {
+ const tracing = devTools?.tracing;
+ // tracing is a set of utilities to be used in your data fetching functions to trace events
+ // in network tab of react-router-devtools
+ const startTime = tracing?.start("my-event")
+ // do something
+ tracing?.end("my-event", startTime!)
+ return "data"
+}
+```
+
+
+
+ If you want to make the devTools available always in your project, you can set `includeInProd` to `{ devTools: true }` in your vite config.
+
+ In production the trace calls won't do anything, but the tracing will be more convinient to use.
+
+ If you do so you can also override the types by adding the following to your project:
+ ```ts
+ import type { ExtendedContext } from "react-router-devtools/context";
+
+ declare module "react-router" {
+ interface LoaderFunctionArgs {
+ devTools: ExtendedContext
+ }
+ interface ActionFunctionArgs {
+ devTools: ExtendedContext
+ }
+ }
+ ```
+
+
+## RouteId
+
+The routeId is a string that is used to identify the route that is being processed. You can access it like so:
+```ts
+const loader = async ({ request, devTools }: LoaderFunctionArgs) => {
+ const routeId = devTools?.routeId;
+ // do something with the routeId
+ return "data"
+}
+```
+
+## Tracing
+
+The tracing object contains all the utilities related to network tab tracing feature of react-router-devtools.
+
+
+There are three functions you can use:
+- trace
+- start
+- end
+
+
+
+### trace
+
+The `trace` function is a function that will trace the event given to it, pipe it to the network tab of react-router-devtools and show you analytics.
+
+This works by calling the provided function and analyzing the time it takes to execute it.
+
+```ts
+const loader = async ({ request, devTools }: LoaderFunctionArgs) => {
+ const tracing = devTools?.tracing;
+ // this will be traced in the network tab of react-router-devtools
+ const user = tracing?.trace("my-event",() => getUser())
+
+ return { user }
+}
+```
+
+#### Parameters
+
+- `name` - The name of the event
+- `event` - The event to be traced
+
+#### Returns
+
+The result of the event
+
+### start
+
+The `start` function is a function that will start a trace for the name provided to it and return the start time.
+This is used together with `end` to trace the time of the event.
+
+```ts
+export const loader = async ({ request, devTools }: LoaderFunctionArgs) => {
+ const tracing = devTools?.tracing;
+ // this will be traced in the network tab of react-router-devtools
+ const startTime = tracing?.start("my-event")
+ // do something here, eg DB call
+
+ // End the trace
+ tracing?.end("my-event", startTime!)
+ return "data"
+}
+```
+
+
+ This function relies on you using the `end` with the same name as the start event, otherwise
+you will end up having a never ending loading bar in the network tab!
+
+
+
+#### Parameters
+
+- `name` - The name of the event
+
+#### Returns
+
+The start time of the event
+
+### end
+
+The `end` function is a function that will end a trace for the name provided to it and return the end time.
+
+```ts
+export const loader = async ({ request, devTools }: LoaderFunctionArgs) => {
+ const tracing = devTools?.tracing;
+ // this will be traced in the network tab of react-router-devtools
+ const startTime = tracing?.start("get user")
+ // do something here, eg DB call
+ const user = await getUser();
+ // End the trace
+ tracing?.end("get user", startTime!, { user })
+ return "data"
+
+}
+```
+
+#### Parameters
+
+- `name` - The name of the event
+- `startTime` - The start time of the sendEvent
+- `data` - The data to be sent with the event
+
+#### Returns
+
+The data provided in the last parameter
diff --git a/content/03-features/03-active-page-tab.mdx b/content/03-features/03-active-page-tab.mdx
new file mode 100644
index 0000000..5b8fdf5
--- /dev/null
+++ b/content/03-features/03-active-page-tab.mdx
@@ -0,0 +1,117 @@
+---
+title: "Active Page Tab"
+description: "Detailed overview of all features on the active page tab."
+summary: "Beginner's Guide"
+---
+
+The Active Page tab is the first tab that appears when you open up the dev tools panel. It contains an overview of all active loaders
+on the current page and detailed information about each loader.
+
+## Route boundaries
+
+The first feature we will go over is the route boundaries. This feature shows you the current route boundaries on the actual page.
+This is useful for debugging and testing purposes. It finds the ` ` component in the route and highlights it with a
+gradient background that can be set in the settings.
+
+
+ This feature is only available in the development mode because it used react dev tools to find the ` ` component.
+
+ If you want to try it open up the dev tools right now nad hover over `/docs/main` in the panel.
+
+ You can also change the gradient background color in the settings.
+
+
+## Loader list
+
+The loader list is a list of all active loaders on the current page. It shows the url segment of the loader,
+the loader type and the loader file.
+
+
+ The loader type is determined by the routing convention.
+ - `purple` - represents the root.tsx file
+ - `blue` - represents a pathless layout file
+ - `green` - represents a normal route file, whether index or not
+
+
+### Open in VS code
+
+Each segment has an **open in VS code** button that opens the loader file in VS code.
+This is useful for quick navigation to the loader file.
+
+
+This only works if you have the `code` command installed in your terminal. If you don't have it installed you can
+ install it by following the instructions [here](https://code.visualstudio.com/docs/setup/mac#_launching-from-the-command-line).
+
+
+### Loader data
+
+Each segment has a loader data **JSON** object that contains all the information returned by the loader of that segment.
+
+If you open the dev tools on this page and look at the `/docs/main` segment you will see the **loader data object** which contains
+`metadata`, `tag`, `serverData`, `deferredServerData` and `key` properties.
+
+This part will contain everything returned from the server and it will be **hot swapped** if the data changes.
+
+
+ When keys are deferred on the server, the data will hot swap when the key is resolved on the client.
+
+
+
+### Route params
+
+The route params section contains all the route params for the current segment.
+
+This will contain all the **wildcard** params currently available on this route.
+
+If you open up the dev tools, you will be able to see that `tag` and `slug` are both in
+the route params.
+
+### Server info
+
+The server info section contains all the server information for the current segment, including:
+- `loaderTriggerCount` - the number of times the loader has been triggered (updates in real-time)
+- `actionTriggerCount` - the number of times the action has been triggered (updates in real-time)
+- `lowestExecutionTime` - the lowest execution time of the loader (updates in real-time)
+- `highestExecutionTime` - the highest execution time of the loader (updates in real-time)
+- `averageExecutionTime` - the average execution time of the loader (updates in real-time)
+- `lastLoaderInfo` - the last loader info object (updates in real-time), includes execution time, request headers and response headers.
+- `lastActionInfo` - the last action info object (updates in real-time), includes execution time, request headers and response headers.
+- `loaderCalls` - an array of loaderInfo objects ordered from most recent to least recent (updates in real-time)
+- `actionCalls` - an array of actionInfo objects ordered from most recent to least recent (updates in real-time)
+
+### handles
+
+The handles section contains all the handles for the current segment.
+
+This will contain all the **handles** currently available on this route.
+
+React Router allows you to export a custom **handle** export which can be anything, it will be shown here if it is exported.
+
+## Revalidation
+
+There is a **Revalidate** button that allows you to revalidate all the loaders on the page.
+
+
+## Timeline
+
+The timeline section on the right contains useful information on navigation and submission events in your application.
+
+Every time there is a navigation or submission event, a new entry will be added to the timeline on the top.
+
+It is limited to 50 entries and will remove the oldest entry when the limit is reached.
+
+The timeline will contain the following information for each event:
+- `type` - the type of event (navigation or submission, fetcher or normal)
+- `method` - the method of the event (GET, POST, PUT, DELETE)
+- `url` - the url of the event
+- `data sent` - the data sent in the event
+- `response` - the response of the event
+
+
+This only happens for events that change the state of the app, if there is a client-side navigation to a
+new location that has no loaders nothing will happen because the state has remained idle.
+
+
+### Clearing the timeline
+
+You can clear the timeline by clicking the **clear** button at the top right of the timeline.
diff --git a/content/03-features/04-routes-tab.mdx b/content/03-features/04-routes-tab.mdx
new file mode 100644
index 0000000..de906b6
--- /dev/null
+++ b/content/03-features/04-routes-tab.mdx
@@ -0,0 +1,51 @@
+---
+title: Routes Tab
+description: Detailed overview of all features on the Routes Tab.
+summary: Beginner's Guide
+---
+
+The Routes tab shows you all the routes in your React Router application either in the tree view or a list view.
+The default is the tree view which shows the routes in a nested tree structure. You can switch to the list view by
+ clicking the list icon in the top left corner of the tab.
+
+The featureset is identical across both but only shown differently based on your preference.
+
+The only difference is the fact that the **tree view** shows you which routes are currently active on the page. This is
+ indicated by a golden line going through the tree from the root to the active route. The **list view** does not have this
+ feature.
+
+## Route types
+
+There are three types of routes in react-router-devtools:
+- *root* - The root route is the first route that is loaded when you open the application.
+It is the first route in the tree. (purple)
+- *route* - A route is a route that is not a root route. It is a route that is nested under another route and has
+a url segment. (green)
+- *layout* - A layout is a route that is not a root route and is a special kind of route that does not have a url
+segment but provides only an outlet with some layout for the child routes (blue)
+
+## Route info
+
+Clicking on any route name will show you detailed information about that route. This includes the route's name, the
+route's path, the route's url, the route's file and does it contain the following things:
+- *loader* - The loader is the function that is called when the route is loaded. It is responsible for fetching the data
+ needed for the route.
+- *action* - The action is the function that is called when the route is submitted. It is responsible for handling the
+ form submission.
+- *ErrorBoundary* - The ErrorBoundary is the component that is called when the route has an error. It is responsible for
+ showing the error message to the user.
+
+All of these segments are colored in either red or green indicating if it exists or not.
+
+
+ The error boundary will tell you if the error boundary for the current route comes from the route itself or is inherited
+ from a parent route. If it is inherited, it will show you the name of the parent route.
+
+
+## Wildcard parameters
+
+If a route has a wildcard parameter, it will be shown in the **Wildcard parameters** section which allows you to enter
+any value for the wildcard parameter. This is useful when combined with the **Open in Browser** button that redirects
+you to the route with the wildcard parameter.
+
+The wildcard values are saved in the browser so you can persist them across development sessions.
diff --git a/content/03-features/05-network-tab.mdx b/content/03-features/05-network-tab.mdx
new file mode 100644
index 0000000..89ab703
--- /dev/null
+++ b/content/03-features/05-network-tab.mdx
@@ -0,0 +1,39 @@
+---
+title: Network Tab
+description: Detailed overview of all features on the Network Tab.
+summary: Beginner's Guide
+---
+
+The Network tab traces all the network requests that are happening in your application.
+
+It shows you all the requests in real-time, with the ability to see if they are aborted, if they are cached, and if they are successful or not.
+
+Clicking on a request will show you detailed information about that request. Additionally, you can shuffle through the requests with your keyboard.
+To shuffle through the requests, press the `←` and `→` keys.
+
+## Request types
+
+There are four types of requests in react-router-devtools:
+- **client-loader** - A client-loader is a request that is initiated by the client and is used to load data for a route.
+- **client-action** - A client-action is a request that is initiated by the client and is used to submit data to a route.
+- **loader** - A loader is a request that is initiated by the server and is used to load data for a route.
+- **action** - An action is a request that is initiated by the server and is used to submit data to a route.
+
+
+ Each of these is colored differently for you to be able to quickly identify them.
+- loader - green
+- client-loader - blue
+- action - purple
+- client-action - yellow
+- aborted requests - red
+
+
+## Request info
+
+Clicking on any request name will show you detailed information about that request. This includes the request's name, the
+request's method, the request's status, the request's start time, the request's end time, the request's type,
+the request's data, the request's headers, and if the request's cached.
+
+## Aborted requests
+
+If a request is aborted, it will be shown in red. This means that the request was aborted by the user.
diff --git a/content/03-features/06-errors-tab.mdx b/content/03-features/06-errors-tab.mdx
new file mode 100644
index 0000000..b4819e8
--- /dev/null
+++ b/content/03-features/06-errors-tab.mdx
@@ -0,0 +1,39 @@
+---
+title: Errors Tab
+description: Detailed overview of all features on the Errors Tab.
+summary: Beginner's Guide
+---
+
+The errors tab is a powerful tool for debugging issues with your react code, namely invalid HTML.
+It helps you detect potential HTML issues in your code, such as invalid HTML nesting or hydration issues.
+
+## Invalid HTML
+
+If you have invalidely nested HTML (eg. a `div` inside a `p`), you will see an error in the errors tab.
+These kind of nesting issues can cause unexpected behavior in your application, namely hydration issues.
+The browser does a lot of work to make sure that the HTML you send to the client is valid so it can
+sometimes move the order of elements around to make sure it's valid. This can cause unexpected hydration
+issues in your application.
+
+Whenever there is a case of this found in your html the errors tab will show you the error and the file
+where the error is found. If the error is found in a file that is a part of your project you can click on the
+file name to open the file in your editor and change the issue right away.
+
+## Hydration Mismatch
+
+Hydration mismatch is a common issue in React applications. It occurs when the server-rendered HTML does not match the
+HTML generated by the client. This can cause unexpected behavior in your application,
+such as the loss of user input or the loss of scroll position. In React Router it can also cause FOUC (Flash of Unstyled Content).
+
+To avoid hydration mismatch, you should make sure that the HTML generated by the server matches the HTML generated by
+the client.
+
+These kind of issues are very hard to track down because they can be caused by a lot of different things.
+
+If a hydration mismatch happens the errors tab will show you the **diff** between the server and client HTML, allowing
+you to analyze the differences and fix the issue.
+
+
+Hydration mismatches happen on document requests (hard refresh or initial load in React Router). So if you don't see it at first
+try refreshing your page.
+
diff --git a/content/03-features/07-settings-tab.mdx b/content/03-features/07-settings-tab.mdx
new file mode 100644
index 0000000..60e8838
--- /dev/null
+++ b/content/03-features/07-settings-tab.mdx
@@ -0,0 +1,96 @@
+---
+title: Settings Tab
+description: Detailed overview of all features on the Settings Tab.
+summary: Beginner's Guide
+---
+
+The settings tab is where you can override the default settings for your project.
+
+
+## Position
+
+This option is used to set the position of the React Router Devtools trigger (the button that opens the panel). The possible values are:
+- `top-left` - the trigger will be positioned at the top left corner of the screen
+- `top-right` - the trigger will be positioned at the top right corner of the screen
+- `bottom-left` - the trigger will be positioned at the bottom left corner of the screen
+- `bottom-right` - the trigger will be positioned at the bottom right corner of the screen
+- `middle-left` - the trigger will be positioned at the middle left of the screen
+- `middle-right` - the trigger will be positioned at the middle right of the screen
+
+## Default Open
+
+This option is used to set the initial state of the panel. If set to `true` the panel will be open by default, if set to `false`
+the panel will be closed by default.
+
+## Expansion Level
+
+This option is used to set the initial expansion level of the returned JSON data in the **Active Page** tab. By default it is set to
+0 and if you open up the **Active Page** and look at the returned loader data it will look like this:
+
+```ts
+"data": { ... } +
+```
+
+If you set the expansion level to 1 the returned loader data will look like this:
+
+```ts
+"data": {
+ "property": "value"
+}
+```
+
+## Height
+
+This option is used to set the initial height of the panel. The default value is 400px.
+
+## Min Height
+
+This option is used to set the minimum height of the panel. The default value is 200px.
+
+## Max Height
+
+This option is used to set the maximum height of the panel. The default value is 800px.
+
+## Hide Until Hover
+
+This option is used to set whether the trigger should be hidden until you hover over it. The default value is `false`.
+
+## Panel Location
+
+This option is used to set the location of the panel. The possible values are:
+- `top` - the panel will be positioned at the top of the screen
+- `bottom` - the panel will be positioned at the bottom of the screen
+
+## Require URL Flag
+
+This option is used to set whether the panel should be opened only if the URL contains a specific flag. The default value is `false`.
+
+
+If you set this option to `true` and you forget to set the URL flag, the panel will hide and you will not be able to see it
+until you enter the url flag.
+
+The default one is `rdt=true` and if you set this option to `true` you will have to add `?rdt=true` to the URL in order to see the panel.
+
+
+## URL Flag
+
+This option is used to set the URL flag that is required to open the panel. The default value is `rdt`.
+
+You can set it to whatever you wish and if you set the **Require URL Flag** option to `true` you will have to add `?yourFlag=true` to the URL in order to see the panel.
+
+## Route Boundary Gradient
+
+This option is used to set the color of the route boundary gradient. The possible values are:
+- `sea`
+- `hyper`
+- `gotham`
+- `gray`
+- `watermelon`
+- `ice`
+- `silver`
+
+
+This changes the color of the route boundary gradient in the **Active Page** tab. When you hover over any route in the panel it will show you it's boundaries.
+
+
+The default value is `ice`.
diff --git a/content/03-features/08-detach.mdx b/content/03-features/08-detach.mdx
new file mode 100644
index 0000000..5526693
--- /dev/null
+++ b/content/03-features/08-detach.mdx
@@ -0,0 +1,15 @@
+---
+title: Detached mode
+description: How you can detach your panel into a new window
+summary: Beginner's Guide
+---
+
+There is a special button on the bottom left side of the panel above the X button.
+When you click on it, the panel will detach and open in a new window.
+
+The detached window will keep in sync with the main panel and will show the same content.
+The logs on the server will happen twice, once for the main panel and once for the detached window.
+
+When you close the detached window, or the main panel, the other one will be terminated and closed.
+In case the detached mode hangs for some reason, you can always return it to the main site by
+clicking the trigger while in detached mode.
diff --git a/content/03-features/index.md b/content/03-features/index.md
new file mode 100644
index 0000000..ea7f610
--- /dev/null
+++ b/content/03-features/index.md
@@ -0,0 +1,3 @@
+---
+title: Features
+---
diff --git a/content/_index.mdx b/content/_index.mdx
new file mode 100644
index 0000000..0f0f79b
--- /dev/null
+++ b/content/_index.mdx
@@ -0,0 +1,33 @@
+---
+title: Quick Start
+summary: React Router Devtools is a set of tools that help you to develop your React Router application.
+description: React Router Devtools is a set of tools that help you to develop your React Router application.
+---
+
+This documentation covers everything you need to know to get started with `react-router-devtools`.
+
+## Prerequisites
+
+- React Router version **7.0** or higher.
+- Your project needs to run on **ESM**. If you are using CommonJS, you will need to convert your project to ESM.
+
+## Why ESM?
+
+In order to use the full feature-set of **Vite** the project has to run on ESM. This is because Vite exposes a websocket
+that **react-router-devtools** uses to communicate with the server. This websocket is **only** available in ESM projects
+because it's exposed by `import.meta` which is only available in ESM.
+
+To avoid creating user confusion and giving you a subpar experience, we have decided to only support ESM projects running on Vite.
+
+
+## Why use `react-router-devtools`?
+
+`react-router-devtools` is a set of tools that help you to develop your React Router application.
+
+They help you, but are not limited to, to do the following things:
+- **Loader data display** - You can see the data that is being loaded by your loaders.
+- **Route display** - You can see the routes that are being used by your application in list/tree format.
+- **Error tracking** - You can see invalid HTML rendered on your page and where it's coming from.
+- **Hydration mismatch tracking** - You can see if there are any hydration mismatches in your application, what was rendered on the client and what was rendered on the server.
+- **Server logs** - You can see the logs of your server in the browser.
+- **Route boundaries** - You can see the route boundaries by hovering over elements.
diff --git a/knip.json b/knip.json
index 2923768..10fa803 100644
--- a/knip.json
+++ b/knip.json
@@ -1,9 +1,15 @@
{
"$schema": "https://unpkg.com/knip@5/schema.json",
- "entry": ["scripts/*.{ts,js}", "app/routes.ts", "app/server/*.ts", "app/library/icon/Icon.tsx"],
+ "entry": ["scripts/*.{ts,js}", "app/routes.ts", "app/server/*.ts", "app/ui/icon/Icon.tsx"],
"remix": true,
"lefthook": true,
"project": ["**/*.{js,cjs,mjs,jsx,ts,cts,mts,tsx}"],
- "ignore": ["app/library/icon/icons/types.ts", "react-router.config.ts"],
- "ignoreDependencies": ["@babel/preset-typescript", "babel-plugin-react-compiler", "tailwindcss"]
+ "ignore": ["app/ui/icon/icons/types.ts", "react-router.config.ts", "content-collections.ts"],
+ "ignoreDependencies": [
+ "@babel/preset-typescript",
+ "babel-plugin-react-compiler",
+ "tailwindcss",
+ "@tailwindcss/typography",
+ "rehype-slug"
+ ]
}
diff --git a/package.json b/package.json
index c986f6c..bae01ee 100644
--- a/package.json
+++ b/package.json
@@ -1,5 +1,5 @@
{
- "name": "@forge42/base-stack",
+ "name": "@forge42/docs-template",
"version": "0.0.1",
"author": "forge-42",
"private": true,
@@ -10,23 +10,31 @@
"execute": "tsx",
"clean": "git clean -fdX --exclude=\"!.env\"",
"script": "tsx scripts/setup.ts",
- "cleanup": "pnpm run script scripts/cleanup.ts",
+ "prebuild": "pnpm run content-collections:build",
"build": "react-router build",
+ "predev": "pnpm run typegen",
"dev": "react-router dev",
"start": "NODE_ENV=production node ./build/server/index.js",
+ "pretest": "pnpm run content-collections:build && pnpm run typegen",
"test": "vitest run --browser.headless",
"test:ui": "vitest",
"test:cov": "vitest run --coverage --browser.headless",
+ "pretypecheck": "pnpm run content-collections:build && pnpm run typegen",
"typecheck": "tsc",
"validate": "pnpm run check && pnpm run typecheck && pnpm run test && pnpm run check:unused",
"check": "biome check .",
"check:fix": "biome check --fix .",
+ "precheck:unused": "pnpm run content-collections:build && pnpm run typegen",
"check:unused": "knip --max-issues 1",
"check:unused:fix": "knip --fix",
"typegen": "react-router typegen",
- "postinstall": "pnpm run typegen"
+ "content-collections:build": "content-collections build"
},
"dependencies": {
+ "@content-collections/cli": "0.1.6",
+ "@content-collections/core": "0.10.0",
+ "@content-collections/mdx": "0.2.2",
+ "@content-collections/remix-vite": "0.2.2",
"@epic-web/client-hints": "1.3.5",
"@forge42/seo-tools": "1.3.0",
"@react-router/node": "7.2.0",
@@ -42,8 +50,10 @@
"react-i18next": "15.4.0",
"react-router": "7.2.0",
"react-router-hono-server": "2.10.0",
+ "rehype-slug": "6.0.0",
"remix-hono": "0.0.18",
"remix-i18next": "7.0.2",
+ "slug": "11.0.0",
"tailwind-merge": "3.0.1",
"zod": "3.24.1"
},
@@ -52,13 +62,14 @@
"@biomejs/biome": "1.9.4",
"@dotenvx/dotenvx": "1.34.0",
"@react-router/dev": "7.2.0",
- "@react-router/fs-routes": "7.2.0",
+ "@tailwindcss/typography": "0.5.16",
"@tailwindcss/vite": "4.0.9",
"@testing-library/react": "16.2.0",
"@types/node": "22.13.1",
"@types/prompt": "1.1.9",
"@types/react": "19.0.8",
"@types/react-dom": "19.0.3",
+ "@types/slug": "5.0.9",
"@vitest/browser": "3.0.5",
"@vitest/coverage-v8": "3.0.5",
"@vitest/ui": "3.0.5",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 03e42ab..94b4cb7 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -8,6 +8,18 @@ importers:
.:
dependencies:
+ '@content-collections/cli':
+ specifier: 0.1.6
+ version: 0.1.6(@content-collections/core@0.10.0(typescript@5.7.3))
+ '@content-collections/core':
+ specifier: 0.10.0
+ version: 0.10.0(typescript@5.7.3)
+ '@content-collections/mdx':
+ specifier: 0.2.2
+ version: 0.2.2(@content-collections/core@0.10.0(typescript@5.7.3))(acorn@8.15.0)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
+ '@content-collections/remix-vite':
+ specifier: 0.2.2
+ version: 0.2.2(@content-collections/core@0.10.0(typescript@5.7.3))(vite@6.2.0(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2)(yaml@2.8.0))
'@epic-web/client-hints':
specifier: 1.3.5
version: 1.3.5
@@ -52,13 +64,19 @@ importers:
version: 7.2.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
react-router-hono-server:
specifier: 2.10.0
- version: 2.10.0(@react-router/dev@7.2.0(@types/node@22.13.1)(babel-plugin-macros@3.1.0)(jiti@2.4.2)(lightningcss@1.29.1)(react-router@7.2.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(tsx@4.19.2)(typescript@5.7.3)(vite@6.2.0(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2)))(@types/react@19.0.8)(react-router@7.2.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(vite@6.2.0(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2))
+ version: 2.10.0(@react-router/dev@7.2.0(@types/node@22.13.1)(babel-plugin-macros@3.1.0)(jiti@2.4.2)(lightningcss@1.29.1)(react-router@7.2.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(tsx@4.19.2)(typescript@5.7.3)(vite@6.2.0(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2)(yaml@2.8.0))(yaml@2.8.0))(@types/react@19.0.8)(react-router@7.2.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(vite@6.2.0(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2)(yaml@2.8.0))
+ rehype-slug:
+ specifier: 6.0.0
+ version: 6.0.0
remix-hono:
specifier: 0.0.18
version: 0.0.18(hono@4.6.20)(i18next@24.2.2(typescript@5.7.3))(pretty-cache-header@1.0.0)(react-router@7.2.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(remix-i18next@7.0.2(i18next@24.2.2(typescript@5.7.3))(react-i18next@15.4.0(i18next@24.2.2(typescript@5.7.3))(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(react-router@7.2.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(react@19.0.0))(zod@3.24.1)
remix-i18next:
specifier: 7.0.2
version: 7.0.2(i18next@24.2.2(typescript@5.7.3))(react-i18next@15.4.0(i18next@24.2.2(typescript@5.7.3))(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(react-router@7.2.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(react@19.0.0)
+ slug:
+ specifier: 11.0.0
+ version: 11.0.0
tailwind-merge:
specifier: 3.0.1
version: 3.0.1
@@ -77,13 +95,13 @@ importers:
version: 1.34.0
'@react-router/dev':
specifier: 7.2.0
- version: 7.2.0(@types/node@22.13.1)(babel-plugin-macros@3.1.0)(jiti@2.4.2)(lightningcss@1.29.1)(react-router@7.2.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(tsx@4.19.2)(typescript@5.7.3)(vite@6.2.0(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2))
- '@react-router/fs-routes':
- specifier: 7.2.0
- version: 7.2.0(@react-router/dev@7.2.0(@types/node@22.13.1)(babel-plugin-macros@3.1.0)(jiti@2.4.2)(lightningcss@1.29.1)(react-router@7.2.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(tsx@4.19.2)(typescript@5.7.3)(vite@6.2.0(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2)))(typescript@5.7.3)
+ version: 7.2.0(@types/node@22.13.1)(babel-plugin-macros@3.1.0)(jiti@2.4.2)(lightningcss@1.29.1)(react-router@7.2.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(tsx@4.19.2)(typescript@5.7.3)(vite@6.2.0(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2)(yaml@2.8.0))(yaml@2.8.0)
+ '@tailwindcss/typography':
+ specifier: 0.5.16
+ version: 0.5.16(tailwindcss@4.0.9)
'@tailwindcss/vite':
specifier: 4.0.9
- version: 4.0.9(vite@6.2.0(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2))
+ version: 4.0.9(vite@6.2.0(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2)(yaml@2.8.0))
'@testing-library/react':
specifier: 16.2.0
version: 16.2.0(@testing-library/dom@10.4.0)(@types/react-dom@19.0.3(@types/react@19.0.8))(@types/react@19.0.8)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
@@ -99,9 +117,12 @@ importers:
'@types/react-dom':
specifier: 19.0.3
version: 19.0.3(@types/react@19.0.8)
+ '@types/slug':
+ specifier: 5.0.9
+ version: 5.0.9
'@vitest/browser':
specifier: 3.0.5
- version: 3.0.5(@types/node@22.13.1)(playwright@1.50.1)(typescript@5.7.3)(vite@6.2.0(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2))(vitest@3.0.5)
+ version: 3.0.5(@types/node@22.13.1)(playwright@1.50.1)(typescript@5.7.3)(vite@6.2.0(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2)(yaml@2.8.0))(vitest@3.0.5)
'@vitest/coverage-v8':
specifier: 3.0.5
version: 3.0.5(@vitest/browser@3.0.5)(vitest@3.0.5)
@@ -131,7 +152,7 @@ importers:
version: 1.3.0
react-router-devtools:
specifier: 5.0.4
- version: 5.0.4(@types/react-dom@19.0.3(@types/react@19.0.8))(@types/react@19.0.8)(react-dom@19.0.0(react@19.0.0))(react-router@7.2.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(react@19.0.0)(vite@6.2.0(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2))
+ version: 5.0.4(@types/react-dom@19.0.3(@types/react@19.0.8))(@types/react@19.0.8)(react-dom@19.0.0(react@19.0.0))(react-router@7.2.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(react@19.0.0)(vite@6.2.0(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2)(yaml@2.8.0))
tailwindcss:
specifier: 4.0.9
version: 4.0.9
@@ -143,19 +164,19 @@ importers:
version: 5.7.3
vite:
specifier: 6.2.0
- version: 6.2.0(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2)
+ version: 6.2.0(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2)(yaml@2.8.0)
vite-plugin-babel:
specifier: 1.3.0
- version: 1.3.0(@babel/core@7.27.1)(vite@6.2.0(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2))
+ version: 1.3.0(@babel/core@7.27.1)(vite@6.2.0(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2)(yaml@2.8.0))
vite-plugin-icons-spritesheet:
specifier: 3.0.1
- version: 3.0.1(vite@6.2.0(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2))
+ version: 3.0.1(vite@6.2.0(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2)(yaml@2.8.0))
vite-tsconfig-paths:
specifier: 5.1.4
- version: 5.1.4(typescript@5.7.3)(vite@6.2.0(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2))
+ version: 5.1.4(typescript@5.7.3)(vite@6.2.0(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2)(yaml@2.8.0))
vitest:
specifier: 3.0.5
- version: 3.0.5(@types/node@22.13.1)(@vitest/browser@3.0.5)(@vitest/ui@3.0.5)(happy-dom@16.8.1)(jiti@2.4.2)(lightningcss@1.29.1)(msw@2.7.3(@types/node@22.13.1)(typescript@5.7.3))(tsx@4.19.2)
+ version: 3.0.5(@types/debug@4.1.12)(@types/node@22.13.1)(@vitest/browser@3.0.5)(@vitest/ui@3.0.5)(happy-dom@16.8.1)(jiti@2.4.2)(lightningcss@1.29.1)(msw@2.7.3(@types/node@22.13.1)(typescript@5.7.3))(tsx@4.19.2)(yaml@2.8.0)
vitest-browser-react:
specifier: 0.0.4
version: 0.0.4(@types/react-dom@19.0.3(@types/react@19.0.8))(@types/react@19.0.8)(@vitest/browser@3.0.5)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(vitest@3.0.5)
@@ -440,10 +461,62 @@ packages:
'@bundled-es-modules/tough-cookie@0.1.6':
resolution: {integrity: sha512-dvMHbL464C0zI+Yqxbz6kZ5TOEp7GLW+pry/RWndAR8MJQAXZ2rPmIs8tziTZjeIyhSNZgZbCePtfSbdWqStJw==}
+ '@clerc/core@0.44.0':
+ resolution: {integrity: sha512-o8RgXNcMRoHRujSw9OPDMxqrmoNk7HG0XAZkjZgOrSyIfRXCf85VLyHGBT3XmaOrPEGY964h02ZxMVFdp8RnNQ==}
+
+ '@clerc/plugin-completions@0.44.0':
+ resolution: {integrity: sha512-r69KpaB+EcWccqe31OwK5iyJQZmgmhxJjEBL4RAGlRr2tu6MRX42AOmD3GDW+ZPHkc4D9NJdkqukLboTJlbycA==}
+ peerDependencies:
+ '@clerc/core': '*'
+
+ '@clerc/plugin-help@0.44.0':
+ resolution: {integrity: sha512-QIH+Lrk6WZtXKNxEAA4gOk7dwseS7U0jTZ0TbJfcyOoNA3fF2p48UV8c7hmKk7OhfPS5009eJRW5CVQEgBB8Ng==}
+ peerDependencies:
+ '@clerc/core': '*'
+
+ '@clerc/plugin-version@0.44.0':
+ resolution: {integrity: sha512-YETH54A0sO32oJcLABpb4P5FyhEkhIhe5oe3IXyeUj9/LMcInvKCm6x/gDMIUjTQuh0a5l4iton0A1RscAANhw==}
+ peerDependencies:
+ '@clerc/core': '*'
+
+ '@clerc/utils@0.44.0':
+ resolution: {integrity: sha512-//1zl8UgVhv1NbqsRoCWWci0Y9uBxzAVn8TqoKZchDywGQNZWK6vQI/Ms9uGe3+PZTDXedoXbVjklOINcVC2aA==}
+ peerDependencies:
+ '@clerc/core': '*'
+
'@colors/colors@1.5.0':
resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==}
engines: {node: '>=0.1.90'}
+ '@content-collections/cli@0.1.6':
+ resolution: {integrity: sha512-1MrxENMhAOAMFoLYNmlyCgwVB3i75PMX9vNLJ+jVh7akSfDrRRDWGn4E4WXDWCs27krSN7o98OJQVNav7Ndapw==}
+ hasBin: true
+ peerDependencies:
+ '@content-collections/core': 0.x
+
+ '@content-collections/core@0.10.0':
+ resolution: {integrity: sha512-GDBYbvhoj9lHNlarY5wr+3PoO3m9GBMjftio9NXatLuZaenY+EHHNCcbbA3J+c06Q7WBYwNoLAaMX2I5N0duAg==}
+ peerDependencies:
+ typescript: ^5.0.2
+
+ '@content-collections/integrations@0.2.1':
+ resolution: {integrity: sha512-AyEcS2MmcOXSYt6vNmJsAiu6EBYjtNiwYGUVUmpG3llm8Gt8uiNrhIhlHyv3cuk+N8KJ2PWemLcMqtQJ+sW3bA==}
+ peerDependencies:
+ '@content-collections/core': 0.x
+
+ '@content-collections/mdx@0.2.2':
+ resolution: {integrity: sha512-7Xx8AohrSuq1jn/k44qWIq1s666KnksGPk64nnoY/T9mFZ7fZkdEtYezBsNpzkDMMKTnf65CNIvyFHtwTD2muA==}
+ peerDependencies:
+ '@content-collections/core': 0.x
+ react: '>= 18'
+ react-dom: '>= 18'
+
+ '@content-collections/remix-vite@0.2.2':
+ resolution: {integrity: sha512-kdHJz9CMJHZcGBtJy8zfRd4zp5bSOiaKvj7hlACYLaZK8m1ABmql8giliGbXDCepKqbx1YLb0b86niZg+6aytQ==}
+ peerDependencies:
+ '@content-collections/core': ^0.x
+ vite: ^5 || ^6 || ^7
+
'@dotenvx/dotenvx@1.34.0':
resolution: {integrity: sha512-+Dp/xaI3IZ4eKv+b2vg4V89VnqLKbmJ7UZ7unnZxMu9SNLOSc2jYaXey1YHCJM+67T0pOr2Gbej3TewnuoqTWQ==}
hasBin: true
@@ -504,6 +577,11 @@ packages:
'@epic-web/client-hints@1.3.5':
resolution: {integrity: sha512-tFIDxdU5NzN5Ak4gcDOPKkj6aF/qNMC0G+K58CTBZIx7CMSjCrxqhuiEbZBKGDAGJcsQLF5uKKlgs6mgqWmB7Q==}
+ '@esbuild-plugins/node-resolve@0.2.2':
+ resolution: {integrity: sha512-+t5FdX3ATQlb53UFDBRb4nqjYBz492bIrnVWvpQHpzZlu9BQL5HasMZhqc409ygUwOWCXZhrWr6NyZ6T6Y+cxw==}
+ peerDependencies:
+ esbuild: '*'
+
'@esbuild/aix-ppc64@0.23.1':
resolution: {integrity: sha512-6VhYk1diRqrhBAqpJEdjASR/+WVRtfjpqKuNw11cLiaWpAT/Uu+nokB+UJnevzy/P9C/ty6AOe0dwueMrGh/iQ==}
engines: {node: '>=18'}
@@ -798,6 +876,9 @@ packages:
cpu: [x64]
os: [win32]
+ '@fal-works/esbuild-plugin-global-externals@2.1.2':
+ resolution: {integrity: sha512-cEee/Z+I12mZcFJshKcCqC8tuX5hG3s+d+9nZ3LabqKF1vKdF41B92pJVCBggjAGORAeOzyyDDKrZwIkLffeOQ==}
+
'@floating-ui/core@1.6.9':
resolution: {integrity: sha512-uMXCuQ3BItDUbAMhIXw7UPXRfAlOAvZzdK9BWpE60MCn+Svt3aLn9jsPTi/WNGlRUu2uI0v5S7JiIUsbsvh3fw==}
@@ -899,6 +980,14 @@ packages:
'@jridgewell/trace-mapping@0.3.25':
resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==}
+ '@mdx-js/esbuild@3.1.0':
+ resolution: {integrity: sha512-Jk42xUb1SEJxh6n2GBAtJjQISFIZccjz8XVEsHVhrlvZJAJziIxR9KyaFF6nTeTB/jCAFQGDgO7+oMRH/ApRsg==}
+ peerDependencies:
+ esbuild: '>=0.14.0'
+
+ '@mdx-js/mdx@3.1.0':
+ resolution: {integrity: sha512-/QxEhPAvGwbQmy1Px8F899L5Uc2KZ6JtXwlCgJmjSTBedwOZkByYcBG4GceIGPXRDsmfxhHazuS+hlOShRLeDw==}
+
'@mjackson/node-fetch-server@0.2.0':
resolution: {integrity: sha512-EMlH1e30yzmTpGLQjlFmaDAjyOeZhng1/XCd7DExR8PNAnG/G1tyruZxEoUe11ClnwGhGrtsdnyyUx1frSzjng==}
@@ -1273,16 +1362,6 @@ packages:
wrangler:
optional: true
- '@react-router/fs-routes@7.2.0':
- resolution: {integrity: sha512-vbXNCJ6Rd9ZhMpYzacz2bZjDi4UTgOtIktdcHG0oFUFS51DWvfzFo0h/7iyqT3r1QFKQ3wg+KhX5PEiksipeaQ==}
- engines: {node: '>=20.0.0'}
- peerDependencies:
- '@react-router/dev': ^7.2.0
- typescript: ^5.1.0
- peerDependenciesMeta:
- typescript:
- optional: true
-
'@react-router/node@7.2.0':
resolution: {integrity: sha512-CqBHLwvvV4BB8htmaSwT+SOwX9B4RVOIiEdTlaIp12sNVCGSYDIEGbv3T4Wxeq8p5ynNfhNcdBeXtZ6ZPWVozA==}
engines: {node: '>=20.0.0'}
@@ -1421,6 +1500,9 @@ packages:
engines: {node: '>=8.10'}
hasBin: true
+ '@standard-schema/spec@1.0.0':
+ resolution: {integrity: sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==}
+
'@tailwindcss/node@4.0.9':
resolution: {integrity: sha512-tOJvdI7XfJbARYhxX+0RArAhmuDcczTC46DGCEziqxzzbIaPnfYaIyRT31n4u8lROrsO7Q6u/K9bmQHL2uL1bQ==}
@@ -1494,6 +1576,11 @@ packages:
resolution: {integrity: sha512-eLizHmXFqHswJONwfqi/WZjtmWZpIalpvMlNhTM99/bkHtUs6IqgI1XQ0/W5eO2HiRQcIlXUogI2ycvKhVLNcA==}
engines: {node: '>= 10'}
+ '@tailwindcss/typography@0.5.16':
+ resolution: {integrity: sha512-0wDLwCVF5V3x3b1SGXPCDcdsbDHMBe+lkFzBRaHeLvNi+nrrnZ1lA18u+OTWO8iSWU2GxUOCvlXtDuqftc1oiA==}
+ peerDependencies:
+ tailwindcss: '>=3.0.0 || insiders || >=4.0.0-alpha.20 || >=4.0.0-beta.1'
+
'@tailwindcss/vite@4.0.9':
resolution: {integrity: sha512-BIKJO+hwdIsN7V6I7SziMZIVHWWMsV/uCQKYEbeiGRDRld+TkqyRRl9+dQ0MCXbhcVr+D9T/qX2E84kT7V281g==}
peerDependencies:
@@ -1530,9 +1617,27 @@ packages:
'@types/cookie@0.6.0':
resolution: {integrity: sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==}
+ '@types/debug@4.1.12':
+ resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==}
+
+ '@types/estree-jsx@1.0.5':
+ resolution: {integrity: sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==}
+
'@types/estree@1.0.6':
resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==}
+ '@types/hast@3.0.4':
+ resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==}
+
+ '@types/mdast@4.0.4':
+ resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==}
+
+ '@types/mdx@2.0.13':
+ resolution: {integrity: sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==}
+
+ '@types/ms@2.1.0':
+ resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==}
+
'@types/node@22.13.1':
resolution: {integrity: sha512-jK8uzQlrvXqEU91UxiK5J7pKHyzgnI1Qnl0QDHIgVGuolJhRb9EEl28Cj9b3rGR8B2lhFCtvIm5os8lFnO/1Ew==}
@@ -1555,15 +1660,33 @@ packages:
'@types/react@19.0.8':
resolution: {integrity: sha512-9P/o1IGdfmQxrujGbIMDyYaaCykhLKc0NGCtYcECNUr9UAaDe4gwvV9bR6tvd5Br1SG0j+PBpbKr2UYY8CwqSw==}
+ '@types/resolve@1.20.6':
+ resolution: {integrity: sha512-A4STmOXPhMUtHH+S6ymgE2GiBSMqf4oTvcQZMcHzokuTLVYzXTB8ttjcgxOVaAp2lGwEdzZ0J+cRbbeevQj1UQ==}
+
'@types/revalidator@0.3.12':
resolution: {integrity: sha512-DsA2jHfz73JaIROVoMDd/x7nVWXBmEdDSoXB4yQlDzv/NCBkFY2fMHkyE6DGrvooLDAFe5QI6l9Wq0TgdopMtg==}
+ '@types/slug@5.0.9':
+ resolution: {integrity: sha512-6Yp8BSplP35Esa/wOG1wLNKiqXevpQTEF/RcL/NV6BBQaMmZh4YlDwCgrrFSoUE4xAGvnKd5c+lkQJmPrBAzfQ==}
+
'@types/statuses@2.0.5':
resolution: {integrity: sha512-jmIUGWrAiwu3dZpxntxieC+1n/5c3mjrImkmOSQ2NC5uP6cYO4aAZDdSmRcI5C1oiTmqlZGHC+/NmJrKogbP5A==}
+ '@types/text-table@0.2.5':
+ resolution: {integrity: sha512-hcZhlNvMkQG/k1vcZ6yHOl6WAYftQ2MLfTHcYRZ2xYZFD8tGVnE3qFV0lj1smQeDSR7/yY0PyuUalauf33bJeA==}
+
'@types/tough-cookie@4.0.5':
resolution: {integrity: sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==}
+ '@types/unist@2.0.11':
+ resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==}
+
+ '@types/unist@3.0.3':
+ resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==}
+
+ '@ungap/structured-clone@1.3.0':
+ resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==}
+
'@vitest/browser@3.0.5':
resolution: {integrity: sha512-5WAWJoucuWcGYU5t0HPBY03k9uogbUEIu4pDmZHoB4Dt+6pXqzDbzEmxGjejZSitSYA3k/udYfuotKNxETVA3A==}
peerDependencies:
@@ -1632,6 +1755,16 @@ packages:
resolution: {integrity: sha512-+/kfrslGQ7TNV2ecmQwMJj/B65g5KVq1/L3SGVZ3tCYGqlzFuFCGBZJtMP99wH3NpEUyAjn0zPdPUg0D+DwrOA==}
engines: {node: ^18.17.0 || >=20.5.0}
+ acorn-jsx@5.3.2:
+ resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==}
+ peerDependencies:
+ acorn: ^6.0.0 || ^7.0.0 || ^8.0.0
+
+ acorn@8.15.0:
+ resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==}
+ engines: {node: '>=0.4.0'}
+ hasBin: true
+
aggregate-error@3.1.0:
resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==}
engines: {node: '>=8'}
@@ -1663,6 +1796,9 @@ packages:
arg@5.0.2:
resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==}
+ argparse@1.0.10:
+ resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==}
+
argparse@2.0.1:
resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
@@ -1677,6 +1813,10 @@ packages:
resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==}
engines: {node: '>=12'}
+ astring@1.9.0:
+ resolution: {integrity: sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==}
+ hasBin: true
+
async@2.6.4:
resolution: {integrity: sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==}
@@ -1693,6 +1833,9 @@ packages:
babel-plugin-react-compiler@19.0.0-beta-df7b47d-20241124:
resolution: {integrity: sha512-93iSASR20HNsotcOTQ+KPL0zpgfRFVWL86AtXpmHp995HuMVnC9femd8Winr3GxkPEh8lEOyaw3nqY4q2HUm5w==}
+ bail@2.0.2:
+ resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==}
+
balanced-match@1.0.2:
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
@@ -1734,9 +1877,16 @@ packages:
resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==}
engines: {node: '>=6'}
+ camelcase@8.0.0:
+ resolution: {integrity: sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA==}
+ engines: {node: '>=16'}
+
caniuse-lite@1.0.30001701:
resolution: {integrity: sha512-faRs/AW3jA9nTwmJBSO1PQ6L/EOgsB5HMQQq4iCu5zhPgVVgO/pZRHlmatwijZKetFw8/Pr4q6dEN8sJuq8qTw==}
+ ccount@2.0.1:
+ resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==}
+
chai@5.2.0:
resolution: {integrity: sha512-mCuXncKXk5iCLhfhwTc0izo0gtEmpz5CtG2y8GiOINBlMVS6v8TMRc5TaLWKS6692m9+dVVfzgeVxR5UxWHTYw==}
engines: {node: '>=12'}
@@ -1752,6 +1902,18 @@ packages:
resolution: {integrity: sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==}
engines: {node: ^12.17.0 || ^14.13 || >=16.0.0}
+ character-entities-html4@2.1.0:
+ resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==}
+
+ character-entities-legacy@3.0.0:
+ resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==}
+
+ character-entities@2.0.2:
+ resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==}
+
+ character-reference-invalid@2.0.1:
+ resolution: {integrity: sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==}
+
check-error@2.1.1:
resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==}
engines: {node: '>= 16'}
@@ -1787,6 +1949,9 @@ packages:
resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==}
engines: {node: '>=6'}
+ collapse-white-space@2.1.0:
+ resolution: {integrity: sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==}
+
color-convert@2.0.1:
resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
engines: {node: '>=7.0.0'}
@@ -1798,6 +1963,9 @@ packages:
resolution: {integrity: sha512-pFGrxThWcWQ2MsAz6RtgeWe4NK2kUE1WfsrvvlctdII745EW9I0yflqhe7++M5LEc7bV2c/9/5zc8sFcpL0Drw==}
engines: {node: '>=0.1.90'}
+ comma-separated-tokens@2.0.3:
+ resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==}
+
commander@10.0.1:
resolution: {integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==}
engines: {node: '>=14'}
@@ -1860,6 +2028,11 @@ packages:
resolution: {integrity: sha512-ljnSOCOiMbklF+dwPbpooyB78foId02vUrTDogWzu6ca2DCNB7Kc/BHEGBnYOlUYtwXvSW0mWTwaiO2pwFIoRg==}
hasBin: true
+ cssesc@3.0.0:
+ resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==}
+ engines: {node: '>=4'}
+ hasBin: true
+
csstype@3.1.3:
resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==}
@@ -1926,6 +2099,9 @@ packages:
supports-color:
optional: true
+ decode-named-character-reference@1.2.0:
+ resolution: {integrity: sha512-c6fcElNV6ShtZXmsgNgFFV5tVX2PaV4g+MOAkb8eXHvn6sryJBrZa9r0zV6+dtTyoCKxtDy5tyQ5ZwQuidtd+Q==}
+
dedent@1.5.3:
resolution: {integrity: sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ==}
peerDependencies:
@@ -1941,6 +2117,9 @@ packages:
defaults@1.0.4:
resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==}
+ defu@6.1.4:
+ resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==}
+
dequal@2.0.3:
resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==}
engines: {node: '>=6'}
@@ -1953,6 +2132,9 @@ packages:
detect-node-es@1.1.0:
resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==}
+ devlop@1.1.0:
+ resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==}
+
diff@5.2.0:
resolution: {integrity: sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==}
engines: {node: '>=0.3.1'}
@@ -2001,6 +2183,9 @@ packages:
electron-to-chromium@1.5.105:
resolution: {integrity: sha512-ccp7LocdXx3yBhwiG0qTQ7XFrK48Ua2pxIxBdJO8cbddp/MvbBtPFzvnTchtyHQTsgqqczO8cdmAIbpMa0u2+g==}
+ emoji-regex@10.4.0:
+ resolution: {integrity: sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==}
+
emoji-regex@8.0.0:
resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
@@ -2027,6 +2212,12 @@ packages:
es-module-lexer@1.6.0:
resolution: {integrity: sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ==}
+ esast-util-from-estree@2.0.0:
+ resolution: {integrity: sha512-4CyanoAudUSBAn5K13H4JhsMH6L9ZP7XbLVe/dKybkxMO7eDyLsT8UHl9TRNrU2Gr9nz+FovfSIjuXWJ81uVwQ==}
+
+ esast-util-from-js@2.0.1:
+ resolution: {integrity: sha512-8Ja+rNJ0Lt56Pcf3TAmpBZjmx8ZcK5Ts4cAzIOjsjevg9oSXJnl6SUQ2EevU8tv3h6ZLWmoKL5H4fgWvdvfETw==}
+
esbuild@0.23.1:
resolution: {integrity: sha512-VVNz/9Sa0bs5SELtn3f7qhJCDPCF5oMEl5cO9/SSinpE9hbPVvxbd572HH5AKiP7WD8INO53GgfDDhRjkylHEg==}
engines: {node: '>=18'}
@@ -2045,6 +2236,36 @@ packages:
resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==}
engines: {node: '>=10'}
+ escape-string-regexp@5.0.0:
+ resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==}
+ engines: {node: '>=12'}
+
+ esprima@4.0.1:
+ resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==}
+ engines: {node: '>=4'}
+ hasBin: true
+
+ estree-util-attach-comments@3.0.0:
+ resolution: {integrity: sha512-cKUwm/HUcTDsYh/9FgnuFqpfquUbwIqwKM26BVCGDPVgvaCl/nDCCjUfiLlx6lsEZ3Z4RFxNbOQ60pkaEwFxGw==}
+
+ estree-util-build-jsx@3.0.1:
+ resolution: {integrity: sha512-8U5eiL6BTrPxp/CHbs2yMgP8ftMhR5ww1eIKoWRMlqvltHF8fZn5LRDvTKuxD3DUn+shRbLGqXemcP51oFCsGQ==}
+
+ estree-util-is-identifier-name@3.0.0:
+ resolution: {integrity: sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==}
+
+ estree-util-scope@1.0.0:
+ resolution: {integrity: sha512-2CAASclonf+JFWBNJPndcOpA8EMJwa0Q8LUFJEKqXLW6+qBvbFZuF5gItbQOs/umBUkjviCSDCbBwU2cXbmrhQ==}
+
+ estree-util-to-js@2.0.0:
+ resolution: {integrity: sha512-WDF+xj5rRWmD5tj6bIqRi6CkLIXbbNQUcxQHzGysQzvHmdYG2G7p/Tf0J0gpxGgkeMZNTIjT/AoSvC9Xehcgdg==}
+
+ estree-util-value-to-estree@3.4.0:
+ resolution: {integrity: sha512-Zlp+gxis+gCfK12d3Srl2PdX2ybsEA8ZYy6vQGVQTNNYLEGRQQ56XB64bjemN8kxIKXP1nC9ip4Z+ILy9LGzvQ==}
+
+ estree-util-visit@2.0.0:
+ resolution: {integrity: sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww==}
+
estree-walker@3.0.3:
resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==}
@@ -2060,6 +2281,13 @@ packages:
resolution: {integrity: sha512-bFi65yM+xZgk+u/KRIpekdSYkTB5W1pEf0Lt8Q8Msh7b+eQ7LXVtIB1Bkm4fvclDEL1b2CZkMhv2mOeF8tMdkA==}
engines: {node: '>=12.0.0'}
+ extend-shallow@2.0.1:
+ resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==}
+ engines: {node: '>=0.10.0'}
+
+ extend@3.0.2:
+ resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==}
+
eyes@0.1.8:
resolution: {integrity: sha512-GipyPsXO1anza0AOZdy69Im7hGFCNB7Y/NGjDlZGJ3GJJLtwNSb2vrzYrTYJRrRloVx7pl+bhUaTB8yiccPvFQ==}
engines: {node: '> 0.1.90'}
@@ -2071,6 +2299,9 @@ packages:
fastq@1.19.0:
resolution: {integrity: sha512-7SFSRCNjBQIZH/xZR3iy5iQYR8aGBE0h3VG6/cwlbrpdciNYBMotQav8c1XI3HjHH+NikUpP53nPdlZSdWmFzA==}
+ fault@2.0.1:
+ resolution: {integrity: sha512-WtySTkS4OKev5JtpHXnib4Gxiurzh5NCGvWrFaZ34m6JehfTUhKZvn9njTfw48t6JumVQOmrKqpmGcdwxnhqBQ==}
+
fdir@6.4.3:
resolution: {integrity: sha512-PMXmW2y1hDDfTSRc9gaXIuCCRpuoz3Kaz8cUelp3smouvfT632ozg2vrT6lJsHKKOF59YLbOGfAWGUcKEfRMQw==}
peerDependencies:
@@ -2096,6 +2327,10 @@ packages:
resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==}
engines: {node: '>=14'}
+ format@0.2.2:
+ resolution: {integrity: sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==}
+ engines: {node: '>=0.4.x'}
+
framer-motion@12.4.7:
resolution: {integrity: sha512-VhrcbtcAMXfxlrjeHPpWVu2+mkcoR31e02aNSR7OUS/hZAciKa8q6o3YN2mA1h+jjscRsSyKvX6E1CiY/7OLMw==}
peerDependencies:
@@ -2146,6 +2381,9 @@ packages:
get-tsconfig@4.10.0:
resolution: {integrity: sha512-kGzZ3LWWQcGIAmg6iWvXn0ei6WDtV26wzHRMwDSzmAbcXrTEXxHy6IehI6/4eT6VRKyMP1eF1VqwrVUmE/LR7A==}
+ github-slugger@2.0.0:
+ resolution: {integrity: sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==}
+
glob-parent@5.1.2:
resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
engines: {node: '>= 6'}
@@ -2173,6 +2411,10 @@ packages:
resolution: {integrity: sha512-AjqGKbDGUFRKIRCP9tCKiIGHyriz2oHEbPIbEtcSLSs4YjReZOIPQQWek4+6hjw62H9QShXHyaGivGiYVLeYFQ==}
engines: {node: ^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0}
+ gray-matter@4.0.3:
+ resolution: {integrity: sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==}
+ engines: {node: '>=6.0'}
+
gunzip-maybe@1.4.2:
resolution: {integrity: sha512-4haO1M4mLO91PW57BMsDFf75UmwoRX0GkdD+Faw+Lr+r/OZrOCS0pIBwOL1xCKQqnQzbNFGgK2V2CpBUPeFNTw==}
hasBin: true
@@ -2189,6 +2431,21 @@ packages:
resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==}
engines: {node: '>= 0.4'}
+ hast-util-heading-rank@3.0.0:
+ resolution: {integrity: sha512-EJKb8oMUXVHcWZTDepnr+WNbfnXKFNf9duMesmr4S8SXTJBJ9M4Yok08pu9vxdJwdlGRhVumk9mEhkEvKGifwA==}
+
+ hast-util-to-estree@3.1.3:
+ resolution: {integrity: sha512-48+B/rJWAp0jamNbAAf9M7Uf//UVqAoMmgXhBdxTDJLGKY+LRnZ99qcG+Qjl5HfMpYNzS5v4EAwVEF34LeAj7w==}
+
+ hast-util-to-jsx-runtime@2.3.6:
+ resolution: {integrity: sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==}
+
+ hast-util-to-string@3.0.1:
+ resolution: {integrity: sha512-XelQVTDWvqcl3axRfI0xSeoVKzyIFPwsAGSLIsKdJKQMXDYJS4WYrBNF/8J7RdhIcFI2BOHgAifggsvsxp/3+A==}
+
+ hast-util-whitespace@3.0.0:
+ resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==}
+
he@1.2.0:
resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==}
hasBin: true
@@ -2253,6 +2510,15 @@ packages:
ini@1.3.8:
resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==}
+ inline-style-parser@0.2.4:
+ resolution: {integrity: sha512-0aO8FkhNZlj/ZIbNi7Lxxr12obT7cL1moPfE4tg1LkX7LlLfC6DeX4l2ZEud1ukP9jNQyNnfzQVqwbwmAATY4Q==}
+
+ is-alphabetical@2.0.1:
+ resolution: {integrity: sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==}
+
+ is-alphanumerical@2.0.1:
+ resolution: {integrity: sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==}
+
is-arrayish@0.2.1:
resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==}
@@ -2260,9 +2526,16 @@ packages:
resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==}
engines: {node: '>= 0.4'}
+ is-decimal@2.0.1:
+ resolution: {integrity: sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==}
+
is-deflate@1.0.0:
resolution: {integrity: sha512-YDoFpuZWu1VRXlsnlYMzKyVRITXj7Ej/V9gXQ2/pAe7X1J7M/RNOqaIYi6qUn+B7nGyB9pDXrv02dsB58d2ZAQ==}
+ is-extendable@0.1.1:
+ resolution: {integrity: sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==}
+ engines: {node: '>=0.10.0'}
+
is-extglob@2.1.1:
resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
engines: {node: '>=0.10.0'}
@@ -2279,6 +2552,9 @@ packages:
resolution: {integrity: sha512-rcfALRIb1YewtnksfRIHGcIY93QnK8BIQ/2c9yDYcG/Y6+vRoJuTWBmmSEbyLLYtXm7q35pHOHbZFQBaLrhlWQ==}
engines: {node: '>=0.10.0'}
+ is-hexadecimal@2.0.1:
+ resolution: {integrity: sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==}
+
is-node-process@1.2.0:
resolution: {integrity: sha512-Vg4o6/fqPxIjtxgUH5QLJhwZ7gW5diGCVlXpuUfELC62CuxM1iHcRe51f2W1FDy04Ai4KJkagKjx3XaqyfRKXw==}
@@ -2286,6 +2562,13 @@ packages:
resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
engines: {node: '>=0.12.0'}
+ is-plain-obj@4.1.0:
+ resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==}
+ engines: {node: '>=12'}
+
+ is-platform@1.0.0:
+ resolution: {integrity: sha512-AKxe6+dvzAQsDXhhhxGRL9G67q5rKiyTL0BUl5mCyQz2NdvmqWNmMsjoCOIVdyXOYpP6MhkmZ1DPYGkfgv0MpA==}
+
is-stream@2.0.1:
resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==}
engines: {node: '>=8'}
@@ -2346,6 +2629,10 @@ packages:
js-tokens@4.0.0:
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
+ js-yaml@3.14.1:
+ resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==}
+ hasBin: true
+
js-yaml@4.1.0:
resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==}
hasBin: true
@@ -2370,6 +2657,10 @@ packages:
jsonfile@6.1.0:
resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==}
+ kind-of@6.0.3:
+ resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==}
+ engines: {node: '>=0.10.0'}
+
knip@5.43.6:
resolution: {integrity: sha512-bUCFlg44imdV5vayYxu0pIAB373S8Ufjda0qaI9oRZDH6ltJFwUoAO2j7nafxDmo5G0ZeP4IiLAHqlc3wYIONQ==}
engines: {node: '>=18.18.0'}
@@ -2499,9 +2790,24 @@ packages:
lines-and-columns@1.2.4:
resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
+ lite-emit@2.3.0:
+ resolution: {integrity: sha512-QMPrnwPho7lfkzZUN3a0RJ/oiwpt464eXf6aVh1HGOYh+s7Utu78q3FcFbW59c8TNWWQaz9flKN1cEb8dmxD+g==}
+
+ lodash.castarray@4.4.0:
+ resolution: {integrity: sha512-aVx8ztPv7/2ULbArGJ2Y42bG1mEQ5mGjpdvrbJcJFU3TbYybe+QlLS4pst9zV52ymy2in1KpFPiZnAOATxD4+Q==}
+
+ lodash.isplainobject@4.0.6:
+ resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==}
+
+ lodash.merge@4.6.2:
+ resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==}
+
lodash@4.17.21:
resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==}
+ longest-streak@3.1.0:
+ resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==}
+
loose-envify@1.4.0:
resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==}
hasBin: true
@@ -2537,6 +2843,46 @@ packages:
resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==}
engines: {node: '>=10'}
+ markdown-extensions@2.0.0:
+ resolution: {integrity: sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q==}
+ engines: {node: '>=16'}
+
+ mdast-util-from-markdown@2.0.2:
+ resolution: {integrity: sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==}
+
+ mdast-util-frontmatter@2.0.1:
+ resolution: {integrity: sha512-LRqI9+wdgC25P0URIJY9vwocIzCcksduHQ9OF2joxQoyTNVduwLAFUzjoopuRJbJAReaKrNQKAZKL3uCMugWJA==}
+
+ mdast-util-mdx-expression@2.0.1:
+ resolution: {integrity: sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==}
+
+ mdast-util-mdx-jsx@3.2.0:
+ resolution: {integrity: sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q==}
+
+ mdast-util-mdx@3.0.0:
+ resolution: {integrity: sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w==}
+
+ mdast-util-mdxjs-esm@2.0.1:
+ resolution: {integrity: sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==}
+
+ mdast-util-phrasing@4.1.0:
+ resolution: {integrity: sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==}
+
+ mdast-util-to-hast@13.2.0:
+ resolution: {integrity: sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==}
+
+ mdast-util-to-markdown@2.1.2:
+ resolution: {integrity: sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==}
+
+ mdast-util-to-string@4.0.0:
+ resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==}
+
+ mdx-bundler@10.1.1:
+ resolution: {integrity: sha512-87FtxC7miUPznwqEaAlJARinHJ6Qin9kDuG2E2BCCNEOszr62kHpqivI/IF/CmwObVSpvApVFFxN1ftM/Gykvw==}
+ engines: {node: '>=18', npm: '>=6'}
+ peerDependencies:
+ esbuild: 0.*
+
memoize-one@6.0.0:
resolution: {integrity: sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==}
@@ -2547,6 +2893,93 @@ packages:
resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
engines: {node: '>= 8'}
+ micromark-core-commonmark@2.0.3:
+ resolution: {integrity: sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==}
+
+ micromark-extension-frontmatter@2.0.0:
+ resolution: {integrity: sha512-C4AkuM3dA58cgZha7zVnuVxBhDsbttIMiytjgsM2XbHAB2faRVaHRle40558FBN+DJcrLNCoqG5mlrpdU4cRtg==}
+
+ micromark-extension-mdx-expression@3.0.1:
+ resolution: {integrity: sha512-dD/ADLJ1AeMvSAKBwO22zG22N4ybhe7kFIZ3LsDI0GlsNr2A3KYxb0LdC1u5rj4Nw+CHKY0RVdnHX8vj8ejm4Q==}
+
+ micromark-extension-mdx-jsx@3.0.2:
+ resolution: {integrity: sha512-e5+q1DjMh62LZAJOnDraSSbDMvGJ8x3cbjygy2qFEi7HCeUT4BDKCvMozPozcD6WmOt6sVvYDNBKhFSz3kjOVQ==}
+
+ micromark-extension-mdx-md@2.0.0:
+ resolution: {integrity: sha512-EpAiszsB3blw4Rpba7xTOUptcFeBFi+6PY8VnJ2hhimH+vCQDirWgsMpz7w1XcZE7LVrSAUGb9VJpG9ghlYvYQ==}
+
+ micromark-extension-mdxjs-esm@3.0.0:
+ resolution: {integrity: sha512-DJFl4ZqkErRpq/dAPyeWp15tGrcrrJho1hKK5uBS70BCtfrIFg81sqcTVu3Ta+KD1Tk5vAtBNElWxtAa+m8K9A==}
+
+ micromark-extension-mdxjs@3.0.0:
+ resolution: {integrity: sha512-A873fJfhnJ2siZyUrJ31l34Uqwy4xIFmvPY1oj+Ean5PHcPBYzEsvqvWGaWcfEIr11O5Dlw3p2y0tZWpKHDejQ==}
+
+ micromark-factory-destination@2.0.1:
+ resolution: {integrity: sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==}
+
+ micromark-factory-label@2.0.1:
+ resolution: {integrity: sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==}
+
+ micromark-factory-mdx-expression@2.0.3:
+ resolution: {integrity: sha512-kQnEtA3vzucU2BkrIa8/VaSAsP+EJ3CKOvhMuJgOEGg9KDC6OAY6nSnNDVRiVNRqj7Y4SlSzcStaH/5jge8JdQ==}
+
+ micromark-factory-space@2.0.1:
+ resolution: {integrity: sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==}
+
+ micromark-factory-title@2.0.1:
+ resolution: {integrity: sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==}
+
+ micromark-factory-whitespace@2.0.1:
+ resolution: {integrity: sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==}
+
+ micromark-util-character@2.1.1:
+ resolution: {integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==}
+
+ micromark-util-chunked@2.0.1:
+ resolution: {integrity: sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==}
+
+ micromark-util-classify-character@2.0.1:
+ resolution: {integrity: sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==}
+
+ micromark-util-combine-extensions@2.0.1:
+ resolution: {integrity: sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==}
+
+ micromark-util-decode-numeric-character-reference@2.0.2:
+ resolution: {integrity: sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==}
+
+ micromark-util-decode-string@2.0.1:
+ resolution: {integrity: sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==}
+
+ micromark-util-encode@2.0.1:
+ resolution: {integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==}
+
+ micromark-util-events-to-acorn@2.0.3:
+ resolution: {integrity: sha512-jmsiEIiZ1n7X1Rr5k8wVExBQCg5jy4UXVADItHmNk1zkwEVhBuIUKRu3fqv+hs4nxLISi2DQGlqIOGiFxgbfHg==}
+
+ micromark-util-html-tag-name@2.0.1:
+ resolution: {integrity: sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==}
+
+ micromark-util-normalize-identifier@2.0.1:
+ resolution: {integrity: sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==}
+
+ micromark-util-resolve-all@2.0.1:
+ resolution: {integrity: sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==}
+
+ micromark-util-sanitize-uri@2.0.1:
+ resolution: {integrity: sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==}
+
+ micromark-util-subtokenize@2.1.0:
+ resolution: {integrity: sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==}
+
+ micromark-util-symbol@2.0.1:
+ resolution: {integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==}
+
+ micromark-util-types@2.0.2:
+ resolution: {integrity: sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==}
+
+ micromark@4.0.2:
+ resolution: {integrity: sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==}
+
micromatch@4.0.8:
resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==}
engines: {node: '>=8.6'}
@@ -2674,6 +3107,10 @@ packages:
outvariant@1.4.3:
resolution: {integrity: sha512-+Sl2UErvtsoajRDKCE5/dBz4DIvHXQQnAxtQTF04OJxY0+DyZXSo5P5Bb7XYWOh81syohlYL24hbDwxedPUJCA==}
+ p-limit@6.2.0:
+ resolution: {integrity: sha512-kuUqqHNUqoIWp/c467RI4X6mmyuojY5jGutNU0wVTmEOOfcuwLqyMVoAi9MKi2Ak+5i9+nhmrK4ufZE8069kHA==}
+ engines: {node: '>=18'}
+
p-map@4.0.0:
resolution: {integrity: sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==}
engines: {node: '>=10'}
@@ -2688,6 +3125,9 @@ packages:
resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==}
engines: {node: '>=6'}
+ parse-entities@4.0.2:
+ resolution: {integrity: sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==}
+
parse-json@5.2.0:
resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==}
engines: {node: '>=8'}
@@ -2752,6 +3192,14 @@ packages:
engines: {node: '>=18'}
hasBin: true
+ pluralize@8.0.0:
+ resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==}
+ engines: {node: '>=4'}
+
+ postcss-selector-parser@6.0.10:
+ resolution: {integrity: sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==}
+ engines: {node: '>=4'}
+
postcss@8.5.3:
resolution: {integrity: sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==}
engines: {node: ^10 || ^12 || >=14}
@@ -2799,6 +3247,9 @@ packages:
prop-types@15.8.1:
resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==}
+ property-information@7.1.0:
+ resolution: {integrity: sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==}
+
proto-list@1.2.4:
resolution: {integrity: sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==}
@@ -2821,6 +3272,9 @@ packages:
queue-microtask@1.2.3:
resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
+ randombytes@2.1.0:
+ resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==}
+
react-d3-tree@3.6.5:
resolution: {integrity: sha512-U/PH6hqgP8m6RvYmxqjqsXBeMowuSMfX4jE+uiBB4lM5CcdrnpR1V7U6h4xsOkPWxpoTqFFotsDnzvZ/D42YKg==}
peerDependencies:
@@ -2962,9 +3416,42 @@ packages:
resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==}
engines: {node: '>= 14.18.0'}
+ recma-build-jsx@1.0.0:
+ resolution: {integrity: sha512-8GtdyqaBcDfva+GUKDr3nev3VpKAhup1+RvkMvUxURHpW7QyIvk9F5wz7Vzo06CEMSilw6uArgRqhpiUcWp8ew==}
+
+ recma-jsx@1.0.0:
+ resolution: {integrity: sha512-5vwkv65qWwYxg+Atz95acp8DMu1JDSqdGkA2Of1j6rCreyFUE/gp15fC8MnGEuG1W68UKjM6x6+YTWIh7hZM/Q==}
+
+ recma-parse@1.0.0:
+ resolution: {integrity: sha512-OYLsIGBB5Y5wjnSnQW6t3Xg7q3fQ7FWbw/vcXtORTnyaSFscOtABg+7Pnz6YZ6c27fG1/aN8CjfwoUEUIdwqWQ==}
+
+ recma-stringify@1.0.0:
+ resolution: {integrity: sha512-cjwII1MdIIVloKvC9ErQ+OgAtwHBmcZ0Bg4ciz78FtbT8In39aAYbaA7zvxQ61xVMSPE8WxhLwLbhif4Js2C+g==}
+
regenerator-runtime@0.14.1:
resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==}
+ rehype-recma@1.0.0:
+ resolution: {integrity: sha512-lqA4rGUf1JmacCNWWZx0Wv1dHqMwxzsDWYMTowuplHF3xH0N/MmrZ/G3BDZnzAkRmxDadujCjaKM2hqYdCBOGw==}
+
+ rehype-slug@6.0.0:
+ resolution: {integrity: sha512-lWyvf/jwu+oS5+hL5eClVd3hNdmwM1kAC0BUvEGD19pajQMIzcNUd/k9GsfQ+FfECvX+JE+e9/btsKH0EjJT6A==}
+
+ remark-frontmatter@5.0.0:
+ resolution: {integrity: sha512-XTFYvNASMe5iPN0719nPrdItC9aU0ssC4v14mH1BCi1u0n1gAocqcujWUrByftZTbLhRtiKRyjYTSIOcr69UVQ==}
+
+ remark-mdx-frontmatter@4.0.0:
+ resolution: {integrity: sha512-PZzAiDGOEfv1Ua7exQ8S5kKxkD8CDaSb4nM+1Mprs6u8dyvQifakh+kCj6NovfGXW+bTvrhjaR3srzjS2qJHKg==}
+
+ remark-mdx@3.1.0:
+ resolution: {integrity: sha512-Ngl/H3YXyBV9RcRNdlYsZujAmhsxwzxpDzpDEhFBVAGthS4GDgnctpDjgFl/ULx5UEDzqtW1cyBSNKqYYrqLBA==}
+
+ remark-parse@11.0.0:
+ resolution: {integrity: sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==}
+
+ remark-rehype@11.1.2:
+ resolution: {integrity: sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==}
+
remix-hono@0.0.18:
resolution: {integrity: sha512-pYRFCRjCSDxjIco+qUkGQNIOZwKC/3NaDssLE2gBsLVHuNymUbhwMZeQDu1ERxdrYQuBE19Zn3vS8jL8AXcoxA==}
peerDependencies:
@@ -3041,6 +3528,10 @@ packages:
scheduler@0.25.0:
resolution: {integrity: sha512-xFVuu11jh+xcO7JOAGJNOXld8/TcEHK/4CituBUeUb5hqxJLj9YuemAEuvm9gQ/+pgXYfbQuqAkiYu+u7YEsNA==}
+ section-matter@1.0.0:
+ resolution: {integrity: sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==}
+ engines: {node: '>=4'}
+
semver@6.3.1:
resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==}
hasBin: true
@@ -3050,6 +3541,9 @@ packages:
engines: {node: '>=10'}
hasBin: true
+ serialize-javascript@6.0.2:
+ resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==}
+
set-cookie-parser@2.7.1:
resolution: {integrity: sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==}
@@ -3075,6 +3569,10 @@ packages:
resolution: {integrity: sha512-FoqMu0NCGBLCcAkS1qA+XJIQTR6/JHfQXl+uGteNCQ76T91DMUjPa9xfmeqMY3z80nLSg9yQmNjK0Px6RWsH/A==}
engines: {node: '>=18'}
+ slug@11.0.0:
+ resolution: {integrity: sha512-71pb27F9TII2dIweGr2ybS220IUZo1A9GKZ+e2q8rpUr24mejBb6fTaSStM0SE1ITUUOshilqZze8Yt1BKj+ew==}
+ hasBin: true
+
smol-toml@1.3.1:
resolution: {integrity: sha512-tEYNll18pPKHroYSmLLrksq233j021G0giwW7P3D24jC54pQ5W5BXMsQ/Mvw1OJCmEYDgY+lrzT+3nNUtoNfXQ==}
engines: {node: '>= 18'}
@@ -3098,6 +3596,9 @@ packages:
resolution: {integrity: sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==}
engines: {node: '>= 8'}
+ space-separated-tokens@2.0.2:
+ resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==}
+
spdx-correct@3.2.0:
resolution: {integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==}
@@ -3110,6 +3611,9 @@ packages:
spdx-license-ids@3.0.21:
resolution: {integrity: sha512-Bvg/8F5XephndSK3JffaRqdT+gyhfqIPwDHpX80tJrF8QQRYMo8sNMeaZ2Dp5+jhwKnUmIOyFFQfHRkjJm5nXg==}
+ sprintf-js@1.0.3:
+ resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==}
+
stack-trace@0.0.10:
resolution: {integrity: sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==}
@@ -3140,9 +3644,16 @@ packages:
resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==}
engines: {node: '>=12'}
+ string-width@6.1.0:
+ resolution: {integrity: sha512-k01swCJAgQmuADB0YIc+7TuatfNvTBVOoaUWJjTB9R4VJzR5vNWzf5t42ESVZFPS8xTySF7CAdV4t/aaIm3UnQ==}
+ engines: {node: '>=16'}
+
string_decoder@1.1.1:
resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==}
+ stringify-entities@4.0.4:
+ resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==}
+
strip-ansi@6.0.1:
resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
engines: {node: '>=8'}
@@ -3151,6 +3662,10 @@ packages:
resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==}
engines: {node: '>=12'}
+ strip-bom-string@1.0.0:
+ resolution: {integrity: sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==}
+ engines: {node: '>=0.10.0'}
+
strip-final-newline@2.0.0:
resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==}
engines: {node: '>=6'}
@@ -3159,6 +3674,12 @@ packages:
resolution: {integrity: sha512-0fk9zBqO67Nq5M/m45qHCJxylV/DhBlIOVExqgOMiCCrzrhU6tCibRXNqE3jwJLftzE9SNuZtYbpzcO+i9FiKw==}
engines: {node: '>=14.16'}
+ style-to-js@1.1.17:
+ resolution: {integrity: sha512-xQcBGDxJb6jjFCTzvQtfiPn6YvvP2O8U1MDIPNfJQlWMYfktPy+iGsHE7cssjs7y84d9fQaK4UF3RIJaAHSoYA==}
+
+ style-to-object@1.0.9:
+ resolution: {integrity: sha512-G4qppLgKu/k6FwRpHiGiKPaPTFcG3g4wNVX/Qsfu+RqQM30E7Tyu/TEgxcL9PNLF5pdRLwQdE3YKKf+KF2Dzlw==}
+
stylis@4.2.0:
resolution: {integrity: sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==}
@@ -3187,6 +3708,9 @@ packages:
resolution: {integrity: sha512-pFYqmTw68LXVjeWJMST4+borgQP2AyMNbg1BpZh9LbyhUeNkeaPF9gzfPGUAnSMV3qPYdWUwDIjjCLiSDOl7vg==}
engines: {node: '>=18'}
+ text-table@0.2.0:
+ resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==}
+
through2@2.0.5:
resolution: {integrity: sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==}
@@ -3220,6 +3744,9 @@ packages:
resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
engines: {node: '>=8.0'}
+ toml@3.0.0:
+ resolution: {integrity: sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==}
+
totalist@3.0.1:
resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==}
engines: {node: '>=6'}
@@ -3231,6 +3758,12 @@ packages:
tr46@0.0.3:
resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==}
+ trim-lines@3.0.1:
+ resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==}
+
+ trough@2.2.0:
+ resolution: {integrity: sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==}
+
tsconfck@3.1.5:
resolution: {integrity: sha512-CLDfGgUp7XPswWnezWwsCRxNmgQjhYq3VXHM0/XIRxhVrKw0M1if9agzryh1QS3nxjCROvV+xWxoJO1YctzzWg==}
engines: {node: ^18 || >=20}
@@ -3260,6 +3793,9 @@ packages:
resolution: {integrity: sha512-2/AwEFQDFEy30iOLjrvHDIH7e4HEWH+f1Yl1bI5XMqzuoCUqwYCdxachgsgv0og/JdVZUhbfjcJAoHj5L1753A==}
engines: {node: '>=16'}
+ type-flag@3.0.0:
+ resolution: {integrity: sha512-3YaYwMseXCAhBB14RXW5cRQfJQlEknS6i4C8fCfeUdS3ihG9EdccdR9kt3vP73ZdeTGmPb4bZtkDn5XMIn1DLA==}
+
typedarray@0.0.6:
resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==}
@@ -3275,6 +3811,27 @@ packages:
resolution: {integrity: sha512-q/1rj5D0/zayJB2FraXdaWxbhWiNKDvu8naDT2dl1yTlvJp4BLtOcp2a5BvgGNQpYYJzau7tf1WgKv3b+7mqpQ==}
engines: {node: '>=18.17'}
+ unified@11.0.5:
+ resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==}
+
+ unist-util-is@6.0.0:
+ resolution: {integrity: sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==}
+
+ unist-util-position-from-estree@2.0.0:
+ resolution: {integrity: sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ==}
+
+ unist-util-position@5.0.0:
+ resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==}
+
+ unist-util-stringify-position@4.0.0:
+ resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==}
+
+ unist-util-visit-parents@6.0.1:
+ resolution: {integrity: sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==}
+
+ unist-util-visit@5.0.0:
+ resolution: {integrity: sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==}
+
universalify@0.2.0:
resolution: {integrity: sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==}
engines: {node: '>= 4.0.0'}
@@ -3323,6 +3880,10 @@ packages:
resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==}
hasBin: true
+ uuid@9.0.1:
+ resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==}
+ hasBin: true
+
valibot@0.41.0:
resolution: {integrity: sha512-igDBb8CTYr8YTQlOKgaN9nSS0Be7z+WRuaeYqGf3Cjz3aKmSnqEmYnkfVjzIuumGqfHpa3fLIvMEAfhrpqN8ng==}
peerDependencies:
@@ -3338,6 +3899,12 @@ packages:
resolution: {integrity: sha512-OljLrQ9SQdOUqTaQxqL5dEfZWrXExyyWsozYlAWFawPVNuD83igl7uJD2RTkNMbniIYgt8l81eCJGIdQF7avLQ==}
engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
+ vfile-message@4.0.2:
+ resolution: {integrity: sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==}
+
+ vfile@6.0.3:
+ resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==}
+
vite-node@3.0.0-beta.2:
resolution: {integrity: sha512-ofTf6cfRdL30Wbl9n/BX81EyIR5s4PReLmSurrxQ+koLaWUNOEo8E0lCM53OJkb8vpa2URM2nSrxZsIFyvY1rg==}
engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0}
@@ -3541,6 +4108,11 @@ packages:
resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==}
engines: {node: '>= 6'}
+ yaml@2.8.0:
+ resolution: {integrity: sha512-4lLa/EcQCB0cJkyts+FpIRx5G/llPxfP6VQU5KByHEhLxY3IJCH0f0Hy1MHI8sClTvsIb8qwRJ6R/ZdlDJ/leQ==}
+ engines: {node: '>= 14.6'}
+ hasBin: true
+
yargs-parser@21.1.1:
resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==}
engines: {node: '>=12'}
@@ -3549,10 +4121,18 @@ packages:
resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==}
engines: {node: '>=12'}
+ yocto-queue@1.2.1:
+ resolution: {integrity: sha512-AyeEbWOu/TAXdxlV9wmGcR0+yh2j3vYPGOECcIj2S7MkrLyC7ne+oye2BKTItt0ii2PHk4cDy+95+LshzbXnGg==}
+ engines: {node: '>=12.20'}
+
yoctocolors-cjs@2.1.2:
resolution: {integrity: sha512-cYVsTjKl8b+FrnidjibDWskAv7UKOfcwaVZdp/it9n1s9fU3IkgDbhdIRKCW4JDsAlECJY0ytoVPT3sK6kideA==}
engines: {node: '>=18'}
+ yoctocolors@1.0.0:
+ resolution: {integrity: sha512-qJNAmSF77lWjfRVwCZK3PcKYWrr+55RUQTiXDxXHGbxzf8WuuRgftIB3hqZ5fykjOF/MC62cazsG/2ZDBedOnQ==}
+ engines: {node: '>=14.16'}
+
zod-validation-error@3.4.0:
resolution: {integrity: sha512-ZOPR9SVY6Pb2qqO5XHt+MkkTRxGXb4EVtnjc9JpXUOtUB1T9Ru7mZOT361AN3MsetVe7R0a1KZshJDZdgp9miQ==}
engines: {node: '>=18.0.0'}
@@ -3562,6 +4142,12 @@ packages:
zod@3.24.1:
resolution: {integrity: sha512-muH7gBL9sI1nciMZV67X5fTKKBLtwpZ5VBp1vsOQzj1MhrBZ4wlVCm3gedKZWLp0Oyel8sIGfeiz54Su+OVT+A==}
+ zod@3.25.76:
+ resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==}
+
+ zwitch@2.0.4:
+ resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==}
+
snapshots:
'@ampproject/remapping@2.3.0':
@@ -3992,8 +4578,86 @@ snapshots:
'@types/tough-cookie': 4.0.5
tough-cookie: 4.1.4
+ '@clerc/core@0.44.0':
+ dependencies:
+ '@clerc/utils': 0.44.0(@clerc/core@0.44.0)
+ defu: 6.1.4
+ is-platform: 1.0.0
+ lite-emit: 2.3.0
+ type-fest: 4.35.0
+ type-flag: 3.0.0
+
+ '@clerc/plugin-completions@0.44.0(@clerc/core@0.44.0)':
+ dependencies:
+ '@clerc/core': 0.44.0
+ '@clerc/utils': 0.44.0(@clerc/core@0.44.0)
+
+ '@clerc/plugin-help@0.44.0(@clerc/core@0.44.0)':
+ dependencies:
+ '@clerc/core': 0.44.0
+ '@clerc/utils': 0.44.0(@clerc/core@0.44.0)
+ '@types/text-table': 0.2.5
+ string-width: 6.1.0
+ text-table: 0.2.0
+ yoctocolors: 1.0.0
+
+ '@clerc/plugin-version@0.44.0(@clerc/core@0.44.0)':
+ dependencies:
+ '@clerc/core': 0.44.0
+ '@clerc/utils': 0.44.0(@clerc/core@0.44.0)
+
+ '@clerc/utils@0.44.0(@clerc/core@0.44.0)':
+ dependencies:
+ '@clerc/core': 0.44.0
+
'@colors/colors@1.5.0': {}
+ '@content-collections/cli@0.1.6(@content-collections/core@0.10.0(typescript@5.7.3))':
+ dependencies:
+ '@clerc/core': 0.44.0
+ '@clerc/plugin-completions': 0.44.0(@clerc/core@0.44.0)
+ '@clerc/plugin-help': 0.44.0(@clerc/core@0.44.0)
+ '@clerc/plugin-version': 0.44.0(@clerc/core@0.44.0)
+ '@content-collections/core': 0.10.0(typescript@5.7.3)
+ '@content-collections/integrations': 0.2.1(@content-collections/core@0.10.0(typescript@5.7.3))
+
+ '@content-collections/core@0.10.0(typescript@5.7.3)':
+ dependencies:
+ '@standard-schema/spec': 1.0.0
+ camelcase: 8.0.0
+ chokidar: 4.0.3
+ esbuild: 0.25.0
+ gray-matter: 4.0.3
+ p-limit: 6.2.0
+ picomatch: 4.0.2
+ pluralize: 8.0.0
+ serialize-javascript: 6.0.2
+ tinyglobby: 0.2.12
+ typescript: 5.7.3
+ yaml: 2.8.0
+ zod: 3.25.76
+
+ '@content-collections/integrations@0.2.1(@content-collections/core@0.10.0(typescript@5.7.3))':
+ dependencies:
+ '@content-collections/core': 0.10.0(typescript@5.7.3)
+
+ '@content-collections/mdx@0.2.2(@content-collections/core@0.10.0(typescript@5.7.3))(acorn@8.15.0)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
+ dependencies:
+ '@content-collections/core': 0.10.0(typescript@5.7.3)
+ esbuild: 0.25.0
+ mdx-bundler: 10.1.1(acorn@8.15.0)(esbuild@0.25.0)
+ react: 19.0.0
+ react-dom: 19.0.0(react@19.0.0)
+ unified: 11.0.5
+ transitivePeerDependencies:
+ - acorn
+ - supports-color
+
+ '@content-collections/remix-vite@0.2.2(@content-collections/core@0.10.0(typescript@5.7.3))(vite@6.2.0(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2)(yaml@2.8.0))':
+ dependencies:
+ '@content-collections/core': 0.10.0(typescript@5.7.3)
+ vite: 6.2.0(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2)(yaml@2.8.0)
+
'@dotenvx/dotenvx@1.34.0':
dependencies:
commander: 11.1.0
@@ -4088,10 +4752,20 @@ snapshots:
'@epic-web/client-hints@1.3.5': {}
- '@esbuild/aix-ppc64@0.23.1':
- optional: true
-
- '@esbuild/aix-ppc64@0.25.0':
+ '@esbuild-plugins/node-resolve@0.2.2(esbuild@0.25.0)':
+ dependencies:
+ '@types/resolve': 1.20.6
+ debug: 4.4.0
+ esbuild: 0.25.0
+ escape-string-regexp: 4.0.0
+ resolve: 1.22.10
+ transitivePeerDependencies:
+ - supports-color
+
+ '@esbuild/aix-ppc64@0.23.1':
+ optional: true
+
+ '@esbuild/aix-ppc64@0.25.0':
optional: true
'@esbuild/android-arm64@0.23.1':
@@ -4235,6 +4909,8 @@ snapshots:
'@esbuild/win32-x64@0.25.0':
optional: true
+ '@fal-works/esbuild-plugin-global-externals@2.1.2': {}
+
'@floating-ui/core@1.6.9':
dependencies:
'@floating-ui/utils': 0.2.9
@@ -4338,6 +5014,48 @@ snapshots:
'@jridgewell/resolve-uri': 3.1.2
'@jridgewell/sourcemap-codec': 1.5.0
+ '@mdx-js/esbuild@3.1.0(acorn@8.15.0)(esbuild@0.25.0)':
+ dependencies:
+ '@mdx-js/mdx': 3.1.0(acorn@8.15.0)
+ '@types/unist': 3.0.3
+ esbuild: 0.25.0
+ source-map: 0.7.4
+ vfile: 6.0.3
+ vfile-message: 4.0.2
+ transitivePeerDependencies:
+ - acorn
+ - supports-color
+
+ '@mdx-js/mdx@3.1.0(acorn@8.15.0)':
+ dependencies:
+ '@types/estree': 1.0.6
+ '@types/estree-jsx': 1.0.5
+ '@types/hast': 3.0.4
+ '@types/mdx': 2.0.13
+ collapse-white-space: 2.1.0
+ devlop: 1.1.0
+ estree-util-is-identifier-name: 3.0.0
+ estree-util-scope: 1.0.0
+ estree-walker: 3.0.3
+ hast-util-to-jsx-runtime: 2.3.6
+ markdown-extensions: 2.0.0
+ recma-build-jsx: 1.0.0
+ recma-jsx: 1.0.0(acorn@8.15.0)
+ recma-stringify: 1.0.0
+ rehype-recma: 1.0.0
+ remark-mdx: 3.1.0
+ remark-parse: 11.0.0
+ remark-rehype: 11.1.2
+ source-map: 0.7.4
+ unified: 11.0.5
+ unist-util-position-from-estree: 2.0.0
+ unist-util-stringify-position: 4.0.0
+ unist-util-visit: 5.0.0
+ vfile: 6.0.3
+ transitivePeerDependencies:
+ - acorn
+ - supports-color
+
'@mjackson/node-fetch-server@0.2.0': {}
'@mswjs/interceptors@0.37.6':
@@ -4679,7 +5397,7 @@ snapshots:
'@radix-ui/rect@1.1.0': {}
- '@react-router/dev@7.2.0(@types/node@22.13.1)(babel-plugin-macros@3.1.0)(jiti@2.4.2)(lightningcss@1.29.1)(react-router@7.2.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(tsx@4.19.2)(typescript@5.7.3)(vite@6.2.0(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2))':
+ '@react-router/dev@7.2.0(@types/node@22.13.1)(babel-plugin-macros@3.1.0)(jiti@2.4.2)(lightningcss@1.29.1)(react-router@7.2.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(tsx@4.19.2)(typescript@5.7.3)(vite@6.2.0(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2)(yaml@2.8.0))(yaml@2.8.0)':
dependencies:
'@babel/core': 7.26.9
'@babel/generator': 7.26.9
@@ -4710,8 +5428,8 @@ snapshots:
semver: 7.7.1
set-cookie-parser: 2.7.1
valibot: 0.41.0(typescript@5.7.3)
- vite: 6.2.0(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2)
- vite-node: 3.0.0-beta.2(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2)
+ vite: 6.2.0(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2)(yaml@2.8.0)
+ vite-node: 3.0.0-beta.2(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2)(yaml@2.8.0)
optionalDependencies:
typescript: 5.7.3
transitivePeerDependencies:
@@ -4730,13 +5448,6 @@ snapshots:
- tsx
- yaml
- '@react-router/fs-routes@7.2.0(@react-router/dev@7.2.0(@types/node@22.13.1)(babel-plugin-macros@3.1.0)(jiti@2.4.2)(lightningcss@1.29.1)(react-router@7.2.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(tsx@4.19.2)(typescript@5.7.3)(vite@6.2.0(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2)))(typescript@5.7.3)':
- dependencies:
- '@react-router/dev': 7.2.0(@types/node@22.13.1)(babel-plugin-macros@3.1.0)(jiti@2.4.2)(lightningcss@1.29.1)(react-router@7.2.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(tsx@4.19.2)(typescript@5.7.3)(vite@6.2.0(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2))
- minimatch: 9.0.5
- optionalDependencies:
- typescript: 5.7.3
-
'@react-router/node@7.2.0(react-router@7.2.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(typescript@5.7.3)':
dependencies:
'@mjackson/node-fetch-server': 0.2.0
@@ -4835,6 +5546,8 @@ snapshots:
ignore: 5.3.2
p-map: 4.0.0
+ '@standard-schema/spec@1.0.0': {}
+
'@tailwindcss/node@4.0.9':
dependencies:
enhanced-resolve: 5.18.1
@@ -4888,13 +5601,21 @@ snapshots:
'@tailwindcss/oxide-win32-arm64-msvc': 4.0.9
'@tailwindcss/oxide-win32-x64-msvc': 4.0.9
- '@tailwindcss/vite@4.0.9(vite@6.2.0(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2))':
+ '@tailwindcss/typography@0.5.16(tailwindcss@4.0.9)':
+ dependencies:
+ lodash.castarray: 4.4.0
+ lodash.isplainobject: 4.0.6
+ lodash.merge: 4.6.2
+ postcss-selector-parser: 6.0.10
+ tailwindcss: 4.0.9
+
+ '@tailwindcss/vite@4.0.9(vite@6.2.0(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2)(yaml@2.8.0))':
dependencies:
'@tailwindcss/node': 4.0.9
'@tailwindcss/oxide': 4.0.9
lightningcss: 1.29.1
tailwindcss: 4.0.9
- vite: 6.2.0(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2)
+ vite: 6.2.0(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2)(yaml@2.8.0)
'@testing-library/dom@10.4.0':
dependencies:
@@ -4925,8 +5646,28 @@ snapshots:
'@types/cookie@0.6.0': {}
+ '@types/debug@4.1.12':
+ dependencies:
+ '@types/ms': 2.1.0
+
+ '@types/estree-jsx@1.0.5':
+ dependencies:
+ '@types/estree': 1.0.6
+
'@types/estree@1.0.6': {}
+ '@types/hast@3.0.4':
+ dependencies:
+ '@types/unist': 3.0.3
+
+ '@types/mdast@4.0.4':
+ dependencies:
+ '@types/unist': 3.0.3
+
+ '@types/mdx@2.0.13': {}
+
+ '@types/ms@2.1.0': {}
+
'@types/node@22.13.1':
dependencies:
undici-types: 6.20.0
@@ -4950,23 +5691,35 @@ snapshots:
dependencies:
csstype: 3.1.3
+ '@types/resolve@1.20.6': {}
+
'@types/revalidator@0.3.12': {}
+ '@types/slug@5.0.9': {}
+
'@types/statuses@2.0.5': {}
+ '@types/text-table@0.2.5': {}
+
'@types/tough-cookie@4.0.5': {}
- '@vitest/browser@3.0.5(@types/node@22.13.1)(playwright@1.50.1)(typescript@5.7.3)(vite@6.2.0(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2))(vitest@3.0.5)':
+ '@types/unist@2.0.11': {}
+
+ '@types/unist@3.0.3': {}
+
+ '@ungap/structured-clone@1.3.0': {}
+
+ '@vitest/browser@3.0.5(@types/node@22.13.1)(playwright@1.50.1)(typescript@5.7.3)(vite@6.2.0(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2)(yaml@2.8.0))(vitest@3.0.5)':
dependencies:
'@testing-library/dom': 10.4.0
'@testing-library/user-event': 14.6.1(@testing-library/dom@10.4.0)
- '@vitest/mocker': 3.0.5(msw@2.7.3(@types/node@22.13.1)(typescript@5.7.3))(vite@6.2.0(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2))
+ '@vitest/mocker': 3.0.5(msw@2.7.3(@types/node@22.13.1)(typescript@5.7.3))(vite@6.2.0(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2)(yaml@2.8.0))
'@vitest/utils': 3.0.5
magic-string: 0.30.17
msw: 2.7.3(@types/node@22.13.1)(typescript@5.7.3)
sirv: 3.0.1
tinyrainbow: 2.0.0
- vitest: 3.0.5(@types/node@22.13.1)(@vitest/browser@3.0.5)(@vitest/ui@3.0.5)(happy-dom@16.8.1)(jiti@2.4.2)(lightningcss@1.29.1)(msw@2.7.3(@types/node@22.13.1)(typescript@5.7.3))(tsx@4.19.2)
+ vitest: 3.0.5(@types/debug@4.1.12)(@types/node@22.13.1)(@vitest/browser@3.0.5)(@vitest/ui@3.0.5)(happy-dom@16.8.1)(jiti@2.4.2)(lightningcss@1.29.1)(msw@2.7.3(@types/node@22.13.1)(typescript@5.7.3))(tsx@4.19.2)(yaml@2.8.0)
ws: 8.18.1
optionalDependencies:
playwright: 1.50.1
@@ -4991,9 +5744,9 @@ snapshots:
std-env: 3.8.0
test-exclude: 7.0.1
tinyrainbow: 2.0.0
- vitest: 3.0.5(@types/node@22.13.1)(@vitest/browser@3.0.5)(@vitest/ui@3.0.5)(happy-dom@16.8.1)(jiti@2.4.2)(lightningcss@1.29.1)(msw@2.7.3(@types/node@22.13.1)(typescript@5.7.3))(tsx@4.19.2)
+ vitest: 3.0.5(@types/debug@4.1.12)(@types/node@22.13.1)(@vitest/browser@3.0.5)(@vitest/ui@3.0.5)(happy-dom@16.8.1)(jiti@2.4.2)(lightningcss@1.29.1)(msw@2.7.3(@types/node@22.13.1)(typescript@5.7.3))(tsx@4.19.2)(yaml@2.8.0)
optionalDependencies:
- '@vitest/browser': 3.0.5(@types/node@22.13.1)(playwright@1.50.1)(typescript@5.7.3)(vite@6.2.0(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2))(vitest@3.0.5)
+ '@vitest/browser': 3.0.5(@types/node@22.13.1)(playwright@1.50.1)(typescript@5.7.3)(vite@6.2.0(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2)(yaml@2.8.0))(vitest@3.0.5)
transitivePeerDependencies:
- supports-color
@@ -5004,14 +5757,14 @@ snapshots:
chai: 5.2.0
tinyrainbow: 2.0.0
- '@vitest/mocker@3.0.5(msw@2.7.3(@types/node@22.13.1)(typescript@5.7.3))(vite@6.2.0(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2))':
+ '@vitest/mocker@3.0.5(msw@2.7.3(@types/node@22.13.1)(typescript@5.7.3))(vite@6.2.0(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2)(yaml@2.8.0))':
dependencies:
'@vitest/spy': 3.0.5
estree-walker: 3.0.3
magic-string: 0.30.17
optionalDependencies:
msw: 2.7.3(@types/node@22.13.1)(typescript@5.7.3)
- vite: 6.2.0(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2)
+ vite: 6.2.0(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2)(yaml@2.8.0)
'@vitest/pretty-format@3.0.5':
dependencies:
@@ -5045,7 +5798,7 @@ snapshots:
sirv: 3.0.1
tinyglobby: 0.2.12
tinyrainbow: 2.0.0
- vitest: 3.0.5(@types/node@22.13.1)(@vitest/browser@3.0.5)(@vitest/ui@3.0.5)(happy-dom@16.8.1)(jiti@2.4.2)(lightningcss@1.29.1)(msw@2.7.3(@types/node@22.13.1)(typescript@5.7.3))(tsx@4.19.2)
+ vitest: 3.0.5(@types/debug@4.1.12)(@types/node@22.13.1)(@vitest/browser@3.0.5)(@vitest/ui@3.0.5)(happy-dom@16.8.1)(jiti@2.4.2)(lightningcss@1.29.1)(msw@2.7.3(@types/node@22.13.1)(typescript@5.7.3))(tsx@4.19.2)(yaml@2.8.0)
'@vitest/utils@3.0.5':
dependencies:
@@ -5058,6 +5811,12 @@ snapshots:
abbrev@3.0.0: {}
+ acorn-jsx@5.3.2(acorn@8.15.0):
+ dependencies:
+ acorn: 8.15.0
+
+ acorn@8.15.0: {}
+
aggregate-error@3.1.0:
dependencies:
clean-stack: 2.2.0
@@ -5081,6 +5840,10 @@ snapshots:
arg@5.0.2: {}
+ argparse@1.0.10:
+ dependencies:
+ sprintf-js: 1.0.3
+
argparse@2.0.1: {}
aria-hidden@1.2.4:
@@ -5093,6 +5856,8 @@ snapshots:
assertion-error@2.0.1: {}
+ astring@1.9.0: {}
+
async@2.6.4:
dependencies:
lodash: 4.17.21
@@ -5118,6 +5883,8 @@ snapshots:
dependencies:
'@babel/types': 7.26.9
+ bail@2.0.2: {}
+
balanced-match@1.0.2: {}
beautify@0.0.8:
@@ -5160,8 +5927,12 @@ snapshots:
callsites@3.1.0: {}
+ camelcase@8.0.0: {}
+
caniuse-lite@1.0.30001701: {}
+ ccount@2.0.1: {}
+
chai@5.2.0:
dependencies:
assertion-error: 2.0.1
@@ -5179,6 +5950,14 @@ snapshots:
chalk@5.4.1: {}
+ character-entities-html4@2.1.0: {}
+
+ character-entities-legacy@3.0.0: {}
+
+ character-entities@2.0.2: {}
+
+ character-reference-invalid@2.0.1: {}
+
check-error@2.1.1: {}
chokidar@4.0.3:
@@ -5204,6 +5983,8 @@ snapshots:
clsx@2.1.1: {}
+ collapse-white-space@2.1.0: {}
+
color-convert@2.0.1:
dependencies:
color-name: 1.1.4
@@ -5212,6 +5993,8 @@ snapshots:
colors@1.0.3: {}
+ comma-separated-tokens@2.0.3: {}
+
commander@10.0.1: {}
commander@11.1.0: {}
@@ -5275,6 +6058,8 @@ snapshots:
cssbeautify@0.3.1: {}
+ cssesc@3.0.0: {}
+
csstype@3.1.3: {}
cycle@1.0.3: {}
@@ -5329,6 +6114,10 @@ snapshots:
dependencies:
ms: 2.1.3
+ decode-named-character-reference@1.2.0:
+ dependencies:
+ character-entities: 2.0.2
+
dedent@1.5.3(babel-plugin-macros@3.1.0):
optionalDependencies:
babel-plugin-macros: 3.1.0
@@ -5340,12 +6129,18 @@ snapshots:
clone: 1.0.4
optional: true
+ defu@6.1.4: {}
+
dequal@2.0.3: {}
detect-libc@1.0.3: {}
detect-node-es@1.1.0: {}
+ devlop@1.1.0:
+ dependencies:
+ dequal: 2.0.3
+
diff@5.2.0: {}
dom-accessibility-api@0.5.16: {}
@@ -5405,6 +6200,8 @@ snapshots:
electron-to-chromium@1.5.105: {}
+ emoji-regex@10.4.0: {}
+
emoji-regex@8.0.0: {}
emoji-regex@9.2.2: {}
@@ -5428,6 +6225,20 @@ snapshots:
es-module-lexer@1.6.0: {}
+ esast-util-from-estree@2.0.0:
+ dependencies:
+ '@types/estree-jsx': 1.0.5
+ devlop: 1.1.0
+ estree-util-visit: 2.0.0
+ unist-util-position-from-estree: 2.0.0
+
+ esast-util-from-js@2.0.1:
+ dependencies:
+ '@types/estree-jsx': 1.0.5
+ acorn: 8.15.0
+ esast-util-from-estree: 2.0.0
+ vfile-message: 4.0.2
+
esbuild@0.23.1:
optionalDependencies:
'@esbuild/aix-ppc64': 0.23.1
@@ -5487,6 +6298,43 @@ snapshots:
escape-string-regexp@4.0.0: {}
+ escape-string-regexp@5.0.0: {}
+
+ esprima@4.0.1: {}
+
+ estree-util-attach-comments@3.0.0:
+ dependencies:
+ '@types/estree': 1.0.6
+
+ estree-util-build-jsx@3.0.1:
+ dependencies:
+ '@types/estree-jsx': 1.0.5
+ devlop: 1.1.0
+ estree-util-is-identifier-name: 3.0.0
+ estree-walker: 3.0.3
+
+ estree-util-is-identifier-name@3.0.0: {}
+
+ estree-util-scope@1.0.0:
+ dependencies:
+ '@types/estree': 1.0.6
+ devlop: 1.1.0
+
+ estree-util-to-js@2.0.0:
+ dependencies:
+ '@types/estree-jsx': 1.0.5
+ astring: 1.9.0
+ source-map: 0.7.4
+
+ estree-util-value-to-estree@3.4.0:
+ dependencies:
+ '@types/estree': 1.0.6
+
+ estree-util-visit@2.0.0:
+ dependencies:
+ '@types/estree-jsx': 1.0.5
+ '@types/unist': 3.0.3
+
estree-walker@3.0.3:
dependencies:
'@types/estree': 1.0.6
@@ -5507,6 +6355,12 @@ snapshots:
expect-type@1.1.0: {}
+ extend-shallow@2.0.1:
+ dependencies:
+ is-extendable: 0.1.1
+
+ extend@3.0.2: {}
+
eyes@0.1.8: {}
fast-glob@3.3.3:
@@ -5521,6 +6375,10 @@ snapshots:
dependencies:
reusify: 1.1.0
+ fault@2.0.1:
+ dependencies:
+ format: 0.2.2
+
fdir@6.4.3(picomatch@4.0.2):
optionalDependencies:
picomatch: 4.0.2
@@ -5540,6 +6398,8 @@ snapshots:
cross-spawn: 7.0.6
signal-exit: 4.1.0
+ format@0.2.2: {}
+
framer-motion@12.4.7(react-dom@19.0.0(react@19.0.0))(react@19.0.0):
dependencies:
motion-dom: 12.4.5
@@ -5575,6 +6435,8 @@ snapshots:
dependencies:
resolve-pkg-maps: 1.0.0
+ github-slugger@2.0.0: {}
+
glob-parent@5.1.2:
dependencies:
is-glob: 4.0.3
@@ -5605,6 +6467,13 @@ snapshots:
graphql@16.10.0: {}
+ gray-matter@4.0.3:
+ dependencies:
+ js-yaml: 3.14.1
+ kind-of: 6.0.3
+ section-matter: 1.0.0
+ strip-bom-string: 1.0.0
+
gunzip-maybe@1.4.2:
dependencies:
browserify-zlib: 0.1.4
@@ -5625,6 +6494,59 @@ snapshots:
dependencies:
function-bind: 1.1.2
+ hast-util-heading-rank@3.0.0:
+ dependencies:
+ '@types/hast': 3.0.4
+
+ hast-util-to-estree@3.1.3:
+ dependencies:
+ '@types/estree': 1.0.6
+ '@types/estree-jsx': 1.0.5
+ '@types/hast': 3.0.4
+ comma-separated-tokens: 2.0.3
+ devlop: 1.1.0
+ estree-util-attach-comments: 3.0.0
+ estree-util-is-identifier-name: 3.0.0
+ hast-util-whitespace: 3.0.0
+ mdast-util-mdx-expression: 2.0.1
+ mdast-util-mdx-jsx: 3.2.0
+ mdast-util-mdxjs-esm: 2.0.1
+ property-information: 7.1.0
+ space-separated-tokens: 2.0.2
+ style-to-js: 1.1.17
+ unist-util-position: 5.0.0
+ zwitch: 2.0.4
+ transitivePeerDependencies:
+ - supports-color
+
+ hast-util-to-jsx-runtime@2.3.6:
+ dependencies:
+ '@types/estree': 1.0.6
+ '@types/hast': 3.0.4
+ '@types/unist': 3.0.3
+ comma-separated-tokens: 2.0.3
+ devlop: 1.1.0
+ estree-util-is-identifier-name: 3.0.0
+ hast-util-whitespace: 3.0.0
+ mdast-util-mdx-expression: 2.0.1
+ mdast-util-mdx-jsx: 3.2.0
+ mdast-util-mdxjs-esm: 2.0.1
+ property-information: 7.1.0
+ space-separated-tokens: 2.0.2
+ style-to-js: 1.1.17
+ unist-util-position: 5.0.0
+ vfile-message: 4.0.2
+ transitivePeerDependencies:
+ - supports-color
+
+ hast-util-to-string@3.0.1:
+ dependencies:
+ '@types/hast': 3.0.4
+
+ hast-util-whitespace@3.0.0:
+ dependencies:
+ '@types/hast': 3.0.4
+
he@1.2.0: {}
headers-polyfill@4.0.3: {}
@@ -5680,14 +6602,27 @@ snapshots:
ini@1.3.8: {}
+ inline-style-parser@0.2.4: {}
+
+ is-alphabetical@2.0.1: {}
+
+ is-alphanumerical@2.0.1:
+ dependencies:
+ is-alphabetical: 2.0.1
+ is-decimal: 2.0.1
+
is-arrayish@0.2.1: {}
is-core-module@2.16.1:
dependencies:
hasown: 2.0.2
+ is-decimal@2.0.1: {}
+
is-deflate@1.0.0: {}
+ is-extendable@0.1.1: {}
+
is-extglob@2.1.1: {}
is-fullwidth-code-point@3.0.0: {}
@@ -5698,10 +6633,16 @@ snapshots:
is-gzip@1.0.0: {}
+ is-hexadecimal@2.0.1: {}
+
is-node-process@1.2.0: {}
is-number@7.0.0: {}
+ is-plain-obj@4.1.0: {}
+
+ is-platform@1.0.0: {}
+
is-stream@2.0.1: {}
isarray@1.0.0: {}
@@ -5759,6 +6700,11 @@ snapshots:
js-tokens@4.0.0: {}
+ js-yaml@3.14.1:
+ dependencies:
+ argparse: 1.0.10
+ esprima: 4.0.1
+
js-yaml@4.1.0:
dependencies:
argparse: 2.0.1
@@ -5777,6 +6723,8 @@ snapshots:
optionalDependencies:
graceful-fs: 4.2.11
+ kind-of@6.0.3: {}
+
knip@5.43.6(@types/node@22.13.1)(typescript@5.7.3):
dependencies:
'@nodelib/fs.walk': 3.0.1
@@ -5888,8 +6836,18 @@ snapshots:
lines-and-columns@1.2.4: {}
+ lite-emit@2.3.0: {}
+
+ lodash.castarray@4.4.0: {}
+
+ lodash.isplainobject@4.0.6: {}
+
+ lodash.merge@4.6.2: {}
+
lodash@4.17.21: {}
+ longest-streak@3.1.0: {}
+
loose-envify@1.4.0:
dependencies:
js-tokens: 4.0.0
@@ -5922,12 +6880,353 @@ snapshots:
dependencies:
semver: 7.7.1
+ markdown-extensions@2.0.0: {}
+
+ mdast-util-from-markdown@2.0.2:
+ dependencies:
+ '@types/mdast': 4.0.4
+ '@types/unist': 3.0.3
+ decode-named-character-reference: 1.2.0
+ devlop: 1.1.0
+ mdast-util-to-string: 4.0.0
+ micromark: 4.0.2
+ micromark-util-decode-numeric-character-reference: 2.0.2
+ micromark-util-decode-string: 2.0.1
+ micromark-util-normalize-identifier: 2.0.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+ unist-util-stringify-position: 4.0.0
+ transitivePeerDependencies:
+ - supports-color
+
+ mdast-util-frontmatter@2.0.1:
+ dependencies:
+ '@types/mdast': 4.0.4
+ devlop: 1.1.0
+ escape-string-regexp: 5.0.0
+ mdast-util-from-markdown: 2.0.2
+ mdast-util-to-markdown: 2.1.2
+ micromark-extension-frontmatter: 2.0.0
+ transitivePeerDependencies:
+ - supports-color
+
+ mdast-util-mdx-expression@2.0.1:
+ dependencies:
+ '@types/estree-jsx': 1.0.5
+ '@types/hast': 3.0.4
+ '@types/mdast': 4.0.4
+ devlop: 1.1.0
+ mdast-util-from-markdown: 2.0.2
+ mdast-util-to-markdown: 2.1.2
+ transitivePeerDependencies:
+ - supports-color
+
+ mdast-util-mdx-jsx@3.2.0:
+ dependencies:
+ '@types/estree-jsx': 1.0.5
+ '@types/hast': 3.0.4
+ '@types/mdast': 4.0.4
+ '@types/unist': 3.0.3
+ ccount: 2.0.1
+ devlop: 1.1.0
+ mdast-util-from-markdown: 2.0.2
+ mdast-util-to-markdown: 2.1.2
+ parse-entities: 4.0.2
+ stringify-entities: 4.0.4
+ unist-util-stringify-position: 4.0.0
+ vfile-message: 4.0.2
+ transitivePeerDependencies:
+ - supports-color
+
+ mdast-util-mdx@3.0.0:
+ dependencies:
+ mdast-util-from-markdown: 2.0.2
+ mdast-util-mdx-expression: 2.0.1
+ mdast-util-mdx-jsx: 3.2.0
+ mdast-util-mdxjs-esm: 2.0.1
+ mdast-util-to-markdown: 2.1.2
+ transitivePeerDependencies:
+ - supports-color
+
+ mdast-util-mdxjs-esm@2.0.1:
+ dependencies:
+ '@types/estree-jsx': 1.0.5
+ '@types/hast': 3.0.4
+ '@types/mdast': 4.0.4
+ devlop: 1.1.0
+ mdast-util-from-markdown: 2.0.2
+ mdast-util-to-markdown: 2.1.2
+ transitivePeerDependencies:
+ - supports-color
+
+ mdast-util-phrasing@4.1.0:
+ dependencies:
+ '@types/mdast': 4.0.4
+ unist-util-is: 6.0.0
+
+ mdast-util-to-hast@13.2.0:
+ dependencies:
+ '@types/hast': 3.0.4
+ '@types/mdast': 4.0.4
+ '@ungap/structured-clone': 1.3.0
+ devlop: 1.1.0
+ micromark-util-sanitize-uri: 2.0.1
+ trim-lines: 3.0.1
+ unist-util-position: 5.0.0
+ unist-util-visit: 5.0.0
+ vfile: 6.0.3
+
+ mdast-util-to-markdown@2.1.2:
+ dependencies:
+ '@types/mdast': 4.0.4
+ '@types/unist': 3.0.3
+ longest-streak: 3.1.0
+ mdast-util-phrasing: 4.1.0
+ mdast-util-to-string: 4.0.0
+ micromark-util-classify-character: 2.0.1
+ micromark-util-decode-string: 2.0.1
+ unist-util-visit: 5.0.0
+ zwitch: 2.0.4
+
+ mdast-util-to-string@4.0.0:
+ dependencies:
+ '@types/mdast': 4.0.4
+
+ mdx-bundler@10.1.1(acorn@8.15.0)(esbuild@0.25.0):
+ dependencies:
+ '@babel/runtime': 7.26.9
+ '@esbuild-plugins/node-resolve': 0.2.2(esbuild@0.25.0)
+ '@fal-works/esbuild-plugin-global-externals': 2.1.2
+ '@mdx-js/esbuild': 3.1.0(acorn@8.15.0)(esbuild@0.25.0)
+ esbuild: 0.25.0
+ gray-matter: 4.0.3
+ remark-frontmatter: 5.0.0
+ remark-mdx-frontmatter: 4.0.0
+ uuid: 9.0.1
+ vfile: 6.0.3
+ transitivePeerDependencies:
+ - acorn
+ - supports-color
+
memoize-one@6.0.0: {}
merge-stream@2.0.0: {}
merge2@1.4.1: {}
+ micromark-core-commonmark@2.0.3:
+ dependencies:
+ decode-named-character-reference: 1.2.0
+ devlop: 1.1.0
+ micromark-factory-destination: 2.0.1
+ micromark-factory-label: 2.0.1
+ micromark-factory-space: 2.0.1
+ micromark-factory-title: 2.0.1
+ micromark-factory-whitespace: 2.0.1
+ micromark-util-character: 2.1.1
+ micromark-util-chunked: 2.0.1
+ micromark-util-classify-character: 2.0.1
+ micromark-util-html-tag-name: 2.0.1
+ micromark-util-normalize-identifier: 2.0.1
+ micromark-util-resolve-all: 2.0.1
+ micromark-util-subtokenize: 2.1.0
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+
+ micromark-extension-frontmatter@2.0.0:
+ dependencies:
+ fault: 2.0.1
+ micromark-util-character: 2.1.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+
+ micromark-extension-mdx-expression@3.0.1:
+ dependencies:
+ '@types/estree': 1.0.6
+ devlop: 1.1.0
+ micromark-factory-mdx-expression: 2.0.3
+ micromark-factory-space: 2.0.1
+ micromark-util-character: 2.1.1
+ micromark-util-events-to-acorn: 2.0.3
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+
+ micromark-extension-mdx-jsx@3.0.2:
+ dependencies:
+ '@types/estree': 1.0.6
+ devlop: 1.1.0
+ estree-util-is-identifier-name: 3.0.0
+ micromark-factory-mdx-expression: 2.0.3
+ micromark-factory-space: 2.0.1
+ micromark-util-character: 2.1.1
+ micromark-util-events-to-acorn: 2.0.3
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+ vfile-message: 4.0.2
+
+ micromark-extension-mdx-md@2.0.0:
+ dependencies:
+ micromark-util-types: 2.0.2
+
+ micromark-extension-mdxjs-esm@3.0.0:
+ dependencies:
+ '@types/estree': 1.0.6
+ devlop: 1.1.0
+ micromark-core-commonmark: 2.0.3
+ micromark-util-character: 2.1.1
+ micromark-util-events-to-acorn: 2.0.3
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+ unist-util-position-from-estree: 2.0.0
+ vfile-message: 4.0.2
+
+ micromark-extension-mdxjs@3.0.0:
+ dependencies:
+ acorn: 8.15.0
+ acorn-jsx: 5.3.2(acorn@8.15.0)
+ micromark-extension-mdx-expression: 3.0.1
+ micromark-extension-mdx-jsx: 3.0.2
+ micromark-extension-mdx-md: 2.0.0
+ micromark-extension-mdxjs-esm: 3.0.0
+ micromark-util-combine-extensions: 2.0.1
+ micromark-util-types: 2.0.2
+
+ micromark-factory-destination@2.0.1:
+ dependencies:
+ micromark-util-character: 2.1.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+
+ micromark-factory-label@2.0.1:
+ dependencies:
+ devlop: 1.1.0
+ micromark-util-character: 2.1.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+
+ micromark-factory-mdx-expression@2.0.3:
+ dependencies:
+ '@types/estree': 1.0.6
+ devlop: 1.1.0
+ micromark-factory-space: 2.0.1
+ micromark-util-character: 2.1.1
+ micromark-util-events-to-acorn: 2.0.3
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+ unist-util-position-from-estree: 2.0.0
+ vfile-message: 4.0.2
+
+ micromark-factory-space@2.0.1:
+ dependencies:
+ micromark-util-character: 2.1.1
+ micromark-util-types: 2.0.2
+
+ micromark-factory-title@2.0.1:
+ dependencies:
+ micromark-factory-space: 2.0.1
+ micromark-util-character: 2.1.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+
+ micromark-factory-whitespace@2.0.1:
+ dependencies:
+ micromark-factory-space: 2.0.1
+ micromark-util-character: 2.1.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+
+ micromark-util-character@2.1.1:
+ dependencies:
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+
+ micromark-util-chunked@2.0.1:
+ dependencies:
+ micromark-util-symbol: 2.0.1
+
+ micromark-util-classify-character@2.0.1:
+ dependencies:
+ micromark-util-character: 2.1.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+
+ micromark-util-combine-extensions@2.0.1:
+ dependencies:
+ micromark-util-chunked: 2.0.1
+ micromark-util-types: 2.0.2
+
+ micromark-util-decode-numeric-character-reference@2.0.2:
+ dependencies:
+ micromark-util-symbol: 2.0.1
+
+ micromark-util-decode-string@2.0.1:
+ dependencies:
+ decode-named-character-reference: 1.2.0
+ micromark-util-character: 2.1.1
+ micromark-util-decode-numeric-character-reference: 2.0.2
+ micromark-util-symbol: 2.0.1
+
+ micromark-util-encode@2.0.1: {}
+
+ micromark-util-events-to-acorn@2.0.3:
+ dependencies:
+ '@types/estree': 1.0.6
+ '@types/unist': 3.0.3
+ devlop: 1.1.0
+ estree-util-visit: 2.0.0
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+ vfile-message: 4.0.2
+
+ micromark-util-html-tag-name@2.0.1: {}
+
+ micromark-util-normalize-identifier@2.0.1:
+ dependencies:
+ micromark-util-symbol: 2.0.1
+
+ micromark-util-resolve-all@2.0.1:
+ dependencies:
+ micromark-util-types: 2.0.2
+
+ micromark-util-sanitize-uri@2.0.1:
+ dependencies:
+ micromark-util-character: 2.1.1
+ micromark-util-encode: 2.0.1
+ micromark-util-symbol: 2.0.1
+
+ micromark-util-subtokenize@2.1.0:
+ dependencies:
+ devlop: 1.1.0
+ micromark-util-chunked: 2.0.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+
+ micromark-util-symbol@2.0.1: {}
+
+ micromark-util-types@2.0.2: {}
+
+ micromark@4.0.2:
+ dependencies:
+ '@types/debug': 4.1.12
+ debug: 4.4.0
+ decode-named-character-reference: 1.2.0
+ devlop: 1.1.0
+ micromark-core-commonmark: 2.0.3
+ micromark-factory-space: 2.0.1
+ micromark-util-character: 2.1.1
+ micromark-util-chunked: 2.0.1
+ micromark-util-combine-extensions: 2.0.1
+ micromark-util-decode-numeric-character-reference: 2.0.2
+ micromark-util-encode: 2.0.1
+ micromark-util-normalize-identifier: 2.0.1
+ micromark-util-resolve-all: 2.0.1
+ micromark-util-sanitize-uri: 2.0.1
+ micromark-util-subtokenize: 2.1.0
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+ transitivePeerDependencies:
+ - supports-color
+
micromatch@4.0.8:
dependencies:
braces: 3.0.3
@@ -6056,6 +7355,10 @@ snapshots:
outvariant@1.4.3: {}
+ p-limit@6.2.0:
+ dependencies:
+ yocto-queue: 1.2.1
+
p-map@4.0.0:
dependencies:
aggregate-error: 3.1.0
@@ -6068,6 +7371,16 @@ snapshots:
dependencies:
callsites: 3.1.0
+ parse-entities@4.0.2:
+ dependencies:
+ '@types/unist': 2.0.11
+ character-entities-legacy: 3.0.0
+ character-reference-invalid: 2.0.1
+ decode-named-character-reference: 1.2.0
+ is-alphanumerical: 2.0.1
+ is-decimal: 2.0.1
+ is-hexadecimal: 2.0.1
+
parse-json@5.2.0:
dependencies:
'@babel/code-frame': 7.27.1
@@ -6121,6 +7434,13 @@ snapshots:
optionalDependencies:
fsevents: 2.3.2
+ pluralize@8.0.0: {}
+
+ postcss-selector-parser@6.0.10:
+ dependencies:
+ cssesc: 3.0.0
+ util-deprecate: 1.0.2
+
postcss@8.5.3:
dependencies:
nanoid: 3.3.8
@@ -6168,6 +7488,8 @@ snapshots:
object-assign: 4.1.1
react-is: 16.13.1
+ property-information@7.1.0: {}
+
proto-list@1.2.4: {}
psl@1.15.0:
@@ -6191,6 +7513,10 @@ snapshots:
queue-microtask@1.2.3: {}
+ randombytes@2.1.0:
+ dependencies:
+ safe-buffer: 5.1.2
+
react-d3-tree@3.6.5(react-dom@19.0.0(react@19.0.0))(react@19.0.0):
dependencies:
'@bkrem/react-transition-group': 1.3.5(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
@@ -6263,7 +7589,7 @@ snapshots:
optionalDependencies:
'@types/react': 19.0.8
- react-router-devtools@5.0.4(@types/react-dom@19.0.3(@types/react@19.0.8))(@types/react@19.0.8)(react-dom@19.0.0(react@19.0.0))(react-router@7.2.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(react@19.0.0)(vite@6.2.0(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2)):
+ react-router-devtools@5.0.4(@types/react-dom@19.0.3(@types/react@19.0.8))(@types/react@19.0.8)(react-dom@19.0.0(react@19.0.0))(react-router@7.2.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(react@19.0.0)(vite@6.2.0(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2)(yaml@2.8.0)):
dependencies:
'@babel/core': 7.27.1
'@babel/generator': 7.27.1
@@ -6288,7 +7614,7 @@ snapshots:
react-router: 7.2.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
react-tooltip: 5.28.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
tailwind-merge: 3.0.1
- vite: 6.2.0(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2)
+ vite: 6.2.0(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2)(yaml@2.8.0)
optionalDependencies:
'@biomejs/cli-darwin-arm64': 1.9.4
'@rollup/rollup-darwin-arm64': 4.34.8
@@ -6297,17 +7623,17 @@ snapshots:
- '@emotion/is-prop-valid'
- supports-color
- react-router-hono-server@2.10.0(@react-router/dev@7.2.0(@types/node@22.13.1)(babel-plugin-macros@3.1.0)(jiti@2.4.2)(lightningcss@1.29.1)(react-router@7.2.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(tsx@4.19.2)(typescript@5.7.3)(vite@6.2.0(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2)))(@types/react@19.0.8)(react-router@7.2.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(vite@6.2.0(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2)):
+ react-router-hono-server@2.10.0(@react-router/dev@7.2.0(@types/node@22.13.1)(babel-plugin-macros@3.1.0)(jiti@2.4.2)(lightningcss@1.29.1)(react-router@7.2.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(tsx@4.19.2)(typescript@5.7.3)(vite@6.2.0(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2)(yaml@2.8.0))(yaml@2.8.0))(@types/react@19.0.8)(react-router@7.2.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(vite@6.2.0(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2)(yaml@2.8.0)):
dependencies:
'@drizzle-team/brocli': 0.11.0
'@hono/node-server': 1.13.8(hono@4.6.20)
'@hono/node-ws': 1.1.0(@hono/node-server@1.13.8(hono@4.6.20))(hono@4.6.20)
'@hono/vite-dev-server': 0.17.0(hono@4.6.20)
- '@react-router/dev': 7.2.0(@types/node@22.13.1)(babel-plugin-macros@3.1.0)(jiti@2.4.2)(lightningcss@1.29.1)(react-router@7.2.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(tsx@4.19.2)(typescript@5.7.3)(vite@6.2.0(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2))
+ '@react-router/dev': 7.2.0(@types/node@22.13.1)(babel-plugin-macros@3.1.0)(jiti@2.4.2)(lightningcss@1.29.1)(react-router@7.2.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(tsx@4.19.2)(typescript@5.7.3)(vite@6.2.0(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2)(yaml@2.8.0))(yaml@2.8.0)
'@types/react': 19.0.8
hono: 4.6.20
react-router: 7.2.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
- vite: 6.2.0(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2)
+ vite: 6.2.0(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2)(yaml@2.8.0)
transitivePeerDependencies:
- bufferutil
- utf-8-validate
@@ -6355,8 +7681,96 @@ snapshots:
readdirp@4.1.2: {}
+ recma-build-jsx@1.0.0:
+ dependencies:
+ '@types/estree': 1.0.6
+ estree-util-build-jsx: 3.0.1
+ vfile: 6.0.3
+
+ recma-jsx@1.0.0(acorn@8.15.0):
+ dependencies:
+ acorn-jsx: 5.3.2(acorn@8.15.0)
+ estree-util-to-js: 2.0.0
+ recma-parse: 1.0.0
+ recma-stringify: 1.0.0
+ unified: 11.0.5
+ transitivePeerDependencies:
+ - acorn
+
+ recma-parse@1.0.0:
+ dependencies:
+ '@types/estree': 1.0.6
+ esast-util-from-js: 2.0.1
+ unified: 11.0.5
+ vfile: 6.0.3
+
+ recma-stringify@1.0.0:
+ dependencies:
+ '@types/estree': 1.0.6
+ estree-util-to-js: 2.0.0
+ unified: 11.0.5
+ vfile: 6.0.3
+
regenerator-runtime@0.14.1: {}
+ rehype-recma@1.0.0:
+ dependencies:
+ '@types/estree': 1.0.6
+ '@types/hast': 3.0.4
+ hast-util-to-estree: 3.1.3
+ transitivePeerDependencies:
+ - supports-color
+
+ rehype-slug@6.0.0:
+ dependencies:
+ '@types/hast': 3.0.4
+ github-slugger: 2.0.0
+ hast-util-heading-rank: 3.0.0
+ hast-util-to-string: 3.0.1
+ unist-util-visit: 5.0.0
+
+ remark-frontmatter@5.0.0:
+ dependencies:
+ '@types/mdast': 4.0.4
+ mdast-util-frontmatter: 2.0.1
+ micromark-extension-frontmatter: 2.0.0
+ unified: 11.0.5
+ transitivePeerDependencies:
+ - supports-color
+
+ remark-mdx-frontmatter@4.0.0:
+ dependencies:
+ '@types/mdast': 4.0.4
+ estree-util-is-identifier-name: 3.0.0
+ estree-util-value-to-estree: 3.4.0
+ toml: 3.0.0
+ unified: 11.0.5
+ yaml: 2.8.0
+
+ remark-mdx@3.1.0:
+ dependencies:
+ mdast-util-mdx: 3.0.0
+ micromark-extension-mdxjs: 3.0.0
+ transitivePeerDependencies:
+ - supports-color
+
+ remark-parse@11.0.0:
+ dependencies:
+ '@types/mdast': 4.0.4
+ mdast-util-from-markdown: 2.0.2
+ micromark-util-types: 2.0.2
+ unified: 11.0.5
+ transitivePeerDependencies:
+ - supports-color
+
+ remark-rehype@11.1.2:
+ dependencies:
+ '@types/hast': 3.0.4
+ '@types/mdast': 4.0.4
+ mdast-util-to-hast: 13.2.0
+ unified: 11.0.5
+ vfile: 6.0.3
+
remix-hono@0.0.18(hono@4.6.20)(i18next@24.2.2(typescript@5.7.3))(pretty-cache-header@1.0.0)(react-router@7.2.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(remix-i18next@7.0.2(i18next@24.2.2(typescript@5.7.3))(react-i18next@15.4.0(i18next@24.2.2(typescript@5.7.3))(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(react-router@7.2.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(react@19.0.0))(zod@3.24.1):
dependencies:
hono: 4.6.20
@@ -6427,10 +7841,19 @@ snapshots:
scheduler@0.25.0: {}
+ section-matter@1.0.0:
+ dependencies:
+ extend-shallow: 2.0.1
+ kind-of: 6.0.3
+
semver@6.3.1: {}
semver@7.7.1: {}
+ serialize-javascript@6.0.2:
+ dependencies:
+ randombytes: 2.1.0
+
set-cookie-parser@2.7.1: {}
shebang-command@2.0.0:
@@ -6451,6 +7874,8 @@ snapshots:
mrmime: 2.0.1
totalist: 3.0.1
+ slug@11.0.0: {}
+
smol-toml@1.3.1: {}
source-map-js@1.2.1: {}
@@ -6464,8 +7889,9 @@ snapshots:
source-map@0.6.1: {}
- source-map@0.7.4:
- optional: true
+ source-map@0.7.4: {}
+
+ space-separated-tokens@2.0.2: {}
spdx-correct@3.2.0:
dependencies:
@@ -6481,6 +7907,8 @@ snapshots:
spdx-license-ids@3.0.21: {}
+ sprintf-js@1.0.3: {}
+
stack-trace@0.0.10: {}
stackback@0.0.2: {}
@@ -6507,10 +7935,21 @@ snapshots:
emoji-regex: 9.2.2
strip-ansi: 7.1.0
+ string-width@6.1.0:
+ dependencies:
+ eastasianwidth: 0.2.0
+ emoji-regex: 10.4.0
+ strip-ansi: 7.1.0
+
string_decoder@1.1.1:
dependencies:
safe-buffer: 5.1.2
+ stringify-entities@4.0.4:
+ dependencies:
+ character-entities-html4: 2.1.0
+ character-entities-legacy: 3.0.0
+
strip-ansi@6.0.1:
dependencies:
ansi-regex: 5.0.1
@@ -6519,10 +7958,20 @@ snapshots:
dependencies:
ansi-regex: 6.1.0
+ strip-bom-string@1.0.0: {}
+
strip-final-newline@2.0.0: {}
strip-json-comments@5.0.1: {}
+ style-to-js@1.1.17:
+ dependencies:
+ style-to-object: 1.0.9
+
+ style-to-object@1.0.9:
+ dependencies:
+ inline-style-parser: 0.2.4
+
stylis@4.2.0: {}
summary@2.1.0: {}
@@ -6545,6 +7994,8 @@ snapshots:
glob: 10.4.5
minimatch: 9.0.5
+ text-table@0.2.0: {}
+
through2@2.0.5:
dependencies:
readable-stream: 2.3.8
@@ -6571,6 +8022,8 @@ snapshots:
dependencies:
is-number: 7.0.0
+ toml@3.0.0: {}
+
totalist@3.0.1: {}
tough-cookie@4.1.4:
@@ -6582,6 +8035,10 @@ snapshots:
tr46@0.0.3: {}
+ trim-lines@3.0.1: {}
+
+ trough@2.2.0: {}
+
tsconfck@3.1.5(typescript@5.7.3):
optionalDependencies:
typescript: 5.7.3
@@ -6601,6 +8058,8 @@ snapshots:
type-fest@4.35.0: {}
+ type-flag@3.0.0: {}
+
typedarray@0.0.6: {}
typescript@5.7.3: {}
@@ -6609,6 +8068,43 @@ snapshots:
undici@6.21.1: {}
+ unified@11.0.5:
+ dependencies:
+ '@types/unist': 3.0.3
+ bail: 2.0.2
+ devlop: 1.1.0
+ extend: 3.0.2
+ is-plain-obj: 4.1.0
+ trough: 2.2.0
+ vfile: 6.0.3
+
+ unist-util-is@6.0.0:
+ dependencies:
+ '@types/unist': 3.0.3
+
+ unist-util-position-from-estree@2.0.0:
+ dependencies:
+ '@types/unist': 3.0.3
+
+ unist-util-position@5.0.0:
+ dependencies:
+ '@types/unist': 3.0.3
+
+ unist-util-stringify-position@4.0.0:
+ dependencies:
+ '@types/unist': 3.0.3
+
+ unist-util-visit-parents@6.0.1:
+ dependencies:
+ '@types/unist': 3.0.3
+ unist-util-is: 6.0.0
+
+ unist-util-visit@5.0.0:
+ dependencies:
+ '@types/unist': 3.0.3
+ unist-util-is: 6.0.0
+ unist-util-visit-parents: 6.0.1
+
universalify@0.2.0: {}
universalify@2.0.1: {}
@@ -6645,6 +8141,8 @@ snapshots:
uuid@8.3.2: {}
+ uuid@9.0.1: {}
+
valibot@0.41.0(typescript@5.7.3):
optionalDependencies:
typescript: 5.7.3
@@ -6656,13 +8154,23 @@ snapshots:
validate-npm-package-name@5.0.1: {}
- vite-node@3.0.0-beta.2(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2):
+ vfile-message@4.0.2:
+ dependencies:
+ '@types/unist': 3.0.3
+ unist-util-stringify-position: 4.0.0
+
+ vfile@6.0.3:
+ dependencies:
+ '@types/unist': 3.0.3
+ vfile-message: 4.0.2
+
+ vite-node@3.0.0-beta.2(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2)(yaml@2.8.0):
dependencies:
cac: 6.7.14
debug: 4.4.0
es-module-lexer: 1.6.0
pathe: 1.1.2
- vite: 6.2.0(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2)
+ vite: 6.2.0(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2)(yaml@2.8.0)
transitivePeerDependencies:
- '@types/node'
- jiti
@@ -6677,13 +8185,13 @@ snapshots:
- tsx
- yaml
- vite-node@3.0.5(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2):
+ vite-node@3.0.5(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2)(yaml@2.8.0):
dependencies:
cac: 6.7.14
debug: 4.4.0
es-module-lexer: 1.6.0
pathe: 2.0.3
- vite: 6.2.0(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2)
+ vite: 6.2.0(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2)(yaml@2.8.0)
transitivePeerDependencies:
- '@types/node'
- jiti
@@ -6698,31 +8206,31 @@ snapshots:
- tsx
- yaml
- vite-plugin-babel@1.3.0(@babel/core@7.27.1)(vite@6.2.0(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2)):
+ vite-plugin-babel@1.3.0(@babel/core@7.27.1)(vite@6.2.0(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2)(yaml@2.8.0)):
dependencies:
'@babel/core': 7.27.1
- vite: 6.2.0(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2)
+ vite: 6.2.0(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2)(yaml@2.8.0)
- vite-plugin-icons-spritesheet@3.0.1(vite@6.2.0(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2)):
+ vite-plugin-icons-spritesheet@3.0.1(vite@6.2.0(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2)(yaml@2.8.0)):
dependencies:
chalk: 5.4.1
glob: 11.0.1
node-html-parser: 7.0.1
tinyexec: 0.3.2
- vite: 6.2.0(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2)
+ vite: 6.2.0(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2)(yaml@2.8.0)
- vite-tsconfig-paths@5.1.4(typescript@5.7.3)(vite@6.2.0(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2)):
+ vite-tsconfig-paths@5.1.4(typescript@5.7.3)(vite@6.2.0(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2)(yaml@2.8.0)):
dependencies:
debug: 4.4.0
globrex: 0.1.2
tsconfck: 3.1.5(typescript@5.7.3)
optionalDependencies:
- vite: 6.2.0(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2)
+ vite: 6.2.0(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2)(yaml@2.8.0)
transitivePeerDependencies:
- supports-color
- typescript
- vite@6.2.0(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2):
+ vite@6.2.0(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2)(yaml@2.8.0):
dependencies:
esbuild: 0.25.0
postcss: 8.5.3
@@ -6733,21 +8241,22 @@ snapshots:
jiti: 2.4.2
lightningcss: 1.29.1
tsx: 4.19.2
+ yaml: 2.8.0
vitest-browser-react@0.0.4(@types/react-dom@19.0.3(@types/react@19.0.8))(@types/react@19.0.8)(@vitest/browser@3.0.5)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(vitest@3.0.5):
dependencies:
- '@vitest/browser': 3.0.5(@types/node@22.13.1)(playwright@1.50.1)(typescript@5.7.3)(vite@6.2.0(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2))(vitest@3.0.5)
+ '@vitest/browser': 3.0.5(@types/node@22.13.1)(playwright@1.50.1)(typescript@5.7.3)(vite@6.2.0(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2)(yaml@2.8.0))(vitest@3.0.5)
react: 19.0.0
react-dom: 19.0.0(react@19.0.0)
- vitest: 3.0.5(@types/node@22.13.1)(@vitest/browser@3.0.5)(@vitest/ui@3.0.5)(happy-dom@16.8.1)(jiti@2.4.2)(lightningcss@1.29.1)(msw@2.7.3(@types/node@22.13.1)(typescript@5.7.3))(tsx@4.19.2)
+ vitest: 3.0.5(@types/debug@4.1.12)(@types/node@22.13.1)(@vitest/browser@3.0.5)(@vitest/ui@3.0.5)(happy-dom@16.8.1)(jiti@2.4.2)(lightningcss@1.29.1)(msw@2.7.3(@types/node@22.13.1)(typescript@5.7.3))(tsx@4.19.2)(yaml@2.8.0)
optionalDependencies:
'@types/react': 19.0.8
'@types/react-dom': 19.0.3(@types/react@19.0.8)
- vitest@3.0.5(@types/node@22.13.1)(@vitest/browser@3.0.5)(@vitest/ui@3.0.5)(happy-dom@16.8.1)(jiti@2.4.2)(lightningcss@1.29.1)(msw@2.7.3(@types/node@22.13.1)(typescript@5.7.3))(tsx@4.19.2):
+ vitest@3.0.5(@types/debug@4.1.12)(@types/node@22.13.1)(@vitest/browser@3.0.5)(@vitest/ui@3.0.5)(happy-dom@16.8.1)(jiti@2.4.2)(lightningcss@1.29.1)(msw@2.7.3(@types/node@22.13.1)(typescript@5.7.3))(tsx@4.19.2)(yaml@2.8.0):
dependencies:
'@vitest/expect': 3.0.5
- '@vitest/mocker': 3.0.5(msw@2.7.3(@types/node@22.13.1)(typescript@5.7.3))(vite@6.2.0(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2))
+ '@vitest/mocker': 3.0.5(msw@2.7.3(@types/node@22.13.1)(typescript@5.7.3))(vite@6.2.0(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2)(yaml@2.8.0))
'@vitest/pretty-format': 3.0.7
'@vitest/runner': 3.0.5
'@vitest/snapshot': 3.0.5
@@ -6763,12 +8272,13 @@ snapshots:
tinyexec: 0.3.2
tinypool: 1.0.2
tinyrainbow: 2.0.0
- vite: 6.2.0(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2)
- vite-node: 3.0.5(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2)
+ vite: 6.2.0(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2)(yaml@2.8.0)
+ vite-node: 3.0.5(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2)(yaml@2.8.0)
why-is-node-running: 2.3.0
optionalDependencies:
+ '@types/debug': 4.1.12
'@types/node': 22.13.1
- '@vitest/browser': 3.0.5(@types/node@22.13.1)(playwright@1.50.1)(typescript@5.7.3)(vite@6.2.0(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2))(vitest@3.0.5)
+ '@vitest/browser': 3.0.5(@types/node@22.13.1)(playwright@1.50.1)(typescript@5.7.3)(vite@6.2.0(@types/node@22.13.1)(jiti@2.4.2)(lightningcss@1.29.1)(tsx@4.19.2)(yaml@2.8.0))(vitest@3.0.5)
'@vitest/ui': 3.0.5(vitest@3.0.5)
happy-dom: 16.8.1
transitivePeerDependencies:
@@ -6863,6 +8373,8 @@ snapshots:
yaml@1.10.2: {}
+ yaml@2.8.0: {}
+
yargs-parser@21.1.1: {}
yargs@17.7.2:
@@ -6875,10 +8387,18 @@ snapshots:
y18n: 5.0.8
yargs-parser: 21.1.1
+ yocto-queue@1.2.1: {}
+
yoctocolors-cjs@2.1.2: {}
+ yoctocolors@1.0.0: {}
+
zod-validation-error@3.4.0(zod@3.24.1):
dependencies:
zod: 3.24.1
zod@3.24.1: {}
+
+ zod@3.25.76: {}
+
+ zwitch@2.0.4: {}
diff --git a/public/banner.png b/public/banner.png
deleted file mode 100644
index 81fd4ef..0000000
Binary files a/public/banner.png and /dev/null differ
diff --git a/public/base-stack.png b/public/base-stack.png
deleted file mode 100644
index 6303ae6..0000000
Binary files a/public/base-stack.png and /dev/null differ
diff --git a/public/logo.png b/public/logo.png
deleted file mode 100644
index e2888a0..0000000
Binary files a/public/logo.png and /dev/null differ
diff --git a/resources/fonts/dyna-puff/DynaPuff-Bold.ttf b/resources/fonts/dyna-puff/DynaPuff-Bold.ttf
new file mode 100644
index 0000000..ae02869
Binary files /dev/null and b/resources/fonts/dyna-puff/DynaPuff-Bold.ttf differ
diff --git a/resources/fonts/dyna-puff/DynaPuff-Medium.ttf b/resources/fonts/dyna-puff/DynaPuff-Medium.ttf
new file mode 100644
index 0000000..bfa6ff8
Binary files /dev/null and b/resources/fonts/dyna-puff/DynaPuff-Medium.ttf differ
diff --git a/resources/fonts/dyna-puff/DynaPuff-Regular.ttf b/resources/fonts/dyna-puff/DynaPuff-Regular.ttf
new file mode 100644
index 0000000..1910fbe
Binary files /dev/null and b/resources/fonts/dyna-puff/DynaPuff-Regular.ttf differ
diff --git a/resources/fonts/dyna-puff/DynaPuff-SemiBold.ttf b/resources/fonts/dyna-puff/DynaPuff-SemiBold.ttf
new file mode 100644
index 0000000..34a715e
Binary files /dev/null and b/resources/fonts/dyna-puff/DynaPuff-SemiBold.ttf differ
diff --git a/resources/fonts/inter/Inter-Black.ttf b/resources/fonts/inter/Inter-Black.ttf
new file mode 100644
index 0000000..dbb1b3b
Binary files /dev/null and b/resources/fonts/inter/Inter-Black.ttf differ
diff --git a/resources/fonts/inter/Inter-BlackItalic.ttf b/resources/fonts/inter/Inter-BlackItalic.ttf
new file mode 100644
index 0000000..b89d61c
Binary files /dev/null and b/resources/fonts/inter/Inter-BlackItalic.ttf differ
diff --git a/resources/fonts/inter/Inter-Bold.ttf b/resources/fonts/inter/Inter-Bold.ttf
new file mode 100644
index 0000000..46b3583
Binary files /dev/null and b/resources/fonts/inter/Inter-Bold.ttf differ
diff --git a/resources/fonts/inter/Inter-BoldItalic.ttf b/resources/fonts/inter/Inter-BoldItalic.ttf
new file mode 100644
index 0000000..d1c0f53
Binary files /dev/null and b/resources/fonts/inter/Inter-BoldItalic.ttf differ
diff --git a/resources/fonts/inter/Inter-ExtraBold.ttf b/resources/fonts/inter/Inter-ExtraBold.ttf
new file mode 100644
index 0000000..b775c08
Binary files /dev/null and b/resources/fonts/inter/Inter-ExtraBold.ttf differ
diff --git a/resources/fonts/inter/Inter-ExtraBoldItalic.ttf b/resources/fonts/inter/Inter-ExtraBoldItalic.ttf
new file mode 100644
index 0000000..3461a92
Binary files /dev/null and b/resources/fonts/inter/Inter-ExtraBoldItalic.ttf differ
diff --git a/resources/fonts/inter/Inter-ExtraLight.ttf b/resources/fonts/inter/Inter-ExtraLight.ttf
new file mode 100644
index 0000000..2ec6ca3
Binary files /dev/null and b/resources/fonts/inter/Inter-ExtraLight.ttf differ
diff --git a/resources/fonts/inter/Inter-ExtraLightItalic.ttf b/resources/fonts/inter/Inter-ExtraLightItalic.ttf
new file mode 100644
index 0000000..c634a5d
Binary files /dev/null and b/resources/fonts/inter/Inter-ExtraLightItalic.ttf differ
diff --git a/resources/fonts/inter/Inter-Italic.ttf b/resources/fonts/inter/Inter-Italic.ttf
new file mode 100644
index 0000000..1048b07
Binary files /dev/null and b/resources/fonts/inter/Inter-Italic.ttf differ
diff --git a/resources/fonts/inter/Inter-Light.ttf b/resources/fonts/inter/Inter-Light.ttf
new file mode 100644
index 0000000..1a2a6f2
Binary files /dev/null and b/resources/fonts/inter/Inter-Light.ttf differ
diff --git a/resources/fonts/inter/Inter-LightItalic.ttf b/resources/fonts/inter/Inter-LightItalic.ttf
new file mode 100644
index 0000000..ded5a75
Binary files /dev/null and b/resources/fonts/inter/Inter-LightItalic.ttf differ
diff --git a/resources/fonts/inter/Inter-Medium.ttf b/resources/fonts/inter/Inter-Medium.ttf
new file mode 100644
index 0000000..5c88739
Binary files /dev/null and b/resources/fonts/inter/Inter-Medium.ttf differ
diff --git a/resources/fonts/inter/Inter-MediumItalic.ttf b/resources/fonts/inter/Inter-MediumItalic.ttf
new file mode 100644
index 0000000..be091b1
Binary files /dev/null and b/resources/fonts/inter/Inter-MediumItalic.ttf differ
diff --git a/resources/fonts/inter/Inter-Regular.ttf b/resources/fonts/inter/Inter-Regular.ttf
new file mode 100644
index 0000000..6b088a7
Binary files /dev/null and b/resources/fonts/inter/Inter-Regular.ttf differ
diff --git a/resources/fonts/inter/Inter-SemiBold.ttf b/resources/fonts/inter/Inter-SemiBold.ttf
new file mode 100644
index 0000000..ceb8576
Binary files /dev/null and b/resources/fonts/inter/Inter-SemiBold.ttf differ
diff --git a/resources/fonts/inter/Inter-SemiBoldItalic.ttf b/resources/fonts/inter/Inter-SemiBoldItalic.ttf
new file mode 100644
index 0000000..6921df2
Binary files /dev/null and b/resources/fonts/inter/Inter-SemiBoldItalic.ttf differ
diff --git a/resources/fonts/inter/Inter-Thin.ttf b/resources/fonts/inter/Inter-Thin.ttf
new file mode 100644
index 0000000..3505b35
Binary files /dev/null and b/resources/fonts/inter/Inter-Thin.ttf differ
diff --git a/resources/fonts/inter/Inter-ThinItalic.ttf b/resources/fonts/inter/Inter-ThinItalic.ttf
new file mode 100644
index 0000000..a3e6feb
Binary files /dev/null and b/resources/fonts/inter/Inter-ThinItalic.ttf differ
diff --git a/resources/fonts/space/Space.woff2 b/resources/fonts/space/Space.woff2
new file mode 100644
index 0000000..0adf4d1
Binary files /dev/null and b/resources/fonts/space/Space.woff2 differ
diff --git a/resources/icons/arrow-left.svg b/resources/icons/arrow-left.svg
new file mode 100644
index 0000000..d316096
--- /dev/null
+++ b/resources/icons/arrow-left.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/resources/icons/arrow-right.svg b/resources/icons/arrow-right.svg
new file mode 100644
index 0000000..8405ae2
--- /dev/null
+++ b/resources/icons/arrow-right.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/resources/icons/chevron-down.svg b/resources/icons/chevron-down.svg
new file mode 100644
index 0000000..e576b4f
--- /dev/null
+++ b/resources/icons/chevron-down.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/resources/icons/chevron-right.svg b/resources/icons/chevron-right.svg
new file mode 100644
index 0000000..5db5d6e
--- /dev/null
+++ b/resources/icons/chevron-right.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/resources/icons/clipboard-check.svg b/resources/icons/clipboard-check.svg
new file mode 100644
index 0000000..084efca
--- /dev/null
+++ b/resources/icons/clipboard-check.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/resources/icons/clipboard-copy.svg b/resources/icons/clipboard-copy.svg
new file mode 100644
index 0000000..62568ac
--- /dev/null
+++ b/resources/icons/clipboard-copy.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/resources/icons/info.svg b/resources/icons/info.svg
new file mode 100644
index 0000000..a2771b4
--- /dev/null
+++ b/resources/icons/info.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/resources/icons/menu.svg b/resources/icons/menu.svg
new file mode 100644
index 0000000..b6f8033
--- /dev/null
+++ b/resources/icons/menu.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/resources/icons/moon.svg b/resources/icons/moon.svg
new file mode 100644
index 0000000..07320f1
--- /dev/null
+++ b/resources/icons/moon.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/resources/icons/sun-moon.svg b/resources/icons/sun-moon.svg
new file mode 100644
index 0000000..91a2370
--- /dev/null
+++ b/resources/icons/sun-moon.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/resources/icons/sun.svg b/resources/icons/sun.svg
new file mode 100644
index 0000000..65c97c7
--- /dev/null
+++ b/resources/icons/sun.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/resources/icons/triangle-alert.svg b/resources/icons/triangle-alert.svg
new file mode 100644
index 0000000..1a5b698
--- /dev/null
+++ b/resources/icons/triangle-alert.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/resources/icons/x.svg b/resources/icons/x.svg
new file mode 100644
index 0000000..eb194fd
--- /dev/null
+++ b/resources/icons/x.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/resources/locales/bs/common.json b/resources/locales/bs/common.json
index fc42f27..981842f 100644
--- a/resources/locales/bs/common.json
+++ b/resources/locales/bs/common.json
@@ -21,5 +21,26 @@
"title": "Nešto je krenulo po zlu!",
"description": "Izgleda da se nešto desilo na serveru."
}
+ },
+ "links": {
+ "previous": "Prethodni",
+ "next": "Sljedeći",
+ "report_an_issue_on_this_page": "Prijavi problem na ovoj stranici",
+ "edit_this_page": "Uredi ovu stranicu"
+ },
+ "p": {
+ "last_update": "Posljednja izmjena:",
+ "version": "Verzija",
+ "all_rights_reserved": "Sva prava zadržana."
+ },
+ "buttons": {
+ "copy": "Kopiraj",
+ "copied": "Kopirano",
+ "home": "Nazad na početnu",
+ "back": "Idi nazad"
+ },
+ "titles": {
+ "good_to_know": "Dobro je znati",
+ "warning": "Upozorenje"
}
}
diff --git a/resources/locales/en/common.json b/resources/locales/en/common.json
index 2cb2014..e43ff97 100644
--- a/resources/locales/en/common.json
+++ b/resources/locales/en/common.json
@@ -21,5 +21,26 @@
"title": "Something went wrong!",
"description": "Looks like something unexpected happened on the server."
}
+ },
+ "links": {
+ "previous": "Previous",
+ "next": "Next",
+ "report_an_issue_on_this_page": "Report an issue on this page",
+ "edit_this_page": "Edit this page"
+ },
+ "p": {
+ "last_update": "Last updated: ",
+ "version": "Version",
+ "all_rights_reserved": "All rights reserved."
+ },
+ "buttons": {
+ "copy": "Copy",
+ "copied": "Copied",
+ "home": "Back to home",
+ "back": "Go back"
+ },
+ "titles": {
+ "good_to_know": "Good to know",
+ "warning": "Warning"
}
}
diff --git a/scripts/README.md b/scripts/README.md
deleted file mode 100644
index 09cdb46..0000000
--- a/scripts/README.md
+++ /dev/null
@@ -1,144 +0,0 @@
-# Scripting
-
-This directory contains scripts that are used to automate various tasks. The scripts are written in Typescript.
-
-They fully work with:
-- alias imports like "~";
-- configurable env variables;
-- confirmation dialogs
-- esm compatibility
-
-The scripts are placed in the `scripts` directory. And you can run them through your package.json scripts.
-
-The main script that sets everything up for other scripts is located in `scripts/setup.ts` and it does the following:
-- sets up the environment variables using `dotenv`
-- asks for confirmation before running the scripts if required
-
-Your `package.json` contains the following scripts:
-```json
-"scripts": {
- "execute": "node --no-warnings --experimental-specifier-resolution=node --loader ./scripts/loader.js",
- "script": "npm run execute scripts/setup.ts",
-}
-```
-
-## execute
-
-This script uses node loaders to run the scripts, due to issues with ts-node and esm compatibility. It is used to run the scripts by
-using a custom loader located in `scripts/loader.js`. This allows for the alias `~` to be used in the scripts.
-
-## script
-
-This script is used to run the scripts. It uses the `execute` script to run the `scripts/setup.ts` script. This script sets up the environment
-variables and asks for confirmation before running the scripts if required.
-
-This is configurable and is set by this part of the code:
-
-```ts
-const ENVIRONMENTS = ["stage", "prod", "test"];
-
-const getEnvInfo = () => {
- // Gets the environment from the command line arguments if set, otherwise defaults to dev
- const env = process.argv.find((arg) => ENVIRONMENTS.includes(arg)) ?? "";
- // Sets the environment name to be console logged for info
- const envName = env !== "" ? env : "dev";
- // Allows for reading from .env .env.prod .env.stage etc
- const path = `.env${env ? `.${env}` : ""}`;
- return { env, envName, path };
-};
-
-const setupEnv = () => {
- const { envName, path } = getEnvInfo();
- console.log(chalk.green(`Loading environment: ${envName}`));
- dotenv.config({ path });
- console.log(
- `Environment loaded: ${chalk.green(envName)} from ${chalk.green(path)}`
- );
-};
-```
-
-You can test this out by adding `.env` and `.env.test` to you root directory and adding the following to the `.env.test` file:
-
-```env
-TEST=This is an env var from .env.test
-```
-
- And in your `.env` file add the following:
-
-```env
-TEST=This is an env var from .env
-```
-
-Then inside of `getEnvInfo` function add the following console log:
-
-```ts
-console.log(process.env.TEST);
-```
-
-then run the following script:
-
-```bash
-npm run script test
-```
-
-and you should see the following output:
-
-```bash
-This is an env var from .env.test
-```
-
-and running:
-
-```bash
-npm run script
-```
-
-you should see the following output:
-
-```bash
-This is an env var from .env
-```
-
-
-After this is done the script checks for the presence of the `confirm` parameter in the command line arguments. If it is present, it will ask for confirmation before running the script.
-
-So if you want to confirm a script (eg database seed) before running it you can do:
-
-```bash
-npm run script \"scripts/your-command.ts\" confirm
-```
-
-This will ask for confirmation before running the script `your-command.ts`.
-
-This is useful for scripts that can have a big impact on the application like database seeding, deleting files etc.
-
-## Script examples
-
-Here are some examples of scripts that you can run:
-
-```bash
-Runs with .env vars and no confirmation
-npm run script scripts/your-command.ts
-```
-
-```bash
-Runs with .env vars and confirmation
-npm run script scripts/your-command.ts confirm
-```
-
-```bash
-Runs with .env.test vars and confirmation
-npm run script scripts/your-command.ts test confirm
-```
-
-```bash
-Runs with .env.stage vars and confirmation
-npm run script scripts/your-command.ts stage confirm
-```
-
-```bash
-Runs with .env.prod vars and confirmation but runs a third-party script
-npm run script \"npx prisma migrate dev\" prod confirm
-```
-
-
\ No newline at end of file
diff --git a/scripts/cleanup.ts b/scripts/cleanup.ts
deleted file mode 100644
index bc8fec4..0000000
--- a/scripts/cleanup.ts
+++ /dev/null
@@ -1,76 +0,0 @@
-import { promises as fs } from "node:fs"
-import chalk from "chalk"
-
-const appDirectory = "app"
-
-const removeAllReadmeFromApp = async (currentDirectory: string) => {
- const files = await fs.readdir(currentDirectory)
-
- for (const file of files) {
- // Check if the current file is directory
- const isDirectory = (await fs.stat(`${currentDirectory}/${file}`)).isDirectory()
- if (isDirectory) {
- await removeAllReadmeFromApp(`${currentDirectory}/${file}`)
- }
- if (file.includes("README.md")) {
- await fs.unlink(`${currentDirectory}/${file}`)
- }
- }
-}
-
-const log = (message: string) => console.log(chalk.green(message))
-
-const removeTheCleanupFromPackageJsonAndScripts = async () => {
- const packageJson = JSON.parse(await fs.readFile("package.json", { encoding: "utf-8" }))
- packageJson.scripts.cleanup = undefined
- packageJson.scripts.postinstall = undefined
-
- await fs.writeFile("package.json", JSON.stringify(packageJson, null, 2), "utf-8")
-
- log(chalk.green("Cleanup script is removed from package.json"))
- await fs.unlink("scripts/cleanup.ts")
-}
-
-const revertIndexRoute = async () => {
- const file = `import type { MetaFunction } from "react-router";
-import { useTranslation } from "react-i18next";
-
-export const meta: MetaFunction = () => {
- return [
- { title: "New Remix App" },
- { name: "description", content: "Welcome to Remix!" },
- ];
-};
-
-export default function Index() {
- const { t } = useTranslation();
- return (
-
- {t("hi")}
-
- );
-}
-`
- await fs.writeFile("app/routes/_index.tsx", file, "utf-8")
- log(chalk.green("Index route is reverted to empty state"))
-}
-
-const removeForgeAssets = async () => {
- await fs.unlink("public/logo.png")
- await fs.unlink("public/base-stack.png")
- await fs.unlink("public/banner.png")
- log(chalk.green("Forge assets are removed from public directory"))
-}
-
-const runCleanup = async () => {
- await removeForgeAssets()
- await revertIndexRoute()
- await removeAllReadmeFromApp(appDirectory).then(async () => {
- await fs.unlink("scripts/README.md")
- await fs.unlink("tests/README.md")
- log(chalk.green("All README.md files are removed from app directory"))
- })
- removeTheCleanupFromPackageJsonAndScripts()
-}
-
-runCleanup()
diff --git a/tests/README.md b/tests/README.md
deleted file mode 100644
index 1defbdb..0000000
--- a/tests/README.md
+++ /dev/null
@@ -1,92 +0,0 @@
-# Testing react-router apps
-
-This directory contains the setup for testing react-router apps. It includes the `setup.unit.tsx` file which sets up the testing environment for unit tests.
-
-The `setup.unit.tsx` file is used to set up the testing environment for unit tests in the following ways:
-1. It sets up the i18next instance with the `i18n` configuration.
-2. It extends your test context with the `renderStub` function which is used to render the react-router routes.
-3. It extends your test context with the `debug` function which is used to debug your unit tests with `jest-preview`.
-
-The `renderStub` function is used to render the react-router routes and return the container. It takes the following arguments:
-- `props`: Optional props to be passed into the react-router stub.
-- `entries`: Optional entries to be passed into the react-router stub.
-- `i18n`: Optional i18n configuration to be passed into the react-router stub.
-
-The `debug` function is used to debug your unit tests with `jest-preview`. To use it, run your tests by running:
-
-
-```bash
-pnpm test:live
-```
-
-This will run your tests in watch mode and you can use the `debug` function to debug your tests.
-This will do two things:
-1. Start the `jest-preview` server.
-2. Open the `jest-preview` server in your browser.
-3. Start `vitest` in UI mode.
-
-You can use the `debug` function to debug your tests by adding the following code to your test:
-
-```ts
-it("should do something", ({ debug }) => {
- // Your test code here
- debug()
-})
-```
-
-This will render the tests current state into the `jest-preview` server and you can use the `debug` function to debug your tests.
-
-## Benefits
-
-- It sets up the i18next instance with the `i18n` configuration.
-- It extends your test context with the `renderStub` function which is used to render the react-router routes.
-- It extends your test context with the `debug` function which is used to debug your unit tests with `jest-preview`.
-- It sets up the testing environment for unit tests
-
-## How to use
-
-1. Extract the `renderStub` function from the vitest test context.
-```ts
-test("should do something", async ({ renderStub }) => {
- // Your test code here
-})
-```
-
-2. Use the `renderStub` function to render the react-router routes.
-```ts
-test("should do something", async ({ renderStub }) => {
- const { container } = await renderStub({
- props: {
- initialEntries: ["/"],
- },
- entries: [
- {
- id: "home",
- path: "/",
- Component: Home,
- ...Home,
- },
- ],
- })
-})
-```
-
-3. Test your routes by using the `container` object.
-```ts
-test("should do something", async ({ renderStub }) => {
- const { container } = await renderStub({
- props: {
- initialEntries: ["/"],
- },
- entries: [
- {
- id: "home",
- path: "/",
- Component: Home,
- ...Home,
- },
- ],
- })
- expect(container.queryByText("Home", { exact: false })).not.toBeNull()
-})
-```
diff --git a/tsconfig.json b/tsconfig.json
index 0fb68c8..4b5d5e3 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -16,7 +16,8 @@
"forceConsistentCasingInFileNames": true,
"baseUrl": ".",
"paths": {
- "~/*": ["./app/*"]
+ "~/*": ["./app/*"],
+ "content-collections": ["./.content-collections/generated"]
},
"rootDirs": [".", "./.react-router/types"],
"plugins": [{ "name": "@react-router/dev" }],
diff --git a/vite.config.ts b/vite.config.ts
index d882529..017f819 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -1,3 +1,4 @@
+import contentCollections from "@content-collections/remix-vite"
import { reactRouter } from "@react-router/dev/vite"
import tailwindcss from "@tailwindcss/vite"
import { reactRouterDevTools } from "react-router-devtools"
@@ -25,17 +26,18 @@ export default defineConfig({
reactRouter(),
reactRouterHonoServer({
dev: {
- exclude: [/^\/(resources)\/.+/],
+ exclude: [/^\/(resources)\/.+/, /^\/(.content-collections)\/.+/],
},
}),
tsconfigPaths(),
iconsSpritesheet({
inputDir: "./resources/icons",
- outputDir: "./app/library/icon/icons",
+ outputDir: "./app/ui/icon/icons",
fileName: "icon.svg",
withTypes: true,
formatter: "biome",
}),
+ contentCollections(),
],
server: {
open: true,