ratatui-image-10.0.8/.cargo_vcs_info.json 0000644 00000000136 10461020230 0013675 0 ustar {
"git": {
"sha1": "6674d3cb1cc9b02114d347b28a7a4be0291e3e72"
},
"path_in_vcs": ""
} ratatui-image-10.0.8/.envrc 0000644 0000000 0000000 00000000012 10461020230 0013552 0 ustar 0000000 0000000 use flake
ratatui-image-10.0.8/.github/workflows/ci.yaml 0000644 0000000 0000000 00000007745 10461020230 0017334 0 ustar 0000000 0000000 name: ci
on:
workflow_dispatch:
push:
branches:
- master
- ci
pull_request:
branches:
- master
merge_group:
workflow_call:
concurrency:
group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
env:
CLICOLOR_FORCE: 1
jobs:
ensure-readme-up-to-date:
name: Ensure readme has been generated
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install rust
uses: actions-rs/toolchain@v1
with:
toolchain: 1.88.0
profile: default
override: true
- uses: davidB/rust-cargo-make@v1
- name: Make readme
run: cargo make readme
- name: Ensure no changes
run: git diff --exit-code .
nix-flake-check:
name: Nix flake check
runs-on: ubuntu-latest
steps:
- name: Checkout Code
uses: actions/checkout@v4
- name: Install Nix
uses: cachix/install-nix-action@v24
- name: Cachix
uses: cachix/cachix-action@v12
with:
name: ratatui-image-ci
authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
- name: Flake check
run: |
nix flake show
nix flake check --print-build-logs
nix-build:
name: Nix build
runs-on: ubuntu-latest
outputs:
artifact_path: ${{ steps.upload-artifact.outputs.artifact_path }}
steps:
- name: Checkout Code
uses: actions/checkout@v4
- name: Install Nix
uses: cachix/install-nix-action@v24
- name: Cachix
uses: cachix/cachix-action@v12
with:
name: ratatui-image-ci
authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
- name: Build package
run: |
nix build . --print-build-logs
nix-build-windows:
name: Nix build (windows)
runs-on: ubuntu-latest
outputs:
artifact_path: ${{ steps.upload-artifact.outputs.artifact_path }}
steps:
- name: Checkout Code
uses: actions/checkout@v4
- name: Install Nix
uses: cachix/install-nix-action@v24
- name: Cachix
uses: cachix/cachix-action@v12
with:
name: ratatui-image-ci
authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
- name: Build package
run: |
nix build .#windows --print-build-logs
setup-terminals:
name: Find terminal tests
runs-on: ubuntu-latest
outputs:
terminals: ${{ steps.set-terminals.outputs.terminals }}
steps:
- name: Checkout Code
uses: actions/checkout@v4
- name: Install Nix
uses: cachix/install-nix-action@v24
- id: set-terminals
run: |
terminals=$(nix eval --raw --impure --expr 'let flake = builtins.getFlake (toString ./.); pkgs = flake.packages.x86_64-linux; terminals = builtins.filter (name: builtins.substring 0 15 name == "screenshot-test") (builtins.attrNames pkgs); in builtins.toJSON (map (t: builtins.substring 16 (-1) t) terminals)')
echo "terminals=$terminals" >> $GITHUB_OUTPUT
nix-flake-screenshots:
name: Nix screenshot tests
runs-on: ubuntu-latest
needs: [nix-build, setup-terminals]
permissions:
contents: read
strategy:
matrix:
terminal: ${{ fromJSON(needs.setup-terminals.outputs.terminals) }}
steps:
- name: Checkout Code
uses: actions/checkout@v4
- name: Install Nix
uses: cachix/install-nix-action@v24
- name: Cachix
uses: cachix/cachix-action@v12
with:
name: ratatui-image-ci
authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
- name: Run screenshot test for ${{ matrix.terminal }}
run: |
nix build .#screenshot-test-${{ matrix.terminal }} --print-build-logs
- name: Upload screenshot artifact
uses: actions/upload-artifact@v4
with:
name: screenshot-${{ matrix.terminal }}
path: result/screenshot-${{ matrix.terminal }}.png
ratatui-image-10.0.8/.github/workflows/fast-forward.yml 0000644 0000000 0000000 00000001452 10461020230 0021164 0 ustar 0000000 0000000 name: fast-forward
on:
issue_comment:
types: [created, edited]
jobs:
fast-forward:
if: ${{ contains(github.event.comment.body, '/merge')
&& github.event.issue.pull_request }}
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
issues: write
steps:
- name: Fast forwarding
uses: sequoia-pgp/fast-forward@v1
with:
merge: true
# To reduce the workflow's verbosity, use 'on-error'
# to only post a comment when an error occurs, or 'never' to
# never post a comment. (In all cases the information is
# still available in the step's summary.)
comment: never
# Use PAT to allow the push to trigger CI workflow
github_token: ${{ secrets.PAT }}
ratatui-image-10.0.8/.github/workflows/pull_request.yml 0000644 0000000 0000000 00000001412 10461020230 0021305 0 ustar 0000000 0000000 name: pull-request
on:
pull_request:
types: [opened, reopened, synchronize]
jobs:
check-fast-forward:
runs-on: ubuntu-latest
permissions:
contents: read
# We appear to need write permission for both pull-requests and
# issues in order to post a comment to a pull request.
pull-requests: write
issues: write
steps:
- name: Checking if fast forwarding is possible
uses: sequoia-pgp/fast-forward@v1
with:
merge: false
# To reduce the workflow's verbosity, use 'on-error'
# to only post a comment when an error occurs, or 'never' to
# never post a comment. (In all cases the information is
# still available in the step's summary.)
comment: never
ratatui-image-10.0.8/.github/workflows/release-plz.yml 0000644 0000000 0000000 00000003736 10461020230 0021017 0 ustar 0000000 0000000 name: Release-plz
permissions:
pull-requests: write
contents: write
on:
push:
branches:
- master
jobs:
nix-flake-check:
name: Nix flake check
runs-on: ubuntu-latest
if: ${{ github.repository_owner == 'ratatui' }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install Nix
uses: cachix/install-nix-action@v24
- name: Cachix
uses: cachix/cachix-action@v12
with:
name: ratatui-image-ci
authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
- name: Flake check
run: |
nix flake show
nix flake check --print-build-logs
# Release unpublished packages.
release-plz-release:
name: Release-plz release
runs-on: ubuntu-latest
needs: nix-flake-check
environment: release
if: ${{ github.repository_owner == 'ratatui' }}
permissions:
contents: write
id-token: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Run release-plz
uses: MarcoIeni/release-plz-action@v0.5
with:
command: release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# Create a PR with the new versions and changelog, preparing the next release.
release-plz-pr:
name: Release-plz PR
runs-on: ubuntu-latest
if: ${{ github.repository_owner == 'ratatui' }}
concurrency:
group: release-plz-${{ github.ref }}
cancel-in-progress: false
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Run release-plz
uses: MarcoIeni/release-plz-action@v0.5
with:
command: release-pr
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ratatui-image-10.0.8/.github/workflows/screenshots.yaml 0000644 0000000 0000000 00000030554 10461020230 0021273 0 ustar 0000000 0000000 name: screenshots
on:
workflow_run:
workflows: ["ci"]
types: [completed]
jobs:
deploy-screenshots-branch:
name: Deploy screenshots branch
runs-on: ubuntu-latest
# Only for PRs, and only if CI succeeded
if: github.event.workflow_run.event == 'pull_request' && github.event.workflow_run.conclusion == 'success'
permissions:
contents: read
pull-requests: write
actions: read # Needed to download artifacts from another workflow
steps:
- name: Download all screenshot artifacts
uses: actions/download-artifact@v4
with:
pattern: screenshot-*
path: screenshots
run-id: ${{ github.event.workflow_run.id }}
github-token: ${{ github.token }}
- name: Get terminal list from artifacts
id: terminals
run: |
# List downloaded artifact directories and extract terminal names
terminal_list=$(ls screenshots | sed 's/screenshot-//' | tr '\n' ' ')
echo "list=$terminal_list" >> $GITHUB_OUTPUT
- name: Check for terminal changes
id: terminal-changes
run: |
# Get terminals from master (reference screenshots)
master_terminals=$(curl -s "https://api.github.com/repos/benjajaja/ratatui-image-screenshots/contents/images?ref=gh-pages" | jq -r '.[].name' | grep '^screenshot-' | sed 's/screenshot-//;s/\.png//' | sort)
# Get terminals from PR
pr_terminals=$(echo "${{ steps.terminals.outputs.list }}" | tr ' ' '\n' | grep -v '^$' | sort)
# Find missing terminals (in master but not in PR)
missing=$(comm -23 <(echo "$master_terminals") <(echo "$pr_terminals") | tr '\n' ' ')
# Find added terminals (in PR but not in master)
added=$(comm -13 <(echo "$master_terminals") <(echo "$pr_terminals") | tr '\n' ' ')
if [ -n "$missing" ] && [ "$missing" != " " ]; then
echo "::warning::Missing terminals compared to master: $missing"
echo "missing=$missing" >> $GITHUB_OUTPUT
fi
if [ -n "$added" ] && [ "$added" != " " ]; then
echo "::notice::New terminals added: $added"
echo "added=$added" >> $GITHUB_OUTPUT
fi
- name: Download dify binary
run: |
curl -L https://github.com/jihchi/dify/releases/download/v0.7.4/dify-x86_64-unknown-linux-gnu-v0.7.4.tar.gz -o dify.tar.gz
tar -xzf dify.tar.gz
chmod +x dify
- name: Download reference screenshots from master
run: |
mkdir -p reference-screenshots
# Base URL for master branch screenshots
BASE_URL="https://raw.githubusercontent.com/benjajaja/ratatui-image-screenshots/gh-pages/images"
terminal_list="${{ steps.terminals.outputs.list }}"
for terminal in $terminal_list; do
echo "Downloading reference screenshot for ${terminal}..."
curl -f -L "${BASE_URL}/screenshot-${terminal}.png" -o "reference-screenshots/screenshot-${terminal}.png" || echo "No reference screenshot found for ${terminal}"
done
- name: Create image diffs
run: |
mkdir -p diffs
terminal_list="${{ steps.terminals.outputs.list }}"
for terminal in $terminal_list; do
if [ -f "screenshots/screenshot-${terminal}/screenshot-${terminal}.png" ] && [ -f "reference-screenshots/screenshot-${terminal}.png" ]; then
echo "Creating diff for ${terminal}..."
# Run dify and capture exit code (which indicates amount of difference)
set +e # Disable exit on error temporarily
./dify "reference-screenshots/screenshot-${terminal}.png" "screenshots/screenshot-${terminal}/screenshot-${terminal}.png"
diff_amount=$?
set -e # Re-enable exit on error
echo "Difference amount for ${terminal}: ${diff_amount}"
# Check if diff.png was created and move it
if [ -f "diff.png" ]; then
mv diff.png "diffs/diff-${terminal}.png"
echo "Created diff for ${terminal}"
else
echo "No diff.png file created for ${terminal}"
fi
else
echo "Missing screenshot files for ${terminal}, skipping diff"
if [ ! -f "screenshots/screenshot-${terminal}/screenshot-${terminal}.png" ]; then
echo " Missing current screenshot"
fi
if [ ! -f "reference-screenshots/screenshot-${terminal}.png" ]; then
echo " Missing reference screenshot"
fi
fi
done
- name: Organize screenshots for deployment
run: |
mkdir -p pages
# Copy screenshots to pages directory
terminal_list="${{ steps.terminals.outputs.list }}"
for terminal in $terminal_list; do
if [ -f "screenshots/screenshot-${terminal}/screenshot-${terminal}.png" ]; then
cp "screenshots/screenshot-${terminal}/screenshot-${terminal}.png" "pages/screenshot-${terminal}.png"
echo "Copied screenshot for ${terminal}"
fi
done
# Copy diff images to pages directory
for terminal in $terminal_list; do
if [ -f "diffs/diff-${terminal}.png" ]; then
cp "diffs/diff-${terminal}.png" "pages/diff-${terminal}.png"
echo "Copied diff for ${terminal}"
fi
done
- name: Get PR number
id: pr
run: |
# Get PR number from the workflow run
# First try the workflow run's pull_requests array (works for same-repo PRs)
PR_NUMBER=$(gh api /repos/${{ github.repository }}/actions/runs/${{ github.event.workflow_run.id }} --jq '.pull_requests[0].number')
# For fork PRs, pull_requests array is empty - use search API instead
if [ -z "$PR_NUMBER" ] || [ "$PR_NUMBER" = "null" ]; then
HEAD_SHA="${{ github.event.workflow_run.head_sha }}"
PR_NUMBER=$(gh pr list --repo ${{ github.repository }} --state all --json number,headRefOid --jq ".[] | select(.headRefOid == \"$HEAD_SHA\") | .number")
fi
if [ -z "$PR_NUMBER" ] || [ "$PR_NUMBER" = "null" ]; then
echo "::error::Could not determine PR number"
exit 1
fi
echo "number=$PR_NUMBER" >> $GITHUB_OUTPUT
env:
GH_TOKEN: ${{ github.token }}
- name: Deploy to external repo
uses: peaceiris/actions-gh-pages@v3
with:
personal_token: ${{ secrets.PAT }}
external_repository: benjajaja/ratatui-image-screenshots
publish_dir: ./pages
publish_branch: pr-${{ steps.pr.outputs.number }}
force_orphan: true
- name: Create combined comment
run: |
terminal_list="${{ steps.terminals.outputs.list }}"
missing_terminals="${{ steps.terminal-changes.outputs.missing }}"
added_terminals="${{ steps.terminal-changes.outputs.added }}"
# Base URL for raw GitHub content
BASE_URL="https://raw.githubusercontent.com/benjajaja/ratatui-image-screenshots/pr-${{ steps.pr.outputs.number }}"
# Initialize comment body
echo "Merge of ${{ github.event.workflow_run.head_sha }} to \`master\`" > comment_body.txt
echo "" >> comment_body.txt
# Add warning if terminals are missing
if [ -n "$missing_terminals" ] && [ "$missing_terminals" != " " ]; then
echo "â ī¸ **Warning: Missing terminals compared to master:** $missing_terminals" >> comment_body.txt
echo "" >> comment_body.txt
fi
# Add notice if terminals are added
if [ -n "$added_terminals" ] && [ "$added_terminals" != " " ]; then
echo "⨠**New terminals added:** $added_terminals" >> comment_body.txt
echo "" >> comment_body.txt
fi
echo "Screenshots from all terminal emulators:" >> comment_body.txt
echo "" >> comment_body.txt
for terminal in $terminal_list; do
echo "### ${terminal}" >> comment_body.txt
echo "" >> comment_body.txt
echo "" >> comment_body.txt
# Check if diff image exists by trying to fetch it
diff_url="${BASE_URL}/diff-${terminal}.png"
if curl -f -s -I "$diff_url" > /dev/null 2>&1; then
echo "**Image diff vs master:**" >> comment_body.txt
echo "" >> comment_body.txt
echo "" >> comment_body.txt
else
echo "**No diff available** (no changes detected)" >> comment_body.txt
echo "" >> comment_body.txt
fi
done
- name: Comment on PR with all screenshots
uses: marocchino/sticky-pull-request-comment@v2
with:
number: ${{ steps.pr.outputs.number }}
path: comment_body.txt
deploy-screenshots-master:
name: Deploy master screenshots to external repo
runs-on: ubuntu-latest
# Only for push to master, and only if CI succeeded
if: github.event.workflow_run.event == 'push' && github.event.workflow_run.head_branch == 'master' && github.event.workflow_run.conclusion == 'success'
permissions:
contents: read
actions: read
steps:
- name: Download all screenshot artifacts
uses: actions/download-artifact@v4
with:
pattern: screenshot-*
path: screenshots
merge-multiple: false
run-id: ${{ github.event.workflow_run.id }}
github-token: ${{ github.token }}
- name: Get terminal list from artifacts
id: terminals
run: |
terminal_list=$(ls screenshots | sed 's/screenshot-//' | tr '\n' ' ')
echo "list=$terminal_list" >> $GITHUB_OUTPUT
- name: Organize screenshots for Pages
run: |
mkdir -p pages/images
# Move screenshot images to pages/images directory
terminal_list="${{ steps.terminals.outputs.list }}"
for terminal in $terminal_list; do
if [ -f "screenshots/screenshot-${terminal}/screenshot-${terminal}.png" ]; then
cp "screenshots/screenshot-${terminal}/screenshot-${terminal}.png" "pages/images/screenshot-${terminal}.png"
echo "Copied screenshot for ${terminal}"
else
echo "Warning: Screenshot file not found for ${terminal}"
fi
done
# Create an index page with timestamp
timestamp=$(date -u '+%Y-%m-%d %H:%M:%S UTC')
cat > pages/index.html << EOF
Screenshots
Ratatui-Image Terminal Screenshots
Screenshots from various terminal emulators
Last updated: ${timestamp}
EOF
# Add screenshots to index using local images
for terminal in $terminal_list; do
echo "
" >> pages/index.html
echo "
$terminal
" >> pages/index.html
# Check if image exists and add to HTML
if [ -f "pages/images/screenshot-${terminal}.png" ]; then
echo "

" >> pages/index.html
else
echo "
No screenshot available
" >> pages/index.html
fi
echo "
" >> pages/index.html
done
echo "
" >> pages/index.html
- name: Deploy to GitHub Pages
uses: peaceiris/actions-gh-pages@v3
with:
personal_token: ${{ secrets.PAT }}
external_repository: benjajaja/ratatui-image-screenshots
publish_dir: ./pages
publish_branch: gh-pages
ratatui-image-10.0.8/.gitignore 0000644 0000000 0000000 00000000033 10461020230 0014427 0 ustar 0000000 0000000 /target
log
.direnv
result
ratatui-image-10.0.8/CHANGELOG.md 0000644 0000000 0000000 00000023530 10461020230 0014257 0 ustar 0000000 0000000 # Changelog
All notable changes to this project will be documented in this file.
## [Unreleased]
## [10.0.8](https://github.com/ratatui/ratatui-image/compare/v10.0.7...v10.0.8) - 2026-04-30
### Added
- feature kitty-offset to skip unicode-placeholders in kitty
## [10.0.7](https://github.com/ratatui/ratatui-image/compare/v10.0.6...v10.0.7) - 2026-04-28
### Other
- release-plz must use ratatui as owner now
- unify clear_area() for sixel and iterm2, simplify single row
- add criterion benchmark
- Update README.md
- move repo links from benjajaja/ to ratatui/
### Other
- Unify the "clear_area" function across sixel and iterm2
- Skip cursor movements in "clear_area" if only one row.
- Add a criterion benchmark
## [10.0.6](https://github.com/benjajaja/ratatui-image/compare/v10.0.5...v10.0.6) - 2026-02-19
### Other
- blacklist kitty and sixel detection for WezTerm and Konsole
## [10.0.5](https://github.com/benjajaja/ratatui-image/compare/v10.0.4...v10.0.5) - 2026-02-06
### Fixed
- fix force iterm2 on wezterm+tmux
### Other
- use release-plz
- wrap each kitty "chunk" in tmux passthrough individually
- stop detecting kitty from env vars
- do not use String::insert_str(0, ...) in sixel
- apply same "append" optimization to iterm2
- don't escape non APC sequences wrongly
- lots of tiny optimizations for kitty
- add missing tmux kitty escapes
- unrelated warning fix
* Fix kitty in tmux. Since the image data is chunked, send each chunk as a separate tmux sequence to avoid exceeding some tmux limits.
* Performance improvements related to image data in all protocols.
* Use release-plz from now on.
## [10.0.4] - 2026-01-22
## [10.0.3] - 2026-01-19
* Fix transparent sixel images not having background cleared (same as iterm2).
* Sixels don't need to always be overlayed / padded, since we now have transparency.
## [10.0.2] - 2025-12-28
* Updated to latest [icy_sixel](https://github.com/mkrueger/icy_sixel/pull/14) v0.5.0 with
transparency support. If you have been overriding the Picker's background color because there
were black bars with Sixels at the bottom or right of an image, you don't need to do that anymore.
## [10.0.1] - 2025-12-27
## [10.0.0] - 2025-12-27
## [9.0.0] - 2025-12-25
* Split `chafa` feature into two mutually exclusive features:
* `chafa-dyn` (default): Dynamically links against `libchafa.so` at compile time.
Requires libchafa to be available at runtime the same way it was at compile time.
* `chafa-static`: Statically links against `libchafa.a` at compile time.
The library is embedded in the binary (see flake.nix for an example on how to build with a
static chafa).
* Removed libloading, because if it would be available at runtime, it should also be available
at compile time.
* Minor stdin-read-timeout adjustments
* Deprecate `Picker::from_fontsize`, add `Picker::halfblocks`
* Added timeout option to `Picker::from_query_stdio_with_options`.
## [8.1.1] - 2025-12-18
* [Chafa](https://hpjansson.org/chafa/) support
The Halfblocks protocol now supports chafa, if the feature is enabled.
This "ASCII Art"-like renderer is a million times better than the basic Halfblocks implementation.
The library is loaded dynamically, if the feature is enabled, at runtime.
That means no linking acrobacies are required, it should "just work" if the user has libchafa installed on their system.
It could still be "wrapped", see how the flake.nix handles `LD_LIBRARY_PATH` to magically include this in the `ratatui-image` binary.
This is still gated behind a feature, because calling chafa uses `unsafe`.
* Improved Halfblocks renderer
Picks upper block, lower block, or space, depending on pixel colors.
This gives some vague feedback when the output is rendered without colors, e.g. in insta testing snapshots.
# [8.0.2] - 2025-09-03
* Performance improvements in kitty and iterm2 protocols
* Use base64-simd
* Picker::from_query_stdio returns a halfblocks picker when: no capabilities, stdio query
timeout, or no font-size received.
* Add screenshot test suite to CI
* Add tokio support to ThreadProtocol
* Updated to rust 2024
* Add support for terminals: BobCat, warp
# [8.0.1] - 2025-05-30
Fix halfblocks not having the same size as other protocols.
# [8.0.0] - 2025-05-18
Fix `TextSizingProtocol` detection (was incorrectly detecting support on Foot terminal).
Separate "stdio query response" from "capability", as they do not match one-to-one.
Moved `Capability` into the `picker` module, as the interpretation is done there.
# [7.0.0] - 2025-05-18
`Picker` has a new field / method `capabilities`, which return the precise capabilities detected by `Picker::from_query_stdio`.
Since the struct now holds a `Vec`, `Picker` is no longer derives `Copy` (but still derives `Clone`).
This uncovered some unnecessary copying on a method that previously consumed self for no good reason.
Add `Picker::from_query_stdio_with_options` to specifically query for [Text Sizing Protocol](https://sw.kovidgoyal.net/kitty/text-sizing-protocol/#detecting-if-the-terminal-supports-this-protocol).
Not used in this library, but rather an optional convencience feature so that stdio must not be queried twice by some programs.
The capability, if detected, is `Capability::TextSizingProtocol` and can be read from `Picker::capabilities()`.
# [6.0.0] - 2025-05-17
`Image::new` uses a non-mutable borrow.
The mutability was only required for the Kitty protocol, necessary to track wether the image has already been transmitted or only needs placement.
Overall this change should remove the need to use locks when using threads or tokio.
# [5.0.0] - 2025-03-01
Add `StatefulProtocol::size_for`, that can be used to get the size that an image will be rendered to.
This allows positioning the image before it has been rendered, for example centering the image widget with the usual ratatui layout options.
ThreadImage and ThreadProtocol work with `ResizeRequest` and `ResizeResponse` instead of some tuples.
They internally track an ID so that a response for a stale area is discarded correctly.
Huge internal refactor that removes duplicated code across image protocols.
- `Errors` variant case names have been fixed.
- `StatefulProtocol` becomes a struct (was enum).
- `StatefulProtocol::area` which returned the last rendered area has been removed, use `size_for` for accurate results.
- `StatefulProtocol` methods has some parameters removed.
- All protocols except kitty lose their `Stateful...` struct implementation, as one struct can share both protocol implementations.
# [4.2.0] - 2024-12-31 đ
Fix Sixel and iTerm2 not working with tmux.
# [4.1.2] - 2024-12-30
Add a release job to the CI that makes a github release when a `v*.*.*` is pushed.
The tag itself and pushing to crates.io is done locally.
# [4.1.0] - 2024-12-23 đ
### Transparency support for Kitty and iTerm2
The image data gains an alpha channel, as well as the background color, which is now transparent by default when the protocol is not Sixel.
The area behind the image is cleared with the control sequences `ECH`, `CUD`, and `CUU` repeatedly for each row and column.
This is not particularly efficient, but it works in most terminals.
`DECERA`, which should erase the entire rectangle with only one sequence, is not implemented correctly (or not at all) in some major terminals.
Sixels could also support transparency, as the spec directly supports it.
A palette color could be set to transparent, and `icy_sixel` in fact supports this, however this is after the fact that the image has been encoded from an API perspective.
In other words, we could set a palette color index to be transparent, but we don't control that this color index would match any transparency of the input image.
This is something that would have to be added to `icy_sixel`.
### Resize: Scale
This feature is brought to you by !
The scale option scales the image, keeping the aspect ratio, to fit the full size of the given area.
It is shown in the demo.
### Capability detection
The control sequence parser has improved its "capability parsing".
In addition to querying Kitty and Sixel protocol support, the "font-size in pixels" is also queried, instead of using `tcgetattr`.
The motivation is that we already need to query stdin, and `tcgetattr` is not supported on Windows Termial, but the control sequence is.
### Minor fixes and changes
- Foreground color is restored after displaying an image with Kitty protocol.
- `Picker` must no longer be mutable.
It only was mutable so that the kitty image ids would have some sequence, but the start was based off a random number anyway to avoid clashes, so we can also just use a new random id every time.
This avoids confusion when a new protocol is created, mutating the picker, but discarding the result.
- `area() -> Rect` method on protocols.
Sometimes it definitely is useful to know how much of the given area a protocol will render to.
- Some logic fixes unnecessary image "needs-resize" calls.
# [3.0.0] - 2024-11-11
Compatible with `ratatui`: `v0.29.0`.
### Windows support
Thanks to Terakomari , windows with WSL is now supported.
The latest terminal supports sixels and necessary CSI sequences.
The CI now runs (almost) fully on Windows.
### Font size guessing and CSI parsing
Font size is queried with CSI sequence instead of tcgetattr.
The CSI response parsing has been extended into a full parser module.
### Miscellaneous improvements
- `rustix` is only used on non-windows, is not a crate feature anymore
- Improve magic env var guessing
- Kitty resets only background color
- iTerm2 use PNG intermediate encoding instead of Jpeg
- Use direnv with flake for development
### Static dispatch
Inspired by Uttarayan Mondal , changed to static dispatch with an enum instead of a `Box`.
Adding a custom protocol isn't really a use case. Errors are also static now instead of `Box`.
# [2.0.1] - 2024-10-07
(See git log)
ratatui-image-10.0.8/CODE_OF_CONDUCT.md 0000644 0000000 0000000 00000012557 10461020230 0015254 0 ustar 0000000 0000000 # Contributor Covenant Code of Conduct
## Our Pledge
We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, caste, color, religion, or sexual
identity and orientation.
We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.
## Our Standards
Examples of behavior that contributes to a positive environment for our
community include:
- Demonstrating empathy and kindness toward other people
- Being respectful of differing opinions, viewpoints, and experiences
- Giving and gracefully accepting constructive feedback
- Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
- Focusing on what is best not just for us as individuals, but for the overall
community
Examples of unacceptable behavior include:
- The use of sexualized language or imagery, and sexual attention or advances of
any kind
- Trolling, insulting or derogatory comments, and personal or political attacks
- Public or private harassment
- Publishing others' private information, such as a physical or email address,
without their explicit permission
- Other conduct which could reasonably be considered inappropriate in a
professional setting
## Enforcement Responsibilities
Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.
Community leaders have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.
## Scope
This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official email address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at
[INSERT CONTACT METHOD].
All complaints will be reviewed and investigated promptly and fairly.
All community leaders are obligated to respect the privacy and security of the
reporter of any incident.
## Enforcement Guidelines
Community leaders will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:
### 1. Correction
**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.
**Consequence**: A private, written warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.
### 2. Warning
**Community Impact**: A violation through a single incident or series of
actions.
**Consequence**: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or permanent
ban.
### 3. Temporary Ban
**Community Impact**: A serious violation of community standards, including
sustained inappropriate behavior.
**Consequence**: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.
### 4. Permanent Ban
**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of individuals.
**Consequence**: A permanent ban from any sort of public interaction within the
community.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.1, available at
[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1].
Community Impact Guidelines were inspired by
[Mozilla's code of conduct enforcement ladder][Mozilla CoC].
For answers to common questions about this code of conduct, see the FAQ at
[https://www.contributor-covenant.org/faq][FAQ]. Translations are available at
[https://www.contributor-covenant.org/translations][translations].
[homepage]: https://www.contributor-covenant.org
[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html
[Mozilla CoC]: https://github.com/mozilla/diversity
[FAQ]: https://www.contributor-covenant.org/faq
[translations]: https://www.contributor-covenant.org/translations
ratatui-image-10.0.8/CONTRIBUTING.md 0000644 0000000 0000000 00000002065 10461020230 0014677 0 ustar 0000000 0000000 ### Ensure that tests pass
* `nix flake check`, or `cargo make ci` (somewhat deprecated, but still there for non-nix users).
* I must manually approve CI runs for new PRs to prevent github-action attacks.
### Manually test the demos
* Run the `demo` and `async` examples, verify that everything works (resizing, cycling images...).
* There are no VM tests in place yet, hopefully someday we will have a terminal and OS test matrix.
* I will do a manual verification before merging, but please do not rely on me.
### Small PRs
* Open separate PRs for separate issues.
* It's okay for a PR to depend on another.
* Can merge the other PRs if minor issues are causing long discussions; faster development.
* One commit per PR:
* Squash / amend changes.
* Except for special cases when it is deemed really necessary for some reason.
### No merge commits
* Merge commits are generally not useful or relevant for *reviewing*.
* Use rebase instead.
* Better history.
### Code of Conduct
By participating, you agree to follow our [Code of Conduct](CODE_OF_CONDUCT.md).
ratatui-image-10.0.8/Cargo.lock 0000644 00000242150 10461020230 0011654 0 ustar # This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "addr2line"
version = "0.25.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b5d307320b3181d6d7954e663bd7c774a838b8220fe0593c86d9fb09f498b4b"
dependencies = [
"gimli",
]
[[package]]
name = "adler2"
version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa"
[[package]]
name = "aho-corasick"
version = "1.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301"
dependencies = [
"memchr",
]
[[package]]
name = "aligned"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee4508988c62edf04abd8d92897fca0c2995d907ce1dfeaf369dac3716a40685"
dependencies = [
"as-slice",
]
[[package]]
name = "aligned-vec"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc890384c8602f339876ded803c97ad529f3842aba97f6392b3dba0dd171769b"
dependencies = [
"equator",
]
[[package]]
name = "allocator-api2"
version = "0.2.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923"
[[package]]
name = "anes"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299"
[[package]]
name = "anstyle"
version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000"
[[package]]
name = "anyhow"
version = "1.0.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61"
[[package]]
name = "arbitrary"
version = "1.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3d036a3c4ab069c7b410a2ce876bd74808d2d0888a82667669f8e783a898bf1"
[[package]]
name = "arg_enum_proc_macro"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ae92a5119aa49cdbcf6b9f893fe4e1d98b04ccbf82ee0584ad948a44a734dea"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.111",
]
[[package]]
name = "arrayvec"
version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50"
[[package]]
name = "as-slice"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "516b6b4f0e40d50dcda9365d53964ec74560ad4284da2e7fc97122cd83174516"
dependencies = [
"stable_deref_trait",
]
[[package]]
name = "atomic"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a89cbf775b137e9b968e67227ef7f775587cde3fd31b0d8599dbd0f598a48340"
dependencies = [
"bytemuck",
]
[[package]]
name = "autocfg"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
[[package]]
name = "av-scenechange"
version = "0.14.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0f321d77c20e19b92c39e7471cf986812cbb46659d2af674adc4331ef3f18394"
dependencies = [
"aligned",
"anyhow",
"arg_enum_proc_macro",
"arrayvec",
"log",
"num-rational",
"num-traits",
"pastey",
"rayon",
"thiserror 2.0.17",
"v_frame",
"y4m",
]
[[package]]
name = "av1-grain"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8cfddb07216410377231960af4fcab838eaa12e013417781b78bd95ee22077f8"
dependencies = [
"anyhow",
"arrayvec",
"log",
"nom 8.0.0",
"num-rational",
"v_frame",
]
[[package]]
name = "avif-serialize"
version = "0.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "47c8fbc0f831f4519fe8b810b6a7a91410ec83031b8233f730a0480029f6a23f"
dependencies = [
"arrayvec",
]
[[package]]
name = "backtrace"
version = "0.3.76"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bb531853791a215d7c62a30daf0dde835f381ab5de4589cfe7c649d2cbe92bd6"
dependencies = [
"addr2line",
"cfg-if",
"libc",
"miniz_oxide",
"object",
"rustc-demangle",
"windows-link",
]
[[package]]
name = "base64"
version = "0.22.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
[[package]]
name = "base64-simd"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "339abbe78e73178762e23bea9dfd08e697eb3f3301cd4be981c0f78ba5859195"
dependencies = [
"outref",
"vsimd",
]
[[package]]
name = "bit-set"
version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1"
dependencies = [
"bit-vec",
]
[[package]]
name = "bit-vec"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb"
[[package]]
name = "bit_field"
version = "0.10.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e4b40c7323adcfc0a41c4b88143ed58346ff65a288fc144329c5c45e05d70c6"
[[package]]
name = "bitflags"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bitflags"
version = "2.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3"
[[package]]
name = "bitstream-io"
version = "4.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "60d4bd9d1db2c6bdf285e223a7fa369d5ce98ec767dec949c6ca62863ce61757"
dependencies = [
"core2",
]
[[package]]
name = "bitvec"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c"
dependencies = [
"funty",
"radium",
"tap",
"wyz",
]
[[package]]
name = "block-buffer"
version = "0.10.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
dependencies = [
"generic-array",
]
[[package]]
name = "built"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f4ad8f11f288f48ca24471bbd51ac257aaeaaa07adae295591266b792902ae64"
[[package]]
name = "bumpalo"
version = "3.19.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510"
[[package]]
name = "by_address"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "64fa3c856b712db6612c019f14756e64e4bcea13337a6b33b696333a9eaa2d06"
[[package]]
name = "bytemuck"
version = "1.24.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fbdf580320f38b612e485521afda1ee26d10cc9884efaaa750d383e13e3c5f4"
dependencies = [
"bytemuck_derive",
]
[[package]]
name = "bytemuck_derive"
version = "1.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f9abbd1bc6865053c427f7198e6af43bfdedc55ab791faed4fbd361d789575ff"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.111",
]
[[package]]
name = "byteorder-lite"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495"
[[package]]
name = "cast"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5"
[[package]]
name = "castaway"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dec551ab6e7578819132c713a93c022a05d60159dc86e7a7050223577484c55a"
dependencies = [
"rustversion",
]
[[package]]
name = "cc"
version = "1.2.49"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90583009037521a116abf44494efecd645ba48b6622457080f080b85544e2215"
dependencies = [
"find-msvc-tools",
"jobserver",
"libc",
"shlex",
]
[[package]]
name = "cfg-if"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
[[package]]
name = "cfg_aliases"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
[[package]]
name = "ciborium"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42e69ffd6f0917f5c029256a24d0161db17cea3997d185db0d35926308770f0e"
dependencies = [
"ciborium-io",
"ciborium-ll",
"serde",
]
[[package]]
name = "ciborium-io"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05afea1e0a06c9be33d539b876f1ce3692f4afea2cb41f740e7743225ed1c757"
[[package]]
name = "ciborium-ll"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9"
dependencies = [
"ciborium-io",
"half",
]
[[package]]
name = "clap"
version = "4.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b193af5b67834b676abd72466a96c1024e6a6ad978a1f484bd90b85c94041351"
dependencies = [
"clap_builder",
]
[[package]]
name = "clap_builder"
version = "4.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "714a53001bf66416adb0e2ef5ac857140e7dc3a0c48fb28b2f10762fc4b5069f"
dependencies = [
"anstyle",
"clap_lex",
]
[[package]]
name = "clap_lex"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9"
[[package]]
name = "color-eyre"
version = "0.6.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5920befb47832a6d61ee3a3a846565cfa39b331331e68a3b1d1116630f2f26d"
dependencies = [
"backtrace",
"color-spantrace",
"eyre",
"indenter",
"once_cell",
"owo-colors",
"tracing-error",
]
[[package]]
name = "color-spantrace"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8b88ea9df13354b55bc7234ebcce36e6ef896aca2e42a15de9e10edce01b427"
dependencies = [
"once_cell",
"owo-colors",
"tracing-core",
"tracing-error",
]
[[package]]
name = "color_quant"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b"
[[package]]
name = "compact_str"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3fdb1325a1cece981e8a296ab8f0f9b63ae357bd0784a9faaf548cc7b480707a"
dependencies = [
"castaway",
"cfg-if",
"itoa",
"rustversion",
"ryu",
"static_assertions",
]
[[package]]
name = "console"
version = "0.15.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "054ccb5b10f9f2cbf51eb355ca1d05c2d279ce1804688d0db74b4733a5aeafd8"
dependencies = [
"encode_unicode",
"libc",
"once_cell",
"windows-sys 0.59.0",
]
[[package]]
name = "convert_case"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "633458d4ef8c78b72454de2d54fd6ab2e60f9e02be22f3c6104cdc8a4e0fceb9"
dependencies = [
"unicode-segmentation",
]
[[package]]
name = "core2"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b49ba7ef1ad6107f8824dbe97de947cbaac53c44e7f9756a1fba0d37c1eec505"
dependencies = [
"memchr",
]
[[package]]
name = "cpufeatures"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280"
dependencies = [
"libc",
]
[[package]]
name = "crc32fast"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511"
dependencies = [
"cfg-if",
]
[[package]]
name = "criterion"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2b12d017a929603d80db1831cd3a24082f8137ce19c69e6447f54f5fc8d692f"
dependencies = [
"anes",
"cast",
"ciborium",
"clap",
"criterion-plot",
"is-terminal",
"itertools 0.10.5",
"num-traits",
"once_cell",
"oorandom",
"plotters",
"rayon",
"regex",
"serde",
"serde_derive",
"serde_json",
"tinytemplate",
"walkdir",
]
[[package]]
name = "criterion-plot"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6b50826342786a51a89e2da3a28f1c32b06e387201bc2d19791f622c673706b1"
dependencies = [
"cast",
"itertools 0.10.5",
]
[[package]]
name = "crossbeam-deque"
version = "0.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51"
dependencies = [
"crossbeam-epoch",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-epoch"
version = "0.9.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e"
dependencies = [
"crossbeam-utils",
]
[[package]]
name = "crossbeam-utils"
version = "0.8.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
[[package]]
name = "crossterm"
version = "0.29.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d8b9f2e4c67f833b660cdb0a3523065869fb35570177239812ed4c905aeff87b"
dependencies = [
"bitflags 2.10.0",
"crossterm_winapi",
"derive_more",
"document-features",
"futures-core",
"mio",
"parking_lot",
"rustix 1.1.2",
"signal-hook",
"signal-hook-mio",
"winapi",
]
[[package]]
name = "crossterm_winapi"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b"
dependencies = [
"winapi",
]
[[package]]
name = "crunchy"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5"
[[package]]
name = "crypto-common"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a"
dependencies = [
"generic-array",
"typenum",
]
[[package]]
name = "csscolorparser"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eb2a7d3066da2de787b7f032c736763eb7ae5d355f81a68bab2675a96008b0bf"
dependencies = [
"lab",
"phf",
]
[[package]]
name = "darling"
version = "0.20.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee"
dependencies = [
"darling_core",
"darling_macro",
]
[[package]]
name = "darling_core"
version = "0.20.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e"
dependencies = [
"fnv",
"ident_case",
"proc-macro2",
"quote",
"strsim",
"syn 2.0.111",
]
[[package]]
name = "darling_macro"
version = "0.20.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead"
dependencies = [
"darling_core",
"quote",
"syn 2.0.111",
]
[[package]]
name = "deltae"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5729f5117e208430e437df2f4843f5e5952997175992d1414f94c57d61e270b4"
[[package]]
name = "deranged"
version = "0.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ececcb659e7ba858fb4f10388c250a7252eb0a27373f1a72b8748afdd248e587"
dependencies = [
"powerfmt",
]
[[package]]
name = "derive_more"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "10b768e943bed7bf2cab53df09f4bc34bfd217cdb57d971e769874c9a6710618"
dependencies = [
"derive_more-impl",
]
[[package]]
name = "derive_more-impl"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d286bfdaf75e988b4a78e013ecd79c581e06399ab53fbacd2d916c2f904f30b"
dependencies = [
"convert_case",
"proc-macro2",
"quote",
"rustc_version",
"syn 2.0.111",
]
[[package]]
name = "digest"
version = "0.10.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
dependencies = [
"block-buffer",
"crypto-common",
]
[[package]]
name = "document-features"
version = "0.2.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4b8a88685455ed29a21542a33abd9cb6510b6b129abadabdcef0f4c55bc8f61"
dependencies = [
"litrs",
]
[[package]]
name = "either"
version = "1.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
[[package]]
name = "encode_unicode"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0"
[[package]]
name = "equator"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4711b213838dfee0117e3be6ac926007d7f433d7bbe33595975d4190cb07e6fc"
dependencies = [
"equator-macro",
]
[[package]]
name = "equator-macro"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "44f23cf4b44bfce11a86ace86f8a73ffdec849c9fd00a386a53d278bd9e81fb3"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.111",
]
[[package]]
name = "equivalent"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
[[package]]
name = "errno"
version = "0.3.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
dependencies = [
"libc",
"windows-sys 0.61.2",
]
[[package]]
name = "euclid"
version = "0.22.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ad9cdb4b747e485a12abb0e6566612956c7a1bafa3bdb8d682c5b6d403589e48"
dependencies = [
"num-traits",
]
[[package]]
name = "exr"
version = "1.74.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4300e043a56aa2cb633c01af81ca8f699a321879a7854d3896a0ba89056363be"
dependencies = [
"bit_field",
"half",
"lebe",
"miniz_oxide",
"rayon-core",
"smallvec",
"zune-inflate",
]
[[package]]
name = "eyre"
version = "0.6.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec"
dependencies = [
"indenter",
"once_cell",
]
[[package]]
name = "fancy-regex"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b95f7c0680e4142284cf8b22c14a476e87d61b004a3a0861872b32ef7ead40a2"
dependencies = [
"bit-set",
"regex",
]
[[package]]
name = "fast-srgb8"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd2e7510819d6fbf51a5545c8f922716ecfb14df168a3242f7d33e0239efe6a1"
[[package]]
name = "fax"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f05de7d48f37cd6730705cbca900770cab77a89f413d23e100ad7fad7795a0ab"
dependencies = [
"fax_derive",
]
[[package]]
name = "fax_derive"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a0aca10fb742cb43f9e7bb8467c91aa9bcb8e3ffbc6a6f7389bb93ffc920577d"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.111",
]
[[package]]
name = "fdeflate"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e6853b52649d4ac5c0bd02320cddc5ba956bdb407c4b75a2c6b75bf51500f8c"
dependencies = [
"simd-adler32",
]
[[package]]
name = "filedescriptor"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e40758ed24c9b2eeb76c35fb0aebc66c626084edd827e07e1552279814c6682d"
dependencies = [
"libc",
"thiserror 1.0.69",
"winapi",
]
[[package]]
name = "find-msvc-tools"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3a3076410a55c90011c298b04d0cfa770b00fa04e1e3c97d3f6c9de105a03844"
[[package]]
name = "finl_unicode"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9844ddc3a6e533d62bba727eb6c28b5d360921d5175e9ff0f1e621a5c590a4d5"
[[package]]
name = "fixedbitset"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80"
[[package]]
name = "flate2"
version = "1.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bfe33edd8e85a12a67454e37f8c75e730830d83e313556ab9ebf9ee7fbeb3bfb"
dependencies = [
"crc32fast",
"miniz_oxide",
]
[[package]]
name = "fnv"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
[[package]]
name = "foldhash"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb"
[[package]]
name = "funty"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c"
[[package]]
name = "futures"
version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876"
dependencies = [
"futures-channel",
"futures-core",
"futures-executor",
"futures-io",
"futures-sink",
"futures-task",
"futures-util",
]
[[package]]
name = "futures-channel"
version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10"
dependencies = [
"futures-core",
"futures-sink",
]
[[package]]
name = "futures-core"
version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e"
[[package]]
name = "futures-executor"
version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f"
dependencies = [
"futures-core",
"futures-task",
"futures-util",
]
[[package]]
name = "futures-io"
version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6"
[[package]]
name = "futures-macro"
version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.111",
]
[[package]]
name = "futures-sink"
version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7"
[[package]]
name = "futures-task"
version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988"
[[package]]
name = "futures-util"
version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81"
dependencies = [
"futures-channel",
"futures-core",
"futures-io",
"futures-macro",
"futures-sink",
"futures-task",
"memchr",
"pin-project-lite",
"pin-utils",
"slab",
]
[[package]]
name = "generic-array"
version = "0.14.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
dependencies = [
"typenum",
"version_check",
]
[[package]]
name = "getrandom"
version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592"
dependencies = [
"cfg-if",
"libc",
"wasi",
]
[[package]]
name = "getrandom"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd"
dependencies = [
"cfg-if",
"libc",
"r-efi",
"wasip2",
]
[[package]]
name = "gif"
version = "0.14.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f5df2ba84018d80c213569363bdcd0c64e6933c67fe4c1d60ecf822971a3c35e"
dependencies = [
"color_quant",
"weezl",
]
[[package]]
name = "gimli"
version = "0.32.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7"
[[package]]
name = "half"
version = "2.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b"
dependencies = [
"cfg-if",
"crunchy",
"zerocopy",
]
[[package]]
name = "hashbrown"
version = "0.16.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100"
dependencies = [
"allocator-api2",
"equivalent",
"foldhash",
]
[[package]]
name = "heck"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
[[package]]
name = "hermit-abi"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c"
[[package]]
name = "hex"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
[[package]]
name = "icy_sixel"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85518b9086bf01117761b90e7691c0ef3236fa8adfb1fb44dd248fe5f87215d5"
dependencies = [
"quantette",
"thiserror 2.0.17",
]
[[package]]
name = "ident_case"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
[[package]]
name = "image"
version = "0.25.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6506c6c10786659413faa717ceebcb8f70731c0a60cbae39795fdf114519c1a"
dependencies = [
"bytemuck",
"byteorder-lite",
"color_quant",
"exr",
"gif",
"image-webp",
"moxcms",
"num-traits",
"png",
"qoi",
"ravif",
"rayon",
"rgb",
"tiff",
"zune-core 0.5.0",
"zune-jpeg 0.5.7",
]
[[package]]
name = "image-webp"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "525e9ff3e1a4be2fbea1fdf0e98686a6d98b4d8f937e1bf7402245af1909e8c3"
dependencies = [
"byteorder-lite",
"quick-error",
]
[[package]]
name = "imgref"
version = "1.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e7c5cedc30da3a610cac6b4ba17597bdf7152cf974e8aab3afb3d54455e371c8"
[[package]]
name = "indenter"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "964de6e86d545b246d84badc0fef527924ace5134f30641c203ef52ba83f58d5"
[[package]]
name = "indoc"
version = "2.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "79cf5c93f93228cf8efb3ba362535fb11199ac548a09ce117c9b1adc3030d706"
dependencies = [
"rustversion",
]
[[package]]
name = "insta"
version = "1.44.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5c943d4415edd8153251b6f197de5eb1640e56d84e8d9159bea190421c73698"
dependencies = [
"console",
"once_cell",
"similar",
]
[[package]]
name = "instability"
version = "0.3.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6778b0196eefee7df739db78758e5cf9b37412268bfa5650bfeed028aed20d9c"
dependencies = [
"darling",
"indoc",
"proc-macro2",
"quote",
"syn 2.0.111",
]
[[package]]
name = "interpolate_name"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c34819042dc3d3971c46c2190835914dfbe0c3c13f61449b2997f4e9722dfa60"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.111",
]
[[package]]
name = "is-terminal"
version = "0.4.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3640c1c38b8e4e43584d8df18be5fc6b0aa314ce6ebf51b53313d4306cca8e46"
dependencies = [
"hermit-abi",
"libc",
"windows-sys 0.61.2",
]
[[package]]
name = "itertools"
version = "0.10.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473"
dependencies = [
"either",
]
[[package]]
name = "itertools"
version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186"
dependencies = [
"either",
]
[[package]]
name = "itertools"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285"
dependencies = [
"either",
]
[[package]]
name = "itoa"
version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
[[package]]
name = "jobserver"
version = "0.1.34"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33"
dependencies = [
"getrandom 0.3.4",
"libc",
]
[[package]]
name = "js-sys"
version = "0.3.83"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "464a3709c7f55f1f721e5389aa6ea4e3bc6aba669353300af094b29ffbdde1d8"
dependencies = [
"once_cell",
"wasm-bindgen",
]
[[package]]
name = "kasuari"
version = "0.4.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8fe90c1150662e858c7d5f945089b7517b0a80d8bf7ba4b1b5ffc984e7230a5b"
dependencies = [
"hashbrown",
"portable-atomic",
"thiserror 2.0.17",
]
[[package]]
name = "lab"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bf36173d4167ed999940f804952e6b08197cae5ad5d572eb4db150ce8ad5d58f"
[[package]]
name = "lazy_static"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
[[package]]
name = "lebe"
version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a79a3332a6609480d7d0c9eab957bca6b455b91bb84e66d19f5ff66294b85b8"
[[package]]
name = "libc"
version = "0.2.178"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37c93d8daa9d8a012fd8ab92f088405fb202ea0b6ab73ee2482ae66af4f42091"
[[package]]
name = "libfuzzer-sys"
version = "0.4.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5037190e1f70cbeef565bd267599242926f724d3b8a9f510fd7e0b540cfa4404"
dependencies = [
"arbitrary",
"cc",
]
[[package]]
name = "libm"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de"
[[package]]
name = "line-clipping"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f4de44e98ddbf09375cbf4d17714d18f39195f4f4894e8524501726fd9a8a4a"
dependencies = [
"bitflags 2.10.0",
]
[[package]]
name = "linux-raw-sys"
version = "0.4.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab"
[[package]]
name = "linux-raw-sys"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039"
[[package]]
name = "litrs"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "11d3d7f243d5c5a8b9bb5d6dd2b1602c0cb0b9db1621bafc7ed66e35ff9fe092"
[[package]]
name = "lock_api"
version = "0.4.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965"
dependencies = [
"scopeguard",
]
[[package]]
name = "log"
version = "0.4.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897"
[[package]]
name = "loop9"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fae87c125b03c1d2c0150c90365d7d6bcc53fb73a9acaef207d2d065860f062"
dependencies = [
"imgref",
]
[[package]]
name = "lru"
version = "0.16.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96051b46fc183dc9cd4a223960ef37b9af631b55191852a8274bfef064cda20f"
dependencies = [
"hashbrown",
]
[[package]]
name = "mac_address"
version = "1.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0aeb26bf5e836cc1c341c8106051b573f1766dfa05aa87f0b98be5e51b02303"
dependencies = [
"nix",
"winapi",
]
[[package]]
name = "maybe-rayon"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ea1f30cedd69f0a2954655f7188c6a834246d2bcf1e315e2ac40c4b24dc9519"
dependencies = [
"cfg-if",
"rayon",
]
[[package]]
name = "memchr"
version = "2.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273"
[[package]]
name = "memmem"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a64a92489e2744ce060c349162be1c5f33c6969234104dbd99ddb5feb08b8c15"
[[package]]
name = "memoffset"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a"
dependencies = [
"autocfg",
]
[[package]]
name = "minimal-lexical"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
[[package]]
name = "miniz_oxide"
version = "0.8.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316"
dependencies = [
"adler2",
"simd-adler32",
]
[[package]]
name = "mio"
version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a69bcab0ad47271a0234d9422b131806bf3968021e5dc9328caf2d4cd58557fc"
dependencies = [
"libc",
"log",
"wasi",
"windows-sys 0.61.2",
]
[[package]]
name = "moxcms"
version = "0.7.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac9557c559cd6fc9867e122e20d2cbefc9ca29d80d027a8e39310920ed2f0a97"
dependencies = [
"num-traits",
"pxfm",
]
[[package]]
name = "new_debug_unreachable"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086"
[[package]]
name = "nix"
version = "0.29.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46"
dependencies = [
"bitflags 2.10.0",
"cfg-if",
"cfg_aliases",
"libc",
"memoffset",
]
[[package]]
name = "nom"
version = "7.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
dependencies = [
"memchr",
"minimal-lexical",
]
[[package]]
name = "nom"
version = "8.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df9761775871bdef83bee530e60050f7e54b1105350d6884eb0fb4f46c2f9405"
dependencies = [
"memchr",
]
[[package]]
name = "noop_proc_macro"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0676bb32a98c1a483ce53e500a81ad9c3d5b3f7c920c28c24e9cb0980d0b5bc8"
[[package]]
name = "num-bigint"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9"
dependencies = [
"num-integer",
"num-traits",
]
[[package]]
name = "num-conv"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9"
[[package]]
name = "num-derive"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.111",
]
[[package]]
name = "num-integer"
version = "0.1.46"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f"
dependencies = [
"num-traits",
]
[[package]]
name = "num-rational"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824"
dependencies = [
"num-bigint",
"num-integer",
"num-traits",
]
[[package]]
name = "num-traits"
version = "0.2.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
dependencies = [
"autocfg",
"libm",
]
[[package]]
name = "num_threads"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9"
dependencies = [
"libc",
]
[[package]]
name = "numtoa"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6aa2c4e539b869820a2b82e1aef6ff40aa85e65decdd5185e83fb4b1249cd00f"
[[package]]
name = "object"
version = "0.37.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ff76201f031d8863c38aa7f905eca4f53abbfa15f609db4277d44cd8938f33fe"
dependencies = [
"memchr",
]
[[package]]
name = "once_cell"
version = "1.21.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
[[package]]
name = "oorandom"
version = "11.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d6790f58c7ff633d8771f42965289203411a5e5c68388703c06e14f24770b41e"
[[package]]
name = "ordered-float"
version = "4.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7bb71e1b3fa6ca1c61f383464aaf2bb0e2f8e772a1f01d486832464de363b951"
dependencies = [
"num-traits",
]
[[package]]
name = "ordered-float"
version = "5.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f4779c6901a562440c3786d08192c6fbda7c1c2060edd10006b05ee35d10f2d"
dependencies = [
"num-traits",
]
[[package]]
name = "outref"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a80800c0488c3a21695ea981a54918fbb37abf04f4d0720c453632255e2ff0e"
[[package]]
name = "owo-colors"
version = "4.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c6901729fa79e91a0913333229e9ca5dc725089d1c363b2f4b4760709dc4a52"
[[package]]
name = "palette"
version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4cbf71184cc5ecc2e4e1baccdb21026c20e5fc3dcf63028a086131b3ab00b6e6"
dependencies = [
"bytemuck",
"fast-srgb8",
"libm",
"palette_derive",
]
[[package]]
name = "palette_derive"
version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f5030daf005bface118c096f510ffb781fc28f9ab6a32ab224d8631be6851d30"
dependencies = [
"by_address",
"proc-macro2",
"quote",
"syn 2.0.111",
]
[[package]]
name = "parking_lot"
version = "0.12.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a"
dependencies = [
"lock_api",
"parking_lot_core",
]
[[package]]
name = "parking_lot_core"
version = "0.9.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1"
dependencies = [
"cfg-if",
"libc",
"redox_syscall",
"smallvec",
"windows-link",
]
[[package]]
name = "paste"
version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
[[package]]
name = "pastey"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "35fb2e5f958ec131621fdd531e9fc186ed768cbe395337403ae56c17a74c68ec"
[[package]]
name = "pest"
version = "2.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cbcfd20a6d4eeba40179f05735784ad32bdaef05ce8e8af05f180d45bb3e7e22"
dependencies = [
"memchr",
"ucd-trie",
]
[[package]]
name = "pest_derive"
version = "2.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "51f72981ade67b1ca6adc26ec221be9f463f2b5839c7508998daa17c23d94d7f"
dependencies = [
"pest",
"pest_generator",
]
[[package]]
name = "pest_generator"
version = "2.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dee9efd8cdb50d719a80088b76f81aec7c41ed6d522ee750178f83883d271625"
dependencies = [
"pest",
"pest_meta",
"proc-macro2",
"quote",
"syn 2.0.111",
]
[[package]]
name = "pest_meta"
version = "2.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bf1d70880e76bdc13ba52eafa6239ce793d85c8e43896507e43dd8984ff05b82"
dependencies = [
"pest",
"sha2",
]
[[package]]
name = "phf"
version = "0.11.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078"
dependencies = [
"phf_macros",
"phf_shared",
]
[[package]]
name = "phf_codegen"
version = "0.11.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aef8048c789fa5e851558d709946d6d79a8ff88c0440c587967f8e94bfb1216a"
dependencies = [
"phf_generator",
"phf_shared",
]
[[package]]
name = "phf_generator"
version = "0.11.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d"
dependencies = [
"phf_shared",
"rand 0.8.5",
]
[[package]]
name = "phf_macros"
version = "0.11.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f84ac04429c13a7ff43785d75ad27569f2951ce0ffd30a3321230db2fc727216"
dependencies = [
"phf_generator",
"phf_shared",
"proc-macro2",
"quote",
"syn 2.0.111",
]
[[package]]
name = "phf_shared"
version = "0.11.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5"
dependencies = [
"siphasher",
]
[[package]]
name = "pin-project-lite"
version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b"
[[package]]
name = "pin-utils"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
[[package]]
name = "pkg-config"
version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c"
[[package]]
name = "plotters"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5aeb6f403d7a4911efb1e33402027fc44f29b5bf6def3effcc22d7bb75f2b747"
dependencies = [
"num-traits",
"plotters-backend",
"plotters-svg",
"wasm-bindgen",
"web-sys",
]
[[package]]
name = "plotters-backend"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df42e13c12958a16b3f7f4386b9ab1f3e7933914ecea48da7139435263a4172a"
[[package]]
name = "plotters-svg"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "51bae2ac328883f7acdfea3d66a7c35751187f870bc81f94563733a154d7a670"
dependencies = [
"plotters-backend",
]
[[package]]
name = "png"
version = "0.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97baced388464909d42d89643fe4361939af9b7ce7a31ee32a168f832a70f2a0"
dependencies = [
"bitflags 2.10.0",
"crc32fast",
"fdeflate",
"flate2",
"miniz_oxide",
]
[[package]]
name = "portable-atomic"
version = "1.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f89776e4d69bb58bc6993e99ffa1d11f228b839984854c7daeb5d37f87cbe950"
[[package]]
name = "powerfmt"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
[[package]]
name = "ppv-lite86"
version = "0.2.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9"
dependencies = [
"zerocopy",
]
[[package]]
name = "proc-macro2"
version = "1.0.103"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8"
dependencies = [
"unicode-ident",
]
[[package]]
name = "profiling"
version = "1.0.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3eb8486b569e12e2c32ad3e204dbaba5e4b5b216e9367044f25f1dba42341773"
dependencies = [
"profiling-procmacros",
]
[[package]]
name = "profiling-procmacros"
version = "1.0.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "52717f9a02b6965224f95ca2a81e2e0c5c43baacd28ca057577988930b6c3d5b"
dependencies = [
"quote",
"syn 2.0.111",
]
[[package]]
name = "pxfm"
version = "0.1.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7186d3822593aa4393561d186d1393b3923e9d6163d3fbfd6e825e3e6cf3e6a8"
dependencies = [
"num-traits",
]
[[package]]
name = "qoi"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f6d64c71eb498fe9eae14ce4ec935c555749aef511cca85b5568910d6e48001"
dependencies = [
"bytemuck",
]
[[package]]
name = "quantette"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c98fecda8b16396ff9adac67644a523dd1778c42b58606a29df5c31ca925d174"
dependencies = [
"bitvec",
"bytemuck",
"image",
"libm",
"num-traits",
"ordered-float 5.1.0",
"palette",
"rand 0.9.2",
"rand_xoshiro",
"rayon",
"ref-cast",
"wide",
]
[[package]]
name = "quick-error"
version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3"
[[package]]
name = "quote"
version = "1.0.42"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a338cc41d27e6cc6dce6cefc13a0729dfbb81c262b1f519331575dd80ef3067f"
dependencies = [
"proc-macro2",
]
[[package]]
name = "r-efi"
version = "5.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
[[package]]
name = "radium"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09"
[[package]]
name = "rand"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
dependencies = [
"libc",
"rand_chacha 0.3.1",
"rand_core 0.6.4",
]
[[package]]
name = "rand"
version = "0.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1"
dependencies = [
"rand_chacha 0.9.0",
"rand_core 0.9.3",
]
[[package]]
name = "rand_chacha"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
dependencies = [
"ppv-lite86",
"rand_core 0.6.4",
]
[[package]]
name = "rand_chacha"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"
dependencies = [
"ppv-lite86",
"rand_core 0.9.3",
]
[[package]]
name = "rand_core"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
dependencies = [
"getrandom 0.2.16",
]
[[package]]
name = "rand_core"
version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38"
dependencies = [
"getrandom 0.3.4",
]
[[package]]
name = "rand_xoshiro"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f703f4665700daf5512dcca5f43afa6af89f09db47fb56be587f80636bda2d41"
dependencies = [
"rand_core 0.9.3",
]
[[package]]
name = "ratatui"
version = "0.30.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d1ce67fb8ba4446454d1c8dbaeda0557ff5e94d39d5e5ed7f10a65eb4c8266bc"
dependencies = [
"instability",
"ratatui-core",
"ratatui-crossterm",
"ratatui-termion",
"ratatui-termwiz",
"ratatui-widgets",
]
[[package]]
name = "ratatui-core"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ef8dea09a92caaf73bff7adb70b76162e5937524058a7e5bff37869cbbec293"
dependencies = [
"bitflags 2.10.0",
"compact_str",
"hashbrown",
"indoc",
"itertools 0.14.0",
"kasuari",
"lru",
"strum",
"thiserror 2.0.17",
"unicode-segmentation",
"unicode-truncate",
"unicode-width",
]
[[package]]
name = "ratatui-crossterm"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "577c9b9f652b4c121fb25c6a391dd06406d3b092ba68827e6d2f09550edc54b3"
dependencies = [
"cfg-if",
"crossterm",
"instability",
"ratatui-core",
]
[[package]]
name = "ratatui-image"
version = "10.0.8"
dependencies = [
"base64-simd",
"color-eyre",
"criterion",
"crossterm",
"futures",
"icy_sixel",
"image",
"insta",
"pkg-config",
"rand 0.8.5",
"ratatui",
"rustix 0.38.44",
"serde",
"thiserror 1.0.69",
"tokio",
"windows",
]
[[package]]
name = "ratatui-termion"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4cade85a8591fbc911e147951422f0d6fd40f4948b271b6216c7dc01838996f8"
dependencies = [
"instability",
"ratatui-core",
"termion",
]
[[package]]
name = "ratatui-termwiz"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0f76fe0bd0ed4295f0321b1676732e2454024c15a35d01904ddb315afd3d545c"
dependencies = [
"ratatui-core",
"termwiz",
]
[[package]]
name = "ratatui-widgets"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d7dbfa023cd4e604c2553483820c5fe8aa9d71a42eea5aa77c6e7f35756612db"
dependencies = [
"bitflags 2.10.0",
"hashbrown",
"indoc",
"instability",
"itertools 0.14.0",
"line-clipping",
"ratatui-core",
"strum",
"time",
"unicode-segmentation",
"unicode-width",
]
[[package]]
name = "rav1e"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43b6dd56e85d9483277cde964fd1bdb0428de4fec5ebba7540995639a21cb32b"
dependencies = [
"aligned-vec",
"arbitrary",
"arg_enum_proc_macro",
"arrayvec",
"av-scenechange",
"av1-grain",
"bitstream-io",
"built",
"cfg-if",
"interpolate_name",
"itertools 0.14.0",
"libc",
"libfuzzer-sys",
"log",
"maybe-rayon",
"new_debug_unreachable",
"noop_proc_macro",
"num-derive",
"num-traits",
"paste",
"profiling",
"rand 0.9.2",
"rand_chacha 0.9.0",
"simd_helpers",
"thiserror 2.0.17",
"v_frame",
"wasm-bindgen",
]
[[package]]
name = "ravif"
version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef69c1990ceef18a116855938e74793a5f7496ee907562bd0857b6ac734ab285"
dependencies = [
"avif-serialize",
"imgref",
"loop9",
"quick-error",
"rav1e",
"rayon",
"rgb",
]
[[package]]
name = "rayon"
version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "368f01d005bf8fd9b1206fb6fa653e6c4a81ceb1466406b81792d87c5677a58f"
dependencies = [
"either",
"rayon-core",
]
[[package]]
name = "rayon-core"
version = "1.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91"
dependencies = [
"crossbeam-deque",
"crossbeam-utils",
]
[[package]]
name = "redox_syscall"
version = "0.5.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d"
dependencies = [
"bitflags 2.10.0",
]
[[package]]
name = "ref-cast"
version = "1.0.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f354300ae66f76f1c85c5f84693f0ce81d747e2c3f21a45fef496d89c960bf7d"
dependencies = [
"ref-cast-impl",
]
[[package]]
name = "ref-cast-impl"
version = "1.0.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.111",
]
[[package]]
name = "regex"
version = "1.12.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4"
dependencies = [
"aho-corasick",
"memchr",
"regex-automata",
"regex-syntax",
]
[[package]]
name = "regex-automata"
version = "0.4.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.8.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58"
[[package]]
name = "rgb"
version = "0.8.52"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c6a884d2998352bb4daf0183589aec883f16a6da1f4dde84d8e2e9a5409a1ce"
[[package]]
name = "rustc-demangle"
version = "0.1.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace"
[[package]]
name = "rustc_version"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92"
dependencies = [
"semver",
]
[[package]]
name = "rustix"
version = "0.38.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154"
dependencies = [
"bitflags 2.10.0",
"errno",
"libc",
"linux-raw-sys 0.4.15",
"windows-sys 0.59.0",
]
[[package]]
name = "rustix"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e"
dependencies = [
"bitflags 2.10.0",
"errno",
"libc",
"linux-raw-sys 0.11.0",
"windows-sys 0.61.2",
]
[[package]]
name = "rustversion"
version = "1.0.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
[[package]]
name = "ryu"
version = "1.0.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
[[package]]
name = "safe_arch"
version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "629516c85c29fe757770fa03f2074cf1eac43d44c02a3de9fc2ef7b0e207dfdd"
dependencies = [
"bytemuck",
]
[[package]]
name = "same-file"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
dependencies = [
"winapi-util",
]
[[package]]
name = "scopeguard"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]]
name = "semver"
version = "1.0.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2"
[[package]]
name = "serde"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
dependencies = [
"serde_core",
"serde_derive",
]
[[package]]
name = "serde_core"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.111",
]
[[package]]
name = "serde_json"
version = "1.0.149"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86"
dependencies = [
"itoa",
"memchr",
"serde",
"serde_core",
"zmij",
]
[[package]]
name = "sha2"
version = "0.10.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283"
dependencies = [
"cfg-if",
"cpufeatures",
"digest",
]
[[package]]
name = "sharded-slab"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6"
dependencies = [
"lazy_static",
]
[[package]]
name = "shlex"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
[[package]]
name = "signal-hook"
version = "0.3.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d881a16cf4426aa584979d30bd82cb33429027e42122b169753d6ef1085ed6e2"
dependencies = [
"libc",
"signal-hook-registry",
]
[[package]]
name = "signal-hook-mio"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b75a19a7a740b25bc7944bdee6172368f988763b744e3d4dfe753f6b4ece40cc"
dependencies = [
"libc",
"mio",
"signal-hook",
]
[[package]]
name = "signal-hook-registry"
version = "1.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7664a098b8e616bdfcc2dc0e9ac44eb231eedf41db4e9fe95d8d32ec728dedad"
dependencies = [
"libc",
]
[[package]]
name = "simd-adler32"
version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2"
[[package]]
name = "simd_helpers"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95890f873bec569a0362c235787f3aca6e1e887302ba4840839bcc6459c42da6"
dependencies = [
"quote",
]
[[package]]
name = "similar"
version = "2.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbbb5d9659141646ae647b42fe094daf6c6192d1620870b449d9557f748b2daa"
[[package]]
name = "siphasher"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d"
[[package]]
name = "slab"
version = "0.4.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589"
[[package]]
name = "smallvec"
version = "1.15.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
[[package]]
name = "stable_deref_trait"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596"
[[package]]
name = "static_assertions"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
[[package]]
name = "strsim"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
[[package]]
name = "strum"
version = "0.27.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af23d6f6c1a224baef9d3f61e287d2761385a5b88fdab4eb4c6f11aeb54c4bcf"
dependencies = [
"strum_macros",
]
[[package]]
name = "strum_macros"
version = "0.27.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7695ce3845ea4b33927c055a39dc438a45b059f7c1b3d91d38d10355fb8cbca7"
dependencies = [
"heck",
"proc-macro2",
"quote",
"syn 2.0.111",
]
[[package]]
name = "syn"
version = "1.0.109"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "syn"
version = "2.0.111"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "390cc9a294ab71bdb1aa2e99d13be9c753cd2d7bd6560c77118597410c4d2e87"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "tap"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369"
[[package]]
name = "terminfo"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4ea810f0692f9f51b382fff5893887bb4580f5fa246fde546e0b13e7fcee662"
dependencies = [
"fnv",
"nom 7.1.3",
"phf",
"phf_codegen",
]
[[package]]
name = "termion"
version = "4.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f44138a9ae08f0f502f24104d82517ef4da7330c35acd638f1f29d3cd5475ecb"
dependencies = [
"libc",
"numtoa",
]
[[package]]
name = "termios"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "411c5bf740737c7918b8b1fe232dca4dc9f8e754b8ad5e20966814001ed0ac6b"
dependencies = [
"libc",
]
[[package]]
name = "termwiz"
version = "0.23.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4676b37242ccbd1aabf56edb093a4827dc49086c0ffd764a5705899e0f35f8f7"
dependencies = [
"anyhow",
"base64",
"bitflags 2.10.0",
"fancy-regex",
"filedescriptor",
"finl_unicode",
"fixedbitset",
"hex",
"lazy_static",
"libc",
"log",
"memmem",
"nix",
"num-derive",
"num-traits",
"ordered-float 4.6.0",
"pest",
"pest_derive",
"phf",
"sha2",
"signal-hook",
"siphasher",
"terminfo",
"termios",
"thiserror 1.0.69",
"ucd-trie",
"unicode-segmentation",
"vtparse",
"wezterm-bidi",
"wezterm-blob-leases",
"wezterm-color-types",
"wezterm-dynamic",
"wezterm-input-types",
"winapi",
]
[[package]]
name = "thiserror"
version = "1.0.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
dependencies = [
"thiserror-impl 1.0.69",
]
[[package]]
name = "thiserror"
version = "2.0.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8"
dependencies = [
"thiserror-impl 2.0.17",
]
[[package]]
name = "thiserror-impl"
version = "1.0.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.111",
]
[[package]]
name = "thiserror-impl"
version = "2.0.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.111",
]
[[package]]
name = "thread_local"
version = "1.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185"
dependencies = [
"cfg-if",
]
[[package]]
name = "tiff"
version = "0.10.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af9605de7fee8d9551863fd692cce7637f548dbd9db9180fcc07ccc6d26c336f"
dependencies = [
"fax",
"flate2",
"half",
"quick-error",
"weezl",
"zune-jpeg 0.4.21",
]
[[package]]
name = "time"
version = "0.3.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "91e7d9e3bb61134e77bde20dd4825b97c010155709965fedf0f49bb138e52a9d"
dependencies = [
"deranged",
"libc",
"num-conv",
"num_threads",
"powerfmt",
"serde",
"time-core",
]
[[package]]
name = "time-core"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "40868e7c1d2f0b8d73e4a8c7f0ff63af4f6d19be117e90bd73eb1d62cf831c6b"
[[package]]
name = "tinytemplate"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc"
dependencies = [
"serde",
"serde_json",
]
[[package]]
name = "tokio"
version = "1.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ff360e02eab121e0bc37a2d3b4d4dc622e6eda3a8e5253d5435ecf5bd4c68408"
dependencies = [
"pin-project-lite",
"tokio-macros",
]
[[package]]
name = "tokio-macros"
version = "2.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.111",
]
[[package]]
name = "tracing"
version = "0.1.43"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2d15d90a0b5c19378952d479dc858407149d7bb45a14de0142f6c534b16fc647"
dependencies = [
"pin-project-lite",
"tracing-core",
]
[[package]]
name = "tracing-core"
version = "0.1.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a04e24fab5c89c6a36eb8558c9656f30d81de51dfa4d3b45f26b21d61fa0a6c"
dependencies = [
"once_cell",
"valuable",
]
[[package]]
name = "tracing-error"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b1581020d7a273442f5b45074a6a57d5757ad0a47dac0e9f0bd57b81936f3db"
dependencies = [
"tracing",
"tracing-subscriber",
]
[[package]]
name = "tracing-subscriber"
version = "0.3.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2f30143827ddab0d256fd843b7a66d164e9f271cfa0dde49142c5ca0ca291f1e"
dependencies = [
"sharded-slab",
"thread_local",
"tracing-core",
]
[[package]]
name = "typenum"
version = "1.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb"
[[package]]
name = "ucd-trie"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971"
[[package]]
name = "unicode-ident"
version = "1.0.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5"
[[package]]
name = "unicode-segmentation"
version = "1.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493"
[[package]]
name = "unicode-truncate"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8fbf03860ff438702f3910ca5f28f8dac63c1c11e7efb5012b8b175493606330"
dependencies = [
"itertools 0.13.0",
"unicode-segmentation",
"unicode-width",
]
[[package]]
name = "unicode-width"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd"
[[package]]
name = "utf8parse"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
[[package]]
name = "uuid"
version = "1.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2e054861b4bd027cd373e18e8d8d8e6548085000e41290d95ce0c373a654b4a"
dependencies = [
"atomic",
"getrandom 0.3.4",
"js-sys",
"wasm-bindgen",
]
[[package]]
name = "v_frame"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "666b7727c8875d6ab5db9533418d7c764233ac9c0cff1d469aec8fa127597be2"
dependencies = [
"aligned-vec",
"num-traits",
"wasm-bindgen",
]
[[package]]
name = "valuable"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65"
[[package]]
name = "version_check"
version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
[[package]]
name = "vsimd"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c3082ca00d5a5ef149bb8b555a72ae84c9c59f7250f013ac822ac2e49b19c64"
[[package]]
name = "vtparse"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d9b2acfb050df409c972a37d3b8e08cdea3bddb0c09db9d53137e504cfabed0"
dependencies = [
"utf8parse",
]
[[package]]
name = "walkdir"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b"
dependencies = [
"same-file",
"winapi-util",
]
[[package]]
name = "wasi"
version = "0.11.1+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
[[package]]
name = "wasip2"
version = "1.0.1+wasi-0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7"
dependencies = [
"wit-bindgen",
]
[[package]]
name = "wasm-bindgen"
version = "0.2.106"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d759f433fa64a2d763d1340820e46e111a7a5ab75f993d1852d70b03dbb80fd"
dependencies = [
"cfg-if",
"once_cell",
"rustversion",
"wasm-bindgen-macro",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.106"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "48cb0d2638f8baedbc542ed444afc0644a29166f1595371af4fecf8ce1e7eeb3"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
]
[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.106"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cefb59d5cd5f92d9dcf80e4683949f15ca4b511f4ac0a6e14d4e1ac60c6ecd40"
dependencies = [
"bumpalo",
"proc-macro2",
"quote",
"syn 2.0.111",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-shared"
version = "0.2.106"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cbc538057e648b67f72a982e708d485b2efa771e1ac05fec311f9f63e5800db4"
dependencies = [
"unicode-ident",
]
[[package]]
name = "web-sys"
version = "0.3.83"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b32828d774c412041098d182a8b38b16ea816958e07cf40eec2bc080ae137ac"
dependencies = [
"js-sys",
"wasm-bindgen",
]
[[package]]
name = "weezl"
version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a28ac98ddc8b9274cb41bb4d9d4d5c425b6020c50c46f25559911905610b4a88"
[[package]]
name = "wezterm-bidi"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c0a6e355560527dd2d1cf7890652f4f09bb3433b6aadade4c9b5ed76de5f3ec"
dependencies = [
"log",
"wezterm-dynamic",
]
[[package]]
name = "wezterm-blob-leases"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "692daff6d93d94e29e4114544ef6d5c942a7ed998b37abdc19b17136ea428eb7"
dependencies = [
"getrandom 0.3.4",
"mac_address",
"sha2",
"thiserror 1.0.69",
"uuid",
]
[[package]]
name = "wezterm-color-types"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7de81ef35c9010270d63772bebef2f2d6d1f2d20a983d27505ac850b8c4b4296"
dependencies = [
"csscolorparser",
"deltae",
"lazy_static",
"wezterm-dynamic",
]
[[package]]
name = "wezterm-dynamic"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f2ab60e120fd6eaa68d9567f3226e876684639d22a4219b313ff69ec0ccd5ac"
dependencies = [
"log",
"ordered-float 4.6.0",
"strsim",
"thiserror 1.0.69",
"wezterm-dynamic-derive",
]
[[package]]
name = "wezterm-dynamic-derive"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46c0cf2d539c645b448eaffec9ec494b8b19bd5077d9e58cb1ae7efece8d575b"
dependencies = [
"proc-macro2",
"quote",
"syn 1.0.109",
]
[[package]]
name = "wezterm-input-types"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7012add459f951456ec9d6c7e6fc340b1ce15d6fc9629f8c42853412c029e57e"
dependencies = [
"bitflags 1.3.2",
"euclid",
"lazy_static",
"serde",
"wezterm-dynamic",
]
[[package]]
name = "wide"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13ca908d26e4786149c48efcf6c0ea09ab0e06d1fe3c17dc1b4b0f1ca4a7e788"
dependencies = [
"bytemuck",
"safe_arch",
]
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-util"
version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22"
dependencies = [
"windows-sys 0.61.2",
]
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "windows"
version = "0.58.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6"
dependencies = [
"windows-core",
"windows-targets",
]
[[package]]
name = "windows-core"
version = "0.58.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99"
dependencies = [
"windows-implement",
"windows-interface",
"windows-result",
"windows-strings",
"windows-targets",
]
[[package]]
name = "windows-implement"
version = "0.58.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.111",
]
[[package]]
name = "windows-interface"
version = "0.58.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.111",
]
[[package]]
name = "windows-link"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
[[package]]
name = "windows-result"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e"
dependencies = [
"windows-targets",
]
[[package]]
name = "windows-strings"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10"
dependencies = [
"windows-result",
"windows-targets",
]
[[package]]
name = "windows-sys"
version = "0.59.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
dependencies = [
"windows-targets",
]
[[package]]
name = "windows-sys"
version = "0.61.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc"
dependencies = [
"windows-link",
]
[[package]]
name = "windows-targets"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_gnullvm",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
[[package]]
name = "windows_aarch64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
[[package]]
name = "windows_i686_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
[[package]]
name = "windows_i686_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
[[package]]
name = "windows_i686_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
[[package]]
name = "windows_x86_64_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
[[package]]
name = "windows_x86_64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
[[package]]
name = "wit-bindgen"
version = "0.46.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59"
[[package]]
name = "wyz"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed"
dependencies = [
"tap",
]
[[package]]
name = "y4m"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a5a4b21e1a62b67a2970e6831bc091d7b87e119e7f9791aef9702e3bef04448"
[[package]]
name = "zerocopy"
version = "0.8.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd74ec98b9250adb3ca554bdde269adf631549f51d8a8f8f0a10b50f1cb298c3"
dependencies = [
"zerocopy-derive",
]
[[package]]
name = "zerocopy-derive"
version = "0.8.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d8a8d209fdf45cf5138cbb5a506f6b52522a25afccc534d1475dad8e31105c6a"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.111",
]
[[package]]
name = "zmij"
version = "1.0.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa"
[[package]]
name = "zune-core"
version = "0.4.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f423a2c17029964870cfaabb1f13dfab7d092a62a29a89264f4d36990ca414a"
[[package]]
name = "zune-core"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "111f7d9820f05fd715df3144e254d6fc02ee4088b0644c0ffd0efc9e6d9d2773"
[[package]]
name = "zune-inflate"
version = "0.2.54"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73ab332fe2f6680068f3582b16a24f90ad7096d5d39b974d1c0aff0125116f02"
dependencies = [
"simd-adler32",
]
[[package]]
name = "zune-jpeg"
version = "0.4.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "29ce2c8a9384ad323cf564b67da86e21d3cfdff87908bc1223ed5c99bc792713"
dependencies = [
"zune-core 0.4.12",
]
[[package]]
name = "zune-jpeg"
version = "0.5.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "51d915729b0e7d5fe35c2f294c5dc10b30207cc637920e5b59077bfa3da63f28"
dependencies = [
"zune-core 0.5.0",
]
ratatui-image-10.0.8/Cargo.toml 0000644 00000006507 10461020230 0011703 0 ustar # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
#
# When uploading crates to the registry Cargo will automatically
# "normalize" Cargo.toml files for maximal compatibility
# with all versions of Cargo and also rewrite `path` dependencies
# to registry (e.g., crates.io) dependencies.
#
# If you are reading this file be aware that the original Cargo.toml
# will likely look very different (and much more reasonable).
# See Cargo.toml.orig for the original contents.
[package]
edition = "2024"
rust-version = "1.86.0"
name = "ratatui-image"
version = "10.0.8"
authors = ["Benjamin GroÃe "]
build = "build.rs"
exclude = ["assets/*"]
autolib = false
autobins = false
autoexamples = false
autotests = false
autobenches = false
description = "An image widget for ratatui, supporting sixels, kitty, iterm2, and unicode-halfblocks"
homepage = "https://github.com/ratatui/ratatui-image"
readme = "README.md"
keywords = [
"ratatui",
"image",
"sixel",
"kitty",
"iterm2",
]
license = "MIT"
repository = "https://github.com/ratatui/ratatui-image"
[package.metadata.docs.rs]
features = [
"crossterm",
"kitty-offset",
]
rustdoc-args = [
"--cfg",
"docsrs",
]
[features]
chafa-dyn = ["dep:pkg-config"]
chafa-static = ["dep:pkg-config"]
crossterm = ["ratatui/crossterm"]
default = [
"image-defaults",
"crossterm",
"chafa-dyn",
]
image-defaults = ["image/default"]
kitty-offset = []
serde = ["dep:serde"]
termion = ["ratatui/termion"]
termwiz = ["ratatui/termwiz"]
thread-example = []
tokio = ["dep:tokio"]
[lib]
name = "ratatui_image"
path = "src/lib.rs"
[[bin]]
name = "ratatui-image"
path = "src/bin/ratatui-image/main.rs"
bench = false
required-features = ["crossterm"]
[[example]]
name = "demo"
path = "examples/demo/main.rs"
doc-scrape-examples = true
[[example]]
name = "thread"
path = "examples/thread.rs"
required-features = [
"crossterm",
"thread-example",
]
[[example]]
name = "tokio"
path = "examples/tokio.rs"
required-features = [
"crossterm",
"tokio",
]
[[bench]]
name = "protocols"
path = "benches/protocols.rs"
harness = false
[dependencies.base64-simd]
version = "0.8"
[dependencies.icy_sixel]
version = "^0.5.0"
[dependencies.image]
version = "^0.25.6"
features = ["png"]
default-features = false
[dependencies.rand]
version = "^0.8.5"
[dependencies.ratatui]
version = "^0.30.0"
features = []
default-features = false
[dependencies.serde]
version = "^1.0"
features = ["derive"]
optional = true
[dependencies.thiserror]
version = "1.0.59"
[dependencies.tokio]
version = "1.45.1"
features = ["sync"]
optional = true
default-features = false
[dev-dependencies.color-eyre]
version = "0.6.5"
[dev-dependencies.criterion]
version = "0.5.1"
[dev-dependencies.crossterm]
version = "0.29.0"
features = ["event-stream"]
[dev-dependencies.futures]
version = "0.3.31"
[dev-dependencies.insta]
version = "1.44.3"
[dev-dependencies.tokio]
version = "1.45.1"
features = [
"macros",
"rt",
"rt-multi-thread",
]
[build-dependencies.pkg-config]
version = "0.3"
optional = true
[target."cfg(not(windows))".dependencies.rustix]
version = "^0.38.4"
features = [
"stdio",
"termios",
"fs",
]
[target."cfg(windows)".dependencies.windows]
version = "0.58.0"
features = [
"std",
"Win32_System_Console",
"Win32_Storage_FileSystem",
"Win32_Security",
]
default-features = false
ratatui-image-10.0.8/Cargo.toml.orig 0000644 0000000 0000000 00000005012 10461020230 0015330 0 ustar 0000000 0000000 [package]
name = "ratatui-image"
version = "10.0.8"
edition = "2024"
autoexamples = true
authors = ["Benjamin GroÃe "]
description = "An image widget for ratatui, supporting sixels, kitty, iterm2, and unicode-halfblocks"
keywords = ["ratatui", "image", "sixel", "kitty", "iterm2"]
repository = "https://github.com/ratatui/ratatui-image"
homepage = "https://github.com/ratatui/ratatui-image"
readme = "README.md"
license = "MIT"
exclude = ["assets/*"]
rust-version = "1.86.0"
[features]
default = ["image-defaults", "crossterm", "chafa-dyn"]
crossterm = ["ratatui/crossterm"]
image-defaults = ["image/default"]
termion = ["ratatui/termion"]
termwiz = ["ratatui/termwiz"]
serde = ["dep:serde"]
tokio = ["dep:tokio"]
thread-example = []
chafa-dyn = ["dep:pkg-config"]
chafa-static = ["dep:pkg-config"]
kitty-offset = []
[dependencies]
image = { version = "^0.25.6", default-features = false, features = ["png"] }
icy_sixel = { version = "^0.5.0" }
serde = { version = "^1.0", optional = true, features = ["derive"] }
base64-simd = { version = "0.8" }
rand = { version = "^0.8.5" }
ratatui = { version = "^0.30.0", default-features = false, features = [] }
thiserror = { version = "1.0.59" }
tokio = { version = "1.45.1", default-features = false, optional = true, features = ["sync"]}
[target.'cfg(not(windows))'.dependencies]
rustix = { version = "^0.38.4", features = ["stdio", "termios", "fs"] }
[target.'cfg(windows)'.dependencies]
windows = { version = "0.58.0", default-features = false, features = [
"std",
"Win32_System_Console",
"Win32_Storage_FileSystem",
"Win32_Security",
] }
[[bin]]
name = "ratatui-image"
path = "./src/bin/ratatui-image/main.rs" # cargo readme needs this for some reason
required-features = ["crossterm"]
bench = false
[[example]]
name = "demo"
# this runs for all of the terminal backends, so it can't be built using --all-features or scraped
doc-scrape-examples = true
[[example]]
name = "thread"
required-features = ["crossterm", "thread-example"] # clashes with "tokio".
[[example]]
name = "tokio"
required-features = ["crossterm", "tokio"]
[build-dependencies]
pkg-config = { version = "0.3", optional = true }
[dev-dependencies]
color-eyre = "0.6.5"
crossterm = { version = "0.29.0", features = ["event-stream"] }
futures = "0.3.31"
tokio = { version = "1.45.1", features = ["macros", "rt", "rt-multi-thread"] }
insta = "1.44.3"
criterion = "0.5.1"
[[bench]]
name = "protocols"
harness = false
[package.metadata.docs.rs]
features = ["crossterm", "kitty-offset"]
rustdoc-args = ["--cfg", "docsrs"]
ratatui-image-10.0.8/LICENSE 0000644 0000000 0000000 00000002367 10461020230 0013460 0 ustar 0000000 0000000 The MIT License (MIT)
Copyright (c) 2022 Atanas Yankov (code and inspiration taken from https://github.com/atanunq/viuer)
Copyright (c) 2022 wooster0 (inspiration taken from https://github.com/wooster0/hanbun)
Copyright (c) 2023 Benjamin GroÃe
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
ratatui-image-10.0.8/Makefile.toml 0000644 0000000 0000000 00000001123 10461020230 0015052 0 ustar 0000000 0000000 [tasks.default]
alias = "ci"
dependencies = [
"fmt",
"clippy",
"check",
"test",
"readme",
"build",
]
[tasks.fmt]
command = "cargo"
args = ["fmt", "--all", "--", "--check"]
[tasks.clippy]
command = "cargo"
args = ["clippy", "--no-deps", "--tests", "--all-features", "--", "-D", "warnings"]
[tasks.check]
command = "cargo"
args = ["check", "--all-features"]
[tasks.test]
command = "cargo"
args = ["test", "--features", "crossterm"]
[tasks.readme]
command = "cargo"
args = ["readme", "-o", "README.md"]
[tasks.build]
command = "cargo"
args = ["build", "--features", "crossterm"]
ratatui-image-10.0.8/README.md 0000644 0000000 0000000 00000025176 10461020230 0013735 0 ustar 0000000 0000000 # Ratatui-image
[![CI Badge]][CI]
[![Crate Badge]][Crate]
[![Docs Badge]][Docs]
[CI Badge]: https://img.shields.io/github/actions/workflow/status/ratatui/ratatui-image/ci.yaml?style=flat-square&logo=github
[CI]: https://github.com/ratatui/ratatui-image/actions?query=workflow%3A
[Crate Badge]: https://img.shields.io/crates/v/ratatui-image?logo=rust&style=flat-square
[Crate]: https://crates.io/crates/ratatui-image
[Docs Badge]: https://img.shields.io/docsrs/ratatui-image?logo=rust&style=flat-square
[Docs]: https://docs.rs/ratatui-image/latest/ratatui_image/index.html
### Showcase:

[Link to screenshot test suite with array of terminals](https://benjajaja.github.io/ratatui-image-screenshots/) (xterm, foot, kitty, wezterm, ghostty, rio, mlterm...)
## Image widgets with multiple graphics protocol backends for [ratatui]
**Unify terminal image rendering across Sixels, Kitty, and iTerm2 protocols.**
[ratatui] is an immediate-mode TUI library.
ratatui-image tackles 3 general problems when rendering images with an immediate-mode TUI:
**Query the terminal for available graphics protocols**
Some terminals may implement one or more graphics protocols, such as Sixels, or the iTerm2 or
Kitty graphics protocols. Guess by env vars. If that fails, query the terminal with some
control sequences.
Fallback to "halfblocks" which uses some unicode half-block characters with fore- and
background colors.
**Query the terminal for the font-size in pixels.**
If there is an actual graphics protocol available, it is necessary to know the font-size to
be able to map the image pixels to character cell area.
Query the terminal with some control sequences for either the font-size directly, or the
window-size in pixels and derive the font-size together with row/column count.
**Render the image by the means of the guessed protocol.**
Some protocols, like Sixels, are essentially "immediate-mode", but we still need to avoid the
TUI from overwriting the image area, even with blank characters.
Other protocols, like Kitty, are essentially stateful, but at least provide a way to re-render
an image that has been loaded, at a different or same position.
Since we have the font-size in pixels, we can precisely map the characters/cells/rows-columns
that will be covered by the image and skip drawing over the image.
## Quick start
```rust
use ratatui::{backend::TestBackend, Terminal, Frame};
use ratatui_image::{picker::Picker, StatefulImage, protocol::StatefulProtocol};
struct App {
// We need to hold the render state.
image: StatefulProtocol,
}
fn main() -> Result<(), Box> {
let backend = TestBackend::new(80, 30);
let mut terminal = Terminal::new(backend)?;
// Should use Picker::from_query_stdio() to get the font size and protocol,
// but we can't put that here because that would break doctests!
let mut picker = Picker::halfblocks();
// Load an image with the image crate.
let dyn_img = image::ImageReader::open("./assets/Ada.png")?.decode()?;
// Create the Protocol which will be used by the widget.
let image = picker.new_resize_protocol(dyn_img);
let mut app = App { image };
// This would be your typical `loop {` in a real app:
terminal.draw(|f| ui(f, &mut app))?;
// It is recommended to handle the encoding result
app.image.last_encoding_result().unwrap()?;
Ok(())
}
fn ui(f: &mut Frame<'_>, app: &mut App) {
// The image widget.
let image = StatefulImage::default();
// Render with the protocol state.
f.render_stateful_widget(image, f.area(), &mut app.image);
}
```
The [picker::Picker] helper is there to do all this font-size and graphics-protocol guessing,
and also to map character-cell-size to pixel size so that we can e.g. "fit" an image inside
a desired columns+rows bound, and so on.
## Widget choice
* The [Image] widget has a fixed size in rows/columns. If the image pixel size exceeds the
pixel area of the rows/columns, the image is scaled down proportionally to "fit" once.
If the actual rendering area is smaller than the initial rows/columns, it is simply not
rendered at all.
The big upside is that this widget is _stateless_ (in terms of ratatui, i.e. immediate-mode),
and thus can never block the rendering thread/task. A lot of ratatui apps only use stateless
widgets, so this factor is also important when chosing.
* The [StatefulImage] widget adapts to its render area at render-time. It can be set to fit,
crop, or scale to the available render area.
This means the widget must be stateful, i.e. use `render_stateful_widget` which takes a
mutable state parameter.
The resizing and encoding is blocking, and since it happens at render-time it is a good idea
to offload that to another thread or async task, if the UI must be responsive (see
`examples/thread.rs` and `examples/tokio.rs`).
## Examples
* `examples/demo.rs` is a fully fledged demo.
* `examples/thread.rs` shows how to offload resize and encoding to another thread, to avoid
blocking the UI thread.
* `examples/tokio.rs` same as `thread.rs` but with tokio.
The lib also includes a binary that renders an image file, but it is focused on testing.
## Features
#### Backend
* `crossterm` (default) if this matches your ratatui backend (most likely).
* `termion` if this matches your ratatui backend.
* `termwiz` is available, but not working correctly with ratatui-image.
#### Chafa library
* `chafa-dyn` (default) to use the amazing [chafa](https://hpjansson.org/chafa/) library for
rendering without image protocols. Dynamically link against libchafa.so at compile time.
Requires libchafa to be available at runtime in the same way.
* `chafa-static` to statically link against libchafa.a at compile time. The library is embedded
in the binary.
* If you absolutely don't want to deal with libchafa, then you should use
`--no-default-features --features image-defaults,crossterm` or a variation thereof.
Note: The chafa features are mutually exclusive - only enable one at a time.
#### Others
* `image-defaults` (default) just enables `image/defaults` (`image` has `default-features =
false`). To only support a selection of image formats and cut down dependencies, disable this
feature, add `image` to your crate, and enable its features/formats as desired. See
.
* `serde` for `#[derive]`s on [picker::ProtocolType] for convenience, because it might be
useful to save it in some user configuration.
* `tokio` whether to use tokio's `UnboundedSender` in `ThreadProtocol`.
* `kitty-offset` is an experimental feature that enables `skip_lines(u16)` on
[`protocol::kitty::Kitty`].
[ratatui]: https://github.com/ratatui-org/ratatui
[sixel]: https://en.wikipedia.org/wiki/Sixel
[`render_stateful_widget`]: https://docs.rs/ratatui/latest/ratatui/terminal/struct.Frame.html#method.render_stateful_widget
### Compatibility matrix
Compatibility and QA:
Terminal | Protocol | OK | QA | Notes
----------|----------|----|----|------
Xterm | `Sixel` | âī¸ | âī¸ | Run with `-ti 340` to make sure sixel support is enabled.
Foot | `Sixel` | âī¸ | âī¸ | Wayland.
Kitty | `Kitty` | âī¸ | âī¸ | Reference for the `Kitty` protocol (requires Kitty 0.28.0 or later).
Wezterm | `iTerm2` | âī¸ | â | Also would support `Sixel` and `Kitty`, but only `iTerm2` actually works bug-free.
Ghostty | `Kitty` | âī¸ | âī¸ | Implements `Kitty` with unicode placeholders.
iTerm2 | `iTerm2` | âī¸ | - | Reference for the `iTerm2` protocol. Mac only.
Rio | `iTerm2` | âī¸ | âī¸ | Also supports `Sixel` but has glitches.
mlterm | `Sixel` | âī¸ | âī¸ | Quite slow but no glitches.
Black Box | `Sixel` | âī¸ | - | Confirmed only with the flatpak version, most distro packages don't enable Sixel support.
Bobcat | `iTerm2` | âī¸ | - | Works on all versions and builds. Falls back to `Sixel` if `TERM_PROGRAM` variable is not set.
Alacritty | `Sixel` | â | - | [There is a sixel fork](https://github.com/microo8/alacritty-sixel), but it's probably never getting merged, and does not clear graphics.
Konsole | `Sixel` | â | - | [Not really fixed in 24.12](https://bugs.kde.org/show_bug.cgi?id=456354)
Contour | `Sixel` | â | â | Does not clear graphics.
ctx | `Sixel` | â | â | Buggy.
Warp | `iTerm2` | â | - | iTerm2 does not clear, Kitty unicode-placeholders part not implemented.
"QA" means that there is a flake VM test that runs the demo and takes a screenshot, posted as PR comment.
`-` means it's not possible or applicable to add a screenshot-test.
[Link to latest screenshot of the test-suite on `master`](https://benjajaja.github.io/ratatui-image-screenshots/)
Halfblocks should work in all terminals, even if the font size could not be detected, with a 4:8 pixel ratio.
### Known issues
Summary | Link
--------|---------
Termwiz backend does not work at all | [#1](https://github.com/ratatui/ratatui-image/issues/1)
Sixel image rendered on the last line of terminal causes a scroll | [#57](https://github.com/ratatui/ratatui-image/issues/57)
### Projects that use ratatui-image
* [mdfried](https://github.com/benjajaja/mdfried)
A markdown viewer that renders headers bigger (as images), and regular images too.
* [iamb](https://github.com/ulyssa/iamb)
A matrix client with vim keybindings.
* [joshuto](https://github.com/kamiyaa/joshuto)
A terminal file manager that can preview images.
* [Aerostream](https://github.com/shigepon7/aerostream)
A Bluesky client using EventStream.
* [Eilmeldung](https://github.com/christo-auer/eilmeldung)
RSS reader
* [rvIRC](https://github.com/KaraZajac/rvIRC)
An IRC client with vim keybindings.
### Comparison
* [viuer](https://crates.io/crates/viuer)
Renders graphics in different terminals/protocols, but "dumps" the image, making it difficult to
work for TUI programs.
The terminal protocol guessing code has been adapted to rustix, thus the author of viuer is
included in the copyright notice.
* [yazi](https://github.com/sxyazi/yazi)
Not a library but a terminal file manager that implementes many graphics protocols and lets you
preview images in the filesystem.
* [Ãberzug++](https://github.com/jstkdng/ueberzugpp)
CLI utility that draws images on terminals by using X11/wayland child windows, sixels, kitty,
and/or iterm2 protocols (any means necessary). There exists several wrapper or bindings crates.
More battle-tested but essentially stateful, which makes it hard to use with immediate-mode.
### Contributing
PRs and issues/discussions welcome!
There are some specific rules for a PR to be reviewed at all, please see [CONTRIBUTING.md](CONTRIBUTING.md) for reference.
License: MIT
ratatui-image-10.0.8/README.tpl 0000644 0000000 0000000 00000011131 10461020230 0014116 0 ustar 0000000 0000000 # Ratatui-image
[![CI Badge]][CI]
[![Crate Badge]][Crate]
[![Docs Badge]][Docs]
[CI Badge]: https://img.shields.io/github/actions/workflow/status/ratatui/ratatui-image/ci.yaml?style=flat-square&logo=github
[CI]: https://github.com/ratatui/ratatui-image/actions?query=workflow%3A
[Crate Badge]: https://img.shields.io/crates/v/ratatui-image?logo=rust&style=flat-square
[Crate]: https://crates.io/crates/ratatui-image
[Docs Badge]: https://img.shields.io/docsrs/ratatui-image?logo=rust&style=flat-square
[Docs]: https://docs.rs/ratatui-image/latest/ratatui_image/index.html
### Showcase:

[Link to screenshot test suite with array of terminals](https://benjajaja.github.io/ratatui-image-screenshots/) (xterm, foot, kitty, wezterm, ghostty, rio, mlterm...)
{{readme}}
### Compatibility matrix
Compatibility and QA:
Terminal | Protocol | OK | QA | Notes
----------|----------|----|----|------
Xterm | `Sixel` | âī¸ | âī¸ | Run with `-ti 340` to make sure sixel support is enabled.
Foot | `Sixel` | âī¸ | âī¸ | Wayland.
Kitty | `Kitty` | âī¸ | âī¸ | Reference for the `Kitty` protocol (requires Kitty 0.28.0 or later).
Wezterm | `iTerm2` | âī¸ | â | Also would support `Sixel` and `Kitty`, but only `iTerm2` actually works bug-free.
Ghostty | `Kitty` | âī¸ | âī¸ | Implements `Kitty` with unicode placeholders.
iTerm2 | `iTerm2` | âī¸ | - | Reference for the `iTerm2` protocol. Mac only.
Rio | `iTerm2` | âī¸ | âī¸ | Also supports `Sixel` but has glitches.
mlterm | `Sixel` | âī¸ | âī¸ | Quite slow but no glitches.
Black Box | `Sixel` | âī¸ | - | Confirmed only with the flatpak version, most distro packages don't enable Sixel support.
Bobcat | `iTerm2` | âī¸ | - | Works on all versions and builds. Falls back to `Sixel` if `TERM_PROGRAM` variable is not set.
Alacritty | `Sixel` | â | - | [There is a sixel fork](https://github.com/microo8/alacritty-sixel), but it's probably never getting merged, and does not clear graphics.
Konsole | `Sixel` | â | - | [Not really fixed in 24.12](https://bugs.kde.org/show_bug.cgi?id=456354)
Contour | `Sixel` | â | â | Does not clear graphics.
ctx | `Sixel` | â | â | Buggy.
Warp | `iTerm2` | â | - | iTerm2 does not clear, Kitty unicode-placeholders part not implemented.
"QA" means that there is a flake VM test that runs the demo and takes a screenshot, posted as PR comment.
`-` means it's not possible or applicable to add a screenshot-test.
[Link to latest screenshot of the test-suite on `master`](https://benjajaja.github.io/ratatui-image-screenshots/)
Halfblocks should work in all terminals, even if the font size could not be detected, with a 4:8 pixel ratio.
### Known issues
Summary | Link
--------|---------
Termwiz backend does not work at all | [#1](https://github.com/ratatui/ratatui-image/issues/1)
Sixel image rendered on the last line of terminal causes a scroll | [#57](https://github.com/ratatui/ratatui-image/issues/57)
### Projects that use ratatui-image
* [mdfried](https://github.com/benjajaja/mdfried)
A markdown viewer that renders headers bigger (as images), and regular images too.
* [iamb](https://github.com/ulyssa/iamb)
A matrix client with vim keybindings.
* [joshuto](https://github.com/kamiyaa/joshuto)
A terminal file manager that can preview images.
* [Aerostream](https://github.com/shigepon7/aerostream)
A Bluesky client using EventStream.
* [Eilmeldung](https://github.com/christo-auer/eilmeldung)
RSS reader
* [rvIRC](https://github.com/KaraZajac/rvIRC)
An IRC client with vim keybindings.
### Comparison
* [viuer](https://crates.io/crates/viuer)
Renders graphics in different terminals/protocols, but "dumps" the image, making it difficult to
work for TUI programs.
The terminal protocol guessing code has been adapted to rustix, thus the author of viuer is
included in the copyright notice.
* [yazi](https://github.com/sxyazi/yazi)
Not a library but a terminal file manager that implementes many graphics protocols and lets you
preview images in the filesystem.
* [Ãberzug++](https://github.com/jstkdng/ueberzugpp)
CLI utility that draws images on terminals by using X11/wayland child windows, sixels, kitty,
and/or iterm2 protocols (any means necessary). There exists several wrapper or bindings crates.
More battle-tested but essentially stateful, which makes it hard to use with immediate-mode.
### Contributing
PRs and issues/discussions welcome!
There are some specific rules for a PR to be reviewed at all, please see [CONTRIBUTING.md](CONTRIBUTING.md) for reference.
License: {{license}}
ratatui-image-10.0.8/benches/protocols.rs 0000644 0000000 0000000 00000004423 10461020230 0016447 0 ustar 0000000 0000000 #![expect(clippy::unwrap_used)]
use criterion::{Criterion, criterion_group, criterion_main};
use ratatui::{buffer::Buffer, layout::Rect, widgets::StatefulWidget as _};
use ratatui_image::{
Resize, ResizeEncodeRender, StatefulImage,
picker::{Picker, ProtocolType},
};
use std::hint::black_box;
fn bench_resize_encode_render(c: &mut Criterion) {
let image = image::ImageReader::open("./assets/Ada.png")
.unwrap()
.decode()
.unwrap();
let protocol_types = [
ProtocolType::Sixel,
ProtocolType::Kitty,
ProtocolType::Iterm2,
ProtocolType::Halfblocks,
];
for &protocol in &protocol_types {
let protocol_str = match protocol {
ProtocolType::Sixel => "sixel",
ProtocolType::Kitty => "kitty",
ProtocolType::Iterm2 => "iterm2",
ProtocolType::Halfblocks => "halfblocks",
};
c.bench_function(&format!("resize_encode_render_{protocol_str}"), |b| {
b.iter(|| {
let mut picker = Picker::halfblocks();
picker.set_protocol_type(protocol);
let mut proto = picker.new_resize_protocol(black_box(image.clone()));
let area = Rect::new(0, 0, 10, 10);
let buf = Buffer::empty(area);
let image = StatefulImage::default();
image.render(black_box(area), &mut black_box(buf), &mut proto);
})
});
c.bench_function(&format!("resize_encode_{protocol_str}"), |b| {
b.iter(|| {
let mut picker = Picker::halfblocks();
picker.set_protocol_type(protocol);
let mut proto = picker.new_resize_protocol(black_box(image.clone()));
let area = Rect::new(0, 0, 10, 10);
proto.resize_encode(&Resize::Fit(None), black_box(area));
})
});
}
}
fn bench_config() -> Criterion {
Criterion::default()
.measurement_time(std::time::Duration::from_secs(30))
.warm_up_time(std::time::Duration::from_secs(5))
.sample_size(250)
.nresamples(10000)
.configure_from_args()
}
criterion_group! {
name = benches;
config = bench_config();
targets = bench_resize_encode_render
}
criterion_main!(benches);
ratatui-image-10.0.8/build.rs 0000644 0000000 0000000 00000004221 10461020230 0014107 0 ustar 0000000 0000000 fn main() {
// chafa-dyn: Use pkg-config to find chafa and emit link flags
#[cfg(feature = "chafa-dyn")]
{
pkg_config::Config::new()
// https://github.com/hpjansson/chafa/commit/b1ddce829798a81db54572261e6864ebab171631
// 1.8.0 added chafa_canvas_get_char_at()
.atleast_version("1.8.0")
.probe("chafa")
.expect(
"Failed to find chafa via pkg-config. Install libchafa-dev or set PKG_CONFIG_PATH. Needs version >= 1.8.0.",
);
}
// chafa-static: Static linking only (no fallback)
#[cfg(feature = "chafa-static")]
{
let lib = pkg_config::Config::new()
.statik(true)
.probe("chafa")
.expect(
"Failed to find chafa via pkg-config. Install libchafa-dev or set PKG_CONFIG_PATH.",
);
// Find the static library
for path in &lib.link_paths {
let static_lib = path.join("libchafa.a");
if static_lib.exists() {
// Use this path for static linking
println!("cargo:rustc-link-search=native={}", path.display());
println!("cargo:rustc-link-lib=static=chafa");
// Also link dependencies that pkg-config found
for link_path in &lib.link_paths {
if link_path != path {
println!("cargo:rustc-link-search=native={}", link_path.display());
}
}
// Link glib and its dependencies statically
println!("cargo:rustc-link-lib=static=glib-2.0");
println!("cargo:rustc-link-lib=static=sysprof-capture-4");
println!("cargo:rustc-link-lib=pcre2-8");
println!("cargo:rustc-link-lib=m");
return;
}
}
// No static lib found - this is an error for chafa-static
panic!(
"chafa-static feature requires libchafa.a but it was not found in {:?}. \
Either build chafa with --enable-static or use chafa-dyn for dynamic linking.",
lib.link_paths
);
}
}
ratatui-image-10.0.8/examples/demo/crossterm.rs 0000644 0000000 0000000 00000004307 10461020230 0017600 0 ustar 0000000 0000000 use std::{
error::Error,
io,
time::{Duration, Instant},
};
use ratatui::{
Terminal,
backend::{Backend, CrosstermBackend},
crossterm::{
event::{self, DisableMouseCapture, EnableMouseCapture, Event, KeyCode, KeyEventKind},
execute,
terminal::{EnterAlternateScreen, LeaveAlternateScreen, disable_raw_mode, enable_raw_mode},
},
};
use crate::{App, ui};
pub fn run() -> Result<(), Box> {
let original_hook = std::panic::take_hook();
std::panic::set_hook(Box::new(move |panic| {
disable_raw_mode().unwrap();
ratatui::crossterm::execute!(io::stdout(), LeaveAlternateScreen).unwrap();
original_hook(panic);
}));
// setup terminal
enable_raw_mode()?;
let mut stdout = io::stdout();
execute!(stdout, EnterAlternateScreen, EnableMouseCapture)?;
let backend = CrosstermBackend::new(stdout);
let mut terminal = Terminal::new(backend)?;
let app = App::new(&mut terminal);
// run app
let res = run_app(&mut terminal, app);
// restore terminal
disable_raw_mode()?;
execute!(
terminal.backend_mut(),
LeaveAlternateScreen,
DisableMouseCapture
)?;
terminal.show_cursor()?;
if let Err(err) = res {
println!("{err:?}");
}
Ok(())
}
fn run_app(terminal: &mut Terminal, mut app: App) -> Result<(), Box>
where
::Error: 'static,
{
let mut last_tick = Instant::now();
loop {
terminal.draw(|f| ui(f, &mut app))?;
let timeout = app
.tick_rate
.checked_sub(last_tick.elapsed())
.unwrap_or_else(|| Duration::from_secs(0));
if ratatui::crossterm::event::poll(timeout)? {
if let Event::Key(key) = event::read()? {
if key.kind == KeyEventKind::Press {
if let KeyCode::Char(c) = key.code {
app.on_key(c);
}
}
}
}
if last_tick.elapsed() >= app.tick_rate {
app.on_tick();
last_tick = Instant::now();
}
if app.should_quit {
return Ok(());
}
}
}
ratatui-image-10.0.8/examples/demo/main.rs 0000644 0000000 0000000 00000024474 10461020230 0016512 0 ustar 0000000 0000000 #[cfg(all(
not(feature = "crossterm"),
not(feature = "termion"),
not(feature = "termwiz")
))]
compile_error!("The demo needs one of the crossterm, termion, or termwiz features");
#[cfg(feature = "crossterm")]
mod crossterm;
#[cfg(feature = "termion")]
mod termion;
#[cfg(feature = "termwiz")]
mod termwiz;
use std::{env, error::Error, num::Wrapping as w, path::PathBuf, sync::Once, time::Duration};
use image::DynamicImage;
use ratatui::{
Frame, Terminal,
backend::Backend,
layout::{Constraint, Direction, Layout, Rect},
style::{Color, Stylize},
text::{Line, Span, Text},
widgets::{Block, Borders, Paragraph, Wrap},
};
use ratatui_image::{
Image, Resize, StatefulImage,
picker::Picker,
protocol::{Protocol, StatefulProtocol},
};
fn main() -> Result<(), Box> {
#[cfg(feature = "crossterm")]
crate::crossterm::run()?;
#[cfg(feature = "termion")]
crate::termion::run()?;
#[cfg(feature = "termwiz")]
crate::termwiz::run()?;
Ok(())
}
static READY: Once = Once::new();
#[derive(Debug)]
enum ShowImages {
All,
Fixed,
Resized,
}
struct App {
title: String,
should_quit: bool,
tick_rate: Duration,
background: String,
split_percent: u16,
show_images: ShowImages,
image_source_path: PathBuf,
image_static_offset: (u16, u16),
picker: Picker,
image_source: DynamicImage,
image_static: Protocol,
image_fit_state: StatefulProtocol,
image_crop_state: StatefulProtocol,
image_scale_state: StatefulProtocol,
}
fn size() -> Rect {
Rect::new(0, 0, 30, 16)
}
impl App {
pub fn new(_: &mut Terminal) -> Self {
let title = format!(
"Demo ({})",
env::var("TERM").unwrap_or("unknown".to_string())
);
let image = if env::args().any(|arg| arg == "--tmp-demo-ready") {
"./assets/Jenkins.png"
} else {
"./assets/Ada.png"
};
let image_source = image::ImageReader::open(image).unwrap().decode().unwrap();
let picker = Picker::from_query_stdio().unwrap();
let image_static = picker
.new_protocol(image_source.clone(), size(), Resize::Fit(None))
.expect("demo gets a protocol from image");
let image_fit_state = picker.new_resize_protocol(image_source.clone());
let image_crop_state = picker.new_resize_protocol(image_source.clone());
let image_scale_state = picker.new_resize_protocol(image_source.clone());
let mut background = String::new();
let mut r: [u64; 2] = [0x8a5cd789635d2dff, 0x121fd2155c472f96];
for _ in 0..5_000 {
let mut s1 = w(r[0]);
let s0 = w(r[1]);
let result = s0 + s1;
r[0] = s0.0;
s1 ^= s1 << 23;
r[1] = (s1 ^ s0 ^ (s1 >> 18) ^ (s0 >> 5)).0;
let c = match result.0 % 4 {
0 => '.',
1 => ' ',
_ => 'âĻ',
};
background.push(c);
}
Self {
title,
should_quit: false,
tick_rate: Duration::from_millis(1000),
background,
show_images: ShowImages::All,
split_percent: 70,
picker,
image_source,
image_source_path: image.into(),
image_static,
image_fit_state,
image_crop_state,
image_scale_state,
image_static_offset: (0, 0),
}
}
pub fn on_key(&mut self, c: char) {
match c {
'q' => {
self.should_quit = true;
}
't' => {
self.show_images = match self.show_images {
ShowImages::All => ShowImages::Fixed,
ShowImages::Fixed => ShowImages::Resized,
ShowImages::Resized => ShowImages::All,
}
}
'i' => {
// Normally, we *never* would want to switch the detected protocol.
// This is for some debug session, where you want to test some other protocol than
// the detected.
// Changing "live" is also quite hazardous, as this will render some artifacts in
// between, or even trigger error messages, or crashes.
// If you need to "downgrade" e.g. to Halfblocks, then do it before any renders.
let next = self.picker.protocol_type().next();
self.picker.set_protocol_type(next);
self.reset_images();
}
'o' => {
let path = match self.image_source_path.to_str() {
Some("./assets/Ada.png") => "./assets/Jenkins.png",
Some("./assets/Jenkins.png") => "./assets/NixOS.png",
_ => "./assets/Ada.png",
};
self.image_source = image::ImageReader::open(path).unwrap().decode().unwrap();
self.image_source_path = path.into();
self.reset_images();
}
'H' => {
if self.split_percent >= 10 {
self.split_percent -= 10;
}
}
'L' => {
if self.split_percent <= 90 {
self.split_percent += 10;
}
}
'h' => {
if self.image_static_offset.0 > 0 {
self.image_static_offset.0 -= 1;
}
}
'j' => {
self.image_static_offset.1 += 1;
}
'k' => {
if self.image_static_offset.1 > 0 {
self.image_static_offset.1 -= 1;
}
}
'l' => {
self.image_static_offset.0 += 1;
}
_ => {}
}
}
fn reset_images(&mut self) {
self.image_static = self
.picker
.new_protocol(self.image_source.clone(), size(), Resize::Fit(None))
.unwrap();
self.image_fit_state = self.picker.new_resize_protocol(self.image_source.clone());
self.image_crop_state = self.picker.new_resize_protocol(self.image_source.clone());
self.image_scale_state = self.picker.new_resize_protocol(self.image_source.clone());
}
pub fn on_tick(&mut self) {
READY.call_once(|| {
// This is normally only set by nixosTest.
if env::args().any(|arg| arg == "--tmp-demo-ready") {
if let Err(err) = std::fs::File::create("/tmp/demo-ready") {
panic!("{err}");
}
}
});
}
fn render_resized_image(&mut self, f: &mut Frame<'_>, resize: Resize, area: Rect) {
let (state, name, color) = match resize {
Resize::Fit(_) => (&mut self.image_fit_state, "Fit", Color::Magenta),
Resize::Crop(_) => (&mut self.image_crop_state, "Crop", Color::Green),
Resize::Scale(_) => (&mut self.image_scale_state, "Scale", Color::Blue),
};
let block = block(name);
let inner_area = block.inner(area);
f.render_widget(paragraph(self.background.as_str().bg(color)), inner_area);
match self.show_images {
ShowImages::Fixed => (),
_ => f.render_stateful_widget(StatefulImage::new().resize(resize), inner_area, state),
};
f.render_widget(block, area);
}
}
fn ui(f: &mut Frame<'_>, app: &mut App) {
let outer_block = Block::default()
.borders(Borders::TOP)
.title(app.title.as_str());
let chunks = Layout::default()
.direction(Direction::Horizontal)
.constraints([
Constraint::Percentage(app.split_percent),
Constraint::Percentage(100 - app.split_percent),
])
.split(outer_block.inner(f.area()));
f.render_widget(outer_block, f.area());
let left_chunks = vertical_layout().split(chunks[0]);
let right_chunks = vertical_layout().split(chunks[1]);
let block_left_top = block("Fixed");
let area = block_left_top.inner(left_chunks[0]);
f.render_widget(
paragraph(app.background.as_str()).style(Color::Yellow),
area,
);
f.render_widget(block_left_top, left_chunks[0]);
match app.show_images {
ShowImages::Resized => {}
_ => {
let image = Image::new(&app.image_static);
// Let it be surrounded by styled text.
let offset_area = Rect {
x: area.x + 1,
y: area.y + 1,
width: area.width.saturating_sub(2),
height: area.height.saturating_sub(2),
};
f.render_widget(image, offset_area);
}
}
let chunks_left_bottom = Layout::default()
.direction(Direction::Horizontal)
.constraints([Constraint::Percentage(50), Constraint::Percentage(50)])
.split(left_chunks[1]);
app.render_resized_image(f, Resize::Crop(None), chunks_left_bottom[0]);
app.render_resized_image(f, Resize::Scale(None), chunks_left_bottom[1]);
app.render_resized_image(f, Resize::Fit(None), right_chunks[0]);
let block_right_bottom = block("Help");
let area = block_right_bottom.inner(right_chunks[1]);
f.render_widget(
paragraph(vec![
Line::from("Key bindings:"),
Line::from(vec![
Span::from("H").green(),
Span::from("/"),
Span::from("L").green(),
Span::from(": resize"),
]),
Line::from(vec![Span::from("o").green(), Span::from(": cycle image")]),
Line::from(vec![
Span::from("t").green(),
Span::from(format!(": toggle ({:?})", app.show_images)),
]),
Line::from(format!("Font size: {:?}", app.picker.font_size())),
Line::from(format!("Protocol: {:?}", app.picker.protocol_type())),
]),
area,
);
f.render_widget(block_right_bottom, right_chunks[1]);
}
fn paragraph<'a, T: Into>>(str: T) -> Paragraph<'a> {
Paragraph::new(str).wrap(Wrap { trim: true })
}
fn vertical_layout() -> Layout {
Layout::default()
.direction(Direction::Vertical)
.constraints([Constraint::Percentage(50), Constraint::Percentage(50)])
}
fn block(name: &str) -> Block<'_> {
Block::default().borders(Borders::ALL).title(name)
}
ratatui-image-10.0.8/examples/demo/termion.rs 0000644 0000000 0000000 00000003577 10461020230 0017244 0 ustar 0000000 0000000 use std::{error::Error, io, sync::mpsc, thread, time::Duration};
use ratatui::{
Terminal,
backend::{Backend, TermionBackend},
termion::{
event::Key,
input::{MouseTerminal, TermRead},
raw::IntoRawMode,
screen::IntoAlternateScreen,
},
};
use crate::{App, ui};
pub fn run() -> Result<(), Box> {
// setup terminal
let stdout = io::stdout()
.into_raw_mode()
.unwrap()
.into_alternate_screen()
.unwrap();
let stdout = MouseTerminal::from(stdout);
let backend = TermionBackend::new(stdout);
let mut terminal = Terminal::new(backend)?;
// create app and run it
let app = App::new(&mut terminal);
run_app(&mut terminal, app)?;
Ok(())
}
fn run_app(terminal: &mut Terminal, mut app: App) -> Result<(), Box> {
let events = events(app.tick_rate);
loop {
terminal.draw(|f| ui(f, &mut app))?;
match events.recv()? {
Event::Input(key) => {
if let Key::Char(c) = key {
app.on_key(c);
}
}
Event::Tick => app.on_tick(),
}
if app.should_quit {
return Ok(());
}
}
}
enum Event {
Input(Key),
Tick,
}
fn events(tick_rate: Duration) -> mpsc::Receiver {
let (tx, rx) = mpsc::channel();
let keys_tx = tx.clone();
thread::spawn(move || {
let stdin = io::stdin();
for key in stdin.keys().flatten() {
if let Err(err) = keys_tx.send(Event::Input(key)) {
eprintln!("{err}");
return;
}
}
});
thread::spawn(move || {
loop {
if let Err(err) = tx.send(Event::Tick) {
eprintln!("{err}");
break;
}
thread::sleep(tick_rate);
}
});
rx
}
ratatui-image-10.0.8/examples/demo/termwiz.rs 0000644 0000000 0000000 00000003461 10461020230 0017260 0 ustar 0000000 0000000 use std::{
error::Error,
io,
time::{Duration, Instant},
};
use ratatui::{
Terminal,
backend::TermwizBackend,
termwiz::{input::*, terminal::Terminal as TermwizTerminal},
};
use crate::{App, ui};
pub fn run() -> Result<(), Box> {
let backend = TermwizBackend::new()?;
let mut terminal = Terminal::new(backend)?;
terminal.hide_cursor()?;
// create app and run it
let app = App::new(&mut terminal);
let res = run_app(&mut terminal, app);
terminal.show_cursor()?;
terminal.flush()?;
if let Err(err) = res {
println!("{err:?}");
}
Ok(())
}
fn run_app(terminal: &mut Terminal, mut app: App) -> io::Result<()> {
let mut last_tick = Instant::now();
loop {
terminal.draw(|f| ui(f, &mut app))?;
let timeout = app
.tick_rate
.checked_sub(last_tick.elapsed())
.unwrap_or_else(|| Duration::from_secs(0));
if let Ok(Some(input)) = terminal
.backend_mut()
.buffered_terminal_mut()
.terminal()
.poll_input(Some(timeout))
{
match input {
InputEvent::Key(key_code) => {
if let KeyCode::Char(c) = key_code.key {
app.on_key(c);
}
}
InputEvent::Resized { cols, rows } => {
terminal
.backend_mut()
.buffered_terminal_mut()
.resize(cols, rows);
}
_ => {}
}
}
if last_tick.elapsed() >= app.tick_rate {
app.on_tick();
last_tick = Instant::now();
}
if app.should_quit {
return Ok(());
}
}
}
ratatui-image-10.0.8/examples/thread.rs 0000644 0000000 0000000 00000013054 10461020230 0016101 0 ustar 0000000 0000000 use std::{
fs,
sync::mpsc::{self},
thread,
time::Duration,
};
use ratatui::{
Frame,
crossterm::event::{self, Event, KeyCode, KeyEvent, KeyEventKind},
layout::{Position, Rect},
style::{Color, Stylize},
widgets::{Block, Borders, Clear, Paragraph},
};
use ratatui_image::{
Resize, StatefulImage,
errors::Errors,
picker::Picker,
thread::{ResizeRequest, ResizeResponse, ThreadProtocol},
};
struct App {
async_state: ThreadProtocol,
last_known_size: Rect,
logo_pos: Position,
logo_size: f64,
source_code_lines: Vec,
}
#[expect(clippy::large_enum_variant)]
enum AppEvent {
KeyEvent(KeyEvent),
Redraw(Result),
Tick,
}
fn main() -> Result<(), Box> {
let mut terminal = ratatui::init();
let picker = Picker::from_query_stdio()?;
let dyn_img = image::ImageReader::open("./assets/NixOS.png")?.decode()?;
// Send a [ResizeProtocol] to resize and encode it in a separate thread.
let (tx_worker, rec_worker) = mpsc::channel::();
// Send UI-events and the [ResizeProtocol] result back to main thread.
let (tx_main, rec_main) = mpsc::channel();
// Resize and encode in background thread.
let tx_main_render = tx_main.clone();
thread::spawn(move || {
loop {
if let Ok(request) = rec_worker.recv() {
tx_main_render
.send(AppEvent::Redraw(request.resize_encode()))
.unwrap();
}
}
});
// Poll events in background thread to demonstrate polling terminal events and redraw events
// concurrently. It's not required to do it this way - the "redraw event" from the channel
// could be read after polling the terminal events (as long as it's done with a timout). But
// then the rendering of the image will always be somewhat delayed.
let tx_main_events = tx_main.clone();
thread::spawn(move || -> Result<(), std::io::Error> {
loop {
if ratatui::crossterm::event::poll(Duration::from_millis(100))? {
if let Event::Key(key) = event::read()? {
tx_main_events.send(AppEvent::KeyEvent(key)).unwrap();
}
} else {
tx_main_events.send(AppEvent::Tick).unwrap();
}
}
});
let mut app = App {
async_state: ThreadProtocol::new(tx_worker, Some(picker.new_resize_protocol(dyn_img))),
last_known_size: Rect::default(),
logo_pos: Position { x: 1, y: 1 },
logo_size: 0.1,
source_code_lines: Vec::new(),
};
let source_code = fs::read_to_string("./examples/thread.rs")?;
app.source_code_lines = source_code.split("\n").map(|s| s.to_string()).collect();
loop {
terminal.draw(|f| ui(f, &mut app))?;
if let Ok(ev) = rec_main.try_recv() {
match ev {
AppEvent::KeyEvent(key) => {
if key.kind == KeyEventKind::Press && key.code == KeyCode::Char('q') {
break;
}
}
AppEvent::Redraw(completed) => {
let _ = app.async_state.update_resized_protocol(completed?);
}
AppEvent::Tick => {
if app.source_code_lines.len() > 1 {
app.source_code_lines.remove(0);
} else {
app.source_code_lines =
source_code.split("\n").map(|s| s.to_string()).collect();
}
if rand::random::() > 0.9 {
if app.logo_size < 1.0 {
app.logo_size += 0.1;
} else {
app.logo_size = 0.1;
}
}
}
}
}
}
ratatui::restore();
Ok(())
}
fn ui(f: &mut Frame<'_>, app: &mut App) {
let area = f.area();
let block = Block::default()
.borders(Borders::ALL)
.title("Thread test")
.bg(Color::Blue);
let inner_area = block.inner(area);
f.render_widget(block, area);
for (i, y) in (inner_area.y..inner_area.height).enumerate() {
if i >= app.source_code_lines.len() {
break;
}
let p = Paragraph::new(app.source_code_lines[i].clone());
f.render_widget(p, Rect::new(inner_area.x, y, inner_area.width, 1));
}
let size_for = app.async_state.size_for(Resize::Fit(None), inner_area);
let mut size = size_for.unwrap_or(app.last_known_size);
app.last_known_size = size;
size.width = (f64::from(size.width) * app.logo_size).ceil() as u16;
size.height = (f64::from(size.height) * app.logo_size).ceil() as u16;
let mut image_block_area = size;
image_block_area.width += 2;
image_block_area.height += 2;
image_block_area.x = app.logo_pos.x;
image_block_area.y = app.logo_pos.y;
let image_block = Block::default()
.borders(Borders::ALL)
.title("Nix")
.bg(Color::White);
let block_inner_area = image_block.inner(image_block_area);
if image_block_area.width <= inner_area.width && image_block_area.height <= inner_area.height {
f.render_widget(image_block, image_block_area);
f.render_widget(Clear, block_inner_area);
f.render_widget(Block::new().bg(Color::White), block_inner_area);
if size_for.is_some() {
f.render_stateful_widget(StatefulImage::new(), block_inner_area, &mut app.async_state);
}
}
}
ratatui-image-10.0.8/examples/tokio.rs 0000644 0000000 0000000 00000004157 10461020230 0015763 0 ustar 0000000 0000000 use color_eyre::eyre::Result;
use crossterm::event::{Event, EventStream};
use image::ImageReader;
use ratatui::{
DefaultTerminal, Frame,
widgets::{Block, Borders, Paragraph},
};
use ratatui_image::{
StatefulImage,
picker::Picker,
thread::{ResizeRequest, ThreadProtocol},
};
use tokio::{
select,
sync::mpsc::{UnboundedReceiver, unbounded_channel},
};
use futures::{FutureExt, StreamExt};
struct App {
running: bool,
protocol: ThreadProtocol,
event_stream: EventStream,
rx: UnboundedReceiver,
}
#[tokio::main]
async fn main() -> Result<()> {
let (tx, rx) = unbounded_channel();
let protocol = Picker::from_query_stdio()?
.new_resize_protocol(ImageReader::open("./assets/Ada.png")?.decode()?);
App {
protocol: ThreadProtocol::new(tx, Some(protocol)),
event_stream: EventStream::new(),
rx,
running: true,
}
.run(ratatui::init())
.await?;
ratatui::restore();
Ok(())
}
impl App {
async fn run(mut self, mut terminal: DefaultTerminal) -> Result<()> {
while self.running {
terminal.draw(|f| self.ui(f))?;
select! {
Some(event) = self.event_stream.next().fuse() => self.handle_event(event?),
Some(request) = self.rx.recv() => self.handle_request(request)?,
}
}
Ok(())
}
fn handle_event(&mut self, event: Event) {
if let Event::Key(_) = event {
self.running = false;
}
}
fn handle_request(&mut self, request: ResizeRequest) -> Result<()> {
self.protocol
.update_resized_protocol(request.resize_encode()?);
Ok(())
}
fn ui(&mut self, f: &mut Frame) {
let area = f.area();
let block = Block::default().borders(Borders::ALL).title("Async test");
f.render_widget(
Paragraph::new("PartiallyHiddenScreenshotParagraphBackground\n".repeat(10)),
block.inner(area),
);
f.render_stateful_widget(StatefulImage::new(), block.inner(area), &mut self.protocol);
f.render_widget(block, area)
}
}
ratatui-image-10.0.8/flake.lock 0000644 0000000 0000000 00000004644 10461020230 0014407 0 ustar 0000000 0000000 {
"nodes": {
"crane": {
"locked": {
"lastModified": 1765739568,
"narHash": "sha256-gQYx35Of4UDKUjAYvmxjUEh/DdszYeTtT6MDin4loGE=",
"owner": "ipetkov",
"repo": "crane",
"rev": "67d2baff0f9f677af35db61b32b5df6863bcc075",
"type": "github"
},
"original": {
"owner": "ipetkov",
"repo": "crane",
"type": "github"
}
},
"flake-utils": {
"inputs": {
"systems": "systems"
},
"locked": {
"lastModified": 1731533236,
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1766025857,
"narHash": "sha256-Lav5jJazCW4mdg1iHcROpuXqmM94BWJvabLFWaJVJp0=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "def3da69945bbe338c373fddad5a1bb49cf199ce",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"crane": "crane",
"flake-utils": "flake-utils",
"nixpkgs": "nixpkgs",
"rust-overlay": "rust-overlay"
}
},
"rust-overlay": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1766025663,
"narHash": "sha256-VSrZmhM22nZckbbE8Cmmc5I2RUGtwo1aii77T/i8YPU=",
"owner": "oxalica",
"repo": "rust-overlay",
"rev": "96617c96d4c455770e6664b5e3aad999b677fae6",
"type": "github"
},
"original": {
"owner": "oxalica",
"repo": "rust-overlay",
"type": "github"
}
},
"systems": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
}
},
"root": "root",
"version": 7
}
ratatui-image-10.0.8/flake.nix 0000644 0000000 0000000 00000016643 10461020230 0014257 0 ustar 0000000 0000000 {
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
crane.url = "github:ipetkov/crane";
flake-utils.url = "github:numtide/flake-utils";
rust-overlay = {
url = "github:oxalica/rust-overlay";
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs = {
self,
nixpkgs,
crane,
flake-utils,
rust-overlay,
...
}:
flake-utils.lib.eachDefaultSystem (system: let
pkgs = nixpkgs.legacyPackages.${system};
inherit (pkgs) lib;
# Build chafa with static library support (uses autotools)
chafaStatic = pkgs.chafa.overrideAttrs (old: {
configureFlags = (old.configureFlags or []) ++ [
"--enable-static"
"--enable-shared"
];
});
# We also need static glib for full static linking (uses meson)
glibStatic = pkgs.glib.overrideAttrs (old: {
mesonFlags = (old.mesonFlags or []) ++ [
"-Ddefault_library=both"
];
});
# Chafa build dependencies for chafa-dyn and chafa-static features
chafaBuildArgs = {
nativeBuildInputs = with pkgs; [
pkg-config
llvmPackages.libclang
];
buildInputs = with pkgs; [
chafaStatic
chafaStatic.dev
glibStatic.dev
libsysprof-capture
pcre2.dev
libffi.dev
zlib.dev
];
PKG_CONFIG_PATH = "${chafaStatic.dev}/lib/pkgconfig:${glibStatic.dev}/lib/pkgconfig:${pkgs.libsysprof-capture}/lib/pkgconfig:${pkgs.pcre2.dev}/lib/pkgconfig:${pkgs.libffi.dev}/lib/pkgconfig:${pkgs.zlib.dev}/lib/pkgconfig";
LIBCLANG_PATH = "${pkgs.llvmPackages.libclang.lib}/lib";
BINDGEN_EXTRA_CLANG_ARGS = "-isystem ${pkgs.glibc.dev}/include";
};
craneLib = crane.mkLib pkgs;
unfilteredRoot = ./.;
src = lib.fileset.toSource {
root = unfilteredRoot;
fileset = lib.fileset.unions [
# Default files from crane (Rust and cargo files)
(craneLib.fileset.commonCargoSources unfilteredRoot)
(lib.fileset.maybeMissing ./assets)
(lib.fileset.fileFilter (file: file.hasExt "snap") ./src)
];
};
commonArgs = {
inherit src;
strictDeps = true;
buildInputs = with pkgs;
[
cargo-watch
cargo-semver-checks
cargo-release
cargo-make
rust-analyzer
]
++ lib.optionals pkgs.stdenv.isDarwin [
# Additional darwin specific inputs can be set here
pkgs.libiconv
];
# Additional environment variables can be set directly
# MY_CUSTOM_VAR = "some value";
};
# Build *just* the cargo dependencies, so we can reuse
# all of that work (e.g. via cachix) when running in CI
cargoArtifacts = craneLib.buildDepsOnly commonArgs;
ratatui-image = craneLib.buildPackage (commonArgs
// chafaBuildArgs
// {
inherit cargoArtifacts;
cargoExtraArgs = "--no-default-features --features chafa-static,image-defaults,crossterm";
});
ratatui-demo = craneLib.buildPackage (commonArgs
// chafaBuildArgs
// {
inherit cargoArtifacts;
pname = "demo";
cargoExtraArgs = "--example demo --no-default-features --features chafa-static,image-defaults,crossterm";
installPhaseCommand = ''
mkdir -p $out/bin
cp target/release/examples/demo $out/bin/
'';
});
screenshotTests = import ./screenshot-tests.nix { inherit pkgs src self system; };
# Feature matrix for checks
featureMatrix = {
default = { args = ""; extraArgs = chafaBuildArgs; };
no-chafa = { args = "--no-default-features --features image-defaults,crossterm"; extraArgs = {}; };
chafa-static = { args = "--no-default-features --features chafa-static,image-defaults,crossterm"; extraArgs = chafaBuildArgs; };
full = { args = "--features serde,tokio,chafa-dyn"; extraArgs = chafaBuildArgs; };
thread-example = { args = "--features thread-example"; extraArgs = chafaBuildArgs; };
};
mkClippy = name: { args, extraArgs }:
craneLib.cargoClippy (commonArgs // {
inherit cargoArtifacts;
cargoClippyExtraArgs = "${args} --all-targets -- --deny warnings";
} // extraArgs);
mkNextest = name: { args, extraArgs }:
craneLib.cargoNextest (commonArgs // {
inherit cargoArtifacts;
cargoExtraArgs = args;
partitions = 1;
partitionType = "count";
} // extraArgs);
mkDoc = name: { args, extraArgs }:
craneLib.cargoDoc (commonArgs // {
inherit cargoArtifacts;
cargoExtraArgs = args;
} // extraArgs);
matrixChecks = lib.foldl' (acc: name: acc // {
"clippy-${name}" = mkClippy name featureMatrix.${name};
"nextest-${name}" = mkNextest name featureMatrix.${name};
"doc-${name}" = mkDoc name featureMatrix.${name};
}) {} (lib.attrNames featureMatrix);
# Cross-compile to Windows
pkgsWindows = import nixpkgs {
overlays = [ (import rust-overlay) ];
localSystem = system;
crossSystem = {
config = "x86_64-w64-mingw32";
libc = "msvcrt";
};
};
craneLibWindows = (crane.mkLib pkgsWindows).overrideToolchain (p:
p.rust-bin.stable.latest.default.override {
targets = [ "x86_64-pc-windows-gnu" ];
}
);
ratatui-image-windows = craneLibWindows.buildPackage {
src = craneLibWindows.cleanCargoSource ./.;
strictDeps = true;
doCheck = false;
cargoExtraArgs = "--no-default-features --features image-defaults,crossterm";
};
in {
checks = {
inherit ratatui-image;
ratatui-image-fmt = craneLib.cargoFmt { inherit src; };
} // matrixChecks;
packages =
{
default = ratatui-image;
demo = ratatui-demo;
windows = ratatui-image-windows;
}
// screenshotTests;
apps.default = flake-utils.lib.mkApp {
drv = ratatui-image;
};
devShells.default = craneLib.devShell {
# Inherit inputs from checks.
checks = self.checks.${system};
# Additional dev-shell environment variables can be set directly
# MY_CUSTOM_DEVELOPMENT_VAR = "something else";
# Extra inputs can be added here; cargo and rustc are provided by default.
packages = with pkgs; [
cargo-release
cargo-insta
cargo-flamegraph
chafa
chafaStatic # for chafa-static feature (has libchafa.a)
chafaStatic.dev
glibStatic.dev # required by chafa.pc (has libglib-2.0.a)
# Dependencies needed for static linking
libsysprof-capture
pcre2.dev
libffi.dev
zlib.dev
pkg-config
llvmPackages.libclang
];
LD_LIBRARY_PATH = lib.makeLibraryPath [ pkgs.chafa ];
# For chafa-static feature, bindgen needs LIBCLANG_PATH and C headers
LIBCLANG_PATH = "${pkgs.llvmPackages.libclang.lib}/lib";
BINDGEN_EXTRA_CLANG_ARGS = "-isystem ${pkgs.glibc.dev}/include";
# Ensure chafaStatic is found first for static linking
PKG_CONFIG_PATH = "${chafaStatic.dev}/lib/pkgconfig:${glibStatic.dev}/lib/pkgconfig";
};
});
}
ratatui-image-10.0.8/release-plz.toml 0000644 0000000 0000000 00000000075 10461020230 0015565 0 ustar 0000000 0000000 [workspace]
changelog_update = true
publish_no_verify = true
ratatui-image-10.0.8/screenshot-tests.nix 0000644 0000000 0000000 00000014612 10461020230 0016504 0 ustar 0000000 0000000 { pkgs, src, self, system }:
let
makeScreenshotTest = { terminal, terminalCommand, terminalPackages, setup ? null, xwayland ? false }: pkgs.testers.nixosTest {
name = "ratatui-test-wayland-${terminal}";
nodes.machine = { pkgs, ... }: {
virtualisation.memorySize = 4096;
programs.sway = {
enable = true;
wrapperFeatures.gtk = true;
};
programs.xwayland.enable = xwayland;
services.xserver.enable = true;
services.displayManager.sddm.enable = true;
services.displayManager.sddm.wayland.enable = true;
services.displayManager.autoLogin = {
enable = true;
user = "test";
};
services.displayManager.defaultSession = "sway";
# Create test user
users.users.test = {
isNormalUser = true;
extraGroups = [ "wheel" "video" ];
packages = [ ];
};
# Fonts for proper Unicode rendering (chafa, braille, block elements, etc.)
fonts.packages = with pkgs; [
unifont # ~77,000 glyphs, covers entire BMP
noto-fonts # Google's "no tofu" - comprehensive Unicode
noto-fonts-lgc-plus
noto-fonts-cjk-sans
noto-fonts-color-emoji
dejavu_fonts # Good fallback with extended coverage
freefont_ttf # GNU FreeFont - wide Unicode range
fira-code
fira-mono
];
# Ensure required packages are available
environment.systemPackages = with pkgs;
terminalPackages ++ [ chafa ];
};
testScript = ''
machine.wait_for_unit("graphical.target")
machine.wait_until_succeeds("pgrep -f sway")
machine.succeed("mkdir -p /tmp/test-assets/assets")
machine.copy_from_host("${src}/assets/Jenkins.png", "/tmp/test-assets/assets/Jenkins.png")
machine.wait_until_succeeds("systemd-run --uid=test --setenv=XDG_RUNTIME_DIR=/run/user/1000 --setenv=WAYLAND_DISPLAY=wayland-1 -- swaymsg -t get_version")
machine.succeed("${if setup != null then setup else "true"}")
# Use systemd-run to ensure proper environment
machine.succeed("""
systemd-run --uid=test --setenv=XDG_RUNTIME_DIR=/run/user/1000 \
--setenv=WAYLAND_DISPLAY=wayland-1 \
--setenv=LIBGL_ALWAYS_SOFTWARE=1 \
--setenv=QT_QPA_PLATFORM="wayland" \
--setenv=RUST_BACKTRACE=full \
${if xwayland then "--setenv=DISPLAY=:0" else ""} \
--working-directory=/tmp/test-assets \
-- ${terminalCommand}
""")
print("Waiting for /tmp/demo-ready...")
with subtest("Waiting for /tmp/demo-ready..."):
try:
machine.wait_until_succeeds("test -f /tmp/demo-ready", timeout=10)
except Exception as e:
print(f"/tmp/demo-ready not found within timeout: {e}")
finally:
machine.succeed("sleep 5")
machine.screenshot("screenshot-${terminal}")
print("Screenshot saved to test output directory as screenshot-${terminal}.png")
'';
};
screenshotTests = {
screenshot-test-foot = makeScreenshotTest {
terminal = "foot";
terminalCommand = "foot ${self.packages.${system}.demo}/bin/demo --tmp-demo-ready";
terminalPackages = [ pkgs.foot ];
};
screenshot-test-kitty = makeScreenshotTest {
terminal = "kitty";
terminalCommand = "kitty ${self.packages.${system}.demo}/bin/demo --tmp-demo-ready";
terminalPackages = [ pkgs.kitty ];
};
screenshot-test-wezterm = makeScreenshotTest {
terminal = "wezterm";
terminalCommand = "wezterm start --always-new-process --cwd /tmp/test-assets -- ${self.packages.${system}.demo}/bin/demo --tmp-demo-ready";
terminalPackages = [ pkgs.wezterm ];
};
screenshot-test-ghostty = makeScreenshotTest {
terminal = "ghostty";
terminalCommand = "ghostty -e ${self.packages.${system}.demo}/bin/demo --tmp-demo-ready";
terminalPackages = [ pkgs.ghostty ];
};
screenshot-test-mlterm = makeScreenshotTest {
terminal = "mlterm";
terminalCommand = "mlterm -e ${self.packages.${system}.demo}/bin/demo --tmp-demo-ready";
terminalPackages = [ pkgs.mlterm ];
};
screenshot-test-rio = makeScreenshotTest {
terminal = "rio";
terminalCommand = "rio -w /tmp/test-assets -e ${self.packages.${system}.demo}/bin/demo --tmp-demo-ready";
terminalPackages = [ pkgs.rio ];
setup = "mkdir -p /home/test/.config/rio && touch /home/test/.config/rio/config.toml"; # Skip welcome screen
};
screenshot-test-xterm-vt340 = makeScreenshotTest {
terminal = "xterm-vt340";
terminalCommand = "xterm -ti vt340 -fa \"Noto Sans Mono\" -fs 16 -e ${self.packages.${system}.demo}/bin/demo --tmp-demo-ready";
terminalPackages = [ pkgs.xterm ];
xwayland = true;
};
screenshot-test-xterm = makeScreenshotTest {
terminal = "xterm";
terminalCommand = "xterm -fa \"Noto Sans Mono\" -fs 16 -e ${self.packages.${system}.demo}/bin/demo --tmp-demo-ready";
terminalPackages = [ pkgs.xterm ];
xwayland = true;
};
screenshot-test-blackbox = makeScreenshotTest {
terminal = "blackbox";
terminalCommand = "blackbox -c \"${self.packages.${system}.demo}/bin/demo --tmp-demo-ready\"";
terminalPackages = [ pkgs.blackbox-terminal ];
};
screenshot-test-xfce4-terminal = makeScreenshotTest {
terminal = "xfce4-terminal";
terminalCommand = "xfce4-terminal -e \"${self.packages.${system}.demo}/bin/demo --tmp-demo-ready\"";
terminalPackages = [ pkgs.xfce.xfce4-terminal ];
};
screenshot-test-contour = makeScreenshotTest {
terminal = "contour";
# This sleep is different: it's something about stdin not being ready immeadiately.
terminalCommand = "contour --working-directory /tmp/test-assets /run/current-system/sw/bin/bash -c \"sleep 1; ${self.packages.${system}.demo}/bin/demo --tmp-demo-ready\"";
terminalPackages = [ pkgs.contour ];
};
screenshot-test-alacritty = makeScreenshotTest {
terminal = "alacritty";
terminalCommand = "alacritty -e ${self.packages.${system}.demo}/bin/demo --tmp-demo-ready";
terminalPackages = [ pkgs.alacritty ];
};
screenshot-test-konsole = makeScreenshotTest {
terminal = "konsole";
terminalCommand = "konsole -e ${self.packages.${system}.demo}/bin/demo --tmp-demo-ready";
terminalPackages = [ pkgs.kdePackages.konsole pkgs.kdePackages.qtwayland ];
};
};
in
screenshotTests
ratatui-image-10.0.8/showcase.gif 0000644 0000000 0000000 00026770733 10461020230 0014777 0 ustar 0000000 0000000 GIF89aā÷1 U Ē ˙ $ $U $Ē $˙ H HU HĒ H˙ l lU lĒ l˙ U Ē ˙ ´ ´U ´Ē ´˙ Ø ØU ØĒ Ø˙ ü üU üĒ ü˙$ $ U$ Ē$ ˙$$ $$U$$Ē$$˙$H $HU$HĒ$H˙$l $lU$lĒ$l˙$ $U$Ē$˙$´ $´U$´Ē$´˙$Ø $ØU$ØĒ$Ø˙$ü $üU$üĒ$ü˙H H UH ĒH ˙H$ H$UH$ĒH$˙HH HHUHHĒHH˙Hl HlUHlĒHl˙H HUHĒH˙H´ H´UH´ĒH´˙HØ HØUHØĒHØ˙Hü HüUHüĒHü˙l l Ul Ēl ˙l$ l$Ul$Ēl$˙lH lHUlHĒlH˙ll llUllĒll˙l lUlĒl˙l´ l´Ul´Ēl´˙lØ lØUlØĒlØ˙lü lüUlüĒlü˙ U Ē ˙$ $U$Ē$˙H HUHĒH˙l lUlĒl˙ UĒ˙´ ´U´Ē´˙Ø ØUØĒØ˙ü üUüĒü˙´ ´ U´ Ē´ ˙´$ ´$U´$Ē´$˙´H ´HU´HĒ´H˙´l ´lU´lĒ´l˙´ ´U´Ē´˙´´ ´´U´´Ē´´˙´Ø ´ØU´ØĒ´Ø˙´ü ´üU´üĒ´ü˙Ø Ø UØ ĒØ ˙Ø$ Ø$UØ$ĒØ$˙ØH ØHUØHĒØH˙Øl ØlUØlĒØl˙Ø ØUØĒØ˙Ø´ Ø´UØ´ĒØ´˙ØØ ØØUØØĒØØ˙Øü ØüUØüĒØü˙ü ü Uü Ēü ˙ü$ ü$Uü$Ēü$˙üH üHUüHĒüH˙ül ülUülĒül˙ü üUüĒü˙ü´ ü´Uü´Ēü´˙üØ üØUüØĒüØ˙üü üüUüüĒüü˙!˙NETSCAPE2.0 !ų , ā ˙ H° Á*\ȰĄÃ#JHąĸÅ3jÜČąŖĮ CI˛¤É(SĒ\ɲĨË0cĘIŗĻÍ8sęÜÉŗ§Ī@
J´¨ŅŖH*]Ę´ŠĶ§PŖJJĩĒÕĢXŗjŨĘĩĢׯ`ÃKļŦŲŗhĶĒ]ËļÛˇpãĘKˇŽŨģxķęŨˡ¯ßŋL¸°áÃ+^ˏąãĮ#KLš˛åË3kŪĖšŗįĪ CMē´é͍SĢ^Íēĩë×°cËMģļíÛ¸sëŪÍģˇīßĀNŧ¸ņãČ+_ÎŧšķįĐŖKNŊēõëØŗkßÎŊģ÷īāÃ˙OžŧųķčĶĢ_ĪžŊû÷đãËOŋžũûøķëßĪŋŋ˙˙ (āhā&¨ā6čāF(áVhá
f¨ávčá (â$ĸ% 'BD¤D'ÂD*ÚD
E¨8Ŗ,¤B c
BIäD"9dL&é¤PcKZ9eOå^vIecšĨ\^)fgfŲ$fÂÉĻZŌųæuâygsę)ĨúIf}ō§Ą{z¨ĸĸš¨Ŗē(ĸ2Z)¤J:(ĻjĒ&ĨGΨb $á7§ú*ǍŽz*̰ž˙ĒĒĢĒĘęŦˇâ:kĒļōÚĢŽŊÖę̝šūjląÃÖŦ°Ę&ģkŗĖ>Ģk´ĀēZ-ąÎVģŦ´Ár{lļßRގØ[.šĐĸ;ēŨ^ŽģëÂÛŽąįĘk-Ŋī⯞ķģļāÖËīŊūoÁæLm$ ĄMq4ÉġÅ_LņÄKI#|q#KÜČ'ŖrĮ%üņʡĄrÄ&ÃL˛Ë2WŦsÄ2ŗŦōĘ:ûsĐCĶÜņÉ<M˛É2ėŗŅ/íôĐT÷\ôÉGKmõŌUßŧ4Ô)'=5×\o-3ØHíuĶj?uÔbÍ´ŌgŋvÛTãũĩŨi7˙-w×n{Ũ7Ũs]ˇāZ¯]¸Üh'.´Ūgˇâ_øäûxãįyāCžøæ|;~ŗ>'a D@ë°D@°ūzí ĖŪ:ëš'Áûî°×;Ã/ėÁ?ņĘŗ^<)|ëēįÎģôļ'}öÔķū:ëÕcÂ÷ãk_~÷žųäˇOŧõéÞūöåĶ˙:ú ¨=ûüã¯?õüŗßûĒ÷ŋܰ~į_ūäˇ?
Đ x?P|î{ #hĀ ēāk ûˇÁJp$ 1xĀ
ĒĐDáAųÉđ%ŦĄK Jju$PB˙nT 0" BPÄ1pb Ä ˛°XÅ"ņW$AĢÆ-Zą (b¨Ä#ŽŅW|ŖitF.1_c÷hF>úąycĢøG>Ņ,d á¸HAÚą