diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index ee6729e..2715609 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -16,7 +16,12 @@ A clear and concise description of what you expected to happen. **To Reproduce** Steps to reproduce the behavior: -If your problem is a non-working obfuscated file, please also include a minimal source code example, your config file as well as the output file that you got. +Please include: +- A **minimal reproducible example** shared via the Prometheus Web playground: https://prometheus-lua.github.io/Prometheus/ +- Your config (preset/custom config) +- The produced output (or relevant excerpt/error) + +If your problem is a non-working obfuscated file, the minimal source code example is required. **Screenshots** If applicable, add screenshots to help explain your problem. diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml index 132338a..cdf7e7c 100644 --- a/.github/workflows/pages.yml +++ b/.github/workflows/pages.yml @@ -31,8 +31,8 @@ jobs: cache: pnpm - name: Install dependencies run: pnpm install --frozen-lockfile - - name: Build web - run: pnpm --filter web build + - name: Build web + docs + run: pnpm run web:build - name: Upload artifact uses: actions/upload-pages-artifact@v3 with: diff --git a/.gitignore b/.gitignore index 1a3a7be..4107fb9 100644 --- a/.gitignore +++ b/.gitignore @@ -17,6 +17,7 @@ node_modules web/node_modules web/dist web/dist-ssr +web/public/docs web/test-results web/playwright-report .vite diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..cea7e9e --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,35 @@ +# Contributing to Prometheus + +Thanks for contributing to Prometheus. + +## Requirements + +- Keep pull requests focused and small where possible. +- Follow the existing project style and structure. +- Ensure your changes do not break existing tests and behavior. +- Add or update tests when changing behavior. +- Document user-visible changes clearly. + +## Reporting Bugs + +When opening a bug report, include: + +- Clear bug description +- Expected behavior +- Steps to reproduce +- A minimal reproducible example shared via the Prometheus Web playground: https://prometheus-lua.github.io/Prometheus/ +- Config used (preset/custom config) +- Produced output and relevant errors/logs +- Environment details (OS, Lua/LuaJIT version) + +Bug reports without a reproducible minimal example may be closed until reproducible information is provided. + +## Contributing New Steps / Features + +If a new step or feature might break existing scripts: + +- It must be clearly documented as potentially breaking. +- It must not be added to any default pipeline. +- It should only be available through custom configuration. + +When proposing such a change, include migration guidance and examples for users. diff --git a/README.md b/README.md index d8e1ed5..9228b6e 100644 --- a/README.md +++ b/README.md @@ -133,11 +133,13 @@ Focused on real obfuscation passes useful for shipped Lua applications. You can find the full documentation, including the getting started guide, here:

- - Documentation + + Documentation

+Contribution guidelines: [CONTRIBUTING.md](CONTRIBUTING.md) + --- ### Requirements @@ -167,7 +169,7 @@ return(function(...)local L={"afT6mf1V","/7mJXsuvmE1c/fT3";"tn1ZSn6=","37ghSJM=" -- remaining obfuscated output omitted ``` -For more advanced use cases, configuration, and presets, see the [documentation](https://levno-710.gitbook.io/prometheus/). +For more advanced use cases, configuration, and presets, see the [documentation](https://prometheus-lua.github.io/Prometheus/docs/). --- diff --git a/doc/README.md b/doc/README.md index 5899437..4668691 100644 --- a/doc/README.md +++ b/doc/README.md @@ -1,11 +1,36 @@ --- -description: Prometheus is an Lua Obfuscator, that is written in pure Lua. +description: Prometheus is a Lua obfuscator written in pure Lua. --- -# Prometheus +# Prometheus Documentation -Prometheus can obfuscate Lua51 as well as Roblox's LuaU, which is an optionally typed superset of Lua51. +Prometheus obfuscates Lua source code using AST transforms and a configurable pipeline. -View Prometheus on [github](https://github.com/levno-710/Prometheus). +Use the [Prometheus Webapp](https://prometheus-lua.github.io/Prometheus/) to quickly try out settings and test small snippets. For larger scripts and advanced workflows, use the CLI (`prometheus-lua` or `cli.lua`). -This Documentation only applies to the newest version of Prometheus. +This documentation covers: + +- CLI usage (`prometheus-lua` and `cli.lua`) +- configuration and presets +- all built-in obfuscation steps +- embedding Prometheus as a library + +## Who this is for + +- Lua developers shipping scripts where source readability is a concern +- users integrating Prometheus in build pipelines +- developers embedding Prometheus into another Lua application + +## Supported language targets + +- Lua 5.1 (`Lua51`) +- LuaU (`LuaU`) + +## Read in this order + +1. Installation +2. Quickstart +3. CLI Usage +4. Presets +5. Custom Config +6. Step Reference diff --git a/doc/SUMMARY.md b/doc/SUMMARY.md index a47a360..e5bcbf1 100644 --- a/doc/SUMMARY.md +++ b/doc/SUMMARY.md @@ -1,27 +1,36 @@ # Table of contents -* [Prometheus](README.md) +* [Prometheus Documentation](README.md) ## Getting Started * [Installation](getting-started/installation.md) -* [Obfuscating your first script](getting-started/obfuscating-your-first-script.md) -* [Command Line Options](getting-started/command-line-options.md) -* [Presets](getting-started/presets.md) -* [Writing a custom Config File](getting-started/writing-a-custom-config-file.md) -* [The Config Object](getting-started/the-config-object.md) - -## Steps - -* [WrapInFunction](steps/wrapinfunction.md) -* [Vmify](steps/vmify.md) -* [SplitStrings](steps/splitstrings.md) -* [ProxifyLocals](steps/proxifylocals.md) -* [EncryptStrings](steps/encryptstrings.md) -* [ConstantArray](steps/constantarray.md) -* [AntiTamper](steps/anti-tamper.md) - - -## advanced - -* [Using Prometheus in your Lua Application](advanced/using-prometheus-in-your-lua-application.md) +* [Quickstart: First Obfuscation](getting-started/quickstart-first-obfuscation.md) +* [Troubleshooting](getting-started/troubleshooting.md) + +## Guides + +* [CLI Usage](guides/cli-usage.md) +* [Presets](guides/presets.md) +* [Writing a Custom Config](guides/writing-a-custom-config.md) +* [Using Prometheus as a Library](guides/using-as-a-library.md) + +## Reference + +* [CLI Options Reference](reference/cli-options.md) +* [Config Object Reference](reference/config-object.md) +* [Step Pipeline Overview](reference/steps/overview.md) +* [Step: WrapInFunction](reference/steps/wrapinfunction.md) +* [Step: Vmify](reference/steps/vmify.md) +* [Step: SplitStrings](reference/steps/splitstrings.md) +* [Step: ProxifyLocals](reference/steps/proxifylocals.md) +* [Step: EncryptStrings](reference/steps/encryptstrings.md) +* [Step: ConstantArray](reference/steps/constantarray.md) +* [Step: AntiTamper](reference/steps/anti-tamper.md) +* [Step: NumbersToExpressions](reference/steps/numberstoexpressions.md) +* [Step: AddVararg](reference/steps/addvararg.md) +* [Step: WatermarkCheck](reference/steps/watermarkcheck.md) + +## Advanced + +* [How the Pipeline Works](advanced/how-the-pipeline-works.md) diff --git a/doc/advanced/how-the-pipeline-works.md b/doc/advanced/how-the-pipeline-works.md new file mode 100644 index 0000000..d067ea2 --- /dev/null +++ b/doc/advanced/how-the-pipeline-works.md @@ -0,0 +1,27 @@ +# How the Pipeline Works + +Execution flow in `Pipeline:apply`: + +1. Seed random generator (`Seed` or generated seed) +2. Parse source to AST +3. Apply configured steps in order +4. Rename variables +5. Unparse AST to Lua code + +## Seeding details + +- If `Seed > 0`: uses that fixed seed. +- Else Prometheus attempts `openssl rand -hex 12` for entropy. +- If OpenSSL is unavailable, it falls back to `os.time()` and logs a warning. + +## Variable renaming + +After all steps finish, Prometheus renames identifiers using: + +- selected `NameGenerator` +- configured `VarNamePrefix` +- language keyword table for selected `LuaVersion` + +## Logging + +Pipeline emits informational logs for each phase and step timing, including output size relative to source. diff --git a/doc/advanced/using-prometheus-in-your-lua-application.md b/doc/advanced/using-prometheus-in-your-lua-application.md deleted file mode 100644 index ed1fb98..0000000 --- a/doc/advanced/using-prometheus-in-your-lua-application.md +++ /dev/null @@ -1,31 +0,0 @@ -# Using Prometheus in your Lua Application - -Prometheus can also be used as a library for your custom Lua Applications instead of using its cli tool. - -In order to do that you'll first need to clone the github repo: - -```batch -git clone "https://github.com/levno-710/Prometheus.git" -``` - -After that, you'll need to copy everything within the src folder to your project. Let's say you created a folder named `prometheus`, where all the Prometheus files are located. You can the use the following code to obfuscate a string: - -{% code title="use_prometheus.lua" %} -```lua -local Prometheus = require("prometheus.prometheus") - --- If you don't want console output -Prometheus.Logger.logLevel = Prometheus.Logger.LogLevel.Error - --- Your code -local code = 'print("Hello, World!")' - --- Create a Pipeline using the Strong preset -local pipeline = Prometheus.Pipeline:fromConfig(Prometheus.Presets.Strong) - --- Apply the obfuscation and print the result -print(pipeline:apply(code)); -``` -{% endcode %} - -Instead of passing the Strong preset you could also pass a custom [Config Object](../getting-started/the-config-object.md). diff --git a/doc/book.json b/doc/book.json new file mode 100644 index 0000000..40dcc71 --- /dev/null +++ b/doc/book.json @@ -0,0 +1,6 @@ +{ + "title": "Prometheus Docs", + "styles": { + "website": "styles/website.css" + } +} diff --git a/doc/getting-started/command-line-options.md b/doc/getting-started/command-line-options.md deleted file mode 100644 index 637c904..0000000 --- a/doc/getting-started/command-line-options.md +++ /dev/null @@ -1,13 +0,0 @@ -# Command Line Options - -The following table provides a brief overview over the command line options: - -| Option | Usage | -| ----------------------------- | ----------------------------------------------------------- | -| --preset \[name]; --p \[name] | Specify the config preset to be used; [Details](presets.md) | -| --config \[path]; --c \[path] | Specify the path to a custom config file | -| --out \[path]; --o \[path] | Specify the path of the output file | -| --nocolors | Disable ansi colors escape sequences | -| --Lua51 | Handle input as Lua 5.1 | -| --LuaU | Handle input as LuaU | -| --pretty | Pretty print the output | diff --git a/doc/getting-started/installation.md b/doc/getting-started/installation.md index 01bde29..2421a0e 100644 --- a/doc/getting-started/installation.md +++ b/doc/getting-started/installation.md @@ -2,32 +2,38 @@ ## Linux and macOS (recommended) -Install the latest release: +Install latest release: ```bash curl -fsSL https://raw.githubusercontent.com/prometheus-lua/Prometheus/master/install.sh | sh ``` -Verify: +Verify installation: ```bash prometheus-lua --version ``` -Release bundles include a Lua runtime, so no separate Lua install is needed for installed CLI usage. - Update later: ```bash prometheus-lua update ``` +The release bundle includes a Lua runtime (`runtime/lua`), so you do not need a separate Lua install for packaged CLI usage. + ## From source ```bash -git clone "https://github.com/prometheus-lua/Prometheus.git" +git clone https://github.com/prometheus-lua/Prometheus.git cd Prometheus -./prometheus-lua --preset Medium ./your_file.lua +lua ./cli.lua --version +``` + +Then run obfuscation: + +```bash +lua ./cli.lua --preset Medium ./your_file.lua ``` -For source usage, Prometheus requires LuaJIT or Lua 5.1+. +For source usage, Prometheus expects a Lua runtime (LuaJIT, `lua5.1`, or `lua`). diff --git a/doc/getting-started/obfuscating-your-first-script.md b/doc/getting-started/obfuscating-your-first-script.md deleted file mode 100644 index 2a74193..0000000 --- a/doc/getting-started/obfuscating-your-first-script.md +++ /dev/null @@ -1,50 +0,0 @@ -# Obfuscating your first script - -Now that you have downloaded and Prometheus, you probably wonder how to use it. In this quick tutorial you are going to learn how to obfuscate your first file. - -Note that in the following command examples `lua` should be replaced by your lua implementation. - -Create the following file within the Prometheus main directory that you just downloaded: - -{% code title="hello_world.lua" %} -```lua -print("Hello, World") -``` -{% endcode %} - -Now run the following command inside of the Prometheus directory: - -```batch -lua ./cli.lua ./hello_world.lua -``` - -You may notice, that the console output looks weird. If that is the case, your terminal does not support ansi color escape sequences. You should add the `--nocolors` option: - -```batch -lua ./cli.lua --nocolors ./hello_world.lua -``` - -This should create the following file: - -{% code title="hello_world.obfuscated.lua" %} -```lua -print("Hello, World") -``` -{% endcode %} - -As you can see, the file hasn't changed at all. That is because by default prometheus is just a minifier and the code we gave it was already as small as possible. To actually obfuscate the file, prometheus must be told which obfuscation steps it should apply in which order. In order to do this, the cli provides the `--preset` option which allows you to specify the name of a predefined configuration. There are currently the following presets: - -* Minify -* Weak -* Medium -* Strong - -In order to perform the obfuscation, you need to specify that Prometheus should use the Strong preset: - -```batch -lua ./cli.lua --preset Medium ./hello_world.lua -``` - -The `hello_world.obfuscated.lua` should now contain the obfuscated code that should still print "Hello World". - -Note that using the "Strong" preset is not recommended for large projects. diff --git a/doc/getting-started/presets.md b/doc/getting-started/presets.md deleted file mode 100644 index b601e5c..0000000 --- a/doc/getting-started/presets.md +++ /dev/null @@ -1,10 +0,0 @@ -# Presets - -The following table provides an overview over the presets - -| name | size | speed | -| ------ | ------ | ------- | -| Minify | tiny | fastest | -| Weak | small | fast | -| Medium | medium | medium | -| Strong | huge | slowest | diff --git a/doc/getting-started/quickstart-first-obfuscation.md b/doc/getting-started/quickstart-first-obfuscation.md new file mode 100644 index 0000000..38b249d --- /dev/null +++ b/doc/getting-started/quickstart-first-obfuscation.md @@ -0,0 +1,32 @@ +# Quickstart: First Obfuscation + +You can quickly try Prometheus in the [Prometheus Webapp](https://prometheus-lua.github.io/Prometheus/). For large scripts or advanced use cases, prefer the CLI workflow below. + +Create a simple Lua file: + +```lua +print("Hello, World") +``` + +Run Prometheus from the repository root: + +```bash +lua ./cli.lua --preset Medium ./hello.lua +``` + +Prometheus will write: + +- `hello.obfuscated.lua` (default output path) + +Run the result with your Lua runtime to validate behavior. + +## Important default behavior + +- If you do not pass `--preset` or `--config`, Prometheus uses `Minify`. +- `Minify` performs minification only (no obfuscation steps). + +## Choosing a preset quickly + +- `Weak`: low overhead +- `Medium`: practical default +- `Strong`: strongest built-in preset, highest overhead diff --git a/doc/getting-started/the-config-object.md b/doc/getting-started/the-config-object.md deleted file mode 100644 index 4df718e..0000000 --- a/doc/getting-started/the-config-object.md +++ /dev/null @@ -1,56 +0,0 @@ -# The Config Object - -Prometheus takes a configuration object. In this object there can be many properties applied. \ -The following table provides an overview: - -| Property | type | possible values | default | -| ------------- | ------- | -------------------------------------------- | ----------------- | -| LuaVersion | string | "Lua51", "LuaU" | "Lua51" | -| PrettyPrint | boolean | true, false | false | -| VarNamePrefix | string | any | "" | -| NameGenerator | string | "Mangled", "MangledShuffled", "Il", "Number" | "MangledShuffled" | -| Seed | number | any | 0 | -| Steps | table | StepConfig\[] | {} | - -As this table shows, all properties in the config object are optional as they have a default value. - -As an example, here is the code for the minify preset: - -```lua -{ - -- The default LuaVersion is Lua51 - LuaVersion = "Lua51"; - -- For minifying no VarNamePrefix is applied - VarNamePrefix = ""; - -- Name Generator for Variables - NameGenerator = "MangledShuffled"; - -- No pretty printing - PrettyPrint = false; - -- Seed is generated based on current time - Seed = 0; - -- No obfuscation steps - Steps = {} -}; -``` - -### Steps - -The most important property is the Steps property. This property must be a table of so called Step Configs. A Step in Prometheus describes a single transformation applied to your script by the Prometheus obfuscation pipeline. A StepConfiguration consists of the Name of the Step as well as settings for the step. All Steps will later be applied in the order they are defined. A single Step can be defined twice and will then be applied twice. - -```lua --- Obfuscation steps -Steps = { - { - -- This obfuscation step puts all constants into an array at the beginning of the code - Name = "ConstantArray"; - Settings = { - -- Apply to Strings only - StringsOnly = true; - -- Apply to all Constants, 0.5 would only affect 50% of strings - Threshold = 1; - } - }, -} -``` - -Under [Steps](broken-reference), you can find all current Steps, their names as well as the possible options. diff --git a/doc/getting-started/troubleshooting.md b/doc/getting-started/troubleshooting.md new file mode 100644 index 0000000..5f7385a --- /dev/null +++ b/doc/getting-started/troubleshooting.md @@ -0,0 +1,38 @@ +# Troubleshooting + +## `No Lua runtime found` + +This comes from `prometheus-lua` when it cannot find: + +1. bundled runtime at `runtime/lua` +2. `luajit` +3. `lua5.1` +4. `lua` + +Install one of these runtimes or reinstall with the installer. + +## ANSI color output looks broken + +Use: + +```bash +--nocolors +``` + +## Parser errors are hard to inspect + +Use: + +```bash +--saveerrors +``` + +Prometheus will write `.error.txt` next to your input file. + +## `The Step "..." was not found` + +Your step `Name` does not match a registered step constructor. Use names documented in [Step Pipeline Overview](../reference/steps/overview.md). + +## `PrettyPrint` with `AntiTamper` + +`AntiTamper` is skipped when `PrettyPrint = true`. Prometheus logs a warning and continues. diff --git a/doc/getting-started/writing-a-custom-config-file.md b/doc/getting-started/writing-a-custom-config-file.md deleted file mode 100644 index ada5f6b..0000000 --- a/doc/getting-started/writing-a-custom-config-file.md +++ /dev/null @@ -1,56 +0,0 @@ -# Writing a custom Config File - -Configuration Files for Prometheus are just lua modules, that return a single object, which contains the configuration. Let's say we have the following config file: - -{% code title="config.lua" %} -```lua -return { - -- The default LuaVersion is Lua51 - LuaVersion = "Lua51"; -- or "LuaU" - -- All Variables will start with this prefix - VarNamePrefix = ""; - -- Name Generator for Variables that look like this: b, a, c, D, t, G - NameGenerator = "MangledShuffled"; - -- No pretty printing - PrettyPrint = false; - -- Seed is generated based on current time - -- When specifying a seed that is not 0, you will get the same output every time - Seed = 0; - -- Obfuscation steps - Steps = { - { - -- This obfuscation step puts all constants into an array at the beginning of the code - Name = "ConstantArray"; - Settings = { - -- Apply to Strings only - StringsOnly = true; - -- Apply to all Constants, 0.5 would only affect 50% of strings - Threshold = 1; - } - }, - } - } -``` -{% endcode %} - -One can now obfuscate a script using this configuration by running: - -```batch -lua ./cli.lua --config config.lua hello_world.lua -``` - -You should get the following output: - -{% code title="hello_world.obfuscated.lua" %} -```lua -local N={"Hello, World!"}local function k(k)return N[k+40058]end print(k(-40057)) -``` -{% endcode %} - -As you can see, the only transformation that was applied to our Hello World example was putting all strings (in this case only `"Hello, World!"` ) into an array and creating a wrapper function for retrieving the value. - -### How does the Config File work? - -The config file is simply a lua file, that returns the configuration object. Please note that this lua file is sandboxed by Prometheus when loading the configuration, meaning that you can't use any predefined functions like `tostring` or libraries like `math`. - -See [The Config Object](the-config-object.md) to learn what this configuration object consists of. diff --git a/doc/guides/cli-usage.md b/doc/guides/cli-usage.md new file mode 100644 index 0000000..aeddc02 --- /dev/null +++ b/doc/guides/cli-usage.md @@ -0,0 +1,53 @@ +# CLI Usage + +## Entry points + +- packaged CLI: `prometheus-lua` +- source CLI: `lua ./cli.lua` + +Both call the same CLI implementation (`src/cli.lua`). + +## Basic usage + +```bash +prometheus-lua --preset Medium ./input.lua +``` + +## Output file behavior + +If `--out` is not provided: + +- `input.lua` -> `input.obfuscated.lua` +- `input` -> `input.obfuscated.lua` + +## Common workflows + +Use a preset: + +```bash +prometheus-lua --preset Strong ./src/main.lua +``` + +Use a custom config file: + +```bash +prometheus-lua --config ./prometheus.config.lua ./src/main.lua +``` + +Force Lua target: + +```bash +prometheus-lua --preset Medium --LuaU ./src/main.lua +``` + +Enable pretty output: + +```bash +prometheus-lua --preset Minify --pretty ./src/main.lua +``` + +## Notes + +- Unknown `--...` options are ignored with a warning. +- If no config/preset is passed, Prometheus falls back to `Minify`. +- `update` command uses the official installer script from GitHub. diff --git a/doc/guides/presets.md b/doc/guides/presets.md new file mode 100644 index 0000000..61537c0 --- /dev/null +++ b/doc/guides/presets.md @@ -0,0 +1,58 @@ +# Presets + +Prometheus ships with these preset names in `src/presets.lua`: + +- `Minify` +- `Weak` +- `Vmify` (test-oriented helper preset) +- `Medium` +- `Strong` + +Use with: + +```bash +prometheus-lua --preset Medium ./file.lua +``` + +## Minify + +- no step transforms (`Steps = {}`) +- variable renaming still applies through pipeline settings +- best for size reduction and minimal runtime overhead + +## Weak + +Steps: + +1. `Vmify` +2. `ConstantArray` +3. `WrapInFunction` + +## Medium + +Steps: + +1. `EncryptStrings` +2. `AntiTamper` (`UseDebug = false`) +3. `Vmify` +4. `ConstantArray` +5. `NumbersToExpressions` +6. `WrapInFunction` + +## Strong + +Steps: + +1. `Vmify` +2. `EncryptStrings` +3. `AntiTamper` (`UseDebug = false`) +4. `Vmify` +5. `ConstantArray` +6. `NumbersToExpressions` +7. `WrapInFunction` + +## Choosing quickly + +- Start with `Medium`. +- Move to `Strong` only after benchmarking your runtime path. +- Use `Minify` when you want readability reduction only through compression/renaming style behavior. diff --git a/doc/guides/using-as-a-library.md b/doc/guides/using-as-a-library.md new file mode 100644 index 0000000..82e2a6d --- /dev/null +++ b/doc/guides/using-as-a-library.md @@ -0,0 +1,41 @@ +# Using Prometheus as a Library + +Prometheus can be required directly from Lua. + +## In this repository + +```lua +local Prometheus = require("src.prometheus") + +local code = 'print("Hello")' +local pipeline = Prometheus.Pipeline:fromConfig(Prometheus.Presets.Medium) +local out = pipeline:apply(code, "inline-source.lua") +print(out) +``` + +## Integration in another project + +Copy the `src/` tree and make sure `require` can resolve `src.prometheus` (or adapt your `package.path` to where `prometheus.lua` is located). + +## Useful runtime controls + +Disable noisy logs: + +```lua +Prometheus.Logger.logLevel = Prometheus.Logger.LogLevel.Error +``` + +Enable syntax highlighting in unparser output: + +```lua +local pipeline = Prometheus.Pipeline:new({ + LuaVersion = "Lua51", + PrettyPrint = false, + Highlight = true, +}) +``` + +## Notes + +- `pipeline:apply` expects source code text. +- If `apply` is called with no filename, logs use `Anonymous Script`. diff --git a/doc/guides/writing-a-custom-config.md b/doc/guides/writing-a-custom-config.md new file mode 100644 index 0000000..09a7be0 --- /dev/null +++ b/doc/guides/writing-a-custom-config.md @@ -0,0 +1,51 @@ +# Writing a Custom Config + +Prometheus accepts a Lua config file via `--config`. + +```bash +prometheus-lua --config ./prometheus.config.lua ./input.lua +``` + +## File format + +The config file must be executable Lua code that returns a table: + +```lua +return { + LuaVersion = "Lua51", + PrettyPrint = false, + VarNamePrefix = "", + NameGenerator = "MangledShuffled", + Seed = 0, + Steps = { + { Name = "EncryptStrings", Settings = {} }, + { Name = "Vmify", Settings = {} }, + { Name = "WrapInFunction", Settings = { Iterations = 1 } }, + } +} +``` + +## Step ordering matters + +`Steps` are applied in order. The same step can appear multiple times. + +## Name generator values + +Supported string values (from `src/prometheus/namegenerators.lua`): + +- `Mangled` +- `MangledShuffled` +- `Il` +- `Number` +- `Confuse` + +## Reproducibility + +- `Seed > 0`: deterministic RNG seed +- `Seed <= 0`: randomized seed (OpenSSL if available, else current time) + +## Common mistakes + +- Misspelled step names in `Name` +- wrong setting types (for example string instead of number) +- invalid `VarNamePrefix` for the selected Lua version diff --git a/doc/reference/cli-options.md b/doc/reference/cli-options.md new file mode 100644 index 0000000..c95d485 --- /dev/null +++ b/doc/reference/cli-options.md @@ -0,0 +1,28 @@ +# CLI Options Reference + +## Commands + +| Command | Description | +| --- | --- | +| `update` | Runs official installer script to install latest release | +| `--version`, `-v` | Prints version (`PROMETHEUS_LUA_VERSION` or `dev`) | +| `--help`, `-h`, `help` | Prints CLI help | + +## Obfuscation options + +| Option | Alias | Argument | Description | +| --- | --- | --- | --- | +| `--preset` | `--p` | `` | Use built-in preset by name | +| `--config` | `--c` | `` | Load config Lua file | +| `--out` | `--o` | `` | Output file path | +| `--Lua51` | - | none | Force Lua 5.1 conventions | +| `--LuaU` | - | none | Force LuaU conventions | +| `--pretty` | - | none | Pretty-print generated output | +| `--nocolors` | - | none | Disable ANSI colors | +| `--saveerrors` | - | none | Write parser/runtime errors to `.error.txt` | + +## Parsing behavior + +- First non-option argument is treated as input file. +- A second non-option argument raises an error. +- Unknown options are ignored with a warning. diff --git a/doc/reference/config-object.md b/doc/reference/config-object.md new file mode 100644 index 0000000..98ff0df --- /dev/null +++ b/doc/reference/config-object.md @@ -0,0 +1,45 @@ +# Config Object Reference + +Prometheus config table fields: + +| Field | Type | Default | Description | +| --- | --- | --- | --- | +| `LuaVersion` | string | `"Lua51"` (in `fromConfig`) | Target parser/unparser conventions (`Lua51` or `LuaU`) | +| `PrettyPrint` | boolean | `false` | Pretty output mode | +| `VarNamePrefix` | string | `""` | Prefix for generated variable names | +| `NameGenerator` | string | `"MangledShuffled"` | Name generator key | +| `Seed` | number | `0` | RNG seed; `<=0` means generated seed | +| `Steps` | table | `{}` | Ordered step list | + +## Steps format + +```lua +Steps = { + { + Name = "WrapInFunction", + Settings = { + Iterations = 1, + } + } +} +``` + +## Validation behavior + +- Unknown step names cause an error. +- Step setting types are validated against each step's descriptor. +- Missing required step settings use defaults when present. + +## Setting-name compatibility + +Canonical setting names are: + +- `Threshold` +- `LocalWrapperThreshold` +- `NumberRepresentationMutation` + +Legacy misspellings are still accepted for backward compatibility: + +- `Treshold` +- `LocalWrapperTreshold` +- `NumberRepresentationMutaton` diff --git a/doc/reference/steps/addvararg.md b/doc/reference/steps/addvararg.md new file mode 100644 index 0000000..1f74ed2 --- /dev/null +++ b/doc/reference/steps/addvararg.md @@ -0,0 +1,15 @@ +# Step: AddVararg + +Constructor key: `AddVararg` + +Appends `...` vararg to function signatures that do not already end in vararg. + +## Settings + +None. + +## Example + +```lua +{ Name = "AddVararg", Settings = {} } +``` diff --git a/doc/reference/steps/anti-tamper.md b/doc/reference/steps/anti-tamper.md new file mode 100644 index 0000000..70df14f --- /dev/null +++ b/doc/reference/steps/anti-tamper.md @@ -0,0 +1,22 @@ +# Step: AntiTamper + +Constructor key: `AntiTamper` + +Injects anti-tamper and anti-hook checks. If tamper checks fail, runtime execution is intentionally broken. + +## Settings + +| Key | Type | Default | +| --- | --- | --- | +| `UseDebug` | boolean | `true` | + +## Behavior notes + +- If pipeline `PrettyPrint` is enabled, this step logs a warning and is skipped. +- With `UseDebug = true`, generated code uses debug-library-based checks. + +## Example + +```lua +{ Name = "AntiTamper", Settings = { UseDebug = false } } +``` diff --git a/doc/reference/steps/constantarray.md b/doc/reference/steps/constantarray.md new file mode 100644 index 0000000..2ec9cd4 --- /dev/null +++ b/doc/reference/steps/constantarray.md @@ -0,0 +1,38 @@ +# Step: ConstantArray + +Constructor key: `ConstantArray` + +Extracts constants into an array and replaces direct constants with indexed access/wrapper calls. + +## Settings + +| Key | Type | Default | Notes | +| --- | --- | --- | --- | +| `Threshold` | number | `1` | probability `0..1` | +| `StringsOnly` | boolean | `false` | when `true`, only string constants are moved | +| `Shuffle` | boolean | `true` | shuffles array order | +| `Rotate` | boolean | `true` | rotates array and injects runtime un-rotate logic | +| `LocalWrapperThreshold` | number | `1` | probability `0..1` | +| `LocalWrapperCount` | number | `0` | wrapper functions per function scope | +| `LocalWrapperArgCount` | number | `10` | wrapper function argument count | +| `MaxWrapperOffset` | number | `65535` | max random index offset | +| `Encoding` | enum | `"mixed"` | `none`, `base64`, `base85`, `mixed` | + +## Example + +```lua +{ + Name = "ConstantArray", + Settings = { + Threshold = 1, + StringsOnly = true, + Shuffle = true, + Rotate = true, + LocalWrapperThreshold = 0, + LocalWrapperCount = 0, + Encoding = "mixed", + } +} +``` + +Legacy keys `Treshold` and `LocalWrapperTreshold` are still accepted for backward compatibility. diff --git a/doc/reference/steps/encryptstrings.md b/doc/reference/steps/encryptstrings.md new file mode 100644 index 0000000..313971e --- /dev/null +++ b/doc/reference/steps/encryptstrings.md @@ -0,0 +1,15 @@ +# Step: EncryptStrings + +Constructor key: `EncryptStrings` + +Encrypts string literals and injects runtime decryption logic. + +## Settings + +None. + +## Example + +```lua +{ Name = "EncryptStrings", Settings = {} } +``` diff --git a/doc/reference/steps/numberstoexpressions.md b/doc/reference/steps/numberstoexpressions.md new file mode 100644 index 0000000..216fcd4 --- /dev/null +++ b/doc/reference/steps/numberstoexpressions.md @@ -0,0 +1,33 @@ +# Step: NumbersToExpressions + +Constructor key: `NumbersToExpressions` + +Rewrites number literals as arithmetic expressions and optionally mutates numeric representation format. + +## Settings + +| Key | Type | Default | Notes | +| --- | --- | --- | --- | +| `Threshold` | number | `1` | probability `0..1` for transforming number literals | +| `InternalThreshold` | number | `0.2` | recursion/representation cutoff (`0..0.8`) | +| `NumberRepresentationMutation` | boolean | `false` | enables representation mutation | +| `AllowedNumberRepresentations` | table | `{ "hex", "scientific", "normal" }` | options include `binary` | + +## Example + +```lua +{ + Name = "NumbersToExpressions", + Settings = { + Threshold = 1, + InternalThreshold = 0.2, + NumberRepresentationMutation = true, + AllowedNumberRepresentations = { "hex", "scientific", "normal" }, + } +} +``` + +## Notes + +- If `binary` is enabled in allowed representations, Prometheus warns that binary literals need Lua 5.2+ syntax support. +- Legacy key `NumberRepresentationMutaton` is still accepted for backward compatibility. diff --git a/doc/reference/steps/overview.md b/doc/reference/steps/overview.md new file mode 100644 index 0000000..846133c --- /dev/null +++ b/doc/reference/steps/overview.md @@ -0,0 +1,36 @@ +# Step Pipeline Overview + +Prometheus applies each configured step to the AST in the order listed in `Steps`. + +After step application, Prometheus performs variable renaming and then unparses code. + +## Registered step constructor keys + +Use these exact values in `Steps[i].Name`: + +- `WrapInFunction` +- `SplitStrings` +- `Vmify` +- `ConstantArray` +- `ProxifyLocals` +- `AntiTamper` +- `EncryptStrings` +- `NumbersToExpressions` +- `AddVararg` +- `WatermarkCheck` + +## General step config shape + +```lua +{ + Name = "Vmify", + Settings = {} +} +``` + +## Notes + +- Some constructor keys differ from internal human-readable names. +- `Vmify` is a legacy constructor key name; behavior is closer to control-flow flattening style obfuscation than full virtualization. +- You can apply the same step more than once. +- If a step returns a new AST, that AST is used for later steps. diff --git a/doc/reference/steps/proxifylocals.md b/doc/reference/steps/proxifylocals.md new file mode 100644 index 0000000..25dc7d5 --- /dev/null +++ b/doc/reference/steps/proxifylocals.md @@ -0,0 +1,22 @@ +# Step: ProxifyLocals + +Constructor key: `ProxifyLocals` + +Wraps local variable accesses through proxy/metatable operations. + +## Settings + +| Key | Type | Default | Values | +| --- | --- | --- | --- | +| `LiteralType` | enum | `"string"` | `dictionary`, `number`, `string`, `any` | + +## Example + +```lua +{ Name = "ProxifyLocals", Settings = { LiteralType = "any" } } +``` + +## Notes + +- Global variables are not transformed. +- Function arguments and loop variables are excluded from proxification. diff --git a/doc/reference/steps/splitstrings.md b/doc/reference/steps/splitstrings.md new file mode 100644 index 0000000..b8817c6 --- /dev/null +++ b/doc/reference/steps/splitstrings.md @@ -0,0 +1,32 @@ +# Step: SplitStrings + +Constructor key: `SplitStrings` + +Splits string literals into chunks and reconstructs them at runtime. + +## Settings + +| Key | Type | Default | Notes | +| --- | --- | --- | --- | +| `Threshold` | number | `1` | probability per candidate string (`0..1`) | +| `MinLength` | number | `5` | minimum chunk length (`>=1`) | +| `MaxLength` | number | `5` | maximum chunk length (`>=1`) | +| `ConcatenationType` | enum | `"custom"` | `strcat`, `table`, `custom` | +| `CustomFunctionType` | enum | `"global"` | `global`, `local`, `inline` (used when `custom`) | +| `CustomLocalFunctionsCount` | number | `2` | used when `CustomFunctionType = "local"` | + +## Example + +```lua +{ + Name = "SplitStrings", + Settings = { + Threshold = 0.8, + MinLength = 3, + MaxLength = 8, + ConcatenationType = "custom", + CustomFunctionType = "local", + CustomLocalFunctionsCount = 2, + } +} +``` diff --git a/doc/reference/steps/vmify.md b/doc/reference/steps/vmify.md new file mode 100644 index 0000000..8884771 --- /dev/null +++ b/doc/reference/steps/vmify.md @@ -0,0 +1,16 @@ +# Step: Vmify + +Constructor key: `Vmify` + +`Vmify` is a legacy step name kept for backward compatibility. +In practice, this transformation is better understood as control-flow flattening style obfuscation rather than full virtualization. + +## Settings + +None. + +## Example + +```lua +{ Name = "Vmify", Settings = {} } +``` diff --git a/doc/reference/steps/watermarkcheck.md b/doc/reference/steps/watermarkcheck.md new file mode 100644 index 0000000..6ace93e --- /dev/null +++ b/doc/reference/steps/watermarkcheck.md @@ -0,0 +1,27 @@ +# Step: WatermarkCheck + +Constructor key: `WatermarkCheck` + +Injects a runtime watermark check and appends a `Watermark` step internally. + +## Settings + +| Key | Type | Default | +| --- | --- | --- | +| `Content` | string | `"This Script is Part of the Prometheus Obfuscator by levno-710"` | + +## Example + +```lua +{ + Name = "WatermarkCheck", + Settings = { + Content = "my watermark", + } +} +``` + +## Notes + +- `Watermark` is not exported in the standard step registry, but `WatermarkCheck` uses it internally. +- On mismatch, the injected guard returns early. diff --git a/doc/reference/steps/wrapinfunction.md b/doc/reference/steps/wrapinfunction.md new file mode 100644 index 0000000..40412de --- /dev/null +++ b/doc/reference/steps/wrapinfunction.md @@ -0,0 +1,17 @@ +# Step: WrapInFunction + +Constructor key: `WrapInFunction` + +Wraps the full script body in a function call one or more times. + +## Settings + +| Key | Type | Default | Range | +| --- | --- | --- | --- | +| `Iterations` | number | `1` | `>= 1` | + +## Example + +```lua +{ Name = "WrapInFunction", Settings = { Iterations = 1 } } +``` diff --git a/doc/steps/anti-tamper.md b/doc/steps/anti-tamper.md deleted file mode 100644 index 56af120..0000000 --- a/doc/steps/anti-tamper.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -description: This step provides an obfuscation step, that breaks the script, when someone tries to tamper with it. ---- - -# Anti Tamper - -### Settings - -| Name | type | description | values | -| ----------- | ---- | ------------------------------------------- | --------------------------------------- | -| UseDebug | boolean | Uses the debug library in lua. Disable this if you don't have access to debug library | "true","false" | diff --git a/doc/steps/constantarray.md b/doc/steps/constantarray.md deleted file mode 100644 index 61338e1..0000000 --- a/doc/steps/constantarray.md +++ /dev/null @@ -1,71 +0,0 @@ ---- -description: >- - This Step will Extract all Constants and put them into an Array at the - beginning of the script ---- - -# ConstantArray - -### Settings - -| Name | type | description | -| -------------------- | ------- | ------------------------------------------------------------------------------------------------------------ | -| Threshold | number | The relative amount of nodes that will be affected" | -| StringsOnly | boolean | Whether to only Extract Strings | -| Shuffle | boolean | Whether to shuffle the order of Elements in the Array | -| Rotate | boolean | Whether to rotate the String Array by a specific (random) amount. This will be undone on runtime. | -| LocalWrapperThreshold | number | The relative amount of nodes functions, that will get local wrappers | -| LocalWrapperCount | number | The number of Local wrapper Functions per scope. This only applies if LocalWrapperThreshold is greater than 0 | -| LocalWrapperArgCount | number | The number of Arguments to the Local wrapper Functions | -| MaxWrapperOffset | number | The Max Offset for the Wrapper Functions | - -### Example - -{% code title="in.lua" %} -```lua -print("1") -print("2") -print("3") -print("4") -``` -{% endcode %} - -{% code title="out.lua" %} -```lua --- LocalWrapperCount = 3 --- LocalWrapperArgCount = 5 -local F = {"4", "3", "2", "1"} -do - local y, G = 1, 4 - while y < G do - F[y], F[G] = F[G], F[y] - y, G = y + 1, G - 1 - end - y, G = 1, 3 - while y < G do - F[y], F[G] = F[G], F[y] - y, G = y + 1, G - 1 - end - y, G = 4, 4 - while y < G do - F[y], F[G] = F[G], F[y] - y, G = y + 1, G - 1 - end -end -local function y(y) - return F[y + 440] -end -local G = {cb = function(F, G, R, p, b) - return y(G - 2277) - end, n = function(F, G, R, p, b) - return y(p + 47178) - end, B = function(F, G, R, p, b) - return y(F + 31775) - end} -print(G.cb(1575, 1840, 2367, 1293, 1280)) -print(G.B(-32213, -31781, -31538, -32780, -32728)) -print(G.B(-32214, -33004, -31973, -32125, -31855)) -print(G.B(-32211, -31884, -31217, -32222, -31210)) - -``` -{% endcode %} diff --git a/doc/steps/encryptstrings.md b/doc/steps/encryptstrings.md deleted file mode 100644 index 329a8cf..0000000 --- a/doc/steps/encryptstrings.md +++ /dev/null @@ -1,86 +0,0 @@ ---- -description: This Step will encrypt all String constants in your code ---- - -# EncryptStrings - -## Settings - -None - -## Example - -{% code title="in.lua" %} -```lua -print("Hello, World!") -``` -{% endcode %} - -{% code title="out.lua" %} -```lua --- Settings: None -local x, F -do - local k = math.floor - local I = math.random - local Y = table.remove - local i = string.char - local K = 0 - local J = 2 - local Q = {} - local W = {} - local q = 0 - local R = {} - for F = 1, 256, 1 do - R[F] = F - end - repeat - local F = I(1, #R) - local x = Y(R, F) - W[x] = i(x - 1) - until #R == 0 - local j = {} - local function B() - if #j == 0 then - K = (K * 173 + 8408159861491) % 35184372088832 - repeat - J = (J * 160) % 257 - until J ~= 1 - local F = J % 32 - local x = (k(K / 2 ^ (13 - (J - F) / 32)) % 4294967296) / 2 ^ F - local I = k((x % 1) * 4294967296) + k(x) - local Y = I % 65536 - local i = (I - Y) / 65536 - local Q = Y % 256 - local W = (Y - Q) / 256 - local q = i % 256 - local R = (i - q) / 256 - j = {Q, W, q, R} - end - return table.remove(j) - end - local d = {} - x = setmetatable({}, {__index = d, __metatable = nil}) - function F(x, k) - local I = d - if I[k] then - else - j = {} - local F = W - K = k % 35184372088832 - J = k % 255 + 2 - local Y = string.len(x) - I[k] = "" - local i = 198 - for Y = 1, Y, 1 do - i = ((string.byte(x, Y) + B()) + i) % 256 - I[k] = I[k] .. F[i + 1] - end - end - return k - end -end -print(x[F("\219\018Q%~Y\225\128u\128\208&\155", 6909832146399)]) - -``` -{% endcode %} diff --git a/doc/steps/proxifylocals.md b/doc/steps/proxifylocals.md deleted file mode 100644 index c596e0b..0000000 --- a/doc/steps/proxifylocals.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -description: This Step wraps all locals into Proxy Objects ---- - -# ProxifyLocals - -### Settings - -| Name | type | description | values | -| ----------- | ---- | ------------------------------------------- | --------------------------------------- | -| LiteralType | enum | The type of the randomly generated literals | "dictionary", "number", "string", "any" | - -### Example - -{% code title="in.lua" %} -```lua -local x = "Hello, World!" -print(x) -``` -{% endcode %} - -{% code title="out.lua" %} -```lua --- LiteralType = "dictionary" -local n = setmetatable -local D = - n( - {Wz = function() - end}, - {__div = function(R, n) - R.Wz = n - end, __concat = function(R, n) - return R.Wz - end} -) -local R = - n( - {Js = "Hello, World!"}, - {__add = function(R, n) - R.Js = n - end, __index = function(R, n) - return rawget(R, "Js") - end} -) -print(R.Muirgen) -``` -{% endcode %} diff --git a/doc/steps/splitstrings.md b/doc/steps/splitstrings.md deleted file mode 100644 index af6f00d..0000000 --- a/doc/steps/splitstrings.md +++ /dev/null @@ -1,40 +0,0 @@ ---- -description: This Step splits Strings to a specific or random length ---- - -# SplitStrings - -### Settings - -| Name | type | description | Values | -| ------------------------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- | -| Threshold | number | The relative amount of nodes that will be affected | 0 <= x <= 1 | -| MinLength | number | The minimal length for the chunks in that the Strings are splitted | x > 0 | -| MaxLength | number | The maximal length for the chunks in that the Strings are splitted | x >= MinLength | -| ConcatenationType | enum | The Functions used for Concatenation. Note that when using custom, the String Array will also be Shuffled | "strcat", "table", "custom" | -| CustomFunctionType | enum |

The Type of Function code injection This Option only applies when custom Concatenation is selected.
Note that when choosing inline, the code size may increase significantly!

| "global", "local", "inline" | -| CustomLocalFunctionsCount | number | The number of local functions per scope. This option only applies when CustomFunctionType = local | x > 0 | - -### Example - -{% code title="in.lua" %} -```lua -print("Hello, World!") -``` -{% endcode %} - -{% code title="out.lua" %} -```lua --- MinLength = 1 --- MaxLength = 1 -local f = function(f) - local k, C = f[#f], "" - for j = 1, #k, 1 do - C = C .. k[f[j]] - end - return C -end -print(f({13, 11, 4, 12, 1, 6, 8, 10, 9, 7, 3, 2, 5, {"o", "d", "l", "l", "!", ",", "r", " ", "o", "W", "e", "l", "H"}})) - -``` -{% endcode %} diff --git a/doc/steps/vmify.md b/doc/steps/vmify.md deleted file mode 100644 index dd0aa69..0000000 --- a/doc/steps/vmify.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -description: This Step will Compile your script and run it within a VM. ---- - -# Vmify - -### Settings - -None diff --git a/doc/steps/wrapinfunction.md b/doc/steps/wrapinfunction.md deleted file mode 100644 index d702bc8..0000000 --- a/doc/steps/wrapinfunction.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -description: This Step Wraps the Entire Script into a Function ---- - -# WrapInFunction - -### Settings - -| Name | type | description | -| ---------- | ------ | ------------------------ | -| Iterations | number | The Number Of Iterations | - -### Example - -{% code title="in.lua" %} -```lua -print("Hello, World!") -``` -{% endcode %} - -{% code title="out.lua" %} -```lua --- Iterations = 1 -return (function() - print("Hello, World!") -end)() - -``` -{% endcode %} diff --git a/doc/styles/website.css b/doc/styles/website.css new file mode 100644 index 0000000..8ea486d --- /dev/null +++ b/doc/styles/website.css @@ -0,0 +1,3 @@ +.gitbook-link { + display: none !important; +} diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..e886551 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,31 @@ +{ + "name": "prometheus-workspace", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "prometheus-workspace", + "dependencies": { + "pnpm": "^11.0.8" + } + }, + "node_modules/pnpm": { + "version": "11.0.8", + "resolved": "https://registry.npmjs.org/pnpm/-/pnpm-11.0.8.tgz", + "integrity": "sha512-TECX4d0tQjcsTn+lp5H/KPx1pITHrBkuZLHfD97xdZS6mC+bT+2a37PHV4RvVlt5mydj+zcz0d4by4LPRmhJEg==", + "license": "MIT", + "bin": { + "pn": "bin/pnpm.mjs", + "pnpm": "bin/pnpm.mjs", + "pnpx": "bin/pnpx.mjs", + "pnx": "bin/pnpx.mjs" + }, + "engines": { + "node": ">=22.13" + }, + "funding": { + "url": "https://opencollective.com/pnpm" + } + } + } +} diff --git a/package.json b/package.json index deaec42..dc491bb 100644 --- a/package.json +++ b/package.json @@ -3,9 +3,14 @@ "private": true, "packageManager": "pnpm@10.33.0", "scripts": { - "web:dev": "pnpm --filter web dev", - "web:build": "pnpm --filter web build", - "web:preview": "pnpm --filter web preview", + "docs:build": "node ./scripts/build-docs.mjs", + "web:dev": "pnpm run docs:build && pnpm --filter web dev", + "web:build": "pnpm run docs:build && pnpm --filter web build", + "web:preview": "pnpm run web:build && pnpm --filter web preview", "web:test": "pnpm --filter web test" + }, + "dependencies": { + "honkit": "^6.1.7", + "pnpm": "^11.0.8" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 33d863a..7e4e8a1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -6,7 +6,14 @@ settings: importers: - .: {} + .: + dependencies: + honkit: + specifier: ^6.1.7 + version: 6.1.7 + pnpm: + specifier: ^11.0.8 + version: 11.0.8 web: dependencies: @@ -113,6 +120,17 @@ packages: '@asamuzakjp/nwsapi@2.3.9': resolution: {integrity: sha512-n8GuYSrI9bF7FFZ/SjhwevlHc8xaVlb/7HmHelnc/PZXBD2ZR49NnN9sMMuDdEGPeeRQ5d0hqlSlEpgCX3Wl0Q==} + '@asciidoctor/cli@3.5.0': + resolution: {integrity: sha512-/VMHXcZBnZ9vgWfmqk9Hu0x0gMjPLup0YGq/xA8qCQuk11kUIZNMVQwgSsIUzOEwJqIUD7CgncJdtfwv1Ndxuw==} + engines: {node: '>=8.11', npm: '>=5.0.0'} + hasBin: true + peerDependencies: + '@asciidoctor/core': ^2.0.0-rc.1 + + '@asciidoctor/core@2.2.9': + resolution: {integrity: sha512-tIPRHo1T2SFmAm+j77cDsj0RuaszP7xJxsaVTTAF5CwKyTbazw9TnIVlpIWM5yWfIWAWcAZy92RcnPgMJwny1w==} + engines: {node: '>=8.11', npm: '>=5.0.0', yarn: '>=1.1.0'} + '@babel/code-frame@7.29.0': resolution: {integrity: sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==} engines: {node: '>=6.9.0'} @@ -428,6 +446,27 @@ packages: '@floating-ui/utils@0.2.11': resolution: {integrity: sha512-RiB/yIh78pcIxl6lLMG0CgBXAZ2Y0eVHqMPYugu+9U0AeT6YBeiJpf7lbdJNIugFP5SIjwNRgo4DhR1Qxi26Gg==} + '@honkit/asciidoc@6.1.7': + resolution: {integrity: sha512-2wn9h6FqxtB6uR2aadh10HPGK34F8ucGmV9WMx+rkAO1irTmKzo0Kllo8QWqNVJ6gOE2nhM1e2HmRX5Qj8jZvQ==} + + '@honkit/honkit-plugin-fontsettings@6.1.7': + resolution: {integrity: sha512-pP0apyv3hI0GJ2sS5EFrE/NPlCYnSO/HXF10FElDZ6tCv7bj4lmJ87TZ5+18Y5gE4hhIRE1SAgtAWtia1LABoA==} + engines: {gitbook: '>=2.4.0'} + + '@honkit/honkit-plugin-highlight@6.1.7': + resolution: {integrity: sha512-W675g59J2Ur+9LnP109n8yQt2XNiO8nTO/BWAEmSBmDxxZLttZGwWxOVQzgvgeEszqiC/4dWLveggOJJdmpNzw==} + engines: {gitbook: '>=2.4.0'} + + '@honkit/honkit-plugin-theme-default@6.1.7': + resolution: {integrity: sha512-KunA3b46QdLZxqTw5Is2/H2YyzNg2AYSeOhUkF5dz+b6nRCYQNScU4u+ZLe7mfmaAd8HX9+mtTwng1qIIrf5xA==} + engines: {gitbook: '>=3.0.0'} + + '@honkit/html@6.1.7': + resolution: {integrity: sha512-aHM2FgybyLbO+DxpMrYK1jt8pzv9npcZzlfxiBjuyrgGKPuwHmfp4xC2W2KOidfR7ZgEVSo858cur3NDjt99Zg==} + + '@honkit/markdown-legacy@6.1.7': + resolution: {integrity: sha512-LLPi7emPv2YaotRfb3IwKC3egQ9nZ4S0E9PV4IurGjfVpSq8dgEXyDMo3Bvgz7pAv/ylo8GN0IAyNVRQtfg4TA==} + '@jridgewell/gen-mapping@0.3.13': resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} @@ -456,6 +495,18 @@ packages: '@marijn/find-cluster-break@1.0.2': resolution: {integrity: sha512-l0h88YhZFyKdXIFNfSWpyjStDjGHwZ/U7iobcK1cQQD8sejsONdQtTVU+1wVN1PBw40PiiHB1vA5S7VTfQiP9g==} + '@nodelib/fs.scandir@2.1.5': + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + + '@nodelib/fs.stat@2.0.5': + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + + '@nodelib/fs.walk@1.2.8': + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + '@playwright/test@1.59.1': resolution: {integrity: sha512-PG6q63nQg5c9rIi4/Z5lR5IVF7yU5MqmKaPOe0HSc0O2cX1fPi96sUQu5j7eo4gKCkB2AnNGoWt7y4/Xx3Kcqg==} engines: {node: '>=18'} @@ -1485,18 +1536,36 @@ packages: '@vitest/utils@4.1.5': resolution: {integrity: sha512-76wdkrmfXfqGjueGgnb45ITPyUi1ycZ4IHgC2bhPDUfWHklY/q3MdLOAB+TF1e6xfl8NxNY0ZYaPCFNWSsw3Ug==} + a-sync-waterfall@1.0.1: + resolution: {integrity: sha512-RYTOHHdWipFUliRFMCS4X2Yn2X8M87V/OpSqWzKKOGhzqyUxzyVmhHDH9sAvG+ZuQf/TAOFsLCpMw09I1ufUnA==} + agent-base@7.1.4: resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} engines: {node: '>= 14'} + ansi-colors@4.1.3: + resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} + engines: {node: '>=6'} + ansi-regex@5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + ansi-styles@5.2.0: resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} engines: {node: '>=10'} + anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + + argparse@1.0.10: + resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} + aria-hidden@1.2.6: resolution: {integrity: sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==} engines: {node: '>=10'} @@ -1508,23 +1577,78 @@ packages: resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==} engines: {node: '>= 0.4'} + array-difference@0.0.1: + resolution: {integrity: sha512-LMXXDKmRSsO+d7N73LyTBWlT+GiLfNUCWeeWmZivzJ1NxSPOobS+w8bIAAfGEV35oVBsk9u9cXii8dDceU5NPw==} + + asap@2.0.6: + resolution: {integrity: sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==} + + asciidoctor-opal-runtime@0.3.4: + resolution: {integrity: sha512-zqd6zn1LV+PZ69AP/kEbB00zuPHMIAJY3IX8+aZV+X1qOwatYvKGjsMmdMc5ApfhtkjZ4mYkqiTPJWnEnBiMJg==} + engines: {node: '>=8.11'} + + asciidoctor@2.2.9: + resolution: {integrity: sha512-lzviGTZ/tnnmDLIE+fY/m8aUc6lGTGRNh5rTC1HPevlc89G0iYez+sQFT60oZ87BPzOYllP+TeK1xh0D1wt/6Q==} + engines: {node: '>=8.11', npm: '>=5.0.0', yarn: '>=1.1.0'} + hasBin: true + assertion-error@2.0.1: resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} engines: {node: '>=12'} + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + baseline-browser-mapping@2.10.27: resolution: {integrity: sha512-zEs/ufmZoUd7WftKpKyXaT6RFxpQ5Qm9xytKRHvJfxFV9DFJkZph9RvJ1LcOUi0Z1ZVijMte65JbILeV+8QQEA==} engines: {node: '>=6.0.0'} hasBin: true + bash-color@0.0.4: + resolution: {integrity: sha512-ZNB4525U7BxT6v9C8LEtywyCgB4Pjnm7/bh+ru/Z9Ecxvg3fDjaJ6z305z9a61orQdbB1zqYHh5JbUqx4s4K0g==} + bidi-js@1.0.3: resolution: {integrity: sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==} + binary-extensions@2.3.0: + resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} + engines: {node: '>=8'} + + body@5.1.0: + resolution: {integrity: sha512-chUsBxGRtuElD6fmw1gHLpvnKdVLK302peeFa9ZqAEk8TyzZ3fygLyUEDDPTJvL9+Bor0dIwn6ePOsRM2y0zQQ==} + + boolbase@1.0.0: + resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} + + brace-expansion@1.1.14: + resolution: {integrity: sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + browserslist@4.28.2: resolution: {integrity: sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true + buffer@5.7.1: + resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} + + bytes@1.0.0: + resolution: {integrity: sha512-/x68VkHLeTl3/Ll8IvxdwzhrT+IyKc52e/oyHhA2RwqPqswSnjVbSddfPRwAsJtbilMAPSRWwAlpxdYsSWOTKQ==} + + call-bind-apply-helpers@1.0.2: + resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} + engines: {node: '>= 0.4'} + + call-bound@1.0.4: + resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} + engines: {node: '>= 0.4'} + caniuse-lite@1.0.30001792: resolution: {integrity: sha512-hVLMUZFgR4JJ6ACt1uEESvQN1/dBVqPAKY0hgrV70eN3391K6juAfTjKZLKvOMsx8PxA7gsY1/tLMMTcfFLLpw==} @@ -1532,23 +1656,85 @@ packages: resolution: {integrity: sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==} engines: {node: '>=18'} + cheerio-select@1.6.0: + resolution: {integrity: sha512-eq0GdBvxVFbqWgmCm7M3XGs1I8oLy/nExUnh6oLqmBditPO9AqQJrkslDpMun/hZ0yyTs8L0m85OHp4ho6Qm9g==} + + cheerio-select@2.1.0: + resolution: {integrity: sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==} + + cheerio@1.0.0: + resolution: {integrity: sha512-quS9HgjQpdaXOvsZz82Oz7uxtXiy6UIsIQcpBj7HRw2M63Skasm9qlDocAM7jNuaxdhpPU7c4kJN+gA5MCu4ww==} + engines: {node: '>=18.17'} + + cheerio@1.0.0-rc.10: + resolution: {integrity: sha512-g0J0q/O6mW8z5zxQ3A8E8J1hUgp4SMOvEoW/x84OwyHKe/Zccz83PVT4y5Crcr530FV6NgmKI1qvGTKVl9XXVw==} + engines: {node: '>= 6'} + + chokidar@3.6.0: + resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} + engines: {node: '>= 8.10.0'} + class-variance-authority@0.7.1: resolution: {integrity: sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==} + cliui@7.0.4: + resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} + clsx@2.1.1: resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} engines: {node: '>=6'} + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + commander@5.1.0: + resolution: {integrity: sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==} + engines: {node: '>= 6'} + + commander@6.2.1: + resolution: {integrity: sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==} + engines: {node: '>= 6'} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + continuable-cache@0.3.1: + resolution: {integrity: sha512-TF30kpKhTH8AGCG3dut0rdd/19B7Z+qCnrMoBLpyQu/2drZdNrrpcjPEoJeSVsQM+8KmWG5O56oPDjSSUsuTyA==} + convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + cp@0.2.0: + resolution: {integrity: sha512-4ftCvShHjIZG/zzomHyunNpBof3sOFTTmU6s6q9DdqAL/ANqrKV3pr6Z6kVfBI4hjn59DFLImrBqn7GuuMqSZA==} + + cpr@3.0.1: + resolution: {integrity: sha512-Xch4PXQ/KC8lJ+KfJ9JI6eG/nmppLrPPWg5Q+vh65Qr9EjuJEubxh/H/Le1TmCZ7+Xv7iJuNRqapyOFZB+wsxA==} + hasBin: true + + crc@3.8.0: + resolution: {integrity: sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==} + crelt@1.0.6: resolution: {integrity: sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==} + css-select@4.3.0: + resolution: {integrity: sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==} + + css-select@5.2.2: + resolution: {integrity: sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==} + css-tree@3.2.1: resolution: {integrity: sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA==} engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} + css-what@6.2.2: + resolution: {integrity: sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==} + engines: {node: '>= 6'} + css.escape@1.5.1: resolution: {integrity: sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==} @@ -1563,6 +1749,22 @@ packages: resolution: {integrity: sha512-euIQENZg6x8mj3fO6o9+fOW8MimUI4PpD/fZBhJfeioZVy9TUpM4UY7KjQNVZFlqwJ0UdzRDzkycB997HEq1BQ==} engines: {node: '>=20'} + debug@2.6.9: + resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + debug@3.2.7: + resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + debug@4.4.3: resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} engines: {node: '>=6.0'} @@ -1575,10 +1777,18 @@ packages: decimal.js@10.6.0: resolution: {integrity: sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==} + depd@2.0.0: + resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} + engines: {node: '>= 0.8'} + dequal@2.0.3: resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} engines: {node: '>=6'} + destroy@1.2.0: + resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + detect-libc@2.1.2: resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} engines: {node: '>=8'} @@ -1586,26 +1796,109 @@ packages: detect-node-es@1.1.0: resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==} + direction@0.1.5: + resolution: {integrity: sha512-HceXsAluGbXKCz2qCVbXFUH4Vn4eNMWxY5gzydMFMnS1zKSwvDASqLwcrYLIFDpwuZ63FUAqjDLEP1eicHt8DQ==} + hasBin: true + dom-accessibility-api@0.5.16: resolution: {integrity: sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==} dom-accessibility-api@0.6.3: resolution: {integrity: sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==} + dom-serializer@0.1.1: + resolution: {integrity: sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA==} + + dom-serializer@1.4.1: + resolution: {integrity: sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==} + + dom-serializer@2.0.0: + resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} + + domelementtype@1.3.1: + resolution: {integrity: sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==} + + domelementtype@2.3.0: + resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} + + domhandler@3.3.0: + resolution: {integrity: sha512-J1C5rIANUbuYK+FuFL98650rihynUOEzRLxW+90bKZRWB6A1X1Tf82GxR1qAWLyfNPRvjqfip3Q5tdYlmAa9lA==} + engines: {node: '>= 4'} + + domhandler@4.3.1: + resolution: {integrity: sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==} + engines: {node: '>= 4'} + + domhandler@5.0.3: + resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} + engines: {node: '>= 4'} + + domutils@2.8.0: + resolution: {integrity: sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==} + + domutils@3.2.2: + resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==} + + dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} + + ee-first@1.1.1: + resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} + electron-to-chromium@1.5.351: resolution: {integrity: sha512-9D7Iqx8RImSvCnOsj86rCH6eQjZFQoM04Jn6HnZVM0Nu/G58/gmKYQ1d12MZTbjQbQSTGI8nwEy07ErsA2slLA==} + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + encodeurl@2.0.0: + resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} + engines: {node: '>= 0.8'} + + encoding-sniffer@0.2.1: + resolution: {integrity: sha512-5gvq20T6vfpekVtqrYQsSCFZ1wEg5+wW0/QaZMWkFr6BqD3NfKs0rLCx4rrVlSWJeZb5NBJgVLswK/w2MWU+Gw==} + enhanced-resolve@5.21.0: resolution: {integrity: sha512-otxSQPw4lkOZWkHpB3zaEQs6gWYEsmX4xQF68ElXC/TWvGxGMSGOvoNbaLXm6/cS/fSfHtsEdw90y20PCd+sCA==} engines: {node: '>=10.13.0'} + entities@1.1.2: + resolution: {integrity: sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==} + + entities@2.2.0: + resolution: {integrity: sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==} + + entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + + entities@6.0.1: + resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==} + engines: {node: '>=0.12'} + entities@8.0.0: resolution: {integrity: sha512-zwfzJecQ/Uej6tusMqwAqU/6KL2XaB2VZ2Jg54Je6ahNBGNH6Ek6g3jjNCF0fG9EWQKGZNddNjU5F1ZQn/sBnA==} engines: {node: '>=20.19.0'} + error@7.0.2: + resolution: {integrity: sha512-UtVv4l5MhijsYUxPJo4390gzfZvAnTHreNnDjnTZaKIiZ/SemXxAhBkYSKtWa5RtBXbLP8tMgn/n0RUa/H7jXw==} + + es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + es-module-lexer@2.1.0: resolution: {integrity: sha512-n27zTYMjYu1aj4MjCWzSP7G9r75utsaoc8m61weK+W8JMBGGQybd43GstCXZ3WNmSFtGT9wi59qQTW6mhTR5LQ==} + es-object-atoms@1.1.1: + resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} + engines: {node: '>= 0.4'} + esbuild@0.27.7: resolution: {integrity: sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w==} engines: {node: '>=18'} @@ -1615,13 +1908,47 @@ packages: resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} engines: {node: '>=6'} + escape-goat@3.0.0: + resolution: {integrity: sha512-w3PwNZJwRxlp47QGzhuEBldEqVHHhh8/tIPcl6ecf2Bou99cdAt0knihBV0Ecc7CGxYduXVBDheH1K2oADRlvw==} + engines: {node: '>=10'} + + escape-html@1.0.3: + resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + + esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + estree-walker@3.0.3: resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + etag@1.8.1: + resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} + engines: {node: '>= 0.6'} + expect-type@1.3.0: resolution: {integrity: sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==} engines: {node: '>=12.0.0'} + extend@3.0.2: + resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} + + fast-glob@3.3.3: + resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} + engines: {node: '>=8.6.0'} + + fastq@1.20.1: + resolution: {integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==} + + faye-websocket@0.10.0: + resolution: {integrity: sha512-Xhj93RXbMSq8urNCUq4p9l0P6hnySJ/7YNRhYNug0bLOuii7pKO7xQFb5mx9xZXWCar88pLPb805PvUkwrLZpQ==} + engines: {node: '>=0.4.0'} + fdir@6.5.0: resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} engines: {node: '>=12.0.0'} @@ -1631,6 +1958,27 @@ packages: picomatch: optional: true + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + + flat-cache@4.0.1: + resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} + engines: {node: '>=16'} + + flatted@3.4.2: + resolution: {integrity: sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==} + + fresh@0.5.2: + resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} + engines: {node: '>= 0.6'} + + front-matter@2.3.0: + resolution: {integrity: sha512-+gOIDsGWHVAiWSDfg3vpiHwkOrwO4XNS3YQH5DMmneLEPWzdCAnbSQCtxReF4yPK1nszLvAmLeR2SprnDQDnyQ==} + + fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + fsevents@2.3.2: resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} @@ -1641,21 +1989,98 @@ packages: engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} os: [darwin] + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + gensync@1.0.0-beta.2: resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} engines: {node: '>=6.9.0'} + get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + + get-intrinsic@1.3.0: + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} + engines: {node: '>= 0.4'} + get-nonce@1.0.1: resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==} engines: {node: '>=6'} + get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} + engines: {node: '>= 0.4'} + + gitbook-plugin-livereload@0.0.1: + resolution: {integrity: sha512-+5xinicId2ZcbP6jBTFfQBnjz8nhoBgcOuQfKTEM6Yg9fBsmo2mxY6ubrx1b5ozuIMyfDLkSihx97A7+X+EtQQ==} + + gitbook-plugin-lunr@1.2.0: + resolution: {integrity: sha512-QBfFLMZmoyOfLzc5aZrlRCkmzb9YcSjzdnyJFiRI/nX+Nd6kK1XyN4DLGnNSMHkRcJchcpWiQ6XGqSqo7e+d+g==} + engines: {gitbook: '>=3.0.0-pre.0'} + + gitbook-plugin-search@2.2.1: + resolution: {integrity: sha512-oP9jhaKFUVPo756G9ywuuI43YdkZClSjfpFzNKe/a/Rcn3oVsrAM/PjdQ+dt65KfZVo3iW1LY4WdiZnNqzRP8g==} + engines: {gitbook: '>=3.0.0-pre.0'} + + github-slugid@1.0.1: + resolution: {integrity: sha512-L5uVRzSM8jyWTgHUtaHwmymZW8S234JrIaOGotPK+0emNz9XsO6qqgw1KiI5YfP1SyBjG0ApNYU0vpb01teM9Q==} + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + glob@7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me + + gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} + graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} + + hasown@2.0.3: + resolution: {integrity: sha512-ej4AhfhfL2Q2zpMmLo7U1Uv9+PyhIZpgQLGT1F9miIGmiCJIoCgSmczFdrc97mWT4kVY72KA+WnnhJ5pghSvSg==} + engines: {node: '>= 0.4'} + + highlight.js@11.11.1: + resolution: {integrity: sha512-Xwwo44whKBVCYoliBQwaPvtd/2tYFkRQtXDWj1nackaV2JPXx3L0+Jvd8/qCJ2p+ML0/XVkJ2q+Mr+UVdpJK5w==} + engines: {node: '>=12.0.0'} + + honkit@6.1.7: + resolution: {integrity: sha512-/o3mojU4wYckkcguTlaCfwJiDPGGx+ndl9MKGCfcVj9sDkrwb3TYdEqI40muE9WTHAWu2JFdd8ymUkixEyPNiQ==} + hasBin: true + html-encoding-sniffer@6.0.0: resolution: {integrity: sha512-CV9TW3Y3f8/wT0BRFc1/KAVQ3TUHiXmaAb6VW9vtiMFf7SLoMd1PdAc4W3KFOFETBJUb90KatHqlsZMWV+R9Gg==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} + html-entities@1.2.0: + resolution: {integrity: sha512-0md7tlUUyb0BEQGsZzbqty1CgV6RESOoxdivt94AScqhBhYsPCCQCOaGvur/RospMjYpPJ7iFe3zw4Bu4SVA8g==} + engines: {'0': node >= 0.4.0} + + htmlparser2@5.0.1: + resolution: {integrity: sha512-vKZZra6CSe9qsJzh0BjBGXo8dvzNsq/oGvsjfRdOrrryfeD9UOBEEQdeoqCRmKZchF5h2zOBMQ6YuQ0uRUmdbQ==} + + htmlparser2@6.1.0: + resolution: {integrity: sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==} + + htmlparser2@9.1.0: + resolution: {integrity: sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==} + + http-errors@2.0.1: + resolution: {integrity: sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==} + engines: {node: '>= 0.8'} + + http-parser-js@0.5.10: + resolution: {integrity: sha512-Pysuw9XpUq5dVc/2SMHpuTY01RFl8fttgcyunjL7eEMhGM3cI4eOmiCycJDVCo/7O7ClfQD3SaI6ftDzqOXYMA==} + http-proxy-agent@7.0.2: resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==} engines: {node: '>= 14'} @@ -1664,13 +2089,79 @@ packages: resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} engines: {node: '>= 14'} + i18n-t@1.0.1: + resolution: {integrity: sha512-2NmZwpsnRTzpZfIP6Rcic16m5QBNVaIwVyU182+iatd6RNbWmGi74LTA/R/oDa58RZ87bHChLgWpmulEAoEruQ==} + + iconv-lite@0.6.3: + resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} + engines: {node: '>=0.10.0'} + + ieee754@1.2.1: + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} + + immutable@3.8.3: + resolution: {integrity: sha512-AUY/VyX0E5XlibOmWt10uabJzam1zlYjwiEgQSDc5+UIkFNaF9WM0JxXKaNMGf+F/ffUF+7kRKXM9A7C0xXqMg==} + engines: {node: '>=0.10.0'} + indent-string@4.0.0: resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} engines: {node: '>=8'} + inflight@1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + + is-core-module@2.16.2: + resolution: {integrity: sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA==} + engines: {node: '>= 0.4'} + + is-docker@2.2.1: + resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} + engines: {node: '>=8'} + hasBin: true + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + is-potential-custom-element-name@1.0.1: resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==} + is-wsl@2.2.0: + resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} + engines: {node: '>=8'} + + is@3.3.2: + resolution: {integrity: sha512-a2xr4E3s1PjDS8ORcGgXpWx6V+liNs+O3JRD2mb9aeugD7rtkkZ0zgLdYgw0tWsKhsdiezGYptSiMlVazCBTuQ==} + engines: {node: '>= 0.4'} + + isobject@0.2.0: + resolution: {integrity: sha512-VaWq6XYAsbvM0wf4dyBO7WH9D7GosB7ZZlqrawI9BBiTMINBeCyqSKBa35m870MY3O4aM31pYyZi9DfGrYMJrQ==} + engines: {node: '>=0.10.0'} + jiti@2.7.0: resolution: {integrity: sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==} hasBin: true @@ -1678,6 +2169,10 @@ packages: js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + js-yaml@3.14.2: + resolution: {integrity: sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==} + hasBin: true + jsdom@27.4.0: resolution: {integrity: sha512-mjzqwWRD9Y1J1KUi7W97Gja1bwOOM5Ug0EZ6UDK3xS7j7mndrkwozHtSblfomlzyB4NepioNt+B2sOSzczVgtQ==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} @@ -1692,11 +2187,32 @@ packages: engines: {node: '>=6'} hasBin: true + json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + + json-schema-defaults@0.1.1: + resolution: {integrity: sha512-6Q5YS7pSDCXUbtS9uAFE+uUgvE45dBHCMyhqe6liJmL+oIa4zbACSS6nr6Lh+73mN+MnWBCExtN3C14S7Jrm7w==} + json5@2.2.3: resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} engines: {node: '>=6'} hasBin: true + jsonschema@1.1.0: + resolution: {integrity: sha512-nQhT+ioA1XM8CpxJYlBfcUj6HF3f3f2KbLgV3tcxOt85RKpk2b0Do/C5BnCCCfdAarAjWRSFlln0Uanl4tBCHA==} + + juice@8.1.0: + resolution: {integrity: sha512-FLzurJrx5Iv1e7CfBSZH68dC04EEvXvvVvPYB7Vx1WAuhCp1ZPIMtqxc+WTWxVkpTIC2Ach/GAv0rQbtGf6YMA==} + engines: {node: '>=10.0.0'} + hasBin: true + + keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + + kramed@0.5.6: + resolution: {integrity: sha512-V4qwQAp8HPQPU6Ph9Q4bc+P+nKQWEGlWYLRDkK7n+CPaMi8/VRm9/R710tRmag4whLsnKR91CO9Ras/Rnff9bw==} + hasBin: true + lightningcss-android-arm64@1.32.0: resolution: {integrity: sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==} engines: {node: '>= 12.0.0'} @@ -1771,6 +2287,12 @@ packages: resolution: {integrity: sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==} engines: {node: '>= 12.0.0'} + livereload-js@2.4.0: + resolution: {integrity: sha512-XPQH8Z2GDP/Hwz2PCDrh2mth4yFejwA1OZ/81Ti3LgKyhDcEjsSsqFWZojHG0va/duGd+WyosY7eXLDoOyqcPw==} + + lodash@4.18.1: + resolution: {integrity: sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==} + lru-cache@11.3.6: resolution: {integrity: sha512-Gf/KoL3C/MlI7Bt0PGI9I+TeTC/I6r/csU58N4BSNc4lppLBeKsOdFYkK+dX0ABDUMJNfCHTyPpzwwO21Awd3A==} engines: {node: 20 || >=22} @@ -1778,11 +2300,17 @@ packages: lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + lru_map@0.4.1: + resolution: {integrity: sha512-I+lBvqMMFfqaV8CJCISjI3wbjmwVu/VyOoU7+qtu9d7ioW5klMgsTTiUOUp+DJvfTTzKXoPbyC6YfgkNcyPSOg==} + lucide-react@0.556.0: resolution: {integrity: sha512-iOb8dRk7kLaYBZhR2VlV1CeJGxChBgUthpSP8wom9jfj79qovgG6qcSdiy6vkoREKPnbUYzJsCn4o4PtG3Iy+A==} peerDependencies: react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0 + lunr@0.5.12: + resolution: {integrity: sha512-/EtfOyuNP7BLVKhDvLyKJkFvCup2vwcIwQXCuasZEFk7XUJ4/blztVuefeLapUb1I5uMGsosN9A8J9Mu9A6yBg==} + lz-string@1.5.0: resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} hasBin: true @@ -1790,13 +2318,62 @@ packages: magic-string@0.30.21: resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + mdn-data@2.27.1: resolution: {integrity: sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==} + memoize-one@5.2.1: + resolution: {integrity: sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==} + + mensch@0.3.4: + resolution: {integrity: sha512-IAeFvcOnV9V0Yk+bFhYR07O3yNina9ANIN5MoXBKYJ/RLYPurd2d0yw14MDhpr9/momp0WofT1bPUh3hkzdi/g==} + + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} + + mime@1.6.0: + resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} + engines: {node: '>=4'} + hasBin: true + + mime@2.6.0: + resolution: {integrity: sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==} + engines: {node: '>=4.0.0'} + hasBin: true + min-indent@1.0.1: resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} engines: {node: '>=4'} + minimatch@3.1.5: + resolution: {integrity: sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==} + + minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + + mkdirp@0.5.6: + resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} + hasBin: true + + mkdirp@1.0.4: + resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} + engines: {node: '>=10'} + hasBin: true + + moment@2.30.1: + resolution: {integrity: sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==} + + ms@2.0.0: + resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} + ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} @@ -1811,21 +2388,103 @@ packages: react: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc react-dom: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc + node-fetch@2.7.0: + resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + node-releases@2.0.38: resolution: {integrity: sha512-3qT/88Y3FbH/Kx4szpQQ4HzUbVrHPKTLVpVocKiLfoYvw9XSGOX2FmD2d6DrXbVYyAQTF2HeF6My8jmzx7/CRw==} + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + + nth-check@2.1.1: + resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} + + nunjucks-do@1.0.0: + resolution: {integrity: sha512-GQwENqZdcSbni0iYfEiNi3hs634JBSQdxnbnd9CetGkMYPnpjG1Jn5DT/qgAaC/STwMc7C4MSIJvLSNertclSg==} + + nunjucks@3.2.4: + resolution: {integrity: sha512-26XRV6BhkgK0VOxfbU5cQI+ICFUtMLixv1noZn1tGU38kQH5A5nmmbk/O45xdyBhD1esk47nKrY0mvQpZIhRjQ==} + engines: {node: '>= 6.9.0'} + hasBin: true + peerDependencies: + chokidar: ^3.3.0 + peerDependenciesMeta: + chokidar: + optional: true + + object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + + object-inspect@1.13.4: + resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} + engines: {node: '>= 0.4'} + + object-path@0.11.8: + resolution: {integrity: sha512-YJjNZrlXJFM42wTBn6zgOJVar9KFJvzx6sTWDte8sWZF//cnjl0BxHNpfZx+ZffXX63A9q0b1zsFiBX4g4X5KA==} + engines: {node: '>= 10.12.0'} + obug@2.1.1: resolution: {integrity: sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==} + omit-keys@0.1.0: + resolution: {integrity: sha512-JfTw3lVL54592o0Vb1frMN6DpS/wT8Uz/IWg1e0w2ZkjF4yyPYHGJAtdcBcUbp/RMf/LbdMzIz6QZ6ycaRCFUA==} + engines: {node: '>=0.10.0'} + + on-finished@2.4.1: + resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} + engines: {node: '>= 0.8'} + + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + + open@7.4.2: + resolution: {integrity: sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==} + engines: {node: '>=8'} + + parse5-htmlparser2-tree-adapter@6.0.1: + resolution: {integrity: sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==} + + parse5-htmlparser2-tree-adapter@7.1.0: + resolution: {integrity: sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==} + + parse5-parser-stream@7.1.2: + resolution: {integrity: sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==} + + parse5@6.0.1: + resolution: {integrity: sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==} + + parse5@7.3.0: + resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==} + parse5@8.0.1: resolution: {integrity: sha512-z1e/HMG90obSGeidlli3hj7cbocou0/wa5HacvI3ASx34PecNjNQeaHNo5WIZpWofN9kgkqV1q5YvXe3F0FoPw==} + path-is-absolute@1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + + path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + pathe@2.0.3: resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + picomatch@2.3.2: + resolution: {integrity: sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==} + engines: {node: '>=8.6'} + picomatch@4.0.4: resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==} engines: {node: '>=12'} @@ -1840,6 +2499,11 @@ packages: engines: {node: '>=18'} hasBin: true + pnpm@11.0.8: + resolution: {integrity: sha512-TECX4d0tQjcsTn+lp5H/KPx1pITHrBkuZLHfD97xdZS6mC+bT+2a37PHV4RvVlt5mydj+zcz0d4by4LPRmhJEg==} + engines: {node: '>=22.13'} + hasBin: true + postcss@8.5.14: resolution: {integrity: sha512-SoSL4+OSEtR99LHFZQiJLkT59C5B1amGO1NzTwj7TT1qCUgUO6hxOvzkOYxD+vMrXBM3XJIKzokoERdqQq/Zmg==} engines: {node: ^10 || ^12 || >=14} @@ -1852,6 +2516,21 @@ packages: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} + q@1.5.1: + resolution: {integrity: sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==} + engines: {node: '>=0.6.0', teleport: '>=0.2.0'} + deprecated: |- + You or someone you depend on is using Q, the JavaScript Promise library that gave JavaScript developers strong feelings about promises. They can almost certainly migrate to the native JavaScript promise now. Thank you literally everyone for joining me in this bet against the odds. Be excellent to each other. + + (For a CapTP with native promises, see @endo/eventual-send and @endo/captp) + + qs@6.15.1: + resolution: {integrity: sha512-6YHEFRL9mfgcAvql/XhwTvf5jKcOiiupt2FiJxHkiX1z4j7WL8J/jRHYLluORvc1XxB5rV20KoeK00gVJamspg==} + engines: {node: '>=0.6'} + + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + radix-ui@1.4.3: resolution: {integrity: sha512-aWizCQiyeAenIdUbqEpXgRA1ya65P13NKn/W8rWkcN0OPkRDxdBVLWnIEDsS2RpwCK2nobI7oMUSmexzTDyAmA==} peerDependencies: @@ -1865,6 +2544,15 @@ packages: '@types/react-dom': optional: true + range-parser@1.2.1: + resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} + engines: {node: '>= 0.6'} + + raw-body@1.1.7: + resolution: {integrity: sha512-WmJJU2e9Y6M5UzTOkHaM7xJGAPQD8PNzx3bAd2+uhZAim6wDk6dAZxPVYLF67XhbR4hmKGh33Lpmh4XWrCH5Mg==} + engines: {node: '>= 0.8.0'} + deprecated: No longer maintained. Please upgrade to a stable version. + react-dom@19.2.6: resolution: {integrity: sha512-0prMI+hvBbPjsWnxDLxlCGyM8PN6UuWjEUCYmZhO67xIV9Xasa/r/vDnq+Xyq4Lo27g8QSbO5YzARu0D1Sps3g==} peerDependencies: @@ -1911,19 +2599,53 @@ packages: resolution: {integrity: sha512-sfWGGfavi0xr8Pg0sVsyHMAOziVYKgPLNrS7ig+ivMNb3wbCBw3KxtflsGBAwD3gYQlE/AEZsTLgToRrSCjb0Q==} engines: {node: '>=0.10.0'} + readdirp@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + redent@3.0.0: resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==} engines: {node: '>=8'} + require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + require-from-string@2.0.2: resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} engines: {node: '>=0.10.0'} + resolve@1.22.12: + resolution: {integrity: sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==} + engines: {node: '>= 0.4'} + hasBin: true + + reusify@1.1.0: + resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + rimraf@2.7.1: + resolution: {integrity: sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==} + deprecated: Rimraf versions prior to v4 are no longer supported + hasBin: true + rollup@4.60.3: resolution: {integrity: sha512-pAQK9HalE84QSm4Po3EmWIZPd3FnjkShVkiMlz1iligWYkWQ7wHYd1PF/T7QZ5TVSD6uSTon5gBVMSM4JfBV+A==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + + safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + + safe-json-parse@1.0.1: + resolution: {integrity: sha512-o0JmTu17WGUaUOHa1l0FPGXKBfijbxK6qoHzlkihsDXxzBHvJcA7zgviKR92Xs841rX9pK16unfphLq0/KqX7A==} + + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + saxes@6.0.0: resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==} engines: {node: '>=v12.22.7'} @@ -1935,9 +2657,40 @@ packages: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true + semver@7.7.4: + resolution: {integrity: sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==} + engines: {node: '>=10'} + hasBin: true + + send@0.19.2: + resolution: {integrity: sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg==} + engines: {node: '>= 0.8.0'} + + setprototypeof@1.2.0: + resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} + + side-channel-list@1.0.1: + resolution: {integrity: sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==} + engines: {node: '>= 0.4'} + + side-channel-map@1.0.1: + resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} + engines: {node: '>= 0.4'} + + side-channel-weakmap@1.0.2: + resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} + engines: {node: '>= 0.4'} + + side-channel@1.1.0: + resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} + engines: {node: '>= 0.4'} + siginfo@2.0.0: resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + slick@1.12.2: + resolution: {integrity: sha512-4qdtOGcBjral6YIBCWJ0ljFSKNLz9KkhbWtuGvUyRowl1kxfuE1x/Z/aJcaiilpb3do9bl5K7/1h9XC5wWpY/A==} + sonner@2.0.7: resolution: {integrity: sha512-W6ZN4p58k8aDKA4XPcx2hpIQXBRAgyiWVkYhT7CvK6D3iAu7xjvVyhQHg2/iaKJZ1XVJ4r7XuwGL+WGEK37i9w==} peerDependencies: @@ -1948,12 +2701,33 @@ packages: resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} engines: {node: '>=0.10.0'} + sprintf-js@1.0.3: + resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + stackback@0.0.2: resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} + statuses@2.0.2: + resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} + engines: {node: '>= 0.8'} + std-env@4.1.0: resolution: {integrity: sha512-Rq7ybcX2RuC55r9oaPVEW7/xu3tj8u4GeBYHBWCychFtzMIr86A7e3PPEBPT37sHStKX3+TiX/Fr/ACmJLVlLQ==} + string-template@0.2.1: + resolution: {integrity: sha512-Yptehjogou2xm4UJbxJ4CxgZx12HBfeystp0y3x7s4Dj32ltVVG1Gg8YhKjHZkHicuKpZX/ffilA8505VbUbpw==} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + string_decoder@0.10.31: + resolution: {integrity: sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + strip-indent@3.0.0: resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==} engines: {node: '>=8'} @@ -1961,6 +2735,10 @@ packages: style-mod@4.1.3: resolution: {integrity: sha512-i/n8VsZydrugj3Iuzll8+x/00GH2vnYsk1eomD8QiRrSAeW6ItbCQDtfXCeJHd0iwiNagqjQkvpvREEPtW3IoQ==} + supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + symbol-tree@3.2.4: resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} @@ -1974,6 +2752,9 @@ packages: resolution: {integrity: sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==} engines: {node: '>=6'} + tiny-lr@1.1.1: + resolution: {integrity: sha512-44yhA3tsaRoMOjQQ+5v5mVdqef+kH6Qze9jTpqtVufgYjYt08zyZAwNwwVBj3i1rJMnR52IxOW0LK0vBzgAkuA==} + tinybench@2.9.0: resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} @@ -1996,10 +2777,25 @@ packages: resolution: {integrity: sha512-ELrFxuqsDdHUwoh0XxDbxuLD3Wnz49Z57IFvTtvWy1hJdcMZjXLIuonjilCiWHlT2GbE4Wlv1wKVTzDFnXH1aw==} hasBin: true + tmp@0.2.4: + resolution: {integrity: sha512-UdiSoX6ypifLmrfQ/XfiawN6hkjSBpCjhKxxZcWlUUmoXLaCKQU0bx4HF/tdDK2uzRuchf1txGvrWBzYREssoQ==} + engines: {node: '>=14.14'} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + toidentifier@1.0.1: + resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} + engines: {node: '>=0.6'} + tough-cookie@6.0.1: resolution: {integrity: sha512-LktZQb3IeoUWB9lqR5EWTHgW/VTITCXg4D21M+lvybRVdylLrRMnqaIONLVb5mav8vM19m44HIcGq4qASeu2Qw==} engines: {node: '>=16'} + tr46@0.0.3: + resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + tr46@6.0.0: resolution: {integrity: sha512-bLVMLPtstlZ4iMQHpFHTR7GAGj2jxi8Dg0s2h2MafAE4uSWF98FC/3MomU51iQAMf8/qDUbKWf5GxuvvVcXEhw==} engines: {node: '>=20'} @@ -2018,12 +2814,23 @@ packages: undici-types@7.16.0: resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==} + undici@6.25.0: + resolution: {integrity: sha512-ZgpWDC5gmNiuY9CnLVXEH8rl50xhRCuLNA97fAUnKi8RRuV4E6KG31pDTsLVUKnohJE0I3XDrTeEydAXRw47xg==} + engines: {node: '>=18.17'} + + unxhr@1.2.0: + resolution: {integrity: sha512-6cGpm8NFXPD9QbSNx0cD2giy7teZ6xOkCUH3U89WKVkL9N9rBrWjlCwhR94Re18ZlAop4MOc3WU1M3Hv/bgpIw==} + engines: {node: '>=8.11'} + update-browserslist-db@1.2.3: resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==} hasBin: true peerDependencies: browserslist: '>= 4.21.0' + urijs@1.19.11: + resolution: {integrity: sha512-HXgFDgDommxn5/bIv0cnQZsPhHDA90NPHD6+c/v21U5+Sx5hoP8+dP9IZXBU1gIfvdRfhG8cel9QNPeionfcCQ==} + use-callback-ref@1.3.3: resolution: {integrity: sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==} engines: {node: '>=10'} @@ -2049,6 +2856,10 @@ packages: peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + valid-data-url@3.0.1: + resolution: {integrity: sha512-jOWVmzVceKlVVdwjNSenT4PbGghU0SBIizAev8ofZVgivk/TVHXSbNL8LP6M3spZvkR9/QolkyJavGSX5Cs0UA==} + engines: {node: '>=10'} + vite@7.3.2: resolution: {integrity: sha512-Bby3NOsna2jsjfLVOHKes8sGwgl4TT0E6vvpYgnAYDIF/tie7MRaFthmKuHx1NSXjiTueXH3do80FMQgvEktRg==} engines: {node: ^20.19.0 || >=22.12.0} @@ -2141,10 +2952,30 @@ packages: resolution: {integrity: sha512-FlRLb15WwAOz1A9OQDbf6oOKKSiefi5VK0ZRF2wgH9xk3o5SnU11tNPaOnQuAh1Ucr66cwwvVXaeVRaFdRBt5g==} hasBin: true + web-resource-inliner@6.0.1: + resolution: {integrity: sha512-kfqDxt5dTB1JhqsCUQVFDj0rmY+4HLwGQIsLPbyrsN9y9WV/1oFDSx3BQ4GfCv9X+jVeQ7rouTqwK53rA/7t8A==} + engines: {node: '>=10.0.0'} + + webidl-conversions@3.0.1: + resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + webidl-conversions@8.0.1: resolution: {integrity: sha512-BMhLD/Sw+GbJC21C/UgyaZX41nPt8bUTg+jWyDeg7e7YN4xOM05YPSIXceACnXVtqyEw/LMClUQMtMZ+PGGpqQ==} engines: {node: '>=20'} + websocket-driver@0.7.4: + resolution: {integrity: sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==} + engines: {node: '>=0.8.0'} + + websocket-extensions@0.1.4: + resolution: {integrity: sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==} + engines: {node: '>=0.8.0'} + + whatwg-encoding@3.1.1: + resolution: {integrity: sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==} + engines: {node: '>=18'} + deprecated: Use @exodus/bytes instead for a more spec-conformant and faster implementation + whatwg-mimetype@4.0.0: resolution: {integrity: sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==} engines: {node: '>=18'} @@ -2157,11 +2988,21 @@ packages: resolution: {integrity: sha512-2ytDk0kiEj/yu90JOAp44PVPUkO9+jVhyf+SybKlRHSDlvOOZhdPIrr7xTH64l4WixO2cP+wQIcgujkGBPPz6g==} engines: {node: '>=20'} + whatwg-url@5.0.0: + resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + why-is-node-running@2.3.0: resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} engines: {node: '>=8'} hasBin: true + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + ws@8.20.0: resolution: {integrity: sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA==} engines: {node: '>=10.0.0'} @@ -2181,9 +3022,25 @@ packages: xmlchars@2.2.0: resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==} + xtend@4.0.2: + resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} + engines: {node: '>=0.4'} + + y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + yallist@3.1.1: resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + yargs-parser@20.2.9: + resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==} + engines: {node: '>=10'} + + yargs@16.2.0: + resolution: {integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==} + engines: {node: '>=10'} + snapshots: '@acemir/cssom@0.9.31': {} @@ -2208,6 +3065,16 @@ snapshots: '@asamuzakjp/nwsapi@2.3.9': {} + '@asciidoctor/cli@3.5.0(@asciidoctor/core@2.2.9)': + dependencies: + '@asciidoctor/core': 2.2.9 + yargs: 16.2.0 + + '@asciidoctor/core@2.2.9': + dependencies: + asciidoctor-opal-runtime: 0.3.4 + unxhr: 1.2.0 + '@babel/code-frame@7.29.0': dependencies: '@babel/helper-validator-identifier': 7.28.5 @@ -2467,6 +3334,30 @@ snapshots: '@floating-ui/utils@0.2.11': {} + '@honkit/asciidoc@6.1.7': + dependencies: + '@honkit/html': 6.1.7 + asciidoctor: 2.2.9 + + '@honkit/honkit-plugin-fontsettings@6.1.7': {} + + '@honkit/honkit-plugin-highlight@6.1.7': + dependencies: + highlight.js: 11.11.1 + + '@honkit/honkit-plugin-theme-default@6.1.7': {} + + '@honkit/html@6.1.7': + dependencies: + cheerio: 1.0.0 + lodash: 4.18.1 + + '@honkit/markdown-legacy@6.1.7': + dependencies: + '@honkit/html': 6.1.7 + kramed: 0.5.6 + lodash: 4.18.1 + '@jridgewell/gen-mapping@0.3.13': dependencies: '@jridgewell/sourcemap-codec': 1.5.5 @@ -2498,6 +3389,18 @@ snapshots: '@marijn/find-cluster-break@1.0.2': {} + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.20.1 + '@playwright/test@1.59.1': dependencies: playwright: 1.59.1 @@ -3525,12 +4428,29 @@ snapshots: convert-source-map: 2.0.0 tinyrainbow: 3.1.0 + a-sync-waterfall@1.0.1: {} + agent-base@7.1.4: {} + ansi-colors@4.1.3: {} + ansi-regex@5.0.1: {} + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + ansi-styles@5.2.0: {} + anymatch@3.1.3: + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.2 + + argparse@1.0.10: + dependencies: + sprintf-js: 1.0.3 + aria-hidden@1.2.6: dependencies: tslib: 2.8.1 @@ -3541,14 +4461,54 @@ snapshots: aria-query@5.3.2: {} + array-difference@0.0.1: {} + + asap@2.0.6: {} + + asciidoctor-opal-runtime@0.3.4: + dependencies: + fast-glob: 3.3.3 + unxhr: 1.2.0 + + asciidoctor@2.2.9: + dependencies: + '@asciidoctor/cli': 3.5.0(@asciidoctor/core@2.2.9) + '@asciidoctor/core': 2.2.9 + assertion-error@2.0.1: {} + balanced-match@1.0.2: {} + + base64-js@1.5.1: {} + baseline-browser-mapping@2.10.27: {} + bash-color@0.0.4: {} + bidi-js@1.0.3: dependencies: require-from-string: 2.0.2 + binary-extensions@2.3.0: {} + + body@5.1.0: + dependencies: + continuable-cache: 0.3.1 + error: 7.0.2 + raw-body: 1.1.7 + safe-json-parse: 1.0.1 + + boolbase@1.0.0: {} + + brace-expansion@1.1.14: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + browserslist@4.28.2: dependencies: baseline-browser-mapping: 2.10.27 @@ -3557,25 +4517,146 @@ snapshots: node-releases: 2.0.38 update-browserslist-db: 1.2.3(browserslist@4.28.2) + buffer@5.7.1: + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + + bytes@1.0.0: {} + + call-bind-apply-helpers@1.0.2: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + + call-bound@1.0.4: + dependencies: + call-bind-apply-helpers: 1.0.2 + get-intrinsic: 1.3.0 + caniuse-lite@1.0.30001792: {} chai@6.2.2: {} + cheerio-select@1.6.0: + dependencies: + css-select: 4.3.0 + css-what: 6.2.2 + domelementtype: 2.3.0 + domhandler: 4.3.1 + domutils: 2.8.0 + + cheerio-select@2.1.0: + dependencies: + boolbase: 1.0.0 + css-select: 5.2.2 + css-what: 6.2.2 + domelementtype: 2.3.0 + domhandler: 5.0.3 + domutils: 3.2.2 + + cheerio@1.0.0: + dependencies: + cheerio-select: 2.1.0 + dom-serializer: 2.0.0 + domhandler: 5.0.3 + domutils: 3.2.2 + encoding-sniffer: 0.2.1 + htmlparser2: 9.1.0 + parse5: 7.3.0 + parse5-htmlparser2-tree-adapter: 7.1.0 + parse5-parser-stream: 7.1.2 + undici: 6.25.0 + whatwg-mimetype: 4.0.0 + + cheerio@1.0.0-rc.10: + dependencies: + cheerio-select: 1.6.0 + dom-serializer: 1.4.1 + domhandler: 4.3.1 + htmlparser2: 6.1.0 + parse5: 6.0.1 + parse5-htmlparser2-tree-adapter: 6.0.1 + tslib: 2.8.1 + + chokidar@3.6.0: + dependencies: + anymatch: 3.1.3 + braces: 3.0.3 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + class-variance-authority@0.7.1: dependencies: clsx: 2.1.1 + cliui@7.0.4: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + clsx@2.1.1: {} + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + + commander@5.1.0: {} + + commander@6.2.1: {} + + concat-map@0.0.1: {} + + continuable-cache@0.3.1: {} + convert-source-map@2.0.0: {} + cp@0.2.0: {} + + cpr@3.0.1: + dependencies: + graceful-fs: 4.2.11 + minimist: 1.2.8 + mkdirp: 0.5.6 + rimraf: 2.7.1 + + crc@3.8.0: + dependencies: + buffer: 5.7.1 + crelt@1.0.6: {} + css-select@4.3.0: + dependencies: + boolbase: 1.0.0 + css-what: 6.2.2 + domhandler: 4.3.1 + domutils: 2.8.0 + nth-check: 2.1.1 + + css-select@5.2.2: + dependencies: + boolbase: 1.0.0 + css-what: 6.2.2 + domhandler: 5.0.3 + domutils: 3.2.2 + nth-check: 2.1.1 + css-tree@3.2.1: dependencies: mdn-data: 2.27.1 source-map-js: 1.2.1 + css-what@6.2.2: {} + css.escape@1.5.1: {} cssstyle@5.3.7: @@ -3592,33 +4673,130 @@ snapshots: whatwg-mimetype: 5.0.0 whatwg-url: 15.1.0 + debug@2.6.9: + dependencies: + ms: 2.0.0 + + debug@3.2.7: + dependencies: + ms: 2.1.3 + debug@4.4.3: dependencies: ms: 2.1.3 decimal.js@10.6.0: {} + depd@2.0.0: {} + dequal@2.0.3: {} + destroy@1.2.0: {} + detect-libc@2.1.2: {} detect-node-es@1.1.0: {} + direction@0.1.5: {} + dom-accessibility-api@0.5.16: {} dom-accessibility-api@0.6.3: {} + dom-serializer@0.1.1: + dependencies: + domelementtype: 1.3.1 + entities: 1.1.2 + + dom-serializer@1.4.1: + dependencies: + domelementtype: 2.3.0 + domhandler: 4.3.1 + entities: 2.2.0 + + dom-serializer@2.0.0: + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + entities: 4.5.0 + + domelementtype@1.3.1: {} + + domelementtype@2.3.0: {} + + domhandler@3.3.0: + dependencies: + domelementtype: 2.3.0 + + domhandler@4.3.1: + dependencies: + domelementtype: 2.3.0 + + domhandler@5.0.3: + dependencies: + domelementtype: 2.3.0 + + domutils@2.8.0: + dependencies: + dom-serializer: 1.4.1 + domelementtype: 2.3.0 + domhandler: 4.3.1 + + domutils@3.2.2: + dependencies: + dom-serializer: 2.0.0 + domelementtype: 2.3.0 + domhandler: 5.0.3 + + dunder-proto@1.0.1: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 + + ee-first@1.1.1: {} + electron-to-chromium@1.5.351: {} + emoji-regex@8.0.0: {} + + encodeurl@2.0.0: {} + + encoding-sniffer@0.2.1: + dependencies: + iconv-lite: 0.6.3 + whatwg-encoding: 3.1.1 + enhanced-resolve@5.21.0: dependencies: graceful-fs: 4.2.11 tapable: 2.3.3 + entities@1.1.2: {} + + entities@2.2.0: {} + + entities@4.5.0: {} + + entities@6.0.1: {} + entities@8.0.0: {} + error@7.0.2: + dependencies: + string-template: 0.2.1 + xtend: 4.0.2 + + es-define-property@1.0.1: {} + + es-errors@1.3.0: {} + es-module-lexer@2.1.0: {} + es-object-atoms@1.1.1: + dependencies: + es-errors: 1.3.0 + esbuild@0.27.7: optionalDependencies: '@esbuild/aix-ppc64': 0.27.7 @@ -3650,34 +4828,227 @@ snapshots: escalade@3.2.0: {} + escape-goat@3.0.0: {} + + escape-html@1.0.3: {} + + escape-string-regexp@4.0.0: {} + + esprima@4.0.1: {} + estree-walker@3.0.3: dependencies: '@types/estree': 1.0.8 + etag@1.8.1: {} + expect-type@1.3.0: {} + extend@3.0.2: {} + + fast-glob@3.3.3: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + + fastq@1.20.1: + dependencies: + reusify: 1.1.0 + + faye-websocket@0.10.0: + dependencies: + websocket-driver: 0.7.4 + fdir@6.5.0(picomatch@4.0.4): optionalDependencies: picomatch: 4.0.4 + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + flat-cache@4.0.1: + dependencies: + flatted: 3.4.2 + keyv: 4.5.4 + + flatted@3.4.2: {} + + fresh@0.5.2: {} + + front-matter@2.3.0: + dependencies: + js-yaml: 3.14.2 + + fs.realpath@1.0.0: {} + fsevents@2.3.2: optional: true fsevents@2.3.3: optional: true + function-bind@1.1.2: {} + gensync@1.0.0-beta.2: {} + get-caller-file@2.0.5: {} + + get-intrinsic@1.3.0: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + function-bind: 1.1.2 + get-proto: 1.0.1 + gopd: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.3 + math-intrinsics: 1.1.0 + get-nonce@1.0.1: {} + get-proto@1.0.1: + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.1.1 + + gitbook-plugin-livereload@0.0.1: {} + + gitbook-plugin-lunr@1.2.0: + dependencies: + gitbook-plugin-search: 2.2.1 + html-entities: 1.2.0 + lunr: 0.5.12 + + gitbook-plugin-search@2.2.1: {} + + github-slugid@1.0.1: {} + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + glob@7.2.3: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.5 + once: 1.4.0 + path-is-absolute: 1.0.1 + + gopd@1.2.0: {} + graceful-fs@4.2.11: {} + has-symbols@1.1.0: {} + + hasown@2.0.3: + dependencies: + function-bind: 1.1.2 + + highlight.js@11.11.1: {} + + honkit@6.1.7: + dependencies: + '@honkit/asciidoc': 6.1.7 + '@honkit/honkit-plugin-fontsettings': 6.1.7 + '@honkit/honkit-plugin-highlight': 6.1.7 + '@honkit/honkit-plugin-theme-default': 6.1.7 + '@honkit/html': 6.1.7 + '@honkit/markdown-legacy': 6.1.7 + bash-color: 0.0.4 + cheerio: 1.0.0 + chokidar: 3.6.0 + commander: 5.1.0 + cp: 0.2.0 + cpr: 3.0.1 + crc: 3.8.0 + destroy: 1.2.0 + direction: 0.1.5 + dom-serializer: 0.1.1 + error: 7.0.2 + escape-html: 1.0.3 + escape-string-regexp: 4.0.0 + extend: 3.0.2 + flat-cache: 4.0.1 + front-matter: 2.3.0 + gitbook-plugin-livereload: 0.0.1 + gitbook-plugin-lunr: 1.2.0 + gitbook-plugin-search: 2.2.1 + github-slugid: 1.0.1 + i18n-t: 1.0.1 + ignore: 5.3.2 + immutable: 3.8.3 + is: 3.3.2 + js-yaml: 3.14.2 + json-schema-defaults: 0.1.1 + jsonschema: 1.1.0 + juice: 8.1.0 + lru_map: 0.4.1 + memoize-one: 5.2.1 + mkdirp: 1.0.4 + moment: 2.30.1 + nunjucks: 3.2.4(chokidar@3.6.0) + nunjucks-do: 1.0.0 + object-path: 0.11.8 + omit-keys: 0.1.0 + open: 7.4.2 + q: 1.5.1 + resolve: 1.22.12 + semver: 7.7.4 + send: 0.19.2 + tiny-lr: 1.1.1 + tmp: 0.2.4 + urijs: 1.19.11 + transitivePeerDependencies: + - encoding + - supports-color + html-encoding-sniffer@6.0.0: dependencies: '@exodus/bytes': 1.15.0 transitivePeerDependencies: - '@noble/hashes' + html-entities@1.2.0: {} + + htmlparser2@5.0.1: + dependencies: + domelementtype: 2.3.0 + domhandler: 3.3.0 + domutils: 2.8.0 + entities: 2.2.0 + + htmlparser2@6.1.0: + dependencies: + domelementtype: 2.3.0 + domhandler: 4.3.1 + domutils: 2.8.0 + entities: 2.2.0 + + htmlparser2@9.1.0: + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + domutils: 3.2.2 + entities: 4.5.0 + + http-errors@2.0.1: + dependencies: + depd: 2.0.0 + inherits: 2.0.4 + setprototypeof: 1.2.0 + statuses: 2.0.2 + toidentifier: 1.0.1 + + http-parser-js@0.5.10: {} + http-proxy-agent@7.0.2: dependencies: agent-base: 7.1.4 @@ -3692,14 +5063,68 @@ snapshots: transitivePeerDependencies: - supports-color + i18n-t@1.0.1: + dependencies: + lodash: 4.18.1 + + iconv-lite@0.6.3: + dependencies: + safer-buffer: 2.1.2 + + ieee754@1.2.1: {} + + ignore@5.3.2: {} + + immutable@3.8.3: {} + indent-string@4.0.0: {} + inflight@1.0.6: + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + + inherits@2.0.4: {} + + is-binary-path@2.1.0: + dependencies: + binary-extensions: 2.3.0 + + is-core-module@2.16.2: + dependencies: + hasown: 2.0.3 + + is-docker@2.2.1: {} + + is-extglob@2.1.1: {} + + is-fullwidth-code-point@3.0.0: {} + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-number@7.0.0: {} + is-potential-custom-element-name@1.0.1: {} + is-wsl@2.2.0: + dependencies: + is-docker: 2.2.1 + + is@3.3.2: {} + + isobject@0.2.0: {} + jiti@2.7.0: {} js-tokens@4.0.0: {} + js-yaml@3.14.2: + dependencies: + argparse: 1.0.10 + esprima: 4.0.1 + jsdom@27.4.0: dependencies: '@acemir/cssom': 0.9.31 @@ -3730,8 +5155,30 @@ snapshots: jsesc@3.1.0: {} + json-buffer@3.0.1: {} + + json-schema-defaults@0.1.1: {} + json5@2.2.3: {} + jsonschema@1.1.0: {} + + juice@8.1.0: + dependencies: + cheerio: 1.0.0-rc.10 + commander: 6.2.1 + mensch: 0.3.4 + slick: 1.12.2 + web-resource-inliner: 6.0.1 + transitivePeerDependencies: + - encoding + + keyv@4.5.4: + dependencies: + json-buffer: 3.0.1 + + kramed@0.5.6: {} + lightningcss-android-arm64@1.32.0: optional: true @@ -3781,26 +5228,67 @@ snapshots: lightningcss-win32-arm64-msvc: 1.32.0 lightningcss-win32-x64-msvc: 1.32.0 + livereload-js@2.4.0: {} + + lodash@4.18.1: {} + lru-cache@11.3.6: {} lru-cache@5.1.1: dependencies: yallist: 3.1.1 + lru_map@0.4.1: {} + lucide-react@0.556.0(react@19.2.6): dependencies: react: 19.2.6 + lunr@0.5.12: {} + lz-string@1.5.0: {} magic-string@0.30.21: dependencies: '@jridgewell/sourcemap-codec': 1.5.5 + math-intrinsics@1.1.0: {} + mdn-data@2.27.1: {} + memoize-one@5.2.1: {} + + mensch@0.3.4: {} + + merge2@1.4.1: {} + + micromatch@4.0.8: + dependencies: + braces: 3.0.3 + picomatch: 2.3.2 + + mime@1.6.0: {} + + mime@2.6.0: {} + min-indent@1.0.1: {} + minimatch@3.1.5: + dependencies: + brace-expansion: 1.1.14 + + minimist@1.2.8: {} + + mkdirp@0.5.6: + dependencies: + minimist: 1.2.8 + + mkdirp@1.0.4: {} + + moment@2.30.1: {} + + ms@2.0.0: {} + ms@2.1.3: {} nanoid@3.3.12: {} @@ -3810,18 +5298,87 @@ snapshots: react: 19.2.6 react-dom: 19.2.6(react@19.2.6) + node-fetch@2.7.0: + dependencies: + whatwg-url: 5.0.0 + node-releases@2.0.38: {} + normalize-path@3.0.0: {} + + nth-check@2.1.1: + dependencies: + boolbase: 1.0.0 + + nunjucks-do@1.0.0: {} + + nunjucks@3.2.4(chokidar@3.6.0): + dependencies: + a-sync-waterfall: 1.0.1 + asap: 2.0.6 + commander: 5.1.0 + optionalDependencies: + chokidar: 3.6.0 + + object-assign@4.1.1: {} + + object-inspect@1.13.4: {} + + object-path@0.11.8: {} + obug@2.1.1: {} + omit-keys@0.1.0: + dependencies: + array-difference: 0.0.1 + isobject: 0.2.0 + + on-finished@2.4.1: + dependencies: + ee-first: 1.1.1 + + once@1.4.0: + dependencies: + wrappy: 1.0.2 + + open@7.4.2: + dependencies: + is-docker: 2.2.1 + is-wsl: 2.2.0 + + parse5-htmlparser2-tree-adapter@6.0.1: + dependencies: + parse5: 6.0.1 + + parse5-htmlparser2-tree-adapter@7.1.0: + dependencies: + domhandler: 5.0.3 + parse5: 7.3.0 + + parse5-parser-stream@7.1.2: + dependencies: + parse5: 7.3.0 + + parse5@6.0.1: {} + + parse5@7.3.0: + dependencies: + entities: 6.0.1 + parse5@8.0.1: dependencies: entities: 8.0.0 + path-is-absolute@1.0.1: {} + + path-parse@1.0.7: {} + pathe@2.0.3: {} picocolors@1.1.1: {} + picomatch@2.3.2: {} + picomatch@4.0.4: {} playwright-core@1.59.1: {} @@ -3832,6 +5389,8 @@ snapshots: optionalDependencies: fsevents: 2.3.2 + pnpm@11.0.8: {} + postcss@8.5.14: dependencies: nanoid: 3.3.12 @@ -3846,6 +5405,14 @@ snapshots: punycode@2.3.1: {} + q@1.5.1: {} + + qs@6.15.1: + dependencies: + side-channel: 1.1.0 + + queue-microtask@1.2.3: {} + radix-ui@1.4.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6): dependencies: '@radix-ui/primitive': 1.1.3 @@ -3909,6 +5476,13 @@ snapshots: '@types/react': 19.2.14 '@types/react-dom': 19.2.3(@types/react@19.2.14) + range-parser@1.2.1: {} + + raw-body@1.1.7: + dependencies: + bytes: 1.0.0 + string_decoder: 0.10.31 + react-dom@19.2.6(react@19.2.6): dependencies: react: 19.2.6 @@ -3947,13 +5521,32 @@ snapshots: react@19.2.6: {} + readdirp@3.6.0: + dependencies: + picomatch: 2.3.2 + redent@3.0.0: dependencies: indent-string: 4.0.0 strip-indent: 3.0.0 + require-directory@2.1.1: {} + require-from-string@2.0.2: {} + resolve@1.22.12: + dependencies: + es-errors: 1.3.0 + is-core-module: 2.16.2 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + + reusify@1.1.0: {} + + rimraf@2.7.1: + dependencies: + glob: 7.2.3 + rollup@4.60.3: dependencies: '@types/estree': 1.0.8 @@ -3985,6 +5578,16 @@ snapshots: '@rollup/rollup-win32-x64-msvc': 4.60.3 fsevents: 2.3.3 + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + + safe-buffer@5.2.1: {} + + safe-json-parse@1.0.1: {} + + safer-buffer@2.1.2: {} + saxes@6.0.0: dependencies: xmlchars: 2.2.0 @@ -3993,8 +5596,60 @@ snapshots: semver@6.3.1: {} + semver@7.7.4: {} + + send@0.19.2: + dependencies: + debug: 2.6.9 + depd: 2.0.0 + destroy: 1.2.0 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + fresh: 0.5.2 + http-errors: 2.0.1 + mime: 1.6.0 + ms: 2.1.3 + on-finished: 2.4.1 + range-parser: 1.2.1 + statuses: 2.0.2 + transitivePeerDependencies: + - supports-color + + setprototypeof@1.2.0: {} + + side-channel-list@1.0.1: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + + side-channel-map@1.0.1: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + + side-channel-weakmap@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + side-channel-map: 1.0.1 + + side-channel@1.1.0: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + side-channel-list: 1.0.1 + side-channel-map: 1.0.1 + side-channel-weakmap: 1.0.2 + siginfo@2.0.0: {} + slick@1.12.2: {} + sonner@2.0.7(react-dom@19.2.6(react@19.2.6))(react@19.2.6): dependencies: react: 19.2.6 @@ -4002,16 +5657,36 @@ snapshots: source-map-js@1.2.1: {} + sprintf-js@1.0.3: {} + stackback@0.0.2: {} + statuses@2.0.2: {} + std-env@4.1.0: {} + string-template@0.2.1: {} + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + string_decoder@0.10.31: {} + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + strip-indent@3.0.0: dependencies: min-indent: 1.0.1 style-mod@4.1.3: {} + supports-preserve-symlinks-flag@1.0.0: {} + symbol-tree@3.2.4: {} tailwind-merge@3.5.0: {} @@ -4020,6 +5695,17 @@ snapshots: tapable@2.3.3: {} + tiny-lr@1.1.1: + dependencies: + body: 5.1.0 + debug: 3.2.7 + faye-websocket: 0.10.0 + livereload-js: 2.4.0 + object-assign: 4.1.1 + qs: 6.15.1 + transitivePeerDependencies: + - supports-color + tinybench@2.9.0: {} tinyexec@1.1.2: {} @@ -4037,10 +5723,20 @@ snapshots: dependencies: tldts-core: 7.0.30 + tmp@0.2.4: {} + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + toidentifier@1.0.1: {} + tough-cookie@6.0.1: dependencies: tldts: 7.0.30 + tr46@0.0.3: {} + tr46@6.0.0: dependencies: punycode: 2.3.1 @@ -4053,12 +5749,18 @@ snapshots: undici-types@7.16.0: {} + undici@6.25.0: {} + + unxhr@1.2.0: {} + update-browserslist-db@1.2.3(browserslist@4.28.2): dependencies: browserslist: 4.28.2 escalade: 3.2.0 picocolors: 1.1.1 + urijs@1.19.11: {} + use-callback-ref@1.3.3(@types/react@19.2.14)(react@19.2.6): dependencies: react: 19.2.6 @@ -4078,6 +5780,8 @@ snapshots: dependencies: react: 19.2.6 + valid-data-url@3.0.1: {} + vite@7.3.2(@types/node@24.12.2)(jiti@2.7.0)(lightningcss@1.32.0): dependencies: esbuild: 0.27.7 @@ -4130,8 +5834,33 @@ snapshots: dependencies: '@types/emscripten': 1.39.10 + web-resource-inliner@6.0.1: + dependencies: + ansi-colors: 4.1.3 + escape-goat: 3.0.0 + htmlparser2: 5.0.1 + mime: 2.6.0 + node-fetch: 2.7.0 + valid-data-url: 3.0.1 + transitivePeerDependencies: + - encoding + + webidl-conversions@3.0.1: {} + webidl-conversions@8.0.1: {} + websocket-driver@0.7.4: + dependencies: + http-parser-js: 0.5.10 + safe-buffer: 5.2.1 + websocket-extensions: 0.1.4 + + websocket-extensions@0.1.4: {} + + whatwg-encoding@3.1.1: + dependencies: + iconv-lite: 0.6.3 + whatwg-mimetype@4.0.0: {} whatwg-mimetype@5.0.0: {} @@ -4141,15 +5870,44 @@ snapshots: tr46: 6.0.0 webidl-conversions: 8.0.1 + whatwg-url@5.0.0: + dependencies: + tr46: 0.0.3 + webidl-conversions: 3.0.1 + why-is-node-running@2.3.0: dependencies: siginfo: 2.0.0 stackback: 0.0.2 + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrappy@1.0.2: {} + ws@8.20.0: {} xml-name-validator@5.0.0: {} xmlchars@2.2.0: {} + xtend@4.0.2: {} + + y18n@5.0.8: {} + yallist@3.1.1: {} + + yargs-parser@20.2.9: {} + + yargs@16.2.0: + dependencies: + cliui: 7.0.4 + escalade: 3.2.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 20.2.9 diff --git a/scripts/build-docs.mjs b/scripts/build-docs.mjs new file mode 100644 index 0000000..167a17b --- /dev/null +++ b/scripts/build-docs.mjs @@ -0,0 +1,24 @@ +import { existsSync, mkdirSync, rmSync } from "node:fs" +import { resolve } from "node:path" +import { spawnSync } from "node:child_process" + +const projectRoot = resolve(import.meta.dirname, "..") +const docsSource = resolve(projectRoot, "doc") +const docsOutput = resolve(projectRoot, "web/public/docs") + +if (!existsSync(docsSource)) { + console.error(`Docs source directory not found: ${docsSource}`) + process.exit(1) +} + +rmSync(docsOutput, { recursive: true, force: true }) +mkdirSync(docsOutput, { recursive: true }) + +const result = spawnSync("pnpm", ["exec", "honkit", "build", docsSource, docsOutput], { + cwd: projectRoot, + stdio: "inherit", +}) + +if (result.status !== 0) { + process.exit(result.status ?? 1) +} diff --git a/src/presets.lua b/src/presets.lua index 5c700b7..deeaf4f 100644 --- a/src/presets.lua +++ b/src/presets.lua @@ -111,7 +111,7 @@ return { { Name = "NumbersToExpressions", Settings = { - NumberRepresentationMutaton = true + NumberRepresentationMutation = true }, }, { Name = "WrapInFunction", Settings = {} }, diff --git a/src/prometheus/step.lua b/src/prometheus/step.lua index e6f5281..59e6f48 100644 --- a/src/prometheus/step.lua +++ b/src/prometheus/step.lua @@ -23,33 +23,43 @@ function Step:new(settings) end for key, data in pairs(self.SettingsDescriptor) do - if settings[key] == nil then + local settingValue = settings[key]; + if settingValue == nil and type(data.aliases) == "table" then + for _, alias in ipairs(data.aliases) do + if settings[alias] ~= nil then + settingValue = settings[alias]; + break; + end + end + end + + if settingValue == nil then if data.default == nil then logger:error(string.format("The Setting \"%s\" was not provided for the Step \"%s\"", key, self.Name)); end instance[key] = data.default; elseif(data.type == "enum") then local lookup = lookupify(data.values); - if not lookup[settings[key]] then + if not lookup[settingValue] then logger:error(string.format("Invalid value for the Setting \"%s\" of the Step \"%s\". It must be one of the following: %s", key, self.Name, table.concat(data, ", "))); end - instance[key] = settings[key]; - elseif(type(settings[key]) ~= data.type) then + instance[key] = settingValue; + elseif(type(settingValue) ~= data.type) then logger:error(string.format("Invalid value for the Setting \"%s\" of the Step \"%s\". It must be a %s", key, self.Name, data.type)); else if data.min then - if settings[key] < data.min then + if settingValue < data.min then logger:error(string.format("Invalid value for the Setting \"%s\" of the Step \"%s\". It must be at least %d", key, self.Name, data.min)); end end if data.max then - if settings[key] > data.max then + if settingValue > data.max then logger:error(string.format("Invalid value for the Setting \"%s\" of the Step \"%s\". The biggest allowed value is %d", key, self.Name, data.min)); end end - instance[key] = settings[key]; + instance[key] = settingValue; end end diff --git a/src/prometheus/steps/ConstantArray.lua b/src/prometheus/steps/ConstantArray.lua index f504eb1..0d7c2dc 100644 --- a/src/prometheus/steps/ConstantArray.lua +++ b/src/prometheus/steps/ConstantArray.lua @@ -23,13 +23,14 @@ ConstantArray.Description = "This Step will Extract all Constants and put them i ConstantArray.Name = "Constant Array"; ConstantArray.SettingsDescriptor = { - Treshold = { - name = "Treshold", + Threshold = { + name = "Threshold", description = "The relative amount of nodes that will be affected", type = "number", default = 1, min = 0, max = 1, + aliases = { "Treshold" }, }, StringsOnly = { name = "StringsOnly", @@ -49,17 +50,18 @@ ConstantArray.SettingsDescriptor = { type = "boolean", default = true, }, - LocalWrapperTreshold = { - name = "LocalWrapperTreshold", + LocalWrapperThreshold = { + name = "LocalWrapperThreshold", description = "The relative amount of nodes functions, that will get local wrappers", type = "number", default = 1, min = 0, max = 1, + aliases = { "LocalWrapperTreshold" }, }, LocalWrapperCount = { name = "LocalWrapperCount", - description = "The number of Local wrapper Functions per scope. This only applies if LocalWrapperTreshold is greater than 0", + description = "The number of Local wrapper Functions per scope. This only applies if LocalWrapperThreshold is greater than 0", type = "number", min = 0, max = 512, @@ -645,7 +647,7 @@ function ConstantArray:apply(ast, pipeline) -- Extract Constants visitast(ast, nil, function(node, data) -- Apply only to some nodes - if math.random() <= self.Treshold then + if math.random() <= self.Threshold then node.__apply_constant_array = true; if node.kind == AstKind.StringExpression then self:addConstant(node.value); @@ -674,7 +676,7 @@ function ConstantArray:apply(ast, pipeline) visitast(ast, function(node, data) -- Add Local Wrapper Functions - if self.LocalWrapperCount > 0 and node.kind == AstKind.Block and node.isFunctionBlock and math.random() <= self.LocalWrapperTreshold then + if self.LocalWrapperCount > 0 and node.kind == AstKind.Block and node.isFunctionBlock and math.random() <= self.LocalWrapperThreshold then local id = node.scope:addVariable() data.functionData.local_wrappers = { id = id; @@ -835,4 +837,4 @@ function ConstantArray:apply(ast, pipeline) self.lookup = nil; end -return ConstantArray; \ No newline at end of file +return ConstantArray; diff --git a/src/prometheus/steps/NumbersToExpressions.lua b/src/prometheus/steps/NumbersToExpressions.lua index 9285089..6d4b383 100644 --- a/src/prometheus/steps/NumbersToExpressions.lua +++ b/src/prometheus/steps/NumbersToExpressions.lua @@ -34,9 +34,10 @@ NumbersToExpressions.SettingsDescriptor = { max = 0.8, }, - NumberRepresentationMutaton = { + NumberRepresentationMutation = { type = "boolean", default = false, + aliases = { "NumberRepresentationMutaton" }, }, AllowedNumberRepresentations = { @@ -107,7 +108,7 @@ end function NumbersToExpressions:CreateNumberExpression(val, depth) if depth > 0 and math.random() >= self.InternalThreshold or depth > 15 then local format = self.AllowedNumberRepresentations[math.random(1, #self.AllowedNumberRepresentations)] - if not self.NumberRepresentationMutaton then + if not self.NumberRepresentationMutation then return Ast.NumberExpression(val) end diff --git a/web/src/App.tsx b/web/src/App.tsx index 90bcc4c..f216e80 100644 --- a/web/src/App.tsx +++ b/web/src/App.tsx @@ -1,4 +1,4 @@ -import { Check, Copy, Download, FileCode2, Github, Loader2, Play, RotateCcw } from "lucide-react" +import { BookText, Check, Copy, Download, FileCode2, Github, Loader2, Play, RotateCcw, Share2, Square } from "lucide-react" import { useEffect, useRef, useState } from "react" import { toast } from "sonner" @@ -28,6 +28,18 @@ print(message) ` const WORKER_TIMEOUT_MS = 90_000 +type ActiveJob = "idle" | "obfuscate" | "run-input" | "run-output" +type SharePayload = { + version: 1 + source: string + preset: PresetName + luaVersion: LuaVersion + prettyPrint: boolean + seed: number + outputHash: string | null +} +type LastObfuscation = Omit + function createSeed() { return Math.floor(crypto.getRandomValues(new Uint32Array(1))[0] % 2147483646) + 1 } @@ -50,10 +62,46 @@ function formatWorkerError(event: ErrorEvent): string { const detail = event.error instanceof Error ? `${event.error.name}: ${event.error.message}${event.error.stack ? `\n${event.error.stack}` : ""}` - : event.message || "Worker crashed while processing the obfuscation request." + : event.message || "Worker crashed while processing the request." return `${detail}${location}` } +function encodeBase64Url(input: string): string { + const bytes = new TextEncoder().encode(input) + let binary = "" + for (const byte of bytes) { + binary += String.fromCharCode(byte) + } + return btoa(binary).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, "") +} + +function decodeBase64Url(input: string): string { + const normalized = input.replace(/-/g, "+").replace(/_/g, "/") + const padding = "=".repeat((4 - (normalized.length % 4)) % 4) + const binary = atob(normalized + padding) + const bytes = Uint8Array.from(binary, (char) => char.charCodeAt(0)) + return new TextDecoder().decode(bytes) +} + +function fallbackHash(input: string): string { + // FNV-1a 32-bit fallback for environments where SubtleCrypto is unavailable. + let hash = 0x811c9dc5 + for (let i = 0; i < input.length; i += 1) { + hash ^= input.charCodeAt(i) + hash = Math.imul(hash, 0x01000193) + } + return `fnv1a32:${(hash >>> 0).toString(16).padStart(8, "0")}` +} + +async function sha256Hex(input: string): Promise { + if (!crypto.subtle) { + return fallbackHash(input) + } + const bytes = new TextEncoder().encode(input) + const digest = await crypto.subtle.digest("SHA-256", bytes) + return Array.from(new Uint8Array(digest), (byte) => byte.toString(16).padStart(2, "0")).join("") +} + export default function App() { const [source, setSource] = useState(initialSource) const [output, setOutput] = useState("") @@ -62,11 +110,21 @@ export default function App() { const [prettyPrint, setPrettyPrint] = useState(false) const [seed, setSeed] = useState(createSeed) const [logs, setLogs] = useState([]) - const [isRunning, setIsRunning] = useState(false) + const [activeJob, setActiveJob] = useState("idle") const [copied, setCopied] = useState(false) + const [lastObfuscation, setLastObfuscation] = useState(null) const workerRef = useRef(null) const requestIdRef = useRef(0) const workerUrlRef = useRef("") + const autoShareLoadedRef = useRef(false) + const pendingWorkerRejectsRef = useRef(new Set<(error: Error) => void>()) + + function rejectPendingWorkerRequests(message: string) { + for (const reject of pendingWorkerRejectsRef.current) { + reject(new Error(message)) + } + pendingWorkerRejectsRef.current.clear() + } function setupWorker(worker: Worker) { worker.addEventListener("error", (event: Event) => { @@ -74,7 +132,8 @@ export default function App() { const detail = formatWorkerError(errorEvent) console.error("Prometheus worker error event:", event) console.error("Prometheus worker detail:", detail) - setIsRunning(false) + rejectPendingWorkerRequests(detail) + setActiveJob("idle") setLogs((current) => [...current, { level: "error", message: detail }]) toast.error("Worker error") workerRef.current?.terminate() @@ -83,7 +142,8 @@ export default function App() { worker.addEventListener("messageerror", (event) => { console.error("Prometheus worker message error:", event) - setIsRunning(false) + rejectPendingWorkerRequests("Worker message decode failed.") + setActiveJob("idle") setLogs((current) => [...current, { level: "error", message: "Worker message decode failed." }]) toast.error("Worker message error") workerRef.current?.terminate() @@ -91,40 +151,33 @@ export default function App() { }) } - async function canLoadWorker(workerUrl: string): Promise<{ ok: boolean; message?: string }> { - if (window.location.protocol === "file:") { - return { - ok: false, - message: - "Worker cannot run from file://. Serve the app over http:// or https:// (for example with `pnpm --filter web dev` or `pnpm --filter web preview`).", - } - } + function createWorker() { + const worker = new Worker(new URL("./worker/prometheus.worker.ts", import.meta.url), { + type: "module", + }) + workerRef.current = worker + setupWorker(worker) + return worker + } - try { - const response = await fetch(workerUrl, { method: "GET", cache: "no-store" }) - if (!response.ok) { - return { - ok: false, - message: `Worker script request failed: ${response.status} ${response.statusText} (${workerUrl})`, - } - } - return { ok: true } - } catch (error) { - return { - ok: false, - message: `Worker script request threw: ${error instanceof Error ? error.message : String(error)} (${workerUrl})`, - } + function stopCurrentJob() { + if (activeJob === "idle") { + return } + + rejectPendingWorkerRequests("Execution stopped by user.") + workerRef.current?.terminate() + workerRef.current = null + createWorker() + setActiveJob("idle") + setLogs((current) => [...current, { level: "warn", message: "Execution stopped by user." }]) + toast("Execution stopped") } useEffect(() => { const workerUrl = new URL("./worker/prometheus.worker.ts", import.meta.url).toString() workerUrlRef.current = workerUrl - const worker = new Worker(new URL("./worker/prometheus.worker.ts", import.meta.url), { - type: "module", - }) - workerRef.current = worker - setupWorker(worker) + createWorker() return () => { workerRef.current?.terminate() @@ -133,81 +186,229 @@ export default function App() { }, []) const canExport = output.trim().length > 0 + const isBusy = activeJob !== "idle" + const isObfuscating = activeJob === "obfuscate" + const isRunningInput = activeJob === "run-input" + const isRunningOutput = activeJob === "run-output" + const docsHref = `${import.meta.env.BASE_URL}docs/index.html` + + async function sendWorkerRequest(request: WorkerRequest): Promise { + try { + let worker = workerRef.current + if (window.location.protocol === "file:") { + return { + ok: false, + error: + "Worker cannot run from file://. Serve the app over http:// or https:// (for example with `pnpm --filter web dev` or `pnpm --filter web preview`).", + logs: [], + } + } + + if (!worker) { + worker = createWorker() + } + + return new Promise((resolve, reject) => { + let settled = false + const settle = (callback: () => void) => { + if (settled) { + return + } + settled = true + window.clearTimeout(timeout) + worker?.removeEventListener("message", listener) + pendingWorkerRejectsRef.current.delete(rejectRequest) + callback() + } + const rejectRequest = (error: Error) => settle(() => reject(error)) + const timeout = window.setTimeout(() => { + rejectRequest(new Error("Worker timed out before returning a result.")) + }, WORKER_TIMEOUT_MS) + + const listener = (event: MessageEvent) => { + const response = event.data + if (response.id !== request.id) { + return + } + if (response.type === "log") { + setLogs((current) => [...current, response.log]) + return + } + if (response.type !== "result") { + return + } + settle(() => resolve(response.result)) + } + pendingWorkerRejectsRef.current.add(rejectRequest) + worker?.addEventListener("message", listener) + worker?.postMessage(request) + }).catch((error): PrometheusResult => { + return { + ok: false, + error: error instanceof Error ? error.message : String(error), + logs: [], + } + }) + } catch (error) { + return { + ok: false, + error: error instanceof Error ? error.message : String(error), + logs: [], + } + } + } - async function obfuscate() { - let worker = workerRef.current - const workerUrl = - workerUrlRef.current || new URL("./worker/prometheus.worker.ts", import.meta.url).toString() - const preflight = await canLoadWorker(workerUrl) - if (!preflight.ok) { - setIsRunning(false) - setLogs([{ level: "error", message: preflight.message ?? "Worker preflight failed." }]) - toast.error("Worker load failed") + async function obfuscate(override?: { + sharedOutputHash?: string | null + options?: { + source: string + preset: PresetName + luaVersion: LuaVersion + prettyPrint: boolean + seed: number + } + }) { + if (isBusy && !override) { return } - if (!worker) { - worker = new Worker(new URL("./worker/prometheus.worker.ts", import.meta.url), { - type: "module", + setActiveJob("obfuscate") + try { + setLogs([]) + const id = ++requestIdRef.current + const options = override?.options ?? { source, preset, luaVersion, prettyPrint, seed } + const request: WorkerRequest = { + id, + action: "obfuscate", + options: { + source: options.source, + filename: "browser-input.lua", + preset: options.preset, + luaVersion: options.luaVersion, + prettyPrint: options.prettyPrint, + seed: options.seed, + }, + } + + const result = await sendWorkerRequest(request) + setLogs(result.logs) + + if (result.ok) { + const outputHash = await sha256Hex(result.output) + setLastObfuscation({ + source: options.source, + preset: options.preset, + luaVersion: options.luaVersion, + prettyPrint: options.prettyPrint, + seed: options.seed, + outputHash, + }) + setOutput(result.output) + setSeed(createSeed()) + if (typeof override?.sharedOutputHash === "string") { + if (outputHash !== override.sharedOutputHash) { + setOutput("") + setLogs((current) => [ + ...current, + { + level: "error", + message: + "This shared link was generated using an older version of Prometheus and no longer produces the intended obfuscated result.", + }, + ]) + toast.error("Shared link hash mismatch") + return + } + toast.success("Shared link loaded") + return + } + toast.success("Obfuscation complete") + return + } + + setLastObfuscation({ + source: options.source, + preset: options.preset, + luaVersion: options.luaVersion, + prettyPrint: options.prettyPrint, + seed: options.seed, + outputHash: null, }) - setupWorker(worker) - workerRef.current = worker + setOutput("") + setLogs([...result.logs, { level: "error", message: result.error }]) + toast.error("Obfuscation failed") + } catch (error) { + const message = error instanceof Error ? error.message : String(error) + setOutput("") + setLogs((current) => [...current, { level: "error", message }]) + toast.error("Obfuscation failed") + } finally { + setActiveJob("idle") } + } - if (!worker || isRunning) { + async function shareLink() { + if (!lastObfuscation) { return } - setIsRunning(true) + const payload: SharePayload = { + version: 1, + source: lastObfuscation.source, + preset: lastObfuscation.preset, + luaVersion: lastObfuscation.luaVersion, + prettyPrint: lastObfuscation.prettyPrint, + seed: lastObfuscation.seed, + outputHash: lastObfuscation.outputHash, + } + const encoded = encodeBase64Url(JSON.stringify(payload)) + const shareUrl = new URL(window.location.href) + shareUrl.searchParams.set("share", encoded) + window.history.replaceState({}, "", shareUrl) + await navigator.clipboard.writeText(shareUrl.toString()) + toast.success("Share link copied") + } + + async function runScript(kind: "input" | "output") { + if (isBusy) { + return + } + + const script = kind === "input" ? source : output + if (!script.trim()) { + setLogs([{ level: "warn", message: `No ${kind} script to run.` }]) + return + } + + setActiveJob(kind === "input" ? "run-input" : "run-output") setLogs([]) const id = ++requestIdRef.current const request: WorkerRequest = { id, - options: { - source, - filename: "browser-input.lua", - preset, - luaVersion, - prettyPrint, - seed, - }, + action: "runScript", + source: script, + filename: kind === "input" ? "browser-input.lua" : "browser-output.lua", } - const result = await new Promise((resolve, reject) => { - const timeout = window.setTimeout(() => { - worker.removeEventListener("message", listener) - reject(new Error("Worker timed out before returning a result.")) - }, WORKER_TIMEOUT_MS) - - const listener = (event: MessageEvent) => { - if (event.data.id !== id) { - return - } - window.clearTimeout(timeout) - worker.removeEventListener("message", listener) - resolve(event.data.result) - } - worker.addEventListener("message", listener) - worker.postMessage(request) - }).catch((error): PrometheusResult => { - return { - ok: false, - error: error instanceof Error ? error.message : String(error), - logs: [], - } - }) + const result = await sendWorkerRequest(request) + setActiveJob("idle") - setIsRunning(false) - setLogs(result.logs) if (result.ok) { - setOutput(result.output) - setSeed(createSeed()) - toast.success("Obfuscation complete") - } else { - setOutput("") - setLogs([...result.logs, { level: "error", message: result.error }]) - toast.error("Obfuscation failed") + setLogs((current) => { + if (current.length > 0) { + return current + } + if (result.logs.length > 0) { + return result.logs + } + return [{ level: "info", message: "Script finished without output." }] + }) + toast.success("Script execution complete") + return } + + setLogs([...result.logs, { level: "error", message: result.error }]) + toast.error("Script execution failed") } async function copyOutput() { @@ -219,9 +420,64 @@ export default function App() { window.setTimeout(() => setCopied(false), 1200) } + useEffect(() => { + if (autoShareLoadedRef.current || isBusy) { + return + } + + const encoded = new URL(window.location.href).searchParams.get("share") + if (!encoded) { + return + } + + const timeout = window.setTimeout(() => { + autoShareLoadedRef.current = true + let payload: SharePayload | null = null + try { + payload = JSON.parse(decodeBase64Url(encoded)) as SharePayload + } catch { + setLogs([{ level: "error", message: "Invalid shared link payload." }]) + toast.error("Invalid shared link") + return + } + + if ( + payload.version !== 1 || + !PRESETS.includes(payload.preset) || + !LUA_VERSIONS.includes(payload.luaVersion) || + typeof payload.source !== "string" || + typeof payload.prettyPrint !== "boolean" || + typeof payload.seed !== "number" || + (typeof payload.outputHash !== "string" && payload.outputHash !== null) + ) { + setLogs([{ level: "error", message: "Invalid shared link payload." }]) + toast.error("Invalid shared link") + return + } + + setSource(payload.source) + setPreset(payload.preset) + setLuaVersion(payload.luaVersion) + setPrettyPrint(payload.prettyPrint) + setSeed(Math.max(1, Math.floor(payload.seed))) + void obfuscate({ + sharedOutputHash: payload.outputHash, + options: { + source: payload.source, + preset: payload.preset, + luaVersion: payload.luaVersion, + prettyPrint: payload.prettyPrint, + seed: payload.seed, + }, + }) + }, 0) + + return () => window.clearTimeout(timeout) + }, [isBusy]) + return ( -
+
@@ -246,9 +502,16 @@ export default function App() { GitHub -
@@ -259,7 +522,7 @@ export default function App() {
setLuaVersion(value as LuaVersion)}> - + @@ -287,7 +550,7 @@ export default function App() {
- + @@ -300,11 +563,12 @@ export default function App() { type="number" min={1} value={seed} + disabled={isBusy} onChange={(event) => setSeed(Math.max(1, Number(event.target.value) || 1))} /> - @@ -329,14 +593,44 @@ export default function App() { Download output + + + + + Share link +
-
- - -