From 4cb51a254c41cdb45ee1bbd44ac7b9c7a8014aa3 Mon Sep 17 00:00:00 2001 From: Adam Matthiesen Date: Thu, 2 Jan 2025 22:13:54 -0800 Subject: [PATCH] init --- .vscode/settings.json | 2 +- biome.json | 3 + package.json | 8 +- packages/markdown-remark/package.json | 69 + packages/markdown-remark/src/HTMLString.ts | 5 + packages/markdown-remark/src/frontmatter.ts | 81 + packages/markdown-remark/src/highlight.ts | 98 + .../src/import-plugin-browser.ts | 8 + .../src/import-plugin-default.ts | 22 + packages/markdown-remark/src/index.ts | 176 + packages/markdown-remark/src/load-plugins.ts | 38 + .../src/rehype-collect-headings.ts | 130 + packages/markdown-remark/src/rehype-images.ts | 33 + packages/markdown-remark/src/rehype-prism.ts | 16 + packages/markdown-remark/src/rehype-shiki.ts | 28 + .../src/remark-collect-images.ts | 43 + packages/markdown-remark/src/shiki.ts | 203 ++ packages/markdown-remark/src/types.ts | 88 + .../markdown-remark/test/autolinking.test.ts | 39 + packages/markdown-remark/test/browser.test.ts | 53 + .../markdown-remark/test/entities.test.ts | 17 + .../markdown-remark/test/frontmatter.test.ts | 102 + packages/markdown-remark/test/plugins.test.ts | 31 + .../test/remark-collect-images.test.ts | 41 + packages/markdown-remark/test/shiki.test.ts | 135 + packages/markdown-remark/tsconfig.json | 8 + packages/markdown-remark/vitest.config.mts | 11 + pnpm-lock.yaml | 2886 ++++++++++++++++- pnpm-workspace.yaml | 2 +- scripts/cmd/build.js | 164 + scripts/cmd/prebuild.js | 115 + scripts/index.js | 19 + scripts/jsconfig.json | 12 + scripts/package.json | 19 + tsconfig.base.json | 15 + vitest.workspace.ts | 3 + 36 files changed, 4709 insertions(+), 14 deletions(-) create mode 100644 packages/markdown-remark/package.json create mode 100644 packages/markdown-remark/src/HTMLString.ts create mode 100644 packages/markdown-remark/src/frontmatter.ts create mode 100644 packages/markdown-remark/src/highlight.ts create mode 100644 packages/markdown-remark/src/import-plugin-browser.ts create mode 100644 packages/markdown-remark/src/import-plugin-default.ts create mode 100644 packages/markdown-remark/src/index.ts create mode 100644 packages/markdown-remark/src/load-plugins.ts create mode 100644 packages/markdown-remark/src/rehype-collect-headings.ts create mode 100644 packages/markdown-remark/src/rehype-images.ts create mode 100644 packages/markdown-remark/src/rehype-prism.ts create mode 100644 packages/markdown-remark/src/rehype-shiki.ts create mode 100644 packages/markdown-remark/src/remark-collect-images.ts create mode 100644 packages/markdown-remark/src/shiki.ts create mode 100644 packages/markdown-remark/src/types.ts create mode 100644 packages/markdown-remark/test/autolinking.test.ts create mode 100644 packages/markdown-remark/test/browser.test.ts create mode 100644 packages/markdown-remark/test/entities.test.ts create mode 100644 packages/markdown-remark/test/frontmatter.test.ts create mode 100644 packages/markdown-remark/test/plugins.test.ts create mode 100644 packages/markdown-remark/test/remark-collect-images.test.ts create mode 100644 packages/markdown-remark/test/shiki.test.ts create mode 100644 packages/markdown-remark/tsconfig.json create mode 100644 packages/markdown-remark/vitest.config.mts create mode 100644 scripts/cmd/build.js create mode 100644 scripts/cmd/prebuild.js create mode 100755 scripts/index.js create mode 100644 scripts/jsconfig.json create mode 100644 scripts/package.json create mode 100644 tsconfig.base.json create mode 100644 vitest.workspace.ts diff --git a/.vscode/settings.json b/.vscode/settings.json index e434fa4..d0744e0 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -6,5 +6,5 @@ }, "editor.defaultFormatter": "biomejs.biome", "editor.gotoLocation.multipleDefinitions": "goto", - "cSpell.words": ["mergebot", "studiocms", "withstudiocms"] + "cSpell.words": ["mergebot", "Shiki", "studiocms", "withstudiocms"] } diff --git a/biome.json b/biome.json index cd36124..495c0e9 100644 --- a/biome.json +++ b/biome.json @@ -34,6 +34,9 @@ "recommended": true, "suspicious": { "noExplicitAny": "warn" + }, + "style": { + "noParameterAssign": "info" } } }, diff --git a/package.json b/package.json index b949ac7..6b501ba 100644 --- a/package.json +++ b/package.json @@ -6,20 +6,26 @@ "node": "20.14.0" }, "scripts": { + "build": "pnpm --filter @studiocms/markdown-remark build", "lint": "biome check .", "lint:fix": "biome check --write .", "ci:lint": "biome ci --formatter-enabled=true --organize-imports-enabled=true --reporter=github", "ci:install": "pnpm install --frozen-lockfile", + "ci:build": "pnpm --filter @studiocms/markdown-remark build:ci", "ci:version": "pnpm changeset version", "ci:publish": "pnpm changeset publish", "ci:snapshot": "pnpx pkg-pr-new publish --pnpm './packages/*'" }, "dependencies": { + "@astrojs/check": "^0.9.4", "@biomejs/biome": "^1.9.4", "@changesets/cli": "^2.27.10", "@changesets/config": "^3.0.4", "@changesets/changelog-github": "^0.5.0", + "@types/node": "^18.17.8", + "esbuild": "^0.21.5", "pkg-pr-new": "^0.0.39", - "typescript": "^5.7.2" + "typescript": "^5.7.2", + "vitest": "^2.1.8" } } \ No newline at end of file diff --git a/packages/markdown-remark/package.json b/packages/markdown-remark/package.json new file mode 100644 index 0000000..11fea50 --- /dev/null +++ b/packages/markdown-remark/package.json @@ -0,0 +1,69 @@ +{ + "name": "@studiocms/markdown-remark", + "version": "0.0.1", + "type": "module", + "author": "studiocms", + "license": "MIT", + "repository": { + "type": "git", + "url": "git+https://github.com/withstudiocms/markdown-remark.git", + "directory": "packages/markdown-remark" + }, + "bugs": "https://github.com/withstudiocms/markdown-remark/issues", + "homepage": "https://studiocms.dev", + "main": "./dist/index.js", + "exports": { + ".": "./dist/index.js" + }, + "imports": { + "#import-plugin": { + "browser": "./dist/import-plugin-browser.js", + "default": "./dist/import-plugin-default.js" + } + }, + "files": [ + "dist" + ], + "scripts": { + "prepublish": "pnpm build", + "build": "run-scripts build \"src/**/*.ts\" && tsc -p tsconfig.json", + "build:ci": "run-scripts build \"src/**/*.ts\"", + "dev": "run-scripts dev \"src/**/*.ts\"" + }, + "dependencies": { + "@astrojs/prism": "^3.2.0", + "github-slugger": "^2.0.0", + "hast-util-from-html": "^2.0.3", + "hast-util-to-text": "^4.0.2", + "import-meta-resolve": "^4.1.0", + "js-yaml": "^4.1.0", + "mdast-util-definitions": "^6.0.0", + "rehype-raw": "^7.0.0", + "rehype-stringify": "^10.0.1", + "remark-gfm": "^4.0.0", + "remark-parse": "^11.0.0", + "remark-rehype": "^11.1.1", + "remark-smartypants": "^3.0.2", + "shiki": "^1.23.1", + "unified": "^11.0.5", + "unist-util-remove-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "unist-util-visit-parents": "^6.0.1", + "vfile": "^6.0.3", + "vitest": "^2.1.8" + }, + "devDependencies": { + "@types/estree": "^1.0.6", + "@types/hast": "^3.0.4", + "@types/js-yaml": "^4.0.9", + "@types/mdast": "^4.0.4", + "@types/unist": "^3.0.3", + "run-scripts": "workspace:*", + "esbuild": "^0.21.5", + "fast-glob": "^3.3.2", + "mdast-util-mdx-expression": "^2.0.1" + }, + "publishConfig": { + "provenance": true + } + } \ No newline at end of file diff --git a/packages/markdown-remark/src/HTMLString.ts b/packages/markdown-remark/src/HTMLString.ts new file mode 100644 index 0000000..a4d7c67 --- /dev/null +++ b/packages/markdown-remark/src/HTMLString.ts @@ -0,0 +1,5 @@ +export class HTMLString extends String { + get [Symbol.toStringTag]() { + return 'HTMLString'; + } +} diff --git a/packages/markdown-remark/src/frontmatter.ts b/packages/markdown-remark/src/frontmatter.ts new file mode 100644 index 0000000..5542a4e --- /dev/null +++ b/packages/markdown-remark/src/frontmatter.ts @@ -0,0 +1,81 @@ +import yaml from 'js-yaml'; + +// biome-ignore lint/suspicious/noExplicitAny: +export function isFrontmatterValid(frontmatter: Record) { + try { + // ensure frontmatter is JSON-serializable + JSON.stringify(frontmatter); + } catch { + return false; + } + return typeof frontmatter === 'object' && frontmatter !== null; +} + +// Capture frontmatter wrapped with `---`, including any characters and new lines within it. +// Only capture if `---` exists near the top of the file, including: +// 1. Start of file (including if has BOM encoding) +// 2. Start of file with any whitespace (but `---` must still start on a new line) +const frontmatterRE = /(?:^\uFEFF?|^\s*\n)---([\s\S]*?\n)---/; +export function extractFrontmatter(code: string): string | undefined { + return frontmatterRE.exec(code)?.[1]; +} + +export interface ParseFrontmatterOptions { + /** + * How the frontmatter should be handled in the returned `content` string. + * - `preserve`: Keep the frontmatter. + * - `remove`: Remove the frontmatter. + * - `empty-with-spaces`: Replace the frontmatter with empty spaces. (preserves sourcemap line/col/offset) + * - `empty-with-lines`: Replace the frontmatter with empty line breaks. (preserves sourcemap line/col) + * + * @default 'remove' + */ + frontmatter: 'preserve' | 'remove' | 'empty-with-spaces' | 'empty-with-lines'; +} + +export interface ParseFrontmatterResult { + // biome-ignore lint/suspicious/noExplicitAny: + frontmatter: Record; + rawFrontmatter: string; + content: string; +} + +export function parseFrontmatter( + code: string, + options?: ParseFrontmatterOptions +): ParseFrontmatterResult { + const rawFrontmatter = extractFrontmatter(code); + + if (rawFrontmatter == null) { + return { frontmatter: {}, rawFrontmatter: '', content: code }; + } + + const parsed = yaml.load(rawFrontmatter); + // biome-ignore lint/suspicious/noExplicitAny: + const frontmatter = (parsed && typeof parsed === 'object' ? parsed : {}) as Record; + + let content: string; + switch (options?.frontmatter ?? 'remove') { + case 'preserve': + content = code; + break; + case 'remove': + content = code.replace(`---${rawFrontmatter}---`, ''); + break; + case 'empty-with-spaces': + content = code.replace( + `---${rawFrontmatter}---`, + ` ${rawFrontmatter.replace(/[^\r\n]/g, ' ')} ` + ); + break; + case 'empty-with-lines': + content = code.replace(`---${rawFrontmatter}---`, rawFrontmatter.replace(/[^\r\n]/g, '')); + break; + } + + return { + frontmatter, + rawFrontmatter, + content, + }; +} diff --git a/packages/markdown-remark/src/highlight.ts b/packages/markdown-remark/src/highlight.ts new file mode 100644 index 0000000..09df6e8 --- /dev/null +++ b/packages/markdown-remark/src/highlight.ts @@ -0,0 +1,98 @@ +import type { Element, Parent, Root } from 'hast'; +import { fromHtml } from 'hast-util-from-html'; +import { toText } from 'hast-util-to-text'; +import { removePosition } from 'unist-util-remove-position'; +import { visitParents } from 'unist-util-visit-parents'; + +type Highlighter = ( + code: string, + language: string, + options?: { meta?: string } +) => Promise; + +const languagePattern = /\blanguage-(\S+)\b/; + +/** + * A hast utility to syntax highlight code blocks with a given syntax highlighter. + * + * @param tree + * The hast tree in which to syntax highlight code blocks. + * @param highlighter + * A function which receives the code and language, and returns the HTML of a syntax + * highlighted `
` element.
+ */
+export async function highlightCodeBlocks(tree: Root, highlighter: Highlighter) {
+	const nodes: Array<{
+		node: Element;
+		language: string;
+		parent: Element;
+		grandParent: Parent;
+	}> = [];
+
+	// We’re looking for `` elements
+	visitParents(tree, { type: 'element', tagName: 'code' }, (node, ancestors) => {
+		const parent = ancestors.at(-1);
+
+		// Whose parent is a `
`.
+		if (parent?.type !== 'element' || parent.tagName !== 'pre') {
+			return;
+		}
+
+		// Where the `` is the only child.
+		if (parent.children.length !== 1) {
+			return;
+		}
+
+		// And the `` has a class name that starts with `language-`.
+		let languageMatch: RegExpMatchArray | null | undefined;
+		const { className } = node.properties;
+		if (typeof className === 'string') {
+			languageMatch = languagePattern.exec(className);
+		} else if (Array.isArray(className)) {
+			for (const cls of className) {
+				if (typeof cls !== 'string') {
+					continue;
+				}
+
+				languageMatch = languagePattern.exec(cls);
+				if (languageMatch) {
+					break;
+				}
+			}
+		}
+
+		// Don’t Highlight math code blocks.
+		if (languageMatch?.[1] === 'math') {
+			return;
+		}
+
+		nodes.push({
+			node,
+			language: languageMatch?.[1] || 'plaintext',
+			parent,
+			// biome-ignore lint/style/noNonNullAssertion: 
+			grandParent: ancestors.at(-2)!,
+		});
+	});
+
+	for (const { node, language, grandParent, parent } of nodes) {
+		// biome-ignore lint/suspicious/noExplicitAny: 
+		const meta = (node.data as any)?.meta ?? node.properties.metastring ?? undefined;
+		const code = toText(node, { whitespace: 'pre' });
+		const result = await highlighter(code, language, { meta });
+
+		let replacement: Element;
+		if (typeof result === 'string') {
+			// The replacement returns a root node with 1 child, the `
` element replacement.
+			replacement = fromHtml(result, { fragment: true }).children[0] as Element;
+			// We just generated this node, so any positional information is invalid.
+			removePosition(replacement);
+		} else {
+			replacement = result.children[0] as Element;
+		}
+
+		// We replace the parent in its parent with the new `
` element.
+		const index = grandParent.children.indexOf(parent);
+		grandParent.children[index] = replacement;
+	}
+}
diff --git a/packages/markdown-remark/src/import-plugin-browser.ts b/packages/markdown-remark/src/import-plugin-browser.ts
new file mode 100644
index 0000000..da81a38
--- /dev/null
+++ b/packages/markdown-remark/src/import-plugin-browser.ts
@@ -0,0 +1,8 @@
+// This file should be imported as `#import-plugin`
+import type * as unified from 'unified';
+
+// In the browser, we can try to do a plain import
+export async function importPlugin(p: string): Promise {
+	const importResult = await import(p);
+	return importResult.default;
+}
\ No newline at end of file
diff --git a/packages/markdown-remark/src/import-plugin-default.ts b/packages/markdown-remark/src/import-plugin-default.ts
new file mode 100644
index 0000000..da8038e
--- /dev/null
+++ b/packages/markdown-remark/src/import-plugin-default.ts
@@ -0,0 +1,22 @@
+import path from 'node:path';
+import { pathToFileURL } from 'node:url';
+// This file should be imported as `#import-plugin`
+import { resolve as importMetaResolve } from 'import-meta-resolve';
+import type * as unified from 'unified';
+
+let cwdUrlStr: string | undefined;
+
+// In non-browser environments, we can try to resolve from the filesystem too
+export async function importPlugin(p: string): Promise {
+	// Try import from this package first
+	try {
+		const importResult = await import(p);
+		return importResult.default;
+	} catch {}
+
+	// Try import from user project
+	cwdUrlStr ??= pathToFileURL(path.join(process.cwd(), 'package.json')).toString();
+	const resolved = importMetaResolve(p, cwdUrlStr);
+	const importResult = await import(resolved);
+	return importResult.default;
+}
\ No newline at end of file
diff --git a/packages/markdown-remark/src/index.ts b/packages/markdown-remark/src/index.ts
new file mode 100644
index 0000000..d88117a
--- /dev/null
+++ b/packages/markdown-remark/src/index.ts
@@ -0,0 +1,176 @@
+import { HTMLString } from './HTMLString.js';
+import type { AstroMarkdownOptions, MarkdownProcessor } from './types.js';
+
+import { loadPlugins } from './load-plugins.js';
+import { rehypeHeadingIds } from './rehype-collect-headings.js';
+import { rehypePrism } from './rehype-prism.js';
+import { rehypeShiki } from './rehype-shiki.js';
+import { remarkCollectImages } from './remark-collect-images.js';
+
+import rehypeRaw from 'rehype-raw';
+import rehypeStringify from 'rehype-stringify';
+import remarkGfm from 'remark-gfm';
+import remarkParse from 'remark-parse';
+import remarkRehype from 'remark-rehype';
+import remarkSmartypants from 'remark-smartypants';
+import { unified } from 'unified';
+import { VFile } from 'vfile';
+import { rehypeImages } from './rehype-images.js';
+
+export { rehypeHeadingIds } from './rehype-collect-headings.js';
+export { remarkCollectImages } from './remark-collect-images.js';
+export { rehypePrism } from './rehype-prism.js';
+export { rehypeShiki } from './rehype-shiki.js';
+export {
+	isFrontmatterValid,
+	extractFrontmatter,
+	parseFrontmatter,
+	type ParseFrontmatterOptions,
+	type ParseFrontmatterResult,
+} from './frontmatter.js';
+export {
+	createShikiHighlighter,
+	type ShikiHighlighter,
+	type CreateShikiHighlighterOptions,
+	type ShikiHighlighterHighlightOptions,
+} from './shiki.js';
+export * from './types.js';
+
+export const markdownConfigDefaults: Required = {
+	syntaxHighlight: 'shiki',
+	shikiConfig: {
+		langs: [],
+		theme: 'github-dark',
+		themes: {},
+		wrap: false,
+		transformers: [],
+		langAlias: {},
+	},
+	remarkPlugins: [],
+	rehypePlugins: [],
+	remarkRehype: {},
+	gfm: true,
+	smartypants: true,
+};
+
+/**
+ * Create a markdown preprocessor to render multiple markdown files
+ */
+export async function createMarkdownProcessor(
+	opts?: AstroMarkdownOptions
+): Promise {
+	const {
+		syntaxHighlight = markdownConfigDefaults.syntaxHighlight,
+		shikiConfig = markdownConfigDefaults.shikiConfig,
+		remarkPlugins = markdownConfigDefaults.remarkPlugins,
+		rehypePlugins = markdownConfigDefaults.rehypePlugins,
+		remarkRehype: remarkRehypeOptions = markdownConfigDefaults.remarkRehype,
+		gfm = markdownConfigDefaults.gfm,
+		smartypants = markdownConfigDefaults.smartypants,
+	} = opts ?? {};
+
+	const loadedRemarkPlugins = await Promise.all(loadPlugins(remarkPlugins));
+	const loadedRehypePlugins = await Promise.all(loadPlugins(rehypePlugins));
+
+	const parser = unified().use(remarkParse);
+
+	// gfm and smartypants
+	if (gfm) {
+		parser.use(remarkGfm);
+	}
+	if (smartypants) {
+		parser.use(remarkSmartypants);
+	}
+
+	// User remark plugins
+	for (const [plugin, pluginOpts] of loadedRemarkPlugins) {
+		parser.use(plugin, pluginOpts);
+	}
+
+	// Apply later in case user plugins resolve relative image paths
+	parser.use(remarkCollectImages);
+
+	// Remark -> Rehype
+	parser.use(remarkRehype, {
+		allowDangerousHtml: true,
+		passThrough: [],
+		...remarkRehypeOptions,
+	});
+
+	// Syntax highlighting
+	if (syntaxHighlight === 'shiki') {
+		parser.use(rehypeShiki, shikiConfig);
+	} else if (syntaxHighlight === 'prism') {
+		parser.use(rehypePrism);
+	}
+
+	// User rehype plugins
+	for (const [plugin, pluginOpts] of loadedRehypePlugins) {
+		parser.use(plugin, pluginOpts);
+	}
+
+	// Images / Assets support
+	parser.use(rehypeImages());
+
+	// Headings
+	parser.use(rehypeHeadingIds);
+
+	// Stringify to HTML
+	parser.use(rehypeRaw).use(rehypeStringify, { allowDangerousHtml: true });
+
+	return {
+		async render(content, renderOpts) {
+			const vfile = new VFile({
+				value: content,
+				path: renderOpts?.fileURL,
+				data: {
+					astro: {
+						frontmatter: renderOpts?.frontmatter ?? {},
+					},
+				},
+			});
+
+			const result = await parser.process(vfile).catch((err) => {
+				// Ensure that the error message contains the input filename
+				// to make it easier for the user to fix the issue
+				err = prefixError(err, `Failed to parse Markdown file "${vfile.path}"`);
+				console.error(err);
+				throw err;
+			});
+
+			return {
+				raw: String(result.value),
+				html: new HTMLString(result.value),
+				metadata: {
+					headings: result.data.astro?.headings ?? [],
+					imagePaths: result.data.astro?.imagePaths ?? [],
+					frontmatter: result.data.astro?.frontmatter ?? {},
+				},
+			};
+		},
+	};
+}
+
+// biome-ignore lint/suspicious/noExplicitAny: 
+function prefixError(err: any, prefix: string) {
+	// If the error is an object with a `message` property, attempt to prefix the message
+	if (err?.message) {
+		try {
+			err.message = `${prefix}:\n${err.message}`;
+			return err;
+		} catch {
+			// Any errors here are ok, there's fallback code below
+		}
+	}
+
+	// If that failed, create a new error with the desired message and attempt to keep the stack
+	const wrappedError = new Error(`${prefix}${err ? `: ${err}` : ''}`);
+	try {
+		wrappedError.stack = err.stack;
+		wrappedError.cause = err;
+	} catch {
+		// It's ok if we could not set the stack or cause - the message is the most important part
+	}
+
+	return wrappedError;
+}
diff --git a/packages/markdown-remark/src/load-plugins.ts b/packages/markdown-remark/src/load-plugins.ts
new file mode 100644
index 0000000..8bedc2f
--- /dev/null
+++ b/packages/markdown-remark/src/load-plugins.ts
@@ -0,0 +1,38 @@
+import type * as unified from 'unified';
+import { importPlugin as _importPlugin } from '#import-plugin';
+
+// biome-ignore lint/suspicious/noExplicitAny: 
+async function importPlugin(p: string | unified.Plugin) {
+	if (typeof p === 'string') {
+		return await _importPlugin(p);
+	}
+	return p;
+}
+
+export function loadPlugins(
+	items: (
+		| string
+		// biome-ignore lint/suspicious/noExplicitAny: 
+		| [string, any]
+		// biome-ignore lint/suspicious/noExplicitAny: 
+		| unified.Plugin
+		// biome-ignore lint/suspicious/noExplicitAny: 
+		| [unified.Plugin, any]
+	)[]
+	// biome-ignore lint/suspicious/noExplicitAny: 
+): Promise<[unified.Plugin, any?]>[] {
+	return items.map((p) => {
+		return new Promise((resolve, reject) => {
+			if (Array.isArray(p)) {
+				const [plugin, opts] = p;
+				return importPlugin(plugin)
+					.then((m) => resolve([m, opts]))
+					.catch((e) => reject(e));
+			}
+
+			return importPlugin(p)
+				.then((m) => resolve([m]))
+				.catch((e) => reject(e));
+		});
+	});
+}
diff --git a/packages/markdown-remark/src/rehype-collect-headings.ts b/packages/markdown-remark/src/rehype-collect-headings.ts
new file mode 100644
index 0000000..86797a3
--- /dev/null
+++ b/packages/markdown-remark/src/rehype-collect-headings.ts
@@ -0,0 +1,130 @@
+import type { Expression, Super } from 'estree';
+import Slugger from 'github-slugger';
+import type { MdxTextExpression } from 'mdast-util-mdx-expression';
+import type { Node } from 'unist';
+import { visit } from 'unist-util-visit';
+import type { VFile } from 'vfile';
+import type { MarkdownHeading, RehypePlugin } from './types.js';
+
+const rawNodeTypes = new Set(['text', 'raw', 'mdxTextExpression']);
+const codeTagNames = new Set(['code', 'pre']);
+
+export function rehypeHeadingIds(): ReturnType {
+	return (tree, file) => {
+		const headings: MarkdownHeading[] = [];
+		const frontmatter = file.data.astro?.frontmatter;
+		const slugger = new Slugger();
+		const isMDX = isMDXFile(file);
+		visit(tree, (node) => {
+			if (node.type !== 'element') return;
+			const { tagName } = node;
+			if (tagName[0] !== 'h') return;
+			const [, level] = /h([0-6])/.exec(tagName) ?? [];
+			if (!level) return;
+			const depth = Number.parseInt(level);
+
+			let text = '';
+			visit(node, (child, __, parent) => {
+				if (child.type === 'element' || parent == null) {
+					return;
+				}
+				if (child.type === 'raw') {
+					if (/^\n?<.*>\n?$/.test(child.value)) {
+						return;
+					}
+				}
+				if (rawNodeTypes.has(child.type)) {
+					if (isMDX || codeTagNames.has(parent.tagName)) {
+						let value = child.value;
+						if (isMdxTextExpression(child) && frontmatter) {
+							const frontmatterPath = getMdxFrontmatterVariablePath(child);
+							if (Array.isArray(frontmatterPath) && frontmatterPath.length > 0) {
+								const frontmatterValue = getMdxFrontmatterVariableValue(
+									frontmatter,
+									frontmatterPath
+								);
+								if (typeof frontmatterValue === 'string') {
+									value = frontmatterValue;
+								}
+							}
+						}
+						text += value;
+					} else {
+						text += child.value.replace(/\{/g, '${');
+					}
+				}
+			});
+
+			node.properties = node.properties || {};
+			if (typeof node.properties.id !== 'string') {
+				let slug = slugger.slug(text);
+
+				if (slug.endsWith('-')) slug = slug.slice(0, -1);
+
+				node.properties.id = slug;
+			}
+
+			headings.push({ depth, slug: node.properties.id, text });
+		});
+
+		file.data.astro ??= {};
+		file.data.astro.headings = headings;
+	};
+}
+
+function isMDXFile(file: VFile) {
+	return Boolean(file.history[0]?.endsWith('.mdx'));
+}
+
+/**
+ * Check if an ESTree entry is `frontmatter.*.VARIABLE`.
+ * If it is, return the variable path (i.e. `["*", ..., "VARIABLE"]`) minus the `frontmatter` prefix.
+ */
+function getMdxFrontmatterVariablePath(node: MdxTextExpression): string[] | Error {
+	if (!node.data?.estree || node.data.estree.body.length !== 1) return new Error();
+
+	const statement = node.data.estree.body[0];
+
+	// Check for "[ANYTHING].[ANYTHING]".
+	if (statement?.type !== 'ExpressionStatement' || statement.expression.type !== 'MemberExpression')
+		return new Error();
+
+	let expression: Expression | Super = statement.expression;
+	const expressionPath: string[] = [];
+
+	// Traverse the expression, collecting the variable path.
+	while (
+		expression.type === 'MemberExpression' &&
+		expression.property.type === (expression.computed ? 'Literal' : 'Identifier')
+	) {
+		expressionPath.push(
+			expression.property.type === 'Literal'
+				? String(expression.property.value)
+				: expression.property.name
+		);
+
+		expression = expression.object;
+	}
+
+	// Check for "frontmatter.[ANYTHING]".
+	if (expression.type !== 'Identifier' || expression.name !== 'frontmatter') return new Error();
+
+	return expressionPath.reverse();
+}
+
+// biome-ignore lint/suspicious/noExplicitAny: 
+function getMdxFrontmatterVariableValue(frontmatter: Record, path: string[]) {
+	let value = frontmatter;
+
+	for (const key of path) {
+		if (!value[key]) return undefined;
+
+		value = value[key];
+	}
+
+	return value;
+}
+
+function isMdxTextExpression(node: Node): node is MdxTextExpression {
+	return node.type === 'mdxTextExpression';
+}
diff --git a/packages/markdown-remark/src/rehype-images.ts b/packages/markdown-remark/src/rehype-images.ts
new file mode 100644
index 0000000..71067f2
--- /dev/null
+++ b/packages/markdown-remark/src/rehype-images.ts
@@ -0,0 +1,33 @@
+import { visit } from 'unist-util-visit';
+import type { VFile } from 'vfile';
+
+export function rehypeImages() {
+	return () =>
+		// biome-ignore lint/suspicious/noExplicitAny: 
+		(tree: any, file: VFile) => {
+			const imageOccurrenceMap = new Map();
+
+			visit(tree, (node) => {
+				if (node.type !== 'element') return;
+				if (node.tagName !== 'img') return;
+
+				if (node.properties?.src) {
+					node.properties.src = decodeURI(node.properties.src);
+
+					if (file.data.astro?.imagePaths?.includes(node.properties.src)) {
+						const { ...props } = node.properties;
+
+						// Initialize or increment occurrence count for this image
+						const index = imageOccurrenceMap.get(node.properties.src) || 0;
+						imageOccurrenceMap.set(node.properties.src, index + 1);
+
+						node.properties.__ASTRO_IMAGE_ = JSON.stringify({ ...props, index });
+
+						for (const prop in Object.keys(props)) {
+							delete node.properties[prop];
+						}
+					}
+				}
+			});
+		};
+}
diff --git a/packages/markdown-remark/src/rehype-prism.ts b/packages/markdown-remark/src/rehype-prism.ts
new file mode 100644
index 0000000..db5a3db
--- /dev/null
+++ b/packages/markdown-remark/src/rehype-prism.ts
@@ -0,0 +1,16 @@
+import { runHighlighterWithAstro } from '@astrojs/prism/dist/highlighter';
+import type { Root } from 'hast';
+import type { Plugin } from 'unified';
+import { highlightCodeBlocks } from './highlight.js';
+
+export const rehypePrism: Plugin<[], Root> = () => {
+	return async (tree) => {
+		await highlightCodeBlocks(tree, (code, language) => {
+			const { html, classLanguage } = runHighlighterWithAstro(language, code);
+
+			return Promise.resolve(
+				`
${html}
` + ); + }); + }; +}; diff --git a/packages/markdown-remark/src/rehype-shiki.ts b/packages/markdown-remark/src/rehype-shiki.ts new file mode 100644 index 0000000..39b1cdc --- /dev/null +++ b/packages/markdown-remark/src/rehype-shiki.ts @@ -0,0 +1,28 @@ +import type { Root } from 'hast'; +import type { Plugin } from 'unified'; +import { highlightCodeBlocks } from './highlight.js'; +import { type ShikiHighlighter, createShikiHighlighter } from './shiki.js'; +import type { ShikiConfig } from './types.js'; + +export const rehypeShiki: Plugin<[ShikiConfig?], Root> = (config) => { + let highlighterAsync: Promise | undefined; + + return async (tree) => { + highlighterAsync ??= createShikiHighlighter({ + langs: config?.langs, + theme: config?.theme, + themes: config?.themes, + langAlias: config?.langAlias, + }); + const highlighter = await highlighterAsync; + + await highlightCodeBlocks(tree, (code, language, options) => { + return highlighter.codeToHast(code, language, { + meta: options?.meta, + wrap: config?.wrap, + defaultColor: config?.defaultColor, + transformers: config?.transformers, + }); + }); + }; +}; \ No newline at end of file diff --git a/packages/markdown-remark/src/remark-collect-images.ts b/packages/markdown-remark/src/remark-collect-images.ts new file mode 100644 index 0000000..5a86b38 --- /dev/null +++ b/packages/markdown-remark/src/remark-collect-images.ts @@ -0,0 +1,43 @@ +import type { Image, ImageReference } from 'mdast'; +import { definitions } from 'mdast-util-definitions'; +import { visit } from 'unist-util-visit'; +import type { VFile } from 'vfile'; + +export function remarkCollectImages() { + // biome-ignore lint/suspicious/noExplicitAny: + return (tree: any, vfile: VFile) => { + if (typeof vfile?.path !== 'string') return; + + const definition = definitions(tree); + const imagePaths = new Set(); + visit(tree, ['image', 'imageReference'], (node: Image | ImageReference) => { + if (node.type === 'image') { + if (shouldOptimizeImage(node.url)) imagePaths.add(decodeURI(node.url)); + } + if (node.type === 'imageReference') { + const imageDefinition = definition(node.identifier); + if (imageDefinition) { + if (shouldOptimizeImage(imageDefinition.url)) + imagePaths.add(decodeURI(imageDefinition.url)); + } + } + }); + + vfile.data.astro ??= {}; + vfile.data.astro.imagePaths = Array.from(imagePaths); + }; +} + +function shouldOptimizeImage(src: string) { + // Optimize anything that is NOT external or an absolute path to `public/` + return !isValidUrl(src) && !src.startsWith('/'); +} + +function isValidUrl(str: string): boolean { + try { + new URL(str); + return true; + } catch { + return false; + } +} diff --git a/packages/markdown-remark/src/shiki.ts b/packages/markdown-remark/src/shiki.ts new file mode 100644 index 0000000..00b69ab --- /dev/null +++ b/packages/markdown-remark/src/shiki.ts @@ -0,0 +1,203 @@ +import type { Properties, Root } from 'hast'; +import { + type BundledLanguage, + type HighlighterCoreOptions, + type LanguageRegistration, + type ShikiTransformer, + type ThemeRegistration, + type ThemeRegistrationRaw, + createCssVariablesTheme, + createHighlighter, + isSpecialLang, +} from 'shiki'; +import type { ThemePresets } from './types.js'; + +export interface ShikiHighlighter { + codeToHast( + code: string, + lang?: string, + options?: ShikiHighlighterHighlightOptions + ): Promise; + codeToHtml( + code: string, + lang?: string, + options?: ShikiHighlighterHighlightOptions + ): Promise; +} + +export interface CreateShikiHighlighterOptions { + langs?: LanguageRegistration[]; + theme?: ThemePresets | ThemeRegistration | ThemeRegistrationRaw; + themes?: Record; + langAlias?: HighlighterCoreOptions['langAlias']; +} + +export interface ShikiHighlighterHighlightOptions { + /** + * Generate inline code element only, without the pre element wrapper. + */ + inline?: boolean; + /** + * Enable word wrapping. + * - true: enabled. + * - false: disabled. + * - null: All overflow styling removed. Code will overflow the element by default. + */ + wrap?: boolean | null; + /** + * Chooses a theme from the "themes" option that you've defined as the default styling theme. + */ + defaultColor?: 'light' | 'dark' | string | false; + /** + * Shiki transformers to customize the generated HTML by manipulating the hast tree. + */ + transformers?: ShikiTransformer[]; + /** + * Additional attributes to be added to the root code block element. + */ + attributes?: Record; + /** + * Raw `meta` information to be used by Shiki transformers. + */ + meta?: string; +} + +let _cssVariablesTheme: ReturnType; +const cssVariablesTheme = () => + _cssVariablesTheme ?? + // biome-ignore lint/suspicious/noAssignInExpressions: + (_cssVariablesTheme = createCssVariablesTheme({ + variablePrefix: '--astro-code-', + })); + +export async function createShikiHighlighter({ + langs = [], + theme = 'github-dark', + themes = {}, + langAlias = {}, +}: CreateShikiHighlighterOptions = {}): Promise { + theme = theme === 'css-variables' ? cssVariablesTheme() : theme; + + const highlighter = await createHighlighter({ + langs: ['plaintext', ...langs], + langAlias, + themes: Object.values(themes).length ? Object.values(themes) : [theme], + }); + + async function highlight( + code: string, + // biome-ignore lint/style/useDefaultParameterLast: + lang = 'plaintext', + options: ShikiHighlighterHighlightOptions, + to: 'hast' | 'html' + ) { + const resolvedLang = langAlias[lang] ?? lang; + const loadedLanguages = highlighter.getLoadedLanguages(); + + if (!isSpecialLang(lang) && !loadedLanguages.includes(resolvedLang)) { + try { + await highlighter.loadLanguage(resolvedLang as BundledLanguage); + } catch (_err) { + const langStr = + lang === resolvedLang ? `"${lang}"` : `"${lang}" (aliased to "${resolvedLang}")`; + console.warn(`[Shiki] The language ${langStr} doesn't exist, falling back to "plaintext".`); + lang = 'plaintext'; + } + } + + code = code.replace(/(?:\r\n|\r|\n)$/, ''); + + const themeOptions = Object.values(themes).length ? { themes } : { theme }; + const inline = options?.inline ?? false; + + return highlighter[to === 'html' ? 'codeToHtml' : 'codeToHast'](code, { + ...themeOptions, + defaultColor: options.defaultColor, + lang, + // NOTE: while we can spread `options.attributes` here so that Shiki can auto-serialize this as rendered + // attributes on the top-level tag, it's not clear whether it is fine to pass all attributes as meta, as + // they're technically not meta, nor parsed from Shiki's `parseMetaString` API. + meta: options?.meta ? { __raw: options?.meta } : undefined, + transformers: [ + { + pre(node) { + // Swap to `code` tag if inline + if (inline) { + node.tagName = 'code'; + } + + const { + class: attributesClass, + style: attributesStyle, + ...rest + } = options?.attributes ?? {}; + Object.assign(node.properties, rest); + + const classValue = + (normalizePropAsString(node.properties.class) ?? '') + + (attributesClass ? ` ${attributesClass}` : ''); + const styleValue = + (normalizePropAsString(node.properties.style) ?? '') + + (attributesStyle ? `; ${attributesStyle}` : ''); + + // Replace "shiki" class naming with "astro-code" + node.properties.class = classValue.replace(/shiki/g, 'astro-code'); + + // Add data-language attribute + node.properties.dataLanguage = lang; + + // Handle code wrapping + // if wrap=null, do nothing. + if (options.wrap === false || options.wrap === undefined) { + node.properties.style = `${styleValue}; overflow-x: auto;`; + } else if (options.wrap === true) { + node.properties.style = `${styleValue}; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;`; + } + }, + line(node) { + // Add "user-select: none;" for "+"/"-" diff symbols. + // Transform `+ something + // into `+ something` + if (resolvedLang === 'diff') { + const innerSpanNode = node.children[0]; + const innerSpanTextNode = + innerSpanNode?.type === 'element' && innerSpanNode.children?.[0]; + + if (innerSpanTextNode && innerSpanTextNode.type === 'text') { + const start = innerSpanTextNode.value[0]; + if (start === '+' || start === '-') { + innerSpanTextNode.value = innerSpanTextNode.value.slice(1); + innerSpanNode.children.unshift({ + type: 'element', + tagName: 'span', + properties: { style: 'user-select: none;' }, + children: [{ type: 'text', value: start }], + }); + } + } + } + }, + code(node) { + if (inline) { + return node.children[0] as typeof node; + } + }, + }, + ...(options.transformers ?? []), + ], + }); + } + + return { + codeToHast(code, lang, options = {}) { + return highlight(code, lang || 'plaintext', options, 'hast') as Promise; + }, + codeToHtml(code, lang, options = {}) { + return highlight(code, lang, options, 'html') as Promise; + }, + }; +} + +function normalizePropAsString(value: Properties[string]): string | null { + return Array.isArray(value) ? value.join(' ') : (value as string | null); +} diff --git a/packages/markdown-remark/src/types.ts b/packages/markdown-remark/src/types.ts new file mode 100644 index 0000000..b520270 --- /dev/null +++ b/packages/markdown-remark/src/types.ts @@ -0,0 +1,88 @@ +import type * as hast from 'hast'; +import type * as mdast from 'mdast'; +import type { Options as RemarkRehypeOptions } from 'remark-rehype'; +import type { BuiltinTheme } from 'shiki'; +import type * as unified from 'unified'; +import type { HTMLString } from './HTMLString.js'; +import type { CreateShikiHighlighterOptions, ShikiHighlighterHighlightOptions } from './shiki.js'; + +export type { Node } from 'unist'; + +declare module 'vfile' { + interface DataMap { + astro: { + headings?: MarkdownHeading[]; + imagePaths?: string[]; + // biome-ignore lint/suspicious/noExplicitAny: + frontmatter?: Record; + }; + } +} + +// biome-ignore lint/suspicious/noExplicitAny: +export type RemarkPlugin = unified.Plugin< + PluginParameters, + mdast.Root +>; + +// biome-ignore lint/suspicious/noExplicitAny: +export type RemarkPlugins = (string | [string, any] | RemarkPlugin | [RemarkPlugin, any])[]; + +// biome-ignore lint/suspicious/noExplicitAny: +export type RehypePlugin = unified.Plugin< + PluginParameters, + hast.Root +>; + +// biome-ignore lint/suspicious/noExplicitAny: +export type RehypePlugins = (string | [string, any] | RehypePlugin | [RehypePlugin, any])[]; + +export type RemarkRehype = RemarkRehypeOptions; + +export type ThemePresets = BuiltinTheme | 'css-variables'; + +export interface ShikiConfig + extends Pick, + Pick {} + +export interface AstroMarkdownOptions { + syntaxHighlight?: 'shiki' | 'prism' | false; + shikiConfig?: ShikiConfig; + remarkPlugins?: RemarkPlugins; + rehypePlugins?: RehypePlugins; + remarkRehype?: RemarkRehype; + gfm?: boolean; + smartypants?: boolean; +} + +export interface MarkdownProcessor { + render: ( + content: string, + opts?: MarkdownProcessorRenderOptions + ) => Promise; +} + +export interface MarkdownProcessorRenderOptions { + /** @internal */ + fileURL?: URL; + /** Used for frontmatter injection plugins */ + // biome-ignore lint/suspicious/noExplicitAny: + frontmatter?: Record; +} + +export interface MarkdownProcessorRenderResult { + raw: string; + html: HTMLString; + metadata: { + headings: MarkdownHeading[]; + imagePaths: string[]; + // biome-ignore lint/suspicious/noExplicitAny: + frontmatter: Record; + }; +} + +export interface MarkdownHeading { + depth: number; + slug: string; + text: string; +} diff --git a/packages/markdown-remark/test/autolinking.test.ts b/packages/markdown-remark/test/autolinking.test.ts new file mode 100644 index 0000000..de30be3 --- /dev/null +++ b/packages/markdown-remark/test/autolinking.test.ts @@ -0,0 +1,39 @@ +import { beforeAll, describe, expect, test } from 'vitest'; +import { type MarkdownProcessor, createMarkdownProcessor } from '../dist/index.js'; + +describe('autolinking', () => { + describe('plain md', () => { + let processor: MarkdownProcessor; + + beforeAll(async () => { + processor = await createMarkdownProcessor(); + }); + + test('autolinks URLs starting with a protocol in plain text', async () => { + const markdown = 'See https://example.com for more.'; + const { raw } = await processor.render(markdown); + + expect(raw.replace(/\n/g, '')).toBe( + `

See https://example.com for more.

` + ); + }); + + test('autolinks URLs starting with "www." in plain text', async () => { + const markdown = 'See www.example.com for more.'; + const { raw } = await processor.render(markdown); + + expect(raw.trim()).toBe( + `

See www.example.com for more.

` + ); + }); + + test('does not autolink URLs in code blocks', async () => { + const markdown = 'See `https://example.com` or `www.example.com` for more.'; + const { raw } = await processor.render(markdown); + + expect(raw.trim()).toBe( + '

See https://example.com or www.example.com for more.

' + ); + }); + }); +}); diff --git a/packages/markdown-remark/test/browser.test.ts b/packages/markdown-remark/test/browser.test.ts new file mode 100644 index 0000000..a0525f2 --- /dev/null +++ b/packages/markdown-remark/test/browser.test.ts @@ -0,0 +1,53 @@ +import esbuild from 'esbuild'; +import glob from 'fast-glob'; +import { describe, expect, test } from 'vitest'; + +const patterns = ['packages/markdown-remark/dist/**/*.js']; + +async function getEntryPoints(patterns: string[]): Promise { + try { + const entryPoints = ([] as string[]).concat( + ...(await Promise.all( + patterns.map((pattern) => glob(pattern, { absolute: true, onlyFiles: true })) + )) + ); + const defaultPlugin = entryPoints.findIndex((entry) => + entry.includes('import-plugin-default.js') + ); + const defaultPluginDTS = entryPoints.findIndex((entry) => + entry.includes('import-plugin-default.d.ts') + ); + + if (defaultPlugin >= 0) { + entryPoints.splice(defaultPlugin, 1); + } + + if (defaultPluginDTS >= 0) { + entryPoints.splice(defaultPluginDTS, 1); + } + return entryPoints; + } catch (error) { + console.error('Error fetching entry points:', error); + return []; + } +} + +describe('Bundle for browsers', () => { + test('esbuild browser build should work', async () => { + try { + const entryPoints = await getEntryPoints(patterns); + const result = await esbuild.build({ + platform: 'browser', + entryPoints: entryPoints, + bundle: true, + write: false, + outdir: 'browser-dist', + }); + + expect(result.outputFiles?.length).toBeGreaterThan(0); + } catch (error) { + // Capture any esbuild errors and fail the test + throw new Error(error.message); + } + }); +}); diff --git a/packages/markdown-remark/test/entities.test.ts b/packages/markdown-remark/test/entities.test.ts new file mode 100644 index 0000000..a92595d --- /dev/null +++ b/packages/markdown-remark/test/entities.test.ts @@ -0,0 +1,17 @@ +import { beforeAll, describe, expect, it } from 'vitest'; +import { type MarkdownProcessor, createMarkdownProcessor } from '../dist/index.js'; + +describe('entities', () => { + let processor: MarkdownProcessor; + + beforeAll(async () => { + processor = await createMarkdownProcessor(); + }); + + it('should not unescape entities in regular Markdown', async () => { + const markdown = '<i>This should NOT be italic</i>'; + const { raw } = await processor.render(markdown); + + expect(raw).toBe('

<i>This should NOT be italic</i>

'); + }); +}); diff --git a/packages/markdown-remark/test/frontmatter.test.ts b/packages/markdown-remark/test/frontmatter.test.ts new file mode 100644 index 0000000..a16e94d --- /dev/null +++ b/packages/markdown-remark/test/frontmatter.test.ts @@ -0,0 +1,102 @@ +import { describe, expect, it } from 'vitest'; +import { extractFrontmatter, parseFrontmatter } from '../dist/index.js'; + +const bom = '\uFEFF'; + +describe('extractFrontmatter', () => { + it('works', () => { + const yaml = '\nfoo: bar\n'; + + expect(extractFrontmatter(`---${yaml}---`)).toBe(yaml); + expect(extractFrontmatter(`${bom}---${yaml}---`)).toBe(yaml); + expect(extractFrontmatter(`\n---${yaml}---`)).toBe(yaml); + expect(extractFrontmatter(`\n \n---${yaml}---`)).toBe(yaml); + expect(extractFrontmatter(`---${yaml}---\ncontent`)).toBe(yaml); + expect(extractFrontmatter(`${bom}---${yaml}---\ncontent`)).toBe(yaml); + expect(extractFrontmatter(`\n\n---${yaml}---\n\ncontent`)).toBe(yaml); + expect(extractFrontmatter(`\n \n---${yaml}---\n\ncontent`)).toBe(yaml); + expect(extractFrontmatter(` ---${yaml}---`)).toBeUndefined(); + expect(extractFrontmatter(`---${yaml} ---`)).toBeUndefined(); + expect(extractFrontmatter(`text\n---${yaml}---\n\ncontent`)).toBeUndefined(); + }); +}); + +describe('parseFrontmatter', () => { + it('works', () => { + const yaml = '\nfoo: bar\n'; + + expect(parseFrontmatter(`---${yaml}---`)).toEqual({ + frontmatter: { foo: 'bar' }, + rawFrontmatter: yaml, + content: '', + }); + expect(parseFrontmatter(`${bom}---${yaml}---`)).toEqual({ + frontmatter: { foo: 'bar' }, + rawFrontmatter: yaml, + content: bom, + }); + expect(parseFrontmatter(`\n---${yaml}---`)).toEqual({ + frontmatter: { foo: 'bar' }, + rawFrontmatter: yaml, + content: '\n', + }); + expect(parseFrontmatter(`\n \n---${yaml}---`)).toEqual({ + frontmatter: { foo: 'bar' }, + rawFrontmatter: yaml, + content: '\n \n', + }); + expect(parseFrontmatter(`---${yaml}---\ncontent`)).toEqual({ + frontmatter: { foo: 'bar' }, + rawFrontmatter: yaml, + content: '\ncontent', + }); + expect(parseFrontmatter(`${bom}---${yaml}---\ncontent`)).toEqual({ + frontmatter: { foo: 'bar' }, + rawFrontmatter: yaml, + content: `${bom}\ncontent`, + }); + expect(parseFrontmatter(`\n\n---${yaml}---\n\ncontent`)).toEqual({ + frontmatter: { foo: 'bar' }, + rawFrontmatter: yaml, + content: '\n\n\n\ncontent', + }); + expect(parseFrontmatter(`\n \n---${yaml}---\n\ncontent`)).toEqual({ + frontmatter: { foo: 'bar' }, + rawFrontmatter: yaml, + content: '\n \n\n\ncontent', + }); + expect(parseFrontmatter(` ---${yaml}---`)).toEqual({ + frontmatter: {}, + rawFrontmatter: '', + content: ` ---${yaml}---`, + }); + expect(parseFrontmatter(`---${yaml} ---`)).toEqual({ + frontmatter: {}, + rawFrontmatter: '', + content: `---${yaml} ---`, + }); + expect(parseFrontmatter(`text\n---${yaml}---\n\ncontent`)).toEqual({ + frontmatter: {}, + rawFrontmatter: '', + content: `text\n---${yaml}---\n\ncontent`, + }); + }); + + it('frontmatter style', () => { + const yaml = '\nfoo: bar\n'; + const parse1 = (style) => parseFrontmatter(`---${yaml}---`, { frontmatter: style }).content; + + expect(parse1('preserve')).toBe(`---${yaml}---`); + expect(parse1('remove')).toBe(''); + expect(parse1('empty-with-spaces')).toBe(' \n \n '); + expect(parse1('empty-with-lines')).toBe('\n\n'); + + const parse2 = (style) => + parseFrontmatter(`\n \n---${yaml}---\n\ncontent`, { frontmatter: style }).content; + + expect(parse2('preserve')).toBe(`\n \n---${yaml}---\n\ncontent`); + expect(parse2('remove')).toBe('\n \n\n\ncontent'); + expect(parse2('empty-with-spaces')).toBe('\n \n \n \n \n\ncontent'); + expect(parse2('empty-with-lines')).toBe('\n \n\n\n\n\ncontent'); + }); +}); diff --git a/packages/markdown-remark/test/plugins.test.ts b/packages/markdown-remark/test/plugins.test.ts new file mode 100644 index 0000000..5c9e155 --- /dev/null +++ b/packages/markdown-remark/test/plugins.test.ts @@ -0,0 +1,31 @@ +import { fileURLToPath } from 'node:url'; +import { describe, expect, it } from 'vitest'; +import { createMarkdownProcessor } from '../dist/index.js'; + +describe('plugins', () => { + it('should be able to get file path when passing fileURL', async () => { + // biome-ignore lint/suspicious/noExplicitAny: + let context: { path: any }; + + const processor = await createMarkdownProcessor({ + remarkPlugins: [ + () => { + const transformer = (_tree, file) => { + context = file; + }; + return transformer; + }, + ], + }); + + await processor.render('test', { + // @ts-expect-error - this is for internal testing and usage + fileURL: new URL('virtual.md', import.meta.url), + }); + + // @ts-expect-error - this is okay. + expect(typeof context).toBe('object'); + // @ts-expect-error - this is okay. + expect(context.path).toBe(fileURLToPath(new URL('virtual.md', import.meta.url))); + }); +}); diff --git a/packages/markdown-remark/test/remark-collect-images.test.ts b/packages/markdown-remark/test/remark-collect-images.test.ts new file mode 100644 index 0000000..7ec71b3 --- /dev/null +++ b/packages/markdown-remark/test/remark-collect-images.test.ts @@ -0,0 +1,41 @@ +import { beforeEach, describe, expect, it } from 'vitest'; +import { type MarkdownProcessor, createMarkdownProcessor } from '../dist/index.js'; + +describe('collect images', () => { + let processor: MarkdownProcessor; + + beforeEach(async () => { + processor = await createMarkdownProcessor(); + }); + + it('should collect inline image paths', async () => { + const markdown = 'Hello ![inline image url](./img.png)'; + const fileURL = 'file.md'; + + const { + raw, + metadata: { imagePaths }, + // @ts-expect-error - fileURL is for internal testing and usage + } = await processor.render(markdown, { fileURL }); + + expect(raw).toBe( + '

Hello inline image url

' + ); + + expect(imagePaths).toEqual(['./img.png']); + }); + + it('should add image paths from definition', async () => { + const markdown = 'Hello ![image ref][img-ref]\n\n[img-ref]: ./img.webp'; + const fileURL = 'file.md'; + + // @ts-expect-error - fileURL is for internal testing and usage + const { raw, metadata } = await processor.render(markdown, { fileURL }); + + expect(raw).toBe( + '

Hello image ref

' + ); + + expect(metadata.imagePaths).toEqual(['./img.webp']); + }); +}); diff --git a/packages/markdown-remark/test/shiki.test.ts b/packages/markdown-remark/test/shiki.test.ts new file mode 100644 index 0000000..ba88cf7 --- /dev/null +++ b/packages/markdown-remark/test/shiki.test.ts @@ -0,0 +1,135 @@ +import { describe, expect, it } from 'vitest'; +import { createMarkdownProcessor, createShikiHighlighter } from '../dist/index.js'; + +describe('shiki syntax highlighting', () => { + it('does not add is:raw to the output', async () => { + const processor = await createMarkdownProcessor(); + const { raw } = await processor.render('```\ntest\n```'); + expect(raw).not.toContain('is:raw'); + }); + + it('supports light/dark themes', async () => { + const processor = await createMarkdownProcessor({ + shikiConfig: { + themes: { + light: 'github-light', + dark: 'github-dark', + }, + }, + }); + const { raw } = await processor.render('```\ntest\n```'); + + // light theme is there: + expect(raw).toMatch(/background-color:/); + expect(raw).toMatch(/github-light/); + + // dark theme is there: + expect(raw).toMatch(/--shiki-dark-bg:/); + expect(raw).toMatch(/github-dark/); + }); + + it('createShikiHighlighter works', async () => { + const highlighter = await createShikiHighlighter(); + const html = await highlighter.codeToHtml('const foo = "bar";', 'js'); + + expect(html).toMatch(/astro-code github-dark/); + expect(html).toMatch(/background-color:#24292e;color:#e1e4e8;/); + }); + + it('createShikiHighlighter works with codeToHast', async () => { + const highlighter = await createShikiHighlighter(); + const hast = await highlighter.codeToHast('const foo = "bar";', 'js'); + + // @ts-expect-error - we're testing the properties here + expect(hast.children[0].properties.class).toMatch(/astro-code github-dark/); + // @ts-expect-error - we're testing the properties here + expect(hast.children[0].properties.style).toMatch(/background-color:#24292e;color:#e1e4e8;/); + }); + + it('diff +/- text has user-select: none', async () => { + const highlighter = await createShikiHighlighter(); + const html = await highlighter.codeToHtml( + `\ +- const foo = "bar"; ++ const foo = "world";`, + 'diff' + ); + + expect(html).toMatch(/user-select: none/); + expect(html).toMatch(/>-<\/span>/); + expect(html).toMatch(/>\+<\/span>/); + }); + + it('renders attributes', async () => { + const highlighter = await createShikiHighlighter(); + const html = await highlighter.codeToHtml('foo', 'js', { + // @ts-expect-error - we're testing the properties here + attributes: { 'data-foo': 'bar', autofocus: true }, + }); + + expect(html).toMatch(/data-foo="bar"/); + expect(html).toMatch(/autofocus(?!=)/); + }); + + it('supports transformers that read meta', async () => { + const highlighter = await createShikiHighlighter(); + const html = await highlighter.codeToHtml('foo', 'js', { + meta: '{1,3-4}', + transformers: [ + { + pre(node) { + const meta = this.options.meta?.__raw; + if (meta) { + node.properties['data-test'] = meta; + } + }, + }, + ], + }); + + expect(html).toMatch(/data-test="\{1,3-4\}"/); + }); + + it('supports the defaultColor setting', async () => { + const processor = await createMarkdownProcessor({ + shikiConfig: { + themes: { + light: 'github-light', + dark: 'github-dark', + }, + defaultColor: false, + }, + }); + const { raw } = await processor.render('```\ntest\n```'); + + expect(raw).not.toMatch(/color:/); + }); + + it('the highlighter supports lang alias', async () => { + const highlighter = await createShikiHighlighter({ + langAlias: { + cjs: 'javascript', + }, + }); + + const html = await highlighter.codeToHtml(`let test = "some string"`, 'cjs', { + attributes: { 'data-foo': 'bar', autofocus: 'true' }, + }); + + expect(html).toMatch(/data-language="cjs"/); + }); + + it('the markdown processor supports lang alias', async () => { + const processor = await createMarkdownProcessor({ + shikiConfig: { + langAlias: { + cjs: 'javascript', + }, + }, + }); + + const { raw } = await processor.render('```cjs\nlet foo = "bar"\n```'); + + expect(raw).toMatch(/data-language="cjs"/); + }); +}); diff --git a/packages/markdown-remark/tsconfig.json b/packages/markdown-remark/tsconfig.json new file mode 100644 index 0000000..c45e939 --- /dev/null +++ b/packages/markdown-remark/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfig.base.json", + "include": ["src"], + "compilerOptions": { + "outDir": "./dist", + "rootDir": "./src" + } + } \ No newline at end of file diff --git a/packages/markdown-remark/vitest.config.mts b/packages/markdown-remark/vitest.config.mts new file mode 100644 index 0000000..f2f58fd --- /dev/null +++ b/packages/markdown-remark/vitest.config.mts @@ -0,0 +1,11 @@ +import { defineProject } from 'vitest/config'; + +process.env.NODE_OPTIONS ??= '--enable-source-maps'; +process.setSourceMapsEnabled(true); + +export default defineProject({ + test: { + maxConcurrency: 1, + name: '@studiocms/markdown-remark', + }, +}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5c549a2..6b28ed1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,6 +8,9 @@ importers: .: dependencies: + '@astrojs/check': + specifier: ^0.9.4 + version: 0.9.4(typescript@5.7.2) '@biomejs/biome': specifier: ^1.9.4 version: 1.9.4 @@ -20,15 +23,167 @@ importers: '@changesets/config': specifier: ^3.0.4 version: 3.0.4 + '@types/node': + specifier: ^18.17.8 + version: 18.19.69 + esbuild: + specifier: ^0.21.5 + version: 0.21.5 pkg-pr-new: specifier: ^0.0.39 version: 0.0.39 typescript: specifier: ^5.7.2 version: 5.7.2 + vitest: + specifier: ^2.1.8 + version: 2.1.8(@types/node@18.19.69) + + packages/markdown-remark: + dependencies: + '@astrojs/prism': + specifier: ^3.2.0 + version: 3.2.0 + github-slugger: + specifier: ^2.0.0 + version: 2.0.0 + hast-util-from-html: + specifier: ^2.0.3 + version: 2.0.3 + hast-util-to-text: + specifier: ^4.0.2 + version: 4.0.2 + import-meta-resolve: + specifier: ^4.1.0 + version: 4.1.0 + js-yaml: + specifier: ^4.1.0 + version: 4.1.0 + mdast-util-definitions: + specifier: ^6.0.0 + version: 6.0.0 + rehype-raw: + specifier: ^7.0.0 + version: 7.0.0 + rehype-stringify: + specifier: ^10.0.1 + version: 10.0.1 + remark-gfm: + specifier: ^4.0.0 + version: 4.0.0 + remark-parse: + specifier: ^11.0.0 + version: 11.0.0 + remark-rehype: + specifier: ^11.1.1 + version: 11.1.1 + remark-smartypants: + specifier: ^3.0.2 + version: 3.0.2 + shiki: + specifier: ^1.23.1 + version: 1.25.1 + unified: + specifier: ^11.0.5 + version: 11.0.5 + unist-util-remove-position: + specifier: ^5.0.0 + version: 5.0.0 + unist-util-visit: + specifier: ^5.0.0 + version: 5.0.0 + unist-util-visit-parents: + specifier: ^6.0.1 + version: 6.0.1 + vfile: + specifier: ^6.0.3 + version: 6.0.3 + vitest: + specifier: ^2.1.8 + version: 2.1.8(@types/node@18.19.69) + devDependencies: + '@types/estree': + specifier: ^1.0.6 + version: 1.0.6 + '@types/hast': + specifier: ^3.0.4 + version: 3.0.4 + '@types/js-yaml': + specifier: ^4.0.9 + version: 4.0.9 + '@types/mdast': + specifier: ^4.0.4 + version: 4.0.4 + '@types/unist': + specifier: ^3.0.3 + version: 3.0.3 + esbuild: + specifier: ^0.21.5 + version: 0.21.5 + fast-glob: + specifier: ^3.3.2 + version: 3.3.2 + mdast-util-mdx-expression: + specifier: ^2.0.1 + version: 2.0.1 + run-scripts: + specifier: workspace:* + version: link:../../scripts + + scripts: + dependencies: + esbuild: + specifier: ^0.21.5 + version: 0.21.5 + esbuild-plugin-copy: + specifier: ^2.1.1 + version: 2.1.1(esbuild@0.21.5) + fast-glob: + specifier: ^3.3.2 + version: 3.3.2 + kleur: + specifier: ^4.1.5 + version: 4.1.5 + p-limit: + specifier: ^6.1.0 + version: 6.2.0 + tinyexec: + specifier: ^0.3.1 + version: 0.3.2 + tsconfck: + specifier: ^3.1.4 + version: 3.1.4(typescript@5.7.2) packages: + '@astrojs/check@0.9.4': + resolution: {integrity: sha512-IOheHwCtpUfvogHHsvu0AbeRZEnjJg3MopdLddkJE70mULItS/Vh37BHcI00mcOJcH1vhD3odbpvWokpxam7xA==} + hasBin: true + peerDependencies: + typescript: ^5.0.0 + + '@astrojs/compiler@2.10.3': + resolution: {integrity: sha512-bL/O7YBxsFt55YHU021oL+xz+B/9HvGNId3F9xURN16aeqDK9juHGktdkCSXz+U4nqFACq6ZFvWomOzhV+zfPw==} + + '@astrojs/language-server@2.15.4': + resolution: {integrity: sha512-JivzASqTPR2bao9BWsSc/woPHH7OGSGc9aMxXL4U6egVTqBycB3ZHdBJPuOCVtcGLrzdWTosAqVPz1BVoxE0+A==} + hasBin: true + peerDependencies: + prettier: ^3.0.0 + prettier-plugin-astro: '>=0.11.0' + peerDependenciesMeta: + prettier: + optional: true + prettier-plugin-astro: + optional: true + + '@astrojs/prism@3.2.0': + resolution: {integrity: sha512-GilTHKGCW6HMq7y3BUv9Ac7GMe/MO9gi9GW62GzKtth0SwukCu/qp2wLiGpEujhY+VVhaG9v7kv/5vFzvf4NYw==} + engines: {node: ^18.17.1 || ^20.3.0 || >=22.0.0} + + '@astrojs/yaml2ts@0.2.2': + resolution: {integrity: sha512-GOfvSr5Nqy2z5XiwqTouBBpy5FyI6DEe+/g/Mk5am9SjILN1S5fOEvYK0GuWHg98yS/dobP4m8qyqw/URW35fQ==} + '@babel/runtime@7.26.0': resolution: {integrity: sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==} engines: {node: '>=6.9.0'} @@ -147,6 +302,168 @@ packages: '@changesets/write@0.3.2': resolution: {integrity: sha512-kDxDrPNpUgsjDbWBvUo27PzKX4gqeKOlhibaOXDJA6kuBisGqNHv/HwGJrAu8U/dSf8ZEFIeHIPtvSlZI1kULw==} + '@emmetio/abbreviation@2.3.3': + resolution: {integrity: sha512-mgv58UrU3rh4YgbE/TzgLQwJ3pFsHHhCLqY20aJq+9comytTXUDNGG/SMtSeMJdkpxgXSXunBGLD8Boka3JyVA==} + + '@emmetio/css-abbreviation@2.1.8': + resolution: {integrity: sha512-s9yjhJ6saOO/uk1V74eifykk2CBYi01STTK3WlXWGOepyKa23ymJ053+DNQjpFcy1ingpaO7AxCcwLvHFY9tuw==} + + '@emmetio/css-parser@0.4.0': + resolution: {integrity: sha512-z7wkxRSZgrQHXVzObGkXG+Vmj3uRlpM11oCZ9pbaz0nFejvCDmAiNDpY75+wgXOcffKpj4rzGtwGaZxfJKsJxw==} + + '@emmetio/html-matcher@1.3.0': + resolution: {integrity: sha512-NTbsvppE5eVyBMuyGfVu2CRrLvo7J4YHb6t9sBFLyY03WYhXET37qA4zOYUjBWFCRHO7pS1B9khERtY0f5JXPQ==} + + '@emmetio/scanner@1.0.4': + resolution: {integrity: sha512-IqRuJtQff7YHHBk4G8YZ45uB9BaAGcwQeVzgj/zj8/UdOhtQpEIupUhSk8dys6spFIWVZVeK20CzGEnqR5SbqA==} + + '@emmetio/stream-reader-utils@0.1.0': + resolution: {integrity: sha512-ZsZ2I9Vzso3Ho/pjZFsmmZ++FWeEd/txqybHTm4OgaZzdS8V9V/YYWQwg5TC38Z7uLWUV1vavpLLbjJtKubR1A==} + + '@emmetio/stream-reader@2.2.0': + resolution: {integrity: sha512-fXVXEyFA5Yv3M3n8sUGT7+fvecGrZP4k6FnWWMSZVQf69kAq0LLpaBQLGcPR30m3zMmKYhECP4k/ZkzvhEW5kw==} + + '@esbuild/aix-ppc64@0.21.5': + resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.21.5': + resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.21.5': + resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.21.5': + resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.21.5': + resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.21.5': + resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.21.5': + resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.21.5': + resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.21.5': + resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.21.5': + resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.21.5': + resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.21.5': + resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.21.5': + resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.21.5': + resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.21.5': + resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.21.5': + resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.21.5': + resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-x64@0.21.5': + resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-x64@0.21.5': + resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + + '@esbuild/sunos-x64@0.21.5': + resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.21.5': + resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.21.5': + resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.21.5': + resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + + '@jridgewell/sourcemap-codec@1.5.0': + resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} + '@jsdevtools/ez-spawn@3.0.4': resolution: {integrity: sha512-f5DRIOZf7wxogefH03RjMPMdBF7ADTWUMoOs9kaJo06EfwF+aFhMZMDZxHg/Xe12hptN9xoZjGso2fdjapBRIA==} engines: {node: '>=10'} @@ -225,14 +542,221 @@ packages: '@octokit/types@13.6.2': resolution: {integrity: sha512-WpbZfZUcZU77DrSW4wbsSgTPfKcp286q3ItaIgvSbBpZJlu6mnYXAkjZz6LVZPXkEvLIM8McanyZejKTYUHipA==} + '@rollup/rollup-android-arm-eabi@4.29.1': + resolution: {integrity: sha512-ssKhA8RNltTZLpG6/QNkCSge+7mBQGUqJRisZ2MDQcEGaK93QESEgWK2iOpIDZ7k9zPVkG5AS3ksvD5ZWxmItw==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.29.1': + resolution: {integrity: sha512-CaRfrV0cd+NIIcVVN/jx+hVLN+VRqnuzLRmfmlzpOzB87ajixsN/+9L5xNmkaUUvEbI5BmIKS+XTwXsHEb65Ew==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.29.1': + resolution: {integrity: sha512-2ORr7T31Y0Mnk6qNuwtyNmy14MunTAMx06VAPI6/Ju52W10zk1i7i5U3vlDRWjhOI5quBcrvhkCHyF76bI7kEw==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.29.1': + resolution: {integrity: sha512-j/Ej1oanzPjmN0tirRd5K2/nncAhS9W6ICzgxV+9Y5ZsP0hiGhHJXZ2JQ53iSSjj8m6cRY6oB1GMzNn2EUt6Ng==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-freebsd-arm64@4.29.1': + resolution: {integrity: sha512-91C//G6Dm/cv724tpt7nTyP+JdN12iqeXGFM1SqnljCmi5yTXriH7B1r8AD9dAZByHpKAumqP1Qy2vVNIdLZqw==} + cpu: [arm64] + os: [freebsd] + + '@rollup/rollup-freebsd-x64@4.29.1': + resolution: {integrity: sha512-hEioiEQ9Dec2nIRoeHUP6hr1PSkXzQaCUyqBDQ9I9ik4gCXQZjJMIVzoNLBRGet+hIUb3CISMh9KXuCcWVW/8w==} + cpu: [x64] + os: [freebsd] + + '@rollup/rollup-linux-arm-gnueabihf@4.29.1': + resolution: {integrity: sha512-Py5vFd5HWYN9zxBv3WMrLAXY3yYJ6Q/aVERoeUFwiDGiMOWsMs7FokXihSOaT/PMWUty/Pj60XDQndK3eAfE6A==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm-musleabihf@4.29.1': + resolution: {integrity: sha512-RiWpGgbayf7LUcuSNIbahr0ys2YnEERD4gYdISA06wa0i8RALrnzflh9Wxii7zQJEB2/Eh74dX4y/sHKLWp5uQ==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm64-gnu@4.29.1': + resolution: {integrity: sha512-Z80O+taYxTQITWMjm/YqNoe9d10OX6kDh8X5/rFCMuPqsKsSyDilvfg+vd3iXIqtfmp+cnfL1UrYirkaF8SBZA==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-arm64-musl@4.29.1': + resolution: {integrity: sha512-fOHRtF9gahwJk3QVp01a/GqS4hBEZCV1oKglVVq13kcK3NeVlS4BwIFzOHDbmKzt3i0OuHG4zfRP0YoG5OF/rA==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-loongarch64-gnu@4.29.1': + resolution: {integrity: sha512-5a7q3tnlbcg0OodyxcAdrrCxFi0DgXJSoOuidFUzHZ2GixZXQs6Tc3CHmlvqKAmOs5eRde+JJxeIf9DonkmYkw==} + cpu: [loong64] + os: [linux] + + '@rollup/rollup-linux-powerpc64le-gnu@4.29.1': + resolution: {integrity: sha512-9b4Mg5Yfz6mRnlSPIdROcfw1BU22FQxmfjlp/CShWwO3LilKQuMISMTtAu/bxmmrE6A902W2cZJuzx8+gJ8e9w==} + cpu: [ppc64] + os: [linux] + + '@rollup/rollup-linux-riscv64-gnu@4.29.1': + resolution: {integrity: sha512-G5pn0NChlbRM8OJWpJFMX4/i8OEU538uiSv0P6roZcbpe/WfhEO+AT8SHVKfp8qhDQzaz7Q+1/ixMy7hBRidnQ==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-s390x-gnu@4.29.1': + resolution: {integrity: sha512-WM9lIkNdkhVwiArmLxFXpWndFGuOka4oJOZh8EP3Vb8q5lzdSCBuhjavJsw68Q9AKDGeOOIHYzYm4ZFvmWez5g==} + cpu: [s390x] + os: [linux] + + '@rollup/rollup-linux-x64-gnu@4.29.1': + resolution: {integrity: sha512-87xYCwb0cPGZFoGiErT1eDcssByaLX4fc0z2nRM6eMtV9njAfEE6OW3UniAoDhX4Iq5xQVpE6qO9aJbCFumKYQ==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-linux-x64-musl@4.29.1': + resolution: {integrity: sha512-xufkSNppNOdVRCEC4WKvlR1FBDyqCSCpQeMMgv9ZyXqqtKBfkw1yfGMTUTs9Qsl6WQbJnsGboWCp7pJGkeMhKA==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-win32-arm64-msvc@4.29.1': + resolution: {integrity: sha512-F2OiJ42m77lSkizZQLuC+jiZ2cgueWQL5YC9tjo3AgaEw+KJmVxHGSyQfDUoYR9cci0lAywv2Clmckzulcq6ig==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.29.1': + resolution: {integrity: sha512-rYRe5S0FcjlOBZQHgbTKNrqxCBUmgDJem/VQTCcTnA2KCabYSWQDrytOzX7avb79cAAweNmMUb/Zw18RNd4mng==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.29.1': + resolution: {integrity: sha512-+10CMg9vt1MoHj6x1pxyjPSMjHTIlqs8/tBztXvPAx24SKs9jwVnKqHJumlH/IzhaPUaj3T6T6wfZr8okdXaIg==} + cpu: [x64] + os: [win32] + + '@shikijs/core@1.25.1': + resolution: {integrity: sha512-0j5k3ZkLTQViOuNzPVyWGoW1zgH3kiFdUT/JOCkTm7TU74mz+dF+NID+YoiCBzHQxgsDpcGYPjKDJRcuVLSt4A==} + + '@shikijs/engine-javascript@1.25.1': + resolution: {integrity: sha512-zQ7UWKnRCfD/Q1M+XOSyjsbhpE0qv8LUnmn82HYCeOsgAHgUZGEDIQ63bbuK3kU5sQg+2CtI+dPfOqD/mjSY9w==} + + '@shikijs/engine-oniguruma@1.25.1': + resolution: {integrity: sha512-iKPMh3H+0USHtWfZ1irfMTH6tGmIUFSnqt3E2K8BgI1VEsqiPh0RYkG2WTwzNiM1/WHN4FzYx/nrKR7PDHiRyw==} + + '@shikijs/langs@1.25.1': + resolution: {integrity: sha512-hdYjq9aRJplAzGe2qF51PR9IDgEoyGb4IkXvr3Ts6lEdg4Z8M/kdknKRo2EIuv3IR/aKkJXTlBQRM+wr3t20Ew==} + + '@shikijs/themes@1.25.1': + resolution: {integrity: sha512-JO0lDn4LgGqg5QKvgich5ScUmC2okK+LxM9a3iLUH7YMeI2c8UGXThuJv6sZduS7pdJbYQHPrvWq9t/V4GhpbQ==} + + '@shikijs/types@1.25.1': + resolution: {integrity: sha512-dceqFUoO95eY4tpOj3OGq8wE8EgJ4ey6Me1HQEu5UbwIYszFndEll/bjlB8Kp9wl4fx3uM7n4+y9XCYuDBmcXA==} + + '@shikijs/vscode-textmate@9.3.1': + resolution: {integrity: sha512-79QfK1393x9Ho60QFyLti+QfdJzRQCVLFb97kOIV7Eo9vQU/roINgk7m24uv0a7AUvN//RDH36FLjjK48v0s9g==} + + '@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/js-yaml@4.0.9': + resolution: {integrity: sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==} + + '@types/mdast@4.0.4': + resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} + + '@types/ms@0.7.34': + resolution: {integrity: sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==} + + '@types/nlcst@2.0.3': + resolution: {integrity: sha512-vSYNSDe6Ix3q+6Z7ri9lyWqgGhJTmzRjZRqyq15N0Z/1/UnVsno9G/N40NBijoYx2seFDIl0+B2mgAb9mezUCA==} + '@types/node@12.20.55': resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} + '@types/node@18.19.69': + resolution: {integrity: sha512-ECPdY1nlaiO/Y6GUnwgtAAhLNaQ53AyIVz+eILxpEo5OvuqE6yWkqWBIb5dU0DqhKQtMeny+FBD3PK6lm7L5xQ==} + + '@types/unist@3.0.3': + resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} + + '@ungap/structured-clone@1.2.1': + resolution: {integrity: sha512-fEzPV3hSkSMltkw152tJKNARhOupqbH96MZWyRjNaYZOMIzbrTeQDG+MTc6Mr2pgzFQzFxAfmhGDNP5QK++2ZA==} + + '@vitest/expect@2.1.8': + resolution: {integrity: sha512-8ytZ/fFHq2g4PJVAtDX57mayemKgDR6X3Oa2Foro+EygiOJHUXhCqBAAKQYYajZpFoIfvBCF1j6R6IYRSIUFuw==} + + '@vitest/mocker@2.1.8': + resolution: {integrity: sha512-7guJ/47I6uqfttp33mgo6ga5Gr1VnL58rcqYKyShoRK9ebu8T5Rs6HN3s1NABiBeVTdWNrwUMcHH54uXZBN4zA==} + peerDependencies: + msw: ^2.4.9 + vite: ^5.0.0 + peerDependenciesMeta: + msw: + optional: true + vite: + optional: true + + '@vitest/pretty-format@2.1.8': + resolution: {integrity: sha512-9HiSZ9zpqNLKlbIDRWOnAWqgcA7xu+8YxXSekhr0Ykab7PAYFkhkwoqVArPOtJhPmYeE2YHgKZlj3CP36z2AJQ==} + + '@vitest/runner@2.1.8': + resolution: {integrity: sha512-17ub8vQstRnRlIU5k50bG+QOMLHRhYPAna5tw8tYbj+jzjcspnwnwtPtiOlkuKC4+ixDPTuLZiqiWWQ2PSXHVg==} + + '@vitest/snapshot@2.1.8': + resolution: {integrity: sha512-20T7xRFbmnkfcmgVEz+z3AU/3b0cEzZOt/zmnvZEctg64/QZbSDJEVm9fLnnlSi74KibmRsO9/Qabi+t0vCRPg==} + + '@vitest/spy@2.1.8': + resolution: {integrity: sha512-5swjf2q95gXeYPevtW0BLk6H8+bPlMb4Vw/9Em4hFxDcaOxS+e0LOX4yqNxoHzMR2akEB2xfpnWUzkZokmgWDg==} + + '@vitest/utils@2.1.8': + resolution: {integrity: sha512-dwSoui6djdwbfFmIgbIjX2ZhIoG7Ex/+xpxyiEgIGzjliY8xGkcpITKTlp6B4MgtGkF2ilvm97cPM96XZaAgcA==} + + '@volar/kit@2.4.11': + resolution: {integrity: sha512-ups5RKbMzMCr6RKafcCqDRnJhJDNWqo2vfekwOAj6psZ15v5TlcQFQAyokQJ3wZxVkzxrQM+TqTRDENfQEXpmA==} + peerDependencies: + typescript: '*' + + '@volar/language-core@2.4.11': + resolution: {integrity: sha512-lN2C1+ByfW9/JRPpqScuZt/4OrUUse57GLI6TbLgTIqBVemdl1wNcZ1qYGEo2+Gw8coYLgCy7SuKqn6IrQcQgg==} + + '@volar/language-server@2.4.11': + resolution: {integrity: sha512-W9P8glH1M8LGREJ7yHRCANI5vOvTrRO15EMLdmh5WNF9sZYSEbQxiHKckZhvGIkbeR1WAlTl3ORTrJXUghjk7g==} + + '@volar/language-service@2.4.11': + resolution: {integrity: sha512-KIb6g8gjUkS2LzAJ9bJCLIjfsJjeRtmXlu7b2pDFGD3fNqdbC53cCAKzgWDs64xtQVKYBU13DLWbtSNFtGuMLQ==} + + '@volar/source-map@2.4.11': + resolution: {integrity: sha512-ZQpmafIGvaZMn/8iuvCFGrW3smeqkq/IIh9F1SdSx9aUl0J4Iurzd6/FhmjNO5g2ejF3rT45dKskgXWiofqlZQ==} + + '@volar/typescript@2.4.11': + resolution: {integrity: sha512-2DT+Tdh88Spp5PyPbqhyoYavYCPDsqbHLFwcUI9K1NlY1YgUJvujGdrqUp0zWxnW7KWNTr3xSpMuv2WnaTKDAw==} + + '@vscode/emmet-helper@2.11.0': + resolution: {integrity: sha512-QLxjQR3imPZPQltfbWRnHU6JecWTF1QSWhx3GAKQpslx7y3Dp6sIIXhKjiUJ/BR9FX8PVthjr9PD6pNwOJfAzw==} + + '@vscode/l10n@0.0.18': + resolution: {integrity: sha512-KYSIHVmslkaCDyw013pphY+d7x1qV8IZupYfeIfzNA+nsaWHbn5uPuQRvdRFsa9zFzGeudPuoGoZ1Op4jrJXIQ==} + acorn@8.14.0: resolution: {integrity: sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==} engines: {node: '>=0.4.0'} hasBin: true + ajv@8.17.1: + resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==} + ansi-colors@4.1.3: resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} engines: {node: '>=6'} @@ -241,13 +765,34 @@ packages: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + argparse@1.0.10: resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + array-iterate@2.0.1: + resolution: {integrity: sha512-I1jXZMjAgCMmxT4qxXfPXa6SthSoE8h6gkSI9BGGNv8mP8G/v0blc+qFnZu6K42vTOiuME596QaLO0TP3Lk0xg==} + array-union@2.1.0: resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} engines: {node: '>=8'} + assertion-error@2.0.1: + resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} + engines: {node: '>=12'} + + bail@2.0.2: + resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==} + before-after-hook@2.2.3: resolution: {integrity: sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==} @@ -255,20 +800,74 @@ packages: resolution: {integrity: sha512-pbnl5XzGBdrFU/wT4jqmJVPn2B6UHPBOhzMQkY/SPUPB6QtUXtmBHBIwCbXJol93mOpGMnQyP/+BB19q04xj7g==} engines: {node: '>=4'} + binary-extensions@2.3.0: + resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} + engines: {node: '>=8'} + braces@3.0.3: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} + cac@6.7.14: + resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} + engines: {node: '>=8'} + call-me-maybe@1.0.2: resolution: {integrity: sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ==} + ccount@2.0.1: + resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} + + chai@5.1.2: + resolution: {integrity: sha512-aGtmf24DW6MLHHG5gCx4zaI3uBq3KRtxeVs0DjFH6Z0rDNbsvTxFASFvdj79pxjxZ8/5u3PIiN3IwEIQkiiuPw==} + engines: {node: '>=12'} + + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + + 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==} + chardet@0.7.0: resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} + check-error@2.1.1: + resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==} + engines: {node: '>= 16'} + + chokidar@3.6.0: + resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} + engines: {node: '>= 8.10.0'} + + chokidar@4.0.3: + resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} + engines: {node: '>= 14.16.0'} + ci-info@3.9.0: resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} engines: {node: '>=8'} + cliui@8.0.1: + resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} + engines: {node: '>=12'} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + comma-separated-tokens@2.0.3: + resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} + confbox@0.1.8: resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} @@ -279,17 +878,40 @@ packages: dataloader@1.4.0: resolution: {integrity: sha512-68s5jYdlvasItOJnCuI2Q9s4q98g0pCyL3HrcKJu8KNugUl8ahgmZYg38ysLTgQjjXX3H8CJLkAvWrclWfcalw==} + debug@4.4.0: + resolution: {integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + decode-named-character-reference@1.0.2: + resolution: {integrity: sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==} + decode-uri-component@0.4.1: resolution: {integrity: sha512-+8VxcR21HhTy8nOt6jf20w0c9CADrw1O8d+VZ/YzzCt4bJ3uBjw+D1q2osAB8RnpwwaeYBxy0HyKQxD5JBMuuQ==} engines: {node: '>=14.16'} + deep-eql@5.0.2: + resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} + engines: {node: '>=6'} + deprecation@2.3.1: resolution: {integrity: sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==} + dequal@2.0.3: + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} + engines: {node: '>=6'} + detect-indent@6.1.0: resolution: {integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==} engines: {node: '>=8'} + devlop@1.1.0: + resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} + dir-glob@3.0.1: resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} engines: {node: '>=8'} @@ -298,15 +920,59 @@ packages: resolution: {integrity: sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g==} engines: {node: '>=10'} + emmet@2.4.11: + resolution: {integrity: sha512-23QPJB3moh/U9sT4rQzGgeyyGIrcM+GH5uVYg2C6wZIxAIJq7Ng3QLT79tl8FUwDXhyq9SusfknOrofAKqvgyQ==} + + emoji-regex-xs@1.0.0: + resolution: {integrity: sha512-LRlerrMYoIDrT6jgpeZ2YYl/L8EulRTt5hQcYjy5AInh7HWXKimpqx68aknBFpGL2+/IcogTcaydJEgaTmOpDg==} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + enquirer@2.4.1: resolution: {integrity: sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==} engines: {node: '>=8.6'} + entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + + es-module-lexer@1.6.0: + resolution: {integrity: sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ==} + + esbuild-plugin-copy@2.1.1: + resolution: {integrity: sha512-Bk66jpevTcV8KMFzZI1P7MZKZ+uDcrZm2G2egZ2jNIvVnivDpodZI+/KnpL3Jnap0PBdIHU7HwFGB8r+vV5CVw==} + peerDependencies: + esbuild: '>= 0.14.0' + + esbuild@0.21.5: + resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} + engines: {node: '>=12'} + hasBin: true + + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + + 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-walker@3.0.3: + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + + expect-type@1.1.0: + resolution: {integrity: sha512-bFi65yM+xZgk+u/KRIpekdSYkTB5W1pEf0Lt8Q8Msh7b+eQ7LXVtIB1Bkm4fvclDEL1b2CZkMhv2mOeF8tMdkA==} + engines: {node: '>=12.0.0'} + + extend@3.0.2: + resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} + extendable-error@0.1.7: resolution: {integrity: sha512-UOiS2in6/Q0FK0R0q6UY9vYpQ21mr/Qn1KOnte7vsACuNJf514WvCCUHSRCPcgjPT2bAhNIJdlE6bVap1GKmeg==} @@ -314,10 +980,16 @@ packages: resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==} engines: {node: '>=4'} + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + fast-glob@3.3.2: resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} engines: {node: '>=8.6.0'} + fast-uri@3.0.3: + resolution: {integrity: sha512-aLrHthzCjH5He4Z2H9YZ+v6Ujb9ocRuW6ZzkJQOrTxleEijANq4v1TsaPaVG1PZcuurEzrLcWRyYBYXD5cEiaw==} + fastq@1.17.1: resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} @@ -341,6 +1013,10 @@ packages: resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} engines: {node: '>=8'} + fs-extra@10.1.0: + resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==} + engines: {node: '>=12'} + fs-extra@7.0.1: resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==} engines: {node: '>=6 <7 || >=8'} @@ -349,6 +1025,18 @@ packages: resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==} engines: {node: '>=6 <7 || >=8'} + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + + 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'} @@ -360,21 +1048,69 @@ packages: graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} - human-id@1.0.2: - resolution: {integrity: sha512-UNopramDEhHJD+VR+ehk8rOslwSfByxPIZyJRfV739NDhN5LF1fa1MqnzKm2lGTQRjNrjK19Q5fhkgIfjlVUKw==} + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} - iconv-lite@0.4.24: - resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} - engines: {node: '>=0.10.0'} + hast-util-from-html@2.0.3: + resolution: {integrity: sha512-CUSRHXyKjzHov8yKsQjGOElXy/3EKpyX56ELnkHH34vDVw1N1XSQ1ZcAvTyAPtGqLTuKP/uxM+aLkSPqF/EtMw==} - ignore@5.3.2: - resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} - engines: {node: '>= 4'} + hast-util-from-parse5@8.0.2: + resolution: {integrity: sha512-SfMzfdAi/zAoZ1KkFEyyeXBn7u/ShQrfd675ZEE9M3qj+PMFX05xubzRyF76CCSJu8au9jgVxDV1+okFvgZU4A==} + + hast-util-is-element@3.0.0: + resolution: {integrity: sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==} + + hast-util-parse-selector@4.0.0: + resolution: {integrity: sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==} + + hast-util-raw@9.1.0: + resolution: {integrity: sha512-Y8/SBAHkZGoNkpzqqfCldijcuUKh7/su31kEBp67cFY09Wy0mTRgtsLYsiIxMJxlu0f6AA5SUTbDR8K0rxnbUw==} + + hast-util-to-html@9.0.4: + resolution: {integrity: sha512-wxQzXtdbhiwGAUKrnQJXlOPmHnEehzphwkK7aluUPQ+lEc1xefC8pblMgpp2w5ldBTEfveRIrADcrhGIWrlTDA==} + + hast-util-to-parse5@8.0.0: + resolution: {integrity: sha512-3KKrV5ZVI8if87DVSi1vDeByYrkGzg4mEfeu4alwgmmIeARiBLKCZS2uw5Gb6nU9x9Yufyj3iudm6i7nl52PFw==} + + hast-util-to-text@4.0.2: + resolution: {integrity: sha512-KK6y/BN8lbaq654j7JgBydev7wuNMcID54lkRav1P0CaE1e47P72AWWPiGKXTJU271ooYzcvTAn/Zt0REnvc7A==} + + hast-util-whitespace@3.0.0: + resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==} + + hastscript@9.0.0: + resolution: {integrity: sha512-jzaLBGavEDKHrc5EfFImKN7nZKKBdSLIdGvCwDZ9TfzbF2ffXiov8CKE445L2Z1Ek2t/m4SKQ2j6Ipv7NyUolw==} + + html-void-elements@3.0.0: + resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==} + + human-id@1.0.2: + resolution: {integrity: sha512-UNopramDEhHJD+VR+ehk8rOslwSfByxPIZyJRfV739NDhN5LF1fa1MqnzKm2lGTQRjNrjK19Q5fhkgIfjlVUKw==} + + iconv-lite@0.4.24: + resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} + engines: {node: '>=0.10.0'} + + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} + + import-meta-resolve@4.1.0: + resolution: {integrity: sha512-I6fiaX09Xivtk+THaMfAwnA3MVA5Big1WHF1Dfx9hFuvNIWpXnorlkzhcQf6ehrqQiiZECRt1poOAkPmer3ruw==} + + is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} is-extglob@2.1.1: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + is-glob@4.0.3: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} @@ -383,6 +1119,10 @@ 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-subdir@1.2.0: resolution: {integrity: sha512-2AT6j+gXe/1ueqbW6fLZJiIw3F8iXGJtt0yDrZaBhAZEG1raiTxKWU+IPqMCzQAXOUCKdA4UDMgacKH25XG2Cw==} engines: {node: '>=4'} @@ -402,9 +1142,29 @@ packages: resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} hasBin: true + js-yaml@4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + hasBin: true + + json-schema-traverse@1.0.0: + resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + + jsonc-parser@2.3.1: + resolution: {integrity: sha512-H8jvkz1O50L3dMZCsLqiuB2tA7muqbSg1AtGEkN0leAqGjsUzDJir3Zwr02BhqdcITPg3ei3mZ+HjMocAknhhg==} + + jsonc-parser@3.3.1: + resolution: {integrity: sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==} + jsonfile@4.0.0: resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} + jsonfile@6.1.0: + resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} + + kleur@4.1.5: + resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} + engines: {node: '>=6'} + locate-path@5.0.0: resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} engines: {node: '>=8'} @@ -412,10 +1172,151 @@ packages: lodash.startcase@4.4.0: resolution: {integrity: sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==} + lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + + longest-streak@3.1.0: + resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==} + + loupe@3.1.2: + resolution: {integrity: sha512-23I4pFZHmAemUnz8WZXbYRSKYj801VDaNv9ETuMh7IrMc7VuVVSo+Z9iLE3ni30+U48iDWfi30d3twAXBYmnCg==} + + magic-string@0.30.17: + resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==} + + markdown-table@3.0.4: + resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==} + + mdast-util-definitions@6.0.0: + resolution: {integrity: sha512-scTllyX6pnYNZH/AIp/0ePz6s4cZtARxImwoPJ7kS42n+MnVsI4XbnG6d4ibehRIldYMWM2LD7ImQblVhUejVQ==} + + mdast-util-find-and-replace@3.0.1: + resolution: {integrity: sha512-SG21kZHGC3XRTSUhtofZkBzZTJNM5ecCi0SK2IMKmSXR8vO3peL+kb1O0z7Zl83jKtutG4k5Wv/W7V3/YHvzPA==} + + mdast-util-from-markdown@2.0.2: + resolution: {integrity: sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==} + + mdast-util-gfm-autolink-literal@2.0.1: + resolution: {integrity: sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==} + + mdast-util-gfm-footnote@2.0.0: + resolution: {integrity: sha512-5jOT2boTSVkMnQ7LTrd6n/18kqwjmuYqo7JUPe+tRCY6O7dAuTFMtTPauYYrMPpox9hlN0uOx/FL8XvEfG9/mQ==} + + mdast-util-gfm-strikethrough@2.0.0: + resolution: {integrity: sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==} + + mdast-util-gfm-table@2.0.0: + resolution: {integrity: sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==} + + mdast-util-gfm-task-list-item@2.0.0: + resolution: {integrity: sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==} + + mdast-util-gfm@3.0.0: + resolution: {integrity: sha512-dgQEX5Amaq+DuUqf26jJqSK9qgixgd6rYDHAv4aTBuA92cTknZlKpPfa86Z/s8Dj8xsAQpFfBmPUHWJBWqS4Bw==} + + mdast-util-mdx-expression@2.0.1: + resolution: {integrity: sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==} + + 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==} + merge2@1.4.1: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} + micromark-core-commonmark@2.0.2: + resolution: {integrity: sha512-FKjQKbxd1cibWMM1P9N+H8TwlgGgSkWZMmfuVucLCHaYqeSvJ0hFeHsIa65pA2nYbes0f8LDHPMrd9X7Ujxg9w==} + + micromark-extension-gfm-autolink-literal@2.1.0: + resolution: {integrity: sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==} + + micromark-extension-gfm-footnote@2.1.0: + resolution: {integrity: sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==} + + micromark-extension-gfm-strikethrough@2.1.0: + resolution: {integrity: sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==} + + micromark-extension-gfm-table@2.1.0: + resolution: {integrity: sha512-Ub2ncQv+fwD70/l4ou27b4YzfNaCJOvyX4HxXU15m7mpYY+rjuWzsLIPZHJL253Z643RpbcP1oeIJlQ/SKW67g==} + + micromark-extension-gfm-tagfilter@2.0.0: + resolution: {integrity: sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==} + + micromark-extension-gfm-task-list-item@2.1.0: + resolution: {integrity: sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==} + + micromark-extension-gfm@3.0.0: + resolution: {integrity: sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==} + + 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-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-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.0.3: + resolution: {integrity: sha512-VXJJuNxYWSoYL6AJ6OQECCFGhIU2GGHMw8tahogePBrjkG8aCCas3ibkp7RnVOSTClg2is05/R7maAhF1XyQMg==} + + micromark-util-symbol@2.0.1: + resolution: {integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==} + + micromark-util-types@2.0.1: + resolution: {integrity: sha512-534m2WhVTddrcKVepwmVEVnUAmtrx9bfIjNoQHRqfnvdaHQiFytEhJoTgpWJvDEXCO5gLTQh3wYC1PgOJA4NSQ==} + + micromark@4.0.1: + resolution: {integrity: sha512-eBPdkcoCNvYcxQOAKAlceo5SNdzZWfF+FcSupREAzdAh9rRmE239CEQAiTwIgblwnoM8zzj35sZ5ZwvSEOF6Kw==} + micromatch@4.0.8: resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} engines: {node: '>=8.6'} @@ -427,6 +1328,20 @@ packages: resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} engines: {node: '>=4'} + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + muggle-string@0.4.1: + resolution: {integrity: sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==} + + nanoid@3.3.8: + resolution: {integrity: sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + nlcst-to-string@4.0.0: + resolution: {integrity: sha512-YKLBCcUYKAg0FNlOBT6aI91qFmSiFKiluk655WzPF+DDMA02qIyy8uiRqI8QXtcFpEvll12LpL5MXqEmAZ+dcA==} + node-fetch@2.7.0: resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} engines: {node: 4.x || >=6.0.0} @@ -436,9 +1351,16 @@ packages: encoding: optional: true + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + once@1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + oniguruma-to-es@0.10.0: + resolution: {integrity: sha512-zapyOUOCJxt+xhiNRPPMtfJkHGsZ98HHB9qJEkdT8BGytO/+kpe4m1Ngf0MzbzTmhacn11w9yGeDP6tzDhnCdg==} + os-tmpdir@1.0.2: resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} engines: {node: '>=0.10.0'} @@ -454,6 +1376,10 @@ packages: resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} engines: {node: '>=6'} + p-limit@6.2.0: + resolution: {integrity: sha512-kuUqqHNUqoIWp/c467RI4X6mmyuojY5jGutNU0wVTmEOOfcuwLqyMVoAi9MKi2Ak+5i9+nhmrK4ufZE8069kHA==} + engines: {node: '>=18'} + p-locate@4.1.0: resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} engines: {node: '>=8'} @@ -469,6 +1395,15 @@ packages: package-manager-detector@0.2.7: resolution: {integrity: sha512-g4+387DXDKlZzHkP+9FLt8yKj8+/3tOkPv7DVTJGGRm00RkEWgqbFstX1mXJ4M0VDYhUqsTOiISqNOJnhAu3PQ==} + parse-latin@7.0.0: + resolution: {integrity: sha512-mhHgobPPua5kZ98EF4HWiH167JWBfl4pvAIXXdbaVohtK7a6YBOy56kvhCqduqyo/f3yrHFWmqmiMg/BkBkYYQ==} + + parse5@7.2.1: + resolution: {integrity: sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ==} + + path-browserify@1.0.1: + resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==} + path-exists@4.0.0: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} engines: {node: '>=8'} @@ -484,6 +1419,10 @@ packages: pathe@1.1.2: resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} + pathval@2.0.0: + resolution: {integrity: sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==} + engines: {node: '>= 14.16'} + picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} @@ -506,11 +1445,27 @@ packages: pkg-types@1.2.1: resolution: {integrity: sha512-sQoqa8alT3nHjGuTjuKgOnvjo4cljkufdtLMnO2LBP/wRwuDlo1tkaEdMxCRhyGRPacv/ztlZgDPm2b7FAmEvw==} + postcss@8.4.49: + resolution: {integrity: sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==} + engines: {node: ^10 || ^12 || >=14} + + prettier@2.8.7: + resolution: {integrity: sha512-yPngTo3aXUUmyuTjeTUT75txrf+aMh9FiD7q9ZE/i6r0bPb22g4FsE6Y338PQX1bmfy08i9QQCB7/rcUAVntfw==} + engines: {node: '>=10.13.0'} + hasBin: true + prettier@2.8.8: resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==} engines: {node: '>=10.13.0'} hasBin: true + prismjs@1.29.0: + resolution: {integrity: sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==} + engines: {node: '>=6'} + + property-information@6.5.0: + resolution: {integrity: sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig==} + query-registry@3.0.1: resolution: {integrity: sha512-M9RxRITi2mHMVPU5zysNjctUT8bAPx6ltEXo/ir9+qmiM47Y7f0Ir3+OxUO5OjYAWdicBQRew7RtHtqUXydqlg==} engines: {node: '>=20'} @@ -530,17 +1485,87 @@ packages: resolution: {integrity: sha512-VIMnQi/Z4HT2Fxuwg5KrY174U1VdUIASQVWXXyqtNRtxSr9IYkn1rsI6Tb6HsrHCmB7gVpNwX6JxPTHcH6IoTA==} engines: {node: '>=6'} + readdirp@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + + readdirp@4.0.2: + resolution: {integrity: sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==} + engines: {node: '>= 14.16.0'} + regenerator-runtime@0.14.1: resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} + regex-recursion@5.1.1: + resolution: {integrity: sha512-ae7SBCbzVNrIjgSbh7wMznPcQel1DNlDtzensnFxpiNpXt1U2ju/bHugH422r+4LAVS1FpW1YCwilmnNsjum9w==} + + regex-utilities@2.3.0: + resolution: {integrity: sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==} + + regex@5.1.1: + resolution: {integrity: sha512-dN5I359AVGPnwzJm2jN1k0W9LPZ+ePvoOeVMMfqIMFz53sSwXkxaJoxr50ptnsC771lK95BnTrVSZxq0b9yCGw==} + + rehype-raw@7.0.0: + resolution: {integrity: sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==} + + rehype-stringify@10.0.1: + resolution: {integrity: sha512-k9ecfXHmIPuFVI61B9DeLPN0qFHfawM6RsuX48hoqlaKSF61RskNjSm1lI8PhBEM0MRdLxVVm4WmTqJQccH9mA==} + + remark-gfm@4.0.0: + resolution: {integrity: sha512-U92vJgBPkbw4Zfu/IiW2oTZLSL3Zpv+uI7My2eq8JxKgqraFdU8YUGicEJCEgSbeaG+QDFqIcwwfMTOEelPxuA==} + + remark-parse@11.0.0: + resolution: {integrity: sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==} + + remark-rehype@11.1.1: + resolution: {integrity: sha512-g/osARvjkBXb6Wo0XvAeXQohVta8i84ACbenPpoSsxTOQH/Ae0/RGP4WZgnMH5pMLpsj4FG7OHmcIcXxpza8eQ==} + + remark-smartypants@3.0.2: + resolution: {integrity: sha512-ILTWeOriIluwEvPjv67v7Blgrcx+LZOkAUVtKI3putuhlZm84FnqDORNXPPm+HY3NdZOMhyDwZ1E+eZB/Df5dA==} + engines: {node: '>=16.0.0'} + + remark-stringify@11.0.0: + resolution: {integrity: sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==} + + request-light@0.5.8: + resolution: {integrity: sha512-3Zjgh+8b5fhRJBQZoy+zbVKpAQGLyka0MPgW3zruTF4dFFJ8Fqcfu9YsAvi/rvdcaTeWG3MkbZv4WKxAn/84Lg==} + + request-light@0.7.0: + resolution: {integrity: sha512-lMbBMrDoxgsyO+yB3sDcrDuX85yYt7sS8BfQd11jtbW/z5ZWgLZRcEGLsLoYw7I0WSUGQBs8CC8ScIxkTX1+6Q==} + + require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + + require-from-string@2.0.2: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + engines: {node: '>=0.10.0'} + resolve-from@5.0.0: resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} engines: {node: '>=8'} + retext-latin@4.0.0: + resolution: {integrity: sha512-hv9woG7Fy0M9IlRQloq/N6atV82NxLGveq+3H2WOi79dtIYWN8OaxogDm77f8YnVXJL2VD3bbqowu5E3EMhBYA==} + + retext-smartypants@6.2.0: + resolution: {integrity: sha512-kk0jOU7+zGv//kfjXEBjdIryL1Acl4i9XNkHxtM7Tm5lFiCog576fjNC9hjoR7LTKQ0DsPWy09JummSsH1uqfQ==} + + retext-stringify@4.0.0: + resolution: {integrity: sha512-rtfN/0o8kL1e+78+uxPTqu1Klt0yPzKuQ2BfWwwfgIUSayyzxpM1PJzkKt4V8803uB9qSy32MvI7Xep9khTpiA==} + + retext@9.0.0: + resolution: {integrity: sha512-sbMDcpHCNjvlheSgMfEcVrZko3cDzdbe1x/e7G66dFp0Ff7Mldvi2uv6JkJQzdRcvLYE8CA8Oe8siQx8ZOgTcA==} + reusify@1.0.4: resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + rollup@4.29.1: + resolution: {integrity: sha512-RaJ45M/kmJUzSWDs1Nnd5DdV4eerC98idtUOVr6FfKcgxqvjwHmxc5upLF9qZU9EpsVzzhleFahrT3shLuJzIw==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} @@ -560,6 +1585,12 @@ packages: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} + shiki@1.25.1: + resolution: {integrity: sha512-/1boRvNYwRW3GLG9Y6dXdnZ/Ha+J5T/5y3hV7TGQUcDSBM185D3FCbXlz2eTGNKG2iWCbWqo+P0yhGKZ4/CUrw==} + + siginfo@2.0.0: + resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + signal-exit@4.1.0: resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} engines: {node: '>=14'} @@ -568,6 +1599,13 @@ packages: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} engines: {node: '>=8'} + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + space-separated-tokens@2.0.2: + resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} + spawndamnit@3.0.1: resolution: {integrity: sha512-MmnduQUuHCoFckZoWnXsTg7JaiLBJrKFj9UI2MbRPGaJeVpsLcVBu6P/IGZovziM/YBsellCmsprgNA+w0CzVg==} @@ -578,10 +1616,23 @@ packages: sprintf-js@1.0.3: resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + stackback@0.0.2: + resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} + + std-env@3.8.0: + resolution: {integrity: sha512-Bc3YwwCB+OzldMxOXJIIvC6cPRWr/LxOp48CdQTOkPyk/t4JWWJbrilwBd7RJzKV8QW7tJkcgAmeuLLJugl5/w==} + string-argv@0.3.2: resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==} engines: {node: '>=0.6.19'} + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + 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'} @@ -590,14 +1641,36 @@ packages: resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} engines: {node: '>=4'} + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + term-size@2.2.1: resolution: {integrity: sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==} engines: {node: '>=8'} + tinybench@2.9.0: + resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} + + tinyexec@0.3.2: + resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} + tinyglobby@0.2.10: resolution: {integrity: sha512-Zc+8eJlFMvgatPZTl6A9L/yht8QqdmUNtURHaKZLmKBE12hNPSrqNkUp2cs3M/UKmNVVAMFQYSjYIVHDjW5zew==} engines: {node: '>=12.0.0'} + tinypool@1.0.2: + resolution: {integrity: sha512-al6n+QEANGFOMf/dmUMsuS5/r9B06uwlyNjZZql/zv8J7ybHCgoihBNORZCY2mzUuAnomQa2JdhyHKzZxPCrFA==} + engines: {node: ^18.0.0 || >=20.0.0} + + tinyrainbow@1.2.0: + resolution: {integrity: sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==} + engines: {node: '>=14.0.0'} + + tinyspy@3.0.2: + resolution: {integrity: sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==} + engines: {node: '>=14.0.0'} + tmp@0.0.33: resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} engines: {node: '>=0.6.0'} @@ -609,10 +1682,32 @@ 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.4: + resolution: {integrity: sha512-kdqWFGVJqe+KGYvlSO9NIaWn9jT1Ny4oKVzAJsKii5eoE9snzTJzL4+MMVOMn+fikWGFmKEylcXL710V/kIPJQ==} + engines: {node: ^18 || >=20} + hasBin: true + peerDependencies: + typescript: ^5.0.0 + peerDependenciesMeta: + typescript: + optional: true + type-detect@4.1.0: resolution: {integrity: sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==} engines: {node: '>=4'} + typesafe-path@0.2.2: + resolution: {integrity: sha512-OJabfkAg1WLZSqJAJ0Z6Sdt3utnbzr/jh+NAHoyWHJe8CMSy79Gm085094M9nvTPy22KzTVn5Zq5mbapCI/hPA==} + + typescript-auto-import-cache@0.3.5: + resolution: {integrity: sha512-fAIveQKsoYj55CozUiBoj4b/7WpN0i4o74wiGY5JVUEoD0XiqDk1tJqTEjgzL2/AizKQrXxyRosSebyDzBZKjw==} + typescript@5.7.2: resolution: {integrity: sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==} engines: {node: '>=14.17'} @@ -621,10 +1716,43 @@ packages: ufo@1.5.4: resolution: {integrity: sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==} + undici-types@5.26.5: + resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + undici@6.21.0: resolution: {integrity: sha512-BUgJXc752Kou3oOIuU1i+yZZypyZRqNPW0vqoMPl8VaoalSfeR0D8/t4iAS3yirs79SSMTxTag+ZC86uswv+Cw==} engines: {node: '>=18.17'} + unified@11.0.5: + resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==} + + unist-util-find-after@5.0.0: + resolution: {integrity: sha512-amQa0Ep2m6hE2g72AugUItjbuM8X8cGQnFoHk0pGfrFeT9GZhzN5SW8nRsiGKK7Aif4CrACPENkA6P/Lw6fHGQ==} + + unist-util-is@6.0.0: + resolution: {integrity: sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==} + + unist-util-modify-children@4.0.0: + resolution: {integrity: sha512-+tdN5fGNddvsQdIzUF3Xx82CU9sMM+fA0dLgR9vOmT0oPT2jH+P1nd5lSqfCfXAw+93NhcXNY2qqvTUtE4cQkw==} + + unist-util-position@5.0.0: + resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==} + + unist-util-remove-position@5.0.0: + resolution: {integrity: sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q==} + + unist-util-stringify-position@4.0.0: + resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==} + + unist-util-visit-children@3.0.0: + resolution: {integrity: sha512-RgmdTfSBOg04sdPcpTSD1jzoNBjt9a80/ZCzp5cI9n1qPzLZWF9YdvWGN2zmTumP1HWhXKdUWexjy/Wy/lJ7tA==} + + 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==} + universal-user-agent@6.0.1: resolution: {integrity: sha512-yCzhz6FN2wU1NiiQRogkTQszlQSlpWaw8SvVegAc+bDxbzHgh1vX8uIe8OYyMH6DwH+sdTJsgMl36+mSMdRJIQ==} @@ -632,6 +1760,10 @@ packages: resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} engines: {node: '>= 4.0.0'} + universalify@2.0.1: + resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} + engines: {node: '>= 10.0.0'} + url-join@5.0.0: resolution: {integrity: sha512-n2huDr9h9yzd6exQVnH/jU5mr+Pfx08LRXXZhkLLetAMESRj+anQsTAh940iMrIetKAmry9coFuZQ2jY8/p3WA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -640,6 +1772,185 @@ packages: resolution: {integrity: sha512-OljLrQ9SQdOUqTaQxqL5dEfZWrXExyyWsozYlAWFawPVNuD83igl7uJD2RTkNMbniIYgt8l81eCJGIdQF7avLQ==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + vfile-location@5.0.3: + resolution: {integrity: sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==} + + 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@2.1.8: + resolution: {integrity: sha512-uPAwSr57kYjAUux+8E2j0q0Fxpn8M9VoyfGiRI8Kfktz9NcYMCenwY5RnZxnF1WTu3TGiYipirIzacLL3VVGFg==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + + vite@5.4.11: + resolution: {integrity: sha512-c7jFQRklXua0mTzneGW9QVyxFjUgwcihC4bXEtujIo2ouWCe1Ajt/amn2PCxYnhYfd5k09JX3SB7OYWFKYqj8Q==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || >=20.0.0 + less: '*' + lightningcss: ^1.21.0 + sass: '*' + sass-embedded: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + + vitest@2.1.8: + resolution: {integrity: sha512-1vBKTZskHw/aosXqQUlVWWlGUxSJR8YtiyZDJAFeW2kPAeX6S3Sool0mjspO+kXLuxVWlEDDowBAeqeAQefqLQ==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@types/node': ^18.0.0 || >=20.0.0 + '@vitest/browser': 2.1.8 + '@vitest/ui': 2.1.8 + happy-dom: '*' + jsdom: '*' + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@types/node': + optional: true + '@vitest/browser': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + + volar-service-css@0.0.62: + resolution: {integrity: sha512-JwNyKsH3F8PuzZYuqPf+2e+4CTU8YoyUHEHVnoXNlrLe7wy9U3biomZ56llN69Ris7TTy/+DEX41yVxQpM4qvg==} + peerDependencies: + '@volar/language-service': ~2.4.0 + peerDependenciesMeta: + '@volar/language-service': + optional: true + + volar-service-emmet@0.0.62: + resolution: {integrity: sha512-U4dxWDBWz7Pi4plpbXf4J4Z/ss6kBO3TYrACxWNsE29abu75QzVS0paxDDhI6bhqpbDFXlpsDhZ9aXVFpnfGRQ==} + peerDependencies: + '@volar/language-service': ~2.4.0 + peerDependenciesMeta: + '@volar/language-service': + optional: true + + volar-service-html@0.0.62: + resolution: {integrity: sha512-Zw01aJsZRh4GTGUjveyfEzEqpULQUdQH79KNEiKVYHZyuGtdBRYCHlrus1sueSNMxwwkuF5WnOHfvBzafs8yyQ==} + peerDependencies: + '@volar/language-service': ~2.4.0 + peerDependenciesMeta: + '@volar/language-service': + optional: true + + volar-service-prettier@0.0.62: + resolution: {integrity: sha512-h2yk1RqRTE+vkYZaI9KYuwpDfOQRrTEMvoHol0yW4GFKc75wWQRrb5n/5abDrzMPrkQbSip8JH2AXbvrRtYh4w==} + peerDependencies: + '@volar/language-service': ~2.4.0 + prettier: ^2.2 || ^3.0 + peerDependenciesMeta: + '@volar/language-service': + optional: true + prettier: + optional: true + + volar-service-typescript-twoslash-queries@0.0.62: + resolution: {integrity: sha512-KxFt4zydyJYYI0kFAcWPTh4u0Ha36TASPZkAnNY784GtgajerUqM80nX/W1d0wVhmcOFfAxkVsf/Ed+tiYU7ng==} + peerDependencies: + '@volar/language-service': ~2.4.0 + peerDependenciesMeta: + '@volar/language-service': + optional: true + + volar-service-typescript@0.0.62: + resolution: {integrity: sha512-p7MPi71q7KOsH0eAbZwPBiKPp9B2+qrdHAd6VY5oTo9BUXatsOAdakTm9Yf0DUj6uWBAaOT01BSeVOPwucMV1g==} + peerDependencies: + '@volar/language-service': ~2.4.0 + peerDependenciesMeta: + '@volar/language-service': + optional: true + + volar-service-yaml@0.0.62: + resolution: {integrity: sha512-k7gvv7sk3wa+nGll3MaSKyjwQsJjIGCHFjVkl3wjaSP2nouKyn9aokGmqjrl39mi88Oy49giog2GkZH526wjig==} + peerDependencies: + '@volar/language-service': ~2.4.0 + peerDependenciesMeta: + '@volar/language-service': + optional: true + + vscode-css-languageservice@6.3.2: + resolution: {integrity: sha512-GEpPxrUTAeXWdZWHev1OJU9lz2Q2/PPBxQ2TIRmLGvQiH3WZbqaNoute0n0ewxlgtjzTW3AKZT+NHySk5Rf4Eg==} + + vscode-html-languageservice@5.3.1: + resolution: {integrity: sha512-ysUh4hFeW/WOWz/TO9gm08xigiSsV/FOAZ+DolgJfeLftna54YdmZ4A+lIn46RbdO3/Qv5QHTn1ZGqmrXQhZyA==} + + vscode-json-languageservice@4.1.8: + resolution: {integrity: sha512-0vSpg6Xd9hfV+eZAaYN63xVVMOTmJ4GgHxXnkLCh+9RsQBkWKIghzLhW2B9ebfG+LQQg8uLtsQ2aUKjTgE+QOg==} + engines: {npm: '>=7.0.0'} + + vscode-jsonrpc@6.0.0: + resolution: {integrity: sha512-wnJA4BnEjOSyFMvjZdpiOwhSq9uDoK8e/kpRJDTaMYzwlkrhG1fwDIZI94CLsLzlCK5cIbMMtFlJlfR57Lavmg==} + engines: {node: '>=8.0.0 || >=10.0.0'} + + vscode-jsonrpc@8.2.0: + resolution: {integrity: sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA==} + engines: {node: '>=14.0.0'} + + vscode-languageserver-protocol@3.16.0: + resolution: {integrity: sha512-sdeUoAawceQdgIfTI+sdcwkiK2KU+2cbEYA0agzM2uqaUy2UpnnGHtWTHVEtS0ES4zHU0eMFRGN+oQgDxlD66A==} + + vscode-languageserver-protocol@3.17.5: + resolution: {integrity: sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg==} + + vscode-languageserver-textdocument@1.0.12: + resolution: {integrity: sha512-cxWNPesCnQCcMPeenjKKsOCKQZ/L6Tv19DTRIGuLWe32lyzWhihGVJ/rcckZXJxfdKCFvRLS3fpBIsV/ZGX4zA==} + + vscode-languageserver-types@3.16.0: + resolution: {integrity: sha512-k8luDIWJWyenLc5ToFQQMaSrqCHiLwyKPHKPQZ5zz21vM+vIVUSvsRpcbiECH4WR88K2XZqc4ScRcZ7nk/jbeA==} + + vscode-languageserver-types@3.17.5: + resolution: {integrity: sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==} + + vscode-languageserver@7.0.0: + resolution: {integrity: sha512-60HTx5ID+fLRcgdHfmz0LDZAXYEV68fzwG0JWwEPBode9NuMYTIxuYXPg4ngO8i8+Ou0lM7y6GzaYWbiDL0drw==} + hasBin: true + + vscode-languageserver@9.0.1: + resolution: {integrity: sha512-woByF3PDpkHFUreUa7Hos7+pUWdeWMXRd26+ZX2A8cFx6v/JPTtd4/uN0/jB6XQHYaOlHbio03NTHCqrgG5n7g==} + hasBin: true + + vscode-nls@5.2.0: + resolution: {integrity: sha512-RAaHx7B14ZU04EU31pT+rKz2/zSl7xMsfIZuo8pd+KZO6PXtQmpevpq3vxvWNcrGbdmhM/rr5Uw5Mz+NBfhVng==} + + vscode-uri@3.0.8: + resolution: {integrity: sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw==} + + web-namespaces@2.0.1: + resolution: {integrity: sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==} + webidl-conversions@3.0.1: resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} @@ -651,9 +1962,47 @@ packages: engines: {node: '>= 8'} hasBin: true + why-is-node-running@2.3.0: + resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} + engines: {node: '>=8'} + hasBin: true + + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + + yaml-language-server@1.15.0: + resolution: {integrity: sha512-N47AqBDCMQmh6mBLmI6oqxryHRzi33aPFPsJhYy3VTUGCdLHYjGh4FZzpUjRlphaADBBkDmnkM/++KNIOHi5Rw==} + hasBin: true + + yaml@2.2.2: + resolution: {integrity: sha512-CBKFWExMn46Foo4cldiChEzn7S7SRV+wqiluAb6xmueD/fGyRHIhX8m14vVGgeFWjN540nKCNVj6P21eQjgTuA==} + engines: {node: '>= 14'} + + yaml@2.7.0: + resolution: {integrity: sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA==} + engines: {node: '>= 14'} + hasBin: true + + yargs-parser@21.1.1: + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} + + yargs@17.7.2: + resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} + engines: {node: '>=12'} + + yocto-queue@1.1.1: + resolution: {integrity: sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g==} + engines: {node: '>=12.20'} + zod-package-json@1.0.3: resolution: {integrity: sha512-Mb6GzuRyUEl8X+6V6xzHbd4XV0au/4gOYrYP+CAfHL32uPmGswES+v2YqonZiW1NZWVA3jkssCKSU2knonm/aQ==} engines: {node: '>=20'} @@ -661,8 +2010,55 @@ packages: zod@3.23.8: resolution: {integrity: sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==} + zwitch@2.0.4: + resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} + snapshots: + '@astrojs/check@0.9.4(typescript@5.7.2)': + dependencies: + '@astrojs/language-server': 2.15.4(typescript@5.7.2) + chokidar: 4.0.3 + kleur: 4.1.5 + typescript: 5.7.2 + yargs: 17.7.2 + transitivePeerDependencies: + - prettier + - prettier-plugin-astro + + '@astrojs/compiler@2.10.3': {} + + '@astrojs/language-server@2.15.4(typescript@5.7.2)': + dependencies: + '@astrojs/compiler': 2.10.3 + '@astrojs/yaml2ts': 0.2.2 + '@jridgewell/sourcemap-codec': 1.5.0 + '@volar/kit': 2.4.11(typescript@5.7.2) + '@volar/language-core': 2.4.11 + '@volar/language-server': 2.4.11 + '@volar/language-service': 2.4.11 + fast-glob: 3.3.2 + muggle-string: 0.4.1 + volar-service-css: 0.0.62(@volar/language-service@2.4.11) + volar-service-emmet: 0.0.62(@volar/language-service@2.4.11) + volar-service-html: 0.0.62(@volar/language-service@2.4.11) + volar-service-prettier: 0.0.62(@volar/language-service@2.4.11) + volar-service-typescript: 0.0.62(@volar/language-service@2.4.11) + volar-service-typescript-twoslash-queries: 0.0.62(@volar/language-service@2.4.11) + volar-service-yaml: 0.0.62(@volar/language-service@2.4.11) + vscode-html-languageservice: 5.3.1 + vscode-uri: 3.0.8 + transitivePeerDependencies: + - typescript + + '@astrojs/prism@3.2.0': + dependencies: + prismjs: 1.29.0 + + '@astrojs/yaml2ts@0.2.2': + dependencies: + yaml: 2.7.0 + '@babel/runtime@7.26.0': dependencies: regenerator-runtime: 0.14.1 @@ -859,6 +2255,100 @@ snapshots: human-id: 1.0.2 prettier: 2.8.8 + '@emmetio/abbreviation@2.3.3': + dependencies: + '@emmetio/scanner': 1.0.4 + + '@emmetio/css-abbreviation@2.1.8': + dependencies: + '@emmetio/scanner': 1.0.4 + + '@emmetio/css-parser@0.4.0': + dependencies: + '@emmetio/stream-reader': 2.2.0 + '@emmetio/stream-reader-utils': 0.1.0 + + '@emmetio/html-matcher@1.3.0': + dependencies: + '@emmetio/scanner': 1.0.4 + + '@emmetio/scanner@1.0.4': {} + + '@emmetio/stream-reader-utils@0.1.0': {} + + '@emmetio/stream-reader@2.2.0': {} + + '@esbuild/aix-ppc64@0.21.5': + optional: true + + '@esbuild/android-arm64@0.21.5': + optional: true + + '@esbuild/android-arm@0.21.5': + optional: true + + '@esbuild/android-x64@0.21.5': + optional: true + + '@esbuild/darwin-arm64@0.21.5': + optional: true + + '@esbuild/darwin-x64@0.21.5': + optional: true + + '@esbuild/freebsd-arm64@0.21.5': + optional: true + + '@esbuild/freebsd-x64@0.21.5': + optional: true + + '@esbuild/linux-arm64@0.21.5': + optional: true + + '@esbuild/linux-arm@0.21.5': + optional: true + + '@esbuild/linux-ia32@0.21.5': + optional: true + + '@esbuild/linux-loong64@0.21.5': + optional: true + + '@esbuild/linux-mips64el@0.21.5': + optional: true + + '@esbuild/linux-ppc64@0.21.5': + optional: true + + '@esbuild/linux-riscv64@0.21.5': + optional: true + + '@esbuild/linux-s390x@0.21.5': + optional: true + + '@esbuild/linux-x64@0.21.5': + optional: true + + '@esbuild/netbsd-x64@0.21.5': + optional: true + + '@esbuild/openbsd-x64@0.21.5': + optional: true + + '@esbuild/sunos-x64@0.21.5': + optional: true + + '@esbuild/win32-arm64@0.21.5': + optional: true + + '@esbuild/win32-ia32@0.21.5': + optional: true + + '@esbuild/win32-x64@0.21.5': + optional: true + + '@jridgewell/sourcemap-codec@1.5.0': {} + '@jsdevtools/ez-spawn@3.0.4': dependencies: call-me-maybe: 1.0.2 @@ -966,36 +2456,333 @@ snapshots: dependencies: '@octokit/openapi-types': 22.2.0 + '@rollup/rollup-android-arm-eabi@4.29.1': + optional: true + + '@rollup/rollup-android-arm64@4.29.1': + optional: true + + '@rollup/rollup-darwin-arm64@4.29.1': + optional: true + + '@rollup/rollup-darwin-x64@4.29.1': + optional: true + + '@rollup/rollup-freebsd-arm64@4.29.1': + optional: true + + '@rollup/rollup-freebsd-x64@4.29.1': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.29.1': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.29.1': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.29.1': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.29.1': + optional: true + + '@rollup/rollup-linux-loongarch64-gnu@4.29.1': + optional: true + + '@rollup/rollup-linux-powerpc64le-gnu@4.29.1': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.29.1': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.29.1': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.29.1': + optional: true + + '@rollup/rollup-linux-x64-musl@4.29.1': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.29.1': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.29.1': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.29.1': + optional: true + + '@shikijs/core@1.25.1': + dependencies: + '@shikijs/engine-javascript': 1.25.1 + '@shikijs/engine-oniguruma': 1.25.1 + '@shikijs/types': 1.25.1 + '@shikijs/vscode-textmate': 9.3.1 + '@types/hast': 3.0.4 + hast-util-to-html: 9.0.4 + + '@shikijs/engine-javascript@1.25.1': + dependencies: + '@shikijs/types': 1.25.1 + '@shikijs/vscode-textmate': 9.3.1 + oniguruma-to-es: 0.10.0 + + '@shikijs/engine-oniguruma@1.25.1': + dependencies: + '@shikijs/types': 1.25.1 + '@shikijs/vscode-textmate': 9.3.1 + + '@shikijs/langs@1.25.1': + dependencies: + '@shikijs/types': 1.25.1 + + '@shikijs/themes@1.25.1': + dependencies: + '@shikijs/types': 1.25.1 + + '@shikijs/types@1.25.1': + dependencies: + '@shikijs/vscode-textmate': 9.3.1 + '@types/hast': 3.0.4 + + '@shikijs/vscode-textmate@9.3.1': {} + + '@types/debug@4.1.12': + dependencies: + '@types/ms': 0.7.34 + + '@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/js-yaml@4.0.9': {} + + '@types/mdast@4.0.4': + dependencies: + '@types/unist': 3.0.3 + + '@types/ms@0.7.34': {} + + '@types/nlcst@2.0.3': + dependencies: + '@types/unist': 3.0.3 + '@types/node@12.20.55': {} + '@types/node@18.19.69': + dependencies: + undici-types: 5.26.5 + + '@types/unist@3.0.3': {} + + '@ungap/structured-clone@1.2.1': {} + + '@vitest/expect@2.1.8': + dependencies: + '@vitest/spy': 2.1.8 + '@vitest/utils': 2.1.8 + chai: 5.1.2 + tinyrainbow: 1.2.0 + + '@vitest/mocker@2.1.8(vite@5.4.11(@types/node@18.19.69))': + dependencies: + '@vitest/spy': 2.1.8 + estree-walker: 3.0.3 + magic-string: 0.30.17 + optionalDependencies: + vite: 5.4.11(@types/node@18.19.69) + + '@vitest/pretty-format@2.1.8': + dependencies: + tinyrainbow: 1.2.0 + + '@vitest/runner@2.1.8': + dependencies: + '@vitest/utils': 2.1.8 + pathe: 1.1.2 + + '@vitest/snapshot@2.1.8': + dependencies: + '@vitest/pretty-format': 2.1.8 + magic-string: 0.30.17 + pathe: 1.1.2 + + '@vitest/spy@2.1.8': + dependencies: + tinyspy: 3.0.2 + + '@vitest/utils@2.1.8': + dependencies: + '@vitest/pretty-format': 2.1.8 + loupe: 3.1.2 + tinyrainbow: 1.2.0 + + '@volar/kit@2.4.11(typescript@5.7.2)': + dependencies: + '@volar/language-service': 2.4.11 + '@volar/typescript': 2.4.11 + typesafe-path: 0.2.2 + typescript: 5.7.2 + vscode-languageserver-textdocument: 1.0.12 + vscode-uri: 3.0.8 + + '@volar/language-core@2.4.11': + dependencies: + '@volar/source-map': 2.4.11 + + '@volar/language-server@2.4.11': + dependencies: + '@volar/language-core': 2.4.11 + '@volar/language-service': 2.4.11 + '@volar/typescript': 2.4.11 + path-browserify: 1.0.1 + request-light: 0.7.0 + vscode-languageserver: 9.0.1 + vscode-languageserver-protocol: 3.17.5 + vscode-languageserver-textdocument: 1.0.12 + vscode-uri: 3.0.8 + + '@volar/language-service@2.4.11': + dependencies: + '@volar/language-core': 2.4.11 + vscode-languageserver-protocol: 3.17.5 + vscode-languageserver-textdocument: 1.0.12 + vscode-uri: 3.0.8 + + '@volar/source-map@2.4.11': {} + + '@volar/typescript@2.4.11': + dependencies: + '@volar/language-core': 2.4.11 + path-browserify: 1.0.1 + vscode-uri: 3.0.8 + + '@vscode/emmet-helper@2.11.0': + dependencies: + emmet: 2.4.11 + jsonc-parser: 2.3.1 + vscode-languageserver-textdocument: 1.0.12 + vscode-languageserver-types: 3.17.5 + vscode-uri: 3.0.8 + + '@vscode/l10n@0.0.18': {} + acorn@8.14.0: {} + ajv@8.17.1: + dependencies: + fast-deep-equal: 3.1.3 + fast-uri: 3.0.3 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + ansi-colors@4.1.3: {} ansi-regex@5.0.1: {} + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + anymatch@3.1.3: + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + argparse@1.0.10: dependencies: sprintf-js: 1.0.3 + argparse@2.0.1: {} + + array-iterate@2.0.1: {} + array-union@2.1.0: {} + assertion-error@2.0.1: {} + + bail@2.0.2: {} + before-after-hook@2.2.3: {} better-path-resolve@1.0.0: dependencies: is-windows: 1.0.2 + binary-extensions@2.3.0: {} + braces@3.0.3: dependencies: fill-range: 7.1.1 + cac@6.7.14: {} + call-me-maybe@1.0.2: {} + ccount@2.0.1: {} + + chai@5.1.2: + dependencies: + assertion-error: 2.0.1 + check-error: 2.1.1 + deep-eql: 5.0.2 + loupe: 3.1.2 + pathval: 2.0.0 + + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + character-entities-html4@2.1.0: {} + + character-entities-legacy@3.0.0: {} + + character-entities@2.0.2: {} + chardet@0.7.0: {} + check-error@2.1.1: {} + + chokidar@3.6.0: + dependencies: + anymatch: 3.1.3 + braces: 3.0.3 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + + chokidar@4.0.3: + dependencies: + readdirp: 4.0.2 + ci-info@3.9.0: {} + cliui@8.0.1: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + + comma-separated-tokens@2.0.3: {} + confbox@0.1.8: {} cross-spawn@7.0.6: @@ -1006,25 +2793,100 @@ snapshots: dataloader@1.4.0: {} + debug@4.4.0: + dependencies: + ms: 2.1.3 + + decode-named-character-reference@1.0.2: + dependencies: + character-entities: 2.0.2 + decode-uri-component@0.4.1: {} + deep-eql@5.0.2: {} + deprecation@2.3.1: {} + dequal@2.0.3: {} + detect-indent@6.1.0: {} + devlop@1.1.0: + dependencies: + dequal: 2.0.3 + dir-glob@3.0.1: dependencies: path-type: 4.0.0 dotenv@8.6.0: {} + emmet@2.4.11: + dependencies: + '@emmetio/abbreviation': 2.3.3 + '@emmetio/css-abbreviation': 2.1.8 + + emoji-regex-xs@1.0.0: {} + + emoji-regex@8.0.0: {} + enquirer@2.4.1: dependencies: ansi-colors: 4.1.3 strip-ansi: 6.0.1 + entities@4.5.0: {} + + es-module-lexer@1.6.0: {} + + esbuild-plugin-copy@2.1.1(esbuild@0.21.5): + dependencies: + chalk: 4.1.2 + chokidar: 3.6.0 + esbuild: 0.21.5 + fs-extra: 10.1.0 + globby: 11.1.0 + + esbuild@0.21.5: + optionalDependencies: + '@esbuild/aix-ppc64': 0.21.5 + '@esbuild/android-arm': 0.21.5 + '@esbuild/android-arm64': 0.21.5 + '@esbuild/android-x64': 0.21.5 + '@esbuild/darwin-arm64': 0.21.5 + '@esbuild/darwin-x64': 0.21.5 + '@esbuild/freebsd-arm64': 0.21.5 + '@esbuild/freebsd-x64': 0.21.5 + '@esbuild/linux-arm': 0.21.5 + '@esbuild/linux-arm64': 0.21.5 + '@esbuild/linux-ia32': 0.21.5 + '@esbuild/linux-loong64': 0.21.5 + '@esbuild/linux-mips64el': 0.21.5 + '@esbuild/linux-ppc64': 0.21.5 + '@esbuild/linux-riscv64': 0.21.5 + '@esbuild/linux-s390x': 0.21.5 + '@esbuild/linux-x64': 0.21.5 + '@esbuild/netbsd-x64': 0.21.5 + '@esbuild/openbsd-x64': 0.21.5 + '@esbuild/sunos-x64': 0.21.5 + '@esbuild/win32-arm64': 0.21.5 + '@esbuild/win32-ia32': 0.21.5 + '@esbuild/win32-x64': 0.21.5 + + escalade@3.2.0: {} + + escape-string-regexp@5.0.0: {} + esprima@4.0.1: {} + estree-walker@3.0.3: + dependencies: + '@types/estree': 1.0.6 + + expect-type@1.1.0: {} + + extend@3.0.2: {} + extendable-error@0.1.7: {} external-editor@3.1.0: @@ -1033,6 +2895,8 @@ snapshots: iconv-lite: 0.4.24 tmp: 0.0.33 + fast-deep-equal@3.1.3: {} + fast-glob@3.3.2: dependencies: '@nodelib/fs.stat': 2.0.5 @@ -1041,6 +2905,8 @@ snapshots: merge2: 1.4.1 micromatch: 4.0.8 + fast-uri@3.0.3: {} + fastq@1.17.1: dependencies: reusify: 1.0.4 @@ -1060,6 +2926,12 @@ snapshots: locate-path: 5.0.0 path-exists: 4.0.0 + fs-extra@10.1.0: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.1.0 + universalify: 2.0.1 + fs-extra@7.0.1: dependencies: graceful-fs: 4.2.11 @@ -1072,6 +2944,13 @@ snapshots: jsonfile: 4.0.0 universalify: 0.1.2 + fsevents@2.3.3: + optional: true + + get-caller-file@2.0.5: {} + + github-slugger@2.0.0: {} + glob-parent@5.1.2: dependencies: is-glob: 4.0.3 @@ -1087,6 +2966,97 @@ snapshots: graceful-fs@4.2.11: {} + has-flag@4.0.0: {} + + hast-util-from-html@2.0.3: + dependencies: + '@types/hast': 3.0.4 + devlop: 1.1.0 + hast-util-from-parse5: 8.0.2 + parse5: 7.2.1 + vfile: 6.0.3 + vfile-message: 4.0.2 + + hast-util-from-parse5@8.0.2: + dependencies: + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + devlop: 1.1.0 + hastscript: 9.0.0 + property-information: 6.5.0 + vfile: 6.0.3 + vfile-location: 5.0.3 + web-namespaces: 2.0.1 + + hast-util-is-element@3.0.0: + dependencies: + '@types/hast': 3.0.4 + + hast-util-parse-selector@4.0.0: + dependencies: + '@types/hast': 3.0.4 + + hast-util-raw@9.1.0: + dependencies: + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + '@ungap/structured-clone': 1.2.1 + hast-util-from-parse5: 8.0.2 + hast-util-to-parse5: 8.0.0 + html-void-elements: 3.0.0 + mdast-util-to-hast: 13.2.0 + parse5: 7.2.1 + unist-util-position: 5.0.0 + unist-util-visit: 5.0.0 + vfile: 6.0.3 + web-namespaces: 2.0.1 + zwitch: 2.0.4 + + hast-util-to-html@9.0.4: + dependencies: + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + ccount: 2.0.1 + comma-separated-tokens: 2.0.3 + hast-util-whitespace: 3.0.0 + html-void-elements: 3.0.0 + mdast-util-to-hast: 13.2.0 + property-information: 6.5.0 + space-separated-tokens: 2.0.2 + stringify-entities: 4.0.4 + zwitch: 2.0.4 + + hast-util-to-parse5@8.0.0: + dependencies: + '@types/hast': 3.0.4 + comma-separated-tokens: 2.0.3 + devlop: 1.1.0 + property-information: 6.5.0 + space-separated-tokens: 2.0.2 + web-namespaces: 2.0.1 + zwitch: 2.0.4 + + hast-util-to-text@4.0.2: + dependencies: + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + hast-util-is-element: 3.0.0 + unist-util-find-after: 5.0.0 + + hast-util-whitespace@3.0.0: + dependencies: + '@types/hast': 3.0.4 + + hastscript@9.0.0: + dependencies: + '@types/hast': 3.0.4 + comma-separated-tokens: 2.0.3 + hast-util-parse-selector: 4.0.0 + property-information: 6.5.0 + space-separated-tokens: 2.0.2 + + html-void-elements@3.0.0: {} + human-id@1.0.2: {} iconv-lite@0.4.24: @@ -1095,14 +3065,24 @@ snapshots: ignore@5.3.2: {} - is-extglob@2.1.1: {} + import-meta-resolve@4.1.0: {} - is-glob@4.0.3: + is-binary-path@2.1.0: dependencies: - is-extglob: 2.1.1 + binary-extensions: 2.3.0 + + is-extglob@2.1.1: {} + + is-fullwidth-code-point@3.0.0: {} + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 is-number@7.0.0: {} + is-plain-obj@4.1.0: {} + is-subdir@1.2.0: dependencies: better-path-resolve: 1.0.0 @@ -1118,18 +3098,370 @@ snapshots: argparse: 1.0.10 esprima: 4.0.1 + js-yaml@4.1.0: + dependencies: + argparse: 2.0.1 + + json-schema-traverse@1.0.0: {} + + jsonc-parser@2.3.1: {} + + jsonc-parser@3.3.1: {} + jsonfile@4.0.0: optionalDependencies: graceful-fs: 4.2.11 + jsonfile@6.1.0: + dependencies: + universalify: 2.0.1 + optionalDependencies: + graceful-fs: 4.2.11 + + kleur@4.1.5: {} + locate-path@5.0.0: dependencies: p-locate: 4.1.0 lodash.startcase@4.4.0: {} + lodash@4.17.21: {} + + longest-streak@3.1.0: {} + + loupe@3.1.2: {} + + magic-string@0.30.17: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.0 + + markdown-table@3.0.4: {} + + mdast-util-definitions@6.0.0: + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + unist-util-visit: 5.0.0 + + mdast-util-find-and-replace@3.0.1: + dependencies: + '@types/mdast': 4.0.4 + escape-string-regexp: 5.0.0 + unist-util-is: 6.0.0 + unist-util-visit-parents: 6.0.1 + + mdast-util-from-markdown@2.0.2: + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + decode-named-character-reference: 1.0.2 + devlop: 1.1.0 + mdast-util-to-string: 4.0.0 + micromark: 4.0.1 + 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.1 + unist-util-stringify-position: 4.0.0 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-autolink-literal@2.0.1: + dependencies: + '@types/mdast': 4.0.4 + ccount: 2.0.1 + devlop: 1.1.0 + mdast-util-find-and-replace: 3.0.1 + micromark-util-character: 2.1.1 + + mdast-util-gfm-footnote@2.0.0: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + micromark-util-normalize-identifier: 2.0.1 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-strikethrough@2.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-table@2.0.0: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + markdown-table: 3.0.4 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-task-list-item@2.0.0: + dependencies: + '@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-gfm@3.0.0: + dependencies: + mdast-util-from-markdown: 2.0.2 + mdast-util-gfm-autolink-literal: 2.0.1 + mdast-util-gfm-footnote: 2.0.0 + mdast-util-gfm-strikethrough: 2.0.0 + mdast-util-gfm-table: 2.0.0 + mdast-util-gfm-task-list-item: 2.0.0 + mdast-util-to-markdown: 2.1.2 + 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-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.2.1 + 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 + merge2@1.4.1: {} + micromark-core-commonmark@2.0.2: + dependencies: + decode-named-character-reference: 1.0.2 + 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.0.3 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.1 + + micromark-extension-gfm-autolink-literal@2.1.0: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.1 + + micromark-extension-gfm-footnote@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-core-commonmark: 2.0.2 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.1 + + micromark-extension-gfm-strikethrough@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-util-chunked: 2.0.1 + micromark-util-classify-character: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.1 + + micromark-extension-gfm-table@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.1 + + micromark-extension-gfm-tagfilter@2.0.0: + dependencies: + micromark-util-types: 2.0.1 + + micromark-extension-gfm-task-list-item@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.1 + + micromark-extension-gfm@3.0.0: + dependencies: + micromark-extension-gfm-autolink-literal: 2.1.0 + micromark-extension-gfm-footnote: 2.1.0 + micromark-extension-gfm-strikethrough: 2.1.0 + micromark-extension-gfm-table: 2.1.0 + micromark-extension-gfm-tagfilter: 2.0.0 + micromark-extension-gfm-task-list-item: 2.1.0 + micromark-util-combine-extensions: 2.0.1 + micromark-util-types: 2.0.1 + + micromark-factory-destination@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.1 + + 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.1 + + micromark-factory-space@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-types: 2.0.1 + + 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.1 + + 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.1 + + micromark-util-character@2.1.1: + dependencies: + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.1 + + 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.1 + + micromark-util-combine-extensions@2.0.1: + dependencies: + micromark-util-chunked: 2.0.1 + micromark-util-types: 2.0.1 + + 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.0.2 + 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-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.1 + + 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.0.3: + dependencies: + devlop: 1.1.0 + micromark-util-chunked: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.1 + + micromark-util-symbol@2.0.1: {} + + micromark-util-types@2.0.1: {} + + micromark@4.0.1: + dependencies: + '@types/debug': 4.1.12 + debug: 4.4.0 + decode-named-character-reference: 1.0.2 + devlop: 1.1.0 + micromark-core-commonmark: 2.0.2 + 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.0.3 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.1 + transitivePeerDependencies: + - supports-color + micromatch@4.0.8: dependencies: braces: 3.0.3 @@ -1144,14 +3476,32 @@ snapshots: mri@1.2.0: {} + ms@2.1.3: {} + + muggle-string@0.4.1: {} + + nanoid@3.3.8: {} + + nlcst-to-string@4.0.0: + dependencies: + '@types/nlcst': 2.0.3 + node-fetch@2.7.0: dependencies: whatwg-url: 5.0.0 + normalize-path@3.0.0: {} + once@1.4.0: dependencies: wrappy: 1.0.2 + oniguruma-to-es@0.10.0: + dependencies: + emoji-regex-xs: 1.0.0 + regex: 5.1.1 + regex-recursion: 5.1.1 + os-tmpdir@1.0.2: {} outdent@0.5.0: {} @@ -1164,6 +3514,10 @@ snapshots: dependencies: p-try: 2.2.0 + p-limit@6.2.0: + dependencies: + yocto-queue: 1.1.1 + p-locate@4.1.0: dependencies: p-limit: 2.3.0 @@ -1174,6 +3528,21 @@ snapshots: package-manager-detector@0.2.7: {} + parse-latin@7.0.0: + dependencies: + '@types/nlcst': 2.0.3 + '@types/unist': 3.0.3 + nlcst-to-string: 4.0.0 + unist-util-modify-children: 4.0.0 + unist-util-visit-children: 3.0.0 + vfile: 6.0.3 + + parse5@7.2.1: + dependencies: + entities: 4.5.0 + + path-browserify@1.0.1: {} + path-exists@4.0.0: {} path-key@3.1.1: {} @@ -1182,6 +3551,8 @@ snapshots: pathe@1.1.2: {} + pathval@2.0.0: {} + picocolors@1.1.1: {} picomatch@2.3.1: {} @@ -1206,8 +3577,21 @@ snapshots: mlly: 1.7.3 pathe: 1.1.2 + postcss@8.4.49: + dependencies: + nanoid: 3.3.8 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + prettier@2.8.7: + optional: true + prettier@2.8.8: {} + prismjs@1.29.0: {} + + property-information@6.5.0: {} + query-registry@3.0.1: dependencies: query-string: 9.1.1 @@ -1234,12 +3618,140 @@ snapshots: pify: 4.0.1 strip-bom: 3.0.0 + readdirp@3.6.0: + dependencies: + picomatch: 2.3.1 + + readdirp@4.0.2: {} + regenerator-runtime@0.14.1: {} + regex-recursion@5.1.1: + dependencies: + regex: 5.1.1 + regex-utilities: 2.3.0 + + regex-utilities@2.3.0: {} + + regex@5.1.1: + dependencies: + regex-utilities: 2.3.0 + + rehype-raw@7.0.0: + dependencies: + '@types/hast': 3.0.4 + hast-util-raw: 9.1.0 + vfile: 6.0.3 + + rehype-stringify@10.0.1: + dependencies: + '@types/hast': 3.0.4 + hast-util-to-html: 9.0.4 + unified: 11.0.5 + + remark-gfm@4.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-gfm: 3.0.0 + micromark-extension-gfm: 3.0.0 + remark-parse: 11.0.0 + remark-stringify: 11.0.0 + unified: 11.0.5 + 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.1 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + + remark-rehype@11.1.1: + 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 + + remark-smartypants@3.0.2: + dependencies: + retext: 9.0.0 + retext-smartypants: 6.2.0 + unified: 11.0.5 + unist-util-visit: 5.0.0 + + remark-stringify@11.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-to-markdown: 2.1.2 + unified: 11.0.5 + + request-light@0.5.8: {} + + request-light@0.7.0: {} + + require-directory@2.1.1: {} + + require-from-string@2.0.2: {} + resolve-from@5.0.0: {} + retext-latin@4.0.0: + dependencies: + '@types/nlcst': 2.0.3 + parse-latin: 7.0.0 + unified: 11.0.5 + + retext-smartypants@6.2.0: + dependencies: + '@types/nlcst': 2.0.3 + nlcst-to-string: 4.0.0 + unist-util-visit: 5.0.0 + + retext-stringify@4.0.0: + dependencies: + '@types/nlcst': 2.0.3 + nlcst-to-string: 4.0.0 + unified: 11.0.5 + + retext@9.0.0: + dependencies: + '@types/nlcst': 2.0.3 + retext-latin: 4.0.0 + retext-stringify: 4.0.0 + unified: 11.0.5 + reusify@1.0.4: {} + rollup@4.29.1: + dependencies: + '@types/estree': 1.0.6 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.29.1 + '@rollup/rollup-android-arm64': 4.29.1 + '@rollup/rollup-darwin-arm64': 4.29.1 + '@rollup/rollup-darwin-x64': 4.29.1 + '@rollup/rollup-freebsd-arm64': 4.29.1 + '@rollup/rollup-freebsd-x64': 4.29.1 + '@rollup/rollup-linux-arm-gnueabihf': 4.29.1 + '@rollup/rollup-linux-arm-musleabihf': 4.29.1 + '@rollup/rollup-linux-arm64-gnu': 4.29.1 + '@rollup/rollup-linux-arm64-musl': 4.29.1 + '@rollup/rollup-linux-loongarch64-gnu': 4.29.1 + '@rollup/rollup-linux-powerpc64le-gnu': 4.29.1 + '@rollup/rollup-linux-riscv64-gnu': 4.29.1 + '@rollup/rollup-linux-s390x-gnu': 4.29.1 + '@rollup/rollup-linux-x64-gnu': 4.29.1 + '@rollup/rollup-linux-x64-musl': 4.29.1 + '@rollup/rollup-win32-arm64-msvc': 4.29.1 + '@rollup/rollup-win32-ia32-msvc': 4.29.1 + '@rollup/rollup-win32-x64-msvc': 4.29.1 + fsevents: 2.3.3 + run-parallel@1.2.0: dependencies: queue-microtask: 1.2.3 @@ -1254,10 +3766,27 @@ snapshots: shebang-regex@3.0.0: {} + shiki@1.25.1: + dependencies: + '@shikijs/core': 1.25.1 + '@shikijs/engine-javascript': 1.25.1 + '@shikijs/engine-oniguruma': 1.25.1 + '@shikijs/langs': 1.25.1 + '@shikijs/themes': 1.25.1 + '@shikijs/types': 1.25.1 + '@shikijs/vscode-textmate': 9.3.1 + '@types/hast': 3.0.4 + + siginfo@2.0.0: {} + signal-exit@4.1.0: {} slash@3.0.0: {} + source-map-js@1.2.1: {} + + space-separated-tokens@2.0.2: {} + spawndamnit@3.0.1: dependencies: cross-spawn: 7.0.6 @@ -1267,21 +3796,50 @@ snapshots: sprintf-js@1.0.3: {} + stackback@0.0.2: {} + + std-env@3.8.0: {} + string-argv@0.3.2: {} + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + 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 strip-bom@3.0.0: {} + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + term-size@2.2.1: {} + tinybench@2.9.0: {} + + tinyexec@0.3.2: {} + tinyglobby@0.2.10: dependencies: fdir: 6.4.2(picomatch@4.0.2) picomatch: 4.0.2 + tinypool@1.0.2: {} + + tinyrainbow@1.2.0: {} + + tinyspy@3.0.2: {} + tmp@0.0.33: dependencies: os-tmpdir: 1.0.2 @@ -1292,22 +3850,280 @@ snapshots: tr46@0.0.3: {} + trim-lines@3.0.1: {} + + trough@2.2.0: {} + + tsconfck@3.1.4(typescript@5.7.2): + optionalDependencies: + typescript: 5.7.2 + type-detect@4.1.0: {} + typesafe-path@0.2.2: {} + + typescript-auto-import-cache@0.3.5: + dependencies: + semver: 7.6.3 + typescript@5.7.2: {} ufo@1.5.4: {} + undici-types@5.26.5: {} + undici@6.21.0: {} + 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-find-after@5.0.0: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.0 + + unist-util-is@6.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-modify-children@4.0.0: + dependencies: + '@types/unist': 3.0.3 + array-iterate: 2.0.1 + + unist-util-position@5.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-remove-position@5.0.0: + dependencies: + '@types/unist': 3.0.3 + unist-util-visit: 5.0.0 + + unist-util-stringify-position@4.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-visit-children@3.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 + universal-user-agent@6.0.1: {} universalify@0.1.2: {} + universalify@2.0.1: {} + url-join@5.0.0: {} validate-npm-package-name@5.0.1: {} + vfile-location@5.0.3: + dependencies: + '@types/unist': 3.0.3 + vfile: 6.0.3 + + 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@2.1.8(@types/node@18.19.69): + dependencies: + cac: 6.7.14 + debug: 4.4.0 + es-module-lexer: 1.6.0 + pathe: 1.1.2 + vite: 5.4.11(@types/node@18.19.69) + transitivePeerDependencies: + - '@types/node' + - less + - lightningcss + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + + vite@5.4.11(@types/node@18.19.69): + dependencies: + esbuild: 0.21.5 + postcss: 8.4.49 + rollup: 4.29.1 + optionalDependencies: + '@types/node': 18.19.69 + fsevents: 2.3.3 + + vitest@2.1.8(@types/node@18.19.69): + dependencies: + '@vitest/expect': 2.1.8 + '@vitest/mocker': 2.1.8(vite@5.4.11(@types/node@18.19.69)) + '@vitest/pretty-format': 2.1.8 + '@vitest/runner': 2.1.8 + '@vitest/snapshot': 2.1.8 + '@vitest/spy': 2.1.8 + '@vitest/utils': 2.1.8 + chai: 5.1.2 + debug: 4.4.0 + expect-type: 1.1.0 + magic-string: 0.30.17 + pathe: 1.1.2 + std-env: 3.8.0 + tinybench: 2.9.0 + tinyexec: 0.3.2 + tinypool: 1.0.2 + tinyrainbow: 1.2.0 + vite: 5.4.11(@types/node@18.19.69) + vite-node: 2.1.8(@types/node@18.19.69) + why-is-node-running: 2.3.0 + optionalDependencies: + '@types/node': 18.19.69 + transitivePeerDependencies: + - less + - lightningcss + - msw + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + + volar-service-css@0.0.62(@volar/language-service@2.4.11): + dependencies: + vscode-css-languageservice: 6.3.2 + vscode-languageserver-textdocument: 1.0.12 + vscode-uri: 3.0.8 + optionalDependencies: + '@volar/language-service': 2.4.11 + + volar-service-emmet@0.0.62(@volar/language-service@2.4.11): + dependencies: + '@emmetio/css-parser': 0.4.0 + '@emmetio/html-matcher': 1.3.0 + '@vscode/emmet-helper': 2.11.0 + vscode-uri: 3.0.8 + optionalDependencies: + '@volar/language-service': 2.4.11 + + volar-service-html@0.0.62(@volar/language-service@2.4.11): + dependencies: + vscode-html-languageservice: 5.3.1 + vscode-languageserver-textdocument: 1.0.12 + vscode-uri: 3.0.8 + optionalDependencies: + '@volar/language-service': 2.4.11 + + volar-service-prettier@0.0.62(@volar/language-service@2.4.11): + dependencies: + vscode-uri: 3.0.8 + optionalDependencies: + '@volar/language-service': 2.4.11 + + volar-service-typescript-twoslash-queries@0.0.62(@volar/language-service@2.4.11): + dependencies: + vscode-uri: 3.0.8 + optionalDependencies: + '@volar/language-service': 2.4.11 + + volar-service-typescript@0.0.62(@volar/language-service@2.4.11): + dependencies: + path-browserify: 1.0.1 + semver: 7.6.3 + typescript-auto-import-cache: 0.3.5 + vscode-languageserver-textdocument: 1.0.12 + vscode-nls: 5.2.0 + vscode-uri: 3.0.8 + optionalDependencies: + '@volar/language-service': 2.4.11 + + volar-service-yaml@0.0.62(@volar/language-service@2.4.11): + dependencies: + vscode-uri: 3.0.8 + yaml-language-server: 1.15.0 + optionalDependencies: + '@volar/language-service': 2.4.11 + + vscode-css-languageservice@6.3.2: + dependencies: + '@vscode/l10n': 0.0.18 + vscode-languageserver-textdocument: 1.0.12 + vscode-languageserver-types: 3.17.5 + vscode-uri: 3.0.8 + + vscode-html-languageservice@5.3.1: + dependencies: + '@vscode/l10n': 0.0.18 + vscode-languageserver-textdocument: 1.0.12 + vscode-languageserver-types: 3.17.5 + vscode-uri: 3.0.8 + + vscode-json-languageservice@4.1.8: + dependencies: + jsonc-parser: 3.3.1 + vscode-languageserver-textdocument: 1.0.12 + vscode-languageserver-types: 3.17.5 + vscode-nls: 5.2.0 + vscode-uri: 3.0.8 + + vscode-jsonrpc@6.0.0: {} + + vscode-jsonrpc@8.2.0: {} + + vscode-languageserver-protocol@3.16.0: + dependencies: + vscode-jsonrpc: 6.0.0 + vscode-languageserver-types: 3.16.0 + + vscode-languageserver-protocol@3.17.5: + dependencies: + vscode-jsonrpc: 8.2.0 + vscode-languageserver-types: 3.17.5 + + vscode-languageserver-textdocument@1.0.12: {} + + vscode-languageserver-types@3.16.0: {} + + vscode-languageserver-types@3.17.5: {} + + vscode-languageserver@7.0.0: + dependencies: + vscode-languageserver-protocol: 3.16.0 + + vscode-languageserver@9.0.1: + dependencies: + vscode-languageserver-protocol: 3.17.5 + + vscode-nls@5.2.0: {} + + vscode-uri@3.0.8: {} + + web-namespaces@2.0.1: {} + webidl-conversions@3.0.1: {} whatwg-url@5.0.0: @@ -1319,10 +4135,58 @@ snapshots: dependencies: isexe: 2.0.0 + why-is-node-running@2.3.0: + dependencies: + siginfo: 2.0.0 + stackback: 0.0.2 + + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrappy@1.0.2: {} + y18n@5.0.8: {} + + yaml-language-server@1.15.0: + dependencies: + ajv: 8.17.1 + lodash: 4.17.21 + request-light: 0.5.8 + vscode-json-languageservice: 4.1.8 + vscode-languageserver: 7.0.0 + vscode-languageserver-textdocument: 1.0.12 + vscode-languageserver-types: 3.17.5 + vscode-nls: 5.2.0 + vscode-uri: 3.0.8 + yaml: 2.2.2 + optionalDependencies: + prettier: 2.8.7 + + yaml@2.2.2: {} + + yaml@2.7.0: {} + + yargs-parser@21.1.1: {} + + yargs@17.7.2: + dependencies: + cliui: 8.0.1 + escalade: 3.2.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 21.1.1 + + yocto-queue@1.1.1: {} + zod-package-json@1.0.3: dependencies: zod: 3.23.8 zod@3.23.8: {} + + zwitch@2.0.4: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 09b8339..2d3761e 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -1,6 +1,6 @@ packages: - "packages/*" - "package" - - "playgrounds/*" + - "scripts" - "playground" - "www/*" \ No newline at end of file diff --git a/scripts/cmd/build.js b/scripts/cmd/build.js new file mode 100644 index 0000000..e28f055 --- /dev/null +++ b/scripts/cmd/build.js @@ -0,0 +1,164 @@ +import fs from 'node:fs/promises'; +import esbuild from 'esbuild'; +import glob from 'fast-glob'; +import { dim, green, red, yellow } from 'kleur/colors'; +import prebuild from './prebuild.js'; + +/** @type {import('esbuild').BuildOptions} */ +const defaultConfig = { + minify: false, + format: 'esm', + platform: 'node', + target: 'node18', + sourcemap: false, + sourcesContent: false, +}; + +const dt = new Intl.DateTimeFormat('en-us', { + hour: '2-digit', + minute: '2-digit', +}); + +function getPreBuilds(isDev, args) { + let preBuilds = []; + while (args.includes('--prebuild')) { + let idx = args.indexOf('--prebuild'); + preBuilds.push(args[idx + 1]); + args.splice(idx, 2); + } + if (preBuilds.length && isDev) { + preBuilds.unshift('--no-minify'); + } + return preBuilds; +} + +export default async function build(...args) { + const config = Object.assign({}, defaultConfig); + const isDev = args.slice(-1)[0] === 'IS_DEV'; + const preBuilds = getPreBuilds(isDev, args); + const patterns = args + .filter((f) => !!f) // remove empty args + .map((f) => f.replace(/^'/, '').replace(/'$/, '')); // Needed for Windows: glob strings contain surrounding string chars??? remove these + let entryPoints = [].concat( + ...(await Promise.all( + patterns.map((pattern) => glob(pattern, { filesOnly: true, absolute: true })), + )), + ); + + const noClean = args.includes('--no-clean-dist'); + const bundle = args.includes('--bundle'); + const forceCJS = args.includes('--force-cjs'); + const copyWASM = args.includes('--copy-wasm'); + + const { type = 'module', dependencies = {} } = await readPackageJSON('./package.json'); + + config.define = {}; + for (const [key, value] of await getDefinedEntries()) { + config.define[`process.env.${key}`] = JSON.stringify(value); + } + const format = type === 'module' && !forceCJS ? 'esm' : 'cjs'; + + const outdir = 'dist'; + + if (!noClean) { + await clean(outdir); + } + + if (!isDev) { + await esbuild.build({ + ...config, + bundle, + external: bundle ? Object.keys(dependencies) : undefined, + entryPoints, + outdir, + outExtension: forceCJS ? { '.js': '.cjs' } : {}, + format, + }); + return; + } + + const rebuildPlugin = { + name: 'astro:rebuild', + setup(build) { + build.onEnd(async (result) => { + if (preBuilds.length) { + await prebuild(...preBuilds); + } + const date = dt.format(new Date()); + if (result && result.errors.length) { + console.error(dim(`[${date}] `) + red(error || result.errors.join('\n'))); + } else { + if (result.warnings.length) { + console.info( + dim(`[${date}] `) + yellow('! updated with warnings:\n' + result.warnings.join('\n')), + ); + } + console.info(dim(`[${date}] `) + green('√ updated')); + } + }); + }, + }; + + const builder = await esbuild.context({ + ...config, + entryPoints, + outdir, + format, + sourcemap: 'linked', + plugins: [rebuildPlugin], + }); + + await builder.watch(); + + process.on('beforeExit', () => { + builder.stop && builder.stop(); + }); +} + +async function clean(outdir) { + const files = await glob([`${outdir}/**`, `!${outdir}/**/*.d.ts`], { filesOnly: true }); + await Promise.all(files.map((file) => fs.rm(file, { force: true }))); +} + +/** + * Contextual `define` values to statically replace in the built JS output. + * Available to all packages, but mostly useful for CLIs like `create-astro`. + */ +async function getDefinedEntries() { + const define = { + /** The current version (at the time of building) for the current package, such as `astro` or `@astrojs/sitemap` */ + PACKAGE_VERSION: await getInternalPackageVersion('./package.json'), + /** The current version (at the time of building) for `@astrojs/check` */ + ASTRO_CHECK_VERSION: await getWorkspacePackageVersion('@astrojs/check'), + /** The current version (at the time of building) for `typescript` */ + TYPESCRIPT_VERSION: await getWorkspacePackageVersion('typescript'), + }; + for (const [key, value] of Object.entries(define)) { + if (value === undefined) { + delete define[key]; + } + } + return Object.entries(define); +} + +async function readPackageJSON(path) { + return await fs.readFile(path, { encoding: 'utf8' }).then((res) => JSON.parse(res)); +} + +async function getInternalPackageVersion(path) { + return readPackageJSON(path).then((res) => res.version); +} + +async function getWorkspacePackageVersion(packageName) { + const { dependencies, devDependencies } = await readPackageJSON( + new URL('../../package.json', import.meta.url), + ); + const deps = { ...dependencies, ...devDependencies }; + const version = deps[packageName]; + if (!version) { + throw new Error( + `Unable to resolve "${packageName}". Is it a dependency of the workspace root?`, + ); + } + return version.replace(/^\D+/, ''); +} \ No newline at end of file diff --git a/scripts/cmd/prebuild.js b/scripts/cmd/prebuild.js new file mode 100644 index 0000000..1e29159 --- /dev/null +++ b/scripts/cmd/prebuild.js @@ -0,0 +1,115 @@ +import fs from 'node:fs'; +import path from 'node:path'; +import { fileURLToPath, pathToFileURL } from 'node:url'; +import esbuild from 'esbuild'; +import glob from 'fast-glob'; +import { red } from 'kleur/colors'; + +function escapeTemplateLiterals(str) { + return str.replace(/\`/g, '\\`').replace(/\$\{/g, '\\${'); +} + +export default async function prebuild(...args) { + let buildToString = args.indexOf('--to-string'); + if (buildToString !== -1) { + args.splice(buildToString, 1); + buildToString = true; + } + let minify = true; + let minifyIdx = args.indexOf('--no-minify'); + if (minifyIdx !== -1) { + minify = false; + args.splice(minifyIdx, 1); + } + + let patterns = args; + // NOTE: absolute paths returned are forward slashes on windows + let entryPoints = [].concat( + ...(await Promise.all( + patterns.map((pattern) => glob(pattern, { onlyFiles: true, absolute: true })), + )), + ); + + function getPrebuildURL(entryfilepath, dev = false) { + const entryURL = pathToFileURL(entryfilepath); + const basename = path.basename(entryfilepath); + const ext = path.extname(entryfilepath); + const name = basename.slice(0, basename.indexOf(ext)); + const outname = dev ? `${name}.prebuilt-dev${ext}` : `${name}.prebuilt${ext}`; + const outURL = new URL('./' + outname, entryURL); + return outURL; + } + + async function prebuildFile(filepath) { + let tscode = await fs.promises.readFile(filepath, 'utf-8'); + // If we're bundling a client directive, modify the code to match `packages/astro/src/core/client-directive/build.ts`. + // If updating this code, make sure to also update that file. + if (filepath.includes('runtime/client')) { + // `export default xxxDirective` is a convention used in the current client directives that we use + // to make sure we bundle this right. We'll error below if this convention isn't followed. + const newTscode = tscode.replace( + /export default (.*?)Directive/, + (_, name) => + `(self.Astro || (self.Astro = {})).${name} = ${name}Directive;window.dispatchEvent(new Event('astro:${name}'))`, + ); + if (newTscode === tscode) { + console.error( + red( + `${filepath} doesn't follow the \`export default xxxDirective\` convention. The prebuilt output may be wrong. ` + + `For more information, check out ${fileURLToPath(import.meta.url)}`, + ), + ); + } + tscode = newTscode; + } + + const esbuildOptions = { + stdin: { + contents: tscode, + resolveDir: path.dirname(filepath), + loader: 'ts', + sourcefile: filepath, + }, + format: 'iife', + target: ['es2018'], + minify, + bundle: true, + write: false, + }; + + const results = await Promise.all( + [ + { + build: await esbuild.build(esbuildOptions), + dev: false, + }, + filepath.includes('astro-island') + ? { + build: await esbuild.build({ + ...esbuildOptions, + define: { 'process.env.NODE_ENV': '"development"' }, + }), + dev: true, + } + : undefined, + ].filter((entry) => entry), + ); + + for (const result of results) { + const code = result.build.outputFiles[0].text.trim(); + const rootURL = new URL('../../', import.meta.url); + const rel = path.relative(fileURLToPath(rootURL), filepath); + const mod = `/** + * This file is prebuilt from ${rel} + * Do not edit this directly, but instead edit that file and rerun the prebuild + * to generate this file. + */ + +export default \`${escapeTemplateLiterals(code)}\`;`; + const url = getPrebuildURL(filepath, result.dev); + await fs.promises.writeFile(url, mod, 'utf-8'); + } + } + + await Promise.all(entryPoints.map(prebuildFile)); +} \ No newline at end of file diff --git a/scripts/index.js b/scripts/index.js new file mode 100755 index 0000000..31b4449 --- /dev/null +++ b/scripts/index.js @@ -0,0 +1,19 @@ +#!/usr/bin/env node +export default async function run() { + const [cmd, ...args] = process.argv.slice(2); + switch (cmd) { + case 'dev': + case 'build': { + const { default: build } = await import('./cmd/build.js'); + await build(...args, cmd === 'dev' ? 'IS_DEV' : undefined); + break; + } + case 'prebuild': { + const { default: prebuild } = await import('./cmd/prebuild.js'); + await prebuild(...args); + break; + } + } +} + +run(); \ No newline at end of file diff --git a/scripts/jsconfig.json b/scripts/jsconfig.json new file mode 100644 index 0000000..fe1a73c --- /dev/null +++ b/scripts/jsconfig.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "declaration": true, + "strict": true, + "module": "esnext", + "moduleResolution": "node", + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "target": "esnext" + } + } \ No newline at end of file diff --git a/scripts/package.json b/scripts/package.json new file mode 100644 index 0000000..9baa36e --- /dev/null +++ b/scripts/package.json @@ -0,0 +1,19 @@ +{ + "name": "run-scripts", + "version": "0.0.1", + "private": true, + "type": "module", + "main": "./index.js", + "bin": { + "run-scripts": "./index.js" + }, + "dependencies": { + "esbuild": "^0.21.5", + "esbuild-plugin-copy": "^2.1.1", + "fast-glob": "^3.3.2", + "kleur": "^4.1.5", + "p-limit": "^6.1.0", + "tinyexec": "^0.3.1", + "tsconfck": "^3.1.4" + } +} \ No newline at end of file diff --git a/tsconfig.base.json b/tsconfig.base.json new file mode 100644 index 0000000..6d41745 --- /dev/null +++ b/tsconfig.base.json @@ -0,0 +1,15 @@ +{ + "$schema": "https://json.schemastore.org/tsconfig", + "compilerOptions": { + "declaration": true, + "emitDeclarationOnly": true, + "strict": true, + "moduleResolution": "Node16", + "target": "ES2022", + "module": "Node16", + "esModuleInterop": true, + "skipLibCheck": true, + "verbatimModuleSyntax": true, + "stripInternal": true + } + } \ No newline at end of file diff --git a/vitest.workspace.ts b/vitest.workspace.ts new file mode 100644 index 0000000..16735a8 --- /dev/null +++ b/vitest.workspace.ts @@ -0,0 +1,3 @@ +import { defineWorkspace } from 'vitest/config'; + +export default defineWorkspace(['packages/*']);