From 1de0358d5ce0f6db89bb88f2fe7b5b59546bed8c Mon Sep 17 00:00:00 2001 From: Jason Caldwell Date: Mon, 11 Dec 2023 21:00:20 -0500 Subject: [PATCH] Project update. [p][robotic] --- .browserslistrc | 2 +- .dockerignore | 3 +- .gitattributes | 2 +- .gitignore | 2 +- .npmignore | 3 +- .prettierignore | 2 +- .vscode/settings.json | 57 +- .vscodeignore | 3 +- brand.config.mjs | 22 + dev-types.d.ts | 17 + dev/.files/bin/includes/import-aliases.mjs | 7 +- dev/.files/bin/includes/utilities.mjs | 23 +- dev/.files/bin/updater/index.mjs | 1 + dev/.files/brand/config.mjs | 27 + dev/.files/madrun/config.mjs | 173 +- dev/.files/madrun/includes/events.mjs | 63 +- dev/.files/mdx/config.mjs | 8 +- dev/.files/postcss/config.mjs | 16 +- dev/.files/rehype/config.mjs | 8 +- .../rehype/plugins/anchors/preact-x-hash.mjs | 2 +- .../plugins/anchors/rel-external-nofollow.mjs | 2 +- .../rehype/plugins/footnotes/fix-anchors.mjs | 4 +- dev/.files/rehype/plugins/images/lazy.mjs | 23 + dev/.files/remark/plugins/alerts/index.mjs | 2 +- dev/.files/tailwind/brand.mjs | 41 + dev/.files/tailwind/cli-sync/base-url.mjs | 15 + dev/.files/tailwind/cli-sync/brand-config.mjs | 16 + dev/.files/tailwind/config.mjs | 21 +- dev/.files/tailwind/imports/starry-night.scss | 298 +++ dev/.files/tailwind/layers.scss | 177 +- dev/.files/tailwind/mixins/_starry-night.scss | 299 --- dev/.files/tailwind/themes.mjs | 58 +- dev/.files/vite/config.mjs | 65 +- .../vite/includes/c10n/brand-config.mjs | 39 + .../vite/includes/c10n/no-module-preload.mjs | 32 + .../vite/includes/c10n/post-processing.mjs | 133 +- .../c10n/{transforms.mjs => side-effects.mjs} | 9 +- dev/.files/vite/includes/dts/config.mjs | 4 +- dev/.files/vite/includes/minify/config.mjs | 4 +- dev/.files/vite/includes/package/updates.mjs | 6 + dev/.files/vite/includes/terser/config.mjs | 30 + dev/.files/vscode/config.mjs | 78 +- dev/.files/wrangler/config.mjs | 11 +- dev/.files/wrangler/settings.mjs | 11 +- package-lock.json | 1710 ++++++++++++----- package.json | 8 +- tsconfig.json | 3 +- wrangler.toml | 11 +- 48 files changed, 2382 insertions(+), 1169 deletions(-) create mode 100644 brand.config.mjs create mode 100644 dev/.files/brand/config.mjs create mode 100644 dev/.files/rehype/plugins/images/lazy.mjs create mode 100644 dev/.files/tailwind/brand.mjs create mode 100755 dev/.files/tailwind/cli-sync/base-url.mjs create mode 100755 dev/.files/tailwind/cli-sync/brand-config.mjs create mode 100644 dev/.files/tailwind/imports/starry-night.scss delete mode 100644 dev/.files/tailwind/mixins/_starry-night.scss create mode 100644 dev/.files/vite/includes/c10n/brand-config.mjs create mode 100644 dev/.files/vite/includes/c10n/no-module-preload.mjs rename dev/.files/vite/includes/c10n/{transforms.mjs => side-effects.mjs} (85%) create mode 100644 dev/.files/vite/includes/terser/config.mjs diff --git a/.browserslistrc b/.browserslistrc index fb5edd01..a03766bd 100644 --- a/.browserslistrc +++ b/.browserslistrc @@ -17,7 +17,7 @@ # Generated data. # -# Last generated Dec 3, 2023 10:52 AM UTC. +# Last generated Dec 12, 2023 2:00 AM UTC. [production] node >= 20.9.0 diff --git a/.dockerignore b/.dockerignore index a7bd343a..703aba85 100644 --- a/.dockerignore +++ b/.dockerignore @@ -17,7 +17,7 @@ # Generated data. # -# Last generated Dec 3, 2023 10:52 AM UTC. +# Last generated Dec 12, 2023 2:00 AM UTC. # Locals @@ -211,6 +211,7 @@ dist # npm:Dots .* +!.well-known # npm:Configs diff --git a/.gitattributes b/.gitattributes index 3d44eb64..754dfd64 100644 --- a/.gitattributes +++ b/.gitattributes @@ -17,7 +17,7 @@ # Generated data. # -# Last generated Dec 3, 2023 10:52 AM UTC. +# Last generated Dec 12, 2023 2:00 AM UTC. # Default diff --git a/.gitignore b/.gitignore index 5fe0ac52..d1542d19 100644 --- a/.gitignore +++ b/.gitignore @@ -17,7 +17,7 @@ # Generated data. # -# Last generated Dec 3, 2023 10:52 AM UTC. +# Last generated Dec 12, 2023 2:00 AM UTC. # Locals diff --git a/.npmignore b/.npmignore index 448dbd04..940a3050 100644 --- a/.npmignore +++ b/.npmignore @@ -25,7 +25,7 @@ # Generated data. # -# Last generated Dec 3, 2023 10:52 AM UTC. +# Last generated Dec 12, 2023 2:00 AM UTC. # Locals @@ -219,6 +219,7 @@ dist # npm:Dots .* +!.well-known # npm:Configs diff --git a/.prettierignore b/.prettierignore index d053f071..af07b42c 100644 --- a/.prettierignore +++ b/.prettierignore @@ -17,7 +17,7 @@ # Generated data. # -# Last generated Dec 3, 2023 10:52 AM UTC. +# Last generated Dec 12, 2023 2:00 AM UTC. # Packages diff --git a/.vscode/settings.json b/.vscode/settings.json index da11aae7..dd92bdd4 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -7,7 +7,7 @@ * @note This entire file will be updated automatically. * @note Instead of editing here, please review `./settings.mjs`. * - * Last generated using `./settings.mjs` Dec 3, 2023 10:52 AM UTC. + * Last generated using `./settings.mjs` Dec 12, 2023 2:00 AM UTC. */ { "editor.formatOnType": false, @@ -72,8 +72,12 @@ "**/CODEOWNERS": "ignore", "**/tsconfig.{json,×××××××}": "jsonc", "**/.vscode/*.{json,×××××××}": "jsonc", + "**/src/cargo/.well-known/**/*.{json,×××××××}": "jsonc", + "**/dist/_headers": "plaintext", "**/src/cargo/_headers": "plaintext", + "**/dist/_redirects": "plaintext", "**/src/cargo/_redirects": "plaintext", + "**/src/cargo/manifest.{json,×××××××}": "jsonc", "**/src/cargo/_routes.{json,×××××××}": "jsonc" }, "files.exclude": { @@ -128,6 +132,7 @@ "**/Network Trash Folder": true, "**/Temporary Items": true, ".*": true, + ".well-known": false, "*.tsbuildinfo": true, "*.config.*": true, "wrangler.*": true, @@ -152,6 +157,7 @@ "search.useParentIgnoreFiles": false, "search.exclude": { "/.*": true, + "/!**/.well-known": true, "/*.tsbuildinfo": true, "/*.config.*": true, "/wrangler.*": true, @@ -227,6 +233,7 @@ "mode": "auto" } ], + "eslint.probe": ["javascript", "javascriptreact", "typescript", "typescriptreact"], "eslint.validate": ["javascript", "javascriptreact", "typescript", "typescriptreact"], "eslint.options": { "overrideConfigFile": "./eslint.config.mjs" @@ -311,7 +318,7 @@ "markdown.preview.fontSize": 16, "markdown.preview.lineHeight": 1.5, "markdown.preview.typographer": true, - "markdown.preview.fontFamily": "Georama, ui-sans-serif, sans-serif", + "markdown.preview.fontFamily": "Georama, sans-serif, 'Apple Color Emoji'", "markdown.validate.enabled": false, "mdx.server.enable": false, "prettier.ignorePath": ".prettierignore", @@ -322,7 +329,7 @@ "files.trimTrailingWhitespace": false, "editor.wordWrap": "on", "editor.codeActionsOnSave": { - "source.fixAll": true + "source.fixAll": "explicit" }, "editor.defaultFormatter": "esbenp.prettier-vscode" }, @@ -332,7 +339,7 @@ "files.trimTrailingWhitespace": false, "editor.wordWrap": "on", "editor.codeActionsOnSave": { - "source.fixAll": true + "source.fixAll": "explicit" }, "editor.defaultFormatter": "esbenp.prettier-vscode" }, @@ -340,7 +347,7 @@ "editor.tabSize": 4, "editor.insertSpaces": true, "editor.codeActionsOnSave": { - "source.fixAll": true + "source.fixAll": "explicit" }, "editor.defaultFormatter": "esbenp.prettier-vscode" }, @@ -348,7 +355,7 @@ "editor.tabSize": 4, "editor.insertSpaces": true, "editor.codeActionsOnSave": { - "source.fixAll": true + "source.fixAll": "explicit" }, "editor.defaultFormatter": "esbenp.prettier-vscode" }, @@ -356,7 +363,7 @@ "editor.tabSize": 4, "editor.insertSpaces": true, "editor.codeActionsOnSave": { - "source.fixAll": true + "source.fixAll": "explicit" }, "editor.defaultFormatter": "esbenp.prettier-vscode" }, @@ -364,7 +371,7 @@ "editor.tabSize": 4, "editor.insertSpaces": true, "editor.codeActionsOnSave": { - "source.fixAll": true + "source.fixAll": "explicit" }, "editor.defaultFormatter": "ms-python.black-formatter" }, @@ -372,7 +379,7 @@ "editor.tabSize": 4, "editor.insertSpaces": true, "editor.codeActionsOnSave": { - "source.fixAll": true + "source.fixAll": "explicit" }, "editor.defaultFormatter": "esbenp.prettier-vscode" }, @@ -380,7 +387,7 @@ "editor.tabSize": 4, "editor.insertSpaces": true, "editor.codeActionsOnSave": { - "source.fixAll": true + "source.fixAll": "explicit" }, "editor.defaultFormatter": "esbenp.prettier-vscode" }, @@ -388,7 +395,7 @@ "editor.tabSize": 4, "editor.insertSpaces": true, "editor.codeActionsOnSave": { - "source.fixAll": true + "source.fixAll": "explicit" }, "editor.defaultFormatter": "dbaeumer.vscode-eslint" }, @@ -396,7 +403,7 @@ "editor.tabSize": 4, "editor.insertSpaces": true, "editor.codeActionsOnSave": { - "source.fixAll": true + "source.fixAll": "explicit" }, "editor.defaultFormatter": "dbaeumer.vscode-eslint" }, @@ -404,7 +411,7 @@ "editor.tabSize": 4, "editor.insertSpaces": true, "editor.codeActionsOnSave": { - "source.fixAll": true + "source.fixAll": "explicit" }, "editor.defaultFormatter": "dbaeumer.vscode-eslint" }, @@ -412,7 +419,7 @@ "editor.tabSize": 4, "editor.insertSpaces": true, "editor.codeActionsOnSave": { - "source.fixAll": true + "source.fixAll": "explicit" }, "editor.defaultFormatter": "dbaeumer.vscode-eslint" }, @@ -420,7 +427,7 @@ "editor.tabSize": 4, "editor.insertSpaces": true, "editor.codeActionsOnSave": { - "source.fixAll": true + "source.fixAll": "explicit" }, "editor.defaultFormatter": "esbenp.prettier-vscode" }, @@ -428,7 +435,7 @@ "editor.tabSize": 4, "editor.insertSpaces": true, "editor.codeActionsOnSave": { - "source.fixAll": true + "source.fixAll": "explicit" }, "editor.defaultFormatter": "esbenp.prettier-vscode" }, @@ -436,7 +443,7 @@ "editor.tabSize": 4, "editor.insertSpaces": true, "editor.codeActionsOnSave": { - "source.fixAll": true + "source.fixAll": "explicit" }, "editor.defaultFormatter": "esbenp.prettier-vscode" }, @@ -444,7 +451,7 @@ "editor.tabSize": 4, "editor.insertSpaces": true, "editor.codeActionsOnSave": { - "source.fixAll": true + "source.fixAll": "explicit" }, "editor.defaultFormatter": "esbenp.prettier-vscode" }, @@ -452,7 +459,7 @@ "editor.tabSize": 4, "editor.insertSpaces": true, "editor.codeActionsOnSave": { - "source.fixAll": true + "source.fixAll": "explicit" }, "editor.defaultFormatter": "esbenp.prettier-vscode" }, @@ -460,7 +467,7 @@ "editor.tabSize": 4, "editor.insertSpaces": true, "editor.codeActionsOnSave": { - "source.fixAll": true + "source.fixAll": "explicit" }, "editor.defaultFormatter": "esbenp.prettier-vscode" }, @@ -468,7 +475,7 @@ "editor.tabSize": 4, "editor.insertSpaces": true, "editor.codeActionsOnSave": { - "source.fixAll": true + "source.fixAll": "explicit" }, "editor.defaultFormatter": "tamasfe.even-better-toml" }, @@ -476,7 +483,7 @@ "editor.tabSize": 4, "editor.insertSpaces": true, "editor.codeActionsOnSave": { - "source.fixAll": true + "source.fixAll": "explicit" }, "editor.defaultFormatter": "esbenp.prettier-vscode" }, @@ -484,7 +491,7 @@ "editor.tabSize": 4, "editor.insertSpaces": true, "editor.codeActionsOnSave": { - "source.fixAll": true + "source.fixAll": "explicit" }, "editor.defaultFormatter": "esbenp.prettier-vscode" }, @@ -492,7 +499,7 @@ "editor.tabSize": 4, "editor.insertSpaces": true, "editor.codeActionsOnSave": { - "source.fixAll": true + "source.fixAll": "explicit" }, "editor.defaultFormatter": "esbenp.prettier-vscode" }, @@ -500,7 +507,7 @@ "editor.tabSize": 4, "editor.insertSpaces": true, "editor.codeActionsOnSave": { - "source.fixAll": true + "source.fixAll": "explicit" }, "editor.defaultFormatter": "esbenp.prettier-vscode" } diff --git a/.vscodeignore b/.vscodeignore index bdec4cb3..bc26ee57 100644 --- a/.vscodeignore +++ b/.vscodeignore @@ -17,7 +17,7 @@ # Generated data. # -# Last generated Dec 3, 2023 10:52 AM UTC. +# Last generated Dec 12, 2023 2:00 AM UTC. # Locals @@ -211,6 +211,7 @@ dist # npm:Dots .* +!.well-known # npm:Configs diff --git a/brand.config.mjs b/brand.config.mjs new file mode 100644 index 00000000..1f56cef0 --- /dev/null +++ b/brand.config.mjs @@ -0,0 +1,22 @@ +/** + * Brand config file. + * + * Vite is aware of this config file's location. + * + * @note CUSTOM EDITS ONLY PLEASE! + * @note In the future this file will be updated automatically. + * @note Only `` will be preserved below. + */ + +import baseConfig from './dev/.files/brand/config.mjs'; +import { $obj } from './node_modules/@clevercanyon/utilities/dist/index.js'; + +/* + * Customizations. + * */ + +export default async (context) => { + return $obj.mergeDeep({}, await baseConfig(context), {}); +}; + +/* */ diff --git a/dev-types.d.ts b/dev-types.d.ts index 2e970dec..8eade0e4 100644 --- a/dev-types.d.ts +++ b/dev-types.d.ts @@ -16,6 +16,8 @@ declare const $$__APP_PKG_VERSION__$$: string; declare const $$__APP_PKG_REPOSITORY__$$: string; declare const $$__APP_PKG_HOMEPAGE__$$: string; declare const $$__APP_PKG_BUGS__$$: string; +declare const $$__APP_BASE_URL__$$: string; +declare const $$__APP_BASE_URL_RESOLVED_NTS__$$: string; declare const $$__APP_BUILD_TIME_YMD__$$: string; /** @@ -23,6 +25,21 @@ declare const $$__APP_BUILD_TIME_YMD__$$: string; */ declare var __PREFRESH__: object; +/** + * Declares virtual brand config file. + */ +declare module 'virtual:brand/config' { + import { $type } from '@clevercanyon/utilities'; + export default {} as Partial<$type.BrandRawProps>; +} + +/** + * Defines missing `entries()` on FormData. + */ +interface FormData { + entries(): IterableIterator<[key: string, value: string | Blob]>; +} + /* * Customizations. * diff --git a/dev/.files/bin/includes/import-aliases.mjs b/dev/.files/bin/includes/import-aliases.mjs index dabe50b1..5f388b6f 100644 --- a/dev/.files/bin/includes/import-aliases.mjs +++ b/dev/.files/bin/includes/import-aliases.mjs @@ -29,7 +29,12 @@ for (const [glob, relPath] of Object.entries(pkg.imports || {})) { if (!$is.string(relPath)) throw new Error('Invalid subpath imports.'); let regExpRepCounter = 0; // e.g., `$1`, `$2`, `$3`, etc. - const regExpString = '^' + $str.escRegExp(glob).replace(/\\\*/gu, '(.+?)') + '$'; + // For some reason, Vite chooses not to resolve `url()` values in CSS whenever they begin with a `#`. + // Unfortunate, because our import aliases use `#`. To fix, we prepend `url()` values starting with `#`, with `&#`. + // For that reason, any glob pattern found here that begins with `#` will be updated to accept an optional leading `&`. + // This only impacts Vite/PostCSS, and therefore we only need to alter the regular expression variants of our import aliases. + // See also: `./dev/.files/postcss/config.mjs` for details regarding the way we automatically prepend CSS `url()`s with `&#`. + const regExpString = '^' + (glob.startsWith('#') ? '&?' : '') + $str.escRegExp(glob).replace(/\\\*/gu, '(.+?)') + '$'; userlandAliasesAsGlobs[glob] = path.resolve(projDir, relPath); userlandAliasesAsRegExpStrings[regExpString] = path.resolve(projDir, relPath).replace(/\*/gu, () => '$' + String(++regExpRepCounter)); diff --git a/dev/.files/bin/includes/utilities.mjs b/dev/.files/bin/includes/utilities.mjs index 74991381..98a45c7f 100755 --- a/dev/.files/bin/includes/utilities.mjs +++ b/dev/.files/bin/includes/utilities.mjs @@ -14,7 +14,7 @@ import fsp from 'node:fs/promises'; import os from 'node:os'; import path from 'node:path'; import { $chalk, $cmd, $dotenv, $fs, $prettier } from '../../../../node_modules/@clevercanyon/utilities.node/dist/index.js'; -import { $is, $json, $obj, $obp, $str, $url, $version } from '../../../../node_modules/@clevercanyon/utilities/dist/index.js'; +import { $brand, $fn, $is, $json, $obj, $obp, $str, $url, $version } from '../../../../node_modules/@clevercanyon/utilities/dist/index.js'; import nodeVersion from './node-version.mjs'; const __dirname = $fs.imuDirname(import.meta.url); @@ -212,6 +212,25 @@ export default class u { await fsp.writeFile(pkgFile, await $prettier.format($json.stringify(pkg, { pretty: true }), prettierConfig)); } + /** + * Brand utilities. + */ + + static async brand({ baseURL } = {}) { + return ( + $fn.try(() => $brand.get(pkgName), undefined)() || + $brand.addApp({ + pkgName: pkgName, + baseURL: baseURL || '', + props: await u.brandConfig(), + }) + ); + } + + static async brandConfig() { + return await (await import(path.resolve(projDir, './brand.config.mjs'))).default(); + } + /* * Git utilities. */ @@ -998,7 +1017,7 @@ export default class u { u.log($chalk.gray('Decrypting `' + envName + '` env using Dotenv Vault key.')); if (!opts.dryRun) { // Note: this doesn’t leak our environment variables, but it does leak all of the - // variables in `./.env.vault`, because of the way it is processed internally by dotenv. + // variables in `./.env.vault` because of the way it is processed internally by dotenv. // Issue opened at dotenv regarding the problem; {@see https://o5p.me/DBbi7j}. const env = $dotenv.$._parseVault({ DOTENV_KEY: key, // Pass explicitly. diff --git a/dev/.files/bin/updater/index.mjs b/dev/.files/bin/updater/index.mjs index c2334259..ad8f6ae6 100644 --- a/dev/.files/bin/updater/index.mjs +++ b/dev/.files/bin/updater/index.mjs @@ -163,6 +163,7 @@ export default async ({ projDir }) => { './wrangler.toml', './wrangler.mjs', + './brand.config.mjs', './madrun.config.mjs', ]) { if (await isLocked(relPath)) { diff --git a/dev/.files/brand/config.mjs b/dev/.files/brand/config.mjs new file mode 100644 index 00000000..cf6696e8 --- /dev/null +++ b/dev/.files/brand/config.mjs @@ -0,0 +1,27 @@ +/** + * Brand config file. + * + * Vite is not aware of this config file's location. + * + * @note PLEASE DO NOT EDIT THIS FILE! + * @note This entire file will be updated automatically. + * @note Instead of editing here, please review . + */ + +/** + * Defines brand configuration. + * + * @param context Optional context. + * + * @returns Raw brand properties. + */ +export default async (/* {} */) => { + /** + * Composition. + */ + return { + name: 'Skeleton', + slogan: 'Masters of the digital divide.', + description: 'Great things, built on great technology.', + }; +}; diff --git a/dev/.files/madrun/config.mjs b/dev/.files/madrun/config.mjs index 202138ae..c08a91d6 100644 --- a/dev/.files/madrun/config.mjs +++ b/dev/.files/madrun/config.mjs @@ -21,9 +21,10 @@ import wranglerSettings from '../wrangler/settings.mjs'; import events from './includes/events.mjs'; const __dirname = path.dirname(url.fileURLToPath(import.meta.url)); +const projDir = path.resolve(__dirname, '../../..'); const distDir = path.resolve(__dirname, '../../../dist'); -const nodeIncludeFile = path.resolve(__dirname, './includes/node.cjs'); +const nodeIncludeFile = path.resolve(__dirname, './includes/node.cjs'); const nodeEnvVars = { NODE_OPTIONS: $cmd.quote([`--require ${$cmd.esc(nodeIncludeFile)}`].join(' ')) }; const cloudflareEnvVars = { CLOUDFLARE_API_TOKEN: process.env.USER_CLOUDFLARE_TOKEN || '' }; @@ -128,90 +129,112 @@ export default async () => { /** * Wrangler commands. */ - 'wrangler': async () => { - return { - env: { ...nodeEnvVars, ...cloudflareEnvVars }, - cmds: [['npx', 'wrangler', '{{@}}']], - }; - }, - 'wrangler:flush': async () => { + 'wrangler': async ({ args }) => { return { env: { ...nodeEnvVars, ...cloudflareEnvVars }, + opts: { ...('pages' === args._?.[0] ? { cwd: distDir } : {}) }, + // Setting `cwd` is a bug workaround; see: . cmds: [ - async () => { - u.log($chalk.green('Flushing Wrangler state for local dev testing.')); - await fsp.rm(wranglerSettings.projStateDir, { recursive: true, force: true }); - }, + // `$ madrun wrangler dev|pages`. + ...('dev' === args._?.[0] || 'pages' === args._?.[0] + ? [ + async () => { + if (!(await fs.existsSync(wranglerSettings.osDir))) return; + + // Ensure `~/.wrangler/local-cert` directory exists. + await fsp.mkdir(wranglerSettings.osSSLCertDir, { recursive: true, mode: 0o700 }); + + // Link our custom SSL key to that used by Wrangler. + await fsp.rm(wranglerSettings.osSSLKeyFile, { recursive: true, force: true }); + await fsp.symlink(wranglerSettings.customSSLKeyFile, wranglerSettings.osSSLKeyFile); + + // Link our custom SSL certificate to that used by Wrangler. + await fsp.rm(wranglerSettings.osSSLCertFile, { recursive: true, force: true }); + await fsp.symlink(wranglerSettings.customSSLCertFile, wranglerSettings.osSSLCertFile); + }, + ] + : []), + ...('dev' === args._?.[0] + ? // `$ madrun wrangler dev`. + // Config pulled from `./wrangler.toml` in this case. + [['npx', 'wrangler', '{{@}}', ...(args.env ? [] : ['--env', 'dev'])]] + : // + // `$ madrun wrangler pages`. + // Config is not pulled from `./wrangler.toml` in this case. + // Therefore, we must configure everything at command line. + 'pages' === args._?.[0] + ? [ + // `$ madrun wrangler pages dev`. + ...('dev' === args._?.[1] && !args.help + ? [ + { + opts: { cwd: projDir }, + env: { VITE_WRANGLER_MODE: 'dev', ...nodeEnvVars, ...cloudflareEnvVars }, + cmd: ['npx', 'vite', 'build', '--mode', 'dev'], + }, + ] + : []), + // `$ madrun wrangler pages *`. + [ + 'npx', + 'wrangler', + '{{@}}', + + // Default `project` command args. + ...('project' === args._?.[1] && 'create' === args._?.[2] ? (args._?.[3] ? [] : [wranglerSettings.defaultProjectName]) : []), + ...('project' === args._?.[1] && 'create' === args._?.[2] + ? args.productionBranch + ? [] // This is the production branch on the Cloudflare side. + : ['--production-branch', wranglerSettings.defaultProductionBranch] + : []), + + // Default `dev` command args. + ...('dev' === args._?.[1] ? (args._?.[2] ? [] : [distDir]) : []), + ...('dev' === args._?.[1] ? (args.ip ? [] : ['--ip', wranglerSettings.defaultLocalIP]) : []), + ...('dev' === args._?.[1] ? (args.port ? [] : ['--port', wranglerSettings.defaultLocalPort]) : []), + ...('dev' === args._?.[1] ? (args.localProtocol ? [] : ['--local-protocol', wranglerSettings.defaultLocalProtocol]) : []), + ...('dev' === args._?.[1] ? (args.compatibilityDate ? [] : ['--compatibility-date', wranglerSettings.compatibilityDate]) : []), + ...('dev' === args._?.[1] + ? args.compatibilityFlag || args.compatibilityFlags + ? [] // `--compatibility-flag` is an alias of `--compatibility-flags`. + : wranglerSettings.compatibilityFlags.map((f) => ['--compatibility-flag', f]).flat() + : []), + ...('dev' === args._?.[1] ? (args.logLevel ? [] : ['--log-level', wranglerSettings.defaultDevLogLevel]) : []), + ...('dev' === args._?.[1] ? ['--binding', wranglerSettings.miniflareDevBinding] : []), // Always on; `--binding` can be passed multiple times. + + // Default `deploy` command args. + ...(['deploy', 'publish'].includes(args._?.[1]) ? (args.projectName ? [] : ['--project-name', wranglerSettings.defaultProjectName]) : []), + ...(['deploy', 'publish'].includes(args._?.[1]) ? (args.branch ? [] : ['--branch', wranglerSettings.defaultProductionBranch]) : []), + + // Default `deployment` command args. + ...('deployment' === args._?.[1] && 'list' === args._?.[2] + ? args.projectName + ? [] + : ['--project-name', wranglerSettings.defaultProjectName] + : []), + ...('deployment' === args._?.[1] && 'tail' === args._?.[2] + ? args.projectName + ? [] + : ['--project-name', wranglerSettings.defaultProjectName] + : []), + ...('deployment' === args._?.[1] && 'tail' === args._?.[2] + ? args.environment + ? [] + : ['--environment', wranglerSettings.defaultEnvironment] + : []), + ], + ] + : // `$ madrun wrangler *`. + [['npx', 'wrangler', '{{@}}']]), ], }; }, - - /** - * Wrangler pages commands. - */ - 'pages': async ({ args }) => { - return { - opts: { cwd: distDir }, // See: . - env: { ...nodeEnvVars, ...cloudflareEnvVars }, - cmds: [ - async () => { - if (!(await fs.existsSync(wranglerSettings.osDir))) return; - - // Ensure `~/.wrangler/local-cert` directory exists. - await fsp.mkdir(wranglerSettings.osSSLCertDir, { recursive: true, mode: 0o700 }); - - // Link our custom SSL key to that used by Wrangler. - await fsp.rm(wranglerSettings.osSSLKeyFile, { recursive: true, force: true }); - await fsp.symlink(wranglerSettings.customSSLKeyFile, wranglerSettings.osSSLKeyFile); - - // Link our custom SSL certificate to that used by Wrangler. - await fsp.rm(wranglerSettings.osSSLCertFile, { recursive: true, force: true }); - await fsp.symlink(wranglerSettings.customSSLCertFile, wranglerSettings.osSSLCertFile); - }, - [ - 'npx', - 'wrangler', - 'pages', - '{{@}}', - - // Default `project` command args. - ...('project' === args._?.[0] && 'create' === args._?.[1] ? (args._?.[2] ? [] : [wranglerSettings.defaultProjectName]) : []), - ...('project' === args._?.[0] && 'create' === args._?.[1] - ? args.productionBranch - ? [] // This is the production branch on the Cloudflare side. - : ['--production-branch', wranglerSettings.defaultProductionBranch] - : []), - - // Default `dev` command args. - ...('dev' === args._?.[0] ? (args._?.[1] ? [] : [distDir]) : []), - ...('dev' === args._?.[0] ? (args.ip ? [] : ['--ip', wranglerSettings.defaultLocalIP]) : []), - ...('dev' === args._?.[0] ? (args.port ? [] : ['--port', wranglerSettings.defaultLocalPort]) : []), - ...('dev' === args._?.[0] ? (args.localProtocol ? [] : ['--local-protocol', wranglerSettings.defaultLocalProtocol]) : []), - ...('dev' === args._?.[0] ? (args.compatibilityDate ? [] : ['--compatibility-date', wranglerSettings.compatibilityDate]) : []), - ...('dev' === args._?.[0] - ? args.compatibilityFlag || args.compatibilityFlags - ? [] // `--compatibility-flag` is an alias of `--compatibility-flags`. - : wranglerSettings.compatibilityFlags.map((f) => ['--compatibility-flag', f]).flat() - : []), - - // Default `deploy` command args. - ...(['deploy', 'publish'].includes(args._?.[0]) ? (args.projectName ? [] : ['--project-name', wranglerSettings.defaultProjectName]) : []), - ...(['deploy', 'publish'].includes(args._?.[0]) ? (args.branch ? [] : ['--branch', wranglerSettings.defaultProductionBranch]) : []), - - // Default `deployment` command args. - ...('deployment' === args._?.[0] && 'list' === args._?.[1] ? (args.projectName ? [] : ['--project-name', wranglerSettings.defaultProjectName]) : []), - ...('deployment' === args._?.[0] && 'tail' === args._?.[1] ? (args.projectName ? [] : ['--project-name', wranglerSettings.defaultProjectName]) : []), - ...('deployment' === args._?.[0] && 'tail' === args._?.[1] ? (args.environment ? [] : ['--environment', wranglerSettings.defaultEnvironment]) : []), - ], - ], - }; - }, - 'pages:flush': async () => { + 'wrangler:flush': async () => { return { env: { ...nodeEnvVars, ...cloudflareEnvVars }, cmds: [ async () => { - u.log($chalk.green('Flushing Wrangler state for local dev testing.')); + u.log($chalk.green('Flushing Wrangler state.')); await fsp.rm(wranglerSettings.projStateDir, { recursive: true, force: true }); }, ], diff --git a/dev/.files/madrun/includes/events.mjs b/dev/.files/madrun/includes/events.mjs index e2ffebfe..304eef99 100644 --- a/dev/.files/madrun/includes/events.mjs +++ b/dev/.files/madrun/includes/events.mjs @@ -67,7 +67,6 @@ export default { const repoName = (/^@/u.test(pkgName) && /[^@/]\/[^@/]/u.test(pkgName) ? pkgName.replace(/^@/u, '').split('/')[1] : '') || _dirBasename; const envsDir = path.resolve(projDir, './dev/.envs'); - const envProdFile = path.resolve(envsDir, './.env.prod'); const readmeFile = path.resolve(projDir, './README.md'); u.log($chalk.gray($json.stringify({ pkgName, pkgSlug, repoOwner, repoName }, { pretty: true }))); @@ -123,22 +122,33 @@ export default { */ if (fs.existsSync(envsDir)) { u.log($chalk.green('Updating `./dev/.envs`.')); + const envFiles = await u.envFiles(); + await fsp - .readFile(envProdFile) - .then((envProd) => envProd.toString()) - .then(async (envProd) => { + .readFile(envFiles.main) + .then((buffer) => buffer.toString()) + .then(async (contents) => { if ('cfw' === pkg.config.c10n.build.targetEnv) { - envProd = envProd.replace( - /^(APP_BASE_URL)\s*=\s*[^\r\n]*$/gmu, - "$1='https://" + wranglerSettings.defaultZoneDomain + '/' + wranglerSettings.defaultWorkerName + "/'", - ); + contents = contents.replace(/^(BASE_PATH)\s*=\s*[^\r\n]*$/gmu, "$1='/" + wranglerSettings.defaultWorkerName + "'"); } else if ('cfp' === pkg.config.c10n.build.targetEnv) { - envProd = envProd.replace( - /^(APP_BASE_URL)\s*=\s*[^\r\n]*$/gmu, - "$1='https://" + wranglerSettings.defaultProjectName + '.' + wranglerSettings.defaultZoneName + "/'", - ); + contents = contents.replace(/^(BASE_PATH)\s*=\s*[^\r\n]*$/gmu, "$1='' # No base path."); } - await fsp.writeFile(envProdFile, envProd); + await fsp.writeFile(envFiles.main, contents); + }) + .catch((error) => { + if ('ENOENT' !== error.code) throw error; + }); + + await fsp + .readFile(envFiles.prod) + .then((buffer) => buffer.toString()) + .then(async (contents) => { + if ('cfw' === pkg.config.c10n.build.targetEnv) { + contents = contents.replace(/^(APP_BASE_URL)\s*=\s*[^\r\n]*$/gmu, "$1='https://" + wranglerSettings.defaultZoneDomain + "${BASE_PATH}/'"); + } else if ('cfp' === pkg.config.c10n.build.targetEnv) { + contents = contents.replace(/^(APP_BASE_URL)\s*=\s*[^\r\n]*$/gmu, "$1='https://" + wranglerSettings.defaultProjectName + '.' + wranglerSettings.defaultZoneName + "${BASE_PATH}/'"); // prettier-ignore + } + await fsp.writeFile(envFiles.prod, contents); }) .catch((error) => { if ('ENOENT' !== error.code) throw error; @@ -146,19 +156,22 @@ export default { } /** - * Updates `./README.md` file in new project directory. + * Updates `./README.md` file, if applicable. */ - u.log($chalk.green('Updating `./README.md`.')); - await fsp - .readFile(readmeFile) - .then(async (readme) => { - readme = readme.toString(); - readme = readme.replace(/^(#\s+)(@[^/?#\s]+\/[^/?#\s]+)/gmu, '$1' + pkgName); - await fsp.writeFile(readmeFile, readme); - }) - .catch((error) => { - if ('ENOENT' !== error.code) throw error; - }); + if (fs.existsSync(readmeFile)) { + u.log($chalk.green('Updating `./README.md`.')); + + await fsp + .readFile(readmeFile) + .then((buffer) => buffer.toString()) + .then(async (contents) => { + contents = contents.replace(/^(#\s+)(@[^/?#\s]+\/[^/?#\s]+)/gmu, '$1' + pkgName); + await fsp.writeFile(readmeFile, contents); + }) + .catch((error) => { + if ('ENOENT' !== error.code) throw error; + }); + } /** * Initializes this as a new git repository. diff --git a/dev/.files/mdx/config.mjs b/dev/.files/mdx/config.mjs index e759cec5..5d79ea90 100644 --- a/dev/.files/mdx/config.mjs +++ b/dev/.files/mdx/config.mjs @@ -15,6 +15,7 @@ import pluginAnchorsPreactXHash from '../rehype/plugins/anchors/preact-x-hash.mj import pluginAnchorsRelExternalNoFollow from '../rehype/plugins/anchors/rel-external-nofollow.mjs'; import pluginFootnotesFixAnchors from '../rehype/plugins/footnotes/fix-anchors.mjs'; import pluginFootnotesFixLabelSection from '../rehype/plugins/footnotes/fix-label-section.mjs'; +import pluginImagesLazy from '../rehype/plugins/images/lazy.mjs'; import pluginStarryNightHeaderExts from '../rehype/plugins/starry-night/header-exts.mjs'; import pluginAlerts from '../remark/plugins/alerts/index.mjs'; import pluginDirectives from '../remark/plugins/directives/index.mjs'; @@ -46,12 +47,13 @@ export default async () => { [pluginTableOfContents], // Runs `remark-toc`, but instead of outputting, we export `TableOfContents`. ], rehypePlugins: [ - [pluginFootnotesFixAnchors], // Modifies `remark-gfm` footnote anchors to enforce a `~` prefix. - [pluginFootnotesFixLabelSection], // Modifies `#footnote-label` section at bottom, generated by `remark-gfm` plugin. [(await import('rehype-slug')).default, { prefix: '~' }], // Auto-generates heading IDs using heading text and counters. [(await import('rehype-autolink-headings')).default, { content: { type: 'text', value: '#' } }], // Auto-links all headings. + [pluginAnchorsRelExternalNoFollow], // Modifies external anchors, adding `rel="external nofollow"`, if applicable, for improved SEO. + [pluginImagesLazy], // Modifies image tags without a `loading` attribute, making them `loading="lazy"` for improved performance. + [pluginFootnotesFixAnchors], // Modifies `remark-gfm` footnote anchors, shortening ID references and enforcing a `~` prefix. + [pluginFootnotesFixLabelSection], // Modifies `#footnote-label` section at bottom, generated by `remark-gfm` plugin. [pluginAnchorsPreactXHash], // Modifies hash-only anchors so they work well with `` in our preact apps. - [pluginAnchorsRelExternalNoFollow], // Modifies external anchors by adding `rel` attribute for improved SEO. // Applies syntax highlighting to fenced code blocks. We also mix in our own custom header extensions. [(await import('@microflash/rehype-starry-night')).default, { headerExtensions: pluginStarryNightHeaderExts }], ], diff --git a/dev/.files/postcss/config.mjs b/dev/.files/postcss/config.mjs index e7442ee8..0d814974 100644 --- a/dev/.files/postcss/config.mjs +++ b/dev/.files/postcss/config.mjs @@ -24,13 +24,17 @@ export default async () => { * Composition. */ return { - /** - * SCSS is not configured here, as it’s already backed into Vite; {@see https://o5p.me/CAJNAF}. To use `*.scss` - * files, just make sure the `sass` package is installed as a dev dependency. Note: Sass runs before postCSS, - * and therefore cannot interpolate Tailwind `theme()` function calls. i.e., Tailwind’s `theme()` function - * works, but don’t try to feed a response into an SCSS variable or function. - */ plugins: [ + (await import('postcss-import')).default(), + (await import('postcss-mixins')).default(), + (await import('postcss-simple-vars')).default(), + (await import('tailwindcss/nesting/index.js')).default(), + + // For some reason, Vite chooses not to resolve `url()` values in CSS whenever they begin with a `#`. + // Unfortunate, because our import aliases use `#`. To fix, we prepend `url()` values starting with `#`, with `&#`. + // See also: `./dev/.files/bin/includes/import-aliases.mjs` for details regarding alias pattern matching formulation. + (await import('postcss-url')).default([{ filter: /./u, url: ({ url }) => (url.startsWith('#') ? '&' + url : url) }]), + // Tailwind CSS plugin. (await import('tailwindcss')).default({ config: path.resolve(projDir, './tailwind.config.mjs') }), diff --git a/dev/.files/rehype/config.mjs b/dev/.files/rehype/config.mjs index 31552485..ebf84d77 100644 --- a/dev/.files/rehype/config.mjs +++ b/dev/.files/rehype/config.mjs @@ -16,6 +16,7 @@ import pluginSlug from 'rehype-slug'; import pluginAnchorsRelExternalNoFollow from './plugins/anchors/rel-external-nofollow.mjs'; import pluginFootnotesFixAnchors from './plugins/footnotes/fix-anchors.mjs'; import pluginFootnotesFixLabelSection from './plugins/footnotes/fix-label-section.mjs'; +import pluginImagesLazy from './plugins/images/lazy.mjs'; import pluginStarryNightHeaderExts from './plugins/starry-night/header-exts.mjs'; /** @@ -28,11 +29,12 @@ export default async () => { return { settings: {}, // No settings at this time. plugins: [ - [pluginFootnotesFixAnchors], // Modifies `remark-gfm` footnote anchors to enforce a `~` prefix. - [pluginFootnotesFixLabelSection], // Modifies section at bottom, generated by `remark-gfm` plugin. [pluginSlug, { prefix: '~' }], // Auto-generates heading IDs using heading text and counters. [pluginAutolinkHeadings, { content: { type: 'text', value: '#' } }], // Auto-links all headings. - [pluginAnchorsRelExternalNoFollow], // Modifies external anchors by adding `rel` attributes. + [pluginAnchorsRelExternalNoFollow], // Modifies external anchors, adding `rel="external nofollow"`, if applicable, for improved SEO. + [pluginImagesLazy], // Modifies image tags without a `loading` attribute, making them `loading="lazy"` for improved performance. + [pluginFootnotesFixAnchors], // Modifies `remark-gfm` footnote anchors, shortening ID references and enforcing a `~` prefix. + [pluginFootnotesFixLabelSection], // Modifies `#footnote-label` section at bottom, generated by `remark-gfm` plugin. // Applies syntax highlighting. We also mix in our own custom header extensions. [pluginStarryNight, { headerExtensions: pluginStarryNightHeaderExts }], ], diff --git a/dev/.files/rehype/plugins/anchors/preact-x-hash.mjs b/dev/.files/rehype/plugins/anchors/preact-x-hash.mjs index ee59e1b6..3d014805 100644 --- a/dev/.files/rehype/plugins/anchors/preact-x-hash.mjs +++ b/dev/.files/rehype/plugins/anchors/preact-x-hash.mjs @@ -21,7 +21,7 @@ export default () => { node.properties.role = node.properties.role || 'link'; node.properties.tabIndex = node.properties.tabIndex || 0; - // Styles `` tags just like `` tags are styled. + // Styles custom element `` just like `` using our own `.link` class. node.properties.class = (node.properties.class || []).concat(node.properties.className || []).concat(['link']); delete node.properties.className; // Removes `className` in favor of `class`. } diff --git a/dev/.files/rehype/plugins/anchors/rel-external-nofollow.mjs b/dev/.files/rehype/plugins/anchors/rel-external-nofollow.mjs index 1490631e..0242640a 100644 --- a/dev/.files/rehype/plugins/anchors/rel-external-nofollow.mjs +++ b/dev/.files/rehype/plugins/anchors/rel-external-nofollow.mjs @@ -9,7 +9,7 @@ import { visit as unistVisit } from 'unist-util-visit'; /** - * Modifies external anchors by adding `rel` attribute for improved SEO. + * Modifies external anchors, adding `rel="external nofollow"`, if applicable, for improved SEO. */ export default () => { return (tree) => { diff --git a/dev/.files/rehype/plugins/footnotes/fix-anchors.mjs b/dev/.files/rehype/plugins/footnotes/fix-anchors.mjs index b95839e8..bf031990 100644 --- a/dev/.files/rehype/plugins/footnotes/fix-anchors.mjs +++ b/dev/.files/rehype/plugins/footnotes/fix-anchors.mjs @@ -9,7 +9,7 @@ import { visit as unistVisit } from 'unist-util-visit'; /** - * Modifies `remark-gfm` footnote anchors to enforce a `~` prefix. + * Modifies `remark-gfm` footnote anchors, shortening ID references and enforcing a `~` prefix. */ export default () => { return (tree) => { @@ -24,7 +24,7 @@ export default () => { if (node.properties.href.startsWith('#user-content-fn-')) { node.properties.href = node.properties.href.replace('#user-content-fn-', '#~fn-'); node.properties.id = (node.properties.id || '').replace('user-content-fnref-', '~fnr-'); - node.properties['aria-describedby'] = '~footnotes'; // Update this. + node.properties.ariaDescribedBy = '~footnotes'; // Update this. node.properties.dataFootnoteRef = null; // Ditch this. // } else if (node.properties.href.startsWith('#user-content-fnref-')) { diff --git a/dev/.files/rehype/plugins/images/lazy.mjs b/dev/.files/rehype/plugins/images/lazy.mjs new file mode 100644 index 00000000..f08720e2 --- /dev/null +++ b/dev/.files/rehype/plugins/images/lazy.mjs @@ -0,0 +1,23 @@ +/** + * Rehype plugin. + * + * @note PLEASE DO NOT EDIT THIS FILE! + * @note This entire file will be updated automatically. + * @note Instead of editing here, please review . + */ + +import { visit as unistVisit } from 'unist-util-visit'; + +/** + * Modifies image tags without a `loading` attribute, making them `loading="lazy"` for improved performance. + */ +export default () => { + return (tree) => { + unistVisit(tree, 'element', (node) => { + if ('img' === node.tagName && !node.properties.loading) { + node.properties.loading = 'lazy'; + } + return node; + }); + }; +}; diff --git a/dev/.files/remark/plugins/alerts/index.mjs b/dev/.files/remark/plugins/alerts/index.mjs index 3cc7adb3..c6c89b7a 100644 --- a/dev/.files/remark/plugins/alerts/index.mjs +++ b/dev/.files/remark/plugins/alerts/index.mjs @@ -24,7 +24,7 @@ export default () => { props.class += ' bg-color-' + (atts.color || 'neutral'); props.class += ' text-color-' + (atts.color || 'neutral') + '-fg'; - props.class += ' border-color-' + (atts.color || 'neutral') + '-bdr'; + props.class += ' border-color-' + (atts.color || 'neutral') + '-line'; if (atts.size) { props.class += ' text-' + atts.size; } diff --git a/dev/.files/tailwind/brand.mjs b/dev/.files/tailwind/brand.mjs new file mode 100644 index 00000000..44c23b1c --- /dev/null +++ b/dev/.files/tailwind/brand.mjs @@ -0,0 +1,41 @@ +/** + * Tailwind brand acquisition. + * + * @note PLEASE DO NOT EDIT THIS FILE! + * @note This entire file will be updated automatically. + * @note Instead of editing here, please review . + */ + +import { execSync } from 'node:child_process'; +import fs from 'node:fs'; +import path from 'node:path'; +import { $brand, $fn, $json, $str } from '../../../node_modules/@clevercanyon/utilities/dist/index.js'; + +// `__dirname` already exists when loaded by Tailwind via Jiti / commonjs. +// eslint-disable-next-line no-undef -- `__dirname` is not actually missing. +const curDir = __dirname; // Current directory. +const projDir = path.resolve(curDir, '../../..'); + +const pkgFile = path.resolve(projDir, './package.json'); +const pkg = $json.parse(fs.readFileSync(pkgFile).toString()); + +/** + * Acquires app’s brand for configuration of Tailwind themes. + * + * Jiti, which is used by Tailwind to load ESM config files, doesn’t support top-level await. Thus, we cannot use async + * functionality here. Consider using a CLI request to acquire resources, if necessary. {@see https://o5p.me/1odhxy}. + */ +export default /* not async compatible */ () => { + let brand = $fn.try(() => $brand.get(pkg.name), undefined)(); + if (brand) return brand; // That was’t such a chore, now was it? + + const baseURL = // Acquires base URL. + process.env._MODE_AWARE_APP_BASE_URL || // Mode-aware. + $str.trim(execSync('./cli-sync/base-url.mjs', { cwd: curDir }).toString()); + if (!baseURL) return; // Not possible; i.e., app has no base URL. + + const brandConfig = $json.parse(execSync('./cli-sync/brand-config.mjs', { cwd: curDir }).toString()); + if (!brandConfig) throw new Error('Missing brand config for Tailwind themes.'); + + return $brand.addApp({ pkgName: pkg.name, baseURL, props: brandConfig }); +}; diff --git a/dev/.files/tailwind/cli-sync/base-url.mjs b/dev/.files/tailwind/cli-sync/base-url.mjs new file mode 100755 index 00000000..4c382c56 --- /dev/null +++ b/dev/.files/tailwind/cli-sync/base-url.mjs @@ -0,0 +1,15 @@ +#!/usr/bin/env node +/** + * Tailwind base URL acquisition. + * + * @note PLEASE DO NOT EDIT THIS FILE! + * @note This entire file will be updated automatically. + * @note Instead of editing here, please review . + */ + +import u from '../../bin/includes/utilities.mjs'; + +/** + * Acquires app’s base URL; i.e., here within a separate CLI process. + */ +console.log((await u.loadEnv({ mode: 'prod' })).APP_BASE_URL || ''); diff --git a/dev/.files/tailwind/cli-sync/brand-config.mjs b/dev/.files/tailwind/cli-sync/brand-config.mjs new file mode 100755 index 00000000..df6852fc --- /dev/null +++ b/dev/.files/tailwind/cli-sync/brand-config.mjs @@ -0,0 +1,16 @@ +#!/usr/bin/env node +/** + * Tailwind brand acquisition. + * + * @note PLEASE DO NOT EDIT THIS FILE! + * @note This entire file will be updated automatically. + * @note Instead of editing here, please review . + */ + +import { $json } from '../../../../node_modules/@clevercanyon/utilities/dist/index.js'; +import u from '../../bin/includes/utilities.mjs'; + +/** + * Acquires app’s brand config; i.e., here within a separate CLI process. + */ +console.log($json.stringify(await u.brandConfig(), { pretty: true })); diff --git a/dev/.files/tailwind/config.mjs b/dev/.files/tailwind/config.mjs index b120c850..7b376306 100644 --- a/dev/.files/tailwind/config.mjs +++ b/dev/.files/tailwind/config.mjs @@ -36,7 +36,7 @@ const projDir = path.resolve(__dirname, '../../..'); * Defines Tailwind configuration. * * Jiti, which is used by Tailwind to load ESM config files, doesn’t support top-level await. Thus, we cannot use async - * functionality here. Consider `make-synchronous` (already in dev-deps) if necessary. {@see https://o5p.me/1odhxy}. + * functionality here. Consider using a CLI request to acquire resources, if necessary. {@see https://o5p.me/1odhxy}. */ export default /* not async compatible */ ({ themesConfig } = {}) => { /** @@ -90,6 +90,11 @@ export default /* not async compatible */ ({ themesConfig } = {}) => { '1.5em': '1.5em', '2em': '2em', }, + lineHeight: { + '1em': '1em', + '1.5em': '1.5em', + '2em': '2em', + }, aspectRatio: { 'image': '40 / 21', // e.g., 1200 x 630 for OG image. }, @@ -125,6 +130,10 @@ export default /* not async compatible */ ({ themesConfig } = {}) => { '2/3': '66.667%', }, fontSize: { + '.5em': ['.5em', '.5em'], + '.75em': ['.75em', '.75em'], + '1em': ['1em', '1em'], + // Neither of these are allowed to autoscale. // We don’t autoscale text that is small already. xs: ['.75rem', { lineHeight: '1rem' }], // Equivalent to 12px/16px. @@ -149,6 +158,9 @@ export default /* not async compatible */ ({ themesConfig } = {}) => { '8xl': ['clamp(2.25rem, 6.667vw, 6rem)', { lineHeight: 'clamp(2.5rem, 7.986vw, 7.188rem)' }], // Equivalent to 96px/115px. '9xl': ['clamp(3rem, 8.889vw, 8rem)', { lineHeight: 'clamp(3.625rem, 10.625vw, 9.563rem)' }], // Equivalent to 128px/153px. }, + boxShadow: { + 'inner-sm': 'inset 0 1px 2px 0 rgb(0 0 0 / 0.05)', + }, /** * Prose styles. * @@ -321,7 +333,7 @@ export default /* not async compatible */ ({ themesConfig } = {}) => { verticalAlign: 'middle', background: 'rgb(var(--colors-color-neutral), .25)', - border: '1px solid rgb(var(--colors-color-neutral-bdr))', + border: '1px solid rgb(var(--colors-color-neutral-line))', borderRadius: '.15em', }, '.task-list-item > input:checked::before': { @@ -362,6 +374,10 @@ export default /* not async compatible */ ({ themesConfig } = {}) => { from: { opacity: 0 }, to: { opacity: 1 }, }, + 'subtle-fade-in': { + from: { opacity: 0.25 }, + to: { opacity: 1 }, + }, 'fade-out': { from: { opacity: 1 }, to: { opacity: 0 }, @@ -370,6 +386,7 @@ export default /* not async compatible */ ({ themesConfig } = {}) => { animation: { 'fade-in': 'fade-in 150ms linear', 'fade-out': 'fade-out 150ms linear', + 'subtle-fade-in': 'subtle-fade-in 150ms linear', }, }, }, diff --git a/dev/.files/tailwind/imports/starry-night.scss b/dev/.files/tailwind/imports/starry-night.scss new file mode 100644 index 00000000..27f6b395 --- /dev/null +++ b/dev/.files/tailwind/imports/starry-night.scss @@ -0,0 +1,298 @@ +/** + * Starry night styles. + */ + +/** + * Rehype plugin {@see https://o5p.me/fSI3OT}. + * `.highlight*` classes are generated by plugin. + */ + +// Code block container. +.highlight { + overflow: hidden; + line-height: 1em; + background: rgb(var(--colors-color-starry-night)); + border: 1px solid rgb(var(--colors-color-starry-night-border)); + border-radius: 0.375rem; +} + +// Header inside code block container. +.highlight-header { + display: flex; + gap: 0.5em; + justify-content: space-between; + padding: 0.5em; + color: rgb(var(--colors-color-starry-night-header-fg)); + background: rgb(var(--colors-color-starry-night-header)); + border-block-end: 1px solid rgb(var(--colors-color-starry-night-border)); + border-radius: 0.375rem 0.375rem 0 0; +} + +// Language inside code block header. +.highlight-language { + padding: 0.25em 0.5em 0.15em; + font-family: ui-monospace, monospace; + font-size: 0.75em; + color: rgb(var(--colors-color-starry-night-header-language-fg)); + text-transform: uppercase; + background: rgb(var(--colors-color-starry-night-header-language)); + border-radius: 0.1875rem; +} + +// Copy button inside code block header. +.highlight-copy { + position: relative; + user-select: none; + + &:disabled { + pointer-events: none; + opacity: 0.7; + } + + &::after { + margin: 0 0 0 0.5em; + line-height: 1em; + vertical-align: middle; + content: '❏'; + } + + &::before { + position: absolute; + top: -25px; + left: -18px; + color: rgb(var(--colors-color-success)); + content: '✔'; + opacity: 0; + } + + &:not(.-copy-success)::before { + top: 0; + visibility: hidden; + opacity: 1; + } + + &.-copy-success::before { + transition: + opacity 1s, + top 1s; + } +} + +// Nested highlight styles. +.highlight { + // `
` tag.
+    > pre {
+        padding: 0.8571em 0;
+        margin: 0;
+        background: none;
+        border: 0;
+        border-radius: 0;
+        box-shadow: inset 0 0 2px 2px rgb(var(--colors-color-starry-night-box-shadows));
+
+        // `` tag.
+        > code {
+            display: grid;
+            color: rgb(var(--colors-color-starry-night-fg));
+        }
+    }
+
+    // Lines of code.
+    .line {
+        padding-inline: 1.1428em;
+
+        // Focused and/or hovered lines of code.
+        &:hover,
+        &:focus:not(:focus-visible) {
+            background: rgb(var(--colors-color-starry-night-hilited-lines));
+        }
+    }
+
+    // Lines of code line numbers.
+    .line-number {
+        margin-inline-end: 1em;
+        color: rgb(var(--colors-color-starry-night-syntax-gutter-mark-fg));
+        user-select: none;
+    }
+
+    // Copy-in-progress and highlighted lines of code.
+    > pre.-copy-in-progress .line,
+    .line[data-highlighted] {
+        background: rgb(var(--colors-color-starry-night-hilited-lines));
+
+        // Highlighted line numbers.
+        .line-number {
+            color: rgb(var(--colors-color-starry-night-syntax-comment-fg));
+        }
+    }
+
+    // Highlighted lines of code.
+    .line[data-highlighted] {
+        border-inline-start: 2px solid rgb(var(--colors-color-starry-night-syntax-comment-fg));
+    }
+
+    // Lines with shell prompt icons.
+    .line-prompt {
+        &::before {
+            display: inline-block;
+            width: 1em;
+            height: 1em;
+            margin-inline: -0.175em 0.35em;
+            vertical-align: middle;
+            content: '';
+            background: rgb(var(--colors-color-starry-night-syntax-comment-fg));
+        }
+
+        &::before {
+            // Define as a variable so that when autoprefixer runs it won’t end up duplicating this lengthy value.
+            --highlight-line-prompt-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' fill-rule='evenodd' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' clip-rule='evenodd' viewBox='0 0 24 24'%3E%3Cpath d='M17 6C13 3 6 3 6 8c1 5 12 2 12 7 0 6-8 6-12 3m6-16v20'/%3E%3C/svg%3E");
+
+            mask-image: var(--highlight-line-prompt-mask-image);
+            mask-repeat: no-repeat;
+            mask-position: top center;
+            mask-size: contain;
+        }
+    }
+}
+
+/**
+ * Pretty lights syntax; {@see https://o5p.me/i6E6m1}.
+ * `.pl*` syntax classes are generated by pretty lights.
+ */
+
+// Bold.
+.pl-mb {
+    font-weight: bold;
+}
+
+// Italic.
+.pl-mi {
+    font-style: italic;
+}
+
+// Comments.
+.pl-c {
+    color: rgb(var(--colors-color-starry-night-syntax-comment-fg));
+}
+
+// Gutter marks; e.g., line numbers.
+.pl-sg {
+    color: rgb(var(--colors-color-starry-night-syntax-gutter-mark-fg));
+}
+
+// Punctuation.
+.pl-pds,
+.pl-ms,
+.pl-ml {
+    color: rgb(var(--colors-color-starry-night-syntax-punctuation-fg));
+}
+
+// Keywords.
+.pl-k {
+    color: rgb(var(--colors-color-starry-night-syntax-keyword-fg));
+}
+
+// Variables.
+.pl-v,
+.pl-smw {
+    color: rgb(var(--colors-color-starry-night-syntax-variable-fg));
+}
+
+// Constants.
+.pl-c1,
+.pl-s .pl-v {
+    color: rgb(var(--colors-color-starry-night-syntax-constant-fg));
+}
+
+// Modifiers.
+.pl-smi,
+.pl-s .pl-s1 {
+    color: rgb(var(--colors-color-starry-night-syntax-modifier-fg));
+}
+
+// Entities.
+.pl-e,
+.pl-en {
+    color: rgb(var(--colors-color-starry-night-syntax-entity-fg));
+}
+
+// Entity tags.
+.pl-ent {
+    color: rgb(var(--colors-color-starry-night-syntax-entity-tag-fg));
+}
+
+// Other; e.g., markdown links.
+.pl-corl {
+    color: rgb(var(--colors-color-starry-night-syntax-other-link-fg));
+    text-decoration: underline;
+}
+
+// Various strings.
+.pl-s,
+.pl-s .pl-pse .pl-s1,
+.pl-sr,
+.pl-sr .pl-cce,
+.pl-sr .pl-sre,
+.pl-sr .pl-sra {
+    color: rgb(var(--colors-color-starry-night-syntax-string-fg));
+}
+
+// Regular expressions.
+.pl-sr .pl-cce {
+    font-weight: bold;
+    color: rgb(var(--colors-color-starry-night-syntax-regexp-fg));
+}
+
+// Markdown headers.
+.pl-mh,
+.pl-mh .pl-en {
+    font-weight: bold;
+    color: rgb(var(--colors-color-starry-night-syntax-entity-tag-fg));
+}
+
+// Range notation in a diff/patch.
+.pl-mdr {
+    font-weight: bold;
+    color: rgb(var(--colors-color-dazzle));
+}
+
+// New added lines in a diff/patch.
+.pl-mi1 {
+    color: rgb(var(--colors-color-success-fg));
+    background: rgb(var(--colors-color-success));
+}
+
+// Old removed lines in a diff/patch.
+.pl-md {
+    color: rgb(var(--colors-color-danger-fg));
+    background: rgb(var(--colors-color-danger));
+}
+
+// Changed lines in a diff/patch.
+.pl-mc {
+    color: rgb(var(--colors-color-warning-fg));
+    background: rgb(var(--colors-color-warning));
+}
+
+// Ignored lines in a diff/patch.
+.pl-mi2 {
+    color: rgb(var(--colors-color-neutral-fg));
+    background: rgb(var(--colors-color-neutral));
+}
+
+// Illegal, broken, or unrecognized syntax.
+.pl-ii {
+    color: rgb(var(--colors-color-danger-fg));
+    background: rgb(var(--colors-color-danger));
+}
+
+// Untested. Some kind of brackets.
+.pl-ba,
+.pl-bu {
+    color: rgb(var(--colors-color-dazzle));
+}
+
+// Untested. Possibly whitespace.
+.pl-c2 {
+    color: rgb(var(--colors-color-dark-fg));
+    background: rgb(var(--colors-color-dark));
+}
diff --git a/dev/.files/tailwind/layers.scss b/dev/.files/tailwind/layers.scss
index 491d652d..d3862e33 100644
--- a/dev/.files/tailwind/layers.scss
+++ b/dev/.files/tailwind/layers.scss
@@ -1,102 +1,110 @@
 /**
- * Charset.
+ * Starry night styles.
  */
-@charset "UTF-8"; // Must use double quotes.
+@import './imports/starry-night.scss' layer(components);
 
 /**
-  * Defaults.
-  */
-$google-fonts: (
-    'Georama': 'ital,wght@0,100..900;1,100..900',
-) !default;
+ * Our base layer.
+ *
+ * We borrow the `_` = `not-prose` selector here and reuse it as `not-basic`.
+ * It works fine, because all basic styles already exclude `p` = `prose` altogether.
+ *
+ * - In our Tailwind implementation, class `p` = `prose`.
+ * - In our Tailwind implementation, a much shorter `_` = `not-p` = `not-prose`.
+ * - In our basic styles implementation, `_` = `not-p` = `not-prose` = `not-basic`.
+ * - In our Tailwind prose implementation, `~` = prose colors should be inherited from a parent containing
+ *   the special `~` class; e.g., if a component applies colors that differ from prose colors, it needs to make
+ *   sure any prose it contains will inherit the colors it has assigned, and not use the default prose colors.
+ *   So `~` is an alternative to `_`, indicating prose is allowed, but it must use inherited coloration.
+ */
+@layer base {
+    /**
+     * Scrollbars.
+     */
+    ::-webkit-scrollbar {
+        @apply w-2;
+        @apply h-2;
+    }
 
-/**
-  * Various mixins.
-  */
-@use './mixins/starry-night';
+    ::-webkit-scrollbar-thumb {
+        @apply rounded;
+        @apply bg-color-basic-fg/25;
 
-/**
-  * Google fonts.
-  */
-@each $family, $weights in $google-fonts {
-    // This import is ok. It must use `url()` for variable interpolation to work properly.
-    /* stylelint-disable-next-line no-invalid-position-at-import-rule, import-notation -- ok. */
-    @import url('https://fonts.googleapis.com/css2?family=#{$family}:#{$weights}&display=swap');
-}
+        &:hover {
+            @apply bg-color-basic-fg/50;
+        }
+    }
 
-/**
-  * Tailwind layers.
-  */
-@tailwind base;
-@tailwind components;
-@include starry-night.styles;
-@tailwind utilities;
-@tailwind variants;
+    ::-webkit-scrollbar-track {
+        @apply bg-color-basic-fg/5;
+    }
 
-/**
-  * Our base layer.
-  *
-  * We borrow the `_` = `not-prose` selector here and reuse it as `not-basic`.
-  * It works fine, because all basic styles already exclude `p` = `prose` altogether.
-  *
-  * - In our Tailwind implementation, class `p` = `prose`.
-  * - In our Tailwind implementation, a much shorter `_` = `not-p` = `not-prose`.
-  * - In our basic styles implementation, `_` = `not-p` = `not-prose` = `not-basic`.
-  *
-  * Also worth noting that in our Tailwind prose implementation, the `~` class means prose colors
-  * should be inherited from the parent containing the `~` class; e.g., if a component applies colors
-  * that differ from prose colors, then it needs to make sure any prose it contains will inherit the colors
-  * it has assigned, and not use the default prose colors. So `~` is an alternative to `_`, indicating
-  * that prose is to be allowed, but it must use inherited coloration.
-  */
-@layer base {
+    /**
+     * Basic HTML styles.
+     */
     html {
+        @apply bg-color-basic text-color-basic-fg;
+
         font-size: 16px; // No auto-scaling at root node.
+    }
 
-        @apply bg-color-basic text-color-basic-fg;
+    /**
+     * Basic link styles and color.
+     */
+    :where(a, .link):not(:where(.p, .p *, ._, ._ *)) {
+        @apply cursor-pointer text-color-basic-link no-underline opacity-90 hover:underline hover:opacity-100;
+    }
 
-        :where(a, .link):not(:where(.p, .p *, ._, ._ *)) {
-            @apply cursor-pointer text-color-basic-link no-underline opacity-90 hover:underline hover:opacity-100;
-        }
+    /**
+     * Basic heading color.
+     */
+    :where(h1, h2, h3, h4, h5, h6):not(:where(.p, .p *, ._, ._ *)) {
+        @apply text-color-basic-heading;
+    }
 
-        :where(h1, h2, h3, h4, h5, h6):not(:where(.p, .p *, ._, ._ *)) {
-            @apply text-color-basic-heading;
-        }
+    /**
+     * Form element placeholders.
+     */
+    input::placeholder,
+    textarea::placeholder,
+    select:has(> :checked[data-placeholder]) {
+        @apply italic;
 
-        ::-webkit-scrollbar {
-            @apply w-2;
-            @apply h-2;
-        }
+        color: rgb(from rgb(var(--colors-color-basic-fg)) r g b / calc(alpha - 0.5));
+    }
+
+    /**
+     * Beautify select elements.
+     */
+    label:has(> select) {
+        @apply relative;
 
-        ::-webkit-scrollbar-thumb {
-            @apply rounded;
-            @apply bg-color-basic-fg/25;
+        &::before {
+            @apply absolute rotate-90 text-.75em opacity-50;
 
-            &:hover {
-                @apply bg-color-basic-fg/50;
-            }
+            top: calc(50% - 0.75em / 2);
+            right: 1.25em;
+            content: '❯';
         }
 
-        ::-webkit-scrollbar-track {
-            @apply bg-color-basic-fg/5;
+        > select {
+            @apply cursor-pointer appearance-none;
         }
     }
 
+    /**
+     * Basic header link color.
+     */
     .basic-header {
-        @apply border-color-header-bdr bg-color-header text-color-header-fg;
-
         :where(a, .link):not(:where(.p, .p *, ._, ._ *)) {
             @apply text-color-header-link;
         }
-
-        :where(h1, h2, h3, h4, h5, h6):not(:where(.p, .p *, ._, ._ *)) {
-            @apply text-color-header-heading;
-        }
     }
 
+    /**
+     * Basic sidebar link and heading colors.
+     */
     .basic-sidebar {
-        @apply border-color-sidebar-bdr bg-color-sidebar text-color-sidebar-fg;
-
         :where(a, .link):not(:where(.p, .p *, ._, ._ *)) {
             @apply text-color-sidebar-link;
         }
@@ -106,25 +114,22 @@ $google-fonts: (
         }
     }
 
+    /**
+     * Basic footer link color.
+     */
     .basic-footer {
-        @apply border-color-footer-bdr bg-color-footer text-color-footer-fg;
-
         :where(a, .link):not(:where(.p, .p *, ._, ._ *)) {
             @apply text-color-footer-link;
         }
-
-        :where(h1, h2, h3, h4, h5, h6):not(:where(.p, .p *, ._, ._ *)) {
-            @apply text-color-footer-heading;
-        }
     }
 }
 
 /**
-  * Our utilities layer.
-  *
-  * All of our utilities get prefixed with a leading `_` to help indicate what is being used.
-  * In the same way that all of our JS utilities are prefixed with a `$` sign, we use `_` in CSS.
-  */
+ * Our utilities layer.
+ *
+ * All of our utilities get prefixed with a leading `_` to help indicate what is being used.
+ * In the same way that all of our JS utilities are prefixed with a `$` sign, we use `_` in CSS.
+ */
 @layer utilities {
     // Y margins like prose `p` tag.
     ._my-lp {
@@ -146,3 +151,11 @@ $google-fonts: (
         }
     }
 }
+
+/**
+ * Tailwind layers.
+ */
+@tailwind base;
+@tailwind components;
+@tailwind utilities;
+@tailwind variants;
diff --git a/dev/.files/tailwind/mixins/_starry-night.scss b/dev/.files/tailwind/mixins/_starry-night.scss
deleted file mode 100644
index 1e27f64f..00000000
--- a/dev/.files/tailwind/mixins/_starry-night.scss
+++ /dev/null
@@ -1,299 +0,0 @@
-/**
- * Starry night styles.
- */
-@mixin styles {
-    /*
-     * Rehype plugin {@see https://o5p.me/fSI3OT}.
-     * `.highlight*` classes are generated by plugin.
-     */
-
-    // Code block container.
-    .highlight {
-        overflow: hidden;
-        line-height: 1em;
-        background: rgb(var(--colors-color-starry-night));
-        border: 1px solid rgb(var(--colors-color-starry-night-border));
-        border-radius: 0.375rem;
-    }
-
-    // Header inside code block container.
-    .highlight-header {
-        display: flex;
-        gap: 0.5em;
-        justify-content: space-between;
-        padding: 0.5em;
-        color: rgb(var(--colors-color-starry-night-header-fg));
-        background: rgb(var(--colors-color-starry-night-header));
-        border-block-end: 1px solid rgb(var(--colors-color-starry-night-border));
-        border-radius: 0.375rem 0.375rem 0 0;
-    }
-
-    // Language inside code block header.
-    .highlight-language {
-        padding: 0.25em 0.5em 0.15em;
-        font-family: ui-monospace, monospace;
-        font-size: 0.75em;
-        color: rgb(var(--colors-color-starry-night-header-language-fg));
-        text-transform: uppercase;
-        background: rgb(var(--colors-color-starry-night-header-language));
-        border-radius: 0.1875rem;
-    }
-
-    // Copy button inside code block header.
-    .highlight-copy {
-        position: relative;
-        user-select: none;
-
-        &:disabled {
-            pointer-events: none;
-            opacity: 0.7;
-        }
-
-        &::after {
-            margin: 0 0 0 0.5em;
-            line-height: 1em;
-            vertical-align: middle;
-            content: '❏';
-        }
-
-        &::before {
-            position: absolute;
-            top: -25px;
-            left: -18px;
-            color: rgb(var(--colors-color-success));
-            content: '✔';
-            opacity: 0;
-        }
-
-        &:not(.-copy-success)::before {
-            top: 0;
-            visibility: hidden;
-            opacity: 1;
-        }
-
-        &.-copy-success::before {
-            transition:
-                opacity 1s,
-                top 1s;
-        }
-    }
-
-    // Nested highlight styles.
-    .highlight {
-        // `
` tag.
-        > pre {
-            padding: 0.8571em 0;
-            margin: 0;
-            background: none;
-            border: 0;
-            border-radius: 0;
-            box-shadow: inset 0 0 2px 2px rgb(var(--colors-color-starry-night-box-shadows));
-
-            // `` tag.
-            > code {
-                display: grid;
-                color: rgb(var(--colors-color-starry-night-fg));
-            }
-        }
-
-        // Lines of code.
-        .line {
-            padding-inline: 1.1428em;
-
-            // Focused and/or hovered lines of code.
-            &:hover,
-            &:focus:not(:focus-visible) {
-                background: rgb(var(--colors-color-starry-night-hilited-lines));
-            }
-        }
-
-        // Lines of code line numbers.
-        .line-number {
-            margin-inline-end: 1em;
-            color: rgb(var(--colors-color-starry-night-syntax-gutter-mark-fg));
-            user-select: none;
-        }
-
-        // Copy-in-progress and highlighted lines of code.
-        > pre.-copy-in-progress .line,
-        .line[data-highlighted] {
-            background: rgb(var(--colors-color-starry-night-hilited-lines));
-
-            // Highlighted line numbers.
-            .line-number {
-                color: rgb(var(--colors-color-starry-night-syntax-comment-fg));
-            }
-        }
-
-        // Highlighted lines of code.
-        .line[data-highlighted] {
-            border-inline-start: 2px solid rgb(var(--colors-color-starry-night-syntax-comment-fg));
-        }
-
-        // Lines with shell prompt icons.
-        .line-prompt {
-            &::before {
-                display: inline-block;
-                width: 1em;
-                height: 1em;
-                margin-inline: -0.175em 0.35em;
-                vertical-align: middle;
-                content: '';
-                background: rgb(var(--colors-color-starry-night-syntax-comment-fg));
-            }
-
-            &::before {
-                // Define as a variable so that when autoprefixer runs it won’t end up duplicating this lengthy value.
-                --highlight-line-prompt-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' fill-rule='evenodd' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' clip-rule='evenodd' viewBox='0 0 24 24'%3E%3Cpath d='M17 6C13 3 6 3 6 8c1 5 12 2 12 7 0 6-8 6-12 3m6-16v20'/%3E%3C/svg%3E");
-
-                mask-image: var(--highlight-line-prompt-mask-image);
-                mask-repeat: no-repeat;
-                mask-position: top center;
-                mask-size: contain;
-            }
-        }
-    }
-
-    /*
-     * Pretty lights syntax; {@see https://o5p.me/i6E6m1}.
-     * `.pl*` syntax classes are generated by pretty lights.
-     */
-
-    // Bold.
-    .pl-mb {
-        font-weight: bold;
-    }
-
-    // Italic.
-    .pl-mi {
-        font-style: italic;
-    }
-
-    // Comments.
-    .pl-c {
-        color: rgb(var(--colors-color-starry-night-syntax-comment-fg));
-    }
-
-    // Gutter marks; e.g., line numbers.
-    .pl-sg {
-        color: rgb(var(--colors-color-starry-night-syntax-gutter-mark-fg));
-    }
-
-    // Punctuation.
-    .pl-pds,
-    .pl-ms,
-    .pl-ml {
-        color: rgb(var(--colors-color-starry-night-syntax-punctuation-fg));
-    }
-
-    // Keywords.
-    .pl-k {
-        color: rgb(var(--colors-color-starry-night-syntax-keyword-fg));
-    }
-
-    // Variables.
-    .pl-v,
-    .pl-smw {
-        color: rgb(var(--colors-color-starry-night-syntax-variable-fg));
-    }
-
-    // Constants.
-    .pl-c1,
-    .pl-s .pl-v {
-        color: rgb(var(--colors-color-starry-night-syntax-constant-fg));
-    }
-
-    // Modifiers.
-    .pl-smi,
-    .pl-s .pl-s1 {
-        color: rgb(var(--colors-color-starry-night-syntax-modifier-fg));
-    }
-
-    // Entities.
-    .pl-e,
-    .pl-en {
-        color: rgb(var(--colors-color-starry-night-syntax-entity-fg));
-    }
-
-    // Entity tags.
-    .pl-ent {
-        color: rgb(var(--colors-color-starry-night-syntax-entity-tag-fg));
-    }
-
-    // Other; e.g., markdown links.
-    .pl-corl {
-        color: rgb(var(--colors-color-starry-night-syntax-other-link-fg));
-        text-decoration: underline;
-    }
-
-    // Various strings.
-    .pl-s,
-    .pl-s .pl-pse .pl-s1,
-    .pl-sr,
-    .pl-sr .pl-cce,
-    .pl-sr .pl-sre,
-    .pl-sr .pl-sra {
-        color: rgb(var(--colors-color-starry-night-syntax-string-fg));
-    }
-
-    // Regular expressions.
-    .pl-sr .pl-cce {
-        font-weight: bold;
-        color: rgb(var(--colors-color-starry-night-syntax-regexp-fg));
-    }
-
-    // Markdown headers.
-    .pl-mh,
-    .pl-mh .pl-en {
-        font-weight: bold;
-        color: rgb(var(--colors-color-starry-night-syntax-entity-tag-fg));
-    }
-
-    // Range notation in a diff/patch.
-    .pl-mdr {
-        font-weight: bold;
-        color: rgb(var(--colors-color-dazzle));
-    }
-
-    // New added lines in a diff/patch.
-    .pl-mi1 {
-        color: rgb(var(--colors-color-success-fg));
-        background: rgb(var(--colors-color-success));
-    }
-
-    // Old removed lines in a diff/patch.
-    .pl-md {
-        color: rgb(var(--colors-color-danger-fg));
-        background: rgb(var(--colors-color-danger));
-    }
-
-    // Changed lines in a diff/patch.
-    .pl-mc {
-        color: rgb(var(--colors-color-warning-fg));
-        background: rgb(var(--colors-color-warning));
-    }
-
-    // Ignored lines in a diff/patch.
-    .pl-mi2 {
-        color: rgb(var(--colors-color-neutral-fg));
-        background: rgb(var(--colors-color-neutral));
-    }
-
-    // Illegal, broken, or unrecognized syntax.
-    .pl-ii {
-        color: rgb(var(--colors-color-danger-fg));
-        background: rgb(var(--colors-color-danger));
-    }
-
-    // Untested. Some kind of brackets.
-    .pl-ba,
-    .pl-bu {
-        color: rgb(var(--colors-color-dazzle));
-    }
-
-    // Untested. Possibly whitespace.
-    .pl-c2 {
-        color: rgb(var(--colors-color-dark-fg));
-        background: rgb(var(--colors-color-dark));
-    }
-}
diff --git a/dev/.files/tailwind/themes.mjs b/dev/.files/tailwind/themes.mjs
index 77d1e514..9f2fe833 100644
--- a/dev/.files/tailwind/themes.mjs
+++ b/dev/.files/tailwind/themes.mjs
@@ -16,16 +16,17 @@ Example `index.scss` starter file contents:
 -------------------------------------------------------------------------------------------------------------------- */
 
 import { $color, $is, $obj } from '../../../node_modules/@clevercanyon/utilities/dist/index.js';
+import getBrand from './brand.mjs'; // Uses `make-synchronous` to acquire brand in a Tailwind/Jiti context.
 
 /**
  * Merges Tailwind themes configuration.
  *
  * Jiti, which is used by Tailwind to load ESM config files, doesn’t support top-level await. Thus, we cannot use async
- * functionality here. Consider `make-synchronous` (already in dev-deps) if necessary. {@see https://o5p.me/1odhxy}.
+ * functionality here. Consider using a CLI request to acquire resources, if necessary. {@see https://o5p.me/1odhxy}.
  */
 export default /* not async compatible */ ({ themesConfig } = {}) => {
     /**
-     * Gets themes.
+     * Acquires themes.
      */
     let themes; // Initialize.
 
@@ -38,6 +39,11 @@ export default /* not async compatible */ ({ themesConfig } = {}) => {
     themes.themes = $is.array(themes.themes) ? themes.themes : [];
     themes.themes.map((theme) => Object(theme || {}));
 
+    /**
+     * Acquires app’s brand theme.
+     */
+    const brandTheme = getBrand()?.theme || {};
+
     /**
      * Sets color defaults, for each theme, using basic colors.
      */
@@ -51,28 +57,29 @@ export default /* not async compatible */ ({ themesConfig } = {}) => {
         /**
          * Defines basic colors.
          *
-         * - Basic palette: {@see https://coolors.co/09090b-f0f0f0-80aff9-ffffff}.
+         * - Basic palette: {@see https://coolors.co/09090b-f0f0f0-80aff9-17171c-ffffff}.
          *
          * From these basic colors we derive additional colors for commonly-used sections automatically, such as those
          * prefixed as `color-prose-*`, `color-header-*`, `color-sidebar-*`, `color-footer-*`. If you'd like to override
          * any basic color derivations, explicitly define the colors you wish to override.
          *
          * 💡 Tip: Fast track. Just change `color-basic-link` to match your brand colors. The other colors use common
-         * defaults that typically work well for most brands. Tune the rest in later.
+         * defaults that typically work well for most brands. Tune the rest in later. It is generally a good practice to
+         * simply reuse the colors defined by your brand theme; see: `./brand.config.mjs`.
          *
          * 💡 Tip: If you change `color-basic`, please remember to adjust `themeIsDark` in ``
          * accordingly; i.e., if your theme is dark, then `themeIsDark` should be set to `true`, such that consumers of
          * `` are aware. Simply map themes by name in your `` implementation.
          */
         const defaultBasicColors = {
-            'color-basic': '#09090b', // Background color.
-            'color-basic-fg': '#f0f0f0', // Foreground color.
-            'color-basic-bdr': '#17171c', // Border color.
-            'color-basic-link': '#80aff9', // Link/anchor color.
-            'color-basic-heading': '#ffffff', // Heading color.
+            'color-basic': brandTheme.color || '#09090b', // Background color.
+            'color-basic-fg': brandTheme.fgColor || '#f0f0f0', // Foreground color.
+            'color-basic-link': brandTheme.linkColor || '#80aff9', // Link/anchor color.
+            'color-basic-line': brandTheme.lineColor || '#17171c', // Line/border color.
+            'color-basic-heading': brandTheme.headingColor || '#ffffff', // Heading color.
         };
         const basicColors = $obj.defaults({}, $obj.pick(theme.extend.colors, Object.keys(defaultBasicColors)), defaultBasicColors);
-        const basicBGIsDark = $color.isDark(basicColors['color-basic']); // Detects basic background color being dark.
+        const basicBGIsDark = basicColors['color-basic'] === brandTheme.color ? brandTheme.isDark : $color.isDark(basicColors['color-basic']);
 
         /**
          * Defines basic prose colors.
@@ -136,20 +143,20 @@ export default /* not async compatible */ ({ themesConfig } = {}) => {
         const defaultBasicSectionColors = {
             'color-header': $color[basicBGIsDark ? 'darken' : 'lighten'](basicColors['color-basic'], 0.015),
             'color-header-fg': $color[basicBGIsDark ? 'darken' : 'lighten'](basicColors['color-basic-fg'], 0.015),
-            'color-header-bdr': $color[basicBGIsDark ? 'lighten' : 'darken'](basicColors['color-basic'], 0.075),
             'color-header-link': $color[basicBGIsDark ? 'darken' : 'lighten'](basicColors['color-basic-link'], 0.015),
+            'color-header-line': $color[basicBGIsDark ? 'lighten' : 'darken'](basicColors['color-basic'], 0.075),
             'color-header-heading': $color[basicBGIsDark ? 'darken' : 'lighten'](basicColors['color-basic-heading'], 0.015),
 
             'color-sidebar': $color[basicBGIsDark ? 'darken' : 'lighten'](basicColors['color-basic'], 0.015),
             'color-sidebar-fg': $color[basicBGIsDark ? 'darken' : 'lighten'](basicColors['color-basic-fg'], 0.015),
-            'color-sidebar-bdr': $color[basicBGIsDark ? 'lighten' : 'darken'](basicColors['color-basic'], 0.075),
             'color-sidebar-link': $color[basicBGIsDark ? 'darken' : 'lighten'](basicColors['color-basic-link'], 0.015),
+            'color-sidebar-line': $color[basicBGIsDark ? 'lighten' : 'darken'](basicColors['color-basic'], 0.075),
             'color-sidebar-heading': $color[basicBGIsDark ? 'darken' : 'lighten'](basicColors['color-basic-heading'], 0.015),
 
             'color-footer': $color[basicBGIsDark ? 'darken' : 'lighten'](basicColors['color-basic'], 0.015),
             'color-footer-fg': $color[basicBGIsDark ? 'darken' : 'lighten'](basicColors['color-basic-fg'], 0.015),
-            'color-footer-bdr': $color[basicBGIsDark ? 'lighten' : 'darken'](basicColors['color-basic'], 0.075),
             'color-footer-link': $color[basicBGIsDark ? 'darken' : 'lighten'](basicColors['color-basic-link'], 0.015),
+            'color-footer-line': $color[basicBGIsDark ? 'lighten' : 'darken'](basicColors['color-basic'], 0.075),
             'color-footer-heading': $color[basicBGIsDark ? 'darken' : 'lighten'](basicColors['color-basic-heading'], 0.015),
         };
 
@@ -197,7 +204,7 @@ export default /* not async compatible */ ({ themesConfig } = {}) => {
         };
         for (const [name, value] of Object.entries(defaultBrandColors)) {
             defaultBrandColors[name + '-fg'] = $color.getReadable(value);
-            defaultBrandColors[name + '-bdr'] = $color[basicBGIsDark ? 'lighten' : 'darken'](value, 0.075);
+            defaultBrandColors[name + '-line'] = $color[basicBGIsDark ? 'lighten' : 'darken'](value, 0.075);
         } // We go ahead and calculate brand colors so they can be used for starry night defaults below.
         const brandColors = $obj.defaults({}, $obj.pick(theme.extend.colors, Object.keys(defaultBrandColors)), defaultBrandColors);
 
@@ -301,27 +308,16 @@ const baseConfigThemes = /* not async compatible */ () => {
         extend: {
             /**
              * Defines font families.
-             *
-             * If font families are customized in ways that introduce new Google fonts, then those new Google fonts must
-             * be declared as an SCSS map in order to configure our Tailwind layers. The variable is `$google-fonts`.
-             * Add the variale to your `./index.scss` file before `@use '../dev/.files/tailwind/layers';`.
-             *
-             *     $google-fonts: ( 'Georama': 'ital,wght@0,100..900;1,100..900' );
              */
             fontFamily: {
                 sans: [
-                    'Georama', //
-                    'ui-sans-serif',
-                    'sans-serif',
-                ],
-                serif: [
-                    'ui-serif', //
-                    'serif',
-                ],
-                mono: [
-                    'ui-monospace', //
-                    'monospace',
+                    'sans-serif', //
+                    'Apple Color Emoji',
+                    'Segoe UI Emoji',
+                    'Segoe UI Symbol',
                 ],
+                serif: ['serif'],
+                mono: ['monospace'],
             },
 
             /**
diff --git a/dev/.files/vite/config.mjs b/dev/.files/vite/config.mjs
index 31a1c52b..32d9c96f 100644
--- a/dev/.files/vite/config.mjs
+++ b/dev/.files/vite/config.mjs
@@ -20,8 +20,10 @@ import extensions from '../bin/includes/extensions.mjs';
 import importAliases from '../bin/includes/import-aliases.mjs';
 import u from '../bin/includes/utilities.mjs';
 import viteA16sDir from './includes/a16s/dir.mjs';
+import viteC10nBrandConfig from './includes/c10n/brand-config.mjs';
+import viteC10nNoModulePreloadConfig from './includes/c10n/no-module-preload.mjs';
 import viteC10nPostProcessingConfig from './includes/c10n/post-processing.mjs';
-import viteC10nTransformsConfig from './includes/c10n/transforms.mjs';
+import viteC10nSideEffectsConfig from './includes/c10n/side-effects.mjs';
 import viteDTSConfig from './includes/dts/config.mjs';
 import viteEJSConfig from './includes/ejs/config.mjs';
 import viteESBuildConfig from './includes/esbuild/config.mjs';
@@ -32,6 +34,7 @@ import viteMinifyConfig from './includes/minify/config.mjs';
 import vitePkgUpdates from './includes/package/updates.mjs';
 import vitePrefreshConfig from './includes/prefresh/config.mjs';
 import viteRollupConfig from './includes/rollup/config.mjs';
+import viteTerserConfig from './includes/terser/config.mjs';
 import viteVitestConfig from './includes/vitest/config.mjs';
 
 /**
@@ -82,12 +85,30 @@ export default async ({ mode, command, isSsrBuild: isSSRBuild }) => {
     if (isSSRBuild) appEnvPrefixes.push('SSR_APP_'); // Added to SSR builds.
     const env = loadEnv(mode, envsDir, appEnvPrefixes); // Includes `APP_IS_VITE`.
 
+    const appBaseURL = env.APP_BASE_URL || '';
+    // A trailing slash or no trailing slash; it definitely matters!
+    // e.g., `new URL('./', 'https://example.com/')` = `https://example.com/`.
+    // e.g., `new URL('./', 'https://example.com/base')` = `https://example.com/`.
+    // e.g., `new URL('./', 'https://example.com/base/')` = `https://example.com/base/`.
+
+    // We leave it up to the implementation to decide which it prefers to use.
+    // A base URL is only required for some app types; e.g., `spa|mpa`. Validation below.
+
+    // This is a variant of the base URL that’s resolved and has no trailing slash.
+    const appBaseURLResolvedNTS = appBaseURL ? $str.rTrim(new URL('./', appBaseURL).toString(), '/') : '';
+
+    // No other choice at this time, we have to store this in an environment variable for Tailwind configuration.
+    // This uses a leading underscore to avoid contaminating current environment variables in @clevercanyon/utilities.
+    process.env._MODE_AWARE_APP_BASE_URL = appBaseURL; // Informs brand acquisition in our Tailwind configuration file.
+
     const staticDefs = {
         ['$$__' + appEnvPrefixes[0] + 'PKG_NAME__$$']: pkg.name || '',
         ['$$__' + appEnvPrefixes[0] + 'PKG_VERSION__$$']: pkg.version || '',
         ['$$__' + appEnvPrefixes[0] + 'PKG_REPOSITORY__$$']: pkg.repository || '',
         ['$$__' + appEnvPrefixes[0] + 'PKG_HOMEPAGE__$$']: pkg.homepage || '',
         ['$$__' + appEnvPrefixes[0] + 'PKG_BUGS__$$']: pkg.bugs || '',
+        ['$$__' + appEnvPrefixes[0] + 'BASE_URL__$$']: appBaseURL || '',
+        ['$$__' + appEnvPrefixes[0] + 'BASE_URL_RESOLVED_NTS__$$']: appBaseURLResolvedNTS || '',
         ['$$__' + appEnvPrefixes[0] + 'BUILD_TIME_YMD__$$']: $time.now().toYMD() || '',
     };
     Object.keys(env) // Add string env vars to static defines.
@@ -98,9 +119,6 @@ export default async ({ mode, command, isSsrBuild: isSSRBuild }) => {
     /**
      * App type, target, path, and related vars.
      */
-    const appBaseURL = env.APP_BASE_URL || ''; // e.g., `https://example.com/`, `https://example.com/base`.
-    // A base URL is only required for some app types; e.g., `spa|mpa`. See validation below for details.
-
     const appType = $obp.get(pkg, 'config.c10n.&.' + (isSSRBuild ? 'ssrBuild' : 'build') + '.appType') || 'cma';
     const targetEnv = $obp.get(pkg, 'config.c10n.&.' + (isSSRBuild ? 'ssrBuild' : 'build') + '.targetEnv') || 'any';
     const entryFiles = $obp.get(pkg, 'config.c10n.&.' + (isSSRBuild ? 'ssrBuild' : 'build') + '.entryFiles') || [];
@@ -129,7 +147,10 @@ export default async ({ mode, command, isSsrBuild: isSSRBuild }) => {
      */
     const peerDepKeys = Object.keys(pkg.peerDependencies || {});
     const targetEnvIsServer = ['cfw', 'node'].includes(targetEnv);
-    const minifyEnable = 'dev' !== mode && !['lib'].includes(appType);
+    const wranglerMode = process.env.VITE_WRANGLER_MODE || ''; // Wrangler mode.
+    const inProdLikeMode = ['prod', 'stage'].includes(mode) || ('dev' === mode && 'dev' === wranglerMode);
+    const sourcemapsEnable = ['dev'].includes(mode); // Only generate sourcemaps when explicitly in dev mode.
+    const minifyEnable = !['lib'].includes(appType) && inProdLikeMode; // We don’t ever minify code in a library.
     const vitestSandboxEnable = process.env.VITEST && $str.parseValue(String(process.env.VITEST_SANDBOX_ENABLE || ''));
     const vitestExamplesEnable = process.env.VITEST && $str.parseValue(String(process.env.VITEST_EXAMPLES_ENABLE || ''));
     const prefreshEnable = process.env.VITE_PREFRESH_ENABLE && !process.env.VITEST && 'serve' === command && 'dev' === mode && ['spa', 'mpa'].includes(appType);
@@ -167,19 +188,26 @@ export default async ({ mode, command, isSsrBuild: isSSRBuild }) => {
         appEntriesAsProjRelPaths, appEntriesAsSrcSubpaths, appEntriesAsSrcSubpathsNoExt
     }); // prettier-ignore
 
+    /**
+     * Updates `sideEffects` to full set established by package update routines.
+     */
+    (sideEffects.length = 0), pkgUpdates.sideEffects.forEach((s) => sideEffects.push(s));
+
     /**
      * Configures plugins for Vite.
      */
     const plugins = [
-        await viteC10nTransformsConfig({}),
         await viteIconsConfig({}),
+        await viteC10nBrandConfig({}),
+        await viteC10nSideEffectsConfig({}),
+        await viteC10nNoModulePreloadConfig({}),
         await viteMDXConfig({ projDir }),
         await viteEJSConfig({ mode, projDir, srcDir, pkg, env }),
-        await viteMinifyConfig({ mode }),
+        await viteMinifyConfig({ minifyEnable }),
         await viteDTSConfig({ distDir }),
         await viteC10nPostProcessingConfig({
-            mode, command, isSSRBuild, projDir, distDir,
-            pkg, env, appType, targetEnv, staticDefs, pkgUpdates
+            mode, wranglerMode, inProdLikeMode, command, isSSRBuild, projDir, distDir,
+            pkg, env, appBaseURL, appType, targetEnv, staticDefs, pkgUpdates
         }), // prettier-ignore
         ...(prefreshEnable ? [await vitePrefreshConfig({})] : []),
     ];
@@ -187,12 +215,17 @@ export default async ({ mode, command, isSsrBuild: isSSRBuild }) => {
     /**
      * Configures esbuild for Vite.
      */
-    const esbuildConfig = await viteESBuildConfig({}); // Minimal config; no props at this time.
+    const esbuildConfig = await viteESBuildConfig({}); // Minimal config. No props at this time.
+
+    /**
+     * Configures terser for Vite.
+     */
+    const terserConfig = await viteTerserConfig({}); // Minimal config. No props passed at this time.
 
     /**
      * Configures rollup for Vite.
      */
-    const rollupConfig = await viteRollupConfig({ projDir, srcDir, distDir, a16sDir, appType, appEntries, peerDepKeys, minifyEnable, sideEffects: pkgUpdates.sideEffects });
+    const rollupConfig = await viteRollupConfig({ projDir, srcDir, distDir, a16sDir, appType, appEntries, peerDepKeys, minifyEnable, sideEffects });
 
     /**
      * Configures tests for Vite.
@@ -230,7 +263,7 @@ export default async ({ mode, command, isSsrBuild: isSSRBuild }) => {
 
         root: srcDir, // Absolute path where entry indexes live.
         publicDir: isSSRBuild ? false : path.relative(srcDir, cargoDir),
-        base: appBaseURL ? $url.toPath(appBaseURL) : '/',
+        base: appBaseURLResolvedNTS ? $url.toPath(appBaseURLResolvedNTS) : '/',
 
         envDir: path.relative(srcDir, envsDir), // Relative to `root` directory.
         envPrefix: appEnvPrefixes, // Env vars w/ these prefixes become part of the app.
@@ -241,12 +274,14 @@ export default async ({ mode, command, isSsrBuild: isSSRBuild }) => {
         server: {
             host: '0.0.0.0', // All.
             port: 443, // Default https.
+            strictPort: true, // Only use 443.
             open: false, // Not automatically.
             https: { key: sslKey, cert: sslCrt },
         },
         preview: {
             host: '0.0.0.0', // All.
             port: 443, // Default https.
+            strictPort: true, // Only use 443.
             open: false, // Not automatically.
             https: { key: sslKey, cert: sslCrt },
         },
@@ -284,14 +319,16 @@ export default async ({ mode, command, isSsrBuild: isSSRBuild }) => {
 
             manifest: !isSSRBuild ? 'vite/manifest.json' : false, // Enables manifest of asset locations.
             ssrManifest: isSSRBuild ? 'vite/ssr-manifest.json' : false, // Enables SSR manifest of asset locations.
-            sourcemap: 'dev' === mode ? 'inline' : false, // Enables creation of sourcemaps; i.e., for debugging.
+            sourcemap: sourcemapsEnable, // Enables creation of sourcemaps; i.e., purely for debugging purposes.
 
-            minify: minifyEnable ? 'esbuild' : false, // {@see https://o5p.me/pkJ5Xz}.
+            terserOptions: terserConfig, // Terser config options.
+            minify: minifyEnable ? 'terser' : false, // {@see https://o5p.me/pkJ5Xz}.
             cssMinify: minifyEnable ? 'lightningcss' : false, // {@see https://o5p.me/h0Hgj3}.
             // We ran several tests between `esbuild`, `cssnano`, and `lightningcss` wins.
 
             modulePreload: false, // Disable. DOM injections conflict with our SPAs.
             // This option is sort-of respected, but not fully; {@see https://github.com/vitejs/vite/issues/13952}.
+            // For now, we have a custom plugin, configured above, which effectively disables all preloading.
 
             ...(['cma', 'lib'].includes(appType) ? { lib: { entry: appEntries, formats: ['es'] } } : {}),
             rollupOptions: rollupConfig, // See: .
diff --git a/dev/.files/vite/includes/c10n/brand-config.mjs b/dev/.files/vite/includes/c10n/brand-config.mjs
new file mode 100644
index 00000000..8bdafd88
--- /dev/null
+++ b/dev/.files/vite/includes/c10n/brand-config.mjs
@@ -0,0 +1,39 @@
+/**
+ * C10n brand plugin.
+ *
+ * Vite is not aware of this config file's location.
+ *
+ * @note PLEASE DO NOT EDIT THIS FILE!
+ * @note This entire file will be updated automatically.
+ * @note Instead of editing here, please review .
+ */
+
+import { $json } from '../../../../../node_modules/@clevercanyon/utilities/dist/index.js';
+import u from '../../../bin/includes/utilities.mjs';
+
+/**
+ * Configures Vite brand plugin.
+ *
+ * @param   props Props from vite config file driver.
+ *
+ * @returns       Plugin configuration.
+ */
+export default async (/* {} */) => {
+    const virtualId = 'virtual:brand/config';
+    const resolvedVirtualId = '\0' + virtualId;
+
+    return {
+        name: 'vite-plugin-c10n-brand-config',
+
+        resolveId(id) {
+            if (id === virtualId) {
+                return '\0' + id;
+            }
+        },
+        async load(id) {
+            if (id === resolvedVirtualId) {
+                return 'export default ' + $json.stringify(await u.brandConfig(), { pretty: true });
+            }
+        },
+    };
+};
diff --git a/dev/.files/vite/includes/c10n/no-module-preload.mjs b/dev/.files/vite/includes/c10n/no-module-preload.mjs
new file mode 100644
index 00000000..67b552ec
--- /dev/null
+++ b/dev/.files/vite/includes/c10n/no-module-preload.mjs
@@ -0,0 +1,32 @@
+/**
+ * C10n no module preload plugin.
+ *
+ * Vite is not aware of this config file's location.
+ *
+ * @note PLEASE DO NOT EDIT THIS FILE!
+ * @note This entire file will be updated automatically.
+ * @note Instead of editing here, please review .
+ */
+
+/**
+ * Configures Vite no module preload plugin.
+ *
+ * @param   props Props from vite config file driver.
+ *
+ * @returns       Plugin configuration.
+ */
+export default async (/* {} */) => {
+    const virtualId = 'vite/preload-helper.js';
+    const resolvedVirtualId = '\0' + virtualId;
+
+    return {
+        name: 'vite-plugin-c10n-no-module-preload',
+        enforce: 'pre', // Before Vite loads this virtual module.
+
+        load(id) {
+            if (id === resolvedVirtualId) {
+                return 'export const __vitePreload = (dynamicImport) => dynamicImport();';
+            }
+        },
+    };
+};
diff --git a/dev/.files/vite/includes/c10n/post-processing.mjs b/dev/.files/vite/includes/c10n/post-processing.mjs
index 9e29fe87..1f06ac9e 100644
--- a/dev/.files/vite/includes/c10n/post-processing.mjs
+++ b/dev/.files/vite/includes/c10n/post-processing.mjs
@@ -12,39 +12,40 @@ import fs from 'node:fs';
 import fsp from 'node:fs/promises';
 import path from 'node:path';
 import { $http as $cfpꓺhttp } from '../../../../../node_modules/@clevercanyon/utilities.cfp/dist/index.js';
-import { $chalk, $fs, $glob } from '../../../../../node_modules/@clevercanyon/utilities.node/dist/index.js';
-import { $mm, $obp, $preact, $str } from '../../../../../node_modules/@clevercanyon/utilities/dist/index.js';
+import { $chalk, $fs, $glob, $prettier } from '../../../../../node_modules/@clevercanyon/utilities.node/dist/index.js';
+import { $crypto, $json, $mm, $obp, $preact, $str } from '../../../../../node_modules/@clevercanyon/utilities/dist/index.js';
 import { StandAlone as StandAlone404 } from '../../../../../node_modules/@clevercanyon/utilities/dist/preact/components/404.js';
 import exclusions from '../../../bin/includes/exclusions.mjs';
 import extensions from '../../../bin/includes/extensions.mjs';
 import u from '../../../bin/includes/utilities.mjs';
 
 /**
- * Configures Vite/Rollup post-processing.
+ * Configures Vite post-processing plugin.
  *
  * @param   props Props from vite config file driver.
  *
  * @returns       Plugin configuration.
  */
-export default async ({ mode, command, isSSRBuild, projDir, distDir, pkg, env, appType, targetEnv, staticDefs, pkgUpdates }) => {
-    let postProcessed = false; // Initialize.
+export default async ({ mode, wranglerMode, inProdLikeMode, command, isSSRBuild, projDir, distDir, pkg, env, appBaseURL, appType, targetEnv, staticDefs, pkgUpdates }) => {
+    let buildEndError = undefined, // Initialize.
+        postProcessed = false; // Initialize.
+
     return {
         name: 'vite-plugin-c10n-post-processing',
         enforce: 'post', // After others on this hook.
 
-        async closeBundle(/* Rollup hook. */) {
-            if (postProcessed) return;
-            postProcessed = true;
+        // Listens for build-related errors.
+        // No post-processing if there were errors.
+        buildEnd: (error) => void (buildEndError = error),
 
-            /**
-             * Not during SSR builds.
-             */
-            if (isSSRBuild) return;
+        async closeBundle(/* Rollup hook. */) {
+            if (postProcessed || buildEndError) return;
+            postProcessed = true; // Processing now.
 
             /**
              * Recompiles `./package.json`.
              */
-            if ('build' === command) {
+            if (!isSSRBuild && 'build' === command) {
                 u.log($chalk.gray('Recompiling `./package.json`.'));
                 await u.updatePkg({ $set: pkgUpdates });
             }
@@ -52,7 +53,7 @@ export default async ({ mode, command, isSSRBuild, projDir, distDir, pkg, env, a
             /**
              * Generates typescript type declaration file(s).
              */
-            if ('build' === command /* Does important type checking at build time. */) {
+            if (!isSSRBuild && 'build' === command /* Does important type checking at build time. */) {
                 u.log($chalk.gray('Running TypeScript type checks.'));
                 await u.spawn('npx', ['tsc']);
             }
@@ -60,9 +61,9 @@ export default async ({ mode, command, isSSRBuild, projDir, distDir, pkg, env, a
             /**
              * Prunes `./.npmignore`s, which we don’t include in any distribution.
              *
-             * We only prune `./.npmignore`s when building for production, as it’s possible there are files being
-             * compiled by TypeScript that are needed for development; i.e., they need to exist in dev mode in order to
-             * be capable of serving their intended purpose; e.g., dev-only utilities, runners, sandbox files, etc.
+             * We only prune `./.npmignore`s when building in a prod-like mode, as it’s possible there are files being
+             * compiled by TypeScript that are needed for development; i.e., they need to exist in to be capable of
+             * serving their intended purpose; e.g., dev-only utilities, runners, sandbox files, etc.
              *
              * Regarding `node_modules`. There is an exception for the case of `node_modules/assets/a16s`, used for
              * Cloudflare SSR-specific assets. See `../a16s/dir.mjs` for details. The `node_modules` folder is pruned by
@@ -74,7 +75,7 @@ export default async ({ mode, command, isSSRBuild, projDir, distDir, pkg, env, a
              * potentially customized `./.npmignore` file in the current project directory. The reason is because we
              * intend to enforce our standards. For further details {@see https://o5p.me/MuskgW}.
              */
-            if ('build' === command && 'prod' === mode) {
+            if (!isSSRBuild && 'build' === command && inProdLikeMode) {
                 for (let globOpts = [{ onlyDirectories: true }, { onlyFiles: false }], i = 0; i < globOpts.length; i++) {
                     for (const fileOrDir of await $glob.promise(exclusions.defaultNPMIgnores, { cwd: distDir, ignoreCase: true, ...globOpts[i] })) {
                         const projRelPath = path.relative(projDir, fileOrDir);
@@ -114,11 +115,11 @@ export default async ({ mode, command, isSSRBuild, projDir, distDir, pkg, env, a
             /**
              * Deletes a few things that are not needed by apps running on Cloudflare Pages.
              *
-             * We only prune when building for production, as it’s possible there are files being compiled by TypeScript
-             * that are needed for development; i.e., they need to exist in dev mode in order to be capable of serving
-             * their intended purpose; e.g., dev-only utilities, runners, sandbox files, etc.
+             * We only prune when building in a prod-like mode, as it’s possible there are files being compiled by
+             * TypeScript that are needed for development; i.e., they need to exist in dev mode in order to be capable
+             * of serving their intended purpose; e.g., dev-only utilities, runners, sandbox files, etc.
              */
-            if ('build' === command && 'prod' === mode && ['spa', 'mpa'].includes(appType) && ['cfp'].includes(targetEnv)) {
+            if (!isSSRBuild && 'build' === command && inProdLikeMode && ['spa', 'mpa'].includes(appType) && ['cfp'].includes(targetEnv)) {
                 for (const fileOrDir of await $glob.promise(
                     [
                         'types', // Prunes TypeScript type declarations.
@@ -134,21 +135,29 @@ export default async ({ mode, command, isSSRBuild, projDir, distDir, pkg, env, a
             /**
              * Updates a few files that configure apps running on Cloudflare Pages.
              *
-             * None of these file must exist, and none of these must contain replacement codes. We leave it up to the
+             * None of these files must exist, and none of these must contain replacement codes. We leave it for the
              * implementation to decide. If they do not exist, or do not contain replacement codes, we assume that
              * nothing should occur. For example, it might be desirable in some cases for `./robots.txt`, `sitemap.xml`,
              * or others to be served dynamically. In which case they may not exist in these locations statically.
              */
-            if ('build' === command && ['spa', 'mpa'].includes(appType) && ['cfp'].includes(targetEnv)) {
+            if (!isSSRBuild && 'build' === command && ['spa', 'mpa'].includes(appType) && ['cfp'].includes(targetEnv)) {
+                const brand = await u.brand({ baseURL: appBaseURL });
+                const isC10n = env.APP_IS_C10N || false;
+
                 for (const file of await $glob.promise(
                     [
-                        '_headers', //
+                        '.well-known/gpc.json',
+                        '.well-known/security.txt',
+                        '_headers',
                         '_redirects',
                         '_routes.json',
-                        '404.html',
-                        'robots.txt',
-                        'sitemap.xml',
                         'sitemaps/**/*.xml',
+                        'sitemap.xml',
+                        'manifest.json',
+                        'ads.txt',
+                        'humans.txt',
+                        'robots.txt',
+                        '404.html',
                     ],
                     { cwd: distDir },
                 )) {
@@ -160,15 +169,50 @@ export default async ({ mode, command, isSSRBuild, projDir, distDir, pkg, env, a
                     for (const key of Object.keys(staticDefs) /* Replaces all static definition tokens. */) {
                         fileContents = fileContents.replace(new RegExp($str.escRegExp(key), 'gu'), staticDefs[key]);
                     }
-                    if (['_headers'].includes(fileRelPath)) {
-                        const cfpDefaultHeaders = $cfpꓺhttp.prepareDefaultHeaders({ appType, isC10n: env.APP_IS_C10N || false });
+                    if (['.well-known/gpc.json'].includes(fileRelPath)) {
+                        const cfpDefaultWellKnownGPC = $cfpꓺhttp.prepareDefaultWellKnownGPC({ appType, brand, isC10n });
+                        fileContents = fileContents
+                            .replace('"$$__APP_CFP_DEFAULT_WELL_KNOWN_GPC__$$"', cfpDefaultWellKnownGPC) //
+                            .replace('$$__APP_CFP_DEFAULT_WELL_KNOWN_GPC__$$', cfpDefaultWellKnownGPC);
+                        //
+                    } else if (['.well-known/security.txt'].includes(fileRelPath)) {
+                        const cfpDefaultWellKnownSecurity = $cfpꓺhttp.prepareDefaultWellKnownSecurity({ appType, brand, isC10n });
+                        fileContents = fileContents.replace('$$__APP_CFP_DEFAULT_WELL_KNOWN_SECURITY__$$', cfpDefaultWellKnownSecurity);
+                        //
+                    } else if (['_headers'].includes(fileRelPath)) {
+                        const cfpDefaultHeaders = $cfpꓺhttp.prepareDefaultHeaders({ appType, brand, isC10n });
                         fileContents = fileContents.replace('$$__APP_CFP_DEFAULT_HEADERS__$$', cfpDefaultHeaders);
-                    }
-                    if (['404.html'].includes(fileRelPath)) {
+                        //
+                    } else if (['_redirects'].includes(fileRelPath)) {
+                        const cfpDefaultRedirects = $cfpꓺhttp.prepareDefaultRedirects({ appType, brand, isC10n });
+                        fileContents = fileContents.replace('$$__APP_CFP_DEFAULT_REDIRECTS__$$', cfpDefaultRedirects);
+                        //
+                    } else if (['_routes.json'].includes(fileRelPath)) {
+                        const cfpDefaultRoutes = $cfpꓺhttp.prepareDefaultRoutes({ appType, brand, isC10n });
+                        fileContents = fileContents
+                            .replace('"$$__APP_CFP_DEFAULT_ROUTES__$$"', cfpDefaultRoutes) //
+                            .replace('$$__APP_CFP_DEFAULT_ROUTES__$$', cfpDefaultRoutes);
+                        //
+                    } else if (['manifest.json'].includes(fileRelPath)) {
+                        const cfpDefaultManifest = $cfpꓺhttp.prepareDefaultManifest({ appType, brand, isC10n });
+                        fileContents = fileContents
+                            .replace('"$$__APP_CFP_DEFAULT_MANIFEST__$$"', cfpDefaultManifest) //
+                            .replace('$$__APP_CFP_DEFAULT_MANIFEST__$$', cfpDefaultManifest);
+                        //
+                    } else if (['ads.txt'].includes(fileRelPath)) {
+                        const cfpDefaultAdsTxt = $cfpꓺhttp.prepareDefaultAdsTxt({ appType, brand, isC10n });
+                        fileContents = fileContents.replace('$$__APP_CFP_DEFAULT_ADS_TXT__$$', cfpDefaultAdsTxt);
+                        //
+                    } else if (['humans.txt'].includes(fileRelPath)) {
+                        const cfpDefaultHumansTxt = $cfpꓺhttp.prepareDefaultHumansTxt({ appType, brand, isC10n });
+                        fileContents = fileContents.replace('$$__APP_CFP_DEFAULT_HUMANS_TXT__$$', cfpDefaultHumansTxt);
+                        //
+                    } else if (['404.html'].includes(fileRelPath)) {
                         const cfpDefault404 = '' + $preact.ssr.renderToString($preact.create(StandAlone404));
                         fileContents = fileContents.replace('$$__APP_CFP_DEFAULT_404_HTML__$$', cfpDefault404);
                     }
-                    if (['_headers', '_redirects', 'robots.txt'].includes(fileRelPath)) {
+
+                    if (['txt'].includes(fileExt) || ['_headers', '_redirects'].includes(fileRelPath)) {
                         fileContents = fileContents.replace(/^#[^\n]*\n/gmu, '');
                         //
                     } else if (['json'].includes(fileExt)) {
@@ -177,17 +221,34 @@ export default async ({ mode, command, isSSRBuild, projDir, distDir, pkg, env, a
                     } else if (['xml', 'html'].includes(fileExt)) {
                         fileContents = fileContents.replace(/\n?/gu, '');
                     }
-                    fileContents = $str.trim(fileContents.replace(/\n{3,}/gu, '\n\n'));
 
+                    fileContents = $str.trim(fileContents.replace(/\n{3,}/gu, '\n\n'));
                     u.log($chalk.gray('Updating `./' + path.relative(projDir, file) + '`.'));
                     await fsp.writeFile(file, fileContents);
                 }
             }
 
+            /**
+             * Generates SHA-1 manifests for JS import compatibility.
+             */
+            if ('build' === command && fs.existsSync(path.resolve(distDir, './vite/' + (isSSRBuild ? 'ssr-' : '') + 'manifest.json'))) {
+                u.log($chalk.gray('Generating MD5-keyed ' + (isSSRBuild ? 'SSR ' : '') + 'manifest.'));
+
+                const file = path.resolve(distDir, './vite/' + (isSSRBuild ? 'ssr-' : '') + 'manifest.json');
+                const data = $json.parse((await fsp.readFile(file)).toString());
+                const sha1Data = {}; // Initialize.
+
+                for (const [key, value] of Object.entries(data)) {
+                    sha1Data['x' + (await $crypto.sha1(key))] = { [key]: value };
+                }
+                const prettierConfig = { ...(await $prettier.resolveConfig(file)), parser: 'json' };
+                await fsp.writeFile(file, await $prettier.format($json.stringify(sha1Data, { pretty: true }), prettierConfig));
+            }
+
             /**
              * Generates SSR build on-the-fly internally.
              */
-            if ('build' === command && $obp.get(pkg, 'config.c10n.&.ssrBuild.appType')) {
+            if (!isSSRBuild && 'build' === command && $obp.get(pkg, 'config.c10n.&.ssrBuild.appType')) {
                 u.log($chalk.gray('Running secondary SSR build routine.'));
                 await u.spawn('npx', ['vite', 'build', '--mode', mode, '--ssr']);
             }
@@ -195,7 +256,7 @@ export default async ({ mode, command, isSSRBuild, projDir, distDir, pkg, env, a
             /**
              * Generates a zip archive containing `./dist` directory.
              */
-            if ('build' === command) {
+            if (!isSSRBuild && 'build' === command && 'dev' !== wranglerMode) {
                 const zipFile = path.resolve(projDir, './.~dist.zip');
                 u.log($chalk.gray('Generating `' + path.relative(projDir, zipFile) + '`.'));
 
diff --git a/dev/.files/vite/includes/c10n/transforms.mjs b/dev/.files/vite/includes/c10n/side-effects.mjs
similarity index 85%
rename from dev/.files/vite/includes/c10n/transforms.mjs
rename to dev/.files/vite/includes/c10n/side-effects.mjs
index 300a9414..f4d0c1f6 100644
--- a/dev/.files/vite/includes/c10n/transforms.mjs
+++ b/dev/.files/vite/includes/c10n/side-effects.mjs
@@ -1,5 +1,5 @@
 /**
- * C10n transforms plugin.
+ * C10n side-effects plugin.
  *
  * Vite is not aware of this config file's location.
  *
@@ -9,7 +9,7 @@
  */
 
 /**
- * Configures Vite/Rollup transforms.
+ * Configures Vite side-effects plugin.
  *
  * @param   props Props from vite config file driver.
  *
@@ -17,9 +17,9 @@
  */
 export default async (/* {} */) => {
     return {
-        name: 'vite-plugin-c10n-transforms',
+        name: 'vite-plugin-c10n-side-effects',
 
-        async transform(/* Rollup hook. */ unusedꓺ, id) {
+        async transform(unusedꓺ, id) {
             /**
              * If `moduleSideEffects` is set to `false` and no other module imports anything from the module, then the
              * module will not be included even if the module would have side effects; {@see https://o5p.me/EcB2d6}.
@@ -31,7 +31,6 @@ export default async (/* {} */) => {
             if (/@preact\/signals(?:-core)?\b/iu.test(id)) {
                 return { moduleSideEffects: false };
             }
-            return null; // No transform.
         },
     };
 };
diff --git a/dev/.files/vite/includes/dts/config.mjs b/dev/.files/vite/includes/dts/config.mjs
index 3c3d8111..ff09c226 100644
--- a/dev/.files/vite/includes/dts/config.mjs
+++ b/dev/.files/vite/includes/dts/config.mjs
@@ -7,7 +7,7 @@
  * @note This entire file will be updated automatically.
  * @note Instead of editing here, please review .
  *
- * @see https://github.com/trapcodeio/vite-plugin-ejs
+ * @see https://www.npmjs.com/package/vite-plugin-dts
  */
 
 /**
@@ -19,7 +19,7 @@
  */
 export default async ({ distDir }) => {
     return (await import('vite-plugin-dts')).default({
-        // logLevel: 'error',
+        logLevel: 'error',
         outDir: distDir + '/types',
     });
 };
diff --git a/dev/.files/vite/includes/minify/config.mjs b/dev/.files/vite/includes/minify/config.mjs
index 84c3d185..bfc69b38 100644
--- a/dev/.files/vite/includes/minify/config.mjs
+++ b/dev/.files/vite/includes/minify/config.mjs
@@ -17,6 +17,6 @@
  *
  * @returns       Minify configuration; else `null` if not applicable.
  */
-export default async ({ mode }) => {
-    return 'dev' === mode ? null : (await import('vite-plugin-minify')).ViteMinifyPlugin();
+export default async ({ minifyEnable }) => {
+    return minifyEnable ? (await import('vite-plugin-minify')).ViteMinifyPlugin() : null;
 };
diff --git a/dev/.files/vite/includes/package/updates.mjs b/dev/.files/vite/includes/package/updates.mjs
index 02dbd2ed..7ec09432 100644
--- a/dev/.files/vite/includes/package/updates.mjs
+++ b/dev/.files/vite/includes/package/updates.mjs
@@ -53,6 +53,12 @@ export default async ({
         if (fs.existsSync(path.resolve(srcDir, './resources/init.ts'))) {
             updates.sideEffects.push('./' + path.relative(projDir, path.resolve(srcDir, './resources/init.ts')));
         }
+        if (fs.existsSync(path.resolve(srcDir, './resources/initialize.ts'))) {
+            updates.sideEffects.push('./' + path.relative(projDir, path.resolve(srcDir, './resources/initialize.ts')));
+        }
+        if (['spa', 'mpa'].includes(appType) && fs.existsSync(path.resolve(srcDir, './resources/hydrate.tsx'))) {
+            updates.sideEffects.push('./' + path.relative(projDir, path.resolve(srcDir, './resources/hydrate.tsx')));
+        }
         const distDirAsProjRelPath = './' + path.relative(projDir, distDir); // Relative dist directory path.
 
         switch (true /* Conditional case handlers. */) {
diff --git a/dev/.files/vite/includes/terser/config.mjs b/dev/.files/vite/includes/terser/config.mjs
new file mode 100644
index 00000000..1216b8bd
--- /dev/null
+++ b/dev/.files/vite/includes/terser/config.mjs
@@ -0,0 +1,30 @@
+/**
+ * Terser config file.
+ *
+ * Terser is not aware of this config file's location.
+ *
+ * @note PLEASE DO NOT EDIT THIS FILE!
+ * @note This entire file will be updated automatically.
+ * @note Instead of editing here, please review .
+ *
+ * @see https://terser.org/docs/api-reference/#minify-options
+ */
+
+import esVersion from '../../../bin/includes/es-version.mjs';
+
+/**
+ * Configures terser for Vite.
+ *
+ * @param   props Props from vite config file driver.
+ *
+ * @returns       Terser configuration.
+ */
+export default async (/* {} */) => {
+    return {
+        module: true,
+        toplevel: true,
+        ecma: esVersion.year,
+        compress: { passes: 1 },
+        format: { comments: false },
+    };
+};
diff --git a/dev/.files/vscode/config.mjs b/dev/.files/vscode/config.mjs
index a9b5c4bb..47f6410d 100755
--- a/dev/.files/vscode/config.mjs
+++ b/dev/.files/vscode/config.mjs
@@ -59,12 +59,19 @@ export default async () => {
         ['**/.env.*']: 'properties', // Suffix, not extension.
         ['**/CODEOWNERS']: 'ignore', // File has no extension.
 
-        ['**/tsconfig.' + fileAssociationsOverrideExt('json')]: 'jsonc', // JSON w/comments.
-        ['**/.vscode/*.' + fileAssociationsOverrideExt('json')]: 'jsonc', // JSON w/comments.
+        ['**/tsconfig.' + fileAssociationsOverrideExt('json')]: 'jsonc',
+        ['**/.vscode/*.' + fileAssociationsOverrideExt('json')]: 'jsonc',
 
+        ['**/src/cargo/.well-known/**/*.' + fileAssociationsOverrideExt('json')]: 'jsonc',
+
+        ['**/dist/_headers']: 'plaintext', // File has no extension.
         ['**/src/cargo/_headers']: 'plaintext', // File has no extension.
+
+        ['**/dist/_redirects']: 'plaintext', // File has no extension.
         ['**/src/cargo/_redirects']: 'plaintext', // File has no extension.
-        ['**/src/cargo/_routes.' + fileAssociationsOverrideExt('json')]: 'jsonc', // JSON w/comments.
+
+        ['**/src/cargo/manifest.' + fileAssociationsOverrideExt('json')]: 'jsonc',
+        ['**/src/cargo/_routes.' + fileAssociationsOverrideExt('json')]: 'jsonc',
     };
 
     /**
@@ -292,6 +299,23 @@ export default async () => {
         'eslint.experimental.useFlatConfig': true,
         'eslint.workingDirectories': [{ 'mode': 'auto' }],
 
+        'eslint.probe': [
+            // For now, disabling eslint for markdown.
+
+            // MDX eslint plugin not compatible with MDX v3 yet.
+            // Outdated package: `eslint-plugin-mdx`.
+
+            // Additionally, the formatter for MDX/markdown has been changed
+            // from eslint to prettier, for now. See langauge settings below.
+
+            // 'mdx',
+            // 'markdown',
+
+            'javascript',
+            'javascriptreact',
+            'typescript',
+            'typescriptreact',
+        ],
         'eslint.validate': [
             // For now, disabling eslint for markdown.
 
@@ -352,7 +376,7 @@ export default async () => {
         'markdown.preview.fontSize': 16,
         'markdown.preview.lineHeight': 1.5,
         'markdown.preview.typographer': true,
-        'markdown.preview.fontFamily': 'Georama, ui-sans-serif, sans-serif',
+        'markdown.preview.fontFamily': "Georama, sans-serif, 'Apple Color Emoji'",
 
         'markdown.validate.enabled': false, // For a different markdown flavor.
         // Disabling because we use remark, a different flavor than VSCode, and several plugins.
@@ -384,7 +408,7 @@ export default async () => {
             'editor.wordWrap': 'on',
 
             'editor.codeActionsOnSave': {
-                'source.fixAll': true,
+                'source.fixAll': 'explicit',
             },
             // Change this back to `dbaeumer.vscode-eslint` when `eslint-plugin-mdx` is compatible with MDX v3.
             'editor.defaultFormatter': 'esbenp.prettier-vscode',
@@ -396,7 +420,7 @@ export default async () => {
             'editor.wordWrap': 'on',
 
             'editor.codeActionsOnSave': {
-                'source.fixAll': true,
+                'source.fixAll': 'explicit',
             },
             // Change this back to `dbaeumer.vscode-eslint` when `eslint-plugin-mdx` is compatible with MDX v3.
             'editor.defaultFormatter': 'esbenp.prettier-vscode',
@@ -406,7 +430,7 @@ export default async () => {
             'editor.insertSpaces': !prettierConfig.useTabs,
 
             'editor.codeActionsOnSave': {
-                'source.fixAll': true,
+                'source.fixAll': 'explicit',
             },
             'editor.defaultFormatter': 'esbenp.prettier-vscode',
         },
@@ -420,7 +444,7 @@ export default async () => {
             'editor.insertSpaces': !prettierConfig.useTabs,
 
             'editor.codeActionsOnSave': {
-                'source.fixAll': true,
+                'source.fixAll': 'explicit',
             },
             'editor.defaultFormatter': 'esbenp.prettier-vscode',
         },
@@ -429,7 +453,7 @@ export default async () => {
             'editor.insertSpaces': !prettierConfig.useTabs,
 
             'editor.codeActionsOnSave': {
-                'source.fixAll': true,
+                'source.fixAll': 'explicit',
             },
             'editor.defaultFormatter': 'esbenp.prettier-vscode',
         },
@@ -438,7 +462,7 @@ export default async () => {
             'editor.insertSpaces': !prettierConfig.useTabs,
 
             'editor.codeActionsOnSave': {
-                'source.fixAll': true,
+                'source.fixAll': 'explicit',
             },
             'editor.defaultFormatter': 'ms-python.black-formatter',
         },
@@ -447,7 +471,7 @@ export default async () => {
             'editor.insertSpaces': !prettierConfig.useTabs,
 
             'editor.codeActionsOnSave': {
-                'source.fixAll': true,
+                'source.fixAll': 'explicit',
             },
             'editor.defaultFormatter': 'esbenp.prettier-vscode',
         },
@@ -456,7 +480,7 @@ export default async () => {
             'editor.insertSpaces': !prettierConfig.useTabs,
 
             'editor.codeActionsOnSave': {
-                'source.fixAll': true,
+                'source.fixAll': 'explicit',
             },
             'editor.defaultFormatter': 'esbenp.prettier-vscode',
         },
@@ -470,7 +494,7 @@ export default async () => {
             'editor.insertSpaces': !prettierConfig.useTabs,
 
             'editor.codeActionsOnSave': {
-                'source.fixAll': true,
+                'source.fixAll': 'explicit',
             },
             'editor.defaultFormatter': 'dbaeumer.vscode-eslint',
         },
@@ -479,7 +503,7 @@ export default async () => {
             'editor.insertSpaces': !prettierConfig.useTabs,
 
             'editor.codeActionsOnSave': {
-                'source.fixAll': true,
+                'source.fixAll': 'explicit',
             },
             'editor.defaultFormatter': 'dbaeumer.vscode-eslint',
         },
@@ -488,7 +512,7 @@ export default async () => {
             'editor.insertSpaces': !prettierConfig.useTabs,
 
             'editor.codeActionsOnSave': {
-                'source.fixAll': true,
+                'source.fixAll': 'explicit',
             },
             'editor.defaultFormatter': 'dbaeumer.vscode-eslint',
         },
@@ -497,7 +521,7 @@ export default async () => {
             'editor.insertSpaces': !prettierConfig.useTabs,
 
             'editor.codeActionsOnSave': {
-                'source.fixAll': true,
+                'source.fixAll': 'explicit',
             },
             'editor.defaultFormatter': 'dbaeumer.vscode-eslint',
         },
@@ -506,7 +530,7 @@ export default async () => {
             'editor.insertSpaces': !prettierConfig.useTabs,
 
             'editor.codeActionsOnSave': {
-                'source.fixAll': true,
+                'source.fixAll': 'explicit',
             },
             'editor.defaultFormatter': 'esbenp.prettier-vscode',
         },
@@ -515,7 +539,7 @@ export default async () => {
             'editor.insertSpaces': !prettierConfig.useTabs,
 
             'editor.codeActionsOnSave': {
-                'source.fixAll': true,
+                'source.fixAll': 'explicit',
             },
             'editor.defaultFormatter': 'esbenp.prettier-vscode',
         },
@@ -524,7 +548,7 @@ export default async () => {
             'editor.insertSpaces': !prettierConfig.useTabs,
 
             'editor.codeActionsOnSave': {
-                'source.fixAll': true,
+                'source.fixAll': 'explicit',
             },
             'editor.defaultFormatter': 'esbenp.prettier-vscode',
         },
@@ -538,7 +562,7 @@ export default async () => {
             'editor.insertSpaces': !prettierConfig.useTabs,
 
             'editor.codeActionsOnSave': {
-                'source.fixAll': true,
+                'source.fixAll': 'explicit',
             },
             'editor.defaultFormatter': 'esbenp.prettier-vscode',
         },
@@ -547,7 +571,7 @@ export default async () => {
             'editor.insertSpaces': !prettierConfig.useTabs,
 
             'editor.codeActionsOnSave': {
-                'source.fixAll': true,
+                'source.fixAll': 'explicit',
             },
             'editor.defaultFormatter': 'esbenp.prettier-vscode',
         },
@@ -556,7 +580,7 @@ export default async () => {
             'editor.insertSpaces': !prettierConfig.useTabs,
 
             'editor.codeActionsOnSave': {
-                'source.fixAll': true,
+                'source.fixAll': 'explicit',
             },
             'editor.defaultFormatter': 'esbenp.prettier-vscode',
         },
@@ -565,7 +589,7 @@ export default async () => {
             'editor.insertSpaces': !prettierConfig.useTabs,
 
             'editor.codeActionsOnSave': {
-                'source.fixAll': true,
+                'source.fixAll': 'explicit',
             },
             'editor.defaultFormatter': 'tamasfe.even-better-toml',
         },
@@ -574,7 +598,7 @@ export default async () => {
             'editor.insertSpaces': !prettierConfig.useTabs,
 
             'editor.codeActionsOnSave': {
-                'source.fixAll': true,
+                'source.fixAll': 'explicit',
             },
             'editor.defaultFormatter': 'esbenp.prettier-vscode',
         },
@@ -583,7 +607,7 @@ export default async () => {
             'editor.insertSpaces': !prettierConfig.useTabs,
 
             'editor.codeActionsOnSave': {
-                'source.fixAll': true,
+                'source.fixAll': 'explicit',
             },
             'editor.defaultFormatter': 'esbenp.prettier-vscode',
         },
@@ -592,7 +616,7 @@ export default async () => {
             'editor.insertSpaces': !prettierConfig.useTabs,
 
             'editor.codeActionsOnSave': {
-                'source.fixAll': true,
+                'source.fixAll': 'explicit',
             },
             'editor.defaultFormatter': 'esbenp.prettier-vscode',
         },
@@ -601,7 +625,7 @@ export default async () => {
             'editor.insertSpaces': !prettierConfig.useTabs,
 
             'editor.codeActionsOnSave': {
-                'source.fixAll': true,
+                'source.fixAll': 'explicit',
             },
             'editor.defaultFormatter': 'esbenp.prettier-vscode',
         },
diff --git a/dev/.files/wrangler/config.mjs b/dev/.files/wrangler/config.mjs
index 4c00587e..5adf4d86 100755
--- a/dev/.files/wrangler/config.mjs
+++ b/dev/.files/wrangler/config.mjs
@@ -44,7 +44,10 @@ export default async () => {
         // Platform settings.
 
         send_metrics: false, // Don't share usage.
-        usage_model: 'bundled', // 10M/mo free + $0.50/M.
+
+        // Cannot be added once we opt into standard pricing.
+        // This field should be configured from CF dashboard.
+        // usage_model: 'bundled', // 10M/mo free + $0.50/M.
 
         // Compatibility settings.
 
@@ -173,15 +176,15 @@ export default async () => {
                   env: {
                       dev: {
                           workers_dev: false,
-                          build: { command: 'npx @clevercanyon/madrun build --mode=dev' },
+                          vars: wranglerSettings.miniflareDevEnvVar,
+                          build: { command: 'VITE_WRANGLER_MODE=dev npx @clevercanyon/madrun build --mode=dev' },
                       },
                   },
                   // `$ wrangler dev` settings.
 
                   dev: {
-                      ip: wranglerSettings.defaultLocalIP,
                       local_protocol: wranglerSettings.defaultLocalProtocol,
-                      // Wrangler requires this to be a number, not a string.
+                      ip: wranglerSettings.defaultLocalIP, // e.g., `0.0.0.0`.
                       port: Number(wranglerSettings.defaultLocalPort),
                   },
               }),
diff --git a/dev/.files/wrangler/settings.mjs b/dev/.files/wrangler/settings.mjs
index 5086a5c4..a288657a 100755
--- a/dev/.files/wrangler/settings.mjs
+++ b/dev/.files/wrangler/settings.mjs
@@ -24,6 +24,9 @@ const pkgSlug = $app.pkgSlug(pkg.name);
 const hop = $brand.get('@clevercanyon/hop.gdn');
 const hopGDNSlug = $str.kebabCase(hop.hostname);
 
+const hopProjectName = pkgSlug.replace(new RegExp('-' + $str.escRegExp(hopGDNSlug) + '$', 'ui'), '');
+const hopWorkerName = pkgSlug.replace(new RegExp('^' + $str.escRegExp('workers-' + hopGDNSlug) + '-', 'ui'), '');
+
 /**
  * Defines Wrangler settings.
  */
@@ -38,14 +41,18 @@ export default {
     defaultLocalProtocol: 'https',
     defaultLocalPort: '443',
 
+    defaultDevLogLevel: 'error',
+    miniflareDevBinding: 'MINIFLARE=true',
+    miniflareDevEnvVar: { MINIFLARE: 'true' },
+
     defaultZoneName: hop.hostname,
     defaultZoneDomain: 'workers.' + hop.hostname,
 
     defaultEnvironment: 'production',
     defaultProductionBranch: 'production',
 
-    defaultProjectName: pkgSlug.replace(new RegExp('-' + $str.escRegExp(hopGDNSlug) + '$', 'ui'), ''), // Pages project name.
-    defaultWorkerName: pkgSlug.replace(new RegExp('^' + $str.escRegExp('workers-' + hopGDNSlug) + '-', 'ui'), ''), // Worker name.
+    defaultProjectName: hopProjectName, // Pages project name.
+    defaultWorkerName: hopWorkerName, // Cloudflare worker name.
 
     osDir: path.resolve(os.homedir(), './.wrangler'),
     projDir: path.resolve(projDir, './.wrangler'),
diff --git a/package-lock.json b/package-lock.json
index 3c520b8f..42c8ac85 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
 {
     "name": "@clevercanyon/micromatch.fork",
-    "version": "4.0.75",
+    "version": "4.0.77",
     "lockfileVersion": 3,
     "requires": true,
     "packages": {
         "": {
             "name": "@clevercanyon/micromatch.fork",
-            "version": "4.0.75",
+            "version": "4.0.77",
             "cpu": [
                 "x64",
                 "arm64"
@@ -17,11 +17,11 @@
                 "linux"
             ],
             "dependencies": {
-                "braces": "npm:@clevercanyon/braces.fork@^3.0.71",
-                "picomatch": "npm:@clevercanyon/picomatch.fork@^2.3.70"
+                "braces": "npm:@clevercanyon/braces.fork@^3.0.73",
+                "picomatch": "npm:@clevercanyon/picomatch.fork@^2.3.72"
             },
             "devDependencies": {
-                "@clevercanyon/dev-deps": "^1.0.285"
+                "@clevercanyon/dev-deps": "^1.0.296"
             },
             "engines": {
                 "node": "^20.5.0 || ^20.9.0",
@@ -134,9 +134,9 @@
             }
         },
         "node_modules/@antfu/utils": {
-            "version": "0.7.6",
-            "resolved": "https://registry.npmjs.org/@antfu/utils/-/utils-0.7.6.tgz",
-            "integrity": "sha512-pvFiLP2BeOKA/ZOS6jxx4XhKzdVLHDhGlFEaZ2flWWYf2xOqVniqpk38I04DFRyz+L0ASggl7SkItTc+ZLju4w==",
+            "version": "0.7.7",
+            "resolved": "https://registry.npmjs.org/@antfu/utils/-/utils-0.7.7.tgz",
+            "integrity": "sha512-gFPqTG7otEJ8uP6wrhDv6mqwGWYZKNvAcCq6u9hOj0c+IKCEsY4L1oC9trPq2SaWIzAfHvqfBDxF591JkMf+kg==",
             "dev": true,
             "funding": {
                 "url": "https://github.com/sponsors/antfu"
@@ -236,21 +236,21 @@
             }
         },
         "node_modules/@babel/core": {
-            "version": "7.23.5",
-            "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.5.tgz",
-            "integrity": "sha512-Cwc2XjUrG4ilcfOw4wBAK+enbdgwAcAJCfGUItPBKR7Mjw4aEfAFYrLxeRp4jWgtNIKn3n2AlBOfwwafl+42/g==",
+            "version": "7.23.6",
+            "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.6.tgz",
+            "integrity": "sha512-FxpRyGjrMJXh7X3wGLGhNDCRiwpWEF74sKjTLDJSG5Kyvow3QZaG0Adbqzi9ZrVjTWpsX+2cxWXD71NMg93kdw==",
             "dev": true,
             "dependencies": {
                 "@ampproject/remapping": "^2.2.0",
                 "@babel/code-frame": "^7.23.5",
-                "@babel/generator": "^7.23.5",
-                "@babel/helper-compilation-targets": "^7.22.15",
+                "@babel/generator": "^7.23.6",
+                "@babel/helper-compilation-targets": "^7.23.6",
                 "@babel/helper-module-transforms": "^7.23.3",
-                "@babel/helpers": "^7.23.5",
-                "@babel/parser": "^7.23.5",
+                "@babel/helpers": "^7.23.6",
+                "@babel/parser": "^7.23.6",
                 "@babel/template": "^7.22.15",
-                "@babel/traverse": "^7.23.5",
-                "@babel/types": "^7.23.5",
+                "@babel/traverse": "^7.23.6",
+                "@babel/types": "^7.23.6",
                 "convert-source-map": "^2.0.0",
                 "debug": "^4.1.0",
                 "gensync": "^1.0.0-beta.2",
@@ -275,12 +275,12 @@
             }
         },
         "node_modules/@babel/generator": {
-            "version": "7.23.5",
-            "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.5.tgz",
-            "integrity": "sha512-BPssCHrBD+0YrxviOa3QzpqwhNIXKEtOa2jQrm4FlmkC2apYgRnQcmPWiGZDlGxiNtltnUFolMe8497Esry+jA==",
+            "version": "7.23.6",
+            "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz",
+            "integrity": "sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==",
             "dev": true,
             "dependencies": {
-                "@babel/types": "^7.23.5",
+                "@babel/types": "^7.23.6",
                 "@jridgewell/gen-mapping": "^0.3.2",
                 "@jridgewell/trace-mapping": "^0.3.17",
                 "jsesc": "^2.5.1"
@@ -290,14 +290,14 @@
             }
         },
         "node_modules/@babel/helper-compilation-targets": {
-            "version": "7.22.15",
-            "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.15.tgz",
-            "integrity": "sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw==",
+            "version": "7.23.6",
+            "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz",
+            "integrity": "sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==",
             "dev": true,
             "dependencies": {
-                "@babel/compat-data": "^7.22.9",
-                "@babel/helper-validator-option": "^7.22.15",
-                "browserslist": "^4.21.9",
+                "@babel/compat-data": "^7.23.5",
+                "@babel/helper-validator-option": "^7.23.5",
+                "browserslist": "^4.22.2",
                 "lru-cache": "^5.1.1",
                 "semver": "^6.3.1"
             },
@@ -440,14 +440,14 @@
             }
         },
         "node_modules/@babel/helpers": {
-            "version": "7.23.5",
-            "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.5.tgz",
-            "integrity": "sha512-oO7us8FzTEsG3U6ag9MfdF1iA/7Z6dz+MtFhifZk8C8o453rGJFFWUP1t+ULM9TUIAzC9uxXEiXjOiVMyd7QPg==",
+            "version": "7.23.6",
+            "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.6.tgz",
+            "integrity": "sha512-wCfsbN4nBidDRhpDhvcKlzHWCTlgJYUUdSJfzXb2NuBssDSIjc3xcb+znA7l+zYsFljAcGM0aFkN40cR3lXiGA==",
             "dev": true,
             "dependencies": {
                 "@babel/template": "^7.22.15",
-                "@babel/traverse": "^7.23.5",
-                "@babel/types": "^7.23.5"
+                "@babel/traverse": "^7.23.6",
+                "@babel/types": "^7.23.6"
             },
             "engines": {
                 "node": ">=6.9.0"
@@ -539,9 +539,9 @@
             }
         },
         "node_modules/@babel/parser": {
-            "version": "7.23.5",
-            "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.5.tgz",
-            "integrity": "sha512-hOOqoiNXrmGdFbhgCzu6GiURxUgM27Xwd/aPuu8RfHEZPBzL1Z54okAHAQjXfcQNwvrlkAmAp4SlRTZ45vlthQ==",
+            "version": "7.23.6",
+            "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.6.tgz",
+            "integrity": "sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==",
             "dev": true,
             "bin": {
                 "parser": "bin/babel-parser.js"
@@ -728,9 +728,9 @@
             }
         },
         "node_modules/@babel/runtime": {
-            "version": "7.23.5",
-            "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.5.tgz",
-            "integrity": "sha512-NdUTHcPe4C99WxPub+K9l9tK5/lV4UXIoaHSYgzco9BCyjKAAwzdBI+wWtYqHt7LJdbo74ZjRPJgzVweq1sz0w==",
+            "version": "7.23.6",
+            "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.6.tgz",
+            "integrity": "sha512-zHd0eUrf5GZoOWVCXp6koAKQTfZV07eit6bGPmJgnZdnSAvvZee6zniW2XMF7Cmc4ISOOnPy3QaSiIJGJkVEDQ==",
             "dev": true,
             "dependencies": {
                 "regenerator-runtime": "^0.14.0"
@@ -754,20 +754,20 @@
             }
         },
         "node_modules/@babel/traverse": {
-            "version": "7.23.5",
-            "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.5.tgz",
-            "integrity": "sha512-czx7Xy5a6sapWWRx61m1Ke1Ra4vczu1mCTtJam5zRTBOonfdJ+S/B6HYmGYu3fJtr8GGET3si6IhgWVBhJ/m8w==",
+            "version": "7.23.6",
+            "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.6.tgz",
+            "integrity": "sha512-czastdK1e8YByZqezMPFiZ8ahwVMh/ESl9vPgvgdB9AmFMGP5jfpFax74AQgl5zj4XHzqeYAg2l8PuUeRS1MgQ==",
             "dev": true,
             "dependencies": {
                 "@babel/code-frame": "^7.23.5",
-                "@babel/generator": "^7.23.5",
+                "@babel/generator": "^7.23.6",
                 "@babel/helper-environment-visitor": "^7.22.20",
                 "@babel/helper-function-name": "^7.23.0",
                 "@babel/helper-hoist-variables": "^7.22.5",
                 "@babel/helper-split-export-declaration": "^7.22.6",
-                "@babel/parser": "^7.23.5",
-                "@babel/types": "^7.23.5",
-                "debug": "^4.1.0",
+                "@babel/parser": "^7.23.6",
+                "@babel/types": "^7.23.6",
+                "debug": "^4.3.1",
                 "globals": "^11.1.0"
             },
             "engines": {
@@ -784,9 +784,9 @@
             }
         },
         "node_modules/@babel/types": {
-            "version": "7.23.5",
-            "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.5.tgz",
-            "integrity": "sha512-ON5kSOJwVO6xXVRTvOI0eOnWe7VdUcIpsovGo9U/Br4Ie4UVFQTboO2cYnDhAGU6Fp+UxSiT+pMft0SMHfuq6w==",
+            "version": "7.23.6",
+            "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.6.tgz",
+            "integrity": "sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg==",
             "dev": true,
             "dependencies": {
                 "@babel/helper-string-parser": "^7.23.4",
@@ -837,9 +837,9 @@
             "dev": true
         },
         "node_modules/@clevercanyon/dev-deps": {
-            "version": "1.0.285",
-            "resolved": "https://registry.npmjs.org/@clevercanyon/dev-deps/-/dev-deps-1.0.285.tgz",
-            "integrity": "sha512-EnXk9db3TggVNWNWbFwNdyul5V+GNTv7Su2MMl4ymnUrQCVLDrWaUqKuCcD359YUM4JvK8SlxmmjQhI6vcA5vA==",
+            "version": "1.0.296",
+            "resolved": "https://registry.npmjs.org/@clevercanyon/dev-deps/-/dev-deps-1.0.296.tgz",
+            "integrity": "sha512-7GgOqFeCq9xzFLO529dvG0hiC9gMNv5HCQHYjgAtYBtOBsAO3Qm5Tege8JDZhp1fYvNew48RvxkM9G+s9p2QNg==",
             "cpu": [
                 "x64",
                 "arm64"
@@ -850,11 +850,11 @@
                 "linux"
             ],
             "dependencies": {
-                "@clevercanyon/madrun": "^1.0.122",
-                "@clevercanyon/utilities": "^1.0.496",
-                "@clevercanyon/utilities.bash": "^1.0.140",
-                "@clevercanyon/utilities.cfp": "^1.0.111",
-                "@clevercanyon/utilities.node": "^1.0.130",
+                "@clevercanyon/madrun": "^1.0.126",
+                "@clevercanyon/utilities": "^1.0.557",
+                "@clevercanyon/utilities.bash": "^1.0.142",
+                "@clevercanyon/utilities.cfp": "^1.0.118",
+                "@clevercanyon/utilities.node": "^1.0.134",
                 "@cloudflare/workers-types": "4.20231121.0",
                 "@eslint/js": "8.48.0",
                 "@iarna/toml": "2.2.5",
@@ -884,8 +884,8 @@
                 "@types/yargs-parser": "21.0.3",
                 "@typescript-eslint/eslint-plugin": "5.62.0",
                 "@typescript-eslint/parser": "5.62.0",
-                "@vitest/coverage-v8": "0.34.6",
-                "@vitest/ui": "0.34.6",
+                "@vitest/coverage-v8": "1.0.4",
+                "@vitest/ui": "1.0.4",
                 "browserslist-generator": "2.0.3",
                 "dotenv-vault": "1.25.0",
                 "eslint": "8.54.0",
@@ -904,10 +904,14 @@
                 "lightningcss": "1.22.1",
                 "mdast-util-to-hast": "13.0.2",
                 "mdast-util-toc": "7.0.0",
-                "postcss": "8.4.31",
+                "postcss": "8.4.32",
+                "postcss-import": "15.1.0",
+                "postcss-mixins": "9.0.4",
                 "postcss-preset-env": "9.3.0",
-                "postcss-safe-parser": "6.0.0",
+                "postcss-safe-parser": "7.0.0",
                 "postcss-scss": "4.0.9",
+                "postcss-simple-vars": "7.0.1",
+                "postcss-url": "10.1.3",
                 "postcss-variable-compress": "3.0.0",
                 "preact": "10.19.2",
                 "prettier": "3.1.0",
@@ -937,19 +941,21 @@
                 "stylelint-config-recess-order": "4.4.0",
                 "stylelint-config-standard-scss": "11.1.0",
                 "stylelint-scss": "5.3.1",
-                "tailwindcss": "3.3.5",
+                "tailwindcss": "3.3.6",
                 "tailwindcss-animated": "1.0.1",
-                "tailwindcss-themer": "3.1.3",
+                "tailwindcss-themer": "4.0.0",
+                "terser": "5.26.0",
+                "tsx": "4.6.2",
                 "typescript": "5.3.2",
                 "unist-util-visit": "5.0.0",
                 "unplugin-icons": "0.17.4",
-                "vite": "5.0.4",
+                "vite": "5.0.7",
                 "vite-plugin-dts": "3.6.4",
                 "vite-plugin-ejs": "1.7.0",
                 "vite-plugin-minify": "1.5.2",
-                "vitest": "0.34.6",
+                "vitest": "1.0.4",
                 "vitest-environment-miniflare": "2.14.1",
-                "wrangler": "3.18.0"
+                "wrangler": "3.19.0"
             },
             "engines": {
                 "node": "^20.5.0 || ^20.9.0",
@@ -960,9 +966,9 @@
             }
         },
         "node_modules/@clevercanyon/madrun": {
-            "version": "1.0.122",
-            "resolved": "https://registry.npmjs.org/@clevercanyon/madrun/-/madrun-1.0.122.tgz",
-            "integrity": "sha512-4SzbzddldtfbyHKsfBjoHtokiG95uIGJkD/HE4OspQk98ytLtfUcZmaSMgDiVcxU8GZg+o3d05b0vNvswsUCgA==",
+            "version": "1.0.126",
+            "resolved": "https://registry.npmjs.org/@clevercanyon/madrun/-/madrun-1.0.126.tgz",
+            "integrity": "sha512-3Jnuf7lsrbMCu2tT17bytkvLuSw0uuEUclfEb/GMCkznId6oCrgtm/xPR5yIOb6ZxpToh7gSC/LDdXyrvS6gbg==",
             "cpu": [
                 "x64",
                 "arm64"
@@ -973,8 +979,8 @@
                 "linux"
             ],
             "dependencies": {
-                "@clevercanyon/utilities": "^1.0.494",
-                "@clevercanyon/utilities.node": "^1.0.129"
+                "@clevercanyon/utilities": "^1.0.553",
+                "@clevercanyon/utilities.node": "^1.0.134"
             },
             "bin": {
                 "madrun": "dist/bin/cli.js"
@@ -988,9 +994,9 @@
             }
         },
         "node_modules/@clevercanyon/split-cmd.fork": {
-            "version": "1.0.73",
-            "resolved": "https://registry.npmjs.org/@clevercanyon/split-cmd.fork/-/split-cmd.fork-1.0.73.tgz",
-            "integrity": "sha512-35jmSFEcaJZV3D6bo4q7Gwgpo+KF+4B6luxbLHETnD0++dwH3J9RV8aLhdGu7X2ADfwdmqv84h0IEbOsCSagJw==",
+            "version": "1.0.75",
+            "resolved": "https://registry.npmjs.org/@clevercanyon/split-cmd.fork/-/split-cmd.fork-1.0.75.tgz",
+            "integrity": "sha512-T2oQ269xZ17xNWfhKHXlQn5DCqdfj/79antpFumFkipJdJnkCQsMo29nopvrPJinDdbfttoQhvjlJnUKcjzUgA==",
             "cpu": [
                 "x64",
                 "arm64"
@@ -1010,9 +1016,9 @@
             }
         },
         "node_modules/@clevercanyon/utilities": {
-            "version": "1.0.501",
-            "resolved": "https://registry.npmjs.org/@clevercanyon/utilities/-/utilities-1.0.501.tgz",
-            "integrity": "sha512-Y/NYa8YYyVM6yoxA6D9DnNYk9R8OrnYOiq70nHd3Nl1ahk3QvdO6YETUPMJGtyYtVZi6TyF53fLtfMrgTX3fgA==",
+            "version": "1.0.581",
+            "resolved": "https://registry.npmjs.org/@clevercanyon/utilities/-/utilities-1.0.581.tgz",
+            "integrity": "sha512-eKOQUmnOXKWeMk4pFP0v0uV3Ofl3auaEtiy5CyV7BNJkjYi1H1PGd9Gx15R/jqMmsAZO5yqNPjt2e52Oy9v8kA==",
             "cpu": [
                 "x64",
                 "arm64"
@@ -1037,18 +1043,18 @@
                 "ignore": "5.3.0",
                 "ip-regex": "5.0.0",
                 "micro-memoize": "4.1.2",
-                "micromatch": "npm:@clevercanyon/micromatch.fork@^4.0.75",
+                "micromatch": "npm:@clevercanyon/micromatch.fork@^4.0.77",
                 "parse-css-color": "0.2.1",
                 "preact": "10.19.2",
                 "preact-render-to-string": "6.3.1",
                 "semver": "7.5.4",
-                "tailwindcss": "3.3.5"
+                "tailwindcss": "3.3.6"
             }
         },
         "node_modules/@clevercanyon/utilities.bash": {
-            "version": "1.0.140",
-            "resolved": "https://registry.npmjs.org/@clevercanyon/utilities.bash/-/utilities.bash-1.0.140.tgz",
-            "integrity": "sha512-FJe1fj+PWbi83NU71QgyE9/O3UmOMT2M1vmKSLSSfJ8X5vUcJWsB2/SJCxGIZHxND9RLkQLQht5Ai7ebifDOaQ==",
+            "version": "1.0.142",
+            "resolved": "https://registry.npmjs.org/@clevercanyon/utilities.bash/-/utilities.bash-1.0.142.tgz",
+            "integrity": "sha512-jqNtzWmH1CmoP9FpwmIyaMICwo3mwAw0pVzcdJS6pePX7er8gnJEoNXKJTMQbbZJX2iQP1KXX9LFMif+i59VYA==",
             "cpu": [
                 "x64",
                 "arm64"
@@ -1066,14 +1072,14 @@
                 "url": "https://github.com/sponsors/clevercanyon"
             },
             "peerDependencies": {
-                "@clevercanyon/utilities": "^1.0.494",
-                "@clevercanyon/utilities.node": "^1.0.129"
+                "@clevercanyon/utilities": "^1.0.501",
+                "@clevercanyon/utilities.node": "^1.0.131"
             }
         },
         "node_modules/@clevercanyon/utilities.cfp": {
-            "version": "1.0.112",
-            "resolved": "https://registry.npmjs.org/@clevercanyon/utilities.cfp/-/utilities.cfp-1.0.112.tgz",
-            "integrity": "sha512-Fql/Z2jGJlhmWyJoeHixHWlX3pMSXdegK4iq2FFP14GHxW/GIJUxWHANI6DlWxFvrEnyO5NcjocnUoSy99A0yA==",
+            "version": "1.0.123",
+            "resolved": "https://registry.npmjs.org/@clevercanyon/utilities.cfp/-/utilities.cfp-1.0.123.tgz",
+            "integrity": "sha512-rTw8lKKQCwS4kHje/8rJNrjvSYBxrlkXkQlUs+0zD9ut6Ke3yFKJLypTKDEo+yKEnmKkfRrqztxRA7XIQIMzkQ==",
             "cpu": [
                 "x64",
                 "arm64"
@@ -1091,15 +1097,15 @@
                 "url": "https://github.com/sponsors/clevercanyon"
             },
             "peerDependencies": {
-                "@clevercanyon/utilities": "^1.0.501",
-                "@clevercanyon/utilities.cfw": "^1.0.123",
-                "@clevercanyon/utilities.web": "^1.0.88"
+                "@clevercanyon/utilities": "^1.0.562",
+                "@clevercanyon/utilities.cfw": "^1.0.128",
+                "@clevercanyon/utilities.web": "^1.0.90"
             }
         },
         "node_modules/@clevercanyon/utilities.cfw": {
-            "version": "1.0.123",
-            "resolved": "https://registry.npmjs.org/@clevercanyon/utilities.cfw/-/utilities.cfw-1.0.123.tgz",
-            "integrity": "sha512-WTmMaTztWy+OBpD42zhELrJszj6zRyEJQc/JWOX9e8O7fk524chDbtp5V9CGN+F4WHCkzLpX3a5chq23lFLKPw==",
+            "version": "1.0.129",
+            "resolved": "https://registry.npmjs.org/@clevercanyon/utilities.cfw/-/utilities.cfw-1.0.129.tgz",
+            "integrity": "sha512-b6zygtATtktQHrtb+z+uocve6uNA+MBAd8WT3br+adSVyxnAOh2OnxyXMN3CD9mJyoPvrmDJDOTKfHpTF9Mb7Q==",
             "cpu": [
                 "x64",
                 "arm64"
@@ -1118,14 +1124,14 @@
                 "url": "https://github.com/sponsors/clevercanyon"
             },
             "peerDependencies": {
-                "@clevercanyon/utilities": "^1.0.501",
+                "@clevercanyon/utilities": "^1.0.559",
                 "@cloudflare/kv-asset-handler": "0.2.0"
             }
         },
         "node_modules/@clevercanyon/utilities.node": {
-            "version": "1.0.131",
-            "resolved": "https://registry.npmjs.org/@clevercanyon/utilities.node/-/utilities.node-1.0.131.tgz",
-            "integrity": "sha512-8jLgNA8DIWaheViXI463gEzhZqqmgJCAk6WbTU4xZ2HxRNI/bnNizl8RVmfU4JgL70tLWSVYFgIpAnuKRLDc6g==",
+            "version": "1.0.134",
+            "resolved": "https://registry.npmjs.org/@clevercanyon/utilities.node/-/utilities.node-1.0.134.tgz",
+            "integrity": "sha512-nmJGFf2QYwu+ACmS7AFBECDOkkWFpjOuQI54P+FUmEcc2AC9LNQJn3eKnMJ8h2RFernVlnGwvwhOV6KHfS9Yaw==",
             "cpu": [
                 "x64",
                 "arm64"
@@ -1143,8 +1149,8 @@
                 "url": "https://github.com/sponsors/clevercanyon"
             },
             "peerDependencies": {
-                "@clevercanyon/split-cmd.fork": "^1.0.73",
-                "@clevercanyon/utilities": "^1.0.501",
+                "@clevercanyon/split-cmd.fork": "^1.0.75",
+                "@clevercanyon/utilities": "^1.0.545",
                 "archiver": "6.0.1",
                 "boxen": "7.1.1",
                 "chalk": "5.3.0",
@@ -1155,16 +1161,16 @@
                 "globby": "14.0.0",
                 "prettier": "3.1.0",
                 "shescape": "2.0.2",
-                "spawn-please": "npm:@clevercanyon/spawn-please.fork@^2.0.67",
+                "spawn-please": "npm:@clevercanyon/spawn-please.fork@^2.0.69",
                 "term-img": "6.0.0",
                 "yargs": "17.7.2",
                 "yargs-parser": "21.1.1"
             }
         },
         "node_modules/@clevercanyon/utilities.web": {
-            "version": "1.0.88",
-            "resolved": "https://registry.npmjs.org/@clevercanyon/utilities.web/-/utilities.web-1.0.88.tgz",
-            "integrity": "sha512-abf3AjKahod2iYqY1xz/NcdECYEv5gUUTmjg38OLfuavm6lvKumRCjKYorHA+cjzFwlQtBS0qfJxfHJRJSrKww==",
+            "version": "1.0.90",
+            "resolved": "https://registry.npmjs.org/@clevercanyon/utilities.web/-/utilities.web-1.0.90.tgz",
+            "integrity": "sha512-WFL0VSN5ydilE9cA0qaYS4UJTVPsvVjm/QXT88kO42dACpTQ9jYJe9jz3y0L/Z+1jdDTBXmeDjGQpuNgERI4cg==",
             "cpu": [
                 "x64",
                 "arm64"
@@ -1183,7 +1189,7 @@
                 "url": "https://github.com/sponsors/clevercanyon"
             },
             "peerDependencies": {
-                "@clevercanyon/utilities": "^1.0.494"
+                "@clevercanyon/utilities": "^1.0.501"
             }
         },
         "node_modules/@cloudflare/kv-asset-handler": {
@@ -2284,9 +2290,9 @@
             }
         },
         "node_modules/@esbuild/android-arm": {
-            "version": "0.19.8",
-            "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.8.tgz",
-            "integrity": "sha512-31E2lxlGM1KEfivQl8Yf5aYU/mflz9g06H6S15ITUFQueMFtFjESRMoDSkvMo8thYvLBax+VKTPlpnx+sPicOA==",
+            "version": "0.19.9",
+            "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.9.tgz",
+            "integrity": "sha512-jkYjjq7SdsWuNI6b5quymW0oC83NN5FdRPuCbs9HZ02mfVdAP8B8eeqLSYU3gb6OJEaY5CQabtTFbqBf26H3GA==",
             "cpu": [
                 "arm"
             ],
@@ -2300,9 +2306,9 @@
             }
         },
         "node_modules/@esbuild/android-arm64": {
-            "version": "0.19.8",
-            "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.8.tgz",
-            "integrity": "sha512-B8JbS61bEunhfx8kasogFENgQfr/dIp+ggYXwTqdbMAgGDhRa3AaPpQMuQU0rNxDLECj6FhDzk1cF9WHMVwrtA==",
+            "version": "0.19.9",
+            "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.9.tgz",
+            "integrity": "sha512-q4cR+6ZD0938R19MyEW3jEsMzbb/1rulLXiNAJQADD/XYp7pT+rOS5JGxvpRW8dFDEfjW4wLgC/3FXIw4zYglQ==",
             "cpu": [
                 "arm64"
             ],
@@ -2316,9 +2322,9 @@
             }
         },
         "node_modules/@esbuild/android-x64": {
-            "version": "0.19.8",
-            "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.8.tgz",
-            "integrity": "sha512-rdqqYfRIn4jWOp+lzQttYMa2Xar3OK9Yt2fhOhzFXqg0rVWEfSclJvZq5fZslnz6ypHvVf3CT7qyf0A5pM682A==",
+            "version": "0.19.9",
+            "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.9.tgz",
+            "integrity": "sha512-KOqoPntWAH6ZxDwx1D6mRntIgZh9KodzgNOy5Ebt9ghzffOk9X2c1sPwtM9P+0eXbefnDhqYfkh5PLP5ULtWFA==",
             "cpu": [
                 "x64"
             ],
@@ -2332,9 +2338,9 @@
             }
         },
         "node_modules/@esbuild/darwin-arm64": {
-            "version": "0.19.8",
-            "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.8.tgz",
-            "integrity": "sha512-RQw9DemMbIq35Bprbboyf8SmOr4UXsRVxJ97LgB55VKKeJOOdvsIPy0nFyF2l8U+h4PtBx/1kRf0BelOYCiQcw==",
+            "version": "0.19.9",
+            "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.9.tgz",
+            "integrity": "sha512-KBJ9S0AFyLVx2E5D8W0vExqRW01WqRtczUZ8NRu+Pi+87opZn5tL4Y0xT0mA4FtHctd0ZgwNoN639fUUGlNIWw==",
             "cpu": [
                 "arm64"
             ],
@@ -2348,9 +2354,9 @@
             }
         },
         "node_modules/@esbuild/darwin-x64": {
-            "version": "0.19.8",
-            "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.8.tgz",
-            "integrity": "sha512-3sur80OT9YdeZwIVgERAysAbwncom7b4bCI2XKLjMfPymTud7e/oY4y+ci1XVp5TfQp/bppn7xLw1n/oSQY3/Q==",
+            "version": "0.19.9",
+            "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.9.tgz",
+            "integrity": "sha512-vE0VotmNTQaTdX0Q9dOHmMTao6ObjyPm58CHZr1UK7qpNleQyxlFlNCaHsHx6Uqv86VgPmR4o2wdNq3dP1qyDQ==",
             "cpu": [
                 "x64"
             ],
@@ -2364,9 +2370,9 @@
             }
         },
         "node_modules/@esbuild/freebsd-arm64": {
-            "version": "0.19.8",
-            "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.8.tgz",
-            "integrity": "sha512-WAnPJSDattvS/XtPCTj1tPoTxERjcTpH6HsMr6ujTT+X6rylVe8ggxk8pVxzf5U1wh5sPODpawNicF5ta/9Tmw==",
+            "version": "0.19.9",
+            "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.9.tgz",
+            "integrity": "sha512-uFQyd/o1IjiEk3rUHSwUKkqZwqdvuD8GevWF065eqgYfexcVkxh+IJgwTaGZVu59XczZGcN/YMh9uF1fWD8j1g==",
             "cpu": [
                 "arm64"
             ],
@@ -2380,9 +2386,9 @@
             }
         },
         "node_modules/@esbuild/freebsd-x64": {
-            "version": "0.19.8",
-            "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.8.tgz",
-            "integrity": "sha512-ICvZyOplIjmmhjd6mxi+zxSdpPTKFfyPPQMQTK/w+8eNK6WV01AjIztJALDtwNNfFhfZLux0tZLC+U9nSyA5Zg==",
+            "version": "0.19.9",
+            "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.9.tgz",
+            "integrity": "sha512-WMLgWAtkdTbTu1AWacY7uoj/YtHthgqrqhf1OaEWnZb7PQgpt8eaA/F3LkV0E6K/Lc0cUr/uaVP/49iE4M4asA==",
             "cpu": [
                 "x64"
             ],
@@ -2396,9 +2402,9 @@
             }
         },
         "node_modules/@esbuild/linux-arm": {
-            "version": "0.19.8",
-            "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.8.tgz",
-            "integrity": "sha512-H4vmI5PYqSvosPaTJuEppU9oz1dq2A7Mr2vyg5TF9Ga+3+MGgBdGzcyBP7qK9MrwFQZlvNyJrvz6GuCaj3OukQ==",
+            "version": "0.19.9",
+            "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.9.tgz",
+            "integrity": "sha512-C/ChPohUYoyUaqn1h17m/6yt6OB14hbXvT8EgM1ZWaiiTYz7nWZR0SYmMnB5BzQA4GXl3BgBO1l8MYqL/He3qw==",
             "cpu": [
                 "arm"
             ],
@@ -2412,9 +2418,9 @@
             }
         },
         "node_modules/@esbuild/linux-arm64": {
-            "version": "0.19.8",
-            "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.8.tgz",
-            "integrity": "sha512-z1zMZivxDLHWnyGOctT9JP70h0beY54xDDDJt4VpTX+iwA77IFsE1vCXWmprajJGa+ZYSqkSbRQ4eyLCpCmiCQ==",
+            "version": "0.19.9",
+            "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.9.tgz",
+            "integrity": "sha512-PiPblfe1BjK7WDAKR1Cr9O7VVPqVNpwFcPWgfn4xu0eMemzRp442hXyzF/fSwgrufI66FpHOEJk0yYdPInsmyQ==",
             "cpu": [
                 "arm64"
             ],
@@ -2428,9 +2434,9 @@
             }
         },
         "node_modules/@esbuild/linux-ia32": {
-            "version": "0.19.8",
-            "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.8.tgz",
-            "integrity": "sha512-1a8suQiFJmZz1khm/rDglOc8lavtzEMRo0v6WhPgxkrjcU0LkHj+TwBrALwoz/OtMExvsqbbMI0ChyelKabSvQ==",
+            "version": "0.19.9",
+            "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.9.tgz",
+            "integrity": "sha512-f37i/0zE0MjDxijkPSQw1CO/7C27Eojqb+r3BbHVxMLkj8GCa78TrBZzvPyA/FNLUMzP3eyHCVkAopkKVja+6Q==",
             "cpu": [
                 "ia32"
             ],
@@ -2444,9 +2450,9 @@
             }
         },
         "node_modules/@esbuild/linux-loong64": {
-            "version": "0.19.8",
-            "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.8.tgz",
-            "integrity": "sha512-fHZWS2JJxnXt1uYJsDv9+b60WCc2RlvVAy1F76qOLtXRO+H4mjt3Tr6MJ5l7Q78X8KgCFudnTuiQRBhULUyBKQ==",
+            "version": "0.19.9",
+            "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.9.tgz",
+            "integrity": "sha512-t6mN147pUIf3t6wUt3FeumoOTPfmv9Cc6DQlsVBpB7eCpLOqQDyWBP1ymXn1lDw4fNUSb/gBcKAmvTP49oIkaA==",
             "cpu": [
                 "loong64"
             ],
@@ -2460,9 +2466,9 @@
             }
         },
         "node_modules/@esbuild/linux-mips64el": {
-            "version": "0.19.8",
-            "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.8.tgz",
-            "integrity": "sha512-Wy/z0EL5qZYLX66dVnEg9riiwls5IYnziwuju2oUiuxVc+/edvqXa04qNtbrs0Ukatg5HEzqT94Zs7J207dN5Q==",
+            "version": "0.19.9",
+            "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.9.tgz",
+            "integrity": "sha512-jg9fujJTNTQBuDXdmAg1eeJUL4Jds7BklOTkkH80ZgQIoCTdQrDaHYgbFZyeTq8zbY+axgptncko3v9p5hLZtw==",
             "cpu": [
                 "mips64el"
             ],
@@ -2476,9 +2482,9 @@
             }
         },
         "node_modules/@esbuild/linux-ppc64": {
-            "version": "0.19.8",
-            "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.8.tgz",
-            "integrity": "sha512-ETaW6245wK23YIEufhMQ3HSeHO7NgsLx8gygBVldRHKhOlD1oNeNy/P67mIh1zPn2Hr2HLieQrt6tWrVwuqrxg==",
+            "version": "0.19.9",
+            "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.9.tgz",
+            "integrity": "sha512-tkV0xUX0pUUgY4ha7z5BbDS85uI7ABw3V1d0RNTii7E9lbmV8Z37Pup2tsLV46SQWzjOeyDi1Q7Wx2+QM8WaCQ==",
             "cpu": [
                 "ppc64"
             ],
@@ -2492,9 +2498,9 @@
             }
         },
         "node_modules/@esbuild/linux-riscv64": {
-            "version": "0.19.8",
-            "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.8.tgz",
-            "integrity": "sha512-T2DRQk55SgoleTP+DtPlMrxi/5r9AeFgkhkZ/B0ap99zmxtxdOixOMI570VjdRCs9pE4Wdkz7JYrsPvsl7eESg==",
+            "version": "0.19.9",
+            "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.9.tgz",
+            "integrity": "sha512-DfLp8dj91cufgPZDXr9p3FoR++m3ZJ6uIXsXrIvJdOjXVREtXuQCjfMfvmc3LScAVmLjcfloyVtpn43D56JFHg==",
             "cpu": [
                 "riscv64"
             ],
@@ -2508,9 +2514,9 @@
             }
         },
         "node_modules/@esbuild/linux-s390x": {
-            "version": "0.19.8",
-            "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.8.tgz",
-            "integrity": "sha512-NPxbdmmo3Bk7mbNeHmcCd7R7fptJaczPYBaELk6NcXxy7HLNyWwCyDJ/Xx+/YcNH7Im5dHdx9gZ5xIwyliQCbg==",
+            "version": "0.19.9",
+            "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.9.tgz",
+            "integrity": "sha512-zHbglfEdC88KMgCWpOl/zc6dDYJvWGLiUtmPRsr1OgCViu3z5GncvNVdf+6/56O2Ca8jUU+t1BW261V6kp8qdw==",
             "cpu": [
                 "s390x"
             ],
@@ -2524,9 +2530,9 @@
             }
         },
         "node_modules/@esbuild/linux-x64": {
-            "version": "0.19.8",
-            "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.8.tgz",
-            "integrity": "sha512-lytMAVOM3b1gPypL2TRmZ5rnXl7+6IIk8uB3eLsV1JwcizuolblXRrc5ShPrO9ls/b+RTp+E6gbsuLWHWi2zGg==",
+            "version": "0.19.9",
+            "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.9.tgz",
+            "integrity": "sha512-JUjpystGFFmNrEHQnIVG8hKwvA2DN5o7RqiO1CVX8EN/F/gkCjkUMgVn6hzScpwnJtl2mPR6I9XV1oW8k9O+0A==",
             "cpu": [
                 "x64"
             ],
@@ -2540,9 +2546,9 @@
             }
         },
         "node_modules/@esbuild/netbsd-x64": {
-            "version": "0.19.8",
-            "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.8.tgz",
-            "integrity": "sha512-hvWVo2VsXz/8NVt1UhLzxwAfo5sioj92uo0bCfLibB0xlOmimU/DeAEsQILlBQvkhrGjamP0/el5HU76HAitGw==",
+            "version": "0.19.9",
+            "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.9.tgz",
+            "integrity": "sha512-GThgZPAwOBOsheA2RUlW5UeroRfESwMq/guy8uEe3wJlAOjpOXuSevLRd70NZ37ZrpO6RHGHgEHvPg1h3S1Jug==",
             "cpu": [
                 "x64"
             ],
@@ -2556,9 +2562,9 @@
             }
         },
         "node_modules/@esbuild/openbsd-x64": {
-            "version": "0.19.8",
-            "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.8.tgz",
-            "integrity": "sha512-/7Y7u77rdvmGTxR83PgaSvSBJCC2L3Kb1M/+dmSIvRvQPXXCuC97QAwMugBNG0yGcbEGfFBH7ojPzAOxfGNkwQ==",
+            "version": "0.19.9",
+            "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.9.tgz",
+            "integrity": "sha512-Ki6PlzppaFVbLnD8PtlVQfsYw4S9n3eQl87cqgeIw+O3sRr9IghpfSKY62mggdt1yCSZ8QWvTZ9jo9fjDSg9uw==",
             "cpu": [
                 "x64"
             ],
@@ -2572,9 +2578,9 @@
             }
         },
         "node_modules/@esbuild/sunos-x64": {
-            "version": "0.19.8",
-            "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.8.tgz",
-            "integrity": "sha512-9Lc4s7Oi98GqFA4HzA/W2JHIYfnXbUYgekUP/Sm4BG9sfLjyv6GKKHKKVs83SMicBF2JwAX6A1PuOLMqpD001w==",
+            "version": "0.19.9",
+            "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.9.tgz",
+            "integrity": "sha512-MLHj7k9hWh4y1ddkBpvRj2b9NCBhfgBt3VpWbHQnXRedVun/hC7sIyTGDGTfsGuXo4ebik2+3ShjcPbhtFwWDw==",
             "cpu": [
                 "x64"
             ],
@@ -2588,9 +2594,9 @@
             }
         },
         "node_modules/@esbuild/win32-arm64": {
-            "version": "0.19.8",
-            "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.8.tgz",
-            "integrity": "sha512-rq6WzBGjSzihI9deW3fC2Gqiak68+b7qo5/3kmB6Gvbh/NYPA0sJhrnp7wgV4bNwjqM+R2AApXGxMO7ZoGhIJg==",
+            "version": "0.19.9",
+            "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.9.tgz",
+            "integrity": "sha512-GQoa6OrQ8G08guMFgeXPH7yE/8Dt0IfOGWJSfSH4uafwdC7rWwrfE6P9N8AtPGIjUzdo2+7bN8Xo3qC578olhg==",
             "cpu": [
                 "arm64"
             ],
@@ -2604,9 +2610,9 @@
             }
         },
         "node_modules/@esbuild/win32-ia32": {
-            "version": "0.19.8",
-            "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.8.tgz",
-            "integrity": "sha512-AIAbverbg5jMvJznYiGhrd3sumfwWs8572mIJL5NQjJa06P8KfCPWZQ0NwZbPQnbQi9OWSZhFVSUWjjIrn4hSw==",
+            "version": "0.19.9",
+            "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.9.tgz",
+            "integrity": "sha512-UOozV7Ntykvr5tSOlGCrqU3NBr3d8JqPes0QWN2WOXfvkWVGRajC+Ym0/Wj88fUgecUCLDdJPDF0Nna2UK3Qtg==",
             "cpu": [
                 "ia32"
             ],
@@ -2620,9 +2626,9 @@
             }
         },
         "node_modules/@esbuild/win32-x64": {
-            "version": "0.19.8",
-            "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.8.tgz",
-            "integrity": "sha512-bfZ0cQ1uZs2PqpulNL5j/3w+GDhP36k1K5c38QdQg+Swy51jFZWWeIkteNsufkQxp986wnqRRsb/bHbY1WQ7TA==",
+            "version": "0.19.9",
+            "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.9.tgz",
+            "integrity": "sha512-oxoQgglOP7RH6iasDrhY+R/3cHrfwIDvRlT4CGChflq6twk8iENeVvMJjmvBb94Ik1Z+93iGO27err7w6l54GQ==",
             "cpu": [
                 "x64"
             ],
@@ -3531,9 +3537,9 @@
             }
         },
         "node_modules/@mdn/browser-compat-data": {
-            "version": "5.4.3",
-            "resolved": "https://registry.npmjs.org/@mdn/browser-compat-data/-/browser-compat-data-5.4.3.tgz",
-            "integrity": "sha512-+VnaO5zYUwFQVuRqp2qLPGR5GwhhJ/lrp0yEmamJ/nI15P2GKwGBEWRDiITZR8i6AYxeiQSu2rOi/gqxehnPuA==",
+            "version": "5.4.5",
+            "resolved": "https://registry.npmjs.org/@mdn/browser-compat-data/-/browser-compat-data-5.4.5.tgz",
+            "integrity": "sha512-n3/+wko8WFd/fbiPCOuBB6HfKL6hTcygFEZ/MpmvpMRbgDSdlNMopDFGjsoTYqCbzTVTX9TL/StXco4yx2v58Q==",
             "dev": true
         },
         "node_modules/@mdx-js/esbuild": {
@@ -3638,15 +3644,15 @@
             }
         },
         "node_modules/@microsoft/api-extractor": {
-            "version": "7.38.3",
-            "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.38.3.tgz",
-            "integrity": "sha512-xt9iYyC5f39281j77JTA9C3ISJpW1XWkCcnw+2vM78CPnro6KhPfwQdPDfwS5JCPNuq0grm8cMdPUOPvrchDWw==",
+            "version": "7.38.5",
+            "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.38.5.tgz",
+            "integrity": "sha512-c/w2zfqBcBJxaCzpJNvFoouWewcYrUOfeu5ZkWCCIXTF9a/gXM85RGevEzlMAIEGM/kssAAZSXRJIZ3Q5vLFow==",
             "dev": true,
             "dependencies": {
-                "@microsoft/api-extractor-model": "7.28.2",
+                "@microsoft/api-extractor-model": "7.28.3",
                 "@microsoft/tsdoc": "0.14.2",
                 "@microsoft/tsdoc-config": "~0.16.1",
-                "@rushstack/node-core-library": "3.61.0",
+                "@rushstack/node-core-library": "3.62.0",
                 "@rushstack/rig-package": "0.5.1",
                 "@rushstack/ts-command-line": "4.17.1",
                 "colors": "~1.2.1",
@@ -3661,14 +3667,14 @@
             }
         },
         "node_modules/@microsoft/api-extractor-model": {
-            "version": "7.28.2",
-            "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.28.2.tgz",
-            "integrity": "sha512-vkojrM2fo3q4n4oPh4uUZdjJ2DxQ2+RnDQL/xhTWSRUNPF6P4QyrvY357HBxbnltKcYu+nNNolVqc6TIGQ73Ig==",
+            "version": "7.28.3",
+            "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.28.3.tgz",
+            "integrity": "sha512-wT/kB2oDbdZXITyDh2SQLzaWwTOFbV326fP0pUwNW00WeliARs0qjmXBWmGWardEzp2U3/axkO3Lboqun6vrig==",
             "dev": true,
             "dependencies": {
                 "@microsoft/tsdoc": "0.14.2",
                 "@microsoft/tsdoc-config": "~0.16.1",
-                "@rushstack/node-core-library": "3.61.0"
+                "@rushstack/node-core-library": "3.62.0"
             }
         },
         "node_modules/@microsoft/api-extractor/node_modules/source-map": {
@@ -5226,9 +5232,9 @@
             }
         },
         "node_modules/@polka/url": {
-            "version": "1.0.0-next.23",
-            "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.23.tgz",
-            "integrity": "sha512-C16M+IYz0rgRhWZdCmK+h58JMv8vijAA61gmz2rspCSwKwzBebpdcsiUmwrtJRdphuY30i6BSLEOP8ppbNLyLg==",
+            "version": "1.0.0-next.24",
+            "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.24.tgz",
+            "integrity": "sha512-2LuNTFBIO0m7kKIQvvPHN6UE63VjpmL9rnEEaOOaiSPbZK+zUOYIzBAWcED+3XYzhYsd/0mD57VdxAEqqV52CQ==",
             "dev": true
         },
         "node_modules/@preact/signals": {
@@ -5249,9 +5255,9 @@
             }
         },
         "node_modules/@preact/signals-core": {
-            "version": "1.5.0",
-            "resolved": "https://registry.npmjs.org/@preact/signals-core/-/signals-core-1.5.0.tgz",
-            "integrity": "sha512-U2diO1Z4i1n2IoFgMYmRdHWGObNrcuTRxyNEn7deSq2cru0vj0583HYQZHsAqcs7FE+hQyX3mjIV7LAfHCvy8w==",
+            "version": "1.5.1",
+            "resolved": "https://registry.npmjs.org/@preact/signals-core/-/signals-core-1.5.1.tgz",
+            "integrity": "sha512-dE6f+WCX5ZUDwXzUIWNMhhglmuLpqJhuy3X3xHrhZYI0Hm2LyQwOu0l9mdPiWrVNsE+Q7txOnJPgtIqHCYoBVA==",
             "dev": true,
             "peer": true,
             "funding": {
@@ -5380,9 +5386,9 @@
             "dev": true
         },
         "node_modules/@rollup/rollup-android-arm-eabi": {
-            "version": "4.6.1",
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.6.1.tgz",
-            "integrity": "sha512-0WQ0ouLejaUCRsL93GD4uft3rOmB8qoQMU05Kb8CmMtMBe7XUDLAltxVZI1q6byNqEtU7N1ZX1Vw5lIpgulLQA==",
+            "version": "4.8.0",
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.8.0.tgz",
+            "integrity": "sha512-zdTObFRoNENrdPpnTNnhOljYIcOX7aI7+7wyrSpPFFIOf/nRdedE6IYsjaBE7tjukphh1tMTojgJ7p3lKY8x6Q==",
             "cpu": [
                 "arm"
             ],
@@ -5393,9 +5399,9 @@
             ]
         },
         "node_modules/@rollup/rollup-android-arm64": {
-            "version": "4.6.1",
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.6.1.tgz",
-            "integrity": "sha512-1TKm25Rn20vr5aTGGZqo6E4mzPicCUD79k17EgTLAsXc1zysyi4xXKACfUbwyANEPAEIxkzwue6JZ+stYzWUTA==",
+            "version": "4.8.0",
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.8.0.tgz",
+            "integrity": "sha512-aiItwP48BiGpMFS9Znjo/xCNQVwTQVcRKkFKsO81m8exrGjHkCBDvm9PHay2kpa8RPnZzzKcD1iQ9KaLY4fPQQ==",
             "cpu": [
                 "arm64"
             ],
@@ -5406,9 +5412,9 @@
             ]
         },
         "node_modules/@rollup/rollup-darwin-arm64": {
-            "version": "4.6.1",
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.6.1.tgz",
-            "integrity": "sha512-cEXJQY/ZqMACb+nxzDeX9IPLAg7S94xouJJCNVE5BJM8JUEP4HeTF+ti3cmxWeSJo+5D+o8Tc0UAWUkfENdeyw==",
+            "version": "4.8.0",
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.8.0.tgz",
+            "integrity": "sha512-zhNIS+L4ZYkYQUjIQUR6Zl0RXhbbA0huvNIWjmPc2SL0cB1h5Djkcy+RZ3/Bwszfb6vgwUvcVJYD6e6Zkpsi8g==",
             "cpu": [
                 "arm64"
             ],
@@ -5419,9 +5425,9 @@
             ]
         },
         "node_modules/@rollup/rollup-darwin-x64": {
-            "version": "4.6.1",
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.6.1.tgz",
-            "integrity": "sha512-LoSU9Xu56isrkV2jLldcKspJ7sSXmZWkAxg7sW/RfF7GS4F5/v4EiqKSMCFbZtDu2Nc1gxxFdQdKwkKS4rwxNg==",
+            "version": "4.8.0",
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.8.0.tgz",
+            "integrity": "sha512-A/FAHFRNQYrELrb/JHncRWzTTXB2ticiRFztP4ggIUAfa9Up1qfW8aG2w/mN9jNiZ+HB0t0u0jpJgFXG6BfRTA==",
             "cpu": [
                 "x64"
             ],
@@ -5432,9 +5438,9 @@
             ]
         },
         "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
-            "version": "4.6.1",
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.6.1.tgz",
-            "integrity": "sha512-EfI3hzYAy5vFNDqpXsNxXcgRDcFHUWSx5nnRSCKwXuQlI5J9dD84g2Usw81n3FLBNsGCegKGwwTVsSKK9cooSQ==",
+            "version": "4.8.0",
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.8.0.tgz",
+            "integrity": "sha512-JsidBnh3p2IJJA4/2xOF2puAYqbaczB3elZDT0qHxn362EIoIkq7hrR43Xa8RisgI6/WPfvb2umbGsuvf7E37A==",
             "cpu": [
                 "arm"
             ],
@@ -5445,9 +5451,9 @@
             ]
         },
         "node_modules/@rollup/rollup-linux-arm64-gnu": {
-            "version": "4.6.1",
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.6.1.tgz",
-            "integrity": "sha512-9lhc4UZstsegbNLhH0Zu6TqvDfmhGzuCWtcTFXY10VjLLUe4Mr0Ye2L3rrtHaDd/J5+tFMEuo5LTCSCMXWfUKw==",
+            "version": "4.8.0",
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.8.0.tgz",
+            "integrity": "sha512-hBNCnqw3EVCkaPB0Oqd24bv8SklETptQWcJz06kb9OtiShn9jK1VuTgi7o4zPSt6rNGWQOTDEAccbk0OqJmS+g==",
             "cpu": [
                 "arm64"
             ],
@@ -5458,9 +5464,9 @@
             ]
         },
         "node_modules/@rollup/rollup-linux-arm64-musl": {
-            "version": "4.6.1",
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.6.1.tgz",
-            "integrity": "sha512-FfoOK1yP5ksX3wwZ4Zk1NgyGHZyuRhf99j64I5oEmirV8EFT7+OhUZEnP+x17lcP/QHJNWGsoJwrz4PJ9fBEXw==",
+            "version": "4.8.0",
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.8.0.tgz",
+            "integrity": "sha512-Fw9ChYfJPdltvi9ALJ9wzdCdxGw4wtq4t1qY028b2O7GwB5qLNSGtqMsAel1lfWTZvf4b6/+4HKp0GlSYg0ahA==",
             "cpu": [
                 "arm64"
             ],
@@ -5470,10 +5476,23 @@
                 "linux"
             ]
         },
+        "node_modules/@rollup/rollup-linux-riscv64-gnu": {
+            "version": "4.8.0",
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.8.0.tgz",
+            "integrity": "sha512-BH5xIh7tOzS9yBi8dFrCTG8Z6iNIGWGltd3IpTSKp6+pNWWO6qy8eKoRxOtwFbMrid5NZaidLYN6rHh9aB8bEw==",
+            "cpu": [
+                "riscv64"
+            ],
+            "dev": true,
+            "optional": true,
+            "os": [
+                "linux"
+            ]
+        },
         "node_modules/@rollup/rollup-linux-x64-gnu": {
-            "version": "4.6.1",
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.6.1.tgz",
-            "integrity": "sha512-DNGZvZDO5YF7jN5fX8ZqmGLjZEXIJRdJEdTFMhiyXqyXubBa0WVLDWSNlQ5JR2PNgDbEV1VQowhVRUh+74D+RA==",
+            "version": "4.8.0",
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.8.0.tgz",
+            "integrity": "sha512-PmvAj8k6EuWiyLbkNpd6BLv5XeYFpqWuRvRNRl80xVfpGXK/z6KYXmAgbI4ogz7uFiJxCnYcqyvZVD0dgFog7Q==",
             "cpu": [
                 "x64"
             ],
@@ -5484,9 +5503,9 @@
             ]
         },
         "node_modules/@rollup/rollup-linux-x64-musl": {
-            "version": "4.6.1",
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.6.1.tgz",
-            "integrity": "sha512-RkJVNVRM+piYy87HrKmhbexCHg3A6Z6MU0W9GHnJwBQNBeyhCJG9KDce4SAMdicQnpURggSvtbGo9xAWOfSvIQ==",
+            "version": "4.8.0",
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.8.0.tgz",
+            "integrity": "sha512-mdxnlW2QUzXwY+95TuxZ+CurrhgrPAMveDWI97EQlA9bfhR8tw3Pt7SUlc/eSlCNxlWktpmT//EAA8UfCHOyXg==",
             "cpu": [
                 "x64"
             ],
@@ -5497,9 +5516,9 @@
             ]
         },
         "node_modules/@rollup/rollup-win32-arm64-msvc": {
-            "version": "4.6.1",
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.6.1.tgz",
-            "integrity": "sha512-v2FVT6xfnnmTe3W9bJXl6r5KwJglMK/iRlkKiIFfO6ysKs0rDgz7Cwwf3tjldxQUrHL9INT/1r4VA0n9L/F1vQ==",
+            "version": "4.8.0",
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.8.0.tgz",
+            "integrity": "sha512-ge7saUz38aesM4MA7Cad8CHo0Fyd1+qTaqoIo+Jtk+ipBi4ATSrHWov9/S4u5pbEQmLjgUjB7BJt+MiKG2kzmA==",
             "cpu": [
                 "arm64"
             ],
@@ -5510,9 +5529,9 @@
             ]
         },
         "node_modules/@rollup/rollup-win32-ia32-msvc": {
-            "version": "4.6.1",
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.6.1.tgz",
-            "integrity": "sha512-YEeOjxRyEjqcWphH9dyLbzgkF8wZSKAKUkldRY6dgNR5oKs2LZazqGB41cWJ4Iqqcy9/zqYgmzBkRoVz3Q9MLw==",
+            "version": "4.8.0",
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.8.0.tgz",
+            "integrity": "sha512-p9E3PZlzurhlsN5h9g7zIP1DnqKXJe8ZUkFwAazqSvHuWfihlIISPxG9hCHCoA+dOOspL/c7ty1eeEVFTE0UTw==",
             "cpu": [
                 "ia32"
             ],
@@ -5523,9 +5542,9 @@
             ]
         },
         "node_modules/@rollup/rollup-win32-x64-msvc": {
-            "version": "4.6.1",
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.6.1.tgz",
-            "integrity": "sha512-0zfTlFAIhgz8V2G8STq8toAjsYYA6eci1hnXuyOTUFnymrtJwnS6uGKiv3v5UrPZkBlamLvrLV2iiaeqCKzb0A==",
+            "version": "4.8.0",
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.8.0.tgz",
+            "integrity": "sha512-kb4/auKXkYKqlUYTE8s40FcJIj5soOyRLHKd4ugR0dCq0G2EfcF54eYcfQiGkHzjidZ40daB4ulsFdtqNKZtBg==",
             "cpu": [
                 "x64"
             ],
@@ -5536,9 +5555,9 @@
             ]
         },
         "node_modules/@rushstack/node-core-library": {
-            "version": "3.61.0",
-            "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-3.61.0.tgz",
-            "integrity": "sha512-tdOjdErme+/YOu4gPed3sFS72GhtWCgNV9oDsHDnoLY5oDfwjKUc9Z+JOZZ37uAxcm/OCahDHfuu2ugqrfWAVQ==",
+            "version": "3.62.0",
+            "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-3.62.0.tgz",
+            "integrity": "sha512-88aJn2h8UpSvdwuDXBv1/v1heM6GnBf3RjEy6ZPP7UnzHNCqOHA2Ut+ScYUbXcqIdfew9JlTAe3g+cnX9xQ/Aw==",
             "dev": true,
             "dependencies": {
                 "colors": "~1.2.1",
@@ -6073,21 +6092,6 @@
             "integrity": "sha512-0WR3b8eaISjEW7RpZnclONaLFDf7buaowRHdqLp4vLj54AsSAYWfh3DRbfiYJY9XDxMgx1B4sE1Afw2PGpuHOA==",
             "dev": true
         },
-        "node_modules/@types/chai": {
-            "version": "4.3.11",
-            "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.11.tgz",
-            "integrity": "sha512-qQR1dr2rGIHYlJulmr8Ioq3De0Le9E4MJ5AiaeAETJJpndT1uUNHsGFK3L/UIu+rbkQSdj8J/w2bCsBZc/Y5fQ==",
-            "dev": true
-        },
-        "node_modules/@types/chai-subset": {
-            "version": "1.3.5",
-            "resolved": "https://registry.npmjs.org/@types/chai-subset/-/chai-subset-1.3.5.tgz",
-            "integrity": "sha512-c2mPnw+xHtXDoHmdtcCXGwyLMiauiAyxWMzhGpqHC4nqI/Y5G2XhTampslK2rb59kpcuHon03UH8W6iYUzw88A==",
-            "dev": true,
-            "dependencies": {
-                "@types/chai": "*"
-            }
-        },
         "node_modules/@types/cli-progress": {
             "version": "3.11.5",
             "resolved": "https://registry.npmjs.org/@types/cli-progress/-/cli-progress-3.11.5.tgz",
@@ -6567,38 +6571,40 @@
             "dev": true
         },
         "node_modules/@vitest/coverage-v8": {
-            "version": "0.34.6",
-            "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-0.34.6.tgz",
-            "integrity": "sha512-fivy/OK2d/EsJFoEoxHFEnNGTg+MmdZBAVK9Ka4qhXR2K3J0DS08vcGVwzDtXSuUMabLv4KtPcpSKkcMXFDViw==",
+            "version": "1.0.4",
+            "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-1.0.4.tgz",
+            "integrity": "sha512-xD6Yuql6RW0Ir/JJIs6rVrmnG2/KOWJF+IRX1oJQk5wGKGxbtdrYPbl+WTUn/4ICCQ2G20zbE1e8/nPNyAG5Vg==",
             "dev": true,
             "dependencies": {
                 "@ampproject/remapping": "^2.2.1",
                 "@bcoe/v8-coverage": "^0.2.3",
-                "istanbul-lib-coverage": "^3.2.0",
+                "debug": "^4.3.4",
+                "istanbul-lib-coverage": "^3.2.2",
                 "istanbul-lib-report": "^3.0.1",
                 "istanbul-lib-source-maps": "^4.0.1",
-                "istanbul-reports": "^3.1.5",
-                "magic-string": "^0.30.1",
+                "istanbul-reports": "^3.1.6",
+                "magic-string": "^0.30.5",
+                "magicast": "^0.3.2",
                 "picocolors": "^1.0.0",
-                "std-env": "^3.3.3",
+                "std-env": "^3.5.0",
                 "test-exclude": "^6.0.0",
-                "v8-to-istanbul": "^9.1.0"
+                "v8-to-istanbul": "^9.2.0"
             },
             "funding": {
                 "url": "https://opencollective.com/vitest"
             },
             "peerDependencies": {
-                "vitest": ">=0.32.0 <1"
+                "vitest": "^1.0.0"
             }
         },
         "node_modules/@vitest/expect": {
-            "version": "0.34.6",
-            "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-0.34.6.tgz",
-            "integrity": "sha512-QUzKpUQRc1qC7qdGo7rMK3AkETI7w18gTCUrsNnyjjJKYiuUB9+TQK3QnR1unhCnWRC0AbKv2omLGQDF/mIjOw==",
+            "version": "1.0.4",
+            "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-1.0.4.tgz",
+            "integrity": "sha512-/NRN9N88qjg3dkhmFcCBwhn/Ie4h064pY3iv7WLRsDJW7dXnEgeoa8W9zy7gIPluhz6CkgqiB3HmpIXgmEY5dQ==",
             "dev": true,
             "dependencies": {
-                "@vitest/spy": "0.34.6",
-                "@vitest/utils": "0.34.6",
+                "@vitest/spy": "1.0.4",
+                "@vitest/utils": "1.0.4",
                 "chai": "^4.3.10"
             },
             "funding": {
@@ -6606,13 +6612,13 @@
             }
         },
         "node_modules/@vitest/runner": {
-            "version": "0.34.6",
-            "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-0.34.6.tgz",
-            "integrity": "sha512-1CUQgtJSLF47NnhN+F9X2ycxUP0kLHQ/JWvNHbeBfwW8CzEGgeskzNnHDyv1ieKTltuR6sdIHV+nmR6kPxQqzQ==",
+            "version": "1.0.4",
+            "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-1.0.4.tgz",
+            "integrity": "sha512-rhOQ9FZTEkV41JWXozFM8YgOqaG9zA7QXbhg5gy6mFOVqh4PcupirIJ+wN7QjeJt8S8nJRYuZH1OjJjsbxAXTQ==",
             "dev": true,
             "dependencies": {
-                "@vitest/utils": "0.34.6",
-                "p-limit": "^4.0.0",
+                "@vitest/utils": "1.0.4",
+                "p-limit": "^5.0.0",
                 "pathe": "^1.1.1"
             },
             "funding": {
@@ -6620,15 +6626,15 @@
             }
         },
         "node_modules/@vitest/runner/node_modules/p-limit": {
-            "version": "4.0.0",
-            "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz",
-            "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==",
+            "version": "5.0.0",
+            "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-5.0.0.tgz",
+            "integrity": "sha512-/Eaoq+QyLSiXQ4lyYV23f14mZRQcXnxfHrN0vCai+ak9G0pp9iEQukIIZq5NccEvwRB8PUnZT0KsOoDCINS1qQ==",
             "dev": true,
             "dependencies": {
                 "yocto-queue": "^1.0.0"
             },
             "engines": {
-                "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+                "node": ">=18"
             },
             "funding": {
                 "url": "https://github.com/sponsors/sindresorhus"
@@ -6647,14 +6653,14 @@
             }
         },
         "node_modules/@vitest/snapshot": {
-            "version": "0.34.6",
-            "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-0.34.6.tgz",
-            "integrity": "sha512-B3OZqYn6k4VaN011D+ve+AA4whM4QkcwcrwaKwAbyyvS/NB1hCWjFIBQxAQQSQir9/RtyAAGuq+4RJmbn2dH4w==",
+            "version": "1.0.4",
+            "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-1.0.4.tgz",
+            "integrity": "sha512-vkfXUrNyNRA/Gzsp2lpyJxh94vU2OHT1amoD6WuvUAA12n32xeVZQ0KjjQIf8F6u7bcq2A2k969fMVxEsxeKYA==",
             "dev": true,
             "dependencies": {
-                "magic-string": "^0.30.1",
+                "magic-string": "^0.30.5",
                 "pathe": "^1.1.1",
-                "pretty-format": "^29.5.0"
+                "pretty-format": "^29.7.0"
             },
             "funding": {
                 "url": "https://opencollective.com/vitest"
@@ -6693,27 +6699,27 @@
             "dev": true
         },
         "node_modules/@vitest/spy": {
-            "version": "0.34.6",
-            "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-0.34.6.tgz",
-            "integrity": "sha512-xaCvneSaeBw/cz8ySmF7ZwGvL0lBjfvqc1LpQ/vcdHEvpLn3Ff1vAvjw+CoGn0802l++5L/pxb7whwcWAw+DUQ==",
+            "version": "1.0.4",
+            "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-1.0.4.tgz",
+            "integrity": "sha512-9ojTFRL1AJVh0hvfzAQpm0QS6xIS+1HFIw94kl/1ucTfGCaj1LV/iuJU4Y6cdR03EzPDygxTHwE1JOm+5RCcvA==",
             "dev": true,
             "dependencies": {
-                "tinyspy": "^2.1.1"
+                "tinyspy": "^2.2.0"
             },
             "funding": {
                 "url": "https://opencollective.com/vitest"
             }
         },
         "node_modules/@vitest/ui": {
-            "version": "0.34.6",
-            "resolved": "https://registry.npmjs.org/@vitest/ui/-/ui-0.34.6.tgz",
-            "integrity": "sha512-/fxnCwGC0Txmr3tF3BwAbo3v6U2SkBTGR9UB8zo0Ztlx0BTOXHucE0gDHY7SjwEktCOHatiGmli9kZD6gYSoWQ==",
+            "version": "1.0.4",
+            "resolved": "https://registry.npmjs.org/@vitest/ui/-/ui-1.0.4.tgz",
+            "integrity": "sha512-gd4p6e7pjukSe4joWS5wpnm/JcEfzCZUYkYWQOORqJK1mDJ0MOaXa/9BbPOEVO5TcvdnKvFJUdJpFHnqoyYwZA==",
             "dev": true,
             "dependencies": {
-                "@vitest/utils": "0.34.6",
-                "fast-glob": "^3.3.0",
-                "fflate": "^0.8.0",
-                "flatted": "^3.2.7",
+                "@vitest/utils": "1.0.4",
+                "fast-glob": "^3.3.2",
+                "fflate": "^0.8.1",
+                "flatted": "^3.2.9",
                 "pathe": "^1.1.1",
                 "picocolors": "^1.0.0",
                 "sirv": "^2.0.3"
@@ -6722,18 +6728,18 @@
                 "url": "https://opencollective.com/vitest"
             },
             "peerDependencies": {
-                "vitest": ">=0.30.1 <1"
+                "vitest": "^1.0.0"
             }
         },
         "node_modules/@vitest/utils": {
-            "version": "0.34.6",
-            "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-0.34.6.tgz",
-            "integrity": "sha512-IG5aDD8S6zlvloDsnzHw0Ut5xczlF+kv2BOTo+iXfPr54Yhi5qbVOgGB1hZaVq4iJ4C/MZ2J0y15IlsV/ZcI0A==",
+            "version": "1.0.4",
+            "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-1.0.4.tgz",
+            "integrity": "sha512-gsswWDXxtt0QvtK/y/LWukN7sGMYmnCcv1qv05CsY6cU/Y1zpGX1QuvLs+GO1inczpE6Owixeel3ShkjhYtGfA==",
             "dev": true,
             "dependencies": {
-                "diff-sequences": "^29.4.3",
-                "loupe": "^2.3.6",
-                "pretty-format": "^29.5.0"
+                "diff-sequences": "^29.6.3",
+                "loupe": "^2.3.7",
+                "pretty-format": "^29.7.0"
             },
             "funding": {
                 "url": "https://opencollective.com/vitest"
@@ -6800,13 +6806,13 @@
             }
         },
         "node_modules/@vue/compiler-core": {
-            "version": "3.3.9",
-            "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.3.9.tgz",
-            "integrity": "sha512-+/Lf68Vr/nFBA6ol4xOtJrW+BQWv3QWKfRwGSm70jtXwfhZNF4R/eRgyVJYoxFRhdCTk/F6g99BP0ffPgZihfQ==",
+            "version": "3.3.11",
+            "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.3.11.tgz",
+            "integrity": "sha512-h97/TGWBilnLuRaj58sxNrsUU66fwdRKLOLQ9N/5iNDfp+DZhYH9Obhe0bXxhedl8fjAgpRANpiZfbgWyruQ0w==",
             "dev": true,
             "dependencies": {
-                "@babel/parser": "^7.23.3",
-                "@vue/shared": "3.3.9",
+                "@babel/parser": "^7.23.5",
+                "@vue/shared": "3.3.11",
                 "estree-walker": "^2.0.2",
                 "source-map-js": "^1.0.2"
             }
@@ -6818,19 +6824,19 @@
             "dev": true
         },
         "node_modules/@vue/compiler-dom": {
-            "version": "3.3.9",
-            "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.3.9.tgz",
-            "integrity": "sha512-nfWubTtLXuT4iBeDSZ5J3m218MjOy42Vp2pmKVuBKo2/BLcrFUX8nCSr/bKRFiJ32R8qbdnnnBgRn9AdU5v0Sg==",
+            "version": "3.3.11",
+            "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.3.11.tgz",
+            "integrity": "sha512-zoAiUIqSKqAJ81WhfPXYmFGwDRuO+loqLxvXmfUdR5fOitPoUiIeFI9cTTyv9MU5O1+ZZglJVTusWzy+wfk5hw==",
             "dev": true,
             "dependencies": {
-                "@vue/compiler-core": "3.3.9",
-                "@vue/shared": "3.3.9"
+                "@vue/compiler-core": "3.3.11",
+                "@vue/shared": "3.3.11"
             }
         },
         "node_modules/@vue/language-core": {
-            "version": "1.8.24",
-            "resolved": "https://registry.npmjs.org/@vue/language-core/-/language-core-1.8.24.tgz",
-            "integrity": "sha512-2ClHvij0WlsDWryPzXJCSpPc6rusZFNoVtRZGgGGkKCmKuIREDDKmH8j+1tYyxPYyH0qL6pZ6+IHD8KIm5nWAw==",
+            "version": "1.8.25",
+            "resolved": "https://registry.npmjs.org/@vue/language-core/-/language-core-1.8.25.tgz",
+            "integrity": "sha512-NJk/5DnAZlpvXX8BdWmHI45bWGLViUaS3R/RMrmFSvFMSbJKuEODpM4kR0F0Ofv5SFzCWuNiMhxameWpVdQsnA==",
             "dev": true,
             "dependencies": {
                 "@volar/language-core": "~1.11.1",
@@ -6877,9 +6883,9 @@
             }
         },
         "node_modules/@vue/shared": {
-            "version": "3.3.9",
-            "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.3.9.tgz",
-            "integrity": "sha512-ZE0VTIR0LmYgeyhurPTpy4KzKsuDyQbMSdM49eKkMnT5X4VfFBLysMzjIZhLEFQYjjOVVfbvUDHckwjDFiO2eA==",
+            "version": "3.3.11",
+            "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.3.11.tgz",
+            "integrity": "sha512-u2G8ZQ9IhMWTMXaWqZycnK4UthG1fA238CD+DP4Dm4WJi5hdUKKLg0RMRaRpDPNMdkTwIDkp7WtD0Rd9BH9fLw==",
             "dev": true
         },
         "node_modules/@wooorm/starry-night": {
@@ -6974,9 +6980,9 @@
             }
         },
         "node_modules/acorn-walk": {
-            "version": "8.3.0",
-            "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.0.tgz",
-            "integrity": "sha512-FS7hV565M5l1R08MXqo8odwMTB02C2UqzB17RVgu9EyuYFBqJZ3/ZY97sQD5FewVu1UyDFc1yztUDrAwT0EypA==",
+            "version": "8.3.1",
+            "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.1.tgz",
+            "integrity": "sha512-TgUZgYvqZprrl7YldZNoa9OciCAyZR+Ejm9eXzKCmjsF5IKp/wgQ7Z/ZpjpGTIUPwrHQIcYeI8qDh4PsEwxMbw==",
             "dev": true,
             "engines": {
                 "node": ">=0.4.0"
@@ -7767,9 +7773,9 @@
         },
         "node_modules/braces": {
             "name": "@clevercanyon/braces.fork",
-            "version": "3.0.71",
-            "resolved": "https://registry.npmjs.org/@clevercanyon/braces.fork/-/braces.fork-3.0.71.tgz",
-            "integrity": "sha512-Y0y8dOv5JLHy/AnUW/XEt8gQJplmUK0d0W08kjQaQK6Ca0FdjshYTpN51e79GzSg5WrntXqGx4VT9CWGnpHKag==",
+            "version": "3.0.73",
+            "resolved": "https://registry.npmjs.org/@clevercanyon/braces.fork/-/braces.fork-3.0.73.tgz",
+            "integrity": "sha512-YnzhOn/uL8EBN5e6UvlI7zgxMmm0igFAlaXkRPP9LKbHsiX7veKvFTtBEHXlG2N5E3X5VCDhNkdaStYVGnkeaw==",
             "cpu": [
                 "x64",
                 "arm64"
@@ -7779,7 +7785,7 @@
                 "linux"
             ],
             "dependencies": {
-                "fill-range": "npm:@clevercanyon/fill-range.fork@^7.0.69"
+                "fill-range": "npm:@clevercanyon/fill-range.fork@^7.0.70"
             },
             "engines": {
                 "node": "^20.5.0 || ^20.9.0",
@@ -8037,9 +8043,9 @@
             }
         },
         "node_modules/caniuse-lite": {
-            "version": "1.0.30001565",
-            "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001565.tgz",
-            "integrity": "sha512-xrE//a3O7TP0vaJ8ikzkD2c2NgcVUvsEe2IvFTntV4Yd1Z9FVzh+gW+enX96L0psrbaFMcVcH2l90xNuGDWc8w==",
+            "version": "1.0.30001568",
+            "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001568.tgz",
+            "integrity": "sha512-vSUkH84HontZJ88MiNrOau1EBrCqEQYgkC5gIySiDlpsm8sGVrhU7Kx4V6h0tnqaHzIHZv08HlJIwPbL4XL9+A==",
             "dev": true,
             "funding": [
                 {
@@ -8908,9 +8914,9 @@
             }
         },
         "node_modules/cssdb": {
-            "version": "7.9.0",
-            "resolved": "https://registry.npmjs.org/cssdb/-/cssdb-7.9.0.tgz",
-            "integrity": "sha512-WPMT9seTQq6fPAa1yN4zjgZZeoTriSN2LqW9C+otjar12DQIWA4LuSfFrvFJiKp4oD0xIk1vumDLw8K9ur4NBw==",
+            "version": "7.9.1",
+            "resolved": "https://registry.npmjs.org/cssdb/-/cssdb-7.9.1.tgz",
+            "integrity": "sha512-fqy6ZnNfpb8qAvTT0qijWyTsUmYThsDX2F2ctMG4ceI7mI4DtsMILSiMBiuuDnVIYTyWvCctdp9Nb08p/6m2SQ==",
             "dev": true,
             "funding": [
                 {
@@ -8947,6 +8953,12 @@
                 "node": ">=14"
             }
         },
+        "node_modules/cuint": {
+            "version": "0.2.2",
+            "resolved": "https://registry.npmjs.org/cuint/-/cuint-0.2.2.tgz",
+            "integrity": "sha512-d4ZVpCW31eWwCMe1YT3ur7mUDnTXbgwyzaL320DrcRT45rfjYxkt5QWLrmOJ+/UEAI2+fQgKe/fCjR8l4TpRgw==",
+            "dev": true
+        },
         "node_modules/damerau-levenshtein": {
             "version": "1.0.8",
             "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz",
@@ -9581,9 +9593,9 @@
             }
         },
         "node_modules/electron-to-chromium": {
-            "version": "1.4.601",
-            "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.601.tgz",
-            "integrity": "sha512-SpwUMDWe9tQu8JX5QCO1+p/hChAi9AE9UpoC3rcHVc+gdCGlbT3SGb5I1klgb952HRIyvt9wZhSz9bNBYz9swA==",
+            "version": "1.4.610",
+            "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.610.tgz",
+            "integrity": "sha512-mqi2oL1mfeHYtOdCxbPQYV/PL7YrQlxbvFEZ0Ee8GbDdShimqt2/S6z2RWqysuvlwdOrQdqvE0KZrBTipAeJzg==",
             "dev": true
         },
         "node_modules/emittery": {
@@ -9776,9 +9788,9 @@
             "dev": true
         },
         "node_modules/esbuild": {
-            "version": "0.19.8",
-            "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.8.tgz",
-            "integrity": "sha512-l7iffQpT2OrZfH2rXIp7/FkmaeZM0vxbxN9KfiCwGYuZqzMg/JdvX26R31Zxn/Pxvsrg3Y9N6XTcnknqDyyv4w==",
+            "version": "0.19.9",
+            "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.9.tgz",
+            "integrity": "sha512-U9CHtKSy+EpPsEBa+/A2gMs/h3ylBC0H0KSqIg7tpztHerLi6nrrcoUJAkNCEPumx8yJ+Byic4BVwHgRbN0TBg==",
             "dev": true,
             "hasInstallScript": true,
             "bin": {
@@ -9788,28 +9800,28 @@
                 "node": ">=12"
             },
             "optionalDependencies": {
-                "@esbuild/android-arm": "0.19.8",
-                "@esbuild/android-arm64": "0.19.8",
-                "@esbuild/android-x64": "0.19.8",
-                "@esbuild/darwin-arm64": "0.19.8",
-                "@esbuild/darwin-x64": "0.19.8",
-                "@esbuild/freebsd-arm64": "0.19.8",
-                "@esbuild/freebsd-x64": "0.19.8",
-                "@esbuild/linux-arm": "0.19.8",
-                "@esbuild/linux-arm64": "0.19.8",
-                "@esbuild/linux-ia32": "0.19.8",
-                "@esbuild/linux-loong64": "0.19.8",
-                "@esbuild/linux-mips64el": "0.19.8",
-                "@esbuild/linux-ppc64": "0.19.8",
-                "@esbuild/linux-riscv64": "0.19.8",
-                "@esbuild/linux-s390x": "0.19.8",
-                "@esbuild/linux-x64": "0.19.8",
-                "@esbuild/netbsd-x64": "0.19.8",
-                "@esbuild/openbsd-x64": "0.19.8",
-                "@esbuild/sunos-x64": "0.19.8",
-                "@esbuild/win32-arm64": "0.19.8",
-                "@esbuild/win32-ia32": "0.19.8",
-                "@esbuild/win32-x64": "0.19.8"
+                "@esbuild/android-arm": "0.19.9",
+                "@esbuild/android-arm64": "0.19.9",
+                "@esbuild/android-x64": "0.19.9",
+                "@esbuild/darwin-arm64": "0.19.9",
+                "@esbuild/darwin-x64": "0.19.9",
+                "@esbuild/freebsd-arm64": "0.19.9",
+                "@esbuild/freebsd-x64": "0.19.9",
+                "@esbuild/linux-arm": "0.19.9",
+                "@esbuild/linux-arm64": "0.19.9",
+                "@esbuild/linux-ia32": "0.19.9",
+                "@esbuild/linux-loong64": "0.19.9",
+                "@esbuild/linux-mips64el": "0.19.9",
+                "@esbuild/linux-ppc64": "0.19.9",
+                "@esbuild/linux-riscv64": "0.19.9",
+                "@esbuild/linux-s390x": "0.19.9",
+                "@esbuild/linux-x64": "0.19.9",
+                "@esbuild/netbsd-x64": "0.19.9",
+                "@esbuild/openbsd-x64": "0.19.9",
+                "@esbuild/sunos-x64": "0.19.9",
+                "@esbuild/win32-arm64": "0.19.9",
+                "@esbuild/win32-ia32": "0.19.9",
+                "@esbuild/win32-x64": "0.19.9"
             }
         },
         "node_modules/escalade": {
@@ -12715,9 +12727,9 @@
         },
         "node_modules/fill-range": {
             "name": "@clevercanyon/fill-range.fork",
-            "version": "7.0.70",
-            "resolved": "https://registry.npmjs.org/@clevercanyon/fill-range.fork/-/fill-range.fork-7.0.70.tgz",
-            "integrity": "sha512-jJxuUuA6hhNDiGzhvj9uFTHYsPazpCjTw7dAAof1cH4wE3xc6664Lu8aazkgQCTv3gmathzOTNbKPmtdbfcByA==",
+            "version": "7.0.72",
+            "resolved": "https://registry.npmjs.org/@clevercanyon/fill-range.fork/-/fill-range.fork-7.0.72.tgz",
+            "integrity": "sha512-rJqWLyEVt1A5Hwm63YwHVh8+mIzEO0YeoI0a9FQGrUvg5msoenkkIPFbwBwogzhq2GzFkm1APVyiS5mMnTM4sg==",
             "cpu": [
                 "x64",
                 "arm64"
@@ -12727,7 +12739,7 @@
                 "linux"
             ],
             "dependencies": {
-                "to-regex-range": "npm:@clevercanyon/to-regex-range.fork@^5.0.69"
+                "to-regex-range": "npm:@clevercanyon/to-regex-range.fork@^5.0.70"
             },
             "engines": {
                 "node": "^20.5.0 || ^20.9.0",
@@ -13065,6 +13077,18 @@
                 "url": "https://github.com/sponsors/ljharb"
             }
         },
+        "node_modules/get-tsconfig": {
+            "version": "4.7.2",
+            "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.2.tgz",
+            "integrity": "sha512-wuMsz4leaj5hbGgg4IvDU0bqJagpftG5l5cXIAvo8uZrqn0NJqwtfupTN00VnkQJPcIRrxYrm1Ue24btpCha2A==",
+            "dev": true,
+            "dependencies": {
+                "resolve-pkg-maps": "^1.0.0"
+            },
+            "funding": {
+                "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1"
+            }
+        },
         "node_modules/github-slugger": {
             "version": "2.0.0",
             "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-2.0.0.tgz",
@@ -14321,9 +14345,9 @@
         },
         "node_modules/is-number": {
             "name": "@clevercanyon/is-number.fork",
-            "version": "7.0.73",
-            "resolved": "https://registry.npmjs.org/@clevercanyon/is-number.fork/-/is-number.fork-7.0.73.tgz",
-            "integrity": "sha512-dvTcWY2YI5q0TNQ9lTa2ntCmwtF1uKI5KHQV2TK6FhnkUyi29IuZglcwRBzW72Ajj//+TNnZyshrL538Ms6zYA==",
+            "version": "7.0.75",
+            "resolved": "https://registry.npmjs.org/@clevercanyon/is-number.fork/-/is-number.fork-7.0.75.tgz",
+            "integrity": "sha512-7XNOk7miX+E7FCrGZhQ6HQxn8vPjnStQjQKOdWTSdBZN4tUjZX4Uf2v/AHiRE5acAPQA1HR0AhnM84UGhzr+jg==",
             "cpu": [
                 "x64",
                 "arm64"
@@ -16866,6 +16890,17 @@
                 "node": ">=12"
             }
         },
+        "node_modules/magicast": {
+            "version": "0.3.2",
+            "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.3.2.tgz",
+            "integrity": "sha512-Fjwkl6a0syt9TFN0JSYpOybxiMCkYNEeOTnOTNRbjphirLakznZXAqrXgj/7GG3D1dvETONNwrBfinvAbpunDg==",
+            "dev": true,
+            "dependencies": {
+                "@babel/parser": "^7.23.3",
+                "@babel/types": "^7.23.3",
+                "source-map-js": "^1.0.2"
+            }
+        },
         "node_modules/make-dir": {
             "version": "4.0.0",
             "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz",
@@ -20052,9 +20087,9 @@
         },
         "node_modules/micromatch": {
             "name": "@clevercanyon/micromatch.fork",
-            "version": "4.0.75",
-            "resolved": "https://registry.npmjs.org/@clevercanyon/micromatch.fork/-/micromatch.fork-4.0.75.tgz",
-            "integrity": "sha512-+1ge1hDB0bR8ac073CHsTq0Y7781mpPO46+OC5oRqD9uNNz1QhGuYIrC/AzU44xglJsUpJw/DpRe/mokpg1sug==",
+            "version": "4.0.77",
+            "resolved": "https://registry.npmjs.org/@clevercanyon/micromatch.fork/-/micromatch.fork-4.0.77.tgz",
+            "integrity": "sha512-M0s/lHLrSIePFcBdjNqr91btuXTt9LVkA1Rs6YbDTb/ska45Z07MHtUlc0Gc6PCU6eu7dE5cNhcF4LWy+2eueQ==",
             "cpu": [
                 "x64",
                 "arm64"
@@ -20065,8 +20100,8 @@
                 "linux"
             ],
             "dependencies": {
-                "braces": "npm:@clevercanyon/braces.fork@^3.0.70",
-                "picomatch": "npm:@clevercanyon/picomatch.fork@^2.3.69"
+                "braces": "npm:@clevercanyon/braces.fork@^3.0.71",
+                "picomatch": "npm:@clevercanyon/picomatch.fork@^2.3.70"
             },
             "engines": {
                 "node": "^20.5.0 || ^20.9.0",
@@ -20131,9 +20166,9 @@
             }
         },
         "node_modules/miniflare": {
-            "version": "3.20231030.2",
-            "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-3.20231030.2.tgz",
-            "integrity": "sha512-+DYdMqWlUaY4wBylIjewNu8OVsPFquYjQkxoSb2jGIMBmlKaef65Hn2Bu8sub5tQzQ8tLO0FRklmD2Upx0HCCQ==",
+            "version": "3.20231030.3",
+            "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-3.20231030.3.tgz",
+            "integrity": "sha512-lquHSh0XiO8uoWDujOLHtDS9mkUTJTc5C5amiQ6A++5y0f+DWiMqbDBvvwjlYf4Dvqk6ChFya9dztk7fg2ZVxA==",
             "dev": true,
             "dependencies": {
                 "acorn": "^8.8.0",
@@ -21261,9 +21296,9 @@
         },
         "node_modules/picomatch": {
             "name": "@clevercanyon/picomatch.fork",
-            "version": "2.3.70",
-            "resolved": "https://registry.npmjs.org/@clevercanyon/picomatch.fork/-/picomatch.fork-2.3.70.tgz",
-            "integrity": "sha512-7Oif0cQ3ZSH7O0g/2r60rLDNeM6y3a9EQZEtFCiGuKpkfXU1rQpT79a4fcegWcl9vcw6V8zFggau+Dx9XJ8ImQ==",
+            "version": "2.3.72",
+            "resolved": "https://registry.npmjs.org/@clevercanyon/picomatch.fork/-/picomatch.fork-2.3.72.tgz",
+            "integrity": "sha512-hxuFrzaIhJYFNwV1/Qj1XJpo0lUx6kvPfkJnoHxuteMab+zHERp8DPX56sxck7X1Mv4mxdy08sssgh0UNiu81g==",
             "cpu": [
                 "x64",
                 "arm64"
@@ -21407,9 +21442,9 @@
             }
         },
         "node_modules/postcss": {
-            "version": "8.4.31",
-            "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz",
-            "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==",
+            "version": "8.4.32",
+            "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.32.tgz",
+            "integrity": "sha512-D/kj5JNu6oo2EIy+XL/26JEDTlIbB8hw85G8StOE6L74RQAVVP5rej6wxCNqyMbR4RkPfqvezVbPw81Ngd6Kcw==",
             "dev": true,
             "funding": [
                 {
@@ -21426,7 +21461,7 @@
                 }
             ],
             "dependencies": {
-                "nanoid": "^3.3.6",
+                "nanoid": "^3.3.7",
                 "picocolors": "^1.0.0",
                 "source-map-js": "^1.0.2"
             },
@@ -21970,6 +22005,28 @@
             "integrity": "sha512-3sOlxmbKcSHMjlUXQZKQ06jOswE7oVkXPxmZdoB1r5l0q6gTFTQSHxNxOrCccElbW7dxNytifNEo8qidX2Vsig==",
             "dev": true
         },
+        "node_modules/postcss-mixins": {
+            "version": "9.0.4",
+            "resolved": "https://registry.npmjs.org/postcss-mixins/-/postcss-mixins-9.0.4.tgz",
+            "integrity": "sha512-XVq5jwQJDRu5M1XGkdpgASqLk37OqkH4JCFDXl/Dn7janOJjCTEKL+36cnRVy7bMtoBzALfO7bV7nTIsFnUWLA==",
+            "dev": true,
+            "dependencies": {
+                "fast-glob": "^3.2.11",
+                "postcss-js": "^4.0.0",
+                "postcss-simple-vars": "^7.0.0",
+                "sugarss": "^4.0.1"
+            },
+            "engines": {
+                "node": ">=14.0"
+            },
+            "funding": {
+                "type": "opencollective",
+                "url": "https://opencollective.com/postcss/"
+            },
+            "peerDependencies": {
+                "postcss": "^8.2.14"
+            }
+        },
         "node_modules/postcss-nested": {
             "version": "6.0.1",
             "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.1.tgz",
@@ -22282,19 +22339,29 @@
             "dev": true
         },
         "node_modules/postcss-safe-parser": {
-            "version": "6.0.0",
-            "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-6.0.0.tgz",
-            "integrity": "sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ==",
+            "version": "7.0.0",
+            "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-7.0.0.tgz",
+            "integrity": "sha512-ovehqRNVCpuFzbXoTb4qLtyzK3xn3t/CUBxOs8LsnQjQrShaB4lKiHoVqY8ANaC0hBMHq5QVWk77rwGklFUDrg==",
             "dev": true,
+            "funding": [
+                {
+                    "type": "opencollective",
+                    "url": "https://opencollective.com/postcss/"
+                },
+                {
+                    "type": "tidelift",
+                    "url": "https://tidelift.com/funding/github/npm/postcss-safe-parser"
+                },
+                {
+                    "type": "github",
+                    "url": "https://github.com/sponsors/ai"
+                }
+            ],
             "engines": {
-                "node": ">=12.0"
-            },
-            "funding": {
-                "type": "opencollective",
-                "url": "https://opencollective.com/postcss/"
+                "node": ">=18.0"
             },
             "peerDependencies": {
-                "postcss": "^8.3.3"
+                "postcss": "^8.4.31"
             }
         },
         "node_modules/postcss-scss": {
@@ -22355,6 +22422,22 @@
                 "node": ">=4"
             }
         },
+        "node_modules/postcss-simple-vars": {
+            "version": "7.0.1",
+            "resolved": "https://registry.npmjs.org/postcss-simple-vars/-/postcss-simple-vars-7.0.1.tgz",
+            "integrity": "sha512-5GLLXaS8qmzHMOjVxqkk1TZPf1jMqesiI7qLhnlyERalG0sMbHIbJqrcnrpmZdKCLglHnRHoEBB61RtGTsj++A==",
+            "dev": true,
+            "engines": {
+                "node": ">=14.0"
+            },
+            "funding": {
+                "type": "opencollective",
+                "url": "https://opencollective.com/postcss/"
+            },
+            "peerDependencies": {
+                "postcss": "^8.2.1"
+            }
+        },
         "node_modules/postcss-sorting": {
             "version": "8.0.2",
             "resolved": "https://registry.npmjs.org/postcss-sorting/-/postcss-sorting-8.0.2.tgz",
@@ -22364,6 +22447,72 @@
                 "postcss": "^8.4.20"
             }
         },
+        "node_modules/postcss-url": {
+            "version": "10.1.3",
+            "resolved": "https://registry.npmjs.org/postcss-url/-/postcss-url-10.1.3.tgz",
+            "integrity": "sha512-FUzyxfI5l2tKmXdYc6VTu3TWZsInayEKPbiyW+P6vmmIrrb4I6CGX0BFoewgYHLK+oIL5FECEK02REYRpBvUCw==",
+            "dev": true,
+            "dependencies": {
+                "make-dir": "~3.1.0",
+                "mime": "~2.5.2",
+                "minimatch": "~3.0.4",
+                "xxhashjs": "~0.2.2"
+            },
+            "engines": {
+                "node": ">=10"
+            },
+            "peerDependencies": {
+                "postcss": "^8.0.0"
+            }
+        },
+        "node_modules/postcss-url/node_modules/make-dir": {
+            "version": "3.1.0",
+            "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
+            "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==",
+            "dev": true,
+            "dependencies": {
+                "semver": "^6.0.0"
+            },
+            "engines": {
+                "node": ">=8"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/sindresorhus"
+            }
+        },
+        "node_modules/postcss-url/node_modules/mime": {
+            "version": "2.5.2",
+            "resolved": "https://registry.npmjs.org/mime/-/mime-2.5.2.tgz",
+            "integrity": "sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg==",
+            "dev": true,
+            "bin": {
+                "mime": "cli.js"
+            },
+            "engines": {
+                "node": ">=4.0.0"
+            }
+        },
+        "node_modules/postcss-url/node_modules/minimatch": {
+            "version": "3.0.8",
+            "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.8.tgz",
+            "integrity": "sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==",
+            "dev": true,
+            "dependencies": {
+                "brace-expansion": "^1.1.7"
+            },
+            "engines": {
+                "node": "*"
+            }
+        },
+        "node_modules/postcss-url/node_modules/semver": {
+            "version": "6.3.1",
+            "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+            "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+            "dev": true,
+            "bin": {
+                "semver": "bin/semver.js"
+            }
+        },
         "node_modules/postcss-value-parser": {
             "version": "4.2.0",
             "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
@@ -26145,6 +26294,15 @@
                 "node": ">=4"
             }
         },
+        "node_modules/resolve-pkg-maps": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz",
+            "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==",
+            "dev": true,
+            "funding": {
+                "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1"
+            }
+        },
         "node_modules/resolve.exports": {
             "version": "2.0.2",
             "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz",
@@ -26616,9 +26774,9 @@
             }
         },
         "node_modules/rollup": {
-            "version": "4.6.1",
-            "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.6.1.tgz",
-            "integrity": "sha512-jZHaZotEHQaHLgKr8JnQiDT1rmatjgKlMekyksz+yk9jt/8z9quNjnKNRoaM0wd9DC2QKXjmWWuDYtM3jfF8pQ==",
+            "version": "4.8.0",
+            "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.8.0.tgz",
+            "integrity": "sha512-NpsklK2fach5CdI+PScmlE5R4Ao/FSWtF7LkoIrHDxPACY/xshNasPsbpG0VVHxUTbf74tJbVT4PrP8JsJ6ZDA==",
             "dev": true,
             "bin": {
                 "rollup": "dist/bin/rollup"
@@ -26628,18 +26786,19 @@
                 "npm": ">=8.0.0"
             },
             "optionalDependencies": {
-                "@rollup/rollup-android-arm-eabi": "4.6.1",
-                "@rollup/rollup-android-arm64": "4.6.1",
-                "@rollup/rollup-darwin-arm64": "4.6.1",
-                "@rollup/rollup-darwin-x64": "4.6.1",
-                "@rollup/rollup-linux-arm-gnueabihf": "4.6.1",
-                "@rollup/rollup-linux-arm64-gnu": "4.6.1",
-                "@rollup/rollup-linux-arm64-musl": "4.6.1",
-                "@rollup/rollup-linux-x64-gnu": "4.6.1",
-                "@rollup/rollup-linux-x64-musl": "4.6.1",
-                "@rollup/rollup-win32-arm64-msvc": "4.6.1",
-                "@rollup/rollup-win32-ia32-msvc": "4.6.1",
-                "@rollup/rollup-win32-x64-msvc": "4.6.1",
+                "@rollup/rollup-android-arm-eabi": "4.8.0",
+                "@rollup/rollup-android-arm64": "4.8.0",
+                "@rollup/rollup-darwin-arm64": "4.8.0",
+                "@rollup/rollup-darwin-x64": "4.8.0",
+                "@rollup/rollup-linux-arm-gnueabihf": "4.8.0",
+                "@rollup/rollup-linux-arm64-gnu": "4.8.0",
+                "@rollup/rollup-linux-arm64-musl": "4.8.0",
+                "@rollup/rollup-linux-riscv64-gnu": "4.8.0",
+                "@rollup/rollup-linux-x64-gnu": "4.8.0",
+                "@rollup/rollup-linux-x64-musl": "4.8.0",
+                "@rollup/rollup-win32-arm64-msvc": "4.8.0",
+                "@rollup/rollup-win32-ia32-msvc": "4.8.0",
+                "@rollup/rollup-win32-x64-msvc": "4.8.0",
                 "fsevents": "~2.3.2"
             }
         },
@@ -27204,9 +27363,9 @@
         },
         "node_modules/spawn-please": {
             "name": "@clevercanyon/spawn-please.fork",
-            "version": "2.0.67",
-            "resolved": "https://registry.npmjs.org/@clevercanyon/spawn-please.fork/-/spawn-please.fork-2.0.67.tgz",
-            "integrity": "sha512-N0SLa0AUMgaxrjSMW0b6SNGuzp/d3Wu0wxO7GwFDDrh8toXQYf8czUXF7LETq3vw6NQcUNcB4REPHC0xO8iesw==",
+            "version": "2.0.69",
+            "resolved": "https://registry.npmjs.org/@clevercanyon/spawn-please.fork/-/spawn-please.fork-2.0.69.tgz",
+            "integrity": "sha512-34CwsIfHmsgtSeErTl491h0Eghkhnzp+IIYLQ9PZuOcT+d4Q+gD1t3f9O9MPM8R8P/6P0yHmPMCCWcHBFC5t7A==",
             "cpu": [
                 "x64",
                 "arm64"
@@ -27355,9 +27514,9 @@
             }
         },
         "node_modules/streamx": {
-            "version": "2.15.5",
-            "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.15.5.tgz",
-            "integrity": "sha512-9thPGMkKC2GctCzyCUjME3yR03x2xNo0GPKGkRw2UMYN+gqWa9uqpyNWhmsNCutU5zHmkUum0LsCRQTXUgUCAg==",
+            "version": "2.15.6",
+            "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.15.6.tgz",
+            "integrity": "sha512-q+vQL4AAz+FdfT137VF69Cc/APqUbxy+MDOImRrMvchJpigHj9GksgDU2LYbO9rx7RX6osWgxJB2WxhYv4SZAw==",
             "dev": true,
             "peer": true,
             "dependencies": {
@@ -27764,16 +27923,16 @@
             }
         },
         "node_modules/stylelint-order": {
-            "version": "6.0.3",
-            "resolved": "https://registry.npmjs.org/stylelint-order/-/stylelint-order-6.0.3.tgz",
-            "integrity": "sha512-1j1lOb4EU/6w49qZeT2SQVJXm0Ht+Qnq9GMfUa3pMwoyojIWfuA+JUDmoR97Bht1RLn4ei0xtLGy87M7d29B1w==",
+            "version": "6.0.4",
+            "resolved": "https://registry.npmjs.org/stylelint-order/-/stylelint-order-6.0.4.tgz",
+            "integrity": "sha512-0UuKo4+s1hgQ/uAxlYU4h0o0HS4NiQDud0NAUNI0aa8FJdmYHA5ZZTFHiV5FpmE3071e9pZx5j0QpVJW5zOCUA==",
             "dev": true,
             "dependencies": {
-                "postcss": "^8.4.21",
+                "postcss": "^8.4.32",
                 "postcss-sorting": "^8.0.2"
             },
             "peerDependencies": {
-                "stylelint": "^14.0.0 || ^15.0.0"
+                "stylelint": "^14.0.0 || ^15.0.0 || ^16.0.1"
             }
         },
         "node_modules/stylelint-scss": {
@@ -27871,6 +28030,22 @@
                 "url": "https://github.com/sponsors/sindresorhus"
             }
         },
+        "node_modules/stylelint/node_modules/postcss-safe-parser": {
+            "version": "6.0.0",
+            "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-6.0.0.tgz",
+            "integrity": "sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ==",
+            "dev": true,
+            "engines": {
+                "node": ">=12.0"
+            },
+            "funding": {
+                "type": "opencollective",
+                "url": "https://opencollective.com/postcss/"
+            },
+            "peerDependencies": {
+                "postcss": "^8.3.3"
+            }
+        },
         "node_modules/stylelint/node_modules/postcss-selector-parser": {
             "version": "6.0.13",
             "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz",
@@ -28017,6 +28192,22 @@
                 "url": "https://github.com/sponsors/isaacs"
             }
         },
+        "node_modules/sugarss": {
+            "version": "4.0.1",
+            "resolved": "https://registry.npmjs.org/sugarss/-/sugarss-4.0.1.tgz",
+            "integrity": "sha512-WCjS5NfuVJjkQzK10s8WOBY+hhDxxNt/N6ZaGwxFZ+wN3/lKKFSaaKUNecULcTTvE4urLcKaZFQD8vO0mOZujw==",
+            "dev": true,
+            "engines": {
+                "node": ">=12.0"
+            },
+            "funding": {
+                "type": "opencollective",
+                "url": "https://opencollective.com/postcss/"
+            },
+            "peerDependencies": {
+                "postcss": "^8.3.3"
+            }
+        },
         "node_modules/supports-color": {
             "version": "8.1.1",
             "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
@@ -28162,9 +28353,9 @@
             }
         },
         "node_modules/tailwindcss": {
-            "version": "3.3.5",
-            "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.3.5.tgz",
-            "integrity": "sha512-5SEZU4J7pxZgSkv7FP1zY8i2TIAOooNZ1e/OGtxIEv6GltpoiXUqWvLy89+a10qYTB1N5Ifkuw9lqQkN9sscvA==",
+            "version": "3.3.6",
+            "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.3.6.tgz",
+            "integrity": "sha512-AKjF7qbbLvLaPieoKeTjG1+FyNZT6KaJMJPFeQyLfIp7l82ggH1fbHJSsYIvnbTFQOlkh+gBYpyby5GT1LIdLw==",
             "dev": true,
             "dependencies": {
                 "@alloc/quick-lru": "^5.2.0",
@@ -28208,9 +28399,9 @@
             }
         },
         "node_modules/tailwindcss-themer": {
-            "version": "3.1.3",
-            "resolved": "https://registry.npmjs.org/tailwindcss-themer/-/tailwindcss-themer-3.1.3.tgz",
-            "integrity": "sha512-P9f0cBXNZ744EdbEdCta56mGsoWWRLyTaek2D2KAhqeIpOoPzDTohh+F3hfPQpM/qw4kVlitptXiwdl0tFgipg==",
+            "version": "4.0.0",
+            "resolved": "https://registry.npmjs.org/tailwindcss-themer/-/tailwindcss-themer-4.0.0.tgz",
+            "integrity": "sha512-kngKDW+z36JtjvaNziX0aesO95r8f5+3FFdANVFDt1uzNHZsL6XLla1YDK6EBAYFqPichoPDbO4lrrTyB+UAbA==",
             "dev": true,
             "dependencies": {
                 "color": "^4.1.0",
@@ -28322,9 +28513,9 @@
             }
         },
         "node_modules/terser": {
-            "version": "5.24.0",
-            "resolved": "https://registry.npmjs.org/terser/-/terser-5.24.0.tgz",
-            "integrity": "sha512-ZpGR4Hy3+wBEzVEnHvstMvqpD/nABNelQn/z2r0fjVWGQsN3bpOLzQlqDxmb4CDZnXq5lpjnQ+mHQLAOpfM5iw==",
+            "version": "5.26.0",
+            "resolved": "https://registry.npmjs.org/terser/-/terser-5.26.0.tgz",
+            "integrity": "sha512-dytTGoE2oHgbNV9nTzgBEPaqAWvcJNl66VZ0BkJqlvp71IjO8CxdBx/ykCNb47cLnCmCvRZ6ZR0tLkqvZCdVBQ==",
             "dev": true,
             "dependencies": {
                 "@jridgewell/source-map": "^0.3.3",
@@ -28432,9 +28623,9 @@
             "dev": true
         },
         "node_modules/tinypool": {
-            "version": "0.7.0",
-            "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.7.0.tgz",
-            "integrity": "sha512-zSYNUlYSMhJ6Zdou4cJwo/p7w5nmAH17GRfU/ui3ctvjXFErXXkruT4MWW6poDeXgCaIBlGLrfU6TbTXxyGMww==",
+            "version": "0.8.1",
+            "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.8.1.tgz",
+            "integrity": "sha512-zBTCK0cCgRROxvs9c0CGK838sPkeokNGdQVUUwHAbynHFlmyJYj825f/oRs528HaIJ97lo0pLIlDUzwN+IorWg==",
             "dev": true,
             "engines": {
                 "node": ">=14.0.0"
@@ -28490,9 +28681,9 @@
         },
         "node_modules/to-regex-range": {
             "name": "@clevercanyon/to-regex-range.fork",
-            "version": "5.0.70",
-            "resolved": "https://registry.npmjs.org/@clevercanyon/to-regex-range.fork/-/to-regex-range.fork-5.0.70.tgz",
-            "integrity": "sha512-yp6JToRvjkDo6ZF2/YCRMjmOD0H45AWSC21Y4ffJSJBCQDvh89O8eWdepzViK8wU6NK5PJoR63VDYRPxfdAJ0Q==",
+            "version": "5.0.72",
+            "resolved": "https://registry.npmjs.org/@clevercanyon/to-regex-range.fork/-/to-regex-range.fork-5.0.72.tgz",
+            "integrity": "sha512-lMZ1sxlh0yYnsqZM+/Ph3Kr0/dZqaDrHoFUU2yxHthofciSQCx1DsDZHvW5ySxykrmrM+M1ICZvDxN/oi12jhw==",
             "cpu": [
                 "x64",
                 "arm64"
@@ -28502,7 +28693,7 @@
                 "linux"
             ],
             "dependencies": {
-                "is-number": "npm:@clevercanyon/is-number.fork@^7.0.72"
+                "is-number": "npm:@clevercanyon/is-number.fork@^7.0.73"
             },
             "engines": {
                 "node": "^20.5.0 || ^20.9.0",
@@ -28665,9 +28856,9 @@
             "dev": true
         },
         "node_modules/ts-node": {
-            "version": "10.9.1",
-            "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz",
-            "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==",
+            "version": "10.9.2",
+            "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz",
+            "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==",
             "dev": true,
             "dependencies": {
                 "@cspotcode/source-map-support": "^0.8.0",
@@ -28749,37 +28940,445 @@
             "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
             "dev": true
         },
-        "node_modules/tunnel-agent": {
-            "version": "0.6.0",
-            "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
-            "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==",
+        "node_modules/tsx": {
+            "version": "4.6.2",
+            "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.6.2.tgz",
+            "integrity": "sha512-QPpBdJo+ZDtqZgAnq86iY/PD2KYCUPSUGIunHdGwyII99GKH+f3z3FZ8XNFLSGQIA4I365ui8wnQpl8OKLqcsg==",
             "dev": true,
             "dependencies": {
-                "safe-buffer": "^5.0.1"
+                "esbuild": "~0.18.20",
+                "get-tsconfig": "^4.7.2"
+            },
+            "bin": {
+                "tsx": "dist/cli.mjs"
             },
             "engines": {
-                "node": "*"
+                "node": ">=18.0.0"
+            },
+            "optionalDependencies": {
+                "fsevents": "~2.3.3"
             }
         },
-        "node_modules/type-check": {
-            "version": "0.4.0",
-            "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
-            "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
+        "node_modules/tsx/node_modules/@esbuild/android-arm": {
+            "version": "0.18.20",
+            "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz",
+            "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==",
+            "cpu": [
+                "arm"
+            ],
             "dev": true,
-            "dependencies": {
-                "prelude-ls": "^1.2.1"
-            },
+            "optional": true,
+            "os": [
+                "android"
+            ],
             "engines": {
-                "node": ">= 0.8.0"
+                "node": ">=12"
             }
         },
-        "node_modules/type-detect": {
-            "version": "4.0.8",
-            "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz",
-            "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==",
+        "node_modules/tsx/node_modules/@esbuild/android-arm64": {
+            "version": "0.18.20",
+            "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz",
+            "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==",
+            "cpu": [
+                "arm64"
+            ],
             "dev": true,
+            "optional": true,
+            "os": [
+                "android"
+            ],
             "engines": {
-                "node": ">=4"
+                "node": ">=12"
+            }
+        },
+        "node_modules/tsx/node_modules/@esbuild/android-x64": {
+            "version": "0.18.20",
+            "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz",
+            "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==",
+            "cpu": [
+                "x64"
+            ],
+            "dev": true,
+            "optional": true,
+            "os": [
+                "android"
+            ],
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/tsx/node_modules/@esbuild/darwin-arm64": {
+            "version": "0.18.20",
+            "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz",
+            "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==",
+            "cpu": [
+                "arm64"
+            ],
+            "dev": true,
+            "optional": true,
+            "os": [
+                "darwin"
+            ],
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/tsx/node_modules/@esbuild/darwin-x64": {
+            "version": "0.18.20",
+            "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz",
+            "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==",
+            "cpu": [
+                "x64"
+            ],
+            "dev": true,
+            "optional": true,
+            "os": [
+                "darwin"
+            ],
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/tsx/node_modules/@esbuild/freebsd-arm64": {
+            "version": "0.18.20",
+            "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz",
+            "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==",
+            "cpu": [
+                "arm64"
+            ],
+            "dev": true,
+            "optional": true,
+            "os": [
+                "freebsd"
+            ],
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/tsx/node_modules/@esbuild/freebsd-x64": {
+            "version": "0.18.20",
+            "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz",
+            "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==",
+            "cpu": [
+                "x64"
+            ],
+            "dev": true,
+            "optional": true,
+            "os": [
+                "freebsd"
+            ],
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/tsx/node_modules/@esbuild/linux-arm": {
+            "version": "0.18.20",
+            "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz",
+            "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==",
+            "cpu": [
+                "arm"
+            ],
+            "dev": true,
+            "optional": true,
+            "os": [
+                "linux"
+            ],
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/tsx/node_modules/@esbuild/linux-arm64": {
+            "version": "0.18.20",
+            "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz",
+            "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==",
+            "cpu": [
+                "arm64"
+            ],
+            "dev": true,
+            "optional": true,
+            "os": [
+                "linux"
+            ],
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/tsx/node_modules/@esbuild/linux-ia32": {
+            "version": "0.18.20",
+            "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz",
+            "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==",
+            "cpu": [
+                "ia32"
+            ],
+            "dev": true,
+            "optional": true,
+            "os": [
+                "linux"
+            ],
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/tsx/node_modules/@esbuild/linux-loong64": {
+            "version": "0.18.20",
+            "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz",
+            "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==",
+            "cpu": [
+                "loong64"
+            ],
+            "dev": true,
+            "optional": true,
+            "os": [
+                "linux"
+            ],
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/tsx/node_modules/@esbuild/linux-mips64el": {
+            "version": "0.18.20",
+            "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz",
+            "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==",
+            "cpu": [
+                "mips64el"
+            ],
+            "dev": true,
+            "optional": true,
+            "os": [
+                "linux"
+            ],
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/tsx/node_modules/@esbuild/linux-ppc64": {
+            "version": "0.18.20",
+            "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz",
+            "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==",
+            "cpu": [
+                "ppc64"
+            ],
+            "dev": true,
+            "optional": true,
+            "os": [
+                "linux"
+            ],
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/tsx/node_modules/@esbuild/linux-riscv64": {
+            "version": "0.18.20",
+            "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz",
+            "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==",
+            "cpu": [
+                "riscv64"
+            ],
+            "dev": true,
+            "optional": true,
+            "os": [
+                "linux"
+            ],
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/tsx/node_modules/@esbuild/linux-s390x": {
+            "version": "0.18.20",
+            "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz",
+            "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==",
+            "cpu": [
+                "s390x"
+            ],
+            "dev": true,
+            "optional": true,
+            "os": [
+                "linux"
+            ],
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/tsx/node_modules/@esbuild/linux-x64": {
+            "version": "0.18.20",
+            "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz",
+            "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==",
+            "cpu": [
+                "x64"
+            ],
+            "dev": true,
+            "optional": true,
+            "os": [
+                "linux"
+            ],
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/tsx/node_modules/@esbuild/netbsd-x64": {
+            "version": "0.18.20",
+            "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz",
+            "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==",
+            "cpu": [
+                "x64"
+            ],
+            "dev": true,
+            "optional": true,
+            "os": [
+                "netbsd"
+            ],
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/tsx/node_modules/@esbuild/openbsd-x64": {
+            "version": "0.18.20",
+            "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz",
+            "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==",
+            "cpu": [
+                "x64"
+            ],
+            "dev": true,
+            "optional": true,
+            "os": [
+                "openbsd"
+            ],
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/tsx/node_modules/@esbuild/sunos-x64": {
+            "version": "0.18.20",
+            "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz",
+            "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==",
+            "cpu": [
+                "x64"
+            ],
+            "dev": true,
+            "optional": true,
+            "os": [
+                "sunos"
+            ],
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/tsx/node_modules/@esbuild/win32-arm64": {
+            "version": "0.18.20",
+            "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz",
+            "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==",
+            "cpu": [
+                "arm64"
+            ],
+            "dev": true,
+            "optional": true,
+            "os": [
+                "win32"
+            ],
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/tsx/node_modules/@esbuild/win32-ia32": {
+            "version": "0.18.20",
+            "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz",
+            "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==",
+            "cpu": [
+                "ia32"
+            ],
+            "dev": true,
+            "optional": true,
+            "os": [
+                "win32"
+            ],
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/tsx/node_modules/@esbuild/win32-x64": {
+            "version": "0.18.20",
+            "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz",
+            "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==",
+            "cpu": [
+                "x64"
+            ],
+            "dev": true,
+            "optional": true,
+            "os": [
+                "win32"
+            ],
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/tsx/node_modules/esbuild": {
+            "version": "0.18.20",
+            "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz",
+            "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==",
+            "dev": true,
+            "hasInstallScript": true,
+            "bin": {
+                "esbuild": "bin/esbuild"
+            },
+            "engines": {
+                "node": ">=12"
+            },
+            "optionalDependencies": {
+                "@esbuild/android-arm": "0.18.20",
+                "@esbuild/android-arm64": "0.18.20",
+                "@esbuild/android-x64": "0.18.20",
+                "@esbuild/darwin-arm64": "0.18.20",
+                "@esbuild/darwin-x64": "0.18.20",
+                "@esbuild/freebsd-arm64": "0.18.20",
+                "@esbuild/freebsd-x64": "0.18.20",
+                "@esbuild/linux-arm": "0.18.20",
+                "@esbuild/linux-arm64": "0.18.20",
+                "@esbuild/linux-ia32": "0.18.20",
+                "@esbuild/linux-loong64": "0.18.20",
+                "@esbuild/linux-mips64el": "0.18.20",
+                "@esbuild/linux-ppc64": "0.18.20",
+                "@esbuild/linux-riscv64": "0.18.20",
+                "@esbuild/linux-s390x": "0.18.20",
+                "@esbuild/linux-x64": "0.18.20",
+                "@esbuild/netbsd-x64": "0.18.20",
+                "@esbuild/openbsd-x64": "0.18.20",
+                "@esbuild/sunos-x64": "0.18.20",
+                "@esbuild/win32-arm64": "0.18.20",
+                "@esbuild/win32-ia32": "0.18.20",
+                "@esbuild/win32-x64": "0.18.20"
+            }
+        },
+        "node_modules/tunnel-agent": {
+            "version": "0.6.0",
+            "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
+            "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==",
+            "dev": true,
+            "dependencies": {
+                "safe-buffer": "^5.0.1"
+            },
+            "engines": {
+                "node": "*"
+            }
+        },
+        "node_modules/type-check": {
+            "version": "0.4.0",
+            "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
+            "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
+            "dev": true,
+            "dependencies": {
+                "prelude-ls": "^1.2.1"
+            },
+            "engines": {
+                "node": ">= 0.8.0"
+            }
+        },
+        "node_modules/type-detect": {
+            "version": "4.0.8",
+            "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz",
+            "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==",
+            "dev": true,
+            "engines": {
+                "node": ">=4"
             }
         },
         "node_modules/type-fest": {
@@ -29950,13 +30549,13 @@
             }
         },
         "node_modules/vite": {
-            "version": "5.0.4",
-            "resolved": "https://registry.npmjs.org/vite/-/vite-5.0.4.tgz",
-            "integrity": "sha512-RzAr8LSvM8lmhB4tQ5OPcBhpjOZRZjuxv9zO5UcxeoY2bd3kP3Ticd40Qma9/BqZ8JS96Ll/jeBX9u+LJZrhVg==",
+            "version": "5.0.7",
+            "resolved": "https://registry.npmjs.org/vite/-/vite-5.0.7.tgz",
+            "integrity": "sha512-B4T4rJCDPihrQo2B+h1MbeGL/k/GMAHzhQ8S0LjQ142s6/+l3hHTT095ORvsshj4QCkoWu3Xtmob5mazvakaOw==",
             "dev": true,
             "dependencies": {
                 "esbuild": "^0.19.3",
-                "postcss": "^8.4.31",
+                "postcss": "^8.4.32",
                 "rollup": "^4.2.0"
             },
             "bin": {
@@ -30005,23 +30604,22 @@
             }
         },
         "node_modules/vite-node": {
-            "version": "0.34.6",
-            "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-0.34.6.tgz",
-            "integrity": "sha512-nlBMJ9x6n7/Amaz6F3zJ97EBwR2FkzhBRxF5e+jE6LA3yi6Wtc2lyTij1OnDMIr34v5g/tVQtsVAzhT0jc5ygA==",
+            "version": "1.0.4",
+            "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-1.0.4.tgz",
+            "integrity": "sha512-9xQQtHdsz5Qn8hqbV7UKqkm8YkJhzT/zr41Dmt5N7AlD8hJXw/Z7y0QiD5I8lnTthV9Rvcvi0QW7PI0Fq83ZPg==",
             "dev": true,
             "dependencies": {
                 "cac": "^6.7.14",
                 "debug": "^4.3.4",
-                "mlly": "^1.4.0",
                 "pathe": "^1.1.1",
                 "picocolors": "^1.0.0",
-                "vite": "^3.0.0 || ^4.0.0 || ^5.0.0-0"
+                "vite": "^5.0.0"
             },
             "bin": {
                 "vite-node": "vite-node.mjs"
             },
             "engines": {
-                "node": ">=v14.18.0"
+                "node": "^18.0.0 || >=20.0.0"
             },
             "funding": {
                 "url": "https://opencollective.com/vitest"
@@ -30078,59 +30676,57 @@
             }
         },
         "node_modules/vitest": {
-            "version": "0.34.6",
-            "resolved": "https://registry.npmjs.org/vitest/-/vitest-0.34.6.tgz",
-            "integrity": "sha512-+5CALsOvbNKnS+ZHMXtuUC7nL8/7F1F2DnHGjSsszX8zCjWSSviphCb/NuS9Nzf4Q03KyyDRBAXhF/8lffME4Q==",
+            "version": "1.0.4",
+            "resolved": "https://registry.npmjs.org/vitest/-/vitest-1.0.4.tgz",
+            "integrity": "sha512-s1GQHp/UOeWEo4+aXDOeFBJwFzL6mjycbQwwKWX2QcYfh/7tIerS59hWQ20mxzupTJluA2SdwiBuWwQHH67ckg==",
             "dev": true,
             "dependencies": {
-                "@types/chai": "^4.3.5",
-                "@types/chai-subset": "^1.3.3",
-                "@types/node": "*",
-                "@vitest/expect": "0.34.6",
-                "@vitest/runner": "0.34.6",
-                "@vitest/snapshot": "0.34.6",
-                "@vitest/spy": "0.34.6",
-                "@vitest/utils": "0.34.6",
-                "acorn": "^8.9.0",
-                "acorn-walk": "^8.2.0",
+                "@vitest/expect": "1.0.4",
+                "@vitest/runner": "1.0.4",
+                "@vitest/snapshot": "1.0.4",
+                "@vitest/spy": "1.0.4",
+                "@vitest/utils": "1.0.4",
+                "acorn-walk": "^8.3.0",
                 "cac": "^6.7.14",
                 "chai": "^4.3.10",
                 "debug": "^4.3.4",
-                "local-pkg": "^0.4.3",
-                "magic-string": "^0.30.1",
+                "execa": "^8.0.1",
+                "local-pkg": "^0.5.0",
+                "magic-string": "^0.30.5",
                 "pathe": "^1.1.1",
                 "picocolors": "^1.0.0",
-                "std-env": "^3.3.3",
-                "strip-literal": "^1.0.1",
-                "tinybench": "^2.5.0",
-                "tinypool": "^0.7.0",
-                "vite": "^3.1.0 || ^4.0.0 || ^5.0.0-0",
-                "vite-node": "0.34.6",
+                "std-env": "^3.5.0",
+                "strip-literal": "^1.3.0",
+                "tinybench": "^2.5.1",
+                "tinypool": "^0.8.1",
+                "vite": "^5.0.0",
+                "vite-node": "1.0.4",
                 "why-is-node-running": "^2.2.2"
             },
             "bin": {
                 "vitest": "vitest.mjs"
             },
             "engines": {
-                "node": ">=v14.18.0"
+                "node": "^18.0.0 || >=20.0.0"
             },
             "funding": {
                 "url": "https://opencollective.com/vitest"
             },
             "peerDependencies": {
                 "@edge-runtime/vm": "*",
-                "@vitest/browser": "*",
-                "@vitest/ui": "*",
+                "@types/node": "^18.0.0 || >=20.0.0",
+                "@vitest/browser": "^1.0.0",
+                "@vitest/ui": "^1.0.0",
                 "happy-dom": "*",
-                "jsdom": "*",
-                "playwright": "*",
-                "safaridriver": "*",
-                "webdriverio": "*"
+                "jsdom": "*"
             },
             "peerDependenciesMeta": {
                 "@edge-runtime/vm": {
                     "optional": true
                 },
+                "@types/node": {
+                    "optional": true
+                },
                 "@vitest/browser": {
                     "optional": true
                 },
@@ -30142,15 +30738,6 @@
                 },
                 "jsdom": {
                     "optional": true
-                },
-                "playwright": {
-                    "optional": true
-                },
-                "safaridriver": {
-                    "optional": true
-                },
-                "webdriverio": {
-                    "optional": true
                 }
             }
         },
@@ -30173,16 +30760,126 @@
                 "vitest": ">=0.23.0"
             }
         },
-        "node_modules/vitest/node_modules/local-pkg": {
-            "version": "0.4.3",
-            "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.4.3.tgz",
-            "integrity": "sha512-SFppqq5p42fe2qcZQqqEOiVRXl+WCP1MdT6k7BDEW1j++sp5fIY+/fdRQitvKgB5BrBcmrs5m/L0v2FrU5MY1g==",
+        "node_modules/vitest/node_modules/execa": {
+            "version": "8.0.1",
+            "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz",
+            "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==",
+            "dev": true,
+            "dependencies": {
+                "cross-spawn": "^7.0.3",
+                "get-stream": "^8.0.1",
+                "human-signals": "^5.0.0",
+                "is-stream": "^3.0.0",
+                "merge-stream": "^2.0.0",
+                "npm-run-path": "^5.1.0",
+                "onetime": "^6.0.0",
+                "signal-exit": "^4.1.0",
+                "strip-final-newline": "^3.0.0"
+            },
+            "engines": {
+                "node": ">=16.17"
+            },
+            "funding": {
+                "url": "https://github.com/sindresorhus/execa?sponsor=1"
+            }
+        },
+        "node_modules/vitest/node_modules/get-stream": {
+            "version": "8.0.1",
+            "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz",
+            "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==",
+            "dev": true,
+            "engines": {
+                "node": ">=16"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/sindresorhus"
+            }
+        },
+        "node_modules/vitest/node_modules/human-signals": {
+            "version": "5.0.0",
+            "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz",
+            "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==",
+            "dev": true,
+            "engines": {
+                "node": ">=16.17.0"
+            }
+        },
+        "node_modules/vitest/node_modules/is-stream": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz",
+            "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==",
+            "dev": true,
+            "engines": {
+                "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/sindresorhus"
+            }
+        },
+        "node_modules/vitest/node_modules/npm-run-path": {
+            "version": "5.1.0",
+            "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.1.0.tgz",
+            "integrity": "sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==",
+            "dev": true,
+            "dependencies": {
+                "path-key": "^4.0.0"
+            },
+            "engines": {
+                "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/sindresorhus"
+            }
+        },
+        "node_modules/vitest/node_modules/onetime": {
+            "version": "6.0.0",
+            "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz",
+            "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==",
+            "dev": true,
+            "dependencies": {
+                "mimic-fn": "^4.0.0"
+            },
+            "engines": {
+                "node": ">=12"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/sindresorhus"
+            }
+        },
+        "node_modules/vitest/node_modules/path-key": {
+            "version": "4.0.0",
+            "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz",
+            "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==",
+            "dev": true,
+            "engines": {
+                "node": ">=12"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/sindresorhus"
+            }
+        },
+        "node_modules/vitest/node_modules/signal-exit": {
+            "version": "4.1.0",
+            "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
+            "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
             "dev": true,
             "engines": {
                 "node": ">=14"
             },
             "funding": {
-                "url": "https://github.com/sponsors/antfu"
+                "url": "https://github.com/sponsors/isaacs"
+            }
+        },
+        "node_modules/vitest/node_modules/strip-final-newline": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz",
+            "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==",
+            "dev": true,
+            "engines": {
+                "node": ">=12"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/sindresorhus"
             }
         },
         "node_modules/vscode-oniguruma": {
@@ -30208,13 +30905,13 @@
             }
         },
         "node_modules/vue-tsc": {
-            "version": "1.8.24",
-            "resolved": "https://registry.npmjs.org/vue-tsc/-/vue-tsc-1.8.24.tgz",
-            "integrity": "sha512-eH1CSj231OzVEY5Hi7wS6ubzyOEwgr5jCptR0Ddf2SitGcaXIsPVDvrprm3eolCdyhDt3WS1Eb2F4fGX9BsUUw==",
+            "version": "1.8.25",
+            "resolved": "https://registry.npmjs.org/vue-tsc/-/vue-tsc-1.8.25.tgz",
+            "integrity": "sha512-lHsRhDc/Y7LINvYhZ3pv4elflFADoEOo67vfClAfF2heVHpHmVquLSjojgCSIwzA4F0Pc4vowT/psXCYcfk+iQ==",
             "dev": true,
             "dependencies": {
                 "@volar/typescript": "~1.11.1",
-                "@vue/language-core": "1.8.24",
+                "@vue/language-core": "1.8.25",
                 "semver": "^7.5.4"
             },
             "bin": {
@@ -30480,9 +31177,9 @@
             }
         },
         "node_modules/wrangler": {
-            "version": "3.18.0",
-            "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-3.18.0.tgz",
-            "integrity": "sha512-3UrmldsD84JDBa7HRZ5ACFr1nH+ZZs+Hth37Iv/mAaW2DiQOGcrevKwn4dofmTQO2qYP01u1vtfVJxLM0mq+1w==",
+            "version": "3.19.0",
+            "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-3.19.0.tgz",
+            "integrity": "sha512-pY7xWqkQn6DJ+1vz9YHz2pCftEmK+JCTj9sqnucp0NZnlUiILDmBWegsjjCLZycgfiA62J213N7NvjLPr2LB8w==",
             "dev": true,
             "dependencies": {
                 "@cloudflare/kv-asset-handler": "^0.2.0",
@@ -30491,7 +31188,7 @@
                 "blake3-wasm": "^2.1.5",
                 "chokidar": "^3.5.3",
                 "esbuild": "0.17.19",
-                "miniflare": "3.20231030.2",
+                "miniflare": "3.20231030.3",
                 "nanoid": "^3.3.3",
                 "path-to-regexp": "^6.2.0",
                 "resolve.exports": "^2.0.2",
@@ -31033,9 +31730,9 @@
             }
         },
         "node_modules/ws": {
-            "version": "8.14.2",
-            "resolved": "https://registry.npmjs.org/ws/-/ws-8.14.2.tgz",
-            "integrity": "sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g==",
+            "version": "8.15.0",
+            "resolved": "https://registry.npmjs.org/ws/-/ws-8.15.0.tgz",
+            "integrity": "sha512-H/Z3H55mrcrgjFwI+5jKavgXvwQLtfPCUEp6pi35VhoB0pfcHnSoyuTzkBEZpzq49g1193CUEwIvmsjcotenYw==",
             "dev": true,
             "engines": {
                 "node": ">=10.0.0"
@@ -31084,6 +31781,15 @@
             "integrity": "sha512-ibF0Or+FivM9lNrg+HGJfVX8WJqgo+kCLDc4vx6xMeTce7Aj+DLttKbxxRR/gNLSAelRc1omAPlJ77N/Jem07A==",
             "dev": true
         },
+        "node_modules/xxhashjs": {
+            "version": "0.2.2",
+            "resolved": "https://registry.npmjs.org/xxhashjs/-/xxhashjs-0.2.2.tgz",
+            "integrity": "sha512-AkTuIuVTET12tpsVIQo+ZU6f/qDmKuRUcjaqR+OIvm+aCBsZ95i7UVY5WJ9TMsSaZ0DA2WxoZ4acu0sPH+OKAw==",
+            "dev": true,
+            "dependencies": {
+                "cuint": "^0.2.2"
+            }
+        },
         "node_modules/y18n": {
             "version": "5.0.8",
             "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
diff --git a/package.json b/package.json
index 2aecbd38..0089514f 100644
--- a/package.json
+++ b/package.json
@@ -3,7 +3,7 @@
     "publishConfig": {
         "access": "public"
     },
-    "version": "4.0.77",
+    "version": "4.0.78",
     "license": "MIT",
     "name": "@clevercanyon/micromatch.fork",
     "description": "Glob matching. A replacement and faster alternative to minimatch and multimatch.",
@@ -35,15 +35,15 @@
     "types": "",
     "typesVersions": {},
     "dependencies": {
-        "braces": "npm:@clevercanyon/braces.fork@^3.0.71",
-        "picomatch": "npm:@clevercanyon/picomatch.fork@^2.3.70"
+        "braces": "npm:@clevercanyon/braces.fork@^3.0.73",
+        "picomatch": "npm:@clevercanyon/picomatch.fork@^2.3.72"
     },
     "peerDependencies": {},
     "peerDependenciesMeta": {},
     "optionalDependencies": {},
     "bundleDependencies": [],
     "devDependencies": {
-        "@clevercanyon/dev-deps": "^1.0.285"
+        "@clevercanyon/dev-deps": "^1.0.296"
     },
     "overrides": {},
     "cpu": ["x64", "arm64"],
diff --git a/tsconfig.json b/tsconfig.json
index 404aebc4..7715fbe4 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -7,7 +7,7 @@
  * @note This entire file will be updated automatically.
  * @note Instead of editing here, please review `./tsconfig.mjs`.
  *
- * Last generated using `./tsconfig.mjs` Dec 3, 2023 10:52 AM UTC.
+ * Last generated using `./tsconfig.mjs` Dec 12, 2023 2:00 AM UTC.
  */
 {
     "include": ["./src/**/*", "./dev-types.d.ts"],
@@ -78,6 +78,7 @@
         "**/Network Trash Folder/**",
         "**/Temporary Items/**",
         "**/.*/**",
+        "!**/.well-known/**",
         "**/*.config.*/**",
         "**/wrangler.*/**",
         "**/tsconfig.*/**",
diff --git a/wrangler.toml b/wrangler.toml
index 7491c197..af730896 100644
--- a/wrangler.toml
+++ b/wrangler.toml
@@ -7,11 +7,10 @@
 # @note This entire file will be updated automatically.
 # @note Instead of editing here, please review `./wrangler.mjs`.
 #
-# Last generated using `./wrangler.mjs` Dec 3, 2023 10:52 AM UTC.
+# Last generated using `./wrangler.mjs` Dec 12, 2023 2:00 AM UTC.
 ##
 
 send_metrics = false
-usage_model = "bundled"
 compatibility_date = "2023-08-15"
 compatibility_flags = [ ]
 account_id = "f1176464a976947aa5665d989814a4b1"
@@ -371,6 +370,7 @@ exclude = [
   "dist",
   "!dist",
   ".*",
+  "!.well-known",
   "*.config.*",
   "wrangler.*",
   "tsconfig.*",
@@ -419,10 +419,13 @@ pattern = "workers.hop.gdn/micromatch-fork/*"
 [env.dev]
 workers_dev = false
 
+  [env.dev.vars]
+  MINIFLARE = "true"
+
   [env.dev.build]
-  command = "npx @clevercanyon/madrun build --mode=dev"
+  command = "VITE_WRANGLER_MODE=dev npx @clevercanyon/madrun build --mode=dev"
 
 [dev]
-ip = "0.0.0.0"
 local_protocol = "https"
+ip = "0.0.0.0"
 port = 443