diff --git a/docs/.gitignore b/docs-i18n/.gitignore similarity index 100% rename from docs/.gitignore rename to docs-i18n/.gitignore diff --git a/docs/ru/config_ru.md b/docs-i18n/ru/config_ru.md similarity index 100% rename from docs/ru/config_ru.md rename to docs-i18n/ru/config_ru.md diff --git a/docs/ru/import_ru.md b/docs-i18n/ru/import_ru.md similarity index 100% rename from docs/ru/import_ru.md rename to docs-i18n/ru/import_ru.md diff --git a/docs/ru/key-binding_ru.md b/docs-i18n/ru/key-binding_ru.md similarity index 100% rename from docs/ru/key-binding_ru.md rename to docs-i18n/ru/key-binding_ru.md diff --git a/docs/ru/list_ru.md b/docs-i18n/ru/list_ru.md similarity index 100% rename from docs/ru/list_ru.md rename to docs-i18n/ru/list_ru.md diff --git a/docs/ru/search_ru.md b/docs-i18n/ru/search_ru.md similarity index 100% rename from docs/ru/search_ru.md rename to docs-i18n/ru/search_ru.md diff --git a/docs/ru/server_ru.md b/docs-i18n/ru/server_ru.md similarity index 100% rename from docs/ru/server_ru.md rename to docs-i18n/ru/server_ru.md diff --git a/docs/ru/shell-completions_ru.md b/docs-i18n/ru/shell-completions_ru.md similarity index 100% rename from docs/ru/shell-completions_ru.md rename to docs-i18n/ru/shell-completions_ru.md diff --git a/docs/ru/stats_ru.md b/docs-i18n/ru/stats_ru.md similarity index 100% rename from docs/ru/stats_ru.md rename to docs-i18n/ru/stats_ru.md diff --git a/docs/ru/sync_ru.md b/docs-i18n/ru/sync_ru.md similarity index 100% rename from docs/ru/sync_ru.md rename to docs-i18n/ru/sync_ru.md diff --git a/docs/zh-CN/README.md b/docs-i18n/zh-CN/README.md similarity index 100% rename from docs/zh-CN/README.md rename to docs-i18n/zh-CN/README.md diff --git a/docs/zh-CN/config.md b/docs-i18n/zh-CN/config.md similarity index 100% rename from docs/zh-CN/config.md rename to docs-i18n/zh-CN/config.md diff --git a/docs/zh-CN/docker.md b/docs-i18n/zh-CN/docker.md similarity index 100% rename from docs/zh-CN/docker.md rename to docs-i18n/zh-CN/docker.md diff --git a/docs/zh-CN/import.md b/docs-i18n/zh-CN/import.md similarity index 100% rename from docs/zh-CN/import.md rename to docs-i18n/zh-CN/import.md diff --git a/docs/zh-CN/k8s.md b/docs-i18n/zh-CN/k8s.md similarity index 100% rename from docs/zh-CN/k8s.md rename to docs-i18n/zh-CN/k8s.md diff --git a/docs/zh-CN/key-binding.md b/docs-i18n/zh-CN/key-binding.md similarity index 100% rename from docs/zh-CN/key-binding.md rename to docs-i18n/zh-CN/key-binding.md diff --git a/docs/zh-CN/list.md b/docs-i18n/zh-CN/list.md similarity index 100% rename from docs/zh-CN/list.md rename to docs-i18n/zh-CN/list.md diff --git a/docs/zh-CN/search.md b/docs-i18n/zh-CN/search.md similarity index 100% rename from docs/zh-CN/search.md rename to docs-i18n/zh-CN/search.md diff --git a/docs/zh-CN/server.md b/docs-i18n/zh-CN/server.md similarity index 100% rename from docs/zh-CN/server.md rename to docs-i18n/zh-CN/server.md diff --git a/docs/zh-CN/shell-completions.md b/docs-i18n/zh-CN/shell-completions.md similarity index 100% rename from docs/zh-CN/shell-completions.md rename to docs-i18n/zh-CN/shell-completions.md diff --git a/docs/zh-CN/stats.md b/docs-i18n/zh-CN/stats.md similarity index 100% rename from docs/zh-CN/stats.md rename to docs-i18n/zh-CN/stats.md diff --git a/docs/zh-CN/sync.md b/docs-i18n/zh-CN/sync.md similarity index 100% rename from docs/zh-CN/sync.md rename to docs-i18n/zh-CN/sync.md diff --git a/docs/docs/configuration/config.md b/docs/docs/configuration/config.md new file mode 100644 index 00000000..fa51ff3e --- /dev/null +++ b/docs/docs/configuration/config.md @@ -0,0 +1,733 @@ +# Config + +Atuin maintains two configuration files, stored in `~/.config/atuin/`. We store +data in `~/.local/share/atuin` (unless overridden by XDG\_\*). + +The full path to the config file would be `~/.config/atuin/config.toml` + +The config location can be overridden with ATUIN_CONFIG_DIR + +### `db_path` + +Default: `~/.local/share/atuin/history.db` + +The path to the Atuin SQLite database. + +```toml +db_path = "~/.history.db" +``` + +### `key_path` + +Default: `~/.local/share/atuin/key` + +The path to the Atuin encryption key. + +```toml +key_path = "~/.atuin-key" +``` + +### `session_path` + +Default: `~/.local/share/atuin/session` + +The path to the Atuin server session file. +This is essentially just an API token + +```toml +session_path = "~/.atuin-session" +``` + +### `dialect` + +Default: `us` + +This configures how the [stats](../reference/stats.md) command parses dates. It has two +possible values + +```toml +dialect = "uk" +``` + +or + +```toml +dialect = "us" +``` + +### `auto_sync` + +Default: `true` + +Configures whether or not to automatically sync, when logged in. + +```toml +auto_sync = true/false +``` + +### `update_check` + +Default: `true` + +Configures whether or not to automatically check for updates. + +```toml +update_check = true/false +``` + +### `sync_address` + +Default: `https://api.atuin.sh` + +The address of the server to sync with! + +```toml +sync_address = "https://api.atuin.sh" +``` + +### `sync_frequency` + +Default: `1h` + +How often to automatically sync with the server. This can be given in a +"human-readable" format. For example, `10s`, `20m`, `1h`, etc. + +If set to `0`, Atuin will sync after every command. Some servers may potentially +rate limit, which won't cause any issues. + +```toml +sync_frequency = "1h" +``` + +### `search_mode` + +Default: `fuzzy` + +Which search mode to use. Atuin supports "prefix", "fulltext", "fuzzy", and +"skim" search modes. + +Prefix mode searches for "query\*"; fulltext mode searches for "\*query\*"; +"fuzzy" applies the [fuzzy search syntax](#fuzzy-search-syntax); +"skim" applies the [skim search syntax](https://github.com/lotabout/skim#search-syntax). + +#### `fuzzy` search syntax + +The "fuzzy" search syntax is based on the +[fzf search syntax](https://github.com/junegunn/fzf#search-syntax). + +| Token | Match type | Description | +| --------- | -------------------------- | ------------------------------------ | +| `sbtrkt` | fuzzy-match | Items that match `sbtrkt` | +| `'wild` | exact-match (quoted) | Items that include `wild` | +| `^music` | prefix-exact-match | Items that start with `music` | +| `.mp3$` | suffix-exact-match | Items that end with `.mp3` | +| `!fire` | inverse-exact-match | Items that do not include `fire` | +| `!^music` | inverse-prefix-exact-match | Items that do not start with `music` | +| `!.mp3$` | inverse-suffix-exact-match | Items that do not end with `.mp3` | + +A single bar character term acts as an OR operator. For example, the following +query matches entries that start with `core` and end with either `go`, `rb`, +or `py`. + +``` +^core go$ | rb$ | py$ +``` + +### `filter_mode` + +Default: `global` + +The default filter to use when searching + +| Mode | Description | +| ---------------- | ------------------------------------------------------------ | +| global (default) | Search history from all hosts, all sessions, all directories | +| host | Search history just from this host | +| session | Search history just from the current session | +| directory | Search history just from the current directory | +| workspace | Search history just from the current git repository (>17.0) | + +Filter modes can still be toggled via ctrl-r + +```toml +filter_mode = "host" +``` + +### `search_mode_shell_up_key_binding` + +Atuin version: >= 17.0 + +Default: `fuzzy` + +The default searchmode to use when searching and being invoked from a shell up-key binding. + +Accepts exactly the same options as `search_mode` above + +```toml +search_mode_shell_up_key_binding = "fuzzy" +``` + +Defaults to the value specified for `search_mode`. + +### `filter_mode_shell_up_key_binding` + +Default: `global` + +The default filter to use when searching and being invoked from a shell up-key binding. + +Accepts exactly the same options as `filter_mode` above + +```toml +filter_mode_shell_up_key_binding = "session" +``` + +Defaults to the value specified for `filter_mode`. + +### `workspaces` + +Atuin version: >= 17.0 + +Default: `false` + +This flag enables a pseudo filter-mode named "workspace": the filter is automatically +activated when you are in a git repository. + +With workspace filtering enabled, Atuin will filter for commands executed in any directory +within a git repository tree. + +Filter modes can still be toggled via ctrl-r. + +### `style` + +Default: `compact` + +Which style to use. Possible values: `auto`, `full` and `compact`. + +- `compact`: + +![compact](https://user-images.githubusercontent.com/1710904/161623659-4fec047f-ea4b-471c-9581-861d2eb701a9.png) + +- `full`: + +![full](https://user-images.githubusercontent.com/1710904/161623547-42afbfa7-a3ef-4820-bacd-fcaf1e324969.png) + +This means that Atuin will automatically switch to `compact` mode when the terminal window is too short for `full` to display properly. + +### `invert` + +Atuin version: >= 17.0 + +Default: `false` + +Invert the UI - put the search bar at the top. + +```toml +invert = true/false +``` + +### `inline_height` + +Default: `40` + +Set the maximum number of lines Atuin's interface should take up. + +If set to `0`, Atuin will always take up as many lines as available (full screen). + +### `show_preview` + +Default: `true` + +Configure whether or not to show a preview of the selected command. + +Useful when the command is longer than the terminal width and is cut off. + +### `max_preview_height` + +Atuin version: >= 17.0 + +Default: `4` + +Configure the maximum height of the preview to show. + +Useful when you have long scripts in your history that you want to distinguish by more than the first few lines. + +### `show_help` + +Atuin version: >= 17.0 + +Default: `true` + +Configure whether or not to show the help row, which includes the current Atuin version (and whether an update is available), a keymap hint, and the total amount of commands in your history. + +### `show_tabs` + +Atuin version: >= 18.0 + +Default: `true` + +Configure whether or not to show tabs for search and inspect. + +### `exit_mode` + +Default: `return-original` + +What to do when the escape key is pressed when searching + +| Value | Behaviour | +| ------------------------- | ---------------------------------------------------------------- | +| return-original (default) | Set the command-line to the value it had before starting search | +| return-query | Set the command-line to the search query you have entered so far | + +Pressing ctrl+c or ctrl+d will always return the original command-line value. + +```toml +exit_mode = "return-query" +``` + +### `history_format` + +Default to `history list` + +The history format allows you to configure the default `history list` format - which can also be specified with the --format arg. + +The specified --format arg will prioritize the config when both are present + +More on [history list](../reference/list.md) + +### `history_filter` + +The history filter allows you to exclude commands from history tracking - maybe you want to keep ALL of your `curl` commands totally out of your shell history, or maybe just some matching a pattern. + +This supports regular expressions, so you can hide pretty much whatever you want! + +```toml +## Note that these regular expressions are unanchored, i.e. if they don't start +## with ^ or end with $, they'll match anywhere in the command. +history_filter = [ + "^secret-cmd", + "^innocuous-cmd .*--secret=.+" +] +``` + +### `cwd_filter` + +The cwd filter allows you to exclude directories from history tracking. + +This supports regular expressions, so you can hide pretty much whatever you want! + +```toml +## Note that these regular expressions are unanchored, i.e. if they don't start +## with ^ or end with $, they'll match anywhere in the command. +# cwd_filter = [ +# "^/very/secret/directory", +# ] +``` + +After updating that parameter, you can run [the prune command](../reference/prune.md) to remove old history entries that match the new filters. + +### `store_failed` + +Atuin version: >= 18.3.0 + +Default: `true` + +```toml +store_failed = true +``` + +Configures whether to store commands that failed (those with non-zero exit status) or not. + +### `secrets_filter` + +Atuin version: >= 17.0 + +Default: `true` + +```toml +secrets_filter = true +``` + +This matches history against a set of default regex, and will not save it if we get a match. Defaults include + +1. AWS key id +2. Github pat (old and new) +3. Slack oauth tokens (bot, user) +4. Slack webhooks +5. Stripe live/test keys +6. Atuin login command +7. Cloud environment variable patterns (`AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, `AZURE_STORAGE_CLASS_KEY`, `GOOGLE_SERVICE_ACCOUNT_KEY`) +8. Netlify authentication tokens +9. Npm pat +10. Pulumi pat + +### macOS Ctrl-n key shortcuts + +Default: `true` + +macOS does not have an ++alt++ key, although terminal emulators can often be configured to map the ++option++ key to be used as ++alt++. _However_, remapping ++option++ this way may prevent typing some characters, such as using ++option+3++ to type `#` on the British English layout. For such a scenario, set the `ctrl_n_shortcuts` option to `true` in your config file to replace ++alt+0++ to ++alt+9++ shortcuts with ++ctrl+0++ to ++ctrl+9++ instead: + +```toml +# Use Ctrl-0 .. Ctrl-9 instead of Alt-0 .. Alt-9 UI shortcuts +ctrl_n_shortcuts = true +``` + +### `network_timeout` + +Atuin version: >= 18.0 + +Default: `30` + +The max amount of time (in seconds) to wait for a network request. If any +operations with a sync server take longer than this, the code will fail - +rather than wait indefinitely. + +### `network_connect_timeout` + +Atuin version: >= 18.0 + +Default: `5` + +The max time (in seconds) we wait for a connection to become established with a +remote sync server. Any longer than this and the request will fail. + +### `local_timeout` + +Atuin version: >= 18.0 + +Default: `5` + +Timeout (in seconds) for acquiring a local database connection (sqlite). + +### `command_chaining` + +Atuin version: >= 18.8 + +Default: `false` + +Allows building a command chain with the `&&` or `||` operator. When enabled, opening atuin will search for the next command in the chain, and append to the current buffer. + +### `enter_accept` + +Atuin version: >= 17.0 + +Default: `false` + +Not supported by NuShell presently + +When set to true, Atuin will default to immediately executing a command rather +than the user having to press enter twice. Pressing tab will return to the +shell and give the user a chance to edit. + +This technically defaults to true for new users, but false for existing. We +have set `enter_accept = true` in the default config file. This is likely to +change to be the default for everyone in a later release. + +### `keymap_mode` + +Atuin version: >= 18.0 + +Default: `emacs` + +The initial keymap mode of the interactive Atuin search (e.g. started by the +keybindings in the shells). There are four supported values: `"emacs"`, +`"vim-normal"`, `"vim-insert"`, and `"auto"`. The keymap mode `"emacs"` is the +most basic one. In the keymap mode `"vim-normal"`, you may use ++k++ +and ++j++ to navigate the history list as in Vim, whilst pressing + +++i++ changes the keymap mode to `"vim-insert"`. In the keymap mode `"vim-insert"`, +you can search for a string as in the keymap mode `"emacs"`, while pressing ++esc++ +switches the keymap mode to `"vim-normal"`. When set to `"auto"`, the initial +keymap mode is automatically determined based on the shell's keymap that triggered +the Atuin search. `"auto"` is not supported by NuShell at present, where it will +always trigger the Atuin search with the keymap mode `"emacs"`. + +### `keymap_cursor` + +Atuin version: >= 18.0 + +Default: `(empty dictionary)` + +The terminal's cursor style associated with each keymap mode in the Atuin +search. This is specified by a dictionary whose keys and values being the +keymap names and the cursor styles, respectively. A key specifies one of the +keymaps from `emacs`, `vim_insert`, and `vim_normal`. A value is one of the +cursor styles, `default` or `{blink,steady}-{block,underline,bar}`. The +following is an example. + +```toml +keymap_cursor = { emacs = "blink-block", vim_insert = "blink-block", vim_normal = "steady-block" } +``` + +If the cursor style is specified, the terminal's cursor style is changed to the +specified one when the Atuin search starts with or switches to the +corresponding keymap mode. Also, the terminal's cursor style is reset to the +one associated with the keymap mode corresponding to the shell's keymap on the +termination of the Atuin search. + +### `prefers_reduced_motion` + +Atuin version: >= 18.0 + +Default: `false` + +Enable this, and Atuin will reduce motion in the TUI as much as possible. Users +with motion sensitivity can find the live-updating timestamps distracting. + +Alternatively, set env var NO_MOTION + +## Stats + +This section of client config is specifically for configuring Atuin stats calculations + +``` +[stats] +common_subcommands = [...] +common_prefix = [...] +``` + +### `common_subcommands` + +Default: + +```toml +common_subcommands = [ + "apt", + "cargo", + "composer", + "dnf", + "docker", + "git", + "go", + "ip", + "kubectl", + "nix", + "nmcli", + "npm", + "pecl", + "pnpm", + "podman", + "port", + "systemctl", + "tmux", + "yarn", +] +``` + +Configures commands where we should consider the subcommand as part of the statistics. For example, consider `kubectl get` rather than just `kubectl`. + +### `common_prefix` + +Atuin version: >= 17.1 + +Default: + +```toml +common_prefix = [ + "sudo", +] +``` + +Configures commands that should be totally stripped from stats calculations. For example, 'sudo' should be ignored. + +## sync + +We have developed a new version of sync, that is both faster and more efficient than the original version. + +Presently, it is the default for fresh installs but not for existing users. This will change in a later release. + +To enable sync v2, add the following to your config + +```toml +[sync] +records = true +``` + +## `dotfiles` + +Atuin version: >= 18.1 + +Default: `false` + +To enable sync of shell aliases between hosts. Requires `sync` enabled. + +Add the new section to the bottom of your config file, for every machine you use Atuin with + +```toml +[dotfiles] +enabled = true +``` + +Note: you will need to have sync v2 enabled. See the above section. + +Manage aliases using the command line options + +``` +# Alias 'k' to 'kubectl' +atuin dotfiles alias set k kubectl + +# List all aliases +atuin dotfiles alias list + +# Delete an alias +atuin dotfiles alias delete k +``` + +After setting an alias, you will either need to restart your shell or source the init file for the change to take affect + +## keys + +This section of the client config is specifically for configuring key-related settings. + +``` +[keys] +scroll_exits = [...] +prefix = 'a' +``` + +### `scroll_exits` + +Atuin version: >= 18.1 + +Default: `true` + +Configures whether the TUI exits, when scrolled past the last or first entry. + +### `prefix` + +Atuin version: > 18.3 + +Default: `a` + +Which key to use as the prefix + +## preview + +This section of the client config is specifically for configuring preview-related settings. +(In the future the other 2 preview settings will be moved here.) + +``` +[preview] +strategy = [...] +``` + +### `strategy` + +Atuin version: >= 18.3 + +Default: `auto` + +Which preview strategy is used to calculate the preview height. It respects `max_preview_height`. + +| Value | Preview height is calculated from the length of the | +| -------------- | --------------------------------------------------- | +| auto (default) | selected command | +| static | longest command in the current result set | +| fixed | use `max_preview_height` as fixed value | + +By using `auto` a preview is shown, if the command is longer than the width of the terminal. + +## Daemon + +Atuin version: >= 18.3 + +Default: `false` + +Enable the background daemon + +Add the new section to the bottom of your config file + +```toml +[daemon] +enabled = true +``` + +### sync_frequency + +Default: `300` + +How often the daemon should sync, in seconds + +```toml +sync_frequency = 300 +``` + +### socket_path + +Default: + +```toml +socket_path = "~/.local/share/atuin/atuin.sock" +``` + +Where to bind a unix socket for client -> daemon communication + +If XDG_RUNTIME_DIR is available, then we use this directory instead. + +### systemd_socket + +Default `false` + +Use a socket passed via systemd socket activation protocol instead of the path + +```toml +systemd_socket = false +``` + +### tcp_port + +Default: `8889` + +The port to use for client -> daemon communication. Only used on non-unix systems. + +```toml +tcp_port = 8889 +``` + +## theme + +Atuin version: >= 18.4 + +The theme to use for showing the terminal interface. + +```toml +[theme] +name = "" +debug = false +max_depth = 10 +``` + +### `name` + +Default: `""` + +A theme name that must be present as a built-in (an empty string for the default, +`autumn` or `marine`), or found in the themes directory, with the suffix `.toml`. +By default this is `~/.config/atuin/themes/` but can be overridden with the +`ATUIN_THEME_DIR` environment variable. + +```toml +name = "my-theme" +``` + +### `debug` + +Default: `false` + +Output information about why a theme will not load. Independent from other log +levels as it can cause data from the theme file to be printed unfiltered to the +terminal. + +```toml +debug = false +``` + +### `max_depth` + +Default: 10 + +Number of levels of "parenthood" that will be traversed for a theme. This should not +need to be added in or changed in normal usage. + +```toml +max_depth = 10 +``` diff --git a/docs/docs/configuration/key-binding.md b/docs/docs/configuration/key-binding.md new file mode 100644 index 00000000..4a01cd2d --- /dev/null +++ b/docs/docs/configuration/key-binding.md @@ -0,0 +1,208 @@ +# Key Binding + +Atuin does not yet have full key binding customization, though we do allow some changes. + +## Custom up arrow filter mode + +It can be useful to use a different filter or search mode on the up arrow. For example, you could use ctrl-r for searching globally, but the up arrow for searching history from the current directory only. + +Set your config like this: + +``` +filter_mode_shell_up_key_binding = "directory" # or global, host, directory, etc +``` + +## Disable up arrow + +Our default up-arrow binding can be a bit contentious. Some people love it, some people hate it. Many people who found it a bit jarring at first have since come to love it, so give it a try! + +It becomes much more powerful if you consider binding a different filter mode to the up arrow. For example, on "up" Atuin can default to searching all history for the current directory only, while ctrl-r searches history globally. See the [config](config.md#filter_mode_shell_up_key_binding) for more. + +Otherwise, if you don't like it, it's easy to disable. + +You can also disable either the up-arrow or ++ctrl+r++ bindings individually, by passing +`--disable-up-arrow` or `--disable-ctrl-r` to the call to `atuin init` in your shell config file: + +An example for zsh: +``` +# Bind ctrl-r but not up arrow +eval "$(atuin init zsh --disable-up-arrow)" + +# Bind up-arrow but not ctrl-r +eval "$(atuin init zsh --disable-ctrl-r)" +``` + +If you do not want either key to be bound, either pass both `--disable` arguments, or set the +environment variable `ATUIN_NOBIND` to any value before the call to `atuin init`: + +``` +## Do not bind any keys +# Either: +eval "$(atuin init zsh --disable-up-arrow --disable-ctrl-r)" + +# Or: +export ATUIN_NOBIND="true" +eval "$(atuin init zsh)" +``` + +You can then choose to bind Atuin if needed, do this after the call to init. + +## Enter key behavior + +By default, the `enter` key will directly execute the selected command instead of letting you edit it like the `tab` key. If you want to change this behavior, set `enter_accept = false` in your config. For more details: [enter_accept](config.md#enter_accept). + +## Ctrl-n key shortcuts + +macOS does not have an ++alt++ key, although terminal emulators can often be configured to map the ++option++ key to be used as ++alt++. *However*, remapping ++option++ this way may prevent typing some characters, such as using ++option+3++ to type `#` on the British English layout. For such a scenario, set the `ctrl_n_shortcuts` option to `true` in your config file to replace ++alt+0++ to ++alt+9++ shortcuts with ++ctrl+0++ to ++ctrl+9++ instead: + +``` +# Use Ctrl-0 .. Ctrl-9 instead of Alt-0 .. Alt-9 UI shortcuts +ctrl_n_shortcuts = true +``` + +## zsh + +If you'd like to customize your bindings further, it's possible to do so with custom shell config: + +Atuin defines the ZLE widgets "atuin-search" and "atuin-up-search". The latter +can be used for the keybindings to the ++up++ key and similar keys. + +Note: instead use the widget names "\_atuin\_search\_widget" and "\_atuin\_up\_search\_widget", respectively, in `atuin < 18.0` + +``` +export ATUIN_NOBIND="true" +eval "$(atuin init zsh)" + +bindkey '^r' atuin-search + +# bind to the up key, which depends on terminal mode +bindkey '^[[A' atuin-up-search +bindkey '^[OA' atuin-up-search +``` + +For the keybindings in vi mode, "atuin-search-viins", "atuin-search-vicmd", +"atuin-up-search-viins", and "atuin-up-search-vicmd" (`atuin >= 18.0`) can be +used in combination with the config +["keymap\_mode"](config.md#keymap_mode) +(`atuin >= 18.0`) to start the Atuin search in respective keymap modes. + +## bash + +Atuin provides a bindable shell function "`__atuin_history`" for keybindings in +Bash. The flag `--shell-up-key-binding` can be optionally specified to the +first argument for keybindings to the ++up++ key or similar keys. + +``` +export ATUIN_NOBIND="true" +eval "$(atuin init bash)" + +# bind to ctrl-r, add any other bindings you want here too +bind -x '"\C-r": __atuin_history' + +# bind to the up key, which depends on terminal mode +bind -x '"\e[A": __atuin_history --shell-up-key-binding' +bind -x '"\eOA": __atuin_history --shell-up-key-binding' +``` + +For the keybindings in the `vi` editing mode, the options +`--keymap-mode=vim-insert` and `--keymap-mode=vim-normal` (`atuin >= 18.0`) can +be additionally specified to the shell function `__atuin_history` in +combination with the config +["keymap\_mode"](config.md#keymap_mode) +(`atuin >= 18.0`) to start the Atuin search in respective keymap modes. + +## fish +Edit key bindings in FISH shell by adding the following to ~/.config/fish/config.fish + +``` +set -gx ATUIN_NOBIND "true" +atuin init fish | source + +# bind to ctrl-r in normal and insert mode, add any other bindings you want here too +bind \cr _atuin_search +bind -M insert \cr _atuin_search +``` + +For the ++up++ keybinding, `_atuin_bind_up` can be used instead of `_atuin_search`. + +Adding the useful alternative key binding of ++ctrl+up++ is tricky and determined by the terminals adherence to terminfo(5). + +Conveniently FISH uses a command to capture keystrokes and advises you of the exact command to add for your specific terminal. +In your terminal, run `fish_key_reader` then punch the desired keystroke/s. + +For example, in Gnome Terminal the output to ++ctrl+up++ is `bind \e\[1\;5A 'do something'` + +So, adding this to the above sample, `bind \e\[1\;5A _atuin_search` will provide the additional search keybinding. + +## nu + +``` +$env.ATUIN_NOBIND = true +atuin init nu | save -f ~/.local/share/atuin/init.nu #make sure you created the directory beforehand with `mkdir ~/.local/share/atuin/init.nu` +source ~/.local/share/atuin/init.nu + +#bind to ctrl-r in emacs, vi_normal and vi_insert modes, add any other bindings you want here too +$env.config = ( + $env.config | upsert keybindings ( + $env.config.keybindings + | append { + name: atuin + modifier: control + keycode: char_r + mode: [emacs, vi_normal, vi_insert] + event: { send: executehostcommand cmd: (_atuin_search_cmd) } + } + ) +) +``` + + +## Atuin UI shortcuts + +| Shortcut | Action | +| ----------------------------------------- | ----------------------------------------------------------------------------- | +| enter | Execute selected item | +| tab | Select item and edit | +| ctrl + r | Cycle through filter modes | +| ctrl + s | Cycle through search modes | +| alt + 1 to alt + 9 | Select item by the number located near it | +| ctrl + c / ctrl + d / ctrl + g / esc | Return original | +| ctrl + y | Copy selected item to clipboard | +| ctrl + ← / alt + b | Move the cursor to the previous word | +| ctrl + → / alt + f | Move the cursor to the next word | +| ctrl + b / ← | Move the cursor to the left | +| ctrl + f / → | Move the cursor to the right | +| ctrl + a / home | Move the cursor to the start of the line | +| ctrl + e / end | Move the cursor to the end of the line | +| ctrl + backspace / ctrl + alt + backspace | Remove the previous word / remove the word just before the cursor | +| ctrl + delete / ctrl + alt + delete | Remove the next word or the word just after the cursor | +| ctrl + w | Remove the word before the cursor even if it spans across the word boundaries | +| ctrl + u | Clear the current line | +| ctrl + n / ctrl + j / ↑ | Select the next item on the list | +| ctrl + p / ctrl + k / ↓ | Select the previous item on the list | +| ctrl + o | Open the inspector | +| page down | Scroll search results one page down | +| page up | Scroll search results one page up | +| ↓ (with no entry selected) | Return original or return query depending on [settings](config.md#exit_mode) | +| ↓ | Select the next item on the list | + + +### Vim mode +If [vim is enabled in the config](config.md#keymap_mode), the following keybindings are enabled: + +| Shortcut | Mode | Action | +| -------- | ------ | ------------------------------------- | +| k | Normal | Selects the next item on the list | +| j | Normal | Selects the previous item on the list | +| i | Normal | Enters insert mode | +| Esc | Insert | Enters normal mode | + + +### Inspector +Open the inspector with ctrl-o + +| Shortcut | Action | +| -------- | --------------------------------------------- | +| Esc | Close the inspector, returning to the shell | +| ctrl+o | Close the inspector, returning to search view | +| ctrl+d | Delete the inspected item from the history | diff --git a/docs/docs/faq.md b/docs/docs/faq.md new file mode 100644 index 00000000..0949dbfe --- /dev/null +++ b/docs/docs/faq.md @@ -0,0 +1,39 @@ +# FAQ + +## How do I remove the default up arrow binding? + +Open your shell config file, find the line containing `atuin init`. + +Add `--disable-up-arrow` + +EG: + +``` +eval "$(atuin init zsh --disable-up-arrow)" +``` + +See [key binding](../configuration/key-binding.md) for more + +## How do I edit a command instead of running it immediately? + +Press tab! By default, enter will execute a command, and tab will insert it ready for editing. + +You can make `enter` edit a command by putting `enter_accept = false` into your config file (~/.config/atuin/config.toml) + +## How do I delete my account? + +**Attention:** This command does not prompt for confirmation. + +``` +atuin account delete +``` + +This will delete your account, and all history from the remote server. It will not delete your local data. + +## I've forgotten my password! How can I reset it? + +We don't (yet) have a password reset system, as we don't verify emails. This +may change soon, but in the meantime so long as you're still logged in on at +least one account, it's safe to delete and re-create the account. + +We're aware this isn't optimal. diff --git a/docs/docs/guide/basic-usage.md b/docs/docs/guide/basic-usage.md new file mode 100644 index 00000000..c024c90e --- /dev/null +++ b/docs/docs/guide/basic-usage.md @@ -0,0 +1,64 @@ +# Basic Usage + +Now that you're all setup and running, here's a quick walkthrough of how you can use Atuin best + +## What does Atuin record? + +While you work, Atuin records + +1. The command you run +2. The directory you ran it in +3. The time you ran it, and how long it took to run +4. The exit code of the command +5. The hostname + user of the machine +6. The shell session you ran it in + +## Opening and using the TUI + +At any time, you can open the TUI with the default keybindings of the up arrow, or control-R. + +Once in the TUI, press enter to immediately execute a command, or press tab to insert it into your shell for editing. + +While searching in the TUI, you can adjust the "filter mode" by repeatedly pressing ctrl-r. Atuin can filter by + +1. All hosts +2. Just your local machine +3. The current directory only +4. The current shell session only + +## Common config adjustment + +For a full set of config values, please see the [config reference page](../configuration/config.md) + +The default configuration file is location at `~/.config/atuin/config.toml` + +### Keybindings + +We have a full page dedicated to keybinding adjustments, there are a whole bunch of options here! Including disabling the up arrow if you don't like it. + +Read more [here](../configuration/key-binding.md) + +### Enter to run + +You may prefer that Atuin always inserts the selected command for editing. To configure this, set + +``` +enter_accept = false +``` + +in your config file. + +### Inline window + +If you find the full screen TUI overwhelming or too much, you can adjust it like so + +``` +# height of the search window +inline_height = 40 +``` + +You may also prefer the compact UI mode + +``` +style = "compact" +``` diff --git a/docs/docs/guide/dotfiles.md b/docs/docs/guide/dotfiles.md new file mode 100644 index 00000000..74105e95 --- /dev/null +++ b/docs/docs/guide/dotfiles.md @@ -0,0 +1,140 @@ +# Syncing dotfiles + +While Atuin started as a tool for syncing and searching shell history, we are +building tooling for syncing dotfiles across machines, and making them easier +to work with. + +At the moment, we support managing and syncing of shell aliases and environment variables - with more +coming soon. + +The following shells are supported: + +- zsh +- bash +- fish +- xonsh + +Note: Atuin handles your configuration internally, so once it is installed you +no longer need to edit your config files manually. + +## Required config + +Once Atuin is setup and installed, the following is required in your config file (`~/.config/atuin/config.toml`) + +``` +[dotfiles] +enabled = true +``` + +In a later release, this will be enabled by default. + +Note: If you have not yet setup sync v2, please also add + +``` +[sync] +records = true +``` + +to the same config file. + +## Usage + +### Aliases + +After creating or deleting an alias, remember to restart your shell! + +#### Creating an alias + +``` +atuin dotfiles alias set NAME 'COMMAND' +``` + +For example, to alias `k` to be `kubectl` + + +``` +atuin dotfiles alias set k 'kubectl' +``` + +or to alias `ll` to be `ls -lah` + +``` +atuin dotfiles alias set ll 'ls -lah' +``` + +#### Deleting an alias + +Deleting an alias is as simple as: + +``` +atuin dotfiles alias delete NAME +``` + +For example, to delete the above alias `k`: + +``` +atuin dotfiles alias delete k +``` + +#### Listing aliases + +You can list all aliases with: + +``` +atuin dotfiles alias list +``` + +### Env vars + +After creating or deleting an env var, remember to restart your shell! + +#### Creating a var + +``` +atuin dotfiles var set NAME 'value' +``` + +For example, to set `FOO` to be `bar` + + +``` +atuin dotfiles var set FOO 'bar' +``` + +Vars are exported by default, but you can create a shell var like so + +``` +atuin dotfiles var set -n foo 'bar' +``` + + +#### Deleting a var + +Deleting a var is as simple as: + +``` +atuin dotfiles var delete NAME +``` + +For example, to delete the above var `FOO`: + +``` +atuin dotfiles var delete FOO +``` + +#### Listing vars + +You can list all vars with: + +``` +atuin dotfiles var list +``` + +### Syncing and backing up dotfiles +If you have [setup sync](sync.md), then running + +``` +atuin sync +``` + +will backup your config to the server and sync it across machines. diff --git a/docs/docs/guide/getting-started.md b/docs/docs/guide/getting-started.md new file mode 100644 index 00000000..c25645d0 --- /dev/null +++ b/docs/docs/guide/getting-started.md @@ -0,0 +1,53 @@ +# Getting Started + +Atuin replaces your existing shell history with a SQLite database, and records +additional context for your commands. With this context, Atuin gives you faster +and better search of your shell history. + +Additionally, Atuin (optionally) syncs your shell history between all of your +machines. Fully end-to-end encrypted, of course. + +You may use either the server I host, or host your own! Or just don't use sync +at all. As all history sync is encrypted, I couldn't access your data even if I +wanted to. And I **really** don't want to. + +If you have any problems, please open an [issue](https://github.com/ellie/atuin/issues) or get in touch on our [Discord](https://discord.gg/Fq8bJSKPHh)! + +## Supported Shells + +- zsh +- bash +- fish +- nushell +- xonsh + +## Quickstart + +Please do try and read this guide, but if you're in a hurry and want to get +started quickly: + +``` +bash <(curl --proto '=https' --tlsv1.2 -sSf https://setup.atuin.sh) + +atuin register -u -e +atuin import auto +atuin sync +``` + +Now restart your shell! + +Anytime you press ctrl-r or up, you will see the Atuin search UI. Type your +query, enter to execute. If you'd like to select a command without executing +it, press tab. + +You might like to configure an [inline window](../configuration/config.md#inline_height), or [disable up arrow bindings](../configuration/key-binding.md#disable-up-arrow) + +Note: The above sync and registration is fully optional. If you'd like to use Atuin offline, you can run + +``` +bash <(curl --proto '=https' --tlsv1.2 -sSf https://setup.atuin.sh) + +atuin import auto +``` + +Your shell history will be local only, not backed up, and not synchronized across devices. diff --git a/docs/docs/guide/import.md b/docs/docs/guide/import.md new file mode 100644 index 00000000..3e19b26c --- /dev/null +++ b/docs/docs/guide/import.md @@ -0,0 +1,18 @@ +# Import existing history + +Atuin uses a shell plugin to ensure that we capture new shell history. But for +older history, you will need to import it + +This will import the history for your current shell: +``` +atuin import auto +``` + +Alternatively, you can specify the shell like so: + +``` +atuin import bash +atuin import zsh # etc +``` + +Your old shell history file will continue to be updated, regardless of Atuin usage. diff --git a/docs/docs/guide/installation.md b/docs/docs/guide/installation.md new file mode 100644 index 00000000..a0009bbc --- /dev/null +++ b/docs/docs/guide/installation.md @@ -0,0 +1,228 @@ +# Installation + +## Recommended installation approach + +Let's get started! First up, you will want to install Atuin. The recommended +approach is to use the installation script, which automatically handles the +installation of Atuin including the requirements for your environment. + + +It will install a binary to `~/.atuin/bin`, and if you'd rather do something else +then the manual steps below offer much more flexibility. + +```shell +curl --proto '=https' --tlsv1.2 -LsSf https://setup.atuin.sh | sh +``` + +[**Setup sync** - Move on to the next step, or read on to manually install Atuin instead.](sync.md) + +## Manual installation + +### Installing the binary + +If you don't wish to use the installer, the manual installation steps are as follows. + +=== "Cargo" + + It's best to use [rustup](https://rustup.rs/) to get setup with a Rust + toolchain, then you can run: + + ```shell + cargo install atuin + ``` + +=== "Homebrew" + + ```shell + brew install atuin + ``` + +=== "MacPorts" + + Atuin is also available in [MacPorts](https://ports.macports.org/port/atuin/) + + ```shell + sudo port install atuin + ``` + +=== "Nix" + + This repository is a flake, and can be installed using `nix profile`: + + ```shell + nix profile install "github:atuinsh/atuin" + ``` + + Atuin is also available in [nixpkgs](https://github.com/NixOS/nixpkgs): + + ```shell + nix-env -f '' -iA atuin + ``` + +=== "Pacman" + + Atuin is available in the Arch Linux [extra repository](https://archlinux.org/packages/extra/x86_64/atuin/): + + ```shell + pacman -S atuin + ``` + +=== "XBPS" + + Atuin is available in the Void Linux [repository](https://github.com/void-linux/void-packages/tree/master/srcpkgs/atuin): + + ```shell + sudo xbps-install atuin + ``` + +=== "Termux" + + Atuin is available in the Termux package repository: + + ```shell + pkg install atuin + ``` + +=== "zinit" + + Atuin is installable from github-releases directly: + + ```shell + # line 1: `atuin` binary as command, from github release, only look at .tar.gz files, use the `atuin` file from the extracted archive + # line 2: setup at clone(create init.zsh, completion) + # line 3: pull behavior same as clone, source init.zsh + zinit ice as"command" from"gh-r" bpick"atuin-*.tar.gz" mv"atuin*/atuin -> atuin" \ + atclone"./atuin init zsh > init.zsh; ./atuin gen-completions --shell zsh > _atuin" \ + atpull"%atclone" src"init.zsh" + zinit light atuinsh/atuin + ``` + +=== "Source" + + Atuin builds on the latest stable version of Rust, and we make no + promises regarding older versions. We recommend using [rustup](https://rustup.rs/). + + ```shell + git clone https://github.com/atuinsh/atuin.git + cd atuin/crates/atuin + cargo install --path . + ``` + +!!! warning "Please be advised" + + If you choose to manually install Atuin rather than using the recommended installation script, + merely installing the binary is not sufficient, you should also set up the shell plugin. + +--- + +### Installing the shell plugin + +Once the binary is installed, the shell plugin requires installing. +If you use the install script, this should all be done for you! +After installing, remember to restart your shell. + +=== "zsh" + + ```shell + echo 'eval "$(atuin init zsh)"' >> ~/.zshrc + ``` + + === "zinit" + + ```shell + # if you _only_ want to install the shell-plugin, do this; otherwise look above for a "everything via zinit" solution + zinit load atuinsh/atuin + ``` + + === "Antigen" + + ```shell + antigen bundle atuinsh/atuin@main + ``` + +=== "bash" + + === "ble.sh" + + Atuin works best in bash when using [ble.sh](https://github.com/akinomyoga/ble.sh) >= 0.4. + + With ble.sh (>= 0.4) installed and loaded in `~/.bashrc`, just add atuin to your `~/.bashrc` + + ```shell + echo 'eval "$(atuin init bash)"' >> ~/.bashrc + ``` + + === "bash-preexec" + + [Bash-preexec](https://github.com/rcaloras/bash-preexec) can also be used, but you may experience + some minor problems with the recorded duration and exit status of some commands. + + !!! warning "Please note" + + bash-preexec currently has an issue where it will stop honoring `ignorespace`. + While Atuin will ignore commands prefixed with whitespace, they may still end up in your bash history. + Please check your configuration! All other shells do not have this issue. + + To use Atuin in `bash < 4` with bash-preexec, the option `enter_accept` needs + to be turned on (which is so by default). + + bash-preexec cannot properly invoke the `preexec` hook for subshell commands + `(...)`, function definitions `func() { ...; }`, empty for-in-statements `for + i in; do ...; done`, etc., so those commands and duration may not be recorded + in the Atuin's history correctly. + + To use bash-preexec, download and initialize it + + ```shell + curl https://raw.githubusercontent.com/rcaloras/bash-preexec/master/bash-preexec.sh -o ~/.bash-preexec.sh + echo '[[ -f ~/.bash-preexec.sh ]] && source ~/.bash-preexec.sh' >> ~/.bashrc + ``` + + Then setup Atuin + + ```shell + echo 'eval "$(atuin init bash)"' >> ~/.bashrc + ``` + +=== "fish" + + Add + + ```shell + atuin init fish | source + ``` + + to your `is-interactive` block in your `~/.config/fish/config.fish` file + +=== "Nushell" + + Run in *Nushell*: + + ```shell + mkdir ~/.local/share/atuin/ + atuin init nu | save ~/.local/share/atuin/init.nu + ``` + + Add to `config.nu`: + + ```shell + source ~/.local/share/atuin/init.nu + ``` + +=== "xonsh" + + Add + ```shell + execx($(atuin init xonsh)) + ``` + to the end of your `~/.xonshrc` + +## Upgrade + +Run `atuin update`, and if that command is not available, run the install script again. + +If you used a package manager to install Atuin, then you should also use your package manager to update Atuin. + +## Uninstall + +If you'd like to uninstall Atuin, please check out [the uninstall page](../uninstall.md). diff --git a/docs/docs/guide/sync.md b/docs/docs/guide/sync.md new file mode 100644 index 00000000..070d8178 --- /dev/null +++ b/docs/docs/guide/sync.md @@ -0,0 +1,78 @@ +# Setting up Sync + +At this point, you have Atuin storing and searching your shell history! But it +isn't syncing it just yet. To do so, you'll need to register with the sync +server. All of your history is fully end-to-end encrypted, so there are no +risks of the server snooping on you. + +If you don't have an account, please [register](#register). If you have already registered, +proceed to [login](#login). + +**Note:** You first have to set up your `sync_address` if you want to use a [self hosted server](../self-hosting/server-setup.md). + +## Register + +``` +atuin register -u -e +``` + +After registration, Atuin will generate an encryption key for you and store it +locally. This is needed for logging in to other machines, and can be seen with + +``` +atuin key +``` + +Please **never** share this key with anyone! The Atuin developers will never +ask you for your key, your password, or the contents of your Atuin directory. + +If you lose your key, we can do nothing to help you. We recommend you store +this somewhere safe, such as in a password manager. + +## First sync +By default, Atuin will sync your history once per hour. This can be +[configured](../configuration/config.md#sync_frequency). + +To run a sync manually, please run + +``` +atuin sync +``` + +Atuin tries to be smart with a sync, and not waste data transfer. However, if +you are seeing some missing data, please try running + +``` +atuin sync -f +``` + +This triggers a full sync, which may take longer as it works through historical data. + +## Login + +When only signed in on one machine, Atuin sync operates as a backup. This is +pretty useful by itself, but syncing multiple machines is where the magic +happens. + +First, ensure you are [registered with the sync server](#register) and make a +note of your key. You can see this with `atuin key`. + +Then, install Atuin on a new machine. Once installed, login with + +``` +atuin login -u +``` + +You will be prompted for your password, and for your key. + +Syncing will happen automatically in the background, but you may wish to run it manually with + +``` +atuin sync +``` + +Or, if you see missing data, force a full sync with: + +``` +atuin sync -f +``` diff --git a/docs/docs/guide/theming.md b/docs/docs/guide/theming.md new file mode 100644 index 00000000..a749d9cc --- /dev/null +++ b/docs/docs/guide/theming.md @@ -0,0 +1,111 @@ +# Theming + +Available in Atuin >= 18.4 + +For terminal interface customization, Atuin supports user and built-in color themes. + +Atuin ships with only a couple of built-in alternative themes, but more can be added via TOML files. + +## Required config + +The following is required in your config file (`~/.config/atuin/config.toml`) + +``` +[theme] +name = "THEMENAME" +``` + +Where `THEMENAME` is a known theme. The following themes are available out-of-the-box: + +* default theme (can be explicitly referenced with an empty name `""`) +* `autumn` theme +* `marine` theme + +These are present to ensure users and developers can try out theming, but in general, you +will need to download themes or make your own. + +If you are writing your own themes, you can add the following line to get additional output: + +``` +debug = true +``` + +to the same config block. This will print out any color names that cannot be parsed from +the requested theme. + +A final optional setting is available: + +``` +max_depth: 10 +``` + +which sets the maximum levels of theme parents to traverse. This should not need to be +explicitly added in normal use. + +## Usage + +### Theme structure + +Themes are maps from *Meanings*, describing the developer's intentions, +to (at present) colors. In future, this may be expanded to allow richer style support. + +*Meanings* are from an enum with the following values: + +* `AlertInfo`: alerting the user at an INFO level +* `AlertWarn`: alerting the user at a WARN level +* `AlertError`: alerting the user at an ERROR level +* `Annotation`: less-critical, supporting text +* `Base`: default foreground color +* `Guidance`: instructing the user as help or context +* `Important`: drawing the user's attention to information +* `Title`: titling a section or view + +These may expand over time as they are added to Atuin's codebase, but Atuin +should have fallbacks added for any new *Meanings* so that, whether themes limit to +the present list or take advantage of new *Meanings* in future, they should +keep working sensibly. + +**Note for Atuin contributors**: please do identify and, where appropriate during your own +PRs, extend the Meanings enum if needed (along with a fallback Meaning!). + +### Theme creation + +When a theme name is read but not yet loaded, Atuin will look for it in the folder +`~/.config/atuin/themes/` unless overridden by the `ATUIN_THEME_DIR` environment +variable. It will attempt to open a file of name `THEMENAME.toml` and read it as a +map from *Meanings* to colors. + +Colors may be specified either as names from the [palette](https://ogeon.github.io/docs/palette/master/palette/named/index.html) +crate in lowercase, or as six-character hex codes, prefixed with `#`. For example, +the following are valid color names: + +* `#ff0088` +* `teal` +* `powderblue` + +A theme file, say `my-theme.toml` can then be built up, such as: + +```toml +[theme] +name = "my-theme" +parent = "autumn" + +[colors] +AlertInfo = "green" +Guidance = "#888844" + +``` + +where not all of the *Meanings* need to be explicitly defined. If they are absent, +then the color will be chosen from the parent theme, if one is defined, or if that +key is missing in the `theme` block, from the default theme. + +This theme file should be moved to `~/.config/atuin/themes/my-theme.toml` and the +following added to `~/.config/atuin/config.toml`: + +``` +[theme] +name = "my-theme" +``` + +When you next run Atuin, your theme should be applied. diff --git a/docs/docs/index.md b/docs/docs/index.md new file mode 100644 index 00000000..76a4b51f --- /dev/null +++ b/docs/docs/index.md @@ -0,0 +1,47 @@ +# Getting started + +Atuin replaces your existing shell history with a SQLite database, and records +additional context for your commands. With this context, Atuin gives you faster +and better search of your shell history. + +Additionally, Atuin (optionally) syncs your shell history between all of your +machines. Fully end-to-end encrypted, of course. + +You may use either the server I host, or host your own! Or just don't use sync +at all. As all history sync is encrypted, I couldn't access your data even if I +wanted to. And I **really** don't want to. + +If you have any problems, please open a topic on the [forum](https://forum.atuin.sh) + +Alternatively, get in touch on our [Discord](https://discord.gg/Fq8bJSKPHh) or open an [issue](https://github.com/atuinsh/atuin/issues) + +#### Supported Shells + +- zsh +- bash +- fish +- nushell +- xonsh + +## Quickstart + +Please do try and read this guide, but if you're in a hurry and want to get +started quickly: + +```bash +bash <(curl --proto '=https' --tlsv1.2 -sSf https://setup.atuin.sh) + +atuin register -u -e +atuin import auto +atuin sync +``` + +Now restart your shell! + +Anytime you press ctrl-r or up, you will see the Atuin search UI. Type your +query, enter to execute. If you'd like to select a command without executing +it, press tab. + +You might like to configure an [inline window](configuration/config.md#inline_height), or [disable up arrow bindings](configuration/key-binding.md#disable-up-arrow) + +[**Installation** - Install and setup Atuin](guide/installation.md) diff --git a/docs/docs/integrations.md b/docs/docs/integrations.md new file mode 100644 index 00000000..27983add --- /dev/null +++ b/docs/docs/integrations.md @@ -0,0 +1,22 @@ +# Integrations + +## zsh-autosuggestions + +Atuin automatically adds itself as an [autosuggest strategy](https://github.com/zsh-users/zsh-autosuggestions#suggestion-strategy). + +If you'd like to override this, add your own config after "$(atuin init zsh)" in your zshrc. + +## ble.sh auto-complete (Bash) + +If ble.sh is available when Atuin's integration is loaded in Bash, Atuin automatically defines and registers an auto-complete source for the autosuggestion feature of ble.sh. + +If you'd like to change the behavior, please overwrite the shell function `ble/complete/auto-complete/source:atuin-history` after `eval "$(atuin init bash)"` in your `.bashrc`. + +If you would not like Atuin's auto-complete source, please add the following setting after `eval "$(atuin init bash)"` in your `.bashrc`: + +```shell +# bashrc (after eval "$(atuin init bash)") + +ble/util/import/eval-after-load core-complete ' + ble/array#remove _ble_complete_auto_source atuin-history' +``` diff --git a/docs/docs/known-issues.md b/docs/docs/known-issues.md new file mode 100644 index 00000000..21179fa9 --- /dev/null +++ b/docs/docs/known-issues.md @@ -0,0 +1,4 @@ +# Known Issues + +- SQLite has some issues with ZFS in certain configurations. As Atuin uses SQLite, this may cause your shell to become slow! We have an [issue](https://github.com/atuinsh/atuin/issues/952) to track, with some workarounds +- SQLite also does not tend to like network filesystems (eg, NFS) diff --git a/docs/docs/reference/daemon.md b/docs/docs/reference/daemon.md new file mode 100644 index 00000000..22088254 --- /dev/null +++ b/docs/docs/reference/daemon.md @@ -0,0 +1,29 @@ +# daemon + +## `atuin daemon` +_This is experimental!_ + +The Atuin daemon is a background daemon designed to + +1. Speed up database writes +2. Allow machines to sync when not in use, so they're ready to go right away +3. Perform background maintenance + +It may also work around issues with ZFS/SQLite performance. + +It's currently experimental, but is safe to use with a little bit of setup + +## To enable + +Add the following to the bottom of your Atuin config file + +```toml +[daemon] +enabled = true +``` + +Then, run `atuin daemon`. This might make sense in a tmux session, systemd unit, etc. Once it's ready for wider use, we will handle this setup for you. + +## Extra config + +See the [config section](../configuration/config.md#daemon) diff --git a/docs/docs/reference/doctor.md b/docs/docs/reference/doctor.md new file mode 100644 index 00000000..bd091aeb --- /dev/null +++ b/docs/docs/reference/doctor.md @@ -0,0 +1,38 @@ +# doctor + +## `atuin doctor` + +This command will attempt to diagnose common problems. It will also dump information about your system + +Please include its output with issues and support requests. + +Example output: + +``` +Atuin Doctor +Checking for diagnostics + + +Please include the output below with any bug reports or issues + +atuin: + version: 18.1.0 + sync: + cloud: true + records: true + auto_sync: true + last_sync: 2024-03-05 14:54:48.447677 +00:00:00 +shell: + name: zsh + plugins: + - atuin +system: + os: Darwin + arch: arm64 + version: 14.4 + disks: + - name: Macintosh HD + filesystem: apfs + - name: Macintosh HD + filesystem: apfs +``` diff --git a/docs/docs/reference/gen-completions.md b/docs/docs/reference/gen-completions.md new file mode 100644 index 00000000..3027d8a9 --- /dev/null +++ b/docs/docs/reference/gen-completions.md @@ -0,0 +1,20 @@ +# gen-completions + +[Shell completions](https://en.wikipedia.org/wiki/Command-line_completion) for Atuin can be generated by specifying the output directory and desired shell via `gen-completions` subcommand. + +``` +$ atuin gen-completions --shell bash --out-dir $HOME + +Shell completion for BASH is generated in "/home/user" +``` + +Possible values for the `--shell` argument are the following: + +- `bash` +- `fish` +- `zsh` +- `nushell` +- `powershell` +- `elvish` + +Also, see the [supported shells](https://github.com/atuinsh/atuin#supported-shells). diff --git a/docs/docs/reference/import.md b/docs/docs/reference/import.md new file mode 100644 index 00000000..a618e2c8 --- /dev/null +++ b/docs/docs/reference/import.md @@ -0,0 +1,93 @@ +# import + +## `atuin import` + +Atuin can import your history from your "old" history file + +`atuin import auto` will attempt to figure out your shell (via \$SHELL) and run +the correct importer + +Unfortunately these older files do not store as much information as Atuin does, +so not all features are available with imported data. + +Except as noted otherwise, you can set the `HISTFILE` environment variable to +control which file is read, otherwise each importer will try some default filenames. + +``` +HISTFILE=/path/to/history/file atuin import zsh +``` + +Note that for shells such as Xonsh that store history in many files rather than a +single file, `$HISTFILE` should be set to the directory in which those files reside. + +For formats that don't store timestamps, timestamps will be generated starting at +the current time plus 1ms for each additional command in the history. + +Most importers will discard commands found that have invalid UTF-8. + +## bash + +This will read the history from `$HISTFILE` or `$HOME/.bash_history`. + +Warnings will be issued if timestamps are found to be out of order, which could also +happen when a history file starts without timestamps but later entries include them. + +## fish + +fish supports multiple history sessions, so the importer will default to the `fish` +session unless the `fish_history` environment variable is set. The file to be read +will be `{session}_history` in `$XDG_DATA_HOME/fish/` (or `$HOME/.local/share/fish`). + +Not all of the data in the fish history is preserved, some data about filenames used +for each command are not used by Atuin, so it is discarded. + +## nu-hist-db + +This importer reads from Nushell's SQLite history database, which is stored in +`$XDG_CONFIG_HOME/nushell/history.sqlite3` or `$HOME/.config/nushell/history.sqlite3`. +There is no way to set the filename otherwise. + +## nu + +This importer reads from Nushell's text history format, which is stored in +`$XDG_CONFIG_HOME/nushell/history.txt` or `$HOME/.config/nushell/history.txt`. +There is no way to set the filename otherwise. + +## resh + +The [RESH](https://github.com/curusarn/resh) importer will read from `$HISTFILE` or `$HOME/.resh_history.json`. + +## xonsh + +The Xonsh importer will read from all JSON files it finds in the Xonsh history +directory. The location of the directory is determined as follows: +* If `$HISTFILE` is set, its value is used as the history directory. +* If `$XONSH_DATA_DIR` is set (as it typically will be if the importer is invoked +from within Xonsh), `$XONSH_DATA_DIR/history_json` is used. +* If `$XDG_DATA_HOME` is set, `$XDG_DATA_HOME/xonsh/history_json` is used. +* Otherwise, `$HOME/.local/share/xonsh/history_json` is used. + +Not all data present in Xonsh history JSON files is used by Atuin. Xonsh stores the +environment variables present when each session was initiated, but this data is +discarded by Atuin. Xonsh optionally stores the output of each command; if present +this data is also ignored by Atuin. + +## xonsh_sqlite + +The Xonsh SQLite importer will read from the Xonsh SQLite history file. The history +file's location is determined by the same process as the regular Xonsh importer, +but with `history_json` replaced by `xonsh-history.sqlite`. + +The Xonsh SQLite backend does not store environment variables, but like the JSON +backend it can optionally store the output of each command. As with the JSON backend, +if present this data will be ignored by Atuin. + +## zsh_histdb + +This will read the Zsh histdb SQLite file from `$HISTDB_FILE` or +`$HOME/.histdb/zsh-history.db`. + +## zsh + +This will read the Zsh history from `$HISTFILE` or `$HOME/.zhistory` +or `$HOME/.zsh_history` in either the simple or extended format. diff --git a/docs/docs/reference/info.md b/docs/docs/reference/info.md new file mode 100644 index 00000000..a19d0b42 --- /dev/null +++ b/docs/docs/reference/info.md @@ -0,0 +1,22 @@ +# info + +## `atuin info` + +This command shows the location of config files on your system + +Example output: + +``` +Config files: +client config: "/Users/ellie/.config/atuin/config.toml" +server config: "/Users/ellie/.config/atuin/server.toml" +client db path: "/Users/ellie/.local/share/atuin/history.db" +key path: "/Users/ellie/.local/share/atuin/key" +session path: "/Users/ellie/.local/share/atuin/session" + +Env Vars: +ATUIN_CONFIG_DIR = "None" + +Version info: +version: 18.1.0 +``` diff --git a/docs/docs/reference/list.md b/docs/docs/reference/list.md new file mode 100644 index 00000000..a9920718 --- /dev/null +++ b/docs/docs/reference/list.md @@ -0,0 +1,31 @@ +# history list + +## `atuin history list` + + +| Arg | Description | +|------------------|-------------------------------------------------------------------------------| +| `--cwd`/`-c` | List history for the current directory only (default: all dirs) | +| `--session`/`-s` | List history for the current session only (default: false) | +| `--human` | Use human-readable formatting for the timestamp and duration (default: false) | +| `--cmd-only` | Show only the text of the command (default: false) | +| `--reverse` | Reverse the order of the output (default: false) | +| `--format` | Specify the formatting of a command (see below) | +| `--print0` | Terminate the output with a null, for better multiline support | + + +## Format + +Customize the output of `history list` + +Example + +``` +atuin history list --format "{time} - {duration} - {command}" +``` + +Supported variables + +``` +{command}, {directory}, {duration}, {user}, {host} and {time} +``` diff --git a/docs/docs/reference/prune.md b/docs/docs/reference/prune.md new file mode 100644 index 00000000..5d85819a --- /dev/null +++ b/docs/docs/reference/prune.md @@ -0,0 +1,11 @@ +# history prune + +## `atuin history prune` + +This command deletes history entries matching the [history_filter](../configuration/config.md#history_filter) configuration parameter. + +It can be run with `--dry-run` first to list history entries that will be removed. + +| Argument | Description | +|------------------|--------------------------------------------------------------------| +| `--dry-run`/`-n` | List matching history lines without performing the actual deletion | diff --git a/docs/docs/reference/search.md b/docs/docs/reference/search.md new file mode 100644 index 00000000..6330df57 --- /dev/null +++ b/docs/docs/reference/search.md @@ -0,0 +1,65 @@ +# search + +Atuin search supports wildcards, with either the `*` or `%` character. By +default, a prefix search is performed (ie, all queries are automatically +appended with a wildcard). + +| Arg | Description | +| -------------------- | ----------------------------------------------------------------------------- | +| `--cwd`/`-c` | The directory to list history for (default: all dirs) | +| `--exclude-cwd` | Do not include commands that ran in this directory (default: none) | +| `--exit`/`-e` | Filter by exit code (default: none) | +| `--exclude-exit` | Do not include commands that exited with this value (default: none) | +| `--before` | Only include commands ran before this time(default: none) | +| `--after` | Only include commands ran after this time(default: none) | +| `--interactive`/`-i` | Open the interactive search UI (default: false) | +| `--human` | Use human-readable formatting for the timestamp and duration (default: false) | +| `--limit` | Limit the number of results (default: none) | +| `--offset` | Offset from the start of the results (default: none) | +| `--delete` | Delete history matching this query | +| `--delete-it-all` | Delete all shell history | +| `--reverse` | Reverse order of search results, oldest first | +| `--format`/`-f` | Available variables: {command}, {directory}, {duration}, {user}, {host}, {time}, {exit} and {relativetime}. Example: --format "{time} - [{duration}] - {directory}$\t{command}" | +| `--inline-height` | Set the maximum number of lines Atuin's interface should take up | +| `--help`/`-h` | Print help | + +## `atuin search -i` + +Atuin's interactive search TUI allows you to fuzzy search through your history. + +![compact](https://user-images.githubusercontent.com/1710904/161623659-4fec047f-ea4b-471c-9581-861d2eb701a9.png) + +You can replay the `nth` command with `alt + #` where `#` is the line number of the command you would like to replay. + +Note: This is not yet supported on macOS. + +## Examples + +``` +# Open the interactive search TUI +atuin search -i + +# Open the interactive search TUI preloaded with a query +atuin search -i atuin + +# Search for all commands, beginning with cargo, that exited successfully +atuin search --exit 0 cargo + +# Search for all commands, that failed, from the current dir, and were ran before April 1st 2021 +atuin search --exclude-exit 0 --before 01/04/2021 --cwd . + +# Search for all commands, beginning with cargo, that exited successfully, and were ran after yesterday at 3pm +atuin search --exit 0 --after "yesterday 3pm" cargo + +# Delete all commands, beginning with cargo, that exited successfully, and were ran after yesterday at 3pm +atuin search --delete --exit 0 --after "yesterday 3pm" cargo + +# Search for a command beginning with cargo, return exactly one result. +atuin search --limit 1 cargo + +# Search for a single result for a command beginning with cargo, skipping (offsetting) one result +atuin search --offset 1 --limit 1 cargo + +# Find the oldest cargo command +atuin search --limit 1 --reverse cargo +``` diff --git a/docs/docs/reference/stats.md b/docs/docs/reference/stats.md new file mode 100644 index 00000000..b1e4f0f9 --- /dev/null +++ b/docs/docs/reference/stats.md @@ -0,0 +1,50 @@ +# stats + +Atuin can also calculate stats based on your history - this is currently a +little basic, but more features to come. + +## 1-day stats + +You provide the starting point, and Atuin computes the stats for 24h from that point. +Date parsing is provided by `interim`, which supports different formats +for full or relative dates. Certain formats rely on the dialect option in your +[configuration](../configuration/config.md#dialect) to differentiate day from month. +Refer to [the module's documentation](https://docs.rs/interim/0.1.0/interim/#supported-formats) for more details on the supported date formats. + +``` +$ atuin stats last friday + ++---------------------+------------+ +| Statistic | Value | ++---------------------+------------+ +| Most used command | git status | ++---------------------+------------+ +| Commands ran | 450 | ++---------------------+------------+ +| Unique commands ran | 213 | ++---------------------+------------+ + +# A few more examples: +$ atuin stats 2018-04-01 +$ atuin stats April 1 +$ atuin stats 01/04/22 +$ atuin stats last thursday 3pm # between last thursday 3:00pm and the following friday 3:00pm +``` + +## Full history stats + +``` +$ atuin stats +# or +$ atuin stats all + ++---------------------+-------+ +| Statistic | Value | ++---------------------+-------+ +| Most used command | ls | ++---------------------+-------+ +| Commands ran | 8190 | ++---------------------+-------+ +| Unique commands ran | 2996 | ++---------------------+-------+ +``` diff --git a/docs/docs/reference/sync.md b/docs/docs/reference/sync.md new file mode 100644 index 00000000..97e2bf41 --- /dev/null +++ b/docs/docs/reference/sync.md @@ -0,0 +1,77 @@ +# sync + +Atuin can back up your history to a server, and use this to ensure multiple +machines have the same shell history. This is all encrypted end-to-end, so the +server operator can _never_ see your data! + +Anyone can host a server (try `atuin server start`, more docs to follow), but I +host one at https://api.atuin.sh. This is the default server address, which can +be changed in the [config](../configuration/config.md#sync_address). Again, I _cannot_ see your data, and +do not want to. + +## Sync frequency + +Syncing will happen automatically, unless configured otherwise. The sync +frequency is configurable in [config](../configuration/config.md#sync_frequency) + +## Sync + +You can manually trigger a sync with `atuin sync` + +## Register + +Register for a sync account with + +``` +atuin register -u -e -p +``` + +If you don't want to have your password be included in shell history, you can omit +the password flag and you will be prompted to provide it through stdin. + +Usernames must be unique and only contain alphanumerics or hyphens, +and emails shall only be used for important notifications (security breaches, changes to service, etc). + +Upon success, you are also logged in :) Syncing should happen automatically from +here! + +## Delete + +You can delete your sync account with + +``` +atuin account delete +``` + +This will remove your account and all synchronized history from the server. Local data will not be touched! + +## Key + +As all your data is encrypted, Atuin generates a key for you. It's stored in the +Atuin data directory (`~/.local/share/atuin` on Linux). + +You can also get this with + +``` +atuin key +``` + +Never share this with anyone! + +## Login + +If you want to log in to a new machine, you will require your encryption key +(`atuin key`). + +``` +atuin login -u -p -k +``` + +If you don't want to have your password be included in shell history, you can omit +the password flag and you will be prompted to provide it through stdin. + +## Logout + +``` +atuin logout +``` diff --git a/docs/docs/self-hosting/docker.md b/docs/docs/self-hosting/docker.md new file mode 100644 index 00000000..8ed36010 --- /dev/null +++ b/docs/docs/self-hosting/docker.md @@ -0,0 +1,125 @@ +# Docker + +!!! warning + If you are self hosting, we strongly suggest you stick to [tagged releases](https://github.com/atuinsh/atuin/releases), and do not follow `main` or `latest` + + Follow the GitHub releases, and please read the notes for each release. Most of the time, upgrades can occur without any manual intervention. + + We cannot guarantee that all updates will apply cleanly, and some may require some extra steps. + +There is a supplied docker image to make deploying a server as a container easier. The "LATEST TAGGED RELEASE" can be found on the [releases page](https://github.com/atuinsh/atuin/releases). + +```sh +docker run -d -v "$HOME/.config/atuin:/config" ghcr.io/atuinsh/atuin: server start +``` + +## Docker Compose + +Using the already build docker image hosting your own Atuin can be done using the supplied docker-compose file. + +Create a `.env` file next to [`docker-compose.yml`](https://github.com/atuinsh/atuin/raw/main/docker-compose.yml) with contents like this: + +```ini +ATUIN_DB_NAME=atuin +ATUIN_DB_USERNAME=atuin +# Choose your own secure password. Stick to [A-Za-z0-9.~_-] +ATUIN_DB_PASSWORD=really-insecure +``` + +Create a `docker-compose.yml`: + +```yaml +services: + atuin: + restart: always + image: ghcr.io/atuinsh/atuin: + command: server start + volumes: + - "./config:/config" + ports: + - 8888:8888 + environment: + ATUIN_HOST: "0.0.0.0" + ATUIN_OPEN_REGISTRATION: "true" + ATUIN_DB_URI: postgres://${ATUIN_DB_USERNAME}:${ATUIN_DB_PASSWORD}@db/${ATUIN_DB_NAME} + RUST_LOG: info,atuin_server=debug + depends_on: + - db + db: + image: postgres:14 + restart: unless-stopped + volumes: # Don't remove permanent storage for index database files! + - "./database:/var/lib/postgresql/data/" + environment: + POSTGRES_USER: ${ATUIN_DB_USERNAME} + POSTGRES_PASSWORD: ${ATUIN_DB_PASSWORD} + POSTGRES_DB: ${ATUIN_DB_NAME} +``` + +Start the services using `docker compose`: + +```sh +docker compose up -d +``` + +## Using systemd to manage your atuin server + +The following `systemd` unit file to manage your `docker-compose` managed service: + +```ini +[Unit] +Description=Docker Compose Atuin Service +Requires=docker.service +After=docker.service + +[Service] +# Where the docker-compose file is located +WorkingDirectory=/srv/atuin-server +ExecStart=/usr/bin/docker compose up +ExecStop=/usr/bin/docker compose down +TimeoutStartSec=0 +Restart=on-failure +StartLimitBurst=3 + +[Install] +WantedBy=multi-user.target +``` + +Start and enable the service with: + +```sh +systemctl enable --now atuin +``` + +Check if its running with: + +```sh +systemctl status atuin +``` + +## Creating backups of the Postgres database + +You can add another service to your `docker-compose.yml` file to have it run daily backups. It should look like this: + +```yaml + backup: + container_name: atuin_db_dumper + image: prodrigestivill/postgres-backup-local + env_file: + - .env + environment: + POSTGRES_HOST: postgresql + POSTGRES_DB: ${ATUIN_DB_NAME} + POSTGRES_USER: ${ATUIN_DB_USERNAME} + POSTGRES_PASSWORD: ${ATUIN_DB_PASSWORD} + SCHEDULE: "@daily" + BACKUP_DIR: /db_dumps + volumes: + - ./db_dumps:/db_dumps + depends_on: + - postgresql +``` + +This will create daily backups of your database for that additional layer of comfort. + +PLEASE NOTE: The `./db_dumps` mount MUST be a POSIX-compliant filesystem to store the backups (mainly with support for hardlinks and softlinks). So filesystems like VFAT, EXFAT, SMB/CIFS, ... can't be used with this docker image. See https://github.com/prodrigestivill/docker-postgres-backup-local for more details on how this works. There are additional settings for the number of backups retained, etc., all explained on the linked page. diff --git a/docs/docs/self-hosting/kubernetes.md b/docs/docs/self-hosting/kubernetes.md new file mode 100644 index 00000000..73bb772d --- /dev/null +++ b/docs/docs/self-hosting/kubernetes.md @@ -0,0 +1,290 @@ +# Kubernetes + +!!! warning + If you are self hosting, we strongly suggest you stick to tagged releases, and do not follow `main` or `latest` + + Follow the GitHub releases, and please read the notes for each release. Most of the time, upgrades can occur without any manual intervention. + + We cannot guarantee that all updates will apply cleanly, and some may require some extra steps. + +You could host your own Atuin server using the Kubernetes platform. + +Create a [`secrets.yaml`](https://github.com/atuinsh/atuin/blob/main/k8s/secrets.yaml) file for the database credentials: + +```yaml +apiVersion: v1 +kind: Secret +metadata: + name: atuin-secrets +type: Opaque +stringData: + ATUIN_DB_USERNAME: atuin + ATUIN_DB_PASSWORD: seriously-insecure + ATUIN_HOST: "127.0.0.1" + ATUIN_PORT: "8888" + ATUIN_OPEN_REGISTRATION: "true" + ATUIN_DB_URI: "postgres://atuin:seriously-insecure@postgres/atuin" +immutable: true +``` + +Create a [`atuin.yaml`](https://github.com/atuinsh/atuin/blob/main/k8s/atuin.yaml) file for the Atuin server: + +```yaml +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: postgres + namespace: atuin +spec: + replicas: 1 + strategy: + type: Recreate # This is important to ensure duplicate pods don't run and cause corruption + selector: + matchLabels: + io.kompose.service: postgres + template: + metadata: + labels: + io.kompose.service: postgres + spec: + containers: + - name: postgresql + image: postgres:14 + ports: + - containerPort: 5432 + env: + - name: POSTGRES_DB + value: atuin + - name: POSTGRES_PASSWORD + valueFrom: + secretKeyRef: + name: atuin-secrets + key: ATUIN_DB_PASSWORD + optional: false + - name: POSTGRES_USER + valueFrom: + secretKeyRef: + name: atuin-secrets + key: ATUIN_DB_USERNAME + optional: false + lifecycle: + preStop: + exec: + # This ensures graceful shutdown see: https://stackoverflow.com/a/75829325/3437018 + # Potentially consider using a `StatefulSet` instead of a `Deployment` + command: ["/usr/local/bin/pg_ctl stop -D /var/lib/postgresql/data -w -t 60 -m fast"] + resources: + requests: + cpu: 100m + memory: 100Mi + limits: + cpu: 250m + memory: 600Mi + volumeMounts: + - mountPath: /var/lib/postgresql/data/ + name: database + volumes: + - name: database + persistentVolumeClaim: + claimName: database +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: atuin +spec: + replicas: 1 + selector: + matchLabels: + io.kompose.service: atuin + template: + metadata: + labels: + io.kompose.service: atuin + spec: + containers: + - args: + - server + - start + env: + - name: ATUIN_DB_URI + valueFrom: + secretKeyRef: + name: atuin-secrets + key: ATUIN_DB_URI + optional: false + - name: ATUIN_HOST + value: 0.0.0.0 + - name: ATUIN_PORT + value: "8888" + - name: ATUIN_OPEN_REGISTRATION + value: "true" + image: ghcr.io/atuinsh/atuin:latest + name: atuin + ports: + - containerPort: 8888 + resources: + limits: + cpu: 250m + memory: 1Gi + requests: + cpu: 250m + memory: 1Gi + volumeMounts: + - mountPath: /config + name: atuin-claim0 + volumes: + - name: atuin-claim0 + persistentVolumeClaim: + claimName: atuin-claim0 +--- +apiVersion: v1 +kind: Service +metadata: + labels: + io.kompose.service: atuin + name: atuin +spec: + type: NodePort + ports: + - name: "8888" + port: 8888 + nodePort: 30530 + selector: + io.kompose.service: atuin +--- +apiVersion: v1 +kind: Service +metadata: + labels: + io.kompose.service: postgres + name: postgres +spec: + type: ClusterIP + selector: + io.kompose.service: postgres + ports: + - protocol: TCP + port: 5432 + targetPort: 5432 +--- +kind: PersistentVolume +apiVersion: v1 +metadata: + name: database-pv + labels: + app: database + type: local +spec: + storageClassName: manual + capacity: + storage: 300Mi + accessModes: + - ReadWriteOnce + hostPath: + path: "/Users/firstname.lastname/.kube/database" +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + labels: + io.kompose.service: database + name: database +spec: + storageClassName: manual + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 300Mi +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + labels: + io.kompose.service: atuin-claim0 + name: atuin-claim0 +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Mi +``` + +Finally, you may want to use a separate namespace for atuin, by creating a [`namespaces.yaml`](https://github.com/atuinsh/atuin/blob/main/k8s/namespaces.yaml) file: + +```yaml +apiVersion: v1 +kind: Namespace +metadata: + name: atuin-namespace + labels: + name: atuin +``` + +Note that this configuration will store the database folder _outside_ the kubernetes cluster, in the folder `/Users/firstname.lastname/.kube/database` of the host system by configuring the `storageClassName` to be `manual`. In a real enterprise setup, you would probably want to store the database content permanently in the cluster, and not in the host system. + +You should also change the password string in `ATUIN_DB_PASSWORD` and `ATUIN_DB_URI` in the`secrets.yaml` file to a more secure one. + +The atuin service on the port `30530` of the host system. That is configured by the `nodePort` property. Kubernetes has a strict rule that you are not allowed to expose a port numbered lower than 30000. To make the clients work, you can simply set the port in in your `config.toml` file, e.g. `sync_address = "http://192.168.1.10:30530"`. + +Deploy the Atuin server using `kubectl`: + +```shell + kubectl apply -f ./namespaces.yaml + kubectl apply -n atuin-namespace \ + -f ./secrets.yaml \ + -f ./atuin.yaml +``` + +The sample files above are also in the [k8s folder](https://github.com/atuinsh/atuin/tree/main/k8s) of the atuin repository. + +## Creating backups of the Postgres database + +Now you're up and running it's a good time to think about backups. + +You can create a [`CronJob`](https://kubernetes.io/docs/concepts/workloads/controllers/cron-jobs/) which uses [`pg_dump`](https://www.postgresql.org/docs/current/app-pgdump.html) to create a backup of the database. This example runs weekly and dumps to the local disk on the node. + +```yaml +apiVersion: batch/v1 +kind: CronJob +metadata: + name: atuin-db-backup +spec: + schedule: "0 0 * * 0" # Run every Sunday at midnight + jobTemplate: + spec: + template: + spec: + containers: + - name: atuin-db-backup-pg-dump + image: postgres:14 + command: [ + "/bin/bash", + "-c", + "pg_dump --host=postgres --username=atuin --format=c --file=/backup/atuin-backup-$(date +'%Y-%m-%d').pg_dump", + ] + env: + - name: PGPASSWORD + valueFrom: + secretKeyRef: + name: atuin-secrets + key: ATUIN_DB_PASSWORD + optional: false + volumeMounts: + - name: backup-volume + mountPath: /backup + restartPolicy: OnFailure + volumes: + - name: backup-volume + hostPath: + path: /somewhere/on/node/for/database-backups + type: Directory +``` + +Configure/update the example `yaml` with the following: +- Set a more or less frequent schedule with the `schedule` property. +- Replace `/somewhere/on/node/for/database-backups` with a path on your node or reconfigure to use a `PersistentVolume` instead of `hostPath`. +- `--format=c` outputs a format that can be restored with `pg_restore`. Use [`plain`](https://www.postgresql.org/docs/current/app-pgdump.html) if you want `.sql` files outputted instead. diff --git a/docs/docs/self-hosting/server-setup.md b/docs/docs/self-hosting/server-setup.md new file mode 100644 index 00000000..942312fe --- /dev/null +++ b/docs/docs/self-hosting/server-setup.md @@ -0,0 +1,66 @@ +# Server setup + +While we offer a public sync server, and cannot view your data (as it is encrypted), you may still wish to self host your own Atuin sync server. + +The requirements to do so are pretty minimal! You need to be able to run a binary or docker container, and have a PostgreSQL database setup. Atuin requires PostgreSQL 14 or above. + +Atuin also supports sqlite 3 and above. + +Any host with the `atuin` binary may also run a server, by running + +```shell +atuin server start +``` + +## Configuration + +The config for the server is kept separate from the config for the client, even +though they are the same binary. Server config can be found at +`~/.config/atuin/server.toml`. + +It looks something like this for PostgreSQL: + +```toml +host = "0.0.0.0" +port = 8888 +open_registration = true +db_uri="postgres://user:password@hostname/database" +``` + +Alternatively, configuration can also be provided with environment variables. + +```sh +ATUIN_HOST="0.0.0.0" +ATUIN_PORT=8888 +ATUIN_OPEN_REGISTRATION=true +ATUIN_DB_URI="postgres://user:password@hostname/database" +``` + +| Parameter | Description | +| ------------------- | -------------------------------------------------------------- | +| `host` | The host to listen on (default: 127.0.0.1) | +| `port` | The TCP port to listen on (default: 8888) | +| `open_registration` | If `true`, accept new user registrations (default: false) | +| `db_uri` | A valid PostgreSQL URI, for saving history (default: false) | +| `path` | A path to prepend to all routes of the server (default: false) | + +For sqlite, substitute the following: + +db_uri="sqlite:///config/atuin.db" + +ATUIN_DB_URI="sqlite:///config/atuin.db" + +These will create the database in the /config directory. + +You will need to map some sort of persistent volume for the /config directory and it should be writable by the atuin server. + +### TLS + +The server supports TLS through the `[tls]` section: + +```toml +[tls] +enable = true +cert_path = "/path/to/letsencrypt/live/fully.qualified.domain/fullchain.pem" +pkey_path = "/path/to/letsencrypt/live/fully.qualified.domain/privkey.pem" +``` diff --git a/docs/docs/self-hosting/systemd.md b/docs/docs/self-hosting/systemd.md new file mode 100644 index 00000000..d31d0ee7 --- /dev/null +++ b/docs/docs/self-hosting/systemd.md @@ -0,0 +1,65 @@ +# Systemd + +First, create the service unit file +[`atuin-server.service`](https://github.com/atuinsh/atuin/raw/main/systemd/atuin-server.service) at +`/etc/systemd/system/atuin-server.service` with contents like this: + +```ini +[Unit] +Description=Start the Atuin server syncing service +After=network-online.target +Wants=network-online.target systemd-networkd-wait-online.service + +[Service] +ExecStart=atuin server start +Restart=on-failure +User=atuin +Group=atuin + +Environment=ATUIN_CONFIG_DIR=/etc/atuin +ReadWritePaths=/etc/atuin + +# Hardening options +CapabilityBoundingSet= +AmbientCapabilities= +NoNewPrivileges=true +ProtectHome=true +ProtectSystem=strict +ProtectKernelTunables=true +ProtectKernelModules=true +ProtectControlGroups=true +PrivateTmp=true +PrivateDevices=true +LockPersonality=true + +[Install] +WantedBy=multi-user.target +``` + +This is the official Atuin service unit file which includes a lot of hardening options to increase +security. + +Next, create [`atuin-server.conf`](https://github.com/atuinsh/atuin/raw/main/systemd/atuin-server.sysusers) at +`/etc/sysusers.d/atuin-server.conf` with contents like this: + +``` +u atuin - "Atuin synchronized shell history" +``` +This file will ensure a system user is created in the proper manner. + +Afterwards, run +```sh +systemctl restart systemd-sysusers +``` +to make sure the file is read. A new `atuin-server` user should then be available. + +Now, you can attempt to run the Atuin server: +```sh +systemctl enable --now atuin-server +``` + +```sh +systemctl status atuin-server +``` + +If it started fine, it should have created the default config inside `/etc/atuin/`. diff --git a/docs/docs/self-hosting/usage.md b/docs/docs/self-hosting/usage.md new file mode 100644 index 00000000..c5f598e8 --- /dev/null +++ b/docs/docs/self-hosting/usage.md @@ -0,0 +1,14 @@ +# Using a self hosted server + +!!! warning + If you are self hosting, we strongly suggest you stick to tagged releases, and do not follow `main` or `latest` + + Follow the GitHub releases, and please read the notes for each release. Most of the time, upgrades can occur without any manual intervention. + + We cannot guarantee that all updates will apply cleanly, and some may require some extra steps. + +## Client setup + +In order use a self hosted server with Atuin, you'll have to set up the `sync_address` in the config file at `~/.config/atuin/config.toml`. See the [config](../configuration/config.md#sync_address) page for more details on how to set the `sync_address`. + +Alternatively you can set the environment variable `ATUIN_SYNC_ADDRESS` to the correct host ie.: `ATUIN_SYNC_ADDRESS=https://api.atuin.sh`. diff --git a/docs/docs/sync-v2.md b/docs/docs/sync-v2.md new file mode 100644 index 00000000..9055794d --- /dev/null +++ b/docs/docs/sync-v2.md @@ -0,0 +1,27 @@ +# Sync v2 + +Just installed Atuin? Don't worry about this page, everything should be setup +for you. + +If you've been using Atuin for a while, you might not be using the best sync. A +long time ago, we shipped sync v1. It was "good enough", but never intended for +the wide use it ended up getting. + +After evaluating issues and feedback from users, we developed sync v2. It +includes a whole bunch of changes that I'll save writing about for a future +blog post or deep dive, but suffice to say it's + +1. Faster +2. More reliable +3. Uses less bandwidth +4. Supports many more features +5. Recovers from issues more effectively + +There's really no reason to not use it. + +You can opt in with the following configuration + +```toml +[sync] +records = true +``` diff --git a/docs/docs/uninstall.md b/docs/docs/uninstall.md new file mode 100644 index 00000000..77008ab6 --- /dev/null +++ b/docs/docs/uninstall.md @@ -0,0 +1,19 @@ +# Uninstalling Atuin + +Sorry to see you go! + +If you used the Atuin installer, you can totally delete it by removing the following + +1. Delete the ~/.atuin directory +2. Delete the ~/.local/share/atuin directory +3. Remove the line referencing "atuin init" from your shell config + +Otherwise, uninstalling Atuin depends on your system, and how you installed it. + +EG, on macOS, you'd want to run + +``` +brew uninstall atuin +``` + +and then remove the shell integration. diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml new file mode 100644 index 00000000..1d435de9 --- /dev/null +++ b/docs/mkdocs.yml @@ -0,0 +1,92 @@ +site_name: Atuin CLI Docs +site_url: https://docs.atuin.sh/cli/ + +repo_name: atuinsh/atuin +repo_url: https://github.com/atuinsh/atuin +edit_uri: edit/main/docs/docs/ + +theme: + name: material + palette: + - scheme: default + primary: deep purple + accent: deep purple + toggle: + icon: material/brightness-7 + name: Switch to dark mode + - scheme: slate + primary: deep purple + accent: deep purple + toggle: + icon: material/brightness-4 + name: Switch to light mode + features: + - navigation.sections + - navigation.expand + - search.suggest + - search.highlight + - content.code.copy + - content.action.edit + - content.action.view + +plugins: + - search + - multirepo: + imported_repo: true + url: https://github.com/atuinsh/docs + section_name: CLI + paths: ["mkdocs.yml", "docs/index.md", "docs/stylesheets/*"] + yml_file: mkdocs.yml + branch: mkt/docs-migration + +markdown_extensions: + - pymdownx.highlight: + anchor_linenums: true + - pymdownx.superfences + - pymdownx.tabbed: + alternate_style: true + - admonition + - pymdownx.details + - attr_list + - md_in_html + - tables + - pymdownx.keys + - pymdownx.emoji: + emoji_index: !!python/name:material.extensions.emoji.twemoji + emoji_generator: !!python/name:material.extensions.emoji.to_svg + +nav: + - Home: index.md + - Guide: + - Getting Started: guide/getting-started.md + - Installation: guide/installation.md + - Setting up sync: guide/sync.md + - Import existing history: guide/import.md + - Basic usage: guide/basic-usage.md + - Syncing dotfiles: guide/dotfiles.md + - Theming: guide/theming.md + - Configuration: + - Config: configuration/config.md + - Key Binding: configuration/key-binding.md + - Reference: + - doctor: reference/doctor.md + - daemon: reference/daemon.md + - gen-completions: reference/gen-completions.md + - import: reference/import.md + - info: reference/info.md + - history list: reference/list.md + - history prune: reference/prune.md + - search: reference/search.md + - stats: reference/stats.md + - sync: reference/sync.md + - Self Hosting: + - Server Setup: self-hosting/server-setup.md + - Usage: self-hosting/usage.md + - Docker: self-hosting/docker.md + - Kubernetes: self-hosting/kubernetes.md + - Systemd: self-hosting/systemd.md + - Known Issues: known-issues.md + - Integrations: integrations.md + - FAQ: faq.md + - Uninstall: uninstall.md + - Sync v2: sync-v2.md diff --git a/docs/pyproject.toml b/docs/pyproject.toml new file mode 100644 index 00000000..e3bef982 --- /dev/null +++ b/docs/pyproject.toml @@ -0,0 +1,15 @@ +[project] +name = "atuin-cli-docs" +version = "1.0.0" +description = "Atuin CLI documentation" +requires-python = ">=3.11" +dependencies = [ + "mkdocs-material>=9.5", + "mkdocs-multirepo-plugin @ git+https://github.com/atuinsh/mkdocs-multirepo-plugin@mkt/imported_repo", + "mkdocs-git-revision-date-localized-plugin>=1.2", + "mkdocs-glightbox>=0.4", + "mkdocs-redirects>=1.2.2", +] + +[dependency-groups] +dev = [] diff --git a/docs/uv.lock b/docs/uv.lock new file mode 100644 index 00000000..9575e6ea --- /dev/null +++ b/docs/uv.lock @@ -0,0 +1,750 @@ +version = 1 +revision = 3 +requires-python = ">=3.11" + +[[package]] +name = "atuin-cli-docs" +version = "1.0.0" +source = { virtual = "." } +dependencies = [ + { name = "mkdocs-git-revision-date-localized-plugin" }, + { name = "mkdocs-glightbox" }, + { name = "mkdocs-material" }, + { name = "mkdocs-multirepo-plugin" }, + { name = "mkdocs-redirects" }, +] + +[package.metadata] +requires-dist = [ + { name = "mkdocs-git-revision-date-localized-plugin", specifier = ">=1.2" }, + { name = "mkdocs-glightbox", specifier = ">=0.4" }, + { name = "mkdocs-material", specifier = ">=9.5" }, + { name = "mkdocs-multirepo-plugin", git = "https://github.com/atuinsh/mkdocs-multirepo-plugin?rev=mkt%2Fimported_repo" }, + { name = "mkdocs-redirects", specifier = ">=1.2.2" }, +] + +[package.metadata.requires-dev] +dev = [] + +[[package]] +name = "babel" +version = "2.17.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/7d/6b/d52e42361e1aa00709585ecc30b3f9684b3ab62530771402248b1b1d6240/babel-2.17.0.tar.gz", hash = "sha256:0c54cffb19f690cdcc52a3b50bcbf71e07a808d1c80d549f2459b9d2cf0afb9d", size = 9951852, upload-time = "2025-02-01T15:17:41.026Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b7/b8/3fe70c75fe32afc4bb507f75563d39bc5642255d1d94f1f23604725780bf/babel-2.17.0-py3-none-any.whl", hash = "sha256:4d0b53093fdfb4b21c92b5213dba5a1b23885afa8383709427046b21c366e5f2", size = 10182537, upload-time = "2025-02-01T15:17:37.39Z" }, +] + +[[package]] +name = "backrefs" +version = "6.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/86/e3/bb3a439d5cb255c4774724810ad8073830fac9c9dee123555820c1bcc806/backrefs-6.1.tar.gz", hash = "sha256:3bba1749aafe1db9b915f00e0dd166cba613b6f788ffd63060ac3485dc9be231", size = 7011962, upload-time = "2025-11-15T14:52:08.323Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3b/ee/c216d52f58ea75b5e1841022bbae24438b19834a29b163cb32aa3a2a7c6e/backrefs-6.1-py310-none-any.whl", hash = "sha256:2a2ccb96302337ce61ee4717ceacfbf26ba4efb1d55af86564b8bbaeda39cac1", size = 381059, upload-time = "2025-11-15T14:51:59.758Z" }, + { url = "https://files.pythonhosted.org/packages/e6/9a/8da246d988ded941da96c7ed945d63e94a445637eaad985a0ed88787cb89/backrefs-6.1-py311-none-any.whl", hash = "sha256:e82bba3875ee4430f4de4b6db19429a27275d95a5f3773c57e9e18abc23fd2b7", size = 392854, upload-time = "2025-11-15T14:52:01.194Z" }, + { url = "https://files.pythonhosted.org/packages/37/c9/fd117a6f9300c62bbc33bc337fd2b3c6bfe28b6e9701de336b52d7a797ad/backrefs-6.1-py312-none-any.whl", hash = "sha256:c64698c8d2269343d88947c0735cb4b78745bd3ba590e10313fbf3f78c34da5a", size = 398770, upload-time = "2025-11-15T14:52:02.584Z" }, + { url = "https://files.pythonhosted.org/packages/eb/95/7118e935b0b0bd3f94dfec2d852fd4e4f4f9757bdb49850519acd245cd3a/backrefs-6.1-py313-none-any.whl", hash = "sha256:4c9d3dc1e2e558965202c012304f33d4e0e477e1c103663fd2c3cc9bb18b0d05", size = 400726, upload-time = "2025-11-15T14:52:04.093Z" }, + { url = "https://files.pythonhosted.org/packages/1d/72/6296bad135bfafd3254ae3648cd152980a424bd6fed64a101af00cc7ba31/backrefs-6.1-py314-none-any.whl", hash = "sha256:13eafbc9ccd5222e9c1f0bec563e6d2a6d21514962f11e7fc79872fd56cbc853", size = 412584, upload-time = "2025-11-15T14:52:05.233Z" }, + { url = "https://files.pythonhosted.org/packages/02/e3/a4fa1946722c4c7b063cc25043a12d9ce9b4323777f89643be74cef2993c/backrefs-6.1-py39-none-any.whl", hash = "sha256:a9e99b8a4867852cad177a6430e31b0f6e495d65f8c6c134b68c14c3c95bf4b0", size = 381058, upload-time = "2025-11-15T14:52:06.698Z" }, +] + +[[package]] +name = "certifi" +version = "2025.11.12" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a2/8c/58f469717fa48465e4a50c014a0400602d3c437d7c0c468e17ada824da3a/certifi-2025.11.12.tar.gz", hash = "sha256:d8ab5478f2ecd78af242878415affce761ca6bc54a22a27e026d7c25357c3316", size = 160538, upload-time = "2025-11-12T02:54:51.517Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/70/7d/9bc192684cea499815ff478dfcdc13835ddf401365057044fb721ec6bddb/certifi-2025.11.12-py3-none-any.whl", hash = "sha256:97de8790030bbd5c2d96b7ec782fc2f7820ef8dba6db909ccf95449f2d062d4b", size = 159438, upload-time = "2025-11-12T02:54:49.735Z" }, +] + +[[package]] +name = "charset-normalizer" +version = "3.4.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/13/69/33ddede1939fdd074bce5434295f38fae7136463422fe4fd3e0e89b98062/charset_normalizer-3.4.4.tar.gz", hash = "sha256:94537985111c35f28720e43603b8e7b43a6ecfb2ce1d3058bbe955b73404e21a", size = 129418, upload-time = "2025-10-14T04:42:32.879Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ed/27/c6491ff4954e58a10f69ad90aca8a1b6fe9c5d3c6f380907af3c37435b59/charset_normalizer-3.4.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6e1fcf0720908f200cd21aa4e6750a48ff6ce4afe7ff5a79a90d5ed8a08296f8", size = 206988, upload-time = "2025-10-14T04:40:33.79Z" }, + { url = "https://files.pythonhosted.org/packages/94/59/2e87300fe67ab820b5428580a53cad894272dbb97f38a7a814a2a1ac1011/charset_normalizer-3.4.4-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5f819d5fe9234f9f82d75bdfa9aef3a3d72c4d24a6e57aeaebba32a704553aa0", size = 147324, upload-time = "2025-10-14T04:40:34.961Z" }, + { url = "https://files.pythonhosted.org/packages/07/fb/0cf61dc84b2b088391830f6274cb57c82e4da8bbc2efeac8c025edb88772/charset_normalizer-3.4.4-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:a59cb51917aa591b1c4e6a43c132f0cdc3c76dbad6155df4e28ee626cc77a0a3", size = 142742, upload-time = "2025-10-14T04:40:36.105Z" }, + { url = "https://files.pythonhosted.org/packages/62/8b/171935adf2312cd745d290ed93cf16cf0dfe320863ab7cbeeae1dcd6535f/charset_normalizer-3.4.4-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:8ef3c867360f88ac904fd3f5e1f902f13307af9052646963ee08ff4f131adafc", size = 160863, upload-time = "2025-10-14T04:40:37.188Z" }, + { url = "https://files.pythonhosted.org/packages/09/73/ad875b192bda14f2173bfc1bc9a55e009808484a4b256748d931b6948442/charset_normalizer-3.4.4-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d9e45d7faa48ee908174d8fe84854479ef838fc6a705c9315372eacbc2f02897", size = 157837, upload-time = "2025-10-14T04:40:38.435Z" }, + { url = "https://files.pythonhosted.org/packages/6d/fc/de9cce525b2c5b94b47c70a4b4fb19f871b24995c728e957ee68ab1671ea/charset_normalizer-3.4.4-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:840c25fb618a231545cbab0564a799f101b63b9901f2569faecd6b222ac72381", size = 151550, upload-time = "2025-10-14T04:40:40.053Z" }, + { url = "https://files.pythonhosted.org/packages/55/c2/43edd615fdfba8c6f2dfbd459b25a6b3b551f24ea21981e23fb768503ce1/charset_normalizer-3.4.4-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:ca5862d5b3928c4940729dacc329aa9102900382fea192fc5e52eb69d6093815", size = 149162, upload-time = "2025-10-14T04:40:41.163Z" }, + { url = "https://files.pythonhosted.org/packages/03/86/bde4ad8b4d0e9429a4e82c1e8f5c659993a9a863ad62c7df05cf7b678d75/charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d9c7f57c3d666a53421049053eaacdd14bbd0a528e2186fcb2e672effd053bb0", size = 150019, upload-time = "2025-10-14T04:40:42.276Z" }, + { url = "https://files.pythonhosted.org/packages/1f/86/a151eb2af293a7e7bac3a739b81072585ce36ccfb4493039f49f1d3cae8c/charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:277e970e750505ed74c832b4bf75dac7476262ee2a013f5574dd49075879e161", size = 143310, upload-time = "2025-10-14T04:40:43.439Z" }, + { url = "https://files.pythonhosted.org/packages/b5/fe/43dae6144a7e07b87478fdfc4dbe9efd5defb0e7ec29f5f58a55aeef7bf7/charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:31fd66405eaf47bb62e8cd575dc621c56c668f27d46a61d975a249930dd5e2a4", size = 162022, upload-time = "2025-10-14T04:40:44.547Z" }, + { url = "https://files.pythonhosted.org/packages/80/e6/7aab83774f5d2bca81f42ac58d04caf44f0cc2b65fc6db2b3b2e8a05f3b3/charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:0d3d8f15c07f86e9ff82319b3d9ef6f4bf907608f53fe9d92b28ea9ae3d1fd89", size = 149383, upload-time = "2025-10-14T04:40:46.018Z" }, + { url = "https://files.pythonhosted.org/packages/4f/e8/b289173b4edae05c0dde07f69f8db476a0b511eac556dfe0d6bda3c43384/charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:9f7fcd74d410a36883701fafa2482a6af2ff5ba96b9a620e9e0721e28ead5569", size = 159098, upload-time = "2025-10-14T04:40:47.081Z" }, + { url = "https://files.pythonhosted.org/packages/d8/df/fe699727754cae3f8478493c7f45f777b17c3ef0600e28abfec8619eb49c/charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ebf3e58c7ec8a8bed6d66a75d7fb37b55e5015b03ceae72a8e7c74495551e224", size = 152991, upload-time = "2025-10-14T04:40:48.246Z" }, + { url = "https://files.pythonhosted.org/packages/1a/86/584869fe4ddb6ffa3bd9f491b87a01568797fb9bd8933f557dba9771beaf/charset_normalizer-3.4.4-cp311-cp311-win32.whl", hash = "sha256:eecbc200c7fd5ddb9a7f16c7decb07b566c29fa2161a16cf67b8d068bd21690a", size = 99456, upload-time = "2025-10-14T04:40:49.376Z" }, + { url = "https://files.pythonhosted.org/packages/65/f6/62fdd5feb60530f50f7e38b4f6a1d5203f4d16ff4f9f0952962c044e919a/charset_normalizer-3.4.4-cp311-cp311-win_amd64.whl", hash = "sha256:5ae497466c7901d54b639cf42d5b8c1b6a4fead55215500d2f486d34db48d016", size = 106978, upload-time = "2025-10-14T04:40:50.844Z" }, + { url = "https://files.pythonhosted.org/packages/7a/9d/0710916e6c82948b3be62d9d398cb4fcf4e97b56d6a6aeccd66c4b2f2bd5/charset_normalizer-3.4.4-cp311-cp311-win_arm64.whl", hash = "sha256:65e2befcd84bc6f37095f5961e68a6f077bf44946771354a28ad434c2cce0ae1", size = 99969, upload-time = "2025-10-14T04:40:52.272Z" }, + { url = "https://files.pythonhosted.org/packages/f3/85/1637cd4af66fa687396e757dec650f28025f2a2f5a5531a3208dc0ec43f2/charset_normalizer-3.4.4-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0a98e6759f854bd25a58a73fa88833fba3b7c491169f86ce1180c948ab3fd394", size = 208425, upload-time = "2025-10-14T04:40:53.353Z" }, + { url = "https://files.pythonhosted.org/packages/9d/6a/04130023fef2a0d9c62d0bae2649b69f7b7d8d24ea5536feef50551029df/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b5b290ccc2a263e8d185130284f8501e3e36c5e02750fc6b6bdeb2e9e96f1e25", size = 148162, upload-time = "2025-10-14T04:40:54.558Z" }, + { url = "https://files.pythonhosted.org/packages/78/29/62328d79aa60da22c9e0b9a66539feae06ca0f5a4171ac4f7dc285b83688/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:74bb723680f9f7a6234dcf67aea57e708ec1fbdf5699fb91dfd6f511b0a320ef", size = 144558, upload-time = "2025-10-14T04:40:55.677Z" }, + { url = "https://files.pythonhosted.org/packages/86/bb/b32194a4bf15b88403537c2e120b817c61cd4ecffa9b6876e941c3ee38fe/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f1e34719c6ed0b92f418c7c780480b26b5d9c50349e9a9af7d76bf757530350d", size = 161497, upload-time = "2025-10-14T04:40:57.217Z" }, + { url = "https://files.pythonhosted.org/packages/19/89/a54c82b253d5b9b111dc74aca196ba5ccfcca8242d0fb64146d4d3183ff1/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:2437418e20515acec67d86e12bf70056a33abdacb5cb1655042f6538d6b085a8", size = 159240, upload-time = "2025-10-14T04:40:58.358Z" }, + { url = "https://files.pythonhosted.org/packages/c0/10/d20b513afe03acc89ec33948320a5544d31f21b05368436d580dec4e234d/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:11d694519d7f29d6cd09f6ac70028dba10f92f6cdd059096db198c283794ac86", size = 153471, upload-time = "2025-10-14T04:40:59.468Z" }, + { url = "https://files.pythonhosted.org/packages/61/fa/fbf177b55bdd727010f9c0a3c49eefa1d10f960e5f09d1d887bf93c2e698/charset_normalizer-3.4.4-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:ac1c4a689edcc530fc9d9aa11f5774b9e2f33f9a0c6a57864e90908f5208d30a", size = 150864, upload-time = "2025-10-14T04:41:00.623Z" }, + { url = "https://files.pythonhosted.org/packages/05/12/9fbc6a4d39c0198adeebbde20b619790e9236557ca59fc40e0e3cebe6f40/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:21d142cc6c0ec30d2efee5068ca36c128a30b0f2c53c1c07bd78cb6bc1d3be5f", size = 150647, upload-time = "2025-10-14T04:41:01.754Z" }, + { url = "https://files.pythonhosted.org/packages/ad/1f/6a9a593d52e3e8c5d2b167daf8c6b968808efb57ef4c210acb907c365bc4/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:5dbe56a36425d26d6cfb40ce79c314a2e4dd6211d51d6d2191c00bed34f354cc", size = 145110, upload-time = "2025-10-14T04:41:03.231Z" }, + { url = "https://files.pythonhosted.org/packages/30/42/9a52c609e72471b0fc54386dc63c3781a387bb4fe61c20231a4ebcd58bdd/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:5bfbb1b9acf3334612667b61bd3002196fe2a1eb4dd74d247e0f2a4d50ec9bbf", size = 162839, upload-time = "2025-10-14T04:41:04.715Z" }, + { url = "https://files.pythonhosted.org/packages/c4/5b/c0682bbf9f11597073052628ddd38344a3d673fda35a36773f7d19344b23/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:d055ec1e26e441f6187acf818b73564e6e6282709e9bcb5b63f5b23068356a15", size = 150667, upload-time = "2025-10-14T04:41:05.827Z" }, + { url = "https://files.pythonhosted.org/packages/e4/24/a41afeab6f990cf2daf6cb8c67419b63b48cf518e4f56022230840c9bfb2/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:af2d8c67d8e573d6de5bc30cdb27e9b95e49115cd9baad5ddbd1a6207aaa82a9", size = 160535, upload-time = "2025-10-14T04:41:06.938Z" }, + { url = "https://files.pythonhosted.org/packages/2a/e5/6a4ce77ed243c4a50a1fecca6aaaab419628c818a49434be428fe24c9957/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:780236ac706e66881f3b7f2f32dfe90507a09e67d1d454c762cf642e6e1586e0", size = 154816, upload-time = "2025-10-14T04:41:08.101Z" }, + { url = "https://files.pythonhosted.org/packages/a8/ef/89297262b8092b312d29cdb2517cb1237e51db8ecef2e9af5edbe7b683b1/charset_normalizer-3.4.4-cp312-cp312-win32.whl", hash = "sha256:5833d2c39d8896e4e19b689ffc198f08ea58116bee26dea51e362ecc7cd3ed26", size = 99694, upload-time = "2025-10-14T04:41:09.23Z" }, + { url = "https://files.pythonhosted.org/packages/3d/2d/1e5ed9dd3b3803994c155cd9aacb60c82c331bad84daf75bcb9c91b3295e/charset_normalizer-3.4.4-cp312-cp312-win_amd64.whl", hash = "sha256:a79cfe37875f822425b89a82333404539ae63dbdddf97f84dcbc3d339aae9525", size = 107131, upload-time = "2025-10-14T04:41:10.467Z" }, + { url = "https://files.pythonhosted.org/packages/d0/d9/0ed4c7098a861482a7b6a95603edce4c0d9db2311af23da1fb2b75ec26fc/charset_normalizer-3.4.4-cp312-cp312-win_arm64.whl", hash = "sha256:376bec83a63b8021bb5c8ea75e21c4ccb86e7e45ca4eb81146091b56599b80c3", size = 100390, upload-time = "2025-10-14T04:41:11.915Z" }, + { url = "https://files.pythonhosted.org/packages/97/45/4b3a1239bbacd321068ea6e7ac28875b03ab8bc0aa0966452db17cd36714/charset_normalizer-3.4.4-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:e1f185f86a6f3403aa2420e815904c67b2f9ebc443f045edd0de921108345794", size = 208091, upload-time = "2025-10-14T04:41:13.346Z" }, + { url = "https://files.pythonhosted.org/packages/7d/62/73a6d7450829655a35bb88a88fca7d736f9882a27eacdca2c6d505b57e2e/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b39f987ae8ccdf0d2642338faf2abb1862340facc796048b604ef14919e55ed", size = 147936, upload-time = "2025-10-14T04:41:14.461Z" }, + { url = "https://files.pythonhosted.org/packages/89/c5/adb8c8b3d6625bef6d88b251bbb0d95f8205831b987631ab0c8bb5d937c2/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3162d5d8ce1bb98dd51af660f2121c55d0fa541b46dff7bb9b9f86ea1d87de72", size = 144180, upload-time = "2025-10-14T04:41:15.588Z" }, + { url = "https://files.pythonhosted.org/packages/91/ed/9706e4070682d1cc219050b6048bfd293ccf67b3d4f5a4f39207453d4b99/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:81d5eb2a312700f4ecaa977a8235b634ce853200e828fbadf3a9c50bab278328", size = 161346, upload-time = "2025-10-14T04:41:16.738Z" }, + { url = "https://files.pythonhosted.org/packages/d5/0d/031f0d95e4972901a2f6f09ef055751805ff541511dc1252ba3ca1f80cf5/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5bd2293095d766545ec1a8f612559f6b40abc0eb18bb2f5d1171872d34036ede", size = 158874, upload-time = "2025-10-14T04:41:17.923Z" }, + { url = "https://files.pythonhosted.org/packages/f5/83/6ab5883f57c9c801ce5e5677242328aa45592be8a00644310a008d04f922/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a8a8b89589086a25749f471e6a900d3f662d1d3b6e2e59dcecf787b1cc3a1894", size = 153076, upload-time = "2025-10-14T04:41:19.106Z" }, + { url = "https://files.pythonhosted.org/packages/75/1e/5ff781ddf5260e387d6419959ee89ef13878229732732ee73cdae01800f2/charset_normalizer-3.4.4-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:bc7637e2f80d8530ee4a78e878bce464f70087ce73cf7c1caf142416923b98f1", size = 150601, upload-time = "2025-10-14T04:41:20.245Z" }, + { url = "https://files.pythonhosted.org/packages/d7/57/71be810965493d3510a6ca79b90c19e48696fb1ff964da319334b12677f0/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f8bf04158c6b607d747e93949aa60618b61312fe647a6369f88ce2ff16043490", size = 150376, upload-time = "2025-10-14T04:41:21.398Z" }, + { url = "https://files.pythonhosted.org/packages/e5/d5/c3d057a78c181d007014feb7e9f2e65905a6c4ef182c0ddf0de2924edd65/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:554af85e960429cf30784dd47447d5125aaa3b99a6f0683589dbd27e2f45da44", size = 144825, upload-time = "2025-10-14T04:41:22.583Z" }, + { url = "https://files.pythonhosted.org/packages/e6/8c/d0406294828d4976f275ffbe66f00266c4b3136b7506941d87c00cab5272/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:74018750915ee7ad843a774364e13a3db91682f26142baddf775342c3f5b1133", size = 162583, upload-time = "2025-10-14T04:41:23.754Z" }, + { url = "https://files.pythonhosted.org/packages/d7/24/e2aa1f18c8f15c4c0e932d9287b8609dd30ad56dbe41d926bd846e22fb8d/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:c0463276121fdee9c49b98908b3a89c39be45d86d1dbaa22957e38f6321d4ce3", size = 150366, upload-time = "2025-10-14T04:41:25.27Z" }, + { url = "https://files.pythonhosted.org/packages/e4/5b/1e6160c7739aad1e2df054300cc618b06bf784a7a164b0f238360721ab86/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:362d61fd13843997c1c446760ef36f240cf81d3ebf74ac62652aebaf7838561e", size = 160300, upload-time = "2025-10-14T04:41:26.725Z" }, + { url = "https://files.pythonhosted.org/packages/7a/10/f882167cd207fbdd743e55534d5d9620e095089d176d55cb22d5322f2afd/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9a26f18905b8dd5d685d6d07b0cdf98a79f3c7a918906af7cc143ea2e164c8bc", size = 154465, upload-time = "2025-10-14T04:41:28.322Z" }, + { url = "https://files.pythonhosted.org/packages/89/66/c7a9e1b7429be72123441bfdbaf2bc13faab3f90b933f664db506dea5915/charset_normalizer-3.4.4-cp313-cp313-win32.whl", hash = "sha256:9b35f4c90079ff2e2edc5b26c0c77925e5d2d255c42c74fdb70fb49b172726ac", size = 99404, upload-time = "2025-10-14T04:41:29.95Z" }, + { url = "https://files.pythonhosted.org/packages/c4/26/b9924fa27db384bdcd97ab83b4f0a8058d96ad9626ead570674d5e737d90/charset_normalizer-3.4.4-cp313-cp313-win_amd64.whl", hash = "sha256:b435cba5f4f750aa6c0a0d92c541fb79f69a387c91e61f1795227e4ed9cece14", size = 107092, upload-time = "2025-10-14T04:41:31.188Z" }, + { url = "https://files.pythonhosted.org/packages/af/8f/3ed4bfa0c0c72a7ca17f0380cd9e4dd842b09f664e780c13cff1dcf2ef1b/charset_normalizer-3.4.4-cp313-cp313-win_arm64.whl", hash = "sha256:542d2cee80be6f80247095cc36c418f7bddd14f4a6de45af91dfad36d817bba2", size = 100408, upload-time = "2025-10-14T04:41:32.624Z" }, + { url = "https://files.pythonhosted.org/packages/2a/35/7051599bd493e62411d6ede36fd5af83a38f37c4767b92884df7301db25d/charset_normalizer-3.4.4-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:da3326d9e65ef63a817ecbcc0df6e94463713b754fe293eaa03da99befb9a5bd", size = 207746, upload-time = "2025-10-14T04:41:33.773Z" }, + { url = "https://files.pythonhosted.org/packages/10/9a/97c8d48ef10d6cd4fcead2415523221624bf58bcf68a802721a6bc807c8f/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8af65f14dc14a79b924524b1e7fffe304517b2bff5a58bf64f30b98bbc5079eb", size = 147889, upload-time = "2025-10-14T04:41:34.897Z" }, + { url = "https://files.pythonhosted.org/packages/10/bf/979224a919a1b606c82bd2c5fa49b5c6d5727aa47b4312bb27b1734f53cd/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:74664978bb272435107de04e36db5a9735e78232b85b77d45cfb38f758efd33e", size = 143641, upload-time = "2025-10-14T04:41:36.116Z" }, + { url = "https://files.pythonhosted.org/packages/ba/33/0ad65587441fc730dc7bd90e9716b30b4702dc7b617e6ba4997dc8651495/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:752944c7ffbfdd10c074dc58ec2d5a8a4cd9493b314d367c14d24c17684ddd14", size = 160779, upload-time = "2025-10-14T04:41:37.229Z" }, + { url = "https://files.pythonhosted.org/packages/67/ed/331d6b249259ee71ddea93f6f2f0a56cfebd46938bde6fcc6f7b9a3d0e09/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d1f13550535ad8cff21b8d757a3257963e951d96e20ec82ab44bc64aeb62a191", size = 159035, upload-time = "2025-10-14T04:41:38.368Z" }, + { url = "https://files.pythonhosted.org/packages/67/ff/f6b948ca32e4f2a4576aa129d8bed61f2e0543bf9f5f2b7fc3758ed005c9/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ecaae4149d99b1c9e7b88bb03e3221956f68fd6d50be2ef061b2381b61d20838", size = 152542, upload-time = "2025-10-14T04:41:39.862Z" }, + { url = "https://files.pythonhosted.org/packages/16/85/276033dcbcc369eb176594de22728541a925b2632f9716428c851b149e83/charset_normalizer-3.4.4-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:cb6254dc36b47a990e59e1068afacdcd02958bdcce30bb50cc1700a8b9d624a6", size = 149524, upload-time = "2025-10-14T04:41:41.319Z" }, + { url = "https://files.pythonhosted.org/packages/9e/f2/6a2a1f722b6aba37050e626530a46a68f74e63683947a8acff92569f979a/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c8ae8a0f02f57a6e61203a31428fa1d677cbe50c93622b4149d5c0f319c1d19e", size = 150395, upload-time = "2025-10-14T04:41:42.539Z" }, + { url = "https://files.pythonhosted.org/packages/60/bb/2186cb2f2bbaea6338cad15ce23a67f9b0672929744381e28b0592676824/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:47cc91b2f4dd2833fddaedd2893006b0106129d4b94fdb6af1f4ce5a9965577c", size = 143680, upload-time = "2025-10-14T04:41:43.661Z" }, + { url = "https://files.pythonhosted.org/packages/7d/a5/bf6f13b772fbb2a90360eb620d52ed8f796f3c5caee8398c3b2eb7b1c60d/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:82004af6c302b5d3ab2cfc4cc5f29db16123b1a8417f2e25f9066f91d4411090", size = 162045, upload-time = "2025-10-14T04:41:44.821Z" }, + { url = "https://files.pythonhosted.org/packages/df/c5/d1be898bf0dc3ef9030c3825e5d3b83f2c528d207d246cbabe245966808d/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:2b7d8f6c26245217bd2ad053761201e9f9680f8ce52f0fcd8d0755aeae5b2152", size = 149687, upload-time = "2025-10-14T04:41:46.442Z" }, + { url = "https://files.pythonhosted.org/packages/a5/42/90c1f7b9341eef50c8a1cb3f098ac43b0508413f33affd762855f67a410e/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:799a7a5e4fb2d5898c60b640fd4981d6a25f1c11790935a44ce38c54e985f828", size = 160014, upload-time = "2025-10-14T04:41:47.631Z" }, + { url = "https://files.pythonhosted.org/packages/76/be/4d3ee471e8145d12795ab655ece37baed0929462a86e72372fd25859047c/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:99ae2cffebb06e6c22bdc25801d7b30f503cc87dbd283479e7b606f70aff57ec", size = 154044, upload-time = "2025-10-14T04:41:48.81Z" }, + { url = "https://files.pythonhosted.org/packages/b0/6f/8f7af07237c34a1defe7defc565a9bc1807762f672c0fde711a4b22bf9c0/charset_normalizer-3.4.4-cp314-cp314-win32.whl", hash = "sha256:f9d332f8c2a2fcbffe1378594431458ddbef721c1769d78e2cbc06280d8155f9", size = 99940, upload-time = "2025-10-14T04:41:49.946Z" }, + { url = "https://files.pythonhosted.org/packages/4b/51/8ade005e5ca5b0d80fb4aff72a3775b325bdc3d27408c8113811a7cbe640/charset_normalizer-3.4.4-cp314-cp314-win_amd64.whl", hash = "sha256:8a6562c3700cce886c5be75ade4a5db4214fda19fede41d9792d100288d8f94c", size = 107104, upload-time = "2025-10-14T04:41:51.051Z" }, + { url = "https://files.pythonhosted.org/packages/da/5f/6b8f83a55bb8278772c5ae54a577f3099025f9ade59d0136ac24a0df4bde/charset_normalizer-3.4.4-cp314-cp314-win_arm64.whl", hash = "sha256:de00632ca48df9daf77a2c65a484531649261ec9f25489917f09e455cb09ddb2", size = 100743, upload-time = "2025-10-14T04:41:52.122Z" }, + { url = "https://files.pythonhosted.org/packages/0a/4c/925909008ed5a988ccbb72dcc897407e5d6d3bd72410d69e051fc0c14647/charset_normalizer-3.4.4-py3-none-any.whl", hash = "sha256:7a32c560861a02ff789ad905a2fe94e3f840803362c84fecf1851cb4cf3dc37f", size = 53402, upload-time = "2025-10-14T04:42:31.76Z" }, +] + +[[package]] +name = "click" +version = "8.3.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/3d/fa/656b739db8587d7b5dfa22e22ed02566950fbfbcdc20311993483657a5c0/click-8.3.1.tar.gz", hash = "sha256:12ff4785d337a1bb490bb7e9c2b1ee5da3112e94a8622f26a6c77f5d2fc6842a", size = 295065, upload-time = "2025-11-15T20:45:42.706Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/98/78/01c019cdb5d6498122777c1a43056ebb3ebfeef2076d9d026bfe15583b2b/click-8.3.1-py3-none-any.whl", hash = "sha256:981153a64e25f12d547d3426c367a4857371575ee7ad18df2a6183ab0545b2a6", size = 108274, upload-time = "2025-11-15T20:45:41.139Z" }, +] + +[[package]] +name = "colorama" +version = "0.4.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, +] + +[[package]] +name = "dacite" +version = "1.9.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/55/a0/7ca79796e799a3e782045d29bf052b5cde7439a2bbb17f15ff44f7aacc63/dacite-1.9.2.tar.gz", hash = "sha256:6ccc3b299727c7aa17582f0021f6ae14d5de47c7227932c47fec4cdfefd26f09", size = 22420, upload-time = "2025-02-05T09:27:29.757Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/94/35/386550fd60316d1e37eccdda609b074113298f23cef5bddb2049823fe666/dacite-1.9.2-py3-none-any.whl", hash = "sha256:053f7c3f5128ca2e9aceb66892b1a3c8936d02c686e707bee96e19deef4bc4a0", size = 16600, upload-time = "2025-02-05T09:27:24.345Z" }, +] + +[[package]] +name = "ghp-import" +version = "2.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "python-dateutil" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/d9/29/d40217cbe2f6b1359e00c6c307bb3fc876ba74068cbab3dde77f03ca0dc4/ghp-import-2.1.0.tar.gz", hash = "sha256:9c535c4c61193c2df8871222567d7fd7e5014d835f97dc7b7439069e2413d343", size = 10943, upload-time = "2022-05-02T15:47:16.11Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f7/ec/67fbef5d497f86283db54c22eec6f6140243aae73265799baaaa19cd17fb/ghp_import-2.1.0-py3-none-any.whl", hash = "sha256:8337dd7b50877f163d4c0289bc1f1c7f127550241988d568c1db512c4324a619", size = 11034, upload-time = "2022-05-02T15:47:14.552Z" }, +] + +[[package]] +name = "gitdb" +version = "4.0.12" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "smmap" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/72/94/63b0fc47eb32792c7ba1fe1b694daec9a63620db1e313033d18140c2320a/gitdb-4.0.12.tar.gz", hash = "sha256:5ef71f855d191a3326fcfbc0d5da835f26b13fbcba60c32c21091c349ffdb571", size = 394684, upload-time = "2025-01-02T07:20:46.413Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a0/61/5c78b91c3143ed5c14207f463aecfc8f9dbb5092fb2869baf37c273b2705/gitdb-4.0.12-py3-none-any.whl", hash = "sha256:67073e15955400952c6565cc3e707c554a4eea2e428946f7a4c162fab9bd9bcf", size = 62794, upload-time = "2025-01-02T07:20:43.624Z" }, +] + +[[package]] +name = "gitpython" +version = "3.1.45" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "gitdb" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/9a/c8/dd58967d119baab745caec2f9d853297cec1989ec1d63f677d3880632b88/gitpython-3.1.45.tar.gz", hash = "sha256:85b0ee964ceddf211c41b9f27a49086010a190fd8132a24e21f362a4b36a791c", size = 215076, upload-time = "2025-07-24T03:45:54.871Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/01/61/d4b89fec821f72385526e1b9d9a3a0385dda4a72b206d28049e2c7cd39b8/gitpython-3.1.45-py3-none-any.whl", hash = "sha256:8908cb2e02fb3b93b7eb0f2827125cb699869470432cc885f019b8fd0fccff77", size = 208168, upload-time = "2025-07-24T03:45:52.517Z" }, +] + +[[package]] +name = "idna" +version = "3.11" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/6f/6d/0703ccc57f3a7233505399edb88de3cbd678da106337b9fcde432b65ed60/idna-3.11.tar.gz", hash = "sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902", size = 194582, upload-time = "2025-10-12T14:55:20.501Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl", hash = "sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea", size = 71008, upload-time = "2025-10-12T14:55:18.883Z" }, +] + +[[package]] +name = "jinja2" +version = "3.1.6" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markupsafe" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/df/bf/f7da0350254c0ed7c72f3e33cef02e048281fec7ecec5f032d4aac52226b/jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d", size = 245115, upload-time = "2025-03-05T20:05:02.478Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67", size = 134899, upload-time = "2025-03-05T20:05:00.369Z" }, +] + +[[package]] +name = "markdown" +version = "3.10" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/7d/ab/7dd27d9d863b3376fcf23a5a13cb5d024aed1db46f963f1b5735ae43b3be/markdown-3.10.tar.gz", hash = "sha256:37062d4f2aa4b2b6b32aefb80faa300f82cc790cb949a35b8caede34f2b68c0e", size = 364931, upload-time = "2025-11-03T19:51:15.007Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/70/81/54e3ce63502cd085a0c556652a4e1b919c45a446bd1e5300e10c44c8c521/markdown-3.10-py3-none-any.whl", hash = "sha256:b5b99d6951e2e4948d939255596523444c0e677c669700b1d17aa4a8a464cb7c", size = 107678, upload-time = "2025-11-03T19:51:13.887Z" }, +] + +[[package]] +name = "markupsafe" +version = "3.0.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/7e/99/7690b6d4034fffd95959cbe0c02de8deb3098cc577c67bb6a24fe5d7caa7/markupsafe-3.0.3.tar.gz", hash = "sha256:722695808f4b6457b320fdc131280796bdceb04ab50fe1795cd540799ebe1698", size = 80313, upload-time = "2025-09-27T18:37:40.426Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/08/db/fefacb2136439fc8dd20e797950e749aa1f4997ed584c62cfb8ef7c2be0e/markupsafe-3.0.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1cc7ea17a6824959616c525620e387f6dd30fec8cb44f649e31712db02123dad", size = 11631, upload-time = "2025-09-27T18:36:18.185Z" }, + { url = "https://files.pythonhosted.org/packages/e1/2e/5898933336b61975ce9dc04decbc0a7f2fee78c30353c5efba7f2d6ff27a/markupsafe-3.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4bd4cd07944443f5a265608cc6aab442e4f74dff8088b0dfc8238647b8f6ae9a", size = 12058, upload-time = "2025-09-27T18:36:19.444Z" }, + { url = "https://files.pythonhosted.org/packages/1d/09/adf2df3699d87d1d8184038df46a9c80d78c0148492323f4693df54e17bb/markupsafe-3.0.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b5420a1d9450023228968e7e6a9ce57f65d148ab56d2313fcd589eee96a7a50", size = 24287, upload-time = "2025-09-27T18:36:20.768Z" }, + { url = "https://files.pythonhosted.org/packages/30/ac/0273f6fcb5f42e314c6d8cd99effae6a5354604d461b8d392b5ec9530a54/markupsafe-3.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0bf2a864d67e76e5c9a34dc26ec616a66b9888e25e7b9460e1c76d3293bd9dbf", size = 22940, upload-time = "2025-09-27T18:36:22.249Z" }, + { url = "https://files.pythonhosted.org/packages/19/ae/31c1be199ef767124c042c6c3e904da327a2f7f0cd63a0337e1eca2967a8/markupsafe-3.0.3-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:bc51efed119bc9cfdf792cdeaa4d67e8f6fcccab66ed4bfdd6bde3e59bfcbb2f", size = 21887, upload-time = "2025-09-27T18:36:23.535Z" }, + { url = "https://files.pythonhosted.org/packages/b2/76/7edcab99d5349a4532a459e1fe64f0b0467a3365056ae550d3bcf3f79e1e/markupsafe-3.0.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:068f375c472b3e7acbe2d5318dea141359e6900156b5b2ba06a30b169086b91a", size = 23692, upload-time = "2025-09-27T18:36:24.823Z" }, + { url = "https://files.pythonhosted.org/packages/a4/28/6e74cdd26d7514849143d69f0bf2399f929c37dc2b31e6829fd2045b2765/markupsafe-3.0.3-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:7be7b61bb172e1ed687f1754f8e7484f1c8019780f6f6b0786e76bb01c2ae115", size = 21471, upload-time = "2025-09-27T18:36:25.95Z" }, + { url = "https://files.pythonhosted.org/packages/62/7e/a145f36a5c2945673e590850a6f8014318d5577ed7e5920a4b3448e0865d/markupsafe-3.0.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f9e130248f4462aaa8e2552d547f36ddadbeaa573879158d721bbd33dfe4743a", size = 22923, upload-time = "2025-09-27T18:36:27.109Z" }, + { url = "https://files.pythonhosted.org/packages/0f/62/d9c46a7f5c9adbeeeda52f5b8d802e1094e9717705a645efc71b0913a0a8/markupsafe-3.0.3-cp311-cp311-win32.whl", hash = "sha256:0db14f5dafddbb6d9208827849fad01f1a2609380add406671a26386cdf15a19", size = 14572, upload-time = "2025-09-27T18:36:28.045Z" }, + { url = "https://files.pythonhosted.org/packages/83/8a/4414c03d3f891739326e1783338e48fb49781cc915b2e0ee052aa490d586/markupsafe-3.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:de8a88e63464af587c950061a5e6a67d3632e36df62b986892331d4620a35c01", size = 15077, upload-time = "2025-09-27T18:36:29.025Z" }, + { url = "https://files.pythonhosted.org/packages/35/73/893072b42e6862f319b5207adc9ae06070f095b358655f077f69a35601f0/markupsafe-3.0.3-cp311-cp311-win_arm64.whl", hash = "sha256:3b562dd9e9ea93f13d53989d23a7e775fdfd1066c33494ff43f5418bc8c58a5c", size = 13876, upload-time = "2025-09-27T18:36:29.954Z" }, + { url = "https://files.pythonhosted.org/packages/5a/72/147da192e38635ada20e0a2e1a51cf8823d2119ce8883f7053879c2199b5/markupsafe-3.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d53197da72cc091b024dd97249dfc7794d6a56530370992a5e1a08983ad9230e", size = 11615, upload-time = "2025-09-27T18:36:30.854Z" }, + { url = "https://files.pythonhosted.org/packages/9a/81/7e4e08678a1f98521201c3079f77db69fb552acd56067661f8c2f534a718/markupsafe-3.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1872df69a4de6aead3491198eaf13810b565bdbeec3ae2dc8780f14458ec73ce", size = 12020, upload-time = "2025-09-27T18:36:31.971Z" }, + { url = "https://files.pythonhosted.org/packages/1e/2c/799f4742efc39633a1b54a92eec4082e4f815314869865d876824c257c1e/markupsafe-3.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3a7e8ae81ae39e62a41ec302f972ba6ae23a5c5396c8e60113e9066ef893da0d", size = 24332, upload-time = "2025-09-27T18:36:32.813Z" }, + { url = "https://files.pythonhosted.org/packages/3c/2e/8d0c2ab90a8c1d9a24f0399058ab8519a3279d1bd4289511d74e909f060e/markupsafe-3.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d6dd0be5b5b189d31db7cda48b91d7e0a9795f31430b7f271219ab30f1d3ac9d", size = 22947, upload-time = "2025-09-27T18:36:33.86Z" }, + { url = "https://files.pythonhosted.org/packages/2c/54/887f3092a85238093a0b2154bd629c89444f395618842e8b0c41783898ea/markupsafe-3.0.3-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:94c6f0bb423f739146aec64595853541634bde58b2135f27f61c1ffd1cd4d16a", size = 21962, upload-time = "2025-09-27T18:36:35.099Z" }, + { url = "https://files.pythonhosted.org/packages/c9/2f/336b8c7b6f4a4d95e91119dc8521402461b74a485558d8f238a68312f11c/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:be8813b57049a7dc738189df53d69395eba14fb99345e0a5994914a3864c8a4b", size = 23760, upload-time = "2025-09-27T18:36:36.001Z" }, + { url = "https://files.pythonhosted.org/packages/32/43/67935f2b7e4982ffb50a4d169b724d74b62a3964bc1a9a527f5ac4f1ee2b/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:83891d0e9fb81a825d9a6d61e3f07550ca70a076484292a70fde82c4b807286f", size = 21529, upload-time = "2025-09-27T18:36:36.906Z" }, + { url = "https://files.pythonhosted.org/packages/89/e0/4486f11e51bbba8b0c041098859e869e304d1c261e59244baa3d295d47b7/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:77f0643abe7495da77fb436f50f8dab76dbc6e5fd25d39589a0f1fe6548bfa2b", size = 23015, upload-time = "2025-09-27T18:36:37.868Z" }, + { url = "https://files.pythonhosted.org/packages/2f/e1/78ee7a023dac597a5825441ebd17170785a9dab23de95d2c7508ade94e0e/markupsafe-3.0.3-cp312-cp312-win32.whl", hash = "sha256:d88b440e37a16e651bda4c7c2b930eb586fd15ca7406cb39e211fcff3bf3017d", size = 14540, upload-time = "2025-09-27T18:36:38.761Z" }, + { url = "https://files.pythonhosted.org/packages/aa/5b/bec5aa9bbbb2c946ca2733ef9c4ca91c91b6a24580193e891b5f7dbe8e1e/markupsafe-3.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:26a5784ded40c9e318cfc2bdb30fe164bdb8665ded9cd64d500a34fb42067b1c", size = 15105, upload-time = "2025-09-27T18:36:39.701Z" }, + { url = "https://files.pythonhosted.org/packages/e5/f1/216fc1bbfd74011693a4fd837e7026152e89c4bcf3e77b6692fba9923123/markupsafe-3.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:35add3b638a5d900e807944a078b51922212fb3dedb01633a8defc4b01a3c85f", size = 13906, upload-time = "2025-09-27T18:36:40.689Z" }, + { url = "https://files.pythonhosted.org/packages/38/2f/907b9c7bbba283e68f20259574b13d005c121a0fa4c175f9bed27c4597ff/markupsafe-3.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e1cf1972137e83c5d4c136c43ced9ac51d0e124706ee1c8aa8532c1287fa8795", size = 11622, upload-time = "2025-09-27T18:36:41.777Z" }, + { url = "https://files.pythonhosted.org/packages/9c/d9/5f7756922cdd676869eca1c4e3c0cd0df60ed30199ffd775e319089cb3ed/markupsafe-3.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:116bb52f642a37c115f517494ea5feb03889e04df47eeff5b130b1808ce7c219", size = 12029, upload-time = "2025-09-27T18:36:43.257Z" }, + { url = "https://files.pythonhosted.org/packages/00/07/575a68c754943058c78f30db02ee03a64b3c638586fba6a6dd56830b30a3/markupsafe-3.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:133a43e73a802c5562be9bbcd03d090aa5a1fe899db609c29e8c8d815c5f6de6", size = 24374, upload-time = "2025-09-27T18:36:44.508Z" }, + { url = "https://files.pythonhosted.org/packages/a9/21/9b05698b46f218fc0e118e1f8168395c65c8a2c750ae2bab54fc4bd4e0e8/markupsafe-3.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ccfcd093f13f0f0b7fdd0f198b90053bf7b2f02a3927a30e63f3ccc9df56b676", size = 22980, upload-time = "2025-09-27T18:36:45.385Z" }, + { url = "https://files.pythonhosted.org/packages/7f/71/544260864f893f18b6827315b988c146b559391e6e7e8f7252839b1b846a/markupsafe-3.0.3-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:509fa21c6deb7a7a273d629cf5ec029bc209d1a51178615ddf718f5918992ab9", size = 21990, upload-time = "2025-09-27T18:36:46.916Z" }, + { url = "https://files.pythonhosted.org/packages/c2/28/b50fc2f74d1ad761af2f5dcce7492648b983d00a65b8c0e0cb457c82ebbe/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a4afe79fb3de0b7097d81da19090f4df4f8d3a2b3adaa8764138aac2e44f3af1", size = 23784, upload-time = "2025-09-27T18:36:47.884Z" }, + { url = "https://files.pythonhosted.org/packages/ed/76/104b2aa106a208da8b17a2fb72e033a5a9d7073c68f7e508b94916ed47a9/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:795e7751525cae078558e679d646ae45574b47ed6e7771863fcc079a6171a0fc", size = 21588, upload-time = "2025-09-27T18:36:48.82Z" }, + { url = "https://files.pythonhosted.org/packages/b5/99/16a5eb2d140087ebd97180d95249b00a03aa87e29cc224056274f2e45fd6/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8485f406a96febb5140bfeca44a73e3ce5116b2501ac54fe953e488fb1d03b12", size = 23041, upload-time = "2025-09-27T18:36:49.797Z" }, + { url = "https://files.pythonhosted.org/packages/19/bc/e7140ed90c5d61d77cea142eed9f9c303f4c4806f60a1044c13e3f1471d0/markupsafe-3.0.3-cp313-cp313-win32.whl", hash = "sha256:bdd37121970bfd8be76c5fb069c7751683bdf373db1ed6c010162b2a130248ed", size = 14543, upload-time = "2025-09-27T18:36:51.584Z" }, + { url = "https://files.pythonhosted.org/packages/05/73/c4abe620b841b6b791f2edc248f556900667a5a1cf023a6646967ae98335/markupsafe-3.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:9a1abfdc021a164803f4d485104931fb8f8c1efd55bc6b748d2f5774e78b62c5", size = 15113, upload-time = "2025-09-27T18:36:52.537Z" }, + { url = "https://files.pythonhosted.org/packages/f0/3a/fa34a0f7cfef23cf9500d68cb7c32dd64ffd58a12b09225fb03dd37d5b80/markupsafe-3.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:7e68f88e5b8799aa49c85cd116c932a1ac15caaa3f5db09087854d218359e485", size = 13911, upload-time = "2025-09-27T18:36:53.513Z" }, + { url = "https://files.pythonhosted.org/packages/e4/d7/e05cd7efe43a88a17a37b3ae96e79a19e846f3f456fe79c57ca61356ef01/markupsafe-3.0.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:218551f6df4868a8d527e3062d0fb968682fe92054e89978594c28e642c43a73", size = 11658, upload-time = "2025-09-27T18:36:54.819Z" }, + { url = "https://files.pythonhosted.org/packages/99/9e/e412117548182ce2148bdeacdda3bb494260c0b0184360fe0d56389b523b/markupsafe-3.0.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3524b778fe5cfb3452a09d31e7b5adefeea8c5be1d43c4f810ba09f2ceb29d37", size = 12066, upload-time = "2025-09-27T18:36:55.714Z" }, + { url = "https://files.pythonhosted.org/packages/bc/e6/fa0ffcda717ef64a5108eaa7b4f5ed28d56122c9a6d70ab8b72f9f715c80/markupsafe-3.0.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4e885a3d1efa2eadc93c894a21770e4bc67899e3543680313b09f139e149ab19", size = 25639, upload-time = "2025-09-27T18:36:56.908Z" }, + { url = "https://files.pythonhosted.org/packages/96/ec/2102e881fe9d25fc16cb4b25d5f5cde50970967ffa5dddafdb771237062d/markupsafe-3.0.3-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8709b08f4a89aa7586de0aadc8da56180242ee0ada3999749b183aa23df95025", size = 23569, upload-time = "2025-09-27T18:36:57.913Z" }, + { url = "https://files.pythonhosted.org/packages/4b/30/6f2fce1f1f205fc9323255b216ca8a235b15860c34b6798f810f05828e32/markupsafe-3.0.3-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b8512a91625c9b3da6f127803b166b629725e68af71f8184ae7e7d54686a56d6", size = 23284, upload-time = "2025-09-27T18:36:58.833Z" }, + { url = "https://files.pythonhosted.org/packages/58/47/4a0ccea4ab9f5dcb6f79c0236d954acb382202721e704223a8aafa38b5c8/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9b79b7a16f7fedff2495d684f2b59b0457c3b493778c9eed31111be64d58279f", size = 24801, upload-time = "2025-09-27T18:36:59.739Z" }, + { url = "https://files.pythonhosted.org/packages/6a/70/3780e9b72180b6fecb83a4814d84c3bf4b4ae4bf0b19c27196104149734c/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:12c63dfb4a98206f045aa9563db46507995f7ef6d83b2f68eda65c307c6829eb", size = 22769, upload-time = "2025-09-27T18:37:00.719Z" }, + { url = "https://files.pythonhosted.org/packages/98/c5/c03c7f4125180fc215220c035beac6b9cb684bc7a067c84fc69414d315f5/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8f71bc33915be5186016f675cd83a1e08523649b0e33efdb898db577ef5bb009", size = 23642, upload-time = "2025-09-27T18:37:01.673Z" }, + { url = "https://files.pythonhosted.org/packages/80/d6/2d1b89f6ca4bff1036499b1e29a1d02d282259f3681540e16563f27ebc23/markupsafe-3.0.3-cp313-cp313t-win32.whl", hash = "sha256:69c0b73548bc525c8cb9a251cddf1931d1db4d2258e9599c28c07ef3580ef354", size = 14612, upload-time = "2025-09-27T18:37:02.639Z" }, + { url = "https://files.pythonhosted.org/packages/2b/98/e48a4bfba0a0ffcf9925fe2d69240bfaa19c6f7507b8cd09c70684a53c1e/markupsafe-3.0.3-cp313-cp313t-win_amd64.whl", hash = "sha256:1b4b79e8ebf6b55351f0d91fe80f893b4743f104bff22e90697db1590e47a218", size = 15200, upload-time = "2025-09-27T18:37:03.582Z" }, + { url = "https://files.pythonhosted.org/packages/0e/72/e3cc540f351f316e9ed0f092757459afbc595824ca724cbc5a5d4263713f/markupsafe-3.0.3-cp313-cp313t-win_arm64.whl", hash = "sha256:ad2cf8aa28b8c020ab2fc8287b0f823d0a7d8630784c31e9ee5edea20f406287", size = 13973, upload-time = "2025-09-27T18:37:04.929Z" }, + { url = "https://files.pythonhosted.org/packages/33/8a/8e42d4838cd89b7dde187011e97fe6c3af66d8c044997d2183fbd6d31352/markupsafe-3.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:eaa9599de571d72e2daf60164784109f19978b327a3910d3e9de8c97b5b70cfe", size = 11619, upload-time = "2025-09-27T18:37:06.342Z" }, + { url = "https://files.pythonhosted.org/packages/b5/64/7660f8a4a8e53c924d0fa05dc3a55c9cee10bbd82b11c5afb27d44b096ce/markupsafe-3.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c47a551199eb8eb2121d4f0f15ae0f923d31350ab9280078d1e5f12b249e0026", size = 12029, upload-time = "2025-09-27T18:37:07.213Z" }, + { url = "https://files.pythonhosted.org/packages/da/ef/e648bfd021127bef5fa12e1720ffed0c6cbb8310c8d9bea7266337ff06de/markupsafe-3.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f34c41761022dd093b4b6896d4810782ffbabe30f2d443ff5f083e0cbbb8c737", size = 24408, upload-time = "2025-09-27T18:37:09.572Z" }, + { url = "https://files.pythonhosted.org/packages/41/3c/a36c2450754618e62008bf7435ccb0f88053e07592e6028a34776213d877/markupsafe-3.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:457a69a9577064c05a97c41f4e65148652db078a3a509039e64d3467b9e7ef97", size = 23005, upload-time = "2025-09-27T18:37:10.58Z" }, + { url = "https://files.pythonhosted.org/packages/bc/20/b7fdf89a8456b099837cd1dc21974632a02a999ec9bf7ca3e490aacd98e7/markupsafe-3.0.3-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e8afc3f2ccfa24215f8cb28dcf43f0113ac3c37c2f0f0806d8c70e4228c5cf4d", size = 22048, upload-time = "2025-09-27T18:37:11.547Z" }, + { url = "https://files.pythonhosted.org/packages/9a/a7/591f592afdc734f47db08a75793a55d7fbcc6902a723ae4cfbab61010cc5/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ec15a59cf5af7be74194f7ab02d0f59a62bdcf1a537677ce67a2537c9b87fcda", size = 23821, upload-time = "2025-09-27T18:37:12.48Z" }, + { url = "https://files.pythonhosted.org/packages/7d/33/45b24e4f44195b26521bc6f1a82197118f74df348556594bd2262bda1038/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:0eb9ff8191e8498cca014656ae6b8d61f39da5f95b488805da4bb029cccbfbaf", size = 21606, upload-time = "2025-09-27T18:37:13.485Z" }, + { url = "https://files.pythonhosted.org/packages/ff/0e/53dfaca23a69fbfbbf17a4b64072090e70717344c52eaaaa9c5ddff1e5f0/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2713baf880df847f2bece4230d4d094280f4e67b1e813eec43b4c0e144a34ffe", size = 23043, upload-time = "2025-09-27T18:37:14.408Z" }, + { url = "https://files.pythonhosted.org/packages/46/11/f333a06fc16236d5238bfe74daccbca41459dcd8d1fa952e8fbd5dccfb70/markupsafe-3.0.3-cp314-cp314-win32.whl", hash = "sha256:729586769a26dbceff69f7a7dbbf59ab6572b99d94576a5592625d5b411576b9", size = 14747, upload-time = "2025-09-27T18:37:15.36Z" }, + { url = "https://files.pythonhosted.org/packages/28/52/182836104b33b444e400b14f797212f720cbc9ed6ba34c800639d154e821/markupsafe-3.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:bdc919ead48f234740ad807933cdf545180bfbe9342c2bb451556db2ed958581", size = 15341, upload-time = "2025-09-27T18:37:16.496Z" }, + { url = "https://files.pythonhosted.org/packages/6f/18/acf23e91bd94fd7b3031558b1f013adfa21a8e407a3fdb32745538730382/markupsafe-3.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:5a7d5dc5140555cf21a6fefbdbf8723f06fcd2f63ef108f2854de715e4422cb4", size = 14073, upload-time = "2025-09-27T18:37:17.476Z" }, + { url = "https://files.pythonhosted.org/packages/3c/f0/57689aa4076e1b43b15fdfa646b04653969d50cf30c32a102762be2485da/markupsafe-3.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:1353ef0c1b138e1907ae78e2f6c63ff67501122006b0f9abad68fda5f4ffc6ab", size = 11661, upload-time = "2025-09-27T18:37:18.453Z" }, + { url = "https://files.pythonhosted.org/packages/89/c3/2e67a7ca217c6912985ec766c6393b636fb0c2344443ff9d91404dc4c79f/markupsafe-3.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:1085e7fbddd3be5f89cc898938f42c0b3c711fdcb37d75221de2666af647c175", size = 12069, upload-time = "2025-09-27T18:37:19.332Z" }, + { url = "https://files.pythonhosted.org/packages/f0/00/be561dce4e6ca66b15276e184ce4b8aec61fe83662cce2f7d72bd3249d28/markupsafe-3.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1b52b4fb9df4eb9ae465f8d0c228a00624de2334f216f178a995ccdcf82c4634", size = 25670, upload-time = "2025-09-27T18:37:20.245Z" }, + { url = "https://files.pythonhosted.org/packages/50/09/c419f6f5a92e5fadde27efd190eca90f05e1261b10dbd8cbcb39cd8ea1dc/markupsafe-3.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fed51ac40f757d41b7c48425901843666a6677e3e8eb0abcff09e4ba6e664f50", size = 23598, upload-time = "2025-09-27T18:37:21.177Z" }, + { url = "https://files.pythonhosted.org/packages/22/44/a0681611106e0b2921b3033fc19bc53323e0b50bc70cffdd19f7d679bb66/markupsafe-3.0.3-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f190daf01f13c72eac4efd5c430a8de82489d9cff23c364c3ea822545032993e", size = 23261, upload-time = "2025-09-27T18:37:22.167Z" }, + { url = "https://files.pythonhosted.org/packages/5f/57/1b0b3f100259dc9fffe780cfb60d4be71375510e435efec3d116b6436d43/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e56b7d45a839a697b5eb268c82a71bd8c7f6c94d6fd50c3d577fa39a9f1409f5", size = 24835, upload-time = "2025-09-27T18:37:23.296Z" }, + { url = "https://files.pythonhosted.org/packages/26/6a/4bf6d0c97c4920f1597cc14dd720705eca0bf7c787aebc6bb4d1bead5388/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:f3e98bb3798ead92273dc0e5fd0f31ade220f59a266ffd8a4f6065e0a3ce0523", size = 22733, upload-time = "2025-09-27T18:37:24.237Z" }, + { url = "https://files.pythonhosted.org/packages/14/c7/ca723101509b518797fedc2fdf79ba57f886b4aca8a7d31857ba3ee8281f/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:5678211cb9333a6468fb8d8be0305520aa073f50d17f089b5b4b477ea6e67fdc", size = 23672, upload-time = "2025-09-27T18:37:25.271Z" }, + { url = "https://files.pythonhosted.org/packages/fb/df/5bd7a48c256faecd1d36edc13133e51397e41b73bb77e1a69deab746ebac/markupsafe-3.0.3-cp314-cp314t-win32.whl", hash = "sha256:915c04ba3851909ce68ccc2b8e2cd691618c4dc4c4232fb7982bca3f41fd8c3d", size = 14819, upload-time = "2025-09-27T18:37:26.285Z" }, + { url = "https://files.pythonhosted.org/packages/1a/8a/0402ba61a2f16038b48b39bccca271134be00c5c9f0f623208399333c448/markupsafe-3.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4faffd047e07c38848ce017e8725090413cd80cbc23d86e55c587bf979e579c9", size = 15426, upload-time = "2025-09-27T18:37:27.316Z" }, + { url = "https://files.pythonhosted.org/packages/70/bc/6f1c2f612465f5fa89b95bead1f44dcb607670fd42891d8fdcd5d039f4f4/markupsafe-3.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:32001d6a8fc98c8cb5c947787c5d08b0a50663d139f1305bac5885d98d9b40fa", size = 14146, upload-time = "2025-09-27T18:37:28.327Z" }, +] + +[[package]] +name = "mergedeep" +version = "1.3.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/3a/41/580bb4006e3ed0361b8151a01d324fb03f420815446c7def45d02f74c270/mergedeep-1.3.4.tar.gz", hash = "sha256:0096d52e9dad9939c3d975a774666af186eda617e6ca84df4c94dec30004f2a8", size = 4661, upload-time = "2021-02-05T18:55:30.623Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2c/19/04f9b178c2d8a15b076c8b5140708fa6ffc5601fb6f1e975537072df5b2a/mergedeep-1.3.4-py3-none-any.whl", hash = "sha256:70775750742b25c0d8f36c55aed03d24c3384d17c951b3175d898bd778ef0307", size = 6354, upload-time = "2021-02-05T18:55:29.583Z" }, +] + +[[package]] +name = "mkdocs" +version = "1.6.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "click" }, + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "ghp-import" }, + { name = "jinja2" }, + { name = "markdown" }, + { name = "markupsafe" }, + { name = "mergedeep" }, + { name = "mkdocs-get-deps" }, + { name = "packaging" }, + { name = "pathspec" }, + { name = "pyyaml" }, + { name = "pyyaml-env-tag" }, + { name = "watchdog" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/bc/c6/bbd4f061bd16b378247f12953ffcb04786a618ce5e904b8c5a01a0309061/mkdocs-1.6.1.tar.gz", hash = "sha256:7b432f01d928c084353ab39c57282f29f92136665bdd6abf7c1ec8d822ef86f2", size = 3889159, upload-time = "2024-08-30T12:24:06.899Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/22/5b/dbc6a8cddc9cfa9c4971d59fb12bb8d42e161b7e7f8cc89e49137c5b279c/mkdocs-1.6.1-py3-none-any.whl", hash = "sha256:db91759624d1647f3f34aa0c3f327dd2601beae39a366d6e064c03468d35c20e", size = 3864451, upload-time = "2024-08-30T12:24:05.054Z" }, +] + +[[package]] +name = "mkdocs-get-deps" +version = "0.2.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mergedeep" }, + { name = "platformdirs" }, + { name = "pyyaml" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/98/f5/ed29cd50067784976f25ed0ed6fcd3c2ce9eb90650aa3b2796ddf7b6870b/mkdocs_get_deps-0.2.0.tar.gz", hash = "sha256:162b3d129c7fad9b19abfdcb9c1458a651628e4b1dea628ac68790fb3061c60c", size = 10239, upload-time = "2023-11-20T17:51:09.981Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9f/d4/029f984e8d3f3b6b726bd33cafc473b75e9e44c0f7e80a5b29abc466bdea/mkdocs_get_deps-0.2.0-py3-none-any.whl", hash = "sha256:2bf11d0b133e77a0dd036abeeb06dec8775e46efa526dc70667d8863eefc6134", size = 9521, upload-time = "2023-11-20T17:51:08.587Z" }, +] + +[[package]] +name = "mkdocs-git-revision-date-localized-plugin" +version = "1.5.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "babel" }, + { name = "gitpython" }, + { name = "mkdocs" }, + { name = "tzdata", marker = "sys_platform == 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/0f/c5/1d3c4e6ddae6230b89d09105cb79de711655e3ebd6745f7a92efea0f5160/mkdocs_git_revision_date_localized_plugin-1.5.0.tar.gz", hash = "sha256:17345ccfdf69a1905dc96fb1070dce82d03a1eb6b0d48f958081a7589ce3c248", size = 460697, upload-time = "2025-10-31T16:11:34.44Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bc/51/fe0e3fdb16f6eed65c9459d12bae6a4e1f0bb4e2228cb037e7907b002678/mkdocs_git_revision_date_localized_plugin-1.5.0-py3-none-any.whl", hash = "sha256:933f9e35a8c135b113f21bb57610d82e9b7bcc71dd34fb06a029053c97e99656", size = 26153, upload-time = "2025-10-31T16:11:32.987Z" }, +] + +[[package]] +name = "mkdocs-glightbox" +version = "0.5.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "selectolax" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/8d/26/c793459622da8e31f954c6f5fb51e8f098143fdfc147b1e3c25bf686f4aa/mkdocs_glightbox-0.5.2.tar.gz", hash = "sha256:c7622799347c32310878e01ccf14f70648445561010911c80590cec0353370ac", size = 510586, upload-time = "2025-10-23T14:55:18.909Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4e/ca/03624e017e5ee2d7ce8a08d89f81c1e535eb3c30d7b2dc4a435ea3fbbeae/mkdocs_glightbox-0.5.2-py3-none-any.whl", hash = "sha256:23a431ea802b60b1030c73323db2eed6ba859df1a0822ce575afa43e0ea3f47e", size = 26458, upload-time = "2025-10-23T14:55:17.43Z" }, +] + +[[package]] +name = "mkdocs-material" +version = "9.7.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "babel" }, + { name = "backrefs" }, + { name = "colorama" }, + { name = "jinja2" }, + { name = "markdown" }, + { name = "mkdocs" }, + { name = "mkdocs-material-extensions" }, + { name = "paginate" }, + { name = "pygments" }, + { name = "pymdown-extensions" }, + { name = "requests" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/9c/3b/111b84cd6ff28d9e955b5f799ef217a17bc1684ac346af333e6100e413cb/mkdocs_material-9.7.0.tar.gz", hash = "sha256:602b359844e906ee402b7ed9640340cf8a474420d02d8891451733b6b02314ec", size = 4094546, upload-time = "2025-11-11T08:49:09.73Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/04/87/eefe8d5e764f4cf50ed91b943f8e8f96b5efd65489d8303b7a36e2e79834/mkdocs_material-9.7.0-py3-none-any.whl", hash = "sha256:da2866ea53601125ff5baa8aa06404c6e07af3c5ce3d5de95e3b52b80b442887", size = 9283770, upload-time = "2025-11-11T08:49:06.26Z" }, +] + +[[package]] +name = "mkdocs-material-extensions" +version = "1.3.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/79/9b/9b4c96d6593b2a541e1cb8b34899a6d021d208bb357042823d4d2cabdbe7/mkdocs_material_extensions-1.3.1.tar.gz", hash = "sha256:10c9511cea88f568257f960358a467d12b970e1f7b2c0e5fb2bb48cab1928443", size = 11847, upload-time = "2023-11-22T19:09:45.208Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5b/54/662a4743aa81d9582ee9339d4ffa3c8fd40a4965e033d77b9da9774d3960/mkdocs_material_extensions-1.3.1-py3-none-any.whl", hash = "sha256:adff8b62700b25cb77b53358dad940f3ef973dd6db797907c49e3c2ef3ab4e31", size = 8728, upload-time = "2023-11-22T19:09:43.465Z" }, +] + +[[package]] +name = "mkdocs-multirepo-plugin" +version = "0.8.3" +source = { git = "https://github.com/atuinsh/mkdocs-multirepo-plugin?rev=mkt%2Fimported_repo#e2aed29184af719cce2bc0dddb90ceec99af21b9" } +dependencies = [ + { name = "dacite" }, + { name = "mkdocs" }, + { name = "python-slugify" }, + { name = "typing-inspect" }, +] + +[[package]] +name = "mkdocs-redirects" +version = "1.2.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mkdocs" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f1/a8/6d44a6cf07e969c7420cb36ab287b0669da636a2044de38a7d2208d5a758/mkdocs_redirects-1.2.2.tar.gz", hash = "sha256:3094981b42ffab29313c2c1b8ac3969861109f58b2dd58c45fc81cd44bfa0095", size = 7162, upload-time = "2024-11-07T14:57:21.109Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c4/ec/38443b1f2a3821bbcb24e46cd8ba979154417794d54baf949fefde1c2146/mkdocs_redirects-1.2.2-py3-none-any.whl", hash = "sha256:7dbfa5647b79a3589da4401403d69494bd1f4ad03b9c15136720367e1f340ed5", size = 6142, upload-time = "2024-11-07T14:57:19.143Z" }, +] + +[[package]] +name = "mypy-extensions" +version = "1.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a2/6e/371856a3fb9d31ca8dac321cda606860fa4548858c0cc45d9d1d4ca2628b/mypy_extensions-1.1.0.tar.gz", hash = "sha256:52e68efc3284861e772bbcd66823fde5ae21fd2fdb51c62a211403730b916558", size = 6343, upload-time = "2025-04-22T14:54:24.164Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/79/7b/2c79738432f5c924bef5071f933bcc9efd0473bac3b4aa584a6f7c1c8df8/mypy_extensions-1.1.0-py3-none-any.whl", hash = "sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505", size = 4963, upload-time = "2025-04-22T14:54:22.983Z" }, +] + +[[package]] +name = "packaging" +version = "25.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a1/d4/1fc4078c65507b51b96ca8f8c3ba19e6a61c8253c72794544580a7b6c24d/packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f", size = 165727, upload-time = "2025-04-19T11:48:59.673Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", size = 66469, upload-time = "2025-04-19T11:48:57.875Z" }, +] + +[[package]] +name = "paginate" +version = "0.5.7" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ec/46/68dde5b6bc00c1296ec6466ab27dddede6aec9af1b99090e1107091b3b84/paginate-0.5.7.tar.gz", hash = "sha256:22bd083ab41e1a8b4f3690544afb2c60c25e5c9a63a30fa2f483f6c60c8e5945", size = 19252, upload-time = "2024-08-25T14:17:24.139Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/90/96/04b8e52da071d28f5e21a805b19cb9390aa17a47462ac87f5e2696b9566d/paginate-0.5.7-py2.py3-none-any.whl", hash = "sha256:b885e2af73abcf01d9559fd5216b57ef722f8c42affbb63942377668e35c7591", size = 13746, upload-time = "2024-08-25T14:17:22.55Z" }, +] + +[[package]] +name = "pathspec" +version = "0.12.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ca/bc/f35b8446f4531a7cb215605d100cd88b7ac6f44ab3fc94870c120ab3adbf/pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712", size = 51043, upload-time = "2023-12-10T22:30:45Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cc/20/ff623b09d963f88bfde16306a54e12ee5ea43e9b597108672ff3a408aad6/pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08", size = 31191, upload-time = "2023-12-10T22:30:43.14Z" }, +] + +[[package]] +name = "platformdirs" +version = "4.5.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/cf/86/0248f086a84f01b37aaec0fa567b397df1a119f73c16f6c7a9aac73ea309/platformdirs-4.5.1.tar.gz", hash = "sha256:61d5cdcc6065745cdd94f0f878977f8de9437be93de97c1c12f853c9c0cdcbda", size = 21715, upload-time = "2025-12-05T13:52:58.638Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cb/28/3bfe2fa5a7b9c46fe7e13c97bda14c895fb10fa2ebf1d0abb90e0cea7ee1/platformdirs-4.5.1-py3-none-any.whl", hash = "sha256:d03afa3963c806a9bed9d5125c8f4cb2fdaf74a55ab60e5d59b3fde758104d31", size = 18731, upload-time = "2025-12-05T13:52:56.823Z" }, +] + +[[package]] +name = "pygments" +version = "2.19.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b0/77/a5b8c569bf593b0140bde72ea885a803b82086995367bf2037de0159d924/pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887", size = 4968631, upload-time = "2025-06-21T13:39:12.283Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b", size = 1225217, upload-time = "2025-06-21T13:39:07.939Z" }, +] + +[[package]] +name = "pymdown-extensions" +version = "10.19" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markdown" }, + { name = "pyyaml" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/1f/4e/e73e88f4f2d0b26cbd2e100074107470984f0a6055869805fc181b847ac7/pymdown_extensions-10.19.tar.gz", hash = "sha256:01bb917ea231f9ce14456fa9092cdb95ac3e5bd32202a3ee61dbd5ad2dd9ef9b", size = 847701, upload-time = "2025-12-11T18:20:46.093Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d4/56/fa9edaceb3805e03ac9faf68ca1ddc660a75b49aee5accb493511005fef5/pymdown_extensions-10.19-py3-none-any.whl", hash = "sha256:dc5f249fc3a1b6d8a6de4634ba8336b88d0942cee75e92b18ac79eaf3503bf7c", size = 266670, upload-time = "2025-12-11T18:20:44.736Z" }, +] + +[[package]] +name = "python-dateutil" +version = "2.9.0.post0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "six" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432, upload-time = "2024-03-01T18:36:20.211Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892, upload-time = "2024-03-01T18:36:18.57Z" }, +] + +[[package]] +name = "python-slugify" +version = "8.0.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "text-unidecode" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/87/c7/5e1547c44e31da50a460df93af11a535ace568ef89d7a811069ead340c4a/python-slugify-8.0.4.tar.gz", hash = "sha256:59202371d1d05b54a9e7720c5e038f928f45daaffe41dd10822f3907b937c856", size = 10921, upload-time = "2024-02-08T18:32:45.488Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a4/62/02da182e544a51a5c3ccf4b03ab79df279f9c60c5e82d5e8bec7ca26ac11/python_slugify-8.0.4-py2.py3-none-any.whl", hash = "sha256:276540b79961052b66b7d116620b36518847f52d5fd9e3a70164fc8c50faa6b8", size = 10051, upload-time = "2024-02-08T18:32:43.911Z" }, +] + +[[package]] +name = "pyyaml" +version = "6.0.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/05/8e/961c0007c59b8dd7729d542c61a4d537767a59645b82a0b521206e1e25c2/pyyaml-6.0.3.tar.gz", hash = "sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f", size = 130960, upload-time = "2025-09-25T21:33:16.546Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6d/16/a95b6757765b7b031c9374925bb718d55e0a9ba8a1b6a12d25962ea44347/pyyaml-6.0.3-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:44edc647873928551a01e7a563d7452ccdebee747728c1080d881d68af7b997e", size = 185826, upload-time = "2025-09-25T21:31:58.655Z" }, + { url = "https://files.pythonhosted.org/packages/16/19/13de8e4377ed53079ee996e1ab0a9c33ec2faf808a4647b7b4c0d46dd239/pyyaml-6.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:652cb6edd41e718550aad172851962662ff2681490a8a711af6a4d288dd96824", size = 175577, upload-time = "2025-09-25T21:32:00.088Z" }, + { url = "https://files.pythonhosted.org/packages/0c/62/d2eb46264d4b157dae1275b573017abec435397aa59cbcdab6fc978a8af4/pyyaml-6.0.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:10892704fc220243f5305762e276552a0395f7beb4dbf9b14ec8fd43b57f126c", size = 775556, upload-time = "2025-09-25T21:32:01.31Z" }, + { url = "https://files.pythonhosted.org/packages/10/cb/16c3f2cf3266edd25aaa00d6c4350381c8b012ed6f5276675b9eba8d9ff4/pyyaml-6.0.3-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:850774a7879607d3a6f50d36d04f00ee69e7fc816450e5f7e58d7f17f1ae5c00", size = 882114, upload-time = "2025-09-25T21:32:03.376Z" }, + { url = "https://files.pythonhosted.org/packages/71/60/917329f640924b18ff085ab889a11c763e0b573da888e8404ff486657602/pyyaml-6.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b8bb0864c5a28024fac8a632c443c87c5aa6f215c0b126c449ae1a150412f31d", size = 806638, upload-time = "2025-09-25T21:32:04.553Z" }, + { url = "https://files.pythonhosted.org/packages/dd/6f/529b0f316a9fd167281a6c3826b5583e6192dba792dd55e3203d3f8e655a/pyyaml-6.0.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1d37d57ad971609cf3c53ba6a7e365e40660e3be0e5175fa9f2365a379d6095a", size = 767463, upload-time = "2025-09-25T21:32:06.152Z" }, + { url = "https://files.pythonhosted.org/packages/f2/6a/b627b4e0c1dd03718543519ffb2f1deea4a1e6d42fbab8021936a4d22589/pyyaml-6.0.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:37503bfbfc9d2c40b344d06b2199cf0e96e97957ab1c1b546fd4f87e53e5d3e4", size = 794986, upload-time = "2025-09-25T21:32:07.367Z" }, + { url = "https://files.pythonhosted.org/packages/45/91/47a6e1c42d9ee337c4839208f30d9f09caa9f720ec7582917b264defc875/pyyaml-6.0.3-cp311-cp311-win32.whl", hash = "sha256:8098f252adfa6c80ab48096053f512f2321f0b998f98150cea9bd23d83e1467b", size = 142543, upload-time = "2025-09-25T21:32:08.95Z" }, + { url = "https://files.pythonhosted.org/packages/da/e3/ea007450a105ae919a72393cb06f122f288ef60bba2dc64b26e2646fa315/pyyaml-6.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:9f3bfb4965eb874431221a3ff3fdcddc7e74e3b07799e0e84ca4a0f867d449bf", size = 158763, upload-time = "2025-09-25T21:32:09.96Z" }, + { url = "https://files.pythonhosted.org/packages/d1/33/422b98d2195232ca1826284a76852ad5a86fe23e31b009c9886b2d0fb8b2/pyyaml-6.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7f047e29dcae44602496db43be01ad42fc6f1cc0d8cd6c83d342306c32270196", size = 182063, upload-time = "2025-09-25T21:32:11.445Z" }, + { url = "https://files.pythonhosted.org/packages/89/a0/6cf41a19a1f2f3feab0e9c0b74134aa2ce6849093d5517a0c550fe37a648/pyyaml-6.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fc09d0aa354569bc501d4e787133afc08552722d3ab34836a80547331bb5d4a0", size = 173973, upload-time = "2025-09-25T21:32:12.492Z" }, + { url = "https://files.pythonhosted.org/packages/ed/23/7a778b6bd0b9a8039df8b1b1d80e2e2ad78aa04171592c8a5c43a56a6af4/pyyaml-6.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9149cad251584d5fb4981be1ecde53a1ca46c891a79788c0df828d2f166bda28", size = 775116, upload-time = "2025-09-25T21:32:13.652Z" }, + { url = "https://files.pythonhosted.org/packages/65/30/d7353c338e12baef4ecc1b09e877c1970bd3382789c159b4f89d6a70dc09/pyyaml-6.0.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5fdec68f91a0c6739b380c83b951e2c72ac0197ace422360e6d5a959d8d97b2c", size = 844011, upload-time = "2025-09-25T21:32:15.21Z" }, + { url = "https://files.pythonhosted.org/packages/8b/9d/b3589d3877982d4f2329302ef98a8026e7f4443c765c46cfecc8858c6b4b/pyyaml-6.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ba1cc08a7ccde2d2ec775841541641e4548226580ab850948cbfda66a1befcdc", size = 807870, upload-time = "2025-09-25T21:32:16.431Z" }, + { url = "https://files.pythonhosted.org/packages/05/c0/b3be26a015601b822b97d9149ff8cb5ead58c66f981e04fedf4e762f4bd4/pyyaml-6.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8dc52c23056b9ddd46818a57b78404882310fb473d63f17b07d5c40421e47f8e", size = 761089, upload-time = "2025-09-25T21:32:17.56Z" }, + { url = "https://files.pythonhosted.org/packages/be/8e/98435a21d1d4b46590d5459a22d88128103f8da4c2d4cb8f14f2a96504e1/pyyaml-6.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:41715c910c881bc081f1e8872880d3c650acf13dfa8214bad49ed4cede7c34ea", size = 790181, upload-time = "2025-09-25T21:32:18.834Z" }, + { url = "https://files.pythonhosted.org/packages/74/93/7baea19427dcfbe1e5a372d81473250b379f04b1bd3c4c5ff825e2327202/pyyaml-6.0.3-cp312-cp312-win32.whl", hash = "sha256:96b533f0e99f6579b3d4d4995707cf36df9100d67e0c8303a0c55b27b5f99bc5", size = 137658, upload-time = "2025-09-25T21:32:20.209Z" }, + { url = "https://files.pythonhosted.org/packages/86/bf/899e81e4cce32febab4fb42bb97dcdf66bc135272882d1987881a4b519e9/pyyaml-6.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:5fcd34e47f6e0b794d17de1b4ff496c00986e1c83f7ab2fb8fcfe9616ff7477b", size = 154003, upload-time = "2025-09-25T21:32:21.167Z" }, + { url = "https://files.pythonhosted.org/packages/1a/08/67bd04656199bbb51dbed1439b7f27601dfb576fb864099c7ef0c3e55531/pyyaml-6.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:64386e5e707d03a7e172c0701abfb7e10f0fb753ee1d773128192742712a98fd", size = 140344, upload-time = "2025-09-25T21:32:22.617Z" }, + { url = "https://files.pythonhosted.org/packages/d1/11/0fd08f8192109f7169db964b5707a2f1e8b745d4e239b784a5a1dd80d1db/pyyaml-6.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8", size = 181669, upload-time = "2025-09-25T21:32:23.673Z" }, + { url = "https://files.pythonhosted.org/packages/b1/16/95309993f1d3748cd644e02e38b75d50cbc0d9561d21f390a76242ce073f/pyyaml-6.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1", size = 173252, upload-time = "2025-09-25T21:32:25.149Z" }, + { url = "https://files.pythonhosted.org/packages/50/31/b20f376d3f810b9b2371e72ef5adb33879b25edb7a6d072cb7ca0c486398/pyyaml-6.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c", size = 767081, upload-time = "2025-09-25T21:32:26.575Z" }, + { url = "https://files.pythonhosted.org/packages/49/1e/a55ca81e949270d5d4432fbbd19dfea5321eda7c41a849d443dc92fd1ff7/pyyaml-6.0.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a33284e20b78bd4a18c8c2282d549d10bc8408a2a7ff57653c0cf0b9be0afce5", size = 841159, upload-time = "2025-09-25T21:32:27.727Z" }, + { url = "https://files.pythonhosted.org/packages/74/27/e5b8f34d02d9995b80abcef563ea1f8b56d20134d8f4e5e81733b1feceb2/pyyaml-6.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6", size = 801626, upload-time = "2025-09-25T21:32:28.878Z" }, + { url = "https://files.pythonhosted.org/packages/f9/11/ba845c23988798f40e52ba45f34849aa8a1f2d4af4b798588010792ebad6/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f7057c9a337546edc7973c0d3ba84ddcdf0daa14533c2065749c9075001090e6", size = 753613, upload-time = "2025-09-25T21:32:30.178Z" }, + { url = "https://files.pythonhosted.org/packages/3d/e0/7966e1a7bfc0a45bf0a7fb6b98ea03fc9b8d84fa7f2229e9659680b69ee3/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:eda16858a3cab07b80edaf74336ece1f986ba330fdb8ee0d6c0d68fe82bc96be", size = 794115, upload-time = "2025-09-25T21:32:31.353Z" }, + { url = "https://files.pythonhosted.org/packages/de/94/980b50a6531b3019e45ddeada0626d45fa85cbe22300844a7983285bed3b/pyyaml-6.0.3-cp313-cp313-win32.whl", hash = "sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26", size = 137427, upload-time = "2025-09-25T21:32:32.58Z" }, + { url = "https://files.pythonhosted.org/packages/97/c9/39d5b874e8b28845e4ec2202b5da735d0199dbe5b8fb85f91398814a9a46/pyyaml-6.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c", size = 154090, upload-time = "2025-09-25T21:32:33.659Z" }, + { url = "https://files.pythonhosted.org/packages/73/e8/2bdf3ca2090f68bb3d75b44da7bbc71843b19c9f2b9cb9b0f4ab7a5a4329/pyyaml-6.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb", size = 140246, upload-time = "2025-09-25T21:32:34.663Z" }, + { url = "https://files.pythonhosted.org/packages/9d/8c/f4bd7f6465179953d3ac9bc44ac1a8a3e6122cf8ada906b4f96c60172d43/pyyaml-6.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:8d1fab6bb153a416f9aeb4b8763bc0f22a5586065f86f7664fc23339fc1c1fac", size = 181814, upload-time = "2025-09-25T21:32:35.712Z" }, + { url = "https://files.pythonhosted.org/packages/bd/9c/4d95bb87eb2063d20db7b60faa3840c1b18025517ae857371c4dd55a6b3a/pyyaml-6.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:34d5fcd24b8445fadc33f9cf348c1047101756fd760b4dacb5c3e99755703310", size = 173809, upload-time = "2025-09-25T21:32:36.789Z" }, + { url = "https://files.pythonhosted.org/packages/92/b5/47e807c2623074914e29dabd16cbbdd4bf5e9b2db9f8090fa64411fc5382/pyyaml-6.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:501a031947e3a9025ed4405a168e6ef5ae3126c59f90ce0cd6f2bfc477be31b7", size = 766454, upload-time = "2025-09-25T21:32:37.966Z" }, + { url = "https://files.pythonhosted.org/packages/02/9e/e5e9b168be58564121efb3de6859c452fccde0ab093d8438905899a3a483/pyyaml-6.0.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b3bc83488de33889877a0f2543ade9f70c67d66d9ebb4ac959502e12de895788", size = 836355, upload-time = "2025-09-25T21:32:39.178Z" }, + { url = "https://files.pythonhosted.org/packages/88/f9/16491d7ed2a919954993e48aa941b200f38040928474c9e85ea9e64222c3/pyyaml-6.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c458b6d084f9b935061bc36216e8a69a7e293a2f1e68bf956dcd9e6cbcd143f5", size = 794175, upload-time = "2025-09-25T21:32:40.865Z" }, + { url = "https://files.pythonhosted.org/packages/dd/3f/5989debef34dc6397317802b527dbbafb2b4760878a53d4166579111411e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7c6610def4f163542a622a73fb39f534f8c101d690126992300bf3207eab9764", size = 755228, upload-time = "2025-09-25T21:32:42.084Z" }, + { url = "https://files.pythonhosted.org/packages/d7/ce/af88a49043cd2e265be63d083fc75b27b6ed062f5f9fd6cdc223ad62f03e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5190d403f121660ce8d1d2c1bb2ef1bd05b5f68533fc5c2ea899bd15f4399b35", size = 789194, upload-time = "2025-09-25T21:32:43.362Z" }, + { url = "https://files.pythonhosted.org/packages/23/20/bb6982b26a40bb43951265ba29d4c246ef0ff59c9fdcdf0ed04e0687de4d/pyyaml-6.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:4a2e8cebe2ff6ab7d1050ecd59c25d4c8bd7e6f400f5f82b96557ac0abafd0ac", size = 156429, upload-time = "2025-09-25T21:32:57.844Z" }, + { url = "https://files.pythonhosted.org/packages/f4/f4/a4541072bb9422c8a883ab55255f918fa378ecf083f5b85e87fc2b4eda1b/pyyaml-6.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:93dda82c9c22deb0a405ea4dc5f2d0cda384168e466364dec6255b293923b2f3", size = 143912, upload-time = "2025-09-25T21:32:59.247Z" }, + { url = "https://files.pythonhosted.org/packages/7c/f9/07dd09ae774e4616edf6cda684ee78f97777bdd15847253637a6f052a62f/pyyaml-6.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:02893d100e99e03eda1c8fd5c441d8c60103fd175728e23e431db1b589cf5ab3", size = 189108, upload-time = "2025-09-25T21:32:44.377Z" }, + { url = "https://files.pythonhosted.org/packages/4e/78/8d08c9fb7ce09ad8c38ad533c1191cf27f7ae1effe5bb9400a46d9437fcf/pyyaml-6.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c1ff362665ae507275af2853520967820d9124984e0f7466736aea23d8611fba", size = 183641, upload-time = "2025-09-25T21:32:45.407Z" }, + { url = "https://files.pythonhosted.org/packages/7b/5b/3babb19104a46945cf816d047db2788bcaf8c94527a805610b0289a01c6b/pyyaml-6.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6adc77889b628398debc7b65c073bcb99c4a0237b248cacaf3fe8a557563ef6c", size = 831901, upload-time = "2025-09-25T21:32:48.83Z" }, + { url = "https://files.pythonhosted.org/packages/8b/cc/dff0684d8dc44da4d22a13f35f073d558c268780ce3c6ba1b87055bb0b87/pyyaml-6.0.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a80cb027f6b349846a3bf6d73b5e95e782175e52f22108cfa17876aaeff93702", size = 861132, upload-time = "2025-09-25T21:32:50.149Z" }, + { url = "https://files.pythonhosted.org/packages/b1/5e/f77dc6b9036943e285ba76b49e118d9ea929885becb0a29ba8a7c75e29fe/pyyaml-6.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c", size = 839261, upload-time = "2025-09-25T21:32:51.808Z" }, + { url = "https://files.pythonhosted.org/packages/ce/88/a9db1376aa2a228197c58b37302f284b5617f56a5d959fd1763fb1675ce6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:66e1674c3ef6f541c35191caae2d429b967b99e02040f5ba928632d9a7f0f065", size = 805272, upload-time = "2025-09-25T21:32:52.941Z" }, + { url = "https://files.pythonhosted.org/packages/da/92/1446574745d74df0c92e6aa4a7b0b3130706a4142b2d1a5869f2eaa423c6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65", size = 829923, upload-time = "2025-09-25T21:32:54.537Z" }, + { url = "https://files.pythonhosted.org/packages/f0/7a/1c7270340330e575b92f397352af856a8c06f230aa3e76f86b39d01b416a/pyyaml-6.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9", size = 174062, upload-time = "2025-09-25T21:32:55.767Z" }, + { url = "https://files.pythonhosted.org/packages/f1/12/de94a39c2ef588c7e6455cfbe7343d3b2dc9d6b6b2f40c4c6565744c873d/pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b", size = 149341, upload-time = "2025-09-25T21:32:56.828Z" }, +] + +[[package]] +name = "pyyaml-env-tag" +version = "1.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pyyaml" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/eb/2e/79c822141bfd05a853236b504869ebc6b70159afc570e1d5a20641782eaa/pyyaml_env_tag-1.1.tar.gz", hash = "sha256:2eb38b75a2d21ee0475d6d97ec19c63287a7e140231e4214969d0eac923cd7ff", size = 5737, upload-time = "2025-05-13T15:24:01.64Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/04/11/432f32f8097b03e3cd5fe57e88efb685d964e2e5178a48ed61e841f7fdce/pyyaml_env_tag-1.1-py3-none-any.whl", hash = "sha256:17109e1a528561e32f026364712fee1264bc2ea6715120891174ed1b980d2e04", size = 4722, upload-time = "2025-05-13T15:23:59.629Z" }, +] + +[[package]] +name = "requests" +version = "2.32.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "certifi" }, + { name = "charset-normalizer" }, + { name = "idna" }, + { name = "urllib3" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c9/74/b3ff8e6c8446842c3f5c837e9c3dfcfe2018ea6ecef224c710c85ef728f4/requests-2.32.5.tar.gz", hash = "sha256:dbba0bac56e100853db0ea71b82b4dfd5fe2bf6d3754a8893c3af500cec7d7cf", size = 134517, upload-time = "2025-08-18T20:46:02.573Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl", hash = "sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6", size = 64738, upload-time = "2025-08-18T20:46:00.542Z" }, +] + +[[package]] +name = "selectolax" +version = "0.4.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/fb/c5/959b8661d200d9fd3cf52061ce6f1d7087ec94823bb324fe1ca76c80b250/selectolax-0.4.6.tar.gz", hash = "sha256:bd9326cfc9bbd5bfcda980b0452b9761b3cf134015154e95d83fa32cbfbb751b", size = 4793248, upload-time = "2025-12-06T12:35:48.513Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a0/76/9b5358d82353b68c5828cc8ceae4ff1073495462979d2035c1089f4421dd/selectolax-0.4.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:751f727c9963584fcfa101b2696e0dd31236142901bbe7866a8e39f2ec346cc4", size = 2052057, upload-time = "2025-12-06T12:34:24.448Z" }, + { url = "https://files.pythonhosted.org/packages/e3/d1/9f8c8841f414a1b72174acef916d4ed38cc0fa041d3e933013e2b3213f30/selectolax-0.4.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d6f45737b638836b9fe2a4e7ccfbcd48a315ebb96da76a79a04b8227c1a967ee", size = 2050379, upload-time = "2025-12-06T12:34:26.383Z" }, + { url = "https://files.pythonhosted.org/packages/bc/c4/8e5ab9275a185a31d06b5ea58e3ba61d57e57700964cbd56fe074dbe458c/selectolax-0.4.6-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:15a22c5cd9c23f09227b2b9c227d986396125a9b0eb21be655f22fe4ccc5679a", size = 2238005, upload-time = "2025-12-06T12:34:28.2Z" }, + { url = "https://files.pythonhosted.org/packages/ea/af/f4299d931a8e11ba1998cac70d407c5338436978325232eb252ac7f5aba2/selectolax-0.4.6-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e64f771807f1a7353f4d6878c303bfbd6c6fe58897e301aa6d0de7e5e60cef61", size = 2272927, upload-time = "2025-12-06T12:34:29.955Z" }, + { url = "https://files.pythonhosted.org/packages/7b/5e/9afbb0e8495846bf97fa7725a6f97622ad85efc654cb3cbf4c881bd345de/selectolax-0.4.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:a0144a37fbf01695ccf2d0d24caaa058a28449cecb2c754bb9e616f339468d74", size = 2250901, upload-time = "2025-12-06T12:34:31.442Z" }, + { url = "https://files.pythonhosted.org/packages/d5/6b/914cc9c977fd21949af5776d25b9c011b6e72fb38569161ab6ca83d6130a/selectolax-0.4.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:3c9bdd4a9b3f71f28a0ee558a105451debd33cbe1ed350ebba7ad6b68d62815c", size = 2279842, upload-time = "2025-12-06T12:34:32.739Z" }, + { url = "https://files.pythonhosted.org/packages/e1/30/b32d79d31c893cf5ccea5a5be4565db1eda9bbf458ddfe402559267f2d31/selectolax-0.4.6-cp311-cp311-win32.whl", hash = "sha256:b91c34b854fdd5d21c8353f130899f8413b7104a96078acbca59c8b2d57e9352", size = 1730462, upload-time = "2025-12-06T12:34:34.435Z" }, + { url = "https://files.pythonhosted.org/packages/8f/f1/c7ba048d4fcc4c8d5857233c59d07f18e60b21400a8ad8e8d7da670024c2/selectolax-0.4.6-cp311-cp311-win_amd64.whl", hash = "sha256:901064121e706bc86ed13f6e0dbe478398ad05ab112f5efbc8d722320a087b93", size = 1831442, upload-time = "2025-12-06T12:34:35.846Z" }, + { url = "https://files.pythonhosted.org/packages/d5/55/b33853f66b1f875bbbbfc2294ce7a4065774621ab6ebf20e8abf19965846/selectolax-0.4.6-cp311-cp311-win_arm64.whl", hash = "sha256:609c6c19f5b7cb669a6321a1d4133d2e2b443f23f7d454de76904118a91236a6", size = 1781850, upload-time = "2025-12-06T12:34:37.175Z" }, + { url = "https://files.pythonhosted.org/packages/ee/81/1fdf6633df840afd9d7054a3441f04cfb1fc9d098c6c9f3bd46a64fb632e/selectolax-0.4.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:20615062d6062b197b61fd646e667591e987be3a894e8a8408d2a482ccddc747", size = 2051021, upload-time = "2025-12-06T12:34:38.495Z" }, + { url = "https://files.pythonhosted.org/packages/cc/54/d59738d090cb4df3a3a6297b7ec216b86d3ba7f320013c4bc8d4841c9f5d/selectolax-0.4.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c436006e2af6ade80b96411cf46652c11ced4f230032e25e1f5210b7522a4fe3", size = 2047409, upload-time = "2025-12-06T12:34:39.875Z" }, + { url = "https://files.pythonhosted.org/packages/fc/67/3b163ec18a128df3a3b59ce676a2dacfb26e714da81ba8a98e184b4ef187/selectolax-0.4.6-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:705a70b6f4e553e8c5299881269d3735a7df8a23711927a33caa16b4eaef580f", size = 2237052, upload-time = "2025-12-06T12:34:41.24Z" }, + { url = "https://files.pythonhosted.org/packages/f0/04/c3ae4a77e8cfa647b9177e727a7e80f64b160b65ad0db0dcb3738a4ef4a0/selectolax-0.4.6-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c04fd180689ed9450ad2453a3cba74cff2475a4281f76db9e18a658b7823e594", size = 2275615, upload-time = "2025-12-06T12:34:43.114Z" }, + { url = "https://files.pythonhosted.org/packages/12/de/aaa016c44e63a1efd5525f6da6eac807388a06c70671091c735d93f13b74/selectolax-0.4.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:cb33eb0809e70ba4a475105d164c3f90a4bb711744ca69e20037298256b8e9d7", size = 2249186, upload-time = "2025-12-06T12:34:44.84Z" }, + { url = "https://files.pythonhosted.org/packages/76/9a/a9cf9f0158b0804c7ea404d790af031830eb6452a4948853f7582eea6c51/selectolax-0.4.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:97f30b7c731f9f3328e9c6aef7ca3c17fbcbc4495e286a2cdad9a77bcadfadf1", size = 2282041, upload-time = "2025-12-06T12:34:46.19Z" }, + { url = "https://files.pythonhosted.org/packages/4c/ea/85de7ab8a9fc0301d1b428e69dc0bced9c1cd7379872d576a2b88eb91933/selectolax-0.4.6-cp312-cp312-win32.whl", hash = "sha256:f4375b352b609508e4a6980431dc6cc1812b97658ad1aa8caa61e01565de0d7d", size = 1727544, upload-time = "2025-12-06T12:34:47.541Z" }, + { url = "https://files.pythonhosted.org/packages/50/70/4aac2df64920112672cda846941d85c90b8152b2eddc9cf2615181551957/selectolax-0.4.6-cp312-cp312-win_amd64.whl", hash = "sha256:1d02637a6746bf1ba7de1dfc00a0344ffb30bedd1b5d4e61727c960225bf6ce0", size = 1827825, upload-time = "2025-12-06T12:34:49.283Z" }, + { url = "https://files.pythonhosted.org/packages/8d/b0/09648383afed1a10df97ce30527d30714edc4072086915b4bb1a0d81a728/selectolax-0.4.6-cp312-cp312-win_arm64.whl", hash = "sha256:bb0b371c3e2a94e6658ba4b5af88fc35aaf44f57f5a066ecaf96b4875a47aec4", size = 1775233, upload-time = "2025-12-06T12:34:51.576Z" }, + { url = "https://files.pythonhosted.org/packages/4d/87/7ed053cce7de8b29746c602851c67654287e25ec404d575911c6f40b671f/selectolax-0.4.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8303af0eeef6ab2f06f2b18e3c825df4f6984405a862c8e9e654621c26558aca", size = 2050412, upload-time = "2025-12-06T12:34:53.086Z" }, + { url = "https://files.pythonhosted.org/packages/44/74/e8cd9b9b53da0e849b27a2ef68580915321ee52a662f015275a1cf6cca85/selectolax-0.4.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d8b1fb5507d90e719de705d93eaa3bdd5f2d69facf012fb67b7da8a9cd20ea6b", size = 2046513, upload-time = "2025-12-06T12:34:54.583Z" }, + { url = "https://files.pythonhosted.org/packages/a0/ca/c1cc7f03b681d272dbb0dc47cf9d0df857ae156d7ea54d88cc25ec23c8e9/selectolax-0.4.6-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:30ac51bd5bfcd6bffe58720b1fc5f97666681f0793d79d292069b3a3f8599ef0", size = 2234404, upload-time = "2025-12-06T12:34:55.971Z" }, + { url = "https://files.pythonhosted.org/packages/df/00/a6e5c4d65243147fbd8837951267f098d9bee66ada4dc0c99d97259e052c/selectolax-0.4.6-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cfee4d1269fd462256641abdf6c2ee4dd799ba82c578acab0bcde07547637826", size = 2272678, upload-time = "2025-12-06T12:34:57.3Z" }, + { url = "https://files.pythonhosted.org/packages/ab/a2/05351e0f0da62d1bc01b7820a990f1e4dec688206e0278ee8faeeb878940/selectolax-0.4.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:fce09eeb5dd19fba672a829f63e3c40238af4a929ce1e5fd16dcbc4fd253e300", size = 2247471, upload-time = "2025-12-06T12:34:59.048Z" }, + { url = "https://files.pythonhosted.org/packages/ea/95/1ab9e3ad2d53dbcd7141af149c7259c693dc2dc46e27d72b7a68f17f3364/selectolax-0.4.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b4e97ca71d545cab9c57ba3b18358cbc96ef0dcd01920ea903a531386ca1f849", size = 2278271, upload-time = "2025-12-06T12:35:00.487Z" }, + { url = "https://files.pythonhosted.org/packages/04/41/ca80ca68fb9990cb46d753363d8dc0771225bc9bb9a77247a1987e52d2d5/selectolax-0.4.6-cp313-cp313-win32.whl", hash = "sha256:98fce08839cb8fd5d8788cbed2724cd892c78182cd923e246ef586d552a29a94", size = 1727514, upload-time = "2025-12-06T12:35:02.081Z" }, + { url = "https://files.pythonhosted.org/packages/f0/47/f048994ab32773fda8eda57a874afb30d0b2bf30952c009006e81737e07e/selectolax-0.4.6-cp313-cp313-win_amd64.whl", hash = "sha256:cdc8e7833d2456331e519fe901d1c8844d120a26b21b6429f47ae946e65b0c04", size = 1829070, upload-time = "2025-12-06T12:35:03.857Z" }, + { url = "https://files.pythonhosted.org/packages/50/94/ab0d86b1a719c090e2bde9f7d9037439900e86fb50c258b5fd9f6530521b/selectolax-0.4.6-cp313-cp313-win_arm64.whl", hash = "sha256:d6f8c976ad067a6607b2a052b141149ae23584819b73288c32f08a1ece23d60a", size = 1774935, upload-time = "2025-12-06T12:35:05.323Z" }, + { url = "https://files.pythonhosted.org/packages/d2/38/93b4907c596487e13f8261129b1663559c96fc37ea2c973c98a393307484/selectolax-0.4.6-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:961c037ac41a12bf9db35a95d6076461f9b127d361c9ef26a77f76c45b1056eb", size = 2069131, upload-time = "2025-12-06T12:35:06.737Z" }, + { url = "https://files.pythonhosted.org/packages/f6/04/d29769a8313ccb9db6278401840e79662f341b716d268f7468b6270d15e1/selectolax-0.4.6-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:f2be076a69a12657a38933b99d31c604d95d63911e0799f89305da8e89918874", size = 2066134, upload-time = "2025-12-06T12:35:08.163Z" }, + { url = "https://files.pythonhosted.org/packages/29/a2/1c26b4cc6a708d234e39199bd75acdc1cfdcf4f3138e16d25e3e7aa0295d/selectolax-0.4.6-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:25ae5dd7c20035312211de43952934981e8ff4e1502467ce78665f57bc5eaf7f", size = 2240810, upload-time = "2025-12-06T12:35:09.556Z" }, + { url = "https://files.pythonhosted.org/packages/1f/de/b021342d306bd08c92d0d9e9072a3ed6a3038f78387187d37fb775196fa0/selectolax-0.4.6-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cfe1274930affe2b986fd20cbf2916ddf4a760edf30a7eeb9151b31e8cbe6027", size = 2274401, upload-time = "2025-12-06T12:35:11.023Z" }, + { url = "https://files.pythonhosted.org/packages/29/77/b2816be2f4878f4e86fabca5932610401dc88d956948d97a82947e27d8bc/selectolax-0.4.6-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:e52174a75236c1321f0f0353b5d97ba575c61428f16c2d78159cb154fa407e97", size = 2271054, upload-time = "2025-12-06T12:35:12.878Z" }, + { url = "https://files.pythonhosted.org/packages/1f/3a/ae48b9febf2af21a0fdd4fba07861ae3e13bd7235df3fa39918d33004058/selectolax-0.4.6-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5032187ed8f8d77da6dee5467a87fe9b1553c10c63671fe830e87a2d347ef8ae", size = 2297773, upload-time = "2025-12-06T12:35:14.383Z" }, + { url = "https://files.pythonhosted.org/packages/f9/8c/4e120b2b6dc55543bf2ffc43e78589022e59c02fa93dea0b4d22dfe3fc27/selectolax-0.4.6-cp314-cp314-win32.whl", hash = "sha256:8a4f50eb37abffe118730c062827a204a732cc1b9cd28b5dbf40752c371e9339", size = 1838289, upload-time = "2025-12-06T12:35:16.278Z" }, + { url = "https://files.pythonhosted.org/packages/c4/2f/51f15b06f4fcf9d5845d6bba534f7f2ed531f148c77ed8fff105cd770aa5/selectolax-0.4.6-cp314-cp314-win_amd64.whl", hash = "sha256:11527cd430cb6d1d1a422209d87aec5767befff424f2affaa3daa2789878cf9f", size = 1938201, upload-time = "2025-12-06T12:35:17.694Z" }, + { url = "https://files.pythonhosted.org/packages/f3/8d/c099dcbb385e7d2145c4f19da183639bf4e429e1524dcba31ea311c5d276/selectolax-0.4.6-cp314-cp314-win_arm64.whl", hash = "sha256:254d7f59580631dac1fcb861bb01f45039e3ac53187f07d8ccc3519110bacad0", size = 1886188, upload-time = "2025-12-06T12:35:19.538Z" }, + { url = "https://files.pythonhosted.org/packages/54/ce/f3fa904517745ecd289b6ce18845ae968cf7d0b17e65ab781259f2746254/selectolax-0.4.6-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:48a9bce389c281fec8bf3b5a36bd376f1ad1f36ff072dcedaa977188b3882be1", size = 2088107, upload-time = "2025-12-06T12:35:21.061Z" }, + { url = "https://files.pythonhosted.org/packages/4f/18/359da9723d3ec1235819cea0958bc417ce6a12699977920854b300ad4529/selectolax-0.4.6-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:ff1632c1767f6005adc2dff7b72ea9d0b6493702e86e04ee5cf934ab630172aa", size = 2090836, upload-time = "2025-12-06T12:35:22.421Z" }, + { url = "https://files.pythonhosted.org/packages/e2/20/199f2a05ca8dfd9bc146af03fbfaa1e2050601d3141267070a2a023ea68f/selectolax-0.4.6-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:64a56dd91c22e809305e127bbd4cd75ad1016dd329a4e945a176c6f3376d00e2", size = 2248608, upload-time = "2025-12-06T12:35:23.946Z" }, + { url = "https://files.pythonhosted.org/packages/f9/67/261c06cdae29fad287008d39f51a80431f3fce66c2865b880e61d04cdfd2/selectolax-0.4.6-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:223471d2c9095406d69faf461aa217782575d62362d36809e350f6d3c2f69f4e", size = 2275653, upload-time = "2025-12-06T12:35:25.423Z" }, + { url = "https://files.pythonhosted.org/packages/10/80/f2519487a86b5366acadd9e07c212b38fb657bb62b9e01de9fb24c3ada27/selectolax-0.4.6-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:8c1043e61df29f4f8ef49f9f623b3d710f0c545d9a7939eee52c49987b06aef7", size = 2283495, upload-time = "2025-12-06T12:35:26.843Z" }, + { url = "https://files.pythonhosted.org/packages/66/cc/35a0fd896371e0b5a84365b03f88c7dbe8984862e34ce32baed81ee6f486/selectolax-0.4.6-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:b323ad4ebcf2edad2488022402fbc73ee158ffe81607ec1ce5eb1039eab94086", size = 2300207, upload-time = "2025-12-06T12:35:28.23Z" }, + { url = "https://files.pythonhosted.org/packages/51/b2/dc83cce2f38a3c72d6bf9268ef6c1708ab1b4d546074384e7e0d097bf4f6/selectolax-0.4.6-cp314-cp314t-win32.whl", hash = "sha256:f5017f6e2408160604c87fb21490d9af802d09dbc1b91ac89acd9922b7b04d31", size = 1890595, upload-time = "2025-12-06T12:35:29.625Z" }, + { url = "https://files.pythonhosted.org/packages/87/f9/8da49637643b1dffbcadc8972f1fee519c126978acaf5df59405e48424f4/selectolax-0.4.6-cp314-cp314t-win_amd64.whl", hash = "sha256:56adb0f014ab55627f20f53888a7bf1ec53aac8189fe344aec3d5077a7ad9889", size = 2005252, upload-time = "2025-12-06T12:35:31.116Z" }, + { url = "https://files.pythonhosted.org/packages/94/7f/f783e2254db082df4f6bc00fe3b32b9dd27c3b7302a44c8c37728bb67fb7/selectolax-0.4.6-cp314-cp314t-win_arm64.whl", hash = "sha256:66558cfb1c7402fed0f47b9a2692eed53e3e2f345526314b493b5093cb951e21", size = 1906079, upload-time = "2025-12-06T12:35:32.951Z" }, +] + +[[package]] +name = "six" +version = "1.17.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031, upload-time = "2024-12-04T17:35:28.174Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050, upload-time = "2024-12-04T17:35:26.475Z" }, +] + +[[package]] +name = "smmap" +version = "5.0.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/44/cd/a040c4b3119bbe532e5b0732286f805445375489fceaec1f48306068ee3b/smmap-5.0.2.tar.gz", hash = "sha256:26ea65a03958fa0c8a1c7e8c7a58fdc77221b8910f6be2131affade476898ad5", size = 22329, upload-time = "2025-01-02T07:14:40.909Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/04/be/d09147ad1ec7934636ad912901c5fd7667e1c858e19d355237db0d0cd5e4/smmap-5.0.2-py3-none-any.whl", hash = "sha256:b30115f0def7d7531d22a0fb6502488d879e75b260a9db4d0819cfb25403af5e", size = 24303, upload-time = "2025-01-02T07:14:38.724Z" }, +] + +[[package]] +name = "text-unidecode" +version = "1.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ab/e2/e9a00f0ccb71718418230718b3d900e71a5d16e701a3dae079a21e9cd8f8/text-unidecode-1.3.tar.gz", hash = "sha256:bad6603bb14d279193107714b288be206cac565dfa49aa5b105294dd5c4aab93", size = 76885, upload-time = "2019-08-30T21:36:45.405Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a6/a5/c0b6468d3824fe3fde30dbb5e1f687b291608f9473681bbf7dabbf5a87d7/text_unidecode-1.3-py2.py3-none-any.whl", hash = "sha256:1311f10e8b895935241623731c2ba64f4c455287888b18189350b67134a822e8", size = 78154, upload-time = "2019-08-30T21:37:03.543Z" }, +] + +[[package]] +name = "typing-extensions" +version = "4.15.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", size = 109391, upload-time = "2025-08-25T13:49:26.313Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548", size = 44614, upload-time = "2025-08-25T13:49:24.86Z" }, +] + +[[package]] +name = "typing-inspect" +version = "0.8.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mypy-extensions" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/72/23/bed3ea644bcd77ffe9a7f591eb058c00739747e33ab94d80cc4319ddee8e/typing_inspect-0.8.0.tar.gz", hash = "sha256:8b1ff0c400943b6145df8119c41c244ca8207f1f10c9c057aeed1560e4806e3d", size = 13550, upload-time = "2022-08-17T14:00:05.915Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/be/01/59b743dca816c4b6ca891b9e0f84d20513cd61bdbbaa8615de8f5aab68c1/typing_inspect-0.8.0-py3-none-any.whl", hash = "sha256:5fbf9c1e65d4fa01e701fe12a5bca6c6e08a4ffd5bc60bfac028253a447c5188", size = 8710, upload-time = "2022-08-17T14:00:03.093Z" }, +] + +[[package]] +name = "tzdata" +version = "2025.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/95/32/1a225d6164441be760d75c2c42e2780dc0873fe382da3e98a2e1e48361e5/tzdata-2025.2.tar.gz", hash = "sha256:b60a638fcc0daffadf82fe0f57e53d06bdec2f36c4df66280ae79bce6bd6f2b9", size = 196380, upload-time = "2025-03-23T13:54:43.652Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5c/23/c7abc0ca0a1526a0774eca151daeb8de62ec457e77262b66b359c3c7679e/tzdata-2025.2-py2.py3-none-any.whl", hash = "sha256:1a403fada01ff9221ca8044d701868fa132215d84beb92242d9acd2147f667a8", size = 347839, upload-time = "2025-03-23T13:54:41.845Z" }, +] + +[[package]] +name = "urllib3" +version = "2.6.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/1e/24/a2a2ed9addd907787d7aa0355ba36a6cadf1768b934c652ea78acbd59dcd/urllib3-2.6.2.tar.gz", hash = "sha256:016f9c98bb7e98085cb2b4b17b87d2c702975664e4f060c6532e64d1c1a5e797", size = 432930, upload-time = "2025-12-11T15:56:40.252Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6d/b9/4095b668ea3678bf6a0af005527f39de12fb026516fb3df17495a733b7f8/urllib3-2.6.2-py3-none-any.whl", hash = "sha256:ec21cddfe7724fc7cb4ba4bea7aa8e2ef36f607a4bab81aa6ce42a13dc3f03dd", size = 131182, upload-time = "2025-12-11T15:56:38.584Z" }, +] + +[[package]] +name = "watchdog" +version = "6.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/db/7d/7f3d619e951c88ed75c6037b246ddcf2d322812ee8ea189be89511721d54/watchdog-6.0.0.tar.gz", hash = "sha256:9ddf7c82fda3ae8e24decda1338ede66e1c99883db93711d8fb941eaa2d8c282", size = 131220, upload-time = "2024-11-01T14:07:13.037Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e0/24/d9be5cd6642a6aa68352ded4b4b10fb0d7889cb7f45814fb92cecd35f101/watchdog-6.0.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6eb11feb5a0d452ee41f824e271ca311a09e250441c262ca2fd7ebcf2461a06c", size = 96393, upload-time = "2024-11-01T14:06:31.756Z" }, + { url = "https://files.pythonhosted.org/packages/63/7a/6013b0d8dbc56adca7fdd4f0beed381c59f6752341b12fa0886fa7afc78b/watchdog-6.0.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ef810fbf7b781a5a593894e4f439773830bdecb885e6880d957d5b9382a960d2", size = 88392, upload-time = "2024-11-01T14:06:32.99Z" }, + { url = "https://files.pythonhosted.org/packages/d1/40/b75381494851556de56281e053700e46bff5b37bf4c7267e858640af5a7f/watchdog-6.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:afd0fe1b2270917c5e23c2a65ce50c2a4abb63daafb0d419fde368e272a76b7c", size = 89019, upload-time = "2024-11-01T14:06:34.963Z" }, + { url = "https://files.pythonhosted.org/packages/39/ea/3930d07dafc9e286ed356a679aa02d777c06e9bfd1164fa7c19c288a5483/watchdog-6.0.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:bdd4e6f14b8b18c334febb9c4425a878a2ac20efd1e0b231978e7b150f92a948", size = 96471, upload-time = "2024-11-01T14:06:37.745Z" }, + { url = "https://files.pythonhosted.org/packages/12/87/48361531f70b1f87928b045df868a9fd4e253d9ae087fa4cf3f7113be363/watchdog-6.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c7c15dda13c4eb00d6fb6fc508b3c0ed88b9d5d374056b239c4ad1611125c860", size = 88449, upload-time = "2024-11-01T14:06:39.748Z" }, + { url = "https://files.pythonhosted.org/packages/5b/7e/8f322f5e600812e6f9a31b75d242631068ca8f4ef0582dd3ae6e72daecc8/watchdog-6.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6f10cb2d5902447c7d0da897e2c6768bca89174d0c6e1e30abec5421af97a5b0", size = 89054, upload-time = "2024-11-01T14:06:41.009Z" }, + { url = "https://files.pythonhosted.org/packages/68/98/b0345cabdce2041a01293ba483333582891a3bd5769b08eceb0d406056ef/watchdog-6.0.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:490ab2ef84f11129844c23fb14ecf30ef3d8a6abafd3754a6f75ca1e6654136c", size = 96480, upload-time = "2024-11-01T14:06:42.952Z" }, + { url = "https://files.pythonhosted.org/packages/85/83/cdf13902c626b28eedef7ec4f10745c52aad8a8fe7eb04ed7b1f111ca20e/watchdog-6.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:76aae96b00ae814b181bb25b1b98076d5fc84e8a53cd8885a318b42b6d3a5134", size = 88451, upload-time = "2024-11-01T14:06:45.084Z" }, + { url = "https://files.pythonhosted.org/packages/fe/c4/225c87bae08c8b9ec99030cd48ae9c4eca050a59bf5c2255853e18c87b50/watchdog-6.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a175f755fc2279e0b7312c0035d52e27211a5bc39719dd529625b1930917345b", size = 89057, upload-time = "2024-11-01T14:06:47.324Z" }, + { url = "https://files.pythonhosted.org/packages/a9/c7/ca4bf3e518cb57a686b2feb4f55a1892fd9a3dd13f470fca14e00f80ea36/watchdog-6.0.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:7607498efa04a3542ae3e05e64da8202e58159aa1fa4acddf7678d34a35d4f13", size = 79079, upload-time = "2024-11-01T14:06:59.472Z" }, + { url = "https://files.pythonhosted.org/packages/5c/51/d46dc9332f9a647593c947b4b88e2381c8dfc0942d15b8edc0310fa4abb1/watchdog-6.0.0-py3-none-manylinux2014_armv7l.whl", hash = "sha256:9041567ee8953024c83343288ccc458fd0a2d811d6a0fd68c4c22609e3490379", size = 79078, upload-time = "2024-11-01T14:07:01.431Z" }, + { url = "https://files.pythonhosted.org/packages/d4/57/04edbf5e169cd318d5f07b4766fee38e825d64b6913ca157ca32d1a42267/watchdog-6.0.0-py3-none-manylinux2014_i686.whl", hash = "sha256:82dc3e3143c7e38ec49d61af98d6558288c415eac98486a5c581726e0737c00e", size = 79076, upload-time = "2024-11-01T14:07:02.568Z" }, + { url = "https://files.pythonhosted.org/packages/ab/cc/da8422b300e13cb187d2203f20b9253e91058aaf7db65b74142013478e66/watchdog-6.0.0-py3-none-manylinux2014_ppc64.whl", hash = "sha256:212ac9b8bf1161dc91bd09c048048a95ca3a4c4f5e5d4a7d1b1a7d5752a7f96f", size = 79077, upload-time = "2024-11-01T14:07:03.893Z" }, + { url = "https://files.pythonhosted.org/packages/2c/3b/b8964e04ae1a025c44ba8e4291f86e97fac443bca31de8bd98d3263d2fcf/watchdog-6.0.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:e3df4cbb9a450c6d49318f6d14f4bbc80d763fa587ba46ec86f99f9e6876bb26", size = 79078, upload-time = "2024-11-01T14:07:05.189Z" }, + { url = "https://files.pythonhosted.org/packages/62/ae/a696eb424bedff7407801c257d4b1afda455fe40821a2be430e173660e81/watchdog-6.0.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:2cce7cfc2008eb51feb6aab51251fd79b85d9894e98ba847408f662b3395ca3c", size = 79077, upload-time = "2024-11-01T14:07:06.376Z" }, + { url = "https://files.pythonhosted.org/packages/b5/e8/dbf020b4d98251a9860752a094d09a65e1b436ad181faf929983f697048f/watchdog-6.0.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:20ffe5b202af80ab4266dcd3e91aae72bf2da48c0d33bdb15c66658e685e94e2", size = 79078, upload-time = "2024-11-01T14:07:07.547Z" }, + { url = "https://files.pythonhosted.org/packages/07/f6/d0e5b343768e8bcb4cda79f0f2f55051bf26177ecd5651f84c07567461cf/watchdog-6.0.0-py3-none-win32.whl", hash = "sha256:07df1fdd701c5d4c8e55ef6cf55b8f0120fe1aef7ef39a1c6fc6bc2e606d517a", size = 79065, upload-time = "2024-11-01T14:07:09.525Z" }, + { url = "https://files.pythonhosted.org/packages/db/d9/c495884c6e548fce18a8f40568ff120bc3a4b7b99813081c8ac0c936fa64/watchdog-6.0.0-py3-none-win_amd64.whl", hash = "sha256:cbafb470cf848d93b5d013e2ecb245d4aa1c8fd0504e863ccefa32445359d680", size = 79070, upload-time = "2024-11-01T14:07:10.686Z" }, + { url = "https://files.pythonhosted.org/packages/33/e8/e40370e6d74ddba47f002a32919d91310d6074130fe4e17dabcafc15cbf1/watchdog-6.0.0-py3-none-win_ia64.whl", hash = "sha256:a1914259fa9e1454315171103c6a30961236f508b9b623eae470268bbcc6a22f", size = 79067, upload-time = "2024-11-01T14:07:11.845Z" }, +]