Rust library to generate static websites
5
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat: create a proper setup for JavaScript code in the repo (#82)

* feat: create a proper setup for JavaScript code in the repo

* fix: linting and formatting and stuff

* fix: embrace the future I guess

* fix: some more future

* fix: vscode

* fix: ci

* fix: sha

* fix: broken shortcode

authored by

Erika and committed by
GitHub
cbdac639 9f4ad731

+1320 -1171
+2
.cargo/config.toml
··· 1 + [alias] 2 + xtask = "run --package xtask --"
+15
.github/workflows/benchmark.yaml
··· 34 34 cache-target: release 35 35 bins: cargo-codspeed 36 36 37 + - name: Setup pnpm 38 + uses: pnpm/action-setup@v4 39 + 40 + - name: Setup Node.js 41 + uses: actions/setup-node@v4 42 + with: 43 + node-version: latest 44 + cache: 'pnpm' 45 + 46 + - name: Install dependencies 47 + run: pnpm install 48 + 49 + - name: Build JS dependencies 50 + run: cargo xtask build-js 51 + 37 52 - name: Build the benchmark target(s) 38 53 run: cargo codspeed build 39 54
+45
.github/workflows/ci.yaml
··· 31 31 with: 32 32 components: clippy 33 33 34 + - name: Setup pnpm 35 + uses: pnpm/action-setup@v4 36 + 37 + - name: Setup Node.js 38 + uses: actions/setup-node@v4 39 + with: 40 + node-version: latest 41 + cache: 'pnpm' 42 + 43 + - name: Install dependencies 44 + run: pnpm install 45 + 46 + - name: Build JS dependencies 47 + run: cargo xtask build-js 48 + 34 49 - name: Run Clippy 35 50 run: cargo clippy --all-targets --all-features 36 51 ··· 44 59 - name: Setup Rust 45 60 uses: moonrepo/setup-rust@v1 46 61 62 + - name: Setup pnpm 63 + uses: pnpm/action-setup@v4 64 + 65 + - name: Setup Node.js 66 + uses: actions/setup-node@v4 67 + with: 68 + node-version: latest 69 + cache: 'pnpm' 70 + 71 + - name: Install dependencies 72 + run: pnpm install 73 + 74 + - name: Build JS dependencies 75 + run: cargo xtask build-js 76 + 47 77 - name: Build 48 78 run: cargo build 49 79 ··· 56 86 57 87 - name: Setup Rust 58 88 uses: moonrepo/setup-rust@v1 89 + 90 + - name: Setup pnpm 91 + uses: pnpm/action-setup@v4 92 + 93 + - name: Setup Node.js 94 + uses: actions/setup-node@v4 95 + with: 96 + node-version: latest 97 + cache: 'pnpm' 98 + 99 + - name: Install dependencies 100 + run: pnpm install 101 + 102 + - name: Build JS dependencies 103 + run: cargo xtask build-js 59 104 60 105 - name: Test 61 106 run: cargo test
+15
.github/workflows/release.yml
··· 23 23 - name: Setup Rust 24 24 uses: moonrepo/setup-rust@v1 25 25 26 + - name: Setup pnpm 27 + uses: pnpm/action-setup@v4 28 + 29 + - name: Setup Node.js 30 + uses: actions/setup-node@v4 31 + with: 32 + node-version: latest 33 + cache: 'pnpm' 34 + 35 + - name: Install dependencies 36 + run: pnpm install 37 + 38 + - name: Build JS dependencies 39 + run: cargo xtask build-js 40 + 26 41 - name: Run Sampo Release/Publish Action 27 42 uses: bruits/sampo/crates/sampo-github-action@main 28 43 env:
+12
.oxfmtrc.json
··· 1 + { 2 + "$schema": "./node_modules/oxfmt/configuration_schema.json", 3 + "ignorePatterns": [ 4 + "node_modules", 5 + "dist", 6 + "pnpm-lock.yaml", 7 + "target", 8 + "benchmarks", 9 + "CHANGELOG.md" 10 + ], 11 + "useTabs": true 12 + }
+7
.oxlintrc.json
··· 1 + { 2 + "$schema": "./node_modules/oxlint/configuration_schema.json", 3 + "env": { 4 + "browser": true 5 + }, 6 + "ignorePatterns": ["dist", "node_modules", "target", "benchmarks"] 7 + }
+7
.vscode/extensions.json
··· 1 + { 2 + "recommendations": [ 3 + "oxc.oxc-vscode", 4 + "TypeScriptTeam.native-preview", 5 + "rust-lang.rust-analyzer" 6 + ] 7 + }
+14 -8
.vscode/settings.json
··· 1 1 { 2 - "tailwindCSS.includeLanguages": { 3 - "rust": "html" 4 - }, 5 - "tailwindCSS.experimental.classRegex": [ 6 - ["[\\w-]+((?:\\.\\s*\\S+\\s*)*)", "\\.\"?([^.\"]+)\"?"] 7 - ], 8 - "biome.enabled": false 9 - } 2 + "typescript.experimental.useTsgo": true, 3 + "editor.defaultFormatter": "oxc.oxc-vscode", 4 + "oxc.typeAware": true, 5 + "oxc.fixKind": "safe_fix", 6 + "oxc.unusedDisableDirectives": "deny", 7 + "[rust]": { 8 + "editor.defaultFormatter": "rust-lang.rust-analyzer" 9 + }, 10 + "editor.codeActionsOnSave": { 11 + "source.fixAll.oxc": "explicit" 12 + }, 13 + "biome.enabled": false, 14 + "css.lint.unknownAtRules": "ignore", 15 + }
+73
.zed/settings.json
··· 1 + { 2 + "formatter": { 3 + "language_server": { 4 + "name": "oxfmt" 5 + } 6 + }, 7 + "languages": { 8 + "Rust": { 9 + "formatter": "language_server" 10 + }, 11 + "TypeScript": { 12 + "language_servers": ["tsgo", "!vtsls", "!typescript-language-server", "!eslint", "..."], 13 + "formatter": [ 14 + { 15 + "language_server": { 16 + "name": "oxfmt" 17 + } 18 + }, 19 + { 20 + "code_action": "source.fixAll.oxc" 21 + } 22 + ] 23 + }, 24 + "JavaScript": { 25 + "language_servers": ["tsgo", "!vtsls", "!typescript-language-server", "!eslint", "..."], 26 + "formatter": [ 27 + { 28 + "language_server": { 29 + "name": "oxfmt" 30 + } 31 + }, 32 + { 33 + "code_action": "source.fixAll.oxc" 34 + } 35 + ] 36 + } 37 + }, 38 + "lsp": { 39 + "oxlint": { 40 + "initialization_options": { 41 + "settings": { 42 + "disableNestedConfig": false, 43 + "fixKind": "safe_fix", 44 + "run": "onType", 45 + "typeAware": true, 46 + "unusedDisableDirectives": "deny" 47 + } 48 + } 49 + }, 50 + "oxfmt": { 51 + "initialization_options": { 52 + "settings": { 53 + "configPath": null, 54 + "flags": {}, 55 + "fmt.configPath": null, 56 + "fmt.experimental": true, 57 + "run": "onSave", 58 + "typeAware": false, 59 + "unusedDisableDirectives": false 60 + } 61 + } 62 + }, 63 + "vscode-css-language-server": { 64 + "settings": { 65 + "css": { 66 + "lint": { 67 + "unknownAtRules": "ignore" 68 + } 69 + } 70 + } 71 + } 72 + } 73 + }
+12 -12
CODE_OF_CONDUCT.md
··· 17 17 Examples of behavior that contributes to a positive environment for our 18 18 community include: 19 19 20 - * Demonstrating empathy and kindness toward other people 21 - * Being respectful of differing opinions, viewpoints, and experiences 22 - * Giving and gracefully accepting constructive feedback 23 - * Accepting responsibility and apologizing to those affected by our mistakes, 20 + - Demonstrating empathy and kindness toward other people 21 + - Being respectful of differing opinions, viewpoints, and experiences 22 + - Giving and gracefully accepting constructive feedback 23 + - Accepting responsibility and apologizing to those affected by our mistakes, 24 24 and learning from the experience 25 - * Focusing on what is best not just for us as individuals, but for the 25 + - Focusing on what is best not just for us as individuals, but for the 26 26 overall community 27 27 28 28 Examples of unacceptable behavior include: 29 29 30 - * The use of sexualized language or imagery, and sexual attention or 30 + - The use of sexualized language or imagery, and sexual attention or 31 31 advances of any kind 32 - * Trolling, insulting or derogatory comments, and personal or political attacks 33 - * Public or private harassment 34 - * Publishing others' private information, such as a physical or email 32 + - Trolling, insulting or derogatory comments, and personal or political attacks 33 + - Public or private harassment 34 + - Publishing others' private information, such as a physical or email 35 35 address, without their explicit permission 36 - * Other conduct which could reasonably be considered inappropriate in a 36 + - Other conduct which could reasonably be considered inappropriate in a 37 37 professional setting 38 38 39 39 ## Enforcement Responsibilities ··· 59 59 ## Enforcement 60 60 61 61 Instances of abusive, harassing, or otherwise unacceptable behavior may be 62 - reported to the community leaders responsible for enforcement at 62 + reported to the community leaders responsible for enforcement at 63 63 princesseuh@proton.me or goulven.clech@protonmail.com . 64 64 All complaints will be reviewed and investigated promptly and fairly. 65 65 ··· 106 106 ### 4. Permanent Ban 107 107 108 108 **Community Impact**: Demonstrating a pattern of violation of community 109 - standards, including sustained inappropriate behavior, harassment of an 109 + standards, including sustained inappropriate behavior, harassment of an 110 110 individual, or aggression toward or disparagement of classes of individuals. 111 111 112 112 **Consequence**: A permanent ban from any sort of public interaction within
+8 -1
Cargo.lock
··· 2590 2590 version = "0.6.2" 2591 2591 dependencies = [ 2592 2592 "axum", 2593 - "brk_rolldown", 2594 2593 "cargo_metadata", 2595 2594 "chrono", 2596 2595 "clap", ··· 5869 5868 dependencies = [ 5870 5869 "libc", 5871 5870 "rustix", 5871 + ] 5872 + 5873 + [[package]] 5874 + name = "xtask" 5875 + version = "0.1.0" 5876 + dependencies = [ 5877 + "brk_rolldown", 5878 + "tokio", 5872 5879 ] 5873 5880 5874 5881 [[package]]
+1 -1
Cargo.toml
··· 1 1 [workspace] 2 - members = ["crates/*", "benchmarks/*", "examples/*", "website"] 2 + members = ["crates/*", "benchmarks/*", "examples/*", "website", "xtask"] 3 3 resolver = "3" 4 4 5 5 [workspace.dependencies]
+2 -14
crates/maudit-cli/Cargo.toml
··· 13 13 chrono = "0.4.39" 14 14 colored = "2.2.0" 15 15 clap = { version = "4.5.23", features = ["derive"] } 16 - tokio = { version = "1", features = [ 17 - "macros", 18 - "rt-multi-thread", 19 - "signal", 20 - "process", 21 - ] } 16 + tokio = { version = "1", features = ["macros", "rt-multi-thread", "signal", "process"] } 22 17 axum = { version = "0.8.6", features = ["ws"] } 23 18 futures = "0.3" 24 19 tower-http = { version = "0.6.6", features = ["fs", "trace"] } 25 20 tracing = "0.1" 26 - tracing-subscriber = { version = "=0.3.19", features = [ 27 - "env-filter", 28 - "chrono", 29 - ] } 21 + tracing-subscriber = { version = "=0.3.19", features = ["env-filter", "chrono"] } 30 22 notify = "8.2.0" 31 23 notify-debouncer-full = "0.6.0" 32 24 inquire = "0.7.5" ··· 41 33 serde_json = "1.0" 42 34 tokio-util = "0.7" 43 35 cargo_metadata = "0.23.0" 44 - 45 - [build-dependencies] 46 - rolldown = { package = "brk_rolldown", version = "0.2.3" } 47 - tokio = { version = "1", features = ["rt"] }
-44
crates/maudit-cli/build.rs
··· 1 - use rolldown::{Bundler, BundlerOptions, InputItem}; 2 - use std::path::PathBuf; 3 - 4 - fn main() { 5 - // Tell Cargo to rerun if any of our JS/TS files change 6 - println!("cargo:rerun-if-changed=src/dev/js"); 7 - println!("cargo:rerun-if-changed=tsconfig.json"); 8 - 9 - // Only bundle during regular builds, not during cargo check or similar 10 - if std::env::var("CARGO_CFG_TARGET_ARCH").is_err() { 11 - return; 12 - } 13 - 14 - let js_src_dir = PathBuf::from("src/dev/js"); 15 - let out_dir = std::env::var("OUT_DIR").expect("OUT_DIR environment variable not set"); 16 - let js_dist_dir = PathBuf::from(out_dir).join("js"); 17 - 18 - // Ensure the dist directory exists 19 - std::fs::create_dir_all(&js_dist_dir).expect("Failed to create dist directory"); 20 - 21 - // Configure Rolldown bundler input 22 - let input_items = vec![InputItem { 23 - name: Some("client".to_string()), 24 - import: js_src_dir.join("client.ts").to_string_lossy().to_string(), 25 - }]; 26 - 27 - let bundler_options = BundlerOptions { 28 - input: Some(input_items), 29 - dir: Some(js_dist_dir.to_string_lossy().to_string()), 30 - format: Some(rolldown::OutputFormat::Esm), 31 - ..Default::default() 32 - }; 33 - 34 - // Create and run the bundler 35 - let runtime = tokio::runtime::Runtime::new().expect("Failed to create tokio runtime"); 36 - 37 - runtime.block_on(async { 38 - let mut bundler = Bundler::new(bundler_options).unwrap(); 39 - if let Err(e) = bundler.write().await { 40 - panic!("Failed to bundle JavaScript: {:?}", e); 41 - } 42 - println!("Successfully bundled JavaScript files"); 43 - }); 44 - }
+7
crates/maudit-cli/package.json
··· 1 + { 2 + "name": "maudit-cli-packages", 3 + "private": true, 4 + "dependencies": { 5 + "ansi_up": "^6.0.6" 6 + } 7 + }
+11 -11
crates/maudit-cli/src/dev/404.html
··· 1 1 <!-- TODO: Make this prettier --> 2 - <!DOCTYPE html> 2 + <!doctype html> 3 3 <html lang="en"> 4 - <head> 5 - <meta charset="UTF-8" /> 6 - <meta name="viewport" content="width=device-width, initial-scale=1.0" /> 7 - <title>404 - Not Found</title> 8 - </head> 9 - <body> 10 - <h1>404</h1> 11 - <h2>Page not found</h2> 12 - <p>The page you're looking for doesn't exist or has been moved.</p> 13 - </body> 4 + <head> 5 + <meta charset="UTF-8" /> 6 + <meta name="viewport" content="width=device-width, initial-scale=1.0" /> 7 + <title>404 - Not Found</title> 8 + </head> 9 + <body> 10 + <h1>404</h1> 11 + <h2>Page not found</h2> 12 + <p>The page you're looking for doesn't exist or has been moved.</p> 13 + </body> 14 14 </html>
+1
crates/maudit-cli/src/dev/filterer.rs
··· 1 +
+2 -2
crates/maudit-cli/src/dev/js/client.ts crates/maudit-cli/js/client.ts
··· 3 3 * It might be better to use a more sophisticated approach, using some sort of diffing, handling reconnecting, etc. 4 4 */ 5 5 6 - import { AnsiUp } from "./vendor/ansi_up"; 6 + import { AnsiUp } from "ansi_up"; 7 7 import { createErrorOverlay } from "./overlay"; 8 8 import { error, log } from "./utils"; 9 9 ··· 32 32 33 33 const socket = new WebSocket(`ws://${WS_SERVER_ADDRESS}/ws`); 34 34 35 - socket.addEventListener("open", (event) => { 35 + socket.addEventListener("open", () => { 36 36 console.log("Connected to server"); 37 37 socket.send("Hello Server!"); 38 38 });
+1 -3
crates/maudit-cli/src/dev/js/overlay.ts crates/maudit-cli/js/overlay.ts
··· 70 70 } 71 71 72 72 export function clearErrorOverlay() { 73 - document 74 - .querySelectorAll<MauditErrorOverlay>(overlayTagName) 75 - .forEach((n) => n.close()); 73 + document.querySelectorAll<MauditErrorOverlay>(overlayTagName).forEach((n) => n.close()); 76 74 }
+3 -4
crates/maudit-cli/src/dev/js/utils.ts crates/maudit-cli/js/utils.ts
··· 1 1 const ansiPattern = new RegExp( 2 + // oxlint-disable-next-line no-control-regex 2 3 "(?:\\u001B\\][\\s\\S]*?(?:\\u0007|\\u001B\\u005C|\\u009C))|[\\u001B\\u009B][[\\]()#;?]*(?:\\d{1,4}(?:[;:]\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]", 3 - "g" 4 + "g", 4 5 ); 5 6 6 7 export function stripAnsi(str: string): string { ··· 23 24 console[level]( 24 25 "%cMaudit", 25 26 "background: #ba1f33; color: white; padding-inline: 4px; border-radius: 2px; font-family: serif;", 26 - ...message.map((m) => 27 - typeof m === "string" ? stripAnsi(m) : JSON.stringify(m, null, 2) 28 - ) 27 + ...message.map((m) => (typeof m === "string" ? stripAnsi(m) : JSON.stringify(m, null, 2))), 29 28 ); 30 29 }
-7
crates/maudit-cli/src/dev/js/vendor/README.md
··· 1 - # Vendored libraries for the Maudit CLI dev server. 2 - 3 - Since the JS part of the Maudit CLI is built at build time through a Rust build script, we cannot rely on a package manager to fetch dependencies, as people downloading the Maudit CLI from crates.io won't have access to npm, pnpm, yarn, etc. 4 - 5 - As such, we vendor the dependencies we need here. They are copied as-is from their respective repositories and include their license information at the top of the file. 6 - 7 - An alternative to this approach would be to pre-bundle the JS code and ship the bundled version with the crate, but it's a lot more cumbersome in development so while things are still evolving, we prefer this approach.
-46
crates/maudit-cli/src/dev/js/vendor/ansi_up.d.ts
··· 1 - export declare class AnsiUp { 2 - VERSION: string; 3 - private ansi_colors; 4 - private palette_256; 5 - private fg; 6 - private bg; 7 - private bold; 8 - private faint; 9 - private italic; 10 - private underline; 11 - private _use_classes; 12 - private _csi_regex; 13 - private _osc_st; 14 - private _osc_regex; 15 - private _url_allowlist; 16 - private _escape_html; 17 - private _buffer; 18 - private _boldStyle; 19 - private _faintStyle; 20 - private _italicStyle; 21 - private _underlineStyle; 22 - constructor(); 23 - set use_classes(arg: boolean); 24 - get use_classes(): boolean; 25 - set url_allowlist(arg: {}); 26 - get url_allowlist(): {}; 27 - set escape_html(arg: boolean); 28 - get escape_html(): boolean; 29 - set boldStyle(arg: string); 30 - get boldStyle(): string; 31 - set faintStyle(arg: string); 32 - get faintStyle(): string; 33 - set italicStyle(arg: string); 34 - get italicStyle(): string; 35 - set underlineStyle(arg: string); 36 - get underlineStyle(): string; 37 - private setup_palettes; 38 - private escape_txt_for_html; 39 - private append_buffer; 40 - private get_next_packet; 41 - ansi_to_html(txt: string): string; 42 - private with_state; 43 - private process_ansi; 44 - private transform_to_html; 45 - private process_hyperlink; 46 - }
-469
crates/maudit-cli/src/dev/js/vendor/ansi_up.js
··· 1 - /* ansi_up.js 2 - * author : http://github.com/drudru/ 3 - * license : MIT 4 - * http://github.com/drudru/ansi_up 5 - */ 6 - 7 - "use strict"; 8 - var __makeTemplateObject = 9 - (this && this.__makeTemplateObject) || 10 - function (cooked, raw) { 11 - if (Object.defineProperty) { 12 - Object.defineProperty(cooked, "raw", { value: raw }); 13 - } else { 14 - cooked.raw = raw; 15 - } 16 - return cooked; 17 - }; 18 - var PacketKind; 19 - (function (PacketKind) { 20 - PacketKind[(PacketKind["EOS"] = 0)] = "EOS"; 21 - PacketKind[(PacketKind["Text"] = 1)] = "Text"; 22 - PacketKind[(PacketKind["Incomplete"] = 2)] = "Incomplete"; 23 - PacketKind[(PacketKind["ESC"] = 3)] = "ESC"; 24 - PacketKind[(PacketKind["Unknown"] = 4)] = "Unknown"; 25 - PacketKind[(PacketKind["SGR"] = 5)] = "SGR"; 26 - PacketKind[(PacketKind["OSCURL"] = 6)] = "OSCURL"; 27 - })(PacketKind || (PacketKind = {})); 28 - export class AnsiUp { 29 - constructor() { 30 - this.VERSION = "6.0.6"; 31 - this.setup_palettes(); 32 - this._use_classes = false; 33 - this.bold = false; 34 - this.faint = false; 35 - this.italic = false; 36 - this.underline = false; 37 - this.fg = this.bg = null; 38 - this._buffer = ""; 39 - this._url_allowlist = { http: 1, https: 1 }; 40 - this._escape_html = true; 41 - this.boldStyle = "font-weight:bold"; 42 - this.faintStyle = "opacity:0.7"; 43 - this.italicStyle = "font-style:italic"; 44 - this.underlineStyle = "text-decoration:underline"; 45 - } 46 - set use_classes(arg) { 47 - this._use_classes = arg; 48 - } 49 - get use_classes() { 50 - return this._use_classes; 51 - } 52 - set url_allowlist(arg) { 53 - this._url_allowlist = arg; 54 - } 55 - get url_allowlist() { 56 - return this._url_allowlist; 57 - } 58 - set escape_html(arg) { 59 - this._escape_html = arg; 60 - } 61 - get escape_html() { 62 - return this._escape_html; 63 - } 64 - set boldStyle(arg) { 65 - this._boldStyle = arg; 66 - } 67 - get boldStyle() { 68 - return this._boldStyle; 69 - } 70 - set faintStyle(arg) { 71 - this._faintStyle = arg; 72 - } 73 - get faintStyle() { 74 - return this._faintStyle; 75 - } 76 - set italicStyle(arg) { 77 - this._italicStyle = arg; 78 - } 79 - get italicStyle() { 80 - return this._italicStyle; 81 - } 82 - set underlineStyle(arg) { 83 - this._underlineStyle = arg; 84 - } 85 - get underlineStyle() { 86 - return this._underlineStyle; 87 - } 88 - setup_palettes() { 89 - this.ansi_colors = [ 90 - [ 91 - { rgb: [0, 0, 0], class_name: "ansi-black" }, 92 - { rgb: [187, 0, 0], class_name: "ansi-red" }, 93 - { rgb: [0, 187, 0], class_name: "ansi-green" }, 94 - { rgb: [187, 187, 0], class_name: "ansi-yellow" }, 95 - { rgb: [0, 0, 187], class_name: "ansi-blue" }, 96 - { rgb: [187, 0, 187], class_name: "ansi-magenta" }, 97 - { rgb: [0, 187, 187], class_name: "ansi-cyan" }, 98 - { rgb: [255, 255, 255], class_name: "ansi-white" }, 99 - ], 100 - [ 101 - { rgb: [85, 85, 85], class_name: "ansi-bright-black" }, 102 - { rgb: [255, 85, 85], class_name: "ansi-bright-red" }, 103 - { rgb: [0, 255, 0], class_name: "ansi-bright-green" }, 104 - { rgb: [255, 255, 85], class_name: "ansi-bright-yellow" }, 105 - { rgb: [85, 85, 255], class_name: "ansi-bright-blue" }, 106 - { rgb: [255, 85, 255], class_name: "ansi-bright-magenta" }, 107 - { rgb: [85, 255, 255], class_name: "ansi-bright-cyan" }, 108 - { rgb: [255, 255, 255], class_name: "ansi-bright-white" }, 109 - ], 110 - ]; 111 - this.palette_256 = []; 112 - this.ansi_colors.forEach((palette) => { 113 - palette.forEach((rec) => { 114 - this.palette_256.push(rec); 115 - }); 116 - }); 117 - let levels = [0, 95, 135, 175, 215, 255]; 118 - for (let r = 0; r < 6; ++r) { 119 - for (let g = 0; g < 6; ++g) { 120 - for (let b = 0; b < 6; ++b) { 121 - let col = { 122 - rgb: [levels[r], levels[g], levels[b]], 123 - class_name: "truecolor", 124 - }; 125 - this.palette_256.push(col); 126 - } 127 - } 128 - } 129 - let grey_level = 8; 130 - for (let i = 0; i < 24; ++i, grey_level += 10) { 131 - let gry = { 132 - rgb: [grey_level, grey_level, grey_level], 133 - class_name: "truecolor", 134 - }; 135 - this.palette_256.push(gry); 136 - } 137 - } 138 - escape_txt_for_html(txt) { 139 - if (!this._escape_html) return txt; 140 - return txt.replace(/[&<>"']/gm, (str) => { 141 - if (str === "&") return "&amp;"; 142 - if (str === "<") return "&lt;"; 143 - if (str === ">") return "&gt;"; 144 - if (str === '"') return "&quot;"; 145 - if (str === "'") return "&#x27;"; 146 - }); 147 - } 148 - append_buffer(txt) { 149 - var str = this._buffer + txt; 150 - this._buffer = str; 151 - } 152 - get_next_packet() { 153 - var pkt = { 154 - kind: PacketKind.EOS, 155 - text: "", 156 - url: "", 157 - }; 158 - var len = this._buffer.length; 159 - if (len == 0) return pkt; 160 - var pos = this._buffer.indexOf("\x1B"); 161 - if (pos == -1) { 162 - pkt.kind = PacketKind.Text; 163 - pkt.text = this._buffer; 164 - this._buffer = ""; 165 - return pkt; 166 - } 167 - if (pos > 0) { 168 - pkt.kind = PacketKind.Text; 169 - pkt.text = this._buffer.slice(0, pos); 170 - this._buffer = this._buffer.slice(pos); 171 - return pkt; 172 - } 173 - if (pos == 0) { 174 - if (len < 3) { 175 - pkt.kind = PacketKind.Incomplete; 176 - return pkt; 177 - } 178 - var next_char = this._buffer.charAt(1); 179 - if (next_char != "[" && next_char != "]" && next_char != "(") { 180 - pkt.kind = PacketKind.ESC; 181 - pkt.text = this._buffer.slice(0, 1); 182 - this._buffer = this._buffer.slice(1); 183 - return pkt; 184 - } 185 - if (next_char == "[") { 186 - if (!this._csi_regex) { 187 - this._csi_regex = rgx( 188 - templateObject_1 || 189 - (templateObject_1 = __makeTemplateObject( 190 - [ 191 - "\n ^ # beginning of line\n #\n # First attempt\n (?: # legal sequence\n \u001B[ # CSI\n ([<-?]?) # private-mode char\n ([d;]*) # any digits or semicolons\n ([ -/]? # an intermediate modifier\n [@-~]) # the command\n )\n | # alternate (second attempt)\n (?: # illegal sequence\n \u001B[ # CSI\n [ -~]* # anything legal\n ([\0-\u001F:]) # anything illegal\n )\n ", 192 - ], 193 - [ 194 - "\n ^ # beginning of line\n #\n # First attempt\n (?: # legal sequence\n \\x1b\\[ # CSI\n ([\\x3c-\\x3f]?) # private-mode char\n ([\\d;]*) # any digits or semicolons\n ([\\x20-\\x2f]? # an intermediate modifier\n [\\x40-\\x7e]) # the command\n )\n | # alternate (second attempt)\n (?: # illegal sequence\n \\x1b\\[ # CSI\n [\\x20-\\x7e]* # anything legal\n ([\\x00-\\x1f:]) # anything illegal\n )\n ", 195 - ] 196 - )) 197 - ); 198 - } 199 - let match = this._buffer.match(this._csi_regex); 200 - if (match === null) { 201 - pkt.kind = PacketKind.Incomplete; 202 - return pkt; 203 - } 204 - if (match[4]) { 205 - pkt.kind = PacketKind.ESC; 206 - pkt.text = this._buffer.slice(0, 1); 207 - this._buffer = this._buffer.slice(1); 208 - return pkt; 209 - } 210 - if (match[1] != "" || match[3] != "m") pkt.kind = PacketKind.Unknown; 211 - else pkt.kind = PacketKind.SGR; 212 - pkt.text = match[2]; 213 - var rpos = match[0].length; 214 - this._buffer = this._buffer.slice(rpos); 215 - return pkt; 216 - } else if (next_char == "]") { 217 - if (len < 4) { 218 - pkt.kind = PacketKind.Incomplete; 219 - return pkt; 220 - } 221 - if (this._buffer.charAt(2) != "8" || this._buffer.charAt(3) != ";") { 222 - pkt.kind = PacketKind.ESC; 223 - pkt.text = this._buffer.slice(0, 1); 224 - this._buffer = this._buffer.slice(1); 225 - return pkt; 226 - } 227 - if (!this._osc_st) { 228 - this._osc_st = rgxG( 229 - templateObject_2 || 230 - (templateObject_2 = __makeTemplateObject( 231 - [ 232 - "\n (?: # legal sequence\n (\u001B\\) # ESC | # alternate\n (\u0007) # BEL (what xterm did)\n )\n | # alternate (second attempt)\n ( # illegal sequence\n [\0-\u0006] # anything illegal\n | # alternate\n [\b-\u001A] # anything illegal\n | # alternate\n [\u001C-\u001F] # anything illegal\n )\n ", 233 - ], 234 - [ 235 - "\n (?: # legal sequence\n (\\x1b\\\\) # ESC \\\n | # alternate\n (\\x07) # BEL (what xterm did)\n )\n | # alternate (second attempt)\n ( # illegal sequence\n [\\x00-\\x06] # anything illegal\n | # alternate\n [\\x08-\\x1a] # anything illegal\n | # alternate\n [\\x1c-\\x1f] # anything illegal\n )\n ", 236 - ] 237 - )) 238 - ); 239 - } 240 - this._osc_st.lastIndex = 0; 241 - { 242 - let match = this._osc_st.exec(this._buffer); 243 - if (match === null) { 244 - pkt.kind = PacketKind.Incomplete; 245 - return pkt; 246 - } 247 - if (match[3]) { 248 - pkt.kind = PacketKind.ESC; 249 - pkt.text = this._buffer.slice(0, 1); 250 - this._buffer = this._buffer.slice(1); 251 - return pkt; 252 - } 253 - } 254 - { 255 - let match = this._osc_st.exec(this._buffer); 256 - if (match === null) { 257 - pkt.kind = PacketKind.Incomplete; 258 - return pkt; 259 - } 260 - if (match[3]) { 261 - pkt.kind = PacketKind.ESC; 262 - pkt.text = this._buffer.slice(0, 1); 263 - this._buffer = this._buffer.slice(1); 264 - return pkt; 265 - } 266 - } 267 - if (!this._osc_regex) { 268 - this._osc_regex = rgx( 269 - templateObject_3 || 270 - (templateObject_3 = __makeTemplateObject( 271 - [ 272 - "\n ^ # beginning of line\n #\n \u001B]8; # OSC Hyperlink\n [ -:<-~]* # params (excluding ;)\n ; # end of params\n ([!-~]{0,512}) # URL capture\n (?: # ST\n (?:\u001B\\) # ESC | # alternate\n (?:\u0007) # BEL (what xterm did)\n )\n ([ -~]+) # TEXT capture\n \u001B]8;; # OSC Hyperlink End\n (?: # ST\n (?:\u001B\\) # ESC | # alternate\n (?:\u0007) # BEL (what xterm did)\n )\n ", 273 - ], 274 - [ 275 - "\n ^ # beginning of line\n #\n \\x1b\\]8; # OSC Hyperlink\n [\\x20-\\x3a\\x3c-\\x7e]* # params (excluding ;)\n ; # end of params\n ([\\x21-\\x7e]{0,512}) # URL capture\n (?: # ST\n (?:\\x1b\\\\) # ESC \\\n | # alternate\n (?:\\x07) # BEL (what xterm did)\n )\n ([\\x20-\\x7e]+) # TEXT capture\n \\x1b\\]8;; # OSC Hyperlink End\n (?: # ST\n (?:\\x1b\\\\) # ESC \\\n | # alternate\n (?:\\x07) # BEL (what xterm did)\n )\n ", 276 - ] 277 - )) 278 - ); 279 - } 280 - let match = this._buffer.match(this._osc_regex); 281 - if (match === null) { 282 - pkt.kind = PacketKind.ESC; 283 - pkt.text = this._buffer.slice(0, 1); 284 - this._buffer = this._buffer.slice(1); 285 - return pkt; 286 - } 287 - pkt.kind = PacketKind.OSCURL; 288 - pkt.url = match[1]; 289 - pkt.text = match[2]; 290 - var rpos = match[0].length; 291 - this._buffer = this._buffer.slice(rpos); 292 - return pkt; 293 - } else if (next_char == "(") { 294 - pkt.kind = PacketKind.Unknown; 295 - this._buffer = this._buffer.slice(3); 296 - return pkt; 297 - } 298 - } 299 - } 300 - ansi_to_html(txt) { 301 - this.append_buffer(txt); 302 - var blocks = []; 303 - while (true) { 304 - var packet = this.get_next_packet(); 305 - if (packet.kind == PacketKind.EOS || packet.kind == PacketKind.Incomplete) 306 - break; 307 - if (packet.kind == PacketKind.ESC || packet.kind == PacketKind.Unknown) 308 - continue; 309 - if (packet.kind == PacketKind.Text) 310 - blocks.push(this.transform_to_html(this.with_state(packet))); 311 - else if (packet.kind == PacketKind.SGR) this.process_ansi(packet); 312 - else if (packet.kind == PacketKind.OSCURL) 313 - blocks.push(this.process_hyperlink(packet)); 314 - } 315 - return blocks.join(""); 316 - } 317 - with_state(pkt) { 318 - return { 319 - bold: this.bold, 320 - faint: this.faint, 321 - italic: this.italic, 322 - underline: this.underline, 323 - fg: this.fg, 324 - bg: this.bg, 325 - text: pkt.text, 326 - }; 327 - } 328 - process_ansi(pkt) { 329 - let sgr_cmds = pkt.text.split(";"); 330 - while (sgr_cmds.length > 0) { 331 - let sgr_cmd_str = sgr_cmds.shift(); 332 - let num = parseInt(sgr_cmd_str, 10); 333 - if (isNaN(num) || num === 0) { 334 - this.fg = null; 335 - this.bg = null; 336 - this.bold = false; 337 - this.faint = false; 338 - this.italic = false; 339 - this.underline = false; 340 - } else if (num === 1) { 341 - this.bold = true; 342 - } else if (num === 2) { 343 - this.faint = true; 344 - } else if (num === 3) { 345 - this.italic = true; 346 - } else if (num === 4) { 347 - this.underline = true; 348 - } else if (num === 21) { 349 - this.bold = false; 350 - } else if (num === 22) { 351 - this.faint = false; 352 - this.bold = false; 353 - } else if (num === 23) { 354 - this.italic = false; 355 - } else if (num === 24) { 356 - this.underline = false; 357 - } else if (num === 39) { 358 - this.fg = null; 359 - } else if (num === 49) { 360 - this.bg = null; 361 - } else if (num >= 30 && num < 38) { 362 - this.fg = this.ansi_colors[0][num - 30]; 363 - } else if (num >= 40 && num < 48) { 364 - this.bg = this.ansi_colors[0][num - 40]; 365 - } else if (num >= 90 && num < 98) { 366 - this.fg = this.ansi_colors[1][num - 90]; 367 - } else if (num >= 100 && num < 108) { 368 - this.bg = this.ansi_colors[1][num - 100]; 369 - } else if (num === 38 || num === 48) { 370 - if (sgr_cmds.length > 0) { 371 - let is_foreground = num === 38; 372 - let mode_cmd = sgr_cmds.shift(); 373 - if (mode_cmd === "5" && sgr_cmds.length > 0) { 374 - let palette_index = parseInt(sgr_cmds.shift(), 10); 375 - if (palette_index >= 0 && palette_index <= 255) { 376 - if (is_foreground) this.fg = this.palette_256[palette_index]; 377 - else this.bg = this.palette_256[palette_index]; 378 - } 379 - } 380 - if (mode_cmd === "2" && sgr_cmds.length > 2) { 381 - let r = parseInt(sgr_cmds.shift(), 10); 382 - let g = parseInt(sgr_cmds.shift(), 10); 383 - let b = parseInt(sgr_cmds.shift(), 10); 384 - if ( 385 - r >= 0 && 386 - r <= 255 && 387 - g >= 0 && 388 - g <= 255 && 389 - b >= 0 && 390 - b <= 255 391 - ) { 392 - let c = { rgb: [r, g, b], class_name: "truecolor" }; 393 - if (is_foreground) this.fg = c; 394 - else this.bg = c; 395 - } 396 - } 397 - } 398 - } 399 - } 400 - } 401 - transform_to_html(fragment) { 402 - let txt = fragment.text; 403 - if (txt.length === 0) return txt; 404 - txt = this.escape_txt_for_html(txt); 405 - if ( 406 - !fragment.bold && 407 - !fragment.italic && 408 - !fragment.faint && 409 - !fragment.underline && 410 - fragment.fg === null && 411 - fragment.bg === null 412 - ) 413 - return txt; 414 - let styles = []; 415 - let classes = []; 416 - let fg = fragment.fg; 417 - let bg = fragment.bg; 418 - if (fragment.bold) styles.push(this._boldStyle); 419 - if (fragment.faint) styles.push(this._faintStyle); 420 - if (fragment.italic) styles.push(this._italicStyle); 421 - if (fragment.underline) styles.push(this._underlineStyle); 422 - if (!this._use_classes) { 423 - if (fg) styles.push(`color:rgb(${fg.rgb.join(",")})`); 424 - if (bg) styles.push(`background-color:rgb(${bg.rgb})`); 425 - } else { 426 - if (fg) { 427 - if (fg.class_name !== "truecolor") { 428 - classes.push(`${fg.class_name}-fg`); 429 - } else { 430 - styles.push(`color:rgb(${fg.rgb.join(",")})`); 431 - } 432 - } 433 - if (bg) { 434 - if (bg.class_name !== "truecolor") { 435 - classes.push(`${bg.class_name}-bg`); 436 - } else { 437 - styles.push(`background-color:rgb(${bg.rgb.join(",")})`); 438 - } 439 - } 440 - } 441 - let class_string = ""; 442 - let style_string = ""; 443 - if (classes.length) class_string = ` class="${classes.join(" ")}"`; 444 - if (styles.length) style_string = ` style="${styles.join(";")}"`; 445 - return `<span${style_string}${class_string}>${txt}</span>`; 446 - } 447 - process_hyperlink(pkt) { 448 - let parts = pkt.url.split(":"); 449 - if (parts.length < 1) return ""; 450 - if (!this._url_allowlist[parts[0]]) return ""; 451 - let result = `<a href="${this.escape_txt_for_html( 452 - pkt.url 453 - )}">${this.escape_txt_for_html(pkt.text)}</a>`; 454 - return result; 455 - } 456 - } 457 - function rgx(tmplObj, ...subst) { 458 - let regexText = tmplObj.raw[0]; 459 - let wsrgx = /^\s+|\s+\n|\s*#[\s\S]*?\n|\n/gm; 460 - let txt2 = regexText.replace(wsrgx, ""); 461 - return new RegExp(txt2); 462 - } 463 - function rgxG(tmplObj, ...subst) { 464 - let regexText = tmplObj.raw[0]; 465 - let wsrgx = /^\s+|\s+\n|\s*#[\s\S]*?\n|\n/gm; 466 - let txt2 = regexText.replace(wsrgx, ""); 467 - return new RegExp(txt2, "g"); 468 - } 469 - var templateObject_1, templateObject_2, templateObject_3;
+2 -1
crates/maudit-cli/src/dev/server.rs
··· 72 72 fn inject_live_reload_script(html_content: &str, socket_addr: SocketAddr, host: bool) -> String { 73 73 let mut content = html_content.to_string(); 74 74 75 - let script_content = include_str!(concat!(env!("OUT_DIR"), "/js/client.js")).replace( 75 + // Run cargo xtask build-cli-js to build the client.js file if missing 76 + let script_content = include_str!("../../js/dist/client.js").replace( 76 77 "{SERVER_ADDRESS}", 77 78 &format!( 78 79 "{}:{}",
+2 -24
crates/maudit-cli/tsconfig.json
··· 1 1 { 2 - "compilerOptions": { 3 - "rootDir": "./src/dev/js", 4 - "noEmit": true, 5 - 6 - "module": "esnext", 7 - "target": "es2020", 8 - "lib": ["dom", "dom.iterable", "es2020"], 9 - "moduleResolution": "bundler", 10 - 11 - // Other Outputs 12 - "sourceMap": true, 13 - 14 - // Stricter Typechecking Options 15 - "noUncheckedIndexedAccess": true, 16 - "exactOptionalPropertyTypes": true, 17 - 18 - // Recommended Options 19 - "strict": true, 20 - "verbatimModuleSyntax": true, 21 - "isolatedModules": true, 22 - "noUncheckedSideEffectImports": true, 23 - "moduleDetection": "force", 24 - "skipLibCheck": true, 25 - } 2 + "extends": "../../tsconfig.json", 3 + "include": ["js"] 26 4 }
+3 -6
crates/maudit-macros/CHANGELOG.md
··· 17 17 ### Minor changes 18 18 19 19 - [2bfa8a8](https://github.com/bruits/maudit/commit/2bfa8a87212243b27c2231b836e7da9ec2cd3288) Rename (almost) all instances of Routes to Pages and vice versa. 20 - 20 + 21 21 Previously, in Maudit, a _page_ referred to the struct you'd pass to `coronate` and a page could have multiple routes if it was dynamic. In my opinion, the reverse is more intuitive: a _route_ is the struct you define, and a route can have multiple _pages_ if it's dynamic. This also applies to every other types that had "Route" or "Page" in their name. 22 - 22 + 23 23 As such, the following renames were made: 24 - 25 24 - `Route` -> `Page` 26 25 - `FullRoute` -> `FullPage` 27 26 - `RouteContext` -> `PageContext` ··· 29 28 - `Routes` -> `Pages` 30 29 - `fn routes` -> `fn pages` 31 30 - `maudit::page` -> `maudit::route` (including the prelude, which is now `maudit::route::prelude`) 32 - 31 + 33 32 And probably some others I forgot. — Thanks @Princesseuh! 34 - 35 33 36 34 ## 0.4.0 37 35 38 36 ### Minor changes 39 37 40 38 - [52eda9e](https://github.com/bruits/maudit/commit/52eda9ea4eac8efd3efd945d00f39a1b99f284ab) Update generated code to support returning properties in dynamic routes. — Thanks @Princesseuh! 41 -
crates/maudit/js/preload.ts

This is a binary file and will not be displayed.

+4
crates/maudit/tsconfig.json
··· 1 + { 2 + "extends": "../../tsconfig.json", 3 + "include": ["js"] 4 + }
-5
crates/oubli/CHANGELOG.md
··· 60 60 61 61 - Updated dependencies: maudit@0.6.2 62 62 63 - 64 63 ## 0.1.4 65 64 66 65 ### Patch changes 67 66 68 67 - Updated dependencies: maudit@0.6.1 69 - 70 68 71 69 ## 0.1.3 72 70 73 71 ### Patch changes 74 72 75 73 - Updated dependencies: maudit@0.6.0 76 - 77 74 78 75 ## 0.1.2 79 76 ··· 81 78 82 79 - Updated dependencies: maudit@0.5.1 83 80 84 - 85 81 ## 0.1.1 86 82 87 83 ### Patch changes 88 84 89 85 - Updated dependencies: maudit@0.5.0 90 -
+9 -5
examples/i18n/README.md
··· 35 35 ``` 36 36 37 37 This route is accessible at: 38 + 38 39 - `/about` - the base/default path 39 40 - `/en/about` - English variant 40 41 - `/sv/om-oss` - Swedish variant (using natural Swedish URL structure) ··· 62 63 Page::from_params(MixedParams { id: "phone".to_string() }), 63 64 ] 64 65 } 65 - 66 + 66 67 fn render(&self, ctx: &mut PageContext) -> impl Into<RenderResult> { 67 68 let params = ctx.params::<MixedParams>(); 68 69 // Render using params.id ··· 71 72 ``` 72 73 73 74 This generates only variant pages: 75 + 74 76 - `/en/products/laptop` and `/en/products/phone` 75 77 - `/sv/produkter/laptop` and `/sv/produkter/phone` 76 78 ··· 97 99 Page::from_params(ArticleParams { slug: "getting-started".to_string() }), 98 100 ] 99 101 } 100 - 102 + 101 103 fn render(&self, ctx: &mut PageContext) -> impl Into<RenderResult> { 102 104 let params = ctx.params::<ArticleParams>(); 103 105 // Render using params.slug ··· 106 108 ``` 107 109 108 110 This generates: 111 + 109 112 - `/articles/hello-world` and `/articles/getting-started` - base pages 110 113 - `/en/articles/hello-world` and `/en/articles/getting-started` - English variants 111 114 - `/sv/artiklar/hello-world` and `/sv/artiklar/getting-started` - Swedish variants (note the localized "artiklar" path segment) ··· 119 122 - `variants(&self) -> Vec<(String, String)>` - Get all variants as `(id, path)` tuples 120 123 121 124 Example: 125 + 122 126 ```rust 123 127 let about = About; 124 128 let variants = about.variants(); ··· 173 177 174 178 fn render(&self, ctx: &mut PageContext) -> impl Into<RenderResult> { 175 179 let params = ctx.params::<ArticleParams>(); 176 - 180 + 177 181 // Render differently based on variant 178 182 let greeting = match ctx.variant.as_deref() { 179 183 Some("en") => "Hello", ··· 181 185 None => "Hi", 182 186 _ => "?" 183 187 }; 184 - 188 + 185 189 format!("{}: {}", greeting, params.slug) 186 190 } 187 191 } ··· 211 215 16:38:08 pages generated 13 pages in 1ms 212 216 ``` 213 217 214 - Each variant is treated as a separate page with its own URL and output file. For dynamic routes, all pages are generated for each variant automatically. 218 + Each variant is treated as a separate page with its own URL and output file. For dynamic routes, all pages are generated for each variant automatically.
+1 -1
examples/kitchen-sink/data/script.js
··· 1 1 import { sayHello } from "./some_other_script.js"; 2 2 3 3 document.addEventListener("DOMContentLoaded", () => { 4 - sayHello(); 4 + sayHello(); 5 5 });
+2 -2
examples/kitchen-sink/data/some_other_script.js
··· 1 1 export function sayHello() { 2 - const world = "world"; 3 - console.log(`hello${world}`); 2 + const world = "world"; 3 + console.log(`hello${world}`); 4 4 }
+150 -150
examples/markdown-components/src/style.css
··· 1 1 /* Reset and base styles */ 2 2 * { 3 - box-sizing: border-box; 3 + box-sizing: border-box; 4 4 } 5 5 body { 6 - margin: 0; 7 - padding: 0; 8 - font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, 9 - "Helvetica Neue", Arial, sans-serif; 10 - line-height: 1.6; 11 - color: #333; 12 - min-height: 100vh; 6 + margin: 0; 7 + padding: 0; 8 + font-family: 9 + -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; 10 + line-height: 1.6; 11 + color: #333; 12 + min-height: 100vh; 13 13 } 14 14 15 15 /* Layout */ 16 16 .container { 17 - max-width: 1024px; 18 - margin: 0 auto; 19 - padding: 48px 24px; 17 + max-width: 1024px; 18 + margin: 0 auto; 19 + padding: 48px 24px; 20 20 } 21 21 22 22 .header { 23 - text-align: center; 24 - margin-bottom: 48px; 23 + text-align: center; 24 + margin-bottom: 48px; 25 25 } 26 26 27 27 .header h1 { 28 - font-size: 2.5rem; 29 - font-weight: bold; 30 - color: #1a1a1a; 31 - margin: 0 0 16px 0; 28 + font-size: 2.5rem; 29 + font-weight: bold; 30 + color: #1a1a1a; 31 + margin: 0 0 16px 0; 32 32 } 33 33 34 34 .header p { 35 - font-size: 1.25rem; 36 - color: #666; 37 - margin: 0; 35 + font-size: 1.25rem; 36 + color: #666; 37 + margin: 0; 38 38 } 39 39 40 40 .footer { 41 - margin-top: 48px; 42 - text-align: center; 43 - color: #888; 41 + margin-top: 48px; 42 + text-align: center; 43 + color: #888; 44 44 } 45 45 46 46 /* Component styles */ 47 47 .prose { 48 - font-size: 1.125rem; 49 - color: #374151; 50 - line-height: 1.75; 48 + font-size: 1.125rem; 49 + color: #374151; 50 + line-height: 1.75; 51 51 } 52 52 53 53 /* Heading styles */ 54 54 .anchor-link { 55 - opacity: 0; 56 - transition: opacity 0.2s; 57 - text-decoration: none; 58 - color: #ba1f33; 55 + opacity: 0; 56 + transition: opacity 0.2s; 57 + text-decoration: none; 58 + color: #ba1f33; 59 59 } 60 60 h1:hover .anchor-link, 61 61 h2:hover .anchor-link, ··· 63 63 h4:hover .anchor-link, 64 64 h5:hover .anchor-link, 65 65 h6:hover .anchor-link { 66 - opacity: 1; 66 + opacity: 1; 67 67 } 68 68 69 69 /* Link styles */ 70 70 .external-link { 71 - color: #ba1f33; 72 - text-decoration: none; 71 + color: #ba1f33; 72 + text-decoration: none; 73 73 } 74 74 .external-link:hover { 75 - text-decoration: underline; 75 + text-decoration: underline; 76 76 } 77 77 .external-link::after { 78 - content: "↗"; 79 - color: #ba1f33; 78 + content: "↗"; 79 + color: #ba1f33; 80 80 } 81 81 82 82 .internal-link { 83 - color: #ba1f33; 84 - text-decoration: none; 83 + color: #ba1f33; 84 + text-decoration: none; 85 85 } 86 86 .internal-link:hover { 87 - text-decoration: underline; 87 + text-decoration: underline; 88 88 } 89 89 90 90 /* Image styles */ 91 91 .image-wrapper { 92 - margin: 24px 0; 93 - text-align: center; 92 + margin: 24px 0; 93 + text-align: center; 94 94 } 95 95 .responsive-image { 96 - max-width: 100%; 97 - height: auto; 98 - border-radius: 8px; 99 - box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); 96 + max-width: 100%; 97 + height: auto; 98 + border-radius: 8px; 99 + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); 100 100 } 101 101 .image-wrapper figcaption { 102 - margin-top: 8px; 103 - font-style: italic; 104 - color: #666; 105 - font-size: 0.9rem; 102 + margin-top: 8px; 103 + font-style: italic; 104 + color: #666; 105 + font-size: 0.9rem; 106 106 } 107 107 108 108 /* Strong and emphasis */ 109 109 .gradient-text { 110 - font-weight: bold; 111 - background: linear-gradient(to right, #ba1f33, #fa3252); 112 - -webkit-background-clip: text; 113 - -webkit-text-fill-color: transparent; 114 - background-clip: text; 110 + font-weight: bold; 111 + background: linear-gradient(to right, #ba1f33, #fa3252); 112 + -webkit-background-clip: text; 113 + -webkit-text-fill-color: transparent; 114 + background-clip: text; 115 115 } 116 116 117 117 .emphasis-text { 118 - font-style: italic; 119 - color: #ba1f33; 118 + font-style: italic; 119 + color: #ba1f33; 120 120 } 121 121 122 122 /* Code styles */ 123 123 .inline-code { 124 - background-color: #f3f4f6; 125 - color: #dc2626; 126 - padding: 2px 4px; 127 - border-radius: 4px; 128 - font-family: "SF Mono", Monaco, "Cascadia Code", "Roboto Mono", Consolas, 129 - "Courier New", monospace; 130 - font-size: 0.875rem; 124 + background-color: #f3f4f6; 125 + color: #dc2626; 126 + padding: 2px 4px; 127 + border-radius: 4px; 128 + font-family: 129 + "SF Mono", Monaco, "Cascadia Code", "Roboto Mono", Consolas, "Courier New", monospace; 130 + font-size: 0.875rem; 131 131 } 132 132 133 133 /* Code blocks */ 134 134 pre { 135 - background-color: #1a202c; 136 - color: #e2e8f0; 137 - padding: 16px; 138 - border-radius: 8px; 139 - overflow-x: auto; 140 - margin: 16px 0; 141 - border: 1px solid #2d3748; 135 + background-color: #1a202c; 136 + color: #e2e8f0; 137 + padding: 16px; 138 + border-radius: 8px; 139 + overflow-x: auto; 140 + margin: 16px 0; 141 + border: 1px solid #2d3748; 142 142 } 143 143 144 144 pre code { 145 - background: none; 146 - color: inherit; 147 - padding: 0; 148 - border-radius: 0; 149 - font-family: "SF Mono", Monaco, "Cascadia Code", "Roboto Mono", Consolas, 150 - "Courier New", monospace; 151 - font-size: 0.875rem; 152 - line-height: 1.5; 145 + background: none; 146 + color: inherit; 147 + padding: 0; 148 + border-radius: 0; 149 + font-family: 150 + "SF Mono", Monaco, "Cascadia Code", "Roboto Mono", Consolas, "Courier New", monospace; 151 + font-size: 0.875rem; 152 + line-height: 1.5; 153 153 } 154 154 155 155 /* Blockquote styles */ ··· 158 158 .blockquote-warning, 159 159 .blockquote-important, 160 160 .blockquote-caution { 161 - padding: 16px; 162 - margin: 16px 0; 163 - border-radius: 8px; 164 - display: flex; 165 - align-items: center; 166 - gap: 12px; 161 + padding: 16px; 162 + margin: 16px 0; 163 + border-radius: 8px; 164 + display: flex; 165 + align-items: center; 166 + gap: 12px; 167 167 } 168 168 169 169 .blockquote-note { 170 - border-left: 4px solid #3b82f6; 171 - background-color: #eff6ff; 170 + border-left: 4px solid #3b82f6; 171 + background-color: #eff6ff; 172 172 } 173 173 .blockquote-tip { 174 - border-left: 4px solid #10b981; 175 - background-color: #f0fdf4; 174 + border-left: 4px solid #10b981; 175 + background-color: #f0fdf4; 176 176 } 177 177 .blockquote-warning { 178 - border-left: 4px solid #f59e0b; 179 - background-color: #fffbeb; 178 + border-left: 4px solid #f59e0b; 179 + background-color: #fffbeb; 180 180 } 181 181 .blockquote-important { 182 - border-left: 4px solid #8b5cf6; 183 - background-color: #faf5ff; 182 + border-left: 4px solid #8b5cf6; 183 + background-color: #faf5ff; 184 184 } 185 185 .blockquote-caution { 186 - border-left: 4px solid #ef4444; 187 - background-color: #fef2f2; 186 + border-left: 4px solid #ef4444; 187 + background-color: #fef2f2; 188 188 } 189 189 .blockquote-default { 190 - border-left: 4px solid #9ca3af; 191 - background-color: #f9fafb; 192 - padding: 16px; 193 - margin: 16px 0; 194 - font-style: italic; 195 - border-radius: 8px; 190 + border-left: 4px solid #9ca3af; 191 + background-color: #f9fafb; 192 + padding: 16px; 193 + margin: 16px 0; 194 + font-style: italic; 195 + border-radius: 8px; 196 196 } 197 197 198 198 .blockquote-icon { 199 - font-size: 1.2em; 200 - line-height: 1; 201 - flex-shrink: 0; 202 - display: flex; 203 - align-items: center; 204 - justify-content: center; 199 + font-size: 1.2em; 200 + line-height: 1; 201 + flex-shrink: 0; 202 + display: flex; 203 + align-items: center; 204 + justify-content: center; 205 205 } 206 206 207 207 .blockquote-content { 208 - flex: 1; 209 - margin: 0; 208 + flex: 1; 209 + margin: 0; 210 210 } 211 211 212 212 .blockquote-content p { 213 - margin: 0; 213 + margin: 0; 214 214 } 215 215 216 216 /* List styles */ 217 217 .custom-list { 218 - margin: 16px 0; 219 - padding-left: 16px; 218 + margin: 16px 0; 219 + padding-left: 16px; 220 220 } 221 221 .custom-list li { 222 - margin: 8px 0; 223 - color: #374151; 224 - transition: color 0.2s; 222 + margin: 8px 0; 223 + color: #374151; 224 + transition: color 0.2s; 225 225 } 226 226 .custom-list li:hover { 227 - color: #1f2937; 227 + color: #1f2937; 228 228 } 229 229 230 230 /* Strikethrough */ 231 231 .strikethrough { 232 - text-decoration: line-through; 233 - color: #6b7280; 234 - opacity: 0.75; 232 + text-decoration: line-through; 233 + color: #6b7280; 234 + opacity: 0.75; 235 235 } 236 236 237 237 /* Task list */ 238 238 .task-checkbox { 239 - margin-right: 8px; 239 + margin-right: 8px; 240 240 } 241 241 .task-checkbox[checked] { 242 - accent-color: #ba1f33; 242 + accent-color: #ba1f33; 243 243 } 244 244 245 245 /* Table styles */ 246 246 .custom-table { 247 - width: 100%; 248 - border-collapse: separate; 249 - border-spacing: 0; 250 - border: 1px solid #d1d5db; 251 - border-radius: 8px; 252 - overflow: hidden; 253 - margin: 24px 0; 247 + width: 100%; 248 + border-collapse: separate; 249 + border-spacing: 0; 250 + border: 1px solid #d1d5db; 251 + border-radius: 8px; 252 + overflow: hidden; 253 + margin: 24px 0; 254 254 } 255 255 256 256 .table-header { 257 - background-color: #f9fafb; 257 + background-color: #f9fafb; 258 258 } 259 259 260 260 .table-header th { 261 - padding: 12px 24px; 262 - text-align: left; 263 - font-size: 0.75rem; 264 - font-weight: 500; 265 - color: #6b7280; 266 - text-transform: uppercase; 267 - letter-spacing: 0.05em; 261 + padding: 12px 24px; 262 + text-align: left; 263 + font-size: 0.75rem; 264 + font-weight: 500; 265 + color: #6b7280; 266 + text-transform: uppercase; 267 + letter-spacing: 0.05em; 268 268 } 269 269 270 270 .table-row { 271 - transition: background-color 0.2s; 271 + transition: background-color 0.2s; 272 272 } 273 273 .table-row:hover { 274 - background-color: #f9fafb; 274 + background-color: #f9fafb; 275 275 } 276 276 277 277 .table-cell { 278 - padding: 12px 24px; 279 - white-space: nowrap; 280 - font-size: 0.875rem; 281 - color: #1f2937; 278 + padding: 12px 24px; 279 + white-space: nowrap; 280 + font-size: 0.875rem; 281 + color: #1f2937; 282 282 } 283 283 284 284 .table-cell.center { 285 - text-align: center; 285 + text-align: center; 286 286 } 287 287 .table-cell.right { 288 - text-align: right; 288 + text-align: right; 289 289 } 290 290 291 291 /* Horizontal rule */ 292 292 .custom-hr { 293 - margin: 32px 0; 294 - border: none; 295 - height: 2px; 296 - background: linear-gradient(to right, #ba1f33, #fa3252); 293 + margin: 32px 0; 294 + border: none; 295 + height: 2px; 296 + background: linear-gradient(to right, #ba1f33, #fa3252); 297 297 } 298 298 299 299 /* Hard break */ 300 300 .hard-break { 301 - display: block; 302 - content: ""; 303 - margin: 8px 0; 301 + display: block; 302 + content: ""; 303 + margin: 8px 0; 304 304 }
-2
netlify.toml
··· 1 - [[plugins]] 2 - package = "netlify-plugin-debug-cache"
+21 -8
package.json
··· 1 1 { 2 2 "name": "root", 3 + "private": true, 3 4 "type": "module", 4 - "private": true, 5 - "packageManager": "pnpm@9.15.0+sha512.76e2379760a4328ec4415815bcd6628dee727af3779aaa4c914e3944156c4299921a89f976381ee107d41f12cfa4b66681ca9c718f0668fa0831ed4c6d8ba56c", 5 + "scripts": { 6 + "check": "pnpm run check:js && pnpm run check:rs", 7 + "check:ts": "tsgo", 8 + "check:rs": "cargo check", 9 + "lint": "pnpm run lint:ts && pnpm run lint:rs", 10 + "lint:ts": "oxlint --type-aware", 11 + "lint:rs": "cargo clippy", 12 + "lint:fix": "oxlint --fix --type-aware && cargo clippy --fix --allow-dirty --allow-staged", 13 + "format": "pnpm run format:ts && pnpm run format:rs", 14 + "format:ts": "oxfmt", 15 + "format:rs": "cargo fmt" 16 + }, 6 17 "dependencies": { 7 - "@tailwindcss/cli": "^4.0.0", 8 - "tailwindcss": "^4.0.0", 9 - "thumbhash": "^0.1.1" 18 + "@tailwindcss/cli": "^4.1.18", 19 + "tailwindcss": "^4.1.18" 10 20 }, 11 21 "devDependencies": { 12 - "netlify-plugin-debug-cache": "^1.0.4", 13 - "typescript": "^5.9.2" 14 - } 22 + "@typescript/native-preview": "7.0.0-dev.20260109.1", 23 + "oxfmt": "^0.23.0", 24 + "oxlint": "^1.38.0", 25 + "oxlint-tsgolint": "^0.11.0" 26 + }, 27 + "packageManager": "pnpm@10.28.0+sha512.05df71d1421f21399e053fde567cea34d446fa02c76571441bfc1c7956e98e363088982d940465fd34480d4d90a0668bc12362f8aa88000a64e83d0b0e47be48" 15 28 }
+577 -208
pnpm-lock.yaml
··· 9 9 .: 10 10 dependencies: 11 11 '@tailwindcss/cli': 12 - specifier: ^4.0.0 13 - version: 4.0.0 12 + specifier: ^4.1.18 13 + version: 4.1.18 14 14 tailwindcss: 15 - specifier: ^4.0.0 16 - version: 4.0.0 17 - thumbhash: 18 - specifier: ^0.1.1 19 - version: 0.1.1 15 + specifier: ^4.1.18 16 + version: 4.1.18 20 17 devDependencies: 21 - netlify-plugin-debug-cache: 22 - specifier: ^1.0.4 23 - version: 1.0.4 24 - typescript: 25 - specifier: ^5.9.2 26 - version: 5.9.2 18 + '@typescript/native-preview': 19 + specifier: 7.0.0-dev.20260109.1 20 + version: 7.0.0-dev.20260109.1 21 + oxfmt: 22 + specifier: ^0.23.0 23 + version: 0.23.0 24 + oxlint: 25 + specifier: ^1.38.0 26 + version: 1.38.0(oxlint-tsgolint@0.11.0) 27 + oxlint-tsgolint: 28 + specifier: ^0.11.0 29 + version: 0.11.0 30 + 31 + crates/maudit-cli: 32 + dependencies: 33 + ansi_up: 34 + specifier: ^6.0.6 35 + version: 6.0.6 27 36 28 37 packages: 29 38 30 - '@parcel/watcher-android-arm64@2.5.0': 31 - resolution: {integrity: sha512-qlX4eS28bUcQCdribHkg/herLe+0A9RyYC+mm2PXpncit8z5b3nSqGVzMNR3CmtAOgRutiZ02eIJJgP/b1iEFQ==} 39 + '@jridgewell/gen-mapping@0.3.13': 40 + resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} 41 + 42 + '@jridgewell/remapping@2.3.5': 43 + resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} 44 + 45 + '@jridgewell/resolve-uri@3.1.2': 46 + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} 47 + engines: {node: '>=6.0.0'} 48 + 49 + '@jridgewell/sourcemap-codec@1.5.5': 50 + resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} 51 + 52 + '@jridgewell/trace-mapping@0.3.31': 53 + resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} 54 + 55 + '@oxfmt/darwin-arm64@0.23.0': 56 + resolution: {integrity: sha512-shGng2EjBspvuqtFtcjcKf0WoZ9QCdL8iLYgdOoKSiSQ9pPyLJ4jQf62yhm4b2PpZNVcV/20gV6d8SyKzg6SZQ==} 57 + cpu: [arm64] 58 + os: [darwin] 59 + 60 + '@oxfmt/darwin-x64@0.23.0': 61 + resolution: {integrity: sha512-DxQ7Hm7B+6JiIkiRU3CSJmM15nTJDDezyaAv+x9NN8BfU0C49O8JuZIFu1Lr9AKEPV+ECIYM2X4HU0xm6IdiMQ==} 62 + cpu: [x64] 63 + os: [darwin] 64 + 65 + '@oxfmt/linux-arm64-gnu@0.23.0': 66 + resolution: {integrity: sha512-7qTXPpENi45sEKsaYFit4VRywPVkX+ZJc5JVA17KW1coJ/SLUuRAdLjRipU+QTZsr1TF93HCmGFSlUjB7lmEVQ==} 67 + cpu: [arm64] 68 + os: [linux] 69 + 70 + '@oxfmt/linux-arm64-musl@0.23.0': 71 + resolution: {integrity: sha512-qkFXbf+K01B++j69o9mLvvyfhmmL4+qX7hGPA2PRDkE5xxuUTWdqboQQc1FgGI0teUlIYYyxjamq9UztL2A7NA==} 72 + cpu: [arm64] 73 + os: [linux] 74 + 75 + '@oxfmt/linux-x64-gnu@0.23.0': 76 + resolution: {integrity: sha512-J7Q13Ujyn8IgjHD96urA377GOy8HerxC13OrEyYaM8iwH3gc/EoboK9AKu0bxp9qai4btPFDhnkRnpCwJE9pAw==} 77 + cpu: [x64] 78 + os: [linux] 79 + 80 + '@oxfmt/linux-x64-musl@0.23.0': 81 + resolution: {integrity: sha512-3gb25Zk2/y4An8fi399KdpLkDYFTJEB5Nq/sSHmeXG0pZlR/jnKoXEFHsjU+9nqF2wsuZ+tmkoi/swcaGG8+Qg==} 82 + cpu: [x64] 83 + os: [linux] 84 + 85 + '@oxfmt/win32-arm64@0.23.0': 86 + resolution: {integrity: sha512-JKfRP2ENWwRZ73rMZFyChvRi/+oDEW+3obp1XIwecot8gvDHgGZ4nX3hTp4VPiBFL89JORMpWSKzJvjRDucJIw==} 87 + cpu: [arm64] 88 + os: [win32] 89 + 90 + '@oxfmt/win32-x64@0.23.0': 91 + resolution: {integrity: sha512-vgqtYK1X1n/KexCNQKWXao3hyOnmWuCzk2sQyCSpkLhjSNIDPm7dmnEkvOXhf1t0O5RjCwHpk2VB6Fuaq3GULg==} 92 + cpu: [x64] 93 + os: [win32] 94 + 95 + '@oxlint-tsgolint/darwin-arm64@0.11.0': 96 + resolution: {integrity: sha512-F67T8dXgYIrgv6wpd52fKQFdmieSOHaxBkscgso64YdtEHrV3s52ASiZGNzw62TKihn9Ox9ek3PYx9XsxIJDUw==} 97 + cpu: [arm64] 98 + os: [darwin] 99 + 100 + '@oxlint-tsgolint/darwin-x64@0.11.0': 101 + resolution: {integrity: sha512-z44LO7+3z2mtcBxA9T66yEy/otp/2r5ypbkx7EYlPwbEqBAIDRt/8hqQ9/BUC//1qE549P1cBU6NjhgeyuXjYQ==} 102 + cpu: [x64] 103 + os: [darwin] 104 + 105 + '@oxlint-tsgolint/linux-arm64@0.11.0': 106 + resolution: {integrity: sha512-IeIjmpPi2j2Dn1CRizGikysyLp9B0q3jqiAalv9ewRyb8hqQW5YeMlsswo8pHd0Hz3KyFfone0NkvBt77Ex2pg==} 107 + cpu: [arm64] 108 + os: [linux] 109 + 110 + '@oxlint-tsgolint/linux-x64@0.11.0': 111 + resolution: {integrity: sha512-fpYGYU2pXjaXYnKgWrihFXE8zJiTRjYKSHAaBaVI056oqKjKGEoU2BfFbddpBrKgz9TmSOX/NGftrJnyMn1wXQ==} 112 + cpu: [x64] 113 + os: [linux] 114 + 115 + '@oxlint-tsgolint/win32-arm64@0.11.0': 116 + resolution: {integrity: sha512-37nzks9eqBt7NYE6okquu51vaqMruF5voX475L16Y8asJVCGpO/2VSy3ulYAXhZ+5Kdc8ZgrljVViJOjfPEPaA==} 117 + cpu: [arm64] 118 + os: [win32] 119 + 120 + '@oxlint-tsgolint/win32-x64@0.11.0': 121 + resolution: {integrity: sha512-TsK4C61+mjmbkUJ3Q3E9Ev3VFbeI6prPEAm9FAOq8VsfUGEiIUBBjrZ8ysGoQXNiU3dCKpmu012ptVUZTk5/eg==} 122 + cpu: [x64] 123 + os: [win32] 124 + 125 + '@oxlint/darwin-arm64@1.38.0': 126 + resolution: {integrity: sha512-9rN3047QTyA4i73FKikDUBdczRcLtOsIwZ5TsEx5Q7jr5nBjolhYQOFQf9QdhBLdInxw1iX4+lgdMCf1g74zjg==} 127 + cpu: [arm64] 128 + os: [darwin] 129 + 130 + '@oxlint/darwin-x64@1.38.0': 131 + resolution: {integrity: sha512-Y1UHW4KOlg5NvyrSn/bVBQP8/LRuid7Pnu+BWGbAVVsFcK0b565YgMSO3Eu9nU3w8ke91dr7NFpUmS+bVkdkbw==} 132 + cpu: [x64] 133 + os: [darwin] 134 + 135 + '@oxlint/linux-arm64-gnu@1.38.0': 136 + resolution: {integrity: sha512-ZiVxPZizlXSnAMdkEFWX/mAj7U3bNiku8p6I9UgLrXzgGSSAhFobx8CaFGwVoKyWOd+gQgZ/ogCrunvx2k0CFg==} 137 + cpu: [arm64] 138 + os: [linux] 139 + 140 + '@oxlint/linux-arm64-musl@1.38.0': 141 + resolution: {integrity: sha512-ELtlCIGZ72A65ATZZHFxHMFrkRtY+DYDCKiNKg6v7u5PdeOFey+OlqRXgXtXlxWjCL+g7nivwI2FPVsWqf05Qw==} 142 + cpu: [arm64] 143 + os: [linux] 144 + 145 + '@oxlint/linux-x64-gnu@1.38.0': 146 + resolution: {integrity: sha512-E1OcDh30qyng1m0EIlsOuapYkqk5QB6o6IMBjvDKqIoo6IrjlVAasoJfS/CmSH998gXRL3BcAJa6Qg9IxPFZnQ==} 147 + cpu: [x64] 148 + os: [linux] 149 + 150 + '@oxlint/linux-x64-musl@1.38.0': 151 + resolution: {integrity: sha512-4AfpbM/4sQnr6S1dMijEPfsq4stQbN5vJ2jsahSy/QTcvIVbFkgY+RIhrA5UWlC6eb0rD5CdaPQoKGMJGeXpYw==} 152 + cpu: [x64] 153 + os: [linux] 154 + 155 + '@oxlint/win32-arm64@1.38.0': 156 + resolution: {integrity: sha512-OvUVYdI68OwXh3d1RjH9N/okCxb6PrOGtEtzXyqGA7Gk+IxyZcX0/QCTBwV8FNbSSzDePSSEHOKpoIB+VXdtvg==} 157 + cpu: [arm64] 158 + os: [win32] 159 + 160 + '@oxlint/win32-x64@1.38.0': 161 + resolution: {integrity: sha512-7IuZMYiZiOcgg5zHvpJY6jRlEwh8EB/uq7GsoQJO9hANq96TIjyntGByhIjFSsL4asyZmhTEki+MO/u5Fb/WQA==} 162 + cpu: [x64] 163 + os: [win32] 164 + 165 + '@parcel/watcher-android-arm64@2.5.1': 166 + resolution: {integrity: sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA==} 32 167 engines: {node: '>= 10.0.0'} 33 168 cpu: [arm64] 34 169 os: [android] 35 170 36 - '@parcel/watcher-darwin-arm64@2.5.0': 37 - resolution: {integrity: sha512-hyZ3TANnzGfLpRA2s/4U1kbw2ZI4qGxaRJbBH2DCSREFfubMswheh8TeiC1sGZ3z2jUf3s37P0BBlrD3sjVTUw==} 171 + '@parcel/watcher-darwin-arm64@2.5.1': 172 + resolution: {integrity: sha512-eAzPv5osDmZyBhou8PoF4i6RQXAfeKL9tjb3QzYuccXFMQU0ruIc/POh30ePnaOyD1UXdlKguHBmsTs53tVoPw==} 38 173 engines: {node: '>= 10.0.0'} 39 174 cpu: [arm64] 40 175 os: [darwin] 41 176 42 - '@parcel/watcher-darwin-x64@2.5.0': 43 - resolution: {integrity: sha512-9rhlwd78saKf18fT869/poydQK8YqlU26TMiNg7AIu7eBp9adqbJZqmdFOsbZ5cnLp5XvRo9wcFmNHgHdWaGYA==} 177 + '@parcel/watcher-darwin-x64@2.5.1': 178 + resolution: {integrity: sha512-1ZXDthrnNmwv10A0/3AJNZ9JGlzrF82i3gNQcWOzd7nJ8aj+ILyW1MTxVk35Db0u91oD5Nlk9MBiujMlwmeXZg==} 44 179 engines: {node: '>= 10.0.0'} 45 180 cpu: [x64] 46 181 os: [darwin] 47 182 48 - '@parcel/watcher-freebsd-x64@2.5.0': 49 - resolution: {integrity: sha512-syvfhZzyM8kErg3VF0xpV8dixJ+RzbUaaGaeb7uDuz0D3FK97/mZ5AJQ3XNnDsXX7KkFNtyQyFrXZzQIcN49Tw==} 183 + '@parcel/watcher-freebsd-x64@2.5.1': 184 + resolution: {integrity: sha512-SI4eljM7Flp9yPuKi8W0ird8TI/JK6CSxju3NojVI6BjHsTyK7zxA9urjVjEKJ5MBYC+bLmMcbAWlZ+rFkLpJQ==} 50 185 engines: {node: '>= 10.0.0'} 51 186 cpu: [x64] 52 187 os: [freebsd] 53 188 54 - '@parcel/watcher-linux-arm-glibc@2.5.0': 55 - resolution: {integrity: sha512-0VQY1K35DQET3dVYWpOaPFecqOT9dbuCfzjxoQyif1Wc574t3kOSkKevULddcR9znz1TcklCE7Ht6NIxjvTqLA==} 189 + '@parcel/watcher-linux-arm-glibc@2.5.1': 190 + resolution: {integrity: sha512-RCdZlEyTs8geyBkkcnPWvtXLY44BCeZKmGYRtSgtwwnHR4dxfHRG3gR99XdMEdQ7KeiDdasJwwvNSF5jKtDwdA==} 56 191 engines: {node: '>= 10.0.0'} 57 192 cpu: [arm] 58 193 os: [linux] 59 194 60 - '@parcel/watcher-linux-arm-musl@2.5.0': 61 - resolution: {integrity: sha512-6uHywSIzz8+vi2lAzFeltnYbdHsDm3iIB57d4g5oaB9vKwjb6N6dRIgZMujw4nm5r6v9/BQH0noq6DzHrqr2pA==} 195 + '@parcel/watcher-linux-arm-musl@2.5.1': 196 + resolution: {integrity: sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q==} 62 197 engines: {node: '>= 10.0.0'} 63 198 cpu: [arm] 64 199 os: [linux] 65 200 66 - '@parcel/watcher-linux-arm64-glibc@2.5.0': 67 - resolution: {integrity: sha512-BfNjXwZKxBy4WibDb/LDCriWSKLz+jJRL3cM/DllnHH5QUyoiUNEp3GmL80ZqxeumoADfCCP19+qiYiC8gUBjA==} 201 + '@parcel/watcher-linux-arm64-glibc@2.5.1': 202 + resolution: {integrity: sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==} 68 203 engines: {node: '>= 10.0.0'} 69 204 cpu: [arm64] 70 205 os: [linux] 71 206 72 - '@parcel/watcher-linux-arm64-musl@2.5.0': 73 - resolution: {integrity: sha512-S1qARKOphxfiBEkwLUbHjCY9BWPdWnW9j7f7Hb2jPplu8UZ3nes7zpPOW9bkLbHRvWM0WDTsjdOTUgW0xLBN1Q==} 207 + '@parcel/watcher-linux-arm64-musl@2.5.1': 208 + resolution: {integrity: sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg==} 74 209 engines: {node: '>= 10.0.0'} 75 210 cpu: [arm64] 76 211 os: [linux] 77 212 78 - '@parcel/watcher-linux-x64-glibc@2.5.0': 79 - resolution: {integrity: sha512-d9AOkusyXARkFD66S6zlGXyzx5RvY+chTP9Jp0ypSTC9d4lzyRs9ovGf/80VCxjKddcUvnsGwCHWuF2EoPgWjw==} 213 + '@parcel/watcher-linux-x64-glibc@2.5.1': 214 + resolution: {integrity: sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A==} 80 215 engines: {node: '>= 10.0.0'} 81 216 cpu: [x64] 82 217 os: [linux] 83 218 84 - '@parcel/watcher-linux-x64-musl@2.5.0': 85 - resolution: {integrity: sha512-iqOC+GoTDoFyk/VYSFHwjHhYrk8bljW6zOhPuhi5t9ulqiYq1togGJB5e3PwYVFFfeVgc6pbz3JdQyDoBszVaA==} 219 + '@parcel/watcher-linux-x64-musl@2.5.1': 220 + resolution: {integrity: sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg==} 86 221 engines: {node: '>= 10.0.0'} 87 222 cpu: [x64] 88 223 os: [linux] 89 224 90 - '@parcel/watcher-win32-arm64@2.5.0': 91 - resolution: {integrity: sha512-twtft1d+JRNkM5YbmexfcH/N4znDtjgysFaV9zvZmmJezQsKpkfLYJ+JFV3uygugK6AtIM2oADPkB2AdhBrNig==} 225 + '@parcel/watcher-win32-arm64@2.5.1': 226 + resolution: {integrity: sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw==} 92 227 engines: {node: '>= 10.0.0'} 93 228 cpu: [arm64] 94 229 os: [win32] 95 230 96 - '@parcel/watcher-win32-ia32@2.5.0': 97 - resolution: {integrity: sha512-+rgpsNRKwo8A53elqbbHXdOMtY/tAtTzManTWShB5Kk54N8Q9mzNWV7tV+IbGueCbcj826MfWGU3mprWtuf1TA==} 231 + '@parcel/watcher-win32-ia32@2.5.1': 232 + resolution: {integrity: sha512-c2KkcVN+NJmuA7CGlaGD1qJh1cLfDnQsHjE89E60vUEMlqduHGCdCLJCID5geFVM0dOtA3ZiIO8BoEQmzQVfpQ==} 98 233 engines: {node: '>= 10.0.0'} 99 234 cpu: [ia32] 100 235 os: [win32] 101 236 102 - '@parcel/watcher-win32-x64@2.5.0': 103 - resolution: {integrity: sha512-lPrxve92zEHdgeff3aiu4gDOIt4u7sJYha6wbdEZDCDUhtjTsOMiaJzG5lMY4GkWH8p0fMmO2Ppq5G5XXG+DQw==} 237 + '@parcel/watcher-win32-x64@2.5.1': 238 + resolution: {integrity: sha512-9lHBdJITeNR++EvSQVUcaZoWupyHfXe1jZvGZ06O/5MflPcuPLtEphScIBL+AiCWBO46tDSHzWyD0uDmmZqsgA==} 104 239 engines: {node: '>= 10.0.0'} 105 240 cpu: [x64] 106 241 os: [win32] 107 242 108 - '@parcel/watcher@2.5.0': 109 - resolution: {integrity: sha512-i0GV1yJnm2n3Yq1qw6QrUrd/LI9bE8WEBOTtOkpCXHHdyN3TAGgqAK/DAT05z4fq2x04cARXt2pDmjWjL92iTQ==} 243 + '@parcel/watcher@2.5.1': 244 + resolution: {integrity: sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==} 110 245 engines: {node: '>= 10.0.0'} 111 246 112 - '@tailwindcss/cli@4.0.0': 113 - resolution: {integrity: sha512-nh6kzSTalHf9yk6WNsS4MMZakSINsncNQXsSJthvcPI4x+yajEaNQvS2uUti3PGLbsmlGoUvjhnGTBpzh7H0bA==} 247 + '@tailwindcss/cli@4.1.18': 248 + resolution: {integrity: sha512-sMZ+lZbDyxwjD2E0L7oRUjJ01Ffjtme5OtjvvnC+cV4CEDcbqzbp25TCpxHj6kWLU9+DlqJOiNgSOgctC2aZmg==} 114 249 hasBin: true 115 250 116 - '@tailwindcss/node@4.0.0': 117 - resolution: {integrity: sha512-tfG2uBvo6j6kDIPmntxwXggCOZAt7SkpAXJ6pTIYirNdk5FBqh/CZZ9BZPpgcl/tNFLs6zc4yghM76sqiELG9g==} 251 + '@tailwindcss/node@4.1.18': 252 + resolution: {integrity: sha512-DoR7U1P7iYhw16qJ49fgXUlry1t4CpXeErJHnQ44JgTSKMaZUdf17cfn5mHchfJ4KRBZRFA/Coo+MUF5+gOaCQ==} 118 253 119 - '@tailwindcss/oxide-android-arm64@4.0.0': 120 - resolution: {integrity: sha512-EAhjU0+FIdyGPR+7MbBWubLLPtmOu+p7c2egTTFBRk/n//zYjNvVK0WhcBK5Y7oUB5mo4EjA2mCbY7dcEMWSRw==} 254 + '@tailwindcss/oxide-android-arm64@4.1.18': 255 + resolution: {integrity: sha512-dJHz7+Ugr9U/diKJA0W6N/6/cjI+ZTAoxPf9Iz9BFRF2GzEX8IvXxFIi/dZBloVJX/MZGvRuFA9rqwdiIEZQ0Q==} 121 256 engines: {node: '>= 10'} 122 257 cpu: [arm64] 123 258 os: [android] 124 259 125 - '@tailwindcss/oxide-darwin-arm64@4.0.0': 126 - resolution: {integrity: sha512-hdz4xnSWS11cIp+7ye+3dGHqs0X33z+BXXTtgPOguDWVa+TdXUzwxonklSzf5wlJFuot3dv5eWzhlNai0oYYQg==} 260 + '@tailwindcss/oxide-darwin-arm64@4.1.18': 261 + resolution: {integrity: sha512-Gc2q4Qhs660bhjyBSKgq6BYvwDz4G+BuyJ5H1xfhmDR3D8HnHCmT/BSkvSL0vQLy/nkMLY20PQ2OoYMO15Jd0A==} 127 262 engines: {node: '>= 10'} 128 263 cpu: [arm64] 129 264 os: [darwin] 130 265 131 - '@tailwindcss/oxide-darwin-x64@4.0.0': 132 - resolution: {integrity: sha512-+dOUUaXTkPKKhtUI9QtVaYg+MpmLh2CN0dHohiYXaBirEyPMkjaT0zbRgzQlNnQWjCVVXPQluIEb0OMEjSTH+Q==} 266 + '@tailwindcss/oxide-darwin-x64@4.1.18': 267 + resolution: {integrity: sha512-FL5oxr2xQsFrc3X9o1fjHKBYBMD1QZNyc1Xzw/h5Qu4XnEBi3dZn96HcHm41c/euGV+GRiXFfh2hUCyKi/e+yw==} 133 268 engines: {node: '>= 10'} 134 269 cpu: [x64] 135 270 os: [darwin] 136 271 137 - '@tailwindcss/oxide-freebsd-x64@4.0.0': 138 - resolution: {integrity: sha512-CJhGDhxnrmu4SwyC62fA+wP24MhA/TZlIhRHqg1kRuIHoGoVR2uSSm1qxTxU37tSSZj8Up0q6jsBJCAP4k7rgQ==} 272 + '@tailwindcss/oxide-freebsd-x64@4.1.18': 273 + resolution: {integrity: sha512-Fj+RHgu5bDodmV1dM9yAxlfJwkkWvLiRjbhuO2LEtwtlYlBgiAT4x/j5wQr1tC3SANAgD+0YcmWVrj8R9trVMA==} 139 274 engines: {node: '>= 10'} 140 275 cpu: [x64] 141 276 os: [freebsd] 142 277 143 - '@tailwindcss/oxide-linux-arm-gnueabihf@4.0.0': 144 - resolution: {integrity: sha512-Wy7Av0xzXfY2ujZBcYy4+7GQm25/J1iHvlQU2CfwdDCuPWfIjYzR6kggz+uVdSJyKV2s64znchBxRE8kV4uXSA==} 278 + '@tailwindcss/oxide-linux-arm-gnueabihf@4.1.18': 279 + resolution: {integrity: sha512-Fp+Wzk/Ws4dZn+LV2Nqx3IilnhH51YZoRaYHQsVq3RQvEl+71VGKFpkfHrLM/Li+kt5c0DJe/bHXK1eHgDmdiA==} 145 280 engines: {node: '>= 10'} 146 281 cpu: [arm] 147 282 os: [linux] 148 283 149 - '@tailwindcss/oxide-linux-arm64-gnu@4.0.0': 150 - resolution: {integrity: sha512-srwBo2l6pvM0swBntc1ucuhGsfFOLkqPRFQ3dWARRTfSkL1U9nAsob2MKc/n47Eva/W9pZZgMOuf7rDw8pK1Ew==} 284 + '@tailwindcss/oxide-linux-arm64-gnu@4.1.18': 285 + resolution: {integrity: sha512-S0n3jboLysNbh55Vrt7pk9wgpyTTPD0fdQeh7wQfMqLPM/Hrxi+dVsLsPrycQjGKEQk85Kgbx+6+QnYNiHalnw==} 151 286 engines: {node: '>= 10'} 152 287 cpu: [arm64] 153 288 os: [linux] 154 289 155 - '@tailwindcss/oxide-linux-arm64-musl@4.0.0': 156 - resolution: {integrity: sha512-abhusswkduYWuezkBmgo0K0/erGq3M4Se5xP0fhc/0dKs0X/rJUYYCFWntHb3IGh3aVzdQ0SXJs93P76DbUqtw==} 290 + '@tailwindcss/oxide-linux-arm64-musl@4.1.18': 291 + resolution: {integrity: sha512-1px92582HkPQlaaCkdRcio71p8bc8i/ap5807tPRDK/uw953cauQBT8c5tVGkOwrHMfc2Yh6UuxaH4vtTjGvHg==} 157 292 engines: {node: '>= 10'} 158 293 cpu: [arm64] 159 294 os: [linux] 160 295 161 - '@tailwindcss/oxide-linux-x64-gnu@4.0.0': 162 - resolution: {integrity: sha512-hGtRYIUEx377/HlU49+jvVKKwU1MDSKYSMMs0JFO2Wp7LGxk5+0j5+RBk9NFnmp/lbp32yPTgIOO5m1BmDq36A==} 296 + '@tailwindcss/oxide-linux-x64-gnu@4.1.18': 297 + resolution: {integrity: sha512-v3gyT0ivkfBLoZGF9LyHmts0Isc8jHZyVcbzio6Wpzifg/+5ZJpDiRiUhDLkcr7f/r38SWNe7ucxmGW3j3Kb/g==} 163 298 engines: {node: '>= 10'} 164 299 cpu: [x64] 165 300 os: [linux] 166 301 167 - '@tailwindcss/oxide-linux-x64-musl@4.0.0': 168 - resolution: {integrity: sha512-7xgQgSAThs0I14VAgmxpJnK6XFSZBxHMGoDXkLyYkEnu+8WRQMbCP93dkCUn2PIv+Q+JulRgc00PJ09uORSLXQ==} 302 + '@tailwindcss/oxide-linux-x64-musl@4.1.18': 303 + resolution: {integrity: sha512-bhJ2y2OQNlcRwwgOAGMY0xTFStt4/wyU6pvI6LSuZpRgKQwxTec0/3Scu91O8ir7qCR3AuepQKLU/kX99FouqQ==} 169 304 engines: {node: '>= 10'} 170 305 cpu: [x64] 171 306 os: [linux] 172 307 173 - '@tailwindcss/oxide-win32-arm64-msvc@4.0.0': 174 - resolution: {integrity: sha512-qEcgTIPcWY5ZE7f6VxQ/JPrSFMcehzVIlZj7sGE3mVd5YWreAT+Fl1vSP8q2pjnWXn0avZG3Iw7a2hJQAm+fTQ==} 308 + '@tailwindcss/oxide-wasm32-wasi@4.1.18': 309 + resolution: {integrity: sha512-LffYTvPjODiP6PT16oNeUQJzNVyJl1cjIebq/rWWBF+3eDst5JGEFSc5cWxyRCJ0Mxl+KyIkqRxk1XPEs9x8TA==} 310 + engines: {node: '>=14.0.0'} 311 + cpu: [wasm32] 312 + bundledDependencies: 313 + - '@napi-rs/wasm-runtime' 314 + - '@emnapi/core' 315 + - '@emnapi/runtime' 316 + - '@tybys/wasm-util' 317 + - '@emnapi/wasi-threads' 318 + - tslib 319 + 320 + '@tailwindcss/oxide-win32-arm64-msvc@4.1.18': 321 + resolution: {integrity: sha512-HjSA7mr9HmC8fu6bdsZvZ+dhjyGCLdotjVOgLA2vEqxEBZaQo9YTX4kwgEvPCpRh8o4uWc4J/wEoFzhEmjvPbA==} 175 322 engines: {node: '>= 10'} 176 323 cpu: [arm64] 177 324 os: [win32] 178 325 179 - '@tailwindcss/oxide-win32-x64-msvc@4.0.0': 180 - resolution: {integrity: sha512-bqT0AY8RXb8GMDy28JtngvqaOSB2YixbLPLvUo6I6lkvvUwA6Eqh2Tj60e2Lh7O/k083f8tYiB0WEK4wmTI7Jg==} 326 + '@tailwindcss/oxide-win32-x64-msvc@4.1.18': 327 + resolution: {integrity: sha512-bJWbyYpUlqamC8dpR7pfjA0I7vdF6t5VpUGMWRkXVE3AXgIZjYUYAK7II1GNaxR8J1SSrSrppRar8G++JekE3Q==} 181 328 engines: {node: '>= 10'} 182 329 cpu: [x64] 183 330 os: [win32] 184 331 185 - '@tailwindcss/oxide@4.0.0': 186 - resolution: {integrity: sha512-W3FjpJgy4VV1JiL7iBYDf2n/WkeDg1Il+0Q7eWnqPyvkPPCo/Mbwc5BiaT7dfBNV6tQKAhVE34rU5xl8pSl50w==} 332 + '@tailwindcss/oxide@4.1.18': 333 + resolution: {integrity: sha512-EgCR5tTS5bUSKQgzeMClT6iCY3ToqE1y+ZB0AKldj809QXk1Y+3jB0upOYZrn9aGIzPtUsP7sX4QQ4XtjBB95A==} 187 334 engines: {node: '>= 10'} 188 335 336 + '@typescript/native-preview-darwin-arm64@7.0.0-dev.20260109.1': 337 + resolution: {integrity: sha512-rEY7JFH9JhIQ7SCjD+cpwPhIBLzNOgA7IVkfIcOpbWTmtOufx0sTZejR5B2b81x2fLCJDPZGpUv71wD1LP45iA==} 338 + cpu: [arm64] 339 + os: [darwin] 340 + 341 + '@typescript/native-preview-darwin-x64@7.0.0-dev.20260109.1': 342 + resolution: {integrity: sha512-zBrxf4LYMhLGimvEZHJjtpYnpSqV4Q0rOkXEi8I5durn9NaGIBTOebBYXwF8/na6Pufdqd+vI1KQYxkm2G02pw==} 343 + cpu: [x64] 344 + os: [darwin] 345 + 346 + '@typescript/native-preview-linux-arm64@7.0.0-dev.20260109.1': 347 + resolution: {integrity: sha512-WeDI+wrA1GqBFwFzj9i/zXlOuUaJdKidg6Jgry1P1TNpsHYW5YiKoNcpFirm1Fq3Dnav5cAa66z6VK5lvz7tgQ==} 348 + cpu: [arm64] 349 + os: [linux] 350 + 351 + '@typescript/native-preview-linux-arm@7.0.0-dev.20260109.1': 352 + resolution: {integrity: sha512-J8kHoVttxNeMq1wdT12HPe6i/524svbdw1RsMBgb+kbqTfFFElSK7rbeZFuTfzpEA0/c6y2MY96qLP07Fq4zEw==} 353 + cpu: [arm] 354 + os: [linux] 355 + 356 + '@typescript/native-preview-linux-x64@7.0.0-dev.20260109.1': 357 + resolution: {integrity: sha512-D0nuBsJTIfc1JD2HyoMKqc2Wpe0tMAP92hgwap6E3iTlKFMW9ayd7KLUjLz6EFxxw9LRw2sjECT1VvjCjAJ4GQ==} 358 + cpu: [x64] 359 + os: [linux] 360 + 361 + '@typescript/native-preview-win32-arm64@7.0.0-dev.20260109.1': 362 + resolution: {integrity: sha512-nv365W1TiJEAAJ/NiBaKE9hSvG7U7ipuAoaSdr6HzdyMVouArq2DxxLo06mzDMOjNdc6U7vAIkLB52CcK3Y8ZQ==} 363 + cpu: [arm64] 364 + os: [win32] 365 + 366 + '@typescript/native-preview-win32-x64@7.0.0-dev.20260109.1': 367 + resolution: {integrity: sha512-da44CbC8ktr741ISLvCQlz3Gv2UqO2M+rB585xCFNjcz+0IyOKkBGr9eR++f6uy46/QKFK4w44x0cK71PVqk9g==} 368 + cpu: [x64] 369 + os: [win32] 370 + 371 + '@typescript/native-preview@7.0.0-dev.20260109.1': 372 + resolution: {integrity: sha512-27XQhOQWcGp7/nOS1NbEoC4vA2dZOmG5X+OP4e5KX2uAUc2cjE1Scn1Nnv9D7wU2ZBA+/wrqqvJqidCPFRlq+A==} 373 + hasBin: true 374 + 375 + ansi_up@6.0.6: 376 + resolution: {integrity: sha512-yIa1x3Ecf8jWP4UWEunNjqNX6gzE4vg2gGz+xqRGY+TBSucnYp6RRdPV4brmtg6bQ1ljD48mZ5iGSEj7QEpRKA==} 377 + 189 378 braces@3.0.3: 190 379 resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} 191 380 engines: {node: '>=8'} ··· 195 384 engines: {node: '>=0.10'} 196 385 hasBin: true 197 386 198 - enhanced-resolve@5.18.0: 199 - resolution: {integrity: sha512-0/r0MySGYG8YqlayBZ6MuCfECmHFdJ5qyPh8s8wa5Hnm6SaFLSK1VYCbj+NKp090Nm1caZhD+QTnmxO7esYGyQ==} 387 + detect-libc@2.1.2: 388 + resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} 389 + engines: {node: '>=8'} 390 + 391 + enhanced-resolve@5.18.4: 392 + resolution: {integrity: sha512-LgQMM4WXU3QI+SYgEc2liRgznaD5ojbmY3sb8LxyguVkIg5FxdpTkvk72te2R38/TGKxH634oLxXRGY6d7AP+Q==} 200 393 engines: {node: '>=10.13.0'} 201 394 202 395 fill-range@7.1.1: ··· 218 411 resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} 219 412 engines: {node: '>=0.12.0'} 220 413 221 - jiti@2.4.2: 222 - resolution: {integrity: sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==} 414 + jiti@2.6.1: 415 + resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==} 223 416 hasBin: true 224 417 225 - lightningcss-darwin-arm64@1.29.1: 226 - resolution: {integrity: sha512-HtR5XJ5A0lvCqYAoSv2QdZZyoHNttBpa5EP9aNuzBQeKGfbyH5+UipLWvVzpP4Uml5ej4BYs5I9Lco9u1fECqw==} 418 + lightningcss-android-arm64@1.30.2: 419 + resolution: {integrity: sha512-BH9sEdOCahSgmkVhBLeU7Hc9DWeZ1Eb6wNS6Da8igvUwAe0sqROHddIlvU06q3WyXVEOYDZ6ykBZQnjTbmo4+A==} 420 + engines: {node: '>= 12.0.0'} 421 + cpu: [arm64] 422 + os: [android] 423 + 424 + lightningcss-darwin-arm64@1.30.2: 425 + resolution: {integrity: sha512-ylTcDJBN3Hp21TdhRT5zBOIi73P6/W0qwvlFEk22fkdXchtNTOU4Qc37SkzV+EKYxLouZ6M4LG9NfZ1qkhhBWA==} 227 426 engines: {node: '>= 12.0.0'} 228 427 cpu: [arm64] 229 428 os: [darwin] 230 429 231 - lightningcss-darwin-x64@1.29.1: 232 - resolution: {integrity: sha512-k33G9IzKUpHy/J/3+9MCO4e+PzaFblsgBjSGlpAaFikeBFm8B/CkO3cKU9oI4g+fjS2KlkLM/Bza9K/aw8wsNA==} 430 + lightningcss-darwin-x64@1.30.2: 431 + resolution: {integrity: sha512-oBZgKchomuDYxr7ilwLcyms6BCyLn0z8J0+ZZmfpjwg9fRVZIR5/GMXd7r9RH94iDhld3UmSjBM6nXWM2TfZTQ==} 233 432 engines: {node: '>= 12.0.0'} 234 433 cpu: [x64] 235 434 os: [darwin] 236 435 237 - lightningcss-freebsd-x64@1.29.1: 238 - resolution: {integrity: sha512-0SUW22fv/8kln2LnIdOCmSuXnxgxVC276W5KLTwoehiO0hxkacBxjHOL5EtHD8BAXg2BvuhsJPmVMasvby3LiQ==} 436 + lightningcss-freebsd-x64@1.30.2: 437 + resolution: {integrity: sha512-c2bH6xTrf4BDpK8MoGG4Bd6zAMZDAXS569UxCAGcA7IKbHNMlhGQ89eRmvpIUGfKWNVdbhSbkQaWhEoMGmGslA==} 239 438 engines: {node: '>= 12.0.0'} 240 439 cpu: [x64] 241 440 os: [freebsd] 242 441 243 - lightningcss-linux-arm-gnueabihf@1.29.1: 244 - resolution: {integrity: sha512-sD32pFvlR0kDlqsOZmYqH/68SqUMPNj+0pucGxToXZi4XZgZmqeX/NkxNKCPsswAXU3UeYgDSpGhu05eAufjDg==} 442 + lightningcss-linux-arm-gnueabihf@1.30.2: 443 + resolution: {integrity: sha512-eVdpxh4wYcm0PofJIZVuYuLiqBIakQ9uFZmipf6LF/HRj5Bgm0eb3qL/mr1smyXIS1twwOxNWndd8z0E374hiA==} 245 444 engines: {node: '>= 12.0.0'} 246 445 cpu: [arm] 247 446 os: [linux] 248 447 249 - lightningcss-linux-arm64-gnu@1.29.1: 250 - resolution: {integrity: sha512-0+vClRIZ6mmJl/dxGuRsE197o1HDEeeRk6nzycSy2GofC2JsY4ifCRnvUWf/CUBQmlrvMzt6SMQNMSEu22csWQ==} 448 + lightningcss-linux-arm64-gnu@1.30.2: 449 + resolution: {integrity: sha512-UK65WJAbwIJbiBFXpxrbTNArtfuznvxAJw4Q2ZGlU8kPeDIWEX1dg3rn2veBVUylA2Ezg89ktszWbaQnxD/e3A==} 251 450 engines: {node: '>= 12.0.0'} 252 451 cpu: [arm64] 253 452 os: [linux] 254 453 255 - lightningcss-linux-arm64-musl@1.29.1: 256 - resolution: {integrity: sha512-UKMFrG4rL/uHNgelBsDwJcBqVpzNJbzsKkbI3Ja5fg00sgQnHw/VrzUTEc4jhZ+AN2BvQYz/tkHu4vt1kLuJyw==} 454 + lightningcss-linux-arm64-musl@1.30.2: 455 + resolution: {integrity: sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA==} 257 456 engines: {node: '>= 12.0.0'} 258 457 cpu: [arm64] 259 458 os: [linux] 260 459 261 - lightningcss-linux-x64-gnu@1.29.1: 262 - resolution: {integrity: sha512-u1S+xdODy/eEtjADqirA774y3jLcm8RPtYztwReEXoZKdzgsHYPl0s5V52Tst+GKzqjebkULT86XMSxejzfISw==} 460 + lightningcss-linux-x64-gnu@1.30.2: 461 + resolution: {integrity: sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w==} 263 462 engines: {node: '>= 12.0.0'} 264 463 cpu: [x64] 265 464 os: [linux] 266 465 267 - lightningcss-linux-x64-musl@1.29.1: 268 - resolution: {integrity: sha512-L0Tx0DtaNUTzXv0lbGCLB/c/qEADanHbu4QdcNOXLIe1i8i22rZRpbT3gpWYsCh9aSL9zFujY/WmEXIatWvXbw==} 466 + lightningcss-linux-x64-musl@1.30.2: 467 + resolution: {integrity: sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA==} 269 468 engines: {node: '>= 12.0.0'} 270 469 cpu: [x64] 271 470 os: [linux] 272 471 273 - lightningcss-win32-arm64-msvc@1.29.1: 274 - resolution: {integrity: sha512-QoOVnkIEFfbW4xPi+dpdft/zAKmgLgsRHfJalEPYuJDOWf7cLQzYg0DEh8/sn737FaeMJxHZRc1oBreiwZCjog==} 472 + lightningcss-win32-arm64-msvc@1.30.2: 473 + resolution: {integrity: sha512-FZn+vaj7zLv//D/192WFFVA0RgHawIcHqLX9xuWiQt7P0PtdFEVaxgF9rjM/IRYHQXNnk61/H/gb2Ei+kUQ4xQ==} 275 474 engines: {node: '>= 12.0.0'} 276 475 cpu: [arm64] 277 476 os: [win32] 278 477 279 - lightningcss-win32-x64-msvc@1.29.1: 280 - resolution: {integrity: sha512-NygcbThNBe4JElP+olyTI/doBNGJvLs3bFCRPdvuCcxZCcCZ71B858IHpdm7L1btZex0FvCmM17FK98Y9MRy1Q==} 478 + lightningcss-win32-x64-msvc@1.30.2: 479 + resolution: {integrity: sha512-5g1yc73p+iAkid5phb4oVFMB45417DkRevRbt/El/gKXJk4jid+vPFF/AXbxn05Aky8PapwzZrdJShv5C0avjw==} 281 480 engines: {node: '>= 12.0.0'} 282 481 cpu: [x64] 283 482 os: [win32] 284 483 285 - lightningcss@1.29.1: 286 - resolution: {integrity: sha512-FmGoeD4S05ewj+AkhTY+D+myDvXI6eL27FjHIjoyUkO/uw7WZD1fBVs0QxeYWa7E17CUHJaYX/RUGISCtcrG4Q==} 484 + lightningcss@1.30.2: 485 + resolution: {integrity: sha512-utfs7Pr5uJyyvDETitgsaqSyjCb2qNRAtuqUeWIAKztsOYdcACf2KtARYXg2pSvhkt+9NfoaNY7fxjl6nuMjIQ==} 287 486 engines: {node: '>= 12.0.0'} 288 487 289 - make-dir@3.1.0: 290 - resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==} 291 - engines: {node: '>=8'} 488 + magic-string@0.30.21: 489 + resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} 292 490 293 491 micromatch@4.0.8: 294 492 resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} ··· 298 496 resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} 299 497 engines: {node: '>=4'} 300 498 301 - netlify-plugin-debug-cache@1.0.4: 302 - resolution: {integrity: sha512-a9yBPnQlsDaNO8iPiSVxpiFnz3gj8BkhXRwT6bshLMCQRVezf/uIChTB55L675t6mZj+U4PwVIc7u8X2Ptc2Fw==} 303 - 304 499 node-addon-api@7.1.1: 305 500 resolution: {integrity: sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==} 306 501 502 + oxfmt@0.23.0: 503 + resolution: {integrity: sha512-dh4rlNBua93aVf2ZaDecbQxVLMnUUTvDi1K1fdvBdontQeEf6K22Z1KQg5QKl2D9aNFeFph+wOVwcjjYUIO6Mw==} 504 + engines: {node: ^20.19.0 || >=22.12.0} 505 + hasBin: true 506 + 507 + oxlint-tsgolint@0.11.0: 508 + resolution: {integrity: sha512-fGYb7z/cljC0Rjtbxh7mIe8vtF/M9TShLvniwc2rdcqNG3Z9g3nM01cr2kWRb1DZdbY4/kItvIsrV4uhaMifyQ==} 509 + hasBin: true 510 + 511 + oxlint@1.38.0: 512 + resolution: {integrity: sha512-XT7tBinQS+hVLxtfJOnokJ9qVBiQvZqng40tDgR6qEJMRMnpVq/JwYfbYyGntSq8MO+Y+N9M1NG4bAMFUtCJiw==} 513 + engines: {node: ^20.19.0 || >=22.12.0} 514 + hasBin: true 515 + peerDependencies: 516 + oxlint-tsgolint: '>=0.10.0' 517 + peerDependenciesMeta: 518 + oxlint-tsgolint: 519 + optional: true 520 + 307 521 picocolors@1.1.1: 308 522 resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} 309 523 ··· 311 525 resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} 312 526 engines: {node: '>=8.6'} 313 527 314 - semver@6.3.1: 315 - resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} 316 - hasBin: true 528 + source-map-js@1.2.1: 529 + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} 530 + engines: {node: '>=0.10.0'} 317 531 318 - tailwindcss@4.0.0: 319 - resolution: {integrity: sha512-ULRPI3A+e39T7pSaf1xoi58AqqJxVCLg8F/uM5A3FadUbnyDTgltVnXJvdkTjwCOGA6NazqHVcwPJC5h2vRYVQ==} 532 + tailwindcss@4.1.18: 533 + resolution: {integrity: sha512-4+Z+0yiYyEtUVCScyfHCxOYP06L5Ne+JiHhY2IjR2KWMIWhJOYZKLSGZaP5HkZ8+bY0cxfzwDE5uOmzFXyIwxw==} 320 534 321 535 tapable@2.2.1: 322 536 resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} 323 537 engines: {node: '>=6'} 324 538 325 - thumbhash@0.1.1: 326 - resolution: {integrity: sha512-kH5pKeIIBPQXAOni2AiY/Cu/NKdkFREdpH+TLdM0g6WA7RriCv0kPLgP731ady67MhTAqrVG/4mnEeibVuCJcg==} 539 + tinypool@2.0.0: 540 + resolution: {integrity: sha512-/RX9RzeH2xU5ADE7n2Ykvmi9ED3FBGPAjw9u3zucrNNaEBIO0HPSYgL0NT7+3p147ojeSdaVu08F6hjpv31HJg==} 541 + engines: {node: ^20.0.0 || >=22.0.0} 327 542 328 543 to-regex-range@5.0.1: 329 544 resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} 330 545 engines: {node: '>=8.0'} 331 - 332 - typescript@5.9.2: 333 - resolution: {integrity: sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==} 334 - engines: {node: '>=14.17'} 335 - hasBin: true 336 546 337 547 snapshots: 338 548 339 - '@parcel/watcher-android-arm64@2.5.0': 549 + '@jridgewell/gen-mapping@0.3.13': 550 + dependencies: 551 + '@jridgewell/sourcemap-codec': 1.5.5 552 + '@jridgewell/trace-mapping': 0.3.31 553 + 554 + '@jridgewell/remapping@2.3.5': 555 + dependencies: 556 + '@jridgewell/gen-mapping': 0.3.13 557 + '@jridgewell/trace-mapping': 0.3.31 558 + 559 + '@jridgewell/resolve-uri@3.1.2': {} 560 + 561 + '@jridgewell/sourcemap-codec@1.5.5': {} 562 + 563 + '@jridgewell/trace-mapping@0.3.31': 564 + dependencies: 565 + '@jridgewell/resolve-uri': 3.1.2 566 + '@jridgewell/sourcemap-codec': 1.5.5 567 + 568 + '@oxfmt/darwin-arm64@0.23.0': 340 569 optional: true 341 570 342 - '@parcel/watcher-darwin-arm64@2.5.0': 571 + '@oxfmt/darwin-x64@0.23.0': 572 + optional: true 573 + 574 + '@oxfmt/linux-arm64-gnu@0.23.0': 575 + optional: true 576 + 577 + '@oxfmt/linux-arm64-musl@0.23.0': 578 + optional: true 579 + 580 + '@oxfmt/linux-x64-gnu@0.23.0': 343 581 optional: true 344 582 345 - '@parcel/watcher-darwin-x64@2.5.0': 583 + '@oxfmt/linux-x64-musl@0.23.0': 346 584 optional: true 347 585 348 - '@parcel/watcher-freebsd-x64@2.5.0': 586 + '@oxfmt/win32-arm64@0.23.0': 349 587 optional: true 350 588 351 - '@parcel/watcher-linux-arm-glibc@2.5.0': 589 + '@oxfmt/win32-x64@0.23.0': 352 590 optional: true 353 591 354 - '@parcel/watcher-linux-arm-musl@2.5.0': 592 + '@oxlint-tsgolint/darwin-arm64@0.11.0': 355 593 optional: true 356 594 357 - '@parcel/watcher-linux-arm64-glibc@2.5.0': 595 + '@oxlint-tsgolint/darwin-x64@0.11.0': 358 596 optional: true 359 597 360 - '@parcel/watcher-linux-arm64-musl@2.5.0': 598 + '@oxlint-tsgolint/linux-arm64@0.11.0': 361 599 optional: true 362 600 363 - '@parcel/watcher-linux-x64-glibc@2.5.0': 601 + '@oxlint-tsgolint/linux-x64@0.11.0': 364 602 optional: true 365 603 366 - '@parcel/watcher-linux-x64-musl@2.5.0': 604 + '@oxlint-tsgolint/win32-arm64@0.11.0': 367 605 optional: true 368 606 369 - '@parcel/watcher-win32-arm64@2.5.0': 607 + '@oxlint-tsgolint/win32-x64@0.11.0': 370 608 optional: true 371 609 372 - '@parcel/watcher-win32-ia32@2.5.0': 610 + '@oxlint/darwin-arm64@1.38.0': 373 611 optional: true 374 612 375 - '@parcel/watcher-win32-x64@2.5.0': 613 + '@oxlint/darwin-x64@1.38.0': 376 614 optional: true 377 615 378 - '@parcel/watcher@2.5.0': 616 + '@oxlint/linux-arm64-gnu@1.38.0': 617 + optional: true 618 + 619 + '@oxlint/linux-arm64-musl@1.38.0': 620 + optional: true 621 + 622 + '@oxlint/linux-x64-gnu@1.38.0': 623 + optional: true 624 + 625 + '@oxlint/linux-x64-musl@1.38.0': 626 + optional: true 627 + 628 + '@oxlint/win32-arm64@1.38.0': 629 + optional: true 630 + 631 + '@oxlint/win32-x64@1.38.0': 632 + optional: true 633 + 634 + '@parcel/watcher-android-arm64@2.5.1': 635 + optional: true 636 + 637 + '@parcel/watcher-darwin-arm64@2.5.1': 638 + optional: true 639 + 640 + '@parcel/watcher-darwin-x64@2.5.1': 641 + optional: true 642 + 643 + '@parcel/watcher-freebsd-x64@2.5.1': 644 + optional: true 645 + 646 + '@parcel/watcher-linux-arm-glibc@2.5.1': 647 + optional: true 648 + 649 + '@parcel/watcher-linux-arm-musl@2.5.1': 650 + optional: true 651 + 652 + '@parcel/watcher-linux-arm64-glibc@2.5.1': 653 + optional: true 654 + 655 + '@parcel/watcher-linux-arm64-musl@2.5.1': 656 + optional: true 657 + 658 + '@parcel/watcher-linux-x64-glibc@2.5.1': 659 + optional: true 660 + 661 + '@parcel/watcher-linux-x64-musl@2.5.1': 662 + optional: true 663 + 664 + '@parcel/watcher-win32-arm64@2.5.1': 665 + optional: true 666 + 667 + '@parcel/watcher-win32-ia32@2.5.1': 668 + optional: true 669 + 670 + '@parcel/watcher-win32-x64@2.5.1': 671 + optional: true 672 + 673 + '@parcel/watcher@2.5.1': 379 674 dependencies: 380 675 detect-libc: 1.0.3 381 676 is-glob: 4.0.3 382 677 micromatch: 4.0.8 383 678 node-addon-api: 7.1.1 384 679 optionalDependencies: 385 - '@parcel/watcher-android-arm64': 2.5.0 386 - '@parcel/watcher-darwin-arm64': 2.5.0 387 - '@parcel/watcher-darwin-x64': 2.5.0 388 - '@parcel/watcher-freebsd-x64': 2.5.0 389 - '@parcel/watcher-linux-arm-glibc': 2.5.0 390 - '@parcel/watcher-linux-arm-musl': 2.5.0 391 - '@parcel/watcher-linux-arm64-glibc': 2.5.0 392 - '@parcel/watcher-linux-arm64-musl': 2.5.0 393 - '@parcel/watcher-linux-x64-glibc': 2.5.0 394 - '@parcel/watcher-linux-x64-musl': 2.5.0 395 - '@parcel/watcher-win32-arm64': 2.5.0 396 - '@parcel/watcher-win32-ia32': 2.5.0 397 - '@parcel/watcher-win32-x64': 2.5.0 680 + '@parcel/watcher-android-arm64': 2.5.1 681 + '@parcel/watcher-darwin-arm64': 2.5.1 682 + '@parcel/watcher-darwin-x64': 2.5.1 683 + '@parcel/watcher-freebsd-x64': 2.5.1 684 + '@parcel/watcher-linux-arm-glibc': 2.5.1 685 + '@parcel/watcher-linux-arm-musl': 2.5.1 686 + '@parcel/watcher-linux-arm64-glibc': 2.5.1 687 + '@parcel/watcher-linux-arm64-musl': 2.5.1 688 + '@parcel/watcher-linux-x64-glibc': 2.5.1 689 + '@parcel/watcher-linux-x64-musl': 2.5.1 690 + '@parcel/watcher-win32-arm64': 2.5.1 691 + '@parcel/watcher-win32-ia32': 2.5.1 692 + '@parcel/watcher-win32-x64': 2.5.1 398 693 399 - '@tailwindcss/cli@4.0.0': 694 + '@tailwindcss/cli@4.1.18': 400 695 dependencies: 401 - '@parcel/watcher': 2.5.0 402 - '@tailwindcss/node': 4.0.0 403 - '@tailwindcss/oxide': 4.0.0 404 - enhanced-resolve: 5.18.0 405 - lightningcss: 1.29.1 696 + '@parcel/watcher': 2.5.1 697 + '@tailwindcss/node': 4.1.18 698 + '@tailwindcss/oxide': 4.1.18 699 + enhanced-resolve: 5.18.4 406 700 mri: 1.2.0 407 701 picocolors: 1.1.1 408 - tailwindcss: 4.0.0 702 + tailwindcss: 4.1.18 409 703 410 - '@tailwindcss/node@4.0.0': 704 + '@tailwindcss/node@4.1.18': 411 705 dependencies: 412 - enhanced-resolve: 5.18.0 413 - jiti: 2.4.2 414 - tailwindcss: 4.0.0 706 + '@jridgewell/remapping': 2.3.5 707 + enhanced-resolve: 5.18.4 708 + jiti: 2.6.1 709 + lightningcss: 1.30.2 710 + magic-string: 0.30.21 711 + source-map-js: 1.2.1 712 + tailwindcss: 4.1.18 713 + 714 + '@tailwindcss/oxide-android-arm64@4.1.18': 715 + optional: true 415 716 416 - '@tailwindcss/oxide-android-arm64@4.0.0': 717 + '@tailwindcss/oxide-darwin-arm64@4.1.18': 417 718 optional: true 418 719 419 - '@tailwindcss/oxide-darwin-arm64@4.0.0': 720 + '@tailwindcss/oxide-darwin-x64@4.1.18': 420 721 optional: true 421 722 422 - '@tailwindcss/oxide-darwin-x64@4.0.0': 723 + '@tailwindcss/oxide-freebsd-x64@4.1.18': 423 724 optional: true 424 725 425 - '@tailwindcss/oxide-freebsd-x64@4.0.0': 726 + '@tailwindcss/oxide-linux-arm-gnueabihf@4.1.18': 426 727 optional: true 427 728 428 - '@tailwindcss/oxide-linux-arm-gnueabihf@4.0.0': 729 + '@tailwindcss/oxide-linux-arm64-gnu@4.1.18': 429 730 optional: true 430 731 431 - '@tailwindcss/oxide-linux-arm64-gnu@4.0.0': 732 + '@tailwindcss/oxide-linux-arm64-musl@4.1.18': 432 733 optional: true 433 734 434 - '@tailwindcss/oxide-linux-arm64-musl@4.0.0': 735 + '@tailwindcss/oxide-linux-x64-gnu@4.1.18': 435 736 optional: true 436 737 437 - '@tailwindcss/oxide-linux-x64-gnu@4.0.0': 738 + '@tailwindcss/oxide-linux-x64-musl@4.1.18': 438 739 optional: true 439 740 440 - '@tailwindcss/oxide-linux-x64-musl@4.0.0': 741 + '@tailwindcss/oxide-wasm32-wasi@4.1.18': 441 742 optional: true 442 743 443 - '@tailwindcss/oxide-win32-arm64-msvc@4.0.0': 744 + '@tailwindcss/oxide-win32-arm64-msvc@4.1.18': 444 745 optional: true 445 746 446 - '@tailwindcss/oxide-win32-x64-msvc@4.0.0': 747 + '@tailwindcss/oxide-win32-x64-msvc@4.1.18': 447 748 optional: true 448 749 449 - '@tailwindcss/oxide@4.0.0': 750 + '@tailwindcss/oxide@4.1.18': 450 751 optionalDependencies: 451 - '@tailwindcss/oxide-android-arm64': 4.0.0 452 - '@tailwindcss/oxide-darwin-arm64': 4.0.0 453 - '@tailwindcss/oxide-darwin-x64': 4.0.0 454 - '@tailwindcss/oxide-freebsd-x64': 4.0.0 455 - '@tailwindcss/oxide-linux-arm-gnueabihf': 4.0.0 456 - '@tailwindcss/oxide-linux-arm64-gnu': 4.0.0 457 - '@tailwindcss/oxide-linux-arm64-musl': 4.0.0 458 - '@tailwindcss/oxide-linux-x64-gnu': 4.0.0 459 - '@tailwindcss/oxide-linux-x64-musl': 4.0.0 460 - '@tailwindcss/oxide-win32-arm64-msvc': 4.0.0 461 - '@tailwindcss/oxide-win32-x64-msvc': 4.0.0 752 + '@tailwindcss/oxide-android-arm64': 4.1.18 753 + '@tailwindcss/oxide-darwin-arm64': 4.1.18 754 + '@tailwindcss/oxide-darwin-x64': 4.1.18 755 + '@tailwindcss/oxide-freebsd-x64': 4.1.18 756 + '@tailwindcss/oxide-linux-arm-gnueabihf': 4.1.18 757 + '@tailwindcss/oxide-linux-arm64-gnu': 4.1.18 758 + '@tailwindcss/oxide-linux-arm64-musl': 4.1.18 759 + '@tailwindcss/oxide-linux-x64-gnu': 4.1.18 760 + '@tailwindcss/oxide-linux-x64-musl': 4.1.18 761 + '@tailwindcss/oxide-wasm32-wasi': 4.1.18 762 + '@tailwindcss/oxide-win32-arm64-msvc': 4.1.18 763 + '@tailwindcss/oxide-win32-x64-msvc': 4.1.18 764 + 765 + '@typescript/native-preview-darwin-arm64@7.0.0-dev.20260109.1': 766 + optional: true 767 + 768 + '@typescript/native-preview-darwin-x64@7.0.0-dev.20260109.1': 769 + optional: true 770 + 771 + '@typescript/native-preview-linux-arm64@7.0.0-dev.20260109.1': 772 + optional: true 773 + 774 + '@typescript/native-preview-linux-arm@7.0.0-dev.20260109.1': 775 + optional: true 776 + 777 + '@typescript/native-preview-linux-x64@7.0.0-dev.20260109.1': 778 + optional: true 779 + 780 + '@typescript/native-preview-win32-arm64@7.0.0-dev.20260109.1': 781 + optional: true 782 + 783 + '@typescript/native-preview-win32-x64@7.0.0-dev.20260109.1': 784 + optional: true 785 + 786 + '@typescript/native-preview@7.0.0-dev.20260109.1': 787 + optionalDependencies: 788 + '@typescript/native-preview-darwin-arm64': 7.0.0-dev.20260109.1 789 + '@typescript/native-preview-darwin-x64': 7.0.0-dev.20260109.1 790 + '@typescript/native-preview-linux-arm': 7.0.0-dev.20260109.1 791 + '@typescript/native-preview-linux-arm64': 7.0.0-dev.20260109.1 792 + '@typescript/native-preview-linux-x64': 7.0.0-dev.20260109.1 793 + '@typescript/native-preview-win32-arm64': 7.0.0-dev.20260109.1 794 + '@typescript/native-preview-win32-x64': 7.0.0-dev.20260109.1 795 + 796 + ansi_up@6.0.6: {} 462 797 463 798 braces@3.0.3: 464 799 dependencies: ··· 466 801 467 802 detect-libc@1.0.3: {} 468 803 469 - enhanced-resolve@5.18.0: 804 + detect-libc@2.1.2: {} 805 + 806 + enhanced-resolve@5.18.4: 470 807 dependencies: 471 808 graceful-fs: 4.2.11 472 809 tapable: 2.2.1 ··· 485 822 486 823 is-number@7.0.0: {} 487 824 488 - jiti@2.4.2: {} 825 + jiti@2.6.1: {} 826 + 827 + lightningcss-android-arm64@1.30.2: 828 + optional: true 489 829 490 - lightningcss-darwin-arm64@1.29.1: 830 + lightningcss-darwin-arm64@1.30.2: 491 831 optional: true 492 832 493 - lightningcss-darwin-x64@1.29.1: 833 + lightningcss-darwin-x64@1.30.2: 494 834 optional: true 495 835 496 - lightningcss-freebsd-x64@1.29.1: 836 + lightningcss-freebsd-x64@1.30.2: 497 837 optional: true 498 838 499 - lightningcss-linux-arm-gnueabihf@1.29.1: 839 + lightningcss-linux-arm-gnueabihf@1.30.2: 500 840 optional: true 501 841 502 - lightningcss-linux-arm64-gnu@1.29.1: 842 + lightningcss-linux-arm64-gnu@1.30.2: 503 843 optional: true 504 844 505 - lightningcss-linux-arm64-musl@1.29.1: 845 + lightningcss-linux-arm64-musl@1.30.2: 506 846 optional: true 507 847 508 - lightningcss-linux-x64-gnu@1.29.1: 848 + lightningcss-linux-x64-gnu@1.30.2: 509 849 optional: true 510 850 511 - lightningcss-linux-x64-musl@1.29.1: 851 + lightningcss-linux-x64-musl@1.30.2: 512 852 optional: true 513 853 514 - lightningcss-win32-arm64-msvc@1.29.1: 854 + lightningcss-win32-arm64-msvc@1.30.2: 515 855 optional: true 516 856 517 - lightningcss-win32-x64-msvc@1.29.1: 857 + lightningcss-win32-x64-msvc@1.30.2: 518 858 optional: true 519 859 520 - lightningcss@1.29.1: 860 + lightningcss@1.30.2: 521 861 dependencies: 522 - detect-libc: 1.0.3 862 + detect-libc: 2.1.2 523 863 optionalDependencies: 524 - lightningcss-darwin-arm64: 1.29.1 525 - lightningcss-darwin-x64: 1.29.1 526 - lightningcss-freebsd-x64: 1.29.1 527 - lightningcss-linux-arm-gnueabihf: 1.29.1 528 - lightningcss-linux-arm64-gnu: 1.29.1 529 - lightningcss-linux-arm64-musl: 1.29.1 530 - lightningcss-linux-x64-gnu: 1.29.1 531 - lightningcss-linux-x64-musl: 1.29.1 532 - lightningcss-win32-arm64-msvc: 1.29.1 533 - lightningcss-win32-x64-msvc: 1.29.1 864 + lightningcss-android-arm64: 1.30.2 865 + lightningcss-darwin-arm64: 1.30.2 866 + lightningcss-darwin-x64: 1.30.2 867 + lightningcss-freebsd-x64: 1.30.2 868 + lightningcss-linux-arm-gnueabihf: 1.30.2 869 + lightningcss-linux-arm64-gnu: 1.30.2 870 + lightningcss-linux-arm64-musl: 1.30.2 871 + lightningcss-linux-x64-gnu: 1.30.2 872 + lightningcss-linux-x64-musl: 1.30.2 873 + lightningcss-win32-arm64-msvc: 1.30.2 874 + lightningcss-win32-x64-msvc: 1.30.2 534 875 535 - make-dir@3.1.0: 876 + magic-string@0.30.21: 536 877 dependencies: 537 - semver: 6.3.1 878 + '@jridgewell/sourcemap-codec': 1.5.5 538 879 539 880 micromatch@4.0.8: 540 881 dependencies: ··· 543 884 544 885 mri@1.2.0: {} 545 886 546 - netlify-plugin-debug-cache@1.0.4: 887 + node-addon-api@7.1.1: {} 888 + 889 + oxfmt@0.23.0: 547 890 dependencies: 548 - make-dir: 3.1.0 891 + tinypool: 2.0.0 892 + optionalDependencies: 893 + '@oxfmt/darwin-arm64': 0.23.0 894 + '@oxfmt/darwin-x64': 0.23.0 895 + '@oxfmt/linux-arm64-gnu': 0.23.0 896 + '@oxfmt/linux-arm64-musl': 0.23.0 897 + '@oxfmt/linux-x64-gnu': 0.23.0 898 + '@oxfmt/linux-x64-musl': 0.23.0 899 + '@oxfmt/win32-arm64': 0.23.0 900 + '@oxfmt/win32-x64': 0.23.0 901 + 902 + oxlint-tsgolint@0.11.0: 903 + optionalDependencies: 904 + '@oxlint-tsgolint/darwin-arm64': 0.11.0 905 + '@oxlint-tsgolint/darwin-x64': 0.11.0 906 + '@oxlint-tsgolint/linux-arm64': 0.11.0 907 + '@oxlint-tsgolint/linux-x64': 0.11.0 908 + '@oxlint-tsgolint/win32-arm64': 0.11.0 909 + '@oxlint-tsgolint/win32-x64': 0.11.0 549 910 550 - node-addon-api@7.1.1: {} 911 + oxlint@1.38.0(oxlint-tsgolint@0.11.0): 912 + optionalDependencies: 913 + '@oxlint/darwin-arm64': 1.38.0 914 + '@oxlint/darwin-x64': 1.38.0 915 + '@oxlint/linux-arm64-gnu': 1.38.0 916 + '@oxlint/linux-arm64-musl': 1.38.0 917 + '@oxlint/linux-x64-gnu': 1.38.0 918 + '@oxlint/linux-x64-musl': 1.38.0 919 + '@oxlint/win32-arm64': 1.38.0 920 + '@oxlint/win32-x64': 1.38.0 921 + oxlint-tsgolint: 0.11.0 551 922 552 923 picocolors@1.1.1: {} 553 924 554 925 picomatch@2.3.1: {} 555 926 556 - semver@6.3.1: {} 927 + source-map-js@1.2.1: {} 557 928 558 - tailwindcss@4.0.0: {} 929 + tailwindcss@4.1.18: {} 559 930 560 931 tapable@2.2.1: {} 561 932 562 - thumbhash@0.1.1: {} 933 + tinypool@2.0.0: {} 563 934 564 935 to-regex-range@5.0.1: 565 936 dependencies: 566 937 is-number: 7.0.0 567 - 568 - typescript@5.9.2: {}
+5
pnpm-workspace.yaml
··· 1 + packages: 2 + - crates/* 3 + 4 + onlyBuiltDependencies: 5 + - "@parcel/watcher"
+26
tsconfig.json
··· 1 + { 2 + "compilerOptions": { 3 + "noEmit": true, 4 + 5 + "module": "esnext", 6 + "target": "es2020", 7 + "lib": ["dom", "dom.iterable", "es2020"], 8 + "moduleResolution": "bundler", 9 + 10 + // Other Outputs 11 + "sourceMap": true, 12 + 13 + // Stricter Typechecking Options 14 + "noUncheckedIndexedAccess": true, 15 + "exactOptionalPropertyTypes": true, 16 + 17 + // Recommended Options 18 + "strict": true, 19 + "verbatimModuleSyntax": true, 20 + "isolatedModules": true, 21 + "noUncheckedSideEffectImports": true, 22 + "moduleDetection": "force", 23 + "skipLibCheck": true 24 + }, 25 + "exclude": ["node_modules", "dist", "vendor"] 26 + }
+1 -1
website/Cargo.toml
··· 8 8 maudit = { workspace = true } 9 9 maud = { workspace = true } 10 10 serde = { workspace = true } 11 - chrono = {version = "0.4.42", features = ["serde"]} 11 + chrono = { version = "0.4.42", features = ["serde"] }
+4 -14
website/assets/docs-sidebar.ts
··· 1 1 document.addEventListener("DOMContentLoaded", function () { 2 - const leftSidebarToggleElement = document.getElementById( 3 - "left-sidebar-toggle" 4 - ); 5 - const rightSidebarToggleElement = document.getElementById( 6 - "right-sidebar-toggle" 7 - ); 2 + const leftSidebarToggleElement = document.getElementById("left-sidebar-toggle"); 3 + const rightSidebarToggleElement = document.getElementById("right-sidebar-toggle"); 8 4 const leftSidebarElement = document.getElementById("mobile-left-sidebar"); 9 5 const rightSidebarElement = document.getElementById("mobile-right-sidebar"); 10 6 ··· 53 49 function toggleRightSidebar() { 54 50 rightOpen = !rightOpen; 55 51 56 - const rightSidebarContent = rightSidebar.querySelector( 57 - "div" 58 - ) as HTMLElement; 52 + const rightSidebarContent = rightSidebar.querySelector("div") as HTMLElement; 59 53 60 54 // Toggle overlay opacity 61 55 rightSidebar.classList.toggle("opacity-0", !rightOpen); ··· 98 92 // Close right sidebar when clicking on table of contents links 99 93 rightSidebar.addEventListener("click", function (event) { 100 94 const target = event.target as HTMLElement; 101 - if ( 102 - target && 103 - target.tagName === "A" && 104 - target.getAttribute("href")?.startsWith("#") 105 - ) { 95 + if (target && target.tagName === "A" && target.getAttribute("href")?.startsWith("#")) { 106 96 if (rightOpen) { 107 97 toggleRightSidebar(); 108 98 }
+119 -119
website/assets/prin.css
··· 1 1 @import "tailwindcss"; 2 2 3 3 @font-face { 4 - font-family: "Charter"; 5 - src: 6 - local("Charter"), 7 - url("./fonts/charter_regular.woff2") format("woff2"); 8 - font-weight: normal; 9 - font-style: normal; 10 - font-display: swap; 4 + font-family: "Charter"; 5 + src: 6 + local("Charter"), 7 + url("./fonts/charter_regular.woff2") format("woff2"); 8 + font-weight: normal; 9 + font-style: normal; 10 + font-display: swap; 11 11 } 12 12 13 13 @theme { 14 - --color-our-white: #fafafa; 15 - --color-our-black: #262421; 16 - --color-darker-black: #21201c; 17 - --color-darker-white: #f5f5f4; 18 - --color-brighter-white: #ffffff; 19 - --color-borders: #e9e9e7; 20 - --color-brand-red: #ba1f33; 21 - --color-brighter-brand: #fa3252; 14 + --color-our-white: #fafafa; 15 + --color-our-black: #262421; 16 + --color-darker-black: #21201c; 17 + --color-darker-white: #f5f5f4; 18 + --color-brighter-white: #ffffff; 19 + --color-borders: #e9e9e7; 20 + --color-brand-red: #ba1f33; 21 + --color-brighter-brand: #fa3252; 22 22 23 - --max-width-larger-prose: 75ch; 23 + --max-width-larger-prose: 75ch; 24 24 25 - --docs-columns: 0.17fr 0.72fr 0.15fr; 26 - --docs-tablet-columns: 25% 75%; 25 + --docs-columns: 0.17fr 0.72fr 0.15fr; 26 + --docs-tablet-columns: 25% 75%; 27 27 } 28 28 29 29 html, 30 30 body { 31 - background-color: var(--color-our-black); 32 - color: var(--color-our-black); 33 - height: 100%; 31 + background-color: var(--color-our-black); 32 + color: var(--color-our-black); 33 + height: 100%; 34 34 } 35 35 36 36 body { 37 - font-family: Charter, "Bitstream Charter", Cambria, serif; 37 + font-family: Charter, "Bitstream Charter", Cambria, serif; 38 38 } 39 39 40 40 a:hover { 41 - color: var(--color-brand-red); 41 + color: var(--color-brand-red); 42 42 } 43 43 44 44 .btn { 45 - color: var(--color-brand-red); 46 - font-size: 1.55rem; 47 - font-weight: bold; 45 + color: var(--color-brand-red); 46 + font-size: 1.55rem; 47 + font-weight: bold; 48 48 } 49 49 50 50 .btn:hover { 51 - color: var(--color-brighter-brand); 51 + color: var(--color-brighter-brand); 52 52 } 53 53 54 54 .card { 55 - border-color: var(--color-borders); 56 - border-width: 1px; 57 - border-style: solid; 58 - border-radius: 0.5rem; 59 - padding: 1.5rem; 60 - box-shadow: 0 0 0.25rem 0 rgba(0, 0, 0, 0.025); 55 + border-color: var(--color-borders); 56 + border-width: 1px; 57 + border-style: solid; 58 + border-radius: 0.5rem; 59 + padding: 1.5rem; 60 + box-shadow: 0 0 0.25rem 0 rgba(0, 0, 0, 0.025); 61 61 } 62 62 63 63 .card:hover { 64 - box-shadow: 0 0 0.5rem 0 rgba(0, 0, 0, 0.05); 65 - background-color: var(--color-brighter-white); 64 + box-shadow: 0 0 0.5rem 0 rgba(0, 0, 0, 0.05); 65 + background-color: var(--color-brighter-white); 66 66 } 67 67 68 68 .banner { 69 - background-color: var(--color-brand-red); 70 - color: var(--color-our-white); 69 + background-color: var(--color-brand-red); 70 + color: var(--color-our-white); 71 71 } 72 72 73 73 .hero-background { 74 - background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbDpzcGFjZT0icHJlc2VydmUiIHZpZXdCb3g9IjAgMCA0NjYgNDY1Ij48ZGVmcz48Y2xpcFBhdGggaWQ9ImEiIGNsaXBQYXRoVW5pdHM9InVzZXJTcGFjZU9uVXNlIj48cGF0aCBmaWxsPSIjZmZmIiBkPSJNMjMgMTRoNDc2djQ3NUgyM1ptMjQ3IDU4Yy0yOCAwLTU1IDYtODEgMjBhMTY0IDE2NCAwIDAgMC03MCAyMjRjNDUgODEgMTQ3IDExMSAyMjkgNjggODMtNDMgMTE0LTE0NCA3MC0yMjRsLTEzIDdjNDAgNzMgMTIgMTY0LTY0IDIwNC03NSAzOS0xNjggMTEtMjA4LTYyLTQxLTc0LTEyLTE2NSA2My0yMDRzMTY5LTExIDIwOSA2MmwxMy03Yy0zMC01Ni04OC04Ny0xNDgtODhabTcyIDI0OSAzNCA2di01MmwtMi01Mi00LTIyLTMtMjIgNC0zIDUtM2MxLTIgMi02IDEtMTItMS00LTEtNS00LTdzLTMtMi04LTJoLTZsLTQgNS00IDV2MTJsNCAzIDMgMi0xMSAzOGMtMTAgMzYtMTEgMzktMTQgMzlsLTI2LTc3IDMtMSA0LTNjMi0zIDEtOC0xLTEzLTItNC0zLTQtNy01bC03IDFjLTMgMy00IDMtNSA3bC0xIDQgMyA0IDMgNC04IDMxLTExIDM3LTMgOWMtMSAyLTQtMy0xNS0yNC0xMS0yMi0xMS0yMi0xNS0zNGwtNC0xNCAzLTdjMy04IDMtMTAgMS0xNS0zLTQtNi02LTEyLTQtNCAwLTQgMS04IDVsLTQgNCAxIDYgNSAxMSAyIDVhMTIzMSAxMjMxIDAgMCAwLTExIDQwbC0zIDEwLTM1LTQ1LTgtMTIgMS0yIDItNy0yLTgtNi0yYy00LTEtNC0xLTcgMS00IDItNCAyLTQgNi0xIDUgMSAxMSA1IDEybDEgMSAyIDY5IDMgNjlhOTA4IDkwOCAwIDAgMSA1OS00bDQxLTIgMjAgMmMyMSAwIDIxIDAgNTMgNnoiIGNsYXNzPSJwb3dlcmNsaXAiIGNvbG9yPSIjMDAwIiBzdHlsZT0iLWlua3NjYXBlLXN0cm9rZTpub25lIi8+PC9jbGlwUGF0aD48L2RlZnM+PHBhdGggZmlsbD0iI2ZhZmFmYSIgZD0ibTM3Mi4xODUgMzcxLjcxMi0xMTEuMDg5IDM2LjM0LTExNi4zMi0xMS40NTItNjguODg5LTk0LjQyMi0yNS4wNTMtMTE0LjE2NSA2OC41MTMtOTQuNjk2TDIyMC4xODMgMzQuMjFsMTExLjIzMiAzNS44OTcgODcuMzczIDc3LjYzNi4yMzMgMTE2Ljg4MVoiIHBhaW50LW9yZGVyPSJzdHJva2UgZmlsbCBtYXJrZXJzIi8+PHBhdGggZmlsbD0iI2JhMWYzMyIgZD0iTTQ1NyA0MTFjLTcgMC0xNSAyLTIxIDctMzUgMjYtMTAgNzUgMzEgNDEgMzMtMjcgMTQtNDktMTAtNDhaTTI5MCAxOWMtMzEgMC02NyAxNC04NyAyNS0xNSA4LTY0IDM3LTEwNyA0Ni01NSAxMC04NyA2My01NSA5MCA1NCA0NCA1NiAxMDEgMTYgMTQzLTQ0IDQ2IDEgMTEzIDY0IDEwNiA2My04IDg5IDAgMTIxIDMyIDQxIDQxIDEzMiAyNSAxNTQtMzMgMTAtMjYgMjQtNTYgNTgtNjggNDEtMTQgNTMtNTkgMjYtOTEtMTktMjMtMjEtNDcgNS05NSAyMi00MCA1LTg0LTU2LTgxLTQ1IDMtNjQtMjctOTctNTlhNTkgNTkgMCAwIDAtNDItMTV6IiBjbGlwLXBhdGg9InVybCgjYSkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yOCAtMTkpIi8+PC9zdmc+"); 75 - background-repeat: no-repeat; 76 - background-position-x: calc(50%); 77 - background-position-y: calc(100%); 78 - background-size: 175px; 74 + background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbDpzcGFjZT0icHJlc2VydmUiIHZpZXdCb3g9IjAgMCA0NjYgNDY1Ij48ZGVmcz48Y2xpcFBhdGggaWQ9ImEiIGNsaXBQYXRoVW5pdHM9InVzZXJTcGFjZU9uVXNlIj48cGF0aCBmaWxsPSIjZmZmIiBkPSJNMjMgMTRoNDc2djQ3NUgyM1ptMjQ3IDU4Yy0yOCAwLTU1IDYtODEgMjBhMTY0IDE2NCAwIDAgMC03MCAyMjRjNDUgODEgMTQ3IDExMSAyMjkgNjggODMtNDMgMTE0LTE0NCA3MC0yMjRsLTEzIDdjNDAgNzMgMTIgMTY0LTY0IDIwNC03NSAzOS0xNjggMTEtMjA4LTYyLTQxLTc0LTEyLTE2NSA2My0yMDRzMTY5LTExIDIwOSA2MmwxMy03Yy0zMC01Ni04OC04Ny0xNDgtODhabTcyIDI0OSAzNCA2di01MmwtMi01Mi00LTIyLTMtMjIgNC0zIDUtM2MxLTIgMi02IDEtMTItMS00LTEtNS00LTdzLTMtMi04LTJoLTZsLTQgNS00IDV2MTJsNCAzIDMgMi0xMSAzOGMtMTAgMzYtMTEgMzktMTQgMzlsLTI2LTc3IDMtMSA0LTNjMi0zIDEtOC0xLTEzLTItNC0zLTQtNy01bC03IDFjLTMgMy00IDMtNSA3bC0xIDQgMyA0IDMgNC04IDMxLTExIDM3LTMgOWMtMSAyLTQtMy0xNS0yNC0xMS0yMi0xMS0yMi0xNS0zNGwtNC0xNCAzLTdjMy04IDMtMTAgMS0xNS0zLTQtNi02LTEyLTQtNCAwLTQgMS04IDVsLTQgNCAxIDYgNSAxMSAyIDVhMTIzMSAxMjMxIDAgMCAwLTExIDQwbC0zIDEwLTM1LTQ1LTgtMTIgMS0yIDItNy0yLTgtNi0yYy00LTEtNC0xLTcgMS00IDItNCAyLTQgNi0xIDUgMSAxMSA1IDEybDEgMSAyIDY5IDMgNjlhOTA4IDkwOCAwIDAgMSA1OS00bDQxLTIgMjAgMmMyMSAwIDIxIDAgNTMgNnoiIGNsYXNzPSJwb3dlcmNsaXAiIGNvbG9yPSIjMDAwIiBzdHlsZT0iLWlua3NjYXBlLXN0cm9rZTpub25lIi8+PC9jbGlwUGF0aD48L2RlZnM+PHBhdGggZmlsbD0iI2ZhZmFmYSIgZD0ibTM3Mi4xODUgMzcxLjcxMi0xMTEuMDg5IDM2LjM0LTExNi4zMi0xMS40NTItNjguODg5LTk0LjQyMi0yNS4wNTMtMTE0LjE2NSA2OC41MTMtOTQuNjk2TDIyMC4xODMgMzQuMjFsMTExLjIzMiAzNS44OTcgODcuMzczIDc3LjYzNi4yMzMgMTE2Ljg4MVoiIHBhaW50LW9yZGVyPSJzdHJva2UgZmlsbCBtYXJrZXJzIi8+PHBhdGggZmlsbD0iI2JhMWYzMyIgZD0iTTQ1NyA0MTFjLTcgMC0xNSAyLTIxIDctMzUgMjYtMTAgNzUgMzEgNDEgMzMtMjcgMTQtNDktMTAtNDhaTTI5MCAxOWMtMzEgMC02NyAxNC04NyAyNS0xNSA4LTY0IDM3LTEwNyA0Ni01NSAxMC04NyA2My01NSA5MCA1NCA0NCA1NiAxMDEgMTYgMTQzLTQ0IDQ2IDEgMTEzIDY0IDEwNiA2My04IDg5IDAgMTIxIDMyIDQxIDQxIDEzMiAyNSAxNTQtMzMgMTAtMjYgMjQtNTYgNTgtNjggNDEtMTQgNTMtNTkgMjYtOTEtMTktMjMtMjEtNDcgNS05NSAyMi00MCA1LTg0LTU2LTgxLTQ1IDMtNjQtMjctOTctNTlhNTkgNTkgMCAwIDAtNDItMTV6IiBjbGlwLXBhdGg9InVybCgjYSkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yOCAtMTkpIi8+PC9zdmc+"); 75 + background-repeat: no-repeat; 76 + background-position-x: calc(50%); 77 + background-position-y: calc(100%); 78 + background-size: 175px; 79 79 } 80 80 81 81 @media (max-width: 1250px) { 82 - .hero-background { 83 - background-size: 100px; 84 - background-position-y: calc(50%); 85 - } 82 + .hero-background { 83 + background-size: 100px; 84 + background-position-y: calc(50%); 85 + } 86 86 } 87 87 88 88 .prose { 89 - font-size: 1.125rem; 90 - line-height: 1.75; 89 + font-size: 1.125rem; 90 + line-height: 1.75; 91 91 } 92 92 93 93 .prose h1, ··· 95 95 .prose h3, 96 96 .prose h4, 97 97 .prose h5 { 98 - font-weight: bold; 98 + font-weight: bold; 99 99 } 100 100 101 101 .prose h1 { 102 - margin-top: 0; 103 - margin-bottom: 0.5em; 104 - font-size: 2.25rem; 105 - line-height: 1.11111; 102 + margin-top: 0; 103 + margin-bottom: 0.5em; 104 + font-size: 2.25rem; 105 + line-height: 1.11111; 106 106 } 107 107 108 108 .prose h2 { 109 - margin-top: 1.2em; 110 - margin-bottom: 0.6em; 111 - font-size: 1.66667em; 112 - line-height: 1.33333; 109 + margin-top: 1.2em; 110 + margin-bottom: 0.6em; 111 + font-size: 1.66667em; 112 + line-height: 1.33333; 113 113 } 114 114 115 115 .prose h2:first-child { 116 - margin-top: 0; 116 + margin-top: 0; 117 117 } 118 118 119 119 .prose h3 { 120 - margin-top: 1em; 121 - margin-bottom: 0.4em; 122 - font-size: 1.5rem; 123 - line-height: 1.4; 120 + margin-top: 1em; 121 + margin-bottom: 0.4em; 122 + font-size: 1.5rem; 123 + line-height: 1.4; 124 124 } 125 125 126 126 .prose h4 { 127 - margin-top: 0.8em; 128 - margin-bottom: 0.3em; 129 - font-size: 1.25rem; 130 - line-height: 1.5; 127 + margin-top: 0.8em; 128 + margin-bottom: 0.3em; 129 + font-size: 1.25rem; 130 + line-height: 1.5; 131 131 } 132 132 133 133 .prose h5 { 134 - margin-top: 0.8em; 135 - margin-bottom: 0.3em; 136 - font-size: 1.125rem; 137 - line-height: 1.55556; 134 + margin-top: 0.8em; 135 + margin-bottom: 0.3em; 136 + font-size: 1.125rem; 137 + line-height: 1.55556; 138 138 } 139 139 140 140 .prose a { 141 - text-decoration: underline; 141 + text-decoration: underline; 142 142 } 143 143 144 144 .prose p { 145 - margin-top: 1em; 146 - margin-bottom: 1em; 147 - line-height: 1.75; 145 + margin-top: 1em; 146 + margin-bottom: 1em; 147 + line-height: 1.75; 148 148 } 149 149 150 150 .prose blockquote { 151 - border-left: 4px solid var(--color-borders); 152 - margin-left: -1.5rem; 153 - margin-right: -1.5rem; 154 - padding-left: 1rem; 155 - color: var(--color-darker-black); 156 - font-style: italic; 157 - margin-top: 1em; 158 - margin-bottom: 1em; 151 + border-left: 4px solid var(--color-borders); 152 + margin-left: -1.5rem; 153 + margin-right: -1.5rem; 154 + padding-left: 1rem; 155 + color: var(--color-darker-black); 156 + font-style: italic; 157 + margin-top: 1em; 158 + margin-bottom: 1em; 159 159 } 160 160 161 161 .prose code, 162 162 .intro-code code { 163 - font-family: 164 - ui-monospace, "Cascadia Code", "Source Code Pro", Menlo, Consolas, 165 - "DejaVu Sans Mono", monospace; 166 - font-size: 0.888889em; 163 + font-family: 164 + ui-monospace, "Cascadia Code", "Source Code Pro", Menlo, Consolas, "DejaVu Sans Mono", 165 + monospace; 166 + font-size: 0.888889em; 167 167 } 168 168 169 169 .prose code:not(pre code) { 170 - font-weight: bold; 170 + font-weight: bold; 171 171 } 172 172 173 173 .prose code:not(pre code):before { 174 - content: "`"; 174 + content: "`"; 175 175 } 176 176 177 177 .prose code:not(pre code):after { 178 - content: "`"; 178 + content: "`"; 179 179 } 180 180 181 181 .prose pre, 182 182 .intro-code pre { 183 - background-color: var(--color-darker-black); 184 - overflow-x: auto; 185 - padding-top: 1em; 186 - padding-inline-end: 1.5em; 187 - padding-bottom: 1em; 188 - border-radius: 0.375rem; 189 - margin-top: 2em; 190 - margin-bottom: 2em; 191 - padding-inline-start: 1.5em; 192 - font-size: 0.888889em; 193 - margin-left: -1.5rem; 194 - margin-right: -1.5rem; 183 + background-color: var(--color-darker-black); 184 + overflow-x: auto; 185 + padding-top: 1em; 186 + padding-inline-end: 1.5em; 187 + padding-bottom: 1em; 188 + border-radius: 0.375rem; 189 + margin-top: 2em; 190 + margin-bottom: 2em; 191 + padding-inline-start: 1.5em; 192 + font-size: 0.888889em; 193 + margin-left: -1.5rem; 194 + margin-right: -1.5rem; 195 195 } 196 196 197 197 @media (min-width: 769px) and (max-width: 1280px) { 198 - .prose pre, 199 - .intro-code pre { 200 - margin-left: 0; 201 - margin-right: 0; 202 - } 198 + .prose pre, 199 + .intro-code pre { 200 + margin-left: 0; 201 + margin-right: 0; 202 + } 203 203 } 204 204 205 205 .prose ul { 206 - list-style-type: disc; 207 - margin-top: 1em; 208 - margin-bottom: 1em; 209 - padding-left: 1.5em; 206 + list-style-type: disc; 207 + margin-top: 1em; 208 + margin-bottom: 1em; 209 + padding-left: 1.5em; 210 210 } 211 211 212 212 .prose li { 213 - margin-top: 0.5em; 214 - margin-bottom: 0.5em; 213 + margin-top: 0.5em; 214 + margin-bottom: 0.5em; 215 215 } 216 216 217 217 @media (max-width: 768px) { 218 - .prose pre, 219 - .intro-code pre { 220 - border-radius: 0; 221 - } 218 + .prose pre, 219 + .intro-code pre { 220 + border-radius: 0; 221 + } 222 222 } 223 223 224 224 .prose hr { 225 - border-color: var(--color-borders); 226 - margin-top: 2em; 227 - margin-bottom: 2em; 225 + border-color: var(--color-borders); 226 + margin-top: 2em; 227 + margin-bottom: 2em; 228 228 }
+1 -1
website/content/docs/javascript.md
··· 6 6 7 7 Maudit supports adding JavaScript and TypeScript files to your site. 8 8 9 - To import a script, add it anywhere in your project's directory, and use the [`ctx.assets.add_script()`](https://docs.rs/maudit/latest/maudit/assets/struct.RouteAssets.html#method.add_script) method to add it to a page's assets. 9 + To import a script, add it anywhere in your project's directory, and use the [`ctx.assets.add_script()`](https://docs.rs/maudit/latest/maudit/assets/struct.RouteAssets.html#method.add_script) method to add it to a page's assets. 10 10 11 11 This function will return an error if the image file does not exist, or cannot be read for any reason. If you'd rather not deal with errors, you can use the `add_script_unchecked()` method, which will instead panic on failure. 12 12
+1 -1
website/content/docs/routing.md
··· 162 162 163 163 ## Internationalization (i18n) 164 164 165 - Maudit includes the ability to generate *variants* of pages based on locales. For instance, you may have a `/about` page and want to create a `/fr/about` or `/a-propos` page with a localized slug. 165 + Maudit includes the ability to generate _variants_ of pages based on locales. For instance, you may have a `/about` page and want to create a `/fr/about` or `/a-propos` page with a localized slug. 166 166 167 167 While you could do this by duplicating your `/about` page, creating a new struct, re-implementing Route etc etc, it would be quite time consuming if your website support more languages and probably lead to a lot of duplicated code, as your Swedish about page probably uses a lot of the same layout as your Danish one. 168 168
+1 -1
website/content/news/for-static-websites.md
··· 5 5 date: 2025-10-15 6 6 --- 7 7 8 - We have one goal for Maudit: To make it the best tool to generate static websites. This may include helpful side features like loading Markdown content, syntax highlighting, image processing, sitemap generation, RSS feeds, etc. 8 + We have one goal for Maudit: To make it the best tool to generate static websites. This may include helpful side features like loading Markdown content, syntax highlighting, image processing, sitemap generation, RSS feeds, etc. 9 9 10 10 But the end result is always the same: You get a static website. No server, no serverless (with a server), no nothing. You get `.html` files that you can host wherever support hosting static files. 11 11
+8
xtask/Cargo.toml
··· 1 + [package] 2 + name = "xtask" 3 + version = "0.1.0" 4 + edition = "2024" 5 + 6 + [dependencies] 7 + rolldown = { package = "brk_rolldown", version = "0.2.3" } 8 + tokio = { version = "1", features = ["rt"] }
+145
xtask/src/main.rs
··· 1 + use rolldown::{Bundler, BundlerOptions, InputItem, RawMinifyOptions}; 2 + use std::{ 3 + env, fs, 4 + path::{Path, PathBuf}, 5 + }; 6 + 7 + type DynError = Box<dyn std::error::Error>; 8 + 9 + fn main() { 10 + if let Err(e) = try_main() { 11 + eprintln!("{}", e); 12 + std::process::exit(-1); 13 + } 14 + } 15 + 16 + fn try_main() -> Result<(), DynError> { 17 + let task = env::args().nth(1); 18 + match task.as_deref() { 19 + Some("build-js") => build_js()?, 20 + Some("build-cli-js") => build_cli_js()?, 21 + Some("build-maudit-js") => build_maudit_js()?, 22 + _ => print_help(), 23 + } 24 + Ok(()) 25 + } 26 + 27 + fn print_help() { 28 + println!("Usage: cargo xtask <task>"); 29 + println!(); 30 + println!("Available tasks:"); 31 + println!(" build-js Bundle JavaScript/TypeScript assets for all crates"); 32 + println!(" build-cli-js Bundle JavaScript/TypeScript assets for the CLI crate"); 33 + println!(" build-maudit-js Bundle JavaScript/TypeScript assets for the maudit crate"); 34 + } 35 + 36 + fn build_js() -> Result<(), DynError> { 37 + println!("Building JavaScript for all crates..."); 38 + build_cli_js()?; 39 + build_maudit_js()?; 40 + println!("All JavaScript builds completed successfully!"); 41 + Ok(()) 42 + } 43 + 44 + fn build_cli_js() -> Result<(), DynError> { 45 + let workspace_root = project_root(); 46 + let cli_crate = workspace_root.join("crates/maudit-cli"); 47 + let js_src_dir = cli_crate.join("js"); 48 + let js_dist_dir = js_src_dir.join("dist"); 49 + 50 + println!("Building JavaScript for maudit-cli..."); 51 + 52 + // Ensure the dist directory exists 53 + fs::create_dir_all(&js_dist_dir)?; 54 + 55 + // Configure Rolldown bundler input 56 + let input_items = vec![InputItem { 57 + name: Some("client".to_string()), 58 + import: js_src_dir.join("client.ts").to_string_lossy().to_string(), 59 + }]; 60 + 61 + let bundler_options = BundlerOptions { 62 + input: Some(input_items), 63 + dir: Some(js_dist_dir.to_string_lossy().to_string()), 64 + format: Some(rolldown::OutputFormat::Esm), 65 + minify: Some(RawMinifyOptions::Bool(true)), 66 + ..Default::default() 67 + }; 68 + 69 + // Create and run the bundler 70 + let runtime = tokio::runtime::Runtime::new()?; 71 + 72 + runtime.block_on(async { 73 + let mut bundler = Bundler::new(bundler_options) 74 + .map_err(|e| format!("Failed to create bundler: {:?}", e))?; 75 + 76 + bundler 77 + .write() 78 + .await 79 + .map_err(|e| format!("Failed to bundle JavaScript: {:?}", e))?; 80 + 81 + println!( 82 + "Successfully bundled JavaScript files to {}", 83 + js_dist_dir.display() 84 + ); 85 + 86 + Ok::<(), DynError>(()) 87 + })?; 88 + 89 + Ok(()) 90 + } 91 + 92 + fn build_maudit_js() -> Result<(), DynError> { 93 + let workspace_root = project_root(); 94 + let maudit_crate = workspace_root.join("crates/maudit"); 95 + let js_src_dir = maudit_crate.join("js"); 96 + let js_dist_dir = js_src_dir.join("dist"); 97 + 98 + println!("Building JavaScript for maudit..."); 99 + 100 + // Ensure the dist directory exists 101 + fs::create_dir_all(&js_dist_dir)?; 102 + 103 + // Configure Rolldown bundler input 104 + let input_items = vec![InputItem { 105 + name: Some("preload".to_string()), 106 + import: js_src_dir.join("preload.ts").to_string_lossy().to_string(), 107 + }]; 108 + 109 + let bundler_options = BundlerOptions { 110 + input: Some(input_items), 111 + dir: Some(js_dist_dir.to_string_lossy().to_string()), 112 + format: Some(rolldown::OutputFormat::Esm), 113 + ..Default::default() 114 + }; 115 + 116 + // Create and run the bundler 117 + let runtime = tokio::runtime::Runtime::new()?; 118 + 119 + runtime.block_on(async { 120 + let mut bundler = Bundler::new(bundler_options) 121 + .map_err(|e| format!("Failed to create bundler: {:?}", e))?; 122 + 123 + bundler 124 + .write() 125 + .await 126 + .map_err(|e| format!("Failed to bundle JavaScript: {:?}", e))?; 127 + 128 + println!( 129 + "Successfully bundled JavaScript files to {}", 130 + js_dist_dir.display() 131 + ); 132 + 133 + Ok::<(), DynError>(()) 134 + })?; 135 + 136 + Ok(()) 137 + } 138 + 139 + fn project_root() -> PathBuf { 140 + Path::new(&env!("CARGO_MANIFEST_DIR")) 141 + .ancestors() 142 + .nth(1) 143 + .unwrap() 144 + .to_path_buf() 145 + }