diff options
| author | 魏曹先生 <1992414357@qq.com> | 2026-05-25 22:01:06 +0800 |
|---|---|---|
| committer | 魏曹先生 <1992414357@qq.com> | 2026-05-25 22:01:06 +0800 |
| commit | 17217317eaaf57dd5c39538c115e35ddccb8666d (patch) | |
| tree | 9f1944b847d5e9d157bbc6a8c496bf8f2e7e1d23 | |
| parent | 979e881762a728661e72efd99bc2b35b3db8c71b (diff) | |
Restructure docs
add template and interactive tutorial, update tool runner
29 files changed, 2122 insertions, 1592 deletions
diff --git a/docs/TEMPLATE.md b/docs/TEMPLATE.md new file mode 100644 index 0000000..7ab2785 --- /dev/null +++ b/docs/TEMPLATE.md @@ -0,0 +1,14 @@ +<h1 align="center">Title</h1> +<p align="center"> + Description +</p> + +Content here + +<iframe + src="../play/play.html?tur=default.md&title=Title" + height="600px"/> + +<p align="center" style="font-size: 0.85em; color: gray;"> + Written by @Weicao-CatilGrass +</p> diff --git a/docs/_sidebar.md b/docs/_sidebar.md index 009dc34..40968ba 100644 --- a/docs/_sidebar.md +++ b/docs/_sidebar.md @@ -1,6 +1 @@ - [Welcome!](README) -* [Creating your first Program](pages/1-creating-your-first-program) -* [Implementing Fallbacks](pages/2-implementing-fallbacks) -* [Parsing Complex Args](pages/3-parsing-complex-arguments) -* [Impl Help Display](pages/4-implementing-help-display) -* [Impl Shell Completion](pages/5-implementing-completion) diff --git a/docs/_zh_CN/_sidebar.md b/docs/_zh_CN/_sidebar.md index f8905de..40968ba 100644 --- a/docs/_zh_CN/_sidebar.md +++ b/docs/_zh_CN/_sidebar.md @@ -1,6 +1 @@ - [Welcome!](README) -* [创建您的第一个程序](pages/1-creating-your-first-program) -* [实现回退机制](pages/2-implementing-fallbacks) -* [解析复杂参数](pages/3-parsing-complex-arguments) -* [实现帮助文档显示](pages/4-implementing-help-display) -* [实现命令行补全](pages/5-implementing-completion) diff --git a/docs/_zh_CN/index.html b/docs/_zh_CN/index.html index 2e265c7..5420691 100644 --- a/docs/_zh_CN/index.html +++ b/docs/_zh_CN/index.html @@ -13,6 +13,12 @@ content="Quick start with Mingling and build your command-line program!" /> + <link rel="preconnect" href="https://fonts.googleapis.com" /> + <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin /> + <link + href="https://fonts.googleapis.com/css2?family=Source+Sans+Pro:wght@400;600;700&family=Roboto+Mono&family=Dosis:wght@500&display=swap" + rel="stylesheet" + /> <link rel="stylesheet" href="../css/light.css" /> <link id="dark-style" diff --git a/docs/_zh_CN/pages/1-creating-your-first-program.md b/docs/_zh_CN/pages/1-creating-your-first-program.md deleted file mode 100644 index 64c9cb2..0000000 --- a/docs/_zh_CN/pages/1-creating-your-first-program.md +++ /dev/null @@ -1,258 +0,0 @@ -<h1 align="center">创建您的第一个程序</h1> -<p align="center"> - 了解 <b>Mingling</b>,并使用它创建您的第一个命令行程序 -</p> - -## 前言 - - 本章节将介绍如何渐进式地了解 **Mingling** - - 在开始之前,我先来讲讲 **Mingling** 能做什么: - - 在未开启其他特性时,它本身是一个基于 `proc-macro` 的子命令调度系统:它匹配用户输入的文本,以此查找并创建具体的数据,并将该数据放入调度器中不断转换类型,当该数据被转换到无法转换时,程序会将最终的数据渲染到终端上。 - - 也就是说,您需要理解一套新的开发范式:**完全基于类型的调度系统**。这可能会让您前期的学习**充满挫败感**,但当您逐渐理解这套范式后,您将可以写出极其方便修改和拓展的命令行程序。 - - - -## 创建基本程序 - - 接下来我将会讲述如何创建一个基本的程序,相信您已经准备好了一个空的 Rust 项目! - -#### 1. 添加依赖 - - 在 `Cargo.toml` 中添加如下依赖 ✏️ - -```toml -[dependencies] -mingling = "0.1.9" - -# 如果您要尝鲜,可以试试 Github 上托管的版本 -mingling = { git = "https://github.com/catilgrass/mingling", branch = "main" } -``` - -> [!NOTE] -> -> 该版本基于文档编写时的 **Mingling** 版本,您可以前往 [crates.io](https://crates.io/crates/mingling) 查看最新的版本!😄 -> -> **Mingling** 会积极更新文档,以确保文档内容能紧跟最新版本 - - - -#### 2. 创建程序 - - 接下来,在 `src/main.rs` 中创建程序 ✏️ - -```rust -fn main() { - // 创建 ThisProgram,并执行 - ThisProgram::new().exec(); -} - -// gen_program! 宏将会收集 *它之前* 的所有组件、类型 -// 然后生成程序 `ThisProgram` -mingling::macros::gen_program!(); -``` - -> [!TIP] -> -> `gen_program!()` 宏展开时,会收集在它之前展开的其他组件、类型的信息,这意味着您需要将 `gen_program!()` 放在整个 crate 中最后被展开的位置 -> -> 我推荐放在 `main.rs` 或者 `lib.rs` 的结尾。 - - - -#### 3. 创建命令 - - 当然,现在的程序什么都没有,在运行时不会输出任何消息。所以,让我们创建第一条命令 `greet`,给谁打个招呼吧 ✏️ - -```rust -fn main() { - // ... -} - -// 创建分发器,并将 GreetCommand 绑定在 "greet" 子命令 -// 在用户指定该命令时,向调度器发送 GreetEntry -dispatcher!("greet", GreetCommand => GreetEntry); - -// ... -gen_program!(); -``` - - 不要被突然多出来的一个宏和两个类型所吓到!我来逐一解释这个宏干了什么: - -##### 关于 `dispatcher!` 宏 💡 - -1. 宏创建了一个` GreetCommand` 结构体,并实现了 `Dispatcher` trait - - *这一步告诉框架:现在有了个新的分发器,它将会承接一个子命令的行为。* - -2. 宏实现了 `Dispatcher` trait 内部的 `node(&self) -> Node` 函数,并告诉节点为 `"greet"` - - *这一步告诉框架:该分发器将承接子命令 `"greet"` 的行为* - -3. 宏实现了 `Dispatcher` trait 内部的 `begin` 函数,将用户输入的完整参数转换为了第一个类型 `GreetEntry` - - *这一步告诉框架:该分发器在被匹配到后,将会向调度器发送类型 `GreetEntry`,供后续执行* - - 简而言之:**“用户输入 `greet`,我就创建 `GreetEntry`,丢给调度器转换”** - - - -#### 4. 注册命令 - - 在 `Dispatcher` 创建后,我们得到了两个类型 `GreetCommand` 和 `GreetEntry`,首先将 `GreetCommand` 注册到 `ThisProgram` ✏️ - -```rust -fn main() { - let mut program = ThisProgram::new(); - - // 注册分发器 - program.with_dispatcher(GreetCommand); - program.exec(); -} -``` - - 这样,`ThisProgram` 就认得 `"greet"` 子命令了,但是框架还不知道 `"greet"` 的行为是怎样的。此时我们便需要实现具体的逻辑: - - - -#### 5. 实现渲染行为 - - 我们期望 `"greet"` 的时候输出 `"Hello, World"`:既然要输出到终端,那么我们可以使用 **Mingling** 的另一个组件 `Renderer`,它负责将数据渲染到终端 ✏️ - -```rust -// ... -dispatcher!("greet", GreetCommand => GreetEntry); - -// 声明渲染器 `render_greet`,并表示前一个类型是 `GreetEntry` -#[renderer] -fn render_greet(_prev: GreetEntry) { - r_println!("Hello, World!"); -} - -// ... -gen_program!(); // 渲染器会被注册到程序 -``` - - 对于 `#[renderer]` 属性宏标记的函数,**Mingling** 严格规定只允许使用一种函数签名: - -```rust -#[renderer] -fn renderer_name (_prev: PreviousType) { } -``` - - 宏会读取到第一个参数的类型,并告诉 `gen_program!` 该函数用来渲染该类型。 - -##### 关于 `r_println!()` 💡 - - 您可能会注意到,在 `#[renderer]` 中使用的打印宏是 `r_println!` 而非 `println!`,这是因为框架的渲染逻辑并不在该函数内:在 `#[renderer]` 展开后,会向函数注入一个 `__renderer_inner_result: &mut RenderResult`;而 `r_println!` 将信息追加到 `RenderResult` 内,并在调度器关闭后,将最终的渲染数据交给 `Program::exec` 函数输出。 - - - -#### 6. 增加执行逻辑 - - 我猜您已经很想实现 `greet Alice` 这样的语法来输出 `"Hello, Alice!"` 了,本段正准备干这件事! - - **Mingling** 的核心执行流程是 `Dispatcher -> Chain -> Renderer`,而最关键的就是 `Chain`:它负责将输入的数据类型转换为其他类型,然后让调度器根据结果的类型找到下一个 `Chain` 或者 `Renderer ✏️ - -```rust -dispatcher!("greet", GreetCommand => GreetEntry); - -// 包装中间类型 `ResultGreetSomeone` -pack!(ResultGreetSomeone = String); - -#[chain] -fn handle_greet_entry(prev: GreetEntry) -> Next { - let args = prev.inner; - let name = args - .first() - .cloned() - .unwrap_or_else(|| "World".to_string()); - - // 包装为中间类型 - ResultGreetSomeone::new(name) -} - -#[renderer] -fn render_greet_someone(prev: ResultGreetSomeone) { - // 解引用 prev 拿到原始类型 - r_println!("Hello, {}!", *prev); -} -``` - - 像 `#[renderer]` 一样,我们创建了一个 `#[chain]`,它处理类型 `GreetEntr`,输出 `ResultGreetSomeone` - - 这样我们就在原本的 `Dispatcher` 和 `Renderer` 中间插入了一个 `Chain`:它可以将用户输入的参数提取出来(或回退到默认值 "World"),再交由渲染器打印到终端。 - -##### 关于 `Next` 💡 - - `Next` 是由 `gen_program!()` 生成的占位符,在 `#[chain]` 展开后,它将被替换为调度器能识别的类型擦除类型 `ChainProcess<ThisProgram>`,用于减少代码量 - -> [!NOTE] -> -> `Next` 方案为临时替代,下一次更新需要等待 Rust 的 `Impl In Type Aliases` 特性稳定后。 -> -> **不过,您不用担心**:下一次 `Next` 的更新不会引入 **破坏性变更!** - -##### 关于 `pack!` 💡 - - `pack!` 是 **Mingling** 开发过程中使用频率 **极高** 的宏:它负责将任意类型包装成另一个类型,并自动为其派生框架所需的特征。 - - 它的语法如您所见,极为简单: - -```rust -pack!(PackedType = RawType); -``` - - 不过请注意:`pack!` 宏不支持带有生命周期的类型包装,因为类型在调度器之间的流转方式永远都是 `move` 而非 `borrow`。 - - - -#### 7. 编译并运行 - - 好的,至此我们完成了一个基本的命令行程序,以下是完整代码,您可以直接粘贴运行: - -```rust -use mingling::macros::{chain, dispatcher, gen_program, pack, r_println, renderer}; - -fn main() { - let mut program = ThisProgram::new(); - program.with_dispatcher(GreetCommand); - program.exec(); -} - -dispatcher!("greet", GreetCommand => GreetEntry); - -pack!(ResultGreetSomeone = String); - -#[chain] -fn handle_greet_entry(prev: GreetEntry) -> Next { - let args = prev.inner; - let name = args.first().cloned().unwrap_or_else(|| "World".to_string()); - - ResultGreetSomeone::new(name) -} - -#[renderer] -fn render_greet_someone(prev: ResultGreetSomeone) { - r_println!("Hello, {}!", *prev); -} - -gen_program!(); -``` - - 运行结果: - -```bash -~> your-bin greet -Hello, World! -~> your-bin greet Alice -Hello, Alice! -``` - - 至此,您已成功创建基本的 **Mingling** 命令行程序,下一章节将会讲述如何为您的命令行程序实现回退机制来处理命令不存在、渲染器不存在的情况。 - -<p align="center" style="font-size: 0.85em; color: gray;"> - Written by @Weicao-CatilGrass -</p> diff --git a/docs/_zh_CN/pages/2-implementing-fallbacks.md b/docs/_zh_CN/pages/2-implementing-fallbacks.md deleted file mode 100644 index b57a9e7..0000000 --- a/docs/_zh_CN/pages/2-implementing-fallbacks.md +++ /dev/null @@ -1,141 +0,0 @@ -<h1 align="center">实现回退机制</h1> -<p align="center"> - 使用回退机制处理程序的错误情况 -</p> - -## 书接上文 - - 在上文中,我们介绍了如何使用 **Mingling** 开发基本的命令行程序:你可以使用 `"greet"` 子命令输出 `"Hello, World!"`,也可以使用 `"greet Alice"` 输出 `"Hello, Alice!"` - - 而当用户并未输入 `"greet"` 时呢?让我们键入命令尝试一下 ⌨️ - -```bash -~> your-bin hello -~> your-bin hello Alice -``` - - **它没有任何反应!** 👆 - - 让我来解释为什么:**Mingling** 不自作主张,无论发生什么它都不会输出内容到终端(除了 `unwind` 下的 `panic!`) - - 这意味着,如果您需要在命令行程序出错时能够主动地做些什么,你就得显式声明。 - - 好在 **Mingling** 提供了较为方便的接口实现该功能:在 `gen_program!` 宏中,会生成两个 `FallBack` 类型 - -|类型|发生时机|发生方式| -|-|-|-| -|RendererNotFound|调度无法找到的渲染器时|作为 `Chain` 调度| -|DispatcherNotFound|输入命令但无法匹配分发器|作为 `Chain` 调度| - -### `DispatcherNotFound` 类型 - - 首先让我们关注 `DispatcherNotFound` 类型,它的产生方式如下: - -```rust -// 1. 定义 `greet` 命令 -dispatcher!("greet", GreetCommand => GreetEntry); - -fn main() { - // ->> 用户输入 "hello Alice" - let mut program = ThisProgram::new(); - - // 2. 导入 `greet` 命令 - program.with_dispatcher(GreetCommand); - - // 3. 执行程序 - program.exec(); -} - -// ... - -// 5. 接收 DispatcherNotFound 调度 -#[renderer] -fn dispatcher_not_found(prev: DispatcherNotFound) { - // 6. 输出 - r_println!( - "Cannot match any command! Current input: \"{}\"", - prev.join(" ") - ); -} - -// 4. 无法匹配到任何名为 `hello` 的分发器 -// 将用户参数原样分发到 DispatcherNotFound -gen_program!(); -``` - - 上述程序的运行效果为: - -```bash -~> omg hello -Cannot match any command! Current input: "hello" - -~> omg hello Alice -Cannot match any command! Current input: "hello Alice" -``` - - 现在若用户输入了不匹配的命令,**Mingling** 将会输出对应的内容! - -## `RendererNotFound` 类型 - - `RendererNotFound` 有两种可能产生: - - 1. 该类型被显式分发到了 `Renderer` (使用 `.to_render()` 函数),但是该类型未实现渲染器 - 2. 该类型被分发到了 `Chain`,但是该类型未实现链,也未实现渲染器 - - 一般来说,`RendererNotFound` **不应该在业务逻辑中产生**:它被调度意味着您的类型需要被渲染但是并不能被渲染。您可以使用该类型来定位哪个类型缺失渲染器实现 ✏️ - -```rust -dispatcher!("greet", GreetCommand => GreetEntry); - -fn main() { - let mut program = ThisProgram::new(); - - program.with_dispatcher(GreetCommand); - program.exec(); -} - -pack!(ResultGreetSomeone = String); - -#[chain] -fn handle_greet_entry(prev: GreetEntry) -> Next { - let args = prev.inner; - let name = args.first().cloned().unwrap_or_else(|| "World".to_string()); - - ResultGreetSomeone::new(name) -} - -// 让我们故意去除 `ResultGreetSomeone` 类型的渲染器实现 -// #[renderer] -// fn render_greet_someone(prev: ResultGreetSomeone) { -// r_println!("Hello, {}!", *prev); -// } - -#[renderer] -fn renderer_not_found(prev: RendererNotFound) { - if *prev == "DispatcherNotFound" { - return; // 排除 "DispatcherNotFound" 类型 - } - - // 当未找到渲染器时触发 `panic!` - panic!("Renderer \"{}\" not found!", *prev); -} - -gen_program!(); - -``` - - 上述程序的运行效果为: - -```bash -~> your-bin greet Alice - -thread 'main' (90772) panicked at src/bin/your-bin.rs:30:5: -Renderer "ResultGreetSomeone" not found! -note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace -``` - - 以上便是 **Mingling** 的回退机制,在接下来的章节中,您将学习如何使用 `Picker` 解析复杂的用户输入。 - -<p align="center" style="font-size: 0.85em; color: gray;"> - Written by @Weicao-CatilGrass -</p> diff --git a/docs/_zh_CN/pages/3-parsing-complex-arguments.md b/docs/_zh_CN/pages/3-parsing-complex-arguments.md deleted file mode 100644 index 054f203..0000000 --- a/docs/_zh_CN/pages/3-parsing-complex-arguments.md +++ /dev/null @@ -1,364 +0,0 @@ -<h1 align="center">解析复杂参数</h1> -<p align="center"> - 使用 Mingling Picker 解析复杂的用户输入 -</p> - -## 引言 - - 在前文的示例中,我们成功创建了带有 `"greet"` 子命令的命令行程序,可以输出用户输入的第一个参数。 - - 您也注意到了,示例当中使用的方式近乎直接操作字符串,不够语义化,这不利于长期维护。 - -```rust -let name = args.first().cloned().unwrap_or_else(|| "World".to_string()); -``` - - 而本章节将会引入新的 **Mingling** 特性:`Picker`,它提供轻量且和 **Mingling** 类型路由高度契合的命令解析方案。 - - 要启用 `Picker`,您需要修改 `Cargo.toml` ✏️ - -```toml -[dependencies] -mingling = { - version = "...", - features = ["parser"] -} -``` - - 好了,多的不说,让我们上手编辑代码,重写前文的解析代码 ✏️ - -```rust -#[chain] -fn handle_greet_entry(prev: GreetEntry) -> Next { - // 前文中使用的方式: - // let args = prev.inner; - // let name = args.first().cloned().unwrap_or_else(|| "World".to_string()); - - // 引入 Picker 后使用的方式 - let name = prev.pick_or((), "World").unpack(); - - ResultGreetSomeone::new(name) -} -``` - - `Picker` 为所有 `Into<Vec<String>>` 实现了 `pick` `pick_or` `pick_or_route` 函数:它们可以语义化地从字符串列表中 **拾取 (Pick)** 参数,并转换为结构化数据。 - - 对于上述示例中的代码: - -```rust -prev.pick_or((), "World").unpack(); -``` - - 它的语义为: - -```rust - prev.pick_or((), "World").unpack(); -// ~~~~ ~~~~~~~ ~~ ~~~~~~~ ~~~~~~~~ -// | | | | |_ 解包为 String -// | | | |__________ 默认值为 "World" -// | | |______________ 取出第一个位置参数(不指定标志) -// | |______________________ 拾取或使用默认 -// |___________________________ 从前一个输入中 -``` - -## 解析标志参数 - - 若您的程序设计需要解析标志参数 (例如:`greet --name Alice`),可以使用如下方式: - -```rust -prev.pick_or(["--name", "-n"], "World").unpack(); -``` - - 同理,它的语义为: - -```rust - prev.pick_or(["--name", "-n"], "World").unpack(); -// ~~~~ ~~~~~~~ ~~~~~~~~~~~~~~~~ ~~~~~~~ ~~~~~~~~ -// | | | | |_ 解包为 String -// | | | |__________ 默认值为 "World" -// | | |____________________________ 取出 "--name" 或 "-n" 后面的参数 -// | |____________________________________ 拾取或使用默认 -// |_________________________________________ 从前一个输入中 -``` - -## 关于 `.unpack()` 💡 - - 您可能注意到了,`Picker` 在命令解析的最后,会执行一个 `.unpack()` 函数,它的作用是将前面解析出来的结果,转换为结构化信息。 - - 对于只拾取了一次的数据来说,`.unpack()` 会返回单个数据,而对于多次拾取,`Picker` 则会返回元组: - -```rust -let name_single: String = prev.clone().pick_or((), "World").unpack(); -let (name, age, id) = prev - .pick::<String>(["--name", "-n"]) - .pick::<u8>(["--age", "-a"]) - .pick::<u32>(["--id", "-I"]) - .unpack(); - -// 可解析参数 --name Alice --age 21 --id 0711251 -``` - -> [!IMPORTANT] -> `Picker` 对解析顺序极其敏感,特别是位置参数:因为它是顺序解析的 -> -> 若您需要解析位置参数,请确保解析前已拾取并消费所有 **标志参数** - -## 使用 `pick_or_route` 处理边界情况 - - 哈哈,就像那句老话:“永远不要相信你的用户”,为了应对错误情况:必要参数缺失、输入类型不匹配、同时启用了互斥选项,这些都是令人头疼的边界情况。 - - `pick_or_route` 便用于上述问题发生时,能将执行链路由到专门的错误处理类型上,以提供精细的错误处理逻辑。 - - 让我们先编写一个简单的示例来展示基本的用法: - -```rust -dispatcher!("greet", GreetCommand => GreetEntry); - -pack!(ResultGreetSomeone = String); -pack!(ErrorGreetNoNameProvided = ()); - -#[chain] -fn handle_greet_entry(prev: GreetEntry) -> Next { - // 使用 `pick_or_route` 提取 `--name` 参数 - // 如果不存在或解析失败,则路由到 ErrorGreetNoNameProvided - let pick_result = prev - .pick_or_route( - ["--name", "-n"], - ErrorGreetNoNameProvided::default().to_render(), - ) - // 在使用了任何可路由的函数后,`unpack` 将会返回 `Result<Value, Route>` - .unpack(); - - // 使用 route! 宏展开 `pick_result`, - // 若内部为 Err,该链在此处返回,并路由到指定类型 - let name = route!(pick_result); - ResultGreetSomeone::new(name).to_chain() -} - -// 承接 `ErrorGreetNoNameProvided` 的渲染 -#[renderer] -fn render_err_greet_no_name_provided(_prev: ErrorGreetNoNameProvided) { - r_println!("Error: No name provided.") -} - -#[renderer] -fn render_greet_someone(prev: ResultGreetSomeone) { - r_println!("Hello, {}!", *prev); -} -``` - - 若使用 `pick_or_route`,写法会变得相对复杂:因为 `.unpack()` 不再直接返回参数,而是 `Result<Value, Route>` - - 不过 **Mingling** 提供了简化展开的宏 `route!`,它不复杂,只是省略了一部分样板代码: - -```rust -let name = route!(pick_result); - -// 展开为 -let name = match pick_result { - Ok(r) => r, - Err(e) => return e, -}; -``` - -## 提取值的后处理 - - 在您使用 `pick` 提取了用户输入后,可以使用 `after` 或 `after_or_route` 立刻处理该参数 ✏️ - -```rust -#[chain] -fn handle_greet_entry(prev: GreetEntry) -> Next { - let name = prev - .pick_or(["--name", "-n"], "World") - // 在提取出 `--name` 后,立刻对其进行格式化 - .after(|name: String| { - name.replace(['-', '_', '.'], " ") - .to_lowercase() - .trim() - .to_string() - }) - .unpack(); - - ResultGreetSomeone::new(name) // 此处传入的 name 已被格式化处理 -} -``` - - 同样,您可以使用 `after_or_route` 来处理输入参数的格式错误 ✏️ - -```rust -dispatcher!("greet", GreetCommand => GreetEntry); - -pack!(ResultGreetSomeone = String); -pack!(ErrorGreetNameTooLong = usize); - -#[chain] -fn handle_greet_entry(prev: GreetEntry) -> Next { - let pick_result = prev - .pick_or(["--name", "-n"], "World") - // 和 `after` 不同,此处传入的是 &String - .after_or_route(|name: &String| { - name.replace(['-', '_', '.'], " ") - .to_lowercase() - .trim() - .to_string(); - - // 判断名字长度,若过长则路由到错误类型 - let len = name.len(); - if len < 32 { - Ok(name.clone()) - } else { - Err(ErrorGreetNameTooLong::new(len).to_render()) - } - }) - .unpack(); - let name = route!(pick_result); - - ResultGreetSomeone::new(name).to_chain() -} - -#[renderer] -fn render_error_greet_name_too_long(prev: ErrorGreetNameTooLong) { - let len = *prev; - r_println!("Error: name too long (length: {} > 32)", len); -} - -#[renderer] -fn render_greet_someone(prev: ResultGreetSomeone) { - r_println!("Hello, {}!", *prev); -} -``` - -## 布尔值解析 - - `Picker` 当然也可以解析 **布尔类型**,但是布尔类型分为显式和隐式模式, - - |模式|格式| - |-|-| - |显式|`--confirm true` 或 `--confirm yes`| - |隐式|`--confirmed`| - - - 若您使用 `.pick` 解析 `bool` 类型的时候,它将使用隐式解析:只要标志存在则为 `true` - - 若您使用 `.pick` 解析 `mingling::parser::Yes` 或 `mingling::parser::True` 时,它将使用显式解析,此处必须填写为 `true` / `yes` 时,才能识别为 `true` - - 一般来说:使用隐式解析足以,但是在处理位置参数或重要确认行为时,使用显式逻辑可能更符合语义。 - -```rust -#[chain] -fn handle_some_entry(prev: SomeEntry) -> Next { - let confirmed: bool = prev.pick::<Yes>(()).unpack().is_yes(); - let confirm: bool = prev.pick::<bool>(["--confirm", "-C"]).unpack(); - - // 其他逻辑 -} -``` - -## 特殊用法:`usize` 解析 - - **Mingling** 为 `usize` 提供了一个特殊的用法:解析类似 `25G`、`32mb` 等字样 ✏️ - -```rust -#[test] -fn parse_size() { - let vec = vec!["--size".to_string(), "25mib".to_string()]; - let size: usize = vec.pick(["--size", "-S"]).unpack(); - assert_eq!(size, 25 * 1024 * 1024); -} -``` - -## 自定义可解析类型 - - 您可以使用 `Pickable` trait 使您的类型支持被 `Picker` 解析,这也是 `Picker` 拓展性的来源 ✏️ - -```rust -// 必须实现 Default:当解析失败时,内部会直接记录默认值 -#[derive(Default)] -pub struct Address { - ip: String, - port: u16, -} - -impl Pickable for Address { - type Output = Self; - fn pick(args: &mut Argument, flag: Flag) -> Option<Self::Output> { - // 直接从 Argument 中使用 Flag 提取原始字符 - let raw = args.pick_argument(flag)?; - - // 解析原始字符,转换为结构化数据 - let parts: Vec<&str> = raw.split(':').collect(); - let ip = parts.first()?.to_string(); - let port: u16 = parts.get(1)?.parse().ok()?; - - Some(Address { ip, port }) - } -} -``` - - 我们为 `Address` 实现 `Pickable`:接下来我们便可以使用 `ip:port` 的方式来输入参数了 ✏️ - -```rust -dispatcher!("connect", ConnectCommand => ConnectEntry); - -pack!(ResultConnected = Address); - -#[chain] -fn handle_connect_entry(prev: ConnectEntry) -> Next { - let address: Address = prev.pick("--addr").unpack(); - ResultConnected::new(address) -} - -#[renderer] -fn render_connected(prev: ResultConnected) { - let addr = prev.inner; - r_println!("Connected: IP: {} PORT: {}", addr.ip, addr.port); -} -``` - - 执行效果如下: - -```bash -~> your-bin connect --addr 127.0.0.1:8080 -Connected: IP: 127.0.0.1 PORT: 8080 -``` - -## 自动为枚举实现 Pickable - - 要为枚举类型实现 `Pickable` trait,无需手动实现:`Picker` 会为所有实现了 `PickableEnum` 的类型实现 `Pickable`,只需要该枚举类型实现了 `EnumTag` ✏️ - -```rust -// Debug : 用于渲染 -// Default: 用于 Picker 解析 -// EnumTag: 用于实现 PickableEnum -#[derive(Debug, Default, EnumTag)] -pub enum Fruits { - #[default] - Apple, - Banana, - Orange, -} - -// 为 Fruits 实现 PickableEnum -impl PickableEnum for Fruits {} -``` - - 接下来您便可以直接使用 `Picker` 解析该类型 ✏️ - -```rust -pack!(ResultFruit = Fruits); - -#[chain] -fn handle_eat_fruit_entry(prev: EatFruitEntry) -> Next { - let fruit: Fruits = prev.pick("--fruit").unpack(); - ResultFruit::new(fruit) -} - -#[renderer] -fn render_ate_fruit(prev: ResultFruit) { - r_println!("Picked fruit: {:?}", *prev); -} -``` - - 以上便是 `Picker` 的所有用法,在下一章节,我会介绍如何在 **Mingling** 内为命令实现帮助文档。 - -<p align="center" style="font-size: 0.85em; color: gray;"> - Written by @Weicao-CatilGrass -</p> diff --git a/docs/_zh_CN/pages/4-implementing-help-display.md b/docs/_zh_CN/pages/4-implementing-help-display.md deleted file mode 100644 index 57179d7..0000000 --- a/docs/_zh_CN/pages/4-implementing-help-display.md +++ /dev/null @@ -1,4 +0,0 @@ -<h1 align="center">实现帮助文档显示</h1> -<p align="center"> - 用 help 宏为命令实现帮助文档 -</p> diff --git a/docs/_zh_CN/pages/5-implementing-completion.md b/docs/_zh_CN/pages/5-implementing-completion.md deleted file mode 100644 index f0729f7..0000000 --- a/docs/_zh_CN/pages/5-implementing-completion.md +++ /dev/null @@ -1,4 +0,0 @@ -<h1 align="center">实现命令行补全</h1> -<p align="center"> - 使用 Mingling Completion 实现全动态补全系统 -</p> diff --git a/docs/css/dark.css b/docs/css/dark.css index e7f7ac0..551be70 100644 --- a/docs/css/dark.css +++ b/docs/css/dark.css @@ -333,7 +333,7 @@ body.sticky .sidebar-toggle { } .markdown-section { margin: 0 auto; - max-width: 100%; + max-width: 80%; padding: 30px 45px 40px; position: relative; background-color: #121212; @@ -1021,3 +1021,10 @@ code .token { box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3); color: #f4fefe; } + +.markdown-section iframe { + border: none; + border-radius: 16px; + display: block; + margin: 1em auto; +} diff --git a/docs/css/light.css b/docs/css/light.css index d4f93dd..fd04754 100644 --- a/docs/css/light.css +++ b/docs/css/light.css @@ -331,7 +331,7 @@ body.sticky .sidebar-toggle { } .markdown-section { margin: 0 auto; - max-width: 100%; + max-width: 80%; padding: 30px 45px 40px; position: relative; } @@ -949,3 +949,11 @@ code .token { overflow-y: auto; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); } + +.markdown-section iframe { + border: none; + border-radius: 16px; + box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1); + display: block; + margin: 1em auto; +} diff --git a/docs/index.html b/docs/index.html index 3142dbd..505f02a 100644 --- a/docs/index.html +++ b/docs/index.html @@ -13,6 +13,12 @@ content="Quick start with Mingling and build your command-line program!" /> + <link rel="preconnect" href="https://fonts.googleapis.com" /> + <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin /> + <link + href="https://fonts.googleapis.com/css2?family=Source+Sans+Pro:wght@400;600;700&family=Roboto+Mono&family=Dosis:wght@500&display=swap" + rel="stylesheet" + /> <link rel="stylesheet" href="css/light.css" /> <link id="dark-style" rel="stylesheet" href="css/dark.css" disabled /> </head> diff --git a/docs/pages/1-creating-your-first-program.md b/docs/pages/1-creating-your-first-program.md deleted file mode 100644 index 7348805..0000000 --- a/docs/pages/1-creating-your-first-program.md +++ /dev/null @@ -1,258 +0,0 @@ -<h1 align="center">Creating your first Program</h1> -<p align="center"> - Learn <b>Mingling</b> and use it to create your first command-line program -</p> - -## Intro - - This chapter will guide you through **Mingling** step by step. - - Before we start, let me explain what **Mingling** can do: - - Without extra features, it is a sub-command dispatch system based on `proc-macro`: it matches user input, finds & creates the corresponding data, then pushes that data into a dispatcher that continually transforms its type. When the data can no longer be transformed, the program renders the final result to the terminal. - - In other words, you need to understand a new dev paradigm: **a fully type-based dispatch system**. This may feel **frustrating** at first, but once you get the hang of it, you'll be able to write CLI apps that are super easy to modify and extend. - - - -## Creating a Basic Program - - Next I'll walk you through creating a basic program—I assume you already have an empty Rust project ready! - -#### 1. Add Dependencies - - Add the following deps to `Cargo.toml` ✏️ - -```toml -[dependencies] -mingling = "0.1.9" - -# If you want the latest, try the version hosted on Github -mingling = { git = "https://github.com/catilgrass/mingling", branch = "main" } -``` - -> [!NOTE] -> -> This version matches the **Mingling** version used when writing this doc. Check [crates.io](https://crates.io/crates/mingling) for the latest release! 😄 -> -> **Mingling** docs are actively updated to keep pace with the latest version. - - - -#### 2. Create the Program - - Now, create the program in `src/main.rs` ✏️ - -```rust -fn main() { - // Create ThisProgram and run it - ThisProgram::new().exec(); -} - -// The gen_program! macro collects *all preceding* components & types -// then generates the `ThisProgram` struct -mingling::macros::gen_program!(); -``` - -> [!TIP] -> -> When `gen_program!()` expands, it gathers info from other components & types that were expanded before it. This means you must place `gen_program!()` at the very last expansion point in the crate. -> -> I recommend putting it at the end of `main.rs` or `lib.rs`. - - - -#### 3. Create a Command - - Of course, the program currently does nothing—it won't output anything at runtime. So let's create our first command `greet` and say hi to someone ✏️ - -```rust -fn main() { - // ... -} - -// Create a dispatcher, binding GreetCommand to the "greet" sub-command -// When the user specifies this command, send GreetEntry to the dispatcher -dispatcher!("greet", GreetCommand => GreetEntry); - -// ... -gen_program!(); -``` - - Don't be scared by the sudden macro and two new types! Let me explain what this macro does: - -##### About the `dispatcher!` macro 💡 - -1. It creates a `GreetCommand` struct and implements the `Dispatcher` trait - - *This tells the framework: there's a new dispatcher that will handle a sub-command's behavior.* - -2. It implements the `Dispatcher` trait's `node(&self) -> Node` function, setting the node to `"greet"` - - *This tells the framework: this dispatcher handles the `"greet"` sub-command.* - -3. It implements the `Dispatcher` trait's `begin` function, converting the user's full input into the first type `GreetEntry` - - *This tells the framework: when this dispatcher is matched, it sends a `GreetEntry` type to the dispatcher for further processing.* - - In short: **"When user types `greet`, I create a `GreetEntry` and throw it into the dispatcher for conversion."** - - - -#### 4. Register the Command - - After creating the `Dispatcher`, we have two types: `GreetCommand` and `GreetEntry`. First, register `GreetCommand` with `ThisProgram` ✏️ - -```rust -fn main() { - let mut program = ThisProgram::new(); - - // Register the dispatcher - program.with_dispatcher(GreetCommand); - program.exec(); -} -``` - - Now `ThisProgram` recognizes the `"greet"` sub-command, but the framework still doesn't know what `"greet"` should do. That's where we implement the actual logic: - - - -#### 5. Implement Rendering Behavior - - We want `"greet"` to output `"Hello, World"`: since we're outputting to the screen, we can use another **Mingling** component, `Renderer`, which handles rendering data to the terminal ✏️ - -```rust -// ... -dispatcher!("greet", GreetCommand => GreetEntry); - -// Declare a renderer `render_greet`, specifying the previous type as `GreetEntry` -#[renderer] -fn render_greet(_prev: GreetEntry) { - r_println!("Hello, World!"); -} - -// ... -gen_program!(); // The renderer will be registered with the program -``` - - For functions marked with `#[renderer]`, **Mingling** strictly enforces only one function signature: - -```rust -#[renderer] -fn renderer_name (_prev: PreviousType) { } -``` - - The macro reads the type of the first param and tells `gen_program!` that this function renders that type. - -##### About `r_println!()` 💡 - - You might notice that the print macro used inside `#[renderer]` is `r_println!` instead of `println!`. This is because the framework's rendering logic doesn't happen inside that function: after `#[renderer]` expands, it injects a `__renderer_inner_result: &mut RenderResult` into the function; `r_println!` appends the message to the `RenderResult`, and after the dispatcher closes, the final rendered data is handed to `Program::exec` for output. - - - -#### 6. Add Execution Logic - - I bet you're already itching to implement something like `greet Alice` to output `"Hello, Alice!"`—and this section is about to do just that! - - **Mingling**'s core execution flow is `Dispatcher -> Chain -> Renderer`, and the key part is `Chain`: it converts the input data type into another type, then lets the dispatcher find the next `Chain` or `Renderer` based on the result type ✏️ - -```rust -dispatcher!("greet", GreetCommand => GreetEntry); - -// Wrap the intermediate type `ResultGreetSomeone` -pack!(ResultGreetSomeone = String); - -#[chain] -fn handle_greet_entry(prev: GreetEntry) -> Next { - let args = prev.inner; - let name = args - .first() - .cloned() - .unwrap_or_else(|| "World".to_string()); - - // Wrap into intermediate type - ResultGreetSomeone::new(name) -} - -#[renderer] -fn render_greet_someone(prev: ResultGreetSomeone) { - // Deref prev to get the raw type - r_println!("Hello, {}!", *prev); -} -``` - - Just like `#[renderer]`, we created a `#[chain]` that processes type `GreetEntry` and outputs `ResultGreetSomeone`. - - This inserts a `Chain` between the original `Dispatcher` and `Renderer`: it extracts the user's input params (or falls back to "World"), then passes them to the renderer to print to the terminal. - -##### About `Next` 💡 - - `Next` is a placeholder generated by `gen_program!()`. After `#[chain]` expands, it's replaced by a type-erased type `ChainProcess<ThisProgram>` that the dispatcher can recognize, helping reduce boilerplate code. - -> [!NOTE] -> -> `Next` is a temporary solution; the next update will wait until Rust's `Impl In Type Aliases` feature is stable. -> -> **But don't worry**: the next `Next` update won't introduce **breaking changes!** - -##### About `pack!` 💡 - - `pack!` is an **extremely** frequently used macro in **Mingling** development: it wraps any type into another type and auto-derives the traits the framework needs. - - Its syntax is as simple as you see: - -```rust -pack!(PackedType = RawType); -``` - - Note: `pack!` doesn't support types with lifetimes, because types are always moved (not borrowed) between dispatchers. - - - -#### 7. Compile & Run - - Alright, we've completed a basic CLI app. Here's the full code—you can paste it and run it directly: - -```rust -use mingling::macros::{chain, dispatcher, gen_program, pack, r_println, renderer}; - -fn main() { - let mut program = ThisProgram::new(); - program.with_dispatcher(GreetCommand); - program.exec(); -} - -dispatcher!("greet", GreetCommand => GreetEntry); - -pack!(ResultGreetSomeone = String); - -#[chain] -fn handle_greet_entry(prev: GreetEntry) -> Next { - let args = prev.inner; - let name = args.first().cloned().unwrap_or_else(|| "World".to_string()); - - ResultGreetSomeone::new(name) -} - -#[renderer] -fn render_greet_someone(prev: ResultGreetSomeone) { - r_println!("Hello, {}!", *prev); -} - -gen_program!(); -``` - - Output: - -```bash -~> your-bin greet -Hello, World! -~> your-bin greet Alice -Hello, Alice! -``` - - At this point, you have successfully created a basic **Mingling** command-line program. The next chapter will explain how to implement a fallback mechanism for your command-line program to handle cases where a command or renderer does not exist. - -<p align="center" style="font-size: 0.85em; color: gray;"> - Written by @Weicao-CatilGrass -</p> diff --git a/docs/pages/2-implementing-fallbacks.md b/docs/pages/2-implementing-fallbacks.md deleted file mode 100644 index 3f3cb93..0000000 --- a/docs/pages/2-implementing-fallbacks.md +++ /dev/null @@ -1,141 +0,0 @@ -<h1 align="center">Implementing Fallbacks</h1> -<p align="center"> - Handling error cases in your program using a fallback mechanism -</p> - -## Recap - - In the last post, we introduced how to develop a basic CLI program using **Mingling**: you can use the `"greet"` subcommand to output `"Hello, World!"`, or use `"greet Alice"` to output `"Hello, Alice!"` - - But what happens when the user does not enter `"greet"`? Let's type a command and find out ⌨️ - -```bash -~> your-bin hello -~> your-bin hello Alice -``` - - **It does nothing!** 👆 - - Let me explain why: **Mingling** doesn't presume to act; it will not output anything to the terminal no matter what happens (except for `panic!` under `unwind`) - - This means that if you need to actively do something when your CLI program encounters an error, you have to state it explicitly. - - Fortunately, **Mingling** provides a convenient interface for this functionality: inside the `gen_program!` macro, two `FallBack` types are generated - -|Type|When it occurs|How it occurs| -|-|-|-| -|RendererNotFound|When a renderer cannot be found for scheduling|Scheduled as a `Chain`| -|DispatcherNotFound|When a command is entered but no dispatcher matches|Scheduled as a `Chain`| - -### The `DispatcherNotFound` Type - - Let's first focus on the `DispatcherNotFound` type. It is produced as follows: - -```rust -// 1. Define the `greet` command -dispatcher!("greet", GreetCommand => GreetEntry); - -fn main() { - // ->> User enters "hello Alice" - let mut program = ThisProgram::new(); - - // 2. Import the `greet` command - program.with_dispatcher(GreetCommand); - - // 3. Execute the program - program.exec(); -} - -// ... - -// 5. Receive the DispatcherNotFound dispatch -#[renderer] -fn dispatcher_not_found(prev: DispatcherNotFound) { - // 6. Output - r_println!( - "Cannot match any command! Current input: \"{}\"", - prev.join(" ") - ); -} - -// 4. Cannot match any dispatcher named `hello` -// Forward the user's arguments as-is to DispatcherNotFound -gen_program!(); -``` - - The output of the above program is: - -```bash -~> omg hello -Cannot match any command! Current input: "hello" - -~> omg hello Alice -Cannot match any command! Current input: "hello Alice" -``` - - Now, if the user enters a command that doesn't match, **Mingling** will output the appropriate message! - -## The `RendererNotFound` Type - - `RendererNotFound` can be produced in two ways: - - 1. The type was explicitly dispatched to a `Renderer` (using the `.to_render()` function), but the type does not have a renderer implementation - 2. The type was dispatched to a `Chain`, but the type has neither a chain nor a renderer implementation - - Generally, `RendererNotFound` **should not occur in business logic**: its dispatch means your type needs to be rendered but can't be. You can use this type to pinpoint which type is missing a renderer implementation ✏️ - -```rust -dispatcher!("greet", GreetCommand => GreetEntry); - -fn main() { - let mut program = ThisProgram::new(); - - program.with_dispatcher(GreetCommand); - program.exec(); -} - -pack!(ResultGreetSomeone = String); - -#[chain] -fn handle_greet_entry(prev: GreetEntry) -> Next { - let args = prev.inner; - let name = args.first().cloned().unwrap_or_else(|| "World".to_string()); - - ResultGreetSomeone::new(name) -} - -// Let's intentionally remove the renderer implementation for `ResultGreetSomeone` -// #[renderer] -// fn render_greet_someone(prev: ResultGreetSomeone) { -// r_println!("Hello, {}!", *prev); -// } - -#[renderer] -fn renderer_not_found(prev: RendererNotFound) { - if *prev == "DispatcherNotFound" { - return; // Exclude the "DispatcherNotFound" type - } - - // Trigger `panic!` when a renderer is not found - panic!("Renderer \"{}\" not found!", *prev); -} - -gen_program!(); - -``` - - The output of the above program is: - -```bash -~> your-bin greet Alice - -thread 'main' (90772) panicked at src/bin/your-bin.rs:30:5: -Renderer "ResultGreetSomeone" not found! -note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace -``` - - The above is the fallback mechanism of **Mingling**. In the next chapter, you will learn how to use `Picker` to parse complex user inputs. - -<p align="center" style="font-size: 0.85em; color: gray;"> - Written by @Weicao-CatilGrass -</p> diff --git a/docs/pages/3-parsing-complex-arguments.md b/docs/pages/3-parsing-complex-arguments.md deleted file mode 100644 index 141c571..0000000 --- a/docs/pages/3-parsing-complex-arguments.md +++ /dev/null @@ -1,364 +0,0 @@ -<h1 align="center">Parsing Complex Args</h1> -<p align="center"> - Use Mingling Picker to parse complex user input -</p> - -## Intro - - In the prev. example, we built a CLI app with a `"greet"` subcommand that outputs the user's first arg. - - You may have noticed the approach used was almost direct string manipulation—not very semantic, and hard to maintain long-term. - -```rust -let name = args.first().cloned().unwrap_or_else(|| "World".to_string()); -``` - - This chapter introduces a new **Mingling** feature: `Picker`. It provides a lightweight parsing solution that meshes well with **Mingling**'s typed routing. - - To enable `Picker`, edit `Cargo.toml` ✏️ - -```toml -[dependencies] -mingling = { - version = "...", - features = ["parser"] -} -``` - - Enough talk, let's get coding and rewrite the parsing logic from the prev. section ✏️ - -```rust -#[chain] -fn handle_greet_entry(prev: GreetEntry) -> Next { - // Prev. approach: - // let args = prev.inner; - // let name = args.first().cloned().unwrap_or_else(|| "World".to_string()); - - // New approach with Picker - let name = prev.pick_or((), "World").unpack(); - - ResultGreetSomeone::new(name) -} -``` - - `Picker` implements `pick`, `pick_or`, and `pick_or_route` for anything `Into<Vec<String>>`. These functions let you semantically **pick** args from a string list and convert them into structured data. - - In the code above: - -```rust -prev.pick_or((), "World").unpack(); -``` - - Its meaning: - -```rust - prev.pick_or((), "World").unpack(); -// ~~~~ ~~~~~~~ ~~ ~~~~~~~ ~~~~~~~~ -// | | | | |_ unpack to String -// | | | |__________ default value is "World" -// | | |______________ pick the first positional arg (no flag) -// | |______________________ pick or use default -// |___________________________ from the prev. input -``` - -## Parsing Flag Args - - If your app needs to parse flag args (e.g., `greet --name Alice`), do: - -```rust -prev.pick_or(["--name", "-n"], "World").unpack(); -``` - - Its meaning: - -```rust - prev.pick_or(["--name", "-n"], "World").unpack(); -// ~~~~ ~~~~~~~ ~~~~~~~~~~~~~~~~ ~~~~~~~ ~~~~~~~~ -// | | | | |_ unpack to String -// | | | |__________ default value is "World" -// | | |____________________________ pick the value after "--name" or "-n" -// | |____________________________________ pick or use default -// |_________________________________________ from the prev. input -``` - -## About `.unpack()` 💡 - - You may have noticed `Picker` calls `.unpack()` at the end of parsing. It converts the parsed result into structured info. - - For a single pick, `.unpack()` returns a single value. For multiple picks, `Picker` returns a tuple: - -```rust -let name_single: String = prev.clone().pick_or((), "World").unpack(); -let (name, age, id) = prev - .pick::<String>(["--name", "-n"]) - .pick::<u8>(["--age", "-a"]) - .pick::<u32>(["--id", "-I"]) - .unpack(); - -// Parses: --name Alice --age 21 --id 0711251 -``` - -> [!IMPORTANT] -> `Picker` is very order-sensitive, esp. with positional args: it parses sequentially. -> -> If you need to parse positional args, make sure to pick & consume all **flag args** first. - -## Using `pick_or_route` for Edge Cases - - Ha, as the old saying goes: "Never trust your users." Missing required args, type mismatches, enabling mutually exclusive options—these are all headache-inducing edge cases. - - `pick_or_route` handles these by routing the chain to a dedicated error-handling type, giving you fine-grained error control. - - Let's write a simple example showing basic usage: - -```rust -dispatcher!("greet", GreetCommand => GreetEntry); - -pack!(ResultGreetSomeone = String); -pack!(ErrorGreetNoNameProvided = ()); - -#[chain] -fn handle_greet_entry(prev: GreetEntry) -> Next { - // Use `pick_or_route` to extract the `--name` arg - // If missing or parse fails, route to ErrorGreetNoNameProvided - let pick_result = prev - .pick_or_route( - ["--name", "-n"], - ErrorGreetNoNameProvided::default().to_render(), - ) - // After using any routable method, `unpack` returns `Result<Value, Route>` - .unpack(); - - // Use the `route!` macro to expand `pick_result`, - // If it's `Err`, the chain returns here, routing to the specified type - let name = route!(pick_result); - ResultGreetSomeone::new(name).to_chain() -} - -// Handles rendering for `ErrorGreetNoNameProvided` -#[renderer] -fn render_err_greet_no_name_provided(_prev: ErrorGreetNoNameProvided) { - r_println!("Error: No name provided.") -} - -#[renderer] -fn render_greet_someone(prev: ResultGreetSomeone) { - r_println!("Hello, {}!", *prev); -} -``` - - Using `pick_or_route` makes the code a bit more complex: `.unpack()` no longer returns the value directly, but `Result<Value, Route>`. - - However, **Mingling** provides the `route!` macro to simplify expansion. It's not complex—just cuts some boilerplate: - -```rust -let name = route!(pick_result); - -// Expands to -let name = match pick_result { - Ok(r) => r, - Err(e) => return e, -}; -``` - -## Post-Processing Extracted Values - - After using `pick` to extract user input, you can use `after` or `after_or_route` to process the arg immediately ✏️ - -```rust -#[chain] -fn handle_greet_entry(prev: GreetEntry) -> Next { - let name = prev - .pick_or(["--name", "-n"], "World") - // After extracting `--name`, format it immediately - .after(|name: String| { - name.replace(['-', '_', '.'], " ") - .to_lowercase() - .trim() - .to_string() - }) - .unpack(); - - ResultGreetSomeone::new(name) // name is now formatted -} -``` - - Similarly, use `after_or_route` to handle format errors in input args ✏️ - -```rust -dispatcher!("greet", GreetCommand => GreetEntry); - -pack!(ResultGreetSomeone = String); -pack!(ErrorGreetNameTooLong = usize); - -#[chain] -fn handle_greet_entry(prev: GreetEntry) -> Next { - let pick_result = prev - .pick_or(["--name", "-n"], "World") - // Unlike `after`, this borrows &String - .after_or_route(|name: &String| { - name.replace(['-', '_', '.'], " ") - .to_lowercase() - .trim() - .to_string(); - - // Check name length, route to error type if too long - let len = name.len(); - if len < 32 { - Ok(name.clone()) - } else { - Err(ErrorGreetNameTooLong::new(len).to_render()) - } - }) - .unpack(); - let name = route!(pick_result); - - ResultGreetSomeone::new(name).to_chain() -} - -#[renderer] -fn render_error_greet_name_too_long(prev: ErrorGreetNameTooLong) { - let len = *prev; - r_println!("Error: name too long (length: {} > 32)", len); -} - -#[renderer] -fn render_greet_someone(prev: ResultGreetSomeone) { - r_println!("Hello, {}!", *prev); -} -``` - -## Parsing Booleans - - `Picker` can parse **bool** types too, but with both explicit and implicit modes: - - |Mode|Format| - |-|-| - |Explicit|`--confirm true` or `--confirm yes`| - |Implicit|`--confirmed`| - - - Using `.pick` on `bool` uses implicit parsing: flag present → `true` - - Using `.pick` on `mingling::parser::Yes` or `mingling::parser::True` uses explicit parsing; the value must be `true` / `yes` to be recognized as `true` - - Generally, implicit parsing is enough, but for positional args or important confirmations, explicit logic might be more semantic. - -```rust -#[chain] -fn handle_some_entry(prev: SomeEntry) -> Next { - let confirmed: bool = prev.pick::<Yes>(()).unpack().is_yes(); - let confirm: bool = prev.pick::<bool>(["--confirm", "-C"]).unpack(); - - // other logic -} -``` - -## Special Use: `usize` Parsing - - **Mingling** has a special use for `usize`: parsing strings like `25G`, `32mb`, etc. ✏️ - -```rust -#[test] -fn parse_size() { - let vec = vec!["--size".to_string(), "25mib".to_string()]; - let size: usize = vec.pick(["--size", "-S"]).unpack(); - assert_eq!(size, 25 * 1024 * 1024); -} -``` - -## Custom Parsable Types - - Use the `Pickable` trait to make your types parsable by `Picker`. This is where `Picker`'s extensibility comes from ✏️ - -```rust -// Must implement Default: parse failures record the default directly -#[derive(Default)] -pub struct Address { - ip: String, - port: u16, -} - -impl Pickable for Address { - type Output = Self; - fn pick(args: &mut Argument, flag: Flag) -> Option<Self::Output> { - // Extract raw string from Argument using Flag - let raw = args.pick_argument(flag)?; - - // Parse raw string into structured data - let parts: Vec<&str> = raw.split(':').collect(); - let ip = parts.first()?.to_string(); - let port: u16 = parts.get(1)?.parse().ok()?; - - Some(Address { ip, port }) - } -} -``` - - With `Pickable` implemented for `Address`, we can now use `ip:port` format for input ✏️ - -```rust -dispatcher!("connect", ConnectCommand => ConnectEntry); - -pack!(ResultConnected = Address); - -#[chain] -fn handle_connect_entry(prev: ConnectEntry) -> Next { - let address: Address = prev.pick("--addr").unpack(); - ResultConnected::new(address) -} - -#[renderer] -fn render_connected(prev: ResultConnected) { - let addr = prev.inner; - r_println!("Connected: IP: {} PORT: {}", addr.ip, addr.port); -} -``` - - Running it: - -```bash -~> your-bin connect --addr 127.0.0.1:8080 -Connected: IP: 127.0.0.1 PORT: 8080 -``` - -## Auto-Implementing Pickable for Enums - - No need to manually implement `Pickable` for enums: `Picker` auto-implements it for any type that implements `PickableEnum`, as long as it also implements `EnumTag` ✏️ - -```rust -// Debug : for rendering -// Default: for Picker parsing -// EnumTag: for implementing PickableEnum -#[derive(Debug, Default, EnumTag)] -pub enum Fruits { - #[default] - Apple, - Banana, - Orange, -} - -// Implement PickableEnum for Fruits -impl PickableEnum for Fruits {} -``` - - Now you can directly use `Picker` to parse this type ✏️ - -```rust -pack!(ResultFruit = Fruits); - -#[chain] -fn handle_eat_fruit_entry(prev: EatFruitEntry) -> Next { - let fruit: Fruits = prev.pick("--fruit").unpack(); - ResultFruit::new(fruit) -} - -#[renderer] -fn render_ate_fruit(prev: ResultFruit) { - r_println!("Picked fruit: {:?}", *prev); -} -``` - - That's all for `Picker`'s usage. In the next chapter, I'll introduce how to implement help docs for commands in **Mingling**. - -<p align="center" style="font-size: 0.85em; color: gray;"> - Written by @Weicao-CatilGrass -</p> diff --git a/docs/pages/4-implementing-help-display.md b/docs/pages/4-implementing-help-display.md deleted file mode 100644 index 625863e..0000000 --- a/docs/pages/4-implementing-help-display.md +++ /dev/null @@ -1,4 +0,0 @@ -<h1 align="center">Impl Help Display</h1> -<p align="center"> - Implement help documentation for commands using the help macro -</p> diff --git a/docs/pages/5-implementing-completion.md b/docs/pages/5-implementing-completion.md deleted file mode 100644 index 7622775..0000000 --- a/docs/pages/5-implementing-completion.md +++ /dev/null @@ -1,4 +0,0 @@ -<h1 align="center">Impl Shell Completion</h1> -<p align="center"> - Implementing a fully dynamic completion system using Mingling Completion -</p> diff --git a/docs/play/play.html b/docs/play/play.html new file mode 100644 index 0000000..8620908 --- /dev/null +++ b/docs/play/play.html @@ -0,0 +1,135 @@ +<!doctype html> +<html lang="zh-CN"> + <head> + <meta charset="UTF-8" /> + <meta name="viewport" content="width=device-width, initial-scale=1.0" /> + + <!-- highlight.js --> + <link rel="stylesheet" href="../scripts/highlight/github.min.css" /> + <link + id="hljs-light" + rel="stylesheet" + href="../scripts/highlight/github.min.css" + /> + <link + id="hljs-dark" + rel="stylesheet" + href="../scripts/highlight/github-dark.min.css" + disabled + /> + <script src="../scripts/highlight/highlight.min.js"></script> + <script src="../scripts/highlight/rust.min.js"></script> + <script src="../scripts/highlight/bash.min.js"></script> + + <link rel="preconnect" href="https://fonts.googleapis.com" /> + <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin /> + <link + href="https://fonts.googleapis.com/css2?family=JetBrains+Mono&display=swap" + rel="stylesheet" + /> + <link rel="stylesheet" href="style.css" /> + </head> + <body> + <!-- Topbar --> + <div class="topbar"> + <h1 class="topbar__title"> + <span id="tutorialTitle">Title</span> + </h1> + <div style="display: flex; align-items: center; gap: 16px"> + <span class="topbar__step"> + STEP <span id="stepNum">1</span> / + <span id="totalSteps">0</span> + </span> + <button class="theme-toggle" id="themeToggle">🌙</button> + </div> + </div> + + <!-- Main area --> + <div class="layout" id="layout"> + <!-- Left: code panel --> + <div class="code-panel"> + <pre id="codeDisplay"></pre> + </div> + + <!-- Right: description --> + <div class="speech-panel"> + <div class="speech-content" id="speechDisplay"></div> + </div> + </div> + + <!-- Control bar --> + <div class="controls"> + <button id="prevBtn" disabled>◀ PREV</button> + <button id="nextBtn" class="controls__btn--primary">NEXT ▶</button> + + <div class="controls__progress"> + <div + class="controls__progress-fill" + id="progressFill" + style="width: 0%" + ></div> + </div> + + <span class="controls__text" id="progressText">0%</span> + </div> + + <script src="player.js"></script> + <script> + (function () { + var hljsDark = document.getElementById("hljs-dark"); + var html = document.documentElement; + var btn = document.getElementById("themeToggle"); + + function resolveTheme() { + var t = localStorage.getItem("theme"); + if (t === "dark" || t === "light") return t; + return window.matchMedia && + window.matchMedia("(prefers-color-scheme: dark)") + .matches + ? "dark" + : "light"; + } + + function applyTheme(t) { + if (t === "dark") { + hljsDark.disabled = false; + html.setAttribute("data-theme", "dark"); + if (btn) btn.textContent = "☀️"; + } else { + hljsDark.disabled = true; + html.setAttribute("data-theme", "light"); + if (btn) btn.textContent = "🌙"; + } + } + + applyTheme(resolveTheme()); + + window.addEventListener("storage", function (e) { + if (e.key === "theme") applyTheme(resolveTheme()); + }); + + setInterval(function () { + var desired = resolveTheme(); + var current = html.getAttribute("data-theme") || "dark"; + if (desired !== current) applyTheme(desired); + }, 1000); + + if (btn) { + btn.addEventListener("click", function () { + var current = resolveTheme(); + var next = current === "dark" ? "light" : "dark"; + localStorage.setItem("theme", next); + applyTheme(next); + }); + } + })(); + </script> + </body> +</html> + +<!-- + INCLUDE + <iframe + src="../play/play.html?tur=default.md&title=Title" + height="400px"/> +--> diff --git a/docs/play/player.js b/docs/play/player.js new file mode 100644 index 0000000..796debe --- /dev/null +++ b/docs/play/player.js @@ -0,0 +1,198 @@ +function parseTeachMarkdown(raw) { + raw = raw.replace(/^```\s*\n?/, ""); + + const blocks = raw.split(/^---\s*$/m); + const steps = []; + + for (const block of blocks) { + const text = block.trim(); + if (!text) continue; + + const codes = []; + let match; + const codeRe = /```(rust|toml|bash|text)\n([\s\S]*?)```/g; + while ((match = codeRe.exec(text)) !== null) { + const lang = match[1]; + const code = match[2].trimEnd(); + codes.push({ lang, code }); + } + + const last = codes.length > 0 ? codes[codes.length - 1] : null; + const code = last ? { lang: last.lang, code: last.code } : null; + + const speech = text + .replace(/```(rust|toml|bash|text)\n[\s\S]*?```/g, "") + .trim(); + const paragraphs = speech + .split(/\n+/) + .map((s) => s.trim()) + .filter(Boolean); + + steps.push({ code, paragraphs }); + } + + let lastCode = ""; + let lastLang = "rust"; + let lastParagraphs = []; + for (const step of steps) { + if (step.code !== null) { + lastCode = step.code.code; + lastLang = step.code.lang; + step.code = { lang: lastLang, code: lastCode }; + } else { + step.code = { lang: lastLang, code: lastCode }; + } + + if (step.paragraphs.length > 0) { + lastParagraphs = step.paragraphs; + } else { + step.paragraphs = lastParagraphs; + } + } + + return steps; +} + +function renderCode(codeInfo) { + if (!codeInfo || !codeInfo.code) return ""; + + const lang = codeInfo.lang || "rust"; + const code = codeInfo.code; + const lines = code.split("\n"); + const html = []; + + const plainText = lang === "text"; + + for (let i = 0; i < lines.length; i++) { + const lineNum = i + 1; + const rawLine = lines[i]; + const prefix = `<span class="line-num">${lineNum}</span>`; + + if (plainText) { + html.push(`${prefix}${escapeHtml(rawLine)}`); + continue; + } + + const hl = rawLine.match(/^(.*?)\s*<{8,}\s*"([^"]*?)"\s*$/); + + if (hl) { + const indent = rawLine.match(/^\s*/)[0]; + const hlCode = hljs.highlight(indent + hl[1].trimStart(), { + language: lang, + }).value; + html.push( + `${prefix}${hlCode} <span class="bubble">${escapeHtml(hl[2])}</span>`, + ); + } else if (rawLine.trim() === "") { + html.push(prefix); + } else { + const hlLine = hljs.highlight(rawLine, { language: lang }).value; + html.push(`${prefix}${hlLine}`); + } + } + + return html.join("\n"); +} + +function escapeHtml(text) { + return text + .replace(/&/g, "&") + .replace(/</g, "<") + .replace(/>/g, ">"); +} + +function renderSpeech(paragraphs) { + return paragraphs + .map((p) => { + if (p.startsWith("> ")) { + return `<div class="cmd">${escapeHtml(p.slice(2))}</div>`; + } + let html = p + .replace(/`([^`]+)`/g, "<code>$1</code>") + .replace( + /\*\*([^*]+)\*\*/g, + '<strong style="color:#7dcfff">$1</strong>', + ); + return `<p>${html}</p>`; + }) + .join(""); +} + +const dom = { + code: document.getElementById("codeDisplay"), + speech: document.getElementById("speechDisplay"), + stepNum: document.getElementById("stepNum"), + totalSteps: document.getElementById("totalSteps"), + progress: document.getElementById("progressFill"), + progressText: document.getElementById("progressText"), + prevBtn: document.getElementById("prevBtn"), + nextBtn: document.getElementById("nextBtn"), +}; + +let steps = []; +let currentStep = 0; + +function goToStep(index) { + currentStep = Math.max(0, Math.min(index, steps.length - 1)); + const step = steps[currentStep]; + + dom.code.innerHTML = renderCode(step.code); + dom.speech.innerHTML = renderSpeech(step.paragraphs); + + dom.stepNum.textContent = currentStep + 1; + dom.totalSteps.textContent = steps.length; + const pct = + steps.length > 1 + ? Math.round((currentStep / (steps.length - 1)) * 100) + : 100; + dom.progress.style.width = pct + "%"; + dom.progressText.textContent = pct + "%"; + + dom.prevBtn.disabled = currentStep === 0; + const isLast = currentStep === steps.length - 1; + dom.nextBtn.disabled = false; + dom.nextBtn.textContent = isLast ? "🎉 COMPLETE" : "NEXT ▶"; +} + +dom.prevBtn.addEventListener("click", () => goToStep(currentStep - 1)); +dom.nextBtn.addEventListener("click", () => { + if (currentStep < steps.length - 1) goToStep(currentStep + 1); +}); + +document.addEventListener("keydown", (e) => { + if (e.key === "ArrowRight" || e.key === " " || e.key === "Enter") { + e.preventDefault(); + if (currentStep < steps.length - 1) goToStep(currentStep + 1); + } else if (e.key === "ArrowLeft") { + e.preventDefault(); + if (currentStep > 0) goToStep(currentStep - 1); + } +}); + +async function loadTutorial(filePath) { + try { + const resp = await fetch(filePath); + const raw = await resp.text(); + steps = parseTeachMarkdown(raw); + dom.totalSteps.textContent = steps.length; + goToStep(0); + } catch (e) { + dom.code.textContent = "Load tutorial failed: " + e.message; + } +} + +const params = new URLSearchParams(window.location.search); +const tutorialFile = "sources/" + (params.get("tur") || "default.md"); + +const title = params.get("title"); +if (title) { + document.getElementById("tutorialTitle").textContent = title; +} + +const layoutEl = document.getElementById("layout"); +const speechPanel = document.querySelector(".speech-panel"); +const codePanel = document.querySelector(".code-panel"); +layoutEl.append(speechPanel, codePanel); +layoutEl.classList.add("layout--tb"); + +loadTutorial(tutorialFile); diff --git a/docs/play/style.css b/docs/play/style.css new file mode 100644 index 0000000..7a6f27d --- /dev/null +++ b/docs/play/style.css @@ -0,0 +1,337 @@ +*, +*::before, +*::after { + box-sizing: border-box; + margin: 0; + padding: 0; +} + +:root { + --bg-primary: #1a1b1c; + --bg-secondary: #1f2021; + --border: #2f3031; + --text-primary: #c0c1c2; + --text-secondary: #7a7b7c; + --text-muted: #565758; + --code-bg: #292a2b; + --code-text: #bbbcbd; + --bubble-bg: #e64a199f; + --bubble-text: #ffccbc; + --line-num: #3b3c3d; + --btn-bg: #2f3031; + --btn-text: #c0c1c2; + --btn-hover: #3b3c3d; + --btn-primary-bg: #7a7b7c; + --btn-primary-text: #1a1b1c; + --btn-primary-hover: #898a8b; + --progress-bg: #2f3031; + --progress-fill: #7a7b7c; + --cmd-bg: #1a1b1c; + --cmd-border: #2f3031; + --cmd-text: #9e9fa0; + --topbar-bg: #1f2021; + --hljs-bg: #1a1b1c; +} + +[data-theme="light"] { + --bg-primary: #ffffff; + --bg-secondary: #f5f6f7; + --border: #dcddde; + --text-primary: #2c2d2e; + --text-secondary: #5a5b5c; + --text-muted: #8a8b8c; + --code-bg: #e8e9ea; + --code-text: #2c2d2e; + --bubble-bg: #e64a19cf; + --bubble-text: #ffffff; + --line-num: #b0b1b2; + --btn-bg: #dcddde; + --btn-text: #2c2d2e; + --btn-hover: #c8c9ca; + --btn-primary-bg: #3a7bd5; + --btn-primary-text: #ffffff; + --btn-primary-hover: #2a6bc5; + --progress-bg: #dcddde; + --progress-fill: #3a7bd5; + --cmd-bg: #f5f6f7; + --cmd-border: #dcddde; + --cmd-text: #5a5b5c; + --topbar-bg: #f5f6f7; + --hljs-bg: #f5f6f7; +} + +body { + font-family: + -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Noto Sans SC", + sans-serif; + background: var(--bg-primary); + color: var(--text-primary); + height: 100vh; + display: flex; + flex-direction: column; +} + +/* Top bar */ +.topbar { + padding: 12px 24px; + background: var(--topbar-bg); + border-bottom: 1px solid var(--border); + display: flex; + align-items: center; + justify-content: space-between; + flex-shrink: 0; +} + +.topbar__title { + font-size: 18px; + font-weight: 600; + color: var(--text-secondary); +} + +.topbar__step { + font-size: 14px; + color: var(--text-muted); +} + +/* Theme toggle button */ +.theme-toggle { + background: none; + border: 1px solid var(--border); + color: var(--text-primary); + cursor: pointer; + font-size: 16px; + padding: 4px 10px; + border-radius: 6px; + transition: all 0.15s; + font-family: inherit; + line-height: 1; +} + +.theme-toggle:hover { + background: var(--btn-hover); +} + +/* Main panel */ +.layout { + display: flex; + flex: 1; + overflow: hidden; +} + +/* Left: code panel */ +.code-panel { + flex: 1; + background: var(--bg-primary); + overflow: hidden; +} + +.code-panel pre { + height: 100%; + margin: 0; + padding: 32px; + overflow: auto; + font-family: "JetBrains Mono", monospace; + font-size: 15px; + line-height: 1.7; + color: var(--text-primary); + tab-size: 4; + white-space: pre-wrap; + word-break: break-word; +} + +.code-panel pre .hljs { + background: transparent; +} + +.code-panel pre code.hljs { + font-family: inherit; + background: transparent; + padding: 0; +} + +/* Bubble comment */ +.code-panel pre .bubble { + display: inline-block; + position: relative; + margin-left: 8px; + padding: 0 12px; + background: var(--bubble-bg); + color: var(--bubble-text); + border-radius: 10px; + font-family: + -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Noto Sans SC", + sans-serif; + font-size: 13px; + font-style: normal; + line-height: 24px; + white-space: nowrap; + cursor: default; +} + +.code-panel pre .bubble::before { + content: ""; + position: absolute; + left: -6px; + top: 50%; + transform: translateY(-50%); + width: 0; + height: 0; + border-top: 5px solid transparent; + border-bottom: 5px solid transparent; + border-right: 6px solid var(--bubble-bg); +} + +/* Line number */ +.code-panel .line-num { + display: inline-block; + width: 32px; + text-align: right; + margin-right: 16px; + color: var(--line-num); + user-select: none; +} + +/* Right: description panel */ +.speech-panel { + width: 380px; + background: var(--bg-secondary); + border-left: 1px solid var(--border); + display: flex; + flex-direction: column; + flex-shrink: 0; +} + +.layout--tb { + flex-direction: column; +} + +.layout--tb .speech-panel { + width: 100%; + border-left: none; + border-bottom: 1px solid var(--border); + max-height: none; + flex: 0 0 auto; +} + +.layout--tb .code-panel { + flex: 1; + min-height: 0; +} + +.speech-content { + flex: 1; + padding: 32px 24px; + overflow-y: auto; +} + +.speech-content p { + font-size: 15px; + line-height: 1.8; + color: var(--text-primary); + margin-bottom: 16px; +} + +.speech-content p:last-child { + margin-bottom: 0; +} + +.speech-content code { + background: var(--code-bg); + color: var(--code-text); + padding: 2px 6px; + border-radius: 4px; + font-size: 13px; +} + +.speech-content .cmd { + display: block; + background: var(--cmd-bg); + border: 1px solid var(--cmd-border); + border-radius: 6px; + padding: 10px 14px; + margin: 12px 0; + font-family: "JetBrains Mono", monospace; + font-size: 14px; + color: var(--cmd-text); +} + +/* Control panel */ +.controls { + padding: 12px 24px; + background: var(--bg-secondary); + border-top: 1px solid var(--border); + display: flex; + align-items: center; + gap: 12px; + flex-shrink: 0; +} + +.controls button { + background: var(--btn-bg); + border: none; + color: var(--btn-text); + padding: 8px 20px; + border-radius: 6px; + font-size: 14px; + cursor: pointer; + transition: all 0.15s; + font-family: inherit; +} + +.controls button:hover { + background: var(--btn-hover); +} + +.controls button:active { + transform: scale(0.97); +} + +.controls__btn--primary { + background: var(--btn-primary-bg); + color: var(--btn-primary-text); + font-weight: 600; +} + +.controls__btn--primary:hover { + background: var(--btn-primary-hover); +} + +.controls button:disabled { + opacity: 0.4; + cursor: not-allowed; +} + +.controls__progress { + flex: 1; + height: 4px; + background: var(--progress-bg); + border-radius: 2px; + overflow: hidden; +} + +.controls__progress-fill { + height: 100%; + background: var(--progress-fill); + border-radius: 2px; + transition: width 0.3s; +} + +.controls__text { + font-size: 13px; + color: var(--text-muted); + min-width: 60px; + text-align: right; +} + +@media (max-width: 800px) { + .layout { + flex-direction: column; + } + + .speech-panel { + width: 100%; + border-left: none; + border-top: 1px solid var(--border); + max-height: 40vh; + } +} diff --git a/docs/res/graph/flow.drawio b/docs/res/graph/flow.drawio new file mode 100644 index 0000000..db162b8 --- /dev/null +++ b/docs/res/graph/flow.drawio @@ -0,0 +1,52 @@ +<mxfile host="Electron" agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/29.6.6 Chrome/144.0.7559.236 Electron/40.8.4 Safari/537.36" version="29.6.6"> + <diagram name="第 1 页" id="k4Qmdujz4_MrBDZmr3JA"> + <mxGraphModel dx="1899" dy="672" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0"> + <root> + <mxCell id="0" /> + <mxCell id="1" parent="0" /> + <mxCell id="waftmcoGh0EoTaqUSBJa-11" edge="1" parent="1" source="waftmcoGh0EoTaqUSBJa-1" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;fillColor=#d5e8d4;strokeColor=#82b366;" target="waftmcoGh0EoTaqUSBJa-2"> + <mxGeometry relative="1" as="geometry" /> + </mxCell> + <mxCell id="waftmcoGh0EoTaqUSBJa-1" parent="1" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" value="<font style="color: rgb(0, 0, 0);"><font>Vec</font><font>&lt;String&gt;</font></font>" vertex="1"> + <mxGeometry height="40" width="120" as="geometry" /> + </mxCell> + <mxCell id="waftmcoGh0EoTaqUSBJa-12" edge="1" parent="1" source="waftmcoGh0EoTaqUSBJa-2" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;fillColor=#d5e8d4;strokeColor=#82b366;" target="waftmcoGh0EoTaqUSBJa-3"> + <mxGeometry relative="1" as="geometry" /> + </mxCell> + <mxCell id="waftmcoGh0EoTaqUSBJa-2" parent="1" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" value="EntryGreet" vertex="1"> + <mxGeometry height="40" width="120" y="60" as="geometry" /> + </mxCell> + <mxCell id="waftmcoGh0EoTaqUSBJa-13" edge="1" parent="1" source="waftmcoGh0EoTaqUSBJa-3" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;fillColor=#d5e8d4;strokeColor=#82b366;" target="waftmcoGh0EoTaqUSBJa-4"> + <mxGeometry relative="1" as="geometry" /> + </mxCell> + <mxCell id="waftmcoGh0EoTaqUSBJa-3" parent="1" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" value="StateNameParse" vertex="1"> + <mxGeometry height="40" width="120" y="120" as="geometry" /> + </mxCell> + <mxCell id="waftmcoGh0EoTaqUSBJa-14" edge="1" parent="1" source="waftmcoGh0EoTaqUSBJa-4" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;fillColor=#d5e8d4;strokeColor=#82b366;" target="waftmcoGh0EoTaqUSBJa-8"> + <mxGeometry relative="1" as="geometry" /> + </mxCell> + <mxCell id="waftmcoGh0EoTaqUSBJa-4" parent="1" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" value="ResultGreet" vertex="1"> + <mxGeometry height="40" width="120" y="180" as="geometry" /> + </mxCell> + <mxCell id="waftmcoGh0EoTaqUSBJa-18" edge="1" parent="1" source="waftmcoGh0EoTaqUSBJa-8" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;fillColor=#ffe6cc;strokeColor=#d79b00;" target="waftmcoGh0EoTaqUSBJa-16"> + <mxGeometry relative="1" as="geometry" /> + </mxCell> + <mxCell id="waftmcoGh0EoTaqUSBJa-8" parent="1" style="whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" value="String" vertex="1"> + <mxGeometry height="40" width="120" y="240" as="geometry" /> + </mxCell> + <mxCell id="waftmcoGh0EoTaqUSBJa-9" edge="1" parent="1" source="waftmcoGh0EoTaqUSBJa-8" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;fillColor=#d5e8d4;strokeColor=#82b366;" target="waftmcoGh0EoTaqUSBJa-8"> + <mxGeometry relative="1" as="geometry" /> + </mxCell> + <mxCell id="waftmcoGh0EoTaqUSBJa-17" edge="1" parent="1" source="waftmcoGh0EoTaqUSBJa-15" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;fillColor=#ffe6cc;strokeColor=#d79b00;" target="waftmcoGh0EoTaqUSBJa-1"> + <mxGeometry relative="1" as="geometry" /> + </mxCell> + <mxCell id="waftmcoGh0EoTaqUSBJa-15" parent="1" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#ffe6cc;strokeColor=#d79b00;" value="INPUT" vertex="1"> + <mxGeometry height="60" width="120" x="-200" y="110" as="geometry" /> + </mxCell> + <mxCell id="waftmcoGh0EoTaqUSBJa-16" parent="1" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#ffe6cc;strokeColor=#d79b00;" value="OUTPUT" vertex="1"> + <mxGeometry height="60" width="120" x="200" y="110" as="geometry" /> + </mxCell> + </root> + </mxGraphModel> + </diagram> +</mxfile> diff --git a/docs/res/graph/flow.drawio.svg b/docs/res/graph/flow.drawio.svg new file mode 100644 index 0000000..f4c7f6c --- /dev/null +++ b/docs/res/graph/flow.drawio.svg @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Do not edit this file with editors other than draw.io --> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<svg xmlns="http://www.w3.org/2000/svg" style="background: transparent; background-color: transparent; color-scheme: light;" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="527" height="295" viewBox="0 0 527 295" content="<mxfile host="Electron" agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/29.6.6 Chrome/144.0.7559.236 Electron/40.8.4 Safari/537.36" version="29.6.6" scale="1" border="0"> <diagram name="第 1 页" id="k4Qmdujz4_MrBDZmr3JA"> <mxGraphModel dx="1560" dy="672" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0"> <root> <mxCell id="0" /> <mxCell id="1" parent="0" /> <mxCell id="waftmcoGh0EoTaqUSBJa-11" edge="1" parent="1" source="waftmcoGh0EoTaqUSBJa-1" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;fillColor=#d5e8d4;strokeColor=#82b366;" target="waftmcoGh0EoTaqUSBJa-2"> <mxGeometry relative="1" as="geometry" /> </mxCell> <mxCell id="waftmcoGh0EoTaqUSBJa-1" parent="1" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" value="&lt;font style=&quot;color: rgb(0, 0, 0);&quot;&gt;&lt;font&gt;Vec&lt;/font&gt;&lt;font&gt;&amp;lt;String&amp;gt;&lt;/font&gt;&lt;/font&gt;" vertex="1"> <mxGeometry height="40" width="120" as="geometry" /> </mxCell> <mxCell id="waftmcoGh0EoTaqUSBJa-12" edge="1" parent="1" source="waftmcoGh0EoTaqUSBJa-2" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;fillColor=#d5e8d4;strokeColor=#82b366;" target="waftmcoGh0EoTaqUSBJa-3"> <mxGeometry relative="1" as="geometry" /> </mxCell> <mxCell id="waftmcoGh0EoTaqUSBJa-2" parent="1" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" value="EntryGreet" vertex="1"> <mxGeometry height="40" width="120" y="60" as="geometry" /> </mxCell> <mxCell id="waftmcoGh0EoTaqUSBJa-13" edge="1" parent="1" source="waftmcoGh0EoTaqUSBJa-3" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;fillColor=#d5e8d4;strokeColor=#82b366;" target="waftmcoGh0EoTaqUSBJa-4"> <mxGeometry relative="1" as="geometry" /> </mxCell> <mxCell id="waftmcoGh0EoTaqUSBJa-3" parent="1" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" value="StateNameParse" vertex="1"> <mxGeometry height="40" width="120" y="120" as="geometry" /> </mxCell> <mxCell id="waftmcoGh0EoTaqUSBJa-14" edge="1" parent="1" source="waftmcoGh0EoTaqUSBJa-4" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;fillColor=#d5e8d4;strokeColor=#82b366;" target="waftmcoGh0EoTaqUSBJa-8"> <mxGeometry relative="1" as="geometry" /> </mxCell> <mxCell id="waftmcoGh0EoTaqUSBJa-4" parent="1" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" value="ResultGreet" vertex="1"> <mxGeometry height="40" width="120" y="180" as="geometry" /> </mxCell> <mxCell id="waftmcoGh0EoTaqUSBJa-18" edge="1" parent="1" source="waftmcoGh0EoTaqUSBJa-8" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;fillColor=#ffe6cc;strokeColor=#d79b00;" target="waftmcoGh0EoTaqUSBJa-16"> <mxGeometry relative="1" as="geometry" /> </mxCell> <mxCell id="waftmcoGh0EoTaqUSBJa-8" parent="1" style="whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" value="String" vertex="1"> <mxGeometry height="40" width="120" y="240" as="geometry" /> </mxCell> <mxCell id="waftmcoGh0EoTaqUSBJa-9" edge="1" parent="1" source="waftmcoGh0EoTaqUSBJa-8" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;fillColor=#d5e8d4;strokeColor=#82b366;" target="waftmcoGh0EoTaqUSBJa-8"> <mxGeometry relative="1" as="geometry" /> </mxCell> <mxCell id="waftmcoGh0EoTaqUSBJa-17" edge="1" parent="1" source="waftmcoGh0EoTaqUSBJa-15" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;fillColor=#ffe6cc;strokeColor=#d79b00;" target="waftmcoGh0EoTaqUSBJa-1"> <mxGeometry relative="1" as="geometry" /> </mxCell> <mxCell id="waftmcoGh0EoTaqUSBJa-15" parent="1" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#ffe6cc;strokeColor=#d79b00;" value="INPUT" vertex="1"> <mxGeometry height="60" width="120" x="-200" y="110" as="geometry" /> </mxCell> <mxCell id="waftmcoGh0EoTaqUSBJa-16" parent="1" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#ffe6cc;strokeColor=#d79b00;" value="OUTPUT" vertex="1"> <mxGeometry height="60" width="120" x="200" y="110" as="geometry" /> </mxCell> </root> </mxGraphModel> </diagram> </mxfile> "><defs/><g style="filter: drop-shadow(light-dark(rgba(61, 69, 116, 0.4), rgba(168, 175, 216, 0.4)) 3px 3px 1.7px);"><g data-cell-id="0"><g data-cell-id="1"><g data-cell-id="waftmcoGh0EoTaqUSBJa-11"><g transform="translate(0.5,0.5)"><path d="M 260 40 L 260 53.63" fill="none" stroke="#82b366" stroke-miterlimit="10" pointer-events="stroke" style="stroke: rgb(130, 179, 102);"/><path d="M 260 58.88 L 256.5 51.88 L 260 53.63 L 263.5 51.88 Z" fill="#82b366" stroke="#82b366" stroke-miterlimit="10" pointer-events="all" style="fill: rgb(130, 179, 102); stroke: rgb(130, 179, 102);"/></g></g><g data-cell-id="waftmcoGh0EoTaqUSBJa-1"><g transform="translate(0.5,0.5)"><rect x="200" y="0" width="120" height="40" fill="#d5e8d4" stroke="#82b366" pointer-events="all" style="fill: rgb(213, 232, 212); stroke: rgb(130, 179, 102);"/></g><g><g><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 20px; margin-left: 201px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "><font style="color: rgb(0, 0, 0);"><font>Vec</font><font><String></font></font></div></div></div></foreignObject><image x="201" y="13.5" width="118" height="17" xlink:href="data:image/png;base64,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"/></switch></g></g></g><g data-cell-id="waftmcoGh0EoTaqUSBJa-12"><g transform="translate(0.5,0.5)"><path d="M 260 100 L 260 113.63" fill="none" stroke="#82b366" stroke-miterlimit="10" pointer-events="stroke" style="stroke: rgb(130, 179, 102);"/><path d="M 260 118.88 L 256.5 111.88 L 260 113.63 L 263.5 111.88 Z" fill="#82b366" stroke="#82b366" stroke-miterlimit="10" pointer-events="all" style="fill: rgb(130, 179, 102); stroke: rgb(130, 179, 102);"/></g></g><g data-cell-id="waftmcoGh0EoTaqUSBJa-2"><g transform="translate(0.5,0.5)"><rect x="200" y="60" width="120" height="40" fill="#d5e8d4" stroke="#82b366" pointer-events="all" style="fill: rgb(213, 232, 212); stroke: rgb(130, 179, 102);"/></g><g><g><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 80px; margin-left: 201px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">EntryGreet</div></div></div></foreignObject><image x="201" y="73.5" width="118" height="17" xlink:href="data:image/png;base64,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"/></switch></g></g></g><g data-cell-id="waftmcoGh0EoTaqUSBJa-13"><g transform="translate(0.5,0.5)"><path d="M 260 160 L 260 173.63" fill="none" stroke="#82b366" stroke-miterlimit="10" pointer-events="stroke" style="stroke: rgb(130, 179, 102);"/><path d="M 260 178.88 L 256.5 171.88 L 260 173.63 L 263.5 171.88 Z" fill="#82b366" stroke="#82b366" stroke-miterlimit="10" pointer-events="all" style="fill: rgb(130, 179, 102); stroke: rgb(130, 179, 102);"/></g></g><g data-cell-id="waftmcoGh0EoTaqUSBJa-3"><g transform="translate(0.5,0.5)"><rect x="200" y="120" width="120" height="40" fill="#d5e8d4" stroke="#82b366" pointer-events="all" style="fill: rgb(213, 232, 212); stroke: rgb(130, 179, 102);"/></g><g><g><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 140px; margin-left: 201px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">StateNameParse</div></div></div></foreignObject><image x="201" y="133.5" width="118" height="17" xlink:href="data:image/png;base64,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"/></switch></g></g></g><g data-cell-id="waftmcoGh0EoTaqUSBJa-14"><g transform="translate(0.5,0.5)"><path d="M 260 220 L 260 233.63" fill="none" stroke="#82b366" stroke-miterlimit="10" pointer-events="stroke" style="stroke: rgb(130, 179, 102);"/><path d="M 260 238.88 L 256.5 231.88 L 260 233.63 L 263.5 231.88 Z" fill="#82b366" stroke="#82b366" stroke-miterlimit="10" pointer-events="all" style="fill: rgb(130, 179, 102); stroke: rgb(130, 179, 102);"/></g></g><g data-cell-id="waftmcoGh0EoTaqUSBJa-4"><g transform="translate(0.5,0.5)"><rect x="200" y="180" width="120" height="40" fill="#d5e8d4" stroke="#82b366" pointer-events="all" style="fill: rgb(213, 232, 212); stroke: rgb(130, 179, 102);"/></g><g><g><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 200px; margin-left: 201px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">ResultGreet</div></div></div></foreignObject><image x="201" y="193.5" width="118" height="17" xlink:href="data:image/png;base64,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"/></switch></g></g></g><g data-cell-id="waftmcoGh0EoTaqUSBJa-18"><g transform="translate(0.5,0.5)"><path d="M 320 260 L 360 260 L 360 140 L 393.63 140" fill="none" stroke="#d79b00" stroke-miterlimit="10" pointer-events="stroke" style="stroke: rgb(215, 155, 0);"/><path d="M 398.88 140 L 391.88 143.5 L 393.63 140 L 391.88 136.5 Z" fill="#d79b00" stroke="#d79b00" stroke-miterlimit="10" pointer-events="all" style="fill: rgb(215, 155, 0); stroke: rgb(215, 155, 0);"/></g></g><g data-cell-id="waftmcoGh0EoTaqUSBJa-8"><g transform="translate(0.5,0.5)"><rect x="200" y="240" width="120" height="40" fill="#d5e8d4" stroke="#82b366" pointer-events="all" style="fill: rgb(213, 232, 212); stroke: rgb(130, 179, 102);"/></g><g><g><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 260px; margin-left: 201px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">String</div></div></div></foreignObject><image x="201" y="253.5" width="118" height="17" xlink:href="data:image/png;base64,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"/></switch></g></g></g><g data-cell-id="waftmcoGh0EoTaqUSBJa-9"><g transform="translate(0.5,0.5)"/></g><g data-cell-id="waftmcoGh0EoTaqUSBJa-17"><g transform="translate(0.5,0.5)"><path d="M 120 140 L 160 140 L 160 20 L 193.63 20" fill="none" stroke="#d79b00" stroke-miterlimit="10" pointer-events="stroke" style="stroke: rgb(215, 155, 0);"/><path d="M 198.88 20 L 191.88 23.5 L 193.63 20 L 191.88 16.5 Z" fill="#d79b00" stroke="#d79b00" stroke-miterlimit="10" pointer-events="all" style="fill: rgb(215, 155, 0); stroke: rgb(215, 155, 0);"/></g></g><g data-cell-id="waftmcoGh0EoTaqUSBJa-15"><g transform="translate(0.5,0.5)"><rect x="0" y="110" width="120" height="60" fill="#ffe6cc" stroke="#d79b00" pointer-events="all" style="fill: rgb(255, 230, 204); stroke: rgb(215, 155, 0);"/></g><g><g><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 140px; margin-left: 1px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">INPUT</div></div></div></foreignObject><image x="1" y="133.5" width="118" height="17" xlink:href="data:image/png;base64,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"/></switch></g></g></g><g data-cell-id="waftmcoGh0EoTaqUSBJa-16"><g transform="translate(0.5,0.5)"><rect x="400" y="110" width="120" height="60" fill="#ffe6cc" stroke="#d79b00" pointer-events="all" style="fill: rgb(255, 230, 204); stroke: rgb(215, 155, 0);"/></g><g><g><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 140px; margin-left: 401px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">OUTPUT</div></div></div></foreignObject><image x="401" y="133.5" width="118" height="17" xlink:href="data:image/png;base64,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"/></switch></g></g></g></g></g></g></svg>
\ No newline at end of file diff --git a/docs/scripts/highlight/bash.min.js b/docs/scripts/highlight/bash.min.js new file mode 100644 index 0000000..6971457 --- /dev/null +++ b/docs/scripts/highlight/bash.min.js @@ -0,0 +1,20 @@ +/*! `bash` grammar compiled for Highlight.js 11.9.0 */ +(()=>{var e=(()=>{"use strict";return e=>{const s=e.regex,t={},n={begin:/\$\{/, +end:/\}/,contains:["self",{begin:/:-/,contains:[t]}]};Object.assign(t,{ +className:"variable",variants:[{ +begin:s.concat(/\$[\w\d#@][\w\d_]*/,"(?![\\w\\d])(?![$])")},n]});const a={ +className:"subst",begin:/\$\(/,end:/\)/,contains:[e.BACKSLASH_ESCAPE]},i={ +begin:/<<-?\s*(?=\w+)/,starts:{contains:[e.END_SAME_AS_BEGIN({begin:/(\w+)/, +end:/(\w+)/,className:"string"})]}},c={className:"string",begin:/"/,end:/"/, +contains:[e.BACKSLASH_ESCAPE,t,a]};a.contains.push(c);const o={begin:/\$?\(\(/, +end:/\)\)/,contains:[{begin:/\d+#[0-9a-f]+/,className:"number"},e.NUMBER_MODE,t] +},r=e.SHEBANG({binary:"(fish|bash|zsh|sh|csh|ksh|tcsh|dash|scsh)",relevance:10 +}),l={className:"function",begin:/\w[\w\d_]*\s*\(\s*\)\s*\{/,returnBegin:!0, +contains:[e.inherit(e.TITLE_MODE,{begin:/\w[\w\d_]*/})],relevance:0};return{ +name:"Bash",aliases:["sh"],keywords:{$pattern:/\b[a-z][a-z0-9._-]+\b/, +keyword:["if","then","else","elif","fi","for","while","until","in","do","done","case","esac","function","select"], +literal:["true","false"], +built_in:["break","cd","continue","eval","exec","exit","export","getopts","hash","pwd","readonly","return","shift","test","times","trap","umask","unset","alias","bind","builtin","caller","command","declare","echo","enable","help","let","local","logout","mapfile","printf","read","readarray","source","type","typeset","ulimit","unalias","set","shopt","autoload","bg","bindkey","bye","cap","chdir","clone","comparguments","compcall","compctl","compdescribe","compfiles","compgroups","compquote","comptags","comptry","compvalues","dirs","disable","disown","echotc","echoti","emulate","fc","fg","float","functions","getcap","getln","history","integer","jobs","kill","limit","log","noglob","popd","print","pushd","pushln","rehash","sched","setcap","setopt","stat","suspend","ttyctl","unfunction","unhash","unlimit","unsetopt","vared","wait","whence","where","which","zcompile","zformat","zftp","zle","zmodload","zparseopts","zprof","zpty","zregexparse","zsocket","zstyle","ztcp","chcon","chgrp","chown","chmod","cp","dd","df","dir","dircolors","ln","ls","mkdir","mkfifo","mknod","mktemp","mv","realpath","rm","rmdir","shred","sync","touch","truncate","vdir","b2sum","base32","base64","cat","cksum","comm","csplit","cut","expand","fmt","fold","head","join","md5sum","nl","numfmt","od","paste","ptx","pr","sha1sum","sha224sum","sha256sum","sha384sum","sha512sum","shuf","sort","split","sum","tac","tail","tr","tsort","unexpand","uniq","wc","arch","basename","chroot","date","dirname","du","echo","env","expr","factor","groups","hostid","id","link","logname","nice","nohup","nproc","pathchk","pinky","printenv","printf","pwd","readlink","runcon","seq","sleep","stat","stdbuf","stty","tee","test","timeout","tty","uname","unlink","uptime","users","who","whoami","yes"] +},contains:[r,e.SHEBANG(),l,o,e.HASH_COMMENT_MODE,i,{match:/(\/[a-z._-]+)+/},c,{ +match:/\\"/},{className:"string",begin:/'/,end:/'/},{match:/\\'/},t]}}})() +;hljs.registerLanguage("bash",e)})();
\ No newline at end of file diff --git a/docs/scripts/highlight/github-dark.min.css b/docs/scripts/highlight/github-dark.min.css new file mode 100644 index 0000000..03b6da8 --- /dev/null +++ b/docs/scripts/highlight/github-dark.min.css @@ -0,0 +1,10 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}/*! + Theme: GitHub Dark + Description: Dark theme as seen on github.com + Author: github.com + Maintainer: @Hirse + Updated: 2021-05-15 + + Outdated base version: https://github.com/primer/github-syntax-dark + Current colors taken from GitHub's CSS +*/.hljs{color:#c9d1d9;background:#0d1117}.hljs-doctag,.hljs-keyword,.hljs-meta .hljs-keyword,.hljs-template-tag,.hljs-template-variable,.hljs-type,.hljs-variable.language_{color:#ff7b72}.hljs-title,.hljs-title.class_,.hljs-title.class_.inherited__,.hljs-title.function_{color:#d2a8ff}.hljs-attr,.hljs-attribute,.hljs-literal,.hljs-meta,.hljs-number,.hljs-operator,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-id,.hljs-variable{color:#79c0ff}.hljs-meta .hljs-string,.hljs-regexp,.hljs-string{color:#a5d6ff}.hljs-built_in,.hljs-symbol{color:#ffa657}.hljs-code,.hljs-comment,.hljs-formula{color:#8b949e}.hljs-name,.hljs-quote,.hljs-selector-pseudo,.hljs-selector-tag{color:#7ee787}.hljs-subst{color:#c9d1d9}.hljs-section{color:#1f6feb;font-weight:700}.hljs-bullet{color:#f2cc60}.hljs-emphasis{color:#c9d1d9;font-style:italic}.hljs-strong{color:#c9d1d9;font-weight:700}.hljs-addition{color:#aff5b4;background-color:#033a16}.hljs-deletion{color:#ffdcd7;background-color:#67060c}
\ No newline at end of file diff --git a/docs/scripts/highlight/github.min.css b/docs/scripts/highlight/github.min.css new file mode 100644 index 0000000..275239a --- /dev/null +++ b/docs/scripts/highlight/github.min.css @@ -0,0 +1,10 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}/*! + Theme: GitHub + Description: Light theme as seen on github.com + Author: github.com + Maintainer: @Hirse + Updated: 2021-05-15 + + Outdated base version: https://github.com/primer/github-syntax-light + Current colors taken from GitHub's CSS +*/.hljs{color:#24292e;background:#fff}.hljs-doctag,.hljs-keyword,.hljs-meta .hljs-keyword,.hljs-template-tag,.hljs-template-variable,.hljs-type,.hljs-variable.language_{color:#d73a49}.hljs-title,.hljs-title.class_,.hljs-title.class_.inherited__,.hljs-title.function_{color:#6f42c1}.hljs-attr,.hljs-attribute,.hljs-literal,.hljs-meta,.hljs-number,.hljs-operator,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-id,.hljs-variable{color:#005cc5}.hljs-meta .hljs-string,.hljs-regexp,.hljs-string{color:#032f62}.hljs-built_in,.hljs-symbol{color:#e36209}.hljs-code,.hljs-comment,.hljs-formula{color:#6a737d}.hljs-name,.hljs-quote,.hljs-selector-pseudo,.hljs-selector-tag{color:#22863a}.hljs-subst{color:#24292e}.hljs-section{color:#005cc5;font-weight:700}.hljs-bullet{color:#735c0f}.hljs-emphasis{color:#24292e;font-style:italic}.hljs-strong{color:#24292e;font-weight:700}.hljs-addition{color:#22863a;background-color:#f0fff4}.hljs-deletion{color:#b31d28;background-color:#ffeef0}
\ No newline at end of file diff --git a/docs/scripts/highlight/highlight.min.js b/docs/scripts/highlight/highlight.min.js new file mode 100644 index 0000000..5d699ae --- /dev/null +++ b/docs/scripts/highlight/highlight.min.js @@ -0,0 +1,1213 @@ +/*! + Highlight.js v11.9.0 (git: f47103d4f1) + (c) 2006-2023 undefined and other contributors + License: BSD-3-Clause + */ +var hljs=function(){"use strict";function e(n){ +return n instanceof Map?n.clear=n.delete=n.set=()=>{ +throw Error("map is read-only")}:n instanceof Set&&(n.add=n.clear=n.delete=()=>{ +throw Error("set is read-only") +}),Object.freeze(n),Object.getOwnPropertyNames(n).forEach((t=>{ +const a=n[t],i=typeof a;"object"!==i&&"function"!==i||Object.isFrozen(a)||e(a) +})),n}class n{constructor(e){ +void 0===e.data&&(e.data={}),this.data=e.data,this.isMatchIgnored=!1} +ignoreMatch(){this.isMatchIgnored=!0}}function t(e){ +return e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'") +}function a(e,...n){const t=Object.create(null);for(const n in e)t[n]=e[n] +;return n.forEach((e=>{for(const n in e)t[n]=e[n]})),t}const i=e=>!!e.scope +;class r{constructor(e,n){ +this.buffer="",this.classPrefix=n.classPrefix,e.walk(this)}addText(e){ +this.buffer+=t(e)}openNode(e){if(!i(e))return;const n=((e,{prefix:n})=>{ +if(e.startsWith("language:"))return e.replace("language:","language-") +;if(e.includes(".")){const t=e.split(".") +;return[`${n}${t.shift()}`,...t.map(((e,n)=>`${e}${"_".repeat(n+1)}`))].join(" ") +}return`${n}${e}`})(e.scope,{prefix:this.classPrefix});this.span(n)} +closeNode(e){i(e)&&(this.buffer+="</span>")}value(){return this.buffer}span(e){ +this.buffer+=`<span class="${e}">`}}const s=(e={})=>{const n={children:[]} +;return Object.assign(n,e),n};class o{constructor(){ +this.rootNode=s(),this.stack=[this.rootNode]}get top(){ +return this.stack[this.stack.length-1]}get root(){return this.rootNode}add(e){ +this.top.children.push(e)}openNode(e){const n=s({scope:e}) +;this.add(n),this.stack.push(n)}closeNode(){ +if(this.stack.length>1)return this.stack.pop()}closeAllNodes(){ +for(;this.closeNode(););}toJSON(){return JSON.stringify(this.rootNode,null,4)} +walk(e){return this.constructor._walk(e,this.rootNode)}static _walk(e,n){ +return"string"==typeof n?e.addText(n):n.children&&(e.openNode(n), +n.children.forEach((n=>this._walk(e,n))),e.closeNode(n)),e}static _collapse(e){ +"string"!=typeof e&&e.children&&(e.children.every((e=>"string"==typeof e))?e.children=[e.children.join("")]:e.children.forEach((e=>{ +o._collapse(e)})))}}class l extends o{constructor(e){super(),this.options=e} +addText(e){""!==e&&this.add(e)}startScope(e){this.openNode(e)}endScope(){ +this.closeNode()}__addSublanguage(e,n){const t=e.root +;n&&(t.scope="language:"+n),this.add(t)}toHTML(){ +return new r(this,this.options).value()}finalize(){ +return this.closeAllNodes(),!0}}function c(e){ +return e?"string"==typeof e?e:e.source:null}function d(e){return b("(?=",e,")")} +function g(e){return b("(?:",e,")*")}function u(e){return b("(?:",e,")?")} +function b(...e){return e.map((e=>c(e))).join("")}function m(...e){const n=(e=>{ +const n=e[e.length-1] +;return"object"==typeof n&&n.constructor===Object?(e.splice(e.length-1,1),n):{} +})(e);return"("+(n.capture?"":"?:")+e.map((e=>c(e))).join("|")+")"} +function p(e){return RegExp(e.toString()+"|").exec("").length-1} +const _=/\[(?:[^\\\]]|\\.)*\]|\(\??|\\([1-9][0-9]*)|\\./ +;function h(e,{joinWith:n}){let t=0;return e.map((e=>{t+=1;const n=t +;let a=c(e),i="";for(;a.length>0;){const e=_.exec(a);if(!e){i+=a;break} +i+=a.substring(0,e.index), +a=a.substring(e.index+e[0].length),"\\"===e[0][0]&&e[1]?i+="\\"+(Number(e[1])+n):(i+=e[0], +"("===e[0]&&t++)}return i})).map((e=>`(${e})`)).join(n)} +const f="[a-zA-Z]\\w*",E="[a-zA-Z_]\\w*",y="\\b\\d+(\\.\\d+)?",N="(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",w="\\b(0b[01]+)",v={ +begin:"\\\\[\\s\\S]",relevance:0},O={scope:"string",begin:"'",end:"'", +illegal:"\\n",contains:[v]},k={scope:"string",begin:'"',end:'"',illegal:"\\n", +contains:[v]},x=(e,n,t={})=>{const i=a({scope:"comment",begin:e,end:n, +contains:[]},t);i.contains.push({scope:"doctag", +begin:"[ ]*(?=(TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):)", +end:/(TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):/,excludeBegin:!0,relevance:0}) +;const r=m("I","a","is","so","us","to","at","if","in","it","on",/[A-Za-z]+['](d|ve|re|ll|t|s|n)/,/[A-Za-z]+[-][a-z]+/,/[A-Za-z][a-z]{2,}/) +;return i.contains.push({begin:b(/[ ]+/,"(",r,/[.]?[:]?([.][ ]|[ ])/,"){3}")}),i +},M=x("//","$"),S=x("/\\*","\\*/"),A=x("#","$");var C=Object.freeze({ +__proto__:null,APOS_STRING_MODE:O,BACKSLASH_ESCAPE:v,BINARY_NUMBER_MODE:{ +scope:"number",begin:w,relevance:0},BINARY_NUMBER_RE:w,COMMENT:x, +C_BLOCK_COMMENT_MODE:S,C_LINE_COMMENT_MODE:M,C_NUMBER_MODE:{scope:"number", +begin:N,relevance:0},C_NUMBER_RE:N,END_SAME_AS_BEGIN:e=>Object.assign(e,{ +"on:begin":(e,n)=>{n.data._beginMatch=e[1]},"on:end":(e,n)=>{ +n.data._beginMatch!==e[1]&&n.ignoreMatch()}}),HASH_COMMENT_MODE:A,IDENT_RE:f, +MATCH_NOTHING_RE:/\b\B/,METHOD_GUARD:{begin:"\\.\\s*"+E,relevance:0}, +NUMBER_MODE:{scope:"number",begin:y,relevance:0},NUMBER_RE:y, +PHRASAL_WORDS_MODE:{ +begin:/\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\b/ +},QUOTE_STRING_MODE:k,REGEXP_MODE:{scope:"regexp",begin:/\/(?=[^/\n]*\/)/, +end:/\/[gimuy]*/,contains:[v,{begin:/\[/,end:/\]/,relevance:0,contains:[v]}]}, +RE_STARTERS_RE:"!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~", +SHEBANG:(e={})=>{const n=/^#![ ]*\// +;return e.binary&&(e.begin=b(n,/.*\b/,e.binary,/\b.*/)),a({scope:"meta",begin:n, +end:/$/,relevance:0,"on:begin":(e,n)=>{0!==e.index&&n.ignoreMatch()}},e)}, +TITLE_MODE:{scope:"title",begin:f,relevance:0},UNDERSCORE_IDENT_RE:E, +UNDERSCORE_TITLE_MODE:{scope:"title",begin:E,relevance:0}});function T(e,n){ +"."===e.input[e.index-1]&&n.ignoreMatch()}function R(e,n){ +void 0!==e.className&&(e.scope=e.className,delete e.className)}function D(e,n){ +n&&e.beginKeywords&&(e.begin="\\b("+e.beginKeywords.split(" ").join("|")+")(?!\\.)(?=\\b|\\s)", +e.__beforeBegin=T,e.keywords=e.keywords||e.beginKeywords,delete e.beginKeywords, +void 0===e.relevance&&(e.relevance=0))}function I(e,n){ +Array.isArray(e.illegal)&&(e.illegal=m(...e.illegal))}function L(e,n){ +if(e.match){ +if(e.begin||e.end)throw Error("begin & end are not supported with match") +;e.begin=e.match,delete e.match}}function B(e,n){ +void 0===e.relevance&&(e.relevance=1)}const $=(e,n)=>{if(!e.beforeMatch)return +;if(e.starts)throw Error("beforeMatch cannot be used with starts") +;const t=Object.assign({},e);Object.keys(e).forEach((n=>{delete e[n] +})),e.keywords=t.keywords,e.begin=b(t.beforeMatch,d(t.begin)),e.starts={ +relevance:0,contains:[Object.assign(t,{endsParent:!0})] +},e.relevance=0,delete t.beforeMatch +},z=["of","and","for","in","not","or","if","then","parent","list","value"],F="keyword" +;function U(e,n,t=F){const a=Object.create(null) +;return"string"==typeof e?i(t,e.split(" ")):Array.isArray(e)?i(t,e):Object.keys(e).forEach((t=>{ +Object.assign(a,U(e[t],n,t))})),a;function i(e,t){ +n&&(t=t.map((e=>e.toLowerCase()))),t.forEach((n=>{const t=n.split("|") +;a[t[0]]=[e,j(t[0],t[1])]}))}}function j(e,n){ +return n?Number(n):(e=>z.includes(e.toLowerCase()))(e)?0:1}const P={},K=e=>{ +console.error(e)},H=(e,...n)=>{console.log("WARN: "+e,...n)},q=(e,n)=>{ +P[`${e}/${n}`]||(console.log(`Deprecated as of ${e}. ${n}`),P[`${e}/${n}`]=!0) +},G=Error();function Z(e,n,{key:t}){let a=0;const i=e[t],r={},s={} +;for(let e=1;e<=n.length;e++)s[e+a]=i[e],r[e+a]=!0,a+=p(n[e-1]) +;e[t]=s,e[t]._emit=r,e[t]._multi=!0}function W(e){(e=>{ +e.scope&&"object"==typeof e.scope&&null!==e.scope&&(e.beginScope=e.scope, +delete e.scope)})(e),"string"==typeof e.beginScope&&(e.beginScope={ +_wrap:e.beginScope}),"string"==typeof e.endScope&&(e.endScope={_wrap:e.endScope +}),(e=>{if(Array.isArray(e.begin)){ +if(e.skip||e.excludeBegin||e.returnBegin)throw K("skip, excludeBegin, returnBegin not compatible with beginScope: {}"), +G +;if("object"!=typeof e.beginScope||null===e.beginScope)throw K("beginScope must be object"), +G;Z(e,e.begin,{key:"beginScope"}),e.begin=h(e.begin,{joinWith:""})}})(e),(e=>{ +if(Array.isArray(e.end)){ +if(e.skip||e.excludeEnd||e.returnEnd)throw K("skip, excludeEnd, returnEnd not compatible with endScope: {}"), +G +;if("object"!=typeof e.endScope||null===e.endScope)throw K("endScope must be object"), +G;Z(e,e.end,{key:"endScope"}),e.end=h(e.end,{joinWith:""})}})(e)}function Q(e){ +function n(n,t){ +return RegExp(c(n),"m"+(e.case_insensitive?"i":"")+(e.unicodeRegex?"u":"")+(t?"g":"")) +}class t{constructor(){ +this.matchIndexes={},this.regexes=[],this.matchAt=1,this.position=0} +addRule(e,n){ +n.position=this.position++,this.matchIndexes[this.matchAt]=n,this.regexes.push([n,e]), +this.matchAt+=p(e)+1}compile(){0===this.regexes.length&&(this.exec=()=>null) +;const e=this.regexes.map((e=>e[1]));this.matcherRe=n(h(e,{joinWith:"|" +}),!0),this.lastIndex=0}exec(e){this.matcherRe.lastIndex=this.lastIndex +;const n=this.matcherRe.exec(e);if(!n)return null +;const t=n.findIndex(((e,n)=>n>0&&void 0!==e)),a=this.matchIndexes[t] +;return n.splice(0,t),Object.assign(n,a)}}class i{constructor(){ +this.rules=[],this.multiRegexes=[], +this.count=0,this.lastIndex=0,this.regexIndex=0}getMatcher(e){ +if(this.multiRegexes[e])return this.multiRegexes[e];const n=new t +;return this.rules.slice(e).forEach((([e,t])=>n.addRule(e,t))), +n.compile(),this.multiRegexes[e]=n,n}resumingScanAtSamePosition(){ +return 0!==this.regexIndex}considerAll(){this.regexIndex=0}addRule(e,n){ +this.rules.push([e,n]),"begin"===n.type&&this.count++}exec(e){ +const n=this.getMatcher(this.regexIndex);n.lastIndex=this.lastIndex +;let t=n.exec(e) +;if(this.resumingScanAtSamePosition())if(t&&t.index===this.lastIndex);else{ +const n=this.getMatcher(0);n.lastIndex=this.lastIndex+1,t=n.exec(e)} +return t&&(this.regexIndex+=t.position+1, +this.regexIndex===this.count&&this.considerAll()),t}} +if(e.compilerExtensions||(e.compilerExtensions=[]), +e.contains&&e.contains.includes("self"))throw Error("ERR: contains `self` is not supported at the top-level of a language. See documentation.") +;return e.classNameAliases=a(e.classNameAliases||{}),function t(r,s){const o=r +;if(r.isCompiled)return o +;[R,L,W,$].forEach((e=>e(r,s))),e.compilerExtensions.forEach((e=>e(r,s))), +r.__beforeBegin=null,[D,I,B].forEach((e=>e(r,s))),r.isCompiled=!0;let l=null +;return"object"==typeof r.keywords&&r.keywords.$pattern&&(r.keywords=Object.assign({},r.keywords), +l=r.keywords.$pattern, +delete r.keywords.$pattern),l=l||/\w+/,r.keywords&&(r.keywords=U(r.keywords,e.case_insensitive)), +o.keywordPatternRe=n(l,!0), +s&&(r.begin||(r.begin=/\B|\b/),o.beginRe=n(o.begin),r.end||r.endsWithParent||(r.end=/\B|\b/), +r.end&&(o.endRe=n(o.end)), +o.terminatorEnd=c(o.end)||"",r.endsWithParent&&s.terminatorEnd&&(o.terminatorEnd+=(r.end?"|":"")+s.terminatorEnd)), +r.illegal&&(o.illegalRe=n(r.illegal)), +r.contains||(r.contains=[]),r.contains=[].concat(...r.contains.map((e=>(e=>(e.variants&&!e.cachedVariants&&(e.cachedVariants=e.variants.map((n=>a(e,{ +variants:null},n)))),e.cachedVariants?e.cachedVariants:X(e)?a(e,{ +starts:e.starts?a(e.starts):null +}):Object.isFrozen(e)?a(e):e))("self"===e?r:e)))),r.contains.forEach((e=>{t(e,o) +})),r.starts&&t(r.starts,s),o.matcher=(e=>{const n=new i +;return e.contains.forEach((e=>n.addRule(e.begin,{rule:e,type:"begin" +}))),e.terminatorEnd&&n.addRule(e.terminatorEnd,{type:"end" +}),e.illegal&&n.addRule(e.illegal,{type:"illegal"}),n})(o),o}(e)}function X(e){ +return!!e&&(e.endsWithParent||X(e.starts))}class V extends Error{ +constructor(e,n){super(e),this.name="HTMLInjectionError",this.html=n}} +const J=t,Y=a,ee=Symbol("nomatch"),ne=t=>{ +const a=Object.create(null),i=Object.create(null),r=[];let s=!0 +;const o="Could not find the language '{}', did you forget to load/include a language module?",c={ +disableAutodetect:!0,name:"Plain text",contains:[]};let p={ +ignoreUnescapedHTML:!1,throwUnescapedHTML:!1,noHighlightRe:/^(no-?highlight)$/i, +languageDetectRe:/\blang(?:uage)?-([\w-]+)\b/i,classPrefix:"hljs-", +cssSelector:"pre code",languages:null,__emitter:l};function _(e){ +return p.noHighlightRe.test(e)}function h(e,n,t){let a="",i="" +;"object"==typeof n?(a=e, +t=n.ignoreIllegals,i=n.language):(q("10.7.0","highlight(lang, code, ...args) has been deprecated."), +q("10.7.0","Please use highlight(code, options) instead.\nhttps://github.com/highlightjs/highlight.js/issues/2277"), +i=e,a=n),void 0===t&&(t=!0);const r={code:a,language:i};x("before:highlight",r) +;const s=r.result?r.result:f(r.language,r.code,t) +;return s.code=r.code,x("after:highlight",s),s}function f(e,t,i,r){ +const l=Object.create(null);function c(){if(!x.keywords)return void S.addText(A) +;let e=0;x.keywordPatternRe.lastIndex=0;let n=x.keywordPatternRe.exec(A),t="" +;for(;n;){t+=A.substring(e,n.index) +;const i=w.case_insensitive?n[0].toLowerCase():n[0],r=(a=i,x.keywords[a]);if(r){ +const[e,a]=r +;if(S.addText(t),t="",l[i]=(l[i]||0)+1,l[i]<=7&&(C+=a),e.startsWith("_"))t+=n[0];else{ +const t=w.classNameAliases[e]||e;g(n[0],t)}}else t+=n[0] +;e=x.keywordPatternRe.lastIndex,n=x.keywordPatternRe.exec(A)}var a +;t+=A.substring(e),S.addText(t)}function d(){null!=x.subLanguage?(()=>{ +if(""===A)return;let e=null;if("string"==typeof x.subLanguage){ +if(!a[x.subLanguage])return void S.addText(A) +;e=f(x.subLanguage,A,!0,M[x.subLanguage]),M[x.subLanguage]=e._top +}else e=E(A,x.subLanguage.length?x.subLanguage:null) +;x.relevance>0&&(C+=e.relevance),S.__addSublanguage(e._emitter,e.language) +})():c(),A=""}function g(e,n){ +""!==e&&(S.startScope(n),S.addText(e),S.endScope())}function u(e,n){let t=1 +;const a=n.length-1;for(;t<=a;){if(!e._emit[t]){t++;continue} +const a=w.classNameAliases[e[t]]||e[t],i=n[t];a?g(i,a):(A=i,c(),A=""),t++}} +function b(e,n){ +return e.scope&&"string"==typeof e.scope&&S.openNode(w.classNameAliases[e.scope]||e.scope), +e.beginScope&&(e.beginScope._wrap?(g(A,w.classNameAliases[e.beginScope._wrap]||e.beginScope._wrap), +A=""):e.beginScope._multi&&(u(e.beginScope,n),A="")),x=Object.create(e,{parent:{ +value:x}}),x}function m(e,t,a){let i=((e,n)=>{const t=e&&e.exec(n) +;return t&&0===t.index})(e.endRe,a);if(i){if(e["on:end"]){const a=new n(e) +;e["on:end"](t,a),a.isMatchIgnored&&(i=!1)}if(i){ +for(;e.endsParent&&e.parent;)e=e.parent;return e}} +if(e.endsWithParent)return m(e.parent,t,a)}function _(e){ +return 0===x.matcher.regexIndex?(A+=e[0],1):(D=!0,0)}function h(e){ +const n=e[0],a=t.substring(e.index),i=m(x,e,a);if(!i)return ee;const r=x +;x.endScope&&x.endScope._wrap?(d(), +g(n,x.endScope._wrap)):x.endScope&&x.endScope._multi?(d(), +u(x.endScope,e)):r.skip?A+=n:(r.returnEnd||r.excludeEnd||(A+=n), +d(),r.excludeEnd&&(A=n));do{ +x.scope&&S.closeNode(),x.skip||x.subLanguage||(C+=x.relevance),x=x.parent +}while(x!==i.parent);return i.starts&&b(i.starts,e),r.returnEnd?0:n.length} +let y={};function N(a,r){const o=r&&r[0];if(A+=a,null==o)return d(),0 +;if("begin"===y.type&&"end"===r.type&&y.index===r.index&&""===o){ +if(A+=t.slice(r.index,r.index+1),!s){const n=Error(`0 width match regex (${e})`) +;throw n.languageName=e,n.badRule=y.rule,n}return 1} +if(y=r,"begin"===r.type)return(e=>{ +const t=e[0],a=e.rule,i=new n(a),r=[a.__beforeBegin,a["on:begin"]] +;for(const n of r)if(n&&(n(e,i),i.isMatchIgnored))return _(t) +;return a.skip?A+=t:(a.excludeBegin&&(A+=t), +d(),a.returnBegin||a.excludeBegin||(A=t)),b(a,e),a.returnBegin?0:t.length})(r) +;if("illegal"===r.type&&!i){ +const e=Error('Illegal lexeme "'+o+'" for mode "'+(x.scope||"<unnamed>")+'"') +;throw e.mode=x,e}if("end"===r.type){const e=h(r);if(e!==ee)return e} +if("illegal"===r.type&&""===o)return 1 +;if(R>1e5&&R>3*r.index)throw Error("potential infinite loop, way more iterations than matches") +;return A+=o,o.length}const w=v(e) +;if(!w)throw K(o.replace("{}",e)),Error('Unknown language: "'+e+'"') +;const O=Q(w);let k="",x=r||O;const M={},S=new p.__emitter(p);(()=>{const e=[] +;for(let n=x;n!==w;n=n.parent)n.scope&&e.unshift(n.scope) +;e.forEach((e=>S.openNode(e)))})();let A="",C=0,T=0,R=0,D=!1;try{ +if(w.__emitTokens)w.__emitTokens(t,S);else{for(x.matcher.considerAll();;){ +R++,D?D=!1:x.matcher.considerAll(),x.matcher.lastIndex=T +;const e=x.matcher.exec(t);if(!e)break;const n=N(t.substring(T,e.index),e) +;T=e.index+n}N(t.substring(T))}return S.finalize(),k=S.toHTML(),{language:e, +value:k,relevance:C,illegal:!1,_emitter:S,_top:x}}catch(n){ +if(n.message&&n.message.includes("Illegal"))return{language:e,value:J(t), +illegal:!0,relevance:0,_illegalBy:{message:n.message,index:T, +context:t.slice(T-100,T+100),mode:n.mode,resultSoFar:k},_emitter:S};if(s)return{ +language:e,value:J(t),illegal:!1,relevance:0,errorRaised:n,_emitter:S,_top:x} +;throw n}}function E(e,n){n=n||p.languages||Object.keys(a);const t=(e=>{ +const n={value:J(e),illegal:!1,relevance:0,_top:c,_emitter:new p.__emitter(p)} +;return n._emitter.addText(e),n})(e),i=n.filter(v).filter(k).map((n=>f(n,e,!1))) +;i.unshift(t);const r=i.sort(((e,n)=>{ +if(e.relevance!==n.relevance)return n.relevance-e.relevance +;if(e.language&&n.language){if(v(e.language).supersetOf===n.language)return 1 +;if(v(n.language).supersetOf===e.language)return-1}return 0})),[s,o]=r,l=s +;return l.secondBest=o,l}function y(e){let n=null;const t=(e=>{ +let n=e.className+" ";n+=e.parentNode?e.parentNode.className:"" +;const t=p.languageDetectRe.exec(n);if(t){const n=v(t[1]) +;return n||(H(o.replace("{}",t[1])), +H("Falling back to no-highlight mode for this block.",e)),n?t[1]:"no-highlight"} +return n.split(/\s+/).find((e=>_(e)||v(e)))})(e);if(_(t))return +;if(x("before:highlightElement",{el:e,language:t +}),e.dataset.highlighted)return void console.log("Element previously highlighted. To highlight again, first unset `dataset.highlighted`.",e) +;if(e.children.length>0&&(p.ignoreUnescapedHTML||(console.warn("One of your code blocks includes unescaped HTML. This is a potentially serious security risk."), +console.warn("https://github.com/highlightjs/highlight.js/wiki/security"), +console.warn("The element with unescaped HTML:"), +console.warn(e)),p.throwUnescapedHTML))throw new V("One of your code blocks includes unescaped HTML.",e.innerHTML) +;n=e;const a=n.textContent,r=t?h(a,{language:t,ignoreIllegals:!0}):E(a) +;e.innerHTML=r.value,e.dataset.highlighted="yes",((e,n,t)=>{const a=n&&i[n]||t +;e.classList.add("hljs"),e.classList.add("language-"+a) +})(e,t,r.language),e.result={language:r.language,re:r.relevance, +relevance:r.relevance},r.secondBest&&(e.secondBest={ +language:r.secondBest.language,relevance:r.secondBest.relevance +}),x("after:highlightElement",{el:e,result:r,text:a})}let N=!1;function w(){ +"loading"!==document.readyState?document.querySelectorAll(p.cssSelector).forEach(y):N=!0 +}function v(e){return e=(e||"").toLowerCase(),a[e]||a[i[e]]} +function O(e,{languageName:n}){"string"==typeof e&&(e=[e]),e.forEach((e=>{ +i[e.toLowerCase()]=n}))}function k(e){const n=v(e) +;return n&&!n.disableAutodetect}function x(e,n){const t=e;r.forEach((e=>{ +e[t]&&e[t](n)}))} +"undefined"!=typeof window&&window.addEventListener&&window.addEventListener("DOMContentLoaded",(()=>{ +N&&w()}),!1),Object.assign(t,{highlight:h,highlightAuto:E,highlightAll:w, +highlightElement:y, +highlightBlock:e=>(q("10.7.0","highlightBlock will be removed entirely in v12.0"), +q("10.7.0","Please use highlightElement now."),y(e)),configure:e=>{p=Y(p,e)}, +initHighlighting:()=>{ +w(),q("10.6.0","initHighlighting() deprecated. Use highlightAll() now.")}, +initHighlightingOnLoad:()=>{ +w(),q("10.6.0","initHighlightingOnLoad() deprecated. Use highlightAll() now.") +},registerLanguage:(e,n)=>{let i=null;try{i=n(t)}catch(n){ +if(K("Language definition for '{}' could not be registered.".replace("{}",e)), +!s)throw n;K(n),i=c} +i.name||(i.name=e),a[e]=i,i.rawDefinition=n.bind(null,t),i.aliases&&O(i.aliases,{ +languageName:e})},unregisterLanguage:e=>{delete a[e] +;for(const n of Object.keys(i))i[n]===e&&delete i[n]}, +listLanguages:()=>Object.keys(a),getLanguage:v,registerAliases:O, +autoDetection:k,inherit:Y,addPlugin:e=>{(e=>{ +e["before:highlightBlock"]&&!e["before:highlightElement"]&&(e["before:highlightElement"]=n=>{ +e["before:highlightBlock"](Object.assign({block:n.el},n)) +}),e["after:highlightBlock"]&&!e["after:highlightElement"]&&(e["after:highlightElement"]=n=>{ +e["after:highlightBlock"](Object.assign({block:n.el},n))})})(e),r.push(e)}, +removePlugin:e=>{const n=r.indexOf(e);-1!==n&&r.splice(n,1)}}),t.debugMode=()=>{ +s=!1},t.safeMode=()=>{s=!0},t.versionString="11.9.0",t.regex={concat:b, +lookahead:d,either:m,optional:u,anyNumberOfTimes:g} +;for(const n in C)"object"==typeof C[n]&&e(C[n]);return Object.assign(t,C),t +},te=ne({});te.newInstance=()=>ne({});var ae=te;const ie=e=>({IMPORTANT:{ +scope:"meta",begin:"!important"},BLOCK_COMMENT:e.C_BLOCK_COMMENT_MODE,HEXCOLOR:{ +scope:"number",begin:/#(([0-9a-fA-F]{3,4})|(([0-9a-fA-F]{2}){3,4}))\b/}, +FUNCTION_DISPATCH:{className:"built_in",begin:/[\w-]+(?=\()/}, +ATTRIBUTE_SELECTOR_MODE:{scope:"selector-attr",begin:/\[/,end:/\]/,illegal:"$", +contains:[e.APOS_STRING_MODE,e.QUOTE_STRING_MODE]},CSS_NUMBER_MODE:{ +scope:"number", +begin:e.NUMBER_RE+"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?", +relevance:0},CSS_VARIABLE:{className:"attr",begin:/--[A-Za-z_][A-Za-z0-9_-]*/} +}),re=["a","abbr","address","article","aside","audio","b","blockquote","body","button","canvas","caption","cite","code","dd","del","details","dfn","div","dl","dt","em","fieldset","figcaption","figure","footer","form","h1","h2","h3","h4","h5","h6","header","hgroup","html","i","iframe","img","input","ins","kbd","label","legend","li","main","mark","menu","nav","object","ol","p","q","quote","samp","section","span","strong","summary","sup","table","tbody","td","textarea","tfoot","th","thead","time","tr","ul","var","video"],se=["any-hover","any-pointer","aspect-ratio","color","color-gamut","color-index","device-aspect-ratio","device-height","device-width","display-mode","forced-colors","grid","height","hover","inverted-colors","monochrome","orientation","overflow-block","overflow-inline","pointer","prefers-color-scheme","prefers-contrast","prefers-reduced-motion","prefers-reduced-transparency","resolution","scan","scripting","update","width","min-width","max-width","min-height","max-height"],oe=["active","any-link","blank","checked","current","default","defined","dir","disabled","drop","empty","enabled","first","first-child","first-of-type","fullscreen","future","focus","focus-visible","focus-within","has","host","host-context","hover","indeterminate","in-range","invalid","is","lang","last-child","last-of-type","left","link","local-link","not","nth-child","nth-col","nth-last-child","nth-last-col","nth-last-of-type","nth-of-type","only-child","only-of-type","optional","out-of-range","past","placeholder-shown","read-only","read-write","required","right","root","scope","target","target-within","user-invalid","valid","visited","where"],le=["after","backdrop","before","cue","cue-region","first-letter","first-line","grammar-error","marker","part","placeholder","selection","slotted","spelling-error"],ce=["align-content","align-items","align-self","all","animation","animation-delay","animation-direction","animation-duration","animation-fill-mode","animation-iteration-count","animation-name","animation-play-state","animation-timing-function","backface-visibility","background","background-attachment","background-blend-mode","background-clip","background-color","background-image","background-origin","background-position","background-repeat","background-size","block-size","border","border-block","border-block-color","border-block-end","border-block-end-color","border-block-end-style","border-block-end-width","border-block-start","border-block-start-color","border-block-start-style","border-block-start-width","border-block-style","border-block-width","border-bottom","border-bottom-color","border-bottom-left-radius","border-bottom-right-radius","border-bottom-style","border-bottom-width","border-collapse","border-color","border-image","border-image-outset","border-image-repeat","border-image-slice","border-image-source","border-image-width","border-inline","border-inline-color","border-inline-end","border-inline-end-color","border-inline-end-style","border-inline-end-width","border-inline-start","border-inline-start-color","border-inline-start-style","border-inline-start-width","border-inline-style","border-inline-width","border-left","border-left-color","border-left-style","border-left-width","border-radius","border-right","border-right-color","border-right-style","border-right-width","border-spacing","border-style","border-top","border-top-color","border-top-left-radius","border-top-right-radius","border-top-style","border-top-width","border-width","bottom","box-decoration-break","box-shadow","box-sizing","break-after","break-before","break-inside","caption-side","caret-color","clear","clip","clip-path","clip-rule","color","column-count","column-fill","column-gap","column-rule","column-rule-color","column-rule-style","column-rule-width","column-span","column-width","columns","contain","content","content-visibility","counter-increment","counter-reset","cue","cue-after","cue-before","cursor","direction","display","empty-cells","filter","flex","flex-basis","flex-direction","flex-flow","flex-grow","flex-shrink","flex-wrap","float","flow","font","font-display","font-family","font-feature-settings","font-kerning","font-language-override","font-size","font-size-adjust","font-smoothing","font-stretch","font-style","font-synthesis","font-variant","font-variant-caps","font-variant-east-asian","font-variant-ligatures","font-variant-numeric","font-variant-position","font-variation-settings","font-weight","gap","glyph-orientation-vertical","grid","grid-area","grid-auto-columns","grid-auto-flow","grid-auto-rows","grid-column","grid-column-end","grid-column-start","grid-gap","grid-row","grid-row-end","grid-row-start","grid-template","grid-template-areas","grid-template-columns","grid-template-rows","hanging-punctuation","height","hyphens","icon","image-orientation","image-rendering","image-resolution","ime-mode","inline-size","isolation","justify-content","left","letter-spacing","line-break","line-height","list-style","list-style-image","list-style-position","list-style-type","margin","margin-block","margin-block-end","margin-block-start","margin-bottom","margin-inline","margin-inline-end","margin-inline-start","margin-left","margin-right","margin-top","marks","mask","mask-border","mask-border-mode","mask-border-outset","mask-border-repeat","mask-border-slice","mask-border-source","mask-border-width","mask-clip","mask-composite","mask-image","mask-mode","mask-origin","mask-position","mask-repeat","mask-size","mask-type","max-block-size","max-height","max-inline-size","max-width","min-block-size","min-height","min-inline-size","min-width","mix-blend-mode","nav-down","nav-index","nav-left","nav-right","nav-up","none","normal","object-fit","object-position","opacity","order","orphans","outline","outline-color","outline-offset","outline-style","outline-width","overflow","overflow-wrap","overflow-x","overflow-y","padding","padding-block","padding-block-end","padding-block-start","padding-bottom","padding-inline","padding-inline-end","padding-inline-start","padding-left","padding-right","padding-top","page-break-after","page-break-before","page-break-inside","pause","pause-after","pause-before","perspective","perspective-origin","pointer-events","position","quotes","resize","rest","rest-after","rest-before","right","row-gap","scroll-margin","scroll-margin-block","scroll-margin-block-end","scroll-margin-block-start","scroll-margin-bottom","scroll-margin-inline","scroll-margin-inline-end","scroll-margin-inline-start","scroll-margin-left","scroll-margin-right","scroll-margin-top","scroll-padding","scroll-padding-block","scroll-padding-block-end","scroll-padding-block-start","scroll-padding-bottom","scroll-padding-inline","scroll-padding-inline-end","scroll-padding-inline-start","scroll-padding-left","scroll-padding-right","scroll-padding-top","scroll-snap-align","scroll-snap-stop","scroll-snap-type","scrollbar-color","scrollbar-gutter","scrollbar-width","shape-image-threshold","shape-margin","shape-outside","speak","speak-as","src","tab-size","table-layout","text-align","text-align-all","text-align-last","text-combine-upright","text-decoration","text-decoration-color","text-decoration-line","text-decoration-style","text-emphasis","text-emphasis-color","text-emphasis-position","text-emphasis-style","text-indent","text-justify","text-orientation","text-overflow","text-rendering","text-shadow","text-transform","text-underline-position","top","transform","transform-box","transform-origin","transform-style","transition","transition-delay","transition-duration","transition-property","transition-timing-function","unicode-bidi","vertical-align","visibility","voice-balance","voice-duration","voice-family","voice-pitch","voice-range","voice-rate","voice-stress","voice-volume","white-space","widows","width","will-change","word-break","word-spacing","word-wrap","writing-mode","z-index"].reverse(),de=oe.concat(le) +;var ge="[0-9](_*[0-9])*",ue=`\\.(${ge})`,be="[0-9a-fA-F](_*[0-9a-fA-F])*",me={ +className:"number",variants:[{ +begin:`(\\b(${ge})((${ue})|\\.)?|(${ue}))[eE][+-]?(${ge})[fFdD]?\\b`},{ +begin:`\\b(${ge})((${ue})[fFdD]?\\b|\\.([fFdD]\\b)?)`},{ +begin:`(${ue})[fFdD]?\\b`},{begin:`\\b(${ge})[fFdD]\\b`},{ +begin:`\\b0[xX]((${be})\\.?|(${be})?\\.(${be}))[pP][+-]?(${ge})[fFdD]?\\b`},{ +begin:"\\b(0|[1-9](_*[0-9])*)[lL]?\\b"},{begin:`\\b0[xX](${be})[lL]?\\b`},{ +begin:"\\b0(_*[0-7])*[lL]?\\b"},{begin:"\\b0[bB][01](_*[01])*[lL]?\\b"}], +relevance:0};function pe(e,n,t){return-1===t?"":e.replace(n,(a=>pe(e,n,t-1)))} +const _e="[A-Za-z$_][0-9A-Za-z$_]*",he=["as","in","of","if","for","while","finally","var","new","function","do","return","void","else","break","catch","instanceof","with","throw","case","default","try","switch","continue","typeof","delete","let","yield","const","class","debugger","async","await","static","import","from","export","extends"],fe=["true","false","null","undefined","NaN","Infinity"],Ee=["Object","Function","Boolean","Symbol","Math","Date","Number","BigInt","String","RegExp","Array","Float32Array","Float64Array","Int8Array","Uint8Array","Uint8ClampedArray","Int16Array","Int32Array","Uint16Array","Uint32Array","BigInt64Array","BigUint64Array","Set","Map","WeakSet","WeakMap","ArrayBuffer","SharedArrayBuffer","Atomics","DataView","JSON","Promise","Generator","GeneratorFunction","AsyncFunction","Reflect","Proxy","Intl","WebAssembly"],ye=["Error","EvalError","InternalError","RangeError","ReferenceError","SyntaxError","TypeError","URIError"],Ne=["setInterval","setTimeout","clearInterval","clearTimeout","require","exports","eval","isFinite","isNaN","parseFloat","parseInt","decodeURI","decodeURIComponent","encodeURI","encodeURIComponent","escape","unescape"],we=["arguments","this","super","console","window","document","localStorage","sessionStorage","module","global"],ve=[].concat(Ne,Ee,ye) +;function Oe(e){const n=e.regex,t=_e,a={begin:/<[A-Za-z0-9\\._:-]+/, +end:/\/[A-Za-z0-9\\._:-]+>|\/>/,isTrulyOpeningTag:(e,n)=>{ +const t=e[0].length+e.index,a=e.input[t] +;if("<"===a||","===a)return void n.ignoreMatch();let i +;">"===a&&(((e,{after:n})=>{const t="</"+e[0].slice(1) +;return-1!==e.input.indexOf(t,n)})(e,{after:t})||n.ignoreMatch()) +;const r=e.input.substring(t) +;((i=r.match(/^\s*=/))||(i=r.match(/^\s+extends\s+/))&&0===i.index)&&n.ignoreMatch() +}},i={$pattern:_e,keyword:he,literal:fe,built_in:ve,"variable.language":we +},r="[0-9](_?[0-9])*",s=`\\.(${r})`,o="0|[1-9](_?[0-9])*|0[0-7]*[89][0-9]*",l={ +className:"number",variants:[{ +begin:`(\\b(${o})((${s})|\\.)?|(${s}))[eE][+-]?(${r})\\b`},{ +begin:`\\b(${o})\\b((${s})\\b|\\.)?|(${s})\\b`},{ +begin:"\\b(0|[1-9](_?[0-9])*)n\\b"},{ +begin:"\\b0[xX][0-9a-fA-F](_?[0-9a-fA-F])*n?\\b"},{ +begin:"\\b0[bB][0-1](_?[0-1])*n?\\b"},{begin:"\\b0[oO][0-7](_?[0-7])*n?\\b"},{ +begin:"\\b0[0-7]+n?\\b"}],relevance:0},c={className:"subst",begin:"\\$\\{", +end:"\\}",keywords:i,contains:[]},d={begin:"html`",end:"",starts:{end:"`", +returnEnd:!1,contains:[e.BACKSLASH_ESCAPE,c],subLanguage:"xml"}},g={ +begin:"css`",end:"",starts:{end:"`",returnEnd:!1, +contains:[e.BACKSLASH_ESCAPE,c],subLanguage:"css"}},u={begin:"gql`",end:"", +starts:{end:"`",returnEnd:!1,contains:[e.BACKSLASH_ESCAPE,c], +subLanguage:"graphql"}},b={className:"string",begin:"`",end:"`", +contains:[e.BACKSLASH_ESCAPE,c]},m={className:"comment", +variants:[e.COMMENT(/\/\*\*(?!\/)/,"\\*/",{relevance:0,contains:[{ +begin:"(?=@[A-Za-z]+)",relevance:0,contains:[{className:"doctag", +begin:"@[A-Za-z]+"},{className:"type",begin:"\\{",end:"\\}",excludeEnd:!0, +excludeBegin:!0,relevance:0},{className:"variable",begin:t+"(?=\\s*(-)|$)", +endsParent:!0,relevance:0},{begin:/(?=[^\n])\s/,relevance:0}]}] +}),e.C_BLOCK_COMMENT_MODE,e.C_LINE_COMMENT_MODE] +},p=[e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,d,g,u,b,{match:/\$\d+/},l] +;c.contains=p.concat({begin:/\{/,end:/\}/,keywords:i,contains:["self"].concat(p) +});const _=[].concat(m,c.contains),h=_.concat([{begin:/\(/,end:/\)/,keywords:i, +contains:["self"].concat(_)}]),f={className:"params",begin:/\(/,end:/\)/, +excludeBegin:!0,excludeEnd:!0,keywords:i,contains:h},E={variants:[{ +match:[/class/,/\s+/,t,/\s+/,/extends/,/\s+/,n.concat(t,"(",n.concat(/\./,t),")*")], +scope:{1:"keyword",3:"title.class",5:"keyword",7:"title.class.inherited"}},{ +match:[/class/,/\s+/,t],scope:{1:"keyword",3:"title.class"}}]},y={relevance:0, +match:n.either(/\bJSON/,/\b[A-Z][a-z]+([A-Z][a-z]*|\d)*/,/\b[A-Z]{2,}([A-Z][a-z]+|\d)+([A-Z][a-z]*)*/,/\b[A-Z]{2,}[a-z]+([A-Z][a-z]+|\d)*([A-Z][a-z]*)*/), +className:"title.class",keywords:{_:[...Ee,...ye]}},N={variants:[{ +match:[/function/,/\s+/,t,/(?=\s*\()/]},{match:[/function/,/\s*(?=\()/]}], +className:{1:"keyword",3:"title.function"},label:"func.def",contains:[f], +illegal:/%/},w={ +match:n.concat(/\b/,(v=[...Ne,"super","import"],n.concat("(?!",v.join("|"),")")),t,n.lookahead(/\(/)), +className:"title.function",relevance:0};var v;const O={ +begin:n.concat(/\./,n.lookahead(n.concat(t,/(?![0-9A-Za-z$_(])/))),end:t, +excludeBegin:!0,keywords:"prototype",className:"property",relevance:0},k={ +match:[/get|set/,/\s+/,t,/(?=\()/],className:{1:"keyword",3:"title.function"}, +contains:[{begin:/\(\)/},f] +},x="(\\([^()]*(\\([^()]*(\\([^()]*\\)[^()]*)*\\)[^()]*)*\\)|"+e.UNDERSCORE_IDENT_RE+")\\s*=>",M={ +match:[/const|var|let/,/\s+/,t,/\s*/,/=\s*/,/(async\s*)?/,n.lookahead(x)], +keywords:"async",className:{1:"keyword",3:"title.function"},contains:[f]} +;return{name:"JavaScript",aliases:["js","jsx","mjs","cjs"],keywords:i,exports:{ +PARAMS_CONTAINS:h,CLASS_REFERENCE:y},illegal:/#(?![$_A-z])/, +contains:[e.SHEBANG({label:"shebang",binary:"node",relevance:5}),{ +label:"use_strict",className:"meta",relevance:10, +begin:/^\s*['"]use (strict|asm)['"]/ +},e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,d,g,u,b,m,{match:/\$\d+/},l,y,{ +className:"attr",begin:t+n.lookahead(":"),relevance:0},M,{ +begin:"("+e.RE_STARTERS_RE+"|\\b(case|return|throw)\\b)\\s*", +keywords:"return throw case",relevance:0,contains:[m,e.REGEXP_MODE,{ +className:"function",begin:x,returnBegin:!0,end:"\\s*=>",contains:[{ +className:"params",variants:[{begin:e.UNDERSCORE_IDENT_RE,relevance:0},{ +className:null,begin:/\(\s*\)/,skip:!0},{begin:/\(/,end:/\)/,excludeBegin:!0, +excludeEnd:!0,keywords:i,contains:h}]}]},{begin:/,/,relevance:0},{match:/\s+/, +relevance:0},{variants:[{begin:"<>",end:"</>"},{ +match:/<[A-Za-z0-9\\._:-]+\s*\/>/},{begin:a.begin, +"on:begin":a.isTrulyOpeningTag,end:a.end}],subLanguage:"xml",contains:[{ +begin:a.begin,end:a.end,skip:!0,contains:["self"]}]}]},N,{ +beginKeywords:"while if switch catch for"},{ +begin:"\\b(?!function)"+e.UNDERSCORE_IDENT_RE+"\\([^()]*(\\([^()]*(\\([^()]*\\)[^()]*)*\\)[^()]*)*\\)\\s*\\{", +returnBegin:!0,label:"func.def",contains:[f,e.inherit(e.TITLE_MODE,{begin:t, +className:"title.function"})]},{match:/\.\.\./,relevance:0},O,{match:"\\$"+t, +relevance:0},{match:[/\bconstructor(?=\s*\()/],className:{1:"title.function"}, +contains:[f]},w,{relevance:0,match:/\b[A-Z][A-Z_0-9]+\b/, +className:"variable.constant"},E,k,{match:/\$[(.]/}]}} +const ke=e=>b(/\b/,e,/\w$/.test(e)?/\b/:/\B/),xe=["Protocol","Type"].map(ke),Me=["init","self"].map(ke),Se=["Any","Self"],Ae=["actor","any","associatedtype","async","await",/as\?/,/as!/,"as","borrowing","break","case","catch","class","consume","consuming","continue","convenience","copy","default","defer","deinit","didSet","distributed","do","dynamic","each","else","enum","extension","fallthrough",/fileprivate\(set\)/,"fileprivate","final","for","func","get","guard","if","import","indirect","infix",/init\?/,/init!/,"inout",/internal\(set\)/,"internal","in","is","isolated","nonisolated","lazy","let","macro","mutating","nonmutating",/open\(set\)/,"open","operator","optional","override","postfix","precedencegroup","prefix",/private\(set\)/,"private","protocol",/public\(set\)/,"public","repeat","required","rethrows","return","set","some","static","struct","subscript","super","switch","throws","throw",/try\?/,/try!/,"try","typealias",/unowned\(safe\)/,/unowned\(unsafe\)/,"unowned","var","weak","where","while","willSet"],Ce=["false","nil","true"],Te=["assignment","associativity","higherThan","left","lowerThan","none","right"],Re=["#colorLiteral","#column","#dsohandle","#else","#elseif","#endif","#error","#file","#fileID","#fileLiteral","#filePath","#function","#if","#imageLiteral","#keyPath","#line","#selector","#sourceLocation","#warning"],De=["abs","all","any","assert","assertionFailure","debugPrint","dump","fatalError","getVaList","isKnownUniquelyReferenced","max","min","numericCast","pointwiseMax","pointwiseMin","precondition","preconditionFailure","print","readLine","repeatElement","sequence","stride","swap","swift_unboxFromSwiftValueWithType","transcode","type","unsafeBitCast","unsafeDowncast","withExtendedLifetime","withUnsafeMutablePointer","withUnsafePointer","withVaList","withoutActuallyEscaping","zip"],Ie=m(/[/=\-+!*%<>&|^~?]/,/[\u00A1-\u00A7]/,/[\u00A9\u00AB]/,/[\u00AC\u00AE]/,/[\u00B0\u00B1]/,/[\u00B6\u00BB\u00BF\u00D7\u00F7]/,/[\u2016-\u2017]/,/[\u2020-\u2027]/,/[\u2030-\u203E]/,/[\u2041-\u2053]/,/[\u2055-\u205E]/,/[\u2190-\u23FF]/,/[\u2500-\u2775]/,/[\u2794-\u2BFF]/,/[\u2E00-\u2E7F]/,/[\u3001-\u3003]/,/[\u3008-\u3020]/,/[\u3030]/),Le=m(Ie,/[\u0300-\u036F]/,/[\u1DC0-\u1DFF]/,/[\u20D0-\u20FF]/,/[\uFE00-\uFE0F]/,/[\uFE20-\uFE2F]/),Be=b(Ie,Le,"*"),$e=m(/[a-zA-Z_]/,/[\u00A8\u00AA\u00AD\u00AF\u00B2-\u00B5\u00B7-\u00BA]/,/[\u00BC-\u00BE\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u00FF]/,/[\u0100-\u02FF\u0370-\u167F\u1681-\u180D\u180F-\u1DBF]/,/[\u1E00-\u1FFF]/,/[\u200B-\u200D\u202A-\u202E\u203F-\u2040\u2054\u2060-\u206F]/,/[\u2070-\u20CF\u2100-\u218F\u2460-\u24FF\u2776-\u2793]/,/[\u2C00-\u2DFF\u2E80-\u2FFF]/,/[\u3004-\u3007\u3021-\u302F\u3031-\u303F\u3040-\uD7FF]/,/[\uF900-\uFD3D\uFD40-\uFDCF\uFDF0-\uFE1F\uFE30-\uFE44]/,/[\uFE47-\uFEFE\uFF00-\uFFFD]/),ze=m($e,/\d/,/[\u0300-\u036F\u1DC0-\u1DFF\u20D0-\u20FF\uFE20-\uFE2F]/),Fe=b($e,ze,"*"),Ue=b(/[A-Z]/,ze,"*"),je=["attached","autoclosure",b(/convention\(/,m("swift","block","c"),/\)/),"discardableResult","dynamicCallable","dynamicMemberLookup","escaping","freestanding","frozen","GKInspectable","IBAction","IBDesignable","IBInspectable","IBOutlet","IBSegueAction","inlinable","main","nonobjc","NSApplicationMain","NSCopying","NSManaged",b(/objc\(/,Fe,/\)/),"objc","objcMembers","propertyWrapper","requires_stored_property_inits","resultBuilder","Sendable","testable","UIApplicationMain","unchecked","unknown","usableFromInline","warn_unqualified_access"],Pe=["iOS","iOSApplicationExtension","macOS","macOSApplicationExtension","macCatalyst","macCatalystApplicationExtension","watchOS","watchOSApplicationExtension","tvOS","tvOSApplicationExtension","swift"] +;var Ke=Object.freeze({__proto__:null,grmr_bash:e=>{const n=e.regex,t={},a={ +begin:/\$\{/,end:/\}/,contains:["self",{begin:/:-/,contains:[t]}]} +;Object.assign(t,{className:"variable",variants:[{ +begin:n.concat(/\$[\w\d#@][\w\d_]*/,"(?![\\w\\d])(?![$])")},a]});const i={ +className:"subst",begin:/\$\(/,end:/\)/,contains:[e.BACKSLASH_ESCAPE]},r={ +begin:/<<-?\s*(?=\w+)/,starts:{contains:[e.END_SAME_AS_BEGIN({begin:/(\w+)/, +end:/(\w+)/,className:"string"})]}},s={className:"string",begin:/"/,end:/"/, +contains:[e.BACKSLASH_ESCAPE,t,i]};i.contains.push(s);const o={begin:/\$?\(\(/, +end:/\)\)/,contains:[{begin:/\d+#[0-9a-f]+/,className:"number"},e.NUMBER_MODE,t] +},l=e.SHEBANG({binary:"(fish|bash|zsh|sh|csh|ksh|tcsh|dash|scsh)",relevance:10 +}),c={className:"function",begin:/\w[\w\d_]*\s*\(\s*\)\s*\{/,returnBegin:!0, +contains:[e.inherit(e.TITLE_MODE,{begin:/\w[\w\d_]*/})],relevance:0};return{ +name:"Bash",aliases:["sh"],keywords:{$pattern:/\b[a-z][a-z0-9._-]+\b/, +keyword:["if","then","else","elif","fi","for","while","until","in","do","done","case","esac","function","select"], +literal:["true","false"], +built_in:["break","cd","continue","eval","exec","exit","export","getopts","hash","pwd","readonly","return","shift","test","times","trap","umask","unset","alias","bind","builtin","caller","command","declare","echo","enable","help","let","local","logout","mapfile","printf","read","readarray","source","type","typeset","ulimit","unalias","set","shopt","autoload","bg","bindkey","bye","cap","chdir","clone","comparguments","compcall","compctl","compdescribe","compfiles","compgroups","compquote","comptags","comptry","compvalues","dirs","disable","disown","echotc","echoti","emulate","fc","fg","float","functions","getcap","getln","history","integer","jobs","kill","limit","log","noglob","popd","print","pushd","pushln","rehash","sched","setcap","setopt","stat","suspend","ttyctl","unfunction","unhash","unlimit","unsetopt","vared","wait","whence","where","which","zcompile","zformat","zftp","zle","zmodload","zparseopts","zprof","zpty","zregexparse","zsocket","zstyle","ztcp","chcon","chgrp","chown","chmod","cp","dd","df","dir","dircolors","ln","ls","mkdir","mkfifo","mknod","mktemp","mv","realpath","rm","rmdir","shred","sync","touch","truncate","vdir","b2sum","base32","base64","cat","cksum","comm","csplit","cut","expand","fmt","fold","head","join","md5sum","nl","numfmt","od","paste","ptx","pr","sha1sum","sha224sum","sha256sum","sha384sum","sha512sum","shuf","sort","split","sum","tac","tail","tr","tsort","unexpand","uniq","wc","arch","basename","chroot","date","dirname","du","echo","env","expr","factor","groups","hostid","id","link","logname","nice","nohup","nproc","pathchk","pinky","printenv","printf","pwd","readlink","runcon","seq","sleep","stat","stdbuf","stty","tee","test","timeout","tty","uname","unlink","uptime","users","who","whoami","yes"] +},contains:[l,e.SHEBANG(),c,o,e.HASH_COMMENT_MODE,r,{match:/(\/[a-z._-]+)+/},s,{ +match:/\\"/},{className:"string",begin:/'/,end:/'/},{match:/\\'/},t]}}, +grmr_c:e=>{const n=e.regex,t=e.COMMENT("//","$",{contains:[{begin:/\\\n/}] +}),a="decltype\\(auto\\)",i="[a-zA-Z_]\\w*::",r="("+a+"|"+n.optional(i)+"[a-zA-Z_]\\w*"+n.optional("<[^<>]+>")+")",s={ +className:"type",variants:[{begin:"\\b[a-z\\d_]*_t\\b"},{ +match:/\batomic_[a-z]{3,6}\b/}]},o={className:"string",variants:[{ +begin:'(u8?|U|L)?"',end:'"',illegal:"\\n",contains:[e.BACKSLASH_ESCAPE]},{ +begin:"(u8?|U|L)?'(\\\\(x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4,8}|[0-7]{3}|\\S)|.)", +end:"'",illegal:"."},e.END_SAME_AS_BEGIN({ +begin:/(?:u8?|U|L)?R"([^()\\ ]{0,16})\(/,end:/\)([^()\\ ]{0,16})"/})]},l={ +className:"number",variants:[{begin:"\\b(0b[01']+)"},{ +begin:"(-?)\\b([\\d']+(\\.[\\d']*)?|\\.[\\d']+)((ll|LL|l|L)(u|U)?|(u|U)(ll|LL|l|L)?|f|F|b|B)" +},{ +begin:"(-?)(\\b0[xX][a-fA-F0-9']+|(\\b[\\d']+(\\.[\\d']*)?|\\.[\\d']+)([eE][-+]?[\\d']+)?)" +}],relevance:0},c={className:"meta",begin:/#\s*[a-z]+\b/,end:/$/,keywords:{ +keyword:"if else elif endif define undef warning error line pragma _Pragma ifdef ifndef include" +},contains:[{begin:/\\\n/,relevance:0},e.inherit(o,{className:"string"}),{ +className:"string",begin:/<.*?>/},t,e.C_BLOCK_COMMENT_MODE]},d={ +className:"title",begin:n.optional(i)+e.IDENT_RE,relevance:0 +},g=n.optional(i)+e.IDENT_RE+"\\s*\\(",u={ +keyword:["asm","auto","break","case","continue","default","do","else","enum","extern","for","fortran","goto","if","inline","register","restrict","return","sizeof","struct","switch","typedef","union","volatile","while","_Alignas","_Alignof","_Atomic","_Generic","_Noreturn","_Static_assert","_Thread_local","alignas","alignof","noreturn","static_assert","thread_local","_Pragma"], +type:["float","double","signed","unsigned","int","short","long","char","void","_Bool","_Complex","_Imaginary","_Decimal32","_Decimal64","_Decimal128","const","static","complex","bool","imaginary"], +literal:"true false NULL", +built_in:"std string wstring cin cout cerr clog stdin stdout stderr stringstream istringstream ostringstream auto_ptr deque list queue stack vector map set pair bitset multiset multimap unordered_set unordered_map unordered_multiset unordered_multimap priority_queue make_pair array shared_ptr abort terminate abs acos asin atan2 atan calloc ceil cosh cos exit exp fabs floor fmod fprintf fputs free frexp fscanf future isalnum isalpha iscntrl isdigit isgraph islower isprint ispunct isspace isupper isxdigit tolower toupper labs ldexp log10 log malloc realloc memchr memcmp memcpy memset modf pow printf putchar puts scanf sinh sin snprintf sprintf sqrt sscanf strcat strchr strcmp strcpy strcspn strlen strncat strncmp strncpy strpbrk strrchr strspn strstr tanh tan vfprintf vprintf vsprintf endl initializer_list unique_ptr" +},b=[c,s,t,e.C_BLOCK_COMMENT_MODE,l,o],m={variants:[{begin:/=/,end:/;/},{ +begin:/\(/,end:/\)/},{beginKeywords:"new throw return else",end:/;/}], +keywords:u,contains:b.concat([{begin:/\(/,end:/\)/,keywords:u, +contains:b.concat(["self"]),relevance:0}]),relevance:0},p={ +begin:"("+r+"[\\*&\\s]+)+"+g,returnBegin:!0,end:/[{;=]/,excludeEnd:!0, +keywords:u,illegal:/[^\w\s\*&:<>.]/,contains:[{begin:a,keywords:u,relevance:0},{ +begin:g,returnBegin:!0,contains:[e.inherit(d,{className:"title.function"})], +relevance:0},{relevance:0,match:/,/},{className:"params",begin:/\(/,end:/\)/, +keywords:u,relevance:0,contains:[t,e.C_BLOCK_COMMENT_MODE,o,l,s,{begin:/\(/, +end:/\)/,keywords:u,relevance:0,contains:["self",t,e.C_BLOCK_COMMENT_MODE,o,l,s] +}]},s,t,e.C_BLOCK_COMMENT_MODE,c]};return{name:"C",aliases:["h"],keywords:u, +disableAutodetect:!0,illegal:"</",contains:[].concat(m,p,b,[c,{ +begin:e.IDENT_RE+"::",keywords:u},{className:"class", +beginKeywords:"enum class struct union",end:/[{;:<>=]/,contains:[{ +beginKeywords:"final class struct"},e.TITLE_MODE]}]),exports:{preprocessor:c, +strings:o,keywords:u}}},grmr_cpp:e=>{const n=e.regex,t=e.COMMENT("//","$",{ +contains:[{begin:/\\\n/}] +}),a="decltype\\(auto\\)",i="[a-zA-Z_]\\w*::",r="(?!struct)("+a+"|"+n.optional(i)+"[a-zA-Z_]\\w*"+n.optional("<[^<>]+>")+")",s={ +className:"type",begin:"\\b[a-z\\d_]*_t\\b"},o={className:"string",variants:[{ +begin:'(u8?|U|L)?"',end:'"',illegal:"\\n",contains:[e.BACKSLASH_ESCAPE]},{ +begin:"(u8?|U|L)?'(\\\\(x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4,8}|[0-7]{3}|\\S)|.)", +end:"'",illegal:"."},e.END_SAME_AS_BEGIN({ +begin:/(?:u8?|U|L)?R"([^()\\ ]{0,16})\(/,end:/\)([^()\\ ]{0,16})"/})]},l={ +className:"number",variants:[{begin:"\\b(0b[01']+)"},{ +begin:"(-?)\\b([\\d']+(\\.[\\d']*)?|\\.[\\d']+)((ll|LL|l|L)(u|U)?|(u|U)(ll|LL|l|L)?|f|F|b|B)" +},{ +begin:"(-?)(\\b0[xX][a-fA-F0-9']+|(\\b[\\d']+(\\.[\\d']*)?|\\.[\\d']+)([eE][-+]?[\\d']+)?)" +}],relevance:0},c={className:"meta",begin:/#\s*[a-z]+\b/,end:/$/,keywords:{ +keyword:"if else elif endif define undef warning error line pragma _Pragma ifdef ifndef include" +},contains:[{begin:/\\\n/,relevance:0},e.inherit(o,{className:"string"}),{ +className:"string",begin:/<.*?>/},t,e.C_BLOCK_COMMENT_MODE]},d={ +className:"title",begin:n.optional(i)+e.IDENT_RE,relevance:0 +},g=n.optional(i)+e.IDENT_RE+"\\s*\\(",u={ +type:["bool","char","char16_t","char32_t","char8_t","double","float","int","long","short","void","wchar_t","unsigned","signed","const","static"], +keyword:["alignas","alignof","and","and_eq","asm","atomic_cancel","atomic_commit","atomic_noexcept","auto","bitand","bitor","break","case","catch","class","co_await","co_return","co_yield","compl","concept","const_cast|10","consteval","constexpr","constinit","continue","decltype","default","delete","do","dynamic_cast|10","else","enum","explicit","export","extern","false","final","for","friend","goto","if","import","inline","module","mutable","namespace","new","noexcept","not","not_eq","nullptr","operator","or","or_eq","override","private","protected","public","reflexpr","register","reinterpret_cast|10","requires","return","sizeof","static_assert","static_cast|10","struct","switch","synchronized","template","this","thread_local","throw","transaction_safe","transaction_safe_dynamic","true","try","typedef","typeid","typename","union","using","virtual","volatile","while","xor","xor_eq"], +literal:["NULL","false","nullopt","nullptr","true"],built_in:["_Pragma"], +_type_hints:["any","auto_ptr","barrier","binary_semaphore","bitset","complex","condition_variable","condition_variable_any","counting_semaphore","deque","false_type","future","imaginary","initializer_list","istringstream","jthread","latch","lock_guard","multimap","multiset","mutex","optional","ostringstream","packaged_task","pair","promise","priority_queue","queue","recursive_mutex","recursive_timed_mutex","scoped_lock","set","shared_future","shared_lock","shared_mutex","shared_timed_mutex","shared_ptr","stack","string_view","stringstream","timed_mutex","thread","true_type","tuple","unique_lock","unique_ptr","unordered_map","unordered_multimap","unordered_multiset","unordered_set","variant","vector","weak_ptr","wstring","wstring_view"] +},b={className:"function.dispatch",relevance:0,keywords:{ +_hint:["abort","abs","acos","apply","as_const","asin","atan","atan2","calloc","ceil","cerr","cin","clog","cos","cosh","cout","declval","endl","exchange","exit","exp","fabs","floor","fmod","forward","fprintf","fputs","free","frexp","fscanf","future","invoke","isalnum","isalpha","iscntrl","isdigit","isgraph","islower","isprint","ispunct","isspace","isupper","isxdigit","labs","launder","ldexp","log","log10","make_pair","make_shared","make_shared_for_overwrite","make_tuple","make_unique","malloc","memchr","memcmp","memcpy","memset","modf","move","pow","printf","putchar","puts","realloc","scanf","sin","sinh","snprintf","sprintf","sqrt","sscanf","std","stderr","stdin","stdout","strcat","strchr","strcmp","strcpy","strcspn","strlen","strncat","strncmp","strncpy","strpbrk","strrchr","strspn","strstr","swap","tan","tanh","terminate","to_underlying","tolower","toupper","vfprintf","visit","vprintf","vsprintf"] +}, +begin:n.concat(/\b/,/(?!decltype)/,/(?!if)/,/(?!for)/,/(?!switch)/,/(?!while)/,e.IDENT_RE,n.lookahead(/(<[^<>]+>|)\s*\(/)) +},m=[b,c,s,t,e.C_BLOCK_COMMENT_MODE,l,o],p={variants:[{begin:/=/,end:/;/},{ +begin:/\(/,end:/\)/},{beginKeywords:"new throw return else",end:/;/}], +keywords:u,contains:m.concat([{begin:/\(/,end:/\)/,keywords:u, +contains:m.concat(["self"]),relevance:0}]),relevance:0},_={className:"function", +begin:"("+r+"[\\*&\\s]+)+"+g,returnBegin:!0,end:/[{;=]/,excludeEnd:!0, +keywords:u,illegal:/[^\w\s\*&:<>.]/,contains:[{begin:a,keywords:u,relevance:0},{ +begin:g,returnBegin:!0,contains:[d],relevance:0},{begin:/::/,relevance:0},{ +begin:/:/,endsWithParent:!0,contains:[o,l]},{relevance:0,match:/,/},{ +className:"params",begin:/\(/,end:/\)/,keywords:u,relevance:0, +contains:[t,e.C_BLOCK_COMMENT_MODE,o,l,s,{begin:/\(/,end:/\)/,keywords:u, +relevance:0,contains:["self",t,e.C_BLOCK_COMMENT_MODE,o,l,s]}] +},s,t,e.C_BLOCK_COMMENT_MODE,c]};return{name:"C++", +aliases:["cc","c++","h++","hpp","hh","hxx","cxx"],keywords:u,illegal:"</", +classNameAliases:{"function.dispatch":"built_in"}, +contains:[].concat(p,_,b,m,[c,{ +begin:"\\b(deque|list|queue|priority_queue|pair|stack|vector|map|set|bitset|multiset|multimap|unordered_map|unordered_set|unordered_multiset|unordered_multimap|array|tuple|optional|variant|function)\\s*<(?!<)", +end:">",keywords:u,contains:["self",s]},{begin:e.IDENT_RE+"::",keywords:u},{ +match:[/\b(?:enum(?:\s+(?:class|struct))?|class|struct|union)/,/\s+/,/\w+/], +className:{1:"keyword",3:"title.class"}}])}},grmr_csharp:e=>{const n={ +keyword:["abstract","as","base","break","case","catch","class","const","continue","do","else","event","explicit","extern","finally","fixed","for","foreach","goto","if","implicit","in","interface","internal","is","lock","namespace","new","operator","out","override","params","private","protected","public","readonly","record","ref","return","scoped","sealed","sizeof","stackalloc","static","struct","switch","this","throw","try","typeof","unchecked","unsafe","using","virtual","void","volatile","while"].concat(["add","alias","and","ascending","async","await","by","descending","equals","from","get","global","group","init","into","join","let","nameof","not","notnull","on","or","orderby","partial","remove","select","set","unmanaged","value|0","var","when","where","with","yield"]), +built_in:["bool","byte","char","decimal","delegate","double","dynamic","enum","float","int","long","nint","nuint","object","sbyte","short","string","ulong","uint","ushort"], +literal:["default","false","null","true"]},t=e.inherit(e.TITLE_MODE,{ +begin:"[a-zA-Z](\\.?\\w)*"}),a={className:"number",variants:[{ +begin:"\\b(0b[01']+)"},{ +begin:"(-?)\\b([\\d']+(\\.[\\d']*)?|\\.[\\d']+)(u|U|l|L|ul|UL|f|F|b|B)"},{ +begin:"(-?)(\\b0[xX][a-fA-F0-9']+|(\\b[\\d']+(\\.[\\d']*)?|\\.[\\d']+)([eE][-+]?[\\d']+)?)" +}],relevance:0},i={className:"string",begin:'@"',end:'"',contains:[{begin:'""'}] +},r=e.inherit(i,{illegal:/\n/}),s={className:"subst",begin:/\{/,end:/\}/, +keywords:n},o=e.inherit(s,{illegal:/\n/}),l={className:"string",begin:/\$"/, +end:'"',illegal:/\n/,contains:[{begin:/\{\{/},{begin:/\}\}/ +},e.BACKSLASH_ESCAPE,o]},c={className:"string",begin:/\$@"/,end:'"',contains:[{ +begin:/\{\{/},{begin:/\}\}/},{begin:'""'},s]},d=e.inherit(c,{illegal:/\n/, +contains:[{begin:/\{\{/},{begin:/\}\}/},{begin:'""'},o]}) +;s.contains=[c,l,i,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,a,e.C_BLOCK_COMMENT_MODE], +o.contains=[d,l,r,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,a,e.inherit(e.C_BLOCK_COMMENT_MODE,{ +illegal:/\n/})];const g={variants:[c,l,i,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE] +},u={begin:"<",end:">",contains:[{beginKeywords:"in out"},t] +},b=e.IDENT_RE+"(<"+e.IDENT_RE+"(\\s*,\\s*"+e.IDENT_RE+")*>)?(\\[\\])?",m={ +begin:"@"+e.IDENT_RE,relevance:0};return{name:"C#",aliases:["cs","c#"], +keywords:n,illegal:/::/,contains:[e.COMMENT("///","$",{returnBegin:!0, +contains:[{className:"doctag",variants:[{begin:"///",relevance:0},{ +begin:"\x3c!--|--\x3e"},{begin:"</?",end:">"}]}] +}),e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,{className:"meta",begin:"#", +end:"$",keywords:{ +keyword:"if else elif endif define undef warning error line region endregion pragma checksum" +}},g,a,{beginKeywords:"class interface",relevance:0,end:/[{;=]/, +illegal:/[^\s:,]/,contains:[{beginKeywords:"where class" +},t,u,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},{beginKeywords:"namespace", +relevance:0,end:/[{;=]/,illegal:/[^\s:]/, +contains:[t,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},{ +beginKeywords:"record",relevance:0,end:/[{;=]/,illegal:/[^\s:]/, +contains:[t,u,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},{className:"meta", +begin:"^\\s*\\[(?=[\\w])",excludeBegin:!0,end:"\\]",excludeEnd:!0,contains:[{ +className:"string",begin:/"/,end:/"/}]},{ +beginKeywords:"new return throw await else",relevance:0},{className:"function", +begin:"("+b+"\\s+)+"+e.IDENT_RE+"\\s*(<[^=]+>\\s*)?\\(",returnBegin:!0, +end:/\s*[{;=]/,excludeEnd:!0,keywords:n,contains:[{ +beginKeywords:"public private protected static internal protected abstract async extern override unsafe virtual new sealed partial", +relevance:0},{begin:e.IDENT_RE+"\\s*(<[^=]+>\\s*)?\\(",returnBegin:!0, +contains:[e.TITLE_MODE,u],relevance:0},{match:/\(\)/},{className:"params", +begin:/\(/,end:/\)/,excludeBegin:!0,excludeEnd:!0,keywords:n,relevance:0, +contains:[g,a,e.C_BLOCK_COMMENT_MODE] +},e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},m]}},grmr_css:e=>{ +const n=e.regex,t=ie(e),a=[e.APOS_STRING_MODE,e.QUOTE_STRING_MODE];return{ +name:"CSS",case_insensitive:!0,illegal:/[=|'\$]/,keywords:{ +keyframePosition:"from to"},classNameAliases:{keyframePosition:"selector-tag"}, +contains:[t.BLOCK_COMMENT,{begin:/-(webkit|moz|ms|o)-(?=[a-z])/ +},t.CSS_NUMBER_MODE,{className:"selector-id",begin:/#[A-Za-z0-9_-]+/,relevance:0 +},{className:"selector-class",begin:"\\.[a-zA-Z-][a-zA-Z0-9_-]*",relevance:0 +},t.ATTRIBUTE_SELECTOR_MODE,{className:"selector-pseudo",variants:[{ +begin:":("+oe.join("|")+")"},{begin:":(:)?("+le.join("|")+")"}] +},t.CSS_VARIABLE,{className:"attribute",begin:"\\b("+ce.join("|")+")\\b"},{ +begin:/:/,end:/[;}{]/, +contains:[t.BLOCK_COMMENT,t.HEXCOLOR,t.IMPORTANT,t.CSS_NUMBER_MODE,...a,{ +begin:/(url|data-uri)\(/,end:/\)/,relevance:0,keywords:{built_in:"url data-uri" +},contains:[...a,{className:"string",begin:/[^)]/,endsWithParent:!0, +excludeEnd:!0}]},t.FUNCTION_DISPATCH]},{begin:n.lookahead(/@/),end:"[{;]", +relevance:0,illegal:/:/,contains:[{className:"keyword",begin:/@-?\w[\w]*(-\w+)*/ +},{begin:/\s/,endsWithParent:!0,excludeEnd:!0,relevance:0,keywords:{ +$pattern:/[a-z-]+/,keyword:"and or not only",attribute:se.join(" ")},contains:[{ +begin:/[a-z-]+(?=:)/,className:"attribute"},...a,t.CSS_NUMBER_MODE]}]},{ +className:"selector-tag",begin:"\\b("+re.join("|")+")\\b"}]}},grmr_diff:e=>{ +const n=e.regex;return{name:"Diff",aliases:["patch"],contains:[{ +className:"meta",relevance:10, +match:n.either(/^@@ +-\d+,\d+ +\+\d+,\d+ +@@/,/^\*\*\* +\d+,\d+ +\*\*\*\*$/,/^--- +\d+,\d+ +----$/) +},{className:"comment",variants:[{ +begin:n.either(/Index: /,/^index/,/={3,}/,/^-{3}/,/^\*{3} /,/^\+{3}/,/^diff --git/), +end:/$/},{match:/^\*{15}$/}]},{className:"addition",begin:/^\+/,end:/$/},{ +className:"deletion",begin:/^-/,end:/$/},{className:"addition",begin:/^!/, +end:/$/}]}},grmr_go:e=>{const n={ +keyword:["break","case","chan","const","continue","default","defer","else","fallthrough","for","func","go","goto","if","import","interface","map","package","range","return","select","struct","switch","type","var"], +type:["bool","byte","complex64","complex128","error","float32","float64","int8","int16","int32","int64","string","uint8","uint16","uint32","uint64","int","uint","uintptr","rune"], +literal:["true","false","iota","nil"], +built_in:["append","cap","close","complex","copy","imag","len","make","new","panic","print","println","real","recover","delete"] +};return{name:"Go",aliases:["golang"],keywords:n,illegal:"</", +contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,{className:"string", +variants:[e.QUOTE_STRING_MODE,e.APOS_STRING_MODE,{begin:"`",end:"`"}]},{ +className:"number",variants:[{begin:e.C_NUMBER_RE+"[i]",relevance:1 +},e.C_NUMBER_MODE]},{begin:/:=/},{className:"function",beginKeywords:"func", +end:"\\s*(\\{|$)",excludeEnd:!0,contains:[e.TITLE_MODE,{className:"params", +begin:/\(/,end:/\)/,endsParent:!0,keywords:n,illegal:/["']/}]}]}}, +grmr_graphql:e=>{const n=e.regex;return{name:"GraphQL",aliases:["gql"], +case_insensitive:!0,disableAutodetect:!1,keywords:{ +keyword:["query","mutation","subscription","type","input","schema","directive","interface","union","scalar","fragment","enum","on"], +literal:["true","false","null"]}, +contains:[e.HASH_COMMENT_MODE,e.QUOTE_STRING_MODE,e.NUMBER_MODE,{ +scope:"punctuation",match:/[.]{3}/,relevance:0},{scope:"punctuation", +begin:/[\!\(\)\:\=\[\]\{\|\}]{1}/,relevance:0},{scope:"variable",begin:/\$/, +end:/\W/,excludeEnd:!0,relevance:0},{scope:"meta",match:/@\w+/,excludeEnd:!0},{ +scope:"symbol",begin:n.concat(/[_A-Za-z][_0-9A-Za-z]*/,n.lookahead(/\s*:/)), +relevance:0}],illegal:[/[;<']/,/BEGIN/]}},grmr_ini:e=>{const n=e.regex,t={ +className:"number",relevance:0,variants:[{begin:/([+-]+)?[\d]+_[\d_]+/},{ +begin:e.NUMBER_RE}]},a=e.COMMENT();a.variants=[{begin:/;/,end:/$/},{begin:/#/, +end:/$/}];const i={className:"variable",variants:[{begin:/\$[\w\d"][\w\d_]*/},{ +begin:/\$\{(.*?)\}/}]},r={className:"literal", +begin:/\bon|off|true|false|yes|no\b/},s={className:"string", +contains:[e.BACKSLASH_ESCAPE],variants:[{begin:"'''",end:"'''",relevance:10},{ +begin:'"""',end:'"""',relevance:10},{begin:'"',end:'"'},{begin:"'",end:"'"}] +},o={begin:/\[/,end:/\]/,contains:[a,r,i,s,t,"self"],relevance:0 +},l=n.either(/[A-Za-z0-9_-]+/,/"(\\"|[^"])*"/,/'[^']*'/);return{ +name:"TOML, also INI",aliases:["toml"],case_insensitive:!0,illegal:/\S/, +contains:[a,{className:"section",begin:/\[+/,end:/\]+/},{ +begin:n.concat(l,"(\\s*\\.\\s*",l,")*",n.lookahead(/\s*=\s*[^#\s]/)), +className:"attr",starts:{end:/$/,contains:[a,o,r,i,s,t]}}]}},grmr_java:e=>{ +const n=e.regex,t="[\xc0-\u02b8a-zA-Z_$][\xc0-\u02b8a-zA-Z_$0-9]*",a=t+pe("(?:<"+t+"~~~(?:\\s*,\\s*"+t+"~~~)*>)?",/~~~/g,2),i={ +keyword:["synchronized","abstract","private","var","static","if","const ","for","while","strictfp","finally","protected","import","native","final","void","enum","else","break","transient","catch","instanceof","volatile","case","assert","package","default","public","try","switch","continue","throws","protected","public","private","module","requires","exports","do","sealed","yield","permits"], +literal:["false","true","null"], +type:["char","boolean","long","float","int","byte","short","double"], +built_in:["super","this"]},r={className:"meta",begin:"@"+t,contains:[{ +begin:/\(/,end:/\)/,contains:["self"]}]},s={className:"params",begin:/\(/, +end:/\)/,keywords:i,relevance:0,contains:[e.C_BLOCK_COMMENT_MODE],endsParent:!0} +;return{name:"Java",aliases:["jsp"],keywords:i,illegal:/<\/|#/, +contains:[e.COMMENT("/\\*\\*","\\*/",{relevance:0,contains:[{begin:/\w+@/, +relevance:0},{className:"doctag",begin:"@[A-Za-z]+"}]}),{ +begin:/import java\.[a-z]+\./,keywords:"import",relevance:2 +},e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,{begin:/"""/,end:/"""/, +className:"string",contains:[e.BACKSLASH_ESCAPE] +},e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,{ +match:[/\b(?:class|interface|enum|extends|implements|new)/,/\s+/,t],className:{ +1:"keyword",3:"title.class"}},{match:/non-sealed/,scope:"keyword"},{ +begin:[n.concat(/(?!else)/,t),/\s+/,t,/\s+/,/=(?!=)/],className:{1:"type", +3:"variable",5:"operator"}},{begin:[/record/,/\s+/,t],className:{1:"keyword", +3:"title.class"},contains:[s,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},{ +beginKeywords:"new throw return else",relevance:0},{ +begin:["(?:"+a+"\\s+)",e.UNDERSCORE_IDENT_RE,/\s*(?=\()/],className:{ +2:"title.function"},keywords:i,contains:[{className:"params",begin:/\(/, +end:/\)/,keywords:i,relevance:0, +contains:[r,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,me,e.C_BLOCK_COMMENT_MODE] +},e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},me,r]}},grmr_javascript:Oe, +grmr_json:e=>{const n=["true","false","null"],t={scope:"literal", +beginKeywords:n.join(" ")};return{name:"JSON",keywords:{literal:n},contains:[{ +className:"attr",begin:/"(\\.|[^\\"\r\n])*"(?=\s*:)/,relevance:1.01},{ +match:/[{}[\],:]/,className:"punctuation",relevance:0 +},e.QUOTE_STRING_MODE,t,e.C_NUMBER_MODE,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE], +illegal:"\\S"}},grmr_kotlin:e=>{const n={ +keyword:"abstract as val var vararg get set class object open private protected public noinline crossinline dynamic final enum if else do while for when throw try catch finally import package is in fun override companion reified inline lateinit init interface annotation data sealed internal infix operator out by constructor super tailrec where const inner suspend typealias external expect actual", +built_in:"Byte Short Char Int Long Boolean Float Double Void Unit Nothing", +literal:"true false null"},t={className:"symbol",begin:e.UNDERSCORE_IDENT_RE+"@" +},a={className:"subst",begin:/\$\{/,end:/\}/,contains:[e.C_NUMBER_MODE]},i={ +className:"variable",begin:"\\$"+e.UNDERSCORE_IDENT_RE},r={className:"string", +variants:[{begin:'"""',end:'"""(?=[^"])',contains:[i,a]},{begin:"'",end:"'", +illegal:/\n/,contains:[e.BACKSLASH_ESCAPE]},{begin:'"',end:'"',illegal:/\n/, +contains:[e.BACKSLASH_ESCAPE,i,a]}]};a.contains.push(r);const s={ +className:"meta", +begin:"@(?:file|property|field|get|set|receiver|param|setparam|delegate)\\s*:(?:\\s*"+e.UNDERSCORE_IDENT_RE+")?" +},o={className:"meta",begin:"@"+e.UNDERSCORE_IDENT_RE,contains:[{begin:/\(/, +end:/\)/,contains:[e.inherit(r,{className:"string"}),"self"]}] +},l=me,c=e.COMMENT("/\\*","\\*/",{contains:[e.C_BLOCK_COMMENT_MODE]}),d={ +variants:[{className:"type",begin:e.UNDERSCORE_IDENT_RE},{begin:/\(/,end:/\)/, +contains:[]}]},g=d;return g.variants[1].contains=[d],d.variants[1].contains=[g], +{name:"Kotlin",aliases:["kt","kts"],keywords:n, +contains:[e.COMMENT("/\\*\\*","\\*/",{relevance:0,contains:[{className:"doctag", +begin:"@[A-Za-z]+"}]}),e.C_LINE_COMMENT_MODE,c,{className:"keyword", +begin:/\b(break|continue|return|this)\b/,starts:{contains:[{className:"symbol", +begin:/@\w+/}]}},t,s,o,{className:"function",beginKeywords:"fun",end:"[(]|$", +returnBegin:!0,excludeEnd:!0,keywords:n,relevance:5,contains:[{ +begin:e.UNDERSCORE_IDENT_RE+"\\s*\\(",returnBegin:!0,relevance:0, +contains:[e.UNDERSCORE_TITLE_MODE]},{className:"type",begin:/</,end:/>/, +keywords:"reified",relevance:0},{className:"params",begin:/\(/,end:/\)/, +endsParent:!0,keywords:n,relevance:0,contains:[{begin:/:/,end:/[=,\/]/, +endsWithParent:!0,contains:[d,e.C_LINE_COMMENT_MODE,c],relevance:0 +},e.C_LINE_COMMENT_MODE,c,s,o,r,e.C_NUMBER_MODE]},c]},{ +begin:[/class|interface|trait/,/\s+/,e.UNDERSCORE_IDENT_RE],beginScope:{ +3:"title.class"},keywords:"class interface trait",end:/[:\{(]|$/,excludeEnd:!0, +illegal:"extends implements",contains:[{ +beginKeywords:"public protected internal private constructor" +},e.UNDERSCORE_TITLE_MODE,{className:"type",begin:/</,end:/>/,excludeBegin:!0, +excludeEnd:!0,relevance:0},{className:"type",begin:/[,:]\s*/,end:/[<\(,){\s]|$/, +excludeBegin:!0,returnEnd:!0},s,o]},r,{className:"meta",begin:"^#!/usr/bin/env", +end:"$",illegal:"\n"},l]}},grmr_less:e=>{ +const n=ie(e),t=de,a="[\\w-]+",i="("+a+"|@\\{"+a+"\\})",r=[],s=[],o=e=>({ +className:"string",begin:"~?"+e+".*?"+e}),l=(e,n,t)=>({className:e,begin:n, +relevance:t}),c={$pattern:/[a-z-]+/,keyword:"and or not only", +attribute:se.join(" ")},d={begin:"\\(",end:"\\)",contains:s,keywords:c, +relevance:0} +;s.push(e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,o("'"),o('"'),n.CSS_NUMBER_MODE,{ +begin:"(url|data-uri)\\(",starts:{className:"string",end:"[\\)\\n]", +excludeEnd:!0} +},n.HEXCOLOR,d,l("variable","@@?"+a,10),l("variable","@\\{"+a+"\\}"),l("built_in","~?`[^`]*?`"),{ +className:"attribute",begin:a+"\\s*:",end:":",returnBegin:!0,excludeEnd:!0 +},n.IMPORTANT,{beginKeywords:"and not"},n.FUNCTION_DISPATCH);const g=s.concat({ +begin:/\{/,end:/\}/,contains:r}),u={beginKeywords:"when",endsWithParent:!0, +contains:[{beginKeywords:"and not"}].concat(s)},b={begin:i+"\\s*:", +returnBegin:!0,end:/[;}]/,relevance:0,contains:[{begin:/-(webkit|moz|ms|o)-/ +},n.CSS_VARIABLE,{className:"attribute",begin:"\\b("+ce.join("|")+")\\b", +end:/(?=:)/,starts:{endsWithParent:!0,illegal:"[<=$]",relevance:0,contains:s}}] +},m={className:"keyword", +begin:"@(import|media|charset|font-face|(-[a-z]+-)?keyframes|supports|document|namespace|page|viewport|host)\\b", +starts:{end:"[;{}]",keywords:c,returnEnd:!0,contains:s,relevance:0}},p={ +className:"variable",variants:[{begin:"@"+a+"\\s*:",relevance:15},{begin:"@"+a +}],starts:{end:"[;}]",returnEnd:!0,contains:g}},_={variants:[{ +begin:"[\\.#:&\\[>]",end:"[;{}]"},{begin:i,end:/\{/}],returnBegin:!0, +returnEnd:!0,illegal:"[<='$\"]",relevance:0, +contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,u,l("keyword","all\\b"),l("variable","@\\{"+a+"\\}"),{ +begin:"\\b("+re.join("|")+")\\b",className:"selector-tag" +},n.CSS_NUMBER_MODE,l("selector-tag",i,0),l("selector-id","#"+i),l("selector-class","\\."+i,0),l("selector-tag","&",0),n.ATTRIBUTE_SELECTOR_MODE,{ +className:"selector-pseudo",begin:":("+oe.join("|")+")"},{ +className:"selector-pseudo",begin:":(:)?("+le.join("|")+")"},{begin:/\(/, +end:/\)/,relevance:0,contains:g},{begin:"!important"},n.FUNCTION_DISPATCH]},h={ +begin:a+":(:)?"+`(${t.join("|")})`,returnBegin:!0,contains:[_]} +;return r.push(e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,m,p,h,b,_,u,n.FUNCTION_DISPATCH), +{name:"Less",case_insensitive:!0,illegal:"[=>'/<($\"]",contains:r}}, +grmr_lua:e=>{const n="\\[=*\\[",t="\\]=*\\]",a={begin:n,end:t,contains:["self"] +},i=[e.COMMENT("--(?!"+n+")","$"),e.COMMENT("--"+n,t,{contains:[a],relevance:10 +})];return{name:"Lua",keywords:{$pattern:e.UNDERSCORE_IDENT_RE, +literal:"true false nil", +keyword:"and break do else elseif end for goto if in local not or repeat return then until while", +built_in:"_G _ENV _VERSION __index __newindex __mode __call __metatable __tostring __len __gc __add __sub __mul __div __mod __pow __concat __unm __eq __lt __le assert collectgarbage dofile error getfenv getmetatable ipairs load loadfile loadstring module next pairs pcall print rawequal rawget rawset require select setfenv setmetatable tonumber tostring type unpack xpcall arg self coroutine resume yield status wrap create running debug getupvalue debug sethook getmetatable gethook setmetatable setlocal traceback setfenv getinfo setupvalue getlocal getregistry getfenv io lines write close flush open output type read stderr stdin input stdout popen tmpfile math log max acos huge ldexp pi cos tanh pow deg tan cosh sinh random randomseed frexp ceil floor rad abs sqrt modf asin min mod fmod log10 atan2 exp sin atan os exit setlocale date getenv difftime remove time clock tmpname rename execute package preload loadlib loaded loaders cpath config path seeall string sub upper len gfind rep find match char dump gmatch reverse byte format gsub lower table setn insert getn foreachi maxn foreach concat sort remove" +},contains:i.concat([{className:"function",beginKeywords:"function",end:"\\)", +contains:[e.inherit(e.TITLE_MODE,{ +begin:"([_a-zA-Z]\\w*\\.)*([_a-zA-Z]\\w*:)?[_a-zA-Z]\\w*"}),{className:"params", +begin:"\\(",endsWithParent:!0,contains:i}].concat(i) +},e.C_NUMBER_MODE,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,{className:"string", +begin:n,end:t,contains:[a],relevance:5}])}},grmr_makefile:e=>{const n={ +className:"variable",variants:[{begin:"\\$\\("+e.UNDERSCORE_IDENT_RE+"\\)", +contains:[e.BACKSLASH_ESCAPE]},{begin:/\$[@%<?\^\+\*]/}]},t={className:"string", +begin:/"/,end:/"/,contains:[e.BACKSLASH_ESCAPE,n]},a={className:"variable", +begin:/\$\([\w-]+\s/,end:/\)/,keywords:{ +built_in:"subst patsubst strip findstring filter filter-out sort word wordlist firstword lastword dir notdir suffix basename addsuffix addprefix join wildcard realpath abspath error warning shell origin flavor foreach if or and call eval file value" +},contains:[n]},i={begin:"^"+e.UNDERSCORE_IDENT_RE+"\\s*(?=[:+?]?=)"},r={ +className:"section",begin:/^[^\s]+:/,end:/$/,contains:[n]};return{ +name:"Makefile",aliases:["mk","mak","make"],keywords:{$pattern:/[\w-]+/, +keyword:"define endef undefine ifdef ifndef ifeq ifneq else endif include -include sinclude override export unexport private vpath" +},contains:[e.HASH_COMMENT_MODE,n,t,a,i,{className:"meta",begin:/^\.PHONY:/, +end:/$/,keywords:{$pattern:/[\.\w]+/,keyword:".PHONY"}},r]}},grmr_markdown:e=>{ +const n={begin:/<\/?[A-Za-z_]/,end:">",subLanguage:"xml",relevance:0},t={ +variants:[{begin:/\[.+?\]\[.*?\]/,relevance:0},{ +begin:/\[.+?\]\(((data|javascript|mailto):|(?:http|ftp)s?:\/\/).*?\)/, +relevance:2},{ +begin:e.regex.concat(/\[.+?\]\(/,/[A-Za-z][A-Za-z0-9+.-]*/,/:\/\/.*?\)/), +relevance:2},{begin:/\[.+?\]\([./?&#].*?\)/,relevance:1},{ +begin:/\[.*?\]\(.*?\)/,relevance:0}],returnBegin:!0,contains:[{match:/\[(?=\])/ +},{className:"string",relevance:0,begin:"\\[",end:"\\]",excludeBegin:!0, +returnEnd:!0},{className:"link",relevance:0,begin:"\\]\\(",end:"\\)", +excludeBegin:!0,excludeEnd:!0},{className:"symbol",relevance:0,begin:"\\]\\[", +end:"\\]",excludeBegin:!0,excludeEnd:!0}]},a={className:"strong",contains:[], +variants:[{begin:/_{2}(?!\s)/,end:/_{2}/},{begin:/\*{2}(?!\s)/,end:/\*{2}/}] +},i={className:"emphasis",contains:[],variants:[{begin:/\*(?![*\s])/,end:/\*/},{ +begin:/_(?![_\s])/,end:/_/,relevance:0}]},r=e.inherit(a,{contains:[] +}),s=e.inherit(i,{contains:[]});a.contains.push(s),i.contains.push(r) +;let o=[n,t];return[a,i,r,s].forEach((e=>{e.contains=e.contains.concat(o) +})),o=o.concat(a,i),{name:"Markdown",aliases:["md","mkdown","mkd"],contains:[{ +className:"section",variants:[{begin:"^#{1,6}",end:"$",contains:o},{ +begin:"(?=^.+?\\n[=-]{2,}$)",contains:[{begin:"^[=-]*$"},{begin:"^",end:"\\n", +contains:o}]}]},n,{className:"bullet",begin:"^[ \t]*([*+-]|(\\d+\\.))(?=\\s+)", +end:"\\s+",excludeEnd:!0},a,i,{className:"quote",begin:"^>\\s+",contains:o, +end:"$"},{className:"code",variants:[{begin:"(`{3,})[^`](.|\\n)*?\\1`*[ ]*"},{ +begin:"(~{3,})[^~](.|\\n)*?\\1~*[ ]*"},{begin:"```",end:"```+[ ]*$"},{ +begin:"~~~",end:"~~~+[ ]*$"},{begin:"`.+?`"},{begin:"(?=^( {4}|\\t))", +contains:[{begin:"^( {4}|\\t)",end:"(\\n)$"}],relevance:0}]},{ +begin:"^[-\\*]{3,}",end:"$"},t,{begin:/^\[[^\n]+\]:/,returnBegin:!0,contains:[{ +className:"symbol",begin:/\[/,end:/\]/,excludeBegin:!0,excludeEnd:!0},{ +className:"link",begin:/:\s*/,end:/$/,excludeBegin:!0}]}]}},grmr_objectivec:e=>{ +const n=/[a-zA-Z@][a-zA-Z0-9_]*/,t={$pattern:n, +keyword:["@interface","@class","@protocol","@implementation"]};return{ +name:"Objective-C",aliases:["mm","objc","obj-c","obj-c++","objective-c++"], +keywords:{"variable.language":["this","super"],$pattern:n, +keyword:["while","export","sizeof","typedef","const","struct","for","union","volatile","static","mutable","if","do","return","goto","enum","else","break","extern","asm","case","default","register","explicit","typename","switch","continue","inline","readonly","assign","readwrite","self","@synchronized","id","typeof","nonatomic","IBOutlet","IBAction","strong","weak","copy","in","out","inout","bycopy","byref","oneway","__strong","__weak","__block","__autoreleasing","@private","@protected","@public","@try","@property","@end","@throw","@catch","@finally","@autoreleasepool","@synthesize","@dynamic","@selector","@optional","@required","@encode","@package","@import","@defs","@compatibility_alias","__bridge","__bridge_transfer","__bridge_retained","__bridge_retain","__covariant","__contravariant","__kindof","_Nonnull","_Nullable","_Null_unspecified","__FUNCTION__","__PRETTY_FUNCTION__","__attribute__","getter","setter","retain","unsafe_unretained","nonnull","nullable","null_unspecified","null_resettable","class","instancetype","NS_DESIGNATED_INITIALIZER","NS_UNAVAILABLE","NS_REQUIRES_SUPER","NS_RETURNS_INNER_POINTER","NS_INLINE","NS_AVAILABLE","NS_DEPRECATED","NS_ENUM","NS_OPTIONS","NS_SWIFT_UNAVAILABLE","NS_ASSUME_NONNULL_BEGIN","NS_ASSUME_NONNULL_END","NS_REFINED_FOR_SWIFT","NS_SWIFT_NAME","NS_SWIFT_NOTHROW","NS_DURING","NS_HANDLER","NS_ENDHANDLER","NS_VALUERETURN","NS_VOIDRETURN"], +literal:["false","true","FALSE","TRUE","nil","YES","NO","NULL"], +built_in:["dispatch_once_t","dispatch_queue_t","dispatch_sync","dispatch_async","dispatch_once"], +type:["int","float","char","unsigned","signed","short","long","double","wchar_t","unichar","void","bool","BOOL","id|0","_Bool"] +},illegal:"</",contains:[{className:"built_in", +begin:"\\b(AV|CA|CF|CG|CI|CL|CM|CN|CT|MK|MP|MTK|MTL|NS|SCN|SK|UI|WK|XC)\\w+" +},e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,e.C_NUMBER_MODE,e.QUOTE_STRING_MODE,e.APOS_STRING_MODE,{ +className:"string",variants:[{begin:'@"',end:'"',illegal:"\\n", +contains:[e.BACKSLASH_ESCAPE]}]},{className:"meta",begin:/#\s*[a-z]+\b/,end:/$/, +keywords:{ +keyword:"if else elif endif define undef warning error line pragma ifdef ifndef include" +},contains:[{begin:/\\\n/,relevance:0},e.inherit(e.QUOTE_STRING_MODE,{ +className:"string"}),{className:"string",begin:/<.*?>/,end:/$/,illegal:"\\n" +},e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},{className:"class", +begin:"("+t.keyword.join("|")+")\\b",end:/(\{|$)/,excludeEnd:!0,keywords:t, +contains:[e.UNDERSCORE_TITLE_MODE]},{begin:"\\."+e.UNDERSCORE_IDENT_RE, +relevance:0}]}},grmr_perl:e=>{const n=e.regex,t=/[dualxmsipngr]{0,12}/,a={ +$pattern:/[\w.]+/, +keyword:"abs accept alarm and atan2 bind binmode bless break caller chdir chmod chomp chop chown chr chroot close closedir connect continue cos crypt dbmclose dbmopen defined delete die do dump each else elsif endgrent endhostent endnetent endprotoent endpwent endservent eof eval exec exists exit exp fcntl fileno flock for foreach fork format formline getc getgrent getgrgid getgrnam gethostbyaddr gethostbyname gethostent getlogin getnetbyaddr getnetbyname getnetent getpeername getpgrp getpriority getprotobyname getprotobynumber getprotoent getpwent getpwnam getpwuid getservbyname getservbyport getservent getsockname getsockopt given glob gmtime goto grep gt hex if index int ioctl join keys kill last lc lcfirst length link listen local localtime log lstat lt ma map mkdir msgctl msgget msgrcv msgsnd my ne next no not oct open opendir or ord our pack package pipe pop pos print printf prototype push q|0 qq quotemeta qw qx rand read readdir readline readlink readpipe recv redo ref rename require reset return reverse rewinddir rindex rmdir say scalar seek seekdir select semctl semget semop send setgrent sethostent setnetent setpgrp setpriority setprotoent setpwent setservent setsockopt shift shmctl shmget shmread shmwrite shutdown sin sleep socket socketpair sort splice split sprintf sqrt srand stat state study sub substr symlink syscall sysopen sysread sysseek system syswrite tell telldir tie tied time times tr truncate uc ucfirst umask undef unless unlink unpack unshift untie until use utime values vec wait waitpid wantarray warn when while write x|0 xor y|0" +},i={className:"subst",begin:"[$@]\\{",end:"\\}",keywords:a},r={begin:/->\{/, +end:/\}/},s={variants:[{begin:/\$\d/},{ +begin:n.concat(/[$%@](\^\w\b|#\w+(::\w+)*|\{\w+\}|\w+(::\w*)*)/,"(?![A-Za-z])(?![@$%])") +},{begin:/[$%@][^\s\w{]/,relevance:0}] +},o=[e.BACKSLASH_ESCAPE,i,s],l=[/!/,/\//,/\|/,/\?/,/'/,/"/,/#/],c=(e,a,i="\\1")=>{ +const r="\\1"===i?i:n.concat(i,a) +;return n.concat(n.concat("(?:",e,")"),a,/(?:\\.|[^\\\/])*?/,r,/(?:\\.|[^\\\/])*?/,i,t) +},d=(e,a,i)=>n.concat(n.concat("(?:",e,")"),a,/(?:\\.|[^\\\/])*?/,i,t),g=[s,e.HASH_COMMENT_MODE,e.COMMENT(/^=\w/,/=cut/,{ +endsWithParent:!0}),r,{className:"string",contains:o,variants:[{ +begin:"q[qwxr]?\\s*\\(",end:"\\)",relevance:5},{begin:"q[qwxr]?\\s*\\[", +end:"\\]",relevance:5},{begin:"q[qwxr]?\\s*\\{",end:"\\}",relevance:5},{ +begin:"q[qwxr]?\\s*\\|",end:"\\|",relevance:5},{begin:"q[qwxr]?\\s*<",end:">", +relevance:5},{begin:"qw\\s+q",end:"q",relevance:5},{begin:"'",end:"'", +contains:[e.BACKSLASH_ESCAPE]},{begin:'"',end:'"'},{begin:"`",end:"`", +contains:[e.BACKSLASH_ESCAPE]},{begin:/\{\w+\}/,relevance:0},{ +begin:"-?\\w+\\s*=>",relevance:0}]},{className:"number", +begin:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b", +relevance:0},{ +begin:"(\\/\\/|"+e.RE_STARTERS_RE+"|\\b(split|return|print|reverse|grep)\\b)\\s*", +keywords:"split return print reverse grep",relevance:0, +contains:[e.HASH_COMMENT_MODE,{className:"regexp",variants:[{ +begin:c("s|tr|y",n.either(...l,{capture:!0}))},{begin:c("s|tr|y","\\(","\\)")},{ +begin:c("s|tr|y","\\[","\\]")},{begin:c("s|tr|y","\\{","\\}")}],relevance:2},{ +className:"regexp",variants:[{begin:/(m|qr)\/\//,relevance:0},{ +begin:d("(?:m|qr)?",/\//,/\//)},{begin:d("m|qr",n.either(...l,{capture:!0 +}),/\1/)},{begin:d("m|qr",/\(/,/\)/)},{begin:d("m|qr",/\[/,/\]/)},{ +begin:d("m|qr",/\{/,/\}/)}]}]},{className:"function",beginKeywords:"sub", +end:"(\\s*\\(.*?\\))?[;{]",excludeEnd:!0,relevance:5,contains:[e.TITLE_MODE]},{ +begin:"-\\w\\b",relevance:0},{begin:"^__DATA__$",end:"^__END__$", +subLanguage:"mojolicious",contains:[{begin:"^@@.*",end:"$",className:"comment"}] +}];return i.contains=g,r.contains=g,{name:"Perl",aliases:["pl","pm"],keywords:a, +contains:g}},grmr_php:e=>{ +const n=e.regex,t=/(?![A-Za-z0-9])(?![$])/,a=n.concat(/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/,t),i=n.concat(/(\\?[A-Z][a-z0-9_\x7f-\xff]+|\\?[A-Z]+(?=[A-Z][a-z0-9_\x7f-\xff])){1,}/,t),r={ +scope:"variable",match:"\\$+"+a},s={scope:"subst",variants:[{begin:/\$\w+/},{ +begin:/\{\$/,end:/\}/}]},o=e.inherit(e.APOS_STRING_MODE,{illegal:null +}),l="[ \t\n]",c={scope:"string",variants:[e.inherit(e.QUOTE_STRING_MODE,{ +illegal:null,contains:e.QUOTE_STRING_MODE.contains.concat(s)}),o,{ +begin:/<<<[ \t]*(?:(\w+)|"(\w+)")\n/,end:/[ \t]*(\w+)\b/, +contains:e.QUOTE_STRING_MODE.contains.concat(s),"on:begin":(e,n)=>{ +n.data._beginMatch=e[1]||e[2]},"on:end":(e,n)=>{ +n.data._beginMatch!==e[1]&&n.ignoreMatch()}},e.END_SAME_AS_BEGIN({ +begin:/<<<[ \t]*'(\w+)'\n/,end:/[ \t]*(\w+)\b/})]},d={scope:"number",variants:[{ +begin:"\\b0[bB][01]+(?:_[01]+)*\\b"},{begin:"\\b0[oO][0-7]+(?:_[0-7]+)*\\b"},{ +begin:"\\b0[xX][\\da-fA-F]+(?:_[\\da-fA-F]+)*\\b"},{ +begin:"(?:\\b\\d+(?:_\\d+)*(\\.(?:\\d+(?:_\\d+)*))?|\\B\\.\\d+)(?:[eE][+-]?\\d+)?" +}],relevance:0 +},g=["false","null","true"],u=["__CLASS__","__DIR__","__FILE__","__FUNCTION__","__COMPILER_HALT_OFFSET__","__LINE__","__METHOD__","__NAMESPACE__","__TRAIT__","die","echo","exit","include","include_once","print","require","require_once","array","abstract","and","as","binary","bool","boolean","break","callable","case","catch","class","clone","const","continue","declare","default","do","double","else","elseif","empty","enddeclare","endfor","endforeach","endif","endswitch","endwhile","enum","eval","extends","final","finally","float","for","foreach","from","global","goto","if","implements","instanceof","insteadof","int","integer","interface","isset","iterable","list","match|0","mixed","new","never","object","or","private","protected","public","readonly","real","return","string","switch","throw","trait","try","unset","use","var","void","while","xor","yield"],b=["Error|0","AppendIterator","ArgumentCountError","ArithmeticError","ArrayIterator","ArrayObject","AssertionError","BadFunctionCallException","BadMethodCallException","CachingIterator","CallbackFilterIterator","CompileError","Countable","DirectoryIterator","DivisionByZeroError","DomainException","EmptyIterator","ErrorException","Exception","FilesystemIterator","FilterIterator","GlobIterator","InfiniteIterator","InvalidArgumentException","IteratorIterator","LengthException","LimitIterator","LogicException","MultipleIterator","NoRewindIterator","OutOfBoundsException","OutOfRangeException","OuterIterator","OverflowException","ParentIterator","ParseError","RangeException","RecursiveArrayIterator","RecursiveCachingIterator","RecursiveCallbackFilterIterator","RecursiveDirectoryIterator","RecursiveFilterIterator","RecursiveIterator","RecursiveIteratorIterator","RecursiveRegexIterator","RecursiveTreeIterator","RegexIterator","RuntimeException","SeekableIterator","SplDoublyLinkedList","SplFileInfo","SplFileObject","SplFixedArray","SplHeap","SplMaxHeap","SplMinHeap","SplObjectStorage","SplObserver","SplPriorityQueue","SplQueue","SplStack","SplSubject","SplTempFileObject","TypeError","UnderflowException","UnexpectedValueException","UnhandledMatchError","ArrayAccess","BackedEnum","Closure","Fiber","Generator","Iterator","IteratorAggregate","Serializable","Stringable","Throwable","Traversable","UnitEnum","WeakReference","WeakMap","Directory","__PHP_Incomplete_Class","parent","php_user_filter","self","static","stdClass"],m={ +keyword:u,literal:(e=>{const n=[];return e.forEach((e=>{ +n.push(e),e.toLowerCase()===e?n.push(e.toUpperCase()):n.push(e.toLowerCase()) +})),n})(g),built_in:b},p=e=>e.map((e=>e.replace(/\|\d+$/,""))),_={variants:[{ +match:[/new/,n.concat(l,"+"),n.concat("(?!",p(b).join("\\b|"),"\\b)"),i],scope:{ +1:"keyword",4:"title.class"}}]},h=n.concat(a,"\\b(?!\\()"),f={variants:[{ +match:[n.concat(/::/,n.lookahead(/(?!class\b)/)),h],scope:{2:"variable.constant" +}},{match:[/::/,/class/],scope:{2:"variable.language"}},{ +match:[i,n.concat(/::/,n.lookahead(/(?!class\b)/)),h],scope:{1:"title.class", +3:"variable.constant"}},{match:[i,n.concat("::",n.lookahead(/(?!class\b)/))], +scope:{1:"title.class"}},{match:[i,/::/,/class/],scope:{1:"title.class", +3:"variable.language"}}]},E={scope:"attr", +match:n.concat(a,n.lookahead(":"),n.lookahead(/(?!::)/))},y={relevance:0, +begin:/\(/,end:/\)/,keywords:m,contains:[E,r,f,e.C_BLOCK_COMMENT_MODE,c,d,_] +},N={relevance:0, +match:[/\b/,n.concat("(?!fn\\b|function\\b|",p(u).join("\\b|"),"|",p(b).join("\\b|"),"\\b)"),a,n.concat(l,"*"),n.lookahead(/(?=\()/)], +scope:{3:"title.function.invoke"},contains:[y]};y.contains.push(N) +;const w=[E,f,e.C_BLOCK_COMMENT_MODE,c,d,_];return{case_insensitive:!1, +keywords:m,contains:[{begin:n.concat(/#\[\s*/,i),beginScope:"meta",end:/]/, +endScope:"meta",keywords:{literal:g,keyword:["new","array"]},contains:[{ +begin:/\[/,end:/]/,keywords:{literal:g,keyword:["new","array"]}, +contains:["self",...w]},...w,{scope:"meta",match:i}] +},e.HASH_COMMENT_MODE,e.COMMENT("//","$"),e.COMMENT("/\\*","\\*/",{contains:[{ +scope:"doctag",match:"@[A-Za-z]+"}]}),{match:/__halt_compiler\(\);/, +keywords:"__halt_compiler",starts:{scope:"comment",end:e.MATCH_NOTHING_RE, +contains:[{match:/\?>/,scope:"meta",endsParent:!0}]}},{scope:"meta",variants:[{ +begin:/<\?php/,relevance:10},{begin:/<\?=/},{begin:/<\?/,relevance:.1},{ +begin:/\?>/}]},{scope:"variable.language",match:/\$this\b/},r,N,f,{ +match:[/const/,/\s/,a],scope:{1:"keyword",3:"variable.constant"}},_,{ +scope:"function",relevance:0,beginKeywords:"fn function",end:/[;{]/, +excludeEnd:!0,illegal:"[$%\\[]",contains:[{beginKeywords:"use" +},e.UNDERSCORE_TITLE_MODE,{begin:"=>",endsParent:!0},{scope:"params", +begin:"\\(",end:"\\)",excludeBegin:!0,excludeEnd:!0,keywords:m, +contains:["self",r,f,e.C_BLOCK_COMMENT_MODE,c,d]}]},{scope:"class",variants:[{ +beginKeywords:"enum",illegal:/[($"]/},{beginKeywords:"class interface trait", +illegal:/[:($"]/}],relevance:0,end:/\{/,excludeEnd:!0,contains:[{ +beginKeywords:"extends implements"},e.UNDERSCORE_TITLE_MODE]},{ +beginKeywords:"namespace",relevance:0,end:";",illegal:/[.']/, +contains:[e.inherit(e.UNDERSCORE_TITLE_MODE,{scope:"title.class"})]},{ +beginKeywords:"use",relevance:0,end:";",contains:[{ +match:/\b(as|const|function)\b/,scope:"keyword"},e.UNDERSCORE_TITLE_MODE]},c,d]} +},grmr_php_template:e=>({name:"PHP template",subLanguage:"xml",contains:[{ +begin:/<\?(php|=)?/,end:/\?>/,subLanguage:"php",contains:[{begin:"/\\*", +end:"\\*/",skip:!0},{begin:'b"',end:'"',skip:!0},{begin:"b'",end:"'",skip:!0 +},e.inherit(e.APOS_STRING_MODE,{illegal:null,className:null,contains:null, +skip:!0}),e.inherit(e.QUOTE_STRING_MODE,{illegal:null,className:null, +contains:null,skip:!0})]}]}),grmr_plaintext:e=>({name:"Plain text", +aliases:["text","txt"],disableAutodetect:!0}),grmr_python:e=>{ +const n=e.regex,t=/[\p{XID_Start}_]\p{XID_Continue}*/u,a=["and","as","assert","async","await","break","case","class","continue","def","del","elif","else","except","finally","for","from","global","if","import","in","is","lambda","match","nonlocal|10","not","or","pass","raise","return","try","while","with","yield"],i={ +$pattern:/[A-Za-z]\w+|__\w+__/,keyword:a, +built_in:["__import__","abs","all","any","ascii","bin","bool","breakpoint","bytearray","bytes","callable","chr","classmethod","compile","complex","delattr","dict","dir","divmod","enumerate","eval","exec","filter","float","format","frozenset","getattr","globals","hasattr","hash","help","hex","id","input","int","isinstance","issubclass","iter","len","list","locals","map","max","memoryview","min","next","object","oct","open","ord","pow","print","property","range","repr","reversed","round","set","setattr","slice","sorted","staticmethod","str","sum","super","tuple","type","vars","zip"], +literal:["__debug__","Ellipsis","False","None","NotImplemented","True"], +type:["Any","Callable","Coroutine","Dict","List","Literal","Generic","Optional","Sequence","Set","Tuple","Type","Union"] +},r={className:"meta",begin:/^(>>>|\.\.\.) /},s={className:"subst",begin:/\{/, +end:/\}/,keywords:i,illegal:/#/},o={begin:/\{\{/,relevance:0},l={ +className:"string",contains:[e.BACKSLASH_ESCAPE],variants:[{ +begin:/([uU]|[bB]|[rR]|[bB][rR]|[rR][bB])?'''/,end:/'''/, +contains:[e.BACKSLASH_ESCAPE,r],relevance:10},{ +begin:/([uU]|[bB]|[rR]|[bB][rR]|[rR][bB])?"""/,end:/"""/, +contains:[e.BACKSLASH_ESCAPE,r],relevance:10},{ +begin:/([fF][rR]|[rR][fF]|[fF])'''/,end:/'''/, +contains:[e.BACKSLASH_ESCAPE,r,o,s]},{begin:/([fF][rR]|[rR][fF]|[fF])"""/, +end:/"""/,contains:[e.BACKSLASH_ESCAPE,r,o,s]},{begin:/([uU]|[rR])'/,end:/'/, +relevance:10},{begin:/([uU]|[rR])"/,end:/"/,relevance:10},{ +begin:/([bB]|[bB][rR]|[rR][bB])'/,end:/'/},{begin:/([bB]|[bB][rR]|[rR][bB])"/, +end:/"/},{begin:/([fF][rR]|[rR][fF]|[fF])'/,end:/'/, +contains:[e.BACKSLASH_ESCAPE,o,s]},{begin:/([fF][rR]|[rR][fF]|[fF])"/,end:/"/, +contains:[e.BACKSLASH_ESCAPE,o,s]},e.APOS_STRING_MODE,e.QUOTE_STRING_MODE] +},c="[0-9](_?[0-9])*",d=`(\\b(${c}))?\\.(${c})|\\b(${c})\\.`,g="\\b|"+a.join("|"),u={ +className:"number",relevance:0,variants:[{ +begin:`(\\b(${c})|(${d}))[eE][+-]?(${c})[jJ]?(?=${g})`},{begin:`(${d})[jJ]?`},{ +begin:`\\b([1-9](_?[0-9])*|0+(_?0)*)[lLjJ]?(?=${g})`},{ +begin:`\\b0[bB](_?[01])+[lL]?(?=${g})`},{begin:`\\b0[oO](_?[0-7])+[lL]?(?=${g})` +},{begin:`\\b0[xX](_?[0-9a-fA-F])+[lL]?(?=${g})`},{begin:`\\b(${c})[jJ](?=${g})` +}]},b={className:"comment",begin:n.lookahead(/# type:/),end:/$/,keywords:i, +contains:[{begin:/# type:/},{begin:/#/,end:/\b\B/,endsWithParent:!0}]},m={ +className:"params",variants:[{className:"",begin:/\(\s*\)/,skip:!0},{begin:/\(/, +end:/\)/,excludeBegin:!0,excludeEnd:!0,keywords:i, +contains:["self",r,u,l,e.HASH_COMMENT_MODE]}]};return s.contains=[l,u,r],{ +name:"Python",aliases:["py","gyp","ipython"],unicodeRegex:!0,keywords:i, +illegal:/(<\/|\?)|=>/,contains:[r,u,{begin:/\bself\b/},{beginKeywords:"if", +relevance:0},l,b,e.HASH_COMMENT_MODE,{match:[/\bdef/,/\s+/,t],scope:{ +1:"keyword",3:"title.function"},contains:[m]},{variants:[{ +match:[/\bclass/,/\s+/,t,/\s*/,/\(\s*/,t,/\s*\)/]},{match:[/\bclass/,/\s+/,t]}], +scope:{1:"keyword",3:"title.class",6:"title.class.inherited"}},{ +className:"meta",begin:/^[\t ]*@/,end:/(?=#)|$/,contains:[u,m,l]}]}}, +grmr_python_repl:e=>({aliases:["pycon"],contains:[{className:"meta.prompt", +starts:{end:/ |$/,starts:{end:"$",subLanguage:"python"}},variants:[{ +begin:/^>>>(?=[ ]|$)/},{begin:/^\.\.\.(?=[ ]|$)/}]}]}),grmr_r:e=>{ +const n=e.regex,t=/(?:(?:[a-zA-Z]|\.[._a-zA-Z])[._a-zA-Z0-9]*)|\.(?!\d)/,a=n.either(/0[xX][0-9a-fA-F]+\.[0-9a-fA-F]*[pP][+-]?\d+i?/,/0[xX][0-9a-fA-F]+(?:[pP][+-]?\d+)?[Li]?/,/(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+)?[Li]?/),i=/[=!<>:]=|\|\||&&|:::?|<-|<<-|->>|->|\|>|[-+*\/?!$&|:<=>@^~]|\*\*/,r=n.either(/[()]/,/[{}]/,/\[\[/,/[[\]]/,/\\/,/,/) +;return{name:"R",keywords:{$pattern:t, +keyword:"function if in break next repeat else for while", +literal:"NULL NA TRUE FALSE Inf NaN NA_integer_|10 NA_real_|10 NA_character_|10 NA_complex_|10", +built_in:"LETTERS letters month.abb month.name pi T F abs acos acosh all any anyNA Arg as.call as.character as.complex as.double as.environment as.integer as.logical as.null.default as.numeric as.raw asin asinh atan atanh attr attributes baseenv browser c call ceiling class Conj cos cosh cospi cummax cummin cumprod cumsum digamma dim dimnames emptyenv exp expression floor forceAndCall gamma gc.time globalenv Im interactive invisible is.array is.atomic is.call is.character is.complex is.double is.environment is.expression is.finite is.function is.infinite is.integer is.language is.list is.logical is.matrix is.na is.name is.nan is.null is.numeric is.object is.pairlist is.raw is.recursive is.single is.symbol lazyLoadDBfetch length lgamma list log max min missing Mod names nargs nzchar oldClass on.exit pos.to.env proc.time prod quote range Re rep retracemem return round seq_along seq_len seq.int sign signif sin sinh sinpi sqrt standardGeneric substitute sum switch tan tanh tanpi tracemem trigamma trunc unclass untracemem UseMethod xtfrm" +},contains:[e.COMMENT(/#'/,/$/,{contains:[{scope:"doctag",match:/@examples/, +starts:{end:n.lookahead(n.either(/\n^#'\s*(?=@[a-zA-Z]+)/,/\n^(?!#')/)), +endsParent:!0}},{scope:"doctag",begin:"@param",end:/$/,contains:[{ +scope:"variable",variants:[{match:t},{match:/`(?:\\.|[^`\\])+`/}],endsParent:!0 +}]},{scope:"doctag",match:/@[a-zA-Z]+/},{scope:"keyword",match:/\\[a-zA-Z]+/}] +}),e.HASH_COMMENT_MODE,{scope:"string",contains:[e.BACKSLASH_ESCAPE], +variants:[e.END_SAME_AS_BEGIN({begin:/[rR]"(-*)\(/,end:/\)(-*)"/ +}),e.END_SAME_AS_BEGIN({begin:/[rR]"(-*)\{/,end:/\}(-*)"/ +}),e.END_SAME_AS_BEGIN({begin:/[rR]"(-*)\[/,end:/\](-*)"/ +}),e.END_SAME_AS_BEGIN({begin:/[rR]'(-*)\(/,end:/\)(-*)'/ +}),e.END_SAME_AS_BEGIN({begin:/[rR]'(-*)\{/,end:/\}(-*)'/ +}),e.END_SAME_AS_BEGIN({begin:/[rR]'(-*)\[/,end:/\](-*)'/}),{begin:'"',end:'"', +relevance:0},{begin:"'",end:"'",relevance:0}]},{relevance:0,variants:[{scope:{ +1:"operator",2:"number"},match:[i,a]},{scope:{1:"operator",2:"number"}, +match:[/%[^%]*%/,a]},{scope:{1:"punctuation",2:"number"},match:[r,a]},{scope:{ +2:"number"},match:[/[^a-zA-Z0-9._]|^/,a]}]},{scope:{3:"operator"}, +match:[t,/\s+/,/<-/,/\s+/]},{scope:"operator",relevance:0,variants:[{match:i},{ +match:/%[^%]*%/}]},{scope:"punctuation",relevance:0,match:r},{begin:"`",end:"`", +contains:[{begin:/\\./}]}]}},grmr_ruby:e=>{ +const n=e.regex,t="([a-zA-Z_]\\w*[!?=]?|[-+~]@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?)",a=n.either(/\b([A-Z]+[a-z0-9]+)+/,/\b([A-Z]+[a-z0-9]+)+[A-Z]+/),i=n.concat(a,/(::\w+)*/),r={ +"variable.constant":["__FILE__","__LINE__","__ENCODING__"], +"variable.language":["self","super"], +keyword:["alias","and","begin","BEGIN","break","case","class","defined","do","else","elsif","end","END","ensure","for","if","in","module","next","not","or","redo","require","rescue","retry","return","then","undef","unless","until","when","while","yield","include","extend","prepend","public","private","protected","raise","throw"], +built_in:["proc","lambda","attr_accessor","attr_reader","attr_writer","define_method","private_constant","module_function"], +literal:["true","false","nil"]},s={className:"doctag",begin:"@[A-Za-z]+"},o={ +begin:"#<",end:">"},l=[e.COMMENT("#","$",{contains:[s] +}),e.COMMENT("^=begin","^=end",{contains:[s],relevance:10 +}),e.COMMENT("^__END__",e.MATCH_NOTHING_RE)],c={className:"subst",begin:/#\{/, +end:/\}/,keywords:r},d={className:"string",contains:[e.BACKSLASH_ESCAPE,c], +variants:[{begin:/'/,end:/'/},{begin:/"/,end:/"/},{begin:/`/,end:/`/},{ +begin:/%[qQwWx]?\(/,end:/\)/},{begin:/%[qQwWx]?\[/,end:/\]/},{ +begin:/%[qQwWx]?\{/,end:/\}/},{begin:/%[qQwWx]?</,end:/>/},{begin:/%[qQwWx]?\//, +end:/\//},{begin:/%[qQwWx]?%/,end:/%/},{begin:/%[qQwWx]?-/,end:/-/},{ +begin:/%[qQwWx]?\|/,end:/\|/},{begin:/\B\?(\\\d{1,3})/},{ +begin:/\B\?(\\x[A-Fa-f0-9]{1,2})/},{begin:/\B\?(\\u\{?[A-Fa-f0-9]{1,6}\}?)/},{ +begin:/\B\?(\\M-\\C-|\\M-\\c|\\c\\M-|\\M-|\\C-\\M-)[\x20-\x7e]/},{ +begin:/\B\?\\(c|C-)[\x20-\x7e]/},{begin:/\B\?\\?\S/},{ +begin:n.concat(/<<[-~]?'?/,n.lookahead(/(\w+)(?=\W)[^\n]*\n(?:[^\n]*\n)*?\s*\1\b/)), +contains:[e.END_SAME_AS_BEGIN({begin:/(\w+)/,end:/(\w+)/, +contains:[e.BACKSLASH_ESCAPE,c]})]}]},g="[0-9](_?[0-9])*",u={className:"number", +relevance:0,variants:[{ +begin:`\\b([1-9](_?[0-9])*|0)(\\.(${g}))?([eE][+-]?(${g})|r)?i?\\b`},{ +begin:"\\b0[dD][0-9](_?[0-9])*r?i?\\b"},{begin:"\\b0[bB][0-1](_?[0-1])*r?i?\\b" +},{begin:"\\b0[oO][0-7](_?[0-7])*r?i?\\b"},{ +begin:"\\b0[xX][0-9a-fA-F](_?[0-9a-fA-F])*r?i?\\b"},{ +begin:"\\b0(_?[0-7])+r?i?\\b"}]},b={variants:[{match:/\(\)/},{ +className:"params",begin:/\(/,end:/(?=\))/,excludeBegin:!0,endsParent:!0, +keywords:r}]},m=[d,{variants:[{match:[/class\s+/,i,/\s+<\s+/,i]},{ +match:[/\b(class|module)\s+/,i]}],scope:{2:"title.class", +4:"title.class.inherited"},keywords:r},{match:[/(include|extend)\s+/,i],scope:{ +2:"title.class"},keywords:r},{relevance:0,match:[i,/\.new[. (]/],scope:{ +1:"title.class"}},{relevance:0,match:/\b[A-Z][A-Z_0-9]+\b/, +className:"variable.constant"},{relevance:0,match:a,scope:"title.class"},{ +match:[/def/,/\s+/,t],scope:{1:"keyword",3:"title.function"},contains:[b]},{ +begin:e.IDENT_RE+"::"},{className:"symbol", +begin:e.UNDERSCORE_IDENT_RE+"(!|\\?)?:",relevance:0},{className:"symbol", +begin:":(?!\\s)",contains:[d,{begin:t}],relevance:0},u,{className:"variable", +begin:"(\\$\\W)|((\\$|@@?)(\\w+))(?=[^@$?])(?![A-Za-z])(?![@$?'])"},{ +className:"params",begin:/\|/,end:/\|/,excludeBegin:!0,excludeEnd:!0, +relevance:0,keywords:r},{begin:"("+e.RE_STARTERS_RE+"|unless)\\s*", +keywords:"unless",contains:[{className:"regexp",contains:[e.BACKSLASH_ESCAPE,c], +illegal:/\n/,variants:[{begin:"/",end:"/[a-z]*"},{begin:/%r\{/,end:/\}[a-z]*/},{ +begin:"%r\\(",end:"\\)[a-z]*"},{begin:"%r!",end:"![a-z]*"},{begin:"%r\\[", +end:"\\][a-z]*"}]}].concat(o,l),relevance:0}].concat(o,l) +;c.contains=m,b.contains=m;const p=[{begin:/^\s*=>/,starts:{end:"$",contains:m} +},{className:"meta.prompt", +begin:"^([>?]>|[\\w#]+\\(\\w+\\):\\d+:\\d+[>*]|(\\w+-)?\\d+\\.\\d+\\.\\d+(p\\d+)?[^\\d][^>]+>)(?=[ ])", +starts:{end:"$",keywords:r,contains:m}}];return l.unshift(o),{name:"Ruby", +aliases:["rb","gemspec","podspec","thor","irb"],keywords:r,illegal:/\/\*/, +contains:[e.SHEBANG({binary:"ruby"})].concat(p).concat(l).concat(m)}}, +grmr_rust:e=>{const n=e.regex,t={className:"title.function.invoke",relevance:0, +begin:n.concat(/\b/,/(?!let|for|while|if|else|match\b)/,e.IDENT_RE,n.lookahead(/\s*\(/)) +},a="([ui](8|16|32|64|128|size)|f(32|64))?",i=["drop ","Copy","Send","Sized","Sync","Drop","Fn","FnMut","FnOnce","ToOwned","Clone","Debug","PartialEq","PartialOrd","Eq","Ord","AsRef","AsMut","Into","From","Default","Iterator","Extend","IntoIterator","DoubleEndedIterator","ExactSizeIterator","SliceConcatExt","ToString","assert!","assert_eq!","bitflags!","bytes!","cfg!","col!","concat!","concat_idents!","debug_assert!","debug_assert_eq!","env!","eprintln!","panic!","file!","format!","format_args!","include_bytes!","include_str!","line!","local_data_key!","module_path!","option_env!","print!","println!","select!","stringify!","try!","unimplemented!","unreachable!","vec!","write!","writeln!","macro_rules!","assert_ne!","debug_assert_ne!"],r=["i8","i16","i32","i64","i128","isize","u8","u16","u32","u64","u128","usize","f32","f64","str","char","bool","Box","Option","Result","String","Vec"] +;return{name:"Rust",aliases:["rs"],keywords:{$pattern:e.IDENT_RE+"!?",type:r, +keyword:["abstract","as","async","await","become","box","break","const","continue","crate","do","dyn","else","enum","extern","false","final","fn","for","if","impl","in","let","loop","macro","match","mod","move","mut","override","priv","pub","ref","return","self","Self","static","struct","super","trait","true","try","type","typeof","unsafe","unsized","use","virtual","where","while","yield"], +literal:["true","false","Some","None","Ok","Err"],built_in:i},illegal:"</", +contains:[e.C_LINE_COMMENT_MODE,e.COMMENT("/\\*","\\*/",{contains:["self"] +}),e.inherit(e.QUOTE_STRING_MODE,{begin:/b?"/,illegal:null}),{ +className:"string",variants:[{begin:/b?r(#*)"(.|\n)*?"\1(?!#)/},{ +begin:/b?'\\?(x\w{2}|u\w{4}|U\w{8}|.)'/}]},{className:"symbol", +begin:/'[a-zA-Z_][a-zA-Z0-9_]*/},{className:"number",variants:[{ +begin:"\\b0b([01_]+)"+a},{begin:"\\b0o([0-7_]+)"+a},{ +begin:"\\b0x([A-Fa-f0-9_]+)"+a},{ +begin:"\\b(\\d[\\d_]*(\\.[0-9_]+)?([eE][+-]?[0-9_]+)?)"+a}],relevance:0},{ +begin:[/fn/,/\s+/,e.UNDERSCORE_IDENT_RE],className:{1:"keyword", +3:"title.function"}},{className:"meta",begin:"#!?\\[",end:"\\]",contains:[{ +className:"string",begin:/"/,end:/"/}]},{ +begin:[/let/,/\s+/,/(?:mut\s+)?/,e.UNDERSCORE_IDENT_RE],className:{1:"keyword", +3:"keyword",4:"variable"}},{ +begin:[/for/,/\s+/,e.UNDERSCORE_IDENT_RE,/\s+/,/in/],className:{1:"keyword", +3:"variable",5:"keyword"}},{begin:[/type/,/\s+/,e.UNDERSCORE_IDENT_RE], +className:{1:"keyword",3:"title.class"}},{ +begin:[/(?:trait|enum|struct|union|impl|for)/,/\s+/,e.UNDERSCORE_IDENT_RE], +className:{1:"keyword",3:"title.class"}},{begin:e.IDENT_RE+"::",keywords:{ +keyword:"Self",built_in:i,type:r}},{className:"punctuation",begin:"->"},t]}}, +grmr_scss:e=>{const n=ie(e),t=le,a=oe,i="@[a-z-]+",r={className:"variable", +begin:"(\\$[a-zA-Z-][a-zA-Z0-9_-]*)\\b",relevance:0};return{name:"SCSS", +case_insensitive:!0,illegal:"[=/|']", +contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,n.CSS_NUMBER_MODE,{ +className:"selector-id",begin:"#[A-Za-z0-9_-]+",relevance:0},{ +className:"selector-class",begin:"\\.[A-Za-z0-9_-]+",relevance:0 +},n.ATTRIBUTE_SELECTOR_MODE,{className:"selector-tag", +begin:"\\b("+re.join("|")+")\\b",relevance:0},{className:"selector-pseudo", +begin:":("+a.join("|")+")"},{className:"selector-pseudo", +begin:":(:)?("+t.join("|")+")"},r,{begin:/\(/,end:/\)/, +contains:[n.CSS_NUMBER_MODE]},n.CSS_VARIABLE,{className:"attribute", +begin:"\\b("+ce.join("|")+")\\b"},{ +begin:"\\b(whitespace|wait|w-resize|visible|vertical-text|vertical-ideographic|uppercase|upper-roman|upper-alpha|underline|transparent|top|thin|thick|text|text-top|text-bottom|tb-rl|table-header-group|table-footer-group|sw-resize|super|strict|static|square|solid|small-caps|separate|se-resize|scroll|s-resize|rtl|row-resize|ridge|right|repeat|repeat-y|repeat-x|relative|progress|pointer|overline|outside|outset|oblique|nowrap|not-allowed|normal|none|nw-resize|no-repeat|no-drop|newspaper|ne-resize|n-resize|move|middle|medium|ltr|lr-tb|lowercase|lower-roman|lower-alpha|loose|list-item|line|line-through|line-edge|lighter|left|keep-all|justify|italic|inter-word|inter-ideograph|inside|inset|inline|inline-block|inherit|inactive|ideograph-space|ideograph-parenthesis|ideograph-numeric|ideograph-alpha|horizontal|hidden|help|hand|groove|fixed|ellipsis|e-resize|double|dotted|distribute|distribute-space|distribute-letter|distribute-all-lines|disc|disabled|default|decimal|dashed|crosshair|collapse|col-resize|circle|char|center|capitalize|break-word|break-all|bottom|both|bolder|bold|block|bidi-override|below|baseline|auto|always|all-scroll|absolute|table|table-cell)\\b" +},{begin:/:/,end:/[;}{]/,relevance:0, +contains:[n.BLOCK_COMMENT,r,n.HEXCOLOR,n.CSS_NUMBER_MODE,e.QUOTE_STRING_MODE,e.APOS_STRING_MODE,n.IMPORTANT,n.FUNCTION_DISPATCH] +},{begin:"@(page|font-face)",keywords:{$pattern:i,keyword:"@page @font-face"}},{ +begin:"@",end:"[{;]",returnBegin:!0,keywords:{$pattern:/[a-z-]+/, +keyword:"and or not only",attribute:se.join(" ")},contains:[{begin:i, +className:"keyword"},{begin:/[a-z-]+(?=:)/,className:"attribute" +},r,e.QUOTE_STRING_MODE,e.APOS_STRING_MODE,n.HEXCOLOR,n.CSS_NUMBER_MODE] +},n.FUNCTION_DISPATCH]}},grmr_shell:e=>({name:"Shell Session", +aliases:["console","shellsession"],contains:[{className:"meta.prompt", +begin:/^\s{0,3}[/~\w\d[\]()@-]*[>%$#][ ]?/,starts:{end:/[^\\](?=\s*$)/, +subLanguage:"bash"}}]}),grmr_sql:e=>{ +const n=e.regex,t=e.COMMENT("--","$"),a=["true","false","unknown"],i=["bigint","binary","blob","boolean","char","character","clob","date","dec","decfloat","decimal","float","int","integer","interval","nchar","nclob","national","numeric","real","row","smallint","time","timestamp","varchar","varying","varbinary"],r=["abs","acos","array_agg","asin","atan","avg","cast","ceil","ceiling","coalesce","corr","cos","cosh","count","covar_pop","covar_samp","cume_dist","dense_rank","deref","element","exp","extract","first_value","floor","json_array","json_arrayagg","json_exists","json_object","json_objectagg","json_query","json_table","json_table_primitive","json_value","lag","last_value","lead","listagg","ln","log","log10","lower","max","min","mod","nth_value","ntile","nullif","percent_rank","percentile_cont","percentile_disc","position","position_regex","power","rank","regr_avgx","regr_avgy","regr_count","regr_intercept","regr_r2","regr_slope","regr_sxx","regr_sxy","regr_syy","row_number","sin","sinh","sqrt","stddev_pop","stddev_samp","substring","substring_regex","sum","tan","tanh","translate","translate_regex","treat","trim","trim_array","unnest","upper","value_of","var_pop","var_samp","width_bucket"],s=["create table","insert into","primary key","foreign key","not null","alter table","add constraint","grouping sets","on overflow","character set","respect nulls","ignore nulls","nulls first","nulls last","depth first","breadth first"],o=r,l=["abs","acos","all","allocate","alter","and","any","are","array","array_agg","array_max_cardinality","as","asensitive","asin","asymmetric","at","atan","atomic","authorization","avg","begin","begin_frame","begin_partition","between","bigint","binary","blob","boolean","both","by","call","called","cardinality","cascaded","case","cast","ceil","ceiling","char","char_length","character","character_length","check","classifier","clob","close","coalesce","collate","collect","column","commit","condition","connect","constraint","contains","convert","copy","corr","corresponding","cos","cosh","count","covar_pop","covar_samp","create","cross","cube","cume_dist","current","current_catalog","current_date","current_default_transform_group","current_path","current_role","current_row","current_schema","current_time","current_timestamp","current_path","current_role","current_transform_group_for_type","current_user","cursor","cycle","date","day","deallocate","dec","decimal","decfloat","declare","default","define","delete","dense_rank","deref","describe","deterministic","disconnect","distinct","double","drop","dynamic","each","element","else","empty","end","end_frame","end_partition","end-exec","equals","escape","every","except","exec","execute","exists","exp","external","extract","false","fetch","filter","first_value","float","floor","for","foreign","frame_row","free","from","full","function","fusion","get","global","grant","group","grouping","groups","having","hold","hour","identity","in","indicator","initial","inner","inout","insensitive","insert","int","integer","intersect","intersection","interval","into","is","join","json_array","json_arrayagg","json_exists","json_object","json_objectagg","json_query","json_table","json_table_primitive","json_value","lag","language","large","last_value","lateral","lead","leading","left","like","like_regex","listagg","ln","local","localtime","localtimestamp","log","log10","lower","match","match_number","match_recognize","matches","max","member","merge","method","min","minute","mod","modifies","module","month","multiset","national","natural","nchar","nclob","new","no","none","normalize","not","nth_value","ntile","null","nullif","numeric","octet_length","occurrences_regex","of","offset","old","omit","on","one","only","open","or","order","out","outer","over","overlaps","overlay","parameter","partition","pattern","per","percent","percent_rank","percentile_cont","percentile_disc","period","portion","position","position_regex","power","precedes","precision","prepare","primary","procedure","ptf","range","rank","reads","real","recursive","ref","references","referencing","regr_avgx","regr_avgy","regr_count","regr_intercept","regr_r2","regr_slope","regr_sxx","regr_sxy","regr_syy","release","result","return","returns","revoke","right","rollback","rollup","row","row_number","rows","running","savepoint","scope","scroll","search","second","seek","select","sensitive","session_user","set","show","similar","sin","sinh","skip","smallint","some","specific","specifictype","sql","sqlexception","sqlstate","sqlwarning","sqrt","start","static","stddev_pop","stddev_samp","submultiset","subset","substring","substring_regex","succeeds","sum","symmetric","system","system_time","system_user","table","tablesample","tan","tanh","then","time","timestamp","timezone_hour","timezone_minute","to","trailing","translate","translate_regex","translation","treat","trigger","trim","trim_array","true","truncate","uescape","union","unique","unknown","unnest","update","upper","user","using","value","values","value_of","var_pop","var_samp","varbinary","varchar","varying","versioning","when","whenever","where","width_bucket","window","with","within","without","year","add","asc","collation","desc","final","first","last","view"].filter((e=>!r.includes(e))),c={ +begin:n.concat(/\b/,n.either(...o),/\s*\(/),relevance:0,keywords:{built_in:o}} +;return{name:"SQL",case_insensitive:!0,illegal:/[{}]|<\//,keywords:{ +$pattern:/\b[\w\.]+/,keyword:((e,{exceptions:n,when:t}={})=>{const a=t +;return n=n||[],e.map((e=>e.match(/\|\d+$/)||n.includes(e)?e:a(e)?e+"|0":e)) +})(l,{when:e=>e.length<3}),literal:a,type:i, +built_in:["current_catalog","current_date","current_default_transform_group","current_path","current_role","current_schema","current_transform_group_for_type","current_user","session_user","system_time","system_user","current_time","localtime","current_timestamp","localtimestamp"] +},contains:[{begin:n.either(...s),relevance:0,keywords:{$pattern:/[\w\.]+/, +keyword:l.concat(s),literal:a,type:i}},{className:"type", +begin:n.either("double precision","large object","with timezone","without timezone") +},c,{className:"variable",begin:/@[a-z0-9][a-z0-9_]*/},{className:"string", +variants:[{begin:/'/,end:/'/,contains:[{begin:/''/}]}]},{begin:/"/,end:/"/, +contains:[{begin:/""/}]},e.C_NUMBER_MODE,e.C_BLOCK_COMMENT_MODE,t,{ +className:"operator",begin:/[-+*/=%^~]|&&?|\|\|?|!=?|<(?:=>?|<|>)?|>[>=]?/, +relevance:0}]}},grmr_swift:e=>{const n={match:/\s+/,relevance:0 +},t=e.COMMENT("/\\*","\\*/",{contains:["self"]}),a=[e.C_LINE_COMMENT_MODE,t],i={ +match:[/\./,m(...xe,...Me)],className:{2:"keyword"}},r={match:b(/\./,m(...Ae)), +relevance:0},s=Ae.filter((e=>"string"==typeof e)).concat(["_|0"]),o={variants:[{ +className:"keyword", +match:m(...Ae.filter((e=>"string"!=typeof e)).concat(Se).map(ke),...Me)}]},l={ +$pattern:m(/\b\w+/,/#\w+/),keyword:s.concat(Re),literal:Ce},c=[i,r,o],g=[{ +match:b(/\./,m(...De)),relevance:0},{className:"built_in", +match:b(/\b/,m(...De),/(?=\()/)}],u={match:/->/,relevance:0},p=[u,{ +className:"operator",relevance:0,variants:[{match:Be},{match:`\\.(\\.|${Le})+`}] +}],_="([0-9]_*)+",h="([0-9a-fA-F]_*)+",f={className:"number",relevance:0, +variants:[{match:`\\b(${_})(\\.(${_}))?([eE][+-]?(${_}))?\\b`},{ +match:`\\b0x(${h})(\\.(${h}))?([pP][+-]?(${_}))?\\b`},{match:/\b0o([0-7]_*)+\b/ +},{match:/\b0b([01]_*)+\b/}]},E=(e="")=>({className:"subst",variants:[{ +match:b(/\\/,e,/[0\\tnr"']/)},{match:b(/\\/,e,/u\{[0-9a-fA-F]{1,8}\}/)}] +}),y=(e="")=>({className:"subst",match:b(/\\/,e,/[\t ]*(?:[\r\n]|\r\n)/) +}),N=(e="")=>({className:"subst",label:"interpol",begin:b(/\\/,e,/\(/),end:/\)/ +}),w=(e="")=>({begin:b(e,/"""/),end:b(/"""/,e),contains:[E(e),y(e),N(e)] +}),v=(e="")=>({begin:b(e,/"/),end:b(/"/,e),contains:[E(e),N(e)]}),O={ +className:"string", +variants:[w(),w("#"),w("##"),w("###"),v(),v("#"),v("##"),v("###")] +},k=[e.BACKSLASH_ESCAPE,{begin:/\[/,end:/\]/,relevance:0, +contains:[e.BACKSLASH_ESCAPE]}],x={begin:/\/[^\s](?=[^/\n]*\/)/,end:/\//, +contains:k},M=e=>{const n=b(e,/\//),t=b(/\//,e);return{begin:n,end:t, +contains:[...k,{scope:"comment",begin:`#(?!.*${t})`,end:/$/}]}},S={ +scope:"regexp",variants:[M("###"),M("##"),M("#"),x]},A={match:b(/`/,Fe,/`/) +},C=[A,{className:"variable",match:/\$\d+/},{className:"variable", +match:`\\$${ze}+`}],T=[{match:/(@|#(un)?)available/,scope:"keyword",starts:{ +contains:[{begin:/\(/,end:/\)/,keywords:Pe,contains:[...p,f,O]}]}},{ +scope:"keyword",match:b(/@/,m(...je))},{scope:"meta",match:b(/@/,Fe)}],R={ +match:d(/\b[A-Z]/),relevance:0,contains:[{className:"type", +match:b(/(AV|CA|CF|CG|CI|CL|CM|CN|CT|MK|MP|MTK|MTL|NS|SCN|SK|UI|WK|XC)/,ze,"+") +},{className:"type",match:Ue,relevance:0},{match:/[?!]+/,relevance:0},{ +match:/\.\.\./,relevance:0},{match:b(/\s+&\s+/,d(Ue)),relevance:0}]},D={ +begin:/</,end:/>/,keywords:l,contains:[...a,...c,...T,u,R]};R.contains.push(D) +;const I={begin:/\(/,end:/\)/,relevance:0,keywords:l,contains:["self",{ +match:b(Fe,/\s*:/),keywords:"_|0",relevance:0 +},...a,S,...c,...g,...p,f,O,...C,...T,R]},L={begin:/</,end:/>/, +keywords:"repeat each",contains:[...a,R]},B={begin:/\(/,end:/\)/,keywords:l, +contains:[{begin:m(d(b(Fe,/\s*:/)),d(b(Fe,/\s+/,Fe,/\s*:/))),end:/:/, +relevance:0,contains:[{className:"keyword",match:/\b_\b/},{className:"params", +match:Fe}]},...a,...c,...p,f,O,...T,R,I],endsParent:!0,illegal:/["']/},$={ +match:[/(func|macro)/,/\s+/,m(A.match,Fe,Be)],className:{1:"keyword", +3:"title.function"},contains:[L,B,n],illegal:[/\[/,/%/]},z={ +match:[/\b(?:subscript|init[?!]?)/,/\s*(?=[<(])/],className:{1:"keyword"}, +contains:[L,B,n],illegal:/\[|%/},F={match:[/operator/,/\s+/,Be],className:{ +1:"keyword",3:"title"}},U={begin:[/precedencegroup/,/\s+/,Ue],className:{ +1:"keyword",3:"title"},contains:[R],keywords:[...Te,...Ce],end:/}/} +;for(const e of O.variants){const n=e.contains.find((e=>"interpol"===e.label)) +;n.keywords=l;const t=[...c,...g,...p,f,O,...C];n.contains=[...t,{begin:/\(/, +end:/\)/,contains:["self",...t]}]}return{name:"Swift",keywords:l, +contains:[...a,$,z,{beginKeywords:"struct protocol class extension enum actor", +end:"\\{",excludeEnd:!0,keywords:l,contains:[e.inherit(e.TITLE_MODE,{ +className:"title.class",begin:/[A-Za-z$_][\u00C0-\u02B80-9A-Za-z$_]*/}),...c] +},F,U,{beginKeywords:"import",end:/$/,contains:[...a],relevance:0 +},S,...c,...g,...p,f,O,...C,...T,R,I]}},grmr_typescript:e=>{ +const n=Oe(e),t=_e,a=["any","void","number","boolean","string","object","never","symbol","bigint","unknown"],i={ +beginKeywords:"namespace",end:/\{/,excludeEnd:!0, +contains:[n.exports.CLASS_REFERENCE]},r={beginKeywords:"interface",end:/\{/, +excludeEnd:!0,keywords:{keyword:"interface extends",built_in:a}, +contains:[n.exports.CLASS_REFERENCE]},s={$pattern:_e, +keyword:he.concat(["type","namespace","interface","public","private","protected","implements","declare","abstract","readonly","enum","override"]), +literal:fe,built_in:ve.concat(a),"variable.language":we},o={className:"meta", +begin:"@"+t},l=(e,n,t)=>{const a=e.contains.findIndex((e=>e.label===n)) +;if(-1===a)throw Error("can not find mode to replace");e.contains.splice(a,1,t)} +;return Object.assign(n.keywords,s), +n.exports.PARAMS_CONTAINS.push(o),n.contains=n.contains.concat([o,i,r]), +l(n,"shebang",e.SHEBANG()),l(n,"use_strict",{className:"meta",relevance:10, +begin:/^\s*['"]use strict['"]/ +}),n.contains.find((e=>"func.def"===e.label)).relevance=0,Object.assign(n,{ +name:"TypeScript",aliases:["ts","tsx","mts","cts"]}),n},grmr_vbnet:e=>{ +const n=e.regex,t=/\d{1,2}\/\d{1,2}\/\d{4}/,a=/\d{4}-\d{1,2}-\d{1,2}/,i=/(\d|1[012])(:\d+){0,2} *(AM|PM)/,r=/\d{1,2}(:\d{1,2}){1,2}/,s={ +className:"literal",variants:[{begin:n.concat(/# */,n.either(a,t),/ *#/)},{ +begin:n.concat(/# */,r,/ *#/)},{begin:n.concat(/# */,i,/ *#/)},{ +begin:n.concat(/# */,n.either(a,t),/ +/,n.either(i,r),/ *#/)}] +},o=e.COMMENT(/'''/,/$/,{contains:[{className:"doctag",begin:/<\/?/,end:/>/}] +}),l=e.COMMENT(null,/$/,{variants:[{begin:/'/},{begin:/([\t ]|^)REM(?=\s)/}]}) +;return{name:"Visual Basic .NET",aliases:["vb"],case_insensitive:!0, +classNameAliases:{label:"symbol"},keywords:{ +keyword:"addhandler alias aggregate ansi as async assembly auto binary by byref byval call case catch class compare const continue custom declare default delegate dim distinct do each equals else elseif end enum erase error event exit explicit finally for friend from function get global goto group handles if implements imports in inherits interface into iterator join key let lib loop me mid module mustinherit mustoverride mybase myclass namespace narrowing new next notinheritable notoverridable of off on operator option optional order overloads overridable overrides paramarray partial preserve private property protected public raiseevent readonly redim removehandler resume return select set shadows shared skip static step stop structure strict sub synclock take text then throw to try unicode until using when where while widening with withevents writeonly yield", +built_in:"addressof and andalso await directcast gettype getxmlnamespace is isfalse isnot istrue like mod nameof new not or orelse trycast typeof xor cbool cbyte cchar cdate cdbl cdec cint clng cobj csbyte cshort csng cstr cuint culng cushort", +type:"boolean byte char date decimal double integer long object sbyte short single string uinteger ulong ushort", +literal:"true false nothing"}, +illegal:"//|\\{|\\}|endif|gosub|variant|wend|^\\$ ",contains:[{ +className:"string",begin:/"(""|[^/n])"C\b/},{className:"string",begin:/"/, +end:/"/,illegal:/\n/,contains:[{begin:/""/}]},s,{className:"number",relevance:0, +variants:[{begin:/\b\d[\d_]*((\.[\d_]+(E[+-]?[\d_]+)?)|(E[+-]?[\d_]+))[RFD@!#]?/ +},{begin:/\b\d[\d_]*((U?[SIL])|[%&])?/},{begin:/&H[\dA-F_]+((U?[SIL])|[%&])?/},{ +begin:/&O[0-7_]+((U?[SIL])|[%&])?/},{begin:/&B[01_]+((U?[SIL])|[%&])?/}]},{ +className:"label",begin:/^\w+:/},o,l,{className:"meta", +begin:/[\t ]*#(const|disable|else|elseif|enable|end|externalsource|if|region)\b/, +end:/$/,keywords:{ +keyword:"const disable else elseif enable end externalsource if region then"}, +contains:[l]}]}},grmr_wasm:e=>{e.regex;const n=e.COMMENT(/\(;/,/;\)/) +;return n.contains.push("self"),{name:"WebAssembly",keywords:{$pattern:/[\w.]+/, +keyword:["anyfunc","block","br","br_if","br_table","call","call_indirect","data","drop","elem","else","end","export","func","global.get","global.set","local.get","local.set","local.tee","get_global","get_local","global","if","import","local","loop","memory","memory.grow","memory.size","module","mut","nop","offset","param","result","return","select","set_global","set_local","start","table","tee_local","then","type","unreachable"] +},contains:[e.COMMENT(/;;/,/$/),n,{match:[/(?:offset|align)/,/\s*/,/=/], +className:{1:"keyword",3:"operator"}},{className:"variable",begin:/\$[\w_]+/},{ +match:/(\((?!;)|\))+/,className:"punctuation",relevance:0},{ +begin:[/(?:func|call|call_indirect)/,/\s+/,/\$[^\s)]+/],className:{1:"keyword", +3:"title.function"}},e.QUOTE_STRING_MODE,{match:/(i32|i64|f32|f64)(?!\.)/, +className:"type"},{className:"keyword", +match:/\b(f32|f64|i32|i64)(?:\.(?:abs|add|and|ceil|clz|const|convert_[su]\/i(?:32|64)|copysign|ctz|demote\/f64|div(?:_[su])?|eqz?|extend_[su]\/i32|floor|ge(?:_[su])?|gt(?:_[su])?|le(?:_[su])?|load(?:(?:8|16|32)_[su])?|lt(?:_[su])?|max|min|mul|nearest|neg?|or|popcnt|promote\/f32|reinterpret\/[fi](?:32|64)|rem_[su]|rot[lr]|shl|shr_[su]|store(?:8|16|32)?|sqrt|sub|trunc(?:_[su]\/f(?:32|64))?|wrap\/i64|xor))\b/ +},{className:"number",relevance:0, +match:/[+-]?\b(?:\d(?:_?\d)*(?:\.\d(?:_?\d)*)?(?:[eE][+-]?\d(?:_?\d)*)?|0x[\da-fA-F](?:_?[\da-fA-F])*(?:\.[\da-fA-F](?:_?[\da-fA-D])*)?(?:[pP][+-]?\d(?:_?\d)*)?)\b|\binf\b|\bnan(?::0x[\da-fA-F](?:_?[\da-fA-D])*)?\b/ +}]}},grmr_xml:e=>{ +const n=e.regex,t=n.concat(/[\p{L}_]/u,n.optional(/[\p{L}0-9_.-]*:/u),/[\p{L}0-9_.-]*/u),a={ +className:"symbol",begin:/&[a-z]+;|&#[0-9]+;|&#x[a-f0-9]+;/},i={begin:/\s/, +contains:[{className:"keyword",begin:/#?[a-z_][a-z1-9_-]+/,illegal:/\n/}] +},r=e.inherit(i,{begin:/\(/,end:/\)/}),s=e.inherit(e.APOS_STRING_MODE,{ +className:"string"}),o=e.inherit(e.QUOTE_STRING_MODE,{className:"string"}),l={ +endsWithParent:!0,illegal:/</,relevance:0,contains:[{className:"attr", +begin:/[\p{L}0-9._:-]+/u,relevance:0},{begin:/=\s*/,relevance:0,contains:[{ +className:"string",endsParent:!0,variants:[{begin:/"/,end:/"/,contains:[a]},{ +begin:/'/,end:/'/,contains:[a]},{begin:/[^\s"'=<>`]+/}]}]}]};return{ +name:"HTML, XML", +aliases:["html","xhtml","rss","atom","xjb","xsd","xsl","plist","wsf","svg"], +case_insensitive:!0,unicodeRegex:!0,contains:[{className:"meta",begin:/<![a-z]/, +end:/>/,relevance:10,contains:[i,o,s,r,{begin:/\[/,end:/\]/,contains:[{ +className:"meta",begin:/<![a-z]/,end:/>/,contains:[i,r,o,s]}]}] +},e.COMMENT(/<!--/,/-->/,{relevance:10}),{begin:/<!\[CDATA\[/,end:/\]\]>/, +relevance:10},a,{className:"meta",end:/\?>/,variants:[{begin:/<\?xml/, +relevance:10,contains:[o]},{begin:/<\?[a-z][a-z0-9]+/}]},{className:"tag", +begin:/<style(?=\s|>)/,end:/>/,keywords:{name:"style"},contains:[l],starts:{ +end:/<\/style>/,returnEnd:!0,subLanguage:["css","xml"]}},{className:"tag", +begin:/<script(?=\s|>)/,end:/>/,keywords:{name:"script"},contains:[l],starts:{ +end:/<\/script>/,returnEnd:!0,subLanguage:["javascript","handlebars","xml"]}},{ +className:"tag",begin:/<>|<\/>/},{className:"tag", +begin:n.concat(/</,n.lookahead(n.concat(t,n.either(/\/>/,/>/,/\s/)))), +end:/\/?>/,contains:[{className:"name",begin:t,relevance:0,starts:l}]},{ +className:"tag",begin:n.concat(/<\//,n.lookahead(n.concat(t,/>/))),contains:[{ +className:"name",begin:t,relevance:0},{begin:/>/,relevance:0,endsParent:!0}]}]} +},grmr_yaml:e=>{ +const n="true false yes no null",t="[\\w#;/?:@&=+$,.~*'()[\\]]+",a={ +className:"string",relevance:0,variants:[{begin:/'/,end:/'/},{begin:/"/,end:/"/ +},{begin:/\S+/}],contains:[e.BACKSLASH_ESCAPE,{className:"template-variable", +variants:[{begin:/\{\{/,end:/\}\}/},{begin:/%\{/,end:/\}/}]}]},i=e.inherit(a,{ +variants:[{begin:/'/,end:/'/},{begin:/"/,end:/"/},{begin:/[^\s,{}[\]]+/}]}),r={ +end:",",endsWithParent:!0,excludeEnd:!0,keywords:n,relevance:0},s={begin:/\{/, +end:/\}/,contains:[r],illegal:"\\n",relevance:0},o={begin:"\\[",end:"\\]", +contains:[r],illegal:"\\n",relevance:0},l=[{className:"attr",variants:[{ +begin:"\\w[\\w :\\/.-]*:(?=[ \t]|$)"},{begin:'"\\w[\\w :\\/.-]*":(?=[ \t]|$)'},{ +begin:"'\\w[\\w :\\/.-]*':(?=[ \t]|$)"}]},{className:"meta",begin:"^---\\s*$", +relevance:10},{className:"string", +begin:"[\\|>]([1-9]?[+-])?[ ]*\\n( +)[^ ][^\\n]*\\n(\\2[^\\n]+\\n?)*"},{ +begin:"<%[%=-]?",end:"[%-]?%>",subLanguage:"ruby",excludeBegin:!0,excludeEnd:!0, +relevance:0},{className:"type",begin:"!\\w+!"+t},{className:"type", +begin:"!<"+t+">"},{className:"type",begin:"!"+t},{className:"type",begin:"!!"+t +},{className:"meta",begin:"&"+e.UNDERSCORE_IDENT_RE+"$"},{className:"meta", +begin:"\\*"+e.UNDERSCORE_IDENT_RE+"$"},{className:"bullet",begin:"-(?=[ ]|$)", +relevance:0},e.HASH_COMMENT_MODE,{beginKeywords:n,keywords:{literal:n}},{ +className:"number", +begin:"\\b[0-9]{4}(-[0-9][0-9]){0,2}([Tt \\t][0-9][0-9]?(:[0-9][0-9]){2})?(\\.[0-9]*)?([ \\t])*(Z|[-+][0-9][0-9]?(:[0-9][0-9])?)?\\b" +},{className:"number",begin:e.C_NUMBER_RE+"\\b",relevance:0},s,o,a],c=[...l] +;return c.pop(),c.push(i),r.contains=c,{name:"YAML",case_insensitive:!0, +aliases:["yml"],contains:l}}});const He=ae;for(const e of Object.keys(Ke)){ +const n=e.replace("grmr_","").replace("_","-");He.registerLanguage(n,Ke[e])} +return He}() +;"object"==typeof exports&&"undefined"!=typeof module&&(module.exports=hljs);
\ No newline at end of file diff --git a/docs/scripts/highlight/rust.min.js b/docs/scripts/highlight/rust.min.js new file mode 100644 index 0000000..eb61ab9 --- /dev/null +++ b/docs/scripts/highlight/rust.min.js @@ -0,0 +1,28 @@ +/*! `rust` grammar compiled for Highlight.js 11.9.0 */ +(()=>{var e=(()=>{"use strict";return e=>{const t=e.regex,n={ +className:"title.function.invoke",relevance:0, +begin:t.concat(/\b/,/(?!let|for|while|if|else|match\b)/,e.IDENT_RE,t.lookahead(/\s*\(/)) +},a="([ui](8|16|32|64|128|size)|f(32|64))?",i=["drop ","Copy","Send","Sized","Sync","Drop","Fn","FnMut","FnOnce","ToOwned","Clone","Debug","PartialEq","PartialOrd","Eq","Ord","AsRef","AsMut","Into","From","Default","Iterator","Extend","IntoIterator","DoubleEndedIterator","ExactSizeIterator","SliceConcatExt","ToString","assert!","assert_eq!","bitflags!","bytes!","cfg!","col!","concat!","concat_idents!","debug_assert!","debug_assert_eq!","env!","eprintln!","panic!","file!","format!","format_args!","include_bytes!","include_str!","line!","local_data_key!","module_path!","option_env!","print!","println!","select!","stringify!","try!","unimplemented!","unreachable!","vec!","write!","writeln!","macro_rules!","assert_ne!","debug_assert_ne!"],r=["i8","i16","i32","i64","i128","isize","u8","u16","u32","u64","u128","usize","f32","f64","str","char","bool","Box","Option","Result","String","Vec"] +;return{name:"Rust",aliases:["rs"],keywords:{$pattern:e.IDENT_RE+"!?",type:r, +keyword:["abstract","as","async","await","become","box","break","const","continue","crate","do","dyn","else","enum","extern","false","final","fn","for","if","impl","in","let","loop","macro","match","mod","move","mut","override","priv","pub","ref","return","self","Self","static","struct","super","trait","true","try","type","typeof","unsafe","unsized","use","virtual","where","while","yield"], +literal:["true","false","Some","None","Ok","Err"],built_in:i},illegal:"</", +contains:[e.C_LINE_COMMENT_MODE,e.COMMENT("/\\*","\\*/",{contains:["self"] +}),e.inherit(e.QUOTE_STRING_MODE,{begin:/b?"/,illegal:null}),{ +className:"string",variants:[{begin:/b?r(#*)"(.|\n)*?"\1(?!#)/},{ +begin:/b?'\\?(x\w{2}|u\w{4}|U\w{8}|.)'/}]},{className:"symbol", +begin:/'[a-zA-Z_][a-zA-Z0-9_]*/},{className:"number",variants:[{ +begin:"\\b0b([01_]+)"+a},{begin:"\\b0o([0-7_]+)"+a},{ +begin:"\\b0x([A-Fa-f0-9_]+)"+a},{ +begin:"\\b(\\d[\\d_]*(\\.[0-9_]+)?([eE][+-]?[0-9_]+)?)"+a}],relevance:0},{ +begin:[/fn/,/\s+/,e.UNDERSCORE_IDENT_RE],className:{1:"keyword", +3:"title.function"}},{className:"meta",begin:"#!?\\[",end:"\\]",contains:[{ +className:"string",begin:/"/,end:/"/}]},{ +begin:[/let/,/\s+/,/(?:mut\s+)?/,e.UNDERSCORE_IDENT_RE],className:{1:"keyword", +3:"keyword",4:"variable"}},{ +begin:[/for/,/\s+/,e.UNDERSCORE_IDENT_RE,/\s+/,/in/],className:{1:"keyword", +3:"variable",5:"keyword"}},{begin:[/type/,/\s+/,e.UNDERSCORE_IDENT_RE], +className:{1:"keyword",3:"title.class"}},{ +begin:[/(?:trait|enum|struct|union|impl|for)/,/\s+/,e.UNDERSCORE_IDENT_RE], +className:{1:"keyword",3:"title.class"}},{begin:e.IDENT_RE+"::",keywords:{ +keyword:"Self",built_in:i,type:r}},{className:"punctuation",begin:"->"},n]}}})() +;hljs.registerLanguage("rust",e)})();
\ No newline at end of file diff --git a/run-tools.ps1 b/run-tools.ps1 index 20c4565..9bea120 100644 --- a/run-tools.ps1 +++ b/run-tools.ps1 @@ -1,31 +1,46 @@ Set-Location -Path (Split-Path -Parent $MyInvocation.MyCommand.Path) -ErrorAction Stop -if ($args.Count -eq 0) { - Write-Host "Available:" - if (Test-Path "dev_tools/src/bin") { - $files = Get-ChildItem -Path "dev_tools/src/bin/*.rs" - foreach ($file in $files) { - if ($file -is [System.IO.FileInfo]) { - Write-Host $file.BaseName - } +# Collect all available tool names +$tools = @() + +if (Test-Path "dev_tools/scripts") { + $scripts = Get-ChildItem -Path "dev_tools/scripts/*.ps1", "dev_tools/scripts/*.py" + foreach ($script in $scripts) { + if ($script -is [System.IO.FileInfo]) { + $tools += $script.BaseName } - } else { - Write-Host "Warning: dev_tools/src/bin directory does not exist" } - if (Test-Path "dev_tools/scripts") { - $scripts = Get-ChildItem -Path "dev_tools/scripts/*.ps1", "dev_tools/scripts/*.py" - foreach ($script in $scripts) { - if ($script -is [System.IO.FileInfo]) { - Write-Host $script.BaseName - } +} +if (Test-Path "dev_tools/src/bin") { + $files = Get-ChildItem -Path "dev_tools/src/bin/*.rs" + foreach ($file in $files) { + if ($file -is [System.IO.FileInfo]) { + $tools += $file.BaseName } - } else { - Write-Host "Warning: dev_tools/scripts directory does not exist" + } +} + +if ($args.Count -eq 0) { + Write-Host "Available:" + for ($i = 0; $i -lt $tools.Count; $i++) { + Write-Host (" [{0,2}] {1}" -f ($i + 1), $tools[$i]) } exit 1 } $target_name = $args[0] + +# Check if input is a number +if ($target_name -match '^\d+$') { + $idx = [int]$target_name - 1 + if ($idx -ge 0 -and $idx -lt $tools.Count) { + $target_name = $tools[$idx] + } else { + Write-Host "Error: invalid number '$target_name', valid range is 1-$($tools.Count)" + exit 1 + } +} + $script_file_ps1 = "dev_tools/scripts/${target_name}.ps1" $script_file_py = "dev_tools/scripts/${target_name}.py" $rust_file = "dev_tools/src/bin/${target_name}.rs" diff --git a/run-tools.sh b/run-tools.sh index 7a1062a..c80f9db 100755 --- a/run-tools.sh +++ b/run-tools.sh @@ -2,31 +2,50 @@ cd "$(dirname "$0")" || exit 1 +# 收集所有可用工具名称 +tools=() + +if [ -d "dev_tools/scripts" ]; then + for file in dev_tools/scripts/*.sh; do + if [ -f "$file" ]; then + tools+=("$(basename "$file" .sh)") + fi + done + for file in dev_tools/scripts/*.py; do + if [ -f "$file" ]; then + tools+=("$(basename "$file" .py)") + fi + done +fi +if [ -d "dev_tools/src/bin" ]; then + for file in dev_tools/src/bin/*.rs; do + if [ -f "$file" ]; then + tools+=("$(basename "$file" .rs)") + fi + done +fi + if [ $# -eq 0 ]; then echo "Available:" - if [ -d "dev_tools/scripts" ]; then - for file in dev_tools/scripts/*.sh; do - if [ -f "$file" ]; then - basename "$file" .sh - fi - done - for file in dev_tools/scripts/*.py; do - if [ -f "$file" ]; then - basename "$file" .py - fi - done - fi - if [ -d "dev_tools/src/bin" ]; then - for file in dev_tools/src/bin/*.rs; do - if [ -f "$file" ]; then - basename "$file" .rs - fi - done - fi + for i in "${!tools[@]}"; do + printf " [%2d] %s\n" $((i + 1)) "${tools[$i]}" + done exit 1 fi target_bin="$1" + +# 检查是否输入的是数字 +if [[ "$target_bin" =~ ^[0-9]+$ ]]; then + idx=$((target_bin - 1)) + if [ "$idx" -ge 0 ] && [ "$idx" -lt "${#tools[@]}" ]; then + target_bin="${tools[$idx]}" + else + echo "Error: invalid number '$target_bin', valid range is 1-${#tools[@]}" + exit 1 + fi +fi + target_script="dev_tools/scripts/${target_bin}.sh" target_python="dev_tools/scripts/${target_bin}.py" target_file="dev_tools/src/bin/${target_bin}.rs" @@ -37,7 +56,7 @@ if [ -f "$target_script" ]; then elif [ -f "$target_python" ]; then python "$target_python" elif [ -f "$target_file" ]; then - cargo run --manifest-path dev_tools/Cargo.toml --bin "$1" --quiet + cargo run --manifest-path dev_tools/Cargo.toml --bin "$target_bin" --quiet else echo "Error: target '$target_bin' does not exist" exit 1 |
